tx · DvNMDLA5jgYQGRNG4CMji4WivuEdJ449ivZVnL3dYsLE

3P8Df2b7ywHtLBHBe8PBVQYd3A5MdEEJAou:  -0.03700000 Waves

2024.03.25 16:07 [4099530] smart account 3P8Df2b7ywHtLBHBe8PBVQYd3A5MdEEJAou > SELF 0.00000000 Waves

{ "type": 13, "id": "DvNMDLA5jgYQGRNG4CMji4WivuEdJ449ivZVnL3dYsLE", "fee": 3700000, "feeAssetId": null, "timestamp": 1711372140759, "version": 2, "chainId": 87, "sender": "3P8Df2b7ywHtLBHBe8PBVQYd3A5MdEEJAou", "senderPublicKey": "A5ACGLGvvgWBydWzVw8E6mfj6rYi74ihiSwjfUHDQY8F", "proofs": [ "5J3Nx3Nas8Ps4kxZq8t8YVTaYpvkL9qXzyKczKmUqF9oD7VhxaDDNc91t7vv1XMY9xaLAG4ShteVaDZaDc143oiE" ], "script": "base64:BgKbAQgCEgASBAoCCAESBAoCCAESABIDCgEIEgQKAggBEgMKAQgSBAoCCAESBAoCCAESABIGCgQICAgIEgYKBAgICAgSBAoCCAgSBAoCCAgSAwoBBBIDCgEIEgMKAQQSCAoGBAgBCAgIEgUKAwQICBIGCgQECAQIEgMKAQQSBAoCCAQSBAoCCAQSAwoBBBIDCgEEEgMKAQgSAwoBCBIAKAAHVkVSU0lPTgIJUExQLTEuMC43ARNnZXRBZGRyZXNzRnJvbVN0YXRlAQNrZXkJAQt2YWx1ZU9yRWxzZQIJAKYIAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQCsAgICDnNldHVwX2FkZHJlc3NfBQNrZXkCIzNQRXdSY1lOQVV0b0Z2S3BCaEtvaXdham5aZmRvRFI2aDRoCQEHQWRkcmVzcwEBGgFXjrNqi19PmtPLr8EF1shiHDBcMjzmTCG+ARVnZXRBZGRyZXNzZXNGcm9tU3RhdGUBA2tleQoBAWYCBWFjY3VtBG5leHQJAM4IAgUFYWNjdW0JAMwIAgkBC3ZhbHVlT3JFbHNlAgkApggBBQRuZXh0CQEHQWRkcmVzcwEBGgFXjrNqi19PmtPLr8EF1shiHDBcMjzmTCG+BQNuaWwKAAIkbAkAvAkCCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJAKwCAgIOc2V0dXBfYWRkcmVzc18FA2tleQIjM1BFd1JjWU5BVXRvRnZLcEJoS29pd2FqblpmZG9EUjZoNGgCASwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDE1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABJyZXNlcnZlRnVuZEFkZHJlc3MJARNnZXRBZGRyZXNzRnJvbVN0YXRlAQILcmVzZXJ2ZUZ1bmQADW9yYWNsZUFkZHJlc3MJARNnZXRBZGRyZXNzRnJvbVN0YXRlAQIGb3JhY2xlABFhZ2dyZWdhdG9yQWRkcmVzcwkBE2dldEFkZHJlc3NGcm9tU3RhdGUBAgphZ2dyZWdhdG9yABB3eFN0YWtpbmdBZGRyZXNzCQETZ2V0QWRkcmVzc0Zyb21TdGF0ZQECB3N0YWtpbmcADGFkbWluQWRkcmVzcwkBE2dldEFkZHJlc3NGcm9tU3RhdGUBAgVhZG1pbgARc3RhYmxlRnVuZEFkZHJlc3MJARNnZXRBZGRyZXNzRnJvbVN0YXRlAQIKc3RhYmxlRnVuZAARc2h1dGRvd25XaGl0ZWxpc3QJARVnZXRBZGRyZXNzZXNGcm9tU3RhdGUBAg9zaHV0ZG93bkNhbGxlcnMAFGxpcXVpZGF0b3JzV2hpdGVsaXN0CQEVZ2V0QWRkcmVzc2VzRnJvbVN0YXRlAQILbGlxdWlkYXRvcnMBFnZlcmlmeUxpcXVpZGF0b3JSaWdodHMBB2FkZHJlc3MJAQIhPQIJAM8IAgUUbGlxdWlkYXRvcnNXaGl0ZWxpc3QFB2FkZHJlc3MFBHVuaXQAC3Jlc2VydmVGdW5kCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMCFHNldHVwX3Jlc2VydmVGdW5kRmVlABQADHN0YWJsZXNJZFN0cgkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMCEHNldHVwX3N0YWJsZXNJZHMCWTl3YzNMWE5BNFRFQnNYeUt0b0xFOW1yYkREN1dNSFh2WHJDalp2YWJMQXNpLEhHZ2FiVHFVUzhXdFZGVUp6Zm1yVERNZ0VjY0p1WkxCUGhGZ1FGeHZuc29XAgEsAQxnZXRSYXRlQ3VydmUBCmFzc2V0SWRTdHIEDmN1cnZlUmF0ZVN0ckxpCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkArAICAhBzZXR1cF9yYXRlQ3VydmVfBQphc3NldElkU3RyAiUyMDAwMDAwMCwxMDAwMDAwMDAsNjAwMDAwMDAsNDAwMDAwMDAwAgEsCQCWCgQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5jdXJ2ZVJhdGVTdHJMaQAACQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOY3VydmVSYXRlU3RyTGkAAQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmN1cnZlUmF0ZVN0ckxpAAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5jdXJ2ZVJhdGVTdHJMaQADARNnZXRSZXdhcmRzU3BsaXR0aW5nAQphc3NldElkU3RyBBVyZXdhcmRzU3BsaXR0aW5nU3RyTGkJALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQCsAgICF3NldHVwX3Jld2FyZHNTcGxpdHRpbmdfBQphc3NldElkU3RyAggzMCw1MCwyMAIBLAkAlQoDCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUVcmV3YXJkc1NwbGl0dGluZ1N0ckxpAAAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBRVyZXdhcmRzU3BsaXR0aW5nU3RyTGkAAQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFFXJld2FyZHNTcGxpdHRpbmdTdHJMaQACAAlzZW50aW5lbHMJAMwIAgkBB0FkZHJlc3MBARoBV9fhI1GOfKuIWtXXKJd12Ih104+uIwWm4QkAzAgCCQEHQWRkcmVzcwEBGgFX+Pr6AibAUYvsajtGM0nSHHGwdYv5pMqaCQDMCAIJAQdBZGRyZXNzAQEaAVdJARj2Q38/TGzhZ3Xlt+SXL95QLbKD3fEJAMwIAgkBB0FkZHJlc3MBARoBV0vDbM77M1hDWENREO7v7iEQF0vyeMt8MgUDbmlsAAZTY2FsZTgAgMLXLwAHU2NhbGUxMACAyK+gJQAHU2NhbGUxNgkAaAIFBlNjYWxlOAUGU2NhbGU4AAlkYXlCbG9ja3MAoAsBCmxpSW50VG9TdHIBAmxpCgEBZgIFYWNjdW0EbmV4dAkArAICCQCsAgIFBWFjY3VtCQCkAwEFBG5leHQCASwKAAIkbAUCbGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwAgAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEyCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAQ10cnlHZXRJbnRlZ2VyAQNrZXkEByRtYXRjaDAJAJoIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACA0ludAQBYgUHJG1hdGNoMAUBYgAAAQ10cnlHZXRCb29sZWFuAQNrZXkEByRtYXRjaDAJAJsIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACB0Jvb2xlYW4EAWIFByRtYXRjaDAFAWIHAQx0cnlHZXRTdHJpbmcBA2tleQQHJG1hdGNoMAkAnQgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFiBQckbWF0Y2gwBQFiAgABDHRyeUdldEJpbmFyeQEDa2V5BAckbWF0Y2gwCQCcCAIFBHRoaXMFA2tleQMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAFiBQckbWF0Y2gwBQFiAQABDmdldEFzc2V0U3RyaW5nAQdhc3NldElkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWIFByRtYXRjaDAJANgEAQUBYgIFV0FWRVMBDWdldEFzc2V0Qnl0ZXMBCmFzc2V0SWRTdHIDCQAAAgUKYXNzZXRJZFN0cgIFV0FWRVMFBHVuaXQJANkEAQUKYXNzZXRJZFN0cgEKZ2V0QmFsYW5jZQEKYXNzZXRJZFN0cgMJAAACBQphc3NldElkU3RyAgVXQVZFUwgJAO8HAQUEdGhpcwlhdmFpbGFibGUJAPAHAgUEdGhpcwkA2QQBBQphc3NldElkU3RyAQ9nZXRNYXJrZXRBc3NldHMACQC1CQIJAQx0cnlHZXRTdHJpbmcBAgxzZXR1cF90b2tlbnMCASwBDWdldE91dGRhdGVkVXIBCmFzc2V0SWRTdHIEBGRvd24JAGsDCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlBQdTY2FsZTE2AwkAAAIFBGRvd24AAAAACQBrAwUGU2NhbGU4CQBrAwkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFzc2V0SWRTdHICBl9iUmF0ZQUHU2NhbGUxNgUEZG93bgELZ2V0SW50ZXJlc3QBCmFzc2V0SWRTdHIEAnVyCQENZ2V0T3V0ZGF0ZWRVcgEFCmFzc2V0SWRTdHIEBWN1cnZlCQEMZ2V0UmF0ZUN1cnZlAQUKYXNzZXRJZFN0cgQEcmF0ZQkAZAIIBQVjdXJ2ZQJfMQMJAGcCCAUFY3VydmUCXzMFAnVyCQBrAwUCdXIIBQVjdXJ2ZQJfMggFBWN1cnZlAl8zCQBkAggFBWN1cnZlAl8yCQBrAwkAZQIFAnVyCAUFY3VydmUCXzMIBQVjdXJ2ZQJfNAkAZQIAgMLXLwgFBWN1cnZlAl8zCQCWAwEJAMwIAgkAawMFBHJhdGUFBlNjYWxlOAkAaAIFCWRheUJsb2NrcwDtAgkAzAgCAAEFA25pbAEQdG9rZW5SYXRlc1JlY2FsYwEKYXNzZXRJZFN0cgQIaW50ZXJlc3QJAQtnZXRJbnRlcmVzdAEFCmFzc2V0SWRTdHIEAnVyCQENZ2V0T3V0ZGF0ZWRVcgEFCmFzc2V0SWRTdHIEEGxhc3RSZWNhbGNIZWlnaHQJAQ10cnlHZXRJbnRlZ2VyAQIObGFzdFJhdGVIZWlnaHQECWxhc3RCUmF0ZQkAlgMBCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphc3NldElkU3RyAgZfYlJhdGUJAMwIAgUHU2NhbGUxNgUDbmlsBAhuZXdCUmF0ZQkAZAIFCWxhc3RCUmF0ZQkAaAIJAGUCBQZoZWlnaHQFEGxhc3RSZWNhbGNIZWlnaHQFCGludGVyZXN0BAlsYXN0U1JhdGUJAJYDAQkAzAgCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlCQDMCAIFB1NjYWxlMTYFA25pbAQIbmV3U1JhdGUJAGQCBQlsYXN0U1JhdGUJAGkCCQBoAgkAaAIJAGUCBQZoZWlnaHQFEGxhc3RSZWNhbGNIZWlnaHQJAGsDBQhpbnRlcmVzdAUCdXIFBlNjYWxlOAkAZQIAZAULcmVzZXJ2ZUZ1bmQAZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQphc3NldElkU3RyAgZfc1JhdGUFCG5ld1NSYXRlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFzc2V0SWRTdHICBl9iUmF0ZQUIbmV3QlJhdGUJAMwIAgkBDEludGVnZXJFbnRyeQICDmxhc3RSYXRlSGVpZ2h0BQZoZWlnaHQFA25pbAENZ2V0QWN0dWFsUmF0ZQIKYXNzZXRJZFN0cghyYXRlVHlwZQoBAWYCBWFjY3VtBXRva2VuBAZyZWNhbGMJARB0b2tlblJhdGVzUmVjYWxjAQUFdG9rZW4JAJQKAgMJAQIhPQIFBXRva2VuBQphc3NldElkU3RyCAUFYWNjdW0CXzEDCQAAAgUIcmF0ZVR5cGUCBXNSYXRlCAkAkQMCBQZyZWNhbGMAAAV2YWx1ZQgJAJEDAgUGcmVjYWxjAAEFdmFsdWUJAM4IAggFBWFjY3VtAl8yBQZyZWNhbGMKAAIkbAkBD2dldE1hcmtldEFzc2V0cwAKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAEFZ2V0VXIBCmFzc2V0SWRTdHIEBXJhdGVzCQEQdG9rZW5SYXRlc1JlY2FsYwEFCmFzc2V0SWRTdHIEBGRvd24JAGsDCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCAkAkQMCBQVyYXRlcwAABXZhbHVlBQdTY2FsZTE2CQBrAwUGU2NhbGU4CQBrAwkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cggJAJEDAgUFcmF0ZXMAAQV2YWx1ZQUHU2NhbGUxNgUEZG93bgELcmF0ZXNSZWNhbGMACgEBZgIFYWNjdW0FdG9rZW4JAM4IAgUFYWNjdW0JARB0b2tlblJhdGVzUmVjYWxjAQUFdG9rZW4KAAIkbAkBD2dldE1hcmtldEFzc2V0cwAKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEyCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMARVnZXRUb2tlblByaWNlV2l0aFJpc2sCCmFzc2V0SWRTdHIMcmlza0F2ZXJzaXR5AwkBAiE9AgkAzwgCBQxzdGFibGVzSWRTdHIFCmFzc2V0SWRTdHIFBHVuaXQJAJQKAgDAhD0AwIQ9BAVwcmljZQkBEUBleHRyTmF0aXZlKDEwNTApAgUNb3JhY2xlQWRkcmVzcwkArAICBQphc3NldElkU3RyAgdfdHdhcDVCBAlyaXNrTGV2ZWwJARFAZXh0ck5hdGl2ZSgxMDUwKQIFDW9yYWNsZUFkZHJlc3MJAKwCAgUKYXNzZXRJZFN0cgIKX3Jpc2tMZXZlbAMJAGcCBQxyaXNrQXZlcnNpdHkFCXJpc2tMZXZlbAkAlAoCBQVwcmljZQUFcHJpY2UJAAIBCQCsAgIJAKwCAgIbb3JhY2xlIHByaWNlcyBkb24ndCBtYXRjaDogCQCkAwEFBXByaWNlAiMgaXMgdGhlIHByaWNlLCBidXQgcmlzayBpcyB0b28gaGlnaAENZ2V0VG9rZW5QcmljZQEKYXNzZXRJZFN0cgkBFWdldFRva2VuUHJpY2VXaXRoUmlzawIFCmFzc2V0SWRTdHIAAwEOY2FsY0Fzc2V0U2NhbGUBCmFzc2V0SWRTdHIECGRlY2ltYWxzAwkAAAIFCmFzc2V0SWRTdHICBVdBVkVTAAgICQEFdmFsdWUBCQDsBwEJANkEAQUKYXNzZXRJZFN0cghkZWNpbWFscwkAbAYACgAABQhkZWNpbWFscwAAAAAFBERPV04BEmNhbGNVc2VyQ29sbGF0ZXJhbAEHYWRkcmVzcwQUdXNlckNvbGxhdGVyYWxJbnZva2UJAPwHBAUEdGhpcwIRZ2V0VXNlckNvbGxhdGVyYWwJAMwIAgcJAMwIAgUHYWRkcmVzcwkAzAgCBgkAzAgCAgAFA25pbAUDbmlsAwkAAAIFFHVzZXJDb2xsYXRlcmFsSW52b2tlBRR1c2VyQ29sbGF0ZXJhbEludm9rZQQTdXNlckNvbGxhdGVyYWxWYWx1ZQQHJG1hdGNoMAUUdXNlckNvbGxhdGVyYWxJbnZva2UDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4CQACAQIkaXNzdWUgd2hpbGUgZG9pbmcgaW4tZGFwcCBpbnZvY2F0aW9uAwkAAAIFE3VzZXJDb2xsYXRlcmFsVmFsdWUFE3VzZXJDb2xsYXRlcmFsVmFsdWUFE3VzZXJDb2xsYXRlcmFsVmFsdWUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4cAWkBBnN1cHBseQADCQEBIQEJAQ10cnlHZXRCb29sZWFuAQIMc2V0dXBfYWN0aXZlCQACAQIRbWFya2V0IGlzIHN0b3BwZWQDAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABBgkAAAIICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50AAAJAAIBAhwxIHBheW1lbnQgaGFzIHRvIGJlIGF0dGFjaGVkBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQEC2Fzc2V0QW1vdW50CAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQLJHQwODM5Njg0NjMJAQ1nZXRBY3R1YWxSYXRlAgUKYXNzZXRJZFN0cgIFc1JhdGUEBXNSYXRlCAULJHQwODM5Njg0NjMCXzEEEXJhdGVzUmVjYWxjUmVzdWx0CAULJHQwODM5Njg0NjMCXzIEBmFtb3VudAkAbgQFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQVzUmF0ZQUERE9XTgQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIECW1heFN1cHBseQQHJG1hdGNoMAkAoggBCQCsAgICEHNldHVwX21heFN1cHBseV8FCmFzc2V0SWRTdHIDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAF4BQckbWF0Y2gwCQENcGFyc2VJbnRWYWx1ZQEFAXgJAQ10cnlHZXRJbnRlZ2VyAQkArAICAhBzZXR1cF9tYXhTdXBwbHlfBQphc3NldElkU3RyBAphc3NldFByaWNlCQENZ2V0VG9rZW5QcmljZQEFCmFzc2V0SWRTdHIEEm5ld0FkZHJlc3NTdXBwbGllZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FCmFzc2V0SWRTdHIFBmFtb3VudAQQbmV3VG90YWxTdXBwbGllZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIFBmFtb3VudAQEcmF0ZQgJAQ1nZXRBY3R1YWxSYXRlAgUKYXNzZXRJZFN0cgIFc1JhdGUCXzEECmFzc2V0U2NhbGUJAQ5jYWxjQXNzZXRTY2FsZQEFCmFzc2V0SWRTdHIEE25ld1RvdGFsU3VwcGxpZWRVc2QJAGsDCQBrAwUQbmV3VG90YWxTdXBwbGllZAUEcmF0ZQUHU2NhbGUxNggFCmFzc2V0UHJpY2UCXzEFCmFzc2V0U2NhbGUDCQAAAgkAswkCCQEMdHJ5R2V0U3RyaW5nAQIMc2V0dXBfdG9rZW5zBQphc3NldElkU3RyBQR1bml0CQACAQIpdGhpcyBhc3NldCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBtYXJrZXQDAwkBAiE9AgUJbWF4U3VwcGx5AAAJAGYCBRNuZXdUb3RhbFN1cHBsaWVkVXNkBQltYXhTdXBwbHkHCQACAQIzbWF4IHRvdGFsIHN1cHBseSBmb3IgdGhpcyB0b2tlbiByZWFjaGVkIGluIHRoZSBwb29sAwkAZgIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg1zZXR1cF9wYXVzZWRfBQphc3NldElkU3RyAAAJAAIBAih0aGlzIGFzc2V0IGNhbid0IGJlIHN1cHBsaWVkIG9yIGJvcnJvd2VkBANpbnYDCQECIT0CCQEMdHJ5R2V0U3RyaW5nAQkArAICAhBzZXR1cF9hdXRvc3Rha2VfBQphc3NldElkU3RyAgAJAPwHBAUEdGhpcwIKc3Rha2VUb2tlbgkAzAgCBQphc3NldElkU3RyCQDMCAIFC2Fzc2V0QW1vdW50BQNuaWwFA25pbAUEdW5pdAMJAAACBQNpbnYFA2ludgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgUSbmV3QWRkcmVzc1N1cHBsaWVkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgUQbmV3VG90YWxTdXBwbGllZAUDbmlsBRFyYXRlc1JlY2FsY1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQh3aXRoZHJhdwIKYXNzZXRJZFN0cgthc3NldEFtb3VudAQNJHQwMTAwMjQxMDA5MQkBDWdldEFjdHVhbFJhdGUCBQphc3NldElkU3RyAgVzUmF0ZQQFc1JhdGUIBQ0kdDAxMDAyNDEwMDkxAl8xBBFyYXRlc1JlY2FsY1Jlc3VsdAgFDSR0MDEwMDI0MTAwOTECXzIEBmFtb3VudAkAbgQFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQVzUmF0ZQUHQ0VJTElORwQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEDWFzc2V0U3VwcGxpZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIEDWFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIEEXVzZXJBc3NldFN1cHBsaWVkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQphc3NldElkU3RyBBF1c2VyQXNzZXRCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgQSY29sbGF0ZXJhbFZhbHVlSW52CQD8BwQFBHRoaXMCEWdldFVzZXJDb2xsYXRlcmFsCQDMCAIHCQDMCAIFB2FkZHJlc3MJAMwIAgYJAMwIAgkArAICCQCsAgIFCmFzc2V0SWRTdHICCixzdXBwbGllZCwJAKQDAQkBAS0BBQZhbW91bnQFA25pbAUDbmlsAwkAAAIFEmNvbGxhdGVyYWxWYWx1ZUludgUSY29sbGF0ZXJhbFZhbHVlSW52BA9jb2xsYXRlcmFsVmFsdWUEByRtYXRjaDAFEmNvbGxhdGVyYWxWYWx1ZUludgMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgJAAIBAh9jYW4ndCBnZXQgdXNlciBjb2xsYXRlcmFsIHZhbHVlAwkBASEBCQENdHJ5R2V0Qm9vbGVhbgECDHNldHVwX2FjdGl2ZQkAAgECEW1hcmtldCBpcyBzdG9wcGVkAwkAZgIAAAUPY29sbGF0ZXJhbFZhbHVlCQACAQIyeW91IGRvbnQgaGF2ZSBlbm91Z2ggY29sbGF0ZXJhbCBmb3IgdGhpcyBvcGVyYXRpb24DCQBmAgUGYW1vdW50CQBlAgUNYXNzZXRTdXBwbGllZAUNYXNzZXRCb3Jyb3dlZAkAAgECKnRoaXMgYW1vdW50IGlzIG5vdCBhdmFpbGFibGUgb24gdGhlIG1hcmtldAMJAGYCBQZhbW91bnQJAGUCBRF1c2VyQXNzZXRTdXBwbGllZAURdXNlckFzc2V0Qm9ycm93ZWQJAAIBAip0aGlzIGFtb3VudCBpcyBub3QgYXZhaWxhYmxlIGZvciB0aGlzIHVzZXIEA2ludgMJAQIhPQIJAQx0cnlHZXRTdHJpbmcBCQCsAgICEHNldHVwX2F1dG9zdGFrZV8FCmFzc2V0SWRTdHICAAkA/AcEBQR0aGlzAgx1bnN0YWtlVG9rZW4JAMwIAgUKYXNzZXRJZFN0cgkAzAgCBQthc3NldEFtb3VudAUDbmlsBQNuaWwFBHVuaXQDCQAAAgUDaW52BQNpbnYJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FCmFzc2V0SWRTdHIJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQphc3NldElkU3RyBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgUGYW1vdW50CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgULYXNzZXRBbW91bnQJAQ1nZXRBc3NldEJ5dGVzAQUKYXNzZXRJZFN0cgUDbmlsBRFyYXRlc1JlY2FsY1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQZib3Jyb3cCCmFzc2V0SWRTdHILYXNzZXRBbW91bnQEB2FkZHJlc3MJAKUIAQgFAWkGY2FsbGVyBA0kdDAxMTc0NzExODE0CQENZ2V0QWN0dWFsUmF0ZQIFCmFzc2V0SWRTdHICBWJSYXRlBAViUmF0ZQgFDSR0MDExNzQ3MTE4MTQCXzEEEXJhdGVzUmVjYWxjUmVzdWx0CAUNJHQwMTE3NDcxMTgxNAJfMgQGYW1vdW50CQBuBAULYXNzZXRBbW91bnQFB1NjYWxlMTYFBWJSYXRlBQdDRUlMSU5HBBJjb2xsYXRlcmFsVmFsdWVJbnYJAPwHBAUEdGhpcwIRZ2V0VXNlckNvbGxhdGVyYWwJAMwIAgcJAMwIAgUHYWRkcmVzcwkAzAgCBgkAzAgCCQCsAgIJAKwCAgUKYXNzZXRJZFN0cgIKLGJvcnJvd2VkLAkApAMBBQZhbW91bnQFA25pbAUDbmlsAwkAAAIFEmNvbGxhdGVyYWxWYWx1ZUludgUSY29sbGF0ZXJhbFZhbHVlSW52BA9jb2xsYXRlcmFsVmFsdWUEByRtYXRjaDAFEmNvbGxhdGVyYWxWYWx1ZUludgMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgJAAIBAh9jYW4ndCBnZXQgdXNlciBjb2xsYXRlcmFsIHZhbHVlAwkBASEBCQENdHJ5R2V0Qm9vbGVhbgECDHNldHVwX2FjdGl2ZQkAAgECEW1hcmtldCBpcyBzdG9wcGVkAwkAZgIAAAUPY29sbGF0ZXJhbFZhbHVlCQACAQIheW91IGhhdmUgdG8gc3VwcGx5IG1vcmUgdG8gYm9ycm93AwkAZgIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg1zZXR1cF9wYXVzZWRfBQphc3NldElkU3RyAAAJAAIBAih0aGlzIGFzc2V0IGNhbid0IGJlIHN1cHBsaWVkIG9yIGJvcnJvd2VkBA1hc3NldFN1cHBsaWVkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyBA1hc3NldEJvcnJvd2VkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQphc3NldElkU3RyBBF1c2VyQXNzZXRCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgMJAGYCBQZhbW91bnQJAGUCBQ1hc3NldFN1cHBsaWVkBQ1hc3NldEJvcnJvd2VkCQACAQIcdGhpcyBhbW91bnQgaXMgbm90IGF2YWlsYWJsZQQDaW52AwkBAiE9AgkBDHRyeUdldFN0cmluZwEJAKwCAgIQc2V0dXBfYXV0b3N0YWtlXwUKYXNzZXRJZFN0cgIACQD8BwQFBHRoaXMCDHVuc3Rha2VUb2tlbgkAzAgCBQphc3NldElkU3RyCQDMCAIFC2Fzc2V0QW1vdW50BQNuaWwFA25pbAUEdW5pdAMJAAACBQNpbnYFA2ludgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgkAZAIFEXVzZXJBc3NldEJvcnJvd2VkBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQphc3NldElkU3RyCQBkAgUNYXNzZXRCb3Jyb3dlZAUGYW1vdW50CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgULYXNzZXRBbW91bnQJAQ1nZXRBc3NldEJ5dGVzAQUKYXNzZXRJZFN0cgUDbmlsBRFyYXRlc1JlY2FsY1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQVyZXBheQADCQEBIQEJAQ10cnlHZXRCb29sZWFuAQIMc2V0dXBfYWN0aXZlCQACAQIRbWFya2V0IGlzIHN0b3BwZWQDAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABBgkAAAIICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50AAAJAAIBAhwxIHBheW1lbnQgaGFzIHRvIGJlIGF0dGFjaGVkBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQEC2Fzc2V0QW1vdW50CAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQNJHQwMTM1OTAxMzY1NwkBDWdldEFjdHVhbFJhdGUCBQphc3NldElkU3RyAgViUmF0ZQQFYlJhdGUIBQ0kdDAxMzU5MDEzNjU3Al8xBBFyYXRlc1JlY2FsY1Jlc3VsdAgFDSR0MDEzNTkwMTM2NTcCXzIEBmFtb3VudAkAbgQFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQViUmF0ZQUHQ0VJTElORwQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEDWFzc2V0U3VwcGxpZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIEDWFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIEEXVzZXJBc3NldEJvcnJvd2VkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQphc3NldElkU3RyBAphbW91bnRMZWZ0CQBlAgURdXNlckFzc2V0Qm9ycm93ZWQFBmFtb3VudAQLcmVwYXlBbW91bnQDCQBnAgUKYW1vdW50TGVmdAAABQZhbW91bnQFEXVzZXJBc3NldEJvcnJvd2VkAwkAAAIJALMJAgkBDHRyeUdldFN0cmluZwECDHNldHVwX3Rva2VucwUKYXNzZXRJZFN0cgUEdW5pdAkAAgECKXRoaXMgYXNzZXQgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgbWFya2V0BANpbnYDCQECIT0CCQEMdHJ5R2V0U3RyaW5nAQkArAICAhBzZXR1cF9hdXRvc3Rha2VfBQphc3NldElkU3RyAgAJAPwHBAUEdGhpcwIKc3Rha2VUb2tlbgkAzAgCBQphc3NldElkU3RyCQDMCAIFC2Fzc2V0QW1vdW50BQNuaWwFA25pbAUEdW5pdAMJAAACBQNpbnYFA2ludgkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQphc3NldElkU3RyCQBlAgURdXNlckFzc2V0Qm9ycm93ZWQFC3JlcGF5QW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgkAZQIFDWFzc2V0Qm9ycm93ZWQFC3JlcGF5QW1vdW50BQNuaWwFEXJhdGVzUmVjYWxjUmVzdWx0AwkAZwIFCmFtb3VudExlZnQAAAUDbmlsCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgkBAS0BBQphbW91bnRMZWZ0CAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQhyZXBheUZvcgEHYWRkcmVzcwMJAQEhAQkBDXRyeUdldEJvb2xlYW4BAgxzZXR1cF9hY3RpdmUJAAIBAhFtYXJrZXQgaXMgc3RvcHBlZAMJAQIhPQIIBQFpBmNhbGxlcgUScmVzZXJ2ZUZ1bmRBZGRyZXNzCQACAQInYXZhaWxhYmxlIG9ubHkgZm9yIHJlc2VydmUgZnVuZCBhZGRyZXNzAwkAAAIFB2FkZHJlc3MCBmdsb2JhbAkAAgECIHlvdSBjYW4ndCByZXBheSBmb3IgZXZlcnlvbmUgOl8pAwMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQYJAAACCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAAACQACAQIcMSBwYXltZW50IGhhcyB0byBiZSBhdHRhY2hlZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBAthc3NldEFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEDSR0MDE1MzA4MTUzNzUJAQ1nZXRBY3R1YWxSYXRlAgUKYXNzZXRJZFN0cgIFYlJhdGUEBWJSYXRlCAUNJHQwMTUzMDgxNTM3NQJfMQQRcmF0ZXNSZWNhbGNSZXN1bHQIBQ0kdDAxNTMwODE1Mzc1Al8yBAZhbW91bnQJAG4EBQthc3NldEFtb3VudAUHU2NhbGUxNgUFYlJhdGUFB0NFSUxJTkcEDWFzc2V0U3VwcGxpZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIEDWFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIEEXVzZXJBc3NldEJvcnJvd2VkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQphc3NldElkU3RyBAphbW91bnRMZWZ0CQBlAgURdXNlckFzc2V0Qm9ycm93ZWQFBmFtb3VudAQLcmVwYXlBbW91bnQDCQBnAgUKYW1vdW50TGVmdAAABQZhbW91bnQFEXVzZXJBc3NldEJvcnJvd2VkAwkAAAIJALMJAgkBDHRyeUdldFN0cmluZwECDHNldHVwX3Rva2VucwUKYXNzZXRJZFN0cgUEdW5pdAkAAgECKXRoaXMgYXNzZXQgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgbWFya2V0BANpbnYDCQECIT0CCQEMdHJ5R2V0U3RyaW5nAQkArAICAhBzZXR1cF9hdXRvc3Rha2VfBQphc3NldElkU3RyAgAJAPwHBAUEdGhpcwIKc3Rha2VUb2tlbgkAzAgCBQphc3NldElkU3RyCQDMCAIFC2Fzc2V0QW1vdW50BQNuaWwFA25pbAUEdW5pdAMJAAACBQNpbnYFA2ludgkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQphc3NldElkU3RyCQBlAgURdXNlckFzc2V0Qm9ycm93ZWQFC3JlcGF5QW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgkAZQIFDWFzc2V0Qm9ycm93ZWQFC3JlcGF5QW1vdW50BQNuaWwFEXJhdGVzUmVjYWxjUmVzdWx0AwkAZwIFCmFtb3VudExlZnQAAAUDbmlsCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgkBAS0BBQphbW91bnRMZWZ0CAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQpzdGFrZVRva2VuAgphc3NldElkU3RyBmFtb3VudAQXd3hTdGFrZXJTdXBwb3J0ZWRBc3NldHMJARFAZXh0ck5hdGl2ZSgxMDUzKQIFEHd4U3Rha2luZ0FkZHJlc3MCFXNldHVwX3N1cHBvcnRlZEFzc2V0cwMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECLG9ubHkgZm9yIGludGVybmFsIHNtYXJ0IGNvbnRyYWN0IGludm9jYXRpb25zAwkAAAIJALMJAgUXd3hTdGFrZXJTdXBwb3J0ZWRBc3NldHMFCmFzc2V0SWRTdHIFBHVuaXQFA25pbAQMYW1vdW50U3Rha2VkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIRYXV0b3N0YWtlX2Ftb3VudF8FCmFzc2V0SWRTdHIECHN0YWtlSW52CQD9BwQFEHd4U3Rha2luZ0FkZHJlc3MCB3N0YWtlTFAFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDWdldEFzc2V0Qnl0ZXMBBQphc3NldElkU3RyBQZhbW91bnQFA25pbAMJAAACBQhzdGFrZUludgUIc3Rha2VJbnYJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIRYXV0b3N0YWtlX2Ftb3VudF8FCmFzc2V0SWRTdHIJAGQCBQxhbW91bnRTdGFrZWQFBmFtb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDXN0YWtlVG9rZW5BbGwBCmFzc2V0SWRTdHIDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAixvbmx5IGZvciBpbnRlcm5hbCBzbWFydCBjb250cmFjdCBpbnZvY2F0aW9ucwQGYW1vdW50CQEKZ2V0QmFsYW5jZQEFCmFzc2V0SWRTdHIEA2ludgkA/QcEBQR0aGlzAgpzdGFrZVRva2VuCQDMCAIFCmFzc2V0SWRTdHIJAMwIAgUGYW1vdW50BQNuaWwFA25pbAMJAAACBQNpbnYFA2ludgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDHVuc3Rha2VUb2tlbgIKYXNzZXRJZFN0cgZhbW91bnQEF3d4U3Rha2VyU3VwcG9ydGVkQXNzZXRzCQERQGV4dHJOYXRpdmUoMTA1MykCBRB3eFN0YWtpbmdBZGRyZXNzAhVzZXR1cF9zdXBwb3J0ZWRBc3NldHMDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAixvbmx5IGZvciBpbnRlcm5hbCBzbWFydCBjb250cmFjdCBpbnZvY2F0aW9ucwMJAAACCQCzCQIFF3d4U3Rha2VyU3VwcG9ydGVkQXNzZXRzBQphc3NldElkU3RyBQR1bml0BQNuaWwEDGFtb3VudFN0YWtlZAkBDXRyeUdldEludGVnZXIBCQCsAgICEWF1dG9zdGFrZV9hbW91bnRfBQphc3NldElkU3RyBAhzdGFrZUludgkA/QcEBRB3eFN0YWtpbmdBZGRyZXNzAgl1bnN0YWtlTFAJAMwIAgUKYXNzZXRJZFN0cgkAzAgCBQZhbW91bnQFA25pbAUDbmlsAwkAAAIFCHN0YWtlSW52BQhzdGFrZUludgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAhFhdXRvc3Rha2VfYW1vdW50XwUKYXNzZXRJZFN0cgkAZQIFDGFtb3VudFN0YWtlZAUGYW1vdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQELYWRkSW50ZXJlc3QCCmFzc2V0SWRTdHIGYW1vdW50AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIYb25seSBmb3Igc2VsZiBpbnZvY2F0aW9uBAZlYXJuZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAhVhdXRvc3Rha2VfbGFzdEVhcm5lZF8FCmFzc2V0SWRTdHIECmxhc3RIZWlnaHQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAhRhdXRvc3Rha2VfbGFzdEJsb2NrXwUKYXNzZXRJZFN0cgQLY2xlYW5BbW91bnQJAGsDBQZhbW91bnQAUABkBAxzdGF0ZUNoYW5nZXMDAwkAAAIFCmxhc3RIZWlnaHQFBmhlaWdodAYJAAACBQZhbW91bnQAAAUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICGGF1dG9zdGFrZV9wcmVMYXN0RWFybmVkXwUKYXNzZXRJZFN0cgUGZWFybmVkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICF2F1dG9zdGFrZV9wcmVMYXN0QmxvY2tfBQphc3NldElkU3RyBQpsYXN0SGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICFWF1dG9zdGFrZV9sYXN0RWFybmVkXwUKYXNzZXRJZFN0cgkAZAIFBmVhcm5lZAULY2xlYW5BbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIUYXV0b3N0YWtlX2xhc3RCbG9ja18FCmFzc2V0SWRTdHIFBmhlaWdodAUDbmlsCQDOCAIFDHN0YXRlQ2hhbmdlcwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQphc3NldElkU3RyAgZfc1JhdGUJAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlCQBrAwUHU2NhbGUxNgULY2xlYW5BbW91bnQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIFA25pbAFpARNhZGRJbnRlcmVzdEVYVEVSTkFMAAQHYXNzZXRJZAgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBBQdhc3NldElkBAlzcGxpdHRpbmcJARNnZXRSZXdhcmRzU3BsaXR0aW5nAQUKYXNzZXRJZFN0cgQGYW1vdW50CQBrAwgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQIBQlzcGxpdHRpbmcCXzIAZAQGZWFybmVkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIVYXV0b3N0YWtlX2xhc3RFYXJuZWRfBQphc3NldElkU3RyBApsYXN0SGVpZ2h0CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIUYXV0b3N0YWtlX2xhc3RCbG9ja18FCmFzc2V0SWRTdHIEDHN0YXRlQ2hhbmdlcwMDCQAAAgUKbGFzdEhlaWdodAUGaGVpZ2h0BgkAAAIFBmFtb3VudAAABQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIYYXV0b3N0YWtlX3ByZUxhc3RFYXJuZWRfBQphc3NldElkU3RyBQZlYXJuZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIXYXV0b3N0YWtlX3ByZUxhc3RCbG9ja18FCmFzc2V0SWRTdHIFCmxhc3RIZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIVYXV0b3N0YWtlX2xhc3RFYXJuZWRfBQphc3NldElkU3RyCQBkAgUGZWFybmVkBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIUYXV0b3N0YWtlX2xhc3RCbG9ja18FCmFzc2V0SWRTdHIFBmhlaWdodAUDbmlsCQDOCAIFDHN0YXRlQ2hhbmdlcwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQphc3NldElkU3RyAgZfc1JhdGUJAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlCQBrAwUHU2NhbGUxNgUGYW1vdW50CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFEXN0YWJsZUZ1bmRBZGRyZXNzCQBrAwgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQIBQlzcGxpdHRpbmcCXzEAZAUHYXNzZXRJZAUDbmlsAWkBB3ByZUluaXQEBnRva2VucwRsdHZzA2x0cwlwZW5hbHRpZXMKAQFmAgVhY2N1bQV0b2tlbgkAzggCBQVhY2N1bQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQV0b2tlbgIGX2JSYXRlBQdTY2FsZTE2CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBXRva2VuAgZfc1JhdGUFB1NjYWxlMTYFA25pbAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECCmFkbWluIG9ubHkEBXJhdGVzCgACJGwJALUJAgUGdG9rZW5zAgEsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQICDHNldHVwX3Rva2VucwUGdG9rZW5zCQDMCAIJAQtTdHJpbmdFbnRyeQICCnNldHVwX2x0dnMFBGx0dnMJAMwIAgkBC1N0cmluZ0VudHJ5AgIJc2V0dXBfbHRzBQNsdHMJAMwIAgkBC1N0cmluZ0VudHJ5AgIPc2V0dXBfcGVuYWx0aWVzBQlwZW5hbHRpZXMJAMwIAgkBDEJvb2xlYW5FbnRyeQICDHNldHVwX2FjdGl2ZQYFA25pbAUFcmF0ZXMBaQEMaW5pdE5ld1Rva2VuBAV0b2tlbgNsdHYCbHQHcGVuYWx0eQMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECCmFkbWluIG9ubHkJAMwIAgkBC1N0cmluZ0VudHJ5AgIMc2V0dXBfdG9rZW5zCQCsAgIJAKwCAgkBDHRyeUdldFN0cmluZwECDHNldHVwX3Rva2VucwIBLAUFdG9rZW4JAMwIAgkBC1N0cmluZ0VudHJ5AgIKc2V0dXBfbHR2cwkArAICCQCsAgIJAQx0cnlHZXRTdHJpbmcBAgpzZXR1cF9sdHZzAgEsBQNsdHYJAMwIAgkBC1N0cmluZ0VudHJ5AgIJc2V0dXBfbHRzCQCsAgIJAKwCAgkBDHRyeUdldFN0cmluZwECCXNldHVwX2x0cwIBLAUCbHQJAMwIAgkBC1N0cmluZ0VudHJ5AgIPc2V0dXBfcGVuYWx0aWVzCQCsAgIJAKwCAgkBDHRyeUdldFN0cmluZwECD3NldHVwX3BlbmFsdGllcwIBLAUHcGVuYWx0eQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQV0b2tlbgIGX2JSYXRlBQdTY2FsZTE2CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBXRva2VuAgZfc1JhdGUFB1NjYWxlMTYFA25pbAFpAQ91cGRhdGVQYXJhbWV0ZXICA2tleQN2YWwDAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQECIT0CCAUBaQZjYWxsZXIFDGFkbWluQWRkcmVzcwcJAAIBAgphZG1pbiBvbmx5CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQNrZXkJAQ1wYXJzZUludFZhbHVlAQUDdmFsBQNuaWwBaQEMdXBkYXRlU3RyaW5nAgNrZXkDdmFsAwMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkBAiE9AggFAWkGY2FsbGVyBQxhZG1pbkFkZHJlc3MHCQACAQIKYWRtaW4gb25seQkAzAgCCQELU3RyaW5nRW50cnkCBQNrZXkFA3ZhbAUDbmlsAWkBEmNsYWltVG9SZXNlcnZlRnVuZAEFZGVidWcEBmFzc2V0cwkBD2dldE1hcmtldEFzc2V0cwAEBXJhdGVzCAkBDWdldEFjdHVhbFJhdGUCCQCRAwIFBmFzc2V0cwAAAgVzUmF0ZQJfMgQCbGkJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUJAMwIAgAGCQDMCAIABwkAzAgCAAgJAMwIAgAJCQDMCAIACgkAzAgCAAsFA25pbAoBAWYCBWFjY3VtAW4DCQBnAgUBbgkAkAMBBQZhc3NldHMFBWFjY3VtBAphc3NldElkU3RyCQCRAwIFBmFzc2V0cwUBbgQPYXV0b3N0YWtlQW1vdW50CQEMdHJ5R2V0U3RyaW5nAQkArAICAhFhdXRvc3Rha2VfYW1vdW50XwUKYXNzZXRJZFN0cgQGYW1vdW50CQBlAgkAZAIJAGQCCQBkAgkBCmdldEJhbGFuY2UBBQphc3NldElkU3RyCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIRYXV0b3N0YWtlX2Ftb3VudF8FCmFzc2V0SWRTdHIDCQECIT0CBQ9hdXRvc3Rha2VBbW91bnQCAAkBDXBhcnNlSW50VmFsdWUBBQ9hdXRvc3Rha2VBbW91bnQAAAkAawMJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIICQCRAwIFBXJhdGVzCQBkAgkAaAIFAW4AAwABBXZhbHVlBQdTY2FsZTE2CQBrAwkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cggJAJEDAgUFcmF0ZXMJAGgCBQFuAAMFdmFsdWUFB1NjYWxlMTYEA2ludgMJAQIhPQIJAQx0cnlHZXRTdHJpbmcBCQCsAgICEHNldHVwX2F1dG9zdGFrZV8FCmFzc2V0SWRTdHICAAkA/AcEBQR0aGlzAgx1bnN0YWtlVG9rZW4JAMwIAgUKYXNzZXRJZFN0cgkAzAgCBQZhbW91bnQFA25pbAUDbmlsBQR1bml0AwkAAAIFA2ludgUDaW52CQDOCAIFBWFjY3VtCQDMCAIFBmFtb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAlwYXJhbWV0ZXIKAAIkbAUCbGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEyCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMCgECZjICBWFjY3VtAW4DCQBnAgUBbgkAkAMBBQZhc3NldHMFBWFjY3VtBAphc3NldElkU3RyCQCRAwIFBmFzc2V0cwUBbgkAzggCBQVhY2N1bQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBRJyZXNlcnZlRnVuZEFkZHJlc3MJAJYDAQkAzAgCCQCRAwIFCXBhcmFtZXRlcgUBbgkAzAgCAAAFA25pbAkBDWdldEFzc2V0Qnl0ZXMBBQphc3NldElkU3RyBQNuaWwDBQVkZWJ1ZwkAAgEJAQpsaUludFRvU3RyAQUJcGFyYW1ldGVyCQCUCgIKAAIkbAUCbGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAmYyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMgkBBSRmMV8yAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAUJcGFyYW1ldGVyAWkBB3JlU2V0dXABCmFzc2V0SWRTdHIEC2xhc3RSZXNldHVwCQENdHJ5R2V0SW50ZWdlcgECEnJlc2V0dXBfbGFzdFVwZGF0ZQMJAGYCBQlkYXlCbG9ja3MJAGUCBQZoZWlnaHQFC2xhc3RSZXNldHVwCQACAQIgY2FuIGJlIHVwZGF0ZWQgb25seSBvbmNlIHBlciBkYXkEA2x0cwkAtQkCCQEMdHJ5R2V0U3RyaW5nAQIJc2V0dXBfbHRzAgEsBAZhc3NldHMJAQ9nZXRNYXJrZXRBc3NldHMABAJ1cgkBBWdldFVyAQUKYXNzZXRJZFN0cgQGdGVtcExUCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgZzZXR1cF8FCmFzc2V0SWRTdHICB190ZW1wTFQEAmx0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGYXNzZXRzCQEFdmFsdWUBCQDPCAIFBmFzc2V0cwUKYXNzZXRJZFN0cgMJAGYCBQJ1cgCAlfUqCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIGc2V0dXBfBQphc3NldElkU3RyAgdfdGVtcExUCQBrAwUGdGVtcExUAPdNAJBOBQNuaWwDAwkAZgIFAmx0BQZ0ZW1wTFQJAGYCAICV9SoFAnVyBwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICBnNldHVwXwUKYXNzZXRJZFN0cgIHX3RlbXBMVAkAawMFBnRlbXBMVACpTgCQTgUDbmlsBQNuaWwBaQEIc2h1dGRvd24BCHNodXRkb3duAwkAAAIJAM8IAgURc2h1dGRvd25XaGl0ZWxpc3QIBQFpBmNhbGxlcgUEdW5pdAkAAgECF3VzZXIgbm90IGluIGEgd2hpdGVsaXN0CQDMCAIJAQxCb29sZWFuRW50cnkCAgxzZXR1cF9hY3RpdmUJAQEhAQUIc2h1dGRvd24FA25pbAFpAQlsaXF1aWRhdGUGBWRlYnVnB2FkZHJlc3MLYXNzZXRBbW91bnQLc0Fzc2V0SWRTdHILYkFzc2V0SWRTdHIIcm91dGVTdHIDCQEBIQEJARZ2ZXJpZnlMaXF1aWRhdG9yUmlnaHRzAQgFAWkGY2FsbGVyCQACAQIodGVtcG9yYXJpbHkgYXZhaWxhYmxlIGZvciB3aGl0ZWxpc3Qgb25seQMJAQEhAQkBDXRyeUdldEJvb2xlYW4BAgxzZXR1cF9hY3RpdmUJAAIBAhFtYXJrZXQgaXMgc3RvcHBlZAQOdXNlckNvbGxhdGVyYWwJARJjYWxjVXNlckNvbGxhdGVyYWwBBQdhZGRyZXNzAwkAAAIFDnVzZXJDb2xsYXRlcmFsBQ51c2VyQ29sbGF0ZXJhbAQNJHQwMjQyNDcyNDMwOQkBDWdldEFjdHVhbFJhdGUCBQtzQXNzZXRJZFN0cgIFc1JhdGUEBXNSYXRlCAUNJHQwMjQyNDcyNDMwOQJfMQQLcmF0ZXNSZXN1bHQIBQ0kdDAyNDI0NzI0MzA5Al8yBA0kdDAyNDMxNDI0MzgzCQENZ2V0QWN0dWFsUmF0ZQIFC2JBc3NldElkU3RyAgViUmF0ZQQFYlJhdGUIBQ0kdDAyNDMxNDI0MzgzAl8xBBJyYXRlc1JlY2FsY1Jlc3VsdDIIBQ0kdDAyNDMxNDI0MzgzAl8yBAxzQXNzZXRBbW91bnQJAGsDBQthc3NldEFtb3VudAUHU2NhbGUxNgUFc1JhdGUEEGN1cnJlbnRTUG9zaXRpb24JAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FC3NBc3NldElkU3RyBBNjdXJyZW50QlBvc2l0aW9uVmFsCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgQQY3VycmVudEJQb3NpdGlvbgMJAGYCBRNjdXJyZW50QlBvc2l0aW9uVmFsAAAFE2N1cnJlbnRCUG9zaXRpb25WYWwJAAIBAiB1c2VyIGhhcyBubyBib3Jyb3cgaW4gdGhpcyB0b2tlbgMJAGYCBQ51c2VyQ29sbGF0ZXJhbAAACQACAQIYdXNlciBjYW4ndCBiZSBsaXF1aWRhdGVkAwkAZgIFDHNBc3NldEFtb3VudAUQY3VycmVudFNQb3NpdGlvbgkAAgECMnBvc2l0aW9uIHRvIGxpcXVpZGF0ZSBpcyBiaWdnZXIgdGhhbiB1c2VyJ3Mgc3VwcGx5BA5iYWxhbmNlMEJlZm9yZQkBCmdldEJhbGFuY2UBBQtzQXNzZXRJZFN0cgMJAAACBQ5iYWxhbmNlMEJlZm9yZQUOYmFsYW5jZTBCZWZvcmUEDmJhbGFuY2UxQmVmb3JlCQEKZ2V0QmFsYW5jZQEFC2JBc3NldElkU3RyAwkAAAIFDmJhbGFuY2UxQmVmb3JlBQ5iYWxhbmNlMUJlZm9yZQQDaW52AwkBAiE9AgkBDHRyeUdldFN0cmluZwEJAKwCAgIQc2V0dXBfYXV0b3N0YWtlXwULc0Fzc2V0SWRTdHICAAkA/AcEBQR0aGlzAgx1bnN0YWtlVG9rZW4JAMwIAgULc0Fzc2V0SWRTdHIJAMwIAgUMc0Fzc2V0QW1vdW50BQNuaWwFA25pbAUEdW5pdAMJAAACBQNpbnYFA2ludgQOZXhjaGFuZ2VJbnZva2UJAPwHBAURYWdncmVnYXRvckFkZHJlc3MCBHN3YXAJAMwIAgUIcm91dGVTdHIJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ1nZXRBc3NldEJ5dGVzAQULc0Fzc2V0SWRTdHIFC2Fzc2V0QW1vdW50BQNuaWwDCQAAAgUOZXhjaGFuZ2VJbnZva2UFDmV4Y2hhbmdlSW52b2tlBAphc3NldDBTb2xkCQBlAgUOYmFsYW5jZTBCZWZvcmUJAQpnZXRCYWxhbmNlAQULc0Fzc2V0SWRTdHIDCQAAAgUKYXNzZXQwU29sZAUKYXNzZXQwU29sZAQMYXNzZXQxQm91Z2h0CQBlAgkBCmdldEJhbGFuY2UBBQtiQXNzZXRJZFN0cgUOYmFsYW5jZTFCZWZvcmUDCQAAAgUMYXNzZXQxQm91Z2h0BQxhc3NldDFCb3VnaHQEC2Fzc2V0MFByaWNlCAkBDWdldFRva2VuUHJpY2UBBQtzQXNzZXRJZFN0cgJfMQQLYXNzZXQwU2NhbGUJAQ5jYWxjQXNzZXRTY2FsZQEFC3NBc3NldElkU3RyBAlhc3NldDBVc2QJAGsDBQphc3NldDBTb2xkBQthc3NldDBQcmljZQULYXNzZXQwU2NhbGUEC2Fzc2V0MVByaWNlCAkBDWdldFRva2VuUHJpY2UBBQtiQXNzZXRJZFN0cgJfMgQLYXNzZXQxU2NhbGUJAQ5jYWxjQXNzZXRTY2FsZQEFC2JBc3NldElkU3RyBAlhc3NldDFVc2QJAGsDBQxhc3NldDFCb3VnaHQFC2Fzc2V0MVByaWNlBQthc3NldDFTY2FsZQQHcGVuYWx0eQkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgkBDHRyeUdldFN0cmluZwECD3NldHVwX3BlbmFsdGllcwIBLAkBBXZhbHVlAQkAzwgCCQEPZ2V0TWFya2V0QXNzZXRzAAULYkFzc2V0SWRTdHIEEWxpcXVpZGF0aW9uUHJvZml0CQBlAgUJYXNzZXQxVXNkCQBrAwUJYXNzZXQwVXNkCQBlAgUGU2NhbGU4BQdwZW5hbHR5BQZTY2FsZTgEDHNBc3NldENoYW5nZQkAawMFCmFzc2V0MFNvbGQFB1NjYWxlMTYFBXNSYXRlBAxiQXNzZXRDaGFuZ2UJAGsDCQBrAwUMYXNzZXQxQm91Z2h0BQdTY2FsZTE2BQViUmF0ZQkAZQIFBlNjYWxlOAkAawMFEWxpcXVpZGF0aW9uUHJvZml0BQZTY2FsZTgFCWFzc2V0MVVzZAUGU2NhbGU4AwkAZgIFCmFzc2V0MFNvbGQFC2Fzc2V0QW1vdW50CQACAQIjbW9yZSBhc3NldHMgZXhjaGFuZ2VkIHRoYW4gZXhwZWN0ZWQDCQBmAgAABRFsaXF1aWRhdGlvblByb2ZpdAkAAgECL3ByaWNlIGltcGFjdCBpcyBiaWdnZXIgdGhhbiBsaXF1aWRhdGlvbiBwZW5hbHR5CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIJAGUCBRBjdXJyZW50U1Bvc2l0aW9uBQxzQXNzZXRDaGFuZ2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgkAZQIFEGN1cnJlbnRCUG9zaXRpb24FDGJBc3NldENoYW5nZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9zdXBwbGllZF8FC3NBc3NldElkU3RyCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIFDHNBc3NldENoYW5nZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9ib3Jyb3dlZF8FC2JBc3NldElkU3RyCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwULYkFzc2V0SWRTdHIFDGJBc3NldENoYW5nZQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBC2xpcXVpZGF0ZVYyAwVkZWJ1ZwdhZGRyZXNzC3NBc3NldElkU3RyAwkBASEBCQEWdmVyaWZ5TGlxdWlkYXRvclJpZ2h0cwEIBQFpBmNhbGxlcgkAAgECKHRlbXBvcmFyaWx5IGF2YWlsYWJsZSBmb3Igd2hpdGVsaXN0IG9ubHkDCQEBIQEJAQ10cnlHZXRCb29sZWFuAQIMc2V0dXBfYWN0aXZlCQACAQIRbWFya2V0IGlzIHN0b3BwZWQECGJBc3NldElkCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQEC2JBc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBBQhiQXNzZXRJZAQMYkFzc2V0QW1vdW50CAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQOdXNlckNvbGxhdGVyYWwJARJjYWxjVXNlckNvbGxhdGVyYWwBBQdhZGRyZXNzAwkAAAIFDnVzZXJDb2xsYXRlcmFsBQ51c2VyQ29sbGF0ZXJhbAMJAGYCBQ51c2VyQ29sbGF0ZXJhbAAACQACAQIYdXNlciBjYW4ndCBiZSBsaXF1aWRhdGVkBAxtYXJrZXRBc3NldHMJAQ9nZXRNYXJrZXRBc3NldHMABAlhc3NldDFOdW0JAQV2YWx1ZQEJAM8IAgUMbWFya2V0QXNzZXRzBQtiQXNzZXRJZFN0cgQJYXNzZXQwTnVtCQEFdmFsdWUBCQDPCAIFDG1hcmtldEFzc2V0cwULc0Fzc2V0SWRTdHIEDSR0MDI3NzExMjc3NzMJAQ1nZXRBY3R1YWxSYXRlAgULYkFzc2V0SWRTdHICBWJSYXRlBAViUmF0ZQgFDSR0MDI3NzExMjc3NzMCXzEEC3JhdGVzUmVzdWx0CAUNJHQwMjc3MTEyNzc3MwJfMgQLYXNzZXQxUHJpY2UICQENZ2V0VG9rZW5QcmljZQEFC2JBc3NldElkU3RyAl8yBAthc3NldDFTY2FsZQkBDmNhbGNBc3NldFNjYWxlAQULYkFzc2V0SWRTdHIECmJBbW91bnRVc2QJAGsDBQxiQXNzZXRBbW91bnQFC2Fzc2V0MVByaWNlBQthc3NldDFTY2FsZQQHcGVuYWx0eQkBDXBhcnNlSW50VmFsdWUBCQEFdmFsdWUBCQCRAwIJALUJAgkBDHRyeUdldFN0cmluZwECD3NldHVwX3BlbmFsdGllcwIBLAUJYXNzZXQxTnVtBAthc3NldDBQcmljZQgJAQ1nZXRUb2tlblByaWNlAQULc0Fzc2V0SWRTdHICXzEEC2Fzc2V0MFNjYWxlCQEOY2FsY0Fzc2V0U2NhbGUBBQtzQXNzZXRJZFN0cgQKc0Ftb3VudFVzZAkAawMFCmJBbW91bnRVc2QJAGQCBQZTY2FsZTgFB3BlbmFsdHkFBlNjYWxlOAQMc0Fzc2V0QW1vdW50CQBrAwUKc0Ftb3VudFVzZAULYXNzZXQwU2NhbGUFC2Fzc2V0MFByaWNlBAdiQW1vdW50CQBrAwUMYkFzc2V0QW1vdW50BQdTY2FsZTE2BQViUmF0ZQQHc0Ftb3VudAkAawMFDHNBc3NldEFtb3VudAUHU2NhbGUxNggJAJEDAgULcmF0ZXNSZXN1bHQJAGgCBQlhc3NldDBOdW0AAwV2YWx1ZQQQY3VycmVudFNQb3NpdGlvbgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIEE2N1cnJlbnRCUG9zaXRpb25WYWwJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FC2JBc3NldElkU3RyBBBjdXJyZW50QlBvc2l0aW9uAwkAZgIFE2N1cnJlbnRCUG9zaXRpb25WYWwAAAUTY3VycmVudEJQb3NpdGlvblZhbAkAAgECIHVzZXIgaGFzIG5vIGJvcnJvdyBpbiB0aGlzIHRva2VuAwkAZgIFB3NBbW91bnQFEGN1cnJlbnRTUG9zaXRpb24JAAIBAjJwb3NpdGlvbiB0byBsaXF1aWRhdGUgaXMgYmlnZ2VyIHRoYW4gdXNlcidzIHN1cHBseQQDaW52AwkBAiE9AgkBDHRyeUdldFN0cmluZwEJAKwCAgIQc2V0dXBfYXV0b3N0YWtlXwULc0Fzc2V0SWRTdHICAAkA/AcEBQR0aGlzAgx1bnN0YWtlVG9rZW4JAMwIAgULc0Fzc2V0SWRTdHIJAMwIAgUMc0Fzc2V0QW1vdW50BQNuaWwFA25pbAUEdW5pdAMJAAACBQNpbnYFA2ludgMFBWRlYnVnCQACAQIVbGlxdWlkYXRpb24gd2lsbCBwYXNzCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQxzQXNzZXRBbW91bnQJAQ1nZXRBc3NldEJ5dGVzAQULc0Fzc2V0SWRTdHIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQtzQXNzZXRJZFN0cgkAZQIFEGN1cnJlbnRTUG9zaXRpb24FB3NBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgkAZQIFEGN1cnJlbnRCUG9zaXRpb24FB2JBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQtzQXNzZXRJZFN0cgkAZQIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FC3NBc3NldElkU3RyBQdzQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX2JvcnJvd2VkXwULYkFzc2V0SWRTdHIJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgUHYkFtb3VudAUDbmlsBQtyYXRlc1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARFnZXRVc2VyQ29sbGF0ZXJhbAQFZGVidWcHYWRkcmVzcw1taW51c0JvcnJvd2VkC2FmdGVyQ2hhbmdlBAZhc3NldHMJAQ9nZXRNYXJrZXRBc3NldHMABARsdHZzCQC1CQIJAQx0cnlHZXRTdHJpbmcBAgpzZXR1cF9sdHZzAgEsBANsdHMJALUJAgkBDHRyeUdldFN0cmluZwECCXNldHVwX2x0cwIBLAQFcmF0ZXMICQENZ2V0QWN0dWFsUmF0ZQIJAJEDAgUGYXNzZXRzAAACBXNSYXRlAl8yBA1jaGFuZ2VIYW5kbGVyCQC1CQIFC2FmdGVyQ2hhbmdlAgEsCgEBZgIFYWNjdW0EbmV4dAMJAGcCBQRuZXh0CQCQAwEFBmFzc2V0cwUFYWNjdW0EDHVzZXJTdXBwbGllZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwkAkQMCBQZhc3NldHMFBG5leHQEDHVzZXJCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwkAkQMCBQZhc3NldHMFBG5leHQEE25lZWRUb2tlbkFjY291bnRpbmcDCQAAAgULYWZ0ZXJDaGFuZ2UCAAMDCQECIT0CBQx1c2VyQm9ycm93ZWQAAAYJAQIhPQIFDHVzZXJTdXBwbGllZAAABgcGAwUTbmVlZFRva2VuQWNjb3VudGluZwQKYXNzZXRTY2FsZQkBDmNhbGNBc3NldFNjYWxlAQkAkQMCBQZhc3NldHMFBG5leHQECmFzc2V0UHJpY2UJAQ1nZXRUb2tlblByaWNlAQkAkQMCBQZhc3NldHMFBG5leHQJAGUCCQBkAgUFYWNjdW0JAGsDCQBrAwkAawMJAGQCBQx1c2VyU3VwcGxpZWQDAwMJAQIhPQIFC2FmdGVyQ2hhbmdlAgAJAAACCQCRAwIFDWNoYW5nZUhhbmRsZXIAAAkAkQMCBQZhc3NldHMFBG5leHQHCQAAAgkAkQMCBQ1jaGFuZ2VIYW5kbGVyAAECCHN1cHBsaWVkBwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDWNoYW5nZUhhbmRsZXIAAgAACAkAkQMCBQVyYXRlcwkAaAIFBG5leHQAAwV2YWx1ZQUHU2NhbGUxNgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGx0dnMFBG5leHQF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MF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAMFBWRlYnVnCQACAQUJcGFyYW1ldGVyCQCUCgIFA25pbAUJcGFyYW1ldGVyAWkBDWluaXROZXdNYXN0ZXIBBm1hc3RlcgQJYWRkcmVzc09LBAckbWF0Y2gwCQCmCAEFBm1hc3RlcgMJAAECBQckbWF0Y2gwAgdBZGRyZXNzBAFhBQckbWF0Y2gwBgcDCQEBIQEFCWFkZHJlc3NPSwkAAgEJAKwCAgISaW5jb3JyZWN0IGFkZHJlc3MgBQZtYXN0ZXIDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhxhdmFpbGFibGUgZm9yIHNlbGYgY2FsbCBvbmx5CQDMCAIJAQtTdHJpbmdFbnRyeQICD3ZlcmlmaWVyX21hc3RlcgUGbWFzdGVyBQNuaWwBaQEQcmVxdWVzdE5ld01hc3RlcgEJbmV3TWFzdGVyBAlhZGRyZXNzT0sEByRtYXRjaDAJAKYIAQUJbmV3TWFzdGVyAwkAAQIFByRtYXRjaDACB0FkZHJlc3MEAWEFByRtYXRjaDAGBwMJAQEhAQUJYWRkcmVzc09LCQACAQkArAICAhJpbmNvcnJlY3QgYWRkcmVzcyAFCW5ld01hc3RlcgMJAAACCQDPCAIFCXNlbnRpbmVscwgFAWkGY2FsbGVyBQR1bml0CQACAQIOd2hpdGVsaXN0IG9ubHkJAMwIAgkBC1N0cmluZ0VudHJ5AgISdmVyaWZpZXJfbmV3TWFzdGVyBQluZXdNYXN0ZXIJAMwIAgkBDEludGVnZXJFbnRyeQICH3ZlcmlmaWVyX25ld01hc3RlckVsaWdpYmxlQWZ0ZXIJAGQCBQZoZWlnaHQAkE4FA25pbAFpARFhY3RpdmF0ZU5ld01hc3RlcgAEDmVsaWdpYmxlSGVpZ2h0CQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzAh92ZXJpZmllcl9uZXdNYXN0ZXJFbGlnaWJsZUFmdGVyBAluZXdNYXN0ZXIJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMCEnZlcmlmaWVyX25ld01hc3RlcgMJAAACCQDPCAIFCXNlbnRpbmVscwgFAWkGY2FsbGVyBQR1bml0CQACAQIOd2hpdGVsaXN0IG9ubHkDCQBmAgUOZWxpZ2libGVIZWlnaHQFBmhlaWdodAkAAgECIm5ldyBtYXN0ZXIgY2Fubm90IGJlIGFjdGl2YXRlZCB5ZXQJAMwIAgkBC0RlbGV0ZUVudHJ5AQISdmVyaWZpZXJfbmV3TWFzdGVyCQDMCAIJAQtEZWxldGVFbnRyeQECH3ZlcmlmaWVyX25ld01hc3RlckVsaWdpYmxlQWZ0ZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgIPdmVyaWZpZXJfbWFzdGVyBQluZXdNYXN0ZXIFA25pbAECdHgBBnZlcmlmeQAEDW1hc3RlckFkZHJlc3MJAKIIAQIPdmVyaWZpZXJfbWFzdGVyBBBhcHByb3ZlZEJ5TWFzdGVyBAckbWF0Y2gwBQ1tYXN0ZXJBZGRyZXNzAwkAAQIFByRtYXRjaDACBlN0cmluZwQBeAUHJG1hdGNoMAQHJG1hdGNoMQkAmggCCQERQGV4dHJOYXRpdmUoMTA2MikBBQF4CQCsAgICC2FwcHJvdmVkVHhfCQDYBAEIBQJ0eAJpZAMJAAECBQckbWF0Y2gxAgNJbnQEAXkFByRtYXRjaDEFAXkAAAABAwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAgFAnR4D3NlbmRlclB1YmxpY0tleQkAZgIFEGFwcHJvdmVkQnlNYXN0ZXIAAAesHZtL", "height": 4099530, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: ERtF3zw9ZcN5AaRH4Kucm8SNDiGXcqeaD5ZEsTfUgTYp Next: JAPaqb9WL68BUXKRATgf4kw6QKJ9xrjfETh4sJjMWh9x Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let VERSION = "PLP-1.0.6"
4+let VERSION = "PLP-1.0.7"
55
66 func getAddressFromState (key) = valueOrElse(addressFromString(valueOrElse(getString(this, ("setup_address_" + key)), "3PEwRcYNAUtoFvKpBhKoiwajnZfdoDR6h4h")), Address(base58'3PEwRcYNAUtoFvKpBhKoiwajnZfdoDR6h4h'))
77
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let VERSION = "PLP-1.0.6"
4+let VERSION = "PLP-1.0.7"
55
66 func getAddressFromState (key) = valueOrElse(addressFromString(valueOrElse(getString(this, ("setup_address_" + key)), "3PEwRcYNAUtoFvKpBhKoiwajnZfdoDR6h4h")), Address(base58'3PEwRcYNAUtoFvKpBhKoiwajnZfdoDR6h4h'))
77
88
99 func getAddressesFromState (key) = {
1010 func f (accum,next) = (accum ++ [valueOrElse(addressFromString(next), Address(base58'3PEwRcYNAUtoFvKpBhKoiwajnZfdoDR6h4h'))])
1111
1212 let $l = split_4C(valueOrElse(getString(this, ("setup_address_" + key)), "3PEwRcYNAUtoFvKpBhKoiwajnZfdoDR6h4h"), ",")
1313 let $s = size($l)
1414 let $acc0 = nil
1515 func $f0_1 ($a,$i) = if (($i >= $s))
1616 then $a
1717 else f($a, $l[$i])
1818
1919 func $f0_2 ($a,$i) = if (($i >= $s))
2020 then $a
2121 else throw("List size exceeds 15")
2222
2323 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($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), 11), 12), 13), 14), 15)
2424 }
2525
2626
2727 let reserveFundAddress = getAddressFromState("reserveFund")
2828
2929 let oracleAddress = getAddressFromState("oracle")
3030
3131 let aggregatorAddress = getAddressFromState("aggregator")
3232
3333 let wxStakingAddress = getAddressFromState("staking")
3434
3535 let adminAddress = getAddressFromState("admin")
3636
3737 let stableFundAddress = getAddressFromState("stableFund")
3838
3939 let shutdownWhitelist = getAddressesFromState("shutdownCallers")
4040
4141 let liquidatorsWhitelist = getAddressesFromState("liquidators")
4242
4343 func verifyLiquidatorRights (address) = (indexOf(liquidatorsWhitelist, address) != unit)
4444
4545
4646 let reserveFund = valueOrElse(getInteger(this, "setup_reserveFundFee"), 20)
4747
4848 let stablesIdStr = split(valueOrElse(getString(this, "setup_stablesIds"), "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi,HGgabTqUS8WtVFUJzfmrTDMgEccJuZLBPhFgQFxvnsoW"), ",")
4949
5050 func getRateCurve (assetIdStr) = {
5151 let curveRateStrLi = split(valueOrElse(getString(this, ("setup_rateCurve_" + assetIdStr)), "20000000,100000000,60000000,400000000"), ",")
5252 $Tuple4(parseIntValue(curveRateStrLi[0]), parseIntValue(curveRateStrLi[1]), parseIntValue(curveRateStrLi[2]), parseIntValue(curveRateStrLi[3]))
5353 }
5454
5555
5656 func getRewardsSplitting (assetIdStr) = {
5757 let rewardsSplittingStrLi = split(valueOrElse(getString(this, ("setup_rewardsSplitting_" + assetIdStr)), "30,50,20"), ",")
5858 $Tuple3(parseIntValue(rewardsSplittingStrLi[0]), parseIntValue(rewardsSplittingStrLi[1]), parseIntValue(rewardsSplittingStrLi[2]))
5959 }
6060
6161
6262 let sentinels = [Address(base58'3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL'), Address(base58'3PQdNxynJy5mche2kxMVc5shXWzK8Gstq3o'), Address(base58'3P8auNWJkxxByyJtwErFXaxiXcGM45qQ1hA'), Address(base58'3P8qVX189qpoTJZQQQdKS9endHK5sxWsvrd')]
6363
6464 let Scale8 = 100000000
6565
6666 let Scale10 = 10000000000
6767
6868 let Scale16 = (Scale8 * Scale8)
6969
7070 let dayBlocks = 1440
7171
7272 func liIntToStr (li) = {
7373 func f (accum,next) = ((accum + toString(next)) + ",")
7474
7575 let $l = li
7676 let $s = size($l)
7777 let $acc0 = ""
7878 func $f0_1 ($a,$i) = if (($i >= $s))
7979 then $a
8080 else f($a, $l[$i])
8181
8282 func $f0_2 ($a,$i) = if (($i >= $s))
8383 then $a
8484 else throw("List size exceeds 12")
8585
8686 $f0_2($f0_1($f0_1($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), 11), 12)
8787 }
8888
8989
9090 func tryGetInteger (key) = match getInteger(this, key) {
9191 case b: Int =>
9292 b
9393 case _ =>
9494 0
9595 }
9696
9797
9898 func tryGetBoolean (key) = match getBoolean(this, key) {
9999 case b: Boolean =>
100100 b
101101 case _ =>
102102 false
103103 }
104104
105105
106106 func tryGetString (key) = match getString(this, key) {
107107 case b: String =>
108108 b
109109 case _ =>
110110 ""
111111 }
112112
113113
114114 func tryGetBinary (key) = match getBinary(this, key) {
115115 case b: ByteVector =>
116116 b
117117 case _ =>
118118 base58''
119119 }
120120
121121
122122 func getAssetString (assetId) = match assetId {
123123 case b: ByteVector =>
124124 toBase58String(b)
125125 case _ =>
126126 "WAVES"
127127 }
128128
129129
130130 func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
131131 then unit
132132 else fromBase58String(assetIdStr)
133133
134134
135135 func getBalance (assetIdStr) = if ((assetIdStr == "WAVES"))
136136 then wavesBalance(this).available
137137 else assetBalance(this, fromBase58String(assetIdStr))
138138
139139
140140 func getMarketAssets () = split(tryGetString("setup_tokens"), ",")
141141
142142
143143 func getOutdatedUr (assetIdStr) = {
144144 let down = fraction(tryGetInteger(("total_supplied_" + assetIdStr)), tryGetInteger((assetIdStr + "_sRate")), Scale16)
145145 if ((down == 0))
146146 then 0
147147 else fraction(Scale8, fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), tryGetInteger((assetIdStr + "_bRate")), Scale16), down)
148148 }
149149
150150
151151 func getInterest (assetIdStr) = {
152152 let ur = getOutdatedUr(assetIdStr)
153153 let curve = getRateCurve(assetIdStr)
154154 let rate = (curve._1 + (if ((curve._3 >= ur))
155155 then fraction(ur, curve._2, curve._3)
156156 else (curve._2 + fraction((ur - curve._3), curve._4, (100000000 - curve._3)))))
157157 max([fraction(rate, Scale8, (dayBlocks * 365)), 1])
158158 }
159159
160160
161161 func tokenRatesRecalc (assetIdStr) = {
162162 let interest = getInterest(assetIdStr)
163163 let ur = getOutdatedUr(assetIdStr)
164164 let lastRecalcHeight = tryGetInteger("lastRateHeight")
165165 let lastBRate = max([tryGetInteger((assetIdStr + "_bRate")), Scale16])
166166 let newBRate = (lastBRate + ((height - lastRecalcHeight) * interest))
167167 let lastSRate = max([tryGetInteger((assetIdStr + "_sRate")), Scale16])
168168 let newSRate = (lastSRate + ((((height - lastRecalcHeight) * fraction(interest, ur, Scale8)) * (100 - reserveFund)) / 100))
169169 [IntegerEntry((assetIdStr + "_sRate"), newSRate), IntegerEntry((assetIdStr + "_bRate"), newBRate), IntegerEntry("lastRateHeight", height)]
170170 }
171171
172172
173173 func getActualRate (assetIdStr,rateType) = {
174174 func f (accum,token) = {
175175 let recalc = tokenRatesRecalc(token)
176176 $Tuple2(if ((token != assetIdStr))
177177 then accum._1
178178 else if ((rateType == "sRate"))
179179 then recalc[0].value
180180 else recalc[1].value, (accum._2 ++ recalc))
181181 }
182182
183183 let $l = getMarketAssets()
184184 let $s = size($l)
185185 let $acc0 = $Tuple2(0, nil)
186186 func $f0_1 ($a,$i) = if (($i >= $s))
187187 then $a
188188 else f($a, $l[$i])
189189
190190 func $f0_2 ($a,$i) = if (($i >= $s))
191191 then $a
192192 else throw("List size exceeds 12")
193193
194194 $f0_2($f0_1($f0_1($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), 11), 12)
195195 }
196196
197197
198198 func getUr (assetIdStr) = {
199199 let rates = tokenRatesRecalc(assetIdStr)
200200 let down = fraction(tryGetInteger(("total_supplied_" + assetIdStr)), rates[0].value, Scale16)
201201 fraction(Scale8, fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), rates[1].value, Scale16), down)
202202 }
203203
204204
205205 func ratesRecalc () = {
206206 func f (accum,token) = (accum ++ tokenRatesRecalc(token))
207207
208208 let $l = getMarketAssets()
209209 let $s = size($l)
210210 let $acc0 = nil
211211 func $f0_1 ($a,$i) = if (($i >= $s))
212212 then $a
213213 else f($a, $l[$i])
214214
215215 func $f0_2 ($a,$i) = if (($i >= $s))
216216 then $a
217217 else throw("List size exceeds 12")
218218
219219 $f0_2($f0_1($f0_1($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), 11), 12)
220220 }
221221
222222
223223 func getTokenPriceWithRisk (assetIdStr,riskAversity) = if ((indexOf(stablesIdStr, assetIdStr) != unit))
224224 then $Tuple2(1000000, 1000000)
225225 else {
226226 let price = getIntegerValue(oracleAddress, (assetIdStr + "_twap5B"))
227227 let riskLevel = getIntegerValue(oracleAddress, (assetIdStr + "_riskLevel"))
228228 if ((riskAversity >= riskLevel))
229229 then $Tuple2(price, price)
230230 else throw((("oracle prices don't match: " + toString(price)) + " is the price, but risk is too high"))
231231 }
232232
233233
234234 func getTokenPrice (assetIdStr) = getTokenPriceWithRisk(assetIdStr, 3)
235235
236236
237237 func calcAssetScale (assetIdStr) = {
238238 let decimals = if ((assetIdStr == "WAVES"))
239239 then 8
240240 else value(assetInfo(fromBase58String(assetIdStr))).decimals
241241 pow(10, 0, decimals, 0, 0, DOWN)
242242 }
243243
244244
245245 func calcUserCollateral (address) = {
246246 let userCollateralInvoke = invoke(this, "getUserCollateral", [false, address, true, ""], nil)
247247 if ((userCollateralInvoke == userCollateralInvoke))
248248 then {
249249 let userCollateralValue = match userCollateralInvoke {
250250 case x: Int =>
251251 x
252252 case _ =>
253253 throw("issue while doing in-dapp invocation")
254254 }
255255 if ((userCollateralValue == userCollateralValue))
256256 then userCollateralValue
257257 else throw("Strict value is not equal to itself.")
258258 }
259259 else throw("Strict value is not equal to itself.")
260260 }
261261
262262
263263 @Callable(i)
264264 func supply () = if (!(tryGetBoolean("setup_active")))
265265 then throw("market is stopped")
266266 else if (if ((size(i.payments) != 1))
267267 then true
268268 else (i.payments[0].amount == 0))
269269 then throw("1 payment has to be attached")
270270 else {
271271 let assetIdStr = getAssetString(i.payments[0].assetId)
272272 let assetAmount = i.payments[0].amount
273273 let $t083968463 = getActualRate(assetIdStr, "sRate")
274274 let sRate = $t083968463._1
275275 let ratesRecalcResult = $t083968463._2
276276 let amount = fraction(assetAmount, Scale16, sRate, DOWN)
277277 let address = toString(i.caller)
278278 let maxSupply = match getString(("setup_maxSupply_" + assetIdStr)) {
279279 case x: String =>
280280 parseIntValue(x)
281281 case _ =>
282282 tryGetInteger(("setup_maxSupply_" + assetIdStr))
283283 }
284284 let assetPrice = getTokenPrice(assetIdStr)
285285 let newAddressSupplied = (tryGetInteger(((address + "_supplied_") + assetIdStr)) + amount)
286286 let newTotalSupplied = (tryGetInteger(("total_supplied_" + assetIdStr)) + amount)
287287 let rate = getActualRate(assetIdStr, "sRate")._1
288288 let assetScale = calcAssetScale(assetIdStr)
289289 let newTotalSuppliedUsd = fraction(fraction(newTotalSupplied, rate, Scale16), assetPrice._1, assetScale)
290290 if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
291291 then throw("this asset is not supported by the market")
292292 else if (if ((maxSupply != 0))
293293 then (newTotalSuppliedUsd > maxSupply)
294294 else false)
295295 then throw("max total supply for this token reached in the pool")
296296 else if ((tryGetInteger(("setup_paused_" + assetIdStr)) > 0))
297297 then throw("this asset can't be supplied or borrowed")
298298 else {
299299 let inv = if ((tryGetString(("setup_autostake_" + assetIdStr)) != ""))
300300 then invoke(this, "stakeToken", [assetIdStr, assetAmount], nil)
301301 else unit
302302 if ((inv == inv))
303303 then ([IntegerEntry(((address + "_supplied_") + assetIdStr), newAddressSupplied), IntegerEntry(("total_supplied_" + assetIdStr), newTotalSupplied)] ++ ratesRecalcResult)
304304 else throw("Strict value is not equal to itself.")
305305 }
306306 }
307307
308308
309309
310310 @Callable(i)
311311 func withdraw (assetIdStr,assetAmount) = {
312312 let $t01002410091 = getActualRate(assetIdStr, "sRate")
313313 let sRate = $t01002410091._1
314314 let ratesRecalcResult = $t01002410091._2
315315 let amount = fraction(assetAmount, Scale16, sRate, CEILING)
316316 let address = toString(i.caller)
317317 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
318318 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
319319 let userAssetSupplied = tryGetInteger(((address + "_supplied_") + assetIdStr))
320320 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
321321 let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",supplied,") + toString(-(amount)))], nil)
322322 if ((collateralValueInv == collateralValueInv))
323323 then {
324324 let collateralValue = match collateralValueInv {
325325 case x: Int =>
326326 x
327327 case _ =>
328328 throw("can't get user collateral value")
329329 }
330330 if (!(tryGetBoolean("setup_active")))
331331 then throw("market is stopped")
332332 else if ((0 > collateralValue))
333333 then throw("you dont have enough collateral for this operation")
334334 else if ((amount > (assetSupplied - assetBorrowed)))
335335 then throw("this amount is not available on the market")
336336 else if ((amount > (userAssetSupplied - userAssetBorrowed)))
337337 then throw("this amount is not available for this user")
338338 else {
339339 let inv = if ((tryGetString(("setup_autostake_" + assetIdStr)) != ""))
340340 then invoke(this, "unstakeToken", [assetIdStr, assetAmount], nil)
341341 else unit
342342 if ((inv == inv))
343343 then ([IntegerEntry(((address + "_supplied_") + assetIdStr), (tryGetInteger(((address + "_supplied_") + assetIdStr)) - amount)), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) - amount)), ScriptTransfer(i.caller, assetAmount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult)
344344 else throw("Strict value is not equal to itself.")
345345 }
346346 }
347347 else throw("Strict value is not equal to itself.")
348348 }
349349
350350
351351
352352 @Callable(i)
353353 func borrow (assetIdStr,assetAmount) = {
354354 let address = toString(i.caller)
355355 let $t01174711814 = getActualRate(assetIdStr, "bRate")
356356 let bRate = $t01174711814._1
357357 let ratesRecalcResult = $t01174711814._2
358358 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
359359 let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",borrowed,") + toString(amount))], nil)
360360 if ((collateralValueInv == collateralValueInv))
361361 then {
362362 let collateralValue = match collateralValueInv {
363363 case x: Int =>
364364 x
365365 case _ =>
366366 throw("can't get user collateral value")
367367 }
368368 if (!(tryGetBoolean("setup_active")))
369369 then throw("market is stopped")
370370 else if ((0 > collateralValue))
371371 then throw("you have to supply more to borrow")
372372 else if ((tryGetInteger(("setup_paused_" + assetIdStr)) > 0))
373373 then throw("this asset can't be supplied or borrowed")
374374 else {
375375 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
376376 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
377377 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
378378 if ((amount > (assetSupplied - assetBorrowed)))
379379 then throw("this amount is not available")
380380 else {
381381 let inv = if ((tryGetString(("setup_autostake_" + assetIdStr)) != ""))
382382 then invoke(this, "unstakeToken", [assetIdStr, assetAmount], nil)
383383 else unit
384384 if ((inv == inv))
385385 then ([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed + amount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed + amount)), ScriptTransfer(i.caller, assetAmount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult)
386386 else throw("Strict value is not equal to itself.")
387387 }
388388 }
389389 }
390390 else throw("Strict value is not equal to itself.")
391391 }
392392
393393
394394
395395 @Callable(i)
396396 func repay () = if (!(tryGetBoolean("setup_active")))
397397 then throw("market is stopped")
398398 else if (if ((size(i.payments) != 1))
399399 then true
400400 else (i.payments[0].amount == 0))
401401 then throw("1 payment has to be attached")
402402 else {
403403 let assetIdStr = getAssetString(i.payments[0].assetId)
404404 let assetAmount = i.payments[0].amount
405405 let $t01359013657 = getActualRate(assetIdStr, "bRate")
406406 let bRate = $t01359013657._1
407407 let ratesRecalcResult = $t01359013657._2
408408 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
409409 let address = toString(i.caller)
410410 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
411411 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
412412 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
413413 let amountLeft = (userAssetBorrowed - amount)
414414 let repayAmount = if ((amountLeft >= 0))
415415 then amount
416416 else userAssetBorrowed
417417 if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
418418 then throw("this asset is not supported by the market")
419419 else {
420420 let inv = if ((tryGetString(("setup_autostake_" + assetIdStr)) != ""))
421421 then invoke(this, "stakeToken", [assetIdStr, assetAmount], nil)
422422 else unit
423423 if ((inv == inv))
424424 then (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
425425 then nil
426426 else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
427427 else throw("Strict value is not equal to itself.")
428428 }
429429 }
430430
431431
432432
433433 @Callable(i)
434434 func repayFor (address) = if (!(tryGetBoolean("setup_active")))
435435 then throw("market is stopped")
436436 else if ((i.caller != reserveFundAddress))
437437 then throw("available only for reserve fund address")
438438 else if ((address == "global"))
439439 then throw("you can't repay for everyone :_)")
440440 else if (if ((size(i.payments) != 1))
441441 then true
442442 else (i.payments[0].amount == 0))
443443 then throw("1 payment has to be attached")
444444 else {
445445 let assetIdStr = getAssetString(i.payments[0].assetId)
446446 let assetAmount = i.payments[0].amount
447447 let $t01530815375 = getActualRate(assetIdStr, "bRate")
448448 let bRate = $t01530815375._1
449449 let ratesRecalcResult = $t01530815375._2
450450 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
451451 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
452452 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
453453 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
454454 let amountLeft = (userAssetBorrowed - amount)
455455 let repayAmount = if ((amountLeft >= 0))
456456 then amount
457457 else userAssetBorrowed
458458 if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
459459 then throw("this asset is not supported by the market")
460460 else {
461461 let inv = if ((tryGetString(("setup_autostake_" + assetIdStr)) != ""))
462462 then invoke(this, "stakeToken", [assetIdStr, assetAmount], nil)
463463 else unit
464464 if ((inv == inv))
465465 then (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
466466 then nil
467467 else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
468468 else throw("Strict value is not equal to itself.")
469469 }
470470 }
471471
472472
473473
474474 @Callable(i)
475475 func stakeToken (assetIdStr,amount) = {
476476 let wxStakerSupportedAssets = getStringValue(wxStakingAddress, "setup_supportedAssets")
477477 if ((i.caller != this))
478478 then throw("only for internal smart contract invocations")
479479 else if ((indexOf(wxStakerSupportedAssets, assetIdStr) == unit))
480480 then nil
481481 else {
482482 let amountStaked = tryGetInteger(("autostake_amount_" + assetIdStr))
483483 let stakeInv = reentrantInvoke(wxStakingAddress, "stakeLP", nil, [AttachedPayment(getAssetBytes(assetIdStr), amount)])
484484 if ((stakeInv == stakeInv))
485485 then [IntegerEntry(("autostake_amount_" + assetIdStr), (amountStaked + amount))]
486486 else throw("Strict value is not equal to itself.")
487487 }
488488 }
489489
490490
491491
492492 @Callable(i)
493493 func stakeTokenAll (assetIdStr) = if ((i.caller != this))
494494 then throw("only for internal smart contract invocations")
495495 else {
496496 let amount = getBalance(assetIdStr)
497497 let inv = reentrantInvoke(this, "stakeToken", [assetIdStr, amount], nil)
498498 if ((inv == inv))
499499 then nil
500500 else throw("Strict value is not equal to itself.")
501501 }
502502
503503
504504
505505 @Callable(i)
506506 func unstakeToken (assetIdStr,amount) = {
507507 let wxStakerSupportedAssets = getStringValue(wxStakingAddress, "setup_supportedAssets")
508508 if ((i.caller != this))
509509 then throw("only for internal smart contract invocations")
510510 else if ((indexOf(wxStakerSupportedAssets, assetIdStr) == unit))
511511 then nil
512512 else {
513513 let amountStaked = tryGetInteger(("autostake_amount_" + assetIdStr))
514514 let stakeInv = reentrantInvoke(wxStakingAddress, "unstakeLP", [assetIdStr, amount], nil)
515515 if ((stakeInv == stakeInv))
516516 then [IntegerEntry(("autostake_amount_" + assetIdStr), (amountStaked - amount))]
517517 else throw("Strict value is not equal to itself.")
518518 }
519519 }
520520
521521
522522
523523 @Callable(i)
524524 func addInterest (assetIdStr,amount) = if ((i.caller != this))
525525 then throw("only for self invocation")
526526 else {
527527 let earned = tryGetInteger(("autostake_lastEarned_" + assetIdStr))
528528 let lastHeight = tryGetInteger(("autostake_lastBlock_" + assetIdStr))
529529 let cleanAmount = fraction(amount, 80, 100)
530530 let stateChanges = if (if ((lastHeight == height))
531531 then true
532532 else (amount == 0))
533533 then nil
534534 else [IntegerEntry(("autostake_preLastEarned_" + assetIdStr), earned), IntegerEntry(("autostake_preLastBlock_" + assetIdStr), lastHeight), IntegerEntry(("autostake_lastEarned_" + assetIdStr), (earned + cleanAmount)), IntegerEntry(("autostake_lastBlock_" + assetIdStr), height)]
535535 (stateChanges ++ [IntegerEntry((assetIdStr + "_sRate"), (tryGetInteger((assetIdStr + "_sRate")) + fraction(Scale16, cleanAmount, tryGetInteger(("total_supplied_" + assetIdStr)))))])
536536 }
537537
538538
539539
540540 @Callable(i)
541541 func addInterestEXTERNAL () = {
542542 let assetId = i.payments[0].assetId
543543 let assetIdStr = getAssetString(assetId)
544544 let splitting = getRewardsSplitting(assetIdStr)
545545 let amount = fraction(i.payments[0].amount, splitting._2, 100)
546546 let earned = tryGetInteger(("autostake_lastEarned_" + assetIdStr))
547547 let lastHeight = tryGetInteger(("autostake_lastBlock_" + assetIdStr))
548548 let stateChanges = if (if ((lastHeight == height))
549549 then true
550550 else (amount == 0))
551551 then nil
552552 else [IntegerEntry(("autostake_preLastEarned_" + assetIdStr), earned), IntegerEntry(("autostake_preLastBlock_" + assetIdStr), lastHeight), IntegerEntry(("autostake_lastEarned_" + assetIdStr), (earned + amount)), IntegerEntry(("autostake_lastBlock_" + assetIdStr), height)]
553553 (stateChanges ++ [IntegerEntry((assetIdStr + "_sRate"), (tryGetInteger((assetIdStr + "_sRate")) + fraction(Scale16, amount, tryGetInteger(("total_supplied_" + assetIdStr))))), ScriptTransfer(stableFundAddress, fraction(i.payments[0].amount, splitting._1, 100), assetId)])
554554 }
555555
556556
557557
558558 @Callable(i)
559559 func preInit (tokens,ltvs,lts,penalties) = {
560560 func f (accum,token) = (accum ++ [IntegerEntry((token + "_bRate"), Scale16), IntegerEntry((token + "_sRate"), Scale16)])
561561
562562 if ((i.caller != this))
563563 then throw("admin only")
564564 else {
565565 let rates = {
566566 let $l = split(tokens, ",")
567567 let $s = size($l)
568568 let $acc0 = nil
569569 func $f0_1 ($a,$i) = if (($i >= $s))
570570 then $a
571571 else f($a, $l[$i])
572572
573573 func $f0_2 ($a,$i) = if (($i >= $s))
574574 then $a
575575 else throw("List size exceeds 12")
576576
577577 $f0_2($f0_1($f0_1($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), 11), 12)
578578 }
579579 ([StringEntry("setup_tokens", tokens), StringEntry("setup_ltvs", ltvs), StringEntry("setup_lts", lts), StringEntry("setup_penalties", penalties), BooleanEntry("setup_active", true)] ++ rates)
580580 }
581581 }
582582
583583
584584
585585 @Callable(i)
586586 func initNewToken (token,ltv,lt,penalty) = if ((i.caller != this))
587587 then throw("admin only")
588588 else [StringEntry("setup_tokens", ((tryGetString("setup_tokens") + ",") + token)), StringEntry("setup_ltvs", ((tryGetString("setup_ltvs") + ",") + ltv)), StringEntry("setup_lts", ((tryGetString("setup_lts") + ",") + lt)), StringEntry("setup_penalties", ((tryGetString("setup_penalties") + ",") + penalty)), IntegerEntry((token + "_bRate"), Scale16), IntegerEntry((token + "_sRate"), Scale16)]
589589
590590
591591
592592 @Callable(i)
593593 func updateParameter (key,val) = if (if ((i.caller != this))
594594 then (i.caller != adminAddress)
595595 else false)
596596 then throw("admin only")
597597 else [IntegerEntry(key, parseIntValue(val))]
598598
599599
600600
601601 @Callable(i)
602602 func updateString (key,val) = if (if ((i.caller != this))
603603 then (i.caller != adminAddress)
604604 else false)
605605 then throw("admin only")
606606 else [StringEntry(key, val)]
607607
608608
609609
610610 @Callable(i)
611611 func claimToReserveFund (debug) = {
612612 let assets = getMarketAssets()
613613 let rates = getActualRate(assets[0], "sRate")._2
614614 let li = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
615615 func f (accum,n) = if ((n >= size(assets)))
616616 then accum
617617 else {
618618 let assetIdStr = assets[n]
619619 let autostakeAmount = tryGetString(("autostake_amount_" + assetIdStr))
620620 let amount = ((((getBalance(assetIdStr) + tryGetInteger(("autostake_amount_" + assetIdStr))) + (if ((autostakeAmount != ""))
621621 then parseIntValue(autostakeAmount)
622622 else 0)) + fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), rates[((n * 3) + 1)].value, Scale16)) - fraction(tryGetInteger(("total_supplied_" + assetIdStr)), rates[(n * 3)].value, Scale16))
623623 let inv = if ((tryGetString(("setup_autostake_" + assetIdStr)) != ""))
624624 then invoke(this, "unstakeToken", [assetIdStr, amount], nil)
625625 else unit
626626 if ((inv == inv))
627627 then (accum ++ [amount])
628628 else throw("Strict value is not equal to itself.")
629629 }
630630
631631 let parameter = {
632632 let $l = li
633633 let $s = size($l)
634634 let $acc0 = nil
635635 func $f0_1 ($a,$i) = if (($i >= $s))
636636 then $a
637637 else f($a, $l[$i])
638638
639639 func $f0_2 ($a,$i) = if (($i >= $s))
640640 then $a
641641 else throw("List size exceeds 12")
642642
643643 $f0_2($f0_1($f0_1($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), 11), 12)
644644 }
645645 func f2 (accum,n) = if ((n >= size(assets)))
646646 then accum
647647 else {
648648 let assetIdStr = assets[n]
649649 (accum ++ [ScriptTransfer(reserveFundAddress, max([parameter[n], 0]), getAssetBytes(assetIdStr))])
650650 }
651651
652652 if (debug)
653653 then throw(liIntToStr(parameter))
654654 else $Tuple2({
655655 let $l = li
656656 let $s = size($l)
657657 let $acc0 = nil
658658 func $f1_1 ($a,$i) = if (($i >= $s))
659659 then $a
660660 else f2($a, $l[$i])
661661
662662 func $f1_2 ($a,$i) = if (($i >= $s))
663663 then $a
664664 else throw("List size exceeds 12")
665665
666666 $f1_2($f1_1($f1_1($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), 11), 12)
667667 }, parameter)
668668 }
669669
670670
671671
672672 @Callable(i)
673673 func reSetup (assetIdStr) = {
674674 let lastResetup = tryGetInteger("resetup_lastUpdate")
675675 if ((dayBlocks > (height - lastResetup)))
676676 then throw("can be updated only once per day")
677677 else {
678678 let lts = split(tryGetString("setup_lts"), ",")
679679 let assets = getMarketAssets()
680680 let ur = getUr(assetIdStr)
681681 let tempLT = tryGetInteger((("setup_" + assetIdStr) + "_tempLT"))
682682 let lt = parseIntValue(assets[value(indexOf(assets, assetIdStr))])
683683 if ((ur > 90000000))
684684 then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 9975, 10000))]
685685 else if (if ((lt > tempLT))
686686 then (90000000 > ur)
687687 else false)
688688 then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 10025, 10000))]
689689 else nil
690690 }
691691 }
692692
693693
694694
695695 @Callable(i)
696696 func shutdown (shutdown) = if ((indexOf(shutdownWhitelist, i.caller) == unit))
697697 then throw("user not in a whitelist")
698698 else [BooleanEntry("setup_active", !(shutdown))]
699699
700700
701701
702702 @Callable(i)
703703 func liquidate (debug,address,assetAmount,sAssetIdStr,bAssetIdStr,routeStr) = if (!(verifyLiquidatorRights(i.caller)))
704704 then throw("temporarily available for whitelist only")
705705 else if (!(tryGetBoolean("setup_active")))
706706 then throw("market is stopped")
707707 else {
708708 let userCollateral = calcUserCollateral(address)
709709 if ((userCollateral == userCollateral))
710710 then {
711711 let $t02424724309 = getActualRate(sAssetIdStr, "sRate")
712712 let sRate = $t02424724309._1
713713 let ratesResult = $t02424724309._2
714714 let $t02431424383 = getActualRate(bAssetIdStr, "bRate")
715715 let bRate = $t02431424383._1
716716 let ratesRecalcResult2 = $t02431424383._2
717717 let sAssetAmount = fraction(assetAmount, Scale16, sRate)
718718 let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
719719 let currentBPositionVal = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
720720 let currentBPosition = if ((currentBPositionVal > 0))
721721 then currentBPositionVal
722722 else throw("user has no borrow in this token")
723723 if ((userCollateral > 0))
724724 then throw("user can't be liquidated")
725725 else if ((sAssetAmount > currentSPosition))
726726 then throw("position to liquidate is bigger than user's supply")
727727 else {
728728 let balance0Before = getBalance(sAssetIdStr)
729729 if ((balance0Before == balance0Before))
730730 then {
731731 let balance1Before = getBalance(bAssetIdStr)
732732 if ((balance1Before == balance1Before))
733733 then {
734734 let inv = if ((tryGetString(("setup_autostake_" + sAssetIdStr)) != ""))
735735 then invoke(this, "unstakeToken", [sAssetIdStr, sAssetAmount], nil)
736736 else unit
737737 if ((inv == inv))
738738 then {
739739 let exchangeInvoke = invoke(aggregatorAddress, "swap", [routeStr, 0], [AttachedPayment(getAssetBytes(sAssetIdStr), assetAmount)])
740740 if ((exchangeInvoke == exchangeInvoke))
741741 then {
742742 let asset0Sold = (balance0Before - getBalance(sAssetIdStr))
743743 if ((asset0Sold == asset0Sold))
744744 then {
745745 let asset1Bought = (getBalance(bAssetIdStr) - balance1Before)
746746 if ((asset1Bought == asset1Bought))
747747 then {
748748 let asset0Price = getTokenPrice(sAssetIdStr)._1
749749 let asset0Scale = calcAssetScale(sAssetIdStr)
750750 let asset0Usd = fraction(asset0Sold, asset0Price, asset0Scale)
751751 let asset1Price = getTokenPrice(bAssetIdStr)._2
752752 let asset1Scale = calcAssetScale(bAssetIdStr)
753753 let asset1Usd = fraction(asset1Bought, asset1Price, asset1Scale)
754754 let penalty = parseIntValue(split(tryGetString("setup_penalties"), ",")[value(indexOf(getMarketAssets(), bAssetIdStr))])
755755 let liquidationProfit = (asset1Usd - fraction(asset0Usd, (Scale8 - penalty), Scale8))
756756 let sAssetChange = fraction(asset0Sold, Scale16, sRate)
757757 let bAssetChange = fraction(fraction(asset1Bought, Scale16, bRate), (Scale8 - fraction(liquidationProfit, Scale8, asset1Usd)), Scale8)
758758 if ((asset0Sold > assetAmount))
759759 then throw("more assets exchanged than expected")
760760 else if ((0 > liquidationProfit))
761761 then throw("price impact is bigger than liquidation penalty")
762762 else [IntegerEntry(((address + "_supplied_") + sAssetIdStr), (currentSPosition - sAssetChange)), IntegerEntry(((address + "_borrowed_") + bAssetIdStr), (currentBPosition - bAssetChange)), IntegerEntry(("total_supplied_" + sAssetIdStr), (tryGetInteger(("total_supplied_" + sAssetIdStr)) - sAssetChange)), IntegerEntry(("total_borrowed_" + bAssetIdStr), (tryGetInteger(("total_borrowed_" + bAssetIdStr)) - bAssetChange))]
763763 }
764764 else throw("Strict value is not equal to itself.")
765765 }
766766 else throw("Strict value is not equal to itself.")
767767 }
768768 else throw("Strict value is not equal to itself.")
769769 }
770770 else throw("Strict value is not equal to itself.")
771771 }
772772 else throw("Strict value is not equal to itself.")
773773 }
774774 else throw("Strict value is not equal to itself.")
775775 }
776776 }
777777 else throw("Strict value is not equal to itself.")
778778 }
779779
780780
781781
782782 @Callable(i)
783783 func liquidateV2 (debug,address,sAssetIdStr) = if (!(verifyLiquidatorRights(i.caller)))
784784 then throw("temporarily available for whitelist only")
785785 else if (!(tryGetBoolean("setup_active")))
786786 then throw("market is stopped")
787787 else {
788788 let bAssetId = i.payments[0].assetId
789789 let bAssetIdStr = getAssetString(bAssetId)
790790 let bAssetAmount = i.payments[0].amount
791791 let userCollateral = calcUserCollateral(address)
792792 if ((userCollateral == userCollateral))
793793 then if ((userCollateral > 0))
794794 then throw("user can't be liquidated")
795795 else {
796796 let marketAssets = getMarketAssets()
797797 let asset1Num = value(indexOf(marketAssets, bAssetIdStr))
798798 let asset0Num = value(indexOf(marketAssets, sAssetIdStr))
799799 let $t02771127773 = getActualRate(bAssetIdStr, "bRate")
800800 let bRate = $t02771127773._1
801801 let ratesResult = $t02771127773._2
802802 let asset1Price = getTokenPrice(bAssetIdStr)._2
803803 let asset1Scale = calcAssetScale(bAssetIdStr)
804804 let bAmountUsd = fraction(bAssetAmount, asset1Price, asset1Scale)
805805 let penalty = parseIntValue(value(split(tryGetString("setup_penalties"), ",")[asset1Num]))
806806 let asset0Price = getTokenPrice(sAssetIdStr)._1
807807 let asset0Scale = calcAssetScale(sAssetIdStr)
808808 let sAmountUsd = fraction(bAmountUsd, (Scale8 + penalty), Scale8)
809809 let sAssetAmount = fraction(sAmountUsd, asset0Scale, asset0Price)
810810 let bAmount = fraction(bAssetAmount, Scale16, bRate)
811811 let sAmount = fraction(sAssetAmount, Scale16, ratesResult[(asset0Num * 3)].value)
812812 let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
813813 let currentBPositionVal = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
814814 let currentBPosition = if ((currentBPositionVal > 0))
815815 then currentBPositionVal
816816 else throw("user has no borrow in this token")
817817 if ((sAmount > currentSPosition))
818818 then throw("position to liquidate is bigger than user's supply")
819819 else {
820820 let inv = if ((tryGetString(("setup_autostake_" + sAssetIdStr)) != ""))
821821 then invoke(this, "unstakeToken", [sAssetIdStr, sAssetAmount], nil)
822822 else unit
823823 if ((inv == inv))
824824 then if (debug)
825825 then throw("liquidation will pass")
826826 else ([ScriptTransfer(i.caller, sAssetAmount, getAssetBytes(sAssetIdStr)), IntegerEntry(((address + "_supplied_") + sAssetIdStr), (currentSPosition - sAmount)), IntegerEntry(((address + "_borrowed_") + bAssetIdStr), (currentBPosition - bAmount)), IntegerEntry(("total_supplied_" + sAssetIdStr), (tryGetInteger(("total_supplied_" + sAssetIdStr)) - sAmount)), IntegerEntry(("total_borrowed_" + bAssetIdStr), (tryGetInteger(("total_borrowed_" + bAssetIdStr)) - bAmount))] ++ ratesResult)
827827 else throw("Strict value is not equal to itself.")
828828 }
829829 }
830830 else throw("Strict value is not equal to itself.")
831831 }
832832
833833
834834
835835 @Callable(i)
836836 func getUserCollateral (debug,address,minusBorrowed,afterChange) = {
837837 let assets = getMarketAssets()
838838 let ltvs = split(tryGetString("setup_ltvs"), ",")
839839 let lts = split(tryGetString("setup_lts"), ",")
840840 let rates = getActualRate(assets[0], "sRate")._2
841841 let changeHandler = split(afterChange, ",")
842842 func f (accum,next) = if ((next >= size(assets)))
843843 then accum
844844 else {
845845 let userSupplied = tryGetInteger(((address + "_supplied_") + assets[next]))
846846 let userBorrowed = tryGetInteger(((address + "_borrowed_") + assets[next]))
847847 let needTokenAccounting = if ((afterChange == ""))
848848 then if (if ((userBorrowed != 0))
849849 then true
850850 else (userSupplied != 0))
851851 then true
852852 else false
853853 else true
854854 if (needTokenAccounting)
855855 then {
856856 let assetScale = calcAssetScale(assets[next])
857857 let assetPrice = getTokenPrice(assets[next])
858858 ((accum + fraction(fraction(fraction((userSupplied + (if (if (if ((afterChange != ""))
859859 then (changeHandler[0] == assets[next])
860860 else false)
861861 then (changeHandler[1] == "supplied")
862862 else false)
863863 then parseIntValue(changeHandler[2])
864864 else 0)), rates[(next * 3)].value, Scale16), parseIntValue(ltvs[next]), Scale8), assetPrice._1, assetScale)) - (if (minusBorrowed)
865865 then fraction(fraction(fraction((userBorrowed + (if (if (if ((afterChange != ""))
866866 then (changeHandler[0] == assets[next])
867867 else false)
868868 then (changeHandler[1] == "borrowed")
869869 else false)
870870 then parseIntValue(changeHandler[2])
871871 else 0)), rates[((next * 3) + 1)].value, Scale16), Scale8, parseIntValue(lts[next])), assetPrice._2, assetScale)
872872 else 0))
873873 }
874874 else accum
875875 }
876876
877877 let result = {
878878 let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
879879 let $s = size($l)
880880 let $acc0 = 0
881881 func $f0_1 ($a,$i) = if (($i >= $s))
882882 then $a
883883 else f($a, $l[$i])
884884
885885 func $f0_2 ($a,$i) = if (($i >= $s))
886886 then $a
887887 else throw("List size exceeds 12")
888888
889889 $f0_2($f0_1($f0_1($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), 11), 12)
890890 }
891891 if (debug)
892892 then throw(toString(result))
893893 else $Tuple2(rates, result)
894894 }
895895
896896
897897
898898 @Callable(i)
899899 func getPrices (debug) = {
900900 let assets = getMarketAssets()
901901 func f (accum,next) = if ((next >= size(assets)))
902902 then accum
903903 else {
904904 let assetPrice = getTokenPriceWithRisk(assets[next], 3)
905905 ((((accum + toString(assetPrice._1)) + ",") + toString(assetPrice._2)) + "|")
906906 }
907907
908908 let result = {
909909 let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
910910 let $s = size($l)
911911 let $acc0 = ""
912912 func $f0_1 ($a,$i) = if (($i >= $s))
913913 then $a
914914 else f($a, $l[$i])
915915
916916 func $f0_2 ($a,$i) = if (($i >= $s))
917917 then $a
918918 else throw("List size exceeds 12")
919919
920920 $f0_2($f0_1($f0_1($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), 11), 12)
921921 }
922922 if (debug)
923923 then throw(result)
924924 else $Tuple2(nil, result)
925925 }
926926
927927
928928
929929 @Callable(i)
930930 func calculateUtilizationRatio (assetIdStr,debug) = if (debug)
931931 then throw(toString(getUr(assetIdStr)))
932932 else $Tuple2(nil, getUr(assetIdStr))
933933
934934
935935
936936 @Callable(i)
937937 func calculateOutdatedUR (assetIdStr,debug) = if (debug)
938938 then throw(toString(getOutdatedUr(assetIdStr)))
939939 else $Tuple2(nil, getOutdatedUr(assetIdStr))
940940
941941
942942
943943 @Callable(i)
944944 func calculateTokenRates (debug) = {
945945 func f (accum,assetIdStr) = {
946946 let rates = tokenRatesRecalc(assetIdStr)
947947 $Tuple2(((((accum._1 + toString(rates[1].value)) + "|") + toString(rates[0].value)) + ","), (accum._2 ++ rates))
948948 }
949949
950950 let parameter = {
951951 let $l = getMarketAssets()
952952 let $s = size($l)
953953 let $acc0 = $Tuple2("", nil)
954954 func $f0_1 ($a,$i) = if (($i >= $s))
955955 then $a
956956 else f($a, $l[$i])
957957
958958 func $f0_2 ($a,$i) = if (($i >= $s))
959959 then $a
960960 else throw("List size exceeds 12")
961961
962962 $f0_2($f0_1($f0_1($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), 11), 12)
963963 }
964964 if (debug)
965965 then throw(parameter._1)
966966 else $Tuple2(parameter._2, parameter._1)
967967 }
968968
969969
970970
971971 @Callable(i)
972972 func calculateTokensInterest (debug) = {
973973 func f (accum,assetIdStr) = {
974974 let rate = fraction(getInterest(assetIdStr), dayBlocks, Scale8)
975975 ((accum + toString(rate)) + ",")
976976 }
977977
978978 let parameter = {
979979 let $l = getMarketAssets()
980980 let $s = size($l)
981981 let $acc0 = ""
982982 func $f0_1 ($a,$i) = if (($i >= $s))
983983 then $a
984984 else f($a, $l[$i])
985985
986986 func $f0_2 ($a,$i) = if (($i >= $s))
987987 then $a
988988 else throw("List size exceeds 12")
989989
990990 $f0_2($f0_1($f0_1($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), 11), 12)
991991 }
992992 if (debug)
993993 then throw(parameter)
994994 else $Tuple2(nil, parameter)
995995 }
996996
997997
998998
999999 @Callable(i)
10001000 func initNewMaster (master) = {
10011001 let addressOK = match addressFromString(master) {
10021002 case a: Address =>
10031003 true
10041004 case _ =>
10051005 false
10061006 }
10071007 if (!(addressOK))
10081008 then throw(("incorrect address " + master))
10091009 else if ((i.caller != this))
10101010 then throw("available for self call only")
10111011 else [StringEntry("verifier_master", master)]
10121012 }
10131013
10141014
10151015
10161016 @Callable(i)
10171017 func requestNewMaster (newMaster) = {
10181018 let addressOK = match addressFromString(newMaster) {
10191019 case a: Address =>
10201020 true
10211021 case _ =>
10221022 false
10231023 }
10241024 if (!(addressOK))
10251025 then throw(("incorrect address " + newMaster))
10261026 else if ((indexOf(sentinels, i.caller) == unit))
10271027 then throw("whitelist only")
10281028 else [StringEntry("verifier_newMaster", newMaster), IntegerEntry("verifier_newMasterEligibleAfter", (height + 10000))]
10291029 }
10301030
10311031
10321032
10331033 @Callable(i)
10341034 func activateNewMaster () = {
10351035 let eligibleHeight = getIntegerValue(this, "verifier_newMasterEligibleAfter")
10361036 let newMaster = getStringValue(this, "verifier_newMaster")
10371037 if ((indexOf(sentinels, i.caller) == unit))
10381038 then throw("whitelist only")
10391039 else if ((eligibleHeight > height))
10401040 then throw("new master cannot be activated yet")
10411041 else [DeleteEntry("verifier_newMaster"), DeleteEntry("verifier_newMasterEligibleAfter"), StringEntry("verifier_master", newMaster)]
10421042 }
10431043
10441044
10451045 @Verifier(tx)
10461046 func verify () = {
10471047 let masterAddress = getString("verifier_master")
10481048 let approvedByMaster = match masterAddress {
10491049 case x: String =>
10501050 match getInteger(addressFromStringValue(x), ("approvedTx_" + toBase58String(tx.id))) {
10511051 case y: Int =>
10521052 y
10531053 case _ =>
10541054 0
10551055 }
10561056 case _ =>
10571057 1
10581058 }
10591059 if (sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey))
10601060 then (approvedByMaster > 0)
10611061 else false
10621062 }
10631063

github/deemru/w8io/6500d08 
104.40 ms