tx · AD3NkvxyFk26D12gcTn7xdmZWoQfABPtwtkUf9pRNV99

3N8y4wxX3JC4TdrCJBXX16SjWf6X256hrep:  -0.03700000 Waves

2023.04.02 13:43 [2516855] smart account 3N8y4wxX3JC4TdrCJBXX16SjWf6X256hrep > SELF 0.00000000 Waves

{ "type": 13, "id": "AD3NkvxyFk26D12gcTn7xdmZWoQfABPtwtkUf9pRNV99", "fee": 3700000, "feeAssetId": null, "timestamp": 1680432211104, "version": 2, "chainId": 84, "sender": "3N8y4wxX3JC4TdrCJBXX16SjWf6X256hrep", "senderPublicKey": "7v5L7QkXxfkirALdyqmox38QCsa9jtfAtgUfHTh34eWq", "proofs": [ "4KMpgFmB6WnMyFXjpe8AGZyyLjvXv2H7dX9Z5wKpAkndH21hforkvBpo1o84xGudCTEXt3arH6JPaLAJrLoHvmEW" ], "script": "base64:BgIxCAISAwoBCBIECgIRERIECgIRERIDCgEREgUKAwEBARIDCgEIEgQKAggIEgUKAwgICEkAA1NFUAICX18ABU1VTFQ2AMCEPQAFTVVMVDgAgMLXLwAGTVVMVDEwAIDIr6AlAAVjaGFpbgkAyQECCQDKAQIIBQR0aGlzBWJ5dGVzAAEAAQALdXNkbkFzc2V0SWQEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDABILYmKcME9c5TkaQOS3UkL2SMUbH6369UKb1I0h0qsqrRAwkAAAIBAVQFByRtYXRjaDABIPd26vf3g8pl224T7gI7z1gplanB0Y3yS9ps2B1igMjeCQACAQINVW5rbm93biBjaGFpbgAVZGVmYXVsdFJlc3RBZGRyZXNzU3RyBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAiMzUFFDdXZGYnZoNExrUFVucm5VMXozam5iQTFwOW0zV05odgMJAAACAQFUBQckbWF0Y2gwAiMzTXVta0dHenRDS0FYcFdEcXhrZGRvZnFYU1VicVFrdlNKeQkAAgECDVVua25vd24gY2hhaW4BD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAAQxnZXRJbnRPckVsc2UCA2tleQpkZWZhdWx0VmFsCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFA2tleQUKZGVmYXVsdFZhbAARSWR4Q2ZnU3Rha2luZ0RhcHAAAQARSWR4Q2ZnRWNvbm9teURhcHAAAgAUSWR4Q2ZnR292ZXJuYW5jZURhcHAAAwEKa2V5UmVzdENmZwACDiVzX19yZXN0Q29uZmlnAQ5rZXlSZXN0QWRkcmVzcwACDCVzX19yZXN0QWRkcgERcmVhZFJlc3RDZmdPckZhaWwBBHJlc3QJALwJAgkBD2dldFN0cmluZ09yRmFpbAIFBHJlc3QJAQprZXlSZXN0Q2ZnAAUDU0VQARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCB3Jlc3RDZmcDaWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQdyZXN0Q2ZnBQNpZHgJAKwCAgIqUmVzdCBjZmcgZG9lc24ndCBjb250YWluIGFkZHJlc3MgYXQgaW5kZXggCQCkAwEFA2lkeAAMcmVzdENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJAQ5rZXlSZXN0QWRkcmVzcwAFFWRlZmF1bHRSZXN0QWRkcmVzc1N0cgAHcmVzdENmZwkBEXJlYWRSZXN0Q2ZnT3JGYWlsAQUMcmVzdENvbnRyYWN0AA9zdGFraW5nQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBRFJZHhDZmdTdGFraW5nRGFwcAAPREVGQVVMVExPQ0FUSU9OAg9BZnJpY2FfRl9BZnJpY2EABk5VTVJFUwAGABNGQUNUT1JZTUFYV0FSRUhPVVNFAIDIr6AlABBSRVNPVVJDRVBSSUNFTUlOANXWCQAKTUlOUEFZTUVOVACQTgAOU0VMTE1VTFRJUExJRVIAyAEADUJVWU1VTFRJUExJRVIArAIACkxBTkRQUkVGSVgCBExBTkQACkRVQ0tQUkVGSVgCBERVQ0sADFdITVVMVElQTElFUgCAyK+gJQAKQVVDVElPTkZFRQCQTgAIcmVzVHlwZXMJAMwIAgIDT2lsCQDMCAICA09yZQkAzAgCAgRXb29kCQDMCAICBFNhbmQJAMwIAgIEQ2xheQkAzAgCAgdPcmdhbmljBQNuaWwACG1hdFR5cGVzCQDMCAICBEZ1ZWwJAMwIAgIFTWV0YWwJAMwIAgIFUGxhbmsJAMwIAgIFR2xhc3MJAMwIAgIHUGxhc3RpYwkAzAgCAgdQcm90ZWluBQNuaWwACXByb2RUeXBlcwkAzAgCAg1GaXJzdCBBaWQgS2l0CQDMCAICCEJhY2twYWNrCQDMCAICC0Zvb2QgUmF0aW9uCQDMCAICCEpldCBQYWNrCQDMCAICBVJhZGFyBQNuaWwACmNvbnRpbmVudHMJAMwIAgIIQW1lcmljYXMJAMwIAgIGRXVyb3BlCQDMCAICBEFzaWEJAMwIAgIGQWZyaWNhCQDMCAICB09jZWFuaWEFA25pbAAQcHJvZHVjdGlvbk1hdHJpeAkAzAgCAhAxXzFfMV8yXzJfNV8xXzEwCQDMCAICETJfNV81XzJfN181XzJfMTAwCQDMCAICEDFfMV8xXzJfMl81XzFfMTAJAMwIAgIROV85XzFfNV81XzFfNV8xMDAJAMwIAgIRMV81XzFfNV81XzFfMV8xMDAFA25pbAAPY29udElkeEFtZXJpY2FzAAAADWNvbnRJZHhFdXJvcGUAAQALY29udElkeEFzaWEAAgANY29udElkeEFmcmljYQADAA5jb250SWR4T2NlYW5pYQAEAR5rZXlGYWN0b3J5V2FyZWhvdXNlQnlJZEFuZFR5cGUCCWZhY3RvcnlJZAdyZXNUeXBlCQCsAgIJAKwCAgkArAICAhtmYWN0b3J5V2hCeUNvbnRpbmVudEFuZFJlc18FCWZhY3RvcnlJZAIBXwkApAMBBQdyZXNUeXBlAQ5rZXlPcmRlckJ5TGFuZAELbGFuZEFzc2V0SWQJAKwCAgIKbGFuZE9yZGVyXwULbGFuZEFzc2V0SWQBFGtleVN0YWtlZER1Y2tCeU93bmVyAQlvd25lckFkZHIJAKwCAgISc3Rha2VkRHVja0J5T3duZXJfBQlvd25lckFkZHIBEWtleUJhY2twYWNrQnlEdWNrAQtkdWNrQXNzZXRJZAkArAICAgliYWNrUGFja18FC2R1Y2tBc3NldElkAQ9rZXlEdWNrTG9jYXRpb24BC2R1Y2tBc3NldElkCQCsAgICDWR1Y2tMb2NhdGlvbl8FC2R1Y2tBc3NldElkAQprZXlCbG9ja2VkAAIQY29udHJhY3RzQmxvY2tlZAEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQdhc3NldElkCQCsAgICCW5mdE93bmVyXwUHYXNzZXRJZAEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEHYXNzZXRJZAkArAICAgtzdGFrZWRUaW1lXwUHYXNzZXRJZAAPbG9jSWR4Q29udGluZW50AAAACmxvY0lkeFR5cGUAAQAIbG9jSWR4SWQAAgAKYnBJZHhMZXZlbAAAAAhicElkeFJlcwABAAhicElkeE1hdAACAAlicElkeFByb2QAAwAId2hJZHhWb2wAAAAId2hJZHhSZXMAAQAId2hJZHhNYXQAAgAJd2hJZHhQcm9kAAMADndoSWR4TG9ja2VkVm9sAAQACW9yZElkeFJlcwAAAAlvcmRJZHhNYXQAAQAKb3JkSWR4UHJvZAACAQhhc1N0cmluZwEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAFAXMJAAIBAhhmYWlsIHRvIGNhc3QgaW50byBTdHJpbmcBCGdldE9yZGVyAQZvcmRLZXkEAXAJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQZvcmRLZXkCMDBAMF8wQDBfMEAwXzBAMF8wQDBfMEAwOjBAMF8wQDBfMEAwXzBAMF8wQDBfMEAwOgIBOgkAzAgCAwkAAAIJAJADAQkAtQkCCQCRAwIFAXAFCW9yZElkeFJlcwIBXwUGTlVNUkVTCQCRAwIFAXAFCW9yZElkeFJlcwIXMEAwXzBAMF8wQDBfMEAwXzBAMF8wQDAJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQFwBQlvcmRJZHhNYXQCAV8FBk5VTVJFUwkAkQMCBQFwBQlvcmRJZHhNYXQCFzBAMF8wQDBfMEAwXzBAMF8wQDBfMEAwCQDMCAIJAJEDAgUBcAUKb3JkSWR4UHJvZAUDbmlsARJnZXRXYXJlaG91c2VWb2x1bWUBCXZvbFByZWZpeAQFcGFydHMJALUJAgUJdm9sUHJlZml4AgFfCQBoAgkAaAIFDFdITVVMVElQTElFUgkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwYXJ0cwABAAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwYXJ0cwAAARlnZXRXYXJlaG91c2VDdXJyUmVzVm9sdW1lAQljdXJyZW50V2gKAQNzdW0CA2FjYwRpdGVtCQBkAgUDYWNjCQENcGFyc2VJbnRWYWx1ZQEFBGl0ZW0KAAIkbAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8KAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBA3N1bQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8y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YXhQcmljZSA9IAkApAMBBQhtYXhQcmljZQIDLCAoBQVsb2NJZAICLCAJAJEDAgUIbWF0VHlwZXMFB21hdFR5cGUCASkJAJUKAwkBDEludGVnZXJFbnRyeQIFBXdoS2V5CQBlAgUCdzAFAW0FCXVzZG5TcGVudAUBbQELZ2V0QmFja3BhY2sBBWJwS2V5BAFwCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0BQVicEtleQIaMDowXzBfMF8wXzBfMDowXzBfMF8wXzBfMDoCAToJAMwIAgkApAMBCQELdmFsdWVPckVsc2UCCQC2CQEJAJEDAgUBcAUKYnBJZHhMZXZlbAAACQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUBcAUIYnBJZHhSZXMCAV8FBk5VTVJFUwkAkQMCBQFwBQhicElkeFJlcwILMF8wXzBfMF8wXzAJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQFwBQhicElkeE1hdAIBXwUGTlVNUkVTCQCRAwIFAXAFCGJwSWR4TWF0AgswXzBfMF8wXzBfMAkAzAgCCQCRAwIFAXAFCWJwSWR4UHJvZAUDbmlsAQxjaGVja0Jsb2NrZWQAAwkBC3ZhbHVlT3JFbHNlAgkAmwgCBQ9zdGFraW5nQ29udHJhY3QJAQprZXlCbG9ja2VkAAcJAAIBAh9Db250cmFjdHMgYXJlIHVuZGVyIG1haW50ZW5hbmNlBQR1bml0CAFpAQ1jb25zdHJ1Y3RvclYxAQhyZXN0QWRkcgMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECEVBlcm1pc3Npb24gZGVuaWVkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ5rZXlSZXN0QWRkcmVzcwAFCHJlc3RBZGRyBQNuaWwBaQENc2VsbFJlc291cmNlcwIHYW1vdW50cwltaW5QcmljZXMEB2Jsb2NrZWQJAQxjaGVja0Jsb2NrZWQAAwkAAAIFB2Jsb2NrZWQFB2Jsb2NrZWQEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECKnNlbGxSZXNvdXJjZXMgZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50cwQLY3VyTG9jYXRpb24JALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OAgFfAwkBAiE9AgkAkQMCBQtjdXJMb2NhdGlvbgUKbG9jSWR4VHlwZQIBRgkAAgEJAKwCAgItRHVjayBsb2NhdGlvbiB0eXBlIHNob3VsZCBiZSBGYWN0b3J5LCBidXQgaXMgCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlBAVsb2NJZAkAkQMCBQtjdXJMb2NhdGlvbgUIbG9jSWR4SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQHcmVzTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwoBBWFkZGVyAgNhY2MBagMJAGYCCQCRAwIFB2Ftb3VudHMFAWoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdyZXNMaXN0BQFqCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCVlvdSBoYXZlIAkAkQMCBQdyZXNMaXN0BQFqAgQgb2YgCQCRAwIFCHJlc1R5cGVzBQFqAhQsIGJ1dCB0cmllZCB0byBzZWxsIAkApAMBCQCRAwIFB2Ftb3VudHMFAWoDCQBmAgAACQCRAwIFB2Ftb3VudHMFAWoJAAIBCQCsAgIJAKwCAgkArAICAiVZb3UgdHJpZWQgdG8gc2VsbCBuZWdhdGl2ZSBhbW91bnQgb2YgCQCRAwIFCHJlc1R5cGVzBQFqAgI6IAkApAMBCQCRAwIFB2Ftb3VudHMFAWoDCQBmAgkAkQMCBQdhbW91bnRzBQFqAAAEAWIJAQxzZWxsSW50ZXJuYWwEBQVsb2NJZAUBagkAkQMCBQdhbW91bnRzBQFqCQCRAwIFCW1pblByaWNlcwUBagkAlQoDCQDNCAIIBQNhY2MCXzEIBQFiAl8xCQDNCAIIBQNhY2MCXzIJAKQDAQkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdyZXNMaXN0BQFqCQCRAwIFB2Ftb3VudHMFAWoJAGQCCAUDYWNjAl8zCAUBYgJfMgkAlQoDCAUDYWNjAl8xCQDNCAIIBQNhY2MCXzIJAJEDAgUHcmVzTGlzdAUBaggFA2FjYwJfMwQGbWVyZ2VkCgACJGwJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUFA25pbAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJUKAwUDbmlsBQNuaWwAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEFYWRkZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYEB25ld1BhY2sJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJALkJAggFBm1lcmdlZAJfMgIBXwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgQGcmVzdWx0CQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQmFja3BhY2sJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUHbmV3UGFjawUDbmlsBQNuaWwJAJQKAgkAzQgCCAUGbWVyZ2VkAl8xCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIIBQZtZXJnZWQCXzMFC3VzZG5Bc3NldElkBQZyZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEMYnV5TWF0ZXJpYWxzAgdhbW91bnRzCW1heFByaWNlcwQHYmxvY2tlZAkBDGNoZWNrQmxvY2tlZAADCQAAAgUHYmxvY2tlZAUHYmxvY2tlZAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEA2FtdAgFA3BtdAZhbW91bnQECnBtdEFzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAggFA3BtdAdhc3NldElkAh5XQVZFUyBjYW4ndCBiZSB1c2VkIGFzIHBheW1lbnQDCQECIT0CBQpwbXRBc3NldElkBQt1c2RuQXNzZXRJZAkAAgECE1VTRE4gcGF5bWVudHMgb25seSEEC2N1ckxvY2F0aW9uCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgIBXwMJAQIhPQIJAJEDAgULY3VyTG9jYXRpb24FCmxvY0lkeFR5cGUCAUYJAAIBCQCsAgICLUR1Y2sgbG9jYXRpb24gdHlwZSBzaG91bGQgYmUgRmFjdG9yeSwgYnV0IGlzIAkAkQMCBQtjdXJMb2NhdGlvbgUKbG9jSWR4VHlwZQQFbG9jSWQJAJEDAgULY3VyTG9jYXRpb24FCGxvY0lkeElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEB21hdExpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8KAQhtVXBkYXRlcgIDYWNjAWoDCQBmAgAACQCRAwIFB2Ftb3VudHMFAWoJAAIBCQCsAgIJAKwCAgkArAICAiRZb3UgdHJpZWQgdG8gYnV5IG5lZ2F0aXZlIGFtb3VudCBvZiAJAJEDAgUIbWF0VHlwZXMFAWoCAjogCQCkAwEJAJEDAgUHYW1vdW50cwUBagMJAGYCCQCRAwIFB2Ftb3VudHMFAWoAAAQBYgkBC2J1eUludGVybmFsBAUFbG9jSWQFAWoJAJEDAgUHYW1vdW50cwUBagkAkQMCBQltYXhQcmljZXMFAWoJAJUKAwkAzQgCCAUDYWNjAl8xCAUBYgJfMQkAzQgCCAUDYWNjAl8yCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHbWF0TGlzdAUBaggFAWICXzMJAGQCCAUDYWNjAl8zCAUBYgJfMgkAlQoDCAUDYWNjAl8xCQDNCAIIBQNhY2MCXzIJAJEDAgUHbWF0TGlzdAUBaggFA2FjYwJfMwQGbWVyZ2VkCgACJGwJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUFA25pbAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJUKAwUDbmlsBQNuaWwAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIbVVwZGF0ZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYDCQBmAggFBm1lcmdlZAJfMwUDYW10CQACAQkArAICCQCsAgIJAKwCAgIfSW5zdWZmaWNpZW50IHBheW1lbnQhIEF0dGFjaGVkPQkApAMBBQNhbXQCCywgcmVxdWlyZWQ9CQCkAwEIBQZtZXJnZWQCXzMEB25ld1BhY2sJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQDMCAIJALkJAggFBm1lcmdlZAJfMgIBXwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgQGcmVzdWx0CQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQmFja3BhY2sJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUHbmV3UGFjawUDbmlsBQNuaWwEBHJlc3QDCQBmAgkAZQIFA2FtdAgFBm1lcmdlZAJfMwAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgkAZQIFA2FtdAgFBm1lcmdlZAJfMwULdXNkbkFzc2V0SWQFA25pbAUDbmlsCQCUCgIJAM4IAggFBm1lcmdlZAJfMQUEcmVzdAUGcmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEWV4Y2hhbmdlUmVzb3VyY2VzAQdhbW91bnRzBAdibG9ja2VkCQEMY2hlY2tCbG9ja2VkAAMJAAACBQdibG9ja2VkBQdibG9ja2VkBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQDYW10CAUDcG10BmFtb3VudAQKcG10QXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCAUDcG10B2Fzc2V0SWQCHldBVkVTIGNhbid0IGJlIHVzZWQgYXMgcGF5bWVudAMJAQIhPQIFCnBtdEFzc2V0SWQFC3VzZG5Bc3NldElkCQACAQITVVNETiBwYXltZW50cyBvbmx5IQQLY3VyTG9jYXRpb24JALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OAgFfAwkBAiE9AgkAkQMCBQtjdXJMb2NhdGlvbgUKbG9jSWR4VHlwZQIBRgkAAgEJAKwCAgItRHVjayBsb2NhdGlvbiB0eXBlIHNob3VsZCBiZSBGYWN0b3J5LCBidXQgaXMgCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlBAVsb2NJZAkAkQMCBQtjdXJMb2NhdGlvbgUIbG9jSWR4SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQHcmVzTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwQHbWF0TGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwoBCWV4Y2hhbmdlcgIDYWNjAWoEBXdoS2V5CQEea2V5RmFjdG9yeVdhcmVob3VzZUJ5SWRBbmRUeXBlAgUFbG9jSWQFAWoEAncwCQELdmFsdWVPckVsc2UCCQCfCAEFBXdoS2V5AAAEA2FtagkAkQMCBQdhbW91bnRzBQFqAwkAZgIFA2FtagkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB3Jlc0xpc3QFAWoJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIJWW91IGhhdmUgCQCRAwIFB3Jlc0xpc3QFAWoCBCBvZiAJAJEDAgUIcmVzVHlwZXMFAWoCGCwgYnV0IHRyaWVkIHRvIGV4Y2hhbmdlIAkApAMBBQNhbWoDCQBmAgAABQNhbWoJAAIBCQCsAgIJAKwCAgkArAICAilZb3UgdHJpZWQgdG8gZXhjaGFuZ2UgbmVnYXRpdmUgYW1vdW50IG9mIAkAkQMCBQhyZXNUeXBlcwUBagICOiAJAKQDAQUDYW1qAwkAZgIFA2FtagAACQCWCgQJAM0IAggFA2FjYwJfMQkApAMBCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB3Jlc0xpc3QFAWoFA2FtagkAzQgCCAUDYWNjAl8yCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHbWF0TGlzdAUBagUDYW1qCQBkAggFA2FjYwJfMwkAawMFA2FtagUQUkVTT1VSQ0VQUklDRU1JTgUFTVVMVDgJAM0IAggFA2FjYwJfNAkBDEludGVnZXJFbnRyeQIFBXdoS2V5BQJ3MAkAlgoECQDNCAIIBQNhY2MCXzEJAJEDAgUHcmVzTGlzdAUBagkAzQgCCAUDYWNjAl8yCQCRAwIFB21hdExpc3QFAWoIBQNhY2MCXzMIBQNhY2MCXzQEBm1lcmdlZAoAAiRsCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCWCgQFA25pbAUDbmlsAAAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEJZXhjaGFuZ2VyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAwkAZgIIBQZtZXJnZWQCXzMFA2FtdAkAAgEJAKwCAgkArAICCQCsAgICH0luc3VmZmljaWVudCBwYXltZW50ISBBdHRhY2hlZD0JAKQDAQUDYW10AgssIHJlcXVpcmVkPQkApAMBCAUGbWVyZ2VkAl8zBAduZXdQYWNrCQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQC5CQIIBQZtZXJnZWQCXzECAV8JAMwIAgkAuQkCCAUGbWVyZ2VkAl8yAgFfCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6BAZyZXN1bHQJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag51cGRhdGVCYWNrcGFjawkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCBQduZXdQYWNrBQNuaWwFA25pbAQEcmVzdAMJAGYCCQBlAgUDYW10CAUGbWVyZ2VkAl8zAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQBlAgUDYW10CAUGbWVyZ2VkAl8zBQt1c2RuQXNzZXRJZAUDbmlsBQNuaWwJAJQKAgkAzggCBQRyZXN0CAUGbWVyZ2VkAl80BQZyZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEIYnV5R29vZHMDCnByb2R1Y3RJZHgFbGV2ZWwIcXVhbnRpdHkEB2Jsb2NrZWQJAQxjaGVja0Jsb2NrZWQAAwkAAAIFB2Jsb2NrZWQFB2Jsb2NrZWQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAiVidXlHb29kcyBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnRzAwkAZgIAAAUIcXVhbnRpdHkJAAIBAhtRdWFudGl0eSBzaG91bGQgYmUgcG9zaXRpdmUEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQLY3VyTG9jYXRpb24JALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OAgFfAwkBAiE9AgkAkQMCBQtjdXJMb2NhdGlvbgUKbG9jSWR4VHlwZQIBTQkAAgEJAKwCAgIxRHVjayBsb2NhdGlvbiB0eXBlIHNob3VsZCBiZSBNYW51ZmFjdG9yeSwgYnV0IGlzIAkAkQMCBQtjdXJMb2NhdGlvbgUKbG9jSWR4VHlwZQQEY29udAkAkQMCBQtjdXJMb2NhdGlvbgUPbG9jSWR4Q29udGluZW50BAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEB21hdExpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8DAwkAZgIAAAUKcHJvZHVjdElkeAYJAGcCBQpwcm9kdWN0SWR4CQCQAwEFEHByb2R1Y3Rpb25NYXRyaXgJAAIBCQCsAgICFFVua25vd24gcHJvZHVjdCBpZHg9CQCkAwEFCnByb2R1Y3RJZHgEDnByb2R1Y3RDb250SWR4CQBqAgUKcHJvZHVjdElkeAkAkAMBBQpjb250aW5lbnRzAwkBAiE9AgkAkQMCBQpjb250aW5lbnRzBQ5wcm9kdWN0Q29udElkeAUEY29udAkAAgEJAKwCAgkArAICCQCsAgICHVRoaXMgcHJvZHVjdCBpcyBhdmFpbGFibGUgaW4gCQCRAwIFCmNvbnRpbmVudHMFDnByb2R1Y3RDb250SWR4AhEsIGJ1dCB5b3UgYXJlIGluIAUEY29udAQGcmVjaXBlCQC1CQIJAJEDAgUQcHJvZHVjdGlvbk1hdHJpeAUKcHJvZHVjdElkeAIBXwMJAQIhPQIJAJADAQUGcmVjaXBlCQBkAgUGTlVNUkVTAAIJAAIBCQCsAgICF0ZhdGFsOiB1bmtub3duIHJlY2lwZTogCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgFCnByb2R1Y3RJZHgECHByb2RMaXN0AwkAAAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIABQNuaWwJALUJAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgFfCgEGZmlsbGVyAgNhY2MLaWdub3JlZEl0ZW0EAW4IBQNhY2MCXzIEAXgDCQBmAgkAkAMBBQhwcm9kTGlzdAUBbgkAtQkCCQCRAwIFCHByb2RMaXN0BQFuAgEsCQDMCAICATAJAMwIAgIBMAkAzAgCAgEwBQNuaWwEA3gxcwkAkQMCBQF4AAAEAngxCQENcGFyc2VJbnRWYWx1ZQEFA3gxcwQDeDJzCQCRAwIFAXgAAQQCeDIJAQ1wYXJzZUludFZhbHVlAQUDeDJzBAN4M3MJAJEDAgUBeAACBAJ4MwkBDXBhcnNlSW50VmFsdWUBBQN4M3MEBmFtb3VudAkAaAIFCHF1YW50aXR5CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcmVjaXBlAAcEAXkDCQAAAgUBbgUKcHJvZHVjdElkeAQHJG1hdGNoMAUFbGV2ZWwDCQAAAgABBQckbWF0Y2gwCQCsAgIJAKwCAgkArAICCQCsAgIJAKQDAQkAZAIFAngxBQZhbW91bnQCASwFA3gycwIBLAUDeDNzAwkAAAIAAgUHJG1hdGNoMAkArAICCQCsAgIJAKwCAgkArAICBQN4MXMCASwJAKQDAQkAZAIFAngyBQZhbW91bnQCASwFA3gzcwMJAAACAAMFByRtYXRjaDAJAKwCAgkArAICCQCsAgIJAKwCAgUDeDFzAgEsBQN4MnMCASwJAKQDAQkAZAIFAngzBQZhbW91bnQJAAIBCQCsAgICIlByb2R1Y3QgbGV2ZWwgc2hvdWxkIGJlIDEuLjMsIG5vdCAJAKQDAQUFbGV2ZWwJAKwCAgkArAICCQCsAgIJAKwCAgUDeDFzAgEsBQN4MnMCASwFA3gzcwkAlAoCCQDNCAIIBQNhY2MCXzEFAXkJAGQCBQFuAAEEBmJwUHJvZAgKAAIkbAUQcHJvZHVjdGlvbk1hdHJpeAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBmZpbGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyAl8xCgEIcHJvZHVjZXICA2FjYwFqBAduZWVkTWF0CQBoAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnJlY2lwZQUBagUIcXVhbnRpdHkEB2hhdmVNYXQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdtYXRMaXN0BQFqAwkAZgIFB25lZWRNYXQFB2hhdmVNYXQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCVlvdSBoYXZlIAkAkQMCBQdtYXRMaXN0BQFqAgQgb2YgCQCRAwIFCG1hdFR5cGVzBQFqAhYsIGJ1dCByZWNpcGUgcmVxdWlyZXMgCQCkAwEFB25lZWRNYXQCDiBmb3IgcXVhbnRpdHkgCQCkAwEFCHF1YW50aXR5AwkAZgIFB25lZWRNYXQAAAkAzQgCBQNhY2MJAKQDAQkAZQIFB2hhdmVNYXQFB25lZWRNYXQJAM0IAgUDYWNjCQCRAwIFB21hdExpc3QFAWoEBm1lcmdlZAoAAiRsCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCHByb2R1Y2VyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYxXzICCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECBQUkYWNjMAAAAAEAAgADAAQABQAGBAduZXdQYWNrCQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwkAzAgCCQC5CQIFBm1lcmdlZAIBXwkAzAgCCQC5CQIFBmJwUHJvZAIBXwUDbmlsAgE6BAZyZXN1bHQJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag51cGRhdGVCYWNrcGFjawkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCBQduZXdQYWNrBQNuaWwFA25pbAkAlAoCBQNuaWwFBnJlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARRhY2NlcHRTZXJ2aWNlUGF5bWVudAEHc2VydmljZQQHYmxvY2tlZAkBDGNoZWNrQmxvY2tlZAADCQAAAgUHYmxvY2tlZAUHYmxvY2tlZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABANhbXQIBQNwbXQGYW1vdW50BApwbXRBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIIBQNwbXQHYXNzZXRJZAIeV0FWRVMgY2FuJ3QgYmUgdXNlZCBhcyBwYXltZW50AwkBAiE9AgUKcG10QXNzZXRJZAULdXNkbkFzc2V0SWQJAAIBAhNVU0ROIHBheW1lbnRzIG9ubHkhBARuZWVkBAckbWF0Y2gwBQdzZXJ2aWNlAwkAAAICC0xBTkRfUkVOQU1FBQckbWF0Y2gwAICt4gQJAAIBAhBVbmtub3duIHNlcnZpY2UhAwkBAiE9AgUDYW10BQRuZWVkCQACAQkArAICCQCsAgIJAKwCAgUHc2VydmljZQIHIGNvc3RzIAkApAMBBQRuZWVkAgUgVVNETgkAlAoCBQNuaWwFA2FtdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARFzZXRXYXJlaG91c2VPcmRlcgIMY2FyZ29MaXN0U3RyC2xhbmRBc3NldElkBAR1c2VyCAUBaQxvcmlnaW5DYWxsZXIEBGFkZHIJAKUIAQUEdXNlcgQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEJAJoIAgUPc3Rha2luZ0NvbnRyYWN0CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQKY2FyZ29QYXJ0cwkAvAkCBQxjYXJnb0xpc3RTdHICAToDCQECIT0CCQCQAwEFCmNhcmdvUGFydHMAAwkAAgECNGNhcmdvTGlzdFN0ciBzaG91bGQgY29udGFpbiBleGFjdGx5IDIgJzonIHNlcGFyYXRvcnMECHJlc1BhcnRzCQC1CQIJAJEDAgUKY2FyZ29QYXJ0cwAAAgFfBAhtYXRQYXJ0cwkAtQkCCQCRAwIFCmNhcmdvUGFydHMAAQIBXwQJcHJvZFBhcnRzAwkAAAIJAJEDAgUKY2FyZ29QYXJ0cwACAgAFA25pbAkAtQkCCQCRAwIFCmNhcmdvUGFydHMAAgIBXwMJAQIhPQIJAJADAQUIcmVzUGFydHMFBk5VTVJFUwkAAgECIEFsbCA2IHJlc291cmNlcyBzaG91bGQgYmUgcGFzc2VkAwkBAiE9AgkAkAMBBQhtYXRQYXJ0cwUGTlVNUkVTCQACAQIgQWxsIDYgbWF0ZXJpYWxzIHNob3VsZCBiZSBwYXNzZWQEAndoCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIUZ2V0V2FyZWhvdXNlUkVBRE9OTFkJAMwIAgULbGFuZEFzc2V0SWQFA25pbAUDbmlsBAljdXJyZW50V2gJALwJAgUCd2gCAToECWN1cnJXaFJlcwkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8ECWN1cnJXaE1hdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhNYXQCAV8ECmN1cnJXaFByb2QDCQAAAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAIABQNuaWwJALUJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAIBXwQMY3VycldoUmVzVm9sCQEZZ2V0V2FyZWhvdXNlQ3VyclJlc1ZvbHVtZQEFCWN1cnJlbnRXaAQMY3VycldoTWF0Vm9sCQEZZ2V0V2FyZWhvdXNlQ3Vyck1hdFZvbHVtZQEFCWN1cnJlbnRXaAQOY3VycldoR29vZHNWb2wJARtnZXRXYXJlaG91c2VDdXJyR29vZHNWb2x1bWUBBQljdXJyZW50V2gED2N1cnJXaExvY2tlZFZvbAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWN1cnJlbnRXaAUOd2hJZHhMb2NrZWRWb2wEC3doU3BhY2VMZWZ0CQBlAgkAZQIJAGUCCQBlAgkBEmdldFdhcmVob3VzZVZvbHVtZQEJAJEDAgUJY3VycmVudFdoBQh3aElkeFZvbAUMY3VycldoUmVzVm9sBQxjdXJyV2hNYXRWb2wFDmN1cnJXaEdvb2RzVm9sBQ9jdXJyV2hMb2NrZWRWb2wEBm9yZEtleQkBDmtleU9yZGVyQnlMYW5kAQULbGFuZEFzc2V0SWQECmN1cnJlbnRPcmQJAQhnZXRPcmRlcgEFBm9yZEtleQQNY3VycmVudE9yZFJlcwkAtQkCCQCRAwIFCmN1cnJlbnRPcmQFCW9yZElkeFJlcwIBXwQNY3VycmVudE9yZE1hdAkAtQkCCQCRAwIFCmN1cnJlbnRPcmQFCW9yZElkeE1hdAIBXwQOY3VycmVudE9yZFByb2QDCQAAAgkAkQMCBQpjdXJyZW50T3JkBQpvcmRJZHhQcm9kAgAFA25pbAkAtQkCCQCRAwIFCmN1cnJlbnRPcmQFCm9yZElkeFByb2QCAV8EDXVzZG5OZWVkMkxvY2sAAAoBBG9yZFICA2FjYwRpdGVtBAFqCAUDYWNjAl8xBAlpdGVtUGFydHMJALUJAgUEaXRlbQIBQAMJAQIhPQIJAJADAQUJaXRlbVBhcnRzAAIJAAIBAi5JbmNvcnJlY3Qgb3JkZXIgZm9ybWF0LCBzaG91bGQgYmUgYW1vdW50QHByaWNlBAhuZXdPcmRBbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWl0ZW1QYXJ0cwAABAhuZXdPcmRQcgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWl0ZW1QYXJ0cwABBAluZXdPcmRVc2QJAGsDBQhuZXdPcmRBbQUIbmV3T3JkUHIFBU1VTFQ4BAN3aHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQljdXJyV2hSZXMFAWoEC2N1ck9yZFBhcnRzCQC1CQIJAJEDAgUNY3VycmVudE9yZFJlcwUBagIBQAQIY3VyT3JkQW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQtjdXJPcmRQYXJ0cwAABAhjdXJPcmRQcgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFC2N1ck9yZFBhcnRzAAEDCQBmAgAABQhjdXJPcmRQcgkAAgECF1ByaWNlIGNhbid0IGJlIG5lZ2F0aXZlBAljdXJPcmRVc2QJAGsDBQhjdXJPcmRBbQUIY3VyT3JkUHIFBU1VTFQ4AwkAAAIFCG5ld09yZEFtAAADCQBmAgUIY3VyT3JkQW0AAAkAlgoECQBkAgUBagABCQDNCAIIBQNhY2MCXzIJAKQDAQUDd2hyCQBlAggFA2FjYwJfMwUIY3VyT3JkQW0JAGUCCAUDYWNjAl80BQljdXJPcmRVc2QJAJYKBAkAZAIFAWoAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGUCBQN3aHIFCGN1ck9yZEFtCQBkAggFA2FjYwJfMwUIY3VyT3JkQW0IBQNhY2MCXzQDCQBmAgUIbmV3T3JkQW0AAAMJAGYCAAAFCGN1ck9yZEFtBAZhbURpZmYJAGQCBQhuZXdPcmRBbQUIY3VyT3JkQW0JAJYKBAkAZAIFAWoAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGUCBQN3aHIFCGN1ck9yZEFtCQBkAggFA2FjYwJfMwUGYW1EaWZmCQBkAggFA2FjYwJfNAUJbmV3T3JkVXNkCQCWCgQJAGQCBQFqAAEJAM0IAggFA2FjYwJfMgkApAMBBQN3aHIJAGUCCQBkAggFA2FjYwJfMwUIbmV3T3JkQW0FCGN1ck9yZEFtCQBlAgkAZAIIBQNhY2MCXzQFCW5ld09yZFVzZAUJY3VyT3JkVXNkAwkAZgIAAAUIY3VyT3JkQW0EBmFtRGlmZgkAZQIFCGN1ck9yZEFtBQhuZXdPcmRBbQMJAGYCAAAJAGUCBQN3aHIFBmFtRGlmZgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byB0YWtlIAkApAMBBQZhbURpZmYCGiBmcm9tIHdhcmVob3VzZSwgYnV0IG9ubHkgCQCkAwEFA3docgIKIGF2YWlsYWJsZQkAlgoECQBkAgUBagABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZQIFA3docgUGYW1EaWZmCQBkAggFA2FjYwJfMwUGYW1EaWZmCAUDYWNjAl80AwkAZgIAAAkAZAIFA3docgUIbmV3T3JkQW0JAAIBCQCsAgIJAKwCAgkArAICCQCsAgICEEF0dGVtcHQgdG8gdGFrZSAJAKQDAQkBAS0BBQhuZXdPcmRBbQIaIGZyb20gd2FyZWhvdXNlLCBidXQgb25seSAJAKQDAQUDd2hyAgogYXZhaWxhYmxlCQCWCgQJAGQCBQFqAAEJAM0IAggFA2FjYwJfMgkApAMBCQBkAgUDd2hyBQhuZXdPcmRBbQkAZQIJAGUCCAUDYWNjAl8zBQhuZXdPcmRBbQUIY3VyT3JkQW0JAGUCCAUDYWNjAl80BQljdXJPcmRVc2QEAXIKAAIkbAUIcmVzUGFydHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCWCgQAAAUDbmlsAAAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEEb3JkUgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgoBBG9yZE0CA2FjYwRpdGVtBAFqCAUDYWNjAl8xBAlpdGVtUGFydHMJALUJAgUEaXRlbQIBQAMJAQIhPQIJAJADAQUJaXRlbVBhcnRzAAIJAAIBAi5JbmNvcnJlY3Qgb3JkZXIgZm9ybWF0LCBzaG91bGQgYmUgYW1vdW50QHByaWNlBAhuZXdPcmRBbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWl0ZW1QYXJ0cwAABAhuZXdPcmRQcgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWl0ZW1QYXJ0cwABBAluZXdPcmRVc2QJAGsDBQhuZXdPcmRBbQUIbmV3T3JkUHIFBU1VTFQ4BAN3aG0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQljdXJyV2hNYXQFAWoEC2N1ck9yZFBhcnRzCQC1CQIJAJEDAgUNY3VycmVudE9yZE1hdAUBagIBQAQIY3VyT3JkQW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQtjdXJPcmRQYXJ0cwAABAhjdXJPcmRQcgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFC2N1ck9yZFBhcnRzAAEDCQBmAgAABQhjdXJPcmRQcgkAAgECF1ByaWNlIGNhbid0IGJlIG5lZ2F0aXZlBAljdXJPcmRVc2QJAGsDBQhjdXJPcmRBbQUIY3VyT3JkUHIFBU1VTFQ4AwkAAAIFCG5ld09yZEFtAAADCQBmAgUIY3VyT3JkQW0AAAkAlgoECQBkAgUBagABCQDNCAIIBQNhY2MCXzIJAKQDAQUDd2htCQBlAggFA2FjYwJfMwUIY3VyT3JkQW0JAGUCCAUDYWNjAl80BQljdXJPcmRVc2QJAJYKBAkAZAIFAWoAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGUCBQN3aG0FCGN1ck9yZEFtCQBkAggFA2FjYwJfMwUIY3VyT3JkQW0IBQNhY2MCXzQDCQBmAgUIbmV3T3JkQW0AAAMJAGYCAAAFCGN1ck9yZEFtBAZhbURpZmYJAGQCBQhuZXdPcmRBbQUIY3VyT3JkQW0JAJYKBAkAZAIFAWoAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGUCBQN3aG0FCGN1ck9yZEFtCQBkAggFA2FjYwJfMwUGYW1EaWZmCQBkAggFA2FjYwJfNAUJbmV3T3JkVXNkCQCWCgQJAGQCBQFqAAEJAM0IAggFA2FjYwJfMgkApAMBBQN3aG0JAGUCCQBkAggFA2FjYwJfMwUIbmV3T3JkQW0FCGN1ck9yZEFtCQBlAgkAZAIIBQNhY2MCXzQFCW5ld09yZFVzZAUJY3VyT3JkVXNkAwkAZgIAAAUIY3VyT3JkQW0EBmFtRGlmZgkAZQIFCGN1ck9yZEFtBQhuZXdPcmRBbQMJAGYCAAAJAGUCBQN3aG0FBmFtRGlmZgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byB0YWtlIAkApAMBBQZhbURpZmYCGiBmcm9tIHdhcmVob3VzZSwgYnV0IG9ubHkgCQCkAwEFA3dobQIKIGF2YWlsYWJsZQkAlgoECQBkAgUBagABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZQIFA3dobQUGYW1EaWZmCQBkAggFA2FjYwJfMwUGYW1EaWZmCAUDYWNjAl80AwkAZgIAAAkAZAIFA3dobQUIbmV3T3JkQW0JAAIBCQCsAgIJAKwCAgkArAICCQCsAgICEEF0dGVtcHQgdG8gdGFrZSAJAKQDAQkBAS0BBQhuZXdPcmRBbQIaIGZyb20gd2FyZWhvdXNlLCBidXQgb25seSAJAKQDAQUDd2htAgogYXZhaWxhYmxlCQCWCgQJAGQCBQFqAAEJAM0IAggFA2FjYwJfMgkApAMBCQBkAgUDd2htBQhuZXdPcmRBbQkAZQIJAGUCCAUDYWNjAl8zBQhuZXdPcmRBbQUIY3VyT3JkQW0JAGUCCAUDYWNjAl80BQljdXJPcmRVc2QEAW0KAAIkbAUIbWF0UGFydHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCWCgQAAAUDbmlsCAUBcgJfMwgFAXICXzQKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBG9yZE0CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjFfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjFfMgIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYKAQRvcmRQAgNhY2MEaXRlbQQBaggFA2FjYwJfMQQJaXRlbVBhcnRzCQC1CQIFBGl0ZW0CAUADCQECIT0CCQCQAwEFCWl0ZW1QYXJ0cwACCQACAQIuSW5jb3JyZWN0IG9yZGVyIGZvcm1hdCwgc2hvdWxkIGJlIGFtb3VudEBwcmljZQQIbmV3T3JkQW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlpdGVtUGFydHMAAAQIbmV3T3JkUHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlpdGVtUGFydHMAAQQJbmV3T3JkVXNkCQBrAwUIbmV3T3JkQW0FCG5ld09yZFByBQVNVUxUOAQDd2hwCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKY3VycldoUHJvZAUBagQLY3VyT3JkUGFydHMJALUJAgkAkQMCBQ5jdXJyZW50T3JkUHJvZAUBagIBQAQIY3VyT3JkQW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQtjdXJPcmRQYXJ0cwAABAhjdXJPcmRQcgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFC2N1ck9yZFBhcnRzAAEDCQBmAgAABQhjdXJPcmRQcgkAAgECF1ByaWNlIGNhbid0IGJlIG5lZ2F0aXZlBAljdXJPcmRVc2QJAGsDBQhjdXJPcmRBbQUIY3VyT3JkUHIFBU1VTFQ4AwkAAAIFCG5ld09yZEFtAAADCQBmAgUIY3VyT3JkQW0AAAkAlgoECQBkAgUBagABCQDNCAIIBQNhY2MCXzIJAKQDAQUDd2hwCQBlAggFA2FjYwJfMwUIY3VyT3JkQW0JAGUCCAUDYWNjAl80BQljdXJPcmRVc2QJAJYKBAkAZAIFAWoAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGUCBQN3aHAFCGN1ck9yZEFtCQBkAggFA2FjYwJfMwUIY3VyT3JkQW0IBQNhY2MCXzQDCQBmAgUIbmV3T3JkQW0AAAMJAGYCAAAFCGN1ck9yZEFtBAZhbURpZmYJAGQCBQhuZXdPcmRBbQUIY3VyT3JkQW0JAJYKBAkAZAIFAWoAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGUCBQN3aHAFCGN1ck9yZEFtCQBkAggFA2FjYwJfMwUGYW1EaWZmCQBkAggFA2FjYwJfNAUJbmV3T3JkVXNkCQCWCgQJAGQCBQFqAAEJAM0IAggFA2FjYwJfMgkApAMBBQN3aHAJAGUCCQBkAggFA2FjYwJfMwUIbmV3T3JkQW0FCGN1ck9yZEFtCQBlAgkAZAIIBQNhY2MCXzQFCW5ld09yZFVzZAUJY3VyT3JkVXNkAwkAZgIAAAUIY3VyT3JkQW0EBmFtRGlmZgkAZQIFCGN1ck9yZEFtBQhuZXdPcmRBbQMJAGYCAAAJAGUCBQN3aHAFBmFtRGlmZgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byB0YWtlIAkApAMBBQZhbURpZmYCGiBmcm9tIHdhcmVob3VzZSwgYnV0IG9ubHkgCQCkAwEFA3docAIKIGF2YWlsYWJsZQkAlgoECQBkAgUBagABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZQIFA3docAUGYW1EaWZmCQBkAggFA2FjYwJfMwUGYW1EaWZmCAUDYWNjAl8zAwkAZgIAAAkAZAIFA3docAUIbmV3T3JkQW0JAAIBCQCsAgIJAKwCAgkArAIC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ZG8AAAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECEk5vIHBheW1lbnRzIG5lZWRlZAkAzAgCCQELU3RyaW5nRW50cnkCBQZvcmRLZXkFDGNhcmdvTGlzdFN0cgUDbmlsAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQISTm8gcGF5bWVudHMgbmVlZGVkCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBHVzZXIJAQEtAQUIdXNkU2FsZG8FC3VzZG5Bc3NldElkCQDMCAIJAQtTdHJpbmdFbnRyeQIFBm9yZEtleQUMY2FyZ29MaXN0U3RyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEUYWNjZXB0V2FyZWhvdXNlT3JkZXIDCmJwT3JkZXJTdHILbGFuZEFzc2V0SWQLZHVja0Fzc2V0SWQEBmNhbGxlcggFAWkMb3JpZ2luQ2FsbGVyBApjYWxsZXJBZGRyCQClCAEFBmNhbGxlcgQRc3Rha2VkRHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFCmNhbGxlckFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQEC2N1ckxvY2F0aW9uCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBD2tleUR1Y2tMb2NhdGlvbgEFEXN0YWtlZER1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04EA2xvYwkAtQkCCQEFdmFsdWUBBQtjdXJMb2NhdGlvbgIBXwMJAQIhPQIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFMCQACAQkArAICCQCsAgICFkR1Y2sgbG9jYXRpb24gdHlwZSBpcyAJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAhEsIGJ1dCBzaG91bGQgYmUgTAMJAQIhPQIFEXN0YWtlZER1Y2tBc3NldElkBQtkdWNrQXNzZXRJZAkAAgEJAKwCAgkArAICCQCsAgICFFlvdXIgc3Rha2VkIGR1Y2sgaXMgBRFzdGFrZWREdWNrQXNzZXRJZAINLCBidXQgcGFzc2VkIAULZHVja0Fzc2V0SWQECWxhbmRBc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAmggCBQ9zdGFraW5nQ29udHJhY3QJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQJAAIBCQCsAgIJAKwCAgIETkZUIAgFCWxhbmRBc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQJbGFuZE93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAKwCAgkArAICAgRORlQgCAUJbGFuZEFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAAACBQlsYW5kT3duZXIFCmNhbGxlckFkZHIJAAIBAh5Zb3UgY2Fubm90IHRyYWRlIHdpdGggeW91cnNlbGYEDGJwT3JkZXJQYXJ0cwkAvAkCBQpicE9yZGVyU3RyAgE6AwkBAiE9AgkAkAMBBQxicE9yZGVyUGFydHMAAwkAAgECMmJwT3JkZXJTdHIgc2hvdWxkIGNvbnRhaW4gZXhhY3RseSAyICc6JyBzZXBhcmF0b3JzBAhicE9yZFJlcwkAtQkCCQCRAwIFDGJwT3JkZXJQYXJ0cwAAAgFfBAhicE9yZE1hdAkAtQkCCQCRAwIFDGJwT3JkZXJQYXJ0cwABAgFfBAlicE9yZFByb2QDCQAAAgkAkQMCBQxicE9yZGVyUGFydHMAAgIABQNuaWwJALUJAgkAkQMCBQxicE9yZGVyUGFydHMAAgIBXwMJAQIhPQIJAJADAQUIYnBPcmRSZXMFBk5VTVJFUwkAAgECIEFsbCA2IHJlc291cmNlcyBzaG91bGQgYmUgcGFzc2VkAwkBAiE9AgkAkAMBBQhicE9yZE1hdAUGTlVNUkVTCQACAQIgQWxsIDYgbWF0ZXJpYWxzIHNob3VsZCBiZSBwYXNzZWQEAndoCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIUZ2V0V2FyZWhvdXNlUkVBRE9OTFkJAMwIAgULbGFuZEFzc2V0SWQFA25pbAUDbmlsBAljdXJyZW50V2gJALwJAgUCd2gCAToECWN1cnJXaFJlcwkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8ECWN1cnJXaE1hdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhNYXQCAV8ECmN1cnJXaFByb2QDCQAAAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAIABQNuaWwJALUJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAIBXwQMY3VycldoUmVzVm9sCQEZZ2V0V2FyZWhvdXNlQ3VyclJlc1ZvbHVtZQEFCWN1cnJlbnRXaAQMY3VycldoTWF0Vm9sCQEZZ2V0V2FyZWhvdXNlQ3Vyck1hdFZvbHVtZQEFCWN1cnJlbnRXaAQOY3VycldoR29vZHNWb2wJARtnZXRXYXJlaG91c2VDdXJyR29vZHNWb2x1bWUBBQljdXJyZW50V2gED2N1cnJXaExvY2tlZFZvbAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWN1cnJlbnRXaAUOd2hJZHhMb2NrZWRWb2wEC3doU3BhY2VMZWZ0CQBlAgkAZQIJAGUCCQBlAgkBEmdldFdhcmVob3VzZVZvbHVtZQEJAJEDAgUJY3VycmVudFdoBQh3aElkeFZvbAUMY3VycldoUmVzVm9sBQxjdXJyV2hNYXRWb2wFDmN1cnJXaEdvb2RzVm9sBQ9jdXJyV2hMb2NrZWRWb2wEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAlicFJlc0xpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMCAV8ECWJwTWF0TGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQKYnBQcm9kTGlzdAMJAAACCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAAUDbmlsCQC1CQIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIBXwQGb3JkS2V5CQEOa2V5T3JkZXJCeUxhbmQBBQtsYW5kQXNzZXRJZAQFd2hPcmQJAQhnZXRPcmRlcgEFBm9yZEtleQQId2hPcmRSZXMJALUJAgkAkQMCBQV3aE9yZAUJb3JkSWR4UmVzAgFfBAh3aE9yZE1hdAkAtQkCCQCRAwIFBXdoT3JkBQlvcmRJZHhNYXQCAV8ECXdoT3JkUHJvZAMJAAACCQCRAwIFBXdoT3JkBQpvcmRJZHhQcm9kAgAFA25pbAkAtQkCCQCRAwIFBXdoT3JkBQpvcmRJZHhQcm9kAgFfBA11c2RuTmVlZDJMb2NrAAAKAQRvcmRSAgNhY2MBagQNYnBPcmRSZXNQYXJ0cwkAtQkCCQCRAwIFCGJwT3JkUmVzBQFqAgFAAwkBAiE9AgkAkAMBBQ1icE9yZFJlc1BhcnRzAAIJAAIBAi5JbmNvcnJlY3Qgb3JkZXIgZm9ybWF0LCBzaG91bGQgYmUgYW1vdW50QHByaWNlBAdicE9yZEFtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUNYnBPcmRSZXNQYXJ0cwAABAdicE9yZFByCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUNYnBPcmRSZXNQYXJ0cwABAwkAZgIAAAUHYnBPcmRQcgkAAgECF1ByaWNlIGNhbid0IGJlIG5lZ2F0aXZlBAhicE9yZFVzZAkAawMFB2JwT3JkQW0FB2JwT3JkUHIFBU1VTFQ4BANicHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlicFJlc0xpc3QFAWoEA3docgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWN1cnJXaFJlcwUBagQKd2hPcmRQYXJ0cwkAtQkCCQCRAwIFCHdoT3JkUmVzBQFqAgFABAd3aE9yZEFtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKd2hPcmRQYXJ0cwAABAd3aE9yZFByCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKd2hPcmRQYXJ0cwABAwkBAiE9AgUHYnBPcmRQcgUHd2hPcmRQcgkAAgEJAKwCAgkArAICAgpQcmljZXMgb2YgCQCRAwIFCHJlc1R5cGVzBQFqAgwgZG9uJ3QgbWF0Y2gECHdoT3JkVXNkCQBrAwUHd2hPcmRBbQUHd2hPcmRQcgUFTVVMVDgDCQAAAgUHYnBPcmRBbQAACQCYCgYJAM0IAggFA2FjYwJfMQkAkQMCBQljdXJyV2hSZXMFAWoJAM0IAggFA2FjYwJfMgkAkQMCBQh3aE9yZFJlcwUBagkAzQgCCAUDYWNjAl8zCQCRAwIFCWJwUmVzTGlzdAUBaggFA2FjYwJfNAgFA2FjYwJfNQgFA2FjYwJfNgMJAGYCBQdicE9yZEFtAAADCQBmAgAABQd3aE9yZEFtAwkAZgIFB2JwT3JkQW0JAQEtAQUHd2hPcmRBbQkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAg9BdHRlbXB0IHRvIGJ1eSAJAKQDAQUHYnBPcmRBbQIEIG9mIAkAkQMCBQhyZXNUeXBlcwUBagIbLCBidXQgd2FyZWhvdXNlIG9ubHkgc2VsbHMgCQCkAwEJAQEtAQUHd2hPcmRBbQkAmAoGCQDNCAIIBQNhY2MCXzEJAJEDAgUJY3VycldoUmVzBQFqCQDNCAIIBQNhY2MCXzIJAKwCAgkArAICCQCkAwEJAGQCBQd3aE9yZEFtBQdicE9yZEFtAgFACQCkAwEFB3doT3JkUHIJAM0IAggFA2FjYwJfMwkApAMBCQBkAgUDYnByBQdicE9yZEFtCQBkAggFA2FjYwJfNAUHYnBPcmRBbQgFA2FjYwJfNQkAZAIIBQNhY2MCXzYFCGJwT3JkVXNkCQACAQkArAICCQCsAgICD0F0dGVtcHQgdG8gYnV5IAkAkQMCBQhyZXNUeXBlcwUBagIgIHdoaWxlIHdhcmVob3VzZSBkb2Vzbid0IHNlbGwgaXQDCQBmAgUHd2hPcmRBbQAAAwkAZgIJAQEtAQUHYnBPcmRBbQUHd2hPcmRBbQkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhBBdHRlbXB0IHRvIHNlbGwgCQCkAwEJAQEtAQUHYnBPcmRBbQIEIG9mIAkAkQMCBQhyZXNUeXBlcwUBagIaLCBidXQgd2FyZWhvdXNlIG9ubHkgYnV5cyAJAKQDAQUHd2hPcmRBbQMJAGYCCQEBLQEFB2JwT3JkQW0FA2JwcgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhBBdHRlbXB0IHRvIHNlbGwgCQCkAwEJAQEtAQUHYnBPcmRBbQIULCBidXQgeW91IG9ubHkgaGF2ZSAJAJEDAgUJYnBSZXNMaXN0BQFqAgQgb2YgCQCRAwIFCHJlc1R5cGVzBQFqCQCYCgYJAM0IAggFA2FjYwJfMQkApAMBCQBlAgUDd2hyBQdicE9yZEFtCQDNCAIIBQNhY2MCXzIJAKwCAgkArAICCQCkAwEJAGQCBQd3aE9yZEFtBQdicE9yZEFtAgFACQCkAwEFB3doT3JkUHIJAM0IAggFA2FjYwJfMwIBMAkAZQIIBQNhY2MCXzQFB2JwT3JkQW0JAGUCCAUDYWNjAl81BQhicE9yZFVzZAgFA2FjYwJfNgkAAgEJAKwCAgkArAICAhBBdHRlbXB0IHRvIHNlbGwgCQCRAwIFCHJlc1R5cGVzBQFqAh8gd2hpbGUgd2FyZWhvdXNlIGRvZXNuJ3QgYnV5IGl0BAFyCgACJGwJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUFA25pbAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJgKBgUDbmlsBQNuaWwFA25pbAAAAAAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEEb3JkUgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgoBBG9yZE0CA2FjYwFqBA1icE9yZE1hdFBhcnRzCQC1CQIJAJEDAgUIYnBPcmRNYXQFAWoCAUADCQECIT0CCQCQAwEFDWJwT3JkTWF0UGFydHMAAgkAAgECLkluY29ycmVjdCBvcmRlciBmb3JtYXQsIHNob3VsZCBiZSBhbW91bnRAcHJpY2UEB2JwT3JkQW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ1icE9yZE1hdFBhcnRzAAAEB2JwT3JkUHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ1icE9yZE1hdFBhcnRzAAEDCQBmAgAABQdicE9yZFByCQACAQIXUHJpY2UgY2FuJ3QgYmUgbmVnYXRpdmUECGJwT3JkVXNkCQBrAwUHYnBPcmRBbQUHYnBPcmRQcgUFTVVMVDgEA2JwcgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWJwTWF0TGlzdAUBagQDd2hyCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJY3VycldoTWF0BQFqBAp3aE9yZFBhcnRzCQC1CQIJAJEDAgUId2hPcmRNYXQFAWoCAUAEB3doT3JkQW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQp3aE9yZFBhcnRzAAAEB3doT3JkUHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQp3aE9yZFBhcnRzAAEDCQECIT0CBQdicE9yZFByBQd3aE9yZFByCQACAQkArAICCQCsAgICClByaWNlcyBvZiAJAJEDAgUIbWF0VHlwZXMFAWoCDCBkb24ndCBtYXRjaAQId2hPcmRVc2QJAGsDBQd3aE9yZEFtBQd3aE9yZFByBQVNVUxUOAMJAAACBQdicE9yZEFtAAAJAJgKBgkAzQgCCAUDYWNjAl8xCQCRAwIFCWN1cnJXaE1hdAUBagkAzQgCCAUDYWNjAl8yCQCRAwIFCHdoT3JkTWF0BQFqCQDNCAIIBQNhY2MCXzMJAJEDAgUJYnBNYXRMaXN0BQFqCAUDYWNjAl80CAUDYWNjAl81CAUDYWNjAl82AwkAZgIFB2JwT3JkQW0AAAMJAGYCAAAFB3doT3JkQW0DCQBmAgUHYnBPcmRBbQkBAS0BBQd3aE9yZEFtCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICD0F0dGVtcHQgdG8gYnV5IAkApAMBBQdicE9yZEFtAgQgb2YgCQCRAwIFCG1hdFR5cGVzBQFqAhssIGJ1dCB3YXJlaG91c2Ugb25seSBzZWxscyAJAKQDAQkBAS0BBQd3aE9yZEFtCQCYCgYJAM0IAggFA2FjYwJfMQkAkQMCBQljdXJyV2hNYXQFAWoJAM0IAggFA2FjYwJfMgkArAICCQCsAgIJAKQDAQkAZAIFB3doT3JkQW0FB2JwT3JkQW0CAUAJAKQDAQUHd2hPcmRQcgkAzQgCCAUDYWNjAl8zCQCkAwEJAGQCBQNicHIFB2JwT3JkQW0JAGQCCAUDYWNjAl80BQdicE9yZEFtCAUDYWNjAl81CQBkAggFA2FjYwJfNgUIYnBPcmRVc2QJAAIBCQCsAgIJAKwCAgIPQXR0ZW1wdCB0byBidXkgCQCRAwIFCG1hdFR5cGVzBQFqAiAgd2hpbGUgd2FyZWhvdXNlIGRvZXNuJ3Qgc2VsbCBpdAMJAGYCBQd3aE9yZEFtAAADCQBmAgkBAS0BBQdicE9yZEFtBQd3aE9yZEFtCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICEEF0dGVtcHQgdG8gc2VsbCAJAKQDAQkBAS0BBQdicE9yZEFtAgQgb2YgCQCRAwIFCG1hdFR5cGVzBQFqAhosIGJ1dCB3YXJlaG91c2Ugb25seSBidXlzIAkApAMBBQd3aE9yZEFtAwkAZgIJAQEtAQUHYnBPcmRBbQUDYnByCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICEEF0dGVtcHQgdG8gc2VsbCAJAKQDAQkBAS0BBQdicE9yZEFtAhQsIGJ1dCB5b3Ugb25seSBoYXZlIAkAkQMCBQlicE1hdExpc3QFAWoCBCBvZiAJAJEDAgUIbWF0VHlwZXMFAWoJAJgKBgkAzQgCCAUDYWNjAl8xCQCkAwEJAGUCBQN3aHIFB2JwT3JkQW0JAM0IAggFA2FjYwJfMgkArAICCQCsAgIJAKQDAQkAZAIFB3doT3JkQW0FB2JwT3JkQW0CAUAJAKQDAQUHd2hPcmRQcgkAzQgCCAUDYWNjAl8zAgEwCQBlAggFA2FjYwJfNAUHYnBPcmRBbQkAZQIIBQNhY2MCXzUFCGJwT3JkVXNkCAUDYWNjAl82CQACAQkArAICCQCsAgICEEF0dGVtcHQgdG8gc2VsbCAJAJEDAgUIbWF0VHlwZXMFAWoCHyB3aGlsZSB3YXJlaG91c2UgZG9lc24ndCBidXkgaXQEAW0KAAIkbAkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAmAoGBQNuaWwFA25pbAUDbmlsCAUBcgJfNAgFAXICXzUIBQFyAl82CgEFJGYxXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQRvcmRNAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYxXzICCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECBQUkYWNjMAAAAAEAAgADAAQABQAGCgEEb3JkUAIDYWNjAWoEDmJwT3JkUHJvZFBhcnRzCQC1CQIJAJEDAgUJYnBPcmRQcm9kBQFqAgFAAwkBAiE9AgkAkAMBBQ5icE9yZFByb2RQYXJ0cwACCQACAQIuSW5jb3JyZWN0IG9yZGVyIGZvcm1hdCwgc2hvdWxkIGJlIGFtb3VudEBwcmljZQQHYnBPcmRBbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmJwT3JkUHJvZFBhcnRzAAAEB2JwT3JkUHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5icE9yZFByb2RQYXJ0cwABAwkAZgIAAAUHYnBPcmRQcgkAAgECF1ByaWNlIGNhbid0IGJlIG5lZ2F0aXZlBAhicE9yZFVzZAkAawMFB2JwT3JkQW0FB2JwT3JkUHIFBU1VTFQ4BANicHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpicFByb2RMaXN0BQFqBAN3aHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpjdXJyV2hQcm9kBQFqBAp3aE9yZFBhcnRzCQC1CQIJAJEDAgUJd2hPcmRQcm9kBQFqAgFABAd3aE9yZEFtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKd2hPcmRQYXJ0cwAABAd3aE9yZFByCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKd2hPcmRQYXJ0cwABAwkBAiE9AgUHYnBPcmRQcgUHd2hPcmRQcgkAAgEJAKwCAgkArAICAgpQcmljZXMgb2YgCQCRAwIFCXByb2RUeXBlcwUBagIMIGRvbid0IG1hdGNoBAh3aE9yZFVzZAkAawMFB3doT3JkQW0FB3doT3JkUHIFBU1VTFQ4AwkAAAIFB2JwT3JkQW0AAAkAmAoGCQDNCAIIBQNhY2MCXzEJAJEDAgUKY3VycldoUHJvZAUBagkAzQgCCAUDYWNjAl8yCQCRAwIFCXdoT3JkUHJvZAUBagkAzQgCCAUDYWNjAl8zCQCRAwIFCmJwUHJvZExpc3QFAWoIBQNhY2MCXzQIBQNhY2MCXzUIBQNhY2MCXzYDCQBmAgUHYnBPcmRBbQAAAwkAZgIAAAUHd2hPcmRBbQMJAGYCBQdicE9yZEFtCQEBLQEFB3doT3JkQW0JAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIPQXR0ZW1wdCB0byBidXkgCQCkAwEFB2JwT3JkQW0CBCBvZiAJAJEDAgUJcHJvZFR5cGVzBQFqAhssIGJ1dCB3YXJlaG91c2Ugb25seSBzZWxscyAJAKQDAQkBAS0BBQd3aE9yZEFtCQCYCgYJAM0IAggFA2FjYwJfMQkAkQMCBQpjdXJyV2hQcm9kBQFqCQDNCAIIBQNhY2MCXzIJAKwCAgkArAICCQCkAwEJAGQCBQd3aE9yZEFtBQdicE9yZEFtAgFACQCkAwEFB3doT3JkUHIJAM0IAggFA2FjYwJfMwkApAMBCQBkAgUDYnByBQdicE9yZEFtCQBkAggFA2FjYwJfNAUHYnBPcmRBbQgFA2FjYwJfNQkAZAIIBQNhY2MCXzYFCGJwT3JkVXNkCQACAQkArAICCQCsAgICD0F0dGVtcHQgdG8gYnV5IAkAkQMCBQlwcm9kVHlwZXMFAWoCICB3aGlsZSB3YXJlaG91c2UgZG9lc24ndCBzZWxsIGl0AwkAZgIFB3doT3JkQW0AAAMJAGYCCQEBLQEFB2JwT3JkQW0FB3doT3JkQW0JAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byBzZWxsIAkApAMBCQEBLQEFB2JwT3JkQW0CBCBvZiAJAJEDAgUJcHJvZFR5cGVzBQFqAhosIGJ1dCB3YXJlaG91c2Ugb25seSBidXlzIAkApAMBBQd3aE9yZEFtAwkAZgIJAQEtAQUHYnBPcmRBbQUDYnByCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICEEF0dGVtcHQgdG8gc2VsbCAJAKQDAQkBAS0BBQdicE9yZEFtAhQsIGJ1dCB5b3Ugb25seSBoYXZlIAkAkQMCBQpicFByb2RMaXN0BQFqAgQgb2YgCQCRAwIFCXByb2RUeXBlcwUBagkAmAoGCQDNCAIIBQNhY2MCXzEJAKQDAQkAZQIFA3docgUHYnBPcmRBbQkAzQgCCAUDYWNjAl8yCQCsAgIJAKwCAgkApAMBCQBkAgUHd2hPcmRBbQUHYnBPcmRBbQIBQAkApAMBBQd3aE9yZFByCQDNCAIIBQNhY2MCXzMCATAJAGUCCAUDYWNjAl80BQdicE9yZEFtCQBlAggFA2FjYwJfNQUIYnBPcmRVc2QIBQNhY2MCXzYJAAIBCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byBzZWxsIAkAkQMCBQlwcm9kVHlwZXMFAWoCHyB3aGlsZSB3YXJlaG91c2UgZG9lc24ndCBidXkgaXQEAXAKAAIkbAkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAmAoGBQNuaWwFA25pbAUDbmlsCAUBbQJfNAgFAW0CXzUIBQFtAl82CgEFJGYyXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQRvcmRQAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYyXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyA1MAkBBSRmMl8yAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgkBBSRmMl8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIECHZvbFNhbGRvCAUBcAJfNAQFd2hTdHIJALoJAgkAzAgCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhWb2wJAMwIAgkAuQkCCAUBcgJfMQIBXwkAzAgCCQC5CQIIBQFtAl8xAgFfCQDMCAIJALkJAggFAXACXzECAV8JAMwIAgkApAMBBQh2b2xTYWxkbwUDbmlsAgE6BAtuZXdXaE9yZFN0cgkAugkCCQDMCAIJALkJAggFAXICXzICAV8JAMwIAgkAuQkCCAUBbQJfMgIBXwkAzAgCCQC5CQIIBQFwAl8yAgFfBQNuaWwCAToECG5ld0JwU3RyCQC6CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQC5CQIIBQFyAl8zAgFfCQDMCAIJALkJAggFAW0CXzMCAV8JAMwIAgkAuQkCCAUBcAJfMwIBXwUDbmlsAgE6BAZ3aFNhdmUJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag1zYXZlV2FyZWhvdXNlCQDMCAIFBXdoU3RyCQDMCAIFC2xhbmRBc3NldElkBQNuaWwFA25pbAMJAAACBQZ3aFNhdmUFBndoU2F2ZQQGYnBTYXZlCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQmFja3BhY2sJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUIbmV3QnBTdHIFA25pbAUDbmlsAwkAAAIFBmJwU2F2ZQUGYnBTYXZlBAdhY3Rpb25zCQDMCAIJAQtTdHJpbmdFbnRyeQIFBm9yZEtleQULbmV3V2hPcmRTdHIFA25pbAQNdXNkV2gyQnBTYWxkbwkAawMIBQFwAl81CQBkAgUFTVVMVDYFCkFVQ1RJT05GRUUFBU1VTFQ2BAhhY3Rpb25zMQMJAGYCBQ11c2RXaDJCcFNhbGRvAAAJAM0IAgUHYWN0aW9ucwkBDlNjcmlwdFRyYW5zZmVyAwUGY2FsbGVyCAUBcAJfNQULdXNkbkFzc2V0SWQFB2FjdGlvbnMEDXVzZEJwMldoU2FsZG8JAGsDCAUBcAJfNgkAZAIFBU1VTFQ2BQpBVUNUSU9ORkVFBQVNVUxUNgMJAGYCBQ11c2RCcDJXaFNhbGRvAAADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQDYW10CAUDcG10BmFtb3VudAQKcG10QXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCAUDcG10B2Fzc2V0SWQCHldBVkVTIGNhbid0IGJlIHVzZWQgYXMgcGF5bWVudAMJAQIhPQIFCnBtdEFzc2V0SWQFC3VzZG5Bc3NldElkCQACAQITVVNETiBwYXltZW50cyBvbmx5IQMJAQIhPQIFA2FtdAUNdXNkQnAyV2hTYWxkbwkAAgEJAKwCAgISUGF5bWVudCBuZWVkZWQgaXMgCQCkAwEFDXVzZEJwMldoU2FsZG8JAM0IAgUIYWN0aW9uczEJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCWxhbmRPd25lcggFAXACXzYFC3VzZG5Bc3NldElkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQISTm8gcGF5bWVudHMgbmVlZGVkBQhhY3Rpb25zMQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgDXv7F6", "height": 2516855, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 4e8CR9WsTCjwR4wM8UyPBvpwYLBEq5MrNrvcJvRQfU4h Next: 5mVjATuTepdb2fK1y43A8WMVy8WQp5MQvCGoSMjjt1Jo Diff:
OldNewDifferences
7979
8080 let WHMULTIPLIER = 10000000000
8181
82+let AUCTIONFEE = 10000
83+
8284 let resTypes = ["Oil", "Ore", "Wood", "Sand", "Clay", "Organic"]
8385
8486 let matTypes = ["Fuel", "Metal", "Plank", "Glass", "Plastic", "Protein"]
87+
88+let prodTypes = ["First Aid Kit", "Backpack", "Food Ration", "Jet Pack", "Radar"]
8589
8690 let continents = ["Americas", "Europe", "Asia", "Africa", "Oceania"]
8791
670674 let curOrdParts = split(currentOrdRes[j], "@")
671675 let curOrdAm = parseIntValue(curOrdParts[0])
672676 let curOrdPr = parseIntValue(curOrdParts[1])
673- let curOrdUsd = fraction(curOrdAm, curOrdPr, MULT8)
674- if ((newOrdAm == 0))
675- then if ((curOrdAm > 0))
676- then $Tuple4((j + 1), (acc._2 :+ toString(whr)), (acc._3 - curOrdAm), (acc._4 - curOrdUsd))
677- else $Tuple4((j + 1), (acc._2 :+ toString((whr - curOrdAm))), (acc._3 + curOrdAm), acc._4)
678- else if ((newOrdAm > 0))
679- then if ((0 > curOrdAm))
680- then {
681- let amDiff = (newOrdAm + curOrdAm)
682- $Tuple4((j + 1), (acc._2 :+ toString((whr - curOrdAm))), (acc._3 + amDiff), (acc._4 + newOrdUsd))
683- }
684- else $Tuple4((j + 1), (acc._2 :+ toString(whr)), ((acc._3 + newOrdAm) - curOrdAm), ((acc._4 + newOrdUsd) - curOrdUsd))
685- else if ((0 > curOrdAm))
686- then {
687- let amDiff = (curOrdAm - newOrdAm)
688- if ((0 > (whr - amDiff)))
689- then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whr)) + " available"))
690- else $Tuple4((j + 1), (acc._2 :+ toString((whr - amDiff))), (acc._3 + amDiff), acc._4)
691- }
692- else if ((0 > (whr + newOrdAm)))
693- then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whr)) + " available"))
694- else $Tuple4((j + 1), (acc._2 :+ toString((whr + newOrdAm))), ((acc._3 - newOrdAm) - curOrdAm), (acc._4 - curOrdUsd))
677+ if ((0 > curOrdPr))
678+ then throw("Price can't be negative")
679+ else {
680+ let curOrdUsd = fraction(curOrdAm, curOrdPr, MULT8)
681+ if ((newOrdAm == 0))
682+ then if ((curOrdAm > 0))
683+ then $Tuple4((j + 1), (acc._2 :+ toString(whr)), (acc._3 - curOrdAm), (acc._4 - curOrdUsd))
684+ else $Tuple4((j + 1), (acc._2 :+ toString((whr - curOrdAm))), (acc._3 + curOrdAm), acc._4)
685+ else if ((newOrdAm > 0))
686+ then if ((0 > curOrdAm))
687+ then {
688+ let amDiff = (newOrdAm + curOrdAm)
689+ $Tuple4((j + 1), (acc._2 :+ toString((whr - curOrdAm))), (acc._3 + amDiff), (acc._4 + newOrdUsd))
690+ }
691+ else $Tuple4((j + 1), (acc._2 :+ toString(whr)), ((acc._3 + newOrdAm) - curOrdAm), ((acc._4 + newOrdUsd) - curOrdUsd))
692+ else if ((0 > curOrdAm))
693+ then {
694+ let amDiff = (curOrdAm - newOrdAm)
695+ if ((0 > (whr - amDiff)))
696+ then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whr)) + " available"))
697+ else $Tuple4((j + 1), (acc._2 :+ toString((whr - amDiff))), (acc._3 + amDiff), acc._4)
698+ }
699+ else if ((0 > (whr + newOrdAm)))
700+ then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whr)) + " available"))
701+ else $Tuple4((j + 1), (acc._2 :+ toString((whr + newOrdAm))), ((acc._3 - newOrdAm) - curOrdAm), (acc._4 - curOrdUsd))
702+ }
695703 }
696704 }
697705
722730 let curOrdParts = split(currentOrdMat[j], "@")
723731 let curOrdAm = parseIntValue(curOrdParts[0])
724732 let curOrdPr = parseIntValue(curOrdParts[1])
725- let curOrdUsd = fraction(curOrdAm, curOrdPr, MULT8)
726- if ((newOrdAm == 0))
727- then if ((curOrdAm > 0))
728- then $Tuple4((j + 1), (acc._2 :+ toString(whm)), (acc._3 - curOrdAm), (acc._4 - curOrdUsd))
729- else $Tuple4((j + 1), (acc._2 :+ toString((whm - curOrdAm))), (acc._3 + curOrdAm), acc._4)
730- else if ((newOrdAm > 0))
731- then if ((0 > curOrdAm))
732- then {
733- let amDiff = (newOrdAm + curOrdAm)
734- $Tuple4((j + 1), (acc._2 :+ toString((whm - curOrdAm))), (acc._3 + amDiff), (acc._4 + newOrdUsd))
735- }
736- else $Tuple4((j + 1), (acc._2 :+ toString(whm)), ((acc._3 + newOrdAm) - curOrdAm), ((acc._4 + newOrdUsd) - curOrdUsd))
737- else if ((0 > curOrdAm))
738- then {
739- let amDiff = (curOrdAm - newOrdAm)
740- if ((0 > (whm - amDiff)))
741- then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whm)) + " available"))
742- else $Tuple4((j + 1), (acc._2 :+ toString((whm - amDiff))), (acc._3 + amDiff), acc._4)
743- }
744- else if ((0 > (whm + newOrdAm)))
745- then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whm)) + " available"))
746- else $Tuple4((j + 1), (acc._2 :+ toString((whm + newOrdAm))), ((acc._3 - newOrdAm) - curOrdAm), (acc._4 - curOrdUsd))
733+ if ((0 > curOrdPr))
734+ then throw("Price can't be negative")
735+ else {
736+ let curOrdUsd = fraction(curOrdAm, curOrdPr, MULT8)
737+ if ((newOrdAm == 0))
738+ then if ((curOrdAm > 0))
739+ then $Tuple4((j + 1), (acc._2 :+ toString(whm)), (acc._3 - curOrdAm), (acc._4 - curOrdUsd))
740+ else $Tuple4((j + 1), (acc._2 :+ toString((whm - curOrdAm))), (acc._3 + curOrdAm), acc._4)
741+ else if ((newOrdAm > 0))
742+ then if ((0 > curOrdAm))
743+ then {
744+ let amDiff = (newOrdAm + curOrdAm)
745+ $Tuple4((j + 1), (acc._2 :+ toString((whm - curOrdAm))), (acc._3 + amDiff), (acc._4 + newOrdUsd))
746+ }
747+ else $Tuple4((j + 1), (acc._2 :+ toString(whm)), ((acc._3 + newOrdAm) - curOrdAm), ((acc._4 + newOrdUsd) - curOrdUsd))
748+ else if ((0 > curOrdAm))
749+ then {
750+ let amDiff = (curOrdAm - newOrdAm)
751+ if ((0 > (whm - amDiff)))
752+ then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whm)) + " available"))
753+ else $Tuple4((j + 1), (acc._2 :+ toString((whm - amDiff))), (acc._3 + amDiff), acc._4)
754+ }
755+ else if ((0 > (whm + newOrdAm)))
756+ then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whm)) + " available"))
757+ else $Tuple4((j + 1), (acc._2 :+ toString((whm + newOrdAm))), ((acc._3 - newOrdAm) - curOrdAm), (acc._4 - curOrdUsd))
758+ }
747759 }
748760 }
749761
774786 let curOrdParts = split(currentOrdProd[j], "@")
775787 let curOrdAm = parseIntValue(curOrdParts[0])
776788 let curOrdPr = parseIntValue(curOrdParts[1])
777- let curOrdUsd = fraction(curOrdAm, curOrdPr, MULT8)
778- if ((newOrdAm == 0))
779- then if ((curOrdAm > 0))
780- then $Tuple4((j + 1), (acc._2 :+ toString(whp)), (acc._3 - curOrdAm), (acc._4 - curOrdUsd))
781- else $Tuple4((j + 1), (acc._2 :+ toString((whp - curOrdAm))), (acc._3 + curOrdAm), acc._4)
782- else if ((newOrdAm > 0))
783- then if ((0 > curOrdAm))
784- then {
785- let amDiff = (newOrdAm + curOrdAm)
786- $Tuple4((j + 1), (acc._2 :+ toString((whp - curOrdAm))), (acc._3 + amDiff), (acc._4 + newOrdUsd))
787- }
788- else $Tuple4((j + 1), (acc._2 :+ toString(whp)), ((acc._3 + newOrdAm) - curOrdAm), ((acc._4 + newOrdUsd) - curOrdUsd))
789- else if ((0 > curOrdAm))
790- then {
791- let amDiff = (curOrdAm - newOrdAm)
792- if ((0 > (whp - amDiff)))
793- then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whp)) + " available"))
794- else $Tuple4((j + 1), (acc._2 :+ toString((whp - amDiff))), (acc._3 + amDiff), acc._3)
795- }
796- else if ((0 > (whp + newOrdAm)))
797- then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whp)) + " available"))
798- else $Tuple4((j + 1), (acc._2 :+ toString((whp + newOrdAm))), ((acc._3 - newOrdAm) - curOrdAm), (acc._4 - curOrdUsd))
789+ if ((0 > curOrdPr))
790+ then throw("Price can't be negative")
791+ else {
792+ let curOrdUsd = fraction(curOrdAm, curOrdPr, MULT8)
793+ if ((newOrdAm == 0))
794+ then if ((curOrdAm > 0))
795+ then $Tuple4((j + 1), (acc._2 :+ toString(whp)), (acc._3 - curOrdAm), (acc._4 - curOrdUsd))
796+ else $Tuple4((j + 1), (acc._2 :+ toString((whp - curOrdAm))), (acc._3 + curOrdAm), acc._4)
797+ else if ((newOrdAm > 0))
798+ then if ((0 > curOrdAm))
799+ then {
800+ let amDiff = (newOrdAm + curOrdAm)
801+ $Tuple4((j + 1), (acc._2 :+ toString((whp - curOrdAm))), (acc._3 + amDiff), (acc._4 + newOrdUsd))
802+ }
803+ else $Tuple4((j + 1), (acc._2 :+ toString(whp)), ((acc._3 + newOrdAm) - curOrdAm), ((acc._4 + newOrdUsd) - curOrdUsd))
804+ else if ((0 > curOrdAm))
805+ then {
806+ let amDiff = (curOrdAm - newOrdAm)
807+ if ((0 > (whp - amDiff)))
808+ then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whp)) + " available"))
809+ else $Tuple4((j + 1), (acc._2 :+ toString((whp - amDiff))), (acc._3 + amDiff), acc._3)
810+ }
811+ else if ((0 > (whp + newOrdAm)))
812+ then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whp)) + " available"))
813+ else $Tuple4((j + 1), (acc._2 :+ toString((whp + newOrdAm))), ((acc._3 - newOrdAm) - curOrdAm), (acc._4 - curOrdUsd))
814+ }
799815 }
800816 }
801817
821837 let whSave = invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)
822838 if ((whSave == whSave))
823839 then {
824- let usdSaldo = p._4
840+ let usdSaldo = fraction(p._4, (MULT6 + AUCTIONFEE), MULT6)
825841 if ((usdSaldo > 0))
826842 then if ((size(i.payments) != 1))
827843 then throw("exactly 1 payment must be attached")
852868 }
853869
854870
871+
872+@Callable(i)
873+func acceptWarehouseOrder (bpOrderStr,landAssetId,duckAssetId) = {
874+ let caller = i.originCaller
875+ let callerAddr = toString(caller)
876+ let stakedDuckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(callerAddr)), "You don't have a duck staked")
877+ let curLocation = valueOrElse(getString(stakingContract, keyDuckLocation(stakedDuckAssetId)), DEFAULTLOCATION)
878+ let loc = split(value(curLocation), "_")
879+ if ((loc[locIdxType] != "L"))
880+ then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
881+ else if ((stakedDuckAssetId != duckAssetId))
882+ then throw(((("Your staked duck is " + stakedDuckAssetId) + ", but passed ") + duckAssetId))
883+ else {
884+ let landAsset = value(assetInfo(fromBase58String(landAssetId)))
885+ if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId)))))
886+ then throw((("NFT " + landAsset.name) + " is not staked"))
887+ else {
888+ let landOwner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + landAsset.name) + " is orphaned"))
889+ if ((landOwner == callerAddr))
890+ then throw("You cannot trade with yourself")
891+ else {
892+ let bpOrderParts = split_4C(bpOrderStr, ":")
893+ if ((size(bpOrderParts) != 3))
894+ then throw("bpOrderStr should contain exactly 2 ':' separators")
895+ else {
896+ let bpOrdRes = split(bpOrderParts[0], "_")
897+ let bpOrdMat = split(bpOrderParts[1], "_")
898+ let bpOrdProd = if ((bpOrderParts[2] == ""))
899+ then nil
900+ else split(bpOrderParts[2], "_")
901+ if ((size(bpOrdRes) != NUMRES))
902+ then throw("All 6 resources should be passed")
903+ else if ((size(bpOrdMat) != NUMRES))
904+ then throw("All 6 materials should be passed")
905+ else {
906+ let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil))
907+ let currentWh = split_4C(wh, ":")
908+ let currWhRes = split(currentWh[whIdxRes], "_")
909+ let currWhMat = split(currentWh[whIdxMat], "_")
910+ let currWhProd = if ((currentWh[whIdxProd] == ""))
911+ then nil
912+ else split(currentWh[whIdxProd], "_")
913+ let currWhResVol = getWarehouseCurrResVolume(currentWh)
914+ let currWhMatVol = getWarehouseCurrMatVolume(currentWh)
915+ let currWhGoodsVol = getWarehouseCurrGoodsVolume(currentWh)
916+ let currWhLockedVol = parseIntValue(currentWh[whIdxLockedVol])
917+ let whSpaceLeft = ((((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol) - currWhLockedVol)
918+ let bpKey = keyBackpackByDuck(duckAssetId)
919+ let currentPack = getBackpack(bpKey)
920+ let bpResList = split(currentPack[bpIdxRes], "_")
921+ let bpMatList = split(currentPack[bpIdxMat], "_")
922+ let bpProdList = if ((currentPack[bpIdxProd] == ""))
923+ then nil
924+ else split(currentPack[bpIdxProd], "_")
925+ let ordKey = keyOrderByLand(landAssetId)
926+ let whOrd = getOrder(ordKey)
927+ let whOrdRes = split(whOrd[ordIdxRes], "_")
928+ let whOrdMat = split(whOrd[ordIdxMat], "_")
929+ let whOrdProd = if ((whOrd[ordIdxProd] == ""))
930+ then nil
931+ else split(whOrd[ordIdxProd], "_")
932+ let usdnNeed2Lock = 0
933+ func ordR (acc,j) = {
934+ let bpOrdResParts = split(bpOrdRes[j], "@")
935+ if ((size(bpOrdResParts) != 2))
936+ then throw("Incorrect order format, should be amount@price")
937+ else {
938+ let bpOrdAm = parseIntValue(bpOrdResParts[0])
939+ let bpOrdPr = parseIntValue(bpOrdResParts[1])
940+ if ((0 > bpOrdPr))
941+ then throw("Price can't be negative")
942+ else {
943+ let bpOrdUsd = fraction(bpOrdAm, bpOrdPr, MULT8)
944+ let bpr = parseIntValue(bpResList[j])
945+ let whr = parseIntValue(currWhRes[j])
946+ let whOrdParts = split(whOrdRes[j], "@")
947+ let whOrdAm = parseIntValue(whOrdParts[0])
948+ let whOrdPr = parseIntValue(whOrdParts[1])
949+ if ((bpOrdPr != whOrdPr))
950+ then throw((("Prices of " + resTypes[j]) + " don't match"))
951+ else {
952+ let whOrdUsd = fraction(whOrdAm, whOrdPr, MULT8)
953+ if ((bpOrdAm == 0))
954+ then $Tuple6((acc._1 :+ currWhRes[j]), (acc._2 :+ whOrdRes[j]), (acc._3 :+ bpResList[j]), acc._4, acc._5, acc._6)
955+ else if ((bpOrdAm > 0))
956+ then if ((0 > whOrdAm))
957+ then if ((bpOrdAm > -(whOrdAm)))
958+ then throw(((((("Attempt to buy " + toString(bpOrdAm)) + " of ") + resTypes[j]) + ", but warehouse only sells ") + toString(-(whOrdAm))))
959+ else $Tuple6((acc._1 :+ currWhRes[j]), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ toString((bpr + bpOrdAm))), (acc._4 + bpOrdAm), acc._5, (acc._6 + bpOrdUsd))
960+ else throw((("Attempt to buy " + resTypes[j]) + " while warehouse doesn't sell it"))
961+ else if ((whOrdAm > 0))
962+ then if ((-(bpOrdAm) > whOrdAm))
963+ then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + " of ") + resTypes[j]) + ", but warehouse only buys ") + toString(whOrdAm)))
964+ else if ((-(bpOrdAm) > bpr))
965+ then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + ", but you only have ") + bpResList[j]) + " of ") + resTypes[j]))
966+ else $Tuple6((acc._1 :+ toString((whr - bpOrdAm))), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ "0"), (acc._4 - bpOrdAm), (acc._5 - bpOrdUsd), acc._6)
967+ else throw((("Attempt to sell " + resTypes[j]) + " while warehouse doesn't buy it"))
968+ }
969+ }
970+ }
971+ }
972+
973+ let r = {
974+ let $l = [0, 1, 2, 3, 4, 5]
975+ let $s = size($l)
976+ let $acc0 = $Tuple6(nil, nil, nil, 0, 0, 0)
977+ func $f0_1 ($a,$i) = if (($i >= $s))
978+ then $a
979+ else ordR($a, $l[$i])
980+
981+ func $f0_2 ($a,$i) = if (($i >= $s))
982+ then $a
983+ else throw("List size exceeds 6")
984+
985+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
986+ }
987+ func ordM (acc,j) = {
988+ let bpOrdMatParts = split(bpOrdMat[j], "@")
989+ if ((size(bpOrdMatParts) != 2))
990+ then throw("Incorrect order format, should be amount@price")
991+ else {
992+ let bpOrdAm = parseIntValue(bpOrdMatParts[0])
993+ let bpOrdPr = parseIntValue(bpOrdMatParts[1])
994+ if ((0 > bpOrdPr))
995+ then throw("Price can't be negative")
996+ else {
997+ let bpOrdUsd = fraction(bpOrdAm, bpOrdPr, MULT8)
998+ let bpr = parseIntValue(bpMatList[j])
999+ let whr = parseIntValue(currWhMat[j])
1000+ let whOrdParts = split(whOrdMat[j], "@")
1001+ let whOrdAm = parseIntValue(whOrdParts[0])
1002+ let whOrdPr = parseIntValue(whOrdParts[1])
1003+ if ((bpOrdPr != whOrdPr))
1004+ then throw((("Prices of " + matTypes[j]) + " don't match"))
1005+ else {
1006+ let whOrdUsd = fraction(whOrdAm, whOrdPr, MULT8)
1007+ if ((bpOrdAm == 0))
1008+ then $Tuple6((acc._1 :+ currWhMat[j]), (acc._2 :+ whOrdMat[j]), (acc._3 :+ bpMatList[j]), acc._4, acc._5, acc._6)
1009+ else if ((bpOrdAm > 0))
1010+ then if ((0 > whOrdAm))
1011+ then if ((bpOrdAm > -(whOrdAm)))
1012+ then throw(((((("Attempt to buy " + toString(bpOrdAm)) + " of ") + matTypes[j]) + ", but warehouse only sells ") + toString(-(whOrdAm))))
1013+ else $Tuple6((acc._1 :+ currWhMat[j]), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ toString((bpr + bpOrdAm))), (acc._4 + bpOrdAm), acc._5, (acc._6 + bpOrdUsd))
1014+ else throw((("Attempt to buy " + matTypes[j]) + " while warehouse doesn't sell it"))
1015+ else if ((whOrdAm > 0))
1016+ then if ((-(bpOrdAm) > whOrdAm))
1017+ then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + " of ") + matTypes[j]) + ", but warehouse only buys ") + toString(whOrdAm)))
1018+ else if ((-(bpOrdAm) > bpr))
1019+ then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + ", but you only have ") + bpMatList[j]) + " of ") + matTypes[j]))
1020+ else $Tuple6((acc._1 :+ toString((whr - bpOrdAm))), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ "0"), (acc._4 - bpOrdAm), (acc._5 - bpOrdUsd), acc._6)
1021+ else throw((("Attempt to sell " + matTypes[j]) + " while warehouse doesn't buy it"))
1022+ }
1023+ }
1024+ }
1025+ }
1026+
1027+ let m = {
1028+ let $l = [0, 1, 2, 3, 4, 5]
1029+ let $s = size($l)
1030+ let $acc0 = $Tuple6(nil, nil, nil, r._4, r._5, r._6)
1031+ func $f1_1 ($a,$i) = if (($i >= $s))
1032+ then $a
1033+ else ordM($a, $l[$i])
1034+
1035+ func $f1_2 ($a,$i) = if (($i >= $s))
1036+ then $a
1037+ else throw("List size exceeds 6")
1038+
1039+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1040+ }
1041+ func ordP (acc,j) = {
1042+ let bpOrdProdParts = split(bpOrdProd[j], "@")
1043+ if ((size(bpOrdProdParts) != 2))
1044+ then throw("Incorrect order format, should be amount@price")
1045+ else {
1046+ let bpOrdAm = parseIntValue(bpOrdProdParts[0])
1047+ let bpOrdPr = parseIntValue(bpOrdProdParts[1])
1048+ if ((0 > bpOrdPr))
1049+ then throw("Price can't be negative")
1050+ else {
1051+ let bpOrdUsd = fraction(bpOrdAm, bpOrdPr, MULT8)
1052+ let bpr = parseIntValue(bpProdList[j])
1053+ let whr = parseIntValue(currWhProd[j])
1054+ let whOrdParts = split(whOrdProd[j], "@")
1055+ let whOrdAm = parseIntValue(whOrdParts[0])
1056+ let whOrdPr = parseIntValue(whOrdParts[1])
1057+ if ((bpOrdPr != whOrdPr))
1058+ then throw((("Prices of " + prodTypes[j]) + " don't match"))
1059+ else {
1060+ let whOrdUsd = fraction(whOrdAm, whOrdPr, MULT8)
1061+ if ((bpOrdAm == 0))
1062+ then $Tuple6((acc._1 :+ currWhProd[j]), (acc._2 :+ whOrdProd[j]), (acc._3 :+ bpProdList[j]), acc._4, acc._5, acc._6)
1063+ else if ((bpOrdAm > 0))
1064+ then if ((0 > whOrdAm))
1065+ then if ((bpOrdAm > -(whOrdAm)))
1066+ then throw(((((("Attempt to buy " + toString(bpOrdAm)) + " of ") + prodTypes[j]) + ", but warehouse only sells ") + toString(-(whOrdAm))))
1067+ else $Tuple6((acc._1 :+ currWhProd[j]), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ toString((bpr + bpOrdAm))), (acc._4 + bpOrdAm), acc._5, (acc._6 + bpOrdUsd))
1068+ else throw((("Attempt to buy " + prodTypes[j]) + " while warehouse doesn't sell it"))
1069+ else if ((whOrdAm > 0))
1070+ then if ((-(bpOrdAm) > whOrdAm))
1071+ then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + " of ") + prodTypes[j]) + ", but warehouse only buys ") + toString(whOrdAm)))
1072+ else if ((-(bpOrdAm) > bpr))
1073+ then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + ", but you only have ") + bpProdList[j]) + " of ") + prodTypes[j]))
1074+ else $Tuple6((acc._1 :+ toString((whr - bpOrdAm))), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ "0"), (acc._4 - bpOrdAm), (acc._5 - bpOrdUsd), acc._6)
1075+ else throw((("Attempt to sell " + prodTypes[j]) + " while warehouse doesn't buy it"))
1076+ }
1077+ }
1078+ }
1079+ }
1080+
1081+ let p = {
1082+ let $l = [0, 1, 2, 3, 4, 5]
1083+ let $s = size($l)
1084+ let $acc0 = $Tuple6(nil, nil, nil, m._4, m._5, m._6)
1085+ func $f2_1 ($a,$i) = if (($i >= $s))
1086+ then $a
1087+ else ordP($a, $l[$i])
1088+
1089+ func $f2_2 ($a,$i) = if (($i >= $s))
1090+ then $a
1091+ else throw("List size exceeds 50")
1092+
1093+ $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
1094+ }
1095+ let volSaldo = p._4
1096+ let whStr = makeString_2C([currentWh[whIdxVol], makeString(r._1, "_"), makeString(m._1, "_"), makeString(p._1, "_"), toString(volSaldo)], ":")
1097+ let newWhOrdStr = makeString_2C([makeString(r._2, "_"), makeString(m._2, "_"), makeString(p._2, "_")], ":")
1098+ let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(r._3, "_"), makeString(m._3, "_"), makeString(p._3, "_")], ":")
1099+ let whSave = invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)
1100+ if ((whSave == whSave))
1101+ then {
1102+ let bpSave = invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil)
1103+ if ((bpSave == bpSave))
1104+ then {
1105+ let actions = [StringEntry(ordKey, newWhOrdStr)]
1106+ let usdWh2BpSaldo = fraction(p._5, (MULT6 + AUCTIONFEE), MULT6)
1107+ let actions1 = if ((usdWh2BpSaldo > 0))
1108+ then (actions :+ ScriptTransfer(caller, p._5, usdnAssetId))
1109+ else actions
1110+ let usdBp2WhSaldo = fraction(p._6, (MULT6 + AUCTIONFEE), MULT6)
1111+ if ((usdBp2WhSaldo > 0))
1112+ then if ((size(i.payments) != 1))
1113+ then throw("exactly 1 payment must be attached")
1114+ else {
1115+ let pmt = i.payments[0]
1116+ let amt = pmt.amount
1117+ let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
1118+ if ((pmtAssetId != usdnAssetId))
1119+ then throw("USDN payments only!")
1120+ else if ((amt != usdBp2WhSaldo))
1121+ then throw(("Payment needed is " + toString(usdBp2WhSaldo)))
1122+ else (actions1 :+ ScriptTransfer(addressFromStringValue(landOwner), p._6, usdnAssetId))
1123+ }
1124+ else if ((size(i.payments) != 0))
1125+ then throw("No payments needed")
1126+ else actions1
1127+ }
1128+ else throw("Strict value is not equal to itself.")
1129+ }
1130+ else throw("Strict value is not equal to itself.")
1131+ }
1132+ }
1133+ }
1134+ }
1135+ }
1136+ }
1137+
1138+
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
55
66 let MULT6 = 1000000
77
88 let MULT8 = 100000000
99
1010 let MULT10 = 10000000000
1111
1212 let chain = take(drop(this.bytes, 1), 1)
1313
1414 let usdnAssetId = match chain {
1515 case _ =>
1616 if ((base58'2W' == $match0))
1717 then base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
1818 else if ((base58'2T' == $match0))
1919 then base58'HezsdQuRDtzksAYUy97gfhKy7Z1NW2uXYSHA3bgqenNZ'
2020 else throw("Unknown chain")
2121 }
2222
2323 let defaultRestAddressStr = match chain {
2424 case _ =>
2525 if ((base58'2W' == $match0))
2626 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
2727 else if ((base58'2T' == $match0))
2828 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
2929 else throw("Unknown chain")
3030 }
3131
3232 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
3333
3434
3535 func getIntOrElse (key,defaultVal) = valueOrElse(getInteger(this, key), defaultVal)
3636
3737
3838 let IdxCfgStakingDapp = 1
3939
4040 let IdxCfgEconomyDapp = 2
4141
4242 let IdxCfgGovernanceDapp = 3
4343
4444 func keyRestCfg () = "%s__restConfig"
4545
4646
4747 func keyRestAddress () = "%s__restAddr"
4848
4949
5050 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
5151
5252
5353 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
5454
5555
5656 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
5757
5858 let restCfg = readRestCfgOrFail(restContract)
5959
6060 let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
6161
6262 let DEFAULTLOCATION = "Africa_F_Africa"
6363
6464 let NUMRES = 6
6565
6666 let FACTORYMAXWAREHOUSE = 10000000000
6767
6868 let RESOURCEPRICEMIN = 158549
6969
7070 let MINPAYMENT = 10000
7171
7272 let SELLMULTIPLIER = 200
7373
7474 let BUYMULTIPLIER = 300
7575
7676 let LANDPREFIX = "LAND"
7777
7878 let DUCKPREFIX = "DUCK"
7979
8080 let WHMULTIPLIER = 10000000000
8181
82+let AUCTIONFEE = 10000
83+
8284 let resTypes = ["Oil", "Ore", "Wood", "Sand", "Clay", "Organic"]
8385
8486 let matTypes = ["Fuel", "Metal", "Plank", "Glass", "Plastic", "Protein"]
87+
88+let prodTypes = ["First Aid Kit", "Backpack", "Food Ration", "Jet Pack", "Radar"]
8589
8690 let continents = ["Americas", "Europe", "Asia", "Africa", "Oceania"]
8791
8892 let productionMatrix = ["1_1_1_2_2_5_1_10", "2_5_5_2_7_5_2_100", "1_1_1_2_2_5_1_10", "9_9_1_5_5_1_5_100", "1_5_1_5_5_1_1_100"]
8993
9094 let contIdxAmericas = 0
9195
9296 let contIdxEurope = 1
9397
9498 let contIdxAsia = 2
9599
96100 let contIdxAfrica = 3
97101
98102 let contIdxOceania = 4
99103
100104 func keyFactoryWarehouseByIdAndType (factoryId,resType) = ((("factoryWhByContinentAndRes_" + factoryId) + "_") + toString(resType))
101105
102106
103107 func keyOrderByLand (landAssetId) = ("landOrder_" + landAssetId)
104108
105109
106110 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
107111
108112
109113 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
110114
111115
112116 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
113117
114118
115119 func keyBlocked () = "contractsBlocked"
116120
117121
118122 func keyLandAssetIdToOwner (assetId) = ("nftOwner_" + assetId)
119123
120124
121125 func keyStakedTimeByAssetId (assetId) = ("stakedTime_" + assetId)
122126
123127
124128 let locIdxContinent = 0
125129
126130 let locIdxType = 1
127131
128132 let locIdxId = 2
129133
130134 let bpIdxLevel = 0
131135
132136 let bpIdxRes = 1
133137
134138 let bpIdxMat = 2
135139
136140 let bpIdxProd = 3
137141
138142 let whIdxVol = 0
139143
140144 let whIdxRes = 1
141145
142146 let whIdxMat = 2
143147
144148 let whIdxProd = 3
145149
146150 let whIdxLockedVol = 4
147151
148152 let ordIdxRes = 0
149153
150154 let ordIdxMat = 1
151155
152156 let ordIdxProd = 2
153157
154158 func asString (v) = match v {
155159 case s: String =>
156160 s
157161 case _ =>
158162 throw("fail to cast into String")
159163 }
160164
161165
162166 func getOrder (ordKey) = {
163167 let p = split(valueOrElse(getString(ordKey), "0@0_0@0_0@0_0@0_0@0_0@0:0@0_0@0_0@0_0@0_0@0_0@0:"), ":")
164168 [if ((size(split(p[ordIdxRes], "_")) == NUMRES))
165169 then p[ordIdxRes]
166170 else "0@0_0@0_0@0_0@0_0@0_0@0", if ((size(split(p[ordIdxMat], "_")) == NUMRES))
167171 then p[ordIdxMat]
168172 else "0@0_0@0_0@0_0@0_0@0_0@0", p[ordIdxProd]]
169173 }
170174
171175
172176 func getWarehouseVolume (volPrefix) = {
173177 let parts = split(volPrefix, "_")
174178 ((WHMULTIPLIER * (parseIntValue(parts[1]) + 1)) * parseIntValue(parts[0]))
175179 }
176180
177181
178182 func getWarehouseCurrResVolume (currentWh) = {
179183 func sum (acc,item) = (acc + parseIntValue(item))
180184
181185 let $l = split(currentWh[whIdxRes], "_")
182186 let $s = size($l)
183187 let $acc0 = 0
184188 func $f0_1 ($a,$i) = if (($i >= $s))
185189 then $a
186190 else sum($a, $l[$i])
187191
188192 func $f0_2 ($a,$i) = if (($i >= $s))
189193 then $a
190194 else throw("List size exceeds 6")
191195
192196 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
193197 }
194198
195199
196200 func getWarehouseCurrMatVolume (currentWh) = {
197201 func sum (acc,item) = (acc + parseIntValue(item))
198202
199203 let $l = split(currentWh[whIdxMat], "_")
200204 let $s = size($l)
201205 let $acc0 = 0
202206 func $f0_1 ($a,$i) = if (($i >= $s))
203207 then $a
204208 else sum($a, $l[$i])
205209
206210 func $f0_2 ($a,$i) = if (($i >= $s))
207211 then $a
208212 else throw("List size exceeds 6")
209213
210214 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
211215 }
212216
213217
214218 func getWarehouseCurrGoodsVolume (currentWh) = {
215219 let goods = currentWh[whIdxProd]
216220 if ((goods == ""))
217221 then 0
218222 else {
219223 func sum (acc,item) = (acc + parseIntValue(item))
220224
221225 let $l = split_4C(goods, "_")
222226 let $s = size($l)
223227 let $acc0 = 0
224228 func $f0_1 ($a,$i) = if (($i >= $s))
225229 then $a
226230 else sum($a, $l[$i])
227231
228232 func $f0_2 ($a,$i) = if (($i >= $s))
229233 then $a
230234 else throw("List size exceeds 50")
231235
232236 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
233237 }
234238 }
235239
236240
237241 func sellInternal (locId,resType,amount,minPrice) = {
238242 let whKey = keyFactoryWarehouseByIdAndType(locId, resType)
239243 let w0 = valueOrElse(getInteger(whKey), 0)
240244 let r0 = if ((w0 > FACTORYMAXWAREHOUSE))
241245 then 0
242246 else if (((w0 + amount) > FACTORYMAXWAREHOUSE))
243247 then (FACTORYMAXWAREHOUSE - w0)
244248 else amount
245249 let usdnReceived = (fraction(r0, ((SELLMULTIPLIER * RESOURCEPRICEMIN) - fraction(((100 * w0) + (50 * r0)), RESOURCEPRICEMIN, FACTORYMAXWAREHOUSE)), MULT10) + fraction((amount - r0), RESOURCEPRICEMIN, MULT8))
246250 let min99 = (minPrice - (minPrice / 100))
247251 if (((min99 * amount) > (usdnReceived * MULT8)))
248252 then throw((((((((((("Actual price = " + toString(usdnReceived)) + " / ") + toString(amount)) + " < minPrice = ") + toString(minPrice)) + ", (") + locId) + ", ") + resTypes[resType]) + ")"))
249253 else $Tuple2(IntegerEntry(whKey, (w0 + amount)), usdnReceived)
250254 }
251255
252256
253257 func buyInternal (locId,matType,amount,maxPrice) = {
254258 let whKey = keyFactoryWarehouseByIdAndType(locId, matType)
255259 let w0 = valueOrElse(getInteger(whKey), 0)
256260 let m1 = if ((w0 > FACTORYMAXWAREHOUSE))
257261 then min([amount, (w0 - FACTORYMAXWAREHOUSE)])
258262 else 0
259263 let m0 = min([w0, (amount - m1)])
260264 let m = (m0 + m1)
261265 let usdnSpent = (fraction(m0, ((BUYMULTIPLIER * RESOURCEPRICEMIN) - fraction(((100 * w0) - (50 * m0)), RESOURCEPRICEMIN, FACTORYMAXWAREHOUSE)), MULT10) + fraction(m1, (2 * RESOURCEPRICEMIN), MULT8))
262266 let max101 = (maxPrice + (maxPrice / 100))
263267 if (((usdnSpent * MULT8) > (max101 * m)))
264268 then throw((((((((((("Actual price = " + toString(usdnSpent)) + " / ") + toString(m)) + " > maxPrice = ") + toString(maxPrice)) + ", (") + locId) + ", ") + matTypes[matType]) + ")"))
265269 else $Tuple3(IntegerEntry(whKey, (w0 - m)), usdnSpent, m)
266270 }
267271
268272
269273 func getBackpack (bpKey) = {
270274 let p = split(valueOrElse(getString(stakingContract, bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
271275 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
272276 then p[bpIdxRes]
273277 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
274278 then p[bpIdxMat]
275279 else "0_0_0_0_0_0", p[bpIdxProd]]
276280 }
277281
278282
279283 func checkBlocked () = if (valueOrElse(getBoolean(stakingContract, keyBlocked()), false))
280284 then throw("Contracts are under maintenance")
281285 else unit
282286
283287
284288 @Callable(i)
285289 func constructorV1 (restAddr) = if ((i.caller != this))
286290 then throw("Permission denied")
287291 else [StringEntry(keyRestAddress(), restAddr)]
288292
289293
290294
291295 @Callable(i)
292296 func sellResources (amounts,minPrices) = {
293297 let blocked = checkBlocked()
294298 if ((blocked == blocked))
295299 then {
296300 let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
297301 if ((size(i.payments) != 0))
298302 then throw("sellResources doesn't require any payments")
299303 else {
300304 let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
301305 if ((curLocation[locIdxType] != "F"))
302306 then throw(("Duck location type should be Factory, but is " + curLocation[locIdxType]))
303307 else {
304308 let locId = curLocation[locIdxId]
305309 let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
306310 let resList = split(currentPack[bpIdxRes], "_")
307311 func adder (acc,j) = if ((amounts[j] > parseIntValue(resList[j])))
308312 then throw(((((("You have " + resList[j]) + " of ") + resTypes[j]) + ", but tried to sell ") + toString(amounts[j])))
309313 else if ((0 > amounts[j]))
310314 then throw(((("You tried to sell negative amount of " + resTypes[j]) + ": ") + toString(amounts[j])))
311315 else if ((amounts[j] > 0))
312316 then {
313317 let b = sellInternal(locId, j, amounts[j], minPrices[j])
314318 $Tuple3((acc._1 :+ b._1), (acc._2 :+ toString((parseIntValue(resList[j]) - amounts[j]))), (acc._3 + b._2))
315319 }
316320 else $Tuple3(acc._1, (acc._2 :+ resList[j]), acc._3)
317321
318322 let merged = {
319323 let $l = [0, 1, 2, 3, 4, 5]
320324 let $s = size($l)
321325 let $acc0 = $Tuple3(nil, nil, 0)
322326 func $f0_1 ($a,$i) = if (($i >= $s))
323327 then $a
324328 else adder($a, $l[$i])
325329
326330 func $f0_2 ($a,$i) = if (($i >= $s))
327331 then $a
328332 else throw("List size exceeds 6")
329333
330334 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
331335 }
332336 let newPack = makeString([currentPack[bpIdxLevel], makeString(merged._2, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":")
333337 let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
334338 $Tuple2((merged._1 :+ ScriptTransfer(i.caller, merged._3, usdnAssetId)), result)
335339 }
336340 }
337341 }
338342 else throw("Strict value is not equal to itself.")
339343 }
340344
341345
342346
343347 @Callable(i)
344348 func buyMaterials (amounts,maxPrices) = {
345349 let blocked = checkBlocked()
346350 if ((blocked == blocked))
347351 then {
348352 let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
349353 if ((size(i.payments) != 1))
350354 then throw("exactly 1 payment must be attached")
351355 else {
352356 let pmt = i.payments[0]
353357 let amt = pmt.amount
354358 let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
355359 if ((pmtAssetId != usdnAssetId))
356360 then throw("USDN payments only!")
357361 else {
358362 let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
359363 if ((curLocation[locIdxType] != "F"))
360364 then throw(("Duck location type should be Factory, but is " + curLocation[locIdxType]))
361365 else {
362366 let locId = curLocation[locIdxId]
363367 let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
364368 let matList = split(currentPack[bpIdxMat], "_")
365369 func mUpdater (acc,j) = if ((0 > amounts[j]))
366370 then throw(((("You tried to buy negative amount of " + matTypes[j]) + ": ") + toString(amounts[j])))
367371 else if ((amounts[j] > 0))
368372 then {
369373 let b = buyInternal(locId, j, amounts[j], maxPrices[j])
370374 $Tuple3((acc._1 :+ b._1), (acc._2 :+ toString((parseIntValue(matList[j]) + b._3))), (acc._3 + b._2))
371375 }
372376 else $Tuple3(acc._1, (acc._2 :+ matList[j]), acc._3)
373377
374378 let merged = {
375379 let $l = [0, 1, 2, 3, 4, 5]
376380 let $s = size($l)
377381 let $acc0 = $Tuple3(nil, nil, 0)
378382 func $f0_1 ($a,$i) = if (($i >= $s))
379383 then $a
380384 else mUpdater($a, $l[$i])
381385
382386 func $f0_2 ($a,$i) = if (($i >= $s))
383387 then $a
384388 else throw("List size exceeds 6")
385389
386390 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
387391 }
388392 if ((merged._3 > amt))
389393 then throw(((("Insufficient payment! Attached=" + toString(amt)) + ", required=") + toString(merged._3)))
390394 else {
391395 let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(merged._2, "_"), currentPack[bpIdxProd]], ":")
392396 let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
393397 let rest = if (((amt - merged._3) > 0))
394398 then [ScriptTransfer(i.caller, (amt - merged._3), usdnAssetId)]
395399 else nil
396400 $Tuple2((merged._1 ++ rest), result)
397401 }
398402 }
399403 }
400404 }
401405 }
402406 else throw("Strict value is not equal to itself.")
403407 }
404408
405409
406410
407411 @Callable(i)
408412 func exchangeResources (amounts) = {
409413 let blocked = checkBlocked()
410414 if ((blocked == blocked))
411415 then {
412416 let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
413417 if ((size(i.payments) != 1))
414418 then throw("exactly 1 payment must be attached")
415419 else {
416420 let pmt = i.payments[0]
417421 let amt = pmt.amount
418422 let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
419423 if ((pmtAssetId != usdnAssetId))
420424 then throw("USDN payments only!")
421425 else {
422426 let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
423427 if ((curLocation[locIdxType] != "F"))
424428 then throw(("Duck location type should be Factory, but is " + curLocation[locIdxType]))
425429 else {
426430 let locId = curLocation[locIdxId]
427431 let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
428432 let resList = split(currentPack[bpIdxRes], "_")
429433 let matList = split(currentPack[bpIdxMat], "_")
430434 func exchanger (acc,j) = {
431435 let whKey = keyFactoryWarehouseByIdAndType(locId, j)
432436 let w0 = valueOrElse(getInteger(whKey), 0)
433437 let amj = amounts[j]
434438 if ((amj > parseIntValue(resList[j])))
435439 then throw(((((("You have " + resList[j]) + " of ") + resTypes[j]) + ", but tried to exchange ") + toString(amj)))
436440 else if ((0 > amj))
437441 then throw(((("You tried to exchange negative amount of " + resTypes[j]) + ": ") + toString(amj)))
438442 else if ((amj > 0))
439443 then $Tuple4((acc._1 :+ toString((parseIntValue(resList[j]) - amj))), (acc._2 :+ toString((parseIntValue(matList[j]) + amj))), (acc._3 + fraction(amj, RESOURCEPRICEMIN, MULT8)), (acc._4 :+ IntegerEntry(whKey, w0)))
440444 else $Tuple4((acc._1 :+ resList[j]), (acc._2 :+ matList[j]), acc._3, acc._4)
441445 }
442446
443447 let merged = {
444448 let $l = [0, 1, 2, 3, 4, 5]
445449 let $s = size($l)
446450 let $acc0 = $Tuple4(nil, nil, 0, nil)
447451 func $f0_1 ($a,$i) = if (($i >= $s))
448452 then $a
449453 else exchanger($a, $l[$i])
450454
451455 func $f0_2 ($a,$i) = if (($i >= $s))
452456 then $a
453457 else throw("List size exceeds 6")
454458
455459 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
456460 }
457461 if ((merged._3 > amt))
458462 then throw(((("Insufficient payment! Attached=" + toString(amt)) + ", required=") + toString(merged._3)))
459463 else {
460464 let newPack = makeString([currentPack[bpIdxLevel], makeString(merged._1, "_"), makeString(merged._2, "_"), currentPack[bpIdxProd]], ":")
461465 let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
462466 let rest = if (((amt - merged._3) > 0))
463467 then [ScriptTransfer(i.caller, (amt - merged._3), usdnAssetId)]
464468 else nil
465469 $Tuple2((rest ++ merged._4), result)
466470 }
467471 }
468472 }
469473 }
470474 }
471475 else throw("Strict value is not equal to itself.")
472476 }
473477
474478
475479
476480 @Callable(i)
477481 func buyGoods (productIdx,level,quantity) = {
478482 let blocked = checkBlocked()
479483 if ((blocked == blocked))
480484 then if ((size(i.payments) != 0))
481485 then throw("buyGoods doesn't require any payments")
482486 else if ((0 > quantity))
483487 then throw("Quantity should be positive")
484488 else {
485489 let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
486490 let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
487491 if ((curLocation[locIdxType] != "M"))
488492 then throw(("Duck location type should be Manufactory, but is " + curLocation[locIdxType]))
489493 else {
490494 let cont = curLocation[locIdxContinent]
491495 let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
492496 let matList = split(currentPack[bpIdxMat], "_")
493497 if (if ((0 > productIdx))
494498 then true
495499 else (productIdx >= size(productionMatrix)))
496500 then throw(("Unknown product idx=" + toString(productIdx)))
497501 else {
498502 let productContIdx = (productIdx % size(continents))
499503 if ((continents[productContIdx] != cont))
500504 then throw(((("This product is available in " + continents[productContIdx]) + ", but you are in ") + cont))
501505 else {
502506 let recipe = split(productionMatrix[productIdx], "_")
503507 if ((size(recipe) != (NUMRES + 2)))
504508 then throw(("Fatal: unknown recipe: " + productionMatrix[productIdx]))
505509 else {
506510 let prodList = if ((currentPack[bpIdxProd] == ""))
507511 then nil
508512 else split(currentPack[bpIdxProd], "_")
509513 func filler (acc,ignoredItem) = {
510514 let n = acc._2
511515 let x = if ((size(prodList) > n))
512516 then split(prodList[n], ",")
513517 else ["0", "0", "0"]
514518 let x1s = x[0]
515519 let x1 = parseIntValue(x1s)
516520 let x2s = x[1]
517521 let x2 = parseIntValue(x2s)
518522 let x3s = x[2]
519523 let x3 = parseIntValue(x3s)
520524 let amount = (quantity * parseIntValue(recipe[7]))
521525 let y = if ((n == productIdx))
522526 then match level {
523527 case _ =>
524528 if ((1 == $match0))
525529 then ((((toString((x1 + amount)) + ",") + x2s) + ",") + x3s)
526530 else if ((2 == $match0))
527531 then ((((x1s + ",") + toString((x2 + amount))) + ",") + x3s)
528532 else if ((3 == $match0))
529533 then ((((x1s + ",") + x2s) + ",") + toString((x3 + amount)))
530534 else throw(("Product level should be 1..3, not " + toString(level)))
531535 }
532536 else ((((x1s + ",") + x2s) + ",") + x3s)
533537 $Tuple2((acc._1 :+ y), (n + 1))
534538 }
535539
536540 let bpProd = ( let $l = productionMatrix
537541 let $s = size($l)
538542 let $acc0 = $Tuple2(nil, 0)
539543 func $f0_1 ($a,$i) = if (($i >= $s))
540544 then $a
541545 else filler($a, $l[$i])
542546
543547 func $f0_2 ($a,$i) = if (($i >= $s))
544548 then $a
545549 else throw("List size exceeds 50")
546550
547551 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50))._1
548552 func producer (acc,j) = {
549553 let needMat = (parseIntValue(recipe[j]) * quantity)
550554 let haveMat = parseIntValue(matList[j])
551555 if ((needMat > haveMat))
552556 then throw(((((((("You have " + matList[j]) + " of ") + matTypes[j]) + ", but recipe requires ") + toString(needMat)) + " for quantity ") + toString(quantity)))
553557 else if ((needMat > 0))
554558 then (acc :+ toString((haveMat - needMat)))
555559 else (acc :+ matList[j])
556560 }
557561
558562 let merged = {
559563 let $l = [0, 1, 2, 3, 4, 5]
560564 let $s = size($l)
561565 let $acc0 = nil
562566 func $f1_1 ($a,$i) = if (($i >= $s))
563567 then $a
564568 else producer($a, $l[$i])
565569
566570 func $f1_2 ($a,$i) = if (($i >= $s))
567571 then $a
568572 else throw("List size exceeds 6")
569573
570574 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
571575 }
572576 let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(merged, "_"), makeString(bpProd, "_")], ":")
573577 let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
574578 $Tuple2(nil, result)
575579 }
576580 }
577581 }
578582 }
579583 }
580584 else throw("Strict value is not equal to itself.")
581585 }
582586
583587
584588
585589 @Callable(i)
586590 func acceptServicePayment (service) = {
587591 let blocked = checkBlocked()
588592 if ((blocked == blocked))
589593 then if ((size(i.payments) != 1))
590594 then throw("exactly 1 payment must be attached")
591595 else {
592596 let pmt = i.payments[0]
593597 let amt = pmt.amount
594598 let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
595599 if ((pmtAssetId != usdnAssetId))
596600 then throw("USDN payments only!")
597601 else {
598602 let need = match service {
599603 case _ =>
600604 if (("LAND_RENAME" == $match0))
601605 then 10000000
602606 else throw("Unknown service!")
603607 }
604608 if ((amt != need))
605609 then throw((((service + " costs ") + toString(need)) + " USDN"))
606610 else $Tuple2(nil, amt)
607611 }
608612 }
609613 else throw("Strict value is not equal to itself.")
610614 }
611615
612616
613617
614618 @Callable(i)
615619 func setWarehouseOrder (cargoListStr,landAssetId) = {
616620 let user = i.originCaller
617621 let addr = toString(user)
618622 let asset = value(assetInfo(fromBase58String(landAssetId)))
619623 if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId)))))
620624 then throw((("NFT " + asset.name) + " is not staked"))
621625 else {
622626 let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
623627 if ((owner != addr))
624628 then throw((LANDPREFIX + " is not yours"))
625629 else {
626630 let cargoParts = split_4C(cargoListStr, ":")
627631 if ((size(cargoParts) != 3))
628632 then throw("cargoListStr should contain exactly 2 ':' separators")
629633 else {
630634 let resParts = split(cargoParts[0], "_")
631635 let matParts = split(cargoParts[1], "_")
632636 let prodParts = if ((cargoParts[2] == ""))
633637 then nil
634638 else split(cargoParts[2], "_")
635639 if ((size(resParts) != NUMRES))
636640 then throw("All 6 resources should be passed")
637641 else if ((size(matParts) != NUMRES))
638642 then throw("All 6 materials should be passed")
639643 else {
640644 let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil))
641645 let currentWh = split_4C(wh, ":")
642646 let currWhRes = split(currentWh[whIdxRes], "_")
643647 let currWhMat = split(currentWh[whIdxMat], "_")
644648 let currWhProd = if ((currentWh[whIdxProd] == ""))
645649 then nil
646650 else split(currentWh[whIdxProd], "_")
647651 let currWhResVol = getWarehouseCurrResVolume(currentWh)
648652 let currWhMatVol = getWarehouseCurrMatVolume(currentWh)
649653 let currWhGoodsVol = getWarehouseCurrGoodsVolume(currentWh)
650654 let currWhLockedVol = parseIntValue(currentWh[whIdxLockedVol])
651655 let whSpaceLeft = ((((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol) - currWhLockedVol)
652656 let ordKey = keyOrderByLand(landAssetId)
653657 let currentOrd = getOrder(ordKey)
654658 let currentOrdRes = split(currentOrd[ordIdxRes], "_")
655659 let currentOrdMat = split(currentOrd[ordIdxMat], "_")
656660 let currentOrdProd = if ((currentOrd[ordIdxProd] == ""))
657661 then nil
658662 else split(currentOrd[ordIdxProd], "_")
659663 let usdnNeed2Lock = 0
660664 func ordR (acc,item) = {
661665 let j = acc._1
662666 let itemParts = split(item, "@")
663667 if ((size(itemParts) != 2))
664668 then throw("Incorrect order format, should be amount@price")
665669 else {
666670 let newOrdAm = parseIntValue(itemParts[0])
667671 let newOrdPr = parseIntValue(itemParts[1])
668672 let newOrdUsd = fraction(newOrdAm, newOrdPr, MULT8)
669673 let whr = parseIntValue(currWhRes[j])
670674 let curOrdParts = split(currentOrdRes[j], "@")
671675 let curOrdAm = parseIntValue(curOrdParts[0])
672676 let curOrdPr = parseIntValue(curOrdParts[1])
673- let curOrdUsd = fraction(curOrdAm, curOrdPr, MULT8)
674- if ((newOrdAm == 0))
675- then if ((curOrdAm > 0))
676- then $Tuple4((j + 1), (acc._2 :+ toString(whr)), (acc._3 - curOrdAm), (acc._4 - curOrdUsd))
677- else $Tuple4((j + 1), (acc._2 :+ toString((whr - curOrdAm))), (acc._3 + curOrdAm), acc._4)
678- else if ((newOrdAm > 0))
679- then if ((0 > curOrdAm))
680- then {
681- let amDiff = (newOrdAm + curOrdAm)
682- $Tuple4((j + 1), (acc._2 :+ toString((whr - curOrdAm))), (acc._3 + amDiff), (acc._4 + newOrdUsd))
683- }
684- else $Tuple4((j + 1), (acc._2 :+ toString(whr)), ((acc._3 + newOrdAm) - curOrdAm), ((acc._4 + newOrdUsd) - curOrdUsd))
685- else if ((0 > curOrdAm))
686- then {
687- let amDiff = (curOrdAm - newOrdAm)
688- if ((0 > (whr - amDiff)))
689- then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whr)) + " available"))
690- else $Tuple4((j + 1), (acc._2 :+ toString((whr - amDiff))), (acc._3 + amDiff), acc._4)
691- }
692- else if ((0 > (whr + newOrdAm)))
693- then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whr)) + " available"))
694- else $Tuple4((j + 1), (acc._2 :+ toString((whr + newOrdAm))), ((acc._3 - newOrdAm) - curOrdAm), (acc._4 - curOrdUsd))
677+ if ((0 > curOrdPr))
678+ then throw("Price can't be negative")
679+ else {
680+ let curOrdUsd = fraction(curOrdAm, curOrdPr, MULT8)
681+ if ((newOrdAm == 0))
682+ then if ((curOrdAm > 0))
683+ then $Tuple4((j + 1), (acc._2 :+ toString(whr)), (acc._3 - curOrdAm), (acc._4 - curOrdUsd))
684+ else $Tuple4((j + 1), (acc._2 :+ toString((whr - curOrdAm))), (acc._3 + curOrdAm), acc._4)
685+ else if ((newOrdAm > 0))
686+ then if ((0 > curOrdAm))
687+ then {
688+ let amDiff = (newOrdAm + curOrdAm)
689+ $Tuple4((j + 1), (acc._2 :+ toString((whr - curOrdAm))), (acc._3 + amDiff), (acc._4 + newOrdUsd))
690+ }
691+ else $Tuple4((j + 1), (acc._2 :+ toString(whr)), ((acc._3 + newOrdAm) - curOrdAm), ((acc._4 + newOrdUsd) - curOrdUsd))
692+ else if ((0 > curOrdAm))
693+ then {
694+ let amDiff = (curOrdAm - newOrdAm)
695+ if ((0 > (whr - amDiff)))
696+ then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whr)) + " available"))
697+ else $Tuple4((j + 1), (acc._2 :+ toString((whr - amDiff))), (acc._3 + amDiff), acc._4)
698+ }
699+ else if ((0 > (whr + newOrdAm)))
700+ then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whr)) + " available"))
701+ else $Tuple4((j + 1), (acc._2 :+ toString((whr + newOrdAm))), ((acc._3 - newOrdAm) - curOrdAm), (acc._4 - curOrdUsd))
702+ }
695703 }
696704 }
697705
698706 let r = {
699707 let $l = resParts
700708 let $s = size($l)
701709 let $acc0 = $Tuple4(0, nil, 0, 0)
702710 func $f0_1 ($a,$i) = if (($i >= $s))
703711 then $a
704712 else ordR($a, $l[$i])
705713
706714 func $f0_2 ($a,$i) = if (($i >= $s))
707715 then $a
708716 else throw("List size exceeds 6")
709717
710718 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
711719 }
712720 func ordM (acc,item) = {
713721 let j = acc._1
714722 let itemParts = split(item, "@")
715723 if ((size(itemParts) != 2))
716724 then throw("Incorrect order format, should be amount@price")
717725 else {
718726 let newOrdAm = parseIntValue(itemParts[0])
719727 let newOrdPr = parseIntValue(itemParts[1])
720728 let newOrdUsd = fraction(newOrdAm, newOrdPr, MULT8)
721729 let whm = parseIntValue(currWhMat[j])
722730 let curOrdParts = split(currentOrdMat[j], "@")
723731 let curOrdAm = parseIntValue(curOrdParts[0])
724732 let curOrdPr = parseIntValue(curOrdParts[1])
725- let curOrdUsd = fraction(curOrdAm, curOrdPr, MULT8)
726- if ((newOrdAm == 0))
727- then if ((curOrdAm > 0))
728- then $Tuple4((j + 1), (acc._2 :+ toString(whm)), (acc._3 - curOrdAm), (acc._4 - curOrdUsd))
729- else $Tuple4((j + 1), (acc._2 :+ toString((whm - curOrdAm))), (acc._3 + curOrdAm), acc._4)
730- else if ((newOrdAm > 0))
731- then if ((0 > curOrdAm))
732- then {
733- let amDiff = (newOrdAm + curOrdAm)
734- $Tuple4((j + 1), (acc._2 :+ toString((whm - curOrdAm))), (acc._3 + amDiff), (acc._4 + newOrdUsd))
735- }
736- else $Tuple4((j + 1), (acc._2 :+ toString(whm)), ((acc._3 + newOrdAm) - curOrdAm), ((acc._4 + newOrdUsd) - curOrdUsd))
737- else if ((0 > curOrdAm))
738- then {
739- let amDiff = (curOrdAm - newOrdAm)
740- if ((0 > (whm - amDiff)))
741- then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whm)) + " available"))
742- else $Tuple4((j + 1), (acc._2 :+ toString((whm - amDiff))), (acc._3 + amDiff), acc._4)
743- }
744- else if ((0 > (whm + newOrdAm)))
745- then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whm)) + " available"))
746- else $Tuple4((j + 1), (acc._2 :+ toString((whm + newOrdAm))), ((acc._3 - newOrdAm) - curOrdAm), (acc._4 - curOrdUsd))
733+ if ((0 > curOrdPr))
734+ then throw("Price can't be negative")
735+ else {
736+ let curOrdUsd = fraction(curOrdAm, curOrdPr, MULT8)
737+ if ((newOrdAm == 0))
738+ then if ((curOrdAm > 0))
739+ then $Tuple4((j + 1), (acc._2 :+ toString(whm)), (acc._3 - curOrdAm), (acc._4 - curOrdUsd))
740+ else $Tuple4((j + 1), (acc._2 :+ toString((whm - curOrdAm))), (acc._3 + curOrdAm), acc._4)
741+ else if ((newOrdAm > 0))
742+ then if ((0 > curOrdAm))
743+ then {
744+ let amDiff = (newOrdAm + curOrdAm)
745+ $Tuple4((j + 1), (acc._2 :+ toString((whm - curOrdAm))), (acc._3 + amDiff), (acc._4 + newOrdUsd))
746+ }
747+ else $Tuple4((j + 1), (acc._2 :+ toString(whm)), ((acc._3 + newOrdAm) - curOrdAm), ((acc._4 + newOrdUsd) - curOrdUsd))
748+ else if ((0 > curOrdAm))
749+ then {
750+ let amDiff = (curOrdAm - newOrdAm)
751+ if ((0 > (whm - amDiff)))
752+ then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whm)) + " available"))
753+ else $Tuple4((j + 1), (acc._2 :+ toString((whm - amDiff))), (acc._3 + amDiff), acc._4)
754+ }
755+ else if ((0 > (whm + newOrdAm)))
756+ then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whm)) + " available"))
757+ else $Tuple4((j + 1), (acc._2 :+ toString((whm + newOrdAm))), ((acc._3 - newOrdAm) - curOrdAm), (acc._4 - curOrdUsd))
758+ }
747759 }
748760 }
749761
750762 let m = {
751763 let $l = matParts
752764 let $s = size($l)
753765 let $acc0 = $Tuple4(0, nil, r._3, r._4)
754766 func $f1_1 ($a,$i) = if (($i >= $s))
755767 then $a
756768 else ordM($a, $l[$i])
757769
758770 func $f1_2 ($a,$i) = if (($i >= $s))
759771 then $a
760772 else throw("List size exceeds 6")
761773
762774 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
763775 }
764776 func ordP (acc,item) = {
765777 let j = acc._1
766778 let itemParts = split(item, "@")
767779 if ((size(itemParts) != 2))
768780 then throw("Incorrect order format, should be amount@price")
769781 else {
770782 let newOrdAm = parseIntValue(itemParts[0])
771783 let newOrdPr = parseIntValue(itemParts[1])
772784 let newOrdUsd = fraction(newOrdAm, newOrdPr, MULT8)
773785 let whp = parseIntValue(currWhProd[j])
774786 let curOrdParts = split(currentOrdProd[j], "@")
775787 let curOrdAm = parseIntValue(curOrdParts[0])
776788 let curOrdPr = parseIntValue(curOrdParts[1])
777- let curOrdUsd = fraction(curOrdAm, curOrdPr, MULT8)
778- if ((newOrdAm == 0))
779- then if ((curOrdAm > 0))
780- then $Tuple4((j + 1), (acc._2 :+ toString(whp)), (acc._3 - curOrdAm), (acc._4 - curOrdUsd))
781- else $Tuple4((j + 1), (acc._2 :+ toString((whp - curOrdAm))), (acc._3 + curOrdAm), acc._4)
782- else if ((newOrdAm > 0))
783- then if ((0 > curOrdAm))
784- then {
785- let amDiff = (newOrdAm + curOrdAm)
786- $Tuple4((j + 1), (acc._2 :+ toString((whp - curOrdAm))), (acc._3 + amDiff), (acc._4 + newOrdUsd))
787- }
788- else $Tuple4((j + 1), (acc._2 :+ toString(whp)), ((acc._3 + newOrdAm) - curOrdAm), ((acc._4 + newOrdUsd) - curOrdUsd))
789- else if ((0 > curOrdAm))
790- then {
791- let amDiff = (curOrdAm - newOrdAm)
792- if ((0 > (whp - amDiff)))
793- then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whp)) + " available"))
794- else $Tuple4((j + 1), (acc._2 :+ toString((whp - amDiff))), (acc._3 + amDiff), acc._3)
795- }
796- else if ((0 > (whp + newOrdAm)))
797- then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whp)) + " available"))
798- else $Tuple4((j + 1), (acc._2 :+ toString((whp + newOrdAm))), ((acc._3 - newOrdAm) - curOrdAm), (acc._4 - curOrdUsd))
789+ if ((0 > curOrdPr))
790+ then throw("Price can't be negative")
791+ else {
792+ let curOrdUsd = fraction(curOrdAm, curOrdPr, MULT8)
793+ if ((newOrdAm == 0))
794+ then if ((curOrdAm > 0))
795+ then $Tuple4((j + 1), (acc._2 :+ toString(whp)), (acc._3 - curOrdAm), (acc._4 - curOrdUsd))
796+ else $Tuple4((j + 1), (acc._2 :+ toString((whp - curOrdAm))), (acc._3 + curOrdAm), acc._4)
797+ else if ((newOrdAm > 0))
798+ then if ((0 > curOrdAm))
799+ then {
800+ let amDiff = (newOrdAm + curOrdAm)
801+ $Tuple4((j + 1), (acc._2 :+ toString((whp - curOrdAm))), (acc._3 + amDiff), (acc._4 + newOrdUsd))
802+ }
803+ else $Tuple4((j + 1), (acc._2 :+ toString(whp)), ((acc._3 + newOrdAm) - curOrdAm), ((acc._4 + newOrdUsd) - curOrdUsd))
804+ else if ((0 > curOrdAm))
805+ then {
806+ let amDiff = (curOrdAm - newOrdAm)
807+ if ((0 > (whp - amDiff)))
808+ then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whp)) + " available"))
809+ else $Tuple4((j + 1), (acc._2 :+ toString((whp - amDiff))), (acc._3 + amDiff), acc._3)
810+ }
811+ else if ((0 > (whp + newOrdAm)))
812+ then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whp)) + " available"))
813+ else $Tuple4((j + 1), (acc._2 :+ toString((whp + newOrdAm))), ((acc._3 - newOrdAm) - curOrdAm), (acc._4 - curOrdUsd))
814+ }
799815 }
800816 }
801817
802818 let p = {
803819 let $l = prodParts
804820 let $s = size($l)
805821 let $acc0 = $Tuple4(0, nil, m._3, m._4)
806822 func $f2_1 ($a,$i) = if (($i >= $s))
807823 then $a
808824 else ordP($a, $l[$i])
809825
810826 func $f2_2 ($a,$i) = if (($i >= $s))
811827 then $a
812828 else throw("List size exceeds 50")
813829
814830 $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
815831 }
816832 let volSaldo = p._3
817833 if ((volSaldo > whSpaceLeft))
818834 then throw((((("Attempt to reserve " + toString(volSaldo)) + " space, but only ") + toString(whSpaceLeft)) + " warehouse space left"))
819835 else {
820836 let whStr = makeString_2C([currentWh[whIdxVol], makeString(r._2, "_"), makeString(m._2, "_"), makeString(p._2, "_"), toString(volSaldo)], ":")
821837 let whSave = invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)
822838 if ((whSave == whSave))
823839 then {
824- let usdSaldo = p._4
840+ let usdSaldo = fraction(p._4, (MULT6 + AUCTIONFEE), MULT6)
825841 if ((usdSaldo > 0))
826842 then if ((size(i.payments) != 1))
827843 then throw("exactly 1 payment must be attached")
828844 else {
829845 let pmt = i.payments[0]
830846 let amt = pmt.amount
831847 let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
832848 if ((pmtAssetId != usdnAssetId))
833849 then throw("USDN payments only!")
834850 else if ((amt != usdSaldo))
835851 then throw(("Payment needed is " + toString(usdSaldo)))
836852 else [StringEntry(ordKey, cargoListStr)]
837853 }
838854 else if ((usdSaldo == 0))
839855 then if ((size(i.payments) != 0))
840856 then throw("No payments needed")
841857 else [StringEntry(ordKey, cargoListStr)]
842858 else if ((size(i.payments) != 0))
843859 then throw("No payments needed")
844860 else [ScriptTransfer(user, -(usdSaldo), usdnAssetId), StringEntry(ordKey, cargoListStr)]
845861 }
846862 else throw("Strict value is not equal to itself.")
847863 }
848864 }
849865 }
850866 }
851867 }
852868 }
853869
854870
871+
872+@Callable(i)
873+func acceptWarehouseOrder (bpOrderStr,landAssetId,duckAssetId) = {
874+ let caller = i.originCaller
875+ let callerAddr = toString(caller)
876+ let stakedDuckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(callerAddr)), "You don't have a duck staked")
877+ let curLocation = valueOrElse(getString(stakingContract, keyDuckLocation(stakedDuckAssetId)), DEFAULTLOCATION)
878+ let loc = split(value(curLocation), "_")
879+ if ((loc[locIdxType] != "L"))
880+ then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
881+ else if ((stakedDuckAssetId != duckAssetId))
882+ then throw(((("Your staked duck is " + stakedDuckAssetId) + ", but passed ") + duckAssetId))
883+ else {
884+ let landAsset = value(assetInfo(fromBase58String(landAssetId)))
885+ if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId)))))
886+ then throw((("NFT " + landAsset.name) + " is not staked"))
887+ else {
888+ let landOwner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + landAsset.name) + " is orphaned"))
889+ if ((landOwner == callerAddr))
890+ then throw("You cannot trade with yourself")
891+ else {
892+ let bpOrderParts = split_4C(bpOrderStr, ":")
893+ if ((size(bpOrderParts) != 3))
894+ then throw("bpOrderStr should contain exactly 2 ':' separators")
895+ else {
896+ let bpOrdRes = split(bpOrderParts[0], "_")
897+ let bpOrdMat = split(bpOrderParts[1], "_")
898+ let bpOrdProd = if ((bpOrderParts[2] == ""))
899+ then nil
900+ else split(bpOrderParts[2], "_")
901+ if ((size(bpOrdRes) != NUMRES))
902+ then throw("All 6 resources should be passed")
903+ else if ((size(bpOrdMat) != NUMRES))
904+ then throw("All 6 materials should be passed")
905+ else {
906+ let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil))
907+ let currentWh = split_4C(wh, ":")
908+ let currWhRes = split(currentWh[whIdxRes], "_")
909+ let currWhMat = split(currentWh[whIdxMat], "_")
910+ let currWhProd = if ((currentWh[whIdxProd] == ""))
911+ then nil
912+ else split(currentWh[whIdxProd], "_")
913+ let currWhResVol = getWarehouseCurrResVolume(currentWh)
914+ let currWhMatVol = getWarehouseCurrMatVolume(currentWh)
915+ let currWhGoodsVol = getWarehouseCurrGoodsVolume(currentWh)
916+ let currWhLockedVol = parseIntValue(currentWh[whIdxLockedVol])
917+ let whSpaceLeft = ((((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol) - currWhLockedVol)
918+ let bpKey = keyBackpackByDuck(duckAssetId)
919+ let currentPack = getBackpack(bpKey)
920+ let bpResList = split(currentPack[bpIdxRes], "_")
921+ let bpMatList = split(currentPack[bpIdxMat], "_")
922+ let bpProdList = if ((currentPack[bpIdxProd] == ""))
923+ then nil
924+ else split(currentPack[bpIdxProd], "_")
925+ let ordKey = keyOrderByLand(landAssetId)
926+ let whOrd = getOrder(ordKey)
927+ let whOrdRes = split(whOrd[ordIdxRes], "_")
928+ let whOrdMat = split(whOrd[ordIdxMat], "_")
929+ let whOrdProd = if ((whOrd[ordIdxProd] == ""))
930+ then nil
931+ else split(whOrd[ordIdxProd], "_")
932+ let usdnNeed2Lock = 0
933+ func ordR (acc,j) = {
934+ let bpOrdResParts = split(bpOrdRes[j], "@")
935+ if ((size(bpOrdResParts) != 2))
936+ then throw("Incorrect order format, should be amount@price")
937+ else {
938+ let bpOrdAm = parseIntValue(bpOrdResParts[0])
939+ let bpOrdPr = parseIntValue(bpOrdResParts[1])
940+ if ((0 > bpOrdPr))
941+ then throw("Price can't be negative")
942+ else {
943+ let bpOrdUsd = fraction(bpOrdAm, bpOrdPr, MULT8)
944+ let bpr = parseIntValue(bpResList[j])
945+ let whr = parseIntValue(currWhRes[j])
946+ let whOrdParts = split(whOrdRes[j], "@")
947+ let whOrdAm = parseIntValue(whOrdParts[0])
948+ let whOrdPr = parseIntValue(whOrdParts[1])
949+ if ((bpOrdPr != whOrdPr))
950+ then throw((("Prices of " + resTypes[j]) + " don't match"))
951+ else {
952+ let whOrdUsd = fraction(whOrdAm, whOrdPr, MULT8)
953+ if ((bpOrdAm == 0))
954+ then $Tuple6((acc._1 :+ currWhRes[j]), (acc._2 :+ whOrdRes[j]), (acc._3 :+ bpResList[j]), acc._4, acc._5, acc._6)
955+ else if ((bpOrdAm > 0))
956+ then if ((0 > whOrdAm))
957+ then if ((bpOrdAm > -(whOrdAm)))
958+ then throw(((((("Attempt to buy " + toString(bpOrdAm)) + " of ") + resTypes[j]) + ", but warehouse only sells ") + toString(-(whOrdAm))))
959+ else $Tuple6((acc._1 :+ currWhRes[j]), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ toString((bpr + bpOrdAm))), (acc._4 + bpOrdAm), acc._5, (acc._6 + bpOrdUsd))
960+ else throw((("Attempt to buy " + resTypes[j]) + " while warehouse doesn't sell it"))
961+ else if ((whOrdAm > 0))
962+ then if ((-(bpOrdAm) > whOrdAm))
963+ then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + " of ") + resTypes[j]) + ", but warehouse only buys ") + toString(whOrdAm)))
964+ else if ((-(bpOrdAm) > bpr))
965+ then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + ", but you only have ") + bpResList[j]) + " of ") + resTypes[j]))
966+ else $Tuple6((acc._1 :+ toString((whr - bpOrdAm))), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ "0"), (acc._4 - bpOrdAm), (acc._5 - bpOrdUsd), acc._6)
967+ else throw((("Attempt to sell " + resTypes[j]) + " while warehouse doesn't buy it"))
968+ }
969+ }
970+ }
971+ }
972+
973+ let r = {
974+ let $l = [0, 1, 2, 3, 4, 5]
975+ let $s = size($l)
976+ let $acc0 = $Tuple6(nil, nil, nil, 0, 0, 0)
977+ func $f0_1 ($a,$i) = if (($i >= $s))
978+ then $a
979+ else ordR($a, $l[$i])
980+
981+ func $f0_2 ($a,$i) = if (($i >= $s))
982+ then $a
983+ else throw("List size exceeds 6")
984+
985+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
986+ }
987+ func ordM (acc,j) = {
988+ let bpOrdMatParts = split(bpOrdMat[j], "@")
989+ if ((size(bpOrdMatParts) != 2))
990+ then throw("Incorrect order format, should be amount@price")
991+ else {
992+ let bpOrdAm = parseIntValue(bpOrdMatParts[0])
993+ let bpOrdPr = parseIntValue(bpOrdMatParts[1])
994+ if ((0 > bpOrdPr))
995+ then throw("Price can't be negative")
996+ else {
997+ let bpOrdUsd = fraction(bpOrdAm, bpOrdPr, MULT8)
998+ let bpr = parseIntValue(bpMatList[j])
999+ let whr = parseIntValue(currWhMat[j])
1000+ let whOrdParts = split(whOrdMat[j], "@")
1001+ let whOrdAm = parseIntValue(whOrdParts[0])
1002+ let whOrdPr = parseIntValue(whOrdParts[1])
1003+ if ((bpOrdPr != whOrdPr))
1004+ then throw((("Prices of " + matTypes[j]) + " don't match"))
1005+ else {
1006+ let whOrdUsd = fraction(whOrdAm, whOrdPr, MULT8)
1007+ if ((bpOrdAm == 0))
1008+ then $Tuple6((acc._1 :+ currWhMat[j]), (acc._2 :+ whOrdMat[j]), (acc._3 :+ bpMatList[j]), acc._4, acc._5, acc._6)
1009+ else if ((bpOrdAm > 0))
1010+ then if ((0 > whOrdAm))
1011+ then if ((bpOrdAm > -(whOrdAm)))
1012+ then throw(((((("Attempt to buy " + toString(bpOrdAm)) + " of ") + matTypes[j]) + ", but warehouse only sells ") + toString(-(whOrdAm))))
1013+ else $Tuple6((acc._1 :+ currWhMat[j]), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ toString((bpr + bpOrdAm))), (acc._4 + bpOrdAm), acc._5, (acc._6 + bpOrdUsd))
1014+ else throw((("Attempt to buy " + matTypes[j]) + " while warehouse doesn't sell it"))
1015+ else if ((whOrdAm > 0))
1016+ then if ((-(bpOrdAm) > whOrdAm))
1017+ then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + " of ") + matTypes[j]) + ", but warehouse only buys ") + toString(whOrdAm)))
1018+ else if ((-(bpOrdAm) > bpr))
1019+ then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + ", but you only have ") + bpMatList[j]) + " of ") + matTypes[j]))
1020+ else $Tuple6((acc._1 :+ toString((whr - bpOrdAm))), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ "0"), (acc._4 - bpOrdAm), (acc._5 - bpOrdUsd), acc._6)
1021+ else throw((("Attempt to sell " + matTypes[j]) + " while warehouse doesn't buy it"))
1022+ }
1023+ }
1024+ }
1025+ }
1026+
1027+ let m = {
1028+ let $l = [0, 1, 2, 3, 4, 5]
1029+ let $s = size($l)
1030+ let $acc0 = $Tuple6(nil, nil, nil, r._4, r._5, r._6)
1031+ func $f1_1 ($a,$i) = if (($i >= $s))
1032+ then $a
1033+ else ordM($a, $l[$i])
1034+
1035+ func $f1_2 ($a,$i) = if (($i >= $s))
1036+ then $a
1037+ else throw("List size exceeds 6")
1038+
1039+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1040+ }
1041+ func ordP (acc,j) = {
1042+ let bpOrdProdParts = split(bpOrdProd[j], "@")
1043+ if ((size(bpOrdProdParts) != 2))
1044+ then throw("Incorrect order format, should be amount@price")
1045+ else {
1046+ let bpOrdAm = parseIntValue(bpOrdProdParts[0])
1047+ let bpOrdPr = parseIntValue(bpOrdProdParts[1])
1048+ if ((0 > bpOrdPr))
1049+ then throw("Price can't be negative")
1050+ else {
1051+ let bpOrdUsd = fraction(bpOrdAm, bpOrdPr, MULT8)
1052+ let bpr = parseIntValue(bpProdList[j])
1053+ let whr = parseIntValue(currWhProd[j])
1054+ let whOrdParts = split(whOrdProd[j], "@")
1055+ let whOrdAm = parseIntValue(whOrdParts[0])
1056+ let whOrdPr = parseIntValue(whOrdParts[1])
1057+ if ((bpOrdPr != whOrdPr))
1058+ then throw((("Prices of " + prodTypes[j]) + " don't match"))
1059+ else {
1060+ let whOrdUsd = fraction(whOrdAm, whOrdPr, MULT8)
1061+ if ((bpOrdAm == 0))
1062+ then $Tuple6((acc._1 :+ currWhProd[j]), (acc._2 :+ whOrdProd[j]), (acc._3 :+ bpProdList[j]), acc._4, acc._5, acc._6)
1063+ else if ((bpOrdAm > 0))
1064+ then if ((0 > whOrdAm))
1065+ then if ((bpOrdAm > -(whOrdAm)))
1066+ then throw(((((("Attempt to buy " + toString(bpOrdAm)) + " of ") + prodTypes[j]) + ", but warehouse only sells ") + toString(-(whOrdAm))))
1067+ else $Tuple6((acc._1 :+ currWhProd[j]), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ toString((bpr + bpOrdAm))), (acc._4 + bpOrdAm), acc._5, (acc._6 + bpOrdUsd))
1068+ else throw((("Attempt to buy " + prodTypes[j]) + " while warehouse doesn't sell it"))
1069+ else if ((whOrdAm > 0))
1070+ then if ((-(bpOrdAm) > whOrdAm))
1071+ then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + " of ") + prodTypes[j]) + ", but warehouse only buys ") + toString(whOrdAm)))
1072+ else if ((-(bpOrdAm) > bpr))
1073+ then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + ", but you only have ") + bpProdList[j]) + " of ") + prodTypes[j]))
1074+ else $Tuple6((acc._1 :+ toString((whr - bpOrdAm))), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ "0"), (acc._4 - bpOrdAm), (acc._5 - bpOrdUsd), acc._6)
1075+ else throw((("Attempt to sell " + prodTypes[j]) + " while warehouse doesn't buy it"))
1076+ }
1077+ }
1078+ }
1079+ }
1080+
1081+ let p = {
1082+ let $l = [0, 1, 2, 3, 4, 5]
1083+ let $s = size($l)
1084+ let $acc0 = $Tuple6(nil, nil, nil, m._4, m._5, m._6)
1085+ func $f2_1 ($a,$i) = if (($i >= $s))
1086+ then $a
1087+ else ordP($a, $l[$i])
1088+
1089+ func $f2_2 ($a,$i) = if (($i >= $s))
1090+ then $a
1091+ else throw("List size exceeds 50")
1092+
1093+ $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
1094+ }
1095+ let volSaldo = p._4
1096+ let whStr = makeString_2C([currentWh[whIdxVol], makeString(r._1, "_"), makeString(m._1, "_"), makeString(p._1, "_"), toString(volSaldo)], ":")
1097+ let newWhOrdStr = makeString_2C([makeString(r._2, "_"), makeString(m._2, "_"), makeString(p._2, "_")], ":")
1098+ let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(r._3, "_"), makeString(m._3, "_"), makeString(p._3, "_")], ":")
1099+ let whSave = invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)
1100+ if ((whSave == whSave))
1101+ then {
1102+ let bpSave = invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil)
1103+ if ((bpSave == bpSave))
1104+ then {
1105+ let actions = [StringEntry(ordKey, newWhOrdStr)]
1106+ let usdWh2BpSaldo = fraction(p._5, (MULT6 + AUCTIONFEE), MULT6)
1107+ let actions1 = if ((usdWh2BpSaldo > 0))
1108+ then (actions :+ ScriptTransfer(caller, p._5, usdnAssetId))
1109+ else actions
1110+ let usdBp2WhSaldo = fraction(p._6, (MULT6 + AUCTIONFEE), MULT6)
1111+ if ((usdBp2WhSaldo > 0))
1112+ then if ((size(i.payments) != 1))
1113+ then throw("exactly 1 payment must be attached")
1114+ else {
1115+ let pmt = i.payments[0]
1116+ let amt = pmt.amount
1117+ let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
1118+ if ((pmtAssetId != usdnAssetId))
1119+ then throw("USDN payments only!")
1120+ else if ((amt != usdBp2WhSaldo))
1121+ then throw(("Payment needed is " + toString(usdBp2WhSaldo)))
1122+ else (actions1 :+ ScriptTransfer(addressFromStringValue(landOwner), p._6, usdnAssetId))
1123+ }
1124+ else if ((size(i.payments) != 0))
1125+ then throw("No payments needed")
1126+ else actions1
1127+ }
1128+ else throw("Strict value is not equal to itself.")
1129+ }
1130+ else throw("Strict value is not equal to itself.")
1131+ }
1132+ }
1133+ }
1134+ }
1135+ }
1136+ }
1137+
1138+

github/deemru/w8io/873ac7e 
138.51 ms