tx · 8enY1DccBCEnJqyPrSPE419gACgopHfUPmjahFojd7xx

3PFKZDRSFv5QPbe4b6Q22fLZniqAc8u9MLp:  -0.02500000 Waves

2023.04.13 18:16 [3598581] smart account 3PFKZDRSFv5QPbe4b6Q22fLZniqAc8u9MLp > SELF 0.00000000 Waves

{ "type": 13, "id": "8enY1DccBCEnJqyPrSPE419gACgopHfUPmjahFojd7xx", "fee": 2500000, "feeAssetId": null, "timestamp": 1681399029512, "version": 2, "chainId": 87, "sender": "3PFKZDRSFv5QPbe4b6Q22fLZniqAc8u9MLp", "senderPublicKey": "BU38Szr6CXwv8YFSUKV7XbdQyMU7qb2wGvpeHAE2i5HX", "proofs": [ "4BqNDtM3TkSYF6B2YZQEHP7NybssDT7PBVVfhe4MRWpsxE1Ni54yL6G55JEzby2XyhimZHRSifKisa45w24NPH4v" ], "script": "base64:BgI1CAISABIAEgMKAQESABIAEgASABIAEgASABIAEggKBgEBAQEBAhIAEgoKCAEBAQEBAQECEgA8AANTRVACAl9fAAltaW5BbW91bnQAoI0GAAVNVUxUNgDAhD0ABU1VTFQ4AIDC1y8ADHdhdmVzQXNzZXRJZAkA2QQBAgVXQVZFUwAJd3hBc3NldElkASCTARyrqcduJVfOZp5xtr2qa/g86FgLKu7ZoE67PNwUsQALc3VyZkFzc2V0SWQBIJLR9EriEQEr9H7q3iGOPcX7yfJ9zoey7VIZ8DpOJFj1AAp4dG5Bc3NldElkASC2JinDBPXOU5GkDkt1JC9kjFGx+t+vVCm9SNIdKrKq0QALZGV4Q29udHJhY3QBGgFXymv8n9fLujU9O2aaHo6wilKnNKKaQ5SCABduZXV0cmlub0NvbnRyYWN0QWRkcmVzcwEaAVdwBGKmR5vprVZolMvvhYwwgiAomggUlrIAFm5ldXRyaW5vU3Rha2luZ0FkZHJlc3MBGgFXa2g44QPUmoyfEhvGLLwjBzkLze0S1wpfABluZXV0cmlub1ByaWNlSW5kZXhBZGRyZXNzARoBVyOzrRJck6TK7Dn+T0bWzVZNLfsQ+2OYegAUY2FzZVh0blN3YXBTdGF0ZUlkbGUAAAAcY2FzZVh0blN3YXBTdGF0ZVh0blRvUmV3YXJkcwABACRjYXNlWHRuU3dhcFN0YXRlRXhjaGFuZ2VSZXdhcmRzT25EZXgAAgAOY29uc3RydWN0ZWRLZXkCC2NvbnN0cnVjdGVkABN4dG5Td2FwU3RhdGVFbnVtS2V5AhB4dG5Td2FwU3RhdGVFbnVtABJ0b3RhbFN1cmZTdGFrZWRLZXkCD3RvdGFsU3VyZlN0YWtlZAAlcGVuZGluZ1RvdGFsU3VyZkFtb3VudFRvV2l0aGRyYXdhbEtleQIicGVuZGluZ1RvdGFsU3VmdEFtb3VudFRvV2l0aGRyYXdhbAASZGV2c1dhdmVzQW1vdW50S2V5Ag9kZXZzV2F2ZXNBbW91bnQAEWRldnNTdXJmQW1vdW50S2V5Ag5kZXZzU3VyZkFtb3VudAAPZGV2c1d4QW1vdW50S2V5AgxkZXZzV3hBbW91bnQAEGRldnNYdG5BbW91bnRLZXkCEGRldnNYdG5BbW91bnRLZXkAEXh0blN3YXBCbG9ja0lkS2V5Ag54dG5Td2FwQmxvY2tJZAAXeHRuU3dhcFRyYW5zYWN0aW9uSWRLZXkCFHh0blN3YXBUcmFuc2FjdGlvbklkABR4dG5Td2FwUHJpY2VJbmRleEtleQIReHRuU3dhcFByaWNlSW5kZXgAGnh0blN3YXBYdG5Td2FwcGVkQW1vdW50S2V5Ahd4dG5Td2FwWHRuU3dhcHBlZEFtb3VudAAceHRuU3dhcFdhdmVzQmFsYW5jZUF0U3dhcEtleQIZeHRuU3dhcFdhdmVzQmFsYW5jZUF0U3dhcAAZeHRuU3dhcFd4QmFsYW5jZUF0U3dhcEtleQIWeHRuU3dhcFd4QmFsYW5jZUF0U3dhcAAeeHRuU3dhcFh0bkJhbGFuY2VBdEV4Y2hhbmdlS2V5Aht4dG5Td2FwWHRuQmFsYW5jZUF0RXhjaGFuZ2UAGXh0blN3YXBFeGNoYW5nZUJsb2NrSWRLZXkCFnh0blN3YXBFeGNoYW5nZUJsb2NrSWQAGmxhc3RTdWNjZXNzU3dhcEJsb2NrSGVpZ2h0AhpsYXN0U3VjY2Vzc1N3YXBCbG9ja0hlaWdodAAcY3VycmVudFdpdGhkcmF3YWxQZXJpb2RJZEtleQIZY3VycmVudFdpdGhkcmF3YWxQZXJpb2RJZAAZY3VycmVudFhUTlN3YXBQZXJpb2RJZEtleQIWY3VycmVudFhUTlN3YXBQZXJpb2RJZAAkY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkS2V5AiRjdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kSWRLZXkBKmtleUN1cnJlbnRYdG5Td2FwUGVyaW9kWHRuQW1vdW50Rm9yT25lU3VyZgEIcGVyaW9kSWQJAKwCAgkArAICAhRjdXJyZW50WFROU3dhcFBlcmlvZAUDU0VQCQCkAwEFCHBlcmlvZElkATZrZXlDdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RXYXZlc0Ftb3VudEZvck9uZVN1cmYBCHBlcmlvZElkCQCsAgIJAKwCAgIpY3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kV2F2ZXNBbW91bnQFA1NFUAkApAMBBQhwZXJpb2RJZAEza2V5Q3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kV3hBbW91bnRGb3JPbmVTdXJmAQhwZXJpb2RJZAkArAICCQCsAgICJmN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZFd3QW1vdW50BQNTRVAJAKQDAQUIcGVyaW9kSWQBNGtleUN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZFh0bkFtb3VudEZvck9uZVN1cmYBCHBlcmlvZElkCQCsAgIJAKwCAgInY3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kWHRuQW1vdW50BQNTRVAJAKQDAQUIcGVyaW9kSWQBHWtleUN1cnJlbnRVc2VyVG90YWxTdXJmU3Rha2VkAQdhZGRyZXNzCQCsAgIJAKwCAgIaY3VycmVudFVzZXJUb3RhbFN1cmZTdGFrZWQFA1NFUAUHYWRkcmVzcwEsa2V5Q3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQBB2FkZHJlc3MJAKwCAgkArAICAiljdXJyZW50VXNlclVuY2xhaW1lZFh0blN3YXBSZXdhcmRQZXJpb2RJZAUDU0VQBQdhZGRyZXNzATBrZXlDdXJyZW50VXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kSWQBB2FkZHJlc3MJAKwCAgkArAICAi1jdXJyZW50VXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kSWQFA1NFUAUHYWRkcmVzcwEna2V5Q3VycmVudFVzZXJQZW5kaW5nV2l0aGRyYXdhbFBlcmlvZElkAQdhZGRyZXNzCQCsAgIJAKwCAgIkY3VycmVudFVzZXJQZW5kaW5nV2l0aGRyYXdhbFBlcmlvZElkBQNTRVAFB2FkZHJlc3MBK2tleUN1cnJlbnRVc2VyVG90YWxTdXJmUGVuZGluZ0ZvcldpdGhkcmF3YWwBB2FkZHJlc3MJAKwCAgkArAICAihjdXJyZW50VXNlclRvdGFsU3VyZlBlbmRpbmdGb3JXaXRoZHJhd2FsBQNTRVAFB2FkZHJlc3MBCWFzUGF5bWVudAEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAg9BdHRhY2hlZFBheW1lbnQEAXAFByRtYXRjaDAFAXAJAAIBAiFmYWlsIHRvIGNhc3QgaW50byBBdHRhY2hlZFBheW1lbnQBBWFzSW50AQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAgNJbnQEBnZhbEludAUHJG1hdGNoMAUGdmFsSW50CQACAQIVZmFpbCB0byBjYXN0IGludG8gSW50AQxhc0ludE9yVGhyb3cCA3ZhbAdtZXNzYWdlBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAkAAgEFB21lc3NhZ2UBCmFzSW50T3JEZWYCA3ZhbAdkZWZhdWx0BAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAUHZGVmYXVsdAEIYXNTdHJpbmcBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACBlN0cmluZwQJdmFsU3RyaW5nBQckbWF0Y2gwBQl2YWxTdHJpbmcJAAIBAhhmYWlsIHRvIGNhc3QgaW50byBTdHJpbmcBDWFzU3RyaW5nT3JEZWYCA3ZhbAdkZWZhdWx0BAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAl2YWxTdHJpbmcFByRtYXRjaDAFCXZhbFN0cmluZwUHZGVmYXVsdAEJYXNCb29sZWFuAQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAgdCb29sZWFuBAd2YWxCb29sBQckbWF0Y2gwBQd2YWxCb29sCQACAQIZZmFpbCB0byBjYXN0IGludG8gQm9vbGVhbgEOYXNCb29sZWFuT3JEZWYCA3ZhbAdkZWZhdWx0BAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIHQm9vbGVhbgQHdmFsQm9vbAUHJG1hdGNoMAUHdmFsQm9vbAUHZGVmYXVsdAERY3VycmVudFByb3BvcnRpb24BD3h0blN3YXBMaW1pdE1heAQPdG90YWxTdXJmU3Rha2VkCQERQGV4dHJOYXRpdmUoMTA1NSkBBRJ0b3RhbFN1cmZTdGFrZWRLZXkJAL0CBAkAtgIBBQ90b3RhbFN1cmZTdGFrZWQJALYCAQUFTVVMVDYJALYCAQUPeHRuU3dhcExpbWl0TWF4BQZIQUxGVVABD2NoZWNrUHJvcG9ydGlvbgMPeHRuU3dhcExpbWl0TWF4CnN1cmZBbW91bnQJeG50QW1vdW50BApwcm9wb3J0aW9uCQERY3VycmVudFByb3BvcnRpb24BBQ94dG5Td2FwTGltaXRNYXgEEmV4cGVjdGVkU3VyZkFtb3VudAkAoAMBCQC9AgQFCnByb3BvcnRpb24JALYCAQUJeG50QW1vdW50CQC2AgEFBU1VTFQ2BQZIQUxGVVADCQAAAgUSZXhwZWN0ZWRTdXJmQW1vdW50BQpzdXJmQW1vdW50BgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIFV2l0aCAJAKQDAQUPeHRuU3dhcExpbWl0TWF4Ah8gWE5UIGFtb3VudCB5b3Ugc2hvdWxkIHByb3ZpZGUgCQCkAwEFEmV4cGVjdGVkU3VyZkFtb3VudAIVIFNVUkYgYW1vdW50IHRvIHN0YWtlAAVFTVBUWQIBXgEZa2V5T3BlcmF0aW9uSGlzdG9yeVJlY29yZAMEdHlwZQt1c2VyQWRkcmVzcwZ0eElkNTgJALkJAgkAzAgCAhElcyVzJXMlc19faGlzdG9yeQkAzAgCBQR0eXBlCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIFBnR4SWQ1OAUDbmlsBQNTRVABE2Zvcm1hdEhpc3RvcnlSZWNvcmQEC3VzZXJBZGRyZXNzCWxwQXNzZXRJZAR0eXBlBmFtb3VudAkAuQkCCQDMCAICDCVzJXMlcyVkJWQlZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCBQlscEFzc2V0SWQJAMwIAgUEdHlwZQkAzAgCCQCkAwEFBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAKQDAQUGYW1vdW50BQNuaWwFA1NFUAEVT3BlcmF0aW9uSGlzdG9yeUVudHJ5BQR0eXBlC3VzZXJBZGRyZXNzCWxwQXNzZXRJZAZhbW91bnQEdHhJZAkBC1N0cmluZ0VudHJ5AgkBGWtleU9wZXJhdGlvbkhpc3RvcnlSZWNvcmQDBQR0eXBlBQt1c2VyQWRkcmVzcwkA2AQBBQR0eElkCQETZm9ybWF0SGlzdG9yeVJlY29yZAQFC3VzZXJBZGRyZXNzBQlscEFzc2V0SWQFBHR5cGUFBmFtb3VudAEcaW50ZXJhY3RXaXRoU3dhcFBhcmFtc0J5VXNlcgAEBnJlc3VsdAkA/AcECQEHQWRkcmVzcwEFFm5ldXRyaW5vU3Rha2luZ0FkZHJlc3MCG3N3YXBQYXJhbXNCeVVzZXJTWVNSRUFET05MWQkAzAgCBQR0aGlzCQDMCAIAAAUDbmlsBQNuaWwDCQAAAgUGcmVzdWx0BQZyZXN1bHQEByRtYXRjaDAFBnJlc3VsdAMJAAECBQckbWF0Y2gwAiMoSW50LCBJbnQsIEludCwgSW50LCBJbnQsIEludCwgSW50KQQFdHVwbGUFByRtYXRjaDAJAMwIAggFBXR1cGxlAl8xCQDMCAIIBQV0dXBsZQJfMgkAzAgCCAUFdHVwbGUCXzMJAMwIAggFBXR1cGxlAl80CQDMCAIIBQV0dXBsZQJfNQkAzAgCCAUFdHVwbGUCXzYJAMwIAggFBXR1cGxlAl83BQNuaWwJAAIBAi5GQVRBTDogQ2FuJ3QgZmV0Y2ggZGF0YSBmcm9tIG5ldXRyaW5vIGNvbnRyYWN0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuASppc1VzZXJIYXNVbmNsYWltZWRSZXdhcmRzSW5QcmV2aW91c1BlcmlvZHMBB2FkZHJlc3MEInVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQJAQphc0ludE9yRGVmAgkAnwgBCQEsa2V5Q3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQBBQdhZGRyZXNzAP///////////wEEJ3VzZXJVbmNsYWltZWRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAkBCmFzSW50T3JEZWYCCQCfCAEJATBrZXlDdXJyZW50VXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kSWQBBQdhZGRyZXNzAP///////////wEEFGN1cnJlbnRYVE5Td2FwUGVyaW9kCQEKYXNJbnRPckRlZgIJAJ8IAQUZY3VycmVudFhUTlN3YXBQZXJpb2RJZEtleQAABB9jdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kCQEKYXNJbnRPckRlZgIJAJ8IAQUkY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkS2V5AAADAwkAZgIFInVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQA////////////AQkAZgIFFGN1cnJlbnRYVE5Td2FwUGVyaW9kBSJ1c2VyVW5jbGFpbWVkWHRuU3dhcFJld2FyZFBlcmlvZElkBwYDAwkAZgIFJ3VzZXJVbmNsYWltZWRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAD///////////8BCQBmAgUfY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZAUndXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkBwYHDwFpAQtjb25zdHJ1Y3RvcgAEByRtYXRjaDAJAKAIAQUOY29uc3RydWN0ZWRLZXkDCQABAgUHJG1hdGNoMAIHQm9vbGVhbgkAAgECI0NvbnN0cnVjdG9yIGNhbiBiZSBjYWxsZWQganVzdCBvbmNlCQDMCAIJAQxCb29sZWFuRW50cnkCBQ5jb25zdHJ1Y3RlZEtleQYJAMwIAgkBDEludGVnZXJFbnRyeQIFHGN1cnJlbnRXaXRoZHJhd2FsUGVyaW9kSWRLZXkAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUZY3VycmVudFhUTlN3YXBQZXJpb2RJZEtleQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBSVwZW5kaW5nVG90YWxTdXJmQW1vdW50VG9XaXRoZHJhd2FsS2V5AAAJAMwIAgkBDEludGVnZXJFbnRyeQIFEmRldnNXYXZlc0Ftb3VudEtleQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFkZXZzU3VyZkFtb3VudEtleQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9kZXZzV3hBbW91bnRLZXkAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUQZGV2c1h0bkFtb3VudEtleQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBRpsYXN0U3VjY2Vzc1N3YXBCbG9ja0hlaWdodAAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBRN4dG5Td2FwU3RhdGVFbnVtS2V5BRRjYXNlWHRuU3dhcFN0YXRlSWRsZQUDbmlsAWkBBXN0YWtlAAMJAQIhPQIJARFAZXh0ck5hdGl2ZSgxMDU1KQEFE3h0blN3YXBTdGF0ZUVudW1LZXkFFGNhc2VYdG5Td2FwU3RhdGVJZGxlCQACAQIzWFROIHN3YXAgaW4gcHJvZ3Jlc3MsIHdhaXQgYXBwcm94aW1hdGVsbHkgMyBtaW51dGVzAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIzWW91IG11c3QgaW5jbHVkZSBleGFjdGx5IG9uZSBwYXltZW50IGluIHRyYW5zYWN0aW9uBAdwYXltZW50CQEJYXNQYXltZW50AQkAkQMCCAUBaQhwYXltZW50cwAAAwMJAQIhPQIIBQdwYXltZW50B2Fzc2V0SWQFC3N1cmZBc3NldElkBgkAZgIFCW1pbkFtb3VudAgFB3BheW1lbnQGYW1vdW50CQACAQIXV3JvbmcgYXNzZXRJZCBvciBhbW91bnQEE2NhbGxlckFkZHJlc3NTdHJpbmcJANgEAQgIBQFpBmNhbGxlcgVieXRlcwMJASppc1VzZXJIYXNVbmNsYWltZWRSZXdhcmRzSW5QcmV2aW91c1BlcmlvZHMBBRNjYWxsZXJBZGRyZXNzU3RyaW5nCQACAQI+WW91IGhhdmUgdW5jbGFpbWVkIHJld2FyZHMsIGNsYWltIHRoZW0gZmlyc3QsIHRoZW4gc3Rha2UgYWdhaW4EBnJlc3VsdAkA/AcECQEHQWRkcmVzcwEFFm5ldXRyaW5vU3Rha2luZ0FkZHJlc3MCBXN0YWtlBQNuaWwJAMwIAgUHcGF5bWVudAUDbmlsAwkAAAIFBnJlc3VsdAUGcmVzdWx0BBJuZXdUb3RhbFN1cmZTdGFrZWQEByRtYXRjaDAJAJ8IAQUSdG90YWxTdXJmU3Rha2VkS2V5AwkAAQIFByRtYXRjaDACA0ludAQBdgUHJG1hdGNoMAkAZAIFAXYIBQdwYXltZW50BmFtb3VudAgFB3BheW1lbnQGYW1vdW50BBhjYWxsZXJUb3RhbFN1cmZTdGFrZWRLZXkJAR1rZXlDdXJyZW50VXNlclRvdGFsU3VyZlN0YWtlZAEFE2NhbGxlckFkZHJlc3NTdHJpbmcEGG5ld0NhbGxlclRvdGFsU3VyZlN0YWtlZAQHJG1hdGNoMAkAnwgBBRhjYWxsZXJUb3RhbFN1cmZTdGFrZWRLZXkDCQABAgUHJG1hdGNoMAIDSW50BAF2BQckbWF0Y2gwCQBkAgUBdggFB3BheW1lbnQGYW1vdW50CAUHcGF5bWVudAZhbW91bnQEFGN1cnJlbnRYVE5Td2FwUGVyaW9kCQEKYXNJbnRPckRlZgIJAJ8IAQUZY3VycmVudFhUTlN3YXBQZXJpb2RJZEtleQAABB9jdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kCQEKYXNJbnRPckRlZgIJAJ8IAQUkY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkS2V5AAAJAMwIAgkBDEludGVnZXJFbnRyeQIFEnRvdGFsU3VyZlN0YWtlZEtleQUSbmV3VG90YWxTdXJmU3Rha2VkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRhjYWxsZXJUb3RhbFN1cmZTdGFrZWRLZXkFGG5ld0NhbGxlclRvdGFsU3VyZlN0YWtlZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBLGtleUN1cnJlbnRVc2VyVW5jbGFpbWVkWHRuU3dhcFJld2FyZFBlcmlvZElkAQUTY2FsbGVyQWRkcmVzc1N0cmluZwUUY3VycmVudFhUTlN3YXBQZXJpb2QJAMwIAgkBDEludGVnZXJFbnRyeQIJATBrZXlDdXJyZW50VXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kSWQBBRNjYWxsZXJBZGRyZXNzU3RyaW5nBR9jdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEXYXBwbHlGb3JQZW5kaW5nV2l0aGRyYXcBBmFtb3VudAMJAQIhPQIJARFAZXh0ck5hdGl2ZSgxMDU1KQEFE3h0blN3YXBTdGF0ZUVudW1LZXkFFGNhc2VYdG5Td2FwU3RhdGVJZGxlCQACAQIzWFROIHN3YXAgaW4gcHJvZ3Jlc3MsIHdhaXQgYXBwcm94aW1hdGVsbHkgMyBtaW51dGVzAwkAZgIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECJlRoaXMgZnVuY3Rpb24gZG9lcyBub3QgYWNjZXB0IHBheW1lbnRzAwkAZwIAAAUGYW1vdW50CQACAQIXQW1vdW50IG11c3QgYmUgcG9zaXRpdmUEE2NhbGxlckFkZHJlc3NTdHJpbmcJANgEAQgIBQFpBmNhbGxlcgVieXRlcwQVY2FsbGVyVG90YWxTdXJmU3Rha2VkCQERQGV4dHJOYXRpdmUoMTA1NSkBCQEda2V5Q3VycmVudFVzZXJUb3RhbFN1cmZTdGFrZWQBBRNjYWxsZXJBZGRyZXNzU3RyaW5nAwkAZgIFBmFtb3VudAUVY2FsbGVyVG90YWxTdXJmU3Rha2VkCQACAQIgSW5zdWZmaWNpZW50IGJhbGFuY2UgdG8gd2l0aGRyYXcDCQEqaXNVc2VySGFzVW5jbGFpbWVkUmV3YXJkc0luUHJldmlvdXNQZXJpb2RzAQUTY2FsbGVyQWRkcmVzc1N0cmluZwkAAgECPFlvdSBoYXZlIHVuY2xhaW1lZCByZXdhcmRzLCBjbGFpbSB0aGVtIGZpcnN0LCB0aGVuIHRyeSBhZ2FpbgQTY3VycmVudFdpdGhkcmF3YWxJZAkBEUBleHRyTmF0aXZlKDEwNTUpAQUcY3VycmVudFdpdGhkcmF3YWxQZXJpb2RJZEtleQQlcGVuZGluZ1RvdGFsU3VyZlRvVW5zdGFrZUZyb21OZXV0cmlubwkBEUBleHRyTmF0aXZlKDEwNTUpAQUlcGVuZGluZ1RvdGFsU3VyZkFtb3VudFRvV2l0aGRyYXdhbEtleQQddXNlclBlbmRpbmdXaXRoZHJhd2FsUGVyaW9kSWQJAQphc0ludE9yRGVmAgkAnwgBCQEna2V5Q3VycmVudFVzZXJQZW5kaW5nV2l0aGRyYXdhbFBlcmlvZElkAQUTY2FsbGVyQWRkcmVzc1N0cmluZwD///////////8BBCF1c2VyVG90YWxTdXJmUGVuZGluZ0ZvcldpdGhkcmF3YWwJAQphc0ludE9yRGVmAgkAnwgBCQEra2V5Q3VycmVudFVzZXJUb3RhbFN1cmZQZW5kaW5nRm9yV2l0aGRyYXdhbAEFE2NhbGxlckFkZHJlc3NTdHJpbmcAAAMDCQBmAgUddXNlclBlbmRpbmdXaXRoZHJhd2FsUGVyaW9kSWQA////////////AQkAZgIFE2N1cnJlbnRXaXRoZHJhd2FsSWQFHXVzZXJQZW5kaW5nV2l0aGRyYXdhbFBlcmlvZElkBwkAAgECP1lvdSBoYXZlIHVuY2xhaW1lZCBzdWZ0IG9uIGNvbnRyYWN0LCBwbGVhc2UgcGVyZm9ybSBjbGFpbSBmaXJzdAQcdXNlck5ld1RvdGFsU3VyZlN0YWtlZEFtb3VudAkAZQIFFWNhbGxlclRvdGFsU3VyZlN0YWtlZAUGYW1vdW50BCR1c2VyTmV3VG90YWxTdXJmUGVuZGluZ0ZvcldpdGhkcmF3YWwJAGQCBSF1c2VyVG90YWxTdXJmUGVuZGluZ0ZvcldpdGhkcmF3YWwFBmFtb3VudAQobmV3UGVuZGluZ1RvdGFsU3VyZlRvVW5zdGFrZUZyb21OZXV0cmlubwkAZAIFJXBlbmRpbmdUb3RhbFN1cmZUb1Vuc3Rha2VGcm9tTmV1dHJpbm8FBmFtb3VudAQYbmV3VG90YWxTdXJmU3Rha2VkQW1vdW50CQBlAgkBEUBleHRyTmF0aXZlKDEwNTUpAQUSdG90YWxTdXJmU3Rha2VkS2V5BQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAR1rZXlDdXJyZW50VXNlclRvdGFsU3VyZlN0YWtlZAEFE2NhbGxlckFkZHJlc3NTdHJpbmcFHHVzZXJOZXdUb3RhbFN1cmZTdGFrZWRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJASdrZXlDdXJyZW50VXNlclBlbmRpbmdXaXRoZHJhd2FsUGVyaW9kSWQBBRNjYWxsZXJBZGRyZXNzU3RyaW5nBRNjdXJyZW50V2l0aGRyYXdhbElkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEra2V5Q3VycmVudFVzZXJUb3RhbFN1cmZQZW5kaW5nRm9yV2l0aGRyYXdhbAEFE2NhbGxlckFkZHJlc3NTdHJpbmcFJHVzZXJOZXdUb3RhbFN1cmZQZW5kaW5nRm9yV2l0aGRyYXdhbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUlcGVuZGluZ1RvdGFsU3VyZkFtb3VudFRvV2l0aGRyYXdhbEtleQUobmV3UGVuZGluZ1RvdGFsU3VyZlRvVW5zdGFrZUZyb21OZXV0cmlubwkAzAgCCQEMSW50ZWdlckVudHJ5AgUSdG90YWxTdXJmU3Rha2VkS2V5BRhuZXdUb3RhbFN1cmZTdGFrZWRBbW91bnQFA25pbAFpARpwZXJmb3JtRGlzdHJpYnV0ZWRXaXRoZHJhdwADCQBmAgkAkAMBCAUBaQhwYXltZW50cwAACQACAQImVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBhY2NlcHQgcGF5bWVudHMEE2N1cnJlbnRXaXRoZHJhd2FsSWQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFHGN1cnJlbnRXaXRoZHJhd2FsUGVyaW9kSWRLZXkEJXBlbmRpbmdUb3RhbFN1cmZUb1Vuc3Rha2VGcm9tTmV1dHJpbm8JARFAZXh0ck5hdGl2ZSgxMDU1KQEFJXBlbmRpbmdUb3RhbFN1cmZBbW91bnRUb1dpdGhkcmF3YWxLZXkDCQBnAgAABSVwZW5kaW5nVG90YWxTdXJmVG9VbnN0YWtlRnJvbU5ldXRyaW5vBQNuaWwEBnJlc3VsdAkA/AcECQEHQWRkcmVzcwEFFm5ldXRyaW5vU3Rha2luZ0FkZHJlc3MCB3Vuc3Rha2UJAMwIAgUlcGVuZGluZ1RvdGFsU3VyZlRvVW5zdGFrZUZyb21OZXV0cmlubwUDbmlsBQNuaWwDCQAAAgUGcmVzdWx0BQZyZXN1bHQJAMwIAgkBDEludGVnZXJFbnRyeQIFHGN1cnJlbnRXaXRoZHJhd2FsUGVyaW9kSWRLZXkJAGQCBRNjdXJyZW50V2l0aGRyYXdhbElkAAEJAMwIAgkBDEludGVnZXJFbnRyeQIFJXBlbmRpbmdUb3RhbFN1cmZBbW91bnRUb1dpdGhkcmF3YWxLZXkAAAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCWNsYWltU3VyZgADCQBmAgkAkAMBCAUBaQhwYXltZW50cwAACQACAQImVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBhY2NlcHQgcGF5bWVudHMEE2NhbGxlckFkZHJlc3NTdHJpbmcJANgEAQgIBQFpBmNhbGxlcgVieXRlcwQZY3VycmVudFdpdGhkcmF3YWxQZXJpb2RJZAkBEUBleHRyTmF0aXZlKDEwNTUpAQUcY3VycmVudFdpdGhkcmF3YWxQZXJpb2RJZEtleQQWdXNlcldpdGhkcmF3YWxQZXJpb2RJZAkBCmFzSW50T3JEZWYCCQCfCAEJASdrZXlDdXJyZW50VXNlclBlbmRpbmdXaXRoZHJhd2FsUGVyaW9kSWQBBRNjYWxsZXJBZGRyZXNzU3RyaW5nAP///////////wEEIXVzZXJUb3RhbFN1cmZQZW5kaW5nRm9yV2l0aGRyYXdhbAkBCmFzSW50T3JEZWYCCQCfCAEJAStrZXlDdXJyZW50VXNlclRvdGFsU3VyZlBlbmRpbmdGb3JXaXRoZHJhd2FsAQUTY2FsbGVyQWRkcmVzc1N0cmluZwAAAwMJAAACBRZ1c2VyV2l0aGRyYXdhbFBlcmlvZElkAP///////////wEGCQAAAgUhdXNlclRvdGFsU3VyZlBlbmRpbmdGb3JXaXRoZHJhd2FsAAAJAAIBAhNOb3RoaW5nIHRvIHdpdGhkcmF3AwkAAAIFFnVzZXJXaXRoZHJhd2FsUGVyaW9kSWQFGWN1cnJlbnRXaXRoZHJhd2FsUGVyaW9kSWQJAAIBAiRZb3UgbXVzdCB3YWl0IGZvciBwZXJpb2QgdG8gY29tcGxldGUJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBSF1c2VyVG90YWxTdXJmUGVuZGluZ0ZvcldpdGhkcmF3YWwFC3N1cmZBc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEJASdrZXlDdXJyZW50VXNlclBlbmRpbmdXaXRoZHJhd2FsUGVyaW9kSWQBBRNjYWxsZXJBZGRyZXNzU3RyaW5nCQDMCAIJAQtEZWxldGVFbnRyeQEJAStrZXlDdXJyZW50VXNlclRvdGFsU3VyZlBlbmRpbmdGb3JXaXRoZHJhd2FsAQUTY2FsbGVyQWRkcmVzc1N0cmluZwUDbmlsAWkBH3h0blN3YXBQYXJ0MXN3YXBYVE5Gcm9tTmV1dHJpbm8AAwkBAiE9AgkBEUBleHRyTmF0aXZlKDEwNTUpAQUTeHRuU3dhcFN0YXRlRW51bUtleQUUY2FzZVh0blN3YXBTdGF0ZUlkbGUJAAIBAhlXcm9uZyBzdGF0ZSwgbXVzdCBiZSBJZGxlBA53aXRoZHJhd1Jlc3VsdAkA/AcEBQR0aGlzAhpwZXJmb3JtRGlzdHJpYnV0ZWRXaXRoZHJhdwUDbmlsBQNuaWwDCQAAAgUOd2l0aGRyYXdSZXN1bHQFDndpdGhkcmF3UmVzdWx0BAZyZXN1bHQJAPwHBAkBB0FkZHJlc3MBBRduZXV0cmlub0NvbnRyYWN0QWRkcmVzcwIbc3dhcFBhcmFtc0J5VXNlclNZU1JFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwkAzAgCAAAFA25pbAUDbmlsAwkAAAIFBnJlc3VsdAUGcmVzdWx0BAckbWF0Y2gwBQZyZXN1bHQDCQABAgUHJG1hdGNoMAIjKEludCwgSW50LCBJbnQsIEludCwgSW50LCBJbnQsIEludCkEBXR1cGxlBQckbWF0Y2gwAwkAZgIIBQV0dXBsZQJfMwAACQACAQkArAICCQCsAgICJ1RpbWUgaXMgbm90IGNvbWUgeWV0LCB5b3UgbmVlZCB0byB3YWl0IAkApAMBCAUFdHVwbGUCXzMCByBibG9ja3MEDW1heFN3YXBBbW91bnQIBQV0dXBsZQJfNwMJAGYCAMCEPQUNbWF4U3dhcEFtb3VudAkAAgECLE1pbiBYVE4gYW1vdW50IHRvIHN3YXAgaXMgMSwgc3Rha2UgbW9yZSBTVVJGAwkAZgIFDW1heFN3YXBBbW91bnQJAPAHAgUEdGhpcwUKeHRuQXNzZXRJZAkAAgECVlhUTiBCYWxhbmNlIG9uIGNvbnRyYWN0IGlzIHNtYWxsZXIgdGhhbiBtYXggc3dhcCBhbW91bnQsIGluY3JlYXNlIFhUTiBjb250cmFjdCBiYWxhbmNlBBNjdXJyZW50V2F2ZXNCYWxhbmNlCQDvBwEFBHRoaXMEEGN1cnJlbnRXWEJhbGFuY2UJAPAHAgUEdGhpcwUJd3hBc3NldElkBBRzd2FwTmV1dHJpbm9Ub0Fzc2V0cwkA/AcECQEHQWRkcmVzcwEFF25ldXRyaW5vQ29udHJhY3RBZGRyZXNzAhRzd2FwTmV1dHJpbm9Ub0Jhc2tldAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQp4dG5Bc3NldElkBQ1tYXhTd2FwQW1vdW50BQNuaWwDCQAAAgUUc3dhcE5ldXRyaW5vVG9Bc3NldHMFFHN3YXBOZXV0cmlub1RvQXNzZXRzBApwcmljZUluZGV4CQBkAgkBEUBleHRyTmF0aXZlKDEwNTApAgkBB0FkZHJlc3MBBRluZXV0cmlub1ByaWNlSW5kZXhBZGRyZXNzAgtwcmljZV9pbmRleAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRF4dG5Td2FwQmxvY2tJZEtleQUGaGVpZ2h0CQDMCAIJAQtTdHJpbmdFbnRyeQIFF3h0blN3YXBUcmFuc2FjdGlvbklkS2V5CQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQJAMwIAgkBDEludGVnZXJFbnRyeQIFFHh0blN3YXBQcmljZUluZGV4S2V5BQpwcmljZUluZGV4CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRp4dG5Td2FwWHRuU3dhcHBlZEFtb3VudEtleQUNbWF4U3dhcEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUceHRuU3dhcFdhdmVzQmFsYW5jZUF0U3dhcEtleQgFE2N1cnJlbnRXYXZlc0JhbGFuY2UJYXZhaWxhYmxlCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRl4dG5Td2FwV3hCYWxhbmNlQXRTd2FwS2V5BRBjdXJyZW50V1hCYWxhbmNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRN4dG5Td2FwU3RhdGVFbnVtS2V5BRxjYXNlWHRuU3dhcFN0YXRlWHRuVG9SZXdhcmRzBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAitJbmNvcnJlY3QgZGF0YSBmcm9tIG5ldXRyaW5vIHNtYXJ0IGNvbnRyYWN0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBJ3h0blN3YXBQYXJ0MmV4Y2hhbmdlWHRuU3dhcFJld2FyZHNPbkRleAADCQECIT0CCQERQGV4dHJOYXRpdmUoMTA1NSkBBRN4dG5Td2FwU3RhdGVFbnVtS2V5BRxjYXNlWHRuU3dhcFN0YXRlWHRuVG9SZXdhcmRzCQACAQIhV3Jvbmcgc3RhdGUsIG11c3QgYmUgWHRuVG9SZXdhcmRzAwkAZwIJARFAZXh0ck5hdGl2ZSgxMDU1KQEFEXh0blN3YXBCbG9ja0lkS2V5BQZoZWlnaHQJAAIBAhVNdXN0IHdhaXQgZm9yIDEgYmxvY2sEEHN3YXBUcmFuc2F0aW9uSWQJARFAZXh0ck5hdGl2ZSgxMDU4KQEFF3h0blN3YXBUcmFuc2FjdGlvbklkS2V5BA5zd2FwUHJpY2VJbmRleAkBEUBleHRyTmF0aXZlKDEwNTUpAQUUeHRuU3dhcFByaWNlSW5kZXhLZXkEDHdpdGhkcmF3X3JlcwkA/AcECQEHQWRkcmVzcwEFF25ldXRyaW5vQ29udHJhY3RBZGRyZXNzAgh3aXRoZHJhdwkAzAgCCQClCAEFBHRoaXMJAMwIAgUOc3dhcFByaWNlSW5kZXgJAMwIAgUQc3dhcFRyYW5zYXRpb25JZAUDbmlsBQNuaWwDCQAAAgUMd2l0aGRyYXdfcmVzBQx3aXRoZHJhd19yZXMEEndhdmVzQmFsYW5jZUF0U3dhcAkBEUBleHRyTmF0aXZlKDEwNTUpAQUceHRuU3dhcFdhdmVzQmFsYW5jZUF0U3dhcEtleQQPd3hCYWxhbmNlQXRTd2FwCQERQGV4dHJOYXRpdmUoMTA1NSkBBRl4dG5Td2FwV3hCYWxhbmNlQXRTd2FwS2V5BBNjdXJyZW50V2F2ZXNCYWxhbmNlCQDvBwEFBHRoaXMEEGN1cnJlbnRXWEJhbGFuY2UJAPAHAgUEdGhpcwUJd3hBc3NldElkBAx3YXZlc1Jld2FyZHMJAGUCCAUTY3VycmVudFdhdmVzQmFsYW5jZQlhdmFpbGFibGUFEndhdmVzQmFsYW5jZUF0U3dhcAQJd3hSZXdhcmRzCQBlAgUQY3VycmVudFdYQmFsYW5jZQUPd3hCYWxhbmNlQXRTd2FwBA1leGNoYW5nZVdhdmVzAwkAZwIAAAUMd2F2ZXNSZXdhcmRzBQNuaWwECXdhdmVzU3dhcAkA/AcECQEHQWRkcmVzcwEFC2RleENvbnRyYWN0AhRleGNoYW5nZVRoZW5UcmFuc2ZlcgkAzAgCCQClCAEJAQdBZGRyZXNzAQUKeHRuQXNzZXRJZAkAzAgCCQClCAEFBHRoaXMJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBHVuaXQFDHdhdmVzUmV3YXJkcwUDbmlsAwkAAAIFCXdhdmVzU3dhcAUJd2F2ZXNTd2FwBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DCQAAAgUNZXhjaGFuZ2VXYXZlcwUNZXhjaGFuZ2VXYXZlcwQGd3hTd2FwCQD8BwQJAQdBZGRyZXNzAQULZGV4Q29udHJhY3QCFGV4Y2hhbmdlVGhlblRyYW5zZmVyCQDMCAIJAKUIAQkBB0FkZHJlc3MBBQp4dG5Bc3NldElkCQDMCAIJAKUIAQUEdGhpcwkAzAgCAAAFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUJd3hBc3NldElkBQl3eFJld2FyZHMFA25pbAMJAAACBQZ3eFN3YXAFBnd4U3dhcAkAzAgCCQEMSW50ZWdlckVudHJ5AgIWV0FWRVNfUkVXQVJEU19GT1JfU1dBUAUMd2F2ZXNSZXdhcmRzCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhNXWF9SRVdBUkRTX0ZPUl9TV0FQBQl3eFJld2FyZHMJAMwIAgkBDEludGVnZXJFbnRyeQIFHnh0blN3YXBYdG5CYWxhbmNlQXRFeGNoYW5nZUtleQkA8AcCBQR0aGlzBQp4dG5Bc3NldElkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRl4dG5Td2FwRXhjaGFuZ2VCbG9ja0lkS2V5BQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFE3h0blN3YXBTdGF0ZUVudW1LZXkFJGNhc2VYdG5Td2FwU3RhdGVFeGNoYW5nZVJld2FyZHNPbkRleAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBGHh0blN3YXBQYXJ0M0ZpbmFsaXplU3dhcAADCQECIT0CCQERQGV4dHJOYXRpdmUoMTA1NSkBBRN4dG5Td2FwU3RhdGVFbnVtS2V5BSRjYXNlWHRuU3dhcFN0YXRlRXhjaGFuZ2VSZXdhcmRzT25EZXgJAAIBAiVXcm9uZyBzdGF0ZSwgbXVzdCBiZSBFeGNoYW5nZSByZXdhcmRzAwkAZwIJARFAZXh0ck5hdGl2ZSgxMDU1KQEFGXh0blN3YXBFeGNoYW5nZUJsb2NrSWRLZXkFBmhlaWdodAkAAgECFU11c3Qgd2FpdCBmb3IgMSBibG9jawMJAGYCCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAiZUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IGFjY2VwdCBwYXltZW50cwQXeHRuQW1vdW50QmVmb3JlRXhjaGFuZ2UJARFAZXh0ck5hdGl2ZSgxMDU1KQEFHnh0blN3YXBYdG5CYWxhbmNlQXRFeGNoYW5nZUtleQQKeHRuU3dhcHBlZAkBEUBleHRyTmF0aXZlKDEwNTUpAQUaeHRuU3dhcFh0blN3YXBwZWRBbW91bnRLZXkEEGN1cnJlbnRYdG5BbW91bnQJAPAHAgUEdGhpcwUKeHRuQXNzZXRJZAQYeHRuUmV3YXJkQW1vdW50Rm9yUGVyaW9kCQBlAgUQY3VycmVudFh0bkFtb3VudAkAZAIFF3h0bkFtb3VudEJlZm9yZUV4Y2hhbmdlBQp4dG5Td2FwcGVkBBZjdXJyZW50WHRuU3dhcFBlcmlvZElkCQERQGV4dHJOYXRpdmUoMTA1NSkBBRljdXJyZW50WFROU3dhcFBlcmlvZElkS2V5BA90b3RhbFN1cmZTdGFrZWQJAQphc0ludE9yRGVmAgkAnwgBBRJ0b3RhbFN1cmZTdGFrZWRLZXkAAAQceHRuUmV3YXJkUGVyT25lU3VyZkZvclBlcmlvZAMJAGcCAAAFGHh0blJld2FyZEFtb3VudEZvclBlcmlvZAAACQBuBAUYeHRuUmV3YXJkQW1vdW50Rm9yUGVyaW9kBQVNVUxUNgUPdG90YWxTdXJmU3Rha2VkBQZIQUxGVVAJAMwIAgkBDEludGVnZXJFbnRyeQIJASprZXlDdXJyZW50WHRuU3dhcFBlcmlvZFh0bkFtb3VudEZvck9uZVN1cmYBBRZjdXJyZW50WHRuU3dhcFBlcmlvZElkBRx4dG5SZXdhcmRQZXJPbmVTdXJmRm9yUGVyaW9kCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRljdXJyZW50WFROU3dhcFBlcmlvZElkS2V5CQBkAgUWY3VycmVudFh0blN3YXBQZXJpb2RJZAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRN4dG5Td2FwU3RhdGVFbnVtS2V5BRRjYXNlWHRuU3dhcFN0YXRlSWRsZQUDbmlsAWkBBWNsYWltAAQJeHRuUmVzdWx0CQD8BwQFBHRoaXMCE2NsYWltWHRuU3dhcFJld2FyZHMFA25pbAUDbmlsAwkAAAIFCXh0blJlc3VsdAUJeHRuUmVzdWx0BApzdXJmUmVzdWx0CQD8BwQFBHRoaXMCF2NsYWltU3VyZlN0YWtpbmdSZXdhcmRzBQNuaWwFA25pbAMJAAACBQpzdXJmUmVzdWx0BQpzdXJmUmVzdWx0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQETY2xhaW1YdG5Td2FwUmV3YXJkcwADCQBmAgkAkAMBCAUBaQhwYXltZW50cwAACQACAQImVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBhY2NlcHQgcGF5bWVudHMEE2NhbGxlckFkZHJlc3NTdHJpbmcJANgEAQgIBQFpBmNhbGxlcgVieXRlcwQWY3VycmVudFh0blN3YXBQZXJpb2RJZAkBCmFzSW50T3JEZWYCCQCfCAEFGWN1cnJlbnRYVE5Td2FwUGVyaW9kSWRLZXkAAAQpY3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQJAQphc0ludE9yRGVmAgkAnwgBCQEsa2V5Q3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQBBRNjYWxsZXJBZGRyZXNzU3RyaW5nAP///////////wEDCQAAAgUpY3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQA////////////AQkAlAoCBQNuaWwA////////////AQMJAAACBSljdXJyZW50VXNlclVuY2xhaW1lZFh0blN3YXBSZXdhcmRQZXJpb2RJZAUWY3VycmVudFh0blN3YXBQZXJpb2RJZAkAAgECMllvdSBuZWVkIHRvIHdhaXQgZm9yIGN1cnJlbnQgc3dhcCBwZXJpb2QgdG8gZmluaXNoBBZ1bmNsYWltZWRYdG5Td2Fwc0NvdW50CQBlAgUWY3VycmVudFh0blN3YXBQZXJpb2RJZAUpY3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQEE3VzZXJUb3RhbFN1cmZTdGFrZWQJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAR1rZXlDdXJyZW50VXNlclRvdGFsU3VyZlN0YWtlZAEFE2NhbGxlckFkZHJlc3NTdHJpbmcELG5ld0N1cnJlbnRVc2VyVW5jbGFpbWVkWHRuU3dhcFJld2FyZFBlcmlvZElkAwkAZgIFFnVuY2xhaW1lZFh0blN3YXBzQ291bnQALQkAZAIFKWN1cnJlbnRVc2VyVW5jbGFpbWVkWHRuU3dhcFJld2FyZFBlcmlvZElkAC0FFmN1cnJlbnRYdG5Td2FwUGVyaW9kSWQECml0ZXJhdGlvbnMDCQBmAgAtBRZ1bmNsYWltZWRYdG5Td2Fwc0NvdW50BRZ1bmNsYWltZWRYdG5Td2Fwc0NvdW50AC0EBnJlc3VsdAkA/AcEBQR0aGlzAiBpbnRlcm5hbEFjY3VtdWxhdGVYdG5Td2FwUmV3YXJkcwkAzAgCBQppdGVyYXRpb25zCQDMCAIAAAkAzAgCBSljdXJyZW50VXNlclVuY2xhaW1lZFh0blN3YXBSZXdhcmRQZXJpb2RJZAkAzAgCAAAJAMwIAgUTdXNlclRvdGFsU3VyZlN0YWtlZAkAzAgCCAgFAWkGY2FsbGVyBWJ5dGVzBQNuaWwFA25pbAMJAAACBQZyZXN1bHQFBnJlc3VsdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBLGtleUN1cnJlbnRVc2VyVW5jbGFpbWVkWHRuU3dhcFJld2FyZFBlcmlvZElkAQUTY2FsbGVyQWRkcmVzc1N0cmluZwUsbmV3Q3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQZmaXhLZXkACQDMCAIJAQxJbnRlZ2VyRW50cnkCAk5jdXJyZW50VXNlclVuY2xhaW1lZFh0blN3YXBSZXdhcmRQZXJpb2RJZF9fM1BBdjQyc2tOTVdlZE1TTng3NWZNRHVNY0Z6Z2dhRUxZcUsAAAUDbmlsAWkBIGludGVybmFsQWNjdW11bGF0ZVh0blN3YXBSZXdhcmRzBgppdGVyYXRpb25zB2N1cnJlbnQUc3RhcnRYdG5Td2FwUGVyaW9kSWQUYWNjdW11bGF0ZWRSZXdhcmRYdG4OdXNlclN1cmZBbW91bnQHYWRkcmVzcwMJAQIhPQIFBHRoaXMIBQFpBmNhbGxlcgkAAgECEUludGVybmFsIGZ1bmN0aW9uAwkAZwIFB2N1cnJlbnQFCml0ZXJhdGlvbnMDCQBmAgUUYWNjdW11bGF0ZWRSZXdhcmRYdG4AAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQEHQWRkcmVzcwEFB2FkZHJlc3MFFGFjY3VtdWxhdGVkUmV3YXJkWHRuBQp4dG5Bc3NldElkBQNuaWwFA25pbAQQeHRuQW1vdW50UGVyU3VyZgkBCmFzSW50T3JEZWYCCQCfCAEJASprZXlDdXJyZW50WHRuU3dhcFBlcmlvZFh0bkFtb3VudEZvck9uZVN1cmYBCQBkAgUUc3RhcnRYdG5Td2FwUGVyaW9kSWQFB2N1cnJlbnQAAAQGcmV3YXJkAwkAAAIFEHh0bkFtb3VudFBlclN1cmYAAAAACQBuBAUQeHRuQW1vdW50UGVyU3VyZgUOdXNlclN1cmZBbW91bnQFBU1VTFQ2BQZIQUxGVVAEBnJlc3VsdAkA/AcEBQR0aGlzAiBpbnRlcm5hbEFjY3VtdWxhdGVYdG5Td2FwUmV3YXJkcwkAzAgCBQppdGVyYXRpb25zCQDMCAIJAGQCBQdjdXJyZW50AAEJAMwIAgkAZAIFFHN0YXJ0WHRuU3dhcFBlcmlvZElkBQdjdXJyZW50CQDMCAIJAGQCBRRhY2N1bXVsYXRlZFJld2FyZFh0bgUGcmV3YXJkCQDMCAIFDnVzZXJTdXJmQW1vdW50CQDMCAIFB2FkZHJlc3MFA25pbAUDbmlsAwkAAAIFBnJlc3VsdAUGcmVzdWx0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEXY2xhaW1TdXJmU3Rha2luZ1Jld2FyZHMAAwkAZgIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECJlRoaXMgZnVuY3Rpb24gZG9lcyBub3QgYWNjZXB0IHBheW1lbnRzBBNjYWxsZXJBZGRyZXNzU3RyaW5nCQDYBAEICAUBaQZjYWxsZXIFYnl0ZXMEIWN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAkBCmFzSW50T3JEZWYCCQCfCAEFJGN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZEtleQAABC1jdXJyZW50VXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kSWQJAQphc0ludE9yRGVmAgkAnwgBCQEwa2V5Q3VycmVudFVzZXJVbmNsYWltZWRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZElkAQUTY2FsbGVyQWRkcmVzc1N0cmluZwD///////////8BAwkAAAIFLWN1cnJlbnRVc2VyVW5jbGFpbWVkU3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RJZAD///////////8BCQCUCgIFA25pbAD///////////8BAwkAAAIFLWN1cnJlbnRVc2VyVW5jbGFpbWVkU3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RJZAUhY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkCQACAQIyWW91IG5lZWQgdG8gd2FpdCBmb3IgY3VycmVudCBzd2FwIHBlcmlvZCB0byBmaW5pc2gEGnVuY2xhaW1lZFN1cmZTdGFraW5nc0NvdW50CQBlAgUhY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkBS1jdXJyZW50VXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kSWQEE3VzZXJUb3RhbFN1cmZTdGFrZWQJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAR1rZXlDdXJyZW50VXNlclRvdGFsU3VyZlN0YWtlZAEFE2NhbGxlckFkZHJlc3NTdHJpbmcEMG5ld0N1cnJlbnRVc2VyVW5jbGFpbWVkU3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RJZAMJAGYCBRp1bmNsYWltZWRTdXJmU3Rha2luZ3NDb3VudAAtCQBkAgUtY3VycmVudFVzZXJVbmNsYWltZWRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZElkAC0FIWN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAQKaXRlcmF0aW9ucwMJAGYCAC0FGnVuY2xhaW1lZFN1cmZTdGFraW5nc0NvdW50BRp1bmNsYWltZWRTdXJmU3Rha2luZ3NDb3VudAAtBAZyZXN1bHQJAPwHBAUEdGhpcwIkaW50ZXJuYWxBY2N1bXVsYXRlU3VyZlN0YWtpbmdSZXdhcmRzCQDMCAIFCml0ZXJhdGlvbnMJAMwIAgAACQDMCAIFLWN1cnJlbnRVc2VyVW5jbGFpbWVkU3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RJZAkAzAgCAAAJAMwIAgAACQDMCAIAAAkAzAgCBRN1c2VyVG90YWxTdXJmU3Rha2VkCQDMCAIICAUBaQZjYWxsZXIFYnl0ZXMFA25pbAUDbmlsAwkAAAIFBnJlc3VsdAUGcmVzdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEwa2V5Q3VycmVudFVzZXJVbmNsYWltZWRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZElkAQUTY2FsbGVyQWRkcmVzc1N0cmluZwUwbmV3Q3VycmVudFVzZXJVbmNsYWltZWRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZElkBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEkaW50ZXJuYWxBY2N1bXVsYXRlU3VyZlN0YWtpbmdSZXdhcmRzCAppdGVyYXRpb25zB2N1cnJlbnQVc3RhcnRTdXJmU3dhcFBlcmlvZElkFmFjY3VtdWxhdGVkUmV3YXJkV2F2ZXMTYWNjdW11bGF0ZWRSZXdhcmRXeBRhY2N1bXVsYXRlZFJld2FyZFh0bg51c2VyU3VyZkFtb3VudAdhZGRyZXNzAwkBAiE9AgUEdGhpcwgFAWkGY2FsbGVyCQACAQIRSW50ZXJuYWwgZnVuY3Rpb24DCQBnAgUHY3VycmVudAUKaXRlcmF0aW9ucwMDAwkAZgIFFGFjY3VtdWxhdGVkUmV3YXJkWHRuAAAGCQBmAgUWYWNjdW11bGF0ZWRSZXdhcmRXYXZlcwAABgkAZgIFE2FjY3VtdWxhdGVkUmV3YXJkV3gAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQEHQWRkcmVzcwEFB2FkZHJlc3MFFGFjY3VtdWxhdGVkUmV3YXJkWHRuBQp4dG5Bc3NldElkCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJAQdBZGRyZXNzAQUHYWRkcmVzcwUWYWNjdW11bGF0ZWRSZXdhcmRXYXZlcwUMd2F2ZXNBc3NldElkCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJAQdBZGRyZXNzAQUHYWRkcmVzcwUTYWNjdW11bGF0ZWRSZXdhcmRXeAUJd3hBc3NldElkBQNuaWwFA25pbAQQeHRuQW1vdW50UGVyU3VyZgkBCmFzSW50T3JEZWYCCQCfCAEJATRrZXlDdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RYdG5BbW91bnRGb3JPbmVTdXJmAQkAZAIFFXN0YXJ0U3VyZlN3YXBQZXJpb2RJZAUHY3VycmVudAAABBJ3YXZlc0Ftb3VudFBlclN1cmYJAQphc0ludE9yRGVmAgkAnwgBCQE2a2V5Q3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kV2F2ZXNBbW91bnRGb3JPbmVTdXJmAQkAZAIFFXN0YXJ0U3VyZlN3YXBQZXJpb2RJZAUHY3VycmVudAAABA93eEFtb3VudFBlclN1cmYJAQphc0ludE9yRGVmAgkAnwgBCQEza2V5Q3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kV3hBbW91bnRGb3JPbmVTdXJmAQkAZAIFFXN0YXJ0U3VyZlN3YXBQZXJpb2RJZAUHY3VycmVudAAABAl4dG5SZXdhcmQDCQAAAgUQeHRuQW1vdW50UGVyU3VyZgAAAAAJAG4EBRB4dG5BbW91bnRQZXJTdXJmBQ51c2VyU3VyZkFtb3VudAUFTVVMVDYFBkhBTEZVUAQLd2F2ZXNSZXdhcmQDCQAAAgUSd2F2ZXNBbW91bnRQZXJTdXJmAAAAAAkAbgQFEndhdmVzQW1vdW50UGVyU3VyZgUOdXNlclN1cmZBbW91bnQFBU1VTFQ2BQZIQUxGVVAECHd4UmV3YXJkAwkAAAIFD3d4QW1vdW50UGVyU3VyZgAAAAAJAG4EBQ93eEFtb3VudFBlclN1cmYFDnVzZXJTdXJmQW1vdW50BQVNVUxUNgUGSEFMRlVQBAZyZXN1bHQJAPwHBAUEdGhpcwIkaW50ZXJuYWxBY2N1bXVsYXRlU3VyZlN0YWtpbmdSZXdhcmRzCQDMCAIFCml0ZXJhdGlvbnMJAMwIAgkAZAIFB2N1cnJlbnQAAQkAzAgCCQBkAgUVc3RhcnRTdXJmU3dhcFBlcmlvZElkBQdjdXJyZW50CQDMCAIJAGQCBRZhY2N1bXVsYXRlZFJld2FyZFdhdmVzBQt3YXZlc1Jld2FyZAkAzAgCCQBkAgUTYWNjdW11bGF0ZWRSZXdhcmRXeAUId3hSZXdhcmQJAMwIAgkAZAIFFGFjY3VtdWxhdGVkUmV3YXJkWHRuBQl4dG5SZXdhcmQJAMwIAgUOdXNlclN1cmZBbW91bnQJAMwIAgUHYWRkcmVzcwUDbmlsBQNuaWwDCQAAAgUGcmVzdWx0BQZyZXN1bHQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpASNzdXJmU3Rha2luZ1Jld2FyZHNDbGFpbUZyb21OZXV0cmlubwADCQBmAgkAkAMBCAUBaQhwYXltZW50cwAACQACAQImVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBhY2NlcHQgcGF5bWVudHMEFmN1cnJlbnRXYXZlc09uQ29udHJhY3QJAPAHAgUEdGhpcwUMd2F2ZXNBc3NldElkAwkAAAIFFmN1cnJlbnRXYXZlc09uQ29udHJhY3QFFmN1cnJlbnRXYXZlc09uQ29udHJhY3QEE2N1cnJlbnRXeE9uQ29udHJhY3QJAPAHAgUEdGhpcwUJd3hBc3NldElkAwkAAAIFE2N1cnJlbnRXeE9uQ29udHJhY3QFE2N1cnJlbnRXeE9uQ29udHJhY3QEFGN1cnJlbnRYdG5PbkNvbnRyYWN0CQDwBwIFBHRoaXMFCnh0bkFzc2V0SWQDCQAAAgUUY3VycmVudFh0bk9uQ29udHJhY3QFFGN1cnJlbnRYdG5PbkNvbnRyYWN0BAZyZXN1bHQJAPwHBAkBB0FkZHJlc3MBBRZuZXV0cmlub1N0YWtpbmdBZGRyZXNzAgxjbGFpbVJld2FyZHMFA25pbAUDbmlsAwkAAAIFBnJlc3VsdAUGcmVzdWx0BBJuZXdXYXZlc09uQ29udHJhY3QJAPAHAgUEdGhpcwUMd2F2ZXNBc3NldElkBA9uZXdXeE9uQ29udHJhY3QJAPAHAgUEdGhpcwUJd3hBc3NldElkBBBuZXdYdG5PbkNvbnRyYWN0CQDwBwIFBHRoaXMFCnh0bkFzc2V0SWQEGndhdmVzUmV3YXJkQW1vdW50Rm9yUGVyaW9kCQBlAgUSbmV3V2F2ZXNPbkNvbnRyYWN0BRZjdXJyZW50V2F2ZXNPbkNvbnRyYWN0BBd3eFJld2FyZEFtb3VudEZvclBlcmlvZAkAZQIFD25ld1d4T25Db250cmFjdAUTY3VycmVudFd4T25Db250cmFjdAQYeHRuUmV3YXJkQW1vdW50Rm9yUGVyaW9kCQBlAgUQbmV3WHRuT25Db250cmFjdAUUY3VycmVudFh0bk9uQ29udHJhY3QEIWN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAkBEUBleHRyTmF0aXZlKDEwNTUpAQUkY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkS2V5BA90b3RhbFN1cmZTdGFrZWQJAQphc0ludE9yRGVmAgkAnwgBBRJ0b3RhbFN1cmZTdGFrZWRLZXkAAAMDCQAAAgUPdG90YWxTdXJmU3Rha2VkAAADAwkBAiE9AgUad2F2ZXNSZXdhcmRBbW91bnRGb3JQZXJpb2QAAAYJAQIhPQIFF3d4UmV3YXJkQW1vdW50Rm9yUGVyaW9kAAAGCQECIT0CBRh4dG5SZXdhcmRBbW91bnRGb3JQZXJpb2QAAAcEHG5ld0RldnNXYXZlc0Ftb3VudEF0Q29udHJhY3QJAGQCCQERQGV4dHJOYXRpdmUoMTA1NSkBBRJkZXZzV2F2ZXNBbW91bnRLZXkFGndhdmVzUmV3YXJkQW1vdW50Rm9yUGVyaW9kBBluZXdEZXZzV3hBbW91bnRBdENvbnRyYWN0CQBkAgkBEUBleHRyTmF0aXZlKDEwNTUpAQUPZGV2c1d4QW1vdW50S2V5BRd3eFJld2FyZEFtb3VudEZvclBlcmlvZAQabmV3RGV2c1h0bkFtb3VudEF0Q29udHJhY3QJAGQCCQERQGV4dHJOYXRpdmUoMTA1NSkBBRBkZXZzWHRuQW1vdW50S2V5BRh4dG5SZXdhcmRBbW91bnRGb3JQZXJpb2QJAMwIAgkBDEludGVnZXJFbnRyeQIJATZrZXlDdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RXYXZlc0Ftb3VudEZvck9uZVN1cmYBBSFjdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kSWQAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBM2tleUN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZFd4QW1vdW50Rm9yT25lU3VyZgEFIWN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAAACQDMCAIJAQxJbnRlZ2VyRW50cnkCCQE0a2V5Q3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kWHRuQW1vdW50Rm9yT25lU3VyZgEFIWN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBSRjdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kSWRLZXkJAGQCBSFjdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kSWQAAQkAzAgCCQEMSW50ZWdlckVudHJ5AgUSZGV2c1dhdmVzQW1vdW50S2V5BRxuZXdEZXZzV2F2ZXNBbW91bnRBdENvbnRyYWN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9kZXZzV3hBbW91bnRLZXkFGW5ld0RldnNXeEFtb3VudEF0Q29udHJhY3QJAMwIAgkBDEludGVnZXJFbnRyeQIFEGRldnNYdG5BbW91bnRLZXkFGm5ld0RldnNYdG5BbW91bnRBdENvbnRyYWN0BQNuaWwDCQAAAgUPdG90YWxTdXJmU3Rha2VkAAAFA25pbAQed2F2ZXNSZXdhcmRQZXJPbmVTdXJmRm9yUGVyaW9kAwkAAAIFGndhdmVzUmV3YXJkQW1vdW50Rm9yUGVyaW9kAAAAAAkAbgQFGndhdmVzUmV3YXJkQW1vdW50Rm9yUGVyaW9kBQVNVUxUNgUPdG90YWxTdXJmU3Rha2VkBQZIQUxGVVAEG3d4UmV3YXJkUGVyT25lU3VyZkZvclBlcmlvZAMJAAACBRd3eFJld2FyZEFtb3VudEZvclBlcmlvZAAAAAAJAG4EBRd3eFJld2FyZEFtb3VudEZvclBlcmlvZAUFTVVMVDYFD3RvdGFsU3VyZlN0YWtlZAUGSEFMRlVQBBx4dG5SZXdhcmRQZXJPbmVTdXJmRm9yUGVyaW9kAwkAAAIFGHh0blJld2FyZEFtb3VudEZvclBlcmlvZAAAAAAJAG4EBRh4dG5SZXdhcmRBbW91bnRGb3JQZXJpb2QFBU1VTFQ2BQ90b3RhbFN1cmZTdGFrZWQFBkhBTEZVUAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBNmtleUN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZFdhdmVzQW1vdW50Rm9yT25lU3VyZgEFIWN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAUed2F2ZXNSZXdhcmRQZXJPbmVTdXJmRm9yUGVyaW9kCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEza2V5Q3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kV3hBbW91bnRGb3JPbmVTdXJmAQUhY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkBRt3eFJld2FyZFBlck9uZVN1cmZGb3JQZXJpb2QJAMwIAgkBDEludGVnZXJFbnRyeQIJATRrZXlDdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RYdG5BbW91bnRGb3JPbmVTdXJmAQUhY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkBRx4dG5SZXdhcmRQZXJPbmVTdXJmRm9yUGVyaW9kCQDMCAIJAQxJbnRlZ2VyRW50cnkCBSRjdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kSWRLZXkJAGQCBSFjdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kSWQAAQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJ0eAEGdmVyaWZ5AAkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAgFAnR4D3NlbmRlclB1YmxpY0tleRVxl5c=", "height": 3598581, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 2tX5s9AYza71shnLs6iP4poZKsoWJ9C1od5ygnhyeqE4 Next: 33FFMKymaLuQhqEzDiEDoSzhUA9JM2s6QhAPFZBFQUaX Diff:
OldNewDifferences
490490
491491
492492 @Callable(i)
493-func addKey () = [IntegerEntry("currentXTNSwapPeriodXtnAmountForOneSurf__0", 214)]
493+func fixKey () = [IntegerEntry("currentUserUnclaimedXtnSwapRewardPeriodId__3PAv42skNMWedMSNx75fMDuMcFzggaELYqK", 0)]
494494
495495
496496
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
55
66 let minAmount = 100000
77
88 let MULT6 = 1000000
99
1010 let MULT8 = 100000000
1111
1212 let wavesAssetId = fromBase58String("WAVES")
1313
1414 let wxAssetId = base58'Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on'
1515
1616 let surfAssetId = base58'At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL'
1717
1818 let xtnAssetId = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
1919
2020 let dexContract = base58'3PLPCb3wF2H2gtzohoAjeWcGaMKEiJvtE5X'
2121
2222 let neutrinoContractAddress = base58'3PC9BfRwJWWiw9AREE2B3eWzCks3CYtg4yo'
2323
2424 let neutrinoStakingAddress = base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'
2525
2626 let neutrinoPriceIndexAddress = base58'3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP'
2727
2828 let caseXtnSwapStateIdle = 0
2929
3030 let caseXtnSwapStateXtnToRewards = 1
3131
3232 let caseXtnSwapStateExchangeRewardsOnDex = 2
3333
3434 let constructedKey = "constructed"
3535
3636 let xtnSwapStateEnumKey = "xtnSwapStateEnum"
3737
3838 let totalSurfStakedKey = "totalSurfStaked"
3939
4040 let pendingTotalSurfAmountToWithdrawalKey = "pendingTotalSuftAmountToWithdrawal"
4141
4242 let devsWavesAmountKey = "devsWavesAmount"
4343
4444 let devsSurfAmountKey = "devsSurfAmount"
4545
4646 let devsWxAmountKey = "devsWxAmount"
4747
4848 let devsXtnAmountKey = "devsXtnAmountKey"
4949
5050 let xtnSwapBlockIdKey = "xtnSwapBlockId"
5151
5252 let xtnSwapTransactionIdKey = "xtnSwapTransactionId"
5353
5454 let xtnSwapPriceIndexKey = "xtnSwapPriceIndex"
5555
5656 let xtnSwapXtnSwappedAmountKey = "xtnSwapXtnSwappedAmount"
5757
5858 let xtnSwapWavesBalanceAtSwapKey = "xtnSwapWavesBalanceAtSwap"
5959
6060 let xtnSwapWxBalanceAtSwapKey = "xtnSwapWxBalanceAtSwap"
6161
6262 let xtnSwapXtnBalanceAtExchangeKey = "xtnSwapXtnBalanceAtExchange"
6363
6464 let xtnSwapExchangeBlockIdKey = "xtnSwapExchangeBlockId"
6565
6666 let lastSuccessSwapBlockHeight = "lastSuccessSwapBlockHeight"
6767
6868 let currentWithdrawalPeriodIdKey = "currentWithdrawalPeriodId"
6969
7070 let currentXTNSwapPeriodIdKey = "currentXTNSwapPeriodId"
7171
7272 let currentSurfStakingRewardsPeriodIdKey = "currentSurfStakingRewardsPeriodIdKey"
7373
7474 func keyCurrentXtnSwapPeriodXtnAmountForOneSurf (periodId) = (("currentXTNSwapPeriod" + SEP) + toString(periodId))
7575
7676
7777 func keyCurrentSurfStakingRewardPeriodWavesAmountForOneSurf (periodId) = (("currentSurfStakingRewardPeriodWavesAmount" + SEP) + toString(periodId))
7878
7979
8080 func keyCurrentSurfStakingRewardPeriodWxAmountForOneSurf (periodId) = (("currentSurfStakingRewardPeriodWwAmount" + SEP) + toString(periodId))
8181
8282
8383 func keyCurrentSurfStakingRewardPeriodXtnAmountForOneSurf (periodId) = (("currentSurfStakingRewardPeriodXtnAmount" + SEP) + toString(periodId))
8484
8585
8686 func keyCurrentUserTotalSurfStaked (address) = (("currentUserTotalSurfStaked" + SEP) + address)
8787
8888
8989 func keyCurrentUserUnclaimedXtnSwapRewardPeriodId (address) = (("currentUserUnclaimedXtnSwapRewardPeriodId" + SEP) + address)
9090
9191
9292 func keyCurrentUserUnclaimedSurfStakingRewardPeriodId (address) = (("currentUserUnclaimedSurfStakingRewardPeriodId" + SEP) + address)
9393
9494
9595 func keyCurrentUserPendingWithdrawalPeriodId (address) = (("currentUserPendingWithdrawalPeriodId" + SEP) + address)
9696
9797
9898 func keyCurrentUserTotalSurfPendingForWithdrawal (address) = (("currentUserTotalSurfPendingForWithdrawal" + SEP) + address)
9999
100100
101101 func asPayment (v) = match v {
102102 case p: AttachedPayment =>
103103 p
104104 case _ =>
105105 throw("fail to cast into AttachedPayment")
106106 }
107107
108108
109109 func asInt (val) = match val {
110110 case valInt: Int =>
111111 valInt
112112 case _ =>
113113 throw("fail to cast into Int")
114114 }
115115
116116
117117 func asIntOrThrow (val,message) = match val {
118118 case valInt: Int =>
119119 valInt
120120 case _ =>
121121 throw(message)
122122 }
123123
124124
125125 func asIntOrDef (val,default) = match val {
126126 case valInt: Int =>
127127 valInt
128128 case _ =>
129129 default
130130 }
131131
132132
133133 func asString (val) = match val {
134134 case valString: String =>
135135 valString
136136 case _ =>
137137 throw("fail to cast into String")
138138 }
139139
140140
141141 func asStringOrDef (val,default) = match val {
142142 case valString: String =>
143143 valString
144144 case _ =>
145145 default
146146 }
147147
148148
149149 func asBoolean (val) = match val {
150150 case valBool: Boolean =>
151151 valBool
152152 case _ =>
153153 throw("fail to cast into Boolean")
154154 }
155155
156156
157157 func asBooleanOrDef (val,default) = match val {
158158 case valBool: Boolean =>
159159 valBool
160160 case _ =>
161161 default
162162 }
163163
164164
165165 func currentProportion (xtnSwapLimitMax) = {
166166 let totalSurfStaked = getIntegerValue(totalSurfStakedKey)
167167 fraction(toBigInt(totalSurfStaked), toBigInt(MULT6), toBigInt(xtnSwapLimitMax), HALFUP)
168168 }
169169
170170
171171 func checkProportion (xtnSwapLimitMax,surfAmount,xntAmount) = {
172172 let proportion = currentProportion(xtnSwapLimitMax)
173173 let expectedSurfAmount = toInt(fraction(proportion, toBigInt(xntAmount), toBigInt(MULT6), HALFUP))
174174 if ((expectedSurfAmount == surfAmount))
175175 then true
176176 else throw((((("With " + toString(xtnSwapLimitMax)) + " XNT amount you should provide ") + toString(expectedSurfAmount)) + " SURF amount to stake"))
177177 }
178178
179179
180180 let EMPTY = "^"
181181
182182 func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
183183
184184
185185 func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP)
186186
187187
188188 func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount))
189189
190190
191191 func interactWithSwapParamsByUser () = {
192192 let result = invoke(Address(neutrinoStakingAddress), "swapParamsByUserSYSREADONLY", [this, 0], nil)
193193 if ((result == result))
194194 then match result {
195195 case tuple: (Int, Int, Int, Int, Int, Int, Int) =>
196196 [tuple._1, tuple._2, tuple._3, tuple._4, tuple._5, tuple._6, tuple._7]
197197 case _ =>
198198 throw("FATAL: Can't fetch data from neutrino contract")
199199 }
200200 else throw("Strict value is not equal to itself.")
201201 }
202202
203203
204204 func isUserHasUnclaimedRewardsInPreviousPeriods (address) = {
205205 let userUnclaimedXtnSwapRewardPeriodId = asIntOrDef(getInteger(keyCurrentUserUnclaimedXtnSwapRewardPeriodId(address)), -1)
206206 let userUnclaimedSurfStakingRewardsPeriodId = asIntOrDef(getInteger(keyCurrentUserUnclaimedSurfStakingRewardPeriodId(address)), -1)
207207 let currentXTNSwapPeriod = asIntOrDef(getInteger(currentXTNSwapPeriodIdKey), 0)
208208 let currentSurfStakingRewardsPeriod = asIntOrDef(getInteger(currentSurfStakingRewardsPeriodIdKey), 0)
209209 if (if ((userUnclaimedXtnSwapRewardPeriodId > -1))
210210 then (currentXTNSwapPeriod > userUnclaimedXtnSwapRewardPeriodId)
211211 else false)
212212 then true
213213 else if (if ((userUnclaimedSurfStakingRewardsPeriodId > -1))
214214 then (currentSurfStakingRewardsPeriod > userUnclaimedSurfStakingRewardsPeriodId)
215215 else false)
216216 then true
217217 else false
218218 }
219219
220220
221221 @Callable(i)
222222 func constructor () = match getBoolean(constructedKey) {
223223 case _: Boolean =>
224224 throw("Constructor can be called just once")
225225 case _ =>
226226 [BooleanEntry(constructedKey, true), IntegerEntry(currentWithdrawalPeriodIdKey, 0), IntegerEntry(currentXTNSwapPeriodIdKey, 0), IntegerEntry(pendingTotalSurfAmountToWithdrawalKey, 0), IntegerEntry(devsWavesAmountKey, 0), IntegerEntry(devsSurfAmountKey, 0), IntegerEntry(devsWxAmountKey, 0), IntegerEntry(devsXtnAmountKey, 0), IntegerEntry(lastSuccessSwapBlockHeight, 0), IntegerEntry(xtnSwapStateEnumKey, caseXtnSwapStateIdle)]
227227 }
228228
229229
230230
231231 @Callable(i)
232232 func stake () = if ((getIntegerValue(xtnSwapStateEnumKey) != caseXtnSwapStateIdle))
233233 then throw("XTN swap in progress, wait approximatelly 3 minutes")
234234 else if ((size(i.payments) != 1))
235235 then throw("You must include exactly one payment in transaction")
236236 else {
237237 let payment = asPayment(i.payments[0])
238238 if (if ((payment.assetId != surfAssetId))
239239 then true
240240 else (minAmount > payment.amount))
241241 then throw("Wrong assetId or amount")
242242 else {
243243 let callerAddressString = toBase58String(i.caller.bytes)
244244 if (isUserHasUnclaimedRewardsInPreviousPeriods(callerAddressString))
245245 then throw("You have unclaimed rewards, claim them first, then stake again")
246246 else {
247247 let result = invoke(Address(neutrinoStakingAddress), "stake", nil, [payment])
248248 if ((result == result))
249249 then {
250250 let newTotalSurfStaked = match getInteger(totalSurfStakedKey) {
251251 case v: Int =>
252252 (v + payment.amount)
253253 case _ =>
254254 payment.amount
255255 }
256256 let callerTotalSurfStakedKey = keyCurrentUserTotalSurfStaked(callerAddressString)
257257 let newCallerTotalSurfStaked = match getInteger(callerTotalSurfStakedKey) {
258258 case v: Int =>
259259 (v + payment.amount)
260260 case _ =>
261261 payment.amount
262262 }
263263 let currentXTNSwapPeriod = asIntOrDef(getInteger(currentXTNSwapPeriodIdKey), 0)
264264 let currentSurfStakingRewardsPeriod = asIntOrDef(getInteger(currentSurfStakingRewardsPeriodIdKey), 0)
265265 [IntegerEntry(totalSurfStakedKey, newTotalSurfStaked), IntegerEntry(callerTotalSurfStakedKey, newCallerTotalSurfStaked), IntegerEntry(keyCurrentUserUnclaimedXtnSwapRewardPeriodId(callerAddressString), currentXTNSwapPeriod), IntegerEntry(keyCurrentUserUnclaimedSurfStakingRewardPeriodId(callerAddressString), currentSurfStakingRewardsPeriod)]
266266 }
267267 else throw("Strict value is not equal to itself.")
268268 }
269269 }
270270 }
271271
272272
273273
274274 @Callable(i)
275275 func applyForPendingWithdraw (amount) = if ((getIntegerValue(xtnSwapStateEnumKey) != caseXtnSwapStateIdle))
276276 then throw("XTN swap in progress, wait approximatelly 3 minutes")
277277 else if ((size(i.payments) > 0))
278278 then throw("This function does not accept payments")
279279 else if ((0 >= amount))
280280 then throw("Amount must be positive")
281281 else {
282282 let callerAddressString = toBase58String(i.caller.bytes)
283283 let callerTotalSurfStaked = getIntegerValue(keyCurrentUserTotalSurfStaked(callerAddressString))
284284 if ((amount > callerTotalSurfStaked))
285285 then throw("Insufficient balance to withdraw")
286286 else if (isUserHasUnclaimedRewardsInPreviousPeriods(callerAddressString))
287287 then throw("You have unclaimed rewards, claim them first, then try again")
288288 else {
289289 let currentWithdrawalId = getIntegerValue(currentWithdrawalPeriodIdKey)
290290 let pendingTotalSurfToUnstakeFromNeutrino = getIntegerValue(pendingTotalSurfAmountToWithdrawalKey)
291291 let userPendingWithdrawalPeriodId = asIntOrDef(getInteger(keyCurrentUserPendingWithdrawalPeriodId(callerAddressString)), -1)
292292 let userTotalSurfPendingForWithdrawal = asIntOrDef(getInteger(keyCurrentUserTotalSurfPendingForWithdrawal(callerAddressString)), 0)
293293 if (if ((userPendingWithdrawalPeriodId > -1))
294294 then (currentWithdrawalId > userPendingWithdrawalPeriodId)
295295 else false)
296296 then throw("You have unclaimed suft on contract, please perform claim first")
297297 else {
298298 let userNewTotalSurfStakedAmount = (callerTotalSurfStaked - amount)
299299 let userNewTotalSurfPendingForWithdrawal = (userTotalSurfPendingForWithdrawal + amount)
300300 let newPendingTotalSurfToUnstakeFromNeutrino = (pendingTotalSurfToUnstakeFromNeutrino + amount)
301301 let newTotalSurfStakedAmount = (getIntegerValue(totalSurfStakedKey) - amount)
302302 [IntegerEntry(keyCurrentUserTotalSurfStaked(callerAddressString), userNewTotalSurfStakedAmount), IntegerEntry(keyCurrentUserPendingWithdrawalPeriodId(callerAddressString), currentWithdrawalId), IntegerEntry(keyCurrentUserTotalSurfPendingForWithdrawal(callerAddressString), userNewTotalSurfPendingForWithdrawal), IntegerEntry(pendingTotalSurfAmountToWithdrawalKey, newPendingTotalSurfToUnstakeFromNeutrino), IntegerEntry(totalSurfStakedKey, newTotalSurfStakedAmount)]
303303 }
304304 }
305305 }
306306
307307
308308
309309 @Callable(i)
310310 func performDistributedWithdraw () = if ((size(i.payments) > 0))
311311 then throw("This function does not accept payments")
312312 else {
313313 let currentWithdrawalId = getIntegerValue(currentWithdrawalPeriodIdKey)
314314 let pendingTotalSurfToUnstakeFromNeutrino = getIntegerValue(pendingTotalSurfAmountToWithdrawalKey)
315315 if ((0 >= pendingTotalSurfToUnstakeFromNeutrino))
316316 then nil
317317 else {
318318 let result = invoke(Address(neutrinoStakingAddress), "unstake", [pendingTotalSurfToUnstakeFromNeutrino], nil)
319319 if ((result == result))
320320 then [IntegerEntry(currentWithdrawalPeriodIdKey, (currentWithdrawalId + 1)), IntegerEntry(pendingTotalSurfAmountToWithdrawalKey, 0)]
321321 else throw("Strict value is not equal to itself.")
322322 }
323323 }
324324
325325
326326
327327 @Callable(i)
328328 func claimSurf () = if ((size(i.payments) > 0))
329329 then throw("This function does not accept payments")
330330 else {
331331 let callerAddressString = toBase58String(i.caller.bytes)
332332 let currentWithdrawalPeriodId = getIntegerValue(currentWithdrawalPeriodIdKey)
333333 let userWithdrawalPeriodId = asIntOrDef(getInteger(keyCurrentUserPendingWithdrawalPeriodId(callerAddressString)), -1)
334334 let userTotalSurfPendingForWithdrawal = asIntOrDef(getInteger(keyCurrentUserTotalSurfPendingForWithdrawal(callerAddressString)), 0)
335335 if (if ((userWithdrawalPeriodId == -1))
336336 then true
337337 else (userTotalSurfPendingForWithdrawal == 0))
338338 then throw("Nothing to withdraw")
339339 else if ((userWithdrawalPeriodId == currentWithdrawalPeriodId))
340340 then throw("You must wait for period to complete")
341341 else [ScriptTransfer(i.caller, userTotalSurfPendingForWithdrawal, surfAssetId), DeleteEntry(keyCurrentUserPendingWithdrawalPeriodId(callerAddressString)), DeleteEntry(keyCurrentUserTotalSurfPendingForWithdrawal(callerAddressString))]
342342 }
343343
344344
345345
346346 @Callable(i)
347347 func xtnSwapPart1swapXTNFromNeutrino () = if ((getIntegerValue(xtnSwapStateEnumKey) != caseXtnSwapStateIdle))
348348 then throw("Wrong state, must be Idle")
349349 else {
350350 let withdrawResult = invoke(this, "performDistributedWithdraw", nil, nil)
351351 if ((withdrawResult == withdrawResult))
352352 then {
353353 let result = invoke(Address(neutrinoContractAddress), "swapParamsByUserSYSREADONLY", [toString(this), 0], nil)
354354 if ((result == result))
355355 then match result {
356356 case tuple: (Int, Int, Int, Int, Int, Int, Int) =>
357357 if ((tuple._3 > 0))
358358 then throw((("Time is not come yet, you need to wait " + toString(tuple._3)) + " blocks"))
359359 else {
360360 let maxSwapAmount = tuple._7
361361 if ((1000000 > maxSwapAmount))
362362 then throw("Min XTN amount to swap is 1, stake more SURF")
363363 else if ((maxSwapAmount > assetBalance(this, xtnAssetId)))
364364 then throw("XTN Balance on contract is smaller than max swap amount, increase XTN contract balance")
365365 else {
366366 let currentWavesBalance = wavesBalance(this)
367367 let currentWXBalance = assetBalance(this, wxAssetId)
368368 let swapNeutrinoToAssets = invoke(Address(neutrinoContractAddress), "swapNeutrinoToBasket", nil, [AttachedPayment(xtnAssetId, maxSwapAmount)])
369369 if ((swapNeutrinoToAssets == swapNeutrinoToAssets))
370370 then {
371371 let priceIndex = (getIntegerValue(Address(neutrinoPriceIndexAddress), "price_index") + 1)
372372 [IntegerEntry(xtnSwapBlockIdKey, height), StringEntry(xtnSwapTransactionIdKey, toBase58String(i.transactionId)), IntegerEntry(xtnSwapPriceIndexKey, priceIndex), IntegerEntry(xtnSwapXtnSwappedAmountKey, maxSwapAmount), IntegerEntry(xtnSwapWavesBalanceAtSwapKey, currentWavesBalance.available), IntegerEntry(xtnSwapWxBalanceAtSwapKey, currentWXBalance), IntegerEntry(xtnSwapStateEnumKey, caseXtnSwapStateXtnToRewards)]
373373 }
374374 else throw("Strict value is not equal to itself.")
375375 }
376376 }
377377 case _ =>
378378 throw("Incorrect data from neutrino smart contract")
379379 }
380380 else throw("Strict value is not equal to itself.")
381381 }
382382 else throw("Strict value is not equal to itself.")
383383 }
384384
385385
386386
387387 @Callable(i)
388388 func xtnSwapPart2exchangeXtnSwapRewardsOnDex () = if ((getIntegerValue(xtnSwapStateEnumKey) != caseXtnSwapStateXtnToRewards))
389389 then throw("Wrong state, must be XtnToRewards")
390390 else if ((getIntegerValue(xtnSwapBlockIdKey) >= height))
391391 then throw("Must wait for 1 block")
392392 else {
393393 let swapTransationId = getStringValue(xtnSwapTransactionIdKey)
394394 let swapPriceIndex = getIntegerValue(xtnSwapPriceIndexKey)
395395 let withdraw_res = invoke(Address(neutrinoContractAddress), "withdraw", [toString(this), swapPriceIndex, swapTransationId], nil)
396396 if ((withdraw_res == withdraw_res))
397397 then {
398398 let wavesBalanceAtSwap = getIntegerValue(xtnSwapWavesBalanceAtSwapKey)
399399 let wxBalanceAtSwap = getIntegerValue(xtnSwapWxBalanceAtSwapKey)
400400 let currentWavesBalance = wavesBalance(this)
401401 let currentWXBalance = assetBalance(this, wxAssetId)
402402 let wavesRewards = (currentWavesBalance.available - wavesBalanceAtSwap)
403403 let wxRewards = (currentWXBalance - wxBalanceAtSwap)
404404 let exchangeWaves = if ((0 >= wavesRewards))
405405 then nil
406406 else {
407407 let wavesSwap = invoke(Address(dexContract), "exchangeThenTransfer", [toString(Address(xtnAssetId)), toString(this), 0], [AttachedPayment(unit, wavesRewards)])
408408 if ((wavesSwap == wavesSwap))
409409 then nil
410410 else throw("Strict value is not equal to itself.")
411411 }
412412 if ((exchangeWaves == exchangeWaves))
413413 then {
414414 let wxSwap = invoke(Address(dexContract), "exchangeThenTransfer", [toString(Address(xtnAssetId)), toString(this), 0], [AttachedPayment(wxAssetId, wxRewards)])
415415 if ((wxSwap == wxSwap))
416416 then [IntegerEntry("WAVES_REWARDS_FOR_SWAP", wavesRewards), IntegerEntry("WX_REWARDS_FOR_SWAP", wxRewards), IntegerEntry(xtnSwapXtnBalanceAtExchangeKey, assetBalance(this, xtnAssetId)), IntegerEntry(xtnSwapExchangeBlockIdKey, height), IntegerEntry(xtnSwapStateEnumKey, caseXtnSwapStateExchangeRewardsOnDex)]
417417 else throw("Strict value is not equal to itself.")
418418 }
419419 else throw("Strict value is not equal to itself.")
420420 }
421421 else throw("Strict value is not equal to itself.")
422422 }
423423
424424
425425
426426 @Callable(i)
427427 func xtnSwapPart3FinalizeSwap () = if ((getIntegerValue(xtnSwapStateEnumKey) != caseXtnSwapStateExchangeRewardsOnDex))
428428 then throw("Wrong state, must be Exchange rewards")
429429 else if ((getIntegerValue(xtnSwapExchangeBlockIdKey) >= height))
430430 then throw("Must wait for 1 block")
431431 else if ((size(i.payments) > 0))
432432 then throw("This function does not accept payments")
433433 else {
434434 let xtnAmountBeforeExchange = getIntegerValue(xtnSwapXtnBalanceAtExchangeKey)
435435 let xtnSwapped = getIntegerValue(xtnSwapXtnSwappedAmountKey)
436436 let currentXtnAmount = assetBalance(this, xtnAssetId)
437437 let xtnRewardAmountForPeriod = (currentXtnAmount - (xtnAmountBeforeExchange + xtnSwapped))
438438 let currentXtnSwapPeriodId = getIntegerValue(currentXTNSwapPeriodIdKey)
439439 let totalSurfStaked = asIntOrDef(getInteger(totalSurfStakedKey), 0)
440440 let xtnRewardPerOneSurfForPeriod = if ((0 >= xtnRewardAmountForPeriod))
441441 then 0
442442 else fraction(xtnRewardAmountForPeriod, MULT6, totalSurfStaked, HALFUP)
443443 [IntegerEntry(keyCurrentXtnSwapPeriodXtnAmountForOneSurf(currentXtnSwapPeriodId), xtnRewardPerOneSurfForPeriod), IntegerEntry(currentXTNSwapPeriodIdKey, (currentXtnSwapPeriodId + 1)), IntegerEntry(xtnSwapStateEnumKey, caseXtnSwapStateIdle)]
444444 }
445445
446446
447447
448448 @Callable(i)
449449 func claim () = {
450450 let xtnResult = invoke(this, "claimXtnSwapRewards", nil, nil)
451451 if ((xtnResult == xtnResult))
452452 then {
453453 let surfResult = invoke(this, "claimSurfStakingRewards", nil, nil)
454454 if ((surfResult == surfResult))
455455 then nil
456456 else throw("Strict value is not equal to itself.")
457457 }
458458 else throw("Strict value is not equal to itself.")
459459 }
460460
461461
462462
463463 @Callable(i)
464464 func claimXtnSwapRewards () = if ((size(i.payments) > 0))
465465 then throw("This function does not accept payments")
466466 else {
467467 let callerAddressString = toBase58String(i.caller.bytes)
468468 let currentXtnSwapPeriodId = asIntOrDef(getInteger(currentXTNSwapPeriodIdKey), 0)
469469 let currentUserUnclaimedXtnSwapRewardPeriodId = asIntOrDef(getInteger(keyCurrentUserUnclaimedXtnSwapRewardPeriodId(callerAddressString)), -1)
470470 if ((currentUserUnclaimedXtnSwapRewardPeriodId == -1))
471471 then $Tuple2(nil, -1)
472472 else if ((currentUserUnclaimedXtnSwapRewardPeriodId == currentXtnSwapPeriodId))
473473 then throw("You need to wait for current swap period to finish")
474474 else {
475475 let unclaimedXtnSwapsCount = (currentXtnSwapPeriodId - currentUserUnclaimedXtnSwapRewardPeriodId)
476476 let userTotalSurfStaked = getIntegerValue(keyCurrentUserTotalSurfStaked(callerAddressString))
477477 let newCurrentUserUnclaimedXtnSwapRewardPeriodId = if ((unclaimedXtnSwapsCount > 45))
478478 then (currentUserUnclaimedXtnSwapRewardPeriodId + 45)
479479 else currentXtnSwapPeriodId
480480 let iterations = if ((45 > unclaimedXtnSwapsCount))
481481 then unclaimedXtnSwapsCount
482482 else 45
483483 let result = invoke(this, "internalAccumulateXtnSwapRewards", [iterations, 0, currentUserUnclaimedXtnSwapRewardPeriodId, 0, userTotalSurfStaked, i.caller.bytes], nil)
484484 if ((result == result))
485485 then [IntegerEntry(keyCurrentUserUnclaimedXtnSwapRewardPeriodId(callerAddressString), newCurrentUserUnclaimedXtnSwapRewardPeriodId)]
486486 else throw("Strict value is not equal to itself.")
487487 }
488488 }
489489
490490
491491
492492 @Callable(i)
493-func addKey () = [IntegerEntry("currentXTNSwapPeriodXtnAmountForOneSurf__0", 214)]
493+func fixKey () = [IntegerEntry("currentUserUnclaimedXtnSwapRewardPeriodId__3PAv42skNMWedMSNx75fMDuMcFzggaELYqK", 0)]
494494
495495
496496
497497 @Callable(i)
498498 func internalAccumulateXtnSwapRewards (iterations,current,startXtnSwapPeriodId,accumulatedRewardXtn,userSurfAmount,address) = if ((this != i.caller))
499499 then throw("Internal function")
500500 else if ((current >= iterations))
501501 then if ((accumulatedRewardXtn > 0))
502502 then [ScriptTransfer(Address(address), accumulatedRewardXtn, xtnAssetId)]
503503 else nil
504504 else {
505505 let xtnAmountPerSurf = asIntOrDef(getInteger(keyCurrentXtnSwapPeriodXtnAmountForOneSurf((startXtnSwapPeriodId + current))), 0)
506506 let reward = if ((xtnAmountPerSurf == 0))
507507 then 0
508508 else fraction(xtnAmountPerSurf, userSurfAmount, MULT6, HALFUP)
509509 let result = invoke(this, "internalAccumulateXtnSwapRewards", [iterations, (current + 1), (startXtnSwapPeriodId + current), (accumulatedRewardXtn + reward), userSurfAmount, address], nil)
510510 if ((result == result))
511511 then nil
512512 else throw("Strict value is not equal to itself.")
513513 }
514514
515515
516516
517517 @Callable(i)
518518 func claimSurfStakingRewards () = if ((size(i.payments) > 0))
519519 then throw("This function does not accept payments")
520520 else {
521521 let callerAddressString = toBase58String(i.caller.bytes)
522522 let currentSurfStakingRewardsPeriodId = asIntOrDef(getInteger(currentSurfStakingRewardsPeriodIdKey), 0)
523523 let currentUserUnclaimedSurfStakingRewardPeriodId = asIntOrDef(getInteger(keyCurrentUserUnclaimedSurfStakingRewardPeriodId(callerAddressString)), -1)
524524 if ((currentUserUnclaimedSurfStakingRewardPeriodId == -1))
525525 then $Tuple2(nil, -1)
526526 else if ((currentUserUnclaimedSurfStakingRewardPeriodId == currentSurfStakingRewardsPeriodId))
527527 then throw("You need to wait for current swap period to finish")
528528 else {
529529 let unclaimedSurfStakingsCount = (currentSurfStakingRewardsPeriodId - currentUserUnclaimedSurfStakingRewardPeriodId)
530530 let userTotalSurfStaked = getIntegerValue(keyCurrentUserTotalSurfStaked(callerAddressString))
531531 let newCurrentUserUnclaimedSurfStakingRewardPeriodId = if ((unclaimedSurfStakingsCount > 45))
532532 then (currentUserUnclaimedSurfStakingRewardPeriodId + 45)
533533 else currentSurfStakingRewardsPeriodId
534534 let iterations = if ((45 > unclaimedSurfStakingsCount))
535535 then unclaimedSurfStakingsCount
536536 else 45
537537 let result = invoke(this, "internalAccumulateSurfStakingRewards", [iterations, 0, currentUserUnclaimedSurfStakingRewardPeriodId, 0, 0, 0, userTotalSurfStaked, i.caller.bytes], nil)
538538 if ((result == result))
539539 then [IntegerEntry(keyCurrentUserUnclaimedSurfStakingRewardPeriodId(callerAddressString), newCurrentUserUnclaimedSurfStakingRewardPeriodId)]
540540 else throw("Strict value is not equal to itself.")
541541 }
542542 }
543543
544544
545545
546546 @Callable(i)
547547 func internalAccumulateSurfStakingRewards (iterations,current,startSurfSwapPeriodId,accumulatedRewardWaves,accumulatedRewardWx,accumulatedRewardXtn,userSurfAmount,address) = if ((this != i.caller))
548548 then throw("Internal function")
549549 else if ((current >= iterations))
550550 then if (if (if ((accumulatedRewardXtn > 0))
551551 then true
552552 else (accumulatedRewardWaves > 0))
553553 then true
554554 else (accumulatedRewardWx > 0))
555555 then [ScriptTransfer(Address(address), accumulatedRewardXtn, xtnAssetId), ScriptTransfer(Address(address), accumulatedRewardWaves, wavesAssetId), ScriptTransfer(Address(address), accumulatedRewardWx, wxAssetId)]
556556 else nil
557557 else {
558558 let xtnAmountPerSurf = asIntOrDef(getInteger(keyCurrentSurfStakingRewardPeriodXtnAmountForOneSurf((startSurfSwapPeriodId + current))), 0)
559559 let wavesAmountPerSurf = asIntOrDef(getInteger(keyCurrentSurfStakingRewardPeriodWavesAmountForOneSurf((startSurfSwapPeriodId + current))), 0)
560560 let wxAmountPerSurf = asIntOrDef(getInteger(keyCurrentSurfStakingRewardPeriodWxAmountForOneSurf((startSurfSwapPeriodId + current))), 0)
561561 let xtnReward = if ((xtnAmountPerSurf == 0))
562562 then 0
563563 else fraction(xtnAmountPerSurf, userSurfAmount, MULT6, HALFUP)
564564 let wavesReward = if ((wavesAmountPerSurf == 0))
565565 then 0
566566 else fraction(wavesAmountPerSurf, userSurfAmount, MULT6, HALFUP)
567567 let wxReward = if ((wxAmountPerSurf == 0))
568568 then 0
569569 else fraction(wxAmountPerSurf, userSurfAmount, MULT6, HALFUP)
570570 let result = invoke(this, "internalAccumulateSurfStakingRewards", [iterations, (current + 1), (startSurfSwapPeriodId + current), (accumulatedRewardWaves + wavesReward), (accumulatedRewardWx + wxReward), (accumulatedRewardXtn + xtnReward), userSurfAmount, address], nil)
571571 if ((result == result))
572572 then nil
573573 else throw("Strict value is not equal to itself.")
574574 }
575575
576576
577577
578578 @Callable(i)
579579 func surfStakingRewardsClaimFromNeutrino () = if ((size(i.payments) > 0))
580580 then throw("This function does not accept payments")
581581 else {
582582 let currentWavesOnContract = assetBalance(this, wavesAssetId)
583583 if ((currentWavesOnContract == currentWavesOnContract))
584584 then {
585585 let currentWxOnContract = assetBalance(this, wxAssetId)
586586 if ((currentWxOnContract == currentWxOnContract))
587587 then {
588588 let currentXtnOnContract = assetBalance(this, xtnAssetId)
589589 if ((currentXtnOnContract == currentXtnOnContract))
590590 then {
591591 let result = invoke(Address(neutrinoStakingAddress), "claimRewards", nil, nil)
592592 if ((result == result))
593593 then {
594594 let newWavesOnContract = assetBalance(this, wavesAssetId)
595595 let newWxOnContract = assetBalance(this, wxAssetId)
596596 let newXtnOnContract = assetBalance(this, xtnAssetId)
597597 let wavesRewardAmountForPeriod = (newWavesOnContract - currentWavesOnContract)
598598 let wxRewardAmountForPeriod = (newWxOnContract - currentWxOnContract)
599599 let xtnRewardAmountForPeriod = (newXtnOnContract - currentXtnOnContract)
600600 let currentSurfStakingRewardsPeriodId = getIntegerValue(currentSurfStakingRewardsPeriodIdKey)
601601 let totalSurfStaked = asIntOrDef(getInteger(totalSurfStakedKey), 0)
602602 if (if ((totalSurfStaked == 0))
603603 then if (if ((wavesRewardAmountForPeriod != 0))
604604 then true
605605 else (wxRewardAmountForPeriod != 0))
606606 then true
607607 else (xtnRewardAmountForPeriod != 0)
608608 else false)
609609 then {
610610 let newDevsWavesAmountAtContract = (getIntegerValue(devsWavesAmountKey) + wavesRewardAmountForPeriod)
611611 let newDevsWxAmountAtContract = (getIntegerValue(devsWxAmountKey) + wxRewardAmountForPeriod)
612612 let newDevsXtnAmountAtContract = (getIntegerValue(devsXtnAmountKey) + xtnRewardAmountForPeriod)
613613 [IntegerEntry(keyCurrentSurfStakingRewardPeriodWavesAmountForOneSurf(currentSurfStakingRewardsPeriodId), 0), IntegerEntry(keyCurrentSurfStakingRewardPeriodWxAmountForOneSurf(currentSurfStakingRewardsPeriodId), 0), IntegerEntry(keyCurrentSurfStakingRewardPeriodXtnAmountForOneSurf(currentSurfStakingRewardsPeriodId), 0), IntegerEntry(currentSurfStakingRewardsPeriodIdKey, (currentSurfStakingRewardsPeriodId + 1)), IntegerEntry(devsWavesAmountKey, newDevsWavesAmountAtContract), IntegerEntry(devsWxAmountKey, newDevsWxAmountAtContract), IntegerEntry(devsXtnAmountKey, newDevsXtnAmountAtContract)]
614614 }
615615 else if ((totalSurfStaked == 0))
616616 then nil
617617 else {
618618 let wavesRewardPerOneSurfForPeriod = if ((wavesRewardAmountForPeriod == 0))
619619 then 0
620620 else fraction(wavesRewardAmountForPeriod, MULT6, totalSurfStaked, HALFUP)
621621 let wxRewardPerOneSurfForPeriod = if ((wxRewardAmountForPeriod == 0))
622622 then 0
623623 else fraction(wxRewardAmountForPeriod, MULT6, totalSurfStaked, HALFUP)
624624 let xtnRewardPerOneSurfForPeriod = if ((xtnRewardAmountForPeriod == 0))
625625 then 0
626626 else fraction(xtnRewardAmountForPeriod, MULT6, totalSurfStaked, HALFUP)
627627 [IntegerEntry(keyCurrentSurfStakingRewardPeriodWavesAmountForOneSurf(currentSurfStakingRewardsPeriodId), wavesRewardPerOneSurfForPeriod), IntegerEntry(keyCurrentSurfStakingRewardPeriodWxAmountForOneSurf(currentSurfStakingRewardsPeriodId), wxRewardPerOneSurfForPeriod), IntegerEntry(keyCurrentSurfStakingRewardPeriodXtnAmountForOneSurf(currentSurfStakingRewardsPeriodId), xtnRewardPerOneSurfForPeriod), IntegerEntry(currentSurfStakingRewardsPeriodIdKey, (currentSurfStakingRewardsPeriodId + 1))]
628628 }
629629 }
630630 else throw("Strict value is not equal to itself.")
631631 }
632632 else throw("Strict value is not equal to itself.")
633633 }
634634 else throw("Strict value is not equal to itself.")
635635 }
636636 else throw("Strict value is not equal to itself.")
637637 }
638638
639639
640640 @Verifier(tx)
641641 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
642642

github/deemru/w8io/6500d08 
61.95 ms