tx · 3Cogxta8DijDxaLPXFSqGcEeaz6yd5WB4zScGQykidxd

3M6YWiE3651WV8x5LmeRQJXZ6nVGNW1tWKi:  -0.10000000 Waves

2026.05.06 02:42 [537308] smart account 3M6YWiE3651WV8x5LmeRQJXZ6nVGNW1tWKi > SELF 0.00000000 Waves

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

github/deemru/w8io
221.88 ms