2022.12.02 11:38 [3407988] smart account 3PKpsc1TNquw4HAF62pWK8ka1DBz9vyEBkt > SELF 0.00000000 Waves

{ "type": 13, "id": "G1aBFYzozkdmu4ZkQ1EssN594NX4Bsa64NYD6VvRU4ZW", "fee": 3200000, "feeAssetId": null, "timestamp": 1669970231534, "version": 1, "sender": "3PKpsc1TNquw4HAF62pWK8ka1DBz9vyEBkt", "senderPublicKey": "8ZLAVkwG8sZ97hmBdGRkQpYTp5En9xgEYX4PeupqxpFw", "proofs": [ "89848CQw88YKcP4tnkjKo9mJhtFWpCcoxFfURnsLNqZ6KVBHenn9ymJ5AUdu6PrDFEBLLA5T8QveGrFV3khL6oA" ], "script": "base64:BgIoCAISCQoHAQEBAQEIARIAEgQKAggIEgQKAggIEgQKAggIEgMKAQgSAEMBD2dldFN0cmluZ09yRmFpbAEDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQUDa2V5CQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQNrZXkCDyBpcyBub3QgZGVmaW5lZAADU0VQAgJfXwAIQlVGU0NBTEUJALYCAQCAgJC7utat8A0ABnNjYWxlOACAwtcvAQh0aHJvd0VycgEDbXNnCQACAQkAuQkCCQDMCAICCWlkby5yaWRlOgkAzAgCBQNtc2cFA25pbAIBIAEIYXNTdHJpbmcBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACBlN0cmluZwQGdmFsU3RyBQckbWF0Y2gwBQZ2YWxTdHIJAAIBAhhmYWlsIHRvIGNhc3QgaW50byBTdHJpbmcBHWNvbnZlcnRQcmljZUFzc2V0SW50b0lkb0Fzc2V0BRBwcmljZUFzc2V0QW1vdW50DnByaWNlQXNzZXRNVUxUBXByaWNlCXByaWNlTVVMVAxpZG9Bc3NldE1VTFQED2JQcmljZUFzc2V0TVVMVAkAtgIBBQ5wcmljZUFzc2V0TVVMVAQNYklkb0Fzc2V0TVVMVAkAtgIBBQxpZG9Bc3NldE1VTFQEDmJQcmljZUFzc2V0QlVGCQC8AgMJALYCAQUQcHJpY2VBc3NldEFtb3VudAUIQlVGU0NBTEUFD2JQcmljZUFzc2V0TVVMVAQPYkFtb3VudEFzc2V0QlVGCQC8AgMFDmJQcmljZUFzc2V0QlVGCQC2AgEFCXByaWNlTVVMVAkAtgIBBQVwcmljZQkAoAMBCQC8AgMFD2JBbW91bnRBc3NldEJVRgkAtgIBBQxpZG9Bc3NldE1VTFQFCEJVRlNDQUxFAA5JZHhDZmdJZG9TdGFydAABABFJZHhDZmdJZG9EdXJhdGlvbgACABBJZHhDZmdDbGFpbVN0YXJ0AAMAE0lkeENmZ0NsYWltRHVyYXRpb24ABAALSWR4Q2ZnUHJpY2UABQAPSWR4Q2ZnUHJpY2VNdWx0AAYAEElkeENmZ0lkb0Fzc2V0SWQABwASSWR4Q2ZnSWRvQXNzZXRNdWx0AAgAEklkeENmZ1ByaWNlQXNzZXRJZAAJABRJZHhDZmdQcmljZUFzc2V0TXVsdAAKABVJZHhDZmdNaW5JbnZlc3RBbW91bnQACwENZnJvbWF0Q29uZmlnUwwIaWRvU3RhcnQLaWRvRHVyYXRpb24KY2xhaW1TdGFydA1jbGFpbUR1cmF0aW9uBXByaWNlCXByaWNlTXVsdAxpZG9Bc3NldElkNTgMaWRvQXNzZXRNdWx0DnByaWNlQXNzZXRJZDU4DnByaWNlQXNzZXRNdWx0D21pbkludmVzdEFtb3VudBN0b3RhbElkb0Fzc2V0VG9TZWxsCQC5CQIJAMwIAgIYJWQlZCVkJWQlZCVkJXMlZCVzJWQlZCVkCQDMCAIFCGlkb1N0YXJ0CQDMCAIFC2lkb0R1cmF0aW9uCQDMCAIFCmNsYWltU3RhcnQJAMwIAgUNY2xhaW1EdXJhdGlvbgkAzAgCBQVwcmljZQkAzAgCBQlwcmljZU11bHQJAMwIAgUMaWRvQXNzZXRJZDU4CQDMCAIFDGlkb0Fzc2V0TXVsdAkAzAgCBQ5wcmljZUFzc2V0SWQ1OAkAzAgCBQ5wcmljZUFzc2V0TXVsdAkAzAgCBQ9taW5JbnZlc3RBbW91bnQJAMwIAgUTdG90YWxJZG9Bc3NldFRvU2VsbAUDbmlsBQNTRVABDGZyb21hdENvbmZpZwwIaWRvU3RhcnQLaWRvRHVyYXRpb24KY2xhaW1TdGFydA1jbGFpbUR1cmF0aW9uBXByaWNlCXByaWNlTXVsdAxpZG9Bc3NldElkNTgMaWRvQXNzZXRNdWx0DnByaWNlQXNzZXRJZDU4DnByaWNlQXNzZXRNdWx0D21pbkludmVzdEFtb3VudBN0b3RhbElkb0Fzc2V0VG9TZWxsCQENZnJvbWF0Q29uZmlnUwwJAKQDAQUIaWRvU3RhcnQJAKQDAQULaWRvRHVyYXRpb24JAKQDAQUKY2xhaW1TdGFydAkApAMBBQ1jbGFpbUR1cmF0aW9uCQCkAwEFBXByaWNlCQCkAwEFCXByaWNlTXVsdAUMaWRvQXNzZXRJZDU4CQCkAwEFDGlkb0Fzc2V0TXVsdAUOcHJpY2VBc3NldElkNTgJAKQDAQUOcHJpY2VBc3NldE11bHQJAKQDAQUPbWluSW52ZXN0QW1vdW50CQCkAwEFE3RvdGFsSWRvQXNzZXRUb1NlbGwAEUlkeEludlRvdGFsQW1vdW50AAEAFUlkeEludlJlbWFpbmluZ0Ftb3VudAACAB1JZHhJbnZDbGFpbWVkUHJpY2VBc3NldEFtb3VudAADABtJZHhJbnZDbGFpbWVkSWRvQXNzZXRBbW91bnQABAAXSWR4SW52TGFzdENsYWltZWRIZWlnaHQABQEPZm9ybWF0SW52ZXN0b3JTBQt0b3RhbEFtb3VudA9yZW1haW5pbmdBbW91bnQXY2xhaW1lZFByaWNlQXNzZXRBbW91bnQVY2xhaW1lZElkb0Fzc2V0QW1vdW50EWxhc3RDbGFpbWVkSGVpZ2h0CQC5CQIJAMwIAgIKJWQlZCVkJWQlZAkAzAgCBQt0b3RhbEFtb3VudAkAzAgCBQ9yZW1haW5pbmdBbW91bnQJAMwIAgUXY2xhaW1lZFByaWNlQXNzZXRBbW91bnQJAMwIAgUVY2xhaW1lZElkb0Fzc2V0QW1vdW50CQDMCAIFEWxhc3RDbGFpbWVkSGVpZ2h0BQNuaWwFA1NFUAEOZm9ybWF0SW52ZXN0b3IFC3RvdGFsQW1vdW50D3JlbWFpbmluZ0Ftb3VudBdjbGFpbWVkUHJpY2VBc3NldEFtb3VudBVjbGFpbWVkSWRvQXNzZXRBbW91bnQRbGFzdENsYWltZWRIZWlnaHQJAQ9mb3JtYXRJbnZlc3RvclMFCQCkAwEFC3RvdGFsQW1vdW50CQCkAwEFD3JlbWFpbmluZ0Ftb3VudAkApAMBBRdjbGFpbWVkUHJpY2VBc3NldEFtb3VudAkApAMBBRVjbGFpbWVkSWRvQXNzZXRBbW91bnQJAKQDAQURbGFzdENsYWltZWRIZWlnaHQBE2Zvcm1hdEhpc3RvcnlSZWNvcmQCEHByaWNlQXNzZXRBbW91bnQOaWRvQXNzZXRBbW91bnQJALkJAgkAzAgCAgglZCVkJWQlZAkAzAgCCQCkAwEFBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAKQDAQUQcHJpY2VBc3NldEFtb3VudAkAzAgCCQCkAwEFDmlkb0Fzc2V0QW1vdW50BQNuaWwFA1NFUAEJa2V5Q29uZmlnAAIKJXNfX2NvbmZpZwELa2V5SW52ZXN0b3IBC3VzZXJBZGRyZXNzCQCsAgICBCVzX18FC3VzZXJBZGRyZXNzAQlrZXlUb3RhbHMAAgolc19fdG90YWxzARlrZXlPcGVyYXRpb25IaXN0b3J5UmVjb3JkAwR0eXBlC3VzZXJBZGRyZXNzBnR4SWQ1OAkAuQkCCQDMCAICESVzJXMlcyVzX19oaXN0b3J5CQDMCAIFBHR5cGUJAMwIAgULdXNlckFkZHJlc3MJAMwIAgUGdHhJZDU4BQNuaWwFA1NFUAEUa2V5VVNETkNsYWltRGlzYWJsZWQAAhUlc19fdXNkbkNsYWltRGlzYWJsZWQBFWtleVVTRE5DbGFpbUVuZEhlaWdodAACFiVzX191c2RuQ2xhaW1FbmRIZWlnaHQBD2tleVBlcmlvZExlbmd0aAAJALkJAgkAzAgCAgIlcwkAzAgCAgxwZXJpb2RMZW5ndGgFA25pbAUDU0VQARBrZXlDdXJyZW50UGVyaW9kAAkAuQkCCQDMCAICAiVzCQDMCAICDWN1cnJlbnRQZXJpb2QFA25pbAUDU0VQARRrZXlQZXJpb2RTdGFydEhlaWdodAEJcGVyaW9kTnVtCQC5CQIJAMwIAgIEJXMlcwkAzAgCAhFwZXJpb2RTdGFydEhlaWdodAkAzAgCCQCkAwEFCXBlcmlvZE51bQUDbmlsBQNTRVABEmtleVBlcmlvZEVuZEhlaWdodAEJcGVyaW9kTnVtCQC5CQIJAMwIAgIEJXMlcwkAzAgCAg9wZXJpb2RFbmRIZWlnaHQJAMwIAgkApAMBBQlwZXJpb2ROdW0FA25pbAUDU0VQAR9rZXlVc2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvAAkAuQkCCQDMCAICAiVzCQDMCAICHHVzZHRQcmljZUFzc2V0QWxsb3dhYmxlUmF0aW8FA25pbAUDU0VQARdrZXlUb3RhbFBlcmlvZEFsbG93YW5jZQEHYXNzZXRJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgIUdG90YWxQZXJpb2RBbGxvd2FuY2UJAMwIAgUHYXNzZXRJZAUDbmlsBQNTRVABFmtleVVzZXJQZXJpb2RBbGxvd2FuY2UBB2Fzc2V0SWQJALkJAgkAzAgCAgQlcyVzCQDMCAICE3VzZXJQZXJpb2RBbGxvd2FuY2UJAMwIAgUHYXNzZXRJZAUDbmlsBQNTRVABHmtleVBlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQIHYXNzZXRJZAlwZXJpb2ROdW0JALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIbcGVyaW9kVG90YWxBdmFpbGFibGVUb0NsYWltCQDMCAIFB2Fzc2V0SWQJAMwIAgkApAMBBQlwZXJpb2ROdW0FA25pbAUDU0VQAR1rZXlQZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQMHYXNzZXRJZAlwZXJpb2ROdW0LdXNlckFkZHJlc3MJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCAhpwZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQkAzAgCBQdhc3NldElkCQDMCAIJAKQDAQUJcGVyaW9kTnVtCQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAEba2V5VXNkdFByaWNlQXNzZXRTdGFibGVQb29sAAkAuQkCCQDMCAICAiVzCQDMCAICGHVzZHRQcmljZUFzc2V0U3RhYmxlUG9vbAUDbmlsBQNTRVABDmtleVVzZHRBc3NldElkAAkAuQkCCQDMCAICAiVzCQDMCAICC3VzZHRBc3NldElkBQNuaWwFA1NFUAEUa2V5UHJpY2VBc3NldEJhbGFuY2UBB2FkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAICEXByaWNlQXNzZXRCYWxhbmNlCQDMCAIFB2FkZHJlc3MFA25pbAUDU0VQARprZXlJbnZlc3RvclJlbWFpbmluZ0Ftb3VudAEHYWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIXaW52ZXN0b3JSZW1haW5pbmdBbW91bnQJAMwIAgUHYWRkcmVzcwUDbmlsBQNTRVABF2tleVRvdGFsUmVtYWluaW5nQW1vdW50AAkAuQkCCQDMCAICAiVzCQDMCAICFHRvdGFsUmVtYWluaW5nQW1vdW50BQNuaWwFA1NFUAETa2V5TWFuYWdlclB1YmxpY0tleQACFCVzX19tYW5hZ2VyUHVibGljS2V5ARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQEPcmVhZENvbmZpZ0FycmF5AAkAtQkCCQEPZ2V0U3RyaW5nT3JGYWlsAQkBCWtleUNvbmZpZwAFA1NFUAEjcmVhZFRvdGFsc0FycmF5T3JEZWZhdWx0QnlDdXN0b21LZXkBCWN1c3RvbUtleQkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEFCWN1c3RvbUtleQkBD2Zvcm1hdEludmVzdG9yUwUCATACATACATACATACATAFA1NFUAEYcmVhZFRvdGFsc0FycmF5T3JEZWZhdWx0AAkBI3JlYWRUb3RhbHNBcnJheU9yRGVmYXVsdEJ5Q3VzdG9tS2V5AQkBCWtleVRvdGFscwABGnJlYWRJbnZlc3RvckFycmF5T3JEZWZhdWx0AQt1c2VyQWRkcmVzcwkBI3JlYWRUb3RhbHNBcnJheU9yRGVmYXVsdEJ5Q3VzdG9tS2V5AQkBC2tleUludmVzdG9yAQULdXNlckFkZHJlc3MBF3JlYWRJbnZlc3RvckFycmF5T3JGYWlsAQt1c2VyQWRkcmVzcwkAtQkCCQEPZ2V0U3RyaW5nT3JGYWlsAQkBC2tleUludmVzdG9yAQULdXNlckFkZHJlc3MFA1NFUAAVSWR4RGlmZlRvdGFsSW5jcmVtZW50AAAAJElkeERpZmZSZW1haW5pbmdQcmljZUFtb3VudEluY3JlbWVudAABACJJZHhEaWZmQ2xhaW1lZFByaWNlQW1vdW50SW5jcmVtZW50AAIAJUlkeERpZmZDbGFpbWVkSWRvQXNzZXRBbW91bnRJbmNyZW1lbnQAAwELVG90YWxzRW50cnkFA2tleQlvcmlnQXJyYXkNaW5jcmVtZW50RGlmZhRuZXdMYXN0Q2xhaW1lZEhlaWdodBFwcmljZUFzc2V0QmFsYW5jZQQLdG90YWxBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlvcmlnQXJyYXkFEUlkeEludlRvdGFsQW1vdW50BA9yZW1haW5pbmdBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlvcmlnQXJyYXkFFUlkeEludlJlbWFpbmluZ0Ftb3VudAQXY2xhaW1lZFByaWNlQXNzZXRBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlvcmlnQXJyYXkFHUlkeEludkNsYWltZWRQcmljZUFzc2V0QW1vdW50BBVjbGFpbWVkSWRvQXNzZXRBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlvcmlnQXJyYXkFG0lkeEludkNsYWltZWRJZG9Bc3NldEFtb3VudAQRbGFzdENsYWltZWRIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlvcmlnQXJyYXkFF0lkeEludkxhc3RDbGFpbWVkSGVpZ2h0BA5uZXdUb3RhbEFtb3VudAkAZAIFC3RvdGFsQW1vdW50CQCRAwIFDWluY3JlbWVudERpZmYFFUlkeERpZmZUb3RhbEluY3JlbWVudAQSbmV3UmVtYWluaW5nQW1vdW50CQBkAgUPcmVtYWluaW5nQW1vdW50CQCRAwIFDWluY3JlbWVudERpZmYFJElkeERpZmZSZW1haW5pbmdQcmljZUFtb3VudEluY3JlbWVudAQIY2ZnQXJyYXkJAQ9yZWFkQ29uZmlnQXJyYXkABA5wcmljZUFzc2V0SWQ1OAkAkQMCBQhjZmdBcnJheQUSSWR4Q2ZnUHJpY2VBc3NldElkBBJwcmljZUFzc2V0RGVjaW1hbHMICQEFdmFsdWUBCQDsBwEJANkEAQUOcHJpY2VBc3NldElkNTgIZGVjaW1hbHMEI3ByaWNlQXNzZXRCYWxhbmNlUHJpY2VBc3NldERlY2ltYWxzCQBrAwURcHJpY2VBc3NldEJhbGFuY2UFBnNjYWxlOAkAbAYACgAABRJwcmljZUFzc2V0RGVjaW1hbHMAAAAABQRET1dOBBpuZXdDbGFpbWVkUHJpY2VBc3NldEFtb3VudAkAZQIJAGQCBRdjbGFpbWVkUHJpY2VBc3NldEFtb3VudAkAkQMCBQ1pbmNyZW1lbnREaWZmBSJJZHhEaWZmQ2xhaW1lZFByaWNlQW1vdW50SW5jcmVtZW50BRFwcmljZUFzc2V0QmFsYW5jZQQYbmV3Q2xhaW1lZElkb0Fzc2V0QW1vdW50CQBkAgkAZAIFFWNsYWltZWRJZG9Bc3NldEFtb3VudAkAkQMCBQ1pbmNyZW1lbnREaWZmBSVJZHhEaWZmQ2xhaW1lZElkb0Fzc2V0QW1vdW50SW5jcmVtZW50BSNwcmljZUFzc2V0QmFsYW5jZVByaWNlQXNzZXREZWNpbWFscwQHZW50cmllcwMJAGYCAAAFEm5ld1JlbWFpbmluZ0Ftb3VudAQEZGlmZgkAZQIJAGUCBQ5uZXdUb3RhbEFtb3VudAUabmV3Q2xhaW1lZFByaWNlQXNzZXRBbW91bnQFGG5ld0NsYWltZWRJZG9Bc3NldEFtb3VudAQXbmV3TG9naWNSZW1haW5pbmdBbW91bnQDCQBmAgAABQRkaWZmAAAFBGRpZmYJAQtTdHJpbmdFbnRyeQIFA2tleQkBDmZvcm1hdEludmVzdG9yBQUObmV3VG90YWxBbW91bnQFF25ld0xvZ2ljUmVtYWluaW5nQW1vdW50BRpuZXdDbGFpbWVkUHJpY2VBc3NldEFtb3VudAUYbmV3Q2xhaW1lZElkb0Fzc2V0QW1vdW50BRRuZXdMYXN0Q2xhaW1lZEhlaWdodAkBC1N0cmluZ0VudHJ5AgUDa2V5CQEOZm9ybWF0SW52ZXN0b3IFBQ5uZXdUb3RhbEFtb3VudAUSbmV3UmVtYWluaW5nQW1vdW50BRpuZXdDbGFpbWVkUHJpY2VBc3NldEFtb3VudAUYbmV3Q2xhaW1lZElkb0Fzc2V0QW1vdW50BRRuZXdMYXN0Q2xhaW1lZEhlaWdodAUHZW50cmllcwEbSW52ZXN0T3BlcmF0aW9uSGlzdG9yeUVudHJ5BAt1c2VyQWRkcmVzcxBwcmljZUFzc2V0QW1vdW50Dmlkb0Fzc2V0QW1vdW50BHR4SWQJAQtTdHJpbmdFbnRyeQIJARlrZXlPcGVyYXRpb25IaXN0b3J5UmVjb3JkAwIGaW52ZXN0BQt1c2VyQWRkcmVzcwkA2AQBBQR0eElkCQETZm9ybWF0SGlzdG9yeVJlY29yZAIFEHByaWNlQXNzZXRBbW91bnQFDmlkb0Fzc2V0QW1vdW50ARpDbGFpbU9wZXJhdGlvbkhpc3RvcnlFbnRyeQQLdXNlckFkZHJlc3MQcHJpY2VBc3NldEFtb3VudA5pZG9Bc3NldEFtb3VudAR0eElkCQELU3RyaW5nRW50cnkCCQEZa2V5T3BlcmF0aW9uSGlzdG9yeVJlY29yZAMCBWNsYWltBQt1c2VyQWRkcmVzcwkA2AQBBQR0eElkCQETZm9ybWF0SGlzdG9yeVJlY29yZAIFEHByaWNlQXNzZXRBbW91bnQFDmlkb0Fzc2V0QW1vdW50AQ1pbnRlcm5hbENsYWltAxBjbGFpbWVkQXNzZXRJZDU4C3VzZXJBZGRyZXNzBHR4SWQECGNmZ0FycmF5CQEPcmVhZENvbmZpZ0FycmF5AAQKY2xhaW1TdGFydAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRBJZHhDZmdDbGFpbVN0YXJ0BA1jbGFpbUR1cmF0aW9uCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFE0lkeENmZ0NsYWltRHVyYXRpb24ECGNsYWltRW5kCQBkAgUKY2xhaW1TdGFydAUNY2xhaW1EdXJhdGlvbgQFcHJpY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQULSWR4Q2ZnUHJpY2UECXByaWNlTXVsdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BQ9JZHhDZmdQcmljZU11bHQEDGlkb0Fzc2V0SWQ1OAkAkQMCBQhjZmdBcnJheQUQSWR4Q2ZnSWRvQXNzZXRJZAQKaWRvQXNzZXRJZAkA2QQBBQxpZG9Bc3NldElkNTgEDGlkb0Fzc2V0TXVsdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRJJZHhDZmdJZG9Bc3NldE11bHQEDnByaWNlQXNzZXRJZDU4CQCRAwIFCGNmZ0FycmF5BRJJZHhDZmdQcmljZUFzc2V0SWQEDHByaWNlQXNzZXRJZAkA2QQBBQ5wcmljZUFzc2V0SWQ1OAQOcHJpY2VBc3NldE11bHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUUSWR4Q2ZnUHJpY2VBc3NldE11bHQEDXVzZXJBZGRyZXNzNTgJAKUIAQULdXNlckFkZHJlc3MED29yaWdJbnZlc3RBcnJheQkBF3JlYWRJbnZlc3RvckFycmF5T3JGYWlsAQUNdXNlckFkZHJlc3M1OAQRaW52ZXN0VG90YWxBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ9vcmlnSW52ZXN0QXJyYXkFEUlkeEludlRvdGFsQW1vdW50BBppbnZlc3RMYXN0Q2xhaW1lZEhlaWdodFRNUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD29yaWdJbnZlc3RBcnJheQUXSWR4SW52TGFzdENsYWltZWRIZWlnaHQEF2ludmVzdExhc3RDbGFpbWVkSGVpZ2h0AwkAZwIFCmNsYWltU3RhcnQFGmludmVzdExhc3RDbGFpbWVkSGVpZ2h0VE1QBQpjbGFpbVN0YXJ0BRppbnZlc3RMYXN0Q2xhaW1lZEhlaWdodFRNUAQUbmV3Q2xhaW1QZXJpb2RIZWlnaHQDCQBmAgUGaGVpZ2h0BQhjbGFpbUVuZAUIY2xhaW1FbmQDCQBmAgUKY2xhaW1TdGFydAUGaGVpZ2h0BQpjbGFpbVN0YXJ0BQZoZWlnaHQEDmNsYWltaW5nQmxvY2tzCQBlAgUUbmV3Q2xhaW1QZXJpb2RIZWlnaHQFF2ludmVzdExhc3RDbGFpbWVkSGVpZ2h0BBhjbGFpbWluZ1ByaWNlQXNzZXRBbW91bnQJAGsDBRFpbnZlc3RUb3RhbEFtb3VudAUOY2xhaW1pbmdCbG9ja3MFDWNsYWltRHVyYXRpb24EFmNsYWltaW5nSWRvQXNzZXRBbW91bnQJAR1jb252ZXJ0UHJpY2VBc3NldEludG9JZG9Bc3NldAUFGGNsYWltaW5nUHJpY2VBc3NldEFtb3VudAUOcHJpY2VBc3NldE11bHQFBXByaWNlBQlwcmljZU11bHQFDGlkb0Fzc2V0TXVsdAQGaXNVU0ROCQAAAgUQY2xhaW1lZEFzc2V0SWQ1OAUOcHJpY2VBc3NldElkNTgEE2lzVVNETkNsYWltRGlzYWJsZWQJAQt2YWx1ZU9yRWxzZQIJAKAIAQkBFGtleVVTRE5DbGFpbURpc2FibGVkAAcEBmNoZWNrcwkAzAgCAwkBASEBAwUGaXNVU0ROBRNpc1VTRE5DbGFpbURpc2FibGVkBwYJAAIBAhZVU0ROIGNsYWltIGlzIGRpc2FibGVkBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MDCQAAAgUQY2xhaW1lZEFzc2V0SWQ1OAUOcHJpY2VBc3NldElkNTgJAJgKBgkAzAgCAAAJAMwIAgkBAS0BBRhjbGFpbWluZ1ByaWNlQXNzZXRBbW91bnQJAMwIAgUYY2xhaW1pbmdQcmljZUFzc2V0QW1vdW50CQDMCAIAAAUDbmlsBRhjbGFpbWluZ1ByaWNlQXNzZXRBbW91bnQFDHByaWNlQXNzZXRJZAUPb3JpZ0ludmVzdEFycmF5BRRuZXdDbGFpbVBlcmlvZEhlaWdodAkAzAgCBRhjbGFpbWluZ1ByaWNlQXNzZXRBbW91bnQJAMwIAgUWY2xhaW1pbmdJZG9Bc3NldEFtb3VudAUDbmlsAwkAAAIFEGNsYWltZWRBc3NldElkNTgFDGlkb0Fzc2V0SWQ1OAkAmAoGCQDMCAIAAAkAzAgCCQEBLQEFGGNsYWltaW5nUHJpY2VBc3NldEFtb3VudAkAzAgCAAAJAMwIAgUWY2xhaW1pbmdJZG9Bc3NldEFtb3VudAUDbmlsBRZjbGFpbWluZ0lkb0Fzc2V0QW1vdW50BQppZG9Bc3NldElkBQ9vcmlnSW52ZXN0QXJyYXkFFG5ld0NsYWltUGVyaW9kSGVpZ2h0CQDMCAIFGGNsYWltaW5nUHJpY2VBc3NldEFtb3VudAkAzAgCBRZjbGFpbWluZ0lkb0Fzc2V0QW1vdW50BQNuaWwJAAIBCQCsAgICFXVuc3VwcG9ydGVkIGFzc2V0SWQ6IAUQY2xhaW1lZEFzc2V0SWQ1OAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEPaW50ZXJuYWxDbGFpbVYyBA5wcmljZUFzc2V0SWQ1OA11c2VyQWRkcmVzczU4CW91dEFtb3VudBl0b3RhbFVzZXJBdmFpbGFibGVUb0NsYWltBB50b3RhbFBlcmlvZFByaWNlQXNzZXRBbGxvd2FuY2UJAQV2YWx1ZQEJAJ8IAQkBF2tleVRvdGFsUGVyaW9kQWxsb3dhbmNlAQUOcHJpY2VBc3NldElkNTgEHXVzZXJQZXJpb2RQcmljZUFzc2V0QWxsb3dhbmNlCQEFdmFsdWUBCQCfCAEJARZrZXlVc2VyUGVyaW9kQWxsb3dhbmNlAQUOcHJpY2VBc3NldElkNTgEDHBlcmlvZExlbmd0aAkBBXZhbHVlAQkAnwgBCQEPa2V5UGVyaW9kTGVuZ3RoAAQNY3VycmVudFBlcmlvZAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEQa2V5Q3VycmVudFBlcmlvZAAAAAQbemVyb1BlcmlvZEVuZEhlaWdoSXNEZWZpbmVkCQEJaXNEZWZpbmVkAQkAnwgBCQESa2V5UGVyaW9kRW5kSGVpZ2h0AQAABA0kdDAxMjk4NzE0ODU3AwkAZgIFDWN1cnJlbnRQZXJpb2QAAAQVbGFzdFBlcmlvZFN0YXJ0SGVpZ2h0CQEFdmFsdWUBCQCfCAEJARRrZXlQZXJpb2RTdGFydEhlaWdodAEFDWN1cnJlbnRQZXJpb2QEE2xhc3RQZXJpb2RFbmRIZWlnaHQJAQV2YWx1ZQEJAJ8IAQkBEmtleVBlcmlvZEVuZEhlaWdodAEFDWN1cnJlbnRQZXJpb2QEDSR0MDEzMjQ3MTM5NTIDCQBmAgUGaGVpZ2h0BRNsYXN0UGVyaW9kRW5kSGVpZ2h0BBR1cGRhdGVkQ3VycmVudFBlcmlvZAkAZAIFDWN1cnJlbnRQZXJpb2QAAQQLcGVyaW9kU3RhcnQDCQBmAgUGaGVpZ2h0CQBkAgUTbGFzdFBlcmlvZEVuZEhlaWdodAUMcGVyaW9kTGVuZ3RoBBdibG9ja3NUb0xhc3RQZXJpb2RTdGFydAkAagIJAGUCBQZoZWlnaHQFE2xhc3RQZXJpb2RFbmRIZWlnaHQFDHBlcmlvZExlbmd0aAMJAAACBRdibG9ja3NUb0xhc3RQZXJpb2RTdGFydAAACQBkAgkAZQIFBmhlaWdodAUMcGVyaW9kTGVuZ3RoAAEJAGUCBQZoZWlnaHQFF2Jsb2Nrc1RvTGFzdFBlcmlvZFN0YXJ0CQBkAgUTbGFzdFBlcmlvZEVuZEhlaWdodAABBAlwZXJpb2RFbmQJAGUCCQBkAgULcGVyaW9kU3RhcnQFDHBlcmlvZExlbmd0aAABCQCVCgMFFHVwZGF0ZWRDdXJyZW50UGVyaW9kBQtwZXJpb2RTdGFydAUJcGVyaW9kRW5kCQCVCgMFDWN1cnJlbnRQZXJpb2QFFWxhc3RQZXJpb2RTdGFydEhlaWdodAUTbGFzdFBlcmlvZEVuZEhlaWdodAQUdXBkYXRlZEN1cnJlbnRQZXJpb2QIBQ0kdDAxMzI0NzEzOTUyAl8xBAtwZXJpb2RTdGFydAgFDSR0MDEzMjQ3MTM5NTICXzIECXBlcmlvZEVuZAgFDSR0MDEzMjQ3MTM5NTICXzMJAJUKAwUUdXBkYXRlZEN1cnJlbnRQZXJpb2QFC3BlcmlvZFN0YXJ0BQlwZXJpb2RFbmQDBRt6ZXJvUGVyaW9kRW5kSGVpZ2hJc0RlZmluZWQEFXplcm9QZXJpb2RTdGFydEhlaWdodAkBBXZhbHVlAQkAnwgBCQEUa2V5UGVyaW9kU3RhcnRIZWlnaHQBAAAEE3plcm9QZXJpb2RFbmRIZWlnaHQJAQV2YWx1ZQEJAJ8IAQkBEmtleVBlcmlvZEVuZEhlaWdodAEAAAQNJHQwMTQyMDcxNDU4OQMJAGYCBQZoZWlnaHQFE3plcm9QZXJpb2RFbmRIZWlnaHQEFHVwZGF0ZWRDdXJyZW50UGVyaW9kCQBkAgUNY3VycmVudFBlcmlvZAABBAtwZXJpb2RTdGFydAkAZAIFE3plcm9QZXJpb2RFbmRIZWlnaHQAAQQJcGVyaW9kRW5kCQBlAgkAZAIFC3BlcmlvZFN0YXJ0BQxwZXJpb2RMZW5ndGgAAQkAlQoDBRR1cGRhdGVkQ3VycmVudFBlcmlvZAULcGVyaW9kU3RhcnQFCXBlcmlvZEVuZAkAlQoDBQ1jdXJyZW50UGVyaW9kBRV6ZXJvUGVyaW9kU3RhcnRIZWlnaHQFE3plcm9QZXJpb2RFbmRIZWlnaHQEFHVwZGF0ZWRDdXJyZW50UGVyaW9kCAUNJHQwMTQyMDcxNDU4OQJfMQQLcGVyaW9kU3RhcnQIBQ0kdDAxNDIwNzE0NTg5Al8yBAlwZXJpb2RFbmQIBQ0kdDAxNDIwNzE0NTg5Al8zCQCVCgMFFHVwZGF0ZWRDdXJyZW50UGVyaW9kBQtwZXJpb2RTdGFydAUJcGVyaW9kRW5kCQCVCgMFDWN1cnJlbnRQZXJpb2QJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFGtleVBlcmlvZFN0YXJ0SGVpZ2h0AQUNY3VycmVudFBlcmlvZAUGaGVpZ2h0CQELdmFsdWVPckVsc2UCCQCfCAEJARJrZXlQZXJpb2RFbmRIZWlnaHQBBQ1jdXJyZW50UGVyaW9kCQBlAgkAZAIFBmhlaWdodAUMcGVyaW9kTGVuZ3RoAAEEFHVwZGF0ZWRDdXJyZW50UGVyaW9kCAUNJHQwMTI5ODcxNDg1NwJfMQQLcGVyaW9kU3RhcnQIBQ0kdDAxMjk4NzE0ODU3Al8yBAlwZXJpb2RFbmQIBQ0kdDAxMjk4NzE0ODU3Al8zBBtwZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0JAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBHmtleVBlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQIFDnByaWNlQXNzZXRJZDU4BRR1cGRhdGVkQ3VycmVudFBlcmlvZAUedG90YWxQZXJpb2RQcmljZUFzc2V0QWxsb3dhbmNlBBpwZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEda2V5UGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0DBQ5wcmljZUFzc2V0SWQ1OAUUdXBkYXRlZEN1cnJlbnRQZXJpb2QFDXVzZXJBZGRyZXNzNTgFHXVzZXJQZXJpb2RQcmljZUFzc2V0QWxsb3dhbmNlBBFwcmljZUFzc2V0QmFsYW5jZQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEUa2V5UHJpY2VBc3NldEJhbGFuY2UBBQ11c2VyQWRkcmVzczU4AAAEGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0JAJcDAQkAzAgCCQBkAgUJb3V0QW1vdW50BRFwcmljZUFzc2V0QmFsYW5jZQkAzAgCBRtwZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0JAMwIAgUacGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0FA25pbAQcdXNkdFByaWNlQXNzZXRBbGxvd2FibGVSYXRpbwkBBXZhbHVlAQkAnwgBCQEfa2V5VXNkdFByaWNlQXNzZXRBbGxvd2FibGVSYXRpbwAEG3B1dE9uZVRrblYyUHJpY2VBc3NldEFtb3VudAUGc2NhbGU4BA0kdDAxNTYxMjE1ODY1CgABQAkA/AcECQERQGV4dHJOYXRpdmUoMTA2MikBCQEFdmFsdWUBCQCiCAEJARtrZXlVc2R0UHJpY2VBc3NldFN0YWJsZVBvb2wAAiFwdXRPbmVUa25WMldpdGhvdXRUYWtlRmVlUkVBRE9OTFkJAMwIAgUbcHV0T25lVGtuVjJQcmljZUFzc2V0QW1vdW50CQDMCAIFDnByaWNlQXNzZXRJZDU4BQNuaWwFA25pbAMJAAECBQFAAg8oSW50LCBJbnQsIEludCkFAUAJAAIBCQCsAgIJAAMBBQFAAiQgY291bGRuJ3QgYmUgY2FzdCB0byAoSW50LCBJbnQsIEludCkDCQAAAgUNJHQwMTU2MTIxNTg2NQUNJHQwMTU2MTIxNTg2NQQFYm9udXMIBQ0kdDAxNTYxMjE1ODY1Al8zBAlmZWVBbW91bnQIBQ0kdDAxNTYxMjE1ODY1Al8yBAhscEFtb3VudAgFDSR0MDE1NjEyMTU4NjUCXzEEC3VzZHRBc3NldElkCQEFdmFsdWUBCQCiCAEJAQ5rZXlVc2R0QXNzZXRJZAAEDSR0MDE1OTI3MTYxNDUKAAFACQD8BwQJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQV2YWx1ZQEJAKIIAQkBG2tleVVzZHRQcmljZUFzc2V0U3RhYmxlUG9vbAACE2dldE9uZVRrblYyUkVBRE9OTFkJAMwIAgULdXNkdEFzc2V0SWQJAMwIAgUIbHBBbW91bnQFA25pbAUDbmlsAwkAAQIFAUACCihJbnQsIEludCkFAUAJAAIBCQCsAgIJAAMBBQFAAh8gY291bGRuJ3QgYmUgY2FzdCB0byAoSW50LCBJbnQpAwkAAAIFDSR0MDE1OTI3MTYxNDUFDSR0MDE1OTI3MTYxNDUEFGdldE9uZVRrblYyRmVlQW1vdW50CAUNJHQwMTU5MjcxNjE0NQJfMgQKdXNkdEFtb3VudAgFDSR0MDE1OTI3MTYxNDUCXzEEGmN1cnJlbnRVc2R0UHJpY2VBc3NldFJhdGlvCQBrAwUbcHV0T25lVGtuVjJQcmljZUFzc2V0QW1vdW50BQZzY2FsZTgFCnVzZHRBbW91bnQEE2VuZFBlcmlvZEJsb2Nrc0xlZnQJAGUCBQlwZXJpb2RFbmQFBmhlaWdodAkAnAoKBRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltBRtwZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0FGnBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltBRl0b3RhbFVzZXJBdmFpbGFibGVUb0NsYWltBRx1c2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvBRpjdXJyZW50VXNkdFByaWNlQXNzZXRSYXRpbwUTZW5kUGVyaW9kQmxvY2tzTGVmdAUUdXBkYXRlZEN1cnJlbnRQZXJpb2QFC3BlcmlvZFN0YXJ0BQlwZXJpb2RFbmQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQABAckbWF0Y2gwCQCiCAEJARNrZXlNYW5hZ2VyUHVibGljS2V5AAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJANkEAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0AAQHJG1hdGNoMAkAoggBCQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgELbXVzdE1hbmFnZXIBAWkEAnBkCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEByRtYXRjaDAJARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAMJAAACCAUBaQ9jYWxsZXJQdWJsaWNLZXkFAnBrBgUCcGQDCQABAgUHJG1hdGNoMAIEVW5pdAMJAAACCAUBaQZjYWxsZXIFBHRoaXMGBQJwZAkAAgECC01hdGNoIGVycm9yBwFpAQtjb25zdHJ1Y3RvcgcIaWRvU3RhcnQLaWRvRHVyYXRpb24KY2xhaW1TdGFydA1jbGFpbUR1cmF0aW9uBXByaWNlDnByaWNlQXNzZXRJZDU4D21pbkludmVzdEFtb3VudAQJcHJpY2VNdWx0CQBoAgkAaAIAZADoBwDoBwQGaWRvRW5kCQBkAgUIaWRvU3RhcnQFC2lkb0R1cmF0aW9uAwkBCWlzRGVmaW5lZAEJAKIIAQkBCWtleUNvbmZpZwAJAAIBAhNhbHJlYWR5IGluaXRpYWxpemVkAwkBAiE9AgIjM1BNRUhMeDFqNnplcmFyWlRZZnNHcURlZVpxUW9NcHhxNVMJAKUIAQgFAWkGY2FsbGVyCQACAQIObm90IGF1dGhvcml6ZWQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkAwkAZwIFBmlkb0VuZAUKY2xhaW1TdGFydAkAAgECJmNsYWltU3RhcnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gaWRvRW5kBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAQKaWRvQXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkBAxpZG9Bc3NldEluZm8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQppZG9Bc3NldElkAhtmYWlsIHRvIGxvYWQgaWRvIGFzc2V0IGluZm8EDGlkb0Fzc2V0SWQ1OAkA2AQBBQppZG9Bc3NldElkBAxpZG9Bc3NldE11bHQJAGwGAAoAAAgFDGlkb0Fzc2V0SW5mbwhkZWNpbWFscwAAAAAFBERPV04EDHByaWNlQXNzZXRJZAkA2QQBBQ5wcmljZUFzc2V0SWQ1OAQOcHJpY2VBc3NldEluZm8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQxwcmljZUFzc2V0SWQCHWZhaWwgdG8gbG9hZCBwcmljZSBhc3NldCBpbmZvBA5wcmljZUFzc2V0TXVsdAkAbAYACgAACAUOcHJpY2VBc3NldEluZm8IZGVjaW1hbHMAAAAABQRET1dOBA9vcmlnVG90YWxzQXJyYXkJARhyZWFkVG90YWxzQXJyYXlPckRlZmF1bHQABAp0b3RhbHNEaWZmCQDMCAIAAAkAzAgCAAAJAMwIAgAACQDMCAIAAAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQlrZXlDb25maWcACQEMZnJvbWF0Q29uZmlnDAUIaWRvU3RhcnQFC2lkb0R1cmF0aW9uBQpjbGFpbVN0YXJ0BQ1jbGFpbUR1cmF0aW9uBQVwcmljZQUJcHJpY2VNdWx0BQxpZG9Bc3NldElkNTgFDGlkb0Fzc2V0TXVsdAUOcHJpY2VBc3NldElkNTgFDnByaWNlQXNzZXRNdWx0BQ9taW5JbnZlc3RBbW91bnQIBQNwbXQGYW1vdW50CQDMCAIJAQtUb3RhbHNFbnRyeQUJAQlrZXlUb3RhbHMABQ9vcmlnVG90YWxzQXJyYXkFCnRvdGFsc0RpZmYFCmNsYWltU3RhcnQAAAUDbmlsAWkBBmludmVzdAAECGNmZ0FycmF5CQEPcmVhZENvbmZpZ0FycmF5AAQIaWRvU3RhcnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUOSWR4Q2ZnSWRvU3RhcnQEC2lkb0R1cmF0aW9uCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFEUlkeENmZ0lkb0R1cmF0aW9uBAZpZG9FbmQJAGQCBQhpZG9TdGFydAULaWRvRHVyYXRpb24ECmNsYWltU3RhcnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUQSWR4Q2ZnQ2xhaW1TdGFydAQNY2xhaW1EdXJhdGlvbgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRNJZHhDZmdDbGFpbUR1cmF0aW9uBAVwcmljZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BQtJZHhDZmdQcmljZQQJcHJpY2VNdWx0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFD0lkeENmZ1ByaWNlTXVsdAQMaWRvQXNzZXRJZDU4CQCRAwIFCGNmZ0FycmF5BRBJZHhDZmdJZG9Bc3NldElkBAppZG9Bc3NldElkCQDZBAEFDGlkb0Fzc2V0SWQ1OAQMaWRvQXNzZXRNdWx0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ0lkb0Fzc2V0TXVsdAQOcHJpY2VBc3NldElkNTgJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ1ByaWNlQXNzZXRJZAQMcHJpY2VBc3NldElkCQDZBAEFDnByaWNlQXNzZXRJZDU4BA5wcmljZUFzc2V0TXVsdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRRJZHhDZmdQcmljZUFzc2V0TXVsdAQObWluSXZlc3RBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUVSWR4Q2ZnTWluSW52ZXN0QW1vdW50BAt1c2VyQWRkcmVzcwkApQgBCAUBaQZjYWxsZXIDCQBmAgUIaWRvU3RhcnQFBmhlaWdodAkAAgECHGlkbyBoYXMgbm90IGJlZW4gc3RhcnRlZCB5ZXQDCQBmAgUGaGVpZ2h0BQZpZG9FbmQJAAIBAhppZG8gaGFzIGJlZW4gYWxyZWFkeSBlbmRlZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHWV4YWN0bHkgMSBwYXltZW50IGlzIGV4cGVjdGVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAQKcG10QXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkBAlwbXRBbW91bnQIBQNwbXQGYW1vdW50AwkBAiE9AgUKcG10QXNzZXRJZAUMcHJpY2VBc3NldElkCQACAQkArAICCQCsAgICGmludmFsaWQgcGF5bWVudCBhc3NldCBpZDogCQDYBAEFCnBtdEFzc2V0SWQCDCBpcyBleHBlY3RlZAQRb3JpZ0ludmVzdG9yQXJyYXkJARpyZWFkSW52ZXN0b3JBcnJheU9yRGVmYXVsdAEFC3VzZXJBZGRyZXNzBA9vcmlnVG90YWxzQXJyYXkJARhyZWFkVG90YWxzQXJyYXlPckRlZmF1bHQABBNuZXdQcmljZVRvdGFsQW1vdW50CQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD29yaWdUb3RhbHNBcnJheQURSWR4SW52VG90YWxBbW91bnQFCXBtdEFtb3VudAQWcmVxdWlyZWRJZG9Bc3NldEFtb3VudAkAaAIFE25ld1ByaWNlVG90YWxBbW91bnQAZAMJAGYCBRZyZXF1aXJlZElkb0Fzc2V0QW1vdW50CQDwBwIFBHRoaXMFCmlkb0Fzc2V0SWQJAAIBAjlJRE8gYXNzZXQgaGFzIGJlZW4gLSBzb2xkIGNvbnNpZGVyIHRvIHVzZSBzbWFsbGVyIHBheW1lbnQECnRvdGFsc0RpZmYJAMwIAgUJcG10QW1vdW50CQDMCAIFCXBtdEFtb3VudAkAzAgCAAAJAMwIAgAABQNuaWwJAMwIAgkBC1RvdGFsc0VudHJ5BQkBC2tleUludmVzdG9yAQULdXNlckFkZHJlc3MFEW9yaWdJbnZlc3RvckFycmF5BQp0b3RhbHNEaWZmBQpjbGFpbVN0YXJ0AAAJAMwIAgkBC1RvdGFsc0VudHJ5BQkBCWtleVRvdGFscwAFD29yaWdUb3RhbHNBcnJheQUKdG90YWxzRGlmZgUKY2xhaW1TdGFydAAACQDMCAIJARtJbnZlc3RPcGVyYXRpb25IaXN0b3J5RW50cnkEBQt1c2VyQWRkcmVzcwUJcG10QW1vdW50AAAIBQFpDXRyYW5zYWN0aW9uSWQFA25pbAFpAQVjbGFpbQIQY2xhaW1lZEFzc2V0SWQ1OA11c2VyQWRkcmVzczU4BA9jYWxsZXJBZGRyZXNzNTgJAKUIAQgFAWkGY2FsbGVyAwkBAiE9AgUNdXNlckFkZHJlc3M1OAUPY2FsbGVyQWRkcmVzczU4CQACAQIObm90IGF1dGhvcml6ZWQECGNmZ0FycmF5CQEPcmVhZENvbmZpZ0FycmF5AAQOcHJpY2VBc3NldElkNTgJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ1ByaWNlQXNzZXRJZAQQY2xhaW1SZXN1bHRUdXBsZQkBDWludGVybmFsQ2xhaW0DBRBjbGFpbWVkQXNzZXRJZDU4CAUBaQZjYWxsZXIIBQFpDXRyYW5zYWN0aW9uSWQECnRvdGFsc0RpZmYIBRBjbGFpbVJlc3VsdFR1cGxlAl8xBAlvdXRBbW91bnQIBRBjbGFpbVJlc3VsdFR1cGxlAl8yBApvdXRBc3NldElkCAUQY2xhaW1SZXN1bHRUdXBsZQJfMwQPb3JpZ0ludmVzdEFycmF5CAUQY2xhaW1SZXN1bHRUdXBsZQJfNAQUbmV3Q2xhaW1QZXJpb2RIZWlnaHQIBRBjbGFpbVJlc3VsdFR1cGxlAl81BBpjbGFpbWVkUHJpY2VBbW91bnRGcm9tRGlmZgkAkQMCBQp0b3RhbHNEaWZmBSJJZHhEaWZmQ2xhaW1lZFByaWNlQW1vdW50SW5jcmVtZW50BB1jbGFpbWVkSWRvQXNzZXRBbW91bnRGcm9tRGlmZgkAkQMCBQp0b3RhbHNEaWZmBSVJZHhEaWZmQ2xhaW1lZElkb0Fzc2V0QW1vdW50SW5jcmVtZW50BBFwcmljZUFzc2V0QmFsYW5jZQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEUa2V5UHJpY2VBc3NldEJhbGFuY2UBBQ11c2VyQWRkcmVzczU4AAAEEnByaWNlQXNzZXREZWNpbWFscwgJAQV2YWx1ZQEJAOwHAQkA2QQBBQ5wcmljZUFzc2V0SWQ1OAhkZWNpbWFscwQHZW50cmllcwMJAAACBRBjbGFpbWVkQXNzZXRJZDU4BQ5wcmljZUFzc2V0SWQ1OAQNJHQwMjIwNTQyMjQ5OAkBD2ludGVybmFsQ2xhaW1WMgQFDnByaWNlQXNzZXRJZDU4BQ11c2VyQWRkcmVzczU4BQlvdXRBbW91bnQJAJEDAgUKdG90YWxzRGlmZgUiSWR4RGlmZkNsYWltZWRQcmljZUFtb3VudEluY3JlbWVudAQZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQgFDSR0MDIyMDU0MjI0OTgCXzEEG3BlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQgFDSR0MDIyMDU0MjI0OTgCXzIEGnBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltCAUNJHQwMjIwNTQyMjQ5OAJfMwQZdG90YWxVc2VyQXZhaWxhYmxlVG9DbGFpbQgFDSR0MDIyMDU0MjI0OTgCXzQEHHVzZHRQcmljZUFzc2V0QWxsb3dhYmxlUmF0aW8IBQ0kdDAyMjA1NDIyNDk4Al81BBpjdXJyZW50VXNkdFByaWNlQXNzZXRSYXRpbwgFDSR0MDIyMDU0MjI0OTgCXzYEE2VuZFBlcmlvZEJsb2Nrc0xlZnQIBQ0kdDAyMjA1NDIyNDk4Al83BBR1cGRhdGVkQ3VycmVudFBlcmlvZAgFDSR0MDIyMDU0MjI0OTgCXzgEC3BlcmlvZFN0YXJ0CAUNJHQwMjIwNTQyMjQ5OAJfOQQJcGVyaW9kRW5kCAUNJHQwMjIwNTQyMjQ5OANfMTAEBmNoZWNrcwkAzAgCAwkAZgIFGnBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltAAAGCQEIdGhyb3dFcnIBAjp1bmF2YWlsYWJsZSB0byBjbGFpbSBiZWNhdXNlIHVzZXIgcGVyaW9kIGFsbG93YW5jZSByZWFjaGVkCQDMCAIDCQBmAgUbcGVyaW9kVG90YWxBdmFpbGFibGVUb0NsYWltAAAGCQEIdGhyb3dFcnIBAjt1bmF2YWlsYWJsZSB0byBjbGFpbSBiZWNhdXNlIHRvdGFsIHBlcmlvZCBhbGxvd2FuY2UgcmVhY2hlZAkAzAgCAwkAZgIFGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0AAAYJAQh0aHJvd0VycgECEG5vdGhpbmcgdG8gY2xhaW0JAMwIAgMJAGYCBRx1c2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvBRpjdXJyZW50VXNkdFByaWNlQXNzZXRSYXRpbwYJAQh0aHJvd0VycgECT3VuYXZhaWxhYmxlIHRvIGNsYWltIGJlY2F1c2UgdXNkbiBwcmljZSBsb3dlciB0aGFuIHVzZHRQcmljZUFzc2V0QWxsb3dhYmxlUmF0aW8FA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQidXBkYXRlZFBlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQkAZQIFG3BlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQUZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQQhdXBkYXRlZFBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltCQBlAgUacGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0FGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0EB2VudHJpZXMDCQBmAgURcHJpY2VBc3NldEJhbGFuY2UFGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltBQpvdXRBc3NldElkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEUa2V5UHJpY2VBc3NldEJhbGFuY2UBBQ11c2VyQWRkcmVzczU4CQBlAgURcHJpY2VBc3NldEJhbGFuY2UFGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0FA25pbAQOZXZhbHVhdGVSZXN1bHQJALUJAgkBCGFzU3RyaW5nAQkA/AcEBQR0aGlzAg1jbGFpbVJFQURPTkxZCQDMCAIFDnByaWNlQXNzZXRJZDU4CQDMCAIFDXVzZXJBZGRyZXNzNTgFA25pbAUDbmlsBQNTRVADCQAAAgUOZXZhbHVhdGVSZXN1bHQFDmV2YWx1YXRlUmVzdWx0BBthdmFpbGFibGVQcmljZUFtb3VudFRvQ2xhaW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5ldmFsdWF0ZVJlc3VsdAADBBBsYXN0Q2xhaW1FbnRyaWVzAwkAAAIFG2F2YWlsYWJsZVByaWNlQW1vdW50VG9DbGFpbQUZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQQTaW52ZXN0b3JUb3RhbEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD29yaWdJbnZlc3RBcnJheQURSWR4SW52VG90YWxBbW91bnQEF2ludmVzdG9yUmVtYWluaW5nQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPb3JpZ0ludmVzdEFycmF5BRVJZHhJbnZSZW1haW5pbmdBbW91bnQEGWludmVzdG9yUHJpY2VBc3NldEJhbGFuY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ9vcmlnSW52ZXN0QXJyYXkFHUlkeEludkNsYWltZWRQcmljZUFzc2V0QW1vdW50BBdpbnZlc3Rvcklkb0Fzc2V0QmFsYW5jZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD29yaWdJbnZlc3RBcnJheQUbSWR4SW52Q2xhaW1lZElkb0Fzc2V0QW1vdW50BBlpbnZlc3Rvckxhc3RDbGFpbWVkSGVpZ2h0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPb3JpZ0ludmVzdEFycmF5BRdJZHhJbnZMYXN0Q2xhaW1lZEhlaWdodAQObmV3SW52ZXN0QXJyYXkJAMwIAgkApAMBBRNpbnZlc3RvclRvdGFsQW1vdW50CQDMCAICATAJAMwIAgkApAMBBRlpbnZlc3RvclByaWNlQXNzZXRCYWxhbmNlCQDMCAIJAKQDAQUXaW52ZXN0b3JJZG9Bc3NldEJhbGFuY2UJAMwIAgkApAMBBRlpbnZlc3Rvckxhc3RDbGFpbWVkSGVpZ2h0BQNuaWwEBnRvdGFscwkBGHJlYWRUb3RhbHNBcnJheU9yRGVmYXVsdAAEEXRvdGFsc1RvdGFsQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGdG90YWxzBRFJZHhJbnZUb3RhbEFtb3VudAQVdG90YWxzUmVtYWluaW5nQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGdG90YWxzBRVJZHhJbnZSZW1haW5pbmdBbW91bnQEHXRvdGFsc0NsYWltZWRQcmljZUFzc2V0QW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGdG90YWxzBRVJZHhJbnZSZW1haW5pbmdBbW91bnQEG3RvdGFsc0NsYWltZWRJZG9Bc3NldEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnRvdGFscwUdSWR4SW52Q2xhaW1lZFByaWNlQXNzZXRBbW91bnQEF3RvdGFsc0xhc3RDbGFpbWVkSGVpZ2h0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGdG90YWxzBRdJZHhJbnZMYXN0Q2xhaW1lZEhlaWdodAQYbmV3VG90YWxzUmVtYWluaW5nQW1vdW50CQBlAgUVdG90YWxzUmVtYWluaW5nQW1vdW50BRdpbnZlc3RvclJlbWFpbmluZ0Ftb3VudAQNbmV3VG90YWxBcnJheQkAzAgCCQCkAwEFEXRvdGFsc1RvdGFsQW1vdW50CQDMCAIJAKQDAQUYbmV3VG90YWxzUmVtYWluaW5nQW1vdW50CQDMCAIJAKQDAQUddG90YWxzQ2xhaW1lZFByaWNlQXNzZXRBbW91bnQJAMwIAgkApAMBBRt0b3RhbHNDbGFpbWVkSWRvQXNzZXRBbW91bnQJAMwIAgkApAMBBRd0b3RhbHNMYXN0Q2xhaW1lZEhlaWdodAUDbmlsBBduZXdUb3RhbFJlbWFpbmluZ0Ftb3VudAkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBF2tleVRvdGFsUmVtYWluaW5nQW1vdW50AAAABRdpbnZlc3RvclJlbWFpbmluZ0Ftb3VudAkAzAgCCQELU3RyaW5nRW50cnkCCQEaa2V5SW52ZXN0b3JSZW1haW5pbmdBbW91bnQBBQ11c2VyQWRkcmVzczU4CQCkAwEFF2ludmVzdG9yUmVtYWluaW5nQW1vdW50CQDMCAIJAQtTdHJpbmdFbnRyeQIJARdrZXlUb3RhbFJlbWFpbmluZ0Ftb3VudAAJAKQDAQUXbmV3VG90YWxSZW1haW5pbmdBbW91bnQJAMwIAgkBC1RvdGFsc0VudHJ5BQkBC2tleUludmVzdG9yAQUNdXNlckFkZHJlc3M1OAUObmV3SW52ZXN0QXJyYXkFCnRvdGFsc0RpZmYFFG5ld0NsYWltUGVyaW9kSGVpZ2h0AAAJAMwIAgkBC1RvdGFsc0VudHJ5BQkBCWtleVRvdGFscwAFDW5ld1RvdGFsQXJyYXkFCnRvdGFsc0RpZmYFFG5ld0NsYWltUGVyaW9kSGVpZ2h0AAAFA25pbAkAzAgCCQELVG90YWxzRW50cnkFCQELa2V5SW52ZXN0b3IBBQ11c2VyQWRkcmVzczU4BQ9vcmlnSW52ZXN0QXJyYXkFCnRvdGFsc0RpZmYFFG5ld0NsYWltUGVyaW9kSGVpZ2h0AAAJAMwIAgkBC1RvdGFsc0VudHJ5BQkBCWtleVRvdGFscwAJARhyZWFkVG90YWxzQXJyYXlPckRlZmF1bHQABQp0b3RhbHNEaWZmBRRuZXdDbGFpbVBlcmlvZEhlaWdodAAABQNuaWwEGHVwZGF0ZWRQcmljZUFzc2V0QmFsYW5jZQkAZQIJAGQCBRFwcmljZUFzc2V0QmFsYW5jZQUJb3V0QW1vdW50BRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltBQpvdXRBc3NldElkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEUa2V5UHJpY2VBc3NldEJhbGFuY2UBBQ11c2VyQWRkcmVzczU4BRh1cGRhdGVkUHJpY2VBc3NldEJhbGFuY2UFA25pbAUQbGFzdENsYWltRW50cmllcwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJARBrZXlDdXJyZW50UGVyaW9kAAUUdXBkYXRlZEN1cnJlbnRQZXJpb2QJAMwIAgkBDEludGVnZXJFbnRyeQIJARRrZXlQZXJpb2RTdGFydEhlaWdodAEFFHVwZGF0ZWRDdXJyZW50UGVyaW9kBQtwZXJpb2RTdGFydAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmtleVBlcmlvZEVuZEhlaWdodAEFFHVwZGF0ZWRDdXJyZW50UGVyaW9kBQlwZXJpb2RFbmQJAMwIAgkBDEludGVnZXJFbnRyeQIJAR5rZXlQZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0CBQ5wcmljZUFzc2V0SWQ1OAUUdXBkYXRlZEN1cnJlbnRQZXJpb2QFInVwZGF0ZWRQZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0JAMwIAgkBDEludGVnZXJFbnRyeQIJAR1rZXlQZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQMFDnByaWNlQXNzZXRJZDU4BRR1cGRhdGVkQ3VycmVudFBlcmlvZAUNdXNlckFkZHJlc3M1OAUhdXBkYXRlZFBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltCQDMCAIJARpDbGFpbU9wZXJhdGlvbkhpc3RvcnlFbnRyeQQFDXVzZXJBZGRyZXNzNTgFGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0FHWNsYWltZWRJZG9Bc3NldEFtb3VudEZyb21EaWZmCAUBaQ10cmFuc2FjdGlvbklkBQNuaWwFB2VudHJpZXMFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EHHByaWNlQXNzZXRCYWxhbmNlSWRvRGVjaW1hbHMJAGsDBRFwcmljZUFzc2V0QmFsYW5jZQUGc2NhbGU4CQBsBgAKAAAFEnByaWNlQXNzZXREZWNpbWFscwAAAAAFBERPV04JAJQKAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAGQCBQlvdXRBbW91bnQFHHByaWNlQXNzZXRCYWxhbmNlSWRvRGVjaW1hbHMFCm91dEFzc2V0SWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARRrZXlQcmljZUFzc2V0QmFsYW5jZQEFDXVzZXJBZGRyZXNzNTgAAAkAzAgCCQELVG90YWxzRW50cnkFCQELa2V5SW52ZXN0b3IBBQ11c2VyQWRkcmVzczU4BQ9vcmlnSW52ZXN0QXJyYXkFCnRvdGFsc0RpZmYFFG5ld0NsYWltUGVyaW9kSGVpZ2h0BRFwcmljZUFzc2V0QmFsYW5jZQkAzAgCCQELVG90YWxzRW50cnkFCQEJa2V5VG90YWxzAAkBGHJlYWRUb3RhbHNBcnJheU9yRGVmYXVsdAAFCnRvdGFsc0RpZmYFFG5ld0NsYWltUGVyaW9kSGVpZ2h0BRFwcmljZUFzc2V0QmFsYW5jZQkAzAgCCQEaQ2xhaW1PcGVyYXRpb25IaXN0b3J5RW50cnkEBQ11c2VyQWRkcmVzczU4BRpjbGFpbWVkUHJpY2VBbW91bnRGcm9tRGlmZgkAZAIFHWNsYWltZWRJZG9Bc3NldEFtb3VudEZyb21EaWZmBRxwcmljZUFzc2V0QmFsYW5jZUlkb0RlY2ltYWxzCAUBaQ10cmFuc2FjdGlvbklkBQNuaWwFBHVuaXQFB2VudHJpZXMBaQENY2xhaW1SRUFET05MWQIQY2xhaW1lZEFzc2V0SWQ1OA11c2VyQWRkcmVzczU4BBBjbGFpbVJlc3VsdFR1cGxlCQENaW50ZXJuYWxDbGFpbQMFEGNsYWltZWRBc3NldElkNTgJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDXVzZXJBZGRyZXNzNTgJANkEAQIABAp0b3RhbHNEaWZmCAUQY2xhaW1SZXN1bHRUdXBsZQJfMQQJb3V0QW1vdW50CAUQY2xhaW1SZXN1bHRUdXBsZQJfMgQKb3V0QXNzZXRJZAgFEGNsYWltUmVzdWx0VHVwbGUCXzMED29yaWdJbnZlc3RBcnJheQgFEGNsYWltUmVzdWx0VHVwbGUCXzQEFG5ld0NsYWltUGVyaW9kSGVpZ2h0CAUQY2xhaW1SZXN1bHRUdXBsZQJfNQQVYXZhaWxhYmxlVG9DbGFpbUFycmF5CAUQY2xhaW1SZXN1bHRUdXBsZQJfNgQbYXZhaWxhYmxlUHJpY2VBbW91bnRUb0NsYWltCQCRAwIFFWF2YWlsYWJsZVRvQ2xhaW1BcnJheQAABBlhdmFpbGFibGVJZG9BbW91bnRUb0NsYWltCQCRAwIFFWF2YWlsYWJsZVRvQ2xhaW1BcnJheQABCQCUCgIFA25pbAkAuQkCCQDMCAICBiVzJWQlZAkAzAgCBQ11c2VyQWRkcmVzczU4CQDMCAIJAKQDAQUbYXZhaWxhYmxlUHJpY2VBbW91bnRUb0NsYWltCQDMCAIJAKQDAQUZYXZhaWxhYmxlSWRvQW1vdW50VG9DbGFpbQUDbmlsBQNTRVABaQEPY2xhaW1WMlJFQURPTkxZAhBjbGFpbWVkQXNzZXRJZDU4DXVzZXJBZGRyZXNzNTgEEGNsYWltUmVzdWx0VHVwbGUJAQ1pbnRlcm5hbENsYWltAwUQY2xhaW1lZEFzc2V0SWQ1OAkBEUBleHRyTmF0aXZlKDEwNjIpAQUNdXNlckFkZHJlc3M1OAkA2QQBAgAECnRvdGFsc0RpZmYIBRBjbGFpbVJlc3VsdFR1cGxlAl8xBAlvdXRBbW91bnQIBRBjbGFpbVJlc3VsdFR1cGxlAl8yBApvdXRBc3NldElkCAUQY2xhaW1SZXN1bHRUdXBsZQJfMwQPb3JpZ0ludmVzdEFycmF5CAUQY2xhaW1SZXN1bHRUdXBsZQJfNAQUbmV3Q2xhaW1QZXJpb2RIZWlnaHQIBRBjbGFpbVJlc3VsdFR1cGxlAl81BBVhdmFpbGFibGVUb0NsYWltQXJyYXkIBRBjbGFpbVJlc3VsdFR1cGxlAl82BBthdmFpbGFibGVQcmljZUFtb3VudFRvQ2xhaW0JAJEDAgUVYXZhaWxhYmxlVG9DbGFpbUFycmF5AAAEGWF2YWlsYWJsZUlkb0Ftb3VudFRvQ2xhaW0JAJEDAgUVYXZhaWxhYmxlVG9DbGFpbUFycmF5AAEECGNmZ0FycmF5CQEPcmVhZENvbmZpZ0FycmF5AAQOcHJpY2VBc3NldElkNTgJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ1ByaWNlQXNzZXRJZAQRcHJpY2VBc3NldEJhbGFuY2UJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFGtleVByaWNlQXNzZXRCYWxhbmNlAQUNdXNlckFkZHJlc3M1OAAABBxwcmljZUFzc2V0QmFsYW5jZUlkb0RlY2ltYWxzCQBoAgURcHJpY2VBc3NldEJhbGFuY2UAZAQuYXZhaWxhYmxlSWRvQW1vdW50VG9DbGFpbVdpdGhQcmljZUFzc2V0QmFsYW5jZQkAZAIFGWF2YWlsYWJsZUlkb0Ftb3VudFRvQ2xhaW0FHHByaWNlQXNzZXRCYWxhbmNlSWRvRGVjaW1hbHMEDSR0MDMxMjgyMzE2OTQJAQ9pbnRlcm5hbENsYWltVjIEBQ5wcmljZUFzc2V0SWQ1OAUNdXNlckFkZHJlc3M1OAUJb3V0QW1vdW50CQCRAwIFCnRvdGFsc0RpZmYFIklkeERpZmZDbGFpbWVkUHJpY2VBbW91bnRJbmNyZW1lbnQEGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0IBQ0kdDAzMTI4MjMxNjk0Al8xBBtwZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0IBQ0kdDAzMTI4MjMxNjk0Al8yBBpwZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQgFDSR0MDMxMjgyMzE2OTQCXzMEGXRvdGFsVXNlckF2YWlsYWJsZVRvQ2xhaW0IBQ0kdDAzMTI4MjMxNjk0Al80BBx1c2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvCAUNJHQwMzEyODIzMTY5NAJfNQQaY3VycmVudFVzZHRQcmljZUFzc2V0UmF0aW8IBQ0kdDAzMTI4MjMxNjk0Al82BBNlbmRQZXJpb2RCbG9ja3NMZWZ0CAUNJHQwMzEyODIzMTY5NAJfNwQUdXBkYXRlZEN1cnJlbnRQZXJpb2QIBQ0kdDAzMTI4MjMxNjk0Al84BAtwZXJpb2RTdGFydAgFDSR0MDMxMjgyMzE2OTQCXzkECXBlcmlvZEVuZAgFDSR0MDMxMjgyMzE2OTQDXzEwBBZjdXJyZW50UGVyaW9kRW5kSGVpZ2h0CQELdmFsdWVPckVsc2UCCQCfCAEJARJrZXlQZXJpb2RFbmRIZWlnaHQBBRR1cGRhdGVkQ3VycmVudFBlcmlvZAAABBp1c2VyVG90YWxQcmljZUFzc2V0Q2xhaW1lZAkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQEXcmVhZEludmVzdG9yQXJyYXlPckZhaWwBBQ11c2VyQWRkcmVzczU4BR1JZHhJbnZDbGFpbWVkUHJpY2VBc3NldEFtb3VudAURcHJpY2VBc3NldEJhbGFuY2UEDHJlc3VsdFN0cmluZwMJAGYCBQZoZWlnaHQFFmN1cnJlbnRQZXJpb2RFbmRIZWlnaHQEDHBlcmlvZExlbmdodAkBBXZhbHVlAQkAnwgBCQEPa2V5UGVyaW9kTGVuZ3RoAAQTdXNlclBlcmlvZEFsbG93YW5jZQkBBXZhbHVlAQkAnwgBCQEWa2V5VXNlclBlcmlvZEFsbG93YW5jZQEFDnByaWNlQXNzZXRJZDU4BBR0b3RhbFBlcmlvZEFsbG93YW5jZQkBBXZhbHVlAQkAnwgBCQEXa2V5VG90YWxQZXJpb2RBbGxvd2FuY2UBBQ5wcmljZUFzc2V0SWQ1OAkAuQkCCQDMCAICDCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFLmF2YWlsYWJsZUlkb0Ftb3VudFRvQ2xhaW1XaXRoUHJpY2VBc3NldEJhbGFuY2UJAMwIAgkApAMBBRN1c2VyUGVyaW9kQWxsb3dhbmNlCQDMCAIJAKQDAQUUdG90YWxQZXJpb2RBbGxvd2FuY2UJAMwIAgkApAMBBRx1c2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvCQDMCAIJAKQDAQUaY3VycmVudFVzZHRQcmljZUFzc2V0UmF0aW8JAMwIAgkApAMBBQxwZXJpb2RMZW5naHQJAMwIAgkApAMBBRp1c2VyVG90YWxQcmljZUFzc2V0Q2xhaW1lZAUDbmlsBQNTRVAJALkJAgkAzAgCAgwlZCVkJWQlZCVkJWQJAMwIAgkApAMBBS5hdmFpbGFibGVJZG9BbW91bnRUb0NsYWltV2l0aFByaWNlQXNzZXRCYWxhbmNlCQDMCAIJAKQDAQUZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQkAzAgCCQCkAwEFG3BlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQkAzAgCCQCkAwEFHHVzZHRQcmljZUFzc2V0QWxsb3dhYmxlUmF0aW8JAMwIAgkApAMBBRpjdXJyZW50VXNkdFByaWNlQXNzZXRSYXRpbwkAzAgCCQCkAwEFE2VuZFBlcmlvZEJsb2Nrc0xlZnQJAMwIAgkApAMBBRp1c2VyVG90YWxQcmljZUFzc2V0Q2xhaW1lZAUDbmlsBQNTRVAJAJQKAgUDbmlsBQxyZXN1bHRTdHJpbmcBaQEKc2V0TWFuYWdlcgEXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkEC2NoZWNrQ2FsbGVyCQELbXVzdE1hbmFnZXIBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQDZBAEFF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AwkAAAIFFWNoZWNrTWFuYWdlclB1YmxpY0tleQUVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQDMCAIJAQtTdHJpbmdFbnRyeQIJARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQAFF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEOY29uZmlybU1hbmFnZXIABAJwbQkBHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0AAQFaGFzUE0DCQEJaXNEZWZpbmVkAQUCcG0GCQACAQISTm8gcGVuZGluZyBtYW5hZ2VyAwkAAAIFBWhhc1BNBQVoYXNQTQQHY2hlY2tQTQMJAAACCAUBaQ9jYWxsZXJQdWJsaWNLZXkJAQV2YWx1ZQEFAnBtBgkAAgECG1lvdSBhcmUgbm90IHBlbmRpbmcgbWFuYWdlcgMJAAACBQdjaGVja1BNBQdjaGVja1BNCQDMCAIJAQtTdHJpbmdFbnRyeQIJARNrZXlNYW5hZ2VyUHVibGljS2V5AAkA2AQBCQEFdmFsdWUBBQJwbQkAzAgCCQELRGVsZXRlRW50cnkBCQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAnR4AQZ2ZXJpZnkABA90YXJnZXRQdWJsaWNLZXkEByRtYXRjaDAJARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAUCcGsDCQABAgUHJG1hdGNoMAIEVW5pdAgFAnR4D3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQ90YXJnZXRQdWJsaWNLZXkNJgYa", "chainId": 87, "height": 3407988, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Fp8ScCKp7ofJxa1R5VsnVgrTnaDwdWxkpuAMB5vWWs7B Next: J6YGvoLyetNcouWxfyCCLrJy5mDjE9EnDLH7rWSRcLjU Diff:
OldNewDifferences
537537
538538
539539 @Callable(i)
540-func cleanRemaingAmount (userAddress58) = {
541- let priceAssetId58 = readConfigArray()[IdxCfgPriceAssetId]
542- let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
543- if ((evaluateResult == evaluateResult))
544- then {
545- let availablePriceAmountToClaim = parseIntValue(evaluateResult[2])
546- let checkUnclaimedAssets = if ((availablePriceAmountToClaim == 0))
547- then true
548- else throwErr("user have unclaimed assets")
549- if ((checkUnclaimedAssets == checkUnclaimedAssets))
550- then {
551- let investor = split(value(getString(keyInvestor(userAddress58))), SEP)
552- let investorTotalAmount = parseIntValue(investor[IdxInvTotalAmount])
553- let investorRemainingAmount = parseIntValue(investor[IdxInvRemainingAmount])
554- let investorPriceAssetBalance = parseIntValue(investor[IdxInvClaimedPriceAssetAmount])
555- let investorIdoAssetBalance = parseIntValue(investor[IdxInvClaimedIdoAssetAmount])
556- let investorLastClaimedHeight = parseIntValue(investor[IdxInvLastClaimedHeight])
557- let investorRemainingAmountCheck = if ((investorRemainingAmount != 0))
558- then true
559- else throwErr("investorRemainingAmount already zero")
560- if ((investorRemainingAmountCheck == investorRemainingAmountCheck))
561- then {
562- let newInvestor = makeString(["%d%d%d%d%d", toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)], SEP)
563- let totals = split(value(getString(keyTotals())), SEP)
564- let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
565- let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
566- let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
567- let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedIdoAssetAmount])
568- let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
569- let newTotals = makeString(["%d%d%d%d%d", toString(totalsTotalAmount), toString((totalsRemainingAmount - investorRemainingAmount)), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)], SEP)
570- let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
571-[StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), StringEntry(keyInvestor(userAddress58), newInvestor), StringEntry(keyTotals(), newTotals)]
572- }
573- else throw("Strict value is not equal to itself.")
574- }
575- else throw("Strict value is not equal to itself.")
576- }
577- else throw("Strict value is not equal to itself.")
578- }
579-
580-
581-
582-@Callable(i)
583540 func claimREADONLY (claimedAssetId58,userAddress58) = {
584541 let claimResultTuple = internalClaim(claimedAssetId58, addressFromStringValue(userAddress58), fromBase58String(""))
585542 let totalsDiff = claimResultTuple._1
611568 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
612569 let priceAssetBalanceIdoDecimals = (priceAssetBalance * 100)
613570 let availableIdoAmountToClaimWithPriceAssetBalance = (availableIdoAmountToClaim + priceAssetBalanceIdoDecimals)
614- let $t03374334155 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
615- let periodMinAvailableToClaim = $t03374334155._1
616- let periodTotalAvailableToClaim = $t03374334155._2
617- let periodUserAvailableToClaim = $t03374334155._3
618- let totalUserAvailableToClaim = $t03374334155._4
619- let usdtPriceAssetAllowableRatio = $t03374334155._5
620- let currentUsdtPriceAssetRatio = $t03374334155._6
621- let endPeriodBlocksLeft = $t03374334155._7
622- let updatedCurrentPeriod = $t03374334155._8
623- let periodStart = $t03374334155._9
624- let periodEnd = $t03374334155._10
571+ let $t03128231694 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
572+ let periodMinAvailableToClaim = $t03128231694._1
573+ let periodTotalAvailableToClaim = $t03128231694._2
574+ let periodUserAvailableToClaim = $t03128231694._3
575+ let totalUserAvailableToClaim = $t03128231694._4
576+ let usdtPriceAssetAllowableRatio = $t03128231694._5
577+ let currentUsdtPriceAssetRatio = $t03128231694._6
578+ let endPeriodBlocksLeft = $t03128231694._7
579+ let updatedCurrentPeriod = $t03128231694._8
580+ let periodStart = $t03128231694._9
581+ let periodEnd = $t03128231694._10
625582 let currentPeriodEndHeight = valueOrElse(getInteger(keyPeriodEndHeight(updatedCurrentPeriod)), 0)
626583 let userTotalPriceAssetClaimed = (parseIntValue(readInvestorArrayOrFail(userAddress58)[IdxInvClaimedPriceAssetAmount]) - priceAssetBalance)
627584 let resultString = if ((height > currentPeriodEndHeight))
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getStringOrFail (key) = valueOrErrorMessage(getString(key), (("mandatory this." + key) + " is not defined"))
55
66
77 let SEP = "__"
88
99 let BUFSCALE = toBigInt(1000000000000000000)
1010
1111 let scale8 = 100000000
1212
1313 func throwErr (msg) = throw(makeString(["ido.ride:", msg], " "))
1414
1515
1616 func asString (val) = match val {
1717 case valStr: String =>
1818 valStr
1919 case _ =>
2020 throw("fail to cast into String")
2121 }
2222
2323
2424 func convertPriceAssetIntoIdoAsset (priceAssetAmount,priceAssetMULT,price,priceMULT,idoAssetMULT) = {
2525 let bPriceAssetMULT = toBigInt(priceAssetMULT)
2626 let bIdoAssetMULT = toBigInt(idoAssetMULT)
2727 let bPriceAssetBUF = fraction(toBigInt(priceAssetAmount), BUFSCALE, bPriceAssetMULT)
2828 let bAmountAssetBUF = fraction(bPriceAssetBUF, toBigInt(priceMULT), toBigInt(price))
2929 toInt(fraction(bAmountAssetBUF, toBigInt(idoAssetMULT), BUFSCALE))
3030 }
3131
3232
3333 let IdxCfgIdoStart = 1
3434
3535 let IdxCfgIdoDuration = 2
3636
3737 let IdxCfgClaimStart = 3
3838
3939 let IdxCfgClaimDuration = 4
4040
4141 let IdxCfgPrice = 5
4242
4343 let IdxCfgPriceMult = 6
4444
4545 let IdxCfgIdoAssetId = 7
4646
4747 let IdxCfgIdoAssetMult = 8
4848
4949 let IdxCfgPriceAssetId = 9
5050
5151 let IdxCfgPriceAssetMult = 10
5252
5353 let IdxCfgMinInvestAmount = 11
5454
5555 func fromatConfigS (idoStart,idoDuration,claimStart,claimDuration,price,priceMult,idoAssetId58,idoAssetMult,priceAssetId58,priceAssetMult,minInvestAmount,totalIdoAssetToSell) = makeString(["%d%d%d%d%d%d%s%d%s%d%d%d", idoStart, idoDuration, claimStart, claimDuration, price, priceMult, idoAssetId58, idoAssetMult, priceAssetId58, priceAssetMult, minInvestAmount, totalIdoAssetToSell], SEP)
5656
5757
5858 func fromatConfig (idoStart,idoDuration,claimStart,claimDuration,price,priceMult,idoAssetId58,idoAssetMult,priceAssetId58,priceAssetMult,minInvestAmount,totalIdoAssetToSell) = fromatConfigS(toString(idoStart), toString(idoDuration), toString(claimStart), toString(claimDuration), toString(price), toString(priceMult), idoAssetId58, toString(idoAssetMult), priceAssetId58, toString(priceAssetMult), toString(minInvestAmount), toString(totalIdoAssetToSell))
5959
6060
6161 let IdxInvTotalAmount = 1
6262
6363 let IdxInvRemainingAmount = 2
6464
6565 let IdxInvClaimedPriceAssetAmount = 3
6666
6767 let IdxInvClaimedIdoAssetAmount = 4
6868
6969 let IdxInvLastClaimedHeight = 5
7070
7171 func formatInvestorS (totalAmount,remainingAmount,claimedPriceAssetAmount,claimedIdoAssetAmount,lastClaimedHeight) = makeString(["%d%d%d%d%d", totalAmount, remainingAmount, claimedPriceAssetAmount, claimedIdoAssetAmount, lastClaimedHeight], SEP)
7272
7373
7474 func formatInvestor (totalAmount,remainingAmount,claimedPriceAssetAmount,claimedIdoAssetAmount,lastClaimedHeight) = formatInvestorS(toString(totalAmount), toString(remainingAmount), toString(claimedPriceAssetAmount), toString(claimedIdoAssetAmount), toString(lastClaimedHeight))
7575
7676
7777 func formatHistoryRecord (priceAssetAmount,idoAssetAmount) = makeString(["%d%d%d%d", toString(height), toString(lastBlock.timestamp), toString(priceAssetAmount), toString(idoAssetAmount)], SEP)
7878
7979
8080 func keyConfig () = "%s__config"
8181
8282
8383 func keyInvestor (userAddress) = ("%s__" + userAddress)
8484
8585
8686 func keyTotals () = "%s__totals"
8787
8888
8989 func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
9090
9191
9292 func keyUSDNClaimDisabled () = "%s__usdnClaimDisabled"
9393
9494
9595 func keyUSDNClaimEndHeight () = "%s__usdnClaimEndHeight"
9696
9797
9898 func keyPeriodLength () = makeString(["%s", "periodLength"], SEP)
9999
100100
101101 func keyCurrentPeriod () = makeString(["%s", "currentPeriod"], SEP)
102102
103103
104104 func keyPeriodStartHeight (periodNum) = makeString(["%s%s", "periodStartHeight", toString(periodNum)], SEP)
105105
106106
107107 func keyPeriodEndHeight (periodNum) = makeString(["%s%s", "periodEndHeight", toString(periodNum)], SEP)
108108
109109
110110 func keyUsdtPriceAssetAllowableRatio () = makeString(["%s", "usdtPriceAssetAllowableRatio"], SEP)
111111
112112
113113 func keyTotalPeriodAllowance (assetId) = makeString(["%s%s", "totalPeriodAllowance", assetId], SEP)
114114
115115
116116 func keyUserPeriodAllowance (assetId) = makeString(["%s%s", "userPeriodAllowance", assetId], SEP)
117117
118118
119119 func keyPeriodTotalAvailableToClaim (assetId,periodNum) = makeString(["%s%s%s", "periodTotalAvailableToClaim", assetId, toString(periodNum)], SEP)
120120
121121
122122 func keyPeriodUserAvailableToClaim (assetId,periodNum,userAddress) = makeString(["%s%s%s%s", "periodUserAvailableToClaim", assetId, toString(periodNum), userAddress], SEP)
123123
124124
125125 func keyUsdtPriceAssetStablePool () = makeString(["%s", "usdtPriceAssetStablePool"], SEP)
126126
127127
128128 func keyUsdtAssetId () = makeString(["%s", "usdtAssetId"], SEP)
129129
130130
131131 func keyPriceAssetBalance (address) = makeString(["%s%s", "priceAssetBalance", address], SEP)
132132
133133
134134 func keyInvestorRemainingAmount (address) = makeString(["%s%s", "investorRemainingAmount", address], SEP)
135135
136136
137137 func keyTotalRemainingAmount () = makeString(["%s", "totalRemainingAmount"], SEP)
138138
139139
140140 func keyManagerPublicKey () = "%s__managerPublicKey"
141141
142142
143143 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
144144
145145
146146 func readConfigArray () = split(getStringOrFail(keyConfig()), SEP)
147147
148148
149149 func readTotalsArrayOrDefaultByCustomKey (customKey) = split(valueOrElse(getString(customKey), formatInvestorS("0", "0", "0", "0", "0")), SEP)
150150
151151
152152 func readTotalsArrayOrDefault () = readTotalsArrayOrDefaultByCustomKey(keyTotals())
153153
154154
155155 func readInvestorArrayOrDefault (userAddress) = readTotalsArrayOrDefaultByCustomKey(keyInvestor(userAddress))
156156
157157
158158 func readInvestorArrayOrFail (userAddress) = split(getStringOrFail(keyInvestor(userAddress)), SEP)
159159
160160
161161 let IdxDiffTotalIncrement = 0
162162
163163 let IdxDiffRemainingPriceAmountIncrement = 1
164164
165165 let IdxDiffClaimedPriceAmountIncrement = 2
166166
167167 let IdxDiffClaimedIdoAssetAmountIncrement = 3
168168
169169 func TotalsEntry (key,origArray,incrementDiff,newLastClaimedHeight,priceAssetBalance) = {
170170 let totalAmount = parseIntValue(origArray[IdxInvTotalAmount])
171171 let remainingAmount = parseIntValue(origArray[IdxInvRemainingAmount])
172172 let claimedPriceAssetAmount = parseIntValue(origArray[IdxInvClaimedPriceAssetAmount])
173173 let claimedIdoAssetAmount = parseIntValue(origArray[IdxInvClaimedIdoAssetAmount])
174174 let lastClaimedHeight = parseIntValue(origArray[IdxInvLastClaimedHeight])
175175 let newTotalAmount = (totalAmount + incrementDiff[IdxDiffTotalIncrement])
176176 let newRemainingAmount = (remainingAmount + incrementDiff[IdxDiffRemainingPriceAmountIncrement])
177177 let cfgArray = readConfigArray()
178178 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
179179 let priceAssetDecimals = value(assetInfo(fromBase58String(priceAssetId58))).decimals
180180 let priceAssetBalancePriceAssetDecimals = fraction(priceAssetBalance, scale8, pow(10, 0, priceAssetDecimals, 0, 0, DOWN))
181181 let newClaimedPriceAssetAmount = ((claimedPriceAssetAmount + incrementDiff[IdxDiffClaimedPriceAmountIncrement]) - priceAssetBalance)
182182 let newClaimedIdoAssetAmount = ((claimedIdoAssetAmount + incrementDiff[IdxDiffClaimedIdoAssetAmountIncrement]) + priceAssetBalancePriceAssetDecimals)
183183 let entries = if ((0 > newRemainingAmount))
184184 then {
185185 let diff = ((newTotalAmount - newClaimedPriceAssetAmount) - newClaimedIdoAssetAmount)
186186 let newLogicRemainingAmount = if ((0 > diff))
187187 then 0
188188 else diff
189189 StringEntry(key, formatInvestor(newTotalAmount, newLogicRemainingAmount, newClaimedPriceAssetAmount, newClaimedIdoAssetAmount, newLastClaimedHeight))
190190 }
191191 else StringEntry(key, formatInvestor(newTotalAmount, newRemainingAmount, newClaimedPriceAssetAmount, newClaimedIdoAssetAmount, newLastClaimedHeight))
192192 entries
193193 }
194194
195195
196196 func InvestOperationHistoryEntry (userAddress,priceAssetAmount,idoAssetAmount,txId) = StringEntry(keyOperationHistoryRecord("invest", userAddress, toBase58String(txId)), formatHistoryRecord(priceAssetAmount, idoAssetAmount))
197197
198198
199199 func ClaimOperationHistoryEntry (userAddress,priceAssetAmount,idoAssetAmount,txId) = StringEntry(keyOperationHistoryRecord("claim", userAddress, toBase58String(txId)), formatHistoryRecord(priceAssetAmount, idoAssetAmount))
200200
201201
202202 func internalClaim (claimedAssetId58,userAddress,txId) = {
203203 let cfgArray = readConfigArray()
204204 let claimStart = parseIntValue(cfgArray[IdxCfgClaimStart])
205205 let claimDuration = parseIntValue(cfgArray[IdxCfgClaimDuration])
206206 let claimEnd = (claimStart + claimDuration)
207207 let price = parseIntValue(cfgArray[IdxCfgPrice])
208208 let priceMult = parseIntValue(cfgArray[IdxCfgPriceMult])
209209 let idoAssetId58 = cfgArray[IdxCfgIdoAssetId]
210210 let idoAssetId = fromBase58String(idoAssetId58)
211211 let idoAssetMult = parseIntValue(cfgArray[IdxCfgIdoAssetMult])
212212 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
213213 let priceAssetId = fromBase58String(priceAssetId58)
214214 let priceAssetMult = parseIntValue(cfgArray[IdxCfgPriceAssetMult])
215215 let userAddress58 = toString(userAddress)
216216 let origInvestArray = readInvestorArrayOrFail(userAddress58)
217217 let investTotalAmount = parseIntValue(origInvestArray[IdxInvTotalAmount])
218218 let investLastClaimedHeightTMP = parseIntValue(origInvestArray[IdxInvLastClaimedHeight])
219219 let investLastClaimedHeight = if ((claimStart >= investLastClaimedHeightTMP))
220220 then claimStart
221221 else investLastClaimedHeightTMP
222222 let newClaimPeriodHeight = if ((height > claimEnd))
223223 then claimEnd
224224 else if ((claimStart > height))
225225 then claimStart
226226 else height
227227 let claimingBlocks = (newClaimPeriodHeight - investLastClaimedHeight)
228228 let claimingPriceAssetAmount = fraction(investTotalAmount, claimingBlocks, claimDuration)
229229 let claimingIdoAssetAmount = convertPriceAssetIntoIdoAsset(claimingPriceAssetAmount, priceAssetMult, price, priceMult, idoAssetMult)
230230 let isUSDN = (claimedAssetId58 == priceAssetId58)
231231 let isUSDNClaimDisabled = valueOrElse(getBoolean(keyUSDNClaimDisabled()), false)
232232 let checks = [if (!(if (isUSDN)
233233 then isUSDNClaimDisabled
234234 else false))
235235 then true
236236 else throw("USDN claim is disabled")]
237237 if ((checks == checks))
238238 then if ((claimedAssetId58 == priceAssetId58))
239239 then $Tuple6([0, -(claimingPriceAssetAmount), claimingPriceAssetAmount, 0], claimingPriceAssetAmount, priceAssetId, origInvestArray, newClaimPeriodHeight, [claimingPriceAssetAmount, claimingIdoAssetAmount])
240240 else if ((claimedAssetId58 == idoAssetId58))
241241 then $Tuple6([0, -(claimingPriceAssetAmount), 0, claimingIdoAssetAmount], claimingIdoAssetAmount, idoAssetId, origInvestArray, newClaimPeriodHeight, [claimingPriceAssetAmount, claimingIdoAssetAmount])
242242 else throw(("unsupported assetId: " + claimedAssetId58))
243243 else throw("Strict value is not equal to itself.")
244244 }
245245
246246
247247 func internalClaimV2 (priceAssetId58,userAddress58,outAmount,totalUserAvailableToClaim) = {
248248 let totalPeriodPriceAssetAllowance = value(getInteger(keyTotalPeriodAllowance(priceAssetId58)))
249249 let userPeriodPriceAssetAllowance = value(getInteger(keyUserPeriodAllowance(priceAssetId58)))
250250 let periodLength = value(getInteger(keyPeriodLength()))
251251 let currentPeriod = valueOrElse(getInteger(keyCurrentPeriod()), 0)
252252 let zeroPeriodEndHeighIsDefined = isDefined(getInteger(keyPeriodEndHeight(0)))
253253 let $t01298714857 = if ((currentPeriod > 0))
254254 then {
255255 let lastPeriodStartHeight = value(getInteger(keyPeriodStartHeight(currentPeriod)))
256256 let lastPeriodEndHeight = value(getInteger(keyPeriodEndHeight(currentPeriod)))
257257 let $t01324713952 = if ((height > lastPeriodEndHeight))
258258 then {
259259 let updatedCurrentPeriod = (currentPeriod + 1)
260260 let periodStart = if ((height > (lastPeriodEndHeight + periodLength)))
261261 then {
262262 let blocksToLastPeriodStart = ((height - lastPeriodEndHeight) % periodLength)
263263 if ((blocksToLastPeriodStart == 0))
264264 then ((height - periodLength) + 1)
265265 else (height - blocksToLastPeriodStart)
266266 }
267267 else (lastPeriodEndHeight + 1)
268268 let periodEnd = ((periodStart + periodLength) - 1)
269269 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
270270 }
271271 else $Tuple3(currentPeriod, lastPeriodStartHeight, lastPeriodEndHeight)
272272 let updatedCurrentPeriod = $t01324713952._1
273273 let periodStart = $t01324713952._2
274274 let periodEnd = $t01324713952._3
275275 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
276276 }
277277 else if (zeroPeriodEndHeighIsDefined)
278278 then {
279279 let zeroPeriodStartHeight = value(getInteger(keyPeriodStartHeight(0)))
280280 let zeroPeriodEndHeight = value(getInteger(keyPeriodEndHeight(0)))
281281 let $t01420714589 = if ((height > zeroPeriodEndHeight))
282282 then {
283283 let updatedCurrentPeriod = (currentPeriod + 1)
284284 let periodStart = (zeroPeriodEndHeight + 1)
285285 let periodEnd = ((periodStart + periodLength) - 1)
286286 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
287287 }
288288 else $Tuple3(currentPeriod, zeroPeriodStartHeight, zeroPeriodEndHeight)
289289 let updatedCurrentPeriod = $t01420714589._1
290290 let periodStart = $t01420714589._2
291291 let periodEnd = $t01420714589._3
292292 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
293293 }
294294 else $Tuple3(currentPeriod, valueOrElse(getInteger(keyPeriodStartHeight(currentPeriod)), height), valueOrElse(getInteger(keyPeriodEndHeight(currentPeriod)), ((height + periodLength) - 1)))
295295 let updatedCurrentPeriod = $t01298714857._1
296296 let periodStart = $t01298714857._2
297297 let periodEnd = $t01298714857._3
298298 let periodTotalAvailableToClaim = valueOrElse(getInteger(keyPeriodTotalAvailableToClaim(priceAssetId58, updatedCurrentPeriod)), totalPeriodPriceAssetAllowance)
299299 let periodUserAvailableToClaim = valueOrElse(getInteger(keyPeriodUserAvailableToClaim(priceAssetId58, updatedCurrentPeriod, userAddress58)), userPeriodPriceAssetAllowance)
300300 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
301301 let periodMinAvailableToClaim = min([(outAmount + priceAssetBalance), periodTotalAvailableToClaim, periodUserAvailableToClaim])
302302 let usdtPriceAssetAllowableRatio = value(getInteger(keyUsdtPriceAssetAllowableRatio()))
303303 let putOneTknV2PriceAssetAmount = scale8
304304 let $t01561215865 = {
305305 let @ = invoke(addressFromStringValue(value(getString(keyUsdtPriceAssetStablePool()))), "putOneTknV2WithoutTakeFeeREADONLY", [putOneTknV2PriceAssetAmount, priceAssetId58], nil)
306306 if ($isInstanceOf(@, "(Int, Int, Int)"))
307307 then @
308308 else throw(($getType(@) + " couldn't be cast to (Int, Int, Int)"))
309309 }
310310 if (($t01561215865 == $t01561215865))
311311 then {
312312 let bonus = $t01561215865._3
313313 let feeAmount = $t01561215865._2
314314 let lpAmount = $t01561215865._1
315315 let usdtAssetId = value(getString(keyUsdtAssetId()))
316316 let $t01592716145 = {
317317 let @ = invoke(addressFromStringValue(value(getString(keyUsdtPriceAssetStablePool()))), "getOneTknV2READONLY", [usdtAssetId, lpAmount], nil)
318318 if ($isInstanceOf(@, "(Int, Int)"))
319319 then @
320320 else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
321321 }
322322 if (($t01592716145 == $t01592716145))
323323 then {
324324 let getOneTknV2FeeAmount = $t01592716145._2
325325 let usdtAmount = $t01592716145._1
326326 let currentUsdtPriceAssetRatio = fraction(putOneTknV2PriceAssetAmount, scale8, usdtAmount)
327327 let endPeriodBlocksLeft = (periodEnd - height)
328328 $Tuple10(periodMinAvailableToClaim, periodTotalAvailableToClaim, periodUserAvailableToClaim, totalUserAvailableToClaim, usdtPriceAssetAllowableRatio, currentUsdtPriceAssetRatio, endPeriodBlocksLeft, updatedCurrentPeriod, periodStart, periodEnd)
329329 }
330330 else throw("Strict value is not equal to itself.")
331331 }
332332 else throw("Strict value is not equal to itself.")
333333 }
334334
335335
336336 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
337337 case s: String =>
338338 fromBase58String(s)
339339 case _: Unit =>
340340 unit
341341 case _ =>
342342 throw("Match error")
343343 }
344344
345345
346346 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
347347 case s: String =>
348348 fromBase58String(s)
349349 case _: Unit =>
350350 unit
351351 case _ =>
352352 throw("Match error")
353353 }
354354
355355
356356 func mustManager (i) = {
357357 let pd = throw("Permission denied")
358358 match managerPublicKeyOrUnit() {
359359 case pk: ByteVector =>
360360 if ((i.callerPublicKey == pk))
361361 then true
362362 else pd
363363 case _: Unit =>
364364 if ((i.caller == this))
365365 then true
366366 else pd
367367 case _ =>
368368 throw("Match error")
369369 }
370370 }
371371
372372
373373 @Callable(i)
374374 func constructor (idoStart,idoDuration,claimStart,claimDuration,price,priceAssetId58,minInvestAmount) = {
375375 let priceMult = ((100 * 1000) * 1000)
376376 let idoEnd = (idoStart + idoDuration)
377377 if (isDefined(getString(keyConfig())))
378378 then throw("already initialized")
379379 else if (("3PMEHLx1j6zerarZTYfsGqDeeZqQoMpxq5S" != toString(i.caller)))
380380 then throw("not authorized")
381381 else if ((size(i.payments) != 1))
382382 then throw("exactly 1 payment must be attached")
383383 else if ((idoEnd >= claimStart))
384384 then throw("claimStart must be greater than idoEnd")
385385 else {
386386 let pmt = value(i.payments[0])
387387 let idoAssetId = value(pmt.assetId)
388388 let idoAssetInfo = valueOrErrorMessage(assetInfo(idoAssetId), "fail to load ido asset info")
389389 let idoAssetId58 = toBase58String(idoAssetId)
390390 let idoAssetMult = pow(10, 0, idoAssetInfo.decimals, 0, 0, DOWN)
391391 let priceAssetId = fromBase58String(priceAssetId58)
392392 let priceAssetInfo = valueOrErrorMessage(assetInfo(priceAssetId), "fail to load price asset info")
393393 let priceAssetMult = pow(10, 0, priceAssetInfo.decimals, 0, 0, DOWN)
394394 let origTotalsArray = readTotalsArrayOrDefault()
395395 let totalsDiff = [0, 0, 0, 0]
396396 [StringEntry(keyConfig(), fromatConfig(idoStart, idoDuration, claimStart, claimDuration, price, priceMult, idoAssetId58, idoAssetMult, priceAssetId58, priceAssetMult, minInvestAmount, pmt.amount)), TotalsEntry(keyTotals(), origTotalsArray, totalsDiff, claimStart, 0)]
397397 }
398398 }
399399
400400
401401
402402 @Callable(i)
403403 func invest () = {
404404 let cfgArray = readConfigArray()
405405 let idoStart = parseIntValue(cfgArray[IdxCfgIdoStart])
406406 let idoDuration = parseIntValue(cfgArray[IdxCfgIdoDuration])
407407 let idoEnd = (idoStart + idoDuration)
408408 let claimStart = parseIntValue(cfgArray[IdxCfgClaimStart])
409409 let claimDuration = parseIntValue(cfgArray[IdxCfgClaimDuration])
410410 let price = parseIntValue(cfgArray[IdxCfgPrice])
411411 let priceMult = parseIntValue(cfgArray[IdxCfgPriceMult])
412412 let idoAssetId58 = cfgArray[IdxCfgIdoAssetId]
413413 let idoAssetId = fromBase58String(idoAssetId58)
414414 let idoAssetMult = parseIntValue(cfgArray[IdxCfgIdoAssetMult])
415415 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
416416 let priceAssetId = fromBase58String(priceAssetId58)
417417 let priceAssetMult = parseIntValue(cfgArray[IdxCfgPriceAssetMult])
418418 let minIvestAmount = parseIntValue(cfgArray[IdxCfgMinInvestAmount])
419419 let userAddress = toString(i.caller)
420420 if ((idoStart > height))
421421 then throw("ido has not been started yet")
422422 else if ((height > idoEnd))
423423 then throw("ido has been already ended")
424424 else if ((size(i.payments) != 1))
425425 then throw("exactly 1 payment is expected")
426426 else {
427427 let pmt = value(i.payments[0])
428428 let pmtAssetId = value(pmt.assetId)
429429 let pmtAmount = pmt.amount
430430 if ((pmtAssetId != priceAssetId))
431431 then throw((("invalid payment asset id: " + toBase58String(pmtAssetId)) + " is expected"))
432432 else {
433433 let origInvestorArray = readInvestorArrayOrDefault(userAddress)
434434 let origTotalsArray = readTotalsArrayOrDefault()
435435 let newPriceTotalAmount = (parseIntValue(origTotalsArray[IdxInvTotalAmount]) + pmtAmount)
436436 let requiredIdoAssetAmount = (newPriceTotalAmount * 100)
437437 if ((requiredIdoAssetAmount > assetBalance(this, idoAssetId)))
438438 then throw("IDO asset has been - sold consider to use smaller payment")
439439 else {
440440 let totalsDiff = [pmtAmount, pmtAmount, 0, 0]
441441 [TotalsEntry(keyInvestor(userAddress), origInvestorArray, totalsDiff, claimStart, 0), TotalsEntry(keyTotals(), origTotalsArray, totalsDiff, claimStart, 0), InvestOperationHistoryEntry(userAddress, pmtAmount, 0, i.transactionId)]
442442 }
443443 }
444444 }
445445 }
446446
447447
448448
449449 @Callable(i)
450450 func claim (claimedAssetId58,userAddress58) = {
451451 let callerAddress58 = toString(i.caller)
452452 if ((userAddress58 != callerAddress58))
453453 then throw("not authorized")
454454 else {
455455 let cfgArray = readConfigArray()
456456 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
457457 let claimResultTuple = internalClaim(claimedAssetId58, i.caller, i.transactionId)
458458 let totalsDiff = claimResultTuple._1
459459 let outAmount = claimResultTuple._2
460460 let outAssetId = claimResultTuple._3
461461 let origInvestArray = claimResultTuple._4
462462 let newClaimPeriodHeight = claimResultTuple._5
463463 let claimedPriceAmountFromDiff = totalsDiff[IdxDiffClaimedPriceAmountIncrement]
464464 let claimedIdoAssetAmountFromDiff = totalsDiff[IdxDiffClaimedIdoAssetAmountIncrement]
465465 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
466466 let priceAssetDecimals = value(assetInfo(fromBase58String(priceAssetId58))).decimals
467467 let entries = if ((claimedAssetId58 == priceAssetId58))
468468 then {
469469 let $t02205422498 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
470470 let periodMinAvailableToClaim = $t02205422498._1
471471 let periodTotalAvailableToClaim = $t02205422498._2
472472 let periodUserAvailableToClaim = $t02205422498._3
473473 let totalUserAvailableToClaim = $t02205422498._4
474474 let usdtPriceAssetAllowableRatio = $t02205422498._5
475475 let currentUsdtPriceAssetRatio = $t02205422498._6
476476 let endPeriodBlocksLeft = $t02205422498._7
477477 let updatedCurrentPeriod = $t02205422498._8
478478 let periodStart = $t02205422498._9
479479 let periodEnd = $t02205422498._10
480480 let checks = [if ((periodUserAvailableToClaim > 0))
481481 then true
482482 else throwErr("unavailable to claim because user period allowance reached"), if ((periodTotalAvailableToClaim > 0))
483483 then true
484484 else throwErr("unavailable to claim because total period allowance reached"), if ((periodMinAvailableToClaim > 0))
485485 then true
486486 else throwErr("nothing to claim"), if ((usdtPriceAssetAllowableRatio > currentUsdtPriceAssetRatio))
487487 then true
488488 else throwErr("unavailable to claim because usdn price lower than usdtPriceAssetAllowableRatio")]
489489 if ((checks == checks))
490490 then {
491491 let updatedPeriodTotalAvailableToClaim = (periodTotalAvailableToClaim - periodMinAvailableToClaim)
492492 let updatedPeriodUserAvailableToClaim = (periodUserAvailableToClaim - periodMinAvailableToClaim)
493493 let entries = if ((priceAssetBalance > periodMinAvailableToClaim))
494494 then [ScriptTransfer(i.caller, periodMinAvailableToClaim, outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), (priceAssetBalance - periodMinAvailableToClaim))]
495495 else {
496496 let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
497497 if ((evaluateResult == evaluateResult))
498498 then {
499499 let availablePriceAmountToClaim = parseIntValue(evaluateResult[3])
500500 let lastClaimEntries = if ((availablePriceAmountToClaim == periodMinAvailableToClaim))
501501 then {
502502 let investorTotalAmount = parseIntValue(origInvestArray[IdxInvTotalAmount])
503503 let investorRemainingAmount = parseIntValue(origInvestArray[IdxInvRemainingAmount])
504504 let investorPriceAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedPriceAssetAmount])
505505 let investorIdoAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedIdoAssetAmount])
506506 let investorLastClaimedHeight = parseIntValue(origInvestArray[IdxInvLastClaimedHeight])
507507 let newInvestArray = [toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)]
508508 let totals = readTotalsArrayOrDefault()
509509 let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
510510 let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
511511 let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvRemainingAmount])
512512 let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
513513 let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
514514 let newTotalsRemainingAmount = (totalsRemainingAmount - investorRemainingAmount)
515515 let newTotalArray = [toString(totalsTotalAmount), toString(newTotalsRemainingAmount), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)]
516516 let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
517517 [StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), TotalsEntry(keyInvestor(userAddress58), newInvestArray, totalsDiff, newClaimPeriodHeight, 0), TotalsEntry(keyTotals(), newTotalArray, totalsDiff, newClaimPeriodHeight, 0)]
518518 }
519519 else [TotalsEntry(keyInvestor(userAddress58), origInvestArray, totalsDiff, newClaimPeriodHeight, 0), TotalsEntry(keyTotals(), readTotalsArrayOrDefault(), totalsDiff, newClaimPeriodHeight, 0)]
520520 let updatedPriceAssetBalance = ((priceAssetBalance + outAmount) - periodMinAvailableToClaim)
521521 ([ScriptTransfer(i.caller, periodMinAvailableToClaim, outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), updatedPriceAssetBalance)] ++ lastClaimEntries)
522522 }
523523 else throw("Strict value is not equal to itself.")
524524 }
525525 $Tuple2(([IntegerEntry(keyCurrentPeriod(), updatedCurrentPeriod), IntegerEntry(keyPeriodStartHeight(updatedCurrentPeriod), periodStart), IntegerEntry(keyPeriodEndHeight(updatedCurrentPeriod), periodEnd), IntegerEntry(keyPeriodTotalAvailableToClaim(priceAssetId58, updatedCurrentPeriod), updatedPeriodTotalAvailableToClaim), IntegerEntry(keyPeriodUserAvailableToClaim(priceAssetId58, updatedCurrentPeriod, userAddress58), updatedPeriodUserAvailableToClaim), ClaimOperationHistoryEntry(userAddress58, periodMinAvailableToClaim, claimedIdoAssetAmountFromDiff, i.transactionId)] ++ entries), unit)
526526 }
527527 else throw("Strict value is not equal to itself.")
528528 }
529529 else {
530530 let priceAssetBalanceIdoDecimals = fraction(priceAssetBalance, scale8, pow(10, 0, priceAssetDecimals, 0, 0, DOWN))
531531 $Tuple2([ScriptTransfer(i.caller, (outAmount + priceAssetBalanceIdoDecimals), outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), 0), TotalsEntry(keyInvestor(userAddress58), origInvestArray, totalsDiff, newClaimPeriodHeight, priceAssetBalance), TotalsEntry(keyTotals(), readTotalsArrayOrDefault(), totalsDiff, newClaimPeriodHeight, priceAssetBalance), ClaimOperationHistoryEntry(userAddress58, claimedPriceAmountFromDiff, (claimedIdoAssetAmountFromDiff + priceAssetBalanceIdoDecimals), i.transactionId)], unit)
532532 }
533533 entries
534534 }
535535 }
536536
537537
538538
539539 @Callable(i)
540-func cleanRemaingAmount (userAddress58) = {
541- let priceAssetId58 = readConfigArray()[IdxCfgPriceAssetId]
542- let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
543- if ((evaluateResult == evaluateResult))
544- then {
545- let availablePriceAmountToClaim = parseIntValue(evaluateResult[2])
546- let checkUnclaimedAssets = if ((availablePriceAmountToClaim == 0))
547- then true
548- else throwErr("user have unclaimed assets")
549- if ((checkUnclaimedAssets == checkUnclaimedAssets))
550- then {
551- let investor = split(value(getString(keyInvestor(userAddress58))), SEP)
552- let investorTotalAmount = parseIntValue(investor[IdxInvTotalAmount])
553- let investorRemainingAmount = parseIntValue(investor[IdxInvRemainingAmount])
554- let investorPriceAssetBalance = parseIntValue(investor[IdxInvClaimedPriceAssetAmount])
555- let investorIdoAssetBalance = parseIntValue(investor[IdxInvClaimedIdoAssetAmount])
556- let investorLastClaimedHeight = parseIntValue(investor[IdxInvLastClaimedHeight])
557- let investorRemainingAmountCheck = if ((investorRemainingAmount != 0))
558- then true
559- else throwErr("investorRemainingAmount already zero")
560- if ((investorRemainingAmountCheck == investorRemainingAmountCheck))
561- then {
562- let newInvestor = makeString(["%d%d%d%d%d", toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)], SEP)
563- let totals = split(value(getString(keyTotals())), SEP)
564- let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
565- let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
566- let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
567- let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedIdoAssetAmount])
568- let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
569- let newTotals = makeString(["%d%d%d%d%d", toString(totalsTotalAmount), toString((totalsRemainingAmount - investorRemainingAmount)), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)], SEP)
570- let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
571-[StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), StringEntry(keyInvestor(userAddress58), newInvestor), StringEntry(keyTotals(), newTotals)]
572- }
573- else throw("Strict value is not equal to itself.")
574- }
575- else throw("Strict value is not equal to itself.")
576- }
577- else throw("Strict value is not equal to itself.")
578- }
579-
580-
581-
582-@Callable(i)
583540 func claimREADONLY (claimedAssetId58,userAddress58) = {
584541 let claimResultTuple = internalClaim(claimedAssetId58, addressFromStringValue(userAddress58), fromBase58String(""))
585542 let totalsDiff = claimResultTuple._1
586543 let outAmount = claimResultTuple._2
587544 let outAssetId = claimResultTuple._3
588545 let origInvestArray = claimResultTuple._4
589546 let newClaimPeriodHeight = claimResultTuple._5
590547 let availableToClaimArray = claimResultTuple._6
591548 let availablePriceAmountToClaim = availableToClaimArray[0]
592549 let availableIdoAmountToClaim = availableToClaimArray[1]
593550 $Tuple2(nil, makeString(["%s%d%d", userAddress58, toString(availablePriceAmountToClaim), toString(availableIdoAmountToClaim)], SEP))
594551 }
595552
596553
597554
598555 @Callable(i)
599556 func claimV2READONLY (claimedAssetId58,userAddress58) = {
600557 let claimResultTuple = internalClaim(claimedAssetId58, addressFromStringValue(userAddress58), fromBase58String(""))
601558 let totalsDiff = claimResultTuple._1
602559 let outAmount = claimResultTuple._2
603560 let outAssetId = claimResultTuple._3
604561 let origInvestArray = claimResultTuple._4
605562 let newClaimPeriodHeight = claimResultTuple._5
606563 let availableToClaimArray = claimResultTuple._6
607564 let availablePriceAmountToClaim = availableToClaimArray[0]
608565 let availableIdoAmountToClaim = availableToClaimArray[1]
609566 let cfgArray = readConfigArray()
610567 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
611568 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
612569 let priceAssetBalanceIdoDecimals = (priceAssetBalance * 100)
613570 let availableIdoAmountToClaimWithPriceAssetBalance = (availableIdoAmountToClaim + priceAssetBalanceIdoDecimals)
614- let $t03374334155 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
615- let periodMinAvailableToClaim = $t03374334155._1
616- let periodTotalAvailableToClaim = $t03374334155._2
617- let periodUserAvailableToClaim = $t03374334155._3
618- let totalUserAvailableToClaim = $t03374334155._4
619- let usdtPriceAssetAllowableRatio = $t03374334155._5
620- let currentUsdtPriceAssetRatio = $t03374334155._6
621- let endPeriodBlocksLeft = $t03374334155._7
622- let updatedCurrentPeriod = $t03374334155._8
623- let periodStart = $t03374334155._9
624- let periodEnd = $t03374334155._10
571+ let $t03128231694 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
572+ let periodMinAvailableToClaim = $t03128231694._1
573+ let periodTotalAvailableToClaim = $t03128231694._2
574+ let periodUserAvailableToClaim = $t03128231694._3
575+ let totalUserAvailableToClaim = $t03128231694._4
576+ let usdtPriceAssetAllowableRatio = $t03128231694._5
577+ let currentUsdtPriceAssetRatio = $t03128231694._6
578+ let endPeriodBlocksLeft = $t03128231694._7
579+ let updatedCurrentPeriod = $t03128231694._8
580+ let periodStart = $t03128231694._9
581+ let periodEnd = $t03128231694._10
625582 let currentPeriodEndHeight = valueOrElse(getInteger(keyPeriodEndHeight(updatedCurrentPeriod)), 0)
626583 let userTotalPriceAssetClaimed = (parseIntValue(readInvestorArrayOrFail(userAddress58)[IdxInvClaimedPriceAssetAmount]) - priceAssetBalance)
627584 let resultString = if ((height > currentPeriodEndHeight))
628585 then {
629586 let periodLenght = value(getInteger(keyPeriodLength()))
630587 let userPeriodAllowance = value(getInteger(keyUserPeriodAllowance(priceAssetId58)))
631588 let totalPeriodAllowance = value(getInteger(keyTotalPeriodAllowance(priceAssetId58)))
632589 makeString(["%d%d%d%d%d%d", toString(availableIdoAmountToClaimWithPriceAssetBalance), toString(userPeriodAllowance), toString(totalPeriodAllowance), toString(usdtPriceAssetAllowableRatio), toString(currentUsdtPriceAssetRatio), toString(periodLenght), toString(userTotalPriceAssetClaimed)], SEP)
633590 }
634591 else makeString(["%d%d%d%d%d%d", toString(availableIdoAmountToClaimWithPriceAssetBalance), toString(periodMinAvailableToClaim), toString(periodTotalAvailableToClaim), toString(usdtPriceAssetAllowableRatio), toString(currentUsdtPriceAssetRatio), toString(endPeriodBlocksLeft), toString(userTotalPriceAssetClaimed)], SEP)
635592 $Tuple2(nil, resultString)
636593 }
637594
638595
639596
640597 @Callable(i)
641598 func setManager (pendingManagerPublicKey) = {
642599 let checkCaller = mustManager(i)
643600 if ((checkCaller == checkCaller))
644601 then {
645602 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
646603 if ((checkManagerPublicKey == checkManagerPublicKey))
647604 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
648605 else throw("Strict value is not equal to itself.")
649606 }
650607 else throw("Strict value is not equal to itself.")
651608 }
652609
653610
654611
655612 @Callable(i)
656613 func confirmManager () = {
657614 let pm = pendingManagerPublicKeyOrUnit()
658615 let hasPM = if (isDefined(pm))
659616 then true
660617 else throw("No pending manager")
661618 if ((hasPM == hasPM))
662619 then {
663620 let checkPM = if ((i.callerPublicKey == value(pm)))
664621 then true
665622 else throw("You are not pending manager")
666623 if ((checkPM == checkPM))
667624 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
668625 else throw("Strict value is not equal to itself.")
669626 }
670627 else throw("Strict value is not equal to itself.")
671628 }
672629
673630
674631 @Verifier(tx)
675632 func verify () = {
676633 let targetPublicKey = match managerPublicKeyOrUnit() {
677634 case pk: ByteVector =>
678635 pk
679636 case _: Unit =>
680637 tx.senderPublicKey
681638 case _ =>
682639 throw("Match error")
683640 }
684641 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
685642 }
686643

github/deemru/w8io/786bc32 
76.03 ms