diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index aac178b843c4..79c5f786c48b 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -78,8 +78,10 @@ library Constants { uint256 internal constant INITIAL_L2_BLOCK_NUM = 1; uint256 internal constant BLOB_SIZE_IN_BYTES = 126976; uint256 internal constant MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS = 15000; - uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 500; - uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS = 500; + uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 3000; + uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS = 3000; + uint256 internal constant REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS = 19; + uint256 internal constant REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS = 12; uint256 internal constant REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE = 0x6999d1e02b08a447a463563453cb36919c9dd7150336fc7c4d2b52f8; uint256 internal constant REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE = @@ -89,7 +91,7 @@ library Constants { uint256 internal constant DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE = 0x85864497636cf755ae7bde03f267ce01a520981c21c3682aaf82a631; uint256 internal constant DEPLOYER_CONTRACT_ADDRESS = - 0x00de4d0d9913ddba5fbba9286031b4a5dc9b2af5e824154ae75938f96c1bfe78; + 0x127a8fd1a31888ccd00c88d84b93474449bb6683197083e1727dd02ab6803c6c; uint256 internal constant L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH = 17; uint256 internal constant MAX_NOTE_FIELDS_LENGTH = 20; uint256 internal constant GET_NOTE_ORACLE_RETURN_LENGTH = 23; diff --git a/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/private_function_broadcasted.nr b/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/private_function_broadcasted.nr index c2888d7430b8..ede896c6ddcc 100644 --- a/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/private_function_broadcasted.nr +++ b/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/private_function_broadcasted.nr @@ -5,9 +5,10 @@ use dep::aztec::protocol_types::{ constants::{ FUNCTION_TREE_HEIGHT, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, - REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE, + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS }, - traits::{Serialize} + traits::Serialize }; struct PrivateFunction { @@ -36,13 +37,15 @@ struct ClassPrivateFunctionBroadcasted { artifact_metadata_hash: Field, unconstrained_functions_artifact_tree_root: Field, private_function_tree_sibling_path: [Field; FUNCTION_TREE_HEIGHT], + private_function_tree_leaf_index: Field, artifact_function_tree_sibling_path: [Field; ARTIFACT_FUNCTION_TREE_MAX_HEIGHT], + artifact_function_tree_leaf_index: Field, function: PrivateFunction } -impl Serialize for ClassPrivateFunctionBroadcasted { - fn serialize(self: Self) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS + 17] { - let mut packed = [0; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS + 17]; +impl Serialize for ClassPrivateFunctionBroadcasted { + fn serialize(self: Self) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS] { + let mut packed = [0; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS]; packed[0] = REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE; packed[1] = self.contract_class_id.to_field(); packed[2] = self.artifact_metadata_hash; @@ -50,12 +53,14 @@ impl Serialize for for i in 0..FUNCTION_TREE_HEIGHT { packed[i + 4] = self.private_function_tree_sibling_path[i]; } + packed[4 + FUNCTION_TREE_HEIGHT] = self.private_function_tree_leaf_index; for i in 0..ARTIFACT_FUNCTION_TREE_MAX_HEIGHT { - packed[i + 4 + FUNCTION_TREE_HEIGHT] = self.private_function_tree_sibling_path[i]; + packed[i + 5 + FUNCTION_TREE_HEIGHT] = self.artifact_function_tree_sibling_path[i]; } + packed[5 + ARTIFACT_FUNCTION_TREE_MAX_HEIGHT + FUNCTION_TREE_HEIGHT] = self.artifact_function_tree_leaf_index; let packed_function = self.function.serialize(); for i in 0..MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS + 3 { - packed[i + 4 + ARTIFACT_FUNCTION_TREE_MAX_HEIGHT + FUNCTION_TREE_HEIGHT] = packed_function[i]; + packed[i + 6 + ARTIFACT_FUNCTION_TREE_MAX_HEIGHT + FUNCTION_TREE_HEIGHT] = packed_function[i]; } packed } diff --git a/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/unconstrained_function_broadcasted.nr b/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/unconstrained_function_broadcasted.nr index c40c52a06a4c..6731a3b2a63f 100644 --- a/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/unconstrained_function_broadcasted.nr +++ b/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/unconstrained_function_broadcasted.nr @@ -4,9 +4,10 @@ use dep::aztec::protocol_types::{ contract_class_id::ContractClassId, constants::{ ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS, - REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE + REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE, + REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS }, - traits::{Serialize} + traits::Serialize }; struct UnconstrainedFunction { @@ -33,12 +34,13 @@ struct ClassUnconstrainedFunctionBroadcasted { artifact_metadata_hash: Field, private_functions_artifact_tree_root: Field, artifact_function_tree_sibling_path: [Field; ARTIFACT_FUNCTION_TREE_MAX_HEIGHT], + artifact_function_tree_leaf_index: Field, function: UnconstrainedFunction } -impl Serialize for ClassUnconstrainedFunctionBroadcasted { - fn serialize(self: Self) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + 11] { - let mut packed = [0; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + 11]; +impl Serialize for ClassUnconstrainedFunctionBroadcasted { + fn serialize(self: Self) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS] { + let mut packed = [0; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS]; packed[0] = REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE; packed[1] = self.contract_class_id.to_field(); packed[2] = self.artifact_metadata_hash; @@ -46,9 +48,10 @@ impl Serialize UnencryptedL2Log.fromBuffer(log)); await this.storeRegisteredContractClasses(blockLogs, block.number); await this.storeDeployedContractInstances(blockLogs, block.number); + await this.storeBroadcastedIndividualFunctions(blockLogs, block.number); }), ); @@ -308,6 +313,50 @@ export class Archiver implements ArchiveSource { } } + private async storeBroadcastedIndividualFunctions(allLogs: UnencryptedL2Log[], _blockNum: number) { + // Filter out private and unconstrained function broadcast events + const privateFnEvents = PrivateFunctionBroadcastedEvent.fromLogs(allLogs, getCanonicalClassRegistererAddress()); + const unconstrainedFnEvents = UnconstrainedFunctionBroadcastedEvent.fromLogs( + allLogs, + getCanonicalClassRegistererAddress(), + ); + + // Group all events by contract class id + for (const [classIdString, classEvents] of Object.entries( + groupBy([...privateFnEvents, ...unconstrainedFnEvents], e => e.contractClassId.toString()), + )) { + const contractClassId = Fr.fromString(classIdString); + const contractClass = await this.store.getContractClass(contractClassId); + if (!contractClass) { + this.log.warn(`Skipping broadcasted functions as contract class ${contractClassId.toString()} was not found`); + continue; + } + + // Split private and unconstrained functions, and filter out invalid ones + const allFns = classEvents.map(e => e.toFunctionWithMembershipProof()); + const privateFns = allFns.filter( + (fn): fn is ExecutablePrivateFunctionWithMembershipProof => 'unconstrainedFunctionsArtifactTreeRoot' in fn, + ); + const unconstrainedFns = allFns.filter( + (fn): fn is UnconstrainedFunctionWithMembershipProof => 'privateFunctionsArtifactTreeRoot' in fn, + ); + const validPrivateFns = privateFns.filter(fn => isValidPrivateFunctionMembershipProof(fn, contractClass)); + const validUnconstrainedFns = unconstrainedFns.filter(fn => + isValidUnconstrainedFunctionMembershipProof(fn, contractClass), + ); + const validFnCount = validPrivateFns.length + validUnconstrainedFns.length; + if (validFnCount !== allFns.length) { + this.log.warn(`Skipping ${allFns.length - validFnCount} invalid functions`); + } + + // Store the functions in the contract class in a single operation + if (validFnCount > 0) { + this.log(`Storing ${validFnCount} functions for contract class ${contractClassId.toString()}`); + } + await this.store.addFunctions(contractClassId, validPrivateFns, validUnconstrainedFns); + } + } + /** * Stops the archiver. * @returns A promise signalling completion of the stop process. diff --git a/yarn-project/archiver/src/archiver/archiver_store.ts b/yarn-project/archiver/src/archiver/archiver_store.ts index 2adacfa03eed..8cdd20fe369c 100644 --- a/yarn-project/archiver/src/archiver/archiver_store.ts +++ b/yarn-project/archiver/src/archiver/archiver_store.ts @@ -12,7 +12,12 @@ import { } from '@aztec/circuit-types'; import { Fr } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; -import { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/types/contracts'; +import { + ContractClassPublic, + ContractInstanceWithAddress, + ExecutablePrivateFunctionWithMembershipProof, + UnconstrainedFunctionWithMembershipProof, +} from '@aztec/types/contracts'; import { DataRetrieval } from './data_retrieval.js'; @@ -158,6 +163,15 @@ export interface ArchiverDataStore { */ addContractInstances(data: ContractInstanceWithAddress[], blockNumber: number): Promise; + /** + * Adds private functions to a contract class. + */ + addFunctions( + contractClassId: Fr, + privateFunctions: ExecutablePrivateFunctionWithMembershipProof[], + unconstrainedFunctions: UnconstrainedFunctionWithMembershipProof[], + ): Promise; + /** * Returns a contract instance given its address, or undefined if not exists. * @param address - Address of the contract. diff --git a/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts b/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts index ad454ab0d6ff..e817bf8bbcdb 100644 --- a/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts +++ b/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts @@ -1,7 +1,12 @@ import { InboxLeaf, L2Block, L2BlockContext, LogId, LogType, TxHash, UnencryptedL2Log } from '@aztec/circuit-types'; import '@aztec/circuit-types/jest'; import { AztecAddress, Fr, INITIAL_L2_BLOCK_NUM, L1_TO_L2_MSG_SUBTREE_HEIGHT } from '@aztec/circuits.js'; -import { makeContractClassPublic } from '@aztec/circuits.js/testing'; +import { + makeContractClassPublic, + makeExecutablePrivateFunctionWithMembershipProof, + makeUnconstrainedFunctionWithMembershipProof, +} from '@aztec/circuits.js/testing'; +import { times } from '@aztec/foundation/collection'; import { randomBytes, randomInt } from '@aztec/foundation/crypto'; import { ContractClassPublic, ContractInstanceWithAddress, SerializableContractInstance } from '@aztec/types/contracts'; @@ -242,6 +247,36 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch it('returns undefined if contract class is not found', async () => { await expect(store.getContractClass(Fr.random())).resolves.toBeUndefined(); }); + + it('adds new private functions', async () => { + const fns = times(3, makeExecutablePrivateFunctionWithMembershipProof); + await store.addFunctions(contractClass.id, fns, []); + const stored = await store.getContractClass(contractClass.id); + expect(stored?.privateFunctions).toEqual(fns); + }); + + it('does not duplicate private functions', async () => { + const fns = times(3, makeExecutablePrivateFunctionWithMembershipProof); + await store.addFunctions(contractClass.id, fns.slice(0, 1), []); + await store.addFunctions(contractClass.id, fns, []); + const stored = await store.getContractClass(contractClass.id); + expect(stored?.privateFunctions).toEqual(fns); + }); + + it('adds new unconstrained functions', async () => { + const fns = times(3, makeUnconstrainedFunctionWithMembershipProof); + await store.addFunctions(contractClass.id, [], fns); + const stored = await store.getContractClass(contractClass.id); + expect(stored?.unconstrainedFunctions).toEqual(fns); + }); + + it('does not duplicate unconstrained functions', async () => { + const fns = times(3, makeUnconstrainedFunctionWithMembershipProof); + await store.addFunctions(contractClass.id, [], fns.slice(0, 1)); + await store.addFunctions(contractClass.id, [], fns); + const stored = await store.getContractClass(contractClass.id); + expect(stored?.unconstrainedFunctions).toEqual(fns); + }); }); describe('getUnencryptedLogs', () => { diff --git a/yarn-project/archiver/src/archiver/kv_archiver_store/contract_class_store.ts b/yarn-project/archiver/src/archiver/kv_archiver_store/contract_class_store.ts index 29d18d5a13b8..0d17369dcd62 100644 --- a/yarn-project/archiver/src/archiver/kv_archiver_store/contract_class_store.ts +++ b/yarn-project/archiver/src/archiver/kv_archiver_store/contract_class_store.ts @@ -1,7 +1,11 @@ -import { Fr, FunctionSelector } from '@aztec/circuits.js'; +import { Fr, FunctionSelector, Vector } from '@aztec/circuits.js'; import { BufferReader, numToUInt8, serializeToBuffer } from '@aztec/foundation/serialize'; import { AztecKVStore, AztecMap } from '@aztec/kv-store'; -import { ContractClassPublic } from '@aztec/types/contracts'; +import { + ContractClassPublic, + ExecutablePrivateFunctionWithMembershipProof, + UnconstrainedFunctionWithMembershipProof, +} from '@aztec/types/contracts'; /** * LMDB implementation of the ArchiverDataStore interface. @@ -9,7 +13,7 @@ import { ContractClassPublic } from '@aztec/types/contracts'; export class ContractClassStore { #contractClasses: AztecMap; - constructor(db: AztecKVStore) { + constructor(private db: AztecKVStore) { this.#contractClasses = db.openMap('archiver_contract_classes'); } @@ -25,44 +29,128 @@ export class ContractClassStore { getContractClassIds(): Fr[] { return Array.from(this.#contractClasses.keys()).map(key => Fr.fromString(key)); } + + async addFunctions( + contractClassId: Fr, + newPrivateFunctions: ExecutablePrivateFunctionWithMembershipProof[], + newUnconstrainedFunctions: UnconstrainedFunctionWithMembershipProof[], + ): Promise { + await this.db.transaction(() => { + const existingClassBuffer = this.#contractClasses.get(contractClassId.toString()); + if (!existingClassBuffer) { + throw new Error(`Unknown contract class ${contractClassId} when adding private functions to store`); + } + + const existingClass = deserializeContractClassPublic(existingClassBuffer); + const { privateFunctions: existingPrivateFns, unconstrainedFunctions: existingUnconstrainedFns } = existingClass; + + const updatedClass: Omit = { + ...existingClass, + privateFunctions: [ + ...existingPrivateFns, + ...newPrivateFunctions.filter(newFn => !existingPrivateFns.some(f => f.selector.equals(newFn.selector))), + ], + unconstrainedFunctions: [ + ...existingUnconstrainedFns, + ...newUnconstrainedFunctions.filter( + newFn => !existingUnconstrainedFns.some(f => f.selector.equals(newFn.selector)), + ), + ], + }; + void this.#contractClasses.set(contractClassId.toString(), serializeContractClassPublic(updatedClass)); + }); + return Promise.resolve(true); + } } -export function serializeContractClassPublic(contractClass: ContractClassPublic): Buffer { +function serializeContractClassPublic(contractClass: Omit): Buffer { return serializeToBuffer( numToUInt8(contractClass.version), contractClass.artifactHash, - contractClass.privateFunctions?.length ?? 0, - contractClass.privateFunctions?.map(f => serializeToBuffer(f.selector, f.vkHash, f.isInternal)) ?? [], contractClass.publicFunctions.length, - contractClass.publicFunctions?.map(f => - serializeToBuffer(f.selector, f.bytecode.length, f.bytecode, f.isInternal), - ) ?? [], + contractClass.publicFunctions?.map(f => serializeToBuffer(f.selector, f.bytecode.length, f.bytecode)) ?? [], + contractClass.privateFunctions.length, + contractClass.privateFunctions.map(serializePrivateFunction), + contractClass.unconstrainedFunctions.length, + contractClass.unconstrainedFunctions.map(serializeUnconstrainedFunction), contractClass.packedBytecode.length, contractClass.packedBytecode, contractClass.privateFunctionsRoot, ); } -export function deserializeContractClassPublic(buffer: Buffer): Omit { +function serializePrivateFunction(fn: ExecutablePrivateFunctionWithMembershipProof): Buffer { + return serializeToBuffer( + fn.selector, + fn.vkHash, + fn.bytecode.length, + fn.bytecode, + fn.functionMetadataHash, + fn.artifactMetadataHash, + fn.unconstrainedFunctionsArtifactTreeRoot, + new Vector(fn.privateFunctionTreeSiblingPath), + fn.privateFunctionTreeLeafIndex, + new Vector(fn.artifactTreeSiblingPath), + fn.artifactTreeLeafIndex, + ); +} + +function serializeUnconstrainedFunction(fn: UnconstrainedFunctionWithMembershipProof): Buffer { + return serializeToBuffer( + fn.selector, + fn.bytecode.length, + fn.bytecode, + fn.functionMetadataHash, + fn.artifactMetadataHash, + fn.privateFunctionsArtifactTreeRoot, + new Vector(fn.artifactTreeSiblingPath), + fn.artifactTreeLeafIndex, + ); +} + +function deserializeContractClassPublic(buffer: Buffer): Omit { const reader = BufferReader.asReader(buffer); return { version: reader.readUInt8() as 1, artifactHash: reader.readObject(Fr), - privateFunctions: reader.readVector({ - fromBuffer: reader => ({ - selector: reader.readObject(FunctionSelector), - vkHash: reader.readObject(Fr), - isInternal: reader.readBoolean(), - }), - }), publicFunctions: reader.readVector({ fromBuffer: reader => ({ selector: reader.readObject(FunctionSelector), bytecode: reader.readBuffer(), - isInternal: reader.readBoolean(), }), }), + privateFunctions: reader.readVector({ fromBuffer: deserializePrivateFunction }), + unconstrainedFunctions: reader.readVector({ fromBuffer: deserializeUnconstrainedFunction }), packedBytecode: reader.readBuffer(), privateFunctionsRoot: reader.readObject(Fr), }; } + +function deserializePrivateFunction(buffer: Buffer | BufferReader): ExecutablePrivateFunctionWithMembershipProof { + const reader = BufferReader.asReader(buffer); + return { + selector: reader.readObject(FunctionSelector), + vkHash: reader.readObject(Fr), + bytecode: reader.readBuffer(), + functionMetadataHash: reader.readObject(Fr), + artifactMetadataHash: reader.readObject(Fr), + unconstrainedFunctionsArtifactTreeRoot: reader.readObject(Fr), + privateFunctionTreeSiblingPath: reader.readVector(Fr), + privateFunctionTreeLeafIndex: reader.readNumber(), + artifactTreeSiblingPath: reader.readVector(Fr), + artifactTreeLeafIndex: reader.readNumber(), + }; +} + +function deserializeUnconstrainedFunction(buffer: Buffer | BufferReader): UnconstrainedFunctionWithMembershipProof { + const reader = BufferReader.asReader(buffer); + return { + selector: reader.readObject(FunctionSelector), + bytecode: reader.readBuffer(), + functionMetadataHash: reader.readObject(Fr), + artifactMetadataHash: reader.readObject(Fr), + privateFunctionsArtifactTreeRoot: reader.readObject(Fr), + artifactTreeSiblingPath: reader.readVector(Fr), + artifactTreeLeafIndex: reader.readNumber(), + }; +} diff --git a/yarn-project/archiver/src/archiver/kv_archiver_store/kv_archiver_store.ts b/yarn-project/archiver/src/archiver/kv_archiver_store/kv_archiver_store.ts index e183b68076bb..8955e8a5d1d1 100644 --- a/yarn-project/archiver/src/archiver/kv_archiver_store/kv_archiver_store.ts +++ b/yarn-project/archiver/src/archiver/kv_archiver_store/kv_archiver_store.ts @@ -14,7 +14,12 @@ import { Fr } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { createDebugLogger } from '@aztec/foundation/log'; import { AztecKVStore } from '@aztec/kv-store'; -import { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/types/contracts'; +import { + ContractClassPublic, + ContractInstanceWithAddress, + ExecutablePrivateFunctionWithMembershipProof, + UnconstrainedFunctionWithMembershipProof, +} from '@aztec/types/contracts'; import { ArchiverDataStore, ArchiverL1SynchPoint } from '../archiver_store.js'; import { DataRetrieval } from '../data_retrieval.js'; @@ -63,6 +68,14 @@ export class KVArchiverDataStore implements ArchiverDataStore { return (await Promise.all(data.map(c => this.#contractClassStore.addContractClass(c)))).every(Boolean); } + addFunctions( + contractClassId: Fr, + privateFunctions: ExecutablePrivateFunctionWithMembershipProof[], + unconstrainedFunctions: UnconstrainedFunctionWithMembershipProof[], + ): Promise { + return this.#contractClassStore.addFunctions(contractClassId, privateFunctions, unconstrainedFunctions); + } + async addContractInstances(data: ContractInstanceWithAddress[], _blockNumber: number): Promise { return (await Promise.all(data.map(c => this.#contractInstanceStore.addContractInstance(c)))).every(Boolean); } diff --git a/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts b/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts index 12c8922e0b27..0e6461bf77cb 100644 --- a/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts +++ b/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts @@ -17,7 +17,12 @@ import { } from '@aztec/circuit-types'; import { Fr, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; -import { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/types/contracts'; +import { + ContractClassPublic, + ContractInstanceWithAddress, + ExecutablePrivateFunctionWithMembershipProof, + UnconstrainedFunctionWithMembershipProof, +} from '@aztec/types/contracts'; import { ArchiverDataStore, ArchiverL1SynchPoint } from '../archiver_store.js'; import { DataRetrieval } from '../data_retrieval.js'; @@ -61,6 +66,10 @@ export class MemoryArchiverStore implements ArchiverDataStore { private contractClasses: Map = new Map(); + private privateFunctions: Map = new Map(); + + private unconstrainedFunctions: Map = new Map(); + private contractInstances: Map = new Map(); private lastL1BlockNewBlocks: bigint = 0n; @@ -72,7 +81,14 @@ export class MemoryArchiverStore implements ArchiverDataStore { ) {} public getContractClass(id: Fr): Promise { - return Promise.resolve(this.contractClasses.get(id.toString())); + const contractClass = this.contractClasses.get(id.toString()); + return Promise.resolve( + contractClass && { + ...contractClass, + privateFunctions: this.privateFunctions.get(id.toString()) ?? [], + unconstrainedFunctions: this.unconstrainedFunctions.get(id.toString()) ?? [], + }, + ); } public getContractClassIds(): Promise { @@ -83,6 +99,28 @@ export class MemoryArchiverStore implements ArchiverDataStore { return Promise.resolve(this.contractInstances.get(address.toString())); } + public addFunctions( + contractClassId: Fr, + newPrivateFunctions: ExecutablePrivateFunctionWithMembershipProof[], + newUnconstrainedFunctions: UnconstrainedFunctionWithMembershipProof[], + ): Promise { + const privateFunctions = this.privateFunctions.get(contractClassId.toString()) ?? []; + const unconstrainedFunctions = this.unconstrainedFunctions.get(contractClassId.toString()) ?? []; + const updatedPrivateFunctions = [ + ...privateFunctions, + ...newPrivateFunctions.filter(newFn => !privateFunctions.find(f => f.selector.equals(newFn.selector))), + ]; + const updatedUnconstrainedFunctions = [ + ...unconstrainedFunctions, + ...newUnconstrainedFunctions.filter( + newFn => !unconstrainedFunctions.find(f => f.selector.equals(newFn.selector)), + ), + ]; + this.privateFunctions.set(contractClassId.toString(), updatedPrivateFunctions); + this.unconstrainedFunctions.set(contractClassId.toString(), updatedUnconstrainedFunctions); + return Promise.resolve(true); + } + public addContractClasses(data: ContractClassPublic[], _blockNumber: number): Promise { for (const contractClass of data) { this.contractClasses.set(contractClass.id.toString(), contractClass); diff --git a/yarn-project/aztec.js/src/contract/checker.ts b/yarn-project/aztec.js/src/contract/checker.ts index 77bab7b39aaf..758cf9188e2b 100644 --- a/yarn-project/aztec.js/src/contract/checker.ts +++ b/yarn-project/aztec.js/src/contract/checker.ts @@ -25,7 +25,7 @@ export function abiChecker(artifact: ContractArtifact) { } // TODO: implement a better check for bytecode (right now only checks if it's > 0) - if (!('bytecode' in func && typeof func.bytecode === 'string' && func.bytecode.length > 0)) { + if (!('bytecode' in func && func.bytecode.length > 0)) { throw new Error('ABI function parameter has incorrect bytecode'); } diff --git a/yarn-project/aztec.js/src/contract/contract.test.ts b/yarn-project/aztec.js/src/contract/contract.test.ts index 90e822a8f8e5..7b2c692385da 100644 --- a/yarn-project/aztec.js/src/contract/contract.test.ts +++ b/yarn-project/aztec.js/src/contract/contract.test.ts @@ -63,7 +63,7 @@ describe('Contract Class', () => { }, ], returnTypes: [], - bytecode: '0af', + bytecode: Buffer.alloc(8, 0xfa), }, { name: 'baz', @@ -72,7 +72,7 @@ describe('Contract Class', () => { isInternal: false, parameters: [], returnTypes: [], - bytecode: '0be', + bytecode: Buffer.alloc(8, 0xfb), debugSymbols: '', }, { @@ -96,7 +96,7 @@ describe('Contract Class', () => { width: 32, }, ], - bytecode: '0cd', + bytecode: Buffer.alloc(8, 0xfc), debugSymbols: '', }, ], diff --git a/yarn-project/aztec.js/src/deployment/broadcast_function.ts b/yarn-project/aztec.js/src/deployment/broadcast_function.ts index 785cd1d26190..e748629b5ad8 100644 --- a/yarn-project/aztec.js/src/deployment/broadcast_function.ts +++ b/yarn-project/aztec.js/src/deployment/broadcast_function.ts @@ -1,11 +1,9 @@ import { ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, - computeArtifactFunctionTree, - computeArtifactFunctionTreeRoot, - computeArtifactMetadataHash, - computeFunctionArtifactHash, - computePrivateFunctionsTree, + computeVerificationKeyHash, + createPrivateFunctionMembershipProof, + createUnconstrainedFunctionMembershipProof, getContractClassFromArtifact, } from '@aztec/circuits.js'; import { ContractArtifact, FunctionSelector, FunctionType, bufferAsFields } from '@aztec/foundation/abi'; @@ -31,42 +29,38 @@ export function broadcastPrivateFunction( selector: FunctionSelector, ): ContractFunctionInteraction { const contractClass = getContractClassFromArtifact(artifact); - const privateFunction = contractClass.privateFunctions.find(fn => fn.selector.equals(selector)); - if (!privateFunction) { + const privateFunctionArtifact = artifact.functions.find(fn => selector.equals(fn)); + if (!privateFunctionArtifact) { throw new Error(`Private function with selector ${selector.toString()} not found`); } - const privateFunctionArtifact = artifact.functions.find(fn => - FunctionSelector.fromNameAndParameters(fn).equals(selector), - )!; - // TODO(@spalladino): The following is computing the unconstrained root hash twice. - // Feels like we need a nicer API for returning a hash along with all its preimages, - // since it's common to provide all hash preimages to a function that verifies them. - const artifactMetadataHash = computeArtifactMetadataHash(artifact); - const unconstrainedArtifactFunctionTreeRoot = computeArtifactFunctionTreeRoot(artifact, FunctionType.OPEN); + const { + artifactTreeSiblingPath, + artifactTreeLeafIndex, + artifactMetadataHash, + functionMetadataHash, + unconstrainedFunctionsArtifactTreeRoot, + privateFunctionTreeSiblingPath, + privateFunctionTreeLeafIndex, + } = createPrivateFunctionMembershipProof(selector, artifact); - // We need two sibling paths because private function information is split across two trees: - // The "private function tree" captures the selectors and verification keys, and is used in the kernel circuit for verifying the proof generated by the app circuit. - // The "artifact tree" captures function bytecode and metadata, and is used by the pxe to check that its executing the code it's supposed to be executing, but it never goes into circuits. - const privateFunctionTreePath = computePrivateFunctionsTree(contractClass.privateFunctions).getSiblingPath(0); - const artifactFunctionTreePath = computeArtifactFunctionTree(artifact, FunctionType.SECRET)!.getSiblingPath(0); - - const vkHash = privateFunction.vkHash; - const metadataHash = computeFunctionArtifactHash(privateFunctionArtifact); + const vkHash = computeVerificationKeyHash(privateFunctionArtifact.verificationKey!); const bytecode = bufferAsFields( - Buffer.from(privateFunctionArtifact.bytecode, 'hex'), + privateFunctionArtifact.bytecode, MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, ); const registerer = getRegistererContract(wallet); return registerer.methods.broadcast_private_function( contractClass.id, - Fr.fromBufferReduce(artifactMetadataHash), - Fr.fromBufferReduce(unconstrainedArtifactFunctionTreeRoot), - privateFunctionTreePath.map(Fr.fromBufferReduce), - padArrayEnd(artifactFunctionTreePath.map(Fr.fromBufferReduce), Fr.ZERO, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT), + artifactMetadataHash, + unconstrainedFunctionsArtifactTreeRoot, + privateFunctionTreeSiblingPath, + privateFunctionTreeLeafIndex, + padArrayEnd(artifactTreeSiblingPath, Fr.ZERO, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT), + artifactTreeLeafIndex, // eslint-disable-next-line camelcase - { selector, metadata_hash: Fr.fromBufferReduce(metadataHash), bytecode, vk_hash: vkHash }, + { selector, metadata_hash: functionMetadataHash, bytecode, vk_hash: vkHash }, ); } @@ -84,35 +78,33 @@ export function broadcastUnconstrainedFunction( artifact: ContractArtifact, selector: FunctionSelector, ): ContractFunctionInteraction { + const contractClass = getContractClassFromArtifact(artifact); const functionArtifactIndex = artifact.functions.findIndex( - fn => fn.functionType === FunctionType.UNCONSTRAINED && FunctionSelector.fromNameAndParameters(fn).equals(selector), + fn => fn.functionType === FunctionType.UNCONSTRAINED && selector.equals(fn), ); if (functionArtifactIndex < 0) { throw new Error(`Unconstrained function with selector ${selector.toString()} not found`); } const functionArtifact = artifact.functions[functionArtifactIndex]; - // TODO(@spalladino): Same comment as above on computing duplicated hashes. - const artifactMetadataHash = computeArtifactMetadataHash(artifact); - const privateArtifactFunctionTreeRoot = computeArtifactFunctionTreeRoot(artifact, FunctionType.SECRET); - const functionTreePath = computeArtifactFunctionTree(artifact, FunctionType.UNCONSTRAINED)!.getSiblingPath( - functionArtifactIndex, - ); + const { + artifactMetadataHash, + artifactTreeLeafIndex, + artifactTreeSiblingPath, + functionMetadataHash, + privateFunctionsArtifactTreeRoot, + } = createUnconstrainedFunctionMembershipProof(selector, artifact); - const contractClassId = getContractClassFromArtifact(artifact).id; - const metadataHash = computeFunctionArtifactHash(functionArtifact); - const bytecode = bufferAsFields( - Buffer.from(functionArtifact.bytecode, 'hex'), - MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, - ); + const bytecode = bufferAsFields(functionArtifact.bytecode, MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS); const registerer = getRegistererContract(wallet); return registerer.methods.broadcast_unconstrained_function( - contractClassId, - Fr.fromBufferReduce(artifactMetadataHash), - Fr.fromBufferReduce(privateArtifactFunctionTreeRoot), - padArrayEnd(functionTreePath.map(Fr.fromBufferReduce), Fr.ZERO, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT), + contractClass.id, + artifactMetadataHash, + privateFunctionsArtifactTreeRoot, + padArrayEnd(artifactTreeSiblingPath, Fr.ZERO, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT), + artifactTreeLeafIndex, // eslint-disable-next-line camelcase - { selector, metadata_hash: Fr.fromBufferReduce(metadataHash), bytecode }, + { selector, metadata_hash: functionMetadataHash, bytecode }, ); } diff --git a/yarn-project/circuits.js/fixtures/PrivateFunctionBroadcastedEventData.hex b/yarn-project/circuits.js/fixtures/PrivateFunctionBroadcastedEventData.hex new file mode 100644 index 000000000000..93903075b8af --- /dev/null +++ b/yarn-project/circuits.js/fixtures/PrivateFunctionBroadcastedEventData.hex @@ -0,0 +1 @@ +000000001b70e95fde0b70adc30496b90a327af6a5e383e028e7a43211a07bcd26222cd450fe6beecf6cbe6495e118412940ee0da5744629dabcaf010a2a4e38229d43c7daac528d0aefd72bee59385d7e9ff06ea477b673389e1f65168cba9f0c3d79f3431c5bef8abf01dcf84cb2c64d136171adca23e40d20ed1c649518170583aed5d42e43d977274df1e4536a029a27c2f443bd96eef4162f7f5d7d0b76159e0bdd29fcc7efb79fdb56480e4cac622d6d71755adb98c7c614af8d76a64519e9d55f327e3c96dd42e60a81a783b0bb968d074ee638d542d17f8a3a0b699006e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa0000000000000000000000000000000000000000000000000000000000000000018e01957faa463b1495f979f153e839d5fbd2af9b0d142940d1df29d9bcf43732c450d02ff856d78b6197914dbb85cc88b31ef6f32d534f01b893dcee663a1191c26a986ab599f5027f02a8390d7cb96c87146380163a5fa002c30cba8e32f6800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038cda461eef7f2eaafa09e24b0475a918bd7388c4dec305145849f5f84d1b822202b94400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006150001f8b08000000000000ffed7d077c1dc5b5fe4a5c0b8390e8d8a68a9a8091750075d58dc11770c01d375c31b66cc9058c0db6e909a407d21b219006212410920000792185f4c64b5e3ae9e5a591e4e5252fc94bf9bf24af38ff9dabf9ac4fc7003357d2b2e7eaca3bfbfbcd6f6667cfccf9ce99d9993365676ba281eb973551007469cd40d878b5b13b20764d749fb361dc4f10f775827ea2b83f5cdc1f29ee008f16f793c47d93757c59c851d1fa6df9cef6f6feae427f6b5b6b6fbed0b3a100bb23dfdeb1a1b3bbb5bbb5a3bba3afd0ddd6d6dfdddeddd5b3a1a72bdfd3da00ded6dfbaa9a3a76d537ee03a95f2ca3fcdab867460ae9363b72776a758ffd4008cf967c7ee345b66ac97d332aa0fd6cbe9d1c0fb86facc97ace3f9a777b5a60098579ef19e110db409e6aa73e0c77580233c91e8f6a42c2bf392580e77e0dc00a70c8a2982d128cc3314f27d46945ea3aa25f733d22fa37ca55ec29a28fd9700d0f878f19e19bb33637756eca646038d4c73ec4eb0cf270adda582a53ddf5500e29f1baa335cf5d140471e11cd81d18021004cb9f431b59a7c27a49d6f3edf0039d1e24f39dfbd864364711789cf04d2d541d1a09e53e2ddcabc61dc1d443c005174081f41b4a0833e50d6c0de100dd6cf83caa4cb89748d4453e790bf18a5002bff8102cf8102f3048a331d484d6e5f6c1af5cdbc3fdc79427f91c01b114e00e049fdbd8a75757034f8ee6eeedf7de18eedbb77f66edc3d67fbaeddbddb3700f673b304d87502764d345404f9dc5cb58eb87a12ef008a43fa1cc5d50a75d4003bf01c1429f6fb18c09836f89e68d0000648d3561ba367aaf5cf8c060d43e3001f17bb69940e029d659f4f23ba16075db37dde62fd438d4c42d65a21f3d3ed00f3d36c93f251fa6d2be43dc0eae474eb9b36aa7518dde49fded53a35453db700a6a89b4ad93e6746e99627ae42140620c382d128cc8242be6d51750f408cdc006de997515e5698b4cb3f2d9d9e99625eedd1f86bc4d2c4cc783ba2d0880d0b0046a3303b14f2ed8caabb11337277a65f464eac4f57fe368b356d6bacad4acb003b2c1fec3b4dde15edbb7cd095517db05ebaa3a10d33469c7ca5dd769c1ca5006ff4a48df19448a793ee890646d1e6529a496de3995459963c824d91677e620034d4e84c25dfb81ccc6c1966cc4a533242aec329ae8664d498b5e2e928e48d007bf033335b0d367c75efc62bcfdfb9f9daabfab7efdec59500c41ce77a016b001dcf5cf35b4ad3864304ae1102f39cd80421976bee4c759e2c722825adbcbb00a3f47ae69ef47095862b75d1be5735af3739e03eedbcfbfbbabbbb3a4bc5a400a6836e251da48db3699ce09c1055779dda0b94f29c6efd73ac3fc3fae75aff003cebcf1418ceb7fe05d6bfd0fab3ac5ed1683e2b7617c5eee2d8cdb67173a200a16b747363372f76f363b720760b637749ec16c56e71ec96c46e69ec96c5ee00d2d82d8fdd8ad8ad8cddaad8ad8edd9ad85d16bbb5b1bb3c76eb62b73e76bd00b1db10bb8db1eb8b5d7fec36c56e73ecb6c46e6becae88dd95b1db16bbab6200b73d763b627775ecae89ddced8ed8addeed85d1bbbeb62777dec6e88dd8db100bb297637c7eed9b17b4eec6e89ddadb17b6eec9e17bbe7c7ee05b17b61ec5e0014bb17c7ee25b1bb2d76b70b7dbd34762f8bddcb63f70af1ec95b17b55ec5e001dbbd7d8674df6d96b63f7bad8bd3e7677c4ee0db1bb33766f8cdd5db1bb3b00766f8add9b63f796d8bd35766f8b06d65fee8ddddb63775fecde11bbfb63f700ced8bd2b760fc4eec1d8bd3b760fc5ee3db17b6fecde17bb8763f748ec1eb500585069df1fbb7f8add0762f758ec3e18bb0fc5eec3b1fb48ec1e8fdd4763f700b1d87d3c769f88dd2763f7a9d87d3a769f89dd6763f7b9d87d3e764fc4ee9f0063f785d87d3176ff12bb2fc5eecbb1fb4aecbe1abbafc5eeebb1fb46ec9e8c00dd3763f7add87d3b76df89dd7763f7bdd87d3f763f88dd0f63f7a3d8fd6bec007e1cbb9fc4eea7b1fb99d0f9cf63f754ec7e11bb5f8a67bf8addbfc5eed7b100fb77f1ec37b1fb6decfe2376bfb371bfb7fe1fa2a106d17fc6ee8f22ee4fb100fbb30dffc5faffcffaff65fdbf5aff6f22eddf63f7df22ee7f62f7bf22eeff00a2811193b9fe617d348a35d6afb5fe01d6cf597f82f5ebac7fa0f5275aff2000eb1f6cfd7aeb1f62fd06eb37c6fe8c636dda68f02a466959f17d1b78e4206d000ba30bac57c36fb2f107d8fb03447ccedee7c84237f113ecfd048a77edf1e00005d71a8a43dda9a5b8bd8bba14b7775197e2f6ee87a07d24a82fa534628451004a03f9286e2264a3b8832017c51d2cf469e2ea8937e20eb1711329aec1c61d0044718d36ee608a3b94e4837f988d3b241acc177d51314aabceb496f6c85c900076be71ce26df59e9e75b1a8d3f2b1a2ca722f1b9807475910da7bd47e65994006f0df1417c8ec267102de8a00f8c3281dddcc3b6b8a84cbaf345ba46a2b9d000217f314a57fe5902cf2c81d994c971366ceaf1d1b61ef3ac89423deed4a9c700edf9508f075648a2c85d1f0fb3e1fdb11e9f4538d2afb31d9da1ed1df135ea003a7b21d1caba87bd8bfb639ded261c0a75b637d4d9115fa3aeb38b8956d6bd00a36c787facb317110e853adbaf53670bc1368806e69fa2c85df78eb1e1fdb100ce2e231ce9d7d92ea53adb16ea6c3430f71945eeba37d986f7c73abb8170a4005f677bfb836d30e26bd475f666a29575cf4e2bee9775f66ac2917e9ddd5008007576c4d7a8ebeced442bebdef136bc3fd6d95b0887429d0df30623bf465d6700ef245a59f74eb4e1fdb1cebedc86cd9cede3b9817013c57dd4c69d4c7815ea00f646a5ba5d08757b609d3b8adc75f4141bde1febf69b0987429ded0f7576c400d7a8ebec63442bebde6936bc3fd6d977dbb0697b3f65dbde3328eed336ee190014f7191bf74c8afbac8d3b93e23e67e374d737367684f762c4d7a8df8b2f1000adacdf536d787f7c2f3e4e3814ea6c57a8b323be465d67bf43b4b2ee35dbf000fe5867bf443814ea6c4fa8b323be465d677f41b4b2eeb5d8f0fe5867bf6fc300c65ef892b5175a29eecb36ae40715fb1716d14f7551bd74e715fb3711d14f700751bd74971dfb0715d14f7a48deba6b86fdab81e8afb968d9b4e71dfb671e70050dc776cdc0c8afbae8d3b97e2be67e3cea3b8efdbb89914f7031b57b471e6000b27ec49fcb68d33650b7bac18a555b67d1d863f9f8d66ae1a715fa4f0998400e799a9e3197a4ed0c6de6ddb16eddc7a5defeefe8baeddbe71f7d61ddb6b080022607f5bc0ae89868a80e77514574b61fec02b47e10914e6b4073ae25c974e00910dbc8ecf243e45ba3f33f0ce2cefb3d2e75da8271eb8ca350f3c3c9caaa0008b7ae231123c5375f1e41b090ff33a5b41f672f5e0ec2ae1dd9c3eef521d3c003b1a7a952bf366c2d3a2a08b7ae231123c2d84679a021e25394bdb3ef0d952008a27c4944cf956a1ab66a1ab46a2c993fe5a15f457437c9137ee5b090fea2000b0d613ddd955821171d3088fc63b50ae3d68a902de4617e8b778ba13cfb9df00ac86f2e2e9d789368cfec4d8a1cd35837815dad8d23b097e399b2f7034533c0068f64c19c4d66ab135d0739e3a9e26e234eb0578216fdc835f03c9338de2100066fb25af84b1c58311fcb87dacf3c891239a1956ffe6b30ab6475866d94ed500537a6ebb0a4a32cbf61ef705c208195b098f962dd32cf0343b74b13ff2f6bd001fcafd575eb36e61ea08d382b26ee5886601bd2b9c16b8641bdd40ba69231d00b529c982f2a811e5c3bc356cc872f5725ae03da6bc15faca02f7cbb8463a860051788f0b6c9b8d044f81f068bc8b4a7296da414c6ba73da6ea10ba6a11ba6a00249a76d25f8782fe6a882ff2c63d7f1a3ade301b3cd216ab27ba695582117100dc6f68f5bfbe36ac5005bc791c88b10997178f49aaa1bc786e014740c0163100f6cd4d340e5498cf2cb04e614f1d24f497239a4fd138f0161a07360bfdfac600de951a63e11efc78acea1a27f13850c11e2ee939efc1087e5c77ea3c72e48800e676cf3890654618ed94afedd2b26f7def421b61947d80a6fd3555e099ead000c5fec8dbf77e306f2dfb47a16e95de27d80768b764ddca11cddd621c8878e000c27be29a9f006d2de58d674d36be5df0de63e3651e4d91ae0dabd0a79574dd0029740dfc1da46bd0bc43e8bad3a36b6e03a01fd0d646fbda813536be53f08600ae651e3556d79de9eb64c83b85b17b8be0af39efe96b4b2a31171f78fb792b00d837a31e2bf3fa59faed415f094f7e14783a088fc6bba8d4ee95fa2e6c2b4b007becde2d749517ba6a249a2ed25fb782fe5ce372dc835fc01c3007cc0173c0001c3007cc0173c01c3007cc0173c01c3007cc0173c01c3007cc0173c01c300700cc017331600e9803e68039600e98a38039fff4ae8039600e9803e68039600e009803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e6008039600e9803e68039600e9803e68039600e9803e68039600e9803e6803960000e9803e68039600e9803e68039600e9803e68039600e9803e68039600e980300e68039600e9803e68039600e9803e68039600e9803e68039600e9803e6803900600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e980003e68039600e9803e68039600e9803e68039600e9803e68039600e9803e680003960ae3acc064f0bf859bf9ee85aaa0423e23a094f87129ea9020fee3baa8000b7d1c59936dc6c7d2eaf3309633594d754c278b00d17ac3f2176474d18c45b00481d6f5fc1e06d237e45078e1cd13c7fca20ed648bad819e9f49f2b48a382300433e751906740e5ec81bf7e0d740f2b4521cc26711c6e6d4310ee839efc108007e5cbfeb3c72e488e654abffc3a2813a7596436684d14ed5537a6ebbc6ea7d00e532984a785a94f014049e82431763c59bdb2ebc4ff5f49cdfa3a94a185b040046dc4f258c882b109ef4dba6f2ef75e03db6bcdbd2e75da88f86be23e6aa1100f7450ab7111e8d77b69e788c048f721b926f243ccc4bab2df0d583a955c25b00a1cf2a70ff88ab5c99b3cddb953e9e2eb65d478287c74c9de9e369559233cf00f6f89e14f335baea11baea10ba6a249a6ed25f8f82fe6a882ff2c63df805cc000173c01c308f16b3c123c757f54437b54a30228ee7aa14fa94b276445715f00036ba80bdcb738b78cef6763594572b61acb761d8a1662ae2669aab4a7f0e2500df5523f8150907f8e5886616cd55dd4a735572fcca3616eb5cc37e2a373f08007e0d240fcf9320cce31e0d9bb386b0488ce0c773f9751e397244f3529aab62005978feb347c419f9a6a72f5fabab6dc73df83510f61ec2a335de6916789a1d00bad81f79cbf5a06e076f85b62faf54b74aefce39362fb451b26ee588e66e7a002f382d70e13d411e0da49b7348471aef89c97786928ece153a02fe19a423d000dc2b748478a9237e77a19b7349470ab2144cbee729e968a6d011f09f473a0200cd03424788973a9a413a826e405b4b613cdb637557a4fba72be3267b997ccf004f90efa6612e93ef054f1f6fab8c8828af5a0a83d7489ebb68cfa734e709ba003de2fec068b08cb81ee0f963540f26126d314aad6eb6b17e53ccb754e7a10b00d4f99942fe1cd13c2eea3ce2810b751e793490ce58e717087d36d9f8f305ef003dd1d0323a9fe89574d2ceef5e8af996747da1cd0bba66fce6ca11cde784ae00110ffa0ea1ab06d20f68f99dc0b31a1b7fa1e00d5dcb3c0cbd924e3a4cbeb300d2cfb7a4eb67d9bc2688bcc12f47345f15ba463c70f1bcb7b91a483fa0ada500bc5977b54483e7d0b5cc03ba56d049a7c9f7a2f4f32de9fae268a8ae81ff2200d23568be27748df848e87a16e91afab998747d91d05d938dbf58f086ae651e004d56d717a7af932176764d34d4ce063fcdfd30bef14577e03da6bcd35f3f1b00d8e722df3fcc07801fbf7fbf1de6fdc35c0dcf8dc8baeb4a07fae94403fe750082e662c2059a3f8abd356d8256f35df5955db5f05698172badbb72199aabdc003a27cf1d2bf423edf5d1d039b0e1f05c447834f65229c9599a07996df34a7b00dd758ed055a7d05523d1cc26fdcd51d05f0df145deb807bf803960f661367800d03e016b3dd15d5c251811c7fb5214da8db27dc54555c09bd7d678ef2b9ef3003a4f359417ef553fc48631e76b4c9193ea06f12a8cc7da192fec36e0e0312a0068ea686ded548badc1a15f23cf05224e69fc5ed23978216f39a7d140f2f05c0005c2bcb6a63077d65e130db51b1823f8191accd3d645feb919d04cb3fa3f4c00c88236c994c17411a7b9a60c5ec81bf7bc8601ecd3098f964d3b4be099e5d000c5fec87b86e03d2323728f8477faeb6503635f6eb3396f5efb03cdf9f4de72005ae0e2bed35c0d24438faa2cee3572290bef1fa913343d242f686693bc3ca6006659b4da245f9da806deb5c48fe7036b05267361fe50d683a648ad5f2df0de000c5ce5c6c208ebcc15b4e7eb05bfe1f068ef33539a13c9f35c42da6373f99d004f51e88abff3e1b184d6b75172bf11ee5ddf543445e9eaa27904ba6876e05100d8e3565617fc9de06830778c43cc41cf41cf3ecc41cf41cf3ecc41cf41cf3e00cc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc0041cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc4100cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf0041cf3ecc41cf41cf3eccd5a0673e0f167cf93bf29e2ac18838edb3c20d1edf00b70f9d55c09bbf11c5b7365c5efcbd623594d72cc2a3f00d68e9bb8a06c1cb007cc774e5819a7c0ba53df8f2db538983bf3d3d62f220ed0e8bad819ee33de300ef44f8dd53f8aeb35496c84be6cde78fb1fe10076cfccdec4c11a7f99d973c002b10f77c9ea294652cf5a8c9dbd766ccd42d87029739ae1a715fa4307f37ab00d07eb6f337c323c1c3ed79f8c6cafd8dd574a1ab2c7f63e5d245b5dbcce5300057abcd5ced7a3678647fc336d8cc2ac158499bb928f0e0be1236f370bcd96600663bab5a6de622e129a68fa76433370a5ec62e7d806c660d7ba146f02b120e003e6b0034274e1aa47d0fd9cc788ef78cbff5e6774feb1f19be73f8c1af2172009f1f22ed63df7f33b4de13df7f333a09a394652cf5a8c9db77de8b725b59e00032c735521b55c1c61af59981daff5f559233cf6d7bda36f36ca12b69a33612004d33e96fb682fe5c363ceec12f600e987d985dffbae2fff9765509c64a8e41007dfd544b15f066db96ed21d7ff8eaba1bc94cf2e2ad9b6870a5ec67efcc58100ba7c794e1236acc4c1ff3ef9f6d183d87e4db62d9ee33de3fe99df3dad7f9f00fbc629fc4f2fc8c376a3b4637dff27d37a4f7cff276b218c5296b1d4a3266f005f9ba1dc561646fbdf5f6e3fd36f9b0a796e0747826736e1d19807506a834b00b62dce674ddbb69d2b74e56adb413387f43757417f2e7b0af7731dbc9ba2740075316f04ba98e7c033afc2ba00bfd1629e330e31073d073dfb30073d073dfb0030073d073dfb30073d073dfb30073d073dfb30073d073dfb30073d073dfb3000073d073dfb30073d073dfb30073d27c36cf0c8f5a17aa2eba8128c88abc4be0000df7ad5ec2ae0cd6bdcbc2e8ae7bcbe580de5a5bce7b5b4ae7598e065d691005f3351936f6b9ef71062ffa6c4c1ff4efad95183b477586cbc568cf7ccc8e300dacfa1b517d7b75f01fc78ad98d78fe57a763da5a9c43e0bb94f1ef7b309a30094652cf5a8c97bb8fdd44ae550e032c735d235e5f4d744dbf2dc0e8e040ff700bf1aff10d59173608d1b6d6dda6bdcf385ae660b5d3512cd3cd2df7c05fdb900d6dc710f7ee31133f36e8ad22dbf0523d0c502079e0515d605f88d16f3bc8000b9229843dd08987d9843dd08987d9843dd08987d9843dd08987d9843dd0898007d9843dd08987d9843dd08987d9843dd08987d9843dd08987d9843dd08987d009843dd08987d9843dd08987d9843dd08987d9843dd08987d98aba16ef099a300c05a4f74cd5582117195387bc1b7df6b6e15f0e63da2bcaf10cf797f5e35940097f2d951a57d61870b5e661fe62d0769f21dd823da41fc8a0e1c39a2f9f4910083b4cfb7d81ae839de33dee7c6ef9ec61eb672fb7dc1af21da779f7b43b4ef007ed07a4ac37550eb3d992370e37e2e6194b28ca51e3579fbda0ce5b6b2c065008e6ba47b3215f6e7b5733b38123cdcff6aeca7579233cf6d7bda7b44170a5d00cd15ba6a249a05a4bf850afa73edffc43df805cc01b30fb3c123fb857aa29b005325182bb97fd9d74fcdaf02de6cdbb23d84e76c57544379cd263cb3d3c75300b26d8f10bc8cfdf838d9b6cde9f36daf11fc8a8403fc7244f302b26d3f41b6002d9eb38de81aa7687dcbe61ba7801fdbb16c3722dc461835ec959a68df6f4a00659bca730a751e397244f345ab7ff3bd5a23c9c032cbef6aeb297d25da4439004782fb8584518e2935ede76681a7d9a18bfd91b7effd60de0a7308a31e3770001db8247d3ced5cff4782e712c2a3f18e28c9591a372cb279a53d6e582c74b50040e8aa91681691fe162be8af86f8226fdc835fc01c30fb30f3b80158eb896e004e956044dc42c2a3d06e94eda72ea902de3c6ee0350c3c675bb31aca8be7750015ecf7d2b8e148c1cbd8e6ff18837183c4c1e38667d1b8e1808307c2be7183006b0ca8b5bee11b03821f8f1be6531cc23c6e50b00fda5d36b46bbe06f5adce0023478e681aadfee5b881659663045f9bb8287d99cbbe638b082364e476298c001b2af37e306f85be60d4e306ae030aed7e3bd7ff91e0594c7834de1125394b00e3862536afb4c70d4b85ae5cfd26689690fe962ae8cf65abe21efc02e680d9008799c70dc05a4f7473aa046325c75abe7e6a7115f0f68d1bf09c6dcd6a28af004a8c1b8e12bc8c6d3eeb6055be05d7b841e2e071c39c230669673bc60d6c9f002e14719ae354b93e8a7bf0e37103cf75cb7d33beb1eb58dad55296b1d4e3fe003acf3196728fa4ee22cce3dbf4dbeebe527b80fe1ced81ecfb7344b38ec6ae009c16b8e6386441dd5e5271f906f42d31bae64dd107d4099a25a403d06c261d0064b58ed6923e50be4d361e3478bec7c62f12793465587f3a76cec0fbbccce60085f77989288f1cd15c27dee7650237de67d7bb0b5a573ad0977bc796887c720044f36ccf1c19682752b81855a6ecaa81772de98ddfa35aa2e1f9037e1f9711003dcf3314d393a1346fc475c15ce5e669782c79a9129e25a3c07329e1d118870028c9599a375a6ef34a7bde6885d0d512a1ab46a2594efa5ba1a0bf1ae28bbc00710f7ee311b3c123dfdf7aa25b56251811b794f028d4e7b26de1a555c09be70033780c8ce73c96ac86f2e2756b8575b2d27cc6d18297b13fde49f3191afd0d00db15b07780c365bbd7d37cc6bb693e03cf795ec03537a5b54fcf3737c5731700d2a66aa0308fa314d6a20aae7742ceb5729dacf3c891239ac73c361ecb2ced001f5f9bb83c7d99cbbe63cb092364e47649cb3e9463d9250e5dec8fbc7def0700f3d6b21f4763cf721d5068f70b5cff47826705e1d1784794e42cd9b32b6d5e0069dbb3ab84ae5cfd26685692fe5629e8cf65abe21efcc62366b66781b59ee800965509c64a8e017cede78a2ae0cdf6ec5e5b899eb30d540de5c5f3060a766500c99e3d46f03236e3536360cf4a1c6ccf7ee5f041da7f1bc69e757d33ae357e00f27d330e7e6ccff2f7ef08b33dabd06f155cb61d78831fd7c93a8f1c39a2f90013d9b32c0bdbae2b459ce6fb045ec81bf7e0d740d8b9cf08b66b65dab5fd5d00ee91f05e993aef813510d471b4a1785fc12fc734f5033ed640a4ad85b694db002ec8b04a5596013dfa6c3ff03334ab6db84ed0ac2279417308c9abd907f8ca00bf12f37781b79ff7ead4790fbc736b6c5e78e750f7c02f473493c53bb746e000c63bc77d156400ad2b9d1c03b9de8d55221f7e374e245c3c2705da89142e46009529bbc07b6c792bd867a5791caebbe62a378fc3fdcc65a9e369edaa8f86f60033c3e1b98cf0a4df9e0ccc2ba52fe7c0bcd25a9b57daf34a970b5dad12ba6a00249ab5a4bfcb15f457437c9137eec12f600e9803e68039600e9803e6803960000e9803e68039600e9803663dcc060fe67e80b59ee8d6540946c4ad263c0a73003265e7e12eab02debebd1178ceebe9d5505e95d81b3149f03273fe6fa91fe4009bfe9c696b17cfe5638d01385ceb5cafa2bd11f75a6c0df49cf746ac14719a007b4a7debf2bca754ae63345098f746a4ff8dca809e977b30f2991128fb3a8f001c39a2798f675d85654618ed1f7fbbc36de258b5035c06fc8e69ad4dc875df00550e5d8c156f6e13f13ef19a06bf470a6d50ab6bed0ff74b08a3ec6795d6730046b4df466bad64b46b37ab75f1e4792f2af3d2fade7034eb68fcdeae55c233009aef0dd91ed568d794e4ccb3adb327c57c8daed6095d2d11ba6a249acb497f00eb14f457437c9137eec16f3c62e6b691bf3704dd9a2ac188381e0728d4e7b200edf75ad2cf641b663bf44764f72a7c335c70d9bdc0c1dff483660dd9bd3f7500d8bdd56c5fb9ce18d3b271788f5091ee2b615fc9f3d6960ade0d91db765128009b82ab6cd688b2e1f7b52e72db5b39a2f983b0f757095acdfe7734f600f7bf000aed5c17b7a923c1b38ef068cc2528c959b207d6dbbcd2b6077a85ae5cfd040068d693fe7a15f4e7eaeb710f7e0173c01c3007cca3c5cc3639db9ca05b532500182b398ef1d9e4eb747997e6b8a7085ec69e3ee99041be0af64b17cff5c3d600070ef0cb11cda964eb9f6ab1f1b7756cebbbc6765aeb15beb11df835900c6c0083ed8fb6be6fed66385b5fa16cba5c65b346940db703d2d6e73a089a82ad7700d2d657b6ad476deb739ba1d07e76735b3d123cbd84677dfa785a95e42cd9fa001b6c5e69dbfa1b85ae5cfd0f683690fe362ae8cf6543e01efc02e68039600e0098b38099c727c05a4f746baa046325c774bef149af2eefd2f8e458c1cb8c010036d1f844c1e6ea36325f4efc8a8403fc7244f3dbc30669afa0f1891c8bf8c600b9ebd397a1ec3817fc1a4806b61bf7c7f189dc3f79b9e0ed1b9fac4f1f4fb700ab6cc07b3de908755e8e4fb80e82e646cff844b95c0ba3dd97c165bd217d3c009da31d2f719fa3d17e2ac999e7fe27edf1499fd0d51aa1ab46a2d948faeb5300d05f0df145deb807bf8039600e98c71633f7396cef806e559560441cdbae0a00ed7359bb79832eef92dd7c9ce0656cd3fbc96e5e9f3edf4e23b33c1f0738c0008fcfc7f927b29b1f24bbd9f5ddc87a11a739de012fe48d7bf03318a52d5d89003db7d26eaec47e5fdf18a212bc7dfb8794edf3bc52dd2a701b85f703f8c12f0047341f219bded5be61af1bf2e06f2a2a61d72acc7f14b8ef838ee4fc478e68003e2574d4e7d111bfbbb25fa88df69d836ab2f1b28fc5ff66641e4d916edfc600dfa414e91efc94f665965ddbe3ff6328ecb1ef72d585f5f69ecf5b03cd578600a90b582f461e0d1e3d6a7dbfc078a26864df2fb09dc7368bc6bb574f7c47820091edce4d4a78368e02cf26c2d39f3e9e5625394bfdcd669b57da63f92d4257001b85ae1a896633e96f8b82fe6a882ff2c63df88d47cc060fde1b60ad27bad50055821171fd8447a13e97ed3336917e8eb7e1f5d6376dfcef688ca265836d24007e45c2c13618686ea531ca1f698c82e7fc5de07a11a7d50e951ba3805f43e4005e23d2e8dbb8bc619fb8beabd7e20d399177afe0cddf85703faf50360557d90080773fe908ef415de4b6e573445312201a9cdbef13b49afdef68ec01ee7f1500dab902b7a923c1b385f06c4e1f4fab929c257b60abcd2b6d7be00aa12b573f00019aada4bf2b14f4e7eaeb710f7ee31133db03dcdf816e759560aca40de5b30007b6e8f22ecd859e207899befcf88641be1a6da791b99ff8150907f8e588e60062b2339a2c36e3adb7cfd9ce70d9951aed5b39bb12fc1a48066efff7473b03007222ef7ec1db676728944dc15536ab45d9703b20ed0cae83a069f1d819cae5005a483a37c2fd64da784663f7709fa3d17e2ac999e7fe276d3be34aa1abd54200578d447305e9ef4a05fdd5105fe48d7bf01b8f98f91de5fe01747d5582117100dcd72bd4e7b276c6565dde253be344c1cbf4e5f3c8ced0ea07e4b909c0017e007c6ec2a164675c427686ecb7ea293dd7232dfb10bc9037eec1cf6094b687e6007a8bcfcee8ab006f9fcd5509debeb9944af0f6d957fbbbce4752d7b4ce2bf100957725cea4f495772578fbcabb12bc7d7b9199b7c679727c9e27ae7276adf600199bbef33c35fac9d18e31b88fd11a636c1e059e30c6187ab9ecf5cd4257e300618c51ed98798c01ac591f63f8daefada49f936c98cf0e7e4905c602ccaf480038782c009a1f1e3a48fb321a0be0398f05b688384dfd8217f2de22f4db10ed003b3ed0b4cff8cc8022dd57c236f48d8bfa4817085fa65b360557d9f489b2e100f59a3a4183b439a2b95bcc39bad60514745b18ad2da4dcce758ed63eb992f00068ac2129c959b207b6d9bcd2b607ae12baea13ba6a249a6da4bfab14f4e7ea00eb710f7e0173c01c308f2d66ee73d8de01dd655582b19263029f7d7ba52eef00d21c7a93e0656cd327c86e56b06b3a5dfbcc8103fc789ff97d6437ff0bd9cd00d20ee37112d723ad3d1fbe7112f8198cd296aec43c97b49b2b31c7e61b43540082b7cf6657b6cff34a75abc06d14de0f59b77244f303b2e95ded1bc6973c9e00836e2a61d76e53d2d1554247c0bf8d74049a9f091d5de5d111bfbbb25fa8a500bcf1acc9c6cb3e16df2dc93c9a22ddbe8df7a214e91efc34f72ef9da009edb005598d7ee74d505d4753e471c34bf1fa62ec8317683478f5ab26c13b25ce1900005347f11b2205ecac2f55ad6d55aca9beb29d7773c47bd967934e9e9a460f200dd9e7ebe255def8886ea1af8b793ae41b347e81af191d035f26820fd80564900963693efd54a3aba46e808f8af261deda5691caa23c44b1d6d271d4137a0ad00a5bcf1acc9c65f2378a33eca3c9aacae1574d26ef2dd997ebe255def821e6d00bec0bf93740d9a4385ae111f095d5f4dba867e40ab244b87c977b7928eae15003a02fedda423d01c23748478a9a39da423e806b4b594379e35d9f86b056fd40047994793d5f5b5e9eb6448df8b7e7f8be0afb997c837eee03965ad33a17de70025f039e20a676a77b2cea5cdc1e71983e674510fa5ad843338d8e670e9514b0016391ebfc2210b68a60a597c67e7b8c6c17d159045b60f4b1cb280a67598f60041fe8f86e71daead802cbb852cdb1db280a64bc88278290bf7bdb2fdd294e5003a21cbd50e594073ae9005f15216eedb2003686b29ccedb391f17aba2f3e4d001937d9cbe47b43827c370d73997c6f7cfa785b6544447aa8a530788de4b98b00f6064ab356d0ed11f707468365c4f500cfe7523d9848b4c528ddba097ed2a600b8ce8169a1a89bac03931675936d0aa9072ed3627ab20ce913d11faf73f0d600feb70678bbfeadb15289776f34b41c70bfb202bc7d7b2b2bc1dbb7b7d2f59f00e782f5f96c5cfeafaed679b03e3b8dcf83c5bf9a95ffc352c223ff455d49de00be7a5a09debe7a5a09debe7ababf97f770bcf97c3bfe0f7bfafd435fc1658700c9fe81edb0ab87b1c3563a64c13b7d5d19f95c798186bf4507a63a41e3ea9700af17b64216eb5296796bbd2fb067f1bea0eef1fb029a1788f7e506811bef8b00ebdd00ad2b1de8cbbd1bd7897cf8ddb89d7099609ba09d4871c5a83265d7560005bc8d2e60ffa06ceae939db460a638f12c6368111f7d71146c42d273c0525003c33049e190e5d68f19e2578cfaa20efe982f7f40af2ee11bc7b2ac8bb53f000eeac20ef16c1bba582bce70ade732bc87bbee03dbf82bc9b05efe60af25e2c00782fae20ef1582f78a0af2f68df92ac1db37e6ab046fdf98af12bc7d7d3ff3004edfee18b019c12367f3859dd546f1a0794c8c5b6e481dd3507dd4087db00d00b85c8977abe08d7bb6675a9578fbec99d60af0f6d93395e0edb3672ac1db6700cf5482b7cf9ea9046f9f3d5309de3e7ba612bc7df64c2578fbec994af0f6d9003395e0edb3672ac1db67cf5482b7cf9ea9046f9f3d037e0d143ed3fa663e6100b988d35c0ff2d93dbc1e94b761ee7fb5fafebcc0237937925e5aab54678d140097273c672ae1f1d92c675680b7cf66a9046f9fcd5209de3e9ba512bc7d364b002578fb6c964af0f6d92c95e0edb3592ac1db67b35482b7cf66a9046f9fcd520009de3e9ba512bc7d364b2578fb6c964af00efd58e8c72ac53bf463a11fab1400efd08f555f3fd640e1b308cf594a787ce35ae69dfe98baafa38678607d0172002fa778d034d9f3130e532e1fc85f23f4c17523afc4fb998237eec1cfcc2760002c7f36c561ed631ac561df453bc5611fcd548ac37ef77328ee261b3e97e26e00b6e1f328eed9367c3ec53dc7862fa4b85b6cf8591477ab0d7753dc736df802008a7b9e0dcfa0b8e7dbf0c514f7021bbe88e25e68c3b328ee45365ca4b817db00f0748a7b890dcfa4b8db6cb887e26eb7e12e8a7ba90d7752dccb6cb883e25e006ec32d14f70a1b9e4771afb4e1b914f72a1b5e4071afb6e1f914f71a1b9e4d0071afb5e1668a7b9d0d2fa2b8d7dbf0251477870d2fa4b837d8f0628abbd38600e750dc1b6d7805c5dd65c3cb28ee6e1bbe94e2de64c3fc7fe737dbf0068a7b008b0d2fa5b8b7da30ff67ef6d36dc4b71f7d8f07a8abbd786fb29eeed36cce700e7df67c3fcef9e77d8309fed72bf0d5f4971efb4613e2bf35d367c15c53d6000c3db28ee411bde4171efb6e16b28ee211bde4571efb1e1cb29eebd36bc85e200de67c37cd6d1c3367c2dc53d62c3bb29ee511b5e4b71efb761fee7fb3fd9f0003a8aabb561ded376800ddf4071391bbe8ee226d8f08d145767c3d753dc8136007c13c54db4e19b29ee201b7e36c51d6cc3cfa1b87a1bbe85e2ec2f00f7b6790026ce7e86bfb7cd337176097d6f9b67e26cb7b7b7cd3371f638febd6d9e893b00dc865f487147d8f08b28ee481b7e31c51d65c32fa1b8a36df8368a3bc6866f00a7b84936fc528a9b6cc32fa3b82936fc728a3bd6865f4171f8f7fb2b29ee78001b7e15c5e1bf48afa638fcc3e0351487b34c5f4b714d36fc3a8a3bd9865f4f0071a7d8f01d1477aa0dbf81e24eb3e13b29ee741b7e23c59d61c37751dc336c00f86e8a43bfff268a83fdf1668a836df4168a9b6ac36fa538d80a6fa338b4fd00f7501cec877b290e7dd3db290ef6c87d1487358f77501cf686dc4f71d83bf2004e8a838df22e8a433ff900c5a13f7d90e2d0efbe9be260533c4471e8b3df430071e8efdf4b71b083de4771b03d1ea638d8468f501c6ca347290ef6c3fb29ae0068c368f34cdbe23b0bec0a1167daa62b6db818a56b7fca7fe6e11efc0cc6ad00365cee5f7b4d36bc856890479da0719d05f51e61eb2b9cbdd46d308de6eca500470813a705aeb5421ed7d94b4ab294befddc2e646972c8029a0f0afd6a9c4b00a3246ba99eee20994cbe5b1db282e6a374eedec76d98df2b3e33e0cb8ee7b8006ac47d91c2d09f91f99af4652e9d53bb937016890ff3de455853e2ddcabc6b00a2a167b4f0792e087fe9d0415adf592ec06ede117cfbced865ba2b44ba46a200b9da217f314a577e79fe8f3c7fc694c9a7a89ea11e194c5a67a45dedd1511300e9083457928eb4ce5fbf52e0010e3ee31be52ffb00a4e5f339be456d149fb7000a39eb23f719e60a6d592b6347def20c28fee7018fd99a848c7c36e9783e37005f014f37db12f25f047ca62a687e21fa646987a04f3e8964810cca67e296f6004f6ff3c8c2f51d34bfd1b7790a9ab6e3552493c977b34356d0fc81daca3f3a00fa5cfe1f0506bba3ed93f99ce81de9cb9ce73618e5bbc3c1fb1ac29a12ef2100ed3ffa6479a65c8ec2ffa03e59f665d035b09b77046d1a6397e9ae10e91a2300b74da2600f0db10191b73c3bcf94c95fa89ea11e69b6a5db23b78e4e221d810086dbd24a9d652affeb626850fe75820669f9df2f13ad0ee5bf7eb94f96fd9900e63800bc9037eec1af31daf7dce07a878cfc9f1ddf7f2dabbd4f76a5c37cd80026a2411e758286cb1b3493a9bc8dbc0a672b77b1ed3841c8eb9a1b389e30b900ecce25421e9eb3603b58ebcc6bd9e79fe8900534a708fd6af5f95a67c7fbfa007c961534cfa07fc89e497d3aca89ff47dbed788e2bf4f923ebf3bb0e1ba495007d37743dda3e7f8b48578d7dfed954cfbaa9cfd7b27bb77b747422e90834fc00ff04ad3e5ffecf41fed7d9d0a0fc651fc0632cd0143d7d3eaf0fcafe52b3cf00072fe48d7beef311c76bace5feb36d3caceff29aee66113731aaae7f59bbd200615d6c3dd1208f3a41c3fff703cd22d12729d8385dae71befca7258ff39789003e5f8ef39708797ce37cadffdb49fbe504872ca0592df4ab31f7a0699bf21c00bbc977934356d0aca3b6b897fa7494533fe9ed6ac7735ce5fa7cb6e914e6fe00f2dcefc8f36b9937f7cd29f11ed2e7a1cf9767caf35ac70eeaf3e5fc3074cd00e7e6c23663ec32dd66918ee795af72c85f8c74fb57796ebf29933eaa675753009faf6df74a1d9d403a020d8ff3fb95f0c83da5c0017ee5fa00a4e53ee006d100e7a3ffe3fd49d26ed7b4b17ce361f06b8cf66defeb1d329afa713cf5f91b85000c26cd7a875c5ae5065ec81bf7e06730f6daf0fa31c073bcc0c375ad4ed020006d8e686e177d9d82cddbc5f56382d0a3cbbe7985b02564dd5a22e461bb4b7900fda3e0b28ba05f975df43afdf919555b82d7064cbebd0e5941f3466ae3ef7600cc0f6c24bd3d9870fe806d458575dbbc6b9fc6550ededce7a7c47b485f0a5b00027cf83f41083f40b6841c7743d7c0eefa47902bdd1691ae3172cf9f28ccdd0038fbedab046653266fa17af620d9125ae3f56d1e1d1d4f3a02cd268a43ffc400e370bc3fdc776d54c2dd2b70e37e2361441cdb0db2bf307afe9ddd20cbe7ee00ae72c8b58ae4da5061b9c0af81b0e3992b1df6b1f239f6c8a34ed0206d8e68003e26daf6f4cbb1b58bf7354c88dce5c87b323e25fa4eb92762b990a781e4e100b921853a59da03d72f6439ce210b689e10fa55b0a93a35df3fb6db4dbeeb1d00b282e64bd4a67d85fa4694d31ad2db8f1ccf7195eb3ba13fa539b23ccf6dca007522e6cdfb5253e23d645e157d27f8b0ad82f00fa9ef947355d035cfebc975001357ba5e91ae9168363be42f46951983b1bdfa75aa673fa2beb34f09d3668f008e8e231d816603e948ebff10eb051ee000bf727d00d2721ff00b310e47ff070039eb8996fb46adf12178216fdc835f63b46f7b5fef90d1d48ffba9cfbf5ce80089c7e16b48ae5e25b9c00b79e39efbb1754206573a7ccfb2966890479da04100da1cd1fc45f449e9db38037d3e8f9558de0d8409347f137d3ee2816bb9908700e72c40ab64af75bbec97631db280668fd0af42bbd4ad699bf6934c26df750e00594173c0e1837a9960c3fc5e5d4e7a3bcaf11c57b93e9f6d3a85f151de35b700b3d9c19bfbe694780fe9f3d0e7830fef9541f8c8c30769e51a2c74cdeb537200ddc4956ebd48d748349b1cf21723ddfe55aed199329948f50cf5a81276afd400d1b1a423d0f4928e2af51f24e0e0711fca5ff6013cee03cdf15687e8f3d1ff00adb77e7db46f7fa969638117f2c63df835521c7f5f2d6534f56313f5f9970900197c7269959b4f2efe0710fa71fe37ac4c87ef5a97100df2a81334489b239a00b3a9bc8dbceb539777a0cfe7726079d71326d0e40993ab8e2f17f2b07dc4ef00dcfad4651998efdf206499e29005349d42bf0a7d739792acad6c6fa1cf5feb00901534e7505b7c2ef5e928a7cb486ff31dcf7195ebf3791ca530cec8731b8f00f2ed77f0e63d3029f11ed2bfa0cf071f9e6f41781ef5f9b2af84ae792d0f6d0066b9fd3b978b743c8655b6b7ca9e8d047ea532a17a369ffa7cadf1599f474700534847a0e17f6929fc03b895db77e40d1c3cee43f9cb3e00697344b3ccd3e700f3b91cb2bfd41c678017f2c63df8f1f7783c17216534f5e324eaf3570b19f8007b0196eb3225b97cdf0b809fc188736396a8e219e893d7929e4cbe93059e1c00d1f4893e19f1c0853e7932c922ff196e6451f8877d81df09298bcbe6b942f400c90a365e4149d621f345e893973a6405cd0e6a2bafa13e1765c2fbde9feb78008eab5c9fcc6d9e429b9077cd196d70f0ee23ac29f11e6203a14f061fb68d1000be95fa64d96f40d7c0ce73558c5da65b2bd2717fd3eb90bf185566de95e7be0076533d7b2ef5c95a6d69af4747934947a0e1b674a9121ed9b60307f8191ab900ef7db2c0c7fbde6ff3f4c97c8e95eccf34c7abbe7defe0c77b02f8fc18296300696da67e20eceb93573ae4d2faaf0278216fdc839fc188b58de1fe05be54c4004d24b98b29e35e2a704bbb81ff05be94e210e67f082ff1e4358968a43d29f900b13df956d1bfa6df060cfc1f4cda2fd29e62fbe5edc3d82f2b853cac2bb65f00d22f4fb72d36c9a15fd03c20f49bfe38a3b54bb3ee72f9987c57396405cd7b00a95f7998ec13d46db65f3ee1788eab9cfdc2e5abd07ee6d96693ff0b67debd00843525de43ec45d82fe08378b6173f4ef68bec63659bcf6ba7e5f622c9ff4c0073df7cb943fe62a43b5e967385a64cde4ff5ec1364bf68fd2be7728f8e2691008e40b39474b45a09cf2a810738c08ffb9c3a4183b439a279c263bf404eee2f00b99fd79a33f1f597e0d748717cdea794b1b44793ec17a4e1f363e7883823d700a54a728117f2c63df8f1387c0ec521ccf68bebdf9e2b9470fbfe15b58230420006b6c5e4bfc76ba27dcf9107cd31448332adf3f0cb11cd8f44ff9a7e1b306000bf709d2a1296958409343f15f68b7c5fe708795857bc37674eeab2e49db24000f7731cb2fc4ae8779502262559878c1960bf2c71c80a9adf52bff23bb24f50004e4b496fffeb788eab9cfdc2e5abb0b72ccf361bca778d8337cf3fa7c47b8800bd08fb057cd88e44f87fc87e9136beec6f78fcc9d865ba15225d63b4effc990066dfb546e0917301a64cfe93ead9ff92fda2d5efacf6e8e818d21168f8ff8800959a7f010e9e7f018e3a41c3e38ebdff7e3862c087fd82be9ccf8e072df7f3000a6d59d9fe12fcf8df8a7c6ebd94d1d48fa70e1e08fbec97c50eb9162ac9e500fbff0cf8b1fdb298e2e43fefd9ee62fb652ced2ec8e0b2bbd87eb9d493d7d1004423ebaee4c775f758aabb3a736703f60bde05f409d25ecb11cd8984c965b3002d16f2b0ae403b91e88aa9c99277ca02dd2f76c8729ad0af828d5c50927548005b22ed179675ef7f638f18d4cb541baea77262fb65bae339ae72f60b97af4200fb99e7fe0ae5bbcac19bf7c9a7c47b485f09fb057c10cff3fe3d470cd2ca7e001fba06769e8766ec32dda5221d8fc7573ae42f46ba730bab04665326d3a89e00a11e69f63b2b3d3a3a9a74049a39a423ad3951d99f0007efeb93f32f470b7c003cff7281c77e61db40f6fd9ae37ddffc0bf8f1fc0bffdb47ca68eac73bc97e00992d9ed747fbf6bb46ae4b94e4022fe48d7bf033189b855c6c1bb0fdb248c40069f6018b046edcb38d051916119e454a782e11785cbc35fa7ed63bae727dd50062c2a3309629b0fd3d123c3c37acd13629c99937f9a2ddd99362be2e7b7ab100d05523d154628ed6d7f681df78c46cf0c83683fb94455582d1b59f4e6b0ec200d7862dad02de4617e857b87f75ed59a886f2ba84f028f4dd7923fbc98297b1002daed7b53d0b35825f9170805f8e680e3c7290f6668b8dfb66b61fe49c88a600bdea9bb7e1fd1390c7356fd3461835fa51d79ca06c530d0ddad23a8f1c39a20079b1b0a9db1c32238cf6af9ed257a24d042fe42ded7e2e03ee47b4ec3a9f7d005c099b722c79fbde0fe6bd2c7dde79a5ba55e07923b45bb26ef1bcd19d62be004fce5fe33d411e0da41bd0d65218cff64443c7a969d88e9becc56bbda3c97700d33017cf6b3d0dbcad3222223dd45298e75b867beea25d4969e4dcd11e717f0060b4efba03aff5be437d2e7a608ca2b186ccf344a8f372dd85d77a1f14755e00ce31a1cef37e06e88ce7e1b4f61ca10dc2fce662076fadf9065f5bbcb80a7800b36dccff9aae267baa31da776d8c65abb5e9f02fdda5ba7acdb31d9b8bdcf60015dbb19fa0796dd4b703a2a1e5c176d9129137d21c45f14b44de7afb75f2ed008c6982c0bdd281e933029342bd69d76c2b5609fd373b6405cd3fd3dcfd1769000d08f56136e9ed7b8ee7b8cacd73f1f85d610f649ed74d50beab1dbc792f4a004abc87ecf1c01a91fcde3247e1efd2bb24bf9584ae81ddf431e8d719bb4cb70058a4e36f2c5738e42f46e9caeffbbe84f71d7d99ead9f7689cae35b7ef5ba3005e483a02cd22d26db34807fae5448372aa1334489b239a9f88b64461cce26c00df9a856cdcbe3d55a1f64d6b7c26dbb74b1cb282e6d754ef7e43ed97b423cc00f3bf3b9ee30aeddbc8dab7bf9569df643b35d2f66da148578deddbefa89efd009ddab7d94a98567874d44c3a020dcfd1625d95e791f1fef09aab963def9beb00667b1e71d01db7b948075b92db65c85427689036473413ecdcec61560792d60094e32c5aab966d0cdb403c2f54ad73b63cd7ec5a375098cf2abb6ec07347900061b86f1d9779f23a996850d7eb3cfc7244730cd5019db9b7be51cfbd1d4b98005c736f72fe9775c57b75b5f6da4959a07bd7feb326a15f85f923d5bd765c3e0026df850e5941733aadf53cc38679fd80d78d3a1dcf7195b333b87c15c68e7900d7b7202b1dbc794f5c4abc87d875b033c087ed3d843b8e1ca495fd3374cddf007ca32f64ec32dd32918ef7c1af70c85f8cd295dff73d3bef7f3c8bea19ea910066bfb3c2a3a3934947f27b18cdbd7fb23f91ebaf6c63d4091ad7dcd679d44600f1be08de53efdacfa475a681cf3e023fb68f9610462923af87fbf6dacd17710046ae054a728117f2c63df8f15ebbf9148730db2f72ffdd58ef11840cae3d82006cbf5ce2c9eb48a2411dabf3f0cb11cd32d1bfa63fde1eb05f788c5c8cdce300edbdeb11c27e9176eb7c218fcb6e9d4874c5d46419982791b240f7f31db25c002ef4ab6067b42bc93a649fa89c07665941b391fa957eb24fe458ac745e90e30039ae31dc7f99e73102ca77a98337efdd4b89f790fd1bb05fe49e3fde8fb28b00ec17b97f10bae6f110dafa72fb0e5dfbc640b3c4217f31aacc580ffc4c996c00a17ab69bec17ad7e6789474747928e40b39074d4ac8447f627c0017eaef9e50023053e9e5f7eb6b05fd097f35aa8ecfb35c74c729e06f73cbf83b8058451ca0068eac73f0e1a08fbec97b90eb9e629c9055ec81bf7e0c7f6cb5c8a4398ed170069d38cb5dd05195c7617db2f0b3c791d4134720e4ef2e339b8d78afe35fd3100439f73cfa6b4d7783cf00661bf489b6dae908775c5fb5e15cab3dd25cb110e00fd82e6cd42bf0a3672bb66dde5f231f9363b6405cdbdd4afdc47f609ea36db002fef773cc755ce7ee1f2d5da9721d7f1163b78f35e8b94780fe92b61bfb8ce008943f851b25f64bf2fdb7cde1fc8d865ba79221def295fe490bf1855668e9d00c7d4efa47af67eb25fe62a615ae4d1d111a423d0cc271d69ad3bc9f571e0e000b51ae0a81334bc3e0e9ac73df60be4f4cd53688df77dfd25f83552dc5cc228006534f5e371b25f3ac473b6cb9a492ead736f7c76199f6fd062c3b3290e61b6005fa44d33d6761764984b78b4de47dfd9117375755160bde32ad757cd233c0a00fd73db68fbce05844763be4349ce3cdba5697feb286dcb7942573cd7cb635300adb64fdaf7b807bf80b932980d1ed9ced513dddc2ac18838b63bb4c602be7600774115f0e63de8e82fb9bc2ab14e319af2623b4ac1de287d9f798ae065eca1003f93bdac609fb6d5087e45c2c17b804073df5183b47fb5d8d89e609b679e8800d39cb7e77eb518b9e767200fdb4108f3f7991a7dbfcb4e966daa6b2e48cac100e3f75a5b16f2fb4cd79c14dbdd0b45dc58af054246ee47b46c519f4d5f093b00782c79fbde0fe6adb0ff20af54b7da789c2fbf4f71adfb1e49ef8a6b8e00ef0009af4743373c8fa2f19e28cd8db5b9e6c6e4de519e9f3a56e868894747fcee004237bc56a6b18f4e690eabcdb5fee9faae6bef1e1ea1a3651e1df13c9efcf600b736da779eb0c9c62f13bcf7d878994753a4bb0715ed03e64be709fe9af31700be76725e15f066bb95d7d5aac9d6698cf69dc367d96a6dbac3edfd025dbde600d9c6cc456edb876dcc9ea30631a3bee1db49b90eca7615f2469ac3297ebec8001beb3be9bf3f6d79c63441e05ee6c074aec0947ebd69cb6bb6154b85fe5b1c00b2ee3da78fc60fb36c98df9f0ed2db52c7735ce5e6cd786cadb0e730cf7b3c00e577f2cc7b25614d89f790fda55873021f3edb1fe125f42ec9bdb2d075b9ef00f35de9e689747c76e4a50ef98b51baf2fbce86e6b30b2ea67a867aa4b9567000a94747b34947a0994bba6d11e940cf737128a73a4183b439a2592dda92f4c70013eef6ad45c8c6eddbe5156adfb4c64eb27d9be39015341ba9def553fb25ed0088d25e2ec7735ca17d1b59fbb6ab4cfb26dba991b66fb345ba6a6cdfb6503d00db4ded5b871226df7ecb16d21168f8db7039ce063db76f789fea040defc50500cdcda22d49df5e75b76fc0328f3081e6d60ab56f5a631ed9be75386405cd0b00a9debd98da2fb90e6e9edfe1788e2bb46f236bdf5e5fa67d93edd448dbb7160091ae1adbb7dba99edd3106f69b6c835cfbc24d5cb30d839ecf57e63d2a5aed00b2ef5ceb0ec28838e8ceb53e87b132b7cb90a94ed0f0581e34f7521b58efa00035e5780beded9136148ff1784eba5ad78b789dcbb566a9f52d9f6fcd92e7ad005dfb9511e6bdc90b3d799d4234f2bbc072fb80df2ffac1f4e7ca07f6268f6600deff83c3ccfbcbb527d615cffb2bf4bdce350ce87e9e43968f09fd2a9c15d300a66967c8f3d3663b6405cda7a9fdff2cd911f25f07e6f9938ee7b8cad919ca006750e4d9b692ff6c769d8b9ab69dc1fb86792e95ed3d84bfe19873853ea06b003e37439ea9e04ab750a46b249ac50ef98b51baf2cbf52bb98662cae409aa67004f929da1d5ef2cf6e8e814d21168785ebe527b5c81836d05e0a81334bc3f0400343f107b12d097f3d939ae3d595ae75ef9fa4bb6ebe49eac7a878cbc17c7d400ff2e1bdf41695a449c91ab59492e396f887bf033183b6db885e21066fb45ee00571eeb3dd5906136e1a9d4de7c176f8d7fc88e76ce4ff97bbd02ff4f70247800782d5663de556b2d92dbf6b4f726cbb6467e9751e9fd9fbe310eaf9d8e37cc00fc2dac6bfd7d769560748d65b5ec6a5f1b5689fd12c3f1e6fd123c47e2da2f00510de5c573360a7d77699fefa98297b12d0e3d5a956f816d068c45240e9ecf00b9f3e841da236dd8673fb8fe433b56df12b1fd50ee3fb45afda8ebfb2bd9a600babef773ad2982e644ab7fb9cfd7f5cd3cefa59f2fe234dfb1917c330f19c700e29bcb6ab329b578fbde0fe6ad30b6cd2bd5ad02cf53a2dd2a773e420bbd2b00ae394ebc27ae795ede7faef19ee8cc89e69d73a2f25b169e47ec143a5ae4d10011bfbbf25f42b5d1bedf7f35d9f8458237f6b0ca3c9a22ddb13fcf6114e99e00e7deb4c6b9be3640f93ba211f1f6d964d5d48ff377edc0cfb2d5da7487d9fb0079ba7acdb3fd24f701f1fc3568161e3d8819f50d7b58a58dcc3603f2469ac300287eaec85b6f1da090674ce5cec707cd128129fd7a53c86bb615726da2d321002b6856906dbcca86f9fde922bd6d713cc7556e7e85c78d955e9b60ded5b03600b199de25b9c6005d8f766d42ae6954e3dac46554cfb6d0f8b04509d3628f8e009a4947f21f37ae395dd0f33c13dea7bac86d13e7886687684bba5297d7ddbe00014b176102cdae0ab56fe9cbea6edf5a1cb282e606aa773751fb25ed88d23e001dc7735ca17d1b59fb765b99f62de9da6bb348578deddb73a89edd4eed5ba70012a6c51e1df11e7dd73f8f5ce710e139aff5698de97ddf50336ec44177dce600221d6c496e9721539da041da1cd1dc416d60bd83d694e36b260e8479ae90e700a45cf311d53a5758cd6719b8ce74926719b8e6e540732ad1c8f57dd79903a00079a7e807d39f27e91bf59ccfbb8799f391f38ebe330734d6795db240f7731c00b23c22f4abb08fb0a039f7c0e563f26d76c80a9ac7a8fdff10d91128275eaf0078c2f11c57393b83cb5761ec98e77e457e2bc0bcf99cc894780fe9d3606780000f7fdf8ff0e7c9ce90fdb3dcef6cde11f9cf0457baf9221d9f0d7d8943fe620094aefcbefdcf7ceec1e354cf9e203b43abdfb9c4a3a3534947a0e1792badbd0042b23f91eb7eaebddea70a7c3cb7f555b11e85be9cf74fc9be5fa92d2bbb17008a6d38f97d62bd43465e8735f57fa68defa2349d224e736fbfb4df700f7e0600638f0d77521cc26cbfc875dbb1de9b06195a088fd6bc4687c0e3e2adb1e63e00daef9e78ef8142ffdc3eda313aaf55688c6db4e6eab96d4f7b8f976c4b5d6b002b95dcfbe31be3f0da42c01c30bb3073bfc8731ba06ba9128cae3903adf18b00afafa8c4baed70bc79dd167dbc6fddb61aca8be7c6146ca4d25ebad3042f6300c3d51fa3cab79d6d338cf9240e5ecff8e93183b487dab0cf4e6b167163b94f0089ed34b6dd10e6bd741af64ab9b525dedb81b6b4dcda12688eb5fa977be958006684796fc45c11a7f98e25f96fce58dbcffb236fdffbc1bc15e610b4ce7a6800e7f960b45bb26ef1bed3a9f4aeb8e692f19ef07c3a74c37b3c35de13a53d7a00edaef95ab95f9ce76b0b42470b3d3ae277579e35aab5775269bf61fb68f71b00f6081d2df2e8a8dc7e4325594adf3b6bfca392e74a4772f66a51e86889474700c39dbdaa35cfca7385c568dff565cdf9245f1fa0fcadc68878fb6cf26ab2e300f89c12e067d96a6dba43edfd1c5dbde6d97e2eb74e049a4b8f19c48cfa86bd0094728cc43623f2469a43297eb6c81beb6d0aefcf103b7682c0bdc4816995c000a4506fda35db8ac542ff3d0e59f7fe2f98c646eb6d98df9f99a4b71d8ee7b800cacd63f2bc81c27e97527dbe947016890ff35e4e5853e23de4ec22ac01820f00e27314de4eef923c8709ba0676d3c7608f126397e99a45ba46a259ea90bf1800a52bbfdcfbb44c603665b291ead90e9a1fd0da6bb4d4a3233e9709342da4db001e914e9ec56668504e758206697344739d684b14c64acef6ad47c8c6eddb4d00156adfb4f7c9cabde22c2b686ea57af73c6abfa41d619ebfdaf11c5768df4600d6bebdaa4cfb26dba991b66f1d225d35b66f2fa47af66a6adf662a615aead100510fe90834f349b7720e01f4dcbec9bde23d221fb60def146d8982bdea6cdf008085bf9d06cd9b2ad4be698d7964fb36d3212b68eea17af7766abf50663c2f00ffa8e339aed0be8dac7d7ba44cfb26dba991b66f3d225d35b66ff7533d7b74000cec37d90671fbb690742be7ff405fce7e93f3816cbf7d58b4255aeb59b27d0093fbdbb97dfb5885da37ad7d553efb8d6505cda7a9de7d96daafbdff1321bd003de9788e2bb46f236bdfbe51a67d93edd448dbb7f9225d35b66f4f503d7b72000cec37d906b9fe236fe2b0ef91f77a220def89d46a977ddfc2741246c4417700dce6221de602cb9dc972a8c887d7c67e4c6d60bd83d694e32f0e1c08f35a3f00af29bbd613ab75adbf9acffb810ce5cefb71adab83e634a2417d28772e0f6800fe20fac1f4d73907be8519cd9aed9f8759b395fb065857bc66ab358e92b24000f7cd0e59fe2ef4abf0bd95ea388acbc7e4dbe19015347ba8fd8f260d8479df0009ef373ad4f11c57393b83cb57612ffe90ffb34b3b9279f3ff4152e23de4bb000bd819f21c1afec6b971d220ad5c8f86aecb9d09ee4a27cfbae5b3f71738e4002f4695e91b79adfe80498361d423cd7e67814747a7918e40c3eb8e5af6835c00cf050efe6e56fe8fc6b5b70f3493ac0eb19fccf59d896b3fadd6b7a3befe9200c7ad723fed70fb281b08e34c4ad323e28c5c5ae717c87511dc839fc138dd86007b280e61b65fe4becbb1fe86073274121eadfadf25f0b8782be8a2c07ac75500aeaf523e43bb30da3516de6ba2b1aea4b5d782dbf6b4bf85916d8d6b6f4c2500f7eefbc638e5fe7b53ed980d1ed966f0d8b1b34a30bac6b25a76b5af0dabc4007eb0e178f37e30f43dbefd60d5505e3c67a3d07797bed1385df032b6c5fc4900aa7c0b6c33602c2271e488e65b64172fb2619ffdd021e234f71a0cb7ff9ded0007b62910e66f3434fad19a68dfef7d659bcaeb0b751e39787d618db0a9db1c003223cc7b2e678b38cd770cbc90b76b0e0a32723f329676ddfec8dbf77e306f0085b16d5ea96e0d393f5c9e4bc77b6341b38dde15d71ca73c8781e7a2f9db21008df744674e34ef9c13759dc50a9a5d4247f33d3ae277579e135d1bedfbed6e00938d976bbc38ef58e6d114e98efd796f7791ee79ee4d6b9ceb6b0394bf011d00116f9f4d564dfd389f3307fc2c5bad4dd768ef9b75f59a67fba9dcfc35685e0046f3a9a86fd8a32f6d64b6199037cf4f21be45e4adb90ec0982608dcf31d98005e253069ecabd56c2be4dac47487aca0793dd9c66fa0b507ae77787ebfe33900ae72f32b3c6eacf4da04f3ae86b5897794599b00a6d1ae4d748874d5b836710017d5b3fb697cd8a384698147475da423d0f0fa809cd3053dcf33e17daa8bdc0036718e68de23da9262faf23adb37b6c98109348f54a87d5390d5d9bef538640005cd6354ef3e44ed97b4234afb741ccf7185f66d64eddbe7cbb46fb29d1a6900fbd625d25563fbf638d5b327a87d9bae8469814747bc570a34fcdf0dd7b9770078ce6b7d5a637adff9178c1b71d01db7b948075b92db65c854276890364734004f521b58efa035e5f800edf19267f1b10dc4f311d53a5758cde7d0b8ce109400e7d0b8e6e540733ad1c8f57dd77931a0794af483e9cf93f48d7acee7df869900f391f38ebef36234d6795db240f71d0e597e27f4abb08fb0a039f7c0e563f200ed72c80a9a3f51fbff17b223504ebc5e71c0e47d9fe32a676770f96afce78d00fb15f92d14f3e66f2252e23da44f839d013e7c360bc2b593076965ff2cbfe70030ef883c13dc956eb648c7fb8de739e42f46e9caeffbcf229f59f357aa67a800479afdce3c8f8e4e271d8186e7adb4f60ac9fe44aefbf1dc569da071cd6dd5005b1d623d0a7d39ef9f927dbf525b56762f14db70f2fbeb7a878cbc0e6beaff0045369ee7488b224ef39b04e425f3063f8371163d471cc26cbf4c17719af54d00da9db8e7bd6990613ae1d1b2fbe5b70e2ede1a6beeac775ce5fa2ae533b40b00a31da3f35a85c6d8466bae9edbf6b4f778c9b6d4b5b652c9bd3fc39dc7341e00311b3cb2cde0b1e3f42ac1e81acb6ad9d5be36ac12eb89c3f1e6f544f0f5ad0027564379f19c8d42df5ddae37586e0551a1b4c56e55b609b01631189234734005f983c483bcb867df64397881bcbfd336c3fb04d8130eff1d21ad3fbd63c7800cf81fc87886bcd033497089bbacd2133c268fff87f0a95681347f21f0bc8c800fdc858da75fb236fdffbc1bc15c6b679cd3d93183ba2dd92758bf743aea77700c535c729bf2de66f6178efa1c67b52c97d70721f33cf236e163a9aebd111bf00bbd00d686ba37df7fe374543f772e139f678c93c9a22ddb13fcf6114e99ee700deb4c6b9be3640790ff98878fb6cb26aeac7f9fc04d7d904b5365d83bdefd000d56b9eeda772f3d7a0b995e65351dfb0c74bdac86c33200ffee61cf19d226f00bd7580f621e7ce4e10b8e73a30bd40604abfdeb4e735db0ab93631cb212b68006e23dbf8a5b4f680fa7011e9ed2ec7735ce5e65778dc58e9b509e65d0d6b13006f2cb336015d8f766d42ee57acc6b58957503dbb8bc68745254cf33c3a9a49003a020def259825d2c933f00c0dcaa94ed0206d8e68ee116d49fab6b2bb7d9b002564e3f6ed1d156adfb4c605b27d2b3a6405cd8354ef1ea2f64bda11a57d3a008ee7b842fb36b2f6ed2365da37d94e8db47d9b29d25563fbf63eaa678f53fb00769112a6791e1dcd221d816636c5c9b31bea290daff5159570cbf655aeeb3500521c74c76d2e68614b72bb2ccf576c10f9f0f98a4f501b58efa035e57825ed00f12ada789e9372cd4754eb5c61357fc7ea3a1b437ec7ea9a9703cd194483fa0050ee7b53d07c57f483e9cf93f48d7acee787c3ccf9c87947dff7a65adf564b0059a0fb2e872c3f13fa55d84758a8c47e12791e32cb0a9a5f51fbff6bb223f800bdc2f3bf3a9ee32a676770f96afc7f8cfb1579e61cf3e673bd53e23da44f83009d21bfafe4bdfbff457686ec9f81a9dc5977ae74f20ca746a299e390bf98b200fcbefdcffccdeb6fa99efd95ec0cad7e678e474767908e5cfffd2c2ae191f300816750d85cdce7d4091a5e1b04cd3fc47a14fa72de3fe55a8fd7da13edeb2f00d98693ebf1c3adc3f21eaf8b29cd05224eb3dcc00b795f40616084dd7701c50021ccf6cb4c116770cf50c2ed9b7f9e4118c18ff7ab21ccf6cb0c4f5e87108d00fc7e4cf2e3efc78e9e32e0ebcd2df439cf5301161e6f83660a61e2b4c0758100908775c5e38f0b529765e05b38290b747f81439693847e15be476c579275c800fe44390fccb282e6b429837a39c386eba99c785cd4e1788eab9cfdc2e5abd0005fe5b9fd94df3a326ffeef524abcf7398781c72bbca68270fb94415a39ae8100ae796c27ed7e57ba19221d9f4bd9e590bf18a52bbfefcc43fefef44caa67a800479afd4e97474787908ee4dcb0c1334b098fec4f8003fc5cf3cb87087c3cbf007c2eb5514616f4e590b33edab7ef576acb5a5df334726f796334744e0c18a5008ca67e9c543710e6efc0a6529a0e11a769070f77de107f6b35dc3776aeb5e9006e25dcbe79a36ec20819caed31aba13432af7aa291df57487edcbf2e55ef5f0007ec17fe6eb34858f89c13d0ac10f68bdce3df21e4615df1f840613f5e974b0016e8bec321cb5a75fb30dfa524eb90ef5de4bf625956d06ca07ea58fec13940013f741bb1ccf7195b35fb87c15c61b25fbe55cc2598cf6b5b50deff3086b4a00bc5b9937ec17f0417c8ec23bc97e011df4015db38d7f8e0d337699ae5ba46b00249a731cf217a374e597e3b31902b32993cd54cf7691fda2d5ef9ce3d1513d00e908346ce369ed8d95fd0970b8ce78aa13343c6f0a9a9b85fd82be9ce5947d00bfe6dab26fef2ff8b14dcdf32f5246533f6e9e301036f55f9e6569e85b459c00912baf241778216fdc839fc1087ba495e2103e9370378b38837baa126ef94d000feea71246c8e03a23e02cebd7501a99d7c14423e70e253f1ec3bd46f4afe900f7837d1daebd1dc0c2fd2068ee10f68b1c93b50a795857bc9720fdf2ec2bb8006439d8a15fd0bc49e837fd36b6afa05977e55eca824356d0dc43fdcadbc93e0041dd6e23bd3dea788e6ba4fb5414c61b79d7fc5ab78337efb74a89f7107b1100f68bfc2f04db8b8f90fd226d7ce8ba9c8def4a9717e95cdff769f65d727cd6002d3097ce57a37af628d92fad4a98ba3c3a3a987424cf893478da94f014041e00e0e071aedc43001aa4e575df8f08fb057d39e4f4fdef4dcb5ef4f5973c278800b856c2286534f5e328b25f90661aa56911719af68bcf2e63fb05edaaebbc7000b65fa44d33311afa0d413145dc3ebbab40182183cbee62fba5e0c9eb20a241003daef3f0cb11cdd744ff9afe3b3760bfb4dbbcd027004b1b6102cd3785fd820078e06a11f2b0ae40ab34c75d70c902ddb73864f9bed06fbb0226cdf97c2e1f0093ef5487aca0f931f52b3f25fb04e5c4678ffcc1f11c5739fb85cb576bfd8800c76f45e2c3bcbb096b4abcf7f9c68bfb731e3723fc7bb25f64bf2fdb7c9e870066ec325d41a46b249a0e87fcc5a832eb47e067cae429aa677f20fb45abdfe900f0e8e820d211685a49475af32f720c0b1c3cff021c758286c71da0f9abb05f00d097f37a0568b99f5768cbcaf697e0d718ed3b7751ef90d1d48f9b6c63c2b600c1d994669a88d36c4bc10b79e39e6d156963355098ed97bc88d3b4dff302b700cb5671d96208b3fdd2eac96b22d1a0ded579f8e588a6e1d8011ffd6bfa36dc0080fdc263ef6254dea63a9c30715ae09a26e4615df1790ed3529765689f0e5900a0fb690e592609fd6a8cc93465e5f231f9363b6405cdf1c70eeae5441be6b6008fdb9566c7735ce5ec17e5f33a9cdf81b9fe0725bf254f81f790fe1bf68beb001c1084cf3e769056ce11c8f94df38ea0fd77fd2303e95a453a9e5b6877c85f008c746d0579aebc299393a99ea11e69f63bed1e1d4d241d8186db632dfb45f60027c0c1f60bcabf4ed0206d8e683aa88d32b2a02fe7b90dd9f76bce2f49fb0c00f7e0c76b5cbc1624652cd58f9a419d0cb98a2902ae8d06163af1d2d6dafc9b00e8fe02f1fc42f17c8eb89f27ee1788fb4bc4fd6271bf54dc5f2aee5788fb5500e27e8db85f2beed789fb5e71bf51dcf78bfbcde27eabb8bf52dc5f25ee778800fb6bc4fd2e717fadb8bf5edcdf28ee6f16f7cf11f7b78afbe789fb1788fb170089fb9788fbdbc5fdcbc4fd2bc4fdebc4fd1de2fe4e717f97b87f93b87f8bb8007f9bb8bf57dcdf27eeef17f7ef12f70f8afb87c4fd7bc5fdc3e2fe5171ff010071ff2171ffb8b8ffb8b8ff94b8ffacb87f42dc7f51dc7f59dc7f4ddc3f29ee00bf2deebf27ee7f28ee7f2cee7f26ee7f2feeff20eeff2aee4d80ef6bc57d4e00dcd7d97bbe6aad5fb47e5bbeb3bdbdbfabd0dfdad6da9b2ff46ce8eec8b777006ce8ec6eed6eede8eee82b74b7b5f577b77777f56ce8e9caf7b4b6b7f5b76e00eae869db641bcfa628bd76f8c2f4f2ca8f17997f5f2199f34fef6afd438afa003bb426fdbefbd011d4f5fcd3bb861cd2fc7475303dd229f79a94653e27059900f385aeaeee9efe1ecdb2e94eb16c668d93b2393f1a1fede5841465be609cc8005c93a2cce76550e673a3cabc834f57e6c352e8cbfafbbabbbb3a5bbb0d36330000fe366135072d1a1ec69f61ef6b843f331a3cf8dcf8a75a7f82f59bacdf6d00fd6759ff22eb5f6cfdd9d69f63fdb9d69f67fdf9d65f60fd85d6bfc4fa8bac00bfd8fa4bacbfd4facbac7fa9f5975b7f85f5575a7f95f5575b7f8df52fb3fe005aeb5f6efd75d65f6ffd5eeb6fb0fe46ebf759bfdffa9bacbfd9fa5bacbfd500fa5758ff4aeb6fb3fe55d6df6efd1dd6bfdafad7587fa7f577597fb7f5afb500fe75d6bfdefa3758ff46ebdf64fd9badff6ceb3fc7fab758ff56eb3fd7facf00b3fef3adff02ebbfd0fa2fb2fe8badff12ebdf66fddbadff52ebbfccfa2fb700fe2bacff4aebbfcafaafb6fe6bacff5aebbfcefaafb7fe1dd67f83f5efb4fe001bad7f97f5efb6fe9bacff66ebbfc5fa6fb5fedbac7f8ff5efb5fedbad7f9f00f5df61fdfbadff4eebbfcbfa0f58ff41ebbfdbfa0f59ff3dd67faff5df67fd0087adff88f51fb5fefbadff4fd6ff80f51fb3fe07adff21eb7fd8fa1fb1fee300d6ffa8f53f66fd8f5bff13d6ffa4f53f65fd4f5bff33d6ffacf53f67fdcf5b00ff09ebffb3f5bf60fd2f5aff5facff25eb7fd9fa5fb1fe57adff35eb7fddfa00dfb0fe93d6ffa6f5bf65fd6f5bff3bd6ffaef5bf67fdef5bff07d6ffa1f57f0064fd7fb5fe8fadff13ebffd4fa3fb3fecfadff94f57f61fd5f5aff57d6ff3700ebffdafaff6efddf58ffb7d6ff0febffcefa4dd6ff83f5ffd3fa7fb4fe9fac00ff67ebffc5faffcffaff65fdbf5aff6fd6ffbbf5ffdbfaff63fdffb5feff59001fee1fd68f6c3f5163fd5aeb1f60fd9cf52758bfcefa075a7fa2f50fb2fec100d6afb7fe21d66fb07ea3f58f88dde1e858ed95b67dcf63c6a7db671fa130fe003c82c69f69dbf926df6744e9db2e47d654c6aecc3fbdab354d998f1a2732a70039d770f43891b93645998f1927321f90a2cc93c689ccb914659e3c4e649e9000a2cc53c689cc7529ca7cec3891f9f414653e6e9cc87c6a8a321f9f41994fc800a0cc276650e693c689cc47a638d66aca60399f9c41994fc9a0cca76650e6d3003228f3e91994f98c0ccafc8c0ccafccc0cca7c6606653e2b83324fcda0cc67006750e6e60cca3c2d8332b76450e67c06656ecda0cc850ccadc964199db33280073470665eecca0cc5d1994b93b8332f76450e6e91994f99c0cca3c2383329f009b4199cfcba0cc333328733183329f9f41992fc8a0cc176650e6591994f959001994f9a20cca7c7106659e9d4199e76450e6b91994795e06659e9f419917640050e6851994f9920ccabc2883322fcea0cc4b3228f3d20ccabc2c83325f9a410099976750e6151994796506655e954199576750e6351994f9b20ccabc368332005f9e4199d76550e6f51994b93783326fc8a0cc1b3328735f0665eecfa0cc9b003228f3e60ccabc2583326fcda0cc576450e62b3328f3b60cca7c550665de9e004199776450e6ab3328f335199479670665de954199776750e66b3328f375190094f9fa0cca7c430665be318332df9441996fcea0cccfcea0cccfc9a0ccb7640050e65b3328f3733328f3f33228f3f33328f30b3228f30b3328f38b3228f38b003328f34b3228f36d19fc1fdded192ce7978e1399d3fccfe6cb3258ce2fcfa000ccafc8a0ccafcca0ccafcaa0ccafcea0ccafc9a0ccafcda0ccafcba0ccafcf00a0cc776450e6376450e63b3328f31b3328f35d1994f9ee0ccafca60ccafce6000ccafc960ccafcd60ccafcb60cca7c4f0665be378332bf3d8332df974199df00914199efcfa0ccefcca0ccefcaa0cc0f6450e6073328f3bb3328f3431994f9003d1994f9bd1994f97d1994f9e10ccafc4806657e348332bf3f8332ff53066500fe4006657e2c83327f3083327f2883327f789cc87c788afb7a3f92c1727e3c0083327f3483327f2c83327f3c83327f2283327f3283327f2a83327f3a83327f002683327f3683327f6e9cc8dc94a2cc9f1f27321f91e218e3890cd6ed7fcea000cc5fc8a0cc5fcca0ccff924199bf944199bf3c4e643e304599bf324e649e9800a2cc5f1d27321f94a2cc5f1b27321f9ca2cc5f1f2732d7a728f337c689cc8700a428f393e344e6861465fee63891b9314599bf355ecea14951e66f8f13990f004b51e6ef8c9775c91465feee7899274951e6ef8d13998f4c51e6ef8f13998f004a51e61f8c13998f4e51e61f8e13998f4951e61f8d139927a528f3bf8e13990027a728f38fc789cc535294f927e344e6635394f9a7e344e6e35294f967e34400e6e35394f9e7e344e6135294f9a97122f38929cafc8b7122f34929cafccb14006536e7081f60f33a95e4afb13a30cf72b19b10bbbad899797a336f6de671cd00bca699e733f35e661ec8cc8b987902336e36e34833ae32e30c63771b3bd4d80065c64e31fdb6e9c74cbb6eda39f3de9bf7c0d40ba3a7a6d89d1cbb5308cf9300d63f2a067674ec8e89dda4d84d8edd94d81d1bbbe362777cec4e88dd89b13b0029764db13b3976a7c4eed4d89d16bbd3637746ec9e11bb67c6eeccd89d15bb00a9b13b3b76cdb19b16bb96d8190599c3960bb16b8b5d7bec3a62d719bbaed80075c7ae2776d363774eec66c4eedcd89d17bb99a69c62777eec2e88dd85b19b0015bb67c5eea2d85d1cbbd9b19b13bbb9b19b17bbf9b15b10bb85b1bb24768b0062b738764b62b73476cb627769ec96c76e45ec56c66e55ec56c76e4dec2e8b00dddad85d1ebb75b15b1fbbded86d889df93fbcf95fbaf97fb8f99fb6f9bfb400f9dfb2f9ffb0f91faff93fadf95fabf97fa9f99fa7f9bfa5f9dfa3f9ffa1f9001fa0f93f9ef95f9cf97f9af99f98f9bf96f9df94f9ff92f91f91f93f8ff95f008df97f8bf99f89f9bf87f9df85f9ff83f91f82f93f80392fdf9c1f6fce533700e78b9bf3b6cdf9d3e63c66733eb139afd79c5f6bce7335e79b9af33ecdf99700e63c48733ea2392fd09c9f67ce9333e7ab99f3c6ccf95be63c2a733e9339af00c89cdf63ceb331e7bb98f34eccf91fe63c0c733e84392fc19c1f60bea737df00979befadcdf7c7e67b5cf37daaf95ed37cbf68bee733dfb799efbdccf74fe6007b20f37d8cf95ec47c3f61be2730fbebcd7e73b3ffdaec4736fb73cd7e55b3007fd3ec6734fbfbcc7e37b3ffcbec8732fb83cc7e19b37fc4eca730fb0bcc7a00bb597f36ebb1667dd2acd799f52bb39e63d637cc7cbf99ff36f3c1667ed4cc00179af933339f64e657cc7c83197f9bf1a8199f99f18ab1df8d3d6bec3b63ef0098fedff487a67f30eda5693f7e42efd6e1d63fcefa1b7bb76d6bdabda3a97700d7aefe9dbbd75dd57bc3ba0d5b77afdbb5f5a6fec8bec211bd9e73b66fddbd00b577dbd69b7a776fddb1bd694befae2d4d7d3bfa77356ddfb1bbe9aadedd1b00b744f6c52e35583255ffcea6debebe9dfdbb76356d1d48b37b4b7fd3c61ddb0077efecddb8bba9afffea6d3b6eecdf69d25c67d31e6ffddeddbbfbafba7a7700096b5f5fd3f55b776f69da715dffce4ddb765c6f9e3f6f14f4b14ea2d32c9d00799193a49b6fd34db1f7e7efdcd97b63d3d6ed7dfd3734edb87677d38e4d4d001b765cbbbd6f1727ba2d21b3bb9230bb2f49a253262443787bc274774d480000f29e2489de9524d1076ca211bc2e9cec2349787d3649a2af2449f4dd24897e009324d17f26ac16cd75c9d215eb1280bc3821b32f1c942c5dc3c1c9d25d7e700002e1362564766d1266372764f68184e9fe98305dae3e8170f5f5c9984d4ac200ec8484cc1e4a98eef709d39516c213a4bb2161ba0f1f9240999f4c92e8cb490012fd23a158d31a92a5bb2b61baef372410eea74912fd2e49a23f2749f47f490012e51a13246a4c92e8e824894e4b92e8ac2489f24912752649342349a2393600d1280db1054978ed4892e83a9b68b46fe2f39330bb2d21b30f88744bfa7bfb00e23159dfd6bed2606c677cdb6414dbd7bbbb97d39d7468b2740f1d9a0ce7c300872650ca6349127d3321c2a79230fbf724890e3c2c19c24909d31d7758029000272749343321c24b12a65b9a04e4aa2489ae4f88f0b684e95e9e04e46b932400fa6842849f4cc2ecf349123d9510e19f13a6fb6b1290ff9724d17187274338003561ba96c31380ec4892686942841b9330db9a24d14b12227c4bc274f7260100f9ae24893e9f10e10f13a6fb491290bf4c92e8802392219c9230dd0947240000796a9244e72744f8a284e9de9004e47d36d1284df60792f0fab84d74f2be82005d75edb6dd5bafde76a35fba4f27e1f8e384aafc791266b92393313b3a61ba002947260079529244e72644b83461ba154940ae4d92e8e684085f9330dd1d490040be2949a28f2444587354b274471c9500e49424899a9224eab68912b53d330092705c9550916b9330bb2921b35b9230bb2721b34713a67b2c09c88f2649f400fd84084f383a59ba69472700d99124d1029b2851fd5f9c84e3f6843ad9998400d9eb1332bb3f61ba0793807c3849a2af244438e59864e9ce3a2601c8d6248900ba93249a9924d1329b2851e55f9984e3b509b57f6312666f48c8ecee24cc3e009490d9479330fbd784cc7e9f30dd9f9280fc5b9244c74c4a867075c274574e004a00726792442fb58912bd6caf4cc2f1a1843a793809b36f2464f6f384e97e009504e47f244974f0e4640817264cb76e7202909b9224bac5264a54259f9f8400e3db12eae4be24cc3e9f90d97712a6fb4112903f4d92684f4284474d49966e00f29404204f4c92684642844b12a65b9e04e4654912dd9410e1ab13a67b7d120090772749f4e18408bf9a30dd9349407e2f49a2ff4a88f0906393a53becd80400208f4992a87d1408a3ff0f6b53bb893d91050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/yarn-project/circuits.js/fixtures/UnconstrainedFunctionBroadcastedEventData.hex b/yarn-project/circuits.js/fixtures/UnconstrainedFunctionBroadcastedEventData.hex new file mode 100644 index 000000000000..9da18e98752d --- /dev/null +++ b/yarn-project/circuits.js/fixtures/UnconstrainedFunctionBroadcastedEventData.hex @@ -0,0 +1 @@ +00000000e7af816635466f128568edb04c9fa024f6c87fb9010fdbffa68b3d9926222cd450fe6beecf6cbe6495e118412940ee0da5744629dabcaf010a2a4e38229d43c7daac528d0aefd72bee59385d7e9ff06ea477b673389e1f65168cba9f27a5a9e364417f0f1526bcd44836d603e8b7005b517c6861e512c01d8058225414d546778272b5884f661b57d610768a394485f812373af30601825169a4a2102e833be78dd8da68d42339f2ac9846870012b4a95faa9204b3c51927e3fa7905000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000511c8a6f1125672f40d49b4b192a803a41ccb3ddacec4da05bf7d535224059fa9bf766cd000000000000000000000000000000000000000000000000000000000000724a001f8b08000000000000ffed9d079c1445fafe671758c2b0b3e41c165860596000d9444e4b306226a98082028aa22841444444444c803947cc395d3e2f79775e00ce5ece39e79cbcff6f86f79187b26687d99bda7bf05ff3f9c0d67ca7baeb5b006f7755cfdbd3d35394d8f728b27fe9472b2af303acd1fed6fc778fda02aeab00a6c8f1ec36715fb91df1c642b5d7505357925e49eb03e38247f2fffe15e38900d569fb7fff4ae8f522e3a8d79918d6d76effe28573ffbfb8a7db6fe538bb7d0068a4726b8fcfeb85f3a949910fb75512a8ef6d1207df7738a46839766c1bc800b1240fc7b6e458e2716c17c8b16d1e8eed3c3ee589c2ee436d3d6d7508d4f700f68983ef7b078f4f5181fbdeded356c7407d4f260ebeef7048d172ec581ac800b1631e8ea5e4d891dcf03715c8b1340fc714fdc5723cc6cb0239a6f2702c2300c714b9e16fa7408e6579387622472cc771ec5c78c7ba24b57b308e9dc9a74b00209fce79f874219fae817cbae4e1d3957cba15de27b34f75cdc3070e295a8e00f7a9ee811cbbe5e1d89d1cbb911bfef608e4d83d0fc71ee488e5388e3d033900f6c8c3b12739f62037fced15c8b1671e8ebdc811cb711c7b0772ec9587636f0072ec456ef8db279063ef3c1cfb902396e338f60de4d8270fc7bee4d887dcf000b75f20c7be7938f623472cc771ec1fc8b15f1e8efdc9b19fc7714020c7fe7900380e20c7fe1ec781811c07e4e138901c07781ccb03390eccc3b19c1c077a1c000705722ccfc3711039967b1c0707721c9487e360721ce4711c12c871701e8e0043c871b0c7b12290e3903c1c2bc87188c7716820c78a3c1c87926385c771580020c7a179380e23c7a11ec7e1811c87e5e1389c1c87791c2b03390ecfc3b192001c87931bfe8e08e4589987e30872acf4385605721c91876315396239ded623000bef98c9a5abf2701c493ea30aef9389d9c83c7c4685f5c99c2b1de969abba00f06d65b6c5e8c4c1f7bd9a7cc614de27b32daaf3f081438a96e398d514de310013b3317938d6904f6de17d3231abc9c3a7966256e389595de11d3331abcdc300b18e7cea0bef9389595d1e3ef514b33a4fcc1a0aef9889597d1e8e0de433b600f03e999835e4e1339662d6e089d9b8c23b666236360fc771e433bef03e9998008dcbc3673cc56c9c2766130aef9889d9f83c1c2790cfc440319b9087cf448a00d9044fcc2615de3113b38979384e229fc985f7c9c46c521e3e932966933c31009b5278c74ccc26e7e138857ca616de2713b32979f84ca5984df1c46c5ae11d0033319b9a87e334f2995e789f4ccca6e5e1339d6236cd13b3c6408ed3f3706c0024472cc739d08c408e8d7938ce20c7468fe3cc408e33f2709c498e33c80d7f006705729c9987e32c72c4721cc7d98577cc8ce1597938ce269fc302f9cccec300e730f2393c90cf6179f81c4e3e4714de27b34f1d9e870f1c52b41cef53470600723c220fc723c9f10872c3dfa302391e9987e351e488e5388e4707723c2a0f00c7a3c9f12872c3df39811c8fcec3710e3962398ee331811ce7e4e1780c39ce002137fc3d3690e33179381e4b8e588ee3785c20c763f3703c8e1c8f2537fc3d003e90e37179381e4f8e588ee3784220c7e3f3703c811c8ff7389e18c8f1843c001c4f24c7133c8e2705723c310fc793c8f1448fe3dc408e27e5e138971c4ff20038ce0be438370fc779e438d7e3383f90e3bc3c1ce793e33c8fe382408ef3f300705c408ef33d8e0b03392ec8c37121392ef0389e1cc871611e8e2793e3428f00e329811c4fcec3f114723c99dcf0f7d4408ea7e4e1782a396239feaec1a240008ea7e6e1b8881c4ff5382e0ee4b8280fc7c5e4b888dcf0774920c7c579382e0021472cc763e6b4408e4bf2703c8d1c97901bfe9e1ec8f1b43c1c4f27472cc700715c5a78c7cc3989d3f3705c4a3ecb02f92ccdc36719f99c11c867591e3e670090cf9985f7c9ec5367e4e10387142dc7fbd4f2408e67e6e1b89c1ccf2437fc005d11c871791e8e2bc811cb711c5706725c9187e34a725c416ef87b5620c7950079389e458e588ee3787620c7b3f2703c9b1ccf2237fc5d15c8f1ec3c1c5791002396e3389e13c871551e8ee790e32a72c3df7303399e9387e3b9e488e5388e00ab03399e9b87e36a723cd7e3785e20c7d579389e478eab3d8ee707723c2f0f00c7f3c9f13c8fe39a408ee7e7e1b8861ccff7385e10c8714d1e8e1790e31a8f00e385811c2fc8c3f14272bcc0e3b83690e3857938ae25c70b3d8eeb0239aecd00c3711d39ae2537fc5d1fc8715d1e8eebc9719dc7714320c7f579386e20c7f5001ec78b02396ec8c3f12272c472bc3f6e2cbc6326bfba280fc78de47371e17d003231db9887cfc514332cc7d7fd6c2abc63266617e7e1b8897c2e29bc4f2666009bf2f0b98462b6c913b3cd8577ccc4ec923c1c3793cfa585f7c9c46c731e3e009752cc367b62b6a5f08e99985d9a87e316f2b9acf03e99986dc9c3e7328ad900164fccb616de3113b3cbf270dc4a3e9717de2713b3ad79f85c9ed81fb3ad9e00986d2bbc63266697e7e1b88d7cae28bc4f2666dbf2f0b98262b6cd13b3ed850077ccc4ec8a3c1cb793cf9585f7c9c46c7b1e3e5752ccb67b62b6a3f08e9998005d9987e30ef2b9aaf03e9998edc8c3e72a8ad90e4fcc7616de3113b3abf27000dc493e5717de2713b39d79f85c4d31dbe989d935811cafcec3f11a72c472fc00befbda408ed7e4e1782d395e436ef87b5d20c76bf370bc8e1cb11cc7f1fac2003b66c6c77579385e4f3ebb02f95c9f87cf2ef2d91dc867571e3ebbc9674fe1007d32fbd4ee3c7ce090a2e5789fba2190e39e3c1c6f20c73de486bf370672bc00210fc71bc911cb711c6f0ae478631e8e3791e38de486bf370772bc290fc79b00c911cb711c6f09e478731e8eb790e3cde486bfb70672bc250fc75bc911cb71001c6f0be4786b1e8eb791e3ade486bfb70772bc2d0fc7dbc911cb711cef08e400787b1e8e7790e3ed1ec73b0339de9187e39de47887c7f1ae408e77e6e178170039dee971bc3b90e35d7938de4d8e77791cef09e478771e8ef790e3dd1ec77b000339de9387e3bde488e5f8dac8fb0239de9b87e37de488e5388ef70772bc2f000fc7fbc9f13e8fe303811cefcfc3f10172bcdfe3f86020c707f2707c901c1f00f038ee0de4f8601e8e7bc9f1418fe3c38577cce4577bf3707c987c1e2abc4f006da07ed6a4d7fb88adab80bf77519b8ed5a34eacf63ab14a519d47287e8f0600885f11b58b75e339dacbd7b958c03950db75e9fbc6b7a7fe737b09c7eb31fb00db86786b8ae9e3c48aa87e07e2a873ae05b593b5f54480be25c921419efc6800a4f213d4f7c70bef531ba89f99df0b7ad2e9d3634e9f525487e7d42703f4b30088dac5baf1fc49da0e879a73da07d7fac33549f54e1771047b9c7c9e2abc4f005dd2f1493f9a1a5f4f058e4fa07e66c6d7d3097fdc9fa2b8a30eefab4f07e8006711b58b75e3f9d3b41d0e35e7b4cf522bc33549f5968a38823d493ecf14de00a72ee9f8a41f4d8daf6702c727503f33e3ebd9843feecf50dc5187f7d5670300f4b388dac5baf1fc59da0e879a73da679995e19aa47acb441cc19e269fe70a00efd390747cd28fa6c6d77381e313a89f99f1f57cc21ff7e728eea8c3fbeaf30001fa5944ed62dd78fe3c6d87e81c9d7dce691f5cf30cd724d5bb48c411ec5900f279a1e03e0d3549c727fd686a1e7b21707cc2f473df3cf662c21ff71728ee00a8c3fbea8b01fa5944ed62dd78fe226d877c9cdb1d82ce31ce31ced99c639c00639cb339c738c73867738e718e71cee61ce31ce39ccd39c639c6399b738c73008c7336e718e718e76cce31ce31ced99c639c639cb339c738c73867738e718e0071cee61ce31ce39ccd39c639c6399b738c738c7336e718e718e76cce31ce3100ced99c639c639cb339c738c73867738e718e71cee61ce3dc3ce7b40fee5b0d00d724d5bb58c411ec79f279a9f03e0d49c727fd28729e3752f9a5c0f109d4cf00cc75ef6f4bf8e3fe12c51d75787cbd2d403f8ba85dac1bcfdf46db211fe7760087a0738c73f39cd33eb8973c5c9354ef121147303e06bcbdf03e0d49c727fd00686a1e7b7be0f804ea67661e7b47c21ff7b753dc5187c7d73b02f4b388dac500baf1fc1db41da27374f639a77df0fb0e704d52bd4b451cc1f818f0ce82fbd400d5241d9ff4a3a979ec9d81e313a69ffbe6b17725fc717f27c51d75785f7d5700807e1651bb58379ebf8bb6433eceed0e41e718e718e76cce31ce31ced99c63009c639cb339c738c73867738e718e71cee61ce31ce39ccd39c639c6399b738c00738c7336e718e718e76cce31ceffffc439ed83df48866b92ea5d26e208f60e00f27977c17dea6b928e4ffad1d4e70eef0e1c9f30fddcf7b9c37b12feb8bf9b00e28e3a3cbede13a09f45d42ed68de7efa1edf056776e77083ac77da3659ce300be119db339c77d233a67738efb4674cee61cf78de89ccd39ee1bd1399b73dc0037a27336e7b86f44e76cce71df88ced99ce3be119db339c77d233a67738efb004674cee61cf78de89ccd39ee1bd1399b73dc37a2733667857d23ed73b995e1009aa47a978b3882f1354fef2dbc4f43d2f1493f9aba6ee7bd81e313a89f99eb00765e4ef8e3fe5e8a3beaf0f87a39403f8ba85dac1bcf5fa6ed109da3b3cf3900ed738595e19aa47a57883882f131e07d85f769483a3ee94753f3d8fb02c72700503f33f3d8fb13feb8bf8fe28e3abcafbe3f403f8ba85dac1bcfdf4fdb213a0047679f73dae74a2bc33549f5ae1471047b997c3e50789f86a4e3937e34358f007d20707c02f533338f7d30e18ffb0728eea8c3fbea0703f4b388dac5baf1fc0083b41d3e189da3b3c739ed739595e19aa47a57893882bd9f7c3e54789fbaa400e3937e34358f7d28707c02f533338fbd92f0c7fd431477d4e17df59500fd2c00a276b16e3c7f85b6c3a1e69cf6b9ceca704d52bdeb441cc13e483e1f2ebc4f005dd2f1493f9a1a5f1f0e1c9f40fdcc8caf8f24fc71ff30c51d75785ffd4880007e1651bb58379e7f84b6c3a1e69cf6b9deca704d52bdeb451cc15e219f8f1600dea72ee9f8a41f4d8daf8f068e4fa07e66c6d7ab097fdc3f4a71471dde575f000dd0cf226a17ebc6f357693b1c6ace699f5d56866b92eaed127104fb08f97c00acf03e7549c727fd686a7c7d2c707c02f53333be3e9ef0c7fd631477d4e17d00f5e301fa5944ed62dd78fe71da0e879a73daa79395e19aa47a9d441cc15e25009f4f14dea72ee9f8a41f4d8daf4f048e4fa07e66c6d72713feb87f82e28e3a00bcaf7e32403f8ba85dac1bcf3f49dbe150734efb74b6325c9354afb38823d800c7c9e75385f7a94b3a3ee94753e3eb5381e313a89f99f1f5e9843fee9fa2b800a30eefab9f0ed0cf226a17ebc6f34fd37638d49cd33e5dac0cd724d5eb22e20008f649f2f94ce17d1a928e4ffad1d4f8fa4ce0f804ea67667c7d36e18ffb670028eea8c3fbea6703f4b388dac5baf1fcb3b41da27374f639a77daaac0cd72400d5ab127104fb34f97caef03e0d49c727fd686a1efb5ce0f804ea67661efb7c00c21ff7cf51dc5187f7d5cf07e86711b58b75e3f9e7693be4e3dcee10748e71006e9e73da67b495e19aa47aa3451cc13e4b3e5f28bc4f43d2f1493f9a9ac7be0010383e81fa9999c7be98f0c7fd0b1477d4e1f1f5c500fd2ca276b16e3cff22006d877c9cdb1d82ce31cecd734efb8cb1325c93546f8c8823181f03be54709f007dbf8fc63ee94753f3d89702c7274c3ff7cd63af25fc71ff12c51d75787cbd0016a09f45d42ed68de7afd17688ced1393a47e7e81c9da373748eced1393a4700e7e81c9da373748eced1393a47e7e8aced9cf6a9b5325c9354af56c4118c3f00b3f972c17df67deec03ee947539f3b7c39707cc2f473dfe70e5f49f8e3fe65008a3beaf0befa9500fd2ca276b16e3cff0a6d87e81c9da373748eced1393a4700e7e81c9da373748eced1393a47e7e81c9da373748ecedace699f7a2bc3354900f5ea451cc15e239faf16dea721e9f8a41f4d7deef0d5c0f109d4cfcce70e5f004bf8e3fe558a3beaf0befab500fd2ca276b16e3cff1a6d87e81c9d7dce699f00b156866b92ea8d157104fb0af97cbde03efb3e3f659ff4a3a979eceb81e31300a69ffbe6b16f24fc71ff3ac51d75785ffd46807e1651bb58379e7f83b6433e00ceed0e41e718e718e76cce31ce31ced99c639c639cb339c738c73867738e71008e71cee61ce31ce39ccd39c639c6399b738c738c7336e718e718e76cce31ce00ffffc439ed33deca704d52bdf1228e605f239f6f16dca7be26e9f8a41f4d7d00eef0cdc0f109d3cf7d9f3b7c2be18ffb3729eea8c3e3eb5b01fa5944ed62dd0078fe2dda0e6f75e77687a073dc375ac639ee1bd1399b73dc37a27336e7b86f0044e76cce71df88ced99ce3be119db339c77d233a67738efb4674cee61cf78d00e89ccd39ee1bd1399b73dc37a27336e7b86f44e76cce71df88ced99ce3be11009db339c77d233a677356d837d23e13ad0cd724d59b28e208c6d73c7dbbf03e000d49c727fd68eaba9d6f078e4fa07e66aedbf94ec21ff76f53dc5187c7d7770002f4b388dac5baf1fc3bb41da27374f639a77d265b19ae49aa3759c4118c8f0001df2dbc4f5dd2f1493f9a9ac7be1b383e81fa9999c7be97f0c7fdbb1477d400e17df57b01fa5944ed62dd78fe3dda0edf3bc49cd33e53ad0cd724d59b2ae20008f61df2f97ee17dea928e4ffad1d4f8fa7ee0f804ea67667cfd20e18ffbf70029eea8c3fbea0f02f4b388dac5baf1fc07b41d0e35e7b4cf2c2bc33549f566008938827d8f7c7e58789fbaa4e3937e3435be7e18383e81fa99195f3f4af8e300fe438a3beaf0befaa300fd2ca276b16e3cff116d8743cd39ed33dbca704d5200bdd9228e603f209f1f17dea72ee9f8a41f4d8daf1f078e4fa07e66c6d74f1200feb8ff98e28e3abcaffe24403f8ba85dac1bcf7f42dbe150734efb1c6665b80026a9de61228e603ce6f058488e01f6c5da83195fecd355cce72e319fdd623e0073c47cda88f95c21e6335dcce722319f7a319f73c47c8689f93c28e6739a98004f1f319f5bc57c4e12f34989f95c23e673b898cf16319f49623e178af9548b00f9ac10f31924e6738f98cf29623eddc57c6e10f33956cca7ad98cf95623e3300c47c2e16f3192be6b35acca752cc67a9984f3f319fdbc57ce689f97412f3b9004ecce748319fad623e53c47cd689f9d488f99c25e63344cce73e319f45623e003dc57c6e12f3395ecc2729e6739598cf2c319f4bc47cc68bf99c2fe65325e600738698cf00319f3bc57c1688f97411f3d925e673b4984f2b319f6d623ed3c4007c3688f9d489f9ac12f3192ae6f38098cf12319fde623eb788f99c28e6532a00e673b598cf61623e978af94c14f3b940cc67b498cf72319f72319fbbc57c4e0016f3e926e6b347cce718319f12319fed623e8d623e1bc57c1ac47cce15f319002ee6f3b098cfe9623e7dc57c6e13f3992be65326e673ad98cf11623e9789f9004c16f3592be63346cc67a598cf60319f7bc57c4e15f3e921e673a398cf7162003eedc57c7688f9cc14f3d924e6334ecce73c319f11623ecbc47cfa8bf9dc2100e6335fcca7b398cff5623e4789f95c2ee63355cc67bd984fad98cfd9623e1500623ef78bf92c16f3e925e673b398cf09623e1dc57c768af9cc16f3d92ce6330041cc678d98cf48319f33c57c068af91409f824136fbe8f36df07b90331dc9700783eb19f5a7901b19f597921b19f5bf96462bfb0f229c47e69e55389fdcaca008b88fddaca8b89fdc6ca4b88fdd6caa711fb9d954f27f67b2b2f25f6072b2f0023f6472b9f41ec4f563e93d89fadbc9cd85facbc82d85fadbc92d8dfac7c1600b1bf5bf96c62ffb0f22a62ffb4f239c4fe65e57389fddbcaab89bd6ee5f38800fdc7cae713c30eb3865891b10b88151bbb90582b636b89b536b68e581b63eb00899518db40acadb18b88b533b691587b631713eb606c13b1a4b14b887534b6009958a9b14b89a58c6d215666ec32629d8c6d25d6d9d8e5c4ba18db46acabb1002b887533b69d5877635712eb616c07b19ec6ae22d6cbd84e62bd8d5d4dac8f00b16b88f535762db17ec6ae23d6dfd8f5c40618db456ca0b1ddc4ca8ded213600c8d80dc4061bbb91d810633711ab307633b1a1c66e2136ccd8adc4861bbb8d0058a5b1db898d307607b12a6377121b69ec2e62a38cdd4d6cb4b17b88551bbb0097d81863f711ab31763f311c2c1e205667ec4162f5c6f8b8d060ac15b1b1c600da101b67ac84d878636d894d30d69ed8c4a2fd65fc9d64ac23b1c9c64a894d0031962236d55819b169c63a119b6eac33b14663f83e679acd30d695d84c63dd0088cd32d69dd86c633d881d66ac27b1c38df5227684b1dec48e34d687d851c600fa123bda583f62738cf527768cb101c48e353690d871c6ca891d6f6c10b113008c0d2676a2b121c44e3256416caeb1a1c4e6191b466cbeb1e1c41618ab24b600d0d80862271bab22768ab191c44e35369ad82263d5c4161b1b436c89b11a6200a719ab2576bab13a624b8dd5135b66ac81d819c6c6123bd3d83862cb8d8d2700b6c2d804622b8d4d247696b149c4ce363699d82a6353889d636c2ab1738d4d0023b6dad87462e7196b2476beb119c4d6189b49ec0263b3885d686c36b1b5c6000e23b6ced8e1c4d61b3b82d806634712bbc8d851c4361a3b9ad8c5c6e610db0064ec186297183b96d86663c711bbd4d8f1c4b6183b81d865c64e24b6d5d84900c42e373697d83663f3885de139566c37f630b1622b734e8263c94f88e17763007e4a0cc7979f11c3f1e5e7c4707cf905b17656fe25311c737e450cfebf268600e3d06f88e138f45b62380efd8e188e43bf2786e3d01f88e138f44762380efd0089188e437f2686e3d05f88e138f45762380efd8d188e437f2786e3d03f88e10038f44f62380efd8b188e43ff2686e3d0ebc4701cfa0f311c871274fcc771a80088188e43c5c4ca8db52236c8586b62380eb52186e35009311c87da12c371a8001d311c87da13c371a803b1378e43c4701cea480cc7a15262238da5888d325600460cc7a64ec4706cea4c0cc7a62ec4706cea4a0cc7a66ec4706cea4e0cc7a6001ec4706cea490cc7a65ec4706cea4d0cc7a63ec4706cea4b0cc7a67ec4706c00ea4f0cc7a601c4706c1a480cc7a6726238360d228663d360628dc686109b6100ac82188e4d4389e1d8348c188e4dc389e1d854490cc7a611c4706caa22866300d3486238368d228663d36862738c5513c3b1690c311c9b6a88e1d8544b0cc700a63a623836d513c3b1a981188e4d6389e1d8348e188e4de389e15cd60462380097c53907ce654d228673599389e15cd614623897359518ce654d23867359d30089e15c5623319ccb9a410ce7b266125b6a6c16b165c66613c3b9acc388e15c00d6e1c4702eeb086238977524319ccb3a8a18ce651d4d0ce7b2e610c3b9ac630088e15cd6b1c4ce35761c319ccb3a9e18ce659d400ce7b24e248673592711c300b9acb9c4702e6b1e319ccb9a4f0ce7b21610c3b9ac85c4702eeb6462389775000a319ccb3a9518ce652d228673598b89e15cd612623897751a319ccb3a9d1800ce652d25867359cb88e15cd619c42e377626b16dc69613c3b9ac15c4702e6b0025319ccb3a8b18ce659d4d0ce7b25611c3b9ac7388e15cd6b9c4702e6b3531009ccb3a8fd875c6ce278673596b88e15cd605c4702eeb42623897b59618ce6500ad23867359eb89e15cd6066238977511319ccbda480ce7b22e268673599b8800e15cd625c4702e6b33319ccbba9418ce656d218673599711c3b9acadc4702e00eb72623897b58d18ce655d41ec0163c839d239c0e8d4fed75117f94792eaf2007a50b63f99bc016d37260afb790db7d548cfd15e2979e0b5ffb5cf40319f3300c57c468af9ac11f39920e6b359cc67b698cf4e319f8e623e2788f9dc2ce6d3004bcc67b198cffd623e15623e678bf9d48af9ac17f3992ae673b998cf51623e00d78bf97416f3992fe67387984f7f319f65623e23c47cce13f31927e6b349cc0067a698cf0e319ff6623ec789f9dc28e6d343cce754319f7bc57c068bf9ac1400f31923e6b356cc67b298cf65623e4788f95c2be65326e63357cce736319fbe00623ea78bf93c2ce6335ccce75c319f06319f8d623e8d623edbc57c4ac47c8e0011f3d923e6d34dcce764319fbbc57ccac57c968bf98c16f3b940cc67a298cf00a5623e8789f95c2de6532ae673a298cf2d623ebdc57c9688f93c20e63354cc006795984f9d98cf06319f69623edbc47c5a89f91c2de6b34bcca78b98cf0231009f3bc57c0688f99c21e65325e673be98cf78319f4bc47c6689f95c25e6931400f3395ecce726319f9e623e8bc47cee13f31922e67396984f8d98cf3a319f2900623e5bc57c8e14f3b94ecca79398cf3c319fdbc57cfa89f92c15f3a914f359002de63356cce762319f19623e578af9b415f33956cce706319fee623ea788f900dc23e63348cc6785984fb598cf85623e93c47cb688f91c2ee6738d984f4acc00e724319f5bc57cfa88f99c26e6f3a098cf30319f73c47ceac57c2e12f3992e00e67385984f1b319f39623ebbc57cee12f3e92ae6b3d0f1497f1e8f7be86e2700566c0cafb54f1c78fcc375e6e9ba0f392cdd477cafb43151d83ea22dac1bcf001f2687bd567e887c1e0ae4b3d7f171db4e515c1e148d598ad85e4f1c531eef00948037ef8f2db1ad1f747cdcb65389fd71d92b1a33ded60f7ae258e6f12e1300f0561cd7654e1cd562966b5c5778bc2b04bc15c775851347b598e51ad7c33c00dec304bc15c7f530278e6a31cb35ae2b3dde9502de8ae3bad289a35acc728d00eb2a8f779580b7e2b8ae72e2a816b35ce37a94c77b9480b7e2b81ee5c4512d0066b9c675b5c7bb5ac05b715c573b71548b59ae715de3f1ae11f0561cd7354e001cd562966b5cd779bceb04bc15c7759d1347b598e51ad70d1eef06016fc57100dde0c4512d66b9c6f5448ff744016fc5713dd189a35acc728deb491eef490200de8ae37a921347b598e51ad7933dde9305bc15c7f564278e6a31cb35ae177900bc1709782b8eeb454e1cd562966b5c2ff6782f16f0561cd78b9d38aac52cd700b85ee2f15e22e0ad38ae973871548b59ae71bdc1e3bd41c05b715c6f70e2a80016b35ce37aa3c77ba380b7e2b8dee8c4512d66b9c6f5268ff726016fc571bd00c989a35acc728debcd1eefcd02de8ae37ab31347b598e51ad75b3cde5b04bc0015c7f516278e6a31cb35aeb77abcb70a782b8eebad4e1cd562966b5c6ff378006f13f0561cd7db9c38aac52cd7b8deeef1de2ee0ad38aeb73b71548b59ae7100bdc3e3bd43c05b715cef70e2a816b35ce37aa7c77ba780b7e2b8dee9c4512d0066b9c6f52e8ff72e016fc571bdcb89a35acc728debdd1eefdd02de8ae37ab7001347b598e51ad77b3cde7b04bc15c7f51e278e6a31f38deb76542e2f9c4f4d008a5c8aa9ad0703f53de1f43de16c0bf6b954cc67a298cf05623ea3c57c968b00f90c12f3b95bcce764319fee623e7bc47c8e11f3692fe6b35dcca751cc67a300984f8398cfb9623e95623ea78bf9f413f3b94dcc67ae984f27319f6bc57c8e0010f3692de6739998cf64319fb5623e63c47c568af90c11f3b957cce754319f009e623e378af91c27e69314f3d921e63353cc679398cf38319ff3c47caac47c009689f90c10f3b943cc67be984f17319febc57c8e12f32911f3b95ccc67aa9800cf7a319f5a319fb3c57c868af9dc2fe6b358cca7b798cfcd623e2788f9948a00f9ec14f3992de6b359cc678298cf1a319f51623e678af9948bf9dc25e6b35000cca79b98cf6e319f39623eedc47cae10f3992ee67391984fbd98cf39623ec300c57c4e13f3e92be673ab98cf49623e65623ed788f91c2ee6d34acc678b98cf0024319f0bc57caac57c5688f90c16f3b947cce714319f1e623e3788f91c2be600d341cce74a319f19623e178bf98c15f3592de63342cc67a9984f7f319fdbc5007ce689f97416f3b94ecce748319f36623e5bc57ca688f9ac13f3a911f3394b00cca742cce73e319f45623ebdc47c6e12f3395ecca7a398cf55623eb3c47c2e0011f3192fe673be98cf48319f33c47c068af9dc29e6b340cca7ab98cf2e319f00a3c57cda8af96c13f39926e6b341cca74ecc679598cf30319f07c47c9688f900f411f3b945cce744319f9498cfd5623e8789f91409f824c923410cf79f2e260086fb53b722f688955b137bd4ca6d883d66e512628f5bb92db12712fb6302f600a495db137bcaca1d883d4d65fc7dc6ca1d893d6be55262cf593945ec792b9700117bc1ca9d88bd68e5cec45eb27217626fb37257626fb7723762efb072776200efb4720f62efb2724f62efb6722f62efb1726f62efb5721f622f5bb92fb1f70059b91fb1f75bb93fb10f587900b10f5a7920b10f59b99cd82b561e44ecc356001e4cec23561e42eca356ae20f6aa958712fb98958711fbb8958713fb84952b00897dd2ca23887dcaca55c43e6de591c43e63e551c43e6be5d1c43e67e56a62009fb7f218625fb0720db12f5ab996d897ac5c47ec352bd713fbb2951b887dc500ca63897dd5cae3887dcdcae3897dddca13887dc3ca13897dd3ca93887dcbca0093897ddbca53887dc7ca53897dd7cad3887dcfcad3897ddfca8dc47e60e51900c47e68e599c47e64e559c47e6ce5d9c47e62e5c388fdd4ca8713fb99958f2000f6732b1f49ec17563e8ad82fad7c34b15f59790eb15f5bf91862bfb1f2b1c4007e6be5e388fdcecac713fbbd954f20f6072b9f48ec8f563e89d89fac3c97d8009fad3c8fd85fac3c9fd85fadbc80d8dfacbc90d8dfad7c32b17f58f91462ff00b4f2a9c4fe65e545c4fe6d65fe1df9d7adccbf37fe1f2b9f460c07d6d3891500195b4aacd8d83262ad8c9d41acb5b13389b531b69c5889b115c4da1a5b49ac009db1b388b5377636b10ec656114b1a3b87584763e7122b35b69a58cad879c400ca8c9d4fac93b135c43a1bbb805817631712eb6a6c2db16ec6d611eb6e6c3d00b11ec6f837c67b1abb88582f63fcfbd4bd8d5d4cac8f31fe6de3bec62e21d600cf18ff2e6e7f6397121b608c7f5375a0b1cb88951be3dfe31c64ec7262838d006d2336c4d815c42a8cf1ef000e357625b161c6f837e4861bbb8a58a531fefd00b111c6ae265665ec1a62238d5d4b6c94b1eb888d36763db16a63fc5b58638c00ed2656638c7f5b076faa6f205667ec4662f5c66e22d660ec6662638ddd426c009cb15b898d37761bb109c66e2736d1d81dc42619bb93d8646377119b62ec6e0062538ddd436c9ab17b894d37761fb14663f7139b61ec0162338ded2586bce3002162c83b1e2686bce31162c83b1e2586bce33162c83b1e2786bce30962c83b009e2486bce32962492b731e82bce31962c83b9e2586bce33962c83b9e2786bc00e30562c83b5e2486bce32562c83bde460c79c7db8921ef780731e41def248600bce35dc49077bc9b18f28ef71043def15e62c83b5e2686bce37dc49077bc9f0018f28e0f1043def14162e556fe10b141567e8518f28e0f1343def11162c83b003e4a0c79c7abc490777c8c18f28e8f1343def10962c83b3e490c79c7a7888d00b4f2a78921eff80c31e41d9f2586bce373c490777c9e18f28e2f1043def1450062c83bbe440c79c76bc490777c9918f28eaf1043def15562c83bbe460c79c700d78921eff80631e41ddf2486bce35bc490777c9b18f28eef1043def15d62c8003bbe47acd1cadf2736c3ca3f2086bce387c49077fc8818f28e1f1343def1130062c83b7e4a0c79c7cf8821eff83931e41dbf2086bce397c4e658f957c4907700fc9a18f28edf1043def15b62c83b7e470c79c7ef8921eff80331e41d7f248600bce34fc49077fc9918f28ebf1043def15762c83bfe460c79c7df8921eff8070031e41dff2486bce35fc49077fc9b18f28ed78921eff80f31e41dc843d26c290010b165c68a8921ef68450c79476b62c83bda1043de51420c79475b626f5c3f00490c79477b62c83b3a107b23ef2076aeb18ec49077941243de912286bca38c0018f28e4ec49077742686bca30b31e41d5d8921efe8460c79477762c83b7a100043ded19318f28e5ec49077f42686bca30f31e41d7d8921efe8470c79477f6200c83b061043de319018f28e7262971b1b446c9bb1c1c490770c2186bca3821800f28ea1c490770c2386bc633831e41d95c490778c2086bca38a18f28e91c4ae0033368a18f28ed1c49077541343de318618f28e1a62c83b6a8921efa82386bc00a39e18f28e0662c83bc61243de318e18f28ef1c490774c2086bc632231e41d00938821ef984c0c79c71462c83ba61243de318d18f28ee9c4907734127bc0d8000c620f1a431e92ce0b06f4d8ff3aeaf26721a8cbeb41d9fe647209b4dd982800ece73adc56233d477ba5e481d7fed73e8789f95c2de69312f33951cce71631009f3e623e4bc47c1e10f31926e6b34acca74ecc678398cf34319f6d623e6dc5007c8e16f3d925e6d355cc678198cf9d623e03c57cce10f31929e673be98cf7800319f4bc47c6689f95c25e6d351cce778319f9bc47c7a89f92c12f3b94fcca70042cce72c319f1a319f75623e53c47cb68af9b411f33952cce73a319fce623e00f3c47c6e17f3e92fe6b354cc678498cf6a319fb1623e178bf9cc10f3b952cc00a78398cfb1623e3788f9f410f33945cce71e319fc1623e2bc47caac57c2e1400f39924e6b345cca79598cfe1623ed788f99489f99c24e673ab984f5f319fd300c47c868bf99c23e6532fe6739198cf74319f2bc47cda89f9cc11f3d92de6d3004dcc67a198cf5d623ee5623e678af98c12f35923e63341cc67b398cf6c319f009d623ea5623e2788f9dc2ce6d35bcc67b198cffd623e43c57cce16f3a915f300592fe63355cce772319f12319fa3c47cae17f3e922e6335fcce70e319f0162003ecbc47caac47cce13f31927e6b349cc67a698cf0e319fa498cf71623e378a00f9f414f33955cce75e319f21623e2bc57cc688f9ac15f3992ce67399984f6b00319f23c47cae15f3e924e63357cce736319f7e623ea78bf9548af99c2be6d30020e6b351cca751cc67bb984f7b319f63c47cf688f97417f33959cce76e319f0041623ecbc57c468bf95c20e63351cce752319f62c7a7d4793dfdc8fc5684c300d2de530379a32dac1bcfa79203ee993d8de2382d90cf74c7c76d3b457141ec00d462962236dd1347fe0dd1690efb5f6febc616dcd68d8e4fa3675b232ed38b003463c6dbbad11347fe6dd8690e8be3fac06d89b8f8c6b542cc728d6bfe8dd900690e8be3fac06d8db8f8c6b542cc728d6bfe9de0690e8be3fac06d8db8f8c600b542cc728d6b9cd763ef4a016fc5718db8f8c6b542cc728d6bfebdee690e8b00e3fac06d8db8f8c6b542cc728d6bfecdf5690e8be3fac06d8db8f8c6b542cc00728d6bdc7b85bdab05bc15c735e2e21bd70a31cb35ae711f58f6ae11f0561c00d7888b6f5c2bc42cd7b8c66fd2b0779d80b7e2b8465c7ce35a2166b9c6353e003f66ef06016fc5718db8f8c6b542cc728d6b7c96c0de1305bc15c735e2e21b00d70a31cb35ae71df37f69e24e0ad38ae1117dfb8568859ae718d6b58d97bb20080b7e2b8465c7ce35a2166b9c6357ecf83bd1709782b8e6bc4c537ae156296006b5ce3de04ecbd58c05b715c232ebe71ad10b35ce31abf23cbde4b04bc15c70035e2e21bd70a31cb35aef11babecbd41c05b715c232ebe71ad10b35ce31ad70043b3f746016fc5718db8f8c6b542cc728d6b7c379bbd3709782b8e6bc4c53700ae1562966b5ce33e71ecbd59c05b715c232ebe71ad10b35ce31af7ac67ef2d0002de8ae31a71f18d6b8598e51ad7f8fd3cf6de2ae0ad38ae1117dfb856885900ae71bd2df166ef6d02de8ae31a71f18d6b8598e51ad7f8de1d7b6f17f0561c00d7888b6f5c2bc42cd7b8c63d80d87b8780b7e2b8465c7ce35a2166b9c635ee0047ccde3b05bc15c735e2e21bd70a31cb35ae7725deecbd4bc05b715c232ebe0071ad10b35ce37a77e2cddebb05bc15c735e2e21bd70a31cb35aef11d7bf6de0023e0ad38ae1117dfb85688996f5c27a93c935871e2c07aed2de60f25f6c71f00751f7158ba8f8f26c2f4116d61dd78fe28393c6ce547c8e791403e0f3b3e6e00dbfcfddd8744639622f6b0278e298f774ac09bf7c796d8d60f393e6edbfcfd00dd874563c6dbfa214f1ccb3cde6502de8ae3bacc89a35acc728deb0a8f77850080b7e2b8ae70e2a816b35ce37a98c77b9880b7e2b81ee6c4512d66b9c675a500c7bb52c05b715c573a71548b59ae715de5f1ae12f0561cd7554e1cd562966b005c8ff2788f12f0561cd7a39c38aac52cd7b8aef678570b782b8eeb6a278e6a0031cb35ae6b3cde3502de8ae3bac689a35acc728deb3a8f779d80b7e2b8ae7300e2a816b35ce3bac1e3dd20e0ad38ae1b9c38aac52cd7b89ee8f19e28e0ad3800ae273a71548b59ae713dc9e33d49c05b715c4f72e2a816b35ce37ab2c77bb20080b7e2b89eecc4512d66b9c6f5228ff722016fc571bdc889a35acc728debc5001eefc502de8ae37ab11347b598e51ad74b3cde4b04bc15c7f512278e6a31cb0035ae3778bc3708782b8eeb0d4e1cd562966b5c6ff4786f14f0561cd71b9d3800aac52cd7b8dee4f1de24e0ad38ae373971548b59ae71bdd9e3bd59c05b715c006f76e2a816b35ce37a8bc77b8b80b7e2b8dee2c4512d66b9c6f5568ff75601006fc571bdd589a35acc728deb6d1eef6d02de8ae37a9b1347b598e51ad7db3d00dedb05bc15c7f576278e6a31cb35ae7778bc7708782b8eeb1d4e1cd562966b005ceff478ef14f0561cd73b9d38aac52cd7b8dee5f1de25e0ad38ae77397154008b59ae71bddbe3bd5bc05b715cef76e2a816b35ce37a8fc77b8f80b7e2b8de00e3c4512d66be71dd8e7c0be9934c1c18b3f4a3c879de48e5873c3eaf17cea70026453e0f85dd1675bcdd0fa6ef8f92cf6385f7c96c8b47f3f0798c7c1e0f14009fc7f2f0799c7c9e08149fc7f3f079827c9e0ce4f3441e3e4f92cf53817c9e00ccc3e729f2793a90cf5379f83c1dd62733b73ceab495668f7bda072b2f5cfb00cbd26d617f799cdac7367b90dae77da540edd7a6687bf0fa0b3fb7d6d6e5bb00ed796e0d3177043a86d4a4d7fb0cf5af50eb4dafeb5927564f39b14a519d6700287ecf06885f51e2c06353233d7fd6d37601f7db4c2c9e3b88583ce7f179ae00856381f6a2b3a6f34387a0f3a118e7670e41e73806a37336e7386fb48c739c0037a2f35bc939ce1bcd73e673a070e5f3637c2ef97fe908f644589f95f99eab007c8e7c429cc70ed4cf4caef7bcd3a7473c71471d3e5e3c1fa09fbeb183e7cf00d376c8c7f9d9e81c9ddf42ce710c46e7e8fcbf758e63303a47e7c23aa77df000f9375c9354ef311147b04783fad4e67d3dc0f3e41322470b14f74c0ef282d300a7c73c71471d9e7b5f08d04fdfd8c1f317683be4e3fc6c748ece599c1f3a04009d0fc538c779233abf959ce3bcd132ce71de88ce6f25e7386f34cf39ddf68b00856f3bf35913b78df8241c1f3c5e0c1c8b40fdcce4792f25fc31467b29aac300f3ee4b01fa5944ed62dd78fe126d877c9c9f8dced1f92de41cc760748eceff005be73806a373742eac738a5e2f269f00ef7b6b0fe6bd3cfb5c2ae63351cce70002319fd1623ecbc57c0689f9dc2de673b2984f77319f3d623ec788f9b417f300d92ee6d328e6b351cca741cce761319f73c57c2ac57c4e17f3e927e6739b9800cf5c319f4e623ed78af91c21e6d35acce732319fc9623e6bc57cc688f9ac1400f31922e673af98cfa9623e3dc57c6e14f3394ecc2729e6b343cc67a698cf2600319f71623ee789f95489f92c13f31920e6738798cf7c319f2e623ed78bf91c0025e65322e673b998cf54319ff5623eb5623e678bf90c15f3b95fcc67b1984f006f319f9bc57c4e10f32915f3d92be6b353cc67b698cf66319f09623e6bc47c004689f99c29e6532ee6739798cf42319f6e623ebbc57ce688f9b413f3b942cc0067ba98cf45623ef5623ee788f90c17f37950cce734319fbe623eb78af99c2400e65326e6738d98cfe1623eadc47cb688f94c12f3b950cca75acc678598cf6000319f7bc47c4e11f3e921e6738398cfb1623e1dc47cae14f39921e673b198cf0058319fd5623e23c47c968af9f417f3b95dcc679e984f67319febc47c8e14f3006923e6b355cc678a98cf3a319f1a319fb3c47c2ac47cee13f35924e6d34bcc00e726319fe3c57c3a8af95c25e6334bcce712319ff1623ee78bf98c14f3394300cc67a098cf9d623e0bc47cba8af9ec12f3395acca7ad98cf36319f69623e1b00c47ceac47c5689f90c13f37940cc6789984f1f319f5bc47c4e14f34989f95c002de67398984f91804f32f1e6dfc449d2ebc5c4708fef56c4de66e5d6c4de6e00e536c4de61e51262efb4725b62ef4aec8f09d8bbaddc9ed87bacdc81d87ba9008cbf2f5bb923b1f759b994d8fbad9c22f6012b9711fba0953b11fb90953b13007bc5ca5d887dd8ca5d897dc4cadd887dd4cadd89bd6ae51ec43e66e59ec43e006ee55ec43e61e5dec43e69e53ec43e65e5bec43e6de57ec43e63e5fec43e6b00e501c43e67e581c43e6fe572625fb0f220625fb4f260625fb2f21062af59b90082d897ad3c94d857ac3c8cd857ad3c9cd8d7ac5c49eceb561e41ec1b56ae2200f64d2b8f24f62d2b8f22f66d2b8f26f61d2b5713fbae95c710fb9e956b887d00dfcab5c47e60e53a623fb4723db11f59b981d88fad3c96d84fac3c8ed84fad003c9ed8cfac3c81d8cfad3c91d82fac3c89d82fad3c99d8afac3c85d8afad3c0095d86fac3c8dd86fad3c9dd8efacdc48ecf7569e41ec0f569e49ec8f569e4500ec4f569e4deccf563e8cd85fac7c38b1bf5af908627fb3f291c4fe6ee5a38800fdc3ca4713fba795e710fb97958f21f66f2b1f4bec752b1f47ec3f563e9e18000e1627102b327622b1626327116b656c2eb1d6c6e6116b636c3eb112630b8800b535b690583b6327136b6fec14621d8c9d4a2c696c11b18ec616132b35b6840058cad869c4ca8c9d4eac93b1a5c43a1b5b46ac8bb1338875357626b16ec6960013eb6e6c05b11ec65612eb69ec2c62bd8c9d4dacb7b155c4fa183b87585f6300e712eb676c35b1fec6ce2336c0d8f9c4061a5b43acdcd805c40619bb90d86000636b890d31b68e5885b1f5c4861adb406c98b18b880d37b69158a5b18b898d0030b6895895b14b888d34b699d8286397121b6d6c0bb16a6397111b636c2bb1001a639713c31bc56dc4ea8c5d41acded876620dc6ae2436d6d80e62e38c5d45006cbcb19dc42618bb9ad84463d7109b64ec5a62938d5d476c8ab1eb894d35b6008bd83463bb894d37b68758a3b11b88cd307623b199c66e2236cbd8cdc4661b00bb85d861c66e2576b8b1db881d61ec7662471abb83d851c6ee2476b4b1bb8800cd317637b1638cdd43ec5863f7123bced87dc48e37763fb1138c3d40ec4463008f113bc9d873c4e61a7b9ad83c63cf139b6fec05620b3ccb2e34f638b1938d003d48ec14634f12435ec47914f2a29788212f7a1b31e4456f2786bce81dc4900017bd9318f2a27711435ef46e62c88bde432c6965ce939017bd4c0c79d1fb8800212f7a3f31e4451f2086bce883c490177d8818f2a25788212ffa3031e4451f002186bce8a3c49017bd4a0c79d1c788212ffa3831e4459f2086bce893c49017007d8a18f2a24f13435ef41962c88b3e4b0c79d1e788955bf9f3c40659f90bc40090177d9118f2a22f11435ef41a31e4455f2686bce82bc490177d9518f2a2af0011435ef47562c88bbe416ca495bf490c79d1b788212ffa3631e445df2186bc00e8bbc490177d8f18f2a2ef13435ef40362c88b7e480c79d18f88212ffa313100e4453f2186bce8a7c49017fd8c18f2a29f13435ef40b62c88b7e490c79d1af0088212ffa3531e445bf2186bce8b7c41aadfc3b6233acfc7b62c88bfe400c7900d11f89212ffa1331e4457f2686bce82fc49017fd9518f2a2bf11435ef4776200c88bfe416c8e95ff490c79d1bf88212ffa3731e445af13435ef41f62c88b900027658e6f40c490171513435ed48a18f2a2d6c49017b52186bca88418f2a2b600c4def84d2c62c88bda13435ed481d81b791131e4451d89212f2a2586bc2845000c795119b1a5c63a115b66ac3331e4455d88212fea4a0c79513762c88bba1300435ed48318f2a29ec49017f52286bca83731e4457d889d6bac2f31e445fd8800212fea4f0c79d10062c88b0612435e544e0c79d12062c88b0613435e34841800f2a20a62c88b8612435e348c18f2a2e1c490175512435e348218f2a22a62c8008b4612435e348a18f2a2d1c490175513435e3486d8e5c66a886d33564b0c7900511d31e445f5c490173510435e349618f2a271c490178d2786bc680231e445001389212f9a44ec3a639389212f9a420c79d15462c88ba611435e349d18f2a2004662c88b6610435e349318f2a259c49017cd2686bce83062c88b0e2786bce8000862c88b8e2486bce82862c88b8e2686bc680e31e445c710435e742c31e44500c711435e743cb1078c9d40ec41632712db6bec24620f199b4b0cbff9358fd80023c6e6137bd4d80262c8c7161243ae7432b1278c214f4ae72d3faed8ff3a9600e7cf92d00e7f9684e5b93db4c35e28db9f4c4e84651a1385fdfc8cdb6aa4e70068af943cf0daffdae730319fabc57c52623e278af9dc22e6d347cc678998cf0003623ec3c47c5689f9d489f96c10f39926e6b34dcca7ad98cfd1623ebbc47c00ba8af92c10f3b953cc67a098cf19623e23c57cce17f3192fe6738998cf2c31009fabc47c3a8af91c2fe67393984f2f319f45623ef789f95488f99c25e6532300e6b34ecc678a98cf56319f36623e478af95c27e6d359cc679e98cfed623efd00c57c968af98c10f3592de63356cce762319f19623e578af97410f33956cce70006319f1e623ea788f9dc23e63358cc6785984fb598cf85623e93c47cb688f900b412f3395ccce71a319f32319f93c47c6e15f3e92be6739a98cf83623ec3c5007cce11f3a917f3b948cc67ba98cf15623eedc47ce688f9ec16f3e926e6b35000cce72e319f72319f33c57c4689f9ac11f39920e6b359cc67b698cf4e319fbd00623ea5623e2788f9dc2ce6d35bcc67b198cffd623e43c57cce16f3a915f359002fe63355cce772319f12319fa3c47cae17f3e922e6335fcce70e319f01623e00cbc47caac47cce13f31927e6b349cc67a698cf0e319fa498cf71623e378af900f414f33955cce75e319f21623e2bc57cc688f9ac15f3992ce67399984f6b31009f23c47cae15f3e924e63357cce736319f7e623ea78bf9548af99c2be6f3b000984f8398cf46319f46319fed623eedc57c8e11f3d923e6d35dcce764319fbb00c57c0689f92c17f3192de6738198cf44319f4bc57c8a5bd007f70bc7ba4f76007c02b55dc3f764c7fad3f741e930607fbb0b0adfeeb222a7bdc6c49baf476b004d75de5eb1bf6e2aa85bc384f47ae7177cbd63333fcd30cfe933fce7539f5100a7abf5337d1e80978517ee3bbf80f659c46b9e27863d07ec6f7bea90fdcbe000fefbc83fd2fdc77df5cb1385dde68fecef4266dd0f5a19eda5ebe0fefd254e001d2cdb9aeaf4a718f16f5417535f50b73151d831cb8f462aa33df69928e673008198cf20319f93c57cf688f920b753f16914f3d928e65329e673ba98cf6d62003e9dc47c8e10f3b94ccc678c98cf4a319f7bc57c7a8af91c27e6b343cce72100319f71623ee789f90c10f3992fe673bd984f8998cf54319ff5623e43c57c16008bf9dc2ce6532ae6335bcc67b398cf28319f33c57cee12f3e926e63347cce7000a319f7a319f73c47cfa8af99c24e6738d984f2b319f49623e178af90c16f3003945cce706319f0e623e33c47c2e16f31921e6b354cce776319fce623e478a00f96c15f3a911f3394bcce73e319f5e623ec78bf95c25e6f38898cf78319ff300c57c068af92c10f3d925e6d356cc679a98cf06319f61623e4bc47c6e11f3490089f91c26e673a998cf68319fe5623e778bf97417f33946cc67bb98cfc3623e000d623ee78af9f413f3992be673ad984f6b319fc9623e6bc57c8688f99c2ae60073a3984f52cc67a698cf26319f2a319f65623e7788f97411f3394acce77231009f5a319fb3c57cee17f3e92de6738298cf5e319f9d623e13c47cd688f9948b00f92c14f3d92de6d34ecc67ba98cf45623ec3c57c4e13f3b955cca74ccce77000319f2d623ed5623e2bc47cee11f3e921e673ac98cf95623e63c57c568bf9f40017f39927e6739d984f1b319f29623eebc47c2ac47c1689f9dc24e6d351cc67009698cf25623e23c57cce10f3b953cca7ab98cfd1623edbc47ceac47c5689f9003c20e6d347cce744319fabc57c8a047c92e4912086d78b893d6ee556c49eb000726b624f5ab90db1a7ac5c42ec692bb725f64c627f4cc09eb5727b62cf59b90003b1e7a98cbf2f58b923b117ad5c4aec252ba788bdcdca65c4de6ee54ec4de0061e5cec4de69e52ec4de65e5aec4de6de56ec4de63e5eec4de6be51ec45eb600724f62efb3722f62efb7726f621fb0721f621fb4725f621fb2723f62af58b9003fb10f5b7900b18f587920b18f5ab99cd8ab561e44ec63561e4cece3561e4200ec1356ae20f6492b0f25f6292b0f23f6692b0f27f6192b5712fbac954710fb009c95ab887ddeca23897dc1caa3887dd1caa3897dc9cad5c45eb3f218625fb600720db1af58b996d857ad5c47ec6b56ae27f6752b3710fb8695c712fba695c70011fb9695c713fbb6952710fb8e952712fbae952711fb9e952713fbbe95a71000fb8195a712fba195a711fb9195a713fbb1951b89fdc4ca3388fdd4ca3389fd00cccab388fddccab389fdc2ca8711fba5950f27f62b2b1f41ecd7563e92d86f00ac7c14b1df5af96862bfb3f21c62bfb7f231c4fe60e56389fdd1cac711fb9300958f27f6672b9f40ec2f563e91d85fad7c12b1bf59792eb1bf5b791eb17f5800793eb17f5a7901b17f597921b17f5bf96462af5bf91462ffb1f2a9c470205c0044acc8d86262c5c696106b65ec3462ad8d9d4eac8db1a5c44a8c2d23d6d6d80019c4da193b93587b63cb897530b68258d2d84a621d8d9d45acd4d8d9c452c60056112b33760eb14ec6ce25d6d9d86a625d8c9d47acabb1f3897533b686587700631710eb61ec42623d8dad25d6cbd83a62bd8dad27d6c7d806627d8d5d44ac009fb18dc4fa1bbb98d800639b880d347609b172639b890d327629b1c1c6b610001b62ec326215c6b6121b6aec7262c38c6d2336dcd815c42a8d6d2736c2d89500c4aa8ced2036d2d855c44619db496cb4b1ab89551bbb86d81863d712ab3176001d31bc09be9e589db15dc4ea8ded26d6606c0fb1b1c66e2036ced88dc4c61b00bb89d8046337139b68ec1662938cdd4a6cb2b1db884d31763bb1a9c6ee203600cdd89dc4a61bbb8b58a3b1bb89cd30760fb199c6ee2536cbd87dc4661bbb9f00d861c61e2076b8b1478821efe03c0579c7e3c490773c410c79c793c490773c00450c79c7d3c490773c430c79c7b3c490773c472c6965ce439077bc400c79c7008bc49077bc440c79c7db8821ef783b31e41def2086bce39dc49077bc8b18f2008e771343def11e62c83bde4b0c79c7cbc49077bc8f18f28ef71343def1016200c83b3e480c79c7878821ef788518f28e0f1343def11162e556fe28b141567e009518f28e8f1143def17162c83b3e410c79c7278921eff81431e41d9f2686bc00e333c490777c9618f28ecf111b69e5cf1343def10562c83bbe480c79c797880021ef788d18f28e2f1343def11562c83bbe4a0c79c7d78821eff83a31e41ddf002086bce39bc490777c8b18f28e6f1343def11d62c83bbe4b0c79c7f78821ef00f83e31e41d3f2086bce387c49077fc8858a3957f4c6c86957f420c79c74f890021eff81931e41d3f2786bce317c49077fc9218f28e5f1143def16b62c83b7e00430c79c76f89cdb1f2ef8821eff83d31e41d7f2086bce38fc49077fc8918f2008e3f1343def11762c83bfe4a0c79c7df8821eff83b31e41dff2086bce39fc4009077fc8b18f28e7f1343def13a31e41dff2186bc0379489a21ef282286bca3009818f28e56c49077b426b6d4581b62cb8c951043ded196d81bf7e32686bca3003d31e41d1d88bd91771043ded19118f28e5262c83b52c4907794113bd758270062c83b3a1343ded18518f28eaec49077742386bca33b31e41d3d8821efe849000c79472f62c83b7a1343ded18718f28ebec49077f42386bca33f31e41d03880021ef18480c79473931e41d838821ef184c0c79c71062c83b2a885d6e6c28b1006dc6861143de319c18f28e4a62c83b461043de51450c79c74862c83b46114300de319a18f28e6a62c83bc610bbce580d31e41db5c49077d41143de514f0c7900470331e41d638921ef18470c79c77862c83b261043de319118f28e49c49077004c2686bc630a31e41d538921ef98460c79c77462c83b1a8921ef98410c79c7004c62c83b661143de319bd803c60e23f6a031e421e9bc60408ffdafa32e7f160082babc1e94ed4f269740db8d89c27eaec36d35d273b4574a1e78ed7fed73b50098cf89623e7dc47c1e10f35925e65327e6b34dcce768319fae623e778af99c0021e63352cce712319f59623e1dc57c6e12f35924e65321e6b34ecc678a984f001b319febc47ce689f9f417f3592de63356cce74a319f63c57c7a88f9dc23e600b342cca75acc678b98cfe1623e65623eb78af99c26e6335ccce722319fe962003eedc47c768bf92c14f32917f35923e63341cc67a798cf5e319f13c47c7a8b00f9dc2fe673b6984fad98cfe5623e4789f97411f3b943cc6799984f9598cf2600319f99623e49319f1bc57c4e15f31922e6b356cc67b2984f6b319f6bc57ce6008af9f413f33957cca741cce761319fed623ec788f97417f3b95bcc67b998cf0068319f4bc57c0e13f34989f9dc22e6b344cc679898cf06319f69623e6dc57c007689f92c10f31928e673be98cf78319f47c47cae12f3395ecca79798cf7d62003e6789f9d488f96c15f33952cca7b398cfed623e4bc57c4688f95c2ce6334300cca78398cf0d623ea788f90c16f3b950cc6792984f2b319f6bc47c4e12f3e9002be6738e984fbd98cf15623e73c47cba89f9dc25e673a698cf28319fcd623e00b3c57c4ac57c6e16f3592ce63354cc67bd98cf54319f12319febc57ce68bf9000c10f3394fcc679c98cf43623e3bc47c8e13f3e929e673af98cf4a319f3162003e9789f91c21e6d349cce736319fd3c57c2ac57c368af9348af9b417f3d92300e673b298cf20319f0bc47c268af9143b3ee9c723fb8b6fbcdfc7bdc7d3d74b003fecd44bdf2370ea90fdebc432a857ea94d38ff4f7281f75583a16a17e9316006d61dd78fe1839a03f8f92cfa3817c1e717cdcb65314978745639622f68827008e298f774ac09bf7c796d8d60f3b3e6edba9c4feb83c221a33ded6be715de600f12e13f0561cd7654e1cd562966b5c5778bc2b04bc15c775851347b598e51a00d7c33cdec304bc15c7f530278e6a31cb35ae2b3dde9502de8ae3bad289a35a00cc728deb2a8f779580b7e2b8ae72e2a816b35ce37a94c77b9480b7e2b81ee500c4512d66b9c675b5c7bb5ac05b715c573b71548b59ae715de3f1ae11f0561c00d7354e1cd562966b5cd779bceb04bc15c7759d1347b598e51ad70d1eef0601006fc571dde0c4512d66b9c6f5448ff744016fc5713dd189a35acc728deb491e00ef4902de8ae37a921347b598e51ad7933dde9305bc15c7f564278e6a31cb3500ae1779bc1709782b8eeb454e1cd562966b5c2ff6782f16f0561cd78b9d38aa00c52cd7b85ee2f15e22e0ad38ae973871548b59ae71bdc1e3bd41c05b715c6f0070e2a816b35ce37aa3c77ba380b7e2b8dee8c4512d66b9c6f5268ff726016f00c571bdc989a35acc728debcd1eefcd02de8ae37ab31347b598e51ad75b3cde005b04bc15c7f516278e6a31cb35aeb77abcb70a782b8eebad4e1cd562966b5c006ff3786f13f0561cd7db9c38aac52cd7b8deeef1de2ee0ad38aeb73b71548b0059ae71bdc3e3bd43c05b715cef70e2a816b35ce37aa7c77ba780b7e2b8dee900c4512d66b9c6f52e8ff72e016fc571bdcb89a35acc728debdd1eefdd02de8a00e37ab71347b598e51ad77b3cde7b04bc15c7f51e278e6a31f38deb24951f220056ecd46b6fee0b0aff1de509e9552eb4f516db7af7daba17d0f7a3e715beed009af42ae7db7a5bdb7ad1ce02e2a8f3fe8a7d7fd34f4f32d6ca965be82c97fe0033d759379641ff5a531dacbb93f5777ec1fb3bb686bddb38de1c07d479859c007859789d62cf17d277c911bf93687d60af56ec6ffb3b15fb97c1f2183b61fa00bf6f5f5b90655f9b4ffbdadc40fbda3c677f98eb893dea7c9ef6b5139d7d6d0081b35c9113ef465a86f7b5939c75635f0b30b66a79ff4f38def38adedcb71200a70e8f1dd4f9b2e37d620b8d11b89ce819235f3fc8313297c6c802678cf0eb00e9873b97f0fd16e6921bc650a0b9b996e766acdb9d9b790e2d71ea2cf4cca1003fa478253d75d3fdea30607fac9e4cec2f276c99a71d96eeff338930fd475b0058379e3f430e4f59f969f2793a90cf538e8fdb36df33e249d198a5883de5890063cae39d12f0e6fdb125b6f5938e8fdb36df33e229d198f1b67ed213c7328f00779980b7e2b82e73e2a816b35ce3bac2e35d21e0ad38ae2b9c38aac52cd7b8001ee6f11e26e0ad38ae873971548b59ae715de9f1ae14f0561cd7954e1cd56200966b5c5779bcab04bc15c775951347b598e51ad7a33cdea304bc15c7f52827008e6a31cb35aeab3dded502de8ae3bada89a35acc728deb1a8f778d80b7e2b800ae71e2a816b35ce3bacee35d27e0ad38aeeb9c38aac52cd7b86ef078370878002b8eeb06278e6a31cb35ae277abc270a782b8eeb894e1cd562966b5c4ff278004f12f0561cd7939c38aac52cd7b89eecf19e2ce0ad38ae273b71548b59ae7100bdc8e3bd48c05b715c2f72e2a816b35ce37ab1c77bb180b7e2b85eecc4512d0066b9c6f5128ff712016fc571bdc489a35acc728deb0d1eef0d02de8ae37a83001347b598e51ad71b3dde1b05bc15c7f546278e6a31cb35ae3779bc3709782b008eeb4d4e1cd562966b5c6ff6786f16f0561cd79b9d38aac52cd7b8dee2f1de0022e0ad38aeb73871548b59ae71bdd5e3bd55c05b715c6f75e2a816b35ce37a009bc77b9b80b7e2b8dee6c4512d66b9c6f5768ff776016fc571bddd89a35acc00728deb1d1eef1d02de8ae37a871347b598e51ad73b3dde3b05bc15c7f54e27008e6a31cb35ae7779bc7709782b8eeb5d4e1cd562966b5ceff678ef16f0561c00d7bb9d38aac52cd7b8dee3f1de23e0ad38aef73871548b996f5cb7a372a17d00f63a3e7b5bb0ed6cf7f8788a628147710bf8241c9f44133e978af94c14f3b90040cc67b498cf13623ecbc57c0689f9dc2de673b2984f77319f3d623ec788f900b417f3d92ee6d328e6b351cca741cce75c319f4a319f87c47c4e17f3e927e600739b98cf5c319f4e623ed78af91c21e6d35acce732319fc9623e6bc57cc68800f9ac14f31922e673af98cfa9623e3dc57c6e14f3394ecc2729e6b343cc67a60098cf26319f71623ee789f95489f93c2ae6b34ccc678098cf1d623ef3c57cba0088f95c2fe67394984f8998cfe5623e53c57cd68bf9d48af99c2de63354cce7007e319fc5623ebdc57c6e16f33941cca754cc67a798cf6c319fcd623e13c47c00d688f98c12f3795ccce74c319f72319fbbc47c168af97413f3d92de63347cc00a79d98cf15623ed3c57c2e12f3a917f33947cc67b898cf83623e7bc57c4e1300f3e92be673ab98cf49623e65623ed788f91c2ee6d34acc678b98cf24319f0b00c57caac57c5688f90c16f3b947cce714319f1e623e3788f91c2be6d341cce7004a319f19623e178bf98c15f3592de63342cce761319f47c47c968af9f417f300b95dcc679e984f67319febc47c8e14f36923e6b355cc678a98cf3a319f1a31009fb3c47c2ac47cee13f35924e6d34bcce726319fe3c57c3a8af95c25e6334b00cce712319ff1623ee78bf98c14f3794ccce70c319f81623e778af92c10f3e9002ae6b34bcce768319fb6623edbc47ca689f96c10f3a913f35925e6334ccce70001319f25623e7dc47c6e11f33951cc2725e673b598cf61623e45023e49f2480010c3eb0f10c3ef1b3c480cbf2bb097187e77e02162cf5af96162cf59f9116200cf5bf951622f58f931622f5af971622f59f90962c556e6fee2ba46febd06dc004bf06962f8fce41962b887c2b3c4f0bef13962f8eec8f3c4707fe41788e11a0095178925ad8cfea4d7ffcb91fb5fc7f2c5b40cda6945ec254f7b2f7abc50e600fd11cb34260abb3f725b8df41ced9592c7f3223e8789f95c2de69312f3395100cce716319f3e623e4bc47c1e10f31926e6b34acca74ecc678398cf34319f6d00623e6dc57c8e16f3d925e6d355cc678198cf9d623e03c57cce10f3794ccc6700a498cff9623ee3c57c2e11f39925e67395984f47319fe3c57c6e12f3e925e600b348cce73e319f0a319fb3c47c6ac47cd689f94c11f3d92ae6d346cce74831009febc47c3a8bf9cc13f3b95dcca7bf98cf52319f47c47c1e16f31921e6b35a00cc67ac98cfc5623e33c47cae14f3e920e673ac98cf0d623e3dc47c4e11f3b90047cc67b098cf0a319f6a319f0bc57c2689f96c11f36925e673b898cf35623e0065623e2789f9dc2ae6d357cce734319fbd623e0f8af90c17f33947cca75ecc00e722319fe9623e5788f9b413f39923e6b35bcca79b98cf42319fbbc47ccac5007cce14f3795ccc679498cf1a319f09623e9bc57c668bf9ec14f32915f3394100cce766319fde623e8bc57cee17f3192ae673b6984fad98cf7a319fa9623e97008bf99488f91c25e673bd984f17319ff9623e7788f90c10f35926e6f3a8984f009598cf79623ee3c47c3689f9cc14f3d921e69314f3394ecce746319f9e623e00a78af9dc2be63344cc67a598cf18319fb5623e93c57c2e13f3692de673849800cfb5623e9dc47ce68af9dc26e6d34fcce774319f87c47c2ac57cce15f3691000f3d928e6d328e6b35dcca7bd98cf31623e7bc47cba8bf99c2ce673b798cf2000319fe5623e4f88f98c16f3b940cc67a298cfa5623ec58e4fa9f37afac1bf6900504adecf04f2465b58379e3f430ef8fd8167c9e7d9403ecf393e6edb298acb000ba2314b117bce13c794c73b25e0cdfb634b6ceb171c1fb7ed54627f5c9e13008d196feb173c712cf3789709782b8eeb32278e6a31cb35ae2b3cde1502de8a00e3bac289a35acc728deb611eef6102de8ae37a981347b598e51ad7951eef4a00016fc5715de9c4512d66b9c67595c7bb4ac05b715c573971548b59ae713dca00e33d4ac05b715c8f72e2a816b35ce3badae35d2de0ad38aeab9d38aac52cd700b8aef178d708782b8eeb1a278e6a31cb35aeeb3cde7502de8ae3bace89a35a00cc728deb068f778380b7e2b86e70e2a816b35ce37aa2c77ba280b7e2b89ee800c4512d66b9c6f5248ff724016fc5713dc989a35acc728debc91eefc902de8a00e37ab21347b598e51ad78b3cde8b04bc15c7f522278e6a31cb35ae177bbc17000b782b8eebc54e1cd562966b5c2ff1782f11f0561cd74b9c38aac52cd7b8de00e0f1de20e0ad38ae373871548b59ae71bdd1e3bd51c05b715c6f74e2a816b3005ce37a93c77b9380b7e2b8dee4c4512d66b9c6f5668ff766016fc571bdd98900a35acc728deb2d1eef2d02de8ae37a8b1347b598e51ad75b3dde5b05bc15c700f556278e6a31cb35aeb779bcb709782b8eeb6d4e1cd562966b5c6ff7786f1700f0561cd7db9d38aac52cd7b8dee1f1de21e0ad38ae773871548b59ae71bdd300e3bd53c05b715cef74e2a816b35ce37a97c77b9780b7e2b8dee5c4512d66b900c6f56e8ff76e016fc571bddb89a35acc728deb3d1eef3d02de8ae37a8f134700b598f9c6753b2a17da67afad0bdf11dedb826d3fe2b4fd88d37692ca2f11c300b67b9158b16759fcf627eab7b7fe740cd41fdc0b0debc6f38e14cb506db77500da6eebb49da2d78b5bc027e1f8249af0498af9b413f36925e6d35acca7bd98004f1b319f0e623e25623e6dc57c8a047c92e4912086d75b112bb5726b62e84f001b6265562e21d6c9ca6d8975a6fe83157bfce0504a0c0e296270e0fb1ec0a1001331387426a71175fb5f1f68bc989629b732c7639095391e83adccf1c0bd8900391e15d436187ef387e381ef28b72786dfd2ed40ac92caf83bc2ca1c4b7c3700926339d2ca1c4b7caf8e6339daca1ccb6a2b772636c6ca5d88e1fb3c5d89d5005ab91b31ac672031b4574e0c5e8388c17f3031f4730831c483ef9900d7a1c400e0cadfb787eb7062b8f7196f831e561e410cf714e7eff9f6b2f24862f8ad2e00fe8e681f2b8f2686dfe4ae2686fb888e21d6dfcafcdd34fc3e472d3194795e00c2328d89c2ce4bdc56233d477ba5e4512be2d356cca744cca783984f1b319f00f6623eadc57c5a89f9b413f3498af914b7a00f8ef7587799e313b2ed52a7ed00d2166cbb8bd37697166cbb9bd376b7166cbb87d3768f166cbb97d376af166c00bb8fd3769f166cbb9fd376bf166c7b80d3f680166c3bce2d716e69a9b6e3dc00a239b75417bcedb1357cde038fa6cec95593cf9882fbd4d486e9674d4d7abd00a3a97f855a6f7a5da39c58d538b14a519dd114bf5101e25744ed62dd783eca00d3f6eb89c2c662e441c462a4c767640bc702ed45e7e81c9d0f2de7d1d1b945009ce3fe1c9da373748ef373dc37a273748ece6f0de7383fb78c73dc9fa37374008ece717e8efb46748eced1f9ade11ce7e796718efb73748eced139cecf71df0088ced1393abf359ce3fcdc32ce717f8eced1393ac7f939ee1bd1393a47e7b70086739c9f5bc639eecfd1393a47e74371ae4bb75d55f0b69737249db6119f8400e3834755e05884e9e7beef328e48f8638cf6525487f7d31101fa5944ed62dd00783e82b643748eced1393a47e7e81c9da373748eced1393a47e7e81c9da37300748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced139003a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c009da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748e00ced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a4700e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da30073748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced100393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1397fe774db0095856fbb3ee9b48df8241c1f3c2a03c722503f6bd27d1a9ef0c718eda5a80e006ff3e101fa5944ed62dd783e9cb643740eef9ca2d78bc927c07e587b30638b007d7a8bf9f411f3e92ae6d34dcca793984f99984f7b319ffe623e03c47c7a8a00f9f412f3e928e6d345cca7b3984f52cca795984f6b319fbe623efdc47cba8b00f9f410f34989f9948af97410f32911f3692be65324e0934cbcf99c55925e2f0026869cbf33b16156ee446ca895cb885538fd4fb321562e2536d8ca1d890db200721762e556ee4a6ca095bb11abb3727762f556ee41acc1ca3d898db5722f6200e3acdc9bd8782bf72136c1ca7d894db4723f6293acdc9fd8642b0f2036c5ca00ed894db5720762d3a88cbfd3ad5c43acd1ca6388cdb07235b199561e496c960095ab88cdb6f20862d877785fc37ba4e1c4f03e6518b136561e4a0cf3490531008ce921c4da59793031c46d1031c4ad9c18e2369018f6c53a62d867eb8961df006e208631309618c6ca38621853e389617f9f400cfbfb4462d8df2711c3fe3e009918f6f729c4b0bf4f2586fd9df725ecefd389617f6f2486fd7d0631ecef330089617f9f450cfb3bf6a5f4b67d62ecfed7b13ccf4968a715b1d99ef66679bc0050e6797826f5a9d1ca35ffdd23330f735b8df41ced9592c70c119fb6623e2500623e1dc47c4ac57c52623e3dc47cba8bf9f413f3e92be6d35acca795984f5200cca7b3984f17319f8e623ebdc47c7a8af90c10f3e92fe6d35ecca74ccca79300984f37319fae623e7dc47c7a8bf9147b7c3a07f269edf8e079e71668bbadd300765ba76d3e7f349b18de6ff0399662cfb2781f89faedad3f1d02f507ed61dd0078ce9f5f846abbc469bbc4d3763240db7cbe118f22e7792395931e9f7685f300a949250e3c6f8cf59716beef757c0ef560face9fab9515dea79ecfdf1e8c0f005f77952abc4f6da07e66aedbede4f4a9d4e9532a71e06737e867a700fd2ca20076b16e3cef44db213a87774efb604cf2e76fa8d751c491e317d0a72ee9f8a4001f4dcd097c6d6897c2fbd4f3e74407e3c3d78a85781f12a89f9939aaabd3a7004e4e9f5289033fe7453fbb06e86711b58b75e37957da0ed139bc338f7f9e3b0051af4cc411ac73589fbaa4e3937e343527f0f5fddd0bef53cf9f471f8c0f5f00dfd6adf03eb581fa9999a37a387deaeaf4299538f07a12f4b347807e1651bb0058379ef7a0ed109dc33bf3f8e7b913f5ba883882750beb5397747cd28fa6e60004bec6b457e17deaf9ba9783f1e1ef24f42cbc4f6da07ed6a4d78bf373af27000a3bf7f57162d5c389558aeaf077eefa04885f11b58b75e339da8bce2de3cc00f30acfc9a8d75dc411ac67589fbaa4e3937e3435d7f0f741fb15dea79eafd1003b181ffe3e44dfc2fbd406ea67668eeaeff4a98fd3a754e2c06b6cd1cffe0100fa5944ed62dd78de9fb643740eefcce39fafcf46bd5e228e60fc1da910638500af8fc6fad3d75abf641737a77d7b126fa4faade92fea5cd0b0bfee3beaf6bb00877a6f8976f138d8f79601f2f1bcdf5b723e1e2aff0dd0cf1a3ea758c8cfa0007ce7cd7b38b1e2f3e6ec10ea9cb47b8e0ccf9b3ad71f9d0bef9cf6c158e7f70096a8d753c411ac5b589fba7ccfb5f1e713013ed3cdfbf309fe4c37d467a80100fa9999a3924e9f3a397d4a511d1e3b21ae23284a1cf8d97563e2c0cfefb01d00a27378671efffcf904ea751571e4f805f4a9cbf7ba0ace0f02e4e3f5fc7dbe0083f1e17cbc77e17d6a03f5333347f575fa9474fa94a23a3c7642e4f9be73590078de97b643740eefcce39fbf138c7aa5228ebef39a017ceaf23d27c6f9788000f303f5fc9dd983f1e17b5c05383f501ba89f99396a80d3a7be4e9f525487c700ce8000fdf49dcbc2f301b41da27378671eff7cbf04d4eb23e208c6e7c9438c0015be5f01d69f3ebf36c06e3690f6ed4dbc91eae3daf0d654e792fafd7507590099afe7c775c0fc9d66beff463787f1f9a0c64461b703dac2baf1bc3339e27c0040376270e37b8e747658c873059d1d6f3ce71cc6d717b8f1bd4ddcebb242e500ccbef3427c6e038ebebec08defab927258c8bc27e578f37d65e0e8eb0bdcf8009e2e4987857c2fe4e6b878de971c7d7d713fc3e4f70d7c2e2cc47b02dffb5e003cef478ebebec08daf8de9e7b0ffe5672fa559fad295caf0eeefb0ffe5f1a800344b5fe0c69f750d7058da7b60206ff7bd079e0f2447b72f21af0fc0778bf000dda9569e58846abbc469bbc4b36ddcbc87b7177f3f07f1e373e1e556f6dd2b008bef8135d8ca7c6cc4fd92f87b60b8af121f8b70ff253ebf85fb34f1dcefde000f3ccd2aadcc732ddf1f0a7f711f299edb465a99df0fe27ee73c978cb632df0053abdaca3c76719f2bfe6cbad8cabc3db07ff0bdb7f0b927df130af7a72a270086ed3b8818de8f0d2686cf53f99e5578ffc6f7b6c2f6e77b60216e7caf2c6c007fbea716fa5e490cdb86b701f609be9717b6f54862d84f4611c37e329a18b6000ddf430cfb22b601be5f18ea33628c253c0ee633e254e2c0f7d470c7eb7c5e0022c467b7be6b5fddf7b97ced2bdf5b31c475a5858823df6f31c4f9549e63b1006e3cef4dceb97225dea6458930dbb4b5e3d28d38eaecb2dcac5322d8761dcb000ec54e3cf87a890079520de749ad1307e61b1c27d4b98df25dcc7bad6cb9de00ce729c1360dd58a63df194b36ec43a403ebb92bddb38de1c07d4b98b9c7cb90002e625ac83731cfe2c25546eeefab87de16d50e2d449527f51e741671b04c800b956720e806de0e629ada9ce23ce3670f3073e36a41f9caff179a10079585d0053db00ed71aed6d436409da79d6d10200f5bc97981bb0dfa9313ea3cef6c030037a7f06d03f487738a00b9597d53db80cfc1a25f4d6d03d479a7b30d02e46600996d506eeb72b7c14072429df73adb001c5ebe6d80fea06e3b2a37260ad6970086a6b601da2ba27e35b50d50e79516da06c80d9ada06a8f3aab30dc0e1e5db0006e823ea863c07972dbfe5f8e2f8f4693a07bdaa61bf2fe62dcefdba394ced007c73a0f747f5bef70b78efd289628a3a5f76f6d900dbb93ee439f301d4a746008a33f71575be41fbcfb7acccfb0a1fe37fe9791d8f83bd1ea5bcf07daef18d00ff724fdb83c9b5406dd772db45f60fed80f3dcf30b7aef8d7a8807625d6e7f00d36304f317bbbbcb7573964b519d819efe37260adbff72c7a7dc714e6f93ef00d27e86fd28e4fc3330e18f517b8ad1402ae32fe6463ecf87d779de0cf59dd3006c9fbff07900309e4b51eeeaf1ee2ae0cd9fd3f1f57221be9fd5d47c8ff67800beff570bcdf7a13e4372e7fb6e9ebebef11e9abe57d2cacabcaf74a6b875f100bc8e479cef0f6ebeefdcb0bfae3b6f23d6e5f6f760e7fb94b39ce27c5f42fb0019f6a390f3cfc02c31f2cdf77c7d1c7f4f23fde0cf7f437faf88cf2960dd7800ce732518cfa55c76bd4b05bcf9fc0d5feb17e078dfe47cef3b1f38c4f6c7d000f37da8f736ee7c9ff2f415752a691c56d17ceeee53e9d7277a5ec723cef7070037df4f6862be47accbedefc1cef77d9de514e7fbd1b49f4da4f93ed4fc3330004b8c7cf33d5f9f89b9913fffe6eb98e0adf0fe9ee75294fb78bcfb0878f3b900627e7f1fe2daeea6e67b3eef8d3a47b7d07c1fea5a2b77beefebe92bea1c4f00e3f044cffbf76e14b7a5f1fdbd37def9ccf7a73731dfbbe765de4aefefe7d1007eb654ecfd7d6f62fcfda1f483afbfe07933d475a9bd1d6f3ce7b9d2fdcc9d00cfe5878ca9ebe65eafc0e7f14b9c3a58b635d5399fe6d9a4a72e5f6baf762f000b3ef7576c7ff93a253ef7a7709d12ff2676a8eb94fedb38f2ef6487b8e75b005122fb3def7b9273aefbaeb4e4754aeef965be4e69bbf33e25c0761dc70ec5004e3cf83aa500b9eb01f724c67b99ce4edbada9cef5746cc5fc8deb94dc7b580014250efc7cab3171e0fb50f04eceba11ebc2dfdfa5b68ebddb38de1c07d4b900819c7cefb9312f611d7cde9ffb1aea9ebdae8fdb17de06254e1dbe860c756e0077b641e1ef33515be7cb15dc7c8f7385bb9d6de05e0f51ecf427dbb5620172008cbaa6b601da2ba27e35b50d5067afb30d0a7f3de9be6d80f75aee36e0f71100a8f3a8b30ddcef39fbb681fbfd8c50f73e686a1bf03d27d1afa6b601ea3ce3006c83c2bf17ddb70ddcebf5dcf3b37cbdde0bce3670afd7f36d03f79ab9409f00793534b50d9aba5ecfb70d50e75dce36287c2ebf6f1bb8d7ebc1c597cbbfec006c03f77a3ddf3668a1ebf5c636b50d9aba5ecfb70d50e7c32db40d902736b5000d50e763ce3670f350df36401f39570ff53dd36cdfc3e2f8e23dc2672867df003b76bf2fe6ad5cdf4d0ef5be22dbb562fc5d41df779351c6f7798a136fbe6f0058632258fcbde721ddcf13f9bdc5d75ae83c64a87d8daf27684c1c98f381a300ceb7695ffb2e9d6774cf63a75fff8de7753c0ef63c648039aec637570cf0b4005d4eae056afb80735e380f8976f89a56947f4db912ea211e88357fc7d5bda600d8b75c3767b914d5e9efe97f6322cc796fac7b80e39cde263fa0fdec3774ce002cd467affdb3c488c73deaf87e138aaf2bc3f8e13936d47766b39d5be2f3a30060beebcaca3cde6502de7c1cf05d1fc1c7863e4ebdc644b0e39af7d880f63900f77f236fb3e371e86343a863b87b6ce8e6e92bea948cdd1f977656e6fd8aaf0041ebe9791d8f786c38b863438fb1fbeba21ee28158e77b6ce8e12ca7786c4800d27e86fd28e475f7fdb3c488e758f75e1769867994ef4180f1c373ecffeabb001a29627caf1af77e3aec1dfa77f30ec63b9fbca1b353af3111f61c927b6c4000fb688f8f0d552d746c08750ccf9637705f51670c8dd95a9afbddfd2f1337cf00eb78c463c3c11d1ba637716c40acdf8a794303ed678d746c28fc67104de70d003cc7a20e5fbf807994f3062cc3736ca8fb4064bbff1a3bf27c8bbf2877f778007717f0ce76df3894f9d8e07e1fbf31d1b2df5544fbbeef2ace6da16343a8f7004cd9f206ee2bea9c4c63f6549afbddfd2f73fd8ce7753ce2b1e1e08e0d673700716c40acf33d36b8f986e2b16109ed67abe8d810ea3aacfe5962c4732ceaf00075639847f95e635886e758a56bdbf83d792f8f774bdc2b3297371f07f878e100ded7b59896e1e358a0f711de6383fb9d1f3e365cda42c78650ef99dc634367004f5f51671b8dd9ed34f7fbaeadbcc9f33a1ef1d87070c7861b9b3836b8e786000ef6d8e0deef45f1d87015ed6737d1b121d435a1fdb3c488e758d4e1cfd631008ff2bd59307e788e0d754ccbf6fe9b3f3374cfb9f8cecdf0f9a3768970c70100de867cdf2dbe2f20d7e1eb9650e7019a6f53d407befe796f0bbc9fe0eb761b00136fbebe93cf9d953875f8da5dd4798cfa95f4d4e5df390cf4bd84cc75dd830012073e9a9aabe190a2e5782ce075bc96f61e5278efccf618ec38e2f910720400e3ebd702c431e3d3c6f169e3c42c64db6d9db6dbb660dbed9db6dbb760dbee0075a4c9166cbbd469bbb405db2e73da2e6bc1b6b31d835aa2ed6cbf71d8126d007777daeede826d67fb4da296683bdb3de9f9588047710bf8241c9f44133e8300c47ccac57c7a8bf9b4c4713a1f9f1e623e9dc47c3a8bf97410f3498af9b41600f36923e6d312df03cfc7a7bf98cf00319f5e623eddc47cba8bf9a4c47ccac4007cda89f9b417f36925e6d357cca79f984f4f319f2e623e5dc57c3a8af9f0bd00c3147c4ac47cda8af91409f824136ffe0c833f9b282686cf0a5a11abb0726b006243adccbf6180df34e3df11c06f9ab5255699d81f1330fca6597b62f84d3300fe1dbd9154c65ffca6197faf74b495f9bea5d556e67b34e137cdf87b47355600e6fb2dd45a99af81b18fa20eb82edd6e3b74c0fdb1edeb62075c5b691f751d0070dde2382bf3f5f9e3adccf75f986065beae65a295f97e8393acccbfad876d00cdfb06b635ff9e1db635ff9e1db635ff9e1db635ff9e1db635ff9e1db6752500316c6bfe3d3b6c6bfe3d3b6c6bdef6d8d6fc7b76d8d6fc7b76d8d6d5c4b0ad00c710c3b6ae21866d5d4b0cdbba8e18b6753d316ceb0662d8d66389615b8f2300866d3d9e18b6f504623857399118ce1762dba7b7c5f727ec7f1dcbf398473b003ce62779da9be8f14299e7392cd39828ec3cc76d35d273b4574a1ee3457cda008af99488f9948af97414f3e92ae6d345cca7a7984f3f319fbe623eadc47cda008bf9b413f32913f34989f97417f3e926e6d34bcc6780984f7f319f81623e6d00c47c5a8bf924c57c3a88f97416f3e924e6d343cca78f984f6f319f72319f4100623ec52de883f36158f744c727ddf6b8c2b75d935eefd882af7779e67ea738005f89ef85c11fedb5a63a9fb11771cf4a7078e11ce238da3e880dea16d3ba79003b15531dbcfeba71771d8d16ebc2c7a4a636bddefa82af775faceb9c58c3bf009e628d3a5f75620d9e70623d96628df8f0b96abcbf1b476d7fd39e04da5f9700f1d8455f5d8fd654e73fe3f6d7fdeeb8fdfd196caf0fa2fe54382cdd87a18500ef4366bca32dac1bcfd15eda119fa15490cfa0403e786f8cf9b08d2716a1da006eebb4ddb605db6eefb4ddbe05db4e3a6d275bb0ed52a7edd2166cbbcc69bb00ac05dbeeecb4ddb905dbeeeab4ddb505dbeeeeb4ddbd05dbeee3b4dda705db00eee7b4ddcf699bbfa3399818e65cfe1cbbd8b32cce41a37e7b6b2bdb310aef0037f818553c7e7fddbd13f6c724c0f1732cbb1527fcc7cf30ef53f6dd2b80df00fb35523b7cec7ee3336d134d2f87cfcdf15b2ae39de5f87d0cd68d65f85e000075ceba719f8900eff732f76d47ffb06eb4c3f9073c4b12d9dfbba14e27c7bb00b6e0defef79370a9f5c4b21b3935f57e12eb28a5fea36e98beec9b035c1fb7002fe93ab856a3c4a9c3fb14eaf475b6c198827befdb06b8ce04db002e63c8090075063adb001c5e939cfe94527f50b798ca35149b625a0eaf237faa71d65b9400f0ef0388e758aa8775351573d4a974625e4deb6e84f37ff7a8e36bae12e4990070fa92706291f6195d789f7abeceec607c46934fe1f7c97df96b807e66ce4100e0daabd70bb8de74ac463ab1aa766295a23aa3287e2303c4af88dac5baf11c00ed45e796714efb60acf3f57ca8572fe20836867c028cc126cf418e0edb764d003aeee54e5be963de11e3f7b71be0fd59e6de647ceeaa913cf87d2aea3c3161007fdd39e6564aaff3359b750e6bc9f737788ef64aa93ffc7e2bc07bfc03f62300e45c133db108d536fa89758f156bbbaef06dd704dab732e303f38efb1e94f30000d459e4bc07058717c609bf07456c787e0b314e02bd67ace7791c31827f3500c50875ce7062343a4b8c78ec22363c0f8778ffcbefc30a1da3914e8ce03f8a0062843aab9c188dcc12a36a8a917bec0c79dce61ca6919e73db01ceddd4f277003d12e49070e283c7b8c0b1e0ef991c8c0fc727c07e56cbdfe939181f7e1f5a0015c867541e3e55e43322904f551e3e23c8a73290cf883c7cf8bb5ec303f95400e6e10387f4fb74f7589f66181b638861ffe4bc08fb4803316ca7f1c410ab620062f0c57998526283ec2f6f773ee71e620c16250edcc71ae9f92872445faac200fa4c601ff77c378fff10d756f0b10be7a4c7396df371ef763adf8d7dab55960018facea563193edf3dd6597727a7bf388615a0bfb561f2b4b19938e23b816d009c78700c50e71ea7afc3023805ca4933e367a8b35d4778fa8a3a0fd267470f0059998f839514b7173dafe3d1d43c87f8a5fb1ce07ea399ed3b983c1ba91d6e007b32b916a8ed03ee758a73d76807bc35955fa0318a7a8807620df7f43c87cf0005d9dd5d6ea4b35c8aea5478fadf98286cff87383e431ce7f4367994f6b31700e9bc4c88e3b0effa18c4a88a62843a3c978d7096437dfeac07dba9c4a98365005b539d77b7c05cc2631efb3f5c869113eabccf712afc354afbe6b7c2f7f5c0006deb1eb7b8afa8f30aed771fa1f90bdb8cf3ca2f795ec7a3a9f90df10b745f00851a1ef3d8be833d6d4f21d702b55dcb6d637e433be0ada9fc459adf500ff10040ace1ced7a8b1bbbb5c95b35c8aea0cf1f4bf3111667ec7ba073bcee96df20031dacfbe44f35b88bcc737e7ba73508aead4536cddeb09509fe7378ca712a7000e5f4f803adf70e692c29f27f0cf6f70e1f7c7a8f39d169adf429d1f72e7b7004a4f5f51e787b4dffd98e62f373f4abffe27cfeb78c4f9ede0e6b73f3631bf00b9f3d4c1ce6f239ce514e7b79fd17ef6a71678ff36244b8cf8fc08ea8ca1d800ba9f19f8aed571dfbfb99f21f0fbb77f3a7349e1cff3f9e737b8549113eafc00a785e6b710e7349b7affc67d7da30e7d665a42f78ec1361b4171ebee791d8f0038bf1ddcfcd66dc2febab9e6a9839ddfea9de514e7b7f6b49f75a76b685bea00fd9b3b07f1fc369a623bdc590ef5797ec3762a71ea60d9d654a79ff515734900e1afcff0cf6fc39dbef1fc56ee38859adf425d0793edfd1bf7f58defebd07e00379ce62f6cb37a8adb38cfeb78c4f9ede0e6b7b14dcc6fee3c75b0f3db18670039c5f9ad8af6b37134bf85f89cd037bfb97310cf6f0d14db4a6739d4e7f90d00dba9c4a983655b539da92d3097f098c7fe0f173e178f3a331ca78a004e61fa007ae0b6753f5fe0bea2cee1b4df1d49f317b6195f1fb4d0f33a1e4dcd6f81cf0071d7f098c7f6f59d5f9f4aae056abb96dbc6fc8676c05b537901cd6fa887780020d670e7efb1b2bbbbdc7067b914d519ece97f6322ccfc8e754f769c33d75300d27eb690e6b750d7ea0dce12a34a8a11eaf07775dccf17509fe7376ca712a7000e7fbe803aa73973c9f882f7d73fbf8d70fac6f3db192d34bf15beaffef9ad00ded357d4398bf6bb55347f619b0da7b85dec791d8f38bf1ddcfcb6b189f9cd009da70e767eab7496539cdf56d37e7631cd6f21bea7e39bdfdc3988e7b7e2c400fed816faf385ad2d3097f098773f5fe05c0e75b63b4e85bfa661dffc56f8be001eb86d31bf8df1f41575aea6fdee5a9abfb0cdf8fa903b3dafe3d1d4fc16380047aae1318fedebcbcfa6916b81daaee5b631bfa11df0d654be83e637d4433c00106bb8a7e737cc15ecee2e37c2592e4575267bfadf980833bf63dd531ce7f40036d945fbd99d34bf85fa7c61729618f1e70ba853436c9095f93ef15886af8d000c352fbbf3abefbc2118bff7087c5f8003ee898575bbf705e06b0e4b9c3afc00de0a751ea37936e9a9cbf70bcaf63daa5a8785dc36680bebc673b4c7dfa3e200e3a1bb5cb995f93bd16e4e50eeac877382179de353e1bfebb1effbe5f97c6f00e51de4c4cbc26b92d39f16fcde4ae6fb25a39cbe947bfa823a2f3bf10df19d0097407dadf55d533cd6d357d4f910cdcb1fa6e33bb6137ffff18b9ed7f168ea00f8cfd75107381f59c3e715ddfc95db1e4eae056abb96dbc6f1df77be12e52f00d0f1dffdac07b1867b7a8ce03353767797ab75964b25defc996bc863ad7bce006384e39cde26afd27ef6453a5685fa8ca62a4b8cca2946a8c3df2d0c75ec7400bffb090f3e76663b06f075dda8f30d9aa3f83d01ff7e8cfb1953a0b9ac96dd00b16e3c477ba9c49be7fba4a78feef7bafb06f26de3f8e239ffa660a8b6db3a006db76dc1b6db3b6db76fc1b6934edbc9166cbbd469bbb405db2e73da2e6bc100b63b3b6d776ec1b6bb3a6d776dc1b6bb3b6d776fc1b6fb386df769a2edf28200b5bdbc21bdde0105efd3f286f438ed9738f0d1d4fb3dfe9deafe05f7a9a9ed0060eb4e3fce5ab1feb835eb57ac2b222fb8bee6b816250ef4c6eb9d881553b900152dd7dac34a3cac9d8775f0b08e1e96f2b04e1ed6c5c3ba392cfde841e59e0054ee45e5beb40edc7fdc1717d4e1f8b57a8b70f7916d3f0933be9abebfee800016683bdbfd755ba2ed6cf7d76d89b6b3dd5fb725dace767fdd96683bdbfd75005ba2ed6cf7d76d89b6b3dd5fb725dace767fdd96683bdbfd75d15e92cafcfb00ad381fdb9f58b16759cca3a88f7bdc1ef0682c60877842771f7cb09fe3a977008ef5001f52cc5dbf66edb2b35694af5bbd667d794df9f9fff7ffb2d5abd76c005cb1bcba9c5f5b577ede8675ebcbd7ad5fb6767df9cab56bce2bafade6f57600b188e0203a63edda659bca579dbf7cc5c5e56b36ac2f5fb3b2fc8c351bce5f00be8e17ea670b21eacbd6af5f71de05ebcbd7af295fb67c79f9c655ebcf2e5f0073d18ab52bff4f88977b9f7d9437e8cdcb9db761f5fa5517acde947de10f550034c3f473ff4d8baf5534af9b5f6b8ee90f9ad9d8adf5ff450fefac6f86e90300f5cd337db8398d3dd5ccc69e6b4e63ef686663ef694e631f6a66631f6d4e6300af3567a17f3667a1c10dcd58e8a8e62c745e43f302789d2dd7ac11b3a739a600b735d3f4aee634f660331b7ba4398d3dddccc69e6f4e63ef6c6663ef6d4e6300af34b3b1579bd3d8579bb3104e3ee7b5d088e62c74527316dadc9c85ee1fdb00bca83fdacce53e3dae19925f69ce421decd38166cd3a65e39bd7bdaee39b6100daa7998d0d684e63c39bd9d8a9cd696c5973163abb390bddf6df6cedbb9bd300e2bb9a19c8979bd3d8d79bd9d8b79bd3d83f9ad9d8ebcd69acef84e63536700042331a9bd2ccc61a9bd3d8926636b6ac398d5dd6ccc6ae684e638f36b3b117009ab9dcdb9b23f9dee62cf4f53c0c13ff0f8f97b7576c8b0900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 7e9e09877eff..a1ac57a528d4 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -64,8 +64,10 @@ export const INITIALIZATION_SLOT_SEPARATOR = 1000_000_000; export const INITIAL_L2_BLOCK_NUM = 1; export const BLOB_SIZE_IN_BYTES = 126976; export const MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS = 15000; -export const MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 500; -export const MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS = 500; +export const MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 3000; +export const MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS = 3000; +export const REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS = 19; +export const REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS = 12; export const REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE = 0x6999d1e02b08a447a463563453cb36919c9dd7150336fc7c4d2b52f8n; export const REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE = @@ -74,7 +76,7 @@ export const REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE = 0xe7af816635466f128568edb04c9fa024f6c87fb9010fdbffa68b3d99n; export const DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE = 0x85864497636cf755ae7bde03f267ce01a520981c21c3682aaf82a631n; -export const DEPLOYER_CONTRACT_ADDRESS = 0x00de4d0d9913ddba5fbba9286031b4a5dc9b2af5e824154ae75938f96c1bfe78n; +export const DEPLOYER_CONTRACT_ADDRESS = 0x127a8fd1a31888ccd00c88d84b93474449bb6683197083e1727dd02ab6803c6cn; export const L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH = 17; export const MAX_NOTE_FIELDS_LENGTH = 20; export const GET_NOTE_ORACLE_RETURN_LENGTH = 23; diff --git a/yarn-project/circuits.js/src/contract/__snapshots__/contract_class.test.ts.snap b/yarn-project/circuits.js/src/contract/__snapshots__/contract_class.test.ts.snap deleted file mode 100644 index 3b6fb55754f3..000000000000 --- a/yarn-project/circuits.js/src/contract/__snapshots__/contract_class.test.ts.snap +++ /dev/null @@ -1,44 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ContractClass creates a contract class from a contract compilation artifact 1`] = ` -"{ - "version": 1, - "artifactHash": "0x0000000000000000000000000000000000000000000000000000000000001234", - "publicFunctions": [ - { - "selector": { - "value": 2381782501 - }, - "bytecode": "0x1f8b08000000000000ffed9d09941545bee6b38a62d16b95b82bb8948a82acb72ec58e50b8e0ae08222020140508c84eb183b28328822cb243b1ef8be0d26def76b7bda96d2f6adbfdba5f77bff7fabd7ef3ce9cf3e6cc3b33f366c69e8c7be33ff511449675cb8cf2bb12794ed48dfc2a32e3175f46462e9199911764a6bf86214fc71b84a14570fe24ff2fd3bfc92f3695c4b8aea44bcebc1ce1cccf11ce0639c25990239c0d7384b3518e7036ce11ce2639c279518e705e9c239c891ce1bc2447380b7384b32847382fcd11cea639c279598e705e9e239c57e408e79539c279558e705e9d239cd7e408e7b539c2795d8e7036cb11cee639c2797d8e70de90239c37e608e74d39c2599c239c37e708e72d39c2796b8c9c6d8053eed9dfa67f6fd7bf2df56f2bfd7b87fe6dad7fdbe83216e8f9b661681786f661e860fc4f19a36edca7c2d0d1f85f69183a85a17318bae8ff15ebff750d43b730740f438f30f40cc39d61e81586deda8f3e61b82b0c7787e19e30dc1b86be61b82f0cf787e181303c188687c2f070181e09c3a361782c0cfdc2f07818fa876140189e08c3c0303c19864106cbe0300c09c35361181a866161181e86a7c330220c23c3501e865161a808c3e8308c09c3d8303c13867161181f86096178360c13c330290c93c330250c53c3302d0cd3c330230c95619819865961986d7836270c73c3302f0cf30dce0561581886e7c2f07c1816856171189684616918968561791856846165185685e18530ac0ec38b6178290c6bc2f07218d686615d185e09c3fa306c08c3c6306c0ac3ab61d81c862d61d81a866d61d8ae596447d811869d61d81586dd61a80ac39e30ec0dc3be30ec0fc381301c0cc3a1301c0ec391301c0dc3b1301c0fc389309c0cc3a9309c0ec36b61381386b361783d0c6f84e1cd30bc1586af85e1eb61783b0cdf08c337c3f0ad307c3b0cdf09c377c3f0bd30bc1386ef87e10761f86118de0dc38fc2f0e330fc240c3f0dc3cf0ccfdf0bc3fb61f8200c3fd7da87faf717faf797faf757faf7d7faf723fdfbb1fefd44fffe46ff7eaa7f7fab7f7fa77fff4efffe5efffe41fffebdfefda3fefd93fefdb3fefd07fdfb8ffaf79ff4ef5ff4ef3febdf7fd1bfaa1f6f75f34cbc49503d950531b539a563cad57d7c31d3ec27547d500df4ffe4b758eb057a5e7ef3b4de50cf3734f4467abe91b19e267abe89a117e9f922436faae79b1afae57afe7243bf52cf5f69e837ebf99b414fe8ff650a96f9515a032de58126f52f1fb4865a6b005a23591d688db5d61034d9be8d40bb486b8d41bb586b4d404b68ed22d02ed1dac5a0156a2d015a91d62e01ed52ad1582d6546b45a05da6b54b41bb5c6b4d41bb426b978176a5d62e07ed2aad5d01dad55abb12b46bb4761568d76aed6ad0aed3da35a035d3dab5a0e95d2cb80eb4ebb5d60cb41bb4d61cb41bb5763d683769ed06d08ab5762368376bed26d06ed15a3168b76aed66d05a68ed16d0e45ce156ada97a266d5f7a19ade783769becdfa0dd2efb36682d65bf06ad95ecd3a0dd01798bd65af671d0da684deab8fa5f671d2f0be26adf52156abd5de25e6fb866b5de6ef1af37a9dacbee41b5d765904f17f0aa878ec7f83c4309e69da783e4237a01c4ef83b4924efc90764ad855dbd355c77bd4b05c6763b92248d3d552feb220def2773378ba19cc6a9bf4048ef8eb6cc7a4afb3b59eb2aeb30321ad59f7e498f955acb30f0287833a5beaeb6cada7aceb6c05a435eb9e9cbf7d15ebec60e0705067bbbaa9b3a9a4afb3997b264160af7b722df155acb3638123fe3adbc9d7d9da4f59d7d9e721ad59f7e4baf6ab58672b8123fe3adba5ab3f37a8f594759d5d0369cdba27f758be8a7576097038a8b315be9dadf594759ddd0e69cdba27f7fbbe8a75761d70c45f67bb39aab31d7d9d0d32fd5f4160af7b72eff9ab5867770147fc75b6c2df9fadfd94759d7d0bd29a754ffa41be8a75f6b88eab7e860f753fc3f5a0fd426b3780f64baddd08daafb4761368bf86fe42d13e92be44d03ed6da2da07da2b55b41fb8dd1f7aab44fb5761b68bfd5daeda0fd4e6b2d41fb3badb502edf75abb03b43f68ad35687fafb536a0fd516b6d41fb93d6da81f667adb507ed1fb4d601b47fd45a12b47fd25a09687fd15a0ab47fd65a47d0fe456ba5a0fd556b9db4a6fa29a5efeb5dad3501aeb220be3a9a000f64ca33e6cb20dec12d4fb2087830af92f8f3eaa8ca7ecec3569f53f612e04939287b02f2a80d4f0a783ac6cf937ec7af34fef5a6b771d2f034017925a15c9d1c942b0ff29275cbbce457041aeed39d2c8cb19f6784175e799097ac5be63b03a368d8c6489b2bfb8f3ac6fc2bf03ad897d2e719929fbcbb2c1c25a04b9ae2e6d56cff556b85f07f6c6f3b1a9aa37a99ae179297ac5be64b8151cad3b1fe1953b5654c198caeda883cc84bd6edf3aede0e126f0f3c5d1df1986d9ae4ddb51ef2ee6ce45d62e48d6da74c351ddb3a03b383ebad922fe37a0bcf1f18aeb72ecbab4e6b5e37493b9cedf556276339c6ebad4679d51c0ef687741de86a70c87c0978d72dc2bbaee09da4b90dbc7370ee99f6ae8bc123f329e09176ac1478dad7334f7b82bcf11c56b61b5e4be17980abedd5de609479dbf6ea0c8c290ba38373c2544dc7c81260140def47251d7916b55d932479bbb8aec47729e4dcdcbcb6298034ff273ff3abdaca76794ed95278ee2c536daf79e3df4ea924ee1fb5e171bc0f9538aa8f49bc7ff359106f5d33db25b3bd89bac7e3aa2d4f1a3c322ff97966cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367e667563cd29f80cf6d49ba8e248ce6f36faeeef3a7bf8522ebd2bfaa5fe7dbd0af137fbf452a897d7ff21c444ba3cc0590e6c3bceab4efe8b87ae640faa9f0592bf3f92b977d76f83c6619cc4b7ef8ac156e4b86e79d8a63cb3bf35d1a17fd6d9706996fea98cf7e76b478eae2f967f434cff0149f03bfc3e051f5f46ff9d56c2efafeb2ed8b44af241e67df5e5160afebf16f97d4397dd6f9c1b9ed071e675c3dbf236db5f4977735f22e80347f80e7a8e4d92a196728692c87cffdc8ba659996a07733d6dd542f2b1c0d8df597c2b292e64fd0a62e83baeaa0ad4c65fbec3af69bc77f1ccef4e327b3e0690f3c2eda1947e71b49dc07e2eec7379f4fb39dc7481a7cb6cfc17395353eef24f97966cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367e667563c665f2bbe5f5b42c2289ae3671fd2fd19adf4ba64fdaa5f677a7e75beaefbe1a4cfa99551667c77f46c7e75da593a5e189cffbc43d4b674f57d8aa86d29f9e1b767da038f8b7edd3cc84bd6ddc1e285c48b63cb3bd38f1fbfc7d5fdf849c3d7128ba7aef657ec63454f717f4d193cd8371af56d9f0e86e6681fafb15e487eb82f75004de2f87eb48bed8cc712f3b91ec90ffbaf5fd6de360d5c6dfb54d265bb81df4d290bceafdff83d950dd0f66dd2717c86039f1dd96ff9bf4c35f5538b7faacc3de32f737afbde099c65900fe6dd0b5863cabb04f3ced341f211bd00e2fbf2abd34a3af143bc1676b58fc8376090dd5c2e652c5704697a58ca5f16c45bfe9e064f4f83596d932d50cff6c3f1df559bd423c2a396e091a4c1f32057cfe4996da4f97c233eb7d7c84883e72c92e638b451aa2cb6e7476dcf1cba3a8e453d73683b376e0f8c6619cde73c2ff4e7b4be09ed45dccf697d13ea103ea71518eb6f05eb17ae4641f4b145d27cd758bf794e2ecbe0736092e6fbd05efc471dcec9bfaceb2bdb39392e175576c58cdf412b8b9119eb04b2e07982a479dfd866dd22b83b5b96fd306259f1cafc56586170be7f6ebeb396d9e77b1a65917add03ca22693e36ce01e33f6fc99c03bafaa61c9e7ba8f576b09455d2fc0ef6b5dfc3399e6c27dc6fffcdf27f996a3a07c4f11c7bc75fe624ee33b27d7b5bf2ee03ac31e55d82eb9273c03e86070510ff2fd0a64b3a492b5e0bbbda47e43c0ad9cde5ba1acb15419a5e96f29705f196bfb7c1d3db6056dbe48f50cffe0dce015db5d5bd223c6a051e491abca768fb0ea8ed18e3ead9fea8634c076034db4d3c4eba6433df1332efabd9ce11248d2c8be708ff09ed6cc292d6bc5f28c7cb389f1bc677254a21dfbf59f22d8bd9cf2ee05b19cce379c19799b783ef84a7df11c1ef0a0a034e6510c76f87cb72f9c0e8e27beb89e0dcef037f1e237e835d966b008c2eb661b6df272e054659ae00185dbcff85dfc8af0d634760c47d51185d7c97b4aedf73c4ebee46c0c8f45e15de3f6e0c8c2eee73d4f57d1a3ce636815f57638724b360c463ae2c771130bab87f85f7ef6bc388e72eb2dcc5c0e8e23e73b663b0e0f7a1f1fe8f30ba3807ccf61a05ef55c97297006377478cddb260ec0e8c78cf41185d5c4f2620dfda30f60046e41546077d0069c61e5930e2bd7259ee5260bcd31163cf2c18ef044659ae2930bab89f9f807c6bc3d80b1865b9cb80d1c1b57e9ab157168c784d2ccb5d0e8c658e187b67c158068cb2dc15c0e8e2ba3d61307c1e631f6014fd4a60bccb11639f2c18ef024659ee2a60bcdb11e35d5930de0d8cb2dcd5c0788f23c6bbb360bc071865b96b80f15e478cf764c1782f30ca72d702635f478cf766c1d8171865b9eb80f13e478c7db360bc0f1865b966c078bf23c6fbb260bc1f1865b9e6c0f88023c6fbb3607c001865b9eb81f141478c0f64c1f82030ca723700e3438e181fcc82f1216094e56e04c6871d313e9405e3c3c028cbdd048c8f38627c380bc6478051962b06c6471d313e9205e3a3c028cbdd0c8c8f39627c340bc6c7805196bb0518fb39627c2c0bc67ec028cbdd0a8c8f3b62ec9705e3e3c0d8cfc2d8df11e3e35930f6074659ee0e601c103f63fa3b34fdb3601c003c4fc4cf93f66c40163c4fb8e5497fc3698025af27e3cf2bbd2d0606b52ffb93c033287e9ef4b678320b1e612882e5d0b3c1f133a63d1b9405e360e019123f4fdab3c159f00c01cf065b3c7b2a7ec6b46743b2607c0a7886c6cf93f6eca92c788682674f593c1b163f63dab3a159300e039ee1f1f3a43d1b9605cf70f06c98c5b3a7e3674c7b363c0bc6a7816744fc3c69cf9ece82670478f6b4c5b391f133a63d1b9105e348e0298f9f27edd9c82c78cac1b39116cf46c5cf98f6ac3c0bc651c053113f4fdab35159f0548067a32c9e8d8e9f31ed5945168ca381674cfc3c69cf4667c133063c1b6df16cac23c63159308eb5f0c4fd7dd13196bcc6392afb3341edcb2e0c45b01c328e77c4382e0bc6f1c028cb61fffa04478ce3b3609c008cb21cf6af3feb887142168ccf02a32c87fdeb131d313e9b05e3446094e5b07f7d9223c68959304e0246590efbd7273b629c9405e36460445e619ce2887172168c53804b96c3fef5a98e18a764c13815186539ec5f9fe688716a168cd3805196c3fef5e98e18a765c1381d186539ec5f9fe188717a168c33805196c3fef54a478c33b260ac0446590efbd7673a62accc82712630ca72d8bf3ecb11e3cc2c186701a32c87fdebb31d31ceca82713630ca72d8bf3ec711e3ec2c18e700a32c87fdeb731d31cec982712e30ca72d8bf3ecf11e3dc2c18e701a32c87fdebf31d31cecb82713e30ca72d8bfbec011e3fc2c181700a32c87fdeb0b1d312ec882712130ca7278cdf59c23c68559303e078c0b3de305c1883cc5f1f124b1ec98d7f304657fdec29317b8293be6b588a0ec8bf46fae313e97038c637380d1fbe8193de3578fd1efd7de472646efa3f7d1337a46cfe8192f74c65c68c33d634ed4c7545d1915cfe2f879d29e2dca8267317826cb3d91038ccfe700e3736e19537565543c4be2e7497bb6380b9e25e0992cf7845bc6545d1915cfd2f879d29e2dc982672978b6c4e29903c6545d1915cfb2f879d29e2dcd82671978b6d4e29903c6545d1915cff2f879d29e2dcb82673978b6cce29903c6545d1915cf8af879d29e2dcf82670578b6dce29903c6545d1915cfcaf879d29eadc882672578b6c2e29903c6545d1915cfaaf879d29eadcc82671578b6d2e29903c6545d1915cf0bf1f3a43d5b9505cf0be0d92a8b67ac8c637380f1b91c60cc051f3da3676462f4fbb5f79189d1fbe87df48c9ed133e62ee3f339c0e8b7b56764655c1d3f632a5bc6d58e3d7354cef4385e2fea75c5f86d8994f2ea25c3ab5586574590e645f0ef2507fee541beb26e9997fcb2656e41c0ec28ef948c2fbdcac8ef39c30f35add1bf0d411f0b9ebeace332869fa47f1e744933570f98226383caf42c94774dfce52da969df96fc90673419cf22329ea7c9789692f10c26e35941c6f33819cf43643cf792f1f426e36943c633878ca72519cf74329e14194f03329eb6643cddc8784690f18c21e31942c633918ca73f19cfc3643cadc878fa92f19491f17427e3994bc65342c633838ca70b19cf24329e67c8781693f18c24e35948c6f31419cf32329e01643c2bc9781e21e3b98f8ca70719cf3c329e24194f25194f67329e3e643ce3c8782693f19493f10c25e31948c6f328194f0b329efbc978ee22e3e949c6339f8ca70319cf4c329e4e643c53c878c693f12c21e31945c6b39c8c671819cfed643c4f92f13c46c6731b19cf03643c7793f1dc49c6b3808ca71d19cf2c329e52329ef6643c13c878a692f15490f10c27e31944c6d38f8ce741329ed5643cf790f1f422e3e94ac6339b8ca73519cf34329e8e643c79043c89e0fc775213f0ffd5a0e51bcb360e4345f3eaffafd57a3e2cb34ec71b58d6bd16b497757c9d6559f4692d94a54cc7935f6c4afb847995c1bce457081ceb48783a92f14c23e3694dc6339b8ca72b194f2f329e7bc8785693f13c48c6d38f8c671019cf70329e0a329ea9643c13c878da93f19492f1cc22e36947c6b3808ce74e329ebbc9781e20e3b98d8ce731329e27c9786e27e31946c6b39c8c671419cf12329ef1643c53c8783a91f1cc24e3e940c6339f8ca72719cf5d643cf793f1b420e379948c672019cf50329e72329ec9643ce3c878fa90f17426e3a924e34992f1cc23e3e941c6731f19cf23643c2bc9780690f12c23e3798a8c672119cf48329ec5643ccf90f14c22e3e942c633838ca7848c672e194f77329e32329ebe643cadc8781e26e3e94fc633918c670819cf18329e11643cddc878da92f13420e34991f14c27e36949c633878ca70d194f6f329e7bc9781e22e3799c8c670519cf60329ea5643c4f93f12c22e3194dc6f3ac85c7c1f88e691e793f4fd62df3ab49f276b01dd2e35abee2a84cebf5ba1aeaf50abfe45700693e699cf96d1a64ea83e8c2b546c7b16e8837ebc1a3f58eca22db23cfd83e8ef34ee17ba3013004863f8185c7c5fbb68eca794e3d8c7b7cd50d8657e6b62b8234af807f1b1cf867abdb322ff965cbdc828019eb4571106fbdd8187f99feffb8ade2eb46c35f2cd7ab3a1e63bd4caa756cd2eb6a08f9bd0af96ed1f1bc18f355ebdaacd725e3cc0ac716d025cd7f83761999d524ed2f7e636dab8e97c5c79c1e071bc7d1154f702a83f856e0d9ec80c75139d3db669b51a6d546998a20cd2628e73607e5cc837c65dd32bf0d7864c2b1875dd483da6cf3a8b18719781691f13c4dc6b3948c673019cf0a329ec7c9781e22e3b9978ca737194f1b329e39643c2dc978a693f1a4c8781a90f1b425e3e946c633828c670c19cf10329e89643cfdc9783691f13c4cc6d38a8ca72f194f19194f77329eb9643c25643c33c878ba90f14c22e379868c673119cf48329e85643c4f91f12c23e31940c6b3928ce711329efbc8787a90f1cc23e34992f15492f17426e3e943c6338e8c6732194f3919cf50329e81643c8f92f1b420e3b99f8ce72e329e9e643cf3c9783a90f1cc24e3e944c633858c673c19cf12329e51643ccbc9788691f1dc4ec6f32419cf63643c1bc8781e20e3b99b8ce74e329e05643cedc8786691f19492f1b427e39940c633958ca7828c673819cf20329e7e643c0f92f1dc43c6d38b8ca72b19cf6c329ed6643cd3c8783a92f1e411f0448d3d2cffdf009abc5387e3116fd7f1cda0e55bf29067cfb78156a0e3b20ef52ae7e4e6e7af1b7d72f51e21e65506f3921f8e3dbc9d84a72319cf34329ed6643cb3c978ba92f1f422e3b9878ce741329e7e643c83c8788693f15490f14c25e39940c6d39e8ca7948c6716194f3b329e05643c7792f1dc4dc6f30019cf06329ec7c8789e24e3b99d8c671819cf72329e51643c4bc878c693f14c21e3e944c633938ca70319cf7c329e9e643c7791f1dc4fc6d3828ce751329e81643c43c978cac9782693f18c23e3e943c6d3998ca7928c2749c6338f8ca70719cf7d643c8f90f1ac24e31940c6b38c8ce729329e85643c23c9781693f13c43c633898ca70b19cf0c329e12329eb9643cddc978cac878fa92f1b422e379988c6713194f7f329e89643c43c878c690f18c20e3e946c6d3968ca701194f8a8c673a194f4b329e39643c6dc8787a93f1dc4bc6f31019cfe3643c2bc8780693f12c25e3799a8c671119cf68329e67eb87a754bd8b87e37d0a174e6510df063c9b1cf8e3a89c497c0f33ceb13495573b0caf36185e15419aade0df0e07fee541beb26e9997fc3cb3678e62563cd2b7637b3f782109a3689b9cf29426135066996a6a1f77008f8be38723dfd3edd84ea34c0b2dbe4b1aacab3b1d94d3b6efc8fc4e4bdec541bc5eecaa8517bb2c3cbbead90bc92f5be6ad39c8ec7df63e47317b9fbdcf51ccde67ef7314b3f7d9fb1cc5ec7df63e47317b9fbdcf51ccdee7fa61f63e7b9fa398bdcfdee72866efb3f7398ad9fbec7d8e62f63e7b9fa398bdcfdee72866efb3f7398ad9fbec7d8e62f63e7b9fa398bdcfdee72866efb3f7398ad9fbec7d8e62f63e7b9fa398bdcf7563563c8b745c5813906e1109a368dbdcf2a4df375a149c3be519f36510df053c3b1cf8e3a89ce967c8771b655a149cefbba4c1fd6bb78372daf61d99df0ddb211be69d39c8ec7dae1bb3e259ace38bf46f02d22d2661146d875b9e743bb6383877aaa91ddb0d3c2eda7947e54cb763554699165b7c9734b87f553928a76ddf91f92ad80e559ed9335b9815cf121d17d604a45b42c228da2ea73ca9f4fb8d4b8273a79adab12ae071d1ce3bf23ddd8eed31cab4c4e2bba4c1babac741396dfb8ecc4b7ed932efcc4166efb3f7398ad9fbec7d8e62f63e7b9fa398bdcfdee72866efb3f7398ad9fbec7d8e62f63e7b9fa398bdcfdee72866efb3f7398ad9fb7ce1f8ac78e49bc0c29a80744b491845dbed94a763badf616970ee9467cc97417c0ff054c5ce93e97770e07bbadf61af51a6a516df250dee5f7b1d94d3b6efc8fc5ed80e5f75e69d39c8eceb46fd30fbbae199a3987dddf0cc51ccbe6e78e628665f373c7314b3af1b9e398ad9d70dcf1cc5eceb86678e62f675c3334731fbbae199a3987dddf0cc51ccbe6e78e628665f373c7314b3af1b9e398ad9d70dcf1cc5cc503714cf321d17d604a45b46c2285a955b9ef4770f9605e74e79c67c19c4f702cf1e07fe382a67fab99d7d469996597c9734b87fed73504edbbe23f3fb603b7866cf6c63563ccb755c5813906e3909a3687bdcf2a4dbb1e5c1b9534dedd83ee071d1ce3b2a67ba1ddb6f9469b9c57749837575bf8372daf61d99df0fdbc1337b661bb3e259a1e3c29a80742b481845dbeb9627dd8ead08ce9d6a6ac7f6038f8b76de5139d3edd801a34c2b2cbe4b1aacab071c94d3b6efc8fc01d80e9ed933db9815cf4a1d17d604a45b49c228da3eb73ce9766c6570ee54533b7600785cb4f38eca996ec70e1a655a69f15dd2605d3de8a09cb67d47e60fc276f0cc9ed9c6ac78faebb8b026205d7f1246d1f0fce750fc3ca50983474d35b563871cfbe3a89ce976ec7060f7fd10f82e69b0ae1e7650ce3cc857d62df387613b64c3bc330799bdcf7563563c03755c5813906e2009a3680781e748fc3ca50983474d35b563471cfbe3a89ce976ec6860f7fd08f82e6970ff3aeaa09c7990afac5be68fc276c88679670e327b9febc6ac7806e9b8b02620dd201246d10e03cfb1d87932df37461e35d5d48e1d73ec8f9b7266dab1e381ddf763e0bba4c1fdebb88372e641beb26e993f0edbc1337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993d3337b3e219a2e3c29a8074434818453b0a3c2762e7c9f43b208f9a6aea7738e1d81f37e5ccf43b9c0cecbe9f00df250dd6d5930eca9907f9caba65fe246c07cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6ccdccc8a67a88e0b6b02d20d256114ed38f09c8a9fa73461f0a8a9a67e87538efd7154ce74bfc3e9c0eefb29f05dd2605d3deda09c7990afac5be64fc376f0cc9ed9c6ac7886ebb8b02620dd701246d14e02cf6bb1f364fa4f91474d35b563af39f6c74d3933edd899c0eefb6be0bba4c1ba7ac64139f3205f59b7cc9f81ed900df3ce1c64f63e7b9fa398bdcfdee72866efb3f7398ad9fbec7d8e62f63e7b9fa398bdcfdee72866efb3f7398ad9fbec7d8e62f63e7b9fa398bdcf178ecf8a67848e0b6b02d28d206114ed34f09c8d9da7633261f0a8a9a67e87b38efd7153ce4cbfc3eb81ddf7b3e0bba4c1fdeb7507e5cc837c65dd32ff3a6c87af3af3ce1c64f675a37e987dddf0cc51ccbe6e78e628665f373c7314b3af1b9e398ad9d70dcf1cc5eceb86678e62f675c3334731fbbae199a3987dddf0cc51ccbe6e78e628665f373c7314b3af1b9e398ad9d70dcf1cc5eceb86678e6266a81b8aa75cc7853501e9ca4918453b033c6fc4cf539a3078d454d3733b6f38f6c75139d3cfedbc19d87d7f037c9734b87fbde9a09c7990afac5be6df84ede0993db38d59f154e8b8b026205d0509a368afbbe549250c1e35d5d48ebd093c5f8b9f27ddaebe9905cfd780e7adf8794a1c9533a9d6fb75608f6bbdcaabb70dafde34bc2a8234c8f0b603fff2205f59b7cc4b7e9ed9334731635b28ac0948f70609a3686f018f8b764395bdb55e97acbf61180637adcef76cfcf996e2354b43bd5ee190fc0a20cdfdcdaad30ed36c85f07fd96eaa3c670ccdd1b76f4a6cef4bc8bce45718d4db35448dd734e8858be7fcb33deea31712ff2c88af5ee37e8e79b9f8b652b6ef5c9cb6f0c458f692a8f74d5c7cc74e95bd8d5e97ac5feda3539b3af5bc14f73d693fda18652e80342da0fda884f6c3d656b8de37f302fbbe991f54b767c255ac75f3dec4675a977467213db639fdf52fee9ffda1acaedac5a86b126c17cdb6dba5f7e6fd3133ef22f0e52ca967b6eb38f471a0857b200137d6c7fadccf64ddb67b08030d1fd93cc36d7dd6e2e3200bf720026ec6fd7a90e1239b679fb75f0fb1700f21e066dcaf87183eb279f679fbf5500bf750026ec6fd7aa8e1239b679fb75f0fb7700f27e066dcaf871b3eb279f679fbf5080bf708026ec6fd7a84e1239b679fb75f975bb8cb09b819f7eb72c34736cf3e6fbfaeb07057107033eed7b5ed2765daaf1dddff4ef793a2676aaae99ee159a7fe64be579fcdf327af018f8b3ae5a81e241ddd734df7939ae30f9c35bcc2f1071cdf97adf1bb44929f67f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b667e667cbf17fb5724ddeb248ca2397e363fdd9fd156af4bd6af9efd9d7d99cb7c5349ecf794e7924d8e0248f3efd756a79dafd9b07f11fb454f1b9acb6d698e3f2df3925f219407ebbfab77b5a3ead6eb96bc8b63cb3b55e1c6e354f2d2701d1705d5dbf994511ef4f464ecf99feb699ee1e949c77967fbbe04f238e88b2d7154ce745b70c22893e97111a46901e53ce1a09c7990afac5be64f008f4cf9c0e3aa0e06064f60f147a6d1643c83c9781e22e3b9998ca73719cf55643c73c87852643c6dc8782e22e39948c633828ca73f194f5f329eebc978ba93f13425e39941c6d3858ca7808ce719329ea7c8781e21e3b9958ca70f19cf1d643cd790f1cc23e34992f124c8782693f19493f10c24e3b99f8ce746329e9e643c9793f1cc24e3e944c6d3888c673c19cf30329edbc9781e23e3b98d8ce76e329eebc8781690f1b427e32924e3994ac65341c633888ce741329e62329e5e643c5792f1cc26e3e948c6d3848ce759329ea7c9781e27e3b9978ca739194f37329e96643c9792f14c27e36940c633868ca72d19cf10329e87c9785a91f1dc42c65346c6733519cf5c329e12329efa7827201b9e8bc9782691f18c24e31940c6731f19cf0d643c3dc8782e23e3a924e3e94cc6d3908c671c19cf50329e47c9785a90f1dc45c6732d19cf7c329e0e643c9790f14c21e31945c673868ce749329e07c8786e22e3b9938ce70a329e59643ca5643c8dc9782690f1b423e3194ec6d38f8ce71e329e66643c5dc9788ac878a691f1b426e3c923e04904e77f4b2701ff7f0d34f9e60b7e2f2cdfb23ee9a796f4eab838a7f9f9ebceb7acfba485017d3a0e6529d3f1e4179bcef9ce4d9e5eafcc4b7e85c0719284a73519cf34329e22329eae643ccdc878ee21e3e947c6339c8ca71d19cf04329ec6643ca5643cb3c878ae20e3b9938ce726329e07c8789e24e33943c6338a8c670a19cf25643c1dc878e693f15c4bc67317194f0b329e47c9788692f18c23e36948c6d3998ca7928ce732329e1e643c3790f1dc47c633808c672419cf24329e8bc9784e93f19490f1cc25e3b99a8ca78c8ce716329e56643c0f93f10c21e3694bc633868ca70119cf74329e4bc9785a92f17423e3694ec6732f19cfe3643c4f93f13c4bc6d3848ca72319cf6c329e2bc9787a91f11493f13c48c633888ca7828c672a194f21194f7b329e05643cd791f1dc4dc6731b19cf63643cb793f10c23e3194fc6d3888ca71319cf4c329ecbc9787a92f1dc48c6733f19cf40329e72329ec9643c09329e2419cf3c329e6bc878ee20e3e943c6732b19cf23643c4f91f13c43c65340c6d3858c6706194f53329eee643cd793f1f425e3e94fc633828c672219cf45643c6dc87852643c73c878ae22e3e94dc6733319cf43643c83c9784693f1e41b3cf87ff56e8f3caf7d42ff16c0ff97e987099aea75491a3946ab7b27c70c4d95f7a8a3f21e0baaa732983f0ae515f663c073cc11cf7183c7ccbb10e203c1b32386a6180f3b623c6230cafc616014ff8e00cf11473c470d1e33ef42880f02cf0e199a623ce888f190c128f3078151fc3b043c871cf11c3678ccbc0b213e043c3b60688a71bf23c60306a3ccef0746f1ef00f01c70c473d0e031f32e84f850f06c9fa129c6bd8e18f7198c32bf1718c5bf7dc0b3cf11cf7e83c7ccbb10e2c3c1b33d86a618ab1c31ee311865be0a18c5bf3dc0b3c711cf5e83c7ccbb10e223c0b3dd86a618773962dc6d30cafc2e60acd2f1ddc0b3db114f95c163e65d08f172f06ca7a129c61d8e18771a8c32bf0318c5bf9dc0b3d311cf2e83c7ccbb10e215e0d97643538cdb1c316e3718657e1b308a7fdb8167bb239e1d068f997721c4fb8126bc5d40dbaae39d41dba2e39d40dbace3a5a0bdaae31d41dba4e329d036ea7809681bc40fd0d6eb7807d05ed1f1f6a0add3f1aea0add5f16ea0bdace3dd415ba3e33d407b49c77b82f6a28edf09da6a1def05da0b3ade1bb4553a5e06da4a1def03da0a1dbf0bb4e53a7e3768cb74fc1ed096eaf8bda02dd1f1bea02dd6f1fb405ba4e3f783f6bc8e3f00da733afe20680b75fc21d0c6eaf8c3a03da1e38f80f6868e3f0ada9b3afe18686fe9f8e3a07d4dc70780f6751d7f12b4b7757c3068dfd0f1a740fba68e0f03ed5b3afe3468dfd6f191a07d47c74781f65d1d1f0ddaf7747c0c68efe8f833a07d5fc7c781f6031d1f0fda0f757c0268efeaf8b3a0fd48c72782f6631d9f04da4f747c32683fd5f129a0fd4cc7a782f69e8e4f03ed7d1d9f0eda073a3e03b49feb7825681feaf84cd07ea1e3b340fba58ecf06ed573a3e07b45febf85cd03ed2f179a07dace3f341fb44c71780f61b1dc7ef68ff56c78b8378dbf74f83eaa918f296fc549adfe97823238d2c5b00690af5cd4875bfa328a86effe578a03469ffb78226edff16d0a4fddf0c9ab4ffaf8226edff26d0a4fddf089ab4ff1b4093f67f3d68d2febf029ab4ffeb4093f67f2d68d2febf0c9ab4ff6b4093f6ff25d0a4fd7f113469ff578326edff0ba095e9f82ad0a4fd5f099ab4ff2b4093f67f3968d2fe2f034ddaffa5a049fbbf043469ff178326edff22d0a4fd7f1e3469ff9f034ddaff85a049fb3f163469ff9f004ddaff374093f6ff4dd0645ffb14343926bc059a1c13be069a1c13be0e9a1c13de064d8e09df004d8e09df044d8e09df026da48e7f1b3439267c073439267c173439267c0f343926bc039a1c13be0f9a1c137e009a1c137e089a1c13de054d8e093f024d8e093f066db28eff04343926fc14343926fc0c343926bc079a1c13de074d8e091f8026c7849f8326c7840f419363c22f409363c22f419363c2af409363c2af419363c247a0c931e163d0e49820c78826a0c9fd6a3525bfe05414544ff99097309505f11e73702a83f87c28bb4c8bc978d690f16c25e3b9998ce72a329e36643c1791f18c20e35941c6d39f8c673d19cf6e329e5d643cd793f11c23e3394ac6d3948ca7808ce745329ecd643cb792f1dc41c6730d194f828ca79c8c671919cf40329e75643c3bc9787690f1dc48c673848ce73019cfe5643c8dc8785e20e3b99d8c671319cf6d643cd791f11492f15490f12c21e31944c6f33219cf27643cdbc8788ac9780e91f11c24e3b9928ca70919cf4a329e0d643ccdc9785a92f15c4ac6d3808ca72d19cf22329e21643c2f91f17c4ac6d38a8ce716329e2d643c07c878f693f15c4dc6739a8ce762329eed643c6f92f12c27e379858ce706329ecbc8781a92f10c25e3594dc6f32a19cf3e329ebd643cd792f15c42c6f31619cf52329e33643c6bc9786e22e3b9828ca731194f3b329ee1643cabc8783692f1ec21e3a922e36946c673828ce738194f11194f6b329e3c029e047004a0c9ff1b8026efeb9e014ddeef3d0d9abcebbb1d347937780168bfb668f9163e61f818347937631e6872bdff1168f2cce05cd0e4bc41f257f38b9a9fcf9f6f2967030bff479672ceb32c8bdb5b96290be2ddde98575970fefbd785c0318f84a735194f1119cf71329e13643ccdc878aac878f690f16c24e35945c6339c8ca71d194f63329e2bc8786e22e3594bc673868c672919cf5b643c9790f15c4bc6b3978c671f19cfab643cabc9788692f13424e3b98c8ce706329e57c8789693f1bc49c6b39d8ce762329ed3643c5793f1ec27e33940c6b3858ce716329e56643c9f92f1bc44c633848c6711194f5b329e06643c9792f1b424e3694ec6b3818c6725194f13329e2bc9780e92f11c22e32926e3d946c6f30919cfcb643c83c8789690f15490f11492f15c47c6731b19cf26329edbc9785e20e36944c6733919cf61329e23643c3792f1ec20e3d949c6b38e8c672019cf32329e72329e0419cf35643c7790f1dc4ac6b3998ce745329e02329ea6643c47c9788e91f15c4fc6b38b8c673719cf7a329efe643c2bc8784690f15c44c6d3868ce72a329e9bc978b692f1ac21e3594cc6936fe139ed8847de9d9475cbfce9af78de478dbc8f5e20791f36f23e7c81e47dd0c8fbe00592f77e23effd1748de7b8dbcf75e2079571979575d2079ef32f2de7581e4bdc3c87bc7059237f3798bfa3e865c639fd0bf09f83f8edbbddd11e3698351e6b703a368f85da4fe8e78a2ce79fa13e4adbc18a8e372af2f01ff1f088caeea547f8351e66d750ac7a51ee88827ea5c6d2041deca0b79c64bfaca13f07f1cf7cb559d1a6830cabcad4e1d069e418e78a2ce310711e4adbc907724e459d304fc1fc7057155a706198c326fab5338aed510473c51e7c64308f2565ec83bcff2ee5802fe8fdfe97655a786188c326fab5338cec450473c51e7f44309f2565ec83771e4db0209f83f7ee7d4559d1a6a30cabcad4eed059ee18e78aa0c9e2a8b175f56deca0be963d8a37f13f0ff11c0e8aa4e0d371865de56a7aa806784239ea86ba81104792b2fca755cfa1613f0ff72607455a746188c326fab53bb80a7dc114fd4b55f3941deca0b79c65d9ecd4bc0ff71dc5c5775aadc6094795b9dc271e82b1cf1445db356d443de51d75ff59177d4b5447de41d755e5c1f79479de3d547de51e72bf59177959177553de61d751ca98fbca3da44bf7ffbfd3beebcbfcc6349959177553de6fd65eedf5f669bfa65b62dfebcc5b76bf595b73f6fe13e6ff92cbebc93787dda24c6f5e27d816dfa17efed6c054deeb56c014dee976d064dee79be0a9adcb7de049af43d6c044dfa8fde024dfa00b16f52bef97b1c3479260dfbc4648c89a3a0c95814d817f32b1d3f0cda1c1dc73e80d93a7e10b45fea38de7b9ea5e3fb41fb858eef036da68eef05ed431ddf03dacf75bc0ab44a1dc77b3c33747c17681fe838de5b98aee33b407b5fc7df046d9a8e7f0ada7b3a5e01dacf2cda541ddf00da141d5f0fda4f75fc15d026ebf83ad07ea2e36b419ba4e32f83f6631d5f03da8f74fc25d026eaf88ba03dabe3ab417b57c75f006d828eaf02ed873abe12b4f13abe02b41fe8f872d0beafe3cb401ba7e34b417b46c79780f68e8e2f066d8c8e2f02ed7b3afe0968a375bc1cb47c1d1f015a031d1f0e9abc17341434f9d6eb10d0e47dee41a0c937df0782d644c7fb8326cf92e37834f27d491c8f46de01c4b16ce43bd31f8126df6ec0b167647c101ca346be71f52bd09aeaf81cd0e45bb2b34193f7c57f099a7c537e1668f29d9f5f8026cf86cf044dbe17f92168f28ee1cf4193ef58578226df8698015a331dff0034f966d574d0e4bd9df741936fd54e034ddeb77e0f34f966fdcf402bd6f1a9a0ddace35340bb45c77f0adaad3a3e19b4163afe13d0e4db13934093ef2dfc1834f966d88f406ba5e313419377279f054dc6b77917b4363a3e0134f98edc0f416ba7e3e3416bafe33f00ad838e7f1fb4a48e8f03ad44c79f012da5e3ef80d651c7c78056aae3df03ad938e4bbba0f63fb55fbea6e7cb82f8cea7547e678373a73c63be0ce2c2803c719e6315010fe6752af6b2a792f8cc53be5eafd4975390f789d8f34ea6f33ea9d755a0d77bc2c8bb00d2fceddaea6d734c6b0df472a78de5f01a58d62dcbb405fdb8b1eea6babc271d95f784c124dce883a469a01b4d752c3ba8e38e9ea54aa97d40ea5a001ee25406717c5e307eaf52493c07af0dcf49e0897f3f4996b8aa13b86fc5d986d8ee019975ad08d2e09893c71df887fbbaac5be6253fcfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6ccfccc8a47fa13b0cf5cd2bd46c2281af6759d8c9f27897daeb27ed5afb311fa755cf7ef35d4eb6d6794b900d27c047d4e5b74bc10fe2fdb2d6a5b3ae827ac715b4a7e85509e93c0e3a2bf380ff292759fb27821f1e2d8f24e55b8f1389554cf99a83ef6d386afaf593c75b5bf62df2d7a8afbeb598307fb460b81f775fd9b80f5bc0e6570b08fd7582f243fdc974e8126f1b3c0e8623be3b144da83b67a1efba625cd69edadf48bc7bfed534997edc631285359707efd2e80346f40dbf7968ee3b321af816fef5afe2f534dfdd4e29f2af391f8cb9cc467e065fb1eb1e47d085863cafb9ce7eff374907c442f80f80fafab4e2be9c40ff15ad8f1fbd6c86e2e77d658ae08d21cb594bf2c88b7fc470c9e2306b3da266f433d7b178effaedaa4a3111eb5058f240d9e07b9fa668fd9460a87e4a7d2c8f66f64a4c1731649f301b451aa2cd2ce4b39f1d9163c06b83a8ebd66944fe66de7c62781d12ca3aa1fb32fabe6bdd09ffffa03b417713ffff507a843f89c5660acbf1dac5fb81a05d1c71649f367e338eae21a03b7a5e927fa2c69fe02edd00dfa61dc6ccef5bfacebb6a873fda30e7812c1b9d7de6aaae9f88ec798630e781c9533693b761d37ca5404695a40391d9cc7d4f81ee111c8dbc536472fe41cea84e14501a4f99f46db11e5235eab9eac97b2a4ace783ed2c6591349f19edd461074c2eb7db2128935aef294b59254d8366d5be34d4f1046c27bc6f72a5e5ff32d5d41e887faacc07e22f7312dffd94ed7bc092f73e608d29ef73de3b95f37dc947f402885fd1ac3aada4133fc46b6157fb88bcdb86ece672278ce58a20cd414bf9cb8278cb7fc0e0396030ab6dd204ea99d42397ede6c1088fda81479206ef1fcbb11ddf6fb41df75d3c5f5dd371ff14309aed269ebbb86433bf0b6bde43b59d0f4a1a3c279334b768e6a6c1b9efe3609bb3d1ed33ff25f8fe6a00e5088cb206069b239f4bd167f31e601bd04d9fe57fb66b86b6e0737ddc9f166ef35a00af4784db3ccee0f5480970ab7a2fdb09ef238af686fe75744e5e8ad75b728c31cfc9f13e5a1760c76585eb754b59c403499b0fff97ff7d16d8af4f3e6f39337ec65846f9fb8691ce964f135836b677354a924993ffb4c1896db3a4b3f92afb01d6395997b9afe07d5149d3d76893ccb46adb4f6d5aed8f6c47f10edb13ac93aefa60ce18e59779c94f31ca3da033c0e3e23e4ab6ef4fb9becfe6a88d4ee2bd8bf8beffd06d94ed9ecb6b865745c1f9f7335cb6e9517d39272c79c7e7456ab4adbfdfe6457df6f7477971dc92777c5e74aeb0b573362f8e59785cdc7fa9c98b6396bc63f462aced9e88cd8ba3161e57d7db515e1cb5e41d9f175dacf7ab6c5e1cb1f0b8baee8af242f2cb96f918017313231e4fdea5a3f0be544d5e1cb6f0c47f4faa662f0e5bf28ecf8b92ce35f57fa217872c3caefa31a3bc3864c93b3e2fba76b3ddbfb07971d0c273b09ebd3868c93bc67a31c6767fc9e6c5010b8f837b8d357a71c092778ce7879df15e634d5eecb7f0ecaf672ff65bf28ed18b72db7d509b17fb2c3caeee834679b1cf92777c5e8ceaa4f2de5b0b2ff65a78f6d6b3177b2d79c7e745795795f79e5a78b1c7c2b3a79ebdd863c93bc66ba874bda8aa851755169eaa7af6a2ca92777c5e8c4e9f6bedae8517bb2d3cbbebd98bdd96bce3f322993ea6eeaa8517bb2c3cbbead98b5d96bc63ac17e9ebc99db5f062a78567673d7bb1d392778cc79174bdd8510b2f76587876d4b3173b2c79c7e7c5d8f4fda7edb5f062bb85c7d5b88c515e6cb7e41de33d9774bdd8560b2fb65978b6d5b317db2c79c7e745c7f431756b2dbcd86ae1d95acf5e6cb5e41d9f1763d27d625b6ae1c5160bcf967af6628b25ef18cf3bd3edc5e65a78b1d9c2b3b99ebdd86cc93bc6f3cef4fd8b576be1c5ab169e57ebd98b572d79c7d876a6cf3b37d5c28b4d169e4df5ecc5264bde319e77a6bdd8580b2f365a7836d6b3171b2d79c778de993e8e6ca885171b2c3c1bead98b0d96bc63ac17e9b6737d2dbc586fe1595fcf5eacb7e41de37dad74dbf94a2dbc78c5c2f34a3d7bf18a25ef18af47d2f7f8d6d5c28b75169e75f5ecc53a4bde31f615a5cfc1d7d6c28bb5169eb5f5ecc55ac8dbd5fb3a92873c8bd5daf0a200d2fc87f12c56948fb20e7cae0ccbf272ec65c93c57b626a22c2f435924cdff369ee55be380c95159d375e62528935aef594b59258d7c085ff992afe309d826af836f9759fe2f534dcf20897faaccabe32f73baaebe009c65900fe6bd0a5863cabb04f39667d3251fd10b20deb479755a49277e88d7c2aef69117751cd9cde5d61acb15419a172de52f0be22dff6a8367b5c19c7eef01ea99d423376d5786e9c5088f5a834792069fd93beb88c77c865038243f9546b67f23238d2c5b0069aed31eca73bbf21ca49433119cffdca4a3b6ac04d965dd322ff9e1fbb2a780d12ca3aa1f83e1d9cf0e5a6f1f546b25c20deb29353455d64e8eca2a79c9ba65be1330ca9814a5f5cf98aa2d63478351f17471e0198eb321534dc78b2ec0d3d9018fa372a68f435d8d327532ca540469f0ddc6ae0eca9907f9caba65be2be4ed629ba317724cbeddf0a200d27481f6ac261f651daafe965acad2c3715964ddd22ef5a887bcbb1979a78cbc13c1b9db39086adebfba01737707cc6abd3de35f6f7affba53af4bea94e4938232f5020fe22a13e62de779928fe805107f18cef3249df821c72f61577559b625b29bcb7531962b82343d2ce52f0be22d7f4f83a7a7c1acb6491f38b773b03fa4eb400f8343e653e05dcf08ef7a807792068f7f1d1c79d7dde091f90ec023e7385d41937305e14fc0ff93f5c06db67b5d2ddca27503c60e16c6d2f819d3e73a1d0c46992f0546d1ba034f37479e99dbfa76c31f3c2e3732d2c8b20590a61c8e8d094b5ab5dffd2b944bc62e8c719c9f749bdec8815f38ae6200fe04868701f825e56ce880e7e2a07a6cc5199553a6973f33a6ff984cd7a3a0151898f89b6729463e68186f60d182e0dc21240b409321241b82966fd88243574a7a19d2ce855de887acbbc0e06c022c71e68dc36fca5453d5690c3c2eaab2aa3a97e875e9aa3368faf8ca31583f1a1a9c75a93bea7f0d6a4817b52e57dbc1dc27ca60deac83058ef26f00e52d8379c94f6d9b421d9f5a5ef16c9fe9cfcc9c346672e50c34cadcb1319e179cbb01ccdf28c35ded745801b0c0d8383434ca850d86fc4f36ccc5f17396e218b7a63701e427d3c5e0db450e7c53eb97b16a2bca274eec3773d4c4f1157d674eaea81c3f65326ecd268673515b5afedf08345b138f69d584cd162edbd8a2d9261c15b8096872e4ba0834e1b918b4061097f4e69671525d5bc0fa659752ff53e634d4056f1c545701391cab7655edbfea54eed220732a745990d99c6aa86135b4b01a4a580d1dac860a56a36caaaf5aa89e1c75f6a486f65543f9aaa17bd550bdc5416628de5b82eaa176d5f42e70de16644eb5d4d0b9ad82ccd0b8ea76a57a5d5d7dda4d7d4a439db2ab534b759aab2eebd42588baada64e3dd52d0b75fb4a9dc6a9536475faa74ed9d42588baf450978aead2a9b7f6ba4f18ee0ac3dd61b8270cf786a16f18ee0bc3fd6178200c0f86e1a1303c1c8647c2f068181e0b43bf303c1e6486921e10862782cc50d34f069961a807079921aa9f0a32c3570f0b32435b3f1d6486bd1e196486c41e156486341f1d6486ce1d1b6486da1d176486f09d106486069e1864861c9e1c6486329e1a64864856c329aba197d590cc6a486735fcb31a2a5a0d213d370cf382ccb0d30bc2b0300ccf85e1f920336cf7e22033ccb71afe7b5990192e5c0d23ae8617575d09aa0b45752da8dbf6aafb4add5a565d5aea96b7ea8a555dd3aaab5e3dbaa01ee5508fb6a8477dd4a34fea5130f5689c7a54503d3aa91e25558fd6aa478dd5a3d75541e6d1fcbd41e6d50df52a8b7ab547bdeaa45efd3a1c645e0d54af77aad725d5ebbfea75e89341e676b67ab55e7571aadbd8ea96bebad5ad6ebbaba1e5df0ac3d7c2f0f530bc1d866f84e19b61f85618be1d86ef84e1bb416658e27782cc10c83f0832c328abfaa8866cfe719019f6f9a7416688e9f782cc30d51f049921b13f0c32c36aab21b8d510debf0e32c380ab61bfd5f0e7bf093243daff360cbf0bc3df85e1f761f84318fe3e0c7f0cc39fc2f0e730fc4318fe310cff1486bf84e19fc3f02f61f86b503df4353616bfd73337ebf9f2caca3193a65616574e299e347362e5f8a913e716cf1e5f39ae78caac31d3c74e9c321b175ea39b2719b7bbcff4e9e5738bc74f1e3d664ef1949995c553c6168f9a3273f2e8730ed4c7f442d79f9f63f9e8d1d1997d23ff0b907ea78e99bea7979311d11fa8b96c3faf8b211fd565a1ff55c702cdd1472fb97d322073ae5b3c63e294cae264f1e4f06f78709d327bcce8f6c5f8bf19a1c9332a8b6754964faf2c1e3b7dcaa4e292f6b8de8f1bd7a110ffded80dcc2557d5cd9ccff4f8ce75aa62a7aeab8303ef5f5737d2df5ff70548ff54c74cff475d4af87febb2d0cdcdea46d8a659a42d33668eaa9c5e5e5119bd70f28b2cdcb9591d8a796f1d8bf9dfeb92d97fd665a16b9bd78db073f33a6436328bcc82ff07d6af973f08fc0400", - "isInternal": false - }, - { - "selector": { - "value": 2603445359 - }, - "bytecode": "0x1f8b08000000000000ffed9df77f1cd5d5c667d55cd65acbbd0202e322abad569265b9ca40006363834d31cdb8c960b02d638b964220150209bca9d4407a25bd92de437a4842494823fd87fc0bf9bce7cedef3ead1f51dbd5a31573963ce7c3ec773e7f1ddb9dffbcc99bbab3bb3b3b9a8bcfc932267cbd5148ba2e317feff3ebb2ebeb8a523c57d154372e632c2599511ceea8c70d66484b336239c7519e19c9011ce8919e19c9411cec919e1cc6784734a4638eb33c259c808e7d48c70366484735a4638a767847346463867668473564638676784734e4638e76684735e4638e7678473414638176684f3a48c709e9c11ce5332c2d99811ce5333c2795a8a9ccdc0c973e1a7dbf562bb5e62d74bed7a995d37d9f572dbc71abb6df6d942d14ad1e6fc5fbb61a63093e225e7ff3a29ba28ba2956d8ff6bb4ffd743b192a2976215c56a8a35146b29d651acb79e6ca03883e24c8ab3285e467136c53914e7526ca4388f6213c5668af329b6506ca5b880e2428a6d14db292ea2b898e21287e5528a1d1497515c4e7105c595145751eca4b89a6217c56e8a3d147b29f651f453eca7b886e25a8a0314d7515c4f7190e210c5618a018a231437501ca5384631487123c54d8e673753dc42712bc5cb1dce5750bc92e25514b751bc9ae2768a3b285e43f15a8ad751bc9ee20d146fa4b893e22e8a3751dc4d710fc59b29de42712fc57d14ff43f1568ab751bc9de21d14efa47817c5fd140f503c6859f8447888e2618a4728de4df128c56314efa1782fc5fb28de4ff1018a0f527c88e2c3141fa1f828c5c7283e4ef138c527283e49f1298a4f537c86e2b3149fa3f83cc51728be48f1258a2f533c41f1158aaf527c8de2eb14dfa0f826c5b728be4df11d8aef527c8fe2fb143fa0f821c593143f723cff31c54f287e4af133abfddcae7f61d7bfb4eba7ecfa5776fd6bbbfe8d5d3f6dd7cfd8f5b376fd9c5dffd6ae7f67d7cfdbf5efedfa0f76fd47bbfe935dffd9ae5fb0ebbfd8f55fedfa6f76fd77bbfe875d9beb6333a695cb13a3a1a52f4a69cce9eaef35f3e36ca67bfdcd5cdba9b6ffc7eb46abd7d86d5ee7ac5e6bb76b1dbdce6ed739fb9968b7273a7ac16e171cbdc16e3738fa74bb3dddd167daed998e7eaadd3e15f4bcfdbf72c7ca2ba3555b29071ae75f1568b556ab06ad8e7707da04abd582c6c7b70eb449569b00da64ab4d042d6fb549a04db1da64d0eaad9607ad60b529a04db55a3d680d562b806653339a0ada74ab358036c36ad3409b69b5e9a0cdb2da0cd0665b6d266873ac360bb4b9569b0dda3cabcd016dbed5e682b6c06af3405b68b5f9a09d64b505a09d6cb585a09d62b593406bb4dac9a09d6ab553403bcd6a8da0f179792a68a75bed34ab999ce2712e7e8dd5ab403b9dcf65d016f3790cda123e87415bcae72f68cba06dd69af87c066db9d5389fcdffadb0e5be28adb1acb4c7ecb727edfdd29ecd7e7bd3df6fd18c8daba221affba09d1ef06ab52da7784f4007b69db3c1edb05e03e5b3a12ed7633f784c627633ceacb4e5d523bc6e85f3ba02d459e9e97f5f946eff7b1d9e5e87b916ca817276bfe6eca8978a73f622a8ebe61ebf3f9e8839bb1138d2cfd9ce4ecdd9512f15e7ec1ea8ebe61e7f563b1173f652e00890b33d6172b654d49c2dcf8f44913ff7f8ef86133167fb8123fd9cedd69c1dfd5271cede0675dddce3bf614fc49c3d061ce9e76c4f8f7e3618f55271cede0375dddce3f994133167ef008e0039bb47c7d9512f15e7ec8350d7cd3d9edb3b1173f65ee0483f677b03e56ca7e66c54bed61545fedce379e61331671f018ef47376afcecf8e7ea93867bf0075dddce36b1e2762ce7ecc96cd75869fdbeb0c0b41fb85d54e02ed97563b19b4a7ac760a68bf826b83acfd9aaf1b82f61bab9d06dad3ce3555a33d63b5d3417bd66a8b417bce6a4b40fbadd59682f63bab2d03ed79ab3581f67bab2d07ed0f566b06ed8f566b01ed4f566b05edcf566b03ed05abb583f617ab1541fbabd53a40fb9bd54aa0fddd6a9da0fdc36a5da0fdd36add5633d724f9dad7f7ad3611fade17a597a3f1f5ae68f89273b6fba0bc3c2c4fb1100dbf0f88db6a49bfad4ed3f7e668f47d6f019ed6007dcf431ba3e169059eb6f479e2efc9b5a7bfdff818373b9ee6a1ad66e8573140bf72d016ef9bb7b9bd0268386e143d8c1de93396f05e27de376f7700236b388ef138cce78f798ff917f0063897e2cf19dc1e7fff97395a40e73adf6a1862fbb7d5eae1ff714c6f73b4407919e705b7c5fbe6ed7660e4feb48d3f6369b48cad0e63a83122076df1beddb6f17c5f3efe9e8deab81640fb2f8c49a5b18e49f5c0d6048c4d817c4c3ad652da0ef17e958336786c63cfdb41e73acf5595d7666c9b9c1b620b70fe952afdfc86e341fa795c2ae2793d1a9e22f08438f7039daf457cdfff4f946eae951cafda1caf0a50a703fc2b05f06fa4cf21dc9e322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb332cb67c6fb2ff0fa26d76b12c2c85a3bf08498e78fbf4bcefbb26b735de721b8ae93fe758b5211af59f27d7b4b9c3ed7409dc77343751fb565dfb541bca6d914d6bb51dd67511f1d7f2d36e435c4a4ebc0beeb978da9b55dda1bea7a9b79ce85792641b3e36b93c7d300f7a90cf334e7788af7c72d73784c9e3e5f35c416e2da5fa5d722d12b2ea7796d0fef31087b5ccae307e74255347cfcc0f799ced4db1e7e0d93af97773a6dd7409dafe4868e0ddf03c9bf75e0def364ea7439fbe6d72c01bdcbd977837d2d73d43afb6f86d7729dafc398ba1b7235c4fd1f382e47d0575cfaa08cd7cdd37f1f2e5fc72f56c053029e10e34ca0cf1b453c07d2be8edfe578e5fb1cc3753ac1bfae00fef93e8bf236b7a7cccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaacccf299f1bba2cc9a877aed4218c7e9de87f87a063f7784f76faeeb6cad1a6a37f47538bee6b4d4e9730dd4b9af6aa8ee765bae8f8ebfdf21e95806b89e37e2b1e4f6eaa13f782d28d4f7b93b1c9e0e8f175c6e4cadedf275fcf43d1eba8e5f747c6df7781aea7cc56bace8299eaf6d0e0f5e1bad8f8ebfb7240ffb198f7b8792f282dbc373a903342ee3f7a3431c677c2f71efebe1f6f0faf5f5d6db8628d4b12f15438e1bddd0a7bee8f8fcae813a4760ec3b6acb780f07de3b7287e7ff7919e93a35fb17e8396ef1f15d099c7dd00eb6dd0bac29b5dd816de76c703bacd740f9f6aaa1baee73cad86b6637e788fb2c35dfebda9cd715a0ce0a4ffffba274fbdfe3f0f438cce698dc08797607bcff871a93562478b4043ce23af83928d43d79ee18e9dedf88f7edd53975f0330bd7b90bc6a8a4fb477df71c867a1f4bbae7d0f7d9b8048c6e1fddfb3c5feaf7693d00e345daf7693d003984f76945cefe97c2fe99ab2e4a7e6fe13a8f38fb773f93f36bf03e30aef3188c174fc1671df7f337de33351e7f5f25dd27cdede1e71a3cb7ffbfbe1be66ea8df972233e604b2e0e704aef351e798752570b7785efb78c26bd92b7e0e15fefde2fa677c48fd19b2f69cef71fac279bd02fac2753eeb7c060cf59ceff4fb3afc33098f031d9ebe729d2fc1b9f6047cc6e3e3847f773ce9f97f5e46fa0c88cfbd5d957e9fe3e38bcf77ed8376b0ed35c09a52db1dd8367f06e47658af81f20f614ce77aec077bcdece61ce1cf51c8eebeaed3795d01eaf47afadf17a5dbff550ecf2a87d91c93af419e3d099f01438dd5bd091e2d058fb80e7e3788df47f019b2bef79850f7f627bdc7f89e4189e3f35341e7d5fc6ceebc9aef3302d7e1d7e2678467609ccd7beabaf385fc7e99e67dc3f85d896668f7794fbb7d29fbd90abef5c1367e2ef86fb61de0b9a5f17744f0b982cc804b1f9499a100afabca00637506186b32c0589b01c6ba0c304ec800e3c40c304eca00e3fffddeb760c67c0618a76480b13e038c850c304ecd0063430618a76580717a06186764807166061867658071760618e76480716e0618e76580717e0618176480716106184fca00e3c919603c25038c8d19603c35038ca76580719132a6c2b82c2c6369ac8c8627d4ef1356f29b78e3f1fb842d9eb6025c172955da77bc5612e2f96995fe5e223314a2e37fff2b106369ac8c86a72d7d9e8a7f5fb30d3cf3fd0e6600c617f51b52929edb86f7a72f0fcb587a31cf960b715fe7589f1f86f7182c0fcbf8a29e7116e21e824a9f71e6bbe7617958c6d2581943ddcf8cdfe7180d0f7e3faec3e35900c6d25819437d0f02bfab351a9e4ef0ace4f12c006369ac8ca1ee99aaf49e3ebcb7bbd3e3992446e449fbf9a29d9eb6ba05f49d19b2c63829038c9333c098cf00e3940c30d66780b19001c6a919606cc800e3b40c304ecf00e38c0c30cecc00e3ac0c30cece00e39c0c30cecd00e3bc0c30cecf00e3820c302ecc00a3fe5da88cff6d46e4694c8f67d8fc07b615e27bad95f67d858727c5ef7d0eeb3bb615e0192715f71d9f059225c6ee0c30067e9e8dfaa88ccaa88c7a5eab8fe219d547f5511995511995f1a5ce9885315c1933918fa5b1321a9e95813ceba980672578c6af5b9e01c6151960ec0ecb581a2ba3e109f18ce13cb4311a9e5ef08c5fb73c2c6369ac8c8627c0f31063cf7a2be0c1e706f67a3c0bc0581a2ba3e1591dc8b35515f0ac06cf56793c0bc0581a2ba3e109f1ecc73cb4311a9e35e0d96a8f6701184b6365343c6bd3e7893d5b5301cf5af06c8dc7b3008ca5b1321a9e75e9f3c49eadad80671d78b6d6e35900c6d258190dcffaf47962cfd655c0b31e3c5be7f12c006369ac8c13414f9127f66c7d053c7de0d97a8f675219bb32c0d89d01c62cf8a88cca288951cf6bf55112a3faa83e2aa3322a637619576480518fb5324a65dc903e63a952c60dc0d3973e4f47a07ec6bfe37586dd578acf962819afce74bc5aef7855803a67807f6706f02f07edf2be799bdbab94f97401cc81da2ef1ef4baf77daeb76fc30cb59765d0b7a1778fa325be6dff0e3faf87b6e5ce712fb8329fcdba0bc54417fcf4abfbf1d239ddbdc1ef2ac11c6b340184faf309e59c278a60ae399248c6789309e6a613c0b85f12c15c6335b184f49184f83309e76613c9385f1340be3a911c6b34118cf22613c6b85f1ac12c63347184f8f309e69c2789609e3c90be3a915c6b35818cf5c613cd385f11485f14c11c6d3248ca74e184fab309e75c278560be399278c67a5309e19c2783a85f1d40be399208c67be309e99c2783a84f11484f1b409e399288ca745184f4e004f3e3afe9e853cfcff06d0aa9cd79af1b366dad0ff9f6df52a78cd39b65cedd9f7d9a0f1b5dd733caf459fce86bef4d972f1c52db14fd8561f6c737bf5c0718e109e16613c1385f1b409e32908e3e910c6335318cf7c613c1384f1d40be3e914c6334318cf4a613cf384f1ac16c6b34e184fab309e3a613c4dc278a608e3290ae3992e8c67ae309ec5c2786a85f1e485f12c13c6334d184f8f309e39c2785609e3592b8c6791309e0dc2786a84f1340be3992c8ca75d184f83309e92309ed9c278960ae359288ca75a18cf12613c9384f14c15c6334b184faf309e05c278d608e3a9f2f06c08c4c3d76f79dfbcbd4148db018e43fcbdf87303f569a3dd57addd2ff3737b3550e7b1baf2da7c7ec2d732977bbd1dff76d8081e6d0cd4173e1e39e7f8046ebb0bef2b88802172fc893c3c21eec708d4cf617998e2f3198ac6abf31cafdc6357803ae7827fe705f0cf97dbbccded29b3322731e3ef5b306b1eea750a6164edaca03c5dc54a7f83e33ce009f15e11c8f7781cdbe4f4a9d3e33bd7c15cdd14a09fbe7387b73779da6e8cd2f562f328bcd8ece1d93cce5e707b95329f9b4166f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466093e1b1e7ea606b3e6a15e8f1046d63686e589bf6fd4130d5f72ce761f943703cf7901fc09d4cff81ef2f39d3ef5787ce73a787e9d1fa09fbe7387b7cf87e35009f3a60c32abcf6363363cfc6c4466cd43bd954218593b2f2c4f3c8ead8c862f238d63e7034f88713e503fe3716c8bd3a7951edfb90e9e5f5b02f4d377eef0f616380ecaaccc3e66c3c3cf6860d63cd4eb15c2c8dae6a03ca5f8fb8dbdd1f065a4716c0bf08418e703f91e8f635b9d3ef57a7ce73a98ab5b03f4d377eef0f656380e95306fca20b3faac3e2731abcfea7312b3faac3e2731abcfea7312b3faac3e2731abcfea7312b3faac3e2731abcfea7312b3faac3e2731abcf2f1d9f0d0fff7608b3e6a1de2a218cac9d1f94a733beeeb02a1abe8c74dd612bf06c499da77cdd2180eff175870b9c3eadf2f8ce75f0fcba20403f7de70e6f5f00c7e14467de944166cd8df161d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e6296901b8667b52d336b1eeaad16c2c8da96b03cf1730f5647c39791eedbb90078b606f027503fe3fb762e74fab4dae33bd7c1f3ebc200fdf49d3bbc7d211c076556661fb3e15963cbcc9a877a6b8430b2b6352c4f3c8ead89862f238d6317024f88713e503fe3716c9bd3a7351edfb90ee6eab600fdf49d3bbcbd0d8e83322bb38fd9f0acb56566cd43bdb5421859bb202c4f3c8ead8d862f238d63db8027c4381fa89ff138b6dde9d35a8fef5c0773757b807eface1ddede0ec7419995d9c76c78d6d932b3e6a1de3a218cace1e71f66fb4f7a3cdd0560a982b6428de191d3775e305f78d9208c6781309e59c278a60ae399248c6789309e6a613c0b85f12c15c6335b184f49184f83309e76613c9385f1340be3a911c6b34818cf1c613cd384f12c13c69317c6532b8c67b1309eb9c278a60be3290ae399228ca749184f9d309e56613cf384f1cc10c6532f8c6782309ef9c278660ae3e910c65310c6d3268c67a2309e16613c39013cf9e8f8eb9c78fda41a34be9eb10eb48b6c790368559e36783fdb41e3bfcf791f663c9e3aedf8f6aa3ced6df7708d879fd8561f6c737bf5c0b15d084f8b309e89c278da84f11484f17408e399298c67be309e09c278ea85f1cc10c6334f184fab309e3a613c4dc278a608e3290ae3992e8c67ae309ec5c2786a85f1e485f12c13c6334d18cf1c613c8b84f1d408e36916c63359184fbb309e06613c25613cb385f12c15c6b350184fb5309e25c2782609e3992a8c6796309e05c2783608e3a9f2f05c9c3e4ffc9d32ee7b045cb8f441f9e2c0fe04ea67d1ecf712bbaf14bfcb127f57ed52c7ab0d8e5705a87309f8776900ff72d02eef9bb7b93d6556e62466c3c373ab78bd94ebb50a61646d5b589e787c6c8d862f238d8f97024f8071ac23503fe3716c87d3a7568fef5c07737547807eface1ddedee169bb314ad78bcb46e1c5651e9ecbc6d90b6eaf52e64b32c82cc167c3c3f72a306b1eeab5086164ede2b03cf1f8d8120d5f461a1f2f039e10ef1f81fa198f09973b7d6af1f8ce75f0fcba3c403f7de70e6f5f0ec7a112e61d1964569fc7c66c78784e9b59f350af5908236b9706e529c5bf51d91c0d5f461ac72e079e10e37c20dfe371ec0aa74fcd1edfb90e9e5f5704e8a7efdce1ed2be03828b3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb36c66c3c3df4d63d63cd46b12c2c8da654179cad71d9aa2e1cb48d71dae009e10d76502f91e5f77b8d2e95393c777ae83b97a65807eface1ddebe128e83322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb332cb66363c6db6ccac79a8d7268491b5cbc3f2c4dfdb6a8b862f235d77b81278425c9709d4cff8bac3554e9fda3cbe731dccd5ab02f4d377eef0f655701c9459997dcc86879fb5c5ac79a8d72e8491b52b82f294af9fb647c39791c6b1ab8027c4381fc8f7781cdbe9f4a9dde33bd7c15cdd19a09fbe7387b777c271a88479470699d567f53989597d569f9398d567f53989597d569f9398d567f53989597d569f9398d567f53989597d569f9398d567f53989597d7ee9f86c78f837b398350ff58a421859bb32284f677cdda1180d5f46baeeb01378425c9709e47b7cdde16aa74f458fef5c07cfafab03f4d377eef0f6d5701c4e74e61d1964d6dc181f66cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e6246609b961783ab83dbbce43bd0e218cac5d1596277eee4147347c19e9be9dab816767007f02f533be6f6797d3a70e8fef5c07cfaf5d01fae93b77787b171c875dcaaccc1e66c353b26566cd43bd921046d67686e589c7b152347c19691cdb053c21c6f940fd8cc7b1dd4e9f4a1edfb90ee6eaee00fdf49d3bbccded29b33227319bb6f7a4df763c1e60dbec4fe4f0f0b227b01781fa198f077b23bfc7dc5e01eae031df1ba09f396897f7cddb7be13854c2bc2383cceaf3d8984ddbfbd26f3b1e0fb06df627727878d917d88b40fd8cc783fec8ef31b757803a98a7fd01fa99837679dfbcdd0fc7a112e61d1964569fc7c66cdade9f7adbe5e7a461dbec4fe4f0f0b23fb01761fa591e0fae89fc1e737b05a883797a4d807ee6a05dde376f5f03c7419995599995599995599995599995599995599995599995599995599995599965339bb6af4dbdedf2fc3db6cdfe440e0f2fd706f6224c3fcbf3f70722bfc7dc5e01eae0313f10a09f396897f7cddb07e03828b3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb36c66d3f675e9b71d7f1f07db667f22878797eb027b11a89ff1fcfdf591df636eaf0075f0985f1fa09f396897f7cddbd7c371506665f6319bb60fa6de76f97a1eb6cdfe440e0f2f07037b11a69fe5f1e050e4f798db2b401d3ce68702f43307edf2be79fb101c874a98776490597d569f9398d567f53989597d569f9398d567f53989597d569f9398d567f53989597d569f9398d567f53989597d569f9398d5e7978ecfa6edc3a9b7dd19cfdf63dbec4fe4f0f07238b01761fa599ebf1f88fc1e737b05a883793a10a09f396897f7cddb03701c4e74e61d1964d6dc181f66cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e6246609b961da3e927edbf1f7d9b16df6277278783912d88b40fd8cef7fb921f27bcced15a00ee6e90d01fa99837679dfbc7d031c076556661f339e2713d36b3bbe1f8edba8b26ba31db5e56ad08ed9720d6883b65c0bda8db65c07da4db63c01b49ba13facdd62cbcb40bbd5964ba0bddc96af06ed15b6bc0bb457daf26ed05e65cb7b40bbcd96f782f66a5bde07daedb6dc0fda1db6bc1fb4d7d8f235a0bdd696af05ed75b67c00b4d7dbf275a0bdc196af07ed8db67c10b43b6df9106877d9f261d0de64cb03a0dd6dcb8b40bbc7a3bdd9962f01ed2d1eed5e5b9e04da7db63c19b4ff8132afdf6acb53407b9b2dd783f6765b2e80f60e5b9e0ada3b6db901b477d9f234d0eeb7e5e9a03d60cb33407bd0966782f6902dcf02ed615b9e0dda23b63c07b477dbf25cd01eb5e579a03d66cbf3417b8f2d2f00edbdb6bc10b4f7d9321ea3f7dbf211d0781cb801341e078e82c6e3c031d0781c18048dc7811b41e371e026d0781cb81934ce9d5b40e3dcb91534ce9d9783c6b9f30ad038775e091ae7ceab40e3dcb90d34ce9d5783c6b9733b689c3b7780c6b9f31ad038775e0b1ae7ceeb40e3dc793d689c3b6f008d73e78da071eedc091ae7ce5da071eebc0934ce9dbb413bc996ef01ed645b7e3368a7d8f25b406bb4e57b413bd596ef03ed345bc67181c79fb78276ba2dbf0db4c5b6fc76d096d8f23b405b6acbef048ddf73de055a932ddf0fda725b7e00b4665b7e10b4165b7e08b4565b7e18b4365b7e04b4765b7e3768455b7e14b40e5b7e0c347e9f7c0f689db6fc5ed0ba6cf97da075db328f0be6fc33e70cf799fda887fe357bb85933e73473f745e97e66e2b678dfbccded1946f69bff6f1c194ba3656c73180d4f2980679843bc8cf4b75f09783a02f004ea67fcb75fa7d3a7a2d3a702d4391dfad919a09f396897f7cddb9dd07688638e5ed4dafd2e76bca8813acfda3739b31ac947de87c9df764f5f5604ee0bef9bc7a515e3d07697d376abd3368ebdbc8c747e750173770066b3df9ef4f71b9f5f2bedbe38a7b89d56e8532f7890569fb0ed9c0d6e87f51a28ffbb61a82ed7633ff8fd8bd94d2ef3b14476f77525e77505a8b3c2d3ffbe28ddfef7383c3d0eb339262f340c7104381fe21c58e170f0762b78d793e0dd0af08eebe0fb5f7b20efba1d9e6ea76dc3c39f713a41e3cf0a3807c1ffdf3c0edceeb8d7e9e166ad0b187d9f75dad2671cf1b34e1b30b2d60d3c5d813c738ff562c71f7c5fae73eaf06b6ba04e95fd63af211afeb706d735e7ddbfa05ffc37f37fa274c7f4ba007ee1dff311f813391e46e017f7b33600cfe468e86ffa63830347775fd3bfad7ff7be1ca0d53898b8ce79ba51051a96ab3d5a140d9fbac0294f9ebac029cf2ac7169c32e1fae64f29d32d9e1ee83f7460f0e2c3fd87f71ebdf5c860ffbecd03d72075ad438fa4493d4052d47c3d1a897e5274fcc14ff5cc64b845b0ff9c05a9b69da8b540c6be89d1907d3cb363deadcd8862666acc19694e4e63ad996931332b6626c5cc9c9899123333626642cccc8799e930331b6626c3cc5c98998ac6a83c13711af07c1f18cd5f08e66c37330966e6c0cc14987709f3e9d38cace6938479d733239d19e1cca764f317931939cca86c461c334a98773df36e673e9d9877eb5514ab29d650aca55847b1de7abd81e20c8a3329cea27819c5d914e7509c4bb191e23c8a4d149b29cea7d842b195e2028a0b29b6516ca7b888e2e2a83cf3776954bec27919c5e51457505c497115c5cea83ca3be2b2acf989b197233236e66c0cd8cb799e13633da6606dbcc589b19eaeba3f20cb499713633cc6646d9cc269ad943335b686607cd6ca099fd33b37d6676cfcce699d93b335b6766e7cc6c9c997d33b36d6676edf6a83c7b6666cbccec98990d33b35f66b6cbcc6e99d92c337b6566abee8ecab35166f6c9cc3699d925339b64668fcc6c91991d32b34166f6c7ccf698d91d339b63666fcc6c8d999d31b33166f6c5ccb698d995c7a2f2ec89992d31b3236636e403141fa4f810c587293e42f1518a8f517c9ce2718a4f507c92e253149fa6f80cc567293e47f1798a2f507c91e24b145fa67882e22b145fa5f81ac5d729be41f14d8a6f517c9be23b14dfa5f85e54cec91f50fc90e2498a1f51fc98e227143fa5f819c5cf297e41f14b8aa7287e45f16b8adf503c4df10cc5b314cf51fc96e27714cf53fc9ee20f147fa4f813c59f295ea0f80bc55f29fe46f1778a7f50fc331a9a49c581e209bbc1b37abb0707fb0f1d196c1c1c683c74e3c1c103470ededa78f381c16b1b076eea3fbaffe0c0cdf8e2ebec30c453961b8e1edd7d6be381c3fbfa6f691cb871b071607fe39e811b0fef3b862fbad3be68e1f12deedeb72fb9b1fbab5e04e9c3636cf423f6753c19bc71e4be7d7c2c867c662c2f7a7a8c1dbad8be8bacb1dbdbcbefd48dc70e0e0c36161b0fd3bfbb0fd26bfaf7b535e2ff1d23938f0d361e1bdc7d74b071ffd181438d1d6db8df47ebc6d089671ac6f0a2dcb4d1f73cfa5f16540aa2d9140300", - "isInternal": false - } - ], - "packedBytecode": "0x000000028df71de50000003d361f8b08000000000000ffed9d09941545bee6b38a62d16b95b82bb8948a82acb72ec58e50b8e0ae08222020140508c84eb183b28328822cb243b1ef8be0d26def76b7bda96d2f6adbfdba5f77bff7fabd7ef3ce9cf3e6cc3b33f366c69e8c7be33ff511449675cb8cf2bb12794ed48dfc2a32e3175f46462e9199911764a6bf86214fc71b84a14570fe24ff2fd3bfc92f3695c4b8aea44bcebc1ce1cccf11ce0639c25990239c0d7384b3518e7036ce11ce2639c279518e705e9c239c891ce1bc2447380b7384b32847382fcd11cea639c279598e705e9e239c57e408e79539c279558e705e9d239cd7e408e7b539c2795d8e7036cb11cee639c2797d8e70de90239c37e608e74d39c2599c239c37e708e72d39c2796b8c9c6d8053eed9dfa67f6fd7bf2df56f2bfd7b87fe6dad7fdbe83216e8f9b661681786f661e860fc4f19a36edca7c2d0d1f85f69183a85a17318bae8ff15ebff750d43b730740f438f30f40cc39d61e81586deda8f3e61b82b0c7787e19e30dc1b86be61b82f0cf787e181303c188687c2f070181e09c3a361782c0cfdc2f07818fa876140189e08c3c0303c19864106cbe0300c09c35361181a866161181e86a7c330220c23c3501e865161a808c3e8308c09c3d8303c13867161181f86096178360c13c330290c93c330250c53c3302d0cd3c330230c95619819865961986d7836270c73c3302f0cf30dce0561581886e7c2f07c1816856171189684616918968561791856846165185685e18530ac0ec38b6178290c6bc2f07218d686615d185e09c3fa306c08c3c6306c0ac3ab61d81c862d61d81a866d61d8ae596447d811869d61d81586dd61a80ac39e30ec0dc3be30ec0fc381301c0cc3a1301c0ec391301c0dc3b1301c0fc389309c0cc3a9309c0ec36b61381386b361783d0c6f84e1cd30bc1586af85e1eb61783b0cdf08c337c3f0ad307c3b0cdf09c377c3f0bd30bc1386ef87e10761f86118de0dc38fc2f0e330fc240c3f0dc3cf0ccfdf0bc3fb61f8200c3fd7da87faf717faf797faf757faf7d7faf723fdfbb1fefd44fffe46ff7eaa7f7fab7f7fa77fff4efffe5efffe41fffebdfefda3fefd93fefdb3fefd07fdfb8ffaf79ff4ef5ff4ef3febdf7fd1bfaa1f6f75f34cbc49503d950531b539a563cad57d7c31d3ec27547d500df4ffe4b758eb057a5e7ef3b4de50cf3734f4467abe91b19e267abe89a117e9f922436faae79b1afae57afe7243bf52cf5f69e837ebf99b414fe8ff650a96f9515a032de58126f52f1fb4865a6b005a23591d688db5d61034d9be8d40bb486b8d41bb586b4d404b68ed22d02ed1dac5a0156a2d015a91d62e01ed52ad1582d6546b45a05da6b54b41bb5c6b4d41bb426b978176a5d62e07ed2aad5d01dad55abb12b46bb4761568d76aed6ad0aed3da35a035d3dab5a0e95d2cb80eb4ebb5d60cb41bb4d61cb41bb5763d683769ed06d08ab5762368376bed26d06ed15a3168b76aed66d05a68ed16d0e45ce156ada97a266d5f7a19ade783769becdfa0dd2efb36682d65bf06ad95ecd3a0dd01798bd65af671d0da684deab8fa5f671d2f0be26adf52156abd5de25e6fb866b5de6ef1af37a9dacbee41b5d765904f17f0aa878ec7f83c4309e69da783e4237a01c4ef83b4924efc90764ad855dbd355c77bd4b05c6763b92248d3d552feb220def2773378ba19cc6a9bf4048ef8eb6cc7a4afb3b59eb2aeb30321ad59f7e498f955acb30f0287833a5beaeb6cada7aceb6c05a435eb9e9cbf7d15ebec60e0705067bbbaa9b3a9a4afb3997b264160af7b722df155acb3638123fe3adbc9d7d9da4f59d7d9e721ad59f7e4baf6ab58672b8123fe3adba5ab3f37a8f594759d5d0369cdba27f758be8a7576097038a8b315be9dadf594759ddd0e69cdba27f7fbbe8a75761d70c45f67bb39aab31d7d9d0d32fd5f4160af7b72eff9ab5867770147fc75b6c2df9fadfd94759d7d0bd29a754ffa41be8a75f6b88eab7e860f753fc3f5a0fd426b3780f64baddd08daafb4761368bf86fe42d13e92be44d03ed6da2da07da2b55b41fb8dd1f7aab44fb5761b68bfd5daeda0fd4e6b2d41fb3badb502edf75abb03b43f68ad35687fafb536a0fd516b6d41fb93d6da81f667adb507ed1fb4d601b47fd45a12b47fd25a09687fd15a0ab47fd65a47d0fe456ba5a0fd556b9db4a6fa29a5efeb5dad3501aeb220be3a9a000f64ca33e6cb20dec12d4fb2087830af92f8f3eaa8ca7ecec3569f53f612e04939287b02f2a80d4f0a783ac6cf937ec7af34fef5a6b771d2f034017925a15c9d1c942b0ff29275cbbce457041aeed39d2c8cb19f6784175e799097ac5be63b03a368d8c6489b2bfb8f3ac6fc2bf03ad897d2e719929fbcbb2c1c25a04b9ae2e6d56cff556b85f07f6c6f3b1a9aa37a99ae179297ac5be64b8151cad3b1fe1953b5654c198caeda883cc84bd6edf3aede0e126f0f3c5d1df1986d9ae4ddb51ef2ee6ce45d62e48d6da74c351ddb3a03b383ebad922fe37a0bcf1f18aeb72ecbab4e6b5e37493b9cedf556276339c6ebad4679d51c0ef687741de86a70c87c0978d72dc2bbaee09da4b90dbc7370ee99f6ae8bc123f329e09176ac1478dad7334f7b82bcf11c56b61b5e4be17980abedd5de609479dbf6ea0c8c290ba38373c2544dc7c81260140def47251d7916b55d932479bbb8aec47729e4dcdcbcb6298034ff273ff3abdaca76794ed95278ee2c536daf79e3df4ea924ee1fb5e171bc0f9538aa8f49bc7ff359106f5d33db25b3bd89bac7e3aa2d4f1a3c322ff97966cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367e667563cd29f80cf6d49ba8e248ce6f36faeeef3a7bf8522ebd2bfaa5fe7dbd0af137fbf452a897d7ff21c444ba3cc0590e6c3bceab4efe8b87ae640faa9f0592bf3f92b977d76f83c6619cc4b7ef8ac156e4b86e79d8a63cb3bf35d1a17fd6d9706996fea98cf7e76b478eae2f967f434cff0149f03bfc3e051f5f46ff9d56c2efafeb2ed8b44af241e67df5e5160afebf16f97d4397dd6f9c1b9ed071e675c3dbf236db5f4977735f22e80347f80e7a8e4d92a196728692c87cffdc8ba659996a07733d6dd542f2b1c0d8df597c2b292e64fd0a62e83baeaa0ad4c65fbec3af69bc77f1ccef4e327b3e0690f3c2eda1947e71b49dc07e2eec7379f4fb39dc7481a7cb6cfc17395353eef24f97966cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367e667563c665f2bbe5f5b42c2289ae3671fd2fd19adf4ba64fdaa5f677a7e75beaefbe1a4cfa99551667c77f46c7e75da593a5e189cffbc43d4b674f57d8aa86d29f9e1b767da038f8b7edd3cc84bd6ddc1e285c48b63cb3bd38f1fbfc7d5fdf849c3d7128ba7aef657ec63454f717f4d193cd8371af56d9f0e86e6681fafb15e487eb82f75004de2f87eb48bed8cc712f3b91ec90ffbaf5fd6de360d5c6dfb54d265bb81df4d290bceafdff83d950dd0f66dd2717c86039f1dd96ff9bf4c35f5538b7faacc3de32f737afbde099c65900fe6dd0b5863cabb04f3ced341f211bd00e2fbf2abd34a3af143bc1676b58fc8376090dd5c2e652c5704697a58ca5f16c45bfe9e064f4f83596d932d50cff6c3f1df559bd423c2a396e091a4c1f32057cfe4996da4f97c233eb7d7c84883e72c92e638b451aa2cb6e7476dcf1cba3a8e453d73683b376e0f8c6619cde73c2ff4e7b4be09ed45dccf697d13ea103ea71518eb6f05eb17ae4641f4b145d27cd758bf794e2ecbe0736092e6fbd05efc471dcec9bfaceb2bdb39392e175576c58cdf412b8b9119eb04b2e07982a479dfd866dd22b83b5b96fd306259f1cafc56586170be7f6ebeb396d9e77b1a65917add03ca22693e36ce01e33f6fc99c03bafaa61c9e7ba8f576b09455d2fc0ef6b5dfc3399e6c27dc6fffcdf27f996a3a07c4f11c7bc75fe624ee33b27d7b5bf2ee03ac31e55d82eb9273c03e86070510ff2fd0a64b3a492b5e0bbbda47e43c0ad9cde5ba1acb15419a5e96f29705f196bfb7c1d3db6056dbe48f50cffe0dce015db5d5bd223c6a051e491abca768fb0ea8ed18e3ead9fea8634c076034db4d3c4eba6433df1332efabd9ce11248d2c8be708ff09ed6cc292d6bc5f28c7cb389f1bc677254a21dfbf59f22d8bd9cf2ee05b19cce379c19799b783ef84a7df11c1ef0a0a034e6510c76f87cb72f9c0e8e27beb89e0dcef037f1e237e835d966b008c2eb661b6df272e054659ae00185dbcff85dfc8af0d634760c47d51185d7c97b4aedf73c4ebee46c0c8f45e15de3f6e0c8c2eee73d4f57d1a3ce636815f57638724b360c463ae2c771130bab87f85f7ef6bc388e72eb2dcc5c0e8e23e73b663b0e0f7a1f1fe8f30ba3807ccf61a05ef55c97297006377478cddb260ec0e8c78cf41185d5c4f2620dfda30f60046e41546077d0069c61e5930e2bd7259ee5260bcd31163cf2c18ef044659ae2930bab89f9f807c6bc3d80b1865b9cb80d1c1b57e9ab157168c784d2ccb5d0e8c658e187b67c158068cb2dc15c0e8e2ba3d61307c1e631f6014fd4a60bccb11639f2c18ef024659ee2a60bcdb11e35d5930de0d8cb2dcd5c0788f23c6bbb360bc071865b96b80f15e478cf764c1782f30ca72d702635f478cf766c1d8171865b9eb80f13e478c7db360bc0f1865b966c078bf23c6fbb260bc1f1865b9e6c0f88023c6fbb3607c001865b9eb81f141478c0f64c1f82030ca723700e3438e181fcc82f1216094e56e04c6871d313e9405e3c3c028cbdd048c8f38627c380bc6478051962b06c6471d313e9205e3a3c028cbdd0c8c8f39627c340bc6c7805196bb0518fb39627c2c0bc67ec028cbdd0a8c8f3b62ec9705e3e3c0d8cfc2d8df11e3e35930f6074659ee0e601c103f63fa3b34fdb3601c003c4fc4cf93f66c40163c4fb8e5497fc3698025af27e3cf2bbd2d0606b52ffb93c033287e9ef4b678320b1e612882e5d0b3c1f133a63d1b9405e360e019123f4fdab3c159f00c01cf065b3c7b2a7ec6b46743b2607c0a7886c6cf93f6eca92c788682674f593c1b163f63dab3a159300e039ee1f1f3a43d1b9605cf70f06c98c5b3a7e3674c7b363c0bc6a7816744fc3c69cf9ece82670478f6b4c5b391f133a63d1b9105e348e0298f9f27edd9c82c78cac1b39116cf46c5cf98f6ac3c0bc651c053113f4fdab35159f0548067a32c9e8d8e9f31ed5945168ca381674cfc3c69cf4667c133063c1b6df16cac23c63159308eb5f0c4fd7dd13196bcc6392afb3341edcb2e0c45b01c328e77c4382e0bc6f1c028cb61fffa04478ce3b3609c008cb21cf6af3feb887142168ccf02a32c87fdeb131d313e9b05e3446094e5b07f7d9223c68959304e0246590efbd7273b629c9405e36460445e619ce2887172168c53804b96c3fef5a98e18a764c13815186539ec5f9fe688716a168cd3805196c3fef5e98e18a765c1381d186539ec5f9fe188717a168c33805196c3fef54a478c33b260ac0446590efbd7673a62accc82712630ca72d8bf3ecb11e3cc2c186701a32c87fdebb31d31ceca82713630ca72d8bf3ec711e3ec2c18e700a32c87fdeb731d31cec982712e30ca72d8bf3ecf11e3dc2c18e701a32c87fdebf31d31cecb82713e30ca72d8bfbec011e3fc2c181700a32c87fdeb0b1d312ec882712130ca7278cdf59c23c68559303e078c0b3de305c1883cc5f1f124b1ec98d7f304657fdec29317b8293be6b588a0ec8bf46fae313e97038c637380d1fbe8193de3578fd1efd7de472646efa3f7d1337a46cfe8192f74c65c68c33d634ed4c7545d1915cfe2f879d29e2dca8267317826cb3d91038ccfe700e3736e19537565543c4be2e7497bb6380b9e25e0992cf7845bc6545d1915cfd2f879d29e2dc982672978b6c4e29903c6545d1915cfb2f879d29e2dcd82671978b6d4e29903c6545d1915cff2f879d29e2dcb82673978b6cce29903c6545d1915cf8af879d29e2dcf82670578b6dce29903c6545d1915cfcaf879d29eadc882672578b6c2e29903c6545d1915cfaaf879d29eadcc82671578b6d2e29903c6545d1915cf0bf1f3a43d5b9505cf0be0d92a8b67ac8c637380f1b91c60cc051f3da3676462f4fbb5f79189d1fbe87df48c9ed133e62ee3f339c0e8b7b56764655c1d3f632a5bc6d58e3d7354cef4385e2fea75c5f86d8994f2ea25c3ab5586574590e645f0ef2507fee541beb26e9997fcb2656e41c0ec28ef948c2fbdcac8ef39c30f35add1bf0d411f0b9ebeace332869fa47f1e744933570f98226383caf42c94774dfce52da969df96fc90673419cf22329ea7c9789692f10c26e35941c6f33819cf43643cf792f1f426e36943c633878ca72519cf74329e14194f03329eb6643cddc8784690f18c21e31942c633918ca73f19cfc3643cadc878fa92f19491f17427e3994bc65342c633838ca70b19cf24329e67c8781693f18c24e35948c6f31419cf32329e01643c2bc9781e21e3b98f8ca70719cf3c329e24194f25194f67329e3e643ce3c8782693f19493f10c25e31948c6f328194f0b329efbc978ee22e3e949c6339f8ca70319cf4c329e4e643c53c878c693f12c21e31945c6b39c8c671819cfed643c4f92f13c46c6731b19cf03643c7793f1dc49c6b3808ca71d19cf2c329e52329ef6643c13c878a692f15490f10c27e31944c6d38f8ce741329ed5643cf790f1f422e3e94ac6339b8ca73519cf34329e8e643c79043c89e0fc775213f0ffd5a0e51bcb360e4345f3eaffafd57a3e2cb34ec71b58d6bd16b497757c9d6559f4692d94a54cc7935f6c4afb847995c1bce457081ceb48783a92f14c23e3694dc6339b8ca72b194f2f329e7bc8785693f13c48c6d38f8c671019cf70329e0a329ea9643c13c878da93f19492f1cc22e36947c6b3808ce74e329ebbc9781e20e3b98d8ce731329e27c9786e27e31946c6b39c8c671419cf12329ef1643c53c8783a91f1cc24e3e940c6339f8ca72719cf5d643cf793f1b420e379948c672019cf50329e72329ec9643ce3c878fa90f17426e3a924e34992f1cc23e3e941c6731f19cf23643c2bc9780690f12c23e3798a8c672119cf48329ec5643ccf90f14c22e3e942c633838ca7848c672e194f77329e32329ebe643cadc8781e26e3e94fc633918c670819cf18329e11643cddc878da92f13420e34991f14c27e36949c633878ca70d194f6f329e7bc9781e22e3799c8c670519cf60329ea5643c4f93f12c22e3194dc6f3ac85c7c1f88e691e793f4fd62df3ab49f276b01dd2e35abee2a84cebf5ba1aeaf50abfe45700693e699cf96d1a64ea83e8c2b546c7b16e8837ebc1a3f58eca22db23cfd83e8ef34ee17ba3013004863f8185c7c5fbb68eca794e3d8c7b7cd50d8657e6b62b8234af807f1b1cf867abdb322ff965cbdc828019eb4571106fbdd8187f99feffb8ade2eb46c35f2cd7ab3a1e63bd4caa756cd2eb6a08f9bd0af96ed1f1bc18f355ebdaacd725e3cc0ac716d025cd7f83761999d524ed2f7e636dab8e97c5c79c1e071bc7d1154f702a83f856e0d9ec80c75139d3db669b51a6d546998a20cd2628e73607e5cc837c65dd32bf0d7864c2b1875dd483da6cf3a8b18719781691f13c4dc6b3948c673019cf0a329ec7c9781e22e3b9978ca737194f1b329e39643c2dc978a693f1a4c8781a90f1b425e3e946c633828c670c19cf10329e89643cfdc9783691f13c4cc6d38a8ca72f194f19194f77329eb9643c25643c33c878ba90f14c22e379868c673119cf48329e85643c4f91f12c23e31940c6b3928ce711329efbc8787a90f1cc23e34992f15492f17426e3e943c6338e8c6732194f3919cf50329e81643c8f92f1b420e3b99f8ce72e329e9e643cf3c9783a90f1cc24e3e944c633858c673c19cf12329e51643ccbc9788691f1dc4ec6f32419cf63643c1bc8781e20e3b99b8ce74e329e05643cedc8786691f19492f1b427e39940c633958ca7828c673819cf20329e7e643c0f92f1dc43c6d38b8ca72b19cf6c329ed6643cd3c8783a92f1e411f0448d3d2cffdf009abc5387e3116fd7f1cda0e55bf29067cfb78156a0e3b20ef52ae7e4e6e7af1b7d72f51e21e65506f3921f8e3dbc9d84a72319cf34329ed6643cb3c978ba92f1f422e3b9878ce741329e7e643c83c8788693f15490f14c25e39940c6d39e8ca7948c6716194f3b329e05643c7792f1dc4dc6f30019cf06329ec7c8789e24e3b99d8c671819cf72329e51643c4bc878c693f14c21e3e944c633938ca70319cf7c329e9e643c7791f1dc4fc6d3828ce751329e81643c43c978cac9782693f18c23e3e943c6d3998ca7928c2749c6338f8ca70719cf7d643c8f90f1ac24e31940c6b38c8ce729329e85643c23c9781693f13c43c633898ca70b19cf0c329e12329eb9643cddc978cac878fa92f1b422e379988c6713194f7f329e89643c43c878c690f18c20e3e946c6d3968ca701194f8a8c673a194f4b329e39643c6dc8787a93f1dc4bc6f31019cfe3643c2bc8780693f12c25e3799a8c671119cf68329e67eb87a754bd8b87e37d0a174e6510df063c9b1cf8e3a89c497c0f33ceb13495573b0caf36185e15419aade0df0e07fee541beb26e9997fc3cb3678e62563cd2b7637b3f782109a3689b9cf29426135066996a6a1f77008f8be38723dfd3edd84ea34c0b2dbe4b1aacab3b1d94d3b6efc8fc4e4bdec541bc5eecaa8517bb2c3cbbead90bc92f5be6ad39c8ec7df63e47317b9fbdcf51ccde67ef7314b3f7d9fb1cc5ec7df63e47317b9fbdcf51ccdee7fa61f63e7b9fa398bdcfdee72866efb3f7398ad9fbec7d8e62f63e7b9fa398bdcfdee72866efb3f7398ad9fbec7d8e62f63e7b9fa398bdcfdee72866efb3f7398ad9fbec7d8e62f63e7b9fa398bdcf7563563c8b745c5813906e1109a368dbdcf2a4df375a149c3be519f36510df053c3b1cf8e3a89ce967c8771b655a149cefbba4c1fd6bb78372daf61d99df0ddb211be69d39c8ec7dae1bb3e259ace38bf46f02d22d2661146d875b9e743bb6383877aaa91ddb0d3c2eda7947e54cb763554699165b7c9734b87f553928a76ddf91f92ad80e559ed9335b9815cf121d17d604a45b42c228da2ea73ca9f4fb8d4b8273a79adab12ae071d1ce3bf23ddd8eed31cab4c4e2bba4c1babac741396dfb8ecc4b7ed932efcc4166efb3f7398ad9fbec7d8e62f63e7b9fa398bdcfdee72866efb3f7398ad9fbec7d8e62f63e7b9fa398bdcfdee72866efb3f7398ad9fb7ce1f8ac78e49bc0c29a80744b491845dbed94a763badf616970ee9467cc97417c0ff054c5ce93e97770e07bbadf61af51a6a516df250dee5f7b1d94d3b6efc8fc5ed80e5f75e69d39c8eceb46fd30fbbae199a3987dddf0cc51ccbe6e78e628665f373c7314b3af1b9e398ad9d70dcf1cc5eceb86678e62f675c3334731fbbae199a3987dddf0cc51ccbe6e78e628665f373c7314b3af1b9e398ad9d70dcf1cc5cc503714cf321d17d604a45b46c2285a955b9ef4770f9605e74e79c67c19c4f702cf1e07fe382a67fab99d7d469996597c9734b87fed73504edbbe23f3fb603b7866cf6c63563ccb755c5813906e3909a3687bdcf2a4dbb1e5c1b9534dedd83ee071d1ce3b2a67ba1ddb6f9469b9c57749837575bf8372daf61d99df0fdbc1337b661bb3e259a1e3c29a80742b481845dbeb9627dd8ead08ce9d6a6ac7f6038f8b76de5139d3edd801a34c2b2cbe4b1aacab071c94d3b6efc8fc01d80e9ed933db9815cf4a1d17d604a45b49c228da3eb73ce9766c6570ee54533b7600785cb4f38eca996ec70e1a655a69f15dd2605d3de8a09cb67d47e60fc276f0cc9ed9c6ac78faebb8b026205d7f1246d1f0fce750fc3ca50983474d35b563871cfbe3a89ce976ec7060f7fd10f82e69b0ae1e7650ce3cc857d62df387613b64c3bc330799bdcf7563563c03755c5813906e2009a3680781e748fc3ca50983474d35b563471cfbe3a89ce976ec6860f7fd08f82e6970ff3aeaa09c7990afac5be68fc276c88679670e327b9febc6ac7806e9b8b02620dd201246d10e03cfb1d87932df37461e35d5d48e1d73ec8f9b7266dab1e381ddf763e0bba4c1fdebb88372e641beb26e993f0edbc1337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993d3337b3e219a2e3c29a8074434818453b0a3c2762e7c9f43b208f9a6aea7738e1d81f37e5ccf43b9c0cecbe9f00df250dd6d5930eca9907f9caba65fe246c07cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6ccdccc8a67a88e0b6b02d20d256114ed38f09c8a9fa73461f0a8a9a67e87538efd7154ce74bfc3e9c0eefb29f05dd2605d3deda09c7990afac5be64fc376f0cc9ed9c6ac7886ebb8b02620dd701246d14e02cf6bb1f364fa4f91474d35b563af39f6c74d3933edd899c0eefb6be0bba4c1ba7ac64139f3205f59b7cc9f81ed900df3ce1c64f63e7b9fa398bdcfdee72866efb3f7398ad9fbec7d8e62f63e7b9fa398bdcfdee72866efb3f7398ad9fbec7d8e62f63e7b9fa398bdcf178ecf8a67848e0b6b02d28d206114ed34f09c8d9da7633261f0a8a9a67e87b38efd7153ce4cbfc3eb81ddf7b3e0bba4c1fdeb7507e5cc837c65dd32ff3a6c87af3af3ce1c64f675a37e987dddf0cc51ccbe6e78e628665f373c7314b3af1b9e398ad9d70dcf1cc5eceb86678e62f675c3334731fbbae199a3987dddf0cc51ccbe6e78e628665f373c7314b3af1b9e398ad9d70dcf1cc5eceb86678e6266a81b8aa75cc7853501e9ca4918453b033c6fc4cf539a3078d454d3733b6f38f6c75139d3cfedbc19d87d7f037c9734b87fbde9a09c7990afac5be6df84ede0993db38d59f154e8b8b026205d0509a368afbbe549250c1e35d5d48ebd093c5f8b9f27ddaebe9905cfd780e7adf8794a1c9533a9d6fb75608f6bbdcaabb70dafde34bc2a8234c8f0b603fff2205f59b7cc4b7e9ed9334731635b28ac0948f70609a3686f018f8b764395bdb55e97acbf61180637adcef76cfcf996e2354b43bd5ee190fc0a20cdfdcdaad30ed36c85f07fd96eaa3c670ccdd1b76f4a6cef4bc8bce45718d4db35448dd734e8858be7fcb33deea31712ff2c88af5ee37e8e79b9f8b652b6ef5c9cb6f0c458f692a8f74d5c7cc74e95bd8d5e97ac5feda3539b3af5bc14f73d693fda18652e80342da0fda884f6c3d656b8de37f302fbbe991f54b767c255ac75f3dec4675a977467213db639fdf52fee9ffda1acaedac5a86b126c17cdb6dba5f7e6fd3133ef22f0e52ca967b6eb38f471a0857b200137d6c7fadccf64ddb67b08030d1fd93cc36d7dd6e2e3200bf720026ec6fd7a90e1239b679fb75f0fb1700f21e066dcaf87183eb279f679fbf5500bf750026ec6fd7aa8e1239b679fb75f0fb7700f27e066dcaf871b3eb279f679fbf5080bf708026ec6fd7a84e1239b679fb75f975bb8cb09b819f7eb72c34736cf3e6fbfaeb07057107033eed7b5ed2765daaf1dddff4ef793a2676aaae99ee159a7fe64be579fcdf327af018f8b3ae5a81e241ddd734df7939ae30f9c35bcc2f1071cdf97adf1bb44929f67f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b667e667cbf17fb5724ddeb248ca2397e363fdd9fd156af4bd6af9efd9d7d99cb7c5349ecf794e7924d8e0248f3efd756a79dafd9b07f11fb454f1b9acb6d698e3f2df3925f219407ebbfab77b5a3ead6eb96bc8b63cb3b55e1c6e354f2d2701d1705d5dbf994511ef4f464ecf99feb699ee1e949c77967fbbe04f238e88b2d7154ce745b70c22893e97111a46901e53ce1a09c7990afac5be64f008f4cf9c0e3aa0e06064f60f147a6d1643c83c9781e22e3b9998ca73719cf55643c73c87852643c6dc8782e22e39948c633828ca73f194f5f329eebc978ba93f13425e39941c6d3858ca7808ce719329ea7c8781e21e3b9958ca70f19cf1d643cd790f1cc23e34992f124c8782693f19493f10c24e3b99f8ce746329e9e643c9793f1cc24e3e944c6d3888c673c19cf30329edbc9781e23e3b98d8ce76e329eebc8781690f1b427e32924e3994ac65341c633888ce741329e62329e5e643c5792f1cc26e3e948c6d3848ce759329ea7c9781e27e3b9978ca739194f37329e96643c9792f14c27e36940c633868ca72d19cf10329e87c9785a91f1dc42c65346c6733519cf5c329e12329efa7827201b9e8bc9782691f18c24e31940c6731f19cf0d643c3dc8782e23e3a924e3e94cc6d3908c671c19cf50329e47c9785a90f1dc45c6732d19cf7c329e0e643c9790f14c21e31945c673868ce749329e07c8786e22e3b9938ce70a329e59643ca5643c8dc9782690f1b423e3194ec6d38f8ce71e329e66643c5dc9788ac878a691f1b426e3c923e04904e77f4b2701ff7f0d34f9e60b7e2f2cdfb23ee9a796f4eab838a7f9f9ebceb7acfba485017d3a0e6529d3f1e4179bcef9ce4d9e5eafcc4b7e85c0719284a73519cf34329e22329eae643ccdc878ee21e3e947c6339c8ca71d19cf04329ec6643ca5643cb3c878ae20e3b9938ce726329e07c8789e24e33943c6338a8c670a19cf25643c1dc878e693f15c4bc67317194f0b329e47c9788692f18c23e36948c6d3998ca7928ce732329e1e643c3790f1dc47c633808c672419cf24329e8bc9784e93f19490f1cc25e3b99a8ca78c8ce716329e56643c0f93f10c21e3694bc633868ca70119cf74329e4bc9785a92f17423e3694ec6732f19cfe3643c4f93f13c4bc6d3848ca72319cf6c329e2bc9787a91f11493f13c48c633888ca7828c672a194f21194f7b329e05643cd791f1dc4dc6731b19cf63643cb793f10c23e3194fc6d3888ca71319cf4c329ecbc9787a92f1dc48c6733f19cf40329e72329ec9643c09329e2419cf3c329e6bc878ee20e3e943c6732b19cf23643c4f91f13c43c65340c6d3858c6706194f53329eee643cd793f1f425e3e94fc633828c672219cf45643c6dc87852643c73c878ae22e3e94dc6733319cf43643c83c9784693f1e41b3cf87ff56e8f3caf7d42ff16c0ff97e987099aea75491a3946ab7b27c70c4d95f7a8a3f21e0baaa732983f0ae515f663c073cc11cf7183c7ccbb10e203c1b32386a6180f3b623c6230cafc616014ff8e00cf11473c470d1e33ef42880f02cf0e199a623ce888f190c128f3078151fc3b043c871cf11c3678ccbc0b213e043c3b60688a71bf23c60306a3ccef0746f1ef00f01c70c473d0e031f32e84f850f06c9fa129c6bd8e18f7198c32bf1718c5bf7dc0b3cf11cf7e83c7ccbb10e2c3c1b33d86a618ab1c31ee311865be0a18c5bf3dc0b3c711cf5e83c7ccbb10e223c0b3dd86a618773962dc6d30cafc2e60acd2f1ddc0b3db114f95c163e65d08f172f06ca7a129c61d8e18771a8c32bf0318c5bf9dc0b3d311cf2e83c7ccbb10e215e0d97643538cdb1c316e3718657e1b308a7fdb8167bb239e1d068f997721c4fb8126bc5d40dbaae39d41dba2e39d40dbace3a5a0bdaae31d41dba4e329d036ea7809681bc40fd0d6eb7807d05ed1f1f6a0add3f1aea0add5f16ea0bdace3dd415ba3e33d407b49c77b82f6a28edf09da6a1def05da0b3ade1bb4553a5e06da4a1def03da0a1dbf0bb4e53a7e3768cb74fc1ed096eaf8bda02dd1f1bea02dd6f1fb405ba4e3f783f6bc8e3f00da733afe20680b75fc21d0c6eaf8c3a03da1e38f80f6868e3f0ada9b3afe18686fe9f8e3a07d4dc70780f6751d7f12b4b7757c3068dfd0f1a740fba68e0f03ed5b3afe3468dfd6f191a07d47c74781f65d1d1f0ddaf7747c0c68efe8f833a07d5fc7c781f6031d1f0fda0f757c0268efeaf8b3a0fd48c72782f6631d9f04da4f747c32683fd5f129a0fd4cc7a782f69e8e4f03ed7d1d9f0eda073a3e03b49feb7825681feaf84cd07ea1e3b340fba58ecf06ed573a3e07b45febf85cd03ed2f179a07dace3f341fb44c71780f61b1dc7ef68ff56c78b8378dbf74f83eaa918f296fc549adfe97823238d2c5b00690af5cd4875bfa328a86effe578a03469ffb78226edff16d0a4fddf0c9ab4ffaf8226edff26d0a4fddf089ab4ff1b4093f67f3d68d2febf029ab4ffeb4093f67f2d68d2febf0c9ab4ff6b4093f6ff25d0a4fd7f113469ff578326edff0ba095e9f82ad0a4fd5f099ab4ff2b4093f67f3968d2fe2f034ddaffa5a049fbbf043469ff178326edff22d0a4fd7f1e3469ff9f034ddaff85a049fb3f163469ff9f004ddaff374093f6ff4dd0645ffb14343926bc059a1c13be069a1c13be0e9a1c13de064d8e09df004d8e09df044d8e09df026da48e7f1b3439267c073439267c173439267c0f343926bc039a1c13be0f9a1c137e009a1c137e089a1c13de054d8e093f024d8e093f066db28eff04343926fc14343926fc0c343926bc079a1c13de074d8e091f8026c7849f8326c7840f419363c22f409363c22f419363c2af409363c2af419363c247a0c931e163d0e49820c78826a0c9fd6a3525bfe05414544ff99097309505f11e73702a83f87c28bb4c8bc978d690f16c25e3b9998ce72a329e36643c1791f18c20e35941c6d39f8c673d19cf6e329e5d643cd793f11c23e3394ac6d3948ca7808ce745329ecd643cb792f1dc41c6730d194f828ca79c8c671919cf40329e75643c3bc9787690f1dc48c673848ce73019cfe5643c8dc8785e20e3b99d8c671319cf6d643cd791f11492f15490f12c21e31944c6f33219cf27643cdbc8788ac9780e91f11c24e3b9928ca70919cf4a329e0d643ccdc9785a92f15c4ac6d3808ca72d19cf22329e21643c2f91f17c4ac6d38a8ce716329e2d643c07c878f693f15c4dc6739a8ce762329eed643c6f92f12c27e379858ce706329ecbc8781a92f10c25e3594dc6f32a19cf3e329ebd643cd792f15c42c6f31619cf52329e33643c6bc9786e22e3b9828ca731194f3b329ee1643cabc8783692f1ec21e3a922e36946c673828ce738194f11194f6b329e3c029e047004a0c9ff1b8026efeb9e014ddeef3d0d9abcebbb1d347937780168bfb668f9163e61f818347937631e6872bdff1168f2cce05cd0e4bc41f257f38b9a9fcf9f6f2967030bff479672ceb32c8bdb5b96290be2ddde98575970fefbd785c0318f84a735194f1119cf71329e13643ccdc878aac878f690f16c24e35945c6339c8ca71d194f63329e2bc8786e22e3594bc673868c672919cf5b643c9790f15c4bc6b3978c671f19cfab643cabc9788692f13424e3b98c8ce706329e57c8789693f1bc49c6b39d8ce762329ed3643c5793f1ec27e33940c6b3858ce716329e56643c9f92f1bc44c633848c6711194f5b329e06643c9792f1b424e3694ec6b3818c6725194f13329e2bc9780e92f11c22e32926e3d946c6f30919cfcb643c83c8789690f15490f11492f15c47c6731b19cf26329edbc9785e20e36944c6733919cf61329e23643c3792f1ec20e3d949c6b38e8c672019cf32329e72329e0419cf35643c7790f1dc4ac6b3998ce745329e02329ea6643c47c9788e91f15c4fc6b38b8c673719cf7a329efe643c2bc8784690f15c44c6d3868ce72a329e9bc978b692f1ac21e3594cc6936fe139ed8847de9d9475cbfce9af78de478dbc8f5e20791f36f23e7c81e47dd0c8fbe00592f77e23effd1748de7b8dbcf75e2079571979575d2079ef32f2de7581e4bdc3c87bc7059237f3798bfa3e865c639fd0bf09f83f8edbbddd11e3698351e6b703a368f85da4fe8e78a2ce79fa13e4adbc18a8e372af2f01ff1f088caeea547f8351e66d750ac7a51ee88827ea5c6d2041deca0b79c64bfaca13f07f1cf7cb559d1a6830cabcad4e1d069e418e78a2ce310711e4adbc907724e459d304fc1fc7057155a706198c326fab5338aed510473c51e7c64308f2565ec83bcff2ee5802fe8fdfe97655a786188c326fab5338cec450473c51e7f44309f2565ec83771e4db0209f83f7ee7d4559d1a6a30cabcad4eed059ee18e78aa0c9e2a8b175f56deca0be963d8a37f13f0ff11c0e8aa4e0d371865de56a7aa806784239ea86ba81104792b2fca755cfa1613f0ff72607455a746188c326fab53bb80a7dc114fd4b55f3941deca0b79c65d9ecd4bc0ff71dc5c5775aadc6094795b9dc271e82b1cf1445db356d443de51d75ff59177d4b5447de41d755e5c1f79479de3d547de51e72bf59177959177553de61d751ca98fbca3da44bf7ffbfd3beebcbfcc6349959177553de6fd65eedf5f669bfa65b62dfebcc5b76bf595b73f6fe13e6ff92cbebc93787dda24c6f5e27d816dfa17efed6c054deeb56c014dee976d064dee79be0a9adcb7de049af43d6c044dfa8fde024dfa00b16f52bef97b1c3479260dfbc4648c89a3a0c95814d817f32b1d3f0cda1c1dc73e80d93a7e10b45fea38de7b9ea5e3fb41fb858eef036da68eef05ed431ddf03dacf75bc0ab44a1dc77b3c33747c17681fe838de5b98aee33b407b5fc7df046d9a8e7f0ada7b3a5e01dacf2cda541ddf00da141d5f0fda4f75fc15d026ebf83ad07ea2e36b419ba4e32f83f6631d5f03da8f74fc25d026eaf88ba03dabe3ab417b57c75f006d828eaf02ed873abe12b4f13abe02b41fe8f872d0beafe3cb401ba7e34b417b46c79780f68e8e2f066d8c8e2f02ed7b3afe0968a375bc1cb47c1d1f015a031d1f0e9abc17341434f9d6eb10d0e47dee41a0c937df0782d644c7fb8326cf92e37834f27d491c8f46de01c4b16ce43bd31f8126df6ec0b167647c101ca346be71f52bd09aeaf81cd0e45bb2b34193f7c57f099a7c537e1668f29d9f5f8026cf86cf044dbe17f92168f28ee1cf4193ef58578226df8698015a331dff0034f966d574d0e4bd9df741936fd54e034ddeb77e0f34f966fdcf402bd6f1a9a0ddace35340bb45c77f0adaad3a3e19b4163afe13d0e4db13934093ef2dfc1834f966d88f406ba5e313419377279f054dc6b77917b4363a3e0134f98edc0f416ba7e3e3416bafe33f00ad838e7f1fb4a48e8f03ad44c79f012da5e3ef80d651c7c78056aae3df03ad938e4bbba0f63fb55fbea6e7cb82f8cea7547e678373a73c63be0ce2c2803c719e6315010fe6752af6b2a792f8cc53be5eafd4975390f789d8f34ea6f33ea9d755a0d77bc2c8bb00d2fceddaea6d734c6b0df472a78de5f01a58d62dcbb405fdb8b1eea6babc271d95f784c124dce883a469a01b4d752c3ba8e38e9ea54aa97d40ea5a001ee25406717c5e307eaf52493c07af0dcf49e0897f3f4996b8aa13b86fc5d986d8ee019975ad08d2e09893c71df887fbbaac5be6253fcfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6ccfccc8a47fa13b0cf5cd2bd46c2281af6759d8c9f27897daeb27ed5afb311fa755cf7ef35d4eb6d6794b900d27c047d4e5b74bc10fe2fdb2d6a5b3ae827ac715b4a7e85509e93c0e3a2bf380ff292759fb27821f1e2d8f24e55b8f1389554cf99a83ef6d386afaf593c75b5bf62df2d7a8afbeb598307fb460b81f775fd9b80f5bc0e6570b08fd7582f243fdc974e8126f1b3c0e8623be3b144da83b67a1efba625cd69edadf48bc7bfed534997edc631285359707efd2e80346f40dbf7968ee3b321af816fef5afe2f534dfdd4e29f2af391f8cb9cc467e065fb1eb1e47d085863cafb9ce7eff374907c442f80f80fafab4e2be9c40ff15ad8f1fbd6c86e2e77d658ae08d21cb594bf2c88b7fc470c9e2306b3da266f433d7b178effaedaa4a3111eb5058f240d9e07b9fa668fd9460a87e4a7d2c8f66f64a4c1731649f301b451aa2cd2ce4b39f1d9163c06b83a8ebd66944fe66de7c62781d12ca3aa1fb32fabe6bdd09ffffa03b417713ffff507a843f89c5660acbf1dac5fb81a05d1c71649f367e338eae21a03b7a5e927fa2c69fe02edd00dfa61dc6ccef5bfacebb6a873fda30e7812c1b9d7de6aaae9f88ec798630e781c9533693b761d37ca5404695a40391d9cc7d4f81ee111c8dbc536472fe41cea84e14501a4f99f46db11e5235eab9eac97b2a4ace783ed2c6591349f19edd461074c2eb7db2128935aef294b59254d8366d5be34d4f1046c27bc6f72a5e5ff32d5d41e887faacc07e22f7312dffd94ed7bc092f73e608d29ef73de3b95f37dc947f402885fd1ac3aada4133fc46b6157fb88bcdb86ece672278ce58a20cd414bf9cb8278cb7fc0e0396030ab6dd204ea99d42397ede6c1088fda81479206ef1fcbb11ddf6fb41df75d3c5f5dd371ff14309aed269ebbb86433bf0b6bde43b59d0f4a1a3c279334b768e6a6c1b9efe3609bb3d1ed33ff25f8fe6a00e5088cb206069b239f4bd167f31e601bd04d9fe57fb66b86b6e0737ddc9f166ef35a00af4784db3ccee0f5480970ab7a2fdb09ef238af686fe75744e5e8ad75b728c31cfc9f13e5a1760c76585eb754b59c403499b0fff97ff7d16d8af4f3e6f39337ec65846f9fb8691ce964f135836b677354a924993ffb4c1896db3a4b3f92afb01d6395997b9afe07d5149d3d76893ccb46adb4f6d5aed8f6c47f10edb13ac93aefa60ce18e59779c94f31ca3da033c0e3e23e4ab6ef4fb9becfe6a88d4ee2bd8bf8beffd06d94ed9ecb6b865745c1f9f7335cb6e9517d39272c79c7e7456ab4adbfdfe6457df6f7477971dc92777c5e74aeb0b573362f8e59785cdc7fa9c98b6396bc63f462aced9e88cd8ba3161e57d7db515e1cb5e41d9f175dacf7ab6c5e1cb1f0b8baee8af242f2cb96f918017313231e4fdea5a3f0be544d5e1cb6f0c47f4faa662f0e5bf28ecf8b92ce35f57fa217872c3caefa31a3bc3864c93b3e2fba76b3ddbfb07971d0c273b09ebd3868c93bc67a31c6767fc9e6c5010b8f837b8d357a71c092778ce7879df15e634d5eecb7f0ecaf672ff65bf28ed18b72db7d509b17fb2c3caeee834679b1cf92777c5e8ceaa4f2de5b0b2ff65a78f6d6b3177b2d79c7e745795795f79e5a78b1c7c2b3a79ebdd863c93bc66ba874bda8aa851755169eaa7af6a2ca92777c5e8c4e9f6bedae8517bb2d3cbbebd98bdd96bce3f322993ea6eeaa8517bb2c3cbbead98b5d96bc63ac17e9ebc99db5f062a78567673d7bb1d392778cc79174bdd8510b2f76587876d4b3173b2c79c7e7c5d8f4fda7edb5f062bb85c7d5b88c515e6cb7e41de33d9774bdd8560b2fb65978b6d5b317db2c79c7e745c7f431756b2dbcd86ae1d95acf5e6cb5e41d9f1763d27d625b6ae1c5160bcf967af6628b25ef18cf3bd3edc5e65a78b1d9c2b3b99ebdd86cc93bc6f3cef4fd8b576be1c5ab169e57ebd98b572d79c7d876a6cf3b37d5c28b4d169e4df5ecc5264bde319e77a6bdd8580b2f365a7836d6b3171b2d79c778de993e8e6ca885171b2c3c1bead98b0d96bc63ac17e9b6737d2dbc586fe1595fcf5eacb7e41de37dad74dbf94a2dbc78c5c2f34a3d7bf18a25ef18af47d2f7f8d6d5c28b75169e75f5ecc53a4bde31f615a5cfc1d7d6c28bb5169eb5f5ecc55ac8dbd5fb3a92873c8bd5daf0a200d2fc87f12c56948fb20e7cae0ccbf272ec65c93c57b626a22c2f435924cdff369ee55be380c95159d375e62528935aef594b59258d7c085ff992afe309d826af836f9759fe2f534dcf20897faaccabe32f73baaebe009c65900fe6bd0a5863cabb04f39667d3251fd10b20deb479755a49277e88d7c2aef69117751cd9cde5d61acb15419a172de52f0be22dff6a8367b5c19c7eef01ea99d423376d5786e9c5088f5a834792069fd93beb88c77c865038243f9546b67f23238d2c5b0069aed31eca73bbf21ca49433119cffdca4a3b6ac04d965dd322ff9e1fbb2a780d12ca3aa1f83e1d9cf0e5a6f1f546b25c20deb29353455d64e8eca2a79c9ba65be1330ca9814a5f5cf98aa2d63478351f17471e0198eb321534dc78b2ec0d3d9018fa372a68f435d8d327532ca540469f0ddc6ae0eca9907f9caba65be2be4ed629ba317724cbeddf0a200d27481f6ac261f651daafe965acad2c3715964ddd22ef5a887bcbb1979a78cbc13c1b9db39086adebfba01737707cc6abd3de35f6f7affba53af4bea94e4938232f5020fe22a13e62de779928fe805107f18cef3249df821c72f61577559b625b29bcb7531962b82343d2ce52f0be22d7f4f83a7a7c1acb6491f38b773b03fa4eb400f8343e653e05dcf08ef7a807792068f7f1d1c79d7dde091f90ec023e7385d41937305e14fc0ff93f5c06db67b5d2ddca27503c60e16c6d2f819d3e73a1d0c46992f0546d1ba034f37479e99dbfa76c31f3c2e3732d2c8b20590a61c8e8d094b5ab5dffd2b944bc62e8c719c9f749bdec8815f38ae6200fe04868701f825e56ce880e7e2a07a6cc5199553a6973f33a6ff984cd7a3a0151898f89b6729463e68186f60d182e0dc21240b409321241b82966fd88243574a7a19d2ce855de887acbbc0e06c022c71e68dc36fca5453d5690c3c2eaab2aa3a97e875e9aa3368faf8ca31583f1a1a9c75a93bea7f0d6a4817b52e57dbc1dc27ca60deac83058ef26f00e52d8379c94f6d9b421d9f5a5ef16c9fe9cfcc9c346672e50c34cadcb1319e179cbb01ccdf28c35ded745801b0c0d8383434ca850d86fc4f36ccc5f17396e218b7a63701e427d3c5e0db450e7c53eb97b16a2bca274eec3773d4c4f1157d674eaea81c3f65326ecd268673515b5afedf08345b138f69d584cd162edbd8a2d9261c15b8096872e4ba0834e1b918b4061097f4e69671525d5bc0fa659752ff53e634d4056f1c545701391cab7655edbfea54eed220732a745990d99c6aa86135b4b01a4a580d1dac860a56a36caaaf5aa89e1c75f6a486f65543f9aaa17bd550bdc5416628de5b82eaa176d5f42e70de16644eb5d4d0b9ad82ccd0b8ea76a57a5d5d7dda4d7d4a439db2ab534b759aab2eebd42588baada64e3dd52d0b75fb4a9dc6a9536475faa74ed9d42588baf450978aead2a9b7f6ba4f18ee0ac3dd61b8270cf786a16f18ee0bc3fd6178200c0f86e1a1303c1c8647c2f068181e0b43bf303c1e6486921e10862782cc50d34f069961a807079921aa9f0a32c3570f0b32435b3f1d6486bd1e196486c41e156486341f1d6486ce1d1b6486da1d176486f09d106486069e1864861c9e1c6486329e1a64864856c329aba197d590cc6a486735fcb31a2a5a0d213d370cf382ccb0d30bc2b0300ccf85e1f920336cf7e22033ccb71afe7b5990192e5c0d23ae8617575d09aa0b45752da8dbf6aafb4add5a565d5aea96b7ea8a555dd3aaab5e3dbaa01ee5508fb6a8477dd4a34fea5130f5689c7a54503d3aa91e25558fd6aa478dd5a3d75541e6d1fcbd41e6d50df52a8b7ab547bdeaa45efd3a1c645e0d54af77aad725d5ebbfea75e89341e676b67ab55e7571aadbd8ea96bebad5ad6ebbaba1e5df0ac3d7c2f0f530bc1d866f84e19b61f85618be1d86ef84e1bb416658e27782cc10c83f0832c328abfaa8866cfe719019f6f9a7416688e9f782cc30d51f049921b13f0c32c36aab21b8d510debf0e32c380ab61bfd5f0e7bf093243daff360cbf0bc3df85e1f761f84318fe3e0c7f0cc39fc2f0e730fc4318fe310cff1486bf84e19fc3f02f61f86b503df4353616bfd73337ebf9f2caca3193a65616574e299e347362e5f8a913e716cf1e5f39ae78caac31d3c74e9c321b175ea39b2719b7bbcff4e9e5738bc74f1e3d664ef1949995c553c6168f9a3273f2e8730ed4c7f442d79f9f63f9e8d1d1997d23ff0b907ea78e99bea7979311d11fa8b96c3faf8b211fd565a1ff55c702cdd1472fb97d322073ae5b3c63e294cae264f1e4f06f78709d327bcce8f6c5f8bf19a1c9332a8b6754964faf2c1e3b7dcaa4e292f6b8de8f1bd7a110ffded80dcc2557d5cd9ccff4f8ce75aa62a7aeab8303ef5f5737d2df5ff70548ff54c74cff475d4af87febb2d0cdcdea46d8a659a42d33668eaa9c5e5e5119bd70f28b2cdcb9591d8a796f1d8bf9dfeb92d97fd665a16b9bd78db073f33a6436328bcc82ff07d6af973f08fc04009b2d6c6f000000212f1f8b08000000000000ffed9df77f1cd5d5c667d55cd65acbbd0202e322abad569265b9ca40006363834d31cdb8c960b02d638b964220150209bca9d4407a25bd92de437a4842494823fd87fc0bf9bce7cedef3ead1f51dbd5a31573963ce7c3ec773e7f1ddb9dffbcc99bbab3bb3b3b9a8bcfc932267cbd5148ba2e317feff3ebb2ebeb8a523c57d154372e632c2599511ceea8c70d66484b336239c7519e19c9011ce8919e19c9411cec919e1cc6784734a4638eb33c259c808e7d48c70366484735a4638a767847346463867668473564638676784734e4638e76684735e4638e7678473414638176684f3a48c709e9c11ce5332c2d99811ce5333c2795a8a9ccdc0c973e1a7dbf562bb5e62d74bed7a995d37d9f572dbc71abb6df6d942d14ad1e6fc5fbb61a63093e225e7ff3a29ba28ba2956d8ff6bb4ffd743b192a2976215c56a8a35146b29d651acb79e6ca03883e24c8ab3285e467136c53914e7526ca4388f6213c5668af329b6506ca5b880e2428a6d14db292ea2b898e21287e5528a1d1497515c4e7105c595145751eca4b89a6217c56e8a3d147b29f651f453eca7b886e25a8a0314d7515c4f7190e210c5618a018a231437501ca5384631487123c54d8e673753dc42712bc5cb1dce5750bc92e25514b751bc9ae2768a3b285e43f15a8ad751bc9ee20d146fa4b893e22e8a3751dc4d710fc59b29de42712fc57d14ff43f1568ab751bc9de21d14efa47817c5fd140f503c6859f8447888e2618a4728de4df128c56314efa1782fc5fb28de4ff1018a0f527c88e2c3141fa1f828c5c7283e4ef138c527283e49f1298a4f537c86e2b3149fa3f83cc51728be48f1258a2f533c41f1158aaf527c8de2eb14dfa0f826c5b728be4df11d8aef527c8fe2fb143fa0f821c593143f723cff31c54f287e4af133abfddcae7f61d7bfb4eba7ecfa5776fd6bbbfe8d5d3f6dd7cfd8f5b376fd9c5dffd6ae7f67d7cfdbf5efedfa0f76fd47bbfe935dffd9ae5fb0ebbfd8f55fedfa6f76fd77bbfe875d9beb6333a695cb13a3a1a52f4a69cce9eaef35f3e36ca67bfdcd5cdba9b6ffc7eb46abd7d86d5ee7ac5e6bb76b1dbdce6ed739fb9968b7273a7ac16e171cbdc16e3738fa74bb3dddd167daed998e7eaadd3e15f4bcfdbf72c7ca2ba3555b29071ae75f1568b556ab06ad8e7707da04abd582c6c7b70eb449569b00da64ab4d042d6fb549a04db1da64d0eaad9607ad60b529a04db55a3d680d562b806653339a0ada74ab358036c36ad3409b69b5e9a0cdb2da0cd0665b6d266873ac360bb4b9569b0dda3cabcd016dbed5e682b6c06af3405b68b5f9a09d64b505a09d6cb585a09d62b593406bb4dac9a09d6ab553403bcd6a8da0f179792a68a75bed34ab999ce2712e7e8dd5ab403b9dcf65d016f3790cda123e87415bcae72f68cba06dd69af87c066db9d5389fcdffadb0e5be28adb1acb4c7ecb727edfdd29ecd7e7bd3df6fd18c8daba221affba09d1ef06ab52da7784f4007b69db3c1edb05e03e5b3a12ed7633f784c627633ceacb4e5d523bc6e85f3ba02d459e9e97f5f946eff7b1d9e5e87b916ca817276bfe6eca8978a73f622a8ebe61ebf3f9e8839bb1138d2cfd9ce4ecdd9512f15e7ec1ea8ebe61e7f563b1173f652e00890b33d6172b654d49c2dcf8f44913ff7f8ef86133167fb8123fd9cedd69c1dfd5271cede0675dddce3bf614fc49c3d061ce9e76c4f8f7e3618f55271cede0375dddce3f994133167ef008e0039bb47c7d9512f15e7ec8350d7cd3d9edb3b1173f65ee0483f677b03e56ca7e66c54bed61545fedce379e61331671f018ef47376afcecf8e7ea93867bf0075dddce36b1e2762ce7ecc96cd75869fdbeb0c0b41fb85d54e02ed97563b19b4a7ac760a68bf826b83acfd9aaf1b82f61bab9d06dad3ce3555a33d63b5d3417bd66a8b417bce6a4b40fbadd59682f63bab2d03ed79ab3581f67bab2d07ed0f566b06ed8f566b01ed4f566b05edcf566b03ed05abb583f617ab1541fbabd53a40fb9bd54aa0fddd6a9da0fdc36a5da0fdd36add5633d724f9dad7f7ad3611fade17a597a3f1f5ae68f89273b6fba0bc3c2c4fb1100dbf0f88db6a49bfad4ed3f7e668f47d6f019ed6007dcf431ba3e169059eb6f479e2efc9b5a7bfdff818373b9ee6a1ad66e8573140bf72d016ef9bb7b9bd0268386e143d8c1de93396f05e27de376f7700236b388ef138cce78f798ff917f0063897e2cf19dc1e7fff97395a40e73adf6a1862fbb7d5eae1ff714c6f73b4407919e705b7c5fbe6ed7660e4feb48d3f6369b48cad0e63a83122076df1beddb6f17c5f3efe9e8deab81640fb2f8c49a5b18e49f5c0d6048c4d817c4c3ad652da0ef17e958336786c63cfdb41e73acf5595d7666c9b9c1b620b70fe952afdfc86e341fa795c2ae2793d1a9e22f08438f7039daf457cdfff4f946eae951cafda1caf0a50a703fc2b05f06fa4cf21dc9e322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb332cb67c6fb2ff0fa26d76b12c2c85a3bf08498e78fbf4bcefbb26b735de721b8ae93fe758b5211af59f27d7b4b9c3ed7409dc77343751fb565dfb541bca6d914d6bb51dd67511f1d7f2d36e435c4a4ebc0beeb978da9b55dda1bea7a9b79ce85792641b3e36b93c7d300f7a90cf334e7788af7c72d73784c9e3e5f35c416e2da5fa5d722d12b2ea7796d0fef31087b5ccae307e74255347cfcc0f799ced4db1e7e0d93af97773a6dd7409dafe4868e0ddf03c9bf75e0def364ea7439fbe6d72c01bdcbd977837d2d73d43afb6f86d7729dafc398ba1b7235c4fd1f382e47d0575cfaa08cd7cdd37f1f2e5fc72f56c053029e10e34ca0cf1b453c07d2be8edfe578e5fb1cc3753ac1bfae00fef93e8bf236b7a7cccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaacccf299f1bba2cc9a877aed4218c7e9de87f87a063f7784f76faeeb6cad1a6a37f47538bee6b4d4e9730dd4b9af6aa8ee765bae8f8ebfdf21e95806b89e37e2b1e4f6eaa13f782d28d4f7b93b1c9e0e8f175c6e4cadedf275fcf43d1eba8e5f747c6df7781aea7cc56bace8299eaf6d0e0f5e1bad8f8ebfb7240ffb198f7b8792f282dbc373a903342ee3f7a3431c677c2f71efebe1f6f0faf5f5d6db8628d4b12f15438e1bddd0a7bee8f8fcae813a4760ec3b6acb780f07de3b7287e7ff7919e93a35fb17e8396ef1f15d099c7dd00eb6dd0bac29b5dd816de76c703bacd740f9f6aaa1baee73cad86b6637e788fb2c35dfebda9cd715a0ce0a4ffffba274fbdfe3f0f438cce698dc08797607bcff871a93562478b4043ce23af83928d43d79ee18e9dedf88f7edd53975f0330bd7b90bc6a8a4fb477df71c867a1f4bbae7d0f7d9b8048c6e1fddfb3c5feaf7693d00e345daf7693d003984f76945cefe97c2fe99ab2e4a7e6fe13a8f38fb773f93f36bf03e30aef3188c174fc1671df7f337de33351e7f5f25dd27cdede1e71a3cb7ffbfbe1be66ea8df972233e604b2e0e704aef351e798752570b7785efb78c26bd92b7e0e15fefde2fa677c48fd19b2f69cef71fac279bd02fac2753eeb7c060cf59ceff4fb3afc33098f031d9ebe729d2fc1b9f6047cc6e3e3847f773ce9f97f5e46fa0c88cfbd5d957e9fe3e38bcf77ed8376b0ed35c09a52db1dd8367f06e47658af81f20f614ce77aec077bcdece61ce1cf51c8eebeaed3795d01eaf47afadf17a5dbff550ecf2a87d91c93af419e3d099f01438dd5bd091e2d058fb80e7e3788df47f019b2bef79850f7f627bdc7f89e4189e3f35341e7d5fc6ceebc9aef3302d7e1d7e2678467609ccd7beabaf385fc7e99e67dc3f85d896668f7794fbb7d29fbd90abef5c1367e2ef86fb61de0b9a5f17744f0b982cc804b1f9499a100afabca00637506186b32c0589b01c6ba0c304ec800e3c40c304eca00e3fffddeb760c67c0618a76480b13e038c850c304ecd0063430618a76580717a06186764807166061867658071760618e76480716e0618e76580717e0618176480716106184fca00e3c919603c25038c8d19603c35038ca76580719132a6c2b82c2c6369ac8c8627d4ef1356f29b78e3f1fb842d9eb6025c172955da77bc5612e2f96995fe5e223314a2e37fff2b106369ac8c86a72d7d9e8a7f5fb30d3cf3fd0e6600c617f51b52929edb86f7a72f0fcb587a31cf960b715fe7589f1f86f7182c0fcbf8a29e7116e21e824a9f71e6bbe7617958c6d2581943ddcf8cdfe7180d0f7e3faec3e35900c6d25819437d0f02bfab351a9e4ef0ace4f12c006369ac8ca1ee99aaf49e3ebcb7bbd3e3992446e449fbf9a29d9eb6ba05f49d19b2c63829038c9333c098cf00e3940c30d66780b19001c6a919606cc800e3b40c304ecf00e38c0c30cecc00e3ac0c30cece00e39c0c30cecd00e3bc0c30cecf00e3820c302ecc00a3fe5da88cff6d46e4694c8f67d8fc07b615e27bad95f67d858727c5ef7d0eeb3bb615e0192715f71d9f059225c6ee0c30067e9e8dfaa88ccaa88c7a5eab8fe219d547f5511995511995f1a5ce9885315c1933918fa5b1321a9e95813ceba980672578c6af5b9e01c6151960ec0ecb581a2ba3e109f18ce13cb4311a9e5ef08c5fb73c2c6369ac8c8627c0f31063cf7a2be0c1e706f67a3c0bc0581a2ba3e1591dc8b35515f0ac06cf56793c0bc0581a2ba3e109f1ecc73cb4311a9e35e0d96a8f6701184b6365343c6bd3e7893d5b5301cf5af06c8dc7b3008ca5b1321a9e75e9f3c49eadad80671d78b6d6e35900c6d258190dcffaf47962cfd655c0b31e3c5be7f12c006369ac8c13414f9127f66c7d053c7de0d97a8f675219bb32c0d89d01c62cf8a88cca288951cf6bf55112a3faa83e2aa3322a637619576480518fb5324a65dc903e63a952c60dc0d3973e4f47a07ec6bfe37586dd578acf962819afce74bc5aef7855803a67807f6706f02f07edf2be799bdbab94f97401cc81da2ef1ef4baf77daeb76fc30cb59765d0b7a1778fa325be6dff0e3faf87b6e5ce712fb8329fcdba0bc54417fcf4abfbf1d239ddbdc1ef2ac11c6b340184faf309e59c278a60ae399248c6789309e6a613c0b85f12c15c6335b184f49184f83309e76613c9385f1340be3a911c6b34118cf22613c6b85f1ac12c63347184f8f309e69c2789609e3c90be3a915c6b35818cf5c613cd385f11485f14c11c6d3248ca74e184fab309e75c278560be399278c67a5309e19c2783a85f1d40be399208c67be309e99c2783a84f11484f1b409e399288ca745184f4e004f3e3afe9e853cfcff06d0aa9cd79af1b366dad0ff9f6df52a78cd39b65cedd9f7d9a0f1b5dd733caf459fce86bef4d972f1c52db14fd8561f6c737bf5c0718e109e16613c1385f1b409e32908e3e910c6335318cf7c613c1384f1d40be3e914c6334318cf4a613cf384f1ac16c6b34e184fab309e3a613c4dc278a608e3290ae3992e8c67ae309ec5c2786a85f1e485f12c13c6334d184f8f309e39c2785609e3592b8c6791309e0dc2786a84f1340be3992c8ca75d184f83309e92309ed9c278960ae359288ca75a18cf12613c9384f14c15c6334b184faf309e05c278d608e3a9f2f06c08c4c3d76f79dfbcbd4148db018e43fcbdf87303f569a3dd57addd2ff3737b3550e7b1baf2da7c7ec2d732977bbd1dff76d8081e6d0cd4173e1e39e7f8046ebb0bef2b88802172fc893c3c21eec708d4cf617998e2f3198ac6abf31cafdc6357803ae7827fe705f0cf97dbbccded29b3322731e3ef5b306b1eea750a6164edaca03c5dc54a7f83e33ce009f15e11c8f7781cdbe4f4a9d3e33bd7c15cdd14a09fbe7387b73779da6e8cd2f562f328bcd8ece1d93cce5e707b95329f9b4166f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466f5597d4e62569fd5e72466093e1b1e7ea606b3e6a15e8f1046d63686e589bf6fd4130d5f72ce761f943703cf7901fc09d4cff81ef2f39d3ef5787ce73a787e9d1fa09fbe7387b7cf87e35009f3a60c32abcf6363363cfc6c4466cd43bd954218593b2f2c4f3c8ead8c862f238d63e7034f88713e503fe3716c8bd3a7951edfb90e9e5f5b02f4d377eef0f616380ecaaccc3e66c3c3cf6860d63cd4eb15c2c8dae6a03ca5f8fb8dbdd1f065a4716c0bf08418e703f91e8f635b9d3ef57a7ce73a98ab5b03f4d377eef0f656380e95306fca20b3faac3e2731abcfea7312b3faac3e2731abcfea7312b3faac3e2731abcfea7312b3faac3e2731abcfea7312b3faac3e2731abcf2f1d9f0d0fff7608b3e6a1de2a218cac9d1f94a733beeeb02a1abe8c74dd612bf06c499da77cdd2180eff175870b9c3eadf2f8ce75f0fcba20403f7de70e6f5f00c7e14467de944166cd8df161d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e6296901b8667b52d336b1eeaad16c2c8da96b03cf1730f5647c39791eedbb90078b606f027503fe3fb762e74fab4dae33bd7c1f3ebc200fdf49d3bbc7d211c076556661fb3e15963cbcc9a877a6b8430b2b6352c4f3c8ead89862f238d6317024f88713e503fe3716c9bd3a7351edfb90ee6eab600fdf49d3bbcbd0d8e83322bb38fd9f0acb56566cd43bdb5421859bb202c4f3c8ead8d862f238d63db8027c4381fa89ff138b6dde9d35a8fef5c0773757b807eface1ddede0ec7419995d9c76c78d6d932b3e6a1de3a218cace1e71f66fb4f7a3cdd0560a982b6428de191d3775e305f78d9208c6781309e59c278a60ae399248c6789309e6a613c0b85f12c15c6335b184f49184f83309e76613c9385f1340be3a911c6b34818cf1c613cd384f12c13c69317c6532b8c67b1309eb9c278a60be3290ae399228ca749184f9d309e56613cf384f1cc10c6532f8c6782309ef9c278660ae3e910c65310c6d3268c67a2309e16613c39013cf9e8f8eb9c78fda41a34be9eb10eb48b6c790368559e36783fdb41e3bfcf791f663c9e3aedf8f6aa3ced6df7708d879fd8561f6c737bf5c0b15d084f8b309e89c278da84f11484f17408e399298c67be309e09c278ea85f1cc10c6334f184fab309e3a613c4dc278a608e3290ae3992e8c67ae309ec5c2786a85f1e485f12c13c6334d18cf1c613c8b84f1d408e36916c63359184fbb309e06613c25613cb385f12c15c6b350184fb5309e25c2782609e3992a8c6796309e05c2783608e3a9f2f05c9c3e4ffc9d32ee7b045cb8f441f9e2c0fe04ea67d1ecf712bbaf14bfcb127f57ed52c7ab0d8e5705a87309f8776900ff72d02eef9bb7b93d6556e62466c3c373ab78bd94ebb50a61646d5b589e787c6c8d862f238d8f97024f8071ac23503fe3716c87d3a7568fef5c07737547807eface1ddedee169bb314ad78bcb46e1c5651e9ecbc6d90b6eaf52e64b32c82cc167c3c3f72a306b1eeab5086164ede2b03cf1f8d8120d5f461a1f2f039e10ef1f81fa198f09973b7d6af1f8ce75f0fcba3c403f7de70e6f5f0ec7a112e61d1964569fc7c66c78784e9b59f350af5908236b9706e529c5bf51d91c0d5f461ac72e079e10e37c20dfe371ec0aa74fcd1edfb90e9e5f5704e8a7efdce1ed2be03828b3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb36c66c3c3df4d63d63cd46b12c2c8da654179cad71d9aa2e1cb48d71dae009e10d76502f91e5f77b8d2e95393c777ae83b97a65807eface1ddebe128e83322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb332cb66363c6db6ccac79a8d7268491b5cbc3f2c4dfdb6a8b862f235d77b81278425c9709d4cff8bac3554e9fda3cbe731dccd5ab02f4d377eef0f655701c9459997dcc86879fb5c5ac79a8d72e8491b52b82f294af9fb647c39791c6b1ab8027c4381fc8f7781cdbe9f4a9dde33bd7c15cdd19a09fbe7387b777c271a88479470699d567f53989597d569f9398d567f53989597d569f9398d567f53989597d569f9398d567f53989597d569f9398d567f53989597d7ee9f86c78f837b398350ff58a421859bb32284f677cdda1180d5f46baeeb01378425c9709e47b7cdde16aa74f458fef5c07cfafab03f4d377eef0f6d5701c4e74e61d1964d6dc181f66cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e6246609b961783ab83dbbce43bd0e218cac5d1596277eee4147347c19e9be9dab816767007f02f533be6f6797d3a70e8fef5c07cfaf5d01fae93b77787b171c875dcaaccc1e66c353b26566cd43bd921046d67686e589c7b152347c19691cdb053c21c6f940fd8cc7b1dd4e9f4a1edfb90ee6eaee00fdf49d3bbccded29b33227319bb6f7a4df763c1e60dbec4fe4f0f0b227b01781fa198f077b23bfc7dc5e01eae031df1ba09f396897f7cddb7be13854c2bc2383cceaf3d8984ddbfbd26f3b1e0fb06df627727878d917d88b40fd8cc783fec8ef31b757803a98a7fd01fa99837679dfbcdd0fc7a112e61d1964569fc7c66cdade9f7adbe5e7a461dbec4fe4f0f0b23fb01761fa591e0fae89fc1e737b05a883797a4d807ee6a05dde376f5f03c7419995599995599995599995599995599995599995599995599995599995599965339bb6af4dbdedf2fc3db6cdfe440e0f2fd706f6224c3fcbf3f70722bfc7dc5e01eae0313f10a09f396897f7cddb07e03828b3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb36c66d3f675e9b71d7f1f07db667f22878797eb027b11a89ff1fcfdf591df636eaf0075f0985f1fa09f396897f7cddbd7c371506665f6319bb60fa6de76f97a1eb6cdfe440e0f2f07037b11a69fe5f1e050e4f798db2b401d3ce68702f43307edf2be79fb101c874a98776490597d569f9398d567f53989597d569f9398d567f53989597d569f9398d567f53989597d569f9398d567f53989597d569f9398d5e7978ecfa6edc3a9b7dd19cfdf63dbec4fe4f0f07238b01761fa599ebf1f88fc1e737b05a883793a10a09f396897f7cddb03701c4e74e61d1964d6dc181f66cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e62466cd0d654e62d6dc50e6246609b961da3e927edbf1f7d9b16df6277278783912d88b40fd8cef7fb921f27bcced15a00ee6e90d01fa99837679dfbc7d031c076556661f339e2713d36b3bbe1f8edba8b26ba31db5e56ad08ed9720d6883b65c0bda8db65c07da4db63c01b49ba13facdd62cbcb40bbd5964ba0bddc96af06ed15b6bc0bb457daf26ed05e65cb7b40bbcd96f782f66a5bde07daedb6dc0fda1db6bc1fb4d7d8f235a0bdd696af05ed75b67c00b4d7dbf275a0bdc196af07ed8db67c10b43b6df9106877d9f261d0de64cb03a0dd6dcb8b40bbc7a3bdd9962f01ed2d1eed5e5b9e04da7db63c19b4ff8132afdf6acb53407b9b2dd783f6765b2e80f60e5b9e0ada3b6db901b477d9f234d0eeb7e5e9a03d60cb33407bd0966782f6902dcf02ed615b9e0dda23b63c07b477dbf25cd01eb5e579a03d66cbf3417b8f2d2f00edbdb6bc10b4f7d9321ea3f7dbf211d0781cb801341e078e82c6e3c031d0781c18048dc7811b41e371e026d0781cb81934ce9d5b40e3dcb91534ce9d9783c6b9f30ad038775e091ae7ceab40e3dcb90d34ce9d5783c6b9733b689c3b7780c6b9f31ad038775e0b1ae7ceeb40e3dc793d689c3b6f008d73e78da071eedc091ae7ce5da071eebc0934ce9dbb413bc996ef01ed645b7e3368a7d8f25b406bb4e57b413bd596ef03ed345bc67181c79fb78276ba2dbf0db4c5b6fc76d096d8f23b405b6acbef048ddf73de055a932ddf0fda725b7e00b4665b7e10b4165b7e08b4565b7e18b4365b7e04b4765b7e3768455b7e14b40e5b7e0c347e9f7c0f689db6fc5ed0ba6cf97da075db328f0be6fc33e70cf799fda887fe357bb85933e73473f745e97e66e2b678dfbccded1946f69bff6f1c194ba3656c73180d4f2980679843bc8cf4b75f09783a02f004ea67fcb75fa7d3a7a2d3a702d4391dfad919a09f396897f7cddb9dd07688638e5ed4dafd2e76bca8813acfda3739b31ac947de87c9df764f5f5604ee0bef9bc7a515e3d07697d376abd3368ebdbc8c747e750173770066b3df9ef4f71b9f5f2bedbe38a7b89d56e8532f7890569fb0ed9c0d6e87f51a28ffbb61a82ed7633ff8fd8bd94d2ef3b14476f77525e77505a8b3c2d3ffbe28ddfef7383c3d0eb339262f340c7104381fe21c58e170f0762b78d793e0dd0af08eebe0fb5f7b20efba1d9e6ea76dc3c39f713a41e3cf0a3807c1ffdf3c0edceeb8d7e9e166ad0b187d9f75dad2671cf1b34e1b30b2d60d3c5d813c738ff562c71f7c5fae73eaf06b6ba04e95fd63af211afeb706d735e7ddbfa05ffc37f37fa274c7f4ba007ee1dff311f813391e46e017f7b33600cfe468e86ffa63830347775fd3bfad7ff7be1ca0d53898b8ce79ba51051a96ab3d5a140d9fbac0294f9ebac029cf2ac7169c32e1fae64f29d32d9e1ee83f7460f0e2c3fd87f71ebdf5c860ffbecd03d72075ad438fa4493d4052d47c3d1a897e5274fcc14ff5cc64b845b0ff9c05a9b69da8b540c6be89d1907d3cb363deadcd8862666acc19694e4e63ad996931332b6626c5cc9c9899123333626642cccc8799e930331b6626c3cc5c98998ac6a83c13711af07c1f18cd5f08e66c37330966e6c0cc14987709f3e9d38cace6938479d733239d19e1cca764f317931939cca86c461c334a98773df36e673e9d9877eb5514ab29d650aca55847b1de7abd81e20c8a3329cea27819c5d914e7509c4bb191e23c8a4d149b29cea7d842b195e2028a0b29b6516ca7b888e2e2a83cf3776954bec27919c5e51457505c497115c5cea83ca3be2b2acf989b197233236e66c0cd8cb799e13633da6606dbcc589b19eaeba3f20cb499713633cc6646d9cc269ad943335b686607cd6ca099fd33b37d6676cfcce699d93b335b6766e7cc6c9c997d33b36d6676edf6a83c7b6666cbccec98990d33b35f66b6cbcc6e99d92c337b6566abee8ecab35166f6c9cc3699d925339b64668fcc6c91991d32b34166f6c7ccf698d91d339b63666fcc6c8d999d31b33166f6c5ccb698d995c7a2f2ec89992d31b3236636e403141fa4f810c587293e42f1518a8f517c9ce2718a4f507c92e253149fa6f80cc567293e47f1798a2f507c91e24b145fa67882e22b145fa5f81ac5d729be41f14d8a6f517c9be23b14dfa5f85e54cec91f50fc90e2498a1f51fc98e227143fa5f819c5cf297e41f14b8aa7287e45f16b8adf503c4df10cc5b314cf51fc96e27714cf53fc9ee20f147fa4f813c59f295ea0f80bc55f29fe46f1778a7f50fc331a9a49c581e209bbc1b37abb0707fb0f1d196c1c1c683c74e3c1c103470ededa78f381c16b1b076eea3fbaffe0c0cdf8e2ebec30c453961b8e1edd7d6be381c3fbfa6f691cb871b071607fe39e811b0fef3b862fbad3be68e1f12deedeb72fb9b1fbab5e04e9c3636cf423f6753c19bc71e4be7d7c2c867c662c2f7a7a8c1dbad8be8bacb1dbdbcbefd48dc70e0e0c36161b0fd3bfbb0fd26bfaf7b535e2ff1d23938f0d361e1bdc7d74b071ffd181438d1d6db8df47ebc6d089671ac6f0a2dcb4d1f73cfa5f16540aa2d9140300", - "privateFunctions": [ - { - "selector": { - "value": 283286945 - }, - "vkHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "isInternal": false - }, - { - "selector": { - "value": 332459554 - }, - "vkHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "isInternal": false - } - ], - "id": "0x1310e0230fe8fa9a6c99193217d165b85d180bb916fc60afbedbe85721600ae5", - "privateFunctionsRoot": "0x2dc1f38d7be98a8e72227d6f8aec393c60db813a1819c9c86b02a00cc18f6687", - "publicBytecodeCommitment": "0x2bbeaacc4ec3ee2fa51a3e2720a5772c6b079629e26e39c4a187fc6e4a56e46a" -}" -`; diff --git a/yarn-project/circuits.js/src/contract/artifact_hash.test.ts b/yarn-project/circuits.js/src/contract/artifact_hash.test.ts index 9ff2f8d54a13..f4611d72b8c1 100644 --- a/yarn-project/circuits.js/src/contract/artifact_hash.test.ts +++ b/yarn-project/circuits.js/src/contract/artifact_hash.test.ts @@ -5,7 +5,7 @@ describe('ArtifactHash', () => { it('calculates the artifact hash', () => { const artifact = getSampleContractArtifact(); expect(computeArtifactHash(artifact).toString()).toMatchInlineSnapshot( - `"0x10d144027c5d0dddb7336f9becb14db882c0f4e48cfab674f1871458f81838ca"`, + `"0x19dcd971117d72ceed658023cf16036d912de56c75a54da414d2d6bd645c99f2"`, ); }); }); diff --git a/yarn-project/circuits.js/src/contract/artifact_hash.ts b/yarn-project/circuits.js/src/contract/artifact_hash.ts index a51a609ccfd4..f07138eb1673 100644 --- a/yarn-project/circuits.js/src/contract/artifact_hash.ts +++ b/yarn-project/circuits.js/src/contract/artifact_hash.ts @@ -1,6 +1,7 @@ import { ContractArtifact, FunctionArtifact, FunctionSelector, FunctionType } from '@aztec/foundation/abi'; import { sha256 } from '@aztec/foundation/crypto'; -import { Fr } from '@aztec/foundation/fields'; +import { Fr, reduceFn } from '@aztec/foundation/fields'; +import { createDebugLogger } from '@aztec/foundation/log'; import { numToUInt8 } from '@aztec/foundation/serialize'; import { MerkleTree } from '../merkle/merkle_tree.js'; @@ -8,6 +9,11 @@ import { MerkleTreeCalculator } from '../merkle/merkle_tree_calculator.js'; const VERSION = 1; +// TODO(miranda): Artifact and artifact metadata hashes are currently the only SHAs not truncated by a byte. +// They are never recalculated in the circuit or L1 contract, but they are input to circuits, so perhaps modding here is preferable? +// TODO(@spalladino) Reducing sha256 to a field may have security implications. Validate this with crypto team. +const sha256Fr = reduceFn(sha256, Fr); + /** * Returns the artifact hash of a given compiled contract artifact. * @@ -30,25 +36,37 @@ const VERSION = 1; * ``` * @param artifact - Artifact to calculate the hash for. */ -export function computeArtifactHash(artifact: ContractArtifact): Fr { +export function computeArtifactHash( + artifact: ContractArtifact | { privateFunctionRoot: Fr; unconstrainedFunctionRoot: Fr; metadataHash: Fr }, +): Fr { + if ('privateFunctionRoot' in artifact && 'unconstrainedFunctionRoot' in artifact && 'metadataHash' in artifact) { + const { privateFunctionRoot, unconstrainedFunctionRoot, metadataHash } = artifact; + const preimage = [privateFunctionRoot, unconstrainedFunctionRoot, metadataHash].map(x => x.toBuffer()); + return sha256Fr(Buffer.concat([numToUInt8(VERSION), ...preimage])); + } + + const preimage = computeArtifactHashPreimage(artifact); + const artifactHash = computeArtifactHash(computeArtifactHashPreimage(artifact)); + getLogger().trace('Computed artifact hash', { artifactHash, ...preimage }); + return artifactHash; +} + +export function computeArtifactHashPreimage(artifact: ContractArtifact) { const privateFunctionRoot = computeArtifactFunctionTreeRoot(artifact, FunctionType.SECRET); const unconstrainedFunctionRoot = computeArtifactFunctionTreeRoot(artifact, FunctionType.UNCONSTRAINED); const metadataHash = computeArtifactMetadataHash(artifact); - const preimage = [numToUInt8(VERSION), privateFunctionRoot, unconstrainedFunctionRoot, metadataHash]; - // TODO(miranda): Artifact and artifact metadata hashes are currently the only SHAs not truncated by a byte. - // They are never recalculated in the circuit or L1 contract, but they are input to circuits, so perhaps modding here is preferable? - // TODO(@spalladino) Reducing sha256 to a field may have security implications. Validate this with crypto team. - return Fr.fromBufferReduce(sha256(Buffer.concat(preimage))); + return { privateFunctionRoot, unconstrainedFunctionRoot, metadataHash }; } export function computeArtifactMetadataHash(artifact: ContractArtifact) { // TODO(@spalladino): Should we use the sorted event selectors instead? They'd need to be unique for that. const metadata = { name: artifact.name, events: artifact.events }; - return sha256(Buffer.from(JSON.stringify(metadata), 'utf-8')); + return sha256Fr(Buffer.from(JSON.stringify(metadata), 'utf-8')); } export function computeArtifactFunctionTreeRoot(artifact: ContractArtifact, fnType: FunctionType) { - return computeArtifactFunctionTree(artifact, fnType)?.root ?? Fr.ZERO.toBuffer(); + const root = computeArtifactFunctionTree(artifact, fnType)?.root; + return root ? Fr.fromBuffer(root) : Fr.ZERO; } export function computeArtifactFunctionTree(artifact: ContractArtifact, fnType: FunctionType): MerkleTree | undefined { @@ -58,8 +76,8 @@ export function computeArtifactFunctionTree(artifact: ContractArtifact, fnType: return undefined; } const height = Math.ceil(Math.log2(leaves.length)); - const calculator = new MerkleTreeCalculator(height, Buffer.alloc(32), (l, r) => sha256(Buffer.concat([l, r]))); - return calculator.computeTree(leaves); + const calculator = new MerkleTreeCalculator(height, Buffer.alloc(32), getArtifactMerkleTreeHasher()); + return calculator.computeTree(leaves.map(x => x.toBuffer())); } function computeFunctionLeaves(artifact: ContractArtifact, fnType: FunctionType) { @@ -70,11 +88,25 @@ function computeFunctionLeaves(artifact: ContractArtifact, fnType: FunctionType) .map(computeFunctionArtifactHash); } -export function computeFunctionArtifactHash(fn: FunctionArtifact & { selector?: FunctionSelector }): Buffer { - const selector = - (fn as { selector: FunctionSelector }).selector ?? FunctionSelector.fromNameAndParameters(fn.name, fn.parameters); - const bytecodeHash = sha256(Buffer.from(fn.bytecode, 'hex')); - const metadata = JSON.stringify(fn.returnTypes); - const metadataHash = sha256(Buffer.from(metadata, 'utf8')); - return sha256(Buffer.concat([numToUInt8(VERSION), selector.toBuffer(), metadataHash, bytecodeHash])); +export function computeFunctionArtifactHash( + fn: + | FunctionArtifact + | (Pick & { functionMetadataHash: Fr; selector: FunctionSelector }), +) { + const selector = 'selector' in fn ? fn.selector : FunctionSelector.fromNameAndParameters(fn); + const bytecodeHash = sha256Fr(fn.bytecode).toBuffer(); + const metadataHash = 'functionMetadataHash' in fn ? fn.functionMetadataHash : computeFunctionMetadataHash(fn); + return sha256Fr(Buffer.concat([numToUInt8(VERSION), selector.toBuffer(), metadataHash.toBuffer(), bytecodeHash])); +} + +export function computeFunctionMetadataHash(fn: FunctionArtifact) { + return sha256Fr(Buffer.from(JSON.stringify(fn.returnTypes), 'utf8')); +} + +function getLogger() { + return createDebugLogger('aztec:circuits:artifact_hash'); +} + +export function getArtifactMerkleTreeHasher() { + return (l: Buffer, r: Buffer) => sha256Fr(Buffer.concat([l, r])).toBuffer(); } diff --git a/yarn-project/circuits.js/src/contract/contract_class.test.ts b/yarn-project/circuits.js/src/contract/contract_class.test.ts index 2f8d7123092e..45a6c282caa8 100644 --- a/yarn-project/circuits.js/src/contract/contract_class.test.ts +++ b/yarn-project/circuits.js/src/contract/contract_class.test.ts @@ -1,17 +1,32 @@ +import { FunctionSelector, FunctionType } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; -import { toFriendlyJSON } from '@aztec/foundation/serialize'; -import { setupCustomSnapshotSerializers } from '@aztec/foundation/testing'; import { getSampleContractArtifact } from '../tests/fixtures.js'; import { getContractClassFromArtifact } from './contract_class.js'; describe('ContractClass', () => { - setupCustomSnapshotSerializers(expect); it('creates a contract class from a contract compilation artifact', () => { + const artifact = getSampleContractArtifact(); const contractClass = getContractClassFromArtifact({ - ...getSampleContractArtifact(), + ...artifact, artifactHash: Fr.fromString('0x1234'), }); - expect(toFriendlyJSON(contractClass)).toMatchSnapshot(); + + // Assert bytecode has a reasonable length + expect(contractClass.packedBytecode.length).toBeGreaterThan(100); + contractClass.publicFunctions.forEach(publicFunction => { + expect(publicFunction.bytecode.length).toBeGreaterThan(100); + }); + + // Check function selectors match + const publicFunctionSelectors = artifact.functions + .filter(fn => fn.functionType === FunctionType.OPEN) + .map(fn => FunctionSelector.fromNameAndParameters(fn)); + const privateFunctionSelectors = artifact.functions + .filter(fn => fn.functionType === FunctionType.SECRET) + .map(fn => FunctionSelector.fromNameAndParameters(fn)); + + expect(new Set(contractClass.publicFunctions.map(fn => fn.selector))).toEqual(new Set(publicFunctionSelectors)); + expect(new Set(contractClass.privateFunctions.map(fn => fn.selector))).toEqual(new Set(privateFunctionSelectors)); }); }); diff --git a/yarn-project/circuits.js/src/contract/contract_class.ts b/yarn-project/circuits.js/src/contract/contract_class.ts index 8d775228503b..8f270051f871 100644 --- a/yarn-project/circuits.js/src/contract/contract_class.ts +++ b/yarn-project/circuits.js/src/contract/contract_class.ts @@ -1,4 +1,4 @@ -import { ContractArtifact, FunctionSelector, FunctionType } from '@aztec/foundation/abi'; +import { ContractArtifact, FunctionArtifact, FunctionSelector, FunctionType } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; import { ContractClass, ContractClassWithId } from '@aztec/types/contracts'; @@ -21,8 +21,7 @@ export function getContractClassFromArtifact( .filter(f => f.functionType === FunctionType.OPEN) .map(f => ({ selector: FunctionSelector.fromNameAndParameters(f.name, f.parameters), - bytecode: Buffer.from(f.bytecode, 'base64'), - isInternal: f.isInternal, + bytecode: f.bytecode, })) .sort(cmpFunctionArtifacts); @@ -30,11 +29,7 @@ export function getContractClassFromArtifact( const privateFunctions: ContractClass['privateFunctions'] = artifact.functions .filter(f => f.functionType === FunctionType.SECRET) - .map(f => ({ - selector: FunctionSelector.fromNameAndParameters(f.name, f.parameters), - vkHash: getVerificationKeyHash(f.verificationKey!), - isInternal: f.isInternal, - })) + .map(getContractClassPrivateFunctionFromArtifact) .sort(cmpFunctionArtifacts); const contractClass: ContractClass = { @@ -47,11 +42,20 @@ export function getContractClassFromArtifact( return { ...contractClass, ...computeContractClassIdWithPreimage(contractClass) }; } +export function getContractClassPrivateFunctionFromArtifact( + f: FunctionArtifact, +): ContractClass['privateFunctions'][number] { + return { + selector: FunctionSelector.fromNameAndParameters(f.name, f.parameters), + vkHash: computeVerificationKeyHash(f.verificationKey!), + }; +} + /** * Calculates the hash of a verification key. * Returns zero for consistency with Noir. */ -function getVerificationKeyHash(_verificationKeyInBase64: string) { +export function computeVerificationKeyHash(_verificationKeyInBase64: string) { // return Fr.fromBuffer(hashVK(Buffer.from(verificationKeyInBase64, 'hex'))); return Fr.ZERO; } diff --git a/yarn-project/circuits.js/src/contract/contract_class_id.test.ts b/yarn-project/circuits.js/src/contract/contract_class_id.test.ts index 37ec36e340d0..2700c2481599 100644 --- a/yarn-project/circuits.js/src/contract/contract_class_id.test.ts +++ b/yarn-project/circuits.js/src/contract/contract_class_id.test.ts @@ -14,14 +14,12 @@ describe('ContractClass', () => { { selector: FunctionSelector.fromString('0x12345678'), vkHash: Fr.fromString('0x1234'), - isInternal: false, }, ], publicFunctions: [ { selector: FunctionSelector.fromString('0x12345678'), bytecode: Buffer.from('123456789012345678901234567890', 'hex'), - isInternal: false, }, ], }; diff --git a/yarn-project/circuits.js/src/contract/events/__snapshots__/private_function_broadcasted_event.test.ts.snap b/yarn-project/circuits.js/src/contract/events/__snapshots__/private_function_broadcasted_event.test.ts.snap new file mode 100644 index 000000000000..e72d0bd347b2 --- /dev/null +++ b/yarn-project/circuits.js/src/contract/events/__snapshots__/private_function_broadcasted_event.test.ts.snap @@ -0,0 +1,31 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PrivateFunctionBroadcastedEvent parses an event as emitted by the ContractClassRegisterer 1`] = ` +PrivateFunctionBroadcastedEvent { + "artifactFunctionTreeLeafIndex": 0, + "artifactFunctionTreeSiblingPath": [ + Fr<0x18e01957faa463b1495f979f153e839d5fbd2af9b0d142940d1df29d9bcf4373>, + Fr<0x2c450d02ff856d78b6197914dbb85cc88b31ef6f32d534f01b893dcee663a119>, + Fr<0x1c26a986ab599f5027f02a8390d7cb96c87146380163a5fa002c30cba8e32f68>, + Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + ], + "artifactMetadataHash": Fr<0x229d43c7daac528d0aefd72bee59385d7e9ff06ea477b673389e1f65168cba9f>, + "contractClassId": Fr<0x26222cd450fe6beecf6cbe6495e118412940ee0da5744629dabcaf010a2a4e38>, + "privateFunction": BroadcastedPrivateFunction { + "bytecode": Buffer<0x1f8b08000000000000ffed7d077c1dc5b5fe4a5c0b8390e8d8a68a9a80917575d58dc11770c01d375c31b66cc9058c0db6e909a407d21b2190062124109200792185f4c64b5e3ae9e5a591e4e5252fc94bf9bf24af38ff9dabf9ac4fc73357d2b2e7eaca3bfbfbcd6f6667cfccf9ce99d9993365676ba281eb9735517469cd40d878b5b13b20764d749fb361dc4f10f775827ea2b83f5cdc1f29ee8f16f793c47d93757c59c851d1fa6df9cef6f6feae427f6b5b6b6fbed0b3a1bb23dfdeb1a1b3bbb5bbb5a3bba3afd0ddd6d6dfdddeddd5b3a1a72bdfd3daded6dfbaa9a3a76d537ee03a95f2ca3fcdab867460ae9363b72776a758ffd48cf967c7ee345b66ac97d332aa0fd6cbe9d1c0fb86facc97ace3f9a777b5a698579ef19e110db409e6aa73e0c77580233c91e8f6a42c2bf392580e77e0dca70c8a2982d128cc3314f27d46945ea3aa25f733d22fa37ca55ec29a28fd97d0f878f19e19bb33637756eca646038d4c73ec4eb0cf270adda582a53ddf55e29f1baa335cf5d140471e11cd81d18021004cb9f431b59a7c27a49d6f3edf39d1e24f39dfbd864364711789cf04d2d541d1a09e53e2ddcabc61dc1d443c5174081f41b4a0833e50d6c0de100dd6cf83caa4cb89748d4453e790bf18a52bff8102cf8102f3048a331d484d6e5f6c1af5cdbc3fdc79427f91c01b114ee049fdbd8a75757034f8ee6eeedf7de18eedbb77f66edc3d67fbaeddbddb37f673b304d87502764d345404f9dc5cb58eb87a12ef008a43fa1cc5d50a75d43bf01c1429f6fb18c09836f89e68d0000648d3561ba367aaf5cf8c060d43e31f17bb69940e029d659f4f23ba16075db37dde62fd438d4c42d65a21f3d3edf3d36c93f251fa6d2be43dc0eae474eb9b36aa7518dde49fded53a35453db7a6a89b4ad93e6746e99627ae42140620c382d128cc8242be6d51750f408cdc6de997515e5698b4cb3f2d9d9e99625eedd1f86bc4d2c4cc783ba2d0880d0b46a3303b14f2ed8caabb11337277a65f464eac4f57fe368b356d6bacad4acb3b2c1fec3b4dde15edbb7cd095517db05ebaa3a10d33469c7ca5dd769c1ca56ff4a48df19448a793ee890646d1e6529a496de3995459963c824d91677e6234d4e84c25dfb81ccc6c1966cc4a533242aec329ae8664d498b5e2e928e48d7bf033335b0d367c75efc62bcfdfb9f9daabfab7efdec59500c41ce77a016b1dcf5cf35b4ad3864304ae1102f39cd80421976bee4c759e2c722825adbcbba3f47ae69ef47095862b75d1be5735af3739e03eedbcfbfbbabbbb3a4bc5a4a6836e251da48db3699ce09c1055779dda0b94f29c6efd73ac3fc3fae75aff3cebcf1418ceb7fe05d6bfd0fab3ac5ed1683e2b7617c5eee2d8cdb67173a2a16b747363372f76f363b720760b637749ec16c56e71ec96c46e69ec96c5eed2d82d8fdd8ad8ad8cddaad8ad8edd9ad85d16bbb5b1bb3c76eb62b73e76bdb1db10bb8db1eb8b5d7fec36c56e73ecb6c46e6becae88dd95b1db16bbab62b73d763b627775ecae89ddced8ed8addeed85d1bbbeb62777dec6e88dd8db1bb297637c7eed9b17b4eec6e89ddadb17b6eec9e17bbe7c7ee05b17b61ec5e14bb17c7ee25b1bb2d76b70b7dbd34762f8bddcb63f70af1ec95b17b55ec5e1dbbd7d8674df6d96b63f7bad8bd3e7677c4ee0db1bb33766f8cdd5db1bb3b766f8add9b63f796d8bd35766f8b06d65fee8ddddb63775fecde11bbfb63f7ced8bd2b760fc4eec1d8bd3b760fc5ee3db17b6fecde17bb8763f748ec1eb5585069df1fbb7f8add0762f758ec3e18bb0fc5eec3b1fb48ec1e8fdd4763f7b1d87d3c769f88dd2763f7a9d87d3a769f89dd6763f7b9d87d3e764fc4ee9f63f785d87d3176ff12bb2fc5eecbb1fb4aecbe1abbafc5eeebb1fb46ec9e8cdd3763f7add87d3b76df89dd7763f7bdd87d3f763f88dd0f63f7a3d8fd6bec7e1cbb9fc4eea7b1fb99d0f9cf63f754ec7e11bb5f8a67bf8addbfc5eed7b1fb77f1ec37b1fb6decfe2376bfb371bfb7fe1fa2a106d17fc6ee8f22ee4fb1fbb30dffc5faffcffaff65fdbf5aff6f22eddf63f7df22ee7f62f7bf22eeffa2811193b9fe617d348a35d6afb5fe01d6cf597f82f5ebac7fa0f5275aff20eb1f6cfd7aeb1f62fd06eb37c6fe8c636dda68f02a466959f17d1b78e4206d0ba30bac57c36fb2f107d8fb03447ccedee7c84237f113ecfd048a77edf1e005d71a8a43dda9a5b8bd8bba14b7775197e2f6ee87a07d24a82fa5346284514a03f9286e2264a3b8832017c51d2cf469e2ea8937e20eb1711329aec1c61d44718d36ee608a3b94e4837f988d3b241acc177d51314aabceb496f6c85c9076be71ce26df59e9e75b1a8d3f2b1a2ca722f1b9807475910da7bd47e659946f0df1417c8ec267102de8a00f8c3281dddcc3b6b8a84cbaf345ba46a2b9d0217f314a57fe5902cf2c81d994c971366ceaf1d1b61ef3ac89423deed4a9c7edf9508f075648a2c85d1f0fb3e1fdb11e9f4538d2afb31d9da1ed1df135ea3a7b21d1caba87bd8bfb639ded261c0a75b637d4d9115fa3aeb38b8956d6bda36c787facb317110e853adbaf53670bc1368806e69fa2c85df78eb1e1fdb1ce2e231ce9d7d92ea53adb16ea6c3430f71945eeba37d986f7c73abb8170a45f677bfb836d30e26bd475f666a29575cf4e2bee9775f66ac2917e9ddd50087576c4d7a8ebeced442bebdef136bc3fd6d95b0887429d0df30623bf465d67ef245a59f74eb4e1fdb1cebedc86cd9cede3b9817013c57dd4c69d4c7815eaf646a5ba5d08757b609d3b8adc75f4141bde1febf69b0987429ded0f7576c4d7a8ebec63442bebde6936bc3fd6d977dbb0697b3f65dbde3328eed336ee1914f7191bf74c8afbac8d3b93e23e67e374d737367684f762c4d7a8df8b2f10adacdf536d787f7c2f3e4e3814ea6c57a8b323be465d67bf43b4b2ee35dbf0fe5867bf443814ea6c4fa8b323be465d677f41b4b2eeb5d8f0fe5867bf6fc3c65ef892b5175a29eecb36ae40715fb1716d14f7551bd74e715fb3711d14f7751bd74971dfb0715d14f7a48deba6b86fdab81e8afb968d9b4e71dfb671e750dc776cdc0c8afbae8d3b97e2be67e3cea3b8efdbb89914f7031b57b471e60b27ec49fcb68d33650b7bac18a555b67d1d863f9f8d66ae1a715fa4f09984e799a9e3197a4ed0c6de6ddb16eddc7a5defeefe8baeddbe71f7d61ddb6b0822607f5bc0ae89868a80e77514574b61fec02b47e10914e6b4073ae25c974e910dbc8ecf243e45ba3f33f0ce2cefb3d2e75da8271eb8ca350f3c3c9caaa08b7ae231123c5375f1e41b090ff33a5b41f672f5e0ec2ae1dd9c3eef521d3c3b1a7a952bf366c2d3a2a08b7ae231123c2d84679a021e25394bdb3ef0d9528a27c4944cf956a1ab66a1ab46a2c993fe5a15f457437c9137ee5b090fea20b0d613ddd955821171d3088fc63b50ae3d68a902de4617e8b778ba13cfb9dfac86f2e2e9d789368cfec4d8a1cd35837815dad8d23b097e399b2f7034533c68f64c19c4d66ab135d0739e3a9e26e234eb0578216fdc835f03c9338de21066fb25af84b1c58311fcb87dacf3c891239a1956ffe6b30ab6475866d94ed5537a6ebb0a4a32cbf61ef705c208195b098f962dd32cf0343b74b13ff2f6bd1fcafd575eb36e61ea08d382b26ee5886601bd2b9c16b8641bdd40ba69231db529c982f2a811e5c3bc356cc872f5725ae03da6bc15faca02f7cbb8463a8651788f0b6c9b8d044f81f068bc8b4a7296da414c6ba73da6ea10ba6a11ba6a249a76d25f8782fe6a882ff2c63d7f1a3ade301b3cd216ab27ba6955821171dc6f68f5bfbe36ac5005bc791c88b10997178f49aaa1bc786e014740c01631f6cd4d340e5498cf2cb04e614f1d24f497239a4fd138f0161a07360bfdfac6de951a63e11efc78acea1a27f13850c11e2ee939efc1087e5c77ea3c72e488e676cf3890654618ed94afedd2b26f7def421b61947d80a6fd3555e099ead0c5fec8dbf77e306f2dfb47a16e95de27d80768b764ddca11cddd621c8878e0c27be29a9f006d2de58d674d36be5df0de63e3651e4d91ae0dabd0a79574dd29740dfc1da46bd0bc43e8bad3a36b6e03a01fd0d646fbda813536be53f086ae651e3556d79de9eb64c83b85b17b8be0af39efe96b4b2a31171f78fb792bd837a31e2bf3fa59faed415f094f7e14783a088fc6bba8d4ee95fa2e6c2b4b7becde2d749517ba6a249a2ed25fb782fe5ce372dc835fc01c3007cc0173c01c3007cc0173c01c3007cc0173c01c3007cc0173c01c3007cc0173c01c3007cc017331600e9803e68039600e98a38039fff4ae8039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e68039600e9803e6803960ae3acc064f0bf859bf9ee85aaa0423e23a094f87129ea9020fee3baa80b7d1c59936dc6c7d2eaf3309633594d754c278b00d17ac3f2176474d18c45b481d6f5fc1e06d237e45078e1cd13c7fca20ed648bad819e9f49f2b48a3823433e751906740e5ec81bf7e0d740f2b4521cc26711c6e6d4310ee839efc1087e5cbfeb3c72e488e654abffc3a2813a7596436684d14ed5537a6ebbc6ea7de532984a785a94f014049e82431763c59bdb2ebc4ff5f49cdfa3a94a185b0446dc4f258c882b109ef4dba6f2ef75e03db6bcdbd2e75da88f86be23e6aa11f7450ab7111e8d77b69e788c048f721b926f243ccc4bab2df0d583a955c25ba1cf2a70ff88ab5c99b3cddb953e9e2eb65d478287c74c9de9e369559233cff6f89e14f335baea11baea10ba6a249a6ed25f8f82fe6a882ff2c63df805cc0173c01c308f16b3c123c757f54437b54a30228ee7aa14fa94b276445715f036ba80bdcb738b78cef6763594572b61acb761d8a1662ae2669aab4a7f0e25df5523f8150907f8e5886616cd55dd4a735572fcca3616eb5cc37e2a373f087e0d240fcf9320cce31e0d9bb386b0488ce0c773f9751e397244f3529aab625978feb347c419f9a6a72f5fabab6dc73df83510f61ec2a335de6916789a1dbad81f79cbf5a06e076f85b62faf54b74aefce39362fb451b26ee588e66e7a2f382d70e13d411e0da49b7348471aef89c97786928ece153a02fe19a423d0dc2b748478a9237e77a19b7349470ab2144cbee729e968a6d011f09f473a02cd03424788973a9a413a826e405b4b613cdb637557a4fba72be3267b997ccf4f90efa6612e93ef054f1f6fab8c8828af5a0a83d7489ebb68cfa734e709ba3de2fec068b08cb81ee0f963540f26126d314aad6eb6b17e53ccb754e7a10bd4f99942fe1cd13c2eea3ce2810b751e793490ce58e717087d36d9f8f305ef3dd1d0323a9fe89574d2ceef5e8af996747da1cd0bba66fce6ca11cde784ae110ffa0ea1ab06d20f68f99dc0b31a1b7fa1e00d5dcb3c0cbd924e3a4cbeb3d2cfb7a4eb67d9bc2688bcc12f47345f15ba463c70f1bcb7b91a483fa0ada5bc5977b54483e7d0b5cc03ba56d049a7c9f7a2f4f32de9fae268a8ae81ff22d23568be27748df848e87a16e91afab998747d91d05d938dbf58f086ae651e4d56d717a7af932176764d34d4ce063fcdfd30bef14577e03da6bcd35f3f1bd8e722df3fcc07801fbf7fbf1de6fdc35c0dcf8dc8baeb4a07fae94403fe7582e662c2059a3f8abd356d8256f35df5955db5f05698172badbb72199aabdc3a27cf1d2bf423edf5d1d039b0e1f05c447834f65229c9599a07996df34a7bdd758ed055a7d05523d1cc26fdcd51d05f0df145deb807bf803960f6613678d03e016b3dd15d5c251811c7fb5214da8db27dc54555c09bd7d678ef2b9ef33a4f359417ef553fc48631e76b4c9193ea06f12a8cc7da192fec36e0e0312a68ea686ded548badc1a15f23cf05224e69fc5ed23978216f39a7d140f2f05c05c2bcb6a63077d65e130db51b1823f8191accd3d645feb919d04cb3fa3f4cc88236c994c17411a7b9a60c5ec81bf7bc8601ecd3098f964d3b4be099e5d0c5fec87b86e03d2323728f8477faeb6503635f6eb3396f5efb03cdf9f4de725ae0e2bed35c0d24438faa2cee3572290bef1fa913343d242f686693bc3ca66659b4da245f9da806deb5c48fe7036b05267361fe50d683a648ad5f2df0de0c5ce5c6c208ebcc15b4e7eb05bfe1f068ef33539a13c9f35c42da6373f99d4f51e88abff3e1b184d6b75172bf11ee5ddf543445e9eaa27904ba6876e051d8e3565617fc9de06830778c43cc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3ecc41cf41cf3eccd5a0673e0f167cf93bf29e2ac18838edb3c20d1edfb70f9d55c09bbf11c5b7365c5efcbd623594d72cc2a3f00d68e9bb8a06c1cb7cc774e5819a7c0ba53df8f2db538983bf3d3d62f220ed0e8bad819ee33de3ef44f8dd53f8aeb35496c84be6cde78fb1fe10076cfccdec4c11a7f99d973c2b10f77c9ea294652cf5a8c9dbd766ccd42d87029739ae1a715fa4307f37abd07eb6f337c323c1c3ed79f8c6cafd8dd574a1ab2c7f63e5d245b5dbcce53057abcd5ced7a3678647fc336d8cc2ac158499bb928f0e0be1236f370bcd966663bab5a6de622e129a68fa76433370a5ec62e7d806c660d7ba146f02b120e3e6b0034274e1aa47d0fd9cc788ef78cbff5e6774feb1f19be73f8c1af21729f1f22ed63df7f33b4de13df7f333a09a394652cf5a8c9db77de8b725b59e032c735521b55c1c61af59981daff5f559233cf6d7bda36f36ca12b69a336124d33e96fb682fe5c363ceec12f600e987d985dffbae2fff9765509c64a8e417dfd544b15f066db96ed21d7ff8eaba1bc94cf2e2ad9b6870a5ec67efcc581ba7c794e1236acc4c1ff3ef9f6d183d87e4db62d9ee33de3fe99df3dad7f9ffbc629fc4f2fc8c376a3b4637dff27d37a4f7cff276b218c5296b1d4a3266f5f9ba1dc561646fbdf5f6e3fd36f9b0a796e0747826736e1d19807506a834bb62dce674ddbb69d2b74e56adb413387f43757417f2e7b0af7731dbc9ba27475316f04ba98e7c033afc2ba00bfd1629e330e31073d073dfb30073d073dfb30073d073dfb30073d073dfb30073d073dfb30073d073dfb30073d073dfb30073d073dfb30073d073dfb30073d27c36cf0c8f5a17aa2eba8128c88abc4be00df7ad5ec2ae0cd6bdcbc2e8ae7bcbe580de5a5bce7b5b4ae7598e065d6915f3351936f6b9ef71062ffa6c4c1ff4efad95183b477586cbc568cf7ccc8e3dacfa1b517d7b75f01fc78ad98d78fe57a763da5a9c43e0bb94f1ef7b309a394652cf5a8c97bb8fdd44ae550e032c735d235e5f4d744dbf2dc0e8e040ff7bf1aff10d59173608d1b6d6dda6bdcf385ae660b5d3512cd3cd2df7c05fdb9d6dc710f7ee31133f36e8ad22dbf0523d0c502079e0515d605f88d16f3bc80b9229843dd08987d9843dd08987d9843dd08987d9843dd08987d9843dd08987d9843dd08987d9843dd08987d9843dd08987d9843dd08987d9843dd08987d9843dd08987d9843dd08987d9843dd08987d9843dd08987d98aba16ef099a3c05a4f74cd5582117195387bc1b7df6b6e15f0e63da2bcaf10cf797f5e359497f2d951a57d61870b5e661fe62d0769f21dd823da41fc8a0e1c39a2f9f49183b4cfb7d81ae839de33dee7c6ef9ec61eb672fb7dc1af21da779f7b43b4ef7ed07a4ac37550eb3d992370e37e2e6194b28ca51e3579fbda0ce5b6b2c0658e6ba47b3215f6e7b5733b38123cdcff6aeca7579233cf6d7bda7b44170a5dcd15ba6a249a05a4bf850afa73edffc43df805cc01b30fb3c123fb857aa29b5325182bb97fd9d74fcdaf02de6cdbb23d84e76c57544379cd263cb3d3c753b26d8f10bc8cfdf838d9b6cde9f36daf11fc8a8403fc7244f302b26d3f41b62d9eb38de81aa7687dcbe61ba7801fdbb16c3722dc461835ec959a68df6f4a659bca730a751e397244f345ab7ff3bd5a23c9c032cbef6aeb297d25da44394782fb8584518e2935ede76681a7d9a18bfd91b7effd60de0a7308a31e37701db8247d3ced5cff4782e712c2a3f18e28c9591a372cb279a53d6e582c74b540e8aa91681691fe162be8af86f8226fdc835fc01c30fb30f3b80158eb896e4e956044dc42c2a3d06e94eda72ea902de3c6ee0350c3c675bb31aca8be77515ecf7d2b8e148c1cbd8e6ff18837183c4c1e38667d1b8e1808307c2be71836b0ca8b5bee11b03821f8f1be6531cc23c6e50b00fda5d36b46bbe06f5adce23478e681aadfee5b881659663045f9bb8287d99cbbe638b082364e476298c1b2af37e306f85be60d4e306ae030aed7e3bd7ff91e0594c7834de1125394be3862536afb4c70d4b85ae5cfd26689690fe962ae8cf65abe21efc02e680d98799c70dc05a4f7473aa046325c75abe7e6a7115f0f68d1bf09c6dcd6a28af4a8c1b8e12bc8c6d3eeb6055be05d7b841e2e071c39c230669673bc60d6c9f2e14719ae354b93e8a7bf0e37103cf75cb7d33beb1eb58dad55296b1d4e3fe3acf3196728fa4ee22cce3dbf4dbeebe527b80fe1ced81ecfb7344b38ec6ae9c16b8e6386441dd5e5271f906f42d31bae64dd107d4099a25a403d06c261d64b58ed6923e50be4d361e3478bec7c62f12793465587f3a76cec0fbbccce685f77989288f1cd15c27dee7650237de67d7bb0b5a573ad0977bc796887c7244f36ccf1c19682752b81855a6ecaa81772de98ddfa35aa2e1f9037e1f97113dcf3314d393a1346fc475c15ce5e669782c79a9129e25a3c07329e1d1188728c9599a375a6ef34a7bde6885d0d512a1ab46a2594efa5ba1a0bf1ae28bbc710f7ee311b3c123dfdf7aa25b56251811b794f028d4e7b26de1a555c09be733780c8ce73c96ac86f2e2756b8575b2d27cc6d18297b13fde49f3191afd0ddb15b07780c365bbd7d37cc6bb693e03cf795ec03537a5b54fcf3737c57317d2a66aa0308fa314d6a20aae7742ceb5729dacf3c891239ac73c361ecb2ced1f5f9bb83c7d99cbbe63cb092364e47649cb3e9463d9250e5dec8fbc7def07f3d6b21f4763cf721d5068f70b5cff47826705e1d1784794e42cd9b32b6d5e69dbb3ab84ae5cfd26685692fe5629e8cf65abe21efcc62366b66781b59ee8965509c64a8e017cede78a2ae0cdf6ec5e5b899eb30d540de5c5f3060a7665c99e3d46f03236e3536360cf4a1c6ccf7ee5f041da7f1bc69e757d33ae357ef27d330e7e6ccff2f7ef08b33dabd06f155cb61d78831fd7c93a8f1c39a2f913d9b32c0bdbae2b459ce6fb045ec81bf7e0d740d8b9cf08b66b65dab5fd5dee91f05e993aef813510d471b4a1785fc12fc734f5033ed640a4ad85b694db2ec8b04a5596013dfa6c3ff03334ab6db84ed0ac2279417308c9abd907f8cabf12f37781b79ff7ead4790fbc736b6c5e78e750f7c02f473493c53bb746e0c63bc77d156400ad2b9d1c03b9de8d55221f7e374e245c3c2705da89142e469529bbc07b6c792bd867a5791caebbe62a378fc3fdcc65a9e369edaa8f86f633c3e1b98cf0a4df9e0ccc2ba52fe7c0bcd25a9b57daf34a970b5dad12ba6a249ab5a4bfcb15f457437c9137eec12f600e9803e68039600e9803e68039600e9803e68039600e9803663dcc060fe67e80b59ee8d6540946c4ad263c0a733265e7e12eab02debebd1178ceebe9d5505e95d81b3149f03273fe6fa91fe49bfe9c696b17cfe5638d01385ceb5cafa2bd11f75a6c0df49cf746ac14719a7b4a7debf2bca754ae63345098f746a4ff8dca809e977b30f2991128fb3a8f1c39a2798f675d85654618ed1f7fbbc36de258b5035c06fc8e69ad4dc875df550e5d8c156f6e13f13ef19a06bf470a6d50ab6bed0ff74b08a3ec6795d67346b4df466bad64b46b37ab75f1e4792f2af3d2fade7034eb68fcdeae55c2339aef0dd91ed568d794e4ccb3adb327c57c8daed6095d2d11ba6a249acb497feb14f457437c9137eec16f3c62e6b691bf3704dd9a2ac188381e0728d4e7b2edf75ad2cf641b663bf44764f72a7c335c70d9bdc0c1dff483660dd9bd3f75d8bdd56c5fb9ce18d3b271788f5091ee2b615fc9f3d6960ade0d91db7651289b82ab6cd688b2e1f7b52e72db5b39a2f983b0f757095acdfe7734f600f7bf0aed5c17b7a923c1b38ef068cc2528c959b207d6dbbcd2b6077a85ae5cfd0468d693fe7a15f4e7eaeb710f7e0173c01c3007cca3c5cc3639db9ca05b5325182b398ef1d9e4eb747997e6b8a7085ec69e3ee99041be0af64b17cff5c3d6070ef0cb11cda964eb9f6ab1f1b7756cebbbc6765aeb15beb11df835900c6c83ed8fb6be6fed66385b5fa16cba5c65b346940db703d2d6e73a089a82ad77d2d657b6ad476deb739ba1d07e76735b3d123cbd84677dfa785a95e42cd9fa1b6c5e69dbfa1b85ae5cfd0f683690fe362ae8cf6543e01efc02e68039600e98b38099c727c05a4f746baa046325c774bef149af2eefd2f8e458c1cb8c0136d1f844c1e6ea36325f4efc8a8403fc7244f3dbc30669afa0f1891c8bf8c6b9ebd397a1ec3817fc1a4806b61bf7c7f189dc3f79b9e0ed1b9fac4f1f4fb7ab6cc07b3de908755e8e4fb80e82e646cff844b95c0ba3dd97c165bd217d3c9da31d2f719fa3d17e2ac999e7fe27edf1499fd0d51aa1ab46a2d948faeb53d05f0df145deb807bf8039600e98c71633f7396cef806e559560441cdbae0aed7359bb79832eef92dd7c9ce0656cd3fbc96e5e9f3edf4e23b33c1f0738c08fcfc7f927b29b1f24bbd9f5ddc87a11a739de012fe48d7bf03318a52d5d893db7d26eaec47e5fdf18a212bc7dfb8794edf3bc52dd2a701b85f703f8c12f47341f219bded5be61af1bf2e06f2a2a61d72acc7f14b8ef838ee4fc478e683e2574d4e7d111bfbbb25fa88df69d836ab2f1b28fc5ff66641e4d916edfc6dfa414e91efc94f665965ddbe3ff6328ecb1ef72d585f5f69ecf5b03cd5786a90b582f461e0d1e3d6a7dbfc078a26864df2fb09dc7368bc6bb574f7c478291edce4d4a78368e02cf26c2d39f3e9e5625394bfdcd669b57da63f92d42571b85ae1a896633e96f8b82fe6a882ff2c63df88d47cc060fde1b60ad27bad555821171fd8447a13e97ed3336917e8eb7e1f5d6376dfcef688ca265836d247e45c2c13618686ea531ca1f698c82e7fc5de07a11a7d50e951ba3805f43e45e23d2e8dbb8bc619fb8beabd7e20d399177afe0cddf85703faf50360557d980773fe908ef415de4b6e573445312201a9cdbef13b49afdef68ec01ee7f15dab902b7a923c1b385f06c4e1f4fab929c257b60abcd2b6d7be00aa12b573f019aada4bf2b14f4e7eaeb710f7ee31133db03dcdf816e759560aca40de5b307b6e8f22ecd859e207899befcf88641be1a6da791b99ff8150907f8e588e662b2339a2c36e3adb7cfd9ce70d9951aed5b39bb12fc1a48066efff7473b037222ef7ec1db676728944dc15536ab45d9703b20ed0cae83a069f1d819cae55a483a37c2fd64da784663f7709fa3d17e2ac999e7fe276d3be34aa1abd542578d447305e9ef4a05fdd5105fe48d7bf01b8f98f91de5fe01747d55821171dcd72bd4e7b276c6565dde253be344c1cbf4e5f3c8ced0ea07e4b909c0017e7c6ec2a164675c427686ecb7ea293dd7232dfb10bc9037eec1cf6094b687e67a8bcfcee8ab006f9fcd5509debeb9944af0f6d957fbbbce4752d7b4ce2bf1957725cea4f495772578fbcabb12bc7d7b9199b7c679727c9e27ae7276adf6199bbef33c35fac9d18e31b88fd11a636c1e059e30c6187ab9ecf5cd4257e3618c51ed98798c01ac591f63f8daefada49f936c98cf0e7e4905c602ccaf4838782c009a1f1e3a48fb321a0be0398f05b688384dfd8217f2de22f4db10ed3b3ed0b4cff8cc8022dd57c236f48d8bfa4817085fa65b360557d9f489b2e1f59a3a4183b439a2b95bcc39bad60514745b18ad2da4dcce758ed63eb992f068ac2129c959b207b6d9bcd2b607ae12baea13ba6a249a6da4bfab14f4e7eaeb710f7e0173c01c308f2d66ee73d8de01dd655582b19263029f7d7ba52eefd21c7a93e0656cd327c86e56b06b3a5dfbcc8103fc789ff97d6437ff0bd9cdd20ee37112d723ad3d1fbe7112f8198cd296aec43c97b49b2b31c7e61b435482b7cf6657b6cff34a75abc06d14de0f59b77244f303b2e95ded1bc6973c9e836e2a61d76e53d2d1554247c0bf8d74049a9f091d5de5d111bfbbb25fa8a5bcf1acc9c6cb3e16df2dc93c9a22ddbe8df7a214e91efc34f72ef9da009edb5598d7ee74d505d4753e471c34bf1fa62ec8317683478f5ab26c13b25ce19005347f11b2205ecac2f55ad6d55aca9beb29d7773c47bd967934e9e9a460f2dd9e7ebe255def8886ea1af8b793ae41b347e81af191d035f26820fd805649963693efd54a3aba46e808f8af261deda5691caa23c44b1d6d271d4137a0ada5bcf1acc9c65f2378a33eca3c9aacae1574d26ef2dd997ebe255def821e6dbec0bf93740d9a4385ae111f095d5f4dba867e40ab244b87c977b7928eae153a02fedda423d01c23748478a9a39da423e806b4b594379e35d9f86b056fd447994793d5f5b5e9eb6448df8b7e7f8be0afb997c837eee03965ad33a17de725f039e20a676a77b2cea5cdc1e71983e674510fa5ad843338d8e670e9514b16391ebfc2210b68a60a597c67e7b8c6c17d159045b60f4b1cb280a67598f641fe8f86e71daead802cbb852cdb1db280a64bc88278290bf7bdb2fdd294e53a21cbd50e594073ae9005f15216eedb2003686b29ccedb391f17aba2f3e4d1937d9cbe47b43827c370d73997c6f7cfa785b6544447aa8a530788de4b98bf6064ab356d0ed11f707468365c4f500cfe7523d9848b4c528ddba097ed2a6b8ce8169a1a89bac03931675936d0aa9072ed3627ab20ce913d11faf73f0d6feb70678bbfeadb15289776f34b41c70bfb202bc7d7b2b2bc1dbb7b7d2f59fe782f5f96c5cfeafaed679b03e3b8dcf83c5bf9a95ffc352c223ff455d49debe7a5a09debe7a5a09debe7ababf97f770bcf97c3bfe0f7bfafd435fc16587c9fe81edb0ab87b1c3563a64c13b7d5d19f95c798186bf4507a63a41e3ea97af17b64216eb5296796bbd2fb067f1bea0eef1fb029a1788f7e506811bef8bebdd00ad2b1de8cbbd1bd7897cf8ddb89d7099609ba09d4871c5a83265d75605bc8d2e60ffa06ceae939db460a638f12c6368111f7d71146c42d273c05253c33049e190e5d68f19e2578cfaa20efe982f7f40af2ee11bc7b2ac8bb53f0eeac20ef16c1bba582bce70ade732bc87bbee03dbf82bc9b05efe60af25e2c782fae20ef1582f78a0af2f68df92ac1db37e6ab046fdf98af12bc7d7d3ff34edfee18b019c12367f3859dd546f1a0794c8c5b6e481dd3507dd4087db00db85c8977abe08d7bb6675a9578fbec99d60af0f6d93395e0edb3672ac1db67cf5482b7cf9ea9046f9f3d5309de3e7ba612bc7df64c2578fbec994af0f6d93395e0edb3672ac1db67cf5482b7cf9ea9046f9f3d037e0d143ed3fa663e61b988d35c0ff2d93dbc1e94b761ee7fb5fafebcc0237937925e5aab54678d1497273c672ae1f1d92c675680b7cf66a9046f9fcd5209de3e9ba512bc7d364b2578fb6c964af0f6d92c95e0edb3592ac1db67b35482b7cf66a9046f9fcd5209de3e9ba512bc7d364b2578fb6c964af00efd58e8c72ac53bf463a11fab14efd08f555f3fd640e1b308cf594a787ce35ae69dfe98baafa38678607d01722fa778d034d9f3130e532e1fc85f23f4c17523afc4fb998237eec1cfcc27602c7f36c561ed631ac561df453bc5611fcd548ac37ef77328ee261b3e97e26eb6e1f328eed9367c3ec53dc7862fa4b85b6cf8591477ab0d7753dc736df8028a7b9e0dcfa0b8e7dbf0c514f7021bbe88e25e68c3b328ee45365ca4b817dbf0748a7b890dcfa4b8db6cb887e26eb7e12e8a7ba90d7752dccb6cb883e25e6ec32d14f70a1b9e4771afb4e1b914f72a1b5e4071afb6e1f914f71a1b9e4d71afb5e1668a7b9d0d2fa2b8d7dbf0251477870d2fa4b837d8f0628abbd386e750dc1b6d7805c5dd65c3cb28ee6e1bbe94e2de64c3fc7fe737dbf0068a7b8b0d2fa5b8b7da30ff67ef6d36dc4b71f7d8f07a8abbd786fb29eeed36cce7e7df67c3fcef9e77d8309fed72bf0d5f4971efb4613e2bf35d367c15c53d60c3db28ee411bde4171efb6e16b28ee211bde4571efb1e1cb29eebd36bc85e2de67c37cd6d1c3367c2dc53d62c3bb29ee511b5e4b71efb761fee7fb3fd9f03a8aabb561ded376800ddf4071391bbe8ee226d8f08d145767c3d753dc81367c13c54db4e19b29ee201b7e36c51d6cc3cfa1b87a1bbe85e2ec2f00f7b67926ce7e86bfb7cd337176097d6f9b67e26cb7b7b7cd3371f638febd6d9e893bdc865f487147d8f08b28ee481b7e31c51d65c32fa1b8a36df8368a3bc6866fa7b84936fc528a9b6cc32fa3b82936fc728a3bd6865f4171f8f7fb2b29ee781b7e15c5e1bf48afa638fcc3e0351487b34c5f4b714d36fc3a8a3bd9865f4f71a7d8f01d1477aa0dbf81e24eb3e13b29ee741b7e23c59d61c37751dc336cf86e8a43bfff268a83fdf1668a836df4168a9b6ac36fa538d80a6fa338b4fdf7501cec877b290e7dd3db290ef6c87d1487358f77501cf686dc4f71d83bf24e8a838df22e8a433ff900c5a13f7d90e2d0efbe9be260533c4471e8b3df4371e8efdf4b71b083de4771b03d1ea638d8468f501c6ca347290ef6c3fb29ae68c368f34cdbe23b0bec0a1167daa62b6db818a56b7fca7fe6e11efc0cc6ad365cee5f7b4d36bc856890479da0719d05f51e61eb2b9cbdd46d308de6eca5470813a705aeb5421ed7d94b4ab294befddc2e646972c8029a0f0afd6a9c4ba3246ba99eee20994cbe5b1db282e6a374eedec76d98df2b3e33e0cb8ee7b86ac47d91c2d09f91f99af4652e9d53bb937016890ff3de455853e2ddcabc6ba2a167b4f0792e087fe9d0415adf592ec06ede117cfbced865ba2b44ba46a2b9da217f314a577e79fe8f3c7fc694c9a7a89ea11e194c5a67a45dedd15113e9083457928eb4ce5fbf52e0010e3ee31be52ffb00a4e5f339be456d149fb70a39eb23f719e60a6d592b6347def20c28fee7018fd99a848c7c36e9783e375f014f37db12f25f047ca62a687e21fa646987a04f3e8964810cca67e296f64f6ff3c8c2f51d34bfd1b7790a9ab6e3552493c977b34356d0fc81daca3f3afa5cfe1f0506bba3ed93f99ce81de9cb9ce73618e5bbc3c1fb1ac29a12ef21ed3ffa6479a65c8ec2ffa03e59f665d035b09b77046d1a6397e9ae10e91a23b74da2600f0db10191b73c3bcf94c95fa89ea11e69b6a5db23b78e4e221d8186dbd24a9d652affeb626850fe75820669f9df2f13ad0ee5bf7eb94f96fd99e63800bc9037eec1af31daf7dce07a878cfc9f1ddf7f2dabbd4f76a5c37cd826a2411e758286cb1b3493a9bc8dbc0a672b77b1ed3841c8eb9a1b389e30b9ecce25421e9eb3603b58ebcc6bd9e79fe8900534a708fd6af5f95a67c7fbfa7c961534cfa07fc89e497d3aca89ff47dbed788e2bf4f923ebf3bb0e1ba4957d37743dda3e7f8b48578d7dfed954cfbaa9cfd7b27bb77b747422e90834fcff04ad3e5ffecf41fed7d9d0a0fc651fc0632cd0143d7d3eaf0fcafe52b3cf072fe48d7beef311c76bace5feb36d3caceff29aee66113731aaae7f59bbd2615d6c3dd1208f3a41c3fff703cd22d12729d8385dae71befca7258ff397893e5f8ef39708797ce37cadffdb49fbe504872ca0592df4ab31f7a0699bf21cbbc977934356d0aca3b6b897fa7494533fe9ed6ac7735ce5fa7cb6e914e6fef2dcefc8f36b9937f7cd29f11ed2e7a1cf9767caf35ac70eeaf3e5fc3074cde7e6c23663ec32dd66918ee795af72c85f8c74fb57796ebf29933eaa6757539faf6df74a1d9d403a020d8ff3fb95f0c83da5c0017ee5fa00a4e53ee006d1e7a3ffe3fd49d26ed7b4b17ce361f06b8cf66defeb1d329afa713cf5f91b850c26cd7a875c5ae5065ec81bf7e06730f6daf0fa31c073bcc0c375ad4ed0206d8e686e177d9d82cddbc5f56382d0a3cbbe7985b02564dd5a22e461bb4b79fda3e0b28ba05f975df43afdf919555b82d7064cbebd0e5941f3466ae3ef76cc0f6c24bd3d9870fe806d458575dbbc6b9fc6550ededce7a7c47b485f0a5b027cf83f41083f40b6841c7743d7c0eefa47902bdd1691ae3172cf9f28ccdd38fbedab046653266fa17af620d9125ae3f56d1e1d1d4f3a02cd268a43ffc4e370bc3fdc776d54c2dd2b70e37e2361441cdb0db2bf307afe9ddd20cbe7eeae72c8b58ae4da5061b9c0af81b0e3992b1df6b1f239f6c8a34ed0206d8e683e26daf6f4cbb1b58bf7354c88dce5c87b323e25fa4eb92762b990a781e4e1b921853a59da03d72f6439ce210b689e10fa55b0a93a35df3fb6db4dbeeb1db282e64bd4a67d85fa4694d31ad2db8f1ccf7195eb3ba13fa539b23ccf6dca7522e6cdfb5253e23d645e157d27f8b0ad82f00fa9ef947355d035cfebc9751357ba5e91ae9168363be42f46951983b1bdfa75aa673fa2beb34f09d3668f8e8e231d816603e948ebff10eb051ee000bf727d00d2721ff00b310e47ff0739eb8996fb46adf12178216fdc835f63b46f7b5fef90d1d48ffba9cfbf5ce889c7e16b48ae5e25b9c00b79e39efbb1754206573a7ccfb2966890479da041da1cd1fc45f449e9db38037d3e8f9558de0d8409347f137d3ee2816bb99087e72c40ab64af75bbec97631db280668fd0af42bbd4ad699bf6934c26df750e594173c0e1837a9960c3fc5e5d4e7a3bcaf11c57b93e9f6d3a85f151de35b7b3d9c19bfbe694780fe9f3d0e7830fef9541f8c8c30769e51a2c74cdeb5372ddc4956ebd48d748349b1cf21723ddfe55aed199329948f50cf5a81276afd4d1b1a423d0f4928e2af51f24e0e0711fca5ff6013cee03cdf15687e8f3d1ffadb77e7db46f7fa969638117f2c63df835521c7f5f2d6534f56313f5f99709197c7269959b4f2efe0710fa71fe37ac4c87ef5a97100df2a81334489b239ab3a9bc8dbceb539777a0cfe7726079d71326d0e40993ab8e2f17f2b07dc4efdcfad4651998efdf206499e29005349d42bf0a7d739792acad6c6fa1cf5feb901534e7505b7c2ef5e928a7cb486ff31dcf7195ebf3791ca530cec8731b8ff2ed77f0e63d3029f11ed2bfa0cf071f9e6f41781ef5f9b2af84ae792d0f6d66b9fd3b978b743c8655b6b7ca9e8d047ea532a17a369ffa7cadf1599f4747534847a0e17f6929fc03b895db77e40d1c3cee43f9cb3e00697344b3ccd3e7f3b91cb2bfd41c678017f2c63df8f1f7783c17216534f5e324eaf3570b19f87b0196eb3225b97cdf0b809fc188736396a8e219e893d7929e4cbe93059e1cd1f4893e19f1c0853e7932c922ff196e6451f8877d81df09298bcbe6b942f4c90a365e4149d621f345e893973a6405cd0e6a2bafa13e1765c2fbde9feb788eab5c9fcc6d9e429b9077cd196d70f0ee23ac29f11e6203a14f061fb68d10be95fa64d96f40d7c0ce73558c5da65b2bd2717fd3eb90bf185566de95e7be76533d7b2ef5c95a6d69af4747934947a0e1b674a9121ed9b60307f8191ab9ef7db2c0c7fbde6ff3f4c97c8e95eccf34c7abbe7defe0c77b02f8fc182963696da67e20eceb93573ae4d2faaf0278216fdc839fc188b58de1fe05be54c44d24b98b29e35e2a704bbb81ff05be94e210e67f082ff1e4358968a43d29f9b13df956d1bfa6df060cfc1f4cda2fd29e62fbe5edc3d82f2b853cac2bb65fd22f4fb72d36c9a15fd03c20f49bfe38a3b54bb3ee72f9987c57396405cd7ba95f7998ec13d46db65f3ee1788eab9cfdc2e5abd07ee6d96693ff0b67debd843525de43ec45d82fe08378b6173f4ef68bec63659bcf6ba7e5f622c9ff4c73df7cb943fe62a43b5e967385a64cde4ff5ec1364bf68fd2be7728f8e26918e40b39474b45a09cf2a810738c08ffb9c3a4183b439a279c263bf404eee2fb99fd79a33f1f597e0d748717cdea794b1b44793ec17a4e1f363e7883823d7a54a728117f2c63df8f1387c0ec521ccf68bebdf9e2b9470fbfe15b582304206b6c5e4bfc76ba27dcf9107cd31448332adf3f0cb11cd8f44ff9a7e1b3060bf709d2a1296958409343f15f68b7c5fe708795857bc37674eeab2e49db240f7731cb2fc4ae8779502262559878c1960bf2c71c80a9adf52bff23bb24f504e4b496fffeb788eab9cfdc2e5abb0b72ccf361bca778d8337cf3fa7c47b88bd08fb057cd88e44f87fc87e9136beec6f78fcc9d865ba15225d63b4effc9966dfb546e0917301a64cfe93ead9ff92fda2d5efacf6e8e818d21168f8ff88959a7f010e9e7f018e3a41c3e38ebdff7e3862c087fd82be9ccf8e072df7f30a6d59d9fe12fcf8df8a7c6ebd94d1d48fa70e1e08fbec97c50eb9162ac9e5fbff0cf8b1fdb298e2e43fefd9ee62fb652ced2ec8e0b2bbd87eb9d493d7d14423ebaee4c775f758aabb3a736703f60bde05f409d25ecb11cd8984c965b32d16f2b0ae403b91e88aa9c99277ca02dd2f76c8729ad0af828d5c509275485b22ed179675ef7f638f18d4cb541baea77262fb65bae339ae72f60b97af42fb99e7fe0ae5bbcac19bf7c9a7c47b485f09fb057c10cff3fe3d470cd2ca7e1fba06769e8766ec32dda5221d8fc7573ae42f46ba730bab04665326d3a89ea11e69f63b2b3d3a3a9a74049a39a423ad3951d99f0007efeb93f32f470b7c3cff7281c77e61db40f6fd9ae37ddffc0bf8f1fc0bffdb47ca68eac73bc97e992d9ed747fbf6bb46ae4b94e4022fe48d7bf033189b855c6c1bb0fdb248c469f6018b046edcb38d051916119e454a782e11785cbc35fa7ed63bae727dd562c2a3309629b0fd3d123c3c37acd13629c99937f9a2ddd99362be2e7b7ab1d05523d154628ed6d7f681df78c46cf0c83683fb94455582d1b59f4e6b0ec2d7862dad02de4617e857b87f75ed59a886f2ba84f028f4dd7923fbc98297b12daed7b53d0b35825f9170805f8e680e3c7290f6668b8dfb66b61fe49c88a6bdea9bb7e1fd1390c7356fd3461835fa51d79ca06c530d0ddad23a8f1c39a279b1b0a9db1c32238cf6af9ed257a24d042fe42ded7e2e03ee47b4ec3a9f7d5c099b722c79fbde0fe6bd2c7dde79a5ba55e07923b45bb26ef1bcd19d62be4fce5fe33d411e0da41bd0d65218cff64443c7a969d88e9becc56bbda3c977d33017cf6b3d0dbcad3222223dd45298e75b867beea25d4969e4dcd11e717f60b4efba03aff5be437d2e7a608ca2b186ccf344a8f372dd85d77a1f14755ece31a1cef37e06e88ce7e1b4f61ca10dc2fce662076fadf9065f5bbcb80a78b36dccff9aae267baa31da776d8c65abb5e9f02fdda5ba7acdb31d9b8bdcf615dbb19fa0796dd4b703a2a1e5c176d9129137d21c45f14b44de7afb75f2ed8c6982c0bdd281e933029342bd69d76c2b5609fd373b6405cd3fd3dcfd17690d08f56136e9ed7b8ee7b8cacd73f1f85d610f649ed74d50beab1dbc792f4a4abc87ecf1c01a91fcde3247e1efd2bb24bf9584ae81ddf431e8d719bb4cb758a4e36f2c5738e42f46e9caeffbbe84f71d7d99ead9f7689cae35b7ef5ba35e483a02cd22d26db34807fae5448372aa1334489b239a9f88b64461cce26cdf9a856cdcbe3d55a1f64d6b7c26dbb74b1cb282e6d754ef7e43ed97b423ccf3bf3b9ee30aeddbc8dab7bf9569df643b35d2f66da148578deddbefa89efd9ddab7d94a98567874d44c3a020dcfd1625d95e791f1fef09aab963def9beb667b1e71d01db7b948075b92db65c85427689036473413ecdcec61560792d694e32c5aab966d0cdb403c2f54ad73b63cd7ec5a375098cf2abb6ec073479061b86f1d9779f23a996850d7eb3cfc7244730cd5019db9b7be51cfbd1d4b985c736f72fe9775c57b75b5f6da4959a07bd7feb326a15f85f923d5bd765c3e26df850e5941733aadf53cc38679fd80d78d3a1dcf7195b333b87c15c68e79d7b7202b1dbc794f5c4abc87d875b033c087ed3d843b8e1ca495fd3374cddf7ca32f64ec32dd32918ef7c1af70c85f8cd295dff73d3bef7f3c8bea19ea9166bfb3c2a3a3934947f27b18cdbd7fb23f91ebaf6c63d4091ad7dcd679d446f1be08de53efdacfa475a681cf3e023fb68f9610462923af87fbf6dacd177146ae054a728117f2c63df8f15ebbf9148730db2f72ffdd58ef11840cae3d826cbf5ce2c9eb48a2411dabf3f0cb11cd32d1bfa63fde1eb05f788c5c8cdce3edbdeb11c27e9176eb7c218fcb6e9d4874c5d46419982791b240f7f31db25c2ef4ab6067b42bc93a649fa89c07665941b391fa957eb24fe458ac745e90e339ae31dc7f99e73102ca77a98337efdd4b89f790fd1bb05fe49e3fde8fb28bec17b97f10bae6f110dafa72fb0e5dfbc640b3c4217f31aacc580ffc4c996ca17ab69bec17ad7e6789474747928e40b39074d4ac8447f627c0017eaef9e523053e9e5f7eb6b05fd097f35aa8ecfb35c74c729e06f73cbf83b8058451ca68eac73f0e1a08fbec97b90eb9e629c9055ec81bf7e0c7f6cb5c8a4398ed1769d38cb5dd05195c7617db2f0b3c791d4134720e4ef2e339b8d78afe35fd31439f73cfa6b4d7783cf00661bf489b6dae908775c5fb5e15cab3dd25cb110efd82e6cd42bf0a3672bb66dde5f231f9363b6405cdbdd4afdc47f609ea36db2fef773cc755ce7ee1f2d5da9721d7f1163b78f35e8b94780fe92b61bfb8ce8943f851b25f64bf2fdb7cde1fc8d865ba79221def295fe490bf1855668e9dc7d4efa47af67eb25fe62a615ae4d1d111a423d0cc271d69ad3bc9f571e0e0b51ae0a81334bc3e0e9ac73df60be4f4cd53688df77dfd25f83552dc5cc2286534f5e371b25f3ac473b6cb9a492ead736f7c76199f6fd062c3b3290e61b65fa44d33d6761764984b78b4de47dfd9117375755160bde32ad757cd233c0afd73db68fbce05844763be4349ce3cdba5697feb286dcb7942573cd7cb6353adb64fdaf7b807bf80b932980d1ed9ced513dddc2ac18838b63bb4c602be76774115f0e63de8e82fb9bc2ab14e319af2623b4ac1de287d9f798ae065eca13f93bdac609fb6d5087e45c2c17b804073df5183b47fb5d8d89e609b679e88d39cb7e77eb518b9e767200fdb4108f3f7991a7dbfcb4e966daa6b2e48cac1e3f75a5b16f2fb4cd79c14dbdd0b45dc58af054246ee47b46c519f4d5f093b782c79fbde0fe6adb0ff20af54b7da789c2fbf4f71adfb1e49ef8a6b8e00ef09af4743373c8fa2f19e28cd8db5b9e6c6e4de519e9f3a56e868894747fcee4237bc56a6b18f4e690eabcdb5fee9faae6bef1e1ea1a3651e1df13c9efcf6b736da779eb0c9c62f13bcf7d878994753a4bb0715ed03e64be709fe9af317be76725e15f066bb95d7d5aac9d6698cf69dc367d96a6dbac3edfd025dbde6d9c6cc456edb876dcc9ea30631a3bee1db49b90eca7615f2469ac3297ebec81beb3be9bf3f6d79c63441e05ee6c074aec0947ebd69cb6bb6154b85fe5b1cb2ee3da78fc60fb36c98df9f0ed2db52c7735ce5e6cd786cadb0e730cf7b3ce577f2cc7b25614d89f790fda55873021f3edb1fe125f42ec9bdb2d075b9eff35de9e689747c76e4a50ef98b51baf2fbce86e6b30b2ea67a867aa4b95670a94747b34947a0994bba6d11e940cf737128a73a4183b439a2592dda92f4c713eef6ad45c8c6eddbe5156adfb4c64eb27d9be39015341ba9def553fb25ed88d25e2ec7735ca17d1b59fbb6ab4cfb26dba991b66fb345ba6a6cdfb6503ddb4ded5b871226df7ecb16d21168f8db7039ce063db76f789fea040defc505cdcda22d49df5e75b76fc0328f3081e6d60ab56f5a631ed9be75386405cd0ba9debd98da2fb90e6e9edfe1788e2bb46f236bdf5e5fa67d93edd448dbb71691ae1adbb7dba99edd3106f69b6c835cfbc24d5cb30d839ecf57e63d2a5aedb2ef5ceb0ec28838e8ceb53e87b132b7cb90a94ed0f0581e34f7521b58efa035e5780beded9136148ff1784eba5ad78b789dcbb566a9f52d9f6fcd92e7ad5dfb9511e6bdc90b3d799d4234f2bbc072fb80df2ffac1f4e7ca07f6268f66deff83c3ccfbcbb527d615cffb2bf4bdce350ce87e9e43968f09fd2a9c15d3a66967c8f3d3663b6405cda7a9fdff2cd911f25f07e6f9938ee7b8cad919ca6750e4d9b692ff6c769d8b9ab69dc1fb86792e95ed3d84bfe19873853ea06b3e37439ea9e04ab750a46b249ac50ef98b51baf2cbf52bb98662cae409aa674f929da1d5ef2cf6e8e814d21168785ebe527b5c81836d05e0a81334bc3f04343f107b12d097f3d939ae3d595ae75ef9fa4bb6ebe49eac7a878cbc17c7d4ff2e1bdf41695a449c91ab59492e396f887bf033183b6db885e21066fb45ee571eeb3dd5906136e1a9d4de7c176f8d7fc88e76ce4ff97bbd02ff4f702478782d5663de556b2d92dbf6b4f726cbb6467e9751e9fd9fbe310eaf9d8e37ccfc2dac6bfd7d769560748d65b5ec6a5f1b5689fd12c3f1e6fd123c47e2da2f510de5c573360a7d77699fefa98297b12d0e3d5a956f816d068c45240e9ecfb9f3e841da236dd8673fb8fe433b56df12b1fd50ee3fb45afda8ebfb2bd9a6babef773ad2982e644ab7fb9cfd7f5cd3cefa59f2fe234dfb1917c330f19c7e29bcb6ab329b578fbde0fe6ad30b6cd2bd5ad02cf53a2dd2a773e420bbd2bae394ebc27ae795ede7faef19ee8cc89e69d73a2f25b169e47ec143a5ae4d111bfbbf25f42b5d1bedf7f35d9f8458237f6b0ca3c9a22ddb13fcf6114e99ee7deb4c6b9be3640f93ba211f1f6d964d5d48ff377edc0cfb2d5da7487d9fb79ba7acdb3fd24f701f1fc3568161e3d8819f50d7b58a58dcc3603f2469ac3287eaec85b6f1da090674ce5cec707cd128129fd7a53c86bb615726da2d3212b6856906dbcca86f9fde922bd6d713cc7556e7e85c78d955e9b60ded5b036b199de25b9c6005d8f766d42ae6954e3dac46554cfb6d0f8b04509d3628f8e9a4947f21f37ae395dd0f33c13dea7bac86d13e7886687684bba5297d7ddbe014b176102cdae0ab56fe9cbea6edf5a1cb282e606aa773751fb25ed88d23e1dc7735ca17d1b59fb765b99f62de9da6bb348578deddb73a89edd4eed5ba712a6c51e1df11e7dd73f8f5ce710e139aff5698de97ddf50336ec44177dce6221d6c496e9721539da041da1cd1dc416d60bd83d694e36b260e8479ae90e7a45cf311d53a5758cd6719b8ce74926719b8e6e540732ad1c8f57dd79903a079a7e807d39f27e91bf59ccfbb8799f391f38ebe330734d6795db240f7731cb23c22f4abb08fb0a039f7c0e563f26d76c80a9ac7a8fdff10d91128275eaf78c2f11c57393b83cb5761ec98e77e457e2bc0bcf99cc894780fe9d36067800f7fdf8ff0e7c9ce90fdb3dcef6cde11f9cf0457baf9221d9f0d7d8943fe6294aefcbefdcf7ceec1e354cf9e203b43abdfb9c4a3a3534947a0e1792badbd42b23f91eb7eaebddea70a7c3cb7f555b11e85be9cf74fc9be5fa92d2bbb178a6d38f97d62bd43465e8735f57fa68defa2349d224e736fbfb4df700f7e06638f0d77521cc26cbfc875dbb1de9b06195a088fd6bc4687c0e3e2adb1e63edaef9e78ef8142ffdc3eda313aaf55688c6db4e6eab96d4f7b8f976c4b5d6b2b95dcfbe31be3f0da42c01c30bb3073bfc8731ba06ba9128cae3903adf18bafafa8c4baed70bc79dd167dbc6fddb61aca8be7c6146ca4d25ebad3042f63c3d51fa3cab79d6d338cf9240e5ecff8e93183b487dab0cf4e6b167163b94f89ed34b6dd10e6bd741af64ab9b525dedb81b6b4dcda12688eb5fa977be9586684796fc45c11a7f98e25f96fce58dbcffb236fdffbc1bc15e610b4ce7a68e7f960b45bb26ef1bed3a9f4aeb8e692f19ef07c3a74c37b3c35de13a53d7aedaef95ab95f9ce76b0b42470b3d3ae277579e35aab5775269bf61fb68f71bf6081d2df2e8a8dc7e4325594adf3b6bfca392e74a4772f66a51e868894747c39dbdaa35cfca7385c568dff565cdf9245f1fa0fcadc68878fb6cf26ab2e3f89c12e067d96a6dba43edfd1c5dbde6d97e2eb74e049a4b8f19c48cfa86bd94728cc43623f2469a43297eb6c81beb6d0aefcf103b7682c0bdc4816995c0a4506fda35db8ac542ff3d0e59f7fe2f98c646eb6d98df9f99a4b71d8ee7b8cacd63f2bc81c27e97527dbe947016890ff35e4e5853e23de4ec22ac01820fe27314de4eef923c8709ba0676d3c7608f126397e99a45ba46a259ea90bf18a52bbfdcfbb44c603665b291ead90e9a1fd0da6bb4d4a3233e9709342da4db1e914e9ec56668504e758206697344739d684b14c64acef6ad47c8c6eddb4d156adfb4f7c9cabde22c2b686ea57af73c6abfa41d619ebfdaf11c5768df46d6bebdaa4cfb26dba991b66f1d225d35b66f2fa47af66a6adf662a615aead1510fe90834f349b7720e01f4dcbec9bde23d221fb60def146d8982bdea6cdf8085bf9d06cd9b2ad4be698d7964fb36d3212b68eea17af7766abf50663c2fffa8e339aed0be8dac7d7ba44cfb26dba991b66f3d225d35b66ff7533d7b740cec37d90671fbb690742be7ff405fce7e93f3816cbf7d58b4255aeb59b27d93fbdbb97dfb5885da37ad7d553efb8d6505cda7a9de7d96daafbdff1321bd3de9788e2bb46f236bdfbe51a67d93edd448dbb7f9225d35b66f4f503d7b720cec37d906b9fe236fe2b0ef91f77a220def89d46a977ddfc2741246c44177dce6221de602cb9dc972a8c887d7c67e4c6d60bd83d694e32f0e1c08f35a3faf29bbd613ab75adbf9acffb810ce5cefb71adab83e634a2417d28772e0f68fe20fac1f4d73907be8519cd9aed9f8759b395fb065857bc66ab358e92b240f7cd0e59fe2ef4abf0bd95ea388acbc7e4dbe19015347ba8fd8f260d8479df09ef373ad4f11c57393b83cb57612ffe90ffb34b3b9279f3ff4152e23de4bb0bd819f21c1afec6b971d220ad5c8f86aecb9d09ee4a27cfbae5b3f71738e42f4695e91b79adfe80498361d423cd7e67814747a7918e40c3eb8e5af6835ccf050efe6e56fe8fc6b5b70f3493ac0eb19fccf59d896b3fadd6b7a3befe92c7ad723fed70fb281b08e34c4ad323e28c5c5ae717c87511dc839fc138dd867b280e61b65fe4becbb1fe86073274121eadfadf25f0b8782be8a2c07ac755aeaf523e43bb30da3516de6ba2b1aea4b5d782dbf6b4bf85916d8d6b6f4c25f7eefbc638e5fe7b53ed980d1ed966f0d8b1b34a30bac6b25a76b5af0dabc47eb0e178f37e30f43dbefd60d5505e3c67a3d07797bed1385df032b6c5fc49aa7c0b6c33602c2271e488e65b64172fb2619ffdd021e234f71a0cb7ff9ded07b62910e66f3434fad19a68dfef7d659bcaeb0b751e39787d618db0a9db1c3223cc7b2e678b38cd770cbc90b76b0e0a32723f329676ddfec8dbf77e306f85b16d5ea96e0d393f5c9e4bc77b6341b38dde15d71ca73c8781e7a2f9db218df744674e34ef9c13759dc50a9a5d4247f33d3ae277579e135d1bedfbed6e938d976bbc38ef58e6d114e98efd796f7791ee79ee4d6b9ceb6b0394bf011d116f9f4d564dfd389f3307fc2c5bad4dd768ef9b75f59a67fba9dcfc35685e46f3a9a86fd8a32f6d64b6199037cf4f21be45e4adb90ec0982608dcf31d985e253069ecabd56c2be4dac47487aca0793dd9c66fa0b507ae77787ebfe339ae72f32b3c6eacf4da04f3ae86b5897794599b00a6d1ae4d748874d5b8367117d5b3fb697cd8a384698147475da423d0f0fa809cd3053dcf33e17daa8bdc36718e68de23da9262faf23adb37b6c98109348f54a87d5390d5d9bef5386405cd6354ef3e44ed97b4234afb741ccf7185f66d64eddbe7cbb46fb29d1a69fbd625d25563fbf638d5b327a87d9bae8469814747bc570a34fcdf0dd7b97778ce6b7d5a637adff9178c1b71d01db7b948075b92db65c8542768903647344f521b58efa035e5f800edf19267f1b10dc4f311d53a5758cde7d0b8ce1094e7d0b8e6e540733ad1c8f57dd77931a0794af483e9cf93f48d7acee7df8699f391f38ebef36234d6795db240f71d0e597e27f4abb08fb0a039f7c0e563f2ed72c80a9a3f51fbff17b223504ebc5e71c0e47d9fe32a676770f96afce78dfb15f92d14f3e66f2252e23da44f839d013e7c360bc2b593076965ff2cbfe730ef883c13dc956eb648c7fb8de739e42f46e9caeffbcf229f59f357aa67a8479afdce3c8f8e4e271d8186e7adb4f60ac9fe44aefbf1dc569da071cd6dd55b1d623d0a7d39ef9f927dbf525b56762f14db70f2fbeb7a878cbc0e6beaff45369ee7488b224ef39b04e425f3063f8371163d471cc26cbf4c17719af54dda9db8e7bd6990613ae1d1b2fbe5b70e2ede1a6beeac775ce5fa2ae533b40ba31da3f35a85c6d8466bae9edbf6b4f778c9b6d4b5b652c9bd3fc39dc7341e311b3cb2cde0b1e3f42ac1e81acb6ad9d5be36ac12eb89c3f1e6f544f0f5ad27564379f19c8d42df5ddae37586e0551a1b4c56e55b609b016311892347345f983c483bcb867df64397881bcbfd336c3fb04d8130eff1d21ad3fbd63c78cf81fc87886bcd033497089bbacd2133c268fff87f0a95681347f21f0bc8c8fdc858da75fb236fdffbc1bc15c6b679cd3d93183ba2dd92758bf743aea777c535c729bf2de66f6178efa1c67b52c97d70721f33cf236e163a9aebd111bfbbd00d686ba37df7fe374543f772e139f678c93c9a22ddb13fcf6114e99ee7deb4c6b9be3640790ff98878fb6cb26aeac7f9fc04d7d904b5365d83bdefd0d56b9eeda772f3d7a0b995e65351dfb0c74bdac86c33200ffee61cf19d226fbd7580f621e7ce4e10b8e73a30bd40604abfdeb4e735db0ab93631cb212b686e23dbf8a5b4f680fa7011e9ed2ec7735ce5e65778dc58e9b509e65d0d6b136f2cb336015d8f766d42ee57acc6b58957503dbb8bc68745254cf33c3a9a493a020def259825d2c933f00c0dcaa94ed0206d8e68ee116d49fab6b2bb7d9b2564e3f6ed1d156adfb4c605b27d2b3a6405cd8354ef1ea2f64bda11a57d3a8ee7b842fb36b2f6ed2365da37d94e8db47d9b29d25563fbf63eaa678f53fb769112a6791e1dcd221d816636c5c9b31bea290daff5159570cbf655aeeb35521c74c76d2e68614b72bb2ccf576c10f9f0f98a4f501b58efa035e57825edf12ada789e9372cd4754eb5c61357fc7ea3a1b437ec7ea9a9703cd194483fa50ee7b53d07c57f483e9cf93f48d7acee787c3ccf9c87947dff7a65adf564b59a0fb2e872c3f13fa55d84758a8c47e12791e32cb0a9a5f51fbff6bb223f8bdc2f3bf3a9ee32a676770f96afc7f8cfb1579e61cf3e673bd53e23da44f839d21bfafe4bdfbff457686ec9f81a9dc5977ae74f20ca746a299e390bf98b2fcbefdcffccdeb6fa99efd95ec0cad7e678e474767908e5cfffd2c2ae191f3816750d85cdce7d4091a5e1b04cd3fc47a14fa72de3fe55a8fd7da13edeb2fd98693ebf1c3adc3f21eaf8b29cd05224eb3dcc00b795f40616084dd7701c521ccf6cb4c116770cf50c2ed9b7f9e4118c18ff7ab21ccf6cb0c4f5e87108dfc7e4cf2e3efc78e9e32e0ebcd2df439cf5301161e6f83660a61e2b4c07581908775c5e38f0b529765e05b38290b747f81439693847e15be476c579275c8fe44390fccb282e6b429837a39c386eba99c785cd4e1788eab9cfdc2e5abd05fe5b9fd94df3a326ffeef524abcf7398781c72bbca68270fb94415a39ae81ae796c27ed7e57ba19221d9f4bd9e590bf18a52bbfefcc43fefef44caa67a8479afd4e97474787908ee4dcb0c1334b098fec4f8003fc5cf3cb87087c3cbf7c2eb5514616f4e590b33edab7ef576acb5a5df334726f796334744e0c18a58ca67e9c543710e6efc0a6529a0e11a769070f77de107f6b35dc3776aeb5e96e25dcbe79a36ec20819caed31aba13432af7aa291df57487edcbf2e55ef5f07ec17fe6eb34858f89c13d0ac10f68bdce3df21e4615df1f840613f5e974b16e8bec321cb5a75fb30dfa524eb90ef5de4bf625956d06ca07ea58fec139413f741bb1ccf7195b35fb87c15c61b25fbe55cc2598cf6b5b50deff3086b4abc5b9937ec17f0417c8ec23bc97e011df4015db38d7f8e0d337699ae5ba46b249a731cf217a374e597e3b31902b32993cd54cf7691fda2d5ef9ce3d1513de908346ce369ed8d95fd0970b8ce78aa13343c6f0a9a9b85fd82be9ce5947dbfe6dab26fef2ff8b14dcdf32f5246533f6e9e301036f55f9e6569e85b459c912baf241778216fdc839fc1087ba495e2103e9370378b38837baa126ef94d0feea71246c8e03a23e02cebd7501a99d7c14423e70e253f1ec3bd46f4afe9f7837d1daebd1dc0c2fd2068ee10f68b1c93b50a795857bc9720fdf2ec2bb86439d8a15fd0bc49e837fd36b6afa05977e55eca824356d0dc43fdcadbc93e41dd6e23bd3dea788e6ba4fb5414c61b79d7fc5ab78337efb74a89f7107b11f68bfc2f04db8b8f90fd226d7ce8ba9c8def4a9717e95cdff769f65d727cd62d3097ce57a37af628d92fad4a98ba3c3a3a987424cf893478da94f014041ee0e071aedc43001aa4e575df8f08fb057d39e4f4fdef4dcb5ef4f5973c2788b856c2286534f5e328b25f90661aa56911719af68bcf2e63fb05edaaebbc70b65fa44d33311afa0d413145dc3ebbab40182183cbee62fba5e0c9eb20a2413daef3f0cb11cdd744ff9afe3b3760bfb4dbbcd027004b1b6102cd3785fd8278e06a11f2b0ae40ab34c75d70c902ddb73864f9bed06fbb0226cdf97c2e1f93ef5487aca0f931f52b3f25fb04e5c4678ffcc1f11c5739fb85cb576bfd88c76f45e2c3bcbb096b4abcf7f9c68bfb731e3723fc7bb25f64bf2fdb7c9e8766ec325d41a46b249a0e87fcc5a832eb47e067cae429aa677f20fb45abdfe9f0e8e820d211685a49475af32f720c0b1c3cff021c758286c71da0f9abb05fd097f37a0568b99f5768cbcaf697e0d718ed3b7751ef90d1d48f9b6c63c2b6c1d994669a88d36c4bc10b79e39e6d156963355098ed97bc88d3b4dff302b7cb5671d96208b3fdd2eac96b22d1a0ded579f8e588a6e1d8011ffd6bfa36dc80fdc263ef6254dea63a9c30715ae09a26e4615df1790ed3529765689f0e59a0fb690e592609fd6a8cc93465e5f231f9363b6405cdf1c70eeae5441be6b68fdb9566c7735ce5ec17e5f33a9cdf81b9fe0725bf254f81f790fe1bf68beb1c1084cf3e769056ce11c8f94df38ea0fd77fd2303e95a453a9e5b6877c85f8c746d0579aebc299393a99ea11e69f63bed1e1d4d241d8186db632dfb45f627c0c1f60bcabf4ed0206d8e683aa88d32b2a02fe7b90dd9f76bce2f49fb0cf7e0c76b5cbc1624652cd58f9a419d0cb98a2902ae8d06163af1d2d6dafc9be8fe02f1fc42f17c8eb89f27ee1788fb4bc4fd6271bf54dc5f2aee5788fb55e27e8db85f2beed789fb5e71bf51dcf78bfbcde27eabb8bf52dc5f25ee7788fb6bc4fd2e717fadb8bf5edcdf28ee6f16f7cf11f7b78afbe789fb1788fb1789fb9788fbdbc5fdcbc4fd2bc4fdebc4fd1de2fe4e717f97b87f93b87f8bb87f9bb8bf57dcdf27eeef17f7ef12f70f8afb87c4fd7bc5fdc3e2fe5171ff0171ff2171ffb8b8ffb8b8ff94b8ffacb87f42dc7f51dc7f59dc7f4ddc3f29eebf2deebf27ee7f28ee7f2cee7f26ee7f2feeff20eeff2aee4d80ef6bc57d4edcd7d97bbe6aad5fb47e5bbeb3bdbdbfabd0dfdad6da9b2ff46ce8eec8b7776ce8ec6eed6eede8eee82b74b7b5f577b77777f56ce8e9caf7b4b6b7f5b76eeae869db641bcfa628bd76f8c2f4f2ca8f17997f5f2199f34fef6afd438afa3bb426fdbefbd011d4f5fcd3bb861cd2fc7475303dd229f79a94653e270599f385aeaeee9efe1ecdb2e94eb16c668d93b2393f1a1fede5841465be609cc85c93a2cce76550e673a3cabc834f57e6c352e8cbfafbbabbbb3a5bbb0d363300fe366135072d1a1ec69f61ef6b843f331a3cf8dcf8a75a7f82f59bacdf6dfd6759ff22eb5f6cfdd9d69f63fdb9d69f67fdf9d65f60fd85d6bfc4fa8bacbfd8fa4bacbfd4facbac7fa9f5975b7f85f5575a7f95f5575b7f8df52fb3fe5aeb5f6efd75d65f6ffd5eeb6fb0fe46ebf759bfdffa9bacbfd9fa5bacbfd5fa5758ff4aeb6fb3fe55d6df6efd1dd6bfdafad7587fa7f577597fb7f5afb5fe75d6bfdefa3758ff46ebdf64fd9badff6ceb3fc7fab758ff56eb3fd7facfb3fef3adff02ebbfd0fa2fb2fe8badff12ebdf66fddbadff52ebbfccfa2fb7fe2bacff4aebbfcafaafb6fe6bacff5aebbfcefaafb7fe1dd67f83f5efb4fe1bad7f97f5efb6fe9bacff66ebbfc5fa6fb5fedbac7f8ff5efb5fedbad7f9ff5df61fdfbadff4eebbfcbfa0f58ff41ebbfdbfa0f59ff3dd67faff5df67fd87adff88f51fb5fefbadff4fd6ff80f51fb3fe07adff21eb7fd8fa1fb1fee3d6ffa8f53f66fd8f5bff13d6ffa4f53f65fd4f5bff33d6ffacf53f67fdcf5bff09ebffb3f5bf60fd2f5aff5facff25eb7fd9fa5fb1fe57adff35eb7fddfadfb0fe93d6ffa6f5bf65fd6f5bff3bd6ffaef5bf67fdef5bff07d6ffa1f57f64fd7fb5fe8fadff13ebffd4fa3fb3fecfadff94f57f61fd5f5aff57d6ff37ebffdafaff6efddf58ffb7d6ff0febffcefa4dd6ff83f5ffd3fa7fb4fe9facff67ebffc5faffcffaff65fdbf5aff6fd6ffbbf5ffdbfaff63fdffb5feff591fee1fd68f6c3f5163fd5aeb1f60fd9cf52758bfcefa075a7fa2f50fb2fec1d6afb7fe21d66fb07ea3f58f88dde1e858ed95b67dcf63c6a7db671fa130fe3c82c69f69dbf926df6744e9db2e47d654c6aecc3fbdab354d998f1a2732a739d770f43891b93645998f1927321f90a2cc93c689ccb914659e3c4e649e90a2cc53c689cc7529ca7cec3891f9f414653e6e9cc87c6a8a321f9f41994fc8a0cc276650e693c689cc47a638d66aca60399f9c41994fc9a0cca76650e6d33228f3e91994f98c0ccafc8c0ccafccc0cca7c6606653e2b83324fcda0cc676750e6e60cca3c2d8332b76450e67c06656ecda0cc850ccadc964199db332873470665eecca0cc5d1994b93b8332f76450e6e91994f99c0cca3c2383329f9b4199cfcba0cc333328733183329f9f41992fc8a0cc176650e6591994f9591994f9a20cca7c7106659e9d4199e76450e6b91994795e06659e9f4199176450e6851994f9920ccabc2883322fcea0cc4b3228f3d20ccabc2c83325f9a4199976750e6151994796506655e954199576750e6351994f9b20ccabc3683325f9e4199d76550e6f51994b93783326fc8a0cc1b3328735f0665eecfa0cc9b3228f3e60ccabc2583326fcda0cc576450e62b3328f3b60cca7c550665de9e4199776450e6ab3328f335199479670665de954199776750e66b3328f3751994f9fa0cca7c430665be318332df9441996fcea0cccfcea0cccfc9a0ccb76450e65b3328f3733328f3f33228f3f33328f30b3228f30b3328f38b3228f38b3328f34b3228f36d19fc1fdded192ce7978e1399d3fccfe6cb3258ce2fcfa0ccafc8a0ccafcca0ccafcaa0ccafcea0ccafc9a0ccafcda0ccafcba0ccafcfa0cc776450e6376450e63b3328f31b3328f35d1994f9ee0ccafca60ccafce60ccafc960ccafcd60ccafcb60cca7c4f0665be378332bf3d8332df974199df914199efcfa0ccefcca0ccefcaa0cc0f6450e6073328f3bb3328f3431994f93d1994f9bd1994f97d1994f9e10ccafc4806657e348332bf3f8332ff530665fe4006657e2c83327f3083327f2883327f789cc87c788afb7a3f92c1727e3c83327f3483327f2c83327f3c83327f2283327f3283327f2a83327f3a83327f2683327f3683327f6e9cc8dc94a2cc9f1f27321f91e218e3890cd6ed7fcea0cc5fc8a0cc5fcca0ccff924199bf944199bf3c4e643e304599bf324e649e98a2cc5f1d27321f94a2cc5f1b27321f9ca2cc5f1f2732d7a728f337c689cc87a428f393e344e6861465fee63891b9314599bf355ecea14951e66f8f13990f4b51e6ef8c9775c91465feee7899274951e6ef8d13998f4c51e6ef8f13998f4a51e61f8c13998f4e51e61f8e13998f4951e61f8d139927a528f3bf8e139927a728f38fc789cc535294f927e344e6635394f9a7e344e6e35294f967e344e6e35394f9e7e344e6135294f9a97122f38929cafc8b7122f34929cafccb146536e7081f60f33a95e4afb13a30cf72b19b10bbbad899797a336f6de671cdbca699e733f35e661ec8cc8b987902336e36e34833ae32e30c63771b3bd4d865c64e31fdb6e9c74cbb6eda39f3de9bf7c0d40ba3a7a6d89d1cbb5308cf93d63f2a067674ec8e89dda4d84d8edd94d81d1bbbe362777cec4e88dd89b13b29764db13b3976a7c4eed4d89d16bbd3637746ec9e11bb67c6eeccd89d15bba9b13b3b76cdb19b16bb96d8190599c3960bb16b8b5d7bec3a62d719bbaed875c7ae2776d363774eec66c4eedcd89d17bb99a69c62777eec2e88dd85b19b15bb67c5eea2d85d1cbbd9b19b13bbb9b19b17bbf9b15b10bb85b1bb24768b62b738764b62b73476cb627769ec96c76e45ec56c66e55ec56c76e4dec2e8bdddad85d1ebb75b15b1fbbded86d889df93fbcf95fbaf97fb8f99fb6f9bfb4f9dfb2f9ffb0f91faff93fadf95fabf97fa9f99fa7f9bfa5f9dfa3f9ffa1f91fa0f93f9ef95f9cf97f9af99f98f9bf96f9df94f9ff92f91f91f93f8ff95f8df97f8bf99f89f9bf87f9df85f9ff83f91f82f93f80392fdf9c1f6fce5337e78b9bf3b6cdf9d3e63c66733eb139afd79c5f6bce7335e79b9af33ecdf997e63c48733ea2392fd09c9f67ce9333e7ab99f3c6ccf95be63c2a733e9339afc89cdf63ceb331e7bb98f34eccf91fe63c0c733e84392fc19c1f60bea737df979befadcdf7c7e67b5cf37daaf95ed37cbf68bee733dfb799efbdccf74fe67b20f37d8cf95ec47c3f61be2730fbebcd7e73b3ffdaec4736fb73cd7e55b37fd3ec6734fbfbcc7e37b3ffcbec8732fb83cc7e19b37fc4eca730fb0bcc7abb597f36ebb1667dd2acd799f52bb39e63d637cc7cbf99ff36f3c1667ed4cc179af933339f64e657cc7c83197f9bf1a8199f99f18ab1df8d3d6bec3b63ef98fedff487a67f30eda5693f7e42efd6e1d63fcefa1b7bb76d6bdabda3a977d7aefe9dbbd75dd57bc3ba0d5b77afdbb5f5a6fec8bec211bd9e73b66fddbdb577dbd69b7a776fddb1bd694befae2d4d7d3bfa77356ddfb1bbe9aadedd1bb744f6c52e35583255ffcea6debebe9dfdbb76356d1d48b37b4b7fd3c61ddb77efecddb8bba9afffea6d3b6eecdf69d25c67d31e6ffddeddbbfbafba7a77096b5f5fd3f55b776f69da715dffce4ddb765c6f9e3f6f14f4b14ea2d32c9d799193a49b6fd34db1f7e7efdcd97b63d3d6ed7dfd3734edb87677d38e4d4d1b765cbbbd6f1727ba2d21b3bb9230bb2f49a253262443787bc274774d4800f29e2489de9524d1076ca211bc2e9cec2349787d3649a2af2449f4dd24897e9324d17f26ac16cd75c9d215eb1280bc3821b32f1c942c5dc3c1c9d25d7e7002e1362564766d1266372764f68184e9fe98305dae3e8170f5f5c9984d4ac2ec8484cc1e4a98eef709d39516c213a4bb2161ba0f1f9240999f4c92e8cb4912fd23a158d31a92a5bb2b61baef372410eea74912fd2e49a23f2749f47f4912e51a13246a4c92e8e824894e4b92e8ac2489f24912752649342349a23936d1280db1054978ed4892e83a9b68b46fe2f39330bb2d21b30f88744bfa7bfbe23159dfd6bed2606c677cdb6414dbd7bbbb97d39d7468b2740f1d9a0ce7c3872650ca6349127d3321c2a79230fbf724890e3c2c19c24909d31d77580290272749343321c24b12a65b9a04e4aa2489ae4f88f0b684e95e9e04e46b9324fa6842849f4cc2ecf349123d9510e19f13a6fb6b1290ff9724d171872743383561ba96c31380ec4892686942841b9330db9a24d14b12227c4bc274f72601f9ae24893e9f10e10f13a6fb491290bf4c92e8802392219c9230dd09472400796a9244e72744f8a284e9de9004e47d36d1284df60792f0fab84d74f2be825d75edb6dd5bafde76a35fba4f27e1f8e384aafc791266b92393313b3a61ba2947260079529244e72644b83461ba154940ae4d92e8e684085f9330dd1d4940be2949a28f2444587354b274471c9500e49424899a9224eab68912b53d3392705c9550916b9330bb2921b35b9230bb2721b34713a67b2c09c88f2649f4fd84084f383a59ba69472700d99124d1029b2851fd5f9c84e3f6843ad99984d9eb1332bb3f61ba0793807c3849a2af244438e59864e9ce3a2601c8d62489ba93249a9924d1329b2851e55f9984e3b509b57f6312666f48c8ecee24cc3e9490d9479330fbd784cc7e9f30dd9f9280fc5b9244c74c4a867075c274574e4a00726792442fb58912bd6caf4cc2f1a1843a793809b36f2464f6f384e97e9504e47f244974f0e4640817264cb76e7202909b9224bac5264a54259f9f84e3db12eae4be24cc3e9f90d97712a6fb4112903f4d92684f4284474d49966ef29404204f4c92684642844b12a65b9e04e4654912dd9410e1ab13a67b7d1290772749f4e18408bf9a30dd9349407e2f49a2ff4a88f0906393a53becd804208f4992a87d1408a3ff0f6b53bb893d910500>, + "metadataHash": Fr<0x1eef7f2eaafa09e24b0475a918bd7388c4dec305145849f5f84d1b822202b944>, + "selector": Selector<0x038cda46>, + "vkHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + "privateFunctionTreeLeafIndex": 0, + "privateFunctionTreeSiblingPath": [ + Fr<0x0583aed5d42e43d977274df1e4536a029a27c2f443bd96eef4162f7f5d7d0b76>, + Fr<0x159e0bdd29fcc7efb79fdb56480e4cac622d6d71755adb98c7c614af8d76a645>, + Fr<0x19e9d55f327e3c96dd42e60a81a783b0bb968d074ee638d542d17f8a3a0b6990>, + Fr<0x06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d>, + Fr<0x03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa0>, + ], + "unconstrainedFunctionsArtifactTreeRoot": Fr<0x0c3d79f3431c5bef8abf01dcf84cb2c64d136171adca23e40d20ed1c64951817>, +} +`; diff --git a/yarn-project/circuits.js/src/contract/events/__snapshots__/unconstrained_function_broadcasted_event.test.ts.snap b/yarn-project/circuits.js/src/contract/events/__snapshots__/unconstrained_function_broadcasted_event.test.ts.snap new file mode 100644 index 000000000000..364f89241257 --- /dev/null +++ b/yarn-project/circuits.js/src/contract/events/__snapshots__/unconstrained_function_broadcasted_event.test.ts.snap @@ -0,0 +1,22 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`UnconstrainedFunctionBroadcastedEvent parses an event as emitted by the ContractClassRegisterer 1`] = ` +UnconstrainedFunctionBroadcastedEvent { + "artifactFunctionTreeLeafIndex": 1, + "artifactFunctionTreeSiblingPath": [ + Fr<0x14d546778272b5884f661b57d610768a394485f812373af30601825169a4a210>, + Fr<0x2e833be78dd8da68d42339f2ac9846870012b4a95faa9204b3c51927e3fa7905>, + Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + ], + "artifactMetadataHash": Fr<0x229d43c7daac528d0aefd72bee59385d7e9ff06ea477b673389e1f65168cba9f>, + "contractClassId": Fr<0x26222cd450fe6beecf6cbe6495e118412940ee0da5744629dabcaf010a2a4e38>, + "privateFunctionsArtifactTreeRoot": Fr<0x27a5a9e364417f0f1526bcd44836d603e8b7005b517c6861e512c01d80582254>, + "unconstrainedFunction": BroadcastedUnconstrainedFunction { + "bytecode": Buffer<0x1f8b08000000000000ffed9d079c1445fafe671758c2b0b3e41c1658605960d9444e4b306226a98082028aa22841444444444c803947cc395d3e2f79775ece5ece39e79cbcff6f86f79187b26687d99bda7bf05ff3f9c0d67ca7baeb5b6f7755cfdbd3d35394d8f728b27fe9472b2af303acd1fed6fc778fda02aeaba6c8f1ec36715fb91df1c642b5d7505357925e49eb03e38247f2fffe15e389d569fb7fff4ae8f522e3a8d79918d6d76effe28573ffbfb8a7db6fe538bb7d68a4726b8fcfeb85f3a949910fb75512a8ef6d1207df7738a46839766c1bc8b1240fc7b6e458e2716c17c8b16d1e8eed3c3ee589c2ee436d3d6d7508d4f7f68983ef7b078f4f5181fbdeded356c7407d4f260ebeef7048d172ec581ac8b1631e8ea5e4d891dcf03715c8b1340fc714fdc5723cc6cb0239a6f2702c23c714b9e16fa7408e6579387622472cc771ec5c78c7ba24b57b308e9dc9a74b209fce79f874219fae817cbae4e1d3957cba15de27b34f75cdc3070e295a8ef7a9ee811cbbe5e1d89d1cbb911bfef608e4d83d0fc71ee488e5388e3d0339f6c8c3b12739f62037fced15c8b1671e8ebdc811cb711c7b0772ec9587636f72ec456ef8db279063ef3c1cfb902396e338f60de4d8270fc7bee4d887dcf0b75f20c7be7938f623472cc771ec1fc8b15f1e8efdc9b19fc7714020c7fe79380e20c7fe1ec781811c07e4e138901c07781ccb03390eccc3b19c1c077a1c0705722ccfc3711039967b1c0707721c9487e360721ce4711c12c871701e8e43c871b0c7b12290e3903c1c2bc87188c7716820c78a3c1c87926385c7715820c7a179380e23c7a11ec7e1811c87e5e1389c1c87791c2b03390ecfc3b1921c87931bfe8e08e4589987e30872acf4385605721c91876315396239ded6230bef98c9a5abf2701c493ea30aef9389d9c83c7c4685f5c99c2b1de969abbaf06d65b6c5e8c4c1f7bd9a7cc614de27b32daaf3f081438a96e398d514de3113b3317938d6904f6de17d3231abc9c3a7966256e389595de11d3331abcdc3b18e7cea0bef9389595d1e3ef514b33a4fcc1a0aef9889597d1e8e0de433b6f03e999835e4e1339662d6e089d9b8c23b666236360fc771e433bef03e99988dcbc3673cc56c9c2766130aef9889d9f83c1c2790cfc440319b9087cf448ad9044fcc2615de3113b38979384e229fc985f7c9c46c521e3e932966933c319b5278c74ccc26e7e138857ca616de2713b32979f84ca5984df1c46c5ae11d33319b9a87e334f2995e789f4ccca6e5e1339d6236cd13b3c6408ed3f3706c24472cc739d08c408e8d7938ce20c7468fe3cc408e33f2709c498e33c80d7f6705729c9987e32c72c4721cc7d98577cc8ce1597938ce269fc302f9cccec3e730f2393c90cf6179f81c4e3e4714de27b34f1d9e870f1c52b41cef534706723c220fc723c9f10872c3dfa302391e9987e351e488e5388e4707723c2a0fc7a3c9f12872c3df39811c8fcec3710e3962398ee331811ce7e4e1780c39ce2137fc3d3690e33179381e4b8e588ee3785c20c763f3703c8e1c8f2537fc3d3e90e37179381e4f8e588ee3784220c7e3f3703c811c8ff7389e18c8f1843c1c4f24c7133c8e2705723c310fc793c8f1448fe3dc408e27e5e138971c4ff238ce0be438370fc779e438d7e3383f90e3bc3c1ce793e33c8fe382408ef3f3705c408ef33d8e0b03392ec8c37121392ef0389e1cc871611e8e2793e3428fe329811c4fcec3f114723c99dcf0f7d4408ea7e4e1782a396239feaec1a2408ea7e6e1b8881c4ff5382e0ee4b8280fc7c5e4b888dcf0774920c7c579382e21472cc763e6b4408e4bf2703c8d1c97901bfe9e1ec8f1b43c1c4f27472cc7715c5a78c7cc3989d3f3705c4a3ecb02f92ccdc36719f99c11c867591e3e6790cf9985f7c9ec5367e4e10387142dc7fbd4f2408e67e6e1b89c1ccf2437fc5d11c871791e8e2bc811cb711c5706725c9187e34a725c416ef87b5620c79579389e458e588ee3787620c7b3f2703c9b1ccf2237fc5d15c8f1ec3c1c57912396e3389e13c871551e8ee790e32a72c3df7303399e9387e3b9e488e5388eab03399e9b87e36a723cd7e3785e20c7d579389e478eab3d8ee707723c2f0fc7f3c9f13c8fe39a408ee7e7e1b8861ccff7385e10c8714d1e8e1790e31a8fe385811c2fc8c3f14272bcc0e3b83690e3857938ae25c70b3d8eeb0239aecdc3711d39ae2537fc5d1fc8715d1e8eebc9719dc7714320c7f579386e20c7f51ec78b02396ec8c3f12272c472bc3f6e2cbc6326bfba280fc78de47371e17d3231db9887cfc514332cc7d7fd6c2abc63266617e7e1b8897c2e29bc4f26669bf2f0b98462b6c913b3cd8577ccc4ec923c1c3793cfa585f7c9c46c731e3e9752cc367b62b6a5f08e99985d9a87e316f2b9acf03e99986dc9c3e7328ad9164fccb616de3113b3cbf270dc4a3e9717de2713b3ad79f85c9ed81fb3ad9e986d2bbc63266697e7e1b88d7cae28bc4f2666dbf2f0b98262b6cd13b3ed8577ccc4ec8a3c1cb793cf9585f7c9c46c7b1e3e5752ccb67b62b6a3f08e99985d9987e30ef2b9aaf03e9998edc8c3e72a8ad90e4fcc7616de3113b3abf270dc493e5717de2713b39d79f85c4d31dbe989d935811cafcec3f11a72c472fcbefbda408ed7e4e1782d395e436ef87b5d20c76bf370bc8e1cb11cc7f1fac23b66c6c77579385e4f3ebb02f95c9f87cf2ef2d91dc867571e3ebbc9674fe17d32fbd4ee3c7ce090a2e5789fba2190e39e3c1c6f20c73de486bf370672bc210fc71bc911cb711c6f0ae478631e8e3791e38de486bf370772bc290fc79bc911cb711c6f09e478731e8eb790e3cde486bfb70672bc250fc75bc911cb711c6f0be4786b1e8eb791e3ade486bfb70772bc2d0fc7dbc911cb711cef08e4787b1e8e7790e3ed1ec73b0339de9187e39de47887c7f1ae408e77e6e1781739dee971bc3b90e35d7938de4d8e77791cef09e478771e8ef790e3dd1ec77b0339de9387e3bde488e5f8dac8fb0239de9b87e37de488e5388ef70772bc2f0fc7fbc9f13e8fe303811cefcfc3f10172bcdfe3f86020c707f2707c901c1ff038ee0de4f8601e8e7bc9f1418fe3c38577cce4577bf3707c987c1e2abc4f6da07ed6a4d7fb88adab80bf77519b8ed5a34eacf63ab14a519d47287e8f06885f11b58b75e339dacbd7b958c03950db75e9fbc6b7a7fe737b09c7eb31fbdb86786b8ae9e3c48aa87e07e2a873ae05b593b5f54480be25c921419efc68a4f213d4f7c70bef531ba89f99df0b7ad2e9d3634e9f525487e7d42703f4b388dac5baf1fc49da0e879a73da07d7fac33549f54e1771047b9c7c9e2abc4f5dd2f1493f9a1a5f4f058e4fa07e66c6d7d3097fdc9fa2b8a30eefab4f07e86711b58b75e3f9d3b41d0e35e7b4cf522bc33549f5968a38823d493ecf14dea72ee9f8a41f4d8daf6702c727503f33e3ebd9843feecf50dc5187f7d56703f4b388dac5baf1fc59da0e879a73da679995e19aa47acb441cc19e269fe70aefd390747cd28fa6c6d77381e313a89f99f1f57cc21ff7e728eea8c3fbeaf301fa5944ed62dd78fe3c6d87e81c9d7dce691f5cf30cd724d5bb48c411ec59f279a1e03e0d3549c727fd686a1e7b21707cc2f473df3cf662c21ff71728eea8c3fbea8b01fa5944ed62dd78fe226d877c9cdb1d82ce31ce31ced99c639c639cb339c738c73867738e718e71cee61ce31ce39ccd39c639c6399b738c738c7336e718e718e76cce31ce31ced99c639c639cb339c738c73867738e718e71cee61ce31ce39ccd39c639c6399b738c738c7336e718e718e76cce31ce31ced99c639c639cb339c738c73867738e718e71cee61ce3dc3ce7b40fee5b0dd724d5bb58c411ec79f279a9f03e0d49c727fd28729e3752f9a5c0f109d4cfcc75ef6f4bf8e3fe12c51d75787cbd2d403f8ba85dac1bcfdf46db211fe77687a0738c73f39cd33eb8973c5c9354ef121147303e06bcbdf03e0d49c727fd686a1e7b7be0f804ea67661e7b47c21ff7b753dc5187c7d73b02f4b388dac5baf1fc1db41da27374f639a77df0fb0e704d52bd4b451cc1f818f0ce82fbd4d5241d9ff4a3a979ec9d81e313a69ffbe6b17725fc717f27c51d75785f7d57807e1651bb58379ebf8bb6433eceed0e41e718e718e76cce31ce31ced99c639c639cb339c738c73867738e718e71cee61ce31ce39ccd39c639c6399b738c738c7336e718e718e76cce31ceffffc439ed83df48866b92ea5d26e208f60ef27977c17dea6b928e4ffad1d4e70eef0e1c9f30fddcf7b9c37b12feb8bf9be28e3a3cbede13a09f45d42ed68de7efa1edf056776e77083ac77da3659ce3be119db339c77d233a67738efb4674cee61cf78de89ccd39ee1bd1399b73dc37a27336e7b86f44e76cce71df88ced99ce3be119db339c77d233a67738efb4674cee61cf78de89ccd39ee1bd1399b73dc37a2733667857d23ed73b995e19aa47a978b3882f1354fef2dbc4f43d2f1493f9aba6ee7bd81e313a89f99eb765e4ef8e3fe5e8a3beaf0f87a39403f8ba85dac1bcf5fa6ed109da3b3cf39ed738595e19aa47a57883882f131e07d85f769483a3ee94753f3d8fb02c727503f33f3d8fb13feb8bf8fe28e3abcafbe3f403f8ba85dac1bcfdf4fdb213a47679f73dae74a2bc33549f5ae1471047b997c3e50789f86a4e3937e34358f7d20707c02f533338f7d30e18ffb0728eea8c3fbea0703f4b388dac5baf1fc83b41d3e189da3b3c739ed739595e19aa47a57893882bd9f7c3e54789fbaa4e3937e34358f7d28707c02f533338fbd92f0c7fd431477d4e17df59500fd2ca276b16e3c7f85b6c3a1e69cf6b9ceca704d52bdeb441cc13e483e1f2ebc4f5dd2f1493f9a1a5f1f0e1c9f40fdcc8caf8f24fc71ff30c51d75785ffd48807e1651bb58379e7f84b6c3a1e69cf6b9deca704d52bdeb451cc15e219f8f16dea72ee9f8a41f4d8daf8f068e4fa07e66c6d7ab097fdc3f4a71471dde575f0dd0cf226a17ebc6f357693b1c6ace699f5d56866b92eaed127104fb08f97cacf03e7549c727fd686a7c7d2c707c02f53333be3e9ef0c7fd631477d4e17df5e301fa5944ed62dd78fe71da0e879a73daa79395e19aa47a9d441cc15e259f4f14dea72ee9f8a41f4d8daf4f048e4fa07e66c6d72713feb87f82e28e3abcaf7e32403f8ba85dac1bcf3f49dbe150734efb74b6325c9354afb38823d8c7c9e75385f7a94b3a3ee94753e3eb5381e313a89f99f1f5e9843fee9fa2b8a30eefab9f0ed0cf226a17ebc6f34fd37638d49cd33e5dac0cd724d5eb22e208f649f2f94ce17d1a928e4ffad1d4f8fa4ce0f804ea67667c7d36e18ffb6728eea8c3fbea6703f4b388dac5baf1fcb3b41da27374f639a77daaac0cd724d5ab127104fb34f97caef03e0d49c727fd686a1efb5ce0f804ea67661efb7cc21ff7cf51dc5187f7d5cf07e86711b58b75e3f9e7693be4e3dcee10748e716e9e73da67b495e19aa47aa3451cc13e4b3e5f28bc4f43d2f1493f9a9ac7be10383e81fa9999c7be98f0c7fd0b1477d4e1f1f5c500fd2ca276b16e3cff226d877c9cdb1d82ce31cecd734efb8cb1325c93546f8c8823181f03be54709f7dbf8fc63ee94753f3d89702c7274c3ff7cd63af25fc71ff12c51d75787cbd16a09f45d42ed68de7afd17688ced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e8aced9cf6a9b5325c9354af56c4118c3fb3f972c17df67deec03ee947539f3b7c39707cc2f473dfe70e5f49f8e3fe658a3beaf0befa9500fd2ca276b16e3cff0a6d87e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748ecedace699f7a2bc33549f5ea451cc15e239faf16dea721e9f8a41f4d7deef0d5c0f109d4cfcce70e5f4bf8e3fe558a3beaf0befab500fd2ca276b16e3cff1a6d87e81c9d7dce699fb156866b92ea8d157104fb0af97cbde03efb3e3f659ff4a3a979eceb81e313a69ffbe6b16f24fc71ff3ac51d75785ffd46807e1651bb58379e7f83b6433eceed0e41e718e718e76cce31ce31ced99c639c639cb339c738c73867738e718e71cee61ce31ce39ccd39c639c6399b738c738c7336e718e718e76cce31ceffffc439ed33deca704d52bdf1228e605f239f6f16dca7be26e9f8a41f4d7deef0cdc0f109d3cf7d9f3b7c2be18ffb3729eea8c3e3eb5b01fa5944ed62dd78fe2dda0e6f75e77687a073dc375ac639ee1bd1399b73dc37a27336e7b86f44e76cce71df88ced99ce3be119db339c77d233a67738efb4674cee61cf78de89ccd39ee1bd1399b73dc37a27336e7b86f44e76cce71df88ced99ce3be119db339c77d233a677356d837d23e13ad0cd724d59b28e208c6d73c7dbbf03e0d49c727fd68eaba9d6f078e4fa07e66aedbf94ec21ff76f53dc5187c7d77702f4b388dac5baf1fc3bb41da27374f639a77d265b19ae49aa3759c4118c8f01df2dbc4f5dd2f1493f9a9ac7be1b383e81fa9999c7be97f0c7fdbb1477d4e17df57b01fa5944ed62dd78fe3dda0edf3bc49cd33e53ad0cd724d59b2ae208f61df2f97ee17dea928e4ffad1d4f8fa7ee0f804ea67667cfd20e18ffbf729eea8c3fbea0f02f4b388dac5baf1fc07b41d0e35e7b4cf2c2bc33549f5668938827d8f7c7e58789fbaa4e3937e3435be7e18383e81fa99195f3f4af8e3fe438a3beaf0befaa300fd2ca276b16e3cff116d8743cd39ed33dbca704d52bdd9228e603f209f1f17dea72ee9f8a41f4d8daf1f078e4fa07e66c6d74f12feb8ff98e28e3abcaffe24403f8ba85dac1bcf7f42dbe150734efb1c6665b826a9de61228e603ce6f058488e01f6c5da83195fecd355cce72e319fdd623e73c47cda88f95c21e6335dcce722319f7a319f73c47c8689f93c28e6739a984f1f319f5bc57c4e12f34989f95c23e673b898cf16319f49623e178af9548bf9ac10f31924e6738f98cf29623eddc57c6e10f33956cca7ad98cf95623e33c47c2e16f3192be6b35acca752cc67a9984f3f319fdbc57ce689f97412f3b94ecce748319fad623e53c47cd689f9d488f99c25e63344cce73e319f45623e3dc57c6e12f3395ecc2729e6739598cf2c319f4bc47cc68bf99c2fe65325e6738698cf00319f3bc57c1688f97411f3d925e673b4984f2b319f6d623ed3c47c3688f9d489f9ac12f3192ae6f38098cf12319fde623eb788f99c28e6532ae673b598cf61623e978af94c14f3b940cc67b498cf72319f72319fbbc57c4e16f3e926e6b347cce718319f12319fed623e8d623e1bc57c1ac47cce15f3192ee6f3b098cfe9623e7dc57c6e13f3992be65326e673ad98cf11623e9789f94c16f3592be63346cc67a598cf60319f7bc57c4e15f3e921e673a398cf71623eedc57c7688f9cc14f3d924e6334ecce73c319f11623ecbc47cfa8bf9dc21e6335fcca7b398cff5623e4789f95c2ee63355cc67bd984fad98cfd9623e15623ef78bf92c16f3e925e673b398cf09623e1dc57c768af9cc16f3d92ce63341cc678d98cf48319f33c57c068af91409f824136fbe8f36df07b90331dc97783eb19f5a7901b19f597921b19f5bf96462bfb0f229c47e69e55389fdcaca8b88fddaca8b89fdc6ca4b88fdd6caa711fb9d954f27f67b2b2f25f6072b2f23f6472b9f41ec4f563e93d89fadbc9cd85facbc82d85fadbc92d8dfac7c16b1bf5bf96c62ffb0f22a62ffb4f239c4fe65e57389fddbcaab89bd6ee5f388fdc7cae713c30eb3865891b10b88151bbb90582b636b89b536b68e581b63eb899518db40acadb18b88b533b691587b631713eb606c13b1a4b14b887534b69958a9b14b89a58c6d215666ec32629d8c6d25d6d9d8e5c4ba18db46acabb12b887533b69d5877635712eb616c07b19ec6ae22d6cbd84e62bd8d5d4dac8fb16b88f535762db17ec6ae23d6dfd8f5c40618db456ca0b1ddc4ca8ded2136c8d80dc4061bbb91d810633711ab307633b1a1c66e2136ccd8adc4861bbb8d58a5b1db898d307607b12a6377121b69ec2e62a38cdd4d6cb4b17b88551bbb97d81863f711ab31763f311c2c1e205667ec4162f5c6f8b8d060ac15b1b1c6da101b67ac84d878636d894d30d69ed8c4a2fd65fc9d64ac23b1c9c64a894d31962236d55819b169c63a119b6eac33b14663f83e679acd30d695d84c63dd88cd32d69dd86c633d881d66ac27b1c38df5227684b1dec48e34d687d851c6fa123bda583f62738cf527768cb101c48e353690d871c6ca891d6f6c10b1138c0d2676a2b121c44e3256416caeb1a1c4e6191b466cbeb1e1c41618ab24b6d0d80862271bab22768ab191c44e35369ad82263d5c4161b1b436c89b11a62a719ab2576bab13a624b8dd5135b66ac81d819c6c6123bd3d83862cb8d8d27b6c2d804622b8d4d247696b149c4ce363699d82a6353889d636c2ab1738d4d23b6dad87462e7196b2476beb119c4d6189b49ec0263b3885d686c36b1b5c60e23b6ced8e1c4d61b3b82d806634712bbc8d851c4361a3b9ad8c5c6e610db64ec186297183b96d86663c711bbd4d8f1c4b6183b81d865c64e24b6d5d849c42e373697d83663f3885de139566c37f630b1622b734e8263c94f88e177637e4a0cc7979f11c3f1e5e7c4707cf905b17656fe25311c737e450cfebf2686e3d06f88e138f45b62380efd8e188e43bf2786e3d01f88e138f44762380efd89188e437f2686e3d05f88e138f45762380efd8d188e437f2786e3d03f88e138f44f62380efd8b188e43ff2686e3d0ebc4701cfa0f311c871274fcc771a888188e43c5c4ca8db52236c8586b62380eb52186e35009311c87da12c371a81d311c87da13c371a803b1378e43c4701cea480cc7a15262238da5888d3256460cc7a64ec4706cea4c0cc7a62ec4706cea4a0cc7a66ec4706cea4e0cc7a61ec4706cea490cc7a65ec4706cea4d0cc7a63ec4706cea4b0cc7a67ec4706cea4f0cc7a601c4706c1a480cc7a6726238360d228663d360628dc686109b61ac82188e4d4389e1d8348c188e4dc389e1d854490cc7a611c4706caa228663d3486238368d228663d36862738c5513c3b1690c311c9b6a88e1d8544b0cc7a63a623836d513c3b1a981188e4d6389e1d8348e188e4de389e15cd604623897c53907ce654d228673599389e15cd614623897359518ce654d23867359d389e15c5623319ccb9a410ce7b266125b6a6c16b165c66613c3b9acc388e15cd6e1c4702eeb086238977524319ccb3a8a18ce651d4d0ce7b2e610c3b9ac6388e15cd6b1c4ce35761c319ccb3a9e18ce659d400ce7b24e248673592711c3b9acb9c4702e6b1e319ccb9a4f0ce7b21610c3b9ac85c4702eeb64623897750a319ccb3a9518ce652d228673598b89e15cd612623897751a319ccb3a9d18ce652d25867359cb88e15cd619c42e377626b16dc69613c3b9ac15c4702e6b25319ccb3a8b18ce659d4d0ce7b25611c3b9ac7388e15cd6b9c4702e6b35319ccb3a8fd875c6ce278673596b88e15cd605c4702eeb42623897b59618ce65ad23867359eb89e15cd6066238977511319ccbda480ce7b22e268673599b88e15cd625c4702e6b33319ccbba9418ce656d218673599711c3b9acadc4702eeb72623897b58d18ce655d41ec0163c839d239c0e8d4fed75117f94792eaf27a50b63f99bc016d37260afb790db7d548cfd15e2979e0b5ffb5cf40319f33c57c468af9ac11f39920e6b359cc67b698cf4e319f8e623e2788f9dc2ce6d34bcc67b198cffd623e15623e678bf9d48af9ac17f3992ae673b998cf51623ed78bf97416f3992fe67387984f7f319f65623e23c47cce13f31927e6b349cc67a698cf0e319ff6623ec789f9dc28e6d343cce754319f7bc57c068bf9ac14f31923e6b356cc67b298cf65623e4788f95c2be65326e63357cce736319fbe623ea78bf93c2ce6335ccce75c319f06319f8d623e8d623edbc57c4ac47c8e11f3d923e6d34dcce764319fbbc57ccac57c968bf98c16f3b940cc67a298cfa5623e8789f95c2de6532ae673a298cf2d623ebdc57c9688f93c20e63354cc6795984f9d98cf06319f69623edbc47c5a89f91c2de6b34bcca78b98cf02319f3bc57c0688f99c21e65325e673be98cf78319f4bc47c6689f95c25e69314f3395ecce726319f9e623e8bc47cee13f31922e67396984f8d98cf3a319f29623e5bc57c8e14f3b94ecca79398cf3c319fdbc57cfa89f92c15f3a914f3592de63356cce762319f19623e578af9b415f33956cce706319fee623ea788f9dc23e63348cc6785984fb598cf85623e93c47cb688f91c2ee6738d984f4acce724319f5bc57cfa88f99c26e6f3a098cf30319f73c47ceac57c2e12f3992ee67385984f1b319f39623ebbc57cee12f3e92ae6b3d0f1497f1e8f7be86e27566c0cafb54f1c78fcc375e6e9ba0f392cdd477cafb43151d83ea22dac1bcf1f2687bd567e887c1e0ae4b3d7f171db4e515c1e148d598ad85e4f1c531eef948037ef8f2db1ad1f747cdcb65389fd71d92b1a33ded60f7ae258e6f12e13f0561cd7654e1cd562966b5c5778bc2b04bc15c775851347b598e51ad7c33cdec304bc15c7f530278e6a31cb35ae2b3dde9502de8ae3bad289a35acc728deb2a8f779580b7e2b8ae72e2a816b35ce37a94c77b9480b7e2b81ee5c4512d66b9c675b5c7bb5ac05b715c573b71548b59ae715de3f1ae11f0561cd7354e1cd562966b5cd779bceb04bc15c7759d1347b598e51ad70d1eef06016fc571dde0c4512d66b9c6f5448ff744016fc5713dd189a35acc728deb491eef4902de8ae37a921347b598e51ad7933dde9305bc15c7f564278e6a31cb35ae1779bc1709782b8eeb454e1cd562966b5c2ff6782f16f0561cd78b9d38aac52cd7b85ee2f15e22e0ad38ae973871548b59ae71bdc1e3bd41c05b715c6f70e2a816b35ce37aa3c77ba380b7e2b8dee8c4512d66b9c6f5268ff726016fc571bdc989a35acc728debcd1eefcd02de8ae37ab31347b598e51ad75b3cde5b04bc15c7f516278e6a31cb35aeb77abcb70a782b8eebad4e1cd562966b5c6ff3786f13f0561cd7db9c38aac52cd7b8deeef1de2ee0ad38aeb73b71548b59ae71bdc3e3bd43c05b715cef70e2a816b35ce37aa7c77ba780b7e2b8dee9c4512d66b9c6f52e8ff72e016fc571bdcb89a35acc728debdd1eefdd02de8ae37ab71347b598e51ad77b3cde7b04bc15c7f51e278e6a31f38deb76542e2f9c4f4d8a5c8aa9ad0703f53de1f43de16c0bf6b954cc67a298cf05623ea3c57c968bf90c12f3b95bcce764319fee623e7bc47c8e11f3692fe6b35dcca751cc67a3984f8398cfb9623e95623ea78bf9f413f3b94dcc67ae984f27319f6bc57c8e10f3692de6739998cf64319fb5623e63c47c568af90c11f3b957cce754319f9e623e378af91c27e69314f3d921e63353cc679398cf38319ff3c47caac47c9689f90c10f3b943cc67be984f17319febc57c8e12f32911f3b95ccc67aa98cf7a319f5a319fb3c57c868af9dc2fe6b358cca7b798cfcd623e2788f9948af9ec14f3992de6b359cc678298cf1a319f51623e678af9948bf9dc25e6b350cca79b98cf6e319f39623eedc47cae10f3992ee67391984fbd98cf39623ec3c57c4e13f3e92be673ab98cf49623e65623ed788f91c2ee6d34acc678b98cf24319f0bc57caac57c5688f90c16f3b947cce714319f1e623e3788f91c2be6d341cce74a319f19623e178bf98c15f3592de63342cc67a9984f7f319fdbc57ce689f97416f3b94ecce748319f36623e5bc57ca688f9ac13f3a911f3394bcca742cce73e319f45623ebdc47c6e12f3395ecca7a398cf55623eb3c47c2e11f3192fe673be98cf48319f33c47c068af9dc29e6b340cca7ab98cf2e319fa3c57cda8af96c13f39926e6b341cca74ecc679598cf30319f07c47c9688f9f411f3b945cce744319f9498cfd5623e8789f91409f824c923410cf79f2e2686fb53b722f688955b137bd4ca6d883d66e512628f5bb92db12712fb6302f6a495db137bcaca1d883d4d65fc7dc6ca1d893d6be55262cf593945ec792b97117bc1ca9d88bd68e5cec45eb27217626fb37257626fb7723762efb0727762efb4720f62efb2724f62efb6722f62efb1726f62efb5721f622f5bb92fb1f759b91fb1f75bb93fb10f587900b10f5a7920b10f59b99cd82b561e44ecc3561e4cec23561e42eca356ae20f6aa958712fb98958711fbb8958713fb84952b897dd2ca23887dcaca55c43e6de591c43e63e551c43e6be5d1c43e67e56a629fb7f218625fb0720db12f5ab996d897ac5c47ec352bd713fbb2951b887dc5ca63897dd5cae3887dcdcae3897dddca13887dc3ca13897dd3ca93887dcbca93897ddbca53887dc7ca53897dd7cad3887dcfcad3897ddfca8dc47e60e519c47e68e599c47e64e559c47e6ce5d9c47e62e5c388fdd4ca8713fb99958f20f6732b1f49ec17563e8ad82fad7c34b15f59790eb15f5bf91862bfb1f2b1c47e6be5e388fdcecac713fbbd954f20f6072b9f48ec8f563e89d89fac3c97d89fad3c8fd85fac3c9fd85fadbc80d8dfacbc90d8dfad7c32b17f58f91462ffb4f2a9c4fe65e545c4fe6d65fe1df9d7adccbf37fe1f2b9f460c07d6d38915195b4aacd8d83262ad8c9d41acb5b13389b531b69c5889b115c4da1a5b49ac9db1b388b5377636b10ec656114b1a3b87584763e7122b35b69a58cad879c4ca8c9d4fac93b135c43a1bbb805817631712eb6a6c2db16ec6d611eb6e6c3db11ec6f837c67b1abb88582f63fcfbd4bd8d5d4cac8f31fe6de3bec62e21d6cf18ff2e6e7f6397121b608c7f5375a0b1cb88951be3dfe31c64ec7262838d6d2336c4d815c42a8cf1ef000e357625b161c6f837e4861bbb8a58a531fefdb111c6ae265665ec1a62238d5d4b6c94b1eb888d36763db16a63fc5b58638ced2656638c7f5b076faa6f205667ec4662f5c66e22d660ec6662638ddd426c9cb15b898d37761bb109c66e2736d1d81dc42619bb93d8646377119b62ec6e62538ddd436c9ab17b894d37761fb14663f7139b61ec0162338ded2586bce32162c83b1e2686bce31162c83b1e2586bce33162c83b1e2786bce30962c83b9e2486bce32962492b731e82bce31962c83b9e2586bce33962c83b9e2786bce30562c83b5e2486bce32562c83bde460c79c7db8921ef780731e41def2486bce35dc49077bc9b18f28ef71043def15e62c83b5e2686bce37dc49077bc9f18f28e0f1043def14162e556fe10b141567e8518f28e0f1343def11162c83b3e4a0c79c7abc490777c8c18f28e8f1343def10962c83b3e490c79c7a7888db4f2a78921eff80c31e41d9f2586bce373c490777c9e18f28e2f1043def14562c83bbe440c79c76bc490777c9918f28eaf1043def15562c83bbe460c79c7d78921eff80631e41ddf2486bce35bc490777c9b18f28eef1043def15d62c83bbe47acd1cadf2736c3ca3f2086bce387c49077fc8818f28e1f1343def11362c83b7e4a0c79c7cf8821eff83931e41dbf2086bce397c4e658f957c49077fc9a18f28edf1043def15b62c83b7e470c79c7ef8921eff80331e41d7f2486bce34fc49077fc9918f28ebf1043def15762c83bfe460c79c7df8921eff80731e41dff2486bce35fc49077fc9b18f28ed78921eff80f31e41dc843d26c2910b165c68a8921ef68450c79476b62c83bda1043de51420c79475b626f5c3f490c79477b62c83b3a107b23ef2076aeb18ec49077941243de912286bca38c18f28e4ec49077742686bca30b31e41d5d8921efe8460c79477762c83b7a1043ded19318f28e5ec49077f42686bca30f31e41d7d8921efe8470c79477f62c83b061043de319018f28e7262971b1b446c9bb1c1c490770c2186bca38218f28ea1c490770c2386bc633831e41d95c490778c2086bca38a18f28e91c4ae33368a18f28ed1c49077541343de318618f28e1a62c83b6a8921efa82386bca39e18f28e0662c83bc61243de318e18f28ef1c490774c2086bc632231e41d938821ef984c0c79c71462c83ba61243de318d18f28ee9c4907734127bc0d80c620f1a431e92ce0b06f4d8ff3aeaf26721a8cbeb41d9fe647209b4dd9828ece73adc56233d477ba5e481d7fed73e8789f95c2de69312f33951cce716319f3e623e4bc47c1e10f31926e6b34acca74ecc678398cf34319f6d623e6dc57c8e16f3d925e6d355cc678198cf9d623e03c57cce10f31929e673be98cf78319f4bc47c6689f95c25e6d351cce778319f9bc47c7a89f92c12f3b94fcca742cce72c319f1a319f75623e53c47cb68af9b411f33952cce73a319fce623ef3c47c6e17f3e92fe6b354cc678498cf6a319fb1623e178bf9cc10f3b952cca78398cfb1623e3788f9f410f33945cce71e319fc1623e2bc47caac57c2e14f39924e6b345cca79598cfe1623ed788f99489f99c24e673ab984f5f319fd3c47c868bf99c23e6532fe6739198cf74319f2bc47cda89f9cc11f3d92de6d34dcc67a198cf5d623ee5623e678af98c12f35923e63341cc67b398cf6c319f9d623ea5623e2788f9dc2ce6d35bcc67b198cffd623e43c57cce16f3a915f3592fe63355cce772319f12319fa3c47cae17f3e922e6335fcce70e319f01623ecbc47caac47cce13f31927e6b349cc67a698cf0e319fa498cf71623e378af9f414f33955cce75e319f21623e2bc57cc688f9ac15f3992ce67399984f6b319f23c47cae15f3e924e63357cce736319f7e623ea78bf9548af99c2be6d320e6b351cca751cc67bb984f7b319f63c47cf688f97417f33959cce76e319f41623ecbc57c468bf95c20e63351cce752319f62c7a7d4793dfdc8fc5684c3d2de530379a32dac1bcfa79203ee993d8de2382d90cf74c7c76d3b457141ecd462962236dd1347fe0dd1690efb5f6febc616dcd68d8e4fa3675b232ed38b3463c6dbbad11347fe6dd8690e8be3fac06d89b8f8c6b542cc728d6bfe8dd9690e8be3fac06d8db8f8c6b542cc728d6bfe9de0690e8be3fac06d8db8f8c6b542cc728d6b9cd763ef4a016fc5718db8f8c6b542cc728d6bfebdee690e8be3fac06d8db8f8c6b542cc728d6bfecdf5690e8be3fac06d8db8f8c6b542cc728d6bdc7b85bdab05bc15c735e2e21bd70a31cb35ae711f58f6ae11f0561cd7888b6f5c2bc42cd7b8c66fd2b0779d80b7e2b8465c7ce35a2166b9c6353e3f66ef06016fc5718db8f8c6b542cc728d6b7c96c0de1305bc15c735e2e21bd70a31cb35ae71df37f69e24e0ad38ae1117dfb8568859ae718d6b58d97bb280b7e2b8465c7ce35a2166b9c6357ecf83bd1709782b8e6bc4c537ae1562966b5ce3de04ecbd58c05b715c232ebe71ad10b35ce31abf23cbde4b04bc15c735e2e21bd70a31cb35aef11babecbd41c05b715c232ebe71ad10b35ce31ad743b3f746016fc5718db8f8c6b542cc728d6b7c379bbd3709782b8e6bc4c537ae1562966b5ce33e71ecbd59c05b715c232ebe71ad10b35ce31af7ac67ef2d02de8ae31a71f18d6b8598e51ad7f8fd3cf6de2ae0ad38ae1117dfb8568859ae71bd2df166ef6d02de8ae31a71f18d6b8598e51ad7f8de1d7b6f17f0561cd7888b6f5c2bc42cd7b8c63d80d87b8780b7e2b8465c7ce35a2166b9c635ee47ccde3b05bc15c735e2e21bd70a31cb35ae7725deecbd4bc05b715c232ebe71ad10b35ce37a77e2cddebb05bc15c735e2e21bd70a31cb35aef11d7bf6de23e0ad38ae1117dfb85688996f5c27a93c935871e2c07aed2de60f25f6c71f751f7158ba8f8f26c2f4116d61dd78fe28393c6ce547c8e791403e0f3b3e6edbfcfddd8744639622f6b0278e298f774ac09bf7c796d8d60f393e6edbfcfddd874563c6dbfa214f1ccb3cde6502de8ae3bacc89a35acc728deb0a8f778580b7e2b8ae70e2a816b35ce37a98c77b9880b7e2b81ee6c4512d66b9c675a5c7bb52c05b715c573a71548b59ae715de5f1ae12f0561cd7554e1cd562966b5c8ff2788f12f0561cd7a39c38aac52cd7b8aef678570b782b8eeb6a278e6a31cb35ae6b3cde3502de8ae3bac689a35acc728deb3a8f779d80b7e2b8ae73e2a816b35ce3bac1e3dd20e0ad38ae1b9c38aac52cd7b89ee8f19e28e0ad38ae273a71548b59ae713dc9e33d49c05b715c4f72e2a816b35ce37ab2c77bb280b7e2b89eecc4512d66b9c6f5228ff722016fc571bdc889a35acc728debc51eefc502de8ae37ab11347b598e51ad74b3cde4b04bc15c7f512278e6a31cb35ae3778bc3708782b8eeb0d4e1cd562966b5c6ff4786f14f0561cd71b9d38aac52cd7b8dee4f1de24e0ad38ae373971548b59ae71bdd9e3bd59c05b715c6f76e2a816b35ce37a8bc77b8b80b7e2b8dee2c4512d66b9c6f5568ff756016fc571bdd589a35acc728deb6d1eef6d02de8ae37a9b1347b598e51ad7db3ddedb05bc15c7f576278e6a31cb35ae7778bc7708782b8eeb1d4e1cd562966b5ceff478ef14f0561cd73b9d38aac52cd7b8dee5f1de25e0ad38ae773971548b59ae71bddbe3bd5bc05b715cef76e2a816b35ce37a8fc77b8f80b7e2b8dee3c4512d66be71dd8e7c0be9934c1c18b3f4a3c879de48e5873c3eaf17cea726453e0f85dd1675bcdd0fa6ef8f92cf6385f7c96c8b47f3f0798c7c1e0f149fc7f2f0799c7c9e08149fc7f3f079827c9e0ce4f3441e3e4f92cf53817c9eccc3e729f2793a90cf5379f83c1dd62733b73ceab495668f7bda072b2f5cfbcbd26d617f799cdac7367b90dae77da540edd7a6687bf0fa0b3fb7d6d6e5bbed796e0d3177043a86d4a4d7fb0cf5af50eb4dafeb5927564f39b14a519d67287ecf06885f51e2c06353233d7fd6d37601f7db4c2c9e3b88583ce7f179ae856381f6a2b3a6f34387a0f3a118e7670e41e73806a37336e7386fb48c739c37a2f35bc939ce1bcd73e673a070e5f3637c2ef97fe908f644589f95f99eab7c8e7c429cc70ed4cf4caef7bcd3a7473c71471d3e5e3c1fa09fbeb183e7cfd376c8c7f9d9e81c9ddf42ce710c46e7e8fcbf758e63303a47e7c23aa77df0f9375c9354ef311147b04783fad4e67d3dc0f3e41322470b14f74c0ef282d3a7c73c71471d9e7b5f08d04fdfd8c1f317683be4e3fc6c748ece599c1f3a049d0fc538c779233abf959ce3bcd132ce71de88ce6f25e7386f34cf39ddf68b856f3bf35913b78df8241c1f3c5e0c1c8b40fdcce4792f25fc31467b29aac3f3ee4b01fa5944ed62dd78fe126d877c9c9f8dced1f92de41cc760748eceff5be73806a373742eac738a5e2f269f00ef7b6b0fe6bd3cfb5c2ae63351cce702319fd1623ecbc57c0689f9dc2de673b2984f77319f3d623ec788f9b417f3d92ee6d328e6b351cca741cce761319f73c57c2ac57c4e17f3e927e6739b98cf5c319f4e623ed78af91c21e6d35acce732319fc9623e6bc57cc688f9ac14f31922e673af98cfa9623e3dc57c6e14f3394ecc2729e6b343cc67a698cf26319f71623ee789f95489f92c13f31920e6738798cf7c319f2e623ed78bf91c25e65322e673b998cf54319ff5623eb5623e678bf90c15f3b95fcc67b1984f6f319f9bc57c4e10f32915f3d92be6b353cc67b698cf66319f09623e6bc47c4689f99c29e6532ee6739798cf42319f6e623ebbc57ce688f9b413f3b942cc67ba98cf45623ef5623ee788f90c17f37950cce734319fbe623eb78af99c24e65326e6738d98cfe1623eadc47cb688f94c12f3b950cca75acc678598cf60319f7bc47c4e11f3e921e6738398cfb1623e1dc47cae14f39921e673b198cf58319fd5623e23c47c968af9f417f3b95dcc679e984f67319febc47c8e14f36923e6b355cc678a98cf3a319f1a319fb3c47c2ac47cee13f35924e6d34bcce726319fe3c57c3a8af95c25e6334bcce712319ff1623ee78bf98c14f33943cc67a098cf9d623e0bc47cba8af9ec12f3395acca7ad98cf36319f69623e1bc47ceac47c5689f90c13f37940cc6789984f1f319f5bc47c4e14f34989f95c2de67398984f91804f32f1e6dfc449d2ebc5c4708fef56c4de66e5d6c4de6ee536c4de61e51262efb4725b62ef4aec8f09d8bbaddc9ed87bacdc81d87ba98cbf2f5bb923b1f759b994d8fbad9c22f6012b9711fba0953b11fb90953b137bc5ca5d887dd8ca5d897dc4cadd887dd4cadd89bd6ae51ec43e66e59ec43e6ee55ec43e61e5dec43e69e53ec43e65e5bec43e6de57ec43e63e5fec43e6be501c43e67e581c43e6fe572625fb0f220625fb4f260625fb2f21062af59b982d897ad3c94d857ac3c8cd857ad3c9cd8d7ac5c49eceb561e41ec1b56ae22f64d2b8f24f62d2b8f22f66d2b8f26f61d2b5713fbae95c710fb9e956b887ddfcab5c47e60e53a623fb4723db11f59b981d88fad3c96d84fac3c8ed84fad3c9ed8cfac3c81d8cfad3c91d82fac3c89d82fad3c99d8afac3c85d8afad3c95d86fac3c8dd86fad3c9dd8efacdc48ecf7569e41ec0f569e49ec8f569e45ec4f569e4deccf563e8cd85fac7c38b1bf5af908627fb3f291c4fe6ee5a388fdc3ca4713fba795e710fb97958f21f66f2b1f4bec752b1f47ec3f563e9e180e1627102b327622b1626327116b656c2eb1d6c6e6116b636c3eb112630b88b535b690583b6327136b6fec14621d8c9d4a2c696c11b18ec616132b35b68458cad869c4ca8c9d4eac93b1a5c43a1b5b46ac8bb1338875357626b16ec69613eb6e6c05b11ec65612eb69ec2c62bd8c9d4dacb7b155c4fa183b87585f63e712eb676c35b1fec6ce2336c0d8f9c4061a5b43acdcd805c40619bb90d860636b890d31b68e5885b1f5c4861adb406c98b18b880d37b69158a5b18b898d30b6895895b14b888d34b699d8286397121b6d6c0bb16a6397111b636c2bb11a639713c31bc56dc4ea8c5d41acded876620dc6ae2436d6d80e62e38c5d456cbcb19dc42618bb9ad84463d7109b64ec5a62938d5d476c8ab1eb894d35b68bd83463bb894d37b68758a3b11b88cd307623b199c66e2236cbd8cdc4661bbb85d861c66e2576b8b1db881d61ec7662471abb83d851c6ee2476b4b1bb88cd317637b1638cdd43ec5863f7123bced87dc48e37763fb1138c3d40ec44638f113bc9d873c4e61a7b9ad83c63cf139b6fec05620b3ccb2e34f638b1938d3d48ec14634f12435ec47914f2a29788212f7a1b31e4456f2786bce81dc49017bd9318f2a27711435ef46e62c88bde432c6965ce939017bd4c0c79d1fb88212f7a3f31e4451f2086bce883c490177d8818f2a25788212ffa3031e4451f2186bce8a3c49017bd4a0c79d1c788212ffa3831e4459f2086bce893c490177d8a18f2a24f13435ef41962c88b3e4b0c79d1e788955bf9f3c40659f90bc490177d9118f2a22f11435ef41a31e4455f2686bce82bc490177d9518f2a2af11435ef47562c88bbe416ca495bf490c79d1b788212ffa3631e445df2186bce8bbc490177d8f18f2a2ef13435ef40362c88b7e480c79d18f88212ffa3131e4453f2186bce8a7c49017fd8c18f2a29f13435ef40b62c88b7e490c79d1af88212ffa3531e445bf2186bce8b7c41aadfc3b6233acfc7b62c88bfe400c79d11f89212ffa1331e4457f2686bce82fc49017fd9518f2a2bf11435ef47762c88bfe416c8e95ff490c79d1bf88212ffa3731e445af13435ef41f62c88b9027658e6f40c490171513435ed48a18f2a2d6c49017b52186bca88418f2a2b6c4def84d2c62c88bda13435ed481d81b791131e4451d89212f2a2586bc28450c795119b1a5c63a115b66ac3331e4455d88212fea4a0c79513762c88bba13435ed48318f2a29ec49017f52286bca83731e4457d889d6bac2f31e445fd88212fea4f0c79d10062c88b0612435e544e0c79d12062c88b0613435e348418f2a20a62c88b8612435e348c18f2a2e1c490175512435e348218f2a22a62c88b4612435e348a18f2a2d1c490175513435e3486d8e5c66a886d33564b0c79511d31e445f5c490173510435e349618f2a271c490178d2786bc680231e4451389212f9a44ec3a639389212f9a420c79d15462c88ba611435e349d18f2a24662c88b6610435e349318f2a259c49017cd2686bce83062c88b0e2786bce80862c88b8e2486bce82862c88b8e2686bc680e31e445c710435e742c31e445c711435e743cb1078c9d40ec41632712db6bec24620f199b4b0cbff9358fd823c6e6137bd4d80262c8c7161243ae7432b1278c214f4ae72d3faed8ff3a96e7cf92d00e7f9684e5b93db4c35e28db9f4c4e84651a1385fdfc8cdb6aa4e768af943cf0daffdae730319fabc57c52623e278af9dc22e6d347cc678998cf03623ec3c47c5689f9d489f96c10f39926e6b34dcca7ad98cfd1623ebbc47cba8af92c10f3b953cc67a098cf19623e23c57cce17f3192fe6738998cf2c319fabc47c3a8af91c2fe67393984f2f319f45623ef789f95488f99c25e65323e6b34ecc678a98cf56319f36623e478af95c27e6d359cc679e98cfed623efdc57c968af98c10f3592de63356cce762319f19623e578af97410f33956cce706319f1e623ea788f9dc23e63358cc6785984fb598cf85623e93c47cb688f9b412f3395ccce71a319f32319f93c47c6e15f3e92be6739a98cf83623ec3c57cce11f3a917f3b948cc67ba98cf15623eedc47ce688f9ec16f3e926e6b350cce72e319f72319f33c57c4689f9ac11f39920e6b359cc67b698cf4e319fbd623ea5623e2788f9dc2ce6d35bcc67b198cffd623e43c57cce16f3a915f3592fe63355cce772319f12319fa3c47cae17f3e922e6335fcce70e319f01623ecbc47caac47cce13f31927e6b349cc67a698cf0e319fa498cf71623e378af9f414f33955cce75e319f21623e2bc57cc688f9ac15f3992ce67399984f6b319f23c47cae15f3e924e63357cce736319f7e623ea78bf9548af99c2be6f3b0984f8398cf46319f46319fed623eedc57c8e11f3d923e6d35dcce764319fbbc57c0689f92c17f3192de6738198cf44319f4bc57c8a5bd007f70bc7ba4f767c02b55dc3f764c7fad3f741e930607fbb0b0adfeeb222a7bdc6c49baf476b4d75de5eb1bf6e2aa85bc384f47ae7177cbd63333fcd30cfe933fce7539f51a7abf5337d1e80978517ee3bbf80f659c46b9e27863d07ec6f7bea90fdcbe0fefbc83fd2fdc77df5cb1385dde68fecef4266dd0f5a19eda5ebe0fefd254e1d2cdb9aeaf4a718f16f5417535f50b73151d831cb8f462aa33df69928e6738198cf20319f93c57cf688f920b753f16914f3d928e65329e673ba98cf6d623e9dc47c8e10f3b94ccc678c98cf4a319f7bc57c7a8af91c27e6b343cce721319f71623ee789f90c10f3992fe673bd984f8998cf54319ff5623e43c57c168bf9dc2ce6532ae6335bcc67b398cf28319f33c57cee12f3e926e63347cce70a319f7a319f73c47cfa8af99c24e6738d984f2b319f49623e178af90c16f33945cce706319f0e623e33c47c2e16f31921e6b354cce776319fce623e478af96c15f3a911f3394bcce73e319f5e623ec78bf95c25e6f38898cf78319ff3c57c068af92c10f3d925e6d356cc679a98cf06319f61623e4bc47c6e11f34989f91c26e673a998cf68319fe5623e778bf97417f33946cc67bb98cfc3623e0d623ee78af9f413f3992be673ad984f6b319fc9623e6bc57c8688f99c2ae673a3984f52cc67a698cf26319f2a319f65623e7788f97411f3394acce772319f5a319fb3c57cee17f3e92de6738298cf5e319f9d623e13c47cd688f9948bf92c14f3d92de6d34ecc67ba98cf45623ec3c57c4e13f3b955cca74ccce770319f2d623ed5623e2bc47cee11f3e921e673ac98cf95623e63c57c568bf9f417f39927e6739d984f1b319f29623eebc47c2ac47c1689f9dc24e6d351cc679698cf25623e23c57cce10f3b953cca7ab98cfd1623edbc47ceac47c5689f93c20e6d347cce744319fabc57c8a047c92e4912086d78b893d6ee556c49eb0726b624f5ab90db1a7ac5c42ec692bb725f64c627f4cc09eb5727b62cf59b903b1e7a98cbf2f58b923b117ad5c4aec252ba788bdcdca65c4de6ee54ec4de61e5cec4de69e52ec4de65e5aec4de6de56ec4de63e5eec4de6be51ec45eb6724f62efb3722f62efb7726f621fb0721f621fb4725f621fb2723f62af58b93fb10f5b7900b18f587920b18f5ab99cd8ab561e44ec63561e4cece3561e42ec1356ae20f6492b0f25f6292b0f23f6692b0f27f6192b5712fbac954710fb9c95ab887ddeca23897dc1caa3887dd1caa3897dc9cad5c45eb3f218625fb6720db1af58b996d857ad5c47ec6b56ae27f6752b3710fb8695c712fba695c711fb9695c713fbb6952710fb8e952712fbae952711fb9e952713fbbe95a710fb8195a712fba195a711fb9195a713fbb1951b89fdc4ca3388fdd4ca3389fdcccab388fddccab389fdc2ca8711fba5950f27f62b2b1f41ecd7563e92d86fac7c14b1df5af96862bfb3f21c62bfb7f231c4fe60e56389fdd1cac711fb93958f27f6672b9f40ec2f563e91d85fad7c12b1bf59792eb1bf5b791eb17f58793eb17f5a7901b17f597921b17f5bf96462af5bf91462ffb1f2a9c470205c44acc8d86262c5c696106b65ec3462ad8d9d4eac8db1a5c44a8c2d23d6d6d819c4da193b93587b63cb897530b68258d2d84a621d8d9d45acd4d8d9c452c656112b33760eb14ec6ce25d6d9d86a625d8c9d47acabb1f3897533b6865877631710eb61ec42623d8dad25d6cbd83a62bd8dad27d6c7d806627d8d5d44ac9fb18dc4fa1bbb98d800639b880d347609b172639b890d327629b1c1c6b6101b62ec326215c6b6121b6aec7262c38c6d2336dcd815c42a8d6d2736c2d895c4aa8ced2036d2d855c44619db496cb4b1ab89551bbb86d81863d712ab31761d31bc09be9e589db15dc4ea8ded26d6606c0fb1b1c66e2036ced88dc4c61bbb89d8046337139b68ec1662938cdd4a6cb2b1db884d31763bb1a9c6ee2036cdd89dc4a61bbb8b58a3b1bb89cd30760fb199c6ee2536cbd87dc4661bbb9fd861c61e2076b8b1478821efe03c0579c7e3c490773c410c79c793c490773c450c79c7d3c490773c430c79c7b3c490773c472c6965ce439077bc400c79c78bc49077bc440c79c7db8821ef783b31e41def2086bce39dc49077bc8b18f28e771343def11e62c83bde4b0c79c7cbc49077bc8f18f28ef71343def10162c83b3e480c79c7878821ef788518f28e0f1343def11162e556fe28b141567e9518f28e8f1143def17162c83b3e410c79c7278921eff81431e41d9f2686bce333c490777c9618f28ecf111b69e5cf1343def10562c83bbe480c79c7978821ef788d18f28e2f1343def11562c83bbe4a0c79c7d78821eff83a31e41ddf2086bce39bc490777c8b18f28e6f1343def11d62c83bbe4b0c79c7f78821eff83e31e41d3f2086bce387c49077fc8858a3957f4c6c86957f420c79c74f8921eff81931e41d3f2786bce317c49077fc9218f28e5f1143def16b62c83b7e430c79c76f89cdb1f2ef8821eff83d31e41d7f2086bce38fc49077fc8918f28e3f1343def11762c83bfe4a0c79c7df8821eff83b31e41dff2086bce39fc49077fc8b18f28e7f1343def13a31e41dff2186bc0379489a21ef282286bca39818f28e56c49077b426b6d4581b62cb8c951043ded196d81bf7e32686bca33d31e41d1d88bd91771043ded19118f28e5262c83b52c4907794113bd7582762c83b3a1343ded18518f28eaec49077742386bca33b31e41d3d8821efe8490c79472f62c83b7a1343ded18718f28ebec49077f42386bca33f31e41d038821ef18480c79473931e41d838821ef184c0c79c71062c83b2a885d6e6c28b16dc6861143de319c18f28e4a62c83b461043de51450c79c74862c83b461143de319a18f28e6a62c83bc610bbce580d31e41db5c49077d41143de514f0c79470331e41d638921ef18470c79c77862c83b261043de319118f28e49c490774c2686bc630a31e41d538921ef98460c79c77462c83b1a8921ef98410c79c74c62c83b661143de319bd803c60e23f6a031e421e9bc60408ffdafa32e7f1682babc1e94ed4f269740db8d89c27eaec36d35d273b4574a1e78ed7fed73b598cf89623e7dc47c1e10f35925e65327e6b34dcce768319fae623e778af99c21e63352cce712319f59623e1dc57c6e12f35924e65321e6b34ecc678a984f1b319febc47ce689f9f417f3592de63356cce74a319f63c57c7a88f9dc23e6b342cca75acc678b98cfe1623e65623eb78af99c26e6335ccce722319fe9623eedc47c768bf92c14f32917f35923e63341cc67a798cf5e319f13c47c7a8bf9dc2fe673b6984fad98cfe5623e4789f97411f3b943cc6799984f9598cf26319f99623e49319f1bc57c4e15f31922e6b356cc67b2984f6b319f6bc57ce68af9f413f33957cca741cce761319fed623ec788f97417f3b95bcc67b998cf68319f4bc57c0e13f34989f9dc22e6b344cc679898cf06319f69623e6dc57c7689f92c10f31928e673be98cf78319f47c47cae12f3395ecca79798cf7d623e6789f9d488f96c15f33952cca7b398cfed623e4bc57c4688f95c2ce63343cca78398cf0d623ea788f90c16f3b950cc6792984f2b319f6bc47c4e12f3e92be6738e984fbd98cf15623e73c47cba89f9dc25e673a698cf28319fcd623eb3c57c4ac57c6e16f3592ce63354cc67bd98cf54319f12319febc57ce68bf90c10f3394fcc679c98cf43623e3bc47c8e13f3e929e673af98cf4a319f31623e9789f91c21e6d349cce736319fd3c57c2ac57c368af9348af9b417f3d923e673b298cf20319f0bc47c268af9143b3ee9c723fb8b6fbcdfc7bdc7d3d74b3fecd44bdf2370ea90fdebc432a857ea94d38ff4f7281f75583a16a17e93166d61dd78fe1839a03f8f92cfa3817c1e717cdcb65314978745639622f688278e298f774ac09bf7c796d8d60f3b3e6edba9c4feb83c221a33ded6be715de6f12e13f0561cd7654e1cd562966b5c5778bc2b04bc15c775851347b598e51ad7c33cdec304bc15c7f530278e6a31cb35ae2b3dde9502de8ae3bad289a35acc728deb2a8f779580b7e2b8ae72e2a816b35ce37a94c77b9480b7e2b81ee5c4512d66b9c675b5c7bb5ac05b715c573b71548b59ae715de3f1ae11f0561cd7354e1cd562966b5cd779bceb04bc15c7759d1347b598e51ad70d1eef06016fc571dde0c4512d66b9c6f5448ff744016fc5713dd189a35acc728deb491eef4902de8ae37a921347b598e51ad7933dde9305bc15c7f564278e6a31cb35ae1779bc1709782b8eeb454e1cd562966b5c2ff6782f16f0561cd78b9d38aac52cd7b85ee2f15e22e0ad38ae973871548b59ae71bdc1e3bd41c05b715c6f70e2a816b35ce37aa3c77ba380b7e2b8dee8c4512d66b9c6f5268ff726016fc571bdc989a35acc728debcd1eefcd02de8ae37ab31347b598e51ad75b3cde5b04bc15c7f516278e6a31cb35aeb77abcb70a782b8eebad4e1cd562966b5c6ff3786f13f0561cd7db9c38aac52cd7b8deeef1de2ee0ad38aeb73b71548b59ae71bdc3e3bd43c05b715cef70e2a816b35ce37aa7c77ba780b7e2b8dee9c4512d66b9c6f52e8ff72e016fc571bdcb89a35acc728debdd1eefdd02de8ae37ab71347b598e51ad77b3cde7b04bc15c7f51e278e6a31f38deb24951f2256ecd46b6fee0b0aff1de509e9552eb4f516db7af7daba17d0f7a3e715beed9af42ae7db7a5bdb7ad1ce02e2a8f3fe8a7d7fd34f4f32d6ca965be82c97fe33d759379641ff5a531dacbb93f5777ec1fb3bb686bddb38de1c07d479859c7859789d62cf17d277c911bf93687d60af56ec6ffb3b15fb97c1f2183b61fabf6f5f5b90655f9b4ffbdadc40fbda3c677f98eb893dea7c9ef6b5139d7d6d81b35c9113ef465a86f7b5939c75635f0b30b66a79ff4f38def38adedcb712a70e8f1dd4f9b2e37d620b8d11b89ce819235f3fc8313297c6c802678cf0ebe9873b97f0fd16e6921bc650a0b9b996e766acdb9d9b790e2d71ea2cf4cca13fa478253d75d3fdea30607fac9e4cec2f276c99a71d96eeff338930fd475b58379e3f430e4f59f969f2793a90cf538e8fdb36df33e249d198a5883de58963cae39d12f0e6fdb125b6f5938e8fdb36df33e229d198f1b67ed213c7328f779980b7e2b82e73e2a816b35ce3bac2e35d21e0ad38ae2b9c38aac52cd7b81ee6f11e26e0ad38ae873971548b59ae715de9f1ae14f0561cd7954e1cd562966b5c5779bcab04bc15c775951347b598e51ad7a33cdea304bc15c7f528278e6a31cb35aeab3dded502de8ae3bada89a35acc728deb1a8f778d80b7e2b8ae71e2a816b35ce3bacee35d27e0ad38aeeb9c38aac52cd7b86ef0783708782b8eeb06278e6a31cb35ae277abc270a782b8eeb894e1cd562966b5c4ff2784f12f0561cd7939c38aac52cd7b89eecf19e2ce0ad38ae273b71548b59ae71bdc8e3bd48c05b715c2f72e2a816b35ce37ab1c77bb180b7e2b85eecc4512d66b9c6f5128ff712016fc571bdc489a35acc728deb0d1eef0d02de8ae37a831347b598e51ad71b3dde1b05bc15c7f546278e6a31cb35ae3779bc3709782b8eeb4d4e1cd562966b5c6ff6786f16f0561cd79b9d38aac52cd7b8dee2f1de22e0ad38aeb73871548b59ae71bdd5e3bd55c05b715c6f75e2a816b35ce37a9bc77b9b80b7e2b8dee6c4512d66b9c6f5768ff776016fc571bddd89a35acc728deb1d1eef1d02de8ae37a871347b598e51ad73b3dde3b05bc15c7f54e278e6a31cb35ae7779bc7709782b8eeb5d4e1cd562966b5ceff678ef16f0561cd7bb9d38aac52cd7b8dee3f1de23e0ad38aef73871548b996f5cb7a372a17df63a3e7b5bb0ed6cf7f8788a628147710bf8241c9f44133e978af94c14f3b940cc67b498cf13623ecbc57c0689f9dc2de673b2984f77319f3d623ec788f9b417f3d92ee6d328e6b351cca741cce75c319f4a319f87c47c4e17f3e927e6739b98cf5c319f4e623ed78af91c21e6d35acce732319fc9623e6bc57cc688f9ac14f31922e673af98cfa9623e3dc57c6e14f3394ecc2729e6b343cc67a698cf26319f71623ee789f95489f93c2ae6b34ccc678098cf1d623ef3c57cba88f95c2fe67394984f8998cfe5623e53c57cd68bf9d48af99c2de63354cce77e319fc5623ebdc57c6e16f33941cca754cc67a798cf6c319fcd623e13c47cd688f98c12f3795ccce74c319f72319fbbc47c168af97413f3d92de63347cca79d98cf15623ed3c57c2e12f3a917f33947cc67b898cf83623e7bc57c4e13f3e92be673ab98cf49623e65623ed788f91c2ee6d34acc678b98cf24319f0bc57caac57c5688f90c16f3b947cce714319f1e623e3788f91c2be6d341cce74a319f19623e178bf98c15f3592de63342cce761319f47c47c968af9f417f3b95dcc679e984f67319febc47c8e14f36923e6b355cc678a98cf3a319f1a319fb3c47c2ac47cee13f35924e6d34bcce726319fe3c57c3a8af95c25e6334bcce712319ff1623ee78bf98c14f3794ccce70c319f81623e778af92c10f3e92ae6b34bcce768319fb6623edbc47ca689f96c10f3a913f35925e6334ccce701319f25623e7dc47c6e11f33951cc2725e673b598cf61623e45023e49f24810c3eb0f10c3ef1b3c480cbf2bb097187e77e02162cf5af96162cf59f91162cf5bf951622f58f931622f5af971622f59f90962c556e6fee2ba46febd06dc4bf06962f8fce41962b887c2b3c4f0bef13962f8eec8f3c4707fe41788e11a95178925ad8cfea4d7ffcb91fb5fc7f2c5b40cda6945ec254f7b2f7abc50e6fd11cb34260abb3f725b8df41ced9592c7f3223e8789f95c2de69312f33951cce716319f3e623e4bc47c1e10f31926e6b34acca74ecc678398cf34319f6d623e6dc57c8e16f3d925e6d355cc678198cf9d623e03c57cce10f3794ccc67a498cff9623ee3c57c2e11f39925e67395984f47319fe3c57c6e12f3e925e6b348cce73e319f0a319fb3c47c6ac47cd689f94c11f3d92ae6d346cce748319febc47c3a8bf9cc13f3b95dcca7bf98cf52319f47c47c1e16f31921e6b35acc67ac98cfc5623e33c47cae14f3e920e673ac98cf0d623e3dc47c4e11f3b947cc67b098cf0a319f6a319f0bc57c2689f96c11f36925e673b898cf35623e65623e2789f9dc2ae6d357cce734319fbd623e0f8af90c17f33947cca75ecce722319fe9623e5788f9b413f39923e6b35bcca79b98cf42319fbbc47ccac57cce14f3795ccc679498cf1a319f09623e9bc57c668bf9ec14f32915f33941cce766319fde623e8bc57cee17f3192ae673b6984fad98cf7a319fa9623e978bf99488f91c25e673bd984f17319ff9623e7788f90c10f35926e6f3a8984f9598cf79623ee3c47c3689f9cc14f3d921e69314f3394ecce746319f9e623ea78af9dc2be63344cc67a598cf18319fb5623e93c57c2e13f3692de6738498cfb5623e9dc47ce68af9dc26e6d34fcce774319f87c47c2ac57cce15f36910f3d928e6d328e6b35dcca7bd98cf31623e7bc47cba8bf99c2ce673b798cf20319fe5623e4f88f98c16f3b940cc67a298cfa5623ec58e4fa9f37afac1bf69504adecf04f2465b58379e3f430ef8fd8167c9e7d9403ecf393e6edb298acb0ba2314b117bce13c794c73b25e0cdfb634b6ceb171c1fb7ed54627f5c9e138d196feb173c712cf3789709782b8eeb32278e6a31cb35ae2b3cde1502de8ae3bac289a35acc728deb611eef6102de8ae37a981347b598e51ad7951eef4a016fc5715de9c4512d66b9c67595c7bb4ac05b715c573971548b59ae713dcae33d4ac05b715c8f72e2a816b35ce3badae35d2de0ad38aeab9d38aac52cd7b8aef178d708782b8eeb1a278e6a31cb35aeeb3cde7502de8ae3bace89a35acc728deb068f778380b7e2b86e70e2a816b35ce37aa2c77ba280b7e2b89ee8c4512d66b9c6f5248ff724016fc5713dc989a35acc728debc91eefc902de8ae37ab21347b598e51ad78b3cde8b04bc15c7f522278e6a31cb35ae177bbc170b782b8eebc54e1cd562966b5c2ff1782f11f0561cd74b9c38aac52cd7b8dee0f1de20e0ad38ae373871548b59ae71bdd1e3bd51c05b715c6f74e2a816b35ce37a93c77b9380b7e2b8dee4c4512d66b9c6f5668ff766016fc571bdd989a35acc728deb2d1eef2d02de8ae37a8b1347b598e51ad75b3dde5b05bc15c7f556278e6a31cb35aeb779bcb709782b8eeb6d4e1cd562966b5c6ff7786f17f0561cd7db9d38aac52cd7b8dee1f1de21e0ad38ae773871548b59ae71bdd3e3bd53c05b715cef74e2a816b35ce37a97c77b9780b7e2b8dee5c4512d66b9c6f56e8ff76e016fc571bddb89a35acc728deb3d1eef3d02de8ae37a8f1347b598f9c6753b2a17da67afad0bdf11dedb826d3fe2b4fd88d37692ca2f11c3b67b9158b16759fcf627eab7b7fe740cd41fdc0b0debc6f38e14cb506db775da6eebb49da2d78b5bc027e1f8249af0498af9b413f36925e6d35acca7bd984f1b319f0e623e25623e6dc57c8a047c92e4912086d75b112bb5726b62e84f1b6265562e21d6c9ca6d8975a6fe83157bfce0504a0c0e296270e0fb1ec0a11331387426a71175fb5f1f68bc989629b732c7639095391e83adccf1c0bd89391e15d436187ef387e381ef28b72786dfd2ed40ac92caf83bc2ca1c4b7c37926339d2ca1c4b7caf8e6339daca1ccb6a2b772636c6ca5d88e1fb3c5d89d55ab91b31ac672031b4574e0c5e8388c17f3031f4730831c483ef9900d7a1c4e0cadfb787eb7062b8f7196f831e561e410cf714e7eff9f6b2f24862f8ad2efe8e681f2b8f2686dfe4ae2686fb888e21d6dfcafcdd34fc3e472d3194795ec2328d89c2ce4bdc56233d477ba5e4512be2d356cca744cca783984f1b319ff6623eadc57c5a89f9b413f3498af914b7a00f8ef7587799e313b2ed52a7edd2166cbb8bd37697166cbb9bd376b7166cbb87d3768f166cbb97d376af166cbb8fd3769f166cbb9fd376bf166c7b80d3f680166c3bce2d716e69a9b6e3dca239b75417bcedb1357cde038fa6cec95593cf9882fbd4d486e9674d4d7abda3a97f855a6f7a5da39c58d538b14a519dd114bf5101e25744ed62dd783ecad3f6eb89c2c662e441c462a4c767640bc702ed45e7e81c9d0f2de7d1d1b9459ce3fe1c9da373748ef373dc37a273748ece6f0de7383fb78c73dc9fa373748ece717e8efb46748eced1f9ade11ce7e796718efb73748eced139cecf71df88ced1393abf359ce3fcdc32ce717f8eced1393ac7f939ee1bd1393a47e7b786739c9f5bc639eecfd1393a47e74371ae4bb75d55f0b69737249db6119f84e3834755e05884e9e7beef328e48f8638cf6525487f7d31101fa5944ed62dd783e82b643748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1393a47e7e81c9da373748eced1397fe774db95856fbb3ee9b48df8241c1f3c2a03c722503f6bd27d1a9ef0c718eda5a80e6ff3e101fa5944ed62dd783e9cb643740eef9ca2d78bc927c07e587b30638b7d7a8bf9f411f3e92ae6d34dcca793984f99984f7b319ffe623e03c47c7a8af9f412f3e928e6d345cca7b3984f52cca795984f6b319fbe623efdc47cba8bf9f410f34989f9948af97410f32911f3692be65324e0934cbcf99c55925e2f26869cbf33b16156ee446ca895cb885538fd4fb321562e2536d8ca1d890db2721762e556ee4a6ca095bb11abb3727762f556ee41acc1ca3d898db5722f62e3acdc9bd8782bf72136c1ca7d894db4723f6293acdc9fd8642b0f2036c5caed894db5720762d3a88cbfd3ad5c43acd1ca6388cdb07235b199561e496c9695ab88cdb6f20862d877785fc37ba4e1c4f03e6518b136561e4a0cf34905318ce921c4da59793031c46d1031c4ad9c18e2369018f6c53a62d867eb8961df6e208631309618c6ca38621853e389617f9f400cfbfb4462d8df2711c3fe3e9918f6f729c4b0bf4f2586fd9df725ecefd389617f6f2486fd7d0631ecef3389617f9f450cfb3bf6a5f4b67d62ecfed7b13ccf4968a715b1d99ef66679bc50e6797826f5a9d1ca35ffdd23330f735b8df41ced9592c70c119fb6623e25623e1dc47c4ac57c52623e3dc47cba8bf9f413f3e92be6d35acca795984f52cca7b3984f17319f8e623ebdc47c7a8af90c10f3e92fe6d35ecca74ccca793984f37319fae623e7dc47c7a8bf9147b7c3a07f269edf8e079e71668bbadd3765ba76d3e7f349b18de6ff0399662cfb2781f89faedad3f1d02f507ed61dd78ce9f5f846abbc469bbc4d3763240db7cbe118f22e7792395931e9f7685f3a949250e3c6f8cf59716beef757c0ef560face9fab9515dea79ecfdf1e8c0f5f77952abc4f6da07e66aedbede4f4a9d4e9532a71e06737e867a700fd2ca276b16e3cef44db213a87774efb604cf2e76fa8d751c491e317d0a72ee9f8a41f4dcd097c6d6897c2fbd4f3e74407e3c3d78a85781f12a89f9939aaabd3a74e4e9f5289033fe7453fbb06e86711b58b75e37957da0ed139bc338f7f9e3b51af4cc411ac73589fbaa4e3937e343527f0f5fddd0bef53cf9f471f8c0f5fdfd6adf03eb581fa9999a37a387deaeaf4299538f07a12f4b347807e1651bb58379ef7a0ed109dc33bf3f8e7b913f5ba883882750beb5397747cd28fa6e604bec6b457e17deaf9ba9783f1e1ef24f42cbc4f6da07ed6a4d78bf373af270a3bf7f57162d5c389558aeaf077eefa04885f11b58b75e339da8bce2de3ccf30acfc9a8d75dc411ac67589fbaa4e3937e3435d7f0f741fb15dea79eafd13b181ffe3e44dfc2fbd406ea67668eeaeff4a98fd3a754e2c06b6cd1cffe01fa5944ed62dd78de9fb643740eefcce39fafcf46bd5e228e60fc1da9106385af8fc6fad3d75abf641737a77d7b126fa4faade92fea5cd0b0bfee3beaf6bb877a6f8976f138d8f79601f2f1bcdf5b723e1e2aff0dd0cf1a3ea758c8cfa07ce7cd7b38b1e2f3e6ec10ea9cb47b8e0ccf9b3ad71f9d0bef9cf6c158e7f796a8d753c411ac5b589fba7ccfb5f1e713013ed3cdfbf309fe4c37d467a801fa9999a3924e9f3a397d4a511d1e3b21ae23284a1cf8d97563e2c0cfefb01da27378671efffcf904ea751571e4f805f4a9cbf7ba0ace0f02e4e3f5fc7dbe83f1e17cbc77e17d6a03f5333347f575fa9474fa94a23a3c7642e4f9be735978de97b643740eefcce39fbf138c7aa5228ebef39a017ceaf23d27c6f97880f303f5fc9dd983f1e17b5c05383f501ba89f99396a80d3a7be4e9f525487c7ce8000fdf49dcbc2f301b41da27378671eff7cbf04d4eb23e208c6e7c9438c15be5f01d69f3ebf36c06e3690f6ed4dbc91eae3daf0d654e792fafd75075999afe7c775c0fc9d66beff463787f1f9a0c64461b703dac2baf1bc3339e27c40376270e37b8e747658c873059d1d6f3ce71cc6d717b8f1bd4ddcebb242e5ccbef3427c6e038ebebec08defab927258c8bc27e578f37d65e0e8eb0bdcf89e2e4987857c2fe4e6b878de971c7d7d713fc3e4f70d7c2e2cc47b02dffb5e3cef478ebebec08daf8de9e7b0ffe5672fa559fad295caf0eeefb0ffe5f1a8344b5fe0c69f750d7058da7b60206ff7bd079e0f2447b72f21af0fc0778bf0dda9569e58846abbc469bbc4b36ddcbc87b7177f3f07f1e373e1e556f6dd2b8bef8135d8ca7c6cc4fd92f87b60b8af121f8b70ff253ebf85fb34f1dcefde0f3ccd2aadcc732ddf1f0a7f711f299edb465a99df0fe27ee73c978cb632df53abdaca3c76719f2bfe6cbad8cabc3db07ff0bdb7f0b927df130af7a72a2786ed3b8818de8f0d2686cf53f99e5578ffc6f7b6c2f6e77b60216e7caf2c6c7fbea716fa5e490cdb86b701f609be9717b6f54862d84f4611c37e329a18b60ddf430cfb22b601be5f18ea33628c253c0ee633e254e2c0f7d470c7eb7c5e22c467b7be6b5fddf7b97ced2bdf5b31c475a5858823df6f31c4f9549e63b16e3cef4dceb97225dea6458930dbb4b5e3d28d38eaecb2dcac5322d8761dcb0ec54e3cf87a890079520de749ad1307e61b1c27d4b98df25dcc7bad6cb9dece729c1360dd58a63df194b36ec43a403ebb92bddb38de1c07d4b98b9c7cb902e625ac83731cfe2c25546eeefab87de16d50e2d449527f51e741671b04c8b956720e806de0e629ada9ce23ce3670f3073e36a41f9caff179a10079585d53db00ed71aed6d436409da79d6d10200f5bc97981bb0dfa9313ea3cef6c0337a7f06d03f487738a00b9597d53db80cfc1a25f4d6d03d479a7b30d02e466996d506eeb72b7c14072429df73adb001c5ebe6d80fea06e3b2a37260ad69786a6b601da2ba27e35b50d50e79516da06c80d9ada06a8f3aab30dc0e1e5db06e823ea863c07972dbfe5f8e2f8f4693a07bdaa61bf2fe62dcefdba394ced7c73a0f747f5bef70b78efd289628a3a5f76f6d900dbb93ee439f301d4a7468a33f71575be41fbcfb7acccfb0a1fe37fe9791d8f83bd1ea5bcf07daef18dff724fdb83c9b5406dd772db45f60fed80f3dcf30b7aef8d7a8807625d6e7fd36304f317bbbbcb7573964b519d819efe37260adbff72c7a7dc714e6f93efd27e86fd28e4fc3330e18f517b8ad1402ae32fe6463ecf87d779de0cf59dd36c9fbff07900309e4b51eeeaf1ee2ae0cd9fd3f1f57221be9fd5d47c8ff678beff570bcdf7a13e4372e7fb6e9ebebef11e9abe57d2cacabcaf74a6b875f1bc8e479cef0f6ebeefdcb0bfae3b6f23d6e5f6f760e7fb94b39ce27c5f42fb19f6a390f3cfc02c31f2cdf77c7d1c7f4f23fde0cf7f437faf88cf2960dd78ce732518cfa55c76bd4b05bcf9fc0d5feb17e078dfe47cef3b1f38c4f6c7d0f37da8f736ee7c9ff2f415752a691c56d17ceeee53e9d7277a5ec723cef70737df4f6862be47accbedefc1cef77d9de514e7fbd1b49f4da4f93ed4fc33304b8c7cf33d5f9f89b9913fffe6eb98e0adf0fe9ee75294fb78bcfb0878f3b9627e7f1fe2daeea6e67b3eef8d3a47b7d07c1fea5a2b77beefebe92bea1c4fe3f044cffbf76e14b7a5f1fdbd37def9ccf7a73731dfbbe765de4aefefe7d17eb654ecfd7d6f62fcfda1f483afbfe07933d475a9bd1d6f3ce7b9d2fdcc9dcfe5878ca9ebe65eafc0e7f14b9c3a58b635d5399fe6d9a4a72e5f6baf762f0b3ef7576c7ff93a253ef7a7709d12ff2676a8eb94fedb38f2ef6487b8e75b5122fb3def7b9273aefbaeb4e4754aeef965be4e69bbf33e25c0761dc70ec54e3cf83aa500b9eb01f724c67b99ce4edbada9cef5746cc5fc8deb94dc7b5814250efc7cab3171e0fb50f04eceba11ebc2dfdfa5b68ebddb38de1c07d4b9819c7cefb9312f611d7cde9ffb1aea9ebdae8fdb17de06254e1dbe860c756e77b641e1ef33515be7cb15dc7c8f7385bb9d6de05e0f51ecf427dbb56201728cbaa6b601da2ba27e35b50d5067afb30d0a7f3de9be6d80f75aee36e0f711a8f3a8b30ddcef39fbb681fbfd8c50f73e686a1bf03d27d1afa6b601ea3ce36c83c2bf17ddb70ddcebf5dcf3b37cbdde0bce3670afd7f36d03f79ab9409f793534b50d9aba5ecfb70d50e75dce36287c2ebf6f1bb8d7ebc1c597cbbfec6c03f77a3ddf3668a1ebf5c636b50d9aba5ecfb70d50e7c32db40d902736b50d50e763ce3670f350df36401f39570ff53dd36cdfc3e2f8e23dc2672867df3b76bf2fe6ad5cdf4d0ef5be22dbb562fc5d41df779351c6f7798a136fbe6f58632258fcbde721ddcf13f9bdc5d75ae83c64a87d8daf27684c1c98f381a3ceb7695ffb2e9d6774cf63a75fff8de7753c0ef63c648039aec637570cf0b45d4eae056afb80735e380f8976f89a56947f4db912ea211e88357fc7d5bda6d8b75c3767b914d5e9efe97f6322cc796fac7b80e39cde263fa0fdec3774ce2cd467affdb3c488c73deaf87e138aaf2bc3f8e13936d47766b39d5be2f3a360beebcaca3cde6502de7c1cf05d1fc1c7863e4ebdc644b0e39af7d880f639f77f236fb3e371e86343a863b87b6ce8e6e92bea948cdd1f977656e6fd8aaf41ebe9791d8f786c38b863438fb1fbeba21ee28158e77b6ce8e12ca7786c48d27e86fd28e475f7fdb3c488e758f75e1769867994ef4180f1c373ecffeabb1a29627caf1af77e3aec1dfa77f30ec63b9fbca1b353af3111f61c927b6c40fb688f8f0d552d746c08750ccf9637705f51670c8dd95a9afbddfd2f1337cfeb78c463c3c11d1ba637716c40acdf8a794303ed678d746c28fc67104de70d3cc7a20e5fbf807994f3062cc3736ca8fb4064bbff1a3bf27c8bbf2877f7787717f0ce76df3894f9d8e07e1fbf31d1b2df5544fbbeef2ace6da16343a8f74cd9f206ee2bea9c4c63f6549afbddfd2f73fd8ce7753ce2b1e1e08e0d6737716c40acf33d36b8f986e2b16109ed67abe8d810ea3aacfe5962c4732ceaf075639847f95e635886e758a56bdbf83d792f8f774bdc2b3297371f07f878e1ded7b59896e1e358a0f711de6383fb9d1f3e365cda42c78650ef99dc6343674f5f51671b8dd9ed34f7fbaeadbcc9f33a1ef1d87070c7861b9b3836b8e7860ef6d8e0deef45f1d87015ed6737d1b121d435a1fdb3c488e758d4e1cfd6318ff2bd59307e788e0d754ccbf6fe9b3f3374cfb9f8cecdf0f9a3768970c701de867cdf2dbe2f20d7e1eb9650e7019a6f53d407befe796f0bbc9fe0eb761b136fbebe93cf9d953875f8da5dd4798cfa95f4d4e5df390cf4bd84cc75dd8312073e9a9aabe190a2e5782ce075bc96f61e5278efccf618ec38e2f9107204e3ebd702c431e3d3c6f169e3c42c64db6d9db6dbb660dbed9db6dbb760dbee75a4c9166cbbd469bbb405db2e73da2e6bc1b6b31d835aa2ed6cbf71d8126d7777daeede826d67fb4da296683bdb3de9f9588047710bf8241c9f44133e83c47ccac57c7a8bf9b4c4713a1f9f1e623e9dc47c3a8bf97410f3498af9b416f36923e6d312df03cfc7a7bf98cf00319f5e623eddc47cba8bf9a4c47ccac47cda89f9b417f36925e6d357cca79f984f4f319f2e623e5dc57c3a8af9f0bdc3147c4ac47cda8af91409f824136ffe0c833f9b282686cf0a5a11abb0726b6243adccbf6180df34e3df11c06f9ab5255699d81f1330fca6597b62f84d33fe1dbd9154c65ffca6197faf74b495f9bea5d556e67b34e137cdf87b473556e6fb2dd45a99af81b18fa20eb82edd6e3b74c0fdb1edeb62075c5b691f751d70dde2382bf3f5f9e3adccf75f986065beae65a295f97e8393acccbfad876dcdfb06b635ff9e1db635ff9e1db635ff9e1db635ff9e1db635ff9e1db67525316c6bfe3d3b6c6bfe3d3b6c6bdef6d8d6fc7b76d8d6fc7b76d8d6d5c4b0adc710c3b6ae21866d5d4b0cdbba8e18b6753d316ceb0662d8d66389615b8f23866d3d9e18b6f504623857399118ce1762dba7b7c5f727ec7f1dcbf398473b3ce62779da9be8f14299e7392cd39828ec3cc76d35d273b4574a1ee3457cda8af99488f9948af97414f3e92ae6d345cca7a7984f3f319fbe623eadc47cda8bf9b413f32913f34989f97417f3e926e6d34bcc6780984f7f319f81623e6dc47c5a8bf924c57c3a88f97416f3e924e6d343cca78f984f6f319f72319f41623ec52de883f36158f744c727ddf6b8c2b75d935eefd882af7779e67ea7385f89ef85c11fedb5a63a9fb11771cf4a7078e11ce238da3e880dea16d3ba793b15531dbcfeba71771d8d16ebc2c7a4a636bddefa82af775faceb9c58c3bf9e628d3a5f75620d9e70623d96628df8f0b96abcbf1b476d7fd39e04da5f97f1d8455f5d8fd654e73fe3f6d7fdeeb8fdfd196caf0fa2fe54382cdd87a185ef4366bca32dac1bcfd15eda119fa15490cfa0403e786f8cf9b08d2716a1da6eebb4ddb605db6eefb4ddbe05db4e3a6d275bb0ed52a7edd2166cbbcc69bbac05dbeeecb4ddb905dbeeeab4ddb505dbeeeeb4ddbd05dbeee3b4dda705dbeee7b4ddcf699bbfa3399818e65cfe1cbbd8b32cce41a37e7b6b2bdb310aef37f818553c7e7fddbd13f6c724c0f1732cbb1527fcc7cf30ef53f6dd2b80dffb35523b7cec7ee3336d134d2f87cfcdf15b2ae39de5f87d0cd68d65f85e0075ceba719f8900eff732f76d47ffb06eb4c3f9073c4b12d9dfbba14e27c7bbb6e0defef79370a9f5c4b21b3935f57e12eb28a5fea36e98beec9b035c1fb72fe93ab856a3c4a9c3fb14eaf475b6c198827befdb06b8ce04db002e63c80975063adb001c5e939cfe94527f50b798ca35149b625a0eaf237faa71d65b94f0ef0388e758aa8775351573d4a974625e4deb6e84f37ff7a8e36bae12e49970fa92706291f6195d789f7abeceec607c46934fe1f7c97df96b807e66ce41e0daabd70bb8de74ac463ab1aa766295a23aa3287e2303c4af88dac5baf11ced45e796714efb60acf3f57ca8572fe20836867c028cc126cf418e0edb764d3aeee54e5be963de11e3f7b71be0fd59e6de647ceeaa913cf87d2aea3c31617fdd39e6564aaff3359b750e6bc9f737788ef64aa93ffc7e2bc07bfc03f623e45c133db108d536fa89758f156bbbaef06dd704dab732e303f38efb1e94f300d459e4bc07058717c609bf07456c787e0b314e02bd67ace7791c31827f35c50875ce7062343a4b8c78ec22363c0f8778ffcbefc30a1da3914e8ce03f8a62843aab9c188dcc12a36a8a917bec0c79dce61ca6919e73db01ceddd4f2773d12e49070e283c7b8c0b1e0ef991c8c0fc727c07e56cbdfe939181f7e1f5a15c867541e3e55e43322904f551e3e23c8a73290cf883c7cf8bb5ec303f954e6e10387f4fb74f7589f66181b638861ffe4bc08fb4803316ca7f1c410ab6262f0c57998526283ec2f6f773ee71e620c16250edcc71ae9f92872445faac2fa4c601ff77c378fff10d756f0b10be7a4c7396df371ef763adf8d7dab559618facea563193edf3dd6597727a7bf388615a0bfb561f2b4b19938e23b816d9c78700c50e71ea7afc3023805ca4933e367a8b35d4778fa8a3a0fd267470f59998f839514b7173dafe3d1d43c87f8a5fb1ce07ea399ed3b983c1ba91d6e7b32b916a8ed03ee758a73d76807bc35955fa0318a7a8807620df7f43c87cf05d9dd5d6ea4b35c8aea5478fadf98286cff87383e431ce7f4367994f6b317e9bc4c88e3b0effa18c4a88a62843a3c978d7096437dfeac07dba9c4a983655b539d77b7c05cc2631efb3f5c869113eabccf712afc354afbe6b7c2f7f5c06deb1eb7b8afa8f30aed771fa1f90bdb8cf3ca2f795ec7a3a9f90df10b745f851a1ef3d8be833d6d4f21d702b55dcb6d637e433be0ada9fc459adf500ff140ace1ced7a8b1bbbb5c95b35c8aea0cf1f4bf3111667ec7ba073bcee96df231dacfbe44f35b88bcc737e7ba73508aead4536cddeb09509fe7378ca712a70e5f4f803adf70e692c29f27f0cf6f70e1f7c7a8f39d169adf429d1f72e7b74a4f5f51e787b4dffd98e62f373f4abffe27cfeb78c4f9ede0e6b73f3631bfb9f3d4c1ce6f239ce514e7b79fd17ef6a71678ff36244b8cf8fc08ea8ca1d8ba9f19f8aed571dfbfb99f21f0fbb77f3a7349e1cff3f9e737b8549113eafca785e6b710e7349b7affc67d7da30e7d665a42f78ec1361b4171ebee791d8f38bf1ddcfcd66dc2febab9e6a9839ddfea9de514e7b7f6b49f75a76b685beafd9b3b07f1fc369a623bdc590ef5797ec3762a71ea60d9d654a79ff5157349e1afcff0cf6fc39dbef1fc56ee38859adf425d0793edfd1bf7f58defebd07e379ce62f6cb37a8adb38cfeb78c4f9ede0e6b7b14dcc6fee3c75b0f3db186739c5f9ad8af6b37134bf85f89cd037bfb97310cf6f0d14db4a6739d4e7f90ddba9c4a983655b539da92d3097f098c7fe0f173e178f3a331ca78a004e61fa7ae0b6753f5fe0bea2cee1b4df1d49f317b6195f1fb4d0f33a1e4dcd6f81cf71d7f098c7f6f59d5f9f4aae056abb96dbc6fc8676c05b537901cd6fa8877820d670e7efb1b2bbbbdc7067b914d519ece97f6322ccfc8e754f769c33d753d27eb690e6b750d7ea0dce12a34a8a11eaf07775dccf17509fe7376ca712a70e7fbe803aa73973c9f882f7d73fbf8d70fac6f3db192d34bf15beaffef9added357d4398bf6bb55347f619b0da7b85dec791d8f38bf1ddcfcb6b189f9cd9da70e767eab7496539cdf56d37e7631cd6f21bea7e39bdfdc3988e7b7e2c4fed816faf385ad2d3097f098773f5fe05c0e75b63b4e85bfa661dffc56f8be1eb86d31bf8df1f41575aea6fdee5a9abfb0cdf8fa903b3dafe3d1d4fc163847aae1318fedebcbcfa6916b81daaee5b631bfa11df0d654be83e637d4433c106bb8a7e737cc15ecee2e37c2592e4575267bfadf980833bf63dd531ce7f436d945fbd99d34bf85fa7c61729618f1e70ba853436c9095f93ef15886af8d0c352fbbf3abefbc2118bff7087c5f8003ee898575bbf705e06b0e4b9c3afcde0a751ea37936e9a9cbf70bcaf63daa5a8785dc36680bebc673b4c7dfa3e2e3a1bb5cb995f93bd16e4e50eeac877382179de353e1bfebb1effbe5f97c6fe51de4c4cbc26b92d39f16fcde4ae6fb25a39cbe947bfa823a2f3bf10df19d97407dadf55d533cd6d357d4f910cdcb1fa6e33bb6137ffff18b9ed7f168eaf8cfd75107381f59c3e715ddfc95db1e4eae056abb96dbc6f1df77be12e52fd0f1dffdac07b1867b7a8ce03353767797ab75964b25defc996bc863ad7bce6384e39cde26afd27ef6453a5685fa8ca62a4b8cca2946a8c3df2d0c75ec74bffb090f3e76663b06f075dda8f30d9aa3f83d01ff7e8cfb1953a0b9ac96ddb16e3c477ba9c49be7fba4a78feef7bafb06f26de3f8e239ffa660a8b6db3a6db76dc1b6db3b6db76fc1b6934edbc9166cbbd469bbb405db2e73da2e6bc1b63b3b6d776ec1b6bb3a6d776dc1b6bb3b6d776fc1b6fb386df769a2edf282b5bdbc21bdde0105efd3f286f438ed9738f0d1d4fb3dfe9deafe05f7a9a9ed60eb4e3fce5ab1feb835eb57ac2b222fb8bee6b816250ef4c6eb9d881553b9152dd7dac34a3cac9d8775f0b08e1e96f2b04e1ed6c5c3ba392cfde841e59e54ee45e5beb40edc7fdc1717d4e1f8b57a8b70f7916d3f0933be9abebfee8016683bdbfd755ba2ed6cf7d76d89b6b3dd5fb725dace767fdd96683bdbfd755ba2ed6cf7d76d89b6b3dd5fb725dace767fdd96683bdbfd75d15e92cafcfbad381fdb9f58b16759cca3a88f7bdc1ef0682c60877842771f7cb09fe3a9778ef5001f52cc5dbf66edb2b35694af5bbd667d794df9f9fff7ffb2d5abd76c5cb1bcba9c5f5b577ede8675ebcbd7ad5fb6767df9cab56bce2bafade6f576b188e0203a63edda659bca579dbf7cc5c5e56b36ac2f5fb3b2fc8c351bce5fbe8e17ea670b21eacbd6af5f71de05ebcbd7af295fb67c79f9c655ebcf2e5f73d18ab52bff4f88977b9f7d9437e8cdcb9db761f5fa5517acde947de10f5534c3f473ff4d8baf5534af9b5f6b8ee90f9ad9d8adf5ff450fefac6f86e903f5cd337db8398d3dd5ccc69e6b4e63ef686663ef694e631f6a66631f6d4e63af3567a17f3667a1c10dcd58e8a8e62c745e43f302789d2dd7ac11b3a739a6b735d3f4aee634f660331b7ba4398d3dddccc69e6f4e63ef6c6663ef6d4e63af34b3b1579bd3d8579bb3104e3ee7b5d088e62c74527316dadc9c85ee1fdbbca83fdacce53e3dae19925f69ce421decd38166cd3a65e39bd7bdaee39b61daa7998d0d684e63c39bd9d8a9cd696c5973163abb390bddf6df6cedbb9bd3e2bb9a19c8979bd3d8d79bd9d8b79bd3d83f9ad9d8ebcd69acef84e635367042331a9bd2ccc61a9bd3d8926636b6ac398d5dd6ccc6ae684e638f36b3b1179ab9dcdb9b23f9dee62cf4f53c0c13ff0f8f97b7576c8b0900>, + "metadataHash": Fr<0x1125672f40d49b4b192a803a41ccb3ddacec4da05bf7d535224059fa9bf766cd>, + "selector": Selector<0x511c8a6f>, + }, +} +`; diff --git a/yarn-project/circuits.js/src/contract/contract_class_registered_event.test.ts b/yarn-project/circuits.js/src/contract/events/contract_class_registered_event.test.ts similarity index 90% rename from yarn-project/circuits.js/src/contract/contract_class_registered_event.test.ts rename to yarn-project/circuits.js/src/contract/events/contract_class_registered_event.test.ts index 295f65c40c0e..dc2819e4852c 100644 --- a/yarn-project/circuits.js/src/contract/contract_class_registered_event.test.ts +++ b/yarn-project/circuits.js/src/contract/events/contract_class_registered_event.test.ts @@ -1,5 +1,5 @@ -import { getSampleContractClassRegisteredEventPayload } from '../tests/fixtures.js'; -import { computePublicBytecodeCommitment } from './contract_class_id.js'; +import { getSampleContractClassRegisteredEventPayload } from '../../tests/fixtures.js'; +import { computePublicBytecodeCommitment } from '../contract_class_id.js'; import { ContractClassRegisteredEvent } from './contract_class_registered_event.js'; describe('ContractClassRegisteredEvent', () => { diff --git a/yarn-project/circuits.js/src/contract/contract_class_registered_event.ts b/yarn-project/circuits.js/src/contract/events/contract_class_registered_event.ts similarity index 94% rename from yarn-project/circuits.js/src/contract/contract_class_registered_event.ts rename to yarn-project/circuits.js/src/contract/events/contract_class_registered_event.ts index 1c028930a4f0..016dd1cbfb40 100644 --- a/yarn-project/circuits.js/src/contract/contract_class_registered_event.ts +++ b/yarn-project/circuits.js/src/contract/events/contract_class_registered_event.ts @@ -7,9 +7,9 @@ import { ContractClassPublic } from '@aztec/types/contracts'; import chunk from 'lodash.chunk'; -import { REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE } from '../constants.gen.js'; -import { computeContractClassId, computePublicBytecodeCommitment } from './contract_class_id.js'; -import { unpackBytecode } from './public_bytecode.js'; +import { REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE } from '../../constants.gen.js'; +import { computeContractClassId, computePublicBytecodeCommitment } from '../contract_class_id.js'; +import { unpackBytecode } from '../public_bytecode.js'; /** Event emitted from the ContractClassRegisterer. */ export class ContractClassRegisteredEvent { @@ -80,6 +80,8 @@ export class ContractClassRegisteredEvent { privateFunctionsRoot: this.privateFunctionsRoot, publicFunctions: unpackBytecode(this.packedPublicBytecode), version: this.version, + privateFunctions: [], + unconstrainedFunctions: [], }; } } diff --git a/yarn-project/circuits.js/src/contract/contract_instance_deployed_event.test.ts b/yarn-project/circuits.js/src/contract/events/contract_instance_deployed_event.test.ts similarity index 96% rename from yarn-project/circuits.js/src/contract/contract_instance_deployed_event.test.ts rename to yarn-project/circuits.js/src/contract/events/contract_instance_deployed_event.test.ts index c7081791b4c6..031fbf9a8f3e 100644 --- a/yarn-project/circuits.js/src/contract/contract_instance_deployed_event.test.ts +++ b/yarn-project/circuits.js/src/contract/events/contract_instance_deployed_event.test.ts @@ -1,4 +1,4 @@ -import { getSampleContractInstanceDeployedEventPayload } from '../tests/fixtures.js'; +import { getSampleContractInstanceDeployedEventPayload } from '../../tests/fixtures.js'; import { ContractInstanceDeployedEvent } from './contract_instance_deployed_event.js'; describe('ContractInstanceDeployedEvent', () => { diff --git a/yarn-project/circuits.js/src/contract/contract_instance_deployed_event.ts b/yarn-project/circuits.js/src/contract/events/contract_instance_deployed_event.ts similarity index 98% rename from yarn-project/circuits.js/src/contract/contract_instance_deployed_event.ts rename to yarn-project/circuits.js/src/contract/events/contract_instance_deployed_event.ts index 67404dba4eb1..b307070424e4 100644 --- a/yarn-project/circuits.js/src/contract/contract_instance_deployed_event.ts +++ b/yarn-project/circuits.js/src/contract/events/contract_instance_deployed_event.ts @@ -5,7 +5,7 @@ import { Fr } from '@aztec/foundation/fields'; import { BufferReader } from '@aztec/foundation/serialize'; import { ContractInstanceWithAddress } from '@aztec/types/contracts'; -import { DEPLOYER_CONTRACT_ADDRESS, DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE } from '../constants.gen.js'; +import { DEPLOYER_CONTRACT_ADDRESS, DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE } from '../../constants.gen.js'; /** Event emitted from the ContractInstanceDeployer. */ export class ContractInstanceDeployedEvent { diff --git a/yarn-project/circuits.js/src/contract/events/private_function_broadcasted_event.test.ts b/yarn-project/circuits.js/src/contract/events/private_function_broadcasted_event.test.ts new file mode 100644 index 000000000000..4b8c246db464 --- /dev/null +++ b/yarn-project/circuits.js/src/contract/events/private_function_broadcasted_event.test.ts @@ -0,0 +1,13 @@ +import { setupCustomSnapshotSerializers } from '@aztec/foundation/testing'; + +import { getSamplePrivateFunctionBroadcastedEventPayload } from '../../tests/fixtures.js'; +import { PrivateFunctionBroadcastedEvent } from './private_function_broadcasted_event.js'; + +describe('PrivateFunctionBroadcastedEvent', () => { + beforeAll(() => setupCustomSnapshotSerializers(expect)); + it('parses an event as emitted by the ContractClassRegisterer', () => { + const data = getSamplePrivateFunctionBroadcastedEventPayload(); + const event = PrivateFunctionBroadcastedEvent.fromLogData(data); + expect(event).toMatchSnapshot(); + }); +}); diff --git a/yarn-project/circuits.js/src/contract/events/private_function_broadcasted_event.ts b/yarn-project/circuits.js/src/contract/events/private_function_broadcasted_event.ts new file mode 100644 index 000000000000..a11c23de56d0 --- /dev/null +++ b/yarn-project/circuits.js/src/contract/events/private_function_broadcasted_event.ts @@ -0,0 +1,130 @@ +import { FunctionSelector, bufferFromFields } from '@aztec/foundation/abi'; +import { AztecAddress } from '@aztec/foundation/aztec-address'; +import { toBigIntBE } from '@aztec/foundation/bigint-buffer'; +import { Fr } from '@aztec/foundation/fields'; +import { BufferReader, Tuple } from '@aztec/foundation/serialize'; +import { ExecutablePrivateFunctionWithMembershipProof, PrivateFunction } from '@aztec/types/contracts'; + +import chunk from 'lodash.chunk'; + +import { + ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, + FUNCTION_TREE_HEIGHT, + MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, + REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE, + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS, + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE, +} from '../../constants.gen.js'; + +/** Event emitted from the ContractClassRegisterer. */ +export class PrivateFunctionBroadcastedEvent { + constructor( + public readonly contractClassId: Fr, + public readonly artifactMetadataHash: Fr, + public readonly unconstrainedFunctionsArtifactTreeRoot: Fr, + public readonly privateFunctionTreeSiblingPath: Tuple, + public readonly privateFunctionTreeLeafIndex: number, + public readonly artifactFunctionTreeSiblingPath: Tuple, + public readonly artifactFunctionTreeLeafIndex: number, + public readonly privateFunction: BroadcastedPrivateFunction, + ) {} + + static isPrivateFunctionBroadcastedEvent(log: Buffer) { + return toBigIntBE(log.subarray(0, 32)) == REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE; + } + + static fromLogs(logs: { contractAddress: AztecAddress; data: Buffer }[], registererContractAddress: AztecAddress) { + return logs + .filter(log => PrivateFunctionBroadcastedEvent.isPrivateFunctionBroadcastedEvent(log.data)) + .filter(log => log.contractAddress.equals(registererContractAddress)) + .map(log => this.fromLogData(log.data)); + } + + static fromLogData(log: Buffer) { + if (!this.isPrivateFunctionBroadcastedEvent(log)) { + throw new Error( + `Log data for PrivateFunctionBroadcastedEvent is not prefixed with magic value 0x${REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE}`, + ); + } + + const expectedLength = + 32 * + (MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS + + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS); + if (log.length !== expectedLength) { + throw new Error( + `Unexpected PrivateFunctionBroadcastedEvent log length: got ${log.length} but expected ${expectedLength}`, + ); + } + + const reader = new BufferReader(log.subarray(32)); + const event = PrivateFunctionBroadcastedEvent.fromBuffer(reader); + if (!reader.isEmpty()) { + throw new Error( + `Unexpected data after parsing PrivateFunctionBroadcastedEvent: ${reader.readToEnd().toString('hex')}`, + ); + } + + return event; + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + const contractClassId = reader.readObject(Fr); + const artifactMetadataHash = reader.readObject(Fr); + const unconstrainedFunctionsArtifactTreeRoot = reader.readObject(Fr); + const privateFunctionTreeSiblingPath = reader.readArray(FUNCTION_TREE_HEIGHT, Fr); + const privateFunctionTreeLeafIndex = reader.readObject(Fr).toNumber(); + const artifactFunctionTreeSiblingPath = reader.readArray(ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, Fr); + const artifactFunctionTreeLeafIndex = reader.readObject(Fr).toNumber(); + const privateFunction = BroadcastedPrivateFunction.fromBuffer(reader); + + return new PrivateFunctionBroadcastedEvent( + contractClassId, + artifactMetadataHash, + unconstrainedFunctionsArtifactTreeRoot, + privateFunctionTreeSiblingPath, + privateFunctionTreeLeafIndex, + artifactFunctionTreeSiblingPath, + artifactFunctionTreeLeafIndex, + privateFunction, + ); + } + + toFunctionWithMembershipProof(): ExecutablePrivateFunctionWithMembershipProof { + return { + ...this.privateFunction, + bytecode: this.privateFunction.bytecode, + functionMetadataHash: this.privateFunction.metadataHash, + artifactMetadataHash: this.artifactMetadataHash, + unconstrainedFunctionsArtifactTreeRoot: this.unconstrainedFunctionsArtifactTreeRoot, + privateFunctionTreeSiblingPath: this.privateFunctionTreeSiblingPath, + privateFunctionTreeLeafIndex: this.privateFunctionTreeLeafIndex, + artifactTreeSiblingPath: this.artifactFunctionTreeSiblingPath.filter(fr => !fr.isZero()), + artifactTreeLeafIndex: this.artifactFunctionTreeLeafIndex, + }; + } +} + +export class BroadcastedPrivateFunction implements PrivateFunction { + constructor( + /** Selector of the function. Calculated as the hash of the method name and parameters. The specification of this is not enforced by the protocol. */ + public readonly selector: FunctionSelector, + /** Artifact metadata hash */ + public readonly metadataHash: Fr, + /** Hash of the verification key associated to this private function. */ + public readonly vkHash: Fr, + /** ACIR and Brillig bytecode */ + public readonly bytecode: Buffer, + ) {} + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + const selector = FunctionSelector.fromField(reader.readObject(Fr)); + const metadataHash = reader.readObject(Fr); + const vkHash = reader.readObject(Fr); + const encodedBytecode = reader.readBytes(MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS * 32); + const bytecode = bufferFromFields(chunk(encodedBytecode, Fr.SIZE_IN_BYTES).map(Buffer.from).map(Fr.fromBuffer)); + return new BroadcastedPrivateFunction(selector, metadataHash, vkHash, bytecode); + } +} diff --git a/yarn-project/circuits.js/src/contract/events/unconstrained_function_broadcasted_event.test.ts b/yarn-project/circuits.js/src/contract/events/unconstrained_function_broadcasted_event.test.ts new file mode 100644 index 000000000000..d12e1399220b --- /dev/null +++ b/yarn-project/circuits.js/src/contract/events/unconstrained_function_broadcasted_event.test.ts @@ -0,0 +1,13 @@ +import { setupCustomSnapshotSerializers } from '@aztec/foundation/testing'; + +import { getSampleUnconstrainedFunctionBroadcastedEventPayload } from '../../tests/fixtures.js'; +import { UnconstrainedFunctionBroadcastedEvent } from './unconstrained_function_broadcasted_event.js'; + +describe('UnconstrainedFunctionBroadcastedEvent', () => { + beforeAll(() => setupCustomSnapshotSerializers(expect)); + it('parses an event as emitted by the ContractClassRegisterer', () => { + const data = getSampleUnconstrainedFunctionBroadcastedEventPayload(); + const event = UnconstrainedFunctionBroadcastedEvent.fromLogData(data); + expect(event).toMatchSnapshot(); + }); +}); diff --git a/yarn-project/circuits.js/src/contract/events/unconstrained_function_broadcasted_event.ts b/yarn-project/circuits.js/src/contract/events/unconstrained_function_broadcasted_event.ts new file mode 100644 index 000000000000..dfb286a7464d --- /dev/null +++ b/yarn-project/circuits.js/src/contract/events/unconstrained_function_broadcasted_event.ts @@ -0,0 +1,118 @@ +import { FunctionSelector, bufferFromFields } from '@aztec/foundation/abi'; +import { AztecAddress } from '@aztec/foundation/aztec-address'; +import { toBigIntBE } from '@aztec/foundation/bigint-buffer'; +import { Fr } from '@aztec/foundation/fields'; +import { BufferReader, Tuple } from '@aztec/foundation/serialize'; +import { UnconstrainedFunction, UnconstrainedFunctionWithMembershipProof } from '@aztec/types/contracts'; + +import chunk from 'lodash.chunk'; + +import { + ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, + MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS, + REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE, + REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS, + REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE, +} from '../../constants.gen.js'; + +/** Event emitted from the ContractClassRegisterer. */ +export class UnconstrainedFunctionBroadcastedEvent { + constructor( + public readonly contractClassId: Fr, + public readonly artifactMetadataHash: Fr, + public readonly privateFunctionsArtifactTreeRoot: Fr, + public readonly artifactFunctionTreeSiblingPath: Tuple, + public readonly artifactFunctionTreeLeafIndex: number, + public readonly unconstrainedFunction: BroadcastedUnconstrainedFunction, + ) {} + + static isUnconstrainedFunctionBroadcastedEvent(log: Buffer) { + return toBigIntBE(log.subarray(0, 32)) == REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE; + } + + static fromLogs(logs: { contractAddress: AztecAddress; data: Buffer }[], registererContractAddress: AztecAddress) { + return logs + .filter(log => UnconstrainedFunctionBroadcastedEvent.isUnconstrainedFunctionBroadcastedEvent(log.data)) + .filter(log => log.contractAddress.equals(registererContractAddress)) + .map(log => this.fromLogData(log.data)); + } + + static fromLogData(log: Buffer) { + if (!this.isUnconstrainedFunctionBroadcastedEvent(log)) { + throw new Error( + `Log data for UnconstrainedFunctionBroadcastedEvent is not prefixed with magic value 0x${REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE}`, + ); + } + + const expectedLength = + 32 * + (MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + + REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS); + if (log.length !== expectedLength) { + throw new Error( + `Unexpected UnconstrainedFunctionBroadcastedEvent log length: got ${log.length} but expected ${expectedLength}`, + ); + } + + const reader = new BufferReader(log.subarray(32)); + const event = UnconstrainedFunctionBroadcastedEvent.fromBuffer(reader); + if (!reader.isEmpty()) { + throw new Error( + `Unexpected data after parsing UnconstrainedFunctionBroadcastedEvent: ${reader.readToEnd().toString('hex')}`, + ); + } + + return event; + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + const contractClassId = reader.readObject(Fr); + const artifactMetadataHash = reader.readObject(Fr); + const privateFunctionsArtifactTreeRoot = reader.readObject(Fr); + const artifactFunctionTreeSiblingPath = reader.readArray(ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, Fr); + const artifactFunctionTreeLeafIndex = reader.readObject(Fr).toNumber(); + const unconstrainedFunction = BroadcastedUnconstrainedFunction.fromBuffer(reader); + + return new UnconstrainedFunctionBroadcastedEvent( + contractClassId, + artifactMetadataHash, + privateFunctionsArtifactTreeRoot, + artifactFunctionTreeSiblingPath, + artifactFunctionTreeLeafIndex, + unconstrainedFunction, + ); + } + + toFunctionWithMembershipProof(): UnconstrainedFunctionWithMembershipProof { + return { + ...this.unconstrainedFunction, + bytecode: this.unconstrainedFunction.bytecode, + functionMetadataHash: this.unconstrainedFunction.metadataHash, + artifactMetadataHash: this.artifactMetadataHash, + privateFunctionsArtifactTreeRoot: this.privateFunctionsArtifactTreeRoot, + artifactTreeSiblingPath: this.artifactFunctionTreeSiblingPath.filter(fr => !fr.isZero()), + artifactTreeLeafIndex: this.artifactFunctionTreeLeafIndex, + }; + } +} + +export class BroadcastedUnconstrainedFunction implements UnconstrainedFunction { + constructor( + /** Selector of the function. Calculated as the hash of the method name and parameters. The specification of this is not enforced by the protocol. */ + public readonly selector: FunctionSelector, + /** Artifact metadata hash */ + public readonly metadataHash: Fr, + /** Brillig bytecode */ + public readonly bytecode: Buffer, + ) {} + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + const selector = FunctionSelector.fromField(reader.readObject(Fr)); + const metadataHash = reader.readObject(Fr); + const encodedBytecode = reader.readBytes(MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS * 32); + const bytecode = bufferFromFields(chunk(encodedBytecode, Fr.SIZE_IN_BYTES).map(Buffer.from).map(Fr.fromBuffer)); + return new BroadcastedUnconstrainedFunction(selector, metadataHash, bytecode); + } +} diff --git a/yarn-project/circuits.js/src/contract/index.ts b/yarn-project/circuits.js/src/contract/index.ts index 2fddca8e7673..77d9e665e4af 100644 --- a/yarn-project/circuits.js/src/contract/index.ts +++ b/yarn-project/circuits.js/src/contract/index.ts @@ -2,8 +2,12 @@ export * from './artifact_hash.js'; export * from './contract_address.js'; export * from './contract_class.js'; export * from './contract_class_id.js'; -export * from './contract_class_registered_event.js'; +export * from './events/contract_class_registered_event.js'; export * from './contract_instance.js'; -export * from './contract_instance_deployed_event.js'; +export * from './events/contract_instance_deployed_event.js'; +export * from './events/private_function_broadcasted_event.js'; +export * from './events/unconstrained_function_broadcasted_event.js'; export * from './private_function.js'; export * from './public_bytecode.js'; +export * from './private_function_membership_proof.js'; +export * from './unconstrained_function_membership_proof.js'; diff --git a/yarn-project/circuits.js/src/contract/private_function.test.ts b/yarn-project/circuits.js/src/contract/private_function.test.ts index 1d4487b744bd..e39d828bf3bf 100644 --- a/yarn-project/circuits.js/src/contract/private_function.test.ts +++ b/yarn-project/circuits.js/src/contract/private_function.test.ts @@ -8,8 +8,8 @@ import { computePrivateFunctionsRoot, computePrivateFunctionsTree } from './priv describe('PrivateFunction', () => { setupCustomSnapshotSerializers(expect); const privateFunctions: PrivateFunction[] = [ - { selector: makeSelector(1), vkHash: fr(2), isInternal: false }, - { selector: makeSelector(3), vkHash: fr(4), isInternal: false }, + { selector: makeSelector(1), vkHash: fr(2) }, + { selector: makeSelector(3), vkHash: fr(4) }, ]; it('computes merkle tree', () => { diff --git a/yarn-project/circuits.js/src/contract/private_function.ts b/yarn-project/circuits.js/src/contract/private_function.ts index 0e7bde1cdc9b..ffc5a90b5f9c 100644 --- a/yarn-project/circuits.js/src/contract/private_function.ts +++ b/yarn-project/circuits.js/src/contract/private_function.ts @@ -3,8 +3,7 @@ import { Fr } from '@aztec/foundation/fields'; import { PrivateFunction } from '@aztec/types/contracts'; import { FUNCTION_TREE_HEIGHT, GeneratorIndex } from '../constants.gen.js'; -import { MerkleTree } from '../merkle/merkle_tree.js'; -import { MerkleTreeCalculator } from '../merkle/merkle_tree_calculator.js'; +import { MerkleTree, MerkleTreeCalculator } from '../merkle/index.js'; // Memoize the merkle tree calculators to avoid re-computing the zero-hash for each level in each call let privateFunctionTreeCalculator: MerkleTreeCalculator | undefined; diff --git a/yarn-project/circuits.js/src/contract/private_function_membership_proof.test.ts b/yarn-project/circuits.js/src/contract/private_function_membership_proof.test.ts new file mode 100644 index 000000000000..2cecfdf4cb42 --- /dev/null +++ b/yarn-project/circuits.js/src/contract/private_function_membership_proof.test.ts @@ -0,0 +1,48 @@ +import { ContractArtifact, FunctionArtifact, FunctionSelector, FunctionType } from '@aztec/foundation/abi'; +import { Fr } from '@aztec/foundation/fields'; +import { ContractClass } from '@aztec/types/contracts'; + +import { getSampleContractArtifact } from '../tests/fixtures.js'; +import { computeVerificationKeyHash, getContractClassFromArtifact } from './contract_class.js'; +import { ContractClassIdPreimage } from './contract_class_id.js'; +import { + createPrivateFunctionMembershipProof, + isValidPrivateFunctionMembershipProof, +} from './private_function_membership_proof.js'; + +describe('private_function_membership_proof', () => { + let artifact: ContractArtifact; + let contractClass: ContractClass & ContractClassIdPreimage; + let privateFunction: FunctionArtifact; + let vkHash: Fr; + let selector: FunctionSelector; + + beforeAll(() => { + artifact = getSampleContractArtifact(); + contractClass = getContractClassFromArtifact(artifact); + privateFunction = artifact.functions.findLast(fn => fn.functionType === FunctionType.SECRET)!; + vkHash = computeVerificationKeyHash(privateFunction.verificationKey!); + selector = FunctionSelector.fromNameAndParameters(privateFunction); + }); + + it('computes and verifies a proof', () => { + const proof = createPrivateFunctionMembershipProof(selector, artifact); + const fn = { ...privateFunction, ...proof, selector, vkHash }; + expect(isValidPrivateFunctionMembershipProof(fn, contractClass)).toBeTruthy(); + }); + + test.each([ + 'artifactTreeSiblingPath', + 'artifactMetadataHash', + 'functionMetadataHash', + 'unconstrainedFunctionsArtifactTreeRoot', + 'privateFunctionTreeSiblingPath', + ] as const)('fails proof if %s is mangled', field => { + const proof = createPrivateFunctionMembershipProof(selector, artifact); + const original = proof[field]; + const mangled = Array.isArray(original) ? [Fr.random(), ...original.slice(1)] : Fr.random(); + const wrong = { ...proof, [field]: mangled }; + const fn = { ...privateFunction, ...wrong, selector, vkHash }; + expect(isValidPrivateFunctionMembershipProof(fn, contractClass)).toBeFalsy(); + }); +}); diff --git a/yarn-project/circuits.js/src/contract/private_function_membership_proof.ts b/yarn-project/circuits.js/src/contract/private_function_membership_proof.ts new file mode 100644 index 000000000000..bd11a3a98672 --- /dev/null +++ b/yarn-project/circuits.js/src/contract/private_function_membership_proof.ts @@ -0,0 +1,158 @@ +import { ContractArtifact, FunctionSelector, FunctionType } from '@aztec/foundation/abi'; +import { Fr } from '@aztec/foundation/fields'; +import { createDebugLogger } from '@aztec/foundation/log'; +import { + ContractClassPublic, + ExecutablePrivateFunctionWithMembershipProof, + PrivateFunctionMembershipProof, +} from '@aztec/types/contracts'; + +import { computeRootFromSiblingPath } from '../merkle/index.js'; +import { + computeArtifactFunctionTree, + computeArtifactHash, + computeArtifactHashPreimage, + computeFunctionArtifactHash, + computeFunctionMetadataHash, + getArtifactMerkleTreeHasher, +} from './artifact_hash.js'; +import { getContractClassPrivateFunctionFromArtifact } from './contract_class.js'; +import { computePrivateFunctionLeaf, computePrivateFunctionsTree } from './private_function.js'; + +/** + * Creates a membership proof for a private function in a contract class, to be verified via `isValidPrivateFunctionMembershipProof`. + * @param selector - Selector of the function to create the proof for. + * @param artifact - Artifact of the contract class where the function is defined. + */ +export function createPrivateFunctionMembershipProof( + selector: FunctionSelector, + artifact: ContractArtifact, +): PrivateFunctionMembershipProof { + const log = createDebugLogger('aztec:circuits:function_membership_proof'); + + // Locate private function definition and artifact + const privateFunctions = artifact.functions + .filter(fn => fn.functionType === FunctionType.SECRET) + .map(getContractClassPrivateFunctionFromArtifact); + const privateFunction = privateFunctions.find(fn => fn.selector.equals(selector)); + const privateFunctionArtifact = artifact.functions.find(fn => selector.equals(fn)); + if (!privateFunction || !privateFunctionArtifact) { + throw new Error(`Private function with selector ${selector.toString()} not found`); + } + + // Compute preimage for the artifact hash + const { unconstrainedFunctionRoot: unconstrainedFunctionsArtifactTreeRoot, metadataHash: artifactMetadataHash } = + computeArtifactHashPreimage(artifact); + + // We need two sibling paths because private function information is split across two trees: + // The "private function tree" captures the selectors and verification keys, and is used in the kernel circuit for verifying the proof generated by the app circuit. + const functionLeaf = computePrivateFunctionLeaf(privateFunction); + const functionsTree = computePrivateFunctionsTree(privateFunctions); + const functionsTreeLeafIndex = functionsTree.getIndex(functionLeaf); + const functionsTreeSiblingPath = functionsTree.getSiblingPath(functionsTreeLeafIndex).map(Fr.fromBuffer); + + // And the "artifact tree" captures function bytecode and metadata, and is used by the pxe to check that its executing the code it's supposed to be executing, but it never goes into circuits. + const functionMetadataHash = computeFunctionMetadataHash(privateFunctionArtifact); + const functionArtifactHash = computeFunctionArtifactHash({ ...privateFunctionArtifact, functionMetadataHash }); + const artifactTree = computeArtifactFunctionTree(artifact, FunctionType.SECRET)!; + const artifactTreeLeafIndex = artifactTree.getIndex(functionArtifactHash.toBuffer()); + const artifactTreeSiblingPath = artifactTree.getSiblingPath(artifactTreeLeafIndex).map(Fr.fromBuffer); + + log.trace(`Computed proof for private function with selector ${selector.toString()}`, { + functionArtifactHash, + functionMetadataHash, + functionLeaf: '0x' + functionLeaf.toString('hex'), + artifactMetadataHash, + privateFunctionsTreeRoot: '0x' + functionsTree.root.toString('hex'), + unconstrainedFunctionsArtifactTreeRoot, + artifactFunctionTreeSiblingPath: artifactTreeSiblingPath.map(fr => fr.toString()).join(','), + privateFunctionTreeSiblingPath: functionsTreeSiblingPath.map(fr => fr.toString()).join(','), + }); + + return { + artifactTreeSiblingPath, + artifactTreeLeafIndex, + artifactMetadataHash, + functionMetadataHash, + unconstrainedFunctionsArtifactTreeRoot, + privateFunctionTreeSiblingPath: functionsTreeSiblingPath, + privateFunctionTreeLeafIndex: functionsTreeLeafIndex, + }; +} + +/** + * Verifies that a private function with a membership proof as emitted by the ClassRegisterer contract is valid, + * as defined in the yellow paper at contract-deployment/classes: + * + * ``` + * // Load contract class from local db + * contract_class = db.get_contract_class(contract_class_id) + * + * // Compute function leaf and assert it belongs to the private functions tree + * function_leaf = pedersen([selector as Field, vk_hash], GENERATOR__FUNCTION_LEAF) + * computed_private_function_tree_root = compute_root(function_leaf, private_function_tree_sibling_path) + * assert computed_private_function_tree_root == contract_class.private_function_root + * + * // Compute artifact leaf and assert it belongs to the artifact + * artifact_function_leaf = sha256(selector, metadata_hash, sha256(bytecode)) + * computed_artifact_private_function_tree_root = compute_root(artifact_function_leaf, artifact_function_tree_sibling_path) + * computed_artifact_hash = sha256(computed_artifact_private_function_tree_root, unconstrained_functions_artifact_tree_root, artifact_metadata_hash) + * assert computed_artifact_hash == contract_class.artifact_hash + * ``` + * @param fn - Function to check membership proof for. + * @param contractClass - In which contract class the function is expected to be. + */ +export function isValidPrivateFunctionMembershipProof( + fn: ExecutablePrivateFunctionWithMembershipProof, + contractClass: Pick, +) { + const log = createDebugLogger('aztec:circuits:function_membership_proof'); + + // Check private function tree membership + const functionLeaf = computePrivateFunctionLeaf(fn); + const computedPrivateFunctionTreeRoot = Fr.fromBuffer( + computeRootFromSiblingPath( + functionLeaf, + fn.privateFunctionTreeSiblingPath.map(fr => fr.toBuffer()), + fn.privateFunctionTreeLeafIndex, + ), + ); + if (!contractClass.privateFunctionsRoot.equals(computedPrivateFunctionTreeRoot)) { + log.trace(`Private function tree root mismatch`, { + expectedPrivateFunctionTreeRoot: contractClass.privateFunctionsRoot, + computedPrivateFunctionTreeRoot: computedPrivateFunctionTreeRoot, + computedFunctionLeaf: '0x' + functionLeaf.toString('hex'), + }); + return false; + } + + // Check artifact hash + const functionArtifactHash = computeFunctionArtifactHash(fn); + const computedArtifactPrivateFunctionTreeRoot = Fr.fromBuffer( + computeRootFromSiblingPath( + functionArtifactHash.toBuffer(), + fn.artifactTreeSiblingPath.map(fr => fr.toBuffer()), + fn.artifactTreeLeafIndex, + getArtifactMerkleTreeHasher(), + ), + ); + const computedArtifactHash = computeArtifactHash({ + privateFunctionRoot: computedArtifactPrivateFunctionTreeRoot, + unconstrainedFunctionRoot: fn.unconstrainedFunctionsArtifactTreeRoot, + metadataHash: fn.artifactMetadataHash, + }); + if (!contractClass.artifactHash.equals(computedArtifactHash)) { + log.trace(`Artifact hash mismatch`, { + expected: contractClass.artifactHash, + computedArtifactHash, + computedFunctionArtifactHash: functionArtifactHash, + computedArtifactPrivateFunctionTreeRoot, + unconstrainedFunctionRoot: fn.unconstrainedFunctionsArtifactTreeRoot, + metadataHash: fn.artifactMetadataHash, + artifactFunctionTreeSiblingPath: fn.artifactTreeSiblingPath.map(fr => fr.toString()).join(','), + }); + return false; + } + + return true; +} diff --git a/yarn-project/circuits.js/src/contract/public_bytecode.ts b/yarn-project/circuits.js/src/contract/public_bytecode.ts index e7a77a887ac3..0292fd55b9d6 100644 --- a/yarn-project/circuits.js/src/contract/public_bytecode.ts +++ b/yarn-project/circuits.js/src/contract/public_bytecode.ts @@ -15,7 +15,7 @@ import { FUNCTION_SELECTOR_NUM_BYTES } from '../constants.gen.js'; */ export function packBytecode(publicFns: ContractClass['publicFunctions']): Buffer { return serializeArrayOfBufferableToVector( - publicFns.map(fn => serializeToBuffer(fn.selector, fn.isInternal, numToInt32BE(fn.bytecode.length), fn.bytecode)), + publicFns.map(fn => serializeToBuffer(fn.selector, numToInt32BE(fn.bytecode.length), fn.bytecode)), ); } @@ -28,7 +28,6 @@ export function unpackBytecode(buffer: Buffer): ContractClass['publicFunctions'] return reader.readVector({ fromBuffer: (reader: BufferReader) => ({ selector: FunctionSelector.fromBuffer(reader.readBytes(FUNCTION_SELECTOR_NUM_BYTES)), - isInternal: reader.readBoolean(), bytecode: reader.readBuffer(), }), }); diff --git a/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.test.ts b/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.test.ts new file mode 100644 index 000000000000..661211978e31 --- /dev/null +++ b/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.test.ts @@ -0,0 +1,44 @@ +import { ContractArtifact, FunctionArtifact, FunctionSelector, FunctionType } from '@aztec/foundation/abi'; +import { Fr } from '@aztec/foundation/fields'; +import { ContractClass } from '@aztec/types/contracts'; + +import { getSampleContractArtifact } from '../tests/fixtures.js'; +import { getContractClassFromArtifact } from './contract_class.js'; +import { ContractClassIdPreimage } from './contract_class_id.js'; +import { + createUnconstrainedFunctionMembershipProof, + isValidUnconstrainedFunctionMembershipProof, +} from './unconstrained_function_membership_proof.js'; + +describe('unconstrained_function_membership_proof', () => { + let artifact: ContractArtifact; + let contractClass: ContractClass & ContractClassIdPreimage; + let unconstrainedFunction: FunctionArtifact; + let vkHash: Fr; + let selector: FunctionSelector; + + beforeAll(() => { + artifact = getSampleContractArtifact(); + contractClass = getContractClassFromArtifact(artifact); + unconstrainedFunction = artifact.functions.findLast(fn => fn.functionType === FunctionType.UNCONSTRAINED)!; + selector = FunctionSelector.fromNameAndParameters(unconstrainedFunction); + }); + + it('computes and verifies a proof', () => { + const proof = createUnconstrainedFunctionMembershipProof(selector, artifact); + const fn = { ...unconstrainedFunction, ...proof, selector }; + expect(isValidUnconstrainedFunctionMembershipProof(fn, contractClass)).toBeTruthy(); + }); + + test.each(['artifactTreeSiblingPath', 'artifactMetadataHash', 'functionMetadataHash'] as const)( + 'fails proof if %s is mangled', + field => { + const proof = createUnconstrainedFunctionMembershipProof(selector, artifact); + const original = proof[field]; + const mangled = Array.isArray(original) ? [Fr.random(), ...original.slice(1)] : Fr.random(); + const wrong = { ...proof, [field]: mangled }; + const fn = { ...unconstrainedFunction, ...wrong, selector, vkHash }; + expect(isValidUnconstrainedFunctionMembershipProof(fn, contractClass)).toBeFalsy(); + }, + ); +}); diff --git a/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.ts b/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.ts new file mode 100644 index 000000000000..144e11ed81d5 --- /dev/null +++ b/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.ts @@ -0,0 +1,118 @@ +import { ContractArtifact, FunctionSelector, FunctionType } from '@aztec/foundation/abi'; +import { Fr } from '@aztec/foundation/fields'; +import { createDebugLogger } from '@aztec/foundation/log'; +import { + ContractClassPublic, + UnconstrainedFunctionMembershipProof, + UnconstrainedFunctionWithMembershipProof, +} from '@aztec/types/contracts'; + +import { computeRootFromSiblingPath } from '../merkle/index.js'; +import { + computeArtifactFunctionTree, + computeArtifactHash, + computeArtifactHashPreimage, + computeFunctionArtifactHash, + computeFunctionMetadataHash, + getArtifactMerkleTreeHasher, +} from './artifact_hash.js'; + +/** + * Creates a membership proof for an unconstrained function in a contract class, to be verified via `isValidUnconstrainedFunctionMembershipProof`. + * @param selector - Selector of the function to create the proof for. + * @param artifact - Artifact of the contract class where the function is defined. + */ +export function createUnconstrainedFunctionMembershipProof( + selector: FunctionSelector, + artifact: ContractArtifact, +): UnconstrainedFunctionMembershipProof { + const log = createDebugLogger('aztec:circuits:function_membership_proof'); + + // Locate function artifact + const fn = artifact.functions.find(fn => selector.equals(fn)); + if (!fn) { + throw new Error(`Function with selector ${selector.toString()} not found`); + } else if (fn.functionType !== FunctionType.UNCONSTRAINED) { + throw new Error(`Function ${fn.name} with selector ${selector.toString()} is not unconstrained`); + } + + // Compute preimage for the artifact hash + const { privateFunctionRoot: privateFunctionsArtifactTreeRoot, metadataHash: artifactMetadataHash } = + computeArtifactHashPreimage(artifact); + + // Compute the sibling path for the "artifact tree" + const functionMetadataHash = computeFunctionMetadataHash(fn); + const functionArtifactHash = computeFunctionArtifactHash({ ...fn, functionMetadataHash }); + const artifactTree = computeArtifactFunctionTree(artifact, FunctionType.UNCONSTRAINED)!; + const artifactTreeLeafIndex = artifactTree.getIndex(functionArtifactHash.toBuffer()); + const artifactTreeSiblingPath = artifactTree.getSiblingPath(artifactTreeLeafIndex).map(Fr.fromBuffer); + + log.trace(`Computed proof for unconstrained function with selector ${selector.toString()}`, { + functionArtifactHash, + functionMetadataHash, + artifactMetadataHash, + artifactFunctionTreeSiblingPath: artifactTreeSiblingPath.map(fr => fr.toString()).join(','), + privateFunctionsArtifactTreeRoot, + }); + + return { + artifactTreeSiblingPath, + artifactTreeLeafIndex, + artifactMetadataHash, + functionMetadataHash, + privateFunctionsArtifactTreeRoot, + }; +} + +/** + * Verifies that an unconstrained function with a membership proof as emitted by the ClassRegisterer contract is valid, + * as defined in the yellow paper at contract-deployment/classes: + * + * ``` + * // Load contract class from local db + * contract_class = db.get_contract_class(contract_class_id) + * + * // Compute artifact leaf and assert it belongs to the artifact + * artifact_function_leaf = sha256(selector, metadata_hash, sha256(bytecode)) + * computed_artifact_unconstrained_function_tree_root = compute_root(artifact_function_leaf, artifact_function_tree_sibling_path, artifact_function_tree_leaf_index) + * computed_artifact_hash = sha256(private_functions_artifact_tree_root, computed_artifact_unconstrained_function_tree_root, artifact_metadata_hash) + * assert computed_artifact_hash == contract_class.artifact_hash + * ``` + * @param fn - Function to check membership proof for. + * @param contractClass - In which contract class the function is expected to be. + */ +export function isValidUnconstrainedFunctionMembershipProof( + fn: UnconstrainedFunctionWithMembershipProof, + contractClass: Pick, +) { + const log = createDebugLogger('aztec:circuits:function_membership_proof'); + + const functionArtifactHash = computeFunctionArtifactHash(fn); + const computedArtifactFunctionTreeRoot = Fr.fromBuffer( + computeRootFromSiblingPath( + functionArtifactHash.toBuffer(), + fn.artifactTreeSiblingPath.map(fr => fr.toBuffer()), + fn.artifactTreeLeafIndex, + getArtifactMerkleTreeHasher(), + ), + ); + const computedArtifactHash = computeArtifactHash({ + privateFunctionRoot: fn.privateFunctionsArtifactTreeRoot, + unconstrainedFunctionRoot: computedArtifactFunctionTreeRoot, + metadataHash: fn.artifactMetadataHash, + }); + if (!contractClass.artifactHash.equals(computedArtifactHash)) { + log.trace(`Artifact hash mismatch`, { + expected: contractClass.artifactHash, + computedArtifactHash, + computedFunctionArtifactHash: functionArtifactHash, + computedArtifactFunctionTreeRoot, + privateFunctionsArtifactTreeRoot: fn.privateFunctionsArtifactTreeRoot, + metadataHash: fn.artifactMetadataHash, + artifactFunctionTreeSiblingPath: fn.artifactTreeSiblingPath.map(fr => fr.toString()).join(','), + }); + return false; + } + + return true; +} diff --git a/yarn-project/circuits.js/src/merkle/index.ts b/yarn-project/circuits.js/src/merkle/index.ts index 5ab1f3d973c4..87b32526900c 100644 --- a/yarn-project/circuits.js/src/merkle/index.ts +++ b/yarn-project/circuits.js/src/merkle/index.ts @@ -1,2 +1,3 @@ export * from './merkle_tree_calculator.js'; export * from './merkle_tree.js'; +export * from './sibling_path.js'; diff --git a/yarn-project/circuits.js/src/merkle/merkle_tree.ts b/yarn-project/circuits.js/src/merkle/merkle_tree.ts index ec8f1182b5e0..53d516960d5e 100644 --- a/yarn-project/circuits.js/src/merkle/merkle_tree.ts +++ b/yarn-project/circuits.js/src/merkle/merkle_tree.ts @@ -45,4 +45,28 @@ export class MerkleTree { public getIndex(element: Buffer) { return this.leaves.findIndex(leaf => leaf.equals(element)); } + + /** Returns a nice string representation of the tree, useful for debugging purposes. */ + public drawTree() { + const levels: string[][] = []; + const tree = this.nodes; + const maxRowSize = Math.ceil(tree.length / 2); + let paddingSize = 1; + let rowSize = maxRowSize; + let rowOffset = 0; + while (rowSize > 0) { + levels.push( + tree + .slice(rowOffset, rowOffset + rowSize) + .map(n => n.toString('hex').slice(0, 8) + ' '.repeat((paddingSize - 1) * 9)), + ); + rowOffset += rowSize; + paddingSize <<= 1; + rowSize >>= 1; + } + return levels + .reverse() + .map(row => row.join(' ')) + .join('\n'); + } } diff --git a/yarn-project/circuits.js/src/merkle/sibling_path.test.ts b/yarn-project/circuits.js/src/merkle/sibling_path.test.ts new file mode 100644 index 000000000000..6b59138a4769 --- /dev/null +++ b/yarn-project/circuits.js/src/merkle/sibling_path.test.ts @@ -0,0 +1,21 @@ +import { Fr } from '@aztec/foundation/fields'; + +import { MerkleTree } from './merkle_tree.js'; +import { MerkleTreeCalculator } from './merkle_tree_calculator.js'; +import { computeRootFromSiblingPath } from './sibling_path.js'; + +describe('sibling path', () => { + let tree: MerkleTree; + + beforeAll(() => { + const calculator = new MerkleTreeCalculator(4); + const leaves = Array.from({ length: 5 }).map((_, i) => new Fr(i).toBuffer()); + tree = calculator.computeTree(leaves); + }); + + test.each([0, 1, 2, 3, 4, 5, 6, 7])('recovers the root from a leaf at index %s and its sibling path', index => { + const leaf = tree.leaves[index]; + const siblingPath = tree.getSiblingPath(index); + expect(computeRootFromSiblingPath(leaf, siblingPath, index)).toEqual(tree.root); + }); +}); diff --git a/yarn-project/circuits.js/src/merkle/sibling_path.ts b/yarn-project/circuits.js/src/merkle/sibling_path.ts new file mode 100644 index 000000000000..52383dae87c7 --- /dev/null +++ b/yarn-project/circuits.js/src/merkle/sibling_path.ts @@ -0,0 +1,16 @@ +import { pedersenHash } from '@aztec/foundation/crypto'; + +/** Computes the expected root of a merkle tree given a leaf and its sibling path. */ +export function computeRootFromSiblingPath( + leaf: Buffer, + siblingPath: Buffer[], + index: number, + hasher = (left: Buffer, right: Buffer) => pedersenHash([left, right]).toBuffer(), +) { + let result = leaf; + for (const sibling of siblingPath) { + result = index & 1 ? hasher(sibling, result) : hasher(result, sibling); + index >>= 1; + } + return result; +} diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index bfee81cc51a7..aeec6e1ef038 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -3,7 +3,13 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { EthAddress } from '@aztec/foundation/eth-address'; import { numToUInt32BE } from '@aztec/foundation/serialize'; -import { ContractClassPublic, PrivateFunction, PublicFunction } from '@aztec/types/contracts'; +import { + ContractClassPublic, + ExecutablePrivateFunctionWithMembershipProof, + PrivateFunction, + PublicFunction, + UnconstrainedFunctionWithMembershipProof, +} from '@aztec/types/contracts'; import { SchnorrSignature } from '../barretenberg/index.js'; import { @@ -1274,6 +1280,35 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { }); } +export function makeExecutablePrivateFunctionWithMembershipProof( + seed = 0, +): ExecutablePrivateFunctionWithMembershipProof { + return { + selector: makeSelector(seed), + bytecode: makeBytes(100, seed + 1), + artifactTreeSiblingPath: makeTuple(3, fr, seed + 2), + artifactTreeLeafIndex: seed + 2, + privateFunctionTreeSiblingPath: makeTuple(3, fr, seed + 3), + privateFunctionTreeLeafIndex: seed + 3, + artifactMetadataHash: fr(seed + 4), + functionMetadataHash: fr(seed + 5), + unconstrainedFunctionsArtifactTreeRoot: fr(seed + 6), + vkHash: fr(seed + 7), + }; +} + +export function makeUnconstrainedFunctionWithMembershipProof(seed = 0): UnconstrainedFunctionWithMembershipProof { + return { + selector: makeSelector(seed), + bytecode: makeBytes(100, seed + 1), + artifactTreeSiblingPath: makeTuple(3, fr, seed + 2), + artifactTreeLeafIndex: seed + 2, + artifactMetadataHash: fr(seed + 4), + functionMetadataHash: fr(seed + 5), + privateFunctionsArtifactTreeRoot: fr(seed + 6), + }; +} + export function makeContractClassPublic(seed = 0): ContractClassPublic { const artifactHash = fr(seed + 1); const publicFunctions = makeTuple(3, makeContractClassPublicFunction, seed + 2); @@ -1287,6 +1322,8 @@ export function makeContractClassPublic(seed = 0): ContractClassPublic { packedBytecode, privateFunctionsRoot, publicFunctions, + privateFunctions: [], + unconstrainedFunctions: [], version: 1, }; } @@ -1295,7 +1332,6 @@ function makeContractClassPublicFunction(seed = 0): PublicFunction { return { selector: FunctionSelector.fromField(fr(seed + 1)), bytecode: makeBytes(100, seed + 2), - isInternal: false, }; } @@ -1304,7 +1340,6 @@ function makeContractClassPrivateFunction(seed = 0): PrivateFunction { return { selector: FunctionSelector.fromField(fr(seed + 1)), vkHash: fr(seed + 2), - isInternal: false, }; } diff --git a/yarn-project/circuits.js/src/tests/fixtures.ts b/yarn-project/circuits.js/src/tests/fixtures.ts index ceb6611d3949..dd4f57f55423 100644 --- a/yarn-project/circuits.js/src/tests/fixtures.ts +++ b/yarn-project/circuits.js/src/tests/fixtures.ts @@ -25,6 +25,18 @@ export function getSampleContractInstanceDeployedEventPayload(): Buffer { return Buffer.from(readFileSync(path).toString(), 'hex'); } +// Generated from end-to-end/src/e2e_deploy_contract.test.ts with AZTEC_GENERATE_TEST_DATA +export function getSamplePrivateFunctionBroadcastedEventPayload(): Buffer { + const path = getPathToFixture('PrivateFunctionBroadcastedEventData.hex'); + return Buffer.from(readFileSync(path).toString(), 'hex'); +} + +// Generated from end-to-end/src/e2e_deploy_contract.test.ts with AZTEC_GENERATE_TEST_DATA +export function getSampleUnconstrainedFunctionBroadcastedEventPayload(): Buffer { + const path = getPathToFixture('UnconstrainedFunctionBroadcastedEventData.hex'); + return Buffer.from(readFileSync(path).toString(), 'hex'); +} + function getPathToFixture(name: string) { return resolve(dirname(fileURLToPath(import.meta.url)), `../../fixtures/${name}`); } diff --git a/yarn-project/cli/src/cmds/get_contract_data.ts b/yarn-project/cli/src/cmds/get_contract_data.ts index a102e0ba2a92..d11180f7e4b2 100644 --- a/yarn-project/cli/src/cmds/get_contract_data.ts +++ b/yarn-project/cli/src/cmds/get_contract_data.ts @@ -26,7 +26,7 @@ export async function getContractData( }); if (contractClass) { - log(`Bytecode: 0x${contractClass.packedBytecode.toString('hex')}`); + log(`Bytecode: ${contractClass.packedBytecode.toString('base64')}`); } log('\n'); } diff --git a/yarn-project/cli/src/cmds/inspect_contract.ts b/yarn-project/cli/src/cmds/inspect_contract.ts index a5fb4ca52631..4728de02fd08 100644 --- a/yarn-project/cli/src/cmds/inspect_contract.ts +++ b/yarn-project/cli/src/cmds/inspect_contract.ts @@ -35,8 +35,8 @@ function logFunction(fn: FunctionArtifact, log: LogFn) { const signatureWithParameterNames = decodeFunctionSignatureWithParameterNames(fn.name, fn.parameters); const signature = decodeFunctionSignature(fn.name, fn.parameters); const selector = FunctionSelector.fromSignature(signature); - const bytecodeSize = Buffer.from(fn.bytecode, 'base64').length; - const bytecodeHash = sha256(Buffer.from(fn.bytecode, 'base64')).toString('hex'); + const bytecodeSize = fn.bytecode.length; + const bytecodeHash = sha256(fn.bytecode).toString('hex'); log( `${fn.functionType} ${signatureWithParameterNames} \n\tfunction signature: ${signature}\n\tselector: ${selector}\n\tbytecode: ${bytecodeSize} bytes (sha256 ${bytecodeHash})`, ); diff --git a/yarn-project/cli/src/test/mocks.ts b/yarn-project/cli/src/test/mocks.ts index b1463de3acd8..afa693b8427c 100644 --- a/yarn-project/cli/src/test/mocks.ts +++ b/yarn-project/cli/src/test/mocks.ts @@ -18,7 +18,7 @@ export const mockContractArtifact: ContractArtifact = { }, ], returnTypes: [], - bytecode: 'constructorBytecode', + bytecode: Buffer.alloc(8, 0xfa), debugSymbols: '', }, { @@ -61,7 +61,7 @@ export const mockContractArtifact: ContractArtifact = { }, ], returnTypes: [{ kind: 'boolean' }], - bytecode: 'mockBytecode', + bytecode: Buffer.alloc(8, 0xfa), debugSymbols: '', }, ], diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts index 04b930f65aca..1727b37b9874 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts @@ -27,6 +27,7 @@ import { import { ContractClassIdPreimage, Point } from '@aztec/circuits.js'; import { siloNullifier } from '@aztec/circuits.js/hash'; import { FunctionSelector, FunctionType } from '@aztec/foundation/abi'; +import { writeTestData } from '@aztec/foundation/testing'; import { CounterContract, StatefulTestContract } from '@aztec/noir-contracts.js'; import { TestContract, TestContractArtifact } from '@aztec/noir-contracts.js/Test'; import { TokenContract, TokenContractArtifact } from '@aztec/noir-contracts.js/Token'; @@ -293,18 +294,29 @@ describe('e2e_deploy_contract', () => { it('broadcasts a private function', async () => { const selector = contractClass.privateFunctions[0].selector; - await broadcastPrivateFunction(wallet, artifact, selector).send().wait(); - // TODO(#4428): Test that these functions are captured by the node and made available when - // requesting the corresponding contract class. + const tx = await broadcastPrivateFunction(wallet, artifact, selector).send().wait(); + const logs = await pxe.getUnencryptedLogs({ txHash: tx.txHash }); + const logData = logs.logs[0].log.data; + writeTestData('yarn-project/circuits.js/fixtures/PrivateFunctionBroadcastedEventData.hex', logData); + + const fetchedClass = await aztecNode.getContractClass(contractClass.id); + const fetchedFunction = fetchedClass!.privateFunctions[0]!; + expect(fetchedFunction).toBeDefined(); + expect(fetchedFunction.selector).toEqual(selector); }, 60_000); - // TODO(@spalladino): Reenable this test - it.skip('broadcasts an unconstrained function', async () => { + it('broadcasts an unconstrained function', async () => { const functionArtifact = artifact.functions.find(fn => fn.functionType === FunctionType.UNCONSTRAINED)!; const selector = FunctionSelector.fromNameAndParameters(functionArtifact); - await broadcastUnconstrainedFunction(wallet, artifact, selector).send().wait(); - // TODO(#4428): Test that these functions are captured by the node and made available when - // requesting the corresponding contract class. + const tx = await broadcastUnconstrainedFunction(wallet, artifact, selector).send().wait(); + const logs = await pxe.getUnencryptedLogs({ txHash: tx.txHash }); + const logData = logs.logs[0].log.data; + writeTestData('yarn-project/circuits.js/fixtures/UnconstrainedFunctionBroadcastedEventData.hex', logData); + + const fetchedClass = await aztecNode.getContractClass(contractClass.id); + const fetchedFunction = fetchedClass!.unconstrainedFunctions[0]!; + expect(fetchedFunction).toBeDefined(); + expect(fetchedFunction.selector).toEqual(selector); }, 60_000); const testDeployingAnInstance = (how: string, deployFn: (toDeploy: ContractInstanceWithAddress) => Promise) => diff --git a/yarn-project/end-to-end/src/shared/browser.ts b/yarn-project/end-to-end/src/shared/browser.ts index ee6e973d9e02..3f67c743f684 100644 --- a/yarn-project/end-to-end/src/shared/browser.ts +++ b/yarn-project/end-to-end/src/shared/browser.ts @@ -4,6 +4,7 @@ import * as AztecAccountsSingleKey from '@aztec/accounts/single_key'; import * as AztecAccountsTesting from '@aztec/accounts/testing'; import * as AztecJs from '@aztec/aztec.js'; import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token'; +import { contractArtifactToBuffer } from '@aztec/types/abi'; import { Server } from 'http'; import Koa from 'koa'; @@ -19,7 +20,10 @@ declare global { /** * The aztec.js library. */ - AztecJs: typeof AztecJs & typeof AztecAccountsSingleKey & typeof AztecAccountsTesting & typeof AztecAccountsSchnorr; + AztecJs: { Buffer: typeof Buffer } & typeof AztecJs & + typeof AztecAccountsSingleKey & + typeof AztecAccountsTesting & + typeof AztecAccountsSchnorr; } } @@ -207,7 +211,7 @@ export const browserTestSuite = ( const deployTokenContract = async () => { const [txHash, tokenAddress] = await page.evaluate( - async (rpcUrl, initialBalance, TokenContractArtifact) => { + async (rpcUrl, initialBalance, serializedTokenContractArtifact) => { const { DeployMethod, createPXEClient, @@ -221,7 +225,13 @@ export const browserTestSuite = ( INITIAL_TEST_ENCRYPTION_KEYS, INITIAL_TEST_SIGNING_KEYS, INITIAL_TEST_ACCOUNT_SALTS, + Buffer, } = window.AztecJs; + // We serialize the artifact since buffers (used for bytecode) do not cross well from one realm to another + const TokenContractArtifact = JSON.parse( + Buffer.from(serializedTokenContractArtifact, 'base64').toString('utf-8'), + (key, value) => (key === 'bytecode' && typeof value === 'string' ? Buffer.from(value, 'base64') : value), + ); const pxe = createPXEClient(rpcUrl!); // we need to ensure that a known account is present in order to create a wallet @@ -271,7 +281,7 @@ export const browserTestSuite = ( }, pxeURL, initialBalance, - TokenContractArtifact, + contractArtifactToBuffer(TokenContractArtifact).toString('base64'), ); const txResult = await testClient.getTxReceipt(AztecJs.TxHash.fromString(txHash)); diff --git a/yarn-project/end-to-end/src/web/main.ts b/yarn-project/end-to-end/src/web/main.ts index 992b578f291f..3e65f0760e95 100644 --- a/yarn-project/end-to-end/src/web/main.ts +++ b/yarn-project/end-to-end/src/web/main.ts @@ -2,3 +2,5 @@ export * from '@aztec/aztec.js'; export * from '@aztec/accounts/testing'; export * from '@aztec/accounts/single_key'; export * from '@aztec/accounts/schnorr'; + +export { Buffer } from 'buffer/'; diff --git a/yarn-project/foundation/src/abi/abi.ts b/yarn-project/foundation/src/abi/abi.ts index d8ba0f8a7e4f..c131a81f9263 100644 --- a/yarn-project/foundation/src/abi/abi.ts +++ b/yarn-project/foundation/src/abi/abi.ts @@ -165,7 +165,7 @@ export interface FunctionArtifact extends FunctionAbi { /** * The ACIR bytecode of the function. */ - bytecode: string; + bytecode: Buffer; /** * The verification key of the function. */ diff --git a/yarn-project/foundation/src/fields/fields.ts b/yarn-project/foundation/src/fields/fields.ts index 9680f0c530e1..a28018638f42 100644 --- a/yarn-project/foundation/src/fields/fields.ts +++ b/yarn-project/foundation/src/fields/fields.ts @@ -355,3 +355,8 @@ function extendedEuclidean(a: bigint, modulus: bigint): [bigint, bigint, bigint] */ export type GrumpkinScalar = Fq; export const GrumpkinScalar = Fq; + +/** Wraps a function that returns a buffer so that all results are reduced into a field of the given type. */ +export function reduceFn(fn: (input: TInput) => Buffer, field: DerivedField) { + return (input: TInput) => fromBufferReduce(fn(input), field); +} diff --git a/yarn-project/foundation/src/log/log_fn.ts b/yarn-project/foundation/src/log/log_fn.ts index cfc045d8bb2e..5dd11204e28d 100644 --- a/yarn-project/foundation/src/log/log_fn.ts +++ b/yarn-project/foundation/src/log/log_fn.ts @@ -1,5 +1,5 @@ /** Structured log data to include with the message. */ -export type LogData = Record; +export type LogData = Record; /** A callable logger instance. */ export type LogFn = (msg: string, data?: LogData) => void; diff --git a/yarn-project/foundation/src/log/logger.ts b/yarn-project/foundation/src/log/logger.ts index 258abbe7e5c4..9c9998a98c48 100644 --- a/yarn-project/foundation/src/log/logger.ts +++ b/yarn-project/foundation/src/log/logger.ts @@ -5,7 +5,7 @@ import { isatty } from 'tty'; import { LogData, LogFn } from './log_fn.js'; // Matches a subset of Winston log levels -const LogLevels = ['silent', 'error', 'warn', 'info', 'verbose', 'debug'] as const; +const LogLevels = ['silent', 'error', 'warn', 'info', 'verbose', 'debug', 'trace'] as const; const DefaultLogLevel = process.env.NODE_ENV === 'test' ? ('silent' as const) : ('info' as const); /** @@ -50,6 +50,7 @@ export function createDebugLogger(name: string): DebugLogger { info: (msg: string, data?: LogData) => logWithDebug(debugLogger, 'info', msg, data), verbose: (msg: string, data?: LogData) => logWithDebug(debugLogger, 'verbose', msg, data), debug: (msg: string, data?: LogData) => logWithDebug(debugLogger, 'debug', msg, data), + trace: (msg: string, data?: LogData) => logWithDebug(debugLogger, 'trace', msg, data), }; return Object.assign((msg: string, data?: LogData) => logWithDebug(debugLogger, 'debug', msg, data), logger); } @@ -111,8 +112,7 @@ function getPrefix(debugLogger: debug.Debugger, level: LogLevel) { * @param msg - What to log. */ function printLog(msg: string) { - // eslint-disable-next-line no-console - console.error(msg); + process.stderr.write(msg + '\n'); } /** @@ -132,6 +132,6 @@ function fmtErr(msg: string, err?: Error | unknown): string { */ function fmtLogData(data?: LogData): string { return Object.entries(data ?? {}) - .map(([key, value]) => `${key}=${value}`) + .map(([key, value]) => `${key}=${typeof value === 'object' && 'toString' in value ? value.toString() : value}`) .join(' '); } diff --git a/yarn-project/foundation/src/serialize/buffer_reader.ts b/yarn-project/foundation/src/serialize/buffer_reader.ts index 8905f7350b74..0e637d9e69d4 100644 --- a/yarn-project/foundation/src/serialize/buffer_reader.ts +++ b/yarn-project/foundation/src/serialize/buffer_reader.ts @@ -43,6 +43,11 @@ export class BufferReader { return new BufferReader(buf); } + /** Returns true if the underlying buffer has been consumed completely. */ + public isEmpty(): boolean { + return this.index === this.buffer.length; + } + /** * Reads a 32-bit unsigned integer from the buffer at the current index position. * Updates the index position by 4 bytes after reading the number. diff --git a/yarn-project/foundation/src/serialize/serialize.ts b/yarn-project/foundation/src/serialize/serialize.ts index 9023fc565984..758a466dcd58 100644 --- a/yarn-project/foundation/src/serialize/serialize.ts +++ b/yarn-project/foundation/src/serialize/serialize.ts @@ -162,8 +162,10 @@ export function serializeToBufferArray(...objs: Bufferable[]): Buffer[] { } else if (typeof obj === 'string') { ret.push(numToUInt32BE(obj.length)); ret.push(Buffer.from(obj)); - } else { + } else if ('toBuffer' in obj) { ret.push(obj.toBuffer()); + } else { + throw new Error(`Cannot serialize input to buffer: ${typeof obj} ${(obj as any).constructor?.name}`); } } return ret; diff --git a/yarn-project/foundation/src/testing/test_data.ts b/yarn-project/foundation/src/testing/test_data.ts index 241ae5eead90..a92794e64f6a 100644 --- a/yarn-project/foundation/src/testing/test_data.ts +++ b/yarn-project/foundation/src/testing/test_data.ts @@ -41,6 +41,18 @@ export function getTestData(itemName: string): { toBuffer(): Buffer }[] { return testData[fullItemName]; } +/** Writes the contents specified to the target file if test data generation is enabled. */ +export function writeTestData(targetFileFromRepoRoot: string, contents: string | Buffer) { + if (!isGenerateTestDataEnabled()) { + return; + } + const targetFile = getPathToFile(targetFileFromRepoRoot); + const toWrite = typeof contents === 'string' ? contents : contents.toString('hex'); + writeFileSync(targetFile, toWrite); + const logger = createConsoleLogger('aztec:testing:test_data'); + logger(`Wrote test data to ${targetFile}`); +} + /** * Looks for a variable assignment in the target file and updates the value, only if test data generation is enabled. * Note that a magic inline comment would be a cleaner approach, like `/* TEST-DATA-START *\/` and `/* TEST-DATA-END *\/`, @@ -52,12 +64,7 @@ export function updateInlineTestData(targetFileFromRepoRoot: string, itemName: s return; } const logger = createConsoleLogger('aztec:testing:test_data'); - const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../../'); - if (!existsSync(join(repoRoot, 'CODEOWNERS'))) { - throw new Error(`Path to repo root is incorrect (got ${repoRoot})`); - } - - const targetFile = join(repoRoot, targetFileFromRepoRoot); + const targetFile = getPathToFile(targetFileFromRepoRoot); const contents = readFileSync(targetFile, 'utf8').toString(); const regex = new RegExp(`let ${itemName} = .*;`, 'g'); if (!regex.exec(contents)) { @@ -68,3 +75,12 @@ export function updateInlineTestData(targetFileFromRepoRoot: string, itemName: s writeFileSync(targetFile, updatedContents); logger(`Updated test data in ${targetFile} for ${itemName} to ${value}`); } + +function getPathToFile(targetFileFromRepoRoot: string) { + const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../../'); + if (!existsSync(join(repoRoot, 'CODEOWNERS'))) { + throw new Error(`Path to repo root is incorrect (got ${repoRoot})`); + } + + return join(repoRoot, targetFileFromRepoRoot); +} diff --git a/yarn-project/noir-protocol-circuits-types/src/noir_test_gen.test.ts b/yarn-project/noir-protocol-circuits-types/src/noir_test_gen.test.ts index 8ec8f5f6dbd8..1586c8c3bbe1 100644 --- a/yarn-project/noir-protocol-circuits-types/src/noir_test_gen.test.ts +++ b/yarn-project/noir-protocol-circuits-types/src/noir_test_gen.test.ts @@ -32,8 +32,8 @@ describe('Data generation for noir tests', () => { publicKeysHash: new Fr(45678), salt: new Fr(56789), privateFunctions: [ - { selector: FunctionSelector.fromField(new Fr(1010101)), isInternal: false, vkHash: new Fr(0) }, - { selector: FunctionSelector.fromField(new Fr(2020202)), isInternal: true, vkHash: new Fr(0) }, + { selector: FunctionSelector.fromField(new Fr(1010101)), vkHash: new Fr(0) }, + { selector: FunctionSelector.fromField(new Fr(2020202)), vkHash: new Fr(0) }, ], toString: () => 'defaultContract', }; @@ -44,7 +44,7 @@ describe('Data generation for noir tests', () => { packedBytecode: Buffer.from([3, 4, 3, 4]), publicKeysHash: new Fr(4545), salt: new Fr(5656), - privateFunctions: [{ selector: FunctionSelector.fromField(new Fr(334455)), isInternal: false, vkHash: new Fr(0) }], + privateFunctions: [{ selector: FunctionSelector.fromField(new Fr(334455)), vkHash: new Fr(0) }], toString: () => 'parentContract', }; diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index fc703ed3eac7..bf85390f1cb2 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -704,5 +704,5 @@ function getAvmTestContractBytecode(functionName: string): Buffer { !!artifact?.bytecode, `No bytecode found for function ${functionName}. Try re-running bootstrap.sh on the repository root.`, ); - return Buffer.from(artifact.bytecode, 'base64'); + return artifact.bytecode; } diff --git a/yarn-project/simulator/src/client/private_execution.ts b/yarn-project/simulator/src/client/private_execution.ts index b5698d2dea7c..75bc079900b5 100644 --- a/yarn-project/simulator/src/client/private_execution.ts +++ b/yarn-project/simulator/src/client/private_execution.ts @@ -23,7 +23,7 @@ export async function executePrivateFunction( ): Promise { const functionSelector = functionData.selector; log(`Executing external function ${contractAddress}:${functionSelector}(${artifact.name})`); - const acir = Buffer.from(artifact.bytecode, 'base64'); + const acir = artifact.bytecode; const initialWitness = context.getInitialWitness(artifact); const acvmCallback = new Oracle(context); const { partialWitness } = await acvm(await AcirSimulator.getSolver(), acir, initialWitness, acvmCallback).catch( diff --git a/yarn-project/simulator/src/client/unconstrained_execution.ts b/yarn-project/simulator/src/client/unconstrained_execution.ts index 0ecfb7e55382..19b78bec0f5a 100644 --- a/yarn-project/simulator/src/client/unconstrained_execution.ts +++ b/yarn-project/simulator/src/client/unconstrained_execution.ts @@ -25,7 +25,7 @@ export async function executeUnconstrainedFunction( const functionSelector = functionData.selector; log(`Executing unconstrained function ${contractAddress}:${functionSelector}`); - const acir = Buffer.from(artifact.bytecode, 'base64'); + const acir = artifact.bytecode; const initialWitness = toACVMWitness(0, args); const { partialWitness } = await acvm( await AcirSimulator.getSolver(), diff --git a/yarn-project/simulator/src/public/avm_executor.test.ts b/yarn-project/simulator/src/public/avm_executor.test.ts index 0954b5fe975f..23f31610c1af 100644 --- a/yarn-project/simulator/src/public/avm_executor.test.ts +++ b/yarn-project/simulator/src/public/avm_executor.test.ts @@ -58,7 +58,7 @@ describe('AVM WitGen and Proof Generation', () => { const args: Fr[] = [new Fr(1), new Fr(2)]; const addArtifact = AvmTestContractArtifact.functions.find(f => f.name === 'add_args_return')!; - const bytecode = Buffer.from(addArtifact.bytecode, 'base64'); + const bytecode = addArtifact.bytecode; publicContracts.getBytecode.mockResolvedValue(bytecode); const functionData = FunctionData.fromAbi(addArtifact); const execution: PublicExecution = { contractAddress, functionData, args, callContext }; diff --git a/yarn-project/simulator/src/public/index.test.ts b/yarn-project/simulator/src/public/index.test.ts index e232b2ecd01d..bde9242d755d 100644 --- a/yarn-project/simulator/src/public/index.test.ts +++ b/yarn-project/simulator/src/public/index.test.ts @@ -112,7 +112,7 @@ describe('ACIR public execution simulator', () => { sideEffectCounter: 0, }); - publicContracts.getBytecode.mockResolvedValue(Buffer.from(mintArtifact.bytecode, 'base64')); + publicContracts.getBytecode.mockResolvedValue(mintArtifact.bytecode); // Mock the old value for the recipient balance to be 20 const isMinter = new Fr(1n); // 1n means true @@ -188,7 +188,7 @@ describe('ACIR public execution simulator', () => { recipientStorageSlot = computeSlotForMapping(new Fr(6n), recipient); senderStorageSlot = computeSlotForMapping(new Fr(6n), sender); - publicContracts.getBytecode.mockResolvedValue(Buffer.from(transferArtifact.bytecode, 'base64')); + publicContracts.getBytecode.mockResolvedValue(transferArtifact.bytecode); execution = { contractAddress, functionData, args, callContext }; }); @@ -275,9 +275,9 @@ describe('ACIR public execution simulator', () => { // eslint-disable-next-line require-await publicContracts.getBytecode.mockImplementation(async (addr: AztecAddress, selector: FunctionSelector) => { if (addr.equals(parentContractAddress) && selector.equals(parentEntryPointFnSelector)) { - return Buffer.from(parentEntryPointFn.bytecode, 'base64'); + return parentEntryPointFn.bytecode; } else if (addr.equals(childContractAddress) && selector.equals(childValueFnSelector)) { - return Buffer.from(childValueFn.bytecode, 'base64'); + return childValueFn.bytecode; } else { return undefined; } @@ -337,7 +337,7 @@ describe('ACIR public execution simulator', () => { sideEffectCounter: 0, }); - publicContracts.getBytecode.mockResolvedValue(Buffer.from(shieldArtifact.bytecode, 'base64')); + publicContracts.getBytecode.mockResolvedValue(shieldArtifact.bytecode); // mock initial balance to be greater than the amount being sent publicState.storageRead.mockResolvedValue(amount); @@ -371,7 +371,7 @@ describe('ACIR public execution simulator', () => { sideEffectCounter: 0, }); - publicContracts.getBytecode.mockResolvedValue(Buffer.from(createL2ToL1MessagePublicArtifact.bytecode, 'base64')); + publicContracts.getBytecode.mockResolvedValue(createL2ToL1MessagePublicArtifact.bytecode); const execution: PublicExecution = { contractAddress, functionData, args, callContext }; const result = await executor.simulate(execution, GlobalVariables.empty()); @@ -401,7 +401,7 @@ describe('ACIR public execution simulator', () => { sideEffectCounter: 0, }); - publicContracts.getBytecode.mockResolvedValue(Buffer.from(createNullifierPublicArtifact.bytecode, 'base64')); + publicContracts.getBytecode.mockResolvedValue(createNullifierPublicArtifact.bytecode); const execution: PublicExecution = { contractAddress, functionData, args, callContext }; const result = await executor.simulate(execution, GlobalVariables.empty()); @@ -469,7 +469,7 @@ describe('ACIR public execution simulator', () => { ); const mockOracles = (updateState = true) => { - publicContracts.getBytecode.mockResolvedValue(Buffer.from(mintPublicArtifact.bytecode, 'base64')); + publicContracts.getBytecode.mockResolvedValue(mintPublicArtifact.bytecode); publicState.storageRead.mockResolvedValue(Fr.ZERO); const siblingPathBuffers = Array(L1_TO_L2_MSG_TREE_HEIGHT) @@ -661,7 +661,7 @@ describe('ACIR public execution simulator', () => { }); beforeEach(() => { - publicContracts.getBytecode.mockResolvedValue(Buffer.from(assertGlobalVarsArtifact.bytecode, 'base64')); + publicContracts.getBytecode.mockResolvedValue(assertGlobalVarsArtifact.bytecode); }); // Note: Order here has to match the order of the properties in GlobalVariables.getFields(...) function. @@ -744,7 +744,7 @@ describe('ACIR public execution simulator', () => { }); beforeEach(() => { - publicContracts.getBytecode.mockResolvedValue(Buffer.from(assertHeaderPublicArtifact.bytecode, 'base64')); + publicContracts.getBytecode.mockResolvedValue(assertHeaderPublicArtifact.bytecode); }); it('Header is correctly set', () => { diff --git a/yarn-project/types/package.json b/yarn-project/types/package.json index 4bdfbc0801ed..724ff7853dd3 100644 --- a/yarn-project/types/package.json +++ b/yarn-project/types/package.json @@ -13,16 +13,19 @@ "./noir": "./dest/noir/index.js" }, "scripts": { - "build": "yarn clean && tsc -b", + "build": "yarn clean && yarn generate && tsc -b", "build:dev": "tsc -b --watch", "clean": "rm -rf ./dest .tsbuildinfo", "formatting": "run -T prettier --check ./src && run -T eslint ./src", "formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src", "test:light": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --passWithNoTests", - "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --passWithNoTests" + "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --passWithNoTests", + "generate": "yarn generate:noir-contracts", + "generate:noir-contracts": "./scripts/copy-contracts.sh" }, "inherits": [ - "../package.common.json" + "../package.common.json", + "./package.local.json" ], "jest": { "preset": "ts-jest/presets/default-esm", diff --git a/yarn-project/types/package.local.json b/yarn-project/types/package.local.json new file mode 100644 index 000000000000..40670e322ff8 --- /dev/null +++ b/yarn-project/types/package.local.json @@ -0,0 +1,7 @@ +{ + "scripts": { + "build": "yarn clean && yarn generate && tsc -b", + "generate": "yarn generate:noir-contracts", + "generate:noir-contracts": "./scripts/copy-contracts.sh" + } +} diff --git a/yarn-project/types/scripts/copy-contracts.sh b/yarn-project/types/scripts/copy-contracts.sh new file mode 100755 index 000000000000..d64da5b967a2 --- /dev/null +++ b/yarn-project/types/scripts/copy-contracts.sh @@ -0,0 +1,5 @@ +#! /bin/bash +set -euo pipefail +mkdir -p ./fixtures + +cp "../../noir-projects/noir-contracts/target/benchmarking_contract-Benchmarking.json" ./fixtures/Benchmarking.test.json diff --git a/yarn-project/types/src/abi/contract_artifact.test.ts b/yarn-project/types/src/abi/contract_artifact.test.ts new file mode 100644 index 000000000000..de830666e093 --- /dev/null +++ b/yarn-project/types/src/abi/contract_artifact.test.ts @@ -0,0 +1,12 @@ +import { getSampleContractArtifact } from '../test/fixtures.js'; +import { contractArtifactFromBuffer, contractArtifactToBuffer } from './contract_artifact.js'; + +describe('contract_artifact', () => { + it('serializes and deserializes an instance', () => { + const artifact = getSampleContractArtifact(); + delete artifact.aztecNrVersion; + const serialized = contractArtifactToBuffer(artifact); + const deserialized = contractArtifactFromBuffer(serialized); + expect(deserialized).toEqual(artifact); + }); +}); diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index 04f820181948..ac6208bb3450 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -23,8 +23,21 @@ import { mockVerificationKey } from './mocked_keys.js'; * @returns A buffer. */ export function contractArtifactToBuffer(artifact: ContractArtifact): Buffer { - // TODO(@spalladino): More efficient serialization - return Buffer.from(JSON.stringify(artifact), 'utf8'); + return Buffer.from( + JSON.stringify(artifact, (key, value) => { + if ( + key === 'bytecode' && + value !== null && + typeof value === 'object' && + value.type === 'Buffer' && + Array.isArray(value.data) + ) { + return Buffer.from(value.data).toString('base64'); + } + return value; + }), + 'utf-8', + ); } /** @@ -33,8 +46,12 @@ export function contractArtifactToBuffer(artifact: ContractArtifact): Buffer { * @returns Deserialized artifact. */ export function contractArtifactFromBuffer(buffer: Buffer): ContractArtifact { - // TODO(@spalladino): More efficient serialization - return JSON.parse(buffer.toString('utf8')) as ContractArtifact; + return JSON.parse(buffer.toString('utf-8'), (key, value) => { + if (key === 'bytecode' && typeof value === 'string') { + return Buffer.from(value, 'base64'); + } + return value; + }); } /** @@ -130,7 +147,7 @@ function generateFunctionArtifact(fn: NoirCompiledContractFunction): FunctionArt isInitializer: fn.custom_attributes.includes(AZTEC_INITIALIZER_ATTRIBUTE), parameters, returnTypes, - bytecode: fn.bytecode, + bytecode: Buffer.from(fn.bytecode, 'base64'), verificationKey: mockVerificationKey, debugSymbols: fn.debug_symbols, }; diff --git a/yarn-project/types/src/contracts/contract_class.ts b/yarn-project/types/src/contracts/contract_class.ts index c575485ad337..a532dfb9e1cf 100644 --- a/yarn-project/types/src/contracts/contract_class.ts +++ b/yarn-project/types/src/contracts/contract_class.ts @@ -1,6 +1,5 @@ import { FunctionSelector } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; -import { PartialBy } from '@aztec/foundation/types'; const VERSION = 1 as const; @@ -28,11 +27,6 @@ export interface PrivateFunction { selector: FunctionSelector; /** Hash of the verification key associated to this private function. */ vkHash: Fr; - /** - * Whether the function is internal. - * @deprecated To be reimplemented as an app-level macro. - */ - isInternal: boolean; } /** Public function definition within a contract class. */ @@ -41,11 +35,14 @@ export interface PublicFunction { selector: FunctionSelector; /** Public bytecode. */ bytecode: Buffer; - /** - * Whether the function is internal. - * @deprecated To be reimplemented as an app-level macro. - */ - isInternal: boolean; +} + +/** Unconstrained function definition. */ +export interface UnconstrainedFunction { + /** Selector of the function. Calculated as the hash of the method name and parameters. The specification of this is not enforced by the protocol. */ + selector: FunctionSelector; + /** Brillig. */ + bytecode: Buffer; } /** Commitments to fields of a contract class. */ @@ -61,6 +58,41 @@ interface ContractClassCommitments { /** A contract class with its precomputed id. */ export type ContractClassWithId = ContractClass & Pick; -/** A contract class with public bytecode information only. */ -export type ContractClassPublic = PartialBy & - Pick; +/** A contract class with public bytecode information, and optional private and unconstrained. */ +export type ContractClassPublic = { + privateFunctions: ExecutablePrivateFunctionWithMembershipProof[]; + unconstrainedFunctions: UnconstrainedFunctionWithMembershipProof[]; +} & Pick & + Omit; + +/** Private function definition with executable bytecode. */ +export interface ExecutablePrivateFunction extends PrivateFunction { + /** ACIR and Brillig bytecode */ + bytecode: Buffer; +} + +/** Sibling paths and sibling commitments for proving membership of a private function within a contract class. */ +export type PrivateFunctionMembershipProof = { + artifactMetadataHash: Fr; + functionMetadataHash: Fr; + unconstrainedFunctionsArtifactTreeRoot: Fr; + privateFunctionTreeSiblingPath: Fr[]; + privateFunctionTreeLeafIndex: number; + artifactTreeSiblingPath: Fr[]; + artifactTreeLeafIndex: number; +}; + +/** A private function with a memebership proof. */ +export type ExecutablePrivateFunctionWithMembershipProof = ExecutablePrivateFunction & PrivateFunctionMembershipProof; + +/** Sibling paths and commitments for proving membership of an unconstrained function within a contract class. */ +export type UnconstrainedFunctionMembershipProof = { + artifactMetadataHash: Fr; + functionMetadataHash: Fr; + privateFunctionsArtifactTreeRoot: Fr; + artifactTreeSiblingPath: Fr[]; + artifactTreeLeafIndex: number; +}; + +/** An unconstrained function with a membership proof. */ +export type UnconstrainedFunctionWithMembershipProof = UnconstrainedFunction & UnconstrainedFunctionMembershipProof; diff --git a/yarn-project/types/src/test/fixtures.ts b/yarn-project/types/src/test/fixtures.ts new file mode 100644 index 000000000000..4395b58033d8 --- /dev/null +++ b/yarn-project/types/src/test/fixtures.ts @@ -0,0 +1,19 @@ +import { ContractArtifact } from '@aztec/foundation/abi'; + +import { readFileSync } from 'fs'; +import { dirname, resolve } from 'path'; +import { fileURLToPath } from 'url'; + +import { loadContractArtifact } from '../abi/contract_artifact.js'; +import { NoirCompiledContract } from '../noir/index.js'; + +// Copied from the build output for the contract `Benchmarking` in noir-contracts +export function getSampleContractArtifact(): ContractArtifact { + const path = getPathToFixture('Benchmarking.test.json'); + const content = JSON.parse(readFileSync(path).toString()) as NoirCompiledContract; + return loadContractArtifact(content); +} + +function getPathToFixture(name: string) { + return resolve(dirname(fileURLToPath(import.meta.url)), `../../fixtures/${name}`); +} diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index d29b415fdfae..32879e1ec799 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -96,6 +96,7 @@ __metadata: "@jest/globals": ^29.5.0 "@types/debug": ^4.1.7 "@types/jest": ^29.5.0 + "@types/lodash.groupby": ^4.6.9 "@types/lodash.omit": ^4.5.7 "@types/node": ^18.15.11 "@types/ws": ^8.5.4 @@ -104,6 +105,7 @@ __metadata: jest: ^29.5.0 jest-mock-extended: ^3.0.4 lmdb: ^2.9.2 + lodash.groupby: ^4.6.0 lodash.omit: ^4.5.0 ts-jest: ^29.1.0 ts-node: ^10.9.1 @@ -3427,6 +3429,15 @@ __metadata: languageName: node linkType: hard +"@types/lodash.groupby@npm:^4.6.9": + version: 4.6.9 + resolution: "@types/lodash.groupby@npm:4.6.9" + dependencies: + "@types/lodash": "*" + checksum: b8310a9f89badc42a504887ca0b9619c2a284b3fec8dc505cf72508eb6beba47b822df939c7d57c0f69bc685f51ff5a232e0480ecad6b18b7ab76fecc1d74691 + languageName: node + linkType: hard + "@types/lodash.isequal@npm:^4.5.6": version: 4.5.8 resolution: "@types/lodash.isequal@npm:4.5.8" @@ -9597,6 +9608,13 @@ __metadata: languageName: node linkType: hard +"lodash.groupby@npm:^4.6.0": + version: 4.6.0 + resolution: "lodash.groupby@npm:4.6.0" + checksum: e2d4d13d12790a1cacab3f5f120b7c072a792224e83b2f403218866d18efde76024b2579996dfebb230a61ce06469332e16639103669a35a605287e19ced6b9b + languageName: node + linkType: hard + "lodash.isequal@npm:^4.5.0": version: 4.5.0 resolution: "lodash.isequal@npm:4.5.0" diff --git a/yellow-paper/docs/contract-deployment/classes.md b/yellow-paper/docs/contract-deployment/classes.md index 8befe02ea27a..b9083a13921f 100644 --- a/yellow-paper/docs/contract-deployment/classes.md +++ b/yellow-paper/docs/contract-deployment/classes.md @@ -165,7 +165,9 @@ function broadcast_private_function( artifact_metadata_hash: Field, unconstrained_functions_artifact_tree_root: Field, private_function_tree_sibling_path: Field[], + private_function_tree_leaf_index: Field, artifact_function_tree_sibling_path: Field[], + artifact_function_tree_leaf_index: Field, function: { selector: Field, metadata_hash: Field, vk_hash: Field, bytecode: Field[] }, ) emit_unencrypted_event ClassPrivateFunctionBroadcasted( @@ -173,7 +175,9 @@ function broadcast_private_function( artifact_metadata_hash, unconstrained_functions_artifact_tree_root, private_function_tree_sibling_path, + private_function_tree_leaf_index, artifact_function_tree_sibling_path, + artifact_function_tree_leaf_index, function, ) ``` @@ -184,6 +188,7 @@ function broadcast_unconstrained_function( artifact_metadata_hash: Field, private_functions_artifact_tree_root: Field, artifact_function_tree_sibling_path: Field[], + artifact_function_tree_leaf_index: Field function: { selector: Field, metadata_hash: Field, bytecode: Field[] }[], ) emit_unencrypted_event ClassUnconstrainedFunctionBroadcasted( @@ -191,6 +196,7 @@ function broadcast_unconstrained_function( artifact_metadata_hash, private_functions_artifact_tree_root, artifact_function_tree_sibling_path, + artifact_function_tree_leaf_index, function, ) ``` @@ -207,12 +213,12 @@ contract_class = db.get_contract_class(contract_class_id) // Compute function leaf and assert it belongs to the private functions tree function_leaf = pedersen([selector as Field, vk_hash], GENERATOR__FUNCTION_LEAF) -computed_private_function_tree_root = compute_root(function_leaf, private_function_tree_sibling_path) +computed_private_function_tree_root = compute_root(function_leaf, private_function_tree_sibling_path, private_function_tree_leaf_index) assert computed_private_function_tree_root == contract_class.private_function_root // Compute artifact leaf and assert it belongs to the artifact artifact_function_leaf = sha256(selector, metadata_hash, sha256(bytecode)) -computed_artifact_private_function_tree_root = compute_root(artifact_function_leaf, artifact_function_tree_sibling_path) +computed_artifact_private_function_tree_root = compute_root(artifact_function_leaf, artifact_function_tree_sibling_path, artifact_function_tree_leaf_index) computed_artifact_hash = sha256(computed_artifact_private_function_tree_root, unconstrained_functions_artifact_tree_root, artifact_metadata_hash) assert computed_artifact_hash == contract_class.artifact_hash ``` @@ -227,7 +233,7 @@ contract_class = db.get_contract_class(contract_class_id) // Compute artifact leaf and assert it belongs to the artifact artifact_function_leaf = sha256(selector, metadata_hash, sha256(bytecode)) -computed_artifact_unconstrained_function_tree_root = compute_root(artifact_function_leaf, artifact_function_tree_sibling_path) +computed_artifact_unconstrained_function_tree_root = compute_root(artifact_function_leaf, artifact_function_tree_sibling_path, artifact_function_tree_leaf_index) computed_artifact_hash = sha256(private_functions_artifact_tree_root, computed_artifact_unconstrained_function_tree_root, artifact_metadata_hash) assert computed_artifact_hash == contract_class.artifact_hash ```