tx · CNDyKmvhqWUsqX4PihSutC51YwFFsCQqPm34ceRxpRwT

3MPdQu4132jmjX3XXWteFd7ma9gPQ8zG41p:  -0.05500000 Waves

2025.09.22 02:35 [303972] smart account 3MPdQu4132jmjX3XXWteFd7ma9gPQ8zG41p > SELF 0.00000000 Waves

{ "type": 13, "id": "CNDyKmvhqWUsqX4PihSutC51YwFFsCQqPm34ceRxpRwT", "fee": 5500000, "feeAssetId": null, "timestamp": 1758497740508, "version": 2, "chainId": 82, "sender": "3MPdQu4132jmjX3XXWteFd7ma9gPQ8zG41p", "senderPublicKey": "rj1ZkoUrVDy2FugVR1inBNY2255SxXPrZHvHDndrdgx", "proofs": [ "P8Ac3bYXkFPRrbZxRkJxdNrKQJDPXj3cpAQiCCczhRzsXsfhF4HYARE52azz5SUjhLGj3GY8dEabT3htkQ7bgpW" ], "script": "base64:BgJcCAISBAoCCAgSCQoHCAgICAgIARIAEgkKBwgICAgIAQgSAwoBBBIDCgEBEgASAwoBCBIDCgEBEgASAwoBCBIAEgQKAggBEgQKAggBEgUKAwgIARIDCgEIEgMKAQFkAAdWRVJTSU9OAhFQWi0zLjYuMSBPcHRpbWl6ZQAJY29uZmlnU3RyCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMCDWNvbmZpZ0FkZHJlc3MCIzNQTW9FaWJkTGVXcWNVUlE4MzUxWGhhV3d5YWNEYzdHNGU1AA5DT05GSUdfQUREUkVTUwMJAAACBQljb25maWdTdHICAAUEdGhpcwkBB0FkZHJlc3MBCQDZBAEFCWNvbmZpZ1N0cgAVQXNzZXRzV2VpZ2h0c0RlY2ltYWxzAAQABVNjYWxlAJBOAAZTY2FsZTgAgMLXLwAHU2NhbGUxMgCAoJSljR0AB1NjYWxlMTYAgICE/qbe4REACEZlZVNjYWxlAJBOABFQb29sVG9rZW5EZWNpbWFscwAIAA5Qb29sVG9rZW5TY2FsZQkAbAYACgAABRFQb29sVG9rZW5EZWNpbWFscwAAAAAFBkhBTEZVUAAQTUlOX1NURVBTX0FNT1VOVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5DT05GSUdfQUREUkVTUwIQbWluX3N0ZXBzX2Ftb3VudAABABBNQVhfU1RFUFNfQU1PVU5UCQELdmFsdWVPckVsc2UCCQCaCAIFDkNPTkZJR19BRERSRVNTAhBtYXhfc3RlcHNfYW1vdW50APQDABJNSU5fU1RFUFNfSU5URVJWQUwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOQ09ORklHX0FERFJFU1MCEm1pbl9zdGVwc19pbnRlcnZhbAABABJNQVhfU1RFUFNfSU5URVJWQUwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOQ09ORklHX0FERFJFU1MCEm1heF9zdGVwc19pbnRlcnZhbACQTgAKTUlOX1dFSUdIVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5DT05GSUdfQUREUkVTUwIKbWluX3dlaWdodABkAApNQVhfV0VJR0hUCQELdmFsdWVPckVsc2UCCQCaCAIFDkNPTkZJR19BRERSRVNTAgptYXhfd2VpZ2h0AKxNAQ10cnlHZXRJbnRlZ2VyAQNrZXkEByRtYXRjaDAJAJoIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACA0ludAQBYgUHJG1hdGNoMAUBYgAAAQx0cnlHZXRCaW5hcnkBA2tleQQHJG1hdGNoMAkAnAgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYgUHJG1hdGNoMAUBYgEAAQx0cnlHZXRTdHJpbmcBA2tleQQHJG1hdGNoMAkAnQgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFiBQckbWF0Y2gwBQFiAgABE3RyeUdldFN0cmluZ09yVGhyb3cBA2tleQQHJG1hdGNoMAkAnQgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFiBQckbWF0Y2gwBQFiCQACAQkArAICAh1ubyBzdWNoIGtleSBpbiBkYXRhIHN0b3JhZ2U6IAUDa2V5AQ5nZXRBc3NldFN0cmluZwEHYXNzZXRJZAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAFiBQckbWF0Y2gwCQDYBAEFAWICBVdBVkVTAQ1nZXRBc3NldEJ5dGVzAQphc3NldElkU3RyAwkAAAIFCmFzc2V0SWRTdHICBVdBVkVTBQR1bml0CQDZBAEFCmFzc2V0SWRTdHIBD2dldFRva2VuQmFsYW5jZQEHYXNzZXRJZAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAF0BQckbWF0Y2gwCQDwBwIFBHRoaXMFAXQICQDvBwEFBHRoaXMJYXZhaWxhYmxlAQ5nZXRGYWN0QmFsYW5jZQEKYXNzZXRJZFN0cgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwUKYXNzZXRJZFN0cgIMX2ZhY3RCYWxhbmNlARNhZGRBc3NldEJ5dGVzVG9MaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAQ1nZXRBc3NldEJ5dGVzAQUEaXRlbQUDbmlsARRhZGRBc3NldFdlaWdodFRvTGlzdAIFYWNjdW0EaXRlbQkAzggCBQVhY2N1bQkAzAgCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfCQEOZ2V0QXNzZXRTdHJpbmcBBQRpdGVtAgdfd2VpZ2h0BQNuaWwBF2FkZEFzc2V0V2VpZ2h0VG9TdHJMaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAKQDAQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUEaXRlbQIHX3dlaWdodAUDbmlsARZhZGRBc3NldERlY2ltYWxzVG9MaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18JAQ5nZXRBc3NldFN0cmluZwEFBGl0ZW0CCV9kZWNpbWFscwUDbmlsARNhZGRBc3NldFNjYWxlVG9MaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18JAQ5nZXRBc3NldFN0cmluZwEFBGl0ZW0CBl9zY2FsZQUDbmlsAQxhZGRJbnRUb0xpc3QCBWFjY3VtBGl0ZW0JAM4IAgUFYWNjdW0JAMwIAgkBDXBhcnNlSW50VmFsdWUBBQRpdGVtBQNuaWwBEXBhcnN0U3RyVG9JbnRMaXN0AQFzCgEBZgIFYWNjdW0EbmV4dAkAzggCBQVhY2N1bQkAzAgCCQENcGFyc2VJbnRWYWx1ZQEFBG5leHQFA25pbAoAAiRsCQC1CQIFAXMCASwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoADnVzZG5Bc3NldElkU3RyCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg51c2RuQXNzZXRJZFN0cgIsREcyeEZrUGREd0tVb0JrekdBaFF0THBTR3pmWExpQ1lQRXplS0gyQWQyNHAAEHB1enpsZUFzc2V0SWRTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCEHB1enpsZUFzc2V0SWRTdHICLEhFQjhRYXc5eHJXcFdzOHRIc2lBVFlHQldEQnRQMlM3a2NQQUxyTXU0M0FTAA51c2R0QXNzZXRJZFN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIOdXNkdEFzc2V0SWRTdHICLDM0TjlZY0VFVExXbjkzcVlRNjRFc1AxeDg5dFNydUpVNDRSckVNU1hYRVBKABF1c2R0UHB0QXNzZXRJZFN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIRdXNkdFBwdEFzc2V0SWRTdHICLDl3YzNMWE5BNFRFQnNYeUt0b0xFOW1yYkREN1dNSFh2WHJDalp2YWJMQXNpAA5yb21lQXNzZXRJZFN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIOcm9tZUFzc2V0SWRTdHICLEFQNENiNXhMWUdINlppZ0hyZUNaSG9YcFFUV0RrUHNHMkJIcWZEVXg2dGFKAA93YXZlc0Fzc2V0SWRTdHICBVdBVkVTAAt1c2RuQXNzZXRJZAkA2QQBBQ51c2RuQXNzZXRJZFN0cgANcHV6emxlQXNzZXRJZAkA2QQBBRBwdXp6bGVBc3NldElkU3RyAAt1c2R0QXNzZXRJZAkA2QQBBQ51c2R0QXNzZXRJZFN0cgAOdXNkdFBwdEFzc2V0SWQJANkEAQURdXNkdFBwdEFzc2V0SWRTdHIAC3JvbWVBc3NldElkCQDZBAEFDnJvbWVBc3NldElkU3RyAAx3YXZlc0Fzc2V0SWQFBHVuaXQAFXN1cHBvcnRlZEZlZUFzc2V0c1N0cgkAzAgCBQ51c2RuQXNzZXRJZFN0cgkAzAgCBRBwdXp6bGVBc3NldElkU3RyCQDMCAIFDnVzZHRBc3NldElkU3RyCQDMCAIFEXVzZHRQcHRBc3NldElkU3RyCQDMCAIFD3dhdmVzQXNzZXRJZFN0cgkAzAgCBQ5yb21lQXNzZXRJZFN0cgUDbmlsABFwYXJlbnRQb29sQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCEXBhcmVudFBvb2xBZGRyZXNzAiMzUEZEZ3p1MVV0c3dBa0NNeHFxUWpiVGVIYVg0Y01hYjhLaAANbWFzdGVyQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDW1hc3RlckFkZHJlc3MCIzNQTGp3SGN6OU5FdWFUbzYzTlpSOUI5b2tRaUtReFpTYm1mAAxtYXN0ZXJQdWJLZXkJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIMbWFzdGVyUHViS2V5AiwyalRKR3FIU29weWo1ZDFjamJVZTZmMmpYcUdNSEU0MTJjeTN2R3dZb1JiUAANb3JhY2xlQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDW9yYWNsZUFkZHJlc3MCIzNQOGQxRTFCTEtvRDUyeTNiUUoxYkRUZDJURDFncGFMbjl0AA5zdGFraW5nQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDnN0YWtpbmdBZGRyZXNzAiMzUEZUYnl3cXh0RmZ1a1gzSHlUODgxZzRpVzVLNFFMM0ZBUwALZmVlc0FkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAgtmZWVzQWRkcmVzcwIjM1BGV0FWS21YamZIWHl6SmIxMmpDYmhQNFVoaTl0NHVXaUQAD3Bvb2xzSHViQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCD3Bvb2xzSHViQWRkcmVzcwIjM1A1UkdZeUNuRUxGOEpUUHhnWDU0ZEJHendrUU1LVUo1SDcAEnNodXRkb3duQWRkcmVzc1N0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIPc2h1dGRvd25BZGRyZXNzAiMzUEVwdjloUkZXRUVCVTIyV1JuTHN3MWJINFlHdGNVNzI4bwAPbGF5ZXIyQWRkcmVzc2VzCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg9sYXllcjJBZGRyZXNzZXMCRzNQUjFRdmk5bUhUMzVTd1dFa0xTcXFFMkw4dGhpUExkVldVLDNQUW9CZlVLSGtKQWVHV2hvb0xQN1dTOG92YjU0YXY5SnAyAApnb3ZBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIKZ292QWRkcmVzcwIjM1A2dXJvOXhDc0U4dGU3OFFaanpxeTdhcThuYXRTemRjZUMAEWNvbGRNYXN0ZXJBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIRY29sZE1hc3RlckFkZHJlc3MCIzNQSzluaFBmUGJNQnlnQjlaZ0hWTUhhUWJTb29qd3JCZnhqAAFUCQENdHJ5R2V0SW50ZWdlcgECE3N0YXRpY190b2tlbnNBbW91bnQACGFzc2V0SWRzCgACJGwJALUJAgkBDHRyeUdldFN0cmluZwECD3N0YXRpY190b2tlbklkcwIBLAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQETYWRkQXNzZXRCeXRlc1RvTGlzdAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgANQXNzZXRzV2VpZ2h0cwoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMV8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEUYWRkQXNzZXRXZWlnaHRUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjFfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYxXzICCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACERlY2ltYWxzCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYyXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARZhZGRBc3NldERlY2ltYWxzVG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYyXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMl8yAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAZTY2FsZXMKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjNfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBE2FkZEFzc2V0U2NhbGVUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjNfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYzXzICCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECCQEFJGYzXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoAA0ZlZQkBDXRyeUdldEludGVnZXIBAgpzdGF0aWNfZmVlAAxlYXJuZWRBc3NldHMFCGFzc2V0SWRzAQRfZ2V0Agdhc3NldElkBXBhcmFtCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfBQdhc3NldElkAgZfcGFyYW0BD19nZXRfZmVlc0Vhcm5lZAEHYXNzZXRJZAkBDXRyeUdldEludGVnZXIBCQCsAgICEmdsb2JhbF9mZWVzRWFybmVkXwUHYXNzZXRJZAEXX2dldF9sYXN0Q2hlY2tfaW50ZXJlc3QBB2Fzc2V0SWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICEWdsb2JhbF9sYXN0Q2hlY2tfBQdhc3NldElkAglfaW50ZXJlc3QBEF9nZXRfZXh0cmFFYXJuZWQBB2Fzc2V0SWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAhNnbG9iYWxfZXh0cmFFYXJuZWRfBQdhc3NldElkARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBB2Fzc2V0SWQEByRtYXRjaDAJAKIIAQkArAICAg1nbG9iYWxQYXJhbXNfBQdhc3NldElkAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcAUHJG1hdGNoMAQGcGFyYW1zCQC1CQIFAXACAl9fCQCaCggJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZwYXJhbXMAAAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnBhcmFtcwABCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcGFyYW1zAAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZwYXJhbXMAAwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnBhcmFtcwAECQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcGFyYW1zAAUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZwYXJhbXMABgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnBhcmFtcwAHCQCaCggJAQRfZ2V0AgUHYXNzZXRJZAIHYmFsYW5jZQkBBF9nZXQCBQdhc3NldElkAgtmYWN0QmFsYW5jZQkBD19nZXRfZmVlc0Vhcm5lZAEFB2Fzc2V0SWQJARdfZ2V0X2xhc3RDaGVja19pbnRlcmVzdAEFB2Fzc2V0SWQJARBfZ2V0X2V4dHJhRWFybmVkAQUHYXNzZXRJZAkBBF9nZXQCBQdhc3NldElkAgdzZWxsb2ZmCQEEX2dldAIFB2Fzc2V0SWQCE3NlbGxvZmZTdGFydEJhbGFuY2UJAQRfZ2V0AgUHYXNzZXRJZAISc2VsbG9mZlN0YXJ0SGVpZ2h0ARVzYXZlR2xvYmFsVG9rZW5QYXJhbXMCB2Fzc2V0SWQGcGFyYW1zCQELU3RyaW5nRW50cnkCCQCsAgICDWdsb2JhbFBhcmFtc18FB2Fzc2V0SWQJALkJAgkAzAgCCQCkAwEIBQZwYXJhbXMCXzEJAMwIAgkApAMBCAUGcGFyYW1zAl8yCQDMCAIJAKQDAQgFBnBhcmFtcwJfMwkAzAgCCQCkAwEIBQZwYXJhbXMCXzQJAMwIAgkApAMBCAUGcGFyYW1zAl81CQDMCAIJAKQDAQgFBnBhcmFtcwJfNgkAzAgCCQCkAwEIBQZwYXJhbXMCXzcJAMwIAgkApAMBCAUGcGFyYW1zAl84BQNuaWwCAl9fAQppc1NodXRkb3duAAQPc2h1dGRvd25BZGRyZXNzCQCmCAEFEnNodXRkb3duQWRkcmVzc1N0cgMJAAACBQ9zaHV0ZG93bkFkZHJlc3MFBHVuaXQHBAckbWF0Y2gwCQCbCAIJAQV2YWx1ZQEFD3NodXRkb3duQWRkcmVzcwILaXNfc2h1dGRvd24DCQABAgUHJG1hdGNoMAIHQm9vbGVhbgQBeAUHJG1hdGNoMAUBeAcBFmdldEN1cnJlbnRUb2tlbkJhbGFuY2UBCHRva2VuTnVtBAp0b2tlbklkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBCQCRAwIFCGFzc2V0SWRzBQh0b2tlbk51bQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwUKdG9rZW5JZFN0cgIIX2JhbGFuY2UBDXN0YWtlSWZOZWVkZWQCCmFzc2V0SWRTdHIGYW1vdW50BAdzdGFrZVR4AwkBAiE9AgkBDHRyeUdldFN0cmluZwEJAKwCAgIXc3RhdGljX3N0YWtpbmdDb250cmFjdF8FCmFzc2V0SWRTdHICAAkA/AcECQERQGV4dHJOYXRpdmUoMTA2MikBCQEMdHJ5R2V0U3RyaW5nAQkArAICAhdzdGF0aWNfc3Rha2luZ0NvbnRyYWN0XwUKYXNzZXRJZFN0cgIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDWdldEFzc2V0Qnl0ZXMBBQphc3NldElkU3RyBQZhbW91bnQFA25pbAUEdW5pdAMJAAACBQdzdGFrZVR4BQdzdGFrZVR4BgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEPdW5zdGFrZUlmTmVlZGVkAgphc3NldElkU3RyBmFtb3VudAQJdW5zdGFrZVR4AwkBAiE9AgkBDHRyeUdldFN0cmluZwEJAKwCAgIXc3RhdGljX3N0YWtpbmdDb250cmFjdF8FCmFzc2V0SWRTdHICAAkA/AcECQERQGV4dHJOYXRpdmUoMTA2MikBCQEMdHJ5R2V0U3RyaW5nAQkArAICAhdzdGF0aWNfc3Rha2luZ0NvbnRyYWN0XwUKYXNzZXRJZFN0cgIHdW5zdGFrZQkAzAgCBQZhbW91bnQFA25pbAUDbmlsBQR1bml0AwkAAAIFCXVuc3Rha2VUeAUJdW5zdGFrZVR4BgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgERYnVybkluZGV4SWZOZWVkZWQBBmFtb3VudAQKaW5kZXhJZFN0cgkBDHRyeUdldFN0cmluZwECFnN0YXRpY19wb29sVG9rZW5faWRTdHIDCQAAAgUKaW5kZXhJZFN0cgIABQNuaWwDCQAAAgkA7AcBCQDZBAEFCmluZGV4SWRTdHIFBHVuaXQFA25pbAkAzAgCCQEEQnVybgIJANkEAQUKaW5kZXhJZFN0cgUGYW1vdW50BQNuaWwBEW1pbnRJbmRleElmTmVlZGVkAQZhbW91bnQECmluZGV4SWRTdHIJAQx0cnlHZXRTdHJpbmcBAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyAwkAAAIFCmluZGV4SWRTdHICAAUDbmlsAwkAAAIJAOwHAQkA2QQBBQppbmRleElkU3RyBQR1bml0BQNuaWwJAMwIAgkBB1JlaXNzdWUDCQDZBAEFCmluZGV4SWRTdHIFBmFtb3VudAYFA25pbAEIZ2V0S011bHQABAckbWF0Y2gwCQCfCAECDHN0YXRpY19LTXVsdAMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgFB1NjYWxlMTYBEnNhdmVDdXJyZW50V2VpZ2h0cwAECmFzc2V0SWRzTGkJALUJAgkBDHRyeUdldFN0cmluZwECD3N0YXRpY190b2tlbklkcwIBLAoBAXMCBWFjY3VtB2Fzc2V0SWQJAM4IAgUFYWNjdW0JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIWcmViYWxhbmNlX3N0YXJ0V2VpZ2h0XwUHYXNzZXRJZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUHYXNzZXRJZAIHX3dlaWdodAUDbmlsCgACJGwFCmFzc2V0SWRzTGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAXMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoBGWdldFZpcnR1YWxQb29sVG9rZW5BbW91bnQACQBrAwkBDXRyeUdldEludGVnZXIBAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAkBCGdldEtNdWx0AAUHU2NhbGUxNgEQY2FsY3VsYXRlUElzc3VlZAIGYW1vdW50B3Rva2VuSWQEB1BzdXBwbHkJARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAQHQmFsYW5jZQkBDmdldEZhY3RCYWxhbmNlAQkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAQCdDEJAG4EBQZhbW91bnQFB1BzdXBwbHkFB0JhbGFuY2UFBERPV04FAnQxAQ1nZXRNaW5QSXNzdWVkAQhwYXltZW50cwoBB2hhbmRsZXICBWFjY3VtB2N1cnJlbnQDCQAAAgkBDmdldEZhY3RCYWxhbmNlAQkBDmdldEFzc2V0U3RyaW5nAQgFB2N1cnJlbnQHYXNzZXRJZAAABQVhY2N1bQQHUElzc3VlZAkBEGNhbGN1bGF0ZVBJc3N1ZWQCCAUHY3VycmVudAZhbW91bnQIBQdjdXJyZW50B2Fzc2V0SWQDCQAAAgUHUElzc3VlZAAACQACAQIkb25lIG9mIHRoZSB0b2tlbnMgYW1vdW50cyBpcyB0b28gbG93AwMJAAACBQVhY2N1bQAABgkAZgIFBWFjY3VtBQdQSXNzdWVkBQdQSXNzdWVkBQVhY2N1bQQJbWluUElzc2VkCgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdoYW5kbGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBQltaW5QSXNzZWQBEmdldFByaWNlRnJvbU9yYWNsZQEKYXNzZXRJZFN0cgQHJG1hdGNoMAkAmggCBQ1vcmFjbGVBZGRyZXNzCQCsAgIFCmFzc2V0SWRTdHICB190d2FwNUIDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4AAABEWNhbGN1bGF0ZVVzZFZhbHVlBAdhc3NldElkBmFtb3VudAhhQmFsYW5jZQ9mZWVBc3NldEJhbGFuY2UEC2Fzc2V0V2VpZ2h0CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfCQEOZ2V0QXNzZXRTdHJpbmcBBQdhc3NldElkAgdfd2VpZ2h0BAtmZWVBc3NldFN0cgkBDHRyeUdldFN0cmluZwECD3N0YXRpY19mZWVUb2tlbgQNZmVlQXNzZXRTY2FsZQkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICCQCsAgICB3N0YXRpY18FC2ZlZUFzc2V0U3RyAgZfc2NhbGUEC2ZlZUFzc2V0TnVtCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzCQENZ2V0QXNzZXRCeXRlcwEFC2ZlZUFzc2V0U3RyBA5mZWVBc3NldFdlaWdodAkAkQMCBQ1Bc3NldHNXZWlnaHRzBQtmZWVBc3NldE51bQQNdmFsSW5GZWVBc3NldAkAawMFBmFtb3VudAkAaQIFD2ZlZUFzc2V0QmFsYW5jZQUOZmVlQXNzZXRXZWlnaHQJAGkCBQhhQmFsYW5jZQULYXNzZXRXZWlnaHQEDWZlZUFzc2V0UHJpY2UJARJnZXRQcmljZUZyb21PcmFjbGUBBQtmZWVBc3NldFN0cgkAawMFDXZhbEluRmVlQXNzZXQFDWZlZUFzc2V0UHJpY2UFDWZlZUFzc2V0U2NhbGUBFGNhbGNBdmdDb25jZW50cmF0aW9uAAoBAWYCBWFjY3VtBG5leHQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFBG5leHQEBndlaWdodAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUKYXNzZXRJZFN0cgIHX3dlaWdodAQQYXNzZXRGYWN0QmFsYW5jZQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwUKYXNzZXRJZFN0cgIMX2ZhY3RCYWxhbmNlBBBhc3NldFZpcnRCYWxhbmNlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfBQphc3NldElkU3RyAghfYmFsYW5jZQkAlAoCCQBkAggFBWFjY3VtAl8xCQBrAwUQYXNzZXRGYWN0QmFsYW5jZQUGd2VpZ2h0BRBhc3NldFZpcnRCYWxhbmNlCQBkAggFBWFjY3VtAl8yBQZ3ZWlnaHQKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARNjaGVja1Rva2Vuc1ZhbGlkaXR5AQhwYXltZW50cwoBCGhhbmRsZXIxAgVhY2N1bQdwYXltZW50CQDOCAIFBWFjY3VtCQDMCAIIBQdwYXltZW50B2Fzc2V0SWQFA25pbAQDaWRzCgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhoYW5kbGVyMQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgMJAAACBQNpZHMFA2lkcwoBCGhhbmRsZXIyAgVhY2N1bQdhc3NldElkAwkBAiE9AgkAzwgCBQNpZHMFB2Fzc2V0SWQFBHVuaXQJAGQCBQVhY2N1bQABCQACAQkArAICAhRhc3NldCBub3QgYXR0YWNoZWQ6IAkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAQGY2hlY2tzCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY1XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhoYW5kbGVyMgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjVfMgIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgMJAAACBQZjaGVja3MFBmNoZWNrcwYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BE2hhbmRsZVBvb2xUb2tlbnNBZGQEB1BJc3N1ZWQIcGF5bWVudHMLdXNlckFkZHJlc3MKbmVlZENoYW5nZQoBFWdldFRva2VuUGF5bWVudEFtb3VudAEHdG9rZW5JZAoBB2hhbmRsZXICBWFjY3VtB3BheW1lbnQDCQAAAggFB3BheW1lbnQHYXNzZXRJZAUHdG9rZW5JZAgFB3BheW1lbnQGYW1vdW50BQVhY2N1bQoAAiRsBQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgoBEWhhbmRsZVRva2VuQ2hhbmdlAgVhY2N1bQd0b2tlbklkBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBBQd0b2tlbklkBAthc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCmFzc2V0SWRTdHIEDXBheW1lbnRBbW91bnQJARVnZXRUb2tlblBheW1lbnRBbW91bnQBBQd0b2tlbklkBAJCawgFC2Fzc2V0UGFyYW1zAl8yBAdQU3VwcGx5CQEZZ2V0VmlydHVhbFBvb2xUb2tlbkFtb3VudAAEDXRva2VuRGVjaW1hbHMJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICBl9zY2FsZQQCYTEJAL0CBAkAuQICCQC2AgEJAGQCBQdQU3VwcGx5BQdQSXNzdWVkCQC2AgEFBlNjYWxlOAkAtgIBBQ10b2tlbkRlY2ltYWxzCQC2AgEFB1BTdXBwbHkFB0NFSUxJTkcEAkRrCQCgAwEJAL0CBAkAuAICBQJhMQkAuQICCQC2AgEFDXRva2VuRGVjaW1hbHMJALYCAQUGU2NhbGU4CQC2AgEFAkJrCQC5AgIJALYCAQUNdG9rZW5EZWNpbWFscwkAtgIBBQZTY2FsZTgFB0NFSUxJTkcECHRvUmV0dXJuCQBlAgUNcGF5bWVudEFtb3VudAUCRGsEB3N0YWtlVHgJAQ1zdGFrZUlmTmVlZGVkAgUKYXNzZXRJZFN0cgUCRGsDCQAAAgUHc3Rha2VUeAUHc3Rha2VUeAQBdAMDBQpuZWVkQ2hhbmdlCQBmAgUIdG9SZXR1cm4AAAcJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFCHRvUmV0dXJuBQd0b2tlbklkBQNuaWwFA25pbAQTc2VsbG9mZlN0YXJ0QmFsYW5jZQMJAQIhPQIIBQthc3NldFBhcmFtcwJfOAkAaAIJAGkCBQZoZWlnaHQAZABkCAULYXNzZXRQYXJhbXMCXzgJAGsDCAULYXNzZXRQYXJhbXMCXzcJAGQCBQdQU3VwcGx5BQdQSXNzdWVkBQdQU3VwcGx5BA5hc3NldFBhcmFtc1VwZAkAmgoICQBrAwgFC2Fzc2V0UGFyYW1zAl8xCQBkAgUHUFN1cHBseQUHUElzc3VlZAUHUFN1cHBseQkAZAIIBQthc3NldFBhcmFtcwJfMgUCRGsIBQthc3NldFBhcmFtcwJfMwgFC2Fzc2V0UGFyYW1zAl80CAULYXNzZXRQYXJhbXMCXzUIBQthc3NldFBhcmFtcwJfNgUTc2VsbG9mZlN0YXJ0QmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl84CQDOCAIJAM4IAgUFYWNjdW0FAXQJAMwIAgkBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIFCmFzc2V0SWRTdHIFDmFzc2V0UGFyYW1zVXBkBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4KAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEWhhbmRsZVRva2VuQ2hhbmdlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARZjYWxjTWludGVkV2l0aE9uZVRva2VuAg9hc3NldEFkZGVkSWRTdHIGYW1vdW50BAdQU3VwcGx5CQEZZ2V0VmlydHVhbFBvb2xUb2tlbkFtb3VudAAEEGFzc2V0RmFjdEJhbGFuY2UJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB2dsb2JhbF8FD2Fzc2V0QWRkZWRJZFN0cgIMX2ZhY3RCYWxhbmNlBBBhc3NldFZpcnRCYWxhbmNlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfBQ9hc3NldEFkZGVkSWRTdHICCF9iYWxhbmNlBAthc3NldFdlaWdodAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUPYXNzZXRBZGRlZElkU3RyAgdfd2VpZ2h0BAphc3NldFNjYWxlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQ9hc3NldEFkZGVkSWRTdHICBl9zY2FsZQQNYXNzZXREZWNpbWFscwkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUPYXNzZXRBZGRlZElkU3RyAglfZGVjaW1hbHMEE1BJc3N1ZWROb011bHRpcGxpZXIJAGsDBQdQU3VwcGx5CQBlAgkAoAMBCQB2BgkAtgIBCQBkAgUKYXNzZXRTY2FsZQkAawMFBmFtb3VudAUKYXNzZXRTY2FsZQUQYXNzZXRWaXJ0QmFsYW5jZQUNYXNzZXREZWNpbWFscwkAtgIBBQthc3NldFdlaWdodAAEAAgFBERPV04FBlNjYWxlOAUGU2NhbGU4BAdhdmdDb25jCQEUY2FsY0F2Z0NvbmNlbnRyYXRpb24ABAdQSXNzdWVkCQBrAwUTUElzc3VlZE5vTXVsdGlwbGllcggFB2F2Z0NvbmMCXzIIBQdhdmdDb25jAl8xCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgdnbG9iYWxfBQ9hc3NldEFkZGVkSWRTdHICDF9mYWN0QmFsYW5jZQkAZAIFEGFzc2V0RmFjdEJhbGFuY2UFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB2dsb2JhbF8FD2Fzc2V0QWRkZWRJZFN0cgIIX2JhbGFuY2UJAGQCBRBhc3NldFZpcnRCYWxhbmNlBQZhbW91bnQFA25pbAUHUElzc3VlZAEWY2FsY1JlZGVlbVdpdGhPbmVUb2tlbgINYXNzZXRPdXRJZFN0cglQUmVkZWVtZWQEB1BTdXBwbHkJARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAQQYXNzZXRGYWN0QmFsYW5jZQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHZ2xvYmFsXwUNYXNzZXRPdXRJZFN0cgIMX2ZhY3RCYWxhbmNlBBBhc3NldFZpcnRCYWxhbmNlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdnbG9iYWxfBQ1hc3NldE91dElkU3RyAghfYmFsYW5jZQQLYXNzZXRXZWlnaHQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FDWFzc2V0T3V0SWRTdHICB193ZWlnaHQECmFzc2V0U2NhbGUJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FDWFzc2V0T3V0SWRTdHICBl9zY2FsZQQNYXNzZXREZWNpbWFscwkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUNYXNzZXRPdXRJZFN0cgIJX2RlY2ltYWxzBBVhbW91bnRPdXROb011bGl0cGxpZXIJAGsDBRBhc3NldFZpcnRCYWxhbmNlCQBlAgUGU2NhbGU4CQCgAwEJAHYGCQC2AgEJAGUCBQphc3NldFNjYWxlCQBrAwUJUFJlZGVlbWVkBQphc3NldFNjYWxlBQdQU3VwcGx5BQ1hc3NldERlY2ltYWxzCQC2AgEJAGsDAJBOAJBOBQthc3NldFdlaWdodAAEAAgFBERPV04FBlNjYWxlOAQHYXZnQ29uYwkBFGNhbGNBdmdDb25jZW50cmF0aW9uAAQJYW1vdW50T3V0CQBrAwUVYW1vdW50T3V0Tm9NdWxpdHBsaWVyCAUHYXZnQ29uYwJfMQgFB2F2Z0NvbmMCXzIDCQBmAgUJYW1vdW50T3V0BRBhc3NldEZhY3RCYWxhbmNlCQACAQI0bm8gYXZhaWxhYmxlIGZhY3QgbGlxdWlkaXR5IHRvIHdpdGhkcmF3IGluIG9uZSB0b2tlbgkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHZ2xvYmFsXwUNYXNzZXRPdXRJZFN0cgIMX2ZhY3RCYWxhbmNlCQBlAgUQYXNzZXRGYWN0QmFsYW5jZQUJYW1vdW50T3V0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHZ2xvYmFsXwUNYXNzZXRPdXRJZFN0cgIIX2JhbGFuY2UJAGUCBRBhc3NldFZpcnRCYWxhbmNlBQlhbW91bnRPdXQFA25pbAUJYW1vdW50T3V0ARZoYW5kbGVQb29sVG9rZW5zUmVkZWVtAglQUmVkZWVtZWQLdXNlckFkZHJlc3MKARFoYW5kbGVUb2tlblJlZGVlbQIFYWNjdW0HdG9rZW5JZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAQLYXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQphc3NldElkU3RyBAJCawgFC2Fzc2V0UGFyYW1zAl8yBAdQU3VwcGx5CQEZZ2V0VmlydHVhbFBvb2xUb2tlbkFtb3VudAAEDXRva2VuRGVjaW1hbHMJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICBl9zY2FsZQQGcHN1cHBsCQC9AgQJALkCAgkAtgIBCQBlAgUHUFN1cHBseQUJUFJlZGVlbWVkCQC2AgEFBlNjYWxlOAkAtgIBBQZTY2FsZTgJALYCAQUHUFN1cHBseQUERE9XTgQGYW1vdW50CQCgAwEJAL0CBAkAuAICCQC2AgEFB1NjYWxlMTYFBnBzdXBwbAkAtgIBBQJCawkAtgIBBQdTY2FsZTE2BQdDRUlMSU5HBAl1bnN0YWtlVHgJAQ91bnN0YWtlSWZOZWVkZWQCBQphc3NldElkU3RyBQZhbW91bnQDCQAAAgUJdW5zdGFrZVR4BQl1bnN0YWtlVHgEE3NlbGxvZmZTdGFydEJhbGFuY2UDCQECIT0CCAULYXNzZXRQYXJhbXMCXzgJAGgCCQBpAgUGaGVpZ2h0AGQAZAgFC2Fzc2V0UGFyYW1zAl84CQBrAwgFC2Fzc2V0UGFyYW1zAl83CQBlAgUHUFN1cHBseQUJUFJlZGVlbWVkBQdQU3VwcGx5BA5hc3NldFBhcmFtc1VwZAkAmgoICQBrAwgFC2Fzc2V0UGFyYW1zAl8xCQBlAgUHUFN1cHBseQUJUFJlZGVlbWVkBQdQU3VwcGx5CQBlAggFC2Fzc2V0UGFyYW1zAl8yBQZhbW91bnQIBQthc3NldFBhcmFtcwJfMwgFC2Fzc2V0UGFyYW1zAl80CAULYXNzZXRQYXJhbXMCXzUIBQthc3NldFBhcmFtcwJfNgUTc2VsbG9mZlN0YXJ0QmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl84CQDOCAIJAM4IAgUFYWNjdW0JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFBmFtb3VudAUHdG9rZW5JZAUDbmlsCQDMCAIJARVzYXZlR2xvYmFsVG9rZW5QYXJhbXMCBQphc3NldElkU3RyBQ5hc3NldFBhcmFtc1VwZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARFoYW5kbGVUb2tlblJlZGVlbQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgESY2FsY3VsYXRlT3V0QW1vdW50BQhBbW91bnRJbgdhc3NldEluCGFzc2V0T3V0CUJhbGFuY2VJbgpCYWxhbmNlT3V0BAdJbmRleEluCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzBQdhc3NldEluBAhJbmRleE91dAkBBXZhbHVlAQkAzwgCBQhhc3NldElkcwUIYXNzZXRPdXQDCQAAAgUHSW5kZXhJbgUISW5kZXhPdXQFCEFtb3VudEluCQBuBAUKQmFsYW5jZU91dAkAZQIJAGgCBQZTY2FsZTgFBlNjYWxlOAkAoAMBCQB2BgkAvQIECQC5AgIJALYCAQUJQmFsYW5jZUluCQC2AgEAkE4JALYCAQkAaAIFBlNjYWxlOAUGU2NhbGU4CQC5AgIJALYCAQkAZAIFCUJhbGFuY2VJbgUIQW1vdW50SW4JALYCAQCQTgUGSEFMRlVQABAJALYCAQkAawMJAJEDAgUNQXNzZXRzV2VpZ2h0cwUHSW5kZXhJbgCAoJSljR0JAJEDAgUNQXNzZXRzV2VpZ2h0cwUISW5kZXhPdXQADAAQBQdDRUlMSU5HCQBoAgUGU2NhbGU4BQZTY2FsZTgFCEhBTEZFVkVOAQtjbGFpbVJlc3VsdAEHYWRkcmVzcwQKYWRkcmVzc1N0cgkApQgBBQdhZGRyZXNzBAtpbmRleEFtb3VudAkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAQLZmVlQXNzZXRTdHIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfZmVlVG9rZW4EDmZlZUFzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQULZmVlQXNzZXRTdHIED2ZlZVRva2VuQmFsYW5jZQgFDmZlZUFzc2V0UGFyYW1zAl8xCgEHaGFuZGxlcgIFYWNjdW0HYXNzZXRJZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAQLYXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQphc3NldElkU3RyBBRjdXJyZW50VG9rZW5JbnRlcmVzdAgFC2Fzc2V0UGFyYW1zAl80BAhhQmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl8xBAxyZXdhcmRBbW91bnQJAGsDBQtpbmRleEFtb3VudAkAZQIFFGN1cnJlbnRUb2tlbkludGVyZXN0CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICCQCsAgIFCmFkZHJlc3NTdHICC19sYXN0Q2hlY2tfBQphc3NldElkU3RyAglfaW50ZXJlc3QFB1NjYWxlMTYECnVuc3Rha2VJbnYJAQ91bnN0YWtlSWZOZWVkZWQCBQphc3NldElkU3RyBQxyZXdhcmRBbW91bnQDCQAAAgUKdW5zdGFrZUludgUKdW5zdGFrZUludgQIdHJhbnNmZXIDCQAAAgUMcmV3YXJkQW1vdW50AAAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQdhZGRyZXNzBQxyZXdhcmRBbW91bnQFB2Fzc2V0SWQFA25pbAkAlAoCCQDOCAIJAM4IAggFBWFjY3VtAl8xBQh0cmFuc2ZlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUKYWRkcmVzc1N0cgILX2xhc3RDaGVja18FCmFzc2V0SWRTdHICCV9pbnRlcmVzdAUUY3VycmVudFRva2VuSW50ZXJlc3QFA25pbAkAZAIIBQVhY2N1bQJfMgkBEWNhbGN1bGF0ZVVzZFZhbHVlBAUHYXNzZXRJZAUMcmV3YXJkQW1vdW50BQhhQmFsYW5jZQUPZmVlVG9rZW5CYWxhbmNlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAVhY2N1bQoAAiRsBQxlYXJuZWRBc3NldHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIFA25pbAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdoYW5kbGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQCUCgIJAM4IAggFBWFjY3VtAl8xCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFkZHJlc3NTdHICEV9jbGFpbWVkUmV3YXJkVVNECQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICEV9jbGFpbWVkUmV3YXJkVVNECAUFYWNjdW0CXzIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgIKX2xhc3RDbGFpbQgFCWxhc3RCbG9jawl0aW1lc3RhbXAFA25pbAgFBWFjY3VtAl8yARBpbmRleFN0YWtlUmVzdWx0AgphZGRyZXNzU3RyBmFtb3VudAQCbGkICQELY2xhaW1SZXN1bHQBCQERQGV4dHJOYXRpdmUoMTA2MikBBQphZGRyZXNzU3RyAl8xCQDOCAIFAmxpCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgISZ2xvYmFsX2luZGV4U3Rha2VkCQBkAgkBDXRyeUdldEludGVnZXIBAhJnbG9iYWxfaW5kZXhTdGFrZWQFBmFtb3VudAUDbmlsAQNzdW0CBWFjY3VtAW4JAGQCBQVhY2N1bQkBDXBhcnNlSW50VmFsdWUBBQFuAQ1jaGVja0ZlZUFzc2V0AgVhY2N1bQRuZXh0AwMJAQIhPQIJAM8IAgUVc3VwcG9ydGVkRmVlQXNzZXRzU3RyBQRuZXh0BQR1bml0CQAAAgUFYWNjdW0CAAcFBG5leHQFBWFjY3VtARJjYWxjSW50ZXJlc3RDaGFuZ2UCCmFzc2V0SWRTdHIFbHBGZWUECnRvdGFsSW5kZXgJAQ10cnlHZXRJbnRlZ2VyAQISZ2xvYmFsX2luZGV4U3Rha2VkBA1pbnRlcmVzdERlbHRhCQBrAwUFbHBGZWUFB1NjYWxlMTYFCnRvdGFsSW5kZXgFDWludGVyZXN0RGVsdGEBDnVwZFNlbGxvZmZEYXRhBAphc3NldElkU3RyCGFtb3VudEluB2JhbGFuY2UNc2VsbG9mZlBhcmFtcwQNY3VycmVudFBlcmlvZAkAaAIJAGkCBQZoZWlnaHQAZABkBApwcmV2UGVyaW9kCAUNc2VsbG9mZlBhcmFtcwJfMgQLcHJldlNlbGxvZmYDCQAAAgUNY3VycmVudFBlcmlvZAUKcHJldlBlcmlvZAgFDXNlbGxvZmZQYXJhbXMCXzEAAAQTc2VsbG9mZlN0YXJ0QmFsYW5jZQMJAAACBQ1jdXJyZW50UGVyaW9kBQpwcmV2UGVyaW9kCAUNc2VsbG9mZlBhcmFtcwJfMwUHYmFsYW5jZQQMc2VsbG9mZkRlbHRhCQBrAwUHU2NhbGUxNgUIYW1vdW50SW4FE3NlbGxvZmZTdGFydEJhbGFuY2UECm1heFNlbGxvZmYJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICC19tYXhTZWxsb2ZmAwMJAGYCCQBkAgULcHJldlNlbGxvZmYFDHNlbGxvZmZEZWx0YQUKbWF4U2VsbG9mZgkBAiE9AgUKbWF4U2VsbG9mZgAABwkAAgEJAKwCAgIjbWF4IHNlbGxvZmYgcmVhY2hlZCBmb3IgdGhpcyBhc3NldCAFCmFzc2V0SWRTdHIEBnN0YXJ0SAMJAAACBQ1jdXJyZW50UGVyaW9kBQpwcmV2UGVyaW9kBQpwcmV2UGVyaW9kBQ1jdXJyZW50UGVyaW9kBAZzdGFydEIDCQAAAgUNY3VycmVudFBlcmlvZAUKcHJldlBlcmlvZAgFDXNlbGxvZmZQYXJhbXMCXzMFE3NlbGxvZmZTdGFydEJhbGFuY2UJAJUKAwkAZAIFC3ByZXZTZWxsb2ZmBQxzZWxsb2ZmRGVsdGEFBnN0YXJ0SAUGc3RhcnRCARJnZXRUbXBSZWJhbGFuY2VJZHMBDW5ld0Fzc2V0SWRzTGkEEWN1cnJlbnRBc3NldElkc0xpCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfdG9rZW5JZHMCASwEBnJlc3VsdAUNbmV3QXNzZXRJZHNMaQoBAWYCBWFjY3VtB2Fzc2V0SWQDCQAAAgkAzwgCBQZyZXN1bHQFB2Fzc2V0SWQFBHVuaXQJAM4IAgUFYWNjdW0JAMwIAgUHYXNzZXRJZAUDbmlsBQVhY2N1bQoAAiRsBRFjdXJyZW50QXNzZXRJZHNMaQoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFBnJlc3VsdAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEBZgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgERY2hlY2tUb2tlbnNDaGFuZ2UBDW5ld0Fzc2V0SWRzTGkEEWN1cnJlbnRBc3NldElkc0xpCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfdG9rZW5JZHMCASwKAQNyZW0CBWFjY3VtB2Fzc2V0SWQDCQAAAgkAzwgCBQ1uZXdBc3NldElkc0xpBQdhc3NldElkBQR1bml0CQBkAgUFYWNjdW0AAQUFYWNjdW0KAQNhZGQCBWFjY3VtB2Fzc2V0SWQDCQAAAgkAzwgCBRFjdXJyZW50QXNzZXRJZHNMaQUHYXNzZXRJZAUEdW5pdAkAZAIFBWFjY3VtAAEFBWFjY3VtBAdyZW1vdmVkCgACJGwFEWN1cnJlbnRBc3NldElkc0xpCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQNyZW0CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEBWFkZGVkCgACJGwFDW5ld0Fzc2V0SWRzTGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjVfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBA2FkZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjVfMgIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgkAZAIFB3JlbW92ZWQFBWFkZGVkARB2YWxpZGF0ZVBheW1lbnRzAgphc3NldHNMaXN0CHBheW1lbnRzCgEQZ2V0UGF5bWVudEFzc2V0cwIFYWNjdW0EbmV4dAMJAGcCAAAIBQRuZXh0BmFtb3VudAkAAgEJAKwCAgkArAICCQCsAgICG1RvbyBsb3cgcGF5bWVudCBhbW91bnQgZm9yIAkBDmdldEFzc2V0U3RyaW5nAQgFBG5leHQHYXNzZXRJZAICOiAJAKQDAQgFBG5leHQGYW1vdW50CQDOCAIFBWFjY3VtCQDMCAIJAQ5nZXRBc3NldFN0cmluZwEIBQRuZXh0B2Fzc2V0SWQFA25pbAQLcGF5bWVudExpc3QKAAIkbAUIcGF5bWVudHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEGdldFBheW1lbnRBc3NldHMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoKAQJmMQIFYWNjdW0EbmV4dAMJAAACCQDPCAIFCmFzc2V0c0xpc3QFBG5leHQFBHVuaXQJAAIBCQCsAgIJAKwCAgUEbmV4dAI5IGFzc2V0IGlzIHByZXNlbnQgaW4gcGF5bWVudHMsIGJ1dCBpcyBub3QgaW4gbmV3IGFzc2V0czogCQC5CQIFCmFzc2V0c0xpc3QCASwJAGQCBQVhY2N1bQABCgECZjICBWFjY3VtBG5leHQDCQAAAgkAzwgCBQtwYXltZW50TGlzdAUEbmV4dAUEdW5pdAkAAgEJAKwCAgkArAICBQRuZXh0AjkgYXNzZXQgaXMgcHJlc2VudCBpbiBuZXcgYXNzZXRzLCBidXQgaXMgbm90IGluIHBheW1lbnRzOiAJALkJAgULcGF5bWVudExpc3QCASwJAGQCBQVhY2N1bQABBAJhMQoAAiRsBQtwYXltZW50TGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmNV8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQECZjECBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjVfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY1XzICCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEAmEyCgACJGwFCmFzc2V0c0xpc3QKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjZfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAmYyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY2XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNl8yAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQBkAgUCYTEFAmEyAQ92YWxpZGF0ZVdlaWdodHMBB3dlaWdodHMKAQF2AgVhY2N1bQF3BAR3SW50CQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQUBdwkArAICAhVXcm9uZyB3ZWlnaHQgZm9ybWF0OiAFAXcDAwkAZgIFCk1JTl9XRUlHSFQFBHdJbnQGCQBmAgUEd0ludAUKTUFYX1dFSUdIVAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhpXZWlnaHQgc2hvdWxkIGJlIGluIHJhbmdlIAkApAMBBQpNSU5fV0VJR0hUAgMgLSAJAKQDAQUKTUFYX1dFSUdIVAILLCBjdXJyZW50OiAFAXcJAGQCBQVhY2N1bQUEd0ludAoAAiRsBQd3ZWlnaHRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQF2AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAQdnZXRQMVAyAgphc3NldElkU3RyDmJhc2VBc3NldElkU3RyBAthc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCmFzc2V0SWRTdHIED2Jhc2VBc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFDmJhc2VBc3NldElkU3RyBAJCMQgFD2Jhc2VBc3NldFBhcmFtcwJfMQQCQjIIBQthc3NldFBhcmFtcwJfMQQCRjEIBQ9iYXNlQXNzZXRQYXJhbXMCXzIEAkYyCAULYXNzZXRQYXJhbXMCXzIEAlMxCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQ5iYXNlQXNzZXRJZFN0cgIGX3NjYWxlBAJTMgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUKYXNzZXRJZFN0cgIGX3NjYWxlBAJEMQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUOYmFzZUFzc2V0SWRTdHICCV9kZWNpbWFscwQCRDIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICCV9kZWNpbWFscwQCVzEJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FDmJhc2VBc3NldElkU3RyAgdfd2VpZ2h0BAJXMgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUKYXNzZXRJZFN0cgIHX3dlaWdodAQEVzFXMgkAawMFAlcxAJBOBQJXMgQEVzJXMQkAawMFAlcyAJBOBQJXMQQNcDFfdW53ZWlnaHRlZAkAawMJAGUCBQJCMQUCRjEFAlMxCQBrAwUCQjIJAGwGCQBrAwUCQjEFAlMxCQBlAgUCQjEFAkYxBQJEMQUEVzFXMgAEBQJEMQUHQ0VJTElORwUCUzIEAnAxCQBrAwUNcDFfdW53ZWlnaHRlZAUEVzJXMQCQTgMJAAACBQJCMgUCRjIJAJQKAgUCcDEFBHVuaXQEDXAyX3Vud2VpZ2h0ZWQJAGsDCQBrAwUCQjEJAGwGCQBrAwUCQjIFAlMyCQBlAgUCQjIFAkYyBQJEMgUEVzJXMQAEBQJEMgUFRkxPT1IFAlMyBQJTMgkAZQIFAkIyBQJGMgQCcDIJAGsDBQ1wMl91bndlaWdodGVkBQRXMlcxAJBOCQCUCgIFAnAxBQJwMhEBaQETYWRkVW5kZXJseWluZ1N0YWtlcgINc3Rha2VyQWRkcmVzcwphc3NldElkU3RyAwkBAiE9AgUEdGhpcwgFAWkGY2FsbGVyCQACAQIKYWRtaW4gb25seQkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgICF3N0YXRpY19zdGFraW5nQ29udHJhY3RfBQphc3NldElkU3RyBQ1zdGFrZXJBZGRyZXNzBQNuaWwBaQEHcHJlSW5pdAcLYXNzZXRJZHNTdHIPYXNzZXRXZWlnaHRzU3RyEmFzc2V0TWF4U2VsbG9mZlN0cg5iYXNlVG9rZW5JZFN0cgpwb29sRG9tYWluCXBvb2xPd25lcgNmZWUEEHBvb2xPd25lckFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCXBvb2xPd25lcgQNYXNzZXRJZHNTdHJMaQkAtQkCBQthc3NldElkc1N0cgIBLAQUYXNzZXRNYXhTZWxsb2ZmU3RyTGkJALUJAgUSYXNzZXRNYXhTZWxsb2ZmU3RyAgEsBBFhc3NldFdlaWdodHNTdHJMaQkAtQkCBQ9hc3NldFdlaWdodHNTdHICASwECmFzc2V0SWRzTGkKAAIkbAUNYXNzZXRJZHNTdHJMaQoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQETYWRkQXNzZXRCeXRlc1RvTGlzdAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQRZmVlQXNzZXRDaG9zZW5TdHIKAAIkbAUNYXNzZXRJZHNTdHJMaQoAAiRzCQCQAwEFAiRsCgAFJGFjYzACAAoBBSRmNV8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQENY2hlY2tGZWVBc3NldAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjVfMgIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQLZmVlQXNzZXRTdHIDCQAAAgURZmVlQXNzZXRDaG9zZW5TdHICAAUOYmFzZVRva2VuSWRTdHIFEWZlZUFzc2V0Q2hvc2VuU3RyAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAMJAQIhPQIFBHRoaXMIBQFpBmNhbGxlcgkAAgECCmFkbWluIG9ubHkDCQBmAgkAsQIBBQpwb29sRG9tYWluAA0JAAIBAhV0b28gbGFyZ2UgcG9vbCBkb21haW4DAwkAZgIFA2ZlZQD0AwYJAGYCAAAFA2ZlZQkAAgECKmZlZSB2YWx1ZSBtdXN0IGJlIGJldHdlZW4gMCBhbmQgNTAwICgwLTUlKQMJAQIhPQIJAQ92YWxpZGF0ZVdlaWdodHMBBRFhc3NldFdlaWdodHNTdHJMaQCQTgkAAgEJAKwCAgImd2VpZ2h0cyBzdW0gc2hvdWxkIGJlIDEwMDAwLCBjdXJyZW50OiAJAKQDAQkBD3ZhbGlkYXRlV2VpZ2h0cwEFEWFzc2V0V2VpZ2h0c1N0ckxpCgETYWRkVG9rZW5EYXRhRW50cmllcwIFYWNjdW0IYXNzZXROdW0DCQBnAgUIYXNzZXROdW0JAJADAQUKYXNzZXRJZHNMaQUFYWNjdW0EE2Fzc2V0U3Rha2luZ0FkZHJlc3MKAAFACQD8BwQFD3Bvb2xzSHViQWRkcmVzcwIQdXNlRW1wdHlDb250cmFjdAkAzAgCCQCsAgICB3N0YWtlcl8JAJEDAgUNYXNzZXRJZHNTdHJMaQUIYXNzZXROdW0FA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwMJAAACBRNhc3NldFN0YWtpbmdBZGRyZXNzBRNhc3NldFN0YWtpbmdBZGRyZXNzBA1hc3NldERlY2ltYWxzBAckbWF0Y2gwCQCRAwIFCmFzc2V0SWRzTGkFCGFzc2V0TnVtAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAXgFByRtYXRjaDAICQEFdmFsdWUBCQDsBwEFAXgIZGVjaW1hbHMACAkAzggCCQDOCAIFBWFjY3VtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHc3RhdGljXwkAkQMCBQ1hc3NldElkc1N0ckxpBQhhc3NldE51bQIGX3NjYWxlCQBsBgAKAAAFDWFzc2V0RGVjaW1hbHMAAAAABQRET1dOCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHc3RhdGljXwkAkQMCBQ1hc3NldElkc1N0ckxpBQhhc3NldE51bQIJX2RlY2ltYWxzBQ1hc3NldERlY2ltYWxzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHc3RhdGljXwkAkQMCBQ1hc3NldElkc1N0ckxpBQhhc3NldE51bQIHX3dlaWdodAkBBXZhbHVlAQkAtgkBCQCRAwIFEWFzc2V0V2VpZ2h0c1N0ckxpBQhhc3NldE51bQkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgICF3N0YXRpY19zdGFraW5nQ29udHJhY3RfCQCRAwIFDWFzc2V0SWRzU3RyTGkFCGFzc2V0TnVtBRNhc3NldFN0YWtpbmdBZGRyZXNzBQNuaWwDCQAAAgkAkQMCBRRhc3NldE1heFNlbGxvZmZTdHJMaQUIYXNzZXROdW0CAAUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHc3RhdGljXwkAkQMCBQ1hc3NldElkc1N0ckxpBQhhc3NldE51bQILX21heFNlbGxvZmYJAGgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUUYXNzZXRNYXhTZWxsb2ZmU3RyTGkFCGFzc2V0TnVtBQdTY2FsZTEyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAM4IAgoAAiRsCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFCQDMCAIABgkAzAgCAAcJAMwIAgAICQDMCAIACQUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY2XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARNhZGRUb2tlbkRhdGFFbnRyaWVzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY2XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNl8yAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQDMCAIJAQtTdHJpbmdFbnRyeQICD3N0YXRpY190b2tlbklkcwULYXNzZXRJZHNTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgIPc3RhdGljX2ZlZVRva2VuBQtmZWVBc3NldFN0cgkAzAgCCQELU3RyaW5nRW50cnkCAhNzdGF0aWNfdG9rZW5XZWlnaHRzBQ9hc3NldFdlaWdodHNTdHIJAMwIAgkBDEludGVnZXJFbnRyeQICE3N0YXRpY190b2tlbnNBbW91bnQJAJADAQUKYXNzZXRJZHNMaQkAzAgCCQELU3RyaW5nRW50cnkCAhFzdGF0aWNfcG9vbERvbWFpbgUKcG9vbERvbWFpbgkAzAgCCQELU3RyaW5nRW50cnkCAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyAgAJAMwIAgkBC1N0cmluZ0VudHJ5AgISc3RhdGljX2Jhc2VUb2tlbklkBQ5iYXNlVG9rZW5JZFN0cgkAzAgCCQELU3RyaW5nRW50cnkCAhBzdGF0aWNfcG9vbE93bmVyBQlwb29sT3duZXIJAMwIAgkBDEludGVnZXJFbnRyeQICCnN0YXRpY19mZWUFA2ZlZQkAzAgCCQEMSW50ZWdlckVudHJ5AgIMc3RhdGljX0tNdWx0BQdTY2FsZTE2CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgITZ2xvYmFsX3dhc1ByZUluaXRlZAABBQNuaWwBaQEGZGVJbml0AAMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3ADCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAgphZG1pbiBvbmx5CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhBnbG9iYWxfd2FzSW5pdGVkAAAFA25pbAFpAQRpbml0Bwthc3NldElkc1N0cg9hc3NldFdlaWdodHNTdHISYXNzZXRNYXhTZWxsb2ZmU3RyDmJhc2VUb2tlbklkU3RyCnBvb2xEb21haW4DZmVlDHZCYWxhbmNlc1N0cgQKcHJlSW5pdEludgkA/AcEBQR0aGlzAgdwcmVJbml0CQDMCAIFC2Fzc2V0SWRzU3RyCQDMCAIFD2Fzc2V0V2VpZ2h0c1N0cgkAzAgCBRJhc3NldE1heFNlbGxvZmZTdHIJAMwIAgUOYmFzZVRva2VuSWRTdHIJAMwIAgUKcG9vbERvbWFpbgkAzAgCCQClCAEIBQFpBmNhbGxlcgkAzAgCBQNmZWUFA25pbAUDbmlsAwkAAAIFCnByZUluaXRJbnYFCnByZUluaXRJbnYECXZCYWxhbmNlcwkBEXBhcnN0U3RyVG9JbnRMaXN0AQUMdkJhbGFuY2VzU3RyCgEQZ2V0UGF5bWVudEFtb3VudAEKYXNzZXRJZFN0cgoBB2hhbmRsZXICBWFjY3VtB3BheW1lbnQDCQAAAgkBDmdldEFzc2V0U3RyaW5nAQgFB3BheW1lbnQHYXNzZXRJZAULYXNzZXRJZHNTdHIIBQdwYXltZW50BmFtb3VudAUFYWNjdW0KAAIkbAgFAWkIcGF5bWVudHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoKAQtwcmVwYXJlTGlzdAAKAQdoYW5kbGVyAgVhY2N1bQdhc3NldElkBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBBQdhc3NldElkBAFuCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzBQdhc3NldElkBA1wYXltZW50QW1vdW50CQEQZ2V0UGF5bWVudEFtb3VudAEFCmFzc2V0SWRTdHIEC2Fzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKYXNzZXRJZFN0cgQOYXNzZXRQYXJhbXNVcGQJAJoKCAkAkQMCBQl2QmFsYW5jZXMFAW4FDXBheW1lbnRBbW91bnQIBQthc3NldFBhcmFtcwJfMwgFC2Fzc2V0UGFyYW1zAl80CAULYXNzZXRQYXJhbXMCXzUIBQthc3NldFBhcmFtcwJfNggFC2Fzc2V0UGFyYW1zAl83CAULYXNzZXRQYXJhbXMCXzgJAM4IAgUFYWNjdW0JAMwIAgkBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIFCmFzc2V0SWRTdHIFDmFzc2V0UGFyYW1zVXBkBQNuaWwKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoKARljYWxjdWxhdGVQb29sVG9rZW5zQW1vdW50AQdhc3NldElkCgEHaGFuZGxlcgIFYWNjdW0HYXNzZXRJZAoBCGhhbmRsZXIyAgVhY2N1bQFuAwkAAAIFAW4FB2Fzc2V0SWQJAQV2YWx1ZQEJAM8IAgUIYXNzZXRJZHMFAW4FBWFjY3VtBAVUb2tlbgoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAQoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIaGFuZGxlcjICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoJAGsDBQVhY2N1bQkAbAYJAJEDAgUJdkJhbGFuY2VzBQVUb2tlbgkAkQMCBQhEZWNpbWFscwUFVG9rZW4JAJEDAgUNQXNzZXRzV2VpZ2h0cwUFVG9rZW4FFUFzc2V0c1dlaWdodHNEZWNpbWFscwAIBQVGTE9PUgUGU2NhbGU4CgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUOUG9vbFRva2VuU2NhbGUKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECOWF0IGxlYXN0IHNvbWUgb2YgdGhlIGFzc2V0cyBzaG91bGQgYmUgcHJvdmlkZWQgYXMgcGF5bWVudAMJAGYCCQENdHJ5R2V0SW50ZWdlcgECEGdsb2JhbF93YXNJbml0ZWQAAAkAAgECE3Bvb2wgYWxyZWFkeSBpbml0ZWQEEWluaXRpYWxQb29sVG9rZW5zCQEZY2FsY3VsYXRlUG9vbFRva2Vuc0Ftb3VudAEFCGFzc2V0SWRzBAxub3RpZnlJbnZva2UJAPwHBAUPcG9vbHNIdWJBZGRyZXNzAgthZGRTZWxmUG9vbAUDbmlsBQNuaWwDCQAAAgUMbm90aWZ5SW52b2tlBQxub3RpZnlJbnZva2UDCQAAAgURaW5pdGlhbFBvb2xUb2tlbnMAAAkAAgECMnlvdSBuZWVkIGEgYmlnZ2VyIHRva2VucyBhbW91bnQgdG8gbGF1bmNoIHRoZSBwb29sCQDOCAIJAQtwcmVwYXJlTGlzdAAJAMwIAgkBDEludGVnZXJFbnRyeQICF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50BRFpbml0aWFsUG9vbFRva2VucwkAzAgCCQEMSW50ZWdlckVudHJ5AgIQZ2xvYmFsX3dhc0luaXRlZAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgxfaW5kZXhTdGFrZWQFEWluaXRpYWxQb29sVG9rZW5zCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQFEWluaXRpYWxQb29sVG9rZW5zBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQENZ2VuZXJhdGVJbmRleAEKbmVlZENoYW5nZQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMFAVQJAAIBCQCsAgICO3lvdSBuZWVkIHRvIGF0dGFjaCBhbGwgcG9vbCB0b2tlbnMuIGFtb3VudCBvZiBwb29sIHRva2VuczogCQCkAwEFAVQDCQEBIQEJARNjaGVja1Rva2Vuc1ZhbGlkaXR5AQgFAWkIcGF5bWVudHMJAAIBAhV3cm9uZyBhc3NldHMgYXR0YWNoZWQEDVBJc3N1ZWROb011bHQJAQ1nZXRNaW5QSXNzdWVkAQgFAWkIcGF5bWVudHMEBnJlc3VsdAkBE2hhbmRsZVBvb2xUb2tlbnNBZGQEBQ1QSXNzdWVkTm9NdWx0CAUBaQhwYXltZW50cwgFAWkMb3JpZ2luQ2FsbGVyBQpuZWVkQ2hhbmdlBA9QSXNzdWVkV2l0aE11bHQJAG4EBQ1QSXNzdWVkTm9NdWx0BQdTY2FsZTE2CQEIZ2V0S011bHQABQRET1dOCQCUCgIJAM4IAgkAzggCCQDOCAIFBnJlc3VsdAgJAQtjbGFpbVJlc3VsdAEIBQFpBmNhbGxlcgJfMQkBEW1pbnRJbmRleElmTmVlZGVkAQUPUElzc3VlZFdpdGhNdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgxfaW5kZXhTdGFrZWQJAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkApQgBCAUBaQZjYWxsZXICDF9pbmRleFN0YWtlZAUPUElzc3VlZFdpdGhNdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQJAGQCCQENdHJ5R2V0SW50ZWdlcgECEmdsb2JhbF9pbmRleFN0YWtlZAUPUElzc3VlZFdpdGhNdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQFD1BJc3N1ZWRXaXRoTXVsdAUDbmlsBQ9QSXNzdWVkV2l0aE11bHQBaQELcmVkZWVtSW5kZXgBD3Bvb2xUb2tlbkFtb3VudAMJAGYCBQ9wb29sVG9rZW5BbW91bnQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQClCAEIBQFpBmNhbGxlcgIMX2luZGV4U3Rha2VkCQACAQIsdXNlciBkb2Vzbid0IGhhdmUgdGhpcyBhbW91bnQgb2YgcG9vbCB0b2tlbnMDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wBBFQUmVkZWVtZWRXaXRoTXVsdAUPcG9vbFRva2VuQW1vdW50BBNQUmVkZWVtZWRXaXRoTm9NdWx0CQBuBAURUFJlZGVlbWVkV2l0aE11bHQJAQhnZXRLTXVsdAAFB1NjYWxlMTYFBERPV04EBnJlc3VsdAkBFmhhbmRsZVBvb2xUb2tlbnNSZWRlZW0CBRNQUmVkZWVtZWRXaXRoTm9NdWx0CAUBaQZjYWxsZXIJAM4IAgkAzggCCQDOCAIFBnJlc3VsdAgJAQtjbGFpbVJlc3VsdAEIBQFpBmNhbGxlcgJfMQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQClCAEIBQFpBmNhbGxlcgIMX2luZGV4U3Rha2VkCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgxfaW5kZXhTdGFrZWQFEVBSZWRlZW1lZFdpdGhNdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQJAGUCCQENdHJ5R2V0SW50ZWdlcgECEmdsb2JhbF9pbmRleFN0YWtlZAURUFJlZGVlbWVkV2l0aE11bHQJAMwIAgkBDEludGVnZXJFbnRyeQICF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50CQBlAgkBDXRyeUdldEludGVnZXIBAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAURUFJlZGVlbWVkV2l0aE11bHQFA25pbAkBEWJ1cm5JbmRleElmTmVlZGVkAQUPcG9vbFRva2VuQW1vdW50AWkBCnN0YWtlSW5kZXgABAphZGRyZXNzU3RyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQJANkEAQkBDHRyeUdldFN0cmluZwECFnN0YXRpY19wb29sVG9rZW5faWRTdHIJAAIBAhR3cm9uZyBhc3NldCBhdHRhY2hlZAkBEGluZGV4U3Rha2VSZXN1bHQCBQphZGRyZXNzU3RyCAUDcG10BmFtb3VudAFpAQ1zdGFrZUluZGV4Rm9yAQphZGRyZXNzU3RyBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAkA2QQBCQEMdHJ5R2V0U3RyaW5nAQIWc3RhdGljX3Bvb2xUb2tlbl9pZFN0cgkAAgECFHdyb25nIGFzc2V0IGF0dGFjaGVkCQEQaW5kZXhTdGFrZVJlc3VsdAIFCmFkZHJlc3NTdHIIBQNwbXQGYW1vdW50AWkBDHVuc3Rha2VJbmRleAELaW5kZXhBbW91bnQKAQppc3N1ZUluZGV4AAQFaXNzdWUJAMMIBwkArAICAgNQUiAJAQx0cnlHZXRTdHJpbmcBAhFzdGF0aWNfcG9vbERvbWFpbgISUHV6emxlIFJhbmdlIEluZGV4CQENdHJ5R2V0SW50ZWdlcgECF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50BRFQb29sVG9rZW5EZWNpbWFscwYFBHVuaXQAAAQOcG9vbFRva2VuSWRTdHIJANgEAQkAuAgBBQVpc3N1ZQkAlAoCCQDMCAIFBWlzc3VlCQDMCAIJAQtTdHJpbmdFbnRyeQICFnN0YXRpY19wb29sVG9rZW5faWRTdHIFDnBvb2xUb2tlbklkU3RyBQNuaWwFDnBvb2xUb2tlbklkU3RyBA0kdDA0MTk1NDQyMTIwAwkAAAIJAQx0cnlHZXRTdHJpbmcBAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyAgAJAQppc3N1ZUluZGV4AAkAlAoCBQNuaWwJAQx0cnlHZXRTdHJpbmcBAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyBBRwb29sVG9rZW5Jc3N1ZVJlc3VsdAgFDSR0MDQxOTU0NDIxMjACXzEEDnBvb2xUb2tlbklkU3RyCAUNJHQwNDE5NTQ0MjEyMAJfMgQLcG9vbFRva2VuSWQJANkEAQUOcG9vbFRva2VuSWRTdHIECmFkZHJlc3NTdHIJAKUIAQgFAWkGY2FsbGVyBA5pbmRleEF2YWlsYWJsZQkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3ADCQBmAgULaW5kZXhBbW91bnQFDmluZGV4QXZhaWxhYmxlCQACAQIleW91IGRvbid0IGhhdmUgaW5kZXggdG9rZW5zIGF2YWlsYWJsZQMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AJAM4IAgkAzggCBRRwb29sVG9rZW5Jc3N1ZVJlc3VsdAgJAQtjbGFpbVJlc3VsdAEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCmFkZHJlc3NTdHICXzEJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgIMX2luZGV4U3Rha2VkCQBlAgUOaW5kZXhBdmFpbGFibGUFC2luZGV4QW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQJAGUCCQENdHJ5R2V0SW50ZWdlcgECEmdsb2JhbF9pbmRleFN0YWtlZAULaW5kZXhBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQtpbmRleEFtb3VudAULcG9vbFRva2VuSWQFA25pbAFpARFjbGFpbUluZGV4UmV3YXJkcwADCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wCQELY2xhaW1SZXN1bHQBCAUBaQZjYWxsZXIBaQENZXZhbHVhdGVDbGFpbQEEdXNlcgkAlAoCBQNuaWwICQELY2xhaW1SZXN1bHQBCQERQGV4dHJOYXRpdmUoMTA2MikBBQR1c2VyAl8yAWkBE2FkZEludGVyZXN0RXh0ZXJuYWwABAdhc3NldElkCAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFB2Fzc2V0SWQEBmFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEB3N0YWtlVHgJAQ1zdGFrZUlmTmVlZGVkAgUKYXNzZXRJZFN0cgUGYW1vdW50AwkAAAIFB3N0YWtlVHgFB3N0YWtlVHgDCQAAAgkAzwgCBQhhc3NldElkcwUHYXNzZXRJZAUEdW5pdAkAAgECMHlvdSBjYW4gb25seSBhZGQgaW50ZXJlc3QgZm9yIGFzc2V0cyBpbiB0aGUgcG9vbAQGcGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKYXNzZXRJZFN0cgQNaW50ZXJlc3REZWx0YQkBEmNhbGNJbnRlcmVzdENoYW5nZQIFCmFzc2V0SWRTdHIFBmFtb3VudAQJdXBkUGFyYW1zCQCaCggIBQZwYXJhbXMCXzEIBQZwYXJhbXMCXzIIBQZwYXJhbXMCXzMJAGQCCAUGcGFyYW1zAl80BQ1pbnRlcmVzdERlbHRhCQBkAggFBnBhcmFtcwJfNQUGYW1vdW50CAUGcGFyYW1zAl82CAUGcGFyYW1zAl83CAUGcGFyYW1zAl84CQDMCAIJARVzYXZlR2xvYmFsVG9rZW5QYXJhbXMCBQphc3NldElkU3RyBQl1cGRQYXJhbXMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARRub3RpZnlTdGFraW5nUGF5bWVudAIKYXNzZXRJZFN0cgZhbW91bnQEB2Fzc2V0SWQJAQ1nZXRBc3NldEJ5dGVzAQUKYXNzZXRJZFN0cgMJAAACCQDPCAIFCGFzc2V0SWRzBQdhc3NldElkBQR1bml0CQACAQIweW91IGNhbiBvbmx5IGFkZCBpbnRlcmVzdCBmb3IgYXNzZXRzIGluIHRoZSBwb29sAwkBAiE9AgkBDHRyeUdldFN0cmluZwEJAKwCAgIXc3RhdGljX3N0YWtpbmdDb250cmFjdF8FCmFzc2V0SWRTdHIJAKUIAQgFAWkGY2FsbGVyCQACAQImY2FuIG9ubHkgYmUgaW52b2tlZCBieSBzdGFrZXIgY29udHJhY3QEBnBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCmFzc2V0SWRTdHIEDWludGVyZXN0RGVsdGEJARJjYWxjSW50ZXJlc3RDaGFuZ2UCBQphc3NldElkU3RyBQZhbW91bnQECXVwZFBhcmFtcwkAmgoICAUGcGFyYW1zAl8xCAUGcGFyYW1zAl8yCAUGcGFyYW1zAl8zCQBkAggFBnBhcmFtcwJfNAUNaW50ZXJlc3REZWx0YQkAZAIIBQZwYXJhbXMCXzUFBmFtb3VudAgFBnBhcmFtcwJfNggFBnBhcmFtcwJfNwgFBnBhcmFtcwJfOAkAzAgCCQEVc2F2ZUdsb2JhbFRva2VuUGFyYW1zAgUKYXNzZXRJZFN0cgUJdXBkUGFyYW1zBQNuaWwBaQEEc3dhcAIIYXNzZXRPdXQHbWluaW11bQQDcG10AwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAACQACAQIhcGxlYXNlIGF0dGFjaCBleGFjdGx5IG9uZSBwYXltZW50BAhBbW91bnRJbgkBBXZhbHVlAQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEB0Fzc2V0SW4IBQNwbXQHYXNzZXRJZAQIQXNzZXRPdXQJAQ1nZXRBc3NldEJ5dGVzAQUIYXNzZXRPdXQEB2Fzc2V0SW4JAQ5nZXRBc3NldFN0cmluZwEFB0Fzc2V0SW4EB3NjYWxlSW4JAGkCBQZTY2FsZTgJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FB2Fzc2V0SW4CBl9zY2FsZQQIc2NhbGVPdXQJAGkCBQZTY2FsZTgJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCGFzc2V0T3V0AgZfc2NhbGUEDWFzc2V0SW5QYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBCQEOZ2V0QXNzZXRTdHJpbmcBBQdBc3NldEluBA5hc3NldE91dFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCGFzc2V0T3V0BA5Bc3NldEluQmFsYW5jZQgFDWFzc2V0SW5QYXJhbXMCXzEEEkFzc2V0SW5GYWN0QmFsYW5jZQgFDWFzc2V0SW5QYXJhbXMCXzIEEWFzc2V0SW5GZWVzRWFybmVkCAUNYXNzZXRJblBhcmFtcwJfMwQYYXNzZXRJbkxhc3RDaGVja0ludGVyZXN0CAUNYXNzZXRJblBhcmFtcwJfNAQPQXNzZXRPdXRCYWxhbmNlCAUOYXNzZXRPdXRQYXJhbXMCXzEEE2Fzc2V0T3V0RmFjdEJhbGFuY2UIBQ5hc3NldE91dFBhcmFtcwJfMgQUQXNzZXRJbkJhbGFuY2VTY2FsZWQJAGgCBQ5Bc3NldEluQmFsYW5jZQUHc2NhbGVJbgQVQXNzZXRPdXRCYWxhbmNlU2NhbGVkCQBoAgUPQXNzZXRPdXRCYWxhbmNlBQhzY2FsZU91dAQLZmVlQW1vdW50SW4JAGsDBQhBbW91bnRJbgUDRmVlBQhGZWVTY2FsZQQNY2xlYW5BbW91bnRJbgkAZQIFCEFtb3VudEluBQtmZWVBbW91bnRJbgQTY2xlYW5BbW91bnRJblNjYWxlZAkAaAIFDWNsZWFuQW1vdW50SW4FB3NjYWxlSW4ECkFtb3VudE91dDEJARJjYWxjdWxhdGVPdXRBbW91bnQFBRNjbGVhbkFtb3VudEluU2NhbGVkBQdBc3NldEluBQhBc3NldE91dAUUQXNzZXRJbkJhbGFuY2VTY2FsZWQFFUFzc2V0T3V0QmFsYW5jZVNjYWxlZAQJQW1vdW50T3V0CQBrAwUKQW1vdW50T3V0MQABBQhzY2FsZU91dAQQQXNzZXRPdXRCYWxhbmNlMgkAZQIFD0Fzc2V0T3V0QmFsYW5jZQUJQW1vdW50T3V0BA9Bc3NldEluQmFsYW5jZTIJAGQCBQ5Bc3NldEluQmFsYW5jZQUNY2xlYW5BbW91bnRJbgMJAGYCBQdtaW5pbXVtBQlBbW91bnRPdXQJAAIBAilhbW91bnQgdG8gcmVjaWV2ZSBpcyBsb3dlciB0aGFuIGdpdmVuIG9uZQMJAAACBQhBc3NldE91dAUHQXNzZXRJbgkAAgECGHRoaXMgc3dhcCBpcyBub3QgYWxsb3dlZAMJAGYCAAAJAGUCBRNhc3NldE91dEZhY3RCYWxhbmNlBQlBbW91bnRPdXQJAAIBAhtjb250cmFjdCBpcyBvdXQgb2YgcmVzZXJ2ZXMDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wAwkBC3ZhbHVlT3JFbHNlAgkAmwgCBQ9wb29sc0h1YkFkZHJlc3MJAKwCAgISZ2xvYmFsX3NodXRkb3duSW5fBQdhc3NldEluBwkAAgECG3Rva2VuIElOIHRyYWRlcyBhcmUgc3RvcHBlZAMJAQt2YWx1ZU9yRWxzZQIJAJsIAgUPcG9vbHNIdWJBZGRyZXNzCQCsAgICE2dsb2JhbF9zaHV0ZG93bk91dF8FCGFzc2V0T3V0BwkAAgECHHRva2VuIE9VVCB0cmFkZXMgYXJlIHN0b3BwZWQEC3Byb3RvY29sRmVlCQBrAwULZmVlQW1vdW50SW4ABQAKBAVscEZlZQkAZQIFC2ZlZUFtb3VudEluBQtwcm90b2NvbEZlZQQNaW50ZXJlc3REZWx0YQkBEmNhbGNJbnRlcmVzdENoYW5nZQIFB2Fzc2V0SW4FBWxwRmVlBAdzdGFrZVR4CQENc3Rha2VJZk5lZWRlZAIFB2Fzc2V0SW4JAGQCBQ1jbGVhbkFtb3VudEluBQVscEZlZQMJAAACBQdzdGFrZVR4BQdzdGFrZVR4BAl1bnN0YWtlVHgJAQ91bnN0YWtlSWZOZWVkZWQCBQhhc3NldE91dAUJQW1vdW50T3V0AwkAAAIFCXVuc3Rha2VUeAUJdW5zdGFrZVR4BAxuZXdCYWxhbmNlSW4FD0Fzc2V0SW5CYWxhbmNlMgQNbmV3QmFsYW5jZU91dAUQQXNzZXRPdXRCYWxhbmNlMgQSYXNzZXRJblNlbGxvZmZEYXRhCQEOdXBkU2VsbG9mZkRhdGEEBQdhc3NldEluBQ1jbGVhbkFtb3VudEluBQ5Bc3NldEluQmFsYW5jZQkAlQoDCAUNYXNzZXRJblBhcmFtcwJfNggFDWFzc2V0SW5QYXJhbXMCXzcIBQ1hc3NldEluUGFyYW1zAl84BBNhc3NldE91dFNlbGxvZmZEYXRhCQEOdXBkU2VsbG9mZkRhdGEEBQhhc3NldE91dAkBAS0BBQlBbW91bnRPdXQFD0Fzc2V0T3V0QmFsYW5jZQkAlQoDCAUOYXNzZXRPdXRQYXJhbXMCXzYIBQ5hc3NldE91dFBhcmFtcwJfNwgFDmFzc2V0T3V0UGFyYW1zAl84BBJhc3NldEluRmluYWxQYXJhbXMJAJoKCAUMbmV3QmFsYW5jZUluCQBkAgUSQXNzZXRJbkZhY3RCYWxhbmNlBQ1jbGVhbkFtb3VudEluCQBkAgURYXNzZXRJbkZlZXNFYXJuZWQFBWxwRmVlCQBkAgUYYXNzZXRJbkxhc3RDaGVja0ludGVyZXN0BQ1pbnRlcmVzdERlbHRhCAUNYXNzZXRJblBhcmFtcwJfNQgFEmFzc2V0SW5TZWxsb2ZmRGF0YQJfMQgFEmFzc2V0SW5TZWxsb2ZmRGF0YQJfMggFEmFzc2V0SW5TZWxsb2ZmRGF0YQJfMwQTYXNzZXRPdXRGaW5hbFBhcmFtcwkAmgoIBQ1uZXdCYWxhbmNlT3V0CQBlAgUTYXNzZXRPdXRGYWN0QmFsYW5jZQUJQW1vdW50T3V0CAUOYXNzZXRPdXRQYXJhbXMCXzMIBQ5hc3NldE91dFBhcmFtcwJfNAgFDmFzc2V0T3V0UGFyYW1zAl81CAUTYXNzZXRPdXRTZWxsb2ZmRGF0YQJfMQgFE2Fzc2V0T3V0U2VsbG9mZkRhdGECXzIIBRNhc3NldE91dFNlbGxvZmZEYXRhAl8zBA1hc3NldEluQ2hhbmdlCQEVc2F2ZUdsb2JhbFRva2VuUGFyYW1zAgUHYXNzZXRJbgUSYXNzZXRJbkZpbmFsUGFyYW1zBA5hc3NldE91dENoYW5nZQkBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIFCGFzc2V0T3V0BRNhc3NldE91dEZpbmFsUGFyYW1zBAtmZWVBc3NldFN0cgkBDHRyeUdldFN0cmluZwECD3N0YXRpY19mZWVUb2tlbgQOZmVlQXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQtmZWVBc3NldFN0cgQPZmVlVG9rZW5CYWxhbmNlCAUOZmVlQXNzZXRQYXJhbXMCXzEED3ZvbHVtZVVzZFVwZGF0ZQkBEWNhbGN1bGF0ZVVzZFZhbHVlBAUHQXNzZXRJbgUIQW1vdW50SW4FDkFzc2V0SW5CYWxhbmNlBQ9mZWVUb2tlbkJhbGFuY2UJAJQKAgkAzAgCBQ1hc3NldEluQ2hhbmdlCQDMCAIFDmFzc2V0T3V0Q2hhbmdlCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUJQW1vdW50T3V0BQhBc3NldE91dAkAzAgCCQEMSW50ZWdlckVudHJ5AgIRZ2xvYmFsX3ZvbHVtZV91c2QJAGQCCQENdHJ5R2V0SW50ZWdlcgECEWdsb2JhbF92b2x1bWVfdXNkBQ92b2x1bWVVc2RVcGRhdGUJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULZmVlc0FkZHJlc3MFC3Byb3RvY29sRmVlCQENZ2V0QXNzZXRCeXRlcwEFB2Fzc2V0SW4FA25pbAUJQW1vdW50T3V0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDHN3YXBSZWFkT25seQMHYXNzZXRJbghhc3NldE91dAhBbW91bnRJbgQHQXNzZXRJbgkBDWdldEFzc2V0Qnl0ZXMBBQdhc3NldEluBAhBc3NldE91dAkBDWdldEFzc2V0Qnl0ZXMBBQhhc3NldE91dAQHc2NhbGVJbgkAaQIFBlNjYWxlOAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUHYXNzZXRJbgIGX3NjYWxlBAhzY2FsZU91dAkAaQIFBlNjYWxlOAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUIYXNzZXRPdXQCBl9zY2FsZQQOZmVlQXNzZXRPdXRTdHIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfZmVlVG9rZW4EC2ZlZUFzc2V0T3V0AwkAAAIFDmZlZUFzc2V0T3V0U3RyAgAFC3VzZG5Bc3NldElkCQENZ2V0QXNzZXRCeXRlcwEFDmZlZUFzc2V0T3V0U3RyBA1hc3NldEluUGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQkBDmdldEFzc2V0U3RyaW5nAQUHQXNzZXRJbgQOYXNzZXRPdXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQhhc3NldE91dAQOQXNzZXRJbkJhbGFuY2UIBQ1hc3NldEluUGFyYW1zAl8xBBJBc3NldEluRmFjdEJhbGFuY2UIBQ1hc3NldEluUGFyYW1zAl8yBBFhc3NldEluRmVlc0Vhcm5lZAgFDWFzc2V0SW5QYXJhbXMCXzMEGGFzc2V0SW5MYXN0Q2hlY2tJbnRlcmVzdAgFDWFzc2V0SW5QYXJhbXMCXzQED0Fzc2V0T3V0QmFsYW5jZQgFDmFzc2V0T3V0UGFyYW1zAl8xBBNhc3NldE91dEZhY3RCYWxhbmNlCAUOYXNzZXRPdXRQYXJhbXMCXzIEFEFzc2V0SW5CYWxhbmNlU2NhbGVkCQBoAgUOQXNzZXRJbkJhbGFuY2UFB3NjYWxlSW4EFUFzc2V0T3V0QmFsYW5jZVNjYWxlZAkAaAIFD0Fzc2V0T3V0QmFsYW5jZQUIc2NhbGVPdXQEC2ZlZUFtb3VudEluCQBrAwUIQW1vdW50SW4FA0ZlZQUIRmVlU2NhbGUEDWNsZWFuQW1vdW50SW4JAGUCBQhBbW91bnRJbgULZmVlQW1vdW50SW4EE2NsZWFuQW1vdW50SW5TY2FsZWQJAGgCBQ1jbGVhbkFtb3VudEluBQdzY2FsZUluBApBbW91bnRPdXQxCQESY2FsY3VsYXRlT3V0QW1vdW50BQUTY2xlYW5BbW91bnRJblNjYWxlZAUHQXNzZXRJbgUIQXNzZXRPdXQFFEFzc2V0SW5CYWxhbmNlU2NhbGVkBRVBc3NldE91dEJhbGFuY2VTY2FsZWQECUFtb3VudE91dAkAawMFCkFtb3VudE91dDEAAQUIc2NhbGVPdXQEEEFzc2V0T3V0QmFsYW5jZTIJAGUCBQ9Bc3NldE91dEJhbGFuY2UFCUFtb3VudE91dAQPQXNzZXRJbkJhbGFuY2UyCQBkAgUOQXNzZXRJbkJhbGFuY2UFDWNsZWFuQW1vdW50SW4DCQAAAgUIQXNzZXRPdXQFB0Fzc2V0SW4JAAIBAhh0aGlzIHN3YXAgaXMgbm90IGFsbG93ZWQDCQBmAgAACQBlAgkBDmdldEZhY3RCYWxhbmNlAQUIYXNzZXRPdXQFCUFtb3VudE91dAkAAgECG2NvbnRyYWN0IGlzIG91dCBvZiByZXNlcnZlcwMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AJAJQKAgUDbmlsBQlBbW91bnRPdXQBaQERdHJhbnNmZXJPd25lcnNoaXABD25ld093bmVyQWRkcmVzcwMJAQIhPQIJAKUIAQgFAWkGY2FsbGVyCQEMdHJ5R2V0U3RyaW5nAQIQc3RhdGljX3Bvb2xPd25lcgkAAgECJ3RoaXMgY2FsbCBhdmFpbGFibGUgb25seSBmb3IgcG9vbCBvd25lcgkAzAgCCQELU3RyaW5nRW50cnkCAhBzdGF0aWNfcG9vbE93bmVyBQ9uZXdPd25lckFkZHJlc3MFA25pbAFpAQZzZXRGZWUBBm5ld0ZlZQMJAQIhPQIJAKUIAQgFAWkGY2FsbGVyCQEMdHJ5R2V0U3RyaW5nAQIQc3RhdGljX3Bvb2xPd25lcgkAAgECJ3RoaXMgY2FsbCBhdmFpbGFibGUgb25seSBmb3IgcG9vbCBvd25lcgkAzAgCCQEMSW50ZWdlckVudHJ5AgIKc3RhdGljX2ZlZQUGbmV3RmVlBQNuaWwBAnR4AQZ2ZXJpZnkACQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQxtYXN0ZXJQdWJLZXlD6lON", "height": 303972, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: BjxsQ5NoTLhqfu1Uj4wCNrG469KuNEotavc5ttAQPpYP Next: none Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let VERSION = "PZ-3.6.1 Optimize"
55
66 let configStr = valueOrElse(getString(this, "configAddress"), "3PMoEibdLeWqcURQ8351XhaWwyacDc7G4e5")
77
88 let CONFIG_ADDRESS = if ((configStr == ""))
99 then this
1010 else Address(fromBase58String(configStr))
1111
1212 let AssetsWeightsDecimals = 4
1313
1414 let Scale = 10000
1515
1616 let Scale8 = 100000000
1717
1818 let Scale12 = 1000000000000
1919
2020 let Scale16 = 10000000000000000
2121
2222 let FeeScale = 10000
2323
2424 let PoolTokenDecimals = 8
2525
2626 let PoolTokenScale = pow(10, 0, PoolTokenDecimals, 0, 0, HALFUP)
2727
2828 let MIN_STEPS_AMOUNT = valueOrElse(getInteger(CONFIG_ADDRESS, "min_steps_amount"), 1)
2929
3030 let MAX_STEPS_AMOUNT = valueOrElse(getInteger(CONFIG_ADDRESS, "max_steps_amount"), 500)
3131
3232 let MIN_STEPS_INTERVAL = valueOrElse(getInteger(CONFIG_ADDRESS, "min_steps_interval"), 1)
3333
3434 let MAX_STEPS_INTERVAL = valueOrElse(getInteger(CONFIG_ADDRESS, "max_steps_interval"), 10000)
3535
3636 let MIN_WEIGHT = valueOrElse(getInteger(CONFIG_ADDRESS, "min_weight"), 100)
3737
3838 let MAX_WEIGHT = valueOrElse(getInteger(CONFIG_ADDRESS, "max_weight"), 9900)
3939
4040 func tryGetInteger (key) = match getInteger(this, key) {
4141 case b: Int =>
4242 b
4343 case _ =>
4444 0
4545 }
4646
4747
4848 func tryGetBinary (key) = match getBinary(this, key) {
4949 case b: ByteVector =>
5050 b
5151 case _ =>
5252 base58''
5353 }
5454
5555
5656 func tryGetString (key) = match getString(this, key) {
5757 case b: String =>
5858 b
5959 case _ =>
6060 ""
6161 }
6262
6363
6464 func tryGetStringOrThrow (key) = match getString(this, key) {
6565 case b: String =>
6666 b
6767 case _ =>
6868 throw(("no such key in data storage: " + key))
6969 }
7070
7171
7272 func getAssetString (assetId) = match assetId {
7373 case b: ByteVector =>
7474 toBase58String(b)
7575 case _ =>
7676 "WAVES"
7777 }
7878
7979
8080 func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
8181 then unit
8282 else fromBase58String(assetIdStr)
8383
8484
8585 func getTokenBalance (assetId) = match assetId {
8686 case t: ByteVector =>
8787 assetBalance(this, t)
8888 case _ =>
8989 wavesBalance(this).available
9090 }
9191
9292
9393 func getFactBalance (assetIdStr) = tryGetInteger((("global_" + assetIdStr) + "_factBalance"))
9494
9595
9696 func addAssetBytesToList (accum,item) = (accum ++ [getAssetBytes(item)])
9797
9898
9999 func addAssetWeightToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_weight"))])
100100
101101
102102 func addAssetWeightToStrList (accum,item) = (accum ++ [toString(tryGetInteger((("static_" + item) + "_weight")))])
103103
104104
105105 func addAssetDecimalsToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_decimals"))])
106106
107107
108108 func addAssetScaleToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_scale"))])
109109
110110
111111 func addIntToList (accum,item) = (accum ++ [parseIntValue(item)])
112112
113113
114114 func parstStrToIntList (s) = {
115115 func f (accum,next) = (accum ++ [parseIntValue(next)])
116116
117117 let $l = split(s, ",")
118118 let $s = size($l)
119119 let $acc0 = nil
120120 func $f0_1 ($a,$i) = if (($i >= $s))
121121 then $a
122122 else f($a, $l[$i])
123123
124124 func $f0_2 ($a,$i) = if (($i >= $s))
125125 then $a
126126 else throw("List size exceeds 10")
127127
128128 $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)
129129 }
130130
131131
132132 let usdnAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdnAssetIdStr"), "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
133133
134134 let puzzleAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "puzzleAssetIdStr"), "HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS")
135135
136136 let usdtAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdtAssetIdStr"), "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ")
137137
138138 let usdtPptAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdtPptAssetIdStr"), "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi")
139139
140140 let romeAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "romeAssetIdStr"), "AP4Cb5xLYGH6ZigHreCZHoXpQTWDkPsG2BHqfDUx6taJ")
141141
142142 let wavesAssetIdStr = "WAVES"
143143
144144 let usdnAssetId = fromBase58String(usdnAssetIdStr)
145145
146146 let puzzleAssetId = fromBase58String(puzzleAssetIdStr)
147147
148148 let usdtAssetId = fromBase58String(usdtAssetIdStr)
149149
150150 let usdtPptAssetId = fromBase58String(usdtPptAssetIdStr)
151151
152152 let romeAssetId = fromBase58String(romeAssetIdStr)
153153
154154 let wavesAssetId = unit
155155
156156 let supportedFeeAssetsStr = [usdnAssetIdStr, puzzleAssetIdStr, usdtAssetIdStr, usdtPptAssetIdStr, wavesAssetIdStr, romeAssetIdStr]
157157
158158 let parentPoolAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "parentPoolAddress"), "3PFDgzu1UtswAkCMxqqQjbTeHaX4cMab8Kh")))
159159
160160 let masterAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "masterAddress"), "3PLjwHcz9NEuaTo63NZR9B9okQiKQxZSbmf")))
161161
162162 let masterPubKey = fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "masterPubKey"), "2jTJGqHSopyj5d1cjbUe6f2jXqGMHE412cy3vGwYoRbP"))
163163
164164 let oracleAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "oracleAddress"), "3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t")))
165165
166166 let stakingAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "stakingAddress"), "3PFTbywqxtFfukX3HyT881g4iW5K4QL3FAS")))
167167
168168 let feesAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "feesAddress"), "3PFWAVKmXjfHXyzJb12jCbhP4Uhi9t4uWiD")))
169169
170170 let poolsHubAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "poolsHubAddress"), "3P5RGYyCnELF8JTPxgX54dBGzwkQMKUJ5H7")))
171171
172172 let shutdownAddressStr = valueOrElse(getString(CONFIG_ADDRESS, "shutdownAddress"), "3PEpv9hRFWEEBU22WRnLsw1bH4YGtcU728o")
173173
174174 let layer2Addresses = valueOrElse(getString(CONFIG_ADDRESS, "layer2Addresses"), "3PR1Qvi9mHT35SwWEkLSqqE2L8thiPLdVWU,3PQoBfUKHkJAeGWhooLP7WS8ovb54av9Jp2")
175175
176176 let govAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "govAddress"), "3P6uro9xCsE8te78QZjzqy7aq8natSzdceC")))
177177
178178 let coldMasterAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "coldMasterAddress"), "3PK9nhPfPbMBygB9ZgHVMHaQbSoojwrBfxj")))
179179
180180 let T = tryGetInteger("static_tokensAmount")
181181
182182 let assetIds = {
183183 let $l = split(tryGetString("static_tokenIds"), ",")
184184 let $s = size($l)
185185 let $acc0 = nil
186186 func $f0_1 ($a,$i) = if (($i >= $s))
187187 then $a
188188 else addAssetBytesToList($a, $l[$i])
189189
190190 func $f0_2 ($a,$i) = if (($i >= $s))
191191 then $a
192192 else throw("List size exceeds 10")
193193
194194 $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)
195195 }
196196
197197 let AssetsWeights = {
198198 let $l = assetIds
199199 let $s = size($l)
200200 let $acc0 = nil
201201 func $f1_1 ($a,$i) = if (($i >= $s))
202202 then $a
203203 else addAssetWeightToList($a, $l[$i])
204204
205205 func $f1_2 ($a,$i) = if (($i >= $s))
206206 then $a
207207 else throw("List size exceeds 10")
208208
209209 $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)
210210 }
211211
212212 let Decimals = {
213213 let $l = assetIds
214214 let $s = size($l)
215215 let $acc0 = nil
216216 func $f2_1 ($a,$i) = if (($i >= $s))
217217 then $a
218218 else addAssetDecimalsToList($a, $l[$i])
219219
220220 func $f2_2 ($a,$i) = if (($i >= $s))
221221 then $a
222222 else throw("List size exceeds 10")
223223
224224 $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)
225225 }
226226
227227 let Scales = {
228228 let $l = assetIds
229229 let $s = size($l)
230230 let $acc0 = nil
231231 func $f3_1 ($a,$i) = if (($i >= $s))
232232 then $a
233233 else addAssetScaleToList($a, $l[$i])
234234
235235 func $f3_2 ($a,$i) = if (($i >= $s))
236236 then $a
237237 else throw("List size exceeds 10")
238238
239239 $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)
240240 }
241241
242242 let Fee = tryGetInteger("static_fee")
243243
244244 let earnedAssets = assetIds
245245
246246 func _get (assetId,param) = tryGetInteger((("global_" + assetId) + "_param"))
247247
248248
249249 func _get_feesEarned (assetId) = tryGetInteger(("global_feesEarned_" + assetId))
250250
251251
252252 func _get_lastCheck_interest (assetId) = tryGetInteger((("global_lastCheck_" + assetId) + "_interest"))
253253
254254
255255 func _get_extraEarned (assetId) = tryGetInteger(("global_extraEarned_" + assetId))
256256
257257
258258 func loadGlobalTokenParams (assetId) = match getString(("globalParams_" + assetId)) {
259259 case p: String =>
260260 let params = split(p, "__")
261261 $Tuple8(parseIntValue(params[0]), parseIntValue(params[1]), parseIntValue(params[2]), parseIntValue(params[3]), parseIntValue(params[4]), parseIntValue(params[5]), parseIntValue(params[6]), parseIntValue(params[7]))
262262 case _ =>
263263 $Tuple8(_get(assetId, "balance"), _get(assetId, "factBalance"), _get_feesEarned(assetId), _get_lastCheck_interest(assetId), _get_extraEarned(assetId), _get(assetId, "selloff"), _get(assetId, "selloffStartBalance"), _get(assetId, "selloffStartHeight"))
264264 }
265265
266266
267267 func saveGlobalTokenParams (assetId,params) = StringEntry(("globalParams_" + assetId), makeString([toString(params._1), toString(params._2), toString(params._3), toString(params._4), toString(params._5), toString(params._6), toString(params._7), toString(params._8)], "__"))
268268
269269
270270 func isShutdown () = {
271271 let shutdownAddress = addressFromString(shutdownAddressStr)
272272 if ((shutdownAddress == unit))
273273 then false
274274 else match getBoolean(value(shutdownAddress), "is_shutdown") {
275275 case x: Boolean =>
276276 x
277277 case _ =>
278278 false
279279 }
280280 }
281281
282282
283283 func getCurrentTokenBalance (tokenNum) = {
284284 let tokenIdStr = getAssetString(assetIds[tokenNum])
285285 tryGetInteger((("global_" + tokenIdStr) + "_balance"))
286286 }
287287
288288
289289 func stakeIfNeeded (assetIdStr,amount) = {
290290 let stakeTx = if ((tryGetString(("static_stakingContract_" + assetIdStr)) != ""))
291291 then invoke(addressFromStringValue(tryGetString(("static_stakingContract_" + assetIdStr))), "stake", nil, [AttachedPayment(getAssetBytes(assetIdStr), amount)])
292292 else unit
293293 if ((stakeTx == stakeTx))
294294 then true
295295 else throw("Strict value is not equal to itself.")
296296 }
297297
298298
299299 func unstakeIfNeeded (assetIdStr,amount) = {
300300 let unstakeTx = if ((tryGetString(("static_stakingContract_" + assetIdStr)) != ""))
301301 then invoke(addressFromStringValue(tryGetString(("static_stakingContract_" + assetIdStr))), "unstake", [amount], nil)
302302 else unit
303303 if ((unstakeTx == unstakeTx))
304304 then true
305305 else throw("Strict value is not equal to itself.")
306306 }
307307
308308
309309 func burnIndexIfNeeded (amount) = {
310310 let indexIdStr = tryGetString("static_poolToken_idStr")
311311 if ((indexIdStr == ""))
312312 then nil
313313 else if ((assetInfo(fromBase58String(indexIdStr)) == unit))
314314 then nil
315315 else [Burn(fromBase58String(indexIdStr), amount)]
316316 }
317317
318318
319319 func mintIndexIfNeeded (amount) = {
320320 let indexIdStr = tryGetString("static_poolToken_idStr")
321321 if ((indexIdStr == ""))
322322 then nil
323323 else if ((assetInfo(fromBase58String(indexIdStr)) == unit))
324324 then nil
325325 else [Reissue(fromBase58String(indexIdStr), amount, true)]
326326 }
327327
328328
329329 func getKMult () = match getInteger("static_KMult") {
330330 case x: Int =>
331331 x
332332 case _ =>
333333 Scale16
334334 }
335335
336336
337337 func saveCurrentWeights () = {
338338 let assetIdsLi = split(tryGetString("static_tokenIds"), ",")
339339 func s (accum,assetId) = (accum ++ [IntegerEntry(("rebalance_startWeight_" + assetId), tryGetInteger((("static_" + assetId) + "_weight")))])
340340
341341 let $l = assetIdsLi
342342 let $s = size($l)
343343 let $acc0 = nil
344344 func $f4_1 ($a,$i) = if (($i >= $s))
345345 then $a
346346 else s($a, $l[$i])
347347
348348 func $f4_2 ($a,$i) = if (($i >= $s))
349349 then $a
350350 else throw("List size exceeds 10")
351351
352352 $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)
353353 }
354354
355355
356356 func getVirtualPoolTokenAmount () = fraction(tryGetInteger("global_poolToken_amount"), getKMult(), Scale16)
357357
358358
359359 func calculatePIssued (amount,tokenId) = {
360360 let Psupply = getVirtualPoolTokenAmount()
361361 let Balance = getFactBalance(getAssetString(tokenId))
362362 let t1 = fraction(amount, Psupply, Balance, DOWN)
363363 t1
364364 }
365365
366366
367367 func getMinPIssued (payments) = {
368368 func handler (accum,current) = if ((getFactBalance(getAssetString(current.assetId)) == 0))
369369 then accum
370370 else {
371371 let PIssued = calculatePIssued(current.amount, current.assetId)
372372 if ((PIssued == 0))
373373 then throw("one of the tokens amounts is too low")
374374 else if (if ((accum == 0))
375375 then true
376376 else (accum > PIssued))
377377 then PIssued
378378 else accum
379379 }
380380
381381 let minPIssed = {
382382 let $l = payments
383383 let $s = size($l)
384384 let $acc0 = 0
385385 func $f4_1 ($a,$i) = if (($i >= $s))
386386 then $a
387387 else handler($a, $l[$i])
388388
389389 func $f4_2 ($a,$i) = if (($i >= $s))
390390 then $a
391391 else throw("List size exceeds 10")
392392
393393 $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)
394394 }
395395 minPIssed
396396 }
397397
398398
399399 func getPriceFromOracle (assetIdStr) = match getInteger(oracleAddress, (assetIdStr + "_twap5B")) {
400400 case x: Int =>
401401 x
402402 case _ =>
403403 0
404404 }
405405
406406
407407 func calculateUsdValue (assetId,amount,aBalance,feeAssetBalance) = {
408408 let assetWeight = tryGetInteger((("static_" + getAssetString(assetId)) + "_weight"))
409409 let feeAssetStr = tryGetString("static_feeToken")
410410 let feeAssetScale = getIntegerValue(this, (("static_" + feeAssetStr) + "_scale"))
411411 let feeAssetNum = value(indexOf(assetIds, getAssetBytes(feeAssetStr)))
412412 let feeAssetWeight = AssetsWeights[feeAssetNum]
413413 let valInFeeAsset = fraction(amount, (feeAssetBalance / feeAssetWeight), (aBalance / assetWeight))
414414 let feeAssetPrice = getPriceFromOracle(feeAssetStr)
415415 fraction(valInFeeAsset, feeAssetPrice, feeAssetScale)
416416 }
417417
418418
419419 func calcAvgConcentration () = {
420420 func f (accum,next) = {
421421 let assetIdStr = getAssetString(next)
422422 let weight = tryGetInteger((("static_" + assetIdStr) + "_weight"))
423423 let assetFactBalance = tryGetInteger((("global_" + assetIdStr) + "_factBalance"))
424424 let assetVirtBalance = tryGetInteger((("global_" + assetIdStr) + "_balance"))
425425 $Tuple2((accum._1 + fraction(assetFactBalance, weight, assetVirtBalance)), (accum._2 + weight))
426426 }
427427
428428 let $l = assetIds
429429 let $s = size($l)
430430 let $acc0 = $Tuple2(0, 0)
431431 func $f4_1 ($a,$i) = if (($i >= $s))
432432 then $a
433433 else f($a, $l[$i])
434434
435435 func $f4_2 ($a,$i) = if (($i >= $s))
436436 then $a
437437 else throw("List size exceeds 10")
438438
439439 $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)
440440 }
441441
442442
443443 func checkTokensValidity (payments) = {
444444 func handler1 (accum,payment) = (accum ++ [payment.assetId])
445445
446446 let ids = {
447447 let $l = payments
448448 let $s = size($l)
449449 let $acc0 = nil
450450 func $f4_1 ($a,$i) = if (($i >= $s))
451451 then $a
452452 else handler1($a, $l[$i])
453453
454454 func $f4_2 ($a,$i) = if (($i >= $s))
455455 then $a
456456 else throw("List size exceeds 10")
457457
458458 $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)
459459 }
460460 if ((ids == ids))
461461 then {
462462 func handler2 (accum,assetId) = if ((indexOf(ids, assetId) != unit))
463463 then (accum + 1)
464464 else throw(("asset not attached: " + getAssetString(assetId)))
465465
466466 let checks = {
467467 let $l = assetIds
468468 let $s = size($l)
469469 let $acc0 = 0
470470 func $f5_1 ($a,$i) = if (($i >= $s))
471471 then $a
472472 else handler2($a, $l[$i])
473473
474474 func $f5_2 ($a,$i) = if (($i >= $s))
475475 then $a
476476 else throw("List size exceeds 10")
477477
478478 $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)
479479 }
480480 if ((checks == checks))
481481 then true
482482 else throw("Strict value is not equal to itself.")
483483 }
484484 else throw("Strict value is not equal to itself.")
485485 }
486486
487487
488488 func handlePoolTokensAdd (PIssued,payments,userAddress,needChange) = {
489489 func getTokenPaymentAmount (tokenId) = {
490490 func handler (accum,payment) = if ((payment.assetId == tokenId))
491491 then payment.amount
492492 else accum
493493
494494 let $l = payments
495495 let $s = size($l)
496496 let $acc0 = 0
497497 func $f4_1 ($a,$i) = if (($i >= $s))
498498 then $a
499499 else handler($a, $l[$i])
500500
501501 func $f4_2 ($a,$i) = if (($i >= $s))
502502 then $a
503503 else throw("List size exceeds 10")
504504
505505 $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)
506506 }
507507
508508 func handleTokenChange (accum,tokenId) = {
509509 let assetIdStr = getAssetString(tokenId)
510510 let assetParams = loadGlobalTokenParams(assetIdStr)
511511 let paymentAmount = getTokenPaymentAmount(tokenId)
512512 let Bk = assetParams._2
513513 let PSupply = getVirtualPoolTokenAmount()
514514 let tokenDecimals = tryGetInteger((("static_" + assetIdStr) + "_scale"))
515515 let a1 = fraction((toBigInt((PSupply + PIssued)) * toBigInt(Scale8)), toBigInt(tokenDecimals), toBigInt(PSupply), CEILING)
516516 let Dk = toInt(fraction((a1 - (toBigInt(tokenDecimals) * toBigInt(Scale8))), toBigInt(Bk), (toBigInt(tokenDecimals) * toBigInt(Scale8)), CEILING))
517517 let toReturn = (paymentAmount - Dk)
518518 let stakeTx = stakeIfNeeded(assetIdStr, Dk)
519519 if ((stakeTx == stakeTx))
520520 then {
521521 let t = if (if (needChange)
522522 then (toReturn > 0)
523523 else false)
524524 then [ScriptTransfer(userAddress, toReturn, tokenId)]
525525 else nil
526526 let selloffStartBalance = if ((assetParams._8 != ((height / 100) * 100)))
527527 then assetParams._8
528528 else fraction(assetParams._7, (PSupply + PIssued), PSupply)
529529 let assetParamsUpd = $Tuple8(fraction(assetParams._1, (PSupply + PIssued), PSupply), (assetParams._2 + Dk), assetParams._3, assetParams._4, assetParams._5, assetParams._6, selloffStartBalance, assetParams._8)
530530 ((accum ++ t) ++ [saveGlobalTokenParams(assetIdStr, assetParamsUpd)])
531531 }
532532 else throw("Strict value is not equal to itself.")
533533 }
534534
535535 let $l = assetIds
536536 let $s = size($l)
537537 let $acc0 = nil
538538 func $f4_1 ($a,$i) = if (($i >= $s))
539539 then $a
540540 else handleTokenChange($a, $l[$i])
541541
542542 func $f4_2 ($a,$i) = if (($i >= $s))
543543 then $a
544544 else throw("List size exceeds 10")
545545
546546 $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)
547547 }
548548
549549
550550 func calcMintedWithOneToken (assetAddedIdStr,amount) = {
551551 let PSupply = getVirtualPoolTokenAmount()
552552 let assetFactBalance = tryGetInteger((("global_" + assetAddedIdStr) + "_factBalance"))
553553 let assetVirtBalance = tryGetInteger((("global_" + assetAddedIdStr) + "_balance"))
554554 let assetWeight = tryGetInteger((("static_" + assetAddedIdStr) + "_weight"))
555555 let assetScale = tryGetInteger((("static_" + assetAddedIdStr) + "_scale"))
556556 let assetDecimals = tryGetInteger((("static_" + assetAddedIdStr) + "_decimals"))
557557 let PIssuedNoMultiplier = fraction(PSupply, (toInt(pow(toBigInt((assetScale + fraction(amount, assetScale, assetVirtBalance))), assetDecimals, toBigInt(assetWeight), 4, 8, DOWN)) - Scale8), Scale8)
558558 let avgConc = calcAvgConcentration()
559559 let PIssued = fraction(PIssuedNoMultiplier, avgConc._2, avgConc._1)
560560 $Tuple2([IntegerEntry((("global_" + assetAddedIdStr) + "_factBalance"), (assetFactBalance + amount)), IntegerEntry((("global_" + assetAddedIdStr) + "_balance"), (assetVirtBalance + amount))], PIssued)
561561 }
562562
563563
564564 func calcRedeemWithOneToken (assetOutIdStr,PRedeemed) = {
565565 let PSupply = getVirtualPoolTokenAmount()
566566 let assetFactBalance = tryGetInteger((("global_" + assetOutIdStr) + "_factBalance"))
567567 let assetVirtBalance = tryGetInteger((("global_" + assetOutIdStr) + "_balance"))
568568 let assetWeight = tryGetInteger((("static_" + assetOutIdStr) + "_weight"))
569569 let assetScale = tryGetInteger((("static_" + assetOutIdStr) + "_scale"))
570570 let assetDecimals = tryGetInteger((("static_" + assetOutIdStr) + "_decimals"))
571571 let amountOutNoMulitplier = fraction(assetVirtBalance, (Scale8 - toInt(pow(toBigInt((assetScale - fraction(PRedeemed, assetScale, PSupply))), assetDecimals, toBigInt(fraction(10000, 10000, assetWeight)), 4, 8, DOWN))), Scale8)
572572 let avgConc = calcAvgConcentration()
573573 let amountOut = fraction(amountOutNoMulitplier, avgConc._1, avgConc._2)
574574 if ((amountOut > assetFactBalance))
575575 then throw("no available fact liquidity to withdraw in one token")
576576 else $Tuple2([IntegerEntry((("global_" + assetOutIdStr) + "_factBalance"), (assetFactBalance - amountOut)), IntegerEntry((("global_" + assetOutIdStr) + "_balance"), (assetVirtBalance - amountOut))], amountOut)
577577 }
578578
579579
580580 func handlePoolTokensRedeem (PRedeemed,userAddress) = {
581581 func handleTokenRedeem (accum,tokenId) = {
582582 let assetIdStr = getAssetString(tokenId)
583583 let assetParams = loadGlobalTokenParams(assetIdStr)
584584 let Bk = assetParams._2
585585 let PSupply = getVirtualPoolTokenAmount()
586586 let tokenDecimals = tryGetInteger((("static_" + assetIdStr) + "_scale"))
587587 let psuppl = fraction((toBigInt((PSupply - PRedeemed)) * toBigInt(Scale8)), toBigInt(Scale8), toBigInt(PSupply), DOWN)
588588 let amount = toInt(fraction((toBigInt(Scale16) - psuppl), toBigInt(Bk), toBigInt(Scale16), CEILING))
589589 let unstakeTx = unstakeIfNeeded(assetIdStr, amount)
590590 if ((unstakeTx == unstakeTx))
591591 then {
592592 let selloffStartBalance = if ((assetParams._8 != ((height / 100) * 100)))
593593 then assetParams._8
594594 else fraction(assetParams._7, (PSupply - PRedeemed), PSupply)
595595 let assetParamsUpd = $Tuple8(fraction(assetParams._1, (PSupply - PRedeemed), PSupply), (assetParams._2 - amount), assetParams._3, assetParams._4, assetParams._5, assetParams._6, selloffStartBalance, assetParams._8)
596596 ((accum ++ [ScriptTransfer(userAddress, amount, tokenId)]) ++ [saveGlobalTokenParams(assetIdStr, assetParamsUpd)])
597597 }
598598 else throw("Strict value is not equal to itself.")
599599 }
600600
601601 let $l = assetIds
602602 let $s = size($l)
603603 let $acc0 = nil
604604 func $f4_1 ($a,$i) = if (($i >= $s))
605605 then $a
606606 else handleTokenRedeem($a, $l[$i])
607607
608608 func $f4_2 ($a,$i) = if (($i >= $s))
609609 then $a
610610 else throw("List size exceeds 10")
611611
612612 $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)
613613 }
614614
615615
616616 func calculateOutAmount (AmountIn,assetIn,assetOut,BalanceIn,BalanceOut) = {
617617 let IndexIn = value(indexOf(assetIds, assetIn))
618618 let IndexOut = value(indexOf(assetIds, assetOut))
619619 if ((IndexIn == IndexOut))
620620 then AmountIn
621621 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)
622622 }
623623
624624
625625 func claimResult (address) = {
626626 let addressStr = toString(address)
627627 let indexAmount = tryGetInteger((addressStr + "_indexStaked"))
628628 let feeAssetStr = tryGetString("static_feeToken")
629629 let feeAssetParams = loadGlobalTokenParams(feeAssetStr)
630630 let feeTokenBalance = feeAssetParams._1
631631 func handler (accum,assetId) = {
632632 let assetIdStr = getAssetString(assetId)
633633 let assetParams = loadGlobalTokenParams(assetIdStr)
634634 let currentTokenInterest = assetParams._4
635635 let aBalance = assetParams._1
636636 let rewardAmount = fraction(indexAmount, (currentTokenInterest - tryGetInteger((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"))), Scale16)
637637 let unstakeInv = unstakeIfNeeded(assetIdStr, rewardAmount)
638638 if ((unstakeInv == unstakeInv))
639639 then {
640640 let transfer = if ((rewardAmount == 0))
641641 then nil
642642 else [ScriptTransfer(address, rewardAmount, assetId)]
643643 $Tuple2(((accum._1 ++ transfer) ++ [IntegerEntry((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"), currentTokenInterest)]), (accum._2 + calculateUsdValue(assetId, rewardAmount, aBalance, feeTokenBalance)))
644644 }
645645 else throw("Strict value is not equal to itself.")
646646 }
647647
648648 let accum = {
649649 let $l = earnedAssets
650650 let $s = size($l)
651651 let $acc0 = $Tuple2(nil, 0)
652652 func $f4_1 ($a,$i) = if (($i >= $s))
653653 then $a
654654 else handler($a, $l[$i])
655655
656656 func $f4_2 ($a,$i) = if (($i >= $s))
657657 then $a
658658 else throw("List size exceeds 10")
659659
660660 $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)
661661 }
662662 $Tuple2((accum._1 ++ [IntegerEntry((addressStr + "_claimedRewardUSD"), (tryGetInteger((addressStr + "_claimedRewardUSD")) + accum._2)), IntegerEntry((addressStr + "_lastClaim"), lastBlock.timestamp)]), accum._2)
663663 }
664664
665665
666666 func indexStakeResult (addressStr,amount) = {
667667 let li = claimResult(addressFromStringValue(addressStr))._1
668668 (li ++ [IntegerEntry((addressStr + "_indexStaked"), (tryGetInteger((addressStr + "_indexStaked")) + amount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") + amount))])
669669 }
670670
671671
672672 func sum (accum,n) = (accum + parseIntValue(n))
673673
674674
675675 func checkFeeAsset (accum,next) = if (if ((indexOf(supportedFeeAssetsStr, next) != unit))
676676 then (accum == "")
677677 else false)
678678 then next
679679 else accum
680680
681681
682682 func calcInterestChange (assetIdStr,lpFee) = {
683683 let totalIndex = tryGetInteger("global_indexStaked")
684684 let interestDelta = fraction(lpFee, Scale16, totalIndex)
685685 interestDelta
686686 }
687687
688688
689689 func updSelloffData (assetIdStr,amountIn,balance,selloffParams) = {
690690 let currentPeriod = ((height / 100) * 100)
691691 let prevPeriod = selloffParams._2
692692 let prevSelloff = if ((currentPeriod == prevPeriod))
693693 then selloffParams._1
694694 else 0
695695 let selloffStartBalance = if ((currentPeriod == prevPeriod))
696696 then selloffParams._3
697697 else balance
698698 let selloffDelta = fraction(Scale16, amountIn, selloffStartBalance)
699699 let maxSelloff = tryGetInteger((("static_" + assetIdStr) + "_maxSelloff"))
700700 if (if (((prevSelloff + selloffDelta) > maxSelloff))
701701 then (maxSelloff != 0)
702702 else false)
703703 then throw(("max selloff reached for this asset " + assetIdStr))
704704 else {
705705 let startH = if ((currentPeriod == prevPeriod))
706706 then prevPeriod
707707 else currentPeriod
708708 let startB = if ((currentPeriod == prevPeriod))
709709 then selloffParams._3
710710 else selloffStartBalance
711711 $Tuple3((prevSelloff + selloffDelta), startH, startB)
712712 }
713713 }
714714
715715
716716 func getTmpRebalanceIds (newAssetIdsLi) = {
717717 let currentAssetIdsLi = split(tryGetString("static_tokenIds"), ",")
718718 let result = newAssetIdsLi
719719 func f (accum,assetId) = if ((indexOf(result, assetId) == unit))
720720 then (accum ++ [assetId])
721721 else accum
722722
723723 let $l = currentAssetIdsLi
724724 let $s = size($l)
725725 let $acc0 = result
726726 func $f4_1 ($a,$i) = if (($i >= $s))
727727 then $a
728728 else f($a, $l[$i])
729729
730730 func $f4_2 ($a,$i) = if (($i >= $s))
731731 then $a
732732 else throw("List size exceeds 10")
733733
734734 $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)
735735 }
736736
737737
738738 func checkTokensChange (newAssetIdsLi) = {
739739 let currentAssetIdsLi = split(tryGetString("static_tokenIds"), ",")
740740 func rem (accum,assetId) = if ((indexOf(newAssetIdsLi, assetId) == unit))
741741 then (accum + 1)
742742 else accum
743743
744744 func add (accum,assetId) = if ((indexOf(currentAssetIdsLi, assetId) == unit))
745745 then (accum + 1)
746746 else accum
747747
748748 let removed = {
749749 let $l = currentAssetIdsLi
750750 let $s = size($l)
751751 let $acc0 = 0
752752 func $f4_1 ($a,$i) = if (($i >= $s))
753753 then $a
754754 else rem($a, $l[$i])
755755
756756 func $f4_2 ($a,$i) = if (($i >= $s))
757757 then $a
758758 else throw("List size exceeds 10")
759759
760760 $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)
761761 }
762762 let added = {
763763 let $l = newAssetIdsLi
764764 let $s = size($l)
765765 let $acc0 = 0
766766 func $f5_1 ($a,$i) = if (($i >= $s))
767767 then $a
768768 else add($a, $l[$i])
769769
770770 func $f5_2 ($a,$i) = if (($i >= $s))
771771 then $a
772772 else throw("List size exceeds 10")
773773
774774 $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)
775775 }
776776 (removed + added)
777777 }
778778
779779
780780 func validatePayments (assetsList,payments) = {
781781 func getPaymentAssets (accum,next) = if ((0 >= next.amount))
782782 then throw(((("Too low payment amount for " + getAssetString(next.assetId)) + ": ") + toString(next.amount)))
783783 else (accum ++ [getAssetString(next.assetId)])
784784
785785 let paymentList = {
786786 let $l = payments
787787 let $s = size($l)
788788 let $acc0 = nil
789789 func $f4_1 ($a,$i) = if (($i >= $s))
790790 then $a
791791 else getPaymentAssets($a, $l[$i])
792792
793793 func $f4_2 ($a,$i) = if (($i >= $s))
794794 then $a
795795 else throw("List size exceeds 10")
796796
797797 $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)
798798 }
799799 func f1 (accum,next) = if ((indexOf(assetsList, next) == unit))
800800 then throw(((next + " asset is present in payments, but is not in new assets: ") + makeString(assetsList, ",")))
801801 else (accum + 1)
802802
803803 func f2 (accum,next) = if ((indexOf(paymentList, next) == unit))
804804 then throw(((next + " asset is present in new assets, but is not in payments: ") + makeString(paymentList, ",")))
805805 else (accum + 1)
806806
807807 let a1 = {
808808 let $l = paymentList
809809 let $s = size($l)
810810 let $acc0 = 0
811811 func $f5_1 ($a,$i) = if (($i >= $s))
812812 then $a
813813 else f1($a, $l[$i])
814814
815815 func $f5_2 ($a,$i) = if (($i >= $s))
816816 then $a
817817 else throw("List size exceeds 10")
818818
819819 $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)
820820 }
821821 let a2 = {
822822 let $l = assetsList
823823 let $s = size($l)
824824 let $acc0 = 0
825825 func $f6_1 ($a,$i) = if (($i >= $s))
826826 then $a
827827 else f2($a, $l[$i])
828828
829829 func $f6_2 ($a,$i) = if (($i >= $s))
830830 then $a
831831 else throw("List size exceeds 10")
832832
833833 $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)
834834 }
835835 (a1 + a2)
836836 }
837837
838838
839839 func validateWeights (weights) = {
840840 func v (accum,w) = {
841841 let wInt = valueOrErrorMessage(parseInt(w), ("Wrong weight format: " + w))
842842 if (if ((MIN_WEIGHT > wInt))
843843 then true
844844 else (wInt > MAX_WEIGHT))
845845 then throw(((((("Weight should be in range " + toString(MIN_WEIGHT)) + " - ") + toString(MAX_WEIGHT)) + ", current: ") + w))
846846 else (accum + wInt)
847847 }
848848
849849 let $l = weights
850850 let $s = size($l)
851851 let $acc0 = 0
852852 func $f4_1 ($a,$i) = if (($i >= $s))
853853 then $a
854854 else v($a, $l[$i])
855855
856856 func $f4_2 ($a,$i) = if (($i >= $s))
857857 then $a
858858 else throw("List size exceeds 10")
859859
860860 $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)
861861 }
862862
863863
864864 func getP1P2 (assetIdStr,baseAssetIdStr) = {
865865 let assetParams = loadGlobalTokenParams(assetIdStr)
866866 let baseAssetParams = loadGlobalTokenParams(baseAssetIdStr)
867867 let B1 = baseAssetParams._1
868868 let B2 = assetParams._1
869869 let F1 = baseAssetParams._2
870870 let F2 = assetParams._2
871871 let S1 = tryGetInteger((("static_" + baseAssetIdStr) + "_scale"))
872872 let S2 = tryGetInteger((("static_" + assetIdStr) + "_scale"))
873873 let D1 = tryGetInteger((("static_" + baseAssetIdStr) + "_decimals"))
874874 let D2 = tryGetInteger((("static_" + assetIdStr) + "_decimals"))
875875 let W1 = tryGetInteger((("static_" + baseAssetIdStr) + "_weight"))
876876 let W2 = tryGetInteger((("static_" + assetIdStr) + "_weight"))
877877 let W1W2 = fraction(W1, 10000, W2)
878878 let W2W1 = fraction(W2, 10000, W1)
879879 let p1_unweighted = fraction((B1 - F1), S1, fraction(B2, pow(fraction(B1, S1, (B1 - F1)), D1, W1W2, 4, D1, CEILING), S2))
880880 let p1 = fraction(p1_unweighted, W2W1, 10000)
881881 if ((B2 == F2))
882882 then $Tuple2(p1, unit)
883883 else {
884884 let p2_unweighted = fraction(fraction(B1, pow(fraction(B2, S2, (B2 - F2)), D2, W2W1, 4, D2, FLOOR), S2), S2, (B2 - F2))
885885 let p2 = fraction(p2_unweighted, W2W1, 10000)
886886 $Tuple2(p1, p2)
887887 }
888888 }
889889
890890
891891 @Callable(i)
892892 func addUnderlyingStaker (stakerAddress,assetIdStr) = if ((this != i.caller))
893893 then throw("admin only")
894894 else [StringEntry(("static_stakingContract_" + assetIdStr), stakerAddress)]
895895
896896
897897
898898 @Callable(i)
899899 func preInit (assetIdsStr,assetWeightsStr,assetMaxSelloffStr,baseTokenIdStr,poolDomain,poolOwner,fee) = {
900900 let poolOwnerAddress = addressFromStringValue(poolOwner)
901901 let assetIdsStrLi = split(assetIdsStr, ",")
902902 let assetMaxSelloffStrLi = split(assetMaxSelloffStr, ",")
903903 let assetWeightsStrLi = split(assetWeightsStr, ",")
904904 let assetIdsLi = {
905905 let $l = assetIdsStrLi
906906 let $s = size($l)
907907 let $acc0 = nil
908908 func $f4_1 ($a,$i) = if (($i >= $s))
909909 then $a
910910 else addAssetBytesToList($a, $l[$i])
911911
912912 func $f4_2 ($a,$i) = if (($i >= $s))
913913 then $a
914914 else throw("List size exceeds 10")
915915
916916 $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)
917917 }
918918 let feeAssetChosenStr = {
919919 let $l = assetIdsStrLi
920920 let $s = size($l)
921921 let $acc0 = ""
922922 func $f5_1 ($a,$i) = if (($i >= $s))
923923 then $a
924924 else checkFeeAsset($a, $l[$i])
925925
926926 func $f5_2 ($a,$i) = if (($i >= $s))
927927 then $a
928928 else throw("List size exceeds 10")
929929
930930 $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)
931931 }
932932 let feeAssetStr = if ((feeAssetChosenStr == ""))
933933 then baseTokenIdStr
934934 else feeAssetChosenStr
935935 if (isShutdown())
936936 then throw("contract is on stop")
937937 else if ((this != i.caller))
938938 then throw("admin only")
939939 else if ((size(poolDomain) > 13))
940940 then throw("too large pool domain")
941941 else if (if ((fee > 500))
942942 then true
943943 else (0 > fee))
944944 then throw("fee value must be between 0 and 500 (0-5%)")
945945 else if ((validateWeights(assetWeightsStrLi) != 10000))
946946 then throw(("weights sum should be 10000, current: " + toString(validateWeights(assetWeightsStrLi))))
947947 else {
948948 func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetIdsLi)))
949949 then accum
950950 else {
951951 let assetStakingAddress = {
952952 let @ = invoke(poolsHubAddress, "useEmptyContract", [("staker_" + assetIdsStrLi[assetNum])], nil)
953953 if ($isInstanceOf(@, "String"))
954954 then @
955955 else throw(($getType(@) + " couldn't be cast to String"))
956956 }
957957 if ((assetStakingAddress == assetStakingAddress))
958958 then {
959959 let assetDecimals = match assetIdsLi[assetNum] {
960960 case x: ByteVector =>
961961 value(assetInfo(x)).decimals
962962 case _ =>
963963 8
964964 }
965965 ((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]))), StringEntry(("static_stakingContract_" + assetIdsStrLi[assetNum]), assetStakingAddress)]) ++ (if ((assetMaxSelloffStrLi[assetNum] == ""))
966966 then nil
967967 else [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_maxSelloff"), (parseIntValue(assetMaxSelloffStrLi[assetNum]) * Scale12))]))
968968 }
969969 else throw("Strict value is not equal to itself.")
970970 }
971971
972972 ({
973973 let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
974974 let $s = size($l)
975975 let $acc0 = nil
976976 func $f6_1 ($a,$i) = if (($i >= $s))
977977 then $a
978978 else addTokenDataEntries($a, $l[$i])
979979
980980 func $f6_2 ($a,$i) = if (($i >= $s))
981981 then $a
982982 else throw("List size exceeds 10")
983983
984984 $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)
985985 } ++ [StringEntry("static_tokenIds", assetIdsStr), StringEntry("static_feeToken", feeAssetStr), StringEntry("static_tokenWeights", assetWeightsStr), IntegerEntry("static_tokensAmount", size(assetIdsLi)), StringEntry("static_poolDomain", poolDomain), StringEntry("static_poolToken_idStr", ""), StringEntry("static_baseTokenId", baseTokenIdStr), StringEntry("static_poolOwner", poolOwner), IntegerEntry("static_fee", fee), IntegerEntry("static_KMult", Scale16), IntegerEntry("global_indexStaked", 0), IntegerEntry("global_poolToken_amount", 0), IntegerEntry("global_wasPreInited", 1)])
986986 }
987987 }
988988
989989
990990
991991 @Callable(i)
992992 func deInit () = if (isShutdown())
993993 then throw("contract is on stop")
994994 else if ((i.caller != this))
995995 then throw("admin only")
996996 else [IntegerEntry("global_wasInited", 0)]
997997
998998
999999
10001000 @Callable(i)
10011001 func init (assetIdsStr,assetWeightsStr,assetMaxSelloffStr,baseTokenIdStr,poolDomain,fee,vBalancesStr) = {
10021002 let preInitInv = invoke(this, "preInit", [assetIdsStr, assetWeightsStr, assetMaxSelloffStr, baseTokenIdStr, poolDomain, toString(i.caller), fee], nil)
10031003 if ((preInitInv == preInitInv))
10041004 then {
10051005 let vBalances = parstStrToIntList(vBalancesStr)
10061006 func getPaymentAmount (assetIdStr) = {
10071007 func handler (accum,payment) = if ((getAssetString(payment.assetId) == assetIdsStr))
10081008 then payment.amount
10091009 else accum
10101010
10111011 let $l = i.payments
10121012 let $s = size($l)
10131013 let $acc0 = 0
10141014 func $f4_1 ($a,$i) = if (($i >= $s))
10151015 then $a
10161016 else handler($a, $l[$i])
10171017
10181018 func $f4_2 ($a,$i) = if (($i >= $s))
10191019 then $a
10201020 else throw("List size exceeds 10")
10211021
10221022 $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)
10231023 }
10241024
10251025 func prepareList () = {
10261026 func handler (accum,assetId) = {
10271027 let assetIdStr = getAssetString(assetId)
10281028 let n = value(indexOf(assetIds, assetId))
10291029 let paymentAmount = getPaymentAmount(assetIdStr)
10301030 let assetParams = loadGlobalTokenParams(assetIdStr)
10311031 let assetParamsUpd = $Tuple8(vBalances[n], paymentAmount, assetParams._3, assetParams._4, assetParams._5, assetParams._6, assetParams._7, assetParams._8)
10321032 (accum ++ [saveGlobalTokenParams(assetIdStr, assetParamsUpd)])
10331033 }
10341034
10351035 let $l = assetIds
10361036 let $s = size($l)
10371037 let $acc0 = nil
10381038 func $f4_1 ($a,$i) = if (($i >= $s))
10391039 then $a
10401040 else handler($a, $l[$i])
10411041
10421042 func $f4_2 ($a,$i) = if (($i >= $s))
10431043 then $a
10441044 else throw("List size exceeds 10")
10451045
10461046 $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)
10471047 }
10481048
10491049 func calculatePoolTokensAmount (assetId) = {
10501050 func handler (accum,assetId) = {
10511051 func handler2 (accum,n) = if ((n == assetId))
10521052 then value(indexOf(assetIds, n))
10531053 else accum
10541054
10551055 let Token = {
10561056 let $l = assetIds
10571057 let $s = size($l)
10581058 let $acc0 = 1
10591059 func $f4_1 ($a,$i) = if (($i >= $s))
10601060 then $a
10611061 else handler2($a, $l[$i])
10621062
10631063 func $f4_2 ($a,$i) = if (($i >= $s))
10641064 then $a
10651065 else throw("List size exceeds 10")
10661066
10671067 $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)
10681068 }
10691069 fraction(accum, pow(vBalances[Token], Decimals[Token], AssetsWeights[Token], AssetsWeightsDecimals, 8, FLOOR), Scale8)
10701070 }
10711071
10721072 let $l = assetIds
10731073 let $s = size($l)
10741074 let $acc0 = PoolTokenScale
10751075 func $f4_1 ($a,$i) = if (($i >= $s))
10761076 then $a
10771077 else handler($a, $l[$i])
10781078
10791079 func $f4_2 ($a,$i) = if (($i >= $s))
10801080 then $a
10811081 else throw("List size exceeds 10")
10821082
10831083 $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)
10841084 }
10851085
10861086 if (isShutdown())
10871087 then throw("contract is on stop")
10881088 else if ((size(i.payments) == 0))
10891089 then throw("at least some of the assets should be provided as payment")
10901090 else if ((tryGetInteger("global_wasInited") > 0))
10911091 then throw("pool already inited")
10921092 else {
10931093 let initialPoolTokens = calculatePoolTokensAmount(assetIds)
10941094 let notifyInvoke = invoke(poolsHubAddress, "addSelfPool", nil, nil)
10951095 if ((notifyInvoke == notifyInvoke))
10961096 then if ((initialPoolTokens == 0))
10971097 then throw("you need a bigger tokens amount to launch the pool")
10981098 else (prepareList() ++ [IntegerEntry("global_poolToken_amount", initialPoolTokens), IntegerEntry("global_wasInited", 1), IntegerEntry((toString(i.caller) + "_indexStaked"), initialPoolTokens), IntegerEntry("global_indexStaked", initialPoolTokens)])
10991099 else throw("Strict value is not equal to itself.")
11001100 }
11011101 }
11021102 else throw("Strict value is not equal to itself.")
11031103 }
11041104
11051105
11061106
11071107 @Callable(i)
11081108 func generateIndex (needChange) = if ((size(i.payments) != T))
11091109 then throw(("you need to attach all pool tokens. amount of pool tokens: " + toString(T)))
11101110 else if (!(checkTokensValidity(i.payments)))
11111111 then throw("wrong assets attached")
11121112 else {
11131113 let PIssuedNoMult = getMinPIssued(i.payments)
11141114 let result = handlePoolTokensAdd(PIssuedNoMult, i.payments, i.originCaller, needChange)
11151115 let PIssuedWithMult = fraction(PIssuedNoMult, Scale16, getKMult(), DOWN)
11161116 $Tuple2((((result ++ claimResult(i.caller)._1) ++ mintIndexIfNeeded(PIssuedWithMult)) ++ [IntegerEntry((toString(i.caller) + "_indexStaked"), (tryGetInteger((toString(i.caller) + "_indexStaked")) + PIssuedWithMult)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") + PIssuedWithMult)), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") + PIssuedWithMult))]), PIssuedWithMult)
11171117 }
11181118
11191119
11201120
11211121 @Callable(i)
11221122 func redeemIndex (poolTokenAmount) = if ((poolTokenAmount > tryGetInteger((toString(i.caller) + "_indexStaked"))))
11231123 then throw("user doesn't have this amount of pool tokens")
11241124 else if (isShutdown())
11251125 then throw("contract is on stop")
11261126 else {
11271127 let PRedeemedWithMult = poolTokenAmount
11281128 let PRedeemedWithNoMult = fraction(PRedeemedWithMult, getKMult(), Scale16, DOWN)
11291129 let result = handlePoolTokensRedeem(PRedeemedWithNoMult, i.caller)
11301130 (((result ++ claimResult(i.caller)._1) ++ [IntegerEntry((toString(i.caller) + "_indexStaked"), (tryGetInteger((toString(i.caller) + "_indexStaked")) - PRedeemedWithMult)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - PRedeemedWithMult)), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemedWithMult))]) ++ burnIndexIfNeeded(poolTokenAmount))
11311131 }
11321132
11331133
11341134
11351135 @Callable(i)
11361136 func stakeIndex () = {
11371137 let addressStr = toString(i.originCaller)
11381138 let pmt = i.payments[0]
11391139 if ((value(pmt.assetId) != fromBase58String(tryGetString("static_poolToken_idStr"))))
11401140 then throw("wrong asset attached")
11411141 else indexStakeResult(addressStr, pmt.amount)
11421142 }
11431143
11441144
11451145
11461146 @Callable(i)
11471147 func stakeIndexFor (addressStr) = {
11481148 let pmt = i.payments[0]
11491149 if ((value(pmt.assetId) != fromBase58String(tryGetString("static_poolToken_idStr"))))
11501150 then throw("wrong asset attached")
11511151 else indexStakeResult(addressStr, pmt.amount)
11521152 }
11531153
11541154
11551155
11561156 @Callable(i)
11571157 func unstakeIndex (indexAmount) = {
11581158 func issueIndex () = {
11591159 let issue = Issue(("PR " + tryGetString("static_poolDomain")), "Puzzle Range Index", tryGetInteger("global_poolToken_amount"), PoolTokenDecimals, true, unit, 0)
11601160 let poolTokenIdStr = toBase58String(calculateAssetId(issue))
11611161 $Tuple2([issue, StringEntry("static_poolToken_idStr", poolTokenIdStr)], poolTokenIdStr)
11621162 }
11631163
11641164 let $t04195442120 = if ((tryGetString("static_poolToken_idStr") == ""))
11651165 then issueIndex()
11661166 else $Tuple2(nil, tryGetString("static_poolToken_idStr"))
11671167 let poolTokenIssueResult = $t04195442120._1
11681168 let poolTokenIdStr = $t04195442120._2
11691169 let poolTokenId = fromBase58String(poolTokenIdStr)
11701170 let addressStr = toString(i.caller)
11711171 let indexAvailable = tryGetInteger((addressStr + "_indexStaked"))
11721172 if (isShutdown())
11731173 then throw("contract is on stop")
11741174 else if ((indexAmount > indexAvailable))
11751175 then throw("you don't have index tokens available")
11761176 else if (isShutdown())
11771177 then throw("contract is on stop")
11781178 else ((poolTokenIssueResult ++ claimResult(addressFromStringValue(addressStr))._1) ++ [IntegerEntry((addressStr + "_indexStaked"), (indexAvailable - indexAmount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - indexAmount)), ScriptTransfer(i.caller, indexAmount, poolTokenId)])
11791179 }
11801180
11811181
11821182
11831183 @Callable(i)
11841184 func claimIndexRewards () = if (isShutdown())
11851185 then throw("contract is on stop")
11861186 else claimResult(i.caller)
11871187
11881188
11891189
11901190 @Callable(i)
11911191 func evaluateClaim (user) = $Tuple2(nil, claimResult(addressFromStringValue(user))._2)
11921192
11931193
11941194
11951195 @Callable(i)
11961196 func addInterestExternal () = {
11971197 let assetId = value(i.payments[0]).assetId
11981198 let assetIdStr = getAssetString(assetId)
11991199 let amount = i.payments[0].amount
12001200 let stakeTx = stakeIfNeeded(assetIdStr, amount)
12011201 if ((stakeTx == stakeTx))
12021202 then if ((indexOf(assetIds, assetId) == unit))
12031203 then throw("you can only add interest for assets in the pool")
12041204 else {
12051205 let params = loadGlobalTokenParams(assetIdStr)
12061206 let interestDelta = calcInterestChange(assetIdStr, amount)
12071207 let updParams = $Tuple8(params._1, params._2, params._3, (params._4 + interestDelta), (params._5 + amount), params._6, params._7, params._8)
12081208 [saveGlobalTokenParams(assetIdStr, updParams)]
12091209 }
12101210 else throw("Strict value is not equal to itself.")
12111211 }
12121212
12131213
12141214
12151215 @Callable(i)
12161216 func notifyStakingPayment (assetIdStr,amount) = {
12171217 let assetId = getAssetBytes(assetIdStr)
12181218 if ((indexOf(assetIds, assetId) == unit))
12191219 then throw("you can only add interest for assets in the pool")
12201220 else if ((tryGetString(("static_stakingContract_" + assetIdStr)) != toString(i.caller)))
12211221 then throw("can only be invoked by staker contract")
12221222 else {
12231223 let params = loadGlobalTokenParams(assetIdStr)
12241224 let interestDelta = calcInterestChange(assetIdStr, amount)
12251225 let updParams = $Tuple8(params._1, params._2, params._3, (params._4 + interestDelta), (params._5 + amount), params._6, params._7, params._8)
12261226 [saveGlobalTokenParams(assetIdStr, updParams)]
12271227 }
12281228 }
12291229
12301230
12311231
12321232 @Callable(i)
12331233 func swap (assetOut,minimum) = {
12341234 let pmt = if ((size(i.payments) == 1))
12351235 then value(i.payments[0])
12361236 else throw("please attach exactly one payment")
12371237 let AmountIn = value(i.payments[0].amount)
12381238 let AssetIn = pmt.assetId
12391239 let AssetOut = getAssetBytes(assetOut)
12401240 let assetIn = getAssetString(AssetIn)
12411241 let scaleIn = (Scale8 / tryGetInteger((("static_" + assetIn) + "_scale")))
12421242 let scaleOut = (Scale8 / tryGetInteger((("static_" + assetOut) + "_scale")))
12431243 let assetInParams = loadGlobalTokenParams(getAssetString(AssetIn))
12441244 let assetOutParams = loadGlobalTokenParams(assetOut)
12451245 let AssetInBalance = assetInParams._1
12461246 let AssetInFactBalance = assetInParams._2
12471247 let assetInFeesEarned = assetInParams._3
12481248 let assetInLastCheckInterest = assetInParams._4
12491249 let AssetOutBalance = assetOutParams._1
12501250 let assetOutFactBalance = assetOutParams._2
12511251 let AssetInBalanceScaled = (AssetInBalance * scaleIn)
12521252 let AssetOutBalanceScaled = (AssetOutBalance * scaleOut)
12531253 let feeAmountIn = fraction(AmountIn, Fee, FeeScale)
12541254 let cleanAmountIn = (AmountIn - feeAmountIn)
12551255 let cleanAmountInScaled = (cleanAmountIn * scaleIn)
12561256 let AmountOut1 = calculateOutAmount(cleanAmountInScaled, AssetIn, AssetOut, AssetInBalanceScaled, AssetOutBalanceScaled)
12571257 let AmountOut = fraction(AmountOut1, 1, scaleOut)
12581258 let AssetOutBalance2 = (AssetOutBalance - AmountOut)
12591259 let AssetInBalance2 = (AssetInBalance + cleanAmountIn)
12601260 if ((minimum > AmountOut))
12611261 then throw("amount to recieve is lower than given one")
12621262 else if ((AssetOut == AssetIn))
12631263 then throw("this swap is not allowed")
12641264 else if ((0 > (assetOutFactBalance - AmountOut)))
12651265 then throw("contract is out of reserves")
12661266 else if (isShutdown())
12671267 then throw("contract is on stop")
12681268 else if (valueOrElse(getBoolean(poolsHubAddress, ("global_shutdownIn_" + assetIn)), false))
12691269 then throw("token IN trades are stopped")
12701270 else if (valueOrElse(getBoolean(poolsHubAddress, ("global_shutdownOut_" + assetOut)), false))
12711271 then throw("token OUT trades are stopped")
12721272 else {
12731273 let protocolFee = fraction(feeAmountIn, 5, 10)
12741274 let lpFee = (feeAmountIn - protocolFee)
12751275 let interestDelta = calcInterestChange(assetIn, lpFee)
12761276 let stakeTx = stakeIfNeeded(assetIn, (cleanAmountIn + lpFee))
12771277 if ((stakeTx == stakeTx))
12781278 then {
12791279 let unstakeTx = unstakeIfNeeded(assetOut, AmountOut)
12801280 if ((unstakeTx == unstakeTx))
12811281 then {
12821282 let newBalanceIn = AssetInBalance2
12831283 let newBalanceOut = AssetOutBalance2
12841284 let assetInSelloffData = updSelloffData(assetIn, cleanAmountIn, AssetInBalance, $Tuple3(assetInParams._6, assetInParams._7, assetInParams._8))
12851285 let assetOutSelloffData = updSelloffData(assetOut, -(AmountOut), AssetOutBalance, $Tuple3(assetOutParams._6, assetOutParams._7, assetOutParams._8))
12861286 let assetInFinalParams = $Tuple8(newBalanceIn, (AssetInFactBalance + cleanAmountIn), (assetInFeesEarned + lpFee), (assetInLastCheckInterest + interestDelta), assetInParams._5, assetInSelloffData._1, assetInSelloffData._2, assetInSelloffData._3)
12871287 let assetOutFinalParams = $Tuple8(newBalanceOut, (assetOutFactBalance - AmountOut), assetOutParams._3, assetOutParams._4, assetOutParams._5, assetOutSelloffData._1, assetOutSelloffData._2, assetOutSelloffData._3)
12881288 let assetInChange = saveGlobalTokenParams(assetIn, assetInFinalParams)
12891289 let assetOutChange = saveGlobalTokenParams(assetOut, assetOutFinalParams)
12901290 let feeAssetStr = tryGetString("static_feeToken")
12911291 let feeAssetParams = loadGlobalTokenParams(feeAssetStr)
12921292 let feeTokenBalance = feeAssetParams._1
12931293 let volumeUsdUpdate = calculateUsdValue(AssetIn, AmountIn, AssetInBalance, feeTokenBalance)
12941294 $Tuple2([assetInChange, assetOutChange, ScriptTransfer(i.caller, AmountOut, AssetOut), IntegerEntry("global_volume_usd", (tryGetInteger("global_volume_usd") + volumeUsdUpdate)), ScriptTransfer(feesAddress, protocolFee, getAssetBytes(assetIn))], AmountOut)
12951295 }
12961296 else throw("Strict value is not equal to itself.")
12971297 }
12981298 else throw("Strict value is not equal to itself.")
12991299 }
13001300 }
13011301
13021302
13031303
13041304 @Callable(i)
13051305 func swapReadOnly (assetIn,assetOut,AmountIn) = {
13061306 let AssetIn = getAssetBytes(assetIn)
13071307 let AssetOut = getAssetBytes(assetOut)
13081308 let scaleIn = (Scale8 / tryGetInteger((("static_" + assetIn) + "_scale")))
13091309 let scaleOut = (Scale8 / tryGetInteger((("static_" + assetOut) + "_scale")))
13101310 let feeAssetOutStr = tryGetString("static_feeToken")
13111311 let feeAssetOut = if ((feeAssetOutStr == ""))
13121312 then usdnAssetId
13131313 else getAssetBytes(feeAssetOutStr)
13141314 let assetInParams = loadGlobalTokenParams(getAssetString(AssetIn))
13151315 let assetOutParams = loadGlobalTokenParams(assetOut)
13161316 let AssetInBalance = assetInParams._1
13171317 let AssetInFactBalance = assetInParams._2
13181318 let assetInFeesEarned = assetInParams._3
13191319 let assetInLastCheckInterest = assetInParams._4
13201320 let AssetOutBalance = assetOutParams._1
13211321 let assetOutFactBalance = assetOutParams._2
13221322 let AssetInBalanceScaled = (AssetInBalance * scaleIn)
13231323 let AssetOutBalanceScaled = (AssetOutBalance * scaleOut)
13241324 let feeAmountIn = fraction(AmountIn, Fee, FeeScale)
13251325 let cleanAmountIn = (AmountIn - feeAmountIn)
13261326 let cleanAmountInScaled = (cleanAmountIn * scaleIn)
13271327 let AmountOut1 = calculateOutAmount(cleanAmountInScaled, AssetIn, AssetOut, AssetInBalanceScaled, AssetOutBalanceScaled)
13281328 let AmountOut = fraction(AmountOut1, 1, scaleOut)
13291329 let AssetOutBalance2 = (AssetOutBalance - AmountOut)
13301330 let AssetInBalance2 = (AssetInBalance + cleanAmountIn)
13311331 if ((AssetOut == AssetIn))
13321332 then throw("this swap is not allowed")
13331333 else if ((0 > (getFactBalance(assetOut) - AmountOut)))
13341334 then throw("contract is out of reserves")
13351335 else if (isShutdown())
13361336 then throw("contract is on stop")
13371337 else $Tuple2(nil, AmountOut)
13381338 }
13391339
13401340
13411341
13421342 @Callable(i)
13431343 func transferOwnership (newOwnerAddress) = if ((toString(i.caller) != tryGetString("static_poolOwner")))
13441344 then throw("this call available only for pool owner")
13451345 else [StringEntry("static_poolOwner", newOwnerAddress)]
13461346
13471347
13481348
13491349 @Callable(i)
13501350 func setFee (newFee) = if ((toString(i.caller) != tryGetString("static_poolOwner")))
13511351 then throw("this call available only for pool owner")
13521352 else [IntegerEntry("static_fee", newFee)]
13531353
13541354
13551355 @Verifier(tx)
13561356 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], masterPubKey)
13571357

github/deemru/w8io
123.04 ms