tx · FqHW5ogqJ7f1imh5WvBE7ct3CKkYXtmVXzSwY9VZZ614

3M8YQErH3CFFKCSVjTwJsH1bQ6LTU2ZYZgq:  -0.06000000 Waves

2026.06.01 23:10 [765023] smart account 3M8YQErH3CFFKCSVjTwJsH1bQ6LTU2ZYZgq > SELF 0.00000000 Waves

{ "type": 13, "id": "FqHW5ogqJ7f1imh5WvBE7ct3CKkYXtmVXzSwY9VZZ614", "fee": 6000000, "feeAssetId": null, "timestamp": 1780344659956, "version": 2, "chainId": 82, "sender": "3M8YQErH3CFFKCSVjTwJsH1bQ6LTU2ZYZgq", "senderPublicKey": "7zhnoXjr7tdythegoSdGENwZujficycCDsS8Qs42hwjb", "proofs": [ "2J2AjXz7V4SRYwKVbNo6FpF6WJUWxUNCrmnzYT4c1bS5M3om7irzBKLvNV3D87FCKhN9bRo8W6trA9TwiPir8d1u" ], "script": "base64:BgJhCAISBAoCCAgSCQoHCAgICAgIARIDCgEIEgASCQoHCAgICAgBCBIDCgEEEgMKAQESABIDCgEIEgMKAQESABIDCgEIEgASBAoCCAESBAoCCAESBQoDCAgBEgMKAQgSAwoBAW4AB1ZFUlNJT04CDVBaLTMuOS4wIFBST0QADUNPTlRSQUNUX1RZUEUCC1JBTkdFRF9QT09MAA1XQVZFU19SRVNFUlZFAICt4gQACWNvbmZpZ1N0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzAg1jb25maWdBZGRyZXNzAiMzUFBFQlJnNHMyYWYyclEyWmJMdmR1MUhmZDRWbzZRVkRUbwAOQ09ORklHX0FERFJFU1MDCQAAAgUJY29uZmlnU3RyAgAFBHRoaXMJAQdBZGRyZXNzAQkA2QQBBQljb25maWdTdHIAFUFzc2V0c1dlaWdodHNEZWNpbWFscwAEAAVTY2FsZQCQTgAGU2NhbGU4AIDC1y8ACVNjYWxlOF9CSQkAtgIBBQZTY2FsZTgAB1NjYWxlMTIAgKCUpY0dAAdTY2FsZTE2AICAhP6m3uERAApTY2FsZTE2X0JJCQC2AgEFB1NjYWxlMTYACEZlZVNjYWxlAJBOABFQb29sVG9rZW5EZWNpbWFscwAIAA5Qb29sVG9rZW5TY2FsZQkAbAYACgAABRFQb29sVG9rZW5EZWNpbWFscwAAAAAFBkhBTEZVUAAQTUlOX1NURVBTX0FNT1VOVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5DT05GSUdfQUREUkVTUwIQbWluX3N0ZXBzX2Ftb3VudAABABBNQVhfU1RFUFNfQU1PVU5UCQELdmFsdWVPckVsc2UCCQCaCAIFDkNPTkZJR19BRERSRVNTAhBtYXhfc3RlcHNfYW1vdW50APQDABJNSU5fU1RFUFNfSU5URVJWQUwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOQ09ORklHX0FERFJFU1MCEm1pbl9zdGVwc19pbnRlcnZhbAABABJNQVhfU1RFUFNfSU5URVJWQUwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOQ09ORklHX0FERFJFU1MCEm1heF9zdGVwc19pbnRlcnZhbACQTgAKTUlOX1dFSUdIVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5DT05GSUdfQUREUkVTUwIKbWluX3dlaWdodABkAApNQVhfV0VJR0hUCQELdmFsdWVPckVsc2UCCQCaCAIFDkNPTkZJR19BRERSRVNTAgptYXhfd2VpZ2h0AKxNAQ10cnlHZXRJbnRlZ2VyAQNrZXkEByRtYXRjaDAJAJoIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACA0ludAQBYgUHJG1hdGNoMAUBYgAAAQx0cnlHZXRCaW5hcnkBA2tleQQHJG1hdGNoMAkAnAgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYgUHJG1hdGNoMAUBYgEAAQx0cnlHZXRTdHJpbmcBA2tleQQHJG1hdGNoMAkAnQgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFiBQckbWF0Y2gwBQFiAgABE3RyeUdldFN0cmluZ09yVGhyb3cBA2tleQQHJG1hdGNoMAkAnQgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFiBQckbWF0Y2gwBQFiCQACAQkArAICAh1ubyBzdWNoIGtleSBpbiBkYXRhIHN0b3JhZ2U6IAUDa2V5AQ5nZXRBc3NldFN0cmluZwEHYXNzZXRJZAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAFiBQckbWF0Y2gwCQDYBAEFAWICBVdBVkVTAQ1nZXRBc3NldEJ5dGVzAQphc3NldElkU3RyAwkAAAIFCmFzc2V0SWRTdHICBVdBVkVTBQR1bml0CQDZBAEFCmFzc2V0SWRTdHIBD2dldFRva2VuQmFsYW5jZQEHYXNzZXRJZAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAF0BQckbWF0Y2gwCQDwBwIFBHRoaXMFAXQICQDvBwEFBHRoaXMHcmVndWxhcgEOZ2V0Tm9kZUFkZHJlc3MABA5ub2RlQWRkcmVzc1N0cgkBDHRyeUdldFN0cmluZwECEnN0YXRpY19ub2RlQWRkcmVzcwMJAAACBQ5ub2RlQWRkcmVzc1N0cgIABQR1bml0CQCmCAEFDm5vZGVBZGRyZXNzU3RyARVyZWJhbGFuY2VMZWFzZUFjdGlvbnMCCHdhdmVzT3V0CG5vZGVBZGRyBAtfaXNQb3NpdGl2ZQMJAGYCAAAFCHdhdmVzT3V0CQACAQIhbmVnYXRpdmUgYW1vdW50IG9mIFdBVkVTIHRvIGxlYXNlBgMJAAACBQtfaXNQb3NpdGl2ZQULX2lzUG9zaXRpdmUEDmN1cnJlbnRMZWFzZUlkCQEMdHJ5R2V0U3RyaW5nAQISZ2xvYmFsX2xhc3RMZWFzZUlkBBFjYW5jZWxMZWFzZUFjdGlvbgMJAQIhPQIFDmN1cnJlbnRMZWFzZUlkAgAJAMwIAgkBC0xlYXNlQ2FuY2VsAQkA2QQBBQ5jdXJyZW50TGVhc2VJZAUDbmlsBQNuaWwEByRtYXRjaDAFCG5vZGVBZGRyAwkAAQIFByRtYXRjaDACB0FkZHJlc3MEBG5vZGUFByRtYXRjaDAEDm5ld0xlYXNlQW1vdW50CQBlAgkAZQIICQDvBwEFBHRoaXMHcmVndWxhcgUId2F2ZXNPdXQFDVdBVkVTX1JFU0VSVkUDCQBmAgUObmV3TGVhc2VBbW91bnQAAAQLbGVhc2VBY3Rpb24JAMQIAgUEbm9kZQUObmV3TGVhc2VBbW91bnQECm5ld0xlYXNlSWQJANgEAQkAuQgBBQtsZWFzZUFjdGlvbgMJAAACBQpuZXdMZWFzZUlkBQ5jdXJyZW50TGVhc2VJZAUDbmlsCQDOCAIFEWNhbmNlbExlYXNlQWN0aW9uCQDMCAIFC2xlYXNlQWN0aW9uCQDMCAIJAQtTdHJpbmdFbnRyeQICEmdsb2JhbF9sYXN0TGVhc2VJZAUKbmV3TGVhc2VJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgIWZ2xvYmFsX2xhc3RMZWFzZUFtb3VudAUObmV3TGVhc2VBbW91bnQFA25pbAkAzggCBRFjYW5jZWxMZWFzZUFjdGlvbgMJAQIhPQIFDmN1cnJlbnRMZWFzZUlkAgAJAMwIAgkBC0RlbGV0ZUVudHJ5AQISZ2xvYmFsX2xhc3RMZWFzZUlkCQDMCAIJAQtEZWxldGVFbnRyeQECFmdsb2JhbF9sYXN0TGVhc2VBbW91bnQFA25pbAUDbmlsCQDOCAIFEWNhbmNlbExlYXNlQWN0aW9uAwkBAiE9AgUOY3VycmVudExlYXNlSWQCAAkAzAgCCQELRGVsZXRlRW50cnkBAhJnbG9iYWxfbGFzdExlYXNlSWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQIWZ2xvYmFsX2xhc3RMZWFzZUFtb3VudAUDbmlsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BE2FkZEFzc2V0Qnl0ZXNUb0xpc3QCBWFjY3VtBGl0ZW0JAM4IAgUFYWNjdW0JAMwIAgkBDWdldEFzc2V0Qnl0ZXMBBQRpdGVtBQNuaWwBFGFkZEFzc2V0V2VpZ2h0VG9MaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18JAQ5nZXRBc3NldFN0cmluZwEFBGl0ZW0CB193ZWlnaHQFA25pbAEXYWRkQXNzZXRXZWlnaHRUb1N0ckxpc3QCBWFjY3VtBGl0ZW0JAM4IAgUFYWNjdW0JAMwIAgkApAMBCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQRpdGVtAgdfd2VpZ2h0BQNuaWwBFmFkZEFzc2V0RGVjaW1hbHNUb0xpc3QCBWFjY3VtBGl0ZW0JAM4IAgUFYWNjdW0JAMwIAgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwkBDmdldEFzc2V0U3RyaW5nAQUEaXRlbQIJX2RlY2ltYWxzBQNuaWwBE2FkZEFzc2V0U2NhbGVUb0xpc3QCBWFjY3VtBGl0ZW0JAM4IAgUFYWNjdW0JAMwIAgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwkBDmdldEFzc2V0U3RyaW5nAQUEaXRlbQIGX3NjYWxlBQNuaWwBDGFkZEludFRvTGlzdAIFYWNjdW0EaXRlbQkAzggCBQVhY2N1bQkAzAgCCQENcGFyc2VJbnRWYWx1ZQEFBGl0ZW0FA25pbAERcGFyc3RTdHJUb0ludExpc3QBAXMKAQFmAgVhY2N1bQRuZXh0CQDOCAIFBWFjY3VtCQDMCAIJAQ1wYXJzZUludFZhbHVlAQUEbmV4dAUDbmlsCgACJGwJALUJAgUBcwIBLAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEBZgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgAOdXNkbkFzc2V0SWRTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDnVzZG5Bc3NldElkU3RyAixERzJ4RmtQZER3S1VvQmt6R0FoUXRMcFNHemZYTGlDWVBFemVLSDJBZDI0cAAQcHV6emxlQXNzZXRJZFN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIQcHV6emxlQXNzZXRJZFN0cgIsSEVCOFFhdzl4cldwV3M4dEhzaUFUWUdCV0RCdFAyUzdrY1BBTHJNdTQzQVMADnVzZHRBc3NldElkU3RyCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg51c2R0QXNzZXRJZFN0cgIsMzROOVljRUVUTFduOTNxWVE2NEVzUDF4ODl0U3J1SlU0NFJyRU1TWFhFUEoAEXVzZHRQcHRBc3NldElkU3RyCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAhF1c2R0UHB0QXNzZXRJZFN0cgIsOXdjM0xYTkE0VEVCc1h5S3RvTEU5bXJiREQ3V01IWHZYckNqWnZhYkxBc2kADnJvbWVBc3NldElkU3RyCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg5yb21lQXNzZXRJZFN0cgIsQVA0Q2I1eExZR0g2WmlnSHJlQ1pIb1hwUVRXRGtQc0cyQkhxZkRVeDZ0YUoAD3dhdmVzQXNzZXRJZFN0cgIFV0FWRVMAC3VzZG5Bc3NldElkCQDZBAEFDnVzZG5Bc3NldElkU3RyAA1wdXp6bGVBc3NldElkCQDZBAEFEHB1enpsZUFzc2V0SWRTdHIAC3VzZHRBc3NldElkCQDZBAEFDnVzZHRBc3NldElkU3RyAA51c2R0UHB0QXNzZXRJZAkA2QQBBRF1c2R0UHB0QXNzZXRJZFN0cgALcm9tZUFzc2V0SWQJANkEAQUOcm9tZUFzc2V0SWRTdHIADHdhdmVzQXNzZXRJZAUEdW5pdAAVc3VwcG9ydGVkRmVlQXNzZXRzU3RyCQDMCAIFDnVzZG5Bc3NldElkU3RyCQDMCAIFEHB1enpsZUFzc2V0SWRTdHIJAMwIAgUOdXNkdEFzc2V0SWRTdHIJAMwIAgURdXNkdFBwdEFzc2V0SWRTdHIJAMwIAgUPd2F2ZXNBc3NldElkU3RyCQDMCAIFDnJvbWVBc3NldElkU3RyBQNuaWwAEXBhcmVudFBvb2xBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIRcGFyZW50UG9vbEFkZHJlc3MCIzNQRkRnenUxVXRzd0FrQ014cXFRamJUZUhhWDRjTWFiOEtoAA1tYXN0ZXJBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwINbWFzdGVyQWRkcmVzcwIjM1BMandIY3o5TkV1YVRvNjNOWlI5Qjlva1FpS1F4WlNibWYADG1hc3RlclB1YktleQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAgxtYXN0ZXJQdWJLZXkCLDR6OENLU1lRQktreng3UEJiNXVCUDFZUGE2WUFIUk5UQXBXMXNRVkhUNWVVAA1vcmFjbGVBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwINb3JhY2xlQWRkcmVzcwIjM1A4ZDFFMUJMS29ENTJ5M2JRSjFiRFRkMlREMWdwYUxuOXQADnN0YWtpbmdBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIOc3Rha2luZ0FkZHJlc3MCIzNQRlRieXdxeHRGZnVrWDNIeVQ4ODFnNGlXNUs0UUwzRkFTAAtmZWVzQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCC2ZlZXNBZGRyZXNzAiMzUEZXQVZLbVhqZkhYeXpKYjEyakNiaFA0VWhpOXQ0dVdpRAAPcG9vbHNIdWJBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIPcG9vbHNIdWJBZGRyZXNzAiMzUDVSR1l5Q25FTEY4SlRQeGdYNTRkQkd6d2tRTUtVSjVINwASc2h1dGRvd25BZGRyZXNzU3RyCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg9zaHV0ZG93bkFkZHJlc3MCIzNQRXB2OWhSRldFRUJVMjJXUm5Mc3cxYkg0WUd0Y1U3MjhvAA9sYXllcjJBZGRyZXNzZXMJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCD2xheWVyMkFkZHJlc3NlcwJHM1BSMVF2aTltSFQzNVN3V0VrTFNxcUUyTDh0aGlQTGRWV1UsM1BRb0JmVUtIa0pBZUdXaG9vTFA3V1M4b3ZiNTRhdjlKcDIACmdvdkFkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAgpnb3ZBZGRyZXNzAiMzUDZ1cm85eENzRTh0ZTc4UVpqenF5N2FxOG5hdFN6ZGNlQwARY29sZE1hc3RlckFkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAhFjb2xkTWFzdGVyQWRkcmVzcwIjM1BLOW5oUGZQYk1CeWdCOVpnSFZNSGFRYlNvb2p3ckJmeGoAAVQJAQ10cnlHZXRJbnRlZ2VyAQITc3RhdGljX3Rva2Vuc0Ftb3VudAAIYXNzZXRJZHMKAAIkbAkAtQkCCQEMdHJ5R2V0U3RyaW5nAQIPc3RhdGljX3Rva2VuSWRzAgEsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARNhZGRBc3NldEJ5dGVzVG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAA1Bc3NldHNXZWlnaHRzCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYxXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARRhZGRBc3NldFdlaWdodFRvTGlzdAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjFfMgIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgAIRGVjaW1hbHMKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjJfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBFmFkZEFzc2V0RGVjaW1hbHNUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjJfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYyXzICCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoABlNjYWxlcwoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmM18xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQETYWRkQXNzZXRTY2FsZVRvTGlzdAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmM18yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjNfMgIJAQUkZjNfMQIJAQUkZjNfMQIJAQUkZjNfMQIJAQUkZjNfMQIJAQUkZjNfMQIJAQUkZjNfMQIJAQUkZjNfMQIJAQUkZjNfMQIJAQUkZjNfMQIJAQUkZjNfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgADRmVlCQENdHJ5R2V0SW50ZWdlcgECCnN0YXRpY19mZWUADGVhcm5lZEFzc2V0cwUIYXNzZXRJZHMBBF9nZXQCB2Fzc2V0SWQFcGFyYW0JAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIJAKwCAgIHZ2xvYmFsXwUHYXNzZXRJZAIBXwUFcGFyYW0BD19nZXRfZmVlc0Vhcm5lZAEHYXNzZXRJZAkBDXRyeUdldEludGVnZXIBCQCsAgICEmdsb2JhbF9mZWVzRWFybmVkXwUHYXNzZXRJZAEXX2dldF9sYXN0Q2hlY2tfaW50ZXJlc3QBB2Fzc2V0SWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICEWdsb2JhbF9sYXN0Q2hlY2tfBQdhc3NldElkAglfaW50ZXJlc3QBEF9nZXRfZXh0cmFFYXJuZWQBB2Fzc2V0SWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAhNnbG9iYWxfZXh0cmFFYXJuZWRfBQdhc3NldElkARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBB2Fzc2V0SWQEByRtYXRjaDAJAKIIAQkArAICAg1nbG9iYWxQYXJhbXNfBQdhc3NldElkAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcAUHJG1hdGNoMAQGcGFyYW1zCQC1CQIFAXACAl9fCQCaCggJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZwYXJhbXMAAAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnBhcmFtcwABCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcGFyYW1zAAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZwYXJhbXMAAwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnBhcmFtcwAECQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcGFyYW1zAAUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZwYXJhbXMABgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnBhcmFtcwAHCQCaCggJAQRfZ2V0AgUHYXNzZXRJZAIHYmFsYW5jZQkBBF9nZXQCBQdhc3NldElkAgtmYWN0QmFsYW5jZQkBD19nZXRfZmVlc0Vhcm5lZAEFB2Fzc2V0SWQJARdfZ2V0X2xhc3RDaGVja19pbnRlcmVzdAEFB2Fzc2V0SWQJARBfZ2V0X2V4dHJhRWFybmVkAQUHYXNzZXRJZAkBBF9nZXQCBQdhc3NldElkAgdzZWxsb2ZmCQEEX2dldAIFB2Fzc2V0SWQCE3NlbGxvZmZTdGFydEJhbGFuY2UJAQRfZ2V0AgUHYXNzZXRJZAISc2VsbG9mZlN0YXJ0SGVpZ2h0ARVzYXZlR2xvYmFsVG9rZW5QYXJhbXMCB2Fzc2V0SWQGcGFyYW1zCQELU3RyaW5nRW50cnkCCQCsAgICDWdsb2JhbFBhcmFtc18FB2Fzc2V0SWQJALkJAgkAzAgCCQCkAwEIBQZwYXJhbXMCXzEJAMwIAgkApAMBCAUGcGFyYW1zAl8yCQDMCAIJAKQDAQgFBnBhcmFtcwJfMwkAzAgCCQCkAwEIBQZwYXJhbXMCXzQJAMwIAgkApAMBCAUGcGFyYW1zAl81CQDMCAIJAKQDAQgFBnBhcmFtcwJfNgkAzAgCCQCkAwEIBQZwYXJhbXMCXzcJAMwIAgkApAMBCAUGcGFyYW1zAl84BQNuaWwCAl9fAQppc1NodXRkb3duAAQPc2h1dGRvd25BZGRyZXNzCQCmCAEFEnNodXRkb3duQWRkcmVzc1N0cgMJAAACBQ9zaHV0ZG93bkFkZHJlc3MFBHVuaXQHBA5nbG9iYWxTaHV0ZG93bgQHJG1hdGNoMAkAmwgCCQEFdmFsdWUBBQ9zaHV0ZG93bkFkZHJlc3MCC2lzX3NodXRkb3duAwkAAQIFByRtYXRjaDACB0Jvb2xlYW4EAXgFByRtYXRjaDAFAXgHBAxwb29sU2h1dGRvd24JAQt2YWx1ZU9yRWxzZQIJAJsIAgkBBXZhbHVlAQUPc2h1dGRvd25BZGRyZXNzCQCsAgICDXBvb2xTaHV0ZG93bl8JAKUIAQUEdGhpcwcDBQ5nbG9iYWxTaHV0ZG93bgYFDHBvb2xTaHV0ZG93bgEOZ2V0RmFjdEJhbGFuY2UBCmFzc2V0SWRTdHIEC2Fzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKYXNzZXRJZFN0cggFC2Fzc2V0UGFyYW1zAl8yARZnZXRDdXJyZW50VG9rZW5CYWxhbmNlAQh0b2tlbk51bQQKdG9rZW5JZFN0cgkBDmdldEFzc2V0U3RyaW5nAQkAkQMCBQhhc3NldElkcwUIdG9rZW5OdW0EC3Rva2VuUGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKdG9rZW5JZFN0cggFC3Rva2VuUGFyYW1zAl8xAQ1zdGFrZUlmTmVlZGVkAgphc3NldElkU3RyBmFtb3VudAQHc3Rha2VUeAMJAQIhPQIJAQx0cnlHZXRTdHJpbmcBCQCsAgICF3N0YXRpY19zdGFraW5nQ29udHJhY3RfBQphc3NldElkU3RyAgAJAPwHBAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDHRyeUdldFN0cmluZwEJAKwCAgIXc3RhdGljX3N0YWtpbmdDb250cmFjdF8FCmFzc2V0SWRTdHICBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ1nZXRBc3NldEJ5dGVzAQUKYXNzZXRJZFN0cgUGYW1vdW50BQNuaWwFBHVuaXQDCQAAAgUHc3Rha2VUeAUHc3Rha2VUeAYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BD3Vuc3Rha2VJZk5lZWRlZAIKYXNzZXRJZFN0cgZhbW91bnQECXVuc3Rha2VUeAMJAQIhPQIJAQx0cnlHZXRTdHJpbmcBCQCsAgICF3N0YXRpY19zdGFraW5nQ29udHJhY3RfBQphc3NldElkU3RyAgAJAPwHBAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDHRyeUdldFN0cmluZwEJAKwCAgIXc3RhdGljX3N0YWtpbmdDb250cmFjdF8FCmFzc2V0SWRTdHICB3Vuc3Rha2UJAMwIAgUGYW1vdW50BQNuaWwFA25pbAUEdW5pdAMJAAACBQl1bnN0YWtlVHgFCXVuc3Rha2VUeAYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BEWJ1cm5JbmRleElmTmVlZGVkAQZhbW91bnQECmluZGV4SWRTdHIJAQx0cnlHZXRTdHJpbmcBAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyAwkAAAIFCmluZGV4SWRTdHICAAUDbmlsAwkAAAIJAOwHAQkA2QQBBQppbmRleElkU3RyBQR1bml0BQNuaWwJAMwIAgkBBEJ1cm4CCQDZBAEFCmluZGV4SWRTdHIFBmFtb3VudAUDbmlsARFtaW50SW5kZXhJZk5lZWRlZAEGYW1vdW50BAppbmRleElkU3RyCQEMdHJ5R2V0U3RyaW5nAQIWc3RhdGljX3Bvb2xUb2tlbl9pZFN0cgMJAAACBQppbmRleElkU3RyAgAFA25pbAMJAAACCQDsBwEJANkEAQUKaW5kZXhJZFN0cgUEdW5pdAUDbmlsCQDMCAIJAQdSZWlzc3VlAwkA2QQBBQppbmRleElkU3RyBQZhbW91bnQGBQNuaWwBCGdldEtNdWx0AAQHJG1hdGNoMAkAnwgBAgxzdGF0aWNfS011bHQDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4BQdTY2FsZTE2ARJzYXZlQ3VycmVudFdlaWdodHMABAphc3NldElkc0xpCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfdG9rZW5JZHMCASwKAQFzAgVhY2N1bQdhc3NldElkCQDOCAIFBWFjY3VtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICFnJlYmFsYW5jZV9zdGFydFdlaWdodF8FB2Fzc2V0SWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FB2Fzc2V0SWQCB193ZWlnaHQFA25pbAoAAiRsBQphc3NldElkc0xpCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAkAawMJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQJAQhnZXRLTXVsdAAFB1NjYWxlMTYBEGNhbGN1bGF0ZVBJc3N1ZWQCBmFtb3VudAd0b2tlbklkBAdQc3VwcGx5CQEZZ2V0VmlydHVhbFBvb2xUb2tlbkFtb3VudAAEB0JhbGFuY2UJAQ5nZXRGYWN0QmFsYW5jZQEJAQ5nZXRBc3NldFN0cmluZwEFB3Rva2VuSWQEAnQxCQBuBAUGYW1vdW50BQdQc3VwcGx5BQdCYWxhbmNlBQRET1dOBQJ0MQENZ2V0TWluUElzc3VlZAEIcGF5bWVudHMKAQdoYW5kbGVyAgVhY2N1bQdjdXJyZW50AwkAAAIJAQ5nZXRGYWN0QmFsYW5jZQEJAQ5nZXRBc3NldFN0cmluZwEIBQdjdXJyZW50B2Fzc2V0SWQAAAUFYWNjdW0EB1BJc3N1ZWQJARBjYWxjdWxhdGVQSXNzdWVkAggFB2N1cnJlbnQGYW1vdW50CAUHY3VycmVudAdhc3NldElkAwkAAAIFB1BJc3N1ZWQAAAkAAgECJG9uZSBvZiB0aGUgdG9rZW5zIGFtb3VudHMgaXMgdG9vIGxvdwMDCQAAAgUFYWNjdW0AAAYJAGYCBQVhY2N1bQUHUElzc3VlZAUHUElzc3VlZAUFYWNjdW0ECW1pblBJc3NlZAoAAiRsBQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgUJbWluUElzc2VkARJnZXRQcmljZUZyb21PcmFjbGUBCmFzc2V0SWRTdHIEByRtYXRjaDAJAJoIAgUNb3JhY2xlQWRkcmVzcwkArAICBQphc3NldElkU3RyAgdfdHdhcDVCAwkAAQIFByRtYXRjaDACA0ludAQBeAUHJG1hdGNoMAUBeAAAARFjYWxjdWxhdGVVc2RWYWx1ZQQHYXNzZXRJZAZhbW91bnQIYUJhbGFuY2UPZmVlQXNzZXRCYWxhbmNlBAthc3NldFdlaWdodAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAIHX3dlaWdodAQLZmVlQXNzZXRTdHIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfZmVlVG9rZW4EDWZlZUFzc2V0U2NhbGUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgkArAICAgdzdGF0aWNfBQtmZWVBc3NldFN0cgIGX3NjYWxlBAtmZWVBc3NldE51bQkBBXZhbHVlAQkAzwgCBQhhc3NldElkcwkBDWdldEFzc2V0Qnl0ZXMBBQtmZWVBc3NldFN0cgQOZmVlQXNzZXRXZWlnaHQJAJEDAgUNQXNzZXRzV2VpZ2h0cwULZmVlQXNzZXROdW0EB19hbW91bnQJALkCAgkAtgIBBQZhbW91bnQFCVNjYWxlOF9CSQQNX2ZlZUFzc2V0RGF0YQkAugICCQC2AgEFD2ZlZUFzc2V0QmFsYW5jZQkAtgIBBQ5mZWVBc3NldFdlaWdodAQKX2Fzc2V0RGF0YQkAvAIDCQC2AgEFCGFCYWxhbmNlBQlTY2FsZThfQkkJALYCAQULYXNzZXRXZWlnaHQEDXZhbEluRmVlQXNzZXQJAKADAQkAvAIDBQdfYW1vdW50BQ1fZmVlQXNzZXREYXRhBQpfYXNzZXREYXRhBA1mZWVBc3NldFByaWNlCQESZ2V0UHJpY2VGcm9tT3JhY2xlAQULZmVlQXNzZXRTdHIJAGsDBQ12YWxJbkZlZUFzc2V0BQ1mZWVBc3Nl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BSRhY2MwAAAKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoKARFoYW5kbGVUb2tlbkNoYW5nZQIFYWNjdW0HdG9rZW5JZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAQLYXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQphc3NldElkU3RyBA1wYXltZW50QW1vdW50CQEVZ2V0VG9rZW5QYXltZW50QW1vdW50AQUHdG9rZW5JZAQCQmsIBQthc3NldFBhcmFtcwJfMgQHUFN1cHBseQkBGWdldFZpcnR1YWxQb29sVG9rZW5BbW91bnQABAJEawkAoAMBCQC9AgQJALYCAQUHUElzc3VlZAkAtgIBBQJCawkAtgIBBQdQU3VwcGx5BQdDRUlMSU5HBAh0b1JldHVybgkAZQIFDXBheW1lbnRBbW91bnQFAkRrBAdzdGFrZVR4CQENc3Rha2VJZk5lZWRlZAIFCmFzc2V0SWRTdHIFAkRrAwkAAAIFB3N0YWtlVHgFB3N0YWtlVHgEAXQDAwUKbmVlZENoYW5nZQkAZgIFCHRvUmV0dXJuAAAHCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzBQh0b1JldHVybgUHdG9rZW5JZAUDbmlsBQNuaWwEE3NlbGxvZmZTdGFydEJhbGFuY2UDCQECIT0CCAULYXNzZXRQYXJhbXMCXzgJAGgCCQBpAgUGaGVpZ2h0AGQAZAgFC2Fzc2V0UGFyYW1zAl83CQBrAwgFC2Fzc2V0UGFyYW1zAl83CQBkAgUHUFN1cHBseQUHUElzc3VlZAUHUFN1cHBseQQOYXNzZXRQYXJhbXNVcGQJAJoKCAkAawMIBQthc3NldFBhcmFtcwJfMQkAZAIFB1BTdXBwbHkFB1BJc3N1ZWQFB1BTdXBwbHkJAGQCCAULYXNzZXRQYXJhbXMCXzIFAkRrCAULYXNzZXRQYXJhbXMCXzMIBQthc3NldFBhcmFtcwJfNAgFC2Fzc2V0UGFyYW1zAl81CAULYXNzZXRQYXJhbXMCXzYFE3NlbGxvZmZTdGFydEJhbGFuY2UIBQthc3NldFBhcmFtcwJfOAkAzggCCQDOCAIFBWFjY3VtBQF0CQDMCAIJARVzYXZlR2xvYmFsVG9rZW5QYXJhbXMCBQphc3NldElkU3RyBQ5hc3NldFBhcmFtc1VwZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARFoYW5kbGVUb2tlbkNoYW5nZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgEWY2FsY01pbnRlZFdpdGhPbmVUb2tlbgIPYXNzZXRBZGRlZElkU3RyBmFtb3VudAQHUFN1cHBseQkBGWdldFZpcnR1YWxQb29sVG9rZW5BbW91bnQABAthc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFD2Fzc2V0QWRkZWRJZFN0cgQQYXNzZXRGYWN0QmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl8yBBBhc3NldFZpcnRCYWxhbmNlCAULYXNzZXRQYXJhbXMCXzEEC2Fzc2V0V2VpZ2h0CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQ9hc3NldEFkZGVkSWRTdHICB193ZWlnaHQECmFzc2V0U2NhbGUJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FD2Fzc2V0QWRkZWRJZFN0cgIGX3NjYWxlBA1hc3NldERlY2ltYWxzCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQ9hc3NldEFkZGVkSWRTdHICCV9kZWNpbWFscwQTUElzc3VlZE5vTXVsdGlwbGllcgkAawMFB1BTdXBwbHkJAGUCCQCgAwEJAHYGCQC2AgEJAGQCBQphc3NldFNjYWxlCQBrAwUGYW1vdW50BQphc3NldFNjYWxlBRBhc3NldFZpcnRCYWxhbmNlBQ1hc3NldERlY2ltYWxzCQC2AgEFC2Fzc2V0V2VpZ2h0AAQACAUERE9XTgUGU2NhbGU4BQZTY2FsZTgEB2F2Z0NvbmMJARRjYWxjQXZnQ29uY2VudHJhdGlvbgAEB1BJc3N1ZWQJAGsDBRNQSXNzdWVkTm9NdWx0aXBsaWVyCAUHYXZnQ29uYwJfMggFB2F2Z0NvbmMCXzEEDmFzc2V0UGFyYW1zVXBkCQCaCggJAGQCBRBhc3NldFZpcnRCYWxhbmNlBQZhbW91bnQJAGQCBRBhc3NldEZhY3RCYWxhbmNlBQZhbW91bnQIBQthc3NldFBhcmFtcwJfMwgFC2Fzc2V0UGFyYW1zAl80CAULYXNzZXRQYXJhbXMCXzUIBQthc3NldFBhcmFtcwJfNggFC2Fzc2V0UGFyYW1zAl83CAULYXNzZXRQYXJhbXMCXzgJAJQKAgkAzAgCCQEVc2F2ZUdsb2JhbFRva2VuUGFyYW1zAgUPYXNzZXRBZGRlZElkU3RyBQ5hc3NldFBhcmFtc1VwZAUDbmlsBQdQSXNzdWVkARZjYWxjUmVkZWVtV2l0aE9uZVRva2VuAg1hc3NldE91dElkU3RyCVBSZWRlZW1lZAQHUFN1cHBseQkBGWdldFZpcnR1YWxQb29sVG9rZW5BbW91bnQABAthc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFDWFzc2V0T3V0SWRTdHIEEGFzc2V0RmFjdEJhbGFuY2UIBQthc3NldFBhcmFtcwJfMgQQYXNzZXRWaXJ0QmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl8xBAthc3NldFdlaWdodAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUNYXNzZXRPdXRJZFN0cgIHX3dlaWdodAQKYXNzZXRTY2FsZQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUNYXNzZXRPdXRJZFN0cgIGX3NjYWxlBA1hc3NldERlY2ltYWxzCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQ1hc3NldE91dElkU3RyAglfZGVjaW1hbHMEFWFtb3VudE91dE5vTXVsaXRwbGllcgkAawMFEGFzc2V0VmlydEJhbGFuY2UJAGUCBQZTY2FsZTgJAKADAQkAdgYJALYCAQkAZQIFCmFzc2V0U2NhbGUJAGsDBQlQUmVkZWVtZWQFCmFzc2V0U2NhbGUFB1BTdXBwbHkFDWFzc2V0RGVjaW1hbHMJALYCAQkAawMAkE4AkE4FC2Fzc2V0V2VpZ2h0AAQACAUERE9XTgUGU2NhbGU4BAdhdmdDb25jCQEUY2FsY0F2Z0NvbmNlbnRyYXRpb24ABAlhbW91bnRPdXQJAGsDBRVhbW91bnRPdXROb011bGl0cGxpZXIIBQdhdmdDb25jAl8xCAUHYXZnQ29uYwJfMgMJAGYCBQlhbW91bnRPdXQFEGFzc2V0RmFjdEJhbGFuY2UJAAIBAjRubyBhdmFpbGFibGUgZmFjdCBsaXF1aWRpdHkgdG8gd2l0aGRyYXcgaW4gb25lIHRva2VuBA5hc3NldFBhcmFtc1VwZAkAmgoICQBlAgUQYXNzZXRWaXJ0QmFsYW5jZQUJYW1vdW50T3V0CQBlAgUQYXNzZXRGYWN0QmFsYW5jZQUJYW1vdW50T3V0CAULYXNzZXRQYXJhbXMCXzMIBQthc3NldFBhcmFtcwJfNAgFC2Fzc2V0UGFyYW1zAl81CAULYXNzZXRQYXJhbXMCXzYIBQthc3NldFBhcmFtcwJfNwgFC2Fzc2V0UGFyYW1zAl84CQCUCgIJAMwIAgkBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIFDWFzc2V0T3V0SWRTdHIFDmFzc2V0UGFyYW1zVXBkBQNuaWwFCWFtb3VudE91dAEWaGFuZGxlUG9vbFRva2Vuc1JlZGVlbQIJUFJlZGVlbWVkC3VzZXJBZGRyZXNzCgERaGFuZGxlVG9rZW5SZWRlZW0CBWFjY3VtB3Rva2VuSWQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFB3Rva2VuSWQEC2Fzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKYXNzZXRJZFN0cgQCQmsIBQthc3NldFBhcmFtcwJfMgQHUFN1cHBseQkBGWdldFZpcnR1YWxQb29sVG9rZW5BbW91bnQABAZhbW91bnQJAKADAQkAvQIECQC2AgEFCVBSZWRlZW1lZAkAtgIBBQJCawkAtgIBBQdQU3VwcGx5BQRET1dOBAl1bnN0YWtlVHgJAQ91bnN0YWtlSWZOZWVkZWQCBQphc3NldElkU3RyBQZhbW91bnQDCQAAAgUJdW5zdGFrZVR4BQl1bnN0YWtlVHgEE3NlbGxvZmZTdGFydEJhbGFuY2UDCQECIT0CCAULYXNzZXRQYXJhbXMCXzgJAGgCCQBpAgUGaGVpZ2h0AGQAZAgFC2Fzc2V0UGFyYW1zAl83CQBrAwgFC2Fzc2V0UGFyYW1zAl83CQBlAgUHUFN1cHBseQUJUFJlZGVlbWVkBQdQU3VwcGx5BA5hc3NldFBhcmFtc1VwZAkAmgoICQBrAwgFC2Fzc2V0UGFyYW1zAl8xCQBlAgUHUFN1cHBseQUJUFJlZGVlbWVkBQdQU3VwcGx5CQBlAggFC2Fzc2V0UGFyYW1zAl8yBQZhbW91bnQIBQthc3NldFBhcmFtcwJfMwgFC2Fzc2V0UGFyYW1zAl80CAULYXNzZXRQYXJhbXMCXzUIBQthc3NldFBhcmFtcwJfNgUTc2VsbG9mZlN0YXJ0QmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl84CQDOCAIJAM4IAgUFYWNjdW0JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFBmFtb3VudAUHdG9rZW5JZAUDbmlsCQDMCAIJARVzYXZlR2xvYmFsVG9rZW5QYXJhbXMCBQphc3NldElkU3RyBQ5hc3NldFBhcmFtc1VwZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARFoYW5kbGVUb2tlblJlZGVlbQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgESY2FsY3VsYXRlT3V0QW1vdW50BQhBbW91bnRJbgdhc3NldEluCGFzc2V0T3V0CUJhbGFuY2VJbgpCYWxhbmNlT3V0BAdJbmRleEluCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzBQdhc3NldEluBAhJbmRleE91dAkBBXZhbHVlAQkAzwgCBQhhc3NldElkcwUIYXNzZXRPdXQDCQAAAgUHSW5kZXhJbgUISW5kZXhPdXQFCEFtb3VudEluCQBuBAUKQmFsYW5jZU91dAkAZQIJAGgCBQZTY2FsZTgFBlNjYWxlOAkAoAMBCQB2BgkAvQIECQC5AgIJALYCAQUJQmFsYW5jZUluCQC2AgEAkE4JALYCAQkAaAIFBlNjYWxlOAUGU2NhbGU4CQC5AgIJALYCAQkAZAIFCUJhbGFuY2VJbgUIQW1vdW50SW4JALYCAQCQTgUGSEFMRlVQABAJALYCAQkAawMJAJEDAgUNQXNzZXRzV2VpZ2h0cwUHSW5kZXhJbgCAoJSljR0JAJEDAgUNQXNzZXRzV2VpZ2h0cwUISW5kZXhPdXQADAAQBQdDRUlMSU5HCQBoAgUGU2NhbGU4BQZTY2FsZTgFBERPV04BFWNhbGNDbGFpbVJld2FyZEFtb3VudAQKYWRkcmVzc1N0cgtpbmRleEFtb3VudAphc3NldElkU3RyFGN1cnJlbnRUb2tlbkludGVyZXN0CQBrAwULaW5kZXhBbW91bnQJAGUCBRRjdXJyZW50VG9rZW5JbnRlcmVzdAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgkArAICBQphZGRyZXNzU3RyAgtfbGFzdENoZWNrXwUKYXNzZXRJZFN0cgIJX2ludGVyZXN0BQdTY2FsZTE2AQtjbGFpbVJlc3VsdAEHYWRkcmVzcwQKYWRkcmVzc1N0cgkApQgBBQdhZGRyZXNzBAtpbmRleEFtb3VudAkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAQLZmVlQXNzZXRTdHIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfZmVlVG9rZW4EDmZlZUFzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQULZmVlQXNzZXRTdHIED2ZlZVRva2VuQmFsYW5jZQgFDmZlZUFzc2V0UGFyYW1zAl8xCgEHaGFuZGxlcgIFYWNjdW0HYXNzZXRJZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAQLYXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQphc3NldElkU3RyBBRjdXJyZW50VG9rZW5JbnRlcmVzdAgFC2Fzc2V0UGFyYW1zAl80BAhhQmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl8xBAxyZXdhcmRBbW91bnQJARVjYWxjQ2xhaW1SZXdhcmRBbW91bnQEBQphZGRyZXNzU3RyBQtpbmRleEFtb3VudAUKYXNzZXRJZFN0cgUUY3VycmVudFRva2VuSW50ZXJlc3QECHRyYW5zZmVyAwkAAAIFDHJld2FyZEFtb3VudAAABQNuaWwECnVuc3Rha2VJbnYJAQ91bnN0YWtlSWZOZWVkZWQCBQphc3NldElkU3RyBQxyZXdhcmRBbW91bnQDCQAAAgUKdW5zdGFrZUludgUKdW5zdGFrZUludgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQdhZGRyZXNzBQxyZXdhcmRBbW91bnQFB2Fzc2V0SWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAlAoCCQDOCAIJAM4IAggFBWFjY3VtAl8xBQh0cmFuc2ZlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUKYWRkcmVzc1N0cgILX2xhc3RDaGVja18FCmFzc2V0SWRTdHICCV9pbnRlcmVzdAUUY3VycmVudFRva2VuSW50ZXJlc3QFA25pbAkAZAIIBQVhY2N1bQJfMgkBEWNhbGN1bGF0ZVVzZFZhbHVlBAUHYXNzZXRJZAUMcmV3YXJkQW1vdW50BQhhQmFsYW5jZQUPZmVlVG9rZW5CYWxhbmNlBAVhY2N1bQoAAiRsBQxlYXJuZWRBc3NldHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIFA25pbAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdoYW5kbGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQCUCgIJAM4IAggFBWFjY3VtAl8xCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFkZHJlc3NTdHICEV9jbGFpbWVkUmV3YXJkVVNECQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICEV9jbGFpbWVkUmV3YXJkVVNECAUFYWNjdW0CXzIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgIKX2xhc3RDbGFpbQgFCWxhc3RCbG9jawl0aW1lc3RhbXAFA25pbAgFBWFjY3VtAl8yAQpjbGFpbVF1b3RlAQdhZGRyZXNzBAphZGRyZXNzU3RyCQClCAEFB2FkZHJlc3MEC2luZGV4QW1vdW50CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYWRkcmVzc1N0cgIMX2luZGV4U3Rha2VkBAtmZWVBc3NldFN0cgkBDHRyeUdldFN0cmluZwECD3N0YXRpY19mZWVUb2tlbgQOZmVlQXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQtmZWVBc3NldFN0cgQPZmVlVG9rZW5CYWxhbmNlCAUOZmVlQXNzZXRQYXJhbXMCXzEKAQdoYW5kbGVyAgVhY2N1bQdhc3NldElkBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBBQdhc3NldElkBAthc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCmFzc2V0SWRTdHIEFGN1cnJlbnRUb2tlbkludGVyZXN0CAULYXNzZXRQYXJhbXMCXzQECGFCYWxhbmNlCAULYXNzZXRQYXJhbXMCXzEEDHJld2FyZEFtb3VudAkBFWNhbGNDbGFpbVJld2FyZEFtb3VudAQFCmFkZHJlc3NTdHIFC2luZGV4QW1vdW50BQphc3NldElkU3RyBRRjdXJyZW50VG9rZW5JbnRlcmVzdAkAZAIFBWFjY3VtCQERY2FsY3VsYXRlVXNkVmFsdWUEBQdhc3NldElkBQxyZXdhcmRBbW91bnQFCGFCYWxhbmNlBQ9mZWVUb2tlbkJhbGFuY2UKAAIkbAUMZWFybmVkQXNzZXRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdoYW5kbGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARNnZXRXYXZlc0NsYWltQW1vdW50AQdhZGRyZXNzAwkAAAIJAM8IAgUIYXNzZXRJZHMFBHVuaXQFBHVuaXQAAAQKYWRkcmVzc1N0cgkApQgBBQdhZGRyZXNzBAtpbmRleEFtb3VudAkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAQLd2F2ZXNQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBAgVXQVZFUwQUY3VycmVudFRva2VuSW50ZXJlc3QIBQt3YXZlc1BhcmFtcwJfNAQMcmV3YXJkQW1vdW50CQBrAwULaW5kZXhBbW91bnQJAGUCBRRjdXJyZW50VG9rZW5JbnRlcmVzdAkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICGV9sYXN0Q2hlY2tfV0FWRVNfaW50ZXJlc3QFB1NjYWxlMTYJAJYDAQkAzAgCAAAJAMwIAgUMcmV3YXJkQW1vdW50BQNuaWwBFGdldFdhdmVzUmVkZWVtQW1vdW50AQlQUmVkZWVtZWQDCQAAAgkAzwgCBQhhc3NldElkcwUEdW5pdAUEdW5pdAAABAt3YXZlc1BhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwECBVdBVkVTBAJCawgFC3dhdmVzUGFyYW1zAl8yBAdQU3VwcGx5CQEZZ2V0VmlydHVhbFBvb2xUb2tlbkFtb3VudAAJAKADAQkAvQIECQC2AgEFCVBSZWRlZW1lZAkAtgIBBQJCawkAtgIBBQdQU3VwcGx5BQdDRUlMSU5HARRnZXRXYXZlc0NoYW5nZUFtb3VudAMHUElzc3VlZAhwYXltZW50cwpuZWVkQ2hhbmdlAwMJAQEhAQUKbmVlZENoYW5nZQYJAAACCQDPCAIFCGFzc2V0SWRzBQR1bml0BQR1bml0AAAKARBmaW5kV2F2ZXNQYXltZW50AgVhY2N1bQNwbXQDCQAAAggFA3BtdAdhc3NldElkBQR1bml0CAUDcG10BmFtb3VudAUFYWNjdW0ECHdhdmVzUG10CgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARBmaW5kV2F2ZXNQYXltZW50AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkAAAIFCHdhdmVzUG10AAAAAAQLd2F2ZXNQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBAgVXQVZFUwQCQmsIBQt3YXZlc1BhcmFtcwJfMgQHUFN1cHBseQkBGWdldFZpcnR1YWxQb29sVG9rZW5BbW91bnQABAJEawkAoAMBCQC9AgQJALYCAQUHUElzc3VlZAkAtgIBBQJCawkAtgIBBQdQU3VwcGx5BQdDRUlMSU5HCQCWAwEJAMwIAgAACQDMCAIJAGUCBQh3YXZlc1BtdAUCRGsFA25pbAEQaW5kZXhTdGFrZVJlc3VsdAIKYWRkcmVzc1N0cgZhbW91bnQEAmxpCAkBC2NsYWltUmVzdWx0AQkBEUBleHRyTmF0aXZlKDEwNjIpAQUKYWRkcmVzc1N0cgJfMQkAzggCBQJsaQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQJAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYWRkcmVzc1N0cgIMX2luZGV4U3Rha2VkBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQICEmdsb2JhbF9pbmRleFN0YWtlZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQISZ2xvYmFsX2luZGV4U3Rha2VkBQZhbW91bnQFA25pbAEPaXNPd25lck9yTWFzdGVyAQZjYWxsZXIEDG93bmVyQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDHRyeUdldFN0cmluZwECEHN0YXRpY19wb29sT3duZXIDCQAAAgUGY2FsbGVyBQxvd25lckFkZHJlc3MGCQAAAgUGY2FsbGVyBQ1tYXN0ZXJBZGRyZXNzAQNzdW0CBWFjY3VtAW4JAGQCBQVhY2N1bQkBDXBhcnNlSW50VmFsdWUBBQFuAQ1jaGVja0ZlZUFzc2V0AgVhY2N1bQRuZXh0AwMJAQIhPQIJAM8IAgUVc3VwcG9ydGVkRmVlQXNzZXRzU3RyBQRuZXh0BQR1bml0CQAAAgUFYWNjdW0CAAcFBG5leHQFBWFjY3VtARJjYWxjSW50ZXJlc3RDaGFuZ2UCCmFzc2V0SWRTdHIFbHBGZWUECnRvdGFsSW5kZXgJAQ10cnlHZXRJbnRlZ2VyAQISZ2xvYmFsX2luZGV4U3Rha2VkAwkAAAIFCnRvdGFsSW5kZXgAAAAACQBrAwUFbHBGZWUFB1NjYWxlMTYFCnRvdGFsSW5kZXgBDnVwZFNlbGxvZmZEYXRhBAphc3NldElkU3RyCGFtb3VudEluB2JhbGFuY2UNc2VsbG9mZlBhcmFtcwQNY3VycmVudFBlcmlvZAkAaAIJAGkCBQZoZWlnaHQAZABkBApwcmV2UGVyaW9kCAUNc2VsbG9mZlBhcmFtcwJfMwQLcHJldlNlbGxvZmYDCQAAAgUNY3VycmVudFBlcmlvZAUKcHJldlBlcmlvZAgFDXNlbGxvZmZQYXJhbXMCXzEAAAQTc2VsbG9mZlN0YXJ0QmFsYW5jZQMJAAACBQ1jdXJyZW50UGVyaW9kBQpwcmV2UGVyaW9kCAUNc2VsbG9mZlBhcmFtcwJfMgUHYmFsYW5jZQQMc2VsbG9mZkRlbHRhAwkAAAIFE3NlbGxvZmZTdGFydEJhbGFuY2UAAAAACQBrAwUHU2NhbGUxNgUIYW1vdW50SW4FE3NlbGxvZmZTdGFydEJhbGFuY2UECm1heFNlbGxvZmYJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICC19tYXhTZWxsb2ZmAwMJAGYCCQBkAgULcHJldlNlbGxvZmYFDHNlbGxvZmZEZWx0YQUKbWF4U2VsbG9mZgkBAiE9AgUKbWF4U2VsbG9mZgAABwkAAgEJAKwCAgIjbWF4IHNlbGxvZmYgcmVhY2hlZCBmb3IgdGhpcyBhc3NldCAFCmFzc2V0SWRTdHIEBnN0YXJ0SAMJAAACBQ1jdXJyZW50UGVyaW9kBQpwcmV2UGVyaW9kBQpwcmV2UGVyaW9kBQ1jdXJyZW50UGVyaW9kBAZzdGFydEIDCQAAAgUNY3VycmVudFBlcmlvZAUKcHJldlBlcmlvZAgFDXNlbGxvZmZQYXJhbXMCXzIFE3NlbGxvZmZTdGFydEJhbGFuY2UJAJUKAwkAZAIFC3ByZXZTZWxsb2ZmBQxzZWxsb2ZmRGVsdGEFBnN0YXJ0QgUGc3RhcnRIARB2YWxpZGF0ZVBheW1lbnRzAgphc3NldHNMaXN0CHBheW1lbnRzCgEQZ2V0UGF5bWVudEFzc2V0cwIFYWNjdW0EbmV4dAMJAGcCAAAIBQRuZXh0BmFtb3VudAkAAgEJAKwCAgkArAICCQCsAgICG1RvbyBsb3cgcGF5bWVudCBhbW91bnQg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BSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAQdnZXRQMVAyAgphc3NldElkU3RyDmJhc2VBc3NldElkU3RyBAthc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCmFzc2V0SWRTdHIED2Jhc2VBc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFDmJhc2VBc3NldElkU3RyBAJCMQgFD2Jhc2VBc3NldFBhcmFtcwJfMQQCQjIIBQthc3NldFBhcmFtcwJfMQQCRjEIBQ9iYXNlQXNzZXRQYXJhbXMCXzIEAkYyCAULYXNzZXRQYXJhbXMCXzIEAlMxCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQ5iYXNlQXNzZXRJZFN0cgIGX3NjYWxlBAJTMgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUKYXNzZXRJZFN0cgIGX3NjYWxlBAJEMQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUOYmFzZUFzc2V0SWRTdHICCV9kZWNpbWFscwQCRDIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICCV9kZWNpbWFscwQCVzEJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FDmJhc2VBc3NldElkU3RyAgdfd2VpZ2h0BAJXMgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUKYXNzZXRJZFN0cgIHX3dlaWdodAQEVzFXMgkAawMFAlcxAJBOBQJXMgQEVzJXMQkAawMFAlcyAJBOBQJXMQQNcDFfdW53ZWlnaHRlZAkAawMJAGUCBQJCMQUCRjEFAlMxCQBrAwUCQjIJAGwGCQBrAwUCQjEFAlMxCQBlAgUCQjEFAkYxBQJEMQUEVzFXMgAEBQJEMQUHQ0VJTElORwUCUzIEAnAxCQBrAwUNcDFfdW53ZWlnaHRlZAUEVzJXMQCQTgMJAAACBQJCMgUCRjIJAJQKAgUCcDEFBHVuaXQEDXAyX3Vud2VpZ2h0ZWQJAGsDCQBrAwUCQjEJAGwGCQBrAwUCQjIFAlMyCQBlAgUCQjIFAkYyBQJEMgUEVzJXMQAEBQJEMgUFRkxPT1IFAlMyBQJTMgkAZQIFAkIyBQJGMgQCcDIJAGsDBQ1wMl91bndlaWdodGVkBQRXMlcxAJBOCQCUCgIFAnAxBQJwMhIBaQETYWRkVW5kZXJseWluZ1N0YWtlcgINc3Rha2VyQWRkcmVzcwphc3NldElkU3RyBAtfaXNTaHV0ZG93bgMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AHAwkAAAIFC19pc1NodXRkb3duBQtfaXNTaHV0ZG93bgMJAQIhPQIFBHRoaXMIBQFpBmNhbGxlcgkAAgECCmFkbWluIG9ubHkJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICAhdzdGF0aWNfc3Rha2luZ0NvbnRyYWN0XwUKYXNzZXRJZFN0cgUNc3Rha2VyQWRkcmVzcwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBB3ByZUluaXQHC2Fzc2V0SWRzU3RyD2Fzc2V0V2VpZ2h0c1N0chJhc3NldE1heFNlbGxvZmZTdHIOYmFzZVRva2VuSWRTdHIKcG9vbERvbWFpbglwb29sT3duZXIDZmVlBBBwb29sT3duZXJBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQlwb29sT3duZXIED19jaGVja1Bvb2xPd25lcgMJAAACCQCmCAEFCXBvb2xPd25lcgUEdW5pdAkAAgECGHdyb25nIHBvb2wgb3duZXIgYWRkcmVzcwYDCQAAAgUPX2NoZWNrUG9vbE93bmVyBQ9fY2hlY2tQb29sT3duZXIEDWFzc2V0SWRzU3RyTGkJALUJAgULYXNzZXRJZHNTdHICASwEFGFzc2V0TWF4U2VsbG9mZlN0ckxpCQC1CQIFEmFzc2V0TWF4U2VsbG9mZlN0cgIBLAQRYXNzZXRXZWlnaHRzU3RyTGkJALUJAgUPYXNzZXRXZWlnaHRzU3RyAgEsBAphc3NldElkc0xpCgACJGwFDWFzc2V0SWRzU3RyTGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBE2FkZEFzc2V0Qnl0ZXNUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEEWZlZUFzc2V0Q2hvc2VuU3RyCgACJGwFDWFzc2V0SWRzU3RyTGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwAgAKAQUkZjVfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDWNoZWNrRmVlQXNzZXQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjVfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY1XzICCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEC2ZlZUFzc2V0U3RyAwkAAAIFEWZlZUFzc2V0Q2hvc2VuU3RyAgAFDmJhc2VUb2tlbklkU3RyBRFmZWVBc3NldENob3NlblN0cgQLYmFzZVByZXNlbnQDCQAAAgkAzwgCBQ1hc3NldElkc1N0ckxpBQ5iYXNlVG9rZW5JZFN0cgUEdW5pdAkAAgECGmJhc2UgdG9rZW4gbWlzc2luZyBpbiBsaXN0BgMJAAACBQtiYXNlUHJlc2VudAULYmFzZVByZXNlbnQEC3NhbWVMZW5ndGhzAwMJAQIhPQIJAJADAQUNYXNzZXRJZHNTdHJMaQkAkAMBBRFhc3NldFdlaWdodHNTdHJMaQYJAQIhPQIJAJADAQUNYXNzZXRJZHNTdHJMaQkAkAMBBRRhc3NldE1heFNlbGxvZmZTdHJMaQkAAgECMWFzc2V0SWRzLCB3ZWlnaHRzLCBhbmQgbWF4U2VsbG9mZiBsZW5ndGggbWlzbWF0Y2gGAwkAAAIFC3NhbWVMZW5ndGhzBQtzYW1lTGVuZ3RocwMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3ADCQECIT0CBQR0aGlzCAUBaQZjYWxsZXIJAAIBAgphZG1pbiBvbmx5AwkAZgIJALECAQUKcG9vbERvbWFpbgANCQACAQIVdG9vIGxhcmdlIHBvb2wgZG9tYWluAwMJAGYCBQNmZWUA9AMGCQBmAgAABQNmZWUJAAIBAipmZWUgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDUwMCAoMC01JSkDCQECIT0CCQEPdmFsaWRhdGVXZWlnaHRzAQURYXNzZXRXZWlnaHRzU3RyTGkAkE4JAAIBCQCsAgICJndlaWdodHMgc3VtIHNob3VsZCBiZSAxMDAwMCwgY3VycmVudDogCQCkAwEJAQ92YWxpZGF0ZVdlaWdodHMBBRFhc3NldFdlaWdodHNTdHJMaQoBE2FkZFRva2VuRGF0YUVudHJpZXMCBWFjY3VtCGFzc2V0TnVtAwkAZwIFCGFzc2V0TnVtCQCQAwEFCmFzc2V0SWRzTGkFBWFjY3VtBBNhc3NldFN0YWtpbmdBZGRyZXNzCgABQAkA/AcEBQ9wb29sc0h1YkFkZHJlc3MCEHVzZUVtcHR5Q29udHJhY3QJAMwIAgkArAICAgdzdGFrZXJfCQCRAwIFDWFzc2V0SWRzU3RyTGkFCGFzc2V0TnVtBQNuaWwFA25pbAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBBQFAAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcDCQAAAgUTYXNzZXRTdGFraW5nQWRkcmVzcwUTYXNzZXRTdGFraW5nQWRkcmVzcwQNYXNzZXREZWNpbWFscwQHJG1hdGNoMAkAkQMCBQphc3NldElkc0xpBQhhc3NldE51bQMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAF4BQckbWF0Y2gwCAkBBXZhbHVlAQkA7AcBBQF4CGRlY2ltYWxzAAgJAM4IAgkAzggCBQVhY2N1bQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB3N0YXRpY18JAJEDAgUNYXNzZXRJZHNTdHJMaQUIYXNzZXROdW0CBl9zY2FsZQkAbAYACgAABQ1hc3NldERlY2ltYWxzAAAAAAUERE9XTgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB3N0YXRpY18JAJEDAgUNYXNzZXRJZHNTdHJMaQUIYXNzZXROdW0CCV9kZWNpbWFscwUNYXNzZXREZWNpbWFscwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB3N0YXRpY18JAJEDAgUNYXNzZXRJZHNTdHJMaQUIYXNzZXROdW0CB193ZWlnaHQJAQV2YWx1ZQEJALYJAQkAkQMCBRFhc3NldFdlaWdodHNTdHJMaQUIYXNzZXROdW0JAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICAhdzdGF0aWNfc3Rha2luZ0NvbnRyYWN0XwkAkQMCBQ1hc3NldElkc1N0ckxpBQhhc3NldE51bQUTYXNzZXRTdGFraW5nQWRkcmVzcwUDbmlsAwkAAAIJAJEDAgUUYXNzZXRNYXhTZWxsb2ZmU3RyTGkFCGFzc2V0TnVtAgAFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB3N0YXRpY18JAJEDAgUNYXNzZXRJZHNTdHJMaQUIYXNzZXROdW0CC19tYXhTZWxsb2ZmCQBoAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFFGFzc2V0TWF4U2VsbG9mZlN0ckxpBQhhc3NldE51bQUHU2NhbGUxMgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDOCAIKAAIkbAkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkFA25pbAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNl8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQETYWRkVG9rZW5EYXRhRW50cmllcwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNl8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjZfMgIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgkAzAgCCQELU3RyaW5nRW50cnkCAg9zdGF0aWNfdG9rZW5JZHMFC2Fzc2V0SWRzU3RyCQDMCAIJAQtTdHJpbmdFbnRyeQICD3N0YXRpY19mZWVUb2tlbgULZmVlQXNzZXRTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgITc3RhdGljX3Rva2VuV2VpZ2h0cwUPYXNzZXRXZWlnaHRzU3RyCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhNzdGF0aWNfdG9rZW5zQW1vdW50CQCQAwEFCmFzc2V0SWRzTGkJAMwIAgkBC1N0cmluZ0VudHJ5AgIRc3RhdGljX3Bvb2xEb21haW4FCnBvb2xEb21haW4JAMwIAgkBC1N0cmluZ0VudHJ5AgIWc3RhdGljX3Bvb2xUb2tlbl9pZFN0cgIACQDMCAIJAQtTdHJpbmdFbnRyeQICEnN0YXRpY19iYXNlVG9rZW5JZAUOYmFzZVRva2VuSWRTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgIQc3RhdGljX3Bvb2xPd25lcgUJcG9vbE93bmVyCQDMCAIJAQxJbnRlZ2VyRW50cnkCAgpzdGF0aWNfZmVlBQNmZWUJAMwIAgkBDEludGVnZXJFbnRyeQICDHN0YXRpY19LTXVsdAUHU2NhbGUxNgkAzAgCCQEMSW50ZWdlckVudHJ5AgISZ2xvYmFsX2luZGV4U3Rha2VkAAAJAMwIAgkBDEludGVnZXJFbnRyeQICF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50AAAJAMwIAgkBDEludGVnZXJFbnRyeQICE2dsb2JhbF93YXNQcmVJbml0ZWQAAQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDHNldFdhdmVzTm9kZQELbm9kZUFkZHJlc3MDCQEBIQEJAQ9pc093bmVyT3JNYXN0ZXIBCAUBaQZjYWxsZXIJAAIBAhBhZG1pbi9vd25lciBvbmx5BAxfbm9kZUFkZHJlc3MJAKYIAQULbm9kZUFkZHJlc3MEBm5vZGVPawQHJG1hdGNoMAUMX25vZGVBZGRyZXNzAwkAAQIFByRtYXRjaDACB0FkZHJlc3MEAXQFByRtYXRjaDAGBwQKY2FuU2V0Tm9kZQMDBQZub2RlT2sGCQAAAgULbm9kZUFkZHJlc3MCAAYJAAIBAhJXcm9uZyBub2RlIGFkZHJlc3MDCQAAAgUKY2FuU2V0Tm9kZQUKY2FuU2V0Tm9kZQQHc2VsZlNldAMJAAACBQxfbm9kZUFkZHJlc3MFBHRoaXMJAAIBAixOb2RlIGFkZHJlc3MgY2FuJ3QgYmUgY29udHJhY3QncyBvd24gYWRkcmVzcwYDCQAAAgUHc2VsZlNldAUHc2VsZlNldAQLbmV3Tm9kZUFkZHIDCQECIT0CBQtub2RlQWRkcmVzcwIABQxfbm9kZUFkZHJlc3MFBHVuaXQEDGxlYXNlQWN0aW9ucwkBFXJlYmFsYW5jZUxlYXNlQWN0aW9ucwIAAAULbmV3Tm9kZUFkZHIJAM4IAgUMbGVhc2VBY3Rpb25zCQDMCAIJAQtTdHJpbmdFbnRyeQICEnN0YXRpY19ub2RlQWRkcmVzcwULbm9kZUFkZHJlc3MFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQZkZUluaXQAAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECCmFkbWluIG9ubHkJAMwIAgkBDEludGVnZXJFbnRyeQICEGdsb2JhbF93YXNJbml0ZWQAAAUDbmlsAWkBBGluaXQHC2Fzc2V0SWRzU3RyD2Fzc2V0V2VpZ2h0c1N0chJhc3NldE1heFNlbGxvZmZTdHIOYmFzZVRva2VuSWRTdHIKcG9vbERvbWFpbgNmZWUMdkJhbGFuY2VzU3RyBApwcmVJbml0SW52CQD8BwQFBHRoaXMCB3ByZUluaXQJAMwIAgULYXNzZXRJZHNTdHIJAMwIAgUPYXNzZXRXZWlnaHRzU3RyCQDMCAIFEmFzc2V0TWF4U2VsbG9mZlN0cgkAzAgCBQ5iYXNlVG9rZW5JZFN0cgkAzAgCBQpwb29sRG9tYWluCQDMCAIJAKUIAQgFAWkGY2FsbGVyCQDMCAIFA2ZlZQUDbmlsBQNuaWwDCQAAAgUKcHJlSW5pdEludgUKcHJlSW5pdEludgQJdkJhbGFuY2VzCQERcGFyc3RTdHJUb0ludExpc3QBBQx2QmFsYW5jZXNTdHIKARBnZXRQYXltZW50QW1vdW50AQphc3NldElkU3RyCgEHaGFuZGxlcgIFYWNjdW0HcGF5bWVudAMJAAACCQEOZ2V0QXNzZXRTdHJpbmcBCAUHcGF5bWVudAdhc3NldElkBQphc3NldElkU3RyCAUHcGF5bWVudAZhbW91bnQFBWFjY3VtCgACJGwIBQFpCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdoYW5kbGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCgELcHJlcGFyZUxpc3QACgEHaGFuZGxlcgIFYWNjdW0HYXNzZXRJZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAQBbgkBBXZhbHVlAQkAzwgCBQhhc3NldElkcwUHYXNzZXRJZAQNcGF5bWVudEFtb3VudAkBEGdldFBheW1lbnRBbW91bnQBBQphc3NldElkU3RyBAthc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCmFzc2V0SWRTdHIEDmFzc2V0UGFyYW1zVXBk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XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECOWF0IGxlYXN0IHNvbWUgb2YgdGhlIGFzc2V0cyBzaG91bGQgYmUgcHJvdmlkZWQgYXMgcGF5bWVudAMJAGYCCQENdHJ5R2V0SW50ZWdlcgECEGdsb2JhbF93YXNJbml0ZWQAAAkAAgECE3Bvb2wgYWxyZWFkeSBpbml0ZWQEEWluaXRpYWxQb29sVG9rZW5zCQEZY2FsY3VsYXRlUG9vbFRva2Vuc0Ftb3VudAEFCGFzc2V0SWRzBAxub3RpZnlJbnZva2UJAPwHBAUPcG9vbHNIdWJBZGRyZXNzAgthZGRTZWxmUG9vbAUDbmlsBQNuaWwDCQAAAgUMbm90aWZ5SW52b2tlBQxub3RpZnlJbnZva2UDCQAAAgURaW5pdGlhbFBvb2xUb2tlbnMAAAkAAgECMnlvdSBuZWVkIGEgYmlnZ2VyIHRva2VucyBhbW91bnQgdG8gbGF1bmNoIHRoZSBwb29sCQDOCAIJAM4IAgkAzggCCQELcHJlcGFyZUxpc3QACQEMcHJlcGFyZUxpc3QyAAkAzAgCCQEMSW50ZWdlckVudHJ5AgIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQFEWluaXRpYWxQb29sVG9rZW5zCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhBnbG9iYWxfd2FzSW5pdGVkAAEJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkApQgBCAUBaQZjYWxsZXICDF9pbmRleFN0YWtlZAURaW5pdGlhbFBvb2xUb2tlbnMJAMwIAgkBDEludGVnZXJFbnRyeQICEmdsb2JhbF9pbmRleFN0YWtlZAURaW5pdGlhbFBvb2xUb2tlbnMFA25pbAkBFXJlYmFsYW5jZUxlYXNlQWN0aW9ucwIAAAkBDmdldE5vZGVBZGRyZXNzAAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ1nZW5lcmF0ZUluZGV4AQpuZWVkQ2hhbmdlBAtfaXNTaHV0ZG93bgMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AHAwkAAAIFC19pc1NodXRkb3duBQtfaXNTaHV0ZG93bgMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMFAVQJAAIBCQCsAgICO3lvdSBuZWVkIHRvIGF0dGFjaCBhbGwgcG9vbCB0b2tlbnMuIGFtb3VudCBvZiBwb29sIHRva2VuczogCQCkAwEFAVQDCQEBIQEJARNjaGVja1Rva2Vuc1ZhbGlkaXR5AQgFAWkIcGF5bWVudHMJAAIBAhV3cm9uZyBhc3NldHMgYXR0YWNoZWQEDVBJc3N1ZWROb011bHQJAQ1nZXRNaW5QSXNzdWVkAQgFAWkIcGF5bWVudHMEBnJlc3VsdAkBE2hhbmRsZVBvb2xUb2tlbnNBZGQEBQ1QSXNzdWVkTm9NdWx0CAUBaQhwYXltZW50cwgFAWkMb3JpZ2luQ2FsbGVyBQpuZWVkQ2hhbmdlBA9QSXNzdWVkV2l0aE11bHQJAG4EBQ1QSXNzdWVkTm9NdWx0BQdTY2FsZTE2CQEIZ2V0S011bHQABQRET1dOBA13YXZlc0NsYWltT3V0CQETZ2V0V2F2ZXNDbGFpbUFtb3VudAEIBQFpBmNhbGxlcgQMY2xhaW1BY3Rpb25zCAkBC2NsYWltUmVzdWx0AQgFAWkGY2FsbGVyAl8xBAh3YXZlc091dAkAZAIJARRnZXRXYXZlc0NoYW5nZUFtb3VudAMFDVBJc3N1ZWROb011bHQIBQFpCHBheW1lbnRzBQpuZWVkQ2hhbmdlBQ13YXZlc0NsYWltT3V0BAxsZWFzZUFjdGlvbnMJARVyZWJhbGFuY2VMZWFzZUFjdGlvbnMCBQh3YXZlc091dAkBDmdldE5vZGVBZGRyZXNzAAkAlAoCCQDOCAIJAM4IAgkAzggCCQDOCAIFDGxlYXNlQWN0aW9ucwUGcmVzdWx0BQxjbGFpbUFjdGlvbnMJARFtaW50SW5kZXhJZk5lZWRlZAEFD1BJc3N1ZWRXaXRoTXVsdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQClCAEIBQFpBmNhbGxlcgIMX2luZGV4U3Rha2VkCQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgxfaW5kZXhTdGFrZWQFD1BJc3N1ZWRXaXRoTXVsdAkAzAgCCQEMSW50ZWdlckVudHJ5AgISZ2xvYmFsX2luZGV4U3Rha2VkCQBkAgkBDXRyeUdldEludGVnZXIBAhJnbG9iYWxfaW5kZXhTdGFrZWQFD1BJc3N1ZWRXaXRoTXVsdAkAzAgCCQEMSW50ZWdlckVudHJ5AgIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQJAGQCCQENdHJ5R2V0SW50ZWdlcgECF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50BQ9QSXNzdWVkV2l0aE11bHQFA25pbAUPUElzc3VlZFdpdGhNdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBC3JlZGVlbUluZGV4AQ9wb29sVG9rZW5BbW91bnQEDl9pc1ZhbGlkQW1vdW50AwkAZwIAAAUPcG9vbFRva2VuQW1vdW50CQACAQIZYW1vdW50IHNob3VsZCBiZSBwb3NpdGl2ZQYDCQAAAgUOX2lzVmFsaWRBbW91bnQFDl9pc1ZhbGlkQW1vdW50AwkAZgIFD3Bvb2xUb2tlbkFtb3VudAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgxfaW5kZXhTdGFrZWQJAAIBAix1c2VyIGRvZXNuJ3QgaGF2ZSB0aGlzIGFtb3VudCBvZiBwb29sIHRva2VucwMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AEEVBSZWRlZW1lZFdpdGhNdWx0BQ9wb29sVG9rZW5BbW91bnQEE1BSZWRlZW1lZFdpdGhOb011bHQJAG4EBRFQUmVkZWVtZWRXaXRoTXVsdAkBCGdldEtNdWx0AAUHU2NhbGUxNgUERE9XTgQGcmVzdWx0CQEWaGFuZGxlUG9vbFRva2Vuc1JlZGVlbQIFE1BSZWRlZW1lZFdpdGhOb011bHQIBQFpBmNhbGxlcgQNd2F2ZXNDbGFpbU91dAkBE2dldFdhdmVzQ2xhaW1BbW91bnQBCAUBaQZjYWxsZXIEDGNsYWltQWN0aW9ucwgJAQtjbGFpbVJlc3VsdAEIBQFpBmNhbGxlcgJfMQQId2F2ZXNPdXQJAGQCCQEUZ2V0V2F2ZXNSZWRlZW1BbW91bnQBBRNQUmVkZWVtZWRXaXRoTm9NdWx0BQ13YXZlc0NsYWltT3V0BAxsZWFzZUFjdGlvbnMJARVyZWJhbGFuY2VMZWFzZUFjdGlvbnMCBQh3YXZlc091dAkBDmdldE5vZGVBZGRyZXNzAAkAzggCCQDOCAIJAM4IAgkAzggCBQxsZWFzZUFjdGlvbnMFBnJlc3VsdAUMY2xhaW1BY3Rpb25zCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgxfaW5kZXhTdGFrZWQJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkApQgBCAUBaQZjYWxsZXICDF9pbmRleFN0YWtlZAURUFJlZGVlbWVkV2l0aE11bHQJAMwIAgkBDEludGVnZXJFbnRyeQICEmdsb2JhbF9pbmRleFN0YWtlZAkAZQIJAQ10cnlHZXRJbnRlZ2VyAQISZ2xvYmFsX2luZGV4U3Rha2VkBRFQUmVkZWVtZWRXaXRoTXVsdAkAzAgCCQEMSW50ZWdlckVudHJ5AgIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQJAGUCCQENdHJ5R2V0SW50ZWdlcgECF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50BRFQUmVkZWVtZWRXaXRoTXVsdAUDbmlsCQERYnVybkluZGV4SWZOZWVkZWQBBQ9wb29sVG9rZW5BbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKc3Rha2VJbmRleAAEC19pc1NodXRkb3duAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAcDCQAAAgULX2lzU2h1dGRvd24FC19pc1NodXRkb3duBAxjaGVja1BheW1lbnQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhhPbmUgcGF5bWVudCBhbGxvd2VkIG9ubHkGAwkAAAIFDGNoZWNrUGF5bWVudAUMY2hlY2tQYXltZW50BAphZGRyZXNzU3RyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQJANkEAQkBDHRyeUdldFN0cmluZwECFnN0YXRpY19wb29sVG9rZW5faWRTdHIJAAIBAhR3cm9uZyBhc3NldCBhdHRhY2hlZAQNd2F2ZXNDbGFpbU91dAkBE2dldFdhdmVzQ2xhaW1BbW91bnQBCAUBaQxvcmlnaW5DYWxsZXIEDHN0YWtlQWN0aW9ucwkBEGluZGV4U3Rha2VSZXN1bHQCBQphZGRyZXNzU3RyCAUDcG10BmFtb3VudAkAzggCCQEVcmViYWxhbmNlTGVhc2VBY3Rpb25zAgUNd2F2ZXNDbGFpbU91dAkBDmdldE5vZGVBZGRyZXNzAAUMc3Rha2VBY3Rpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDXN0YWtlSW5kZXhGb3IBCmFkZHJlc3NTdHIEC19pc1NodXRkb3duAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAcDCQAAAgULX2lzU2h1dGRvd24FC19pc1NodXRkb3duBAxjaGVja1BheW1lbnQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhhPbmUgcGF5bWVudCBhbGxvd2VkIG9ubHkGAwkAAAIFDGNoZWNrUGF5bWVudAUMY2hlY2tQYXltZW50BAxjaGVja0FkZHJlc3MDCQAAAgkApggBBQphZGRyZXNzU3RyBQR1bml0CQACAQINd3JvbmcgYWRkcmVzcwYDCQAAAgUMY2hlY2tBZGRyZXNzBQxjaGVja0FkZHJlc3MEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkCQDZBAEJAQx0cnlHZXRTdHJpbmcBAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyCQACAQIUd3JvbmcgYXNzZXQgYXR0YWNoZWQEDXdhdmVzQ2xhaW1PdXQJARNnZXRXYXZlc0NsYWltQW1vdW50AQkBEUBleHRyTmF0aXZlKDEwNjIpAQUKYWRkcmVzc1N0cgQMc3Rha2VBY3Rpb25zCQEQaW5kZXhTdGFrZVJlc3VsdAIFCmFkZHJlc3NTdHIIBQNwbXQGYW1vdW50CQDOCAIJARVyZWJhbGFuY2VMZWFzZUFjdGlvbnMCBQ13YXZlc0NsYWltT3V0CQEOZ2V0Tm9kZUFkZHJlc3MABQxzdGFrZUFjdGlvbnMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEMdW5zdGFrZUluZGV4AQtpbmRleEFtb3VudAoBCmlzc3VlSW5kZXgABAVpc3N1ZQkAwwgHCQCsAgICA1BSIAkBDHRyeUdldFN0cmluZwECEXN0YXRpY19wb29sRG9tYWluAhJQdXp6bGUgUmFuZ2UgSW5kZXgJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQFEVBvb2xUb2tlbkRlY2ltYWxzBgUEdW5pdAAABA5wb29sVG9rZW5JZFN0cgkA2AQBCQC4CAEFBWlzc3VlCQCUCgIJAMwIAgUFaXNzdWUJAMwIAgkBC1N0cmluZ0VudHJ5AgIWc3RhdGljX3Bvb2xUb2tlbl9pZFN0cgUOcG9vbFRva2VuSWRTdHIFA25pbAUOcG9vbFRva2VuSWRTdHIEDl9pc1ZhbGlkQW1vdW50AwkAZwIAAAULaW5kZXhBbW91bnQJAAIBAhlhbW91bnQgc2hvdWxkIGJlIHBvc2l0aXZlBgMJAAACBQ5faXNWYWxpZEFtb3VudAUOX2lzVmFsaWRBbW91bnQEDSR0MDQyMzAwNDI0NjYDCQAAAgkBDHRyeUdldFN0cmluZwECFnN0YXRpY19wb29sVG9rZW5faWRTdHICAAkBCmlzc3VlSW5kZXgACQCUCgIFA25pbAkBDHRyeUdldFN0cmluZwECFnN0YXRpY19wb29sVG9rZW5faWRTdHIEFHBvb2xUb2tlbklzc3VlUmVzdWx0CAUNJHQwNDIzMDA0MjQ2NgJfMQQOcG9vbFRva2VuSWRTdHIIBQ0kdDA0MjMwMDQyNDY2Al8yBAtwb29sVG9rZW5JZAkA2QQBBQ5wb29sVG9rZW5JZFN0cgQKYWRkcmVzc1N0cgkApQgBCAUBaQZjYWxsZXIEDmluZGV4QXZhaWxhYmxlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYWRkcmVzc1N0cgIMX2luZGV4U3Rha2VkAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAMJAGYCBQtpbmRleEFtb3VudAUOaW5kZXhBdmFpbGFibGUJAAIBAiV5b3UgZG9uJ3QgaGF2ZSBpbmRleCB0b2tlbnMgYXZhaWxhYmxlBA13YXZlc0NsYWltT3V0CQETZ2V0V2F2ZXNDbGFpbUFtb3VudAEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCmFkZHJlc3NTdHIEDGNsYWltQWN0aW9ucwgJAQtjbGFpbVJlc3VsdAEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCmFkZHJlc3NTdHICXzEJAM4IAgkAzggCCQDOCAIFFHBvb2xUb2tlbklzc3VlUmVzdWx0CQEVcmViYWxhbmNlTGVhc2VBY3Rpb25zAgUNd2F2ZXNDbGFpbU91dAkBDmdldE5vZGVBZGRyZXNzAAUMY2xhaW1BY3Rpb25zCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAkAZQIFDmluZGV4QXZhaWxhYmxlBQtpbmRleEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgISZ2xvYmFsX2luZGV4U3Rha2VkCQBlAgkBDXRyeUdldEludGVnZXIBAhJnbG9iYWxfaW5kZXhTdGFrZWQFC2luZGV4QW1vdW50CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgULaW5kZXhBbW91bnQFC3Bvb2xUb2tlbklkBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQERY2xhaW1JbmRleFJld2FyZHMAAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAQNd2F2ZXNDbGFpbU91dAkBE2dldFdhdmVzQ2xhaW1BbW91bnQBCAUBaQZjYWxsZXIEAmNyCQELY2xhaW1SZXN1bHQBCAUBaQZjYWxsZXIJAJQKAgkAzggCCQEVcmViYWxhbmNlTGVhc2VBY3Rpb25zAgUNd2F2ZXNDbGFpbU91dAkBDmdldE5vZGVBZGRyZXNzAAgFAmNyAl8xCAUCY3ICXzIBaQENZXZhbHVhdGVDbGFpbQEEdXNlcgkAlAoCBQNuaWwJAQpjbGFpbVF1b3RlAQkBEUBleHRyTmF0aXZlKDEwNjIpAQUEdXNlcgFpARNhZGRJbnRlcmVzdEV4dGVybmFsAAQLX2lzU2h1dGRvd24DCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wBwMJAAACBQtfaXNTaHV0ZG93bgULX2lzU2h1dGRvd24EB2Fzc2V0SWQICQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAQGYW1vdW50CAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQHc3Rha2VUeAkBDXN0YWtlSWZOZWVkZWQCBQphc3NldElkU3RyBQZhbW91bnQDCQAAAgUHc3Rha2VUeAUHc3Rha2VUeAMJAAACCQDPCAIFCGFzc2V0SWRzBQdhc3NldElkBQR1bml0CQACAQIweW91IGNhbiBvbmx5IGFkZCBpbnRlcmVzdCBmb3IgYXNzZXRzIGluIHRoZSBwb29sBAZwYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQphc3NldElkU3RyBA1pbnRlcmVzdERlbHRhCQESY2FsY0ludGVyZXN0Q2hhbmdlAgUKYXNzZXRJZFN0cgUGYW1vdW50BAl1cGRQYXJhbXMJAJoKCAgFBnBhcmFtcwJfMQgFBnBhcmFtcwJfMggFBnBhcmFtcwJfMwkAZAIIBQZwYXJhbXMCXzQFDWludGVyZXN0RGVsdGEJAGQCCAUGcGFyYW1zAl81BQZhbW91bnQIBQZwYXJhbXMCXzYIBQZwYXJhbXMCXzcIBQZwYXJhbXMCXzgJAMwIAgkBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIFCmFzc2V0SWRTdHIFCXVwZFBhcmFtcwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBFG5vdGlmeVN0YWtpbmdQYXltZW50Agphc3NldElkU3RyBmFtb3VudAQLX2lzU2h1dGRvd24DCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wBwMJAAACBQtfaXNTaHV0ZG93bgULX2lzU2h1dGRvd24EC2NoZWNrQW1vdW50AwkAZwIAAAUGYW1vdW50CQACAQIZYW1vdW50IHNob3VsZCBiZSBwb3NpdGl2ZQYDCQAAAgULY2hlY2tBbW91bnQFC2NoZWNrQW1vdW50BAdhc3NldElkCQENZ2V0QXNzZXRCeXRlcwEFCmFzc2V0SWRTdHIDCQAAAgkAzwgCBQhhc3NldElkcwUHYXNzZXRJZAUEdW5pdAkAAgECMHlvdSBjYW4gb25seSBhZGQgaW50ZXJlc3QgZm9yIGFzc2V0cyBpbiB0aGUgcG9vbAMJAQIhPQIJAQx0cnlHZXRTdHJpbmcBCQCsAgICF3N0YXRpY19zdGFraW5nQ29udHJhY3RfBQphc3NldElkU3RyCQClCAEIBQFpBmNhbGxlcgkAAgECJmNhbiBvbmx5IGJlIGludm9rZWQgYnkgc3Rha2VyIGNvbnRyYWN0BAZwYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQphc3NldElkU3RyBA1pbnRlcmVzdERlbHRhCQESY2FsY0ludGVyZXN0Q2hhbmdlAgUKYXNzZXRJZFN0cgUGYW1vdW50BAl1cGRQYXJhbXMJAJoKCAgFBnBhcmFtcwJfMQgFBnBhcmFtcwJfMggFBnBhcmFtcwJfMwkAZAIIBQZwYXJhbXMCXzQFDWludGVyZXN0RGVsdGEJAGQCCAUGcGFyYW1zAl81BQZhbW91bnQIBQZwYXJhbXMCXzYIBQZwYXJhbXMCXzcIBQZwYXJhbXMCXzgJAMwIAgkBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIFCmFzc2V0SWRTdHIFCXVwZFBhcmFtcwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBHN3YXACCGFzc2V0T3V0B21pbmltdW0EA3BtdAMJAAACCQCQAwEIBQFpCHBheW1lbnRzAAEJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAkAAgECIXBsZWFzZSBhdHRhY2ggZXhhY3RseSBvbmUgcGF5bWVudAQIQW1vdW50SW4JAQV2YWx1ZQEICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAdBc3NldEluCAUDcG10B2Fzc2V0SWQECEFzc2V0T3V0CQENZ2V0QXNzZXRCeXRlcwEFCGFzc2V0T3V0BAdhc3NldEluCQEOZ2V0QXNzZXRTdHJpbmcBBQdBc3NldEluBAdzY2FsZUluCQBpAgUGU2NhbGU4CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQdhc3NldEluAgZfc2NhbGUECHNjYWxlT3V0CQBpAgUGU2NhbGU4CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQhhc3NldE91dAIGX3NjYWxlBA1hc3NldEluUGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQkBDmdldEFzc2V0U3RyaW5nAQUHQXNzZXRJbgQOYXNzZXRPdXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQhhc3NldE91dAQOQXNzZXRJbkJhbGFuY2UIBQ1hc3NldEluUGFyYW1zAl8xBBJBc3NldEluRmFjdEJhbGFuY2UIBQ1hc3NldEluUGFyYW1zAl8yBBFhc3NldEluRmVlc0Vhcm5lZAgFDWFzc2V0SW5QYXJhbXMCXzMEGGFzc2V0SW5MYXN0Q2hlY2tJbnRlcmVzdAgFDWFzc2V0SW5QYXJhbXMCXzQED0Fzc2V0T3V0QmFsYW5jZQgFDmFzc2V0T3V0UGFyYW1zAl8xBBNhc3NldE91dEZhY3RCYWxhbmNlCAUOYXNzZXRPdXRQYXJhbXMCXzIEFEFzc2V0SW5CYWxhbmNlU2NhbGVkCQBoAgUOQXNzZXRJbkJhbGFuY2UFB3NjYWxlSW4EFUFzc2V0T3V0QmFsYW5jZVNjYWxlZAkAaAIFD0Fzc2V0T3V0QmFsYW5jZQUIc2NhbGVPdXQEC2ZlZUFtb3VudEluCQBuBAUIQW1vdW50SW4FA0ZlZQUIRmVlU2NhbGUFB0NFSUxJTkcEDWNsZWFuQW1vdW50SW4JAGUCBQhBbW91bnRJbgULZmVlQW1vdW50SW4EE2NsZWFuQW1vdW50SW5TY2FsZWQJAGgCBQ1jbGVhbkFtb3VudEluBQdzY2FsZUluBApBbW91bnRPdXQxCQESY2FsY3VsYXRlT3V0QW1vdW50BQUTY2xlYW5BbW91bnRJblNjYWxlZAUHQXNzZXRJbgUIQXNzZXRPdXQFFEFzc2V0SW5CYWxhbmNlU2NhbGVkBRVBc3NldE91dEJhbGFuY2VTY2FsZWQECUFtb3VudE91dAkAawMFCkFtb3VudE91dDEAAQUIc2NhbGVPdXQEEEFzc2V0T3V0QmFsYW5jZTIJAGUCBQ9Bc3NldE91dEJhbGFuY2UFCUFtb3VudE91dAQPQXNzZXRJbkJhbGFuY2UyCQBkAgUOQXNzZXRJbkJhbGFuY2UFDWNsZWFuQW1vdW50SW4DCQBnAgAABQlBbW91bnRPdXQJAAIBAh1hbW91bnQgb3V0IHNob3VsZCBiZSBwb3NpdGl2ZQMJAGYCBQdtaW5pbXVtBQlBbW91bnRPdXQJAAIBAilhbW91bnQgdG8gcmVjaWV2ZSBpcyBsb3dlciB0aGFuIGdpdmVuIG9uZQMJAAACBQhBc3NldE91dAUHQXNzZXRJbgkAAgECGHRoaXMgc3dhcCBpcyBub3QgYWxsb3dlZAMJAGYCAAAJAGUCBRNhc3NldE91dEZhY3RCYWxhbmNlBQlBbW91bnRPdXQJAAIBAhtjb250cmFjdCBpcyBvdXQgb2YgcmVzZXJ2ZXMDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wAwkBC3ZhbHVlT3JFbHNlAgkAmwgCBQ9wb29sc0h1YkFkZHJlc3MJAKwCAgISZ2xvYmFsX3NodXRkb3duSW5fBQdhc3NldEluBwkAAgECG3Rva2VuIElOIHRyYWRlcyBhcmUgc3RvcHBlZAMJAQt2YWx1ZU9yRWxzZQIJAJsIAgUPcG9vbHNIdWJBZGRyZXNzCQCsAgICE2dsb2JhbF9zaHV0ZG93bk91dF8FCGFzc2V0T3V0BwkAAgECHHRva2VuIE9VVCB0cmFkZXMgYXJlIHN0b3BwZWQEC3Byb3RvY29sRmVlCQBrAwULZmVlQW1vdW50SW4ABQAKBAVscEZlZQkAZQIFC2ZlZUFtb3VudEluBQtwcm90b2NvbEZlZQQNaW50ZXJlc3REZWx0YQkBEmNhbGNJbnRlcmVzdENoYW5nZQIFB2Fzc2V0SW4FBWxwRmVlBAdzdGFrZVR4CQENc3Rha2VJZk5lZWRlZAIFB2Fzc2V0SW4JAGQCBQ1jbGVhbkFtb3VudEluBQVscEZlZQMJAAACBQdzdGFrZVR4BQdzdGFrZVR4BAl1bnN0YWtlVHgJAQ91bnN0YWtlSWZOZWVkZWQCBQhhc3NldE91dAUJQW1vdW50T3V0AwkAAAIFCXVuc3Rha2VUeAUJdW5zdGFrZVR4BAxuZXdCYWxhbmNlSW4FD0Fzc2V0SW5CYWxhbmNlMgQNbmV3QmFsYW5jZU91dAUQQXNzZXRPdXRCYWxhbmNlMgQSYXNzZXRJblNlbGxvZmZEYXRhCQEOdXBkU2VsbG9mZkRhdGEEBQdhc3NldEluBQ1jbGVhbkFtb3VudEluBQ5Bc3NldEluQmFsYW5jZQkAlQoDCAUNYXNzZXRJblBhcmFtcwJfNggFDWFzc2V0SW5QYXJhbXMCXzcIBQ1hc3NldEluUGFyYW1zAl84BBNhc3NldE91dFNlbGxvZmZEYXRhCQEOdXBkU2VsbG9mZkRhdGEEBQhhc3NldE91dAkBAS0BBQlBbW91bnRPdXQFD0Fzc2V0T3V0QmFsYW5jZQkAlQoDCAUOYXNzZXRPdXRQYXJhbXMCXzYIBQ5hc3NldE91dFBhcmFtcwJfNwgFDmFzc2V0T3V0UGFyYW1zAl84BBJhc3NldEluRmluYWxQYXJhbXMJAJoKCAUMbmV3QmFsYW5jZUluCQBkAgUSQXNzZXRJbkZhY3RCYWxhbmNlBQ1jbGVhbkFtb3VudEluCQBkAgURYXNzZXRJbkZlZXNFYXJuZWQFBWxwRmVlCQBkAgUYYXNzZXRJbkxhc3RDaGVja0ludGVyZXN0BQ1pbnRlcmVzdERlbHRhCAUNYXNzZXRJblBhcmFtcwJfNQgFEmFzc2V0SW5TZWxsb2ZmRGF0YQJfMQgFEmFzc2V0SW5TZWxsb2ZmRGF0YQJfMggFEmFzc2V0SW5TZWxsb2ZmRGF0YQJfMwQTYXNzZXRPdXRGaW5hbFBhcmFtcwkAmgoIBQ1uZXdCYWxhbmNlT3V0CQBlAgUTYXNzZXRPdXRGYWN0QmFsYW5jZQUJQW1vdW50T3V0CAUOYXNzZXRPdXRQYXJhbXMCXzMIBQ5hc3NldE91dFBhcmFtcwJfNAgFDmFzc2V0T3V0UGFyYW1zAl81CAUTYXNzZXRPdXRTZWxsb2ZmRGF0YQJfMQgFE2Fzc2V0T3V0U2VsbG9mZkRhdGECXzIIBRNhc3NldE91dFNlbGxvZmZEYXRhAl8zBA1hc3NldEluQ2hhbmdlCQEVc2F2ZUdsb2JhbFRva2VuUGFyYW1zAgUHYXNzZXRJbgUSYXNzZXRJbkZpbmFsUGFyYW1zBA5hc3NldE91dENoYW5nZQkBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIFCGFzc2V0T3V0BRNhc3NldE91dEZpbmFsUGFyYW1zBAtmZWVBc3NldFN0cgkBDHRyeUdldFN0cmluZwECD3N0YXRpY19mZWVUb2tlbgQOZmVlQXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQtmZWVBc3NldFN0cgQPZmVlVG9rZW5CYWxhbmNlCAUOZmVlQXNzZXRQYXJhbXMCXzEED3ZvbHVtZVVzZFVwZGF0ZQkBEWNhbGN1bGF0ZVVzZFZhbHVlBAUHQXNzZXRJbgUIQW1vdW50SW4FDkFzc2V0SW5CYWxhbmNlBQ9mZWVUb2tlbkJhbGFuY2UECHdhdmVzT3V0CQBkAgMJAAACBQhBc3NldE91dAUEdW5pdAUJQW1vdW50T3V0AAADCQAAAgUHQXNzZXRJbgUEdW5pdAULcHJvdG9jb2xGZWUAAAQUc2hvdWxkUmViYWxhbmNlTGVhc2UDCQAAAgUHQXNzZXRJbgUEdW5pdAYJAAACBQhBc3NldE91dAUEdW5pdAQMbGVhc2VBY3Rpb25zAwUUc2hvdWxkUmViYWxhbmNlTGVhc2UJARVyZWJhbGFuY2VMZWFzZUFjdGlvbnMCBQh3YXZlc091dAkBDmdldE5vZGVBZGRyZXNzAAUDbmlsCQCUCgIJAM4IAgUMbGVhc2VBY3Rpb25zCQDMCAIFDWFzc2V0SW5DaGFuZ2UJAMwIAgUOYXNzZXRPdXRDaGFuZ2UJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQlBbW91bnRPdXQFCEFzc2V0T3V0CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhFnbG9iYWxfdm9sdW1lX3VzZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQIRZ2xvYmFsX3ZvbHVtZV91c2QFD3ZvbHVtZVVzZFVwZGF0ZQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQtmZWVzQWRkcmVzcwULcHJvdG9jb2xGZWUJAQ1nZXRBc3NldEJ5dGVzAQUHYXNzZXRJbgUDbmlsBQlBbW91bnRPdXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEMc3dhcFJlYWRPbmx5Awdhc3NldEluCGFzc2V0T3V0CEFtb3VudEluBAdBc3NldEluCQENZ2V0QXNzZXRCeXRlcwEFB2Fzc2V0SW4ECEFzc2V0T3V0CQENZ2V0QXNzZXRCeXRlcwEFCGFzc2V0T3V0BAdzY2FsZUluCQBpAgUGU2NhbGU4CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQdhc3NldEluAgZfc2NhbGUECHNjYWxlT3V0CQBpAgUGU2NhbGU4CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQhhc3NldE91dAIGX3NjYWxlBA5mZWVBc3NldE91dFN0cgkBDHRyeUdldFN0cmluZwECD3N0YXRpY19mZWVUb2tlbgQLZmVlQXNzZXRPdXQDCQAAAgUOZmVlQXNzZXRPdXRTdHICAAULdXNkbkFzc2V0SWQJAQ1nZXRBc3NldEJ5dGVzAQUOZmVlQXNzZXRPdXRTdHIEDWFzc2V0SW5QYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBCQEOZ2V0QXNzZXRTdHJpbmcBBQdBc3NldEluBA5hc3NldE91dFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCGFzc2V0T3V0BA5Bc3NldEluQmFsYW5jZQgFDWFzc2V0SW5QYXJhbXMCXzEEEkFzc2V0SW5GYWN0QmFsYW5jZQgFDWFzc2V0SW5QYXJhbXMCXzIEEWFzc2V0SW5GZWVzRWFybmVkCAUNYXNzZXRJblBhcmFtcwJfMwQYYXNzZXRJbkxhc3RDaGVja0ludGVyZXN0CAUNYXNzZXRJblBhcmFtcwJfNAQPQXNzZXRPdXRCYWxhbmNlCAUOYXNzZXRPdXRQYXJhbXMCXzEEE2Fzc2V0T3V0RmFjdEJhbGFuY2UIBQ5hc3NldE91dFBhcmFtcwJfMgQUQXNzZXRJbkJhbGFuY2VTY2FsZWQJAGgCBQ5Bc3NldEluQmFsYW5jZQUHc2NhbGVJbgQVQXNzZXRPdXRCYWxhbmNlU2NhbGVkCQBoAgUPQXNzZXRPdXRCYWxhbmNlBQhzY2FsZU91dAQLZmVlQW1vdW50SW4JAG4EBQhBbW91bnRJbgUDRmVlBQhGZWVTY2FsZQUHQ0VJTElORwQNY2xlYW5BbW91bnRJbgkAZQIFCEFtb3VudEluBQtmZWVBbW91bnRJbgQTY2xlYW5BbW91bnRJblNjYWxlZAkAaAIFDWNsZWFuQW1vdW50SW4FB3NjYWxlSW4ECkFtb3VudE91dDEJARJjYWxjdWxhdGVPdXRBbW91bnQFBRNjbGVhbkFtb3VudEluU2NhbGVkBQdBc3NldEluBQhBc3NldE91dAUUQXNzZXRJbkJhbGFuY2VTY2FsZWQFFUFzc2V0T3V0QmFsYW5jZVNjYWxlZAQJQW1vdW50T3V0CQBrAwUKQW1vdW50T3V0MQABBQhzY2FsZU91dAQQQXNzZXRPdXRCYWxhbmNlMgkAZQIFD0Fzc2V0T3V0QmFsYW5jZQUJQW1vdW50T3V0BA9Bc3NldEluQmFsYW5jZTIJAGQCBQ5Bc3NldEluQmFsYW5jZQUNY2xlYW5BbW91bnRJbgMJAGcCAAAFCUFtb3VudE91dAkAAgECHWFtb3VudCBvdXQgc2hvdWxkIGJlIHBvc2l0aXZlAwkAAAIFCEFzc2V0T3V0BQdBc3NldEluCQACAQIYdGhpcyBzd2FwIGlzIG5vdCBhbGxvd2VkAwkAZgIAAAkAZQIIBQ5hc3NldE91dFBhcmFtcwJfMgUJQW1vdW50T3V0CQACAQIbY29udHJhY3QgaXMgb3V0IG9mIHJlc2VydmVzAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAMJAQt2YWx1ZU9yRWxzZQIJAJsIAgUPcG9vbHNIdWJBZGRyZXNzCQCsAgICEmdsb2JhbF9zaHV0ZG93bkluXwUHYXNzZXRJbgcJAAIBAht0b2tlbiBJTiB0cmFkZXMgYXJlIHN0b3BwZWQDCQELdmFsdWVPckVsc2UCCQCbCAIFD3Bvb2xzSHViQWRkcmVzcwkArAICAhNnbG9iYWxfc2h1dGRvd25PdXRfBQhhc3NldE91dAcJAAIBAhx0b2tlbiBPVVQgdHJhZGVzIGFyZSBzdG9wcGVkCQCUCgIFA25pbAUJQW1vdW50T3V0AWkBEXRyYW5zZmVyT3duZXJzaGlwAQ9uZXdPd25lckFkZHJlc3MEC19pc1NodXRkb3duAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAcDCQAAAgULX2lzU2h1dGRvd24FC19pc1NodXRkb3duAwkBAiE9AgkApQgBCAUBaQZjYWxsZXIJAQx0cnlHZXRTdHJpbmcBAhBzdGF0aWNfcG9vbE93bmVyCQACAQIndGhpcyBjYWxsIGF2YWlsYWJsZSBvbmx5IGZvciBwb29sIG93bmVyAwkAAAIJAKYIAQUPbmV3T3duZXJBZGRyZXNzBQR1bml0CQACAQIPaW52YWxpZCBhZGRyZXNzCQDMCAIJAQtTdHJpbmdFbnRyeQICEHN0YXRpY19wb29sT3duZXIFD25ld093bmVyQWRkcmVzcwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBnNldEZlZQEGbmV3RmVlBAtfaXNWYWxpZEZlZQMDCQBmAgAABQZuZXdGZWUGCQBmAgUGbmV3RmVlAOgHCQACAQIqZmVlIGNhbid0IGJlIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiAxMDAwBgMJAAACBQtfaXNWYWxpZEZlZQULX2lzVmFsaWRGZWUDCQECIT0CCQClCAEIBQFpBmNhbGxlcgkBDHRyeUdldFN0cmluZwECEHN0YXRpY19wb29sT3duZXIJAAIBAid0aGlzIGNhbGwgYXZhaWxhYmxlIG9ubHkgZm9yIHBvb2wgb3duZXIJAMwIAgkBDEludGVnZXJFbnRyeQICCnN0YXRpY19mZWUFBm5ld0ZlZQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJ0eAEGdmVyaWZ5AAMDCQAAAgkBC3ZhbHVlT3JFbHNlAgkAnwgBAhNnbG9iYWxfd2FzUHJlSW5pdGVkAAAAAAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXkGCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQxtYXN0ZXJQdWJLZXkHBgQMX211bHRpc2lnU3RyAiMzUEpkVkVySDVWbVZZdmt1TjNBeXJydGQxekNaNFhydTZnVAQLbXVsdGlzaWdTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwIQQVBQUk9WRVJfQUREUkVTUwUMX211bHRpc2lnU3RyBA9tdWx0aXNpZ0FkZHJlc3MJAKYIAQULbXVsdGlzaWdTdHIECm11bHRpc2lnT2sEByRtYXRjaDAFD211bHRpc2lnQWRkcmVzcwMJAAECBQckbWF0Y2gwAgdBZGRyZXNzBAF0BQckbWF0Y2gwBgcECGlzSW5pdGVkAwUKbXVsdGlzaWdPawkBC3ZhbHVlT3JFbHNlAgkAmwgCCQEFdmFsdWUBBQ9tdWx0aXNpZ0FkZHJlc3MCBklOSVRFRAcHBAloYXNBZG1pbnMDBQptdWx0aXNpZ09rCQECIT0CCQELdmFsdWVPckVsc2UCCQCdCAIJAQV2YWx1ZQEFD211bHRpc2lnQWRkcmVzcwILQURNSU5TX1BCS1MCAAIABwMDAwUKbXVsdGlzaWdPawUIaXNJbml0ZWQHBQloYXNBZG1pbnMHBAckbWF0Y2gwBQJ0eAMJAAECBQckbWF0Y2gwAhRTZXRTY3JpcHRUcmFuc2FjdGlvbgQDdHR4BQckbWF0Y2gwBAckbWF0Y2gxCAUDdHR4BnNjcmlwdAMJAAECBQckbWF0Y2gxAgpCeXRlVmVjdG9yBAZzY3JpcHQFByRtYXRjaDEEC3NjcmlwdEhhc2hhCQDYBAEJAPYDAQUGc2NyaXB0BAl2YWxpZEZyb20JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCCQEFdmFsdWUBBQ9tdWx0aXNpZ0FkZHJlc3MJAKwCAgkArAICCQCsAgIJAKwCAgIIc2NyaXB0JSUFDUNPTlRSQUNUX1RZUEUCAiUlBQtzY3JpcHRIYXNoYQILJSV2YWxpZEZyb20CEXZhbGlkRnJvbSBub3Qgc2V0BAd2YWxpZFRvCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgkBBXZhbHVlAQUPbXVsdGlzaWdBZGRyZXNzCQCsAgIJAKwCAgkArAICCQCsAgICCHNjcmlwdCUlBQ1DT05UUkFDVF9UWVBFAgIlJQULc2NyaXB0SGFzaGECCSUldmFsaWRUbwIPdmFsaWRUbyBub3Qgc2V0AwkAZwIFBmhlaWdodAUJdmFsaWRGcm9tCQBnAgUHdmFsaWRUbwUGaGVpZ2h0BwcEA290eAUHJG1hdGNoMAQGdGFza0lkCQCsAgIJAKwCAgkArAICAgN0eF8JAKUIAQUEdGhpcwIBXwkA2AQBCAUDb3R4AmlkBAppc0FwcHJvdmVkCQELdmFsdWVPckVsc2UCCQCbCAIJAQV2YWx1ZQEFD211bHRpc2lnQWRkcmVzcwkArAICCQCsAgIJAKwCAgkApQgBBQR0aGlzAgFfCQDYBAEIBQNvdHgCaWQCCl9fYXBwcm92ZWQHBAxhcHByb3ZlZEZyb20JAQt2YWx1ZU9yRWxzZQIJAJoIAgkBBXZhbHVlAQUPbXVsdGlzaWdBZGRyZXNzCQCsAgIFBnRhc2tJZAIOX19hcHByb3ZlZEZyb20AAAMFCmlzQXBwcm92ZWQJAGcCBQZoZWlnaHQFDGFwcHJvdmVkRnJvbQcEByRtYXRjaDAFAnR4AwkAAQIFByRtYXRjaDACFFNldFNjcmlwdFRyYW5zYWN0aW9uBAN0dHgFByRtYXRjaDADCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAACAUCdHgPc2VuZGVyUHVibGljS2V5BgkA9AMDCAUDdHR4CWJvZHlCeXRlcwkAkQMCCAUDdHR4BnByb29mcwAABQxtYXN0ZXJQdWJLZXkHZ9cHNw==", "height": 765023, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 6 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let VERSION = "PZ-3.9.0 PROD"
5+
6+let CONTRACT_TYPE = "RANGED_POOL"
7+
8+let WAVES_RESERVE = 10000000
9+
10+let configStr = valueOrElse(getString(this, "configAddress"), "3PPEBRg4s2af2rQ2ZbLvdu1Hfd4Vo6QVDTo")
11+
12+let CONFIG_ADDRESS = if ((configStr == ""))
13+ then this
14+ else Address(fromBase58String(configStr))
15+
16+let AssetsWeightsDecimals = 4
17+
18+let Scale = 10000
19+
20+let Scale8 = 100000000
21+
22+let Scale8_BI = toBigInt(Scale8)
23+
24+let Scale12 = 1000000000000
25+
26+let Scale16 = 10000000000000000
27+
28+let Scale16_BI = toBigInt(Scale16)
29+
30+let FeeScale = 10000
31+
32+let PoolTokenDecimals = 8
33+
34+let PoolTokenScale = pow(10, 0, PoolTokenDecimals, 0, 0, HALFUP)
35+
36+let MIN_STEPS_AMOUNT = valueOrElse(getInteger(CONFIG_ADDRESS, "min_steps_amount"), 1)
37+
38+let MAX_STEPS_AMOUNT = valueOrElse(getInteger(CONFIG_ADDRESS, "max_steps_amount"), 500)
39+
40+let MIN_STEPS_INTERVAL = valueOrElse(getInteger(CONFIG_ADDRESS, "min_steps_interval"), 1)
41+
42+let MAX_STEPS_INTERVAL = valueOrElse(getInteger(CONFIG_ADDRESS, "max_steps_interval"), 10000)
43+
44+let MIN_WEIGHT = valueOrElse(getInteger(CONFIG_ADDRESS, "min_weight"), 100)
45+
46+let MAX_WEIGHT = valueOrElse(getInteger(CONFIG_ADDRESS, "max_weight"), 9900)
47+
48+func tryGetInteger (key) = match getInteger(this, key) {
49+ case b: Int =>
50+ b
51+ case _ =>
52+ 0
53+}
54+
55+
56+func tryGetBinary (key) = match getBinary(this, key) {
57+ case b: ByteVector =>
58+ b
59+ case _ =>
60+ base58''
61+}
62+
63+
64+func tryGetString (key) = match getString(this, key) {
65+ case b: String =>
66+ b
67+ case _ =>
68+ ""
69+}
70+
71+
72+func tryGetStringOrThrow (key) = match getString(this, key) {
73+ case b: String =>
74+ b
75+ case _ =>
76+ throw(("no such key in data storage: " + key))
77+}
78+
79+
80+func getAssetString (assetId) = match assetId {
81+ case b: ByteVector =>
82+ toBase58String(b)
83+ case _ =>
84+ "WAVES"
85+}
86+
87+
88+func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
89+ then unit
90+ else fromBase58String(assetIdStr)
91+
92+
93+func getTokenBalance (assetId) = match assetId {
94+ case t: ByteVector =>
95+ assetBalance(this, t)
96+ case _ =>
97+ wavesBalance(this).regular
98+}
99+
100+
101+func getNodeAddress () = {
102+ let nodeAddressStr = tryGetString("static_nodeAddress")
103+ if ((nodeAddressStr == ""))
104+ then unit
105+ else addressFromString(nodeAddressStr)
106+ }
107+
108+
109+func rebalanceLeaseActions (wavesOut,nodeAddr) = {
110+ let _isPositive = if ((0 > wavesOut))
111+ then throw("negative amount of WAVES to lease")
112+ else true
113+ if ((_isPositive == _isPositive))
114+ then {
115+ let currentLeaseId = tryGetString("global_lastLeaseId")
116+ let cancelLeaseAction = if ((currentLeaseId != ""))
117+ then [LeaseCancel(fromBase58String(currentLeaseId))]
118+ else nil
119+ match nodeAddr {
120+ case node: Address =>
121+ let newLeaseAmount = ((wavesBalance(this).regular - wavesOut) - WAVES_RESERVE)
122+ if ((newLeaseAmount > 0))
123+ then {
124+ let leaseAction = Lease(node, newLeaseAmount)
125+ let newLeaseId = toBase58String(calculateLeaseId(leaseAction))
126+ if ((newLeaseId == currentLeaseId))
127+ then nil
128+ else (cancelLeaseAction ++ [leaseAction, StringEntry("global_lastLeaseId", newLeaseId), IntegerEntry("global_lastLeaseAmount", newLeaseAmount)])
129+ }
130+ else (cancelLeaseAction ++ (if ((currentLeaseId != ""))
131+ then [DeleteEntry("global_lastLeaseId"), DeleteEntry("global_lastLeaseAmount")]
132+ else nil))
133+ case _ =>
134+ (cancelLeaseAction ++ (if ((currentLeaseId != ""))
135+ then [DeleteEntry("global_lastLeaseId"), DeleteEntry("global_lastLeaseAmount")]
136+ else nil))
137+ }
138+ }
139+ else throw("Strict value is not equal to itself.")
140+ }
141+
142+
143+func addAssetBytesToList (accum,item) = (accum ++ [getAssetBytes(item)])
144+
145+
146+func addAssetWeightToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_weight"))])
147+
148+
149+func addAssetWeightToStrList (accum,item) = (accum ++ [toString(tryGetInteger((("static_" + item) + "_weight")))])
150+
151+
152+func addAssetDecimalsToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_decimals"))])
153+
154+
155+func addAssetScaleToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_scale"))])
156+
157+
158+func addIntToList (accum,item) = (accum ++ [parseIntValue(item)])
159+
160+
161+func parstStrToIntList (s) = {
162+ func f (accum,next) = (accum ++ [parseIntValue(next)])
163+
164+ let $l = split(s, ",")
165+ let $s = size($l)
166+ let $acc0 = nil
167+ func $f0_1 ($a,$i) = if (($i >= $s))
168+ then $a
169+ else f($a, $l[$i])
170+
171+ func $f0_2 ($a,$i) = if (($i >= $s))
172+ then $a
173+ else throw("List size exceeds 10")
174+
175+ $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)
176+ }
177+
178+
179+let usdnAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdnAssetIdStr"), "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
180+
181+let puzzleAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "puzzleAssetIdStr"), "HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS")
182+
183+let usdtAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdtAssetIdStr"), "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ")
184+
185+let usdtPptAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdtPptAssetIdStr"), "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi")
186+
187+let romeAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "romeAssetIdStr"), "AP4Cb5xLYGH6ZigHreCZHoXpQTWDkPsG2BHqfDUx6taJ")
188+
189+let wavesAssetIdStr = "WAVES"
190+
191+let usdnAssetId = fromBase58String(usdnAssetIdStr)
192+
193+let puzzleAssetId = fromBase58String(puzzleAssetIdStr)
194+
195+let usdtAssetId = fromBase58String(usdtAssetIdStr)
196+
197+let usdtPptAssetId = fromBase58String(usdtPptAssetIdStr)
198+
199+let romeAssetId = fromBase58String(romeAssetIdStr)
200+
201+let wavesAssetId = unit
202+
203+let supportedFeeAssetsStr = [usdnAssetIdStr, puzzleAssetIdStr, usdtAssetIdStr, usdtPptAssetIdStr, wavesAssetIdStr, romeAssetIdStr]
204+
205+let parentPoolAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "parentPoolAddress"), "3PFDgzu1UtswAkCMxqqQjbTeHaX4cMab8Kh")))
206+
207+let masterAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "masterAddress"), "3PLjwHcz9NEuaTo63NZR9B9okQiKQxZSbmf")))
208+
209+let masterPubKey = fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "masterPubKey"), "4z8CKSYQBKkzx7PBb5uBP1YPa6YAHRNTApW1sQVHT5eU"))
210+
211+let oracleAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "oracleAddress"), "3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t")))
212+
213+let stakingAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "stakingAddress"), "3PFTbywqxtFfukX3HyT881g4iW5K4QL3FAS")))
214+
215+let feesAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "feesAddress"), "3PFWAVKmXjfHXyzJb12jCbhP4Uhi9t4uWiD")))
216+
217+let poolsHubAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "poolsHubAddress"), "3P5RGYyCnELF8JTPxgX54dBGzwkQMKUJ5H7")))
218+
219+let shutdownAddressStr = valueOrElse(getString(CONFIG_ADDRESS, "shutdownAddress"), "3PEpv9hRFWEEBU22WRnLsw1bH4YGtcU728o")
220+
221+let layer2Addresses = valueOrElse(getString(CONFIG_ADDRESS, "layer2Addresses"), "3PR1Qvi9mHT35SwWEkLSqqE2L8thiPLdVWU,3PQoBfUKHkJAeGWhooLP7WS8ovb54av9Jp2")
222+
223+let govAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "govAddress"), "3P6uro9xCsE8te78QZjzqy7aq8natSzdceC")))
224+
225+let coldMasterAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "coldMasterAddress"), "3PK9nhPfPbMBygB9ZgHVMHaQbSoojwrBfxj")))
226+
227+let T = tryGetInteger("static_tokensAmount")
228+
229+let assetIds = {
230+ let $l = split(tryGetString("static_tokenIds"), ",")
231+ let $s = size($l)
232+ let $acc0 = nil
233+ func $f0_1 ($a,$i) = if (($i >= $s))
234+ then $a
235+ else addAssetBytesToList($a, $l[$i])
236+
237+ func $f0_2 ($a,$i) = if (($i >= $s))
238+ then $a
239+ else throw("List size exceeds 10")
240+
241+ $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)
242+ }
243+
244+let AssetsWeights = {
245+ let $l = assetIds
246+ let $s = size($l)
247+ let $acc0 = nil
248+ func $f1_1 ($a,$i) = if (($i >= $s))
249+ then $a
250+ else addAssetWeightToList($a, $l[$i])
251+
252+ func $f1_2 ($a,$i) = if (($i >= $s))
253+ then $a
254+ else throw("List size exceeds 10")
255+
256+ $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)
257+ }
258+
259+let Decimals = {
260+ let $l = assetIds
261+ let $s = size($l)
262+ let $acc0 = nil
263+ func $f2_1 ($a,$i) = if (($i >= $s))
264+ then $a
265+ else addAssetDecimalsToList($a, $l[$i])
266+
267+ func $f2_2 ($a,$i) = if (($i >= $s))
268+ then $a
269+ else throw("List size exceeds 10")
270+
271+ $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)
272+ }
273+
274+let Scales = {
275+ let $l = assetIds
276+ let $s = size($l)
277+ let $acc0 = nil
278+ func $f3_1 ($a,$i) = if (($i >= $s))
279+ then $a
280+ else addAssetScaleToList($a, $l[$i])
281+
282+ func $f3_2 ($a,$i) = if (($i >= $s))
283+ then $a
284+ else throw("List size exceeds 10")
285+
286+ $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)
287+ }
288+
289+let Fee = tryGetInteger("static_fee")
290+
291+let earnedAssets = assetIds
292+
293+func _get (assetId,param) = tryGetInteger(((("global_" + assetId) + "_") + param))
294+
295+
296+func _get_feesEarned (assetId) = tryGetInteger(("global_feesEarned_" + assetId))
297+
298+
299+func _get_lastCheck_interest (assetId) = tryGetInteger((("global_lastCheck_" + assetId) + "_interest"))
300+
301+
302+func _get_extraEarned (assetId) = tryGetInteger(("global_extraEarned_" + assetId))
303+
304+
305+func loadGlobalTokenParams (assetId) = match getString(("globalParams_" + assetId)) {
306+ case p: String =>
307+ let params = split(p, "__")
308+ $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]))
309+ case _ =>
310+ $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"))
311+}
312+
313+
314+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)], "__"))
315+
316+
317+func isShutdown () = {
318+ let shutdownAddress = addressFromString(shutdownAddressStr)
319+ if ((shutdownAddress == unit))
320+ then false
321+ else {
322+ let globalShutdown = match getBoolean(value(shutdownAddress), "is_shutdown") {
323+ case x: Boolean =>
324+ x
325+ case _ =>
326+ false
327+ }
328+ let poolShutdown = valueOrElse(getBoolean(value(shutdownAddress), ("poolShutdown_" + toString(this))), false)
329+ if (globalShutdown)
330+ then true
331+ else poolShutdown
332+ }
333+ }
334+
335+
336+func getFactBalance (assetIdStr) = {
337+ let assetParams = loadGlobalTokenParams(assetIdStr)
338+ assetParams._2
339+ }
340+
341+
342+func getCurrentTokenBalance (tokenNum) = {
343+ let tokenIdStr = getAssetString(assetIds[tokenNum])
344+ let tokenParams = loadGlobalTokenParams(tokenIdStr)
345+ tokenParams._1
346+ }
347+
348+
349+func stakeIfNeeded (assetIdStr,amount) = {
350+ let stakeTx = if ((tryGetString(("static_stakingContract_" + assetIdStr)) != ""))
351+ then invoke(addressFromStringValue(tryGetString(("static_stakingContract_" + assetIdStr))), "stake", nil, [AttachedPayment(getAssetBytes(assetIdStr), amount)])
352+ else unit
353+ if ((stakeTx == stakeTx))
354+ then true
355+ else throw("Strict value is not equal to itself.")
356+ }
357+
358+
359+func unstakeIfNeeded (assetIdStr,amount) = {
360+ let unstakeTx = if ((tryGetString(("static_stakingContract_" + assetIdStr)) != ""))
361+ then invoke(addressFromStringValue(tryGetString(("static_stakingContract_" + assetIdStr))), "unstake", [amount], nil)
362+ else unit
363+ if ((unstakeTx == unstakeTx))
364+ then true
365+ else throw("Strict value is not equal to itself.")
366+ }
367+
368+
369+func burnIndexIfNeeded (amount) = {
370+ let indexIdStr = tryGetString("static_poolToken_idStr")
371+ if ((indexIdStr == ""))
372+ then nil
373+ else if ((assetInfo(fromBase58String(indexIdStr)) == unit))
374+ then nil
375+ else [Burn(fromBase58String(indexIdStr), amount)]
376+ }
377+
378+
379+func mintIndexIfNeeded (amount) = {
380+ let indexIdStr = tryGetString("static_poolToken_idStr")
381+ if ((indexIdStr == ""))
382+ then nil
383+ else if ((assetInfo(fromBase58String(indexIdStr)) == unit))
384+ then nil
385+ else [Reissue(fromBase58String(indexIdStr), amount, true)]
386+ }
387+
388+
389+func getKMult () = match getInteger("static_KMult") {
390+ case x: Int =>
391+ x
392+ case _ =>
393+ Scale16
394+}
395+
396+
397+func saveCurrentWeights () = {
398+ let assetIdsLi = split(tryGetString("static_tokenIds"), ",")
399+ func s (accum,assetId) = (accum ++ [IntegerEntry(("rebalance_startWeight_" + assetId), tryGetInteger((("static_" + assetId) + "_weight")))])
400+
401+ let $l = assetIdsLi
402+ let $s = size($l)
403+ let $acc0 = nil
404+ func $f4_1 ($a,$i) = if (($i >= $s))
405+ then $a
406+ else s($a, $l[$i])
407+
408+ func $f4_2 ($a,$i) = if (($i >= $s))
409+ then $a
410+ else throw("List size exceeds 10")
411+
412+ $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)
413+ }
414+
415+
416+func getVirtualPoolTokenAmount () = fraction(tryGetInteger("global_poolToken_amount"), getKMult(), Scale16)
417+
418+
419+func calculatePIssued (amount,tokenId) = {
420+ let Psupply = getVirtualPoolTokenAmount()
421+ let Balance = getFactBalance(getAssetString(tokenId))
422+ let t1 = fraction(amount, Psupply, Balance, DOWN)
423+ t1
424+ }
425+
426+
427+func getMinPIssued (payments) = {
428+ func handler (accum,current) = if ((getFactBalance(getAssetString(current.assetId)) == 0))
429+ then accum
430+ else {
431+ let PIssued = calculatePIssued(current.amount, current.assetId)
432+ if ((PIssued == 0))
433+ then throw("one of the tokens amounts is too low")
434+ else if (if ((accum == 0))
435+ then true
436+ else (accum > PIssued))
437+ then PIssued
438+ else accum
439+ }
440+
441+ let minPIssed = {
442+ let $l = payments
443+ let $s = size($l)
444+ let $acc0 = 0
445+ func $f4_1 ($a,$i) = if (($i >= $s))
446+ then $a
447+ else handler($a, $l[$i])
448+
449+ func $f4_2 ($a,$i) = if (($i >= $s))
450+ then $a
451+ else throw("List size exceeds 10")
452+
453+ $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)
454+ }
455+ minPIssed
456+ }
457+
458+
459+func getPriceFromOracle (assetIdStr) = match getInteger(oracleAddress, (assetIdStr + "_twap5B")) {
460+ case x: Int =>
461+ x
462+ case _ =>
463+ 0
464+}
465+
466+
467+func calculateUsdValue (assetId,amount,aBalance,feeAssetBalance) = {
468+ let assetWeight = tryGetInteger((("static_" + getAssetString(assetId)) + "_weight"))
469+ let feeAssetStr = tryGetString("static_feeToken")
470+ let feeAssetScale = getIntegerValue(this, (("static_" + feeAssetStr) + "_scale"))
471+ let feeAssetNum = value(indexOf(assetIds, getAssetBytes(feeAssetStr)))
472+ let feeAssetWeight = AssetsWeights[feeAssetNum]
473+ let _amount = (toBigInt(amount) * Scale8_BI)
474+ let _feeAssetData = (toBigInt(feeAssetBalance) / toBigInt(feeAssetWeight))
475+ let _assetData = fraction(toBigInt(aBalance), Scale8_BI, toBigInt(assetWeight))
476+ let valInFeeAsset = toInt(fraction(_amount, _feeAssetData, _assetData))
477+ let feeAssetPrice = getPriceFromOracle(feeAssetStr)
478+ fraction(valInFeeAsset, feeAssetPrice, feeAssetScale)
479+ }
480+
481+
482+func calcAvgConcentration () = {
483+ func f (accum,next) = {
484+ let assetIdStr = getAssetString(next)
485+ let weight = tryGetInteger((("static_" + assetIdStr) + "_weight"))
486+ let assetParams = loadGlobalTokenParams(assetIdStr)
487+ let assetFactBalance = assetParams._2
488+ let assetVirtBalance = assetParams._1
489+ $Tuple2((accum._1 + fraction(assetFactBalance, weight, assetVirtBalance)), (accum._2 + weight))
490+ }
491+
492+ let $l = assetIds
493+ let $s = size($l)
494+ let $acc0 = $Tuple2(0, 0)
495+ func $f4_1 ($a,$i) = if (($i >= $s))
496+ then $a
497+ else f($a, $l[$i])
498+
499+ func $f4_2 ($a,$i) = if (($i >= $s))
500+ then $a
501+ else throw("List size exceeds 10")
502+
503+ $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)
504+ }
505+
506+
507+func checkTokensValidity (payments) = {
508+ func handler1 (accum,payment) = (accum ++ [payment.assetId])
509+
510+ let ids = {
511+ let $l = payments
512+ let $s = size($l)
513+ let $acc0 = nil
514+ func $f4_1 ($a,$i) = if (($i >= $s))
515+ then $a
516+ else handler1($a, $l[$i])
517+
518+ func $f4_2 ($a,$i) = if (($i >= $s))
519+ then $a
520+ else throw("List size exceeds 10")
521+
522+ $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)
523+ }
524+ if ((ids == ids))
525+ then {
526+ func handler2 (accum,assetId) = if ((indexOf(ids, assetId) != unit))
527+ then (accum + 1)
528+ else throw(("asset not attached: " + getAssetString(assetId)))
529+
530+ let checks = {
531+ let $l = assetIds
532+ let $s = size($l)
533+ let $acc0 = 0
534+ func $f5_1 ($a,$i) = if (($i >= $s))
535+ then $a
536+ else handler2($a, $l[$i])
537+
538+ func $f5_2 ($a,$i) = if (($i >= $s))
539+ then $a
540+ else throw("List size exceeds 10")
541+
542+ $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)
543+ }
544+ if ((checks == checks))
545+ then true
546+ else throw("Strict value is not equal to itself.")
547+ }
548+ else throw("Strict value is not equal to itself.")
549+ }
550+
551+
552+func handlePoolTokensAdd (PIssued,payments,userAddress,needChange) = {
553+ func getTokenPaymentAmount (tokenId) = {
554+ func handler (accum,payment) = if ((payment.assetId == tokenId))
555+ then payment.amount
556+ else accum
557+
558+ let $l = payments
559+ let $s = size($l)
560+ let $acc0 = 0
561+ func $f4_1 ($a,$i) = if (($i >= $s))
562+ then $a
563+ else handler($a, $l[$i])
564+
565+ func $f4_2 ($a,$i) = if (($i >= $s))
566+ then $a
567+ else throw("List size exceeds 10")
568+
569+ $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)
570+ }
571+
572+ func handleTokenChange (accum,tokenId) = {
573+ let assetIdStr = getAssetString(tokenId)
574+ let assetParams = loadGlobalTokenParams(assetIdStr)
575+ let paymentAmount = getTokenPaymentAmount(tokenId)
576+ let Bk = assetParams._2
577+ let PSupply = getVirtualPoolTokenAmount()
578+ let Dk = toInt(fraction(toBigInt(PIssued), toBigInt(Bk), toBigInt(PSupply), CEILING))
579+ let toReturn = (paymentAmount - Dk)
580+ let stakeTx = stakeIfNeeded(assetIdStr, Dk)
581+ if ((stakeTx == stakeTx))
582+ then {
583+ let t = if (if (needChange)
584+ then (toReturn > 0)
585+ else false)
586+ then [ScriptTransfer(userAddress, toReturn, tokenId)]
587+ else nil
588+ let selloffStartBalance = if ((assetParams._8 != ((height / 100) * 100)))
589+ then assetParams._7
590+ else fraction(assetParams._7, (PSupply + PIssued), PSupply)
591+ let assetParamsUpd = $Tuple8(fraction(assetParams._1, (PSupply + PIssued), PSupply), (assetParams._2 + Dk), assetParams._3, assetParams._4, assetParams._5, assetParams._6, selloffStartBalance, assetParams._8)
592+ ((accum ++ t) ++ [saveGlobalTokenParams(assetIdStr, assetParamsUpd)])
593+ }
594+ else throw("Strict value is not equal to itself.")
595+ }
596+
597+ let $l = assetIds
598+ let $s = size($l)
599+ let $acc0 = nil
600+ func $f4_1 ($a,$i) = if (($i >= $s))
601+ then $a
602+ else handleTokenChange($a, $l[$i])
603+
604+ func $f4_2 ($a,$i) = if (($i >= $s))
605+ then $a
606+ else throw("List size exceeds 10")
607+
608+ $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)
609+ }
610+
611+
612+func calcMintedWithOneToken (assetAddedIdStr,amount) = {
613+ let PSupply = getVirtualPoolTokenAmount()
614+ let assetParams = loadGlobalTokenParams(assetAddedIdStr)
615+ let assetFactBalance = assetParams._2
616+ let assetVirtBalance = assetParams._1
617+ let assetWeight = tryGetInteger((("static_" + assetAddedIdStr) + "_weight"))
618+ let assetScale = tryGetInteger((("static_" + assetAddedIdStr) + "_scale"))
619+ let assetDecimals = tryGetInteger((("static_" + assetAddedIdStr) + "_decimals"))
620+ let PIssuedNoMultiplier = fraction(PSupply, (toInt(pow(toBigInt((assetScale + fraction(amount, assetScale, assetVirtBalance))), assetDecimals, toBigInt(assetWeight), 4, 8, DOWN)) - Scale8), Scale8)
621+ let avgConc = calcAvgConcentration()
622+ let PIssued = fraction(PIssuedNoMultiplier, avgConc._2, avgConc._1)
623+ let assetParamsUpd = $Tuple8((assetVirtBalance + amount), (assetFactBalance + amount), assetParams._3, assetParams._4, assetParams._5, assetParams._6, assetParams._7, assetParams._8)
624+ $Tuple2([saveGlobalTokenParams(assetAddedIdStr, assetParamsUpd)], PIssued)
625+ }
626+
627+
628+func calcRedeemWithOneToken (assetOutIdStr,PRedeemed) = {
629+ let PSupply = getVirtualPoolTokenAmount()
630+ let assetParams = loadGlobalTokenParams(assetOutIdStr)
631+ let assetFactBalance = assetParams._2
632+ let assetVirtBalance = assetParams._1
633+ let assetWeight = tryGetInteger((("static_" + assetOutIdStr) + "_weight"))
634+ let assetScale = tryGetInteger((("static_" + assetOutIdStr) + "_scale"))
635+ let assetDecimals = tryGetInteger((("static_" + assetOutIdStr) + "_decimals"))
636+ let amountOutNoMulitplier = fraction(assetVirtBalance, (Scale8 - toInt(pow(toBigInt((assetScale - fraction(PRedeemed, assetScale, PSupply))), assetDecimals, toBigInt(fraction(10000, 10000, assetWeight)), 4, 8, DOWN))), Scale8)
637+ let avgConc = calcAvgConcentration()
638+ let amountOut = fraction(amountOutNoMulitplier, avgConc._1, avgConc._2)
639+ if ((amountOut > assetFactBalance))
640+ then throw("no available fact liquidity to withdraw in one token")
641+ else {
642+ let assetParamsUpd = $Tuple8((assetVirtBalance - amountOut), (assetFactBalance - amountOut), assetParams._3, assetParams._4, assetParams._5, assetParams._6, assetParams._7, assetParams._8)
643+ $Tuple2([saveGlobalTokenParams(assetOutIdStr, assetParamsUpd)], amountOut)
644+ }
645+ }
646+
647+
648+func handlePoolTokensRedeem (PRedeemed,userAddress) = {
649+ func handleTokenRedeem (accum,tokenId) = {
650+ let assetIdStr = getAssetString(tokenId)
651+ let assetParams = loadGlobalTokenParams(assetIdStr)
652+ let Bk = assetParams._2
653+ let PSupply = getVirtualPoolTokenAmount()
654+ let amount = toInt(fraction(toBigInt(PRedeemed), toBigInt(Bk), toBigInt(PSupply), DOWN))
655+ let unstakeTx = unstakeIfNeeded(assetIdStr, amount)
656+ if ((unstakeTx == unstakeTx))
657+ then {
658+ let selloffStartBalance = if ((assetParams._8 != ((height / 100) * 100)))
659+ then assetParams._7
660+ else fraction(assetParams._7, (PSupply - PRedeemed), PSupply)
661+ let assetParamsUpd = $Tuple8(fraction(assetParams._1, (PSupply - PRedeemed), PSupply), (assetParams._2 - amount), assetParams._3, assetParams._4, assetParams._5, assetParams._6, selloffStartBalance, assetParams._8)
662+ ((accum ++ [ScriptTransfer(userAddress, amount, tokenId)]) ++ [saveGlobalTokenParams(assetIdStr, assetParamsUpd)])
663+ }
664+ else throw("Strict value is not equal to itself.")
665+ }
666+
667+ let $l = assetIds
668+ let $s = size($l)
669+ let $acc0 = nil
670+ func $f4_1 ($a,$i) = if (($i >= $s))
671+ then $a
672+ else handleTokenRedeem($a, $l[$i])
673+
674+ func $f4_2 ($a,$i) = if (($i >= $s))
675+ then $a
676+ else throw("List size exceeds 10")
677+
678+ $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)
679+ }
680+
681+
682+func calculateOutAmount (AmountIn,assetIn,assetOut,BalanceIn,BalanceOut) = {
683+ let IndexIn = value(indexOf(assetIds, assetIn))
684+ let IndexOut = value(indexOf(assetIds, assetOut))
685+ if ((IndexIn == IndexOut))
686+ then AmountIn
687+ 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)
688+ }
689+
690+
691+func calcClaimRewardAmount (addressStr,indexAmount,assetIdStr,currentTokenInterest) = fraction(indexAmount, (currentTokenInterest - tryGetInteger((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"))), Scale16)
692+
693+
694+func claimResult (address) = {
695+ let addressStr = toString(address)
696+ let indexAmount = tryGetInteger((addressStr + "_indexStaked"))
697+ let feeAssetStr = tryGetString("static_feeToken")
698+ let feeAssetParams = loadGlobalTokenParams(feeAssetStr)
699+ let feeTokenBalance = feeAssetParams._1
700+ func handler (accum,assetId) = {
701+ let assetIdStr = getAssetString(assetId)
702+ let assetParams = loadGlobalTokenParams(assetIdStr)
703+ let currentTokenInterest = assetParams._4
704+ let aBalance = assetParams._1
705+ let rewardAmount = calcClaimRewardAmount(addressStr, indexAmount, assetIdStr, currentTokenInterest)
706+ let transfer = if ((rewardAmount == 0))
707+ then nil
708+ else {
709+ let unstakeInv = unstakeIfNeeded(assetIdStr, rewardAmount)
710+ if ((unstakeInv == unstakeInv))
711+ then [ScriptTransfer(address, rewardAmount, assetId)]
712+ else throw("Strict value is not equal to itself.")
713+ }
714+ $Tuple2(((accum._1 ++ transfer) ++ [IntegerEntry((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"), currentTokenInterest)]), (accum._2 + calculateUsdValue(assetId, rewardAmount, aBalance, feeTokenBalance)))
715+ }
716+
717+ let accum = {
718+ let $l = earnedAssets
719+ let $s = size($l)
720+ let $acc0 = $Tuple2(nil, 0)
721+ func $f4_1 ($a,$i) = if (($i >= $s))
722+ then $a
723+ else handler($a, $l[$i])
724+
725+ func $f4_2 ($a,$i) = if (($i >= $s))
726+ then $a
727+ else throw("List size exceeds 10")
728+
729+ $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)
730+ }
731+ $Tuple2((accum._1 ++ [IntegerEntry((addressStr + "_claimedRewardUSD"), (tryGetInteger((addressStr + "_claimedRewardUSD")) + accum._2)), IntegerEntry((addressStr + "_lastClaim"), lastBlock.timestamp)]), accum._2)
732+ }
733+
734+
735+func claimQuote (address) = {
736+ let addressStr = toString(address)
737+ let indexAmount = tryGetInteger((addressStr + "_indexStaked"))
738+ let feeAssetStr = tryGetString("static_feeToken")
739+ let feeAssetParams = loadGlobalTokenParams(feeAssetStr)
740+ let feeTokenBalance = feeAssetParams._1
741+ func handler (accum,assetId) = {
742+ let assetIdStr = getAssetString(assetId)
743+ let assetParams = loadGlobalTokenParams(assetIdStr)
744+ let currentTokenInterest = assetParams._4
745+ let aBalance = assetParams._1
746+ let rewardAmount = calcClaimRewardAmount(addressStr, indexAmount, assetIdStr, currentTokenInterest)
747+ (accum + calculateUsdValue(assetId, rewardAmount, aBalance, feeTokenBalance))
748+ }
749+
750+ let $l = earnedAssets
751+ let $s = size($l)
752+ let $acc0 = 0
753+ func $f4_1 ($a,$i) = if (($i >= $s))
754+ then $a
755+ else handler($a, $l[$i])
756+
757+ func $f4_2 ($a,$i) = if (($i >= $s))
758+ then $a
759+ else throw("List size exceeds 10")
760+
761+ $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)
762+ }
763+
764+
765+func getWavesClaimAmount (address) = if ((indexOf(assetIds, unit) == unit))
766+ then 0
767+ else {
768+ let addressStr = toString(address)
769+ let indexAmount = tryGetInteger((addressStr + "_indexStaked"))
770+ let wavesParams = loadGlobalTokenParams("WAVES")
771+ let currentTokenInterest = wavesParams._4
772+ let rewardAmount = fraction(indexAmount, (currentTokenInterest - tryGetInteger((addressStr + "_lastCheck_WAVES_interest"))), Scale16)
773+ max([0, rewardAmount])
774+ }
775+
776+
777+func getWavesRedeemAmount (PRedeemed) = if ((indexOf(assetIds, unit) == unit))
778+ then 0
779+ else {
780+ let wavesParams = loadGlobalTokenParams("WAVES")
781+ let Bk = wavesParams._2
782+ let PSupply = getVirtualPoolTokenAmount()
783+ toInt(fraction(toBigInt(PRedeemed), toBigInt(Bk), toBigInt(PSupply), CEILING))
784+ }
785+
786+
787+func getWavesChangeAmount (PIssued,payments,needChange) = if (if (!(needChange))
788+ then true
789+ else (indexOf(assetIds, unit) == unit))
790+ then 0
791+ else {
792+ func findWavesPayment (accum,pmt) = if ((pmt.assetId == unit))
793+ then pmt.amount
794+ else accum
795+
796+ let wavesPmt = {
797+ let $l = payments
798+ let $s = size($l)
799+ let $acc0 = 0
800+ func $f4_1 ($a,$i) = if (($i >= $s))
801+ then $a
802+ else findWavesPayment($a, $l[$i])
803+
804+ func $f4_2 ($a,$i) = if (($i >= $s))
805+ then $a
806+ else throw("List size exceeds 10")
807+
808+ $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)
809+ }
810+ if ((wavesPmt == 0))
811+ then 0
812+ else {
813+ let wavesParams = loadGlobalTokenParams("WAVES")
814+ let Bk = wavesParams._2
815+ let PSupply = getVirtualPoolTokenAmount()
816+ let Dk = toInt(fraction(toBigInt(PIssued), toBigInt(Bk), toBigInt(PSupply), CEILING))
817+ max([0, (wavesPmt - Dk)])
818+ }
819+ }
820+
821+
822+func indexStakeResult (addressStr,amount) = {
823+ let li = claimResult(addressFromStringValue(addressStr))._1
824+ (li ++ [IntegerEntry((addressStr + "_indexStaked"), (tryGetInteger((addressStr + "_indexStaked")) + amount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") + amount))])
825+ }
826+
827+
828+func isOwnerOrMaster (caller) = {
829+ let ownerAddress = addressFromStringValue(tryGetString("static_poolOwner"))
830+ if ((caller == ownerAddress))
831+ then true
832+ else (caller == masterAddress)
833+ }
834+
835+
836+func sum (accum,n) = (accum + parseIntValue(n))
837+
838+
839+func checkFeeAsset (accum,next) = if (if ((indexOf(supportedFeeAssetsStr, next) != unit))
840+ then (accum == "")
841+ else false)
842+ then next
843+ else accum
844+
845+
846+func calcInterestChange (assetIdStr,lpFee) = {
847+ let totalIndex = tryGetInteger("global_indexStaked")
848+ if ((totalIndex == 0))
849+ then 0
850+ else fraction(lpFee, Scale16, totalIndex)
851+ }
852+
853+
854+func updSelloffData (assetIdStr,amountIn,balance,selloffParams) = {
855+ let currentPeriod = ((height / 100) * 100)
856+ let prevPeriod = selloffParams._3
857+ let prevSelloff = if ((currentPeriod == prevPeriod))
858+ then selloffParams._1
859+ else 0
860+ let selloffStartBalance = if ((currentPeriod == prevPeriod))
861+ then selloffParams._2
862+ else balance
863+ let selloffDelta = if ((selloffStartBalance == 0))
864+ then 0
865+ else fraction(Scale16, amountIn, selloffStartBalance)
866+ let maxSelloff = tryGetInteger((("static_" + assetIdStr) + "_maxSelloff"))
867+ if (if (((prevSelloff + selloffDelta) > maxSelloff))
868+ then (maxSelloff != 0)
869+ else false)
870+ then throw(("max selloff reached for this asset " + assetIdStr))
871+ else {
872+ let startH = if ((currentPeriod == prevPeriod))
873+ then prevPeriod
874+ else currentPeriod
875+ let startB = if ((currentPeriod == prevPeriod))
876+ then selloffParams._2
877+ else selloffStartBalance
878+ $Tuple3((prevSelloff + selloffDelta), startB, startH)
879+ }
880+ }
881+
882+
883+func validatePayments (assetsList,payments) = {
884+ func getPaymentAssets (accum,next) = if ((0 >= next.amount))
885+ then throw(((("Too low payment amount for " + getAssetString(next.assetId)) + ": ") + toString(next.amount)))
886+ else (accum ++ [getAssetString(next.assetId)])
887+
888+ let paymentList = {
889+ let $l = payments
890+ let $s = size($l)
891+ let $acc0 = nil
892+ func $f4_1 ($a,$i) = if (($i >= $s))
893+ then $a
894+ else getPaymentAssets($a, $l[$i])
895+
896+ func $f4_2 ($a,$i) = if (($i >= $s))
897+ then $a
898+ else throw("List size exceeds 10")
899+
900+ $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)
901+ }
902+ func f1 (accum,next) = if ((indexOf(assetsList, next) == unit))
903+ then throw(((next + " asset is present in payments, but is not in new assets: ") + makeString(assetsList, ",")))
904+ else (accum + 1)
905+
906+ func f2 (accum,next) = if ((indexOf(paymentList, next) == unit))
907+ then throw(((next + " asset is present in new assets, but is not in payments: ") + makeString(paymentList, ",")))
908+ else (accum + 1)
909+
910+ let a1 = {
911+ let $l = paymentList
912+ let $s = size($l)
913+ let $acc0 = 0
914+ func $f5_1 ($a,$i) = if (($i >= $s))
915+ then $a
916+ else f1($a, $l[$i])
917+
918+ func $f5_2 ($a,$i) = if (($i >= $s))
919+ then $a
920+ else throw("List size exceeds 10")
921+
922+ $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)
923+ }
924+ let a2 = {
925+ let $l = assetsList
926+ let $s = size($l)
927+ let $acc0 = 0
928+ func $f6_1 ($a,$i) = if (($i >= $s))
929+ then $a
930+ else f2($a, $l[$i])
931+
932+ func $f6_2 ($a,$i) = if (($i >= $s))
933+ then $a
934+ else throw("List size exceeds 10")
935+
936+ $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)
937+ }
938+ (a1 + a2)
939+ }
940+
941+
942+func validateWeights (weights) = {
943+ func v (accum,w) = {
944+ let wInt = valueOrErrorMessage(parseInt(w), ("Wrong weight format: " + w))
945+ if (if ((MIN_WEIGHT > wInt))
946+ then true
947+ else (wInt > MAX_WEIGHT))
948+ then throw(((((("Weight should be in range " + toString(MIN_WEIGHT)) + " - ") + toString(MAX_WEIGHT)) + ", current: ") + w))
949+ else (accum + wInt)
950+ }
951+
952+ let $l = weights
953+ let $s = size($l)
954+ let $acc0 = 0
955+ func $f4_1 ($a,$i) = if (($i >= $s))
956+ then $a
957+ else v($a, $l[$i])
958+
959+ func $f4_2 ($a,$i) = if (($i >= $s))
960+ then $a
961+ else throw("List size exceeds 10")
962+
963+ $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)
964+ }
965+
966+
967+func getP1P2 (assetIdStr,baseAssetIdStr) = {
968+ let assetParams = loadGlobalTokenParams(assetIdStr)
969+ let baseAssetParams = loadGlobalTokenParams(baseAssetIdStr)
970+ let B1 = baseAssetParams._1
971+ let B2 = assetParams._1
972+ let F1 = baseAssetParams._2
973+ let F2 = assetParams._2
974+ let S1 = tryGetInteger((("static_" + baseAssetIdStr) + "_scale"))
975+ let S2 = tryGetInteger((("static_" + assetIdStr) + "_scale"))
976+ let D1 = tryGetInteger((("static_" + baseAssetIdStr) + "_decimals"))
977+ let D2 = tryGetInteger((("static_" + assetIdStr) + "_decimals"))
978+ let W1 = tryGetInteger((("static_" + baseAssetIdStr) + "_weight"))
979+ let W2 = tryGetInteger((("static_" + assetIdStr) + "_weight"))
980+ let W1W2 = fraction(W1, 10000, W2)
981+ let W2W1 = fraction(W2, 10000, W1)
982+ let p1_unweighted = fraction((B1 - F1), S1, fraction(B2, pow(fraction(B1, S1, (B1 - F1)), D1, W1W2, 4, D1, CEILING), S2))
983+ let p1 = fraction(p1_unweighted, W2W1, 10000)
984+ if ((B2 == F2))
985+ then $Tuple2(p1, unit)
986+ else {
987+ let p2_unweighted = fraction(fraction(B1, pow(fraction(B2, S2, (B2 - F2)), D2, W2W1, 4, D2, FLOOR), S2), S2, (B2 - F2))
988+ let p2 = fraction(p2_unweighted, W2W1, 10000)
989+ $Tuple2(p1, p2)
990+ }
991+ }
992+
993+
994+@Callable(i)
995+func addUnderlyingStaker (stakerAddress,assetIdStr) = {
996+ let _isShutdown = if (isShutdown())
997+ then throw("contract is on stop")
998+ else false
999+ if ((_isShutdown == _isShutdown))
1000+ then if ((this != i.caller))
1001+ then throw("admin only")
1002+ else [StringEntry(("static_stakingContract_" + assetIdStr), stakerAddress)]
1003+ else throw("Strict value is not equal to itself.")
1004+ }
1005+
1006+
1007+
1008+@Callable(i)
1009+func preInit (assetIdsStr,assetWeightsStr,assetMaxSelloffStr,baseTokenIdStr,poolDomain,poolOwner,fee) = {
1010+ let poolOwnerAddress = addressFromStringValue(poolOwner)
1011+ let _checkPoolOwner = if ((addressFromString(poolOwner) == unit))
1012+ then throw("wrong pool owner address")
1013+ else true
1014+ if ((_checkPoolOwner == _checkPoolOwner))
1015+ then {
1016+ let assetIdsStrLi = split(assetIdsStr, ",")
1017+ let assetMaxSelloffStrLi = split(assetMaxSelloffStr, ",")
1018+ let assetWeightsStrLi = split(assetWeightsStr, ",")
1019+ let assetIdsLi = {
1020+ let $l = assetIdsStrLi
1021+ let $s = size($l)
1022+ let $acc0 = nil
1023+ func $f4_1 ($a,$i) = if (($i >= $s))
1024+ then $a
1025+ else addAssetBytesToList($a, $l[$i])
1026+
1027+ func $f4_2 ($a,$i) = if (($i >= $s))
1028+ then $a
1029+ else throw("List size exceeds 10")
1030+
1031+ $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)
1032+ }
1033+ let feeAssetChosenStr = {
1034+ let $l = assetIdsStrLi
1035+ let $s = size($l)
1036+ let $acc0 = ""
1037+ func $f5_1 ($a,$i) = if (($i >= $s))
1038+ then $a
1039+ else checkFeeAsset($a, $l[$i])
1040+
1041+ func $f5_2 ($a,$i) = if (($i >= $s))
1042+ then $a
1043+ else throw("List size exceeds 10")
1044+
1045+ $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)
1046+ }
1047+ let feeAssetStr = if ((feeAssetChosenStr == ""))
1048+ then baseTokenIdStr
1049+ else feeAssetChosenStr
1050+ let basePresent = if ((indexOf(assetIdsStrLi, baseTokenIdStr) == unit))
1051+ then throw("base token missing in list")
1052+ else true
1053+ if ((basePresent == basePresent))
1054+ then {
1055+ let sameLengths = if (if ((size(assetIdsStrLi) != size(assetWeightsStrLi)))
1056+ then true
1057+ else (size(assetIdsStrLi) != size(assetMaxSelloffStrLi)))
1058+ then throw("assetIds, weights, and maxSelloff length mismatch")
1059+ else true
1060+ if ((sameLengths == sameLengths))
1061+ then if (isShutdown())
1062+ then throw("contract is on stop")
1063+ else if ((this != i.caller))
1064+ then throw("admin only")
1065+ else if ((size(poolDomain) > 13))
1066+ then throw("too large pool domain")
1067+ else if (if ((fee > 500))
1068+ then true
1069+ else (0 > fee))
1070+ then throw("fee value must be between 0 and 500 (0-5%)")
1071+ else if ((validateWeights(assetWeightsStrLi) != 10000))
1072+ then throw(("weights sum should be 10000, current: " + toString(validateWeights(assetWeightsStrLi))))
1073+ else {
1074+ func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetIdsLi)))
1075+ then accum
1076+ else {
1077+ let assetStakingAddress = {
1078+ let @ = invoke(poolsHubAddress, "useEmptyContract", [("staker_" + assetIdsStrLi[assetNum])], nil)
1079+ if ($isInstanceOf(@, "String"))
1080+ then @
1081+ else throw(($getType(@) + " couldn't be cast to String"))
1082+ }
1083+ if ((assetStakingAddress == assetStakingAddress))
1084+ then {
1085+ let assetDecimals = match assetIdsLi[assetNum] {
1086+ case x: ByteVector =>
1087+ value(assetInfo(x)).decimals
1088+ case _ =>
1089+ 8
1090+ }
1091+ ((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] == ""))
1092+ then nil
1093+ else [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_maxSelloff"), (parseIntValue(assetMaxSelloffStrLi[assetNum]) * Scale12))]))
1094+ }
1095+ else throw("Strict value is not equal to itself.")
1096+ }
1097+
1098+ ({
1099+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1100+ let $s = size($l)
1101+ let $acc0 = nil
1102+ func $f6_1 ($a,$i) = if (($i >= $s))
1103+ then $a
1104+ else addTokenDataEntries($a, $l[$i])
1105+
1106+ func $f6_2 ($a,$i) = if (($i >= $s))
1107+ then $a
1108+ else throw("List size exceeds 10")
1109+
1110+ $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)
1111+ } ++ [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)])
1112+ }
1113+ else throw("Strict value is not equal to itself.")
1114+ }
1115+ else throw("Strict value is not equal to itself.")
1116+ }
1117+ else throw("Strict value is not equal to itself.")
1118+ }
1119+
1120+
1121+
1122+@Callable(i)
1123+func setWavesNode (nodeAddress) = if (!(isOwnerOrMaster(i.caller)))
1124+ then throw("admin/owner only")
1125+ else {
1126+ let _nodeAddress = addressFromString(nodeAddress)
1127+ let nodeOk = match _nodeAddress {
1128+ case t: Address =>
1129+ true
1130+ case _ =>
1131+ false
1132+ }
1133+ let canSetNode = if (if (nodeOk)
1134+ then true
1135+ else (nodeAddress == ""))
1136+ then true
1137+ else throw("Wrong node address")
1138+ if ((canSetNode == canSetNode))
1139+ then {
1140+ let selfSet = if ((_nodeAddress == this))
1141+ then throw("Node address can't be contract's own address")
1142+ else true
1143+ if ((selfSet == selfSet))
1144+ then {
1145+ let newNodeAddr = if ((nodeAddress != ""))
1146+ then _nodeAddress
1147+ else unit
1148+ let leaseActions = rebalanceLeaseActions(0, newNodeAddr)
1149+ (leaseActions ++ [StringEntry("static_nodeAddress", nodeAddress)])
1150+ }
1151+ else throw("Strict value is not equal to itself.")
1152+ }
1153+ else throw("Strict value is not equal to itself.")
1154+ }
1155+
1156+
1157+
1158+@Callable(i)
1159+func deInit () = if (isShutdown())
1160+ then throw("contract is on stop")
1161+ else if ((i.caller != this))
1162+ then throw("admin only")
1163+ else [IntegerEntry("global_wasInited", 0)]
1164+
1165+
1166+
1167+@Callable(i)
1168+func init (assetIdsStr,assetWeightsStr,assetMaxSelloffStr,baseTokenIdStr,poolDomain,fee,vBalancesStr) = {
1169+ let preInitInv = invoke(this, "preInit", [assetIdsStr, assetWeightsStr, assetMaxSelloffStr, baseTokenIdStr, poolDomain, toString(i.caller), fee], nil)
1170+ if ((preInitInv == preInitInv))
1171+ then {
1172+ let vBalances = parstStrToIntList(vBalancesStr)
1173+ func getPaymentAmount (assetIdStr) = {
1174+ func handler (accum,payment) = if ((getAssetString(payment.assetId) == assetIdStr))
1175+ then payment.amount
1176+ else accum
1177+
1178+ let $l = i.payments
1179+ let $s = size($l)
1180+ let $acc0 = 0
1181+ func $f4_1 ($a,$i) = if (($i >= $s))
1182+ then $a
1183+ else handler($a, $l[$i])
1184+
1185+ func $f4_2 ($a,$i) = if (($i >= $s))
1186+ then $a
1187+ else throw("List size exceeds 10")
1188+
1189+ $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)
1190+ }
1191+
1192+ func prepareList () = {
1193+ func handler (accum,assetId) = {
1194+ let assetIdStr = getAssetString(assetId)
1195+ let n = value(indexOf(assetIds, assetId))
1196+ let paymentAmount = getPaymentAmount(assetIdStr)
1197+ let assetParams = loadGlobalTokenParams(assetIdStr)
1198+ let assetParamsUpd = $Tuple8(vBalances[n], paymentAmount, assetParams._3, assetParams._4, assetParams._5, assetParams._6, assetParams._7, assetParams._8)
1199+ (accum ++ [saveGlobalTokenParams(assetIdStr, assetParamsUpd)])
1200+ }
1201+
1202+ let $l = assetIds
1203+ let $s = size($l)
1204+ let $acc0 = nil
1205+ func $f4_1 ($a,$i) = if (($i >= $s))
1206+ then $a
1207+ else handler($a, $l[$i])
1208+
1209+ func $f4_2 ($a,$i) = if (($i >= $s))
1210+ then $a
1211+ else throw("List size exceeds 10")
1212+
1213+ $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)
1214+ }
1215+
1216+ func prepareList2 () = {
1217+ func handler1 (accum,payment) = {
1218+ let stakeTx = stakeIfNeeded(getAssetString(payment.assetId), payment.amount)
1219+ if ((stakeTx == stakeTx))
1220+ then accum
1221+ else throw("Strict value is not equal to itself.")
1222+ }
1223+
1224+ let $l = i.payments
1225+ let $s = size($l)
1226+ let $acc0 = nil
1227+ func $f4_1 ($a,$i) = if (($i >= $s))
1228+ then $a
1229+ else handler1($a, $l[$i])
1230+
1231+ func $f4_2 ($a,$i) = if (($i >= $s))
1232+ then $a
1233+ else throw("List size exceeds 10")
1234+
1235+ $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)
1236+ }
1237+
1238+ func calculatePoolTokensAmount (assetId) = {
1239+ func handler (accum,assetId) = {
1240+ func handler2 (accum,n) = if ((n == assetId))
1241+ then value(indexOf(assetIds, n))
1242+ else accum
1243+
1244+ let Token = {
1245+ let $l = assetIds
1246+ let $s = size($l)
1247+ let $acc0 = 1
1248+ func $f4_1 ($a,$i) = if (($i >= $s))
1249+ then $a
1250+ else handler2($a, $l[$i])
1251+
1252+ func $f4_2 ($a,$i) = if (($i >= $s))
1253+ then $a
1254+ else throw("List size exceeds 10")
1255+
1256+ $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)
1257+ }
1258+ fraction(accum, pow(vBalances[Token], Decimals[Token], AssetsWeights[Token], AssetsWeightsDecimals, 8, FLOOR), Scale8)
1259+ }
1260+
1261+ let $l = assetIds
1262+ let $s = size($l)
1263+ let $acc0 = PoolTokenScale
1264+ func $f4_1 ($a,$i) = if (($i >= $s))
1265+ then $a
1266+ else handler($a, $l[$i])
1267+
1268+ func $f4_2 ($a,$i) = if (($i >= $s))
1269+ then $a
1270+ else throw("List size exceeds 10")
1271+
1272+ $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)
1273+ }
1274+
1275+ if (isShutdown())
1276+ then throw("contract is on stop")
1277+ else if ((size(i.payments) == 0))
1278+ then throw("at least some of the assets should be provided as payment")
1279+ else if ((tryGetInteger("global_wasInited") > 0))
1280+ then throw("pool already inited")
1281+ else {
1282+ let initialPoolTokens = calculatePoolTokensAmount(assetIds)
1283+ let notifyInvoke = invoke(poolsHubAddress, "addSelfPool", nil, nil)
1284+ if ((notifyInvoke == notifyInvoke))
1285+ then if ((initialPoolTokens == 0))
1286+ then throw("you need a bigger tokens amount to launch the pool")
1287+ else (((prepareList() ++ prepareList2()) ++ [IntegerEntry("global_poolToken_amount", initialPoolTokens), IntegerEntry("global_wasInited", 1), IntegerEntry((toString(i.caller) + "_indexStaked"), initialPoolTokens), IntegerEntry("global_indexStaked", initialPoolTokens)]) ++ rebalanceLeaseActions(0, getNodeAddress()))
1288+ else throw("Strict value is not equal to itself.")
1289+ }
1290+ }
1291+ else throw("Strict value is not equal to itself.")
1292+ }
1293+
1294+
1295+
1296+@Callable(i)
1297+func generateIndex (needChange) = {
1298+ let _isShutdown = if (isShutdown())
1299+ then throw("contract is on stop")
1300+ else false
1301+ if ((_isShutdown == _isShutdown))
1302+ then if ((size(i.payments) != T))
1303+ then throw(("you need to attach all pool tokens. amount of pool tokens: " + toString(T)))
1304+ else if (!(checkTokensValidity(i.payments)))
1305+ then throw("wrong assets attached")
1306+ else {
1307+ let PIssuedNoMult = getMinPIssued(i.payments)
1308+ let result = handlePoolTokensAdd(PIssuedNoMult, i.payments, i.originCaller, needChange)
1309+ let PIssuedWithMult = fraction(PIssuedNoMult, Scale16, getKMult(), DOWN)
1310+ let wavesClaimOut = getWavesClaimAmount(i.caller)
1311+ let claimActions = claimResult(i.caller)._1
1312+ let wavesOut = (getWavesChangeAmount(PIssuedNoMult, i.payments, needChange) + wavesClaimOut)
1313+ let leaseActions = rebalanceLeaseActions(wavesOut, getNodeAddress())
1314+ $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)
1315+ }
1316+ else throw("Strict value is not equal to itself.")
1317+ }
1318+
1319+
1320+
1321+@Callable(i)
1322+func redeemIndex (poolTokenAmount) = {
1323+ let _isValidAmount = if ((0 >= poolTokenAmount))
1324+ then throw("amount should be positive")
1325+ else true
1326+ if ((_isValidAmount == _isValidAmount))
1327+ then if ((poolTokenAmount > tryGetInteger((toString(i.caller) + "_indexStaked"))))
1328+ then throw("user doesn't have this amount of pool tokens")
1329+ else if (isShutdown())
1330+ then throw("contract is on stop")
1331+ else {
1332+ let PRedeemedWithMult = poolTokenAmount
1333+ let PRedeemedWithNoMult = fraction(PRedeemedWithMult, getKMult(), Scale16, DOWN)
1334+ let result = handlePoolTokensRedeem(PRedeemedWithNoMult, i.caller)
1335+ let wavesClaimOut = getWavesClaimAmount(i.caller)
1336+ let claimActions = claimResult(i.caller)._1
1337+ let wavesOut = (getWavesRedeemAmount(PRedeemedWithNoMult) + wavesClaimOut)
1338+ let leaseActions = rebalanceLeaseActions(wavesOut, getNodeAddress())
1339+ ((((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))
1340+ }
1341+ else throw("Strict value is not equal to itself.")
1342+ }
1343+
1344+
1345+
1346+@Callable(i)
1347+func stakeIndex () = {
1348+ let _isShutdown = if (isShutdown())
1349+ then throw("contract is on stop")
1350+ else false
1351+ if ((_isShutdown == _isShutdown))
1352+ then {
1353+ let checkPayment = if ((size(i.payments) != 1))
1354+ then throw("One payment allowed only")
1355+ else true
1356+ if ((checkPayment == checkPayment))
1357+ then {
1358+ let addressStr = toString(i.originCaller)
1359+ let pmt = i.payments[0]
1360+ if ((value(pmt.assetId) != fromBase58String(tryGetString("static_poolToken_idStr"))))
1361+ then throw("wrong asset attached")
1362+ else {
1363+ let wavesClaimOut = getWavesClaimAmount(i.originCaller)
1364+ let stakeActions = indexStakeResult(addressStr, pmt.amount)
1365+ (rebalanceLeaseActions(wavesClaimOut, getNodeAddress()) ++ stakeActions)
1366+ }
1367+ }
1368+ else throw("Strict value is not equal to itself.")
1369+ }
1370+ else throw("Strict value is not equal to itself.")
1371+ }
1372+
1373+
1374+
1375+@Callable(i)
1376+func stakeIndexFor (addressStr) = {
1377+ let _isShutdown = if (isShutdown())
1378+ then throw("contract is on stop")
1379+ else false
1380+ if ((_isShutdown == _isShutdown))
1381+ then {
1382+ let checkPayment = if ((size(i.payments) != 1))
1383+ then throw("One payment allowed only")
1384+ else true
1385+ if ((checkPayment == checkPayment))
1386+ then {
1387+ let checkAddress = if ((addressFromString(addressStr) == unit))
1388+ then throw("wrong address")
1389+ else true
1390+ if ((checkAddress == checkAddress))
1391+ then {
1392+ let pmt = i.payments[0]
1393+ if ((value(pmt.assetId) != fromBase58String(tryGetString("static_poolToken_idStr"))))
1394+ then throw("wrong asset attached")
1395+ else {
1396+ let wavesClaimOut = getWavesClaimAmount(addressFromStringValue(addressStr))
1397+ let stakeActions = indexStakeResult(addressStr, pmt.amount)
1398+ (rebalanceLeaseActions(wavesClaimOut, getNodeAddress()) ++ stakeActions)
1399+ }
1400+ }
1401+ else throw("Strict value is not equal to itself.")
1402+ }
1403+ else throw("Strict value is not equal to itself.")
1404+ }
1405+ else throw("Strict value is not equal to itself.")
1406+ }
1407+
1408+
1409+
1410+@Callable(i)
1411+func unstakeIndex (indexAmount) = {
1412+ func issueIndex () = {
1413+ let issue = Issue(("PR " + tryGetString("static_poolDomain")), "Puzzle Range Index", tryGetInteger("global_poolToken_amount"), PoolTokenDecimals, true, unit, 0)
1414+ let poolTokenIdStr = toBase58String(calculateAssetId(issue))
1415+ $Tuple2([issue, StringEntry("static_poolToken_idStr", poolTokenIdStr)], poolTokenIdStr)
1416+ }
1417+
1418+ let _isValidAmount = if ((0 >= indexAmount))
1419+ then throw("amount should be positive")
1420+ else true
1421+ if ((_isValidAmount == _isValidAmount))
1422+ then {
1423+ let $t04230042466 = if ((tryGetString("static_poolToken_idStr") == ""))
1424+ then issueIndex()
1425+ else $Tuple2(nil, tryGetString("static_poolToken_idStr"))
1426+ let poolTokenIssueResult = $t04230042466._1
1427+ let poolTokenIdStr = $t04230042466._2
1428+ let poolTokenId = fromBase58String(poolTokenIdStr)
1429+ let addressStr = toString(i.caller)
1430+ let indexAvailable = tryGetInteger((addressStr + "_indexStaked"))
1431+ if (isShutdown())
1432+ then throw("contract is on stop")
1433+ else if ((indexAmount > indexAvailable))
1434+ then throw("you don't have index tokens available")
1435+ else {
1436+ let wavesClaimOut = getWavesClaimAmount(addressFromStringValue(addressStr))
1437+ let claimActions = claimResult(addressFromStringValue(addressStr))._1
1438+ (((poolTokenIssueResult ++ rebalanceLeaseActions(wavesClaimOut, getNodeAddress())) ++ claimActions) ++ [IntegerEntry((addressStr + "_indexStaked"), (indexAvailable - indexAmount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - indexAmount)), ScriptTransfer(i.caller, indexAmount, poolTokenId)])
1439+ }
1440+ }
1441+ else throw("Strict value is not equal to itself.")
1442+ }
1443+
1444+
1445+
1446+@Callable(i)
1447+func claimIndexRewards () = if (isShutdown())
1448+ then throw("contract is on stop")
1449+ else {
1450+ let wavesClaimOut = getWavesClaimAmount(i.caller)
1451+ let cr = claimResult(i.caller)
1452+ $Tuple2((rebalanceLeaseActions(wavesClaimOut, getNodeAddress()) ++ cr._1), cr._2)
1453+ }
1454+
1455+
1456+
1457+@Callable(i)
1458+func evaluateClaim (user) = $Tuple2(nil, claimQuote(addressFromStringValue(user)))
1459+
1460+
1461+
1462+@Callable(i)
1463+func addInterestExternal () = {
1464+ let _isShutdown = if (isShutdown())
1465+ then throw("contract is on stop")
1466+ else false
1467+ if ((_isShutdown == _isShutdown))
1468+ then {
1469+ let assetId = value(i.payments[0]).assetId
1470+ let assetIdStr = getAssetString(assetId)
1471+ let amount = i.payments[0].amount
1472+ let stakeTx = stakeIfNeeded(assetIdStr, amount)
1473+ if ((stakeTx == stakeTx))
1474+ then if ((indexOf(assetIds, assetId) == unit))
1475+ then throw("you can only add interest for assets in the pool")
1476+ else {
1477+ let params = loadGlobalTokenParams(assetIdStr)
1478+ let interestDelta = calcInterestChange(assetIdStr, amount)
1479+ let updParams = $Tuple8(params._1, params._2, params._3, (params._4 + interestDelta), (params._5 + amount), params._6, params._7, params._8)
1480+[saveGlobalTokenParams(assetIdStr, updParams)]
1481+ }
1482+ else throw("Strict value is not equal to itself.")
1483+ }
1484+ else throw("Strict value is not equal to itself.")
1485+ }
1486+
1487+
1488+
1489+@Callable(i)
1490+func notifyStakingPayment (assetIdStr,amount) = {
1491+ let _isShutdown = if (isShutdown())
1492+ then throw("contract is on stop")
1493+ else false
1494+ if ((_isShutdown == _isShutdown))
1495+ then {
1496+ let checkAmount = if ((0 >= amount))
1497+ then throw("amount should be positive")
1498+ else true
1499+ if ((checkAmount == checkAmount))
1500+ then {
1501+ let assetId = getAssetBytes(assetIdStr)
1502+ if ((indexOf(assetIds, assetId) == unit))
1503+ then throw("you can only add interest for assets in the pool")
1504+ else if ((tryGetString(("static_stakingContract_" + assetIdStr)) != toString(i.caller)))
1505+ then throw("can only be invoked by staker contract")
1506+ else {
1507+ let params = loadGlobalTokenParams(assetIdStr)
1508+ let interestDelta = calcInterestChange(assetIdStr, amount)
1509+ let updParams = $Tuple8(params._1, params._2, params._3, (params._4 + interestDelta), (params._5 + amount), params._6, params._7, params._8)
1510+[saveGlobalTokenParams(assetIdStr, updParams)]
1511+ }
1512+ }
1513+ else throw("Strict value is not equal to itself.")
1514+ }
1515+ else throw("Strict value is not equal to itself.")
1516+ }
1517+
1518+
1519+
1520+@Callable(i)
1521+func swap (assetOut,minimum) = {
1522+ let pmt = if ((size(i.payments) == 1))
1523+ then value(i.payments[0])
1524+ else throw("please attach exactly one payment")
1525+ let AmountIn = value(i.payments[0].amount)
1526+ let AssetIn = pmt.assetId
1527+ let AssetOut = getAssetBytes(assetOut)
1528+ let assetIn = getAssetString(AssetIn)
1529+ let scaleIn = (Scale8 / tryGetInteger((("static_" + assetIn) + "_scale")))
1530+ let scaleOut = (Scale8 / tryGetInteger((("static_" + assetOut) + "_scale")))
1531+ let assetInParams = loadGlobalTokenParams(getAssetString(AssetIn))
1532+ let assetOutParams = loadGlobalTokenParams(assetOut)
1533+ let AssetInBalance = assetInParams._1
1534+ let AssetInFactBalance = assetInParams._2
1535+ let assetInFeesEarned = assetInParams._3
1536+ let assetInLastCheckInterest = assetInParams._4
1537+ let AssetOutBalance = assetOutParams._1
1538+ let assetOutFactBalance = assetOutParams._2
1539+ let AssetInBalanceScaled = (AssetInBalance * scaleIn)
1540+ let AssetOutBalanceScaled = (AssetOutBalance * scaleOut)
1541+ let feeAmountIn = fraction(AmountIn, Fee, FeeScale, CEILING)
1542+ let cleanAmountIn = (AmountIn - feeAmountIn)
1543+ let cleanAmountInScaled = (cleanAmountIn * scaleIn)
1544+ let AmountOut1 = calculateOutAmount(cleanAmountInScaled, AssetIn, AssetOut, AssetInBalanceScaled, AssetOutBalanceScaled)
1545+ let AmountOut = fraction(AmountOut1, 1, scaleOut)
1546+ let AssetOutBalance2 = (AssetOutBalance - AmountOut)
1547+ let AssetInBalance2 = (AssetInBalance + cleanAmountIn)
1548+ if ((0 >= AmountOut))
1549+ then throw("amount out should be positive")
1550+ else if ((minimum > AmountOut))
1551+ then throw("amount to recieve is lower than given one")
1552+ else if ((AssetOut == AssetIn))
1553+ then throw("this swap is not allowed")
1554+ else if ((0 > (assetOutFactBalance - AmountOut)))
1555+ then throw("contract is out of reserves")
1556+ else if (isShutdown())
1557+ then throw("contract is on stop")
1558+ else if (valueOrElse(getBoolean(poolsHubAddress, ("global_shutdownIn_" + assetIn)), false))
1559+ then throw("token IN trades are stopped")
1560+ else if (valueOrElse(getBoolean(poolsHubAddress, ("global_shutdownOut_" + assetOut)), false))
1561+ then throw("token OUT trades are stopped")
1562+ else {
1563+ let protocolFee = fraction(feeAmountIn, 5, 10)
1564+ let lpFee = (feeAmountIn - protocolFee)
1565+ let interestDelta = calcInterestChange(assetIn, lpFee)
1566+ let stakeTx = stakeIfNeeded(assetIn, (cleanAmountIn + lpFee))
1567+ if ((stakeTx == stakeTx))
1568+ then {
1569+ let unstakeTx = unstakeIfNeeded(assetOut, AmountOut)
1570+ if ((unstakeTx == unstakeTx))
1571+ then {
1572+ let newBalanceIn = AssetInBalance2
1573+ let newBalanceOut = AssetOutBalance2
1574+ let assetInSelloffData = updSelloffData(assetIn, cleanAmountIn, AssetInBalance, $Tuple3(assetInParams._6, assetInParams._7, assetInParams._8))
1575+ let assetOutSelloffData = updSelloffData(assetOut, -(AmountOut), AssetOutBalance, $Tuple3(assetOutParams._6, assetOutParams._7, assetOutParams._8))
1576+ let assetInFinalParams = $Tuple8(newBalanceIn, (AssetInFactBalance + cleanAmountIn), (assetInFeesEarned + lpFee), (assetInLastCheckInterest + interestDelta), assetInParams._5, assetInSelloffData._1, assetInSelloffData._2, assetInSelloffData._3)
1577+ let assetOutFinalParams = $Tuple8(newBalanceOut, (assetOutFactBalance - AmountOut), assetOutParams._3, assetOutParams._4, assetOutParams._5, assetOutSelloffData._1, assetOutSelloffData._2, assetOutSelloffData._3)
1578+ let assetInChange = saveGlobalTokenParams(assetIn, assetInFinalParams)
1579+ let assetOutChange = saveGlobalTokenParams(assetOut, assetOutFinalParams)
1580+ let feeAssetStr = tryGetString("static_feeToken")
1581+ let feeAssetParams = loadGlobalTokenParams(feeAssetStr)
1582+ let feeTokenBalance = feeAssetParams._1
1583+ let volumeUsdUpdate = calculateUsdValue(AssetIn, AmountIn, AssetInBalance, feeTokenBalance)
1584+ let wavesOut = ((if ((AssetOut == unit))
1585+ then AmountOut
1586+ else 0) + (if ((AssetIn == unit))
1587+ then protocolFee
1588+ else 0))
1589+ let shouldRebalanceLease = if ((AssetIn == unit))
1590+ then true
1591+ else (AssetOut == unit)
1592+ let leaseActions = if (shouldRebalanceLease)
1593+ then rebalanceLeaseActions(wavesOut, getNodeAddress())
1594+ else nil
1595+ $Tuple2((leaseActions ++ [assetInChange, assetOutChange, ScriptTransfer(i.caller, AmountOut, AssetOut), IntegerEntry("global_volume_usd", (tryGetInteger("global_volume_usd") + volumeUsdUpdate)), ScriptTransfer(feesAddress, protocolFee, getAssetBytes(assetIn))]), AmountOut)
1596+ }
1597+ else throw("Strict value is not equal to itself.")
1598+ }
1599+ else throw("Strict value is not equal to itself.")
1600+ }
1601+ }
1602+
1603+
1604+
1605+@Callable(i)
1606+func swapReadOnly (assetIn,assetOut,AmountIn) = {
1607+ let AssetIn = getAssetBytes(assetIn)
1608+ let AssetOut = getAssetBytes(assetOut)
1609+ let scaleIn = (Scale8 / tryGetInteger((("static_" + assetIn) + "_scale")))
1610+ let scaleOut = (Scale8 / tryGetInteger((("static_" + assetOut) + "_scale")))
1611+ let feeAssetOutStr = tryGetString("static_feeToken")
1612+ let feeAssetOut = if ((feeAssetOutStr == ""))
1613+ then usdnAssetId
1614+ else getAssetBytes(feeAssetOutStr)
1615+ let assetInParams = loadGlobalTokenParams(getAssetString(AssetIn))
1616+ let assetOutParams = loadGlobalTokenParams(assetOut)
1617+ let AssetInBalance = assetInParams._1
1618+ let AssetInFactBalance = assetInParams._2
1619+ let assetInFeesEarned = assetInParams._3
1620+ let assetInLastCheckInterest = assetInParams._4
1621+ let AssetOutBalance = assetOutParams._1
1622+ let assetOutFactBalance = assetOutParams._2
1623+ let AssetInBalanceScaled = (AssetInBalance * scaleIn)
1624+ let AssetOutBalanceScaled = (AssetOutBalance * scaleOut)
1625+ let feeAmountIn = fraction(AmountIn, Fee, FeeScale, CEILING)
1626+ let cleanAmountIn = (AmountIn - feeAmountIn)
1627+ let cleanAmountInScaled = (cleanAmountIn * scaleIn)
1628+ let AmountOut1 = calculateOutAmount(cleanAmountInScaled, AssetIn, AssetOut, AssetInBalanceScaled, AssetOutBalanceScaled)
1629+ let AmountOut = fraction(AmountOut1, 1, scaleOut)
1630+ let AssetOutBalance2 = (AssetOutBalance - AmountOut)
1631+ let AssetInBalance2 = (AssetInBalance + cleanAmountIn)
1632+ if ((0 >= AmountOut))
1633+ then throw("amount out should be positive")
1634+ else if ((AssetOut == AssetIn))
1635+ then throw("this swap is not allowed")
1636+ else if ((0 > (assetOutParams._2 - AmountOut)))
1637+ then throw("contract is out of reserves")
1638+ else if (isShutdown())
1639+ then throw("contract is on stop")
1640+ else if (valueOrElse(getBoolean(poolsHubAddress, ("global_shutdownIn_" + assetIn)), false))
1641+ then throw("token IN trades are stopped")
1642+ else if (valueOrElse(getBoolean(poolsHubAddress, ("global_shutdownOut_" + assetOut)), false))
1643+ then throw("token OUT trades are stopped")
1644+ else $Tuple2(nil, AmountOut)
1645+ }
1646+
1647+
1648+
1649+@Callable(i)
1650+func transferOwnership (newOwnerAddress) = {
1651+ let _isShutdown = if (isShutdown())
1652+ then throw("contract is on stop")
1653+ else false
1654+ if ((_isShutdown == _isShutdown))
1655+ then if ((toString(i.caller) != tryGetString("static_poolOwner")))
1656+ then throw("this call available only for pool owner")
1657+ else if ((addressFromString(newOwnerAddress) == unit))
1658+ then throw("invalid address")
1659+ else [StringEntry("static_poolOwner", newOwnerAddress)]
1660+ else throw("Strict value is not equal to itself.")
1661+ }
1662+
1663+
1664+
1665+@Callable(i)
1666+func setFee (newFee) = {
1667+ let _isValidFee = if (if ((0 > newFee))
1668+ then true
1669+ else (newFee > 1000))
1670+ then throw("fee can't be negative or greater than 1000")
1671+ else true
1672+ if ((_isValidFee == _isValidFee))
1673+ then if ((toString(i.caller) != tryGetString("static_poolOwner")))
1674+ then throw("this call available only for pool owner")
1675+ else [IntegerEntry("static_fee", newFee)]
1676+ else throw("Strict value is not equal to itself.")
1677+ }
1678+
1679+
1680+@Verifier(tx)
1681+func verify () = if (if ((valueOrElse(getInteger("global_wasPreInited"), 0) == 0))
1682+ then if (sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey))
1683+ then true
1684+ else sigVerify(tx.bodyBytes, tx.proofs[0], masterPubKey)
1685+ else false)
1686+ then true
1687+ else {
1688+ let _multisigStr = "3PJdVErH5VmVYvkuN3Ayrrtd1zCZ4Xru6gT"
1689+ let multisigStr = valueOrElse(getString(this, "APPROVER_ADDRESS"), _multisigStr)
1690+ let multisigAddress = addressFromString(multisigStr)
1691+ let multisigOk = match multisigAddress {
1692+ case t: Address =>
1693+ true
1694+ case _ =>
1695+ false
1696+ }
1697+ let isInited = if (multisigOk)
1698+ then valueOrElse(getBoolean(value(multisigAddress), "INITED"), false)
1699+ else false
1700+ let hasAdmins = if (multisigOk)
1701+ then (valueOrElse(getString(value(multisigAddress), "ADMINS_PBKS"), "") != "")
1702+ else false
1703+ if (if (if (multisigOk)
1704+ then isInited
1705+ else false)
1706+ then hasAdmins
1707+ else false)
1708+ then match tx {
1709+ case ttx: SetScriptTransaction =>
1710+ match ttx.script {
1711+ case script: ByteVector =>
1712+ let scriptHasha = toBase58String(blake2b256(script))
1713+ let validFrom = valueOrErrorMessage(getInteger(value(multisigAddress), (((("script%%" + CONTRACT_TYPE) + "%%") + scriptHasha) + "%%validFrom")), "validFrom not set")
1714+ let validTo = valueOrErrorMessage(getInteger(value(multisigAddress), (((("script%%" + CONTRACT_TYPE) + "%%") + scriptHasha) + "%%validTo")), "validTo not set")
1715+ if ((height >= validFrom))
1716+ then (validTo >= height)
1717+ else false
1718+ case _ =>
1719+ false
1720+ }
1721+ case otx =>
1722+ let taskId = ((("tx_" + toString(this)) + "_") + toBase58String(otx.id))
1723+ let isApproved = valueOrElse(getBoolean(value(multisigAddress), (((toString(this) + "_") + toBase58String(otx.id)) + "__approved")), false)
1724+ let approvedFrom = valueOrElse(getInteger(value(multisigAddress), (taskId + "__approvedFrom")), 0)
1725+ if (isApproved)
1726+ then (height >= approvedFrom)
1727+ else false
1728+ }
1729+ else match tx {
1730+ case ttx: SetScriptTransaction =>
1731+ if (sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey))
1732+ then true
1733+ else sigVerify(ttx.bodyBytes, ttx.proofs[0], masterPubKey)
1734+ case _ =>
1735+ false
1736+ }
1737+ }
1738+

github/deemru/w8io
84.65 ms