tx · BhvvCj35T5Z7B6vuTAxwKDsJogMpxxPMoWvafTtxtLtN

3PKwZxfPNsHbQBKBYuSkYWGi45BdT9tQXNJ:  -0.07000000 Waves

2024.03.21 17:19 [4093794] smart account 3PKwZxfPNsHbQBKBYuSkYWGi45BdT9tQXNJ > SELF 0.00000000 Waves

{ "type": 13, "id": "BhvvCj35T5Z7B6vuTAxwKDsJogMpxxPMoWvafTtxtLtN", "fee": 7000000, "feeAssetId": null, "timestamp": 1711030802437, "version": 2, "chainId": 87, "sender": "3PKwZxfPNsHbQBKBYuSkYWGi45BdT9tQXNJ", "senderPublicKey": "9fKcp5VpZ7BnNdpdfAh6arBQdwk6s58irztzSiKxTF4f", "proofs": [ "HY8ZKfDpnSmQmz6vEo9gJLwCSYKqzMeH7eDBTMBwWuQr4QyYk4t4yMUbeJtGpEa9UbGHeCAHVrfvey1mJyZoasa" ], "script": "base64:BgJbCAISCAoGCAgICAgBEgASABIDCgEEEgMKAQQSABIDCgEIEgMKAQESABIDCgEIEgQKAggBEgUKAwgIARIDCgEIEgMKAQESBwoFCAgIAQESABIDCgEIEgUKAwgICFMAB1ZFUlNJT04CDVBaLTEuMi4wIFBST0QACWNvbmZpZ1N0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzAg1jb25maWdBZGRyZXNzAiMzUFBFQlJnNHMyYWYyclEyWmJMdmR1MUhmZDRWbzZRVkRUbwAOQ09ORklHX0FERFJFU1MDCQAAAgUJY29uZmlnU3RyAgAFBHRoaXMJAQdBZGRyZXNzAQkA2QQBBQljb25maWdTdHIAFUFzc2V0c1dlaWdodHNEZWNpbWFscwAEAAVTY2FsZQCQTgAGU2NhbGU4AIDC1y8AB1NjYWxlMTYAgICE/qbe4REACEZlZVNjYWxlAJBOABFQb29sVG9rZW5EZWNpbWFscwAIAA5Qb29sVG9rZW5TY2FsZQkAbAYACgAABRFQb29sVG9rZW5EZWNpbWFscwAAAAAFBkhBTEZVUAAQTUlOX1NURVBTX0FNT1VOVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5DT05GSUdfQUREUkVTUwIQbWluX3N0ZXBzX2Ftb3VudAABABBNQVhfU1RFUFNfQU1PVU5UCQELdmFsdWVPckVsc2UCCQCaCAIFDkNPTkZJR19BRERSRVNTAhBtYXhfc3RlcHNfYW1vdW50APQDABJNSU5fU1RFUFNfSU5URVJWQUwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOQ09ORklHX0FERFJFU1MCEm1pbl9zdGVwc19pbnRlcnZhbAABABJNQVhfU1RFUFNfSU5URVJWQUwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOQ09ORklHX0FERFJFU1MCEm1heF9zdGVwc19pbnRlcnZhbACQTgAKTUlOX1dFSUdIVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5DT05GSUdfQUREUkVTUwIKbWluX3dlaWdodABkAApNQVhfV0VJR0hUCQELdmFsdWVPckVsc2UCCQCaCAIFDkNPTkZJR19BRERSRVNTAgptYXhfd2VpZ2h0AKxNAQ10cnlHZXRJbnRlZ2VyAQNrZXkEByRtYXRjaDAJAJoIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACA0ludAQBYgUHJG1hdGNoMAUBYgAAAQx0cnlHZXRCaW5hcnkBA2tleQQHJG1hdGNoMAkAnAgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYgUHJG1hdGNoMAUBYgEAAQx0cnlHZXRTdHJpbmcBA2tleQQHJG1hdGNoMAkAnQgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFiBQckbWF0Y2gwBQFiAgABE3RyeUdldFN0cmluZ09yVGhyb3cBA2tleQQHJG1hdGNoMAkAnQgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFiBQckbWF0Y2gwBQFiCQACAQkArAICAh1ubyBzdWNoIGtleSBpbiBkYXRhIHN0b3JhZ2U6IAUDa2V5AQ5nZXRBc3NldFN0cmluZwEHYXNzZXRJZAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAFiBQckbWF0Y2gwCQDYBAEFAWICBVdBVkVTAQ1nZXRBc3NldEJ5dGVzAQphc3NldElkU3RyAwkAAAIFCmFzc2V0SWRTdHICBVdBVkVTBQR1bml0CQDZBAEFCmFzc2V0SWRTdHIBD2dldFRva2VuQmFsYW5jZQEHYXNzZXRJZAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAF0BQckbWF0Y2gwCQDwBwIFBHRoaXMFAXQICQDvBwEFBHRoaXMJYXZhaWxhYmxlARNhZGRBc3NldEJ5dGVzVG9MaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAQ1nZXRBc3NldEJ5dGVzAQUEaXRlbQUDbmlsARRhZGRBc3NldFdlaWdodFRvTGlzdAIFYWNjdW0EaXRlbQkAzggCBQVhY2N1bQkAzAgCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfCQEOZ2V0QXNzZXRTdHJpbmcBBQRpdGVtAgdfd2VpZ2h0BQNuaWwBF2FkZEFzc2V0V2VpZ2h0VG9TdHJMaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAKQDAQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUEaXRlbQIHX3dlaWdodAUDbmlsARZhZGRBc3NldERlY2ltYWxzVG9MaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18JAQ5nZXRBc3NldFN0cmluZwEFBGl0ZW0CCV9kZWNpbWFscwUDbmlsARNhZGRBc3NldFNjYWxlVG9MaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18JAQ5nZXRBc3NldFN0cmluZwEFBGl0ZW0CBl9zY2FsZQUDbmlsAQxhZGRJbnRUb0xpc3QCBWFjY3VtBGl0ZW0JAM4IAgUFYWNjdW0JAMwIAgkBDXBhcnNlSW50VmFsdWUBBQRpdGVtBQNuaWwADnVzZG5Bc3NldElkU3RyCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg51c2RuQXNzZXRJZFN0cgIsREcyeEZrUGREd0tVb0JrekdBaFF0THBTR3pmWExpQ1lQRXplS0gyQWQyNHAAEHB1enpsZUFzc2V0SWRTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCEHB1enpsZUFzc2V0SWRTdHICLEhFQjhRYXc5eHJXcFdzOHRIc2lBVFlHQldEQnRQMlM3a2NQQUxyTXU0M0FTAA51c2R0QXNzZXRJZFN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIOdXNkdEFzc2V0SWRTdHICLDM0TjlZY0VFVExXbjkzcVlRNjRFc1AxeDg5dFNydUpVNDRSckVNU1hYRVBKABF1c2R0UHB0QXNzZXRJZFN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIRdXNkdFBwdEFzc2V0SWRTdHICLDl3YzNMWE5BNFRFQnNYeUt0b0xFOW1yYkREN1dNSFh2WHJDalp2YWJMQXNpAA5yb21lQXNzZXRJZFN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIOcm9tZUFzc2V0SWRTdHICLEFQNENiNXhMWUdINlppZ0hyZUNaSG9YcFFUV0RrUHNHMkJIcWZEVXg2dGFKAA93YXZlc0Fzc2V0SWRTdHICBVdBVkVTAAt1c2RuQXNzZXRJZAkA2QQBBQ51c2RuQXNzZXRJZFN0cgANcHV6emxlQXNzZXRJZAkA2QQBBRBwdXp6bGVBc3NldElkU3RyAAt1c2R0QXNzZXRJZAkA2QQBBQ51c2R0QXNzZXRJZFN0cgAOdXNkdFBwdEFzc2V0SWQJANkEAQURdXNkdFBwdEFzc2V0SWRTdHIAC3JvbWVBc3NldElkCQDZBAEFDnJvbWVBc3NldElkU3RyAAx3YXZlc0Fzc2V0SWQFBHVuaXQAFXN1cHBvcnRlZEZlZUFzc2V0c1N0cgkAzAgCBQ51c2RuQXNzZXRJZFN0cgkAzAgCBRBwdXp6bGVBc3NldElkU3RyCQDMCAIFDnVzZHRBc3NldElkU3RyCQDMCAIFEXVzZHRQcHRBc3NldElkU3RyCQDMCAIFD3dhdmVzQXNzZXRJZFN0cgkAzAgCBQ5yb21lQXNzZXRJZFN0cgUDbmlsABFwYXJlbnRQb29sQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCEXBhcmVudFBvb2xBZGRyZXNzAiMzUEZEZ3p1MVV0c3dBa0NNeHFxUWpiVGVIYVg0Y01hYjhLaAANbWFzdGVyQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDW1hc3RlckFkZHJlc3MCIzNQTGp3SGN6OU5FdWFUbzYzTlpSOUI5b2tRaUtReFpTYm1mAAxtYXN0ZXJQdWJLZXkJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIMbWFzdGVyUHViS2V5Aiw0ejhDS1NZUUJLa3p4N1BCYjV1QlAxWVBhNllBSFJOVEFwVzFzUVZIVDVlVQANb3JhY2xlQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDW9yYWNsZUFkZHJlc3MCIzNQOGQxRTFCTEtvRDUyeTNiUUoxYkRUZDJURDFncGFMbjl0AA5zdGFraW5nQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDnN0YWtpbmdBZGRyZXNzAiMzUEZUYnl3cXh0RmZ1a1gzSHlUODgxZzRpVzVLNFFMM0ZBUwALZmVlc0FkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAgtmZWVzQWRkcmVzcwIjM1BGV0FWS21YamZIWHl6SmIxMmpDYmhQNFVoaTl0NHVXaUQAD3Bvb2xzSHViQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCD3Bvb2xzSHViQWRkcmVzcwIjM1A1WXV0akROQzNoQUJCVnN2ZUZ1WlRUYlE1UGR0U0RCZ2sAEnNodXRkb3duQWRkcmVzc1N0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIPc2h1dGRvd25BZGRyZXNzAiMzUEVwdjloUkZXRUVCVTIyV1JuTHN3MWJINFlHdGNVNzI4bwAPbGF5ZXIyQWRkcmVzc2VzCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg9sYXllcjJBZGRyZXNzZXMCRzNQUjFRdmk5bUhUMzVTd1dFa0xTcXFFMkw4dGhpUExkVldVLDNQUW9CZlVLSGtKQWVHV2hvb0xQN1dTOG92YjU0YXY5SnAyAApnb3ZBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIKZ292QWRkcmVzcwIjM1A2dXJvOXhDc0U4dGU3OFFaanpxeTdhcThuYXRTemRjZUMAEWNvbGRNYXN0ZXJBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIRY29sZE1hc3RlckFkZHJlc3MCIzNQSzluaFBmUGJNQnlnQjlaZ0hWTUhhUWJTb29qd3JCZnhqAAFUCQENdHJ5R2V0SW50ZWdlcgECE3N0YXRpY190b2tlbnNBbW91bnQACGFzc2V0SWRzCgACJGwJALUJAgkBDHRyeUdldFN0cmluZwECD3N0YXRpY190b2tlbklkcwIBLAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQETYWRkQXNzZXRCeXRlc1RvTGlzdAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgANQXNzZXRzV2VpZ2h0cwoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMV8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEUYWRkQXNzZXRXZWlnaHRUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjFfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYxXzICCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACERlY2ltYWxzCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYyXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARZhZGRBc3NldERlY2ltYWxzVG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYyXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMl8yAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAZTY2FsZXMKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjNfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBE2FkZEFzc2V0U2NhbGVUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjNfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYzXzICCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoAA0ZlZQkBDXRyeUdldEludGVnZXIBAgpzdGF0aWNfZmVlAAxlYXJuZWRBc3NldHMFCGFzc2V0SWRzAQppc1NodXRkb3duAAQPc2h1dGRvd25BZGRyZXNzCQCmCAEFEnNodXRkb3duQWRkcmVzc1N0cgMJAAACBQ9zaHV0ZG93bkFkZHJlc3MFBHVuaXQHBAckbWF0Y2gwCQCbCAIJAQV2YWx1ZQEFD3NodXRkb3duQWRkcmVzcwILaXNfc2h1dGRvd24DCQABAgUHJG1hdGNoMAIHQm9vbGVhbgQBeAUHJG1hdGNoMAUBeAcBFmdldEN1cnJlbnRUb2tlbkJhbGFuY2UBCHRva2VuTnVtBAp0b2tlbklkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBCQCRAwIFCGFzc2V0SWRzBQh0b2tlbk51bQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwUKdG9rZW5JZFN0cgIIX2JhbGFuY2UBCGdldEtNdWx0AAQHJG1hdGNoMAkAnwgBAgxzdGF0aWNfS011bHQDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4BQdTY2FsZTE2ARJzYXZlQ3VycmVudFdlaWdodHMABAphc3NldElkc0xpCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfdG9rZW5JZHMCASwKAQFzAgVhY2N1bQdhc3NldElkCQDOCAIFBWFjY3VtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICFnJlYmFsYW5jZV9zdGFydFdlaWdodF8FB2Fzc2V0SWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FB2Fzc2V0SWQCB193ZWlnaHQFA25pbAoAAiRsBQphc3NldElkc0xpCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAkAawMJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQJAQhnZXRLTXVsdAAFB1NjYWxlMTYBEGNhbGN1bGF0ZVBJc3N1ZWQCBmFtb3VudAd0b2tlbklkBAdQc3VwcGx5CQEZZ2V0VmlydHVhbFBvb2xUb2tlbkFtb3VudAAEB0JhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFB3Rva2VuSWQCCF9iYWxhbmNlBAJ0MQkAbgQFBmFtb3VudAUHUHN1cHBseQUHQmFsYW5jZQUERE9XTgUCdDEBDWdldE1pblBJc3N1ZWQBCHBheW1lbnRzCgEHaGFuZGxlcgIFYWNjdW0HY3VycmVudAQHUElzc3VlZAkBEGNhbGN1bGF0ZVBJc3N1ZWQCCAUHY3VycmVudAZhbW91bnQIBQdjdXJyZW50B2Fzc2V0SWQDCQAAAgUHUElzc3VlZAAACQACAQIkb25lIG9mIHRoZSB0b2tlbnMgYW1vdW50cyBpcyB0b28gbG93AwMJAAACBQVhY2N1bQAABgkAZgIFBWFjY3VtBQdQSXNzdWVkBQdQSXNzdWVkBQVhY2N1bQQJbWluUElzc2VkCgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdoYW5kbGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBQltaW5QSXNzZWQBEmNhbGN1bGF0ZVVzZG5WYWx1ZQQHYXNzZXRJZAZhbW91bnQIYUJhbGFuY2UQZ2l2ZW5Vc2RuQmFsYW5jZQQKdXNkbkluUG9vbAkAzwgCBQhhc3NldElkcwULdXNkbkFzc2V0SWQEDHB1enpsZUluUG9vbAkAzwgCBQhhc3NldElkcwUNcHV6emxlQXNzZXRJZAQKdXNkdEluUG9vbAkAzwgCBQhhc3NldElkcwULdXNkdEFzc2V0SWQEDXVzZHRQcHRJblBvb2wJAM8IAgUIYXNzZXRJZHMFDnVzZHRQcHRBc3NldElkBAt3YXZlc0luUG9vbAkAzwgCBQhhc3NldElkcwUEdW5pdAQLYXNzZXRXZWlnaHQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18JAQ5nZXRBc3NldFN0cmluZwEFB2Fzc2V0SWQCB193ZWlnaHQEC2ZlZUFzc2V0U3RyCQEMdHJ5R2V0U3RyaW5nAQIPc3RhdGljX2ZlZVRva2VuAwkAAAIFC2ZlZUFzc2V0U3RyBRBwdXp6bGVBc3NldElkU3RyBAxwdXp6bGVXZWlnaHQJAJEDAgUNQXNzZXRzV2VpZ2h0cwkBBXZhbHVlAQkAzwgCBQhhc3NldElkcwUNcHV6emxlQXNzZXRJZAQNcHV6emxlQmFsYW5jZQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwUQcHV6emxlQXNzZXRJZFN0cgIIX2JhbGFuY2UEDmFtb3VudEluUHV6emxlCQBrAwUGYW1vdW50CQBpAgUNcHV6emxlQmFsYW5jZQUMcHV6emxlV2VpZ2h0CQBpAgUIYUJhbGFuY2UFC2Fzc2V0V2VpZ2h0BAtwdXp6bGVQcmljZQkBEUBleHRyTmF0aXZlKDEwNTApAgURcGFyZW50UG9vbEFkZHJlc3MCFmdsb2JhbF9sYXN0UHV6emxlUHJpY2UJAGsDCQBoAgUOYW1vdW50SW5QdXp6bGUFC3B1enpsZVByaWNlAAEFBlNjYWxlOAMJAAACBQtmZWVBc3NldFN0cgUOdXNkdEFzc2V0SWRTdHIECnVzZHRXZWlnaHQJAJEDAgUNQXNzZXRzV2VpZ2h0cwkBBXZhbHVlAQUKdXNkdEluUG9vbAQLdXNkdEJhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8FDnVzZHRBc3NldElkU3RyAghfYmFsYW5jZQkAawMFBmFtb3VudAkAaQIFC3VzZHRCYWxhbmNlBQp1c2R0V2VpZ2h0CQBpAgUIYUJhbGFuY2UFC2Fzc2V0V2VpZ2h0AwkAAAIFC2ZlZUFzc2V0U3RyBRF1c2R0UHB0QXNzZXRJZFN0cgQKdXNkdFdlaWdodAkAkQMCBQ1Bc3NldHNXZWlnaHRzCQEFdmFsdWUBBQ11c2R0UHB0SW5Qb29sBAt1c2R0QmFsYW5jZQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwURdXNkdFBwdEFzc2V0SWRTdHICCF9iYWxhbmNlCQBrAwUGYW1vdW50CQBpAgULdXNkdEJhbGFuY2UFCnVzZHRXZWlnaHQJAGkCBQhhQmFsYW5jZQULYXNzZXRXZWlnaHQDCQAAAgULZmVlQXNzZXRTdHIFDnVzZG5Bc3NldElkU3RyBAp1c2RuV2VpZ2h0CQCRAwIFDUFzc2V0c1dlaWdodHMJAQV2YWx1ZQEJAM8IAgUIYXNzZXRJZHMFC3VzZG5Bc3NldElkBAt1c2RuQmFsYW5jZQQHJG1hdGNoMAUQZ2l2ZW5Vc2RuQmFsYW5jZQMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFEGdpdmVuVXNkbkJhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFC3VzZG5Bc3NldElkAghfYmFsYW5jZQkAawMFBmFtb3VudAkAaQIJAQV2YWx1ZQEFC3VzZG5CYWxhbmNlBQp1c2RuV2VpZ2h0CQBpAgUIYUJhbGFuY2UFC2Fzc2V0V2VpZ2h0BAt3YXZlc1dlaWdodAC4FwQId0JhbGFuY2UJAGkCCQENdHJ5R2V0SW50ZWdlcgECFGdsb2JhbF9XQVZFU19iYWxhbmNlADIJAGsDBQZhbW91bnQJAGkCBQh3QmFsYW5jZQULd2F2ZXNXZWlnaHQJAGkCBQhhQmFsYW5jZQULYXNzZXRXZWlnaHQBEmdldFByaWNlRnJvbU9yYWNsZQEKYXNzZXRJZFN0cgQHJG1hdGNoMAkAmggCBQ1vcmFjbGVBZGRyZXNzCQCsAgIFCmFzc2V0SWRTdHICB190d2FwNUIDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4AAABEWNhbGN1bGF0ZVVzZFZhbHVlAwdhc3NldElkBmFtb3VudAhhQmFsYW5jZQQLYXNzZXRXZWlnaHQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18JAQ5nZXRBc3NldFN0cmluZwEFB2Fzc2V0SWQCB193ZWlnaHQEC2ZlZUFzc2V0U3RyCQEMdHJ5R2V0U3RyaW5nAQIPc3RhdGljX2ZlZVRva2VuBA1mZWVBc3NldFNjYWxlCQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzCQCsAgIJAKwCAgIHc3RhdGljXwULZmVlQXNzZXRTdHICBl9zY2FsZQQLZmVlQXNzZXROdW0JAQV2YWx1ZQEJAM8IAgUIYXNzZXRJZHMJAQ1nZXRBc3NldEJ5dGVzAQULZmVlQXNzZXRTdHIEDmZlZUFzc2V0V2VpZ2h0CQCRAwIFDUFzc2V0c1dlaWdodHMFC2ZlZUFzc2V0TnVtBA9mZWVBc3NldEJhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8FC2ZlZUFzc2V0U3RyAghfYmFsYW5jZQQNdmFsSW5GZWVBc3NldAkAawMFBmFtb3VudAkAaQIFD2ZlZUFzc2V0QmFsYW5jZQUOZmVlQXNzZXRXZWlnaHQJAGkCBQhhQmFsYW5jZQULYXNzZXRXZWlnaHQEDWZlZUFzc2V0UHJpY2UJARJnZXRQcmljZUZyb21PcmFjbGUBBQtmZWVBc3NldFN0cgkAawMFDXZhbEluRmVlQXNzZXQFDWZlZUFzc2V0UHJpY2UFDWZlZUFzc2V0U2NhbGUBE2NoZWNrVG9rZW5zVmFsaWRpdHkBCHBheW1lbnRzCgEIaGFuZGxlcjECBWFjY3VtB3BheW1lbnQJAM4IAgUFYWNjdW0JAMwIAggFB3BheW1lbnQHYXNzZXRJZAUDbmlsBANpZHMKAAIkbAUIcGF5bWVudHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGhhbmRsZXIxAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkAAAIFA2lkcwUDaWRzCgEIaGFuZGxlcjICBWFjY3VtB2Fzc2V0SWQDCQECIT0CCQDPCAIFA2lkcwUHYXNzZXRJZAUEdW5pdAkAZAIFBWFjY3VtAAEJAAIBCQCsAgICFGFzc2V0IG5vdCBhdHRhY2hlZDogCQEOZ2V0QXNzZXRTdHJpbmcBBQdhc3NldElkBAZjaGVja3MKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjVfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGhhbmRsZXIyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY1XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNV8yAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkAAAIFBmNoZWNrcwUGY2hlY2tzBgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgETaGFuZGxlUG9vbFRva2Vuc0FkZAQHUElzc3VlZAhwYXltZW50cwt1c2VyQWRkcmVzcwpuZWVkQ2hhbmdlCgEVZ2V0VG9rZW5QYXltZW50QW1vdW50AQd0b2tlbklkCgEHaGFuZGxlcgIFYWNjdW0HcGF5bWVudAMJAAACCAUHcGF5bWVudAdhc3NldElkBQd0b2tlbklkCAUHcGF5bWVudAZhbW91bnQFBWFjY3VtCgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdoYW5kbGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCgERaGFuZGxlVG9rZW5DaGFuZ2UCBWFjY3VtB3Rva2VuSWQEAkJrCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfCQEOZ2V0QXNzZXRTdHJpbmcBBQd0b2tlbklkAghfYmFsYW5jZQQHUFN1cHBseQkBGWdldFZpcnR1YWxQb29sVG9rZW5BbW91bnQABA10b2tlbkRlY2ltYWxzCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfCQEOZ2V0QXNzZXRTdHJpbmcBBQd0b2tlbklkAgZfc2NhbGUEAmExCQC9AgQJALkCAgkAtgIBCQBkAgUHUFN1cHBseQUHUElzc3VlZAkAtgIBBQZTY2FsZTgJALYCAQUNdG9rZW5EZWNpbWFscwkAtgIBBQdQU3VwcGx5BQdDRUlMSU5HBAJEawkAoAMBCQC9AgQJALgCAgUCYTEJALkCAgkAtgIBBQ10b2tlbkRlY2ltYWxzCQC2AgEFBlNjYWxlOAkAtgIBBQJCawkAuQICCQC2AgEFDXRva2VuRGVjaW1hbHMJALYCAQUGU2NhbGU4BQdDRUlMSU5HBA1wYXltZW50QW1vdW50CQEVZ2V0VG9rZW5QYXltZW50QW1vdW50AQUHdG9rZW5JZAQIdG9SZXR1cm4JAGUCBQ1wYXltZW50QW1vdW50BQJEawQBdAMDBQpuZWVkQ2hhbmdlCQBmAgUIdG9SZXR1cm4AAAcJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFCHRvUmV0dXJuBQd0b2tlbklkBQNuaWwFA25pbAkAzggCCQDOCAIFBWFjY3VtBQF0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHZ2xvYmFsXwkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAIIX2JhbGFuY2UJAGQCBQJCawUCRGsFA25pbAoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQERaGFuZGxlVG9rZW5DaGFuZ2UCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoBFmhhbmRsZVBvb2xUb2tlbnNSZWRlZW0CCVBSZWRlZW1lZAt1c2VyQWRkcmVzcwoBEWhhbmRsZVRva2VuUmVkZWVtAgVhY2N1bQd0b2tlbklkBAJCawkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAIIX2JhbGFuY2UEB1BTdXBwbHkJARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAQNdG9rZW5EZWNpbWFscwkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAIGX3NjYWxlBAZwc3VwcGwJAL0CBAkAuQICCQC2AgEJAGUCBQdQU3VwcGx5BQlQUmVkZWVtZWQJALYCAQUGU2NhbGU4CQC2AgEFBlNjYWxlOAkAtgIBBQdQU3VwcGx5BQRET1dOBAZhbW91bnQJAKADAQkAvQIECQC4AgIJALYCAQUHU2NhbGUxNgUGcHN1cHBsCQC2AgEFAkJrCQC2AgEFB1NjYWxlMTYFB0NFSUxJTkcJAM4IAgUFYWNjdW0JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdnbG9iYWxfCQEOZ2V0QXNzZXRTdHJpbmcBBQd0b2tlbklkAghfYmFsYW5jZQkAZQIFAkJrBQZhbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFBmFtb3VudAUHdG9rZW5JZAUDbmlsCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARFoYW5kbGVUb2tlblJlZGVlbQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgESY2FsY3VsYXRlT3V0QW1vdW50BQhBbW91bnRJbgdhc3NldEluCGFzc2V0T3V0CUJhbGFuY2VJbgpCYWxhbmNlT3V0BAdJbmRleEluCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzBQdhc3NldEluBAhJbmRleE91dAkBBXZhbHVlAQkAzwgCBQhhc3NldElkcwUIYXNzZXRPdXQDCQAAAgUHSW5kZXhJbgUISW5kZXhPdXQFCEFtb3VudEluCQBuBAUKQmFsYW5jZU91dAkAZQIJAGgCBQZTY2FsZTgFBlNjYWxlOAkAoAMBCQB2BgkAvQIECQC5AgIJALYCAQUJQmFsYW5jZUluCQC2AgEAkE4JALYCAQkAaAIFBlNjYWxlOAUGU2NhbGU4CQC5AgIJALYCAQkAZAIFCUJhbGFuY2VJbgUIQW1vdW50SW4JALYCAQCQTgUGSEFMRlVQABAJALYCAQkAawMJAJEDAgUNQXNzZXRzV2VpZ2h0cwUHSW5kZXhJbgCAoJSljR0JAJEDAgUNQXNzZXRzV2VpZ2h0cwUISW5kZXhPdXQADAAQBQdDRUlMSU5HCQBoAgUGU2NhbGU4BQZTY2FsZTgFCEhBTEZFVkVOAR1jYWxjdWxhdGVDdXJyZW50QXNzZXRJbnRlcmVzdAQHYXNzZXRJZAphc3NldElkU3RyCGFCYWxhbmNlFnRva2VuRWFybmluZ3NMYXN0Q2hlY2sEC3RvdGFsU3Rha2VkCQENdHJ5R2V0SW50ZWdlcgECEmdsb2JhbF9pbmRleFN0YWtlZAQVdG9rZW5CYWxhbmNlTGFzdENoZWNrBRZ0b2tlbkVhcm5pbmdzTGFzdENoZWNrBBNjdXJyZW50QmFsYW5jZURlbHRhCQBlAgkBD2dldFRva2VuQmFsYW5jZQEFB2Fzc2V0SWQFCGFCYWxhbmNlBBRjdXJyZW50VG9rZW5FYXJuaW5ncwMJAGYCBRNjdXJyZW50QmFsYW5jZURlbHRhBRV0b2tlbkJhbGFuY2VMYXN0Q2hlY2sFE2N1cnJlbnRCYWxhbmNlRGVsdGEFFXRva2VuQmFsYW5jZUxhc3RDaGVjawQLbmV3RWFybmluZ3MJAGUCBRRjdXJyZW50VG9rZW5FYXJuaW5ncwUVdG9rZW5CYWxhbmNlTGFzdENoZWNrBAtuZXdJbnRlcmVzdAMJAAACBQt0b3RhbFN0YWtlZAAAAAAJAGsDBQtuZXdFYXJuaW5ncwUGU2NhbGU4BQt0b3RhbFN0YWtlZAQRbGFzdENoZWNrSW50ZXJlc3QJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICEWdsb2JhbF9sYXN0Q2hlY2tfBQphc3NldElkU3RyAglfaW50ZXJlc3QJAGQCBRFsYXN0Q2hlY2tJbnRlcmVzdAULbmV3SW50ZXJlc3QBC2NsYWltUmVzdWx0AQdhZGRyZXNzBAphZGRyZXNzU3RyCQClCAEFB2FkZHJlc3MEDHB1enpsZUFtb3VudAkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAoBB2hhbmRsZXICBWFjY3VtB2Fzc2V0SWQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFB2Fzc2V0SWQECGFCYWxhbmNlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfCQEOZ2V0QXNzZXRTdHJpbmcBBQdhc3NldElkAghfYmFsYW5jZQQWdG9rZW5FYXJuaW5nc0xhc3RDaGVjawkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIRZ2xvYmFsX2xhc3RDaGVja18FCmFzc2V0SWRTdHICCV9lYXJuaW5ncwQUY3VycmVudFRva2VuSW50ZXJlc3QJAR1jYWxjdWxhdGVDdXJyZW50QXNzZXRJbnRlcmVzdAQFB2Fzc2V0SWQFCmFzc2V0SWRTdHIFCGFCYWxhbmNlBRZ0b2tlbkVhcm5pbmdzTGFzdENoZWNrBBRjdXJyZW50VG9rZW5FYXJuaW5ncwkAlgMBCQDMCAIFFnRva2VuRWFybmluZ3NMYXN0Q2hlY2sJAMwIAgkAZQIJAQ9nZXRUb2tlbkJhbGFuY2UBBQdhc3NldElkBQhhQmFsYW5jZQUDbmlsBAxyZXdhcmRBbW91bnQJAGsDBQxwdXp6bGVBbW91bnQJAGUCBRRjdXJyZW50VG9rZW5JbnRlcmVzdAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgkArAICBQphZGRyZXNzU3RyAgtfbGFzdENoZWNrXwUKYXNzZXRJZFN0cgIJX2ludGVyZXN0BQZTY2FsZTgECHRyYW5zZmVyAwkAAAIFDHJld2FyZEFtb3VudAAABQNuaWwJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUHYWRkcmVzcwUMcmV3YXJkQW1vdW50BQdhc3NldElkBQNuaWwJAJQKAgkAzggCCQDOCAIIBQVhY2N1bQJfMQUIdHJhbnNmZXIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAhFnbG9iYWxfbGFzdENoZWNrXwUKYXNzZXRJZFN0cgIJX2Vhcm5pbmdzCQBlAgUUY3VycmVudFRva2VuRWFybmluZ3MFDHJld2FyZEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICEWdsb2JhbF9sYXN0Q2hlY2tfBQphc3NldElkU3RyAglfaW50ZXJlc3QFFGN1cnJlbnRUb2tlbkludGVyZXN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICBQphZGRyZXNzU3RyAgtfbGFzdENoZWNrXwUKYXNzZXRJZFN0cgIJX2ludGVyZXN0BRRjdXJyZW50VG9rZW5JbnRlcmVzdAUDbmlsCQBkAggFBWFjY3VtAl8yCQERY2FsY3VsYXRlVXNkVmFsdWUDBQdhc3NldElkBQxyZXdhcmRBbW91bnQFCGFCYWxhbmNlBAVhY2N1bQoAAiRsBQxlYXJuZWRBc3NldHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIFA25pbAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdoYW5kbGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQCUCgIJAM4IAggFBWFjY3VtAl8xCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFkZHJlc3NTdHICEV9jbGFpbWVkUmV3YXJkVVNECQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICEV9jbGFpbWVkUmV3YXJkVVNECAUFYWNjdW0CXzIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgIKX2xhc3RDbGFpbQgFCWxhc3RCbG9jawl0aW1lc3RhbXAFA25pbAgFBWFjY3VtAl8yARBpbmRleFN0YWtlUmVzdWx0AgphZGRyZXNzU3RyBmFtb3VudAQCbGkICQELY2xhaW1SZXN1bHQBCQERQGV4dHJOYXRpdmUoMTA2MikBBQphZGRyZXNzU3RyAl8xCQDOCAIFAmxpCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgISZ2xvYmFsX2luZGV4U3Rha2VkCQBkAgkBDXRyeUdldEludGVnZXIBAhJnbG9iYWxfaW5kZXhTdGFrZWQFBmFtb3VudAUDbmlsAQNzdW0CBWFjY3VtAW4JAGQCBQVhY2N1bQkBDXBhcnNlSW50VmFsdWUBBQFuAQ1jaGVja0ZlZUFzc2V0AgVhY2N1bQRuZXh0AwMJAQIhPQIJAM8IAgUVc3VwcG9ydGVkRmVlQXNzZXRzU3RyBQRuZXh0BQR1bml0CQAAAgUFYWNjdW0CAAcFBG5leHQFBWFjY3VtARJnZXRUbXBSZWJhbGFuY2VJZHMBDW5ld0Fzc2V0SWRzTGkEEWN1cnJlbnRBc3NldElkc0xpCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfdG9rZW5JZHMCASwEBnJlc3VsdAUNbmV3QXNzZXRJZHNMaQoBAWYCBWFjY3VtB2Fzc2V0SWQDCQAAAgkAzwgCBQZyZXN1bHQFB2Fzc2V0SWQFBHVuaXQJAM4IAgUFYWNjdW0JAMwIAgUHYXNzZXRJZAUDbmlsBQVhY2N1bQoAAiRsBRFjdXJyZW50QXNzZXRJZHNMaQoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFBnJlc3VsdAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEBZgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIk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JGY3XzECCQEFJGY3XzECCQEFJGY3XzECCQEFJGY3XzECCQEFJGY3XzECCQEFJGY3XzECCQEFJGY3XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoJAMwIAgkBC1N0cmluZ0VudHJ5AgIPc3RhdGljX3Rva2VuSWRzBQthc3NldElkc1N0cgkAzAgCCQELU3RyaW5nRW50cnkCAg9zdGF0aWNfZmVlVG9rZW4FC2ZlZUFzc2V0U3RyCQDMCAIJAQtTdHJpbmdFbnRyeQICE3N0YXRpY190b2tlbldlaWdodHMFD2Fzc2V0V2VpZ2h0c1N0cgkAzAgCCQEMSW50ZWdlckVudHJ5AgITc3RhdGljX3Rva2Vuc0Ftb3VudAkAkAMBBQphc3NldElkc0xpCQDMCAIJAQtTdHJpbmdFbnRyeQICEXN0YXRpY19wb29sRG9tYWluBQpwb29sRG9tYWluCQDMCAIJAQtTdHJpbmdFbnRyeQICEnN0YXRpY19iYXNlVG9rZW5JZAUOYmFzZVRva2VuSWRTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgIQc3RhdGljX3Bvb2xPd25lcgUJcG9vbE93bmVyCQDMCAIJAQxJbnRlZ2VyRW50cnkCAgpzdGF0aWNfZmVlBQNmZWUJAMwIAgkBDEludGVnZXJFbnRyeQICDHN0YXRpY19LTXVsdAUHU2NhbGUxNgUDbmlsAWkBBmRlSW5pdAADCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIKYWRtaW4gb25seQkAzAgCCQEMSW50ZWdlckVudHJ5AgIQZ2xvYmFsX3dhc0luaXRlZAAABQNuaWwBaQEEaW5pdAAKAQtwcmVwYXJlTGlzdAAKAQdoYW5kbGVyAgVhY2N1bQFuCQDOCAIFBWFjY3VtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHZ2xvYmFsXwkBDmdldEFzc2V0U3RyaW5nAQgFAW4HYXNzZXRJZAIIX2JhbGFuY2UIBQFuBmFtb3VudAUDbmlsCgACJGwIBQFpCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdoYW5kbGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCgEZY2FsY3VsYXRlUG9vbFRva2Vuc0Ftb3VudAEIcGF5bWVudHMKAQdoYW5kbGVyAgVhY2N1bQNwbXQEB2Fzc2V0SWQIBQNwbXQHYXNzZXRJZAoBCGhhbmRsZXIyAgVhY2N1bQFuAwkAAAIFAW4FB2Fzc2V0SWQJAQV2YWx1ZQEJAM8IAgUIYXNzZXRJZHMFAW4FBWFjY3VtBAVUb2tlbgoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAQoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIaGFuZGxlcjICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoJAGsDBQVhY2N1bQkAbAYIBQNwbXQGYW1vdW50CQCRAwIFCERlY2ltYWxzBQVUb2tlbgkAkQMCBQ1Bc3NldHNXZWlnaHRzBQVUb2tlbgUVQXNzZXRzV2VpZ2h0c0RlY2ltYWxzAAgFBUZMT09SBQZTY2FsZTgKAAIkbAUIcGF5bWVudHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQ5Qb29sVG9rZW5TY2FsZQoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3ADCQBmAgkBDXRyeUdldEludGVnZXIBAhBnbG9iYWxfd2FzSW5pdGVkAAAJAAIBAhNwb29sIGFscmVhZHkgaW5pdGVkBBFpbml0aWFsUG9vbFRva2VucwkBGWNhbGN1bGF0ZVBvb2xUb2tlbnNBbW91bnQBCAUBaQhwYXltZW50cwMJAAACBRFpbml0aWFsUG9vbFRva2VucwAACQACAQIyeW91IG5lZWQgYSBiaWdnZXIgdG9rZW5zIGFtb3VudCB0byBsYXVuY2ggdGhlIHBvb2wEDnBvb2xUb2tlbklzc3VlCQDDCAcJAKwCAgIDUFogCQEMdHJ5R2V0U3RyaW5nAQIRc3RhdGljX3Bvb2xEb21haW4CHVB1enpsZSBTd2FwOiBwb29sIGluZGV4IHRva2VuBRFpbml0aWFsUG9vbFRva2VucwURUG9vbFRva2VuRGVjaW1hbHMGBQR1bml0AAAEC3Bvb2xUb2tlbklkCQC4CAEFDnBvb2xUb2tlbklzc3VlCQDOCAIJAQtwcmVwYXJlTGlzdAAJAMwIAgUOcG9vbFRva2VuSXNzdWUJAMwIAgkBDEludGVnZXJFbnRyeQICF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50BRFpbml0aWFsUG9vbFRva2VucwkAzAgCCQEMSW50ZWdlckVudHJ5AgIQZ2xvYmFsX3dhc0luaXRlZAABCQDMCAIJAQtCaW5hcnlFbnRyeQICE2dsb2JhbF9wb29sVG9rZW5faWQFC3Bvb2xUb2tlbklkCQDMCAIJAQtTdHJpbmdFbnRyeQICFnN0YXRpY19wb29sVG9rZW5faWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFC3Bvb2xUb2tlbklkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgxfaW5kZXhTdGFrZWQFEWluaXRpYWxQb29sVG9rZW5zCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQFEWluaXRpYWxQb29sVG9rZW5zBQNuaWwBaQENZ2VuZXJhdGVJbmRleAEKbmVlZENoYW5nZQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMFAVQJAAIBCQCsAgICO3lvdSBuZWVkIHRvIGF0dGFjaCBhbGwgcG9vbCB0b2tlbnMuIGFtb3VudCBvZiBwb29sIHRva2VuczogCQCkAwEFAVQDCQEBIQEJARNjaGVja1Rva2Vuc1ZhbGlkaXR5AQgFAWkIcGF5bWVudHMJAAIBAhV3cm9uZyBhc3NldHMgYXR0YWNoZWQEDVBJc3N1ZWROb011bHQJAQ1nZXRNaW5QSXNzdWVkAQgFAWkIcGF5bWVudHMEBnJlc3VsdAkBE2hhbmRsZVBvb2xUb2tlbnNBZGQEBQ1QSXNzdWVkTm9NdWx0CAUBaQhwYXltZW50cwgFAWkMb3JpZ2luQ2FsbGVyBQpuZWVkQ2hhbmdlBA9QSXNzdWVkV2l0aE11bHQJAG4EBQ1QSXNzdWVkTm9NdWx0BQdTY2FsZTE2CQEIZ2V0S011bHQABQRET1dOBAdyZWlzc3VlCQEHUmVpc3N1ZQMJARFAZXh0ck5hdGl2ZSgxMDU3KQECE2dsb2JhbF9wb29sVG9rZW5faWQFD1BJc3N1ZWRXaXRoTXVsdAYJAJQKAgkAzggCBQZyZXN1bHQJAMwIAgUHcmVpc3N1ZQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFD1BJc3N1ZWRXaXRoTXVsdAkBDHRyeUdldEJpbmFyeQECE2dsb2JhbF9wb29sVG9rZW5faWQJAMwIAgkBDEludGVnZXJFbnRyeQICF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50CQBkAgkBDXRyeUdldEludGVnZXIBAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAUPUElzc3VlZFdpdGhNdWx0BQNuaWwFD1BJc3N1ZWRXaXRoTXVsdAFpAQtyZWRlZW1JbmRleAEMc2VuZFRvT3JpZ2luBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIIBQNwbXQHYXNzZXRJZAkBDHRyeUdldEJpbmFyeQECE2dsb2JhbF9wb29sVG9rZW5faWQJAAIBAh5wbGVhc2UgYXR0YWNoIHBvb2wgc2hhcmUgdG9rZW4DCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wBBFQUmVkZWVtZWRXaXRoTXVsdAgFA3BtdAZhbW91bnQEE1BSZWRlZW1lZFdpdGhOb011bHQJAG4EBRFQUmVkZWVtZWRXaXRoTXVsdAkBCGdldEtNdWx0AAUHU2NhbGUxNgUERE9XTgQGcmVzdWx0CQEWaGFuZGxlUG9vbFRva2Vuc1JlZGVlbQIFE1BSZWRlZW1lZFdpdGhOb011bHQDBQxzZW5kVG9PcmlnaW4IBQFpDG9yaWdpbkNhbGxlcggFAWkGY2FsbGVyCQDOCAIFBnJlc3VsdAkAzAgCCQEEQnVybgIJAQx0cnlHZXRCaW5hcnkBAhNnbG9iYWxfcG9vbFRva2VuX2lkBRFQUmVkZWVtZWRXaXRoTXVsdAkAzAgCCQEMSW50ZWdlckVudHJ5AgIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQJAGUCCQENdHJ5R2V0SW50ZWdlcgECF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50BRFQUmVkZWVtZWRXaXRoTXVsdAUDbmlsAWkBCnN0YWtlSW5kZXgABAphZGRyZXNzU3RyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQJAQx0cnlHZXRCaW5hcnkBAhNnbG9iYWxfcG9vbFRva2VuX2lkCQACAQIUd3JvbmcgYXNzZXQgYXR0YWNoZWQJARBpbmRleFN0YWtlUmVzdWx0AgUKYWRkcmVzc1N0cggFA3BtdAZhbW91bnQBaQENc3Rha2VJbmRleEZvcgEKYWRkcmVzc1N0cgQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQJAQx0cnlHZXRCaW5hcnkBAhNnbG9iYWxfcG9vbFRva2VuX2lkCQACAQIUd3JvbmcgYXNzZXQgYXR0YWNoZWQJARBpbmRleFN0YWtlUmVzdWx0AgUKYWRkcmVzc1N0cggFA3BtdAZhbW91bnQBaQEMdW5zdGFrZUluZGV4AQtpbmRleEFtb3VudAQKYWRkcmVzc1N0cgMJAQIhPQIJALMJAgUPbGF5ZXIyQWRkcmVzc2VzCQClCAEIBQFpBmNhbGxlcgUEdW5pdAkApQgBCAUBaQxvcmlnaW5DYWxsZXIJAKUIAQgFAWkGY2FsbGVyBA5pbmRleEF2YWlsYWJsZQkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3ADCQBmAgULaW5kZXhBbW91bnQFDmluZGV4QXZhaWxhYmxlCQACAQIleW91IGRvbid0IGhhdmUgaW5kZXggdG9rZW5zIGF2YWlsYWJsZQMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AJAM4IAggJAQtjbGFpbVJlc3VsdAEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCmFkZHJlc3NTdHICXzEJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgIMX2luZGV4U3Rha2VkCQBlAgUOaW5kZXhBdmFpbGFibGUFC2luZGV4QW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQJAGUCCQENdHJ5R2V0SW50ZWdlcgECEmdsb2JhbF9pbmRleFN0YWtlZAULaW5kZXhBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQtpbmRleEFtb3VudAkBEUBleHRyTmF0aXZlKDEwNTcpAQITZ2xvYmFsX3Bvb2xUb2tlbl9pZAUDbmlsAWkBEWNsYWltSW5kZXhSZXdhcmRzAAMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AJAQtjbGFpbVJlc3VsdAEIBQFpBmNhbGxlcgFpAQ1ldmFsdWF0ZUNsYWltAQR1c2VyCQCUCgIFA25pbAgJAQtjbGFpbVJlc3VsdAEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBHVzZXICXzIBaQEEc3dhcAIIYXNzZXRPdXQHbWluaW11bQQDcG10AwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAACQACAQIhcGxlYXNlIGF0dGFjaCBleGFjdGx5IG9uZSBwYXltZW50BAhBbW91bnRJbgkBBXZhbHVlAQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEB0Fzc2V0SW4IBQNwbXQHYXNzZXRJZAQIQXNzZXRPdXQJAQ1nZXRBc3NldEJ5dGVzAQUIYXNzZXRPdXQEB2Fzc2V0SW4JAQ5nZXRBc3NldFN0cmluZwEFB0Fzc2V0SW4EB3NjYWxlSW4JAGkCBQZTY2FsZTgJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FB2Fzc2V0SW4CBl9zY2FsZQQIc2NhbGVPdXQJAGkCBQZTY2FsZTgJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCGFzc2V0T3V0AgZfc2NhbGUEDmZlZUFzc2V0T3V0U3RyCQEMdHJ5R2V0U3RyaW5nAQIPc3RhdGljX2ZlZVRva2VuBAtmZWVBc3NldE91dAMJAAACBQ5mZWVBc3NldE91dFN0cgIABQt1c2RuQXNzZXRJZAkBDWdldEFzc2V0Qnl0ZXMBBQ5mZWVBc3NldE91dFN0cgQOQXNzZXRJbkJhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFB0Fzc2V0SW4CCF9iYWxhbmNlBA9Bc3NldE91dEJhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8FCGFzc2V0T3V0AghfYmFsYW5jZQQUQXNzZXRJbkJhbGFuY2VTY2FsZWQJAGgCBQ5Bc3NldEluQmFsYW5jZQUHc2NhbGVJbgQVQXNzZXRPdXRCYWxhbmNlU2NhbGVkCQBoAgUPQXNzZXRPdXRCYWxhbmNlBQhzY2FsZU91dAQLZmVlQW1vdW50SW4JAGsDBQhBbW91bnRJbgUDRmVlBQhGZWVTY2FsZQQNY2xlYW5BbW91bnRJbgkAZQIFCEFtb3VudEluBQtmZWVBbW91bnRJbgQTY2xlYW5BbW91bnRJblNjYWxlZAkAaAIFDWNsZWFuQW1vdW50SW4FB3NjYWxlSW4ECkFtb3VudE91dDEJARJjYWxjdWxhdGVPdXRBbW91bnQFBRNjbGVhbkFtb3VudEluU2NhbGVkBQdBc3NldEluBQhBc3NldE91dAUUQXNzZXRJbkJhbGFuY2VTY2FsZWQFFUFzc2V0T3V0QmFsYW5jZVNjYWxlZAQJQW1vdW50T3V0CQBrAwUKQW1vdW50T3V0MQABBQhzY2FsZU91dAQQQXNzZXRPdXRCYWxhbmNlMgkAZQIFD0Fzc2V0T3V0QmFsYW5jZQUJQW1vdW50T3V0BA9Bc3NldEluQmFsYW5jZTIJAGQCBQ5Bc3NldEluQmFsYW5jZQUNY2xlYW5BbW91bnRJbgQSZmVlQXNzZXRPdXRCYWxhbmNlAwkAAAIFC2ZlZUFzc2V0T3V0BQdBc3NldEluBQ9Bc3NldEluQmFsYW5jZTIDCQAAAgULZmVlQXNzZXRPdXQFCEFzc2V0T3V0BRBBc3NldE91dEJhbGFuY2UyCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfCQEOZ2V0QXNzZXRTdHJpbmcBBQtmZWVBc3NldE91dAIIX2JhbGFuY2UEDGZlZUFtb3VudE91dAkBEmNhbGN1bGF0ZU91dEFtb3VudAUFC2ZlZUFtb3VudEluBQdBc3NldEluBQtmZWVBc3NldE91dAUOQXNzZXRJbkJhbGFuY2UFEmZlZUFzc2V0T3V0QmFsYW5jZQMJAGYCBQdtaW5pbXVtBQlBbW91bnRPdXQJAAIBAilhbW91bnQgdG8gcmVjaWV2ZSBpcyBsb3dlciB0aGFuIGdpdmVuIG9uZQMJAAACBQhBc3NldE91dAUHQXNzZXRJbgkAAgECGHRoaXMgc3dhcCBpcyBub3QgYWxsb3dlZAMJAGYCAAAJAGUCBQ9Bc3NldE91dEJhbGFuY2UFCUFtb3VudE91dAkAAgECG2NvbnRyYWN0IGlzIG91dCBvZiByZXNlcnZlcwMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AECmNyZWF0b3JGZWUJAGsDBQxmZWVBbW91bnRPdXQAAQAKBAtwcm90b2NvbEZlZQkAawMFDGZlZUFtb3VudE91dAAEAAoEDG5ld0JhbGFuY2VJbgUPQXNzZXRJbkJhbGFuY2UyBA1uZXdCYWxhbmNlT3V0CQBlAgUQQXNzZXRPdXRCYWxhbmNlMgMJAAACBQhBc3NldE91dAULZmVlQXNzZXRPdXQFDGZlZUFtb3VudE91dAAABBJuZXdCYWxhbmNlRmVlQXNzZXQDAwkBAiE9AgULZmVlQXNzZXRPdXQFB0Fzc2V0SW4JAQIhPQIFC2ZlZUFzc2V0T3V0BQhBc3NldE91dAcJAGUCBRJmZWVBc3NldE91dEJhbGFuY2UFDGZlZUFtb3VudE91dAUEdW5pdAQNYXNzZXRJbkNoYW5nZQkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdnbG9iYWxfCQEOZ2V0QXNzZXRTdHJpbmcBBQdBc3NldEluAghfYmFsYW5jZQUMbmV3QmFsYW5jZUluBA5hc3NldE91dENoYW5nZQkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdnbG9iYWxfBQhhc3NldE91dAIIX2JhbGFuY2UFDW5ld0JhbGFuY2VPdXQEEWZlZUFzc2V0T3V0Q2hhbmdlAwkBAiE9AgUSbmV3QmFsYW5jZUZlZUFzc2V0BQR1bml0CQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFC2ZlZUFzc2V0T3V0AghfYmFsYW5jZQkBBXZhbHVlAQUSbmV3QmFsYW5jZUZlZUFzc2V0CQELU3RyaW5nRW50cnkCAgVoZWxsbwIFd29ybGQEDHZvbHVtZVVwZGF0ZQkBEmNhbGN1bGF0ZVVzZG5WYWx1ZQQFB0Fzc2V0SW4FCEFtb3VudEluBQ5Bc3NldEluQmFsYW5jZQUSZmVlQXNzZXRPdXRCYWxhbmNlBA92b2x1bWVVc2RVcGRhdGUJARFjYWxjdWxhdGVVc2RWYWx1ZQMFB0Fzc2V0SW4FCEFtb3VudEluBQ5Bc3NldEluQmFsYW5jZQkAlAoCCQDMCAIFDmFzc2V0T3V0Q2hhbmdlCQDMCAIFDWFzc2V0SW5DaGFuZ2UJAMwIAgURZmVlQXNzZXRPdXRDaGFuZ2UJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQlBbW91bnRPdXQFCEFzc2V0T3V0CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQx0cnlHZXRTdHJpbmcBAhBzdGF0aWNfcG9vbE93bmVyBQpjcmVhdG9yRmVlBQtmZWVBc3NldE91dAkAzAgCCQEMSW50ZWdlckVudHJ5AgIUZ2xvYmFsX2Vhcm5lZEJ5T3duZXIJAGQCCQENdHJ5R2V0SW50ZWdlcgECFGdsb2JhbF9lYXJuZWRCeU93bmVyBQpjcmVhdG9yRmVlCQDMCAIJAQxJbnRlZ2VyRW50cnkCAg1nbG9iYWxfdm9sdW1lCQBkAgkBDXRyeUdldEludGVnZXIBAg1nbG9iYWxfdm9sdW1lBQx2b2x1bWVVcGRhdGUJAMwIAgkBDEludGVnZXJFbnRyeQICEWdsb2JhbF92b2x1bWVfdXNkCQBkAgkBDXRyeUdldEludGVnZXIBAhFnbG9iYWxfdm9sdW1lX3VzZAUPdm9sdW1lVXNkVXBkYXRlCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFC2ZlZXNBZGRyZXNzBQtwcm90b2NvbEZlZQULZmVlQXNzZXRPdXQFA25pbAUJQW1vdW50T3V0AWkBDHN3YXBSZWFkT25seQMHYXNzZXRJbghhc3NldE91dAhBbW91bnRJbgQHQXNzZXRJbgkBDWdldEFzc2V0Qnl0ZXMBBQdhc3NldEluBAhBc3NldE91dAkBDWdldEFzc2V0Qnl0ZXMBBQhhc3NldE91dAQHc2NhbGVJbgkAaQIFBlNjYWxlOAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUHYXNzZXRJbgIGX3NjYWxlBAhzY2FsZU91dAkAaQIFBlNjYWxlOAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUIYXNzZXRPdXQCBl9zY2FsZQQOZmVlQXNzZXRPdXRTdHIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfZmVlVG9rZW4EC2ZlZUFzc2V0T3V0AwkAAAIFDmZlZUFzc2V0T3V0U3RyAgAFC3VzZG5Bc3NldElkCQENZ2V0QXNzZXRCeXRlcwEFDmZlZUFzc2V0T3V0U3RyBA5Bc3NldEluQmFsYW5jZQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwkBDmdldEFzc2V0U3RyaW5nAQUHQXNzZXRJbgIIX2JhbGFuY2UED0Fzc2V0T3V0QmFsYW5jZQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwUIYXNzZXRPdXQCCF9iYWxhbmNlBBRBc3NldEluQmFsYW5jZVNjYWxlZAkAaAIFDkFzc2V0SW5CYWxhbmNlBQdzY2FsZUluBBVBc3NldE91dEJhbGFuY2VTY2FsZWQJAGgCBQ9Bc3NldE91dEJhbGFuY2UFCHNjYWxlT3V0BAtmZWVBbW91bnRJbgkAawMFCEFtb3VudEluBQNGZWUFCEZlZVNjYWxlBA1jbGVhbkFtb3VudEluCQBlAgUIQW1vdW50SW4FC2ZlZUFtb3VudEluBBNjbGVhbkFtb3VudEluU2NhbGVkCQBoAgUNY2xlYW5BbW91bnRJbgUHc2NhbGVJbgQKQW1vdW50T3V0MQkBEmNhbGN1bGF0ZU91dEFtb3VudAUFE2NsZWFuQW1vdW50SW5TY2FsZWQFB0Fzc2V0SW4FCEFzc2V0T3V0BRRBc3NldEluQmFsYW5jZVNjYWxlZAUVQXNzZXRPdXRCYWxhbmNlU2NhbGVkBAlBbW91bnRPdXQJAGsDBQpBbW91bnRPdXQxAAEFCHNjYWxlT3V0BBBBc3NldE91dEJhbGFuY2UyCQBlAgUPQXNzZXRPdXRCYWxhbmNlBQlBbW91bnRPdXQED0Fzc2V0SW5CYWxhbmNlMgkAZAIFDkFzc2V0SW5CYWxhbmNlBQ1jbGVhbkFtb3VudEluBBJmZWVBc3NldE91dEJhbGFuY2UDCQAAAgULZmVlQXNzZXRPdXQFB0Fzc2V0SW4FD0Fzc2V0SW5CYWxhbmNlMgMJAAACBQtmZWVBc3NldE91dAUIQXNzZXRPdXQFEEFzc2V0T3V0QmFsYW5jZTIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8JAQ5nZXRBc3NldFN0cmluZwEFC2ZlZUFzc2V0T3V0AghfYmFsYW5jZQQMZmVlQW1vdW50T3V0CQESY2FsY3VsYXRlT3V0QW1vdW50BQULZmVlQW1vdW50SW4FB0Fzc2V0SW4FC2ZlZUFzc2V0T3V0BQ5Bc3NldEluQmFsYW5jZQUSZmVlQXNzZXRPdXRCYWxhbmNlAwkAAAIFCEFzc2V0T3V0BQdBc3NldEluCQACAQIYdGhpcyBzd2FwIGlzIG5vdCBhbGxvd2VkAwkAZgIAAAkAZQIFD0Fzc2V0T3V0QmFsYW5jZQUJQW1vdW50T3V0CQACAQIbY29udHJhY3QgaXMgb3V0IG9mIHJlc2VydmVzAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAkAlAoCBQNuaWwFCUFtb3VudE91dAFpARF0cmFuc2Zlck93bmVyc2hpcAEPbmV3T3duZXJBZGRyZXNzAwkBAiE9AgkApQgBCAUBaQZjYWxsZXIJAQx0cnlHZXRTdHJpbmcBAhBzdGF0aWNfcG9vbE93bmVyCQACAQIndGhpcyBjYWxsIGF2YWlsYWJsZSBvbmx5IGZvciBwb29sIG93bmVyCQDMCAIJAQtTdHJpbmdFbnRyeQICEHN0YXRpY19wb29sT3duZXIFD25ld093bmVyQWRkcmVzcwUDbmlsAWkBBnNldEZlZQEGbmV3RmVlAwkBAiE9AgkApQgBCAUBaQZjYWxsZXIJAQx0cnlHZXRTdHJpbmcBAhBzdGF0aWNfcG9vbE93bmVyCQACAQIndGhpcyBjYWxsIGF2YWlsYWJsZSBvbmx5IGZvciBwb29sIG93bmVyAwkAZgIAAQkBC3ZhbHVlT3JFbHNlAgkAmggCBQpnb3ZBZGRyZXNzCQCsAgICC2FwcHJvdmVkVHhfCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQAAAkAAgECM3RoaXMgdHJhbnNhY3Rpb24gbmVlZHMgYXBwcm92YWwgZnJvbSBwdXp6bGUgbmV0d29yawkAzAgCCQEMSW50ZWdlckVudHJ5AgIKc3RhdGljX2ZlZQUGbmV3RmVlBQNuaWwBaQESc2V0UmViYWxhbmNpbmdQbGFuBQthc3NldElkc1N0cg9hc3NldFdlaWdodHNTdHIOYmFzZVRva2VuSWRTdHILc3RlcHNBbW91bnQNc3RlcHNJbnRlcnZhbAMJAQIhPQIIBQFpBmNhbGxlcgkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDHRyeUdldFN0cmluZwECEHN0YXRpY19wb29sT3duZXIJAAIBAid0aGlzIGNhbGwgYXZh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XzECCQEFJGY3XzECCQEFJGY3XzECCQEFJGY3XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEDXZhbGlkUGF5bWVudHMJARB2YWxpZGF0ZVBheW1lbnRzAgULYWRkZWRBc3NldHMIBQFpCHBheW1lbnRzBAx2YWxpZFdlaWdodHMJAQ92YWxpZGF0ZVdlaWdodHMBBRRuZXdBc3NldFdlaWdodHNTdHJMaQMJAAACBQx2YWxpZFdlaWdodHMFDHZhbGlkV2VpZ2h0cwMJAQIhPQIFDXZhbGlkUGF5bWVudHMJAGQCCQCQAwEFC2FkZGVkQXNzZXRzCQCQAwEIBQFpCHBheW1lbnRzCQACAQIxUGF5bWVudHMgbm90IHByZXNlbnQgb3Igc29tZXRoaW5nIHdyb25nIHdpdGggdGhlbQMJAQIhPQIJAJADAQUQbmV3QXNzZXRJZHNTdHJMaQkAkAMBBRRuZXdBc3NldFdlaWdodHNTdHJMaQkAAgECMWFzc2V0SWRzIGFuZCBhc3NldFdlaWdodHMgc2hvdWxkIGhhdmUgc2FtZSBsZW5ndGgDCQECIT0CBQ12YWxpZFBheW1lbnRzCQBkAgkAkAMBBQthZGRlZEFzc2V0cwkAkAMBCAUBaQhwYXltZW50cwkAAgECMVBheW1lbnRzIG5vdCBwcmVzZW50IG9yIHNvbWV0aGluZyB3cm9uZyB3aXRoIHRoZW0DCQAAAgULZmVlQXNzZXRTdHICAAkAAgECQXBvb2wgbXVzdCBoYXZlIG9uZSBvZiB0aGUgc3VwcG9ydGVkIGZlZSBhc3NldHMgaW4gdGhlIGNvbXBvc2l0aW9uAwkAAAIJAM8IAgUQbmV3QXNzZXRJZHNTdHJMaQUOYmFzZVRva2VuSWRTdHIFBHVuaXQJAAIBAiliYXNlVG9rZW5JZCBzaG91bGQgYmUgcHJlc2VudCBpbiBhc3NldElkcwMDCQBmAgUQTUlOX1NURVBTX0FNT1VOVAULc3RlcHNBbW91bnQGCQBmAgULc3RlcHNBbW91bnQFEE1BWF9TVEVQU19BTU9VTlQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIfU3RlcHMgYW1vdW50IHNob3VsZCBiZSBiZXR3ZWVuIAkApAMBBRBNSU5fU1RFUFNfQU1PVU5UAgUgYW5kIAkApAMBBRBNQVhfU1RFUFNfQU1PVU5UAgssIGN1cnJlbnQ6IAkApAMBBQtzdGVwc0Ftb3VudAMDCQBmAgUSTUlOX1NURVBTX0lOVEVSVkFMBQ1zdGVwc0ludGVydmFsBgkAZgIFDXN0ZXBzSW50ZXJ2YWwFEk1BWF9TVEVQU19JTlRFUlZBTAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAiFTdGVwcyBpbnRlcnZhbCBzaG91bGQgYmUgYmV0d2VlbiAJAKQDAQUSTUlOX1NURVBTX0lOVEVSVkFMAgUgYW5kIAkApAMBBRJNQVhfU1RFUFNfSU5URVJWQUwCCywgY3VycmVudDogCQCkAwEFDXN0ZXBzSW50ZXJ2YWwDCQECIT0CBQ9hc3NldFdlaWdodHNTdW0AkE4JAAIBCQCsAgICNnN1bSBvZiB0b2tlbiB3ZWlnaHRzIG11c3QgYmUgZXF1YWwgdG8gMTAwMDAsIGN1cnJlbnQ6IAkApAMBBQ9hc3NldFdlaWdodHNTdW0KAQFmAgVhY2N1bQphc3NldElkU3RyBAlvbGRXZWlnaHQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICB193ZWlnaHQECW5ld1dlaWdodAMJAAACCQDPCAIFEG5ld0Fzc2V0SWRzU3RyTGkFCmFzc2V0SWRTdHIFBHVuaXQAAAkBDXBhcnNlSW50VmFsdWUBCQEFdmFsdWUBCQCRAwIFFG5ld0Fzc2V0V2VpZ2h0c1N0ckxpCQEFdmFsdWUBCQDPCAIFEG5ld0Fzc2V0SWRzU3RyTGkFCmFzc2V0SWRTdHIEDGRlbHRhUGVyU3RlcAkAawMJAGUCBQluZXdXZWlnaHQFCW9sZFdlaWdodACQTgULc3RlcHNBbW91bnQJAM4IAgUFYWNjdW0JAMwIAgkApAMBBQxkZWx0YVBlclN0ZXAFA25pbAQNdG1wQXNzZXRJZHNMaQkBEmdldFRtcFJlYmFsYW5jZUlkcwEFEG5ld0Fzc2V0SWRzU3RyTGkEC2Fzc2V0RGVsdGFzCgACJGwFDXRtcEFzc2V0SWRzTGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjhfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjhfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY4XzICCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEDm5ld1Rva2Vuc0FkZGVkCQBmAgkBEWNoZWNrVG9rZW5zQ2hhbmdlAQUQbmV3QXNzZXRJZHNTdHJMaQAACgEScmVjb3JkQXNzZXRQYXltZW50AgVhY2N1bQRuZXh0CQDOCAIFBWFjY3VtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICGnJlYmFsYW5jZV9hdHRhY2hlZFBheW1lbnRfCQEOZ2V0QXNzZXRTdHJpbmcBCAUEbmV4dAdhc3NldElkCAUEbmV4dAZhbW91bnQFA25pbAQOcGF5bWVudEVudHJpZXMKAAIkbAgFAWkIcGF5bWVudHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjlfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEnJlY29yZEFzc2V0UGF5bWVudAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmOV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjlfMgIJAQUkZjlfMQIJAQUkZjlfMQIJAQUkZjlfMQIJAQUkZjlfMQIJAQUkZjlfMQIJAQUkZjlfMQIJAQUkZjlfMQIJAQUkZjlfMQIJAQUkZjlfMQIJAQUkZjlfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQMc3RvcmVXZWlnaHRzCQESc2F2ZUN1cnJlbnRXZWlnaHRzAAQMbm90aWZ5SW52b2tlCQD8BwQFD3Bvb2xzSHViQWRkcmVzcwIQbm90aWZ5UG9vbENoYW5nZQUDbmlsBQNuaWwDCQAAAgUMbm90aWZ5SW52b2tlBQxub3RpZnlJbnZva2UJAM4IAgkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQICFXJlYmFsYW5jZV9hZGRlZEFzc2V0cwkAuQkCBQthZGRlZEFzc2V0cwIBLAkAzAgCCQELU3RyaW5nRW50cnkCAhdyZWJhbGFuY2VfcmVtb3ZlZEFzc2V0cwkAuQkCBQ1yZW1vdmVkQXNzZXRzAgEsCQDMCAIJAQtTdHJpbmdFbnRyeQICFXRtcF9yZWJhbGFuY2VBc3NldElkcwkAuQkCBQ10bXBBc3NldElkc0xpAgEsCQDMCAIJAQxCb29sZWFuRW50cnkCAhRyZWJhbGFuY2VfaW5Qcm9ncmVzcwYJAMwIAgkBDEJvb2xlYW5FbnRyeQICGHJlYmFsYW5jZV9uZXdUb2tlbnNBZGRlZAUObmV3VG9rZW5zQWRkZWQJAMwIAgkBDEludGVnZXJFbnRyeQICE3JlYmFsYW5jZV9zdGVwc0RvbmUAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgIYcmViYWxhbmNlX2xhc3RTdGVwSGVpZ2h0BQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQICFXJlYmFsYW5jZV9zdGVwc0Ftb3VudAULc3RlcHNBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQICF3JlYmFsYW5jZV9zdGVwc0ludGVydmFsBQ1zdGVwc0ludGVydmFsCQDMCAIJAQtTdHJpbmdFbnRyeQICEnJlYmFsYW5jZV9hc3NldElkcwULYXNzZXRJZHNTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgIYcmViYWxhbmNlX25ld0Jhc2VUb2tlbklkBQ5iYXNlVG9rZW5JZFN0cgkAzAgCCQELU3RyaW5nRW50cnkCAhVyZWJhbGFuY2VfYXNzZXREZWx0YXMJALkJAgULYXNzZXREZWx0YXMCASwFA25pbAUOcGF5bWVudEVudHJpZXMFDHN0b3JlV2VpZ2h0cwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ9zdGVwUmViYWxhbmNpbmcAAwkBASEBCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMCFHJlYmFsYW5jZV9pblByb2dyZXNzBwkAAgECGm5vIHJlYmFsYW5jaW5nIGluIHByb2dyZXNzBA5sYXN0U3RlcEhlaWdodAkBEUBleHRyTmF0aXZlKDEwNTUpAQIYcmViYWxhbmNlX2xhc3RTdGVwSGVpZ2h0BAxzdGVwSW50ZXJ2YWwJARFAZXh0ck5hdGl2ZSgxMDU1KQECF3JlYmFsYW5jZV9zdGVwc0ludGVydmFsBAlzdGVwc0RvbmUJARFAZXh0ck5hdGl2ZSgxMDU1KQECE3JlYmFsYW5jZV9zdGVwc0RvbmUEDm5leHRTdGVwSGVpZ2h0CQBkAgUObGFzdFN0ZXBIZWlnaHQFDHN0ZXBJbnRlcnZhbAMJAGYCBQ5uZXh0U3RlcEhlaWdodAUGaGVpZ2h0CQACAQIRY2FuJ3QgYmUgZG9uZSB5ZXQEC2Fzc2V0RGVsdGFzCQC1CQIJARFAZXh0ck5hdGl2ZSgxMDU4KQECFXJlYmFsYW5jZV9hc3NldERlbHRhcwIBLAQObmV3QXNzZXRJZHNTdHIJARFAZXh0ck5hdGl2ZSgxMDU4KQECFXRtcF9yZWJhbGFuY2VBc3NldElkcwQLbmV3QXNzZXRJZHMJALUJAgUObmV3QXNzZXRJZHNTdHICASwKAQFmAgVhY2N1bQphc3NldElkU3RyCQDOCAIFBWFjY3VtCQDMCAIJAKQDAQkAbgQJAGQCCQBoAgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQCsAgICFnJlYmFsYW5jZV9zdGFydFdlaWdodF8FCmFzc2V0SWRTdHIAAACQTgkAaAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQthc3NldERlbHRhcwkBBXZhbHVlAQkAzwgCBQtuZXdBc3NldElkcwUKYXNzZXRJZFN0cgkAZAIFCXN0ZXBzRG9uZQABAAEAkE4FBkhBTEZVUAUDbmlsBAluZXdTaGFyZXMJALkJAgoAAiRsBQtuZXdBc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEBZgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgIBLAQObmV3VG9rZW5zQWRkZWQJARFAZXh0ck5hdGl2ZSgxMDU2KQECGHJlYmFsYW5jZV9uZXdUb2tlbnNBZGRlZAQDaW52AwMFDm5ld1Rva2Vuc0FkZGVkCQAAAgUJc3RlcHNEb25lAAAHCQD8BwQFBHRoaXMCGmRvUmViYWxhbmNpbmdXaXRoTmV3VG9rZW5zCQDMCAIFDm5ld0Fzc2V0SWRzU3RyCQDMCAIFCW5ld1NoYXJlcwkAzAgCCQERQGV4dHJOYXRpdmUoMTA1OCkBAhhyZWJhbGFuY2VfbmV3QmFzZVRva2VuSWQFA25pbAUDbmlsCQD8BwQFBHRoaXMCDWRvUmViYWxhbmNpbmcJAMwIAgUJbmV3U2hhcmVzBQNuaWwFA25pbAMJAAACBQNpbnYFA2ludgQMbm90aWZ5SW52b2tlCQD8BwQFD3Bvb2xzSHViQWRkcmVzcwIQbm90aWZ5UG9vbENoYW5nZQUDbmlsBQNuaWwDCQAAAgUMbm90aWZ5SW52b2tlBQxub3RpZnlJbnZva2UECmlzRmluaXNoZWQJAGcCCQBkAgUJc3RlcHNEb25lAAEJARFAZXh0ck5hdGl2ZSgxMDU1KQECFXJlYmFsYW5jZV9zdGVwc0Ftb3VudAQHYWN0aW9ucwkAzAgCCQEMQm9vbGVhbkVudHJ5AgIUcmViYWxhbmNlX2luUHJvZ3Jlc3MJAQEhAQUKaXNGaW5pc2hlZAkAzAgCCQEMSW50ZWdlckVudHJ5AgITcmViYWxhbmNlX3N0ZXBzRG9uZQkAZAIFCXN0ZXBzRG9uZQABCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhhyZWJhbGFuY2VfbGFzdFN0ZXBIZWlnaHQFBmhlaWdodAUDbmlsAwkAAAIFCXN0ZXBzRG9uZQAACQDOCAIFB2FjdGlvbnMJAMwIAgkBC1N0cmluZ0VudHJ5AgIPc3RhdGljX3Rva2VuSWRzBQ5uZXdBc3NldElkc1N0cgUDbmlsAwUKaXNGaW5pc2hlZAQPcmVtb3ZlZEFzc2V0c0xpCQC1CQIJAQx0cnlHZXRTdHJpbmcBAhdyZWJhbGFuY2VfcmVtb3ZlZEFzc2V0cwIBLAoBBnJtRGF0YQIFYWNjdW0HYXNzZXRJZAkAzggCBQVhY2N1bQkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgIHc3RhdGljXwUHYXNzZXRJZAIGX3NjYWxlCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgkArAICAgdzdGF0aWNfBQdhc3NldElkAglfZGVjaW1hbHMJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgICB3N0YXRpY18FB2Fzc2V0SWQCB193ZWlnaHQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgICB2dsb2JhbF8FB2Fzc2V0SWQCCF9iYWxhbmNlCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgIacmViYWxhbmNlX2F0dGFjaGVkUGF5bWVudF8FB2Fzc2V0SWQFA25pbAQCcm0KAAIkbAUPcmVtb3ZlZEFzc2V0c0xpCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY1XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQZybURhdGECBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjVfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY1XzICCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEDWFkZGVkQXNzZXRzTGkJALUJAgkBDHRyeUdldFN0cmluZwECFXJlYmFsYW5jZV9hZGRlZEFzc2V0cwIBLAoBEWFkZFJlbW92ZVBheW1lbnRzAgVhY2N1bQdhc3NldElkCQDOCAIFBWFjY3VtCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgIacmViYWxhbmNlX2F0dGFjaGVkUGF5bWVudF8FB2Fzc2V0SWQFA25pbAQKcm1QYXltZW50cwoAAiRsBQ1hZGRlZEFzc2V0c0xpCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEF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CQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEDWFzc2V0SWRzU3RyTGkJALUJAgkBDHRyeUdldFN0cmluZwECD3N0YXRpY190b2tlbklkcwIBLAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECInRoaXMgY2FsbCBhdmFpbGFibGUgb25seSBmb3IgYWRtaW4ECG9sZEtNdWx0CQEIZ2V0S011bHQACgEHaGFuZGxlcgIEcGFycwdhc3NldElkBAVhY2N1bQgFBHBhcnMCXzEECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFB2Fzc2V0SWQKAQhoYW5kbGVyMgIFYWNjdW0BbgMJAAACBQFuBQdhc3NldElkCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzBQFuBQVhY2N1bQQFVG9rZW4KAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAEKAQUkZjVfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGhhbmRsZXIyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY1XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNV8yAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBAdiYWxhbmNlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfBQphc3NldElkU3RyAghfYmFsYW5jZQQGd2VpZ2h0AwkAAAIIBQRwYXJzAl8yAgNuZXcJAQ1wYXJzZUludFZhbHVlAQkAkQMCBRFhc3NldFdlaWdodHNTdHJMaQUFVG9rZW4JAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICB193ZWlnaHQJAJQKAgkAawMFBWFjY3VtCQBsBgUHYmFsYW5jZQkAkQMCBQhEZWNpbWFscwUFVG9rZW4FBndlaWdodAUVQXNzZXRzV2VpZ2h0c0Rl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BSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQkArAICAiR0aGlzIGNhbGwgYXZhaWxhYmxlIG9ubHkgZm9yIGFkbWluLCAJAKUIAQgFAWkGY2FsbGVyBAhvbGRLTXVsdAkBCGdldEtNdWx0AAQEb2xkSwkBGWdldFZpcnR1YWxQb29sVG9rZW5BbW91bnQACgESbXlsdGlwbHlBc3NldHNGb3JLAgRwYXJzB2Fzc2V0SWQKAQxmaW5kQXNzZXROdW0CBWFjY3VtAW4DCQAAAgUBbgUHYXNzZXRJZAkBBXZhbHVlAQkAzwgCBQtuZXdBc3NldElkcwUBbgUFYWNjdW0ECGN1cnJlbnRLBQRwYXJzBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBBQdhc3NldElkBAhUb2tlbk51bQoAAiRsBQtuZXdBc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAQoBBSRmN18xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEMZmluZEFzc2V0TnVtAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY3XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmN18yAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgkBBSRmN18xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBAZ3ZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBRRuZXdBc3NldFdlaWdodHNTdHJMaQUIVG9rZW5OdW0EDmJhbGFuY2VJblN0YXRlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfBQphc3NldElkU3RyAghfYmFsYW5jZQQQYmFsYW5jZUluUGF5bWVudAkAkQMCBRBhdHRhY2hlZEJhbGFuY2VzBQhUb2tlbk51bQQHYmFsYW5jZQkAZAIFDmJhbGFuY2VJblN0YXRlBRBiYWxhbmNlSW5QYXltZW50BA1hc3NldERlY2ltYWxzAwkAAAIFB2Fzc2V0SWQFBHVuaXQACAgJAQV2YWx1ZQEJAOwHAQkBBXZhbHVlAQUHYXNzZXRJZAhkZWNpbWFscwMJAGcCAAAFB2JhbGFuY2UJAAIBCQCsAgICRHlvdSBuZWVkIHRvIGF0dGFjaCBhbGwgbmV3IGFzc2V0cyBpbiBwYXltZW50LiB0aGlzIGFzc2V0IGlzIG1pc3NlZDogBQphc3NldElkU3RyCQBrAwUIY3VycmVudEsJAGwGBQdiYWxhbmNlBQ1hc3NldERlY2ltYWxzBQZ3ZWlnaHQFFUFzc2V0c1dlaWdodHNEZWNpbWFscwAIBQVGTE9PUgUGU2NhbGU4BARuZXdLCgACJGwFC25ld0Fzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUOUG9vbFRva2VuU2NhbGUKAQUkZjdfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEm15bHRpcGx5QXNzZXRzRm9ySwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmN18yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjdfMgIJAQUkZjdfMQIJAQUkZjdfMQIJAQUkZjdfMQIJAQUkZjdfMQIJAQUkZjdfMQIJAQUkZjdfMQIJAQUkZjdfMQIJAQUkZjdfMQIJAQUkZjdfMQIJAQUkZjdfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQIbmV3S011bHQJAGsDBQhvbGRLTXVsdAUEbmV3SwUEb2xkSwoBE2FkZFRva2VuRGF0YUVudHJpZXMCBWFjY3VtCGFzc2V0TnVtBAphc3NldElkU3RyCQCRAwIFEG5ld0Fzc2V0SWRzU3RyTGkFCGFzc2V0TnVtBAdhc3NldElkCQCRAwIFC25ld0Fzc2V0SWRzBQhhc3NldE51bQQNYXNzZXREZWNpbWFscwMJAAACBQdhc3NldElkBQR1bml0AAgICQEFdmFsdWUBCQDsBwEJAQV2YWx1ZQEFB2Fzc2V0SWQIZGVjaW1hbHMEDG5ld0Fzc2V0RGF0YQMJAQIhPQIJAM8IAgULYWRkZWRBc3NldHMFCmFzc2V0SWRTdHIFBHVuaXQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdnbG9iYWxfBQphc3NldElkU3RyAghfYmFsYW5jZQkAkQMCBRBhdHRhY2hlZEJhbGFuY2VzBQhhc3NldE51bQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICBl9zY2FsZQkAbAYACgAABQ1hc3NldERlY2ltYWxzAAAAAAUERE9XTgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICCV9kZWNpbWFscwUNYXNzZXREZWNpbWFscwUDbmlsBQNuaWwDCQBnAgUIYXNzZXROdW0JAJADAQUUbmV3QXNzZXRXZWlnaHRzU3RyTGkFBWFjY3VtCQDOCAIJAM4IAgUFYWNjdW0JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdzdGF0aWNfBQphc3NldElkU3RyAgdfd2VpZ2h0CQEFdmFsdWUBCQC2CQEJAJEDAgUUbmV3QXNzZXRXZWlnaHRzU3RyTGkFCGFzc2V0TnVtBQNuaWwFDG5ld0Fzc2V0RGF0YQkAzggCCgACJGwJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUJAMwIAgAGCQDMCAIABwkAzAgCAAgJAMwIAgAJBQNuaWwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjhfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBE2FkZFRva2VuRGF0YUVudHJpZXMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjhfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY4XzICCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECCQEFJGY4XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoJAMwIAgkBC1N0cmluZ0VudHJ5AgIPc3RhdGljX3Rva2VuSWRzBQthc3NldElkc1N0cgkAzAgCCQELU3RyaW5nRW50cnkCAg9zdGF0aWNfZmVlVG9rZW4FC2ZlZUFzc2V0U3RyCQDMCAIJAQtTdHJpbmdFbnRyeQICE3N0YXRpY190b2tlbldlaWdodHMFD2Fzc2V0V2VpZ2h0c1N0cgkAzAgCCQEMSW50ZWdlckVudHJ5AgITc3RhdGljX3Rva2Vuc0Ftb3VudAkAkAMBBQtuZXdBc3NldElkcwkAzAgCCQEMSW50ZWdlckVudHJ5AgIMc3RhdGljX0tNdWx0BQhuZXdLTXVsdAUDbmlsAQJ0eAEGdmVyaWZ5AAQHJG1hdGNoMAUCdHgDCQABAgUHJG1hdGNoMAIUU2V0U2NyaXB0VHJhbnNhY3Rpb24EAnR4BQckbWF0Y2gwBApzY3JpcHRGdWxsCQEFdmFsdWUBCAUCdHgGc2NyaXB0BARoYXNoCQDYBAEJAPcDAQUKc2NyaXB0RnVsbAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFDG1hc3RlclB1YktleQkAZgIJAQt2YWx1ZU9yRWxzZQIJAJoIAgURY29sZE1hc3RlckFkZHJlc3MJAKwCAgIPYXBwcm92ZWRTY3JpcHRfBQRoYXNoAAAFBmhlaWdodAcDCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQxtYXN0ZXJQdWJLZXkJAGYCCQELdmFsdWVPckVsc2UCCQCaCAIFEWNvbGRNYXN0ZXJBZGRyZXNzCQCsAgICC2FwcHJvdmVkVHhfCQDYBAEIBQJ0eAJpZAAAAAAHUXeTbg==", "height": 4093794, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 6 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let VERSION = "PZ-1.2.0 PROD"
5+
6+let configStr = valueOrElse(getString(this, "configAddress"), "3PPEBRg4s2af2rQ2ZbLvdu1Hfd4Vo6QVDTo")
7+
8+let CONFIG_ADDRESS = if ((configStr == ""))
9+ then this
10+ else Address(fromBase58String(configStr))
11+
12+let AssetsWeightsDecimals = 4
13+
14+let Scale = 10000
15+
16+let Scale8 = 100000000
17+
18+let Scale16 = 10000000000000000
19+
20+let FeeScale = 10000
21+
22+let PoolTokenDecimals = 8
23+
24+let PoolTokenScale = pow(10, 0, PoolTokenDecimals, 0, 0, HALFUP)
25+
26+let MIN_STEPS_AMOUNT = valueOrElse(getInteger(CONFIG_ADDRESS, "min_steps_amount"), 1)
27+
28+let MAX_STEPS_AMOUNT = valueOrElse(getInteger(CONFIG_ADDRESS, "max_steps_amount"), 500)
29+
30+let MIN_STEPS_INTERVAL = valueOrElse(getInteger(CONFIG_ADDRESS, "min_steps_interval"), 1)
31+
32+let MAX_STEPS_INTERVAL = valueOrElse(getInteger(CONFIG_ADDRESS, "max_steps_interval"), 10000)
33+
34+let MIN_WEIGHT = valueOrElse(getInteger(CONFIG_ADDRESS, "min_weight"), 100)
35+
36+let MAX_WEIGHT = valueOrElse(getInteger(CONFIG_ADDRESS, "max_weight"), 9900)
37+
38+func tryGetInteger (key) = match getInteger(this, key) {
39+ case b: Int =>
40+ b
41+ case _ =>
42+ 0
43+}
44+
45+
46+func tryGetBinary (key) = match getBinary(this, key) {
47+ case b: ByteVector =>
48+ b
49+ case _ =>
50+ base58''
51+}
52+
53+
54+func tryGetString (key) = match getString(this, key) {
55+ case b: String =>
56+ b
57+ case _ =>
58+ ""
59+}
60+
61+
62+func tryGetStringOrThrow (key) = match getString(this, key) {
63+ case b: String =>
64+ b
65+ case _ =>
66+ throw(("no such key in data storage: " + key))
67+}
68+
69+
70+func getAssetString (assetId) = match assetId {
71+ case b: ByteVector =>
72+ toBase58String(b)
73+ case _ =>
74+ "WAVES"
75+}
76+
77+
78+func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
79+ then unit
80+ else fromBase58String(assetIdStr)
81+
82+
83+func getTokenBalance (assetId) = match assetId {
84+ case t: ByteVector =>
85+ assetBalance(this, t)
86+ case _ =>
87+ wavesBalance(this).available
88+}
89+
90+
91+func addAssetBytesToList (accum,item) = (accum ++ [getAssetBytes(item)])
92+
93+
94+func addAssetWeightToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_weight"))])
95+
96+
97+func addAssetWeightToStrList (accum,item) = (accum ++ [toString(tryGetInteger((("static_" + item) + "_weight")))])
98+
99+
100+func addAssetDecimalsToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_decimals"))])
101+
102+
103+func addAssetScaleToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_scale"))])
104+
105+
106+func addIntToList (accum,item) = (accum ++ [parseIntValue(item)])
107+
108+
109+let usdnAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdnAssetIdStr"), "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
110+
111+let puzzleAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "puzzleAssetIdStr"), "HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS")
112+
113+let usdtAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdtAssetIdStr"), "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ")
114+
115+let usdtPptAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdtPptAssetIdStr"), "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi")
116+
117+let romeAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "romeAssetIdStr"), "AP4Cb5xLYGH6ZigHreCZHoXpQTWDkPsG2BHqfDUx6taJ")
118+
119+let wavesAssetIdStr = "WAVES"
120+
121+let usdnAssetId = fromBase58String(usdnAssetIdStr)
122+
123+let puzzleAssetId = fromBase58String(puzzleAssetIdStr)
124+
125+let usdtAssetId = fromBase58String(usdtAssetIdStr)
126+
127+let usdtPptAssetId = fromBase58String(usdtPptAssetIdStr)
128+
129+let romeAssetId = fromBase58String(romeAssetIdStr)
130+
131+let wavesAssetId = unit
132+
133+let supportedFeeAssetsStr = [usdnAssetIdStr, puzzleAssetIdStr, usdtAssetIdStr, usdtPptAssetIdStr, wavesAssetIdStr, romeAssetIdStr]
134+
135+let parentPoolAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "parentPoolAddress"), "3PFDgzu1UtswAkCMxqqQjbTeHaX4cMab8Kh")))
136+
137+let masterAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "masterAddress"), "3PLjwHcz9NEuaTo63NZR9B9okQiKQxZSbmf")))
138+
139+let masterPubKey = fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "masterPubKey"), "4z8CKSYQBKkzx7PBb5uBP1YPa6YAHRNTApW1sQVHT5eU"))
140+
141+let oracleAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "oracleAddress"), "3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t")))
142+
143+let stakingAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "stakingAddress"), "3PFTbywqxtFfukX3HyT881g4iW5K4QL3FAS")))
144+
145+let feesAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "feesAddress"), "3PFWAVKmXjfHXyzJb12jCbhP4Uhi9t4uWiD")))
146+
147+let poolsHubAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "poolsHubAddress"), "3P5YutjDNC3hABBVsveFuZTTbQ5PdtSDBgk")))
148+
149+let shutdownAddressStr = valueOrElse(getString(CONFIG_ADDRESS, "shutdownAddress"), "3PEpv9hRFWEEBU22WRnLsw1bH4YGtcU728o")
150+
151+let layer2Addresses = valueOrElse(getString(CONFIG_ADDRESS, "layer2Addresses"), "3PR1Qvi9mHT35SwWEkLSqqE2L8thiPLdVWU,3PQoBfUKHkJAeGWhooLP7WS8ovb54av9Jp2")
152+
153+let govAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "govAddress"), "3P6uro9xCsE8te78QZjzqy7aq8natSzdceC")))
154+
155+let coldMasterAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "coldMasterAddress"), "3PK9nhPfPbMBygB9ZgHVMHaQbSoojwrBfxj")))
156+
157+let T = tryGetInteger("static_tokensAmount")
158+
159+let assetIds = {
160+ let $l = split(tryGetString("static_tokenIds"), ",")
161+ let $s = size($l)
162+ let $acc0 = nil
163+ func $f0_1 ($a,$i) = if (($i >= $s))
164+ then $a
165+ else addAssetBytesToList($a, $l[$i])
166+
167+ func $f0_2 ($a,$i) = if (($i >= $s))
168+ then $a
169+ else throw("List size exceeds 10")
170+
171+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
172+ }
173+
174+let AssetsWeights = {
175+ let $l = assetIds
176+ let $s = size($l)
177+ let $acc0 = nil
178+ func $f1_1 ($a,$i) = if (($i >= $s))
179+ then $a
180+ else addAssetWeightToList($a, $l[$i])
181+
182+ func $f1_2 ($a,$i) = if (($i >= $s))
183+ then $a
184+ else throw("List size exceeds 10")
185+
186+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
187+ }
188+
189+let Decimals = {
190+ let $l = assetIds
191+ let $s = size($l)
192+ let $acc0 = nil
193+ func $f2_1 ($a,$i) = if (($i >= $s))
194+ then $a
195+ else addAssetDecimalsToList($a, $l[$i])
196+
197+ func $f2_2 ($a,$i) = if (($i >= $s))
198+ then $a
199+ else throw("List size exceeds 10")
200+
201+ $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
202+ }
203+
204+let Scales = {
205+ let $l = assetIds
206+ let $s = size($l)
207+ let $acc0 = nil
208+ func $f3_1 ($a,$i) = if (($i >= $s))
209+ then $a
210+ else addAssetScaleToList($a, $l[$i])
211+
212+ func $f3_2 ($a,$i) = if (($i >= $s))
213+ then $a
214+ else throw("List size exceeds 10")
215+
216+ $f3_2($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
217+ }
218+
219+let Fee = tryGetInteger("static_fee")
220+
221+let earnedAssets = assetIds
222+
223+func isShutdown () = {
224+ let shutdownAddress = addressFromString(shutdownAddressStr)
225+ if ((shutdownAddress == unit))
226+ then false
227+ else match getBoolean(value(shutdownAddress), "is_shutdown") {
228+ case x: Boolean =>
229+ x
230+ case _ =>
231+ false
232+ }
233+ }
234+
235+
236+func getCurrentTokenBalance (tokenNum) = {
237+ let tokenIdStr = getAssetString(assetIds[tokenNum])
238+ tryGetInteger((("global_" + tokenIdStr) + "_balance"))
239+ }
240+
241+
242+func getKMult () = match getInteger("static_KMult") {
243+ case x: Int =>
244+ x
245+ case _ =>
246+ Scale16
247+}
248+
249+
250+func saveCurrentWeights () = {
251+ let assetIdsLi = split(tryGetString("static_tokenIds"), ",")
252+ func s (accum,assetId) = (accum ++ [IntegerEntry(("rebalance_startWeight_" + assetId), tryGetInteger((("static_" + assetId) + "_weight")))])
253+
254+ let $l = assetIdsLi
255+ let $s = size($l)
256+ let $acc0 = nil
257+ func $f4_1 ($a,$i) = if (($i >= $s))
258+ then $a
259+ else s($a, $l[$i])
260+
261+ func $f4_2 ($a,$i) = if (($i >= $s))
262+ then $a
263+ else throw("List size exceeds 10")
264+
265+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
266+ }
267+
268+
269+func getVirtualPoolTokenAmount () = fraction(tryGetInteger("global_poolToken_amount"), getKMult(), Scale16)
270+
271+
272+func calculatePIssued (amount,tokenId) = {
273+ let Psupply = getVirtualPoolTokenAmount()
274+ let Balance = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
275+ let t1 = fraction(amount, Psupply, Balance, DOWN)
276+ t1
277+ }
278+
279+
280+func getMinPIssued (payments) = {
281+ func handler (accum,current) = {
282+ let PIssued = calculatePIssued(current.amount, current.assetId)
283+ if ((PIssued == 0))
284+ then throw("one of the tokens amounts is too low")
285+ else if (if ((accum == 0))
286+ then true
287+ else (accum > PIssued))
288+ then PIssued
289+ else accum
290+ }
291+
292+ let minPIssed = {
293+ let $l = payments
294+ let $s = size($l)
295+ let $acc0 = 0
296+ func $f4_1 ($a,$i) = if (($i >= $s))
297+ then $a
298+ else handler($a, $l[$i])
299+
300+ func $f4_2 ($a,$i) = if (($i >= $s))
301+ then $a
302+ else throw("List size exceeds 10")
303+
304+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
305+ }
306+ minPIssed
307+ }
308+
309+
310+func calculateUsdnValue (assetId,amount,aBalance,givenUsdnBalance) = {
311+ let usdnInPool = indexOf(assetIds, usdnAssetId)
312+ let puzzleInPool = indexOf(assetIds, puzzleAssetId)
313+ let usdtInPool = indexOf(assetIds, usdtAssetId)
314+ let usdtPptInPool = indexOf(assetIds, usdtPptAssetId)
315+ let wavesInPool = indexOf(assetIds, unit)
316+ let assetWeight = tryGetInteger((("static_" + getAssetString(assetId)) + "_weight"))
317+ let feeAssetStr = tryGetString("static_feeToken")
318+ if ((feeAssetStr == puzzleAssetIdStr))
319+ then {
320+ let puzzleWeight = AssetsWeights[value(indexOf(assetIds, puzzleAssetId))]
321+ let puzzleBalance = tryGetInteger((("global_" + puzzleAssetIdStr) + "_balance"))
322+ let amountInPuzzle = fraction(amount, (puzzleBalance / puzzleWeight), (aBalance / assetWeight))
323+ let puzzlePrice = getIntegerValue(parentPoolAddress, "global_lastPuzzlePrice")
324+ fraction((amountInPuzzle * puzzlePrice), 1, Scale8)
325+ }
326+ else if ((feeAssetStr == usdtAssetIdStr))
327+ then {
328+ let usdtWeight = AssetsWeights[value(usdtInPool)]
329+ let usdtBalance = tryGetInteger((("global_" + usdtAssetIdStr) + "_balance"))
330+ fraction(amount, (usdtBalance / usdtWeight), (aBalance / assetWeight))
331+ }
332+ else if ((feeAssetStr == usdtPptAssetIdStr))
333+ then {
334+ let usdtWeight = AssetsWeights[value(usdtPptInPool)]
335+ let usdtBalance = tryGetInteger((("global_" + usdtPptAssetIdStr) + "_balance"))
336+ fraction(amount, (usdtBalance / usdtWeight), (aBalance / assetWeight))
337+ }
338+ else if ((feeAssetStr == usdnAssetIdStr))
339+ then {
340+ let usdnWeight = AssetsWeights[value(indexOf(assetIds, usdnAssetId))]
341+ let usdnBalance = match givenUsdnBalance {
342+ case x: Int =>
343+ givenUsdnBalance
344+ case _ =>
345+ tryGetInteger((("global_" + getAssetString(usdnAssetId)) + "_balance"))
346+ }
347+ fraction(amount, (value(usdnBalance) / usdnWeight), (aBalance / assetWeight))
348+ }
349+ else {
350+ let wavesWeight = 3000
351+ let wBalance = (tryGetInteger("global_WAVES_balance") / 50)
352+ fraction(amount, (wBalance / wavesWeight), (aBalance / assetWeight))
353+ }
354+ }
355+
356+
357+func getPriceFromOracle (assetIdStr) = match getInteger(oracleAddress, (assetIdStr + "_twap5B")) {
358+ case x: Int =>
359+ x
360+ case _ =>
361+ 0
362+}
363+
364+
365+func calculateUsdValue (assetId,amount,aBalance) = {
366+ let assetWeight = tryGetInteger((("static_" + getAssetString(assetId)) + "_weight"))
367+ let feeAssetStr = tryGetString("static_feeToken")
368+ let feeAssetScale = getIntegerValue(this, (("static_" + feeAssetStr) + "_scale"))
369+ let feeAssetNum = value(indexOf(assetIds, getAssetBytes(feeAssetStr)))
370+ let feeAssetWeight = AssetsWeights[feeAssetNum]
371+ let feeAssetBalance = tryGetInteger((("global_" + feeAssetStr) + "_balance"))
372+ let valInFeeAsset = fraction(amount, (feeAssetBalance / feeAssetWeight), (aBalance / assetWeight))
373+ let feeAssetPrice = getPriceFromOracle(feeAssetStr)
374+ fraction(valInFeeAsset, feeAssetPrice, feeAssetScale)
375+ }
376+
377+
378+func checkTokensValidity (payments) = {
379+ func handler1 (accum,payment) = (accum ++ [payment.assetId])
380+
381+ let ids = {
382+ let $l = payments
383+ let $s = size($l)
384+ let $acc0 = nil
385+ func $f4_1 ($a,$i) = if (($i >= $s))
386+ then $a
387+ else handler1($a, $l[$i])
388+
389+ func $f4_2 ($a,$i) = if (($i >= $s))
390+ then $a
391+ else throw("List size exceeds 10")
392+
393+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
394+ }
395+ if ((ids == ids))
396+ then {
397+ func handler2 (accum,assetId) = if ((indexOf(ids, assetId) != unit))
398+ then (accum + 1)
399+ else throw(("asset not attached: " + getAssetString(assetId)))
400+
401+ let checks = {
402+ let $l = assetIds
403+ let $s = size($l)
404+ let $acc0 = 0
405+ func $f5_1 ($a,$i) = if (($i >= $s))
406+ then $a
407+ else handler2($a, $l[$i])
408+
409+ func $f5_2 ($a,$i) = if (($i >= $s))
410+ then $a
411+ else throw("List size exceeds 10")
412+
413+ $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
414+ }
415+ if ((checks == checks))
416+ then true
417+ else throw("Strict value is not equal to itself.")
418+ }
419+ else throw("Strict value is not equal to itself.")
420+ }
421+
422+
423+func handlePoolTokensAdd (PIssued,payments,userAddress,needChange) = {
424+ func getTokenPaymentAmount (tokenId) = {
425+ func handler (accum,payment) = if ((payment.assetId == tokenId))
426+ then payment.amount
427+ else accum
428+
429+ let $l = payments
430+ let $s = size($l)
431+ let $acc0 = 0
432+ func $f4_1 ($a,$i) = if (($i >= $s))
433+ then $a
434+ else handler($a, $l[$i])
435+
436+ func $f4_2 ($a,$i) = if (($i >= $s))
437+ then $a
438+ else throw("List size exceeds 10")
439+
440+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
441+ }
442+
443+ func handleTokenChange (accum,tokenId) = {
444+ let Bk = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
445+ let PSupply = getVirtualPoolTokenAmount()
446+ let tokenDecimals = tryGetInteger((("static_" + getAssetString(tokenId)) + "_scale"))
447+ let a1 = fraction((toBigInt((PSupply + PIssued)) * toBigInt(Scale8)), toBigInt(tokenDecimals), toBigInt(PSupply), CEILING)
448+ let Dk = toInt(fraction((a1 - (toBigInt(tokenDecimals) * toBigInt(Scale8))), toBigInt(Bk), (toBigInt(tokenDecimals) * toBigInt(Scale8)), CEILING))
449+ let paymentAmount = getTokenPaymentAmount(tokenId)
450+ let toReturn = (paymentAmount - Dk)
451+ let t = if (if (needChange)
452+ then (toReturn > 0)
453+ else false)
454+ then [ScriptTransfer(userAddress, toReturn, tokenId)]
455+ else nil
456+ ((accum ++ t) ++ [IntegerEntry((("global_" + getAssetString(tokenId)) + "_balance"), (Bk + Dk))])
457+ }
458+
459+ let $l = assetIds
460+ let $s = size($l)
461+ let $acc0 = nil
462+ func $f4_1 ($a,$i) = if (($i >= $s))
463+ then $a
464+ else handleTokenChange($a, $l[$i])
465+
466+ func $f4_2 ($a,$i) = if (($i >= $s))
467+ then $a
468+ else throw("List size exceeds 10")
469+
470+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
471+ }
472+
473+
474+func handlePoolTokensRedeem (PRedeemed,userAddress) = {
475+ func handleTokenRedeem (accum,tokenId) = {
476+ let Bk = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
477+ let PSupply = getVirtualPoolTokenAmount()
478+ let tokenDecimals = tryGetInteger((("static_" + getAssetString(tokenId)) + "_scale"))
479+ let psuppl = fraction((toBigInt((PSupply - PRedeemed)) * toBigInt(Scale8)), toBigInt(Scale8), toBigInt(PSupply), DOWN)
480+ let amount = toInt(fraction((toBigInt(Scale16) - psuppl), toBigInt(Bk), toBigInt(Scale16), CEILING))
481+ (accum ++ [IntegerEntry((("global_" + getAssetString(tokenId)) + "_balance"), (Bk - amount)), ScriptTransfer(userAddress, amount, tokenId)])
482+ }
483+
484+ let $l = assetIds
485+ let $s = size($l)
486+ let $acc0 = nil
487+ func $f4_1 ($a,$i) = if (($i >= $s))
488+ then $a
489+ else handleTokenRedeem($a, $l[$i])
490+
491+ func $f4_2 ($a,$i) = if (($i >= $s))
492+ then $a
493+ else throw("List size exceeds 10")
494+
495+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
496+ }
497+
498+
499+func calculateOutAmount (AmountIn,assetIn,assetOut,BalanceIn,BalanceOut) = {
500+ let IndexIn = value(indexOf(assetIds, assetIn))
501+ let IndexOut = value(indexOf(assetIds, assetOut))
502+ if ((IndexIn == IndexOut))
503+ then AmountIn
504+ else fraction(BalanceOut, ((Scale8 * Scale8) - toInt(pow(fraction((toBigInt(BalanceIn) * toBigInt(10000)), toBigInt((Scale8 * Scale8)), (toBigInt((BalanceIn + AmountIn)) * toBigInt(10000)), HALFUP), 16, toBigInt(fraction(AssetsWeights[IndexIn], 1000000000000, AssetsWeights[IndexOut])), 12, 16, CEILING))), (Scale8 * Scale8), HALFEVEN)
505+ }
506+
507+
508+func calculateCurrentAssetInterest (assetId,assetIdStr,aBalance,tokenEarningsLastCheck) = {
509+ let totalStaked = tryGetInteger("global_indexStaked")
510+ let tokenBalanceLastCheck = tokenEarningsLastCheck
511+ let currentBalanceDelta = (getTokenBalance(assetId) - aBalance)
512+ let currentTokenEarnings = if ((currentBalanceDelta > tokenBalanceLastCheck))
513+ then currentBalanceDelta
514+ else tokenBalanceLastCheck
515+ let newEarnings = (currentTokenEarnings - tokenBalanceLastCheck)
516+ let newInterest = if ((totalStaked == 0))
517+ then 0
518+ else fraction(newEarnings, Scale8, totalStaked)
519+ let lastCheckInterest = tryGetInteger((("global_lastCheck_" + assetIdStr) + "_interest"))
520+ (lastCheckInterest + newInterest)
521+ }
522+
523+
524+func claimResult (address) = {
525+ let addressStr = toString(address)
526+ let puzzleAmount = tryGetInteger((addressStr + "_indexStaked"))
527+ func handler (accum,assetId) = {
528+ let assetIdStr = getAssetString(assetId)
529+ let aBalance = tryGetInteger((("global_" + getAssetString(assetId)) + "_balance"))
530+ let tokenEarningsLastCheck = tryGetInteger((("global_lastCheck_" + assetIdStr) + "_earnings"))
531+ let currentTokenInterest = calculateCurrentAssetInterest(assetId, assetIdStr, aBalance, tokenEarningsLastCheck)
532+ let currentTokenEarnings = max([tokenEarningsLastCheck, (getTokenBalance(assetId) - aBalance)])
533+ let rewardAmount = fraction(puzzleAmount, (currentTokenInterest - tryGetInteger((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"))), Scale8)
534+ let transfer = if ((rewardAmount == 0))
535+ then nil
536+ else [ScriptTransfer(address, rewardAmount, assetId)]
537+ $Tuple2(((accum._1 ++ transfer) ++ [IntegerEntry((("global_lastCheck_" + assetIdStr) + "_earnings"), (currentTokenEarnings - rewardAmount)), IntegerEntry((("global_lastCheck_" + assetIdStr) + "_interest"), currentTokenInterest), IntegerEntry((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"), currentTokenInterest)]), (accum._2 + calculateUsdValue(assetId, rewardAmount, aBalance)))
538+ }
539+
540+ let accum = {
541+ let $l = earnedAssets
542+ let $s = size($l)
543+ let $acc0 = $Tuple2(nil, 0)
544+ func $f4_1 ($a,$i) = if (($i >= $s))
545+ then $a
546+ else handler($a, $l[$i])
547+
548+ func $f4_2 ($a,$i) = if (($i >= $s))
549+ then $a
550+ else throw("List size exceeds 10")
551+
552+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
553+ }
554+ $Tuple2((accum._1 ++ [IntegerEntry((addressStr + "_claimedRewardUSD"), (tryGetInteger((addressStr + "_claimedRewardUSD")) + accum._2)), IntegerEntry((addressStr + "_lastClaim"), lastBlock.timestamp)]), accum._2)
555+ }
556+
557+
558+func indexStakeResult (addressStr,amount) = {
559+ let li = claimResult(addressFromStringValue(addressStr))._1
560+ (li ++ [IntegerEntry((addressStr + "_indexStaked"), (tryGetInteger((addressStr + "_indexStaked")) + amount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") + amount))])
561+ }
562+
563+
564+func sum (accum,n) = (accum + parseIntValue(n))
565+
566+
567+func checkFeeAsset (accum,next) = if (if ((indexOf(supportedFeeAssetsStr, next) != unit))
568+ then (accum == "")
569+ else false)
570+ then next
571+ else accum
572+
573+
574+func getTmpRebalanceIds (newAssetIdsLi) = {
575+ let currentAssetIdsLi = split(tryGetString("static_tokenIds"), ",")
576+ let result = newAssetIdsLi
577+ func f (accum,assetId) = if ((indexOf(result, assetId) == unit))
578+ then (accum ++ [assetId])
579+ else accum
580+
581+ let $l = currentAssetIdsLi
582+ let $s = size($l)
583+ let $acc0 = result
584+ func $f4_1 ($a,$i) = if (($i >= $s))
585+ then $a
586+ else f($a, $l[$i])
587+
588+ func $f4_2 ($a,$i) = if (($i >= $s))
589+ then $a
590+ else throw("List size exceeds 10")
591+
592+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
593+ }
594+
595+
596+func checkTokensChange (newAssetIdsLi) = {
597+ let currentAssetIdsLi = split(tryGetString("static_tokenIds"), ",")
598+ func rem (accum,assetId) = if ((indexOf(newAssetIdsLi, assetId) == unit))
599+ then (accum + 1)
600+ else accum
601+
602+ func add (accum,assetId) = if ((indexOf(currentAssetIdsLi, assetId) == unit))
603+ then (accum + 1)
604+ else accum
605+
606+ let removed = {
607+ let $l = currentAssetIdsLi
608+ let $s = size($l)
609+ let $acc0 = 0
610+ func $f4_1 ($a,$i) = if (($i >= $s))
611+ then $a
612+ else rem($a, $l[$i])
613+
614+ func $f4_2 ($a,$i) = if (($i >= $s))
615+ then $a
616+ else throw("List size exceeds 10")
617+
618+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
619+ }
620+ let added = {
621+ let $l = newAssetIdsLi
622+ let $s = size($l)
623+ let $acc0 = 0
624+ func $f5_1 ($a,$i) = if (($i >= $s))
625+ then $a
626+ else add($a, $l[$i])
627+
628+ func $f5_2 ($a,$i) = if (($i >= $s))
629+ then $a
630+ else throw("List size exceeds 10")
631+
632+ $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
633+ }
634+ (removed + added)
635+ }
636+
637+
638+func validatePayments (assetsList,payments) = {
639+ func getPaymentAssets (accum,next) = if ((0 >= next.amount))
640+ then throw(((("Too low payment amount for " + getAssetString(next.assetId)) + ": ") + toString(next.amount)))
641+ else (accum ++ [getAssetString(next.assetId)])
642+
643+ let paymentList = {
644+ let $l = payments
645+ let $s = size($l)
646+ let $acc0 = nil
647+ func $f4_1 ($a,$i) = if (($i >= $s))
648+ then $a
649+ else getPaymentAssets($a, $l[$i])
650+
651+ func $f4_2 ($a,$i) = if (($i >= $s))
652+ then $a
653+ else throw("List size exceeds 10")
654+
655+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
656+ }
657+ func f1 (accum,next) = if ((indexOf(assetsList, next) == unit))
658+ then throw(((next + " asset is present in payments, but is not in new assets: ") + makeString(assetsList, ",")))
659+ else (accum + 1)
660+
661+ func f2 (accum,next) = if ((indexOf(paymentList, next) == unit))
662+ then throw(((next + " asset is present in new assets, but is not in payments: ") + makeString(paymentList, ",")))
663+ else (accum + 1)
664+
665+ let a1 = {
666+ let $l = paymentList
667+ let $s = size($l)
668+ let $acc0 = 0
669+ func $f5_1 ($a,$i) = if (($i >= $s))
670+ then $a
671+ else f1($a, $l[$i])
672+
673+ func $f5_2 ($a,$i) = if (($i >= $s))
674+ then $a
675+ else throw("List size exceeds 10")
676+
677+ $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
678+ }
679+ let a2 = {
680+ let $l = assetsList
681+ let $s = size($l)
682+ let $acc0 = 0
683+ func $f6_1 ($a,$i) = if (($i >= $s))
684+ then $a
685+ else f2($a, $l[$i])
686+
687+ func $f6_2 ($a,$i) = if (($i >= $s))
688+ then $a
689+ else throw("List size exceeds 10")
690+
691+ $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
692+ }
693+ (a1 + a2)
694+ }
695+
696+
697+func validateWeights (weights) = {
698+ func v (accum,w) = {
699+ let wInt = valueOrErrorMessage(parseInt(w), ("Wrong weight format: " + w))
700+ if (if ((MIN_WEIGHT > wInt))
701+ then true
702+ else (wInt > MAX_WEIGHT))
703+ then throw(((((("Weight should be in range " + toString(MIN_WEIGHT)) + " - ") + toString(MAX_WEIGHT)) + ", current: ") + w))
704+ else accum
705+ }
706+
707+ let $l = weights
708+ let $s = size($l)
709+ let $acc0 = 0
710+ func $f4_1 ($a,$i) = if (($i >= $s))
711+ then $a
712+ else v($a, $l[$i])
713+
714+ func $f4_2 ($a,$i) = if (($i >= $s))
715+ then $a
716+ else throw("List size exceeds 10")
717+
718+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
719+ }
720+
721+
722+@Callable(i)
723+func preInit (assetIdsStr,assetWeightsStr,baseTokenIdStr,poolDomain,poolOwner,fee) = {
724+ let poolOwnerAddress = Address(fromBase58String(poolOwner))
725+ let assetIdsStrLi = split(assetIdsStr, ",")
726+ let assetIdsLi = {
727+ let $l = assetIdsStrLi
728+ let $s = size($l)
729+ let $acc0 = nil
730+ func $f4_1 ($a,$i) = if (($i >= $s))
731+ then $a
732+ else addAssetBytesToList($a, $l[$i])
733+
734+ func $f4_2 ($a,$i) = if (($i >= $s))
735+ then $a
736+ else throw("List size exceeds 10")
737+
738+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
739+ }
740+ let feeAssetStr = {
741+ let $l = assetIdsStrLi
742+ let $s = size($l)
743+ let $acc0 = ""
744+ func $f5_1 ($a,$i) = if (($i >= $s))
745+ then $a
746+ else checkFeeAsset($a, $l[$i])
747+
748+ func $f5_2 ($a,$i) = if (($i >= $s))
749+ then $a
750+ else throw("List size exceeds 10")
751+
752+ $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
753+ }
754+ if (isShutdown())
755+ then throw("contract is on stop")
756+ else if ((this != i.caller))
757+ then throw("admin only")
758+ else if ((feeAssetStr == ""))
759+ then throw("pool must have one of the supported fee assets in the composition")
760+ else if ((size(poolDomain) > 13))
761+ then throw("too large pool domain")
762+ else if (if ((fee > 500))
763+ then true
764+ else (0 > fee))
765+ then throw("fee value must be between 50 and 500 (0.5-5%)")
766+ else {
767+ let assetWeightsStrLi = split(assetWeightsStr, ",")
768+ let assetWeightsSum = {
769+ let $l = assetWeightsStrLi
770+ let $s = size($l)
771+ let $acc0 = 0
772+ func $f6_1 ($a,$i) = if (($i >= $s))
773+ then $a
774+ else sum($a, $l[$i])
775+
776+ func $f6_2 ($a,$i) = if (($i >= $s))
777+ then $a
778+ else throw("List size exceeds 10")
779+
780+ $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
781+ }
782+ func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetIdsLi)))
783+ then accum
784+ else {
785+ let assetDecimals = match assetIdsLi[assetNum] {
786+ case x: ByteVector =>
787+ value(assetInfo(x)).decimals
788+ case _ =>
789+ 8
790+ }
791+ (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])))])
792+ }
793+
794+ if ((assetWeightsSum != 10000))
795+ then throw("sum of token weights must be equal to 10000")
796+ else ({
797+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
798+ let $s = size($l)
799+ let $acc0 = nil
800+ func $f7_1 ($a,$i) = if (($i >= $s))
801+ then $a
802+ else addTokenDataEntries($a, $l[$i])
803+
804+ func $f7_2 ($a,$i) = if (($i >= $s))
805+ then $a
806+ else throw("List size exceeds 10")
807+
808+ $f7_2($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
809+ } ++ [StringEntry("static_tokenIds", assetIdsStr), StringEntry("static_feeToken", feeAssetStr), StringEntry("static_tokenWeights", assetWeightsStr), IntegerEntry("static_tokensAmount", size(assetIdsLi)), StringEntry("static_poolDomain", poolDomain), StringEntry("static_baseTokenId", baseTokenIdStr), StringEntry("static_poolOwner", poolOwner), IntegerEntry("static_fee", fee), IntegerEntry("static_KMult", Scale16)])
810+ }
811+ }
812+
813+
814+
815+@Callable(i)
816+func deInit () = if (isShutdown())
817+ then throw("contract is on stop")
818+ else if ((i.caller != this))
819+ then throw("admin only")
820+ else [IntegerEntry("global_wasInited", 0)]
821+
822+
823+
824+@Callable(i)
825+func init () = {
826+ func prepareList () = {
827+ func handler (accum,n) = (accum ++ [IntegerEntry((("global_" + getAssetString(n.assetId)) + "_balance"), n.amount)])
828+
829+ let $l = i.payments
830+ let $s = size($l)
831+ let $acc0 = nil
832+ func $f4_1 ($a,$i) = if (($i >= $s))
833+ then $a
834+ else handler($a, $l[$i])
835+
836+ func $f4_2 ($a,$i) = if (($i >= $s))
837+ then $a
838+ else throw("List size exceeds 10")
839+
840+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
841+ }
842+
843+ func calculatePoolTokensAmount (payments) = {
844+ func handler (accum,pmt) = {
845+ let assetId = pmt.assetId
846+ func handler2 (accum,n) = if ((n == assetId))
847+ then value(indexOf(assetIds, n))
848+ else accum
849+
850+ let Token = {
851+ let $l = assetIds
852+ let $s = size($l)
853+ let $acc0 = 1
854+ func $f4_1 ($a,$i) = if (($i >= $s))
855+ then $a
856+ else handler2($a, $l[$i])
857+
858+ func $f4_2 ($a,$i) = if (($i >= $s))
859+ then $a
860+ else throw("List size exceeds 10")
861+
862+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
863+ }
864+ fraction(accum, pow(pmt.amount, Decimals[Token], AssetsWeights[Token], AssetsWeightsDecimals, 8, FLOOR), Scale8)
865+ }
866+
867+ let $l = payments
868+ let $s = size($l)
869+ let $acc0 = PoolTokenScale
870+ func $f4_1 ($a,$i) = if (($i >= $s))
871+ then $a
872+ else handler($a, $l[$i])
873+
874+ func $f4_2 ($a,$i) = if (($i >= $s))
875+ then $a
876+ else throw("List size exceeds 10")
877+
878+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
879+ }
880+
881+ if (isShutdown())
882+ then throw("contract is on stop")
883+ else if ((tryGetInteger("global_wasInited") > 0))
884+ then throw("pool already inited")
885+ else {
886+ let initialPoolTokens = calculatePoolTokensAmount(i.payments)
887+ if ((initialPoolTokens == 0))
888+ then throw("you need a bigger tokens amount to launch the pool")
889+ else {
890+ let poolTokenIssue = Issue(("PZ " + tryGetString("static_poolDomain")), "Puzzle Swap: pool index token", initialPoolTokens, PoolTokenDecimals, true, unit, 0)
891+ let poolTokenId = calculateAssetId(poolTokenIssue)
892+ (prepareList() ++ [poolTokenIssue, IntegerEntry("global_poolToken_amount", initialPoolTokens), IntegerEntry("global_wasInited", 1), BinaryEntry("global_poolToken_id", poolTokenId), StringEntry("static_poolToken_idStr", getAssetString(poolTokenId)), IntegerEntry((toString(i.caller) + "_indexStaked"), initialPoolTokens), IntegerEntry("global_indexStaked", initialPoolTokens)])
893+ }
894+ }
895+ }
896+
897+
898+
899+@Callable(i)
900+func generateIndex (needChange) = if ((size(i.payments) != T))
901+ then throw(("you need to attach all pool tokens. amount of pool tokens: " + toString(T)))
902+ else if (!(checkTokensValidity(i.payments)))
903+ then throw("wrong assets attached")
904+ else {
905+ let PIssuedNoMult = getMinPIssued(i.payments)
906+ let result = handlePoolTokensAdd(PIssuedNoMult, i.payments, i.originCaller, needChange)
907+ let PIssuedWithMult = fraction(PIssuedNoMult, Scale16, getKMult(), DOWN)
908+ let reissue = Reissue(getBinaryValue("global_poolToken_id"), PIssuedWithMult, true)
909+ $Tuple2((result ++ [reissue, ScriptTransfer(i.caller, PIssuedWithMult, tryGetBinary("global_poolToken_id")), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") + PIssuedWithMult))]), PIssuedWithMult)
910+ }
911+
912+
913+
914+@Callable(i)
915+func redeemIndex (sendToOrigin) = {
916+ let pmt = i.payments[0]
917+ if ((pmt.assetId != tryGetBinary("global_poolToken_id")))
918+ then throw("please attach pool share token")
919+ else if (isShutdown())
920+ then throw("contract is on stop")
921+ else {
922+ let PRedeemedWithMult = pmt.amount
923+ let PRedeemedWithNoMult = fraction(PRedeemedWithMult, getKMult(), Scale16, DOWN)
924+ let result = handlePoolTokensRedeem(PRedeemedWithNoMult, if (sendToOrigin)
925+ then i.originCaller
926+ else i.caller)
927+ (result ++ [Burn(tryGetBinary("global_poolToken_id"), PRedeemedWithMult), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemedWithMult))])
928+ }
929+ }
930+
931+
932+
933+@Callable(i)
934+func stakeIndex () = {
935+ let addressStr = toString(i.originCaller)
936+ let pmt = i.payments[0]
937+ if ((value(pmt.assetId) != tryGetBinary("global_poolToken_id")))
938+ then throw("wrong asset attached")
939+ else indexStakeResult(addressStr, pmt.amount)
940+ }
941+
942+
943+
944+@Callable(i)
945+func stakeIndexFor (addressStr) = {
946+ let pmt = i.payments[0]
947+ if ((value(pmt.assetId) != tryGetBinary("global_poolToken_id")))
948+ then throw("wrong asset attached")
949+ else indexStakeResult(addressStr, pmt.amount)
950+ }
951+
952+
953+
954+@Callable(i)
955+func unstakeIndex (indexAmount) = {
956+ let addressStr = if ((indexOf(layer2Addresses, toString(i.caller)) != unit))
957+ then toString(i.originCaller)
958+ else toString(i.caller)
959+ let indexAvailable = tryGetInteger((addressStr + "_indexStaked"))
960+ if (isShutdown())
961+ then throw("contract is on stop")
962+ else if ((indexAmount > indexAvailable))
963+ then throw("you don't have index tokens available")
964+ else if (isShutdown())
965+ then throw("contract is on stop")
966+ else (claimResult(addressFromStringValue(addressStr))._1 ++ [IntegerEntry((addressStr + "_indexStaked"), (indexAvailable - indexAmount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - indexAmount)), ScriptTransfer(i.caller, indexAmount, getBinaryValue("global_poolToken_id"))])
967+ }
968+
969+
970+
971+@Callable(i)
972+func claimIndexRewards () = if (isShutdown())
973+ then throw("contract is on stop")
974+ else claimResult(i.caller)
975+
976+
977+
978+@Callable(i)
979+func evaluateClaim (user) = $Tuple2(nil, claimResult(addressFromStringValue(user))._2)
980+
981+
982+
983+@Callable(i)
984+func swap (assetOut,minimum) = {
985+ let pmt = if ((size(i.payments) == 1))
986+ then value(i.payments[0])
987+ else throw("please attach exactly one payment")
988+ let AmountIn = value(i.payments[0].amount)
989+ let AssetIn = pmt.assetId
990+ let AssetOut = getAssetBytes(assetOut)
991+ let assetIn = getAssetString(AssetIn)
992+ let scaleIn = (Scale8 / tryGetInteger((("static_" + assetIn) + "_scale")))
993+ let scaleOut = (Scale8 / tryGetInteger((("static_" + assetOut) + "_scale")))
994+ let feeAssetOutStr = tryGetString("static_feeToken")
995+ let feeAssetOut = if ((feeAssetOutStr == ""))
996+ then usdnAssetId
997+ else getAssetBytes(feeAssetOutStr)
998+ let AssetInBalance = tryGetInteger((("global_" + getAssetString(AssetIn)) + "_balance"))
999+ let AssetOutBalance = tryGetInteger((("global_" + assetOut) + "_balance"))
1000+ let AssetInBalanceScaled = (AssetInBalance * scaleIn)
1001+ let AssetOutBalanceScaled = (AssetOutBalance * scaleOut)
1002+ let feeAmountIn = fraction(AmountIn, Fee, FeeScale)
1003+ let cleanAmountIn = (AmountIn - feeAmountIn)
1004+ let cleanAmountInScaled = (cleanAmountIn * scaleIn)
1005+ let AmountOut1 = calculateOutAmount(cleanAmountInScaled, AssetIn, AssetOut, AssetInBalanceScaled, AssetOutBalanceScaled)
1006+ let AmountOut = fraction(AmountOut1, 1, scaleOut)
1007+ let AssetOutBalance2 = (AssetOutBalance - AmountOut)
1008+ let AssetInBalance2 = (AssetInBalance + cleanAmountIn)
1009+ let feeAssetOutBalance = if ((feeAssetOut == AssetIn))
1010+ then AssetInBalance2
1011+ else if ((feeAssetOut == AssetOut))
1012+ then AssetOutBalance2
1013+ else tryGetInteger((("global_" + getAssetString(feeAssetOut)) + "_balance"))
1014+ let feeAmountOut = calculateOutAmount(feeAmountIn, AssetIn, feeAssetOut, AssetInBalance, feeAssetOutBalance)
1015+ if ((minimum > AmountOut))
1016+ then throw("amount to recieve is lower than given one")
1017+ else if ((AssetOut == AssetIn))
1018+ then throw("this swap is not allowed")
1019+ else if ((0 > (AssetOutBalance - AmountOut)))
1020+ then throw("contract is out of reserves")
1021+ else if (isShutdown())
1022+ then throw("contract is on stop")
1023+ else {
1024+ let creatorFee = fraction(feeAmountOut, 1, 10)
1025+ let protocolFee = fraction(feeAmountOut, 4, 10)
1026+ let newBalanceIn = AssetInBalance2
1027+ let newBalanceOut = (AssetOutBalance2 - (if ((AssetOut == feeAssetOut))
1028+ then feeAmountOut
1029+ else 0))
1030+ let newBalanceFeeAsset = if (if ((feeAssetOut != AssetIn))
1031+ then (feeAssetOut != AssetOut)
1032+ else false)
1033+ then (feeAssetOutBalance - feeAmountOut)
1034+ else unit
1035+ let assetInChange = IntegerEntry((("global_" + getAssetString(AssetIn)) + "_balance"), newBalanceIn)
1036+ let assetOutChange = IntegerEntry((("global_" + assetOut) + "_balance"), newBalanceOut)
1037+ let feeAssetOutChange = if ((newBalanceFeeAsset != unit))
1038+ then IntegerEntry((("global_" + getAssetString(feeAssetOut)) + "_balance"), value(newBalanceFeeAsset))
1039+ else StringEntry("hello", "world")
1040+ let volumeUpdate = calculateUsdnValue(AssetIn, AmountIn, AssetInBalance, feeAssetOutBalance)
1041+ let volumeUsdUpdate = calculateUsdValue(AssetIn, AmountIn, AssetInBalance)
1042+ $Tuple2([assetOutChange, assetInChange, feeAssetOutChange, ScriptTransfer(i.caller, AmountOut, AssetOut), ScriptTransfer(addressFromStringValue(tryGetString("static_poolOwner")), creatorFee, feeAssetOut), IntegerEntry("global_earnedByOwner", (tryGetInteger("global_earnedByOwner") + creatorFee)), IntegerEntry("global_volume", (tryGetInteger("global_volume") + volumeUpdate)), IntegerEntry("global_volume_usd", (tryGetInteger("global_volume_usd") + volumeUsdUpdate)), ScriptTransfer(feesAddress, protocolFee, feeAssetOut)], AmountOut)
1043+ }
1044+ }
1045+
1046+
1047+
1048+@Callable(i)
1049+func swapReadOnly (assetIn,assetOut,AmountIn) = {
1050+ let AssetIn = getAssetBytes(assetIn)
1051+ let AssetOut = getAssetBytes(assetOut)
1052+ let scaleIn = (Scale8 / tryGetInteger((("static_" + assetIn) + "_scale")))
1053+ let scaleOut = (Scale8 / tryGetInteger((("static_" + assetOut) + "_scale")))
1054+ let feeAssetOutStr = tryGetString("static_feeToken")
1055+ let feeAssetOut = if ((feeAssetOutStr == ""))
1056+ then usdnAssetId
1057+ else getAssetBytes(feeAssetOutStr)
1058+ let AssetInBalance = tryGetInteger((("global_" + getAssetString(AssetIn)) + "_balance"))
1059+ let AssetOutBalance = tryGetInteger((("global_" + assetOut) + "_balance"))
1060+ let AssetInBalanceScaled = (AssetInBalance * scaleIn)
1061+ let AssetOutBalanceScaled = (AssetOutBalance * scaleOut)
1062+ let feeAmountIn = fraction(AmountIn, Fee, FeeScale)
1063+ let cleanAmountIn = (AmountIn - feeAmountIn)
1064+ let cleanAmountInScaled = (cleanAmountIn * scaleIn)
1065+ let AmountOut1 = calculateOutAmount(cleanAmountInScaled, AssetIn, AssetOut, AssetInBalanceScaled, AssetOutBalanceScaled)
1066+ let AmountOut = fraction(AmountOut1, 1, scaleOut)
1067+ let AssetOutBalance2 = (AssetOutBalance - AmountOut)
1068+ let AssetInBalance2 = (AssetInBalance + cleanAmountIn)
1069+ let feeAssetOutBalance = if ((feeAssetOut == AssetIn))
1070+ then AssetInBalance2
1071+ else if ((feeAssetOut == AssetOut))
1072+ then AssetOutBalance2
1073+ else tryGetInteger((("global_" + getAssetString(feeAssetOut)) + "_balance"))
1074+ let feeAmountOut = calculateOutAmount(feeAmountIn, AssetIn, feeAssetOut, AssetInBalance, feeAssetOutBalance)
1075+ if ((AssetOut == AssetIn))
1076+ then throw("this swap is not allowed")
1077+ else if ((0 > (AssetOutBalance - AmountOut)))
1078+ then throw("contract is out of reserves")
1079+ else if (isShutdown())
1080+ then throw("contract is on stop")
1081+ else $Tuple2(nil, AmountOut)
1082+ }
1083+
1084+
1085+
1086+@Callable(i)
1087+func transferOwnership (newOwnerAddress) = if ((toString(i.caller) != tryGetString("static_poolOwner")))
1088+ then throw("this call available only for pool owner")
1089+ else [StringEntry("static_poolOwner", newOwnerAddress)]
1090+
1091+
1092+
1093+@Callable(i)
1094+func setFee (newFee) = if ((toString(i.caller) != tryGetString("static_poolOwner")))
1095+ then throw("this call available only for pool owner")
1096+ else if ((1 > valueOrElse(getInteger(govAddress, ("approvedTx_" + toBase58String(i.transactionId))), 0)))
1097+ then throw("this transaction needs approval from puzzle network")
1098+ else [IntegerEntry("static_fee", newFee)]
1099+
1100+
1101+
1102+@Callable(i)
1103+func setRebalancingPlan (assetIdsStr,assetWeightsStr,baseTokenIdStr,stepsAmount,stepsInterval) = if ((i.caller != addressFromStringValue(tryGetString("static_poolOwner"))))
1104+ then throw("this call available only for pool owner")
1105+ else if ((1 > valueOrElse(getInteger(govAddress, ("approvedTx_" + toBase58String(i.transactionId))), 0)))
1106+ then throw("this transaction needs approval from puzzle network")
1107+ else if (valueOrElse(getBoolean(this, "rebalance_inProgress"), false))
1108+ then throw("rebalancing in progress")
1109+ else {
1110+ let newAssetWeightsStrLi = split(assetWeightsStr, ",")
1111+ let newAssetIdsStrLi = split(assetIdsStr, ",")
1112+ let feeAssetStr = {
1113+ let $l = newAssetIdsStrLi
1114+ let $s = size($l)
1115+ let $acc0 = ""
1116+ func $f4_1 ($a,$i) = if (($i >= $s))
1117+ then $a
1118+ else checkFeeAsset($a, $l[$i])
1119+
1120+ func $f4_2 ($a,$i) = if (($i >= $s))
1121+ then $a
1122+ else throw("List size exceeds 10")
1123+
1124+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1125+ }
1126+ let assetWeightsSum = {
1127+ let $l = newAssetWeightsStrLi
1128+ let $s = size($l)
1129+ let $acc0 = 0
1130+ func $f5_1 ($a,$i) = if (($i >= $s))
1131+ then $a
1132+ else sum($a, $l[$i])
1133+
1134+ func $f5_2 ($a,$i) = if (($i >= $s))
1135+ then $a
1136+ else throw("List size exceeds 10")
1137+
1138+ $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1139+ }
1140+ let oldAssetIds = getStringValue("static_tokenIds")
1141+ let oldAssetIdsLi = split(oldAssetIds, ",")
1142+ func findAdded (accum,next) = if ((indexOf(oldAssetIdsLi, next) == unit))
1143+ then (accum ++ [next])
1144+ else accum
1145+
1146+ func findRemoved (accum,next) = if ((indexOf(newAssetIdsStrLi, next) == unit))
1147+ then (accum ++ [next])
1148+ else accum
1149+
1150+ let addedAssets = {
1151+ let $l = newAssetIdsStrLi
1152+ let $s = size($l)
1153+ let $acc0 = nil
1154+ func $f6_1 ($a,$i) = if (($i >= $s))
1155+ then $a
1156+ else findAdded($a, $l[$i])
1157+
1158+ func $f6_2 ($a,$i) = if (($i >= $s))
1159+ then $a
1160+ else throw("List size exceeds 10")
1161+
1162+ $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1163+ }
1164+ let removedAssets = {
1165+ let $l = oldAssetIdsLi
1166+ let $s = size($l)
1167+ let $acc0 = nil
1168+ func $f7_1 ($a,$i) = if (($i >= $s))
1169+ then $a
1170+ else findRemoved($a, $l[$i])
1171+
1172+ func $f7_2 ($a,$i) = if (($i >= $s))
1173+ then $a
1174+ else throw("List size exceeds 10")
1175+
1176+ $f7_2($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1177+ }
1178+ let validPayments = validatePayments(addedAssets, i.payments)
1179+ let validWeights = validateWeights(newAssetWeightsStrLi)
1180+ if ((validWeights == validWeights))
1181+ then if ((validPayments != (size(addedAssets) + size(i.payments))))
1182+ then throw("Payments not present or something wrong with them")
1183+ else if ((size(newAssetIdsStrLi) != size(newAssetWeightsStrLi)))
1184+ then throw("assetIds and assetWeights should have same length")
1185+ else if ((validPayments != (size(addedAssets) + size(i.payments))))
1186+ then throw("Payments not present or something wrong with them")
1187+ else if ((feeAssetStr == ""))
1188+ then throw("pool must have one of the supported fee assets in the composition")
1189+ else if ((indexOf(newAssetIdsStrLi, baseTokenIdStr) == unit))
1190+ then throw("baseTokenId should be present in assetIds")
1191+ else if (if ((MIN_STEPS_AMOUNT > stepsAmount))
1192+ then true
1193+ else (stepsAmount > MAX_STEPS_AMOUNT))
1194+ then throw(((((("Steps amount should be between " + toString(MIN_STEPS_AMOUNT)) + " and ") + toString(MAX_STEPS_AMOUNT)) + ", current: ") + toString(stepsAmount)))
1195+ else if (if ((MIN_STEPS_INTERVAL > stepsInterval))
1196+ then true
1197+ else (stepsInterval > MAX_STEPS_INTERVAL))
1198+ then throw(((((("Steps interval should be between " + toString(MIN_STEPS_INTERVAL)) + " and ") + toString(MAX_STEPS_INTERVAL)) + ", current: ") + toString(stepsInterval)))
1199+ else if ((assetWeightsSum != 10000))
1200+ then throw(("sum of token weights must be equal to 10000, current: " + toString(assetWeightsSum)))
1201+ else {
1202+ func f (accum,assetIdStr) = {
1203+ let oldWeight = tryGetInteger((("static_" + assetIdStr) + "_weight"))
1204+ let newWeight = if ((indexOf(newAssetIdsStrLi, assetIdStr) == unit))
1205+ then 0
1206+ else parseIntValue(value(newAssetWeightsStrLi[value(indexOf(newAssetIdsStrLi, assetIdStr))]))
1207+ let deltaPerStep = fraction((newWeight - oldWeight), 10000, stepsAmount)
1208+ (accum ++ [toString(deltaPerStep)])
1209+ }
1210+
1211+ let tmpAssetIdsLi = getTmpRebalanceIds(newAssetIdsStrLi)
1212+ let assetDeltas = {
1213+ let $l = tmpAssetIdsLi
1214+ let $s = size($l)
1215+ let $acc0 = nil
1216+ func $f8_1 ($a,$i) = if (($i >= $s))
1217+ then $a
1218+ else f($a, $l[$i])
1219+
1220+ func $f8_2 ($a,$i) = if (($i >= $s))
1221+ then $a
1222+ else throw("List size exceeds 10")
1223+
1224+ $f8_2($f8_1($f8_1($f8_1($f8_1($f8_1($f8_1($f8_1($f8_1($f8_1($f8_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1225+ }
1226+ let newTokensAdded = (checkTokensChange(newAssetIdsStrLi) > 0)
1227+ func recordAssetPayment (accum,next) = (accum ++ [IntegerEntry(("rebalance_attachedPayment_" + getAssetString(next.assetId)), next.amount)])
1228+
1229+ let paymentEntries = {
1230+ let $l = i.payments
1231+ let $s = size($l)
1232+ let $acc0 = nil
1233+ func $f9_1 ($a,$i) = if (($i >= $s))
1234+ then $a
1235+ else recordAssetPayment($a, $l[$i])
1236+
1237+ func $f9_2 ($a,$i) = if (($i >= $s))
1238+ then $a
1239+ else throw("List size exceeds 10")
1240+
1241+ $f9_2($f9_1($f9_1($f9_1($f9_1($f9_1($f9_1($f9_1($f9_1($f9_1($f9_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1242+ }
1243+ let storeWeights = saveCurrentWeights()
1244+ let notifyInvoke = invoke(poolsHubAddress, "notifyPoolChange", nil, nil)
1245+ if ((notifyInvoke == notifyInvoke))
1246+ then (([StringEntry("rebalance_addedAssets", makeString(addedAssets, ",")), StringEntry("rebalance_removedAssets", makeString(removedAssets, ",")), StringEntry("tmp_rebalanceAssetIds", makeString(tmpAssetIdsLi, ",")), BooleanEntry("rebalance_inProgress", true), BooleanEntry("rebalance_newTokensAdded", newTokensAdded), IntegerEntry("rebalance_stepsDone", 0), IntegerEntry("rebalance_lastStepHeight", height), IntegerEntry("rebalance_stepsAmount", stepsAmount), IntegerEntry("rebalance_stepsInterval", stepsInterval), StringEntry("rebalance_assetIds", assetIdsStr), StringEntry("rebalance_newBaseTokenId", baseTokenIdStr), StringEntry("rebalance_assetDeltas", makeString(assetDeltas, ","))] ++ paymentEntries) ++ storeWeights)
1247+ else throw("Strict value is not equal to itself.")
1248+ }
1249+ else throw("Strict value is not equal to itself.")
1250+ }
1251+
1252+
1253+
1254+@Callable(i)
1255+func stepRebalancing () = if (!(valueOrElse(getBoolean(this, "rebalance_inProgress"), false)))
1256+ then throw("no rebalancing in progress")
1257+ else {
1258+ let lastStepHeight = getIntegerValue("rebalance_lastStepHeight")
1259+ let stepInterval = getIntegerValue("rebalance_stepsInterval")
1260+ let stepsDone = getIntegerValue("rebalance_stepsDone")
1261+ let nextStepHeight = (lastStepHeight + stepInterval)
1262+ if ((nextStepHeight > height))
1263+ then throw("can't be done yet")
1264+ else {
1265+ let assetDeltas = split(getStringValue("rebalance_assetDeltas"), ",")
1266+ let newAssetIdsStr = getStringValue("tmp_rebalanceAssetIds")
1267+ let newAssetIds = split(newAssetIdsStr, ",")
1268+ func f (accum,assetIdStr) = (accum ++ [toString(fraction(((valueOrElse(getInteger(("rebalance_startWeight_" + assetIdStr)), 0) * 10000) + (parseIntValue(assetDeltas[value(indexOf(newAssetIds, assetIdStr))]) * (stepsDone + 1))), 1, 10000, HALFUP))])
1269+
1270+ let newShares = makeString({
1271+ let $l = newAssetIds
1272+ let $s = size($l)
1273+ let $acc0 = nil
1274+ func $f4_1 ($a,$i) = if (($i >= $s))
1275+ then $a
1276+ else f($a, $l[$i])
1277+
1278+ func $f4_2 ($a,$i) = if (($i >= $s))
1279+ then $a
1280+ else throw("List size exceeds 10")
1281+
1282+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1283+ }, ",")
1284+ let newTokensAdded = getBooleanValue("rebalance_newTokensAdded")
1285+ let inv = if (if (newTokensAdded)
1286+ then (stepsDone == 0)
1287+ else false)
1288+ then invoke(this, "doRebalancingWithNewTokens", [newAssetIdsStr, newShares, getStringValue("rebalance_newBaseTokenId")], nil)
1289+ else invoke(this, "doRebalancing", [newShares], nil)
1290+ if ((inv == inv))
1291+ then {
1292+ let notifyInvoke = invoke(poolsHubAddress, "notifyPoolChange", nil, nil)
1293+ if ((notifyInvoke == notifyInvoke))
1294+ then {
1295+ let isFinished = ((stepsDone + 1) >= getIntegerValue("rebalance_stepsAmount"))
1296+ let actions = [BooleanEntry("rebalance_inProgress", !(isFinished)), IntegerEntry("rebalance_stepsDone", (stepsDone + 1)), IntegerEntry("rebalance_lastStepHeight", height)]
1297+ if ((stepsDone == 0))
1298+ then (actions ++ [StringEntry("static_tokenIds", newAssetIdsStr)])
1299+ else if (isFinished)
1300+ then {
1301+ let removedAssetsLi = split(tryGetString("rebalance_removedAssets"), ",")
1302+ func rmData (accum,assetId) = (accum ++ [DeleteEntry((("static_" + assetId) + "_scale")), DeleteEntry((("static_" + assetId) + "_decimals")), DeleteEntry((("static_" + assetId) + "_weight")), DeleteEntry((("global_" + assetId) + "_balance")), DeleteEntry(("rebalance_attachedPayment_" + assetId))])
1303+
1304+ let rm = {
1305+ let $l = removedAssetsLi
1306+ let $s = size($l)
1307+ let $acc0 = nil
1308+ func $f5_1 ($a,$i) = if (($i >= $s))
1309+ then $a
1310+ else rmData($a, $l[$i])
1311+
1312+ func $f5_2 ($a,$i) = if (($i >= $s))
1313+ then $a
1314+ else throw("List size exceeds 10")
1315+
1316+ $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1317+ }
1318+ let addedAssetsLi = split(tryGetString("rebalance_addedAssets"), ",")
1319+ func addRemovePayments (accum,assetId) = (accum ++ [DeleteEntry(("rebalance_attachedPayment_" + assetId))])
1320+
1321+ let rmPayments = {
1322+ let $l = addedAssetsLi
1323+ let $s = size($l)
1324+ let $acc0 = nil
1325+ func $f6_1 ($a,$i) = if (($i >= $s))
1326+ then $a
1327+ else addRemovePayments($a, $l[$i])
1328+
1329+ func $f6_2 ($a,$i) = if (($i >= $s))
1330+ then $a
1331+ else throw("List size exceeds 10")
1332+
1333+ $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1334+ }
1335+ let finalAssetsIdsStr = tryGetString("rebalance_assetIds")
1336+ let AssetsWeightsStr = {
1337+ let $l = split(finalAssetsIdsStr, ",")
1338+ let $s = size($l)
1339+ let $acc0 = nil
1340+ func $f7_1 ($a,$i) = if (($i >= $s))
1341+ then $a
1342+ else addAssetWeightToStrList($a, $l[$i])
1343+
1344+ func $f7_2 ($a,$i) = if (($i >= $s))
1345+ then $a
1346+ else throw("List size exceeds 10")
1347+
1348+ $f7_2($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1349+ }
1350+ (((actions ++ rm) ++ rmPayments) ++ [StringEntry("static_tokenIds", finalAssetsIdsStr), StringEntry("static_tokenWeights", makeString(AssetsWeightsStr, ",")), IntegerEntry("static_tokensAmount", size(split(finalAssetsIdsStr, ",")))])
1351+ }
1352+ else {
1353+ let finalAssetsIdsStr = tryGetString("rebalance_assetIds")
1354+ let AssetsWeightsStr = {
1355+ let $l = split(finalAssetsIdsStr, ",")
1356+ let $s = size($l)
1357+ let $acc0 = nil
1358+ func $f5_1 ($a,$i) = if (($i >= $s))
1359+ then $a
1360+ else addAssetWeightToStrList($a, $l[$i])
1361+
1362+ func $f5_2 ($a,$i) = if (($i >= $s))
1363+ then $a
1364+ else throw("List size exceeds 10")
1365+
1366+ $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1367+ }
1368+ (actions ++ [StringEntry("static_tokenWeights", makeString(AssetsWeightsStr, ","))])
1369+ }
1370+ }
1371+ else throw("Strict value is not equal to itself.")
1372+ }
1373+ else throw("Strict value is not equal to itself.")
1374+ }
1375+ }
1376+
1377+
1378+
1379+@Callable(i)
1380+func doRebalancing (assetWeightsStr) = {
1381+ let assetWeightsStrLi = split(assetWeightsStr, ",")
1382+ let assetWeightsSum = {
1383+ let $l = assetWeightsStrLi
1384+ let $s = size($l)
1385+ let $acc0 = 0
1386+ func $f4_1 ($a,$i) = if (($i >= $s))
1387+ then $a
1388+ else sum($a, $l[$i])
1389+
1390+ func $f4_2 ($a,$i) = if (($i >= $s))
1391+ then $a
1392+ else throw("List size exceeds 10")
1393+
1394+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1395+ }
1396+ let assetIdsStrLi = split(tryGetString("static_tokenIds"), ",")
1397+ if ((i.caller != this))
1398+ then throw("this call available only for admin")
1399+ else {
1400+ let oldKMult = getKMult()
1401+ func handler (pars,assetId) = {
1402+ let accum = pars._1
1403+ let assetIdStr = getAssetString(assetId)
1404+ func handler2 (accum,n) = if ((n == assetId))
1405+ then value(indexOf(assetIds, n))
1406+ else accum
1407+
1408+ let Token = {
1409+ let $l = assetIds
1410+ let $s = size($l)
1411+ let $acc0 = 1
1412+ func $f5_1 ($a,$i) = if (($i >= $s))
1413+ then $a
1414+ else handler2($a, $l[$i])
1415+
1416+ func $f5_2 ($a,$i) = if (($i >= $s))
1417+ then $a
1418+ else throw("List size exceeds 10")
1419+
1420+ $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1421+ }
1422+ let balance = tryGetInteger((("global_" + assetIdStr) + "_balance"))
1423+ let weight = if ((pars._2 == "new"))
1424+ then parseIntValue(assetWeightsStrLi[Token])
1425+ else tryGetInteger((("static_" + assetIdStr) + "_weight"))
1426+ $Tuple2(fraction(accum, pow(balance, Decimals[Token], weight, AssetsWeightsDecimals, 8, FLOOR), Scale8), pars._2)
1427+ }
1428+
1429+ let newK = ( let $l = assetIds
1430+ let $s = size($l)
1431+ let $acc0 = $Tuple2(PoolTokenScale, "new")
1432+ func $f5_1 ($a,$i) = if (($i >= $s))
1433+ then $a
1434+ else handler($a, $l[$i])
1435+
1436+ func $f5_2 ($a,$i) = if (($i >= $s))
1437+ then $a
1438+ else throw("List size exceeds 10")
1439+
1440+ $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10))._1
1441+ let oldK = ( let $l = assetIds
1442+ let $s = size($l)
1443+ let $acc0 = $Tuple2(PoolTokenScale, "old")
1444+ func $f6_1 ($a,$i) = if (($i >= $s))
1445+ then $a
1446+ else handler($a, $l[$i])
1447+
1448+ func $f6_2 ($a,$i) = if (($i >= $s))
1449+ then $a
1450+ else throw("List size exceeds 10")
1451+
1452+ $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10))._1
1453+ let newKMult = fraction(oldKMult, newK, oldK)
1454+ func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetWeightsStrLi)))
1455+ then accum
1456+ else (accum ++ [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_weight"), value(parseInt(assetWeightsStrLi[assetNum])))])
1457+
1458+ ({
1459+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1460+ let $s = size($l)
1461+ let $acc0 = nil
1462+ func $f7_1 ($a,$i) = if (($i >= $s))
1463+ then $a
1464+ else addTokenDataEntries($a, $l[$i])
1465+
1466+ func $f7_2 ($a,$i) = if (($i >= $s))
1467+ then $a
1468+ else throw("List size exceeds 10")
1469+
1470+ $f7_2($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1471+ } ++ [IntegerEntry("static_KMult", newKMult)])
1472+ }
1473+ }
1474+
1475+
1476+
1477+@Callable(i)
1478+func doRebalancingWithNewTokens (assetIdsStr,assetWeightsStr,baseTokenIdStr) = {
1479+ let newAssetWeightsStrLi = split(assetWeightsStr, ",")
1480+ let prevAssetIdsStrLi = split(tryGetString("static_tokenIds"), ",")
1481+ let newAssetIdsStrLi = split(assetIdsStr, ",")
1482+ let newAssetIds = {
1483+ let $l = newAssetIdsStrLi
1484+ let $s = size($l)
1485+ let $acc0 = nil
1486+ func $f4_1 ($a,$i) = if (($i >= $s))
1487+ then $a
1488+ else addAssetBytesToList($a, $l[$i])
1489+
1490+ func $f4_2 ($a,$i) = if (($i >= $s))
1491+ then $a
1492+ else throw("List size exceeds 10")
1493+
1494+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1495+ }
1496+ let feeAssetStr = {
1497+ let $l = newAssetIdsStrLi
1498+ let $s = size($l)
1499+ let $acc0 = ""
1500+ func $f5_1 ($a,$i) = if (($i >= $s))
1501+ then $a
1502+ else checkFeeAsset($a, $l[$i])
1503+
1504+ func $f5_2 ($a,$i) = if (($i >= $s))
1505+ then $a
1506+ else throw("List size exceeds 10")
1507+
1508+ $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1509+ }
1510+ let addedAssets = split(tryGetString("rebalance_addedAssets"), ",")
1511+ func findAssetPayment (assetId) = valueOrElse(getInteger(("rebalance_attachedPayment_" + getAssetString(assetId))), 0)
1512+
1513+ func addAssetBalanceToLi (li,assetId) = (li ++ [findAssetPayment(assetId)])
1514+
1515+ let attachedBalances = {
1516+ let $l = newAssetIds
1517+ let $s = size($l)
1518+ let $acc0 = nil
1519+ func $f6_1 ($a,$i) = if (($i >= $s))
1520+ then $a
1521+ else addAssetBalanceToLi($a, $l[$i])
1522+
1523+ func $f6_2 ($a,$i) = if (($i >= $s))
1524+ then $a
1525+ else throw("List size exceeds 10")
1526+
1527+ $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1528+ }
1529+ if ((i.caller != this))
1530+ then throw(("this call available only for admin, " + toString(i.caller)))
1531+ else {
1532+ let oldKMult = getKMult()
1533+ let oldK = getVirtualPoolTokenAmount()
1534+ func myltiplyAssetsForK (pars,assetId) = {
1535+ func findAssetNum (accum,n) = if ((n == assetId))
1536+ then value(indexOf(newAssetIds, n))
1537+ else accum
1538+
1539+ let currentK = pars
1540+ let assetIdStr = getAssetString(assetId)
1541+ let TokenNum = {
1542+ let $l = newAssetIds
1543+ let $s = size($l)
1544+ let $acc0 = 1
1545+ func $f7_1 ($a,$i) = if (($i >= $s))
1546+ then $a
1547+ else findAssetNum($a, $l[$i])
1548+
1549+ func $f7_2 ($a,$i) = if (($i >= $s))
1550+ then $a
1551+ else throw("List size exceeds 10")
1552+
1553+ $f7_2($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1554+ }
1555+ let weight = parseIntValue(newAssetWeightsStrLi[TokenNum])
1556+ let balanceInState = tryGetInteger((("global_" + assetIdStr) + "_balance"))
1557+ let balanceInPayment = attachedBalances[TokenNum]
1558+ let balance = (balanceInState + balanceInPayment)
1559+ let assetDecimals = if ((assetId == unit))
1560+ then 8
1561+ else value(assetInfo(value(assetId))).decimals
1562+ if ((0 >= balance))
1563+ then throw(("you need to attach all new assets in payment. this asset is missed: " + assetIdStr))
1564+ else fraction(currentK, pow(balance, assetDecimals, weight, AssetsWeightsDecimals, 8, FLOOR), Scale8)
1565+ }
1566+
1567+ let newK = {
1568+ let $l = newAssetIds
1569+ let $s = size($l)
1570+ let $acc0 = PoolTokenScale
1571+ func $f7_1 ($a,$i) = if (($i >= $s))
1572+ then $a
1573+ else myltiplyAssetsForK($a, $l[$i])
1574+
1575+ func $f7_2 ($a,$i) = if (($i >= $s))
1576+ then $a
1577+ else throw("List size exceeds 10")
1578+
1579+ $f7_2($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($f7_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1580+ }
1581+ let newKMult = fraction(oldKMult, newK, oldK)
1582+ func addTokenDataEntries (accum,assetNum) = {
1583+ let assetIdStr = newAssetIdsStrLi[assetNum]
1584+ let assetId = newAssetIds[assetNum]
1585+ let assetDecimals = if ((assetId == unit))
1586+ then 8
1587+ else value(assetInfo(value(assetId))).decimals
1588+ let newAssetData = if ((indexOf(addedAssets, assetIdStr) != unit))
1589+ then [IntegerEntry((("global_" + assetIdStr) + "_balance"), attachedBalances[assetNum]), IntegerEntry((("static_" + assetIdStr) + "_scale"), pow(10, 0, assetDecimals, 0, 0, DOWN)), IntegerEntry((("static_" + assetIdStr) + "_decimals"), assetDecimals)]
1590+ else nil
1591+ if ((assetNum >= size(newAssetWeightsStrLi)))
1592+ then accum
1593+ else ((accum ++ [IntegerEntry((("static_" + assetIdStr) + "_weight"), value(parseInt(newAssetWeightsStrLi[assetNum])))]) ++ newAssetData)
1594+ }
1595+
1596+ ({
1597+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1598+ let $s = size($l)
1599+ let $acc0 = nil
1600+ func $f8_1 ($a,$i) = if (($i >= $s))
1601+ then $a
1602+ else addTokenDataEntries($a, $l[$i])
1603+
1604+ func $f8_2 ($a,$i) = if (($i >= $s))
1605+ then $a
1606+ else throw("List size exceeds 10")
1607+
1608+ $f8_2($f8_1($f8_1($f8_1($f8_1($f8_1($f8_1($f8_1($f8_1($f8_1($f8_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1609+ } ++ [StringEntry("static_tokenIds", assetIdsStr), StringEntry("static_feeToken", feeAssetStr), StringEntry("static_tokenWeights", assetWeightsStr), IntegerEntry("static_tokensAmount", size(newAssetIds)), IntegerEntry("static_KMult", newKMult)])
1610+ }
1611+ }
1612+
1613+
1614+@Verifier(tx)
1615+func verify () = match tx {
1616+ case tx: SetScriptTransaction =>
1617+ let scriptFull = value(tx.script)
1618+ let hash = toBase58String(sha256(scriptFull))
1619+ if (sigVerify(tx.bodyBytes, tx.proofs[0], masterPubKey))
1620+ then (valueOrElse(getInteger(coldMasterAddress, ("approvedScript_" + hash)), 0) > height)
1621+ else false
1622+ case _ =>
1623+ if (sigVerify(tx.bodyBytes, tx.proofs[0], masterPubKey))
1624+ then (valueOrElse(getInteger(coldMasterAddress, ("approvedTx_" + toBase58String(tx.id))), 0) > 0)
1625+ else false
1626+}
1627+

github/deemru/w8io/3ef1775 
76.19 ms