2022.08.30 21:16 [3273034] smart account 3PCENpEKe8atwELZ7oCSmcdEfcRuKTrUx99 > SELF 0.00000000 Waves

{ "type": 13, "id": "GMWEK59rCMKcLArtiEuPdmX4Qv1xdaETbtWVeQBEgb1r", "fee": 2900000, "feeAssetId": null, "timestamp": 1661883416385, "version": 1, "sender": "3PCENpEKe8atwELZ7oCSmcdEfcRuKTrUx99", "senderPublicKey": "24dorn126Pv4mGCgUu61v1RLxqW4VNXbuHjmCHh7tc3K", "proofs": [ "DiqguxAHnj7sz57Ea3Fh5r3fUSiE9dDAGMQJk5pjcG7Z11WQ8BJtLhqBV4R8AGC3h3S1986L9UFNtjCC4uE1TFg" ], "script": "base64:BgJzCAISAwoBCBIDCgEIEgASBAoCAQQSAwoBARIAEgQKAgEBEgMKAQESBAoCCAgSABIDCgEIEgUKAwEBARIECgIBARIECgIIARIECgIICBILCgkIAQECAQIIBAQSBgoECAgBCBIAEgMKAQESAwoBARIECgIIAUUACmxQZGVjaW1hbHMACAAGc2NhbGU4AIDC1y8ADHNjYWxlOEJpZ0ludAkAtgIBAIDC1y8AB3NjYWxlMTgJALYCAQCAgJC7utat8A0ACnplcm9CaWdJbnQJALYCAQAAAANTRVACAl9fAApQb29sQWN0aXZlAAEAD1Bvb2xQdXREaXNhYmxlZAACABNQb29sTWF0Y2hlckRpc2FibGVkAAMADFBvb2xTaHV0ZG93bgAEAA5pZHhQb29sQWRkcmVzcwABAA1pZHhQb29sU3RhdHVzAAIAEGlkeFBvb2xMUEFzc2V0SWQAAwANaWR4QW10QXNzZXRJZAAEAA9pZHhQcmljZUFzc2V0SWQABQAOaWR4QW10QXNzZXREY20ABgAQaWR4UHJpY2VBc3NldERjbQAHAA5pZHhJQW10QXNzZXRJZAAIABBpZHhJUHJpY2VBc3NldElkAAkADWlkeExQQXNzZXREY20ACgASaWR4UG9vbEFtdEFzc2V0QW10AAEAFGlkeFBvb2xQcmljZUFzc2V0QW10AAIAEWlkeFBvb2xMUEFzc2V0QW10AAMAGWlkeEZhY3RvcnlTdGFraW5nQ29udHJhY3QAAQAaaWR4RmFjdG9yeVNsaXBwYWdlQ29udHJhY3QABwEFdG9YMTgCB29yaWdWYWwNb3JpZ1NjYWxlTXVsdAkAvAIDCQC2AgEFB29yaWdWYWwFB3NjYWxlMTgJALYCAQUNb3JpZ1NjYWxlTXVsdAEHZnJvbVgxOAIDdmFsD3Jlc3VsdFNjYWxlTXVsdAkAoAMBCQC8AgMFA3ZhbAkAtgIBBQ9yZXN1bHRTY2FsZU11bHQFB3NjYWxlMTgBB3RvU2NhbGUDA2FtdAhyZXNTY2FsZQhjdXJTY2FsZQkAawMFA2FtdAUIcmVzU2NhbGUFCGN1clNjYWxlAQNhYnMBA3ZhbAMJAL8CAgUKemVyb0JpZ0ludAUDdmFsCQC+AgEFA3ZhbAUDdmFsAQJmYwACEyVzX19mYWN0b3J5Q29udHJhY3QBA21wawACFCVzX19tYW5hZ2VyUHVibGljS2V5AQRwbXBrAAIbJXNfX3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AQJwbAACESVzJXNfX3ByaWNlX19sYXN0AQJwaAIBaAl0aW1lc3RhbXAJALkJAgkAzAgCAhglcyVzJWQlZF9fcHJpY2VfX2hpc3RvcnkJAMwIAgkApAMBBQFoCQDMCAIJAKQDAQUJdGltZXN0YW1wBQNuaWwFA1NFUAEDcGF1Agt1c2VyQWRkcmVzcwR0eElkCQCsAgIJAKwCAgkArAICAgslcyVzJXNfX1BfXwULdXNlckFkZHJlc3MCAl9fBQR0eElkAQNnYXUCC3VzZXJBZGRyZXNzBHR4SWQJAKwCAgkArAICCQCsAgICCyVzJXMlc19fR19fBQt1c2VyQWRkcmVzcwICX18FBHR4SWQBAmFhAAIPJXNfX2Ftb3VudEFzc2V0AQJwYQACDiVzX19wcmljZUFzc2V0ARBrZXlGYWN0b3J5Q29uZmlnAAIRJXNfX2ZhY3RvcnlDb25maWcBDWtleU1hdGNoZXJQdWIAAhglcyVzX19tYXRjaGVyX19wdWJsaWNLZXkBKWtleU1hcHBpbmdQb29sQ29udHJhY3RBZGRyZXNzVG9Qb29sQXNzZXRzARNwb29sQ29udHJhY3RBZGRyZXNzCQCsAgIJAKwCAgIIJXMlcyVzX18FE3Bvb2xDb250cmFjdEFkZHJlc3MCIF9fbWFwcGluZ3NfX3Bvb2xDb250cmFjdDJMcEFzc2V0AQ1rZXlQb29sQ29uZmlnAglpQW10QXNzZXQLaVByaWNlQXNzZXQJAKwCAgkArAICCQCsAgIJAKwCAgIIJWQlZCVzX18FCWlBbXRBc3NldAICX18FC2lQcmljZUFzc2V0AghfX2NvbmZpZwEfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZAEMYmFzZUFzc2V0U3RyCQCsAgICKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FDGJhc2VBc3NldFN0cgETa2V5QWxsUG9vbHNTaHV0ZG93bgACDCVzX19zaHV0ZG93bgENa2V5UG9vbFdlaWdodAEPY29udHJhY3RBZGRyZXNzCQCsAgICEiVzJXNfX3Bvb2xXZWlnaHRfXwUPY29udHJhY3RBZGRyZXNzARZrZXlBbGxvd2VkTHBTY3JpcHRIYXNoAAIXJXNfX2FsbG93ZWRMcFNjcmlwdEhhc2gBD3Rocm93T3JkZXJFcnJvcgMKb3JkZXJWYWxpZAtzZW5kZXJWYWxpZAxtYXRjaGVyVmFsaWQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIkb3JkZXIgdmFsaWRhdGlvbiBmYWlsZWQ6IG9yZGVyVmFsaWQ9CQClAwEFCm9yZGVyVmFsaWQCDSBzZW5kZXJWYWxpZD0JAKUDAQULc2VuZGVyVmFsaWQCDiBtYXRjaGVyVmFsaWQ9CQClAwEFDG1hdGNoZXJWYWxpZAEPZ2V0U3RyaW5nT3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFB2FkZHJlc3MFA2tleQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQdhZGRyZXNzCQDMCAICAS4JAMwIAgUDa2V5CQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABDGdldEludE9yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAAA9mYWN0b3J5Q29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQ9nZXRTdHJpbmdPckZhaWwCBQR0aGlzCQECZmMAARBpc0dsb2JhbFNodXRkb3duAAkBC3ZhbHVlT3JFbHNlAgkAmwgCBQ9mYWN0b3J5Q29udHJhY3QJARNrZXlBbGxQb29sc1NodXRkb3duAAcBE2dldE1hdGNoZXJQdWJPckZhaWwACQDZBAEJAQ9nZXRTdHJpbmdPckZhaWwCBQ9mYWN0b3J5Q29udHJhY3QJAQ1rZXlNYXRjaGVyUHViAAENZ2V0UG9vbENvbmZpZwAECGFtdEFzc2V0CQEPZ2V0U3RyaW5nT3JGYWlsAgUEdGhpcwkBAmFhAAQKcHJpY2VBc3NldAkBD2dldFN0cmluZ09yRmFpbAIFBHRoaXMJAQJwYQAEC2lQcmljZUFzc2V0CQEMZ2V0SW50T3JGYWlsAgUPZmFjdG9yeUNvbnRyYWN0CQEfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZAEFCnByaWNlQXNzZXQECWlBbXRBc3NldAkBDGdldEludE9yRmFpbAIFD2ZhY3RvcnlDb250cmFjdAkBH2tleU1hcHBpbmdzQmFzZUFzc2V0MmludGVybmFsSWQBBQhhbXRBc3NldAkAtQkCCQEPZ2V0U3RyaW5nT3JGYWlsAgUPZmFjdG9yeUNvbnRyYWN0CQENa2V5UG9vbENvbmZpZwIJAKQDAQUJaUFtdEFzc2V0CQCkAwEFC2lQcmljZUFzc2V0BQNTRVABEGdldEZhY3RvcnlDb25maWcACQC1CQIJAQ9nZXRTdHJpbmdPckZhaWwCBQ9mYWN0b3J5Q29udHJhY3QJARBrZXlGYWN0b3J5Q29uZmlnAAUDU0VQARFkYXRhUHV0QWN0aW9uSW5mbwoNaW5BbXRBc3NldEFtdA9pblByaWNlQXNzZXRBbXQIb3V0THBBbXQFcHJpY2Udc2xpcHBhZ2VUb2xlcmFuY2VQYXNzZWRCeVVzZXIVc2xpcHBhZ2VUb2xlcmFuY2VSZWFsCHR4SGVpZ2h0C3R4VGltZXN0YW1wEnNsaXBhZ2VBbXRBc3NldEFtdBRzbGlwYWdlUHJpY2VBc3NldEFtdAkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUNaW5BbXRBc3NldEFtdAkAzAgCCQCkAwEFD2luUHJpY2VBc3NldEFtdAkAzAgCCQCkAwEFCG91dExwQW10CQDMCAIJAKQDAQUFcHJpY2UJAMwIAgkApAMBBR1zbGlwcGFnZVRvbGVyYW5jZVBhc3NlZEJ5VXNlcgkAzAgCCQCkAwEFFXNsaXBwYWdlVG9sZXJhbmNlUmVhbAkAzAgCCQCkAwEFCHR4SGVpZ2h0CQDMCAIJAKQDAQULdHhUaW1lc3RhbXAJAMwIAgkApAMBBRJzbGlwYWdlQW10QXNzZXRBbXQJAMwIAgkApAMBBRRzbGlwYWdlUHJpY2VBc3NldEFtdAUDbmlsBQNTRVABEWRhdGFHZXRBY3Rpb25JbmZvBg5vdXRBbXRBc3NldEFtdBBvdXRQcmljZUFzc2V0QW10B2luTHBBbXQFcHJpY2UIdHhIZWlnaHQLdHhUaW1lc3RhbXAJALkJAgkAzAgCAgwlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQ5vdXRBbXRBc3NldEFtdAkAzAgCCQCkAwEFEG91dFByaWNlQXNzZXRBbXQJAMwIAgkApAMBBQdpbkxwQW10CQDMCAIJAKQDAQUFcHJpY2UJAMwIAgkApAMBBQh0eEhlaWdodAkAzAgCCQCkAwEFC3R4VGltZXN0YW1wBQNuaWwFA1NFUAENZ2V0QWNjQmFsYW5jZQEHYXNzZXRJZAMJAAACBQdhc3NldElkAgVXQVZFUwgJAO8HAQUEdGhpcwlhdmFpbGFibGUJAPAHAgUEdGhpcwkA2QQBBQdhc3NldElkAQ9jYWxjUHJpY2VCaWdJbnQCCHByQW10WDE4CGFtQW10WDE4CQC8AgMFCHByQW10WDE4BQdzY2FsZTE4BQhhbUFtdFgxOAEQcHJpdmF0ZUNhbGNQcmljZQQKYW1Bc3NldERjbQpwckFzc2V0RGNtBWFtQW10BXByQW10BA5hbXRBc3NldEFtdFgxOAkBBXRvWDE4AgUFYW1BbXQFCmFtQXNzZXREY20EEHByaWNlQXNzZXRBbXRYMTgJAQV0b1gxOAIFBXByQW10BQpwckFzc2V0RGNtCQEPY2FsY1ByaWNlQmlnSW50AgUQcHJpY2VBc3NldEFtdFgxOAUOYW10QXNzZXRBbXRYMTgBCmNhbGNQcmljZXMDBWFtQW10BXByQW10BWxwQW10BANjZmcJAQ1nZXRQb29sQ29uZmlnAAQLYW10QXNzZXREY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFDmlkeEFtdEFzc2V0RGNtBA1wcmljZUFzc2V0RGNtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDY2ZnBRBpZHhQcmljZUFzc2V0RGNtBAhwcmljZVgxOAkBEHByaXZhdGVDYWxjUHJpY2UEBQthbXRBc3NldERjbQUNcHJpY2VBc3NldERjbQUFYW1BbXQFBXByQW10BAhhbUFtdFgxOAkBBXRvWDE4AgUFYW1BbXQFC2FtdEFzc2V0RGNtBAhwckFtdFgxOAkBBXRvWDE4AgUFcHJBbXQFDXByaWNlQXNzZXREY20ECGxwQW10WDE4CQEFdG9YMTgCBQVscEFtdAUGc2NhbGU4BBNscFByaWNlSW5BbUFzc2V0WDE4CQEPY2FsY1ByaWNlQmlnSW50AgUIYW1BbXRYMTgFCGxwQW10WDE4BBNscFByaWNlSW5QckFzc2V0WDE4CQEPY2FsY1ByaWNlQmlnSW50AgUIcHJBbXRYMTgFCGxwQW10WDE4CQDMCAIFCHByaWNlWDE4CQDMCAIFE2xwUHJpY2VJbkFtQXNzZXRYMTgJAMwIAgUTbHBQcmljZUluUHJBc3NldFgxOAUDbmlsAQ9jYWxjdWxhdGVQcmljZXMDBWFtQW10BXByQW10BWxwQW10BAZwcmljZXMJAQpjYWxjUHJpY2VzAwUFYW1BbXQFBXByQW10BQVscEFtdAkAzAgCCQEHZnJvbVgxOAIJAJEDAgUGcHJpY2VzAAAFBnNjYWxlOAkAzAgCCQEHZnJvbVgxOAIJAJEDAgUGcHJpY2VzAAEFBnNjYWxlOAkAzAgCCQEHZnJvbVgxOAIJAJEDAgUGcHJpY2VzAAIFBnNjYWxlOAUDbmlsARRlc3RpbWF0ZUdldE9wZXJhdGlvbgQGdHhJZDU4CnBtdEFzc2V0SWQIcG10THBBbXQLdXNlckFkZHJlc3MEA2NmZwkBDWdldFBvb2xDb25maWcABAlscEFzc2V0SWQJAJEDAgUDY2ZnBRBpZHhQb29sTFBBc3NldElkBAlhbUFzc2V0SWQJAJEDAgUDY2ZnBQ1pZHhBbXRBc3NldElkBAlwckFzc2V0SWQJAJEDAgUDY2ZnBQ9pZHhQcmljZUFzc2V0SWQECmFtQXNzZXREY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFDmlkeEFtdEFzc2V0RGNtBApwckFzc2V0RGNtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDY2ZnBRBpZHhQcmljZUFzc2V0RGNtBApwb29sU3RhdHVzCQCRAwIFA2NmZwUNaWR4UG9vbFN0YXR1cwQKbHBFbWlzc2lvbggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFCWxwQXNzZXRJZAkArAICCQCsAgICBkFzc2V0IAUJbHBBc3NldElkAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQMJAQIhPQIFCWxwQXNzZXRJZAUKcG10QXNzZXRJZAkAAgECFUludmFsaWQgYXNzZXQgcGFzc2VkLgQJYW1CYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFCWFtQXNzZXRJZAQMYW1CYWxhbmNlWDE4CQEFdG9YMTgCBQlhbUJhbGFuY2UFCmFtQXNzZXREY20ECXByQmFsYW5jZQkBDWdldEFjY0JhbGFuY2UBBQlwckFzc2V0SWQEDHByQmFsYW5jZVgxOAkBBXRvWDE4AgUJcHJCYWxhbmNlBQpwckFzc2V0RGNtBAtjdXJQcmljZVgxOAkBD2NhbGNQcmljZUJpZ0ludAIFDHByQmFsYW5jZVgxOAUMYW1CYWxhbmNlWDE4BAhjdXJQcmljZQkBB2Zyb21YMTgCBQtjdXJQcmljZVgxOAUGc2NhbGU4BAtwbXRMcEFtdFgxOAkBBXRvWDE4AgUIcG10THBBbXQFBnNjYWxlOAQNbHBFbWlzc2lvblgxOAkBBXRvWDE4AgUKbHBFbWlzc2lvbgUGc2NhbGU4BAtvdXRBbUFtdFgxOAkAvAIDBQxhbUJhbGFuY2VYMTgFC3BtdExwQW10WDE4BQ1scEVtaXNzaW9uWDE4BAtvdXRQckFtdFgxOAkAvAIDBQxwckJhbGFuY2VYMTgFC3BtdExwQW10WDE4BQ1scEVtaXNzaW9uWDE4BAhvdXRBbUFtdAkBB2Zyb21YMTgCBQtvdXRBbUFtdFgxOAUKYW1Bc3NldERjbQQIb3V0UHJBbXQJAQdmcm9tWDE4AgULb3V0UHJBbXRYMTgFCnByQXNzZXREY20EBXN0YXRlAwkAAAIFBnR4SWQ1OAIABQNuaWwJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFCG91dEFtQW10AwkAAAIFCWFtQXNzZXRJZAIFV0FWRVMFBHVuaXQJANkEAQUJYW1Bc3NldElkCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzBQhvdXRQckFtdAMJAAACBQlwckFzc2V0SWQCBVdBVkVTBQR1bml0CQDZBAEFCXByQXNzZXRJZAkAzAgCCQELU3RyaW5nRW50cnkCCQEDZ2F1AgkApQgBBQt1c2VyQWRkcmVzcwUGdHhJZDU4CQERZGF0YUdldEFjdGlvbkluZm8GBQhvdXRBbUFtdAUIb3V0UHJBbXQFCHBtdExwQW10BQhjdXJQcmljZQUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAnBsAAUIY3VyUHJpY2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJwaAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFCGN1clByaWNlBQNuaWwJAJwKCgUIb3V0QW1BbXQFCG91dFByQW10BQlhbUFzc2V0SWQFCXByQXNzZXRJZAUJYW1CYWxhbmNlBQlwckJhbGFuY2UFCmxwRW1pc3Npb24FC2N1clByaWNlWDE4BQpwb29sU3RhdHVzBQVzdGF0ZQEUZXN0aW1hdGVQdXRPcGVyYXRpb24JBnR4SWQ1OBFzbGlwcGFnZVRvbGVyYW5jZQxpbkFtQXNzZXRBbXQLaW5BbUFzc2V0SWQMaW5QckFzc2V0QW10C2luUHJBc3NldElkC3VzZXJBZGRyZXNzCmlzRXZhbHVhdGUGZW1pdExwBANjZmcJAQ1nZXRQb29sQ29uZmlnAAQJbHBBc3NldElkCQDZBAEJAJEDAgUDY2ZnBRBpZHhQb29sTFBBc3NldElkBAxhbUFzc2V0SWRTdHIJAJEDAgUDY2ZnBQ1pZHhBbXRBc3NldElkBAxwckFzc2V0SWRTdHIJAJEDAgUDY2ZnBQ9pZHhQcmljZUFzc2V0SWQEC2lBbXRBc3NldElkCQCRAwIFA2NmZwUOaWR4SUFtdEFzc2V0SWQEDWlQcmljZUFzc2V0SWQJAJEDAgUDY2ZnBRBpZHhJUHJpY2VBc3NldElkBAthbXRBc3NldERjbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2NmZwUOaWR4QW10QXNzZXREY20EDXByaWNlQXNzZXREY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFEGlkeFByaWNlQXNzZXREY20ECnBvb2xTdGF0dXMJAJEDAgUDY2ZnBQ1pZHhQb29sU3RhdHVzBApscEVtaXNzaW9uCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFCWxwQXNzZXRJZAkArAICCQCsAgICBkFzc2V0IAkA2AQBBQlscEFzc2V0SWQCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BA5pbkFtQXNzZXRJZFN0cgkA2AQBCQELdmFsdWVPckVsc2UCBQtpbkFtQXNzZXRJZAkA2QQBAgVXQVZFUwQOaW5QckFzc2V0SWRTdHIJANgEAQkBC3ZhbHVlT3JFbHNlAgULaW5QckFzc2V0SWQJANkEAQIFV0FWRVMDAwkBAiE9AgUMYW1Bc3NldElkU3RyBQ5pbkFtQXNzZXRJZFN0cgYJAQIhPQIFDHByQXNzZXRJZFN0cgUOaW5QckFzc2V0SWRTdHIJAAIBAiJJbnZhbGlkIGFtdCBvciBwcmljZSBhc3NldCBwYXNzZWQuBAlhbUJhbGFuY2UDBQppc0V2YWx1YXRlCQENZ2V0QWNjQmFsYW5jZQEFDGFtQXNzZXRJZFN0cgkAZQIJAQ1nZXRBY2NCYWxhbmNlAQUMYW1Bc3NldElkU3RyBQxpbkFtQXNzZXRBbXQECXByQmFsYW5jZQMFCmlzRXZhbHVhdGUJAQ1nZXRBY2NCYWxhbmNlAQUMcHJBc3NldElkU3RyCQBlAgkBDWdldEFjY0JhbGFuY2UBBQxwckFzc2V0SWRTdHIFDGluUHJBc3NldEFtdAQPaW5BbUFzc2V0QW10WDE4CQEFdG9YMTgCBQxpbkFtQXNzZXRBbXQFC2FtdEFzc2V0RGNtBA9pblByQXNzZXRBbXRYMTgJAQV0b1gxOAIFDGluUHJBc3NldEFtdAUNcHJpY2VBc3NldERjbQQMdXNlclByaWNlWDE4CQEPY2FsY1ByaWNlQmlnSW50AgUPaW5QckFzc2V0QW10WDE4BQ9pbkFtQXNzZXRBbXRYMTgEDGFtQmFsYW5jZVgxOAkBBXRvWDE4AgUJYW1CYWxhbmNlBQthbXRBc3NldERjbQQMcHJCYWxhbmNlWDE4CQEFdG9YMTgCBQlwckJhbGFuY2UFDXByaWNlQXNzZXREY20EA3JlcwMJAAACBQpscEVtaXNzaW9uAAAEC2N1clByaWNlWDE4BQp6ZXJvQmlnSW50BAtzbGlwcGFnZVgxOAUKemVyb0JpZ0ludAQIbHBBbXRYMTgJAHYGCQC5AgIFD2luQW1Bc3NldEFtdFgxOAUPaW5QckFzc2V0QW10WDE4AAAJALYCAQAFAAEAAAUERE9XTgkAlwoFCQEHZnJvbVgxOAIFCGxwQW10WDE4BQZzY2FsZTgJAQdmcm9tWDE4AgUPaW5BbUFzc2V0QW10WDE4BQthbXRBc3NldERjbQkBB2Zyb21YMTgCBQ9pblByQXNzZXRBbXRYMTgFDXByaWNlQXNzZXREY20JAQ9jYWxjUHJpY2VCaWdJbnQCCQC3AgIFDHByQmFsYW5jZVgxOAUPaW5QckFzc2V0QW10WDE4CQC3AgIFDGFtQmFsYW5jZVgxOAUPaW5BbUFzc2V0QW10WDE4BQtzbGlwcGFnZVgxOAQLY3VyUHJpY2VYMTgJAQ9jYWxjUHJpY2VCaWdJbnQCBQxwckJhbGFuY2VYMTgFDGFtQmFsYW5jZVgxOAQLc2xpcHBhZ2VYMTgJALwCAwkBA2FicwEJALgCAgULY3VyUHJpY2VYMTgFDHVzZXJQcmljZVgxOAUHc2NhbGUxOAULY3VyUHJpY2VYMTgEFHNsaXBwYWdlVG9sZXJhbmNlWDE4CQEFdG9YMTgCBRFzbGlwcGFnZVRvbGVyYW5jZQUGc2NhbGU4AwMJAQIhPQIFC2N1clByaWNlWDE4BQp6ZXJvQmlnSW50CQC/AgIFC3NsaXBwYWdlWDE4BRRzbGlwcGFnZVRvbGVyYW5jZVgxOAcJAAIBCQCsAgIJAKwCAgkArAICAg9QcmljZSBzbGlwcGFnZSAJAKYDAQULc2xpcHBhZ2VYMTgCHiBleGNlZWRlZCB0aGUgcGFzc2VkIGxpbWl0IG9mIAkApgMBBRRzbGlwcGFnZVRvbGVyYW5jZVgxOAQNbHBFbWlzc2lvblgxOAkBBXRvWDE4AgUKbHBFbWlzc2lvbgUGc2NhbGU4BApwclZpYUFtWDE4CQC8AgMFD2luQW1Bc3NldEFtdFgxOAULY3VyUHJpY2VYMTgFB3NjYWxlMTgECmFtVmlhUHJYMTgJALwCAwUPaW5QckFzc2V0QW10WDE4BQdzY2FsZTE4BQtjdXJQcmljZVgxOAQMZXhwZWN0ZWRBbXRzAwkAvwICBQpwclZpYUFtWDE4BQ9pblByQXNzZXRBbXRYMTgJAJQKAgUKYW1WaWFQclgxOAUPaW5QckFzc2V0QW10WDE4CQCUCgIFD2luQW1Bc3NldEFtdFgxOAUKcHJWaWFBbVgxOAQRZXhwQW10QXNzZXRBbXRYMTgIBQxleHBlY3RlZEFtdHMCXzEEE2V4cFByaWNlQXNzZXRBbXRYMTgIBQxleHBlY3RlZEFtdHMCXzIECGxwQW10WDE4CQC8AgMFDWxwRW1pc3Npb25YMTgFE2V4cFByaWNlQXNzZXRBbXRYMTgFDHByQmFsYW5jZVgxOAkAlwoFCQEHZnJvbVgxOAIFCGxwQW10WDE4BQZzY2FsZTgJAQdmcm9tWDE4AgURZXhwQW10QXNzZXRBbXRYMTgFC2FtdEFzc2V0RGNtCQEHZnJvbVgxOAIFE2V4cFByaWNlQXNzZXRBbXRYMTgFDXByaWNlQXNzZXREY20FC2N1clByaWNlWDE4BQtzbGlwcGFnZVgxOAQJY2FsY0xwQW10CAUDcmVzAl8xBA5jYWxjQW1Bc3NldFBtdAgFA3JlcwJfMgQOY2FsY1ByQXNzZXRQbXQIBQNyZXMCXzMECGN1clByaWNlCQEHZnJvbVgxOAIIBQNyZXMCXzQFBnNjYWxlOAQMc2xpcHBhZ2VDYWxjCQEHZnJvbVgxOAIIBQNyZXMCXzUFBnNjYWxlOAMJAGcCAAAFCWNhbGNMcEFtdAkAAgECNkludmFsaWQgY2FsY3VsYXRpb25zLiBMUCBjYWxjdWxhdGVkIGlzIGxlc3MgdGhhbiB6ZXJvLgQJZW1pdExwQW10AwkBASEBBQZlbWl0THAAAAUJY2FsY0xwQW10BAZhbURpZmYJAGUCBQxpbkFtQXNzZXRBbXQFDmNhbGNBbUFzc2V0UG10BAZwckRpZmYJAGUCBQxpblByQXNzZXRBbXQFDmNhbGNQckFzc2V0UG10BAtjb21tb25TdGF0ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAnBsAAUIY3VyUHJpY2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJwaAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFCGN1clByaWNlCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQNwYXUCBQt1c2VyQWRkcmVzcwUGdHhJZDU4CQERZGF0YVB1dEFjdGlvbkluZm8KBQ5jYWxjQW1Bc3NldFBtdAUOY2FsY1ByQXNzZXRQbXQFCWVtaXRMcEFtdAUIY3VyUHJpY2UFEXNsaXBwYWdlVG9sZXJhbmNlBQxzbGlwcGFnZUNhbGMFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFBmFtRGlmZgUGcHJEaWZmBQNuaWwJAJ8KDQUJY2FsY0xwQW10BQllbWl0THBBbXQFCGN1clByaWNlBQlhbUJhbGFuY2UFCXByQmFsYW5jZQUKbHBFbWlzc2lvbgUJbHBBc3NldElkBQpwb29sU3RhdHVzBQtjb21tb25TdGF0ZQUGYW1EaWZmBQZwckRpZmYFC2luQW1Bc3NldElkBQtpblByQXNzZXRJZAEbdmFsaWRhdGVNYXRjaGVyT3JkZXJBbGxvd2VkAQVvcmRlcgQDY2ZnCQENZ2V0UG9vbENvbmZpZwAECmFtdEFzc2V0SWQJAJEDAgUDY2ZnBQ1pZHhBbXRBc3NldElkBAxwcmljZUFzc2V0SWQJAJEDAgUDY2ZnBQ9pZHhQcmljZUFzc2V0SWQECnBvb2xTdGF0dXMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFDWlkeFBvb2xTdGF0dXMEC2FtdEFzc2V0RGNtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDY2ZnBQ5pZHhBbXRBc3NldERjbQQNcHJpY2VBc3NldERjbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2NmZwUQaWR4UHJpY2VBc3NldERjbQQSYWNjQW10QXNzZXRCYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFCmFtdEFzc2V0SWQEFGFjY1ByaWNlQXNzZXRCYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFDHByaWNlQXNzZXRJZAQLY3VyUHJpY2VYMTgDCQAAAggFBW9yZGVyCW9yZGVyVHlwZQUDQnV5CQEQcHJpdmF0ZUNhbGNQcmljZQQFC2FtdEFzc2V0RGNtBQ1wcmljZUFzc2V0RGNtCQBkAgUSYWNjQW10QXNzZXRCYWxhbmNlCAUFb3JkZXIGYW1vdW50BRRhY2NQcmljZUFzc2V0QmFsYW5jZQkBEHByaXZhdGVDYWxjUHJpY2UEBQthbXRBc3NldERjbQUNcHJpY2VBc3NldERjbQkAZQIFEmFjY0FtdEFzc2V0QmFsYW5jZQgFBW9yZGVyBmFtb3VudAUUYWNjUHJpY2VBc3NldEJhbGFuY2UECGN1clByaWNlCQEHZnJvbVgxOAIFC2N1clByaWNlWDE4BQZzY2FsZTgDAwMJARBpc0dsb2JhbFNodXRkb3duAAYJAAACBQpwb29sU3RhdHVzBRNQb29sTWF0Y2hlckRpc2FibGVkBgkAAAIFCnBvb2xTdGF0dXMFDFBvb2xTaHV0ZG93bgkAAgECHEV4Y2hhbmdlIG9wZXJhdGlvbnMgZGlzYWJsZWQEDW9yZGVyQW10QXNzZXQICAUFb3JkZXIJYXNzZXRQYWlyC2Ftb3VudEFzc2V0BBBvcmRlckFtdEFzc2V0U3RyAwkAAAIFDW9yZGVyQW10QXNzZXQFBHVuaXQCBVdBVkVTCQDYBAEJAQV2YWx1ZQEFDW9yZGVyQW10QXNzZXQED29yZGVyUHJpY2VBc3NldAgIBQVvcmRlcglhc3NldFBhaXIKcHJpY2VBc3NldAQSb3JkZXJQcmljZUFzc2V0U3RyAwkAAAIFD29yZGVyUHJpY2VBc3NldAUEdW5pdAIFV0FWRVMJANgEAQkBBXZhbHVlAQUPb3JkZXJQcmljZUFzc2V0AwMJAQIhPQIFEG9yZGVyQW10QXNzZXRTdHIFCmFtdEFzc2V0SWQGCQECIT0CBRJvcmRlclByaWNlQXNzZXRTdHIFDHByaWNlQXNzZXRJZAkAAgECE1dyb25nIG9yZGVyIGFzc2V0cy4ECm9yZGVyUHJpY2UIBQVvcmRlcgVwcmljZQQIcHJpY2VEY20JAGsDBQZzY2FsZTgFDXByaWNlQXNzZXREY20FC2FtdEFzc2V0RGNtBBBjYXN0ZWRPcmRlclByaWNlCQEHdG9TY2FsZQMFCm9yZGVyUHJpY2UFBnNjYWxlOAUIcHJpY2VEY20EEWlzT3JkZXJQcmljZVZhbGlkAwkAAAIIBQVvcmRlcglvcmRlclR5cGUFA0J1eQkAZwIFCGN1clByaWNlBRBjYXN0ZWRPcmRlclByaWNlCQBnAgUQY2FzdGVkT3JkZXJQcmljZQUIY3VyUHJpY2UGAQljb21tb25HZXQBAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAh1leGFjdGx5IDEgcGF5bWVudCBpcyBleHBlY3RlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAECnBtdEFzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQGcG10QW10CAUDcG10BmFtb3VudAQDcmVzCQEUZXN0aW1hdGVHZXRPcGVyYXRpb24ECQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQJANgEAQUKcG10QXNzZXRJZAUGcG10QW10CAUBaQZjYWxsZXIECG91dEFtQW10CAUDcmVzAl8xBAhvdXRQckFtdAgFA3JlcwJfMgQKcG9vbFN0YXR1cwkBDXBhcnNlSW50VmFsdWUBCAUDcmVzAl85BAVzdGF0ZQgFA3JlcwNfMTADAwkBEGlzR2xvYmFsU2h1dGRvd24ABgkAAAIFCnBvb2xTdGF0dXMFDFBvb2xTaHV0ZG93bgkAAgEJAKwCAgIsR2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUKcG9vbFN0YXR1cwkAlwoFBQhvdXRBbUFtdAUIb3V0UHJBbXQFBnBtdEFtdAUKcG10QXNzZXRJZAUFc3RhdGUBCWNvbW1vblB1dAMBaRFzbGlwcGFnZVRvbGVyYW5jZQZlbWl0THADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAIJAAIBAh9leGFjdGx5IDIgcGF5bWVudHMgYXJlIGV4cGVjdGVkBAphbUFzc2V0UG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAECnByQXNzZXRQbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAQQGZXN0UHV0CQEUZXN0aW1hdGVQdXRPcGVyYXRpb24JCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQFEXNsaXBwYWdlVG9sZXJhbmNlCAUKYW1Bc3NldFBtdAZhbW91bnQIBQphbUFzc2V0UG10B2Fzc2V0SWQIBQpwckFzc2V0UG10BmFtb3VudAgFCnByQXNzZXRQbXQHYXNzZXRJZAkApQgBCAUBaQZjYWxsZXIHBQZlbWl0THAECnBvb2xTdGF0dXMJAQ1wYXJzZUludFZhbHVlAQgFBmVzdFB1dAJfOAMDAwkBEGlzR2xvYmFsU2h1dGRvd24ABgkAAAIFCnBvb2xTdGF0dXMFD1Bvb2xQdXREaXNhYmxlZAYJAAACBQpwb29sU3RhdHVzBQxQb29sU2h1dGRvd24JAAIBCQCsAgICLFB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFCnBvb2xTdGF0dXMFBmVzdFB1dAEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAAEByRtYXRjaDAJAKIIAQkBA21wawADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQDZBAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAR1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdAAEByRtYXRjaDAJAKIIAQkBBHBtcGsAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgELbXVzdE1hbmFnZXIBAWkEAnBkCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEByRtYXRjaDAJARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAMJAAACCAUBaQ9jYWxsZXJQdWJsaWNLZXkFAnBrBgUCcGQDCQABAgUHJG1hdGNoMAIEVW5pdAMJAAACCAUBaQZjYWxsZXIFBHRoaXMGBQJwZAkAAgECC01hdGNoIGVycm9yFQFpAQtjb25zdHJ1Y3RvcgEPZmFjdG9yeUNvbnRyYWN0BAtjaGVja0NhbGxlcgkBC211c3RNYW5hZ2VyAQUBaQMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmZjAAUPZmFjdG9yeUNvbnRyYWN0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKc2V0TWFuYWdlcgEXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkEC2NoZWNrQ2FsbGVyCQELbXVzdE1hbmFnZXIBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQDZBAEFF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AwkAAAIFFWNoZWNrTWFuYWdlclB1YmxpY0tleQUVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQRwbXBrAAUXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ5jb25maXJtTWFuYWdlcgAEAnBtCQEdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQABAVoYXNQTQMJAQlpc0RlZmluZWQBBQJwbQYJAAIBAhJObyBwZW5kaW5nIG1hbmFnZXIDCQAAAgUFaGFzUE0FBWhhc1BNBAdjaGVja1BNAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCcG0GCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFB2NoZWNrUE0FB2NoZWNrUE0JAMwIAgkBC1N0cmluZ0VudHJ5AgkBA21wawAJANgEAQkBBXZhbHVlAQUCcG0JAMwIAgkBC0RlbGV0ZUVudHJ5AQkBBHBtcGsABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEDcHV0AhFzbGlwcGFnZVRvbGVyYW5jZQ9zaG91bGRBdXRvU3Rha2UECmZhY3RvcnlDZmcJARBnZXRGYWN0b3J5Q29uZmlnAAQPc3Rha2luZ0NvbnRyYWN0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQpmYWN0b3J5Q2ZnBRlpZHhGYWN0b3J5U3Rha2luZ0NvbnRyYWN0AiFFcnJvci4gSW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcy4EEHNsaXBwYWdlQ29udHJhY3QJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFCmZhY3RvcnlDZmcFGmlkeEZhY3RvcnlTbGlwcGFnZUNvbnRyYWN0AitFcnJvci4gSW5jb3JyZWN0IHNsaXBwYWdlIGNvbnRyYWN0IGFkZHJlc3MuAwkAZgIAAAURc2xpcHBhZ2VUb2xlcmFuY2UJAAIBAiBJbnZhbGlkIHNsaXBwYWdlVG9sZXJhbmNlIHBhc3NlZAQGZXN0UHV0CQEJY29tbW9uUHV0AwUBaQURc2xpcHBhZ2VUb2xlcmFuY2UGBAllbWl0THBBbXQIBQZlc3RQdXQCXzIECWxwQXNzZXRJZAgFBmVzdFB1dAJfNwQFc3RhdGUIBQZlc3RQdXQCXzkEBmFtRGlmZggFBmVzdFB1dANfMTAEBnByRGlmZggFBmVzdFB1dANfMTEEBGFtSWQIBQZlc3RQdXQDXzEyBARwcklkCAUGZXN0UHV0A18xMwQHZW1pdEludgkA/AcEBQ9mYWN0b3J5Q29udHJhY3QCBGVtaXQJAMwIAgUJZW1pdExwQW10BQNuaWwFA25pbAMJAAACBQdlbWl0SW52BQdlbWl0SW52BA1lbWl0SW52TGVnYWN5BAckbWF0Y2gwBQdlbWl0SW52AwkAAQIFByRtYXRjaDACB0FkZHJlc3MEFWxlZ2FjeUZhY3RvcnlDb250cmFjdAUHJG1hdGNoMAkA/AcEBRVsZWdhY3lGYWN0b3J5Q29udHJhY3QCBGVtaXQJAMwIAgUJZW1pdExwQW10BQNuaWwFA25pbAUEdW5pdAMJAAACBQ1lbWl0SW52TGVnYWN5BQ1lbWl0SW52TGVnYWN5BAxzbGlwcGFnZUFJbnYDCQBmAgUGYW1EaWZmAAAJAPwHBAUQc2xpcHBhZ2VDb250cmFjdAIDcHV0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBGFtSWQFBmFtRGlmZgUDbmlsBQNuaWwDCQAAAgUMc2xpcHBhZ2VBSW52BQxzbGlwcGFnZUFJbnYEDHNsaXBwYWdlUEludgMJAGYCBQZwckRpZmYAAAkA/AcEBRBzbGlwcGFnZUNvbnRyYWN0AgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUEcHJJZAUGcHJEaWZmBQNuaWwFA25pbAMJAAACBQxzbGlwcGFnZVBJbnYFDHNsaXBwYWdlUEludgQKbHBUcmFuc2ZlcgMFD3Nob3VsZEF1dG9TdGFrZQQLc2xwU3Rha2VJbnYJAPwHBAUPc3Rha2luZ0NvbnRyYWN0AgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQlscEFzc2V0SWQFCWVtaXRMcEFtdAUDbmlsAwkAAAIFC3NscFN0YWtlSW52BQtzbHBTdGFrZUludgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUJZW1pdExwQW10BQlscEFzc2V0SWQFA25pbAkAzggCBQVzdGF0ZQUKbHBUcmFuc2ZlcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQpwdXRGb3JGcmVlAQttYXhTbGlwcGFnZQMJAGYCAAAFC21heFNsaXBwYWdlCQACAQIUSW52YWxpZCB2YWx1ZSBwYXNzZWQEBmVzdFB1dAkBCWNvbW1vblB1dAMFAWkFC21heFNsaXBwYWdlBwgFBmVzdFB1dAJfOQFpAQNnZXQABANyZXMJAQljb21tb25HZXQBBQFpBAlvdXRBbXRBbXQIBQNyZXMCXzEECG91dFByQW10CAUDcmVzAl8yBAZwbXRBbXQIBQNyZXMCXzMECnBtdEFzc2V0SWQIBQNyZXMCXzQEBXN0YXRlCAUDcmVzAl81BBRidXJuTFBBc3NldE9uRmFjdG9yeQkA/AcEBQ9mYWN0b3J5Q29udHJhY3QCBGJ1cm4JAMwIAgUGcG10QW10BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFCnBtdEFzc2V0SWQFBnBtdEFtdAUDbmlsAwkAAAIFFGJ1cm5MUEFzc2V0T25GYWN0b3J5BRRidXJuTFBBc3NldE9uRmFjdG9yeQUFc3RhdGUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEJZ2V0Tm9MZXNzAhJub0xlc3NUaGVuQW10QXNzZXQUbm9MZXNzVGhlblByaWNlQXNzZXQEA3JlcwkBCWNvbW1vbkdldAEFAWkECG91dEFtQW10CAUDcmVzAl8xBAhvdXRQckFtdAgFA3JlcwJfMgQGcG10QW10CAUDcmVzAl8zBApwbXRBc3NldElkCAUDcmVzAl80BAVzdGF0ZQgFA3JlcwJfNQMJAGYCBRJub0xlc3NUaGVuQW10QXNzZXQFCG91dEFtQW10CQACAQkArAICCQCsAgIJAKwCAgIcbm9MZXNzVGhlbkFtdEFzc2V0IGZhaWxlZDogIAkApAMBBQhvdXRBbUFtdAIDIDwgCQCkAwEFEm5vTGVzc1RoZW5BbXRBc3NldAMJAGYCBRRub0xlc3NUaGVuUHJpY2VBc3NldAUIb3V0UHJBbXQJAAIBCQCsAgIJAKwCAgkArAICAh1ub0xlc3NUaGVuUHJpY2VBc3NldCBmYWlsZWQ6IAkApAMBBQhvdXRQckFtdAIDIDwgCQCkAwEFFG5vTGVzc1RoZW5QcmljZUFzc2V0BBRidXJuTFBBc3NldE9uRmFjdG9yeQkA/AcEBQ9mYWN0b3J5Q29udHJhY3QCBGJ1cm4JAMwIAgUGcG10QW10BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFCnBtdEFzc2V0SWQFBnBtdEFtdAUDbmlsAwkAAAIFFGJ1cm5MUEFzc2V0T25GYWN0b3J5BRRidXJuTFBBc3NldE9uRmFjdG9yeQUFc3RhdGUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQENdW5zdGFrZUFuZEdldAEGYW1vdW50BA1jaGVja1BheW1lbnRzAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIYTm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBgMJAAACBQ1jaGVja1BheW1lbnRzBQ1jaGVja1BheW1lbnRzBANjZmcJAQ1nZXRQb29sQ29uZmlnAAQKZmFjdG9yeUNmZwkBEGdldEZhY3RvcnlDb25maWcABAlscEFzc2V0SWQJANkEAQkAkQMCBQNjZmcFEGlkeFBvb2xMUEFzc2V0SWQED3N0YWtpbmdDb250cmFjdAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUKZmFjdG9yeUNmZwUZaWR4RmFjdG9yeVN0YWtpbmdDb250cmFjdAIhRXJyb3IuIEluY29ycmVjdCBzdGFraW5nIGFkZHJlc3MuBAp1bnN0YWtlSW52CQD8BwQFD3N0YWtpbmdDb250cmFjdAIHdW5zdGFrZQkAzAgCCQDYBAEFCWxwQXNzZXRJZAkAzAgCBQZhbW91bnQFA25pbAUDbmlsAwkAAAIFCnVuc3Rha2VJbnYFCnVuc3Rha2VJbnYEA3JlcwkBFGVzdGltYXRlR2V0T3BlcmF0aW9uBAkA2AQBCAUBaQ10cmFuc2FjdGlvbklkCQDYBAEFCWxwQXNzZXRJZAUGYW1vdW50CAUBaQZjYWxsZXIECnBvb2xTdGF0dXMJAQ1wYXJzZUludFZhbHVlAQgFA3JlcwJfOQQFc3RhdGUIBQNyZXMDXzEwBA9jaGVja1Bvb2xTdGF0dXMDAwkBEGlzR2xvYmFsU2h1dGRvd24ABgkAAAIFCnBvb2xTdGF0dXMFDFBvb2xTaHV0ZG93bgkAAgEJAKwCAgIsR2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUKcG9vbFN0YXR1cwYDCQAAAgUPY2hlY2tQb29sU3RhdHVzBQ9jaGVja1Bvb2xTdGF0dXMEFGJ1cm5MUEFzc2V0T25GYWN0b3J5CQD8BwQFD2ZhY3RvcnlDb250cmFjdAIEYnVybgkAzAgCBQZhbW91bnQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUJbHBBc3NldElkBQZhbW91bnQFA25pbAMJAAACBRRidXJuTFBBc3NldE9uRmFjdG9yeQUUYnVybkxQQXNzZXRPbkZhY3RvcnkFBXN0YXRlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCGFjdGl2YXRlAgthbXRBc3NldFN0cg1wcmljZUFzc2V0U3RyAwkBAiE9AgkApQgBCAUBaQZjYWxsZXIJAKUIAQUPZmFjdG9yeUNvbnRyYWN0CQACAQIScGVybWlzc2lvbnMgZGVuaWVkCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFhAAULYW10QXNzZXRTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAnBhAAUNcHJpY2VBc3NldFN0cgUDbmlsAgdzdWNjZXNzAWkBHGdldFBvb2xDb25maWdXcmFwcGVyUkVBRE9OTFkACQCUCgIFA25pbAkBDWdldFBvb2xDb25maWcAAWkBHGdldEFjY0JhbGFuY2VXcmFwcGVyUkVBRE9OTFkBB2Fzc2V0SWQJAJQKAgUDbmlsCQENZ2V0QWNjQmFsYW5jZQEFB2Fzc2V0SWQBaQEZY2FsY1ByaWNlc1dyYXBwZXJSRUFET05MWQMFYW1BbXQFcHJBbXQFbHBBbXQEBnByaWNlcwkBCmNhbGNQcmljZXMDBQVhbUFtdAUFcHJBbXQFBWxwQW10CQCUCgIFA25pbAkAzAgCCQCmAwEJAJEDAgUGcHJpY2VzAAAJAMwIAgkApgMBCQCRAwIFBnByaWNlcwABCQDMCAIJAKYDAQkAkQMCBQZwcmljZXMAAgUDbmlsAWkBFHRvWDE4V3JhcHBlclJFQURPTkxZAgdvcmlnVmFsDW9yaWdTY2FsZU11bHQJAJQKAgUDbmlsCQCmAwEJAQV0b1gxOAIFB29yaWdWYWwFDW9yaWdTY2FsZU11bHQBaQEWZnJvbVgxOFdyYXBwZXJSRUFET05MWQIDdmFsD3Jlc3VsdFNjYWxlTXVsdAkAlAoCBQNuaWwJAQdmcm9tWDE4AgkApwMBBQN2YWwFD3Jlc3VsdFNjYWxlTXVsdAFpAR5jYWxjUHJpY2VCaWdJbnRXcmFwcGVyUkVBRE9OTFkCCHByQW10WDE4CGFtQW10WDE4CQCUCgIFA25pbAkApgMBCQEPY2FsY1ByaWNlQmlnSW50AgkApwMBBQhwckFtdFgxOAkApwMBBQhhbUFtdFgxOAFpASNlc3RpbWF0ZVB1dE9wZXJhdGlvbldyYXBwZXJSRUFET05MWQkGdHhJZDU4EXNsaXBwYWdlVG9sZXJhbmNlDGluQW1Bc3NldEFtdAtpbkFtQXNzZXRJZAxpblByQXNzZXRBbXQLaW5QckFzc2V0SWQLdXNlckFkZHJlc3MKaXNFdmFsdWF0ZQZlbWl0THAJAJQKAgUDbmlsCQEUZXN0aW1hdGVQdXRPcGVyYXRpb24JBQZ0eElkNTgFEXNsaXBwYWdlVG9sZXJhbmNlBQxpbkFtQXNzZXRBbXQFC2luQW1Bc3NldElkBQxpblByQXNzZXRBbXQFC2luUHJBc3NldElkBQt1c2VyQWRkcmVzcwUKaXNFdmFsdWF0ZQUGZW1pdExwAWkBI2VzdGltYXRlR2V0T3BlcmF0aW9uV3JhcHBlclJFQURPTkxZBAZ0eElkNTgKcG10QXNzZXRJZAhwbXRMcEFtdAt1c2VyQWRkcmVzcwQDcmVzCQEUZXN0aW1hdGVHZXRPcGVyYXRpb24EBQZ0eElkNTgFCnBtdEFzc2V0SWQFCHBtdExwQW10CQERQGV4dHJOYXRpdmUoMTA2MikBBQt1c2VyQWRkcmVzcwkAlAoCBQNuaWwJAJwKCggFA3JlcwJfMQgFA3JlcwJfMggFA3JlcwJfMwgFA3JlcwJfNAgFA3JlcwJfNQgFA3JlcwJfNggFA3JlcwJfNwkApgMBCAUDcmVzAl84CAUDcmVzAl85CAUDcmVzA18xMAFpAQ1zdGF0c1JFQURPTkxZAAQDY2ZnCQENZ2V0UG9vbENvbmZpZwAECWxwQXNzZXRJZAkA2QQBCQCRAwIFA2NmZwUQaWR4UG9vbExQQXNzZXRJZAQKYW10QXNzZXRJZAkAkQMCBQNjZmcFDWlkeEFtdEFzc2V0SWQEDHByaWNlQXNzZXRJZAkAkQMCBQNjZmcFD2lkeFByaWNlQXNzZXRJZAQLaUFtdEFzc2V0SWQJAJEDAgUDY2ZnBQ5pZHhJQW10QXNzZXRJZAQNaVByaWNlQXNzZXRJZAkAkQMCBQNjZmcFEGlkeElQcmljZUFzc2V0SWQEC2FtdEFzc2V0RGNtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDY2ZnBQ5pZHhBbXRBc3NldERjbQQNcHJpY2VBc3NldERjbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2NmZwUQaWR4UHJpY2VBc3NldERjbQQNcG9vbExQQmFsYW5jZQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQlscEFzc2V0SWQJAKwCAgkArAICAgZBc3NldCAJANgEAQUJbHBBc3NldElkAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQSYWNjQW10QXNzZXRCYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFCmFtdEFzc2V0SWQEFGFjY1ByaWNlQXNzZXRCYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFDHByaWNlQXNzZXRJZAQKcHJpY2VzTGlzdAMJAAACBQ1wb29sTFBCYWxhbmNlAAAJAMwIAgUKemVyb0JpZ0ludAkAzAgCBQp6ZXJvQmlnSW50CQDMCAIFCnplcm9CaWdJbnQFA25pbAkBCmNhbGNQcmljZXMDBRJhY2NBbXRBc3NldEJhbGFuY2UFFGFjY1ByaWNlQXNzZXRCYWxhbmNlBQ1wb29sTFBCYWxhbmNlBAhjdXJQcmljZQAABA9scEFtdEFzc2V0U2hhcmUJAQdmcm9tWDE4AgkAkQMCBQpwcmljZXNMaXN0AAEFBnNjYWxlOAQRbHBQcmljZUFzc2V0U2hhcmUJAQdmcm9tWDE4AgkAkQMCBQpwcmljZXNMaXN0AAIFBnNjYWxlOAQKcG9vbFdlaWdodAkBBXZhbHVlAQkAmggCBQ9mYWN0b3J5Q29udHJhY3QJAQ1rZXlQb29sV2VpZ2h0AQkApQgBBQR0aGlzCQCUCgIFA25pbAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUSYWNjQW10QXNzZXRCYWxhbmNlCQDMCAIJAKQDAQUUYWNjUHJpY2VBc3NldEJhbGFuY2UJAMwIAgkApAMBBQ1wb29sTFBCYWxhbmNlCQDMCAIJAKQDAQUIY3VyUHJpY2UJAMwIAgkApAMBBQ9scEFtdEFzc2V0U2hhcmUJAMwIAgkApAMBBRFscFByaWNlQXNzZXRTaGFyZQkAzAgCCQCkAwEFCnBvb2xXZWlnaHQFA25pbAUDU0VQAWkBIGV2YWx1YXRlUHV0QnlBbW91bnRBc3NldFJFQURPTkxZAQxpbkFtQXNzZXRBbXQEA2NmZwkBDWdldFBvb2xDb25maWcABAlscEFzc2V0SWQJANkEAQkAkQMCBQNjZmcFEGlkeFBvb2xMUEFzc2V0SWQEDGFtQXNzZXRJZFN0cgkAkQMCBQNjZmcFDWlkeEFtdEFzc2V0SWQECWFtQXNzZXRJZAkA2QQBBQxhbUFzc2V0SWRTdHIEDHByQXNzZXRJZFN0cgkAkQMCBQNjZmcFD2lkeFByaWNlQXNzZXRJZAQJcHJBc3NldElkCQDZBAEFDHByQXNzZXRJZFN0cgQLYW10QXNzZXREY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFDmlkeEFtdEFzc2V0RGNtBA1wcmljZUFzc2V0RGNtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDY2ZnBRBpZHhQcmljZUFzc2V0RGNtBApwb29sU3RhdHVzCQCRAwIFA2NmZwUNaWR4UG9vbFN0YXR1cwQNcG9vbExQQmFsYW5jZQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQlscEFzc2V0SWQJAKwCAgkArAICAgZBc3NldCAJANgEAQUJbHBBc3NldElkAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQSYWNjQW10QXNzZXRCYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFDGFtQXNzZXRJZFN0cgQUYWNjUHJpY2VBc3NldEJhbGFuY2UJAQ1nZXRBY2NCYWxhbmNlAQUMcHJBc3NldElkU3RyBA5hbXRBc3NldEFtdFgxOAkBBXRvWDE4AgUSYWNjQW10QXNzZXRCYWxhbmNlBQthbXRBc3NldERjbQQQcHJpY2VBc3NldEFtdFgxOAkBBXRvWDE4AgUUYWNjUHJpY2VBc3NldEJhbGFuY2UFDXByaWNlQXNzZXREY20EC2N1clByaWNlWDE4AwkAAAIFDXBvb2xMUEJhbGFuY2UAAAUKemVyb0JpZ0ludAkBD2NhbGNQcmljZUJpZ0ludAIFEHByaWNlQXNzZXRBbXRYMTgFDmFtdEFzc2V0QW10WDE4BA9pbkFtQXNzZXRBbXRYMTgJAQV0b1gxOAIFDGluQW1Bc3NldEFtdAULYW10QXNzZXREY20ED2luUHJBc3NldEFtdFgxOAkAvAIDBQ9pbkFtQXNzZXRBbXRYMTgFC2N1clByaWNlWDE4BQdzY2FsZTE4BAxpblByQXNzZXRBbXQJAQdmcm9tWDE4AgUPaW5QckFzc2V0QW10WDE4BQ1wcmljZUFzc2V0RGNtBAZlc3RQdXQJARRlc3RpbWF0ZVB1dE9wZXJhdGlvbgkCAACgwh4FDGluQW1Bc3NldEFtdAUJYW1Bc3NldElkBQxpblByQXNzZXRBbXQFCXByQXNzZXRJZAIABgcECWNhbGNMcEFtdAgFBmVzdFB1dAJfMQQMY3VyUHJpY2VDYWxjCAUGZXN0UHV0Al8zBAlhbUJhbGFuY2UIBQZlc3RQdXQCXzQECXByQmFsYW5jZQgFBmVzdFB1dAJfNQQKbHBFbWlzc2lvbggFBmVzdFB1dAJfNgkAlAoCBQNuaWwJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUJY2FsY0xwQW10CQDMCAIJAKQDAQkBB2Zyb21YMTgCBQtjdXJQcmljZVgxOAUGc2NhbGU4CQDMCAIJAKQDAQUJYW1CYWxhbmNlCQDMCAIJAKQDAQUJcHJCYWxhbmNlCQDMCAIJAKQDAQUKbHBFbWlzc2lvbgkAzAgCBQpwb29sU3RhdHVzCQDMCAIJAKQDAQUMaW5BbUFzc2V0QW10CQDMCAIJAKQDAQUMaW5QckFzc2V0QW10BQNuaWwFA1NFUAFpAR9ldmFsdWF0ZVB1dEJ5UHJpY2VBc3NldFJFQURPTkxZAQxpblByQXNzZXRBbXQEA2NmZwkBDWdldFBvb2xDb25maWcABAlscEFzc2V0SWQJANkEAQkAkQMCBQNjZmcFEGlkeFBvb2xMUEFzc2V0SWQEDGFtQXNzZXRJZFN0cgkAkQMCBQNjZmcFDWlkeEFtdEFzc2V0SWQECWFtQXNzZXRJZAkA2QQBBQxhbUFzc2V0SWRTdHIEDHByQXNzZXRJZFN0cgkAkQMCBQNjZmcFD2lkeFByaWNlQXNzZXRJZAQJcHJBc3NldElkCQDZBAEFDHByQXNzZXRJZFN0cgQLYW10QXNzZXREY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFDmlkeEFtdEFzc2V0RGNtBA1wcmljZUFzc2V0RGNtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDY2ZnBRBpZHhQcmljZUFzc2V0RGNtBApwb29sU3RhdHVzCQCRAwIFA2NmZwUNaWR4UG9vbFN0YXR1cwQNcG9vbExQQmFsYW5jZQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQlscEFzc2V0SWQJAKwCAgkArAICAgZBc3NldCAJANgEAQUJbHBBc3NldElkAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQMYW1CYWxhbmNlUmF3CQENZ2V0QWNjQmFsYW5jZQEFDGFtQXNzZXRJZFN0cgQMcHJCYWxhbmNlUmF3CQENZ2V0QWNjQmFsYW5jZQEFDHByQXNzZXRJZFN0cgQPYW1CYWxhbmNlUmF3WDE4CQEFdG9YMTgCBQxhbUJhbGFuY2VSYXcFC2FtdEFzc2V0RGNtBA9wckJhbGFuY2VSYXdYMTgJAQV0b1gxOAIFDHByQmFsYW5jZVJhdwUNcHJpY2VBc3NldERjbQQLY3VyUHJpY2VYMTgDCQAAAgUNcG9vbExQQmFsYW5jZQAABQp6ZXJvQmlnSW50CQEPY2FsY1ByaWNlQmlnSW50AgUPcHJCYWxhbmNlUmF3WDE4BQ9hbUJhbGFuY2VSYXdYMTgED2luUHJBc3NldEFtdFgxOAkBBXRvWDE4AgUMaW5QckFzc2V0QW10BQ1wcmljZUFzc2V0RGNtBA9pbkFtQXNzZXRBbXRYMTgJALwCAwUPaW5QckFzc2V0QW10WDE4BQdzY2FsZTE4BQtjdXJQcmljZVgxOAQMaW5BbUFzc2V0QW10CQEHZnJvbVgxOAIFD2luQW1Bc3NldEFtdFgxOAULYW10QXNzZXREY20EBmVzdFB1dAkBFGVzdGltYXRlUHV0T3BlcmF0aW9uCQIAAKDCHgUMaW5BbUFzc2V0QW10BQlhbUFzc2V0SWQFDGluUHJBc3NldEFtdAUJcHJBc3NldElkAgAGBwQJY2FsY0xwQW10CAUGZXN0UHV0Al8xBAxjdXJQcmljZUNhbGMIBQZlc3RQdXQCXzMECWFtQmFsYW5jZQgFBmVzdFB1dAJfNAQJcHJCYWxhbmNlCAUGZXN0UHV0Al81BApscEVtaXNzaW9uCAUGZXN0UHV0Al82CQCUCgIFA25pbAkAuQkCCQDMCAICECVkJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQljYWxjTHBBbXQJAMwIAgkApAMBCQEHZnJvbVgxOAIFC2N1clByaWNlWDE4BQZzY2FsZTgJAMwIAgkApAMBBQlhbUJhbGFuY2UJAMwIAgkApAMBBQlwckJhbGFuY2UJAMwIAgkApAMBBQpscEVtaXNzaW9uCQDMCAIFCnBvb2xTdGF0dXMJAMwIAgkApAMBBQxpbkFtQXNzZXRBbXQJAMwIAgkApAMBBQxpblByQXNzZXRBbXQFA25pbAUDU0VQAWkBE2V2YWx1YXRlR2V0UkVBRE9OTFkCEHBheW1lbnRMcEFzc2V0SWQMcGF5bWVudExwQW10BANyZXMJARRlc3RpbWF0ZUdldE9wZXJhdGlvbgQCAAUQcGF5bWVudExwQXNzZXRJZAUMcGF5bWVudExwQW10BQR0aGlzBAhvdXRBbUFtdAgFA3JlcwJfMQQIb3V0UHJBbXQIBQNyZXMCXzIECWFtQmFsYW5jZQgFA3JlcwJfNQQJcHJCYWxhbmNlCAUDcmVzAl82BApscEVtaXNzaW9uCAUDcmVzAl83BAhjdXJQcmljZQgFA3JlcwJfOAQKcG9vbFN0YXR1cwkBDXBhcnNlSW50VmFsdWUBCAUDcmVzAl85CQCUCgIFA25pbAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUIb3V0QW1BbXQJAMwIAgkApAMBBQhvdXRQckFtdAkAzAgCCQCkAwEFCWFtQmFsYW5jZQkAzAgCCQCkAwEFCXByQmFsYW5jZQkAzAgCCQCkAwEFCmxwRW1pc3Npb24JAMwIAgkApgMBBQhjdXJQcmljZQkAzAgCCQCkAwEFCnBvb2xTdGF0dXMFA25pbAUDU0VQAQJ0eAEGdmVyaWZ5AAQPdGFyZ2V0UHVibGljS2V5BAckbWF0Y2gwCQEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAADCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCcGsFByRtYXRjaDAFAnBrAwkAAQIFByRtYXRjaDACBFVuaXQIBQJ0eA9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgQHJG1hdGNoMAUCdHgDCQABAgUHJG1hdGNoMAIFT3JkZXIEBW9yZGVyBQckbWF0Y2gwBAptYXRjaGVyUHViCQETZ2V0TWF0Y2hlclB1Yk9yRmFpbAAECm9yZGVyVmFsaWQJARt2YWxpZGF0ZU1hdGNoZXJPcmRlckFsbG93ZWQBBQVvcmRlcgQLc2VuZGVyVmFsaWQJAPQDAwgFBW9yZGVyCWJvZHlCeXRlcwkAkQMCCAUFb3JkZXIGcHJvb2ZzAAAIBQVvcmRlcg9zZW5kZXJQdWJsaWNLZXkEDG1hdGNoZXJWYWxpZAkA9AMDCAUFb3JkZXIJYm9keUJ5dGVzCQCRAwIIBQVvcmRlcgZwcm9vZnMAAQUKbWF0Y2hlclB1YgMDAwUKb3JkZXJWYWxpZAULc2VuZGVyVmFsaWQHBQxtYXRjaGVyVmFsaWQHBgkBD3Rocm93T3JkZXJFcnJvcgMFCm9yZGVyVmFsaWQFC3NlbmRlclZhbGlkBQxtYXRjaGVyVmFsaWQDCQABAgUHJG1hdGNoMAIUU2V0U2NyaXB0VHJhbnNhY3Rpb24EAXMFByRtYXRjaDAEB25ld0hhc2gJAPYDAQkBBXZhbHVlAQgFAXMGc2NyaXB0BAthbGxvd2VkSGFzaAkA2wQBCQEFdmFsdWUBCQCdCAIFD2ZhY3RvcnlDb250cmFjdAkBFmtleUFsbG93ZWRMcFNjcmlwdEhhc2gABAtjdXJyZW50SGFzaAkA8QcBBQR0aGlzAwMJAAACBQthbGxvd2VkSGFzaAUHbmV3SGFzaAkBAiE9AgULY3VycmVudEhhc2gFB25ld0hhc2gHBgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUPdGFyZ2V0UHVibGljS2V5CQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQ90YXJnZXRQdWJsaWNLZXmGtmB4", "chainId": 87, "height": 3273034, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 4CvLSXbptbrjCkv7LBTzgPsHDhHaJDgNy5moBUHEH6rP Next: CNLtLCDHZHRLx9sDG1YYykR4ATJesA1rxn5AbFEsHNnx Diff:
OldNewDifferences
765765 }
766766
767767
768-
769-@Callable(i)
770-func testingTest () = $Tuple2(nil, "")
771-
772-
773768 @Verifier(tx)
774769 func verify () = {
775770 let targetPublicKey = match managerPublicKeyOrUnit() {
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let lPdecimals = 8
55
66 let scale8 = 100000000
77
88 let scale8BigInt = toBigInt(100000000)
99
1010 let scale18 = toBigInt(1000000000000000000)
1111
1212 let zeroBigInt = toBigInt(0)
1313
1414 let SEP = "__"
1515
1616 let PoolActive = 1
1717
1818 let PoolPutDisabled = 2
1919
2020 let PoolMatcherDisabled = 3
2121
2222 let PoolShutdown = 4
2323
2424 let idxPoolAddress = 1
2525
2626 let idxPoolStatus = 2
2727
2828 let idxPoolLPAssetId = 3
2929
3030 let idxAmtAssetId = 4
3131
3232 let idxPriceAssetId = 5
3333
3434 let idxAmtAssetDcm = 6
3535
3636 let idxPriceAssetDcm = 7
3737
3838 let idxIAmtAssetId = 8
3939
4040 let idxIPriceAssetId = 9
4141
4242 let idxLPAssetDcm = 10
4343
4444 let idxPoolAmtAssetAmt = 1
4545
4646 let idxPoolPriceAssetAmt = 2
4747
4848 let idxPoolLPAssetAmt = 3
4949
5050 let idxFactoryStakingContract = 1
5151
5252 let idxFactorySlippageContract = 7
5353
5454 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
5555
5656
5757 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
5858
5959
6060 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
6161
6262
6363 func abs (val) = if ((zeroBigInt > val))
6464 then -(val)
6565 else val
6666
6767
6868 func fc () = "%s__factoryContract"
6969
7070
7171 func mpk () = "%s__managerPublicKey"
7272
7373
7474 func pmpk () = "%s__pendingManagerPublicKey"
7575
7676
7777 func pl () = "%s%s__price__last"
7878
7979
8080 func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
8181
8282
8383 func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
8484
8585
8686 func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
8787
8888
8989 func aa () = "%s__amountAsset"
9090
9191
9292 func pa () = "%s__priceAsset"
9393
9494
9595 func keyFactoryConfig () = "%s__factoryConfig"
9696
9797
9898 func keyMatcherPub () = "%s%s__matcher__publicKey"
9999
100100
101101 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
102102
103103
104104 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
105105
106106
107107 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
108108
109109
110110 func keyAllPoolsShutdown () = "%s__shutdown"
111111
112112
113113 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
114114
115115
116116 func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
117117
118118
119119 func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("order validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
120120
121121
122122 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
123123
124124
125125 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
126126
127127
128128 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
129129
130130 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
131131
132132
133133 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
134134
135135
136136 func getPoolConfig () = {
137137 let amtAsset = getStringOrFail(this, aa())
138138 let priceAsset = getStringOrFail(this, pa())
139139 let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
140140 let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
141141 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
142142 }
143143
144144
145145 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
146146
147147
148148 func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageTolerancePassedByUser,slippageToleranceReal,txHeight,txTimestamp,slipageAmtAssetAmt,slipagePriceAssetAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slippageTolerancePassedByUser), toString(slippageToleranceReal), toString(txHeight), toString(txTimestamp), toString(slipageAmtAssetAmt), toString(slipagePriceAssetAmt)], SEP)
149149
150150
151151 func dataGetActionInfo (outAmtAssetAmt,outPriceAssetAmt,inLpAmt,price,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d", toString(outAmtAssetAmt), toString(outPriceAssetAmt), toString(inLpAmt), toString(price), toString(txHeight), toString(txTimestamp)], SEP)
152152
153153
154154 func getAccBalance (assetId) = if ((assetId == "WAVES"))
155155 then wavesBalance(this).available
156156 else assetBalance(this, fromBase58String(assetId))
157157
158158
159159 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
160160
161161
162162 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
163163 let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
164164 let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
165165 calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
166166 }
167167
168168
169169 func calcPrices (amAmt,prAmt,lpAmt) = {
170170 let cfg = getPoolConfig()
171171 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
172172 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
173173 let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
174174 let amAmtX18 = toX18(amAmt, amtAssetDcm)
175175 let prAmtX18 = toX18(prAmt, priceAssetDcm)
176176 let lpAmtX18 = toX18(lpAmt, scale8)
177177 let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
178178 let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
179179 [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
180180 }
181181
182182
183183 func calculatePrices (amAmt,prAmt,lpAmt) = {
184184 let prices = calcPrices(amAmt, prAmt, lpAmt)
185185 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
186186 }
187187
188188
189189 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
190190 let cfg = getPoolConfig()
191191 let lpAssetId = cfg[idxPoolLPAssetId]
192192 let amAssetId = cfg[idxAmtAssetId]
193193 let prAssetId = cfg[idxPriceAssetId]
194194 let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
195195 let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
196196 let poolStatus = cfg[idxPoolStatus]
197197 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
198198 if ((lpAssetId != pmtAssetId))
199199 then throw("Invalid asset passed.")
200200 else {
201201 let amBalance = getAccBalance(amAssetId)
202202 let amBalanceX18 = toX18(amBalance, amAssetDcm)
203203 let prBalance = getAccBalance(prAssetId)
204204 let prBalanceX18 = toX18(prBalance, prAssetDcm)
205205 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
206206 let curPrice = fromX18(curPriceX18, scale8)
207207 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
208208 let lpEmissionX18 = toX18(lpEmission, scale8)
209209 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
210210 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
211211 let outAmAmt = fromX18(outAmAmtX18, amAssetDcm)
212212 let outPrAmt = fromX18(outPrAmtX18, prAssetDcm)
213213 let state = if ((txId58 == ""))
214214 then nil
215215 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
216216 then unit
217217 else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
218218 then unit
219219 else fromBase58String(prAssetId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
220220 $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
221221 }
222222 }
223223
224224
225225 func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
226226 let cfg = getPoolConfig()
227227 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
228228 let amAssetIdStr = cfg[idxAmtAssetId]
229229 let prAssetIdStr = cfg[idxPriceAssetId]
230230 let iAmtAssetId = cfg[idxIAmtAssetId]
231231 let iPriceAssetId = cfg[idxIPriceAssetId]
232232 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
233233 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
234234 let poolStatus = cfg[idxPoolStatus]
235235 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
236236 let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
237237 let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
238238 if (if ((amAssetIdStr != inAmAssetIdStr))
239239 then true
240240 else (prAssetIdStr != inPrAssetIdStr))
241241 then throw("Invalid amt or price asset passed.")
242242 else {
243243 let amBalance = if (isEvaluate)
244244 then getAccBalance(amAssetIdStr)
245245 else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
246246 let prBalance = if (isEvaluate)
247247 then getAccBalance(prAssetIdStr)
248248 else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
249249 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
250250 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
251251 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
252252 let amBalanceX18 = toX18(amBalance, amtAssetDcm)
253253 let prBalanceX18 = toX18(prBalance, priceAssetDcm)
254254 let res = if ((lpEmission == 0))
255255 then {
256256 let curPriceX18 = zeroBigInt
257257 let slippageX18 = zeroBigInt
258258 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
259259 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
260260 }
261261 else {
262262 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
263263 let slippageX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
264264 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
265265 if (if ((curPriceX18 != zeroBigInt))
266266 then (slippageX18 > slippageToleranceX18)
267267 else false)
268268 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
269269 else {
270270 let lpEmissionX18 = toX18(lpEmission, scale8)
271271 let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
272272 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
273273 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
274274 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
275275 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
276276 let expAmtAssetAmtX18 = expectedAmts._1
277277 let expPriceAssetAmtX18 = expectedAmts._2
278278 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
279279 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtAssetDcm), fromX18(expPriceAssetAmtX18, priceAssetDcm), curPriceX18, slippageX18)
280280 }
281281 }
282282 let calcLpAmt = res._1
283283 let calcAmAssetPmt = res._2
284284 let calcPrAssetPmt = res._3
285285 let curPrice = fromX18(res._4, scale8)
286286 let slippageCalc = fromX18(res._5, scale8)
287287 if ((0 >= calcLpAmt))
288288 then throw("Invalid calculations. LP calculated is less than zero.")
289289 else {
290290 let emitLpAmt = if (!(emitLp))
291291 then 0
292292 else calcLpAmt
293293 let amDiff = (inAmAssetAmt - calcAmAssetPmt)
294294 let prDiff = (inPrAssetAmt - calcPrAssetPmt)
295295 let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(calcAmAssetPmt, calcPrAssetPmt, emitLpAmt, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
296296 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
297297 }
298298 }
299299 }
300300
301301
302302 func validateMatcherOrderAllowed (order) = {
303303 let cfg = getPoolConfig()
304304 let amtAssetId = cfg[idxAmtAssetId]
305305 let priceAssetId = cfg[idxPriceAssetId]
306306 let poolStatus = parseIntValue(cfg[idxPoolStatus])
307307 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
308308 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
309309 let accAmtAssetBalance = getAccBalance(amtAssetId)
310310 let accPriceAssetBalance = getAccBalance(priceAssetId)
311311 let curPriceX18 = if ((order.orderType == Buy))
312312 then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
313313 else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
314314 let curPrice = fromX18(curPriceX18, scale8)
315315 if (if (if (isGlobalShutdown())
316316 then true
317317 else (poolStatus == PoolMatcherDisabled))
318318 then true
319319 else (poolStatus == PoolShutdown))
320320 then throw("Exchange operations disabled")
321321 else {
322322 let orderAmtAsset = order.assetPair.amountAsset
323323 let orderAmtAssetStr = if ((orderAmtAsset == unit))
324324 then "WAVES"
325325 else toBase58String(value(orderAmtAsset))
326326 let orderPriceAsset = order.assetPair.priceAsset
327327 let orderPriceAssetStr = if ((orderPriceAsset == unit))
328328 then "WAVES"
329329 else toBase58String(value(orderPriceAsset))
330330 if (if ((orderAmtAssetStr != amtAssetId))
331331 then true
332332 else (orderPriceAssetStr != priceAssetId))
333333 then throw("Wrong order assets.")
334334 else {
335335 let orderPrice = order.price
336336 let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
337337 let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
338338 let isOrderPriceValid = if ((order.orderType == Buy))
339339 then (curPrice >= castedOrderPrice)
340340 else (castedOrderPrice >= curPrice)
341341 true
342342 }
343343 }
344344 }
345345
346346
347347 func commonGet (i) = if ((size(i.payments) != 1))
348348 then throw("exactly 1 payment is expected")
349349 else {
350350 let pmt = value(i.payments[0])
351351 let pmtAssetId = value(pmt.assetId)
352352 let pmtAmt = pmt.amount
353353 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
354354 let outAmAmt = res._1
355355 let outPrAmt = res._2
356356 let poolStatus = parseIntValue(res._9)
357357 let state = res._10
358358 if (if (isGlobalShutdown())
359359 then true
360360 else (poolStatus == PoolShutdown))
361361 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
362362 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
363363 }
364364
365365
366366 func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
367367 then throw("exactly 2 payments are expected")
368368 else {
369369 let amAssetPmt = value(i.payments[0])
370370 let prAssetPmt = value(i.payments[1])
371371 let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
372372 let poolStatus = parseIntValue(estPut._8)
373373 if (if (if (isGlobalShutdown())
374374 then true
375375 else (poolStatus == PoolPutDisabled))
376376 then true
377377 else (poolStatus == PoolShutdown))
378378 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
379379 else estPut
380380 }
381381
382382
383383 func managerPublicKeyOrUnit () = match getString(mpk()) {
384384 case s: String =>
385385 fromBase58String(s)
386386 case _: Unit =>
387387 unit
388388 case _ =>
389389 throw("Match error")
390390 }
391391
392392
393393 func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
394394 case s: String =>
395395 fromBase58String(s)
396396 case _: Unit =>
397397 unit
398398 case _ =>
399399 throw("Match error")
400400 }
401401
402402
403403 func mustManager (i) = {
404404 let pd = throw("Permission denied")
405405 match managerPublicKeyOrUnit() {
406406 case pk: ByteVector =>
407407 if ((i.callerPublicKey == pk))
408408 then true
409409 else pd
410410 case _: Unit =>
411411 if ((i.caller == this))
412412 then true
413413 else pd
414414 case _ =>
415415 throw("Match error")
416416 }
417417 }
418418
419419
420420 @Callable(i)
421421 func constructor (factoryContract) = {
422422 let checkCaller = mustManager(i)
423423 if ((checkCaller == checkCaller))
424424 then [StringEntry(fc(), factoryContract)]
425425 else throw("Strict value is not equal to itself.")
426426 }
427427
428428
429429
430430 @Callable(i)
431431 func setManager (pendingManagerPublicKey) = {
432432 let checkCaller = mustManager(i)
433433 if ((checkCaller == checkCaller))
434434 then {
435435 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
436436 if ((checkManagerPublicKey == checkManagerPublicKey))
437437 then [StringEntry(pmpk(), pendingManagerPublicKey)]
438438 else throw("Strict value is not equal to itself.")
439439 }
440440 else throw("Strict value is not equal to itself.")
441441 }
442442
443443
444444
445445 @Callable(i)
446446 func confirmManager () = {
447447 let pm = pendingManagerPublicKeyOrUnit()
448448 let hasPM = if (isDefined(pm))
449449 then true
450450 else throw("No pending manager")
451451 if ((hasPM == hasPM))
452452 then {
453453 let checkPM = if ((i.callerPublicKey == value(pm)))
454454 then true
455455 else throw("You are not pending manager")
456456 if ((checkPM == checkPM))
457457 then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
458458 else throw("Strict value is not equal to itself.")
459459 }
460460 else throw("Strict value is not equal to itself.")
461461 }
462462
463463
464464
465465 @Callable(i)
466466 func put (slippageTolerance,shouldAutoStake) = {
467467 let factoryCfg = getFactoryConfig()
468468 let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactoryStakingContract]), "Error. Incorrect staking address.")
469469 let slippageContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactorySlippageContract]), "Error. Incorrect slippage contract address.")
470470 if ((0 > slippageTolerance))
471471 then throw("Invalid slippageTolerance passed")
472472 else {
473473 let estPut = commonPut(i, slippageTolerance, true)
474474 let emitLpAmt = estPut._2
475475 let lpAssetId = estPut._7
476476 let state = estPut._9
477477 let amDiff = estPut._10
478478 let prDiff = estPut._11
479479 let amId = estPut._12
480480 let prId = estPut._13
481481 let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
482482 if ((emitInv == emitInv))
483483 then {
484484 let emitInvLegacy = match emitInv {
485485 case legacyFactoryContract: Address =>
486486 invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
487487 case _ =>
488488 unit
489489 }
490490 if ((emitInvLegacy == emitInvLegacy))
491491 then {
492492 let slippageAInv = if ((amDiff > 0))
493493 then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
494494 else nil
495495 if ((slippageAInv == slippageAInv))
496496 then {
497497 let slippagePInv = if ((prDiff > 0))
498498 then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
499499 else nil
500500 if ((slippagePInv == slippagePInv))
501501 then {
502502 let lpTransfer = if (shouldAutoStake)
503503 then {
504504 let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
505505 if ((slpStakeInv == slpStakeInv))
506506 then nil
507507 else throw("Strict value is not equal to itself.")
508508 }
509509 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
510510 (state ++ lpTransfer)
511511 }
512512 else throw("Strict value is not equal to itself.")
513513 }
514514 else throw("Strict value is not equal to itself.")
515515 }
516516 else throw("Strict value is not equal to itself.")
517517 }
518518 else throw("Strict value is not equal to itself.")
519519 }
520520 }
521521
522522
523523
524524 @Callable(i)
525525 func putForFree (maxSlippage) = if ((0 > maxSlippage))
526526 then throw("Invalid value passed")
527527 else {
528528 let estPut = commonPut(i, maxSlippage, false)
529529 estPut._9
530530 }
531531
532532
533533
534534 @Callable(i)
535535 func get () = {
536536 let res = commonGet(i)
537537 let outAmtAmt = res._1
538538 let outPrAmt = res._2
539539 let pmtAmt = res._3
540540 let pmtAssetId = res._4
541541 let state = res._5
542542 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
543543 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
544544 then state
545545 else throw("Strict value is not equal to itself.")
546546 }
547547
548548
549549
550550 @Callable(i)
551551 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
552552 let res = commonGet(i)
553553 let outAmAmt = res._1
554554 let outPrAmt = res._2
555555 let pmtAmt = res._3
556556 let pmtAssetId = res._4
557557 let state = res._5
558558 if ((noLessThenAmtAsset > outAmAmt))
559559 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
560560 else if ((noLessThenPriceAsset > outPrAmt))
561561 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
562562 else {
563563 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
564564 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
565565 then state
566566 else throw("Strict value is not equal to itself.")
567567 }
568568 }
569569
570570
571571
572572 @Callable(i)
573573 func unstakeAndGet (amount) = {
574574 let checkPayments = if ((size(i.payments) != 0))
575575 then throw("No payments are expected")
576576 else true
577577 if ((checkPayments == checkPayments))
578578 then {
579579 let cfg = getPoolConfig()
580580 let factoryCfg = getFactoryConfig()
581581 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
582582 let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactoryStakingContract]), "Error. Incorrect staking address.")
583583 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
584584 if ((unstakeInv == unstakeInv))
585585 then {
586586 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
587587 let poolStatus = parseIntValue(res._9)
588588 let state = res._10
589589 let checkPoolStatus = if (if (isGlobalShutdown())
590590 then true
591591 else (poolStatus == PoolShutdown))
592592 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
593593 else true
594594 if ((checkPoolStatus == checkPoolStatus))
595595 then {
596596 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
597597 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
598598 then state
599599 else throw("Strict value is not equal to itself.")
600600 }
601601 else throw("Strict value is not equal to itself.")
602602 }
603603 else throw("Strict value is not equal to itself.")
604604 }
605605 else throw("Strict value is not equal to itself.")
606606 }
607607
608608
609609
610610 @Callable(i)
611611 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
612612 then throw("permissions denied")
613613 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
614614
615615
616616
617617 @Callable(i)
618618 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
619619
620620
621621
622622 @Callable(i)
623623 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
624624
625625
626626
627627 @Callable(i)
628628 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
629629 let prices = calcPrices(amAmt, prAmt, lpAmt)
630630 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
631631 }
632632
633633
634634
635635 @Callable(i)
636636 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
637637
638638
639639
640640 @Callable(i)
641641 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
642642
643643
644644
645645 @Callable(i)
646646 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
647647
648648
649649
650650 @Callable(i)
651651 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
652652
653653
654654
655655 @Callable(i)
656656 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
657657 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
658658 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
659659 }
660660
661661
662662
663663 @Callable(i)
664664 func statsREADONLY () = {
665665 let cfg = getPoolConfig()
666666 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
667667 let amtAssetId = cfg[idxAmtAssetId]
668668 let priceAssetId = cfg[idxPriceAssetId]
669669 let iAmtAssetId = cfg[idxIAmtAssetId]
670670 let iPriceAssetId = cfg[idxIPriceAssetId]
671671 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
672672 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
673673 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
674674 let accAmtAssetBalance = getAccBalance(amtAssetId)
675675 let accPriceAssetBalance = getAccBalance(priceAssetId)
676676 let pricesList = if ((poolLPBalance == 0))
677677 then [zeroBigInt, zeroBigInt, zeroBigInt]
678678 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
679679 let curPrice = 0
680680 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
681681 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
682682 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
683683 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(accAmtAssetBalance), toString(accPriceAssetBalance), toString(poolLPBalance), toString(curPrice), toString(lpAmtAssetShare), toString(lpPriceAssetShare), toString(poolWeight)], SEP))
684684 }
685685
686686
687687
688688 @Callable(i)
689689 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
690690 let cfg = getPoolConfig()
691691 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
692692 let amAssetIdStr = cfg[idxAmtAssetId]
693693 let amAssetId = fromBase58String(amAssetIdStr)
694694 let prAssetIdStr = cfg[idxPriceAssetId]
695695 let prAssetId = fromBase58String(prAssetIdStr)
696696 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
697697 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
698698 let poolStatus = cfg[idxPoolStatus]
699699 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
700700 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
701701 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
702702 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
703703 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
704704 let curPriceX18 = if ((poolLPBalance == 0))
705705 then zeroBigInt
706706 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
707707 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
708708 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
709709 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
710710 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
711711 let calcLpAmt = estPut._1
712712 let curPriceCalc = estPut._3
713713 let amBalance = estPut._4
714714 let prBalance = estPut._5
715715 let lpEmission = estPut._6
716716 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP))
717717 }
718718
719719
720720
721721 @Callable(i)
722722 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
723723 let cfg = getPoolConfig()
724724 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
725725 let amAssetIdStr = cfg[idxAmtAssetId]
726726 let amAssetId = fromBase58String(amAssetIdStr)
727727 let prAssetIdStr = cfg[idxPriceAssetId]
728728 let prAssetId = fromBase58String(prAssetIdStr)
729729 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
730730 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
731731 let poolStatus = cfg[idxPoolStatus]
732732 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
733733 let amBalanceRaw = getAccBalance(amAssetIdStr)
734734 let prBalanceRaw = getAccBalance(prAssetIdStr)
735735 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
736736 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
737737 let curPriceX18 = if ((poolLPBalance == 0))
738738 then zeroBigInt
739739 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
740740 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
741741 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
742742 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
743743 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
744744 let calcLpAmt = estPut._1
745745 let curPriceCalc = estPut._3
746746 let amBalance = estPut._4
747747 let prBalance = estPut._5
748748 let lpEmission = estPut._6
749749 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP))
750750 }
751751
752752
753753
754754 @Callable(i)
755755 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
756756 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
757757 let outAmAmt = res._1
758758 let outPrAmt = res._2
759759 let amBalance = res._5
760760 let prBalance = res._6
761761 let lpEmission = res._7
762762 let curPrice = res._8
763763 let poolStatus = parseIntValue(res._9)
764764 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(outAmAmt), toString(outPrAmt), toString(amBalance), toString(prBalance), toString(lpEmission), toString(curPrice), toString(poolStatus)], SEP))
765765 }
766766
767767
768-
769-@Callable(i)
770-func testingTest () = $Tuple2(nil, "")
771-
772-
773768 @Verifier(tx)
774769 func verify () = {
775770 let targetPublicKey = match managerPublicKeyOrUnit() {
776771 case pk: ByteVector =>
777772 pk
778773 case _: Unit =>
779774 tx.senderPublicKey
780775 case _ =>
781776 throw("Match error")
782777 }
783778 match tx {
784779 case order: Order =>
785780 let matcherPub = getMatcherPubOrFail()
786781 let orderValid = validateMatcherOrderAllowed(order)
787782 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
788783 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
789784 if (if (if (orderValid)
790785 then senderValid
791786 else false)
792787 then matcherValid
793788 else false)
794789 then true
795790 else throwOrderError(orderValid, senderValid, matcherValid)
796791 case s: SetScriptTransaction =>
797792 let newHash = blake2b256(value(s.script))
798793 let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
799794 let currentHash = scriptHash(this)
800795 if (if ((allowedHash == newHash))
801796 then (currentHash != newHash)
802797 else false)
803798 then true
804799 else sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
805800 case _ =>
806801 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
807802 }
808803 }
809804

github/deemru/w8io/786bc32 
91.15 ms