diff --git a/tests/waku_rln_relay/test_rln_group_manager_onchain.nim b/tests/waku_rln_relay/test_rln_group_manager_onchain.nim index e0d4243e7b..aa28c7cf7a 100644 --- a/tests/waku_rln_relay/test_rln_group_manager_onchain.nim +++ b/tests/waku_rln_relay/test_rln_group_manager_onchain.nim @@ -32,10 +32,10 @@ proc generateCredentials(rlnInstance: ptr RLN): IdentityCredential = proc getRateCommitment( idCredential: IdentityCredential, userMessageLimit: UserMessageLimit -): RateCommitment = +): RlnRelayResult[RawRateCommitment] = return RateCommitment( idCommitment: idCredential.idCommitment, userMessageLimit: userMessageLimit - ) + ).toLeaf() proc generateCredentials(rlnInstance: ptr RLN, n: int): seq[IdentityCredential] = var credentials: seq[IdentityCredential] @@ -60,24 +60,38 @@ proc uploadRLNContract*(ethClientAddress: string): Future[Address] {.async.} = let balance = await web3.provider.eth_getBalance(web3.defaultAccount, "latest") debug "Initial account balance: ", balance - # deploy registry contract with its constructor inputs - let receipt = await web3.deployContract(RegistryContractCode) - let contractAddress = receipt.contractAddress.get() + # deploy poseidon hasher bytecode + let poseidonT3Receipt = await web3.deployContract(PoseidonT3) + let poseidonT3Address = poseidonT3Receipt.contractAddress.get() + let poseidonAddressStripped = strip0xPrefix($poseidonT3Address) + + # deploy lazy imt bytecode + let lazyImtReceipt = await web3.deployContract(LazyIMT.replace("__$PoseidonT3$__", poseidonAddressStripped)) + let lazyImtAddress = lazyImtReceipt.contractAddress.get() + let lazyImtAddressStripped = strip0xPrefix($lazyImtAddress) - debug "Address of the deployed registry contract: ", contractAddress + # deploy waku rlnv2 contract + let wakuRlnContractReceipt = await web3.deployContract(WakuRlnV2Contract.replace("__$PoseidonT3$__", poseidonAddressStripped).replace("__$LazyIMT$__", lazyImtAddressStripped)) + let wakuRlnContractAddress = wakuRlnContractReceipt.contractAddress.get() + let wakuRlnAddressStripped = strip0xPrefix($wakuRlnContractAddress) - let registryContract = web3.contractSender(WakuRlnRegistry, contractAddress) - let initReceipt = await registryContract.initialize().send() - let newStorageReceipt = await registryContract.newStorage(20.u256).send() + debug "Address of the deployed rlnv2 contract: ", wakuRlnContractAddress + + # need to send concat: impl & init_bytes + let contractInput = encode(wakuRlnContractAddress).data & Erc1967ProxyContractInput + debug "contractInput", contractInput + let proxyReceipt = await web3.deployContract(Erc1967Proxy, contractInput = contractInput) + + debug "proxy receipt", proxyReceipt + let proxyAddress = proxyReceipt.contractAddress.get() - debug "Receipt of the newStorage transaction: ", newStorageReceipt let newBalance = await web3.provider.eth_getBalance(web3.defaultAccount, "latest") debug "Account balance after the contract deployment: ", newBalance await web3.close() debug "disconnected from ", ethClientAddress - return contractAddress + return proxyAddress proc createEthAccount(): Future[(keys.PrivateKey, Address)] {.async.} = let web3 = await newWeb3(EthClient) @@ -161,7 +175,7 @@ proc stopAnvil(runAnvil: Process) {.used.} = proc setup(): Future[OnchainGroupManager] {.async.} = let rlnInstanceRes = createRlnInstance(tree_path = genTempPath("rln_tree", "group_manager_onchain")) - require: + check: rlnInstanceRes.isOk() let rlnInstance = rlnInstanceRes.get() @@ -197,8 +211,7 @@ suite "Onchain group manager": check: manager.ethRpc.isSome() - manager.rlnContract.isSome() - manager.membershipFee.isSome() + manager.wakuRlnContract.isSome() manager.initialized manager.rlnContractDeployedBlockNumber > 0 @@ -261,6 +274,8 @@ suite "Onchain group manager": asyncTest "startGroupSync: should sync to the state of the group": let manager = await setup() let credentials = generateCredentials(manager.rlnInstance) + let rateCommitment = getRateCommitment(credentials, UserMessageLimit(1)).valueOr: + raiseAssert $error (await manager.init()).isOkOr: raiseAssert $error @@ -271,15 +286,10 @@ suite "Onchain group manager": proc generateCallback(fut: Future[void]): OnRegisterCallback = proc callback(registrations: seq[Membership]): Future[void] {.async.} = - require: + check: registrations.len == 1 registrations[0].index == 0 - require: - registrations[0].rateCommitment == - getRateCommitment(credentials, UserMessageLimit(1)) - - require: - registrations[0].index == 0 + registrations[0].rateCommitment == rateCommitment fut.complete() return callback @@ -323,9 +333,9 @@ suite "Onchain group manager": ): OnRegisterCallback = var futureIndex = 0 proc callback(registrations: seq[Membership]): Future[void] {.async.} = + let rateCommitment = getRateCommitment(credentials[futureIndex], UserMessageLimit(1)) if registrations.len == 1 and - registrations[0].rateCommitment == - getRateCommitment(credentials[futureIndex], UserMessageLimit(1)) and + registrations[0].rateCommitment == rateCommitment.get() and registrations[0].index == MembershipIndex(futureIndex): futs[futureIndex].complete() futureIndex += 1 @@ -400,18 +410,16 @@ suite "Onchain group manager": asyncTest "register: callback is called": let manager = await setup() - let idCommitment = generateCredentials(manager.rlnInstance).idCommitment + let idCredentials = generateCredentials(manager.rlnInstance) + let idCommitment = idCredentials.idCommitment let fut = newFuture[void]() proc callback(registrations: seq[Membership]): Future[void] {.async.} = - require: + let rateCommitment = getRateCommitment(idCredentials, UserMessageLimit(1)) + check: registrations.len == 1 - require: - registrations[0].rateCommitment == - RateCommitment( - idCommitment: idCommitment, userMessageLimit: UserMessageLimit(1) - ) + registrations[0].rateCommitment == rateCommitment.get() registrations[0].index == 0 fut.complete() @@ -429,7 +437,7 @@ suite "Onchain group manager": except Exception, CatchableError: assert false, "exception raised: " & getCurrentExceptionMsg() - check await fut.withTimeout(5.seconds) + await fut await manager.stop() @@ -457,7 +465,7 @@ suite "Onchain group manager": proc callback(registrations: seq[Membership]): Future[void] {.async.} = if registrations.len == 1 and registrations[0].rateCommitment == - getRateCommitment(credentials, UserMessageLimit(1)) and + getRateCommitment(credentials, UserMessageLimit(1)).get() and registrations[0].index == 0: manager.idCredentials = some(credentials) fut.complete() @@ -485,7 +493,7 @@ suite "Onchain group manager": data = messageBytes, epoch = epoch, messageId = MessageId(1) ) - require: + check: validProofRes.isOk() let validProof = validProofRes.get() @@ -517,12 +525,10 @@ suite "Onchain group manager": debug "epoch in bytes", epochHex = epoch.inHex() # generate proof - let validProofRes = manager.generateProof( + let validProof = manager.generateProof( data = messageBytes, epoch = epoch, messageId = MessageId(0) - ) - require: - validProofRes.isOk() - let validProof = validProofRes.get() + ).valueOr: + raiseAssert $error # validate the root (should be false) let validated = manager.validateRoot(validProof.merkleRoot) @@ -542,7 +548,7 @@ suite "Onchain group manager": proc callback(registrations: seq[Membership]): Future[void] {.async.} = if registrations.len == 1 and registrations[0].rateCommitment == - getRateCommitment(credentials, UserMessageLimit(1)) and + getRateCommitment(credentials, UserMessageLimit(1)).get() and registrations[0].index == 0: manager.idCredentials = some(credentials) fut.complete() @@ -565,20 +571,16 @@ suite "Onchain group manager": debug "epoch in bytes", epochHex = epoch.inHex() # generate proof - let validProofRes = manager.generateProof( + let validProof = manager.generateProof( data = messageBytes, epoch = epoch, messageId = MessageId(0) - ) - require: - validProofRes.isOk() - let validProof = validProofRes.get() + ).valueOr: + raiseAssert $error # verify the proof (should be true) - let verifiedRes = manager.verifyProof(messageBytes, validProof) - require: - verifiedRes.isOk() + let verified = manager.verifyProof(messageBytes, validProof).valueOr: + raiseAssert $error - check: - verifiedRes.get() + check: verified await manager.stop() asyncTest "verifyProof: should reject invalid proof": @@ -591,7 +593,8 @@ suite "Onchain group manager": let idCredential = generateCredentials(manager.rlnInstance) try: - await manager.register(getRateCommitment(idCredential, UserMessageLimit(1))) + await manager.register(RateCommitment(idCommitment: idCredential.idCommitment, + userMessageLimit: UserMessageLimit(1))) except Exception, CatchableError: assert false, "exception raised when calling startGroupSync: " & getCurrentExceptionMsg() @@ -614,7 +617,7 @@ suite "Onchain group manager": data = messageBytes, epoch = epoch, messageId = MessageId(0) ) - require: + check: invalidProofRes.isOk() let invalidProof = invalidProofRes.get() @@ -645,7 +648,7 @@ suite "Onchain group manager": proc callback(registrations: seq[Membership]): Future[void] {.async.} = if registrations.len == 1 and registrations[0].rateCommitment == - getRateCommitment(credentials[futureIndex], UserMessageLimit(1)) and + getRateCommitment(credentials[futureIndex], UserMessageLimit(1)).get() and registrations[0].index == MembershipIndex(futureIndex): futs[futureIndex].complete() futureIndex += 1 @@ -665,7 +668,7 @@ suite "Onchain group manager": await allFutures(futures) # At this point, we should have a full root queue, 5 roots, and partial buffer of 1 root - require: + check: manager.validRoots.len() == credentialCount - 1 manager.validRootBuffer.len() == 1 diff --git a/tests/waku_rln_relay/test_rln_group_manager_static.nim b/tests/waku_rln_relay/test_rln_group_manager_static.nim index a90a56c514..a9f2a71e4c 100644 --- a/tests/waku_rln_relay/test_rln_group_manager_static.nim +++ b/tests/waku_rln_relay/test_rln_group_manager_static.nim @@ -140,7 +140,7 @@ suite "Static group manager": registrations[0].rateCommitment == RateCommitment( idCommitment: idCommitment, userMessageLimit: DefaultUserMessageLimit - ) + ).toLeaf().get() callbackCalled = true fut.complete() @@ -204,7 +204,7 @@ suite "Static group manager": withdrawals[0].rateCommitment == RateCommitment( idCommitment: idCommitment, userMessageLimit: DefaultUserMessageLimit - ) + ).toLeaf().get() callbackCalled = true fut.complete() diff --git a/waku/waku_rln_relay/contract.nim b/waku/waku_rln_relay/contract.nim index a88f83d20f..23bb9ff937 100644 --- a/waku/waku_rln_relay/contract.nim +++ b/waku/waku_rln_relay/contract.nim @@ -1,5 +1,14 @@ # This contract code is used in deployment, note: this is not the deployedBytecode, it includes constructor args. -# Ref: https://github.com/waku-org/waku-rln-contract/blob/886891b57ae54e439563023dd50161fec5ee29f1/deployments/sepolia/WakuRlnRegistry_Implementation.json -const RegistryContractCode* = - "0x60a06040523073ffffffffffffffffffffffffffffffffffffffff1660809073ffffffffffffffffffffffffffffffffffffffff168152506000606760006101000a81548161ffff021916908361ffff16021790555034801561006157600080fd5b50608051614429610099600039600081816106870152818161071801528181610922015281816109b30152610a6c01526144296000f3fe6080604052600436106200010a5760003560e01c80638da5cb5b1162000097578063f184ef4c1162000061578063f184ef4c14620002f3578063f2fde38b1462000323578063f55421471462000351578063fc6ed4641462000395576200010a565b80638da5cb5b146200024b578063cf616374146200027b578063d44fda1f14620002ab578063ef653d5e14620002c5576200010a565b806352d1902d11620000d957806352d1902d14620001b95780635a244efd14620001e9578063715018a614620002175780638129fc1c1462000231576200010a565b80632de999bf146200010f5780633659cfe6146200013d57806339c0364b146200016b5780634f1ef2861462000199575b600080fd5b3480156200011c57600080fd5b506200013b60048036038101906200013591906200197b565b620003c3565b005b3480156200014a57600080fd5b5062000169600480360381019062000163919062001a6e565b62000685565b005b3480156200017857600080fd5b5062000197600480360381019062000191919062001b1a565b6200081d565b005b620001b76004803603810190620001b1919062001cd3565b62000920565b005b348015620001c657600080fd5b50620001d162000a68565b604051620001e0919062001d54565b60405180910390f35b348015620001f657600080fd5b506200021560048036038101906200020f919062001d71565b62000b24565b005b3480156200022457600080fd5b506200022f62000bc7565b005b3480156200023e57600080fd5b506200024962000bdf565b005b3480156200025857600080fd5b506200026362000d2b565b60405162000272919062001db4565b60405180910390f35b3480156200028857600080fd5b506200029362000d55565b604051620002a2919062001de2565b60405180910390f35b348015620002b857600080fd5b50620002c362000d69565b005b348015620002d257600080fd5b50620002f16004803603810190620002eb919062001a6e565b62000e13565b005b3480156200030057600080fd5b506200030b62000ef4565b6040516200031a919062001de2565b60405180910390f35b3480156200033057600080fd5b506200034f600480360381019062000349919062001a6e565b62000f08565b005b3480156200035e57600080fd5b506200037d600480360381019062000377919062001dff565b62000f92565b6040516200038c919062001db4565b60405180910390f35b348015620003a257600080fd5b50620003c16004803603810190620003bb919062001e31565b62000fc5565b005b606560009054906101000a900461ffff1661ffff16606760009054906101000a900461ffff1661ffff161062000425576040517fd23276a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b6001156200067f5760666000606760009054906101000a900461ffff1661ffff1661ffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632de999bf858585856040518563ffffffff1660e01b8152600401620004ba949392919062001f57565b600060405180830381600087803b158015620004d557600080fd5b505af1925050508015620004e7575060015b62000673573d80600081146200051a576040519150601f19603f3d011682016040523d82523d6000602084013e6200051f565b606091505b506040516024016040516020818303038152906040527f57f69531000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505080519060200120818051906020012014620005c057805181602001fd5b606560009054906101000a900461ffff1661ffff166001606760009054906101000a900461ffff16620005f4919062001fc5565b61ffff161062000630576040517fd23276a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001606760008282829054906101000a900461ffff1662000652919062001fc5565b92506101000a81548161ffff021916908361ffff1602179055505062000679565b6200067f565b62000426565b50505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff160362000716576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200070d9062002089565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1662000757620010ce565b73ffffffffffffffffffffffffffffffffffffffff1614620007b0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620007a79062002121565b60405180910390fd5b620007bb8162001127565b6200081a81600067ffffffffffffffff811115620007de57620007dd62001b8c565b5b6040519080825280601f01601f191660200182016040528015620008115781602001600182028036833780820191505090505b50600062001134565b50565b606560009054906101000a900461ffff1661ffff168361ffff16106200086f576040517fd23276a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606660008461ffff1661ffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d66d6c1083836040518363ffffffff1660e01b8152600401620008e792919062002154565b600060405180830381600087803b1580156200090257600080fd5b505af115801562000917573d6000803e3d6000fd5b50505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1603620009b1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620009a89062002089565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16620009f2620010ce565b73ffffffffffffffffffffffffffffffffffffffff161462000a4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000a429062002121565b60405180910390fd5b62000a568262001127565b62000a648282600162001134565b5050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161462000afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000af290620021f7565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b905090565b62000b2e620012b3565b6000810362000b69576040517fe671aff300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081606560009054906101000a900461ffff1660405162000b8b90620018eb565b62000b9892919062002219565b604051809103906000f08015801562000bb5573d6000803e3d6000fd5b50905062000bc38162001338565b5050565b62000bd1620012b3565b62000bdd60006200142c565b565b60008060019054906101000a900460ff1615905080801562000c115750600160008054906101000a900460ff1660ff16105b8062000c42575062000c2330620014f2565b15801562000c415750600160008054906101000a900460ff1660ff16145b5b62000c84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000c7b90620022bc565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801562000cc2576001600060016101000a81548160ff0219169083151502179055505b62000ccc62001515565b801562000d285760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498600160405162000d1f919062002338565b60405180910390a15b50565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606760009054906101000a900461ffff1681565b62000d73620012b3565b606560009054906101000a900461ffff1661ffff16606760009054906101000a900461ffff1661ffff161062000dd5576040517fd23276a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001606760008282829054906101000a900461ffff1662000df7919062001fc5565b92506101000a81548161ffff021916908361ffff160217905550565b62000e1d620012b3565b6000819050606560009054906101000a900461ffff1661ffff168173ffffffffffffffffffffffffffffffffffffffff166328b070e06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000e83573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ea991906200236c565b61ffff161462000ee5576040517fb893b72300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000ef08262001338565b5050565b606560009054906101000a900461ffff1681565b62000f12620012b3565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160362000f84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000f7b9062002414565b60405180910390fd5b62000f8f816200142c565b50565b60666020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606560009054906101000a900461ffff1661ffff168561ffff161062001017576040517fd23276a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606660008661ffff1661ffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632de999bf858585856040518563ffffffff1660e01b815260040162001093949392919062001f57565b600060405180830381600087803b158015620010ae57600080fd5b505af1158015620010c3573d6000803e3d6000fd5b505050505050505050565b6000620010fe7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b62001573565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b62001131620012b3565b50565b620011627f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd914360001b6200157d565b60000160009054906101000a900460ff16156200118a57620011848362001587565b620012ae565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015620011f557506040513d601f19601f82011682018060405250810190620011f2919062002467565b60015b62001237576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200122e906200250f565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b81146200129f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200129690620025a7565b60405180910390fd5b50620012ad83838362001647565b5b505050565b620012bd62001679565b73ffffffffffffffffffffffffffffffffffffffff16620012dd62000d2b565b73ffffffffffffffffffffffffffffffffffffffff161462001336576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200132d9062002619565b60405180910390fd5b565b8060666000606560009054906101000a900461ffff1661ffff1661ffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcf6a3b406170499209d0fcf152a1605c7c5a5c99c855e2bb803433fc960718eb606560009054906101000a900461ffff1682604051620013e59291906200263b565b60405180910390a16001606560008282829054906101000a900461ffff166200140f919062001fc5565b92506101000a81548161ffff021916908361ffff16021790555050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff1662001567576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200155e90620026de565b60405180910390fd5b6200157162001681565b565b6000819050919050565b6000819050919050565b6200159281620016e9565b620015d4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620015cb9062002776565b60405180910390fd5b80620016037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b62001573565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b62001652836200170c565b600082511180620016605750805b1562001674576200167283836200175d565b505b505050565b600033905090565b600060019054906101000a900460ff16620016d3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620016ca90620026de565b60405180910390fd5b620016e7620016e162001679565b6200142c565b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b620017178162001587565b8073ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a250565b6060620017858383604051806060016040528060278152602001620043cd602791396200178d565b905092915050565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051620017b9919062002811565b600060405180830381855af49150503d8060008114620017f6576040519150601f19603f3d011682016040523d82523d6000602084013e620017fb565b606091505b50915091506200180e8683838762001819565b925050509392505050565b60608315620018835760008351036200187a576200183785620016e9565b62001879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162001870906200287a565b60405180910390fd5b5b82905062001890565b6200188f838362001898565b5b949350505050565b600082511115620018ac5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620018e29190620028e8565b60405180910390fd5b611ac0806200290d83390190565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126200193557620019346200190d565b5b8235905067ffffffffffffffff81111562001955576200195462001912565b5b60208301915083602082028301111562001974576200197362001917565b5b9250929050565b6000806000806040858703121562001998576200199762001903565b5b600085013567ffffffffffffffff811115620019b957620019b862001908565b5b620019c7878288016200191c565b9450945050602085013567ffffffffffffffff811115620019ed57620019ec62001908565b5b620019fb878288016200191c565b925092505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062001a368262001a09565b9050919050565b62001a488162001a29565b811462001a5457600080fd5b50565b60008135905062001a688162001a3d565b92915050565b60006020828403121562001a875762001a8662001903565b5b600062001a978482850162001a57565b91505092915050565b600061ffff82169050919050565b62001ab98162001aa0565b811462001ac557600080fd5b50565b60008135905062001ad98162001aae565b92915050565b6000819050919050565b62001af48162001adf565b811462001b0057600080fd5b50565b60008135905062001b148162001ae9565b92915050565b60008060006060848603121562001b365762001b3562001903565b5b600062001b468682870162001ac8565b935050602062001b598682870162001b03565b925050604062001b6c8682870162001b03565b9150509250925092565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b62001bc68262001b7b565b810181811067ffffffffffffffff8211171562001be85762001be762001b8c565b5b80604052505050565b600062001bfd620018f9565b905062001c0b828262001bbb565b919050565b600067ffffffffffffffff82111562001c2e5762001c2d62001b8c565b5b62001c398262001b7b565b9050602081019050919050565b82818337600083830152505050565b600062001c6c62001c668462001c10565b62001bf1565b90508281526020810184848401111562001c8b5762001c8a62001b76565b5b62001c9884828562001c46565b509392505050565b600082601f83011262001cb85762001cb76200190d565b5b813562001cca84826020860162001c55565b91505092915050565b6000806040838503121562001ced5762001cec62001903565b5b600062001cfd8582860162001a57565b925050602083013567ffffffffffffffff81111562001d215762001d2062001908565b5b62001d2f8582860162001ca0565b9150509250929050565b6000819050919050565b62001d4e8162001d39565b82525050565b600060208201905062001d6b600083018462001d43565b92915050565b60006020828403121562001d8a5762001d8962001903565b5b600062001d9a8482850162001b03565b91505092915050565b62001dae8162001a29565b82525050565b600060208201905062001dcb600083018462001da3565b92915050565b62001ddc8162001aa0565b82525050565b600060208201905062001df9600083018462001dd1565b92915050565b60006020828403121562001e185762001e1762001903565b5b600062001e288482850162001ac8565b91505092915050565b60008060008060006060868803121562001e505762001e4f62001903565b5b600062001e608882890162001ac8565b955050602086013567ffffffffffffffff81111562001e845762001e8362001908565b5b62001e92888289016200191c565b9450945050604086013567ffffffffffffffff81111562001eb85762001eb762001908565b5b62001ec6888289016200191c565b92509250509295509295909350565b600082825260208201905092915050565b600080fd5b82818337505050565b600062001f02838562001ed5565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111562001f385762001f3762001ee6565b5b60208302925062001f4b83858462001eeb565b82840190509392505050565b6000604082019050818103600083015262001f7481868862001ef4565b9050818103602083015262001f8b81848662001ef4565b905095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062001fd28262001aa0565b915062001fdf8362001aa0565b9250828201905061ffff81111562001ffc5762001ffb62001f96565b5b92915050565b600082825260208201905092915050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060008201527f64656c656761746563616c6c0000000000000000000000000000000000000000602082015250565b600062002071602c8362002002565b91506200207e8262002013565b604082019050919050565b60006020820190508181036000830152620020a48162002062565b9050919050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060008201527f6163746976652070726f78790000000000000000000000000000000000000000602082015250565b600062002109602c8362002002565b91506200211682620020ab565b604082019050919050565b600060208201905081810360008301526200213c81620020fa565b9050919050565b6200214e8162001adf565b82525050565b60006040820190506200216b600083018562002143565b6200217a602083018462002143565b9392505050565b7f555550535570677261646561626c653a206d757374206e6f742062652063616c60008201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000602082015250565b6000620021df60388362002002565b9150620021ec8262002181565b604082019050919050565b600060208201905081810360008301526200221281620021d0565b9050919050565b600060408201905062002230600083018562002143565b6200223f602083018462001dd1565b9392505050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000620022a4602e8362002002565b9150620022b18262002246565b604082019050919050565b60006020820190508181036000830152620022d78162002295565b9050919050565b6000819050919050565b600060ff82169050919050565b6000819050919050565b6000620023206200231a6200231484620022de565b620022f5565b620022e8565b9050919050565b6200233281620022ff565b82525050565b60006020820190506200234f600083018462002327565b92915050565b600081519050620023668162001aae565b92915050565b60006020828403121562002385576200238462001903565b5b6000620023958482850162002355565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000620023fc60268362002002565b915062002409826200239e565b604082019050919050565b600060208201905081810360008301526200242f81620023ed565b9050919050565b620024418162001d39565b81146200244d57600080fd5b50565b600081519050620024618162002436565b92915050565b60006020828403121562002480576200247f62001903565b5b6000620024908482850162002450565b91505092915050565b7f45524331393637557067726164653a206e657720696d706c656d656e7461746960008201527f6f6e206973206e6f742055555053000000000000000000000000000000000000602082015250565b6000620024f7602e8362002002565b9150620025048262002499565b604082019050919050565b600060208201905081810360008301526200252a81620024e8565b9050919050565b7f45524331393637557067726164653a20756e737570706f727465642070726f7860008201527f6961626c65555549440000000000000000000000000000000000000000000000602082015250565b60006200258f60298362002002565b91506200259c8262002531565b604082019050919050565b60006020820190508181036000830152620025c28162002580565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006200260160208362002002565b91506200260e82620025c9565b602082019050919050565b600060208201905081810360008301526200263481620025f2565b9050919050565b600060408201905062002652600083018562001dd1565b62002661602083018462001da3565b9392505050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000620026c6602b8362002002565b9150620026d38262002668565b604082019050919050565b60006020820190508181036000830152620026f981620026b7565b9050919050565b7f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60008201527f6f74206120636f6e747261637400000000000000000000000000000000000000602082015250565b60006200275e602d8362002002565b91506200276b8262002700565b604082019050919050565b6000602082019050818103600083015262002791816200274f565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015620027ce578082015181840152602081019050620027b1565b60008484015250505050565b6000620027e78262002798565b620027f38185620027a3565b935062002805818560208601620027ae565b80840191505092915050565b60006200281f8284620027da565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b600062002862601d8362002002565b91506200286f826200282a565b602082019050919050565b60006020820190508181036000830152620028958162002853565b9050919050565b600081519050919050565b6000620028b4826200289c565b620028c0818562002002565b9350620028d2818560208601620027ae565b620028dd8162001b7b565b840191505092915050565b60006020820190508181036000830152620029048184620028a7565b90509291505056fe61016060405260006001553480156200001757600080fd5b5060405162001ac038038062001ac083398181016040528101906200003d91906200023a565b600060148360006200006462000058620000ef60201b60201c565b620000f760201b60201c565b8360a0818152505081608081815250508260c08181525050826001901b60e081815250508073ffffffffffffffffffffffffffffffffffffffff166101008173ffffffffffffffffffffffffffffffffffffffff16815250504363ffffffff166101208163ffffffff1681525050505050508061ffff166101408161ffff1681525050505062000281565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b6000819050919050565b620001d581620001c0565b8114620001e157600080fd5b50565b600081519050620001f581620001ca565b92915050565b600061ffff82169050919050565b6200021481620001fb565b81146200022057600080fd5b50565b600081519050620002348162000209565b92915050565b60008060408385031215620002545762000253620001bb565b5b60006200026485828601620001e4565b9250506020620002778582860162000223565b9150509250929050565b60805160a05160c05160e0516101005161012051610140516117cf620002f16000396000610661015260006107c401526000610685015260008181610a4a0152610f24015260006109f001526000818161075f0152610aa00152600081816106050152610dd201526117cf6000f3fe6080604052600436106101665760003560e01c80638be9b119116100d1578063bc4991281161008a578063d66d6c1011610064578063d66d6c1014610568578063e493ef8c14610584578063f220b9ec146105af578063f2fde38b146105da57610166565b8063bc499128146104c3578063c5b208ff14610500578063d0383d681461053d57610166565b80638be9b1191461039f5780638da5cb5b146103c85780639056a9bf146103f3578063933ebfdd1461043057806398366e351461046d578063ae74552a1461049857610166565b80633ccfd60b116101235780633ccfd60b1461028f5780634add651e146102a65780635daf08ca146102d15780636bdcc8ab1461030e578063715018a61461034b5780637671ac051461036257610166565b806309aeb04c1461016b57806322d9730c1461019657806328b070e0146101d35780632b7ac3f3146101fe5780632de999bf14610229578063378de45b14610252575b600080fd5b34801561017757600080fd5b50610180610603565b60405161018d9190610f9c565b60405180910390f35b3480156101a257600080fd5b506101bd60048036038101906101b89190610fed565b610627565b6040516101ca9190611035565b60405180910390f35b3480156101df57600080fd5b506101e861065f565b6040516101f5919061106d565b60405180910390f35b34801561020a57600080fd5b50610213610683565b6040516102209190611107565b60405180910390f35b34801561023557600080fd5b50610250600480360381019061024b9190611187565b6106a7565b005b34801561025e57600080fd5b5061027960048036038101906102749190610fed565b61075b565b6040516102869190610f9c565b60405180910390f35b34801561029b57600080fd5b506102a4610790565b005b3480156102b257600080fd5b506102bb6107c2565b6040516102c89190611227565b60405180910390f35b3480156102dd57600080fd5b506102f860048036038101906102f39190610fed565b6107e6565b6040516103059190610f9c565b60405180910390f35b34801561031a57600080fd5b5061033560048036038101906103309190610fed565b6107fe565b6040516103429190611035565b60405180910390f35b34801561035757600080fd5b5061036061081e565b005b34801561036e57600080fd5b5061038960048036038101906103849190610fed565b610832565b6040516103969190610f9c565b60405180910390f35b3480156103ab57600080fd5b506103c660048036038101906103c191906112a2565b61084a565b005b3480156103d457600080fd5b506103dd61085a565b6040516103ea9190611317565b60405180910390f35b3480156103ff57600080fd5b5061041a60048036038101906104159190610fed565b610883565b6040516104279190610f9c565b60405180910390f35b34801561043c57600080fd5b5061045760048036038101906104529190611332565b61089b565b6040516104649190611430565b60405180910390f35b34801561047957600080fd5b506104826109ee565b60405161048f9190610f9c565b60405180910390f35b3480156104a457600080fd5b506104ad610a12565b6040516104ba9190610f9c565b60405180910390f35b3480156104cf57600080fd5b506104ea60048036038101906104e59190610fed565b610a18565b6040516104f79190610f9c565b60405180910390f35b34801561050c57600080fd5b506105276004803603810190610522919061147e565b610a30565b6040516105349190610f9c565b60405180910390f35b34801561054957600080fd5b50610552610a48565b60405161055f9190610f9c565b60405180910390f35b610582600480360381019061057d9190611332565b610a6c565b005b34801561059057600080fd5b50610599610a7a565b6040516105a69190610f9c565b60405180910390f35b3480156105bb57600080fd5b506105c4610a9e565b6040516105d19190610f9c565b60405180910390f35b3480156105e657600080fd5b5061060160048036038101906105fc919061147e565b610ac2565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b600080821415801561065857507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182105b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6106af610b45565b838383836106bf84848484610bc3565b6106f5576040517fb750624800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088889050905060005b8181101561074f576107448a8a8381811061071e5761071d6114ab565b5b90506020020135898984818110610738576107376114ab565b5b90506020020135610bf5565b806001019050610700565b50505050505050505050565b60007f0000000000000000000000000000000000000000000000000000000000000000826107899190611509565b9050919050565b6040517fd623472500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000081565b60036020528060005260406000206000915090505481565b60066020528060005260406000206000915054906101000a900460ff1681565b610826610b45565b6108306000610cd1565b565b60056020528060005260406000206000915090505481565b610855838383610d95565b505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60046020528060005260406000206000915090505481565b60608183106108e35782826040517f9ffcd53d0000000000000000000000000000000000000000000000000000000081526004016108da92919061154b565b60405180910390fd5b60015482111561092c5782826040517f9ffcd53d00000000000000000000000000000000000000000000000000000000815260040161092392919061154b565b60405180910390fd5b6000838361093a9190611574565b67ffffffffffffffff811115610953576109526115a8565b5b6040519080825280602002602001820160405280156109815781602001602082028036833780820191505090505b50905060008490505b838110156109e35760056000828152602001908152602001600020548286836109b39190611574565b815181106109c4576109c36114ab565b5b60200260200101818152505080806109db906115d7565b91505061098a565b508091505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60015481565b60026020528060005260406000206000915090505481565b60076020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b610a768282610bf5565b5050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b7f000000000000000000000000000000000000000000000000000000000000000081565b610aca610b45565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b30906116a2565b60405180910390fd5b610b4281610cd1565b50565b610b4d610dc7565b73ffffffffffffffffffffffffffffffffffffffff16610b6b61085a565b73ffffffffffffffffffffffffffffffffffffffff1614610bc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb89061170e565b60405180910390fd5b565b6000808585905090506000848490509050808214610be657600092505050610bed565b6001925050505b949350505050565b610bff8282610dcf565b6001546003600084815260200190815260200160002081905550816005600060015481526020019081526020016000208190555060016006600084815260200190815260200160002060006101000a81548160ff0219169083151502179055508060046000848152602001908152602001600020819055507fff42916a89d1f5125f7f47168ee59c2b3fc9246ad1b229082ee85b69d001b5d78282600154604051610cac9392919061172e565b60405180910390a16001806000828254610cc69190611765565b925050819055505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6040517fd623472500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600033905090565b807f0000000000000000000000000000000000000000000000000000000000000000811115610e3557806040517f13a5e2ee000000000000000000000000000000000000000000000000000000008152600401610e2c9190610f9c565b60405180910390fd5b60008103610e7a57806040517f13a5e2ee000000000000000000000000000000000000000000000000000000008152600401610e719190610f9c565b60405180910390fd5b82610e8481610627565b610ec557806040517f7f3e75af000000000000000000000000000000000000000000000000000000008152600401610ebc9190610f9c565b60405180910390fd5b600115156006600086815260200190815260200160002060009054906101000a900460ff16151503610f22576040517e0a60f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000060015410610f7d576040517f57f6953100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6000819050919050565b610f9681610f83565b82525050565b6000602082019050610fb16000830184610f8d565b92915050565b600080fd5b600080fd5b610fca81610f83565b8114610fd557600080fd5b50565b600081359050610fe781610fc1565b92915050565b60006020828403121561100357611002610fb7565b5b600061101184828501610fd8565b91505092915050565b60008115159050919050565b61102f8161101a565b82525050565b600060208201905061104a6000830184611026565b92915050565b600061ffff82169050919050565b61106781611050565b82525050565b6000602082019050611082600083018461105e565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006110cd6110c86110c384611088565b6110a8565b611088565b9050919050565b60006110df826110b2565b9050919050565b60006110f1826110d4565b9050919050565b611101816110e6565b82525050565b600060208201905061111c60008301846110f8565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261114757611146611122565b5b8235905067ffffffffffffffff81111561116457611163611127565b5b6020830191508360208202830111156111805761117f61112c565b5b9250929050565b600080600080604085870312156111a1576111a0610fb7565b5b600085013567ffffffffffffffff8111156111bf576111be610fbc565b5b6111cb87828801611131565b9450945050602085013567ffffffffffffffff8111156111ee576111ed610fbc565b5b6111fa87828801611131565b925092505092959194509250565b600063ffffffff82169050919050565b61122181611208565b82525050565b600060208201905061123c6000830184611218565b92915050565b600061124d82611088565b9050919050565b61125d81611242565b811461126857600080fd5b50565b60008135905061127a81611254565b92915050565b60008190508260206008028201111561129c5761129b61112c565b5b92915050565b600080600061014084860312156112bc576112bb610fb7565b5b60006112ca86828701610fd8565b93505060206112db8682870161126b565b92505060406112ec86828701611280565b9150509250925092565b600061130182611088565b9050919050565b611311816112f6565b82525050565b600060208201905061132c6000830184611308565b92915050565b6000806040838503121561134957611348610fb7565b5b600061135785828601610fd8565b925050602061136885828601610fd8565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6113a781610f83565b82525050565b60006113b9838361139e565b60208301905092915050565b6000602082019050919050565b60006113dd82611372565b6113e7818561137d565b93506113f28361138e565b8060005b8381101561142357815161140a88826113ad565b9750611415836113c5565b9250506001810190506113f6565b5085935050505092915050565b6000602082019050818103600083015261144a81846113d2565b905092915050565b61145b816112f6565b811461146657600080fd5b50565b60008135905061147881611452565b92915050565b60006020828403121561149457611493610fb7565b5b60006114a284828501611469565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061151482610f83565b915061151f83610f83565b925082820261152d81610f83565b91508282048414831517611544576115436114da565b5b5092915050565b60006040820190506115606000830185610f8d565b61156d6020830184610f8d565b9392505050565b600061157f82610f83565b915061158a83610f83565b92508282039050818111156115a2576115a16114da565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006115e282610f83565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611614576116136114da565b5b600182019050919050565b600082825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061168c60268361161f565b915061169782611630565b604082019050919050565b600060208201905081810360008301526116bb8161167f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006116f860208361161f565b9150611703826116c2565b602082019050919050565b60006020820190508181036000830152611727816116eb565b9050919050565b60006060820190506117436000830186610f8d565b6117506020830185610f8d565b61175d6040830184610f8d565b949350505050565b600061177082610f83565b915061177b83610f83565b9250828201905080821115611793576117926114da565b5b9291505056fea2646970667358221220f3d63817472861b92ed47c1c0a059033d26762a83df789a2f02dba13d9cc3df464736f6c63430008130033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212206950adc7c418dd947ac3e184fb9f4d3a3206a03ca637b1c5a6fa23e8ae800c7464736f6c63430008130033" +# Ref: https://github.com/waku-org/waku-rlnv2-contract +const PoseidonT3* = + "0x615be56200003b600b82828239805160001a60731461002e57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100355760003560e01c8063561558fe1461003a575b600080fd5b61004d610048366004615b3e565b61005f565b60405190815260200160405180910390f35b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000017f2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d7f101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa7f19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e07ef1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e8648460805106017f08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f58560a05106018582830986838883840909925086828309905086828883840909915086868309877f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e08509017f5151bcc773d05d360fc9c923795441a9618605f30e31f2b8f087d1575b9c613b01905086858309877f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe238509017f547424ff6c2e186923faa2cf5794c8cd2b5d3e8f151620ffda4a15b70cc05b3f0187858409887f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee29118609017f23dc61092dc247151d38da17703c1ccb157f035575fe333d62fda4d2a5ae1bf5018883800989848b83840909935089838409905089838b83840909925089828309905089828b838409099150898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc63201945089818209935089818b86870909905089868709935089868b86870909955089858609935089858b868709099450898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c01915089848509905089848b83840909935089838409905089838b83840909925089828309905089828b838409099150898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c870501945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd101945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017e5032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc001915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c88701915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da5301945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017e81c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb3801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a001915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c50201945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017eef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba8901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c501945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e401915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e1301945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a9003501945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db6901945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c7701945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017e2e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017eb9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c351201945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017e248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a80801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f0901945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e828401915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd80001915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f17801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e50423301945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc001915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d5901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f8894801945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d14201915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c001945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a5801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d0101945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc79201945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea611101915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa33601945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d601915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f45101945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf7701915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc63001945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc01915089848509905089848b83840909935089838409905089838b83840909925089828309905089828b838409099150898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c232001945089818209935089818b86870909905089868709935089868b86870909955089858609935089858b868709099450898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f801915089848509905089848b83840909935089838409905089838b83840909925089828309905089828b838409099150898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e422832516101945089818209935089818b86870909905089868709935089868b86870909955089858609935089858b868709099450898a8a87098b7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e089098c7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b850901010660005260206000f35b600060408284031215615b5057600080fd5b82601f830112615b5f57600080fd5b6040516040810181811067ffffffffffffffff82111715615ba9577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250806040840185811115615bc057600080fd5b845b81811015615bda578035835260209283019201615bc2565b50919594505050505056" +const LazyIMT* = + "0x611e7861003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100ad5760003560e01c80633c251db111610080578063899375d611610065578063899375d614610183578063b7ca3a2d146101c6578063ca9ecfd4146101d957600080fd5b80633c251db11461014357806361136cec1461016357600080fd5b80630224ef5e146100b257806309489a3c146100d45780630c26d683146100f457806339ebe6e314610122575b600080fd5b8180156100be57600080fd5b506100d26100cd366004611a23565b6101ec565b005b8180156100e057600080fd5b506100d26100ef366004611a5f565b6101fa565b610107610102366004611aa5565b61020a565b60405164ffffffffff90911681526020015b60405180910390f35b610135610130366004611ad8565b61021f565b604051908152602001610119565b610156610151366004611afb565b61022b565b6040516101199190611b2e565b81801561016f57600080fd5b506100d261017e366004611ad8565b610242565b81801561018f57600080fd5b506100d261019e366004611b72565b80547fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff169055565b6101356101d4366004611b72565b61024c565b6101356101e7366004611b8b565b610257565b6101f68282610262565b5050565b6102058383836104d9565b505050565b60006102168383610812565b90505b92915050565b60006102168383610830565b6060610238848484610987565b90505b9392505050565b6101f68282610d23565b600061021982610dbd565b600061021982610e15565b815465010000000000900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001821061030e5760405162461bcd60e51b815260206004820152602a60248201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f534360448201527f414c41525f4649454c440000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b825464ffffffffff908116908216106103695760405162461bcd60e51b815260206004820152601560248201527f4c617a79494d543a20747265652069732066756c6c00000000000000000000006044820152606401610305565b610374816001611bd5565b835464ffffffffff9190911665010000000000027fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff9091161783558160005b818560010160006103c48487610812565b64ffffffffff16815260208101919091526040016000205560018316156104d25760006103fb826103f6600187611bfa565b610812565b60408051808201825264ffffffffff8316600090815260018a01602090815290839020548252810186905290517f561558fe00000000000000000000000000000000000000000000000000000000815291925073__$PoseidonT3$__9163561558fe9161047691600401611c18565b602060405180830381865af4158015610493573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b79190611c49565b647fffffffff600195861c16949093509190910190506103b3565b5050505050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001821061056e5760405162461bcd60e51b815260206004820152602a60248201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f534360448201527f414c41525f4649454c44000000000000000000000000000000000000000000006064820152608401610305565b825464ffffffffff65010000000000909104811690821681116105d35760405162461bcd60e51b815260206004820152601860248201527f4c617a79494d543a206c656166206d75737420657869737400000000000000006044820152606401610305565b8260005b818660010160006105e88488610812565b64ffffffffff1681526020019081526020016000208190555060008160016106109190611c62565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111610645575061080a565b60018516600003610725576000610661836103f6886001611bd5565b60408051808201825286815264ffffffffff8316600090815260018c01602090815290839020549082015290517f561558fe00000000000000000000000000000000000000000000000000000000815291925073__$PoseidonT3$__9163561558fe916106dc91600401611c18565b602060405180830381865af41580156106f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071d9190611c49565b9350506107f6565b6000610736836103f6600189611bfa565b60408051808201825264ffffffffff8316600090815260018c01602090815290839020548252810187905290517f561558fe00000000000000000000000000000000000000000000000000000000815291925073__$PoseidonT3$__9163561558fe916107b191600401611c18565b602060405180830381865af41580156107ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f29190611c49565b9350505b50647fffffffff600194851c1693016105d7565b505050505050565b60008161082660ff851663ffffffff611c7b565b6102169190611bd5565b6000808260ff16116108845760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e20300000000000006044820152606401610305565b602060ff831611156108fe5760405162461bcd60e51b815260206004820152602360248201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f444560448201527f50544800000000000000000000000000000000000000000000000000000000006064820152608401610305565b825465010000000000900464ffffffffff168061091f60ff85166002611db9565b64ffffffffff1610156109745760405162461bcd60e51b815260206004820152601860248201527f4c617a79494d543a20616d626967756f757320646570746800000000000000006044820152606401610305565b61097f8482856114b2565b949350505050565b825460609064ffffffffff65010000000000909104811690841681116109ef5760405162461bcd60e51b815260206004820152601860248201527f4c617a79494d543a206c656166206d75737420657869737400000000000000006044820152606401610305565b60015b64ffffffffff8216610a0860ff83166002611db9565b64ffffffffff161015610a275780610a1f81611dcf565b9150506109f2565b8060ff168460ff161015610a7d5760405162461bcd60e51b815260206004820152601460248201527f4c617a79494d543a2070726f6f662064657074680000000000000000000000006044820152606401610305565b60008460ff1667ffffffffffffffff811115610a9b57610a9b611dee565b604051908082528060200260200182016040528015610ac4578160200160208202803683370190505b509050610add8784610ad7600186611e1d565b846115d4565b60018616600003610b765764ffffffffff8316610afb876001611bd5565b64ffffffffff1610610b3557610b116000610e15565b81600081518110610b2457610b24611e36565b602002602001018181525050610bc4565b866001016000610b4d60008960016103f69190611bd5565b64ffffffffff1681526020019081526020016000205481600081518110610b2457610b24611e36565b866001016000610b8e600060018a6103f69190611bfa565b64ffffffffff1681526020019081526020016000205481600081518110610bb757610bb7611e36565b6020026020010181815250505b647fffffffff600196871c16955b8560ff168160ff161015610d185764ffffffffff80851660ff83161c1660018816600003610cb55780610c06896001611bd5565b64ffffffffff161015610c6657886001016000610c2a848b60016103f69190611bd5565b64ffffffffff16815260200190815260200160002054838360ff1681518110610c5557610c55611e36565b602002602001018181525050610d04565b64ffffffffff881660ff8316610c7d600188611bfa565b64ffffffffff16901c64ffffffffff1611610cb057610c9b82610e15565b838360ff1681518110610c5557610c55611e36565b610d04565b886001016000610ccc8460018c6103f69190611bfa565b64ffffffffff16815260200190815260200160002054838360ff1681518110610cf757610cf7611e36565b6020026020010181815250505b50647fffffffff600197881c169601610bd2565b509695505050505050565b602060ff82161115610d775760405162461bcd60e51b815260206004820152601760248201527f4c617a79494d543a205472656520746f6f206c617267650000000000000000006044820152606401610305565b610d88600160ff831681901b611e65565b82547fffffffffffffffffffffffffffffffffffffffffffff000000000000000000001664ffffffffff919091161790915550565b805460009065010000000000900464ffffffffff1660015b64ffffffffff8216610deb60ff83166002611db9565b64ffffffffff161015610e0a5780610e0281611dcf565b915050610dd5565b61097f8483836114b2565b60008160ff16600003610e2a57506000919050565b8160ff16600103610e5c57507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff16600203610e8e57507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff16600303610ec057507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff16600403610ef257507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff16600503610f2457507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff16600603610f5657507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff16600703610f8857507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff16600803610fba57507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff16600903610fec57507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a0361101e57507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b0361105057507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c0361108257507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d036110b457507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e036110e657507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f0361111857507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff1660100361114a57507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff1660110361117c57507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff166012036111ae57507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff166013036111e057507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff1660140361121257507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff1660150361124457507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff1660160361127657507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff166017036112a857507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff166018036112da57507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff1660190361130c57507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a0361133e57507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b0361137057507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c036113a257507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d036113d457507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e0361140657507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f0361143857507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff1660200361146a57507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e64657800006044820152606401610305565b6000602060ff8316111561152e5760405162461bcd60e51b815260206004820152602360248201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f444560448201527f50544800000000000000000000000000000000000000000000000000000000006064820152608401610305565b8264ffffffffff1660000361154d5761154682610e15565b905061023b565b600061155a836001611c62565b60ff1667ffffffffffffffff81111561157557611575611dee565b60405190808252806020026020018201604052801561159e578160200160208202803683370190505b5090506115ad858585846115d4565b808360ff16815181106115c2576115c2611e36565b60200260200101519150509392505050565b602060ff8316111561164e5760405162461bcd60e51b815260206004820152602360248201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f444560448201527f50544800000000000000000000000000000000000000000000000000000000006064820152608401610305565b60008364ffffffffff16116116cb5760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d757374206260448201527f65203e20300000000000000000000000000000000000000000000000000000006064820152608401610305565b60006116d8600185611bfa565b905060018116600003611730578460010160006116f6600084610812565b64ffffffffff168152602001908152602001600020548260008151811061171f5761171f611e36565b60200260200101818152505061175a565b61173a6000610e15565b8260008151811061174d5761174d611e36565b6020026020010181815250505b60005b8360ff168160ff16101561080a57600182166000036118565773__$PoseidonT3$__63561558fe6040518060400160405280868560ff16815181106117b0576117b0611e36565b602002602001015181526020016117c685610e15565b8152506040518263ffffffff1660e01b81526004016117e59190611c18565b602060405180830381865af4158015611802573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118269190611c49565b83611832836001611c62565b60ff168151811061184557611845611e36565b602002602001018181525050611a10565b6000611863826001611c62565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff168111156119085760008760010160006118bc8560016118ab9190611c62565b60018864ffffffffff16901c610812565b64ffffffffff16815260200190815260200160002054905080858460016118e39190611c62565b60ff16815181106118f6576118f6611e36565b60200260200101818152505050611a0e565b6000876001016000611921856001886103f69190611bfa565b64ffffffffff16815260200190815260200160002054905073__$PoseidonT3$__63561558fe6040518060400160405280848152602001888760ff168151811061197957611979611e36565b60200260200101518152506040518263ffffffff1660e01b81526004016119a09190611c18565b602060405180830381865af41580156119bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e19190611c49565b856119ed856001611c62565b60ff1681518110611a0057611a00611e36565b602002602001018181525050505b505b647fffffffff600192831c16910161175d565b60008060408385031215611a3657600080fd5b50508035926020909101359150565b803564ffffffffff81168114611a5a57600080fd5b919050565b600080600060608486031215611a7457600080fd5b8335925060208401359150611a8b60408501611a45565b90509250925092565b803560ff81168114611a5a57600080fd5b60008060408385031215611ab857600080fd5b611ac183611a94565b9150611acf60208401611a45565b90509250929050565b60008060408385031215611aeb57600080fd5b82359150611acf60208401611a94565b600080600060608486031215611b1057600080fd5b83359250611b2060208501611a45565b9150611a8b60408501611a94565b6020808252825182820181905260009190848201906040850190845b81811015611b6657835183529284019291840191600101611b4a565b50909695505050505050565b600060208284031215611b8457600080fd5b5035919050565b600060208284031215611b9d57600080fd5b61021682611a94565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b64ffffffffff818116838216019080821115611bf357611bf3611ba6565b5092915050565b64ffffffffff828116828216039080821115611bf357611bf3611ba6565b60408101818360005b6002811015611c40578151835260209283019290910190600101611c21565b50505092915050565b600060208284031215611c5b57600080fd5b5051919050565b60ff818116838216019081111561021957610219611ba6565b64ffffffffff818116838216028082169190828114611c9c57611c9c611ba6565b505092915050565b600181815b80851115611ce2578164ffffffffff04821115611cc857611cc8611ba6565b80851615611cd557918102915b93841c9390800290611ca9565b509250929050565b600082611cf957506001610219565b81611d0657506000610219565b8160018114611d1c5760028114611d2657611d58565b6001915050610219565b60ff841115611d3757611d37611ba6565b6001841b915064ffffffffff821115611d5257611d52611ba6565b50610219565b5060208310610133831016604e8410600b8410161715611d90575081810a64ffffffffff811115611d8b57611d8b611ba6565b610219565b611d9a8383611ca4565b8064ffffffffff04821115611db157611db1611ba6565b029392505050565b600064ffffffffff61097f818516828516611cea565b600060ff821660ff8103611de557611de5611ba6565b60010192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60ff828116828216039081111561021957610219611ba6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561021957610219611ba656" +const Erc1967Proxy* = + "0x60806040526040516103c73803806103c78339810160408190526100229161025e565b61002c8282610033565b5050610341565b61003c82610091565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a280511561008557610080828261010c565b505050565b61008d61017f565b5050565b806001600160a01b03163b5f036100cb57604051634c9c8ce360e01b81526001600160a01b03821660048201526024015b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b60605f80846001600160a01b0316846040516101289190610326565b5f60405180830381855af49150503d805f8114610160576040519150601f19603f3d011682016040523d82523d5f602084013e610165565b606091505b5090925090506101768583836101a0565b95945050505050565b341561019e5760405163b398979f60e01b815260040160405180910390fd5b565b6060826101b5576101b0826101ff565b6101f8565b81511580156101cc57506001600160a01b0384163b155b156101f557604051639996b31560e01b81526001600160a01b03851660048201526024016100c2565b50805b9392505050565b80511561020f5780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b634e487b7160e01b5f52604160045260245ffd5b5f5b8381101561025657818101518382015260200161023e565b50505f910152565b5f806040838503121561026f575f80fd5b82516001600160a01b0381168114610285575f80fd5b60208401519092506001600160401b03808211156102a1575f80fd5b818501915085601f8301126102b4575f80fd5b8151818111156102c6576102c6610228565b604051601f8201601f19908116603f011681019083821181831017156102ee576102ee610228565b81604052828152886020848701011115610306575f80fd5b61031783602083016020880161023c565b80955050505050509250929050565b5f825161033781846020870161023c565b9190910192915050565b607a8061034d5f395ff3fe6080604052600a600c565b005b60186014601a565b605d565b565b5f60587f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b365f80375f80365f845af43d5f803e8080156076573d5ff35b3d5ffd" +const Erc1967ProxyContractInput* = + "000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000248d8965bd0000000000000000000000000000000000000000000000000000000000000014" + +const WakuRlnV2Contract* = + "0x60a06040523060805234801561001457600080fd5b5061001d610022565b6100e1565b600054610100900460ff161561008e5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100df576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6080516121ca6200011960003960008181610598015281816106330152818161076e01528181610804015261093301526121ca6000f3fe6080604052600436106101805760003560e01c806374e942fa116100d6578063af7b42101161007f578063e493ef8c11610059578063e493ef8c146104e2578063ebf0c71714610516578063f2fde38b1461052b57600080fd5b8063af7b421014610441578063d0383d6814610461578063d90d0ee61461048657600080fd5b806398366e35116100b057806398366e35146103b75780639ac21345146103de578063a45d5e591461042157600080fd5b806374e942fa146103355780638d8965bd146103625780638da5cb5b1461038257600080fd5b80634add651e11610138578063679537f911610112578063679537f9146102d35780636bdcc8ab14610300578063715018a61461032057600080fd5b80634add651e146102805780634f1ef2861461029d57806352d1902d146102b057600080fd5b806322d9730c1161016957806322d9730c146101e55780633659cfe6146102155780633c979b5f1461023757600080fd5b8063037a791a1461018557806309aeb04c146101c8575b600080fd5b34801561019157600080fd5b5060c9546101ae9068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020015b60405180910390f35b3480156101d457600080fd5b5060c9546101ae9063ffffffff1681565b3480156101f157600080fd5b50610205610200366004611c81565b61054b565b60405190151581526020016101bf565b34801561022157600080fd5b50610235610230366004611cc3565b610581565b005b34801561024357600080fd5b5060cc546102629064ffffffffff808216916501000000000090041682565b6040805164ffffffffff9384168152929091166020830152016101bf565b34801561028c57600080fd5b5060cb546101ae9063ffffffff1681565b6102356102ab366004611d5c565b610757565b3480156102bc57600080fd5b506102c5610919565b6040519081526020016101bf565b3480156102df57600080fd5b506102f36102ee366004611e34565b6109eb565b6040516101bf9190611e67565b34801561030c57600080fd5b5061020561031b366004611c81565b610b6a565b34801561032c57600080fd5b50610235610b81565b34801561034157600080fd5b50610355610350366004611ebe565b610b95565b6040516101bf9190611edb565b34801561036e57600080fd5b5061023561037d366004611f0d565b610cc4565b34801561038e57600080fd5b5060335460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bf565b3480156103c357600080fd5b506103cc601481565b60405160ff90911681526020016101bf565b3480156103ea57600080fd5b506103fe6103f9366004611c81565b610f5f565b6040805163ffffffff9485168152939092166020840152908201526060016101bf565b34801561042d57600080fd5b5061020561043c366004611f0d565b610fd0565b34801561044d57600080fd5b5061023561045c366004611f28565b610ff5565b34801561046d57600080fd5b5060c9546101ae90640100000000900463ffffffff1681565b34801561049257600080fd5b506104c56104a1366004611c81565b60ca6020526000908152604090205463ffffffff8082169164010000000090041682565b6040805163ffffffff9384168152929091166020830152016101bf565b3480156104ee57600080fd5b506102c57f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b34801561052257600080fd5b506102c5611090565b34801561053757600080fd5b50610235610546366004611cc3565b61112c565b6000811580159061057b57507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182105b92915050565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001630036106315760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c000000000000000000000000000000000000000060648201526084015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166106a67f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff161461072f5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401610628565b610738816111c6565b60408051600080825260208201909252610754918391906111ce565b50565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001630036108025760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401610628565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166108777f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16146109005760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401610628565b610909826111c6565b610915828260016111ce565b5050565b60003073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146109c65760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610628565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b60608163ffffffff168363ffffffff161115610a43576040517f9ffcd53d00000000000000000000000000000000000000000000000000000000815263ffffffff808516600483015283166024820152604401610628565b60c95463ffffffff6801000000000000000090910481169083161115610aa5576040517f9ffcd53d00000000000000000000000000000000000000000000000000000000815263ffffffff808516600483015283166024820152604401610628565b6000610ab18484611f7a565b610abc906001611f9e565b63ffffffff1667ffffffffffffffff811115610ada57610ada611cde565b604051908082528060200260200182016040528015610b03578160200160208202803683370190505b509050835b8363ffffffff168163ffffffff1611610b6257610b248161139e565b82610b2f8784611f7a565b63ffffffff1681518110610b4557610b45611fbb565b602090810291909101015280610b5a81611fea565b915050610b08565b509392505050565b600080610b7683610f5f565b151595945050505050565b610b8961145c565b610b9360006114c3565b565b610b9d611c62565b610ba5611c62565b6040517f3c251db100000000000000000000000000000000000000000000000000000000815260cc600482015264ffffffffff841660248201526014604482015260009073__$LazyIMT$__90633c251db190606401600060405180830381865af4158015610c25573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c6b919081019061200d565b905060005b601460ff82161015610cbb57818160ff1681518110610c9157610c91611fbb565b6020026020010151838260ff1660148110610cae57610cae611fbb565b6020020152600101610c70565b50909392505050565b600054610100900460ff1615808015610ce45750600054600160ff909116105b80610cfe5750303b158015610cfe575060005460ff166001145b610d705760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610628565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610dce57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610dd661153a565b610dde6115bf565b60c9805463ffffffff8481167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009092169190911766100000000000001790915560cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000016439092169190911790556040517f61136cec00000000000000000000000000000000000000000000000000000000815260cc60048201526014602482015273__$LazyIMT$__906361136cec9060440160006040518083038186803b158015610eb957600080fd5b505af4158015610ecd573d6000803e3d6000fd5b505060c980547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690555050801561091557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600081815260ca6020908152604080832081518083019092525463ffffffff808216808452640100000000909204169282019290925282918291908203610fb157600080600093509350935050610fc9565b80516020820151610fc18161139e565b935093509350505b9193909250565b6000808263ffffffff1611801561057b57505060c95463ffffffff9081169116111590565b81610fff8161054b565b611038576040517f7f3e75af00000000000000000000000000000000000000000000000000000000815260048101829052602401610628565b8161104281610fd0565b611080576040517f6677a0c700000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610628565b61108a848461163c565b50505050565b6040517f39ebe6e300000000000000000000000000000000000000000000000000000000815260cc60048201526014602482015260009073__$LazyIMT$__906339ebe6e390604401602060405180830381865af4158015611103573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112791906120b3565b905090565b61113461145c565b73ffffffffffffffffffffffffffffffffffffffff81166111bd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610628565b610754816114c3565b61075461145c565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156112065761120183611911565b505050565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561128b575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611288918101906120b3565b60015b6112fd5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152608401610628565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81146113925760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c655555494400000000000000000000000000000000000000000000006064820152608401610628565b50611201838383611a01565b6040517f0c26d68300000000000000000000000000000000000000000000000000000000815260006004820181905263ffffffff831660248301529060cd90829073__$LazyIMT$__90630c26d68390604401602060405180830381865af415801561141b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143f91906120cc565b64ffffffffff168152602001908152602001600020549050919050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610b935760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610628565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166115b75760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610628565b610b93611a26565b600054610100900460ff16610b935760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610628565b61164582610b6a565b1561167b576040517e0a60f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c95463ffffffff640100000000820481166801000000000000000090920416106116d2576040517f57f6953100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825283815263ffffffff8316602082015290517f561558fe00000000000000000000000000000000000000000000000000000000815260009173__$PoseidonT3$__9163561558fe9161173a916004016120e9565b602060405180830381865af4158015611757573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177b91906120b3565b60408051808201825263ffffffff858116825260c95468010000000000000000900416602082015290517f0224ef5e00000000000000000000000000000000000000000000000000000000815260cc6004820152602481018390529192509073__$LazyIMT$__90630224ef5e9060440160006040518083038186803b15801561181157600080fd5b505af4158015611825573d6000803e3d6000fd5b505050600085815260ca6020908152604091829020845181548684015163ffffffff908116640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909216928116929092171790915560c954835187815268010000000000000000909104909116918101919091527fb84da12e8207adb5ee3e5686338302ffe6634fbb95a9fd52f8a466ea2010152d92500160405180910390a1600160c960088282829054906101000a900463ffffffff166118ed9190611f9e565b92506101000a81548163ffffffff021916908363ffffffff16021790555050505050565b73ffffffffffffffffffffffffffffffffffffffff81163b61199b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610628565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b611a0a83611aac565b600082511180611a175750805b156112015761108a8383611af9565b600054610100900460ff16611aa35760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610628565b610b93336114c3565b611ab581611911565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060611b1e83836040518060600160405280602781526020016121a360279139611b25565b9392505050565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051611b4f9190612135565b600060405180830381855af49150503d8060008114611b8a576040519150601f19603f3d011682016040523d82523d6000602084013e611b8f565b606091505b5091509150611ba086838387611baa565b9695505050505050565b60608315611c26578251600003611c1f5773ffffffffffffffffffffffffffffffffffffffff85163b611c1f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610628565b5081611c30565b611c308383611c38565b949350505050565b815115611c485781518083602001fd5b8060405162461bcd60e51b81526004016106289190612151565b6040518061028001604052806014906020820280368337509192915050565b600060208284031215611c9357600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cbe57600080fd5b919050565b600060208284031215611cd557600080fd5b611b1e82611c9a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d5457611d54611cde565b604052919050565b60008060408385031215611d6f57600080fd5b611d7883611c9a565b915060208084013567ffffffffffffffff80821115611d9657600080fd5b818601915086601f830112611daa57600080fd5b813581811115611dbc57611dbc611cde565b611dec847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611d0d565b91508082528784828501011115611e0257600080fd5b80848401858401376000848284010152508093505050509250929050565b803563ffffffff81168114611cbe57600080fd5b60008060408385031215611e4757600080fd5b611e5083611e20565b9150611e5e60208401611e20565b90509250929050565b6020808252825182820181905260009190848201906040850190845b81811015611e9f57835183529284019291840191600101611e83565b50909695505050505050565b64ffffffffff8116811461075457600080fd5b600060208284031215611ed057600080fd5b8135611b1e81611eab565b6102808101818360005b6014811015611f04578151835260209283019290910190600101611ee5565b50505092915050565b600060208284031215611f1f57600080fd5b611b1e82611e20565b60008060408385031215611f3b57600080fd5b82359150611e5e60208401611e20565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff828116828216039080821115611f9757611f97611f4b565b5092915050565b63ffffffff818116838216019080821115611f9757611f97611f4b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff80831681810361200357612003611f4b565b6001019392505050565b6000602080838503121561202057600080fd5b825167ffffffffffffffff8082111561203857600080fd5b818501915085601f83011261204c57600080fd5b81518181111561205e5761205e611cde565b8060051b915061206f848301611d0d565b818152918301840191848101908884111561208957600080fd5b938501935b838510156120a75784518252938501939085019061208e565b98975050505050505050565b6000602082840312156120c557600080fd5b5051919050565b6000602082840312156120de57600080fd5b8151611b1e81611eab565b60408101818360005b6002811015611f045781518352602092830192909101906001016120f2565b60005b8381101561212c578181015183820152602001612114565b50506000910152565b60008251612147818460208701612111565b9190910192915050565b6020815260008251806020840152612170816040850160208701612111565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564" diff --git a/waku/waku_rln_relay/group_manager/group_manager_base.nim b/waku/waku_rln_relay/group_manager/group_manager_base.nim index 7b2c651766..97aaec0998 100644 --- a/waku/waku_rln_relay/group_manager/group_manager_base.nim +++ b/waku/waku_rln_relay/group_manager/group_manager_base.nim @@ -15,7 +15,7 @@ export options, chronos, results, protocol_types, protocol_metrics, deques type Membership* = object index*: MembershipIndex - rateCommitment*: RateCommitment + rateCommitment*: RawRateCommitment type OnRegisterCallback* = proc(registrations: seq[Membership]): Future[void] {.gcsafe.} type OnWithdrawCallback* = proc(withdrawals: seq[Membership]): Future[void] {.gcsafe.} @@ -73,7 +73,7 @@ method register*( # The user may or may not have the identity secret to these commitments # It should be used when detecting a batch of new members in the group, and syncing the group state method registerBatch*( - g: GroupManager, rateCommitments: seq[RateCommitment] + g: GroupManager, rateCommitments: seq[RawRateCommitment] ): Future[void] {.base, async: (raises: [Exception]).} = raise newException( CatchableError, "registerBatch proc for " & $g.type & " is not implemented yet" diff --git a/waku/waku_rln_relay/group_manager/on_chain/group_manager.nim b/waku/waku_rln_relay/group_manager/on_chain/group_manager.nim index ff93b58cb3..a83ae9bb34 100644 --- a/waku/waku_rln_relay/group_manager/on_chain/group_manager.nim +++ b/waku/waku_rln_relay/group_manager/on_chain/group_manager.nim @@ -31,50 +31,34 @@ logScope: topics = "waku rln_relay onchain_group_manager" # using the when predicate does not work within the contract macro, hence need to dupe -contract(WakuRlnRegistry): - # this describes the storage slot to use - proc usingStorageIndex(): Uint16 {.pure.} - # this map contains the address of a given storage slot - proc storages(index: Uint16): Address {.pure.} - # this serves as an entrypoint into the rln storage contract +contract(WakuRlnContract): + # this serves as an entrypoint into the rln membership set proc register( - storageIndex: Uint16, idCommitment: Uint256, userMessageLimit: Uint256 + idCommitment: UInt256, userMessageLimit: UInt32 ) - - # this creates a new storage on the rln registry - proc newStorage(maxMessageLimit: Uint256) # Initializes the implementation contract (only used in unit tests) - proc initialize() - -# membership contract interface -contract(RlnStorage): + proc initialize(maxMessageLimit: UInt256) # this event is raised when a new member is registered proc MemberRegistered( - idCommitment: Uint256, userMessageLimit: Uint256, index: Uint256 + rateCommitment: UInt256, index: Uint32 ) {.event.} - # this constant contains the membership deposit of the contract - proc MEMBERSHIP_DEPOSIT(): Uint256 {.pure.} - # this map denotes existence of a given user - proc memberExists(idCommitment: Uint256): Uint256 {.view.} + # this function denotes existence of a given user + proc memberExists(idCommitment: Uint256): UInt256 {.view.} # this constant describes the next index of a new member - proc idCommitmentIndex(): Uint256 {.view.} + proc commitmentIndex(): UInt256 {.view.} # this constant describes the block number this contract was deployed on - proc deployedBlockNumber(): Uint256 {.view.} + proc deployedBlockNumber(): UInt256 {.view.} type - RegistryContractWithSender = Sender[WakuRlnRegistry] - RlnContractWithSender = Sender[RlnStorage] + WakuRlnContractWithSender = Sender[WakuRlnContract] OnchainGroupManager* = ref object of GroupManager ethClientUrl*: string ethPrivateKey*: Option[string] ethContractAddress*: string ethRpc*: Option[Web3] - rlnContract*: Option[RlnContractWithSender] rlnContractDeployedBlockNumber*: BlockNumber - registryContract*: Option[RegistryContractWithSender] - usingStorageIndex: Option[Uint16] - membershipFee*: Option[Uint256] + wakuRlnContract*: Option[WakuRlnContractWithSender] latestProcessedBlock*: BlockNumber registrationTxHash*: Option[TxHash] chainId*: Option[Quantity] @@ -136,20 +120,14 @@ proc setMetadata*( method atomicBatch*( g: OnchainGroupManager, start: MembershipIndex, - rateCommitments = newSeq[RateCommitment](), + rateCommitments = newSeq[RawRateCommitment](), toRemoveIndices = newSeq[MembershipIndex](), ): Future[void] {.async: (raises: [Exception]), base.} = initializedGuard(g) - # convert the rateCommitment struct to a leaf value - let leaves = rateCommitments.toLeaves().valueOr: - raise newException( - ValueError, "failed to convert rateCommitments to leaves: " & $error - ) - waku_rln_membership_insertion_duration_seconds.nanosecondTime: let operationSuccess = - g.rlnInstance.atomicWrite(some(start), leaves, toRemoveIndices) + g.rlnInstance.atomicWrite(some(start), rateCommitments, toRemoveIndices) if not operationSuccess: raise newException(CatchableError, "atomic batch operation failed") # TODO: when slashing is enabled, we need to track slashed members @@ -159,7 +137,7 @@ method atomicBatch*( var membersSeq = newSeq[Membership]() for i in 0 ..< rateCommitments.len: var index = start + MembershipIndex(i) - trace "registering member", rateCommitment = rateCommitments[i], index = index + debug "registering member to callback", rateCommitment = rateCommitments[i], index = index let member = Membership(rateCommitment: rateCommitments[i], index: index) membersSeq.add(member) await g.registerCb.get()(membersSeq) @@ -171,10 +149,15 @@ method register*( ): Future[void] {.async: (raises: [Exception]).} = initializedGuard(g) - await g.registerBatch(@[rateCommitment]) + try: + let leaf = rateCommitment.toLeaf().get() + await g.registerBatch(@[leaf]) + except CatchableError: + raise newException(ValueError, getCurrentExceptionMsg()) + method registerBatch*( - g: OnchainGroupManager, rateCommitments: seq[RateCommitment] + g: OnchainGroupManager, rateCommitments: seq[RawRateCommitment] ): Future[void] {.async: (raises: [Exception]).} = initializedGuard(g) @@ -189,23 +172,20 @@ method register*( initializedGuard(g) let ethRpc = g.ethRpc.get() - let registryContract = g.registryContract.get() - let membershipFee = g.membershipFee.get() + let wakuRlnContract = g.wakuRlnContract.get() var gasPrice: int g.retryWrapper(gasPrice, "Failed to get gas price"): int(await ethRpc.provider.eth_gasPrice()) * 2 let idCommitment = identityCredential.idCommitment.toUInt256() - let storageIndex = g.usingStorageIndex.get() debug "registering the member", idCommitment = idCommitment, - storageIndex = storageIndex, userMessageLimit = userMessageLimit var txHash: TxHash g.retryWrapper(txHash, "Failed to register the member"): - await registryContract - .register(storageIndex, idCommitment, u256(userMessageLimit)) + await wakuRlnContract + .register(idCommitment, userMessageLimit.stuint(32)) .send(gasPrice = gasPrice) # wait for the transaction to be mined @@ -216,23 +196,24 @@ method register*( g.registrationTxHash = some(txHash) # the receipt topic holds the hash of signature of the raised events # TODO: make this robust. search within the event list for the event + debug "ts receipt", tsReceipt let firstTopic = tsReceipt.logs[0].topics[0] - # the hash of the signature of MemberRegistered(uint256,uint256,uint256) event is equal to the following hex value + # the hash of the signature of MemberRegistered(uint256,uint32) event is equal to the following hex value if firstTopic != cast[FixedBytes[32]](keccak256.digest( - "MemberRegistered(uint256,uint256,uint256)" + "MemberRegistered(uint256,uint32)" ).data): raise newException(ValueError, "unexpected event signature") # the arguments of the raised event i.e., MemberRegistered are encoded inside the data field - # data = pk encoded as 256 bits || index encoded as 256 bits || userMessageLimit encoded as 256 bits + # data = rateCommitment encoded as 256 bits || index encoded as 32 bits let arguments = tsReceipt.logs[0].data debug "tx log data", arguments = arguments let - argumentsBytes = arguments # In TX log data, uints are encoded in big endian - membershipIndex = UInt256.fromBytesBE(argumentsBytes[64 ..^ 1]) + membershipIndex = UInt256.fromBytesBE(arguments[32 ..^ 1]) + debug "parsed membershipIndex", membershipIndex g.userMessageLimit = some(userMessageLimit) g.membershipIndex = some(membershipIndex.toMembershipIndex()) @@ -257,9 +238,8 @@ proc parseEvent( ): GroupManagerResult[Membership] = ## parses the `data` parameter of the `MemberRegistered` event `log` ## returns an error if it cannot parse the `data` parameter - var idComm: UInt256 + var rateCommitment: UInt256 var index: UInt256 - var userMessageLimit: UInt256 var data: string # Remove the 0x prefix try: @@ -271,18 +251,13 @@ proc parseEvent( ) var offset = 0 try: - # Parse the idComm - offset += decode(data, offset, idComm) - # Parse the userMessageLimit - offset += decode(data, offset, userMessageLimit) + # Parse the rateCommitment + offset += decode(data, offset, rateCommitment) # Parse the index offset += decode(data, offset, index) return ok( Membership( - rateCommitment: RateCommitment( - idCommitment: idComm.toIDCommitment(), - userMessageLimit: userMessageLimit.toUserMessageLimit(), - ), + rateCommitment: rateCommitment.toRateCommitment(), index: index.toMembershipIndex(), ) ) @@ -324,11 +299,11 @@ proc getRawEvents( initializedGuard(g) let ethRpc = g.ethRpc.get() - let rlnContract = g.rlnContract.get() + let wakuRlnContract = g.wakuRlnContract.get() var events: JsonNode g.retryWrapper(events, "Failed to get the events"): - await rlnContract.getJsonLogs( + await wakuRlnContract.getJsonLogs( MemberRegistered, fromBlock = some(fromBlock.blockId()), toBlock = some(toBlock.blockId()), @@ -376,7 +351,7 @@ proc handleEvents( toRemoveIndices = removalIndices, ) g.latestIndex = startIndex + MembershipIndex(rateCommitments.len) - trace "new members added to the Merkle tree", commitments = rateCommitments + trace "new members added to the Merkle tree", commitments = rateCommitments.mapIt(it.inHex) except CatchableError: error "failed to insert members into the tree", error = getCurrentExceptionMsg() @@ -579,23 +554,11 @@ method init*(g: OnchainGroupManager): Future[GroupManagerResult[void]] {.async.} ethRpc.defaultAccount = ethRpc.privateKey.get().toPublicKey().toCanonicalAddress().Address - let registryAddress = web3.fromHex(web3.Address, g.ethContractAddress) - let registryContract = ethRpc.contractSender(WakuRlnRegistry, registryAddress) - - # get the current storage index - var usingStorageIndex: Uint16 - g.retryWrapper(usingStorageIndex, "Failed to get the storage index"): - await registryContract.usingStorageIndex().call() - - g.usingStorageIndex = some(usingStorageIndex) - var rlnContractAddress: Address - g.retryWrapper(rlnContractAddress, "Failed to get the rln contract address"): - await registryContract.storages(usingStorageIndex).call() - let rlnContract = ethRpc.contractSender(RlnStorage, rlnContractAddress) - + let contractAddress = web3.fromHex(web3.Address, g.ethContractAddress) + let wakuRlnContract = ethRpc.contractSender(WakuRlnContract, contractAddress) + g.ethRpc = some(ethRpc) - g.rlnContract = some(rlnContract) - g.registryContract = some(registryContract) + g.wakuRlnContract = some(wakuRlnContract) if g.keystorePath.isSome() and g.keystorePassword.isSome(): if not fileExists(g.keystorePath.get()): @@ -621,7 +584,7 @@ method init*(g: OnchainGroupManager): Future[GroupManagerResult[void]] {.async.} g.userMessageLimit = some(keystoreCred.userMessageLimit) # now we check on the contract if the commitment actually has a membership try: - let membershipExists = await rlnContract + let membershipExists = await wakuRlnContract .memberExists(keystoreCred.identityCredential.idCommitment.toUInt256()) .call() if membershipExists == 0: @@ -644,16 +607,10 @@ method init*(g: OnchainGroupManager): Future[GroupManagerResult[void]] {.async.} g.latestProcessedBlock = metadata.lastProcessedBlock g.validRoots = metadata.validRoots.toDeque() - # check if the contract exists by calling a static function - var membershipFee: Uint256 - g.retryWrapper(membershipFee, "Failed to get the membership deposit"): - await rlnContract.MEMBERSHIP_DEPOSIT().call() - g.membershipFee = some(membershipFee) - var deployedBlockNumber: Uint256 g.retryWrapper(deployedBlockNumber, "Failed to get the deployed block number"): - await rlnContract.deployedBlockNumber().call() - debug "using rln storage", deployedBlockNumber, rlnContractAddress + await wakuRlnContract.deployedBlockNumber().call() + debug "using rln contract", deployedBlockNumber, rlnContractAddress = contractAddress g.rlnContractDeployedBlockNumber = cast[BlockNumber](deployedBlockNumber) g.latestProcessedBlock = max(g.latestProcessedBlock, g.rlnContractDeployedBlockNumber) diff --git a/waku/waku_rln_relay/group_manager/static/group_manager.nim b/waku/waku_rln_relay/group_manager/static/group_manager.nim index 877124af4f..e8590325c9 100644 --- a/waku/waku_rln_relay/group_manager/static/group_manager.nim +++ b/waku/waku_rln_relay/group_manager/static/group_manager.nim @@ -66,20 +66,17 @@ method register*( ): Future[void] {.async: (raises: [Exception]).} = initializedGuard(g) - await g.registerBatch(@[rateCommitment]) + let leaf = rateCommitment.toLeaf().get() + + await g.registerBatch(@[leaf]) method registerBatch*( - g: StaticGroupManager, rateCommitments: seq[RateCommitment] + g: StaticGroupManager, rateCommitments: seq[RawRateCommitment] ): Future[void] {.async: (raises: [Exception]).} = initializedGuard(g) - let leavesRes = rateCommitments.toLeaves() - if not leavesRes.isOk(): - raise newException(ValueError, "Failed to convert rate commitments to leaves") - let leaves = cast[seq[seq[byte]]](leavesRes.get()) - - let membersInserted = g.rlnInstance.insertMembers(g.latestIndex + 1, leaves) + let membersInserted = g.rlnInstance.insertMembers(g.latestIndex + 1, rateCommitments) if not membersInserted: raise newException(ValueError, "Failed to insert members into the merkle tree") @@ -112,7 +109,8 @@ method withdraw*( let index = MembershipIndex(i) let rateCommitment = RateCommitment( idCommitment: idCommitment, userMessageLimit: g.userMessageLimit.get() - ) + ).toLeaf().valueOr: + raise newException(ValueError, "Failed to parse rateCommitment") let memberRemoved = g.rlnInstance.removeMember(index) if not memberRemoved: raise newException(ValueError, "Failed to remove member from the merkle tree") diff --git a/waku/waku_rln_relay/protocol_types.nim b/waku/waku_rln_relay/protocol_types.nim index c0224bacae..7fa392247f 100644 --- a/waku/waku_rln_relay/protocol_types.nim +++ b/waku/waku_rln_relay/protocol_types.nim @@ -3,7 +3,7 @@ when (NimMajor, NimMinor) < (1, 4): else: {.push raises: [].} -import std/[options, tables, deques], stew/arrayops, chronos, web3, eth/keys +import std/[options, tables, deques], stew/arrayops, stint, chronos, web3, eth/keys import ../waku_core, ../waku_keystore, ../common/protobuf export waku_keystore, waku_core @@ -16,7 +16,7 @@ type RLNResult* = RlnRelayResult[ptr RLN] type MerkleNode* = array[32, byte] - # Each node of the Merkle tee is a Poseidon hash which is a 32 byte value + # Each node of the Merkle tree is a Poseidon hash which is a 32 byte value Nullifier* = array[32, byte] Epoch* = array[32, byte] RlnIdentifier* = array[32, byte] @@ -26,6 +26,10 @@ type RateCommitment* = object idCommitment*: IDCommitment userMessageLimit*: UserMessageLimit + RawRateCommitment* = seq[byte] + +proc toRateCommitment*(rateCommitmentUint: UInt256): RawRateCommitment = + return RawRateCommitment(@(rateCommitmentUint.toBytesLE())) # Custom data types defined for waku rln relay ------------------------- type RateLimitProof* = object