tx · GErWcMS4rUkmR8JXvMYfHgBSDNYMqgBPAKixYt9kNH1M

3MptKi7f3jwXjzqhHpvLLzsSpEQdZiwAo5c:  -0.04000000 Waves

2024.01.15 16:05 [2932675] smart account 3MptKi7f3jwXjzqhHpvLLzsSpEQdZiwAo5c > SELF 0.00000000 Waves

{ "type": 13, "id": "GErWcMS4rUkmR8JXvMYfHgBSDNYMqgBPAKixYt9kNH1M", "fee": 4000000, "feeAssetId": null, "timestamp": 1705323928226, "version": 2, "chainId": 84, "sender": "3MptKi7f3jwXjzqhHpvLLzsSpEQdZiwAo5c", "senderPublicKey": "44kjsoExo76qSrM51NMhbG8FtdLkcPtyJxEDrwDyT8kz", "proofs": [ "3Y2ew1ta6XZNin7jxWDxc8uDnPvdvgBqvF38SBH1EUFtK49cA2tXB4Qvs85YqYaepjxu1aMBb7f9GAiqy4St2URK" ], "script": "base64:BgIrCAISCQoHAQEBAQEIARIAEgQKAggIEgMKAQgSAwoBCBIECgIICBIECgIICEYBD2dldFN0cmluZ09yRmFpbAEDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQUDa2V5CQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQNrZXkCDyBpcyBub3QgZGVmaW5lZAADU0VQAgJfXwAIQlVGU0NBTEUJALYCAQCAgJC7utat8A0ABnNjYWxlOACAwtcvAQh0aHJvd0VycgEDbXNnCQACAQkAuQkCCQDMCAICCWlkby5yaWRlOgkAzAgCBQNtc2cFA25pbAIBIAEIYXNTdHJpbmcBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACBlN0cmluZwQGdmFsU3RyBQckbWF0Y2gwBQZ2YWxTdHIJAAIBAhhmYWlsIHRvIGNhc3QgaW50byBTdHJpbmcBHWNvbnZlcnRQcmljZUFzc2V0SW50b0lkb0Fzc2V0BRBwcmljZUFzc2V0QW1vdW50DnByaWNlQXNzZXRNVUxUBXByaWNlCXByaWNlTVVMVAxpZG9Bc3NldE1VTFQED2JQcmljZUFzc2V0TVVMVAkAtgIBBQ5wcmljZUFzc2V0TVVMVAQNYklkb0Fzc2V0TVVMVAkAtgIBBQxpZG9Bc3NldE1VTFQEDmJQcmljZUFzc2V0QlVGCQC8AgMJALYCAQUQcHJpY2VBc3NldEFtb3VudAUIQlVGU0NBTEUFD2JQcmljZUFzc2V0TVVMVAQPYkFtb3VudEFzc2V0QlVGCQC8AgMFDmJQcmljZUFzc2V0QlVGCQC2AgEFCXByaWNlTVVMVAkAtgIBBQVwcmljZQkAoAMBCQC8AgMFD2JBbW91bnRBc3NldEJVRgkAtgIBBQxpZG9Bc3NldE1VTFQFCEJVRlNDQUxFAA5JZHhDZmdJZG9TdGFydAABABFJZHhDZmdJZG9EdXJhdGlvbgACABBJZHhDZmdDbGFpbVN0YXJ0AAMAE0lkeENmZ0NsYWltRHVyYXRpb24ABAALSWR4Q2ZnUHJpY2UABQAPSWR4Q2ZnUHJpY2VNdWx0AAYAEElkeENmZ0lkb0Fzc2V0SWQABwASSWR4Q2ZnSWRvQXNzZXRNdWx0AAgAEklkeENmZ1ByaWNlQXNzZXRJZAAJABRJZHhDZmdQcmljZUFzc2V0TXVsdAAKABVJZHhDZmdNaW5JbnZlc3RBbW91bnQACwENZnJvbWF0Q29uZmlnUwwIaWRvU3RhcnQLaWRvRHVyYXRpb24KY2xhaW1TdGFydA1jbGFpbUR1cmF0aW9uBXByaWNlCXByaWNlTXVsdAxpZG9Bc3NldElkNTgMaWRvQXNzZXRNdWx0DnByaWNlQXNzZXRJZDU4DnByaWNlQXNzZXRNdWx0D21pbkludmVzdEFtb3VudBN0b3RhbElkb0Fzc2V0VG9TZWxsCQC5CQIJAMwIAgIYJWQlZCVkJWQlZCVkJXMlZCVzJWQlZCVkCQDMCAIFCGlkb1N0YXJ0CQDMCAIFC2lkb0R1cmF0aW9uCQDMCAIFCmNsYWltU3RhcnQJAMwIAgUNY2xhaW1EdXJhdGlvbgkAzAgCBQVwcmljZQkAzAgCBQlwcmljZU11bHQJAMwIAgUMaWRvQXNzZXRJZDU4CQDMCAIFDGlkb0Fzc2V0TXVsdAkAzAgCBQ5wcmljZUFzc2V0SWQ1OAkAzAgCBQ5wcmljZUFzc2V0TXVsdAkAzAgCBQ9taW5JbnZlc3RBbW91bnQJAMwIAgUTdG90YWxJZG9Bc3NldFRvU2VsbAUDbmlsBQNTRVABDGZyb21hdENvbmZpZwwIaWRvU3RhcnQLaWRvRHVyYXRpb24KY2xhaW1TdGFydA1jbGFpbUR1cmF0aW9uBXByaWNlCXByaWNlTXVsdAxpZG9Bc3NldElkNTgMaWRvQXNzZXRNdWx0DnByaWNlQXNzZXRJZDU4DnByaWNlQXNzZXRNdWx0D21pbkludmVzdEFtb3VudBN0b3RhbElkb0Fzc2V0VG9TZWxsCQENZnJvbWF0Q29uZmlnUwwJAKQDAQUIaWRvU3RhcnQJAKQDAQULaWRvRHVyYXRpb24JAKQDAQUKY2xhaW1TdGFydAkApAMBBQ1jbGFpbUR1cmF0aW9uCQCkAwEFBXByaWNlCQCkAwEFCXByaWNlTXVsdAUMaWRvQXNzZXRJZDU4CQCkAwEFDGlkb0Fzc2V0TXVsdAUOcHJpY2VBc3NldElkNTgJAKQDAQUOcHJpY2VBc3NldE11bHQJAKQDAQUPbWluSW52ZXN0QW1vdW50CQCkAwEFE3RvdGFsSWRvQXNzZXRUb1NlbGwAEUlkeEludlRvdGFsQW1vdW50AAEAFUlkeEludlJlbWFpbmluZ0Ftb3VudAACAB1JZHhJbnZDbGFpbWVkUHJpY2VBc3NldEFtb3VudAADABtJZHhJbnZDbGFpbWVkSWRvQXNzZXRBbW91bnQABAAXSWR4SW52TGFzdENsYWltZWRIZWlnaHQABQEPZm9ybWF0SW52ZXN0b3JTBQt0b3RhbEFtb3VudA9yZW1haW5pbmdBbW91bnQXY2xhaW1lZFByaWNlQXNzZXRBbW91bnQVY2xhaW1lZElkb0Fzc2V0QW1vdW50EWxhc3RDbGFpbWVkSGVpZ2h0CQC5CQIJAMwIAgIKJWQlZCVkJWQlZAkAzAgCBQt0b3RhbEFtb3VudAkAzAgCBQ9yZW1haW5pbmdBbW91bnQJAMwIAgUXY2xhaW1lZFByaWNlQXNzZXRBbW91bnQJAMwIAgUVY2xhaW1lZElkb0Fzc2V0QW1vdW50CQDMCAIFEWxhc3RDbGFpbWVkSGVpZ2h0BQNuaWwFA1NFUAEOZm9ybWF0SW52ZXN0b3IFC3RvdGFsQW1vdW50D3JlbWFpbmluZ0Ftb3VudBdjbGFpbWVkUHJpY2VBc3NldEFtb3VudBVjbGFpbWVkSWRvQXNzZXRBbW91bnQRbGFzdENsYWltZWRIZWlnaHQJAQ9mb3JtYXRJbnZlc3RvclMFCQCkAwEFC3RvdGFsQW1vdW50CQCkAwEFD3JlbWFpbmluZ0Ftb3VudAkApAMBBRdjbGFpbWVkUHJpY2VBc3NldEFtb3VudAkApAMBBRVjbGFpbWVkSWRvQXNzZXRBbW91bnQJAKQDAQURbGFzdENsYWltZWRIZWlnaHQBE2Zvcm1hdEhpc3RvcnlSZWNvcmQCEHByaWNlQXNzZXRBbW91bnQOaWRvQXNzZXRBbW91bnQJALkJAgkAzAgCAgglZCVkJWQlZAkAzAgCCQCkAwEFBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAKQDAQUQcHJpY2VBc3NldEFtb3VudAkAzAgCCQCkAwEFDmlkb0Fzc2V0QW1vdW50BQNuaWwFA1NFUAEJa2V5Q29uZmlnAAIKJXNfX2NvbmZpZwELa2V5SW52ZXN0b3IBC3VzZXJBZGRyZXNzCQCsAgICBCVzX18FC3VzZXJBZGRyZXNzAQlrZXlUb3RhbHMAAgolc19fdG90YWxzARlrZXlPcGVyYXRpb25IaXN0b3J5UmVjb3JkAwR0eXBlC3VzZXJBZGRyZXNzBnR4SWQ1OAkAuQkCCQDMCAICESVzJXMlcyVzX19oaXN0b3J5CQDMCAIFBHR5cGUJAMwIAgULdXNlckFkZHJlc3MJAMwIAgUGdHhJZDU4BQNuaWwFA1NFUAEUa2V5VVNETkNsYWltRGlzYWJsZWQAAhUlc19fdXNkbkNsYWltRGlzYWJsZWQBFWtleVVTRE5DbGFpbUVuZEhlaWdodAACFiVzX191c2RuQ2xhaW1FbmRIZWlnaHQBD2tleVBlcmlvZExlbmd0aAAJALkJAgkAzAgCAgIlcwkAzAgCAgxwZXJpb2RMZW5ndGgFA25pbAUDU0VQARBrZXlDdXJyZW50UGVyaW9kAAkAuQkCCQDMCAICAiVzCQDMCAICDWN1cnJlbnRQZXJpb2QFA25pbAUDU0VQARRrZXlQZXJpb2RTdGFydEhlaWdodAEJcGVyaW9kTnVtCQC5CQIJAMwIAgIEJXMlcwkAzAgCAhFwZXJpb2RTdGFydEhlaWdodAkAzAgCCQCkAwEFCXBlcmlvZE51bQUDbmlsBQNTRVABEmtleVBlcmlvZEVuZEhlaWdodAEJcGVyaW9kTnVtCQC5CQIJAMwIAgIEJXMlcwkAzAgCAg9wZXJpb2RFbmRIZWlnaHQJAMwIAgkApAMBBQlwZXJpb2ROdW0FA25pbAUDU0VQAR9rZXlVc2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvAAkAuQkCCQDMCAICAiVzCQDMCAICHHVzZHRQcmljZUFzc2V0QWxsb3dhYmxlUmF0aW8FA25pbAUDU0VQARdrZXlUb3RhbFBlcmlvZEFsbG93YW5jZQEHYXNzZXRJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgIUdG90YWxQZXJpb2RBbGxvd2FuY2UJAMwIAgUHYXNzZXRJZAUDbmlsBQNTRVABFmtleVVzZXJQZXJpb2RBbGxvd2FuY2UBB2Fzc2V0SWQJALkJAgkAzAgCAgQlcyVzCQDMCAICE3VzZXJQZXJpb2RBbGxvd2FuY2UJAMwIAgUHYXNzZXRJZAUDbmlsBQNTRVABHmtleVBlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQIHYXNzZXRJZAlwZXJpb2ROdW0JALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIbcGVyaW9kVG90YWxBdmFpbGFibGVUb0NsYWltCQDMCAIFB2Fzc2V0SWQJAMwIAgkApAMBBQlwZXJpb2ROdW0FA25pbAUDU0VQAR1rZXlQZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQMHYXNzZXRJZAlwZXJpb2ROdW0LdXNlckFkZHJlc3MJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCAhpwZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQkAzAgCBQdhc3NldElkCQDMCAIJAKQDAQUJcGVyaW9kTnVtCQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAEba2V5VXNkdFByaWNlQXNzZXRTdGFibGVQb29sAAkAuQkCCQDMCAICAiVzCQDMCAICGHVzZHRQcmljZUFzc2V0U3RhYmxlUG9vbAUDbmlsBQNTRVABDmtleVVzZHRBc3NldElkAAkAuQkCCQDMCAICAiVzCQDMCAICC3VzZHRBc3NldElkBQNuaWwFA1NFUAEUa2V5UHJpY2VBc3NldEJhbGFuY2UBB2FkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAICEXByaWNlQXNzZXRCYWxhbmNlCQDMCAIFB2FkZHJlc3MFA25pbAUDU0VQARprZXlJbnZlc3RvclJlbWFpbmluZ0Ftb3VudAEHYWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIXaW52ZXN0b3JSZW1haW5pbmdBbW91bnQJAMwIAgUHYWRkcmVzcwUDbmlsBQNTRVABF2tleVRvdGFsUmVtYWluaW5nQW1vdW50AAkAuQkCCQDMCAICAiVzCQDMCAICFHRvdGFsUmVtYWluaW5nQW1vdW50BQNuaWwFA1NFUAETa2V5TWFuYWdlclB1YmxpY0tleQACFCVzX19tYW5hZ2VyUHVibGljS2V5ARZrZXlNYW5hZ2VyVmF1bHRBZGRyZXNzAAIXJXNfX21hbmFnZXJWYXVsdEFkZHJlc3MBFWtleUNsYWltQ2xvc2luZ0hlaWdodAACFiVzX19jbGFpbUNsb3NpbmdIZWlnaHQAEmNsYWltQ2xvc2luZ0hlaWdodAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEVa2V5Q2xhaW1DbG9zaW5nSGVpZ2h0AAAAAQ9yZWFkQ29uZmlnQXJyYXkACQC1CQIJAQ9nZXRTdHJpbmdPckZhaWwBCQEJa2V5Q29uZmlnAAUDU0VQASNyZWFkVG90YWxzQXJyYXlPckRlZmF1bHRCeUN1c3RvbUtleQEJY3VzdG9tS2V5CQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUJY3VzdG9tS2V5CQEPZm9ybWF0SW52ZXN0b3JTBQIBMAIBMAIBMAIBMAIBMAUDU0VQARhyZWFkVG90YWxzQXJyYXlPckRlZmF1bHQACQEjcmVhZFRvdGFsc0FycmF5T3JEZWZhdWx0QnlDdXN0b21LZXkBCQEJa2V5VG90YWxzAAEacmVhZEludmVzdG9yQXJyYXlPckRlZmF1bHQBC3VzZXJBZGRyZXNzCQEjcmVhZFRvdGFsc0FycmF5T3JEZWZhdWx0QnlDdXN0b21LZXkBCQELa2V5SW52ZXN0b3IBBQt1c2VyQWRkcmVzcwEXcmVhZEludmVzdG9yQXJyYXlPckZhaWwBC3VzZXJBZGRyZXNzCQC1CQIJAQ9nZXRTdHJpbmdPckZhaWwBCQELa2V5SW52ZXN0b3IBBQt1c2VyQWRkcmVzcwUDU0VQARxnZXRNYW5hZ2VyVmF1bHRBZGRyZXNzT3JUaGlzAAQHJG1hdGNoMAkAoggBCQEWa2V5TWFuYWdlclZhdWx0QWRkcmVzcwADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQERQGV4dHJOYXRpdmUoMTA2MikBBQFzBQR0aGlzABVJZHhEaWZmVG90YWxJbmNyZW1lbnQAAAAkSWR4RGlmZlJlbWFpbmluZ1ByaWNlQW1vdW50SW5jcmVtZW50AAEAIklkeERpZmZDbGFpbWVkUHJpY2VBbW91bnRJbmNyZW1lbnQAAgAlSWR4RGlmZkNsYWltZWRJZG9Bc3NldEFtb3VudEluY3JlbWVudAADAQtUb3RhbHNFbnRyeQUDa2V5CW9yaWdBcnJheQ1pbmNyZW1lbnREaWZmFG5ld0xhc3RDbGFpbWVkSGVpZ2h0EXByaWNlQXNzZXRCYWxhbmNlBAt0b3RhbEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCW9yaWdBcnJheQURSWR4SW52VG90YWxBbW91bnQED3JlbWFpbmluZ0Ftb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCW9yaWdBcnJheQUVSWR4SW52UmVtYWluaW5nQW1vdW50BBdjbGFpbWVkUHJpY2VBc3NldEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCW9yaWdBcnJheQUdSWR4SW52Q2xhaW1lZFByaWNlQXNzZXRBbW91bnQEFWNsYWltZWRJZG9Bc3NldEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCW9yaWdBcnJheQUbSWR4SW52Q2xhaW1lZElkb0Fzc2V0QW1vdW50BBFsYXN0Q2xhaW1lZEhlaWdodAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCW9yaWdBcnJheQUXSWR4SW52TGFzdENsYWltZWRIZWlnaHQEDm5ld1RvdGFsQW1vdW50CQBkAgULdG90YWxBbW91bnQJAJEDAgUNaW5jcmVtZW50RGlmZgUVSWR4RGlmZlRvdGFsSW5jcmVtZW50BBJuZXdSZW1haW5pbmdBbW91bnQJAGQCBQ9yZW1haW5pbmdBbW91bnQJAJEDAgUNaW5jcmVtZW50RGlmZgUkSWR4RGlmZlJlbWFpbmluZ1ByaWNlQW1vdW50SW5jcmVtZW50BAhjZmdBcnJheQkBD3JlYWRDb25maWdBcnJheQAEDnByaWNlQXNzZXRJZDU4CQCRAwIFCGNmZ0FycmF5BRJJZHhDZmdQcmljZUFzc2V0SWQEEnByaWNlQXNzZXREZWNpbWFscwgJAQV2YWx1ZQEJAOwHAQkA2QQBBQ5wcmljZUFzc2V0SWQ1OAhkZWNpbWFscwQjcHJpY2VBc3NldEJhbGFuY2VQcmljZUFzc2V0RGVjaW1hbHMJAGsDBRFwcmljZUFzc2V0QmFsYW5jZQUGc2NhbGU4CQBsBgAKAAAFEnByaWNlQXNzZXREZWNpbWFscwAAAAAFBERPV04EGm5ld0NsYWltZWRQcmljZUFzc2V0QW1vdW50CQBlAgkAZAIFF2NsYWltZWRQcmljZUFzc2V0QW1vdW50CQCRAwIFDWluY3JlbWVudERpZmYFIklkeERpZmZDbGFpbWVkUHJpY2VBbW91bnRJbmNyZW1lbnQFEXByaWNlQXNzZXRCYWxhbmNlBBhuZXdDbGFpbWVkSWRvQXNzZXRBbW91bnQJAGQCCQBkAgUVY2xhaW1lZElkb0Fzc2V0QW1vdW50CQCRAwIFDWluY3JlbWVudERpZmYFJUlkeERpZmZDbGFpbWVkSWRvQXNzZXRBbW91bnRJbmNyZW1lbnQFI3ByaWNlQXNzZXRCYWxhbmNlUHJpY2VBc3NldERlY2ltYWxzBAdlbnRyaWVzAwkAZgIAAAUSbmV3UmVtYWluaW5nQW1vdW50BARkaWZmCQBlAgkAZQIFDm5ld1RvdGFsQW1vdW50BRpuZXdDbGFpbWVkUHJpY2VBc3NldEFtb3VudAUYbmV3Q2xhaW1lZElkb0Fzc2V0QW1vdW50BBduZXdMb2dpY1JlbWFpbmluZ0Ftb3VudAMJAGYCAAAFBGRpZmYAAAUEZGlmZgkBC1N0cmluZ0VudHJ5AgUDa2V5CQEOZm9ybWF0SW52ZXN0b3IFBQ5uZXdUb3RhbEFtb3VudAUXbmV3TG9naWNSZW1haW5pbmdBbW91bnQFGm5ld0NsYWltZWRQcmljZUFzc2V0QW1vdW50BRhuZXdDbGFpbWVkSWRvQXNzZXRBbW91bnQFFG5ld0xhc3RDbGFpbWVkSGVpZ2h0CQELU3RyaW5nRW50cnkCBQNrZXkJAQ5mb3JtYXRJbnZlc3RvcgUFDm5ld1RvdGFsQW1vdW50BRJuZXdSZW1haW5pbmdBbW91bnQFGm5ld0NsYWltZWRQcmljZUFzc2V0QW1vdW50BRhuZXdDbGFpbWVkSWRvQXNzZXRBbW91bnQFFG5ld0xhc3RDbGFpbWVkSGVpZ2h0BQdlbnRyaWVzARtJbnZlc3RPcGVyYXRpb25IaXN0b3J5RW50cnkEC3VzZXJBZGRyZXNzEHByaWNlQXNzZXRBbW91bnQOaWRvQXNzZXRBbW91bnQEdHhJZAkBC1N0cmluZ0VudHJ5AgkBGWtleU9wZXJhdGlvbkhpc3RvcnlSZWNvcmQDAgZpbnZlc3QFC3VzZXJBZGRyZXNzCQDYBAEFBHR4SWQJARNmb3JtYXRIaXN0b3J5UmVjb3JkAgUQcHJpY2VBc3NldEFtb3VudAUOaWRvQXNzZXRBbW91bnQBGkNsYWltT3BlcmF0aW9uSGlzdG9yeUVudHJ5BAt1c2VyQWRkcmVzcxBwcmljZUFzc2V0QW1vdW50Dmlkb0Fzc2V0QW1vdW50BHR4SWQJAQtTdHJpbmdFbnRyeQIJARlrZXlPcGVyYXRpb25IaXN0b3J5UmVjb3JkAwIFY2xhaW0FC3VzZXJBZGRyZXNzCQDYBAEFBHR4SWQJARNmb3JtYXRIaXN0b3J5UmVjb3JkAgUQcHJpY2VBc3NldEFtb3VudAUOaWRvQXNzZXRBbW91bnQBDWludGVybmFsQ2xhaW0DEGNsYWltZWRBc3NldElkNTgLdXNlckFkZHJlc3MEdHhJZAQIY2ZnQXJyYXkJAQ9yZWFkQ29uZmlnQXJyYXkABApjbGFpbVN0YXJ0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFEElkeENmZ0NsYWltU3RhcnQEDWNsYWltRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUTSWR4Q2ZnQ2xhaW1EdXJhdGlvbgQIY2xhaW1FbmQJAGQCBQpjbGFpbVN0YXJ0BQ1jbGFpbUR1cmF0aW9uBAVwcmljZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BQtJZHhDZmdQcmljZQQJcHJpY2VNdWx0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFD0lkeENmZ1ByaWNlTXVsdAQMaWRvQXNzZXRJZDU4CQCRAwIFCGNmZ0FycmF5BRBJZHhDZmdJZG9Bc3NldElkBAppZG9Bc3NldElkCQDZBAEFDGlkb0Fzc2V0SWQ1OAQMaWRvQXNzZXRNdWx0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ0lkb0Fzc2V0TXVsdAQOcHJpY2VBc3NldElkNTgJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ1ByaWNlQXNzZXRJZAQMcHJpY2VBc3NldElkCQDZBAEFDnByaWNlQXNzZXRJZDU4BA5wcmljZUFzc2V0TXVsdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRRJZHhDZmdQcmljZUFzc2V0TXVsdAQNdXNlckFkZHJlc3M1OAkApQgBBQt1c2VyQWRkcmVzcwQPb3JpZ0ludmVzdEFycmF5CQEXcmVhZEludmVzdG9yQXJyYXlPckZhaWwBBQ11c2VyQWRkcmVzczU4BBFpbnZlc3RUb3RhbEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD29yaWdJbnZlc3RBcnJheQURSWR4SW52VG90YWxBbW91bnQEGmludmVzdExhc3RDbGFpbWVkSGVpZ2h0VE1QCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPb3JpZ0ludmVzdEFycmF5BRdJZHhJbnZMYXN0Q2xhaW1lZEhlaWdodAQXaW52ZXN0TGFzdENsYWltZWRIZWlnaHQDCQBnAgUKY2xhaW1TdGFydAUaaW52ZXN0TGFzdENsYWltZWRIZWlnaHRUTVAFCmNsYWltU3RhcnQFGmludmVzdExhc3RDbGFpbWVkSGVpZ2h0VE1QBBRuZXdDbGFpbVBlcmlvZEhlaWdodAMJAGYCBQZoZWlnaHQFCGNsYWltRW5kBQhjbGFpbUVuZAMJAGYCBQpjbGFpbVN0YXJ0BQZoZWlnaHQFCmNsYWltU3RhcnQFBmhlaWdodAQOY2xhaW1pbmdCbG9ja3MJAGUCBRRuZXdDbGFpbVBlcmlvZEhlaWdodAUXaW52ZXN0TGFzdENsYWltZWRIZWlnaHQEGGNsYWltaW5nUHJpY2VBc3NldEFtb3VudAkAawMFEWludmVzdFRvdGFsQW1vdW50BQ5jbGFpbWluZ0Jsb2NrcwUNY2xhaW1EdXJhdGlvbgQWY2xhaW1pbmdJZG9Bc3NldEFtb3VudAkBHWNvbnZlcnRQcmljZUFzc2V0SW50b0lkb0Fzc2V0BQUYY2xhaW1pbmdQcmljZUFzc2V0QW1vdW50BQ5wcmljZUFzc2V0TXVsdAUFcHJpY2UFCXByaWNlTXVsdAUMaWRvQXNzZXRNdWx0BAZpc1VTRE4JAAACBRBjbGFpbWVkQXNzZXRJZDU4BQ5wcmljZUFzc2V0SWQ1OAQTaXNVU0ROQ2xhaW1EaXNhYmxlZAkBC3ZhbHVlT3JFbHNlAgkAoAgBCQEUa2V5VVNETkNsYWltRGlzYWJsZWQABwQGY2hlY2tzCQDMCAIDCQEBIQEDBQZpc1VTRE4FE2lzVVNETkNsYWltRGlzYWJsZWQHBgkAAgECFlVTRE4gY2xhaW0gaXMgZGlzYWJsZWQFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwMJAAACBRBjbGFpbWVkQXNzZXRJZDU4BQ5wcmljZUFzc2V0SWQ1OAkAmAoGCQDMCAIAAAkAzAgCCQEBLQEFGGNsYWltaW5nUHJpY2VBc3NldEFtb3VudAkAzAgCBRhjbGFpbWluZ1ByaWNlQXNzZXRBbW91bnQJAMwIAgAABQNuaWwFGGNsYWltaW5nUHJpY2VBc3NldEFtb3VudAUMcHJpY2VBc3NldElkBQ9vcmlnSW52ZXN0QXJyYXkFFG5ld0NsYWltUGVyaW9kSGVpZ2h0CQDMCAIFGGNsYWltaW5nUHJpY2VBc3NldEFtb3VudAkAzAgCBRZjbGFpbWluZ0lkb0Fzc2V0QW1vdW50BQNuaWwDCQAAAgUQY2xhaW1lZEFzc2V0SWQ1OAUMaWRvQXNzZXRJZDU4CQCYCgYJAMwIAgAACQDMCAIJAQEtAQUYY2xhaW1pbmdQcmljZUFzc2V0QW1vdW50CQDMCAIAAAkAzAgCBRZjbGFpbWluZ0lkb0Fzc2V0QW1vdW50BQNuaWwFFmNsYWltaW5nSWRvQXNzZXRBbW91bnQFCmlkb0Fzc2V0SWQFD29yaWdJbnZlc3RBcnJheQUUbmV3Q2xhaW1QZXJpb2RIZWlnaHQJAMwIAgUYY2xhaW1pbmdQcmljZUFzc2V0QW1vdW50CQDMCAIFFmNsYWltaW5nSWRvQXNzZXRBbW91bnQFA25pbAkAAgEJAKwCAgIVdW5zdXBwb3J0ZWQgYXNzZXRJZDogBRBjbGFpbWVkQXNzZXRJZDU4CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQ9pbnRlcm5hbENsYWltVjIEDnByaWNlQXNzZXRJZDU4DXVzZXJBZGRyZXNzNTgJb3V0QW1vdW50GXRvdGFsVXNlckF2YWlsYWJsZVRvQ2xhaW0EHnRvdGFsUGVyaW9kUHJpY2VBc3NldEFsbG93YW5jZQkBBXZhbHVlAQkAnwgBCQEXa2V5VG90YWxQZXJpb2RBbGxvd2FuY2UBBQ5wcmljZUFzc2V0SWQ1OAQddXNlclBlcmlvZFByaWNlQXNzZXRBbGxvd2FuY2UJAQV2YWx1ZQEJAJ8IAQkBFmtleVVzZXJQZXJpb2RBbGxvd2FuY2UBBQ5wcmljZUFzc2V0SWQ1OAQMcGVyaW9kTGVuZ3RoCQEFdmFsdWUBCQCfCAEJAQ9rZXlQZXJpb2RMZW5ndGgABA1jdXJyZW50UGVyaW9kCQELdmFsdWVPckVsc2UCCQCfCAEJARBrZXlDdXJyZW50UGVyaW9kAAAABBt6ZXJvUGVyaW9kRW5kSGVpZ2hJc0RlZmluZWQJAQlpc0RlZmluZWQBCQCfCAEJARJrZXlQZXJpb2RFbmRIZWlnaHQBAAAEDSR0MDEzMjc0MTUxNDQDCQBmAgUNY3VycmVudFBlcmlvZAAABBVsYXN0UGVyaW9kU3RhcnRIZWlnaHQJAQV2YWx1ZQEJAJ8IAQkBFGtleVBlcmlvZFN0YXJ0SGVpZ2h0AQUNY3VycmVudFBlcmlvZAQTbGFzdFBlcmlvZEVuZEhlaWdodAkBBXZhbHVlAQkAnwgBCQESa2V5UGVyaW9kRW5kSGVpZ2h0AQUNY3VycmVudFBlcmlvZAQNJHQwMTM1MzQxNDIzOQMJAGYCBQZoZWlnaHQFE2xhc3RQZXJpb2RFbmRIZWlnaHQEFHVwZGF0ZWRDdXJyZW50UGVyaW9kCQBkAgUNY3VycmVudFBlcmlvZAABBAtwZXJpb2RTdGFydAMJAGYCBQZoZWlnaHQJAGQCBRNsYXN0UGVyaW9kRW5kSGVpZ2h0BQxwZXJpb2RMZW5ndGgEF2Jsb2Nrc1RvTGFzdFBlcmlvZFN0YXJ0CQBqAgkAZQIFBmhlaWdodAUTbGFzdFBlcmlvZEVuZEhlaWdodAUMcGVyaW9kTGVuZ3RoAwkAAAIFF2Jsb2Nrc1RvTGFzdFBlcmlvZFN0YXJ0AAAJAGQCCQBlAgUGaGVpZ2h0BQxwZXJpb2RMZW5ndGgAAQkAZQIFBmhlaWdodAUXYmxvY2tzVG9MYXN0UGVyaW9kU3RhcnQJAGQCBRNsYXN0UGVyaW9kRW5kSGVpZ2h0AAEECXBlcmlvZEVuZAkAZQIJAGQCBQtwZXJpb2RTdGFydAUMcGVyaW9kTGVuZ3RoAAEJAJUKAwUUdXBkYXRlZEN1cnJlbnRQZXJpb2QFC3BlcmlvZFN0YXJ0BQlwZXJpb2RFbmQJAJUKAwUNY3VycmVudFBlcmlvZAUVbGFzdFBlcmlvZFN0YXJ0SGVpZ2h0BRNsYXN0UGVyaW9kRW5kSGVpZ2h0BBR1cGRhdGVkQ3VycmVudFBlcmlvZAgFDSR0MDEzNTM0MTQyMzkCXzEEC3BlcmlvZFN0YXJ0CAUNJHQwMTM1MzQxNDIzOQJfMgQJcGVyaW9kRW5kCAUNJHQwMTM1MzQxNDIzOQJfMwkAlQoDBRR1cGRhdGVkQ3VycmVudFBlcmlvZAULcGVyaW9kU3RhcnQFCXBlcmlvZEVuZAMFG3plcm9QZXJpb2RFbmRIZWlnaElzRGVmaW5lZAQVemVyb1BlcmlvZFN0YXJ0SGVpZ2h0CQEFdmFsdWUBCQCfCAEJARRrZXlQZXJpb2RTdGFydEhlaWdodAEAAAQTemVyb1BlcmlvZEVuZEhlaWdodAkBBXZhbHVlAQkAnwgBCQESa2V5UGVyaW9kRW5kSGVpZ2h0AQAABA0kdDAxNDQ5NDE0ODc2AwkAZgIFBmhlaWdodAUTemVyb1BlcmlvZEVuZEhlaWdodAQUdXBkYXRlZEN1cnJlbnRQZXJpb2QJAGQCBQ1jdXJyZW50UGVyaW9kAAEEC3BlcmlvZFN0YXJ0CQBkAgUTemVyb1BlcmlvZEVuZEhlaWdodAABBAlwZXJpb2RFbmQJAGUCCQBkAgULcGVyaW9kU3RhcnQFDHBlcmlvZExlbmd0aAABCQCVCgMFFHVwZGF0ZWRDdXJyZW50UGVyaW9kBQtwZXJpb2RTdGFydAUJcGVyaW9kRW5kCQCVCgMFDWN1cnJlbnRQZXJpb2QFFXplcm9QZXJpb2RTdGFydEhlaWdodAUTemVyb1BlcmlvZEVuZEhlaWdodAQUdXBkYXRlZEN1cnJlbnRQZXJpb2QIBQ0kdDAxNDQ5NDE0ODc2Al8xBAtwZXJpb2RTdGFydAgFDSR0MDE0NDk0MTQ4NzYCXzIECXBlcmlvZEVuZAgFDSR0MDE0NDk0MTQ4NzYCXzMJAJUKAwUUdXBkYXRlZEN1cnJlbnRQZXJpb2QFC3BlcmlvZFN0YXJ0BQlwZXJpb2RFbmQJAJUKAwUNY3VycmVudFBlcmlvZAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEUa2V5UGVyaW9kU3RhcnRIZWlnaHQBBQ1jdXJyZW50UGVyaW9kBQZoZWlnaHQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBEmtleVBlcmlvZEVuZEhlaWdodAEFDWN1cnJlbnRQZXJpb2QJAGUCCQBkAgUGaGVpZ2h0BQxwZXJpb2RMZW5ndGgAAQQUdXBkYXRlZEN1cnJlbnRQZXJpb2QIBQ0kdDAxMzI3NDE1MTQ0Al8xBAtwZXJpb2RTdGFydAgFDSR0MDEzMjc0MTUxNDQCXzIECXBlcmlvZEVuZAgFDSR0MDEzMjc0MTUxNDQCXzMEG3BlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEea2V5UGVyaW9kVG90YWxBdmFpbGFibGVUb0NsYWltAgUOcHJpY2VBc3NldElkNTgFFHVwZGF0ZWRDdXJyZW50UGVyaW9kBR50b3RhbFBlcmlvZFByaWNlQXNzZXRBbGxvd2FuY2UEGnBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltCQELdmFsdWVPckVsc2UCCQCfCAEJAR1rZXlQZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQMFDnByaWNlQXNzZXRJZDU4BRR1cGRhdGVkQ3VycmVudFBlcmlvZAUNdXNlckFkZHJlc3M1OAUddXNlclBlcmlvZFByaWNlQXNzZXRBbGxvd2FuY2UEEXByaWNlQXNzZXRCYWxhbmNlCQELdmFsdWVPckVsc2UCCQCfCAEJARRrZXlQcmljZUFzc2V0QmFsYW5jZQEFDXVzZXJBZGRyZXNzNTgAAAQZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQkAlwMBCQDMCAIJAGQCBQlvdXRBbW91bnQFEXByaWNlQXNzZXRCYWxhbmNlCQDMCAIFG3BlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQkAzAgCBRpwZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQUDbmlsBBx1c2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvCQEFdmFsdWUBCQCfCAEJAR9rZXlVc2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvAAQbcHV0T25lVGtuVjJQcmljZUFzc2V0QW1vdW50BQZzY2FsZTgEDSR0MDE1ODk5MTYxNTIKAAFACQD8BwQJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQV2YWx1ZQEJAKIIAQkBG2tleVVzZHRQcmljZUFzc2V0U3RhYmxlUG9vbAACIXB1dE9uZVRrblYyV2l0aG91dFRha2VGZWVSRUFET05MWQkAzAgCBRtwdXRPbmVUa25WMlByaWNlQXNzZXRBbW91bnQJAMwIAgUOcHJpY2VBc3NldElkNTgFA25pbAUDbmlsAwkAAQIFAUACDyhJbnQsIEludCwgSW50KQUBQAkAAgEJAKwCAgkAAwEFAUACJCBjb3VsZG4ndCBiZSBjYXN0IHRvIChJbnQsIEludCwgSW50KQMJAAACBQ0kdDAxNTg5OTE2MTUyBQ0kdDAxNTg5OTE2MTUyBAVib251cwgFDSR0MDE1ODk5MTYxNTICXzMECWZlZUFtb3VudAgFDSR0MDE1ODk5MTYxNTICXzIECGxwQW1vdW50CAUNJHQwMTU4OTkxNjE1MgJfMQQLdXNkdEFzc2V0SWQJAQV2YWx1ZQEJAKIIAQkBDmtleVVzZHRBc3NldElkAAQNJHQwMTYyMTQxNjQzMgoAAUAJAPwHBAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBBXZhbHVlAQkAoggBCQEba2V5VXNkdFByaWNlQXNzZXRTdGFibGVQb29sAAITZ2V0T25lVGtuVjJSRUFET05MWQkAzAgCBQt1c2R0QXNzZXRJZAkAzAgCBQhscEFtb3VudAUDbmlsBQNuaWwDCQABAgUBQAIKKEludCwgSW50KQUBQAkAAgEJAKwCAgkAAwEFAUACHyBjb3VsZG4ndCBiZSBjYXN0IHRvIChJbnQsIEludCkDCQAAAgUNJHQwMTYyMTQxNjQzMgUNJHQwMTYyMTQxNjQzMgQUZ2V0T25lVGtuVjJGZWVBbW91bnQIBQ0kdDAxNjIxNDE2NDMyAl8yBAp1c2R0QW1vdW50CAUNJHQwMTYyMTQxNjQzMgJfMQQaY3VycmVudFVzZHRQcmljZUFzc2V0UmF0aW8JAGsDBRtwdXRPbmVUa25WMlByaWNlQXNzZXRBbW91bnQFBnNjYWxlOAUKdXNkdEFtb3VudAQTZW5kUGVyaW9kQmxvY2tzTGVmdAkAZQIFCXBlcmlvZEVuZAUGaGVpZ2h0CQCcCgoFGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0FG3BlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQUacGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0FGXRvdGFsVXNlckF2YWlsYWJsZVRvQ2xhaW0FHHVzZHRQcmljZUFzc2V0QWxsb3dhYmxlUmF0aW8FGmN1cnJlbnRVc2R0UHJpY2VBc3NldFJhdGlvBRNlbmRQZXJpb2RCbG9ja3NMZWZ0BRR1cGRhdGVkQ3VycmVudFBlcmlvZAULcGVyaW9kU3RhcnQFCXBlcmlvZEVuZAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAAEE21hbmFnZXJWYXVsdEFkZHJlc3MJARxnZXRNYW5hZ2VyVmF1bHRBZGRyZXNzT3JUaGlzAAQHJG1hdGNoMAkAnQgCBRNtYW5hZ2VyVmF1bHRBZGRyZXNzCQETa2V5TWFuYWdlclB1YmxpY0tleQADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQDZBAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQttdXN0TWFuYWdlcgEBaQQCcGQJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQHJG1hdGNoMAkBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQAAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAnBrBQckbWF0Y2gwAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQUCcGsGBQJwZAMJAAECBQckbWF0Y2gwAgRVbml0AwkAAAIIBQFpBmNhbGxlcgUEdGhpcwYFAnBkCQACAQILTWF0Y2ggZXJyb3IBEGdldENsYWltRm9yU3RhdGUCDXVzZXJBZGRyZXNzNTgEdHhJZAQMaWRvQXNzZXRJZDU4CQCRAwIJAQ9yZWFkQ29uZmlnQXJyYXkABRBJZHhDZmdJZG9Bc3NldElkBAhpbnZlc3RvcgkAtQkCCQEFdmFsdWUBCQCiCAEJAQtrZXlJbnZlc3RvcgEFDXVzZXJBZGRyZXNzNTgFA1NFUAQTaW52ZXN0b3JUb3RhbEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGludmVzdG9yBRFJZHhJbnZUb3RhbEFtb3VudAQXaW52ZXN0b3JSZW1haW5pbmdBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhpbnZlc3RvcgUVSWR4SW52UmVtYWluaW5nQW1vdW50BBlpbnZlc3RvclByaWNlQXNzZXRCYWxhbmNlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIaW52ZXN0b3IFHUlkeEludkNsYWltZWRQcmljZUFzc2V0QW1vdW50BBdpbnZlc3Rvcklkb0Fzc2V0QmFsYW5jZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGludmVzdG9yBRtJZHhJbnZDbGFpbWVkSWRvQXNzZXRBbW91bnQEGWludmVzdG9yTGFzdENsYWltZWRIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhpbnZlc3RvcgUXSWR4SW52TGFzdENsYWltZWRIZWlnaHQEEHByaWNlQXNzZXRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFGtleVByaWNlQXNzZXRCYWxhbmNlAQUNdXNlckFkZHJlc3M1OAAABBFwcmljZUFzc2V0QWN0aW9ucwMJAQIhPQIFEHByaWNlQXNzZXRBbW91bnQAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFGtleVByaWNlQXNzZXRCYWxhbmNlAQUNdXNlckFkZHJlc3M1OAAABQNuaWwFA25pbAQaaW52ZXN0b3JLZXlSZW1haW5pbmdBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkBC3ZhbHVlT3JFbHNlAgkAoggBCQEaa2V5SW52ZXN0b3JSZW1haW5pbmdBbW91bnQBBQ11c2VyQWRkcmVzczU4AgEwBBtpbnZlc3RvcktleVJlbWFpbmluZ0FjdGlvbnMDCQECIT0CBRppbnZlc3RvcktleVJlbWFpbmluZ0Ftb3VudAAACQDMCAIJAQtTdHJpbmdFbnRyeQIJARprZXlJbnZlc3RvclJlbWFpbmluZ0Ftb3VudAEFDXVzZXJBZGRyZXNzNTgCATAFA25pbAUDbmlsBBd0b3RhbElkb0Fzc2V0U2VuZEFtb3VudAkAaAIJAGQCCQBkAgUXaW52ZXN0b3JSZW1haW5pbmdBbW91bnQFEHByaWNlQXNzZXRBbW91bnQFGmludmVzdG9yS2V5UmVtYWluaW5nQW1vdW50AGQEHHRvdGFsSWRvQXNzZXRGb3JJbnZlc3RvckRhdGEJAGgCCQBkAgUXaW52ZXN0b3JSZW1haW5pbmdBbW91bnQFGmludmVzdG9yS2V5UmVtYWluaW5nQW1vdW50AGQEC25ld0ludmVzdG9yCQC5CQIJAMwIAgIKJWQlZCVkJWQlZAkAzAgCCQCkAwEFE2ludmVzdG9yVG90YWxBbW91bnQJAMwIAgIBMAkAzAgCCQCkAwEFGWludmVzdG9yUHJpY2VBc3NldEJhbGFuY2UJAMwIAgkApAMBCQBkAgUXaW52ZXN0b3JJZG9Bc3NldEJhbGFuY2UFHHRvdGFsSWRvQXNzZXRGb3JJbnZlc3RvckRhdGEJAMwIAgkApAMBBQZoZWlnaHQFA25pbAUDU0VQBBNpbnZlc3RvckRhdGFBY3Rpb25zAwkBAiE9AgUcdG90YWxJZG9Bc3NldEZvckludmVzdG9yRGF0YQAACQDMCAIJAQtTdHJpbmdFbnRyeQIJAQtrZXlJbnZlc3RvcgEFDXVzZXJBZGRyZXNzNTgFC25ld0ludmVzdG9yBQNuaWwFA25pbAQTc2VuZElkb0Fzc2V0QWN0aW9ucwMJAQIhPQIFF3RvdGFsSWRvQXNzZXRTZW5kQW1vdW50AAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUNdXNlckFkZHJlc3M1OAUXdG90YWxJZG9Bc3NldFNlbmRBbW91bnQJANkEAQUMaWRvQXNzZXRJZDU4CQDMCAIJARpDbGFpbU9wZXJhdGlvbkhpc3RvcnlFbnRyeQQFDXVzZXJBZGRyZXNzNTgAAAUXdG90YWxJZG9Bc3NldFNlbmRBbW91bnQFBHR4SWQFA25pbAUDbmlsCQCWCgQFF2ludmVzdG9yUmVtYWluaW5nQW1vdW50BRBwcmljZUFzc2V0QW1vdW50BRppbnZlc3RvcktleVJlbWFpbmluZ0Ftb3VudAkAzQgCCQDNCAIJAM0IAgUTc2VuZElkb0Fzc2V0QWN0aW9ucwUTaW52ZXN0b3JEYXRhQWN0aW9ucwUcdG90YWxJZG9Bc3NldEZvckludmVzdG9yRGF0YQURcHJpY2VBc3NldEFjdGlvbnMHAWkBC2NvbnN0cnVjdG9yBwhpZG9TdGFydAtpZG9EdXJhdGlvbgpjbGFpbVN0YXJ0DWNsYWltRHVyYXRpb24FcHJpY2UOcHJpY2VBc3NldElkNTgPbWluSW52ZXN0QW1vdW50BAlwcmljZU11bHQJAGgCCQBoAgBkAOgHAOgHBAZpZG9FbmQJAGQCBQhpZG9TdGFydAULaWRvRHVyYXRpb24DCQEJaXNEZWZpbmVkAQkAoggBCQEJa2V5Q29uZmlnAAkAAgECE2FscmVhZHkgaW5pdGlhbGl6ZWQDCQECIT0CAiMzUE1FSEx4MWo2emVyYXJaVFlmc0dxRGVlWnFRb01weHE1UwkApQgBCAUBaQZjYWxsZXIJAAIBAg5ub3QgYXV0aG9yaXplZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQDCQBnAgUGaWRvRW5kBQpjbGFpbVN0YXJ0CQACAQImY2xhaW1TdGFydCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBpZG9FbmQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAABAppZG9Bc3NldElkCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQEDGlkb0Fzc2V0SW5mbwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFCmlkb0Fzc2V0SWQCG2ZhaWwgdG8gbG9hZCBpZG8gYXNzZXQgaW5mbwQMaWRvQXNzZXRJZDU4CQDYBAEFCmlkb0Fzc2V0SWQEDGlkb0Fzc2V0TXVsdAkAbAYACgAACAUMaWRvQXNzZXRJbmZvCGRlY2ltYWxzAAAAAAUERE9XTgQMcHJpY2VBc3NldElkCQDZBAEFDnByaWNlQXNzZXRJZDU4BA5wcmljZUFzc2V0SW5mbwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFDHByaWNlQXNzZXRJZAIdZmFpbCB0byBsb2FkIHByaWNlIGFzc2V0IGluZm8EDnByaWNlQXNzZXRNdWx0CQBsBgAKAAAIBQ5wcmljZUFzc2V0SW5mbwhkZWNpbWFscwAAAAAFBERPV04ED29yaWdUb3RhbHNBcnJheQkBGHJlYWRUb3RhbHNBcnJheU9yRGVmYXVsdAAECnRvdGFsc0RpZmYJAMwIAgAACQDMCAIAAAkAzAgCAAAJAMwIAgAABQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBCWtleUNvbmZpZwAJAQxmcm9tYXRDb25maWcMBQhpZG9TdGFydAULaWRvRHVyYXRpb24FCmNsYWltU3RhcnQFDWNsYWltRHVyYXRpb24FBXByaWNlBQlwcmljZU11bHQFDGlkb0Fzc2V0SWQ1OAUMaWRvQXNzZXRNdWx0BQ5wcmljZUFzc2V0SWQ1OAUOcHJpY2VBc3NldE11bHQFD21pbkludmVzdEFtb3VudAgFA3BtdAZhbW91bnQJAMwIAgkBC1RvdGFsc0VudHJ5BQkBCWtleVRvdGFscwAFD29yaWdUb3RhbHNBcnJheQUKdG90YWxzRGlmZgUKY2xhaW1TdGFydAAABQNuaWwBaQEGaW52ZXN0AAQIY2ZnQXJyYXkJAQ9yZWFkQ29uZmlnQXJyYXkABAhpZG9TdGFydAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BQ5JZHhDZmdJZG9TdGFydAQLaWRvRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQURSWR4Q2ZnSWRvRHVyYXRpb24EBmlkb0VuZAkAZAIFCGlkb1N0YXJ0BQtpZG9EdXJhdGlvbgQKY2xhaW1TdGFydAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRBJZHhDZmdDbGFpbVN0YXJ0BA1jbGFpbUR1cmF0aW9uCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFE0lkeENmZ0NsYWltRHVyYXRpb24EBXByaWNlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFC0lkeENmZ1ByaWNlBAlwcmljZU11bHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUPSWR4Q2ZnUHJpY2VNdWx0BAxpZG9Bc3NldElkNTgJAJEDAgUIY2ZnQXJyYXkFEElkeENmZ0lkb0Fzc2V0SWQECmlkb0Fzc2V0SWQJANkEAQUMaWRvQXNzZXRJZDU4BAxpZG9Bc3NldE11bHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUSSWR4Q2ZnSWRvQXNzZXRNdWx0BA5wcmljZUFzc2V0SWQ1OAkAkQMCBQhjZmdBcnJheQUSSWR4Q2ZnUHJpY2VBc3NldElkBAxwcmljZUFzc2V0SWQJANkEAQUOcHJpY2VBc3NldElkNTgEDnByaWNlQXNzZXRNdWx0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFFElkeENmZ1ByaWNlQXNzZXRNdWx0BA5taW5JdmVzdEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRVJZHhDZmdNaW5JbnZlc3RBbW91bnQEC3VzZXJBZGRyZXNzCQClCAEIBQFpBmNhbGxlcgMJAGYCBQhpZG9TdGFydAUGaGVpZ2h0CQACAQIcaWRvIGhhcyBub3QgYmVlbiBzdGFydGVkIHlldAMJAGYCBQZoZWlnaHQFBmlkb0VuZAkAAgECGmlkbyBoYXMgYmVlbiBhbHJlYWR5IGVuZGVkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIdZXhhY3RseSAxIHBheW1lbnQgaXMgZXhwZWN0ZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAABApwbXRBc3NldElkCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQECXBtdEFtb3VudAgFA3BtdAZhbW91bnQDCQECIT0CBQpwbXRBc3NldElkBQxwcmljZUFzc2V0SWQJAAIBCQCsAgIJAKwCAgIaaW52YWxpZCBwYXltZW50IGFzc2V0IGlkOiAJANgEAQUKcG10QXNzZXRJZAIMIGlzIGV4cGVjdGVkBBFvcmlnSW52ZXN0b3JBcnJheQkBGnJlYWRJbnZlc3RvckFycmF5T3JEZWZhdWx0AQULdXNlckFkZHJlc3MED29yaWdUb3RhbHNBcnJheQkBGHJlYWRUb3RhbHNBcnJheU9yRGVmYXVsdAAEE25ld1ByaWNlVG90YWxBbW91bnQJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPb3JpZ1RvdGFsc0FycmF5BRFJZHhJbnZUb3RhbEFtb3VudAUJcG10QW1vdW50BBZyZXF1aXJlZElkb0Fzc2V0QW1vdW50CQBoAgUTbmV3UHJpY2VUb3RhbEFtb3VudABkAwkAZgIFFnJlcXVpcmVkSWRvQXNzZXRBbW91bnQJAPAHAgUEdGhpcwUKaWRvQXNzZXRJZAkAAgECOUlETyBhc3NldCBoYXMgYmVlbiAtIHNvbGQgY29uc2lkZXIgdG8gdXNlIHNtYWxsZXIgcGF5bWVudAQKdG90YWxzRGlmZgkAzAgCBQlwbXRBbW91bnQJAMwIAgUJcG10QW1vdW50CQDMCAIAAAkAzAgCAAAFA25pbAkAzAgCCQELVG90YWxzRW50cnkFCQELa2V5SW52ZXN0b3IBBQt1c2VyQWRkcmVzcwURb3JpZ0ludmVzdG9yQXJyYXkFCnRvdGFsc0RpZmYFCmNsYWltU3RhcnQAAAkAzAgCCQELVG90YWxzRW50cnkFCQEJa2V5VG90YWxzAAUPb3JpZ1RvdGFsc0FycmF5BQp0b3RhbHNEaWZmBQpjbGFpbVN0YXJ0AAAJAMwIAgkBG0ludmVzdE9wZXJhdGlvbkhpc3RvcnlFbnRyeQQFC3VzZXJBZGRyZXNzBQlwbXRBbW91bnQAAAgFAWkNdHJhbnNhY3Rpb25JZAUDbmlsAWkBBWNsYWltAhBjbGFpbWVkQXNzZXRJZDU4DXVzZXJBZGRyZXNzNTgED2NhbGxlckFkZHJlc3M1OAkApQgBCAUBaQZjYWxsZXIDCQECIT0CBQ11c2VyQWRkcmVzczU4BQ9jYWxsZXJBZGRyZXNzNTgJAAIBAg5ub3QgYXV0aG9yaXplZAQIY2ZnQXJyYXkJAQ9yZWFkQ29uZmlnQXJyYXkABA5wcmljZUFzc2V0SWQ1OAkAkQMCBQhjZmdBcnJheQUSSWR4Q2ZnUHJpY2VBc3NldElkBBBjbGFpbVJlc3VsdFR1cGxlCQENaW50ZXJuYWxDbGFpbQMFEGNsYWltZWRBc3NldElkNTgIBQFpBmNhbGxlcggFAWkNdHJhbnNhY3Rpb25JZAQKdG90YWxzRGlmZggFEGNsYWltUmVzdWx0VHVwbGUCXzEECW91dEFtb3VudAgFEGNsYWltUmVzdWx0VHVwbGUCXzIECm91dEFzc2V0SWQIBRBjbGFpbVJlc3VsdFR1cGxlAl8zBA9vcmlnSW52ZXN0QXJyYXkIBRBjbGFpbVJlc3VsdFR1cGxlAl80BBRuZXdDbGFpbVBlcmlvZEhlaWdodAgFEGNsYWltUmVzdWx0VHVwbGUCXzUEGmNsYWltZWRQcmljZUFtb3VudEZyb21EaWZmCQCRAwIFCnRvdGFsc0RpZmYFIklkeERpZmZDbGFpbWVkUHJpY2VBbW91bnRJbmNyZW1lbnQEHWNsYWltZWRJZG9Bc3NldEFtb3VudEZyb21EaWZmCQCRAwIFCnRvdGFsc0RpZmYFJUlkeERpZmZDbGFpbWVkSWRvQXNzZXRBbW91bnRJbmNyZW1lbnQEEXByaWNlQXNzZXRCYWxhbmNlCQELdmFsdWVPckVsc2UCCQCfCAEJARRrZXlQcmljZUFzc2V0QmFsYW5jZQEFDXVzZXJBZGRyZXNzNTgAAAQScHJpY2VBc3NldERlY2ltYWxzCAkBBXZhbHVlAQkA7AcBCQDZBAEFDnByaWNlQXNzZXRJZDU4CGRlY2ltYWxzBAdlbnRyaWVzAwkAAAIFEGNsYWltZWRBc3NldElkNTgFDnByaWNlQXNzZXRJZDU4BA0kdDAyNDQ3MzI0OTE3CQEPaW50ZXJuYWxDbGFpbVYyBAUOcHJpY2VBc3NldElkNTgFDXVzZXJBZGRyZXNzNTgFCW91dEFtb3VudAkAkQMCBQp0b3RhbHNEaWZmBSJJZHhEaWZmQ2xhaW1lZFByaWNlQW1vdW50SW5jcmVtZW50BBlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltCAUNJHQwMjQ0NzMyNDkxNwJfMQQbcGVyaW9kVG90YWxBdmFpbGFibGVUb0NsYWltCAUNJHQwMjQ0NzMyNDkxNwJfMgQacGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0IBQ0kdDAyNDQ3MzI0OTE3Al8zBBl0b3RhbFVzZXJBdmFpbGFibGVUb0NsYWltCAUNJHQwMjQ0NzMyNDkxNwJfNAQcdXNkdFByaWNlQXNzZXRBbGxvd2FibGVSYXRpbwgFDSR0MDI0NDczMjQ5MTcCXzUEGmN1cnJlbnRVc2R0UHJpY2VBc3NldFJhdGlvCAUNJHQwMjQ0NzMyNDkxNwJfNgQTZW5kUGVyaW9kQmxvY2tzTGVmdAgFDSR0MDI0NDczMjQ5MTcCXzcEFHVwZGF0ZWRDdXJyZW50UGVyaW9kCAUNJHQwMjQ0NzMyNDkxNwJfOAQLcGVyaW9kU3RhcnQIBQ0kdDAyNDQ3MzI0OTE3Al85BAlwZXJpb2RFbmQIBQ0kdDAyNDQ3MzI0OTE3A18xMAQGY2hlY2tzCQDMCAIDCQBmAgUacGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0AAAYJAQh0aHJvd0VycgECOnVuYXZhaWxhYmxlIHRvIGNsYWltIGJlY2F1c2UgdXNlciBwZXJpb2QgYWxsb3dhbmNlIHJlYWNoZWQJAMwIAgMJAGYCBRtwZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0AAAYJAQh0aHJvd0VycgECO3VuYXZhaWxhYmxlIHRvIGNsYWltIGJlY2F1c2UgdG90YWwgcGVyaW9kIGFsbG93YW5jZSByZWFjaGVkCQDMCAIDCQBmAgUZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQAABgkBCHRocm93RXJyAQIQbm90aGluZyB0byBjbGFpbQkAzAgCAwkAZgIFHHVzZHRQcmljZUFzc2V0QWxsb3dhYmxlUmF0aW8FGmN1cnJlbnRVc2R0UHJpY2VBc3NldFJhdGlvBgkBCHRocm93RXJyAQJPdW5hdmFpbGFibGUgdG8gY2xhaW0gYmVjYXVzZSB1c2RuIHByaWNlIGxvd2VyIHRoYW4gdXNkdFByaWNlQXNzZXRBbGxvd2FibGVSYXRpbwkAzAgCAwMDCQECIT0CBRBjbGFpbWVkQXNzZXRJZDU4BQ5wcmljZUFzc2V0SWQ1OAYJAAACBRJjbGFpbUNsb3NpbmdIZWlnaHQAAAYJAGYCBRJjbGFpbUNsb3NpbmdIZWlnaHQFBmhlaWdodAYJAQh0aHJvd0VycgECEUNsYWltIGlzIGRpc2FibGVkBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEInVwZGF0ZWRQZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0JAGUCBRtwZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0FGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0EIXVwZGF0ZWRQZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQkAZQIFGnBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltBRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltBAdlbnRyaWVzAwkAZgIFEXByaWNlQXNzZXRCYWxhbmNlBRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQUKb3V0QXNzZXRJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFGtleVByaWNlQXNzZXRCYWxhbmNlAQUNdXNlckFkZHJlc3M1OAkAZQIFEXByaWNlQXNzZXRCYWxhbmNlBRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltBQNuaWwEDmV2YWx1YXRlUmVzdWx0CQC1CQIJAQhhc1N0cmluZwEJAPwHBAUEdGhpcwINY2xhaW1SRUFET05MWQkAzAgCBQ5wcmljZUFzc2V0SWQ1OAkAzAgCBQ11c2VyQWRkcmVzczU4BQNuaWwFA25pbAUDU0VQAwkAAAIFDmV2YWx1YXRlUmVzdWx0BQ5ldmFsdWF0ZVJlc3VsdAQbYXZhaWxhYmxlUHJpY2VBbW91bnRUb0NsYWltCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOZXZhbHVhdGVSZXN1bHQAAwQQbGFzdENsYWltRW50cmllcwMJAAACBRthdmFpbGFibGVQcmljZUFtb3VudFRvQ2xhaW0FGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0EE2ludmVzdG9yVG90YWxBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ9vcmlnSW52ZXN0QXJyYXkFEUlkeEludlRvdGFsQW1vdW50BBdpbnZlc3RvclJlbWFpbmluZ0Ftb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD29yaWdJbnZlc3RBcnJheQUVSWR4SW52UmVtYWluaW5nQW1vdW50BBlpbnZlc3RvclByaWNlQXNzZXRCYWxhbmNlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPb3JpZ0ludmVzdEFycmF5BR1JZHhJbnZDbGFpbWVkUHJpY2VBc3NldEFtb3VudAQXaW52ZXN0b3JJZG9Bc3NldEJhbGFuY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ9vcmlnSW52ZXN0QXJyYXkFG0lkeEludkNsYWltZWRJZG9Bc3NldEFtb3VudAQZaW52ZXN0b3JMYXN0Q2xhaW1lZEhlaWdodAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD29yaWdJbnZlc3RBcnJheQUXSWR4SW52TGFzdENsYWltZWRIZWlnaHQEDm5ld0ludmVzdEFycmF5CQDMCAIJAKQDAQUTaW52ZXN0b3JUb3RhbEFtb3VudAkAzAgCAgEwCQDMCAIJAKQDAQUZaW52ZXN0b3JQcmljZUFzc2V0QmFsYW5jZQkAzAgCCQCkAwEFF2ludmVzdG9ySWRvQXNzZXRCYWxhbmNlCQDMCAIJAKQDAQUZaW52ZXN0b3JMYXN0Q2xhaW1lZEhlaWdodAUDbmlsBAZ0b3RhbHMJARhyZWFkVG90YWxzQXJyYXlPckRlZmF1bHQABBF0b3RhbHNUb3RhbEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnRvdGFscwURSWR4SW52VG90YWxBbW91bnQEFXRvdGFsc1JlbWFpbmluZ0Ftb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnRvdGFscwUVSWR4SW52UmVtYWluaW5nQW1vdW50BB10b3RhbHNDbGFpbWVkUHJpY2VBc3NldEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnRvdGFscwUdSWR4SW52Q2xhaW1lZFByaWNlQXNzZXRBbW91bnQEG3RvdGFsc0NsYWltZWRJZG9Bc3NldEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnRvdGFscwUbSWR4SW52Q2xhaW1lZElkb0Fzc2V0QW1vdW50BBd0b3RhbHNMYXN0Q2xhaW1lZEhlaWdodAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnRvdGFscwUXSWR4SW52TGFzdENsYWltZWRIZWlnaHQEGG5ld1RvdGFsc1JlbWFpbmluZ0Ftb3VudAkAZQIFFXRvdGFsc1JlbWFpbmluZ0Ftb3VudAUXaW52ZXN0b3JSZW1haW5pbmdBbW91bnQEDW5ld1RvdGFsQXJyYXkJAMwIAgkApAMBBRF0b3RhbHNUb3RhbEFtb3VudAkAzAgCCQCkAwEFGG5ld1RvdGFsc1JlbWFpbmluZ0Ftb3VudAkAzAgCCQCkAwEFHXRvdGFsc0NsYWltZWRQcmljZUFzc2V0QW1vdW50CQDMCAIJAKQDAQUbdG90YWxzQ2xhaW1lZElkb0Fzc2V0QW1vdW50CQDMCAIJAKQDAQUXdG90YWxzTGFzdENsYWltZWRIZWlnaHQFA25pbAQXbmV3VG90YWxSZW1haW5pbmdBbW91bnQJAGQCCQELdmFsdWVPckVsc2UCCQCfCAEJARdrZXlUb3RhbFJlbWFpbmluZ0Ftb3VudAAAAAUXaW52ZXN0b3JSZW1haW5pbmdBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBGmtleUludmVzdG9yUmVtYWluaW5nQW1vdW50AQUNdXNlckFkZHJlc3M1OAkApAMBBRdpbnZlc3RvclJlbWFpbmluZ0Ftb3VudAkAzAgCCQELU3RyaW5nRW50cnkCCQEXa2V5VG90YWxSZW1haW5pbmdBbW91bnQACQCkAwEFF25ld1RvdGFsUmVtYWluaW5nQW1vdW50CQDMCAIJAQtUb3RhbHNFbnRyeQUJAQtrZXlJbnZlc3RvcgEFDXVzZXJBZGRyZXNzNTgFDm5ld0ludmVzdEFycmF5BQp0b3RhbHNEaWZmBRRuZXdDbGFpbVBlcmlvZEhlaWdodAAACQDMCAIJAQtUb3RhbHNFbnRyeQUJAQlrZXlUb3RhbHMABQ1uZXdUb3RhbEFycmF5BQp0b3RhbHNEaWZmBRRuZXdDbGFpbVBlcmlvZEhlaWdodAAABQNuaWwJAMwIAgkBC1RvdGFsc0VudHJ5BQkBC2tleUludmVzdG9yAQUNdXNlckFkZHJlc3M1OAUPb3JpZ0ludmVzdEFycmF5BQp0b3RhbHNEaWZmBRRuZXdDbGFpbVBlcmlvZEhlaWdodAAACQDMCAIJAQtUb3RhbHNFbnRyeQUJAQlrZXlUb3RhbHMACQEYcmVhZFRvdGFsc0FycmF5T3JEZWZhdWx0AAUKdG90YWxzRGlmZgUUbmV3Q2xhaW1QZXJpb2RIZWlnaHQAAAUDbmlsBBh1cGRhdGVkUHJpY2VBc3NldEJhbGFuY2UJAGUCCQBkAgURcHJpY2VBc3NldEJhbGFuY2UFCW91dEFtb3VudAUZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQkAzggCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQUKb3V0QXNzZXRJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFGtleVByaWNlQXNzZXRCYWxhbmNlAQUNdXNlckFkZHJlc3M1OAUYdXBkYXRlZFByaWNlQXNzZXRCYWxhbmNlBQNuaWwFEGxhc3RDbGFpbUVudHJpZXMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEQa2V5Q3VycmVudFBlcmlvZAAFFHVwZGF0ZWRDdXJyZW50UGVyaW9kCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEUa2V5UGVyaW9kU3RhcnRIZWlnaHQBBRR1cGRhdGVkQ3VycmVudFBlcmlvZAULcGVyaW9kU3RhcnQJAMwIAgkBDEludGVnZXJFbnRyeQIJARJrZXlQZXJpb2RFbmRIZWlnaHQBBRR1cGRhdGVkQ3VycmVudFBlcmlvZAUJcGVyaW9kRW5kCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEea2V5UGVyaW9kVG90YWxBdmFpbGFibGVUb0NsYWltAgUOcHJpY2VBc3NldElkNTgFFHVwZGF0ZWRDdXJyZW50UGVyaW9kBSJ1cGRhdGVkUGVyaW9kVG90YWxBdmFpbGFibGVUb0NsYWltCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEda2V5UGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0DBQ5wcmljZUFzc2V0SWQ1OAUUdXBkYXRlZEN1cnJlbnRQZXJpb2QFDXVzZXJBZGRyZXNzNTgFIXVwZGF0ZWRQZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQkAzAgCCQEaQ2xhaW1PcGVyYXRpb25IaXN0b3J5RW50cnkEBQ11c2VyQWRkcmVzczU4BRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltBR1jbGFpbWVkSWRvQXNzZXRBbW91bnRGcm9tRGlmZggFAWkNdHJhbnNhY3Rpb25JZAUDbmlsBQdlbnRyaWVzBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBBxwcmljZUFzc2V0QmFsYW5jZUlkb0RlY2ltYWxzCQBrAwURcHJpY2VBc3NldEJhbGFuY2UFBnNjYWxlOAkAbAYACgAABRJwcmljZUFzc2V0RGVjaW1hbHMAAAAABQRET1dOCQCUCgIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQBkAgUJb3V0QW1vdW50BRxwcmljZUFzc2V0QmFsYW5jZUlkb0RlY2ltYWxzBQpvdXRBc3NldElkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEUa2V5UHJpY2VBc3NldEJhbGFuY2UBBQ11c2VyQWRkcmVzczU4AAAJAMwIAgkBC1RvdGFsc0VudHJ5BQkBC2tleUludmVzdG9yAQUNdXNlckFkZHJlc3M1OAUPb3JpZ0ludmVzdEFycmF5BQp0b3RhbHNEaWZmBRRuZXdDbGFpbVBlcmlvZEhlaWdodAURcHJpY2VBc3NldEJhbGFuY2UJAMwIAgkBC1RvdGFsc0VudHJ5BQkBCWtleVRvdGFscwAJARhyZWFkVG90YWxzQXJyYXlPckRlZmF1bHQABQp0b3RhbHNEaWZmBRRuZXdDbGFpbVBlcmlvZEhlaWdodAURcHJpY2VBc3NldEJhbGFuY2UJAMwIAgkBGkNsYWltT3BlcmF0aW9uSGlzdG9yeUVudHJ5BAUNdXNlckFkZHJlc3M1OAUaY2xhaW1lZFByaWNlQW1vdW50RnJvbURpZmYJAGQCBR1jbGFpbWVkSWRvQXNzZXRBbW91bnRGcm9tRGlmZgUccHJpY2VBc3NldEJhbGFuY2VJZG9EZWNpbWFscwgFAWkNdHJhbnNhY3Rpb25JZAUDbmlsBQR1bml0BQdlbnRyaWVzAWkBEmNsZWFuUmVtYWluZ0Ftb3VudAENdXNlckFkZHJlc3M1OAQOcHJpY2VBc3NldElkNTgJAJEDAgkBD3JlYWRDb25maWdBcnJheQAFEklkeENmZ1ByaWNlQXNzZXRJZAQOZXZhbHVhdGVSZXN1bHQJALUJAgkBCGFzU3RyaW5nAQkA/AcEBQR0aGlzAg1jbGFpbVJFQURPTkxZCQDMCAIFDnByaWNlQXNzZXRJZDU4CQDMCAIFDXVzZXJBZGRyZXNzNTgFA25pbAUDbmlsBQNTRVADCQAAAgUOZXZhbHVhdGVSZXN1bHQFDmV2YWx1YXRlUmVzdWx0BBthdmFpbGFibGVQcmljZUFtb3VudFRvQ2xhaW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5ldmFsdWF0ZVJlc3VsdAACBBRjaGVja1VuY2xhaW1lZEFzc2V0cwMJAAACBRthdmFpbGFibGVQcmljZUFtb3VudFRvQ2xhaW0AAAYJAQh0aHJvd0VycgECGnVzZXIgaGF2ZSB1bmNsYWltZWQgYXNzZXRzAwkAAAIFFGNoZWNrVW5jbGFpbWVkQXNzZXRzBRRjaGVja1VuY2xhaW1lZEFzc2V0cwQIaW52ZXN0b3IJALUJAgkBBXZhbHVlAQkAoggBCQELa2V5SW52ZXN0b3IBBQ11c2VyQWRkcmVzczU4BQNTRVAEE2ludmVzdG9yVG90YWxBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhpbnZlc3RvcgURSWR4SW52VG90YWxBbW91bnQEF2ludmVzdG9yUmVtYWluaW5nQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIaW52ZXN0b3IFFUlkeEludlJlbWFpbmluZ0Ftb3VudAQZaW52ZXN0b3JQcmljZUFzc2V0QmFsYW5jZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGludmVzdG9yBR1JZHhJbnZDbGFpbWVkUHJpY2VBc3NldEFtb3VudAQXaW52ZXN0b3JJZG9Bc3NldEJhbGFuY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhpbnZlc3RvcgUbSWR4SW52Q2xhaW1lZElkb0Fzc2V0QW1vdW50BBlpbnZlc3Rvckxhc3RDbGFpbWVkSGVpZ2h0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIaW52ZXN0b3IFF0lkeEludkxhc3RDbGFpbWVkSGVpZ2h0BBxpbnZlc3RvclJlbWFpbmluZ0Ftb3VudENoZWNrAwkBAiE9AgUXaW52ZXN0b3JSZW1haW5pbmdBbW91bnQAAAYJAQh0aHJvd0VycgECJGludmVzdG9yUmVtYWluaW5nQW1vdW50IGFscmVhZHkgemVybwMJAAACBRxpbnZlc3RvclJlbWFpbmluZ0Ftb3VudENoZWNrBRxpbnZlc3RvclJlbWFpbmluZ0Ftb3VudENoZWNrBAtuZXdJbnZlc3RvcgkAuQkCCQDMCAICCiVkJWQlZCVkJWQJAMwIAgkApAMBBRNpbnZlc3RvclRvdGFsQW1vdW50CQDMCAICATAJAMwIAgkApAMBBRlpbnZlc3RvclByaWNlQXNzZXRCYWxhbmNlCQDMCAIJAKQDAQUXaW52ZXN0b3JJZG9Bc3NldEJhbGFuY2UJAMwIAgkApAMBBRlpbnZlc3Rvckxhc3RDbGFpbWVkSGVpZ2h0BQNuaWwFA1NFUAQGdG90YWxzCQC1CQIJAQV2YWx1ZQEJAKIIAQkBCWtleVRvdGFscwAFA1NFUAQRdG90YWxzVG90YWxBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFEUlkeEludlRvdGFsQW1vdW50BBV0b3RhbHNSZW1haW5pbmdBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFFUlkeEludlJlbWFpbmluZ0Ftb3VudAQddG90YWxzQ2xhaW1lZFByaWNlQXNzZXRBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFHUlkeEludkNsYWltZWRQcmljZUFzc2V0QW1vdW50BBt0b3RhbHNDbGFpbWVkSWRvQXNzZXRBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFG0lkeEludkNsYWltZWRJZG9Bc3NldEFtb3VudAQXdG90YWxzTGFzdENsYWltZWRIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFF0lkeEludkxhc3RDbGFpbWVkSGVpZ2h0BAluZXdUb3RhbHMJALkJAgkAzAgCAgolZCVkJWQlZCVkCQDMCAIJAKQDAQURdG90YWxzVG90YWxBbW91bnQJAMwIAgkApAMBCQBlAgUVdG90YWxzUmVtYWluaW5nQW1vdW50BRdpbnZlc3RvclJlbWFpbmluZ0Ftb3VudAkAzAgCCQCkAwEFHXRvdGFsc0NsYWltZWRQcmljZUFzc2V0QW1vdW50CQDMCAIJAKQDAQUbdG90YWxzQ2xhaW1lZElkb0Fzc2V0QW1vdW50CQDMCAIJAKQDAQUXdG90YWxzTGFzdENsYWltZWRIZWlnaHQFA25pbAUDU0VQBBduZXdUb3RhbFJlbWFpbmluZ0Ftb3VudAkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBF2tleVRvdGFsUmVtYWluaW5nQW1vdW50AAAABRdpbnZlc3RvclJlbWFpbmluZ0Ftb3VudAkAzAgCCQELU3RyaW5nRW50cnkCCQEaa2V5SW52ZXN0b3JSZW1haW5pbmdBbW91bnQBBQ11c2VyQWRkcmVzczU4CQCkAwEFF2ludmVzdG9yUmVtYWluaW5nQW1vdW50CQDMCAIJAQtTdHJpbmdFbnRyeQIJARdrZXlUb3RhbFJlbWFpbmluZ0Ftb3VudAAJAKQDAQUXbmV3VG90YWxSZW1haW5pbmdBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBC2tleUludmVzdG9yAQUNdXNlckFkZHJlc3M1OAULbmV3SW52ZXN0b3IJAMwIAgkBC1N0cmluZ0VudHJ5AgkBCWtleVRvdGFscwAFCW5ld1RvdGFscwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCGNsYWltRm9yAQ11c2VyQWRkcmVzczU4BQNuaWwBaQENY2xhaW1SRUFET05MWQIQY2xhaW1lZEFzc2V0SWQ1OA11c2VyQWRkcmVzczU4BBBjbGFpbVJlc3VsdFR1cGxlCQENaW50ZXJuYWxDbGFpbQMFEGNsYWltZWRBc3NldElkNTgJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDXVzZXJBZGRyZXNzNTgJANkEAQIABAp0b3RhbHNEaWZmCAUQY2xhaW1SZXN1bHRUdXBsZQJfMQQJb3V0QW1vdW50CAUQY2xhaW1SZXN1bHRUdXBsZQJfMgQKb3V0QXNzZXRJZAgFEGNsYWltUmVzdWx0VHVwbGUCXzMED29yaWdJbnZlc3RBcnJheQgFEGNsYWltUmVzdWx0VHVwbGUCXzQEFG5ld0NsYWltUGVyaW9kSGVpZ2h0CAUQY2xhaW1SZXN1bHRUdXBsZQJfNQQVYXZhaWxhYmxlVG9DbGFpbUFycmF5CAUQY2xhaW1SZXN1bHRUdXBsZQJfNgQbYXZhaWxhYmxlUHJpY2VBbW91bnRUb0NsYWltCQCRAwIFFWF2YWlsYWJsZVRvQ2xhaW1BcnJheQAABBlhdmFpbGFibGVJZG9BbW91bnRUb0NsYWltCQCRAwIFFWF2YWlsYWJsZVRvQ2xhaW1BcnJheQABCQCUCgIFA25pbAkAuQkCCQDMCAICBiVzJWQlZAkAzAgCBQ11c2VyQWRkcmVzczU4CQDMCAIJAKQDAQUbYXZhaWxhYmxlUHJpY2VBbW91bnRUb0NsYWltCQDMCAIJAKQDAQUZYXZhaWxhYmxlSWRvQW1vdW50VG9DbGFpbQUDbmlsBQNTRVABaQEPY2xhaW1WMlJFQURPTkxZAhBjbGFpbWVkQXNzZXRJZDU4DXVzZXJBZGRyZXNzNTgEEGNsYWltUmVzdWx0VHVwbGUJAQ1pbnRlcm5hbENsYWltAwUQY2xhaW1lZEFzc2V0SWQ1OAkBEUBleHRyTmF0aXZlKDEwNjIpAQUNdXNlckFkZHJlc3M1OAkA2QQBAgAECnRvdGFsc0RpZmYIBRBjbGFpbVJlc3VsdFR1cGxlAl8xBAlvdXRBbW91bnQIBRBjbGFpbVJlc3VsdFR1cGxlAl8yBApvdXRBc3NldElkCAUQY2xhaW1SZXN1bHRUdXBsZQJfMwQPb3JpZ0ludmVzdEFycmF5CAUQY2xhaW1SZXN1bHRUdXBsZQJfNAQUbmV3Q2xhaW1QZXJpb2RIZWlnaHQIBRBjbGFpbVJlc3VsdFR1cGxlAl81BBVhdmFpbGFibGVUb0NsYWltQXJyYXkIBRBjbGFpbVJlc3VsdFR1cGxlAl82BBthdmFpbGFibGVQcmljZUFtb3VudFRvQ2xhaW0JAJEDAgUVYXZhaWxhYmxlVG9DbGFpbUFycmF5AAAEGWF2YWlsYWJsZUlkb0Ftb3VudFRvQ2xhaW0JAJEDAgUVYXZhaWxhYmxlVG9DbGFpbUFycmF5AAEECGNmZ0FycmF5CQEPcmVhZENvbmZpZ0FycmF5AAQOcHJpY2VBc3NldElkNTgJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ1ByaWNlQXNzZXRJZAQRcHJpY2VBc3NldEJhbGFuY2UJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFGtleVByaWNlQXNzZXRCYWxhbmNlAQUNdXNlckFkZHJlc3M1OAAABBxwcmljZUFzc2V0QmFsYW5jZUlkb0RlY2ltYWxzCQBoAgURcHJpY2VBc3NldEJhbGFuY2UAZAQuYXZhaWxhYmxlSWRvQW1vdW50VG9DbGFpbVdpdGhQcmljZUFzc2V0QmFsYW5jZQkAZAIFGWF2YWlsYWJsZUlkb0Ftb3VudFRvQ2xhaW0FHHByaWNlQXNzZXRCYWxhbmNlSWRvRGVjaW1hbHMEDSR0MDM2MzY0MzY3NzYJAQ9pbnRlcm5hbENsYWltVjIEBQ5wcmljZUFzc2V0SWQ1OAUNdXNlckFkZHJlc3M1OAUJb3V0QW1vdW50CQCRAwIFCnRvdGFsc0RpZmYFIklkeERpZmZDbGFpbWVkUHJpY2VBbW91bnRJbmNyZW1lbnQEGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0IBQ0kdDAzNjM2NDM2Nzc2Al8xBBtwZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0IBQ0kdDAzNjM2NDM2Nzc2Al8yBBpwZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQgFDSR0MDM2MzY0MzY3NzYCXzMEGXRvdGFsVXNlckF2YWlsYWJsZVRvQ2xhaW0IBQ0kdDAzNjM2NDM2Nzc2Al80BBx1c2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvCAUNJHQwMzYzNjQzNjc3NgJfNQQaY3VycmVudFVzZHRQcmljZUFzc2V0UmF0aW8IBQ0kdDAzNjM2NDM2Nzc2Al82BBNlbmRQZXJpb2RCbG9ja3NMZWZ0CAUNJHQwMzYzNjQzNjc3NgJfNwQUdXBkYXRlZEN1cnJlbnRQZXJpb2QIBQ0kdDAzNjM2NDM2Nzc2Al84BAtwZXJpb2RTdGFydAgFDSR0MDM2MzY0MzY3NzYCXzkECXBlcmlvZEVuZAgFDSR0MDM2MzY0MzY3NzYDXzEwBBZjdXJyZW50UGVyaW9kRW5kSGVpZ2h0CQELdmFsdWVPckVsc2UCCQCfCAEJARJrZXlQZXJpb2RFbmRIZWlnaHQBBRR1cGRhdGVkQ3VycmVudFBlcmlvZAAABBp1c2VyVG90YWxQcmljZUFzc2V0Q2xhaW1lZAkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQEXcmVhZEludmVzdG9yQXJyYXlPckZhaWwBBQ11c2VyQWRkcmVzczU4BR1JZHhJbnZDbGFpbWVkUHJpY2VBc3NldEFtb3VudAURcHJpY2VBc3NldEJhbGFuY2UEDHJlc3VsdFN0cmluZwMJAGYCBQZoZWlnaHQFFmN1cnJlbnRQZXJpb2RFbmRIZWlnaHQEDHBlcmlvZExlbmdodAkBBXZhbHVlAQkAnwgBCQEPa2V5UGVyaW9kTGVuZ3RoAAQTdXNlclBlcmlvZEFsbG93YW5jZQkBBXZhbHVlAQkAnwgBCQEWa2V5VXNlclBlcmlvZEFsbG93YW5jZQEFDnByaWNlQXNzZXRJZDU4BBR0b3RhbFBlcmlvZEFsbG93YW5jZQkBBXZhbHVlAQkAnwgBCQEXa2V5VG90YWxQZXJpb2RBbGxvd2FuY2UBBQ5wcmljZUFzc2V0SWQ1OAkAuQkCCQDMCAICDCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFLmF2YWlsYWJsZUlkb0Ftb3VudFRvQ2xhaW1XaXRoUHJpY2VBc3NldEJhbGFuY2UJAMwIAgkApAMBBRN1c2VyUGVyaW9kQWxsb3dhbmNlCQDMCAIJAKQDAQUUdG90YWxQZXJpb2RBbGxvd2FuY2UJAMwIAgkApAMBBRx1c2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvCQDMCAIJAKQDAQUaY3VycmVudFVzZHRQcmljZUFzc2V0UmF0aW8JAMwIAgkApAMBBQxwZXJpb2RMZW5naHQJAMwIAgkApAMBBRp1c2VyVG90YWxQcmljZUFzc2V0Q2xhaW1lZAUDbmlsBQNTRVAJALkJAgkAzAgCAgwlZCVkJWQlZCVkJWQJAMwIAgkApAMBBS5hdmFpbGFibGVJZG9BbW91bnRUb0NsYWltV2l0aFByaWNlQXNzZXRCYWxhbmNlCQDMCAIJAKQDAQUZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQkAzAgCCQCkAwEFG3BlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQkAzAgCCQCkAwEFHHVzZHRQcmljZUFzc2V0QWxsb3dhYmxlUmF0aW8JAMwIAgkApAMBBRpjdXJyZW50VXNkdFByaWNlQXNzZXRSYXRpbwkAzAgCCQCkAwEFE2VuZFBlcmlvZEJsb2Nrc0xlZnQJAMwIAgkApAMBBRp1c2VyVG90YWxQcmljZUFzc2V0Q2xhaW1lZAUDbmlsBQNTRVAJAJQKAgUDbmlsBQxyZXN1bHRTdHJpbmcBAnR4AQZ2ZXJpZnkABA90YXJnZXRQdWJsaWNLZXkEByRtYXRjaDAJARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAUCcGsDCQABAgUHJG1hdGNoMAIEVW5pdAgFAnR4D3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQ90YXJnZXRQdWJsaWNLZXnKz0/4", "height": 2932675, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5K7YBBJB538Ra3ayki3hxRNj6FnXkw4KpTTNBM4Y1uWh Next: 61gVU26J8oJzWPLd7WND7RTDF6sEwiM1rM6ypjy4SqYk Diff:
OldNewDifferences
384384 let investorPriceAssetBalance = parseIntValue(investor[IdxInvClaimedPriceAssetAmount])
385385 let investorIdoAssetBalance = parseIntValue(investor[IdxInvClaimedIdoAssetAmount])
386386 let investorLastClaimedHeight = parseIntValue(investor[IdxInvLastClaimedHeight])
387- let $t01793418146 = match getInteger(keyPriceAssetBalance(userAddress58)) {
388- case t: Int =>
389- $Tuple2(t, [IntegerEntry(keyPriceAssetBalance(userAddress58), 0)])
390- case _ =>
391- $Tuple2(0, nil)
392- }
393- let priceAssetAmount = $t01793418146._1
394- let priceAssetActions = $t01793418146._2
395- let $t01815018413 = match getString(keyInvestorRemainingAmount(userAddress58)) {
396- case t: String =>
397- $Tuple2(parseIntValue(t), [StringEntry(keyInvestorRemainingAmount(userAddress58), "0")])
398- case _ =>
399- $Tuple2(0, nil)
400- }
401- let investorKeyRemainingAmount = $t01815018413._1
402- let investorKeyRemainingActions = $t01815018413._2
387+ let priceAssetAmount = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
388+ let priceAssetActions = if ((priceAssetAmount != 0))
389+ then [IntegerEntry(keyPriceAssetBalance(userAddress58), 0)]
390+ else nil
391+ let investorKeyRemainingAmount = parseIntValue(valueOrElse(getString(keyInvestorRemainingAmount(userAddress58)), "0"))
392+ let investorKeyRemainingActions = if ((investorKeyRemainingAmount != 0))
393+ then [StringEntry(keyInvestorRemainingAmount(userAddress58), "0")]
394+ else nil
403395 let totalIdoAssetSendAmount = (((investorRemainingAmount + priceAssetAmount) + investorKeyRemainingAmount) * 100)
404396 let totalIdoAssetForInvestorData = ((investorRemainingAmount + investorKeyRemainingAmount) * 100)
405397 let newInvestor = makeString(["%d%d%d%d%d", toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString((investorIdoAssetBalance + totalIdoAssetForInvestorData)), toString(height)], SEP)
407399 then [StringEntry(keyInvestor(userAddress58), newInvestor)]
408400 else nil
409401 let sendIdoAssetActions = if ((totalIdoAssetSendAmount != 0))
410- then [ScriptTransfer(addressFromStringValue(userAddress58), totalIdoAssetSendAmount, fromBase58String(idoAssetId58))]
402+ then [ScriptTransfer(addressFromStringValue(userAddress58), totalIdoAssetSendAmount, fromBase58String(idoAssetId58)), ClaimOperationHistoryEntry(userAddress58, 0, totalIdoAssetSendAmount, txId)]
411403 else nil
412- let historyActions = ClaimOperationHistoryEntry(userAddress58, 0, totalIdoAssetSendAmount, txId)
413- $Tuple4(investorRemainingAmount, priceAssetAmount, investorKeyRemainingAmount, ((((sendIdoAssetActions :+ investorDataActions) :+ totalIdoAssetForInvestorData) :+ priceAssetActions) :+ historyActions))
404+ $Tuple4(investorRemainingAmount, priceAssetAmount, investorKeyRemainingAmount, (((sendIdoAssetActions :+ investorDataActions) :+ totalIdoAssetForInvestorData) :+ priceAssetActions))
414405 }
415406
416407
510501 let priceAssetDecimals = value(assetInfo(fromBase58String(priceAssetId58))).decimals
511502 let entries = if ((claimedAssetId58 == priceAssetId58))
512503 then {
513- let $t02448324927 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
514- let periodMinAvailableToClaim = $t02448324927._1
515- let periodTotalAvailableToClaim = $t02448324927._2
516- let periodUserAvailableToClaim = $t02448324927._3
517- let totalUserAvailableToClaim = $t02448324927._4
518- let usdtPriceAssetAllowableRatio = $t02448324927._5
519- let currentUsdtPriceAssetRatio = $t02448324927._6
520- let endPeriodBlocksLeft = $t02448324927._7
521- let updatedCurrentPeriod = $t02448324927._8
522- let periodStart = $t02448324927._9
523- let periodEnd = $t02448324927._10
504+ let $t02447324917 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
505+ let periodMinAvailableToClaim = $t02447324917._1
506+ let periodTotalAvailableToClaim = $t02447324917._2
507+ let periodUserAvailableToClaim = $t02447324917._3
508+ let totalUserAvailableToClaim = $t02447324917._4
509+ let usdtPriceAssetAllowableRatio = $t02447324917._5
510+ let currentUsdtPriceAssetRatio = $t02447324917._6
511+ let endPeriodBlocksLeft = $t02447324917._7
512+ let updatedCurrentPeriod = $t02447324917._8
513+ let periodStart = $t02447324917._9
514+ let periodEnd = $t02447324917._10
524515 let checks = [if ((periodUserAvailableToClaim > 0))
525516 then true
526517 else throwErr("unavailable to claim because user period allowance reached"), if ((periodTotalAvailableToClaim > 0))
666657 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
667658 let priceAssetBalanceIdoDecimals = (priceAssetBalance * 100)
668659 let availableIdoAmountToClaimWithPriceAssetBalance = (availableIdoAmountToClaim + priceAssetBalanceIdoDecimals)
669- let $t03637436786 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
670- let periodMinAvailableToClaim = $t03637436786._1
671- let periodTotalAvailableToClaim = $t03637436786._2
672- let periodUserAvailableToClaim = $t03637436786._3
673- let totalUserAvailableToClaim = $t03637436786._4
674- let usdtPriceAssetAllowableRatio = $t03637436786._5
675- let currentUsdtPriceAssetRatio = $t03637436786._6
676- let endPeriodBlocksLeft = $t03637436786._7
677- let updatedCurrentPeriod = $t03637436786._8
678- let periodStart = $t03637436786._9
679- let periodEnd = $t03637436786._10
660+ let $t03636436776 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
661+ let periodMinAvailableToClaim = $t03636436776._1
662+ let periodTotalAvailableToClaim = $t03636436776._2
663+ let periodUserAvailableToClaim = $t03636436776._3
664+ let totalUserAvailableToClaim = $t03636436776._4
665+ let usdtPriceAssetAllowableRatio = $t03636436776._5
666+ let currentUsdtPriceAssetRatio = $t03636436776._6
667+ let endPeriodBlocksLeft = $t03636436776._7
668+ let updatedCurrentPeriod = $t03636436776._8
669+ let periodStart = $t03636436776._9
670+ let periodEnd = $t03636436776._10
680671 let currentPeriodEndHeight = valueOrElse(getInteger(keyPeriodEndHeight(updatedCurrentPeriod)), 0)
681672 let userTotalPriceAssetClaimed = (parseIntValue(readInvestorArrayOrFail(userAddress58)[IdxInvClaimedPriceAssetAmount]) - priceAssetBalance)
682673 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 keyManagerVaultAddress () = "%s__managerVaultAddress"
144144
145145
146146 func keyClaimClosingHeight () = "%s__claimClosingHeight"
147147
148148
149149 let claimClosingHeight = valueOrElse(getInteger(this, keyClaimClosingHeight()), 0)
150150
151151 func readConfigArray () = split(getStringOrFail(keyConfig()), SEP)
152152
153153
154154 func readTotalsArrayOrDefaultByCustomKey (customKey) = split(valueOrElse(getString(customKey), formatInvestorS("0", "0", "0", "0", "0")), SEP)
155155
156156
157157 func readTotalsArrayOrDefault () = readTotalsArrayOrDefaultByCustomKey(keyTotals())
158158
159159
160160 func readInvestorArrayOrDefault (userAddress) = readTotalsArrayOrDefaultByCustomKey(keyInvestor(userAddress))
161161
162162
163163 func readInvestorArrayOrFail (userAddress) = split(getStringOrFail(keyInvestor(userAddress)), SEP)
164164
165165
166166 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
167167 case s: String =>
168168 addressFromStringValue(s)
169169 case _ =>
170170 this
171171 }
172172
173173
174174 let IdxDiffTotalIncrement = 0
175175
176176 let IdxDiffRemainingPriceAmountIncrement = 1
177177
178178 let IdxDiffClaimedPriceAmountIncrement = 2
179179
180180 let IdxDiffClaimedIdoAssetAmountIncrement = 3
181181
182182 func TotalsEntry (key,origArray,incrementDiff,newLastClaimedHeight,priceAssetBalance) = {
183183 let totalAmount = parseIntValue(origArray[IdxInvTotalAmount])
184184 let remainingAmount = parseIntValue(origArray[IdxInvRemainingAmount])
185185 let claimedPriceAssetAmount = parseIntValue(origArray[IdxInvClaimedPriceAssetAmount])
186186 let claimedIdoAssetAmount = parseIntValue(origArray[IdxInvClaimedIdoAssetAmount])
187187 let lastClaimedHeight = parseIntValue(origArray[IdxInvLastClaimedHeight])
188188 let newTotalAmount = (totalAmount + incrementDiff[IdxDiffTotalIncrement])
189189 let newRemainingAmount = (remainingAmount + incrementDiff[IdxDiffRemainingPriceAmountIncrement])
190190 let cfgArray = readConfigArray()
191191 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
192192 let priceAssetDecimals = value(assetInfo(fromBase58String(priceAssetId58))).decimals
193193 let priceAssetBalancePriceAssetDecimals = fraction(priceAssetBalance, scale8, pow(10, 0, priceAssetDecimals, 0, 0, DOWN))
194194 let newClaimedPriceAssetAmount = ((claimedPriceAssetAmount + incrementDiff[IdxDiffClaimedPriceAmountIncrement]) - priceAssetBalance)
195195 let newClaimedIdoAssetAmount = ((claimedIdoAssetAmount + incrementDiff[IdxDiffClaimedIdoAssetAmountIncrement]) + priceAssetBalancePriceAssetDecimals)
196196 let entries = if ((0 > newRemainingAmount))
197197 then {
198198 let diff = ((newTotalAmount - newClaimedPriceAssetAmount) - newClaimedIdoAssetAmount)
199199 let newLogicRemainingAmount = if ((0 > diff))
200200 then 0
201201 else diff
202202 StringEntry(key, formatInvestor(newTotalAmount, newLogicRemainingAmount, newClaimedPriceAssetAmount, newClaimedIdoAssetAmount, newLastClaimedHeight))
203203 }
204204 else StringEntry(key, formatInvestor(newTotalAmount, newRemainingAmount, newClaimedPriceAssetAmount, newClaimedIdoAssetAmount, newLastClaimedHeight))
205205 entries
206206 }
207207
208208
209209 func InvestOperationHistoryEntry (userAddress,priceAssetAmount,idoAssetAmount,txId) = StringEntry(keyOperationHistoryRecord("invest", userAddress, toBase58String(txId)), formatHistoryRecord(priceAssetAmount, idoAssetAmount))
210210
211211
212212 func ClaimOperationHistoryEntry (userAddress,priceAssetAmount,idoAssetAmount,txId) = StringEntry(keyOperationHistoryRecord("claim", userAddress, toBase58String(txId)), formatHistoryRecord(priceAssetAmount, idoAssetAmount))
213213
214214
215215 func internalClaim (claimedAssetId58,userAddress,txId) = {
216216 let cfgArray = readConfigArray()
217217 let claimStart = parseIntValue(cfgArray[IdxCfgClaimStart])
218218 let claimDuration = parseIntValue(cfgArray[IdxCfgClaimDuration])
219219 let claimEnd = (claimStart + claimDuration)
220220 let price = parseIntValue(cfgArray[IdxCfgPrice])
221221 let priceMult = parseIntValue(cfgArray[IdxCfgPriceMult])
222222 let idoAssetId58 = cfgArray[IdxCfgIdoAssetId]
223223 let idoAssetId = fromBase58String(idoAssetId58)
224224 let idoAssetMult = parseIntValue(cfgArray[IdxCfgIdoAssetMult])
225225 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
226226 let priceAssetId = fromBase58String(priceAssetId58)
227227 let priceAssetMult = parseIntValue(cfgArray[IdxCfgPriceAssetMult])
228228 let userAddress58 = toString(userAddress)
229229 let origInvestArray = readInvestorArrayOrFail(userAddress58)
230230 let investTotalAmount = parseIntValue(origInvestArray[IdxInvTotalAmount])
231231 let investLastClaimedHeightTMP = parseIntValue(origInvestArray[IdxInvLastClaimedHeight])
232232 let investLastClaimedHeight = if ((claimStart >= investLastClaimedHeightTMP))
233233 then claimStart
234234 else investLastClaimedHeightTMP
235235 let newClaimPeriodHeight = if ((height > claimEnd))
236236 then claimEnd
237237 else if ((claimStart > height))
238238 then claimStart
239239 else height
240240 let claimingBlocks = (newClaimPeriodHeight - investLastClaimedHeight)
241241 let claimingPriceAssetAmount = fraction(investTotalAmount, claimingBlocks, claimDuration)
242242 let claimingIdoAssetAmount = convertPriceAssetIntoIdoAsset(claimingPriceAssetAmount, priceAssetMult, price, priceMult, idoAssetMult)
243243 let isUSDN = (claimedAssetId58 == priceAssetId58)
244244 let isUSDNClaimDisabled = valueOrElse(getBoolean(keyUSDNClaimDisabled()), false)
245245 let checks = [if (!(if (isUSDN)
246246 then isUSDNClaimDisabled
247247 else false))
248248 then true
249249 else throw("USDN claim is disabled")]
250250 if ((checks == checks))
251251 then if ((claimedAssetId58 == priceAssetId58))
252252 then $Tuple6([0, -(claimingPriceAssetAmount), claimingPriceAssetAmount, 0], claimingPriceAssetAmount, priceAssetId, origInvestArray, newClaimPeriodHeight, [claimingPriceAssetAmount, claimingIdoAssetAmount])
253253 else if ((claimedAssetId58 == idoAssetId58))
254254 then $Tuple6([0, -(claimingPriceAssetAmount), 0, claimingIdoAssetAmount], claimingIdoAssetAmount, idoAssetId, origInvestArray, newClaimPeriodHeight, [claimingPriceAssetAmount, claimingIdoAssetAmount])
255255 else throw(("unsupported assetId: " + claimedAssetId58))
256256 else throw("Strict value is not equal to itself.")
257257 }
258258
259259
260260 func internalClaimV2 (priceAssetId58,userAddress58,outAmount,totalUserAvailableToClaim) = {
261261 let totalPeriodPriceAssetAllowance = value(getInteger(keyTotalPeriodAllowance(priceAssetId58)))
262262 let userPeriodPriceAssetAllowance = value(getInteger(keyUserPeriodAllowance(priceAssetId58)))
263263 let periodLength = value(getInteger(keyPeriodLength()))
264264 let currentPeriod = valueOrElse(getInteger(keyCurrentPeriod()), 0)
265265 let zeroPeriodEndHeighIsDefined = isDefined(getInteger(keyPeriodEndHeight(0)))
266266 let $t01327415144 = if ((currentPeriod > 0))
267267 then {
268268 let lastPeriodStartHeight = value(getInteger(keyPeriodStartHeight(currentPeriod)))
269269 let lastPeriodEndHeight = value(getInteger(keyPeriodEndHeight(currentPeriod)))
270270 let $t01353414239 = if ((height > lastPeriodEndHeight))
271271 then {
272272 let updatedCurrentPeriod = (currentPeriod + 1)
273273 let periodStart = if ((height > (lastPeriodEndHeight + periodLength)))
274274 then {
275275 let blocksToLastPeriodStart = ((height - lastPeriodEndHeight) % periodLength)
276276 if ((blocksToLastPeriodStart == 0))
277277 then ((height - periodLength) + 1)
278278 else (height - blocksToLastPeriodStart)
279279 }
280280 else (lastPeriodEndHeight + 1)
281281 let periodEnd = ((periodStart + periodLength) - 1)
282282 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
283283 }
284284 else $Tuple3(currentPeriod, lastPeriodStartHeight, lastPeriodEndHeight)
285285 let updatedCurrentPeriod = $t01353414239._1
286286 let periodStart = $t01353414239._2
287287 let periodEnd = $t01353414239._3
288288 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
289289 }
290290 else if (zeroPeriodEndHeighIsDefined)
291291 then {
292292 let zeroPeriodStartHeight = value(getInteger(keyPeriodStartHeight(0)))
293293 let zeroPeriodEndHeight = value(getInteger(keyPeriodEndHeight(0)))
294294 let $t01449414876 = if ((height > zeroPeriodEndHeight))
295295 then {
296296 let updatedCurrentPeriod = (currentPeriod + 1)
297297 let periodStart = (zeroPeriodEndHeight + 1)
298298 let periodEnd = ((periodStart + periodLength) - 1)
299299 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
300300 }
301301 else $Tuple3(currentPeriod, zeroPeriodStartHeight, zeroPeriodEndHeight)
302302 let updatedCurrentPeriod = $t01449414876._1
303303 let periodStart = $t01449414876._2
304304 let periodEnd = $t01449414876._3
305305 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
306306 }
307307 else $Tuple3(currentPeriod, valueOrElse(getInteger(keyPeriodStartHeight(currentPeriod)), height), valueOrElse(getInteger(keyPeriodEndHeight(currentPeriod)), ((height + periodLength) - 1)))
308308 let updatedCurrentPeriod = $t01327415144._1
309309 let periodStart = $t01327415144._2
310310 let periodEnd = $t01327415144._3
311311 let periodTotalAvailableToClaim = valueOrElse(getInteger(keyPeriodTotalAvailableToClaim(priceAssetId58, updatedCurrentPeriod)), totalPeriodPriceAssetAllowance)
312312 let periodUserAvailableToClaim = valueOrElse(getInteger(keyPeriodUserAvailableToClaim(priceAssetId58, updatedCurrentPeriod, userAddress58)), userPeriodPriceAssetAllowance)
313313 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
314314 let periodMinAvailableToClaim = min([(outAmount + priceAssetBalance), periodTotalAvailableToClaim, periodUserAvailableToClaim])
315315 let usdtPriceAssetAllowableRatio = value(getInteger(keyUsdtPriceAssetAllowableRatio()))
316316 let putOneTknV2PriceAssetAmount = scale8
317317 let $t01589916152 = {
318318 let @ = invoke(addressFromStringValue(value(getString(keyUsdtPriceAssetStablePool()))), "putOneTknV2WithoutTakeFeeREADONLY", [putOneTknV2PriceAssetAmount, priceAssetId58], nil)
319319 if ($isInstanceOf(@, "(Int, Int, Int)"))
320320 then @
321321 else throw(($getType(@) + " couldn't be cast to (Int, Int, Int)"))
322322 }
323323 if (($t01589916152 == $t01589916152))
324324 then {
325325 let bonus = $t01589916152._3
326326 let feeAmount = $t01589916152._2
327327 let lpAmount = $t01589916152._1
328328 let usdtAssetId = value(getString(keyUsdtAssetId()))
329329 let $t01621416432 = {
330330 let @ = invoke(addressFromStringValue(value(getString(keyUsdtPriceAssetStablePool()))), "getOneTknV2READONLY", [usdtAssetId, lpAmount], nil)
331331 if ($isInstanceOf(@, "(Int, Int)"))
332332 then @
333333 else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
334334 }
335335 if (($t01621416432 == $t01621416432))
336336 then {
337337 let getOneTknV2FeeAmount = $t01621416432._2
338338 let usdtAmount = $t01621416432._1
339339 let currentUsdtPriceAssetRatio = fraction(putOneTknV2PriceAssetAmount, scale8, usdtAmount)
340340 let endPeriodBlocksLeft = (periodEnd - height)
341341 $Tuple10(periodMinAvailableToClaim, periodTotalAvailableToClaim, periodUserAvailableToClaim, totalUserAvailableToClaim, usdtPriceAssetAllowableRatio, currentUsdtPriceAssetRatio, endPeriodBlocksLeft, updatedCurrentPeriod, periodStart, periodEnd)
342342 }
343343 else throw("Strict value is not equal to itself.")
344344 }
345345 else throw("Strict value is not equal to itself.")
346346 }
347347
348348
349349 func managerPublicKeyOrUnit () = {
350350 let managerVaultAddress = getManagerVaultAddressOrThis()
351351 match getString(managerVaultAddress, keyManagerPublicKey()) {
352352 case s: String =>
353353 fromBase58String(s)
354354 case _: Unit =>
355355 unit
356356 case _ =>
357357 throw("Match error")
358358 }
359359 }
360360
361361
362362 func mustManager (i) = {
363363 let pd = throw("Permission denied")
364364 match managerPublicKeyOrUnit() {
365365 case pk: ByteVector =>
366366 if ((i.callerPublicKey == pk))
367367 then true
368368 else pd
369369 case _: Unit =>
370370 if ((i.caller == this))
371371 then true
372372 else pd
373373 case _ =>
374374 throw("Match error")
375375 }
376376 }
377377
378378
379379 func getClaimForState (userAddress58,txId) = {
380380 let idoAssetId58 = readConfigArray()[IdxCfgIdoAssetId]
381381 let investor = split(value(getString(keyInvestor(userAddress58))), SEP)
382382 let investorTotalAmount = parseIntValue(investor[IdxInvTotalAmount])
383383 let investorRemainingAmount = parseIntValue(investor[IdxInvRemainingAmount])
384384 let investorPriceAssetBalance = parseIntValue(investor[IdxInvClaimedPriceAssetAmount])
385385 let investorIdoAssetBalance = parseIntValue(investor[IdxInvClaimedIdoAssetAmount])
386386 let investorLastClaimedHeight = parseIntValue(investor[IdxInvLastClaimedHeight])
387- let $t01793418146 = match getInteger(keyPriceAssetBalance(userAddress58)) {
388- case t: Int =>
389- $Tuple2(t, [IntegerEntry(keyPriceAssetBalance(userAddress58), 0)])
390- case _ =>
391- $Tuple2(0, nil)
392- }
393- let priceAssetAmount = $t01793418146._1
394- let priceAssetActions = $t01793418146._2
395- let $t01815018413 = match getString(keyInvestorRemainingAmount(userAddress58)) {
396- case t: String =>
397- $Tuple2(parseIntValue(t), [StringEntry(keyInvestorRemainingAmount(userAddress58), "0")])
398- case _ =>
399- $Tuple2(0, nil)
400- }
401- let investorKeyRemainingAmount = $t01815018413._1
402- let investorKeyRemainingActions = $t01815018413._2
387+ let priceAssetAmount = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
388+ let priceAssetActions = if ((priceAssetAmount != 0))
389+ then [IntegerEntry(keyPriceAssetBalance(userAddress58), 0)]
390+ else nil
391+ let investorKeyRemainingAmount = parseIntValue(valueOrElse(getString(keyInvestorRemainingAmount(userAddress58)), "0"))
392+ let investorKeyRemainingActions = if ((investorKeyRemainingAmount != 0))
393+ then [StringEntry(keyInvestorRemainingAmount(userAddress58), "0")]
394+ else nil
403395 let totalIdoAssetSendAmount = (((investorRemainingAmount + priceAssetAmount) + investorKeyRemainingAmount) * 100)
404396 let totalIdoAssetForInvestorData = ((investorRemainingAmount + investorKeyRemainingAmount) * 100)
405397 let newInvestor = makeString(["%d%d%d%d%d", toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString((investorIdoAssetBalance + totalIdoAssetForInvestorData)), toString(height)], SEP)
406398 let investorDataActions = if ((totalIdoAssetForInvestorData != 0))
407399 then [StringEntry(keyInvestor(userAddress58), newInvestor)]
408400 else nil
409401 let sendIdoAssetActions = if ((totalIdoAssetSendAmount != 0))
410- then [ScriptTransfer(addressFromStringValue(userAddress58), totalIdoAssetSendAmount, fromBase58String(idoAssetId58))]
402+ then [ScriptTransfer(addressFromStringValue(userAddress58), totalIdoAssetSendAmount, fromBase58String(idoAssetId58)), ClaimOperationHistoryEntry(userAddress58, 0, totalIdoAssetSendAmount, txId)]
411403 else nil
412- let historyActions = ClaimOperationHistoryEntry(userAddress58, 0, totalIdoAssetSendAmount, txId)
413- $Tuple4(investorRemainingAmount, priceAssetAmount, investorKeyRemainingAmount, ((((sendIdoAssetActions :+ investorDataActions) :+ totalIdoAssetForInvestorData) :+ priceAssetActions) :+ historyActions))
404+ $Tuple4(investorRemainingAmount, priceAssetAmount, investorKeyRemainingAmount, (((sendIdoAssetActions :+ investorDataActions) :+ totalIdoAssetForInvestorData) :+ priceAssetActions))
414405 }
415406
416407
417408 @Callable(i)
418409 func constructor (idoStart,idoDuration,claimStart,claimDuration,price,priceAssetId58,minInvestAmount) = {
419410 let priceMult = ((100 * 1000) * 1000)
420411 let idoEnd = (idoStart + idoDuration)
421412 if (isDefined(getString(keyConfig())))
422413 then throw("already initialized")
423414 else if (("3PMEHLx1j6zerarZTYfsGqDeeZqQoMpxq5S" != toString(i.caller)))
424415 then throw("not authorized")
425416 else if ((size(i.payments) != 1))
426417 then throw("exactly 1 payment must be attached")
427418 else if ((idoEnd >= claimStart))
428419 then throw("claimStart must be greater than idoEnd")
429420 else {
430421 let pmt = value(i.payments[0])
431422 let idoAssetId = value(pmt.assetId)
432423 let idoAssetInfo = valueOrErrorMessage(assetInfo(idoAssetId), "fail to load ido asset info")
433424 let idoAssetId58 = toBase58String(idoAssetId)
434425 let idoAssetMult = pow(10, 0, idoAssetInfo.decimals, 0, 0, DOWN)
435426 let priceAssetId = fromBase58String(priceAssetId58)
436427 let priceAssetInfo = valueOrErrorMessage(assetInfo(priceAssetId), "fail to load price asset info")
437428 let priceAssetMult = pow(10, 0, priceAssetInfo.decimals, 0, 0, DOWN)
438429 let origTotalsArray = readTotalsArrayOrDefault()
439430 let totalsDiff = [0, 0, 0, 0]
440431 [StringEntry(keyConfig(), fromatConfig(idoStart, idoDuration, claimStart, claimDuration, price, priceMult, idoAssetId58, idoAssetMult, priceAssetId58, priceAssetMult, minInvestAmount, pmt.amount)), TotalsEntry(keyTotals(), origTotalsArray, totalsDiff, claimStart, 0)]
441432 }
442433 }
443434
444435
445436
446437 @Callable(i)
447438 func invest () = {
448439 let cfgArray = readConfigArray()
449440 let idoStart = parseIntValue(cfgArray[IdxCfgIdoStart])
450441 let idoDuration = parseIntValue(cfgArray[IdxCfgIdoDuration])
451442 let idoEnd = (idoStart + idoDuration)
452443 let claimStart = parseIntValue(cfgArray[IdxCfgClaimStart])
453444 let claimDuration = parseIntValue(cfgArray[IdxCfgClaimDuration])
454445 let price = parseIntValue(cfgArray[IdxCfgPrice])
455446 let priceMult = parseIntValue(cfgArray[IdxCfgPriceMult])
456447 let idoAssetId58 = cfgArray[IdxCfgIdoAssetId]
457448 let idoAssetId = fromBase58String(idoAssetId58)
458449 let idoAssetMult = parseIntValue(cfgArray[IdxCfgIdoAssetMult])
459450 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
460451 let priceAssetId = fromBase58String(priceAssetId58)
461452 let priceAssetMult = parseIntValue(cfgArray[IdxCfgPriceAssetMult])
462453 let minIvestAmount = parseIntValue(cfgArray[IdxCfgMinInvestAmount])
463454 let userAddress = toString(i.caller)
464455 if ((idoStart > height))
465456 then throw("ido has not been started yet")
466457 else if ((height > idoEnd))
467458 then throw("ido has been already ended")
468459 else if ((size(i.payments) != 1))
469460 then throw("exactly 1 payment is expected")
470461 else {
471462 let pmt = value(i.payments[0])
472463 let pmtAssetId = value(pmt.assetId)
473464 let pmtAmount = pmt.amount
474465 if ((pmtAssetId != priceAssetId))
475466 then throw((("invalid payment asset id: " + toBase58String(pmtAssetId)) + " is expected"))
476467 else {
477468 let origInvestorArray = readInvestorArrayOrDefault(userAddress)
478469 let origTotalsArray = readTotalsArrayOrDefault()
479470 let newPriceTotalAmount = (parseIntValue(origTotalsArray[IdxInvTotalAmount]) + pmtAmount)
480471 let requiredIdoAssetAmount = (newPriceTotalAmount * 100)
481472 if ((requiredIdoAssetAmount > assetBalance(this, idoAssetId)))
482473 then throw("IDO asset has been - sold consider to use smaller payment")
483474 else {
484475 let totalsDiff = [pmtAmount, pmtAmount, 0, 0]
485476 [TotalsEntry(keyInvestor(userAddress), origInvestorArray, totalsDiff, claimStart, 0), TotalsEntry(keyTotals(), origTotalsArray, totalsDiff, claimStart, 0), InvestOperationHistoryEntry(userAddress, pmtAmount, 0, i.transactionId)]
486477 }
487478 }
488479 }
489480 }
490481
491482
492483
493484 @Callable(i)
494485 func claim (claimedAssetId58,userAddress58) = {
495486 let callerAddress58 = toString(i.caller)
496487 if ((userAddress58 != callerAddress58))
497488 then throw("not authorized")
498489 else {
499490 let cfgArray = readConfigArray()
500491 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
501492 let claimResultTuple = internalClaim(claimedAssetId58, i.caller, i.transactionId)
502493 let totalsDiff = claimResultTuple._1
503494 let outAmount = claimResultTuple._2
504495 let outAssetId = claimResultTuple._3
505496 let origInvestArray = claimResultTuple._4
506497 let newClaimPeriodHeight = claimResultTuple._5
507498 let claimedPriceAmountFromDiff = totalsDiff[IdxDiffClaimedPriceAmountIncrement]
508499 let claimedIdoAssetAmountFromDiff = totalsDiff[IdxDiffClaimedIdoAssetAmountIncrement]
509500 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
510501 let priceAssetDecimals = value(assetInfo(fromBase58String(priceAssetId58))).decimals
511502 let entries = if ((claimedAssetId58 == priceAssetId58))
512503 then {
513- let $t02448324927 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
514- let periodMinAvailableToClaim = $t02448324927._1
515- let periodTotalAvailableToClaim = $t02448324927._2
516- let periodUserAvailableToClaim = $t02448324927._3
517- let totalUserAvailableToClaim = $t02448324927._4
518- let usdtPriceAssetAllowableRatio = $t02448324927._5
519- let currentUsdtPriceAssetRatio = $t02448324927._6
520- let endPeriodBlocksLeft = $t02448324927._7
521- let updatedCurrentPeriod = $t02448324927._8
522- let periodStart = $t02448324927._9
523- let periodEnd = $t02448324927._10
504+ let $t02447324917 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
505+ let periodMinAvailableToClaim = $t02447324917._1
506+ let periodTotalAvailableToClaim = $t02447324917._2
507+ let periodUserAvailableToClaim = $t02447324917._3
508+ let totalUserAvailableToClaim = $t02447324917._4
509+ let usdtPriceAssetAllowableRatio = $t02447324917._5
510+ let currentUsdtPriceAssetRatio = $t02447324917._6
511+ let endPeriodBlocksLeft = $t02447324917._7
512+ let updatedCurrentPeriod = $t02447324917._8
513+ let periodStart = $t02447324917._9
514+ let periodEnd = $t02447324917._10
524515 let checks = [if ((periodUserAvailableToClaim > 0))
525516 then true
526517 else throwErr("unavailable to claim because user period allowance reached"), if ((periodTotalAvailableToClaim > 0))
527518 then true
528519 else throwErr("unavailable to claim because total period allowance reached"), if ((periodMinAvailableToClaim > 0))
529520 then true
530521 else throwErr("nothing to claim"), if ((usdtPriceAssetAllowableRatio > currentUsdtPriceAssetRatio))
531522 then true
532523 else throwErr("unavailable to claim because usdn price lower than usdtPriceAssetAllowableRatio"), if (if (if ((claimedAssetId58 != priceAssetId58))
533524 then true
534525 else (claimClosingHeight == 0))
535526 then true
536527 else (claimClosingHeight > height))
537528 then true
538529 else throwErr("Claim is disabled")]
539530 if ((checks == checks))
540531 then {
541532 let updatedPeriodTotalAvailableToClaim = (periodTotalAvailableToClaim - periodMinAvailableToClaim)
542533 let updatedPeriodUserAvailableToClaim = (periodUserAvailableToClaim - periodMinAvailableToClaim)
543534 let entries = if ((priceAssetBalance > periodMinAvailableToClaim))
544535 then [ScriptTransfer(i.caller, periodMinAvailableToClaim, outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), (priceAssetBalance - periodMinAvailableToClaim))]
545536 else {
546537 let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
547538 if ((evaluateResult == evaluateResult))
548539 then {
549540 let availablePriceAmountToClaim = parseIntValue(evaluateResult[3])
550541 let lastClaimEntries = if ((availablePriceAmountToClaim == periodMinAvailableToClaim))
551542 then {
552543 let investorTotalAmount = parseIntValue(origInvestArray[IdxInvTotalAmount])
553544 let investorRemainingAmount = parseIntValue(origInvestArray[IdxInvRemainingAmount])
554545 let investorPriceAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedPriceAssetAmount])
555546 let investorIdoAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedIdoAssetAmount])
556547 let investorLastClaimedHeight = parseIntValue(origInvestArray[IdxInvLastClaimedHeight])
557548 let newInvestArray = [toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)]
558549 let totals = readTotalsArrayOrDefault()
559550 let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
560551 let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
561552 let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
562553 let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedIdoAssetAmount])
563554 let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
564555 let newTotalsRemainingAmount = (totalsRemainingAmount - investorRemainingAmount)
565556 let newTotalArray = [toString(totalsTotalAmount), toString(newTotalsRemainingAmount), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)]
566557 let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
567558 [StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), TotalsEntry(keyInvestor(userAddress58), newInvestArray, totalsDiff, newClaimPeriodHeight, 0), TotalsEntry(keyTotals(), newTotalArray, totalsDiff, newClaimPeriodHeight, 0)]
568559 }
569560 else [TotalsEntry(keyInvestor(userAddress58), origInvestArray, totalsDiff, newClaimPeriodHeight, 0), TotalsEntry(keyTotals(), readTotalsArrayOrDefault(), totalsDiff, newClaimPeriodHeight, 0)]
570561 let updatedPriceAssetBalance = ((priceAssetBalance + outAmount) - periodMinAvailableToClaim)
571562 ([ScriptTransfer(i.caller, periodMinAvailableToClaim, outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), updatedPriceAssetBalance)] ++ lastClaimEntries)
572563 }
573564 else throw("Strict value is not equal to itself.")
574565 }
575566 $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)
576567 }
577568 else throw("Strict value is not equal to itself.")
578569 }
579570 else {
580571 let priceAssetBalanceIdoDecimals = fraction(priceAssetBalance, scale8, pow(10, 0, priceAssetDecimals, 0, 0, DOWN))
581572 $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)
582573 }
583574 entries
584575 }
585576 }
586577
587578
588579
589580 @Callable(i)
590581 func cleanRemaingAmount (userAddress58) = {
591582 let priceAssetId58 = readConfigArray()[IdxCfgPriceAssetId]
592583 let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
593584 if ((evaluateResult == evaluateResult))
594585 then {
595586 let availablePriceAmountToClaim = parseIntValue(evaluateResult[2])
596587 let checkUnclaimedAssets = if ((availablePriceAmountToClaim == 0))
597588 then true
598589 else throwErr("user have unclaimed assets")
599590 if ((checkUnclaimedAssets == checkUnclaimedAssets))
600591 then {
601592 let investor = split(value(getString(keyInvestor(userAddress58))), SEP)
602593 let investorTotalAmount = parseIntValue(investor[IdxInvTotalAmount])
603594 let investorRemainingAmount = parseIntValue(investor[IdxInvRemainingAmount])
604595 let investorPriceAssetBalance = parseIntValue(investor[IdxInvClaimedPriceAssetAmount])
605596 let investorIdoAssetBalance = parseIntValue(investor[IdxInvClaimedIdoAssetAmount])
606597 let investorLastClaimedHeight = parseIntValue(investor[IdxInvLastClaimedHeight])
607598 let investorRemainingAmountCheck = if ((investorRemainingAmount != 0))
608599 then true
609600 else throwErr("investorRemainingAmount already zero")
610601 if ((investorRemainingAmountCheck == investorRemainingAmountCheck))
611602 then {
612603 let newInvestor = makeString(["%d%d%d%d%d", toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)], SEP)
613604 let totals = split(value(getString(keyTotals())), SEP)
614605 let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
615606 let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
616607 let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
617608 let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedIdoAssetAmount])
618609 let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
619610 let newTotals = makeString(["%d%d%d%d%d", toString(totalsTotalAmount), toString((totalsRemainingAmount - investorRemainingAmount)), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)], SEP)
620611 let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
621612 [StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), StringEntry(keyInvestor(userAddress58), newInvestor), StringEntry(keyTotals(), newTotals)]
622613 }
623614 else throw("Strict value is not equal to itself.")
624615 }
625616 else throw("Strict value is not equal to itself.")
626617 }
627618 else throw("Strict value is not equal to itself.")
628619 }
629620
630621
631622
632623 @Callable(i)
633624 func claimFor (userAddress58) = nil
634625
635626
636627
637628 @Callable(i)
638629 func claimREADONLY (claimedAssetId58,userAddress58) = {
639630 let claimResultTuple = internalClaim(claimedAssetId58, addressFromStringValue(userAddress58), fromBase58String(""))
640631 let totalsDiff = claimResultTuple._1
641632 let outAmount = claimResultTuple._2
642633 let outAssetId = claimResultTuple._3
643634 let origInvestArray = claimResultTuple._4
644635 let newClaimPeriodHeight = claimResultTuple._5
645636 let availableToClaimArray = claimResultTuple._6
646637 let availablePriceAmountToClaim = availableToClaimArray[0]
647638 let availableIdoAmountToClaim = availableToClaimArray[1]
648639 $Tuple2(nil, makeString(["%s%d%d", userAddress58, toString(availablePriceAmountToClaim), toString(availableIdoAmountToClaim)], SEP))
649640 }
650641
651642
652643
653644 @Callable(i)
654645 func claimV2READONLY (claimedAssetId58,userAddress58) = {
655646 let claimResultTuple = internalClaim(claimedAssetId58, addressFromStringValue(userAddress58), fromBase58String(""))
656647 let totalsDiff = claimResultTuple._1
657648 let outAmount = claimResultTuple._2
658649 let outAssetId = claimResultTuple._3
659650 let origInvestArray = claimResultTuple._4
660651 let newClaimPeriodHeight = claimResultTuple._5
661652 let availableToClaimArray = claimResultTuple._6
662653 let availablePriceAmountToClaim = availableToClaimArray[0]
663654 let availableIdoAmountToClaim = availableToClaimArray[1]
664655 let cfgArray = readConfigArray()
665656 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
666657 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
667658 let priceAssetBalanceIdoDecimals = (priceAssetBalance * 100)
668659 let availableIdoAmountToClaimWithPriceAssetBalance = (availableIdoAmountToClaim + priceAssetBalanceIdoDecimals)
669- let $t03637436786 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
670- let periodMinAvailableToClaim = $t03637436786._1
671- let periodTotalAvailableToClaim = $t03637436786._2
672- let periodUserAvailableToClaim = $t03637436786._3
673- let totalUserAvailableToClaim = $t03637436786._4
674- let usdtPriceAssetAllowableRatio = $t03637436786._5
675- let currentUsdtPriceAssetRatio = $t03637436786._6
676- let endPeriodBlocksLeft = $t03637436786._7
677- let updatedCurrentPeriod = $t03637436786._8
678- let periodStart = $t03637436786._9
679- let periodEnd = $t03637436786._10
660+ let $t03636436776 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
661+ let periodMinAvailableToClaim = $t03636436776._1
662+ let periodTotalAvailableToClaim = $t03636436776._2
663+ let periodUserAvailableToClaim = $t03636436776._3
664+ let totalUserAvailableToClaim = $t03636436776._4
665+ let usdtPriceAssetAllowableRatio = $t03636436776._5
666+ let currentUsdtPriceAssetRatio = $t03636436776._6
667+ let endPeriodBlocksLeft = $t03636436776._7
668+ let updatedCurrentPeriod = $t03636436776._8
669+ let periodStart = $t03636436776._9
670+ let periodEnd = $t03636436776._10
680671 let currentPeriodEndHeight = valueOrElse(getInteger(keyPeriodEndHeight(updatedCurrentPeriod)), 0)
681672 let userTotalPriceAssetClaimed = (parseIntValue(readInvestorArrayOrFail(userAddress58)[IdxInvClaimedPriceAssetAmount]) - priceAssetBalance)
682673 let resultString = if ((height > currentPeriodEndHeight))
683674 then {
684675 let periodLenght = value(getInteger(keyPeriodLength()))
685676 let userPeriodAllowance = value(getInteger(keyUserPeriodAllowance(priceAssetId58)))
686677 let totalPeriodAllowance = value(getInteger(keyTotalPeriodAllowance(priceAssetId58)))
687678 makeString(["%d%d%d%d%d%d", toString(availableIdoAmountToClaimWithPriceAssetBalance), toString(userPeriodAllowance), toString(totalPeriodAllowance), toString(usdtPriceAssetAllowableRatio), toString(currentUsdtPriceAssetRatio), toString(periodLenght), toString(userTotalPriceAssetClaimed)], SEP)
688679 }
689680 else makeString(["%d%d%d%d%d%d", toString(availableIdoAmountToClaimWithPriceAssetBalance), toString(periodMinAvailableToClaim), toString(periodTotalAvailableToClaim), toString(usdtPriceAssetAllowableRatio), toString(currentUsdtPriceAssetRatio), toString(endPeriodBlocksLeft), toString(userTotalPriceAssetClaimed)], SEP)
690681 $Tuple2(nil, resultString)
691682 }
692683
693684
694685 @Verifier(tx)
695686 func verify () = {
696687 let targetPublicKey = match managerPublicKeyOrUnit() {
697688 case pk: ByteVector =>
698689 pk
699690 case _: Unit =>
700691 tx.senderPublicKey
701692 case _ =>
702693 throw("Match error")
703694 }
704695 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
705696 }
706697

github/deemru/w8io/6500d08 
106.29 ms