tx · GW7DhJdLwpgt8eyMYJAMF61S6qM4ZJTxkEmZFxbsCN5R

3N9GCiuQ6yRx1nb4YGSj3W7KYSJUNrw7dZf:  -0.03100000 Waves

2023.02.22 14:59 [2460825] smart account 3N9GCiuQ6yRx1nb4YGSj3W7KYSJUNrw7dZf > SELF 0.00000000 Waves

{ "type": 13, "id": "GW7DhJdLwpgt8eyMYJAMF61S6qM4ZJTxkEmZFxbsCN5R", "fee": 3100000, "feeAssetId": null, "timestamp": 1677067186107, "version": 1, "sender": "3N9GCiuQ6yRx1nb4YGSj3W7KYSJUNrw7dZf", "senderPublicKey": "HWNh3pPUeb27hjqQcsyEmytEmj122ru2SaDrMsquiiiz", "proofs": [ "nZaobgiMPs2Xis3B9QV818WoB5PhLxVwxkFXzTTwhm8PPSiRqATLNKwkQeo82XuDV7jbpq5taEHtt5VL1C1o2ba" ], "script": "base64:BgJCCAISCAoGCAgBAQEIEgUKAwEIAhIDCgEBEgMKAQESBAoCCAgSBAoCCAgSAwoBCBIDCgEIEgQKAggBEgASAwoBCBIAbgADU0VQAgJfXwAGU0NBTEU4AAgABU1VTFQ4AIDC1y8ADlBPT0xXRUlHSFRNVUxUBQVNVUxUOAEEc3RyZgIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4FA2tleQIPIGlzIG5vdCBkZWZpbmVkAQNpb3oCB2FkZHJlc3MDa2V5CQELdmFsdWVPckVsc2UCCQCaCAIFB2FkZHJlc3MFA2tleQAAAQNpb2QDB2FkZHJlc3MDa2V5CmRlZmF1bHRWYWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUHYWRkcmVzcwUDa2V5BQpkZWZhdWx0VmFsAQNpb2YCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUHYWRkcmVzcwUDa2V5CQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQNrZXkCDyBpcyBub3QgZGVmaW5lZAEDYWJzAQN2YWwDCQBmAgAABQN2YWwJAQEtAQUDdmFsBQN2YWwBA2FhbAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIJTGlzdFtBbnldBAp2YWxBbnlMeXN0BQckbWF0Y2gwBQp2YWxBbnlMeXN0CQACAQIbZmFpbCB0byBjYXN0IGludG8gTGlzdFtBbnldAQJhaQEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEba2V5UmVmZXJyYWxzQ29udHJhY3RBZGRyZXNzAAkAuQkCCQDMCAICBCVzJXMJAMwIAgIGY29uZmlnCQDMCAICGHJlZmVycmFsc0NvbnRyYWN0QWRkcmVzcwUDbmlsBQNTRVAAHnJlZmVycmFsc0NvbnRyYWN0QWRkcmVzc09yRmFpbAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBBHN0cmYCBQR0aGlzCQEba2V5UmVmZXJyYWxzQ29udHJhY3RBZGRyZXNzAAAWa2V5UmVmZXJyYWxQcm9ncmFtTmFtZQkAuQkCCQDMCAICBCVzJXMJAMwIAgIIcmVmZXJyYWwJAMwIAgILcHJvZ3JhbU5hbWUFA25pbAUDU0VQABpyZWZlcnJhbFByb2dyYW1OYW1lRGVmYXVsdAIGd3hsb2NrABNyZWZlcnJhbFByb2dyYW1OYW1lCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFFmtleVJlZmVycmFsUHJvZ3JhbU5hbWUFGnJlZmVycmFsUHJvZ3JhbU5hbWVEZWZhdWx0ARFrZXlGYWN0b3J5QWRkcmVzcwACHCVzJXNfX2NvbmZpZ19fZmFjdG9yeUFkZHJlc3MAGElkeEZhY3RvcnlDZmdTdGFraW5nRGFwcAABABlJZHhGYWN0b3J5Q2ZnQm9vc3RpbmdEYXBwAAIAFElkeEZhY3RvcnlDZmdJZG9EYXBwAAMAFUlkeEZhY3RvcnlDZmdUZWFtRGFwcAAEABlJZHhGYWN0b3J5Q2ZnRW1pc3Npb25EYXBwAAUAFUlkeEZhY3RvcnlDZmdSZXN0RGFwcAAGABlJZHhGYWN0b3J5Q2ZnU2xpcHBhZ2VEYXBwAAcAFElkeEZhY3RvcnlDZmdEYW9EYXBwAAgAGklkeEZhY3RvcnlDZmdNYXJrZXRpbmdEYXBwAAkAGklkeEZhY3RvcnlDZmdHd3hSZXdhcmREYXBwAAoAFklkeEZhY3RvcnlDZmdCaXJkc0RhcHAACwENa2V5RmFjdG9yeUNmZwACESVzX19mYWN0b3J5Q29uZmlnARprZXlGYWN0b3J5THAyQXNzZXRzTWFwcGluZwEKbHBBc3NldFN0cgkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQpscEFzc2V0U3RyCQDMCAICHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUDbmlsBQNTRVABEGtleUZhY3RvcnlMcExpc3QAAhAlc19fbHBUb2tlbnNMaXN0ASZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcwEKbHBBc3NldFN0cgkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQpscEFzc2V0U3RyCQDMCAICHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUDbmlsBQNTRVABFGtleUZhY3RvcnlQb29sV2VpZ2h0AQ9jb250cmFjdEFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAICCnBvb2xXZWlnaHQJAMwIAgUPY29udHJhY3RBZGRyZXNzBQNuaWwFA1NFUAEba2V5RmFjdG9yeVBvb2xXZWlnaHRIaXN0b3J5Agtwb29sQWRkcmVzcwNudW0JAKwCAgkArAICCQCsAgICEiVzJXNfX3Bvb2xXZWlnaHRfXwULcG9vbEFkZHJlc3MCAl9fCQCkAwEFA251bQEYcmVhZEZhY3RvcnlBZGRyZXNzT3JGYWlsAAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBBHN0cmYCBQR0aGlzCQERa2V5RmFjdG9yeUFkZHJlc3MAAQpyZWFkTHBMaXN0AAkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIJARhyZWFkRmFjdG9yeUFkZHJlc3NPckZhaWwACQEQa2V5RmFjdG9yeUxwTGlzdAACAAUDU0VQARRyZWFkRmFjdG9yeUNmZ09yRmFpbAEHZmFjdG9yeQkAtQkCCQEEc3RyZgIFB2ZhY3RvcnkJAQ1rZXlGYWN0b3J5Q2ZnAAUDU0VQARhnZXRCb29zdGluZ0FkZHJlc3NPckZhaWwBCmZhY3RvcnlDZmcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUKZmFjdG9yeUNmZwUZSWR4RmFjdG9yeUNmZ0Jvb3N0aW5nRGFwcAEYZ2V0RW1pc3Npb25BZGRyZXNzT3JGYWlsAQpmYWN0b3J5Q2ZnCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFCmZhY3RvcnlDZmcFGUlkeEZhY3RvcnlDZmdFbWlzc2lvbkRhcHABF2dldFN0YWtpbmdBZGRyZXNzT3JGYWlsAQpmYWN0b3J5Q2ZnCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFCmZhY3RvcnlDZmcFGElkeEZhY3RvcnlDZmdTdGFraW5nRGFwcAEZZ2V0R3d4UmV3YXJkQWRkcmVzc09yRmFpbAEKZmFjdG9yeUNmZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQpmYWN0b3J5Q2ZnBRpJZHhGYWN0b3J5Q2ZnR3d4UmV3YXJkRGFwcAETa2V5TWFuYWdlclB1YmxpY0tleQACFCVzX19tYW5hZ2VyUHVibGljS2V5ARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQEea2V5RW1pc3Npb25SYXRlUGVyQmxvY2tDdXJyZW50AAIbJXMlc19fcmF0ZVBlckJsb2NrX19jdXJyZW50ASFrZXlFbWlzc2lvblJhdGVQZXJCbG9ja01heEN1cnJlbnQAAh4lcyVzX19yYXRlUGVyQmxvY2tNYXhfX2N1cnJlbnQBFWtleUVtaXNzaW9uU3RhcnRCbG9jawACGiVzJXNfX2VtaXNzaW9uX19zdGFydEJsb2NrARtrZXlFbWlzc2lvbkR1cmF0aW9uSW5CbG9ja3MAAhglcyVzX19lbWlzc2lvbl9fZHVyYXRpb24BE2tleUVtaXNzaW9uRW5kQmxvY2sAAhglcyVzX19lbWlzc2lvbl9fZW5kQmxvY2sBDWtleU5leHRQZXJpb2QAAg4lc19fbmV4dFBlcmlvZAEfa2V5R3d4UmV3YXJkRW1pc3Npb25TdGFydEhlaWdodAACKCVzJXNfX2d3eFJld2FyZEVtaXNzaW9uUGFydF9fc3RhcnRIZWlnaHQADUlkeENmZ0Fzc2V0SWQAAQATSWR4Q2ZnTWluTG9ja0Ftb3VudAACABVJZHhDZmdNaW5Mb2NrRHVyYXRpb24AAwAVSWR4Q2ZnTWF4TG9ja0R1cmF0aW9uAAQAEklkeENmZ01hdGhDb250cmFjdAAFAQlrZXlDb25maWcAAgolc19fY29uZmlnARVyZWFkQ29uZmlnQXJyYXlPckZhaWwACQC1CQIJAQRzdHJmAgUEdGhpcwkBCWtleUNvbmZpZwAFA1NFUAAMbWF0aENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIJARVyZWFkQ29uZmlnQXJyYXlPckZhaWwABRJJZHhDZmdNYXRoQ29udHJhY3QBDWZvcm1hdENvbmZpZ1MFB2Fzc2V0SWQNbWluTG9ja0Ftb3VudA9taW5Mb2NrRHVyYXRpb24PbWF4TG9ja0R1cmF0aW9uDG1hdGhDb250cmFjdAkAuQkCCQDMCAICCCVzJWQlZCVkCQDMCAIFB2Fzc2V0SWQJAMwIAgUNbWluTG9ja0Ftb3VudAkAzAgCBQ9taW5Mb2NrRHVyYXRpb24JAMwIAgUPbWF4TG9ja0R1cmF0aW9uCQDMCAIFDG1hdGhDb250cmFjdAUDbmlsBQNTRVABDGZvcm1hdENvbmZpZwUHYXNzZXRJZA1taW5Mb2NrQW1vdW50D21pbkxvY2tEdXJhdGlvbg9tYXhMb2NrRHVyYXRpb24MbWF0aENvbnRyYWN0CQENZm9ybWF0Q29uZmlnUwUFB2Fzc2V0SWQJAKQDAQUNbWluTG9ja0Ftb3VudAkApAMBBQ9taW5Mb2NrRHVyYXRpb24JAKQDAQUPbWF4TG9ja0R1cmF0aW9uBQxtYXRoQ29udHJhY3QBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQABAckbWF0Y2gwCQCiCAEJARNrZXlNYW5hZ2VyUHVibGljS2V5AAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJANkEAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0AAQHJG1hdGNoMAkAoggBCQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgELbXVzdE1hbmFnZXIBAWkEAnBkCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEByRtYXRjaDAJARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAMJAAACCAUBaQ9jYWxsZXJQdWJsaWNLZXkFAnBrBgUCcGQDCQABAgUHJG1hdGNoMAIEVW5pdAMJAAACCAUBaQZjYWxsZXIFBHRoaXMGBQJwZAkAAgECC01hdGNoIGVycm9yAA5JZHhMb2NrVXNlck51bQABAA1JZHhMb2NrQW1vdW50AAIADElkeExvY2tTdGFydAADAA9JZHhMb2NrRHVyYXRpb24ABAANSWR4TG9ja1BhcmFtSwAFAA1JZHhMb2NrUGFyYW1CAAYBE2tleUxvY2tQYXJhbXNSZWNvcmQBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIKJXMlc19fbG9jawkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsAQt1c2VyQWRkcmVzcwkAtQkCCQEEc3RyZgIFBHRoaXMJARNrZXlMb2NrUGFyYW1zUmVjb3JkAQULdXNlckFkZHJlc3MFA1NFUAEXZm9ybWF0TG9ja1BhcmFtc1JlY29yZFMIB3VzZXJOdW0GYW1vdW50BXN0YXJ0CGR1cmF0aW9uBnBhcmFtSwZwYXJhbUIQbGFzdFVwZFRpbWVzdGFtcAlnd3hBbW91bnQJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIFB3VzZXJOdW0JAMwIAgUGYW1vdW50CQDMCAIFBXN0YXJ0CQDMCAIFCGR1cmF0aW9uCQDMCAIFBnBhcmFtSwkAzAgCBQZwYXJhbUIJAMwIAgUQbGFzdFVwZFRpbWVzdGFtcAkAzAgCBQlnd3hBbW91bnQFA25pbAUDU0VQARZmb3JtYXRMb2NrUGFyYW1zUmVjb3JkBwd1c2VyTnVtBmFtb3VudAVzdGFydAhkdXJhdGlvbgZwYXJhbUsGcGFyYW1CCWd3eEFtb3VudAkBF2Zvcm1hdExvY2tQYXJhbXNSZWNvcmRTCAUHdXNlck51bQkApAMBBQZhbW91bnQJAKQDAQUFc3RhcnQJAKQDAQUIZHVyYXRpb24JAKQDAQUGcGFyYW1LCQCkAwEFBnBhcmFtQgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkApAMBBQlnd3hBbW91bnQBDmtleU5leHRVc2VyTnVtAAIPJXNfX25leHRVc2VyTnVtARJrZXlVc2VyMk51bU1hcHBpbmcBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIZJXMlcyVzX19tYXBwaW5nX191c2VyMm51bQkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABEmtleU51bTJVc2VyTWFwcGluZwEDbnVtCQC5CQIJAMwIAgIZJXMlcyVzX19tYXBwaW5nX19udW0ydXNlcgkAzAgCBQNudW0FA25pbAUDU0VQARZrZXlMb2NrUGFyYW1Vc2VyQW1vdW50AQd1c2VyTnVtCQC5CQIJAMwIAgIWJXMlZCVzX19wYXJhbUJ5VXNlck51bQkAzAgCBQd1c2VyTnVtCQDMCAICBmFtb3VudAUDbmlsBQNTRVABFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sBB3VzZXJOdW0JALkJAgkAzAgCAhYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQDMCAIFB3VzZXJOdW0JAMwIAgIFc3RhcnQFA25pbAUDU0VQARRrZXlMb2NrUGFyYW1EdXJhdGlvbgEHdXNlck51bQkAuQkCCQDMCAICFiVzJWQlc19fcGFyYW1CeVVzZXJOdW0JAMwIAgUHdXNlck51bQkAzAgCAghkdXJhdGlvbgUDbmlsBQNTRVABDWtleUxvY2tQYXJhbUsBB3VzZXJOdW0JALkJAgkAzAgCAhYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQDMCAIFB3VzZXJOdW0JAMwIAgIBawUDbmlsBQNTRVABDWtleUxvY2tQYXJhbUIBB3VzZXJOdW0JALkJAgkAzAgCAhYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQDMCAIFB3VzZXJOdW0JAMwIAgIBYgUDbmlsBQNTRVABFWtleUxvY2tQYXJhbUJ5UGVyaW9kSwIHdXNlck51bQZwZXJpb2QJALkJAgkAzAgCAhclcyVkJXMlZF9fcGFyYW1CeVBlcmlvZAkAzAgCBQd1c2VyTnVtCQDMCAICAWsJAMwIAgUGcGVyaW9kBQNuaWwFA1NFUAEVa2V5TG9ja1BhcmFtQnlQZXJpb2RCAgd1c2VyTnVtBnBlcmlvZAkAuQkCCQDMCAICFyVzJWQlcyVkX19wYXJhbUJ5UGVyaW9kCQDMCAIFB3VzZXJOdW0JAMwIAgIBYgkAzAgCBQZwZXJpb2QFA25pbAUDU0VQARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAACHiVzJXNfX3N0YXRzX19hY3RpdmVUb3RhbExvY2tlZAEga2V5U3RhdHNMb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MAAiUlcyVzX19zdGF0c19fbG9ja3NEdXJhdGlvblN1bUluQmxvY2tzARJrZXlTdGF0c0xvY2tzQ291bnQAAhclcyVzX19zdGF0c19fbG9ja3NDb3VudAESa2V5U3RhdHNVc2Vyc0NvdW50AAIdJXMlc19fc3RhdHNfX2FjdGl2ZVVzZXJzQ291bnQBIGtleVVzZXJCb29zdEVtaXNzaW9uTGFzdElOVEVHUkFMAQd1c2VyTnVtCQC5CQIJAMwIAgIeJXMlZF9fdXNlckJvb3N0RW1pc3Npb25MYXN0SW50CQDMCAIFB3VzZXJOdW0FA25pbAUDU0VQASJrZXlVc2VyTHBCb29zdEVtaXNzaW9uTGFzdElOVEVHUkFMAgd1c2VyTnVtCWxwQXNzZXRJZAkAuQkCCQDMCAICHiVzJWRfX3VzZXJCb29zdEVtaXNzaW9uTGFzdEludAkAzAgCBQd1c2VyTnVtCQDMCAIFCWxwQXNzZXRJZAUDbmlsBQNTRVABF2tleVVzZXJNYXhCb29zdElOVEVHUkFMAQd1c2VyTnVtCQC5CQIJAMwIAgIRJXMlZF9fbWF4Qm9vc3RJbnQJAMwIAgUHdXNlck51bQUDbmlsBQNTRVABGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAACGCVzJXNfX21heEJvb3N0SW50X190b3RhbAEha2V5VXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsAQd1c2VyTnVtCQC5CQIJAMwIAgIkJXMlZF9fdXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsCQDMCAIFB3VzZXJOdW0FA25pbAUDU0VQARNrZXlVc2VyQm9vc3RDbGFpbWVkAQd1c2VyTnVtCQC5CQIJAMwIAgIWJXMlZF9fdXNlckJvb3N0Q2xhaW1lZAkAzAgCBQd1c2VyTnVtBQNuaWwFA1NFUAERa2V5VG90YWxDYWNoZWRHd3gAAhYlcyVzX19nd3hDYWNoZWRfX3RvdGFsARtrZXlUb3RhbENhY2hlZEd3eENvcnJlY3RpdmUAAhwlc19fZ3d4Q2FjaGVkVG90YWxDb3JyZWN0aXZlAA9mYWN0b3J5Q29udHJhY3QJARhyZWFkRmFjdG9yeUFkZHJlc3NPckZhaWwAAApmYWN0b3J5Q2ZnCQEUcmVhZEZhY3RvcnlDZmdPckZhaWwBBQ9mYWN0b3J5Q29udHJhY3QAEGVtaXNzaW9uQ29udHJhY3QJARhnZXRFbWlzc2lvbkFkZHJlc3NPckZhaWwBBQpmYWN0b3J5Q2ZnAA9zdGFraW5nQ29udHJhY3QJARdnZXRTdGFraW5nQWRkcmVzc09yRmFpbAEFCmZhY3RvcnlDZmcAEWd3eFJld2FyZENvbnRyYWN0CQEZZ2V0R3d4UmV3YXJkQWRkcmVzc09yRmFpbAEFCmZhY3RvcnlDZmcBEWdldFRvdGFsQ2FjaGVkR3d4AQdjb3JyZWN0BBlrZXlWb3RpbmdFbWlzc2lvbkNvbnRyYWN0CQC5CQIJAMwIAgICJXMJAMwIAgIWdm90aW5nRW1pc3Npb25Db250cmFjdAUDbmlsBQNTRVAEFnZvdGluZ0VtaXNzaW9uQ29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJARFAZXh0ck5hdGl2ZSgxMDUzKQIFD2ZhY3RvcnlDb250cmFjdAUZa2V5Vm90aW5nRW1pc3Npb25Db250cmFjdAQRa2V5Q3VycmVudEVwb2NoVWkJALkJAgkAzAgCAgIlcwkAzAgCAg5jdXJyZW50RXBvY2hVaQUDbmlsBQNTRVAEDmN1cnJlbnRFcG9jaFVpCQERQGV4dHJOYXRpdmUoMTA1MCkCBRZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0BRFrZXlDdXJyZW50RXBvY2hVaQQOa2V5VGFyZ2V0RXBvY2gJALkJAgkAzAgCAgQlcyVzCQDMCAICKXRvdGFsQ2FjaGVkR3d4Q29ycmVjdGlvbl9fYWN0aXZhdGlvbkVwb2NoBQNuaWwFA1NFUAQRdGFyZ2V0RXBvY2hPcHRpb24JAJoIAgUEdGhpcwUOa2V5VGFyZ2V0RXBvY2gEEXRvdGFsQ2FjaGVkR3d4UmF3CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJARFrZXlUb3RhbENhY2hlZEd3eAAAAAQVaXNDb3JyZWN0aW9uQWN0aXZhdGVkAwkBCWlzRGVmaW5lZAEFEXRhcmdldEVwb2NoT3B0aW9uCQBnAgUOY3VycmVudEVwb2NoVWkJAQV2YWx1ZQEFEXRhcmdldEVwb2NoT3B0aW9uBwQKY29ycmVjdGl2ZQMDBRVpc0NvcnJlY3Rpb25BY3RpdmF0ZWQFB2NvcnJlY3QHCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJARtrZXlUb3RhbENhY2hlZEd3eENvcnJlY3RpdmUAAAAAAAkAlgMBCQDMCAIAAAkAzAgCCQBkAgURdG90YWxDYWNoZWRHd3hSYXcFCmNvcnJlY3RpdmUFA25pbAEMSGlzdG9yeUVudHJ5CAR0eXBlBHVzZXIGYW1vdW50CWxvY2tTdGFydAhkdXJhdGlvbgFrAWIBaQQKaGlzdG9yeUtFWQkAuQkCCQDMCAICESVzJXMlcyVzX19oaXN0b3J5CQDMCAIFBHR5cGUJAMwIAgUEdXNlcgkAzAgCCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQFA25pbAUDU0VQBAtoaXN0b3J5REFUQQkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQgFCWxhc3RCbG9jawZoZWlnaHQJAMwIAgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQCkAwEFBmFtb3VudAkAzAgCCQCkAwEFCWxvY2tTdGFydAkAzAgCCQCkAwEFCGR1cmF0aW9uCQDMCAIJAKQDAQUBawkAzAgCCQCkAwEFAWIFA25pbAUDU0VQCQELU3RyaW5nRW50cnkCBQpoaXN0b3J5S0VZBQtoaXN0b3J5REFUQQEKU3RhdHNFbnRyeQQOdG90YWxMb2NrZWRJbmMLZHVyYXRpb25JbmMMbG9ja0NvdW50SW5jDXVzZXJzQ291bnRJbmMEG2xvY2tzRHVyYXRpb25TdW1JbkJsb2Nrc0tFWQkBIGtleVN0YXRzTG9ja3NEdXJhdGlvblN1bUluQmxvY2tzAAQNbG9ja3NDb3VudEtFWQkBEmtleVN0YXRzTG9ja3NDb3VudAAEDXVzZXJzQ291bnRLRVkJARJrZXlTdGF0c1VzZXJzQ291bnQABA50b3RhbEFtb3VudEtFWQkBF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAQYbG9ja3NEdXJhdGlvblN1bUluQmxvY2tzCQEDaW96AgUEdGhpcwUbbG9ja3NEdXJhdGlvblN1bUluQmxvY2tzS0VZBApsb2Nrc0NvdW50CQEDaW96AgUEdGhpcwUNbG9ja3NDb3VudEtFWQQKdXNlcnNDb3VudAkBA2lvegIFBHRoaXMFDXVzZXJzQ291bnRLRVkEC3RvdGFsQW1vdW50CQEDaW96AgUEdGhpcwUOdG90YWxBbW91bnRLRVkJAMwIAgkBDEludGVnZXJFbnRyeQIFG2xvY2tzRHVyYXRpb25TdW1JbkJsb2Nrc0tFWQkAZAIFGGxvY2tzRHVyYXRpb25TdW1JbkJsb2NrcwULZHVyYXRpb25JbmMJAMwIAgkBDEludGVnZXJFbnRyeQIFDWxvY2tzQ291bnRLRVkJAGQCBQpsb2Nrc0NvdW50BQxsb2NrQ291bnRJbmMJAMwIAgkBDEludGVnZXJFbnRyeQIFDXVzZXJzQ291bnRLRVkJAGQCBQp1c2Vyc0NvdW50BQ11c2Vyc0NvdW50SW5jCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ50b3RhbEFtb3VudEtFWQkAZAIFC3RvdGFsQW1vdW50BQ50b3RhbExvY2tlZEluYwUDbmlsAQ1jYWxjR3d4QW1vdW50AwRrUmF3BGJSYXcBaAQFU0NBTEUA6AcJAGkCCQBkAgkAaAIFBGtSYXcFAWgFBGJSYXcFBVNDQUxFAQ9Mb2NrUGFyYW1zRW50cnkIC3VzZXJBZGRyZXNzB3VzZXJOdW0GYW1vdW50BXN0YXJ0CGR1cmF0aW9uAWsBYgZwZXJpb2QEDXVzZXJBbW91bnRLRVkJARZrZXlMb2NrUGFyYW1Vc2VyQW1vdW50AQUHdXNlck51bQQNc3RhcnRCbG9ja0tFWQkBFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sBBQd1c2VyTnVtBAtkdXJhdGlvbktFWQkBFGtleUxvY2tQYXJhbUR1cmF0aW9uAQUHdXNlck51bQQEa0tFWQkBDWtleUxvY2tQYXJhbUsBBQd1c2VyTnVtBARiS0VZCQENa2V5TG9ja1BhcmFtQgEFB3VzZXJOdW0EDGtCeVBlcmlvZEtFWQkBFWtleUxvY2tQYXJhbUJ5UGVyaW9kSwIFB3VzZXJOdW0FBnBlcmlvZAQMYkJ5UGVyaW9kS0VZCQEVa2V5TG9ja1BhcmFtQnlQZXJpb2RCAgUHdXNlck51bQUGcGVyaW9kBAlnd3hBbW91bnQJAQ1jYWxjR3d4QW1vdW50AwUBawUBYgUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ11c2VyQW1vdW50S0VZBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFDXN0YXJ0QmxvY2tLRVkFBXN0YXJ0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQtkdXJhdGlvbktFWQUIZHVyYXRpb24JAMwIAgkBDEludGVnZXJFbnRyeQIFBGtLRVkFAWsJAMwIAgkBDEludGVnZXJFbnRyeQIFBGJLRVkFAWIJAMwIAgkBDEludGVnZXJFbnRyeQIFDGtCeVBlcmlvZEtFWQUBawkAzAgCCQEMSW50ZWdlckVudHJ5AgUMYkJ5UGVyaW9kS0VZBQFiCQDMCAIJAQtTdHJpbmdFbnRyeQIJARNrZXlMb2NrUGFyYW1zUmVjb3JkAQULdXNlckFkZHJlc3MJARZmb3JtYXRMb2NrUGFyYW1zUmVjb3JkBwUHdXNlck51bQUGYW1vdW50BQVzdGFydAUIZHVyYXRpb24FAWsFAWIFCWd3eEFtb3VudAUDbmlsASJleHRyYWN0T3B0aW9uYWxQYXltZW50QW1vdW50T3JGYWlsAgFpD2V4cGVjdGVkQXNzZXRJZAMJAGYCCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhtvbmx5IG9uZSBwYXltZW50IGlzIGFsbG93ZWQDCQAAAgkAkAMBCAUBaQhwYXltZW50cwAAAAAEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkBQ9leHBlY3RlZEFzc2V0SWQJAAIBAhtpbnZhbGlkIGFzc2V0IGlkIGluIHBheW1lbnQIBQNwbXQGYW1vdW50ARljYWxjVXNlckd3eEFtb3VudEF0SGVpZ2h0Agt1c2VyQWRkcmVzcwx0YXJnZXRIZWlnaHQEBUVNUFRZAgVlbXB0eQQSdXNlcjJOdW1NYXBwaW5nS0VZCQESa2V5VXNlcjJOdW1NYXBwaW5nAQULdXNlckFkZHJlc3MEB3VzZXJOdW0JAQt2YWx1ZU9yRWxzZQIJAKIIAQUSdXNlcjJOdW1NYXBwaW5nS0VZBQVFTVBUWQQBawkBC3ZhbHVlT3JFbHNlAgkAnwgBCQENa2V5TG9ja1BhcmFtSwEFB3VzZXJOdW0AAAQBYgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQENa2V5TG9ja1BhcmFtQgEFB3VzZXJOdW0AAAQNZ3d4QW1vdW50Q2FsYwkBDWNhbGNHd3hBbW91bnQDBQFrBQFiBQx0YXJnZXRIZWlnaHQECWd3eEFtb3VudAMJAGYCAAAFDWd3eEFtb3VudENhbGMAAAUNZ3d4QW1vdW50Q2FsYwUJZ3d4QW1vdW50ARRjYWxjQ3VycmVudEd3eEFtb3VudAELdXNlckFkZHJlc3MJARljYWxjVXNlckd3eEFtb3VudEF0SGVpZ2h0AgULdXNlckFkZHJlc3MFBmhlaWdodAEUaW50ZXJuYWxDbGFpbVd4Qm9vc3QDDGxwQXNzZXRJZFN0cg51c2VyQWRkcmVzc1N0cghyZWFkT25seQQFRU1QVFkCBUVNUFRZBBF1c2VyUmVjb3JkT3JFbXB0eQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQETa2V5TG9ja1BhcmFtc1JlY29yZAEFDnVzZXJBZGRyZXNzU3RyBQVFTVBUWQMJAAACBRF1c2VyUmVjb3JkT3JFbXB0eQUFRU1QVFkJAJUKAwAABQNuaWwCFXVzZXJSZWNvcmQ6OmlzOjplbXB0eQQPdXNlclJlY29yZEFycmF5CQC1CQIFEXVzZXJSZWNvcmRPckVtcHR5BQNTRVAECnVzZXJOdW1TdHIJAJEDAgUPdXNlclJlY29yZEFycmF5BQ5JZHhMb2NrVXNlck51bQQcZ3d4UmV3YXJkRW1pc3Npb25TdGFydEhlaWdodAkBC3ZhbHVlT3JFbHNlAgkAmggCBRFnd3hSZXdhcmRDb250cmFjdAkBH2tleUd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQAAAAECEVNUFRZU1RSAgVlbXB0eQQNJHQwMTUzMDYxNTg4NAMJAQIhPQIFDGxwQXNzZXRJZFN0cgUIRU1QVFlTVFIEDnBvb2xBZGRyZXNzU3RyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPZmFjdG9yeUNvbnRyYWN0CQEaa2V5RmFjdG9yeUxwMkFzc2V0c01hcHBpbmcBBQxscEFzc2V0SWRTdHIJAKwCAgIVdW5zdXBwb3J0ZWQgbHAgYXNzZXQgBQxscEFzc2V0SWRTdHIEA3B3MQkBEUBleHRyTmF0aXZlKDEwNTApAgUPZmFjdG9yeUNvbnRyYWN0CQEUa2V5RmFjdG9yeVBvb2xXZWlnaHQBBQ5wb29sQWRkcmVzc1N0cgQDcHcwCQELdmFsdWVPckVsc2UCCQCaCAIFD2ZhY3RvcnlDb250cmFjdAkBG2tleUZhY3RvcnlQb29sV2VpZ2h0SGlzdG9yeQIFDnBvb2xBZGRyZXNzU3RyAAAFA3B3MQkAlAoCBQNwdzAFA3B3MQMFCHJlYWRPbmx5CQCUCgIAAAAACQACAQkArAICAihub3QgcmVhZG9ubHkgbW9kZTogdW5zdXBwb3J0ZWQgbHAgYXNzZXQgBQxscEFzc2V0SWRTdHIEC3Bvb2xXZWlnaHQwCAUNJHQwMTUzMDYxNTg4NAJfMQQLcG9vbFdlaWdodDEIBQ0kdDAxNTMwNjE1ODg0Al8yBBJ3eEVtaXNzaW9uUGVyQmxvY2sJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQEea2V5RW1pc3Npb25SYXRlUGVyQmxvY2tDdXJyZW50AAQNZW1pc3Npb25TdGFydAkBA2lvZgIFEGVtaXNzaW9uQ29udHJhY3QJARVrZXlFbWlzc2lvblN0YXJ0QmxvY2sABAtlbWlzc2lvbkVuZAkBA2lvZgIFEGVtaXNzaW9uQ29udHJhY3QJARNrZXlFbWlzc2lvbkVuZEJsb2NrAAQBaAMJAGYCBQZoZWlnaHQFC2VtaXNzaW9uRW5kBQtlbWlzc2lvbkVuZAUGaGVpZ2h0BAJkaAkAlgMBCQDMCAIJAGUCBQFoBQ1lbWlzc2lvblN0YXJ0CQDMCAIAAAUDbmlsBCJ1c2VyTHBCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZCQEia2V5VXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAIFCnVzZXJOdW1TdHIFDGxwQXNzZXRJZFN0cgQgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJASBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAEFCnVzZXJOdW1TdHIEHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFInVzZXJMcEJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJAQNpb3oCBQR0aGlzBSB1c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQQVYm9vc3RFbWlzc2lvbkludGVncmFsCQBpAgkAaAIJAGgCBRJ3eEVtaXNzaW9uUGVyQmxvY2sFAmRoAAIAAwQZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAZQIFFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAUddXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWwEA3VkaAkAawMFGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwAAwkAaAIAAgUSd3hFbWlzc2lvblBlckJsb2NrBAZ1TGFzdEgJAGUCBQFoBQN1ZGgEBHVkaDAJAJYDAQkAzAgCCQBlAgUcZ3d4UmV3YXJkRW1pc3Npb25TdGFydEhlaWdodAUGdUxhc3RICQDMCAIAAAUDbmlsBAR1ZGgxCQBlAgkAZQIFAWgFBnVMYXN0SAUEdWRoMAMDAwkAZgIAAAUGdUxhc3RIBgkAZgIAAAUEdWRoMQYJAGcCCQEDYWJzAQkAZQIJAGQCBQR1ZGgwBQR1ZGgxBQN1ZGgAAQkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIWaW52YWxpZCB1ZGggY2FsYzogdWRoPQkApAMBBQN1ZGgCCCB1TGFzdEg9CQCkAwEFBnVMYXN0SAIGIHVkaDA9CQCkAwEFBHVkaDACBiB1ZGgxPQkApAMBBQR1ZGgxAwkAZgIAAAUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAAgECEndyb25nIGNhbGN1bGF0aW9ucwQXdXNlck1heEJvb3N0SW50ZWdyYWxLRVkJARdrZXlVc2VyTWF4Qm9vc3RJTlRFR1JBTAEFCnVzZXJOdW1TdHIEGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQkBGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAAED3VzZXJNYXhCb29zdEludAkBA2lvegIFBHRoaXMFF3VzZXJNYXhCb29zdEludGVncmFsS0VZBBB0b3RhbE1heEJvb3N0SW50CQEDaW96AgUEdGhpcwUYdG90YWxNYXhCb29zdEludGVncmFsS0VZBBd0b3RhbENhY2hlZEd3eENvcnJlY3RlZAkBEWdldFRvdGFsQ2FjaGVkR3d4AQYEC3VzZXJDdXJyR3d4CQEUY2FsY0N1cnJlbnRHd3hBbW91bnQBBQ51c2VyQWRkcmVzc1N0cgQhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZCQEha2V5VXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsAQUKdXNlck51bVN0cgQedXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsCQEDaW96AgUEdGhpcwUhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZBBp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMAMJAAACBQN1ZGgAAAAACQBrAwUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAUEdWRoMAUDdWRoBBp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMQMJAAACBQN1ZGgAAAAACQBrAwUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAUEdWRoMQUDdWRoBB5wb29sVXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbDAJAGsDBRp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMAULcG9vbFdlaWdodDAFDlBPT0xXRUlHSFRNVUxUBB5wb29sVXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbDEJAGsDBRp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMQULcG9vbFdlaWdodDEFDlBPT0xXRUlHSFRNVUxUBCJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcwAwkAAAIFF3RvdGFsQ2FjaGVkR3d4Q29ycmVjdGVkAAAAAAkAawMFHnBvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsMAULdXNlckN1cnJHd3gFF3RvdGFsQ2FjaGVkR3d4Q29ycmVjdGVkBCJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcxAwkAAAIFF3RvdGFsQ2FjaGVkR3d4Q29ycmVjdGVkAAAAAAkAawMFHnBvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsMQULdXNlckN1cnJHd3gFF3RvdGFsQ2FjaGVkR3d4Q29ycmVjdGVkBCF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcJAGQCBSJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcwBSJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcxBBN1c2VyQm9vc3RDbGFpbWVkS0VZCQETa2V5VXNlckJvb3N0Q2xhaW1lZAEFCnVzZXJOdW1TdHIEEHVzZXJCb29zdENsYWltZWQJAQNpb3oCBQR0aGlzBRN1c2VyQm9vc3RDbGFpbWVkS0VZBBJ1c2VyQm9vc3RBdmFpbGFibGUJAGUCBSF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcFEHVzZXJCb29zdENsYWltZWQECWRhdGFTdGF0ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgUidXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQUVYm9vc3RFbWlzc2lvbkludGVncmFsBQNuaWwEBWRlYnVnCQC5CQIJAMwIAgkApAMBBR11c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbAkAzAgCCQCkAwEFGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAMwIAgkApAMBBRB1c2VyQm9vc3RDbGFpbWVkCQDMCAIJAKQDAQUSdXNlckJvb3N0QXZhaWxhYmxlCQDMCAIJAKQDAQULcG9vbFdlaWdodDAJAMwIAgkApAMBBQtwb29sV2VpZ2h0MQkAzAgCCQCkAwEFAWgJAMwIAgkApAMBBQN1ZGgJAMwIAgkApAMBBQZ1TGFzdEgJAMwIAgkApAMBBQR1ZGgwCQDMCAIJAKQDAQUEdWRoMQkAzAgCCQCkAwEFC3VzZXJDdXJyR3d4CQDMCAIJAKQDAQUXdG90YWxDYWNoZWRHd3hDb3JyZWN0ZWQFA25pbAIBOgkAlQoDBSF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcFCWRhdGFTdGF0ZQUFZGVidWcBC2xvY2tBY3Rpb25zAgFpCGR1cmF0aW9uBAhjZmdBcnJheQkBFXJlYWRDb25maWdBcnJheU9yRmFpbAAECmFzc2V0SWRTdHIJAJEDAgUIY2ZnQXJyYXkFDUlkeENmZ0Fzc2V0SWQEB2Fzc2V0SWQJANkEAQUKYXNzZXRJZFN0cgQNbWluTG9ja0Ftb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRNJZHhDZmdNaW5Mb2NrQW1vdW50BA9taW5Mb2NrRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUVSWR4Q2ZnTWluTG9ja0R1cmF0aW9uBA9tYXhMb2NrRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUVSWR4Q2ZnTWF4TG9ja0R1cmF0aW9uAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQI0aW52YWxpZCBwYXltZW50IC0gZXhhY3Qgb25lIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAECXBtdEFtb3VudAgFA3BtdAZhbW91bnQDCQECIT0CBQdhc3NldElkCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQJAAIBCQCsAgIJAKwCAgIeaW52YWxpZCBhc3NldCBpcyBpbiBwYXltZW50IC0gBQphc3NldElkU3RyAgwgaXMgZXhwZWN0ZWQEDm5leHRVc2VyTnVtS0VZCQEOa2V5TmV4dFVzZXJOdW0ABA51c2VyQWRkcmVzc1N0cgkApQgBCAUBaQZjYWxsZXIEDnVzZXJJc0V4aXN0aW5nCQEJaXNEZWZpbmVkAQkAoggBCQESa2V5VXNlcjJOdW1NYXBwaW5nAQUOdXNlckFkZHJlc3NTdHIECnVzZXJOdW1TdHIDBQ51c2VySXNFeGlzdGluZwkBBXZhbHVlAQkAoggBCQESa2V5VXNlcjJOdW1NYXBwaW5nAQUOdXNlckFkZHJlc3NTdHIJAKQDAQkBA2lvZgIFBHRoaXMFDm5leHRVc2VyTnVtS0VZBAd1c2VyTnVtCQENcGFyc2VJbnRWYWx1ZQEFCnVzZXJOdW1TdHIECWxvY2tTdGFydAUGaGVpZ2h0BA1zdGFydEJsb2NrS0VZCQEWa2V5TG9ja1BhcmFtU3RhcnRCbG9jawEFCnVzZXJOdW1TdHIEC2R1cmF0aW9uS0VZCQEUa2V5TG9ja1BhcmFtRHVyYXRpb24BBQp1c2VyTnVtU3RyBA11c2VyQW1vdW50S0VZCQEWa2V5TG9ja1BhcmFtVXNlckFtb3VudAEFCnVzZXJOdW1TdHIDCQBmAgUNbWluTG9ja0Ftb3VudAUJcG10QW1vdW50CQACAQkArAICAiJhbW91bnQgaXMgbGVzcyB0aGVuIG1pbkxvY2tBbW91bnQ9CQCkAwEFDW1pbkxvY2tBbW91bnQDCQBmAgUPbWluTG9ja0R1cmF0aW9uBQhkdXJhdGlvbgkAAgEJAKwCAgItcGFzc2VkIGR1cmF0aW9uIGlzIGxlc3MgdGhlbiBtaW5Mb2NrRHVyYXRpb249CQCkAwEFD21pbkxvY2tEdXJhdGlvbgMJAGYCBQhkdXJhdGlvbgUPbWF4TG9ja0R1cmF0aW9uCQACAQkArAICAjBwYXNzZWQgZHVyYXRpb24gaXMgZ3JlYXRlciB0aGVuIG1heExvY2tEdXJhdGlvbj0JAKQDAQUPbWF4TG9ja0R1cmF0aW9uAwMFDnVzZXJJc0V4aXN0aW5nCQBnAgkAZAIJAQNpb2YCBQR0aGlzBQ1zdGFydEJsb2NrS0VZCQEDaW9mAgUEdGhpcwULZHVyYXRpb25LRVkFCWxvY2tTdGFydAcJAAIBAjZ0aGVyZSBpcyBhbiBhY3RpdmUgbG9jayAtIGNvbnNpZGVyIHRvIHVzZSBpbmNyZWFzZUxvY2sDCQBmAgkBA2lvegIFBHRoaXMFDXVzZXJBbW91bnRLRVkAAAkAAgEJAKwCAgI0dGhlcmUgYXJlIGxvY2tlZCBXWHMgLSBjb25zaWRlciB0byB1c2UgaW5jcmVhc2VMb2NrIAUNdXNlckFtb3VudEtFWQQHY29lZmZYOAkAawMFCGR1cmF0aW9uBQVNVUxUOAUPbWF4TG9ja0R1cmF0aW9uBA5nV3hBbW91bnRTdGFydAkAawMFCXBtdEFtb3VudAUHY29lZmZYOAUFTVVMVDgEE2dXeFBhcmFtc1Jlc3VsdExpc3QJAQNhYWwBCQD8BwQFDG1hdGhDb250cmFjdAIVY2FsY0d3eFBhcmFtc1JFQURPTkxZCQDMCAIFDmdXeEFtb3VudFN0YXJ0CQDMCAIFCWxvY2tTdGFydAkAzAgCBQhkdXJhdGlvbgUDbmlsBQNuaWwEAWsJAQJhaQEJAJEDAgUTZ1d4UGFyYW1zUmVzdWx0TGlzdAAABAFiCQECYWkBCQCRAwIFE2dXeFBhcmFtc1Jlc3VsdExpc3QAAQQGcGVyaW9kCQCkAwEJAQJhaQEJAJEDAgUTZ1d4UGFyYW1zUmVzdWx0TGlzdAACBBJ3eEVtaXNzaW9uUGVyQmxvY2sJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQEea2V5RW1pc3Npb25SYXRlUGVyQmxvY2tDdXJyZW50AAQNZW1pc3Npb25TdGFydAkBA2lvZgIFEGVtaXNzaW9uQ29udHJhY3QJARVrZXlFbWlzc2lvblN0YXJ0QmxvY2sABAtlbWlzc2lvbkVuZAkBA2lvZgIFEGVtaXNzaW9uQ29udHJhY3QJARNrZXlFbWlzc2lvbkVuZEJsb2NrAAQBaAMJAGYCBQZoZWlnaHQFC2VtaXNzaW9uRW5kBQtlbWlzc2lvbkVuZAUGaGVpZ2h0BAJkaAkAlgMBCQDMCAIJAGUCBQFoBQ1lbWlzc2lvblN0YXJ0CQDMCAIAAAUDbmlsBCB1c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQkBIGtleVVzZXJCb29zdEVtaXNzaW9uTGFzdElOVEVHUkFMAQUKdXNlck51bVN0cgQVYm9vc3RFbWlzc2lvbkludGVncmFsCQBpAgkAaAIJAGgCBRJ3eEVtaXNzaW9uUGVyQmxvY2sFAmRoAAIAAwQXdXNlck1heEJvb3N0SW50ZWdyYWxLRVkJARdrZXlVc2VyTWF4Qm9vc3RJTlRFR1JBTAEFCnVzZXJOdW1TdHIEGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQkBGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAAED3VzZXJNYXhCb29zdEludAkAaQIJAGgCBQ5nV3hBbW91bnRTdGFydAUIZHVyYXRpb24AAgQQdG90YWxNYXhCb29zdEludAkBA2lvegIFBHRoaXMFGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQQRdG90YWxDYWNoZWRHd3hSYXcJARFnZXRUb3RhbENhY2hlZEd3eAEHBANhcnIDBQ51c2VySXNFeGlzdGluZwUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5uZXh0VXNlck51bUtFWQkAZAIFB3VzZXJOdW0AAQkAzAgCCQELU3RyaW5nRW50cnkCCQESa2V5VXNlcjJOdW1NYXBwaW5nAQUOdXNlckFkZHJlc3NTdHIFCnVzZXJOdW1TdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEmtleU51bTJVc2VyTWFwcGluZwEFCnVzZXJOdW1TdHIFDnVzZXJBZGRyZXNzU3RyBQNuaWwJAJQKAgkAzggCCQDNCAIJAM4IAgkAzggCBQNhcnIJAQ9Mb2NrUGFyYW1zRW50cnkIBQ51c2VyQWRkcmVzc1N0cgUKdXNlck51bVN0cgUJcG10QW1vdW50BQlsb2NrU3RhcnQFCGR1cmF0aW9uBQFrBQFiBQZwZXJpb2QJAQpTdGF0c0VudHJ5BAUJcG10QW1vdW50BQhkdXJhdGlvbgABAwUOdXNlcklzRXhpc3RpbmcAAAABCQEMSGlzdG9yeUVudHJ5CAIEbG9jawUOdXNlckFkZHJlc3NTdHIFCXBtdEFtb3VudAUJbG9ja1N0YXJ0BQhkdXJhdGlvbgUBawUBYgUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgUgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkFFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEWtleVRvdGFsQ2FjaGVkR3d4AAkAZAIFEXRvdGFsQ2FjaGVkR3d4UmF3BQ5nV3hBbW91bnRTdGFydAUDbmlsBQ5nV3hBbW91bnRTdGFydAwBaQELY29uc3RydWN0b3IGEWZhY3RvcnlBZGRyZXNzU3RyDmxvY2tBc3NldElkU3RyDW1pbkxvY2tBbW91bnQLbWluRHVyYXRpb24LbWF4RHVyYXRpb24MbWF0aENvbnRyYWN0BAtjaGVja0NhbGxlcgkBC211c3RNYW5hZ2VyAQUBaQMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDmtleU5leHRVc2VyTnVtAAAACQDMCAIJAQtTdHJpbmdFbnRyeQIJAQlrZXlDb25maWcACQEMZm9ybWF0Q29uZmlnBQUObG9ja0Fzc2V0SWRTdHIFDW1pbkxvY2tBbW91bnQFC21pbkR1cmF0aW9uBQttYXhEdXJhdGlvbgUMbWF0aENvbnRyYWN0CQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlGYWN0b3J5QWRkcmVzcwAFEWZhY3RvcnlBZGRyZXNzU3RyBQNuaWwJAQpTdGF0c0VudHJ5BAAAAAAAAAAACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBB2xvY2tSZWYDCGR1cmF0aW9uD3JlZmVycmVyQWRkcmVzcwlzaWduYXR1cmUEDSR0MDI0NDEzMjQ0NzgJAQtsb2NrQWN0aW9ucwIFAWkFCGR1cmF0aW9uBBFsb2NrQWN0aW9uc1Jlc3VsdAgFDSR0MDI0NDEzMjQ0NzgCXzEEDmdXeEFtb3VudFN0YXJ0CAUNJHQwMjQ0MTMyNDQ3OAJfMgQPcmVmZXJyYWxBZGRyZXNzCQClCAEIBQFpBmNhbGxlcgQGcmVmSW52AwMJAAACBQ9yZWZlcnJlckFkZHJlc3MCAAYJAAACBQlzaWduYXR1cmUBAAUEdW5pdAkA/AcEBR5yZWZlcnJhbHNDb250cmFjdEFkZHJlc3NPckZhaWwCCmNyZWF0ZVBhaXIJAMwIAgUTcmVmZXJyYWxQcm9ncmFtTmFtZQkAzAgCBQ9yZWZlcnJlckFkZHJlc3MJAMwIAgUPcmVmZXJyYWxBZGRyZXNzCQDMCAIFCXNpZ25hdHVyZQUDbmlsBQNuaWwDCQAAAgUGcmVmSW52BQZyZWZJbnYEEXVwZGF0ZVJlZkFjdGl2aXR5CQD8BwQFDG1hdGhDb250cmFjdAIWdXBkYXRlUmVmZXJyYWxBY3Rpdml0eQkAzAgCCQClCAEIBQFpBmNhbGxlcgkAzAgCBQ5nV3hBbW91bnRTdGFydAUDbmlsBQNuaWwDCQAAAgURdXBkYXRlUmVmQWN0aXZpdHkFEXVwZGF0ZVJlZkFjdGl2aXR5CQCUCgIFEWxvY2tBY3Rpb25zUmVzdWx0BQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBGxvY2sBCGR1cmF0aW9uBA0kdDAyNDk0ODI1MDEzCQELbG9ja0FjdGlvbnMCBQFpBQhkdXJhdGlvbgQRbG9ja0FjdGlvbnNSZXN1bHQIBQ0kdDAyNDk0ODI1MDEzAl8xBA5nV3hBbW91bnRTdGFydAgFDSR0MDI0OTQ4MjUwMTMCXzIEEXVwZGF0ZVJlZkFjdGl2aXR5CQD8BwQFDG1hdGhDb250cmFjdAIWdXBkYXRlUmVmZXJyYWxBY3Rpdml0eQkAzAgCCQClCAEIBQFpBmNhbGxlcgkAzAgCBQ5nV3hBbW91bnRTdGFydAUDbmlsBQNuaWwDCQAAAgURdXBkYXRlUmVmQWN0aXZpdHkFEXVwZGF0ZVJlZkFjdGl2aXR5CQCUCgIFEWxvY2tBY3Rpb25zUmVzdWx0BQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDGluY3JlYXNlTG9jawENZGVsdGFEdXJhdGlvbgQIY2ZnQXJyYXkJARVyZWFkQ29uZmlnQXJyYXlPckZhaWwABAphc3NldElkU3RyCQCRAwIFCGNmZ0FycmF5BQ1JZHhDZmdBc3NldElkBAdhc3NldElkCQDZBAEFCmFzc2V0SWRTdHIED21pbkxvY2tEdXJhdGlvbgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRVJZHhDZmdNaW5Mb2NrRHVyYXRpb24ED21heExvY2tEdXJhdGlvbgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRVJZHhDZmdNYXhMb2NrRHVyYXRpb24ECXBtdEFtb3VudAkBImV4dHJhY3RPcHRpb25hbFBheW1lbnRBbW91bnRPckZhaWwCBQFpBQdhc3NldElkBA51c2VyQWRkcmVzc1N0cgkApQgBCAUBaQZjYWxsZXIED3VzZXJSZWNvcmRBcnJheQkBGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsAQUOdXNlckFkZHJlc3NTdHIECnVzZXJOdW1TdHIJAJEDAgUPdXNlclJlY29yZEFycmF5BQ5JZHhMb2NrVXNlck51bQQKdXNlckFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUNSWR4TG9ja0Ftb3VudAQJbG9ja1N0YXJ0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdXNlclJlY29yZEFycmF5BQxJZHhMb2NrU3RhcnQEDGxvY2tEdXJhdGlvbgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUPSWR4TG9ja0R1cmF0aW9uBAdsb2NrRW5kCQBkAgUJbG9ja1N0YXJ0BQxsb2NrRHVyYXRpb24EEXJlbWFpbmluZ0R1cmF0aW9uCQCWAwEJAMwIAgkAZQIFB2xvY2tFbmQFBmhlaWdodAkAzAgCAAAFA25pbAQNdXNlckFtb3VudE5ldwkAZAIFCnVzZXJBbW91bnQFCXBtdEFtb3VudAQPbG9ja0R1cmF0aW9uTmV3CQBkAgURcmVtYWluaW5nRHVyYXRpb24FDWRlbHRhRHVyYXRpb24DCQBmAgAABQ1kZWx0YUR1cmF0aW9uCQACAQIaZHVyYXRpb24gaXMgbGVzcyB0aGVuIHplcm8DCQBmAgUPbWluTG9ja0R1cmF0aW9uBQ9sb2NrRHVyYXRpb25OZXcJAAIBCQCsAgICLWxvY2tEdXJhdGlvbk5ldyBpcyBsZXNzIHRoZW4gbWluTG9ja0R1cmF0aW9uPQkApAMBBQ9taW5Mb2NrRHVyYXRpb24DCQBmAgUPbG9ja0R1cmF0aW9uTmV3BQ9tYXhMb2NrRHVyYXRpb24JAAIBCQCsAgICRGRlbHRhRHVyYXRpb24gKyBleGlzdGVkTG9ja0R1cmF0aW9uIGlzIGdyZWF0ZXIgdGhlbiBtYXhMb2NrRHVyYXRpb249CQCkAwEFD21heExvY2tEdXJhdGlvbgQHY29lZmZYOAkAawMFD2xvY2tEdXJhdGlvbk5ldwUFTVVMVDgFD21heExvY2tEdXJhdGlvbgQOZ1d4QW1vdW50U3RhcnQJAGsDBQ11c2VyQW1vdW50TmV3BQdjb2VmZlg4BQVNVUxUOAQRdXBkYXRlUmVmQWN0aXZpdHkJAPwHBAUMbWF0aENvbnRyYWN0AhZ1cGRhdGVSZWZlcnJhbEFjdGl2aXR5CQDMCAIJAKUIAQgFAWkGY2FsbGVyCQDMCAIFDmdXeEFtb3VudFN0YXJ0BQNuaWwFA25pbAMJAAACBRF1cGRhdGVSZWZBY3Rpdml0eQURdXBkYXRlUmVmQWN0aXZpdHkEDGxvY2tTdGFydE5ldwUGaGVpZ2h0BBNnV3hQYXJhbXNSZXN1bHRMaXN0CQEDYWFsAQkA/AcEBQxtYXRoQ29udHJhY3QCFWNhbGNHd3hQYXJhbXNSRUFET05MWQkAzAgCBQ5nV3hBbW91bnRTdGFydAkAzAgCBQxsb2NrU3RhcnROZXcJAMwIAgUPbG9ja0R1cmF0aW9uTmV3BQNuaWwFA25pbAQBawkBAmFpAQkAkQMCBRNnV3hQYXJhbXNSZXN1bHRMaXN0AAAEAWIJAQJhaQEJAJEDAgUTZ1d4UGFyYW1zUmVzdWx0TGlzdAABBAZwZXJpb2QJAKQDAQkBAmFpAQkAkQMCBRNnV3hQYXJhbXNSZXN1bHRMaXN0AAIEEnd4RW1pc3Npb25QZXJCbG9jawkBA2lvZgIFEGVtaXNzaW9uQ29udHJhY3QJAR5rZXlFbWlzc2lvblJhdGVQZXJCbG9ja0N1cnJlbnQABA1lbWlzc2lvblN0YXJ0CQEDaW9mAgUQZW1pc3Npb25Db250cmFjdAkBFWtleUVtaXNzaW9uU3RhcnRCbG9jawAEC2VtaXNzaW9uRW5kCQEDaW9mAgUQZW1pc3Npb25Db250cmFjdAkBE2tleUVtaXNzaW9uRW5kQmxvY2sABAFoAwkAZgIFBmhlaWdodAULZW1pc3Npb25FbmQFC2VtaXNzaW9uRW5kBQZoZWlnaHQEAmRoCQCWAwEJAMwIAgkAZQIFAWgFDWVtaXNzaW9uU3RhcnQJAMwIAgAABQNuaWwEIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZCQEga2V5VXNlckJvb3N0RW1pc3Npb25MYXN0SU5URUdSQUwBBQp1c2VyTnVtU3RyBB11c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbAkBA2lvegIFBHRoaXMFIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZBBVib29zdEVtaXNzaW9uSW50ZWdyYWwJAGkCCQBoAgkAaAIFEnd4RW1pc3Npb25QZXJCbG9jawUCZGgAAgADBBl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsCQBlAgUVYm9vc3RFbWlzc2lvbkludGVncmFsBR11c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbAMJAGYCAAAFGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAAIBAhJ3cm9uZyBjYWxjdWxhdGlvbnMEF3VzZXJNYXhCb29zdEludGVncmFsS0VZCQEXa2V5VXNlck1heEJvb3N0SU5URUdSQUwBBQp1c2VyTnVtU3RyBBh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkJARhrZXlUb3RhbE1heEJvb3N0SU5URUdSQUwABA91c2VyTWF4Qm9vc3RJbnQJAQNpb3oCBQR0aGlzBRd1c2VyTWF4Qm9vc3RJbnRlZ3JhbEtFWQQQdG90YWxNYXhCb29zdEludAkBA2lvegIFBHRoaXMFGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQQLY3VyclVzZXJHd3gJARRjYWxjQ3VycmVudEd3eEFtb3VudAEFDnVzZXJBZGRyZXNzU3RyBAdnd3hEaWZmCQBlAgUOZ1d4QW1vdW50U3RhcnQFC2N1cnJVc2VyR3d4AwkAZgIAAAUHZ3d4RGlmZgkAAgEJAKwCAgIYZ3d4RGlmZiBpcyBsZXNzIHRoZW4gMDogCQCkAwEFB2d3eERpZmYEEXRvdGFsQ2FjaGVkR3d4UmF3CQERZ2V0VG90YWxDYWNoZWRHd3gBBwQXdG90YWxDYWNoZWRHd3hDb3JyZWN0ZWQJARFnZXRUb3RhbENhY2hlZEd3eAEGBCF1c2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWxLRVkJASFrZXlVc2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWwBBQp1c2VyTnVtU3RyBB51c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWwJAQNpb3oCBQR0aGlzBSF1c2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWxLRVkEIXVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldwkAawMFGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwFC2N1cnJVc2VyR3d4BRd0b3RhbENhY2hlZEd3eENvcnJlY3RlZAQSdXNlck1heEJvb3N0SW50TmV3CQBpAgkAaAIFDmdXeEFtb3VudFN0YXJ0BQ9sb2NrRHVyYXRpb25OZXcAAgQYcmVtYWluaW5nVXNlck1heEJvb3N0SW50CQBpAgkAaAIFC2N1cnJVc2VyR3d4BRFyZW1haW5pbmdEdXJhdGlvbgACBBN1c2VyTWF4Qm9vc3RJbnREaWZmCQBlAgUSdXNlck1heEJvb3N0SW50TmV3BRhyZW1haW5pbmdVc2VyTWF4Qm9vc3RJbnQJAM4IAgkAzQgCCQDOCAIJAQ9Mb2NrUGFyYW1zRW50cnkIBQ51c2VyQWRkcmVzc1N0cgUKdXNlck51bVN0cgUNdXNlckFtb3VudE5ldwUMbG9ja1N0YXJ0TmV3BQ9sb2NrRHVyYXRpb25OZXcFAWsFAWIFBnBlcmlvZAkBClN0YXRzRW50cnkEBQlwbXRBbW91bnQFDWRlbHRhRHVyYXRpb24AAAAACQEMSGlzdG9yeUVudHJ5CAIEbG9jawUOdXNlckFkZHJlc3NTdHIFCXBtdEFtb3VudAUJbG9ja1N0YXJ0BQ9sb2NrRHVyYXRpb25OZXcFAWsFAWIFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIJARFrZXlUb3RhbENhY2hlZEd3eAAJAGQCBRF0b3RhbENhY2hlZEd3eFJhdwUHZ3d4RGlmZgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDGNsYWltV3hCb29zdAIMbHBBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyAwkBAiE9AgUPc3Rha2luZ0NvbnRyYWN0CAUBaQZjYWxsZXIJAAIBAhJwZXJtaXNzaW9ucyBkZW5pZWQEDSR0MDMwMDg5MzAxOTEJARRpbnRlcm5hbENsYWltV3hCb29zdAMFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIHBBJ1c2VyQm9vc3RBdmFpbGFibGUIBQ0kdDAzMDA4OTMwMTkxAl8xBAlkYXRhU3RhdGUIBQ0kdDAzMDA4OTMwMTkxAl8yBAVkZWJ1ZwgFDSR0MDMwMDg5MzAxOTECXzMJAJQKAgUJZGF0YVN0YXRlCQDMCAIFEnVzZXJCb29zdEF2YWlsYWJsZQUDbmlsAWkBFGNsYWltV3hCb29zdFJFQURPTkxZAgxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIEDSR0MDMwMzMwMzA0MzEJARRpbnRlcm5hbENsYWltV3hCb29zdAMFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIGBBJ1c2VyQm9vc3RBdmFpbGFibGUIBQ0kdDAzMDMzMDMwNDMxAl8xBAlkYXRhU3RhdGUIBQ0kdDAzMDMzMDMwNDMxAl8yBAVkZWJ1ZwgFDSR0MDMwMzMwMzA0MzECXzMJAJQKAgUDbmlsCQDMCAIFEnVzZXJCb29zdEF2YWlsYWJsZQkAzAgCBQVkZWJ1ZwUDbmlsAWkBBnVubG9jawELdXNlckFkZHJlc3MED3VzZXJSZWNvcmRBcnJheQkBGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsAQULdXNlckFkZHJlc3MECnVzZXJOdW1TdHIJAJEDAgUPdXNlclJlY29yZEFycmF5BQ5JZHhMb2NrVXNlck51bQQKdXNlckFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUNSWR4TG9ja0Ftb3VudAQJbG9ja1N0YXJ0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdXNlclJlY29yZEFycmF5BQxJZHhMb2NrU3RhcnQEDGxvY2tEdXJhdGlvbgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUPSWR4TG9ja0R1cmF0aW9uBAdsb2NrRW5kCQBkAgUJbG9ja1N0YXJ0BQxsb2NrRHVyYXRpb24ECGNmZ0FycmF5CQEVcmVhZENvbmZpZ0FycmF5T3JGYWlsAAQHYXNzZXRJZAkA2QQBCQCRAwIFCGNmZ0FycmF5BQ1JZHhDZmdBc3NldElkAwkAZwIFB2xvY2tFbmQFBmhlaWdodAkAAgEJAKwCAgkArAICAgV3YWl0IAkApAMBBQdsb2NrRW5kAgogdG8gdW5sb2NrAwkAZwIAAAUKdXNlckFtb3VudAkAAgECEW5vdGhpbmcgdG8gdW5sb2NrBAZwZXJpb2QJAQt2YWx1ZU9yRWxzZQIJAJoIAgUMbWF0aENvbnRyYWN0CQENa2V5TmV4dFBlcmlvZAAAAAkAzQgCCQDNCAIJAM4IAgkBD0xvY2tQYXJhbXNFbnRyeQgFC3VzZXJBZGRyZXNzBQp1c2VyTnVtU3RyAAAFCWxvY2tTdGFydAUMbG9ja0R1cmF0aW9uAAAAAAkApAMBBQZwZXJpb2QJAQpTdGF0c0VudHJ5BAkBAS0BBQp1c2VyQW1vdW50AAAAAAD///////////8BCQEMSGlzdG9yeUVudHJ5CAIGdW5sb2NrBQt1c2VyQWRkcmVzcwUKdXNlckFtb3VudAUJbG9ja1N0YXJ0BQxsb2NrRHVyYXRpb24AAAAABQFpCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQt1c2VyQWRkcmVzcwUKdXNlckFtb3VudAUHYXNzZXRJZAFpARNnd3hVc2VySW5mb1JFQURPTkxZAQt1c2VyQWRkcmVzcwQJZ3d4QW1vdW50CQEUY2FsY0N1cnJlbnRHd3hBbW91bnQBBQt1c2VyQWRkcmVzcwkAlAoCBQNuaWwJAMwIAgUJZ3d4QW1vdW50BQNuaWwBaQEgZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0UkVBRE9OTFkCC3VzZXJBZGRyZXNzDHRhcmdldEhlaWdodAQJZ3d4QW1vdW50CQEZY2FsY1VzZXJHd3hBbW91bnRBdEhlaWdodAIFC3VzZXJBZGRyZXNzBQx0YXJnZXRIZWlnaHQJAJQKAgUDbmlsBQlnd3hBbW91bnQBaQEZZ2V0VG90YWxDYWNoZWRHd3hSRUFET05MWQAJAJQKAgUDbmlsCQERZ2V0VG90YWxDYWNoZWRHd3gBBgFpAQpzZXRNYW5hZ2VyARdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQQLY2hlY2tDYWxsZXIJAQttdXN0TWFuYWdlcgEFAWkDCQAAAgULY2hlY2tDYWxsZXIFC2NoZWNrQ2FsbGVyBBVjaGVja01hbmFnZXJQdWJsaWNLZXkJANkEAQUXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkDCQAAAgUVY2hlY2tNYW5hZ2VyUHVibGljS2V5BRVjaGVja01hbmFnZXJQdWJsaWNLZXkJAMwIAgkBC1N0cmluZ0VudHJ5AgkBGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAUXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ5jb25maXJtTWFuYWdlcgAEAnBtCQEdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQABAVoYXNQTQMJAQlpc0RlZmluZWQBBQJwbQYJAAIBAhJObyBwZW5kaW5nIG1hbmFnZXIDCQAAAgUFaGFzUE0FBWhhc1BNBAdjaGVja1BNAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCcG0GCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFB2NoZWNrUE0FB2NoZWNrUE0JAMwIAgkBC1N0cmluZ0VudHJ5AgkBE2tleU1hbmFnZXJQdWJsaWNLZXkACQDYBAEJAQV2YWx1ZQEFAnBtCQDMCAIJAQtEZWxldGVFbnRyeQEJARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECdHgBBnZlcmlmeQAED3RhcmdldFB1YmxpY0tleQQHJG1hdGNoMAkBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQAAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAnBrBQckbWF0Y2gwBQJwawMJAAECBQckbWF0Y2gwAgRVbml0CAUCdHgPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFD3RhcmdldFB1YmxpY0tlecGIGBw=", "chainId": 84, "height": 2460825, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: 3agbCTkq8uU8ARo4JwbEPUdghLkfQbDYyEqFMuZPGajY Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 6 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let SEP = "__"
5+
6+let SCALE8 = 8
7+
8+let MULT8 = 100000000
9+
10+let POOLWEIGHTMULT = MULT8
11+
12+func strf (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
13+
14+
15+func ioz (address,key) = valueOrElse(getInteger(address, key), 0)
16+
17+
18+func iod (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
19+
20+
21+func iof (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
22+
23+
24+func abs (val) = if ((0 > val))
25+ then -(val)
26+ else val
27+
28+
29+func aal (val) = match val {
30+ case valAnyLyst: List[Any] =>
31+ valAnyLyst
32+ case _ =>
33+ throw("fail to cast into List[Any]")
34+}
35+
36+
37+func ai (val) = match val {
38+ case valInt: Int =>
39+ valInt
40+ case _ =>
41+ throw("fail to cast into Int")
42+}
43+
44+
45+func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
46+
47+
48+let referralsContractAddressOrFail = addressFromStringValue(strf(this, keyReferralsContractAddress()))
49+
50+let keyReferralProgramName = makeString(["%s%s", "referral", "programName"], SEP)
51+
52+let referralProgramNameDefault = "wxlock"
53+
54+let referralProgramName = valueOrElse(getString(this, keyReferralProgramName), referralProgramNameDefault)
55+
56+func keyFactoryAddress () = "%s%s__config__factoryAddress"
57+
58+
59+let IdxFactoryCfgStakingDapp = 1
60+
61+let IdxFactoryCfgBoostingDapp = 2
62+
63+let IdxFactoryCfgIdoDapp = 3
64+
65+let IdxFactoryCfgTeamDapp = 4
66+
67+let IdxFactoryCfgEmissionDapp = 5
68+
69+let IdxFactoryCfgRestDapp = 6
70+
71+let IdxFactoryCfgSlippageDapp = 7
72+
73+let IdxFactoryCfgDaoDapp = 8
74+
75+let IdxFactoryCfgMarketingDapp = 9
76+
77+let IdxFactoryCfgGwxRewardDapp = 10
78+
79+let IdxFactoryCfgBirdsDapp = 11
80+
81+func keyFactoryCfg () = "%s__factoryConfig"
82+
83+
84+func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
85+
86+
87+func keyFactoryLpList () = "%s__lpTokensList"
88+
89+
90+func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
91+
92+
93+func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
94+
95+
96+func keyFactoryPoolWeightHistory (poolAddress,num) = ((("%s%s__poolWeight__" + poolAddress) + "__") + toString(num))
97+
98+
99+func readFactoryAddressOrFail () = addressFromStringValue(strf(this, keyFactoryAddress()))
100+
101+
102+func readLpList () = split(valueOrElse(getString(readFactoryAddressOrFail(), keyFactoryLpList()), ""), SEP)
103+
104+
105+func readFactoryCfgOrFail (factory) = split(strf(factory, keyFactoryCfg()), SEP)
106+
107+
108+func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
109+
110+
111+func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
112+
113+
114+func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
115+
116+
117+func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
118+
119+
120+func keyManagerPublicKey () = "%s__managerPublicKey"
121+
122+
123+func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
124+
125+
126+func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
127+
128+
129+func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
130+
131+
132+func keyEmissionStartBlock () = "%s%s__emission__startBlock"
133+
134+
135+func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
136+
137+
138+func keyEmissionEndBlock () = "%s%s__emission__endBlock"
139+
140+
141+func keyNextPeriod () = "%s__nextPeriod"
142+
143+
144+func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
145+
146+
147+let IdxCfgAssetId = 1
148+
149+let IdxCfgMinLockAmount = 2
150+
151+let IdxCfgMinLockDuration = 3
152+
153+let IdxCfgMaxLockDuration = 4
154+
155+let IdxCfgMathContract = 5
156+
157+func keyConfig () = "%s__config"
158+
159+
160+func readConfigArrayOrFail () = split(strf(this, keyConfig()), SEP)
161+
162+
163+let mathContract = addressFromStringValue(readConfigArrayOrFail()[IdxCfgMathContract])
164+
165+func formatConfigS (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = makeString(["%s%d%d%d", assetId, minLockAmount, minLockDuration, maxLockDuration, mathContract], SEP)
166+
167+
168+func formatConfig (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = formatConfigS(assetId, toString(minLockAmount), toString(minLockDuration), toString(maxLockDuration), mathContract)
169+
170+
171+func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
172+ case s: String =>
173+ fromBase58String(s)
174+ case _: Unit =>
175+ unit
176+ case _ =>
177+ throw("Match error")
178+}
179+
180+
181+func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
182+ case s: String =>
183+ fromBase58String(s)
184+ case _: Unit =>
185+ unit
186+ case _ =>
187+ throw("Match error")
188+}
189+
190+
191+func mustManager (i) = {
192+ let pd = throw("Permission denied")
193+ match managerPublicKeyOrUnit() {
194+ case pk: ByteVector =>
195+ if ((i.callerPublicKey == pk))
196+ then true
197+ else pd
198+ case _: Unit =>
199+ if ((i.caller == this))
200+ then true
201+ else pd
202+ case _ =>
203+ throw("Match error")
204+ }
205+ }
206+
207+
208+let IdxLockUserNum = 1
209+
210+let IdxLockAmount = 2
211+
212+let IdxLockStart = 3
213+
214+let IdxLockDuration = 4
215+
216+let IdxLockParamK = 5
217+
218+let IdxLockParamB = 6
219+
220+func keyLockParamsRecord (userAddress) = makeString(["%s%s__lock", userAddress], SEP)
221+
222+
223+func readLockParamsRecordOrFail (userAddress) = split(strf(this, keyLockParamsRecord(userAddress)), SEP)
224+
225+
226+func formatLockParamsRecordS (userNum,amount,start,duration,paramK,paramB,lastUpdTimestamp,gwxAmount) = makeString(["%d%d%d%d%d%d%d%d", userNum, amount, start, duration, paramK, paramB, lastUpdTimestamp, gwxAmount], SEP)
227+
228+
229+func formatLockParamsRecord (userNum,amount,start,duration,paramK,paramB,gwxAmount) = formatLockParamsRecordS(userNum, toString(amount), toString(start), toString(duration), toString(paramK), toString(paramB), toString(lastBlock.timestamp), toString(gwxAmount))
230+
231+
232+func keyNextUserNum () = "%s__nextUserNum"
233+
234+
235+func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", userAddress], SEP)
236+
237+
238+func keyNum2UserMapping (num) = makeString(["%s%s%s__mapping__num2user", num], SEP)
239+
240+
241+func keyLockParamUserAmount (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "amount"], SEP)
242+
243+
244+func keyLockParamStartBlock (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "start"], SEP)
245+
246+
247+func keyLockParamDuration (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "duration"], SEP)
248+
249+
250+func keyLockParamK (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "k"], SEP)
251+
252+
253+func keyLockParamB (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "b"], SEP)
254+
255+
256+func keyLockParamByPeriodK (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "k", period], SEP)
257+
258+
259+func keyLockParamByPeriodB (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "b", period], SEP)
260+
261+
262+func keyLockParamTotalAmount () = "%s%s__stats__activeTotalLocked"
263+
264+
265+func keyStatsLocksDurationSumInBlocks () = "%s%s__stats__locksDurationSumInBlocks"
266+
267+
268+func keyStatsLocksCount () = "%s%s__stats__locksCount"
269+
270+
271+func keyStatsUsersCount () = "%s%s__stats__activeUsersCount"
272+
273+
274+func keyUserBoostEmissionLastINTEGRAL (userNum) = makeString(["%s%d__userBoostEmissionLastInt", userNum], SEP)
275+
276+
277+func keyUserLpBoostEmissionLastINTEGRAL (userNum,lpAssetId) = makeString(["%s%d__userBoostEmissionLastInt", userNum, lpAssetId], SEP)
278+
279+
280+func keyUserMaxBoostINTEGRAL (userNum) = makeString(["%s%d__maxBoostInt", userNum], SEP)
281+
282+
283+func keyTotalMaxBoostINTEGRAL () = "%s%s__maxBoostInt__total"
284+
285+
286+func keyUserBoostAvalaibleToClaimTotal (userNum) = makeString(["%s%d__userBoostAvaliableToClaimTotal", userNum], SEP)
287+
288+
289+func keyUserBoostClaimed (userNum) = makeString(["%s%d__userBoostClaimed", userNum], SEP)
290+
291+
292+func keyTotalCachedGwx () = "%s%s__gwxCached__total"
293+
294+
295+func keyTotalCachedGwxCorrective () = "%s__gwxCachedTotalCorrective"
296+
297+
298+let factoryContract = readFactoryAddressOrFail()
299+
300+let factoryCfg = readFactoryCfgOrFail(factoryContract)
301+
302+let emissionContract = getEmissionAddressOrFail(factoryCfg)
303+
304+let stakingContract = getStakingAddressOrFail(factoryCfg)
305+
306+let gwxRewardContract = getGwxRewardAddressOrFail(factoryCfg)
307+
308+func getTotalCachedGwx (correct) = {
309+ let keyVotingEmissionContract = makeString(["%s", "votingEmissionContract"], SEP)
310+ let votingEmissionContract = addressFromStringValue(getStringValue(factoryContract, keyVotingEmissionContract))
311+ let keyCurrentEpochUi = makeString(["%s", "currentEpochUi"], SEP)
312+ let currentEpochUi = getIntegerValue(votingEmissionContract, keyCurrentEpochUi)
313+ let keyTargetEpoch = makeString(["%s%s", "totalCachedGwxCorrection__activationEpoch"], SEP)
314+ let targetEpochOption = getInteger(this, keyTargetEpoch)
315+ let totalCachedGwxRaw = valueOrElse(getInteger(this, keyTotalCachedGwx()), 0)
316+ let isCorrectionActivated = if (isDefined(targetEpochOption))
317+ then (currentEpochUi >= value(targetEpochOption))
318+ else false
319+ let corrective = if (if (isCorrectionActivated)
320+ then correct
321+ else false)
322+ then valueOrElse(getInteger(this, keyTotalCachedGwxCorrective()), 0)
323+ else 0
324+ max([0, (totalCachedGwxRaw + corrective)])
325+ }
326+
327+
328+func HistoryEntry (type,user,amount,lockStart,duration,k,b,i) = {
329+ let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
330+ let historyDATA = makeString(["%d%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(amount), toString(lockStart), toString(duration), toString(k), toString(b)], SEP)
331+ StringEntry(historyKEY, historyDATA)
332+ }
333+
334+
335+func StatsEntry (totalLockedInc,durationInc,lockCountInc,usersCountInc) = {
336+ let locksDurationSumInBlocksKEY = keyStatsLocksDurationSumInBlocks()
337+ let locksCountKEY = keyStatsLocksCount()
338+ let usersCountKEY = keyStatsUsersCount()
339+ let totalAmountKEY = keyLockParamTotalAmount()
340+ let locksDurationSumInBlocks = ioz(this, locksDurationSumInBlocksKEY)
341+ let locksCount = ioz(this, locksCountKEY)
342+ let usersCount = ioz(this, usersCountKEY)
343+ let totalAmount = ioz(this, totalAmountKEY)
344+[IntegerEntry(locksDurationSumInBlocksKEY, (locksDurationSumInBlocks + durationInc)), IntegerEntry(locksCountKEY, (locksCount + lockCountInc)), IntegerEntry(usersCountKEY, (usersCount + usersCountInc)), IntegerEntry(totalAmountKEY, (totalAmount + totalLockedInc))]
345+ }
346+
347+
348+func calcGwxAmount (kRaw,bRaw,h) = {
349+ let SCALE = 1000
350+ (((kRaw * h) + bRaw) / SCALE)
351+ }
352+
353+
354+func LockParamsEntry (userAddress,userNum,amount,start,duration,k,b,period) = {
355+ let userAmountKEY = keyLockParamUserAmount(userNum)
356+ let startBlockKEY = keyLockParamStartBlock(userNum)
357+ let durationKEY = keyLockParamDuration(userNum)
358+ let kKEY = keyLockParamK(userNum)
359+ let bKEY = keyLockParamB(userNum)
360+ let kByPeriodKEY = keyLockParamByPeriodK(userNum, period)
361+ let bByPeriodKEY = keyLockParamByPeriodB(userNum, period)
362+ let gwxAmount = calcGwxAmount(k, b, height)
363+[IntegerEntry(userAmountKEY, amount), IntegerEntry(startBlockKEY, start), IntegerEntry(durationKEY, duration), IntegerEntry(kKEY, k), IntegerEntry(bKEY, b), IntegerEntry(kByPeriodKEY, k), IntegerEntry(bByPeriodKEY, b), StringEntry(keyLockParamsRecord(userAddress), formatLockParamsRecord(userNum, amount, start, duration, k, b, gwxAmount))]
364+ }
365+
366+
367+func extractOptionalPaymentAmountOrFail (i,expectedAssetId) = if ((size(i.payments) > 1))
368+ then throw("only one payment is allowed")
369+ else if ((size(i.payments) == 0))
370+ then 0
371+ else {
372+ let pmt = i.payments[0]
373+ if ((value(pmt.assetId) != expectedAssetId))
374+ then throw("invalid asset id in payment")
375+ else pmt.amount
376+ }
377+
378+
379+func calcUserGwxAmountAtHeight (userAddress,targetHeight) = {
380+ let EMPTY = "empty"
381+ let user2NumMappingKEY = keyUser2NumMapping(userAddress)
382+ let userNum = valueOrElse(getString(user2NumMappingKEY), EMPTY)
383+ let k = valueOrElse(getInteger(keyLockParamK(userNum)), 0)
384+ let b = valueOrElse(getInteger(keyLockParamB(userNum)), 0)
385+ let gwxAmountCalc = calcGwxAmount(k, b, targetHeight)
386+ let gwxAmount = if ((0 > gwxAmountCalc))
387+ then 0
388+ else gwxAmountCalc
389+ gwxAmount
390+ }
391+
392+
393+func calcCurrentGwxAmount (userAddress) = calcUserGwxAmountAtHeight(userAddress, height)
394+
395+
396+func internalClaimWxBoost (lpAssetIdStr,userAddressStr,readOnly) = {
397+ let EMPTY = "EMPTY"
398+ let userRecordOrEmpty = valueOrElse(getString(this, keyLockParamsRecord(userAddressStr)), EMPTY)
399+ if ((userRecordOrEmpty == EMPTY))
400+ then $Tuple3(0, nil, "userRecord::is::empty")
401+ else {
402+ let userRecordArray = split(userRecordOrEmpty, SEP)
403+ let userNumStr = userRecordArray[IdxLockUserNum]
404+ let gwxRewardEmissionStartHeight = valueOrElse(getInteger(gwxRewardContract, keyGwxRewardEmissionStartHeight()), 0)
405+ let EMPTYSTR = "empty"
406+ let $t01530615884 = if ((lpAssetIdStr != EMPTYSTR))
407+ then {
408+ let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
409+ let pw1 = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
410+ let pw0 = valueOrElse(getInteger(factoryContract, keyFactoryPoolWeightHistory(poolAddressStr, 0)), pw1)
411+ $Tuple2(pw0, pw1)
412+ }
413+ else if (readOnly)
414+ then $Tuple2(0, 0)
415+ else throw(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
416+ let poolWeight0 = $t01530615884._1
417+ let poolWeight1 = $t01530615884._2
418+ let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
419+ let emissionStart = iof(emissionContract, keyEmissionStartBlock())
420+ let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
421+ let h = if ((height > emissionEnd))
422+ then emissionEnd
423+ else height
424+ let dh = max([(h - emissionStart), 0])
425+ let userLpBoostEmissionLastIntegralKEY = keyUserLpBoostEmissionLastINTEGRAL(userNumStr, lpAssetIdStr)
426+ let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
427+ let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), ioz(this, userBoostEmissionLastIntegralKEY))
428+ let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
429+ let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
430+ let udh = fraction(userBoostEmissionIntegral, 3, (2 * wxEmissionPerBlock))
431+ let uLastH = (h - udh)
432+ let udh0 = max([(gwxRewardEmissionStartHeight - uLastH), 0])
433+ let udh1 = ((h - uLastH) - udh0)
434+ if (if (if ((0 > uLastH))
435+ then true
436+ else (0 > udh1))
437+ then true
438+ else (abs(((udh0 + udh1) - udh)) >= 1))
439+ then throw(((((((("invalid udh calc: udh=" + toString(udh)) + " uLastH=") + toString(uLastH)) + " udh0=") + toString(udh0)) + " udh1=") + toString(udh1)))
440+ else if ((0 > userBoostEmissionIntegral))
441+ then throw("wrong calculations")
442+ else {
443+ let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
444+ let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
445+ let userMaxBoostInt = ioz(this, userMaxBoostIntegralKEY)
446+ let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
447+ let totalCachedGwxCorrected = getTotalCachedGwx(true)
448+ let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
449+ let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
450+ let userBoostAvaliableToClaimTotal = ioz(this, userBoostAvalaibleToClaimTotalKEY)
451+ let userBoostEmissionIntegral0 = if ((udh == 0))
452+ then 0
453+ else fraction(userBoostEmissionIntegral, udh0, udh)
454+ let userBoostEmissionIntegral1 = if ((udh == 0))
455+ then 0
456+ else fraction(userBoostEmissionIntegral, udh1, udh)
457+ let poolUserBoostEmissionIntegral0 = fraction(userBoostEmissionIntegral0, poolWeight0, POOLWEIGHTMULT)
458+ let poolUserBoostEmissionIntegral1 = fraction(userBoostEmissionIntegral1, poolWeight1, POOLWEIGHTMULT)
459+ let userBoostAvaliableToClaimTotalNew0 = if ((totalCachedGwxCorrected == 0))
460+ then 0
461+ else fraction(poolUserBoostEmissionIntegral0, userCurrGwx, totalCachedGwxCorrected)
462+ let userBoostAvaliableToClaimTotalNew1 = if ((totalCachedGwxCorrected == 0))
463+ then 0
464+ else fraction(poolUserBoostEmissionIntegral1, userCurrGwx, totalCachedGwxCorrected)
465+ let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotalNew0 + userBoostAvaliableToClaimTotalNew1)
466+ let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
467+ let userBoostClaimed = ioz(this, userBoostClaimedKEY)
468+ let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
469+ let dataState = [IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)]
470+ let debug = makeString([toString(userBoostEmissionLastIntegral), toString(userBoostEmissionIntegral), toString(userBoostClaimed), toString(userBoostAvailable), toString(poolWeight0), toString(poolWeight1), toString(h), toString(udh), toString(uLastH), toString(udh0), toString(udh1), toString(userCurrGwx), toString(totalCachedGwxCorrected)], ":")
471+ $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
472+ }
473+ }
474+ }
475+
476+
477+func lockActions (i,duration) = {
478+ let cfgArray = readConfigArrayOrFail()
479+ let assetIdStr = cfgArray[IdxCfgAssetId]
480+ let assetId = fromBase58String(assetIdStr)
481+ let minLockAmount = parseIntValue(cfgArray[IdxCfgMinLockAmount])
482+ let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
483+ let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
484+ if ((size(i.payments) != 1))
485+ then throw("invalid payment - exact one payment must be attached")
486+ else {
487+ let pmt = i.payments[0]
488+ let pmtAmount = pmt.amount
489+ if ((assetId != value(pmt.assetId)))
490+ then throw((("invalid asset is in payment - " + assetIdStr) + " is expected"))
491+ else {
492+ let nextUserNumKEY = keyNextUserNum()
493+ let userAddressStr = toString(i.caller)
494+ let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
495+ let userNumStr = if (userIsExisting)
496+ then value(getString(keyUser2NumMapping(userAddressStr)))
497+ else toString(iof(this, nextUserNumKEY))
498+ let userNum = parseIntValue(userNumStr)
499+ let lockStart = height
500+ let startBlockKEY = keyLockParamStartBlock(userNumStr)
501+ let durationKEY = keyLockParamDuration(userNumStr)
502+ let userAmountKEY = keyLockParamUserAmount(userNumStr)
503+ if ((minLockAmount > pmtAmount))
504+ then throw(("amount is less then minLockAmount=" + toString(minLockAmount)))
505+ else if ((minLockDuration > duration))
506+ then throw(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
507+ else if ((duration > maxLockDuration))
508+ then throw(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
509+ else if (if (userIsExisting)
510+ then ((iof(this, startBlockKEY) + iof(this, durationKEY)) >= lockStart)
511+ else false)
512+ then throw("there is an active lock - consider to use increaseLock")
513+ else if ((ioz(this, userAmountKEY) > 0))
514+ then throw(("there are locked WXs - consider to use increaseLock " + userAmountKEY))
515+ else {
516+ let coeffX8 = fraction(duration, MULT8, maxLockDuration)
517+ let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
518+ let gWxParamsResultList = aal(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
519+ let k = ai(gWxParamsResultList[0])
520+ let b = ai(gWxParamsResultList[1])
521+ let period = toString(ai(gWxParamsResultList[2]))
522+ let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
523+ let emissionStart = iof(emissionContract, keyEmissionStartBlock())
524+ let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
525+ let h = if ((height > emissionEnd))
526+ then emissionEnd
527+ else height
528+ let dh = max([(h - emissionStart), 0])
529+ let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
530+ let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
531+ let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
532+ let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
533+ let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
534+ let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
535+ let totalCachedGwxRaw = getTotalCachedGwx(false)
536+ let arr = if (userIsExisting)
537+ then nil
538+ else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
539+ $Tuple2(((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
540+ then 0
541+ else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(keyTotalCachedGwx(), (totalCachedGwxRaw + gWxAmountStart))]), gWxAmountStart)
542+ }
543+ }
544+ }
545+ }
546+
547+
548+@Callable(i)
549+func constructor (factoryAddressStr,lockAssetIdStr,minLockAmount,minDuration,maxDuration,mathContract) = {
550+ let checkCaller = mustManager(i)
551+ if ((checkCaller == checkCaller))
552+ then ([IntegerEntry(keyNextUserNum(), 0), StringEntry(keyConfig(), formatConfig(lockAssetIdStr, minLockAmount, minDuration, maxDuration, mathContract)), StringEntry(keyFactoryAddress(), factoryAddressStr)] ++ StatsEntry(0, 0, 0, 0))
553+ else throw("Strict value is not equal to itself.")
554+ }
555+
556+
557+
558+@Callable(i)
559+func lockRef (duration,referrerAddress,signature) = {
560+ let $t02441324478 = lockActions(i, duration)
561+ let lockActionsResult = $t02441324478._1
562+ let gWxAmountStart = $t02441324478._2
563+ let referralAddress = toString(i.caller)
564+ let refInv = if (if ((referrerAddress == ""))
565+ then true
566+ else (signature == base58''))
567+ then unit
568+ else invoke(referralsContractAddressOrFail, "createPair", [referralProgramName, referrerAddress, referralAddress, signature], nil)
569+ if ((refInv == refInv))
570+ then {
571+ let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
572+ if ((updateRefActivity == updateRefActivity))
573+ then $Tuple2(lockActionsResult, unit)
574+ else throw("Strict value is not equal to itself.")
575+ }
576+ else throw("Strict value is not equal to itself.")
577+ }
578+
579+
580+
581+@Callable(i)
582+func lock (duration) = {
583+ let $t02494825013 = lockActions(i, duration)
584+ let lockActionsResult = $t02494825013._1
585+ let gWxAmountStart = $t02494825013._2
586+ let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
587+ if ((updateRefActivity == updateRefActivity))
588+ then $Tuple2(lockActionsResult, unit)
589+ else throw("Strict value is not equal to itself.")
590+ }
591+
592+
593+
594+@Callable(i)
595+func increaseLock (deltaDuration) = {
596+ let cfgArray = readConfigArrayOrFail()
597+ let assetIdStr = cfgArray[IdxCfgAssetId]
598+ let assetId = fromBase58String(assetIdStr)
599+ let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
600+ let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
601+ let pmtAmount = extractOptionalPaymentAmountOrFail(i, assetId)
602+ let userAddressStr = toString(i.caller)
603+ let userRecordArray = readLockParamsRecordOrFail(userAddressStr)
604+ let userNumStr = userRecordArray[IdxLockUserNum]
605+ let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
606+ let lockStart = parseIntValue(userRecordArray[IdxLockStart])
607+ let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
608+ let lockEnd = (lockStart + lockDuration)
609+ let remainingDuration = max([(lockEnd - height), 0])
610+ let userAmountNew = (userAmount + pmtAmount)
611+ let lockDurationNew = (remainingDuration + deltaDuration)
612+ if ((0 > deltaDuration))
613+ then throw("duration is less then zero")
614+ else if ((minLockDuration > lockDurationNew))
615+ then throw(("lockDurationNew is less then minLockDuration=" + toString(minLockDuration)))
616+ else if ((lockDurationNew > maxLockDuration))
617+ then throw(("deltaDuration + existedLockDuration is greater then maxLockDuration=" + toString(maxLockDuration)))
618+ else {
619+ let coeffX8 = fraction(lockDurationNew, MULT8, maxLockDuration)
620+ let gWxAmountStart = fraction(userAmountNew, coeffX8, MULT8)
621+ let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
622+ if ((updateRefActivity == updateRefActivity))
623+ then {
624+ let lockStartNew = height
625+ let gWxParamsResultList = aal(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStartNew, lockDurationNew], nil))
626+ let k = ai(gWxParamsResultList[0])
627+ let b = ai(gWxParamsResultList[1])
628+ let period = toString(ai(gWxParamsResultList[2]))
629+ let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
630+ let emissionStart = iof(emissionContract, keyEmissionStartBlock())
631+ let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
632+ let h = if ((height > emissionEnd))
633+ then emissionEnd
634+ else height
635+ let dh = max([(h - emissionStart), 0])
636+ let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
637+ let userBoostEmissionLastIntegral = ioz(this, userBoostEmissionLastIntegralKEY)
638+ let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
639+ let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
640+ if ((0 > userBoostEmissionIntegral))
641+ then throw("wrong calculations")
642+ else {
643+ let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
644+ let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
645+ let userMaxBoostInt = ioz(this, userMaxBoostIntegralKEY)
646+ let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
647+ let currUserGwx = calcCurrentGwxAmount(userAddressStr)
648+ let gwxDiff = (gWxAmountStart - currUserGwx)
649+ if ((0 > gwxDiff))
650+ then throw(("gwxDiff is less then 0: " + toString(gwxDiff)))
651+ else {
652+ let totalCachedGwxRaw = getTotalCachedGwx(false)
653+ let totalCachedGwxCorrected = getTotalCachedGwx(true)
654+ let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
655+ let userBoostAvaliableToClaimTotal = ioz(this, userBoostAvalaibleToClaimTotalKEY)
656+ let userBoostAvaliableToClaimTotalNew = fraction(userBoostEmissionIntegral, currUserGwx, totalCachedGwxCorrected)
657+ let userMaxBoostIntNew = ((gWxAmountStart * lockDurationNew) / 2)
658+ let remainingUserMaxBoostInt = ((currUserGwx * remainingDuration) / 2)
659+ let userMaxBoostIntDiff = (userMaxBoostIntNew - remainingUserMaxBoostInt)
660+ (((LockParamsEntry(userAddressStr, userNumStr, userAmountNew, lockStartNew, lockDurationNew, k, b, period) ++ StatsEntry(pmtAmount, deltaDuration, 0, 0)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, lockDurationNew, k, b, i)) ++ [IntegerEntry(keyTotalCachedGwx(), (totalCachedGwxRaw + gwxDiff))])
661+ }
662+ }
663+ }
664+ else throw("Strict value is not equal to itself.")
665+ }
666+ }
667+
668+
669+
670+@Callable(i)
671+func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
672+ then throw("permissions denied")
673+ else {
674+ let $t03008930191 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
675+ let userBoostAvailable = $t03008930191._1
676+ let dataState = $t03008930191._2
677+ let debug = $t03008930191._3
678+ $Tuple2(dataState, [userBoostAvailable])
679+ }
680+
681+
682+
683+@Callable(i)
684+func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
685+ let $t03033030431 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
686+ let userBoostAvailable = $t03033030431._1
687+ let dataState = $t03033030431._2
688+ let debug = $t03033030431._3
689+ $Tuple2(nil, [userBoostAvailable, debug])
690+ }
691+
692+
693+
694+@Callable(i)
695+func unlock (userAddress) = {
696+ let userRecordArray = readLockParamsRecordOrFail(userAddress)
697+ let userNumStr = userRecordArray[IdxLockUserNum]
698+ let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
699+ let lockStart = parseIntValue(userRecordArray[IdxLockStart])
700+ let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
701+ let lockEnd = (lockStart + lockDuration)
702+ let cfgArray = readConfigArrayOrFail()
703+ let assetId = fromBase58String(cfgArray[IdxCfgAssetId])
704+ if ((lockEnd >= height))
705+ then throw((("wait " + toString(lockEnd)) + " to unlock"))
706+ else if ((0 >= userAmount))
707+ then throw("nothing to unlock")
708+ else {
709+ let period = valueOrElse(getInteger(mathContract, keyNextPeriod()), 0)
710+ (((LockParamsEntry(userAddress, userNumStr, 0, lockStart, lockDuration, 0, 0, toString(period)) ++ StatsEntry(-(userAmount), 0, 0, -1)) :+ HistoryEntry("unlock", userAddress, userAmount, lockStart, lockDuration, 0, 0, i)) :+ ScriptTransfer(addressFromStringValue(userAddress), userAmount, assetId))
711+ }
712+ }
713+
714+
715+
716+@Callable(i)
717+func gwxUserInfoREADONLY (userAddress) = {
718+ let gwxAmount = calcCurrentGwxAmount(userAddress)
719+ $Tuple2(nil, [gwxAmount])
720+ }
721+
722+
723+
724+@Callable(i)
725+func getUserGwxAmountAtHeightREADONLY (userAddress,targetHeight) = {
726+ let gwxAmount = calcUserGwxAmountAtHeight(userAddress, targetHeight)
727+ $Tuple2(nil, gwxAmount)
728+ }
729+
730+
731+
732+@Callable(i)
733+func getTotalCachedGwxREADONLY () = $Tuple2(nil, getTotalCachedGwx(true))
734+
735+
736+
737+@Callable(i)
738+func setManager (pendingManagerPublicKey) = {
739+ let checkCaller = mustManager(i)
740+ if ((checkCaller == checkCaller))
741+ then {
742+ let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
743+ if ((checkManagerPublicKey == checkManagerPublicKey))
744+ then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
745+ else throw("Strict value is not equal to itself.")
746+ }
747+ else throw("Strict value is not equal to itself.")
748+ }
749+
750+
751+
752+@Callable(i)
753+func confirmManager () = {
754+ let pm = pendingManagerPublicKeyOrUnit()
755+ let hasPM = if (isDefined(pm))
756+ then true
757+ else throw("No pending manager")
758+ if ((hasPM == hasPM))
759+ then {
760+ let checkPM = if ((i.callerPublicKey == value(pm)))
761+ then true
762+ else throw("You are not pending manager")
763+ if ((checkPM == checkPM))
764+ then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
765+ else throw("Strict value is not equal to itself.")
766+ }
767+ else throw("Strict value is not equal to itself.")
768+ }
769+
770+
771+@Verifier(tx)
772+func verify () = {
773+ let targetPublicKey = match managerPublicKeyOrUnit() {
774+ case pk: ByteVector =>
775+ pk
776+ case _: Unit =>
777+ tx.senderPublicKey
778+ case _ =>
779+ throw("Match error")
780+ }
781+ sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
782+ }
783+

github/deemru/w8io/873ac7e 
44.06 ms