From 7c24f468e4bf10da9f658aceb3df8c02d7af6f03 Mon Sep 17 00:00:00 2001 From: Piotr Witek Date: Fri, 17 Jun 2022 08:41:57 +0200 Subject: [PATCH] Added generic contract JS client with e2e-tests and documentation (#72) * Finished generic client with e2e-tests and documentation * Extended CLTypeDict --- Makefile | 2 +- README.md | 1 + client/README.md | 39 +++- client/e2e/e2e-generic-client-local.ts | 122 ++++++++++ client/e2e/e2e-generic-client.ts | 208 +++++++++++++++++ client/e2e/utils.ts | 6 +- client/package.json | 13 +- client/src/generic-client/generic-client.ts | 214 ++++++++++++++++++ client/src/index.ts | 2 + client/wasm/reputation_contract.wasm | Bin 0 -> 154689 bytes client/wasm/reputation_contract_schema.yaml | 140 ++++++++++++ resources/reputation_contract_schema.yaml | 64 +++--- .../variable_repository_contract_schema.yaml | 72 +++--- 13 files changed, 811 insertions(+), 72 deletions(-) create mode 100644 client/e2e/e2e-generic-client-local.ts create mode 100644 client/e2e/e2e-generic-client.ts create mode 100644 client/src/generic-client/generic-client.ts create mode 100755 client/wasm/reputation_contract.wasm create mode 100644 client/wasm/reputation_contract_schema.yaml diff --git a/Makefile b/Makefile index 146e5390..444c68ad 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CARGO_TEST = cargo test --features=test-support --no-default-features prepare: rustup target add wasm32-unknown-unknown - cargo install cargo-expand --version 1.0.17 + # cargo install cargo-expand build-proxy-getter: $(CARGO_BUILD) -p casper-dao-utils --bin getter_proxy diff --git a/README.md b/README.md index 22ce80bc..db3d6d9b 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ Reusable smart contracts for building DAOs on top of Casper. Repository contains following modules: - `dao-contracts` and `dao-modules` provides smart contracts implementation, +- `dao-erc20` and `dao-erc721` allows to use those standards, - `dao-utils` and `dao-macros` makes writing code easier, - `client` implements a JavaScript client for smart contracts interactions. diff --git a/client/README.md b/client/README.md index 9e20f052..e57a371c 100644 --- a/client/README.md +++ b/client/README.md @@ -1,6 +1,6 @@ # `dao-contracts-js-client` -This JavaScript client gives you an easy way to install and interact with the DAO Reputation contract. +This JavaScript client gives you an easy way to install and interact with all the DAO contracts. ## Installation @@ -15,24 +15,29 @@ npm i dao-contracts-js-client ### Install the contract on the network ```ts -const installDeployHash = await installReputationContract( +// create deploy +const deploy = createInstallReputationContractDeploy( CHAIN_NAME, NODE_ADDRESS, - KEYS, // Key pair used for signing 200000000000, // Payment amount "../target/wasm32-unknown-unknown/release/reputation_contract.wasm" // Path to WASM file + OWNER_KEYS, // Key pair used for signing deploy ); + +// send deploy to network +const installDeployHash = await installDeploy.send(NODE_ADDRESS); ``` -### Create an instance to interact with the contract +### Create a client instance to interact with the contract ```ts -const reputationContract = new ReputationContractJSClient( +const reputationContract = new GenericContractJSClient( http://localhost:11101, // RPC address "casper-net-1", // Network name "http://localhost:18101/events/main", // Event stream address "hash-XXXXXXXXXXXXXXXXXXXXx", // contractPackageHash "hash-XXXXXXXXXXXXXXXXXXXXx", // contractHash + 'path-to-contract-yaml-schema-file' ); ``` @@ -43,8 +48,11 @@ const reputationContract = new ReputationContractJSClient( Use getter methods to retrieve values: ```ts -const owner = await reputationContract.getOwner(); -const total_supply = await reputationContract.getTotalSupply(); +const total_supply = + await reputationContract.getNamedKey("total_supply"); + +const isWhitelisted = + await reputationContract.getNamedKey("whitelist", publicKey); ``` ### Deploys @@ -54,12 +62,21 @@ Use deploys to interact with contract: ```ts const mintAmount = "200000000000"; -const deployHashMint = await reputationContract.mint( +const mintResult: Result = await reputationContract.callEntryPoint( + "mint", ownerKeys, - ownerKeys.publicKey, - mintAmount, - DEPLOY_PAYMENT_AMOUNT + DEPLOY_PAYMENT_AMOUNT, + createRecipientAddress(ownerKeys.publicKey), // import { createRecipientAddress } from "casper-js-client-helper/dist/helpers/lib"; + CLValueBuilder.u256(mintAmount) ); + +if (mintResult.ok) { + // handle success + mintResult.val +} else { + // handle error + mintResult.val +} ``` ## Development diff --git a/client/e2e/e2e-generic-client-local.ts b/client/e2e/e2e-generic-client-local.ts new file mode 100644 index 00000000..ffef66d7 --- /dev/null +++ b/client/e2e/e2e-generic-client-local.ts @@ -0,0 +1,122 @@ +import BigNumber from "bignumber.js"; +import { utils } from "casper-js-client-helper"; +import { createRecipientAddress } from "casper-js-client-helper/dist/helpers/lib"; +import { + CLKey, + CLKeyParameters, + CLPublicKey, + CLU256, + CLValue, + CLValueBuilder, + EventName, + EventStream, + Keys, +} from "casper-js-sdk"; +import { Option, Result } from "ts-results"; + +if (process.env.NODE_ENV !== "ci") { + require("dotenv").config({ path: "./.env", debug: true }); +} + +import { + createInstallReputationContractDeploy, + ReputationContractEventParser, + ReputationContractEvents, + GenericContractJSClient, +} from "../src"; +import { createRpcClient } from "../src/common/rpc-client"; +import { + getAccountInfo, + getAccountNamedKeyValue, + waitForDeploy, + assert, +} from "./utils"; + +const { + NODE_ENV, + CHAIN_NAME, + NODE_ADDRESS, + EVENT_STREAM_ADDRESS, + WASM_RELEASE_PATH, + NCTL_USERS_FOLDER_PATH, + INSTALL_PAYMENT_AMOUNT, + DEPLOY_PAYMENT_AMOUNT, +} = process.env; + +console.log("testing env variables", { + NODE_ENV, + CHAIN_NAME, + NODE_ADDRESS, + EVENT_STREAM_ADDRESS, + WASM_RELEASE_PATH, + NCTL_USERS_FOLDER_PATH, + INSTALL_PAYMENT_AMOUNT, + DEPLOY_PAYMENT_AMOUNT, +}); + +const ownerKeys = Keys.Ed25519.parseKeyFiles( + `${NCTL_USERS_FOLDER_PATH}/user-1/public_key.pem`, + `${NCTL_USERS_FOLDER_PATH}/user-1/secret_key.pem` +); +const recipientKeys = Keys.Ed25519.parseKeyFiles( + `${NCTL_USERS_FOLDER_PATH}/user-2/public_key.pem`, + `${NCTL_USERS_FOLDER_PATH}/user-2/secret_key.pem` +); +const test = async () => { + /** SCHEMA */ + + const reputationContractSchema = { + entry_points: { + mint: [ + { name: "recipient", cl_type: "Address" }, + { name: "amount", cl_type: "U256" }, + ], + add_to_whitelist: [{ name: "address", cl_type: "Address" }], + }, + named_keys: { + owner: { + named_key: "owner_owner_access_control_contract", + cl_type: [{ name: "Option", inner: "Address" }], + }, + total_supply: { + named_key: "total_supply_token_token_contract", + cl_type: "U256", + }, + balance: { + named_key: "balances_token_token_contract", + cl_type: [{ name: "Mapping", key: "Address", value: "U256" }], + }, + whitelist: { + named_key: "whitelist_whitelist_access_control_contract", + cl_type: [{ name: "Mapping", key: "Address", value: "Bool" }], + }, + stakes: { + named_key: "token_stakes", + cl_type: [{ name: "Mapping", key: "Address", value: "U256" }], + }, + }, + }; + + const contractHashWithHashPrefix = + "hash-10539a97a58adf60498ecd0e7be1f7284c6dcc01a09154f45f97c8fc5d395a7e"; + const contractPackageHash = + "hash-49f5fc30a7888b74508a1ee4365353e858a4fc26ff1cdd3d7a81a7aff36d5276"; + + // Initialize contract client + const reputationContract = new GenericContractJSClient( + NODE_ADDRESS, + CHAIN_NAME, + EVENT_STREAM_ADDRESS, + contractHashWithHashPrefix, + contractPackageHash, + reputationContractSchema + ); + + console.log(`\n`); + console.log(`... Testing deploys ...`); + +}; + +test().then(() => { + process.exit(0); +}); diff --git a/client/e2e/e2e-generic-client.ts b/client/e2e/e2e-generic-client.ts new file mode 100644 index 00000000..ffb47df6 --- /dev/null +++ b/client/e2e/e2e-generic-client.ts @@ -0,0 +1,208 @@ +import BigNumber from "bignumber.js"; +import { utils } from "casper-js-client-helper"; +import { createRecipientAddress } from "casper-js-client-helper/dist/helpers/lib"; +import { + CLKey, + CLKeyParameters, + CLU256, + CLValue, + CLValueBuilder, + EventName, + EventStream, + Keys, +} from "casper-js-sdk"; +import { Option, Result } from "ts-results"; + +if (process.env.NODE_ENV !== "ci") { + require("dotenv").config({ path: "./.env", debug: true }); +} + +import { + createInstallReputationContractDeploy, + ReputationContractEventParser, + ReputationContractEvents, + GenericContractJSClient, +} from "../src"; +import { createRpcClient } from "../src/common/rpc-client"; +import { + getAccountInfo, + getAccountNamedKeyValue, + waitForDeploy, + assert, +} from "./utils"; + +const { + NODE_ENV, + CHAIN_NAME, + NODE_ADDRESS, + EVENT_STREAM_ADDRESS, + WASM_RELEASE_PATH, + NCTL_USERS_FOLDER_PATH, + INSTALL_PAYMENT_AMOUNT, + DEPLOY_PAYMENT_AMOUNT, +} = process.env; + +console.log("testing env variables", { + NODE_ENV, + CHAIN_NAME, + NODE_ADDRESS, + EVENT_STREAM_ADDRESS, + WASM_RELEASE_PATH, + NCTL_USERS_FOLDER_PATH, + INSTALL_PAYMENT_AMOUNT, + DEPLOY_PAYMENT_AMOUNT, +}); + +const ownerKeys = Keys.Ed25519.parseKeyFiles( + `${NCTL_USERS_FOLDER_PATH}/user-1/public_key.pem`, + `${NCTL_USERS_FOLDER_PATH}/user-1/secret_key.pem` +); +const recipientKeys = Keys.Ed25519.parseKeyFiles( + `${NCTL_USERS_FOLDER_PATH}/user-2/public_key.pem`, + `${NCTL_USERS_FOLDER_PATH}/user-2/secret_key.pem` +); + +const wasmContractPath = WASM_RELEASE_PATH + "/reputation_contract.wasm"; +const wasmContractSchemaPath = + WASM_RELEASE_PATH + "/reputation_contract_schema.yaml"; + +const test = async () => { + console.log(`\n`); + console.log(`... Testing install ...`); + console.log(`\n`); + + const installDeploy = createInstallReputationContractDeploy( + CHAIN_NAME, + NODE_ADDRESS, + INSTALL_PAYMENT_AMOUNT, + wasmContractPath, + ownerKeys + ); + + const installDeployHash = await installDeploy.send(NODE_ADDRESS); + await waitForDeploy(NODE_ADDRESS, installDeployHash); + let accountInfo = await getAccountInfo(NODE_ADDRESS, ownerKeys.publicKey); + const contractPackageHash = await getAccountNamedKeyValue( + accountInfo, + `reputation_contract_package_hash` + ); + if (!contractPackageHash) { + throw Error("Contract not installed correctly!"); + } + + console.log(`... Contract installed successfully.`); + console.log(` - Contract Package Hash: ${contractPackageHash}`); + + const stateRootHash = await utils.getStateRootHash(NODE_ADDRESS); + const rpcClient = createRpcClient(NODE_ADDRESS); + const res = await rpcClient.fetchStateGetItem( + stateRootHash, + contractPackageHash, + [] + ); + const contractHash = res.ContractPackage.versions[0].contract_hash; + const contractHashWithHashPrefix = contractHash.replace("contract-", "hash-"); + console.log(` - Contract Hash: ${contractHashWithHashPrefix}`); + + /** SCHEMA */ + + // Initialize contract client + const reputationContract = new GenericContractJSClient( + NODE_ADDRESS, + CHAIN_NAME, + EVENT_STREAM_ADDRESS, + contractHashWithHashPrefix, + contractPackageHash, + wasmContractSchemaPath + ); + + console.log(`\n`); + console.log(`... Testing deploys ...`); + + /** MINT DEPLOY */ + + console.log(`\n`); + console.log(" - Trying to create and send a mint deploy"); + + const mintAmount = "200000000000"; + const mintResult: Result = + await reputationContract.callEntryPoint( + "mint", + ownerKeys, + DEPLOY_PAYMENT_AMOUNT, + createRecipientAddress(ownerKeys.publicKey), + CLValueBuilder.u256(mintAmount) + ); + // console.log('mintDeployResult',JSON.stringify(mintResult, null, 2)); + + if (mintResult.ok) { + await waitForDeploy(NODE_ADDRESS, mintResult.val); + const total_supply_after_mint = (await reputationContract.getNamedKey( + "total_supply" + )) as BigNumber; // should be CLU256 but sdk returns BigNumber, need to fix in casper-js-sdk + console.log( + ` - Requested Mint Amount: `, + mintAmount + ); + console.log( + ` - Total Supply After Mint: `, + total_supply_after_mint.toString() + ); + const totalSupplyEqMint = total_supply_after_mint.eq(mintAmount); + + console.log( + ` - Total supply equals mint: ${ + totalSupplyEqMint ? "SUCCESS!" : "FAILED!" + }` + ); + assert(totalSupplyEqMint); + } else { + console.error(mintResult.val); + process.exit(1); + } + + /** WHITELIST DEPLOY */ + + console.log(`\n`); + console.log(" - Trying to create and send a add to whitelist deploy"); + + const isWhitelistedBefore = (await reputationContract.getNamedKey( + "whitelist", + recipientKeys.publicKey + )) as Boolean; + console.log(` - Whitelist Value Before Deploy: ${isWhitelistedBefore}`); + + const whitelistResult: Result = + await reputationContract.callEntryPoint( + "add_to_whitelist", + ownerKeys, + DEPLOY_PAYMENT_AMOUNT, + createRecipientAddress(recipientKeys.publicKey) + ); + // console.log("whitelistResult", JSON.stringify(whitelistResult, null, 2)); + + if (whitelistResult.ok) { + await waitForDeploy(NODE_ADDRESS, whitelistResult.val); + const isWhitelisted = await reputationContract.getNamedKey( + "whitelist", + recipientKeys.publicKey + ); + console.log(` - Whitelist Value After Deploy: ${isWhitelisted}`); + + const recipientAddedToTheWhitelist = "true" === isWhitelisted; + + console.log( + ` - Recipient is added to the whitelist: ${ + recipientAddedToTheWhitelist ? "SUCCESS!" : "FAILED!" + }` + ); + assert(recipientAddedToTheWhitelist); + } else { + console.error(whitelistResult.val); + process.exit(1); + } +}; + +test().then(() => { + process.exit(0); +}); diff --git a/client/e2e/utils.ts b/client/e2e/utils.ts index 81d0d940..0bd59e08 100644 --- a/client/e2e/utils.ts +++ b/client/e2e/utils.ts @@ -1,7 +1,10 @@ import { CasperClient, CasperServiceByJsonRPC, + CLKey, + CLKeyParameters, CLPublicKey, + CLValue, } from "casper-js-sdk"; export const sleep = (ms: number) => { @@ -89,7 +92,8 @@ export const createDictionaryGetter = async ( path: string, account: CLPublicKey ) => { - const key = encodeAccountHashStrAsKey(account.toAccountHashStr()); + const accountHashStr = account.toAccountHashStr(); + const key = encodeAccountHashStrAsKey(accountHashStr); try { const result = await contractClient.queryContractDictionary(path, key); return result.value().toString(); diff --git a/client/package.json b/client/package.json index 93e4c7a0..53486b87 100644 --- a/client/package.json +++ b/client/package.json @@ -12,11 +12,14 @@ ], "dependencies": { "@open-rpc/client-js": "1.7.1", - "casper-js-client-helper": "1.0.0", - "casper-js-sdk": "2.8.0" + "bignumber.js": "9.0.2", + "casper-js-client-helper": "1.0.1", + "casper-js-sdk": "2.9.1", + "ts-results": "3.3.0", + "yaml": "2.1.1" }, "devDependencies": { - "dotenv": "16.0.0", + "dotenv": "16.0.1", "ts-node": "10.5.0", "typescript": "4.5.5" }, @@ -27,6 +30,8 @@ "dist": "npm run clean && npm run build", "clean": "rm -rf dist/", "build": "tsc -p tsconfig.build.json", - "e2e:reputation": "ts-node ./e2e/e2e-reputation.ts" + "e2e:reputation": "ts-node ./e2e/e2e-reputation.ts", + "e2e:generic-client": "ts-node ./e2e/e2e-generic-client.ts", + "e2e:generic-client-local": "ts-node ./e2e/e2e-generic-client-local.ts" } } diff --git a/client/src/generic-client/generic-client.ts b/client/src/generic-client/generic-client.ts new file mode 100644 index 00000000..b20ff495 --- /dev/null +++ b/client/src/generic-client/generic-client.ts @@ -0,0 +1,214 @@ +import { CasperContractClient } from "casper-js-client-helper"; +import { + CasperClient, + CLBool, + CLKey, + CLPublicKey, + CLU128, + CLU256, + CLU32, + CLU512, + CLU64, + CLU8, + CLValueBuilder, + Contracts, + Keys, + RuntimeArgs, +} from "casper-js-sdk"; +import fs from "fs"; +import { Err, Ok, Result } from "ts-results"; +import YAML from "yaml"; + +import { createDictionaryGetter } from "../../e2e/utils"; +import { DEFAULT_TTL } from "../common/constants"; +import { createRpcClient } from "../common/rpc-client"; + +/** TYPES */ + +export type GenericContractSchema = { + entry_points: Record; + named_keys: Record< + string, + { + named_key: string; + cl_type: GenericContractSchemaClType; + } + >; +}; + +export type GenericContractSchemaArguments = { + name: string; + cl_type: string; +}[]; + +export type GenericContractSchemaClType = + | string + | Array< + | { name: string; inner: string } + | { name: string; key: string; value: string } + >; + +/** CONSTANTS */ +const CLTypeDict = { + Address: CLKey, + U8: CLU8, + U32: CLU32, + U64: CLU64, + U128: CLU128, + U256: CLU256, + U512: CLU512, + Bool: CLBool, +}; + +/** MAIN */ + +export class GenericContractJSClient< + T extends GenericContractSchema +> extends CasperContractClient { + protected rpcClient: ReturnType; + protected contractClient: Contracts.Contract; + + constructor( + nodeAddress: string, + chainName: string, + eventStreamAddress: string, + contractHash: string, + contractPackageHash: string, + schemaPath: string + ) { + super(nodeAddress, chainName, eventStreamAddress); + this.contractClient = new Contracts.Contract(new CasperClient(nodeAddress)); + this.contractClient.setContractHash(contractHash, contractPackageHash); + this.rpcClient = createRpcClient(nodeAddress); + + const file = fs.readFileSync(schemaPath, "utf8"); + const parsed: { + entry_points: Array<{ + name: string; + arguments: Array<{ name: string; cl_type: string }>; + }>; + named_keys: Array<{ + name: string; + named_key: string; + cl_type: GenericContractSchemaClType; + }>; + } = YAML.parse(file); + + const schema: GenericContractSchema = { + entry_points: parsed.entry_points.reduce((result, val) => { + result[val.name] = { arguments: val.arguments }; + return result; + }, {} as GenericContractSchema['entry_points']), + named_keys: parsed.named_keys.reduce((result, val) => { + result[val.name] = { named_key: val.named_key, cl_type: val.cl_type }; + return result; + }, {} as GenericContractSchema['named_keys']), + }; + + const { entry_points, named_keys } = schema; + + // create entry_points deploy creator methods and attach to the class instance + for (const key in entry_points) { + const argsSchema = entry_points[key].arguments; + this[`${key}`] = this.createEntryPointMethod(argsSchema); + } + + // create named_keys getters methods and attach to the class instance + for (const key in named_keys) { + const { named_key: name, cl_type } = named_keys[key]; + this[`${key}`] = this.createNamedKeyGetterMethod(name, cl_type); + } + } + + public callEntryPoint( + name: string, + keys: Keys.AsymmetricKey = undefined, + paymentAmount: string, + ...args + ): Promise> { + return this[name](name, keys, paymentAmount, ...args); + } + + createEntryPointMethod( + argsSchema: { + name: string; + cl_type: string; + }[] + ) { + return async ( + name: string, + keys: Keys.AsymmetricKey = undefined, + paymentAmount: string, + ...args + ) => { + const runtimeArgs = RuntimeArgs.fromMap({}); + // prepare runtime args + for (let index = 0; index < argsSchema.length; index++) { + const argDefinition = argsSchema[index]; + // argument cl type validation + const arg = args[index]; + if (!(arg instanceof CLTypeDict[argDefinition.cl_type])) { + return Err( + `Invalid type for ${argDefinition.name} argument, expected ${argDefinition.cl_type}` + ); + } + runtimeArgs.insert(argDefinition.name, arg); + } + + const deploy = this.contractClient.callEntrypoint( + name, + runtimeArgs, + keys.publicKey, + this.chainName, + paymentAmount, + [keys] + ); + const deployHash = await deploy.send(this.nodeAddress); + + return Ok(deployHash); // new is optional here + }; + } + + public async getNamedKey(name: string, ...args: any[]): Promise { + return await this[name](...args); + } + + private createNamedKeyGetterMethod( + name: string, + schemaClType: GenericContractSchemaClType + ) { + return async (...args: any[]) => { + if (typeof schemaClType === "string") { + const CLTypeClass = CLTypeDict[schemaClType]; + if (CLTypeClass) { + // this method returns parsed cltype value from sdk + const value = await this.contractClient.queryContractData([name]); + // console.log(` - sdk: ${JSON.stringify(value, null, 2)}`); + return value; + } + } else if (Array.isArray(schemaClType) && schemaClType[0]) { + const clTypeObj = schemaClType[0]; + if ("inner" in clTypeObj) { + // this method returns parsed cltype value from sdk + const value = await this.contractClient.queryContractData([name]); + // console.log(` - sdk: ${JSON.stringify(value, null, 2)}`); + return value; + } else if ("key" in clTypeObj && "value" in clTypeObj) { + if (clTypeObj.name === "Mapping") { + const ArgumentClass = CLTypeDict[clTypeObj.key]; + const value = await createDictionaryGetter( + this.contractClient, + name, + args[0] + // new ArgumentClass(args[0]) + ); + // console.log(` sdk value: ${JSON.stringify(value, null, 2)}`); + return value; + } + } + } + + throw Error("Unknown CLType, possibly the library is outdated."); + }; + } +} diff --git a/client/src/index.ts b/client/src/index.ts index 47308015..61480287 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -4,10 +4,12 @@ import { } from "./reputation/events"; import { ReputationContractJSClient } from "./reputation/client"; import { createInstallReputationContractDeploy } from "./reputation/install"; +import { GenericContractJSClient } from "./generic-client/generic-client"; export { createInstallReputationContractDeploy, ReputationContractJSClient, ReputationContractEvents, ReputationContractEventParser, + GenericContractJSClient }; diff --git a/client/wasm/reputation_contract.wasm b/client/wasm/reputation_contract.wasm new file mode 100755 index 0000000000000000000000000000000000000000..f086e2c6a4e0848706e04265cfc68943a6bacb8b GIT binary patch literal 154689 zcmeFa3zTJ7RqwrD=hUe>r>b{{CN${)`y8THKIxm*k(-Wz&r!PvkZ|L@<~s5*;vIfp zI+9?hgb+Fn#ybKjAV32_1A<0GZ;%E8f(At%irNBV1ccTL8n39$Lv9qsT!|VL<@^2T zTx;)rPF3|I4+N4l)Y*IPwbx^=`C4<%wRUpJHP1|wBuU?#p1e1^{`&NK{Z01f*V}c$ zk6BX1q`=KP)qs8!O-(}Ce zY~TK*5bV(b_Owf`yz*ke*F57{SMko%o^{p!eV06Kf6`N-hlfI!KI3Wod49>hA5ry5 zf0JidKWBe3r)OK61~0kv;^$s+<#R4eGQmdy{=@s8vH!AUAkdZoy6UnYzW6!&E_-@1 zFX*=h=+pLHcFF$BnqFOe^(9Zc;*uY_?BYxIUwru`*Ie#}$D0&>&NV{EzGpq>>SRHc zJ|dK(&Py-8{8`uRzxW5A^Yo`*w$JmxcjxcQ=jV%JRLn0n|AECMEs6mT(qevokf!PU{9-XbS}Ky!;`}Hn z(zHki1IiQ$|1XO9f&QbM|2J>{6^r(aKNK%UTSoD*LAY5IJSoc27A`3P$jT0^X! zdXh#RQId>!0{|mNmZ+y$Nvmm=BvjUCNTboilBCQAqfs`R&qj09$@Gjy+Xh>Bn5mKE z;cAx${8#kStJ8DO?d55*wg1Tc`m|nKJCqEsPwIDmvhzFlhIFz2%*&qntbIR{C52`_ zIi+~URnOR;>?of3jH~u1rxri>oPAd%k6MJuuet`>zxe6RCU0 z6{6tsXIz~;rW9%Kf7Zo6d^x;&{d%aY05bFT8M$1Yra z@uipSzvSY}uDUc&hZkRb`DK?}een-oa?NFVHh&X1sng+;U!DGJ`ZMXP(w|CyBE30% zUHZcOzrQnm;uq2{rhlFOP5Pzu%jwu}nSCnzaQ5T*C$fLY zUY&m|`&@Q=_B+|(>~FKXvj3C)UH0+pL)izjFK2gWzn%R{_RrZp**|4B=0B1DSpJ^; zMfp$Xug`DDUzPuCerx{L{80Y3{O9wx=f9QzX1?%iM+Wc8ztqe7*B8&vuYc?s|0VTJ z=@pawG`p_ydazohRaXAV3wV^R_`fP&&IV6fw0m8TCdFb>C(9X=vzCl|qjad3s-pai zUYqo|vii!GzfkvS{nhl@^|zn9mOnD{(@!!PRDF8;!50BPg|c^0cV4fhtEcD5?v$eSVT0V0w2<2k za#stX)ScmOWtgp01w&O2>$H568XVT?xTxsglNU3}Zdw*d9oCqEUixZdNQ;pRepN9G8yeo)q8q5S*+%F=ju2eoGeufenbBzTdJYm zRHNPbUb>ml%d}byBkfg7;i_M4iKD0XeDCgbrB24hu$p_)VqOiZxj3#-&dAE2&=8Yh zcfeIz-t16~Jj|I5HV&Hs_`sOVdV3hz_Emwc^8%LvTuy@_FvH!T0SgD`_?V!piou_r zK7Dt>m8uqk{l+T%2WBb)tg0_HfE-d@bwb`Utg|?VSNHO{F1@cEgWm67Y8U;9+W$}p z6+4OAFPQW@)PA-w@}~?V3D`Si6#5q(h|}!fv=DHV{6D+%UAzg^h*@BWoympcf$_{& z3U7+5? zU~rcZGX;aM5|}E&s>H4iq(E<@YO98>b!rmWY69G;Okk@F@N|94yYt&rpCpcT#Op5K z*-qs5G&6Nx2a`6DyfrhK7tR*>d=O1W3o-^am`-$Gmmsd3ts{!JKu_0pp3~jKQ41Vp zLVwa`ulFFH&|msSoX}4dEr;Hcbvbl{37utHshC-=h0+?XeNEbO?JZmf8D^|C%e4)= zZNzIEG1@ejp{0z=?uY^bKJ3T@fj3}gfj3}gfj4F5JH*UuS*TAa==4}{t5EPxuLZXn z1)uIYT6GQ0Df84N1Apm&H&Xs`OH}(CDRFg&JxxmR?u?YUZnj7;`duZ2^}uYIn|)yr z)y8Ym*#ZZr3*6EzK!6 z74m{@EaWez!^=W5Map-zXntIS=H=Ppo5=6V(KBaDe5fmDr3g2W#gIU^j_;YRLGicyk=T-emDyM;3oQ;P_V_!tn!6$M60I#PQ}v;(9t>r*3ZVsGDy>Bk?`$ ze10<+i4RTad%qDU^kHdweZ?BH{NGxHj$D-M?zzHJ?;k{_6|vOWB<0$1T7e!FzkH)qAL%EtMKMSBltNXFpatY&#J6;LBP=m3`b zsv}n&xc%f%^%|+bt_v3SXlBd|+DV504qk;%besuQ<9yCmG>p{=gL{flUKeh7)am|7 zA@6dPoxcM&@BlZ?;QSrqOehxC7%YYq1FAJ3(8JF*e&lI5D=XcltSda3asgTK^5=yv zDv(ReoN<5$)?xw*ZCdbd1osFi%ummX-Krkr&dtUxjo0L*Ipn17bpKiV^}f}m0r8N$ z==JB4;T9%?`7VD!joW2i)`h#7@9i_2%ZUctR*UE0c&fb*uO6+p_n}&UHEjo@%XTn4 z9<6RZ*5NxvSxi=1zC+x~^z!~d{x4wEG{&!0FJC#%a;A#PoW%0rN6_R(pTD)_2(^-x zk%pJ7%^@{iczM<8z6knV#BHaRL+y|gQ%$QAyHYpQa)>Pq|2a(;qG#P=S z6+RRLQAMUIIv}dZR7C()nO*IwL@YehYvs>}u72~4>>cYyc5Bwo*#6WTCI-odp0mRhlYMIC$6Qw@o z?esg0N~BA|WIN0zxgmf;Q4DIi00O{bpnqOn`3r`rLXMF@-Jk7n_O2@?S%aw4VBqq0 z<1mpHV>1Tkrx!TPz%aBJn4h_T4gf4!H_r^MsQ2+M#AOqSd(yXXhq!X zxDogI)k3xYbxp0;;H;c+AIA8q4hPSSae9Pwt(n3wIvZQ;tMCB!I}B{4rU?V-XXOV* zZC|%t`Z*(o4wk-I7|YWauus^T}3 z6uPWTAxle4a;ZoKabRzIz?H>N`~Coyo%07$%6h|M|Gaa0UU{I^{Cy^>{FUG|3>CP$ za5D6qfkfE?ms^GWk)QB&GJ@*2n}4mc2j!nSZNf;d(1=ZkD>4JZm306a$18i1-5HKm ztIjH@KW4SDKH(PcUin8p{N;3YoVxj2C1<3UD}qct_1*3sB&Q;+hO)pgU3Dsxp` z?ia&9ci*H~tuIzCMUsp$-;o8na_dD`^HEfc7rZMHnTlUFA|>K!GV+uOzX#tTpTh4! z^HSxwtC*b2vC_;m%;=H(QDsPVOh5)G}c4MRW`G34rru;(!drj`H5KNiM@A| z@O2yb`c=2AgxC)`z4*KSn7@Z8^r=8oPE5UKwjveH1v5nLQby#{%wue^@_Ng+iwL}& ze!~2PhrhnAH`G@RgM#Q)qcG?>Pc(s^2cBpm%GS^>H!@MDt%>qCRpBXB+vT>a8+B3G z;$21nZP>z8l^#lW=Y}xGHr?MlgqTi35w9PPE@qY_Y57*QPdxj#{I`YtS)Mj2Pe)oi zn>F714M9@0W$G^+2g8ISAz+!En|E%ucf3RKqTNftv{Kp?qT3-r52#6 z#b!nOVQ$iz#os}(`(F)X#?=3P8_0V2 zCpUqAY7_VkPP6OkfAJ>pmuv$6gH7uHpBurCG}hJ!ACd0p%IG|pTSBhVwV;WN8>Az9n5XuKres@k`0Y06g@Z$0VF#* zz~;E=taAzj-32`Wc*93M5vzZwwd7BvxjG5_A&x~vYP+1i- zGh^^|GcyVpu$hq|<#Wc&m`M|7W*D9z>(0u~MsxN&bYZhc(>8I}iZ=Nxj3>!@EyF*vbBc zt4G8qn(~3N*?Lu9?AxPL<6bo}Mwod7=SCCdaI!q`Kb8>3qvT9`0qZ-qvE0PLFG)R}6 zp=YD&krm4T$m85aiP5_=D2;w)`&aEccrI@1tILHbTsTKffA3<- z4;N3-IwJee@**;=5*X0fBdbR>TrLpZe^hm9BoHeFEuC8Jm;%{Mof1K<uY z$ym(tYD=hlzB(xsUaYo-tEKAXZUwt`BNAbYz`Y~Q&z356?%iTso0&?1p{mgo_i8TD zn&I&}CXUL$nAn_&#u0vXzR|Q@z}$_nN1Bs6A!gTs8t^py+H_czv5P+`AxeAdRZ2Dyv5ZEIzDy zRKVE7n<;ukJ2RRFle%-f-h-qHRyDFH%yVpaJyuCPRpcg!BNtBfHvChP1@v31kIF`1 za!l!(z#2JLpD9_Nwo zsyCoUk*~?PNI$0bp-C(zJ@96v@PdGYu#86VOYzWheKD;6^JI}}fmMvS#73^X(<$Q0 zL|jY8WfDy0rgPnG-pHsS%oQ0mg!v((QZOfEB)d5yF6J7V8jm0jbwT`Fu~G%c>Wxzv zz35QZT(u-Y6d!APco~v1vQ!sGu$~J75g5Z87t$&&5=<8sE*IuBp%|1ZG^z?GvW6af ztt15&D1%Pv4Ux=Nl$&thSr{=KM1EYujOtLCK%ZbsX3iL^QYFe?RJWSW;8D@r7|V43JpbxU?;bdzwWi(ef;u4Icvf3K7rDC<9YU{Wh(kY9VQGer+u_nBB9*-1Q zJ4uo`#L}v*c$wHFK%loQ-=@JPs>b&7AR3x-z$}m_vnjp{Y|)~G)nXUMIu2rC!4%6e znCSe*-=Mz6mX2~mmb~|-n%h$zcuTyq^nv%=q<~xX_Vyy1XRk^KiOEfo1)9%7Bt+}} zpl1vO8FwNp1`_Qu-J*1atAQY?PJ9KaV-J^wPX^AMlY(GjN+Tp@!3D-a^-52)GC-ud zoyd;}6S>`*%9!~(lk-GVT4d)SST>VH_IOSv5dR;jEuJ9%*j!=_t8Xxg761@@U6mh} z84GX$v=fn+2-;Z>(d!zf=-!=*tYyN?lI2u?NTR#`_WJM*{BEeR>%(g* zva9~|3%W)AT6c9--}u4~beJHpLt@j<7OndfRh)-LaebbZVH(N|F$VXEWKuMPH9x^2 zMxG90rw*H5!q1@N)>JZv88e!1vkwd60_BfOwFq;(dtMM5mh;nAjSIgAtB@F_nPs)B zYLoy(*V^o#7OpfQIib+j)Lg#92oa=~=wp7ik5O%i7}AL(2@K!c4c}CuSuV;~yS`IG zMCGKa2hLDl$!TW2QXBoC%1Q4Edl!QZ8l9vv2h{;)wbKD>SskHqC^GKRtC$AgD+Gox z|IG_*-N%;hRXu8y2n~i{Gzqomi%K#^_$H0e(7H1jBT^W()mQO@8-q@IYKk>2l-LWJ zg;v$sR0gZB*(|0x2r#qUULw2>m+X*2D5PiFrAmBs$AmbVs)&TmxC9 z!|$_%;Jt@&x;w|VOB6&86?Ze7uAOR?#jQZlby-m3cz@WM>dJa z%RvmMOL$1|OA%=SAx-;01>{9mHuk?V;ydw>yuEyvy__|(^dK1Fo3gZsYE9WEX(Sla zESf`2Zup+>T(LZ_cMN$Ok*#gZu`hEPNGBU{DAVilob(5)>L?h+NK?0f^2>GTw7 z^Q6waN*JGAqZaQos^ea}Mz!dT_iP$9r>pL%Ku^Y8L6wy^;8|YumICzmTwXmtdJoFa{Fs#zW}p zPT0W;p!qsc2LmC++Smhf*c7%IInt9;6)5e-ig&D2!7vTlDv-V2hYMg4aKJ;Wt$dG3 z7q^Wn_22(lsq*!vCzwdn69}YX%3HNovQ@o;gAy=g@nV0n(&TA4t^gB}C)K<( zId!o;U(wZOd%l^n8lwEYA~oxtP<3Bth{Hl;JPPv<&G zTM#;KSUNLCP{BNak4gUup8J;H!Z6ATvS=}CsH7kU74`y8rmQ1+bl>-^&-kN(G3QI6jMJ^`^LX2WRc64rx>Lcx-2Xr&Je7)k}BSU#O8^t#ej*)VjQ@1#dNT9Nyx14>3{tn=0A{K-}c1Qx{_ zC(dFYZ#8#?hWsHJR9YW898bHq2*Hci&0>`8r08xlA2Rovb(=C|n;DQ{-I;+r&cKpT zYGPKM$wO3CODIFJI@5`&1~~2>?@WU4hSppB%m@6Ov>u;Uwu}E55jbgTzP1LPTi7ZV zVt-gOsgoGa@Mq|Whlgie#sG&uV-g<`o^iQdb=rJ3kr*cjjKfnxkC)_wB04J~(&#)q zD~-ngh?T|QpFwEv)G7x33}UgI80<3$bw9cZCs>tjn3f$Mrerh4!$fp6;bAnFVO_cr zgIbW)cm&t;`ICXsjW|PeW30LvK&eF4VBNi9kG$bttT0=k%WiWE@HRUQygv9t3Qck%{8m1HXn}mWrOCf;cDe8^!x$CFT+D z2ul+%r`5L>P2`u&NAutn?+0YduO^m!FROci*jDT}vxg)@txmoLkia?iZl|vXA*rm zNc2pyCYS`&eWfB4IJ-LbgZg(00c1jf`jv+coy~C;sLU6GfhpVmCBwSf%JSv=-LQpqivr+`AUcc6ChkMO;yA&VOdc(w8c{h`z zHCw~C@@qHYU~?%(nV)H10t$!&KSt4bBGWP;)9Nvr41RO_wT^Uxb`idyVdG~N?J$PC zvbUu~HPv5H^>Dh(F;c`QL zL(!4L6{aH;&cWi38T0HI49gY$DGL$60M4n^vi=Onho$t&uO;jH0#O+?Wt&w z`EepPO;aL)$wAcv)KgUJ!J<>GHoC`9uBrupwnvuV%cbGgFqUt%_ zHza2&#VE>&PuZKxo{LqHB6U1fiQ?*;j@{(TGJGpShtf(-9SS`rfurCh+O4?P_2U5=VLmR| zD8(8-(=F4ZH?0=7?ZD#I!udNw_-m-sy#&#W%#Zt8m2!9PcmbBFQ`j3H2EK4<*pW~_ zFUp#a!LYe{|0*WHf`Vc4#!${gt?eU*;l?>&36g;(!u%g}L^Ek~HSjCuN>WWZ)ry`; zcX{*-F-ykT53?0nD))d+RGZu)@?*yxlf3S47CO?*<)MOmrny0xrA<*CJ*xT=CB6wd zFof7f{V(*Cky-uB3_ZFhXF@ZBsTTSM>I^jlemoH;v3J5B+7)sQ1e05ig5qug1gl#DLkGkxND$jPkWwK|CkqL``M;=v@*mw1 zXxq}mwZ)ZxS}v&g^tHX#AE*Ovf|?w!X|t$9KpLg(!%eZGjN zck+~>NnHow|Q=X{hLHkec zmc;#IIDWT}O|9r^!XHRbQIJg9N0TlZc!FK^h)Qz`18iZnY+GO$VL5n{19@0b)$!Rikc%}KGMUH z2gC!)`v_Q+0AxW!Ma`*3G}{R@zTE)L92903x8X&OwW7SEIT5MJfVEsjw?9GUFb`) zHmFFbC_RlyUQ4o-`qXBbqWu@Ti^ANPhviE77IU#m+#ms=9otO-|GFrXQd02ep!z9C z9zt(9xkY!jC&Qvfx23z`VzHrb{1An9YgR@M2!oEyhKe=A&_uQ0p}OSZr{>d>H^n<> z@tovLDuvaT`6*Z1og2`&f~5dWdhpB#Jp7#G=wog0b=Aeg*;9DXU5kh9tHi@PcsP~b z(%0?8r@KRC#W#(Kj4*!r4~{*$Q1`o)l;ROp!)BI>E2Q43m6l+2az^q#4f62}nRb_x zUulq8V`H9HWgVQ_ENC*oob*Zu!(eZ!+j4Olk}(ZfVh5TGo&HU=q3N?0e=WAS0g~}B zuT_@D7?DiZB`B*0DUwOM>GH^iNY0to<>Z4At%l@7@$R^gOwQpHlGz>J?6T@|v;=mS zt5NE;A{__C@RnhO*rT$BfwMg?<&kr!@$M&I0V#-g^V+-pM-f0R9{lOnhn@;XO`wN8 zH;KP8t#BbX8S|tHOpnnx`A<}>^R+Yj=OSQ+nO*hyx&R`Vc5`+{Om-xe4Kr{p;-v{- zzwh4>Qx88nrgRML;bUX!ixDw7+C@U}%PnBh0QW?|{eU|4IiT@9#eCeFt8Yl?{|(Vi zpJu)b3xhPypAmhC1miztZtQZa!8*@6Pw8!(hsOq8OjFwP5{@9)`hYhG0XL12PE&R%B3vhAbJh&JFwY}ypg|_=z+5mzzgu{ z@f`-O9S9dQ2-ccza5{i`J>OJ}rVbW<9+waWX`PEuLX!*X-yv*t^6v9n0Q(Ob4 zCjMfyzRy@SHQz)G$dTrZHEqD&&Z zF<$tL^gn2Sc5eH#wY~66cm9?)#ldJ8%M&a`4aDBXiLx_!91B$WQf!4wc0p7_G(Q@% zlGOrngnO|U-L)jwK6^Z`wJnQf)o}V)OF-Y6tzBg?dRnLS&e~)6)$mC)J7O)|Jm!R~ zs;BUXYTq$NoKwE9otS2dhde0O!C8&30yAlhkA!z9f)OlhJrrTV4UB|g-tWTUAiDR+ z@)N={%j?I+^%Ya}affjgR$&z!r2Hy)R2GaKCgSuqe8V6cbkck~G2bGdHrrWLIc$~| zZzJ?GON@eTOpUjRvfvy3QfMQBJb-J!DUt<4Ly|Y9Mw7hRAxfHk zNnb<|x1}vz{*rQ3Ak5pWKcdX{vWRL()805EeK+d1OPuewK6kz;!93lTM&cx}=VOAr zsPNN%E-dsBEF`+1O*s4@$RVCQl4eoA*>HBa`JzNo|Exi7??8Sc;*|-J*h!gfKO!mp zQInH&=AC%aHYDmm&~)pwNL#)vVe`br>8bLIRhK>C%M$+NWP7sMKH;=I+y-gw2p+}=+=d8zc7%I0z*A8J zh&RKP+$;=@{+Nf`a3SM^p&4wjx`(~9dTPsx&4oiOA@|E3(|#LCiAKTp#Oab5)p~jH zvh+9wMo}MWRMng3vV!d|VNtj?B_dd~F-i?JxLu?tq-@NiLHK?3i*C>gMI8p-fIrk{8z2nMML$sWut(^e1x{4^pTOZtk| zwNjTz@UBiBy#$D^qG}o^yGl`;Oa^h3QKzNUO?UMkX){xW>gFVm9X(rbPc&q8(9*MH zNx=N4XWyeddV3I7!FFboT9ZpC7R%4Z&I#{h1F9-)nDP};eq7T%JT+c@vjmVb2ch&= zZE44y7qDcfrsDHikX&g3cO3)O}U7v!-JrXhsMm4Gr=twZDd0wqqY zHhn&Pih-Jm$btupOy|j*=j~EisKgN;-gT6RS12u_klm*4l{fgncP3Y>TS(|&9Eu+B z_+yAjRWix@@%|RIpU_|4&@o7wuK*R0hHdS^yAoCI5SS&vY42ZD=+uK{=Q@)`RjX|c zO+g7$NP`Xx5ofTAv}l+btVP*I2y;Rcx*S>5T>f5A>@@o9$jAiTgT6n|@ABy_Q+&Fs z=~lz1fM)p=Q0!D>T|gW2=`Kc#ZOdN{Tbr^fMLO3;^1q>@!LMU_>?NwyWXY=Bh)>CWMaL^>UwW-?X@7XhcQ<xZ_UrZ^?o9>l#`I zhWbD;wPvW|W4CNZ|3A`@qG7+-Cj$5mmmR#v+4%f*d2NzMs~{k(V;gpGbC5M}1A*Hp z^MnQr#4IYUD*k+P$_HOx8MsZ%xvVgd* zmZPynL`C;iyvHr8`zCEdfi&(Ldrb-T+&9LW?S4dxT9Z&Kj~Scify-PolZ`aJ%Uxr6 z*wDE$jZc@eE0LyII6*Gd@Zyd^(K8Q6;T{faK*7KRaV?oG6L(WYS3za9qd}Nq$S+H_ zGgx7e$RHP5W^1K6-(dL>gkXTfFwcE_dMKsH-0t)P{Ms5CRmos})I2E+!fV&VpyIOn zwX6;kHcN}^91J67_0Kri)Jqd8&FVKf*ceKkNnV+XVF`q4u`Z=8m&LpMQmAG{EGV=f|?|Cd1*a)x$N{8bc<-YJTY6!bo$)w5C2 z;kk+~9y%8l^zbtU`Y(+uHf>I78T$}QXFX#Jx}LEGUC-EpZpPRvB4Ne28>UuiW9li6 zo?_=IUT$XC8CgphQLg5SE9#dS=uOyO4(Cy97BCe2=qf@FMVH3H;>9zKfi2=5-aZQd z(r3N15?n#qa=OR4cg0s6p#duTcrwGhPZp=KYr6gjbxiTDPy_4k3C+J&JUf}&lj;P6 z6bf*9GTzuz9r$k6ZQ6(G2gz?lJVswyw}cldYZ{cY%0X%DId`@P`kLD_IPe4~*o{c+ zJB~qOtifDE4DTLf3$5SqCO&}GlGu?Ab%&tqNlei7Bqr!)Bz8pN%>)9a8Zy%xMrPO* zQ2LV9ubs(fIIB?WZ95l3MsTyxFY=temZ~B zanwnQ(6~HxH;ansF1C#MBH0ZkoVqX45gdGx9Ni=epqH+oh?1Gpuo=1l^uvcHTnNx{ zN1E(9f;)1bhPshE5}ySk0F-&vUc=N_^~A>NjWsSwf5*n^t?G%n8f~omG}P}wM!*{P z#wmF`a%ZsWPRXOnoqo`g8ws8FHBL#?S&UtD728eC*U`Q_N3^1GMcy`Lv0_h|UQ751 zP7X7&Oy+dlkp?u8({V@!a|{CLxFoR>%x=|L7seuIxAKP8Ox$2Nka zV-o>#ElyO6&A82ojFvdkLbh2?itw`Quo+1)h-Z+pFqNhnY6S;Y&&sajEh4Jd@^g!c zOk2JEcyYpL&L8+Lj5>rtucw=m?EIG{=&|*Z@E003s^UUON0EVvtIoVWv?e6Re zK$*Sh@eDU=V`uUs(c@{OWF$7U;3lIUKiR;cs30RC_h+ho?~YRtP>aKhhPXz?Xsomw zy*+kA9k!6Q8%Qj?LTOC_L$-H<$CLiu(r5t3npA-8)RmMzm`;QrvC_z^2CrQl1^>+~hJ5icjUPAb z+`%c_@U(I3(1ABJQsLLHI~^wBZZ2w~osrd9Ua4Fms;8*Kl+68kz2k+{^;*-;0%_FgYeG`^tBgm7PhQmEqA% zSUJ24lf%m46-pnCl_g@jtgOuoC&bDFv2w1+ZM&~~GgkJgf^)y7?E8@^XY90>=?>)k zdZjJsdaW(!dbKU6trRxU+ZQol)7unk77BXd0n^-S@m7=CYOYJ@e**L8ei#Cb0aDUBkuHHO^o zkyB8Fe$t%cn=SVoo>qi!ZS+t;HSrB5;`>8<13#3_w?`Sx&X7xvvUlSv@?2&dh7=zM*7)HJ!{s;5lAr{ z6P2y#pZdSn5aY5DlA5LX3?bbBfh_X`5{z_2ZJM1JJG1Fs-kqyCqY1M?)TGC!gEQ8j zieN=CJ+}wU7B*$%S&mlLXvpj&rZw1Ga{inRosV^c?GMpJx z9a>Dg{iTJo5W8D`2bnGrvNZK z3sn#MM`{7aVzmns=R?yG7Q#8s{PazH->eriM2-Iw^`6aUkg#$zi9=}^VOnoJ0cq1& zHR4e~6~80|~!zwnaS1A~7(tY?6pP-zbR00k&*3wiMEB)rg#S zgV^qn!?&D zJuU0@YWB3^uqqHOS^YO?uSgs~5eExE|9%>Z7!uX~YYSzTlFOXA4!GDv7VbkkT?!9k=IBv(TqeMB1)%g>$m_Cp27}qj5Y9v%KC8796!}PKl^aQqxbR|3n3TXt9Au-ZNqZV4~aGfC9IHqj6 zguZPmnnn+hXu7FmI*p=e`Z*U(jm@HTjLcmPQ=*C3LW7X7P_@La$T3}5L`i@-|B@sp zdB7j4nqJT@x5CE+hlvJ6$F%r)oQn>!*W+pyIUx3$GIp?1FR+G0@M3ieH8MtnFd0MT z9!4;!f~&40W1w)apvlHFnp)n?mU-)ZN6M%|P9HTXb9#_6Srn^{L}gI-m$XrXt+dfy zD{XWKI$CKnh4Dt(EXPHPA)zB}9%r`Ind0w8*ih$sVPlzn5(cbB^uDAGI$W0$F;?%a zSP_&NkzMuTjvd_8+%Zb=XidWmO4eA|`(6#>fFA&01Bcr3<=t z0=*PA=~~yS5{T-$R+T{Ot*Q&O_2q<&s;f2JW7t&SYF0`a`b>{CQp)f=Eu{cOmJCZC z(_p@MfS)=R)ag+!NanNIVsk0g8c@p}18SGWoLc+o?DpQwr$ZK78Oz|2DJvi=ILeEswfnnU;J%KXd0K7xB~Io&3KP^+gqZEfK$l^(lKh#3uSc zOZ_^SI<;f~+q7nT;Rp^kFbn|1OJ2Xcg{h}6#E#dQ-)upuIe9g&lCXhGXuGH(ta!|c zS>^FlO$jHn%03V|X>Plwcauj|H4cLEMo~yI{Bx(K<|M_}SR>7q%2yAy@x^EQ zAu2jiD*CfXMJ@HXGYS3aIPLJ5o*-*QT3X+Bm{Ly=%%W@7^}!T`?5$j2$BXtTq02$W zihI)UGvYF;VhNH+ls2C+l}a^2g4t{nh`ZqJ0Ghyo8xxnYL=>5kz&?|kxH=93i^P?! zwBkxO>w{TVVFyH6g##waD!eWoS@i-4M#4%$RnqFkA|U9(XT1E=NNDDdg@l%~AF!k? zEkk6bWKwH7vIUVT*Q9x=HWMI{qO(){s;OlDL$msb8oT&8ZR$iQ0h;DWkqdc= zv3<$l%k2ZJ(ltD$m%&r-<1iV>vS>MWSnxAH&EXKZ>qix+YJsH?R^gMUFah?DkJ{r2pJ(# z-z@p1FC5QYkdP)Yi=+d6BxkJS7;Q+|pBVc@Tt^Z%elQk_lM|mjMBI>x+os>B#4XCq z%Fi5?EZ@*4k3MhD%|0Q*lt@6BN>(?5v>`*uYDmysYz+x|lHwE;@>9ki%oWONeT%7V zXcz6<%jM^c{-d03+KY0!q4p@J8^JA0ND`*Qy(cWVgP?BAtRSeT8a2TY*hg)e)abI) zy%pSM|FIxzT5oWyZty%Qpcok@?$9bCBA<$EAHxF0VhurG5I_1o(Hski&BlWG?9m$^VW1>yTZr z7o38Encz3UI@o}=8h!QWM`e+BX6<1Y-4C9p@S^p1C z#p~%fKA;6hq+wXeqRm(6xSkE_-*~>_;dFNufHtYpSv!G{4Zb>5x6WChbMPP=0IEW3 ztG-_30q^>UI4Y3!y0_4ev!~s!t?{MjI^X|XIbzK#?aqcR!)W6FMcSTT#2J2xKX-GUbF$)bMTAH| zUpN%&)*BD`p;&3nSxN_WhwiTR6}f|&A005LDd$*D5*vR}&(*z5cW;Y#%A=she)-2X zH5^=Kskm~+E#i{@OOqiyk0B|8hsYcw?R=(3MdE2g>O)K-OP14xsM9~w`H0G)_9H49 zXJ?f3TisNK`x!|yO8ULwDD{yzrgUbM`P3*CgP9b2Udd<<;~+3oPzR!=dz3eKgwRk? zfhxri6~mG3m$VYvK-g8CtWpEPz@3~@1A)v=W(u@of_XcY>v8#2p)*@C`t~m$iT-&d zCM57o(dp*dsPl{}4#k9gHYIO@@7H%w++n`2Hxx6j+XL_Mt!2l~3q^tvJ4OVCoopR; z;xjpaBj%{$$Tu~1Ui83Y=fTdNFX*D!Gie`4_FQ9`pSF_z>q!E_o_Ef&=f8D@S7bp6 z>d1moc*SQk?1|egs=aSQ;q{gKh@ImQUJrKmT>ILx=Qo)4{MQGb0B?Dae%x&vk^h>5 z&#}|)?Z@5LWN_DIb9MvK(5g+4Ldy_WBeSplxZC68Se`ueWw++rdpI*Ilnq9AhH38E z)(R?@F;mIXE0hn*VTI!qWu$~j{do|5+3mr~p?GocD~H}>9J=ix4%PZN=CzQE+PE1x zXUJBwN{6Z}wBgB64{>OM??4_aLV)I>;YN;xXcvPovKrj>9oi=nUL#AUY)!k6CowtxD!WccFrYyI7amnzAG2vyqn zeX3-5Q5dSL@_h?P!;BYmLK~xIbHhzB3SykeSoiS%MeWwy$$_fXO?+N9uqS&sW zL_AlR*=vrF@L~k3_^?z}(T?Z$p>W<~{qqr_Vbp(pd@s1jEY&+q@%@F7mp_D&85()% zLl~LC$lph%dWdU+9QlWbFfv0UzxxnIW-xN#AvrRGk(YhbVC2PlTExWO*$;taD|P3? zHiVgK9g1*J{NbMhu^=!(u;0{TK+!sjBfTd^%TnJe(DBr=WeYjvL>2@jS)5g zEMq|vw>qR6lv(2+#W^GSkN`R;%#0D+WJTU7W+UH>GoxtF%jnfjd?$z{tXnVfYa`ko z)^wRbuRkRd_YdCpMhpH@iGA&7&ka;@$bwtgYznMrvmYK&{Av$YUHF2HSz;m9Z6<8z z%Oag`02$U|tgjn~Qr80fh7+0wKJM3!N#Q&N|8^!H=}g0N^5KZY2XY#0%j(ob==7$; zhQ;HYh|m7j?|!+j$-ZwBp}n)}h=P}HSrYZ@&VrD3j9K`*y#2n@dS-wfKFO(LZMZn$ z3rQz15gqO^KG0%O)7Eegw10YX6z<_u!1!zQT zHwkuWS`}dK_IzrZZCc{ocIR30D#E***NM3Q(I}mZ0lQcBB zyU`KdV-D@GOOb)=1K253H`xr$rda;~Z}{@F>ZFAhskvjnm)|GJ2S+l7T&YtlBO7D*(NttrKj0(wp;{m>8mf!En#xiVuxGw z9U%3kkA&ECa?O!QR#G#$D2(RlPfyvW3j1)bQbDN?*A*Y^E&ojdk+kZLc2Li^@PK@t90NfW8WRl$_XHX5IgCB1i%|UB#tC*2<2~I_@D!F%#vI3Hm@w ziqAhJDekw`!b6fGsDXQHQ9PiM;^!aCHieSX@1sp|r%8&@iP#jZutv7@c*v|s2WsvqS`HWYriPG4aJqz_!Rj8|o@=Fh@cBGA zYC}f>v83+FS%Y6%70ZR9?T5DRmnS$nxXrabAqYLIa4l{H=WAxw0p~+Zq`dH4gsKfHs8V|uX%Pw!d73LwJh?{GLdy4t+ zdW*sV-*$GNojzsHli+&a$X6&gAqRr!gVt4nGEu6V`48<1HYV=c`Wu6@a4T^ZCe2R} zw2xnzuh6_-<|~w|z}@)_r|}gMsT3oHNLAyL6afX;2mA8_(gu|}m^S|pA06%-XG*2J zhIV?A)!ur_6ON45rMkaMv9ZaVZcp-C>av-#XNZi@ z3I!1s)|I(<3_UgP(x7eNCo$^GqAdmfVd`R*Byuza@2CLOq0zPgq?USV0Q}AR9Ou=r z{G145sd}C)30wXROg9`%JdW^p#3P+?aI+5| z5pjCXDR+Zm7$))v?`+jugz$(&cDz~g(={T!;8Sfj_r@tk-AHlH{t+`k7KlMz@d@Q{ zwH(k+Y@AN$>@_R8s2+JI?f&7qC$31R?fy}^_X7x$1iYz7qO|X@55U=XYFL@nZ#^T_J(@;BW37_lGZ~_yZ-DUu{(S0fcUD}3BZ5mB#UosFb)AA+- z?ULapFNT5xtD?T)m50{odPUCbp!|~NFBxvJTh;W-M6#11g!SCE6V(-yp7#@BZf7B( z6xD^ErkuIWg)%291JO~X+(Z!JUp*XvlwN(an&+2Pka$V)qI{hiPKFEgq&%Qr4R6W# zWJnf2fY-qUJuf&JAk`2gKx`zh(K~@?O!Fhc(A5zVq%8v%ISH5ILB^rF`c-1|HP@vt z&6Lv@o_53wF;2SXl6X%t9*ASo??}=;gO?B~Wu|R|qz>1OqEl^S0+`7_!{@$ZJilkH z7=s5%<++v?RMlWldc#WMkADZ7rD?A+xn^}V@?1Nw#Iq+S^HH?A`sW4$6WaV#=SlESulOvg>6hm&?!GU zB~hVG=VDWJox?;+8k&2HCAep9D)F)Jzfvo-LE&Ow`6dyoy-0@3ix|>W>L-j9&hjGsHJJf?(6ff+J8)zK=;6 zGut)C&`=~p=c$)y4u(J4IY*#FFVe)?V`aJ+@6}pX{+7x+_fWr#f)Ge7d{2(#u_9*H zq8fXP1lfcj3cR9Ewy%jpVX*R0n0+Wrx9`=wsX{xF0`8S8k!;`xtE7#r`FwMl#!vcW zHui>E3mia~QDURr%G_54rT?(~K=lmjUl2*u+Kqsu`j8RX`;B^j#!2j37^2xBi%EGz z{e&=+`o^1h%X=d^H+*`UU2ml%bpku_UfdB~jFEOt!j+j^wl$$SePUgW3@Wr{FNVQ< zpUq__{VENqjB&7rBLrlV2BkY3FngO2_j+hObPg>TAReWzzCjG)<0ah0S1Z7GNeU)GI6l9hPx=Or~+o zAxYN-K_iy-6-tpXrYo5o7#n{h3ghy4x|2Nc-TCrtcg~waP8#Hu##4S#WkIn|QTaU&7J z3`&eA&8y76hAnF;*()Ly3&qHU(8ob zv5n}zUDy^^=7p|dF0&M=md@W%epn1P*}@pPe+v4JpL54cL?&x}0%J>^{1>G)EslrM zopv(MybcedgB7UQze?v#M-LRtEXb>=?8|eOjfl-buTe?j`HErT=+$tx0fF!N+_=)D zM*MKrl0Ln#Y({(D(xic)$xaTDfuc3z1ZW^=(yW;P3dw9r0p^KHl!rBKr}!r=$XUxO z^7d9a34cMkc?;F3-oHBL(EG*2#%k$ZBvds58md?johK=>XUtcp=;j2YGB_tVmuLab zVR51|u)n@Ju>j+st0RQ7i5BS2WGO(xNa;fuAYT;8o!7=&<8WAlEcj@sb*VZ@mG`Qx z`WaQFei#W1%!Dyh+=-bBrN*7cfMvBhfd%pObJMyd^+FOcvepvKPm!&d)a1ua6le&7 zgLLl6DU(A0lU!(GO0{a`6|7dbIh{heeGUqrOzZ(IlZ8x-v`C)Z@^5nv9cdrM|Ub>{Y&F;%jEm zQp5!_HR%j25v3}TITtOR;cY3ZL|ild&yWI|jStU*SvZT-bSXFyTjwOMqE~XQ^cWV1 zRAFH$)mN%hOAsU#h-o6*Kw~Z6EDZ2sDj+BfVnF9AsSY`Cc-`_kyv8c?!%l+-L6TUy zZy%!tePAEM*?V1Ol3ZpnXMC7gPi+&uZYUT{0T7>xCj>cYy~)&1-3E$jGw@tup(O4%)04e}{ozF8ugHZ>EzIZ;AD(*n)e1YxYifm9&$^sJEk zFmEOsB_Fc3UXiuFN(Ph$&aktk$ovdn0up_SW<+(TN+vrx=#rnA^{!VPikl1AdvKfX zEFHZ@)M;(U82OY%TN!>QRaJr$Y=n2Kyz#U!K?T1ND=?!0ZP32SN7wb{VA9+3*$=$) z6<_$9JAUcQLG<9nG|8JtAO})GjD}V9Ho73WteohnJnIe%e6%yW$FxZ@COsTp243hn zRa*uozm;YqoNyKkrNC`pst~D9ANyOp!(t}aO?$;235V%tAZ%L;<((otE~A;jnk${M zhdMWh(^lt8PX}6s3PAF-6=a}kE66~SSD;IRn+_UCyhjBQ)L20|ePRGmgu5iHJRqvb zRE4`%tQ1wi1`S9q4(i_pdib)18sX2b)$;9Tv*oQ!AAY>wOYJ1gx%MWc1cC% zq7wxwztmal(y|Tt<#Yqjpkw2$y zo}O=?EL6pHlVP<$UDjE_up6%9!Q4Ci2}*KwA(dDK+s6ww+E78o$G#S>J%h{Dsm^HWxUBLC2u#HR!+-e_@4Xhn5#Q82{N?!ciVQh2mh;R6`BI zgxw;8KmsVeP=*y_KqvCrO2DFCD>PQH7+$m6p1rof8>%L}CNE~?!`kkH#3a$@0%1J_ zD&uj&d3PX59eFCT5$vG6K4O4o3E@Y1Pq7Y`$rR&=x@H(bpjmb?8k}OPz;Wl%L1&z0 zpM)=&Xt2*2xD3YxDx%e1|IW(~ttIuN>JPnw-{{2n#C#F?DX290!Kb-tdMY=jalU?I zeK{@~_qlB;b%x6Ab`%JFbYV4u{yPNjQ;c~9Wr)ssEOH(N61UqWds~Dpx3RyS%U`Xz zg^o41&@ta~5FJC4{?F>m?elFC)0IYmIUPB;Bf$XEzJsTw*afh&anCNqMelhCu+dY; zX=K(>HFzG3Ho6FW_xD^ck8r0tKpRm&@!c~39RamwfDSR- z0~%yZHbkSiiL_$_08#5Clwh+WO0XHlFD^x;bNqXdQAjIMc=@+MNOhtM8;hnoZ$#Id zbA@#pdnBYIq%VkIuHY?RJa3jbq|Mbnc?RT~tfE^YcVmq70k~q6`SA8;4VG zSPL?-CeSd%5^<)4+Q@Yv}#-`da>fGP}n`nqT#O5T#uz`XQ zThv@q=s+6gK^(m(Imm{h~FK(j7ondv<#UJcj23Ss1`;i85$ zTm+ku$jorxi_kK%Y6MxKPb4|4k!6KGqT{eeoE7yg5!OhwqW&#|L5U7a#2vpIVg9bc zem}yz4TJr0gtdJUG7!jo;JVP|uHDJ|xU^5ZL)Yfq@+F1CAncC7b(rbnwueD(UhB1# z|Hq_dQ6FhzvG-D1ZfO3!s6Q($r_Dc^tgX02*j?my-nuo;1t(ztEoh8U2g-sos~iFe z7M$Hq*?%(9;{s=-w=eH3l#qX7<@RlEr|iG*w%G^=umwbiYx;%suH^@MyjsFHb9>U3 zpOTi1tPBfM)Z;o?>4n>pz6#u60eJMaA4A$cHKe#|v1MPtk5+sOC>8Wc9Fi1A(e&If zfyL0^5lj#nHnlVLnly%C0$nkS32b1jt4cPL1{}=^RQL3H=a2zl4;RV$lESp1yG!>F zc6>fqZ%Y7*vc9wOjv66=f(BuY6D$d=c1ioY?}Z_;Art&w0TX2S6N(tkpY|xw%b70G z{6-y*N-B2T7ia43a)*s7;M`hGmPmr7lT&z7rthzHg@L{8RbPw`@-LNNgwK!P{|3 z?Qf$-RVKb|T2*iJf$*o|jtFlXV^z!=0#eH^OjRwruu{kxVCm#E#zaOEyK|Prj?9vn zzK+$gH_S0KO=QdKi44#zkpY^S(ao0Bf49Ms`WSZUcjI$&--%RlvNI`gKeJAG%_n8V zewF{`o=se!{5=J9nGHP7=Oj!6K5WHA|1xjg%hNe&kXKUvvMoTBxyXBXJdB!Bybv){ z5x#^x!$$z{8k%E5;w&&?rfg6RUtZ8D7+7k*BY^ikBr75Xym+Sy!K`?v3c=Jce`2+v z7y5*2=$0i^wfi6N^RMubSG`C)VHHkK_sOayfNrT{)T#6Mo@~P<_;hs~uBmbgeS|Ew z6gN2|*2{Zj99paV#m0TT(5AMQvok%}i7WXVo3M&nqWgeXCaHeTEC0wQpVm^An2LDS z>9ZF#sXTq6$7dua+bZ;-rm)gTs9WEI%+7r_9$H?0c5`xI60bfr*M74^pY+MXyUf`~ zp_Q|;n`um>bC+&w`<95h$ro$GK+no{)&7tU%D}!=`Ag-Wi?nEUnHnZJ9miu%KP}pg zVUa$2;^|+)Cc`lTm9K46GOg2VBu=P`zzS6nc|{D_%MxNZ3PYrcK2&|VUorg4k2?N9 zv_ce+xVk9UJwz|>tbOfNy+p$4tCYBq>+AD7ss?>SqKO%5yf}03ben6Wc%%C`fWS@3eKxGMXA_%*D zBq)JSgkYBqJQI5_EofDqmTQVWbH_x|P&L;yB>=2xUkb&2?j>Nf=2PPK3S_zv*61Sk ze6LxchFon0R~zscfORz{K7YP3ts-X@Fm8ndgmk*SCD8| z{Q-F$>TmagciGMBU#;RHODBF$C;q;;*M3)L+MH(a)l?Nhf=^WuBzRi|>e_p8b=xgB3&RdJ zGN~lN4dz9H1h?-;nFNzi!JkOk1S{GNl7*r#E z4KK6?mU(nFQkakEHD@U9efdk!WB*_)DE@%5)S*5(y8E2zr zAbL>QsuphQs9g@t7!rBVE{34ikU&sxWJok*NO0CV=VaJ1BqH|cT4Mz`3^Hu3fOTXz zRYf4fsVV{)wpBoe-i!N{428MlBtoW@`JN?0OOY}noSGabzm*9yjuC;1`ClSHpUx*b z<(kpgCS+_joi`QJrr<*}I4wv{U#*jU{Pdj7bMK)+9&?NIgBfROW@s1%r}NNnya* zH3lWY0)B#(*L)X}Xtro7idU6I`w(pC%2PoxDDkg~u0mPVhpuiCdCEhY1dGxpnwF|T z(-t!?eG?5xF9GQ;G<2&HQ0FiLq^LLpG{0T7gG_~%tQC7V*pwpZskd}LRW0{Z?Q-Ak zSZu{Y9KjnxV^pI_&cm)GGckJ|6EjyOy=Y=uhKaOkG%*c8H+s>;6o9*6V%o+XoDa#S z1S{`ISdWu{Ci~xUke093LO~pKdisN&0pa8jR;Fi37(uRD#W<3s2mEY!S)lgfcLuEP z(j)NREK8x}kHK@21jc^qL?aC_bF_Y2&d7)G?g;aeGoZ@rW<3Kv?Byv>@Bw+T@=sbh zbEY#I&pI{NcXh1iyuKU!dxd7PHP&-3>-kdZ4A%2rtY_m1H=rF4(-t(&)pHVFk$t$g zv7o)=ahT9T<|WaP`AXUzu1kJeFW52Zlg4((c`vuT|}>YM>fee%_stk2UZ&+aymv=rAGuDjQVDXU}<4)*;pnBE`Ow>h_yp z;&AU7Mp=&np3m14?u7L_v}Evtuhg{Y@ZMg%_TvWK&Xh?QC^@)S-zi}EN-YwT;lCYy z^sgff>Bgss=NQAkr5A^<*P8L)()&6dzhx(y)4+2kvlVk5_|D8?0s;J8Pn%TncUGCX zB=Z$Rh<(%2RaDr>%xcRh=B^&6(V?{t_UpTOiL^}NPV2FlB}*gzW}y_(KIrL*1*=|Y zjkH--qU2Ij5OJcX@}$a#kdYgHx8YeHR|t@#Vbu>Y(xbaok3K^?$wDG=7V=$1W9Sod znv@(aTLFp_CBs3o(M3DM14`9ADl+V>%oD%`yF&~Wa6i6;6GMgCIu<63;WorXcAqeD z<1sPux=qRAred-oUECb#;&89NWtuJqK^QZko6&_ecMNPe|80Z~Sn$5k#it}BI&?A1 zB9ST}QgMfW?=|883e1d{B~77+mezfOjhi6XK=P5;b4Z<|E$e&QDR#nciG8Cf-iWSS z(wFAKt%MpAxgR;ku$n3EjH@%bQv=iFwj&F(b&R1MZ25R*XdBMgWDa5DT zvx6#Z(&1~qjeWF~cm#Kj=~@0}aPea(u^vCy=+&1P8>Pfkif<>O$=Qf4t4S|?Cb>$I z7ul;HnVP4eskM_NrpkX^RE;Y(LV*XE@1hs4dfA`%onwc zxuT8inU)mXV|Mw5oT)ABa@`&je@)^Rc8bNrL^4Z*pT`LsA!iG~ zQ5O-Qz|Muc(_J#g=-z+D`4A^VQX;OYtoz<`-XE>jr>LI)pkJKSlYut}{G8%1 zd?COW48CA++D>;(hPzW8$^qseAdFOk-|D*VwI$Bdjl(_5ddt@1xl&Rt5RRB!&cI3K zIJ&?iD7FZd>s~8ni>klcfZdR|wb>Q$bS?gg!xUVA#T2lZoQp8`l(2euYW|&!u@Pls~g75>%?+rcp#u@FO zDg#X!&uAy9=6Zg-aLl=O1RF+er%Bi=#F)(FHf1o6?4Ls9LKl(HVF!^~BBoUzi$#9j zl+1~v;5cfN;b%__#h-r&#h@4?;6!lz&R$oz-L{c%vt*JEDZh1AxLp)T8H$5HT#RM) z4SorWTGC-we^(R+kZ? zx%VInSKu28SKu28SKzb4^~@+-nK^7TMdUm{ulugB)xE{>w6}vk=^kO*k0%u&Y?X4_ z6}A^m3EK+!y3@n|>m_dxwk~=5E|aGO#tBK@+ZxIHmR{b!zTa+Z+mL7#$LPvmJ50*y zCR>phyn0st5}p^42cj~fby7ZY`ci_{G&LPrM@`^*nw-ptu%v`YU_rCPQxU=&_jqVE zT?th8?Bk-kVim2;+vn)Fqq>2AYk+@iS9Jq_bbvp)qqbY5a8WJse)}JxeA7WJ;7cu+O!+&g(cxSpVn+sggUL+)|&_|p_&c(5=qP9 z+q9`3!fUoW%akQTBfBITTe=^ar;Lkj9so`2Q?HbjDjzMc$5W`x0WR|H`oB{QwDNOi zF7uj<;k>>yY{a*w%^Ya!^(*a`jov)Ew|%wznCnq>XW2Y*dRe(gw&bLh6Y7z5V}Ixd z4fvU*O;zhVF??xGVqj#|_-n|j_pL4s(k#h~UVo0`t}xoLz`etES(kAv_x2e*gvO{g zX{%*5b3E1FhgXl*+xt+hzbZNjgVAL>7#@#~GFJZ@@<&7s<^R%Oe3%ezy#B}eUSVeg zW}FlFSX=)S1#2u}O`Iff{B(&eO4L3KPPBtH+xwhUSudGWSosfd`C+)+-2a(=o~UKn zvaKmSQ%P$BIMk1}vPWWiRjzrP(<5I=ND{0}5G~6U8)hXj@Z-DS0Eh~Zzxbj^Ui8%~ z;b<^*3xP()meyvqpO0i5r(n}TTZj?1G^ZI|)LBJT#oi^=7TS1SkHaKPL=ro|vzaS&30W~o zEMNKlm|V7aHVM%}W&AxO?RqwQNMmqgJq_%veSq5-8Iny%WlRvLks#cm1w~d3A&&90>|oL%qecVMU$13 zkNP8=a}oM87y9F;o~l2jf_D3(O(^OJpU49BGaZpfxAFbR&l`zS@33*kf+b=>@$kS8 z^KI9n;sO2#A!q@rGc$K4k7QEeRA12RAXMzk=!!HI*{tAqCiQGt>*^@v<*L)2m~vVk zc1}}(|1=YF!#8D9Vb;{arhjnKLU%Z@g)JzBAE^>cffiL8)!d&4jowkdnWnMyZ*Xc#>%7p3 z*c>&Hi@T%z^@vT*@wX!cq5ZRpwK;-t%QF2 zuCk0D;fLmN6Q0IntQ!8F77QM>V68;MhkLh&}tPn z{z-zOBBks&?-zq^O0!gzqM;RiUw1Z}5A$f&sMC=KVFmyrRgaEsjmpa*GgG6&P=%19 zS?7i-I|q5>)+h_vWx8&qdmSf>A)7LY8O^+m9%#qw;bjcNNIYDZ(k3z<(Mag{w}^xo zGT7Z~AqGf@Qf&Ox&!tgu^8sv7XCDh)&aRAx1Ztm6Z!L%0Dm;HCKakPaDy+DuWsEhF<#--$N{U3NI`o^M7^K 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 N27Lc|*vG6rKLMklX`TQ8 literal 0 HcmV?d00001 diff --git a/client/wasm/reputation_contract_schema.yaml b/client/wasm/reputation_contract_schema.yaml new file mode 100644 index 00000000..24517168 --- /dev/null +++ b/client/wasm/reputation_contract_schema.yaml @@ -0,0 +1,140 @@ +name: "reputation_contract" + +entry_points: + - name: "mint" + arguments: + - name: "recipient" + cl_type: "Address" + - name: "amount" + cl_type: "U256" + + - name: "burn" + arguments: + - name: "owner" + cl_type: "Address" + - name: "amount" + cl_type: "U256" + + - name: "transfer_from" + arguments: + - name: "owner" + cl_type: "Address" + - name: "recipient" + cl_type: "Address" + - name: "amount" + cl_type: "U256" + + - name: "change_ownership" + arguments: + - name: "owner" + cl_type: "Address" + + - name: "add_to_whitelist" + arguments: + - name: "address" + cl_type: "Address" + + - name: "remove_from_whitelist" + arguments: + - name: "address" + cl_type: "Address" + + - name: "stake" + arguments: + - name: "address" + cl_type: "Address" + - name: "amount" + cl_type: "U256" + + - name: "unstake" + arguments: + - name: "address" + cl_type: "Address" + - name: "amount" + cl_type: "U256" + +events: + - name: "Transfer" + fields: + - name: "from" + cl_type: "Address" + - name: "to" + cl_type: "Address" + - name: "value" + cl_type: "U256" + + - name: "Mint" + fields: + - name: "recipient" + cl_type: "Address" + - name: "value" + cl_type: "U256" + + - name: "Burn" + fields: + - name: "owner" + cl_type: "Address" + - name: "value" + cl_type: "U256" + + - name: "OwnerChanged" + fields: + - name: "new_owner" + cl_type: "Address" + + - name: "AddedToWhitelist" + fields: + - name: "address" + cl_type: "Address" + + - name: "RemovedFromWhitelist" + fields: + - name: "address" + cl_type: "Address" + + - name: "TokensStaked" + fields: + - name: "address" + cl_type: "Address" + - name: "amount" + cl_type: "U256" + + - name: "TokensUnstaked" + fields: + - name: "address" + cl_type: "Address" + - name: "amount" + cl_type: "U256" + +named_keys: + - name: "owner" + named_key: "owner" + cl_type: + - name: "Option" + inner: "Address" + + - name: "total_supply" + named_key: "total_supply" + cl_type: "U256" + + - name: "balance" + named_key: "balances" + cl_type: + - name: "Mapping" + key: "Address" + value: "U256" + + - name: "whitelist" + named_key: "whitelist" + cl_type: + - name: "Mapping" + key: "Address" + value: "Bool" + + - name: "stakes" + named_key: "token_stakes" + cl_type: + - name: "Mapping" + key: "Address" + value: "U256" + diff --git a/resources/reputation_contract_schema.yaml b/resources/reputation_contract_schema.yaml index 0cee1019..74d2e036 100644 --- a/resources/reputation_contract_schema.yaml +++ b/resources/reputation_contract_schema.yaml @@ -4,58 +4,54 @@ entry_points: - name: "mint" arguments: - name: "recipient" - cl_type: "casper_dao_utils::Address" + cl_type: "Address" - name: "amount" - cl_type: "casper_types::U256" + cl_type: "U256" - name: "burn" arguments: - name: "owner" - cl_type: "casper_dao_utils::Address" + cl_type: "Address" - name: "amount" - cl_type: "casper_types::U256" + cl_type: "U256" - name: "transfer_from" arguments: - name: "owner" - cl_type: "casper_dao_utils::Address" + cl_type: "Address" - name: "recipient" - cl_type: "casper_dao_utils::Address" + cl_type: "Address" - name: "amount" - cl_type: "casper_types::U256" + cl_type: "U256" - name: "change_ownership" arguments: - name: "owner" - cl_type: "casper_dao_utils::Address" + cl_type: "Address" - name: "add_to_whitelist" arguments: - name: "address" - cl_type: "casper_dao_utils::Address" + cl_type: "Address" - name: "remove_from_whitelist" arguments: - name: "address" - cl_type: "casper_dao_utils::Address" + cl_type: "Address" - name: "stake" arguments: - name: "address" - cl_type: "casper_dao_utils::Address" + cl_type: "Address" - name: "amount" - cl_type: "casper_types::U256" + cl_type: "U256" - name: "unstake" arguments: - name: "address" - cl_type: "casper_dao_utils::Address" + cl_type: "Address" - name: "amount" - cl_type: "casper_types::U256" - -events_config: - dictionary_named_key: "events" - length_named_key: "events_length" + cl_type: "U256" events: - name: "Transfer" @@ -112,21 +108,33 @@ events: named_keys: - name: "owner" - named_key: "owner" - cl_type: "Option

" + named_key: "owner_owner_access_control_contract" + cl_type: + - name: "Option" + inner: "Address" - name: "total_supply" - named_key: "total_supply" + named_key: "total_supply_token_token_contract" cl_type: "U256" - - name: "balances" - named_key: "balances" - cl_type: "Mapping" + - name: "balance" + named_key: "balances_token_token_contract" + cl_type: + - name: "Mapping" + key: "Address" + value: "U256" - name: "whitelist" - named_key: "whitelist" - cl_type: "Mapping" + named_key: "whitelist_whitelist_access_control_contract" + cl_type: + - name: "Mapping" + key: "Address" + value: "Bool" - name: "stakes" - named_key: "stakes" - cl_type: "Mapping" + named_key: "token_stakes" + cl_type: + - name: "Mapping" + key: "Address" + value: "U256" + diff --git a/resources/variable_repository_contract_schema.yaml b/resources/variable_repository_contract_schema.yaml index 0fad0bc1..7c667bfb 100644 --- a/resources/variable_repository_contract_schema.yaml +++ b/resources/variable_repository_contract_schema.yaml @@ -1,20 +1,6 @@ name: "variable_repository_contract" entry_points: - - name: "set_or_update" - arguments: - - name: "key" - cl_type: "String" - - name: "value" - cl_type: "Bytes" - - - name: "get" - arguments: - - name: "key" - cl_type: "String" - returns: - - cl_type: "Bytes" - - name: "change_ownership" arguments: - name: "owner" @@ -30,26 +16,20 @@ entry_points: - name: "address" cl_type: "Address" -events_config: - dictionary_named_key: "events" - length_named_key: "events_length" - -events: - - name: "ValueSet" - fields: + - name: "update_at" + arguments: - name: "key" cl_type: "String" - name: "value" cl_type: "Bytes" - -- name: "ValueRemoved" - fields: - - name: "key" - cl_type: "String" + - name: "activation_time" + cl_type: + - name: "Option" + inner: "U64" named_keys: - name: "owner" - named_key: "owner" + named_key: "accessowner" cl_type: "Option
" - name: "whitelist" @@ -67,3 +47,41 @@ named_keys: - name: "keys_length" named_key: "keys_length" cl_type: "Variable" + +named_keys: + - name: "owner" + named_key: "access_control_owner_owner" + cl_type: + - name: "Option" + inner: "Address" + + - name: "whitelist" + named_key: "access_control_whitelist_whitelist" + cl_type: + - name: "Mapping" + key: "Address" + value: "Bool" + + - name: "data" + named_key: "repository_storage" + cl_type: + - name: "Mapping" + key: "String" + value: + - name: "Tuple" + first: "Bytes" + second: + - name: "Option" + inner: + - name: "Tuple" + first: "Bytes" + second: "U64" + + - name: "keys" + named_key: "repository_keys_values_mapping" + cl_type: + - name: "Mapping" + key: "U32" + value: + - name: "Option" + inner: "String"