tx · BKoL8Wv967ocXziaQT3jHBgvKETfnQ2JpjjBhR5pYFht

3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy:  -0.03700000 Waves

2025.02.11 17:47 [3499222] smart account 3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy > SELF 0.00000000 Waves

{ "type": 13, "id": "BKoL8Wv967ocXziaQT3jHBgvKETfnQ2JpjjBhR5pYFht", "fee": 3700000, "feeAssetId": null, "timestamp": 1739285287971, "version": 2, "chainId": 84, "sender": "3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy", "senderPublicKey": "9W33iCCNfmFxUbiC6XZcH5x7f6xfwC7Jb3BoExT5q2PV", "proofs": [ "Cf4xBuYEDneH8ubnPLS3GKpxCxoa3SAkw625X8fkHn4u8XusvvqQdPUqWo6iReXnP5q9nyt6iSNuidK1puEdhHK" ], "script": "base64:BgJfCAISCAoGCAgBAQEIEgUKAwEIAhIDCgEBEgMKAQESBAoCCAgSBAoCCAgSAwoBCBIDCgEIEgMKAQgSBAoCCAESABIAEgUKAwgIBBIDCgEIEgMKAQgSBAoCCAgSBAoCCAiMAQADU0VQAgJfXwAGU0NBTEU4AAgABU1VTFQ4AIDC1y8ADlBPT0xXRUlHSFRNVUxUBQVNVUxUOAAITE9OR19NQVgA//////////9/AQd3cmFwRXJyAQNtc2cJALkJAgkAzAgCAg5ib29zdGluZy5yaWRlOgkAzAgCBQNtc2cFA25pbAIBIAEIdGhyb3dFcnIBA21zZwkAAgEJAQd3cmFwRXJyAQUDbXNnAQRzdHJmAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFB2FkZHJlc3MFA2tleQkBB3dyYXBFcnIBCQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQNrZXkCDyBpcyBub3QgZGVmaW5lZAEDaW96AgdhZGRyZXNzA2tleQkBC3ZhbHVlT3JFbHNlAgkAmggCBQdhZGRyZXNzBQNrZXkAAAEDaW9kAwdhZGRyZXNzA2tleQpkZWZhdWx0VmFsCQELdmFsdWVPckVsc2UCCQCaCAIFB2FkZHJlc3MFA2tleQUKZGVmYXVsdFZhbAEDaW9mAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFB2FkZHJlc3MFA2tleQkBB3dyYXBFcnIBCQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQNrZXkCDyBpcyBub3QgZGVmaW5lZAEDYWJzAQN2YWwDCQBmAgAABQN2YWwJAQEtAQUDdmFsBQN2YWwBA2FhbAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIJTGlzdFtBbnldBAp2YWxBbnlMeXN0BQckbWF0Y2gwBQp2YWxBbnlMeXN0CQEIdGhyb3dFcnIBAhtmYWlsIHRvIGNhc3QgaW50byBMaXN0W0FueV0BAmFpAQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAgNJbnQEBnZhbEludAUHJG1hdGNoMAUGdmFsSW50CQEIdGhyb3dFcnIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBG2tleVJlZmVycmFsc0NvbnRyYWN0QWRkcmVzcwAJALkJAgkAzAgCAgQlcyVzCQDMCAICBmNvbmZpZwkAzAgCAhhyZWZlcnJhbHNDb250cmFjdEFkZHJlc3MFA25pbAUDU0VQAB5yZWZlcnJhbHNDb250cmFjdEFkZHJlc3NPckZhaWwJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQRzdHJmAgUEdGhpcwkBG2tleVJlZmVycmFsc0NvbnRyYWN0QWRkcmVzcwAAFmtleVJlZmVycmFsUHJvZ3JhbU5hbWUJALkJAgkAzAgCAgQlcyVzCQDMCAICCHJlZmVycmFsCQDMCAICC3Byb2dyYW1OYW1lBQNuaWwFA1NFUAAacmVmZXJyYWxQcm9ncmFtTmFtZURlZmF1bHQCBnd4bG9jawATcmVmZXJyYWxQcm9ncmFtTmFtZQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBRZrZXlSZWZlcnJhbFByb2dyYW1OYW1lBRpyZWZlcnJhbFByb2dyYW1OYW1lRGVmYXVsdAERa2V5RmFjdG9yeUFkZHJlc3MAAhwlcyVzX19jb25maWdfX2ZhY3RvcnlBZGRyZXNzABhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHAAAQAZSWR4RmFjdG9yeUNmZ0Jvb3N0aW5nRGFwcAACABRJZHhGYWN0b3J5Q2ZnSWRvRGFwcAADABVJZHhGYWN0b3J5Q2ZnVGVhbURhcHAABAAZSWR4RmFjdG9yeUNmZ0VtaXNzaW9uRGFwcAAFABVJZHhGYWN0b3J5Q2ZnUmVzdERhcHAABgAZSWR4RmFjdG9yeUNmZ1NsaXBwYWdlRGFwcAAHABRJZHhGYWN0b3J5Q2ZnRGFvRGFwcAAIABpJZHhGYWN0b3J5Q2ZnTWFya2V0aW5nRGFwcAAJABpJZHhGYWN0b3J5Q2ZnR3d4UmV3YXJkRGFwcAAKABZJZHhGYWN0b3J5Q2ZnQmlyZHNEYXBwAAsBDWtleUZhY3RvcnlDZmcAAhElc19fZmFjdG9yeUNvbmZpZwEQa2V5RmFjdG9yeUxwTGlzdAACECVzX19scFRva2Vuc0xpc3QBJmtleUZhY3RvcnlMcEFzc2V0VG9Qb29sQ29udHJhY3RBZGRyZXNzAQpscEFzc2V0U3RyCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCmxwQXNzZXRTdHIJAMwIAgIebWFwcGluZ3NfX2xwQXNzZXQyUG9vbENvbnRyYWN0BQNuaWwFA1NFUAEUa2V5RmFjdG9yeVBvb2xXZWlnaHQBD2NvbnRyYWN0QWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIKcG9vbFdlaWdodAkAzAgCBQ9jb250cmFjdEFkZHJlc3MFA25pbAUDU0VQARtrZXlGYWN0b3J5UG9vbFdlaWdodEhpc3RvcnkCC3Bvb2xBZGRyZXNzA251bQkArAICCQCsAgIJAKwCAgISJXMlc19fcG9vbFdlaWdodF9fBQtwb29sQWRkcmVzcwICX18JAKQDAQUDbnVtARhyZWFkRmFjdG9yeUFkZHJlc3NPckZhaWwACQERQGV4dHJOYXRpdmUoMTA2MikBCQEEc3RyZgIFBHRoaXMJARFrZXlGYWN0b3J5QWRkcmVzcwABCnJlYWRMcExpc3QACQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgkBGHJlYWRGYWN0b3J5QWRkcmVzc09yRmFpbAAJARBrZXlGYWN0b3J5THBMaXN0AAIABQNTRVABFHJlYWRGYWN0b3J5Q2ZnT3JGYWlsAQdmYWN0b3J5CQC1CQIJAQRzdHJmAgUHZmFjdG9yeQkBDWtleUZhY3RvcnlDZmcABQNTRVABGGdldEJvb3N0aW5nQWRkcmVzc09yRmFpbAEKZmFjdG9yeUNmZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQpmYWN0b3J5Q2ZnBRlJZHhGYWN0b3J5Q2ZnQm9vc3RpbmdEYXBwARhnZXRFbWlzc2lvbkFkZHJlc3NPckZhaWwBCmZhY3RvcnlDZmcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUKZmFjdG9yeUNmZwUZSWR4RmFjdG9yeUNmZ0VtaXNzaW9uRGFwcAEXZ2V0U3Rha2luZ0FkZHJlc3NPckZhaWwBCmZhY3RvcnlDZmcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUKZmFjdG9yeUNmZwUYSWR4RmFjdG9yeUNmZ1N0YWtpbmdEYXBwARlnZXRHd3hSZXdhcmRBZGRyZXNzT3JGYWlsAQpmYWN0b3J5Q2ZnCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFCmZhY3RvcnlDZmcFGklkeEZhY3RvcnlDZmdHd3hSZXdhcmREYXBwARNrZXlNYW5hZ2VyUHVibGljS2V5AAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBFmtleU1hbmFnZXJWYXVsdEFkZHJlc3MAAhclc19fbWFuYWdlclZhdWx0QWRkcmVzcwEea2V5RW1pc3Npb25SYXRlUGVyQmxvY2tDdXJyZW50AAIbJXMlc19fcmF0ZVBlckJsb2NrX19jdXJyZW50ASFrZXlFbWlzc2lvblJhdGVQZXJCbG9ja01heEN1cnJlbnQAAh4lcyVzX19yYXRlUGVyQmxvY2tNYXhfX2N1cnJlbnQBFWtleUVtaXNzaW9uU3RhcnRCbG9jawACGiVzJXNfX2VtaXNzaW9uX19zdGFydEJsb2NrAR1rZXlCb29zdGluZ1YyTGFzdFVwZGF0ZUhlaWdodAACHCVzJXNfX2Jvb3N0aW5nVjJfX3N0YXJ0QmxvY2sBFWtleUJvb3N0aW5nVjJJbnRlZ3JhbAACGiVzJXNfX2Jvb3N0aW5nVjJfX2ludGVncmFsARtrZXlFbWlzc2lvbkR1cmF0aW9uSW5CbG9ja3MAAhglcyVzX19lbWlzc2lvbl9fZHVyYXRpb24BE2tleUVtaXNzaW9uRW5kQmxvY2sAAhglcyVzX19lbWlzc2lvbl9fZW5kQmxvY2sBDWtleU5leHRQZXJpb2QAAg4lc19fbmV4dFBlcmlvZAEfa2V5R3d4UmV3YXJkRW1pc3Npb25TdGFydEhlaWdodAACKCVzJXNfX2d3eFJld2FyZEVtaXNzaW9uUGFydF9fc3RhcnRIZWlnaHQADUlkeENmZ0Fzc2V0SWQAAQATSWR4Q2ZnTWluTG9ja0Ftb3VudAACABVJZHhDZmdNaW5Mb2NrRHVyYXRpb24AAwAVSWR4Q2ZnTWF4TG9ja0R1cmF0aW9uAAQAEklkeENmZ01hdGhDb250cmFjdAAFAQlrZXlDb25maWcAAgolc19fY29uZmlnARVyZWFkQ29uZmlnQXJyYXlPckZhaWwACQC1CQIJAQRzdHJmAgUEdGhpcwkBCWtleUNvbmZpZwAFA1NFUAAMbWF0aENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIJARVyZWFkQ29uZmlnQXJyYXlPckZhaWwABRJJZHhDZmdNYXRoQ29udHJhY3QBDWZvcm1hdENvbmZpZ1MFB2Fzc2V0SWQNbWluTG9ja0Ftb3VudA9taW5Mb2NrRHVyYXRpb24PbWF4TG9ja0R1cmF0aW9uDG1hdGhDb250cmFjdAkAuQkCCQDMCAICCCVzJWQlZCVkCQDMCAIFB2Fzc2V0SWQJAMwIAgUNbWluTG9ja0Ftb3VudAkAzAgCBQ9taW5Mb2NrRHVyYXRpb24JAMwIAgUPbWF4TG9ja0R1cmF0aW9uCQDMCAIFDG1hdGhDb250cmFjdAUDbmlsBQNTRVABDGZvcm1hdENvbmZpZwUHYXNzZXRJZA1taW5Mb2NrQW1vdW50D21pbkxvY2tEdXJhdGlvbg9tYXhMb2NrRHVyYXRpb24MbWF0aENvbnRyYWN0CQENZm9ybWF0Q29uZmlnUwUFB2Fzc2V0SWQJAKQDAQUNbWluTG9ja0Ftb3VudAkApAMBBQ9taW5Mb2NrRHVyYXRpb24JAKQDAQUPbWF4TG9ja0R1cmF0aW9uBQxtYXRoQ29udHJhY3QBHGdldE1hbmFnZXJWYXVsdEFkZHJlc3NPclRoaXMABAckbWF0Y2gwCQCiCAEJARZrZXlNYW5hZ2VyVmF1bHRBZGRyZXNzAAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAXMFBHRoaXMBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQABBNtYW5hZ2VyVmF1bHRBZGRyZXNzCQEcZ2V0TWFuYWdlclZhdWx0QWRkcmVzc09yVGhpcwAEByRtYXRjaDAJAJ0IAgUTbWFuYWdlclZhdWx0QWRkcmVzcwkBE2tleU1hbmFnZXJQdWJsaWNLZXkAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgELbXVzdE1hbmFnZXIBAWkEAnBkCQEIdGhyb3dFcnIBAhFQZXJtaXNzaW9uIGRlbmllZAQHJG1hdGNoMAkBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQAAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAnBrBQckbWF0Y2gwAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQUCcGsGBQJwZAMJAAECBQckbWF0Y2gwAgRVbml0AwkAAAIIBQFpBmNhbGxlcgUEdGhpcwYFAnBkCQACAQILTWF0Y2ggZXJyb3IADklkeExvY2tVc2VyTnVtAAEADUlkeExvY2tBbW91bnQAAgAMSWR4TG9ja1N0YXJ0AAMAD0lkeExvY2tEdXJhdGlvbgAEAA1JZHhMb2NrUGFyYW1LAAUADUlkeExvY2tQYXJhbUIABgETa2V5TG9ja1BhcmFtc1JlY29yZAELdXNlckFkZHJlc3MJALkJAgkAzAgCAgolcyVzX19sb2NrCQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAEacmVhZExvY2tQYXJhbXNSZWNvcmRPckZhaWwBC3VzZXJBZGRyZXNzCQC1CQIJAQRzdHJmAgUEdGhpcwkBE2tleUxvY2tQYXJhbXNSZWNvcmQBBQt1c2VyQWRkcmVzcwUDU0VQARdmb3JtYXRMb2NrUGFyYW1zUmVjb3JkUwgHdXNlck51bQZhbW91bnQFc3RhcnQIZHVyYXRpb24GcGFyYW1LBnBhcmFtQhBsYXN0VXBkVGltZXN0YW1wCWd3eEFtb3VudAkAuQkCCQDMCAICECVkJWQlZCVkJWQlZCVkJWQJAMwIAgUHdXNlck51bQkAzAgCBQZhbW91bnQJAMwIAgUFc3RhcnQJAMwIAgUIZHVyYXRpb24JAMwIAgUGcGFyYW1LCQDMCAIFBnBhcmFtQgkAzAgCBRBsYXN0VXBkVGltZXN0YW1wCQDMCAIFCWd3eEFtb3VudAUDbmlsBQNTRVABFmZvcm1hdExvY2tQYXJhbXNSZWNvcmQHB3VzZXJOdW0GYW1vdW50BXN0YXJ0CGR1cmF0aW9uBnBhcmFtSwZwYXJhbUIJZ3d4QW1vdW50CQEXZm9ybWF0TG9ja1BhcmFtc1JlY29yZFMIBQd1c2VyTnVtCQCkAwEFBmFtb3VudAkApAMBBQVzdGFydAkApAMBBQhkdXJhdGlvbgkApAMBBQZwYXJhbUsJAKQDAQUGcGFyYW1CCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQCkAwEFCWd3eEFtb3VudAEOa2V5TmV4dFVzZXJOdW0AAg8lc19fbmV4dFVzZXJOdW0BEmtleVVzZXIyTnVtTWFwcGluZwELdXNlckFkZHJlc3MJALkJAgkAzAgCAhklcyVzJXNfX21hcHBpbmdfX3VzZXIybnVtCQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAESa2V5TnVtMlVzZXJNYXBwaW5nAQNudW0JALkJAgkAzAgCAhklcyVzJXNfX21hcHBpbmdfX251bTJ1c2VyCQDMCAIFA251bQUDbmlsBQNTRVABFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBB3VzZXJOdW0JALkJAgkAzAgCAhYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQDMCAIFB3VzZXJOdW0JAMwIAgIGYW1vdW50BQNuaWwFA1NFUAEWa2V5TG9ja1BhcmFtU3RhcnRCbG9jawEHdXNlck51bQkAuQkCCQDMCAICFiVzJWQlc19fcGFyYW1CeVVzZXJOdW0JAMwIAgUHdXNlck51bQkAzAgCAgVzdGFydAUDbmlsBQNTRVABFGtleUxvY2tQYXJhbUR1cmF0aW9uAQd1c2VyTnVtCQC5CQIJAMwIAgIWJXMlZCVzX19wYXJhbUJ5VXNlck51bQkAzAgCBQd1c2VyTnVtCQDMCAICCGR1cmF0aW9uBQNuaWwFA1NFUAENa2V5TG9ja1BhcmFtSwEHdXNlck51bQkAuQkCCQDMCAICFiVzJWQlc19fcGFyYW1CeVVzZXJOdW0JAMwIAgUHdXNlck51bQkAzAgCAgFrBQNuaWwFA1NFUAENa2V5TG9ja1BhcmFtQgEHdXNlck51bQkAuQkCCQDMCAICFiVzJWQlc19fcGFyYW1CeVVzZXJOdW0JAMwIAgUHdXNlck51bQkAzAgCAgFiBQNuaWwFA1NFUAEVa2V5TG9ja1BhcmFtQnlQZXJpb2RLAgd1c2VyTnVtBnBlcmlvZAkAuQkCCQDMCAICFyVzJWQlcyVkX19wYXJhbUJ5UGVyaW9kCQDMCAIFB3VzZXJOdW0JAMwIAgIBawkAzAgCBQZwZXJpb2QFA25pbAUDU0VQARVrZXlMb2NrUGFyYW1CeVBlcmlvZEICB3VzZXJOdW0GcGVyaW9kCQC5CQIJAMwIAgIXJXMlZCVzJWRfX3BhcmFtQnlQZXJpb2QJAMwIAgUHdXNlck51bQkAzAgCAgFiCQDMCAIFBnBlcmlvZAUDbmlsBQNTRVABF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAIeJXMlc19fc3RhdHNfX2FjdGl2ZVRvdGFsTG9ja2VkASBrZXlTdGF0c0xvY2tzRHVyYXRpb25TdW1JbkJsb2NrcwACJSVzJXNfX3N0YXRzX19sb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MBEmtleVN0YXRzTG9ja3NDb3VudAACFyVzJXNfX3N0YXRzX19sb2Nrc0NvdW50ARJrZXlTdGF0c1VzZXJzQ291bnQAAh0lcyVzX19zdGF0c19fYWN0aXZlVXNlcnNDb3VudAEga2V5VXNlckJvb3N0RW1pc3Npb25MYXN0SU5URUdSQUwBB3VzZXJOdW0JALkJAgkAzAgCAiAlcyVkX191c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRWMgkAzAgCBQd1c2VyTnVtBQNuaWwFA1NFUAEia2V5VXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAIHdXNlck51bQlscEFzc2V0SWQJALkJAgkAzAgCAiAlcyVkX191c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRWMgkAzAgCBQd1c2VyTnVtCQDMCAIFCWxwQXNzZXRJZAUDbmlsBQNTRVABF2tleVVzZXJNYXhCb29zdElOVEVHUkFMAQd1c2VyTnVtCQC5CQIJAMwIAgIRJXMlZF9fbWF4Qm9vc3RJbnQJAMwIAgUHdXNlck51bQUDbmlsBQNTRVABGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAACGCVzJXNfX21heEJvb3N0SW50X190b3RhbAEha2V5VXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsAQd1c2VyTnVtCQC5CQIJAMwIAgIkJXMlZF9fdXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsCQDMCAIFB3VzZXJOdW0FA25pbAUDU0VQARNrZXlVc2VyQm9vc3RDbGFpbWVkAQd1c2VyTnVtCQC5CQIJAMwIAgIWJXMlZF9fdXNlckJvb3N0Q2xhaW1lZAkAzAgCBQd1c2VyTnVtBQNuaWwFA1NFUAERa2V5VG90YWxDYWNoZWRHd3gAAhYlcyVzX19nd3hDYWNoZWRfX3RvdGFsARtrZXlUb3RhbENhY2hlZEd3eENvcnJlY3RpdmUAAhwlc19fZ3d4Q2FjaGVkVG90YWxDb3JyZWN0aXZlAQdrZXlWb3RlBA1hbW91bnRBc3NldElkDHByaWNlQXNzZXRJZAdhZGRyZXNzBWVwb2NoCQC5CQIJAMwIAgIKJXMlcyVzJXMlZAkAzAgCAgR2b3RlCQDMCAIFDWFtb3VudEFzc2V0SWQJAMwIAgUMcHJpY2VBc3NldElkCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCCQCkAwEFBWVwb2NoBQNuaWwFA1NFUAEVa2V5U3RhcnRIZWlnaHRCeUVwb2NoAQVlcG9jaAkAuQkCCQDMCAICBCVzJWQJAMwIAgILc3RhcnRIZWlnaHQJAMwIAgkApAMBBQVlcG9jaAUDbmlsBQNTRVABEWtleUN1cnJlbnRFcG9jaFVpAAkAuQkCCQDMCAICAiVzCQDMCAICDmN1cnJlbnRFcG9jaFVpBQNuaWwFA1NFUAEVa2V5Vm90aW5nUmVzdWx0U3Rha2VkAgxscEFzc2V0SWRTdHIFZXBvY2gJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgISdm90aW5nUmVzdWx0U3Rha2VkCQDMCAIFDGxwQXNzZXRJZFN0cgkAzAgCCQCkAwEFBWVwb2NoBQNuaWwFA1NFUAEda2V5Vm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwCDGxwQXNzZXRJZFN0cgVlcG9jaAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAhp2b3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbAkAzAgCBQxscEFzc2V0SWRTdHIJAMwIAgkApAMBBQVlcG9jaAUDbmlsBQNTRVABJWtleVZvdGluZ1Jlc3VsdFN0YWtlZExhc3RVcGRhdGVIZWlnaHQCDGxwQXNzZXRJZFN0cgVlcG9jaAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAip2b3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbExhc3RVcGRhdGVIZWlnaHQJAMwIAgUMbHBBc3NldElkU3RyCQDMCAIJAKQDAQUFZXBvY2gFA25pbAUDU0VQASFrZXlWb3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbExhc3QDDGxwQXNzZXRJZFN0cgdhZGRyZXNzBWVwb2NoCQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIedm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWxMYXN0CQDMCAIFDGxwQXNzZXRJZFN0cgkAzAgCCQClCAEFB2FkZHJlc3MJAMwIAgkApAMBBQVlcG9jaAUDbmlsBQNTRVABFWtleVZvdGVTdGFrZWRJbnRlZ3JhbAMMbHBBc3NldElkU3RyB2FkZHJlc3MFZXBvY2gJALkJAgkAzAgCAgglcyVzJXMlZAkAzAgCAhJ2b3RlU3Rha2VkSW50ZWdyYWwJAMwIAgUMbHBBc3NldElkU3RyCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCCQCkAwEFBWVwb2NoBQNuaWwFA1NFUAEda2V5Vm90ZVN0YWtlZExhc3RVcGRhdGVIZWlnaHQDDGxwQXNzZXRJZFN0cgdhZGRyZXNzBWVwb2NoCQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIidm90ZVN0YWtlZEludGVncmFsTGFzdFVwZGF0ZUhlaWdodAkAzAgCBQxscEFzc2V0SWRTdHIJAMwIAgkApQgBBQdhZGRyZXNzCQDMCAIJAKQDAQUFZXBvY2gFA25pbAUDU0VQARlrZXlWb3RlU3Rha2VkSW50ZWdyYWxMYXN0AwxscEFzc2V0SWRTdHIHYWRkcmVzcwVlcG9jaAkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICFnZvdGVTdGFrZWRJbnRlZ3JhbExhc3QJAMwIAgUMbHBBc3NldElkU3RyCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCCQCkAwEFBWVwb2NoBQNuaWwFA1NFUAEPa2V5U3Rha2VkQnlVc2VyAg51c2VyQWRkcmVzc1N0cgxscEFzc2V0SWRTdHIJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIGc3Rha2VkCQDMCAIFDnVzZXJBZGRyZXNzU3RyCQDMCAIFDGxwQXNzZXRJZFN0cgUDbmlsBQNTRVAAD2ZhY3RvcnlDb250cmFjdAkBGHJlYWRGYWN0b3J5QWRkcmVzc09yRmFpbAAACmZhY3RvcnlDZmcJARRyZWFkRmFjdG9yeUNmZ09yRmFpbAEFD2ZhY3RvcnlDb250cmFjdAAQZW1pc3Npb25Db250cmFjdAkBGGdldEVtaXNzaW9uQWRkcmVzc09yRmFpbAEFCmZhY3RvcnlDZmcAD3N0YWtpbmdDb250cmFjdAkBF2dldFN0YWtpbmdBZGRyZXNzT3JGYWlsAQUKZmFjdG9yeUNmZwARZ3d4UmV3YXJkQ29udHJhY3QJARlnZXRHd3hSZXdhcmRBZGRyZXNzT3JGYWlsAQUKZmFjdG9yeUNmZwAWbHBTdGFraW5nUG9vbHNDb250cmFjdAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQC5CQIJAMwIAgICJXMJAMwIAgIWbHBTdGFraW5nUG9vbHNDb250cmFjdAUDbmlsBQNTRVAJAQd3cmFwRXJyAQIubHBfc3Rha2luZ19wb29scyBjb250cmFjdCBhZGRyZXNzIGlzIHVuZGVmaW5lZAkBB3dyYXBFcnIBAilpbnZhbGlkIGxwX3N0YWtpbmdfcG9vbHMgY29udHJhY3QgYWRkcmVzcwAZa2V5Vm90aW5nRW1pc3Npb25Db250cmFjdAkAuQkCCQDMCAICAiVzCQDMCAICFnZvdGluZ0VtaXNzaW9uQ29udHJhY3QFA25pbAUDU0VQABZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQERQGV4dHJOYXRpdmUoMTA1MykCBQ9mYWN0b3J5Q29udHJhY3QFGWtleVZvdGluZ0VtaXNzaW9uQ29udHJhY3QACmJvb3N0Q29lZmYKAAFACQD8BwQFEGVtaXNzaW9uQ29udHJhY3QCFWdldEJvb3N0Q29lZmZSRUFET05MWQUDbmlsBQNuaWwDCQABAgUBQAIDSW50BQFACQACAQkArAICCQADAQUBQAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50ARFnZXRUb3RhbENhY2hlZEd3eAEHY29ycmVjdAQOY3VycmVudEVwb2NoVWkJARFAZXh0ck5hdGl2ZSgxMDUwKQIFFnZvdGluZ0VtaXNzaW9uQ29udHJhY3QJARFrZXlDdXJyZW50RXBvY2hVaQAEDmtleVRhcmdldEVwb2NoCQC5CQIJAMwIAgIEJXMlcwkAzAgCAil0b3RhbENhY2hlZEd3eENvcnJlY3Rpb25fX2FjdGl2YXRpb25FcG9jaAUDbmlsBQNTRVAEEXRhcmdldEVwb2NoT3B0aW9uCQCaCAIFBHRoaXMFDmtleVRhcmdldEVwb2NoBBF0b3RhbENhY2hlZEd3eFJhdwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQERa2V5VG90YWxDYWNoZWRHd3gAAAAEFWlzQ29ycmVjdGlvbkFjdGl2YXRlZAMJAQlpc0RlZmluZWQBBRF0YXJnZXRFcG9jaE9wdGlvbgkAZwIFDmN1cnJlbnRFcG9jaFVpCQEFdmFsdWUBBRF0YXJnZXRFcG9jaE9wdGlvbgcECmNvcnJlY3RpdmUDAwUVaXNDb3JyZWN0aW9uQWN0aXZhdGVkBQdjb3JyZWN0BwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEba2V5VG90YWxDYWNoZWRHd3hDb3JyZWN0aXZlAAAAAAAJAJYDAQkAzAgCAAAJAMwIAgkAZAIFEXRvdGFsQ2FjaGVkR3d4UmF3BQpjb3JyZWN0aXZlBQNuaWwBDEhpc3RvcnlFbnRyeQgEdHlwZQR1c2VyBmFtb3VudAlsb2NrU3RhcnQIZHVyYXRpb24BawFiAWkECmhpc3RvcnlLRVkJALkJAgkAzAgCAhElcyVzJXMlc19faGlzdG9yeQkAzAgCBQR0eXBlCQDMCAIFBHVzZXIJAMwIAgkA2AQBCAUBaQ10cmFuc2FjdGlvbklkBQNuaWwFA1NFUAQLaGlzdG9yeURBVEEJALkJAgkAzAgCAg4lZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkApAMBBQZhbW91bnQJAMwIAgkApAMBBQlsb2NrU3RhcnQJAMwIAgkApAMBBQhkdXJhdGlvbgkAzAgCCQCkAwEFAWsJAMwIAgkApAMBBQFiBQNuaWwFA1NFUAkBC1N0cmluZ0VudHJ5AgUKaGlzdG9yeUtFWQULaGlzdG9yeURBVEEBClN0YXRzRW50cnkEDnRvdGFsTG9ja2VkSW5jC2R1cmF0aW9uSW5jDGxvY2tDb3VudEluYw11c2Vyc0NvdW50SW5jBBtsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3NLRVkJASBrZXlTdGF0c0xvY2tzRHVyYXRpb25TdW1JbkJsb2NrcwAEDWxvY2tzQ291bnRLRVkJARJrZXlTdGF0c0xvY2tzQ291bnQABA11c2Vyc0NvdW50S0VZCQESa2V5U3RhdHNVc2Vyc0NvdW50AAQOdG90YWxBbW91bnRLRVkJARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAEGGxvY2tzRHVyYXRpb25TdW1JbkJsb2NrcwkBA2lvegIFBHRoaXMFG2xvY2tzRHVyYXRpb25TdW1JbkJsb2Nrc0tFWQQKbG9ja3NDb3VudAkBA2lvegIFBHRoaXMFDWxvY2tzQ291bnRLRVkECnVzZXJzQ291bnQJAQNpb3oCBQR0aGlzBQ11c2Vyc0NvdW50S0VZBAt0b3RhbEFtb3VudAkBA2lvegIFBHRoaXMFDnRvdGFsQW1vdW50S0VZCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRtsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3NLRVkJAGQCBRhsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MFC2R1cmF0aW9uSW5jCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ1sb2Nrc0NvdW50S0VZCQBkAgUKbG9ja3NDb3VudAUMbG9ja0NvdW50SW5jCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ11c2Vyc0NvdW50S0VZCQBkAgUKdXNlcnNDb3VudAUNdXNlcnNDb3VudEluYwkAzAgCCQEMSW50ZWdlckVudHJ5AgUOdG90YWxBbW91bnRLRVkJAGQCBQt0b3RhbEFtb3VudAUOdG90YWxMb2NrZWRJbmMFA25pbAENY2FsY0d3eEFtb3VudAMEa1JhdwRiUmF3AWgEBVNDQUxFAOgHCQBpAgkAZAIJAGgCBQRrUmF3BQFoBQRiUmF3BQVTQ0FMRQEPTG9ja1BhcmFtc0VudHJ5CAt1c2VyQWRkcmVzcwd1c2VyTnVtBmFtb3VudAVzdGFydAhkdXJhdGlvbgFrAWIGcGVyaW9kBA11c2VyQW1vdW50S0VZCQEWa2V5TG9ja1BhcmFtVXNlckFtb3VudAEFB3VzZXJOdW0EDXN0YXJ0QmxvY2tLRVkJARZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAQUHdXNlck51bQQLZHVyYXRpb25LRVkJARRrZXlMb2NrUGFyYW1EdXJhdGlvbgEFB3VzZXJOdW0EBGtLRVkJAQ1rZXlMb2NrUGFyYW1LAQUHdXNlck51bQQEYktFWQkBDWtleUxvY2tQYXJhbUIBBQd1c2VyTnVtBAxrQnlQZXJpb2RLRVkJARVrZXlMb2NrUGFyYW1CeVBlcmlvZEsCBQd1c2VyTnVtBQZwZXJpb2QEDGJCeVBlcmlvZEtFWQkBFWtleUxvY2tQYXJhbUJ5UGVyaW9kQgIFB3VzZXJOdW0FBnBlcmlvZAQJZ3d4QW1vdW50CQENY2FsY0d3eEFtb3VudAMFAWsFAWIFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUNdXNlckFtb3VudEtFWQUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ1zdGFydEJsb2NrS0VZBQVzdGFydAkAzAgCCQEMSW50ZWdlckVudHJ5AgULZHVyYXRpb25LRVkFCGR1cmF0aW9uCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQRrS0VZBQFrCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQRiS0VZBQFiCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQxrQnlQZXJpb2RLRVkFAWsJAMwIAgkBDEludGVnZXJFbnRyeQIFDGJCeVBlcmlvZEtFWQUBYgkAzAgCCQELU3RyaW5nRW50cnkCCQETa2V5TG9ja1BhcmFtc1JlY29yZAEFC3VzZXJBZGRyZXNzCQEWZm9ybWF0TG9ja1BhcmFtc1JlY29yZAcFB3VzZXJOdW0FBmFtb3VudAUFc3RhcnQFCGR1cmF0aW9uBQFrBQFiBQlnd3hBbW91bnQFA25pbAEiZXh0cmFjdE9wdGlvbmFsUGF5bWVudEFtb3VudE9yRmFpbAIBaQ9leHBlY3RlZEFzc2V0SWQDCQBmAgkAkAMBCAUBaQhwYXltZW50cwABCQEIdGhyb3dFcnIBAhtvbmx5IG9uZSBwYXltZW50IGlzIGFsbG93ZWQDCQAAAgkAkAMBCAUBaQhwYXltZW50cwAAAAAEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkBQ9leHBlY3RlZEFzc2V0SWQJAQh0aHJvd0VycgECG2ludmFsaWQgYXNzZXQgaWQgaW4gcGF5bWVudAgFA3BtdAZhbW91bnQBGWNhbGNVc2VyR3d4QW1vdW50QXRIZWlnaHQCC3VzZXJBZGRyZXNzDHRhcmdldEhlaWdodAQFRU1QVFkCBWVtcHR5BBJ1c2VyMk51bU1hcHBpbmdLRVkJARJrZXlVc2VyMk51bU1hcHBpbmcBBQt1c2VyQWRkcmVzcwQHdXNlck51bQkBC3ZhbHVlT3JFbHNlAgkAoggBBRJ1c2VyMk51bU1hcHBpbmdLRVkFBUVNUFRZBAFrCQELdmFsdWVPckVsc2UCCQCfCAEJAQ1rZXlMb2NrUGFyYW1LAQUHdXNlck51bQAABAFiCQELdmFsdWVPckVsc2UCCQCfCAEJAQ1rZXlMb2NrUGFyYW1CAQUHdXNlck51bQAABA1nd3hBbW91bnRDYWxjCQENY2FsY0d3eEFtb3VudAMFAWsFAWIFDHRhcmdldEhlaWdodAQJZ3d4QW1vdW50AwkAZgIAAAUNZ3d4QW1vdW50Q2FsYwAABQ1nd3hBbW91bnRDYWxjBQlnd3hBbW91bnQBFGNhbGNDdXJyZW50R3d4QW1vdW50AQt1c2VyQWRkcmVzcwkBGWNhbGNVc2VyR3d4QW1vdW50QXRIZWlnaHQCBQt1c2VyQWRkcmVzcwUGaGVpZ2h0ARpnZXRWb3RpbmdFbWlzc2lvbkVwb2NoSW5mbwAEDSR0MDE3ODY0MTgxNTQEDmN1cnJlbnRFcG9jaFVpCQEFdmFsdWUBCQCaCAIFFnZvdGluZ0VtaXNzaW9uQ29udHJhY3QJARFrZXlDdXJyZW50RXBvY2hVaQAEEmxhc3RGaW5hbGl6ZWRFcG9jaAkAZQIFDmN1cnJlbnRFcG9jaFVpAAEDCQBmAgAABRJsYXN0RmluYWxpemVkRXBvY2gJAQh0aHJvd0VycgECDWludmFsaWQgZXBvY2gJAJQKAgUOY3VycmVudEVwb2NoVWkFEmxhc3RGaW5hbGl6ZWRFcG9jaAQOY3VycmVudEVwb2NoVWkIBQ0kdDAxNzg2NDE4MTU0Al8xBBJsYXN0RmluYWxpemVkRXBvY2gIBQ0kdDAxNzg2NDE4MTU0Al8yBBdjdXJyZW50RXBvY2hTdGFydEhlaWdodAkBBXZhbHVlAQkAmggCBRZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0CQEVa2V5U3RhcnRIZWlnaHRCeUVwb2NoAQUOY3VycmVudEVwb2NoVWkJAJQKAgUSbGFzdEZpbmFsaXplZEVwb2NoBRdjdXJyZW50RXBvY2hTdGFydEhlaWdodAEYZ2V0UG9vbEFzc2V0c0J5THBBc3NldElkAQxscEFzc2V0SWRTdHIEEGlkeEFtb3VudEFzc2V0SWQABAQPaWR4UHJpY2VBc3NldElkAAUEB3Bvb2xDZmcKAAFACQD8BwQFD2ZhY3RvcnlDb250cmFjdAIgZ2V0UG9vbENvbmZpZ0J5THBBc3NldElkUkVBRE9OTFkJAMwIAgUMbHBBc3NldElkU3RyBQNuaWwFA25pbAMJAAECBQFAAglMaXN0W0FueV0FAUAJAAIBCQCsAgIJAAMBBQFAAh4gY291bGRuJ3QgYmUgY2FzdCB0byBMaXN0W0FueV0EDWFtb3VudEFzc2V0SWQKAAFACQCRAwIFB3Bvb2xDZmcFEGlkeEFtb3VudEFzc2V0SWQDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nBAxwcmljZUFzc2V0SWQKAAFACQCRAwIFB3Bvb2xDZmcFD2lkeFByaWNlQXNzZXRJZAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBBQFAAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcJAJQKAgUNYW1vdW50QXNzZXRJZAUMcHJpY2VBc3NldElkARRnZXRVc2VyVm90ZUZpbmFsaXplZAIMbHBBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyBAt1c2VyQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQUOdXNlckFkZHJlc3NTdHIEDSR0MDE4ODQ1MTg5MjUJARpnZXRWb3RpbmdFbWlzc2lvbkVwb2NoSW5mbwAEEmxhc3RGaW5hbGl6ZWRFcG9jaAgFDSR0MDE4ODQ1MTg5MjUCXzEEF2N1cnJlbnRFcG9jaFN0YXJ0SGVpZ2h0CAUNJHQwMTg4NDUxODkyNQJfMgQNJHQwMTg5MjgxOTAwMwkBGGdldFBvb2xBc3NldHNCeUxwQXNzZXRJZAEFDGxwQXNzZXRJZFN0cgQNYW1vdW50QXNzZXRJZAgFDSR0MDE4OTI4MTkwMDMCXzEEDHByaWNlQXNzZXRJZAgFDSR0MDE4OTI4MTkwMDMCXzIEC3VzZXJWb3RlS2V5CQEHa2V5Vm90ZQQFDWFtb3VudEFzc2V0SWQFDHByaWNlQXNzZXRJZAULdXNlckFkZHJlc3MFEmxhc3RGaW5hbGl6ZWRFcG9jaAQIdXNlclZvdGUJAQt2YWx1ZU9yRWxzZQIJAJoIAgUWdm90aW5nRW1pc3Npb25Db250cmFjdAULdXNlclZvdGVLZXkAAAUIdXNlclZvdGUBEWdldFVzZXJWb3RlU3Rha2VkAgxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIEDHN0YWtlZEJ5VXNlcgkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9zdGFraW5nQ29udHJhY3QJAQ9rZXlTdGFrZWRCeVVzZXICBQ51c2VyQWRkcmVzc1N0cgUMbHBBc3NldElkU3RyAAAECHVzZXJWb3RlCQEUZ2V0VXNlclZvdGVGaW5hbGl6ZWQCBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyAwkAAAIFDHN0YWtlZEJ5VXNlcgAAAAAFCHVzZXJWb3RlARVnZXRWb3RpbmdSZXN1bHRTdGFrZWQBDGxwQXNzZXRJZFN0cgQNJHQwMTk1NDcxOTYyNwkBGmdldFZvdGluZ0VtaXNzaW9uRXBvY2hJbmZvAAQSbGFzdEZpbmFsaXplZEVwb2NoCAUNJHQwMTk1NDcxOTYyNwJfMQQXY3VycmVudEVwb2NoU3RhcnRIZWlnaHQIBQ0kdDAxOTU0NzE5NjI3Al8yBBd2b3RpbmdSZXN1bHRTdGFrZWRTdGFydAkBC3ZhbHVlT3JFbHNlAgkAmggCBRZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0CQEVa2V5Vm90aW5nUmVzdWx0U3Rha2VkAgUMbHBBc3NldElkU3RyBRJsYXN0RmluYWxpemVkRXBvY2gAAAQSdm90aW5nUmVzdWx0U3Rha2VkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJARVrZXlWb3RpbmdSZXN1bHRTdGFrZWQCBQxscEFzc2V0SWRTdHIFEmxhc3RGaW5hbGl6ZWRFcG9jaAUXdm90aW5nUmVzdWx0U3Rha2VkU3RhcnQFEnZvdGluZ1Jlc3VsdFN0YWtlZAEdZ2V0Vm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwBDGxwQXNzZXRJZFN0cgQNJHQwMTk5ODkyMDA2OQkBGmdldFZvdGluZ0VtaXNzaW9uRXBvY2hJbmZvAAQSbGFzdEZpbmFsaXplZEVwb2NoCAUNJHQwMTk5ODkyMDA2OQJfMQQXY3VycmVudEVwb2NoU3RhcnRIZWlnaHQIBQ0kdDAxOTk4OTIwMDY5Al8yBBJ2b3RpbmdSZXN1bHRTdGFrZWQJARVnZXRWb3RpbmdSZXN1bHRTdGFrZWQBBQxscEFzc2V0SWRTdHIEHnZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsUHJldgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEda2V5Vm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwCBQxscEFzc2V0SWRTdHIFEmxhc3RGaW5hbGl6ZWRFcG9jaAAABCJ2b3RpbmdSZXN1bHRTdGFrZWRMYXN0VXBkYXRlSGVpZ2h0CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJASVrZXlWb3RpbmdSZXN1bHRTdGFrZWRMYXN0VXBkYXRlSGVpZ2h0AgUMbHBBc3NldElkU3RyBRJsYXN0RmluYWxpemVkRXBvY2gFF2N1cnJlbnRFcG9jaFN0YXJ0SGVpZ2h0BBx2b3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbERoCQBlAgUGaGVpZ2h0BSJ2b3RpbmdSZXN1bHRTdGFrZWRMYXN0VXBkYXRlSGVpZ2h0BBp2b3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbAkAtwICCQC5AgIJALYCAQUcdm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWxEaAkAtgIBBRJ2b3RpbmdSZXN1bHRTdGFrZWQJALYCAQUedm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWxQcmV2CQCgAwEJAJkDAQkAzAgCCQC2AgEFCExPTkdfTUFYCQDMCAIFGnZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsBQNuaWwBIXJlZnJlc2hWb3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbAIMbHBBc3NldElkU3RyD3N0YWtlZFZvdGVEZWx0YQQNJHQwMjA5NzcyMTA1NwkBGmdldFZvdGluZ0VtaXNzaW9uRXBvY2hJbmZvAAQSbGFzdEZpbmFsaXplZEVwb2NoCAUNJHQwMjA5NzcyMTA1NwJfMQQXY3VycmVudEVwb2NoU3RhcnRIZWlnaHQIBQ0kdDAyMDk3NzIxMDU3Al8yBBJ2b3RpbmdSZXN1bHRTdGFrZWQJARVnZXRWb3RpbmdSZXN1bHRTdGFrZWQBBQxscEFzc2V0SWRTdHIEFXZvdGluZ1Jlc3VsdFN0YWtlZE5ldwkAZAIFEnZvdGluZ1Jlc3VsdFN0YWtlZAUPc3Rha2VkVm90ZURlbHRhBBp2b3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbAkBHWdldFZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsAQUMbHBBc3NldElkU3RyCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEVa2V5Vm90aW5nUmVzdWx0U3Rha2VkAgUMbHBBc3NldElkU3RyBRJsYXN0RmluYWxpemVkRXBvY2gFFXZvdGluZ1Jlc3VsdFN0YWtlZE5ldwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBJWtleVZvdGluZ1Jlc3VsdFN0YWtlZExhc3RVcGRhdGVIZWlnaHQCBQxscEFzc2V0SWRTdHIFEmxhc3RGaW5hbGl6ZWRFcG9jaAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEda2V5Vm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwCBQxscEFzc2V0SWRTdHIFEmxhc3RGaW5hbGl6ZWRFcG9jaAUadm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwFA25pbAEZZ2V0VXNlclZvdGVTdGFrZWRJbnRlZ3JhbAIMbHBBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyBA0kdDAyMTY2ODIxNzQ4CQEaZ2V0Vm90aW5nRW1pc3Npb25FcG9jaEluZm8ABBJsYXN0RmluYWxpemVkRXBvY2gIBQ0kdDAyMTY2ODIxNzQ4Al8xBBdjdXJyZW50RXBvY2hTdGFydEhlaWdodAgFDSR0MDIxNjY4MjE3NDgCXzIEC3VzZXJBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQ51c2VyQWRkcmVzc1N0cgQOdXNlclZvdGVTdGFrZWQJARFnZXRVc2VyVm90ZVN0YWtlZAIFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIEGnVzZXJWb3RlU3Rha2VkSW50ZWdyYWxQcmV2CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJARVrZXlWb3RlU3Rha2VkSW50ZWdyYWwDBQxscEFzc2V0SWRTdHIFC3VzZXJBZGRyZXNzBRJsYXN0RmluYWxpemVkRXBvY2gAAAQedXNlclZvdGVTdGFrZWRMYXN0VXBkYXRlSGVpZ2h0CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAR1rZXlWb3RlU3Rha2VkTGFzdFVwZGF0ZUhlaWdodAMFDGxwQXNzZXRJZFN0cgULdXNlckFkZHJlc3MFEmxhc3RGaW5hbGl6ZWRFcG9jaAUXY3VycmVudEVwb2NoU3RhcnRIZWlnaHQEGHVzZXJWb3RlU3Rha2VkSW50ZWdyYWxEaAkAZQIFBmhlaWdodAUedXNlclZvdGVTdGFrZWRMYXN0VXBkYXRlSGVpZ2h0BBZ1c2VyVm90ZVN0YWtlZEludGVncmFsCQC3AgIJALkCAgkAtgIBBRh1c2VyVm90ZVN0YWtlZEludGVncmFsRGgJALYCAQUOdXNlclZvdGVTdGFrZWQJALYCAQUadXNlclZvdGVTdGFrZWRJbnRlZ3JhbFByZXYJAKADAQkAmQMBCQDMCAIJALYCAQUITE9OR19NQVgJAMwIAgUWdXNlclZvdGVTdGFrZWRJbnRlZ3JhbAUDbmlsARlyZWZyZXNoVm90ZVN0YWtlZEludGVncmFsAwxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIEZWRnZQQNJHQwMjI2MzgyMjcxOAkBGmdldFZvdGluZ0VtaXNzaW9uRXBvY2hJbmZvAAQSbGFzdEZpbmFsaXplZEVwb2NoCAUNJHQwMjI2MzgyMjcxOAJfMQQXY3VycmVudEVwb2NoU3RhcnRIZWlnaHQIBQ0kdDAyMjYzODIyNzE4Al8yBAt1c2VyQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQUOdXNlckFkZHJlc3NTdHIEEXVzZXJWb3RlRmluYWxpemVkCQEUZ2V0VXNlclZvdGVGaW5hbGl6ZWQCBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBAdhY3Rpb25zAwkAAAIFEXVzZXJWb3RlRmluYWxpemVkAAAFA25pbAQPc3Rha2VkVm90ZURlbHRhAwUEZWRnZQURdXNlclZvdGVGaW5hbGl6ZWQJAQEtAQURdXNlclZvdGVGaW5hbGl6ZWQEE3ZvdGluZ1Jlc3VsdEFjdGlvbnMJASFyZWZyZXNoVm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwCBQxscEFzc2V0SWRTdHIFD3N0YWtlZFZvdGVEZWx0YQQWdXNlclZvdGVTdGFrZWRJbnRlZ3JhbAkBGWdldFVzZXJWb3RlU3Rha2VkSW50ZWdyYWwCBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBAt2b3RlQWN0aW9ucwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHWtleVZvdGVTdGFrZWRMYXN0VXBkYXRlSGVpZ2h0AwUMbHBBc3NldElkU3RyBQt1c2VyQWRkcmVzcwUSbGFzdEZpbmFsaXplZEVwb2NoBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIJARVrZXlWb3RlU3Rha2VkSW50ZWdyYWwDBQxscEFzc2V0SWRTdHIFC3VzZXJBZGRyZXNzBRJsYXN0RmluYWxpemVkRXBvY2gFFnVzZXJWb3RlU3Rha2VkSW50ZWdyYWwFA25pbAkAzggCBRN2b3RpbmdSZXN1bHRBY3Rpb25zBQt2b3RlQWN0aW9ucwUHYWN0aW9ucwEbZ2V0U3Rha2VkVm90ZXNJbnRlZ3JhbHNEaWZmAgxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIEDSR0MDIzNTcyMjM2NTIJARpnZXRWb3RpbmdFbWlzc2lvbkVwb2NoSW5mbwAEEmxhc3RGaW5hbGl6ZWRFcG9jaAgFDSR0MDIzNTcyMjM2NTICXzEEF2N1cnJlbnRFcG9jaFN0YXJ0SGVpZ2h0CAUNJHQwMjM1NzIyMzY1MgJfMgQLdXNlckFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDnVzZXJBZGRyZXNzU3RyBB11c2VyVm90ZVN0YWtlZEludGVncmFsTGFzdEtleQkBGWtleVZvdGVTdGFrZWRJbnRlZ3JhbExhc3QDBQxscEFzc2V0SWRTdHIFC3VzZXJBZGRyZXNzBRJsYXN0RmluYWxpemVkRXBvY2gEGnVzZXJWb3RlU3Rha2VkSW50ZWdyYWxMYXN0CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFHXVzZXJWb3RlU3Rha2VkSW50ZWdyYWxMYXN0S2V5AAAEIXZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsTGFzdEtleQkBIWtleVZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsTGFzdAMFDGxwQXNzZXRJZFN0cgULdXNlckFkZHJlc3MFEmxhc3RGaW5hbGl6ZWRFcG9jaAQedm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWxMYXN0CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFIXZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsTGFzdEtleQAABBZ1c2VyVm90ZVN0YWtlZEludGVncmFsCQEZZ2V0VXNlclZvdGVTdGFrZWRJbnRlZ3JhbAIFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIEGnZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsCQEdZ2V0Vm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwBBQxscEFzc2V0SWRTdHIEGnVzZXJWb3RlU3Rha2VkSW50ZWdyYWxEaWZmCQBlAgUWdXNlclZvdGVTdGFrZWRJbnRlZ3JhbAUadXNlclZvdGVTdGFrZWRJbnRlZ3JhbExhc3QEHnZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsRGlmZgkAZQIFGnZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsBR52b3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbExhc3QJAJUKAwkAzAgCCQEMSW50ZWdlckVudHJ5AgUddXNlclZvdGVTdGFrZWRJbnRlZ3JhbExhc3RLZXkFFnVzZXJWb3RlU3Rha2VkSW50ZWdyYWwJAMwIAgkBDEludGVnZXJFbnRyeQIFIXZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsTGFzdEtleQUadm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwFA25pbAUadXNlclZvdGVTdGFrZWRJbnRlZ3JhbERpZmYFHnZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsRGlmZgEccmVmcmVzaEJvb3N0RW1pc3Npb25JbnRlZ3JhbAAEEnd4RW1pc3Npb25QZXJCbG9jawkBA2lvZgIFEGVtaXNzaW9uQ29udHJhY3QJAR5rZXlFbWlzc2lvblJhdGVQZXJCbG9ja0N1cnJlbnQABCBib29zdGluZ1YyTGFzdFVwZGF0ZUhlaWdodE9wdGlvbgkAmggCBQR0aGlzCQEda2V5Qm9vc3RpbmdWMkxhc3RVcGRhdGVIZWlnaHQABBhib29zdGluZ1YySW5nZXJnYWxPcHRpb24JAJoIAgUEdGhpcwkBFWtleUJvb3N0aW5nVjJJbnRlZ3JhbAAEC2VtaXNzaW9uRW5kCQEDaW9mAgUQZW1pc3Npb25Db250cmFjdAkBE2tleUVtaXNzaW9uRW5kQmxvY2sABAFoAwkAZgIFBmhlaWdodAULZW1pc3Npb25FbmQFC2VtaXNzaW9uRW5kBQZoZWlnaHQEAmRoBAckbWF0Y2gwBSBib29zdGluZ1YyTGFzdFVwZGF0ZUhlaWdodE9wdGlvbgMJAAECBQckbWF0Y2gwAgNJbnQEEGxhc3RVcGRhdGVIZWlnaHQFByRtYXRjaDAJAJYDAQkAzAgCCQBlAgUBaAUQbGFzdFVwZGF0ZUhlaWdodAkAzAgCAAAFA25pbAMJAAECBQckbWF0Y2gwAgRVbml0AAAJAAIBAgtNYXRjaCBlcnJvcgQVYm9vc3RFbWlzc2lvblBlckJsb2NrCQBpAgkAaAIFEnd4RW1pc3Npb25QZXJCbG9jawkAZQIFCmJvb3N0Q29lZmYAAQUKYm9vc3RDb2VmZgQZYm9vc3RFbWlzc2lvbkludGVncmFsUHJldgkBC3ZhbHVlT3JFbHNlAgUYYm9vc3RpbmdWMkluZ2VyZ2FsT3B0aW9uAAAEFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAZAIJAGgCBRVib29zdEVtaXNzaW9uUGVyQmxvY2sFAmRoBRlib29zdEVtaXNzaW9uSW50ZWdyYWxQcmV2CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJARVrZXlCb29zdGluZ1YySW50ZWdyYWwABRVib29zdEVtaXNzaW9uSW50ZWdyYWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAR1rZXlCb29zdGluZ1YyTGFzdFVwZGF0ZUhlaWdodAAFBmhlaWdodAUDbmlsBRVib29zdEVtaXNzaW9uSW50ZWdyYWwBFGludGVybmFsQ2xhaW1XeEJvb3N0AwxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIIcmVhZE9ubHkEEHVzZXJSZWNvcmRPcHRpb24JAJ0IAgUEdGhpcwkBE2tleUxvY2tQYXJhbXNSZWNvcmQBBQ51c2VyQWRkcmVzc1N0cgMJAAACBRB1c2VyUmVjb3JkT3B0aW9uBQR1bml0CQCVCgMAAAUDbmlsAhV1c2VyUmVjb3JkOjppczo6ZW1wdHkED3VzZXJSZWNvcmRBcnJheQkAtQkCCQEFdmFsdWUBBRB1c2VyUmVjb3JkT3B0aW9uBQNTRVAECnVzZXJOdW1TdHIJAJEDAgUPdXNlclJlY29yZEFycmF5BQ5JZHhMb2NrVXNlck51bQQIRU1QVFlTVFICBWVtcHR5BApwb29sV2VpZ2h0AwkBAiE9AgUMbHBBc3NldElkU3RyBQhFTVBUWVNUUgQOcG9vbEFkZHJlc3NTdHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9mYWN0b3J5Q29udHJhY3QJASZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcwEFDGxwQXNzZXRJZFN0cgkBB3dyYXBFcnIBCQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUMbHBBc3NldElkU3RyCQERQGV4dHJOYXRpdmUoMTA1MCkCBQ9mYWN0b3J5Q29udHJhY3QJARRrZXlGYWN0b3J5UG9vbFdlaWdodAEFDnBvb2xBZGRyZXNzU3RyAwUIcmVhZE9ubHkAAAkBCHRocm93RXJyAQkArAICAihub3QgcmVhZG9ubHkgbW9kZTogdW5zdXBwb3J0ZWQgbHAgYXNzZXQgBQxscEFzc2V0SWRTdHIEInVzZXJMcEJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJASJrZXlVc2VyTHBCb29zdEVtaXNzaW9uTGFzdElOVEVHUkFMAgUKdXNlck51bVN0cgUMbHBBc3NldElkU3RyBCB1c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQkBIGtleVVzZXJCb29zdEVtaXNzaW9uTGFzdElOVEVHUkFMAQUKdXNlck51bVN0cgQddXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUidXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQkBA2lvegIFBHRoaXMFIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZBBVib29zdEVtaXNzaW9uSW50ZWdyYWwICQEccmVmcmVzaEJvb3N0RW1pc3Npb25JbnRlZ3JhbAACXzIEGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAGUCBRVib29zdEVtaXNzaW9uSW50ZWdyYWwFHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsAwkAZgIAAAUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAkBCHRocm93RXJyAQISd3JvbmcgY2FsY3VsYXRpb25zBA0kdDAyNzI3MTI3NDEwCQEbZ2V0U3Rha2VkVm90ZXNJbnRlZ3JhbHNEaWZmAgUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgQbc3Rha2VkVm90ZXNJbnRlZ3JhbHNBY3Rpb25zCAUNJHQwMjcyNzEyNzQxMAJfMQQUdXNlclZvdGVJbnRlZ3JhbERpZmYIBQ0kdDAyNzI3MTI3NDEwAl8yBBZ0b3RhbFZvdGVzSW50ZWdyYWxEaWZmCAUNJHQwMjcyNzEyNzQxMAJfMwQdcG9vbFVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAGsDBRl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsBQpwb29sV2VpZ2h0BQ5QT09MV0VJR0hUTVVMVAQhdXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsTmV3AwkAAAIFFnRvdGFsVm90ZXNJbnRlZ3JhbERpZmYAAAAACQBrAwUdcG9vbFVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwFFHVzZXJWb3RlSW50ZWdyYWxEaWZmBRZ0b3RhbFZvdGVzSW50ZWdyYWxEaWZmBAlkYXRhU3RhdGUJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUidXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQUVYm9vc3RFbWlzc2lvbkludGVncmFsBQNuaWwFG3N0YWtlZFZvdGVzSW50ZWdyYWxzQWN0aW9ucwQFZGVidWcJALkJAgkAzAgCCQCkAwEFHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsCQDMCAIJAKQDAQUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAzAgCCQCkAwEFCnBvb2xXZWlnaHQJAMwIAgkApAMBBRR1c2VyVm90ZUludGVncmFsRGlmZgkAzAgCCQCkAwEFFnRvdGFsVm90ZXNJbnRlZ3JhbERpZmYFA25pbAIBOgkAlQoDBSF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcFCWRhdGFTdGF0ZQUFZGVidWcBC2xvY2tBY3Rpb25zAgFpCGR1cmF0aW9uBAhjZmdBcnJheQkBFXJlYWRDb25maWdBcnJheU9yRmFpbAAECmFzc2V0SWRTdHIJAJEDAgUIY2ZnQXJyYXkFDUlkeENmZ0Fzc2V0SWQEB2Fzc2V0SWQJANkEAQUKYXNzZXRJZFN0cgQNbWluTG9ja0Ftb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRNJZHhDZmdNaW5Mb2NrQW1vdW50BA9taW5Mb2NrRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUVSWR4Q2ZnTWluTG9ja0R1cmF0aW9uBA9tYXhMb2NrRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUVSWR4Q2ZnTWF4TG9ja0R1cmF0aW9uAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQEIdGhyb3dFcnIBAjRpbnZhbGlkIHBheW1lbnQgLSBleGFjdCBvbmUgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQJcG10QW1vdW50CAUDcG10BmFtb3VudAMJAQIhPQIFB2Fzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAkBCHRocm93RXJyAQkArAICCQCsAgICHmludmFsaWQgYXNzZXQgaXMgaW4gcGF5bWVudCAtIAUKYXNzZXRJZFN0cgIMIGlzIGV4cGVjdGVkBA5uZXh0VXNlck51bUtFWQkBDmtleU5leHRVc2VyTnVtAAQOdXNlckFkZHJlc3NTdHIJAKUIAQgFAWkGY2FsbGVyBA51c2VySXNFeGlzdGluZwkBCWlzRGVmaW5lZAEJAKIIAQkBEmtleVVzZXIyTnVtTWFwcGluZwEFDnVzZXJBZGRyZXNzU3RyBAp1c2VyTnVtU3RyAwUOdXNlcklzRXhpc3RpbmcJAQV2YWx1ZQEJAKIIAQkBEmtleVVzZXIyTnVtTWFwcGluZwEFDnVzZXJBZGRyZXNzU3RyCQCkAwEJAQNpb2YCBQR0aGlzBQ5uZXh0VXNlck51bUtFWQQHdXNlck51bQkBDXBhcnNlSW50VmFsdWUBBQp1c2VyTnVtU3RyBAlsb2NrU3RhcnQFBmhlaWdodAQNc3RhcnRCbG9ja0tFWQkBFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sBBQp1c2VyTnVtU3RyBAtkdXJhdGlvbktFWQkBFGtleUxvY2tQYXJhbUR1cmF0aW9uAQUKdXNlck51bVN0cgQNdXNlckFtb3VudEtFWQkBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBBQp1c2VyTnVtU3RyAwMJAGYCBQ1taW5Mb2NrQW1vdW50BQlwbXRBbW91bnQJAQIhPQIIBQFpBmNhbGxlcgUWbHBTdGFraW5nUG9vbHNDb250cmFjdAcJAQh0aHJvd0VycgEJAKwCAgIiYW1vdW50IGlzIGxlc3MgdGhlbiBtaW5Mb2NrQW1vdW50PQkApAMBBQ1taW5Mb2NrQW1vdW50AwkAZgIFD21pbkxvY2tEdXJhdGlvbgUIZHVyYXRpb24JAQh0aHJvd0VycgEJAKwCAgItcGFzc2VkIGR1cmF0aW9uIGlzIGxlc3MgdGhlbiBtaW5Mb2NrRHVyYXRpb249CQCkAwEFD21pbkxvY2tEdXJhdGlvbgMJAGYCBQhkdXJhdGlvbgUPbWF4TG9ja0R1cmF0aW9uCQEIdGhyb3dFcnIBCQCsAgICMHBhc3NlZCBkdXJhdGlvbiBpcyBncmVhdGVyIHRoZW4gbWF4TG9ja0R1cmF0aW9uPQkApAMBBQ9tYXhMb2NrRHVyYXRpb24DAwUOdXNlcklzRXhpc3RpbmcJAGcCCQBkAgkBA2lvZgIFBHRoaXMFDXN0YXJ0QmxvY2tLRVkJAQNpb2YCBQR0aGlzBQtkdXJhdGlvbktFWQUJbG9ja1N0YXJ0BwkBCHRocm93RXJyAQI2dGhlcmUgaXMgYW4gYWN0aXZlIGxvY2sgLSBjb25zaWRlciB0byB1c2UgaW5jcmVhc2VMb2NrAwkAZgIJAQNpb3oCBQR0aGlzBQ11c2VyQW1vdW50S0VZAAAJAQh0aHJvd0VycgEJAKwCAgI0dGhlcmUgYXJlIGxvY2tlZCBXWHMgLSBjb25zaWRlciB0byB1c2UgaW5jcmVhc2VMb2NrIAUNdXNlckFtb3VudEtFWQQHY29lZmZYOAkAawMFCGR1cmF0aW9uBQVNVUxUOAUPbWF4TG9ja0R1cmF0aW9uBA5nV3hBbW91bnRTdGFydAkAawMFCXBtdEFtb3VudAUHY29lZmZYOAUFTVVMVDgEE2dXeFBhcmFtc1Jlc3VsdExpc3QJAQNhYWwBCQD8BwQFDG1hdGhDb250cmFjdAIVY2FsY0d3eFBhcmFtc1JFQURPTkxZCQDMCAIFDmdXeEFtb3VudFN0YXJ0CQDMCAIFCWxvY2tTdGFydAkAzAgCBQhkdXJhdGlvbgUDbmlsBQNuaWwEAWsJAQJhaQEJAJEDAgUTZ1d4UGFyYW1zUmVzdWx0TGlzdAAABAFiCQECYWkBCQCRAwIFE2dXeFBhcmFtc1Jlc3VsdExpc3QAAQQGcGVyaW9kCQCkAwEJAQJhaQEJAJEDAgUTZ1d4UGFyYW1zUmVzdWx0TGlzdAACBBF0b3RhbENhY2hlZEd3eFJhdwkBEWdldFRvdGFsQ2FjaGVkR3d4AQcEIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZCQEga2V5VXNlckJvb3N0RW1pc3Npb25MYXN0SU5URUdSQUwBBQp1c2VyTnVtU3RyBBVib29zdEVtaXNzaW9uSW50ZWdyYWwICQEccmVmcmVzaEJvb3N0RW1pc3Npb25JbnRlZ3JhbAACXzIEA2FycgMFDnVzZXJJc0V4aXN0aW5nBQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIFDm5leHRVc2VyTnVtS0VZCQBkAgUHdXNlck51bQABCQDMCAIJAQtTdHJpbmdFbnRyeQIJARJrZXlVc2VyMk51bU1hcHBpbmcBBQ51c2VyQWRkcmVzc1N0cgUKdXNlck51bVN0cgkAzAgCCQELU3RyaW5nRW50cnkCCQESa2V5TnVtMlVzZXJNYXBwaW5nAQUKdXNlck51bVN0cgUOdXNlckFkZHJlc3NTdHIFA25pbAkAlAoCCQDOCAIJAM0IAgkAzggCCQDOCAIFA2FycgkBD0xvY2tQYXJhbXNFbnRyeQgFDnVzZXJBZGRyZXNzU3RyBQp1c2VyTnVtU3RyBQlwbXRBbW91bnQFCWxvY2tTdGFydAUIZHVyYXRpb24FAWsFAWIFBnBlcmlvZAkBClN0YXRzRW50cnkEBQlwbXRBbW91bnQFCGR1cmF0aW9uAAEDBQ51c2VySXNFeGlzdGluZwAAAAEJAQxIaXN0b3J5RW50cnkIAgRsb2NrBQ51c2VyQWRkcmVzc1N0cgUJcG10QW1vdW50BQlsb2NrU3RhcnQFCGR1cmF0aW9uBQFrBQFiBQFpCQDMCAIJAQxJbnRlZ2VyRW50cnkCBSB1c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQUVYm9vc3RFbWlzc2lvbkludGVncmFsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQERa2V5VG90YWxDYWNoZWRHd3gACQBkAgURdG90YWxDYWNoZWRHd3hSYXcFDmdXeEFtb3VudFN0YXJ0BQNuaWwFDmdXeEFtb3VudFN0YXJ0EQFpAQtjb25zdHJ1Y3RvcgYRZmFjdG9yeUFkZHJlc3NTdHIObG9ja0Fzc2V0SWRTdHINbWluTG9ja0Ftb3VudAttaW5EdXJhdGlvbgttYXhEdXJhdGlvbgxtYXRoQ29udHJhY3QEC2NoZWNrQ2FsbGVyCQELbXVzdE1hbmFnZXIBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOa2V5TmV4dFVzZXJOdW0AAAAJAMwIAgkBC1N0cmluZ0VudHJ5AgkBCWtleUNvbmZpZwAJAQxmb3JtYXRDb25maWcFBQ5sb2NrQXNzZXRJZFN0cgUNbWluTG9ja0Ftb3VudAULbWluRHVyYXRpb24FC21heER1cmF0aW9uBQxtYXRoQ29udHJhY3QJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUZhY3RvcnlBZGRyZXNzAAURZmFjdG9yeUFkZHJlc3NTdHIFA25pbAkBClN0YXRzRW50cnkEAAAAAAAAAAAJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEHbG9ja1JlZgMIZHVyYXRpb24PcmVmZXJyZXJBZGRyZXNzCXNpZ25hdHVyZQQNJHQwMzIwMjEzMjA4NgkBC2xvY2tBY3Rpb25zAgUBaQUIZHVyYXRpb24EEWxvY2tBY3Rpb25zUmVzdWx0CAUNJHQwMzIwMjEzMjA4NgJfMQQOZ1d4QW1vdW50U3RhcnQIBQ0kdDAzMjAyMTMyMDg2Al8yBA9yZWZlcnJhbEFkZHJlc3MJAKUIAQgFAWkGY2FsbGVyBAZyZWZJbnYDAwkAAAIFD3JlZmVycmVyQWRkcmVzcwIABgkAAAIFCXNpZ25hdHVyZQEABQR1bml0CQD8BwQFHnJlZmVycmFsc0NvbnRyYWN0QWRkcmVzc09yRmFpbAIKY3JlYXRlUGFpcgkAzAgCBRNyZWZlcnJhbFByb2dyYW1OYW1lCQDMCAIFD3JlZmVycmVyQWRkcmVzcwkAzAgCBQ9yZWZlcnJhbEFkZHJlc3MJAMwIAgUJc2lnbmF0dXJlBQNuaWwFA25pbAMJAAACBQZyZWZJbnYFBnJlZkludgQRdXBkYXRlUmVmQWN0aXZpdHkJAPwHBAUMbWF0aENvbnRyYWN0AhZ1cGRhdGVSZWZlcnJhbEFjdGl2aXR5CQDMCAIJAKUIAQgFAWkGY2FsbGVyCQDMCAIFDmdXeEFtb3VudFN0YXJ0BQNuaWwFA25pbAMJAAACBRF1cGRhdGVSZWZBY3Rpdml0eQURdXBkYXRlUmVmQWN0aXZpdHkJAJQKAgURbG9ja0FjdGlvbnNSZXN1bHQFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEEbG9jawEIZHVyYXRpb24EDSR0MDMyNTQ0MzI2MDkJAQtsb2NrQWN0aW9ucwIFAWkFCGR1cmF0aW9uBBFsb2NrQWN0aW9uc1Jlc3VsdAgFDSR0MDMyNTQ0MzI2MDkCXzEEDmdXeEFtb3VudFN0YXJ0CAUNJHQwMzI1NDQzMjYwOQJfMgQRdXBkYXRlUmVmQWN0aXZpdHkJAPwHBAUMbWF0aENvbnRyYWN0AhZ1cGRhdGVSZWZlcnJhbEFjdGl2aXR5CQDMCAIJAKUIAQgFAWkGY2FsbGVyCQDMCAIFDmdXeEFtb3VudFN0YXJ0BQNuaWwFA25pbAMJAAACBRF1cGRhdGVSZWZBY3Rpdml0eQURdXBkYXRlUmVmQWN0aXZpdHkJAJQKAgURbG9ja0FjdGlvbnNSZXN1bHQFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEMaW5jcmVhc2VMb2NrAQ1kZWx0YUR1cmF0aW9uBAhjZmdBcnJheQkBFXJlYWRDb25maWdBcnJheU9yRmFpbAAECmFzc2V0SWRTdHIJAJEDAgUIY2ZnQXJyYXkFDUlkeENmZ0Fzc2V0SWQEB2Fzc2V0SWQJANkEAQUKYXNzZXRJZFN0cgQPbWluTG9ja0R1cmF0aW9uCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFFUlkeENmZ01pbkxvY2tEdXJhdGlvbgQPbWF4TG9ja0R1cmF0aW9uCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFFUlkeENmZ01heExvY2tEdXJhdGlvbgQJcG10QW1vdW50CQEiZXh0cmFjdE9wdGlvbmFsUGF5bWVudEFtb3VudE9yRmFpbAIFAWkFB2Fzc2V0SWQEDnVzZXJBZGRyZXNzU3RyCQClCAEIBQFpBmNhbGxlcgQPdXNlclJlY29yZEFycmF5CQEacmVhZExvY2tQYXJhbXNSZWNvcmRPckZhaWwBBQ51c2VyQWRkcmVzc1N0cgQKdXNlck51bVN0cgkAkQMCBQ91c2VyUmVjb3JkQXJyYXkFDklkeExvY2tVc2VyTnVtBAp1c2VyQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdXNlclJlY29yZEFycmF5BQ1JZHhMb2NrQW1vdW50BAlsb2NrU3RhcnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ91c2VyUmVjb3JkQXJyYXkFDElkeExvY2tTdGFydAQMbG9ja0R1cmF0aW9uCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdXNlclJlY29yZEFycmF5BQ9JZHhMb2NrRHVyYXRpb24EB2xvY2tFbmQJAGQCBQlsb2NrU3RhcnQFDGxvY2tEdXJhdGlvbgQRcmVtYWluaW5nRHVyYXRpb24JAJYDAQkAzAgCCQBlAgUHbG9ja0VuZAUGaGVpZ2h0CQDMCAIAAAUDbmlsBA11c2VyQW1vdW50TmV3CQBkAgUKdXNlckFtb3VudAUJcG10QW1vdW50BA9sb2NrRHVyYXRpb25OZXcJAGQCBRFyZW1haW5pbmdEdXJhdGlvbgUNZGVsdGFEdXJhdGlvbgMJAGYCAAAFDWRlbHRhRHVyYXRpb24JAQh0aHJvd0VycgECGmR1cmF0aW9uIGlzIGxlc3MgdGhlbiB6ZXJvAwkAZgIFD21pbkxvY2tEdXJhdGlvbgUPbG9ja0R1cmF0aW9uTmV3CQEIdGhyb3dFcnIBCQCsAgICLWxvY2tEdXJhdGlvbk5ldyBpcyBsZXNzIHRoZW4gbWluTG9ja0R1cmF0aW9uPQkApAMBBQ9taW5Mb2NrRHVyYXRpb24DCQBmAgUPbG9ja0R1cmF0aW9uTmV3BQ9tYXhMb2NrRHVyYXRpb24JAQh0aHJvd0VycgEJAKwCAgJEZGVsdGFEdXJhdGlvbiArIGV4aXN0ZWRMb2NrRHVyYXRpb24gaXMgZ3JlYXRlciB0aGVuIG1heExvY2tEdXJhdGlvbj0JAKQDAQUPbWF4TG9ja0R1cmF0aW9uBAdjb2VmZlg4CQBrAwUPbG9ja0R1cmF0aW9uTmV3BQVNVUxUOAUPbWF4TG9ja0R1cmF0aW9uBA5nV3hBbW91bnRTdGFydAkAawMFDXVzZXJBbW91bnROZXcFB2NvZWZmWDgFBU1VTFQ4BBF1cGRhdGVSZWZBY3Rpdml0eQkA/AcEBQxtYXRoQ29udHJhY3QCFnVwZGF0ZVJlZmVycmFsQWN0aXZpdHkJAMwIAgkApQgBCAUBaQZjYWxsZXIJAMwIAgUOZ1d4QW1vdW50U3RhcnQFA25pbAUDbmlsAwkAAAIFEXVwZGF0ZVJlZkFjdGl2aXR5BRF1cGRhdGVSZWZBY3Rpdml0eQQMbG9ja1N0YXJ0TmV3BQZoZWlnaHQEE2dXeFBhcmFtc1Jlc3VsdExpc3QJAQNhYWwBCQD8BwQFDG1hdGhDb250cmFjdAIVY2FsY0d3eFBhcmFtc1JFQURPTkxZCQDMCAIFDmdXeEFtb3VudFN0YXJ0CQDMCAIFDGxvY2tTdGFydE5ldwkAzAgCBQ9sb2NrRHVyYXRpb25OZXcFA25pbAUDbmlsBAFrCQECYWkBCQCRAwIFE2dXeFBhcmFtc1Jlc3VsdExpc3QAAAQBYgkBAmFpAQkAkQMCBRNnV3hQYXJhbXNSZXN1bHRMaXN0AAEEBnBlcmlvZAkApAMBCQECYWkBCQCRAwIFE2dXeFBhcmFtc1Jlc3VsdExpc3QAAgQLY3VyclVzZXJHd3gJARRjYWxjQ3VycmVudEd3eEFtb3VudAEFDnVzZXJBZGRyZXNzU3RyBAdnd3hEaWZmCQBlAgUOZ1d4QW1vdW50U3RhcnQFC2N1cnJVc2VyR3d4AwkAZgIAAAUHZ3d4RGlmZgkBCHRocm93RXJyAQkArAICAhhnd3hEaWZmIGlzIGxlc3MgdGhlbiAwOiAJAKQDAQUHZ3d4RGlmZgQRdG90YWxDYWNoZWRHd3hSYXcJARFnZXRUb3RhbENhY2hlZEd3eAEHBBd0b3RhbENhY2hlZEd3eENvcnJlY3RlZAkBEWdldFRvdGFsQ2FjaGVkR3d4AQYJAM4IAgkAzQgCCQDOCAIJAQ9Mb2NrUGFyYW1zRW50cnkIBQ51c2VyQWRkcmVzc1N0cgUKdXNlck51bVN0cgUNdXNlckFtb3VudE5ldwUMbG9ja1N0YXJ0TmV3BQ9sb2NrRHVyYXRpb25OZXcFAWsFAWIFBnBlcmlvZAkBClN0YXRzRW50cnkEBQlwbXRBbW91bnQFDWRlbHRhRHVyYXRpb24AAAAACQEMSGlzdG9yeUVudHJ5CAIEbG9jawUOdXNlckFkZHJlc3NTdHIFCXBtdEFtb3VudAUJbG9ja1N0YXJ0BQ9sb2NrRHVyYXRpb25OZXcFAWsFAWIFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIJARFrZXlUb3RhbENhY2hlZEd3eAAJAGQCBRF0b3RhbENhY2hlZEd3eFJhdwUHZ3d4RGlmZgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDGNsYWltV3hCb29zdAIMbHBBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyAwkBAiE9AgUPc3Rha2luZ0NvbnRyYWN0CAUBaQZjYWxsZXIJAQh0aHJvd0VycgECEnBlcm1pc3Npb25zIGRlbmllZAQNJHQwMzU3MTQzNTgxNgkBFGludGVybmFsQ2xhaW1XeEJvb3N0AwUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgcEEnVzZXJCb29zdEF2YWlsYWJsZQgFDSR0MDM1NzE0MzU4MTYCXzEECWRhdGFTdGF0ZQgFDSR0MDM1NzE0MzU4MTYCXzIEBWRlYnVnCAUNJHQwMzU3MTQzNTgxNgJfMwkAlAoCBQlkYXRhU3RhdGUJAMwIAgUSdXNlckJvb3N0QXZhaWxhYmxlBQNuaWwBaQEUY2xhaW1XeEJvb3N0UkVBRE9OTFkCDGxwQXNzZXRJZFN0cg51c2VyQWRkcmVzc1N0cgQNJHQwMzU5NDgzNjA0OQkBFGludGVybmFsQ2xhaW1XeEJvb3N0AwUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgYEEnVzZXJCb29zdEF2YWlsYWJsZQgFDSR0MDM1OTQ4MzYwNDkCXzEECWRhdGFTdGF0ZQgFDSR0MDM1OTQ4MzYwNDkCXzIEBWRlYnVnCAUNJHQwMzU5NDgzNjA0OQJfMwkAlAoCBQNuaWwJAMwIAgUSdXNlckJvb3N0QXZhaWxhYmxlCQDMCAIFBWRlYnVnBQNuaWwBaQEGdW5sb2NrAQt1c2VyQWRkcmVzcwQPdXNlclJlY29yZEFycmF5CQEacmVhZExvY2tQYXJhbXNSZWNvcmRPckZhaWwBBQt1c2VyQWRkcmVzcwQKdXNlck51bVN0cgkAkQMCBQ91c2VyUmVjb3JkQXJyYXkFDklkeExvY2tVc2VyTnVtBAp1c2VyQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdXNlclJlY29yZEFycmF5BQ1JZHhMb2NrQW1vdW50BAlsb2NrU3RhcnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ91c2VyUmVjb3JkQXJyYXkFDElkeExvY2tTdGFydAQMbG9ja0R1cmF0aW9uCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdXNlclJlY29yZEFycmF5BQ9JZHhMb2NrRHVyYXRpb24EB2xvY2tFbmQJAGQCBQlsb2NrU3RhcnQFDGxvY2tEdXJhdGlvbgQIY2ZnQXJyYXkJARVyZWFkQ29uZmlnQXJyYXlPckZhaWwABAdhc3NldElkCQDZBAEJAJEDAgUIY2ZnQXJyYXkFDUlkeENmZ0Fzc2V0SWQDCQBnAgUHbG9ja0VuZAUGaGVpZ2h0CQEIdGhyb3dFcnIBCQCsAgIJAKwCAgIFd2FpdCAJAKQDAQUHbG9ja0VuZAIKIHRvIHVubG9jawMJAGcCAAAFCnVzZXJBbW91bnQJAQh0aHJvd0VycgECEW5vdGhpbmcgdG8gdW5sb2NrBAZwZXJpb2QJAQt2YWx1ZU9yRWxzZQIJAJoIAgUMbWF0aENvbnRyYWN0CQENa2V5TmV4dFBlcmlvZAAAAAkAzQgCCQDNCAIJAM4IAgkBD0xvY2tQYXJhbXNFbnRyeQgFC3VzZXJBZGRyZXNzBQp1c2VyTnVtU3RyAAAFCWxvY2tTdGFydAUMbG9ja0R1cmF0aW9uAAAAAAkApAMBBQZwZXJpb2QJAQpTdGF0c0VudHJ5BAkBAS0BBQp1c2VyQW1vdW50AAAAAAD///////////8BCQEMSGlzdG9yeUVudHJ5CAIGdW5sb2NrBQt1c2VyQWRkcmVzcwUKdXNlckFtb3VudAUJbG9ja1N0YXJ0BQxsb2NrRHVyYXRpb24AAAAABQFpCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQt1c2VyQWRkcmVzcwUKdXNlckFtb3VudAUHYXNzZXRJZAFpARNnd3hVc2VySW5mb1JFQURPTkxZAQt1c2VyQWRkcmVzcwQJZ3d4QW1vdW50CQEUY2FsY0N1cnJlbnRHd3hBbW91bnQBBQt1c2VyQWRkcmVzcwkAlAoCBQNuaWwJAMwIAgUJZ3d4QW1vdW50BQNuaWwBaQEXdXNlck1heER1cmF0aW9uUkVBRE9OTFkBDnVzZXJBZGRyZXNzU3RyBAhjZmdBcnJheQkBFXJlYWRDb25maWdBcnJheU9yRmFpbAAED21heExvY2tEdXJhdGlvbgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRVJZHhDZmdNYXhMb2NrRHVyYXRpb24EEHVzZXJSZWNvcmRPcHRpb24JAJ0IAgUEdGhpcwkBE2tleUxvY2tQYXJhbXNSZWNvcmQBBQ51c2VyQWRkcmVzc1N0cgMJAAACBRB1c2VyUmVjb3JkT3B0aW9uBQR1bml0CQCUCgIFA25pbAkAlAoCAgRsb2NrBQ9tYXhMb2NrRHVyYXRpb24ED3VzZXJSZWNvcmRBcnJheQkAtQkCCQEFdmFsdWUBBRB1c2VyUmVjb3JkT3B0aW9uBQNTRVAECWxvY2tTdGFydAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUMSWR4TG9ja1N0YXJ0BAxsb2NrRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ91c2VyUmVjb3JkQXJyYXkFD0lkeExvY2tEdXJhdGlvbgQHbG9ja0VuZAkAZAIFCWxvY2tTdGFydAUMbG9ja0R1cmF0aW9uBBFyZW1haW5pbmdEdXJhdGlvbgkAlgMBCQDMCAIJAGUCBQdsb2NrRW5kBQZoZWlnaHQJAMwIAgAABQNuaWwEEG1heERlbHRhRHVyYXRpb24JAGUCBQ9tYXhMb2NrRHVyYXRpb24FEXJlbWFpbmluZ0R1cmF0aW9uCQCUCgIFA25pbAkAlAoCAgxpbmNyZWFzZUxvY2sFEG1heERlbHRhRHVyYXRpb24BaQEgZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0UkVBRE9OTFkCC3VzZXJBZGRyZXNzDHRhcmdldEhlaWdodAQJZ3d4QW1vdW50CQEZY2FsY1VzZXJHd3hBbW91bnRBdEhlaWdodAIFC3VzZXJBZGRyZXNzBQx0YXJnZXRIZWlnaHQJAJQKAgUDbmlsBQlnd3hBbW91bnQBaQEZZ2V0VG90YWxDYWNoZWRHd3hSRUFET05MWQAJAJQKAgUDbmlsCQERZ2V0VG90YWxDYWNoZWRHd3gBBgFpARVvbkJvb3N0RW1pc3Npb25VcGRhdGUABAtjaGVja0NhbGxlcgMJAAACCAUBaQZjYWxsZXIFEGVtaXNzaW9uQ29udHJhY3QGCQELbXVzdE1hbmFnZXIBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgkBHHJlZnJlc2hCb29zdEVtaXNzaW9uSW50ZWdyYWwACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEm9uU3Rha2VkVm90ZVVwZGF0ZQMMbHBBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyBGVkZ2UEC2NoZWNrQ2FsbGVyAwkAAAIIBQFpBmNhbGxlcgUPc3Rha2luZ0NvbnRyYWN0BgkBC211c3RNYW5hZ2VyAQUBaQMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIEB2FjdGlvbnMJARlyZWZyZXNoVm90ZVN0YWtlZEludGVncmFsAwUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgUEZWRnZQkAlAoCBQdhY3Rpb25zBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBHWdldFZvdGluZ1Jlc3VsdFN0YWtlZFJFQURPTkxZAQxscEFzc2V0SWRTdHIJAJQKAgUDbmlsCQEVZ2V0Vm90aW5nUmVzdWx0U3Rha2VkAQUMbHBBc3NldElkU3RyAWkBJWdldFZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsUkVBRE9OTFkBDGxwQXNzZXRJZFN0cgkAlAoCBQNuaWwJAR1nZXRWb3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbAEFDGxwQXNzZXRJZFN0cgFpARxnZXRVc2VyVm90ZUZpbmFsaXplZFJFQURPTkxZAgxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIJAJQKAgUDbmlsCQEUZ2V0VXNlclZvdGVGaW5hbGl6ZWQCBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyAWkBIWdldFVzZXJWb3RlU3Rha2VkSW50ZWdyYWxSRUFET05MWQIMbHBBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyCQCUCgIFA25pbAkBGWdldFVzZXJWb3RlU3Rha2VkSW50ZWdyYWwCBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyAQJ0eAEGdmVyaWZ5AAQPdGFyZ2V0UHVibGljS2V5BAckbWF0Y2gwCQEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAADCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCcGsFByRtYXRjaDAFAnBrAwkAAQIFByRtYXRjaDACBFVuaXQIBQJ0eA9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUPdGFyZ2V0UHVibGljS2V5qzF6Dg==", "height": 3499222, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: C9BnnQScYeDuQyA4mykD4xBxZ1diGVSvTe9jvun5mgrF Next: none Diff:
OldNewDifferences
88 let MULT8 = 100000000
99
1010 let POOLWEIGHTMULT = MULT8
11+
12+let LONG_MAX = 9223372036854775807
1113
1214 func wrapErr (msg) = makeString(["boosting.ride:", msg], " ")
1315
447449
448450
449451 func getVotingEmissionEpochInfo () = {
450- let $t01782918119 = {
452+ let $t01786418154 = {
451453 let currentEpochUi = value(getInteger(votingEmissionContract, keyCurrentEpochUi()))
452454 let lastFinalizedEpoch = (currentEpochUi - 1)
453455 if ((0 > lastFinalizedEpoch))
454456 then throwErr("invalid epoch")
455457 else $Tuple2(currentEpochUi, lastFinalizedEpoch)
456458 }
457- let currentEpochUi = $t01782918119._1
458- let lastFinalizedEpoch = $t01782918119._2
459+ let currentEpochUi = $t01786418154._1
460+ let lastFinalizedEpoch = $t01786418154._2
459461 let currentEpochStartHeight = value(getInteger(votingEmissionContract, keyStartHeightByEpoch(currentEpochUi)))
460462 $Tuple2(lastFinalizedEpoch, currentEpochStartHeight)
461463 }
488490
489491 func getUserVoteFinalized (lpAssetIdStr,userAddressStr) = {
490492 let userAddress = addressFromStringValue(userAddressStr)
491- let $t01881018890 = getVotingEmissionEpochInfo()
492- let lastFinalizedEpoch = $t01881018890._1
493- let currentEpochStartHeight = $t01881018890._2
494- let $t01889318968 = getPoolAssetsByLpAssetId(lpAssetIdStr)
495- let amountAssetId = $t01889318968._1
496- let priceAssetId = $t01889318968._2
493+ let $t01884518925 = getVotingEmissionEpochInfo()
494+ let lastFinalizedEpoch = $t01884518925._1
495+ let currentEpochStartHeight = $t01884518925._2
496+ let $t01892819003 = getPoolAssetsByLpAssetId(lpAssetIdStr)
497+ let amountAssetId = $t01892819003._1
498+ let priceAssetId = $t01892819003._2
497499 let userVoteKey = keyVote(amountAssetId, priceAssetId, userAddress, lastFinalizedEpoch)
498500 let userVote = valueOrElse(getInteger(votingEmissionContract, userVoteKey), 0)
499501 userVote
510512
511513
512514 func getVotingResultStaked (lpAssetIdStr) = {
513- let $t01951219592 = getVotingEmissionEpochInfo()
514- let lastFinalizedEpoch = $t01951219592._1
515- let currentEpochStartHeight = $t01951219592._2
515+ let $t01954719627 = getVotingEmissionEpochInfo()
516+ let lastFinalizedEpoch = $t01954719627._1
517+ let currentEpochStartHeight = $t01954719627._2
516518 let votingResultStakedStart = valueOrElse(getInteger(votingEmissionContract, keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch)), 0)
517519 let votingResultStaked = valueOrElse(getInteger(this, keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch)), votingResultStakedStart)
518520 votingResultStaked
520522
521523
522524 func getVotingResultStakedIntegral (lpAssetIdStr) = {
523- let $t01995420034 = getVotingEmissionEpochInfo()
524- let lastFinalizedEpoch = $t01995420034._1
525- let currentEpochStartHeight = $t01995420034._2
525+ let $t01998920069 = getVotingEmissionEpochInfo()
526+ let lastFinalizedEpoch = $t01998920069._1
527+ let currentEpochStartHeight = $t01998920069._2
526528 let votingResultStaked = getVotingResultStaked(lpAssetIdStr)
527529 let votingResultStakedIntegralPrev = valueOrElse(getInteger(this, keyVotingResultStakedIntegral(lpAssetIdStr, lastFinalizedEpoch)), 0)
528530 let votingResultStakedLastUpdateHeight = valueOrElse(getInteger(this, keyVotingResultStakedLastUpdateHeight(lpAssetIdStr, lastFinalizedEpoch)), currentEpochStartHeight)
529531 let votingResultStakedIntegralDh = (height - votingResultStakedLastUpdateHeight)
530- let votingResultStakedIntegral = ((votingResultStakedIntegralDh * votingResultStaked) + votingResultStakedIntegralPrev)
531- votingResultStakedIntegral
532+ let votingResultStakedIntegral = ((toBigInt(votingResultStakedIntegralDh) * toBigInt(votingResultStaked)) + toBigInt(votingResultStakedIntegralPrev))
533+ toInt(min([toBigInt(LONG_MAX), votingResultStakedIntegral]))
532534 }
533535
534536
535537 func refreshVotingResultStakedIntegral (lpAssetIdStr,stakedVoteDelta) = {
536- let $t02087120951 = getVotingEmissionEpochInfo()
537- let lastFinalizedEpoch = $t02087120951._1
538- let currentEpochStartHeight = $t02087120951._2
538+ let $t02097721057 = getVotingEmissionEpochInfo()
539+ let lastFinalizedEpoch = $t02097721057._1
540+ let currentEpochStartHeight = $t02097721057._2
539541 let votingResultStaked = getVotingResultStaked(lpAssetIdStr)
540542 let votingResultStakedNew = (votingResultStaked + stakedVoteDelta)
541543 let votingResultStakedIntegral = getVotingResultStakedIntegral(lpAssetIdStr)
544546
545547
546548 func getUserVoteStakedIntegral (lpAssetIdStr,userAddressStr) = {
547- let $t02156221642 = getVotingEmissionEpochInfo()
548- let lastFinalizedEpoch = $t02156221642._1
549- let currentEpochStartHeight = $t02156221642._2
549+ let $t02166821748 = getVotingEmissionEpochInfo()
550+ let lastFinalizedEpoch = $t02166821748._1
551+ let currentEpochStartHeight = $t02166821748._2
550552 let userAddress = addressFromStringValue(userAddressStr)
551553 let userVoteStaked = getUserVoteStaked(lpAssetIdStr, userAddressStr)
552554 let userVoteStakedIntegralPrev = valueOrElse(getInteger(this, keyVoteStakedIntegral(lpAssetIdStr, userAddress, lastFinalizedEpoch)), 0)
553555 let userVoteStakedLastUpdateHeight = valueOrElse(getInteger(this, keyVoteStakedLastUpdateHeight(lpAssetIdStr, userAddress, lastFinalizedEpoch)), currentEpochStartHeight)
554556 let userVoteStakedIntegralDh = (height - userVoteStakedLastUpdateHeight)
555557 let userVoteStakedIntegral = ((toBigInt(userVoteStakedIntegralDh) * toBigInt(userVoteStaked)) + toBigInt(userVoteStakedIntegralPrev))
556- let LONG_MAX = 9223372036854775807
557558 toInt(min([toBigInt(LONG_MAX), userVoteStakedIntegral]))
558559 }
559560
560561
561562 func refreshVoteStakedIntegral (lpAssetIdStr,userAddressStr,edge) = {
562- let $t02256922649 = getVotingEmissionEpochInfo()
563- let lastFinalizedEpoch = $t02256922649._1
564- let currentEpochStartHeight = $t02256922649._2
563+ let $t02263822718 = getVotingEmissionEpochInfo()
564+ let lastFinalizedEpoch = $t02263822718._1
565+ let currentEpochStartHeight = $t02263822718._2
565566 let userAddress = addressFromStringValue(userAddressStr)
566567 let userVoteFinalized = getUserVoteFinalized(lpAssetIdStr, userAddressStr)
567568 let actions = if ((userVoteFinalized == 0))
580581
581582
582583 func getStakedVotesIntegralsDiff (lpAssetIdStr,userAddressStr) = {
583- let $t02350323583 = getVotingEmissionEpochInfo()
584- let lastFinalizedEpoch = $t02350323583._1
585- let currentEpochStartHeight = $t02350323583._2
584+ let $t02357223652 = getVotingEmissionEpochInfo()
585+ let lastFinalizedEpoch = $t02357223652._1
586+ let currentEpochStartHeight = $t02357223652._2
586587 let userAddress = addressFromStringValue(userAddressStr)
587588 let userVoteStakedIntegralLastKey = keyVoteStakedIntegralLast(lpAssetIdStr, userAddress, lastFinalizedEpoch)
588589 let userVoteStakedIntegralLast = valueOrElse(getInteger(this, userVoteStakedIntegralLastKey), 0)
643644 if ((0 > userBoostEmissionIntegral))
644645 then throwErr("wrong calculations")
645646 else {
646- let $t02720227341 = getStakedVotesIntegralsDiff(lpAssetIdStr, userAddressStr)
647- let stakedVotesIntegralsActions = $t02720227341._1
648- let userVoteIntegralDiff = $t02720227341._2
649- let totalVotesIntegralDiff = $t02720227341._3
647+ let $t02727127410 = getStakedVotesIntegralsDiff(lpAssetIdStr, userAddressStr)
648+ let stakedVotesIntegralsActions = $t02727127410._1
649+ let userVoteIntegralDiff = $t02727127410._2
650+ let totalVotesIntegralDiff = $t02727127410._3
650651 let poolUserBoostEmissionIntegral = fraction(userBoostEmissionIntegral, poolWeight, POOLWEIGHTMULT)
651652 let userBoostAvaliableToClaimTotalNew = if ((totalVotesIntegralDiff == 0))
652653 then 0
733734
734735 @Callable(i)
735736 func lockRef (duration,referrerAddress,signature) = {
736- let $t03195232017 = lockActions(i, duration)
737- let lockActionsResult = $t03195232017._1
738- let gWxAmountStart = $t03195232017._2
737+ let $t03202132086 = lockActions(i, duration)
738+ let lockActionsResult = $t03202132086._1
739+ let gWxAmountStart = $t03202132086._2
739740 let referralAddress = toString(i.caller)
740741 let refInv = if (if ((referrerAddress == ""))
741742 then true
756757
757758 @Callable(i)
758759 func lock (duration) = {
759- let $t03247532540 = lockActions(i, duration)
760- let lockActionsResult = $t03247532540._1
761- let gWxAmountStart = $t03247532540._2
760+ let $t03254432609 = lockActions(i, duration)
761+ let lockActionsResult = $t03254432609._1
762+ let gWxAmountStart = $t03254432609._2
762763 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
763764 if ((updateRefActivity == updateRefActivity))
764765 then $Tuple2(lockActionsResult, unit)
822823 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
823824 then throwErr("permissions denied")
824825 else {
825- let $t03564535747 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
826- let userBoostAvailable = $t03564535747._1
827- let dataState = $t03564535747._2
828- let debug = $t03564535747._3
826+ let $t03571435816 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
827+ let userBoostAvailable = $t03571435816._1
828+ let dataState = $t03571435816._2
829+ let debug = $t03571435816._3
829830 $Tuple2(dataState, [userBoostAvailable])
830831 }
831832
833834
834835 @Callable(i)
835836 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
836- let $t03587935980 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
837- let userBoostAvailable = $t03587935980._1
838- let dataState = $t03587935980._2
839- let debug = $t03587935980._3
837+ let $t03594836049 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
838+ let userBoostAvailable = $t03594836049._1
839+ let dataState = $t03594836049._2
840+ let debug = $t03594836049._3
840841 $Tuple2(nil, [userBoostAvailable, debug])
841842 }
842843
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
55
66 let SCALE8 = 8
77
88 let MULT8 = 100000000
99
1010 let POOLWEIGHTMULT = MULT8
11+
12+let LONG_MAX = 9223372036854775807
1113
1214 func wrapErr (msg) = makeString(["boosting.ride:", msg], " ")
1315
1416
1517 func throwErr (msg) = throw(wrapErr(msg))
1618
1719
1820 func strf (address,key) = valueOrErrorMessage(getString(address, key), wrapErr((("mandatory this." + key) + " is not defined")))
1921
2022
2123 func ioz (address,key) = valueOrElse(getInteger(address, key), 0)
2224
2325
2426 func iod (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
2527
2628
2729 func iof (address,key) = valueOrErrorMessage(getInteger(address, key), wrapErr((("mandatory this." + key) + " is not defined")))
2830
2931
3032 func abs (val) = if ((0 > val))
3133 then -(val)
3234 else val
3335
3436
3537 func aal (val) = match val {
3638 case valAnyLyst: List[Any] =>
3739 valAnyLyst
3840 case _ =>
3941 throwErr("fail to cast into List[Any]")
4042 }
4143
4244
4345 func ai (val) = match val {
4446 case valInt: Int =>
4547 valInt
4648 case _ =>
4749 throwErr("fail to cast into Int")
4850 }
4951
5052
5153 func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
5254
5355
5456 let referralsContractAddressOrFail = addressFromStringValue(strf(this, keyReferralsContractAddress()))
5557
5658 let keyReferralProgramName = makeString(["%s%s", "referral", "programName"], SEP)
5759
5860 let referralProgramNameDefault = "wxlock"
5961
6062 let referralProgramName = valueOrElse(getString(this, keyReferralProgramName), referralProgramNameDefault)
6163
6264 func keyFactoryAddress () = "%s%s__config__factoryAddress"
6365
6466
6567 let IdxFactoryCfgStakingDapp = 1
6668
6769 let IdxFactoryCfgBoostingDapp = 2
6870
6971 let IdxFactoryCfgIdoDapp = 3
7072
7173 let IdxFactoryCfgTeamDapp = 4
7274
7375 let IdxFactoryCfgEmissionDapp = 5
7476
7577 let IdxFactoryCfgRestDapp = 6
7678
7779 let IdxFactoryCfgSlippageDapp = 7
7880
7981 let IdxFactoryCfgDaoDapp = 8
8082
8183 let IdxFactoryCfgMarketingDapp = 9
8284
8385 let IdxFactoryCfgGwxRewardDapp = 10
8486
8587 let IdxFactoryCfgBirdsDapp = 11
8688
8789 func keyFactoryCfg () = "%s__factoryConfig"
8890
8991
9092 func keyFactoryLpList () = "%s__lpTokensList"
9193
9294
9395 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
9496
9597
9698 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
9799
98100
99101 func keyFactoryPoolWeightHistory (poolAddress,num) = ((("%s%s__poolWeight__" + poolAddress) + "__") + toString(num))
100102
101103
102104 func readFactoryAddressOrFail () = addressFromStringValue(strf(this, keyFactoryAddress()))
103105
104106
105107 func readLpList () = split(valueOrElse(getString(readFactoryAddressOrFail(), keyFactoryLpList()), ""), SEP)
106108
107109
108110 func readFactoryCfgOrFail (factory) = split(strf(factory, keyFactoryCfg()), SEP)
109111
110112
111113 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
112114
113115
114116 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
115117
116118
117119 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
118120
119121
120122 func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
121123
122124
123125 func keyManagerPublicKey () = "%s__managerPublicKey"
124126
125127
126128 func keyManagerVaultAddress () = "%s__managerVaultAddress"
127129
128130
129131 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
130132
131133
132134 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
133135
134136
135137 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
136138
137139
138140 func keyBoostingV2LastUpdateHeight () = "%s%s__boostingV2__startBlock"
139141
140142
141143 func keyBoostingV2Integral () = "%s%s__boostingV2__integral"
142144
143145
144146 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
145147
146148
147149 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
148150
149151
150152 func keyNextPeriod () = "%s__nextPeriod"
151153
152154
153155 func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
154156
155157
156158 let IdxCfgAssetId = 1
157159
158160 let IdxCfgMinLockAmount = 2
159161
160162 let IdxCfgMinLockDuration = 3
161163
162164 let IdxCfgMaxLockDuration = 4
163165
164166 let IdxCfgMathContract = 5
165167
166168 func keyConfig () = "%s__config"
167169
168170
169171 func readConfigArrayOrFail () = split(strf(this, keyConfig()), SEP)
170172
171173
172174 let mathContract = addressFromStringValue(readConfigArrayOrFail()[IdxCfgMathContract])
173175
174176 func formatConfigS (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = makeString(["%s%d%d%d", assetId, minLockAmount, minLockDuration, maxLockDuration, mathContract], SEP)
175177
176178
177179 func formatConfig (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = formatConfigS(assetId, toString(minLockAmount), toString(minLockDuration), toString(maxLockDuration), mathContract)
178180
179181
180182 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
181183 case s: String =>
182184 addressFromStringValue(s)
183185 case _ =>
184186 this
185187 }
186188
187189
188190 func managerPublicKeyOrUnit () = {
189191 let managerVaultAddress = getManagerVaultAddressOrThis()
190192 match getString(managerVaultAddress, keyManagerPublicKey()) {
191193 case s: String =>
192194 fromBase58String(s)
193195 case _: Unit =>
194196 unit
195197 case _ =>
196198 throw("Match error")
197199 }
198200 }
199201
200202
201203 func mustManager (i) = {
202204 let pd = throwErr("Permission denied")
203205 match managerPublicKeyOrUnit() {
204206 case pk: ByteVector =>
205207 if ((i.callerPublicKey == pk))
206208 then true
207209 else pd
208210 case _: Unit =>
209211 if ((i.caller == this))
210212 then true
211213 else pd
212214 case _ =>
213215 throw("Match error")
214216 }
215217 }
216218
217219
218220 let IdxLockUserNum = 1
219221
220222 let IdxLockAmount = 2
221223
222224 let IdxLockStart = 3
223225
224226 let IdxLockDuration = 4
225227
226228 let IdxLockParamK = 5
227229
228230 let IdxLockParamB = 6
229231
230232 func keyLockParamsRecord (userAddress) = makeString(["%s%s__lock", userAddress], SEP)
231233
232234
233235 func readLockParamsRecordOrFail (userAddress) = split(strf(this, keyLockParamsRecord(userAddress)), SEP)
234236
235237
236238 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)
237239
238240
239241 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))
240242
241243
242244 func keyNextUserNum () = "%s__nextUserNum"
243245
244246
245247 func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", userAddress], SEP)
246248
247249
248250 func keyNum2UserMapping (num) = makeString(["%s%s%s__mapping__num2user", num], SEP)
249251
250252
251253 func keyLockParamUserAmount (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "amount"], SEP)
252254
253255
254256 func keyLockParamStartBlock (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "start"], SEP)
255257
256258
257259 func keyLockParamDuration (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "duration"], SEP)
258260
259261
260262 func keyLockParamK (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "k"], SEP)
261263
262264
263265 func keyLockParamB (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "b"], SEP)
264266
265267
266268 func keyLockParamByPeriodK (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "k", period], SEP)
267269
268270
269271 func keyLockParamByPeriodB (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "b", period], SEP)
270272
271273
272274 func keyLockParamTotalAmount () = "%s%s__stats__activeTotalLocked"
273275
274276
275277 func keyStatsLocksDurationSumInBlocks () = "%s%s__stats__locksDurationSumInBlocks"
276278
277279
278280 func keyStatsLocksCount () = "%s%s__stats__locksCount"
279281
280282
281283 func keyStatsUsersCount () = "%s%s__stats__activeUsersCount"
282284
283285
284286 func keyUserBoostEmissionLastINTEGRAL (userNum) = makeString(["%s%d__userBoostEmissionLastIntV2", userNum], SEP)
285287
286288
287289 func keyUserLpBoostEmissionLastINTEGRAL (userNum,lpAssetId) = makeString(["%s%d__userBoostEmissionLastIntV2", userNum, lpAssetId], SEP)
288290
289291
290292 func keyUserMaxBoostINTEGRAL (userNum) = makeString(["%s%d__maxBoostInt", userNum], SEP)
291293
292294
293295 func keyTotalMaxBoostINTEGRAL () = "%s%s__maxBoostInt__total"
294296
295297
296298 func keyUserBoostAvalaibleToClaimTotal (userNum) = makeString(["%s%d__userBoostAvaliableToClaimTotal", userNum], SEP)
297299
298300
299301 func keyUserBoostClaimed (userNum) = makeString(["%s%d__userBoostClaimed", userNum], SEP)
300302
301303
302304 func keyTotalCachedGwx () = "%s%s__gwxCached__total"
303305
304306
305307 func keyTotalCachedGwxCorrective () = "%s__gwxCachedTotalCorrective"
306308
307309
308310 func keyVote (amountAssetId,priceAssetId,address,epoch) = makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], SEP)
309311
310312
311313 func keyStartHeightByEpoch (epoch) = makeString(["%s%d", "startHeight", toString(epoch)], SEP)
312314
313315
314316 func keyCurrentEpochUi () = makeString(["%s", "currentEpochUi"], SEP)
315317
316318
317319 func keyVotingResultStaked (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStaked", lpAssetIdStr, toString(epoch)], SEP)
318320
319321
320322 func keyVotingResultStakedIntegral (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStakedIntegral", lpAssetIdStr, toString(epoch)], SEP)
321323
322324
323325 func keyVotingResultStakedLastUpdateHeight (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStakedIntegralLastUpdateHeight", lpAssetIdStr, toString(epoch)], SEP)
324326
325327
326328 func keyVotingResultStakedIntegralLast (lpAssetIdStr,address,epoch) = makeString(["%s%s%s%d", "votingResultStakedIntegralLast", lpAssetIdStr, toString(address), toString(epoch)], SEP)
327329
328330
329331 func keyVoteStakedIntegral (lpAssetIdStr,address,epoch) = makeString(["%s%s%s%d", "voteStakedIntegral", lpAssetIdStr, toString(address), toString(epoch)], SEP)
330332
331333
332334 func keyVoteStakedLastUpdateHeight (lpAssetIdStr,address,epoch) = makeString(["%s%s%s%d", "voteStakedIntegralLastUpdateHeight", lpAssetIdStr, toString(address), toString(epoch)], SEP)
333335
334336
335337 func keyVoteStakedIntegralLast (lpAssetIdStr,address,epoch) = makeString(["%s%s%s%d", "voteStakedIntegralLast", lpAssetIdStr, toString(address), toString(epoch)], SEP)
336338
337339
338340 func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s", "staked", userAddressStr, lpAssetIdStr], SEP)
339341
340342
341343 let factoryContract = readFactoryAddressOrFail()
342344
343345 let factoryCfg = readFactoryCfgOrFail(factoryContract)
344346
345347 let emissionContract = getEmissionAddressOrFail(factoryCfg)
346348
347349 let stakingContract = getStakingAddressOrFail(factoryCfg)
348350
349351 let gwxRewardContract = getGwxRewardAddressOrFail(factoryCfg)
350352
351353 let lpStakingPoolsContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(makeString(["%s", "lpStakingPoolsContract"], SEP)), wrapErr("lp_staking_pools contract address is undefined"))), wrapErr("invalid lp_staking_pools contract address"))
352354
353355 let keyVotingEmissionContract = makeString(["%s", "votingEmissionContract"], SEP)
354356
355357 let votingEmissionContract = addressFromStringValue(getStringValue(factoryContract, keyVotingEmissionContract))
356358
357359 let boostCoeff = {
358360 let @ = invoke(emissionContract, "getBoostCoeffREADONLY", nil, nil)
359361 if ($isInstanceOf(@, "Int"))
360362 then @
361363 else throw(($getType(@) + " couldn't be cast to Int"))
362364 }
363365
364366 func getTotalCachedGwx (correct) = {
365367 let currentEpochUi = getIntegerValue(votingEmissionContract, keyCurrentEpochUi())
366368 let keyTargetEpoch = makeString(["%s%s", "totalCachedGwxCorrection__activationEpoch"], SEP)
367369 let targetEpochOption = getInteger(this, keyTargetEpoch)
368370 let totalCachedGwxRaw = valueOrElse(getInteger(this, keyTotalCachedGwx()), 0)
369371 let isCorrectionActivated = if (isDefined(targetEpochOption))
370372 then (currentEpochUi >= value(targetEpochOption))
371373 else false
372374 let corrective = if (if (isCorrectionActivated)
373375 then correct
374376 else false)
375377 then valueOrElse(getInteger(this, keyTotalCachedGwxCorrective()), 0)
376378 else 0
377379 max([0, (totalCachedGwxRaw + corrective)])
378380 }
379381
380382
381383 func HistoryEntry (type,user,amount,lockStart,duration,k,b,i) = {
382384 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
383385 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)
384386 StringEntry(historyKEY, historyDATA)
385387 }
386388
387389
388390 func StatsEntry (totalLockedInc,durationInc,lockCountInc,usersCountInc) = {
389391 let locksDurationSumInBlocksKEY = keyStatsLocksDurationSumInBlocks()
390392 let locksCountKEY = keyStatsLocksCount()
391393 let usersCountKEY = keyStatsUsersCount()
392394 let totalAmountKEY = keyLockParamTotalAmount()
393395 let locksDurationSumInBlocks = ioz(this, locksDurationSumInBlocksKEY)
394396 let locksCount = ioz(this, locksCountKEY)
395397 let usersCount = ioz(this, usersCountKEY)
396398 let totalAmount = ioz(this, totalAmountKEY)
397399 [IntegerEntry(locksDurationSumInBlocksKEY, (locksDurationSumInBlocks + durationInc)), IntegerEntry(locksCountKEY, (locksCount + lockCountInc)), IntegerEntry(usersCountKEY, (usersCount + usersCountInc)), IntegerEntry(totalAmountKEY, (totalAmount + totalLockedInc))]
398400 }
399401
400402
401403 func calcGwxAmount (kRaw,bRaw,h) = {
402404 let SCALE = 1000
403405 (((kRaw * h) + bRaw) / SCALE)
404406 }
405407
406408
407409 func LockParamsEntry (userAddress,userNum,amount,start,duration,k,b,period) = {
408410 let userAmountKEY = keyLockParamUserAmount(userNum)
409411 let startBlockKEY = keyLockParamStartBlock(userNum)
410412 let durationKEY = keyLockParamDuration(userNum)
411413 let kKEY = keyLockParamK(userNum)
412414 let bKEY = keyLockParamB(userNum)
413415 let kByPeriodKEY = keyLockParamByPeriodK(userNum, period)
414416 let bByPeriodKEY = keyLockParamByPeriodB(userNum, period)
415417 let gwxAmount = calcGwxAmount(k, b, height)
416418 [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))]
417419 }
418420
419421
420422 func extractOptionalPaymentAmountOrFail (i,expectedAssetId) = if ((size(i.payments) > 1))
421423 then throwErr("only one payment is allowed")
422424 else if ((size(i.payments) == 0))
423425 then 0
424426 else {
425427 let pmt = i.payments[0]
426428 if ((value(pmt.assetId) != expectedAssetId))
427429 then throwErr("invalid asset id in payment")
428430 else pmt.amount
429431 }
430432
431433
432434 func calcUserGwxAmountAtHeight (userAddress,targetHeight) = {
433435 let EMPTY = "empty"
434436 let user2NumMappingKEY = keyUser2NumMapping(userAddress)
435437 let userNum = valueOrElse(getString(user2NumMappingKEY), EMPTY)
436438 let k = valueOrElse(getInteger(keyLockParamK(userNum)), 0)
437439 let b = valueOrElse(getInteger(keyLockParamB(userNum)), 0)
438440 let gwxAmountCalc = calcGwxAmount(k, b, targetHeight)
439441 let gwxAmount = if ((0 > gwxAmountCalc))
440442 then 0
441443 else gwxAmountCalc
442444 gwxAmount
443445 }
444446
445447
446448 func calcCurrentGwxAmount (userAddress) = calcUserGwxAmountAtHeight(userAddress, height)
447449
448450
449451 func getVotingEmissionEpochInfo () = {
450- let $t01782918119 = {
452+ let $t01786418154 = {
451453 let currentEpochUi = value(getInteger(votingEmissionContract, keyCurrentEpochUi()))
452454 let lastFinalizedEpoch = (currentEpochUi - 1)
453455 if ((0 > lastFinalizedEpoch))
454456 then throwErr("invalid epoch")
455457 else $Tuple2(currentEpochUi, lastFinalizedEpoch)
456458 }
457- let currentEpochUi = $t01782918119._1
458- let lastFinalizedEpoch = $t01782918119._2
459+ let currentEpochUi = $t01786418154._1
460+ let lastFinalizedEpoch = $t01786418154._2
459461 let currentEpochStartHeight = value(getInteger(votingEmissionContract, keyStartHeightByEpoch(currentEpochUi)))
460462 $Tuple2(lastFinalizedEpoch, currentEpochStartHeight)
461463 }
462464
463465
464466 func getPoolAssetsByLpAssetId (lpAssetIdStr) = {
465467 let idxAmountAssetId = 4
466468 let idxPriceAssetId = 5
467469 let poolCfg = {
468470 let @ = invoke(factoryContract, "getPoolConfigByLpAssetIdREADONLY", [lpAssetIdStr], nil)
469471 if ($isInstanceOf(@, "List[Any]"))
470472 then @
471473 else throw(($getType(@) + " couldn't be cast to List[Any]"))
472474 }
473475 let amountAssetId = {
474476 let @ = poolCfg[idxAmountAssetId]
475477 if ($isInstanceOf(@, "String"))
476478 then @
477479 else throw(($getType(@) + " couldn't be cast to String"))
478480 }
479481 let priceAssetId = {
480482 let @ = poolCfg[idxPriceAssetId]
481483 if ($isInstanceOf(@, "String"))
482484 then @
483485 else throw(($getType(@) + " couldn't be cast to String"))
484486 }
485487 $Tuple2(amountAssetId, priceAssetId)
486488 }
487489
488490
489491 func getUserVoteFinalized (lpAssetIdStr,userAddressStr) = {
490492 let userAddress = addressFromStringValue(userAddressStr)
491- let $t01881018890 = getVotingEmissionEpochInfo()
492- let lastFinalizedEpoch = $t01881018890._1
493- let currentEpochStartHeight = $t01881018890._2
494- let $t01889318968 = getPoolAssetsByLpAssetId(lpAssetIdStr)
495- let amountAssetId = $t01889318968._1
496- let priceAssetId = $t01889318968._2
493+ let $t01884518925 = getVotingEmissionEpochInfo()
494+ let lastFinalizedEpoch = $t01884518925._1
495+ let currentEpochStartHeight = $t01884518925._2
496+ let $t01892819003 = getPoolAssetsByLpAssetId(lpAssetIdStr)
497+ let amountAssetId = $t01892819003._1
498+ let priceAssetId = $t01892819003._2
497499 let userVoteKey = keyVote(amountAssetId, priceAssetId, userAddress, lastFinalizedEpoch)
498500 let userVote = valueOrElse(getInteger(votingEmissionContract, userVoteKey), 0)
499501 userVote
500502 }
501503
502504
503505 func getUserVoteStaked (lpAssetIdStr,userAddressStr) = {
504506 let stakedByUser = valueOrElse(getInteger(stakingContract, keyStakedByUser(userAddressStr, lpAssetIdStr)), 0)
505507 let userVote = getUserVoteFinalized(lpAssetIdStr, userAddressStr)
506508 if ((stakedByUser == 0))
507509 then 0
508510 else userVote
509511 }
510512
511513
512514 func getVotingResultStaked (lpAssetIdStr) = {
513- let $t01951219592 = getVotingEmissionEpochInfo()
514- let lastFinalizedEpoch = $t01951219592._1
515- let currentEpochStartHeight = $t01951219592._2
515+ let $t01954719627 = getVotingEmissionEpochInfo()
516+ let lastFinalizedEpoch = $t01954719627._1
517+ let currentEpochStartHeight = $t01954719627._2
516518 let votingResultStakedStart = valueOrElse(getInteger(votingEmissionContract, keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch)), 0)
517519 let votingResultStaked = valueOrElse(getInteger(this, keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch)), votingResultStakedStart)
518520 votingResultStaked
519521 }
520522
521523
522524 func getVotingResultStakedIntegral (lpAssetIdStr) = {
523- let $t01995420034 = getVotingEmissionEpochInfo()
524- let lastFinalizedEpoch = $t01995420034._1
525- let currentEpochStartHeight = $t01995420034._2
525+ let $t01998920069 = getVotingEmissionEpochInfo()
526+ let lastFinalizedEpoch = $t01998920069._1
527+ let currentEpochStartHeight = $t01998920069._2
526528 let votingResultStaked = getVotingResultStaked(lpAssetIdStr)
527529 let votingResultStakedIntegralPrev = valueOrElse(getInteger(this, keyVotingResultStakedIntegral(lpAssetIdStr, lastFinalizedEpoch)), 0)
528530 let votingResultStakedLastUpdateHeight = valueOrElse(getInteger(this, keyVotingResultStakedLastUpdateHeight(lpAssetIdStr, lastFinalizedEpoch)), currentEpochStartHeight)
529531 let votingResultStakedIntegralDh = (height - votingResultStakedLastUpdateHeight)
530- let votingResultStakedIntegral = ((votingResultStakedIntegralDh * votingResultStaked) + votingResultStakedIntegralPrev)
531- votingResultStakedIntegral
532+ let votingResultStakedIntegral = ((toBigInt(votingResultStakedIntegralDh) * toBigInt(votingResultStaked)) + toBigInt(votingResultStakedIntegralPrev))
533+ toInt(min([toBigInt(LONG_MAX), votingResultStakedIntegral]))
532534 }
533535
534536
535537 func refreshVotingResultStakedIntegral (lpAssetIdStr,stakedVoteDelta) = {
536- let $t02087120951 = getVotingEmissionEpochInfo()
537- let lastFinalizedEpoch = $t02087120951._1
538- let currentEpochStartHeight = $t02087120951._2
538+ let $t02097721057 = getVotingEmissionEpochInfo()
539+ let lastFinalizedEpoch = $t02097721057._1
540+ let currentEpochStartHeight = $t02097721057._2
539541 let votingResultStaked = getVotingResultStaked(lpAssetIdStr)
540542 let votingResultStakedNew = (votingResultStaked + stakedVoteDelta)
541543 let votingResultStakedIntegral = getVotingResultStakedIntegral(lpAssetIdStr)
542544 [IntegerEntry(keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch), votingResultStakedNew), IntegerEntry(keyVotingResultStakedLastUpdateHeight(lpAssetIdStr, lastFinalizedEpoch), height), IntegerEntry(keyVotingResultStakedIntegral(lpAssetIdStr, lastFinalizedEpoch), votingResultStakedIntegral)]
543545 }
544546
545547
546548 func getUserVoteStakedIntegral (lpAssetIdStr,userAddressStr) = {
547- let $t02156221642 = getVotingEmissionEpochInfo()
548- let lastFinalizedEpoch = $t02156221642._1
549- let currentEpochStartHeight = $t02156221642._2
549+ let $t02166821748 = getVotingEmissionEpochInfo()
550+ let lastFinalizedEpoch = $t02166821748._1
551+ let currentEpochStartHeight = $t02166821748._2
550552 let userAddress = addressFromStringValue(userAddressStr)
551553 let userVoteStaked = getUserVoteStaked(lpAssetIdStr, userAddressStr)
552554 let userVoteStakedIntegralPrev = valueOrElse(getInteger(this, keyVoteStakedIntegral(lpAssetIdStr, userAddress, lastFinalizedEpoch)), 0)
553555 let userVoteStakedLastUpdateHeight = valueOrElse(getInteger(this, keyVoteStakedLastUpdateHeight(lpAssetIdStr, userAddress, lastFinalizedEpoch)), currentEpochStartHeight)
554556 let userVoteStakedIntegralDh = (height - userVoteStakedLastUpdateHeight)
555557 let userVoteStakedIntegral = ((toBigInt(userVoteStakedIntegralDh) * toBigInt(userVoteStaked)) + toBigInt(userVoteStakedIntegralPrev))
556- let LONG_MAX = 9223372036854775807
557558 toInt(min([toBigInt(LONG_MAX), userVoteStakedIntegral]))
558559 }
559560
560561
561562 func refreshVoteStakedIntegral (lpAssetIdStr,userAddressStr,edge) = {
562- let $t02256922649 = getVotingEmissionEpochInfo()
563- let lastFinalizedEpoch = $t02256922649._1
564- let currentEpochStartHeight = $t02256922649._2
563+ let $t02263822718 = getVotingEmissionEpochInfo()
564+ let lastFinalizedEpoch = $t02263822718._1
565+ let currentEpochStartHeight = $t02263822718._2
565566 let userAddress = addressFromStringValue(userAddressStr)
566567 let userVoteFinalized = getUserVoteFinalized(lpAssetIdStr, userAddressStr)
567568 let actions = if ((userVoteFinalized == 0))
568569 then nil
569570 else {
570571 let stakedVoteDelta = if (edge)
571572 then userVoteFinalized
572573 else -(userVoteFinalized)
573574 let votingResultActions = refreshVotingResultStakedIntegral(lpAssetIdStr, stakedVoteDelta)
574575 let userVoteStakedIntegral = getUserVoteStakedIntegral(lpAssetIdStr, userAddressStr)
575576 let voteActions = [IntegerEntry(keyVoteStakedLastUpdateHeight(lpAssetIdStr, userAddress, lastFinalizedEpoch), height), IntegerEntry(keyVoteStakedIntegral(lpAssetIdStr, userAddress, lastFinalizedEpoch), userVoteStakedIntegral)]
576577 (votingResultActions ++ voteActions)
577578 }
578579 actions
579580 }
580581
581582
582583 func getStakedVotesIntegralsDiff (lpAssetIdStr,userAddressStr) = {
583- let $t02350323583 = getVotingEmissionEpochInfo()
584- let lastFinalizedEpoch = $t02350323583._1
585- let currentEpochStartHeight = $t02350323583._2
584+ let $t02357223652 = getVotingEmissionEpochInfo()
585+ let lastFinalizedEpoch = $t02357223652._1
586+ let currentEpochStartHeight = $t02357223652._2
586587 let userAddress = addressFromStringValue(userAddressStr)
587588 let userVoteStakedIntegralLastKey = keyVoteStakedIntegralLast(lpAssetIdStr, userAddress, lastFinalizedEpoch)
588589 let userVoteStakedIntegralLast = valueOrElse(getInteger(this, userVoteStakedIntegralLastKey), 0)
589590 let votingResultStakedIntegralLastKey = keyVotingResultStakedIntegralLast(lpAssetIdStr, userAddress, lastFinalizedEpoch)
590591 let votingResultStakedIntegralLast = valueOrElse(getInteger(this, votingResultStakedIntegralLastKey), 0)
591592 let userVoteStakedIntegral = getUserVoteStakedIntegral(lpAssetIdStr, userAddressStr)
592593 let votingResultStakedIntegral = getVotingResultStakedIntegral(lpAssetIdStr)
593594 let userVoteStakedIntegralDiff = (userVoteStakedIntegral - userVoteStakedIntegralLast)
594595 let votingResultStakedIntegralDiff = (votingResultStakedIntegral - votingResultStakedIntegralLast)
595596 $Tuple3([IntegerEntry(userVoteStakedIntegralLastKey, userVoteStakedIntegral), IntegerEntry(votingResultStakedIntegralLastKey, votingResultStakedIntegral)], userVoteStakedIntegralDiff, votingResultStakedIntegralDiff)
596597 }
597598
598599
599600 func refreshBoostEmissionIntegral () = {
600601 let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
601602 let boostingV2LastUpdateHeightOption = getInteger(this, keyBoostingV2LastUpdateHeight())
602603 let boostingV2IngergalOption = getInteger(this, keyBoostingV2Integral())
603604 let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
604605 let h = if ((height > emissionEnd))
605606 then emissionEnd
606607 else height
607608 let dh = match boostingV2LastUpdateHeightOption {
608609 case lastUpdateHeight: Int =>
609610 max([(h - lastUpdateHeight), 0])
610611 case _: Unit =>
611612 0
612613 case _ =>
613614 throw("Match error")
614615 }
615616 let boostEmissionPerBlock = ((wxEmissionPerBlock * (boostCoeff - 1)) / boostCoeff)
616617 let boostEmissionIntegralPrev = valueOrElse(boostingV2IngergalOption, 0)
617618 let boostEmissionIntegral = ((boostEmissionPerBlock * dh) + boostEmissionIntegralPrev)
618619 $Tuple2([IntegerEntry(keyBoostingV2Integral(), boostEmissionIntegral), IntegerEntry(keyBoostingV2LastUpdateHeight(), height)], boostEmissionIntegral)
619620 }
620621
621622
622623 func internalClaimWxBoost (lpAssetIdStr,userAddressStr,readOnly) = {
623624 let userRecordOption = getString(this, keyLockParamsRecord(userAddressStr))
624625 if ((userRecordOption == unit))
625626 then $Tuple3(0, nil, "userRecord::is::empty")
626627 else {
627628 let userRecordArray = split(value(userRecordOption), SEP)
628629 let userNumStr = userRecordArray[IdxLockUserNum]
629630 let EMPTYSTR = "empty"
630631 let poolWeight = if ((lpAssetIdStr != EMPTYSTR))
631632 then {
632633 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr)), wrapErr(("unsupported lp asset " + lpAssetIdStr)))
633634 getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
634635 }
635636 else if (readOnly)
636637 then 0
637638 else throwErr(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
638639 let userLpBoostEmissionLastIntegralKEY = keyUserLpBoostEmissionLastINTEGRAL(userNumStr, lpAssetIdStr)
639640 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
640641 let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), ioz(this, userBoostEmissionLastIntegralKEY))
641642 let boostEmissionIntegral = refreshBoostEmissionIntegral()._2
642643 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
643644 if ((0 > userBoostEmissionIntegral))
644645 then throwErr("wrong calculations")
645646 else {
646- let $t02720227341 = getStakedVotesIntegralsDiff(lpAssetIdStr, userAddressStr)
647- let stakedVotesIntegralsActions = $t02720227341._1
648- let userVoteIntegralDiff = $t02720227341._2
649- let totalVotesIntegralDiff = $t02720227341._3
647+ let $t02727127410 = getStakedVotesIntegralsDiff(lpAssetIdStr, userAddressStr)
648+ let stakedVotesIntegralsActions = $t02727127410._1
649+ let userVoteIntegralDiff = $t02727127410._2
650+ let totalVotesIntegralDiff = $t02727127410._3
650651 let poolUserBoostEmissionIntegral = fraction(userBoostEmissionIntegral, poolWeight, POOLWEIGHTMULT)
651652 let userBoostAvaliableToClaimTotalNew = if ((totalVotesIntegralDiff == 0))
652653 then 0
653654 else fraction(poolUserBoostEmissionIntegral, userVoteIntegralDiff, totalVotesIntegralDiff)
654655 let dataState = ([IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)] ++ stakedVotesIntegralsActions)
655656 let debug = makeString([toString(userBoostEmissionLastIntegral), toString(userBoostEmissionIntegral), toString(poolWeight), toString(userVoteIntegralDiff), toString(totalVotesIntegralDiff)], ":")
656657 $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
657658 }
658659 }
659660 }
660661
661662
662663 func lockActions (i,duration) = {
663664 let cfgArray = readConfigArrayOrFail()
664665 let assetIdStr = cfgArray[IdxCfgAssetId]
665666 let assetId = fromBase58String(assetIdStr)
666667 let minLockAmount = parseIntValue(cfgArray[IdxCfgMinLockAmount])
667668 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
668669 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
669670 if ((size(i.payments) != 1))
670671 then throwErr("invalid payment - exact one payment must be attached")
671672 else {
672673 let pmt = i.payments[0]
673674 let pmtAmount = pmt.amount
674675 if ((assetId != value(pmt.assetId)))
675676 then throwErr((("invalid asset is in payment - " + assetIdStr) + " is expected"))
676677 else {
677678 let nextUserNumKEY = keyNextUserNum()
678679 let userAddressStr = toString(i.caller)
679680 let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
680681 let userNumStr = if (userIsExisting)
681682 then value(getString(keyUser2NumMapping(userAddressStr)))
682683 else toString(iof(this, nextUserNumKEY))
683684 let userNum = parseIntValue(userNumStr)
684685 let lockStart = height
685686 let startBlockKEY = keyLockParamStartBlock(userNumStr)
686687 let durationKEY = keyLockParamDuration(userNumStr)
687688 let userAmountKEY = keyLockParamUserAmount(userNumStr)
688689 if (if ((minLockAmount > pmtAmount))
689690 then (i.caller != lpStakingPoolsContract)
690691 else false)
691692 then throwErr(("amount is less then minLockAmount=" + toString(minLockAmount)))
692693 else if ((minLockDuration > duration))
693694 then throwErr(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
694695 else if ((duration > maxLockDuration))
695696 then throwErr(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
696697 else if (if (userIsExisting)
697698 then ((iof(this, startBlockKEY) + iof(this, durationKEY)) >= lockStart)
698699 else false)
699700 then throwErr("there is an active lock - consider to use increaseLock")
700701 else if ((ioz(this, userAmountKEY) > 0))
701702 then throwErr(("there are locked WXs - consider to use increaseLock " + userAmountKEY))
702703 else {
703704 let coeffX8 = fraction(duration, MULT8, maxLockDuration)
704705 let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
705706 let gWxParamsResultList = aal(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
706707 let k = ai(gWxParamsResultList[0])
707708 let b = ai(gWxParamsResultList[1])
708709 let period = toString(ai(gWxParamsResultList[2]))
709710 let totalCachedGwxRaw = getTotalCachedGwx(false)
710711 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
711712 let boostEmissionIntegral = refreshBoostEmissionIntegral()._2
712713 let arr = if (userIsExisting)
713714 then nil
714715 else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
715716 $Tuple2(((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
716717 then 0
717718 else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(keyTotalCachedGwx(), (totalCachedGwxRaw + gWxAmountStart))]), gWxAmountStart)
718719 }
719720 }
720721 }
721722 }
722723
723724
724725 @Callable(i)
725726 func constructor (factoryAddressStr,lockAssetIdStr,minLockAmount,minDuration,maxDuration,mathContract) = {
726727 let checkCaller = mustManager(i)
727728 if ((checkCaller == checkCaller))
728729 then ([IntegerEntry(keyNextUserNum(), 0), StringEntry(keyConfig(), formatConfig(lockAssetIdStr, minLockAmount, minDuration, maxDuration, mathContract)), StringEntry(keyFactoryAddress(), factoryAddressStr)] ++ StatsEntry(0, 0, 0, 0))
729730 else throw("Strict value is not equal to itself.")
730731 }
731732
732733
733734
734735 @Callable(i)
735736 func lockRef (duration,referrerAddress,signature) = {
736- let $t03195232017 = lockActions(i, duration)
737- let lockActionsResult = $t03195232017._1
738- let gWxAmountStart = $t03195232017._2
737+ let $t03202132086 = lockActions(i, duration)
738+ let lockActionsResult = $t03202132086._1
739+ let gWxAmountStart = $t03202132086._2
739740 let referralAddress = toString(i.caller)
740741 let refInv = if (if ((referrerAddress == ""))
741742 then true
742743 else (signature == base58''))
743744 then unit
744745 else invoke(referralsContractAddressOrFail, "createPair", [referralProgramName, referrerAddress, referralAddress, signature], nil)
745746 if ((refInv == refInv))
746747 then {
747748 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
748749 if ((updateRefActivity == updateRefActivity))
749750 then $Tuple2(lockActionsResult, unit)
750751 else throw("Strict value is not equal to itself.")
751752 }
752753 else throw("Strict value is not equal to itself.")
753754 }
754755
755756
756757
757758 @Callable(i)
758759 func lock (duration) = {
759- let $t03247532540 = lockActions(i, duration)
760- let lockActionsResult = $t03247532540._1
761- let gWxAmountStart = $t03247532540._2
760+ let $t03254432609 = lockActions(i, duration)
761+ let lockActionsResult = $t03254432609._1
762+ let gWxAmountStart = $t03254432609._2
762763 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
763764 if ((updateRefActivity == updateRefActivity))
764765 then $Tuple2(lockActionsResult, unit)
765766 else throw("Strict value is not equal to itself.")
766767 }
767768
768769
769770
770771 @Callable(i)
771772 func increaseLock (deltaDuration) = {
772773 let cfgArray = readConfigArrayOrFail()
773774 let assetIdStr = cfgArray[IdxCfgAssetId]
774775 let assetId = fromBase58String(assetIdStr)
775776 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
776777 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
777778 let pmtAmount = extractOptionalPaymentAmountOrFail(i, assetId)
778779 let userAddressStr = toString(i.caller)
779780 let userRecordArray = readLockParamsRecordOrFail(userAddressStr)
780781 let userNumStr = userRecordArray[IdxLockUserNum]
781782 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
782783 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
783784 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
784785 let lockEnd = (lockStart + lockDuration)
785786 let remainingDuration = max([(lockEnd - height), 0])
786787 let userAmountNew = (userAmount + pmtAmount)
787788 let lockDurationNew = (remainingDuration + deltaDuration)
788789 if ((0 > deltaDuration))
789790 then throwErr("duration is less then zero")
790791 else if ((minLockDuration > lockDurationNew))
791792 then throwErr(("lockDurationNew is less then minLockDuration=" + toString(minLockDuration)))
792793 else if ((lockDurationNew > maxLockDuration))
793794 then throwErr(("deltaDuration + existedLockDuration is greater then maxLockDuration=" + toString(maxLockDuration)))
794795 else {
795796 let coeffX8 = fraction(lockDurationNew, MULT8, maxLockDuration)
796797 let gWxAmountStart = fraction(userAmountNew, coeffX8, MULT8)
797798 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
798799 if ((updateRefActivity == updateRefActivity))
799800 then {
800801 let lockStartNew = height
801802 let gWxParamsResultList = aal(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStartNew, lockDurationNew], nil))
802803 let k = ai(gWxParamsResultList[0])
803804 let b = ai(gWxParamsResultList[1])
804805 let period = toString(ai(gWxParamsResultList[2]))
805806 let currUserGwx = calcCurrentGwxAmount(userAddressStr)
806807 let gwxDiff = (gWxAmountStart - currUserGwx)
807808 if ((0 > gwxDiff))
808809 then throwErr(("gwxDiff is less then 0: " + toString(gwxDiff)))
809810 else {
810811 let totalCachedGwxRaw = getTotalCachedGwx(false)
811812 let totalCachedGwxCorrected = getTotalCachedGwx(true)
812813 (((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))])
813814 }
814815 }
815816 else throw("Strict value is not equal to itself.")
816817 }
817818 }
818819
819820
820821
821822 @Callable(i)
822823 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
823824 then throwErr("permissions denied")
824825 else {
825- let $t03564535747 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
826- let userBoostAvailable = $t03564535747._1
827- let dataState = $t03564535747._2
828- let debug = $t03564535747._3
826+ let $t03571435816 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
827+ let userBoostAvailable = $t03571435816._1
828+ let dataState = $t03571435816._2
829+ let debug = $t03571435816._3
829830 $Tuple2(dataState, [userBoostAvailable])
830831 }
831832
832833
833834
834835 @Callable(i)
835836 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
836- let $t03587935980 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
837- let userBoostAvailable = $t03587935980._1
838- let dataState = $t03587935980._2
839- let debug = $t03587935980._3
837+ let $t03594836049 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
838+ let userBoostAvailable = $t03594836049._1
839+ let dataState = $t03594836049._2
840+ let debug = $t03594836049._3
840841 $Tuple2(nil, [userBoostAvailable, debug])
841842 }
842843
843844
844845
845846 @Callable(i)
846847 func unlock (userAddress) = {
847848 let userRecordArray = readLockParamsRecordOrFail(userAddress)
848849 let userNumStr = userRecordArray[IdxLockUserNum]
849850 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
850851 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
851852 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
852853 let lockEnd = (lockStart + lockDuration)
853854 let cfgArray = readConfigArrayOrFail()
854855 let assetId = fromBase58String(cfgArray[IdxCfgAssetId])
855856 if ((lockEnd >= height))
856857 then throwErr((("wait " + toString(lockEnd)) + " to unlock"))
857858 else if ((0 >= userAmount))
858859 then throwErr("nothing to unlock")
859860 else {
860861 let period = valueOrElse(getInteger(mathContract, keyNextPeriod()), 0)
861862 (((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))
862863 }
863864 }
864865
865866
866867
867868 @Callable(i)
868869 func gwxUserInfoREADONLY (userAddress) = {
869870 let gwxAmount = calcCurrentGwxAmount(userAddress)
870871 $Tuple2(nil, [gwxAmount])
871872 }
872873
873874
874875
875876 @Callable(i)
876877 func userMaxDurationREADONLY (userAddressStr) = {
877878 let cfgArray = readConfigArrayOrFail()
878879 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
879880 let userRecordOption = getString(this, keyLockParamsRecord(userAddressStr))
880881 if ((userRecordOption == unit))
881882 then $Tuple2(nil, $Tuple2("lock", maxLockDuration))
882883 else {
883884 let userRecordArray = split(value(userRecordOption), SEP)
884885 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
885886 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
886887 let lockEnd = (lockStart + lockDuration)
887888 let remainingDuration = max([(lockEnd - height), 0])
888889 let maxDeltaDuration = (maxLockDuration - remainingDuration)
889890 $Tuple2(nil, $Tuple2("increaseLock", maxDeltaDuration))
890891 }
891892 }
892893
893894
894895
895896 @Callable(i)
896897 func getUserGwxAmountAtHeightREADONLY (userAddress,targetHeight) = {
897898 let gwxAmount = calcUserGwxAmountAtHeight(userAddress, targetHeight)
898899 $Tuple2(nil, gwxAmount)
899900 }
900901
901902
902903
903904 @Callable(i)
904905 func getTotalCachedGwxREADONLY () = $Tuple2(nil, getTotalCachedGwx(true))
905906
906907
907908
908909 @Callable(i)
909910 func onBoostEmissionUpdate () = {
910911 let checkCaller = if ((i.caller == emissionContract))
911912 then true
912913 else mustManager(i)
913914 if ((checkCaller == checkCaller))
914915 then refreshBoostEmissionIntegral()
915916 else throw("Strict value is not equal to itself.")
916917 }
917918
918919
919920
920921 @Callable(i)
921922 func onStakedVoteUpdate (lpAssetIdStr,userAddressStr,edge) = {
922923 let checkCaller = if ((i.caller == stakingContract))
923924 then true
924925 else mustManager(i)
925926 if ((checkCaller == checkCaller))
926927 then {
927928 let actions = refreshVoteStakedIntegral(lpAssetIdStr, userAddressStr, edge)
928929 $Tuple2(actions, unit)
929930 }
930931 else throw("Strict value is not equal to itself.")
931932 }
932933
933934
934935
935936 @Callable(i)
936937 func getVotingResultStakedREADONLY (lpAssetIdStr) = $Tuple2(nil, getVotingResultStaked(lpAssetIdStr))
937938
938939
939940
940941 @Callable(i)
941942 func getVotingResultStakedIntegralREADONLY (lpAssetIdStr) = $Tuple2(nil, getVotingResultStakedIntegral(lpAssetIdStr))
942943
943944
944945
945946 @Callable(i)
946947 func getUserVoteFinalizedREADONLY (lpAssetIdStr,userAddressStr) = $Tuple2(nil, getUserVoteFinalized(lpAssetIdStr, userAddressStr))
947948
948949
949950
950951 @Callable(i)
951952 func getUserVoteStakedIntegralREADONLY (lpAssetIdStr,userAddressStr) = $Tuple2(nil, getUserVoteStakedIntegral(lpAssetIdStr, userAddressStr))
952953
953954
954955 @Verifier(tx)
955956 func verify () = {
956957 let targetPublicKey = match managerPublicKeyOrUnit() {
957958 case pk: ByteVector =>
958959 pk
959960 case _: Unit =>
960961 tx.senderPublicKey
961962 case _ =>
962963 throw("Match error")
963964 }
964965 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
965966 }
966967

github/deemru/w8io/169f3d6 
156.06 ms