tx · AXzJC9BUQaA72N1C1gr4GTjq79rfc4Xrgevf5Zt8QNGy

3MyVvNfXht9piazyf1e5BVFsqv1R7z5cWJL:  -0.02900000 Waves

2022.06.22 16:27 [2107661] smart account 3MyVvNfXht9piazyf1e5BVFsqv1R7z5cWJL > SELF 0.00000000 Waves

{ "type": 13, "id": "AXzJC9BUQaA72N1C1gr4GTjq79rfc4Xrgevf5Zt8QNGy", "fee": 2900000, "feeAssetId": null, "timestamp": 1655904489578, "version": 1, "sender": "3MyVvNfXht9piazyf1e5BVFsqv1R7z5cWJL", "senderPublicKey": "DnPyGWCgpQChvoQrnXQRcC9FtN32mPGrcog2wcKHdkVn", "proofs": [ "3iycpHoH6fbNyUacrTSvJTyG26kGShDpUxF3EfC3K6Cdk9NUoQpQiGHdu3sexoRka36tNbdRwt3v7r5k3y89ApWS" ], "script": "base64:BgJhCAISAwoBCBIAEgQKAggBEggKBggICAgIARIECgIICBIFCgMICAESBAoCCAgSAwoBARIDCgEBEgQKAggIEgMKAQgSABIDCgEBEgASAwoBCBIECgIICBIECgIICBIECgIICDIACXNlcGFyYXRvcgICX18ADnBvb2xXZWlnaHRNdWx0AIDC1y8AD21heERlcHRoRGVmYXVsdAAKABZmaW5hbGl6YXRpb25TdGFnZVRvdGFsAAAAF2ZpbmFsaXphdGlvblN0YWdlU2hhcmVzAAEADmtleUVwb2NoTGVuZ3RoCQC5CQIJAMwIAgICJXMJAMwIAgILZXBvY2hMZW5ndGgFA25pbAUJc2VwYXJhdG9yAA9rZXlDdXJyZW50RXBvY2gJALkJAgkAzAgCAgIlcwkAzAgCAgxjdXJyZW50RXBvY2gFA25pbAUJc2VwYXJhdG9yAAtrZXlNYXhEZXB0aAkAuQkCCQDMCAICAiVzCQDMCAICCG1heERlcHRoBQNuaWwFCXNlcGFyYXRvcgAia2V5Vm90aW5nRW1pc3Npb25DYW5kaWRhdGVDb250cmFjdAkAuQkCCQDMCAICAiVzCQDMCAICH3ZvdGluZ0VtaXNzaW9uQ2FuZGlkYXRlQ29udHJhY3QFA25pbAUJc2VwYXJhdG9yABJrZXlGYWN0b3J5Q29udHJhY3QJALkJAgkAzAgCAgIlcwkAzAgCAg9mYWN0b3J5Q29udHJhY3QFA25pbAUJc2VwYXJhdG9yABNrZXlCb29zdGluZ0NvbnRyYWN0CQC5CQIJAMwIAgICJXMJAMwIAgIQYm9vc3RpbmdDb250cmFjdAUDbmlsBQlzZXBhcmF0b3IAEmtleVN0YWtpbmdDb250cmFjdAkAuQkCCQDMCAICAiVzCQDMCAICD3N0YWtpbmdDb250cmFjdAUDbmlsBQlzZXBhcmF0b3IAFmtleUFzc2V0c1N0b3JlQ29udHJhY3QJALkJAgkAzAgCAgIlcwkAzAgCAhNhc3NldHNTdG9yZUNvbnRyYWN0BQNuaWwFCXNlcGFyYXRvcgAUa2V5RmluYWxpemF0aW9uU3RhZ2UJALkJAgkAzAgCAgIlcwkAzAgCAhFmaW5hbGl6YXRpb25TdGFnZQUDbmlsBQlzZXBhcmF0b3IAC2tleU5leHRQb29sCQC5CQIJAMwIAgICJXMJAMwIAgIIbmV4dFBvb2wFA25pbAUJc2VwYXJhdG9yAAtrZXlOZXh0VXNlcgkAuQkCCQDMCAICAiVzCQDMCAICCG5leHRVc2VyBQNuaWwFCXNlcGFyYXRvcgAOa2V5U3RhcnRIZWlnaHQJALkJAgkAzAgCAgIlcwkAzAgCAgtzdGFydEhlaWdodAUDbmlsBQlzZXBhcmF0b3IAEWtleUN1cnJlbnRFcG9jaFVpCQC5CQIJAMwIAgICJXMJAMwIAgIOY3VycmVudEVwb2NoVWkFA25pbAUJc2VwYXJhdG9yABBrZXlTdGFydEhlaWdodFVpCQC5CQIJAMwIAgICJXMJAMwIAgINc3RhcnRIZWlnaHRVaQUDbmlsBQlzZXBhcmF0b3IBFWtleVN0YXJ0SGVpZ2h0QnlFcG9jaAEFZXBvY2gJALkJAgkAzAgCAgQlcyVkCQDMCAICC3N0YXJ0SGVpZ2h0CQDMCAIJAKQDAQUFZXBvY2gFA25pbAUJc2VwYXJhdG9yAQxrZXlGaW5hbGl6ZWQBBWVwb2NoCQC5CQIJAMwIAgIEJXMlZAkAzAgCAglmaW5hbGl6ZWQJAMwIAgkApAMBBQVlcG9jaAUDbmlsBQlzZXBhcmF0b3IBCWtleUluTGlzdAEEcG9vbAQLJHQwMTUxNzE1NTcFBHBvb2wEDWFtb3VudEFzc2V0SWQIBQskdDAxNTE3MTU1NwJfMQQMcHJpY2VBc3NldElkCAULJHQwMTUxNzE1NTcCXzIJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIGaW5MaXN0CQDMCAIFDWFtb3VudEFzc2V0SWQJAMwIAgUMcHJpY2VBc3NldElkBQNuaWwFCXNlcGFyYXRvcgEHa2V5VXNlZAIHYWRkcmVzcwVlcG9jaAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAgR1c2VkCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCCQCkAwEFBWVwb2NoBQNuaWwFCXNlcGFyYXRvcgEHa2V5Vm90ZQMEcG9vbAdhZGRyZXNzBWVwb2NoBAskdDAxODMxMTg3MQUEcG9vbAQNYW1vdW50QXNzZXRJZAgFCyR0MDE4MzExODcxAl8xBAxwcmljZUFzc2V0SWQIBQskdDAxODMxMTg3MQJfMgkAuQkCCQDMCAICCiVzJXMlcyVzJWQJAMwIAgIEdm90ZQkAzAgCBQ1hbW91bnRBc3NldElkCQDMCAIFDHByaWNlQXNzZXRJZAkAzAgCCQClCAEFB2FkZHJlc3MJAMwIAgkApAMBBQVlcG9jaAUDbmlsBQlzZXBhcmF0b3IBD2tleVZvdGluZ1Jlc3VsdAIEcG9vbAVlcG9jaAQLJHQwMjA1MzIwOTMFBHBvb2wEDWFtb3VudEFzc2V0SWQIBQskdDAyMDUzMjA5MwJfMQQMcHJpY2VBc3NldElkCAULJHQwMjA1MzIwOTMCXzIJALkJAgkAzAgCAgglcyVzJXMlZAkAzAgCAgx2b3RpbmdSZXN1bHQJAMwIAgUNYW1vdW50QXNzZXRJZAkAzAgCBQxwcmljZUFzc2V0SWQJAMwIAgkApAMBBQVlcG9jaAUDbmlsBQlzZXBhcmF0b3IBDGtleVBvb2xTaGFyZQIEcG9vbAVlcG9jaAQLJHQwMjI1ODIyOTgFBHBvb2wEDWFtb3VudEFzc2V0SWQIBQskdDAyMjU4MjI5OAJfMQQMcHJpY2VBc3NldElkCAULJHQwMjI1ODIyOTgCXzIJALkJAgkAzAgCAgglcyVzJXMlZAkAzAgCAglwb29sU2hhcmUJAMwIAgUNYW1vdW50QXNzZXRJZAkAzAgCBQxwcmljZUFzc2V0SWQJAMwIAgkApAMBBQVlcG9jaAUDbmlsBQlzZXBhcmF0b3IBDWtleVRvdGFsVm90ZXMBBWVwb2NoCQC5CQIJAMwIAgIEJXMlZAkAzAgCAgp0b3RhbFZvdGVzCQDMCAIJAKQDAQUFZXBvY2gFA25pbAUJc2VwYXJhdG9yAQ5nZXRWYWx1ZU9yRmFpbAMHYWRkcmVzcwNrZXkEdHlwZQQFZXJyb3IJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIACQETdmFsdWVPckVycm9yTWVzc2FnZQIEByRtYXRjaDAFBHR5cGUDCQABAgUHJG1hdGNoMAIGU3RyaW5nBANzdHIFByRtYXRjaDAJAJ0IAgUHYWRkcmVzcwUDa2V5AwkAAQIFByRtYXRjaDACA0ludAQDaW50BQckbWF0Y2gwCQCaCAIFB2FkZHJlc3MFA2tleQkAAgECEmludmFsaWQgZW50cnkgdHlwZQUFZXJyb3IBDGdldFN0ck9yRmFpbAIHYWRkcmVzcwNrZXkKAAFACQEOZ2V0VmFsdWVPckZhaWwDBQdhZGRyZXNzBQNrZXkCAAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBCQEOZ2V0VmFsdWVPckZhaWwDBQdhZGRyZXNzBQNrZXkCAAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nAQxnZXRJbnRPckZhaWwCB2FkZHJlc3MDa2V5CgABQAkBDmdldFZhbHVlT3JGYWlsAwUHYWRkcmVzcwUDa2V5AAADCQABAgUBQAIDSW50BQFACQACAQkArAICCQADAQkBDmdldFZhbHVlT3JGYWlsAwUHYWRkcmVzcwUDa2V5AAACGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAEMcG9vbFRvU3RyaW5nAQRwb29sCQCsAgIJAKwCAggFBHBvb2wCXzEFCXNlcGFyYXRvcggFBHBvb2wCXzIBDHN0cmluZ1RvUG9vbAEDc3RyBAVwYXJ0cwkAtQkCBQNzdHIFCXNlcGFyYXRvcgMJAAACCQCQAwEFBXBhcnRzAAIJAJQKAgkAkQMCBQVwYXJ0cwAACQCRAwIFBXBhcnRzAAEJAAIBAhNpbnZhbGlkIHBvb2wgc3RyaW5nARZnZXRMcEFzc2V0QnlQb29sQXNzZXRzAg1hbW91bnRBc3NldElkDHByaWNlQXNzZXRJZAoBH2tleU1hcHBpbmdzQmFzZUFzc2V0MmludGVybmFsSWQBDGJhc2VBc3NldFN0cgkArAICAiglcyVzJXNfX21hcHBpbmdzX19iYXNlQXNzZXQyaW50ZXJuYWxJZF9fBQxiYXNlQXNzZXRTdHIKASlrZXlNYXBwaW5nUG9vbEFzc2V0c1RvUG9vbENvbnRyYWN0QWRkcmVzcwIYaW50ZXJuYWxBbW91bnRBc3NldElkU3RyF2ludGVybmFsUHJpY2VBc3NldElkU3RyCQCsAgIJAKwCAgkArAICCQCsAgICCiVkJWQlcyVzX18JAKQDAQUYaW50ZXJuYWxBbW91bnRBc3NldElkU3RyAgJfXwkApAMBBRdpbnRlcm5hbFByaWNlQXNzZXRJZFN0cgIjX19tYXBwaW5nc19fcG9vbEFzc2V0czJQb29sQ29udHJhY3QKAR9rZXlNYXBwaW5nUG9vbENvbnRyYWN0VG9MUEFzc2V0ARNwb29sQ29udHJhY3RBZGRyZXNzCQCsAgIJAKwCAgIIJXMlcyVzX18FE3Bvb2xDb250cmFjdEFkZHJlc3MCIF9fbWFwcGluZ3NfX3Bvb2xDb250cmFjdDJMcEFzc2V0BA9mYWN0b3J5Q29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQxnZXRTdHJPckZhaWwCBQR0aGlzBRJrZXlGYWN0b3J5Q29udHJhY3QEFWFtb3VudEFzc2V0SW50ZXJuYWxJZAkBDGdldEludE9yRmFpbAIFD2ZhY3RvcnlDb250cmFjdAkBH2tleU1hcHBpbmdzQmFzZUFzc2V0MmludGVybmFsSWQBBQ1hbW91bnRBc3NldElkBBRwcmljZUFzc2V0SW50ZXJuYWxJZAkBDGdldEludE9yRmFpbAIFD2ZhY3RvcnlDb250cmFjdAkBH2tleU1hcHBpbmdzQmFzZUFzc2V0MmludGVybmFsSWQBBQxwcmljZUFzc2V0SWQEE3Bvb2xDb250cmFjdEFkZHJlc3MJAQxnZXRTdHJPckZhaWwCBQ9mYWN0b3J5Q29udHJhY3QJASlrZXlNYXBwaW5nUG9vbEFzc2V0c1RvUG9vbENvbnRyYWN0QWRkcmVzcwIFFWFtb3VudEFzc2V0SW50ZXJuYWxJZAUUcHJpY2VBc3NldEludGVybmFsSWQECWxwQXNzZXRJZAkBDGdldFN0ck9yRmFpbAIFD2ZhY3RvcnlDb250cmFjdAkBH2tleU1hcHBpbmdQb29sQ29udHJhY3RUb0xQQXNzZXQBBRNwb29sQ29udHJhY3RBZGRyZXNzBQlscEFzc2V0SWQBD2lzQXNzZXRWZXJpZmllZAEHYXNzZXRJZAQTYXNzZXRzU3RvcmVDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDGdldFN0ck9yRmFpbAIFBHRoaXMFFmtleUFzc2V0c1N0b3JlQ29udHJhY3QECmlzVmVyaWZpZWQKAAFACQD8BwQFE2Fzc2V0c1N0b3JlQ29udHJhY3QCEmlzVmVyaWZpZWRSRUFET05MWQkAzAgCBQdhc3NldElkBQNuaWwFA25pbAMJAAECBQFAAgdCb29sZWFuBQFACQACAQkArAICCQADAQkA/AcEBRNhc3NldHNTdG9yZUNvbnRyYWN0AhJpc1ZlcmlmaWVkUkVBRE9OTFkJAMwIAgUHYXNzZXRJZAUDbmlsBQNuaWwCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4FCmlzVmVyaWZpZWQADXBvb2xzTGlzdE5hbWUCBXBvb2xzARBnZXRWb3Rlc0xpc3ROYW1lAQRwb29sBAskdDA0ODM4NDg3OAUEcG9vbAQNYW1vdW50QXNzZXRJZAgFCyR0MDQ4Mzg0ODc4Al8xBAxwcmljZUFzc2V0SWQIBQskdDA0ODM4NDg3OAJfMgkAuQkCCQDMCAICBXZvdGVzCQDMCAIFDWFtb3VudEFzc2V0SWQJAMwIAgUMcHJpY2VBc3NldElkBQNuaWwFCXNlcGFyYXRvcgELa2V5TGlzdEhlYWQBCGxpc3ROYW1lBARtZXRhAwkAAAIFCGxpc3ROYW1lBQ1wb29sc0xpc3ROYW1lAgQlcyVzAgglcyVzJXMlcwkAuQkCCQDMCAIFBG1ldGEJAMwIAgUIbGlzdE5hbWUJAMwIAgIEaGVhZAUDbmlsBQlzZXBhcmF0b3IBC2tleUxpc3RTaXplAQhsaXN0TmFtZQQEbWV0YQMJAAACBQhsaXN0TmFtZQUNcG9vbHNMaXN0TmFtZQIEJXMlcwIIJXMlcyVzJXMJALkJAgkAzAgCBQRtZXRhCQDMCAIFCGxpc3ROYW1lCQDMCAICBHNpemUFA25pbAUJc2VwYXJhdG9yAQtrZXlMaXN0UHJldgIIbGlzdE5hbWUCaWQEBG1ldGEDCQAAAgUIbGlzdE5hbWUFDXBvb2xzTGlzdE5hbWUCCCVzJXMlcyVzAgolcyVzJXMlcyVzCQC5CQIJAMwIAgUEbWV0YQkAzAgCBQhsaXN0TmFtZQkAzAgCBQJpZAkAzAgCAgRwcmV2BQNuaWwFCXNlcGFyYXRvcgELa2V5TGlzdE5leHQCCGxpc3ROYW1lAmlkBARtZXRhAwkAAAIFCGxpc3ROYW1lBQ1wb29sc0xpc3ROYW1lAgglcyVzJXMlcwIKJXMlcyVzJXMlcwkAuQkCCQDMCAIFBG1ldGEJAMwIAgUIbGlzdE5hbWUJAMwIAgUCaWQJAMwIAgIEbmV4dAUDbmlsBQlzZXBhcmF0b3IBDGNvbnRhaW5zTm9kZQIIbGlzdE5hbWUCaWQECmhlYWRPclVuaXQJAJ0IAgUEdGhpcwkBC2tleUxpc3RIZWFkAQUIbGlzdE5hbWUECnByZXZPclVuaXQJAJ0IAgUEdGhpcwkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUFAmlkBApuZXh0T3JVbml0CQCdCAIFBHRoaXMJAQtrZXlMaXN0TmV4dAIFCGxpc3ROYW1lBQJpZAMDCQAAAgUCaWQJAQt2YWx1ZU9yRWxzZQIFCmhlYWRPclVuaXQCAAYJAQIhPQIFCnByZXZPclVuaXQFBHVuaXQGCQECIT0CBQpuZXh0T3JVbml0BQR1bml0ARFpbnNlcnROb2RlQWN0aW9ucwIIbGlzdE5hbWUCaWQECmhlYWRPclVuaXQJAJ0IAgUEdGhpcwkBC2tleUxpc3RIZWFkAQUIbGlzdE5hbWUECGxpc3RTaXplCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQtrZXlMaXN0U2l6ZQEFCGxpc3ROYW1lAAAECWNoZWNrTm9kZQMJAQEhAQkBDGNvbnRhaW5zTm9kZQIFCGxpc3ROYW1lBQJpZAYJAAIBAgtOb2RlIGV4aXN0cwMJAAACBQljaGVja05vZGUFCWNoZWNrTm9kZQkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQtrZXlMaXN0U2l6ZQEFCGxpc3ROYW1lCQBkAgUIbGlzdFNpemUAAQUDbmlsAwkBAiE9AgUKaGVhZE9yVW5pdAUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TGlzdE5leHQCBQhsaXN0TmFtZQUCaWQJAQV2YWx1ZQEFCmhlYWRPclVuaXQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUJAQV2YWx1ZQEFCmhlYWRPclVuaXQFAmlkBQNuaWwFA25pbAkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TGlzdEhlYWQBBQhsaXN0TmFtZQUCaWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgERZGVsZXRlTm9kZUFjdGlvbnMCCGxpc3ROYW1lAmlkBApoZWFkT3JVbml0CQCdCAIFBHRoaXMJAQtrZXlMaXN0SGVhZAEFCGxpc3ROYW1lBAhsaXN0U2l6ZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQELa2V5TGlzdFNpemUBBQhsaXN0TmFtZQAABApwcmV2T3JVbml0CQCdCAIFBHRoaXMJAQtrZXlMaXN0UHJldgIFCGxpc3ROYW1lBQJpZAQKbmV4dE9yVW5pdAkAnQgCBQR0aGlzCQELa2V5TGlzdE5leHQCBQhsaXN0TmFtZQUCaWQJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBC2tleUxpc3RTaXplAQUIbGlzdE5hbWUJAGUCBQhsaXN0U2l6ZQABBQNuaWwDAwkBAiE9AgUKcHJldk9yVW5pdAUEdW5pdAkBAiE9AgUKbmV4dE9yVW5pdAUEdW5pdAcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBC2tleUxpc3ROZXh0AgUIbGlzdE5hbWUJAQV2YWx1ZQEFCnByZXZPclVuaXQJAQV2YWx1ZQEFCm5leHRPclVuaXQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUJAQV2YWx1ZQEFCm5leHRPclVuaXQJAQV2YWx1ZQEFCnByZXZPclVuaXQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUFAmlkCQDMCAIJAQtEZWxldGVFbnRyeQEJAQtrZXlMaXN0TmV4dAIFCGxpc3ROYW1lBQJpZAUDbmlsAwkBAiE9AgUKbmV4dE9yVW5pdAUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TGlzdEhlYWQBBQhsaXN0TmFtZQkBBXZhbHVlAQUKbmV4dE9yVW5pdAkAzAgCCQELRGVsZXRlRW50cnkBCQELa2V5TGlzdE5leHQCBQhsaXN0TmFtZQUCaWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUJAQV2YWx1ZQEFCm5leHRPclVuaXQFA25pbAMJAQIhPQIFCnByZXZPclVuaXQFBHVuaXQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUFAmlkCQDMCAIJAQtEZWxldGVFbnRyeQEJAQtrZXlMaXN0TmV4dAIFCGxpc3ROYW1lCQEFdmFsdWUBBQpwcmV2T3JVbml0BQNuaWwDCQAAAgUCaWQJAQt2YWx1ZU9yRWxzZQIFCmhlYWRPclVuaXQCAAkAzAgCCQELRGVsZXRlRW50cnkBCQELa2V5TGlzdEhlYWQBBQhsaXN0TmFtZQUDbmlsCQACAQkArAICCQCsAgIJAKwCAgIOaW52YWxpZCBub2RlOiAFCGxpc3ROYW1lAgEuBQJpZAETa2V5TWFuYWdlclB1YmxpY0tleQACFCVzX19tYW5hZ2VyUHVibGljS2V5ARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAAEByRtYXRjaDAJAKIIAQkBE2tleU1hbmFnZXJQdWJsaWNLZXkAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgEdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQABAckbWF0Y2gwCQCiCAEJARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQDZBAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yABVwZXJtaXNzaW9uRGVuaWVkRXJyb3IJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAEIbXVzdFRoaXMBAWkDCQAAAggFAWkGY2FsbGVyBQR0aGlzBgUVcGVybWlzc2lvbkRlbmllZEVycm9yAQttdXN0TWFuYWdlcgEBaQQHJG1hdGNoMAkBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQAAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAnBrBQckbWF0Y2gwAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQUCcGsGBRVwZXJtaXNzaW9uRGVuaWVkRXJyb3IDCQABAgUHJG1hdGNoMAIEVW5pdAkBCG11c3RUaGlzAQUBaQkAAgECC01hdGNoIGVycm9yEgFpAQpzZXRNYW5hZ2VyARdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQQLY2hlY2tDYWxsZXIJAQttdXN0TWFuYWdlcgEFAWkDCQAAAgULY2hlY2tDYWxsZXIFC2NoZWNrQ2FsbGVyBBVjaGVja01hbmFnZXJQdWJsaWNLZXkJANkEAQUXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkDCQAAAgUVY2hlY2tNYW5hZ2VyUHVibGljS2V5BRVjaGVja01hbmFnZXJQdWJsaWNLZXkJAMwIAgkBC1N0cmluZ0VudHJ5AgkBGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAUXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ5jb25maXJtTWFuYWdlcgAEAnBtCQEdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQABAVoYXNQTQMJAQlpc0RlZmluZWQBBQJwbQYJAAIBAhJObyBwZW5kaW5nIG1hbmFnZXIDCQAAAgUFaGFzUE0FBWhhc1BNBAdjaGVja1BNAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCcG0GCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFB2NoZWNrUE0FB2NoZWNrUE0JAMwIAgkBC1N0cmluZ0VudHJ5AgkBE2tleU1hbmFnZXJQdWJsaWNLZXkACQDYBAEJAQV2YWx1ZQEFAnBtCQDMCAIJAQtEZWxldGVFbnRyeQEJARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQCC3VzZXJBZGRyZXNzDHRhcmdldEhlaWdodAQXYm9vc3RpbmdDb250cmFjdEFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQEMZ2V0U3RyT3JGYWlsAgUEdGhpcwUTa2V5Qm9vc3RpbmdDb250cmFjdAIhaW52YWxpZCBib29zdGluZyBjb250cmFjdCBhZGRyZXNzCQCUCgIFA25pbAoAAUAJAPwHBAUXYm9vc3RpbmdDb250cmFjdEFkZHJlc3MCIGdldFVzZXJHd3hBbW91bnRBdEhlaWdodFJFQURPTkxZCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIFDHRhcmdldEhlaWdodAUDbmlsBQNuaWwDCQABAgUBQAIDSW50BQFACQACAQkArAICCQADAQkA/AcEBRdib29zdGluZ0NvbnRyYWN0QWRkcmVzcwIgZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0UkVBRE9OTFkJAMwIAgULdXNlckFkZHJlc3MJAMwIAgUMdGFyZ2V0SGVpZ2h0BQNuaWwFA25pbAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AWkBC2NvbnN0cnVjdG9yBg9mYWN0b3J5Q29udHJhY3Qfdm90aW5nRW1pc3Npb25DYW5kaWRhdGVDb250cmFjdBBib29zdGluZ0NvbnRyYWN0D3N0YWtpbmdDb250cmFjdBNhc3NldHNTdG9yZUNvbnRyYWN0C2Vwb2NoTGVuZ3RoBAVjaGVrcwkAzAgCCQELbXVzdE1hbmFnZXIBBQFpCQDMCAIDCQECIT0CCQCmCAEFD2ZhY3RvcnlDb250cmFjdAUEdW5pdAYCIGludmFsaWQgZmFjdG9yeSBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQECIT0CCQCmCAEFH3ZvdGluZ0VtaXNzaW9uQ2FuZGlkYXRlQ29udHJhY3QFBHVuaXQGAjJpbnZhbGlkIHZvdGluZyBlbWlzc2lvbiBjYW5kaWRhdGUgY29udHJhY3QgYWRkcmVzcwkAzAgCAwkBAiE9AgkApggBBRBib29zdGluZ0NvbnRyYWN0BQR1bml0BgIhaW52YWxpZCBib29zdGluZyBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQECIT0CCQCmCAEFD3N0YWtpbmdDb250cmFjdAUEdW5pdAYCIGludmFsaWQgc3Rha2luZyBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQECIT0CCQCmCAEFE2Fzc2V0c1N0b3JlQ29udHJhY3QFBHVuaXQGAiVpbnZhbGlkIGFzc2V0cyBzdG9yZSBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQBmAgULZXBvY2hMZW5ndGgAAAYJAAIBAhRpbnZhbGlkIGVwb2NoIGxlbmd0aAUDbmlsAwkAAAIFBWNoZWtzBQVjaGVrcwkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFEmtleUZhY3RvcnlDb250cmFjdAUPZmFjdG9yeUNvbnRyYWN0CQDMCAIJAQtTdHJpbmdFbnRyeQIFImtleVZvdGluZ0VtaXNzaW9uQ2FuZGlkYXRlQ29udHJhY3QFH3ZvdGluZ0VtaXNzaW9uQ2FuZGlkYXRlQ29udHJhY3QJAMwIAgkBC1N0cmluZ0VudHJ5AgUTa2V5Qm9vc3RpbmdDb250cmFjdAUQYm9vc3RpbmdDb250cmFjdAkAzAgCCQELU3RyaW5nRW50cnkCBRJrZXlTdGFraW5nQ29udHJhY3QFD3N0YWtpbmdDb250cmFjdAkAzAgCCQELU3RyaW5nRW50cnkCBRZrZXlBc3NldHNTdG9yZUNvbnRyYWN0BRNhc3NldHNTdG9yZUNvbnRyYWN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5rZXlFcG9jaExlbmd0aAULZXBvY2hMZW5ndGgFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQZjcmVhdGUCDWFtb3VudEFzc2V0SWQMcHJpY2VBc3NldElkBAZjaGVja3MJAMwIAgMJAAACCQDYBAEICAUBaQZjYWxsZXIFYnl0ZXMJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUia2V5Vm90aW5nRW1pc3Npb25DYW5kaWRhdGVDb250cmFjdAIABgkBC211c3RNYW5hZ2VyAQUBaQUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBARwb29sCQCUCgIFDWFtb3VudEFzc2V0SWQFDHByaWNlQXNzZXRJZAQNaW5MaXN0QWN0aW9ucwkAzggCCQDMCAIJAQxCb29sZWFuRW50cnkCCQEJa2V5SW5MaXN0AQUEcG9vbAYFA25pbAkBEWluc2VydE5vZGVBY3Rpb25zAgUNcG9vbHNMaXN0TmFtZQkBDHBvb2xUb1N0cmluZwEFBHBvb2wEGGN1cnJlbnRFcG9jaElzTm90RGVmaW5lZAkAAAIJAJoIAgUEdGhpcwUPa2V5Q3VycmVudEVwb2NoBQR1bml0BBJzdGFydEhlaWdodEFjdGlvbnMDBRhjdXJyZW50RXBvY2hJc05vdERlZmluZWQEBWVwb2NoAAAJAMwIAgkBDEludGVnZXJFbnRyeQIFD2tleUN1cnJlbnRFcG9jaAUFZXBvY2gJAMwIAgkBDEludGVnZXJFbnRyeQIJARVrZXlTdGFydEhlaWdodEJ5RXBvY2gBBQVlcG9jaAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5rZXlTdGFydEhlaWdodAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrZXlDdXJyZW50RXBvY2hVaQUFZXBvY2gJAMwIAgkBDEludGVnZXJFbnRyeQIFEGtleVN0YXJ0SGVpZ2h0VWkFBmhlaWdodAUDbmlsBQNuaWwJAJQKAgkAzggCBQ1pbkxpc3RBY3Rpb25zBRJzdGFydEhlaWdodEFjdGlvbnMFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEEdm90ZQMNYW1vdW50QXNzZXRJZAxwcmljZUFzc2V0SWQGYW1vdW50BARwb29sCQCUCgIFDWFtb3VudEFzc2V0SWQFDHByaWNlQXNzZXRJZAQFZXBvY2gJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUPa2V5Q3VycmVudEVwb2NoAAAEC3N0YXJ0SGVpZ2h0CQEMZ2V0SW50T3JGYWlsAgUEdGhpcwkBFWtleVN0YXJ0SGVpZ2h0QnlFcG9jaAEFBWVwb2NoBAtlcG9jaExlbmd0aAkBDGdldEludE9yRmFpbAIFBHRoaXMFDmtleUVwb2NoTGVuZ3RoBAllbmRIZWlnaHQJAGQCBQtzdGFydEhlaWdodAULZXBvY2hMZW5ndGgEF2ZpbmFsaXphdGlvblN0YWdlT3JVbml0CQCaCAIFBHRoaXMFFGtleUZpbmFsaXphdGlvblN0YWdlBAR1c2VkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQdrZXlVc2VkAggFAWkGY2FsbGVyBQVlcG9jaAAABAR2b3RlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQdrZXlWb3RlAwUEcG9vbAgFAWkGY2FsbGVyBQVlcG9jaAAABApwb29sUmVzdWx0CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQ9rZXlWb3RpbmdSZXN1bHQCBQRwb29sBQVlcG9jaAAABAp0b3RhbFZvdGVzCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQ1rZXlUb3RhbFZvdGVzAQUFZXBvY2gAAAQTZ3d4QW1vdW50QXRFbmRUb3RhbAoAAUAJAPwHBAUEdGhpcwIYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0CQDMCAIJANgEAQgIBQFpBmNhbGxlcgVieXRlcwkAzAgCBQllbmRIZWlnaHQFA25pbAUDbmlsAwkAAQIFAUACA0ludAUBQAkAAgEJAKwCAgkAAwEJAPwHBAUEdGhpcwIYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0CQDMCAIJANgEAQgIBQFpBmNhbGxlcgVieXRlcwkAzAgCBQllbmRIZWlnaHQFA25pbAUDbmlsAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQECWF2YWlsYWJsZQkAZQIFE2d3eEFtb3VudEF0RW5kVG90YWwFBHVzZWQEB25ld1ZvdGUJAGQCBQR2b3RlBQZhbW91bnQEFWlzQW1vdW50QXNzZXRWZXJpZmllZAkBD2lzQXNzZXRWZXJpZmllZAEFDWFtb3VudEFzc2V0SWQEBmNoZWNrcwkAzAgCAwkBAiE9AgkAoAgBCQEJa2V5SW5MaXN0AQUEcG9vbAUEdW5pdAYJAAIBAg5pbnZhbGlkIGFzc2V0cwkAzAgCAwkAZgIFCWVuZEhlaWdodAUGaGVpZ2h0BgkAAgECDmludmFsaWQgaGVpZ2h0CQDMCAIDCQAAAgUXZmluYWxpemF0aW9uU3RhZ2VPclVuaXQFBHVuaXQGCQACAQIYZmluYWxpemF0aW9uIGluIHByb2dyZXNzCQDMCAIDCQBmAgUTZ3d4QW1vdW50QXRFbmRUb3RhbAAABgkAAgECE3lvdSBkbyBub3QgaGF2ZSBnV1gJAMwIAgMDCQBmAgUGYW1vdW50AAAJAGcCBQlhdmFpbGFibGUFBmFtb3VudAcGCQACAQIOaW52YWxpZCBhbW91bnQJAMwIAgMFFWlzQW1vdW50QXNzZXRWZXJpZmllZAYJAAIBAhxhbW91bnQgYXNzZXQgaXMgbm90IHZlcmlmaWVkBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEDXZvdGVzTGlzdE5hbWUJARBnZXRWb3Rlc0xpc3ROYW1lAQUEcG9vbAQOdXNlckFkZHJlc3NTdHIJAKUIAQgFAWkGY2FsbGVyBBB2b3Rlc0xpc3RBY3Rpb25zAwkBDGNvbnRhaW5zTm9kZQIFDXZvdGVzTGlzdE5hbWUFDnVzZXJBZGRyZXNzU3RyBQNuaWwJARFpbnNlcnROb2RlQWN0aW9ucwIFDXZvdGVzTGlzdE5hbWUFDnVzZXJBZGRyZXNzU3RyCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBB2tleVVzZWQCCAUBaQZjYWxsZXIFBWVwb2NoCQBkAgUEdXNlZAUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEHa2V5Vm90ZQMFBHBvb2wIBQFpBmNhbGxlcgUFZXBvY2gFB25ld1ZvdGUJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ9rZXlWb3RpbmdSZXN1bHQCBQRwb29sBQVlcG9jaAkAZAIFCnBvb2xSZXN1bHQFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDWtleVRvdGFsVm90ZXMBBQVlcG9jaAkAZAIFCnRvdGFsVm90ZXMFBmFtb3VudAUDbmlsBRB2b3Rlc0xpc3RBY3Rpb25zBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCmNhbmNlbFZvdGUCDWFtb3VudEFzc2V0SWQMcHJpY2VBc3NldElkBARwb29sCQCUCgIFDWFtb3VudEFzc2V0SWQFDHByaWNlQXNzZXRJZAQFZXBvY2gJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUPa2V5Q3VycmVudEVwb2NoAAAEC3N0YXJ0SGVpZ2h0CQEMZ2V0SW50T3JGYWlsAgUEdGhpcwkBFWtleVN0YXJ0SGVpZ2h0QnlFcG9jaAEFBWVwb2NoBAtlcG9jaExlbmd0aAkBDGdldEludE9yRmFpbAIFBHRoaXMFDmtleUVwb2NoTGVuZ3RoBAllbmRIZWlnaHQJAGQCBQtzdGFydEhlaWdodAULZXBvY2hMZW5ndGgEF2ZpbmFsaXphdGlvblN0YWdlT3JVbml0CQCaCAIFBHRoaXMFFGtleUZpbmFsaXphdGlvblN0YWdlBAR1c2VkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQdrZXlVc2VkAggFAWkGY2FsbGVyBQVlcG9jaAAABAR2b3RlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQdrZXlWb3RlAwUEcG9vbAgFAWkGY2FsbGVyBQVlcG9jaAAABApwb29sUmVzdWx0CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQ9rZXlWb3RpbmdSZXN1bHQCBQRwb29sBQVlcG9jaAAABAp0b3RhbFZvdGVzCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQ1rZXlUb3RhbFZvdGVzAQUFZXBvY2gAAAQGY2hlY2tzCQDMCAIDCQECIT0CCQCgCAEJAQlrZXlJbkxpc3QBBQRwb29sBQR1bml0BgkAAgECDmludmFsaWQgYXNzZXRzCQDMCAIDCQBmAgUJZW5kSGVpZ2h0BQZoZWlnaHQGCQACAQIOaW52YWxpZCBoZWlnaHQJAMwIAgMJAAACBRdmaW5hbGl6YXRpb25TdGFnZU9yVW5pdAUEdW5pdAYJAAIBAhhmaW5hbGl6YXRpb24gaW4gcHJvZ3Jlc3MJAMwIAgMJAGYCBQR2b3RlAAAGCQACAQIHbm8gdm90ZQUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBA12b3Rlc0xpc3ROYW1lCQEQZ2V0Vm90ZXNMaXN0TmFtZQEFBHBvb2wEDnVzZXJBZGRyZXNzU3RyCQClCAEIBQFpBmNhbGxlcgkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQdrZXlVc2VkAggFAWkGY2FsbGVyBQVlcG9jaAkAlgMBCQDMCAIJAGUCBQR1c2VkBQR2b3RlCQDMCAIAAAUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEJAQdrZXlWb3RlAwUEcG9vbAgFAWkGY2FsbGVyBQVlcG9jaAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBD2tleVZvdGluZ1Jlc3VsdAIFBHBvb2wFBWVwb2NoCQBlAgUKcG9vbFJlc3VsdAUEdm90ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDWtleVRvdGFsVm90ZXMBBQVlcG9jaAkAZQIFCnRvdGFsVm90ZXMFBHZvdGUFA25pbAkBEWRlbGV0ZU5vZGVBY3Rpb25zAgUNdm90ZXNMaXN0TmFtZQUOdXNlckFkZHJlc3NTdHIFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEOc2V0RXBvY2hMZW5ndGgBDm5ld0Vwb2NoTGVuZ3RoBAVjaGVrcwkAzAgCCQELbXVzdE1hbmFnZXIBBQFpCQDMCAIDCQBmAgUObmV3RXBvY2hMZW5ndGgAAAYJAAIBAhRpbnZhbGlkIGVwb2NoIGxlbmd0aAUDbmlsAwkAAAIFBWNoZWtzBQVjaGVrcwkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5rZXlFcG9jaExlbmd0aAUObmV3RXBvY2hMZW5ndGgFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQtzZXRNYXhEZXB0aAELbmV3TWF4RGVwdGgEBWNoZWtzCQDMCAIJAQttdXN0TWFuYWdlcgEFAWkJAMwIAgMJAGYCBQtuZXdNYXhEZXB0aAAABgkAAgECEWludmFsaWQgbWF4IGRlcHRoBQNuaWwDCQAAAgUFY2hla3MFBWNoZWtzCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFC2tleU1heERlcHRoBQtuZXdNYXhEZXB0aAUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBE3Byb2Nlc3NWb3RlSU5URVJOQUwCB3Bvb2xTdHIOdXNlckFkZHJlc3NTdHIEC2NoZWNrQ2FsbGVyCQEIbXVzdFRoaXMBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQLdXNlckFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQ51c2VyQWRkcmVzc1N0cgkArAICAipwcm9jZXNzVm90ZUlOVEVSTkFMOiBpbnZhbGlkIHVzZXIgYWRkcmVzcyAFDnVzZXJBZGRyZXNzU3RyBAVlcG9jaAkBDGdldEludE9yRmFpbAIFBHRoaXMFD2tleUN1cnJlbnRFcG9jaAQNZXBvY2hQcmV2aW91cwkAZQIFBWVwb2NoAAEEC2Vwb2NoTGVuZ3RoCQEMZ2V0SW50T3JGYWlsAgUEdGhpcwUOa2V5RXBvY2hMZW5ndGgEC3N0YXJ0SGVpZ2h0CQEMZ2V0SW50T3JGYWlsAgUEdGhpcwkBFWtleVN0YXJ0SGVpZ2h0QnlFcG9jaAEFBWVwb2NoBAllbmRIZWlnaHQJAGQCBQtzdGFydEhlaWdodAULZXBvY2hMZW5ndGgEE3N0YXJ0SGVpZ2h0UHJldmlvdXMJAQxnZXRJbnRPckZhaWwCBQR0aGlzCQEVa2V5U3RhcnRIZWlnaHRCeUVwb2NoAQUNZXBvY2hQcmV2aW91cwQRZW5kSGVpZ2h0UHJldmlvdXMJAGQCBRNzdGFydEhlaWdodFByZXZpb3VzBQtlcG9jaExlbmd0aAQQY2hlY2tUYXJnZXRFcG9jaAMJAGcCBQ1lcG9jaFByZXZpb3VzAAAGCQACAQIrcHJvY2Vzc1ZvdGVJTlRFUk5BTDogaW52YWxpZCBwcmV2aW91cyBlcG9jaAMJAAACBRBjaGVja1RhcmdldEVwb2NoBRBjaGVja1RhcmdldEVwb2NoBARwb29sCQEMc3RyaW5nVG9Qb29sAQUHcG9vbFN0cgQNJHQwMTc0MTgxNzQ1OAUEcG9vbAQNYW1vdW50QXNzZXRJZAgFDSR0MDE3NDE4MTc0NTgCXzEEDHByaWNlQXNzZXRJZAgFDSR0MDE3NDE4MTc0NTgCXzIEFWlzQW1vdW50QXNzZXRWZXJpZmllZAkBD2lzQXNzZXRWZXJpZmllZAEFDWFtb3VudEFzc2V0SWQEE2d3eEFtb3VudEF0RW5kVG90YWwKAAFACQD8BwQFBHRoaXMCGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAkAzAgCBQ51c2VyQWRkcmVzc1N0cgkAzAgCBQllbmRIZWlnaHQFA25pbAUDbmlsAwkAAQIFAUACA0ludAUBQAkAAgEJAKwCAgkAAwEJAPwHBAUEdGhpcwIYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0CQDMCAIFDnVzZXJBZGRyZXNzU3RyCQDMCAIFCWVuZEhlaWdodAUDbmlsBQNuaWwCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQbZ3d4QW1vdW50QXRFbmRUb3RhbFByZXZpb3VzCgABQAkA/AcEBQR0aGlzAhhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQJAMwIAgUOdXNlckFkZHJlc3NTdHIJAMwIAgURZW5kSGVpZ2h0UHJldmlvdXMFA25pbAUDbmlsAwkAAQIFAUACA0ludAUBQAkAAgEJAKwCAgkAAwEJAPwHBAUEdGhpcwIYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0CQDMCAIFDnVzZXJBZGRyZXNzU3RyCQDMCAIFEWVuZEhlaWdodFByZXZpb3VzBQNuaWwFA25pbAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50BAp0b3RhbFZvdGVzCQELdmFsdWVPckVsc2UCCQCfCAEJAQ1rZXlUb3RhbFZvdGVzAQUFZXBvY2gAAAQMdm90aW5nUmVzdWx0CQELdmFsdWVPckVsc2UCCQCfCAEJAQ9rZXlWb3RpbmdSZXN1bHQCBQRwb29sBQVlcG9jaAAABAx2b3RlUHJldmlvdXMJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBCQEHa2V5Vm90ZQMFBHBvb2wFC3VzZXJBZGRyZXNzBQ1lcG9jaFByZXZpb3VzCQCsAgIJAKwCAgkArAICCQCsAgICFHByb2Nlc3NWb3RlSU5URVJOQUwgBQdwb29sU3RyAgEgBQ51c2VyQWRkcmVzc1N0cgISOiBubyBwcmV2aW91cyB2b3RlBAR1c2VkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQdrZXlVc2VkAgULdXNlckFkZHJlc3MFBWVwb2NoAAAEB25ld1ZvdGUJAGsDBQx2b3RlUHJldmlvdXMFE2d3eEFtb3VudEF0RW5kVG90YWwFG2d3eEFtb3VudEF0RW5kVG90YWxQcmV2aW91cwQHYWN0aW9ucwMDCQBmAgUHbmV3Vm90ZQAABRVpc0Ftb3VudEFzc2V0VmVyaWZpZWQHCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEHa2V5Vm90ZQMFBHBvb2wFC3VzZXJBZGRyZXNzBQVlcG9jaAUHbmV3Vm90ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDWtleVRvdGFsVm90ZXMBBQVlcG9jaAkAZAIFCnRvdGFsVm90ZXMFB25ld1ZvdGUJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ9rZXlWb3RpbmdSZXN1bHQCBQRwb29sBQVlcG9jaAkAZAIFDHZvdGluZ1Jlc3VsdAUHbmV3Vm90ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBB2tleVVzZWQCBQt1c2VyQWRkcmVzcwUFZXBvY2gJAGQCBQR1c2VkBQduZXdWb3RlBQNuaWwJARFkZWxldGVOb2RlQWN0aW9ucwIJARBnZXRWb3Rlc0xpc3ROYW1lAQUEcG9vbAUOdXNlckFkZHJlc3NTdHIJAJQKAgUHYWN0aW9ucwUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARNwcm9jZXNzUG9vbElOVEVSTkFMAQdwb29sU3RyBAtjaGVja0NhbGxlcgkBCG11c3RUaGlzAQUBaQMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIEC3RhcmdldEVwb2NoCQBlAgkBDGdldEludE9yRmFpbAIFBHRoaXMFD2tleUN1cnJlbnRFcG9jaAABBBBjaGVja1RhcmdldEVwb2NoAwkAZwIFC3RhcmdldEVwb2NoAAAGCQACAQIpcHJvY2Vzc1Bvb2xJTlRFUk5BTDogaW52YWxpZCB0YXJnZXQgZXBvY2gDCQAAAgUQY2hlY2tUYXJnZXRFcG9jaAUQY2hlY2tUYXJnZXRFcG9jaAQEcG9vbAkBDHN0cmluZ1RvUG9vbAEFB3Bvb2xTdHIEDSR0MDE4OTk3MTkwMzcFBHBvb2wEDWFtb3VudEFzc2V0SWQIBQ0kdDAxODk5NzE5MDM3Al8xBAxwcmljZUFzc2V0SWQIBQ0kdDAxODk5NzE5MDM3Al8yBA9zdGFraW5nQ29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQxnZXRTdHJPckZhaWwCBQR0aGlzBRJrZXlTdGFraW5nQ29udHJhY3QED2ZhY3RvcnlDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDGdldFN0ck9yRmFpbAIFBHRoaXMFEmtleUZhY3RvcnlDb250cmFjdAQJbHBBc3NldElkCQEWZ2V0THBBc3NldEJ5UG9vbEFzc2V0cwIFDWFtb3VudEFzc2V0SWQFDHByaWNlQXNzZXRJZAQBcgoAAUAJAPwHBAUPc3Rha2luZ0NvbnRyYWN0AhJ1c2Vyc0xpc3RUcmF2ZXJzYWwJAMwIAgUJbHBBc3NldElkBQNuaWwFA25pbAMJAAECBQFAAgdCb29sZWFuBQFACQACAQkArAICCQADAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCEnVzZXJzTGlzdFRyYXZlcnNhbAkAzAgCBQlscEFzc2V0SWQFA25pbAUDbmlsAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuAwkAAAIFAXIFAXIDBQFyCQCUCgIFA25pbAYEFWlzQW1vdW50QXNzZXRWZXJpZmllZAkBD2lzQXNzZXRWZXJpZmllZAEFDWFtb3VudEFzc2V0SWQECnRvdGFsVm90ZXMJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBDWtleVRvdGFsVm90ZXMBBQt0YXJnZXRFcG9jaAAABAx2b3RpbmdSZXN1bHQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBD2tleVZvdGluZ1Jlc3VsdAIFBHBvb2wFC3RhcmdldEVwb2NoAAAEBXNoYXJlAwMJAAACBQp0b3RhbFZvdGVzAAAGCQEBIQEFFWlzQW1vdW50QXNzZXRWZXJpZmllZAAACQBrAwUMdm90aW5nUmVzdWx0BQ5wb29sV2VpZ2h0TXVsdAUKdG90YWxWb3RlcwQPbW9kaWZ5V2VpZ2h0SW52CQD8BwQFD2ZhY3RvcnlDb250cmFjdAIMbW9kaWZ5V2VpZ2h0CQDMCAIFCWxwQXNzZXRJZAkAzAgCBQVzaGFyZQUDbmlsBQNuaWwDCQAAAgUPbW9kaWZ5V2VpZ2h0SW52BQ9tb2RpZnlXZWlnaHRJbnYEEHBvb2xzTGlzdEFjdGlvbnMDBRVpc0Ftb3VudEFzc2V0VmVyaWZpZWQFA25pbAkAzggCCQDMCAIJAQtEZWxldGVFbnRyeQEJAQlrZXlJbkxpc3QBBQRwb29sBQNuaWwJARFkZWxldGVOb2RlQWN0aW9ucwIFDXBvb2xzTGlzdE5hbWUFB3Bvb2xTdHIJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEMa2V5UG9vbFNoYXJlAgUEcG9vbAULdGFyZ2V0RXBvY2gFBXNoYXJlBQNuaWwFEHBvb2xzTGlzdEFjdGlvbnMHCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDmZpbmFsaXplSGVscGVyAAQFZXBvY2gJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUPa2V5Q3VycmVudEVwb2NoAAAEDXByZXZpb3VzRXBvY2gJAGUCBQVlcG9jaAABBAtzdGFydEhlaWdodAkBDGdldEludE9yRmFpbAIFBHRoaXMJARVrZXlTdGFydEhlaWdodEJ5RXBvY2gBBQVlcG9jaAQLZXBvY2hMZW5ndGgJAQxnZXRJbnRPckZhaWwCBQR0aGlzBQ5rZXlFcG9jaExlbmd0aAQJZW5kSGVpZ2h0CQBkAgULc3RhcnRIZWlnaHQFC2Vwb2NoTGVuZ3RoBBdmaW5hbGl6YXRpb25TdGFnZU9yVW5pdAkAmggCBQR0aGlzBRRrZXlGaW5hbGl6YXRpb25TdGFnZQMJAGcCBQZoZWlnaHQFCWVuZEhlaWdodAQIbmV3RXBvY2gJAGQCBQVlcG9jaAABCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJARVrZXlTdGFydEhlaWdodEJ5RXBvY2gBBQhuZXdFcG9jaAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5rZXlTdGFydEhlaWdodAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9rZXlDdXJyZW50RXBvY2gFCG5ld0Vwb2NoCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRRrZXlGaW5hbGl6YXRpb25TdGFnZQUWZmluYWxpemF0aW9uU3RhZ2VUb3RhbAUDbmlsBgMJAAACBRdmaW5hbGl6YXRpb25TdGFnZU9yVW5pdAUEdW5pdAkAlAoCBQNuaWwHAwkAAAIFF2ZpbmFsaXphdGlvblN0YWdlT3JVbml0BRZmaW5hbGl6YXRpb25TdGFnZVRvdGFsBApwb29sT3JVbml0CQCiCAEFC2tleU5leHRQb29sBAp1c2VyT3JVbml0CQCiCAEFC2tleU5leHRVc2VyBAckbWF0Y2gwBQpwb29sT3JVbml0AwkAAQIFByRtYXRjaDACBFVuaXQEByRtYXRjaDEJAKIIAQkBC2tleUxpc3RIZWFkAQUNcG9vbHNMaXN0TmFtZQMJAAECBQckbWF0Y2gxAgRVbml0CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFFGtleUZpbmFsaXphdGlvblN0YWdlBRdmaW5hbGl6YXRpb25TdGFnZVNoYXJlcwkAzAgCCQELRGVsZXRlRW50cnkBBQtrZXlOZXh0UG9vbAkAzAgCCQELRGVsZXRlRW50cnkBBQtrZXlOZXh0VXNlcgUDbmlsBgMJAAECBQckbWF0Y2gxAgZTdHJpbmcEDHBvb2xzSGVhZFN0cgUHJG1hdGNoMQkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFC2tleU5leHRQb29sBQxwb29sc0hlYWRTdHIFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEB3Bvb2xTdHIFByRtYXRjaDAEBHBvb2wJAQxzdHJpbmdUb1Bvb2wBBQdwb29sU3RyBA5uZXh0VXNlck9yVW5pdAQHJG1hdGNoMQUKdXNlck9yVW5pdAMJAAECBQckbWF0Y2gxAgRVbml0CQCiCAEJAQtrZXlMaXN0SGVhZAEJARBnZXRWb3Rlc0xpc3ROYW1lAQUEcG9vbAMJAAECBQckbWF0Y2gxAgZTdHJpbmcEBHVzZXIFByRtYXRjaDEEDnByb2Nlc3NWb3RlSW52CQD8BwQFBHRoaXMCE3Byb2Nlc3NWb3RlSU5URVJOQUwJAMwIAgUHcG9vbFN0cgkAzAgCBQR1c2VyBQNuaWwFA25pbAMJAAACBQ5wcm9jZXNzVm90ZUludgUOcHJvY2Vzc1ZvdGVJbnYJAKIIAQkBC2tleUxpc3ROZXh0AgkBEGdldFZvdGVzTGlzdE5hbWUBBQRwb29sBQR1c2VyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQILTWF0Y2ggZXJyb3IEByRtYXRjaDEFDm5leHRVc2VyT3JVbml0AwkAAQIFByRtYXRjaDECBFVuaXQEDm5leHRQb29sT3JVbml0CQCiCAEJAQtrZXlMaXN0TmV4dAIFDXBvb2xzTGlzdE5hbWUFB3Bvb2xTdHIEByRtYXRjaDIFDm5leHRQb29sT3JVbml0AwkAAQIFByRtYXRjaDICBFVuaXQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUUa2V5RmluYWxpemF0aW9uU3RhZ2UFF2ZpbmFsaXphdGlvblN0YWdlU2hhcmVzCQDMCAIJAQtEZWxldGVFbnRyeQEFC2tleU5leHRQb29sCQDMCAIJAQtEZWxldGVFbnRyeQEFC2tleU5leHRVc2VyBQNuaWwGAwkAAQIFByRtYXRjaDICBlN0cmluZwQBcwUHJG1hdGNoMgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFC2tleU5leHRQb29sBQFzCQDMCAIJAQtEZWxldGVFbnRyeQEFC2tleU5leHRVc2VyBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IDCQABAgUHJG1hdGNoMQIGU3RyaW5nBAhuZXh0VXNlcgUHJG1hdGNoMQkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFC2tleU5leHRVc2VyBQhuZXh0VXNlcgUDbmlsBgkAAgECC01hdGNoIGVycm9yCQACAQILTWF0Y2ggZXJyb3IDCQAAAgUXZmluYWxpemF0aW9uU3RhZ2VPclVuaXQFF2ZpbmFsaXphdGlvblN0YWdlU2hhcmVzBApwb29sT3JVbml0CQCiCAEFC2tleU5leHRQb29sBAckbWF0Y2gwBQpwb29sT3JVbml0AwkAAQIFByRtYXRjaDACBFVuaXQEByRtYXRjaDEJAKIIAQkBC2tleUxpc3RIZWFkAQUNcG9vbHNMaXN0TmFtZQMJAAECBQckbWF0Y2gxAgRVbml0CQCUCgIJAMwIAgkBC0RlbGV0ZUVudHJ5AQUUa2V5RmluYWxpemF0aW9uU3RhZ2UJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQxrZXlGaW5hbGl6ZWQBBQ1wcmV2aW91c0Vwb2NoBgkAzAgCCQEMSW50ZWdlckVudHJ5AgURa2V5Q3VycmVudEVwb2NoVWkFBWVwb2NoCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRBrZXlTdGFydEhlaWdodFVpBQtzdGFydEhlaWdodAUDbmlsBgMJAAECBQckbWF0Y2gxAgZTdHJpbmcEC25leHRQb29sU3RyBQckbWF0Y2gxCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgULa2V5TmV4dFBvb2wFC25leHRQb29sU3RyBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAdwb29sU3RyBQckbWF0Y2gwBAFyCgABQAkA/AcEBQR0aGlzAhNwcm9jZXNzUG9vbElOVEVSTkFMCQDMCAIFB3Bvb2xTdHIFA25pbAUDbmlsAwkAAQIFAUACB0Jvb2xlYW4FAUAJAAIBCQCsAgIJAAMBCQD8BwQFBHRoaXMCE3Byb2Nlc3NQb29sSU5URVJOQUwJAMwIAgUHcG9vbFN0cgUDbmlsBQNuaWwCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUBcgUBcgMFAXIJAJQKAgUDbmlsBgQObmV4dFBvb2xPclVuaXQJAKIIAQkBC2tleUxpc3ROZXh0AgUNcG9vbHNMaXN0TmFtZQUHcG9vbFN0cgQHJG1hdGNoMQUObmV4dFBvb2xPclVuaXQDCQABAgUHJG1hdGNoMQIEVW5pdAkAlAoCCQDMCAIJAQtEZWxldGVFbnRyeQEFFGtleUZpbmFsaXphdGlvblN0YWdlCQDMCAIJAQxCb29sZWFuRW50cnkCCQEMa2V5RmluYWxpemVkAQUNcHJldmlvdXNFcG9jaAYJAMwIAgkBDEludGVnZXJFbnRyeQIFEWtleUN1cnJlbnRFcG9jaFVpBQVlcG9jaAkAzAgCCQEMSW50ZWdlckVudHJ5AgUQa2V5U3RhcnRIZWlnaHRVaQULc3RhcnRIZWlnaHQJAMwIAgkBC0RlbGV0ZUVudHJ5AQULa2V5TmV4dFBvb2wFA25pbAYDCQABAgUHJG1hdGNoMQIGU3RyaW5nBAtuZXh0UG9vbFN0cgUHJG1hdGNoMQkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFC2tleU5leHRQb29sBQtuZXh0UG9vbFN0cgUDbmlsBgkAAgECC01hdGNoIGVycm9yCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQILTWF0Y2ggZXJyb3IJAAIBAhZmaW5hbGl6YXRpb24gaXMgYnJva2VuAWkBD2ZpbmFsaXplV3JhcHBlcgEHY291bnRlcgQGcmVzdWx0CgABQAkA/AcEBQR0aGlzAg5maW5hbGl6ZUhlbHBlcgUDbmlsBQNuaWwDCQABAgUBQAIHQm9vbGVhbgUBQAkAAgEJAKwCAgkAAwEJAPwHBAUEdGhpcwIOZmluYWxpemVIZWxwZXIFA25pbAUDbmlsAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuAwkAAAIFBnJlc3VsdAUGcmVzdWx0AwkBASEBBQZyZXN1bHQDCQAAAgUHY291bnRlcgAACQACAQIeQ3VycmVudCB2b3RpbmcgaXMgbm90IG92ZXIgeWV0CQCUCgIFA25pbAUEdW5pdAQIbWF4RGVwdGgJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwULa2V5TWF4RGVwdGgFD21heERlcHRoRGVmYXVsdAMJAGYCBQhtYXhEZXB0aAUHY291bnRlcgQDaW52CQD8BwQFBHRoaXMCD2ZpbmFsaXplV3JhcHBlcgkAzAgCCQBkAgUHY291bnRlcgABBQNuaWwFA25pbAMJAAACBQNpbnYFA2ludgkAlAoCBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCGZpbmFsaXplAAQDaW52CQD8BwQFBHRoaXMCD2ZpbmFsaXplV3JhcHBlcgkAzAgCAAAFA25pbAUDbmlsAwkAAAIFA2ludgUDaW52CQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARJvblZlcmlmaWNhdGlvbkxvc3MBB2Fzc2V0SWQJAJQKAgUDbmlsBQR1bml0AWkBFGNvbnRhaW5zTm9kZVJFQURPTkxZAghsaXN0TmFtZQJpZAkAlAoCBQNuaWwJAQxjb250YWluc05vZGUCBQhsaXN0TmFtZQUCaWQBaQEKaW5zZXJ0Tm9kZQIIbGlzdE5hbWUCaWQEC2NoZWNrQ2FsbGVyCQELbXVzdE1hbmFnZXIBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgkAlAoCCQERaW5zZXJ0Tm9kZUFjdGlvbnMCBQhsaXN0TmFtZQUCaWQFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKZGVsZXRlTm9kZQIIbGlzdE5hbWUCaWQEC2NoZWNrQ2FsbGVyCQELbXVzdE1hbmFnZXIBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgkAlAoCCQERZGVsZXRlTm9kZUFjdGlvbnMCBQhsaXN0TmFtZQUCaWQFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAnR4AQZ2ZXJpZnkABA90YXJnZXRQdWJsaWNLZXkEByRtYXRjaDAJARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAUCcGsDCQABAgUHJG1hdGNoMAIEVW5pdAgFAnR4D3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQ90YXJnZXRQdWJsaWNLZXmpguwS", "chainId": 84, "height": 2107661, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5onWkaJRBHfGjUcqGk4tUz1cA8dbDDN5R6GxnRP47dPB Next: GFMy6xZ5gD7imZhtnAWP6ooHWfLwXbpbNW2FXvMdniHT Diff:
OldNewDifferences
2525
2626 let keyStakingContract = makeString(["%s", "stakingContract"], separator)
2727
28+let keyAssetsStoreContract = makeString(["%s", "assetsStoreContract"], separator)
29+
2830 let keyFinalizationStage = makeString(["%s", "finalizationStage"], separator)
2931
3032 let keyNextPool = makeString(["%s", "nextPool"], separator)
4446
4547
4648 func keyInList (pool) = {
47- let $t014361476 = pool
48- let amountAssetId = $t014361476._1
49- let priceAssetId = $t014361476._2
49+ let $t015171557 = pool
50+ let amountAssetId = $t015171557._1
51+ let priceAssetId = $t015171557._2
5052 makeString(["%s%s%s", "inList", amountAssetId, priceAssetId], separator)
5153 }
5254
5557
5658
5759 func keyVote (pool,address,epoch) = {
58- let $t017501790 = pool
59- let amountAssetId = $t017501790._1
60- let priceAssetId = $t017501790._2
60+ let $t018311871 = pool
61+ let amountAssetId = $t018311871._1
62+ let priceAssetId = $t018311871._2
6163 makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], separator)
6264 }
6365
6466
6567 func keyVotingResult (pool,epoch) = {
66- let $t019722012 = pool
67- let amountAssetId = $t019722012._1
68- let priceAssetId = $t019722012._2
68+ let $t020532093 = pool
69+ let amountAssetId = $t020532093._1
70+ let priceAssetId = $t020532093._2
6971 makeString(["%s%s%s%d", "votingResult", amountAssetId, priceAssetId, toString(epoch)], separator)
7072 }
7173
7274
7375 func keyPoolShare (pool,epoch) = {
74- let $t021772217 = pool
75- let amountAssetId = $t021772217._1
76- let priceAssetId = $t021772217._2
76+ let $t022582298 = pool
77+ let amountAssetId = $t022582298._1
78+ let priceAssetId = $t022582298._2
7779 makeString(["%s%s%s%d", "poolShare", amountAssetId, priceAssetId, toString(epoch)], separator)
7880 }
7981
137139 }
138140
139141
142+func isAssetVerified (assetId) = {
143+ let assetsStoreContract = addressFromStringValue(getStrOrFail(this, keyAssetsStoreContract))
144+ let isVerified = {
145+ let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [assetId], nil)
146+ if ($isInstanceOf(@, "Boolean"))
147+ then @
148+ else throw(($getType(invoke(assetsStoreContract, "isVerifiedREADONLY", [assetId], nil)) + " couldn't be cast to Boolean"))
149+ }
150+ isVerified
151+ }
152+
153+
140154 let poolsListName = "pools"
141155
142156 func getVotesListName (pool) = {
143- let $t045034543 = pool
144- let amountAssetId = $t045034543._1
145- let priceAssetId = $t045034543._2
157+ let $t048384878 = pool
158+ let amountAssetId = $t048384878._1
159+ let priceAssetId = $t048384878._2
146160 makeString(["votes", amountAssetId, priceAssetId], separator)
147161 }
148162
318332
319333
320334 @Callable(i)
321-func constructor (factoryContract,votingEmissionCandidateContract,boostingContract,stakingContract,epochLength) = {
335+func constructor (factoryContract,votingEmissionCandidateContract,boostingContract,stakingContract,assetsStoreContract,epochLength) = {
322336 let cheks = [mustManager(i), if ((addressFromString(factoryContract) != unit))
323337 then true
324338 else "invalid factory contract address", if ((addressFromString(votingEmissionCandidateContract) != unit))
327341 then true
328342 else "invalid boosting contract address", if ((addressFromString(stakingContract) != unit))
329343 then true
330- else "invalid staking contract address", if ((epochLength > 0))
344+ else "invalid staking contract address", if ((addressFromString(assetsStoreContract) != unit))
345+ then true
346+ else "invalid assets store contract address", if ((epochLength > 0))
331347 then true
332348 else throw("invalid epoch length")]
333349 if ((cheks == cheks))
334- then $Tuple2([StringEntry(keyFactoryContract, factoryContract), StringEntry(keyVotingEmissionCandidateContract, votingEmissionCandidateContract), StringEntry(keyBoostingContract, boostingContract), StringEntry(keyStakingContract, stakingContract), IntegerEntry(keyEpochLength, epochLength)], unit)
350+ then $Tuple2([StringEntry(keyFactoryContract, factoryContract), StringEntry(keyVotingEmissionCandidateContract, votingEmissionCandidateContract), StringEntry(keyBoostingContract, boostingContract), StringEntry(keyStakingContract, stakingContract), StringEntry(keyAssetsStoreContract, assetsStoreContract), IntegerEntry(keyEpochLength, epochLength)], unit)
335351 else throw("Strict value is not equal to itself.")
336352 }
337353
380396 }
381397 let available = (gwxAmountAtEndTotal - used)
382398 let newVote = (vote + amount)
399+ let isAmountAssetVerified = isAssetVerified(amountAssetId)
383400 let checks = [if ((getBoolean(keyInList(pool)) != unit))
384401 then true
385402 else throw("invalid assets"), if ((endHeight > height))
392409 then (available >= amount)
393410 else false)
394411 then true
395- else throw("invalid amount")]
412+ else throw("invalid amount"), if (isAmountAssetVerified)
413+ then true
414+ else throw("amount asset is not verified")]
396415 if ((checks == checks))
397416 then {
398417 let votesListName = getVotesListName(pool)
482501 if ((checkTargetEpoch == checkTargetEpoch))
483502 then {
484503 let pool = stringToPool(poolStr)
504+ let $t01741817458 = pool
505+ let amountAssetId = $t01741817458._1
506+ let priceAssetId = $t01741817458._2
507+ let isAmountAssetVerified = isAssetVerified(amountAssetId)
485508 let gwxAmountAtEndTotal = {
486509 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
487510 if ($isInstanceOf(@, "Int"))
499522 let votePrevious = valueOrErrorMessage(getInteger(keyVote(pool, userAddress, epochPrevious)), (((("processVoteINTERNAL " + poolStr) + " ") + userAddressStr) + ": no previous vote"))
500523 let used = valueOrElse(getInteger(this, keyUsed(userAddress, epoch)), 0)
501524 let newVote = fraction(votePrevious, gwxAmountAtEndTotal, gwxAmountAtEndTotalPrevious)
502- let actions = if ((newVote > 0))
525+ let actions = if (if ((newVote > 0))
526+ then isAmountAssetVerified
527+ else false)
503528 then [IntegerEntry(keyVote(pool, userAddress, epoch), newVote), IntegerEntry(keyTotalVotes(epoch), (totalVotes + newVote)), IntegerEntry(keyVotingResult(pool, epoch), (votingResult + newVote)), IntegerEntry(keyUsed(userAddress, epoch), (used + newVote))]
504529 else deleteNodeActions(getVotesListName(pool), userAddressStr)
505530 $Tuple2(actions, unit)
523548 if ((checkTargetEpoch == checkTargetEpoch))
524549 then {
525550 let pool = stringToPool(poolStr)
526- let $t01821018250 = pool
527- let amountAssetId = $t01821018250._1
528- let priceAssetId = $t01821018250._2
551+ let $t01899719037 = pool
552+ let amountAssetId = $t01899719037._1
553+ let priceAssetId = $t01899719037._2
529554 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
530555 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
531556 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
539564 then if (r)
540565 then $Tuple2(nil, true)
541566 else {
567+ let isAmountAssetVerified = isAssetVerified(amountAssetId)
542568 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
543569 let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
544- let share = if ((totalVotes == 0))
570+ let share = if (if ((totalVotes == 0))
571+ then true
572+ else !(isAmountAssetVerified))
545573 then 0
546574 else fraction(votingResult, poolWeightMult, totalVotes)
547575 let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
548576 if ((modifyWeightInv == modifyWeightInv))
549- then $Tuple2([IntegerEntry(keyPoolShare(pool, targetEpoch), share)], false)
577+ then {
578+ let poolsListActions = if (isAmountAssetVerified)
579+ then nil
580+ else ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolStr))
581+ $Tuple2(([IntegerEntry(keyPoolShare(pool, targetEpoch), share)] ++ poolsListActions), false)
582+ }
550583 else throw("Strict value is not equal to itself.")
551584 }
552585 else throw("Strict value is not equal to itself.")
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
55
66 let poolWeightMult = 100000000
77
88 let maxDepthDefault = 10
99
1010 let finalizationStageTotal = 0
1111
1212 let finalizationStageShares = 1
1313
1414 let keyEpochLength = makeString(["%s", "epochLength"], separator)
1515
1616 let keyCurrentEpoch = makeString(["%s", "currentEpoch"], separator)
1717
1818 let keyMaxDepth = makeString(["%s", "maxDepth"], separator)
1919
2020 let keyVotingEmissionCandidateContract = makeString(["%s", "votingEmissionCandidateContract"], separator)
2121
2222 let keyFactoryContract = makeString(["%s", "factoryContract"], separator)
2323
2424 let keyBoostingContract = makeString(["%s", "boostingContract"], separator)
2525
2626 let keyStakingContract = makeString(["%s", "stakingContract"], separator)
2727
28+let keyAssetsStoreContract = makeString(["%s", "assetsStoreContract"], separator)
29+
2830 let keyFinalizationStage = makeString(["%s", "finalizationStage"], separator)
2931
3032 let keyNextPool = makeString(["%s", "nextPool"], separator)
3133
3234 let keyNextUser = makeString(["%s", "nextUser"], separator)
3335
3436 let keyStartHeight = makeString(["%s", "startHeight"], separator)
3537
3638 let keyCurrentEpochUi = makeString(["%s", "currentEpochUi"], separator)
3739
3840 let keyStartHeightUi = makeString(["%s", "startHeightUi"], separator)
3941
4042 func keyStartHeightByEpoch (epoch) = makeString(["%s%d", "startHeight", toString(epoch)], separator)
4143
4244
4345 func keyFinalized (epoch) = makeString(["%s%d", "finalized", toString(epoch)], separator)
4446
4547
4648 func keyInList (pool) = {
47- let $t014361476 = pool
48- let amountAssetId = $t014361476._1
49- let priceAssetId = $t014361476._2
49+ let $t015171557 = pool
50+ let amountAssetId = $t015171557._1
51+ let priceAssetId = $t015171557._2
5052 makeString(["%s%s%s", "inList", amountAssetId, priceAssetId], separator)
5153 }
5254
5355
5456 func keyUsed (address,epoch) = makeString(["%s%s%d", "used", toString(address), toString(epoch)], separator)
5557
5658
5759 func keyVote (pool,address,epoch) = {
58- let $t017501790 = pool
59- let amountAssetId = $t017501790._1
60- let priceAssetId = $t017501790._2
60+ let $t018311871 = pool
61+ let amountAssetId = $t018311871._1
62+ let priceAssetId = $t018311871._2
6163 makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], separator)
6264 }
6365
6466
6567 func keyVotingResult (pool,epoch) = {
66- let $t019722012 = pool
67- let amountAssetId = $t019722012._1
68- let priceAssetId = $t019722012._2
68+ let $t020532093 = pool
69+ let amountAssetId = $t020532093._1
70+ let priceAssetId = $t020532093._2
6971 makeString(["%s%s%s%d", "votingResult", amountAssetId, priceAssetId, toString(epoch)], separator)
7072 }
7173
7274
7375 func keyPoolShare (pool,epoch) = {
74- let $t021772217 = pool
75- let amountAssetId = $t021772217._1
76- let priceAssetId = $t021772217._2
76+ let $t022582298 = pool
77+ let amountAssetId = $t022582298._1
78+ let priceAssetId = $t022582298._2
7779 makeString(["%s%s%s%d", "poolShare", amountAssetId, priceAssetId, toString(epoch)], separator)
7880 }
7981
8082
8183 func keyTotalVotes (epoch) = makeString(["%s%d", "totalVotes", toString(epoch)], separator)
8284
8385
8486 func getValueOrFail (address,key,type) = {
8587 let error = makeString(["mandatory ", toString(address), ".", key, " is not defined"], "")
8688 valueOrErrorMessage( match type {
8789 case str: String =>
8890 getString(address, key)
8991 case int: Int =>
9092 getInteger(address, key)
9193 case _ =>
9294 throw("invalid entry type")
9395 }, error)
9496 }
9597
9698
9799 func getStrOrFail (address,key) = {
98100 let @ = getValueOrFail(address, key, "")
99101 if ($isInstanceOf(@, "String"))
100102 then @
101103 else throw(($getType(getValueOrFail(address, key, "")) + " couldn't be cast to String"))
102104 }
103105
104106
105107 func getIntOrFail (address,key) = {
106108 let @ = getValueOrFail(address, key, 0)
107109 if ($isInstanceOf(@, "Int"))
108110 then @
109111 else throw(($getType(getValueOrFail(address, key, 0)) + " couldn't be cast to Int"))
110112 }
111113
112114
113115 func poolToString (pool) = ((pool._1 + separator) + pool._2)
114116
115117
116118 func stringToPool (str) = {
117119 let parts = split(str, separator)
118120 if ((size(parts) == 2))
119121 then $Tuple2(parts[0], parts[1])
120122 else throw("invalid pool string")
121123 }
122124
123125
124126 func getLpAssetByPoolAssets (amountAssetId,priceAssetId) = {
125127 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
126128
127129 func keyMappingPoolAssetsToPoolContractAddress (internalAmountAssetIdStr,internalPriceAssetIdStr) = (((("%d%d%s%s__" + toString(internalAmountAssetIdStr)) + "__") + toString(internalPriceAssetIdStr)) + "__mappings__poolAssets2PoolContract")
128130
129131 func keyMappingPoolContractToLPAsset (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
130132
131133 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
132134 let amountAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amountAssetId))
133135 let priceAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAssetId))
134136 let poolContractAddress = getStrOrFail(factoryContract, keyMappingPoolAssetsToPoolContractAddress(amountAssetInternalId, priceAssetInternalId))
135137 let lpAssetId = getStrOrFail(factoryContract, keyMappingPoolContractToLPAsset(poolContractAddress))
136138 lpAssetId
137139 }
138140
139141
142+func isAssetVerified (assetId) = {
143+ let assetsStoreContract = addressFromStringValue(getStrOrFail(this, keyAssetsStoreContract))
144+ let isVerified = {
145+ let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [assetId], nil)
146+ if ($isInstanceOf(@, "Boolean"))
147+ then @
148+ else throw(($getType(invoke(assetsStoreContract, "isVerifiedREADONLY", [assetId], nil)) + " couldn't be cast to Boolean"))
149+ }
150+ isVerified
151+ }
152+
153+
140154 let poolsListName = "pools"
141155
142156 func getVotesListName (pool) = {
143- let $t045034543 = pool
144- let amountAssetId = $t045034543._1
145- let priceAssetId = $t045034543._2
157+ let $t048384878 = pool
158+ let amountAssetId = $t048384878._1
159+ let priceAssetId = $t048384878._2
146160 makeString(["votes", amountAssetId, priceAssetId], separator)
147161 }
148162
149163
150164 func keyListHead (listName) = {
151165 let meta = if ((listName == poolsListName))
152166 then "%s%s"
153167 else "%s%s%s%s"
154168 makeString([meta, listName, "head"], separator)
155169 }
156170
157171
158172 func keyListSize (listName) = {
159173 let meta = if ((listName == poolsListName))
160174 then "%s%s"
161175 else "%s%s%s%s"
162176 makeString([meta, listName, "size"], separator)
163177 }
164178
165179
166180 func keyListPrev (listName,id) = {
167181 let meta = if ((listName == poolsListName))
168182 then "%s%s%s%s"
169183 else "%s%s%s%s%s"
170184 makeString([meta, listName, id, "prev"], separator)
171185 }
172186
173187
174188 func keyListNext (listName,id) = {
175189 let meta = if ((listName == poolsListName))
176190 then "%s%s%s%s"
177191 else "%s%s%s%s%s"
178192 makeString([meta, listName, id, "next"], separator)
179193 }
180194
181195
182196 func containsNode (listName,id) = {
183197 let headOrUnit = getString(this, keyListHead(listName))
184198 let prevOrUnit = getString(this, keyListPrev(listName, id))
185199 let nextOrUnit = getString(this, keyListNext(listName, id))
186200 if (if ((id == valueOrElse(headOrUnit, "")))
187201 then true
188202 else (prevOrUnit != unit))
189203 then true
190204 else (nextOrUnit != unit)
191205 }
192206
193207
194208 func insertNodeActions (listName,id) = {
195209 let headOrUnit = getString(this, keyListHead(listName))
196210 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
197211 let checkNode = if (!(containsNode(listName, id)))
198212 then true
199213 else throw("Node exists")
200214 if ((checkNode == checkNode))
201215 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
202216 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
203217 else nil)) ++ [StringEntry(keyListHead(listName), id)])
204218 else throw("Strict value is not equal to itself.")
205219 }
206220
207221
208222 func deleteNodeActions (listName,id) = {
209223 let headOrUnit = getString(this, keyListHead(listName))
210224 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
211225 let prevOrUnit = getString(this, keyListPrev(listName, id))
212226 let nextOrUnit = getString(this, keyListNext(listName, id))
213227 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
214228 then (nextOrUnit != unit)
215229 else false)
216230 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
217231 else if ((nextOrUnit != unit))
218232 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
219233 else if ((prevOrUnit != unit))
220234 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
221235 else if ((id == valueOrElse(headOrUnit, "")))
222236 then [DeleteEntry(keyListHead(listName))]
223237 else throw(((("invalid node: " + listName) + ".") + id))))
224238 }
225239
226240
227241 func keyManagerPublicKey () = "%s__managerPublicKey"
228242
229243
230244 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
231245
232246
233247 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
234248 case s: String =>
235249 fromBase58String(s)
236250 case _: Unit =>
237251 unit
238252 case _ =>
239253 throw("Match error")
240254 }
241255
242256
243257 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
244258 case s: String =>
245259 fromBase58String(s)
246260 case _: Unit =>
247261 unit
248262 case _ =>
249263 throw("Match error")
250264 }
251265
252266
253267 let permissionDeniedError = throw("Permission denied")
254268
255269 func mustThis (i) = if ((i.caller == this))
256270 then true
257271 else permissionDeniedError
258272
259273
260274 func mustManager (i) = match managerPublicKeyOrUnit() {
261275 case pk: ByteVector =>
262276 if ((i.callerPublicKey == pk))
263277 then true
264278 else permissionDeniedError
265279 case _: Unit =>
266280 mustThis(i)
267281 case _ =>
268282 throw("Match error")
269283 }
270284
271285
272286 @Callable(i)
273287 func setManager (pendingManagerPublicKey) = {
274288 let checkCaller = mustManager(i)
275289 if ((checkCaller == checkCaller))
276290 then {
277291 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
278292 if ((checkManagerPublicKey == checkManagerPublicKey))
279293 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
280294 else throw("Strict value is not equal to itself.")
281295 }
282296 else throw("Strict value is not equal to itself.")
283297 }
284298
285299
286300
287301 @Callable(i)
288302 func confirmManager () = {
289303 let pm = pendingManagerPublicKeyOrUnit()
290304 let hasPM = if (isDefined(pm))
291305 then true
292306 else throw("No pending manager")
293307 if ((hasPM == hasPM))
294308 then {
295309 let checkPM = if ((i.callerPublicKey == value(pm)))
296310 then true
297311 else throw("You are not pending manager")
298312 if ((checkPM == checkPM))
299313 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
300314 else throw("Strict value is not equal to itself.")
301315 }
302316 else throw("Strict value is not equal to itself.")
303317 }
304318
305319
306320
307321 @Callable(i)
308322 func getUserGwxAmountAtHeight (userAddress,targetHeight) = {
309323 let boostingContractAddress = valueOrErrorMessage(addressFromString(getStrOrFail(this, keyBoostingContract)), "invalid boosting contract address")
310324 $Tuple2(nil, {
311325 let @ = invoke(boostingContractAddress, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)
312326 if ($isInstanceOf(@, "Int"))
313327 then @
314328 else throw(($getType(invoke(boostingContractAddress, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)) + " couldn't be cast to Int"))
315329 })
316330 }
317331
318332
319333
320334 @Callable(i)
321-func constructor (factoryContract,votingEmissionCandidateContract,boostingContract,stakingContract,epochLength) = {
335+func constructor (factoryContract,votingEmissionCandidateContract,boostingContract,stakingContract,assetsStoreContract,epochLength) = {
322336 let cheks = [mustManager(i), if ((addressFromString(factoryContract) != unit))
323337 then true
324338 else "invalid factory contract address", if ((addressFromString(votingEmissionCandidateContract) != unit))
325339 then true
326340 else "invalid voting emission candidate contract address", if ((addressFromString(boostingContract) != unit))
327341 then true
328342 else "invalid boosting contract address", if ((addressFromString(stakingContract) != unit))
329343 then true
330- else "invalid staking contract address", if ((epochLength > 0))
344+ else "invalid staking contract address", if ((addressFromString(assetsStoreContract) != unit))
345+ then true
346+ else "invalid assets store contract address", if ((epochLength > 0))
331347 then true
332348 else throw("invalid epoch length")]
333349 if ((cheks == cheks))
334- then $Tuple2([StringEntry(keyFactoryContract, factoryContract), StringEntry(keyVotingEmissionCandidateContract, votingEmissionCandidateContract), StringEntry(keyBoostingContract, boostingContract), StringEntry(keyStakingContract, stakingContract), IntegerEntry(keyEpochLength, epochLength)], unit)
350+ then $Tuple2([StringEntry(keyFactoryContract, factoryContract), StringEntry(keyVotingEmissionCandidateContract, votingEmissionCandidateContract), StringEntry(keyBoostingContract, boostingContract), StringEntry(keyStakingContract, stakingContract), StringEntry(keyAssetsStoreContract, assetsStoreContract), IntegerEntry(keyEpochLength, epochLength)], unit)
335351 else throw("Strict value is not equal to itself.")
336352 }
337353
338354
339355
340356 @Callable(i)
341357 func create (amountAssetId,priceAssetId) = {
342358 let checks = [if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionCandidateContract), "")))
343359 then true
344360 else mustManager(i)]
345361 if ((checks == checks))
346362 then {
347363 let pool = $Tuple2(amountAssetId, priceAssetId)
348364 let inListActions = ([BooleanEntry(keyInList(pool), true)] ++ insertNodeActions(poolsListName, poolToString(pool)))
349365 let currentEpochIsNotDefined = (getInteger(this, keyCurrentEpoch) == unit)
350366 let startHeightActions = if (currentEpochIsNotDefined)
351367 then {
352368 let epoch = 0
353369 [IntegerEntry(keyCurrentEpoch, epoch), IntegerEntry(keyStartHeightByEpoch(epoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, height)]
354370 }
355371 else nil
356372 $Tuple2((inListActions ++ startHeightActions), unit)
357373 }
358374 else throw("Strict value is not equal to itself.")
359375 }
360376
361377
362378
363379 @Callable(i)
364380 func vote (amountAssetId,priceAssetId,amount) = {
365381 let pool = $Tuple2(amountAssetId, priceAssetId)
366382 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
367383 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
368384 let epochLength = getIntOrFail(this, keyEpochLength)
369385 let endHeight = (startHeight + epochLength)
370386 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
371387 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
372388 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
373389 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
374390 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
375391 let gwxAmountAtEndTotal = {
376392 let @ = invoke(this, "getUserGwxAmountAtHeight", [toBase58String(i.caller.bytes), endHeight], nil)
377393 if ($isInstanceOf(@, "Int"))
378394 then @
379395 else throw(($getType(invoke(this, "getUserGwxAmountAtHeight", [toBase58String(i.caller.bytes), endHeight], nil)) + " couldn't be cast to Int"))
380396 }
381397 let available = (gwxAmountAtEndTotal - used)
382398 let newVote = (vote + amount)
399+ let isAmountAssetVerified = isAssetVerified(amountAssetId)
383400 let checks = [if ((getBoolean(keyInList(pool)) != unit))
384401 then true
385402 else throw("invalid assets"), if ((endHeight > height))
386403 then true
387404 else throw("invalid height"), if ((finalizationStageOrUnit == unit))
388405 then true
389406 else throw("finalization in progress"), if ((gwxAmountAtEndTotal > 0))
390407 then true
391408 else throw("you do not have gWX"), if (if ((amount > 0))
392409 then (available >= amount)
393410 else false)
394411 then true
395- else throw("invalid amount")]
412+ else throw("invalid amount"), if (isAmountAssetVerified)
413+ then true
414+ else throw("amount asset is not verified")]
396415 if ((checks == checks))
397416 then {
398417 let votesListName = getVotesListName(pool)
399418 let userAddressStr = toString(i.caller)
400419 let votesListActions = if (containsNode(votesListName, userAddressStr))
401420 then nil
402421 else insertNodeActions(votesListName, userAddressStr)
403422 $Tuple2(([IntegerEntry(keyUsed(i.caller, epoch), (used + amount)), IntegerEntry(keyVote(pool, i.caller, epoch), newVote), IntegerEntry(keyVotingResult(pool, epoch), (poolResult + amount)), IntegerEntry(keyTotalVotes(epoch), (totalVotes + amount))] ++ votesListActions), unit)
404423 }
405424 else throw("Strict value is not equal to itself.")
406425 }
407426
408427
409428
410429 @Callable(i)
411430 func cancelVote (amountAssetId,priceAssetId) = {
412431 let pool = $Tuple2(amountAssetId, priceAssetId)
413432 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
414433 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
415434 let epochLength = getIntOrFail(this, keyEpochLength)
416435 let endHeight = (startHeight + epochLength)
417436 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
418437 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
419438 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
420439 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
421440 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
422441 let checks = [if ((getBoolean(keyInList(pool)) != unit))
423442 then true
424443 else throw("invalid assets"), if ((endHeight > height))
425444 then true
426445 else throw("invalid height"), if ((finalizationStageOrUnit == unit))
427446 then true
428447 else throw("finalization in progress"), if ((vote > 0))
429448 then true
430449 else throw("no vote")]
431450 if ((checks == checks))
432451 then {
433452 let votesListName = getVotesListName(pool)
434453 let userAddressStr = toString(i.caller)
435454 $Tuple2(([IntegerEntry(keyUsed(i.caller, epoch), max([(used - vote), 0])), DeleteEntry(keyVote(pool, i.caller, epoch)), IntegerEntry(keyVotingResult(pool, epoch), (poolResult - vote)), IntegerEntry(keyTotalVotes(epoch), (totalVotes - vote))] ++ deleteNodeActions(votesListName, userAddressStr)), unit)
436455 }
437456 else throw("Strict value is not equal to itself.")
438457 }
439458
440459
441460
442461 @Callable(i)
443462 func setEpochLength (newEpochLength) = {
444463 let cheks = [mustManager(i), if ((newEpochLength > 0))
445464 then true
446465 else throw("invalid epoch length")]
447466 if ((cheks == cheks))
448467 then $Tuple2([IntegerEntry(keyEpochLength, newEpochLength)], unit)
449468 else throw("Strict value is not equal to itself.")
450469 }
451470
452471
453472
454473 @Callable(i)
455474 func setMaxDepth (newMaxDepth) = {
456475 let cheks = [mustManager(i), if ((newMaxDepth > 0))
457476 then true
458477 else throw("invalid max depth")]
459478 if ((cheks == cheks))
460479 then $Tuple2([IntegerEntry(keyMaxDepth, newMaxDepth)], unit)
461480 else throw("Strict value is not equal to itself.")
462481 }
463482
464483
465484
466485 @Callable(i)
467486 func processVoteINTERNAL (poolStr,userAddressStr) = {
468487 let checkCaller = mustThis(i)
469488 if ((checkCaller == checkCaller))
470489 then {
471490 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), ("processVoteINTERNAL: invalid user address " + userAddressStr))
472491 let epoch = getIntOrFail(this, keyCurrentEpoch)
473492 let epochPrevious = (epoch - 1)
474493 let epochLength = getIntOrFail(this, keyEpochLength)
475494 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
476495 let endHeight = (startHeight + epochLength)
477496 let startHeightPrevious = getIntOrFail(this, keyStartHeightByEpoch(epochPrevious))
478497 let endHeightPrevious = (startHeightPrevious + epochLength)
479498 let checkTargetEpoch = if ((epochPrevious >= 0))
480499 then true
481500 else throw("processVoteINTERNAL: invalid previous epoch")
482501 if ((checkTargetEpoch == checkTargetEpoch))
483502 then {
484503 let pool = stringToPool(poolStr)
504+ let $t01741817458 = pool
505+ let amountAssetId = $t01741817458._1
506+ let priceAssetId = $t01741817458._2
507+ let isAmountAssetVerified = isAssetVerified(amountAssetId)
485508 let gwxAmountAtEndTotal = {
486509 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
487510 if ($isInstanceOf(@, "Int"))
488511 then @
489512 else throw(($getType(invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)) + " couldn't be cast to Int"))
490513 }
491514 let gwxAmountAtEndTotalPrevious = {
492515 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeightPrevious], nil)
493516 if ($isInstanceOf(@, "Int"))
494517 then @
495518 else throw(($getType(invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeightPrevious], nil)) + " couldn't be cast to Int"))
496519 }
497520 let totalVotes = valueOrElse(getInteger(keyTotalVotes(epoch)), 0)
498521 let votingResult = valueOrElse(getInteger(keyVotingResult(pool, epoch)), 0)
499522 let votePrevious = valueOrErrorMessage(getInteger(keyVote(pool, userAddress, epochPrevious)), (((("processVoteINTERNAL " + poolStr) + " ") + userAddressStr) + ": no previous vote"))
500523 let used = valueOrElse(getInteger(this, keyUsed(userAddress, epoch)), 0)
501524 let newVote = fraction(votePrevious, gwxAmountAtEndTotal, gwxAmountAtEndTotalPrevious)
502- let actions = if ((newVote > 0))
525+ let actions = if (if ((newVote > 0))
526+ then isAmountAssetVerified
527+ else false)
503528 then [IntegerEntry(keyVote(pool, userAddress, epoch), newVote), IntegerEntry(keyTotalVotes(epoch), (totalVotes + newVote)), IntegerEntry(keyVotingResult(pool, epoch), (votingResult + newVote)), IntegerEntry(keyUsed(userAddress, epoch), (used + newVote))]
504529 else deleteNodeActions(getVotesListName(pool), userAddressStr)
505530 $Tuple2(actions, unit)
506531 }
507532 else throw("Strict value is not equal to itself.")
508533 }
509534 else throw("Strict value is not equal to itself.")
510535 }
511536
512537
513538
514539 @Callable(i)
515540 func processPoolINTERNAL (poolStr) = {
516541 let checkCaller = mustThis(i)
517542 if ((checkCaller == checkCaller))
518543 then {
519544 let targetEpoch = (getIntOrFail(this, keyCurrentEpoch) - 1)
520545 let checkTargetEpoch = if ((targetEpoch >= 0))
521546 then true
522547 else throw("processPoolINTERNAL: invalid target epoch")
523548 if ((checkTargetEpoch == checkTargetEpoch))
524549 then {
525550 let pool = stringToPool(poolStr)
526- let $t01821018250 = pool
527- let amountAssetId = $t01821018250._1
528- let priceAssetId = $t01821018250._2
551+ let $t01899719037 = pool
552+ let amountAssetId = $t01899719037._1
553+ let priceAssetId = $t01899719037._2
529554 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
530555 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
531556 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
532557 let r = {
533558 let @ = invoke(stakingContract, "usersListTraversal", [lpAssetId], nil)
534559 if ($isInstanceOf(@, "Boolean"))
535560 then @
536561 else throw(($getType(invoke(stakingContract, "usersListTraversal", [lpAssetId], nil)) + " couldn't be cast to Boolean"))
537562 }
538563 if ((r == r))
539564 then if (r)
540565 then $Tuple2(nil, true)
541566 else {
567+ let isAmountAssetVerified = isAssetVerified(amountAssetId)
542568 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
543569 let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
544- let share = if ((totalVotes == 0))
570+ let share = if (if ((totalVotes == 0))
571+ then true
572+ else !(isAmountAssetVerified))
545573 then 0
546574 else fraction(votingResult, poolWeightMult, totalVotes)
547575 let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
548576 if ((modifyWeightInv == modifyWeightInv))
549- then $Tuple2([IntegerEntry(keyPoolShare(pool, targetEpoch), share)], false)
577+ then {
578+ let poolsListActions = if (isAmountAssetVerified)
579+ then nil
580+ else ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolStr))
581+ $Tuple2(([IntegerEntry(keyPoolShare(pool, targetEpoch), share)] ++ poolsListActions), false)
582+ }
550583 else throw("Strict value is not equal to itself.")
551584 }
552585 else throw("Strict value is not equal to itself.")
553586 }
554587 else throw("Strict value is not equal to itself.")
555588 }
556589 else throw("Strict value is not equal to itself.")
557590 }
558591
559592
560593
561594 @Callable(i)
562595 func finalizeHelper () = {
563596 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
564597 let previousEpoch = (epoch - 1)
565598 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
566599 let epochLength = getIntOrFail(this, keyEpochLength)
567600 let endHeight = (startHeight + epochLength)
568601 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
569602 if ((height >= endHeight))
570603 then {
571604 let newEpoch = (epoch + 1)
572605 $Tuple2([IntegerEntry(keyStartHeightByEpoch(newEpoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpoch, newEpoch), IntegerEntry(keyFinalizationStage, finalizationStageTotal)], true)
573606 }
574607 else if ((finalizationStageOrUnit == unit))
575608 then $Tuple2(nil, false)
576609 else if ((finalizationStageOrUnit == finalizationStageTotal))
577610 then {
578611 let poolOrUnit = getString(keyNextPool)
579612 let userOrUnit = getString(keyNextUser)
580613 match poolOrUnit {
581614 case _: Unit =>
582615 match getString(keyListHead(poolsListName)) {
583616 case _: Unit =>
584617 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
585618 case poolsHeadStr: String =>
586619 $Tuple2([StringEntry(keyNextPool, poolsHeadStr)], true)
587620 case _ =>
588621 throw("Match error")
589622 }
590623 case poolStr: String =>
591624 let pool = stringToPool(poolStr)
592625 let nextUserOrUnit = match userOrUnit {
593626 case _: Unit =>
594627 getString(keyListHead(getVotesListName(pool)))
595628 case user: String =>
596629 let processVoteInv = invoke(this, "processVoteINTERNAL", [poolStr, user], nil)
597630 if ((processVoteInv == processVoteInv))
598631 then getString(keyListNext(getVotesListName(pool), user))
599632 else throw("Strict value is not equal to itself.")
600633 case _ =>
601634 throw("Match error")
602635 }
603636 match nextUserOrUnit {
604637 case _: Unit =>
605638 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
606639 match nextPoolOrUnit {
607640 case _: Unit =>
608641 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
609642 case s: String =>
610643 $Tuple2([StringEntry(keyNextPool, s), DeleteEntry(keyNextUser)], true)
611644 case _ =>
612645 throw("Match error")
613646 }
614647 case nextUser: String =>
615648 $Tuple2([StringEntry(keyNextUser, nextUser)], true)
616649 case _ =>
617650 throw("Match error")
618651 }
619652 case _ =>
620653 throw("Match error")
621654 }
622655 }
623656 else if ((finalizationStageOrUnit == finalizationStageShares))
624657 then {
625658 let poolOrUnit = getString(keyNextPool)
626659 match poolOrUnit {
627660 case _: Unit =>
628661 match getString(keyListHead(poolsListName)) {
629662 case _: Unit =>
630663 $Tuple2([DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)], true)
631664 case nextPoolStr: String =>
632665 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
633666 case _ =>
634667 throw("Match error")
635668 }
636669 case poolStr: String =>
637670 let r = {
638671 let @ = invoke(this, "processPoolINTERNAL", [poolStr], nil)
639672 if ($isInstanceOf(@, "Boolean"))
640673 then @
641674 else throw(($getType(invoke(this, "processPoolINTERNAL", [poolStr], nil)) + " couldn't be cast to Boolean"))
642675 }
643676 if ((r == r))
644677 then if (r)
645678 then $Tuple2(nil, true)
646679 else {
647680 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
648681 match nextPoolOrUnit {
649682 case _: Unit =>
650683 $Tuple2([DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)], true)
651684 case nextPoolStr: String =>
652685 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
653686 case _ =>
654687 throw("Match error")
655688 }
656689 }
657690 else throw("Strict value is not equal to itself.")
658691 case _ =>
659692 throw("Match error")
660693 }
661694 }
662695 else throw("finalization is broken")
663696 }
664697
665698
666699
667700 @Callable(i)
668701 func finalizeWrapper (counter) = {
669702 let result = {
670703 let @ = invoke(this, "finalizeHelper", nil, nil)
671704 if ($isInstanceOf(@, "Boolean"))
672705 then @
673706 else throw(($getType(invoke(this, "finalizeHelper", nil, nil)) + " couldn't be cast to Boolean"))
674707 }
675708 if ((result == result))
676709 then if (!(result))
677710 then if ((counter == 0))
678711 then throw("Current voting is not over yet")
679712 else $Tuple2(nil, unit)
680713 else {
681714 let maxDepth = valueOrElse(getInteger(this, keyMaxDepth), maxDepthDefault)
682715 if ((maxDepth > counter))
683716 then {
684717 let inv = invoke(this, "finalizeWrapper", [(counter + 1)], nil)
685718 if ((inv == inv))
686719 then $Tuple2(nil, unit)
687720 else throw("Strict value is not equal to itself.")
688721 }
689722 else $Tuple2(nil, unit)
690723 }
691724 else throw("Strict value is not equal to itself.")
692725 }
693726
694727
695728
696729 @Callable(i)
697730 func finalize () = {
698731 let inv = invoke(this, "finalizeWrapper", [0], nil)
699732 if ((inv == inv))
700733 then $Tuple2(nil, unit)
701734 else throw("Strict value is not equal to itself.")
702735 }
703736
704737
705738
706739 @Callable(i)
707740 func onVerificationLoss (assetId) = $Tuple2(nil, unit)
708741
709742
710743
711744 @Callable(i)
712745 func containsNodeREADONLY (listName,id) = $Tuple2(nil, containsNode(listName, id))
713746
714747
715748
716749 @Callable(i)
717750 func insertNode (listName,id) = {
718751 let checkCaller = mustManager(i)
719752 if ((checkCaller == checkCaller))
720753 then $Tuple2(insertNodeActions(listName, id), unit)
721754 else throw("Strict value is not equal to itself.")
722755 }
723756
724757
725758
726759 @Callable(i)
727760 func deleteNode (listName,id) = {
728761 let checkCaller = mustManager(i)
729762 if ((checkCaller == checkCaller))
730763 then $Tuple2(deleteNodeActions(listName, id), unit)
731764 else throw("Strict value is not equal to itself.")
732765 }
733766
734767
735768 @Verifier(tx)
736769 func verify () = {
737770 let targetPublicKey = match managerPublicKeyOrUnit() {
738771 case pk: ByteVector =>
739772 pk
740773 case _: Unit =>
741774 tx.senderPublicKey
742775 case _ =>
743776 throw("Match error")
744777 }
745778 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
746779 }
747780

github/deemru/w8io/169f3d6 
105.25 ms