tx · 2d4D4AP5jC9T68XZuXrtBseyi4VUAX5XxhcYVsHNcmTa

3M8Mh4jy6rphazaiK4BhzU5WjUTa3Kd2fpD:  -0.06450000 Waves

2025.10.19 18:52 [506897] smart account 3M8Mh4jy6rphazaiK4BhzU5WjUTa3Kd2fpD > SELF 0.00000000 Waves

{ "type": 13, "id": "2d4D4AP5jC9T68XZuXrtBseyi4VUAX5XxhcYVsHNcmTa", "fee": 6450000, "feeAssetId": null, "timestamp": 1760889153783, "version": 2, "chainId": 82, "sender": "3M8Mh4jy6rphazaiK4BhzU5WjUTa3Kd2fpD", "senderPublicKey": "6JTTZL4qHWZB1X52JVRr7h8AiTmGYyqE7gXSpQLktTcR", "proofs": [ "4FWGUtH8NZiLs6GaSuxQMM9PP75m8jDyiuzFst7TkpiZT7Enkz6KaJfxkKB117tYBUpYGeiNGgbiG2HRH3jYoCGv" ], "script": "base64:BgJcCAISBAoCCAgSCQoHCAgICAgIARIAEgkKBwgICAgIAQgSAwoBBBIDCgEBEgASAwoBCBIDCgEBEgASAwoBCBIAEgQKAggBEgQKAggBEgUKAwgIARIDCgEIEgMKAQFmAAdWRVJTSU9OAhZQWi0zLjYuMSBQUk9ELXJlZmFjdG9yAAljb25maWdTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwINY29uZmlnQWRkcmVzcwIjM1BNb0VpYmRMZVdxY1VSUTgzNTFYaGFXd3lhY0RjN0c0ZTUADkNPTkZJR19BRERSRVNTAwkAAAIFCWNvbmZpZ1N0cgIABQR0aGlzCQEHQWRkcmVzcwEJANkEAQUJY29uZmlnU3RyABVBc3NldHNXZWlnaHRzRGVjaW1hbHMABAAFU2NhbGUAkE4ABlNjYWxlOACAwtcvAAlTY2FsZThfQkkJALYCAQUGU2NhbGU4AAdTY2FsZTEyAICglKWNHQAHU2NhbGUxNgCAgIT+pt7hEQAKU2NhbGUxNl9CSQkAtgIBBQdTY2FsZTE2AAhGZWVTY2FsZQCQTgARUG9vbFRva2VuRGVjaW1hbHMACAAOUG9vbFRva2VuU2NhbGUJAGwGAAoAAAURUG9vbFRva2VuRGVjaW1hbHMAAAAABQZIQUxGVVAAEE1JTl9TVEVQU19BTU9VTlQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOQ09ORklHX0FERFJFU1MCEG1pbl9zdGVwc19hbW91bnQAAQAQTUFYX1NURVBTX0FNT1VOVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5DT05GSUdfQUREUkVTUwIQbWF4X3N0ZXBzX2Ftb3VudAD0AwASTUlOX1NURVBTX0lOVEVSVkFMCQELdmFsdWVPckVsc2UCCQCaCAIFDkNPTkZJR19BRERSRVNTAhJtaW5fc3RlcHNfaW50ZXJ2YWwAAQASTUFYX1NURVBTX0lOVEVSVkFMCQELdmFsdWVPckVsc2UCCQCaCAIFDkNPTkZJR19BRERSRVNTAhJtYXhfc3RlcHNfaW50ZXJ2YWwAkE4ACk1JTl9XRUlHSFQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOQ09ORklHX0FERFJFU1MCCm1pbl93ZWlnaHQAZAAKTUFYX1dFSUdIVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5DT05GSUdfQUREUkVTUwIKbWF4X3dlaWdodACsTQENdHJ5R2V0SW50ZWdlcgEDa2V5BAckbWF0Y2gwCQCaCAIFBHRoaXMFA2tleQMJAAECBQckbWF0Y2gwAgNJbnQEAWIFByRtYXRjaDAFAWIAAAEMdHJ5R2V0QmluYXJ5AQNrZXkEByRtYXRjaDAJAJwIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWIFByRtYXRjaDAFAWIBAAEMdHJ5R2V0U3RyaW5nAQNrZXkEByRtYXRjaDAJAJ0IAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQBYgUHJG1hdGNoMAUBYgIAARN0cnlHZXRTdHJpbmdPclRocm93AQNrZXkEByRtYXRjaDAJAJ0IAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQBYgUHJG1hdGNoMAUBYgkAAgEJAKwCAgIdbm8gc3VjaCBrZXkgaW4gZGF0YSBzdG9yYWdlOiAFA2tleQEOZ2V0QXNzZXRTdHJpbmcBB2Fzc2V0SWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYgUHJG1hdGNoMAkA2AQBBQFiAgVXQVZFUwENZ2V0QXNzZXRCeXRlcwEKYXNzZXRJZFN0cgMJAAACBQphc3NldElkU3RyAgVXQVZFUwUEdW5pdAkA2QQBBQphc3NldElkU3RyAQ9nZXRUb2tlbkJhbGFuY2UBB2Fzc2V0SWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBdAUHJG1hdGNoMAkA8AcCBQR0aGlzBQF0CAkA7wcBBQR0aGlzCWF2YWlsYWJsZQETYWRkQXNzZXRCeXRlc1RvTGlzdAIFYWNjdW0EaXRlbQkAzggCBQVhY2N1bQkAzAgCCQENZ2V0QXNzZXRCeXRlcwEFBGl0ZW0FA25pbAEUYWRkQXNzZXRXZWlnaHRUb0xpc3QCBWFjY3VtBGl0ZW0JAM4IAgUFYWNjdW0JAMwIAgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwkBDmdldEFzc2V0U3RyaW5nAQUEaXRlbQIHX3dlaWdodAUDbmlsARdhZGRBc3NldFdlaWdodFRvU3RyTGlzdAIFYWNjdW0EaXRlbQkAzggCBQVhY2N1bQkAzAgCCQCkAwEJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FBGl0ZW0CB193ZWlnaHQFA25pbAEWYWRkQXNzZXREZWNpbWFsc1RvTGlzdAIFYWNjdW0EaXRlbQkAzggCBQVhY2N1bQkAzAgCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfCQEOZ2V0QXNzZXRTdHJpbmcBBQRpdGVtAglfZGVjaW1hbHMFA25pbAETYWRkQXNzZXRTY2FsZVRvTGlzdAIFYWNjdW0EaXRlbQkAzggCBQVhY2N1bQkAzAgCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfCQEOZ2V0QXNzZXRTdHJpbmcBBQRpdGVtAgZfc2NhbGUFA25pbAEMYWRkSW50VG9MaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAQ1wYXJzZUludFZhbHVlAQUEaXRlbQUDbmlsARFwYXJzdFN0clRvSW50TGlzdAEBcwoBAWYCBWFjY3VtBG5leHQJAM4IAgUFYWNjdW0JAMwIAgkBDXBhcnNlSW50VmFsdWUBBQRuZXh0BQNuaWwKAAIkbAkAtQkCBQFzAgEsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAA51c2RuQXNzZXRJZFN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIOdXNkbkFzc2V0SWRTdHICLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwABBwdXp6bGVBc3NldElkU3RyCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAhBwdXp6bGVBc3NldElkU3RyAixIRUI4UWF3OXhyV3BXczh0SHNpQVRZR0JXREJ0UDJTN2tjUEFMck11NDNBUwAOdXNkdEFzc2V0SWRTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDnVzZHRBc3NldElkU3RyAiwzNE45WWNFRVRMV245M3FZUTY0RXNQMXg4OXRTcnVKVTQ0UnJFTVNYWEVQSgARdXNkdFBwdEFzc2V0SWRTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCEXVzZHRQcHRBc3NldElkU3RyAiw5d2MzTFhOQTRURUJzWHlLdG9MRTltcmJERDdXTUhYdlhyQ2padmFiTEFzaQAOcm9tZUFzc2V0SWRTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDnJvbWVBc3NldElkU3RyAixBUDRDYjV4TFlHSDZaaWdIcmVDWkhvWHBRVFdEa1BzRzJCSHFmRFV4NnRhSgAPd2F2ZXNBc3NldElkU3RyAgVXQVZFUwALdXNkbkFzc2V0SWQJANkEAQUOdXNkbkFzc2V0SWRTdHIADXB1enpsZUFzc2V0SWQJANkEAQUQcHV6emxlQXNzZXRJZFN0cgALdXNkdEFzc2V0SWQJANkEAQUOdXNkdEFzc2V0SWRTdHIADnVzZHRQcHRBc3NldElkCQDZBAEFEXVzZHRQcHRBc3NldElkU3RyAAtyb21lQXNzZXRJZAkA2QQBBQ5yb21lQXNzZXRJZFN0cgAMd2F2ZXNBc3NldElkBQR1bml0ABVzdXBwb3J0ZWRGZWVBc3NldHNTdHIJAMwIAgUOdXNkbkFzc2V0SWRTdHIJAMwIAgUQcHV6emxlQXNzZXRJZFN0cgkAzAgCBQ51c2R0QXNzZXRJZFN0cgkAzAgCBRF1c2R0UHB0QXNzZXRJZFN0cgkAzAgCBQ93YXZlc0Fzc2V0SWRTdHIJAMwIAgUOcm9tZUFzc2V0SWRTdHIFA25pbAARcGFyZW50UG9vbEFkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAhFwYXJlbnRQb29sQWRkcmVzcwIjM1BGRGd6dTFVdHN3QWtDTXhxcVFqYlRlSGFYNGNNYWI4S2gADW1hc3RlckFkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg1tYXN0ZXJBZGRyZXNzAiMzUExqd0hjejlORXVhVG82M05aUjlCOW9rUWlLUXhaU2JtZgAMbWFzdGVyUHViS2V5CQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDG1hc3RlclB1YktleQIsMmpUSkdxSFNvcHlqNWQxY2piVWU2ZjJqWHFHTUhFNDEyY3kzdkd3WW9SYlAADW9yYWNsZUFkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg1vcmFjbGVBZGRyZXNzAiMzUDhkMUUxQkxLb0Q1MnkzYlFKMWJEVGQyVEQxZ3BhTG45dAAOc3Rha2luZ0FkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg5zdGFraW5nQWRkcmVzcwIjM1BGVGJ5d3F4dEZmdWtYM0h5VDg4MWc0aVc1SzRRTDNGQVMAC2ZlZXNBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwILZmVlc0FkZHJlc3MCIzNQRldBVkttWGpmSFh5ekpiMTJqQ2JoUDRVaGk5dDR1V2lEAA9wb29sc0h1YkFkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg9wb29sc0h1YkFkZHJlc3MCIzNQNVJHWXlDbkVMRjhKVFB4Z1g1NGRCR3p3a1FNS1VKNUg3ABJzaHV0ZG93bkFkZHJlc3NTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCD3NodXRkb3duQWRkcmVzcwIjM1BFcHY5aFJGV0VFQlUyMldSbkxzdzFiSDRZR3RjVTcyOG8AD2xheWVyMkFkZHJlc3NlcwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIPbGF5ZXIyQWRkcmVzc2VzAkczUFIxUXZpOW1IVDM1U3dXRWtMU3FxRTJMOHRoaVBMZFZXVSwzUFFvQmZVS0hrSkFlR1dob29MUDdXUzhvdmI1NGF2OUpwMgAKZ292QWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCCmdvdkFkZHJlc3MCIzNQNnVybzl4Q3NFOHRlNzhRWmp6cXk3YXE4bmF0U3pkY2VDABFjb2xkTWFzdGVyQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCEWNvbGRNYXN0ZXJBZGRyZXNzAiMzUEs5bmhQZlBiTUJ5Z0I5WmdIVk1IYVFiU29vandyQmZ4agABVAkBDXRyeUdldEludGVnZXIBAhNzdGF0aWNfdG9rZW5zQW1vdW50AAhhc3NldElkcwoAAiRsCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfdG9rZW5JZHMCASwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBE2FkZEFzc2V0Qnl0ZXNUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoADUFzc2V0c1dlaWdodHMKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBFGFkZEFzc2V0V2VpZ2h0VG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMV8yAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAhEZWNpbWFscwoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMl8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEWYWRkQXNzZXREZWNpbWFsc1RvTGlzdAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMl8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjJfMgIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgAGU2NhbGVzCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYzXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARNhZGRBc3NldFNjYWxlVG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYzXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmM18yAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAANGZWUJAQ10cnlHZXRJbnRlZ2VyAQIKc3RhdGljX2ZlZQAMZWFybmVkQXNzZXRzBQhhc3NldElkcwEEX2dldAIHYXNzZXRJZAVwYXJhbQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgkArAICAgdnbG9iYWxfBQdhc3NldElkAgFfBQVwYXJhbQEPX2dldF9mZWVzRWFybmVkAQdhc3NldElkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgISZ2xvYmFsX2ZlZXNFYXJuZWRfBQdhc3NldElkARdfZ2V0X2xhc3RDaGVja19pbnRlcmVzdAEHYXNzZXRJZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIRZ2xvYmFsX2xhc3RDaGVja18FB2Fzc2V0SWQCCV9pbnRlcmVzdAEQX2dldF9leHRyYUVhcm5lZAEHYXNzZXRJZAkBDXRyeUdldEludGVnZXIBCQCsAgICE2dsb2JhbF9leHRyYUVhcm5lZF8FB2Fzc2V0SWQBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEHYXNzZXRJZAQHJG1hdGNoMAkAoggBCQCsAgICDWdsb2JhbFBhcmFtc18FB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFwBQckbWF0Y2gwBAZwYXJhbXMJALUJAgUBcAICX18JAJoKCAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnBhcmFtcwAACQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcGFyYW1zAAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZwYXJhbXMAAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnBhcmFtcwADCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcGFyYW1zAAQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZwYXJhbXMABQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnBhcmFtcwAGCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcGFyYW1zAAcJAJoKCAkBBF9nZXQCBQdhc3NldElkAgdiYWxhbmNlCQEEX2dldAIFB2Fzc2V0SWQCC2ZhY3RCYWxhbmNlCQEPX2dldF9mZWVzRWFybmVkAQUHYXNzZXRJZAkBF19nZXRfbGFzdENoZWNrX2ludGVyZXN0AQUHYXNzZXRJZAkBEF9nZXRfZXh0cmFFYXJuZWQBBQdhc3NldElkCQEEX2dldAIFB2Fzc2V0SWQCB3NlbGxvZmYJAQRfZ2V0AgUHYXNzZXRJZAITc2VsbG9mZlN0YXJ0QmFsYW5jZQkBBF9nZXQCBQdhc3NldElkAhJzZWxsb2ZmU3RhcnRIZWlnaHQBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIHYXNzZXRJZAZwYXJhbXMJAQtTdHJpbmdFbnRyeQIJAKwCAgINZ2xvYmFsUGFyYW1zXwUHYXNzZXRJZAkAuQkCCQDMCAIJAKQDAQgFBnBhcmFtcwJfMQkAzAgCCQCkAwEIBQZwYXJhbXMCXzIJAMwIAgkApAMBCAUGcGFyYW1zAl8zCQDMCAIJAKQDAQgFBnBhcmFtcwJfNAkAzAgCCQCkAwEIBQZwYXJhbXMCXzUJAMwIAgkApAMBCAUGcGFyYW1zAl82CQDMCAIJAKQDAQgFBnBhcmFtcwJfNwkAzAgCCQCkAwEIBQZwYXJhbXMCXzgFA25pbAICX18BCmlzU2h1dGRvd24ABA9zaHV0ZG93bkFkZHJlc3MJAKYIAQUSc2h1dGRvd25BZGRyZXNzU3RyAwkAAAIFD3NodXRkb3duQWRkcmVzcwUEdW5pdAcEByRtYXRjaDAJAJsIAgkBBXZhbHVlAQUPc2h1dGRvd25BZGRyZXNzAgtpc19zaHV0ZG93bgMJAAECBQckbWF0Y2gwAgdCb29sZWFuBAF4BQckbWF0Y2gwBQF4BwEOZ2V0RmFjdEJhbGFuY2UBCmFzc2V0SWRTdHIEC2Fzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKYXNzZXRJZFN0cggFC2Fzc2V0UGFyYW1zAl8yARZnZXRDdXJyZW50VG9rZW5CYWxhbmNlAQh0b2tlbk51bQQKdG9rZW5JZFN0cgkBDmdldEFzc2V0U3RyaW5nAQkAkQMCBQhhc3NldElkcwUIdG9rZW5OdW0EC3Rva2VuUGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKdG9rZW5JZFN0cggFC3Rva2VuUGFyYW1zAl8xAQ1zdGFrZUlmTmVlZGVkAgphc3NldElkU3RyBmFtb3VudAQHc3Rha2VUeAMJAQIhPQIJAQx0cnlHZXRTdHJpbmcBCQCsAgICF3N0YXRpY19zdGFraW5nQ29udHJhY3RfBQphc3NldElkU3RyAgAJAPwHBAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDHRyeUdldFN0cmluZwEJAKwCAgIXc3RhdGljX3N0YWtpbmdDb250cmFjdF8FCmFzc2V0SWRTdHICBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ1nZXRBc3NldEJ5dGVzAQUKYXNzZXRJZFN0cgUGYW1vdW50BQNuaWwFBHVuaXQDCQAAAgUHc3Rha2VUeAUHc3Rha2VUeAYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BD3Vuc3Rha2VJZk5lZWRlZAIKYXNzZXRJZFN0cgZhbW91bnQECXVuc3Rha2VUeAMJAQIhPQIJAQx0cnlHZXRTdHJpbmcBCQCsAgICF3N0YXRpY19zdGFraW5nQ29udHJhY3RfBQphc3NldElkU3RyAgAJAPwHBAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDHRyeUdldFN0cmluZwEJAKwCAgIXc3RhdGljX3N0YWtpbmdDb250cmFjdF8FCmFzc2V0SWRTdHICB3Vuc3Rha2UJAMwIAgUGYW1vdW50BQNuaWwFA25pbAUEdW5pdAMJAAACBQl1bnN0YWtlVHgFCXVuc3Rha2VUeAYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BEWJ1cm5JbmRleElmTmVlZGVkAQZhbW91bnQECmluZGV4SWRTdHIJAQx0cnlHZXRTdHJpbmcBAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyAwkAAAIFCmluZGV4SWRTdHICAAUDbmlsAwkAAAIJAOwHAQkA2QQBBQppbmRleElkU3RyBQR1bml0BQNuaWwJAMwIAgkBBEJ1cm4CCQDZBAEFCmluZGV4SWRTdHIFBmFtb3VudAUDbmlsARFtaW50SW5kZXhJZk5lZWRlZAEGYW1vdW50BAppbmRleElkU3RyCQEMdHJ5R2V0U3RyaW5nAQIWc3RhdGljX3Bvb2xUb2tlbl9pZFN0cgMJAAACBQppbmRleElkU3RyAgAFA25pbAMJAAACCQDsBwEJANkEAQUKaW5kZXhJZFN0cgUEdW5pdAUDbmlsCQDMCAIJAQdSZWlzc3VlAwkA2QQBBQppbmRleElkU3RyBQZhbW91bnQGBQNuaWwBCGdldEtNdWx0AAQHJG1hdGNoMAkAnwgBAgxzdGF0aWNfS011bHQDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4BQdTY2FsZTE2ARJzYXZlQ3VycmVudFdlaWdodHMABAphc3NldElkc0xpCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfdG9rZW5JZHMCASwKAQFzAgVhY2N1bQdhc3NldElkCQDOCAIFBWFjY3VtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICFnJlYmFsYW5jZV9zdGFydFdlaWdodF8FB2Fzc2V0SWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FB2Fzc2V0SWQCB193ZWlnaHQFA25pbAoAAiRsBQphc3NldElkc0xpCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAkAawMJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQJAQhnZXRLTXVsdAAFB1NjYWxlMTYBEGNhbGN1bGF0ZVBJc3N1ZWQCBmFtb3VudAd0b2tlbklkBAdQc3VwcGx5CQEZZ2V0VmlydHVhbFBvb2xUb2tlbkFtb3VudAAEB0JhbGFuY2UJAQ5nZXRGYWN0QmFsYW5jZQEJAQ5nZXRBc3NldFN0cmluZwEFB3Rva2VuSWQEAnQxCQBuBAUGYW1vdW50BQdQc3VwcGx5BQdCYWxhbmNlBQRET1dOBQJ0MQENZ2V0TWluUElzc3VlZAEIcGF5bWVudHMKAQdoYW5kbGVyAgVhY2N1bQdjdXJyZW50AwkAAAIJAQ5nZXRGYWN0QmFsYW5jZQEJAQ5nZXRBc3NldFN0cmluZwEIBQdjdXJyZW50B2Fzc2V0SWQAAAUFYWNjdW0EB1BJc3N1ZWQJARBjYWxjdWxhdGVQSXNzdWVkAggFB2N1cnJlbnQGYW1vdW50CAUHY3VycmVudAdhc3NldElkAwkAAAIFB1BJc3N1ZWQAAAkAAgECJG9uZSBvZiB0aGUgdG9rZW5zIGFtb3VudHMgaXMgdG9vIGxvdwMDCQAAAgUFYWNjdW0AAAYJAGYCBQVhY2N1bQUHUElzc3VlZAUHUElzc3VlZAUFYWNjdW0ECW1pblBJc3NlZAoAAiRsBQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgUJbWluUElzc2VkARJnZXRQcmljZUZyb21PcmFjbGUBCmFzc2V0SWRTdHIEByRtYXRjaDAJAJoIAgUNb3JhY2xlQWRkcmVzcwkArAICBQphc3NldElkU3RyAgdfdHdhcDVCAwkAAQIFByRtYXRjaDACA0ludAQBeAUHJG1hdGNoMAUBeAAAARFjYWxjdWxhdGVVc2RWYWx1ZQQHYXNzZXRJZAZhbW91bnQIYUJhbGFuY2UPZmVlQXNzZXRCYWxhbmNlBAthc3NldFdlaWdodAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAIHX3dlaWdodAQLZmVlQXNzZXRTdHIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfZmVlVG9rZW4EDWZlZUFzc2V0U2NhbGUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgkArAICAgdzdGF0aWNfBQtmZWVBc3NldFN0cgIGX3NjYWxlBAtmZWVBc3NldE51bQkBBXZhbHVlAQkAzwgCBQhhc3NldElkcwkBDWdldEFzc2V0Qnl0ZXMBBQtmZWVBc3NldFN0cgQOZmVlQXNzZXRXZWlnaHQJAJEDAgUNQXNzZXRzV2VpZ2h0cwULZmVlQXNzZXROdW0EB19hbW91bnQJALkCAgkAtgIBBQZhbW91bnQFCVNjYWxlOF9CSQQNX2ZlZUFzc2V0RGF0YQkAugICCQC2AgEFD2ZlZUFzc2V0QmFsYW5jZQkAtgIBBQ5mZWVBc3NldFdlaWdodAQKX2Fzc2V0RGF0YQkAvAIDCQC2AgEFCGFCYWxhbmNlBQlTY2FsZThfQkkJALYCAQULYXNzZXRXZWlnaHQEDXZhbEluRmVlQXNzZXQJAKADAQkAvAIDBQdfYW1vdW50BQ1fZmVlQXNzZXREYXRhBQpfYXNzZXREYXRhBA1mZWVBc3NldFByaWNlCQESZ2V0UHJpY2VGcm9tT3JhY2xlAQULZmVlQXNzZXRTdHIJAGsDBQ12YWxJbkZlZUFzc2V0BQ1mZWVBc3NldFByaWNlBQ1mZWVBc3NldFNjYWxlARRjYWxjQXZnQ29uY2VudHJhdGlvbgAKAQFmAgVhY2N1bQRuZXh0BAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBBQRuZXh0BAZ3ZWlnaHQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICB193ZWlnaHQEC2Fzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKYXNzZXRJZFN0cgQQYXNzZXRGYWN0QmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl8yBBBhc3NldFZpcnRCYWxhbmNlCAULYXNzZXRQYXJhbXMCXzEJAJQKAgkAZAIIBQVhY2N1bQJfMQkAawMFEGFzc2V0RmFjdEJhbGFuY2UFBndlaWdodAUQYXNzZXRWaXJ0QmFsYW5jZQkAZAIIBQVhY2N1bQJfMgUGd2VpZ2h0CgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCAAAAAAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEBZgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgETY2hlY2tUb2tlbnNWYWxpZGl0eQEIcGF5bWVudHMKAQhoYW5kbGVyMQIFYWNjdW0HcGF5bWVudAkAzggCBQVhY2N1bQkAzAgCCAUHcGF5bWVudAdhc3NldElkBQNuaWwEA2lkcwoAAiRsBQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIaGFuZGxlcjECBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoDCQAAAgUDaWRzBQNpZHMKAQhoYW5kbGVyMgIFYWNjdW0HYXNzZXRJZAMJAQIhPQIJAM8IAgUDaWRzBQdhc3NldElkBQR1bml0CQBkAgUFYWNjdW0AAQkAAgEJAKwCAgIUYXNzZXQgbm90IGF0dGFjaGVkOiAJAQ5nZXRBc3NldFN0cmluZwEFB2Fzc2V0SWQEBmNoZWNrcwoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmNV8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIaGFuZGxlcjICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjVfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY1XzICCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoDCQAAAgUGY2hlY2tzBQZjaGVja3MGCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuARNoYW5kbGVQb29sVG9rZW5zQWRkBAdQSXNzdWVkCHBheW1lbnRzC3VzZXJBZGRyZXNzCm5lZWRDaGFuZ2UKARVnZXRUb2tlblBheW1lbnRBbW91bnQBB3Rva2VuSWQKAQdoYW5kbGVyAgVhY2N1bQdwYXltZW50AwkAAAIIBQdwYXltZW50B2Fzc2V0SWQFB3Rva2VuSWQIBQdwYXltZW50BmFtb3VudAUFYWNjdW0KAAIkbAUIcGF5bWVudHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoKARFoYW5kbGVUb2tlbkNoYW5nZQIFYWNjdW0HdG9rZW5JZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAQLYXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQphc3NldElkU3RyBA1wYXltZW50QW1vdW50CQEVZ2V0VG9rZW5QYXltZW50QW1vdW50AQUHdG9rZW5JZAQCQmsIBQthc3NldFBhcmFtcwJfMgQHUFN1cHBseQkBGWdldFZpcnR1YWxQb29sVG9rZW5BbW91bnQABA10b2tlbkRlY2ltYWxzCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQphc3NldElkU3RyAgZfc2NhbGUEAmExCQC9AgQJALkCAgkAtgIBCQBkAgUHUFN1cHBseQUHUElzc3VlZAkAtgIBBQZTY2FsZTgJALYCAQUNdG9rZW5EZWNpbWFscwkAtgIBBQdQU3VwcGx5BQdDRUlMSU5HBAJEawkAoAMBCQC9AgQJALgCAgUCYTEJALkCAgkAtgIBBQ10b2tlbkRlY2ltYWxzCQC2AgEFBlNjYWxlOAkAtgIBBQJCawkAuQICCQC2AgEFDXRva2VuRGVjaW1hbHMJALYCAQUGU2NhbGU4BQdDRUlMSU5HBAh0b1JldHVybgkAZQIFDXBheW1lbnRBbW91bnQFAkRrBAdzdGFrZVR4CQENc3Rha2VJZk5lZWRlZAIFCmFzc2V0SWRTdHIFAkRrAwkAAAIFB3N0YWtlVHgFB3N0YWtlVHgEAXQDAwUKbmVlZENoYW5nZQkAZgIFCHRvUmV0dXJuAAAHCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzBQh0b1JldHVybgUHdG9rZW5JZAUDbmlsBQNuaWwEE3NlbGxvZmZTdGFydEJhbGFuY2UDCQECIT0CCAULYXNzZXRQYXJhbXMCXzgJAGgCCQBpAgUGaGVpZ2h0AGQAZAgFC2Fzc2V0UGFyYW1zAl83CQBrAwgFC2Fzc2V0UGFyYW1zAl83CQBkAgUHUFN1cHBseQUHUElzc3VlZAUHUFN1cHBseQQOYXNzZXRQYXJhbXNVcGQJAJoKCAkAbgQIBQthc3NldFBhcmFtcwJfMQkAZAIFB1BTdXBwbHkFB1BJc3N1ZWQFB1BTdXBwbHkFCEhBTEZFVkVOCQBkAggFC2Fzc2V0UGFyYW1zAl8yBQJEawgFC2Fzc2V0UGFyYW1zAl8zCAULYXNzZXRQYXJhbXMCXzQIBQthc3NldFBhcmFtcwJfNQgFC2Fzc2V0UGFyYW1zAl82BRNzZWxsb2ZmU3RhcnRCYWxhbmNlCAULYXNzZXRQYXJhbXMCXzgJAM4IAgkAzggCBQVhY2N1bQUBdAkAzAgCCQEVc2F2ZUdsb2JhbFRva2VuUGFyYW1zAgUKYXNzZXRJZFN0cgUOYXNzZXRQYXJhbXNVcGQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQERaGFuZGxlVG9rZW5DaGFuZ2UCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoBFmNhbGNNaW50ZWRXaXRoT25lVG9rZW4CD2Fzc2V0QWRkZWRJZFN0cgZhbW91bnQEB1BTdXBwbHkJARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAQLYXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQ9hc3NldEFkZGVkSWRTdHIEEGFzc2V0RmFjdEJhbGFuY2UIBQthc3NldFBhcmFtcwJfMgQQYXNzZXRWaXJ0QmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl8xBAthc3NldFdlaWdodAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUPYXNzZXRBZGRlZElkU3RyAgdfd2VpZ2h0BAphc3NldFNjYWxlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQ9hc3NldEFkZGVkSWRTdHICBl9zY2FsZQQNYXNzZXREZWNpbWFscwkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUPYXNzZXRBZGRlZElkU3RyAglfZGVjaW1hbHMEE1BJc3N1ZWROb011bHRpcGxpZXIJAGsDBQdQU3VwcGx5CQBlAgkAoAMBCQB2BgkAtgIBCQBkAgUKYXNzZXRTY2FsZQkAawMFBmFtb3VudAUKYXNzZXRTY2FsZQUQYXNzZXRWaXJ0QmFsYW5jZQUNYXNzZXREZWNpbWFscwkAtgIBBQthc3NldFdlaWdodAAEAAgFBERPV04FBlNjYWxlOAUGU2NhbGU4BAdhdmdDb25jCQEUY2FsY0F2Z0NvbmNlbnRyYXRpb24ABAdQSXNzdWVkCQBrAwUTUElzc3VlZE5vTXVsdGlwbGllcggFB2F2Z0NvbmMCXzIIBQdhdmdDb25jAl8xBA5hc3NldFBhcmFtc1VwZAkAmgoICQBkAgUQYXNzZXRWaXJ0QmFsYW5jZQUGYW1vdW50CQBkAgUQYXNzZXRGYWN0QmFsYW5jZQUGYW1vdW50CAULYXNzZXRQYXJhbXMCXzMIBQthc3NldFBhcmFtcwJfNAgFC2Fzc2V0UGFyYW1zAl81CAULYXNzZXRQYXJhbXMCXzYIBQthc3NldFBhcmFtcwJfNwgFC2Fzc2V0UGFyYW1zAl84CQCUCgIJAMwIAgkBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIFD2Fzc2V0QWRkZWRJZFN0cgUOYXNzZXRQYXJhbXNVcGQFA25pbAUHUElzc3VlZAEWY2FsY1JlZGVlbVdpdGhPbmVUb2tlbgINYXNzZXRPdXRJZFN0cglQUmVkZWVtZWQEB1BTdXBwbHkJARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAQLYXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQ1hc3NldE91dElkU3RyBBBhc3NldEZhY3RCYWxhbmNlCAULYXNzZXRQYXJhbXMCXzIEEGFzc2V0VmlydEJhbGFuY2UIBQthc3NldFBhcmFtcwJfMQQLYXNzZXRXZWlnaHQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FDWFzc2V0T3V0SWRTdHICB193ZWlnaHQECmFzc2V0U2NhbGUJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FDWFzc2V0T3V0SWRTdHICBl9zY2FsZQQNYXNzZXREZWNpbWFscwkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUNYXNzZXRPdXRJZFN0cgIJX2RlY2ltYWxzBBVhbW91bnRPdXROb011bGl0cGxpZXIJAGsDBRBhc3NldFZpcnRCYWxhbmNlCQBlAgUGU2NhbGU4CQCgAwEJAHYGCQC2AgEJAGUCBQphc3NldFNjYWxlCQBrAwUJUFJlZGVlbWVkBQphc3NldFNjYWxlBQdQU3VwcGx5BQ1hc3NldERlY2ltYWxzCQC2AgEJAGsDAJBOAJBOBQthc3NldFdlaWdodAAEAAgFBERPV04FBlNjYWxlOAQHYXZnQ29uYwkBFGNhbGNBdmdDb25jZW50cmF0aW9uAAQJYW1vdW50T3V0CQBrAwUVYW1vdW50T3V0Tm9NdWxpdHBsaWVyCAUHYXZnQ29uYwJfMQgFB2F2Z0NvbmMCXzIDCQBmAgUJYW1vdW50T3V0BRBhc3NldEZhY3RCYWxhbmNlCQACAQI0bm8gYXZhaWxhYmxlIGZhY3QgbGlxdWlkaXR5IHRvIHdpdGhkcmF3IGluIG9uZSB0b2tlbgQOYXNzZXRQYXJhbXNVcGQJAJoKCAkAZQIFEGFzc2V0VmlydEJhbGFuY2UFCWFtb3VudE91dAkAZQIFEGFzc2V0RmFjdEJhbGFuY2UFCWFtb3VudE91dAgFC2Fzc2V0UGFyYW1zAl8zCAULYXNzZXRQYXJhbXMCXzQIBQthc3NldFBhcmFtcwJfNQgFC2Fzc2V0UGFyYW1zAl82CAULYXNzZXRQYXJhbXMCXzcIBQthc3NldFBhcmFtcwJfOAkAlAoCCQDMCAIJARVzYXZlR2xvYmFsVG9rZW5QYXJhbXMCBQ1hc3NldE91dElkU3RyBQ5hc3NldFBhcmFtc1VwZAUDbmlsBQlhbW91bnRPdXQBFmhhbmRsZVBvb2xUb2tlbnNSZWRlZW0CCVBSZWRlZW1lZAt1c2VyQWRkcmVzcwoBEWhhbmRsZVRva2VuUmVkZWVtAgVhY2N1bQd0b2tlbklkBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBBQd0b2tlbklkBAthc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCmFzc2V0SWRTdHIEAkJrCAULYXNzZXRQYXJhbXMCXzIEB1BTdXBwbHkJARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAQNdG9rZW5EZWNpbWFscwkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUKYXNzZXRJZFN0cgIGX3NjYWxlBAZwc3VwcGwJAL0CBAkAuQICCQC2AgEJAGUCBQdQU3VwcGx5BQlQUmVkZWVtZWQJALYCAQUGU2NhbGU4CQC2AgEFBlNjYWxlOAkAtgIBBQdQU3VwcGx5BQRET1dOBAZhbW91bnQJAKADAQkAvQIECQC4AgIJALYCAQUHU2NhbGUxNgUGcHN1cHBsCQC2AgEFAkJrCQC2AgEFB1NjYWxlMTYFCEhBTEZFVkVOBAl1bnN0YWtlVHgJAQ91bnN0YWtlSWZOZWVkZWQCBQphc3NldElkU3RyBQZhbW91bnQDCQAAAgUJdW5zdGFrZVR4BQl1bnN0YWtlVHgEE3NlbGxvZmZTdGFydEJhbGFuY2UDCQECIT0CCAULYXNzZXRQYXJhbXMCXzgJAGgCCQBpAgUGaGVpZ2h0AGQAZAgFC2Fzc2V0UGFyYW1zAl83CQBrAwgFC2Fzc2V0UGFyYW1zAl83CQBlAgUHUFN1cHBseQUJUFJlZGVlbWVkBQdQU3VwcGx5BA5hc3NldFBhcmFtc1VwZAkAmgoICQBrAwgFC2Fzc2V0UGFyYW1zAl8xCQBlAgUHUFN1cHBseQUJUFJlZGVlbWVkBQdQU3VwcGx5CQBlAggFC2Fzc2V0UGFyYW1zAl8yBQZhbW91bnQIBQthc3NldFBhcmFtcwJfMwgFC2Fzc2V0UGFyYW1zAl80CAULYXNzZXRQYXJhbXMCXzUIBQthc3NldFBhcmFtcwJfNgUTc2VsbG9mZlN0YXJ0QmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl84CQDOCAIJAM4IAgUFYWNjdW0JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFBmFtb3VudAUHdG9rZW5JZAUDbmlsCQDMCAIJARVzYXZlR2xvYmFsVG9rZW5QYXJhbXMCBQphc3NldElkU3RyBQ5hc3NldFBhcmFtc1VwZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARFoYW5kbGVUb2tlblJlZGVlbQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgESY2FsY3VsYXRlT3V0QW1vdW50BQhBbW91bnRJbgdhc3NldEluCGFzc2V0T3V0CUJhbGFuY2VJbgpCYWxhbmNlT3V0BAdJbmRleEluCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzBQdhc3NldEluBAhJbmRleE91dAkBBXZhbHVlAQkAzwgCBQhhc3NldElkcwUIYXNzZXRPdXQDCQAAAgUHSW5kZXhJbgUISW5kZXhPdXQFCEFtb3VudEluCQBuBAUKQmFsYW5jZU91dAkAZQIJAGgCBQZTY2FsZTgFBlNjYWxlOAkAoAMBCQB2BgkAvQIECQC5AgIJALYCAQUJQmFsYW5jZUluCQC2AgEAkE4JALYCAQkAaAIFBlNjYWxlOAUGU2NhbGU4CQC5AgIJALYCAQkAZAIFCUJhbGFuY2VJbgUIQW1vdW50SW4JALYCAQCQTgUGSEFMRlVQABAJALYCAQkAawMJAJEDAgUNQXNzZXRzV2VpZ2h0cwUHSW5kZXhJbgCAoJSljR0JAJEDAgUNQXNzZXRzV2VpZ2h0cwUISW5kZXhPdXQADAAQBQdDRUlMSU5HCQBoAgUGU2NhbGU4BQZTY2FsZTgFCEhBTEZFVkVOAQtjbGFpbVJlc3VsdAEHYWRkcmVzcwQKYWRkcmVzc1N0cgkApQgBBQdhZGRyZXNzBAtpbmRleEFtb3VudAkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAQLZmVlQXNzZXRTdHIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfZmVlVG9rZW4EDmZlZUFzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQULZmVlQXNzZXRTdHIED2ZlZVRva2VuQmFsYW5jZQgFDmZlZUFzc2V0UGFyYW1zAl8xCgEHaGFuZGxlcgIFYWNjdW0HYXNzZXRJZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAQLYXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQphc3NldElkU3RyBBRjdXJyZW50VG9rZW5JbnRlcmVzdAgFC2Fzc2V0UGFyYW1zAl80BAhhQmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl8xBAxyZXdhcmRBbW91bnQJAGsDBQtpbmRleEFtb3VudAkAZQIFFGN1cnJlbnRUb2tlbkludGVyZXN0CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICCQCsAgIFCmFkZHJlc3NTdHICC19sYXN0Q2hlY2tfBQphc3NldElkU3RyAglfaW50ZXJlc3QFB1NjYWxlMTYECnVuc3Rha2VJbnYJAQ91bnN0YWtlSWZOZWVkZWQCBQphc3NldElkU3RyBQxyZXdhcmRBbW91bnQDCQAAAgUKdW5zdGFrZUludgUKdW5zdGFrZUludgQIdHJhbnNmZXIDCQAAAgUMcmV3YXJkQW1vdW50AAAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQdhZGRyZXNzBQxyZXdhcmRBbW91bnQFB2Fzc2V0SWQFA25pbAkAlAoCCQDOCAIJAM4IAggFBWFjY3VtAl8xBQh0cmFuc2ZlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUKYWRkcmVzc1N0cgILX2xhc3RDaGVja18FCmFzc2V0SWRTdHICCV9pbnRlcmVzdAUUY3VycmVudFRva2VuSW50ZXJlc3QFA25pbAkAZAIIBQVhY2N1bQJfMgkBEWNhbGN1bGF0ZVVzZFZhbHVlBAUHYXNzZXRJZAUMcmV3YXJkQW1vdW50BQhhQmFsYW5jZQUPZmVlVG9rZW5CYWxhbmNlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAVhY2N1bQoAAiRsBQxlYXJuZWRBc3NldHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIFA25pbAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdoYW5kbGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQCUCgIJAM4IAggFBWFjY3VtAl8xCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFkZHJlc3NTdHICEV9jbGFpbWVkUmV3YXJkVVNECQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICEV9jbGFpbWVkUmV3YXJkVVNECAUFYWNjdW0CXzIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgIKX2xhc3RDbGFpbQgFCWxhc3RCbG9jawl0aW1lc3RhbXAFA25pbAgFBWFjY3VtAl8yARBpbmRleFN0YWtlUmVzdWx0AgphZGRyZXNzU3RyBmFtb3VudAQCbGkICQELY2xhaW1SZXN1bHQBCQERQGV4dHJOYXRpdmUoMTA2MikBBQphZGRyZXNzU3RyAl8xCQDOCAIFAmxpCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgISZ2xvYmFsX2luZGV4U3Rha2VkCQBkAgkBDXRyeUdldEludGVnZXIBAhJnbG9iYWxfaW5kZXhTdGFrZWQFBmFtb3VudAUDbmlsAQNzdW0CBWFjY3VtAW4JAGQCBQVhY2N1bQkBDXBhcnNlSW50VmFsdWUBBQFuAQ1jaGVja0ZlZUFzc2V0AgVhY2N1bQRuZXh0AwMJAQIhPQIJAM8IAgUVc3VwcG9ydGVkRmVlQXNzZXRzU3RyBQRuZXh0BQR1bml0CQAAAgUFYWNjdW0CAAcFBG5leHQFBWFjY3VtARJjYWxjSW50ZXJlc3RDaGFuZ2UCCmFzc2V0SWRTdHIFbHBGZWUECnRvdGFsSW5kZXgJAQ10cnlHZXRJbnRlZ2VyAQISZ2xvYmFsX2luZGV4U3Rha2VkBA1pbnRlcmVzdERlbHRhCQBrAwUFbHBGZWUFB1NjYWxlMTYFCnRvdGFsSW5kZXgFDWludGVyZXN0RGVsdGEBDnVwZFNlbGxvZmZEYXRhBAphc3NldElkU3RyCGFtb3VudEluB2JhbGFuY2UNc2VsbG9mZlBhcmFtcwQNY3VycmVudFBlcmlvZAkAaAIJAGkCBQZoZWlnaHQAZABkBApwcmV2UGVyaW9kCAUNc2VsbG9mZlBhcmFtcwJfMgQLcHJldlNlbGxvZmYDCQAAAgUNY3VycmVudFBlcmlvZAUKcHJldlBlcmlvZAgFDXNlbGxvZmZQYXJhbXMCXzEAAAQTc2VsbG9mZlN0YXJ0QmFsYW5jZQMJAAACBQ1jdXJyZW50UGVyaW9kBQpwcmV2UGVyaW9kCAUNc2VsbG9mZlBhcmFtcwJfMwUHYmFsYW5jZQQMc2VsbG9mZkRlbHRhCQBrAwUHU2NhbGUxNgUIYW1vdW50SW4FE3NlbGxvZmZTdGFydEJhbGFuY2UECm1heFNlbGxvZmYJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICC19tYXhTZWxsb2ZmAwMJAGYCCQBkAgULcHJldlNlbGxvZmYFDHNlbGxvZmZEZWx0YQUKbWF4U2VsbG9mZgkBAiE9AgUKbWF4U2VsbG9mZgAABwkAAgEJAKwCAgIjbWF4IHNlbGxvZmYgcmVhY2hlZCBmb3IgdGhpcyBhc3NldCAFCmFzc2V0SWRTdHIEBnN0YXJ0SAMJAAACBQ1jdXJyZW50UGVyaW9kBQpwcmV2UGVyaW9kBQpwcmV2UGVyaW9kBQ1jdXJyZW50UGVyaW9kBAZzdGFydEIDCQAAAgUNY3VycmVudFBlcmlvZAUKcHJldlBlcmlvZAgFDXNlbGxvZmZQYXJhbXMCXzMFE3NlbGxvZmZTdGFydEJhbGFuY2UJAJUKAwkAZAIFC3ByZXZTZWxsb2ZmBQxzZWxsb2ZmRGVsdGEFBnN0YXJ0SAUGc3RhcnRCARJnZXRUbXBSZWJhbGFuY2VJZHMBDW5ld0Fzc2V0SWRzTGkEEWN1cnJlbnRBc3NldElkc0xpCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfdG9rZW5JZHMCASwEBnJlc3VsdAUNbmV3QXNzZXRJZHNMaQoBAWYCBWFjY3VtB2Fzc2V0SWQDCQAAAgkAzwgCBQZyZXN1bHQFB2Fzc2V0SWQFBHVuaXQJAM4IAgUFYWNjdW0JAMwIAgUHYXNzZXRJZAUDbmlsBQVhY2N1bQoAAiRsBRFjdXJyZW50QXNzZXRJZHNMaQoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFBnJlc3VsdAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEBZgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgERY2hlY2tUb2tlbnNDaGFuZ2UBDW5ld0Fzc2V0SWRzTGkEEWN1cnJlbnRBc3NldElkc0xpCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfdG9rZW5JZHMCASwKAQNyZW0CBWFjY3VtB2Fzc2V0SWQDCQAAAgkAzwgCBQ1uZXdBc3NldElkc0xpBQdhc3NldElkBQR1bml0CQBkAgUFYWNjdW0AAQUFYWNjdW0KAQNhZGQCBWFjY3VtB2Fzc2V0SWQDCQAAAgkAzwgCBRFjdXJyZW50QXNzZXRJZHNMaQUHYXNzZXRJZAUEdW5pdAkAZAIFBWFjY3VtAAEFBWFjY3VtBAdyZW1vdmVkCgACJGwFEWN1cnJlbnRBc3NldElkc0xpCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQNyZW0CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEBWFkZGVkCgACJGwFDW5ld0Fzc2V0SWRzTGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjVfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBA2FkZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjVfMgIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgkAZAIFB3JlbW92ZWQFBWFkZGVkARB2YWxpZGF0ZVBheW1lbnRzAgphc3NldHNMaXN0CHBheW1lbnRzCgEQZ2V0UGF5bWVudEFzc2V0cwIFYWNjdW0EbmV4dAMJAGcCAAAIBQRuZXh0BmFtb3VudAkAAgEJAKwCAgkArAICCQCsAgICG1RvbyBsb3cgcGF5bWVudCBhbW91bnQgZm9yIAkBDmdldEFzc2V0U3RyaW5nAQgFBG5leHQHYXNzZXRJZAICOiAJAKQDAQgFBG5leHQGYW1vdW50CQDOCAIFBWFjY3VtCQDMCAIJAQ5nZXRBc3NldFN0cmluZwEIBQRuZXh0B2Fzc2V0SWQFA25pbAQLcGF5bWVudExpc3QKAAIkbAUIcGF5bWVudHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEGdldFBheW1lbnRBc3NldHMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoKAQJmMQIFYWNjdW0EbmV4dAMJAAACCQDPCAIFCmFzc2V0c0xpc3QFBG5leHQFBHVuaXQJAAIBCQCsAgIJAKwCAgUEbmV4dAI5IGFzc2V0IGlzIHByZXNlbnQgaW4gcGF5bWVudHMsIGJ1dCBpcyBub3QgaW4gbmV3IGFzc2V0czogCQC5CQIFCmFzc2V0c0xpc3QCASwJAGQCBQVhY2N1bQABCgECZjICBWFjY3VtBG5leHQDCQAAAgkAzwgCBQtwYXltZW50TGlzdAUEbmV4dAUEdW5pdAkAAgEJAKwCAgkArAICBQRuZXh0AjkgYXNzZXQgaXMgcHJlc2VudCBpbiBuZXcgYXNzZXRzLCBidXQgaXMgbm90IGluIHBheW1lbnRzOiAJALkJAgULcGF5bWVudExpc3QCASwJAGQCBQVhY2N1bQABBAJhMQoAAiRsBQtwYXltZW50TGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmNV8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQECZjECBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjVfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY1XzICCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEAmEyCgACJGwFCmFzc2V0c0xpc3QKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjZfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAmYyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY2XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNl8yAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQBkAgUCYTEFAmEyAQ92YWxpZGF0ZVdlaWdodHMBB3dlaWdodHMKAQF2AgVhY2N1bQF3BAR3SW50CQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQUBdwkArAICAhVXcm9uZyB3ZWlnaHQgZm9ybWF0OiAFAXcDAwkAZgIFCk1JTl9XRUlHSFQFBHdJbnQGCQBmAgUEd0ludAUKTUFYX1dFSUdIVAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhpXZWlnaHQgc2hvdWxkIGJlIGluIHJhbmdlIAkApAMBBQpNSU5fV0VJR0hUAgMgLSAJAKQDAQUKTUFYX1dFSUdIVAILLCBjdXJyZW50OiAFAXcJAGQCBQVhY2N1bQUEd0ludAoAAiRsBQd3ZWlnaHRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQF2AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAQdnZXRQMVAyAgphc3NldElkU3RyDmJhc2VBc3NldElkU3RyBAthc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCmFzc2V0SWRTdHIED2Jhc2VBc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFDmJhc2VBc3NldElkU3RyBAJCMQgFD2Jhc2VBc3NldFBhcmFtcwJfMQQCQjIIBQthc3NldFBhcmFtcwJfMQQCRjEIBQ9iYXNlQXNzZXRQYXJhbXMCXzIEAkYyCAULYXNzZXRQYXJhbXMCXzIEAlMxCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQ5iYXNlQXNzZXRJZFN0cgIGX3NjYWxlBAJTMgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUKYXNzZXRJZFN0cgIGX3NjYWxlBAJEMQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUOYmFzZUFzc2V0SWRTdHICCV9kZWNpbWFscwQCRDIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICCV9kZWNpbWFscwQCVzEJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FDmJhc2VBc3NldElkU3RyAgdfd2VpZ2h0BAJXMgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUKYXNzZXRJZFN0cgIHX3dlaWdodAQEVzFXMgkAawMFAlcxAJBOBQJXMgQEVzJXMQkAawMFAlcyAJBOBQJXMQQNcDFfdW53ZWlnaHRlZAkAawMJAGUCBQJCMQUCRjEFAlMxCQBrAwUCQjIJAGwGCQBrAwUCQjEFAlMxCQBlAgUCQjEFAkYxBQJEMQUEVzFXMgAEBQJEMQUHQ0VJTElORwUCUzIEAnAxCQBrAwUNcDFfdW53ZWlnaHRlZAUEVzJXMQCQTgMJAAACBQJCMgUCRjIJAJQKAgUCcDEFBHVuaXQEDXAyX3Vud2VpZ2h0ZWQJAGsDCQBrAwUCQjEJAGwGCQBrAwUCQjIFAlMyCQBlAgUCQjIFAkYyBQJEMgUEVzJXMQAEBQJEMgUFRkxPT1IFAlMyBQJTMgkAZQIFAkIyBQJGMgQCcDIJAGsDBQ1wMl91bndlaWdodGVkBQRXMlcxAJBOCQCUCgIFAnAxBQJwMhEBaQETYWRkVW5kZXJseWluZ1N0YWtlcgINc3Rha2VyQWRkcmVzcwphc3NldElkU3RyAwkBAiE9AgUEdGhpcwgFAWkGY2FsbGVyCQACAQIKYWRtaW4gb25seQkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgICF3N0YXRpY19zdGFraW5nQ29udHJhY3RfBQphc3NldElkU3RyBQ1zdGFrZXJBZGRyZXNzBQNuaWwBaQEHcHJlSW5pdAcLYXNzZXRJZHNTdHIPYXNzZXRXZWlnaHRzU3RyEmFzc2V0TWF4U2VsbG9mZlN0cg5iYXNlVG9rZW5JZFN0cgpwb29sRG9tYWluCXBvb2xPd25lcgNmZWUEEHBvb2xPd25lckFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCXBvb2xPd25lcgQNYXNzZXRJZHNTdHJMaQkAtQkCBQthc3NldElkc1N0cgIBLAQUYXNzZXRNYXhTZWxsb2ZmU3RyTGkJALUJAgUSYXNzZXRNYXhTZWxsb2ZmU3RyAgEsBBFhc3NldFdlaWdodHNTdHJMaQkAtQkCBQ9hc3NldFdlaWdodHNTdHICASwECmFzc2V0SWRzTGkKAAIkbAUNYXNzZXRJZHNTdHJMaQoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQETYWRkQXNzZXRCeXRlc1RvTGlzdAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQRZmVlQXNzZXRDaG9zZW5TdHIKAAIkbAUNYXNzZXRJZHNTdHJMaQoAAiRzCQCQAwEFAiRsCgAFJGFjYzACAAoBBSRmNV8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQENY2hlY2tGZWVBc3NldAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjVfMgIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIJAQUkZjVfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQLZmVlQXNzZXRTdHIDCQAAAgURZmVlQXNzZXRDaG9zZW5TdHICAAUOYmFzZVRva2VuSWRTdHIFEWZlZUFzc2V0Q2hvc2VuU3RyAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAMJAQIhPQIFBHRoaXMIBQFpBmNhbGxlcgkAAgECCmFkbWluIG9ubHkDCQBmAgkAsQIBBQpwb29sRG9tYWluAA0JAAIBAhV0b28gbGFyZ2UgcG9vbCBkb21haW4DAwkAZgIFA2ZlZQD0AwYJAGYCAAAFA2ZlZQkAAgECKmZlZSB2YWx1ZSBtdXN0IGJlIGJldHdlZW4gMCBhbmQgNTAwICgwLTUlKQMJAQIhPQIJAQ92YWxpZGF0ZVdlaWdodHMBBRFhc3NldFdlaWdodHNTdHJMaQCQTgkAAgEJAKwCAgImd2VpZ2h0cyBzdW0gc2hvdWxkIGJlIDEwMDAwLCBjdXJyZW50OiAJAKQDAQkBD3ZhbGlkYXRlV2VpZ2h0cwEFEWFzc2V0V2VpZ2h0c1N0ckxpCgETYWRkVG9rZW5EYXRhRW50cmllcwIFYWNjdW0IYXNzZXROdW0DCQBnAgUIYXNzZXROdW0JAJADAQUKYXNzZXRJZHNMaQUFYWNjdW0EE2Fzc2V0U3Rha2luZ0FkZHJlc3MKAAFACQD8BwQFD3Bvb2xzSHViQWRkcmVzcwIQdXNlRW1wdHlDb250cmFjdAkAzAgCCQCsAgICB3N0YWtlcl8JAJEDAgUNYXNzZXRJZHNTdHJMaQUIYXNzZXROdW0FA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwMJAAACBRNhc3NldFN0YWtpbmdBZGRyZXNzBRNhc3NldFN0YWtpbmdBZGRyZXNzBA1hc3NldERlY2ltYWxzBAckbWF0Y2gwCQCRAwIFCmFzc2V0SWRzTGkFCGFzc2V0TnVtAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAXgFByRtYXRjaDAICQEFdmFsdWUBCQDsBwEFAXgIZGVjaW1hbHMACAkAzggCCQDOCAIFBWFjY3VtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHc3RhdGljXwkAkQMCBQ1hc3NldElkc1N0ckxpBQhhc3NldE51bQIGX3NjYWxlCQBsBgAKAAAFDWFzc2V0RGVjaW1hbHMAAAAABQRET1dOCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHc3RhdGljXwkAkQMCBQ1hc3NldElkc1N0ckxpBQhhc3NldE51bQIJX2RlY2ltYWxzBQ1hc3NldERlY2ltYWxzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHc3RhdGljXwkAkQMCBQ1hc3NldElkc1N0ckxpBQhhc3NldE51bQIHX3dlaWdodAkBBXZhbHVlAQkAtgkBCQCRAwIFEWFzc2V0V2VpZ2h0c1N0ckxpBQhhc3NldE51bQkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgICF3N0YXRpY19zdGFraW5nQ29udHJhY3RfCQCRAwIFDWFzc2V0SWRzU3RyTGkFCGFzc2V0TnVtBRNhc3NldFN0YWtpbmdBZGRyZXNzBQNuaWwDCQAAAgkAkQMCBRRhc3NldE1heFNlbGxvZmZTdHJMaQUIYXNzZXROdW0CAAUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIHc3RhdGljXwkAkQMCBQ1hc3NldElkc1N0ckxpBQhhc3NldE51bQILX21heFNlbGxvZmYJAGgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUUYXNzZXRNYXhTZWxsb2ZmU3RyTGkFCGFzc2V0TnVtBQdTY2FsZTEyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAM4IAgoAAiRsCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFCQDMCAIABgkAzAgCAAcJAMwIAgAICQDMCAIACQUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY2XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARNhZGRUb2tlbkRhdGFFbnRyaWVzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY2XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNl8yAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgkBBSRmNl8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQDMCAIJAQtTdHJpbmdFbnRyeQICD3N0YXRpY190b2tlbklkcwULYXNzZXRJZHNTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgIPc3RhdGljX2ZlZVRva2VuBQtmZWVBc3NldFN0cgkAzAgCCQELU3RyaW5nRW50cnkCAhNzdGF0aWNfdG9rZW5XZWlnaHRzBQ9hc3NldFdlaWdodHNTdHIJAMwIAgkBDEludGVnZXJFbnRyeQICE3N0YXRpY190b2tlbnNBbW91bnQJAJADAQUKYXNzZXRJZHNMaQkAzAgCCQELU3RyaW5nRW50cnkCAhFzdGF0aWNfcG9vbERvbWFpbgUKcG9vbERvbWFpbgkAzAgCCQELU3RyaW5nRW50cnkCAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyAgAJAMwIAgkBC1N0cmluZ0VudHJ5AgISc3RhdGljX2Jhc2VUb2tlbklkBQ5iYXNlVG9rZW5JZFN0cgkAzAgCCQELU3RyaW5nRW50cnkCAhBzdGF0aWNfcG9vbE93bmVyBQlwb29sT3duZXIJAMwIAgkBDEludGVnZXJFbnRyeQICCnN0YXRpY19mZWUFA2ZlZQkAzAgCCQEMSW50ZWdlckVudHJ5AgIMc3RhdGljX0tNdWx0BQdTY2FsZTE2CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgITZ2xvYmFsX3dhc1ByZUluaXRlZAABBQNuaWwBaQEGZGVJbml0AAMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3ADCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAgphZG1pbiBvbmx5CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhBnbG9iYWxfd2FzSW5pdGVkAAAFA25pbAFpAQRpbml0Bwthc3NldElkc1N0cg9hc3NldFdlaWdodHNTdHISYXNzZXRNYXhTZWxsb2ZmU3RyDmJhc2VUb2tlbklkU3RyCnBvb2xEb21haW4DZmVlDHZCYWxhbmNlc1N0cgQKcHJlSW5pdEludgkA/AcEBQR0aGlzAgdwcmVJbml0CQDMCAIFC2Fzc2V0SWRzU3RyCQDMCAIFD2Fzc2V0V2VpZ2h0c1N0cgkAzAgCBRJhc3NldE1heFNlbGxvZmZTdHIJAMwIAgUOYmFzZVRva2VuSWRTdHIJAMwIAgUKcG9vbERvbWFpbgkAzAgCCQClCAEIBQFpBmNhbGxlcgkAzAgCBQNmZWUFA25pbAUDbmlsAwkAAAIFCnByZUluaXRJbnYFCnByZUluaXRJbnYECXZCYWxhbmNlcwkBEXBhcnN0U3RyVG9JbnRMaXN0AQUMdkJhbGFuY2VzU3RyCgEQZ2V0UGF5bWVudEFtb3VudAEKYXNzZXRJZFN0cgoBB2hhbmRsZXICBWFjY3VtB3BheW1lbnQDCQAAAgkBDmdldEFzc2V0U3RyaW5nAQgFB3BheW1lbnQHYXNzZXRJZAUKYXNzZXRJZFN0cggFB3BheW1lbnQGYW1vdW50BQVhY2N1bQoAAiRsCAUBaQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgoBC3ByZXBhcmVMaXN0AAoBB2hhbmRsZXICBWFjY3VtB2Fzc2V0SWQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFB2Fzc2V0SWQEAW4JAQV2YWx1ZQEJAM8IAgUIYXNzZXRJZHMFB2Fzc2V0SWQEDXBheW1lbnRBbW91bnQJARBnZXRQYXltZW50QW1vdW50AQUKYXNzZXRJZFN0cgQLYXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQphc3NldElkU3RyBA5hc3NldFBhcmFtc1VwZAkAmgoICQCRAwIFCXZCYWxhbmNlcwUBbgUNcGF5bWVudEFtb3VudAgFC2Fzc2V0UGFyYW1zAl8zCAULYXNzZXRQYXJhbXMCXzQIBQthc3NldFBhcmFtcwJfNQgFC2Fzc2V0UGFyYW1zAl82CAULYXNzZXRQYXJhbXMCXzcIBQthc3NldFBhcmFtcwJfOAkAzggCBQVhY2N1bQkAzAgCCQEVc2F2ZUdsb2JhbFRva2VuUGFyYW1zAgUKYXNzZXRJZFN0cgUOYXNzZXRQYXJhbXNVcGQFA25pbAoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgoBGWNhbGN1bGF0ZVBvb2xUb2tlbnNBbW91bnQBB2Fzc2V0SWQKAQdoYW5kbGVyAgVhY2N1bQdhc3NldElkCgEIaGFuZGxlcjICBWFjY3VtAW4DCQAAAgUBbgUHYXNzZXRJZAkBBXZhbHVlAQkAzwgCBQhhc3NldElkcwUBbgUFYWNjdW0EBVRva2VuCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAABCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhoYW5kbGVyMgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgkAawMFBWFjY3VtCQBsBgkAkQMCBQl2QmFsYW5jZXMFBVRva2VuCQCRAwIFCERlY2ltYWxzBQVUb2tlbgkAkQMCBQ1Bc3NldHNXZWlnaHRzBQVUb2tlbgUVQXNzZXRzV2VpZ2h0c0RlY2ltYWxzAAgFBUZMT09SBQZTY2FsZTgKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQ5Qb29sVG9rZW5TY2FsZQoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3ADCQAAAgkAkAMBCAUBaQhwYXltZW50cwAACQACAQI5YXQgbGVhc3Qgc29tZSBvZiB0aGUgYXNzZXRzIHNob3VsZCBiZSBwcm92aWRlZCBhcyBwYXltZW50AwkAZgIJAQ10cnlHZXRJbnRlZ2VyAQIQZ2xvYmFsX3dhc0luaXRlZAAACQACAQITcG9vbCBhbHJlYWR5IGluaXRlZAQRaW5pdGlhbFBvb2xUb2tlbnMJARljYWxjdWxhdGVQb29sVG9rZW5zQW1vdW50AQUIYXNzZXRJZHMEDG5vdGlmeUludm9rZQkA/AcEBQ9wb29sc0h1YkFkZHJlc3MCC2FkZFNlbGZQb29sBQNuaWwFA25pbAMJAAACBQxub3RpZnlJbnZva2UFDG5vdGlmeUludm9rZQMJAAACBRFpbml0aWFsUG9vbFRva2VucwAACQACAQIyeW91IG5lZWQgYSBiaWdnZXIgdG9rZW5zIGFtb3VudCB0byBsYXVuY2ggdGhlIHBvb2wJAM4IAgkBC3ByZXBhcmVMaXN0AAkAzAgCCQEMSW50ZWdlckVudHJ5AgIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQFEWluaXRpYWxQb29sVG9rZW5zCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhBnbG9iYWxfd2FzSW5pdGVkAAEJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkApQgBCAUBaQZjYWxsZXICDF9pbmRleFN0YWtlZAURaW5pdGlhbFBvb2xUb2tlbnMJAMwIAgkBDEludGVnZXJFbnRyeQICEmdsb2JhbF9pbmRleFN0YWtlZAURaW5pdGlhbFBvb2xUb2tlbnMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ1nZW5lcmF0ZUluZGV4AQpuZWVkQ2hhbmdlAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwUBVAkAAgEJAKwCAgI7eW91IG5lZWQgdG8gYXR0YWNoIGFsbCBwb29sIHRva2Vucy4gYW1vdW50IG9mIHBvb2wgdG9rZW5zOiAJAKQDAQUBVAMJAQEhAQkBE2NoZWNrVG9rZW5zVmFsaWRpdHkBCAUBaQhwYXltZW50cwkAAgECFXdyb25nIGFzc2V0cyBhdHRhY2hlZAQNUElzc3VlZE5vTXVsdAkBDWdldE1pblBJc3N1ZWQBCAUBaQhwYXltZW50cwQGcmVzdWx0CQETaGFuZGxlUG9vbFRva2Vuc0FkZAQFDVBJc3N1ZWROb011bHQIBQFpCHBheW1lbnRzCAUBaQxvcmlnaW5DYWxsZXIFCm5lZWRDaGFuZ2UED1BJc3N1ZWRXaXRoTXVsdAkAbgQFDVBJc3N1ZWROb011bHQFB1NjYWxlMTYJAQhnZXRLTXVsdAAFBERPV04JAJQKAgkAzggCCQDOCAIJAM4IAgUGcmVzdWx0CAkBC2NsYWltUmVzdWx0AQgFAWkGY2FsbGVyAl8xCQERbWludEluZGV4SWZOZWVkZWQBBQ9QSXNzdWVkV2l0aE11bHQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkApQgBCAUBaQZjYWxsZXICDF9pbmRleFN0YWtlZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQClCAEIBQFpBmNhbGxlcgIMX2luZGV4U3Rha2VkBQ9QSXNzdWVkV2l0aE11bHQJAMwIAgkBDEludGVnZXJFbnRyeQICEmdsb2JhbF9pbmRleFN0YWtlZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQISZ2xvYmFsX2luZGV4U3Rha2VkBQ9QSXNzdWVkV2l0aE11bHQJAMwIAgkBDEludGVnZXJFbnRyeQICF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50CQBkAgkBDXRyeUdldEludGVnZXIBAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAUPUElzc3VlZFdpdGhNdWx0BQNuaWwFD1BJc3N1ZWRXaXRoTXVsdAFpAQtyZWRlZW1JbmRleAEPcG9vbFRva2VuQW1vdW50AwkAZgIFD3Bvb2xUb2tlbkFtb3VudAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgxfaW5kZXhTdGFrZWQJAAIBAix1c2VyIGRvZXNuJ3QgaGF2ZSB0aGlzIGFtb3VudCBvZiBwb29sIHRva2VucwMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AEEVBSZWRlZW1lZFdpdGhNdWx0BQ9wb29sVG9rZW5BbW91bnQEE1BSZWRlZW1lZFdpdGhOb011bHQJAG4EBRFQUmVkZWVtZWRXaXRoTXVsdAkBCGdldEtNdWx0AAUHU2NhbGUxNgUERE9XTgQGcmVzdWx0CQEWaGFuZGxlUG9vbFRva2Vuc1JlZGVlbQIFE1BSZWRlZW1lZFdpdGhOb011bHQIBQFpBmNhbGxlcgkAzggCCQDOCAIJAM4IAgUGcmVzdWx0CAkBC2NsYWltUmVzdWx0AQgFAWkGY2FsbGVyAl8xCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgxfaW5kZXhTdGFrZWQJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkApQgBCAUBaQZjYWxsZXICDF9pbmRleFN0YWtlZAURUFJlZGVlbWVkV2l0aE11bHQJAMwIAgkBDEludGVnZXJFbnRyeQICEmdsb2JhbF9pbmRleFN0YWtlZAkAZQIJAQ10cnlHZXRJbnRlZ2VyAQISZ2xvYmFsX2luZGV4U3Rha2VkBRFQUmVkZWVtZWRXaXRoTXVsdAkAzAgCCQEMSW50ZWdlckVudHJ5AgIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQJAGUCCQENdHJ5R2V0SW50ZWdlcgECF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50BRFQUmVkZWVtZWRXaXRoTXVsdAUDbmlsCQERYnVybkluZGV4SWZOZWVkZWQBBQ9wb29sVG9rZW5BbW91bnQBaQEKc3Rha2VJbmRleAAECmFkZHJlc3NTdHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAkA2QQBCQEMdHJ5R2V0U3RyaW5nAQIWc3RhdGljX3Bvb2xUb2tlbl9pZFN0cgkAAgECFHdyb25nIGFzc2V0IGF0dGFjaGVkCQEQaW5kZXhTdGFrZVJlc3VsdAIFCmFkZHJlc3NTdHIIBQNwbXQGYW1vdW50AWkBDXN0YWtlSW5kZXhGb3IBCmFkZHJlc3NTdHIEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkCQDZBAEJAQx0cnlHZXRTdHJpbmcBAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyCQACAQIUd3JvbmcgYXNzZXQgYXR0YWNoZWQJARBpbmRleFN0YWtlUmVzdWx0AgUKYWRkcmVzc1N0cggFA3BtdAZhbW91bnQBaQEMdW5zdGFrZUluZGV4AQtpbmRleEFtb3VudAoBCmlzc3VlSW5kZXgABAVpc3N1ZQkAwwgHCQCsAgICA1BSIAkBDHRyeUdldFN0cmluZwECEXN0YXRpY19wb29sRG9tYWluAhJQdXp6bGUgUmFuZ2UgSW5kZXgJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQFEVBvb2xUb2tlbkRlY2ltYWxzBgUEdW5pdAAABA5wb29sVG9rZW5JZFN0cgkA2AQBCQC4CAEFBWlzc3VlCQCUCgIJAMwIAgUFaXNzdWUJAMwIAgkBC1N0cmluZ0VudHJ5AgIWc3RhdGljX3Bvb2xUb2tlbl9pZFN0cgUOcG9vbFRva2VuSWRTdHIFA25pbAUOcG9vbFRva2VuSWRTdHIEDSR0MDQwNDA4NDA1NzQDCQAAAgkBDHRyeUdldFN0cmluZwECFnN0YXRpY19wb29sVG9rZW5faWRTdHICAAkBCmlzc3VlSW5kZXgACQCUCgIFA25pbAkBDHRyeUdldFN0cmluZwECFnN0YXRpY19wb29sVG9rZW5faWRTdHIEFHBvb2xUb2tlbklzc3VlUmVzdWx0CAUNJHQwNDA0MDg0MDU3NAJfMQQOcG9vbFRva2VuSWRTdHIIBQ0kdDA0MDQwODQwNTc0Al8yBAtwb29sVG9rZW5JZAkA2QQBBQ5wb29sVG9rZW5JZFN0cgQKYWRkcmVzc1N0cgkApQgBCAUBaQZjYWxsZXIEDmluZGV4QXZhaWxhYmxlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYWRkcmVzc1N0cgIMX2luZGV4U3Rha2VkAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAMJAGYCBQtpbmRleEFtb3VudAUOaW5kZXhBdmFpbGFibGUJAAIBAiV5b3UgZG9uJ3QgaGF2ZSBpbmRleCB0b2tlbnMgYXZhaWxhYmxlAwkBCmlzU2h1dGRvd24ACQACAQITY29udHJhY3QgaXMgb24gc3RvcAkAzggCCQDOCAIFFHBvb2xUb2tlbklzc3VlUmVzdWx0CAkBC2NsYWltUmVzdWx0AQkBEUBleHRyTmF0aXZlKDEwNjIpAQUKYWRkcmVzc1N0cgJfMQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQJAGUCBQ5pbmRleEF2YWlsYWJsZQULaW5kZXhBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQICEmdsb2JhbF9pbmRleFN0YWtlZAkAZQIJAQ10cnlHZXRJbnRlZ2VyAQISZ2xvYmFsX2luZGV4U3Rha2VkBQtpbmRleEFtb3VudAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFC2luZGV4QW1vdW50BQtwb29sVG9rZW5JZAUDbmlsAWkBEWNsYWltSW5kZXhSZXdhcmRzAAMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AJAQtjbGFpbVJlc3VsdAEIBQFpBmNhbGxlcgFpAQ1ldmFsdWF0ZUNsYWltAQR1c2VyCQCUCgIFA25pbAgJAQtjbGFpbVJlc3VsdAEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBHVzZXICXzIBaQETYWRkSW50ZXJlc3RFeHRlcm5hbAAEB2Fzc2V0SWQICQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAQGYW1vdW50CAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQHc3Rha2VUeAkBDXN0YWtlSWZOZWVkZWQCBQphc3NldElkU3RyBQZhbW91bnQDCQAAAgUHc3Rha2VUeAUHc3Rha2VUeAMJAAACCQDPCAIFCGFzc2V0SWRzBQdhc3NldElkBQR1bml0CQACAQIweW91IGNhbiBvbmx5IGFkZCBpbnRlcmVzdCBmb3IgYXNzZXRzIGluIHRoZSBwb29sBAZwYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQphc3NldElkU3RyBA1pbnRlcmVzdERlbHRhCQESY2FsY0ludGVyZXN0Q2hhbmdlAgUKYXNzZXRJZFN0cgUGYW1vdW50BAl1cGRQYXJhbXMJAJoKCAgFBnBhcmFtcwJfMQgFBnBhcmFtcwJfMggFBnBhcmFtcwJfMwkAZAIIBQZwYXJhbXMCXzQFDWludGVyZXN0RGVsdGEJAGQCCAUGcGFyYW1zAl81BQZhbW91bnQIBQZwYXJhbXMCXzYIBQZwYXJhbXMCXzcIBQZwYXJhbXMCXzgJAMwIAgkBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIFCmFzc2V0SWRTdHIFCXVwZFBhcmFtcwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBFG5vdGlmeVN0YWtpbmdQYXltZW50Agphc3NldElkU3RyBmFtb3VudAQHYXNzZXRJZAkBDWdldEFzc2V0Qnl0ZXMBBQphc3NldElkU3RyAwkAAAIJAM8IAgUIYXNzZXRJZHMFB2Fzc2V0SWQFBHVuaXQJAAIBAjB5b3UgY2FuIG9ubHkgYWRkIGludGVyZXN0IGZvciBhc3NldHMgaW4gdGhlIHBvb2wDCQECIT0CCQEMdHJ5R2V0U3RyaW5nAQkArAICAhdzdGF0aWNfc3Rha2luZ0NvbnRyYWN0XwUKYXNzZXRJZFN0cgkApQgBCAUBaQZjYWxsZXIJAAIBAiZjYW4gb25seSBiZSBpbnZva2VkIGJ5IHN0YWtlciBjb250cmFjdAQGcGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKYXNzZXRJZFN0cgQNaW50ZXJlc3REZWx0YQkBEmNhbGNJbnRlcmVzdENoYW5nZQIFCmFzc2V0SWRTdHIFBmFtb3VudAQJdXBkUGFyYW1zCQCaCggIBQZwYXJhbXMCXzEIBQZwYXJhbXMCXzIIBQZwYXJhbXMCXzMJAGQCCAUGcGFyYW1zAl80BQ1pbnRlcmVzdERlbHRhCQBkAggFBnBhcmFtcwJfNQUGYW1vdW50CAUGcGFyYW1zAl82CAUGcGFyYW1zAl83CAUGcGFyYW1zAl84CQDMCAIJARVzYXZlR2xvYmFsVG9rZW5QYXJhbXMCBQphc3NldElkU3RyBQl1cGRQYXJhbXMFA25pbAFpAQRzd2FwAghhc3NldE91dAdtaW5pbXVtBANwbXQDCQAAAgkAkAMBCAUBaQhwYXltZW50cwABCQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAJAAIBAiFwbGVhc2UgYXR0YWNoIGV4YWN0bHkgb25lIHBheW1lbnQECEFtb3VudEluCQEFdmFsdWUBCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQHQXNzZXRJbggFA3BtdAdhc3NldElkBAhBc3NldE91dAkBDWdldEFzc2V0Qnl0ZXMBBQhhc3NldE91dAQHYXNzZXRJbgkBDmdldEFzc2V0U3RyaW5nAQUHQXNzZXRJbgQHc2NhbGVJbgkAaQIFBlNjYWxlOAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUHYXNzZXRJbgIGX3NjYWxlBAhzY2FsZU91dAkAaQIFBlNjYWxlOAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUIYXNzZXRPdXQCBl9zY2FsZQQNYXNzZXRJblBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEJAQ5nZXRBc3NldFN0cmluZwEFB0Fzc2V0SW4EDmFzc2V0T3V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUIYXNzZXRPdXQEDkFzc2V0SW5CYWxhbmNlCAUNYXNzZXRJblBhcmFtcwJfMQQSQXNzZXRJbkZhY3RCYWxhbmNlCAUNYXNzZXRJblBhcmFtcwJfMgQRYXNzZXRJbkZlZXNFYXJuZWQIBQ1hc3NldEluUGFyYW1zAl8zBBhhc3NldEluTGFzdENoZWNrSW50ZXJlc3QIBQ1hc3NldEluUGFyYW1zAl80BA9Bc3NldE91dEJhbGFuY2UIBQ5hc3NldE91dFBhcmFtcwJfMQQTYXNzZXRPdXRGYWN0QmFsYW5jZQgFDmFzc2V0T3V0UGFyYW1zAl8yBBRBc3NldEluQmFsYW5jZVNjYWxlZAkAaAIFDkFzc2V0SW5CYWxhbmNlBQdzY2FsZUluBBVBc3NldE91dEJhbGFuY2VTY2FsZWQJAGgCBQ9Bc3NldE91dEJhbGFuY2UFCHNjYWxlT3V0BAtmZWVBbW91bnRJbgkAawMFCEFtb3VudEluBQNGZWUFCEZlZVNjYWxlBA1jbGVhbkFtb3VudEluCQBlAgUIQW1vdW50SW4FC2ZlZUFtb3VudEluBBNjbGVhbkFtb3VudEluU2NhbGVkCQBoAgUNY2xlYW5BbW91bnRJbgUHc2NhbGVJbgQKQW1vdW50T3V0MQkBEmNhbGN1bGF0ZU91dEFtb3VudAUFE2NsZWFuQW1vdW50SW5TY2FsZWQFB0Fzc2V0SW4FCEFzc2V0T3V0BRRBc3NldEluQmFsYW5jZVNjYWxlZAUVQXNzZXRPdXRCYWxhbmNlU2NhbGVkBAlBbW91bnRPdXQJAGsDBQpBbW91bnRPdXQxAAEFCHNjYWxlT3V0BBBBc3NldE91dEJhbGFuY2UyCQBlAgUPQXNzZXRPdXRCYWxhbmNlBQlBbW91bnRPdXQED0Fzc2V0SW5CYWxhbmNlMgkAZAIFDkFzc2V0SW5CYWxhbmNlBQ1jbGVhbkFtb3VudEluAwkAZgIFB21pbmltdW0FCUFtb3VudE91dAkAAgECKWFtb3VudCB0byByZWNpZXZlIGlzIGxvd2VyIHRoYW4gZ2l2ZW4gb25lAwkAAAIFCEFzc2V0T3V0BQdBc3NldEluCQACAQIYdGhpcyBzd2FwIGlzIG5vdCBhbGxvd2VkAwkAZgIAAAkAZQIFE2Fzc2V0T3V0RmFjdEJhbGFuY2UFCUFtb3VudE91dAkAAgECG2NvbnRyYWN0IGlzIG91dCBvZiByZXNlcnZlcwMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3ADCQELdmFsdWVPckVsc2UCCQCbCAIFD3Bvb2xzSHViQWRkcmVzcwkArAICAhJnbG9iYWxfc2h1dGRvd25Jbl8FB2Fzc2V0SW4HCQACAQIbdG9rZW4gSU4gdHJhZGVzIGFyZSBzdG9wcGVkAwkBC3ZhbHVlT3JFbHNlAgkAmwgCBQ9wb29sc0h1YkFkZHJlc3MJAKwCAgITZ2xvYmFsX3NodXRkb3duT3V0XwUIYXNzZXRPdXQHCQACAQIcdG9rZW4gT1VUIHRyYWRlcyBhcmUgc3RvcHBlZAQLcHJvdG9jb2xGZWUJAGsDBQtmZWVBbW91bnRJbgAFAAoEBWxwRmVlCQBlAgULZmVlQW1vdW50SW4FC3Byb3RvY29sRmVlBA1pbnRlcmVzdERlbHRhCQESY2FsY0ludGVyZXN0Q2hhbmdlAgUHYXNzZXRJbgUFbHBGZWUEB3N0YWtlVHgJAQ1zdGFrZUlmTmVlZGVkAgUHYXNzZXRJbgkAZAIFDWNsZWFuQW1vdW50SW4FBWxwRmVlAwkAAAIFB3N0YWtlVHgFB3N0YWtlVHgECXVuc3Rha2VUeAkBD3Vuc3Rha2VJZk5lZWRlZAIFCGFzc2V0T3V0BQlBbW91bnRPdXQDCQAAAgUJdW5zdGFrZVR4BQl1bnN0YWtlVHgEDG5ld0JhbGFuY2VJbgUPQXNzZXRJbkJhbGFuY2UyBA1uZXdCYWxhbmNlT3V0BRBBc3NldE91dEJhbGFuY2UyBBJhc3NldEluU2VsbG9mZkRhdGEJAQ51cGRTZWxsb2ZmRGF0YQQFB2Fzc2V0SW4FDWNsZWFuQW1vdW50SW4FDkFzc2V0SW5CYWxhbmNlCQCVCgMIBQ1hc3NldEluUGFyYW1zAl82CAUNYXNzZXRJblBhcmFtcwJfNwgFDWFzc2V0SW5QYXJhbXMCXzgEE2Fzc2V0T3V0U2VsbG9mZkRhdGEJAQ51cGRTZWxsb2ZmRGF0YQQFCGFzc2V0T3V0CQEBLQEFCUFtb3VudE91dAUPQXNzZXRPdXRCYWxhbmNlCQCVCgMIBQ5hc3NldE91dFBhcmFtcwJfNggFDmFzc2V0T3V0UGFyYW1zAl83CAUOYXNzZXRPdXRQYXJhbXMCXzgEEmFzc2V0SW5GaW5hbFBhcmFtcwkAmgoIBQxuZXdCYWxhbmNlSW4JAGQCBRJBc3NldEluRmFjdEJhbGFuY2UFDWNsZWFuQW1vdW50SW4JAGQCBRFhc3NldEluRmVlc0Vhcm5lZAUFbHBGZWUJAGQCBRhhc3NldEluTGFzdENoZWNrSW50ZXJlc3QFDWludGVyZXN0RGVsdGEIBQ1hc3NldEluUGFyYW1zAl81CAUSYXNzZXRJblNlbGxvZmZEYXRhAl8xCAUSYXNzZXRJblNlbGxvZmZEYXRhAl8yCAUSYXNzZXRJblNlbGxvZmZEYXRhAl8zBBNhc3NldE91dEZpbmFsUGFyYW1zCQCaCggFDW5ld0JhbGFuY2VPdXQJAGUCBRNhc3NldE91dEZhY3RCYWxhbmNlBQlBbW91bnRPdXQIBQ5hc3NldE91dFBhcmFtcwJfMwgFDmFzc2V0T3V0UGFyYW1zAl80CAUOYXNzZXRPdXRQYXJhbXMCXzUIBRNhc3NldE91dFNlbGxvZmZEYXRhAl8xCAUTYXNzZXRPdXRTZWxsb2ZmRGF0YQJfMggFE2Fzc2V0T3V0U2VsbG9mZkRhdGECXzMEDWFzc2V0SW5DaGFuZ2UJARVzYXZlR2xvYmFsVG9rZW5QYXJhbXMCBQdhc3NldEluBRJhc3NldEluRmluYWxQYXJhbXMEDmFzc2V0T3V0Q2hhbmdlCQEVc2F2ZUdsb2JhbFRva2VuUGFyYW1zAgUIYXNzZXRPdXQFE2Fzc2V0T3V0RmluYWxQYXJhbXMEC2ZlZUFzc2V0U3RyCQEMdHJ5R2V0U3RyaW5nAQIPc3RhdGljX2ZlZVRva2VuBA5mZWVBc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFC2ZlZUFzc2V0U3RyBA9mZWVUb2tlbkJhbGFuY2UIBQ5mZWVBc3NldFBhcmFtcwJfMQQPdm9sdW1lVXNkVXBkYXRlCQERY2FsY3VsYXRlVXNkVmFsdWUEBQdBc3NldEluBQhBbW91bnRJbgUOQXNzZXRJbkJhbGFuY2UFD2ZlZVRva2VuQmFsYW5jZQkAlAoCCQDMCAIFDWFzc2V0SW5DaGFuZ2UJAMwIAgUOYXNzZXRPdXRDaGFuZ2UJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQlBbW91bnRPdXQFCEFzc2V0T3V0CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhFnbG9iYWxfdm9sdW1lX3VzZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQIRZ2xvYmFsX3ZvbHVtZV91c2QFD3ZvbHVtZVVzZFVwZGF0ZQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQtmZWVzQWRkcmVzcwULcHJvdG9jb2xGZWUJAQ1nZXRBc3NldEJ5dGVzAQUHYXNzZXRJbgUDbmlsBQlBbW91bnRPdXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEMc3dhcFJlYWRPbmx5Awdhc3NldEluCGFzc2V0T3V0CEFtb3VudEluBAdBc3NldEluCQENZ2V0QXNzZXRCeXRlcwEFB2Fzc2V0SW4ECEFzc2V0T3V0CQENZ2V0QXNzZXRCeXRlcwEFCGFzc2V0T3V0BAdzY2FsZUluCQBpAgUGU2NhbGU4CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQdhc3NldEluAgZfc2NhbGUECHNjYWxlT3V0CQBpAgUGU2NhbGU4CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQhhc3NldE91dAIGX3NjYWxlBA5mZWVBc3NldE91dFN0cgkBDHRyeUdldFN0cmluZwECD3N0YXRpY19mZWVUb2tlbgQLZmVlQXNzZXRPdXQDCQAAAgUOZmVlQXNzZXRPdXRTdHICAAULdXNkbkFzc2V0SWQJAQ1nZXRBc3NldEJ5dGVzAQUOZmVlQXNzZXRPdXRTdHIEDWFzc2V0SW5QYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBCQEOZ2V0QXNzZXRTdHJpbmcBBQdBc3NldEluBA5hc3NldE91dFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCGFzc2V0T3V0BA5Bc3NldEluQmFsYW5jZQgFDWFzc2V0SW5QYXJhbXMCXzEEEkFzc2V0SW5GYWN0QmFsYW5jZQgFDWFzc2V0SW5QYXJhbXMCXzIEEWFzc2V0SW5GZWVzRWFybmVkCAUNYXNzZXRJblBhcmFtcwJfMwQYYXNzZXRJbkxhc3RDaGVja0ludGVyZXN0CAUNYXNzZXRJblBhcmFtcwJfNAQPQXNzZXRPdXRCYWxhbmNlCAUOYXNzZXRPdXRQYXJhbXMCXzEEE2Fzc2V0T3V0RmFjdEJhbGFuY2UIBQ5hc3NldE91dFBhcmFtcwJfMgQUQXNzZXRJbkJhbGFuY2VTY2FsZWQJAGgCBQ5Bc3NldEluQmFsYW5jZQUHc2NhbGVJbgQVQXNzZXRPdXRCYWxhbmNlU2NhbGVkCQBoAgUPQXNzZXRPdXRCYWxhbmNlBQhzY2FsZU91dAQLZmVlQW1vdW50SW4JAGsDBQhBbW91bnRJbgUDRmVlBQhGZWVTY2FsZQQNY2xlYW5BbW91bnRJbgkAZQIFCEFtb3VudEluBQtmZWVBbW91bnRJbgQTY2xlYW5BbW91bnRJblNjYWxlZAkAaAIFDWNsZWFuQW1vdW50SW4FB3NjYWxlSW4ECkFtb3VudE91dDEJARJjYWxjdWxhdGVPdXRBbW91bnQFBRNjbGVhbkFtb3VudEluU2NhbGVkBQdBc3NldEluBQhBc3NldE91dAUUQXNzZXRJbkJhbGFuY2VTY2FsZWQFFUFzc2V0T3V0QmFsYW5jZVNjYWxlZAQJQW1vdW50T3V0CQBrAwUKQW1vdW50T3V0MQABBQhzY2FsZU91dAQQQXNzZXRPdXRCYWxhbmNlMgkAZQIFD0Fzc2V0T3V0QmFsYW5jZQUJQW1vdW50T3V0BA9Bc3NldEluQmFsYW5jZTIJAGQCBQ5Bc3NldEluQmFsYW5jZQUNY2xlYW5BbW91bnRJbgMJAAACBQhBc3NldE91dAUHQXNzZXRJbgkAAgECGHRoaXMgc3dhcCBpcyBub3QgYWxsb3dlZAMJAGYCAAAJAGUCCAUOYXNzZXRPdXRQYXJhbXMCXzIFCUFtb3VudE91dAkAAgECG2NvbnRyYWN0IGlzIG91dCBvZiByZXNlcnZlcwMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AJAJQKAgUDbmlsBQlBbW91bnRPdXQBaQERdHJhbnNmZXJPd25lcnNoaXABD25ld093bmVyQWRkcmVzcwMJAQIhPQIJAKUIAQgFAWkGY2FsbGVyCQEMdHJ5R2V0U3RyaW5nAQIQc3RhdGljX3Bvb2xPd25lcgkAAgECJ3RoaXMgY2FsbCBhdmFpbGFibGUgb25seSBmb3IgcG9vbCBvd25lcgkAzAgCCQELU3RyaW5nRW50cnkCAhBzdGF0aWNfcG9vbE93bmVyBQ9uZXdPd25lckFkZHJlc3MFA25pbAFpAQZzZXRGZWUBBm5ld0ZlZQMJAQIhPQIJAKUIAQgFAWkGY2FsbGVyCQEMdHJ5R2V0U3RyaW5nAQIQc3RhdGljX3Bvb2xPd25lcgkAAgECJ3RoaXMgY2FsbCBhdmFpbGFibGUgb25seSBmb3IgcG9vbCBvd25lcgkAzAgCCQEMSW50ZWdlckVudHJ5AgIKc3RhdGljX2ZlZQUGbmV3RmVlBQNuaWwBAnR4AQZ2ZXJpZnkABBBNVUxUSVNJR19BRERSRVNTCQCmCAECIzNNN3V6RDhyVDU0ZktRY1A0czQxN2lmMVZLVTh5cm9tRVAyBA1DT05UUkFDVF9UWVBFAgtSQU5HRURfUE9PTAMJAQIhPQIFEE1VTFRJU0lHX0FERFJFU1MFBHVuaXQEByRtYXRjaDAFAnR4AwkAAQIFByRtYXRjaDACFFNldFNjcmlwdFRyYW5zYWN0aW9uBAN0dHgFByRtYXRjaDAEC3NjcmlwdEhhc2hhCQDYBAEJAQV2YWx1ZQEJAPYDAQkBBXZhbHVlAQgFA3R0eAZzY3JpcHQEDmFwcHJvdmVkSGFzaGVzCQEFdmFsdWUBCQCdCAIJAQV2YWx1ZQEFEE1VTFRJU0lHX0FERFJFU1MJAKwCAgkArAICAgdzY3JpcHRfBQ1DT05UUkFDVF9UWVBFAgpfX2FwcHJvdmVkCQECIT0CCQCzCQIFDmFwcHJvdmVkSGFzaGVzBQtzY3JpcHRIYXNoYQUEdW5pdAQDb3R4BQckbWF0Y2gwCQELdmFsdWVPckVsc2UCCQCbCAIJAQV2YWx1ZQEFEE1VTFRJU0lHX0FERFJFU1MJAKwCAgkArAICCQCsAgIJAKUIAQUEdGhpcwIBXwkA2AQBCAUDb3R4AmlkAgpfX2FwcHJvdmVkBwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUMbWFzdGVyUHViS2V58gA6iw==", "height": 506897, "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.6.1 PROD-refactor"
5+
6+let configStr = valueOrElse(getString(this, "configAddress"), "3PMoEibdLeWqcURQ8351XhaWwyacDc7G4e5")
7+
8+let CONFIG_ADDRESS = if ((configStr == ""))
9+ then this
10+ else Address(fromBase58String(configStr))
11+
12+let AssetsWeightsDecimals = 4
13+
14+let Scale = 10000
15+
16+let Scale8 = 100000000
17+
18+let Scale8_BI = toBigInt(Scale8)
19+
20+let Scale12 = 1000000000000
21+
22+let Scale16 = 10000000000000000
23+
24+let Scale16_BI = toBigInt(Scale16)
25+
26+let FeeScale = 10000
27+
28+let PoolTokenDecimals = 8
29+
30+let PoolTokenScale = pow(10, 0, PoolTokenDecimals, 0, 0, HALFUP)
31+
32+let MIN_STEPS_AMOUNT = valueOrElse(getInteger(CONFIG_ADDRESS, "min_steps_amount"), 1)
33+
34+let MAX_STEPS_AMOUNT = valueOrElse(getInteger(CONFIG_ADDRESS, "max_steps_amount"), 500)
35+
36+let MIN_STEPS_INTERVAL = valueOrElse(getInteger(CONFIG_ADDRESS, "min_steps_interval"), 1)
37+
38+let MAX_STEPS_INTERVAL = valueOrElse(getInteger(CONFIG_ADDRESS, "max_steps_interval"), 10000)
39+
40+let MIN_WEIGHT = valueOrElse(getInteger(CONFIG_ADDRESS, "min_weight"), 100)
41+
42+let MAX_WEIGHT = valueOrElse(getInteger(CONFIG_ADDRESS, "max_weight"), 9900)
43+
44+func tryGetInteger (key) = match getInteger(this, key) {
45+ case b: Int =>
46+ b
47+ case _ =>
48+ 0
49+}
50+
51+
52+func tryGetBinary (key) = match getBinary(this, key) {
53+ case b: ByteVector =>
54+ b
55+ case _ =>
56+ base58''
57+}
58+
59+
60+func tryGetString (key) = match getString(this, key) {
61+ case b: String =>
62+ b
63+ case _ =>
64+ ""
65+}
66+
67+
68+func tryGetStringOrThrow (key) = match getString(this, key) {
69+ case b: String =>
70+ b
71+ case _ =>
72+ throw(("no such key in data storage: " + key))
73+}
74+
75+
76+func getAssetString (assetId) = match assetId {
77+ case b: ByteVector =>
78+ toBase58String(b)
79+ case _ =>
80+ "WAVES"
81+}
82+
83+
84+func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
85+ then unit
86+ else fromBase58String(assetIdStr)
87+
88+
89+func getTokenBalance (assetId) = match assetId {
90+ case t: ByteVector =>
91+ assetBalance(this, t)
92+ case _ =>
93+ wavesBalance(this).available
94+}
95+
96+
97+func addAssetBytesToList (accum,item) = (accum ++ [getAssetBytes(item)])
98+
99+
100+func addAssetWeightToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_weight"))])
101+
102+
103+func addAssetWeightToStrList (accum,item) = (accum ++ [toString(tryGetInteger((("static_" + item) + "_weight")))])
104+
105+
106+func addAssetDecimalsToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_decimals"))])
107+
108+
109+func addAssetScaleToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_scale"))])
110+
111+
112+func addIntToList (accum,item) = (accum ++ [parseIntValue(item)])
113+
114+
115+func parstStrToIntList (s) = {
116+ func f (accum,next) = (accum ++ [parseIntValue(next)])
117+
118+ let $l = split(s, ",")
119+ let $s = size($l)
120+ let $acc0 = nil
121+ func $f0_1 ($a,$i) = if (($i >= $s))
122+ then $a
123+ else f($a, $l[$i])
124+
125+ func $f0_2 ($a,$i) = if (($i >= $s))
126+ then $a
127+ else throw("List size exceeds 10")
128+
129+ $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)
130+ }
131+
132+
133+let usdnAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdnAssetIdStr"), "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
134+
135+let puzzleAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "puzzleAssetIdStr"), "HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS")
136+
137+let usdtAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdtAssetIdStr"), "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ")
138+
139+let usdtPptAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdtPptAssetIdStr"), "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi")
140+
141+let romeAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "romeAssetIdStr"), "AP4Cb5xLYGH6ZigHreCZHoXpQTWDkPsG2BHqfDUx6taJ")
142+
143+let wavesAssetIdStr = "WAVES"
144+
145+let usdnAssetId = fromBase58String(usdnAssetIdStr)
146+
147+let puzzleAssetId = fromBase58String(puzzleAssetIdStr)
148+
149+let usdtAssetId = fromBase58String(usdtAssetIdStr)
150+
151+let usdtPptAssetId = fromBase58String(usdtPptAssetIdStr)
152+
153+let romeAssetId = fromBase58String(romeAssetIdStr)
154+
155+let wavesAssetId = unit
156+
157+let supportedFeeAssetsStr = [usdnAssetIdStr, puzzleAssetIdStr, usdtAssetIdStr, usdtPptAssetIdStr, wavesAssetIdStr, romeAssetIdStr]
158+
159+let parentPoolAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "parentPoolAddress"), "3PFDgzu1UtswAkCMxqqQjbTeHaX4cMab8Kh")))
160+
161+let masterAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "masterAddress"), "3PLjwHcz9NEuaTo63NZR9B9okQiKQxZSbmf")))
162+
163+let masterPubKey = fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "masterPubKey"), "2jTJGqHSopyj5d1cjbUe6f2jXqGMHE412cy3vGwYoRbP"))
164+
165+let oracleAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "oracleAddress"), "3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t")))
166+
167+let stakingAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "stakingAddress"), "3PFTbywqxtFfukX3HyT881g4iW5K4QL3FAS")))
168+
169+let feesAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "feesAddress"), "3PFWAVKmXjfHXyzJb12jCbhP4Uhi9t4uWiD")))
170+
171+let poolsHubAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "poolsHubAddress"), "3P5RGYyCnELF8JTPxgX54dBGzwkQMKUJ5H7")))
172+
173+let shutdownAddressStr = valueOrElse(getString(CONFIG_ADDRESS, "shutdownAddress"), "3PEpv9hRFWEEBU22WRnLsw1bH4YGtcU728o")
174+
175+let layer2Addresses = valueOrElse(getString(CONFIG_ADDRESS, "layer2Addresses"), "3PR1Qvi9mHT35SwWEkLSqqE2L8thiPLdVWU,3PQoBfUKHkJAeGWhooLP7WS8ovb54av9Jp2")
176+
177+let govAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "govAddress"), "3P6uro9xCsE8te78QZjzqy7aq8natSzdceC")))
178+
179+let coldMasterAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "coldMasterAddress"), "3PK9nhPfPbMBygB9ZgHVMHaQbSoojwrBfxj")))
180+
181+let T = tryGetInteger("static_tokensAmount")
182+
183+let assetIds = {
184+ let $l = split(tryGetString("static_tokenIds"), ",")
185+ let $s = size($l)
186+ let $acc0 = nil
187+ func $f0_1 ($a,$i) = if (($i >= $s))
188+ then $a
189+ else addAssetBytesToList($a, $l[$i])
190+
191+ func $f0_2 ($a,$i) = if (($i >= $s))
192+ then $a
193+ else throw("List size exceeds 10")
194+
195+ $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)
196+ }
197+
198+let AssetsWeights = {
199+ let $l = assetIds
200+ let $s = size($l)
201+ let $acc0 = nil
202+ func $f1_1 ($a,$i) = if (($i >= $s))
203+ then $a
204+ else addAssetWeightToList($a, $l[$i])
205+
206+ func $f1_2 ($a,$i) = if (($i >= $s))
207+ then $a
208+ else throw("List size exceeds 10")
209+
210+ $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)
211+ }
212+
213+let Decimals = {
214+ let $l = assetIds
215+ let $s = size($l)
216+ let $acc0 = nil
217+ func $f2_1 ($a,$i) = if (($i >= $s))
218+ then $a
219+ else addAssetDecimalsToList($a, $l[$i])
220+
221+ func $f2_2 ($a,$i) = if (($i >= $s))
222+ then $a
223+ else throw("List size exceeds 10")
224+
225+ $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)
226+ }
227+
228+let Scales = {
229+ let $l = assetIds
230+ let $s = size($l)
231+ let $acc0 = nil
232+ func $f3_1 ($a,$i) = if (($i >= $s))
233+ then $a
234+ else addAssetScaleToList($a, $l[$i])
235+
236+ func $f3_2 ($a,$i) = if (($i >= $s))
237+ then $a
238+ else throw("List size exceeds 10")
239+
240+ $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)
241+ }
242+
243+let Fee = tryGetInteger("static_fee")
244+
245+let earnedAssets = assetIds
246+
247+func _get (assetId,param) = tryGetInteger(((("global_" + assetId) + "_") + param))
248+
249+
250+func _get_feesEarned (assetId) = tryGetInteger(("global_feesEarned_" + assetId))
251+
252+
253+func _get_lastCheck_interest (assetId) = tryGetInteger((("global_lastCheck_" + assetId) + "_interest"))
254+
255+
256+func _get_extraEarned (assetId) = tryGetInteger(("global_extraEarned_" + assetId))
257+
258+
259+func loadGlobalTokenParams (assetId) = match getString(("globalParams_" + assetId)) {
260+ case p: String =>
261+ let params = split(p, "__")
262+ $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]))
263+ case _ =>
264+ $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"))
265+}
266+
267+
268+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)], "__"))
269+
270+
271+func isShutdown () = {
272+ let shutdownAddress = addressFromString(shutdownAddressStr)
273+ if ((shutdownAddress == unit))
274+ then false
275+ else match getBoolean(value(shutdownAddress), "is_shutdown") {
276+ case x: Boolean =>
277+ x
278+ case _ =>
279+ false
280+ }
281+ }
282+
283+
284+func getFactBalance (assetIdStr) = {
285+ let assetParams = loadGlobalTokenParams(assetIdStr)
286+ assetParams._2
287+ }
288+
289+
290+func getCurrentTokenBalance (tokenNum) = {
291+ let tokenIdStr = getAssetString(assetIds[tokenNum])
292+ let tokenParams = loadGlobalTokenParams(tokenIdStr)
293+ tokenParams._1
294+ }
295+
296+
297+func stakeIfNeeded (assetIdStr,amount) = {
298+ let stakeTx = if ((tryGetString(("static_stakingContract_" + assetIdStr)) != ""))
299+ then invoke(addressFromStringValue(tryGetString(("static_stakingContract_" + assetIdStr))), "stake", nil, [AttachedPayment(getAssetBytes(assetIdStr), amount)])
300+ else unit
301+ if ((stakeTx == stakeTx))
302+ then true
303+ else throw("Strict value is not equal to itself.")
304+ }
305+
306+
307+func unstakeIfNeeded (assetIdStr,amount) = {
308+ let unstakeTx = if ((tryGetString(("static_stakingContract_" + assetIdStr)) != ""))
309+ then invoke(addressFromStringValue(tryGetString(("static_stakingContract_" + assetIdStr))), "unstake", [amount], nil)
310+ else unit
311+ if ((unstakeTx == unstakeTx))
312+ then true
313+ else throw("Strict value is not equal to itself.")
314+ }
315+
316+
317+func burnIndexIfNeeded (amount) = {
318+ let indexIdStr = tryGetString("static_poolToken_idStr")
319+ if ((indexIdStr == ""))
320+ then nil
321+ else if ((assetInfo(fromBase58String(indexIdStr)) == unit))
322+ then nil
323+ else [Burn(fromBase58String(indexIdStr), amount)]
324+ }
325+
326+
327+func mintIndexIfNeeded (amount) = {
328+ let indexIdStr = tryGetString("static_poolToken_idStr")
329+ if ((indexIdStr == ""))
330+ then nil
331+ else if ((assetInfo(fromBase58String(indexIdStr)) == unit))
332+ then nil
333+ else [Reissue(fromBase58String(indexIdStr), amount, true)]
334+ }
335+
336+
337+func getKMult () = match getInteger("static_KMult") {
338+ case x: Int =>
339+ x
340+ case _ =>
341+ Scale16
342+}
343+
344+
345+func saveCurrentWeights () = {
346+ let assetIdsLi = split(tryGetString("static_tokenIds"), ",")
347+ func s (accum,assetId) = (accum ++ [IntegerEntry(("rebalance_startWeight_" + assetId), tryGetInteger((("static_" + assetId) + "_weight")))])
348+
349+ let $l = assetIdsLi
350+ let $s = size($l)
351+ let $acc0 = nil
352+ func $f4_1 ($a,$i) = if (($i >= $s))
353+ then $a
354+ else s($a, $l[$i])
355+
356+ func $f4_2 ($a,$i) = if (($i >= $s))
357+ then $a
358+ else throw("List size exceeds 10")
359+
360+ $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)
361+ }
362+
363+
364+func getVirtualPoolTokenAmount () = fraction(tryGetInteger("global_poolToken_amount"), getKMult(), Scale16)
365+
366+
367+func calculatePIssued (amount,tokenId) = {
368+ let Psupply = getVirtualPoolTokenAmount()
369+ let Balance = getFactBalance(getAssetString(tokenId))
370+ let t1 = fraction(amount, Psupply, Balance, DOWN)
371+ t1
372+ }
373+
374+
375+func getMinPIssued (payments) = {
376+ func handler (accum,current) = if ((getFactBalance(getAssetString(current.assetId)) == 0))
377+ then accum
378+ else {
379+ let PIssued = calculatePIssued(current.amount, current.assetId)
380+ if ((PIssued == 0))
381+ then throw("one of the tokens amounts is too low")
382+ else if (if ((accum == 0))
383+ then true
384+ else (accum > PIssued))
385+ then PIssued
386+ else accum
387+ }
388+
389+ let minPIssed = {
390+ let $l = payments
391+ let $s = size($l)
392+ let $acc0 = 0
393+ func $f4_1 ($a,$i) = if (($i >= $s))
394+ then $a
395+ else handler($a, $l[$i])
396+
397+ func $f4_2 ($a,$i) = if (($i >= $s))
398+ then $a
399+ else throw("List size exceeds 10")
400+
401+ $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)
402+ }
403+ minPIssed
404+ }
405+
406+
407+func getPriceFromOracle (assetIdStr) = match getInteger(oracleAddress, (assetIdStr + "_twap5B")) {
408+ case x: Int =>
409+ x
410+ case _ =>
411+ 0
412+}
413+
414+
415+func calculateUsdValue (assetId,amount,aBalance,feeAssetBalance) = {
416+ let assetWeight = tryGetInteger((("static_" + getAssetString(assetId)) + "_weight"))
417+ let feeAssetStr = tryGetString("static_feeToken")
418+ let feeAssetScale = getIntegerValue(this, (("static_" + feeAssetStr) + "_scale"))
419+ let feeAssetNum = value(indexOf(assetIds, getAssetBytes(feeAssetStr)))
420+ let feeAssetWeight = AssetsWeights[feeAssetNum]
421+ let _amount = (toBigInt(amount) * Scale8_BI)
422+ let _feeAssetData = (toBigInt(feeAssetBalance) / toBigInt(feeAssetWeight))
423+ let _assetData = fraction(toBigInt(aBalance), Scale8_BI, toBigInt(assetWeight))
424+ let valInFeeAsset = toInt(fraction(_amount, _feeAssetData, _assetData))
425+ let feeAssetPrice = getPriceFromOracle(feeAssetStr)
426+ fraction(valInFeeAsset, feeAssetPrice, feeAssetScale)
427+ }
428+
429+
430+func calcAvgConcentration () = {
431+ func f (accum,next) = {
432+ let assetIdStr = getAssetString(next)
433+ let weight = tryGetInteger((("static_" + assetIdStr) + "_weight"))
434+ let assetParams = loadGlobalTokenParams(assetIdStr)
435+ let assetFactBalance = assetParams._2
436+ let assetVirtBalance = assetParams._1
437+ $Tuple2((accum._1 + fraction(assetFactBalance, weight, assetVirtBalance)), (accum._2 + weight))
438+ }
439+
440+ let $l = assetIds
441+ let $s = size($l)
442+ let $acc0 = $Tuple2(0, 0)
443+ func $f4_1 ($a,$i) = if (($i >= $s))
444+ then $a
445+ else f($a, $l[$i])
446+
447+ func $f4_2 ($a,$i) = if (($i >= $s))
448+ then $a
449+ else throw("List size exceeds 10")
450+
451+ $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)
452+ }
453+
454+
455+func checkTokensValidity (payments) = {
456+ func handler1 (accum,payment) = (accum ++ [payment.assetId])
457+
458+ let ids = {
459+ let $l = payments
460+ let $s = size($l)
461+ let $acc0 = nil
462+ func $f4_1 ($a,$i) = if (($i >= $s))
463+ then $a
464+ else handler1($a, $l[$i])
465+
466+ func $f4_2 ($a,$i) = if (($i >= $s))
467+ then $a
468+ else throw("List size exceeds 10")
469+
470+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
471+ }
472+ if ((ids == ids))
473+ then {
474+ func handler2 (accum,assetId) = if ((indexOf(ids, assetId) != unit))
475+ then (accum + 1)
476+ else throw(("asset not attached: " + getAssetString(assetId)))
477+
478+ let checks = {
479+ let $l = assetIds
480+ let $s = size($l)
481+ let $acc0 = 0
482+ func $f5_1 ($a,$i) = if (($i >= $s))
483+ then $a
484+ else handler2($a, $l[$i])
485+
486+ func $f5_2 ($a,$i) = if (($i >= $s))
487+ then $a
488+ else throw("List size exceeds 10")
489+
490+ $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)
491+ }
492+ if ((checks == checks))
493+ then true
494+ else throw("Strict value is not equal to itself.")
495+ }
496+ else throw("Strict value is not equal to itself.")
497+ }
498+
499+
500+func handlePoolTokensAdd (PIssued,payments,userAddress,needChange) = {
501+ func getTokenPaymentAmount (tokenId) = {
502+ func handler (accum,payment) = if ((payment.assetId == tokenId))
503+ then payment.amount
504+ else accum
505+
506+ let $l = payments
507+ let $s = size($l)
508+ let $acc0 = 0
509+ func $f4_1 ($a,$i) = if (($i >= $s))
510+ then $a
511+ else handler($a, $l[$i])
512+
513+ func $f4_2 ($a,$i) = if (($i >= $s))
514+ then $a
515+ else throw("List size exceeds 10")
516+
517+ $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)
518+ }
519+
520+ func handleTokenChange (accum,tokenId) = {
521+ let assetIdStr = getAssetString(tokenId)
522+ let assetParams = loadGlobalTokenParams(assetIdStr)
523+ let paymentAmount = getTokenPaymentAmount(tokenId)
524+ let Bk = assetParams._2
525+ let PSupply = getVirtualPoolTokenAmount()
526+ let tokenDecimals = tryGetInteger((("static_" + assetIdStr) + "_scale"))
527+ let a1 = fraction((toBigInt((PSupply + PIssued)) * toBigInt(Scale8)), toBigInt(tokenDecimals), toBigInt(PSupply), CEILING)
528+ let Dk = toInt(fraction((a1 - (toBigInt(tokenDecimals) * toBigInt(Scale8))), toBigInt(Bk), (toBigInt(tokenDecimals) * toBigInt(Scale8)), CEILING))
529+ let toReturn = (paymentAmount - Dk)
530+ let stakeTx = stakeIfNeeded(assetIdStr, Dk)
531+ if ((stakeTx == stakeTx))
532+ then {
533+ let t = if (if (needChange)
534+ then (toReturn > 0)
535+ else false)
536+ then [ScriptTransfer(userAddress, toReturn, tokenId)]
537+ else nil
538+ let selloffStartBalance = if ((assetParams._8 != ((height / 100) * 100)))
539+ then assetParams._7
540+ else fraction(assetParams._7, (PSupply + PIssued), PSupply)
541+ let assetParamsUpd = $Tuple8(fraction(assetParams._1, (PSupply + PIssued), PSupply, HALFEVEN), (assetParams._2 + Dk), assetParams._3, assetParams._4, assetParams._5, assetParams._6, selloffStartBalance, assetParams._8)
542+ ((accum ++ t) ++ [saveGlobalTokenParams(assetIdStr, assetParamsUpd)])
543+ }
544+ else throw("Strict value is not equal to itself.")
545+ }
546+
547+ let $l = assetIds
548+ let $s = size($l)
549+ let $acc0 = nil
550+ func $f4_1 ($a,$i) = if (($i >= $s))
551+ then $a
552+ else handleTokenChange($a, $l[$i])
553+
554+ func $f4_2 ($a,$i) = if (($i >= $s))
555+ then $a
556+ else throw("List size exceeds 10")
557+
558+ $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)
559+ }
560+
561+
562+func calcMintedWithOneToken (assetAddedIdStr,amount) = {
563+ let PSupply = getVirtualPoolTokenAmount()
564+ let assetParams = loadGlobalTokenParams(assetAddedIdStr)
565+ let assetFactBalance = assetParams._2
566+ let assetVirtBalance = assetParams._1
567+ let assetWeight = tryGetInteger((("static_" + assetAddedIdStr) + "_weight"))
568+ let assetScale = tryGetInteger((("static_" + assetAddedIdStr) + "_scale"))
569+ let assetDecimals = tryGetInteger((("static_" + assetAddedIdStr) + "_decimals"))
570+ let PIssuedNoMultiplier = fraction(PSupply, (toInt(pow(toBigInt((assetScale + fraction(amount, assetScale, assetVirtBalance))), assetDecimals, toBigInt(assetWeight), 4, 8, DOWN)) - Scale8), Scale8)
571+ let avgConc = calcAvgConcentration()
572+ let PIssued = fraction(PIssuedNoMultiplier, avgConc._2, avgConc._1)
573+ let assetParamsUpd = $Tuple8((assetVirtBalance + amount), (assetFactBalance + amount), assetParams._3, assetParams._4, assetParams._5, assetParams._6, assetParams._7, assetParams._8)
574+ $Tuple2([saveGlobalTokenParams(assetAddedIdStr, assetParamsUpd)], PIssued)
575+ }
576+
577+
578+func calcRedeemWithOneToken (assetOutIdStr,PRedeemed) = {
579+ let PSupply = getVirtualPoolTokenAmount()
580+ let assetParams = loadGlobalTokenParams(assetOutIdStr)
581+ let assetFactBalance = assetParams._2
582+ let assetVirtBalance = assetParams._1
583+ let assetWeight = tryGetInteger((("static_" + assetOutIdStr) + "_weight"))
584+ let assetScale = tryGetInteger((("static_" + assetOutIdStr) + "_scale"))
585+ let assetDecimals = tryGetInteger((("static_" + assetOutIdStr) + "_decimals"))
586+ let amountOutNoMulitplier = fraction(assetVirtBalance, (Scale8 - toInt(pow(toBigInt((assetScale - fraction(PRedeemed, assetScale, PSupply))), assetDecimals, toBigInt(fraction(10000, 10000, assetWeight)), 4, 8, DOWN))), Scale8)
587+ let avgConc = calcAvgConcentration()
588+ let amountOut = fraction(amountOutNoMulitplier, avgConc._1, avgConc._2)
589+ if ((amountOut > assetFactBalance))
590+ then throw("no available fact liquidity to withdraw in one token")
591+ else {
592+ let assetParamsUpd = $Tuple8((assetVirtBalance - amountOut), (assetFactBalance - amountOut), assetParams._3, assetParams._4, assetParams._5, assetParams._6, assetParams._7, assetParams._8)
593+ $Tuple2([saveGlobalTokenParams(assetOutIdStr, assetParamsUpd)], amountOut)
594+ }
595+ }
596+
597+
598+func handlePoolTokensRedeem (PRedeemed,userAddress) = {
599+ func handleTokenRedeem (accum,tokenId) = {
600+ let assetIdStr = getAssetString(tokenId)
601+ let assetParams = loadGlobalTokenParams(assetIdStr)
602+ let Bk = assetParams._2
603+ let PSupply = getVirtualPoolTokenAmount()
604+ let tokenDecimals = tryGetInteger((("static_" + assetIdStr) + "_scale"))
605+ let psuppl = fraction((toBigInt((PSupply - PRedeemed)) * toBigInt(Scale8)), toBigInt(Scale8), toBigInt(PSupply), DOWN)
606+ let amount = toInt(fraction((toBigInt(Scale16) - psuppl), toBigInt(Bk), toBigInt(Scale16), HALFEVEN))
607+ let unstakeTx = unstakeIfNeeded(assetIdStr, amount)
608+ if ((unstakeTx == unstakeTx))
609+ then {
610+ let selloffStartBalance = if ((assetParams._8 != ((height / 100) * 100)))
611+ then assetParams._7
612+ else fraction(assetParams._7, (PSupply - PRedeemed), PSupply)
613+ let assetParamsUpd = $Tuple8(fraction(assetParams._1, (PSupply - PRedeemed), PSupply), (assetParams._2 - amount), assetParams._3, assetParams._4, assetParams._5, assetParams._6, selloffStartBalance, assetParams._8)
614+ ((accum ++ [ScriptTransfer(userAddress, amount, tokenId)]) ++ [saveGlobalTokenParams(assetIdStr, assetParamsUpd)])
615+ }
616+ else throw("Strict value is not equal to itself.")
617+ }
618+
619+ let $l = assetIds
620+ let $s = size($l)
621+ let $acc0 = nil
622+ func $f4_1 ($a,$i) = if (($i >= $s))
623+ then $a
624+ else handleTokenRedeem($a, $l[$i])
625+
626+ func $f4_2 ($a,$i) = if (($i >= $s))
627+ then $a
628+ else throw("List size exceeds 10")
629+
630+ $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)
631+ }
632+
633+
634+func calculateOutAmount (AmountIn,assetIn,assetOut,BalanceIn,BalanceOut) = {
635+ let IndexIn = value(indexOf(assetIds, assetIn))
636+ let IndexOut = value(indexOf(assetIds, assetOut))
637+ if ((IndexIn == IndexOut))
638+ then AmountIn
639+ else fraction(BalanceOut, ((Scale8 * Scale8) - toInt(pow(fraction((toBigInt(BalanceIn) * toBigInt(10000)), toBigInt((Scale8 * Scale8)), (toBigInt((BalanceIn + AmountIn)) * toBigInt(10000)), HALFUP), 16, toBigInt(fraction(AssetsWeights[IndexIn], 1000000000000, AssetsWeights[IndexOut])), 12, 16, CEILING))), (Scale8 * Scale8), HALFEVEN)
640+ }
641+
642+
643+func claimResult (address) = {
644+ let addressStr = toString(address)
645+ let indexAmount = tryGetInteger((addressStr + "_indexStaked"))
646+ let feeAssetStr = tryGetString("static_feeToken")
647+ let feeAssetParams = loadGlobalTokenParams(feeAssetStr)
648+ let feeTokenBalance = feeAssetParams._1
649+ func handler (accum,assetId) = {
650+ let assetIdStr = getAssetString(assetId)
651+ let assetParams = loadGlobalTokenParams(assetIdStr)
652+ let currentTokenInterest = assetParams._4
653+ let aBalance = assetParams._1
654+ let rewardAmount = fraction(indexAmount, (currentTokenInterest - tryGetInteger((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"))), Scale16)
655+ let unstakeInv = unstakeIfNeeded(assetIdStr, rewardAmount)
656+ if ((unstakeInv == unstakeInv))
657+ then {
658+ let transfer = if ((rewardAmount == 0))
659+ then nil
660+ else [ScriptTransfer(address, rewardAmount, assetId)]
661+ $Tuple2(((accum._1 ++ transfer) ++ [IntegerEntry((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"), currentTokenInterest)]), (accum._2 + calculateUsdValue(assetId, rewardAmount, aBalance, feeTokenBalance)))
662+ }
663+ else throw("Strict value is not equal to itself.")
664+ }
665+
666+ let accum = {
667+ let $l = earnedAssets
668+ let $s = size($l)
669+ let $acc0 = $Tuple2(nil, 0)
670+ func $f4_1 ($a,$i) = if (($i >= $s))
671+ then $a
672+ else handler($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+ $Tuple2((accum._1 ++ [IntegerEntry((addressStr + "_claimedRewardUSD"), (tryGetInteger((addressStr + "_claimedRewardUSD")) + accum._2)), IntegerEntry((addressStr + "_lastClaim"), lastBlock.timestamp)]), accum._2)
681+ }
682+
683+
684+func indexStakeResult (addressStr,amount) = {
685+ let li = claimResult(addressFromStringValue(addressStr))._1
686+ (li ++ [IntegerEntry((addressStr + "_indexStaked"), (tryGetInteger((addressStr + "_indexStaked")) + amount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") + amount))])
687+ }
688+
689+
690+func sum (accum,n) = (accum + parseIntValue(n))
691+
692+
693+func checkFeeAsset (accum,next) = if (if ((indexOf(supportedFeeAssetsStr, next) != unit))
694+ then (accum == "")
695+ else false)
696+ then next
697+ else accum
698+
699+
700+func calcInterestChange (assetIdStr,lpFee) = {
701+ let totalIndex = tryGetInteger("global_indexStaked")
702+ let interestDelta = fraction(lpFee, Scale16, totalIndex)
703+ interestDelta
704+ }
705+
706+
707+func updSelloffData (assetIdStr,amountIn,balance,selloffParams) = {
708+ let currentPeriod = ((height / 100) * 100)
709+ let prevPeriod = selloffParams._2
710+ let prevSelloff = if ((currentPeriod == prevPeriod))
711+ then selloffParams._1
712+ else 0
713+ let selloffStartBalance = if ((currentPeriod == prevPeriod))
714+ then selloffParams._3
715+ else balance
716+ let selloffDelta = fraction(Scale16, amountIn, selloffStartBalance)
717+ let maxSelloff = tryGetInteger((("static_" + assetIdStr) + "_maxSelloff"))
718+ if (if (((prevSelloff + selloffDelta) > maxSelloff))
719+ then (maxSelloff != 0)
720+ else false)
721+ then throw(("max selloff reached for this asset " + assetIdStr))
722+ else {
723+ let startH = if ((currentPeriod == prevPeriod))
724+ then prevPeriod
725+ else currentPeriod
726+ let startB = if ((currentPeriod == prevPeriod))
727+ then selloffParams._3
728+ else selloffStartBalance
729+ $Tuple3((prevSelloff + selloffDelta), startH, startB)
730+ }
731+ }
732+
733+
734+func getTmpRebalanceIds (newAssetIdsLi) = {
735+ let currentAssetIdsLi = split(tryGetString("static_tokenIds"), ",")
736+ let result = newAssetIdsLi
737+ func f (accum,assetId) = if ((indexOf(result, assetId) == unit))
738+ then (accum ++ [assetId])
739+ else accum
740+
741+ let $l = currentAssetIdsLi
742+ let $s = size($l)
743+ let $acc0 = result
744+ func $f4_1 ($a,$i) = if (($i >= $s))
745+ then $a
746+ else f($a, $l[$i])
747+
748+ func $f4_2 ($a,$i) = if (($i >= $s))
749+ then $a
750+ else throw("List size exceeds 10")
751+
752+ $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)
753+ }
754+
755+
756+func checkTokensChange (newAssetIdsLi) = {
757+ let currentAssetIdsLi = split(tryGetString("static_tokenIds"), ",")
758+ func rem (accum,assetId) = if ((indexOf(newAssetIdsLi, assetId) == unit))
759+ then (accum + 1)
760+ else accum
761+
762+ func add (accum,assetId) = if ((indexOf(currentAssetIdsLi, assetId) == unit))
763+ then (accum + 1)
764+ else accum
765+
766+ let removed = {
767+ let $l = currentAssetIdsLi
768+ let $s = size($l)
769+ let $acc0 = 0
770+ func $f4_1 ($a,$i) = if (($i >= $s))
771+ then $a
772+ else rem($a, $l[$i])
773+
774+ func $f4_2 ($a,$i) = if (($i >= $s))
775+ then $a
776+ else throw("List size exceeds 10")
777+
778+ $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)
779+ }
780+ let added = {
781+ let $l = newAssetIdsLi
782+ let $s = size($l)
783+ let $acc0 = 0
784+ func $f5_1 ($a,$i) = if (($i >= $s))
785+ then $a
786+ else add($a, $l[$i])
787+
788+ func $f5_2 ($a,$i) = if (($i >= $s))
789+ then $a
790+ else throw("List size exceeds 10")
791+
792+ $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)
793+ }
794+ (removed + added)
795+ }
796+
797+
798+func validatePayments (assetsList,payments) = {
799+ func getPaymentAssets (accum,next) = if ((0 >= next.amount))
800+ then throw(((("Too low payment amount for " + getAssetString(next.assetId)) + ": ") + toString(next.amount)))
801+ else (accum ++ [getAssetString(next.assetId)])
802+
803+ let paymentList = {
804+ let $l = payments
805+ let $s = size($l)
806+ let $acc0 = nil
807+ func $f4_1 ($a,$i) = if (($i >= $s))
808+ then $a
809+ else getPaymentAssets($a, $l[$i])
810+
811+ func $f4_2 ($a,$i) = if (($i >= $s))
812+ then $a
813+ else throw("List size exceeds 10")
814+
815+ $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)
816+ }
817+ func f1 (accum,next) = if ((indexOf(assetsList, next) == unit))
818+ then throw(((next + " asset is present in payments, but is not in new assets: ") + makeString(assetsList, ",")))
819+ else (accum + 1)
820+
821+ func f2 (accum,next) = if ((indexOf(paymentList, next) == unit))
822+ then throw(((next + " asset is present in new assets, but is not in payments: ") + makeString(paymentList, ",")))
823+ else (accum + 1)
824+
825+ let a1 = {
826+ let $l = paymentList
827+ let $s = size($l)
828+ let $acc0 = 0
829+ func $f5_1 ($a,$i) = if (($i >= $s))
830+ then $a
831+ else f1($a, $l[$i])
832+
833+ func $f5_2 ($a,$i) = if (($i >= $s))
834+ then $a
835+ else throw("List size exceeds 10")
836+
837+ $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)
838+ }
839+ let a2 = {
840+ let $l = assetsList
841+ let $s = size($l)
842+ let $acc0 = 0
843+ func $f6_1 ($a,$i) = if (($i >= $s))
844+ then $a
845+ else f2($a, $l[$i])
846+
847+ func $f6_2 ($a,$i) = if (($i >= $s))
848+ then $a
849+ else throw("List size exceeds 10")
850+
851+ $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)
852+ }
853+ (a1 + a2)
854+ }
855+
856+
857+func validateWeights (weights) = {
858+ func v (accum,w) = {
859+ let wInt = valueOrErrorMessage(parseInt(w), ("Wrong weight format: " + w))
860+ if (if ((MIN_WEIGHT > wInt))
861+ then true
862+ else (wInt > MAX_WEIGHT))
863+ then throw(((((("Weight should be in range " + toString(MIN_WEIGHT)) + " - ") + toString(MAX_WEIGHT)) + ", current: ") + w))
864+ else (accum + wInt)
865+ }
866+
867+ let $l = weights
868+ let $s = size($l)
869+ let $acc0 = 0
870+ func $f4_1 ($a,$i) = if (($i >= $s))
871+ then $a
872+ else v($a, $l[$i])
873+
874+ func $f4_2 ($a,$i) = if (($i >= $s))
875+ then $a
876+ else throw("List size exceeds 10")
877+
878+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
879+ }
880+
881+
882+func getP1P2 (assetIdStr,baseAssetIdStr) = {
883+ let assetParams = loadGlobalTokenParams(assetIdStr)
884+ let baseAssetParams = loadGlobalTokenParams(baseAssetIdStr)
885+ let B1 = baseAssetParams._1
886+ let B2 = assetParams._1
887+ let F1 = baseAssetParams._2
888+ let F2 = assetParams._2
889+ let S1 = tryGetInteger((("static_" + baseAssetIdStr) + "_scale"))
890+ let S2 = tryGetInteger((("static_" + assetIdStr) + "_scale"))
891+ let D1 = tryGetInteger((("static_" + baseAssetIdStr) + "_decimals"))
892+ let D2 = tryGetInteger((("static_" + assetIdStr) + "_decimals"))
893+ let W1 = tryGetInteger((("static_" + baseAssetIdStr) + "_weight"))
894+ let W2 = tryGetInteger((("static_" + assetIdStr) + "_weight"))
895+ let W1W2 = fraction(W1, 10000, W2)
896+ let W2W1 = fraction(W2, 10000, W1)
897+ let p1_unweighted = fraction((B1 - F1), S1, fraction(B2, pow(fraction(B1, S1, (B1 - F1)), D1, W1W2, 4, D1, CEILING), S2))
898+ let p1 = fraction(p1_unweighted, W2W1, 10000)
899+ if ((B2 == F2))
900+ then $Tuple2(p1, unit)
901+ else {
902+ let p2_unweighted = fraction(fraction(B1, pow(fraction(B2, S2, (B2 - F2)), D2, W2W1, 4, D2, FLOOR), S2), S2, (B2 - F2))
903+ let p2 = fraction(p2_unweighted, W2W1, 10000)
904+ $Tuple2(p1, p2)
905+ }
906+ }
907+
908+
909+@Callable(i)
910+func addUnderlyingStaker (stakerAddress,assetIdStr) = if ((this != i.caller))
911+ then throw("admin only")
912+ else [StringEntry(("static_stakingContract_" + assetIdStr), stakerAddress)]
913+
914+
915+
916+@Callable(i)
917+func preInit (assetIdsStr,assetWeightsStr,assetMaxSelloffStr,baseTokenIdStr,poolDomain,poolOwner,fee) = {
918+ let poolOwnerAddress = addressFromStringValue(poolOwner)
919+ let assetIdsStrLi = split(assetIdsStr, ",")
920+ let assetMaxSelloffStrLi = split(assetMaxSelloffStr, ",")
921+ let assetWeightsStrLi = split(assetWeightsStr, ",")
922+ let assetIdsLi = {
923+ let $l = assetIdsStrLi
924+ let $s = size($l)
925+ let $acc0 = nil
926+ func $f4_1 ($a,$i) = if (($i >= $s))
927+ then $a
928+ else addAssetBytesToList($a, $l[$i])
929+
930+ func $f4_2 ($a,$i) = if (($i >= $s))
931+ then $a
932+ else throw("List size exceeds 10")
933+
934+ $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)
935+ }
936+ let feeAssetChosenStr = {
937+ let $l = assetIdsStrLi
938+ let $s = size($l)
939+ let $acc0 = ""
940+ func $f5_1 ($a,$i) = if (($i >= $s))
941+ then $a
942+ else checkFeeAsset($a, $l[$i])
943+
944+ func $f5_2 ($a,$i) = if (($i >= $s))
945+ then $a
946+ else throw("List size exceeds 10")
947+
948+ $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)
949+ }
950+ let feeAssetStr = if ((feeAssetChosenStr == ""))
951+ then baseTokenIdStr
952+ else feeAssetChosenStr
953+ if (isShutdown())
954+ then throw("contract is on stop")
955+ else if ((this != i.caller))
956+ then throw("admin only")
957+ else if ((size(poolDomain) > 13))
958+ then throw("too large pool domain")
959+ else if (if ((fee > 500))
960+ then true
961+ else (0 > fee))
962+ then throw("fee value must be between 0 and 500 (0-5%)")
963+ else if ((validateWeights(assetWeightsStrLi) != 10000))
964+ then throw(("weights sum should be 10000, current: " + toString(validateWeights(assetWeightsStrLi))))
965+ else {
966+ func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetIdsLi)))
967+ then accum
968+ else {
969+ let assetStakingAddress = {
970+ let @ = invoke(poolsHubAddress, "useEmptyContract", [("staker_" + assetIdsStrLi[assetNum])], nil)
971+ if ($isInstanceOf(@, "String"))
972+ then @
973+ else throw(($getType(@) + " couldn't be cast to String"))
974+ }
975+ if ((assetStakingAddress == assetStakingAddress))
976+ then {
977+ let assetDecimals = match assetIdsLi[assetNum] {
978+ case x: ByteVector =>
979+ value(assetInfo(x)).decimals
980+ case _ =>
981+ 8
982+ }
983+ ((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] == ""))
984+ then nil
985+ else [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_maxSelloff"), (parseIntValue(assetMaxSelloffStrLi[assetNum]) * Scale12))]))
986+ }
987+ else throw("Strict value is not equal to itself.")
988+ }
989+
990+ ({
991+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
992+ let $s = size($l)
993+ let $acc0 = nil
994+ func $f6_1 ($a,$i) = if (($i >= $s))
995+ then $a
996+ else addTokenDataEntries($a, $l[$i])
997+
998+ func $f6_2 ($a,$i) = if (($i >= $s))
999+ then $a
1000+ else throw("List size exceeds 10")
1001+
1002+ $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)
1003+ } ++ [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)])
1004+ }
1005+ }
1006+
1007+
1008+
1009+@Callable(i)
1010+func deInit () = if (isShutdown())
1011+ then throw("contract is on stop")
1012+ else if ((i.caller != this))
1013+ then throw("admin only")
1014+ else [IntegerEntry("global_wasInited", 0)]
1015+
1016+
1017+
1018+@Callable(i)
1019+func init (assetIdsStr,assetWeightsStr,assetMaxSelloffStr,baseTokenIdStr,poolDomain,fee,vBalancesStr) = {
1020+ let preInitInv = invoke(this, "preInit", [assetIdsStr, assetWeightsStr, assetMaxSelloffStr, baseTokenIdStr, poolDomain, toString(i.caller), fee], nil)
1021+ if ((preInitInv == preInitInv))
1022+ then {
1023+ let vBalances = parstStrToIntList(vBalancesStr)
1024+ func getPaymentAmount (assetIdStr) = {
1025+ func handler (accum,payment) = if ((getAssetString(payment.assetId) == assetIdStr))
1026+ then payment.amount
1027+ else accum
1028+
1029+ let $l = i.payments
1030+ let $s = size($l)
1031+ let $acc0 = 0
1032+ func $f4_1 ($a,$i) = if (($i >= $s))
1033+ then $a
1034+ else handler($a, $l[$i])
1035+
1036+ func $f4_2 ($a,$i) = if (($i >= $s))
1037+ then $a
1038+ else throw("List size exceeds 10")
1039+
1040+ $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)
1041+ }
1042+
1043+ func prepareList () = {
1044+ func handler (accum,assetId) = {
1045+ let assetIdStr = getAssetString(assetId)
1046+ let n = value(indexOf(assetIds, assetId))
1047+ let paymentAmount = getPaymentAmount(assetIdStr)
1048+ let assetParams = loadGlobalTokenParams(assetIdStr)
1049+ let assetParamsUpd = $Tuple8(vBalances[n], paymentAmount, assetParams._3, assetParams._4, assetParams._5, assetParams._6, assetParams._7, assetParams._8)
1050+ (accum ++ [saveGlobalTokenParams(assetIdStr, assetParamsUpd)])
1051+ }
1052+
1053+ let $l = assetIds
1054+ let $s = size($l)
1055+ let $acc0 = nil
1056+ func $f4_1 ($a,$i) = if (($i >= $s))
1057+ then $a
1058+ else handler($a, $l[$i])
1059+
1060+ func $f4_2 ($a,$i) = if (($i >= $s))
1061+ then $a
1062+ else throw("List size exceeds 10")
1063+
1064+ $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)
1065+ }
1066+
1067+ func calculatePoolTokensAmount (assetId) = {
1068+ func handler (accum,assetId) = {
1069+ func handler2 (accum,n) = if ((n == assetId))
1070+ then value(indexOf(assetIds, n))
1071+ else accum
1072+
1073+ let Token = {
1074+ let $l = assetIds
1075+ let $s = size($l)
1076+ let $acc0 = 1
1077+ func $f4_1 ($a,$i) = if (($i >= $s))
1078+ then $a
1079+ else handler2($a, $l[$i])
1080+
1081+ func $f4_2 ($a,$i) = if (($i >= $s))
1082+ then $a
1083+ else throw("List size exceeds 10")
1084+
1085+ $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)
1086+ }
1087+ fraction(accum, pow(vBalances[Token], Decimals[Token], AssetsWeights[Token], AssetsWeightsDecimals, 8, FLOOR), Scale8)
1088+ }
1089+
1090+ let $l = assetIds
1091+ let $s = size($l)
1092+ let $acc0 = PoolTokenScale
1093+ func $f4_1 ($a,$i) = if (($i >= $s))
1094+ then $a
1095+ else handler($a, $l[$i])
1096+
1097+ func $f4_2 ($a,$i) = if (($i >= $s))
1098+ then $a
1099+ else throw("List size exceeds 10")
1100+
1101+ $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)
1102+ }
1103+
1104+ if (isShutdown())
1105+ then throw("contract is on stop")
1106+ else if ((size(i.payments) == 0))
1107+ then throw("at least some of the assets should be provided as payment")
1108+ else if ((tryGetInteger("global_wasInited") > 0))
1109+ then throw("pool already inited")
1110+ else {
1111+ let initialPoolTokens = calculatePoolTokensAmount(assetIds)
1112+ let notifyInvoke = invoke(poolsHubAddress, "addSelfPool", nil, nil)
1113+ if ((notifyInvoke == notifyInvoke))
1114+ then if ((initialPoolTokens == 0))
1115+ then throw("you need a bigger tokens amount to launch the pool")
1116+ else (prepareList() ++ [IntegerEntry("global_poolToken_amount", initialPoolTokens), IntegerEntry("global_wasInited", 1), IntegerEntry((toString(i.caller) + "_indexStaked"), initialPoolTokens), IntegerEntry("global_indexStaked", initialPoolTokens)])
1117+ else throw("Strict value is not equal to itself.")
1118+ }
1119+ }
1120+ else throw("Strict value is not equal to itself.")
1121+ }
1122+
1123+
1124+
1125+@Callable(i)
1126+func generateIndex (needChange) = if ((size(i.payments) != T))
1127+ then throw(("you need to attach all pool tokens. amount of pool tokens: " + toString(T)))
1128+ else if (!(checkTokensValidity(i.payments)))
1129+ then throw("wrong assets attached")
1130+ else {
1131+ let PIssuedNoMult = getMinPIssued(i.payments)
1132+ let result = handlePoolTokensAdd(PIssuedNoMult, i.payments, i.originCaller, needChange)
1133+ let PIssuedWithMult = fraction(PIssuedNoMult, Scale16, getKMult(), DOWN)
1134+ $Tuple2((((result ++ claimResult(i.caller)._1) ++ mintIndexIfNeeded(PIssuedWithMult)) ++ [IntegerEntry((toString(i.caller) + "_indexStaked"), (tryGetInteger((toString(i.caller) + "_indexStaked")) + PIssuedWithMult)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") + PIssuedWithMult)), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") + PIssuedWithMult))]), PIssuedWithMult)
1135+ }
1136+
1137+
1138+
1139+@Callable(i)
1140+func redeemIndex (poolTokenAmount) = if ((poolTokenAmount > tryGetInteger((toString(i.caller) + "_indexStaked"))))
1141+ then throw("user doesn't have this amount of pool tokens")
1142+ else if (isShutdown())
1143+ then throw("contract is on stop")
1144+ else {
1145+ let PRedeemedWithMult = poolTokenAmount
1146+ let PRedeemedWithNoMult = fraction(PRedeemedWithMult, getKMult(), Scale16, DOWN)
1147+ let result = handlePoolTokensRedeem(PRedeemedWithNoMult, i.caller)
1148+ (((result ++ claimResult(i.caller)._1) ++ [IntegerEntry((toString(i.caller) + "_indexStaked"), (tryGetInteger((toString(i.caller) + "_indexStaked")) - PRedeemedWithMult)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - PRedeemedWithMult)), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemedWithMult))]) ++ burnIndexIfNeeded(poolTokenAmount))
1149+ }
1150+
1151+
1152+
1153+@Callable(i)
1154+func stakeIndex () = {
1155+ let addressStr = toString(i.originCaller)
1156+ let pmt = i.payments[0]
1157+ if ((value(pmt.assetId) != fromBase58String(tryGetString("static_poolToken_idStr"))))
1158+ then throw("wrong asset attached")
1159+ else indexStakeResult(addressStr, pmt.amount)
1160+ }
1161+
1162+
1163+
1164+@Callable(i)
1165+func stakeIndexFor (addressStr) = {
1166+ let pmt = i.payments[0]
1167+ if ((value(pmt.assetId) != fromBase58String(tryGetString("static_poolToken_idStr"))))
1168+ then throw("wrong asset attached")
1169+ else indexStakeResult(addressStr, pmt.amount)
1170+ }
1171+
1172+
1173+
1174+@Callable(i)
1175+func unstakeIndex (indexAmount) = {
1176+ func issueIndex () = {
1177+ let issue = Issue(("PR " + tryGetString("static_poolDomain")), "Puzzle Range Index", tryGetInteger("global_poolToken_amount"), PoolTokenDecimals, true, unit, 0)
1178+ let poolTokenIdStr = toBase58String(calculateAssetId(issue))
1179+ $Tuple2([issue, StringEntry("static_poolToken_idStr", poolTokenIdStr)], poolTokenIdStr)
1180+ }
1181+
1182+ let $t04040840574 = if ((tryGetString("static_poolToken_idStr") == ""))
1183+ then issueIndex()
1184+ else $Tuple2(nil, tryGetString("static_poolToken_idStr"))
1185+ let poolTokenIssueResult = $t04040840574._1
1186+ let poolTokenIdStr = $t04040840574._2
1187+ let poolTokenId = fromBase58String(poolTokenIdStr)
1188+ let addressStr = toString(i.caller)
1189+ let indexAvailable = tryGetInteger((addressStr + "_indexStaked"))
1190+ if (isShutdown())
1191+ then throw("contract is on stop")
1192+ else if ((indexAmount > indexAvailable))
1193+ then throw("you don't have index tokens available")
1194+ else if (isShutdown())
1195+ then throw("contract is on stop")
1196+ else ((poolTokenIssueResult ++ claimResult(addressFromStringValue(addressStr))._1) ++ [IntegerEntry((addressStr + "_indexStaked"), (indexAvailable - indexAmount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - indexAmount)), ScriptTransfer(i.caller, indexAmount, poolTokenId)])
1197+ }
1198+
1199+
1200+
1201+@Callable(i)
1202+func claimIndexRewards () = if (isShutdown())
1203+ then throw("contract is on stop")
1204+ else claimResult(i.caller)
1205+
1206+
1207+
1208+@Callable(i)
1209+func evaluateClaim (user) = $Tuple2(nil, claimResult(addressFromStringValue(user))._2)
1210+
1211+
1212+
1213+@Callable(i)
1214+func addInterestExternal () = {
1215+ let assetId = value(i.payments[0]).assetId
1216+ let assetIdStr = getAssetString(assetId)
1217+ let amount = i.payments[0].amount
1218+ let stakeTx = stakeIfNeeded(assetIdStr, amount)
1219+ if ((stakeTx == stakeTx))
1220+ then if ((indexOf(assetIds, assetId) == unit))
1221+ then throw("you can only add interest for assets in the pool")
1222+ else {
1223+ let params = loadGlobalTokenParams(assetIdStr)
1224+ let interestDelta = calcInterestChange(assetIdStr, amount)
1225+ let updParams = $Tuple8(params._1, params._2, params._3, (params._4 + interestDelta), (params._5 + amount), params._6, params._7, params._8)
1226+[saveGlobalTokenParams(assetIdStr, updParams)]
1227+ }
1228+ else throw("Strict value is not equal to itself.")
1229+ }
1230+
1231+
1232+
1233+@Callable(i)
1234+func notifyStakingPayment (assetIdStr,amount) = {
1235+ let assetId = getAssetBytes(assetIdStr)
1236+ if ((indexOf(assetIds, assetId) == unit))
1237+ then throw("you can only add interest for assets in the pool")
1238+ else if ((tryGetString(("static_stakingContract_" + assetIdStr)) != toString(i.caller)))
1239+ then throw("can only be invoked by staker contract")
1240+ else {
1241+ let params = loadGlobalTokenParams(assetIdStr)
1242+ let interestDelta = calcInterestChange(assetIdStr, amount)
1243+ let updParams = $Tuple8(params._1, params._2, params._3, (params._4 + interestDelta), (params._5 + amount), params._6, params._7, params._8)
1244+[saveGlobalTokenParams(assetIdStr, updParams)]
1245+ }
1246+ }
1247+
1248+
1249+
1250+@Callable(i)
1251+func swap (assetOut,minimum) = {
1252+ let pmt = if ((size(i.payments) == 1))
1253+ then value(i.payments[0])
1254+ else throw("please attach exactly one payment")
1255+ let AmountIn = value(i.payments[0].amount)
1256+ let AssetIn = pmt.assetId
1257+ let AssetOut = getAssetBytes(assetOut)
1258+ let assetIn = getAssetString(AssetIn)
1259+ let scaleIn = (Scale8 / tryGetInteger((("static_" + assetIn) + "_scale")))
1260+ let scaleOut = (Scale8 / tryGetInteger((("static_" + assetOut) + "_scale")))
1261+ let assetInParams = loadGlobalTokenParams(getAssetString(AssetIn))
1262+ let assetOutParams = loadGlobalTokenParams(assetOut)
1263+ let AssetInBalance = assetInParams._1
1264+ let AssetInFactBalance = assetInParams._2
1265+ let assetInFeesEarned = assetInParams._3
1266+ let assetInLastCheckInterest = assetInParams._4
1267+ let AssetOutBalance = assetOutParams._1
1268+ let assetOutFactBalance = assetOutParams._2
1269+ let AssetInBalanceScaled = (AssetInBalance * scaleIn)
1270+ let AssetOutBalanceScaled = (AssetOutBalance * scaleOut)
1271+ let feeAmountIn = fraction(AmountIn, Fee, FeeScale)
1272+ let cleanAmountIn = (AmountIn - feeAmountIn)
1273+ let cleanAmountInScaled = (cleanAmountIn * scaleIn)
1274+ let AmountOut1 = calculateOutAmount(cleanAmountInScaled, AssetIn, AssetOut, AssetInBalanceScaled, AssetOutBalanceScaled)
1275+ let AmountOut = fraction(AmountOut1, 1, scaleOut)
1276+ let AssetOutBalance2 = (AssetOutBalance - AmountOut)
1277+ let AssetInBalance2 = (AssetInBalance + cleanAmountIn)
1278+ if ((minimum > AmountOut))
1279+ then throw("amount to recieve is lower than given one")
1280+ else if ((AssetOut == AssetIn))
1281+ then throw("this swap is not allowed")
1282+ else if ((0 > (assetOutFactBalance - AmountOut)))
1283+ then throw("contract is out of reserves")
1284+ else if (isShutdown())
1285+ then throw("contract is on stop")
1286+ else if (valueOrElse(getBoolean(poolsHubAddress, ("global_shutdownIn_" + assetIn)), false))
1287+ then throw("token IN trades are stopped")
1288+ else if (valueOrElse(getBoolean(poolsHubAddress, ("global_shutdownOut_" + assetOut)), false))
1289+ then throw("token OUT trades are stopped")
1290+ else {
1291+ let protocolFee = fraction(feeAmountIn, 5, 10)
1292+ let lpFee = (feeAmountIn - protocolFee)
1293+ let interestDelta = calcInterestChange(assetIn, lpFee)
1294+ let stakeTx = stakeIfNeeded(assetIn, (cleanAmountIn + lpFee))
1295+ if ((stakeTx == stakeTx))
1296+ then {
1297+ let unstakeTx = unstakeIfNeeded(assetOut, AmountOut)
1298+ if ((unstakeTx == unstakeTx))
1299+ then {
1300+ let newBalanceIn = AssetInBalance2
1301+ let newBalanceOut = AssetOutBalance2
1302+ let assetInSelloffData = updSelloffData(assetIn, cleanAmountIn, AssetInBalance, $Tuple3(assetInParams._6, assetInParams._7, assetInParams._8))
1303+ let assetOutSelloffData = updSelloffData(assetOut, -(AmountOut), AssetOutBalance, $Tuple3(assetOutParams._6, assetOutParams._7, assetOutParams._8))
1304+ let assetInFinalParams = $Tuple8(newBalanceIn, (AssetInFactBalance + cleanAmountIn), (assetInFeesEarned + lpFee), (assetInLastCheckInterest + interestDelta), assetInParams._5, assetInSelloffData._1, assetInSelloffData._2, assetInSelloffData._3)
1305+ let assetOutFinalParams = $Tuple8(newBalanceOut, (assetOutFactBalance - AmountOut), assetOutParams._3, assetOutParams._4, assetOutParams._5, assetOutSelloffData._1, assetOutSelloffData._2, assetOutSelloffData._3)
1306+ let assetInChange = saveGlobalTokenParams(assetIn, assetInFinalParams)
1307+ let assetOutChange = saveGlobalTokenParams(assetOut, assetOutFinalParams)
1308+ let feeAssetStr = tryGetString("static_feeToken")
1309+ let feeAssetParams = loadGlobalTokenParams(feeAssetStr)
1310+ let feeTokenBalance = feeAssetParams._1
1311+ let volumeUsdUpdate = calculateUsdValue(AssetIn, AmountIn, AssetInBalance, feeTokenBalance)
1312+ $Tuple2([assetInChange, assetOutChange, ScriptTransfer(i.caller, AmountOut, AssetOut), IntegerEntry("global_volume_usd", (tryGetInteger("global_volume_usd") + volumeUsdUpdate)), ScriptTransfer(feesAddress, protocolFee, getAssetBytes(assetIn))], AmountOut)
1313+ }
1314+ else throw("Strict value is not equal to itself.")
1315+ }
1316+ else throw("Strict value is not equal to itself.")
1317+ }
1318+ }
1319+
1320+
1321+
1322+@Callable(i)
1323+func swapReadOnly (assetIn,assetOut,AmountIn) = {
1324+ let AssetIn = getAssetBytes(assetIn)
1325+ let AssetOut = getAssetBytes(assetOut)
1326+ let scaleIn = (Scale8 / tryGetInteger((("static_" + assetIn) + "_scale")))
1327+ let scaleOut = (Scale8 / tryGetInteger((("static_" + assetOut) + "_scale")))
1328+ let feeAssetOutStr = tryGetString("static_feeToken")
1329+ let feeAssetOut = if ((feeAssetOutStr == ""))
1330+ then usdnAssetId
1331+ else getAssetBytes(feeAssetOutStr)
1332+ let assetInParams = loadGlobalTokenParams(getAssetString(AssetIn))
1333+ let assetOutParams = loadGlobalTokenParams(assetOut)
1334+ let AssetInBalance = assetInParams._1
1335+ let AssetInFactBalance = assetInParams._2
1336+ let assetInFeesEarned = assetInParams._3
1337+ let assetInLastCheckInterest = assetInParams._4
1338+ let AssetOutBalance = assetOutParams._1
1339+ let assetOutFactBalance = assetOutParams._2
1340+ let AssetInBalanceScaled = (AssetInBalance * scaleIn)
1341+ let AssetOutBalanceScaled = (AssetOutBalance * scaleOut)
1342+ let feeAmountIn = fraction(AmountIn, Fee, FeeScale)
1343+ let cleanAmountIn = (AmountIn - feeAmountIn)
1344+ let cleanAmountInScaled = (cleanAmountIn * scaleIn)
1345+ let AmountOut1 = calculateOutAmount(cleanAmountInScaled, AssetIn, AssetOut, AssetInBalanceScaled, AssetOutBalanceScaled)
1346+ let AmountOut = fraction(AmountOut1, 1, scaleOut)
1347+ let AssetOutBalance2 = (AssetOutBalance - AmountOut)
1348+ let AssetInBalance2 = (AssetInBalance + cleanAmountIn)
1349+ if ((AssetOut == AssetIn))
1350+ then throw("this swap is not allowed")
1351+ else if ((0 > (assetOutParams._2 - AmountOut)))
1352+ then throw("contract is out of reserves")
1353+ else if (isShutdown())
1354+ then throw("contract is on stop")
1355+ else $Tuple2(nil, AmountOut)
1356+ }
1357+
1358+
1359+
1360+@Callable(i)
1361+func transferOwnership (newOwnerAddress) = if ((toString(i.caller) != tryGetString("static_poolOwner")))
1362+ then throw("this call available only for pool owner")
1363+ else [StringEntry("static_poolOwner", newOwnerAddress)]
1364+
1365+
1366+
1367+@Callable(i)
1368+func setFee (newFee) = if ((toString(i.caller) != tryGetString("static_poolOwner")))
1369+ then throw("this call available only for pool owner")
1370+ else [IntegerEntry("static_fee", newFee)]
1371+
1372+
1373+@Verifier(tx)
1374+func verify () = {
1375+ let MULTISIG_ADDRESS = addressFromString("3M7uzD8rT54fKQcP4s417if1VKU8yromEP2")
1376+ let CONTRACT_TYPE = "RANGED_POOL"
1377+ if ((MULTISIG_ADDRESS != unit))
1378+ then match tx {
1379+ case ttx: SetScriptTransaction =>
1380+ let scriptHasha = toBase58String(value(blake2b256(value(ttx.script))))
1381+ let approvedHashes = value(getString(value(MULTISIG_ADDRESS), (("script_" + CONTRACT_TYPE) + "__approved")))
1382+ (indexOf(approvedHashes, scriptHasha) != unit)
1383+ case otx =>
1384+ valueOrElse(getBoolean(value(MULTISIG_ADDRESS), (((toString(this) + "_") + toBase58String(otx.id)) + "__approved")), false)
1385+ }
1386+ else sigVerify(tx.bodyBytes, tx.proofs[0], masterPubKey)
1387+ }
1388+

github/deemru/w8io
92.00 ms