tx · 4AgFnDVzpjzSeSUZYULLNVZQLQDwqiEh83jGU9tXXSx6

3N8y4wxX3JC4TdrCJBXX16SjWf6X256hrep:  -0.05400000 Waves

2023.09.19 14:34 [2762218] smart account 3N8y4wxX3JC4TdrCJBXX16SjWf6X256hrep > SELF 0.00000000 Waves

{ "type": 13, "id": "4AgFnDVzpjzSeSUZYULLNVZQLQDwqiEh83jGU9tXXSx6", "fee": 5400000, "feeAssetId": null, "timestamp": 1695123296212, "version": 2, "chainId": 84, "sender": "3N8y4wxX3JC4TdrCJBXX16SjWf6X256hrep", "senderPublicKey": "7v5L7QkXxfkirALdyqmox38QCsa9jtfAtgUfHTh34eWq", "proofs": [ "2udxzUozk1YkGR1qeKmhqkNHX1D5kpwgKSaGhcXBkvdb1gKsYuJBaHFutqMActaSbvL1nPTf9XZ516s1PqahuXA5" ], "script": "base64:BgJxCAISBAoCCBgSAwoBCBIECgIRERIFCgMREQgSBgoEEREICBIECgIRERIFCgMREQgSBgoEEREICBIDCgEREgMKARESBAoCEQgSBAoCAQESBAoCCAgSBQoDCAgIEgQKAggIEgUKAwgICBIDCgEREgMKAQhgAAd4cFRyYWRlAJBOAAd4cENyYWZ0AJBOAAp4cFNlbGxUb0VzAJBOAAZ4cFNob3AAkE4ACkxBTkRQUkVGSVgCBExBTkQABk5VTVJFUwAGAA9ERUZBVUxUTE9DQVRJT04CD0FmcmljYV9GX0FmcmljYQAQUkVTT1VSQ0VQUklDRU1JTgDVtQIADUVTTUFYUEFDS0FHRVMACgAJRVNCVVlDT0VGAAQAFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQDQhgMAF01JTl9VU0RUX0ZFRV9ERUxJVkVSWTE1APjJBAAIcmVzVHlwZXMJAMwIAgIDT2lsCQDMCAICA09yZQkAzAgCAgRXb29kCQDMCAICBFNhbmQJAMwIAgIEQ2xheQkAzAgCAgdPcmdhbmljBQNuaWwACG1hdFR5cGVzCQDMCAICBEZ1ZWwJAMwIAgIFTWV0YWwJAMwIAgIFUGxhbmsJAMwIAgIFR2xhc3MJAMwIAgIHUGxhc3RpYwkAzAgCAgdQcm90ZWluBQNuaWwACXByb2RUeXBlcwkAzAgCAhBGaXJzdCBBaWQgS2l0IEwxCQDMCAICEEZpcnN0IEFpZCBLaXQgTDIJAMwIAgIQRmlyc3QgQWlkIEtpdCBMMwkAzAgCAgtCYWNrcGFjayBMMQkAzAgCAgtCYWNrcGFjayBMMgkAzAgCAgtCYWNrcGFjayBMMwkAzAgCAg5Gb29kIFJhdGlvbiBMMQkAzAgCAg5Gb29kIFJhdGlvbiBMMgkAzAgCAg5Gb29kIFJhdGlvbiBMMwkAzAgCAgtKZXQgUGFjayBMMQkAzAgCAgtKZXQgUGFjayBMMgkAzAgCAgtKZXQgUGFjayBMMwkAzAgCAglTaGllbGQgTDEJAMwIAgIJU2hpZWxkIEwyCQDMCAICCVNoaWVsZCBMMwkAzAgCAgdNaW5lIEwxCQDMCAICB01pbmUgTDIJAMwIAgIHTWluZSBMMwkAzAgCAgdUcmFwIEwxCQDMCAICB1RyYXAgTDIJAMwIAgIHVHJhcCBMMwUDbmlsAApjb250aW5lbnRzCQDMCAICCEFtZXJpY2FzCQDMCAICBkV1cm9wZQkAzAgCAgRBc2lhCQDMCAICBkFmcmljYQkAzAgCAgdPY2VhbmlhBQNuaWwACUNPRUZGMk1BVACAreIEABBwcm9kdWN0aW9uTWF0cml4CQDMCAICJThfOF84XzE3XzE3XzQyXzEyXzBfMzBfMCwwLDAsMCwwLDAsMF8JAMwIAgIlOF84XzhfMTdfMTdfNDJfMjRfMF82MF8wLDAsNSwyLDAsMCwwXwkAzAgCAic4XzhfOF8xN18xN180Ml8zNl8wXzEyMF8wLDAsMTAsNCwwLDAsMF8JAMwIAgIpOF8xOV8xOV84XzI3XzE5XzI2XzFfMjBfMCwwLDAsMCwwLDAsMF8wMDEJAMwIAgIpOF8xOV8xOV84XzI3XzE5XzUyXzFfNDBfMCwwLDAsMCwwLDAsMF8wMDEJAMwIAgIpOF8xOV8xOV84XzI3XzE5Xzc4XzFfODBfMCwwLDAsMCwwLDAsMF8wMDEJAMwIAgIlOF84XzhfOF84XzYwXzEzXzJfMl8wLDAsMCwwLDAsMCwwXzAxMQkAzAgCAiU4XzhfOF84XzhfNjBfMjZfMl80XzAsMCwwLDAsMCwwLDBfMDExCQDMCAICJThfOF84XzhfOF82MF8zOV8yXzhfMCwwLDAsMCwwLDAsMF8wMTEJAMwIAgIpMzBfMzBfM18xN18xN18zXzMwXzNfMzBfMCwwLDAsMCwwLDAsMF8xMTEJAMwIAgIpMzBfMzBfM18xN18xN18zXzYwXzNfNTBfMCwwLDAsMCwwLDAsMF8xMTEJAMwIAgIpMzBfMzBfM18xN18xN18zXzkwXzNfNzBfMCwwLDAsMCwwLDAsMF8xMTEJAMwIAgIrMThfMThfMTBfMThfMThfMThfMTFfNF8xMF8wLDAsMCwwLDAsMCwwXzIwMQkAzAgCAisxOF8xOF8xMF8xOF8xOF8xOF8yMl80XzIwXzAsMCwwLDAsMCwwLDBfMjAxCQDMCAICKzE4XzE4XzEwXzE4XzE4XzE4XzMzXzRfMzBfMCwwLDAsMCwwLDAsMF8yMDEJAMwIAgIqNF8xM18yMl80XzM1XzIyXzIzXzBfNTAsMSwwXzAsMCwwLDAsMCwwLDBfCQDMCAICKjRfMTNfMjJfNF8zNV8yMl80Nl8wXzUwLDEsMV8wLDIsNSwwLDAsMCwwXwkAzAgCAis0XzEzXzIyXzRfMzVfMjJfNjlfMF81MCwyLDFfMCw1LDEwLDAsMCwwLDBfCQDMCAICKjVfMjVfNDBfNV8xMF8xNV8yMF8xXzMwLDEsMV8wLDAsMCwwLDAsMCwwXwkAzAgCAio1XzI1XzQwXzVfMTBfMTVfNDBfMV8zMCwxLDJfMiwxLDMsMCwwLDAsMF8JAMwIAgIqNV8yNV80MF81XzEwXzE1XzYwXzFfMzAsMSwzXzUsMiw4LDAsMCwwLDBfBQNuaWwACXJJZHhDb2VmZgAGAA1ySWR4Q29udGluZW50AAcAClJFQ0lQRVNJWkUACwAOUFJPRFVDVFBLR1NJWkUACgALd2hJZHhMZXZlbHMAAAAId2hJZHhSZXMAAQAId2hJZHhNYXQAAgAJd2hJZHhQcm9kAAMACXdoSWR4TE9GVAAEAAl2b2xMb2NrZWQAAAAIdm9sVG90YWwAAwAKYnBJZHhMZXZlbAAAAAhicElkeFJlcwABAAhicElkeE1hdAACAAlicElkeFByb2QAAwAPbG9jSWR4Q29udGluZW50AAAACmxvY0lkeFR5cGUAAQAIbG9jSWR4SWQAAgEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQdhc3NldElkCQCsAgICA25vXwUHYXNzZXRJZAEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEHYXNzZXRJZAkArAICAgNzdF8FB2Fzc2V0SWQBD2tleUFkZHJlc3NSZWZCeQEEYWRkcgkArAICAglhY2NSZWZCeV8FBGFkZHIBFGtleVN0YWtlZER1Y2tCeU93bmVyAQlvd25lckFkZHIJAKwCAgISc3Rha2VkRHVja0J5T3duZXJfBQlvd25lckFkZHIBEWtleUJhY2twYWNrQnlEdWNrAQtkdWNrQXNzZXRJZAkArAICAgliYWNrUGFja18FC2R1Y2tBc3NldElkAQ9rZXlEdWNrTG9jYXRpb24BC2R1Y2tBc3NldElkCQCsAgICDWR1Y2tMb2NhdGlvbl8FC2R1Y2tBc3NldElkAQ5rZXlPcmRlckJ5TGFuZAELbGFuZEFzc2V0SWQJAKwCAgIKbGFuZE9yZGVyXwULbGFuZEFzc2V0SWQBDmtleUVzV2FyZWhvdXNlAAIaZW1lcmdlbmN5V2FyZWhvdXNlUHJvZHVjdHMAD2RlbGl2ZXJ5RnVuZEtleQIMZGVsaXZlcnlGdW5kARJnZXRSZWNpcGVNYXRlcmlhbHMBBnJlY2lwZQkAaAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZyZWNpcGUFCXJJZHhDb2VmZgUJQ09FRkYyTUFUABFLU19BTExPV19ERUxJVkVSWQcABWNoYWluCQDJAQIJAMoBAggFBHRoaXMFYnl0ZXMAAQABAAt1c2R0QXNzZXRJZAQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAEghNp6sggDP07Ru8qO7ouTvMmC3Qtd+geWqNQj+agP/7kDCQAAAgEBVAUHJG1hdGNoMAEgVbHYn3KHgu/l41uNrAWrZd6aQ6EvFrsF8xq3h6XxxRgJAAIBAg1Vbmtub3duIGNoYWluABVkZWZhdWx0UmVzdEFkZHJlc3NTdHIEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDACIzNQUUN1dkZidmg0TGtQVW5yblUxejNqbmJBMXA5bTNXTmh2AwkAAAIBAVQFByRtYXRjaDACIzNNdW1rR0d6dENLQVhwV0RxeGtkZG9mcVhTVWJxUWt2U0p5CQACAQINVW5rbm93biBjaGFpbgADU0VQAgJfXwAFTVVMVDUAoI0GAAVNVUxUNgDAhD0ABU1VTFQ4AIDC1y8ABk1VTFQxMACAyK+gJQAOTUlOU0hPUFBBWU1FTlQAoI0GAAVJVEVSNgkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQUDbmlsAQ9nZXRTdHJpbmdPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUHYWRkcmVzcwUDa2V5CQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFB2FkZHJlc3MJAMwIAgIBLgkAzAgCBQNrZXkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAARSWR4Q2ZnU3Rha2luZ0RhcHAAAQEKa2V5UmVzdENmZwACDiVzX19yZXN0Q29uZmlnAQ5rZXlSZXN0QWRkcmVzcwACDCVzX19yZXN0QWRkcgERcmVhZFJlc3RDZmdPckZhaWwBBHJlc3QJALwJAgkBD2dldFN0cmluZ09yRmFpbAIFBHJlc3QJAQprZXlSZXN0Q2ZnAAUDU0VQARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCB3Jlc3RDZmcDaWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQdyZXN0Q2ZnBQNpZHgJAKwCAgIqUmVzdCBjZmcgZG9lc24ndCBjb250YWluIGFkZHJlc3MgYXQgaW5kZXggCQCkAwEFA2lkeAAMcmVzdENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJAQ5rZXlSZXN0QWRkcmVzcwAFFWRlZmF1bHRSZXN0QWRkcmVzc1N0cgAHcmVzdENmZwkBEXJlYWRSZXN0Q2ZnT3JGYWlsAQUMcmVzdENvbnRyYWN0AA9zdGFraW5nQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBRFJZHhDZmdTdGFraW5nRGFwcAEIYXNTdHJpbmcBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwBQFzCQACAQIYZmFpbCB0byBjYXN0IGludG8gU3RyaW5nAQVhc0ludAEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgNJbnQEAW4FByRtYXRjaDAFAW4JAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBCmtleUJsb2NrZWQAAhBjb250cmFjdHNCbG9ja2VkAQpmaXhlZFBvaW50AgN2YWwIZGVjaW1hbHMEBnRlblBvdwkAbAYACgAABQhkZWNpbWFscwAAAAAFBERPV04EB2xvd1BhcnQJAKQDAQkAagIFA3ZhbAUGdGVuUG93BAZ6ZXJvZXMJALACAgkApAMBBQZ0ZW5Qb3cJAGQCAAEJALECAQUHbG93UGFydAkArAICCQCsAgIJAKwCAgkApAMBCQBpAgUDdmFsBQZ0ZW5Qb3cCAS4FBnplcm9lcwUHbG93UGFydAATRkFDVE9SWU1BWFdBUkVIT1VTRQCAyK+gJQAOU0VMTE1VTFRJUExJRVIAyAEADUJVWU1VTFRJUExJRVIArAIACkFVQ1RJT05GRUUAkE4ADERFTElWRVJZX0ZFRQCQTgAOREVMSVZFUllfRkVFMTUAmHUBHmtleUZhY3RvcnlXYXJlaG91c2VCeUlkQW5kVHlwZQIJZmFjdG9yeUlkB3Jlc1R5cGUJAKwCAgkArAICCQCsAgICG2ZhY3RvcnlXaEJ5Q29udGluZW50QW5kUmVzXwUJZmFjdG9yeUlkAgFfCQCkAwEFB3Jlc1R5cGUACW9yZElkeFJlcwAAAAlvcmRJZHhNYXQAAQAKb3JkSWR4UHJvZAACAQhnZXRPcmRlcgEGb3JkS2V5BAFwCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUGb3JkS2V5AjAwQDBfMEAwXzBAMF8wQDBfMEAwXzBAMDowQDBfMEAwXzBAMF8wQDBfMEAwXzBAMDoCAToJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQFwBQlvcmRJZHhSZXMCAV8FBk5VTVJFUwkAkQMCBQFwBQlvcmRJZHhSZXMCFzBAMF8wQDBfMEAwXzBAMF8wQDBfMEAwCQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUBcAUJb3JkSWR4TWF0AgFfBQZOVU1SRVMJAJEDAgUBcAUJb3JkSWR4TWF0AhcwQDBfMEAwXzBAMF8wQDBfMEAwXzBAMAkAzAgCCQCRAwIFAXAFCm9yZElkeFByb2QFA25pbAEIdG9Wb2x1bWUDBmFtb3VudAdwa2dTaXplCWlzUHJvZHVjdAMFCWlzUHJvZHVjdAQEcGtncwMJAGcCBQZhbW91bnQAAAkAaQIJAGUCCQBkAgUGYW1vdW50BQdwa2dTaXplAAEFB3BrZ1NpemUJAQEtAQkAaQIJAGUCCQBkAgkBAS0BBQZhbW91bnQFB3BrZ1NpemUAAQUHcGtnU2l6ZQkAaAIFBHBrZ3MFBU1VTFQ4BQZhbW91bnQBDHNlbGxJbnRlcm5hbAQFbG9jSWQHcmVzVHlwZQZhbW91bnQIbWluUHJpY2UEBXdoS2V5CQEea2V5RmFjdG9yeVdhcmVob3VzZUJ5SWRBbmRUeXBlAgUFbG9jSWQFB3Jlc1R5cGUEAncwCQELdmFsdWVPckVsc2UCCQCfCAEFBXdoS2V5AAAEAnIwAwkAZgIFAncwBRNGQUNUT1JZTUFYV0FSRUhPVVNFAAADCQBmAgkAZAIFAncwBQZhbW91bnQFE0ZBQ1RPUllNQVhXQVJFSE9VU0UJAGUCBRNGQUNUT1JZTUFYV0FSRUhPVVNFBQJ3MAUGYW1vdW50BAx1c2R0UmVjZWl2ZWQJAGQCCQBrAwUCcjAJAGUCCQBoAgUOU0VMTE1VTFRJUExJRVIFEFJFU09VUkNFUFJJQ0VNSU4JAGsDCQBkAgkAaAIAZAUCdzAJAGgCADIFAnIwBRBSRVNPVVJDRVBSSUNFTUlOBRNGQUNUT1JZTUFYV0FSRUhPVVNFBQZNVUxUMTAJAGsDCQBlAgUGYW1vdW50BQJyMAUQUkVTT1VSQ0VQUklDRU1JTgUFTVVMVDgEBW1pbjk5CQBlAgUIbWluUHJpY2UJAGkCBQhtaW5QcmljZQBkAwkAZgIJAGgCBQVtaW45OQUGYW1vdW50CQBoAgUMdXNkdFJlY2VpdmVkBQVNVUxUOAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIPQWN0dWFsIHByaWNlID0gCQCkAwEFDHVzZHRSZWNlaXZlZAIDIC8gCQCkAwEFBmFtb3VudAIOIDwgbWluUHJpY2UgPSAJAKQDAQUIbWluUHJpY2UCAywgKAUFbG9jSWQCAiwgCQCRAwIFCHJlc1R5cGVzBQdyZXNUeXBlAgEpCQCUCgIJAQxJbnRlZ2VyRW50cnkCBQV3aEtleQkAZAIFAncwBQZhbW91bnQFDHVzZHRSZWNlaXZlZAELYnV5SW50ZXJuYWwEBWxvY0lkB21hdFR5cGUGYW1vdW50CG1heFByaWNlBAV3aEtleQkBHmtleUZhY3RvcnlXYXJlaG91c2VCeUlkQW5kVHlwZQIFBWxvY0lkBQdtYXRUeXBlBAJ3MAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQV3aEtleQAABAJtMQMJAGYCBQJ3MAUTRkFDVE9SWU1BWFdBUkVIT1VTRQkAlwMBCQDMCAIFBmFtb3VudAkAzAgCCQBlAgUCdzAFE0ZBQ1RPUllNQVhXQVJFSE9VU0UFA25pbAAABAJtMAkAlwMBCQDMCAIFAncwCQDMCAIJAGUCBQZhbW91bnQFAm0xBQNuaWwEAW0JAGQCBQJtMAUCbTEECXVzZHRTcGVudAkAZAIJAGsDBQJtMAkAZQIJAGgCBQ1CVVlNVUxUSVBMSUVSBRBSRVNPVVJDRVBSSUNFTUlOCQBrAwkAZQIJAGgCAGQFAncwCQBoAgAyBQJtMAUQUkVTT1VSQ0VQUklDRU1JTgUTRkFDVE9SWU1BWFdBUkVIT1VTRQUGTVVMVDEwCQBrAwUCbTEJAGgCAAIFEFJFU09VUkNFUFJJQ0VNSU4FBU1VTFQ4BAZtYXgxMDEJAGQCBQhtYXhQcmljZQkAaQIFCG1heFByaWNlAGQDCQBmAgkAaAIFCXVzZHRTcGVudAUFTVVMVDgJAGgCBQZtYXgxMDEFAW0JAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICD0FjdHVhbCBwcmljZSA9IAkApAMBBQl1c2R0U3BlbnQCAyAvIAkApAMBBQFtAg4gPiBtYXhQcmljZSA9IAkApAMBBQhtYXhQcmljZQIDLCAoBQVsb2NJZAICLCAJAJEDAgUIbWF0VHlwZXMFB21hdFR5cGUCASkJAJUKAwkBDEludGVnZXJFbnRyeQIFBXdoS2V5CQBlAgUCdzAFAW0FCXVzZHRTcGVudAUBbQELZ2V0QmFja3BhY2sBBWJwS2V5BAFwCQC8CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0BQVicEtleQIaMDowXzBfMF8wXzBfMDowXzBfMF8wXzBfMDoCAToJAMwIAgkApAMBCQELdmFsdWVPckVsc2UCCQC2CQEJAJEDAgUBcAUKYnBJZHhMZXZlbAAACQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUBcAUIYnBJZHhSZXMCAV8FBk5VTVJFUwkAkQMCBQFwBQhicElkeFJlcwILMF8wXzBfMF8wXzAJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQFwBQhicElkeE1hdAIBXwUGTlVNUkVTCQCRAwIFAXAFCGJwSWR4TWF0AgswXzBfMF8wXzBfMAkAzAgCCQCRAwIFAXAFCWJwSWR4UHJvZAUDbmlsAQxjaGVja0Jsb2NrZWQAAwkBC3ZhbHVlT3JFbHNlAgkAmwgCBQ9zdGFraW5nQ29udHJhY3QJAQprZXlCbG9ja2VkAAcJAAIBAh9Db250cmFjdHMgYXJlIHVuZGVyIG1haW50ZW5hbmNlBQR1bml0AQZwcm9sb2cACQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIKc2F2ZUxhc3RUeAUDbmlsBQNuaWwBCXNldENvbW1vbgIDYWNjD2lnbm9yZWRJdGVyYXRvcgQBaggFA2FjYwJfMQQEaXRlbQMJAGYCCQCQAwEIBQNhY2MDXzEwBQFqCQCRAwIIBQNhY2MDXzEwBQFqAgMwQDAEBmlzUHJvZAgFA2FjYwJfOAQJaXRlbVBhcnRzCQC1CQIFBGl0ZW0CAUADCQECIT0CCQCQAwEFCWl0ZW1QYXJ0cwACCQACAQIuSW5jb3JyZWN0IG9yZGVyIGZvcm1hdCwgc2hvdWxkIGJlIGFtb3VudEBwcmljZQQIbmV3T3JkQW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlpdGVtUGFydHMAAAQIbmV3T3JkUHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlpdGVtUGFydHMAAQQJbmV3T3JkVXNkAwUGaXNQcm9kCQBoAgUIbmV3T3JkQW0FCG5ld09yZFByCQBrAwUIbmV3T3JkQW0FCG5ld09yZFByBQVNVUxUOAQJbmV3T3JkVm9sCQEIdG9Wb2x1bWUDBQhuZXdPcmRBbQUOUFJPRFVDVFBLR1NJWkUFBmlzUHJvZAQGd2hJbml0AwkAZgIJAJADAQgFA2FjYwJfNgUBagkBDXBhcnNlSW50VmFsdWUBCQCRAwIIBQNhY2MCXzYFAWoAAAQLY3VyT3JkUGFydHMJALUJAgMJAGYCCQCQAwEIBQNhY2MCXzcFAWoJAJEDAggFA2FjYwJfNwUBagIDMEAwAgFABAhjdXJPcmRBbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFC2N1ck9yZFBhcnRzAAAECGN1ck9yZFByCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgULY3VyT3JkUGFydHMAAQMDCQBmAgAABQhjdXJPcmRQcgYJAGYCAAAFCG5ld09yZFByCQACAQIXUHJpY2UgY2FuJ3QgYmUgbmVnYXRpdmUECWN1ck9yZFVzZAMFBmlzUHJvZAkAaAIFCGN1ck9yZEFtBQhjdXJPcmRQcgkAawMFCGN1ck9yZEFtBQhjdXJPcmRQcgUFTVVMVDgDCQAAAgUIbmV3T3JkQW0AAAMJAGYCBQhjdXJPcmRBbQAACQCcCgoJAGQCBQFqAAEJAM0IAggFA2FjYwJfMgkApAMBBQZ3aEluaXQIBQNhY2MCXzMIBQNhY2MCXzQJAGUCCAUDYWNjAl81BQljdXJPcmRVc2QIBQNhY2MCXzYIBQNhY2MCXzcFBmlzUHJvZAkAZAIIBQNhY2MCXzkJAQh0b1ZvbHVtZQMFBndoSW5pdAUOUFJPRFVDVFBLR1NJWkUFBmlzUHJvZAgFA2FjYwNfMTAJAJwKCgkAZAIFAWoAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGUCBQZ3aEluaXQFCGN1ck9yZEFtCAUDYWNjAl8zCAUDYWNjAl80CAUDYWNjAl81CAUDYWNjAl82CAUDYWNjAl83BQZpc1Byb2QJAGQCCAUDYWNjAl85CQEIdG9Wb2x1bWUDCQBlAgUGd2hJbml0BQhjdXJPcmRBbQUOUFJPRFVDVFBLR1NJWkUFBmlzUHJvZAgFA2FjYwNfMTADCQBmAgUIbmV3T3JkQW0AAAMJAGYCAAAFCGN1ck9yZEFtCQCcCgoJAGQCBQFqAAEJAM0IAggFA2FjYwJfMgkApAMBCQBlAgUGd2hJbml0BQhjdXJPcmRBbQkAZAIIBQNhY2MCXzMFCW5ld09yZFZvbAgFA2FjYwJfNAkAZAIIBQNhY2MCXzUFCW5ld09yZFVzZAgFA2FjYwJfNggFA2FjYwJfNwUGaXNQcm9kCQEIdG9Wb2x1bWUDCQBlAgUGd2hJbml0BQhjdXJPcmRBbQUOUFJPRFVDVFBLR1NJWkUFBmlzUHJvZAgFA2FjYwNfMTAJAJwKCgkAZAIFAWoAAQkAzQgCCAUDYWNjAl8yCQCkAwEFBndoSW5pdAkAZAIIBQNhY2MCXzMFCW5ld09yZFZvbAgFA2FjYwJfNAkAZQIJAGQCCAUDYWNjAl81BQluZXdPcmRVc2QFCWN1ck9yZFVzZAgFA2FjYwJfNggFA2FjYwJfNwUGaXNQcm9kCQEIdG9Wb2x1bWUDBQZ3aEluaXQFDlBST0RVQ1RQS0dTSVpFBQZpc1Byb2QIBQNhY2MDXzEwAwkAZgIAAAUIY3VyT3JkQW0EBmFtRGlmZgkAZQIFCGN1ck9yZEFtBQhuZXdPcmRBbQMJAGYCAAAJAGUCBQZ3aEluaXQFBmFtRGlmZgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byB0YWtlIAkApAMBBQZhbURpZmYCGiBmcm9tIHdhcmVob3VzZSwgYnV0IG9ubHkgCQCkAwEFBndoSW5pdAIKIGF2YWlsYWJsZQkAnAoKCQBkAgUBagABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZQIFBndoSW5pdAUGYW1EaWZmCAUDYWNjAl8zCQBlAggFA2FjYwJfNAUJbmV3T3JkVm9sCAUDYWNjAl81CAUDYWNjAl82CAUDYWNjAl83BQZpc1Byb2QJAQh0b1ZvbHVtZQMJAGUCBQZ3aEluaXQFBmFtRGlmZgUOUFJPRFVDVFBLR1NJWkUFBmlzUHJvZAgFA2FjYwNfMTADCQBmAgAACQBkAgUGd2hJbml0BQhuZXdPcmRBbQkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byB0YWtlIAkApAMBCQEBLQEFCG5ld09yZEFtAhogZnJvbSB3YXJlaG91c2UsIGJ1dCBvbmx5IAkApAMBBQZ3aEluaXQCCiBhdmFpbGFibGUJAJwKCgkAZAIFAWoAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGQCBQZ3aEluaXQFCG5ld09yZEFtCAUDYWNjAl8zCQBlAggFA2FjYwJfNAUJbmV3T3JkVm9sCQBlAggFA2FjYwJfNQUJY3VyT3JkVXNkCAUDYWNjAl82CAUDYWNjAl83BQZpc1Byb2QJAQh0b1ZvbHVtZQMJAGQCBQZ3aEluaXQFCG5ld09yZEFtBQ5QUk9EVUNUUEtHU0laRQUGaXNQcm9kCAUDYWNjA18xMAELc2V0SW50ZXJuYWwDCWN1cnJlbnRXaApjdXJyZW50T3JkBm5ld09yZAQJY3VycldoUmVzCQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeFJlcwIBXwQJY3VycldoTWF0CQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAIBXwQKY3VycldoUHJvZAMJAAACCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kAgAFA25pbAkAvAkCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kAgFfBA1jdXJyZW50T3JkUmVzCQC1CQIJAJEDAgUKY3VycmVudE9yZAUJb3JkSWR4UmVzAgFfBA1jdXJyZW50T3JkTWF0CQC1CQIJAJEDAgUKY3Vy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cgIDYWNjAWoDCQBmAgkAkQMCBQdhbW91bnRzBQFqCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHcmVzTGlzdAUBagkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAglZb3UgaGF2ZSAJAJEDAgUHcmVzTGlzdAUBagIEIG9mIAkAkQMCBQhyZXNUeXBlcwUBagIULCBidXQgdHJpZWQgdG8gc2VsbCAJAKQDAQkAkQMCBQdhbW91bnRzBQFqAwkAZgIAAAkAkQMCBQdhbW91bnRzBQFqCQACAQkArAICCQCsAgIJAKwCAgIlWW91IHRyaWVkIHRvIHNlbGwgbmVnYXRpdmUgYW1vdW50IG9mIAkAkQMCBQhyZXNUeXBlcwUBagICOiAJAKQDAQkAkQMCBQdhbW91bnRzBQFqAwkAZgIJAJEDAgUHYW1vdW50cwUBagAABAFiCQEMc2VsbEludGVybmFsBAUMZmFjdG9yeUxvY0lkBQFqCQCRAwIFB2Ftb3VudHMFAWoJAJEDAgUJbWluUHJpY2VzBQFqCQCWCgQJAM0IAggFA2FjYwJfMQgFAWICXzEJAM0IAggFA2FjYwJfMgkApAMBCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB3Jlc0xpc3QFAWoJAJEDAgUHYW1vdW50cwUBagkAZAIIBQNhY2MCXzMIBQFiAl8yCQBkAggFA2FjYwJfNAkAkQMCBQdhbW91bnRzBQFqCQCWCgQIBQNhY2MCXzEJAM0IAggFA2FjYwJfMgkAkQMCBQdyZXNMaXN0BQFqCAUDYWNjAl8zCAUDYWNjAl80CgACJGwFBUlURVI2CgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlgoEBQNuaWwFA25pbAAAAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBWFkZGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGARJidXlNYXRlcmlhbHNDb21tb24EB21hdExpc3QMZmFjdG9yeUxvY0lkB2Ftb3VudHMJbWF4UHJpY2VzCgEIbVVwZGF0ZXICA2FjYwFqAwkAZgIAAAkAkQMCBQdhbW91bnRzBQFqCQACAQkArAICCQCsAgIJAKwCAgIkWW91IHRyaWVkIHRvIGJ1eSBuZWdhdGl2ZSBhbW91bnQgb2YgCQCRAwIFCG1hdFR5cGVzBQFqAgI6IAkApAMBCQCRAwIFB2Ftb3VudHMFAWoDCQBmAgkAkQMCBQdhbW91bnRzBQFqAAAEAWIJAQtidXlJbnRlcm5hbAQFDGZhY3RvcnlMb2NJZAUBagkAkQMCBQdhbW91bnRzBQFqCQCRAwIFCW1heFByaWNlcwUBagkAlgoECQDNCAIIBQNhY2MCXzEIBQFiAl8xCQDNCAIIBQNhY2MCXzIJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdtYXRMaXN0BQFqCAUBYgJfMwkAZAIIBQNhY2MCXzMIBQFiAl8yCQBkAggFA2FjYwJfNAkAkQMCBQdhbW91bnRzBQFqCQCWCgQIBQNhY2MCXzEJAM0IAggFA2FjYwJfMgkAkQMCBQdtYXRMaXN0BQFqCAUDYWNjAl8zCAUDYWNjAl80CgACJGwFBUlURVI2CgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlgoEBQNuaWwFA25pbAAAAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCG1VcGRhdGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGARdleGNoYW5nZVJlc291cmNlc0NvbW1vbgMHcmVzTGlzdAdtYXRMaXN0B2Ftb3VudHMKAQlleGNoYW5nZXICA2FjYwFqBANhbWoJAJEDAgUHYW1vdW50cwUBagMJAGYCBQNhbWoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdyZXNMaXN0BQFqCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCVlvdSBoYXZlIAkAkQMCBQdyZXNMaXN0BQFqAgQgb2YgCQCRAwIFCHJlc1R5cGVzBQFqAhgsIGJ1dCB0cmllZCB0byBleGNoYW5nZSAJAKQDAQUDYW1qAwkAZgIAAAUDYW1qCQACAQkArAICCQCsAgIJAKwCAgIpWW91IHRyaWVkIHRvIGV4Y2hhbmdlIG5lZ2F0aXZlIGFtb3VudCBvZiAJAJEDAgUIcmVzVHlwZXMFAWoCAjogCQCkAwEFA2FtagMJAGYCBQNhbWoAAAkAlgoECQDNCAIIBQNhY2MCXzEJAKQDAQkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdyZXNMaXN0BQFqBQNhbWoJAM0IAggFA2FjYwJfMgkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB21hdExpc3QFAWoFA2FtagkAZAIIBQNhY2MCXzMJAGsDBQNhbWoFEFJFU09VUkNFUFJJQ0VNSU4FBU1VTFQ4CQBkAggFA2FjYwJfNAUDYW1qCQCWCgQJAM0IAggFA2FjYwJfMQkAkQMCBQdyZXNMaXN0BQFqCQDNCAIIBQNhY2MCXzIJAJEDAgUHbWF0TGlzdAUBaggFA2FjYwJfMwgFA2FjYwJfNAoAAiRsBQVJVEVSNgoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJYKBAUDbmlsBQNuaWwAAAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQlleGNoYW5nZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYBEHNob3AydXNlckFjdGlvbnMDDXVzZFdoMkJwU2FsZG8KY2FsbGVyQWRkcgtyZWNlaXZlZEZlZQMJAGYCBQ11c2RXaDJCcFNhbGRvAAAEC3VzZFdoMkJwRmVlCQBrAwUNdXNkV2gyQnBTYWxkbwUKQVVDVElPTkZFRQUFTVVMVDYDCQBnAgULcmVjZWl2ZWRGZWUJAGUCBQ11c2RXaDJCcFNhbGRvCQBoAgADBQt1c2RXaDJCcEZlZQkAAgEJAKwCAgIrVGhpcyB0cmFkZSBkb2VzIG5vdCBjb3ZlciBkZWxpdmVyeSBjb3N0IG9mIAkBCmZpeGVkUG9pbnQCBQtyZWNlaXZlZEZlZQAGBAhyZWZCeUtleQkBD2tleUFkZHJlc3NSZWZCeQEFCmNhbGxlckFkZHIEBXJlZkJ5CQCdCAIFD3N0YWtpbmdDb250cmFjdAUIcmVmQnlLZXkEBmNhbGxlcgkBEUBleHRyTmF0aXZlKDEwNjIpAQUKY2FsbGVyQWRkcgkAzQgCCQDNCAIDCQEJaXNEZWZpbmVkAQUFcmVmQnkJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBBXZhbHVlAQUFcmVmQnkFC3VzZFdoMkJwRmVlBQt1c2R0QXNzZXRJZAUDbmlsBQNuaWwJAQ5TY3JpcHRUcmFuc2ZlcgMFBmNhbGxlcgkAZQIJAGUCBQ11c2RXaDJCcFNhbGRvCQBoAgADBQt1c2RXaDJCcEZlZQULcmVjZWl2ZWRGZWUFC3VzZHRBc3NldElkCQEOU2NyaXB0VHJhbnNmZXIDBQxyZXN0Q29udHJhY3QFC3VzZFdoMkJwRmVlBQt1c2R0QXNzZXRJZAUDbmlsARB1c2VyMnNob3BBY3Rpb25zBA11c2RCcDJXaFNhbGRvBHBtdHMNc2hvcExhbmRPd25lcghzcGVudEZlZQMJAGYCBQ11c2RCcDJXaFNhbGRvAAADCQECIT0CCQCQAwEFBHBtdHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCBQRwbXRzAAAEA2FtdAgFA3BtdAZhbW91bnQDAwkBASEBCQEJaXNEZWZpbmVkAQgFA3BtdAdhc3NldElkBgkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkBQt1c2R0QXNzZXRJZAkAAgECE1VTRFQgcGF5bWVudHMgb25seSEEEHVzZHRTcGVudFdpdGhGZWUJAGQCBQ11c2RCcDJXaFNhbGRvBQhzcGVudEZlZQMJAQIhPQIFA2FtdAUQdXNkdFNwZW50V2l0aEZlZQkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICH0luc3VmZmljaWVudCBwYXltZW50ISBBdHRhY2hlZD0JAQpmaXhlZFBvaW50AgUDYW10AAYCCywgcmVxdWlyZWQ9CQEKZml4ZWRQb2ludAIFDXVzZEJwMldoU2FsZG8ABgIBKwkBCmZpeGVkUG9pbnQCBQhzcGVudEZlZQAGAg4oZGVsaXZlcnkgZmVlKQMJAGYCBQ5NSU5TSE9QUEFZTUVOVAUNdXNkQnAyV2hTYWxkbwkAAgEJAKwCAgISTWluIHNob3AgdHJhZGUgaXMgCQEKZml4ZWRQb2ludAIFDk1JTlNIT1BQQVlNRU5UAAYEC3VzZEJwMldoRmVlCQBrAwUNdXNkQnAyV2hTYWxkbwUKQVVDVElPTkZFRQUFTVVMVDYECHJlZkJ5S2V5CQEPa2V5QWRkcmVzc1JlZkJ5AQUNc2hvcExhbmRPd25lcgQFcmVmQnkJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0BQhyZWZCeUtleQkAzQgCCQDNCAIDCQEJaXNEZWZpbmVkAQUFcmVmQnkJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBBXZhbHVlAQUFcmVmQnkFC3VzZEJwMldoRmVlBQt1c2R0QXNzZXRJZAUDbmlsBQNuaWwJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDXNob3BMYW5kT3duZXIJAGUCBQ11c2RCcDJXaFNhbGRvCQBoAgADBQt1c2RCcDJXaEZlZQULdXNkdEFzc2V0SWQJAQ5TY3JpcHRUcmFuc2ZlcgMFDHJlc3RDb250cmFjdAULdXNkQnAyV2hGZWUFC3VzZHRBc3NldElkAwkBAiE9AgkAkAMBBQRwbXRzAAAJAAIBAhJObyBwYXltZW50cyBuZWVkZWQFA25pbAEVYWNjZXB0U2hvcE9yZGVyQ29tbW9uBg9zaG9wTGFuZEFzc2V0SWQKY2FsbGVyQWRkcgpicE9yZGVyU3RyCWJwUmVzTGlzdAlicE1hdExpc3QKYnBQcm9kTGlzdAQJbGFuZEFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQUPc2hvcExhbmRBc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAmggCBQ9zdGFraW5nQ29udHJhY3QJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQUPc2hvcExhbmRBc3NldElkCQACAQkArAICCQCsAgICBE5GVCAIBQlsYW5kQXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEDXNob3BMYW5kT3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQ9zaG9wTGFuZEFzc2V0SWQJAKwCAgkArAICAgRORlQgCAUJbGFuZEFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAAACBQ1zaG9wTGFuZE93bmVyBQpjYWxsZXJBZGRyCQACAQIeWW91IGNhbm5vdCB0cmFkZSB3aXRoIHlvdXJzZWxmBAxicE9yZGVyUGFydHMJALwJAgUKYnBPcmRlclN0cgIBOgMJAQIhPQIJAJADAQUMYnBPcmRlclBhcnRzAAMJAAIBAjJicE9yZGVyU3RyIHNob3VsZCBjb250YWluIGV4YWN0bHkgMiAnOicgc2VwYXJhdG9ycwQIYnBPcmRSZXMJALUJAgkAkQMCBQxicE9yZGVyUGFydHMAAAIBXwQIYnBPcmRNYXQJALUJAgkAkQMCBQxicE9yZGVyUGFydHMAAQIBXwQJYnBPcmRQcm9kAwkAAAIJAJEDAgUMYnBPcmRlclBhcnRzAAICAAUDbmlsCQC8CQIJAJEDAgUMYnBPcmRlclBhcnRzAAICAV8DCQECIT0CCQCQAwEFCGJwT3JkUmVzBQZOVU1SRVMJAAIBAiBBbGwgNiByZXNvdXJjZXMgc2hvdWxkIGJlIHBhc3NlZAMJAQIhPQIJAJADAQUIYnBPcmRNYXQFBk5VTVJFUwkAAgECIEFsbCA2IG1hdGVyaWFscyBzaG91bGQgYmUgcGFzc2VkBAJ3aAkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCFGdldFdhcmVob3VzZVJFQURPTkxZCQDMCAIFD3Nob3BMYW5kQXNzZXRJZAUDbmlsBQNuaWwECWN1cnJlbnRXaAkAvAkCBQJ3aAIBOgQJY3VycldoUmVzCQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeFJlcwIBXwQJY3VycldoTWF0CQC1CQIJAJEDAgUJY3Vy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d25lcgUGd2hTYXZlBQ5hY2NTdGF0c1Jlc3VsdBIBaQEacmVjYWxjTG9ja2VkVm9sdW1lUkVBRE9OTFkCC2xhbmRBc3NldElkAndoBApjdXJyZW50T3JkCQEIZ2V0T3JkZXIBCQEOa2V5T3JkZXJCeUxhbmQBBQtsYW5kQXNzZXRJZAQBegkBC3NldEludGVybmFsAwUCd2gFCmN1cnJlbnRPcmQFCmN1cnJlbnRPcmQJAJQKAgUDbmlsCQBkAggFAXoCXzQIBQF6Al81AWkBDWNvbnN0cnVjdG9yVjEBCHJlc3RBZGRyAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIRUGVybWlzc2lvbiBkZW5pZWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDmtleVJlc3RBZGRyZXNzAAUIcmVzdEFkZHIFA25pbAFpAQ1zZWxsUmVzb3VyY2VzAgdhbW91bnRzCW1pblByaWNlcwQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIqc2VsbFJlc291cmNlcyBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnRzBAtjdXJMb2NhdGlvbgkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04CAV8DCQECIT0CCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlAgFGCQACAQkArAICAi1EdWNrIGxvY2F0aW9uIHR5cGUgc2hvdWxkIGJlIEZhY3RvcnksIGJ1dCBpcyAJAJEDAgULY3VyTG9jYXRpb24FCmxvY0lkeFR5cGUEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQHcmVzTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwQNJHQwMjU4NzcyNjAwMwkBE3NlbGxSZXNvdXJjZXNDb21tb24EBQdyZXNMaXN0CQCRAwIFC2N1ckxvY2F0aW9uBQhsb2NJZHhJZAUHYW1vdW50cwUJbWluUHJpY2VzBA5mYWN0b3J5QWN0aW9ucwgFDSR0MDI1ODc3MjYwMDMCXzEEBm5ld1JlcwgFDSR0MDI1ODc3MjYwMDMCXzIEDHVzZHRSZWNlaXZlZAgFDSR0MDI1ODc3MjYwMDMCXzMECHRvdGFsUmVzCAUNJHQwMjU4NzcyNjAwMwJfNAQQYWN0aXZpdGllc0Ftb3VudAkAaQIFDHVzZHRSZWNlaXZlZABkBAduZXdQYWNrCQC6CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQC5CQIFBm5ld1JlcwIBXwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgQOYmFja3BhY2tSZXN1bHQJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag51cGRhdGVCYWNrcGFjawkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCBQduZXdQYWNrBQNuaWwFA25pbAQLc3RhdHNSZXN1bHQJAQVhc0ludAEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag91cGRhdGVEdWNrU3RhdHMJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgkAawMFB3hwVHJhZGUFCHRvdGFsUmVzBQVNVUxUOAUDbmlsBQNuaWwJAJQKAgkAzQgCCQDNCAIFDmZhY3RvcnlBY3Rpb25zCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAGUCBQx1c2R0UmVjZWl2ZWQFEGFjdGl2aXRpZXNBbW91bnQFC3VzZHRBc3NldElkCQEOU2NyaXB0VHJhbnNmZXIDBQxyZXN0Q29udHJhY3QFEGFjdGl2aXRpZXNBbW91bnQFC3VzZHRBc3NldElkCQCVCgMFDmJhY2twYWNrUmVzdWx0BQxwcm9sb2dSZXN1bHQFC3N0YXRzUmVzdWx0AWkBGXNlbGxSZXNvdXJjZXNEdWNrRGVsaXZlcnkDB2Ftb3VudHMJbWluUHJpY2VzEGZhY3RvcnlDb250aW5lbnQDCQEBIQEFEUtTX0FMTE9XX0RFTElWRVJZCQACAQIfRGVsaXZlcnkgZmVhdHVyZSBpcyB0dXJuZWQgb2ZmIQQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIqc2VsbFJlc291cmNlcyBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnRzBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEB3Jlc0xpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMCAV8EDSR0MDI3MjM3MjczNTgJARNzZWxsUmVzb3VyY2VzQ29tbW9uBAUHcmVzTGlzdAUQZmFjdG9yeUNvbnRpbmVudAUHYW1vdW50cwUJbWluUHJpY2VzBA5mYWN0b3J5QWN0aW9ucwgFDSR0MDI3MjM3MjczNTgCXzEEBm5ld1JlcwgFDSR0MDI3MjM3MjczNTgCXzIEDHVzZHRSZWNlaXZlZAgFDSR0MDI3MjM3MjczNTgCXzMECHRvdGFsUmVzCAUNJHQwMjcyMzcyNzM1OAJfNAQHbmV3UGFjawkAugkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAuQkCBQZuZXdSZXMCAV8JAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwCAToEDmJhY2twYWNrUmVzdWx0CQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQmFja3BhY2sJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUHbmV3UGFjawUDbmlsBQNuaWwEC3N0YXRzUmVzdWx0CQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIPdXBkYXRlRHVja1N0YXRzCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIJAGsDBQd4cFRyYWRlBQh0b3RhbFJlcwUFTVVMVDgFA25pbAUDbmlsBAdmZWVQYXJ0CQBrAwUMdXNkdFJlY2VpdmVkBQxERUxJVkVSWV9GRUUFBU1VTFQ2BANmZWUDCQBmAgUVTUlOX1VTRFRfRkVFX0RFTElWRVJZBQdmZWVQYXJ0BRVNSU5fVVNEVF9GRUVfREVMSVZFUlkFB2ZlZVBhcnQEEGFjdGl2aXRpZXNBbW91bnQJAGkCBQx1c2R0UmVjZWl2ZWQAZAMJAGcCBQNmZWUJAGUCBQx1c2R0UmVjZWl2ZWQFEGFjdGl2aXRpZXNBbW91bnQJAAIBCQCsAgICK1RoaXMgdHJhZGUgZG9lcyBub3QgY292ZXIgZGVsaXZlcnkgY29zdCBvZiAJAQpmaXhlZFBvaW50AgUDZmVlAAYECWZ1bmRUb3RhbAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ9kZWxpdmVyeUZ1bmRLZXkAAAkAlAoCCQDNCAIJAM0IAgkAzQgCBQ5mYWN0b3J5QWN0aW9ucwkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQBlAgkAZQIFDHVzZHRSZWNlaXZlZAUQYWN0aXZpdGllc0Ftb3VudAUDZmVlBQt1c2R0QXNzZXRJZAkBDEludGVnZXJFbnRyeQIFD2RlbGl2ZXJ5RnVuZEtleQkAZAIFCWZ1bmRUb3RhbAUDZmVlCQEOU2NyaXB0VHJhbnNmZXIDBQxyZXN0Q29udHJhY3QFEGFjdGl2aXRpZXNBbW91bnQFC3VzZHRBc3NldElkCQCVCgMFDmJhY2twYWNrUmVzdWx0BQxwcm9sb2dSZXN1bHQFC3N0YXRzUmVzdWx0AWkBGXNlbGxSZXNvdXJjZXNMYW5kRGVsaXZlcnkEB2Ftb3VudHMJbWluUHJpY2VzC2xhbmRBc3NldElkEGZhY3RvcnlDb250aW5lbnQDCQEBIQEFEUtTX0FMTE9XX0RFTElWRVJZCQACAQIfRGVsaXZlcnkgZmVhdHVyZSBpcyB0dXJuZWQgb2ZmIQQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECKnNlbGxSZXNvdXJjZXMgZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50cwQEdXNlcggFAWkGY2FsbGVyBARhZGRyCQClCAEFBHVzZXIEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkxBTkRQUkVGSVgCDSBpcyBub3QgeW91cnMEAndoCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIUZ2V0V2FyZWhvdXNlUkVBRE9OTFkJAMwIAgULbGFuZEFzc2V0SWQFA25pbAUDbmlsBAljdXJyZW50V2gJALwJAgUCd2gCAToEB3Jlc0xpc3QJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfBA0kdDAyOTM4NTI5NTA2CQETc2VsbFJlc291cmNlc0NvbW1vbgQFB3Jlc0xpc3QFEGZhY3RvcnlDb250aW5lbnQFB2Ftb3VudHMFCW1pblByaWNlcwQOZmFjdG9yeUFjdGlvbnMIBQ0kdDAyOTM4NTI5NTA2Al8xBAZuZXdSZXMIBQ0kdDAyOTM4NTI5NTA2Al8yBAx1c2R0UmVjZWl2ZWQIBQ0kdDAyOTM4NTI5NTA2Al8zBAh0b3RhbFJlcwgFDSR0MDI5Mzg1Mjk1MDYCXzQEBXdoU3RyCQC6CQIJAMwIAgkAkQMCBQljdXJyZW50V2gFC3doSWR4TGV2ZWxzCQDMCAIJALkJAgUGbmV3UmVzAgFfCQDMCAIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAkAzAgCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kCQDMCAIJAJEDAgUJY3VycmVudFdoBQl3aElkeExPRlQFA25pbAIBOgQGd2hTYXZlCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAINc2F2ZVdhcmVob3VzZQkAzAgCBQV3aFN0cgkAzAgCBQtsYW5kQXNzZXRJZAUDbmlsBQNuaWwEC3N0YXRzUmVzdWx0CQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAkAzAgCBQRhZGRyCQDMCAIJAGsDBQd4cFRyYWRlBQh0b3RhbFJlcwUFTVVMVDgFA25pbAUDbmlsBAdmZWVQYXJ0CQBrAwUMdXNkdFJlY2VpdmVkBQxERUxJVkVSWV9GRUUFBU1VTFQ2BANmZWUDCQBmAgUVTUlOX1VTRFRfRkVFX0RFTElWRVJZBQdmZWVQYXJ0BRVNSU5fVVNEVF9GRUVfREVMSVZFUlkFB2ZlZVBhcnQEEGFjdGl2aXRpZXNBbW91bnQJAGkCBQx1c2R0UmVjZWl2ZWQAZAMJAGcCBQNmZWUJAGUCBQx1c2R0UmVjZWl2ZWQFEGFjdGl2aXRpZXNBbW91bnQJAAIBCQCsAgICK1RoaXMgdHJhZGUgZG9lcyBub3QgY292ZXIgZGVsaXZlcnkgY29zdCBvZiAJAQpmaXhlZFBvaW50AgUDZmVlAAYECWZ1bmRUb3RhbAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ9kZWxpdmVyeUZ1bmRLZXkAAAkAlAoCCQDNCAIJAM0IAgkAzQgCBQ5mYWN0b3J5QWN0aW9ucwkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQBlAgkAZQIFDHVzZHRSZWNlaXZlZAUQYWN0aXZpdGllc0Ftb3VudAUDZmVlBQt1c2R0QXNzZXRJZAkBDEludGVnZXJFbnRyeQIFD2RlbGl2ZXJ5RnVuZEtleQkAZAIFCWZ1bmRUb3RhbAUDZmVlCQEOU2NyaXB0VHJhbnNmZXIDBQxyZXN0Q29udHJhY3QFEGFjdGl2aXRpZXNBbW91bnQFC3VzZHRBc3NldElkCQCVCgMFBndoU2F2ZQUMcHJvbG9nUmVzdWx0BQtzdGF0c1Jlc3VsdAFpAQxidXlNYXRlcmlhbHMCB2Ftb3VudHMJbWF4UHJpY2VzBAxwcm9sb2dSZXN1bHQJAQZwcm9sb2cABAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQDYW10CAUDcG10BmFtb3VudAMDCQEBIQEJAQlpc0RlZmluZWQBCAUDcG10B2Fzc2V0SWQGCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQITVVNEVCBwYXltZW50cyBvbmx5IQQLY3VyTG9jYXRpb24JALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OAgFfAwkBAiE9AgkAkQMCBQtjdXJMb2NhdGlvbgUKbG9jSWR4VHlwZQIBRgkAAgEJAKwCAgItRHVjayBsb2NhdGlvbiB0eXBlIHNob3VsZCBiZSBGYWN0b3J5LCBidXQgaXMgCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEB21hdExpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8EDSR0MDMxMzc0MzE0OTYJARJidXlNYXRlcmlhbHNDb21tb24EBQdtYXRMaXN0CQCRAwIFC2N1ckxvY2F0aW9uBQhsb2NJZHhJZAUHYW1vdW50cwUJbWF4UHJpY2VzBA5mYWN0b3J5QWN0aW9ucwgFDSR0MDMxMzc0MzE0OTYCXzEEBm5ld01hdAgFDSR0MDMxMzc0MzE0OTYCXzIECXVzZHRTcGVudAgFDSR0MDMxMzc0MzE0OTYCXzMECHRvdGFsTWF0CAUNJHQwMzEzNzQzMTQ5NgJfNAMJAGYCBQl1c2R0U3BlbnQFA2FtdAkAAgEJAKwCAgkArAICCQCsAgICH0luc3VmZmljaWVudCBwYXltZW50ISBBdHRhY2hlZD0JAQpmaXhlZFBvaW50AgUDYW10AAYCCywgcmVxdWlyZWQ9CQEKZml4ZWRQb2ludAIFCXVzZHRTcGVudAAGBAduZXdQYWNrCQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwkAzAgCCQC5CQIFBm5ld01hdAIBXwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgQOYmFja3BhY2tSZXN1bHQJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag51cGRhdGVCYWNrcGFjawkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCBQduZXdQYWNrBQNuaWwFA25pbAQEcmVzdAMJAGYCCQBlAgUDYW10BQl1c2R0U3BlbnQAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAGUCBQNhbXQFCXVzZHRTcGVudAULdXNkdEFzc2V0SWQFA25pbAUDbmlsBBBhY3Rpdml0aWVzQW1vdW50CQBpAgUJdXNkdFNwZW50AGQEC3N0YXRzUmVzdWx0CQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIPdXBkYXRlRHVja1N0YXRzCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIJAGsDBQd4cFRyYWRlBQh0b3RhbE1hdAUFTVVMVDgFA25pbAUDbmlsCQCUCgIJAM0IAgkAzggCBQ5mYWN0b3J5QWN0aW9ucwUEcmVzdAkBDlNjcmlwdFRyYW5zZmVyAwUMcmVzdENvbnRyYWN0BRBhY3Rpdml0aWVzQW1vdW50BQt1c2R0QXNzZXRJZAkAlQoDBQ5iYWNrcGFja1Jlc3VsdAUMcHJvbG9nUmVzdWx0BQtzdGF0c1Jlc3VsdAFpARhidXlNYXRlcmlhbHNEdWNrRGVsaXZlcnkDB2Ftb3VudHMJbWF4UHJpY2VzEGZhY3RvcnlDb250aW5lbnQDCQEBIQEFEUtTX0FMTE9XX0RFTElWRVJZCQACAQIfRGVsaXZlcnkgZmVhdHVyZSBpcyB0dXJuZWQgb2ZmIQQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEA2FtdAgFA3BtdAZhbW91bnQDAwkBASEBCQEJaXNEZWZpbmVkAQgFA3BtdAdhc3NldElkBgkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkBQt1c2R0QXNzZXRJZAkAAgECE1VTRFQgcGF5bWVudHMgb25seSEEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQHbWF0TGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQNJHQwMzMwMTQzMzEzMQkBEmJ1eU1hdGVyaWFsc0NvbW1vbgQFB21hdExpc3QFEGZhY3RvcnlDb250aW5lbnQFB2Ftb3VudHMFCW1heFByaWNlcwQOZmFjdG9yeUFjdGlvbnMIBQ0kdDAzMzAxNDMzMTMxAl8xBAZuZXdNYXQIBQ0kdDAzMzAxNDMzMTMxAl8yBAl1c2R0U3BlbnQIBQ0kdDAzMzAxNDMzMTMxAl8zBAh0b3RhbE1hdAgFDSR0MDMzMDE0MzMxMzECXzQEB25ld1BhY2sJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQDMCAIJALkJAgUGbmV3TWF0AgFfCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6BA5iYWNrcGFja1Jlc3VsdAkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCDnVwZGF0ZUJhY2twYWNrCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIFB25ld1BhY2sFA25pbAUDbmlsBAtzdGF0c1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCD3VwZGF0ZUR1Y2tTdGF0cwkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCCQBrAwUHeHBUcmFkZQUIdG90YWxNYXQFBU1VTFQ4BQNuaWwFA25pbAQHZmVlUGFydAkAawMFCXVzZHRTcGVudAUMREVMSVZFUllfRkVFBQVNVUxUNgQDZmVlAwkAZgIFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQUHZmVlUGFydAUVTUlOX1VTRFRfRkVFX0RFTElWRVJZBQdmZWVQYXJ0BBB1c2R0U3BlbnRXaXRoRmVlCQBkAgUJdXNkdFNwZW50BQNmZWUDCQBmAgUQdXNkdFNwZW50V2l0aEZlZQUDYW10CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIfSW5zdWZmaWNpZW50IHBheW1lbnQhIEF0dGFjaGVkPQkBCmZpeGVkUG9pbnQCBQNhbXQABgILLCByZXF1aXJlZD0JAQpmaXhlZFBvaW50AgUJdXNkdFNwZW50AAYCASsJAQpmaXhlZFBvaW50AgUDZmVlAAYCDihkZWxpdmVyeSBmZWUpBARyZXN0AwkAZgIJAGUCBQNhbXQFEHVzZHRTcGVudFdpdGhGZWUAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAGUCBQNhbXQFEHVzZHRTcGVudFdpdGhGZWUFC3VzZHRBc3NldElkBQNuaWwFA25pbAQQYWN0aXZpdGllc0Ftb3VudAkAaQIFCXVzZHRTcGVudABkBAlmdW5kVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUPZGVsaXZlcnlGdW5kS2V5AAAJAJQKAgkAzQgCCQDNCAIJAM4IAgUOZmFjdG9yeUFjdGlvbnMFBHJlc3QJAQ5TY3JpcHRUcmFuc2ZlcgMFDHJlc3RDb250cmFjdAUQYWN0aXZpdGllc0Ftb3VudAULdXNkdEFzc2V0SWQJAQxJbnRlZ2VyRW50cnkCBQ9kZWxpdmVyeUZ1bmRLZXkJAGQCBQlmdW5kVG90YWwFA2ZlZQkAlQoDBQ5iYWNrcGFja1Jlc3VsdAUMcHJvbG9nUmVzdWx0BQtzdGF0c1Jlc3VsdAFpARhidXlNYXRlcmlhbHNMYW5kRGVsaXZlcnkEB2Ftb3VudHMJbWF4UHJpY2VzC2xhbmRBc3NldElkEGZhY3RvcnlDb250aW5lbnQDCQEBIQEFEUtTX0FMTE9XX0RFTElWRVJZCQACAQIfRGVsaXZlcnkgZmVhdHVyZSBpcyB0dXJuZWQgb2ZmIQQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABANhbXQIBQNwbXQGYW1vdW50AwMJAQEhAQkBCWlzRGVmaW5lZAEIBQNwbXQHYXNzZXRJZAYJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhNVU0RUIHBheW1lbnRzIG9ubHkhBAR1c2VyCAUBaQZjYWxsZXIEBGFkZHIJAKUIAQUEdXNlcgQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEJAJoIAgUPc3Rha2luZ0NvbnRyYWN0CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQCd2gJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0AhRnZXRXYXJlaG91c2VSRUFET05MWQkAzAgCBQtsYW5kQXNzZXRJZAUDbmlsBQNuaWwECWN1cnJlbnRXaAkAvAkCBQJ3aAIBOgQHbWF0TGlzdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhNYXQCAV8EDSR0MDM1NDA5MzU1MjYJARJidXlNYXRlcmlhbHNDb21tb24EBQdtYXRMaXN0BRBmYWN0b3J5Q29udGluZW50BQdhbW91bnRzBQltYXhQcmljZXMEDmZhY3RvcnlBY3Rpb25zCAUNJHQwMzU0MDkzNTUyNgJfMQQGbmV3TWF0CAUNJHQwMzU0MDkzNTUyNgJfMgQJdXNkdFNwZW50CAUNJHQwMzU0MDkzNTUyNgJfMwQIdG90YWxNYXQIBQ0kdDAzNTQwOTM1NTI2Al80BAV3aFN0cgkAugkCCQDMCAIJAJEDAgUJY3VycmVudFdoBQt3aElkeExldmVscwkAzAgCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMJAMwIAgkAuQkCBQZuZXdNYXQCAV8JAMwIAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAkAzAgCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhMT0ZUBQNuaWwCAToEBndoU2F2ZQkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCDXNhdmVXYXJlaG91c2UJAMwIAgUFd2hTdHIJAMwIAgULbGFuZEFzc2V0SWQFA25pbAUDbmlsBAtzdGF0c1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCFnVwZGF0ZUFjY1N0YXRzSW50ZXJuYWwJAMwIAgUEYWRkcgkAzAgCCQBrAwUHeHBUcmFkZQUIdG90YWxNYXQFBU1VTFQ4BQNuaWwFA25pbAQHZmVlUGFydAkAawMFCXVzZHRTcGVudAUMREVMSVZFUllfRkVFBQVNVUxUNgQDZmVlAwkAZgIFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQUHZmVlUGFydAUVTUlOX1VTRFRfRkVFX0RFTElWRVJZBQdmZWVQYXJ0BBB1c2R0U3BlbnRXaXRoRmVlCQBkAgUJdXNkdFNwZW50BQNmZWUDCQBmAgUQdXNkdFNwZW50V2l0aEZlZQUDYW10CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIfSW5zdWZmaWNpZW50IHBheW1lbnQhIEF0dGFjaGVkPQkBCmZpeGVkUG9pbnQCBQNhbXQABgILLCByZXF1aXJlZD0JAQpmaXhlZFBvaW50AgUJdXNkdFNwZW50AAYCASsJAQpmaXhlZFBvaW50AgUDZmVlAAYCDihkZWxpdmVyeSBmZWUpBARyZXN0AwkAZgIJAGUCBQNhbXQFEHVzZHRTcGVudFdpdGhGZWUAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAGUCBQNhbXQFEHVzZHRTcGVudFdpdGhGZWUFC3VzZHRBc3NldElkBQNuaWwFA25pbAQQYWN0aXZpdGllc0Ftb3VudAkAaQIFCXVzZHRTcGVudABkBAlmdW5kVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUPZGVsaXZlcnlGdW5kS2V5AAAJAJQKAgkAzQgCCQDNCAIJAM4IAgUOZmFjdG9yeUFjdGlvbnMFBHJlc3QJAQ5TY3JpcHRUcmFuc2ZlcgMFDHJlc3RDb250cmFjdAUQYWN0aXZpdGllc0Ftb3VudAULdXNkdEFzc2V0SWQJAQxJbnRlZ2VyRW50cnkCBQ9kZWxpdmVyeUZ1bmRLZXkJAGQCBQlmdW5kVG90YWwFA2ZlZQkAlQoDBQZ3aFNhdmUFDHByb2xvZ1Jlc3VsdAULc3RhdHNSZXN1bHQBaQERZXhjaGFuZ2VSZXNvdXJjZXMBB2Ftb3VudHMEDHByb2xvZ1Jlc3VsdAkBBnByb2xvZwAEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABANhbXQIBQNwbXQGYW1vdW50AwMJAQEhAQkBCWlzRGVmaW5lZAEIBQNwbXQHYXNzZXRJZAYJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhNVU0RUIHBheW1lbnRzIG9ubHkhBAtjdXJMb2NhdGlvbgkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04CAV8DCQECIT0CCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlAgFGCQACAQkArAICAi1EdWNrIGxvY2F0aW9uIHR5cGUgc2hvdWxkIGJlIEZhY3RvcnksIGJ1dCBpcyAJAJEDAgULY3VyTG9jYXRpb24FCmxvY0lkeFR5cGUEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQHcmVzTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwQHbWF0TGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQNJHQwMzc2NDgzNzc1NAkBF2V4Y2hhbmdlUmVzb3VyY2VzQ29tbW9uAwUHcmVzTGlzdAUHbWF0TGlzdAUHYW1vdW50cwQGbmV3UmVzCAUNJHQwMzc2NDgzNzc1NAJfMQQGbmV3TWF0CAUNJHQwMzc2NDgzNzc1NAJfMgQJdXNkdFNwZW50CAUNJHQwMzc2NDgzNzc1NAJfMwQUdG90YWxBbW91bnRDb252ZXJ0ZWQIBQ0kdDAzNzY0ODM3NzU0Al80AwkAZgIFCXVzZHRTcGVudAUDYW10CQACAQkArAICCQCsAgIJAKwCAgIfSW5zdWZmaWNpZW50IHBheW1lbnQhIEF0dGFjaGVkPQkBCmZpeGVkUG9pbnQCBQNhbXQABgILLCByZXF1aXJlZD0JAQpmaXhlZFBvaW50AgUJdXNkdFNwZW50AAYEB25ld1BhY2sJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJALkJAgUGbmV3UmVzAgFfCQDMCAIJALkJAgUGbmV3TWF0AgFfCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6BA5iYWNrcGFja1Jlc3VsdAkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCDnVwZGF0ZUJhY2twYWNrCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIFB25ld1BhY2sFA25pbAUDbmlsBARyZXN0AwkAZgIJAGUCBQNhbXQFCXVzZHRTcGVudAAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgkAZQIFA2FtdAUJdXNkdFNwZW50BQt1c2R0QXNzZXRJZAUDbmlsBQNuaWwEEGFjdGl2aXRpZXNBbW91bnQJAGkCBQl1c2R0U3BlbnQAZAQLc3RhdHNSZXN1bHQJAQVhc0ludAEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag91cGRhdGVEdWNrU3RhdHMJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgkAawMFB3hwVHJhZGUFFHRvdGFsQW1vdW50Q29udmVydGVkBQVNVUxUOAUDbmlsBQNuaWwJAJQKAgkAzQgCBQRyZXN0CQEOU2NyaXB0VHJhbnNmZXIDBQxyZXN0Q29udHJhY3QFEGFjdGl2aXRpZXNBbW91bnQFC3VzZHRBc3NldElkCQCVCgMFDmJhY2twYWNrUmVzdWx0BQxwcm9sb2dSZXN1bHQFC3N0YXRzUmVzdWx0AWkBHWV4Y2hhbmdlUmVzb3VyY2VzRHVja0RlbGl2ZXJ5AQdhbW91bnRzBAxwcm9sb2dSZXN1bHQJAQZwcm9sb2cABAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQDYW10CAUDcG10BmFtb3VudAMDCQEBIQEJAQlpc0RlZmluZWQBCAUDcG10B2Fzc2V0SWQGCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQITVVNEVCBwYXltZW50cyBvbmx5IQQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAdyZXNMaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzAgFfBAdtYXRMaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBA0kdDAzOTE4OTM5Mjk1CQEXZXhjaGFuZ2VSZXNvdXJjZXNDb21tb24DBQdyZXNMaXN0BQdtYXRMaXN0BQdhbW91bnRzBAZuZXdSZXMIBQ0kdDAzOTE4OTM5Mjk1Al8xBAZuZXdNYXQIBQ0kdDAzOTE4OTM5Mjk1Al8yBAl1c2R0U3BlbnQIBQ0kdDAzOTE4OTM5Mjk1Al8zBBR0b3RhbEFtb3VudENvbnZlcnRlZAgFDSR0MDM5MTg5MzkyOTUCXzQEB2ZlZVBhcnQJAGsDBQl1c2R0U3BlbnQFDkRFTElWRVJZX0ZFRTE1BQVNVUxUNgQDZmVlAwkAZgIFF01JTl9VU0RUX0ZFRV9ERUxJVkVSWTE1BQdmZWVQYXJ0BRdNSU5fVVNEVF9GRUVfREVMSVZFUlkxNQUHZmVlUGFydAQQdXNkdFNwZW50V2l0aEZlZQkAZAIFCXVzZHRTcGVudAUDZmVlAwkAZgIFEHVzZHRTcGVudFdpdGhGZWUFA2FtdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICH0luc3VmZmljaWVudCBwYXltZW50ISBBdHRhY2hlZD0JAQpmaXhlZFBvaW50AgUDYW10AAYCCywgcmVxdWlyZWQ9CQEKZml4ZWRQb2ludAIFCXVzZHRTcGVudAAGAgErCQEKZml4ZWRQb2ludAIFA2ZlZQAGAg4oZGVsaXZlcnkgZmVlKQQHbmV3UGFjawkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAuQkCBQZuZXdSZXMCAV8JAMwIAgkAuQkCBQZuZXdNYXQCAV8JAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwCAToEDmJhY2twYWNrUmVzdWx0CQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQmFja3BhY2sJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUHbmV3UGFjawUDbmlsBQNuaWwEBHJlc3QDCQBmAgkAZQIFA2FtdAUQdXNkdFNwZW50V2l0aEZlZQAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgkAZQIFA2FtdAUQdXNkdFNwZW50V2l0aEZlZQULdXNkdEFzc2V0SWQFA25pbAUDbmlsBBBhY3Rpdml0aWVzQW1vdW50CQBpAgUJdXNkdFNwZW50AGQEC3N0YXRzUmVzdWx0CQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIPdXBkYXRlRHVja1N0YXRzCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIJAGsDBQd4cFRyYWRlBRR0b3RhbEFtb3VudENvbnZlcnRlZAUFTVVMVDgFA25pbAUDbmlsBAlmdW5kVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUPZGVsaXZlcnlGdW5kS2V5AAAJAJQKAgkAzQgCCQDNCAIFBHJlc3QJAQ5TY3JpcHRUcmFuc2ZlcgMFDHJlc3RDb250cmFjdAUQYWN0aXZpdGllc0Ftb3VudAULdXNkdEFzc2V0SWQJAQxJbnRlZ2VyRW50cnkCBQ9kZWxpdmVyeUZ1bmRLZXkJAGQCBQlmdW5kVG90YWwFA2ZlZQkAlQoDBQ5iYWNrcGFja1Jlc3VsdAUMcHJvbG9nUmVzdWx0BQtzdGF0c1Jlc3VsdAFpAR1leGNoYW5nZVJlc291cmNlc0xhbmREZWxpdmVyeQIHYW1vdW50cwtsYW5kQXNzZXRJZAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABANhbXQIBQNwbXQGYW1vdW50AwMJAQEhAQkBCWlzRGVmaW5lZAEIBQNwbXQHYXNzZXRJZAYJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhNVU0RUIHBheW1lbnRzIG9ubHkhBAR1c2VyCAUBaQZjYWxsZXIEBGFkZHIJAKUIAQUEdXNlcgQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEJAJoIAgUPc3Rha2luZ0NvbnRyYWN0CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQCd2gJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0AhRnZXRXYXJlaG91c2VSRUFET05MWQkAzAgCBQtsYW5kQXNzZXRJZAUDbmlsBQNuaWwECWN1cnJlbnRXaAkAvAkCBQJ3aAIBOgQHcmVzTGlzdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8EB21hdExpc3QJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4TWF0AgFfBA0kdDA0MTUxODQxNjI0CQEXZXhjaGFuZ2VSZXNvdXJjZXNDb21tb24DBQdyZXNMaXN0BQdtYXRMaXN0BQdhbW91bnRzBAZuZXdSZXMIBQ0kdDA0MTUxODQxNjI0Al8xBAZuZXdNYXQIBQ0kdDA0MTUxODQxNjI0Al8yBAl1c2R0U3BlbnQIBQ0kdDA0MTUxODQxNjI0Al8zBBR0b3RhbEFtb3VudENvbnZlcnRlZAgFDSR0MDQxNTE4NDE2MjQCXzQEBXdoU3RyCQC6CQIJAMwIAgkAkQMCBQljdXJyZW50V2gFC3doSWR4TGV2ZWxzCQDMCAIJALkJAgUGbmV3UmVzAgFfCQDMCAIJALkJAgUGbmV3TWF0AgFfCQDMCAIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QJAMwIAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4TE9GVAUDbmlsAgE6BAZ3aFNhdmUJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag1zYXZlV2FyZWhvdXNlCQDMCAIFBXdoU3RyCQDMCAIFC2xhbmRBc3NldElkBQNuaWwFA25pbAQLc3RhdHNSZXN1bHQJAQVhc0ludAEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0AhZ1cGRhdGVBY2NTdGF0c0ludGVybmFsCQDMCAIFBGFkZHIJAMwIAgkAawMFB3hwVHJhZGUFFHRvdGFsQW1vdW50Q29udmVydGVkBQVNVUxUOAUDbmlsBQNuaWwEB2ZlZVBhcnQJAGsDBQl1c2R0U3BlbnQFDkRFTElWRVJZX0ZFRTE1BQVNVUxUNgQDZmVlAwkAZgIFF01JTl9VU0RUX0ZFRV9ERUxJVkVSWTE1BQdmZWVQYXJ0BRdNSU5fVVNEVF9GRUVfREVMSVZFUlkxNQUHZmVlUGFydAQQdXNkdFNwZW50V2l0aEZlZQkAZAIFCXVzZHRTcGVudAUDZmVlAwkAZgIFEHVzZHRTcGVudFdpdGhGZWUFA2FtdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICH0luc3VmZmljaWVudCBwYXltZW50ISBBdHRhY2hlZD0JAQpmaXhlZFBvaW50AgUDYW10AAYCCywgcmVxdWlyZWQ9CQEKZml4ZWRQb2ludAIFCXVzZHRTcGVudAAGAgErCQEKZml4ZWRQb2ludAIFA2ZlZQAGAg4oZGVsaXZlcnkgZmVlKQQEcmVzdAMJAGYCCQBlAgUDYW10BRB1c2R0U3BlbnRXaXRoRmVlAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQBlAgUDYW10BRB1c2R0U3BlbnRXaXRoRmVlBQt1c2R0QXNzZXRJZAUDbmlsBQNuaWwEEGFjdGl2aXRpZXNBbW91bnQJAGkCBQl1c2R0U3BlbnQAZAQJZnVuZFRvdGFsCQELdmFsdWVPckVsc2UCCQCfCAEFD2RlbGl2ZXJ5RnVuZEtleQAACQCUCgIJAM0IAgkAzQgCBQRyZXN0CQEOU2NyaXB0VHJhbnNmZXIDBQxyZXN0Q29udHJhY3QFEGFjdGl2aXRpZXNBbW91bnQFC3VzZHRBc3NldElkCQEMSW50ZWdlckVudHJ5AgUPZGVsaXZlcnlGdW5kS2V5CQBkAgUJZnVuZFRvdGFsBQNmZWUJAJUKAwUGd2hTYXZlBQxwcm9sb2dSZXN1bHQFC3N0YXRzUmVzdWx0AWkBCmNyYWZ0R29vZHMCCnByb2R1Y3RJZHgIcXVhbnRpdHkEDHByb2xvZ1Jlc3VsdAkBBnByb2xvZwADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQDYW10CAUDcG10BmFtb3VudAQKcG10QXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCAUDcG10B2Fzc2V0SWQCHldBVkVTIGNhbid0IGJlIHVzZWQgYXMgcGF5bWVudAMJAQIhPQIFCnBtdEFzc2V0SWQFC3VzZHRBc3NldElkCQACAQITVVNEVCBwYXltZW50cyBvbmx5IQMJAQIhPQIFA2FtdAUFTVVMVDYJAAIBAipleGFjdGx5IDEgVVNEVCBtdXN0IGJlIGF0dGFjaGVkIGFzIHBheW1lbnQDCQBnAgAABQhxdWFudGl0eQkAAgECG1F1YW50aXR5IHNob3VsZCBiZSBwb3NpdGl2ZQQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04CAV8DCQECIT0CCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlAgFNCQACAQkArAICAjFEdWNrIGxvY2F0aW9uIHR5cGUgc2hvdWxkIGJlIE1hbnVmYWN0b3J5LCBidXQgaXMgCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlBARjb250CQCRAwIFC2N1ckxvY2F0aW9uBQ9sb2NJZHhDb250aW5lbnQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQHbWF0TGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwMDCQBmAgAABQpwcm9kdWN0SWR4BgkAZwIFCnByb2R1Y3RJZHgJAJADAQUQcHJvZHVjdGlvbk1hdHJpeAkAAgEJAKwCAgIUVW5rbm93biBwcm9kdWN0IGlkeD0JAKQDAQUKcHJvZHVjdElkeAQGcmVjaXBlCQC1CQIJAJEDAgUQcHJvZHVjdGlvbk1hdHJpeAUKcHJvZHVjdElkeAIBXwMJAQIhPQIJAJADAQUGcmVjaXBlBQpSRUNJUEVTSVpFCQACAQkArAICAhdGYXRhbDogdW5rbm93biByZWNpcGU6IAkAkQMCBRBwcm9kdWN0aW9uTWF0cml4BQpwcm9kdWN0SWR4BA5wcm9kdWN0Q29udElkeAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnJlY2lwZQUNcklkeENvbnRpbmVudAMJAQIhPQIJAJEDAgUKY29udGluZW50cwUOcHJvZHVjdENvbnRJZHgFBGNvbnQJAAIBCQCsAgIJAKwCAgkArAICAh1UaGlzIHByb2R1Y3QgaXMgYXZhaWxhYmxlIGluIAkAkQMCBQpjb250aW5lbnRzBQ5wcm9kdWN0Q29udElkeAIRLCBidXQgeW91IGFyZSBpbiAFBGNvbnQECHByb2RMaXN0AwkAAAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIABQNuaWwJALwJAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgFfCgEGZmlsbGVyAgNhY2MLaWdub3JlZEl0ZW0EAW4IBQNhY2MCXzIEAnhzAwkAZgIJAJADAQUIcHJvZExpc3QFAW4JAJEDAgUIcHJvZExpc3QFAW4CATAEAXgJAQ1wYXJzZUludFZhbHVlAQUCeHMEBmFtb3VudAkAaAIFCHF1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QmFja3BhY2sJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUHbmV3UGFjawUDbmlsBQNuaWwEC3N0YXRzUmVzdWx0CQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIPdXBkYXRlRHVja1N0YXRzCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIJAGsDBQd4cENyYWZ0CAUGbWVyZ2VkAl8yBQVNVUxUOAUDbmlsBQNuaWwJAJQKAgUDbmlsCQCVCgMFBnJlc3VsdAUMcHJvbG9nUmVzdWx0BQtzdGF0c1Jlc3VsdAFpARFzZXRXYXJlaG91c2VPcmRlcgILbmV3T3JkZXJTdHILbGFuZEFzc2V0SWQEBHVzZXIIBQFpDG9yaWdpbkNhbGxlcgQEYWRkcgkApQgBBQR1c2VyBAZyZXN1bHQDCQECIT0CBQR1c2VyBQxyZXN0Q29udHJhY3QJAQxjaGVja0Jsb2NrZWQABwQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEJAJoIAgUPc3Rha2luZ0NvbnRyYWN0CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDAwkBAiE9AgUEdXNlcgUMcmVzdENvbnRyYWN0CQECIT0CBQVvd25lcgUEYWRkcgcJAAIBCQCsAgIFCkxBTkRQUkVGSVgCDSBpcyBub3QgeW91cnMECG5ld09yZGVyCQC8CQIFC25ld09yZGVyU3RyAgE6BAJ3aAkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCFGdldFdhcmVob3VzZVJFQURPTkxZCQDMCAIFC2xhbmRBc3NldElkBQNuaWwFA25pbAQJY3VycmVudFdoCQC8CQIFAndoAgE6BARsb2Z0CQC1CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeExPRlQCAV8EB3doVG90YWwJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQh2b2xUb3RhbAQGb3JkS2V5CQEOa2V5T3JkZXJCeUxhbmQBBQtsYW5kQXNzZXRJZAQKY3VycmVudE9yZAkBCGdldE9yZGVyAQUGb3JkS2V5BAF6CQELc2V0SW50ZXJuYWwDBQljdXJyZW50V2gFCmN1cnJlbnRPcmQFCG5ld09yZGVyBAtidXlWb2xTYWxkbwgFAXoCXzQEDHNlbGxWb2xTYWxkbwgFAXoCXzUECndoT2NjdXBpZWQIBQF6Al83BAh3aExvY2tlZAkAZAIFC2J1eVZvbFNhbGRvBQxzZWxsVm9sU2FsZG8EBndoRnJlZQkAZQIJAGUCBQd3aFRvdGFsBQp3aE9jY3VwaWVkBQh3aExvY2tlZAMJAGYCAAAFBndoRnJlZQkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICE0F0dGVtcHQgdG8gcmVzZXJ2ZSAJAKQDAQULYnV5Vm9sU2FsZG8CGyBzcGFjZSBmb3IgYnV5IG9yZGVycywgYW5kIAkApAMBBQxzZWxsVm9sU2FsZG8CJSBzcGFjZSBmb3Igc2VsbCBvcmRlcnMgKGFuZCBvY2N1cGllZD0JAKQDAQUKd2hPY2N1cGllZAIfKSwgbGVhZHMgdG8gbmVnYXRpdmUgZnJlZSBzcGFjZQQFd2hTdHIJALoJAgkAzAgCCQCRAwIFCWN1cnJlbnRXaAULd2hJZHhMZXZlbHMJAMwIAgkAuQkCCAUBegJfMQIBXwkAzAgCCQC5CQIIBQF6Al8yAgFfCQDMCAIJALoJAggFAXoCXzMCAV8JAMwIAgkApAMBBQh3aExvY2tlZAUDbmlsAgE6BAZ3aFNhdmUJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag1zYXZlV2FyZWhvdXNlCQDMCAIFBXdoU3RyCQDMCAIFC2xhbmRBc3NldElkBQNuaWwFA25pbAQIdXNkU2FsZG8IBQF6Al82BAdhY3Rpb25zAwkAZgIFCHVzZFNhbGRvAAADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQDYW10CAUDcG10BmFtb3VudAQKcG10QXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCAUDcG10B2Fzc2V0SWQCHldBVkVTIGNhbid0IGJlIHVzZWQgYXMgcGF5bWVudAMJAQIhPQIFCnBtdEFzc2V0SWQFC3VzZHRBc3NldElkCQACAQITVVNEVCBwYXltZW50cyBvbmx5IQMJAQIhPQIFA2FtdAUIdXNkU2FsZG8JAAIBCQCsAgICElBheW1lbnQgbmVlZGVkIGlzIAkApAMBBQh1c2RTYWxkbwkAzAgCCQELU3RyaW5nRW50cnkCBQZvcmRLZXkFC25ld09yZGVyU3RyBQNuaWwDCQAAAgUIdXNkU2FsZG8AAAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECEk5vIHBheW1lbnRzIG5lZWRlZAkAzAgCCQELU3RyaW5nRW50cnkCBQZvcmRLZXkFC25ld09yZGVyU3RyBQNuaWwDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhJObyBwYXltZW50cyBuZWVkZWQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUFb3duZXIJAQEtAQUIdXNkU2FsZG8FC3VzZHRBc3NldElkCQDMCAIJAQtTdHJpbmdFbnRyeQIFBm9yZEtleQULbmV3T3JkZXJTdHIFA25pbAkAlAoCBQdhY3Rpb25zCQCUCgIFBnJlc3VsdAUGd2hTYXZlAWkBFGFjY2VwdFdhcmVob3VzZU9yZGVyAwpicE9yZGVyU3RyD3Nob3BMYW5kQXNzZXRJZAtkdWNrQXNzZXRJZAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAQGY2FsbGVyCAUBaQxvcmlnaW5DYWxsZXIECmNhbGxlckFkZHIJAKUIAQUGY2FsbGVyBBFzdGFrZWREdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUKY2FsbGVyQWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEPa2V5RHVja0xvY2F0aW9uAQURc3Rha2VkRHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgQDbG9jCQC1CQIJAQV2YWx1ZQEFC2N1ckxvY2F0aW9uAgFfAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUwJAAIBCQCsAgIJAKwCAgIWRHVjayBsb2NhdGlvbiB0eXBlIGlzIAkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCESwgYnV0IHNob3VsZCBiZSBMAwkBAiE9AgURc3Rha2VkRHVja0Fzc2V0SWQFC2R1Y2tBc3NldElkCQACAQkArAICCQCsAgIJAKwCAgIUWW91ciBzdGFrZWQgZHVjayBpcyAFEXN0YWtlZER1Y2tBc3NldElkAg0sIGJ1dCBwYXNzZWQgBQtkdWNrQXNzZXRJZAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkECWJwUmVzTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwQJYnBNYXRMaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBApicFByb2RMaXN0AwkAAAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIABQNuaWwJALwJAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgFfBA0kdDA1MTE0NDUxMzg0CQEVYWNjZXB0U2hvcE9yZGVyQ29tbW9uBgUPc2hvcExhbmRBc3NldElkBQpjYWxsZXJBZGRyBQpicE9yZGVyU3RyBQlicFJlc0xpc3QFCWJwTWF0TGlzdAUKYnBQcm9kTGlzdAQKc2hvcEFjdGlvbggFDSR0MDUxMTQ0NTEzODQCXzEECm5ld1VzZXJSZXMIBQ0kdDA1MTE0NDUxMzg0Al8yBApuZXdVc2VyTWF0CAUNJHQwNTExNDQ1MTM4NAJfMwQLbmV3VXNlclByb2QIBQ0kdDA1MTE0NDUxMzg0Al80BA11c2RXaDJCcFNhbGRvCAUNJHQwNTExNDQ1MTM4NAJfNQQNdXNkQnAyV2hTYWxkbwgFDSR0MDUxMTQ0NTEzODQCXzYECHhwQW1vdW50CAUNJHQwNTExNDQ1MTM4NAJfNwQNc2hvcExhbmRPd25lcggFDSR0MDUxMTQ0NTEzODQCXzgECnNob3BXaFNhdmUIBQ0kdDA1MTE0NDUxMzg0Al85BA5hY2NTdGF0c1Jlc3VsdAgFDSR0MDUxMTQ0NTEzODQDXzEwBAhhY3Rpb25zMQkAzAgCBQpzaG9wQWN0aW9uCQEQc2hvcDJ1c2VyQWN0aW9ucwMFDXVzZFdoMkJwU2FsZG8FCmNhbGxlckFkZHIAAAQIYWN0aW9uczIJARB1c2VyMnNob3BBY3Rpb25zBAUNdXNkQnAyV2hTYWxkbwgFAWkIcGF5bWVudHMFDXNob3BMYW5kT3duZXIAAAQIbmV3QnBTdHIJALoJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJALkJAgUKbmV3VXNlclJlcwIBXwkAzAgCCQC5CQIFCm5ld1VzZXJNYXQCAV8JAMwIAgkAugkCBQtuZXdVc2VyUHJvZAIBXwUDbmlsAgE6BAZicFNhdmUJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag51cGRhdGVCYWNrcGFjawkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCBQhuZXdCcFN0cgUDbmlsBQNuaWwED2R1Y2tTdGF0c1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCD3VwZGF0ZUR1Y2tTdGF0cwkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCCQBrAwUGeHBTaG9wBQh4cEFtb3VudAUFTVVMVDgFA25pbAUDbmlsCQCUCgIJAM4IAgUIYWN0aW9uczEFCGFjdGlvbnMyCQCXCgUFDHByb2xvZ1Jlc3VsdAUKc2hvcFdoU2F2ZQUGYnBTYXZlBQ9kdWNrU3RhdHNSZXN1bHQFDmFjY1N0YXRzUmVzdWx0AWkBG2FjY2VwdFNob3BPcmRlckR1Y2tEZWxpdmVyeQIIb3JkZXJTdHIPc2hvcExhbmRBc3NldElkAwkBASEBBRFLU19BTExPV19ERUxJVkVSWQkAAgECH0RlbGl2ZXJ5IGZlYXR1cmUgaXMgdHVybmVkIG9mZiEEDHByb2xvZ1Jlc3VsdAkBBnByb2xvZwAEBmNhbGxlcggFAWkMb3JpZ2luQ2FsbGVyBApjYWxsZXJBZGRyCQClCAEFBmNhbGxlcgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFCmNhbGxlckFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAlicFJlc0xpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMCAV8ECWJwTWF0TGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQKYnBQcm9kTGlzdAMJAAACCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIBXwQNJHQwNTI4MjM1MzA2MQkBFWFjY2VwdFNob3BPcmRlckNvbW1vbgYFD3Nob3BMYW5kQXNzZXRJZAUKY2FsbGVyQWRkcgUIb3JkZXJTdHIFCWJwUmVzTGlzdAUJYnBNYXRMaXN0BQpicFByb2RMaXN0BApzaG9wQWN0aW9uCAUNJHQwNTI4MjM1MzA2MQJfMQQKbmV3VXNlclJlcwgFDSR0MDUyODIzNTMwNjECXzIECm5ld1VzZXJNYXQIBQ0kdDA1MjgyMzUzMDYxAl8zBAtuZXdVc2VyUHJvZAgFDSR0MDUyODIzNTMwNjECXzQEDXVzZFdoMkJwU2FsZG8IBQ0kdDA1MjgyMzUzMDYxAl81BA11c2RCcDJXaFNhbGRvCAUNJHQwNTI4MjM1MzA2MQJfNgQIeHBBbW91bnQIBQ0kdDA1MjgyMzUzMDYxAl83BA1zaG9wTGFuZE93bmVyCAUNJHQwNTI4MjM1MzA2MQJfOAQKc2hvcFdoU2F2ZQgFDSR0MDUyODIzNTMwNjECXzkEDmFjY1N0YXRzUmVzdWx0CAUNJHQwNTI4MjM1MzA2MQNfMTAED2RlbGl2ZXJ5RmVlUGFydAkAawMJAGQCBQ11c2RCcDJXaFNhbGRvBQ11c2RXaDJCcFNhbGRvBQxERUxJVkVSWV9GRUUFBU1VTFQ2BAtkZWxpdmVyeUZlZQMJAGYCBRVNSU5fVVNEVF9GRUVfREVMSVZFUlkFD2RlbGl2ZXJ5RmVlUGFydAUVTUlOX1VTRFRfRkVFX0RFTElWRVJZBQ9kZWxpdmVyeUZlZVBhcnQECHNwZW50RmVlCQBrAwULZGVsaXZlcnlGZWUFDXVzZEJwMldoU2FsZG8JAGQCBQ11c2RCcDJXaFNhbGRvBQ11c2RXaDJCcFNhbGRvBAtyZWNlaXZlZEZlZQkAZQIFC2RlbGl2ZXJ5RmVlBQhzcGVudEZlZQQJZnVuZFRvdGFsCQELdmFsdWVPckVsc2UCCQCfCAEFD2RlbGl2ZXJ5RnVuZEtleQAABAhhY3Rpb25zMQkAzAgCBQpzaG9wQWN0aW9uCQEQc2hvcDJ1c2VyQWN0aW9ucwMFDXVzZFdoMkJwU2FsZG8FCmNhbGxlckFkZHIFC3JlY2VpdmVkRmVlBAhhY3Rpb25zMgkBEHVzZXIyc2hvcEFjdGlvbnMEBQ11c2RCcDJXaFNhbGRvCAUBaQhwYXltZW50cwUNc2hvcExhbmRPd25lcgUIc3BlbnRGZWUECG5ld0JwU3RyCQC6CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQC5CQIFCm5ld1VzZXJSZXMCAV8JAMwIAgkAuQkCBQpuZXdVc2VyTWF0AgFfCQDMCAIJALoJAgULbmV3VXNlclByb2QCAV8FA25pbAIBOgQGYnBTYXZlCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQmFja3BhY2sJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUIbmV3QnBTdHIFA25pbAUDbmlsBA9kdWNrU3RhdHNSZXN1bHQJAQVhc0ludAEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag91cGRhdGVEdWNrU3RhdHMJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgkAawMFBnhwU2hvcAUIeHBBbW91bnQFBU1VTFQ4BQNuaWwFA25pbAkAlAoCCQDNCAIJAM4IAgUIYWN0aW9uczEFCGFjdGlvbnMyCQEMSW50ZWdlckVudHJ5AgUPZGVsaXZlcnlGdW5kS2V5CQBkAgUJZnVuZFRvdGFsBQtkZWxpdmVyeUZlZQkAlwoFBQxwcm9sb2dSZXN1bHQFCnNob3BXaFNhdmUFBmJwU2F2ZQUPZHVja1N0YXRzUmVzdWx0BQ5hY2NTdGF0c1Jlc3VsdAFpARthY2NlcHRTaG9wT3JkZXJMYW5kRGVsaXZlcnkDCG9yZGVyU3RyD3Nob3BMYW5kQXNzZXRJZA1teUxhbmRBc3NldElkAwkBASEBBRFLU19BTExPV19ERUxJVkVSWQkAAgECH0RlbGl2ZXJ5IGZlYXR1cmUgaXMgdHVybmVkIG9mZiEEDHByb2xvZ1Jlc3VsdAkBBnByb2xvZwAEBmNhbGxlcggFAWkMb3JpZ2luQ2FsbGVyBApjYWxsZXJBZGRyCQClCAEFBmNhbGxlcgQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQ1teUxhbmRBc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAmggCBQ9zdGFraW5nQ29udHJhY3QJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQUNbXlMYW5kQXNzZXRJZAkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQUNbXlMYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUKY2FsbGVyQWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQCd2gJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0AhRnZXRXYXJlaG91c2VSRUFET05MWQkAzAgCBQ1teUxhbmRBc3NldElkBQNuaWwFA25pbAQJY3VycmVudFdoCQC8CQIFAndoAgE6BAdyZXNMaXN0CQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeFJlcwIBXwQHbWF0TGlzdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhNYXQCAV8ECHByb2RMaXN0AwkAAAIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAAUDbmlsCQC1CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAV8EDSR0MDU1MzAwNTU1MzIJARVhY2NlcHRTaG9wT3JkZXJDb21tb24GBQ9zaG9wTGFuZEFzc2V0SWQFCmNhbGxlckFkZHIFCG9yZGVyU3RyBQdyZXNMaXN0BQdtYXRMaXN0BQhwcm9kTGlzdAQKc2hvcEFjdGlvbggFDSR0MDU1MzAwNTU1MzICXzEECm5ld1VzZXJSZXMIBQ0kdDA1NTMwMDU1NTMyAl8yBApuZXdVc2VyTWF0CAUNJHQwNTUzMDA1NTUzMgJfMwQLbmV3VXNlclByb2QIBQ0kdDA1NTMwMDU1NTMyAl80BA11c2RXaDJCcFNhbGRvCAUNJHQwNTUzMDA1NTUzMgJfNQQNdXNkQnAyV2hTYWxkbwgFDSR0MDU1MzAwNTU1MzICXzYECHhwQW1vdW50CAUNJHQwNTUzMDA1NTUzMgJfNwQNc2hvcExhbmRPd25lcggFDSR0MDU1MzAwNTU1MzICXzgECnNob3BXaFNhdmUIBQ0kdDA1NTMwMDU1NTMyAl85BA5hY2NTdGF0c1Jlc3VsdAgFDSR0MDU1MzAwNTU1MzIDXzEwBA9kZWxpdmVyeUZlZVBhcnQJAGsDCQBkAgUNdXNkQnAyV2hTYWxkbwUNdXNkV2gyQnBTYWxkbwUMREVMSVZFUllfRkVFBQVNVUxUNgQLZGVsaXZlcnlGZWUDCQBmAgUVTUlOX1VTRFRfRkVFX0RFTElWRVJZBQ9kZWxpdmVyeUZlZVBhcnQFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQUPZGVsaXZlcnlGZWVQYXJ0BAhzcGVudEZlZQkAawMFC2RlbGl2ZXJ5RmVlBQ11c2RCcDJXaFNhbGRvCQBkAgUNdXNkQnAyV2hTYWxkbwUNdXNkV2gyQnBTYWxkbwQLcmVjZWl2ZWRGZWUJAGUCBQtkZWxpdmVyeUZlZQUIc3BlbnRGZWUECWZ1bmRUb3RhbAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ9kZWxpdmVyeUZ1bmRLZXkAAAQIYWN0aW9uczEJAMwIAgUKc2hvcEFjdGlvbgkBEHNob3AydXNlckFjdGlvbnMDBQ11c2RXaDJCcFNhbGRvBQpjYWxsZXJBZGRyBQtyZWNlaXZlZEZlZQQIYWN0aW9uczIJARB1c2VyMnNob3BBY3Rpb25zBAUNdXNkQnAyV2hTYWxkbwgFAWkIcGF5bWVudHMFDXNob3BMYW5kT3duZXIFCHNwZW50RmVlBAV3aFN0cgkAugkCCQDMCAIJAJEDAgUJY3VycmVudFdoBQt3aElkeExldmVscwkAzAgCCQC5CQIFCm5ld1VzZXJSZXMCAV8JAMwIAgkAuQkCBQpuZXdVc2VyTWF0AgFfCQDMCAIJALkJAgULbmV3VXNlclByb2QCAV8JAMwIAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4TE9GVAUDbmlsAgE6BAZ3aFNhdmUJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag1zYXZlV2FyZWhvdXNlCQDMCAIFBXdoU3RyCQDMCAIFDW15TGFuZEFzc2V0SWQFA25pbAUDbmlsBAtzdGF0c1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCFnVwZGF0ZUFjY1N0YXRzSW50ZXJuYWwJAMwIAgUKY2FsbGVyQWRkcgkAzAgCCQBrAwUGeHBTaG9wBQh4cEFtb3VudAUFTVVMVDgFA25pbAUDbmlsCQCUCgIJAM0IAgkAzggCBQhhY3Rpb25zMQUIYWN0aW9uczIJAQxJbnRlZ2VyRW50cnkCBQ9kZWxpdmVyeUZ1bmRLZXkJAGQCBQlmdW5kVG90YWwFC2RlbGl2ZXJ5RmVlCQCXCgUFDHByb2xvZ1Jlc3VsdAUKc2hvcFdoU2F2ZQUGd2hTYXZlBQtzdGF0c1Jlc3VsdAUOYWNjU3RhdHNSZXN1bHQBaQEQc2VsbFByb2R1Y3RzVG9FUwEHYW1vdW50cwQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECEk5vIHBheW1lbnRzIG5lZWRlZAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04CAV8DCQECIT0CCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlAgFBCQACAQkArAICAi1EdWNrIGxvY2F0aW9uIHR5cGUgc2hvdWxkIGJlIEFpcnBvcnQsIGJ1dCBpcyAJAJEDAgULY3VyTG9jYXRpb24FCmxvY0lkeFR5cGUEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQIcHJvZExpc3QDCQAAAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgAFA25pbAkAvAkCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAV8EBWVzS2V5CQEOa2V5RXNXYXJlaG91c2UABAhleGlzdFN0cgkAoggBBQVlc0tleQQMZXhpc3RBbW91bnRzAwkBCWlzRGVmaW5lZAEFCGV4aXN0U3RyCQC8CQIJAQV2YWx1ZQEFCGV4aXN0U3RyAgFfBQNuaWwKAQhtb3ZlUHJvZAIDYWNjCXJlY2lwZVN0cgQBaggFA2FjYwJfMQQIcXVhbnRpdHkDCQBmAgkAkAMBBQdhbW91bnRzBQFqCQCRAwIFB2Ftb3VudHMFAWoAAAMJAGYCAAAFCHF1YW50aXR5CQACAQIbUXVhbnRpdHkgY2Fubm90IGJlIG5lZ2F0aXZlBAZyZWNpcGUJALUJAgUJcmVjaXBlU3RyAgFfAwkBAiE9AgkAkAMBBQZyZWNpcGUFClJFQ0lQRVNJWkUJAAIBCQCsAgICF0ZhdGFsOiB1bmtub3duIHJlY2lwZTogBQlyZWNpcGVTdHIECW1heEFtb3VudAkAaAIFDUVTTUFYUEFDS0FHRVMFDlBST0RVQ1RQS0dTSVpFBAtleGlzdEFtb3VudAMJAGYCCQCQAwEFDGV4aXN0QW1vdW50cwUBagkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDGV4aXN0QW1vdW50cwUBagAABAZjYW5CdXkJAGUCBQltYXhBbW91bnQFC2V4aXN0QW1vdW50AwkAZgIFCHF1YW50aXR5BQZjYW5CdXkJAAIBCQCsAgIJAKwCAgkArAICAhdXYXJlaG91c2UgY2FuIGJ1eSBvbmx5IAkApAMBBQZjYW5CdXkCBCBvZiAJAJEDAgUJcHJvZFR5cGVzBQFqBAh0b3RhbE1hdAkBEmdldFJlY2lwZU1hdGVyaWFscwEFBnJlY2lwZQQJdW5pdFByaWNlCQBrAwkAaAIFCHRvdGFsTWF0BQlFU0JVWUNPRUYFEFJFU09VUkNFUFJJQ0VNSU4JAGgCBQVNVUxUOAUOUFJPRFVDVFBLR1NJWkUEDGJwUHJvZEFtb3VudAMJAGYCCQCQAwEFCHByb2RMaXN0BQFqCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIcHJvZExpc3QFAWoAAAMJAGYCBQhxdWFudGl0eQUMYnBQcm9kQW1vdW50CQACAQkArAICCQCsAgIJAKwCAgIOWW91IGhhdmUgb25seSAJAKQDAQUMYnBQcm9kQW1vdW50AgQgb2YgCQCRAwIFCXByb2RUeXBlcwUBagkAlwoFCQBkAgUBagABCQBkAggFA2FjYwJfMgkAaAIFCXVuaXRQcmljZQUIcXVhbnRpdHkJAM0IAggFA2FjYwJfMwkApAMBCQBlAgUMYnBQcm9kQW1vdW50BQhxdWFudGl0eQkAzQgCCAUDYWNjAl80CQCkAwEJAGQCBQtleGlzdEFtb3VudAUIcXVhbnRpdHkJAGQCCAUDYWNjAl81CQBoAgUIdG90YWxNYXQFCHF1YW50aXR5BAZtZXJnZWQKAAIkbAUQcHJvZHVjdGlvbk1hdHJpeAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJcKBQAAAAAFA25pbAUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCG1vdmVQcm9kAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyA1MAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIECG5ld0JwU3RyCQC6CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAkAzAgCCQC6CQIIBQZtZXJnZWQCXzMCAV8FA25pbAIBOgQGYnBTYXZlCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQmFja3BhY2sJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUIbmV3QnBTdHIFA25pbAUDbmlsBAtzdGF0c1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCD3VwZGF0ZUR1Y2tTdGF0cwkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCCQBrAwUKeHBTZWxsVG9FcwgFBm1lcmdlZAJfNQkAaAIFBU1VTFQ4AAoFA25pbAUDbmlsCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUFZXNLZXkJALoJAggFBm1lcmdlZAJfNAIBXwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIIBQZtZXJnZWQCXzIFC3VzZHRBc3NldElkBQNuaWwJAJUKAwUGYnBTYXZlBQxwcm9sb2dSZXN1bHQFC3N0YXRzUmVzdWx0AWkBD3VwZGF0ZUVzU3RvcmFnZQEKbmV3U3RvcmFnZQMJAQIhPQIIBQFpBmNhbGxlcgUPc3Rha2luZ0NvbnRyYWN0CQACAQIRUGVybWlzc2lvbiBkZW5pZWQJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQEOa2V5RXNXYXJlaG91c2UABQpuZXdTdG9yYWdlBQNuaWwFCm5ld1N0b3JhZ2UAJ4AXLw==", "height": 2762218, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: EdkYGHGbN33zuNGydmXrvjskXVrFcWHwNQDKcrkMyKzK Next: 2AR9JCgc3UgfKevxfxijBXTXjiLXyqSZddrAuTgM6RWD Diff:
OldNewDifferences
2020 let ESMAXPACKAGES = 10
2121
2222 let ESBUYCOEF = 4
23+
24+let MIN_USDT_FEE_DELIVERY = 50000
25+
26+let MIN_USDT_FEE_DELIVERY15 = 75000
2327
2428 let resTypes = ["Oil", "Ore", "Wood", "Sand", "Clay", "Organic"]
2529
9397 func keyEsWarehouse () = "emergencyWarehouseProducts"
9498
9599
100+let deliveryFundKey = "deliveryFund"
101+
96102 func getRecipeMaterials (recipe) = (parseIntValue(recipe[rIdxCoeff]) * COEFF2MAT)
97103
104+
105+let KS_ALLOW_DELIVERY = false
98106
99107 let chain = take(drop(this.bytes, 1), 1)
100108
188196
189197 let AUCTIONFEE = 10000
190198
199+let DELIVERY_FEE = 10000
200+
201+let DELIVERY_FEE15 = 15000
202+
191203 func keyFactoryWarehouseByIdAndType (factoryId,resType) = ((("factoryWhByContinentAndRes_" + factoryId) + "_") + toString(resType))
192204
193205
250262
251263
252264 func getBackpack (bpKey) = {
253- let p = split(valueOrElse(getString(stakingContract, bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
265+ let p = split_4C(valueOrElse(getString(stakingContract, bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
254266 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
255267 then p[bpIdxRes]
256268 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
455467 }
456468
457469
470+func sellResourcesCommon (resList,factoryLocId,amounts,minPrices) = {
471+ func adder (acc,j) = if ((amounts[j] > parseIntValue(resList[j])))
472+ then throw(((((("You have " + resList[j]) + " of ") + resTypes[j]) + ", but tried to sell ") + toString(amounts[j])))
473+ else if ((0 > amounts[j]))
474+ then throw(((("You tried to sell negative amount of " + resTypes[j]) + ": ") + toString(amounts[j])))
475+ else if ((amounts[j] > 0))
476+ then {
477+ let b = sellInternal(factoryLocId, j, amounts[j], minPrices[j])
478+ $Tuple4((acc._1 :+ b._1), (acc._2 :+ toString((parseIntValue(resList[j]) - amounts[j]))), (acc._3 + b._2), (acc._4 + amounts[j]))
479+ }
480+ else $Tuple4(acc._1, (acc._2 :+ resList[j]), acc._3, acc._4)
481+
482+ let $l = ITER6
483+ let $s = size($l)
484+ let $acc0 = $Tuple4(nil, nil, 0, 0)
485+ func $f0_1 ($a,$i) = if (($i >= $s))
486+ then $a
487+ else adder($a, $l[$i])
488+
489+ func $f0_2 ($a,$i) = if (($i >= $s))
490+ then $a
491+ else throw("List size exceeds 6")
492+
493+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
494+ }
495+
496+
497+func buyMaterialsCommon (matList,factoryLocId,amounts,maxPrices) = {
498+ func mUpdater (acc,j) = if ((0 > amounts[j]))
499+ then throw(((("You tried to buy negative amount of " + matTypes[j]) + ": ") + toString(amounts[j])))
500+ else if ((amounts[j] > 0))
501+ then {
502+ let b = buyInternal(factoryLocId, j, amounts[j], maxPrices[j])
503+ $Tuple4((acc._1 :+ b._1), (acc._2 :+ toString((parseIntValue(matList[j]) + b._3))), (acc._3 + b._2), (acc._4 + amounts[j]))
504+ }
505+ else $Tuple4(acc._1, (acc._2 :+ matList[j]), acc._3, acc._4)
506+
507+ let $l = ITER6
508+ let $s = size($l)
509+ let $acc0 = $Tuple4(nil, nil, 0, 0)
510+ func $f0_1 ($a,$i) = if (($i >= $s))
511+ then $a
512+ else mUpdater($a, $l[$i])
513+
514+ func $f0_2 ($a,$i) = if (($i >= $s))
515+ then $a
516+ else throw("List size exceeds 6")
517+
518+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
519+ }
520+
521+
522+func exchangeResourcesCommon (resList,matList,amounts) = {
523+ func exchanger (acc,j) = {
524+ let amj = amounts[j]
525+ if ((amj > parseIntValue(resList[j])))
526+ then throw(((((("You have " + resList[j]) + " of ") + resTypes[j]) + ", but tried to exchange ") + toString(amj)))
527+ else if ((0 > amj))
528+ then throw(((("You tried to exchange negative amount of " + resTypes[j]) + ": ") + toString(amj)))
529+ else if ((amj > 0))
530+ then $Tuple4((acc._1 :+ toString((parseIntValue(resList[j]) - amj))), (acc._2 :+ toString((parseIntValue(matList[j]) + amj))), (acc._3 + fraction(amj, RESOURCEPRICEMIN, MULT8)), (acc._4 + amj))
531+ else $Tuple4((acc._1 :+ resList[j]), (acc._2 :+ matList[j]), acc._3, acc._4)
532+ }
533+
534+ let $l = ITER6
535+ let $s = size($l)
536+ let $acc0 = $Tuple4(nil, nil, 0, 0)
537+ func $f0_1 ($a,$i) = if (($i >= $s))
538+ then $a
539+ else exchanger($a, $l[$i])
540+
541+ func $f0_2 ($a,$i) = if (($i >= $s))
542+ then $a
543+ else throw("List size exceeds 6")
544+
545+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
546+ }
547+
548+
549+func shop2userActions (usdWh2BpSaldo,callerAddr,receivedFee) = if ((usdWh2BpSaldo > 0))
550+ then {
551+ let usdWh2BpFee = fraction(usdWh2BpSaldo, AUCTIONFEE, MULT6)
552+ if ((receivedFee >= (usdWh2BpSaldo - (3 * usdWh2BpFee))))
553+ then throw(("This trade does not cover delivery cost of " + fixedPoint(receivedFee, 6)))
554+ else {
555+ let refByKey = keyAddressRefBy(callerAddr)
556+ let refBy = getString(stakingContract, refByKey)
557+ let caller = addressFromStringValue(callerAddr)
558+ (((if (isDefined(refBy))
559+ then [ScriptTransfer(addressFromStringValue(value(refBy)), usdWh2BpFee, usdtAssetId)]
560+ else nil) :+ ScriptTransfer(caller, ((usdWh2BpSaldo - (3 * usdWh2BpFee)) - receivedFee), usdtAssetId)) :+ ScriptTransfer(restContract, usdWh2BpFee, usdtAssetId))
561+ }
562+ }
563+ else nil
564+
565+
566+func user2shopActions (usdBp2WhSaldo,pmts,shopLandOwner,spentFee) = if ((usdBp2WhSaldo > 0))
567+ then if ((size(pmts) != 1))
568+ then throw("exactly 1 payment must be attached")
569+ else {
570+ let pmt = pmts[0]
571+ let amt = pmt.amount
572+ if (if (!(isDefined(pmt.assetId)))
573+ then true
574+ else (value(pmt.assetId) != usdtAssetId))
575+ then throw("USDT payments only!")
576+ else {
577+ let usdtSpentWithFee = (usdBp2WhSaldo + spentFee)
578+ if ((amt != usdtSpentWithFee))
579+ then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdBp2WhSaldo, 6)) + "+") + fixedPoint(spentFee, 6)) + "(delivery fee)"))
580+ else if ((MINSHOPPAYMENT > usdBp2WhSaldo))
581+ then throw(("Min shop trade is " + fixedPoint(MINSHOPPAYMENT, 6)))
582+ else {
583+ let usdBp2WhFee = fraction(usdBp2WhSaldo, AUCTIONFEE, MULT6)
584+ let refByKey = keyAddressRefBy(shopLandOwner)
585+ let refBy = getString(stakingContract, refByKey)
586+ (((if (isDefined(refBy))
587+ then [ScriptTransfer(addressFromStringValue(value(refBy)), usdBp2WhFee, usdtAssetId)]
588+ else nil) :+ ScriptTransfer(addressFromStringValue(shopLandOwner), (usdBp2WhSaldo - (3 * usdBp2WhFee)), usdtAssetId)) :+ ScriptTransfer(restContract, usdBp2WhFee, usdtAssetId))
589+ }
590+ }
591+ }
592+ else if ((size(pmts) != 0))
593+ then throw("No payments needed")
594+ else nil
595+
596+
597+func acceptShopOrderCommon (shopLandAssetId,callerAddr,bpOrderStr,bpResList,bpMatList,bpProdList) = {
598+ let landAsset = value(assetInfo(fromBase58String(shopLandAssetId)))
599+ if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(shopLandAssetId)))))
600+ then throw((("NFT " + landAsset.name) + " is not staked"))
601+ else {
602+ let shopLandOwner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(shopLandAssetId)), (("NFT " + landAsset.name) + " is orphaned"))
603+ if ((shopLandOwner == callerAddr))
604+ then throw("You cannot trade with yourself")
605+ else {
606+ let bpOrderParts = split_4C(bpOrderStr, ":")
607+ if ((size(bpOrderParts) != 3))
608+ then throw("bpOrderStr should contain exactly 2 ':' separators")
609+ else {
610+ let bpOrdRes = split(bpOrderParts[0], "_")
611+ let bpOrdMat = split(bpOrderParts[1], "_")
612+ let bpOrdProd = if ((bpOrderParts[2] == ""))
613+ then nil
614+ else split_4C(bpOrderParts[2], "_")
615+ if ((size(bpOrdRes) != NUMRES))
616+ then throw("All 6 resources should be passed")
617+ else if ((size(bpOrdMat) != NUMRES))
618+ then throw("All 6 materials should be passed")
619+ else {
620+ let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [shopLandAssetId], nil))
621+ let currentWh = split_4C(wh, ":")
622+ let currWhRes = split(currentWh[whIdxRes], "_")
623+ let currWhMat = split(currentWh[whIdxMat], "_")
624+ let currWhProd = if ((currentWh[whIdxProd] == ""))
625+ then nil
626+ else split_4C(currentWh[whIdxProd], "_")
627+ let currWhLockedVol = parseIntValue(split(currentWh[whIdxLOFT], "_")[volLocked])
628+ let ordKey = keyOrderByLand(shopLandAssetId)
629+ let whOrd = getOrder(ordKey)
630+ let whOrdRes = split(whOrd[ordIdxRes], "_")
631+ let whOrdMat = split(whOrd[ordIdxMat], "_")
632+ let whOrdProd = if ((whOrd[ordIdxProd] == ""))
633+ then nil
634+ else split_4C(whOrd[ordIdxProd], "_")
635+ let r = {
636+ let $l = bpOrdRes
637+ let $s = size($l)
638+ let $acc0 = $Tuple13(nil, nil, nil, 0, 0, 0, 0, bpResList, currWhRes, whOrdRes, resTypes, false, 0)
639+ func $f0_1 ($a,$i) = if (($i >= $s))
640+ then $a
641+ else acceptCommon($a, $l[$i])
642+
643+ func $f0_2 ($a,$i) = if (($i >= $s))
644+ then $a
645+ else throw("List size exceeds 6")
646+
647+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
648+ }
649+ let m = {
650+ let $l = bpOrdMat
651+ let $s = size($l)
652+ let $acc0 = $Tuple13(nil, nil, nil, r._4, r._5, r._6, 0, bpMatList, currWhMat, whOrdMat, matTypes, false, r._13)
653+ func $f1_1 ($a,$i) = if (($i >= $s))
654+ then $a
655+ else acceptCommon($a, $l[$i])
656+
657+ func $f1_2 ($a,$i) = if (($i >= $s))
658+ then $a
659+ else throw("List size exceeds 6")
660+
661+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
662+ }
663+ let p = if ((size(bpOrdProd) != 0))
664+ then {
665+ let $l = bpOrdProd
666+ let $s = size($l)
667+ let $acc0 = $Tuple13(nil, nil, nil, m._4, m._5, m._6, 0, bpProdList, currWhProd, whOrdProd, prodTypes, true, m._13)
668+ func $f2_1 ($a,$i) = if (($i >= $s))
669+ then $a
670+ else acceptCommon($a, $l[$i])
671+
672+ func $f2_2 ($a,$i) = if (($i >= $s))
673+ then $a
674+ else throw("List size exceeds 50")
675+
676+ $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)
677+ }
678+ else $Tuple13(currWhProd, whOrdProd, bpProdList, m._4, m._5, m._6, 0, bpProdList, currWhProd, whOrdProd, prodTypes, true, m._13)
679+ let volSaldo = p._4
680+ let newLockedVol = if ((0 > (currWhLockedVol - volSaldo)))
681+ then 0
682+ else (currWhLockedVol - volSaldo)
683+ let whStr = makeString_2C([currentWh[whIdxLevels], makeString(r._1, "_"), makeString(m._1, "_"), makeString_2C(p._1, "_"), toString(newLockedVol)], ":")
684+ let newWhOrdStr = makeString_2C([makeString(r._2, "_"), makeString(m._2, "_"), makeString_2C(p._2, "_")], ":")
685+ let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, shopLandAssetId], nil))
686+ let accStatsResult = asInt(invoke(stakingContract, "updateAccStats", [shopLandOwner, fraction(xpShop, p._13, MULT8)], nil))
687+ $Tuple10(StringEntry(ordKey, newWhOrdStr), r._3, m._3, p._3, p._5, p._6, p._13, shopLandOwner, whSave, accStatsResult)
688+ }
689+ }
690+ }
691+ }
692+ }
693+
694+
458695 @Callable(i)
459696 func recalcLockedVolumeREADONLY (landAssetId,wh) = {
460697 let currentOrd = getOrder(keyOrderByLand(landAssetId))
482719 if ((curLocation[locIdxType] != "F"))
483720 then throw(("Duck location type should be Factory, but is " + curLocation[locIdxType]))
484721 else {
485- let locId = curLocation[locIdxId]
486722 let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
487723 let resList = split(currentPack[bpIdxRes], "_")
488- func adder (acc,j) = if ((amounts[j] > parseIntValue(resList[j])))
489- then throw(((((("You have " + resList[j]) + " of ") + resTypes[j]) + ", but tried to sell ") + toString(amounts[j])))
490- else if ((0 > amounts[j]))
491- then throw(((("You tried to sell negative amount of " + resTypes[j]) + ": ") + toString(amounts[j])))
492- else if ((amounts[j] > 0))
493- then {
494- let b = sellInternal(locId, j, amounts[j], minPrices[j])
495- $Tuple4((acc._1 :+ b._1), (acc._2 :+ toString((parseIntValue(resList[j]) - amounts[j]))), (acc._3 + b._2), (acc._4 + amounts[j]))
496- }
497- else $Tuple4(acc._1, (acc._2 :+ resList[j]), acc._3, acc._4)
498-
499- let merged = {
500- let $l = ITER6
501- let $s = size($l)
502- let $acc0 = $Tuple4(nil, nil, 0, 0)
503- func $f0_1 ($a,$i) = if (($i >= $s))
504- then $a
505- else adder($a, $l[$i])
506-
507- func $f0_2 ($a,$i) = if (($i >= $s))
508- then $a
509- else throw("List size exceeds 6")
510-
511- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
512- }
513- let newPack = makeString([currentPack[bpIdxLevel], makeString(merged._2, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":")
514- let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
515- let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, merged._4, MULT8)], nil))
516- $Tuple2((merged._1 :+ ScriptTransfer(i.caller, merged._3, usdtAssetId)), $Tuple3(result, prologResult, statsResult))
724+ let $t02587726003 = sellResourcesCommon(resList, curLocation[locIdxId], amounts, minPrices)
725+ let factoryActions = $t02587726003._1
726+ let newRes = $t02587726003._2
727+ let usdtReceived = $t02587726003._3
728+ let totalRes = $t02587726003._4
729+ let activitiesAmount = (usdtReceived / 100)
730+ let newPack = makeString_2C([currentPack[bpIdxLevel], makeString(newRes, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":")
731+ let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
732+ let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalRes, MULT8)], nil))
733+ $Tuple2(((factoryActions :+ ScriptTransfer(i.caller, (usdtReceived - activitiesAmount), usdtAssetId)) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult))
517734 }
518735 }
519736 }
737+
738+
739+
740+@Callable(i)
741+func sellResourcesDuckDelivery (amounts,minPrices,factoryContinent) = if (!(KS_ALLOW_DELIVERY))
742+ then throw("Delivery feature is turned off!")
743+ else {
744+ let prologResult = prolog()
745+ let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
746+ if ((size(i.payments) != 0))
747+ then throw("sellResources doesn't require any payments")
748+ else {
749+ let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
750+ let resList = split(currentPack[bpIdxRes], "_")
751+ let $t02723727358 = sellResourcesCommon(resList, factoryContinent, amounts, minPrices)
752+ let factoryActions = $t02723727358._1
753+ let newRes = $t02723727358._2
754+ let usdtReceived = $t02723727358._3
755+ let totalRes = $t02723727358._4
756+ let newPack = makeString_2C([currentPack[bpIdxLevel], makeString(newRes, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":")
757+ let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
758+ let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalRes, MULT8)], nil))
759+ let feePart = fraction(usdtReceived, DELIVERY_FEE, MULT6)
760+ let fee = if ((MIN_USDT_FEE_DELIVERY > feePart))
761+ then MIN_USDT_FEE_DELIVERY
762+ else feePart
763+ let activitiesAmount = (usdtReceived / 100)
764+ if ((fee >= (usdtReceived - activitiesAmount)))
765+ then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6)))
766+ else {
767+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
768+ $Tuple2((((factoryActions :+ ScriptTransfer(i.caller, ((usdtReceived - activitiesAmount) - fee), usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult))
769+ }
770+ }
771+ }
772+
773+
774+
775+@Callable(i)
776+func sellResourcesLandDelivery (amounts,minPrices,landAssetId,factoryContinent) = if (!(KS_ALLOW_DELIVERY))
777+ then throw("Delivery feature is turned off!")
778+ else {
779+ let prologResult = prolog()
780+ if ((size(i.payments) != 0))
781+ then throw("sellResources doesn't require any payments")
782+ else {
783+ let user = i.caller
784+ let addr = toString(user)
785+ let asset = value(assetInfo(fromBase58String(landAssetId)))
786+ if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId)))))
787+ then throw((("NFT " + asset.name) + " is not staked"))
788+ else {
789+ let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
790+ if ((owner != addr))
791+ then throw((LANDPREFIX + " is not yours"))
792+ else {
793+ let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil))
794+ let currentWh = split_4C(wh, ":")
795+ let resList = split(currentWh[whIdxRes], "_")
796+ let $t02938529506 = sellResourcesCommon(resList, factoryContinent, amounts, minPrices)
797+ let factoryActions = $t02938529506._1
798+ let newRes = $t02938529506._2
799+ let usdtReceived = $t02938529506._3
800+ let totalRes = $t02938529506._4
801+ let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newRes, "_"), currentWh[whIdxMat], currentWh[whIdxProd], currentWh[whIdxLOFT]], ":")
802+ let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil))
803+ let statsResult = asInt(invoke(stakingContract, "updateAccStatsInternal", [addr, fraction(xpTrade, totalRes, MULT8)], nil))
804+ let feePart = fraction(usdtReceived, DELIVERY_FEE, MULT6)
805+ let fee = if ((MIN_USDT_FEE_DELIVERY > feePart))
806+ then MIN_USDT_FEE_DELIVERY
807+ else feePart
808+ let activitiesAmount = (usdtReceived / 100)
809+ if ((fee >= (usdtReceived - activitiesAmount)))
810+ then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6)))
811+ else {
812+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
813+ $Tuple2((((factoryActions :+ ScriptTransfer(i.caller, ((usdtReceived - activitiesAmount) - fee), usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(whSave, prologResult, statsResult))
814+ }
815+ }
816+ }
817+ }
818+ }
520819
521820
522821
529828 else {
530829 let pmt = i.payments[0]
531830 let amt = pmt.amount
532- let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
533- if ((pmtAssetId != usdtAssetId))
831+ if (if (!(isDefined(pmt.assetId)))
832+ then true
833+ else (value(pmt.assetId) != usdtAssetId))
534834 then throw("USDT payments only!")
535835 else {
536836 let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
537837 if ((curLocation[locIdxType] != "F"))
538838 then throw(("Duck location type should be Factory, but is " + curLocation[locIdxType]))
539839 else {
540- let locId = curLocation[locIdxId]
541840 let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
542841 let matList = split(currentPack[bpIdxMat], "_")
543- func mUpdater (acc,j) = if ((0 > amounts[j]))
544- then throw(((("You tried to buy negative amount of " + matTypes[j]) + ": ") + toString(amounts[j])))
545- else if ((amounts[j] > 0))
546- then {
547- let b = buyInternal(locId, j, amounts[j], maxPrices[j])
548- $Tuple4((acc._1 :+ b._1), (acc._2 :+ toString((parseIntValue(matList[j]) + b._3))), (acc._3 + b._2), (acc._4 + amounts[j]))
549- }
550- else $Tuple4(acc._1, (acc._2 :+ matList[j]), acc._3, acc._4)
551-
552- let merged = {
553- let $l = ITER6
554- let $s = size($l)
555- let $acc0 = $Tuple4(nil, nil, 0, 0)
556- func $f0_1 ($a,$i) = if (($i >= $s))
557- then $a
558- else mUpdater($a, $l[$i])
559-
560- func $f0_2 ($a,$i) = if (($i >= $s))
561- then $a
562- else throw("List size exceeds 6")
563-
564- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
565- }
566- if ((merged._3 > amt))
567- then throw(((("Insufficient payment! Attached=" + toString(amt)) + ", required=") + toString(merged._3)))
842+ let $t03137431496 = buyMaterialsCommon(matList, curLocation[locIdxId], amounts, maxPrices)
843+ let factoryActions = $t03137431496._1
844+ let newMat = $t03137431496._2
845+ let usdtSpent = $t03137431496._3
846+ let totalMat = $t03137431496._4
847+ if ((usdtSpent > amt))
848+ then throw(((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)))
568849 else {
569- let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(merged._2, "_"), currentPack[bpIdxProd]], ":")
570- let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
571- let rest = if (((amt - merged._3) > 0))
572- then [ScriptTransfer(i.caller, (amt - merged._3), usdtAssetId)]
850+ let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), currentPack[bpIdxProd]], ":")
851+ let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
852+ let rest = if (((amt - usdtSpent) > 0))
853+ then [ScriptTransfer(i.caller, (amt - usdtSpent), usdtAssetId)]
573854 else nil
574- let activitiesAmount = (merged._3 / 100)
575- let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, merged._4, MULT8)], nil))
576- $Tuple2(((merged._1 ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(result, prologResult, statsResult))
855+ let activitiesAmount = (usdtSpent / 100)
856+ let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalMat, MULT8)], nil))
857+ $Tuple2(((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult))
577858 }
578859 }
579860 }
580861 }
581862 }
863+
864+
865+
866+@Callable(i)
867+func buyMaterialsDuckDelivery (amounts,maxPrices,factoryContinent) = if (!(KS_ALLOW_DELIVERY))
868+ then throw("Delivery feature is turned off!")
869+ else {
870+ let prologResult = prolog()
871+ let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
872+ if ((size(i.payments) != 1))
873+ then throw("exactly 1 payment must be attached")
874+ else {
875+ let pmt = i.payments[0]
876+ let amt = pmt.amount
877+ if (if (!(isDefined(pmt.assetId)))
878+ then true
879+ else (value(pmt.assetId) != usdtAssetId))
880+ then throw("USDT payments only!")
881+ else {
882+ let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
883+ let matList = split(currentPack[bpIdxMat], "_")
884+ let $t03301433131 = buyMaterialsCommon(matList, factoryContinent, amounts, maxPrices)
885+ let factoryActions = $t03301433131._1
886+ let newMat = $t03301433131._2
887+ let usdtSpent = $t03301433131._3
888+ let totalMat = $t03301433131._4
889+ let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), currentPack[bpIdxProd]], ":")
890+ let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
891+ let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalMat, MULT8)], nil))
892+ let feePart = fraction(usdtSpent, DELIVERY_FEE, MULT6)
893+ let fee = if ((MIN_USDT_FEE_DELIVERY > feePart))
894+ then MIN_USDT_FEE_DELIVERY
895+ else feePart
896+ let usdtSpentWithFee = (usdtSpent + fee)
897+ if ((usdtSpentWithFee > amt))
898+ then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)"))
899+ else {
900+ let rest = if (((amt - usdtSpentWithFee) > 0))
901+ then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)]
902+ else nil
903+ let activitiesAmount = (usdtSpent / 100)
904+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
905+ $Tuple2((((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult))
906+ }
907+ }
908+ }
909+ }
910+
911+
912+
913+@Callable(i)
914+func buyMaterialsLandDelivery (amounts,maxPrices,landAssetId,factoryContinent) = if (!(KS_ALLOW_DELIVERY))
915+ then throw("Delivery feature is turned off!")
916+ else {
917+ let prologResult = prolog()
918+ if ((size(i.payments) != 1))
919+ then throw("exactly 1 payment must be attached")
920+ else {
921+ let pmt = i.payments[0]
922+ let amt = pmt.amount
923+ if (if (!(isDefined(pmt.assetId)))
924+ then true
925+ else (value(pmt.assetId) != usdtAssetId))
926+ then throw("USDT payments only!")
927+ else {
928+ let user = i.caller
929+ let addr = toString(user)
930+ let asset = value(assetInfo(fromBase58String(landAssetId)))
931+ if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId)))))
932+ then throw((("NFT " + asset.name) + " is not staked"))
933+ else {
934+ let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
935+ if ((owner != addr))
936+ then throw((LANDPREFIX + " is not yours"))
937+ else {
938+ let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil))
939+ let currentWh = split_4C(wh, ":")
940+ let matList = split(currentWh[whIdxMat], "_")
941+ let $t03540935526 = buyMaterialsCommon(matList, factoryContinent, amounts, maxPrices)
942+ let factoryActions = $t03540935526._1
943+ let newMat = $t03540935526._2
944+ let usdtSpent = $t03540935526._3
945+ let totalMat = $t03540935526._4
946+ let whStr = makeString_2C([currentWh[whIdxLevels], currentWh[whIdxRes], makeString(newMat, "_"), currentWh[whIdxProd], currentWh[whIdxLOFT]], ":")
947+ let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil))
948+ let statsResult = asInt(invoke(stakingContract, "updateAccStatsInternal", [addr, fraction(xpTrade, totalMat, MULT8)], nil))
949+ let feePart = fraction(usdtSpent, DELIVERY_FEE, MULT6)
950+ let fee = if ((MIN_USDT_FEE_DELIVERY > feePart))
951+ then MIN_USDT_FEE_DELIVERY
952+ else feePart
953+ let usdtSpentWithFee = (usdtSpent + fee)
954+ if ((usdtSpentWithFee > amt))
955+ then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)"))
956+ else {
957+ let rest = if (((amt - usdtSpentWithFee) > 0))
958+ then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)]
959+ else nil
960+ let activitiesAmount = (usdtSpent / 100)
961+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
962+ $Tuple2((((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult))
963+ }
964+ }
965+ }
966+ }
967+ }
968+ }
582969
583970
584971
591978 else {
592979 let pmt = i.payments[0]
593980 let amt = pmt.amount
594- let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
595- if ((pmtAssetId != usdtAssetId))
981+ if (if (!(isDefined(pmt.assetId)))
982+ then true
983+ else (value(pmt.assetId) != usdtAssetId))
596984 then throw("USDT payments only!")
597985 else {
598986 let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
599987 if ((curLocation[locIdxType] != "F"))
600988 then throw(("Duck location type should be Factory, but is " + curLocation[locIdxType]))
601989 else {
602- let locId = curLocation[locIdxId]
603990 let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
604991 let resList = split(currentPack[bpIdxRes], "_")
605992 let matList = split(currentPack[bpIdxMat], "_")
606- func exchanger (acc,j) = {
607- let whKey = keyFactoryWarehouseByIdAndType(locId, j)
608- let w0 = valueOrElse(getInteger(whKey), 0)
609- let amj = amounts[j]
610- if ((amj > parseIntValue(resList[j])))
611- then throw(((((("You have " + resList[j]) + " of ") + resTypes[j]) + ", but tried to exchange ") + toString(amj)))
612- else if ((0 > amj))
613- then throw(((("You tried to exchange negative amount of " + resTypes[j]) + ": ") + toString(amj)))
614- else if ((amj > 0))
615- then $Tuple5((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)), (acc._5 + amj))
616- else $Tuple5((acc._1 :+ resList[j]), (acc._2 :+ matList[j]), acc._3, acc._4, acc._5)
617- }
993+ let $t03764837754 = exchangeResourcesCommon(resList, matList, amounts)
994+ let newRes = $t03764837754._1
995+ let newMat = $t03764837754._2
996+ let usdtSpent = $t03764837754._3
997+ let totalAmountConverted = $t03764837754._4
998+ if ((usdtSpent > amt))
999+ then throw(((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)))
1000+ else {
1001+ let newPack = makeString([currentPack[bpIdxLevel], makeString(newRes, "_"), makeString(newMat, "_"), currentPack[bpIdxProd]], ":")
1002+ let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
1003+ let rest = if (((amt - usdtSpent) > 0))
1004+ then [ScriptTransfer(i.caller, (amt - usdtSpent), usdtAssetId)]
1005+ else nil
1006+ let activitiesAmount = (usdtSpent / 100)
1007+ let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalAmountConverted, MULT8)], nil))
1008+ $Tuple2((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult))
1009+ }
1010+ }
1011+ }
1012+ }
1013+ }
6181014
619- let merged = {
620- let $l = ITER6
621- let $s = size($l)
622- let $acc0 = $Tuple5(nil, nil, 0, nil, 0)
623- func $f0_1 ($a,$i) = if (($i >= $s))
624- then $a
625- else exchanger($a, $l[$i])
6261015
627- func $f0_2 ($a,$i) = if (($i >= $s))
628- then $a
629- else throw("List size exceeds 6")
6301016
631- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
632- }
633- if ((merged._3 > amt))
634- then throw(((("Insufficient payment! Attached=" + toString(amt)) + ", required=") + toString(merged._3)))
1017+@Callable(i)
1018+func exchangeResourcesDuckDelivery (amounts) = {
1019+ let prologResult = prolog()
1020+ let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
1021+ if ((size(i.payments) != 1))
1022+ then throw("exactly 1 payment must be attached")
1023+ else {
1024+ let pmt = i.payments[0]
1025+ let amt = pmt.amount
1026+ if (if (!(isDefined(pmt.assetId)))
1027+ then true
1028+ else (value(pmt.assetId) != usdtAssetId))
1029+ then throw("USDT payments only!")
1030+ else {
1031+ let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
1032+ let resList = split(currentPack[bpIdxRes], "_")
1033+ let matList = split(currentPack[bpIdxMat], "_")
1034+ let $t03918939295 = exchangeResourcesCommon(resList, matList, amounts)
1035+ let newRes = $t03918939295._1
1036+ let newMat = $t03918939295._2
1037+ let usdtSpent = $t03918939295._3
1038+ let totalAmountConverted = $t03918939295._4
1039+ let feePart = fraction(usdtSpent, DELIVERY_FEE15, MULT6)
1040+ let fee = if ((MIN_USDT_FEE_DELIVERY15 > feePart))
1041+ then MIN_USDT_FEE_DELIVERY15
1042+ else feePart
1043+ let usdtSpentWithFee = (usdtSpent + fee)
1044+ if ((usdtSpentWithFee > amt))
1045+ then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)"))
1046+ else {
1047+ let newPack = makeString([currentPack[bpIdxLevel], makeString(newRes, "_"), makeString(newMat, "_"), currentPack[bpIdxProd]], ":")
1048+ let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
1049+ let rest = if (((amt - usdtSpentWithFee) > 0))
1050+ then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)]
1051+ else nil
1052+ let activitiesAmount = (usdtSpent / 100)
1053+ let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalAmountConverted, MULT8)], nil))
1054+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
1055+ $Tuple2(((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult))
1056+ }
1057+ }
1058+ }
1059+ }
1060+
1061+
1062+
1063+@Callable(i)
1064+func exchangeResourcesLandDelivery (amounts,landAssetId) = {
1065+ let prologResult = prolog()
1066+ if ((size(i.payments) != 1))
1067+ then throw("exactly 1 payment must be attached")
1068+ else {
1069+ let pmt = i.payments[0]
1070+ let amt = pmt.amount
1071+ if (if (!(isDefined(pmt.assetId)))
1072+ then true
1073+ else (value(pmt.assetId) != usdtAssetId))
1074+ then throw("USDT payments only!")
1075+ else {
1076+ let user = i.caller
1077+ let addr = toString(user)
1078+ let asset = value(assetInfo(fromBase58String(landAssetId)))
1079+ if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId)))))
1080+ then throw((("NFT " + asset.name) + " is not staked"))
1081+ else {
1082+ let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
1083+ if ((owner != addr))
1084+ then throw((LANDPREFIX + " is not yours"))
6351085 else {
636- let newPack = makeString([currentPack[bpIdxLevel], makeString(merged._1, "_"), makeString(merged._2, "_"), currentPack[bpIdxProd]], ":")
637- let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
638- let rest = if (((amt - merged._3) > 0))
639- then [ScriptTransfer(i.caller, (amt - merged._3), usdtAssetId)]
640- else nil
641- let activitiesAmount = (merged._3 / 100)
642- let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, merged._5, MULT8)], nil))
643- $Tuple2(((rest ++ merged._4) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(result, prologResult, statsResult))
1086+ let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil))
1087+ let currentWh = split_4C(wh, ":")
1088+ let resList = split(currentWh[whIdxRes], "_")
1089+ let matList = split(currentWh[whIdxMat], "_")
1090+ let $t04151841624 = exchangeResourcesCommon(resList, matList, amounts)
1091+ let newRes = $t04151841624._1
1092+ let newMat = $t04151841624._2
1093+ let usdtSpent = $t04151841624._3
1094+ let totalAmountConverted = $t04151841624._4
1095+ let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newRes, "_"), makeString(newMat, "_"), currentWh[whIdxProd], currentWh[whIdxLOFT]], ":")
1096+ let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil))
1097+ let statsResult = asInt(invoke(stakingContract, "updateAccStatsInternal", [addr, fraction(xpTrade, totalAmountConverted, MULT8)], nil))
1098+ let feePart = fraction(usdtSpent, DELIVERY_FEE15, MULT6)
1099+ let fee = if ((MIN_USDT_FEE_DELIVERY15 > feePart))
1100+ then MIN_USDT_FEE_DELIVERY15
1101+ else feePart
1102+ let usdtSpentWithFee = (usdtSpent + fee)
1103+ if ((usdtSpentWithFee > amt))
1104+ then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)"))
1105+ else {
1106+ let rest = if (((amt - usdtSpentWithFee) > 0))
1107+ then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)]
1108+ else nil
1109+ let activitiesAmount = (usdtSpent / 100)
1110+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
1111+ $Tuple2(((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult))
1112+ }
6441113 }
6451114 }
6461115 }
8171286
8181287
8191288 @Callable(i)
820-func acceptWarehouseOrder (bpOrderStr,landAssetId,duckAssetId) = {
1289+func acceptWarehouseOrder (bpOrderStr,shopLandAssetId,duckAssetId) = {
8211290 let prologResult = prolog()
8221291 let caller = i.originCaller
8231292 let callerAddr = toString(caller)
8291298 else if ((stakedDuckAssetId != duckAssetId))
8301299 then throw(((("Your staked duck is " + stakedDuckAssetId) + ", but passed ") + duckAssetId))
8311300 else {
832- let landAsset = value(assetInfo(fromBase58String(landAssetId)))
833- if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId)))))
834- then throw((("NFT " + landAsset.name) + " is not staked"))
1301+ let bpKey = keyBackpackByDuck(duckAssetId)
1302+ let currentPack = getBackpack(bpKey)
1303+ let bpResList = split(currentPack[bpIdxRes], "_")
1304+ let bpMatList = split(currentPack[bpIdxMat], "_")
1305+ let bpProdList = if ((currentPack[bpIdxProd] == ""))
1306+ then nil
1307+ else split_4C(currentPack[bpIdxProd], "_")
1308+ let $t05114451384 = acceptShopOrderCommon(shopLandAssetId, callerAddr, bpOrderStr, bpResList, bpMatList, bpProdList)
1309+ let shopAction = $t05114451384._1
1310+ let newUserRes = $t05114451384._2
1311+ let newUserMat = $t05114451384._3
1312+ let newUserProd = $t05114451384._4
1313+ let usdWh2BpSaldo = $t05114451384._5
1314+ let usdBp2WhSaldo = $t05114451384._6
1315+ let xpAmount = $t05114451384._7
1316+ let shopLandOwner = $t05114451384._8
1317+ let shopWhSave = $t05114451384._9
1318+ let accStatsResult = $t05114451384._10
1319+ let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, 0)]
1320+ let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, 0)
1321+ let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString_2C(newUserProd, "_")], ":")
1322+ let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil))
1323+ let duckStatsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpShop, xpAmount, MULT8)], nil))
1324+ $Tuple2((actions1 ++ actions2), $Tuple5(prologResult, shopWhSave, bpSave, duckStatsResult, accStatsResult))
1325+ }
1326+ }
1327+
1328+
1329+
1330+@Callable(i)
1331+func acceptShopOrderDuckDelivery (orderStr,shopLandAssetId) = if (!(KS_ALLOW_DELIVERY))
1332+ then throw("Delivery feature is turned off!")
1333+ else {
1334+ let prologResult = prolog()
1335+ let caller = i.originCaller
1336+ let callerAddr = toString(caller)
1337+ let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(callerAddr)), "You don't have a duck staked")
1338+ let bpKey = keyBackpackByDuck(duckAssetId)
1339+ let currentPack = getBackpack(bpKey)
1340+ let bpResList = split(currentPack[bpIdxRes], "_")
1341+ let bpMatList = split(currentPack[bpIdxMat], "_")
1342+ let bpProdList = if ((currentPack[bpIdxProd] == ""))
1343+ then nil
1344+ else split_4C(currentPack[bpIdxProd], "_")
1345+ let $t05282353061 = acceptShopOrderCommon(shopLandAssetId, callerAddr, orderStr, bpResList, bpMatList, bpProdList)
1346+ let shopAction = $t05282353061._1
1347+ let newUserRes = $t05282353061._2
1348+ let newUserMat = $t05282353061._3
1349+ let newUserProd = $t05282353061._4
1350+ let usdWh2BpSaldo = $t05282353061._5
1351+ let usdBp2WhSaldo = $t05282353061._6
1352+ let xpAmount = $t05282353061._7
1353+ let shopLandOwner = $t05282353061._8
1354+ let shopWhSave = $t05282353061._9
1355+ let accStatsResult = $t05282353061._10
1356+ let deliveryFeePart = fraction((usdBp2WhSaldo + usdWh2BpSaldo), DELIVERY_FEE, MULT6)
1357+ let deliveryFee = if ((MIN_USDT_FEE_DELIVERY > deliveryFeePart))
1358+ then MIN_USDT_FEE_DELIVERY
1359+ else deliveryFeePart
1360+ let spentFee = fraction(deliveryFee, usdBp2WhSaldo, (usdBp2WhSaldo + usdWh2BpSaldo))
1361+ let receivedFee = (deliveryFee - spentFee)
1362+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
1363+ let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, receivedFee)]
1364+ let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, spentFee)
1365+ let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString_2C(newUserProd, "_")], ":")
1366+ let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil))
1367+ let duckStatsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpShop, xpAmount, MULT8)], nil))
1368+ $Tuple2(((actions1 ++ actions2) :+ IntegerEntry(deliveryFundKey, (fundTotal + deliveryFee))), $Tuple5(prologResult, shopWhSave, bpSave, duckStatsResult, accStatsResult))
1369+ }
1370+
1371+
1372+
1373+@Callable(i)
1374+func acceptShopOrderLandDelivery (orderStr,shopLandAssetId,myLandAssetId) = if (!(KS_ALLOW_DELIVERY))
1375+ then throw("Delivery feature is turned off!")
1376+ else {
1377+ let prologResult = prolog()
1378+ let caller = i.originCaller
1379+ let callerAddr = toString(caller)
1380+ let asset = value(assetInfo(fromBase58String(myLandAssetId)))
1381+ if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(myLandAssetId)))))
1382+ then throw((("NFT " + asset.name) + " is not staked"))
1383+ else {
1384+ let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(myLandAssetId)), (("NFT " + asset.name) + " is orphaned"))
1385+ if ((owner != callerAddr))
1386+ then throw((LANDPREFIX + " is not yours"))
8351387 else {
836- let landOwner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + landAsset.name) + " is orphaned"))
837- if ((landOwner == callerAddr))
838- then throw("You cannot trade with yourself")
839- else {
840- let bpOrderParts = split_4C(bpOrderStr, ":")
841- if ((size(bpOrderParts) != 3))
842- then throw("bpOrderStr should contain exactly 2 ':' separators")
843- else {
844- let bpOrdRes = split(bpOrderParts[0], "_")
845- let bpOrdMat = split(bpOrderParts[1], "_")
846- let bpOrdProd = if ((bpOrderParts[2] == ""))
847- then nil
848- else split_4C(bpOrderParts[2], "_")
849- if ((size(bpOrdRes) != NUMRES))
850- then throw("All 6 resources should be passed")
851- else if ((size(bpOrdMat) != NUMRES))
852- then throw("All 6 materials should be passed")
853- else {
854- let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil))
855- let currentWh = split_4C(wh, ":")
856- let currWhRes = split(currentWh[whIdxRes], "_")
857- let currWhMat = split(currentWh[whIdxMat], "_")
858- let currWhProd = if ((currentWh[whIdxProd] == ""))
859- then nil
860- else split_4C(currentWh[whIdxProd], "_")
861- let currWhLockedVol = parseIntValue(split(currentWh[whIdxLOFT], "_")[volLocked])
862- let bpKey = keyBackpackByDuck(duckAssetId)
863- let currentPack = getBackpack(bpKey)
864- let bpResList = split(currentPack[bpIdxRes], "_")
865- let bpMatList = split(currentPack[bpIdxMat], "_")
866- let bpProdList = if ((currentPack[bpIdxProd] == ""))
867- then nil
868- else split_4C(currentPack[bpIdxProd], "_")
869- let ordKey = keyOrderByLand(landAssetId)
870- let whOrd = getOrder(ordKey)
871- let whOrdRes = split(whOrd[ordIdxRes], "_")
872- let whOrdMat = split(whOrd[ordIdxMat], "_")
873- let whOrdProd = if ((whOrd[ordIdxProd] == ""))
874- then nil
875- else split_4C(whOrd[ordIdxProd], "_")
876- let r = {
877- let $l = bpOrdRes
878- let $s = size($l)
879- let $acc0 = $Tuple13(nil, nil, nil, 0, 0, 0, 0, bpResList, currWhRes, whOrdRes, resTypes, false, 0)
880- func $f0_1 ($a,$i) = if (($i >= $s))
881- then $a
882- else acceptCommon($a, $l[$i])
883-
884- func $f0_2 ($a,$i) = if (($i >= $s))
885- then $a
886- else throw("List size exceeds 6")
887-
888- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
889- }
890- let m = {
891- let $l = bpOrdMat
892- let $s = size($l)
893- let $acc0 = $Tuple13(nil, nil, nil, r._4, r._5, r._6, 0, bpMatList, currWhMat, whOrdMat, matTypes, false, r._13)
894- func $f1_1 ($a,$i) = if (($i >= $s))
895- then $a
896- else acceptCommon($a, $l[$i])
897-
898- func $f1_2 ($a,$i) = if (($i >= $s))
899- then $a
900- else throw("List size exceeds 6")
901-
902- $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
903- }
904- let p = if ((size(bpOrdProd) != 0))
905- then {
906- let $l = bpOrdProd
907- let $s = size($l)
908- let $acc0 = $Tuple13(nil, nil, nil, m._4, m._5, m._6, 0, bpProdList, currWhProd, whOrdProd, prodTypes, true, m._13)
909- func $f2_1 ($a,$i) = if (($i >= $s))
910- then $a
911- else acceptCommon($a, $l[$i])
912-
913- func $f2_2 ($a,$i) = if (($i >= $s))
914- then $a
915- else throw("List size exceeds 50")
916-
917- $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)
918- }
919- else $Tuple13(currWhProd, whOrdProd, bpProdList, m._4, m._5, m._6, 0, bpProdList, currWhProd, whOrdProd, prodTypes, true, m._13)
920- let volSaldo = p._4
921- let newLockedVol = if ((0 > (currWhLockedVol - volSaldo)))
922- then 0
923- else (currWhLockedVol - volSaldo)
924- let whStr = makeString_2C([currentWh[whIdxLevels], makeString(r._1, "_"), makeString(m._1, "_"), makeString_2C(p._1, "_"), toString(newLockedVol)], ":")
925- let newWhOrdStr = makeString_2C([makeString(r._2, "_"), makeString(m._2, "_"), makeString_2C(p._2, "_")], ":")
926- let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(r._3, "_"), makeString(m._3, "_"), makeString_2C(p._3, "_")], ":")
927- let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil))
928- let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil))
929- let duckStatsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpShop, p._13, MULT8)], nil))
930- let accStatsResult = asInt(invoke(stakingContract, "updateAccStats", [landOwner, fraction(xpShop, p._13, MULT8)], nil))
931- let actions = [StringEntry(ordKey, newWhOrdStr)]
932- let usdWh2BpSaldo = p._5
933- let actions1 = if ((usdWh2BpSaldo > 0))
934- then {
935- let usdWh2BpFee = fraction(p._5, AUCTIONFEE, MULT6)
936- let refByKey = keyAddressRefBy(callerAddr)
937- let refBy = getString(stakingContract, refByKey)
938- if (isDefined(refBy))
939- then (((actions :+ ScriptTransfer(caller, (p._5 - (3 * usdWh2BpFee)), usdtAssetId)) :+ ScriptTransfer(restContract, usdWh2BpFee, usdtAssetId)) :+ ScriptTransfer(addressFromStringValue(value(refBy)), usdWh2BpFee, usdtAssetId))
940- else ((actions :+ ScriptTransfer(caller, (p._5 - (3 * usdWh2BpFee)), usdtAssetId)) :+ ScriptTransfer(restContract, usdWh2BpFee, usdtAssetId))
941- }
942- else actions
943- let usdBp2WhSaldo = p._6
944- let actions2 = if ((usdBp2WhSaldo > 0))
945- then if ((size(i.payments) != 1))
946- then throw("exactly 1 payment must be attached")
947- else {
948- let pmt = i.payments[0]
949- let amt = pmt.amount
950- let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
951- if ((pmtAssetId != usdtAssetId))
952- then throw("USDT payments only!")
953- else if ((amt != usdBp2WhSaldo))
954- then throw(("Payment needed is " + toString(usdBp2WhSaldo)))
955- else if ((MINSHOPPAYMENT > amt))
956- then throw(("Payment should be at least " + toString(MINSHOPPAYMENT)))
957- else {
958- let usdBp2WhFee = fraction(p._6, AUCTIONFEE, MULT6)
959- let refByKey = keyAddressRefBy(landOwner)
960- let refBy = getString(stakingContract, refByKey)
961- if (isDefined(refBy))
962- then (((actions1 :+ ScriptTransfer(addressFromStringValue(landOwner), (p._6 - (3 * usdBp2WhFee)), usdtAssetId)) :+ ScriptTransfer(restContract, usdBp2WhFee, usdtAssetId)) :+ ScriptTransfer(addressFromStringValue(value(refBy)), usdBp2WhFee, usdtAssetId))
963- else ((actions1 :+ ScriptTransfer(addressFromStringValue(landOwner), (p._6 - (3 * usdBp2WhFee)), usdtAssetId)) :+ ScriptTransfer(restContract, usdBp2WhFee, usdtAssetId))
964- }
965- }
966- else if ((size(i.payments) != 0))
967- then throw("No payments needed")
968- else actions1
969- $Tuple2(actions2, $Tuple5(prologResult, whSave, bpSave, duckStatsResult, accStatsResult))
970- }
971- }
972- }
1388+ let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [myLandAssetId], nil))
1389+ let currentWh = split_4C(wh, ":")
1390+ let resList = split(currentWh[whIdxRes], "_")
1391+ let matList = split(currentWh[whIdxMat], "_")
1392+ let prodList = if ((currentWh[whIdxProd] == ""))
1393+ then nil
1394+ else split(currentWh[whIdxProd], "_")
1395+ let $t05530055532 = acceptShopOrderCommon(shopLandAssetId, callerAddr, orderStr, resList, matList, prodList)
1396+ let shopAction = $t05530055532._1
1397+ let newUserRes = $t05530055532._2
1398+ let newUserMat = $t05530055532._3
1399+ let newUserProd = $t05530055532._4
1400+ let usdWh2BpSaldo = $t05530055532._5
1401+ let usdBp2WhSaldo = $t05530055532._6
1402+ let xpAmount = $t05530055532._7
1403+ let shopLandOwner = $t05530055532._8
1404+ let shopWhSave = $t05530055532._9
1405+ let accStatsResult = $t05530055532._10
1406+ let deliveryFeePart = fraction((usdBp2WhSaldo + usdWh2BpSaldo), DELIVERY_FEE, MULT6)
1407+ let deliveryFee = if ((MIN_USDT_FEE_DELIVERY > deliveryFeePart))
1408+ then MIN_USDT_FEE_DELIVERY
1409+ else deliveryFeePart
1410+ let spentFee = fraction(deliveryFee, usdBp2WhSaldo, (usdBp2WhSaldo + usdWh2BpSaldo))
1411+ let receivedFee = (deliveryFee - spentFee)
1412+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
1413+ let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, receivedFee)]
1414+ let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, spentFee)
1415+ let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString(newUserProd, "_"), currentWh[whIdxLOFT]], ":")
1416+ let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, myLandAssetId], nil))
1417+ let statsResult = asInt(invoke(stakingContract, "updateAccStatsInternal", [callerAddr, fraction(xpShop, xpAmount, MULT8)], nil))
1418+ $Tuple2(((actions1 ++ actions2) :+ IntegerEntry(deliveryFundKey, (fundTotal + deliveryFee))), $Tuple5(prologResult, shopWhSave, whSave, statsResult, accStatsResult))
9731419 }
9741420 }
975- }
1421+ }
9761422
9771423
9781424
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let xpTrade = 10000
55
66 let xpCraft = 10000
77
88 let xpSellToEs = 10000
99
1010 let xpShop = 10000
1111
1212 let LANDPREFIX = "LAND"
1313
1414 let NUMRES = 6
1515
1616 let DEFAULTLOCATION = "Africa_F_Africa"
1717
1818 let RESOURCEPRICEMIN = 39637
1919
2020 let ESMAXPACKAGES = 10
2121
2222 let ESBUYCOEF = 4
23+
24+let MIN_USDT_FEE_DELIVERY = 50000
25+
26+let MIN_USDT_FEE_DELIVERY15 = 75000
2327
2428 let resTypes = ["Oil", "Ore", "Wood", "Sand", "Clay", "Organic"]
2529
2630 let matTypes = ["Fuel", "Metal", "Plank", "Glass", "Plastic", "Protein"]
2731
2832 let prodTypes = ["First Aid Kit L1", "First Aid Kit L2", "First Aid Kit L3", "Backpack L1", "Backpack L2", "Backpack L3", "Food Ration L1", "Food Ration L2", "Food Ration L3", "Jet Pack L1", "Jet Pack L2", "Jet Pack L3", "Shield L1", "Shield L2", "Shield L3", "Mine L1", "Mine L2", "Mine L3", "Trap L1", "Trap L2", "Trap L3"]
2933
3034 let continents = ["Americas", "Europe", "Asia", "Africa", "Oceania"]
3135
3236 let COEFF2MAT = 10000000
3337
3438 let productionMatrix = ["8_8_8_17_17_42_12_0_30_0,0,0,0,0,0,0_", "8_8_8_17_17_42_24_0_60_0,0,5,2,0,0,0_", "8_8_8_17_17_42_36_0_120_0,0,10,4,0,0,0_", "8_19_19_8_27_19_26_1_20_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_52_1_40_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_78_1_80_0,0,0,0,0,0,0_001", "8_8_8_8_8_60_13_2_2_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_26_2_4_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_39_2_8_0,0,0,0,0,0,0_011", "30_30_3_17_17_3_30_3_30_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_60_3_50_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_90_3_70_0,0,0,0,0,0,0_111", "18_18_10_18_18_18_11_4_10_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_22_4_20_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_33_4_30_0,0,0,0,0,0,0_201", "4_13_22_4_35_22_23_0_50,1,0_0,0,0,0,0,0,0_", "4_13_22_4_35_22_46_0_50,1,1_0,2,5,0,0,0,0_", "4_13_22_4_35_22_69_0_50,2,1_0,5,10,0,0,0,0_", "5_25_40_5_10_15_20_1_30,1,1_0,0,0,0,0,0,0_", "5_25_40_5_10_15_40_1_30,1,2_2,1,3,0,0,0,0_", "5_25_40_5_10_15_60_1_30,1,3_5,2,8,0,0,0,0_"]
3539
3640 let rIdxCoeff = 6
3741
3842 let rIdxContinent = 7
3943
4044 let RECIPESIZE = 11
4145
4246 let PRODUCTPKGSIZE = 10
4347
4448 let whIdxLevels = 0
4549
4650 let whIdxRes = 1
4751
4852 let whIdxMat = 2
4953
5054 let whIdxProd = 3
5155
5256 let whIdxLOFT = 4
5357
5458 let volLocked = 0
5559
5660 let volTotal = 3
5761
5862 let bpIdxLevel = 0
5963
6064 let bpIdxRes = 1
6165
6266 let bpIdxMat = 2
6367
6468 let bpIdxProd = 3
6569
6670 let locIdxContinent = 0
6771
6872 let locIdxType = 1
6973
7074 let locIdxId = 2
7175
7276 func keyLandAssetIdToOwner (assetId) = ("no_" + assetId)
7377
7478
7579 func keyStakedTimeByAssetId (assetId) = ("st_" + assetId)
7680
7781
7882 func keyAddressRefBy (addr) = ("accRefBy_" + addr)
7983
8084
8185 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
8286
8387
8488 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
8589
8690
8791 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
8892
8993
9094 func keyOrderByLand (landAssetId) = ("landOrder_" + landAssetId)
9195
9296
9397 func keyEsWarehouse () = "emergencyWarehouseProducts"
9498
9599
100+let deliveryFundKey = "deliveryFund"
101+
96102 func getRecipeMaterials (recipe) = (parseIntValue(recipe[rIdxCoeff]) * COEFF2MAT)
97103
104+
105+let KS_ALLOW_DELIVERY = false
98106
99107 let chain = take(drop(this.bytes, 1), 1)
100108
101109 let usdtAssetId = match chain {
102110 case _ =>
103111 if ((base58'2W' == $match0))
104112 then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
105113 else if ((base58'2T' == $match0))
106114 then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63'
107115 else throw("Unknown chain")
108116 }
109117
110118 let defaultRestAddressStr = match chain {
111119 case _ =>
112120 if ((base58'2W' == $match0))
113121 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
114122 else if ((base58'2T' == $match0))
115123 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
116124 else throw("Unknown chain")
117125 }
118126
119127 let SEP = "__"
120128
121129 let MULT5 = 100000
122130
123131 let MULT6 = 1000000
124132
125133 let MULT8 = 100000000
126134
127135 let MULT10 = 10000000000
128136
129137 let MINSHOPPAYMENT = 100000
130138
131139 let ITER6 = [0, 1, 2, 3, 4, 5]
132140
133141 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
134142
135143
136144 let IdxCfgStakingDapp = 1
137145
138146 func keyRestCfg () = "%s__restConfig"
139147
140148
141149 func keyRestAddress () = "%s__restAddr"
142150
143151
144152 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
145153
146154
147155 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
148156
149157
150158 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
151159
152160 let restCfg = readRestCfgOrFail(restContract)
153161
154162 let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
155163
156164 func asString (v) = match v {
157165 case s: String =>
158166 s
159167 case _ =>
160168 throw("fail to cast into String")
161169 }
162170
163171
164172 func asInt (v) = match v {
165173 case n: Int =>
166174 n
167175 case _ =>
168176 throw("fail to cast into Int")
169177 }
170178
171179
172180 func keyBlocked () = "contractsBlocked"
173181
174182
175183 func fixedPoint (val,decimals) = {
176184 let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
177185 let lowPart = toString((val % tenPow))
178186 let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
179187 (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
180188 }
181189
182190
183191 let FACTORYMAXWAREHOUSE = 10000000000
184192
185193 let SELLMULTIPLIER = 200
186194
187195 let BUYMULTIPLIER = 300
188196
189197 let AUCTIONFEE = 10000
190198
199+let DELIVERY_FEE = 10000
200+
201+let DELIVERY_FEE15 = 15000
202+
191203 func keyFactoryWarehouseByIdAndType (factoryId,resType) = ((("factoryWhByContinentAndRes_" + factoryId) + "_") + toString(resType))
192204
193205
194206 let ordIdxRes = 0
195207
196208 let ordIdxMat = 1
197209
198210 let ordIdxProd = 2
199211
200212 func getOrder (ordKey) = {
201213 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:"), ":")
202214 [if ((size(split(p[ordIdxRes], "_")) == NUMRES))
203215 then p[ordIdxRes]
204216 else "0@0_0@0_0@0_0@0_0@0_0@0", if ((size(split(p[ordIdxMat], "_")) == NUMRES))
205217 then p[ordIdxMat]
206218 else "0@0_0@0_0@0_0@0_0@0_0@0", p[ordIdxProd]]
207219 }
208220
209221
210222 func toVolume (amount,pkgSize,isProduct) = if (isProduct)
211223 then {
212224 let pkgs = if ((amount >= 0))
213225 then (((amount + pkgSize) - 1) / pkgSize)
214226 else -((((-(amount) + pkgSize) - 1) / pkgSize))
215227 (pkgs * MULT8)
216228 }
217229 else amount
218230
219231
220232 func sellInternal (locId,resType,amount,minPrice) = {
221233 let whKey = keyFactoryWarehouseByIdAndType(locId, resType)
222234 let w0 = valueOrElse(getInteger(whKey), 0)
223235 let r0 = if ((w0 > FACTORYMAXWAREHOUSE))
224236 then 0
225237 else if (((w0 + amount) > FACTORYMAXWAREHOUSE))
226238 then (FACTORYMAXWAREHOUSE - w0)
227239 else amount
228240 let usdtReceived = (fraction(r0, ((SELLMULTIPLIER * RESOURCEPRICEMIN) - fraction(((100 * w0) + (50 * r0)), RESOURCEPRICEMIN, FACTORYMAXWAREHOUSE)), MULT10) + fraction((amount - r0), RESOURCEPRICEMIN, MULT8))
229241 let min99 = (minPrice - (minPrice / 100))
230242 if (((min99 * amount) > (usdtReceived * MULT8)))
231243 then throw((((((((((("Actual price = " + toString(usdtReceived)) + " / ") + toString(amount)) + " < minPrice = ") + toString(minPrice)) + ", (") + locId) + ", ") + resTypes[resType]) + ")"))
232244 else $Tuple2(IntegerEntry(whKey, (w0 + amount)), usdtReceived)
233245 }
234246
235247
236248 func buyInternal (locId,matType,amount,maxPrice) = {
237249 let whKey = keyFactoryWarehouseByIdAndType(locId, matType)
238250 let w0 = valueOrElse(getInteger(whKey), 0)
239251 let m1 = if ((w0 > FACTORYMAXWAREHOUSE))
240252 then min([amount, (w0 - FACTORYMAXWAREHOUSE)])
241253 else 0
242254 let m0 = min([w0, (amount - m1)])
243255 let m = (m0 + m1)
244256 let usdtSpent = (fraction(m0, ((BUYMULTIPLIER * RESOURCEPRICEMIN) - fraction(((100 * w0) - (50 * m0)), RESOURCEPRICEMIN, FACTORYMAXWAREHOUSE)), MULT10) + fraction(m1, (2 * RESOURCEPRICEMIN), MULT8))
245257 let max101 = (maxPrice + (maxPrice / 100))
246258 if (((usdtSpent * MULT8) > (max101 * m)))
247259 then throw((((((((((("Actual price = " + toString(usdtSpent)) + " / ") + toString(m)) + " > maxPrice = ") + toString(maxPrice)) + ", (") + locId) + ", ") + matTypes[matType]) + ")"))
248260 else $Tuple3(IntegerEntry(whKey, (w0 - m)), usdtSpent, m)
249261 }
250262
251263
252264 func getBackpack (bpKey) = {
253- let p = split(valueOrElse(getString(stakingContract, bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
265+ let p = split_4C(valueOrElse(getString(stakingContract, bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
254266 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
255267 then p[bpIdxRes]
256268 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
257269 then p[bpIdxMat]
258270 else "0_0_0_0_0_0", p[bpIdxProd]]
259271 }
260272
261273
262274 func checkBlocked () = if (valueOrElse(getBoolean(stakingContract, keyBlocked()), false))
263275 then throw("Contracts are under maintenance")
264276 else unit
265277
266278
267279 func prolog () = asInt(invoke(stakingContract, "saveLastTx", nil, nil))
268280
269281
270282 func setCommon (acc,ignoredIterator) = {
271283 let j = acc._1
272284 let item = if ((size(acc._10) > j))
273285 then acc._10[j]
274286 else "0@0"
275287 let isProd = acc._8
276288 let itemParts = split(item, "@")
277289 if ((size(itemParts) != 2))
278290 then throw("Incorrect order format, should be amount@price")
279291 else {
280292 let newOrdAm = parseIntValue(itemParts[0])
281293 let newOrdPr = parseIntValue(itemParts[1])
282294 let newOrdUsd = if (isProd)
283295 then (newOrdAm * newOrdPr)
284296 else fraction(newOrdAm, newOrdPr, MULT8)
285297 let newOrdVol = toVolume(newOrdAm, PRODUCTPKGSIZE, isProd)
286298 let whInit = if ((size(acc._6) > j))
287299 then parseIntValue(acc._6[j])
288300 else 0
289301 let curOrdParts = split(if ((size(acc._7) > j))
290302 then acc._7[j]
291303 else "0@0", "@")
292304 let curOrdAm = parseIntValue(curOrdParts[0])
293305 let curOrdPr = parseIntValue(curOrdParts[1])
294306 if (if ((0 > curOrdPr))
295307 then true
296308 else (0 > newOrdPr))
297309 then throw("Price can't be negative")
298310 else {
299311 let curOrdUsd = if (isProd)
300312 then (curOrdAm * curOrdPr)
301313 else fraction(curOrdAm, curOrdPr, MULT8)
302314 if ((newOrdAm == 0))
303315 then if ((curOrdAm > 0))
304316 then $Tuple10((j + 1), (acc._2 :+ toString(whInit)), acc._3, acc._4, (acc._5 - curOrdUsd), acc._6, acc._7, isProd, (acc._9 + toVolume(whInit, PRODUCTPKGSIZE, isProd)), acc._10)
305317 else $Tuple10((j + 1), (acc._2 :+ toString((whInit - curOrdAm))), acc._3, acc._4, acc._5, acc._6, acc._7, isProd, (acc._9 + toVolume((whInit - curOrdAm), PRODUCTPKGSIZE, isProd)), acc._10)
306318 else if ((newOrdAm > 0))
307319 then if ((0 > curOrdAm))
308320 then $Tuple10((j + 1), (acc._2 :+ toString((whInit - curOrdAm))), (acc._3 + newOrdVol), acc._4, (acc._5 + newOrdUsd), acc._6, acc._7, isProd, toVolume((whInit - curOrdAm), PRODUCTPKGSIZE, isProd), acc._10)
309321 else $Tuple10((j + 1), (acc._2 :+ toString(whInit)), (acc._3 + newOrdVol), acc._4, ((acc._5 + newOrdUsd) - curOrdUsd), acc._6, acc._7, isProd, toVolume(whInit, PRODUCTPKGSIZE, isProd), acc._10)
310322 else if ((0 > curOrdAm))
311323 then {
312324 let amDiff = (curOrdAm - newOrdAm)
313325 if ((0 > (whInit - amDiff)))
314326 then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whInit)) + " available"))
315327 else $Tuple10((j + 1), (acc._2 :+ toString((whInit - amDiff))), acc._3, (acc._4 - newOrdVol), acc._5, acc._6, acc._7, isProd, toVolume((whInit - amDiff), PRODUCTPKGSIZE, isProd), acc._10)
316328 }
317329 else if ((0 > (whInit + newOrdAm)))
318330 then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whInit)) + " available"))
319331 else $Tuple10((j + 1), (acc._2 :+ toString((whInit + newOrdAm))), acc._3, (acc._4 - newOrdVol), (acc._5 - curOrdUsd), acc._6, acc._7, isProd, toVolume((whInit + newOrdAm), PRODUCTPKGSIZE, isProd), acc._10)
320332 }
321333 }
322334 }
323335
324336
325337 func setInternal (currentWh,currentOrd,newOrd) = {
326338 let currWhRes = split(currentWh[whIdxRes], "_")
327339 let currWhMat = split(currentWh[whIdxMat], "_")
328340 let currWhProd = if ((currentWh[whIdxProd] == ""))
329341 then nil
330342 else split_4C(currentWh[whIdxProd], "_")
331343 let currentOrdRes = split(currentOrd[ordIdxRes], "_")
332344 let currentOrdMat = split(currentOrd[ordIdxMat], "_")
333345 let currentOrdProd = if ((currentOrd[ordIdxProd] == ""))
334346 then nil
335347 else split_4C(currentOrd[ordIdxProd], "_")
336348 if ((size(newOrd) != 3))
337349 then throw("newOrderStr should contain exactly 2 ':' separators")
338350 else {
339351 let resParts = split(newOrd[0], "_")
340352 let matParts = split(newOrd[1], "_")
341353 let prodParts = if ((newOrd[2] == ""))
342354 then nil
343355 else split_4C(newOrd[2], "_")
344356 if ((size(resParts) != NUMRES))
345357 then throw("All 6 resources should be passed")
346358 else if ((size(matParts) != NUMRES))
347359 then throw("All 6 materials should be passed")
348360 else {
349361 let r = {
350362 let $l = resTypes
351363 let $s = size($l)
352364 let $acc0 = $Tuple10(0, nil, 0, 0, 0, currWhRes, currentOrdRes, false, 0, resParts)
353365 func $f0_1 ($a,$i) = if (($i >= $s))
354366 then $a
355367 else setCommon($a, $l[$i])
356368
357369 func $f0_2 ($a,$i) = if (($i >= $s))
358370 then $a
359371 else throw("List size exceeds 6")
360372
361373 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
362374 }
363375 let m = {
364376 let $l = matTypes
365377 let $s = size($l)
366378 let $acc0 = $Tuple10(0, nil, r._3, r._4, r._5, currWhMat, currentOrdMat, false, r._9, matParts)
367379 func $f1_1 ($a,$i) = if (($i >= $s))
368380 then $a
369381 else setCommon($a, $l[$i])
370382
371383 func $f1_2 ($a,$i) = if (($i >= $s))
372384 then $a
373385 else throw("List size exceeds 6")
374386
375387 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
376388 }
377389 let p = {
378390 let $l = prodTypes
379391 let $s = size($l)
380392 let $acc0 = $Tuple10(0, nil, m._3, m._4, m._5, currWhProd, currentOrdProd, true, m._9, prodParts)
381393 func $f2_1 ($a,$i) = if (($i >= $s))
382394 then $a
383395 else setCommon($a, $l[$i])
384396
385397 func $f2_2 ($a,$i) = if (($i >= $s))
386398 then $a
387399 else throw("List size exceeds 50")
388400
389401 $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)
390402 }
391403 $Tuple7(r._2, m._2, p._2, p._3, p._4, p._5, p._9)
392404 }
393405 }
394406 }
395407
396408
397409 func acceptCommon (acc,bpOrdItem) = {
398410 let j = acc._7
399411 let isProd = acc._12
400412 let bpOrdParts = split(bpOrdItem, "@")
401413 if ((size(bpOrdParts) != 2))
402414 then throw("Incorrect order format, should be amount@price")
403415 else {
404416 let bpOrdAm = parseIntValue(bpOrdParts[0])
405417 let bpOrdPr = parseIntValue(bpOrdParts[1])
406418 if ((0 > bpOrdPr))
407419 then throw("Price can't be negative")
408420 else {
409421 let bpOrdUsd = if (isProd)
410422 then (bpOrdAm * bpOrdPr)
411423 else fraction(bpOrdAm, bpOrdPr, MULT8)
412424 let bpInit = if ((size(acc._8) > j))
413425 then parseIntValue(acc._8[j])
414426 else 0
415427 let whInit = if ((size(acc._9) > j))
416428 then parseIntValue(acc._9[j])
417429 else 0
418430 let whOrdInit = if ((size(acc._10) > j))
419431 then acc._10[j]
420432 else "0@0"
421433 let whOrdParts = split(whOrdInit, "@")
422434 let whOrdAm = parseIntValue(whOrdParts[0])
423435 let whOrdPr = parseIntValue(whOrdParts[1])
424436 if (if ((bpOrdAm != 0))
425437 then (bpOrdPr != whOrdPr)
426438 else false)
427439 then throw(((((("Prices of " + acc._11[j]) + " don't match! WH price=") + toString(whOrdPr)) + ", your price=") + toString(bpOrdPr)))
428440 else {
429441 let whOrdUsd = if (isProd)
430442 then (whOrdAm * whOrdPr)
431443 else fraction(whOrdAm, whOrdPr, MULT8)
432444 let deltaVol = toVolume(bpOrdAm, PRODUCTPKGSIZE, isProd)
433445 if ((bpOrdAm == 0))
434446 then $Tuple13((acc._1 :+ toString(whInit)), (acc._2 :+ whOrdInit), (acc._3 :+ toString(bpInit)), acc._4, acc._5, acc._6, (acc._7 + 1), acc._8, acc._9, acc._10, acc._11, isProd, acc._13)
435447 else if ((bpOrdAm > 0))
436448 then if ((0 > whOrdAm))
437449 then if ((bpOrdAm > -(whOrdAm)))
438450 then throw(((((("Attempt to buy " + toString(bpOrdAm)) + " of ") + acc._11[j]) + ", but warehouse only sells ") + toString(-(whOrdAm))))
439451 else $Tuple13((acc._1 :+ toString(whInit)), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ toString((bpInit + bpOrdAm))), (acc._4 + deltaVol), acc._5, (acc._6 + bpOrdUsd), (acc._7 + 1), acc._8, acc._9, acc._10, acc._11, isProd, (acc._13 + (if (isProd)
440452 then (bpOrdAm * MULT8)
441453 else bpOrdAm)))
442454 else throw((("Attempt to buy " + acc._11[j]) + " while warehouse doesn't sell it"))
443455 else if ((whOrdAm > 0))
444456 then if ((-(bpOrdAm) > whOrdAm))
445457 then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + " of ") + acc._11[j]) + ", but warehouse only buys ") + toString(whOrdAm)))
446458 else if ((-(bpOrdAm) > bpInit))
447459 then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + ", but you only have ") + toString(bpInit)) + " of ") + acc._11[j]))
448460 else $Tuple13((acc._1 :+ toString((whInit - bpOrdAm))), (acc._2 :+ ((toString((whOrdAm + bpOrdAm)) + "@") + toString(whOrdPr))), (acc._3 :+ toString((bpInit + bpOrdAm))), (acc._4 - deltaVol), (acc._5 - bpOrdUsd), acc._6, (acc._7 + 1), acc._8, acc._9, acc._10, acc._11, isProd, (acc._13 - (if (isProd)
449461 then (bpOrdAm * MULT8)
450462 else bpOrdAm)))
451463 else throw((("Attempt to sell " + acc._11[j]) + " while warehouse doesn't buy it"))
452464 }
453465 }
454466 }
455467 }
456468
457469
470+func sellResourcesCommon (resList,factoryLocId,amounts,minPrices) = {
471+ func adder (acc,j) = if ((amounts[j] > parseIntValue(resList[j])))
472+ then throw(((((("You have " + resList[j]) + " of ") + resTypes[j]) + ", but tried to sell ") + toString(amounts[j])))
473+ else if ((0 > amounts[j]))
474+ then throw(((("You tried to sell negative amount of " + resTypes[j]) + ": ") + toString(amounts[j])))
475+ else if ((amounts[j] > 0))
476+ then {
477+ let b = sellInternal(factoryLocId, j, amounts[j], minPrices[j])
478+ $Tuple4((acc._1 :+ b._1), (acc._2 :+ toString((parseIntValue(resList[j]) - amounts[j]))), (acc._3 + b._2), (acc._4 + amounts[j]))
479+ }
480+ else $Tuple4(acc._1, (acc._2 :+ resList[j]), acc._3, acc._4)
481+
482+ let $l = ITER6
483+ let $s = size($l)
484+ let $acc0 = $Tuple4(nil, nil, 0, 0)
485+ func $f0_1 ($a,$i) = if (($i >= $s))
486+ then $a
487+ else adder($a, $l[$i])
488+
489+ func $f0_2 ($a,$i) = if (($i >= $s))
490+ then $a
491+ else throw("List size exceeds 6")
492+
493+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
494+ }
495+
496+
497+func buyMaterialsCommon (matList,factoryLocId,amounts,maxPrices) = {
498+ func mUpdater (acc,j) = if ((0 > amounts[j]))
499+ then throw(((("You tried to buy negative amount of " + matTypes[j]) + ": ") + toString(amounts[j])))
500+ else if ((amounts[j] > 0))
501+ then {
502+ let b = buyInternal(factoryLocId, j, amounts[j], maxPrices[j])
503+ $Tuple4((acc._1 :+ b._1), (acc._2 :+ toString((parseIntValue(matList[j]) + b._3))), (acc._3 + b._2), (acc._4 + amounts[j]))
504+ }
505+ else $Tuple4(acc._1, (acc._2 :+ matList[j]), acc._3, acc._4)
506+
507+ let $l = ITER6
508+ let $s = size($l)
509+ let $acc0 = $Tuple4(nil, nil, 0, 0)
510+ func $f0_1 ($a,$i) = if (($i >= $s))
511+ then $a
512+ else mUpdater($a, $l[$i])
513+
514+ func $f0_2 ($a,$i) = if (($i >= $s))
515+ then $a
516+ else throw("List size exceeds 6")
517+
518+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
519+ }
520+
521+
522+func exchangeResourcesCommon (resList,matList,amounts) = {
523+ func exchanger (acc,j) = {
524+ let amj = amounts[j]
525+ if ((amj > parseIntValue(resList[j])))
526+ then throw(((((("You have " + resList[j]) + " of ") + resTypes[j]) + ", but tried to exchange ") + toString(amj)))
527+ else if ((0 > amj))
528+ then throw(((("You tried to exchange negative amount of " + resTypes[j]) + ": ") + toString(amj)))
529+ else if ((amj > 0))
530+ then $Tuple4((acc._1 :+ toString((parseIntValue(resList[j]) - amj))), (acc._2 :+ toString((parseIntValue(matList[j]) + amj))), (acc._3 + fraction(amj, RESOURCEPRICEMIN, MULT8)), (acc._4 + amj))
531+ else $Tuple4((acc._1 :+ resList[j]), (acc._2 :+ matList[j]), acc._3, acc._4)
532+ }
533+
534+ let $l = ITER6
535+ let $s = size($l)
536+ let $acc0 = $Tuple4(nil, nil, 0, 0)
537+ func $f0_1 ($a,$i) = if (($i >= $s))
538+ then $a
539+ else exchanger($a, $l[$i])
540+
541+ func $f0_2 ($a,$i) = if (($i >= $s))
542+ then $a
543+ else throw("List size exceeds 6")
544+
545+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
546+ }
547+
548+
549+func shop2userActions (usdWh2BpSaldo,callerAddr,receivedFee) = if ((usdWh2BpSaldo > 0))
550+ then {
551+ let usdWh2BpFee = fraction(usdWh2BpSaldo, AUCTIONFEE, MULT6)
552+ if ((receivedFee >= (usdWh2BpSaldo - (3 * usdWh2BpFee))))
553+ then throw(("This trade does not cover delivery cost of " + fixedPoint(receivedFee, 6)))
554+ else {
555+ let refByKey = keyAddressRefBy(callerAddr)
556+ let refBy = getString(stakingContract, refByKey)
557+ let caller = addressFromStringValue(callerAddr)
558+ (((if (isDefined(refBy))
559+ then [ScriptTransfer(addressFromStringValue(value(refBy)), usdWh2BpFee, usdtAssetId)]
560+ else nil) :+ ScriptTransfer(caller, ((usdWh2BpSaldo - (3 * usdWh2BpFee)) - receivedFee), usdtAssetId)) :+ ScriptTransfer(restContract, usdWh2BpFee, usdtAssetId))
561+ }
562+ }
563+ else nil
564+
565+
566+func user2shopActions (usdBp2WhSaldo,pmts,shopLandOwner,spentFee) = if ((usdBp2WhSaldo > 0))
567+ then if ((size(pmts) != 1))
568+ then throw("exactly 1 payment must be attached")
569+ else {
570+ let pmt = pmts[0]
571+ let amt = pmt.amount
572+ if (if (!(isDefined(pmt.assetId)))
573+ then true
574+ else (value(pmt.assetId) != usdtAssetId))
575+ then throw("USDT payments only!")
576+ else {
577+ let usdtSpentWithFee = (usdBp2WhSaldo + spentFee)
578+ if ((amt != usdtSpentWithFee))
579+ then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdBp2WhSaldo, 6)) + "+") + fixedPoint(spentFee, 6)) + "(delivery fee)"))
580+ else if ((MINSHOPPAYMENT > usdBp2WhSaldo))
581+ then throw(("Min shop trade is " + fixedPoint(MINSHOPPAYMENT, 6)))
582+ else {
583+ let usdBp2WhFee = fraction(usdBp2WhSaldo, AUCTIONFEE, MULT6)
584+ let refByKey = keyAddressRefBy(shopLandOwner)
585+ let refBy = getString(stakingContract, refByKey)
586+ (((if (isDefined(refBy))
587+ then [ScriptTransfer(addressFromStringValue(value(refBy)), usdBp2WhFee, usdtAssetId)]
588+ else nil) :+ ScriptTransfer(addressFromStringValue(shopLandOwner), (usdBp2WhSaldo - (3 * usdBp2WhFee)), usdtAssetId)) :+ ScriptTransfer(restContract, usdBp2WhFee, usdtAssetId))
589+ }
590+ }
591+ }
592+ else if ((size(pmts) != 0))
593+ then throw("No payments needed")
594+ else nil
595+
596+
597+func acceptShopOrderCommon (shopLandAssetId,callerAddr,bpOrderStr,bpResList,bpMatList,bpProdList) = {
598+ let landAsset = value(assetInfo(fromBase58String(shopLandAssetId)))
599+ if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(shopLandAssetId)))))
600+ then throw((("NFT " + landAsset.name) + " is not staked"))
601+ else {
602+ let shopLandOwner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(shopLandAssetId)), (("NFT " + landAsset.name) + " is orphaned"))
603+ if ((shopLandOwner == callerAddr))
604+ then throw("You cannot trade with yourself")
605+ else {
606+ let bpOrderParts = split_4C(bpOrderStr, ":")
607+ if ((size(bpOrderParts) != 3))
608+ then throw("bpOrderStr should contain exactly 2 ':' separators")
609+ else {
610+ let bpOrdRes = split(bpOrderParts[0], "_")
611+ let bpOrdMat = split(bpOrderParts[1], "_")
612+ let bpOrdProd = if ((bpOrderParts[2] == ""))
613+ then nil
614+ else split_4C(bpOrderParts[2], "_")
615+ if ((size(bpOrdRes) != NUMRES))
616+ then throw("All 6 resources should be passed")
617+ else if ((size(bpOrdMat) != NUMRES))
618+ then throw("All 6 materials should be passed")
619+ else {
620+ let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [shopLandAssetId], nil))
621+ let currentWh = split_4C(wh, ":")
622+ let currWhRes = split(currentWh[whIdxRes], "_")
623+ let currWhMat = split(currentWh[whIdxMat], "_")
624+ let currWhProd = if ((currentWh[whIdxProd] == ""))
625+ then nil
626+ else split_4C(currentWh[whIdxProd], "_")
627+ let currWhLockedVol = parseIntValue(split(currentWh[whIdxLOFT], "_")[volLocked])
628+ let ordKey = keyOrderByLand(shopLandAssetId)
629+ let whOrd = getOrder(ordKey)
630+ let whOrdRes = split(whOrd[ordIdxRes], "_")
631+ let whOrdMat = split(whOrd[ordIdxMat], "_")
632+ let whOrdProd = if ((whOrd[ordIdxProd] == ""))
633+ then nil
634+ else split_4C(whOrd[ordIdxProd], "_")
635+ let r = {
636+ let $l = bpOrdRes
637+ let $s = size($l)
638+ let $acc0 = $Tuple13(nil, nil, nil, 0, 0, 0, 0, bpResList, currWhRes, whOrdRes, resTypes, false, 0)
639+ func $f0_1 ($a,$i) = if (($i >= $s))
640+ then $a
641+ else acceptCommon($a, $l[$i])
642+
643+ func $f0_2 ($a,$i) = if (($i >= $s))
644+ then $a
645+ else throw("List size exceeds 6")
646+
647+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
648+ }
649+ let m = {
650+ let $l = bpOrdMat
651+ let $s = size($l)
652+ let $acc0 = $Tuple13(nil, nil, nil, r._4, r._5, r._6, 0, bpMatList, currWhMat, whOrdMat, matTypes, false, r._13)
653+ func $f1_1 ($a,$i) = if (($i >= $s))
654+ then $a
655+ else acceptCommon($a, $l[$i])
656+
657+ func $f1_2 ($a,$i) = if (($i >= $s))
658+ then $a
659+ else throw("List size exceeds 6")
660+
661+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
662+ }
663+ let p = if ((size(bpOrdProd) != 0))
664+ then {
665+ let $l = bpOrdProd
666+ let $s = size($l)
667+ let $acc0 = $Tuple13(nil, nil, nil, m._4, m._5, m._6, 0, bpProdList, currWhProd, whOrdProd, prodTypes, true, m._13)
668+ func $f2_1 ($a,$i) = if (($i >= $s))
669+ then $a
670+ else acceptCommon($a, $l[$i])
671+
672+ func $f2_2 ($a,$i) = if (($i >= $s))
673+ then $a
674+ else throw("List size exceeds 50")
675+
676+ $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)
677+ }
678+ else $Tuple13(currWhProd, whOrdProd, bpProdList, m._4, m._5, m._6, 0, bpProdList, currWhProd, whOrdProd, prodTypes, true, m._13)
679+ let volSaldo = p._4
680+ let newLockedVol = if ((0 > (currWhLockedVol - volSaldo)))
681+ then 0
682+ else (currWhLockedVol - volSaldo)
683+ let whStr = makeString_2C([currentWh[whIdxLevels], makeString(r._1, "_"), makeString(m._1, "_"), makeString_2C(p._1, "_"), toString(newLockedVol)], ":")
684+ let newWhOrdStr = makeString_2C([makeString(r._2, "_"), makeString(m._2, "_"), makeString_2C(p._2, "_")], ":")
685+ let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, shopLandAssetId], nil))
686+ let accStatsResult = asInt(invoke(stakingContract, "updateAccStats", [shopLandOwner, fraction(xpShop, p._13, MULT8)], nil))
687+ $Tuple10(StringEntry(ordKey, newWhOrdStr), r._3, m._3, p._3, p._5, p._6, p._13, shopLandOwner, whSave, accStatsResult)
688+ }
689+ }
690+ }
691+ }
692+ }
693+
694+
458695 @Callable(i)
459696 func recalcLockedVolumeREADONLY (landAssetId,wh) = {
460697 let currentOrd = getOrder(keyOrderByLand(landAssetId))
461698 let z = setInternal(wh, currentOrd, currentOrd)
462699 $Tuple2(nil, (z._4 + z._5))
463700 }
464701
465702
466703
467704 @Callable(i)
468705 func constructorV1 (restAddr) = if ((i.caller != this))
469706 then throw("Permission denied")
470707 else [StringEntry(keyRestAddress(), restAddr)]
471708
472709
473710
474711 @Callable(i)
475712 func sellResources (amounts,minPrices) = {
476713 let prologResult = prolog()
477714 let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
478715 if ((size(i.payments) != 0))
479716 then throw("sellResources doesn't require any payments")
480717 else {
481718 let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
482719 if ((curLocation[locIdxType] != "F"))
483720 then throw(("Duck location type should be Factory, but is " + curLocation[locIdxType]))
484721 else {
485- let locId = curLocation[locIdxId]
486722 let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
487723 let resList = split(currentPack[bpIdxRes], "_")
488- func adder (acc,j) = if ((amounts[j] > parseIntValue(resList[j])))
489- then throw(((((("You have " + resList[j]) + " of ") + resTypes[j]) + ", but tried to sell ") + toString(amounts[j])))
490- else if ((0 > amounts[j]))
491- then throw(((("You tried to sell negative amount of " + resTypes[j]) + ": ") + toString(amounts[j])))
492- else if ((amounts[j] > 0))
493- then {
494- let b = sellInternal(locId, j, amounts[j], minPrices[j])
495- $Tuple4((acc._1 :+ b._1), (acc._2 :+ toString((parseIntValue(resList[j]) - amounts[j]))), (acc._3 + b._2), (acc._4 + amounts[j]))
496- }
497- else $Tuple4(acc._1, (acc._2 :+ resList[j]), acc._3, acc._4)
498-
499- let merged = {
500- let $l = ITER6
501- let $s = size($l)
502- let $acc0 = $Tuple4(nil, nil, 0, 0)
503- func $f0_1 ($a,$i) = if (($i >= $s))
504- then $a
505- else adder($a, $l[$i])
506-
507- func $f0_2 ($a,$i) = if (($i >= $s))
508- then $a
509- else throw("List size exceeds 6")
510-
511- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
512- }
513- let newPack = makeString([currentPack[bpIdxLevel], makeString(merged._2, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":")
514- let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
515- let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, merged._4, MULT8)], nil))
516- $Tuple2((merged._1 :+ ScriptTransfer(i.caller, merged._3, usdtAssetId)), $Tuple3(result, prologResult, statsResult))
724+ let $t02587726003 = sellResourcesCommon(resList, curLocation[locIdxId], amounts, minPrices)
725+ let factoryActions = $t02587726003._1
726+ let newRes = $t02587726003._2
727+ let usdtReceived = $t02587726003._3
728+ let totalRes = $t02587726003._4
729+ let activitiesAmount = (usdtReceived / 100)
730+ let newPack = makeString_2C([currentPack[bpIdxLevel], makeString(newRes, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":")
731+ let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
732+ let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalRes, MULT8)], nil))
733+ $Tuple2(((factoryActions :+ ScriptTransfer(i.caller, (usdtReceived - activitiesAmount), usdtAssetId)) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult))
517734 }
518735 }
519736 }
737+
738+
739+
740+@Callable(i)
741+func sellResourcesDuckDelivery (amounts,minPrices,factoryContinent) = if (!(KS_ALLOW_DELIVERY))
742+ then throw("Delivery feature is turned off!")
743+ else {
744+ let prologResult = prolog()
745+ let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
746+ if ((size(i.payments) != 0))
747+ then throw("sellResources doesn't require any payments")
748+ else {
749+ let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
750+ let resList = split(currentPack[bpIdxRes], "_")
751+ let $t02723727358 = sellResourcesCommon(resList, factoryContinent, amounts, minPrices)
752+ let factoryActions = $t02723727358._1
753+ let newRes = $t02723727358._2
754+ let usdtReceived = $t02723727358._3
755+ let totalRes = $t02723727358._4
756+ let newPack = makeString_2C([currentPack[bpIdxLevel], makeString(newRes, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":")
757+ let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
758+ let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalRes, MULT8)], nil))
759+ let feePart = fraction(usdtReceived, DELIVERY_FEE, MULT6)
760+ let fee = if ((MIN_USDT_FEE_DELIVERY > feePart))
761+ then MIN_USDT_FEE_DELIVERY
762+ else feePart
763+ let activitiesAmount = (usdtReceived / 100)
764+ if ((fee >= (usdtReceived - activitiesAmount)))
765+ then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6)))
766+ else {
767+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
768+ $Tuple2((((factoryActions :+ ScriptTransfer(i.caller, ((usdtReceived - activitiesAmount) - fee), usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult))
769+ }
770+ }
771+ }
772+
773+
774+
775+@Callable(i)
776+func sellResourcesLandDelivery (amounts,minPrices,landAssetId,factoryContinent) = if (!(KS_ALLOW_DELIVERY))
777+ then throw("Delivery feature is turned off!")
778+ else {
779+ let prologResult = prolog()
780+ if ((size(i.payments) != 0))
781+ then throw("sellResources doesn't require any payments")
782+ else {
783+ let user = i.caller
784+ let addr = toString(user)
785+ let asset = value(assetInfo(fromBase58String(landAssetId)))
786+ if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId)))))
787+ then throw((("NFT " + asset.name) + " is not staked"))
788+ else {
789+ let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
790+ if ((owner != addr))
791+ then throw((LANDPREFIX + " is not yours"))
792+ else {
793+ let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil))
794+ let currentWh = split_4C(wh, ":")
795+ let resList = split(currentWh[whIdxRes], "_")
796+ let $t02938529506 = sellResourcesCommon(resList, factoryContinent, amounts, minPrices)
797+ let factoryActions = $t02938529506._1
798+ let newRes = $t02938529506._2
799+ let usdtReceived = $t02938529506._3
800+ let totalRes = $t02938529506._4
801+ let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newRes, "_"), currentWh[whIdxMat], currentWh[whIdxProd], currentWh[whIdxLOFT]], ":")
802+ let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil))
803+ let statsResult = asInt(invoke(stakingContract, "updateAccStatsInternal", [addr, fraction(xpTrade, totalRes, MULT8)], nil))
804+ let feePart = fraction(usdtReceived, DELIVERY_FEE, MULT6)
805+ let fee = if ((MIN_USDT_FEE_DELIVERY > feePart))
806+ then MIN_USDT_FEE_DELIVERY
807+ else feePart
808+ let activitiesAmount = (usdtReceived / 100)
809+ if ((fee >= (usdtReceived - activitiesAmount)))
810+ then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6)))
811+ else {
812+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
813+ $Tuple2((((factoryActions :+ ScriptTransfer(i.caller, ((usdtReceived - activitiesAmount) - fee), usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(whSave, prologResult, statsResult))
814+ }
815+ }
816+ }
817+ }
818+ }
520819
521820
522821
523822 @Callable(i)
524823 func buyMaterials (amounts,maxPrices) = {
525824 let prologResult = prolog()
526825 let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
527826 if ((size(i.payments) != 1))
528827 then throw("exactly 1 payment must be attached")
529828 else {
530829 let pmt = i.payments[0]
531830 let amt = pmt.amount
532- let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
533- if ((pmtAssetId != usdtAssetId))
831+ if (if (!(isDefined(pmt.assetId)))
832+ then true
833+ else (value(pmt.assetId) != usdtAssetId))
534834 then throw("USDT payments only!")
535835 else {
536836 let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
537837 if ((curLocation[locIdxType] != "F"))
538838 then throw(("Duck location type should be Factory, but is " + curLocation[locIdxType]))
539839 else {
540- let locId = curLocation[locIdxId]
541840 let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
542841 let matList = split(currentPack[bpIdxMat], "_")
543- func mUpdater (acc,j) = if ((0 > amounts[j]))
544- then throw(((("You tried to buy negative amount of " + matTypes[j]) + ": ") + toString(amounts[j])))
545- else if ((amounts[j] > 0))
546- then {
547- let b = buyInternal(locId, j, amounts[j], maxPrices[j])
548- $Tuple4((acc._1 :+ b._1), (acc._2 :+ toString((parseIntValue(matList[j]) + b._3))), (acc._3 + b._2), (acc._4 + amounts[j]))
549- }
550- else $Tuple4(acc._1, (acc._2 :+ matList[j]), acc._3, acc._4)
551-
552- let merged = {
553- let $l = ITER6
554- let $s = size($l)
555- let $acc0 = $Tuple4(nil, nil, 0, 0)
556- func $f0_1 ($a,$i) = if (($i >= $s))
557- then $a
558- else mUpdater($a, $l[$i])
559-
560- func $f0_2 ($a,$i) = if (($i >= $s))
561- then $a
562- else throw("List size exceeds 6")
563-
564- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
565- }
566- if ((merged._3 > amt))
567- then throw(((("Insufficient payment! Attached=" + toString(amt)) + ", required=") + toString(merged._3)))
842+ let $t03137431496 = buyMaterialsCommon(matList, curLocation[locIdxId], amounts, maxPrices)
843+ let factoryActions = $t03137431496._1
844+ let newMat = $t03137431496._2
845+ let usdtSpent = $t03137431496._3
846+ let totalMat = $t03137431496._4
847+ if ((usdtSpent > amt))
848+ then throw(((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)))
568849 else {
569- let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(merged._2, "_"), currentPack[bpIdxProd]], ":")
570- let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
571- let rest = if (((amt - merged._3) > 0))
572- then [ScriptTransfer(i.caller, (amt - merged._3), usdtAssetId)]
850+ let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), currentPack[bpIdxProd]], ":")
851+ let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
852+ let rest = if (((amt - usdtSpent) > 0))
853+ then [ScriptTransfer(i.caller, (amt - usdtSpent), usdtAssetId)]
573854 else nil
574- let activitiesAmount = (merged._3 / 100)
575- let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, merged._4, MULT8)], nil))
576- $Tuple2(((merged._1 ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(result, prologResult, statsResult))
855+ let activitiesAmount = (usdtSpent / 100)
856+ let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalMat, MULT8)], nil))
857+ $Tuple2(((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult))
577858 }
578859 }
579860 }
580861 }
581862 }
863+
864+
865+
866+@Callable(i)
867+func buyMaterialsDuckDelivery (amounts,maxPrices,factoryContinent) = if (!(KS_ALLOW_DELIVERY))
868+ then throw("Delivery feature is turned off!")
869+ else {
870+ let prologResult = prolog()
871+ let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
872+ if ((size(i.payments) != 1))
873+ then throw("exactly 1 payment must be attached")
874+ else {
875+ let pmt = i.payments[0]
876+ let amt = pmt.amount
877+ if (if (!(isDefined(pmt.assetId)))
878+ then true
879+ else (value(pmt.assetId) != usdtAssetId))
880+ then throw("USDT payments only!")
881+ else {
882+ let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
883+ let matList = split(currentPack[bpIdxMat], "_")
884+ let $t03301433131 = buyMaterialsCommon(matList, factoryContinent, amounts, maxPrices)
885+ let factoryActions = $t03301433131._1
886+ let newMat = $t03301433131._2
887+ let usdtSpent = $t03301433131._3
888+ let totalMat = $t03301433131._4
889+ let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), currentPack[bpIdxProd]], ":")
890+ let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
891+ let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalMat, MULT8)], nil))
892+ let feePart = fraction(usdtSpent, DELIVERY_FEE, MULT6)
893+ let fee = if ((MIN_USDT_FEE_DELIVERY > feePart))
894+ then MIN_USDT_FEE_DELIVERY
895+ else feePart
896+ let usdtSpentWithFee = (usdtSpent + fee)
897+ if ((usdtSpentWithFee > amt))
898+ then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)"))
899+ else {
900+ let rest = if (((amt - usdtSpentWithFee) > 0))
901+ then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)]
902+ else nil
903+ let activitiesAmount = (usdtSpent / 100)
904+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
905+ $Tuple2((((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult))
906+ }
907+ }
908+ }
909+ }
910+
911+
912+
913+@Callable(i)
914+func buyMaterialsLandDelivery (amounts,maxPrices,landAssetId,factoryContinent) = if (!(KS_ALLOW_DELIVERY))
915+ then throw("Delivery feature is turned off!")
916+ else {
917+ let prologResult = prolog()
918+ if ((size(i.payments) != 1))
919+ then throw("exactly 1 payment must be attached")
920+ else {
921+ let pmt = i.payments[0]
922+ let amt = pmt.amount
923+ if (if (!(isDefined(pmt.assetId)))
924+ then true
925+ else (value(pmt.assetId) != usdtAssetId))
926+ then throw("USDT payments only!")
927+ else {
928+ let user = i.caller
929+ let addr = toString(user)
930+ let asset = value(assetInfo(fromBase58String(landAssetId)))
931+ if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId)))))
932+ then throw((("NFT " + asset.name) + " is not staked"))
933+ else {
934+ let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
935+ if ((owner != addr))
936+ then throw((LANDPREFIX + " is not yours"))
937+ else {
938+ let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil))
939+ let currentWh = split_4C(wh, ":")
940+ let matList = split(currentWh[whIdxMat], "_")
941+ let $t03540935526 = buyMaterialsCommon(matList, factoryContinent, amounts, maxPrices)
942+ let factoryActions = $t03540935526._1
943+ let newMat = $t03540935526._2
944+ let usdtSpent = $t03540935526._3
945+ let totalMat = $t03540935526._4
946+ let whStr = makeString_2C([currentWh[whIdxLevels], currentWh[whIdxRes], makeString(newMat, "_"), currentWh[whIdxProd], currentWh[whIdxLOFT]], ":")
947+ let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil))
948+ let statsResult = asInt(invoke(stakingContract, "updateAccStatsInternal", [addr, fraction(xpTrade, totalMat, MULT8)], nil))
949+ let feePart = fraction(usdtSpent, DELIVERY_FEE, MULT6)
950+ let fee = if ((MIN_USDT_FEE_DELIVERY > feePart))
951+ then MIN_USDT_FEE_DELIVERY
952+ else feePart
953+ let usdtSpentWithFee = (usdtSpent + fee)
954+ if ((usdtSpentWithFee > amt))
955+ then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)"))
956+ else {
957+ let rest = if (((amt - usdtSpentWithFee) > 0))
958+ then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)]
959+ else nil
960+ let activitiesAmount = (usdtSpent / 100)
961+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
962+ $Tuple2((((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult))
963+ }
964+ }
965+ }
966+ }
967+ }
968+ }
582969
583970
584971
585972 @Callable(i)
586973 func exchangeResources (amounts) = {
587974 let prologResult = prolog()
588975 let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
589976 if ((size(i.payments) != 1))
590977 then throw("exactly 1 payment must be attached")
591978 else {
592979 let pmt = i.payments[0]
593980 let amt = pmt.amount
594- let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
595- if ((pmtAssetId != usdtAssetId))
981+ if (if (!(isDefined(pmt.assetId)))
982+ then true
983+ else (value(pmt.assetId) != usdtAssetId))
596984 then throw("USDT payments only!")
597985 else {
598986 let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
599987 if ((curLocation[locIdxType] != "F"))
600988 then throw(("Duck location type should be Factory, but is " + curLocation[locIdxType]))
601989 else {
602- let locId = curLocation[locIdxId]
603990 let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
604991 let resList = split(currentPack[bpIdxRes], "_")
605992 let matList = split(currentPack[bpIdxMat], "_")
606- func exchanger (acc,j) = {
607- let whKey = keyFactoryWarehouseByIdAndType(locId, j)
608- let w0 = valueOrElse(getInteger(whKey), 0)
609- let amj = amounts[j]
610- if ((amj > parseIntValue(resList[j])))
611- then throw(((((("You have " + resList[j]) + " of ") + resTypes[j]) + ", but tried to exchange ") + toString(amj)))
612- else if ((0 > amj))
613- then throw(((("You tried to exchange negative amount of " + resTypes[j]) + ": ") + toString(amj)))
614- else if ((amj > 0))
615- then $Tuple5((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)), (acc._5 + amj))
616- else $Tuple5((acc._1 :+ resList[j]), (acc._2 :+ matList[j]), acc._3, acc._4, acc._5)
617- }
993+ let $t03764837754 = exchangeResourcesCommon(resList, matList, amounts)
994+ let newRes = $t03764837754._1
995+ let newMat = $t03764837754._2
996+ let usdtSpent = $t03764837754._3
997+ let totalAmountConverted = $t03764837754._4
998+ if ((usdtSpent > amt))
999+ then throw(((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)))
1000+ else {
1001+ let newPack = makeString([currentPack[bpIdxLevel], makeString(newRes, "_"), makeString(newMat, "_"), currentPack[bpIdxProd]], ":")
1002+ let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
1003+ let rest = if (((amt - usdtSpent) > 0))
1004+ then [ScriptTransfer(i.caller, (amt - usdtSpent), usdtAssetId)]
1005+ else nil
1006+ let activitiesAmount = (usdtSpent / 100)
1007+ let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalAmountConverted, MULT8)], nil))
1008+ $Tuple2((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult))
1009+ }
1010+ }
1011+ }
1012+ }
1013+ }
6181014
619- let merged = {
620- let $l = ITER6
621- let $s = size($l)
622- let $acc0 = $Tuple5(nil, nil, 0, nil, 0)
623- func $f0_1 ($a,$i) = if (($i >= $s))
624- then $a
625- else exchanger($a, $l[$i])
6261015
627- func $f0_2 ($a,$i) = if (($i >= $s))
628- then $a
629- else throw("List size exceeds 6")
6301016
631- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
632- }
633- if ((merged._3 > amt))
634- then throw(((("Insufficient payment! Attached=" + toString(amt)) + ", required=") + toString(merged._3)))
1017+@Callable(i)
1018+func exchangeResourcesDuckDelivery (amounts) = {
1019+ let prologResult = prolog()
1020+ let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
1021+ if ((size(i.payments) != 1))
1022+ then throw("exactly 1 payment must be attached")
1023+ else {
1024+ let pmt = i.payments[0]
1025+ let amt = pmt.amount
1026+ if (if (!(isDefined(pmt.assetId)))
1027+ then true
1028+ else (value(pmt.assetId) != usdtAssetId))
1029+ then throw("USDT payments only!")
1030+ else {
1031+ let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
1032+ let resList = split(currentPack[bpIdxRes], "_")
1033+ let matList = split(currentPack[bpIdxMat], "_")
1034+ let $t03918939295 = exchangeResourcesCommon(resList, matList, amounts)
1035+ let newRes = $t03918939295._1
1036+ let newMat = $t03918939295._2
1037+ let usdtSpent = $t03918939295._3
1038+ let totalAmountConverted = $t03918939295._4
1039+ let feePart = fraction(usdtSpent, DELIVERY_FEE15, MULT6)
1040+ let fee = if ((MIN_USDT_FEE_DELIVERY15 > feePart))
1041+ then MIN_USDT_FEE_DELIVERY15
1042+ else feePart
1043+ let usdtSpentWithFee = (usdtSpent + fee)
1044+ if ((usdtSpentWithFee > amt))
1045+ then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)"))
1046+ else {
1047+ let newPack = makeString([currentPack[bpIdxLevel], makeString(newRes, "_"), makeString(newMat, "_"), currentPack[bpIdxProd]], ":")
1048+ let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
1049+ let rest = if (((amt - usdtSpentWithFee) > 0))
1050+ then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)]
1051+ else nil
1052+ let activitiesAmount = (usdtSpent / 100)
1053+ let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalAmountConverted, MULT8)], nil))
1054+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
1055+ $Tuple2(((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult))
1056+ }
1057+ }
1058+ }
1059+ }
1060+
1061+
1062+
1063+@Callable(i)
1064+func exchangeResourcesLandDelivery (amounts,landAssetId) = {
1065+ let prologResult = prolog()
1066+ if ((size(i.payments) != 1))
1067+ then throw("exactly 1 payment must be attached")
1068+ else {
1069+ let pmt = i.payments[0]
1070+ let amt = pmt.amount
1071+ if (if (!(isDefined(pmt.assetId)))
1072+ then true
1073+ else (value(pmt.assetId) != usdtAssetId))
1074+ then throw("USDT payments only!")
1075+ else {
1076+ let user = i.caller
1077+ let addr = toString(user)
1078+ let asset = value(assetInfo(fromBase58String(landAssetId)))
1079+ if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId)))))
1080+ then throw((("NFT " + asset.name) + " is not staked"))
1081+ else {
1082+ let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
1083+ if ((owner != addr))
1084+ then throw((LANDPREFIX + " is not yours"))
6351085 else {
636- let newPack = makeString([currentPack[bpIdxLevel], makeString(merged._1, "_"), makeString(merged._2, "_"), currentPack[bpIdxProd]], ":")
637- let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
638- let rest = if (((amt - merged._3) > 0))
639- then [ScriptTransfer(i.caller, (amt - merged._3), usdtAssetId)]
640- else nil
641- let activitiesAmount = (merged._3 / 100)
642- let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, merged._5, MULT8)], nil))
643- $Tuple2(((rest ++ merged._4) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(result, prologResult, statsResult))
1086+ let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil))
1087+ let currentWh = split_4C(wh, ":")
1088+ let resList = split(currentWh[whIdxRes], "_")
1089+ let matList = split(currentWh[whIdxMat], "_")
1090+ let $t04151841624 = exchangeResourcesCommon(resList, matList, amounts)
1091+ let newRes = $t04151841624._1
1092+ let newMat = $t04151841624._2
1093+ let usdtSpent = $t04151841624._3
1094+ let totalAmountConverted = $t04151841624._4
1095+ let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newRes, "_"), makeString(newMat, "_"), currentWh[whIdxProd], currentWh[whIdxLOFT]], ":")
1096+ let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil))
1097+ let statsResult = asInt(invoke(stakingContract, "updateAccStatsInternal", [addr, fraction(xpTrade, totalAmountConverted, MULT8)], nil))
1098+ let feePart = fraction(usdtSpent, DELIVERY_FEE15, MULT6)
1099+ let fee = if ((MIN_USDT_FEE_DELIVERY15 > feePart))
1100+ then MIN_USDT_FEE_DELIVERY15
1101+ else feePart
1102+ let usdtSpentWithFee = (usdtSpent + fee)
1103+ if ((usdtSpentWithFee > amt))
1104+ then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)"))
1105+ else {
1106+ let rest = if (((amt - usdtSpentWithFee) > 0))
1107+ then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)]
1108+ else nil
1109+ let activitiesAmount = (usdtSpent / 100)
1110+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
1111+ $Tuple2(((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult))
1112+ }
6441113 }
6451114 }
6461115 }
6471116 }
6481117 }
6491118
6501119
6511120
6521121 @Callable(i)
6531122 func craftGoods (productIdx,quantity) = {
6541123 let prologResult = prolog()
6551124 if ((size(i.payments) != 1))
6561125 then throw("exactly 1 payment must be attached")
6571126 else {
6581127 let pmt = i.payments[0]
6591128 let amt = pmt.amount
6601129 let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
6611130 if ((pmtAssetId != usdtAssetId))
6621131 then throw("USDT payments only!")
6631132 else if ((amt != MULT6))
6641133 then throw("exactly 1 USDT must be attached as payment")
6651134 else if ((0 >= quantity))
6661135 then throw("Quantity should be positive")
6671136 else {
6681137 let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
6691138 let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
6701139 if ((curLocation[locIdxType] != "M"))
6711140 then throw(("Duck location type should be Manufactory, but is " + curLocation[locIdxType]))
6721141 else {
6731142 let cont = curLocation[locIdxContinent]
6741143 let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
6751144 let matList = split(currentPack[bpIdxMat], "_")
6761145 if (if ((0 > productIdx))
6771146 then true
6781147 else (productIdx >= size(productionMatrix)))
6791148 then throw(("Unknown product idx=" + toString(productIdx)))
6801149 else {
6811150 let recipe = split(productionMatrix[productIdx], "_")
6821151 if ((size(recipe) != RECIPESIZE))
6831152 then throw(("Fatal: unknown recipe: " + productionMatrix[productIdx]))
6841153 else {
6851154 let productContIdx = parseIntValue(recipe[rIdxContinent])
6861155 if ((continents[productContIdx] != cont))
6871156 then throw(((("This product is available in " + continents[productContIdx]) + ", but you are in ") + cont))
6881157 else {
6891158 let prodList = if ((currentPack[bpIdxProd] == ""))
6901159 then nil
6911160 else split_4C(currentPack[bpIdxProd], "_")
6921161 func filler (acc,ignoredItem) = {
6931162 let n = acc._2
6941163 let xs = if ((size(prodList) > n))
6951164 then prodList[n]
6961165 else "0"
6971166 let x = parseIntValue(xs)
6981167 let amount = (quantity * PRODUCTPKGSIZE)
6991168 let y = if ((n == productIdx))
7001169 then toString((x + amount))
7011170 else xs
7021171 $Tuple2((acc._1 :+ y), (n + 1))
7031172 }
7041173
7051174 let bpProd = ( let $l = productionMatrix
7061175 let $s = size($l)
7071176 let $acc0 = $Tuple2(nil, 0)
7081177 func $f0_1 ($a,$i) = if (($i >= $s))
7091178 then $a
7101179 else filler($a, $l[$i])
7111180
7121181 func $f0_2 ($a,$i) = if (($i >= $s))
7131182 then $a
7141183 else throw("List size exceeds 50")
7151184
7161185 $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
7171186 func producer (acc,j) = {
7181187 let needMat = (((parseIntValue(recipe[j]) * MULT5) * quantity) * parseIntValue(recipe[rIdxCoeff]))
7191188 let haveMat = parseIntValue(matList[j])
7201189 if ((needMat > haveMat))
7211190 then throw(((((((("You have " + fixedPoint(haveMat, 8)) + " of ") + matTypes[j]) + ", but recipe requires ") + fixedPoint(needMat, 8)) + " for quantity ") + toString(quantity)))
7221191 else if ((needMat > 0))
7231192 then $Tuple2((acc._1 :+ toString((haveMat - needMat))), (acc._2 + needMat))
7241193 else $Tuple2((acc._1 :+ matList[j]), acc._2)
7251194 }
7261195
7271196 let merged = {
7281197 let $l = ITER6
7291198 let $s = size($l)
7301199 let $acc0 = $Tuple2(nil, 0)
7311200 func $f1_1 ($a,$i) = if (($i >= $s))
7321201 then $a
7331202 else producer($a, $l[$i])
7341203
7351204 func $f1_2 ($a,$i) = if (($i >= $s))
7361205 then $a
7371206 else throw("List size exceeds 6")
7381207
7391208 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
7401209 }
7411210 let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(merged._1, "_"), makeString_2C(bpProd, "_")], ":")
7421211 let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil))
7431212 let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpCraft, merged._2, MULT8)], nil))
7441213 $Tuple2(nil, $Tuple3(result, prologResult, statsResult))
7451214 }
7461215 }
7471216 }
7481217 }
7491218 }
7501219 }
7511220 }
7521221
7531222
7541223
7551224 @Callable(i)
7561225 func setWarehouseOrder (newOrderStr,landAssetId) = {
7571226 let user = i.originCaller
7581227 let addr = toString(user)
7591228 let result = if ((user != restContract))
7601229 then checkBlocked()
7611230 else false
7621231 let asset = value(assetInfo(fromBase58String(landAssetId)))
7631232 if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId)))))
7641233 then throw((("NFT " + asset.name) + " is not staked"))
7651234 else {
7661235 let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
7671236 if (if ((user != restContract))
7681237 then (owner != addr)
7691238 else false)
7701239 then throw((LANDPREFIX + " is not yours"))
7711240 else {
7721241 let newOrder = split_4C(newOrderStr, ":")
7731242 let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil))
7741243 let currentWh = split_4C(wh, ":")
7751244 let loft = split(currentWh[whIdxLOFT], "_")
7761245 let whTotal = parseIntValue(loft[volTotal])
7771246 let ordKey = keyOrderByLand(landAssetId)
7781247 let currentOrd = getOrder(ordKey)
7791248 let z = setInternal(currentWh, currentOrd, newOrder)
7801249 let buyVolSaldo = z._4
7811250 let sellVolSaldo = z._5
7821251 let whOccupied = z._7
7831252 let whLocked = (buyVolSaldo + sellVolSaldo)
7841253 let whFree = ((whTotal - whOccupied) - whLocked)
7851254 if ((0 > whFree))
7861255 then throw((((((("Attempt to reserve " + toString(buyVolSaldo)) + " space for buy orders, and ") + toString(sellVolSaldo)) + " space for sell orders (and occupied=") + toString(whOccupied)) + "), leads to negative free space"))
7871256 else {
7881257 let whStr = makeString_2C([currentWh[whIdxLevels], makeString(z._1, "_"), makeString(z._2, "_"), makeString_2C(z._3, "_"), toString(whLocked)], ":")
7891258 let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil))
7901259 let usdSaldo = z._6
7911260 let actions = if ((usdSaldo > 0))
7921261 then if ((size(i.payments) != 1))
7931262 then throw("exactly 1 payment must be attached")
7941263 else {
7951264 let pmt = i.payments[0]
7961265 let amt = pmt.amount
7971266 let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
7981267 if ((pmtAssetId != usdtAssetId))
7991268 then throw("USDT payments only!")
8001269 else if ((amt != usdSaldo))
8011270 then throw(("Payment needed is " + toString(usdSaldo)))
8021271 else [StringEntry(ordKey, newOrderStr)]
8031272 }
8041273 else if ((usdSaldo == 0))
8051274 then if ((size(i.payments) != 0))
8061275 then throw("No payments needed")
8071276 else [StringEntry(ordKey, newOrderStr)]
8081277 else if ((size(i.payments) != 0))
8091278 then throw("No payments needed")
8101279 else [ScriptTransfer(addressFromStringValue(owner), -(usdSaldo), usdtAssetId), StringEntry(ordKey, newOrderStr)]
8111280 $Tuple2(actions, $Tuple2(result, whSave))
8121281 }
8131282 }
8141283 }
8151284 }
8161285
8171286
8181287
8191288 @Callable(i)
820-func acceptWarehouseOrder (bpOrderStr,landAssetId,duckAssetId) = {
1289+func acceptWarehouseOrder (bpOrderStr,shopLandAssetId,duckAssetId) = {
8211290 let prologResult = prolog()
8221291 let caller = i.originCaller
8231292 let callerAddr = toString(caller)
8241293 let stakedDuckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(callerAddr)), "You don't have a duck staked")
8251294 let curLocation = valueOrElse(getString(stakingContract, keyDuckLocation(stakedDuckAssetId)), DEFAULTLOCATION)
8261295 let loc = split(value(curLocation), "_")
8271296 if ((loc[locIdxType] != "L"))
8281297 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
8291298 else if ((stakedDuckAssetId != duckAssetId))
8301299 then throw(((("Your staked duck is " + stakedDuckAssetId) + ", but passed ") + duckAssetId))
8311300 else {
832- let landAsset = value(assetInfo(fromBase58String(landAssetId)))
833- if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId)))))
834- then throw((("NFT " + landAsset.name) + " is not staked"))
1301+ let bpKey = keyBackpackByDuck(duckAssetId)
1302+ let currentPack = getBackpack(bpKey)
1303+ let bpResList = split(currentPack[bpIdxRes], "_")
1304+ let bpMatList = split(currentPack[bpIdxMat], "_")
1305+ let bpProdList = if ((currentPack[bpIdxProd] == ""))
1306+ then nil
1307+ else split_4C(currentPack[bpIdxProd], "_")
1308+ let $t05114451384 = acceptShopOrderCommon(shopLandAssetId, callerAddr, bpOrderStr, bpResList, bpMatList, bpProdList)
1309+ let shopAction = $t05114451384._1
1310+ let newUserRes = $t05114451384._2
1311+ let newUserMat = $t05114451384._3
1312+ let newUserProd = $t05114451384._4
1313+ let usdWh2BpSaldo = $t05114451384._5
1314+ let usdBp2WhSaldo = $t05114451384._6
1315+ let xpAmount = $t05114451384._7
1316+ let shopLandOwner = $t05114451384._8
1317+ let shopWhSave = $t05114451384._9
1318+ let accStatsResult = $t05114451384._10
1319+ let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, 0)]
1320+ let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, 0)
1321+ let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString_2C(newUserProd, "_")], ":")
1322+ let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil))
1323+ let duckStatsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpShop, xpAmount, MULT8)], nil))
1324+ $Tuple2((actions1 ++ actions2), $Tuple5(prologResult, shopWhSave, bpSave, duckStatsResult, accStatsResult))
1325+ }
1326+ }
1327+
1328+
1329+
1330+@Callable(i)
1331+func acceptShopOrderDuckDelivery (orderStr,shopLandAssetId) = if (!(KS_ALLOW_DELIVERY))
1332+ then throw("Delivery feature is turned off!")
1333+ else {
1334+ let prologResult = prolog()
1335+ let caller = i.originCaller
1336+ let callerAddr = toString(caller)
1337+ let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(callerAddr)), "You don't have a duck staked")
1338+ let bpKey = keyBackpackByDuck(duckAssetId)
1339+ let currentPack = getBackpack(bpKey)
1340+ let bpResList = split(currentPack[bpIdxRes], "_")
1341+ let bpMatList = split(currentPack[bpIdxMat], "_")
1342+ let bpProdList = if ((currentPack[bpIdxProd] == ""))
1343+ then nil
1344+ else split_4C(currentPack[bpIdxProd], "_")
1345+ let $t05282353061 = acceptShopOrderCommon(shopLandAssetId, callerAddr, orderStr, bpResList, bpMatList, bpProdList)
1346+ let shopAction = $t05282353061._1
1347+ let newUserRes = $t05282353061._2
1348+ let newUserMat = $t05282353061._3
1349+ let newUserProd = $t05282353061._4
1350+ let usdWh2BpSaldo = $t05282353061._5
1351+ let usdBp2WhSaldo = $t05282353061._6
1352+ let xpAmount = $t05282353061._7
1353+ let shopLandOwner = $t05282353061._8
1354+ let shopWhSave = $t05282353061._9
1355+ let accStatsResult = $t05282353061._10
1356+ let deliveryFeePart = fraction((usdBp2WhSaldo + usdWh2BpSaldo), DELIVERY_FEE, MULT6)
1357+ let deliveryFee = if ((MIN_USDT_FEE_DELIVERY > deliveryFeePart))
1358+ then MIN_USDT_FEE_DELIVERY
1359+ else deliveryFeePart
1360+ let spentFee = fraction(deliveryFee, usdBp2WhSaldo, (usdBp2WhSaldo + usdWh2BpSaldo))
1361+ let receivedFee = (deliveryFee - spentFee)
1362+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
1363+ let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, receivedFee)]
1364+ let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, spentFee)
1365+ let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString_2C(newUserProd, "_")], ":")
1366+ let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil))
1367+ let duckStatsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpShop, xpAmount, MULT8)], nil))
1368+ $Tuple2(((actions1 ++ actions2) :+ IntegerEntry(deliveryFundKey, (fundTotal + deliveryFee))), $Tuple5(prologResult, shopWhSave, bpSave, duckStatsResult, accStatsResult))
1369+ }
1370+
1371+
1372+
1373+@Callable(i)
1374+func acceptShopOrderLandDelivery (orderStr,shopLandAssetId,myLandAssetId) = if (!(KS_ALLOW_DELIVERY))
1375+ then throw("Delivery feature is turned off!")
1376+ else {
1377+ let prologResult = prolog()
1378+ let caller = i.originCaller
1379+ let callerAddr = toString(caller)
1380+ let asset = value(assetInfo(fromBase58String(myLandAssetId)))
1381+ if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(myLandAssetId)))))
1382+ then throw((("NFT " + asset.name) + " is not staked"))
1383+ else {
1384+ let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(myLandAssetId)), (("NFT " + asset.name) + " is orphaned"))
1385+ if ((owner != callerAddr))
1386+ then throw((LANDPREFIX + " is not yours"))
8351387 else {
836- let landOwner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + landAsset.name) + " is orphaned"))
837- if ((landOwner == callerAddr))
838- then throw("You cannot trade with yourself")
839- else {
840- let bpOrderParts = split_4C(bpOrderStr, ":")
841- if ((size(bpOrderParts) != 3))
842- then throw("bpOrderStr should contain exactly 2 ':' separators")
843- else {
844- let bpOrdRes = split(bpOrderParts[0], "_")
845- let bpOrdMat = split(bpOrderParts[1], "_")
846- let bpOrdProd = if ((bpOrderParts[2] == ""))
847- then nil
848- else split_4C(bpOrderParts[2], "_")
849- if ((size(bpOrdRes) != NUMRES))
850- then throw("All 6 resources should be passed")
851- else if ((size(bpOrdMat) != NUMRES))
852- then throw("All 6 materials should be passed")
853- else {
854- let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil))
855- let currentWh = split_4C(wh, ":")
856- let currWhRes = split(currentWh[whIdxRes], "_")
857- let currWhMat = split(currentWh[whIdxMat], "_")
858- let currWhProd = if ((currentWh[whIdxProd] == ""))
859- then nil
860- else split_4C(currentWh[whIdxProd], "_")
861- let currWhLockedVol = parseIntValue(split(currentWh[whIdxLOFT], "_")[volLocked])
862- let bpKey = keyBackpackByDuck(duckAssetId)
863- let currentPack = getBackpack(bpKey)
864- let bpResList = split(currentPack[bpIdxRes], "_")
865- let bpMatList = split(currentPack[bpIdxMat], "_")
866- let bpProdList = if ((currentPack[bpIdxProd] == ""))
867- then nil
868- else split_4C(currentPack[bpIdxProd], "_")
869- let ordKey = keyOrderByLand(landAssetId)
870- let whOrd = getOrder(ordKey)
871- let whOrdRes = split(whOrd[ordIdxRes], "_")
872- let whOrdMat = split(whOrd[ordIdxMat], "_")
873- let whOrdProd = if ((whOrd[ordIdxProd] == ""))
874- then nil
875- else split_4C(whOrd[ordIdxProd], "_")
876- let r = {
877- let $l = bpOrdRes
878- let $s = size($l)
879- let $acc0 = $Tuple13(nil, nil, nil, 0, 0, 0, 0, bpResList, currWhRes, whOrdRes, resTypes, false, 0)
880- func $f0_1 ($a,$i) = if (($i >= $s))
881- then $a
882- else acceptCommon($a, $l[$i])
883-
884- func $f0_2 ($a,$i) = if (($i >= $s))
885- then $a
886- else throw("List size exceeds 6")
887-
888- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
889- }
890- let m = {
891- let $l = bpOrdMat
892- let $s = size($l)
893- let $acc0 = $Tuple13(nil, nil, nil, r._4, r._5, r._6, 0, bpMatList, currWhMat, whOrdMat, matTypes, false, r._13)
894- func $f1_1 ($a,$i) = if (($i >= $s))
895- then $a
896- else acceptCommon($a, $l[$i])
897-
898- func $f1_2 ($a,$i) = if (($i >= $s))
899- then $a
900- else throw("List size exceeds 6")
901-
902- $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
903- }
904- let p = if ((size(bpOrdProd) != 0))
905- then {
906- let $l = bpOrdProd
907- let $s = size($l)
908- let $acc0 = $Tuple13(nil, nil, nil, m._4, m._5, m._6, 0, bpProdList, currWhProd, whOrdProd, prodTypes, true, m._13)
909- func $f2_1 ($a,$i) = if (($i >= $s))
910- then $a
911- else acceptCommon($a, $l[$i])
912-
913- func $f2_2 ($a,$i) = if (($i >= $s))
914- then $a
915- else throw("List size exceeds 50")
916-
917- $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)
918- }
919- else $Tuple13(currWhProd, whOrdProd, bpProdList, m._4, m._5, m._6, 0, bpProdList, currWhProd, whOrdProd, prodTypes, true, m._13)
920- let volSaldo = p._4
921- let newLockedVol = if ((0 > (currWhLockedVol - volSaldo)))
922- then 0
923- else (currWhLockedVol - volSaldo)
924- let whStr = makeString_2C([currentWh[whIdxLevels], makeString(r._1, "_"), makeString(m._1, "_"), makeString_2C(p._1, "_"), toString(newLockedVol)], ":")
925- let newWhOrdStr = makeString_2C([makeString(r._2, "_"), makeString(m._2, "_"), makeString_2C(p._2, "_")], ":")
926- let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(r._3, "_"), makeString(m._3, "_"), makeString_2C(p._3, "_")], ":")
927- let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil))
928- let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil))
929- let duckStatsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpShop, p._13, MULT8)], nil))
930- let accStatsResult = asInt(invoke(stakingContract, "updateAccStats", [landOwner, fraction(xpShop, p._13, MULT8)], nil))
931- let actions = [StringEntry(ordKey, newWhOrdStr)]
932- let usdWh2BpSaldo = p._5
933- let actions1 = if ((usdWh2BpSaldo > 0))
934- then {
935- let usdWh2BpFee = fraction(p._5, AUCTIONFEE, MULT6)
936- let refByKey = keyAddressRefBy(callerAddr)
937- let refBy = getString(stakingContract, refByKey)
938- if (isDefined(refBy))
939- then (((actions :+ ScriptTransfer(caller, (p._5 - (3 * usdWh2BpFee)), usdtAssetId)) :+ ScriptTransfer(restContract, usdWh2BpFee, usdtAssetId)) :+ ScriptTransfer(addressFromStringValue(value(refBy)), usdWh2BpFee, usdtAssetId))
940- else ((actions :+ ScriptTransfer(caller, (p._5 - (3 * usdWh2BpFee)), usdtAssetId)) :+ ScriptTransfer(restContract, usdWh2BpFee, usdtAssetId))
941- }
942- else actions
943- let usdBp2WhSaldo = p._6
944- let actions2 = if ((usdBp2WhSaldo > 0))
945- then if ((size(i.payments) != 1))
946- then throw("exactly 1 payment must be attached")
947- else {
948- let pmt = i.payments[0]
949- let amt = pmt.amount
950- let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment")
951- if ((pmtAssetId != usdtAssetId))
952- then throw("USDT payments only!")
953- else if ((amt != usdBp2WhSaldo))
954- then throw(("Payment needed is " + toString(usdBp2WhSaldo)))
955- else if ((MINSHOPPAYMENT > amt))
956- then throw(("Payment should be at least " + toString(MINSHOPPAYMENT)))
957- else {
958- let usdBp2WhFee = fraction(p._6, AUCTIONFEE, MULT6)
959- let refByKey = keyAddressRefBy(landOwner)
960- let refBy = getString(stakingContract, refByKey)
961- if (isDefined(refBy))
962- then (((actions1 :+ ScriptTransfer(addressFromStringValue(landOwner), (p._6 - (3 * usdBp2WhFee)), usdtAssetId)) :+ ScriptTransfer(restContract, usdBp2WhFee, usdtAssetId)) :+ ScriptTransfer(addressFromStringValue(value(refBy)), usdBp2WhFee, usdtAssetId))
963- else ((actions1 :+ ScriptTransfer(addressFromStringValue(landOwner), (p._6 - (3 * usdBp2WhFee)), usdtAssetId)) :+ ScriptTransfer(restContract, usdBp2WhFee, usdtAssetId))
964- }
965- }
966- else if ((size(i.payments) != 0))
967- then throw("No payments needed")
968- else actions1
969- $Tuple2(actions2, $Tuple5(prologResult, whSave, bpSave, duckStatsResult, accStatsResult))
970- }
971- }
972- }
1388+ let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [myLandAssetId], nil))
1389+ let currentWh = split_4C(wh, ":")
1390+ let resList = split(currentWh[whIdxRes], "_")
1391+ let matList = split(currentWh[whIdxMat], "_")
1392+ let prodList = if ((currentWh[whIdxProd] == ""))
1393+ then nil
1394+ else split(currentWh[whIdxProd], "_")
1395+ let $t05530055532 = acceptShopOrderCommon(shopLandAssetId, callerAddr, orderStr, resList, matList, prodList)
1396+ let shopAction = $t05530055532._1
1397+ let newUserRes = $t05530055532._2
1398+ let newUserMat = $t05530055532._3
1399+ let newUserProd = $t05530055532._4
1400+ let usdWh2BpSaldo = $t05530055532._5
1401+ let usdBp2WhSaldo = $t05530055532._6
1402+ let xpAmount = $t05530055532._7
1403+ let shopLandOwner = $t05530055532._8
1404+ let shopWhSave = $t05530055532._9
1405+ let accStatsResult = $t05530055532._10
1406+ let deliveryFeePart = fraction((usdBp2WhSaldo + usdWh2BpSaldo), DELIVERY_FEE, MULT6)
1407+ let deliveryFee = if ((MIN_USDT_FEE_DELIVERY > deliveryFeePart))
1408+ then MIN_USDT_FEE_DELIVERY
1409+ else deliveryFeePart
1410+ let spentFee = fraction(deliveryFee, usdBp2WhSaldo, (usdBp2WhSaldo + usdWh2BpSaldo))
1411+ let receivedFee = (deliveryFee - spentFee)
1412+ let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0)
1413+ let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, receivedFee)]
1414+ let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, spentFee)
1415+ let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString(newUserProd, "_"), currentWh[whIdxLOFT]], ":")
1416+ let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, myLandAssetId], nil))
1417+ let statsResult = asInt(invoke(stakingContract, "updateAccStatsInternal", [callerAddr, fraction(xpShop, xpAmount, MULT8)], nil))
1418+ $Tuple2(((actions1 ++ actions2) :+ IntegerEntry(deliveryFundKey, (fundTotal + deliveryFee))), $Tuple5(prologResult, shopWhSave, whSave, statsResult, accStatsResult))
9731419 }
9741420 }
975- }
1421+ }
9761422
9771423
9781424
9791425 @Callable(i)
9801426 func sellProductsToES (amounts) = {
9811427 let prologResult = prolog()
9821428 if ((size(i.payments) != 0))
9831429 then throw("No payments needed")
9841430 else {
9851431 let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
9861432 let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
9871433 if ((curLocation[locIdxType] != "A"))
9881434 then throw(("Duck location type should be Airport, but is " + curLocation[locIdxType]))
9891435 else {
9901436 let currentPack = getBackpack(keyBackpackByDuck(duckAssetId))
9911437 let prodList = if ((currentPack[bpIdxProd] == ""))
9921438 then nil
9931439 else split_4C(currentPack[bpIdxProd], "_")
9941440 let esKey = keyEsWarehouse()
9951441 let existStr = getString(esKey)
9961442 let existAmounts = if (isDefined(existStr))
9971443 then split_4C(value(existStr), "_")
9981444 else nil
9991445 func moveProd (acc,recipeStr) = {
10001446 let j = acc._1
10011447 let quantity = if ((size(amounts) > j))
10021448 then amounts[j]
10031449 else 0
10041450 if ((0 > quantity))
10051451 then throw("Quantity cannot be negative")
10061452 else {
10071453 let recipe = split(recipeStr, "_")
10081454 if ((size(recipe) != RECIPESIZE))
10091455 then throw(("Fatal: unknown recipe: " + recipeStr))
10101456 else {
10111457 let maxAmount = (ESMAXPACKAGES * PRODUCTPKGSIZE)
10121458 let existAmount = if ((size(existAmounts) > j))
10131459 then parseIntValue(existAmounts[j])
10141460 else 0
10151461 let canBuy = (maxAmount - existAmount)
10161462 if ((quantity > canBuy))
10171463 then throw(((("Warehouse can buy only " + toString(canBuy)) + " of ") + prodTypes[j]))
10181464 else {
10191465 let totalMat = getRecipeMaterials(recipe)
10201466 let unitPrice = fraction((totalMat * ESBUYCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
10211467 let bpProdAmount = if ((size(prodList) > j))
10221468 then parseIntValue(prodList[j])
10231469 else 0
10241470 if ((quantity > bpProdAmount))
10251471 then throw(((("You have only " + toString(bpProdAmount)) + " of ") + prodTypes[j]))
10261472 else $Tuple5((j + 1), (acc._2 + (unitPrice * quantity)), (acc._3 :+ toString((bpProdAmount - quantity))), (acc._4 :+ toString((existAmount + quantity))), (acc._5 + (totalMat * quantity)))
10271473 }
10281474 }
10291475 }
10301476 }
10311477
10321478 let merged = {
10331479 let $l = productionMatrix
10341480 let $s = size($l)
10351481 let $acc0 = $Tuple5(0, 0, nil, nil, 0)
10361482 func $f0_1 ($a,$i) = if (($i >= $s))
10371483 then $a
10381484 else moveProd($a, $l[$i])
10391485
10401486 func $f0_2 ($a,$i) = if (($i >= $s))
10411487 then $a
10421488 else throw("List size exceeds 50")
10431489
10441490 $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)
10451491 }
10461492 let newBpStr = makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString_2C(merged._3, "_")], ":")
10471493 let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil))
10481494 let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpSellToEs, merged._5, (MULT8 * 10))], nil))
10491495 $Tuple2([StringEntry(esKey, makeString_2C(merged._4, "_")), ScriptTransfer(i.caller, merged._2, usdtAssetId)], $Tuple3(bpSave, prologResult, statsResult))
10501496 }
10511497 }
10521498 }
10531499
10541500
10551501
10561502 @Callable(i)
10571503 func updateEsStorage (newStorage) = if ((i.caller != stakingContract))
10581504 then throw("Permission denied")
10591505 else $Tuple2([StringEntry(keyEsWarehouse(), newStorage)], newStorage)
10601506
10611507

github/deemru/w8io/169f3d6 
162.97 ms