2023.04.05 19:15 [3587102] smart account 3PDB1pdcw6fPCM1WsFmx9VAidTyMouYERC1 > SELF 0.00000000 Waves

{ "type": 13, "id": "DMXVbJXg3ftDBXKz284XLv9d3Q7ctdtPpbzzmdKyzet", "fee": 2800000, "feeAssetId": null, "timestamp": 1680711320343, "version": 2, "chainId": 87, "sender": "3PDB1pdcw6fPCM1WsFmx9VAidTyMouYERC1", "senderPublicKey": "FAdS85KG2ee4mAB8XCDybKpFu79txSRTHQHTFzHcULDn", "proofs": [ "5AcwD8gnsAaVF6aqqVC1mMsjax5p3rfZ3xo1gxUFX58STBwx6wozBoZPxSr1hNxMFhcFY5SkmLWETuJGDMNJh7tn" ], "script": "base64:BgJNCAISBQoDCAgBEgASBgoECAgICBIDCgEIEgMKAQQSABIDCgEEEgMKAQESABIDCgEEEgMKAQESBAoCCAESBQoDBAEIEgASBwoFCAEBCAgxAAlzdGFydFRzTXMA6OeOrPIwARdjYWxjdWxhdGVEYXlzU2luY2VTdGFydAAEBGRpZmYJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUJc3RhcnRUc01zBApkYXlzUGFzc2VkCQBpAgUEZGlmZgkAaAIAgKMFAOgHBQpkYXlzUGFzc2VkAQphc0ludFR1cGxlAQV2YWx1ZQQHJG1hdGNoMAUFdmFsdWUDCQABAgUHJG1hdGNoMAIKKEludCwgSW50KQQDaW50BQckbWF0Y2gwBQNpbnQJAAIBAh9Xcm9uZyB0eXBlLCBleHBlY3RlZDogVHVwbGUgSW50ARBnZXRPcmFjbGVBZGRyZXNzAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzAg1zdGF0aWNfb3JhY2xlAhFvcmFjbGUgbm90IGZvdW5kIQIWY291bGQgbm90IHBhcnNlIG9yYWNsZQEOZ2V0RmVlc0FjY291bnQACQERQGV4dHJOYXRpdmUoMTA2MikBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgkBEGdldE9yYWNsZUFkZHJlc3MAAhRzdGF0aWNfZmVlQWdncmVnYXRvcgIfc3RhdGljX2ZlZUFnZ3JlZ2F0b3Igbm90IGZvdW5kIQEOZ2V0Tm9kZUFjY291bnQACQERQGV4dHJOYXRpdmUoMTA2MikBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgkBEGdldE9yYWNsZUFkZHJlc3MAAhJzdGF0aWNfbm9kZUFkZHJlc3MCF25vZGVfYWRkcmVzcyBub3QgZm91bmQhAQ10cnlHZXRJbnRlZ2VyAQNrZXkEByRtYXRjaDAJAJoIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACA0ludAQBYgUHJG1hdGNoMAUBYgAAAQx0cnlHZXRCaW5hcnkBA2tleQQHJG1hdGNoMAkAnAgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYgUHJG1hdGNoMAUBYgEAAQx0cnlHZXRTdHJpbmcBA2tleQQHJG1hdGNoMAkAnQgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFiBQckbWF0Y2gwBQFiAgABDmdldEFzc2V0U3RyaW5nAQdhc3NldElkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWIFByRtYXRjaDAJANgEAQUBYgIFV0FWRVMBDWdldEFzc2V0Qnl0ZXMBCmFzc2V0SWRTdHIDCQAAAgUKYXNzZXRJZFN0cgIFV0FWRVMFBHVuaXQJANkEAQUKYXNzZXRJZFN0cgETYWRkQXNzZXRCeXRlc1RvTGlzdAIFYWNjdW0EaXRlbQkAzggCBQVhY2N1bQkAzAgCCQENZ2V0QXNzZXRCeXRlcwEFBGl0ZW0FA25pbAEUYWRkQXNzZXRXZWlnaHRUb0xpc3QCBWFjY3VtBGl0ZW0JAM4IAgUFYWNjdW0JAMwIAgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwkBDmdldEFzc2V0U3RyaW5nAQUEaXRlbQIHX3dlaWdodAUDbmlsARZhZGRBc3NldERlY2ltYWxzVG9MaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18JAQ5nZXRBc3NldFN0cmluZwEFBGl0ZW0CCV9kZWNpbWFscwUDbmlsARNhZGRBc3NldFNjYWxlVG9MaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18JAQ5nZXRBc3NldFN0cmluZwEFBGl0ZW0CBl9zY2FsZQUDbmlsAQxhZGRJbnRUb0xpc3QCBWFjY3VtBGl0ZW0JAM4IAgUFYWNjdW0JAMwIAgkBDXBhcnNlSW50VmFsdWUBBQRpdGVtBQNuaWwBFHJldmVuZXVGb3JEYXlCeUFzc2V0AgNkYXkHYXNzZXRJZAkArAICCQCsAgIJAKwCAgIMcmV2ZW5ldV9kYXlfBQdhc3NldElkAgFfCQCkAwEFA2RheQABVAkBDXRyeUdldEludGVnZXIBAhNzdGF0aWNfdG9rZW5zQW1vdW50AAhhc3NldElkcwoAAiRsCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfdG9rZW5JZHMCASwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBE2FkZEFzc2V0Qnl0ZXNUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDMJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMADUFzc2V0c1dlaWdodHMKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBFGFkZEFzc2V0V2VpZ2h0VG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyAzCQEFJGYxXzICCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECBQUkYWNjMAAAAAEAAgADAAhEZWNpbWFscwoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMl8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEWYWRkQXNzZXREZWNpbWFsc1RvTGlzdAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMl8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgMwkBBSRmMl8yAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgUFJGFjYzAAAAABAAIAAwAGU2NhbGVzCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYzXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARNhZGRBc3NldFNjYWxlVG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYzXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyAzCQEFJGYzXzICCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECBQUkYWNjMAAAAAEAAgADAAdzdGFrZUlkCQEMdHJ5R2V0U3RyaW5nAQINbGFzdF9zdGFrZV9pZAADRmVlCQENdHJ5R2V0SW50ZWdlcgECCnN0YXRpY19mZWUAFUFzc2V0c1dlaWdodHNEZWNpbWFscwACAAVTY2FsZQCQTgAGU2NhbGU4AIDC1y8ACEZlZVNjYWxlAJBOABFQb29sVG9rZW5EZWNpbWFscwAIAA5Qb29sVG9rZW5TY2FsZQkAbAYACgAABRFQb29sVG9rZW5EZWNpbWFscwAAAAAFBkhBTEZVUAAMZWFybmVkQXNzZXRzBQhhc3NldElkcwEKaXNTaHV0ZG93bgAECHNodXRkb3duAwkBAiE9AgkBDHRyeUdldFN0cmluZwECDXN0YXRpY19vcmFjbGUCAAQHJG1hdGNoMAkAmwgCCQEQZ2V0T3JhY2xlQWRkcmVzcwACDGFtbV9zaHV0ZG93bgMJAAECBQckbWF0Y2gwAgdCb29sZWFuBAF4BQckbWF0Y2gwBQF4BwcECXNodXRkb3duMgQHJG1hdGNoMAkAmwgCBQR0aGlzAgtpc19zaHV0ZG93bgMJAAECBQckbWF0Y2gwAgdCb29sZWFuBAF4BQckbWF0Y2gwBQF4BwMFCHNodXRkb3duBgUJc2h1dGRvd24yAQljYW5VcGRhdGUAAwkBAiE9AgkBDHRyeUdldFN0cmluZwECDXN0YXRpY19vcmFjbGUCAAQHJG1hdGNoMAkAmwgCCQEQZ2V0T3JhY2xlQWRkcmVzcwACBmFtbV90eAMJAAECBQckbWF0Y2gwAgdCb29sZWFuBAF4BQckbWF0Y2gwBQF4BgYBFmdldEN1cnJlbnRUb2tlbkJhbGFuY2UBCXRva2VuVHlwZQQHdG9rZW5JZAkBDmdldEFzc2V0U3RyaW5nAQkAkQMCBQhhc3NldElkcwUJdG9rZW5UeXBlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfBQd0b2tlbklkAghfYmFsYW5jZQEQY2FsY3VsYXRlUElzc3VlZAIGYW1vdW50B3Rva2VuSWQEB1BzdXBwbHkJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQEB0JhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFB3Rva2VuSWQCCF9iYWxhbmNlCQBuBAUGYW1vdW50BQdQc3VwcGx5BQdCYWxhbmNlBQRET1dOAQ1nZXRNaW5QSXNzdWVkAQhwYXltZW50cwoBB2hhbmRsZXICBWFjY3VtB2N1cnJlbnQEB1BJc3N1ZWQJARBjYWxjdWxhdGVQSXNzdWVkAggFB2N1cnJlbnQGYW1vdW50CAUHY3VycmVudAdhc3NldElkAwkAAAIFB1BJc3N1ZWQAAAkAAgECJG9uZSBvZiB0aGUgdG9rZW5zIGFtb3VudHMgaXMgdG9vIGxvdwMDCQAAAgUFYWNjdW0AAAYJAGYCBQVhY2N1bQUHUElzc3VlZAUHUElzc3VlZAUFYWNjdW0ECW1pblBJc3NlZAoAAiRsBQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgMwkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwUJbWluUElzc2VkARNjaGVja1Rva2Vuc1ZhbGlkaXR5AQhwYXltZW50cwoBCGhhbmRsZXIxAgVhY2N1bQdwYXltZW50CQDOCAIFBWFjY3VtCQDMCAIIBQdwYXltZW50B2Fzc2V0SWQFA25pbAQDaWRzCgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhoYW5kbGVyMQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgMwkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwMJAAACBQNpZHMFA2lkcwoBCGhhbmRsZXIyAgVhY2N1bQdhc3NldElkAwkBAiE9AgkAzwgCBQNpZHMFB2Fzc2V0SWQFBHVuaXQJAGQCBQVhY2N1bQABCQACAQkArAICAhRhc3NldCBub3QgYXR0YWNoZWQ6IAkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAQGY2hlY2tzCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY1XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhoYW5kbGVyMgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgMwkBBSRmNV8yAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgUFJGFjYzAAAAABAAIAAwMJAAACBQZjaGVja3MFBmNoZWNrcwYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BDHN0YWtlVW5zdGFrZQMFc3Rha2UGYW1vdW50B2Fzc2V0SWQDAwkAAAIFB2Fzc2V0SWQCBVdBVkVTCQBmAgUGYW1vdW50AAAHBA1sZWFzaW5nQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMCDmxlYXNpbmdfYW1vdW50AAAEDm5ld0xlYXNlQW1vdW50AwUFc3Rha2UJAGQCBQ1sZWFzaW5nQW1vdW50BQZhbW91bnQJAGUCBQ1sZWFzaW5nQW1vdW50BQZhbW91bnQECG5ld0xlYXNlCQDECAIJAQ5nZXROb2RlQWNjb3VudAAFDm5ld0xlYXNlQW1vdW50BApuZXdMZWFzZUlkCQC5CAEFCG5ld0xlYXNlBARkYXRhCQDMCAIFCG5ld0xlYXNlCQDMCAIJAQtTdHJpbmdFbnRyeQICDWxhc3Rfc3Rha2VfaWQJANgEAQUKbmV3TGVhc2VJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgIObGVhc2luZ19hbW91bnQFDm5ld0xlYXNlQW1vdW50BQNuaWwDCQECIT0CBQdzdGFrZUlkAgAJAM4IAgkAzAgCCQELTGVhc2VDYW5jZWwBCQDZBAEFB3N0YWtlSWQFA25pbAUEZGF0YQUEZGF0YQUDbmlsARNoYW5kbGVQb29sVG9rZW5zQWRkBAdQSXNzdWVkCHBheW1lbnRzC3VzZXJBZGRyZXNzCm5lZWRDaGFuZ2UKARVnZXRUb2tlblBheW1lbnRBbW91bnQBB3Rva2VuSWQKAQdoYW5kbGVyAgVhY2N1bQdwYXltZW50AwkAAAIIBQdwYXltZW50B2Fzc2V0SWQFB3Rva2VuSWQIBQdwYXltZW50BmFtb3VudAUFYWNjdW0KAAIkbAUIcGF5bWVudHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDMJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMKARFoYW5kbGVUb2tlbkNoYW5nZQIFYWNjdW0HdG9rZW5JZAQCQmsJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFB3Rva2VuSWQCCF9iYWxhbmNlBAdQU3VwcGx5CQENdHJ5R2V0SW50ZWdlcgECF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50BA10b2tlbkRlY2ltYWxzCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfCQEOZ2V0QXNzZXRTdHJpbmcBBQd0b2tlbklkAgZfc2NhbGUEBkRrVGVtcAkAbgQJAGUCCQBuBAkAZAIFB1BTdXBwbHkFB1BJc3N1ZWQFDXRva2VuRGVjaW1hbHMFB1BTdXBwbHkFB0NFSUxJTkcFDXRva2VuRGVjaW1hbHMFAkJrBQ10b2tlbkRlY2ltYWxzBQdDRUlMSU5HBA1wYXltZW50QW1vdW50CQEVZ2V0VG9rZW5QYXltZW50QW1vdW50AQUHdG9rZW5JZAQCRGsJAJcDAQkAzAgCBQZEa1RlbXAJAMwIAgUNcGF5bWVudEFtb3VudAUDbmlsBAh0b1JldHVybgkAZQIDCQECIT0CBQ1wYXltZW50QW1vdW50AAAFDXBheW1lbnRBbW91bnQAAAUCRGsEAXQDAwUKbmVlZENoYW5nZQkAZgIFCHRvUmV0dXJuAAAHCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzBQh0b1JldHVybgUHdG9rZW5JZAUDbmlsBQNuaWwEEHN0YWtlVW5zdGFrZURhdGEDCQAAAgkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAIFV0FWRVMJAQxzdGFrZVVuc3Rha2UDBgUCRGsCBVdBVkVTBQNuaWwJAM4IAgkAzggCCQDOCAIFBWFjY3VtBQF0BRBzdGFrZVVuc3Rha2VEYXRhCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHZ2xvYmFsXwkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAIIX2JhbGFuY2UJAGQCBQJCawUCRGsFA25pbAoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQERaGFuZGxlVG9rZW5DaGFuZ2UCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDMJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMBFmhhbmRsZVBvb2xUb2tlbnNSZWRlZW0CCVBSZWRlZW1lZAt1c2VyQWRkcmVzcwoBEWhhbmRsZVRva2VuUmVkZWVtAgVhY2N1bQd0b2tlbklkBAJCawkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAIIX2JhbGFuY2UEB1BTdXBwbHkJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQEDXRva2VuRGVjaW1hbHMJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18JAQ5nZXRBc3NldFN0cmluZwEFB3Rva2VuSWQCBl9zY2FsZQQGYW1vdW50CQCgAwEJAL0CBAkAuAICCQC2AgEFBlNjYWxlOAkAvQIECQC2AgEJAGUCBQdQU3VwcGx5BQlQUmVkZWVtZWQJALYCAQUGU2NhbGU4CQC2AgEFB1BTdXBwbHkFB0NFSUxJTkcJALYCAQUCQmsJALYCAQUGU2NhbGU4BQRET1dOBBBzdGFrZVVuc3Rha2VEYXRhAwkAAAIJAQ5nZXRBc3NldFN0cmluZwEFB3Rva2VuSWQCBVdBVkVTCQEMc3Rha2VVbnN0YWtlAwcFBmFtb3VudAIFV0FWRVMFA25pbAkAzggCCQDOCAIFBWFjY3VtBRBzdGFrZVVuc3Rha2VEYXRhCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHZ2xvYmFsXwkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAIIX2JhbGFuY2UJAGUCBQJCawUGYW1vdW50CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzBQZhbW91bnQFB3Rva2VuSWQFA25pbAoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQERaGFuZGxlVG9rZW5SZWRlZW0CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDMJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMBEmNhbGN1bGF0ZU91dEFtb3VudAUIQW1vdW50SW4HYXNzZXRJbghhc3NldE91dAlCYWxhbmNlSW4KQmFsYW5jZU91dAQHSW5kZXhJbgkBBXZhbHVlAQkAzwgCBQhhc3NldElkcwUHYXNzZXRJbgQISW5kZXhPdXQJAQV2YWx1ZQEJAM8IAgUIYXNzZXRJZHMFCGFzc2V0T3V0AwkAAAIFB0luZGV4SW4FCEluZGV4T3V0CQACAQIRd3JvbmcgdG9rZW5zIHBhaXIJAG4EBQpCYWxhbmNlT3V0CQBlAgkAaAIFBlNjYWxlOAUGU2NhbGU4CQCgAwEJAHYGCQC9AgQJALYCAQUJQmFsYW5jZUluCQC2AgEJAGgCBQZTY2FsZTgFBlNjYWxlOAkAtgIBCQBkAgUJQmFsYW5jZUluBQhBbW91bnRJbgUGSEFMRlVQABAJALYCAQkAawMJAJEDAgUNQXNzZXRzV2VpZ2h0cwUHSW5kZXhJbgCQTgkAkQMCBQ1Bc3NldHNXZWlnaHRzBQhJbmRleE91dAAEABAFB0NFSUxJTkcJAGgCBQZTY2FsZTgFBlNjYWxlOAUERE9XTgERY2FsY3VsYXRlTWluVG9HZXQDBmFzc2V0MQZhc3NldDIMYW1vdW50VG9Td2FwBAlrQmFsYW5jZUEJAKwCAgkArAICAgdnbG9iYWxfBQZhc3NldDECCF9iYWxhbmNlBA9BX2Fzc2V0X2JhbGFuY2UJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMFCWtCYWxhbmNlQQQJa0JhbGFuY2VCCQCsAgIJAKwCAgIHZ2xvYmFsXwUGYXNzZXQyAghfYmFsYW5jZQQPQl9hc3NldF9iYWxhbmNlCQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzBQlrQmFsYW5jZUIECGtXZWlnaHRBCQCsAgIJAKwCAgIHc3RhdGljXwUGYXNzZXQxAgdfd2VpZ2h0BAhrV2VpZ2h0QgkArAICCQCsAgICB3N0YXRpY18FBmFzc2V0MgIHX3dlaWdodAQHd2VpZ2h0QQkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwUIa1dlaWdodEEEB3dlaWdodEIJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMFCGtXZWlnaHRCBAV0b0dldAkAbgQFD0JfYXNzZXRfYmFsYW5jZQkAZQIJAGgCBQZTY2FsZTgFBlNjYWxlOAkAoAMBCQB2BgkAvQIECQC2AgEFD0FfYXNzZXRfYmFsYW5jZQkAtgIBCQBoAgUGU2NhbGU4BQZTY2FsZTgJALYCAQkAZAIFD0FfYXNzZXRfYmFsYW5jZQUMYW1vdW50VG9Td2FwBQZIQUxGVVAAEAkAtgIBCQBrAwUHd2VpZ2h0QQCQTgUHd2VpZ2h0QgAEABAFB0NFSUxJTkcJAGgCBQZTY2FsZTgFBlNjYWxlOAUERE9XTgQJZmVlQW1vdW50CQBrAwUFdG9HZXQFA0ZlZQUIRmVlU2NhbGUDCQAAAgUJZmVlQW1vdW50BQlmZWVBbW91bnQEDmNsZWFuQW1vdW50T3V0CQBlAgUFdG9HZXQFCWZlZUFtb3VudAMJAAACBQ5jbGVhbkFtb3VudE91dAUOY2xlYW5BbW91bnRPdXQFDmNsZWFuQW1vdW50T3V0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQ9nZXRUb2tlbkJhbGFuY2UBB2Fzc2V0SWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBdAUHJG1hdGNoMAkA8AcCBQR0aGlzBQF0CAkA7wcBBQR0aGlzB3JlZ3VsYXIBHWNhbGN1bGF0ZUN1cnJlbnRBc3NldEludGVyZXN0BAdhc3NldElkCmFzc2V0SWRTdHIIYUJhbGFuY2UWdG9rZW5FYXJuaW5nc0xhc3RDaGVjawQLdG90YWxTdGFrZWQJAQ10cnlHZXRJbnRlZ2VyAQISZ2xvYmFsX2luZGV4U3Rha2VkBBV0b2tlbkJhbGFuY2VMYXN0Q2hlY2sFFnRva2VuRWFybmluZ3NMYXN0Q2hlY2sEE2N1cnJlbnRCYWxhbmNlRGVsdGEJAGUCCQEPZ2V0VG9rZW5CYWxhbmNlAQUHYXNzZXRJZAUIYUJhbGFuY2UEFGN1cnJlbnRUb2tlbkVhcm5pbmdzAwkAZgIFE2N1cnJlbnRCYWxhbmNlRGVsdGEFFXRva2VuQmFsYW5jZUxhc3RDaGVjawUTY3VycmVudEJhbGFuY2VEZWx0YQUVdG9rZW5CYWxhbmNlTGFzdENoZWNrBAtuZXdFYXJuaW5ncwkAZQIFFGN1cnJlbnRUb2tlbkVhcm5pbmdzBRV0b2tlbkJhbGFuY2VMYXN0Q2hlY2sEC25ld0ludGVyZXN0AwkAAAIFC3RvdGFsU3Rha2VkAAAAAAkAawMFC25ld0Vhcm5pbmdzBQZTY2FsZTgFC3RvdGFsU3Rha2VkBBFsYXN0Q2hlY2tJbnRlcmVzdAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIRZ2xvYmFsX2xhc3RDaGVja18FCmFzc2V0SWRTdHICCV9pbnRlcmVzdAkAZAIFEWxhc3RDaGVja0ludGVyZXN0BQtuZXdJbnRlcmVzdAELY2xhaW1SZXN1bHQBB2FkZHJlc3MECmFkZHJlc3NTdHIJAKUIAQUHYWRkcmVzcwQLc2hhcmVBbW91bnQJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQKAQdoYW5kbGVyAgVhY2N1bQdhc3NldElkBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBBQdhc3NldElkBAhhQmFsYW5jZQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAIIX2JhbGFuY2UEFnRva2VuRWFybmluZ3NMYXN0Q2hlY2sJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICEWdsb2JhbF9sYXN0Q2hlY2tfBQphc3NldElkU3RyAglfZWFybmluZ3MEFGN1cnJlbnRUb2tlbkludGVyZXN0CQEdY2FsY3VsYXRlQ3VycmVudEFzc2V0SW50ZXJlc3QEBQdhc3NldElkBQphc3NldElkU3RyBQhhQmFsYW5jZQUWdG9rZW5FYXJuaW5nc0xhc3RDaGVjawQUY3VycmVudFRva2VuRWFybmluZ3MJAJYDAQkAzAgCBRZ0b2tlbkVhcm5pbmdzTGFzdENoZWNrCQDMCAIJAGUCCQEPZ2V0VG9rZW5CYWxhbmNlAQUHYXNzZXRJZAUIYUJhbGFuY2UFA25pbAQMcmV3YXJkQW1vdW50CQBrAwULc2hhcmVBbW91bnQJAGUCBRRjdXJyZW50VG9rZW5JbnRlcmVzdAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgkArAICBQphZGRyZXNzU3RyAgtfbGFzdENoZWNrXwUKYXNzZXRJZFN0cgIJX2ludGVyZXN0BQZTY2FsZTgECHRyYW5zZmVyAwkAAAIFDHJld2FyZEFtb3VudAAABQNuaWwJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUHYWRkcmVzcwUMcmV3YXJkQW1vdW50BQdhc3NldElkBQNuaWwEB2NsYWltZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIJAKwCAgUKYWRkcmVzc1N0cgILX2xhc3RDaGVja18FCmFzc2V0SWRTdHICCF9jbGFpbWVkCQDOCAIJAM4IAgUFYWNjdW0FCHRyYW5zZmVyCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIRZ2xvYmFsX2xhc3RDaGVja18FCmFzc2V0SWRTdHICCV9lYXJuaW5ncwkAZQIFFGN1cnJlbnRUb2tlbkVhcm5pbmdzBQxyZXdhcmRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAhFnbG9iYWxfbGFzdENoZWNrXwUKYXNzZXRJZFN0cgIJX2ludGVyZXN0BRRjdXJyZW50VG9rZW5JbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUKYWRkcmVzc1N0cgILX2xhc3RDaGVja18FCmFzc2V0SWRTdHICCV9pbnRlcmVzdAUUY3VycmVudFRva2VuSW50ZXJlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIFCmFkZHJlc3NTdHICC19sYXN0Q2hlY2tfBQphc3NldElkU3RyAghfY2xhaW1lZAkAZAIFB2NsYWltZWQFDHJld2FyZEFtb3VudAUDbmlsBAVhY2N1bQoAAiRsBQxlYXJuZWRBc3NldHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDMJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMJAM4IAgUFYWNjdW0JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgIKX2xhc3RDbGFpbQgFCWxhc3RCbG9jawl0aW1lc3RhbXAFA25pbAEQaW5kZXhTdGFrZVJlc3VsdAIKYWRkcmVzc1N0cgZhbW91bnQEAmxpCQELY2xhaW1SZXN1bHQBCQERQGV4dHJOYXRpdmUoMTA2MikBBQphZGRyZXNzU3RyCQDOCAIFAmxpCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgISZ2xvYmFsX2luZGV4U3Rha2VkCQBkAgkBDXRyeUdldEludGVnZXIBAhJnbG9iYWxfaW5kZXhTdGFrZWQFBmFtb3VudAUDbmlsAQNzdW0CBWFjY3VtAW4JAGQCBQVhY2N1bQkBDXBhcnNlSW50VmFsdWUBBQFuARtzZXRPcmFjbGVBZGRyZXNzQW5kSW5pdGlhdGUBB2FkZHJlc3MJAMwIAgkBC1N0cmluZ0VudHJ5AgINc3RhdGljX29yYWNsZQUHYWRkcmVzcwUDbmlsAQlpc1Rlc3RFbnYABAd0ZXN0ZW52BAckbWF0Y2gwCQCbCAIFBHRoaXMCB1RFU1RFTlYDCQABAgUHJG1hdGNoMAIHQm9vbGVhbgQBeAUHJG1hdGNoMAUBeAcFB3Rlc3RlbnYPAWkBDHJlYWRPbmx5RnVuYwMGYXNzZXQxBmFzc2V0MgxhbW91bnRUb1N3YXAECWFtb3VudE91dAkBEWNhbGN1bGF0ZU1pblRvR2V0AwUGYXNzZXQxBQZhc3NldDIFDGFtb3VudFRvU3dhcAkAzAgCCQEMSW50ZWdlckVudHJ5AgIFREVCVUcFCWFtb3VudE91dAUDbmlsAWkBCnRvcFVwRnVuZHMAAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIYV3JvbmcgcGF5bWVudHMgYXR0YWNoZWQhBAdwYXltZW50CQCRAwIIBQFpCHBheW1lbnRzAAAEBWFzc2V0CAUHcGF5bWVudAdhc3NldElkAwkAAAIJAM8IAgUIYXNzZXRJZHMFBWFzc2V0BQR1bml0CQACAQIVTm90IHN1cHBvcnRlZCBhc3NldElkBAZhbW91bnQIBQdwYXltZW50BmFtb3VudAQIYUJhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFBWFzc2V0AghfYmFsYW5jZQQDZGF5CQEXY2FsY3VsYXRlRGF5c1NpbmNlU3RhcnQABAdyZXZlbmV1CQENdHJ5R2V0SW50ZWdlcgEJARRyZXZlbmV1Rm9yRGF5QnlBc3NldAIFA2RheQkBDmdldEFzc2V0U3RyaW5nAQUFYXNzZXQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdnbG9iYWxfCQEOZ2V0QXNzZXRTdHJpbmcBBQVhc3NldAIIX2JhbGFuY2UJAGQCBQhhQmFsYW5jZQUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCAg5kYXlzX3NpbmNlX2FweQUDZGF5CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEUcmV2ZW5ldUZvckRheUJ5QXNzZXQCBQNkYXkJAQ5nZXRBc3NldFN0cmluZwEFBWFzc2V0CQBkAgUHcmV2ZW5ldQUGYW1vdW50BQNuaWwBaQEHcHJlSW5pdAQLYXNzZXRJZHNTdHIPYXNzZXRXZWlnaHRzU3RyDmJhc2VUb2tlbklkU3RyCnBvb2xEb21haW4DCQECIT0CBQR0aGlzCAUBaQZjYWxsZXIJAAIBAgphZG1pbiBvbmx5AwkAZgIJALECAQUKcG9vbERvbWFpbgANCQACAQIVdG9vIGxhcmdlIHBvb2wgZG9tYWluBA1hc3NldElkc1N0ckxpCQC1CQIFC2Fzc2V0SWRzU3RyAgEsBAphc3NldElkc0xpCgACJGwFDWFzc2V0SWRzU3RyTGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBE2FkZEFzc2V0Qnl0ZXNUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDMJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMEEWFzc2V0V2VpZ2h0c1N0ckxpCQC1CQIFD2Fzc2V0V2VpZ2h0c1N0cgIBLAQPYXNzZXRXZWlnaHRzU3VtCgACJGwFEWFzc2V0V2VpZ2h0c1N0ckxpCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY1XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQNzdW0CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjVfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDMJAQUkZjVfMgIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIFBSRhY2MwAAAAAQACAAMKARNhZGRUb2tlbkRhdGFFbnRyaWVzAgVhY2N1bQhhc3NldE51bQMJAGcCBQhhc3NldE51bQkAkAMBBQphc3NldElkc0xpBQVhY2N1bQQNYXNzZXREZWNpbWFscwQHJG1hdGNoMAkAkQMCBQphc3NldElkc0xpBQhhc3NldE51bQMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAF4BQckbWF0Y2gwCAkBBXZhbHVlAQkA7AcBCQCRAwIFCmFzc2V0SWRzTGkFCGFzc2V0TnVtCGRlY2ltYWxzAAgJAM4IAgUFYWNjdW0JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdzdGF0aWNfCQCRAwIFDWFzc2V0SWRzU3RyTGkFCGFzc2V0TnVtAgZfc2NhbGUJAGwGAAoAAAUNYXNzZXREZWNpbWFscwAAAAAFBERPV04JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdzdGF0aWNfCQCRAwIFDWFzc2V0SWRzU3RyTGkFCGFzc2V0TnVtAglfZGVjaW1hbHMFDWFzc2V0RGVjaW1hbHMJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdzdGF0aWNfCQCRAwIFDWFzc2V0SWRzU3RyTGkFCGFzc2V0TnVtAgdfd2VpZ2h0CQEFdmFsdWUBCQC2CQEJAJEDAgURYXNzZXRXZWlnaHRzU3RyTGkFCGFzc2V0TnVtBQNuaWwDCQECIT0CBQ9hc3NldFdlaWdodHNTdW0AZAkAAgECKXN1bSBvZiB0b2tlbiB3ZWlnaHRzIG11c3QgYmUgZXF1YWwgdG8gMTAwCQDOCAIKAAIkbAkAzAgCAAAJAMwIAgABCQDMCAIAAgUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY2XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARNhZGRUb2tlbkRhdGFFbnRyaWVzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY2XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyAzCQEFJGY2XzICCQEFJGY2XzECCQEFJGY2XzECCQEFJGY2XzECBQUkYWNjMAAAAAEAAgADCQDMCAIJAQtTdHJpbmdFbnRyeQICD3N0YXRpY190b2tlbklkcwULYXNzZXRJZHNTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgITc3RhdGljX3Rva2VuV2VpZ2h0cwUPYXNzZXRXZWlnaHRzU3RyCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhNzdGF0aWNfdG9rZW5zQW1vdW50CQCQAwEFCmFzc2V0SWRzTGkJAMwIAgkBC1N0cmluZ0VudHJ5AgIRc3RhdGljX3Bvb2xEb21haW4FCnBvb2xEb21haW4JAMwIAgkBC1N0cmluZ0VudHJ5AgISc3RhdGljX2Jhc2VUb2tlbklkBQ5iYXNlVG9rZW5JZFN0cgkAzAgCCQEMSW50ZWdlckVudHJ5AgIKc3RhdGljX2ZlZQBkBQNuaWwBaQEEaW5pdAEGb3JhY2xlCgELcHJlcGFyZUxpc3QACgEHaGFuZGxlcgIFYWNjdW0BbgkAzggCBQVhY2N1bQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEIBQFuB2Fzc2V0SWQCCF9iYWxhbmNlCAUBbgZhbW91bnQFA25pbAoAAiRsCAUBaQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgMwkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwoBGWNhbGN1bGF0ZVBvb2xUb2tlbnNBbW91bnQBCHBheW1lbnRzCgEHaGFuZGxlcgIFYWNjdW0DcG10BAdhc3NldElkCAUDcG10B2Fzc2V0SWQKAQhoYW5kbGVyMgIFYWNjdW0BbgMJAAACBQFuBQdhc3NldElkCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzBQFuBQVhY2N1bQQFVG9rZW4KAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAEKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGhhbmRsZXIyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyAzCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADCQBrAwUFYWNjdW0JAGwGCAUDcG10BmFtb3VudAkAkQMCBQhEZWNpbWFscwUFVG9rZW4JAJEDAgUNQXNzZXRzV2VpZ2h0cwUFVG9rZW4FFUFzc2V0c1dlaWdodHNEZWNpbWFscwAIBQVGTE9PUgUGU2NhbGU4CgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUOUG9vbFRva2VuU2NhbGUKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDMJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMDCQBmAgkBDXRyeUdldEludGVnZXIBAhBnbG9iYWxfd2FzSW5pdGVkAAAJAAIBAhNwb29sIGFscmVhZHkgaW5pdGVkBBFpbml0aWFsUG9vbFRva2VucwkBGWNhbGN1bGF0ZVBvb2xUb2tlbnNBbW91bnQBCAUBaQhwYXltZW50cwMJAAACBRFpbml0aWFsUG9vbFRva2VucwAACQACAQIyeW91IG5lZWQgYSBiaWdnZXIgdG9rZW5zIGFtb3VudCB0byBsYXVuY2ggdGhlIHBvb2wEDnBvb2xUb2tlbklzc3VlCQDDCAcJAKwCAgIDV0QgCQEMdHJ5R2V0U3RyaW5nAQIRc3RhdGljX3Bvb2xEb21haW4CDVdEIHBvb2wgdG9rZW4FEWluaXRpYWxQb29sVG9rZW5zBRFQb29sVG9rZW5EZWNpbWFscwYFBHVuaXQAAAQLcG9vbFRva2VuSWQJALgIAQUOcG9vbFRva2VuSXNzdWUJAM4IAgkAzggCCQELcHJlcGFyZUxpc3QACQDMCAIFDnBvb2xUb2tlbklzc3VlCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAURaW5pdGlhbFBvb2xUb2tlbnMJAMwIAgkBDEludGVnZXJFbnRyeQICEGdsb2JhbF93YXNJbml0ZWQAAQkAzAgCCQELQmluYXJ5RW50cnkCAhNnbG9iYWxfcG9vbFRva2VuX2lkBQtwb29sVG9rZW5JZAkAzAgCCQELU3RyaW5nRW50cnkCAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBBQtwb29sVG9rZW5JZAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFEWluaXRpYWxQb29sVG9rZW5zBQtwb29sVG9rZW5JZAUDbmlsCQEbc2V0T3JhY2xlQWRkcmVzc0FuZEluaXRpYXRlAQUGb3JhY2xlAWkBDWdlbmVyYXRlSW5kZXgBCm5lZWRDaGFuZ2UDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzBQFUCQACAQkArAICAjt5b3UgbmVlZCB0byBhdHRhY2ggYWxsIHBvb2wgdG9rZW5zLiBhbW91bnQgb2YgcG9vbCB0b2tlbnM6IAkApAMBBQFUAwkBASEBCQETY2hlY2tUb2tlbnNWYWxpZGl0eQEIBQFpCHBheW1lbnRzCQACAQIVd3JvbmcgYXNzZXRzIGF0dGFjaGVkBAdQSXNzdWVkCQENZ2V0TWluUElzc3VlZAEIBQFpCHBheW1lbnRzBAdyZWlzc3VlCQEHUmVpc3N1ZQMJARFAZXh0ck5hdGl2ZSgxMDU3KQECE2dsb2JhbF9wb29sVG9rZW5faWQFB1BJc3N1ZWQGBAZyZXN1bHQJARNoYW5kbGVQb29sVG9rZW5zQWRkBAUHUElzc3VlZAgFAWkIcGF5bWVudHMIBQFpDG9yaWdpbkNhbGxlcgUKbmVlZENoYW5nZQkAlAoCCQDOCAIFBnJlc3VsdAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFB1BJc3N1ZWQJAQx0cnlHZXRCaW5hcnkBAhNnbG9iYWxfcG9vbFRva2VuX2lkCQDMCAIFB3JlaXNzdWUJAMwIAgkBDEludGVnZXJFbnRyeQICF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50CQBkAgkBDXRyeUdldEludGVnZXIBAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAUHUElzc3VlZAUDbmlsBQdQSXNzdWVkAWkBCnN0YWtlSW5kZXgABAphZGRyZXNzU3RyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQJAQx0cnlHZXRCaW5hcnkBAhNnbG9iYWxfcG9vbFRva2VuX2lkCQACAQIUd3JvbmcgYXNzZXQgYXR0YWNoZWQJARBpbmRleFN0YWtlUmVzdWx0AgUKYWRkcmVzc1N0cggFA3BtdAZhbW91bnQBaQEVZ2VuZXJhdGVBbmRTdGFrZUluZGV4AQpuZWVkQ2hhbmdlAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwUBVAkAAgEJAKwCAgI7eW91IG5lZWQgdG8gYXR0YWNoIGFsbCBwb29sIHRva2Vucy4gYW1vdW50IG9mIHBvb2wgdG9rZW5zOiAJAKQDAQUBVAMJAQEhAQkBE2NoZWNrVG9rZW5zVmFsaWRpdHkBCAUBaQhwYXltZW50cwkAAgECFXdyb25nIGFzc2V0cyBhdHRhY2hlZAQHUElzc3VlZAkBDWdldE1pblBJc3N1ZWQBCAUBaQhwYXltZW50cwQHcmVpc3N1ZQkBB1JlaXNzdWUDCQERQGV4dHJOYXRpdmUoMTA1NykBAhNnbG9iYWxfcG9vbFRva2VuX2lkBQdQSXNzdWVkBgQGcmVzdWx0CQETaGFuZGxlUG9vbFRva2Vuc0FkZAQFB1BJc3N1ZWQIBQFpCHBheW1lbnRzCAUBaQxvcmlnaW5DYWxsZXIFCm5lZWRDaGFuZ2UJAJQKAgkAzggCCQDOCAIFBnJlc3VsdAkAzAgCBQdyZWlzc3VlCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQFB1BJc3N1ZWQFA25pbAkBEGluZGV4U3Rha2VSZXN1bHQCCQClCAEIBQFpDG9yaWdpbkNhbGxlcgUHUElzc3VlZAUHUElzc3VlZAFpAQx1bnN0YWtlSW5kZXgBC3NoYXJlQW1vdW50BAphZGRyZXNzU3RyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQOc2hhcmVBdmFpbGFibGUJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQDCQBmAgULc2hhcmVBbW91bnQFDnNoYXJlQXZhaWxhYmxlCQACAQIleW91IGRvbid0IGhhdmUgaW5kZXggdG9rZW5zIGF2YWlsYWJsZQkAzggCCQELY2xhaW1SZXN1bHQBCAUBaQxvcmlnaW5DYWxsZXIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgIMX2luZGV4U3Rha2VkCQBlAgUOc2hhcmVBdmFpbGFibGUFC3NoYXJlQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQJAGUCCQENdHJ5R2V0SW50ZWdlcgECEmdsb2JhbF9pbmRleFN0YWtlZAULc2hhcmVBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQtzaGFyZUFtb3VudAkBEUBleHRyTmF0aXZlKDEwNTcpAQITZ2xvYmFsX3Bvb2xUb2tlbl9pZAUDbmlsAWkBEWNsYWltSW5kZXhSZXdhcmRzAAkBC2NsYWltUmVzdWx0AQgFAWkGY2FsbGVyAWkBC3JlZGVlbUluZGV4AQxzZW5kVG9PcmlnaW4EA3BtdAkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AggFA3BtdAdhc3NldElkCQEMdHJ5R2V0QmluYXJ5AQITZ2xvYmFsX3Bvb2xUb2tlbl9pZAkAAgECHnBsZWFzZSBhdHRhY2ggcG9vbCBzaGFyZSB0b2tlbgQJUFJlZGVlbWVkCAUDcG10BmFtb3VudAQGcmVzdWx0CQEWaGFuZGxlUG9vbFRva2Vuc1JlZGVlbQIFCVBSZWRlZW1lZAMFDHNlbmRUb09yaWdpbggFAWkMb3JpZ2luQ2FsbGVyCAUBaQZjYWxsZXIJAM4IAgUGcmVzdWx0CQDMCAIJAQRCdXJuAgkBDHRyeUdldEJpbmFyeQECE2dsb2JhbF9wb29sVG9rZW5faWQFCVBSZWRlZW1lZAkAzAgCCQEMSW50ZWdlckVudHJ5AgIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQJAGUCCQENdHJ5R2V0SW50ZWdlcgECF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50BQlQUmVkZWVtZWQFA25pbAFpARV1bnN0YWtlQW5kUmVkZWVtSW5kZXgBC3NoYXJlQW1vdW50BAphZGRyZXNzU3RyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQOc2hhcmVBdmFpbGFibGUJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQDCQBmAgULc2hhcmVBbW91bnQFDnNoYXJlQXZhaWxhYmxlCQACAQIleW91IGRvbid0IGhhdmUgaW5kZXggdG9rZW5zIGF2YWlsYWJsZQQJUFJlZGVlbWVkBQtzaGFyZUFtb3VudAQGcmVzdWx0CQEWaGFuZGxlUG9vbFRva2Vuc1JlZGVlbQIFCVBSZWRlZW1lZAgFAWkMb3JpZ2luQ2FsbGVyCQDOCAIJAM4IAgkAzggCCQELY2xhaW1SZXN1bHQBCAUBaQxvcmlnaW5DYWxsZXIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgIMX2luZGV4U3Rha2VkCQBlAgUOc2hhcmVBdmFpbGFibGUFC3NoYXJlQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQJAGUCCQENdHJ5R2V0SW50ZWdlcgECEmdsb2JhbF9pbmRleFN0YWtlZAULc2hhcmVBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQtzaGFyZUFtb3VudAkBEUBleHRyTmF0aXZlKDEwNTcpAQITZ2xvYmFsX3Bvb2xUb2tlbl9pZAUDbmlsBQZyZXN1bHQJAMwIAgkBBEJ1cm4CCQEMdHJ5R2V0QmluYXJ5AQITZ2xvYmFsX3Bvb2xUb2tlbl9pZAUJUFJlZGVlbWVkCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAkAZQIJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQFCVBSZWRlZW1lZAUDbmlsAWkBBHN3YXACCGFzc2V0T3V0B21pbmltdW0DCQEKaXNTaHV0ZG93bgAJAAIBAhpQb29sIGlzIGN1cnJlbnRseSBzaHV0ZG93bgQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAECEFtb3VudEluCQEFdmFsdWUBCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQHQXNzZXRJbggFA3BtdAdhc3NldElkBAppbnZva2VTd2FwCQEKYXNJbnRUdXBsZQEJAP0HBAUEdGhpcwIMc3dhcEludGVybmFsCQDMCAIFCGFzc2V0T3V0CQDMCAIFB21pbmltdW0JAMwIAgUIQW1vdW50SW4JAMwIAgkBDmdldEFzc2V0U3RyaW5nAQUHQXNzZXRJbgkAzAgCCQClCAEIBQFpBmNhbGxlcgUDbmlsBQNuaWwDCQAAAgUKaW52b2tlU3dhcAUKaW52b2tlU3dhcAQOY2xlYW5BbW91bnRPdXQIBQppbnZva2VTd2FwAl8xAwkAAAIFDmNsZWFuQW1vdW50T3V0BQ5jbGVhbkFtb3VudE91dAQJZmVlQW1vdW50CAUKaW52b2tlU3dhcAJfMgMJAAACBQlmZWVBbW91bnQFCWZlZUFtb3VudAQFdG9wVXADCQAAAgUIYXNzZXRPdXQCBVdBVkVTBAd1bnN0YWtlCQD9BwQFBHRoaXMCCGludGVybmFsCQDMCAIHCQDMCAIJAGQCBQ5jbGVhbkFtb3VudE91dAkAawMFCWZlZUFtb3VudAADAAQJAMwIAgIFV0FWRVMFA25pbAUDbmlsAwkAAAIFB3Vuc3Rha2UFB3Vuc3Rha2UJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBDmdldEZlZXNBY2NvdW50AAkAawMFCWZlZUFtb3VudAACAAQJAQ1nZXRBc3NldEJ5dGVzAQUIYXNzZXRPdXQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQEOZ2V0RmVlc0FjY291bnQACQBrAwUJZmVlQW1vdW50AAIABAkBDWdldEFzc2V0Qnl0ZXMBBQhhc3NldE91dAUDbmlsAwkAAAIFBXRvcFVwBQV0b3BVcAkAlAoCBQV0b3BVcAUOY2xlYW5BbW91bnRPdXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEIaW50ZXJuYWwDBXN0YWtlBmFtb3VudAdhc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQILTm90IGFsbG93ZWQJAQxzdGFrZVVuc3Rha2UDBQVzdGFrZQUGYW1vdW50BQdhc3NldElkAWkBCHN0YWtlQWxsAAkBDHN0YWtlVW5zdGFrZQMGCQBlAgkBDXRyeUdldEludGVnZXIBAhRnbG9iYWxfV0FWRVNfYmFsYW5jZQkBDXRyeUdldEludGVnZXIBAg5sZWFzaW5nX2Ftb3VudAIFV0FWRVMBaQEMc3dhcEludGVybmFsBQhhc3NldE91dAdtaW5pbXVtCEFtb3VudEluB0Fzc2V0SW4GY2FsbGVyAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIbWW91IGNhbnQgY2FsbCB0aGlzIGRpcmVjdGx5BAhBc3NldE91dAkBDWdldEFzc2V0Qnl0ZXMBBQhhc3NldE91dAQDZGF5CQEXY2FsY3VsYXRlRGF5c1NpbmNlU3RhcnQABAdyZXZlbmV1CQENdHJ5R2V0SW50ZWdlcgEJARRyZXZlbmV1Rm9yRGF5QnlBc3NldAIFA2RheQUIYXNzZXRPdXQEDkFzc2V0SW5CYWxhbmNlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfBQdBc3NldEluAghfYmFsYW5jZQMJAAACBQ5Bc3NldEluQmFsYW5jZQUOQXNzZXRJbkJhbGFuY2UED0Fzc2V0T3V0QmFsYW5jZQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwUIYXNzZXRPdXQCCF9iYWxhbmNlAwkAAAIFD0Fzc2V0T3V0QmFsYW5jZQUPQXNzZXRPdXRCYWxhbmNlBAlBbW91bnRPdXQJARJjYWxjdWxhdGVPdXRBbW91bnQFBQhBbW91bnRJbgkBDWdldEFzc2V0Qnl0ZXMBBQdBc3NldEluBQhBc3NldE91dAUOQXNzZXRJbkJhbGFuY2UFD0Fzc2V0T3V0QmFsYW5jZQMJAAACBQlBbW91bnRPdXQFCUFtb3VudE91dAQJZmVlQW1vdW50CQBrAwUJQW1vdW50T3V0BQNGZWUFCEZlZVNjYWxlAwkAAAIFCWZlZUFtb3VudAUJZmVlQW1vdW50BA5jbGVhbkFtb3VudE91dAkAZQIFCUFtb3VudE91dAUJZmVlQW1vdW50AwkAAAIFDmNsZWFuQW1vdW50T3V0BQ5jbGVhbkFtb3VudE91dAMJAGYCBQdtaW5pbXVtBQ5jbGVhbkFtb3VudE91dAkAAgEJAKwCAgIrYW1vdW50IHRvIHJlY2lldmUgaXMgbG93ZXIgdGhhbiBnaXZlbiBvbmU6IAkApAMBBQ5jbGVhbkFtb3VudE91dAMJAGYCAAAJAGUCBQ9Bc3NldE91dEJhbGFuY2UFCUFtb3VudE91dAkAAgECG2NvbnRyYWN0IGlzIG91dCBvZiByZXNlcnZlcwMJAAACBQhBc3NldE91dAkBDWdldEFzc2V0Qnl0ZXMBBQdBc3NldEluCQACAQIYdGhpcyBzd2FwIGlzIG5vdCBhbGxvd2VkBAxuZXdCYWxhbmNlSW4JAGQCBQ5Bc3NldEluQmFsYW5jZQUIQW1vdW50SW4DCQAAAgUMbmV3QmFsYW5jZUluBQxuZXdCYWxhbmNlSW4EBXN0YWtlCQD9BwQFBHRoaXMCCGludGVybmFsCQDMCAIGCQDMCAIFCEFtb3VudEluCQDMCAIFB0Fzc2V0SW4FA25pbAUDbmlsAwkAAAIFBXN0YWtlBQVzdGFrZQQNbmV3QmFsYW5jZU91dAkAZQIFD0Fzc2V0T3V0QmFsYW5jZQUJQW1vdW50T3V0AwkAAAIFDW5ld0JhbGFuY2VPdXQFDW5ld0JhbGFuY2VPdXQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB2dsb2JhbF8FCGFzc2V0T3V0AghfYmFsYW5jZQkAZAIFDW5ld0JhbGFuY2VPdXQJAGsDBQlmZWVBbW91bnQAAQAECQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBmNhbGxlcgUOY2xlYW5BbW91bnRPdXQFCEFzc2V0T3V0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHZ2xvYmFsXwUHQXNzZXRJbgIIX2JhbGFuY2UFDG5ld0JhbGFuY2VJbgkAzAgCCQEMSW50ZWdlckVudHJ5AgIOZGF5c19zaW5jZV9hcHkFA2RheQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFHJldmVuZXVGb3JEYXlCeUFzc2V0AgUDZGF5BQhhc3NldE91dAUHcmV2ZW5ldQUDbmlsCQCUCgIFDmNsZWFuQW1vdW50T3V0BQlmZWVBbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAnR4AQZ2ZXJpZnkAAwkBCWlzVGVzdEVudgAJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXkECWZpcnN0VXNlcgEg3tbGUeRTFtBlgOsBmioL0PeXUfocdpF+m44GQ3cXvSUECnNlY29uZFVzZXIBIMFs347t041zj4ui+fqJD/R1zUQbVHJSo7Sc0lakLeB1BAl0aGlyZFVzZXIBIOdb9I6q0vlJnm6EJrj5fh/cZ6h93Cu41Op7zfJoCsElBA9maXJzdFVzZXJTaWduZWQDCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQlmaXJzdFVzZXIAAQMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAEFCWZpcnN0VXNlcgABAwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAgUJZmlyc3RVc2VyAAEAAAQQc2Vjb25kVXNlclNpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFCnNlY29uZFVzZXIAAQMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAEFCnNlY29uZFVzZXIAAQMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAIFCnNlY29uZFVzZXIAAQAABA90aGlyZFVzZXJTaWduZWQDCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQl0aGlyZFVzZXIAAQMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAEFCXRoaXJkVXNlcgABAwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAgUJdGhpcmRVc2VyAAEAAAQPc2lnbmF0dXJlc0NvdW50CQBkAgkAZAIFD2ZpcnN0VXNlclNpZ25lZAUQc2Vjb25kVXNlclNpZ25lZAUPdGhpcmRVc2VyU2lnbmVkBAckbWF0Y2gwBQJ0eAkAZwIFD3NpZ25hdHVyZXNDb3VudAACddixcg==", "height": 3587102, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Gu286d9cn6YFbPHjKBneuPohVb2UcCiKkNK9JambsP9j Next: Bd9kJMnvsUv6vQPdsfFRN1qqvwEYJnz8K9jdjb3iPu2h Diff:
OldNewDifferences
391391 }
392392
393393
394+func calculateMinToGet (asset1,asset2,amountToSwap) = {
395+ let kBalanceA = (("global_" + asset1) + "_balance")
396+ let A_asset_balance = getIntegerValue(this, kBalanceA)
397+ let kBalanceB = (("global_" + asset2) + "_balance")
398+ let B_asset_balance = getIntegerValue(this, kBalanceB)
399+ let kWeightA = (("static_" + asset1) + "_weight")
400+ let kWeightB = (("static_" + asset2) + "_weight")
401+ let weightA = getIntegerValue(this, kWeightA)
402+ let weightB = getIntegerValue(this, kWeightB)
403+ let toGet = fraction(B_asset_balance, ((Scale8 * Scale8) - toInt(pow(fraction(toBigInt(A_asset_balance), toBigInt((Scale8 * Scale8)), toBigInt((A_asset_balance + amountToSwap)), HALFUP), 16, toBigInt(fraction(weightA, 10000, weightB)), 4, 16, CEILING))), (Scale8 * Scale8), DOWN)
404+ let feeAmount = fraction(toGet, Fee, FeeScale)
405+ if ((feeAmount == feeAmount))
406+ then {
407+ let cleanAmountOut = (toGet - feeAmount)
408+ if ((cleanAmountOut == cleanAmountOut))
409+ then cleanAmountOut
410+ else throw("Strict value is not equal to itself.")
411+ }
412+ else throw("Strict value is not equal to itself.")
413+ }
414+
415+
394416 func getTokenBalance (assetId) = match assetId {
395417 case t: ByteVector =>
396418 assetBalance(this, t)
471493 }
472494 testenv
473495 }
496+
497+
498+@Callable(i)
499+func readOnlyFunc (asset1,asset2,amountToSwap) = {
500+ let amountOut = calculateMinToGet(asset1, asset2, amountToSwap)
501+[IntegerEntry("DEBUG", amountOut)]
502+ }
503+
474504
475505
476506 @Callable(i)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let startTsMs = 1679961601000
55
66 func calculateDaysSinceStart () = {
77 let diff = (lastBlock.timestamp - startTsMs)
88 let daysPassed = (diff / (86400 * 1000))
99 daysPassed
1010 }
1111
1212
1313 func asIntTuple (value) = match value {
1414 case int: (Int, Int) =>
1515 int
1616 case _ =>
1717 throw("Wrong type, expected: Tuple Int")
1818 }
1919
2020
2121 func getOracleAddress () = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, "static_oracle"), "oracle not found!")), "could not parse oracle")
2222
2323
2424 func getFeesAccount () = addressFromStringValue(valueOrErrorMessage(getString(getOracleAddress(), "static_feeAggregator"), "static_feeAggregator not found!"))
2525
2626
2727 func getNodeAccount () = addressFromStringValue(valueOrErrorMessage(getString(getOracleAddress(), "static_nodeAddress"), "node_address not found!"))
2828
2929
3030 func tryGetInteger (key) = match getInteger(this, key) {
3131 case b: Int =>
3232 b
3333 case _ =>
3434 0
3535 }
3636
3737
3838 func tryGetBinary (key) = match getBinary(this, key) {
3939 case b: ByteVector =>
4040 b
4141 case _ =>
4242 base58''
4343 }
4444
4545
4646 func tryGetString (key) = match getString(this, key) {
4747 case b: String =>
4848 b
4949 case _ =>
5050 ""
5151 }
5252
5353
5454 func getAssetString (assetId) = match assetId {
5555 case b: ByteVector =>
5656 toBase58String(b)
5757 case _ =>
5858 "WAVES"
5959 }
6060
6161
6262 func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
6363 then unit
6464 else fromBase58String(assetIdStr)
6565
6666
6767 func addAssetBytesToList (accum,item) = (accum ++ [getAssetBytes(item)])
6868
6969
7070 func addAssetWeightToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_weight"))])
7171
7272
7373 func addAssetDecimalsToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_decimals"))])
7474
7575
7676 func addAssetScaleToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_scale"))])
7777
7878
7979 func addIntToList (accum,item) = (accum ++ [parseIntValue(item)])
8080
8181
8282 func reveneuForDayByAsset (day,assetId) = ((("reveneu_day_" + assetId) + "_") + toString(day))
8383
8484
8585 let T = tryGetInteger("static_tokensAmount")
8686
8787 let assetIds = {
8888 let $l = split(tryGetString("static_tokenIds"), ",")
8989 let $s = size($l)
9090 let $acc0 = nil
9191 func $f0_1 ($a,$i) = if (($i >= $s))
9292 then $a
9393 else addAssetBytesToList($a, $l[$i])
9494
9595 func $f0_2 ($a,$i) = if (($i >= $s))
9696 then $a
9797 else throw("List size exceeds 3")
9898
9999 $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3)
100100 }
101101
102102 let AssetsWeights = {
103103 let $l = assetIds
104104 let $s = size($l)
105105 let $acc0 = nil
106106 func $f1_1 ($a,$i) = if (($i >= $s))
107107 then $a
108108 else addAssetWeightToList($a, $l[$i])
109109
110110 func $f1_2 ($a,$i) = if (($i >= $s))
111111 then $a
112112 else throw("List size exceeds 3")
113113
114114 $f1_2($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3)
115115 }
116116
117117 let Decimals = {
118118 let $l = assetIds
119119 let $s = size($l)
120120 let $acc0 = nil
121121 func $f2_1 ($a,$i) = if (($i >= $s))
122122 then $a
123123 else addAssetDecimalsToList($a, $l[$i])
124124
125125 func $f2_2 ($a,$i) = if (($i >= $s))
126126 then $a
127127 else throw("List size exceeds 3")
128128
129129 $f2_2($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3)
130130 }
131131
132132 let Scales = {
133133 let $l = assetIds
134134 let $s = size($l)
135135 let $acc0 = nil
136136 func $f3_1 ($a,$i) = if (($i >= $s))
137137 then $a
138138 else addAssetScaleToList($a, $l[$i])
139139
140140 func $f3_2 ($a,$i) = if (($i >= $s))
141141 then $a
142142 else throw("List size exceeds 3")
143143
144144 $f3_2($f3_1($f3_1($f3_1($acc0, 0), 1), 2), 3)
145145 }
146146
147147 let stakeId = tryGetString("last_stake_id")
148148
149149 let Fee = tryGetInteger("static_fee")
150150
151151 let AssetsWeightsDecimals = 2
152152
153153 let Scale = 10000
154154
155155 let Scale8 = 100000000
156156
157157 let FeeScale = 10000
158158
159159 let PoolTokenDecimals = 8
160160
161161 let PoolTokenScale = pow(10, 0, PoolTokenDecimals, 0, 0, HALFUP)
162162
163163 let earnedAssets = assetIds
164164
165165 func isShutdown () = {
166166 let shutdown = if ((tryGetString("static_oracle") != ""))
167167 then match getBoolean(getOracleAddress(), "amm_shutdown") {
168168 case x: Boolean =>
169169 x
170170 case _ =>
171171 false
172172 }
173173 else false
174174 let shutdown2 = match getBoolean(this, "is_shutdown") {
175175 case x: Boolean =>
176176 x
177177 case _ =>
178178 false
179179 }
180180 if (shutdown)
181181 then true
182182 else shutdown2
183183 }
184184
185185
186186 func canUpdate () = if ((tryGetString("static_oracle") != ""))
187187 then match getBoolean(getOracleAddress(), "amm_tx") {
188188 case x: Boolean =>
189189 x
190190 case _ =>
191191 true
192192 }
193193 else true
194194
195195
196196 func getCurrentTokenBalance (tokenType) = {
197197 let tokenId = getAssetString(assetIds[tokenType])
198198 tryGetInteger((("global_" + tokenId) + "_balance"))
199199 }
200200
201201
202202 func calculatePIssued (amount,tokenId) = {
203203 let Psupply = tryGetInteger("global_poolToken_amount")
204204 let Balance = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
205205 fraction(amount, Psupply, Balance, DOWN)
206206 }
207207
208208
209209 func getMinPIssued (payments) = {
210210 func handler (accum,current) = {
211211 let PIssued = calculatePIssued(current.amount, current.assetId)
212212 if ((PIssued == 0))
213213 then throw("one of the tokens amounts is too low")
214214 else if (if ((accum == 0))
215215 then true
216216 else (accum > PIssued))
217217 then PIssued
218218 else accum
219219 }
220220
221221 let minPIssed = {
222222 let $l = payments
223223 let $s = size($l)
224224 let $acc0 = 0
225225 func $f4_1 ($a,$i) = if (($i >= $s))
226226 then $a
227227 else handler($a, $l[$i])
228228
229229 func $f4_2 ($a,$i) = if (($i >= $s))
230230 then $a
231231 else throw("List size exceeds 3")
232232
233233 $f4_2($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3)
234234 }
235235 minPIssed
236236 }
237237
238238
239239 func checkTokensValidity (payments) = {
240240 func handler1 (accum,payment) = (accum ++ [payment.assetId])
241241
242242 let ids = {
243243 let $l = payments
244244 let $s = size($l)
245245 let $acc0 = nil
246246 func $f4_1 ($a,$i) = if (($i >= $s))
247247 then $a
248248 else handler1($a, $l[$i])
249249
250250 func $f4_2 ($a,$i) = if (($i >= $s))
251251 then $a
252252 else throw("List size exceeds 3")
253253
254254 $f4_2($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3)
255255 }
256256 if ((ids == ids))
257257 then {
258258 func handler2 (accum,assetId) = if ((indexOf(ids, assetId) != unit))
259259 then (accum + 1)
260260 else throw(("asset not attached: " + getAssetString(assetId)))
261261
262262 let checks = {
263263 let $l = assetIds
264264 let $s = size($l)
265265 let $acc0 = 0
266266 func $f5_1 ($a,$i) = if (($i >= $s))
267267 then $a
268268 else handler2($a, $l[$i])
269269
270270 func $f5_2 ($a,$i) = if (($i >= $s))
271271 then $a
272272 else throw("List size exceeds 3")
273273
274274 $f5_2($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3)
275275 }
276276 if ((checks == checks))
277277 then true
278278 else throw("Strict value is not equal to itself.")
279279 }
280280 else throw("Strict value is not equal to itself.")
281281 }
282282
283283
284284 func stakeUnstake (stake,amount,assetId) = if (if ((assetId == "WAVES"))
285285 then (amount > 0)
286286 else false)
287287 then {
288288 let leasingAmount = valueOrElse(getInteger(this, "leasing_amount"), 0)
289289 let newLeaseAmount = if (stake)
290290 then (leasingAmount + amount)
291291 else (leasingAmount - amount)
292292 let newLease = Lease(getNodeAccount(), newLeaseAmount)
293293 let newLeaseId = calculateLeaseId(newLease)
294294 let data = [newLease, StringEntry("last_stake_id", toBase58String(newLeaseId)), IntegerEntry("leasing_amount", newLeaseAmount)]
295295 if ((stakeId != ""))
296296 then ([LeaseCancel(fromBase58String(stakeId))] ++ data)
297297 else data
298298 }
299299 else nil
300300
301301
302302 func handlePoolTokensAdd (PIssued,payments,userAddress,needChange) = {
303303 func getTokenPaymentAmount (tokenId) = {
304304 func handler (accum,payment) = if ((payment.assetId == tokenId))
305305 then payment.amount
306306 else accum
307307
308308 let $l = payments
309309 let $s = size($l)
310310 let $acc0 = 0
311311 func $f4_1 ($a,$i) = if (($i >= $s))
312312 then $a
313313 else handler($a, $l[$i])
314314
315315 func $f4_2 ($a,$i) = if (($i >= $s))
316316 then $a
317317 else throw("List size exceeds 3")
318318
319319 $f4_2($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3)
320320 }
321321
322322 func handleTokenChange (accum,tokenId) = {
323323 let Bk = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
324324 let PSupply = tryGetInteger("global_poolToken_amount")
325325 let tokenDecimals = tryGetInteger((("static_" + getAssetString(tokenId)) + "_scale"))
326326 let DkTemp = fraction((fraction((PSupply + PIssued), tokenDecimals, PSupply, CEILING) - tokenDecimals), Bk, tokenDecimals, CEILING)
327327 let paymentAmount = getTokenPaymentAmount(tokenId)
328328 let Dk = min([DkTemp, paymentAmount])
329329 let toReturn = ((if ((paymentAmount != 0))
330330 then paymentAmount
331331 else 0) - Dk)
332332 let t = if (if (needChange)
333333 then (toReturn > 0)
334334 else false)
335335 then [ScriptTransfer(userAddress, toReturn, tokenId)]
336336 else nil
337337 let stakeUnstakeData = if ((getAssetString(tokenId) == "WAVES"))
338338 then stakeUnstake(true, Dk, "WAVES")
339339 else nil
340340 (((accum ++ t) ++ stakeUnstakeData) ++ [IntegerEntry((("global_" + getAssetString(tokenId)) + "_balance"), (Bk + Dk))])
341341 }
342342
343343 let $l = assetIds
344344 let $s = size($l)
345345 let $acc0 = nil
346346 func $f4_1 ($a,$i) = if (($i >= $s))
347347 then $a
348348 else handleTokenChange($a, $l[$i])
349349
350350 func $f4_2 ($a,$i) = if (($i >= $s))
351351 then $a
352352 else throw("List size exceeds 3")
353353
354354 $f4_2($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3)
355355 }
356356
357357
358358 func handlePoolTokensRedeem (PRedeemed,userAddress) = {
359359 func handleTokenRedeem (accum,tokenId) = {
360360 let Bk = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
361361 let PSupply = tryGetInteger("global_poolToken_amount")
362362 let tokenDecimals = tryGetInteger((("static_" + getAssetString(tokenId)) + "_scale"))
363363 let amount = toInt(fraction((toBigInt(Scale8) - fraction(toBigInt((PSupply - PRedeemed)), toBigInt(Scale8), toBigInt(PSupply), CEILING)), toBigInt(Bk), toBigInt(Scale8), DOWN))
364364 let stakeUnstakeData = if ((getAssetString(tokenId) == "WAVES"))
365365 then stakeUnstake(false, amount, "WAVES")
366366 else nil
367367 ((accum ++ stakeUnstakeData) ++ [IntegerEntry((("global_" + getAssetString(tokenId)) + "_balance"), (Bk - amount)), ScriptTransfer(userAddress, amount, tokenId)])
368368 }
369369
370370 let $l = assetIds
371371 let $s = size($l)
372372 let $acc0 = nil
373373 func $f4_1 ($a,$i) = if (($i >= $s))
374374 then $a
375375 else handleTokenRedeem($a, $l[$i])
376376
377377 func $f4_2 ($a,$i) = if (($i >= $s))
378378 then $a
379379 else throw("List size exceeds 3")
380380
381381 $f4_2($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3)
382382 }
383383
384384
385385 func calculateOutAmount (AmountIn,assetIn,assetOut,BalanceIn,BalanceOut) = {
386386 let IndexIn = value(indexOf(assetIds, assetIn))
387387 let IndexOut = value(indexOf(assetIds, assetOut))
388388 if ((IndexIn == IndexOut))
389389 then throw("wrong tokens pair")
390390 else fraction(BalanceOut, ((Scale8 * Scale8) - toInt(pow(fraction(toBigInt(BalanceIn), toBigInt((Scale8 * Scale8)), toBigInt((BalanceIn + AmountIn)), HALFUP), 16, toBigInt(fraction(AssetsWeights[IndexIn], 10000, AssetsWeights[IndexOut])), 4, 16, CEILING))), (Scale8 * Scale8), DOWN)
391391 }
392392
393393
394+func calculateMinToGet (asset1,asset2,amountToSwap) = {
395+ let kBalanceA = (("global_" + asset1) + "_balance")
396+ let A_asset_balance = getIntegerValue(this, kBalanceA)
397+ let kBalanceB = (("global_" + asset2) + "_balance")
398+ let B_asset_balance = getIntegerValue(this, kBalanceB)
399+ let kWeightA = (("static_" + asset1) + "_weight")
400+ let kWeightB = (("static_" + asset2) + "_weight")
401+ let weightA = getIntegerValue(this, kWeightA)
402+ let weightB = getIntegerValue(this, kWeightB)
403+ let toGet = fraction(B_asset_balance, ((Scale8 * Scale8) - toInt(pow(fraction(toBigInt(A_asset_balance), toBigInt((Scale8 * Scale8)), toBigInt((A_asset_balance + amountToSwap)), HALFUP), 16, toBigInt(fraction(weightA, 10000, weightB)), 4, 16, CEILING))), (Scale8 * Scale8), DOWN)
404+ let feeAmount = fraction(toGet, Fee, FeeScale)
405+ if ((feeAmount == feeAmount))
406+ then {
407+ let cleanAmountOut = (toGet - feeAmount)
408+ if ((cleanAmountOut == cleanAmountOut))
409+ then cleanAmountOut
410+ else throw("Strict value is not equal to itself.")
411+ }
412+ else throw("Strict value is not equal to itself.")
413+ }
414+
415+
394416 func getTokenBalance (assetId) = match assetId {
395417 case t: ByteVector =>
396418 assetBalance(this, t)
397419 case _ =>
398420 wavesBalance(this).regular
399421 }
400422
401423
402424 func calculateCurrentAssetInterest (assetId,assetIdStr,aBalance,tokenEarningsLastCheck) = {
403425 let totalStaked = tryGetInteger("global_indexStaked")
404426 let tokenBalanceLastCheck = tokenEarningsLastCheck
405427 let currentBalanceDelta = (getTokenBalance(assetId) - aBalance)
406428 let currentTokenEarnings = if ((currentBalanceDelta > tokenBalanceLastCheck))
407429 then currentBalanceDelta
408430 else tokenBalanceLastCheck
409431 let newEarnings = (currentTokenEarnings - tokenBalanceLastCheck)
410432 let newInterest = if ((totalStaked == 0))
411433 then 0
412434 else fraction(newEarnings, Scale8, totalStaked)
413435 let lastCheckInterest = tryGetInteger((("global_lastCheck_" + assetIdStr) + "_interest"))
414436 (lastCheckInterest + newInterest)
415437 }
416438
417439
418440 func claimResult (address) = {
419441 let addressStr = toString(address)
420442 let shareAmount = tryGetInteger((addressStr + "_indexStaked"))
421443 func handler (accum,assetId) = {
422444 let assetIdStr = getAssetString(assetId)
423445 let aBalance = tryGetInteger((("global_" + getAssetString(assetId)) + "_balance"))
424446 let tokenEarningsLastCheck = tryGetInteger((("global_lastCheck_" + assetIdStr) + "_earnings"))
425447 let currentTokenInterest = calculateCurrentAssetInterest(assetId, assetIdStr, aBalance, tokenEarningsLastCheck)
426448 let currentTokenEarnings = max([tokenEarningsLastCheck, (getTokenBalance(assetId) - aBalance)])
427449 let rewardAmount = fraction(shareAmount, (currentTokenInterest - tryGetInteger((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"))), Scale8)
428450 let transfer = if ((rewardAmount == 0))
429451 then nil
430452 else [ScriptTransfer(address, rewardAmount, assetId)]
431453 let claimed = tryGetInteger((((addressStr + "_lastCheck_") + assetIdStr) + "_claimed"))
432454 ((accum ++ transfer) ++ [IntegerEntry((("global_lastCheck_" + assetIdStr) + "_earnings"), (currentTokenEarnings - rewardAmount)), IntegerEntry((("global_lastCheck_" + assetIdStr) + "_interest"), currentTokenInterest), IntegerEntry((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"), currentTokenInterest), IntegerEntry((((addressStr + "_lastCheck_") + assetIdStr) + "_claimed"), (claimed + rewardAmount))])
433455 }
434456
435457 let accum = {
436458 let $l = earnedAssets
437459 let $s = size($l)
438460 let $acc0 = nil
439461 func $f4_1 ($a,$i) = if (($i >= $s))
440462 then $a
441463 else handler($a, $l[$i])
442464
443465 func $f4_2 ($a,$i) = if (($i >= $s))
444466 then $a
445467 else throw("List size exceeds 3")
446468
447469 $f4_2($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3)
448470 }
449471 (accum ++ [IntegerEntry((addressStr + "_lastClaim"), lastBlock.timestamp)])
450472 }
451473
452474
453475 func indexStakeResult (addressStr,amount) = {
454476 let li = claimResult(addressFromStringValue(addressStr))
455477 (li ++ [IntegerEntry((addressStr + "_indexStaked"), (tryGetInteger((addressStr + "_indexStaked")) + amount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") + amount))])
456478 }
457479
458480
459481 func sum (accum,n) = (accum + parseIntValue(n))
460482
461483
462484 func setOracleAddressAndInitiate (address) = [StringEntry("static_oracle", address)]
463485
464486
465487 func isTestEnv () = {
466488 let testenv = match getBoolean(this, "TESTENV") {
467489 case x: Boolean =>
468490 x
469491 case _ =>
470492 false
471493 }
472494 testenv
473495 }
496+
497+
498+@Callable(i)
499+func readOnlyFunc (asset1,asset2,amountToSwap) = {
500+ let amountOut = calculateMinToGet(asset1, asset2, amountToSwap)
501+[IntegerEntry("DEBUG", amountOut)]
502+ }
503+
474504
475505
476506 @Callable(i)
477507 func topUpFunds () = if ((size(i.payments) != 1))
478508 then throw("Wrong payments attached!")
479509 else {
480510 let payment = i.payments[0]
481511 let asset = payment.assetId
482512 if ((indexOf(assetIds, asset) == unit))
483513 then throw("Not supported assetId")
484514 else {
485515 let amount = payment.amount
486516 let aBalance = tryGetInteger((("global_" + getAssetString(asset)) + "_balance"))
487517 let day = calculateDaysSinceStart()
488518 let reveneu = tryGetInteger(reveneuForDayByAsset(day, getAssetString(asset)))
489519 [IntegerEntry((("global_" + getAssetString(asset)) + "_balance"), (aBalance + amount)), IntegerEntry("days_since_apy", day), IntegerEntry(reveneuForDayByAsset(day, getAssetString(asset)), (reveneu + amount))]
490520 }
491521 }
492522
493523
494524
495525 @Callable(i)
496526 func preInit (assetIdsStr,assetWeightsStr,baseTokenIdStr,poolDomain) = if ((this != i.caller))
497527 then throw("admin only")
498528 else if ((size(poolDomain) > 13))
499529 then throw("too large pool domain")
500530 else {
501531 let assetIdsStrLi = split(assetIdsStr, ",")
502532 let assetIdsLi = {
503533 let $l = assetIdsStrLi
504534 let $s = size($l)
505535 let $acc0 = nil
506536 func $f4_1 ($a,$i) = if (($i >= $s))
507537 then $a
508538 else addAssetBytesToList($a, $l[$i])
509539
510540 func $f4_2 ($a,$i) = if (($i >= $s))
511541 then $a
512542 else throw("List size exceeds 3")
513543
514544 $f4_2($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3)
515545 }
516546 let assetWeightsStrLi = split(assetWeightsStr, ",")
517547 let assetWeightsSum = {
518548 let $l = assetWeightsStrLi
519549 let $s = size($l)
520550 let $acc0 = 0
521551 func $f5_1 ($a,$i) = if (($i >= $s))
522552 then $a
523553 else sum($a, $l[$i])
524554
525555 func $f5_2 ($a,$i) = if (($i >= $s))
526556 then $a
527557 else throw("List size exceeds 3")
528558
529559 $f5_2($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3)
530560 }
531561 func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetIdsLi)))
532562 then accum
533563 else {
534564 let assetDecimals = match assetIdsLi[assetNum] {
535565 case x: ByteVector =>
536566 value(assetInfo(assetIdsLi[assetNum])).decimals
537567 case _ =>
538568 8
539569 }
540570 (accum ++ [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_scale"), pow(10, 0, assetDecimals, 0, 0, DOWN)), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_decimals"), assetDecimals), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_weight"), value(parseInt(assetWeightsStrLi[assetNum])))])
541571 }
542572
543573 if ((assetWeightsSum != 100))
544574 then throw("sum of token weights must be equal to 100")
545575 else ({
546576 let $l = [0, 1, 2]
547577 let $s = size($l)
548578 let $acc0 = nil
549579 func $f6_1 ($a,$i) = if (($i >= $s))
550580 then $a
551581 else addTokenDataEntries($a, $l[$i])
552582
553583 func $f6_2 ($a,$i) = if (($i >= $s))
554584 then $a
555585 else throw("List size exceeds 3")
556586
557587 $f6_2($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3)
558588 } ++ [StringEntry("static_tokenIds", assetIdsStr), StringEntry("static_tokenWeights", assetWeightsStr), IntegerEntry("static_tokensAmount", size(assetIdsLi)), StringEntry("static_poolDomain", poolDomain), StringEntry("static_baseTokenId", baseTokenIdStr), IntegerEntry("static_fee", 100)])
559589 }
560590
561591
562592
563593 @Callable(i)
564594 func init (oracle) = {
565595 func prepareList () = {
566596 func handler (accum,n) = (accum ++ [IntegerEntry((("global_" + getAssetString(n.assetId)) + "_balance"), n.amount)])
567597
568598 let $l = i.payments
569599 let $s = size($l)
570600 let $acc0 = nil
571601 func $f4_1 ($a,$i) = if (($i >= $s))
572602 then $a
573603 else handler($a, $l[$i])
574604
575605 func $f4_2 ($a,$i) = if (($i >= $s))
576606 then $a
577607 else throw("List size exceeds 3")
578608
579609 $f4_2($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3)
580610 }
581611
582612 func calculatePoolTokensAmount (payments) = {
583613 func handler (accum,pmt) = {
584614 let assetId = pmt.assetId
585615 func handler2 (accum,n) = if ((n == assetId))
586616 then value(indexOf(assetIds, n))
587617 else accum
588618
589619 let Token = {
590620 let $l = assetIds
591621 let $s = size($l)
592622 let $acc0 = 1
593623 func $f4_1 ($a,$i) = if (($i >= $s))
594624 then $a
595625 else handler2($a, $l[$i])
596626
597627 func $f4_2 ($a,$i) = if (($i >= $s))
598628 then $a
599629 else throw("List size exceeds 3")
600630
601631 $f4_2($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3)
602632 }
603633 fraction(accum, pow(pmt.amount, Decimals[Token], AssetsWeights[Token], AssetsWeightsDecimals, 8, FLOOR), Scale8)
604634 }
605635
606636 let $l = payments
607637 let $s = size($l)
608638 let $acc0 = PoolTokenScale
609639 func $f4_1 ($a,$i) = if (($i >= $s))
610640 then $a
611641 else handler($a, $l[$i])
612642
613643 func $f4_2 ($a,$i) = if (($i >= $s))
614644 then $a
615645 else throw("List size exceeds 3")
616646
617647 $f4_2($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3)
618648 }
619649
620650 if ((tryGetInteger("global_wasInited") > 0))
621651 then throw("pool already inited")
622652 else {
623653 let initialPoolTokens = calculatePoolTokensAmount(i.payments)
624654 if ((initialPoolTokens == 0))
625655 then throw("you need a bigger tokens amount to launch the pool")
626656 else {
627657 let poolTokenIssue = Issue(("WD " + tryGetString("static_poolDomain")), "WD pool token", initialPoolTokens, PoolTokenDecimals, true, unit, 0)
628658 let poolTokenId = calculateAssetId(poolTokenIssue)
629659 ((prepareList() ++ [poolTokenIssue, IntegerEntry("global_poolToken_amount", initialPoolTokens), IntegerEntry("global_wasInited", 1), BinaryEntry("global_poolToken_id", poolTokenId), StringEntry("static_poolToken_idStr", getAssetString(poolTokenId)), ScriptTransfer(i.caller, initialPoolTokens, poolTokenId)]) ++ setOracleAddressAndInitiate(oracle))
630660 }
631661 }
632662 }
633663
634664
635665
636666 @Callable(i)
637667 func generateIndex (needChange) = if ((size(i.payments) != T))
638668 then throw(("you need to attach all pool tokens. amount of pool tokens: " + toString(T)))
639669 else if (!(checkTokensValidity(i.payments)))
640670 then throw("wrong assets attached")
641671 else {
642672 let PIssued = getMinPIssued(i.payments)
643673 let reissue = Reissue(getBinaryValue("global_poolToken_id"), PIssued, true)
644674 let result = handlePoolTokensAdd(PIssued, i.payments, i.originCaller, needChange)
645675 $Tuple2((result ++ [ScriptTransfer(i.caller, PIssued, tryGetBinary("global_poolToken_id")), reissue, IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") + PIssued))]), PIssued)
646676 }
647677
648678
649679
650680 @Callable(i)
651681 func stakeIndex () = {
652682 let addressStr = toString(i.originCaller)
653683 let pmt = i.payments[0]
654684 if ((value(pmt.assetId) != tryGetBinary("global_poolToken_id")))
655685 then throw("wrong asset attached")
656686 else indexStakeResult(addressStr, pmt.amount)
657687 }
658688
659689
660690
661691 @Callable(i)
662692 func generateAndStakeIndex (needChange) = if ((size(i.payments) != T))
663693 then throw(("you need to attach all pool tokens. amount of pool tokens: " + toString(T)))
664694 else if (!(checkTokensValidity(i.payments)))
665695 then throw("wrong assets attached")
666696 else {
667697 let PIssued = getMinPIssued(i.payments)
668698 let reissue = Reissue(getBinaryValue("global_poolToken_id"), PIssued, true)
669699 let result = handlePoolTokensAdd(PIssued, i.payments, i.originCaller, needChange)
670700 $Tuple2(((result ++ [reissue, IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") + PIssued))]) ++ indexStakeResult(toString(i.originCaller), PIssued)), PIssued)
671701 }
672702
673703
674704
675705 @Callable(i)
676706 func unstakeIndex (shareAmount) = {
677707 let addressStr = toString(i.originCaller)
678708 let shareAvailable = tryGetInteger((addressStr + "_indexStaked"))
679709 if ((shareAmount > shareAvailable))
680710 then throw("you don't have index tokens available")
681711 else (claimResult(i.originCaller) ++ [IntegerEntry((addressStr + "_indexStaked"), (shareAvailable - shareAmount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - shareAmount)), ScriptTransfer(i.caller, shareAmount, getBinaryValue("global_poolToken_id"))])
682712 }
683713
684714
685715
686716 @Callable(i)
687717 func claimIndexRewards () = claimResult(i.caller)
688718
689719
690720
691721 @Callable(i)
692722 func redeemIndex (sendToOrigin) = {
693723 let pmt = i.payments[0]
694724 if ((pmt.assetId != tryGetBinary("global_poolToken_id")))
695725 then throw("please attach pool share token")
696726 else {
697727 let PRedeemed = pmt.amount
698728 let result = handlePoolTokensRedeem(PRedeemed, if (sendToOrigin)
699729 then i.originCaller
700730 else i.caller)
701731 (result ++ [Burn(tryGetBinary("global_poolToken_id"), PRedeemed), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemed))])
702732 }
703733 }
704734
705735
706736
707737 @Callable(i)
708738 func unstakeAndRedeemIndex (shareAmount) = {
709739 let addressStr = toString(i.originCaller)
710740 let shareAvailable = tryGetInteger((addressStr + "_indexStaked"))
711741 if ((shareAmount > shareAvailable))
712742 then throw("you don't have index tokens available")
713743 else {
714744 let PRedeemed = shareAmount
715745 let result = handlePoolTokensRedeem(PRedeemed, i.originCaller)
716746 (((claimResult(i.originCaller) ++ [IntegerEntry((addressStr + "_indexStaked"), (shareAvailable - shareAmount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - shareAmount)), ScriptTransfer(i.caller, shareAmount, getBinaryValue("global_poolToken_id"))]) ++ result) ++ [Burn(tryGetBinary("global_poolToken_id"), PRedeemed), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemed))])
717747 }
718748 }
719749
720750
721751
722752 @Callable(i)
723753 func swap (assetOut,minimum) = if (isShutdown())
724754 then throw("Pool is currently shutdown")
725755 else {
726756 let pmt = value(i.payments[0])
727757 let AmountIn = value(i.payments[0].amount)
728758 let AssetIn = pmt.assetId
729759 let invokeSwap = asIntTuple(reentrantInvoke(this, "swapInternal", [assetOut, minimum, AmountIn, getAssetString(AssetIn), toString(i.caller)], nil))
730760 if ((invokeSwap == invokeSwap))
731761 then {
732762 let cleanAmountOut = invokeSwap._1
733763 if ((cleanAmountOut == cleanAmountOut))
734764 then {
735765 let feeAmount = invokeSwap._2
736766 if ((feeAmount == feeAmount))
737767 then {
738768 let topUp = if ((assetOut == "WAVES"))
739769 then {
740770 let unstake = reentrantInvoke(this, "internal", [false, (cleanAmountOut + fraction(feeAmount, 3, 4)), "WAVES"], nil)
741771 if ((unstake == unstake))
742772 then [ScriptTransfer(getFeesAccount(), fraction(feeAmount, 2, 4), getAssetBytes(assetOut))]
743773 else throw("Strict value is not equal to itself.")
744774 }
745775 else [ScriptTransfer(getFeesAccount(), fraction(feeAmount, 2, 4), getAssetBytes(assetOut))]
746776 if ((topUp == topUp))
747777 then $Tuple2(topUp, cleanAmountOut)
748778 else throw("Strict value is not equal to itself.")
749779 }
750780 else throw("Strict value is not equal to itself.")
751781 }
752782 else throw("Strict value is not equal to itself.")
753783 }
754784 else throw("Strict value is not equal to itself.")
755785 }
756786
757787
758788
759789 @Callable(i)
760790 func internal (stake,amount,assetId) = if ((i.caller != this))
761791 then throw("Not allowed")
762792 else stakeUnstake(stake, amount, assetId)
763793
764794
765795
766796 @Callable(i)
767797 func stakeAll () = stakeUnstake(true, (tryGetInteger("global_WAVES_balance") - tryGetInteger("leasing_amount")), "WAVES")
768798
769799
770800
771801 @Callable(i)
772802 func swapInternal (assetOut,minimum,AmountIn,AssetIn,caller) = if ((i.caller != this))
773803 then throw("You cant call this directly")
774804 else {
775805 let AssetOut = getAssetBytes(assetOut)
776806 let day = calculateDaysSinceStart()
777807 let reveneu = tryGetInteger(reveneuForDayByAsset(day, assetOut))
778808 let AssetInBalance = tryGetInteger((("global_" + AssetIn) + "_balance"))
779809 if ((AssetInBalance == AssetInBalance))
780810 then {
781811 let AssetOutBalance = tryGetInteger((("global_" + assetOut) + "_balance"))
782812 if ((AssetOutBalance == AssetOutBalance))
783813 then {
784814 let AmountOut = calculateOutAmount(AmountIn, getAssetBytes(AssetIn), AssetOut, AssetInBalance, AssetOutBalance)
785815 if ((AmountOut == AmountOut))
786816 then {
787817 let feeAmount = fraction(AmountOut, Fee, FeeScale)
788818 if ((feeAmount == feeAmount))
789819 then {
790820 let cleanAmountOut = (AmountOut - feeAmount)
791821 if ((cleanAmountOut == cleanAmountOut))
792822 then if ((minimum > cleanAmountOut))
793823 then throw(("amount to recieve is lower than given one: " + toString(cleanAmountOut)))
794824 else if ((0 > (AssetOutBalance - AmountOut)))
795825 then throw("contract is out of reserves")
796826 else if ((AssetOut == getAssetBytes(AssetIn)))
797827 then throw("this swap is not allowed")
798828 else {
799829 let newBalanceIn = (AssetInBalance + AmountIn)
800830 if ((newBalanceIn == newBalanceIn))
801831 then {
802832 let stake = reentrantInvoke(this, "internal", [true, AmountIn, AssetIn], nil)
803833 if ((stake == stake))
804834 then {
805835 let newBalanceOut = (AssetOutBalance - AmountOut)
806836 if ((newBalanceOut == newBalanceOut))
807837 then $Tuple2([IntegerEntry((("global_" + assetOut) + "_balance"), (newBalanceOut + fraction(feeAmount, 1, 4))), ScriptTransfer(addressFromStringValue(caller), cleanAmountOut, AssetOut), IntegerEntry((("global_" + AssetIn) + "_balance"), newBalanceIn), IntegerEntry("days_since_apy", day), IntegerEntry(reveneuForDayByAsset(day, assetOut), reveneu)], $Tuple2(cleanAmountOut, feeAmount))
808838 else throw("Strict value is not equal to itself.")
809839 }
810840 else throw("Strict value is not equal to itself.")
811841 }
812842 else throw("Strict value is not equal to itself.")
813843 }
814844 else throw("Strict value is not equal to itself.")
815845 }
816846 else throw("Strict value is not equal to itself.")
817847 }
818848 else throw("Strict value is not equal to itself.")
819849 }
820850 else throw("Strict value is not equal to itself.")
821851 }
822852 else throw("Strict value is not equal to itself.")
823853 }
824854
825855
826856 @Verifier(tx)
827857 func verify () = if (isTestEnv())
828858 then sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
829859 else {
830860 let firstUser = base58'FzsTVRXqD46KW5yj6qGNVrsouvWjpCQvD1446A96iGt4'
831861 let secondUser = base58'E23yUg8eun5nXB1nZRDf7RTyRADKxQhGNXdpTYonEvtU'
832862 let thirdUser = base58'Ga8WEBTPXbHuoXRD355mQ6ms8PsM2RFYKeA1mEP32CFe'
833863 let firstUserSigned = if (sigVerify(tx.bodyBytes, tx.proofs[0], firstUser))
834864 then 1
835865 else if (sigVerify(tx.bodyBytes, tx.proofs[1], firstUser))
836866 then 1
837867 else if (sigVerify(tx.bodyBytes, tx.proofs[2], firstUser))
838868 then 1
839869 else 0
840870 let secondUserSigned = if (sigVerify(tx.bodyBytes, tx.proofs[0], secondUser))
841871 then 1
842872 else if (sigVerify(tx.bodyBytes, tx.proofs[1], secondUser))
843873 then 1
844874 else if (sigVerify(tx.bodyBytes, tx.proofs[2], secondUser))
845875 then 1
846876 else 0
847877 let thirdUserSigned = if (sigVerify(tx.bodyBytes, tx.proofs[0], thirdUser))
848878 then 1
849879 else if (sigVerify(tx.bodyBytes, tx.proofs[1], thirdUser))
850880 then 1
851881 else if (sigVerify(tx.bodyBytes, tx.proofs[2], thirdUser))
852882 then 1
853883 else 0
854884 let signaturesCount = ((firstUserSigned + secondUserSigned) + thirdUserSigned)
855885 match tx {
856886 case _ =>
857887 (signaturesCount >= 2)
858888 }
859889 }
860890

github/deemru/w8io/786bc32 
78.63 ms