tx · 3kdaZ5sHGDHH1LJEs8F2ULn5UyAp38iW61jJoZBE9ybX 3N8y4wxX3JC4TdrCJBXX16SjWf6X256hrep: -0.06200000 Waves 2023.10.25 21:02 [2814490] smart account 3N8y4wxX3JC4TdrCJBXX16SjWf6X256hrep > SELF 0.00000000 Waves
{ "type": 13, "id": "3kdaZ5sHGDHH1LJEs8F2ULn5UyAp38iW61jJoZBE9ybX", "fee": 6200000, "feeAssetId": null, "timestamp": 1698257000770, "version": 2, "chainId": 84, "sender": "3N8y4wxX3JC4TdrCJBXX16SjWf6X256hrep", "senderPublicKey": "7v5L7QkXxfkirALdyqmox38QCsa9jtfAtgUfHTh34eWq", "proofs": [ "2d8gog22qgUbLUhFJKTb6cDZtevzG5pLL88TryC1839qczNKPicTBTvBJZqgQsCAXkGWbkHNt3kU2PcybuNAoQLU" ], "script": "base64:BgKVAQgCEgQKAggYEgMKAQgSBAoCERESBAoCCAESAwoBARIFCgMREQgSBgoEEREICBIECgIRERIFCgMREQgSBgoEEREICBIDCgEREgMKARESBAoCEQgSBAoCAQESBQoDAQEIEgYKBAEBCAgSBAoCCAgSBQoDCAgIEgQKAggIEgUKAwgICBIDCgEREgMKAQgSAwoBARIDCgEIaQAHeHBUcmFkZQCQTgAHeHBDcmFmdACQTgAKeHBTZWxsVG9FcwCQTgAGeHBTaG9wAJBOAApMQU5EUFJFRklYAgRMQU5EAAZOVU1SRVMABgAPREVGQVVMVExPQ0FUSU9OAg9BZnJpY2FfRl9BZnJpY2EAEFJFU09VUkNFUFJJQ0VNSU4A1bUCAA1FU01BWFBBQ0tBR0VTAAoACUVTQlVZQ09FRgAEABVNSU5fVVNEVF9GRUVfREVMSVZFUlkA0IYDABdNSU5fVVNEVF9GRUVfREVMSVZFUlkxNQD4yQQAD0NSQUZUX1VTRFRfQ09TVADAhD0AFENSQUZUX0RFTElWRVJZX0NPRUZGAAoAFVVTRFQyQUNSRVNfTVVMVElQTElFUgAKAAhyZXNUeXBlcwkAzAgCAgNPaWwJAMwIAgIDT3JlCQDMCAICBFdvb2QJAMwIAgIEU2FuZAkAzAgCAgRDbGF5CQDMCAICB09yZ2FuaWMFA25pbAAIbWF0VHlwZXMJAMwIAgIERnVlbAkAzAgCAgVNZXRhbAkAzAgCAgVQbGFuawkAzAgCAgVHbGFzcwkAzAgCAgdQbGFzdGljCQDMCAICB1Byb3RlaW4FA25pbAAJcHJvZFR5cGVzCQDMCAICEEZpcnN0IEFpZCBLaXQgTDEJAMwIAgIQRmlyc3QgQWlkIEtpdCBMMgkAzAgCAhBGaXJzdCBBaWQgS2l0IEwzCQDMCAICC0JhY2twYWNrIEwxCQDMCAICC0JhY2twYWNrIEwyCQDMCAICC0JhY2twYWNrIEwzCQDMCAICDkZvb2QgUmF0aW9uIEwxCQDMCAICDkZvb2QgUmF0aW9uIEwyCQDMCAICDkZvb2QgUmF0aW9uIEwzCQDMCAICC0pldCBQYWNrIEwxCQDMCAICC0pldCBQYWNrIEwyCQDMCAICC0pldCBQYWNrIEwzCQDMCAICCVNoaWVsZCBMMQkAzAgCAglTaGllbGQgTDIJAMwIAgIJU2hpZWxkIEwzCQDMCAICB01pbmUgTDEJAMwIAgIHTWluZSBMMgkAzAgCAgdNaW5lIEwzCQDMCAICB1RyYXAgTDEJAMwIAgIHVHJhcCBMMgkAzAgCAgdUcmFwIEwzBQNuaWwACmNvbnRpbmVudHMJAMwIAgIIQW1lcmljYXMJAMwIAgIGRXVyb3BlCQDMCAICBEFzaWEJAMwIAgIGQWZyaWNhCQDMCAICB09jZWFuaWEFA25pbAAJQ09FRkYyTUFUAICt4gQAEHByb2R1Y3Rpb25NYXRyaXgJAMwIAgIlOF84XzhfMTdfMTdfNDJfMTJfMF8zMF8wLDAsMCwwLDAsMCwwXwkAzAgCAiU4XzhfOF8xN18xN180Ml8yNF8wXzYwXzAsMCw1LDIsMCwwLDBfCQDMCAICJzhfOF84XzE3XzE3XzQyXzM2XzBfMTIwXzAsMCwxMCw0LDAsMCwwXwkAzAgCAik4XzE5XzE5XzhfMjdfMTlfMjZfMV8yMF8wLDAsMCwwLDAsMCwwXzAwMQkAzAgCAik4XzE5XzE5XzhfMjdfMTlfNTJfMV80MF8wLDAsMCwwLDAsMCwwXzAwMQkAzAgCAik4XzE5XzE5XzhfMjdfMTlfNzhfMV84MF8wLDAsMCwwLDAsMCwwXzAwMQkAzAgCAiU4XzhfOF84XzhfNjBfMTNfMl8yXzAsMCwwLDAsMCwwLDBfMDExCQDMCAICJThfOF84XzhfOF82MF8yNl8yXzRfMCwwLDAsMCwwLDAsMF8wMTEJAMwIAgIlOF84XzhfOF84XzYwXzM5XzJfOF8wLDAsMCwwLDAsMCwwXzAxMQkAzAgCAikzMF8zMF8zXzE3XzE3XzNfMzBfM18zMF8wLDAsMCwwLDAsMCwwXzExMQkAzAgCAikzMF8zMF8zXzE3XzE3XzNfNjBfM181MF8wLDAsMCwwLDAsMCwwXzExMQkAzAgCAikzMF8zMF8zXzE3XzE3XzNfOTBfM183MF8wLDAsMCwwLDAsMCwwXzExMQkAzAgCAisxOF8xOF8xMF8xOF8xOF8xOF8xMV80XzEwXzAsMCwwLDAsMCwwLDBfMjAxCQDMCAICKzE4XzE4XzEwXzE4XzE4XzE4XzIyXzRfMjBfMCwwLDAsMCwwLDAsMF8yMDEJAMwIAgIrMThfMThfMTBfMThfMThfMThfMzNfNF8zMF8wLDAsMCwwLDAsMCwwXzIwMQkAzAgCAio0XzEzXzIyXzRfMzVfMjJfMjNfMF81MCwxLDBfMCwwLDAsMCwwLDAsMF8JAMwIAgIqNF8xM18yMl80XzM1XzIyXzQ2XzBfNTAsMSwxXzAsMiw1LDAsMCwwLDBfCQDMCAICKzRfMTNfMjJfNF8zNV8yMl82OV8wXzUwLDIsMV8wLDUsMTAsMCwwLDAsMF8JAMwIAgIqNV8yNV80MF81XzEwXzE1XzIwXzFfMzAsMSwxXzAsMCwwLDAsMCwwLDBfCQDMCAICKjVfMjVfNDBfNV8xMF8xNV80MF8xXzMwLDEsMl8yLDEsMywwLDAsMCwwXwkAzAgCAio1XzI1XzQwXzVfMTBfMTVfNjBfMV8zMCwxLDNfNSwyLDgsMCwwLDAsMF8FA25pbAAJcklkeENvZWZmAAYADXJJZHhDb250aW5lbnQABwAKUkVDSVBFU0laRQALAA5QUk9EVUNUUEtHU0laRQAKAAt3aElkeExldmVscwAAAAh3aElkeFJlcwABAAh3aElkeE1hdAACAAl3aElkeFByb2QAAwAJd2hJZHhMT0ZUAAQACXZvbExvY2tlZAAAAAh2b2xUb3RhbAADAApicElkeExldmVsAAAACGJwSWR4UmVzAAEACGJwSWR4TWF0AAIACWJwSWR4UHJvZAADAA9sb2NJZHhDb250aW5lbnQAAAAKbG9jSWR4VHlwZQABAAhsb2NJZHhJZAACARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBB2Fzc2V0SWQJAKwCAgIDbm9fBQdhc3NldElkARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQdhc3NldElkCQCsAgICA3N0XwUHYXNzZXRJZAEPa2V5QWRkcmVzc1JlZkJ5AQRhZGRyCQCsAgICCWFjY1JlZkJ5XwUEYWRkcgEUa2V5U3Rha2VkRHVja0J5T3duZXIBCW93bmVyQWRkcgkArAICAhJzdGFrZWREdWNrQnlPd25lcl8FCW93bmVyQWRkcgERa2V5QmFja3BhY2tCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICCWJhY2tQYWNrXwULZHVja0Fzc2V0SWQBD2tleUR1Y2tMb2NhdGlvbgELZHVja0Fzc2V0SWQJAKwCAgINZHVja0xvY2F0aW9uXwULZHVja0Fzc2V0SWQBDmtleU9yZGVyQnlMYW5kAQtsYW5kQXNzZXRJZAkArAICAgpsYW5kT3JkZXJfBQtsYW5kQXNzZXRJZAEOa2V5RXNXYXJlaG91c2UAAhplbWVyZ2VuY3lXYXJlaG91c2VQcm9kdWN0cwAPZGVsaXZlcnlGdW5kS2V5AgxkZWxpdmVyeUZ1bmQAEWRlbGl2ZXJ5TG9ja2VkS2V5Ag5kZWxpdmVyeUxvY2tlZAESZ2V0UmVjaXBlTWF0ZXJpYWxzAQZyZWNpcGUJAGgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcmVjaXBlBQlySWR4Q29lZmYFCUNPRUZGMk1BVAAFY2hhaW4JAMkBAgkAygECCAUEdGhpcwVieXRlcwABAAEAC3VzZHRBc3NldElkBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwASCE2nqyCAM/TtG7yo7ui5O8yYLdC136B5ao1CP5qA//uQMJAAACAQFUBQckbWF0Y2gwASBVsdifcoeC7+XjW42sBatl3ppDoS8WuwXzGreHpfHFGAkAAgECDVVua25vd24gY2hhaW4AFWRlZmF1bHRSZXN0QWRkcmVzc1N0cgQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAIjM1BRQ3V2RmJ2aDRMa1BVbnJuVTF6M2puYkExcDltM1dOaHYDCQAAAgEBVAUHJG1hdGNoMAIjM011bWtHR3p0Q0tBWHBXRHF4a2Rkb2ZxWFNVYnFRa3ZTSnkJAAIBAg1Vbmtub3duIGNoYWluAANTRVACAl9fAAVNVUxUNQCgjQYABU1VTFQ2AMCEPQAFTVVMVDgAgMLXLwAGTVVMVDEwAIDIr6AlAA5NSU5TSE9QUEFZTUVOVACgjQYABUlURVI2CQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwBD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAABFJZHhDZmdTdGFraW5nRGFwcAABABRJZHhDZmdJbnZlc3RGdW5kRGFwcAAGAA9JZHhDZmdBY3Jlc0RhcHAACAEKa2V5UmVzdENmZwACDiVzX19yZXN0Q29uZmlnAQ5rZXlSZXN0QWRkcmVzcwACDCVzX19yZXN0QWRkcgERcmVhZFJlc3RDZmdPckZhaWwBBHJlc3QJALwJAgkBD2dldFN0cmluZ09yRmFpbAIFBHJlc3QJAQprZXlSZXN0Q2ZnAAUDU0VQARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCB3Jlc3RDZmcDaWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQdyZXN0Q2ZnBQNpZHgJAKwCAgIqUmVzdCBjZmcgZG9lc24ndCBjb250YWluIGFkZHJlc3MgYXQgaW5kZXggCQCkAwEFA2lkeAAMcmVzdENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJAQ5rZXlSZXN0QWRkcmVzcwAFFWRlZmF1bHRSZXN0QWRkcmVzc1N0cgAHcmVzdENmZwkBEXJlYWRSZXN0Q2ZnT3JGYWlsAQUMcmVzdENvbnRyYWN0AA9zdGFraW5nQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBRFJZHhDZmdTdGFraW5nRGFwcAASaW52ZXN0RnVuZENvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUUSWR4Q2ZnSW52ZXN0RnVuZERhcHAADWFjcmVzQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBQ9JZHhDZmdBY3Jlc0RhcHABCGFzU3RyaW5nAQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAUBcwkAAgECGGZhaWwgdG8gY2FzdCBpbnRvIFN0cmluZwEFYXNJbnQBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIDSW50BAFuBQckbWF0Y2gwBQFuCQACAQIVZmFpbCB0byBjYXN0IGludG8gSW50AQprZXlCbG9ja2VkAAIQY29udHJhY3RzQmxvY2tlZAEKZml4ZWRQb2ludAIDdmFsCGRlY2ltYWxzBAZ0ZW5Qb3cJAGwGAAoAAAUIZGVjaW1hbHMAAAAABQRET1dOBAdsb3dQYXJ0CQCkAwEJAGoCBQN2YWwFBnRlblBvdwQGemVyb2VzCQCwAgIJAKQDAQUGdGVuUG93CQBkAgABCQCxAgEFB2xvd1BhcnQJAKwCAgkArAICCQCsAgIJAKQDAQkAaQIFA3ZhbAUGdGVuUG93AgEuBQZ6ZXJvZXMFB2xvd1BhcnQAE0ZBQ1RPUllNQVhXQVJFSE9VU0UAgMivoCUADlNFTExNVUxUSVBMSUVSAMgBAA1CVVlNVUxUSVBMSUVSAKwCAApBVUNUSU9ORkVFAJBOAAxERUxJVkVSWV9GRUUAkE4ADkRFTElWRVJZX0ZFRTE1AJh1AR5rZXlGYWN0b3J5V2FyZWhvdXNlQnlJZEFuZFR5cGUCCWZhY3RvcnlJZAdyZXNUeXBlCQCsAgIJAKwCAgkArAICAhtmYWN0b3J5V2hCeUNvbnRpbmVudEFuZFJlc18FCWZhY3RvcnlJZAIBXwkApAMBBQdyZXNUeXBlAAlvcmRJZHhSZXMAAAAJb3JkSWR4TWF0AAEACm9yZElkeFByb2QAAgEIZ2V0T3JkZXIBBm9yZEtleQQBcAkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEFBm9yZEtleQIwMEAwXzBAMF8wQDBfMEAwXzBAMF8wQDA6MEAwXzBAMF8wQDBfMEAwXzBAMF8wQDA6AgE6CQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUBcAUJb3JkSWR4UmVzAgFfBQZOVU1SRVMJAJEDAgUBcAUJb3JkSWR4UmVzAhcwQDBfMEAwXzBAMF8wQDBfMEAwXzBAMAkAzAgCAwkAAAIJAJADAQkAtQkCCQCRAwIFAXAFCW9yZElkeE1hdAIBXwUGTlVNUkVTCQCRAwIFAXAFCW9yZElkeE1hdAIXMEAwXzBAMF8wQDBfMEAwXzBAMF8wQDAJAMwIAgkAkQMCBQFwBQpvcmRJZHhQcm9kBQNuaWwBCHRvVm9sdW1lAwZhbW91bnQHcGtnU2l6ZQlpc1Byb2R1Y3QDBQlpc1Byb2R1Y3QEBHBrZ3MDCQBnAgUGYW1vdW50AAAJAGkCCQBlAgkAZAIFBmFtb3VudAUHcGtnU2l6ZQABBQdwa2dTaXplCQEBLQEJAGkCCQBlAgkAZAIJAQEtAQUGYW1vdW50BQdwa2dTaXplAAEFB3BrZ1NpemUJAGgCBQRwa2dzBQVNVUxUOAUGYW1vdW50AQxzZWxsSW50ZXJuYWwEBWxvY0lkB3Jlc1R5cGUGYW1vdW50CG1pblByaWNlBAV3aEtleQkBHmtleUZhY3RvcnlXYXJlaG91c2VCeUlkQW5kVHlwZQIFBWxvY0lkBQdyZXNUeXBlBAJ3MAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQV3aEtleQAABAJyMAMJAGYCBQJ3MAUTRkFDVE9SWU1BWFdBUkVIT1VTRQAAAwkAZgIJAGQCBQJ3MAUGYW1vdW50BRNGQUNUT1JZTUFYV0FSRUhPVVNFCQBlAgUTRkFDVE9SWU1BWFdBUkVIT1VTRQUCdzAFBmFtb3VudAQMdXNkdFJlY2VpdmVkCQBkAgkAawMFAnIwCQBlAgkAaAIFDlNFTExNVUxUSVBMSUVSBRBSRVNPVVJDRVBSSUNFTUlOCQBrAwkAZAIJAGgCAGQFAncwCQBoAgAyBQJyMAUQUkVTT1VSQ0VQUklDRU1JTgUTRkFDVE9SWU1BWFdBUkVIT1VTRQUGTVVMVDEwCQBrAwkAZQIFBmFtb3VudAUCcjAFEFJFU09VUkNFUFJJQ0VNSU4FBU1VTFQ4BAVtaW45OQkAZQIFCG1pblByaWNlCQBpAgUIbWluUHJpY2UAZAMJAGYCCQBoAgUFbWluOTkFBmFtb3VudAkAaAIFDHVzZHRSZWNlaXZlZAUFTVVMVDgJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICD0FjdHVhbCBwcmljZSA9IAkApAMBBQx1c2R0UmVjZWl2ZWQCAyAvIAkApAMBBQZhbW91bnQCDiA8IG1pblByaWNlID0gCQCkAwEFCG1pblByaWNlAgMsICgFBWxvY0lkAgIsIAkAkQMCBQhyZXNUeXBlcwUHcmVzVHlwZQIBKQkAlAoCCQEMSW50ZWdlckVudHJ5AgUFd2hLZXkJAGQCBQJ3MAUGYW1vdW50BQx1c2R0UmVjZWl2ZWQBC2J1eUludGVybmFsBAVsb2NJZAdtYXRUeXBlBmFtb3VudAhtYXhQcmljZQQFd2hLZXkJAR5rZXlGYWN0b3J5V2FyZWhvdXNlQnlJZEFuZFR5cGUCBQVsb2NJZAUHbWF0VHlwZQQCdzAJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUFd2hLZXkAAAQCbTEDCQBmAgUCdzAFE0ZBQ1RPUllNQVhXQVJFSE9VU0UJAJcDAQkAzAgCBQZhbW91bnQJAMwIAgkAZQIFAncwBRNGQUNUT1JZTUFYV0FSRUhPVVNFBQNuaWwAAAQCbTAJAJcDAQkAzAgCBQJ3MAkAzAgCCQBlAgUGYW1vdW50BQJtMQUDbmlsBAFtCQBkAgUCbTAFAm0xBAV3MG1pbgkAlwMBCQDMCAIFAncwCQDMCAIFE0ZBQ1RPUllNQVhXQVJFSE9VU0UFA25pbAQJdXNkdFNwZW50CQBkAgkAawMFAm0wCQBlAgkAaAIFDUJVWU1VTFRJUExJRVIFEFJFU09VUkNFUFJJQ0VNSU4JAGsDCQBlAgkAaAIAZAUFdzBtaW4JAGgCADIFAm0wBRBSRVNPVVJDRVBSSUNFTUlOBRNGQUNUT1JZTUFYV0FSRUhPVVNFBQZNVUxUMTAJAGsDBQJtMQkAaAIAAgUQUkVTT1VSQ0VQUklDRU1JTgUFTVVMVDgEBm1heDEwMQkAZAIFCG1heFByaWNlCQBpAgUIbWF4UHJpY2UAZAMJAGYCCQBoAgUJdXNkdFNwZW50BQVNVUxUOAkAaAIFBm1heDEwMQUBbQkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIPQWN0dWFsIHByaWNlID0gCQCkAwEFCXVzZHRTcGVudAIDIC8gCQCkAwEFAW0CDiA+IG1heFByaWNlID0gCQCkAwEFCG1heFByaWNlAgMsICgFBWxvY0lkAgIsIAkAkQMCBQhtYXRUeXBlcwUHbWF0VHlwZQIBKQkAlQoDCQEMSW50ZWdlckVudHJ5AgUFd2hLZXkJAGUCBQJ3MAUBbQUJdXNkdFNwZW50BQFtAQtnZXRCYWNrcGFjawEFYnBLZXkEAXAJALwJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QFBWJwS2V5AhowOjBfMF8wXzBfMF8wOjBfMF8wXzBfMF8wOgIBOgkAzAgCCQCkAwEJAQt2YWx1ZU9yRWxzZQIJALYJAQkAkQMCBQFwBQpicElkeExldmVsAAAJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQFwBQhicElkeFJlcwIBXwUGTlVNUkVTCQCRAwIFAXAFCGJwSWR4UmVzAgswXzBfMF8wXzBfMAkAzAgCAwkAAAIJAJADAQkAtQkCCQCRAwIFAXAFCGJwSWR4TWF0AgFfBQZOVU1SRVMJAJEDAgUBcAUIYnBJZHhNYXQCCzBfMF8wXzBfMF8wCQDMCAIJAJEDAgUBcAUJYnBJZHhQcm9kBQNuaWwBDGNoZWNrQmxvY2tlZAADCQELdmFsdWVPckVsc2UCCQCbCAIFD3N0YWtpbmdDb250cmFjdAkBCmtleUJsb2NrZWQABwkAAgECH0NvbnRyYWN0cyBhcmUgdW5kZXIgbWFpbnRlbmFuY2UFBHVuaXQBBnByb2xvZwAJAQVhc0ludAEJAP0HBAUPc3Rha2luZ0NvbnRyYWN0AgpzYXZlTGFzdFR4BQNuaWwFA25pbAEJc2V0Q29tbW9uAgNhY2MPaWdub3JlZEl0ZXJhdG9yBAFqCAUDYWNjAl8xBARpdGVtAwkAZgIJAJADAQgFA2FjYwNfMTAFAWoJAJEDAggFA2FjYwNfMTAFAWoCAzBAMAQGaXNQcm9kCAUDYWNjAl84BAlpdGVtUGFydHMJALUJAgUEaXRlbQIBQAMJAQIhPQIJAJADAQUJaXRlbVBhcnRzAAIJAAIBAi5JbmNvcnJlY3Qgb3JkZXIgZm9ybWF0LCBzaG91bGQgYmUgYW1vdW50QHByaWNlBAhuZXdPcmRBbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWl0ZW1QYXJ0cwAABAhuZXdPcmRQcgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWl0ZW1QYXJ0cwABBAluZXdPcmRVc2QDBQZpc1Byb2QJAGgCBQhuZXdPcmRBbQUIbmV3T3JkUHIJAGsDBQhuZXdPcmRBbQUIbmV3T3JkUHIFBU1VTFQ4BAluZXdPcmRWb2wJAQh0b1ZvbHVtZQMFCG5ld09yZEFtBQ5QUk9EVUNUUEtHU0laRQUGaXNQcm9kBAZ3aEluaXQDCQBmAgkAkAMBCAUDYWNjAl82BQFqCQENcGFyc2VJbnRWYWx1ZQEJAJEDAggFA2FjYwJfNgUBagAABAtjdXJPcmRQYXJ0cwkAtQkCAwkAZgIJAJADAQgFA2FjYwJfNwUBagkAkQMCCAUDYWNjAl83BQFqAgMwQDACAUAECGN1ck9yZEFtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgULY3VyT3JkUGFydHMAAAQIY3VyT3JkUHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQtjdXJPcmRQYXJ0cwABAwMJAGYCAAAFCGN1ck9yZFByBgkAZgIAAAUIbmV3T3JkUHIJAAIBAhdQcmljZSBjYW4ndCBiZSBuZWdhdGl2ZQQJY3VyT3JkVXNkAwUGaXNQcm9kCQBoAgUIY3VyT3JkQW0FCGN1ck9yZFByCQBrAwUIY3VyT3JkQW0FCGN1ck9yZFByBQVNVUxUOAMJAAACBQhuZXdPcmRBbQAAAwkAZgIFCGN1ck9yZEFtAAAJAJwKCgkAZAIFAWoAAQkAzQgCCAUDYWNjAl8yCQCkAwEFBndoSW5pdAgFA2FjYwJfMwgFA2FjYwJfNAkAZQIIBQNhY2MCXzUFCWN1ck9yZFVzZAgFA2FjYwJfNggFA2FjYwJfNwUGaXNQcm9kCQBkAggFA2FjYwJfOQkBCHRvVm9sdW1lAwUGd2hJbml0BQ5QUk9EVUNUUEtHU0laRQUGaXNQcm9kCAUDYWNjA18xMAkAnAoKCQBkAgUBagABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZQIFBndoSW5pdAUIY3VyT3JkQW0IBQNhY2MCXzMIBQNhY2MCXzQIBQNhY2MCXzUIBQNhY2MCXzYIBQNhY2MCXzcFBmlzUHJvZAkAZAIIBQNhY2MCXzkJAQh0b1ZvbHVtZQMJAGUCBQZ3aEluaXQFCGN1ck9yZEFtBQ5QUk9EVUNUUEtHU0laRQUGaXNQcm9kCAUDYWNjA18xMAMJAGYCBQhuZXdPcmRBbQAAAwkAZgIAAAUIY3VyT3JkQW0JAJwKCgkAZAIFAWoAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGUCBQZ3aEluaXQFCGN1ck9yZEFtCQBkAggFA2FjYwJfMwUJbmV3T3JkVm9sCAUDYWNjAl80CQBkAggFA2FjYwJfNQUJbmV3T3JkVXNkCAUDYWNjAl82CAUDYWNjAl83BQZpc1Byb2QJAQh0b1ZvbHVtZQMJAGUCBQZ3aEluaXQFCGN1ck9yZEFtBQ5QUk9EVUNUUEtHU0laRQUGaXNQcm9kCAUDYWNjA18xMAkAnAoKCQBkAgUBagABCQDNCAIIBQNhY2MCXzIJAKQDAQUGd2hJbml0CQBkAggFA2FjYwJfMwUJbmV3T3JkVm9sCAUDYWNjAl80CQBlAgkAZAIIBQNhY2MCXzUFCW5ld09yZFVzZAUJY3VyT3JkVXNkCAUDYWNjAl82CAUDYWNjAl83BQZpc1Byb2QJAQh0b1ZvbHVtZQMFBndoSW5pdAUOUFJPRFVDVFBLR1NJWkUFBmlzUHJvZAgFA2FjYwNfMTADCQBmAgAABQhjdXJPcmRBbQQGYW1EaWZmCQBlAgUIY3VyT3JkQW0FCG5ld09yZEFtAwkAZgIAAAkAZQIFBndoSW5pdAUGYW1EaWZmCQACAQkArAICCQCsAgIJAKwCAgkArAICAhBBdHRlbXB0IHRvIHRha2UgCQCkAwEFBmFtRGlmZgIaIGZyb20gd2FyZWhvdXNlLCBidXQgb25seSAJAKQDAQUGd2hJbml0AgogYXZhaWxhYmxlCQCcCgoJAGQCBQFqAAEJAM0IAggFA2FjYwJfMgkApAMBCQBlAgUGd2hJbml0BQZhbURpZmYIBQNhY2MCXzMJAGUCCAUDYWNjAl80BQluZXdPcmRWb2wIBQNhY2MCXzUIBQNhY2MCXzYIBQNhY2MCXzcFBmlzUHJvZAkBCHRvVm9sdW1lAwkAZQIFBndoSW5pdAUGYW1EaWZmBQ5QUk9EVUNUUEtHU0laRQUGaXNQcm9kCAUDYWNjA18xMAMJAGYCAAAJAGQCBQZ3aEluaXQFCG5ld09yZEFtCQACAQkArAICCQCsAgIJAKwCAgkArAICAhBBdHRlbXB0IHRvIHRha2UgCQCkAwEJAQEtAQUIbmV3T3JkQW0CGiBmcm9tIHdhcmVob3VzZSwgYnV0IG9ubHkgCQCkAwEFBndoSW5pdAIKIGF2YWlsYWJsZQkAnAoKCQBkAgUBagABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZAIFBndoSW5pdAUIbmV3T3JkQW0IBQNhY2MCXzMJAGUCCAUDYWNjAl80BQluZXdPcmRWb2wJAGUCCAUDYWNjAl81BQljdXJPcmRVc2QIBQNhY2MCXzYIBQNhY2MCXzcFBmlzUHJvZAkBCHRvVm9sdW1lAwkAZAIFBndoSW5pdAUIbmV3T3JkQW0FDlBST0RVQ1RQS0dTSVpFBQZpc1Byb2QIBQNhY2MDXzEwAQtzZXRJbnRlcm5hbAMJY3VycmVudFdoCmN1cnJlbnRPcmQGbmV3T3JkBAljdXJyV2hSZXMJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfBAljdXJyV2hNYXQJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4TWF0AgFfBApjdXJyV2hQcm9kAwkAAAIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAV8EDWN1cnJlbnRPcmRSZXMJALUJAgkAkQMCBQpjdXJyZW50T3JkBQlvcmRJZHhSZXMCAV8EDWN1cnJlbnRPcmRNYXQJALUJAgkAkQMCBQpjdXJyZW50T3JkBQlvcmRJZHhNYXQCAV8EDmN1cnJlbnRPcmRQcm9kAwkAAAIJAJEDAgUKY3VycmVudE9yZAUKb3JkSWR4UHJvZAIABQNuaWwJALwJAgkAkQMCBQpjdXJyZW50T3JkBQpvcmRJZHhQcm9kAgFfAwkBAiE9AgkAkAMBBQZuZXdPcmQAAwkAAgECM25ld09yZGVyU3RyIHNob3VsZCBjb250YWluIGV4YWN0bHkgMiAnOicgc2VwYXJhdG9ycwQIcmVzUGFydHMJALUJAgkAkQMCBQZuZXdPcmQAAAIBXwQIbWF0UGFydHMJALUJAgkAkQMCBQZuZXdPcmQAAQIBXwQJcHJvZFBhcnRzAwkAAAIJAJEDAgUGbmV3T3JkAAICAAUDbmlsCQC8CQIJAJEDAgUGbmV3T3JkAAICAV8DCQECIT0CCQCQAwEFCHJlc1BhcnRzBQZOVU1SRVMJAAIBAiBBbGwgNiByZXNvdXJjZXMgc2hvdWxkIGJlIHBhc3NlZAMJAQIhPQIJAJADAQUIbWF0UGFydHMFBk5VTVJFUwkAAgECIEFsbCA2IG1hdGVyaWFscyBzaG91bGQgYmUgcGFzc2VkBAFyCgACJGwFCHJlc1R5cGVzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAnAoKAAAFA25pbAAAAAAAAAUJY3VycldoUmVzBQ1jdXJy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BQNhY2MCXzgFAWoJAQ1wYXJzZUludFZhbHVlAQkAkQMCCAUDYWNjAl84BQFqAAAEBndoSW5pdAMJAGYCCQCQAwEIBQNhY2MCXzkFAWoJAQ1wYXJzZUludFZhbHVlAQkAkQMCCAUDYWNjAl85BQFqAAAECXdoT3JkSW5pdAMJAGYCCQCQAwEIBQNhY2MDXzEwBQFqCQCRAwIIBQNhY2MDXzEwBQFqAgMwQDAECndoT3JkUGFydHMJALUJAgUJd2hPcmRJbml0AgFABAd3aE9yZEFtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKd2hPcmRQYXJ0cwAABAd3aE9yZFByCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKd2hPcmRQYXJ0cwABAwMJAQIhPQIFB2JwT3JkQW0AAAkBAiE9AgUHYnBPcmRQcgUHd2hPcmRQcgcJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIKUHJpY2VzIG9mIAkAkQMCCAUDYWNjA18xMQUBagIXIGRvbid0IG1hdGNoISBXSCBwcmljZT0JAKQDAQUHd2hPcmRQcgINLCB5b3VyIHByaWNlPQkApAMBBQdicE9yZFByBAh3aE9yZFVzZAMFBmlzUHJvZAkAaAIFB3doT3JkQW0FB3doT3JkUHIJAGsDBQd3aE9yZEFtBQd3aE9yZFByBQVNVUxUOAQIZGVsdGFWb2wJAQh0b1ZvbHVtZQMFB2JwT3JkQW0FDlBST0RVQ1RQS0dTSVpFBQZpc1Byb2QDCQAAAgUHYnBPcmRBbQAACQCfCg0JAM0IAggFA2FjYwJfMQkApAMBBQZ3aEluaXQJAM0IAggFA2FjYwJfMgUJd2hPcmRJbml0CQDNCAIIBQNhY2MCXzMJAKQDAQUGYnBJbml0CAUDYWNjAl80CAUDYWNjAl81CAUDYWNjAl82CQBkAggFA2FjYwJfNwABCAUDYWNjAl84CAUDYWNjAl85CAUDYWNjA18xMAgFA2FjYwNfMTEFBmlzUHJvZAgFA2FjYwNfMTMDCQBmAgUHYnBPcmRBbQAAAwkAZgIAAAUHd2hPcmRBbQMJAGYCBQdicE9yZEFtCQEBLQEFB3doT3JkQW0JAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIPQXR0ZW1wdCB0byBidXkgCQCkAwEFB2JwT3JkQW0CBCBvZiAJAJEDAggFA2FjYwNfMTEFAWoCGywgYnV0IHdhcmVob3VzZSBvbmx5IHNlbGxzIAkApAMBCQEBLQEFB3doT3JkQW0JAJ8KDQkAzQgCCAUDYWNjAl8xCQCkAwEFBndoSW5pdAkAzQgCCAUDYWNjAl8yCQCsAgIJAKwCAgkApAMBCQBkAgUHd2hPcmRBbQUHYnBPcmRBbQIBQAkApAMBBQd3aE9yZFByCQDNCAIIBQNhY2MCXzMJAKQDAQkAZAIFBmJwSW5pdAUHYnBPcmRBbQkAZAIIBQNhY2MCXzQFCGRlbHRhVm9sCAUDYWNjAl81CQBkAggFA2FjYwJfNgUIYnBPcmRVc2QJAGQCCAUDYWNjAl83AAEIBQNhY2MCXzgIBQNhY2MCXzkIBQNhY2MDXzEwCAUDYWNjA18xMQUGaXNQcm9kCQBkAggFA2FjYwNfMTMDBQZpc1Byb2QJAGgCBQdicE9yZEFtBQVNVUxUOAUHYnBPcmRBbQkAAgEJAKwCAgkArAICAg9BdHRlbXB0IHRvIGJ1eSAJAJEDAggFA2FjYwNfMTEFAWoCICB3aGlsZSB3YXJlaG91c2UgZG9lc24ndCBzZWxsIGl0AwkAZgIFB3doT3JkQW0AAAMJAGYCCQEBLQEFB2JwT3JkQW0FB3doT3JkQW0JAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byBzZWxsIAkApAMBCQEBLQEFB2JwT3JkQW0CBCBvZiAJAJEDAggFA2FjYwNfMTEFAWoCGiwgYnV0IHdhcmVob3VzZSBvbmx5IGJ1eXMgCQCkAwEFB3doT3JkQW0DCQBmAgkBAS0BBQdicE9yZEFtBQZicEluaXQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byBzZWxsIAkApAMBCQEBLQEFB2JwT3JkQW0CFCwgYnV0IHlvdSBvbmx5IGhhdmUgCQCkAwEFBmJwSW5pdAIEIG9mIAkAkQMCCAUDYWNjA18xMQUBagkAnwoNCQDNCAIIBQNhY2MCXzEJAKQDAQkAZQIFBndoSW5pdAUHYnBPcmRBbQkAzQgCCAUDYWNjAl8yCQCsAgIJAKwCAgkApAMBCQBkAgUHd2hPcmRBbQUHYnBPcmRBbQIBQAkApAMBBQd3aE9yZFByCQDNCAIIBQNhY2MCXzMJAKQDAQkAZAIFBmJwSW5pdAUHYnBPcmRBbQkAZQIIBQNhY2MCXzQFCGRlbHRhVm9sCQBlAggFA2FjYwJfNQUIYnBPcmRVc2QIBQNhY2MCXzYJAGQCCAUDYWNjAl83AAEIBQNhY2MCXzgIBQNhY2MCXzkIBQNhY2MDXzEwCAUDYWNjA18xMQUGaXNQcm9kCQBlAggFA2FjYwNfMTMDBQZpc1Byb2QJAGgCBQdicE9yZEFtBQVNVUxUOAUHYnBPcmRBbQkAAgEJAKwCAgkArAICAhBBdHRlbXB0IHRvIHNlbGwgCQCRAwIIBQNhY2MDXzExBQFqAh8gd2hpbGUgd2FyZWhvdXNlIGRvZXNuJ3QgYnV5IGl0ARNzZWxsUmVzb3VyY2VzQ29tbW9uBAdyZXNMaXN0DGZhY3RvcnlMb2NJZAdhbW91bnRzCW1pblByaWNlcwoBBWFkZGVyAgNhY2MBagMJAGYCCQCRAwIFB2Ftb3VudHMFAWoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdyZXNMaXN0BQFqCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCVlvdSBoYXZlIAkAkQMCBQdyZXNMaXN0BQFqAgQgb2YgCQCRAwIFCHJlc1R5cGVzBQFqAhQsIGJ1dCB0cmllZCB0byBzZWxsIAkApAMBCQCRAwIFB2Ftb3VudHMFAWoDCQBmAgAACQCRAwIFB2Ftb3VudHMFAWoJAAIBCQCsAgIJAKwCAgkArAICAiVZb3UgdHJpZWQgdG8gc2VsbCBuZWdhdGl2ZSBhbW91bnQgb2YgCQCRAwIFCHJlc1R5cGVzBQFqAgI6IAkApAMBCQCRAwIFB2Ftb3VudHMFAWoDCQBmAgkAkQMCBQdhbW91bnRzBQFqAAAEAWIJAQxzZWxsSW50ZXJuYWwEBQxmYWN0b3J5TG9jSWQFAWoJAJEDAgUHYW1vdW50cwUBagkAkQMCBQltaW5QcmljZXMFAWoJAJYKBAkAzQgCCAUDYWNjAl8xCAUBYgJfMQkAzQgCCAUDYWNjAl8yCQCkAwEJAGUCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHcmVzTGlzdAUBagkAkQMCBQdhbW91bnRzBQFqCQBkAggFA2FjYwJfMwgFAWICXzIJ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AAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCWV4Y2hhbmdlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgEQc2hvcDJ1c2VyQWN0aW9ucwMNdXNkV2gyQnBTYWxkbwpjYWxsZXJBZGRyC3JlY2VpdmVkRmVlAwkAZgIFDXVzZFdoMkJwU2FsZG8AAAQLdXNkV2gyQnBGZWUJAGsDBQ11c2RXaDJCcFNhbGRvBQpBVUNUSU9ORkVFBQVNVUxUNgMJAGcCBQtyZWNlaXZlZEZlZQkAZQIFDXVzZFdoMkJwU2FsZG8JAGgCAAMFC3VzZFdoMkJwRmVlCQACAQkArAICAitUaGlzIHRyYWRlIGRvZXMgbm90IGNvdmVyIGRlbGl2ZXJ5IGNvc3Qgb2YgCQEKZml4ZWRQb2ludAIFC3JlY2VpdmVkRmVlAAYECHJlZkJ5S2V5CQEPa2V5QWRkcmVzc1JlZkJ5AQUKY2FsbGVyQWRkcgQFcmVmQnkJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0BQhyZWZCeUtleQQGY2FsbGVyCQERQGV4dHJOYXRpdmUoMTA2MikBBQpjYWxsZXJBZGRyCQDNCAIJAM0IAgMJAQlpc0RlZmluZWQBBQVyZWZCeQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBCQEFdmFsdWUBBQVyZWZCeQULdXNkV2gyQnBGZWUFC3VzZHRBc3NldElkBQNuaWwFA25pbAkBDlNjcmlwdFRyYW5zZmVyAwUGY2FsbGVyCQBlAgkAZQIFDXVzZFdoMkJwU2FsZG8JAGgCAAMFC3VzZFdoMkJwRmVlBQtyZWNlaXZlZEZlZQULdXNkdEFzc2V0SWQJAQ5TY3JpcHRUcmFuc2ZlcgMFDHJlc3RDb250cmFjdAULdXNkV2gyQnBGZWUFC3VzZHRBc3NldElkBQNuaWwBEHVzZXIyc2hvcEFjdGlvbnMEDXVzZEJwMldoU2FsZG8EcG10cw1zaG9wTGFuZE93bmVyCHNwZW50RmVlAwkAZgIFDXVzZEJwMldoU2FsZG8AAAMJAQIhPQIJAJADAQUEcG10cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIFBHBtdHMAAAQDYW10CAUDcG10BmFtb3VudAMDCQEBIQEJAQlpc0RlZmluZWQBCAUDcG10B2Fzc2V0SWQGCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQITVVNEVCBwYXltZW50cyBvbmx5IQQQdXNkdFNwZW50V2l0aEZlZQkAZAIFDXVzZEJwMldoU2FsZG8FCHNwZW50RmVlAwkBAiE9AgUDYW10BRB1c2R0U3BlbnRXaXRoRmVlCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIfSW5zdWZmaWNpZW50IHBheW1lbnQhIEF0dGFjaGVkPQkBCmZpeGVkUG9pbnQCBQNhbXQABgILLCByZXF1aXJlZD0JAQpmaXhlZFBvaW50AgUNdXNkQnAyV2hTYWxkbwAGAgErCQEKZml4ZWRQb2ludAIFCHNwZW50RmVlAAYCDihkZWxpdmVyeSBmZWUpAwkAZgIFDk1JTlNIT1BQQVlNRU5UBQ11c2RCcDJXaFNhbGRvCQACAQkArAICAhJNaW4gc2hvcCB0cmFkZSBpcyAJAQpmaXhlZFBvaW50AgUOTUlOU0hPUFBBWU1FTlQABgQLdXNkQnAyV2hGZWUJAGsDBQ11c2RCcDJXaFNhbGRvBQpBVUNUSU9ORkVFBQVNVUxUNgQIcmVmQnlLZXkJAQ9rZXlBZGRyZXNzUmVmQnkBBQ1zaG9wTGFuZE93bmVyBAVyZWZCeQkAnQgCBQ9zdGFraW5nQ29udHJhY3QFCHJlZkJ5S2V5CQDNCAIJAM0IAgMJAQlpc0RlZmluZWQBBQVyZWZCeQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBCQEFdmFsdWUBBQVyZWZCeQULdXNkQnAyV2hGZWUFC3VzZHRBc3NldElkBQNuaWwFA25pbAkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUNc2hvcExhbmRPd25lcgkAZQIFDXVzZEJwMldoU2FsZG8JAGgCAAMFC3VzZEJwMldoRmVlBQt1c2R0QXNzZXRJZAkBDlNjcmlwdFRyYW5zZmVyAwUMcmVzdENvbnRyYWN0BQt1c2RCcDJXaEZlZQULdXNkdEFzc2V0SWQDCQECIT0CCQCQAwEFBHBtdHMAAAkAAgECEk5vIHBheW1lbnRzIG5lZWRlZAUDbmlsARVhY2NlcHRTaG9wT3JkZXJDb21tb24GD3Nob3BMYW5kQXNzZXRJZApjYWxsZXJBZGRyCmJwT3JkZXJTdHIJYnBSZXNMaXN0CWJwTWF0TGlzdApicFByb2RMaXN0BAlsYW5kQXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQ9zaG9wTGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQ9zaG9wTGFuZEFzc2V0SWQJAAIBCQCsAgIJAKwCAgIETkZUIAgFCWxhbmRBc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQNc2hvcExhbmRPd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFD3Nob3BMYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQlsYW5kQXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkAAAIFDXNob3BMYW5kT3duZXIFCmNhbGxlckFkZHIJAAIBAh5Zb3UgY2Fubm90IHRyYWRlIHdpdGggeW91cnNlbGYEDGJwT3JkZXJQYXJ0cwkAvAkCBQpicE9yZGVyU3RyAgE6AwkBAiE9AgkAkAMBBQxicE9yZGVyUGFydHMAAwkAAgECMmJwT3JkZXJTdHIgc2hvdWxkIGNvbnRhaW4gZXhhY3RseSAyICc6JyBzZXBhcmF0b3JzBAhicE9yZFJlcwkAtQkCCQCRAwIFDGJwT3JkZXJQYXJ0cwAAAgFfBAhicE9yZE1hdAkAtQkCCQCRAwIFDGJwT3JkZXJQYXJ0cwABAgFfBAlicE9yZFByb2QDCQAAAgkAkQMCBQxicE9yZGVyUGFydHMAAgIABQNuaWwJALwJAgkAkQMCBQxicE9yZGVyUGFydHMAAgIBXwMJAQIhPQIJAJADAQUIYnBPcmRSZXMFBk5VTVJFUwkAAgECIEFsbCA2IHJlc291cmNlcyBzaG91bGQgYmUgcGFzc2VkAwkBAiE9AgkAkAMBBQhicE9yZE1hdAUGTlVNUkVTCQACAQIgQWxsIDYgbWF0ZXJpYWxzIHNob3VsZCBiZSBwYXNzZWQEAndoCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIUZ2V0V2FyZWhvdXNlUkVBRE9OTFkJAMwIAgUPc2hvcExhbmRBc3NldElkBQNuaWwFA25pbAQJY3VycmVudFdoCQC8CQIFAndoAgE6BAljdXJyV2hSZXMJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfBAljdXJyV2hNYXQJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4TWF0AgFfBApjdXJyV2hQcm9kAwkAAAIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAV8ED2N1cnJXaExvY2tlZFZvbAkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4TE9GVAIBXwUJdm9sTG9ja2VkBAZvcmRLZXkJAQ5rZXlPcmRlckJ5TGFuZAEFD3Nob3BMYW5kQXNzZXRJZAQFd2hPcmQJAQhnZXRPcmRlcgEFBm9yZEtleQQId2hPcmRSZXMJALUJAgkAkQMCBQV3aE9yZAUJb3JkSWR4UmVzAgFfBAh3aE9yZE1hdAkAtQkCCQCRAwIFBXdoT3JkBQlvcmRJZHhNYXQCAV8ECXdoT3JkUHJvZAMJAAACCQCRAwIFBXdoT3JkBQpvcmRJZHhQcm9kAgAFA25pbAkAvAkCCQCRAwIFBXdoT3JkBQpvcmRJZHhQcm9kAgFfBAFyCgACJGwFCGJwT3JkUmVzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAnwoNBQNuaWwFA25pbAUDbmlsAAAAAAAAAAAFCWJwUmVzTGlzdAUJY3VycldoUmVzBQh3aE9yZFJlcwUIcmVzVHlwZXMH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AMwIAgkAuQkCCAUBbQJfMgIBXwkAzAgCCQC6CQIIBQFwAl8yAgFfBQNuaWwCAToEBndoU2F2ZQkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCDXNhdmVXYXJlaG91c2UJAMwIAgUFd2hTdHIJAMwIAgUPc2hvcExhbmRBc3NldElkBQNuaWwFA25pbAQOYWNjU3RhdHNSZXN1bHQJAQVhc0ludAEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag51cGRhdGVBY2NTdGF0cwkAzAgCBQ1zaG9wTGFuZE93bmVyCQDMCAIJAGsDBQZ4cFNob3AIBQFwA18xMwUFTVVMVDgFA25pbAUDbmlsCQCcCgoJAQtTdHJpbmdFbnRyeQIFBm9yZEtleQULbmV3V2hPcmRTdHIIBQFyAl8zCAUBbQJfMwgFAXACXzMIBQFwAl81CAUBcAJfNggFAXADXzEzBQ1zaG9wTGFuZE93bmVyBQZ3aFNhdmUFDmFjY1N0YXRzUmVzdWx0ARpzZWxsUmVzb3VyY2VzV29ybGRJbnRlcm5hbAEGYW1vdW50BAZvbmVSZXMJAGkCBQZhbW91bnQAHgQRb25lRmFjdG9yeUFtb3VudHMJAMwIAgUGb25lUmVzCQDMCAIFBm9uZVJlcwkAzAgCBQZvbmVSZXMJAMwIAgUGb25lUmVzCQDMCAIFBm9uZVJlcwkAzAgCBQZvbmVSZXMFA25pbAQBcwkApAMBBQZvbmVSZXMEB3Jlc0xpc3QJAMwIAgUBcwkAzAgCBQFzCQDMCAIFAXMJAMwIAgUBcwkAzAgCBQFzCQDMCAIFAXMFA25pbAQJbWluUHJpY2VzCQDMCAIAAAkAzAgCAAAJAMwIAgAACQDMCAIAAAkAzAgCAAAJAMwIAgAABQNuaWwKAQpvbmVGYWN0b3J5AgNhY2MJY29udGluZW50BAF4CQETc2VsbFJlc291cmNlc0NvbW1vbgQFB3Jlc0xpc3QFCWNvbnRpbmVudAURb25lRmFjdG9yeUFtb3VudHMFCW1pblByaWNlcwkAlQoDCQDOCAIIBQNhY2MCXzEIBQF4Al8xCQBkAggFA2FjYwJfMggFAXgCXzMJAGQCCAUDYWNjAl8zCAUBeAJfNAQNJHQwMjUyOTIyNTM4MgoAAiRsBQpjb250aW5lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlQoDBQNuaWwAAAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpvbmVGYWN0b3J5AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQQOZmFjdG9yeUFjdGlvbnMIBQ0kdDAyNTI5MjI1MzgyAl8xBAx1c2R0UmVjZWl2ZWQIBQ0kdDAyNTI5MjI1MzgyAl8yBAh0b3RhbFJlcwgFDSR0MDI1MjkyMjUzODICXzMEA2ZlZQkAawMFDHVzZHRSZWNlaXZlZAUMREVMSVZFUllfRkVFBQVNVUxUNgQQYWN0aXZpdGllc0Ftb3VudAkAaQIFDHVzZHRSZWNlaXZlZABkBAh1c2R0TGVmdAkAZQIJAGUCBQx1c2R0UmVjZWl2ZWQFEGFjdGl2aXRpZXNBbW91bnQFA2ZlZQkAlwoFBQ5mYWN0b3J5QWN0aW9ucwUIdXNkdExlZnQFA2ZlZQUQYWN0aXZpdGllc0Ftb3VudAUIdG90YWxSZXMBEGNyYWZ0R29vZHNDb21tb24FB21hdExpc3QIcHJvZExpc3QUbWFudWZhY3RvcnlDb250aW5lbnQKcHJvZHVjdElkeAhxdWFudGl0eQMJAGcCAAAFCHF1YW50aXR5CQACAQIbUXVhbnRpdHkgc2hvdWxkIGJlIHBvc2l0aXZlAwMJAGYCAAAFCnByb2R1Y3RJZHgGCQBnAgUKcHJvZHVjdElkeAkAkAMBBRBwcm9kdWN0aW9uTWF0cml4CQACAQkArAICAhRVbmtub3duIHByb2R1Y3QgaWR4PQkApAMBBQpwcm9kdWN0SWR4BAZyZWNpcGUJALUJAgkAkQMCBRBwcm9kdWN0aW9uTWF0cml4BQpwcm9kdWN0SWR4AgFfAwkBAiE9AgkAkAMBBQZyZWNpcGUFClJFQ0lQRVNJWkUJAAIBCQCsAgICF0ZhdGFsOiB1bmtub3duIHJlY2lwZTogCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgFCnBy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aQMJAGcCBQIkaQUCJHMFAiRhCQEIcHJvZHVjZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjFfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjFfMgIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYJAJUKAwgFBm1lcmdlZAJfMQUHbmV3UHJvZAgFBm1lcmdlZAJfMhgBaQEacmVjYWxjTG9ja2VkVm9sdW1lUkVBRE9OTFkCC2xhbmRBc3NldElkAndoBApjdXJyZW50T3JkCQEIZ2V0T3JkZXIBCQEOa2V5T3JkZXJCeUxhbmQBBQtsYW5kQXNzZXRJZAQBegkBC3NldEludGVybmFsAwUCd2gFCmN1cnJlbnRPcmQFCmN1cnJlbnRPcmQJAJQKAgUDbmlsCQBkAggFAXoCXzQIBQF6Al81AWkBDWNvbnN0cnVjdG9yVjEBCHJlc3RBZGRyAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIRUGVybWlzc2lvbiBkZW5pZWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDmtleVJlc3RBZGRyZXNzAAUIcmVzdEFkZHIFA25pbAFpAQ1zZWxsUmVzb3VyY2VzAgdhbW91bnRzCW1pblByaWNlcwQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAAACBQxwcm9sb2dSZXN1bHQFDHByb2xvZ1Jlc3VsdAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIqc2VsbFJlc291cmNlcyBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnRzBAtjdXJMb2NhdGlvbgkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04CAV8DCQECIT0CCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlAgFGCQACAQkArAICAi1EdWNrIGxvY2F0aW9uIHR5cGUgc2hvdWxkIGJlIEZhY3RvcnksIGJ1dCBpcyAJAJEDAgULY3VyTG9jYXRpb24FCmxvY0lkeFR5cGUEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQHcmVzTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwQNJHQwMjg5MTUyOTA0MQkBE3NlbGxSZXNvdXJjZXNDb21tb24EBQdyZXNMaXN0CQCRAwIFC2N1ckxvY2F0aW9uBQhsb2NJZHhJZAUHYW1vdW50cwUJbWluUHJpY2VzBA5mYWN0b3J5QWN0aW9ucwgFDSR0MDI4OTE1MjkwNDECXzEEBm5ld1JlcwgFDSR0MDI4OTE1MjkwNDECXzIEDHVzZHRSZWNlaXZlZAgFDSR0MDI4OTE1MjkwNDECXzMECHRvdGFsUmVzCAUNJHQwMjg5MTUyOTA0MQJfNAQQYWN0aXZpdGllc0Ftb3VudAkAaQIFDHVzZHRSZWNlaXZlZABkBAduZXdQYWNrCQC6CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQC5CQIFBm5ld1JlcwIBXwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgQOYmFja3BhY2tSZXN1bHQJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag51cGRhdGVCYWNrcGFjawkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCBQduZXdQYWNrBQNuaWwFA25pbAQLc3RhdHNSZXN1bHQJAQVhc0ludAEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag91cGRhdGVEdWNrU3RhdHMJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgkAawMFB3hwVHJhZGUFCHRvdGFsUmVzBQVNVUxUOAUDbmlsBQNuaWwJAJQKAgkAzQgCCQDNCAIFDmZhY3RvcnlBY3Rpb25zCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAGUCBQx1c2R0UmVjZWl2ZWQFEGFjdGl2aXRpZXNBbW91bnQFC3VzZHRBc3NldElkCQEOU2NyaXB0VHJhbnNmZXIDBQxyZXN0Q29udHJhY3QFEGFjdGl2aXRpZXNBbW91bnQFC3VzZHRBc3NldElkCQCVCgMFDmJhY2twYWNrUmVzdWx0BQxwcm9sb2dSZXN1bHQFC3N0YXRzUmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEnNlbGxSZXNvdXJjZXNXb3JsZAIEYWRkcgZhbW91bnQDCQECIT0CCAUBaQZjYWxsZXIFDWFjcmVzQ29udHJhY3QJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQNJHQwMjk4MzMyOTk5MAkBGnNlbGxSZXNvdXJjZXNXb3JsZEludGVybmFsAQUGYW1vdW50BA5mYWN0b3J5QWN0aW9ucwgFDSR0MDI5ODMzMjk5OTACXzEECHVzZHRMZWZ0CAUNJHQwMjk4MzMyOTk5MAJfMgQDZmVlCAUNJHQwMjk4MzMyOTk5MAJfMwQQYWN0aXZpdGllc0Ftb3VudAgFDSR0MDI5ODMzMjk5OTACXzQECHRvdGFsUmVzCAUNJHQwMjk4MzMyOTk5MAJfNQMJAGcCAAAFCHVzZHRMZWZ0CQACAQkArAICAitUaGlzIHRyYWRlIGRvZXMgbm90IGNvdmVyIGRlbGl2ZXJ5IGNvc3Qgb2YgCQEKZml4ZWRQb2ludAIFA2ZlZQAGBAtzdGF0c1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCDnVwZGF0ZUFjY1N0YXRzCQDMCAIFBGFkZHIJAMwIAgkAawMFB3hwVHJhZGUFCHRvdGFsUmVzBQVNVUxUOAUDbmlsBQNuaWwJAJQKAgkAzQgCCQDNCAIJAM0IAgUOZmFjdG9yeUFjdGlvbnMJAQxJbnRlZ2VyRW50cnkCBQ9kZWxpdmVyeUZ1bmRLZXkJAGQCCQELdmFsdWVPckVsc2UCCQCfCAEFD2RlbGl2ZXJ5RnVuZEtleQAABQNmZWUJAQ5TY3JpcHRUcmFuc2ZlcgMFDHJlc3RDb250cmFjdAUQYWN0aXZpdGllc0Ftb3VudAULdXNkdEFzc2V0SWQJAQ5TY3JpcHRUcmFuc2ZlcgMFEmludmVzdEZ1bmRDb250cmFjdAUIdXNkdExlZnQFC3VzZHRBc3NldElkCQCUCgIFCHVzZHRMZWZ0BQtzdGF0c1Jlc3VsdAFpARpzZWxsUmVzb3VyY2VzV29ybGRSRUFET05MWQEGYW1vdW50BAh1c2R0TGVmdAgJARpzZWxsUmVzb3VyY2VzV29ybGRJbnRlcm5hbAEFBmFtb3VudAJfMgkAlAoCBQNuaWwFCHVzZHRMZWZ0AWkBGXNlbGxSZXNvdXJjZXNEdWNrRGVsaXZlcnkDB2Ftb3VudHMJbWluUHJpY2VzEGZhY3RvcnlDb250aW5lbnQEDHByb2xvZ1Jlc3VsdAkBBnByb2xvZwADCQAAAgUMcHJvbG9nUmVzdWx0BQxwcm9sb2dSZXN1bHQEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECKnNlbGxSZXNvdXJjZXMgZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50cwQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAdyZXNMaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzAgFfBA0kdDAzMTE0OTMxMjcwCQETc2VsbFJlc291cmNlc0NvbW1vbgQFB3Jlc0xpc3QFEGZhY3RvcnlDb250aW5lbnQFB2Ftb3VudHMFCW1pblByaWNlcwQOZmFjdG9yeUFjdGlvbnMIBQ0kdDAzMTE0OTMxMjcwAl8xBAZuZXdSZXMIBQ0kdDAzMTE0OTMxMjcwAl8yBAx1c2R0UmVjZWl2ZWQIBQ0kdDAzMTE0OTMxMjcwAl8zBAh0b3RhbFJlcwgFDSR0MDMxMTQ5MzEyNzACXzQEB25ld1BhY2sJALoJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJALkJAgUGbmV3UmVzAgFfCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6BA5iYWNrcGFja1Jlc3VsdAkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCDnVwZGF0ZUJhY2twYWNrCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIFB25ld1BhY2sFA25pbAUDbmlsBAtzdGF0c1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCD3VwZGF0ZUR1Y2tTdGF0cwkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCCQBrAwUHeHBUcmFkZQUIdG90YWxSZXMFBU1VTFQ4BQNuaWwFA25pbAQHZmVlUGFydAkAawMFDHVzZHRSZWNlaXZlZAUMREVMSVZFUllfRkVFBQVNVUxUNgQDZmVlCQCWAwEJAMwIAgUHZmVlUGFydAkAzAgCBRVNSU5fVVNEVF9GRUVfREVMSVZFUlkFA25pbAQQYWN0aXZpdGllc0Ftb3VudAkAaQIFDHVzZHRSZWNlaXZlZABkAwkAZwIFA2ZlZQkAZQIFDHVzZHRSZWNlaXZlZAUQYWN0aXZpdGllc0Ftb3VudAkAAgEJAKwCAgIrVGhpcyB0cmFkZSBkb2VzIG5vdCBjb3ZlciBkZWxpdmVyeSBjb3N0IG9mIAkBCmZpeGVkUG9pbnQCBQNmZWUABgQJZnVuZFRvdGFsCQELdmFsdWVPckVsc2UCCQCfCAEFD2RlbGl2ZXJ5RnVuZEtleQAACQCUCgIJAM0IAgkAzQgCCQDNCAIFDmZhY3RvcnlBY3Rpb25zCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAGUCCQBlAgUMdXNkdFJlY2VpdmVkBRBhY3Rpdml0aWVzQW1vdW50BQNmZWUFC3VzZHRBc3NldElkCQEMSW50ZWdlckVudHJ5AgUPZGVsaXZlcnlGdW5kS2V5CQBkAgUJZnVuZFRvdGFsBQNmZWUJAQ5TY3JpcHRUcmFuc2ZlcgMFDHJlc3RDb250cmFjdAUQYWN0aXZpdGllc0Ftb3VudAULdXNkdEFzc2V0SWQJAJUKAwUOYmFja3BhY2tSZXN1bHQFDHByb2xvZ1Jlc3VsdAULc3RhdHNSZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEZc2VsbFJlc291cmNlc0xhbmREZWxpdmVyeQQHYW1vdW50cwltaW5QcmljZXMLbGFuZEFzc2V0SWQQZmFjdG9yeUNvbnRpbmVudAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAAACBQxwcm9sb2dSZXN1bHQFDHByb2xvZ1Jlc3VsdAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECKnNlbGxSZXNvdXJjZXMgZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50cwQEdXNlcggFAWkGY2FsbGVyBARhZGRyCQClCAEFBHVzZXIEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkxBTkRQUkVGSVgCDSBpcyBub3QgeW91cnMEAndoCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIUZ2V0V2FyZWhvdXNlUkVBRE9OTFkJAMwIAgULbGFuZEFzc2V0SWQFA25pbAUDbmlsBAljdXJyZW50V2gJALwJAgUCd2gCAToEB3Jlc0xpc3QJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfBA0kdDAzMzE4NDMzMzA1CQETc2VsbFJlc291cmNlc0NvbW1vbgQFB3Jlc0xpc3QFEGZhY3RvcnlDb250aW5lbnQFB2Ftb3VudHMFCW1pblByaWNlcwQOZmFjdG9yeUFjdGlvbnMIBQ0kdDAzMzE4NDMzMzA1Al8xBAZuZXdSZXMIBQ0kdDAzMzE4NDMzMzA1Al8yBAx1c2R0UmVjZWl2ZWQIBQ0kdDAzMzE4NDMzMzA1Al8zBAh0b3RhbFJlcwgFDSR0MDMzMTg0MzMzMDUCXzQEBXdoU3RyCQC6CQIJAMwIAgkAkQMCBQljdXJyZW50V2gFC3doSWR4TGV2ZWxzCQDMCAIJALkJAgUGbmV3UmVzAgFfCQDMCAIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAkAzAgCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kCQDMCAIJAJEDAgUJY3VycmVudFdoBQl3aElkeExPRlQFA25pbAIBOgQGd2hTYXZlCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAINc2F2ZVdhcmVob3VzZQkAzAgCBQV3aFN0cgkAzAgCBQtsYW5kQXNzZXRJZAUDbmlsBQNuaWwEC3N0YXRzUmVzdWx0CQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQWNjU3RhdHMJAMwIAgUEYWRkcgkAzAgCCQBrAwUHeHBUcmFkZQUIdG90YWxSZXMFBU1VTFQ4BQNuaWwFA25pbAQHZmVlUGFydAkAawMFDHVzZHRSZWNlaXZlZAUMREVMSVZFUllfRkVFBQVNVUxUNgQDZmVlCQCWAwEJAMwIAgUHZmVlUGFydAkAzAgCBRVNSU5fVVNEVF9GRUVfREVMSVZFUlkFA25pbAQQYWN0aXZpdGllc0Ftb3VudAkAaQIFDHVzZHRSZWNlaXZlZABkAwkAZwIFA2ZlZQkAZQIFDHVzZHRSZWNlaXZlZAUQYWN0aXZpdGllc0Ftb3VudAkAAgEJAKwCAgIrVGhpcyB0cmFkZSBkb2VzIG5vdCBjb3ZlciBkZWxpdmVyeSBjb3N0IG9mIAkBCmZpeGVkUG9pbnQCBQNmZWUABgQJZnVuZFRvdGFsCQELdmFsdWVPckVsc2UCCQCfCAEFD2RlbGl2ZXJ5RnVuZEtleQAACQCUCgIJAM0IAgkAzQgCCQDNCAIFDmZhY3RvcnlBY3Rpb25zCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAGUCCQBlAgUMdXNkdFJlY2VpdmVkBRBhY3Rpdml0aWVzQW1vdW50BQNmZWUFC3VzZHRBc3NldElkCQEMSW50ZWdlckVudHJ5AgUPZGVsaXZlcnlGdW5kS2V5CQBkAgUJZnVuZFRvdGFsBQNmZWUJAQ5TY3JpcHRUcmFuc2ZlcgMFDHJlc3RDb250cmFjdAUQYWN0aXZpdGllc0Ftb3VudAULdXNkdEFzc2V0SWQJAJUKAwUGd2hTYXZlBQxwcm9sb2dSZXN1bHQFC3N0YXRzUmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDGJ1eU1hdGVyaWFscwIHYW1vdW50cwltYXhQcmljZXMEDHByb2xvZ1Jlc3VsdAkBBnByb2xvZwADCQAAAgUMcHJvbG9nUmVzdWx0BQxwcm9sb2dSZXN1bHQEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABANhbXQIBQNwbXQGYW1vdW50AwMJAQEhAQkBCWlzRGVmaW5lZAEIBQNwbXQHYXNzZXRJZAYJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhNVU0RUIHBheW1lbnRzIG9ubHkhBAtjdXJMb2NhdGlvbgkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04CAV8DCQECIT0CCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlAgFGCQACAQkArAICAi1EdWNrIGxvY2F0aW9uIHR5cGUgc2hvdWxkIGJlIEZhY3RvcnksIGJ1dCBpcyAJAJEDAgULY3VyTG9jYXRpb24FCmxvY0lkeFR5cGUEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQHbWF0TGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQNJHQwMzUxMjkzNTI1MQkBEmJ1eU1hdGVyaWFsc0NvbW1vbgQFB21hdExpc3QJAJEDAgULY3VyTG9jYXRpb24FCGxvY0lkeElkBQdhbW91bnRzBQltYXhQcmljZXMEDmZhY3RvcnlBY3Rpb25zCAUNJHQwMzUxMjkzNTI1MQJfMQQGbmV3TWF0CAUNJHQwMzUxMjkzNTI1MQJfMgQJdXNkdFNwZW50CAUNJHQwMzUxMjkzNTI1MQJfMwQIdG90YWxNYXQIBQ0kdDAzNTEyOTM1MjUxAl80AwkAZgIFCXVzZHRTcGVudAUDYW10CQACAQkArAICCQCsAgIJAKwCAgIfSW5zdWZmaWNpZW50IHBheW1lbnQhIEF0dGFjaGVkPQkBCmZpeGVkUG9pbnQCBQNhbXQABgILLCByZXF1aXJlZD0JAQpmaXhlZFBvaW50AgUJdXNkdFNwZW50AAYEB25ld1BhY2sJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQDMCAIJALkJAgUGbmV3TWF0AgFfCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6BA5iYWNrcGFja1Jlc3VsdAkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCDnVwZGF0ZUJhY2twYWNrCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIFB25ld1BhY2sFA25pbAUDbmlsBARyZXN0AwkAZgIJAGUCBQNhbXQFCXVzZHRTcGVudAAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgkAZQIFA2FtdAUJdXNkdFNwZW50BQt1c2R0QXNzZXRJZAUDbmlsBQNuaWwEEGFjdGl2aXRpZXNBbW91bnQJAGkCBQl1c2R0U3BlbnQAZAQLc3RhdHNSZXN1bHQJAQVhc0ludAEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag91cGRhdGVEdWNrU3RhdHMJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgkAawMFB3hwVHJhZGUFCHRvdGFsTWF0BQVNVUxUOAUDbmlsBQNuaWwJAJQKAgkAzQgCCQDOCAIFDmZhY3RvcnlBY3Rpb25zBQRyZXN0CQEOU2NyaXB0VHJhbnNmZXIDBQxyZXN0Q29udHJhY3QFEGFjdGl2aXRpZXNBbW91bnQFC3VzZHRBc3NldElkCQCVCgMFDmJhY2twYWNrUmVzdWx0BQxwcm9sb2dSZXN1bHQFC3N0YXRzUmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBGGJ1eU1hdGVyaWFsc0R1Y2tEZWxpdmVyeQMHYW1vdW50cwltYXhQcmljZXMQZmFjdG9yeUNvbnRpbmVudAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAAACBQxwcm9sb2dSZXN1bHQFDHByb2xvZ1Jlc3VsdAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEA2FtdAgFA3BtdAZhbW91bnQDAwkBASEBCQEJaXNEZWZpbmVkAQgFA3BtdAdhc3NldElkBgkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkBQt1c2R0QXNzZXRJZAkAAgECE1VTRFQgcGF5bWVudHMgb25seSEEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQHbWF0TGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQNJHQwMzY2OTUzNjgxMgkBEmJ1eU1hdGVyaWFsc0NvbW1vbgQFB21hdExpc3QFEGZhY3RvcnlDb250aW5lbnQFB2Ftb3VudHMFCW1heFByaWNlcwQOZmFjdG9yeUFjdGlvbnMIBQ0kdDAzNjY5NTM2ODEyAl8xBAZuZXdNYXQIBQ0kdDAzNjY5NTM2ODEyAl8yBAl1c2R0U3BlbnQIBQ0kdDAzNjY5NTM2ODEyAl8zBAh0b3RhbE1hdAgFDSR0MDM2Njk1MzY4MTICXzQEB25ld1BhY2sJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQDMCAIJALkJAgUGbmV3TWF0AgFfCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6BA5iYWNrcGFja1Jlc3VsdAkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCDnVwZGF0ZUJhY2twYWNrCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIFB25ld1BhY2sFA25pbAUDbmlsBAtzdGF0c1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCD3VwZGF0ZUR1Y2tTdGF0cwkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCCQBrAwUHeHBUcmFkZQUIdG90YWxNYXQFBU1VTFQ4BQNuaWwFA25pbAQHZmVlUGFydAkAawMFCXVzZHRTcGVudAUMREVMSVZFUllfRkVFBQVNVUxUNgQDZmVlCQCWAwEJAMwIAgUHZmVlUGFydAkAzAgCBRVNSU5fVVNEVF9GRUVfREVMSVZFUlkFA25pbAQQdXNkdFNwZW50V2l0aEZlZQkAZAIFCXVzZHRTcGVudAUDZmVlAwkAZgIFEHVzZHRTcGVudFdpdGhGZWUFA2FtdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICH0luc3VmZmljaWVudCBwYXltZW50ISBBdHRhY2hlZD0JAQpmaXhlZFBvaW50AgUDYW10AAYCCywgcmVxdWlyZWQ9CQEKZml4ZWRQb2ludAIFCXVzZHRTcGVudAAGAgErCQEKZml4ZWRQb2ludAIFA2ZlZQAGAg4oZGVsaXZlcnkgZmVlKQQEcmVzdAMJAGYCCQBlAgUDYW10BRB1c2R0U3BlbnRXaXRoRmVlAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQBlAgUDYW10BRB1c2R0U3BlbnRXaXRoRmVlBQt1c2R0QXNzZXRJZAUDbmlsBQNuaWwEEGFjdGl2aXRpZXNBbW91bnQJAGkCBQl1c2R0U3BlbnQAZAQJZnVuZFRvdGFsCQELdmFsdWVPckVsc2UCCQCfCAEFD2RlbGl2ZXJ5RnVuZEtleQAACQCUCgIJAM0IAgkAzQgCCQDOCAIFDmZhY3RvcnlBY3Rpb25zBQRyZXN0CQEOU2NyaXB0VHJhbnNmZXIDBQxyZXN0Q29udHJhY3QFEGFjdGl2aXRpZXNBbW91bnQFC3VzZHRBc3NldElkCQEMSW50ZWdlckVudHJ5AgUPZGVsaXZlcnlGdW5kS2V5CQBkAgUJZnVuZFRvdGFsBQNmZWUJAJUKAwUOYmFja3BhY2tSZXN1bHQFDHByb2xvZ1Jlc3VsdAULc3RhdHNSZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEYYnV5TWF0ZXJpYWxzTGFuZERlbGl2ZXJ5BAdhbW91bnRzCW1heFByaWNlcwtsYW5kQXNzZXRJZBBmYWN0b3J5Q29udGluZW50BAxwcm9sb2dSZXN1bHQJAQZwcm9sb2cAAwkAAAIFDHByb2xvZ1Jlc3VsdAUMcHJvbG9nUmVzdWx0AwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEA2FtdAgFA3BtdAZhbW91bnQDAwkBASEBCQEJaXNEZWZpbmVkAQgFA3BtdAdhc3NldElkBgkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkBQt1c2R0QXNzZXRJZAkAAgECE1VTRFQgcGF5bWVudHMgb25seSEEBHVzZXIIBQFpBmNhbGxlcgQEYWRkcgkApQgBBQR1c2VyBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAmggCBQ9zdGFraW5nQ29udHJhY3QJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQJAAIBCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAJ3aAkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCFGdldFdhcmVob3VzZVJFQURPTkxZCQDMCAIFC2xhbmRBc3NldElkBQNuaWwFA25pbAQJY3VycmVudFdoCQC8CQIFAndoAgE6BAdtYXRMaXN0CQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAIBXwQNJHQwMzg5NzczOTA5NAkBEmJ1eU1hdGVyaWFsc0NvbW1vbgQFB21hdExpc3QFEGZhY3RvcnlDb250aW5lbnQFB2Ftb3VudHMFCW1heFByaWNlcwQOZmFjdG9yeUFjdGlvbnMIBQ0kdDAzODk3NzM5MDk0Al8xBAZuZXdNYXQIBQ0kdDAzODk3NzM5MDk0Al8yBAl1c2R0U3BlbnQIBQ0kdDAzODk3NzM5MDk0Al8zBAh0b3RhbE1hdAgFDSR0MDM4OTc3MzkwOTQCXzQEBXdoU3RyCQC6CQIJAMwIAgkAkQMCBQljdXJyZW50V2gFC3doSWR4TGV2ZWxzCQDMCAIJAJEDAgUJY3VycmVudFdoBQh3aElkeFJlcwkAzAgCCQC5CQIFBm5ld01hdAIBXwkAzAgCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kCQDMCAIJAJEDAgUJY3VycmVudFdoBQl3aElkeExPRlQFA25pbAIBOgQGd2hTYXZlCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAINc2F2ZVdhcmVob3VzZQkAzAgCBQV3aFN0cgkAzAgCBQtsYW5kQXNzZXRJZAUDbmlsBQNuaWwEC3N0YXRzUmVzdWx0CQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQWNjU3RhdHMJAMwIAgUEYWRkcgkAzAgCCQBrAwUHeHBUcmFkZQUIdG90YWxNYXQFBU1VTFQ4BQNuaWwFA25pbAQHZmVlUGFydAkAawMFCXVzZHRTcGVudAUMREVMSVZFUllfRkVFBQVNVUxUNgQDZmVlCQCWAwEJAMwIAgUHZmVlUGFydAkAzAgCBRVNSU5fVVNEVF9GRUVfREVMSVZFUlkFA25pbAQQdXNkdFNwZW50V2l0aEZlZQkAZAIFCXVzZHRTcGVudAUDZmVlAwkAZgIFEHVzZHRTcGVudFdpdGhGZWUFA2FtdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICH0luc3VmZmljaWVudCBwYXltZW50ISBBdHRhY2hlZD0JAQpmaXhlZFBvaW50AgUDYW10AAYCCywgcmVxdWlyZWQ9CQEKZml4ZWRQb2ludAIFCXVzZHRTcGVudAAGAgErCQEKZml4ZWRQb2ludAIFA2ZlZQAGAg4oZGVsaXZlcnkgZmVlKQQEcmVzdAMJAGYCCQBlAgUDYW10BRB1c2R0U3BlbnRXaXRoRmVlAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQBlAgUDYW10BRB1c2R0U3BlbnRXaXRoRmVlBQt1c2R0QXNzZXRJZAUDbmlsBQNuaWwEEGFjdGl2aXRpZXNBbW91bnQJAGkCBQl1c2R0U3BlbnQAZAQJZnVuZFRvdGFsCQELdmFsdWVPckVsc2UCCQCfCAEFD2RlbGl2ZXJ5RnVuZEtleQAACQCUCgIJAM0IAgkAzQgCCQDOCAIFDmZhY3RvcnlBY3Rpb25zBQRyZXN0CQEOU2NyaXB0VHJhbnNmZXIDBQxyZXN0Q29udHJhY3QFEGFjdGl2aXRpZXNBbW91bnQFC3VzZHRBc3NldElkCQEMSW50ZWdlckVudHJ5AgUPZGVsaXZlcnlGdW5kS2V5CQBkAgUJZnVuZFRvdGFsBQNmZWUJAJUKAwUGd2hTYXZlBQxwcm9sb2dSZXN1bHQFC3N0YXRzUmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEWV4Y2hhbmdlUmVzb3VyY2VzAQdhbW91bnRzBAxwcm9sb2dSZXN1bHQJAQZwcm9sb2cAAwkAAAIFDHByb2xvZ1Jlc3VsdAUMcHJvbG9nUmVzdWx0BAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQDYW10CAUDcG10BmFtb3VudAMDCQEBIQEJAQlpc0RlZmluZWQBCAUDcG10B2Fzc2V0SWQGCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQITVVNEVCBwYXltZW50cyBvbmx5IQQLY3VyTG9jYXRpb24JALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OAgFfAwkBAiE9AgkAkQMCBQtjdXJMb2NhdGlvbgUKbG9jSWR4VHlwZQIBRgkAAgEJAKwCAgItRHVjayBsb2NhdGlvbiB0eXBlIHNob3VsZCBiZSBGYWN0b3J5LCBidXQgaXMgCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEB3Jlc0xpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMCAV8EB21hdExpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8EDSR0MDQxMTcyNDEyNzgJARdleGNoYW5nZVJlc291cmNlc0NvbW1vbgMFB3Jlc0xpc3QFB21hdExpc3QFB2Ftb3VudHMEBm5ld1JlcwgFDSR0MDQxMTcyNDEyNzgCXzEEBm5ld01hdAgFDSR0MDQxMTcyNDEyNzgCXzIECXVzZHRTcGVudAgFDSR0MDQxMTcyNDEyNzgCXzMEFHRvdGFsQW1vdW50Q29udmVydGVkCAUNJHQwNDExNzI0MTI3OAJfNAMJAGYCBQl1c2R0U3BlbnQFA2FtdAkAAgEJAKwCAgkArAICCQCsAgICH0luc3VmZmljaWVudCBwYXltZW50ISBBdHRhY2hlZD0JAQpmaXhlZFBvaW50AgUDYW10AAYCCywgcmVxdWlyZWQ9CQEKZml4ZWRQb2ludAIFCXVzZHRTcGVudAAGBAduZXdQYWNrCQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQC5CQIFBm5ld1JlcwIBXwkAzAgCCQC5CQIFBm5ld01hdAIBXwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgQOYmFja3BhY2tSZXN1bHQJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag51cGRhdGVCYWNrcGFjawkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCBQduZXdQYWNrBQNuaWwFA25pbAQEcmVzdAMJAGYCCQBlAgUDYW10BQl1c2R0U3BlbnQAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAGUCBQNhbXQFCXVzZHRTcGVudAULdXNkdEFzc2V0SWQFA25pbAUDbmlsBBBhY3Rpdml0aWVzQW1vdW50CQBpAgUJdXNkdFNwZW50AGQEC3N0YXRzUmVzdWx0CQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIPdXBkYXRlRHVja1N0YXRzCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIJAGsDBQd4cFRyYWRlBRR0b3RhbEFtb3VudENvbnZlcnRlZAUFTVVMVDgFA25pbAUDbmlsCQCUCgIJAM0IAgUEcmVzdAkBDlNjcmlwdFRyYW5zZmVyAwUMcmVzdENvbnRyYWN0BRBhY3Rpdml0aWVzQW1vdW50BQt1c2R0QXNzZXRJZAkAlQoDBQ5iYWNrcGFja1Jlc3VsdAUMcHJvbG9nUmVzdWx0BQtzdGF0c1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAR1leGNoYW5nZVJlc291cmNlc0R1Y2tEZWxpdmVyeQEHYW1vdW50cwQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAAACBQxwcm9sb2dSZXN1bHQFDHByb2xvZ1Jlc3VsdAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEA2FtdAgFA3BtdAZhbW91bnQDAwkBASEBCQEJaXNEZWZpbmVkAQgFA3BtdAdhc3NldElkBgkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkBQt1c2R0QXNzZXRJZAkAAgECE1VTRFQgcGF5bWVudHMgb25seSEEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQHcmVzTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwQHbWF0TGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQNJHQwNDI3MTY0MjgyMgkBF2V4Y2hhbmdlUmVzb3VyY2VzQ29tbW9uAwUHcmVzTGlzdAUHbWF0TGlzdAUHYW1vdW50cwQGbmV3UmVzCAUNJHQwNDI3MTY0MjgyMgJfMQQGbmV3TWF0CAUNJHQwNDI3MTY0MjgyMgJfMgQJdXNkdFNwZW50CAUNJHQwNDI3MTY0MjgyMgJfMwQUdG90YWxBbW91bnRDb252ZXJ0ZWQIBQ0kdDA0MjcxNjQyODIyAl80BAdmZWVQYXJ0CQBrAwUJdXNkdFNwZW50BQ5ERUxJVkVSWV9GRUUxNQUFTVVMVDYEA2ZlZQkAlgMBCQDMCAIFB2ZlZVBhcnQJAMwIAgUXTUlOX1VTRFRfRkVFX0RFTElWRVJZMTUFA25pbAQQdXNkdFNwZW50V2l0aEZlZQkAZAIFCXVzZHRTcGVudAUDZmVlAwkAZgIFEHVzZHRTcGVudFdpdGhGZWUFA2FtdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICH0luc3VmZmljaWVudCBwYXltZW50ISBBdHRhY2hlZD0JAQpmaXhlZFBvaW50AgUDYW10AAYCCywgcmVxdWlyZWQ9CQEKZml4ZWRQb2ludAIFCXVzZHRTcGVudAAGAgErCQEKZml4ZWRQb2ludAIFA2ZlZQAGAg4oZGVsaXZlcnkgZmVlKQQHbmV3UGFjawkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAuQkCBQZuZXdSZXMCAV8JAMwIAgkAuQkCBQZuZXdNYXQCAV8JAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwCAToEDmJhY2twYWNrUmVzdWx0CQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQmFja3BhY2sJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUHbmV3UGFjawUDbmlsBQNuaWwEBHJlc3QDCQBmAgkAZQIFA2FtdAUQdXNkdFNwZW50V2l0aEZlZQAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgkAZQIFA2FtdAUQdXNkdFNwZW50V2l0aEZlZQULdXNkdEFzc2V0SWQFA25pbAUDbmlsBBBhY3Rpdml0aWVzQW1vdW50CQBpAgUJdXNkdFNwZW50AGQEC3N0YXRzUmVzdWx0CQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIPdXBkYXRlRHVja1N0YXRzCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIJAGsDBQd4cFRyYWRlBRR0b3RhbEFtb3VudENvbnZlcnRlZAUFTVVMVDgFA25pbAUDbmlsBAlmdW5kVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUPZGVsaXZlcnlGdW5kS2V5AAAJAJQKAgkAzQgCCQDNCAIFBHJlc3QJAQ5TY3JpcHRUcmFuc2ZlcgMFDHJlc3RDb250cmFjdAUQYWN0aXZpdGllc0Ftb3VudAULdXNkdEFzc2V0SWQJAQxJbnRlZ2VyRW50cnkCBQ9kZWxpdmVyeUZ1bmRLZXkJAGQCBQlmdW5kVG90YWwFA2ZlZQkAlQoDBQ5iYWNrcGFja1Jlc3VsdAUMcHJvbG9nUmVzdWx0BQtzdGF0c1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAR1leGNoYW5nZVJlc291cmNlc0xhbmREZWxpdmVyeQIHYW1vdW50cwtsYW5kQXNzZXRJZAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAAACBQxwcm9sb2dSZXN1bHQFDHByb2xvZ1Jlc3VsdAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABANhbXQIBQNwbXQGYW1vdW50AwMJAQEhAQkBCWlzRGVmaW5lZAEIBQNwbXQHYXNzZXRJZAYJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhNVU0RUIHBheW1lbnRzIG9ubHkhBAR1c2VyCAUBaQZjYWxsZXIEBGFkZHIJAKUIAQUEdXNlcgQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEJAJoIAgUPc3Rha2luZ0NvbnRyYWN0CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQCd2gJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0AhRnZXRXYXJlaG91c2VSRUFET05MWQkAzAgCBQtsYW5kQXNzZXRJZAUDbmlsBQNuaWwECWN1cnJlbnRXaAkAvAkCBQJ3aAIBOgQHcmVzTGlzdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8EB21hdExpc3QJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4TWF0AgFfBA0kdDA0NTAwNzQ1MTEzCQEXZXhjaGFuZ2VSZXNvdXJjZXNDb21tb24DBQdyZXNMaXN0BQdtYXRMaXN0BQdhbW91bnRzBAZuZXdSZXMIBQ0kdDA0NTAwNzQ1MTEzAl8xBAZuZXdNYXQIBQ0kdDA0NTAwNzQ1MTEzAl8yBAl1c2R0U3BlbnQIBQ0kdDA0NTAwNzQ1MTEzAl8zBBR0b3RhbEFtb3VudENvbnZlcnRlZAgFDSR0MDQ1MDA3NDUxMTMCXzQEBXdoU3RyCQC6CQIJAMwIAgkAkQMCBQljdXJyZW50V2gFC3doSWR4TGV2ZWxzCQDMCAIJALkJAgUGbmV3UmVzAgFfCQDMCAIJALkJAgUGbmV3TWF0AgFfCQDMCAIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QJAMwIAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4TE9GVAUDbmlsAgE6BAZ3aFNhdmUJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag1zYXZlV2FyZWhvdXNlCQDMCAIFBXdoU3RyCQDMCAIFC2xhbmRBc3NldElkBQNuaWwFA25pbAQLc3RhdHNSZXN1bHQJAQVhc0ludAEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag51cGRhdGVBY2NTdGF0cwkAzAgCBQRhZGRyCQDMCAIJAGsDBQd4cFRyYWRlBRR0b3RhbEFtb3VudENvbnZlcnRlZAUFTVVMVDgFA25pbAUDbmlsBAdmZWVQYXJ0CQBrAwUJdXNkdFNwZW50BQ5ERUxJVkVSWV9GRUUxNQUFTVVMVDYEA2ZlZQkAlgMBCQDMCAIFB2ZlZVBhcnQJAMwIAgUXTUlOX1VTRFRfRkVFX0RFTElWRVJZMTUFA25pbAQQdXNkdFNwZW50V2l0aEZlZQkAZAIFCXVzZHRTcGVudAUDZmVlAwkAZgIFEHVzZHRTcGVudFdpdGhGZWUFA2FtdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICH0luc3VmZmljaWVudCBwYXltZW50ISBBdHRhY2hlZD0JAQpmaXhlZFBvaW50AgUDYW10AAYCCywgcmVxdWlyZWQ9CQEKZml4ZWRQb2ludAIFCXVzZHRTcGVudAAGAgErCQEKZml4ZWRQb2ludAIFA2ZlZQAGAg4oZGVsaXZlcnkgZmVlKQQEcmVzdAMJAGYCCQBlAgUDYW10BRB1c2R0U3BlbnRXaXRoRmVlAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQBlAgUDYW10BRB1c2R0U3BlbnRXaXRoRmVlBQt1c2R0QXNzZXRJZAUDbmlsBQNuaWwEEGFjdGl2aXRpZXNBbW91bnQJAGkCBQl1c2R0U3BlbnQAZAQJZnVuZFRvdGFsCQELdmFsdWVPckVsc2UCCQCfCAEFD2RlbGl2ZXJ5RnVuZEtleQAACQCUCgIJAM0IAgkAzQgCBQRyZXN0CQEOU2NyaXB0VHJhbnNmZXIDBQxyZXN0Q29udHJhY3QFEGFjdGl2aXRpZXNBbW91bnQFC3VzZHRBc3NldElkCQEMSW50ZWdlckVudHJ5AgUPZGVsaXZlcnlGdW5kS2V5CQBkAgUJZnVuZFRvdGFsBQNmZWUJAJUKAwUGd2hTYXZlBQxwcm9sb2dSZXN1bHQFC3N0YXRzUmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCmNyYWZ0R29vZHMCCnByb2R1Y3RJZHgIcXVhbnRpdHkEDHByb2xvZ1Jlc3VsdAkBBnByb2xvZwADCQAAAgUMcHJvbG9nUmVzdWx0BQxwcm9sb2dSZXN1bHQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQDYW10CAUDcG10BmFtb3VudAMDCQEBIQEJAQlpc0RlZmluZWQBCAUDcG10B2Fzc2V0SWQGCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQITVVNEVCBwYXltZW50cyBvbmx5IQMJAQIhPQIFA2FtdAUFTVVMVDYJAAIBCQCsAgIJAKwCAgIIZXhhY3RseSAJAQpmaXhlZFBvaW50AgUPQ1JBRlRfVVNEVF9DT1NUAAYCISBVU0RUIG11c3QgYmUgYXR0YWNoZWQgYXMgcGF5bWVudAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04CAV8DCQECIT0CCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlAgFNCQACAQkArAICAjFEdWNrIGxvY2F0aW9uIHR5cGUgc2hvdWxkIGJlIE1hbnVmYWN0b3J5LCBidXQgaXMgCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlBARjb250CQCRAwIFC2N1ckxvY2F0aW9uBQ9sb2NJZHhDb250aW5lbnQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQHbWF0TGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQIcHJvZExpc3QDCQAAAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgAFA25pbAkAvAkCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAV8EDSR0MDQ3NDM4NDc1MzUJARBjcmFmdEdvb2RzQ29tbW9uBQUHbWF0TGlzdAUIcHJvZExpc3QFBGNvbnQFCnByb2R1Y3RJZHgFCHF1YW50aXR5BAZuZXdNYXQIBQ0kdDA0NzQzODQ3NTM1Al8xBAduZXdQcm9kCAUNJHQwNDc0Mzg0NzUzNQJfMgQIbWF0U3BlbnQIBQ0kdDA0NzQzODQ3NTM1Al8zBAduZXdQYWNrCQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwkAzAgCCQC5CQIFBm5ld01hdAIBXwkAzAgCCQC6CQIFB25ld1Byb2QCAV8FA25pbAIBOgQGcmVzdWx0CQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQmFja3BhY2sJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUHbmV3UGFjawUDbmlsBQNuaWwEC3N0YXRzUmVzdWx0CQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIPdXBkYXRlRHVja1N0YXRzCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIJAGsDBQd4cENyYWZ0BQhtYXRTcGVudAUFTVVMVDgFA25pbAUDbmlsCQCUCgIFA25pbAkAlQoDBQZyZXN1bHQFDHByb2xvZ1Jlc3VsdAULc3RhdHNSZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEWY3JhZnRHb29kc0R1Y2tEZWxpdmVyeQMKcHJvZHVjdElkeAhxdWFudGl0eRRtYW51ZmFjdG9yeUNvbnRpbmVudAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAAACBQxwcm9sb2dSZXN1bHQFDHByb2xvZ1Jlc3VsdAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEA2FtdAgFA3BtdAZhbW91bnQDAwkBASEBCQEJaXNEZWZpbmVkAQgFA3BtdAdhc3NldElkBgkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkBQt1c2R0QXNzZXRJZAkAAgECE1VTRFQgcGF5bWVudHMgb25seSEEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQHbWF0TGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQIcHJvZExpc3QDCQAAAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgAFA25pbAkAvAkCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAV8EDSR0MDQ4NjgzNDg3OTYJARBjcmFmdEdvb2RzQ29tbW9uBQUHbWF0TGlzdAUIcHJvZExpc3QFFG1hbnVmYWN0b3J5Q29udGluZW50BQpwcm9kdWN0SWR4BQhxdWFudGl0eQQGbmV3TWF0CAUNJHQwNDg2ODM0ODc5NgJfMQQHbmV3UHJvZAgFDSR0MDQ4NjgzNDg3OTYCXzIECG1hdFNwZW50CAUNJHQwNDg2ODM0ODc5NgJfMwQHbmV3UGFjawkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMJAMwIAgkAuQkCBQZuZXdNYXQCAV8JAMwIAgkAugkCBQduZXdQcm9kAgFfBQNuaWwCAToEDmJhY2twYWNrUmVzdWx0CQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQmFja3BhY2sJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUHbmV3UGFjawUDbmlsBQNuaWwEC3N0YXRzUmVzdWx0CQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIPdXBkYXRlRHVja1N0YXRzCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIJAGsDBQd4cENyYWZ0BQhtYXRTcGVudAUFTVVMVDgFA25pbAUDbmlsBAdmZWVQYXJ0CQBrAwUIcXVhbnRpdHkFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQUUQ1JBRlRfREVMSVZFUllfQ09FRkYEA2ZlZQkAlgMBCQDMCAIFB2ZlZVBhcnQJAMwIAgUVTUlOX1VTRFRfRkVFX0RFTElWRVJZBQNuaWwEEHVzZHRTcGVudFdpdGhGZWUJAGQCBQ9DUkFGVF9VU0RUX0NPU1QFA2ZlZQMJAGYCBRB1c2R0U3BlbnRXaXRoRmVlBQNhbXQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAh9JbnN1ZmZpY2llbnQgcGF5bWVudCEgQXR0YWNoZWQ9CQEKZml4ZWRQb2ludAIFA2FtdAAGAgssIHJlcXVpcmVkPQkBCmZpeGVkUG9pbnQCBQ9DUkFGVF9VU0RUX0NPU1QABgIBKwkBCmZpeGVkUG9pbnQCBQNmZWUABgIOKGRlbGl2ZXJ5IGZlZSkEBHJlc3QDCQBmAgkAZQIFA2FtdAUQdXNkdFNwZW50V2l0aEZlZQAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgkAZQIFA2FtdAUQdXNkdFNwZW50V2l0aEZlZQULdXNkdEFzc2V0SWQFA25pbAUDbmlsBAlmdW5kVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUPZGVsaXZlcnlGdW5kS2V5AAAJAJQKAgkAzQgCBQRyZXN0CQEMSW50ZWdlckVudHJ5AgUPZGVsaXZlcnlGdW5kS2V5CQBkAgUJZnVuZFRvdGFsBQNmZWUJAJUKAwUOYmFja3BhY2tSZXN1bHQFDHByb2xvZ1Jlc3VsdAULc3RhdHNSZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEWY3JhZnRHb29kc0xhbmREZWxpdmVyeQQKcHJvZHVjdElkeAhxdWFudGl0eQtsYW5kQXNzZXRJZBRtYW51ZmFjdG9yeUNvbnRpbmVudAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAAACBQxwcm9sb2dSZXN1bHQFDHByb2xvZ1Jlc3VsdAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABANhbXQIBQNwbXQGYW1vdW50AwMJAQEhAQkBCWlzRGVmaW5lZAEIBQNwbXQHYXNzZXRJZAYJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhNVU0RUIHBheW1lbnRzIG9ubHkhBAR1c2VyCAUBaQZjYWxsZXIEBGFkZHIJAKUIAQUEdXNlcgQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEJAJoIAgUPc3Rha2luZ0NvbnRyYWN0CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQCd2gJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0AhRnZXRXYXJlaG91c2VSRUFET05MWQkAzAgCBQtsYW5kQXNzZXRJZAUDbmlsBQNuaWwECWN1cnJlbnRXaAkAvAkCBQJ3aAIBOgQHbWF0TGlzdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhNYXQCAV8ECHByb2RMaXN0AwkAAAIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAV8EDSR0MDUwOTYyNTEwNzUJARBjcmFmdEdvb2RzQ29tbW9uBQUHbWF0TGlzdAUIcHJvZExpc3QFFG1hbnVmYWN0b3J5Q29udGluZW50BQpwcm9kdWN0SWR4BQhxdWFudGl0eQQGbmV3TWF0CAUNJHQwNTA5NjI1MTA3NQJfMQQHbmV3UHJvZAgFDSR0MDUwOTYyNTEwNzUCXzIECG1hdFNwZW50CAUNJHQwNTA5NjI1MTA3NQJfMwQFd2hTdHIJALoJAgkAzAgCCQCRAwIFCWN1cnJlbnRXaAULd2hJZHhMZXZlbHMJAMwIAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzCQDMCAIJALkJAgUGbmV3TWF0AgFfCQDMCAIJALoJAgUHbmV3UHJvZAIBXwkAzAgCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhMT0ZUBQNuaWwCAToEBndoU2F2ZQkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCDXNhdmVXYXJlaG91c2UJAMwIAgUFd2hTdHIJAMwIAgULbGFuZEFzc2V0SWQFA25pbAUDbmlsBAtzdGF0c1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCDnVwZGF0ZUFjY1N0YXRzCQDMCAIFBGFkZHIJAMwIAgkAawMFB3hwQ3JhZnQFCG1hdFNwZW50BQVNVUxUOAUDbmlsBQNuaWwEB2ZlZVBhcnQJAGsDBQhxdWFudGl0eQUVTUlOX1VTRFRfRkVFX0RFTElWRVJZBRRDUkFGVF9ERUxJVkVSWV9DT0VGRgQDZmVlCQCWAwEJAMwIAgUHZmVlUGFydAkAzAgCBRVNSU5fVVNEVF9GRUVfREVMSVZFUlkFA25pbAQQdXNkdFNwZW50V2l0aEZlZQkAZAIFD0NSQUZUX1VTRFRfQ09TVAUDZmVlAwkAZgIFEHVzZHRTcGVudFdpdGhGZWUFA2FtdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICH0luc3VmZmljaWVudCBwYXltZW50ISBBdHRhY2hlZD0JAQpmaXhlZFBvaW50AgUDYW10AAYCCywgcmVxdWlyZWQ9CQEKZml4ZWRQb2ludAIFD0NSQUZUX1VTRFRfQ09TVAAGAgErCQEKZml4ZWRQb2ludAIFA2ZlZQAGAg4oZGVsaXZlcnkgZmVlKQQEcmVzdAMJAGYCCQBlAgUDYW10BRB1c2R0U3BlbnRXaXRoRmVlAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQBlAgUDYW10BRB1c2R0U3BlbnRXaXRoRmVlBQt1c2R0QXNzZXRJZAUDbmlsBQNuaWwECWZ1bmRUb3RhbAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ9kZWxpdmVyeUZ1bmRLZXkAAAkAlAoCCQDNCAIFBHJlc3QJAQxJbnRlZ2VyRW50cnkCBQ9kZWxpdmVyeUZ1bmRLZXkJAGQCBQlmdW5kVG90YWwFA2ZlZQkAlQoDBQZ3aFNhdmUFDHByb2xvZ1Jlc3VsdAULc3RhdHNSZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQERc2V0V2FyZWhvdXNlT3JkZXICC25ld09yZGVyU3RyC2xhbmRBc3NldElkBAR1c2VyCAUBaQxvcmlnaW5DYWxsZXIEBGFkZHIJAKUIAQUEdXNlcgQGcmVzdWx0AwkBAiE9AgUEdXNlcgUMcmVzdENvbnRyYWN0CQEMY2hlY2tCbG9ja2VkAAcEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwMJAQIhPQIFBHVzZXIFDHJlc3RDb250cmFjdAkBAiE9AgUFb3duZXIFBGFkZHIHCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAhuZXdPcmRlcgkAvAkCBQtuZXdPcmRlclN0cgIBOgQCd2gJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0AhRnZXRXYXJlaG91c2VSRUFET05MWQkAzAgCBQtsYW5kQXNzZXRJZAUDbmlsBQNuaWwECWN1cnJlbnRXaAkAvAkCBQJ3aAIBOgQEbG9mdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhMT0ZUAgFfBAd3aFRvdGFsCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAUIdm9sVG90YWwEBm9yZEtleQkBDmtleU9yZGVyQnlMYW5kAQULbGFuZEFzc2V0SWQECmN1cnJlbnRPcmQJAQhnZXRPcmRlcgEFBm9yZEtleQQBegkBC3NldEludGVybmFsAwUJY3VycmVudFdoBQpjdXJyZW50T3JkBQhuZXdPcmRlcgQLYnV5Vm9sU2FsZG8IBQF6Al80BAxzZWxsVm9sU2FsZG8IBQF6Al81BAp3aE9jY3VwaWVkCAUBegJfNwQId2hMb2NrZWQJAGQCBQtidXlWb2xTYWxkbwUMc2VsbFZvbFNhbGRvBAZ3aEZyZWUJAGUCCQBlAgUHd2hUb3RhbAUKd2hPY2N1cGllZAUId2hMb2NrZWQDCQBmAgAABQZ3aEZyZWUJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhNBdHRlbXB0IHRvIHJlc2VydmUgCQCkAwEFC2J1eVZvbFNhbGRvAhsgc3BhY2UgZm9yIGJ1eSBvcmRlcnMsIGFuZCAJAKQDAQUMc2VsbFZvbFNhbGRvAiUgc3BhY2UgZm9yIHNlbGwgb3JkZXJzIChhbmQgb2NjdXBpZWQ9CQCkAwEFCndoT2NjdXBpZWQCHyksIGxlYWRzIHRvIG5lZ2F0aXZlIGZyZWUgc3BhY2UEBXdoU3RyCQC6CQIJAMwIAgkAkQMCBQljdXJyZW50V2gFC3doSWR4TGV2ZWxzCQDMCAIJALkJAggFAXoCXzECAV8JAMwIAgkAuQkCCAUBegJfMgIBXwkAzAgCCQC6CQIIBQF6Al8zAgFfCQDMCAIJAKQDAQUId2hMb2NrZWQFA25pbAIBOgQGd2hTYXZlCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAINc2F2ZVdhcmVob3VzZQkAzAgCBQV3aFN0cgkAzAgCBQtsYW5kQXNzZXRJZAUDbmlsBQNuaWwECHVzZFNhbGRvCAUBegJfNgQHYWN0aW9ucwMJAGYCBQh1c2RTYWxkbwAAAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEA2FtdAgFA3BtdAZhbW91bnQECnBtdEFzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAggFA3BtdAdhc3NldElkAh5XQVZFUyBjYW4ndCBiZSB1c2VkIGFzIHBheW1lbnQDCQECIT0CBQpwbXRBc3NldElkBQt1c2R0QXNzZXRJZAkAAgECE1VTRFQgcGF5bWVudHMgb25seSEDCQECIT0CBQNhbXQFCHVzZFNhbGRvCQACAQkArAICAhJQYXltZW50IG5lZWRlZCBpcyAJAKQDAQUIdXNkU2FsZG8JAMwIAgkBC1N0cmluZ0VudHJ5AgUGb3JkS2V5BQtuZXdPcmRlclN0cgUDbmlsAwkAAAIFCHVzZFNhbGRvAAADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhJObyBwYXltZW50cyBuZWVkZWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUGb3JkS2V5BQtuZXdPcmRlclN0cgUDbmlsAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQISTm8gcGF5bWVudHMgbmVlZGVkCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBW93bmVyCQEBLQEFCHVzZFNhbGRvBQt1c2R0QXNzZXRJZAkAzAgCCQELU3RyaW5nRW50cnkCBQZvcmRLZXkFC25ld09yZGVyU3RyBQNuaWwJAJQKAgUHYWN0aW9ucwkAlAoCBQZyZXN1bHQFBndoU2F2ZQFpARRhY2NlcHRXYXJlaG91c2VPcmRlcgMKYnBPcmRlclN0cg9zaG9wTGFuZEFzc2V0SWQLZHVja0Fzc2V0SWQEDHByb2xvZ1Jlc3VsdAkBBnByb2xvZwADCQAAAgUMcHJvbG9nUmVzdWx0BQxwcm9sb2dSZXN1bHQEBmNhbGxlcggFAWkMb3JpZ2luQ2FsbGVyBApjYWxsZXJBZGRyCQClCAEFBmNhbGxlcgQRc3Rha2VkRHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFCmNhbGxlckFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQEC2N1ckxvY2F0aW9uCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBD2tleUR1Y2tMb2NhdGlvbgEFEXN0YWtlZER1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04EA2xvYwkAtQkCCQEFdmFsdWUBBQtjdXJMb2NhdGlvbgIBXwMJAQIhPQIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFMCQACAQkArAICCQCsAgICFkR1Y2sgbG9jYXRpb24gdHlwZSBpcyAJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAhEsIGJ1dCBzaG91bGQgYmUgTAMJAQIhPQIFEXN0YWtlZER1Y2tBc3NldElkBQtkdWNrQXNzZXRJZAkAAgEJAKwCAgkArAICCQCsAgICFFlvdXIgc3Rha2VkIGR1Y2sgaXMgBRFzdGFrZWREdWNrQXNzZXRJZAINLCBidXQgcGFzc2VkIAULZHVja0Fzc2V0SWQEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAlicFJlc0xpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMCAV8ECWJwTWF0TGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQKYnBQcm9kTGlzdAMJAAACCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIBXwQNJHQwNTY5ODg1NzIyOAkBFWFjY2VwdFNob3BPcmRlckNvbW1vbgYFD3Nob3BMYW5kQXNzZXRJZAUKY2FsbGVyQWRkcgUKYnBPcmRlclN0cgUJYnBSZXNMaXN0BQlicE1hdExpc3QFCmJwUHJvZExpc3QECnNob3BBY3Rpb24IBQ0kdDA1Njk4ODU3MjI4Al8xBApuZXdVc2VyUmVzCAUNJHQwNTY5ODg1NzIyOAJfMgQKbmV3VXNlck1hdAgFDSR0MDU2OTg4NTcyMjgCXzMEC25ld1VzZXJQcm9kCAUNJHQwNTY5ODg1NzIyOAJfNAQNdXNkV2gyQnBTYWxkbwgFDSR0MDU2OTg4NTcyMjgCXzUEDXVzZEJwMldoU2FsZG8IBQ0kdDA1Njk4ODU3MjI4Al82BAh4cEFtb3VudAgFDSR0MDU2OTg4NTcyMjgCXzcEDXNob3BMYW5kT3duZXIIBQ0kdDA1Njk4ODU3MjI4Al84BApzaG9wV2hTYXZlCAUNJHQwNTY5ODg1NzIyOAJfOQQOYWNjU3RhdHNSZXN1bHQIBQ0kdDA1Njk4ODU3MjI4A18xMAQIYWN0aW9uczEJAMwIAgUKc2hvcEFjdGlvbgkBEHNob3AydXNlckFjdGlvbnMDBQ11c2RXaDJCcFNhbGRvBQpjYWxsZXJBZGRyAAAECGFjdGlvbnMyCQEQdXNlcjJzaG9wQWN0aW9ucwQFDXVzZEJwMldoU2FsZG8IBQFpCHBheW1lbnRzBQ1zaG9wTGFuZE93bmVyAAAECG5ld0JwU3RyCQC6CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQC5CQIFCm5ld1VzZXJSZXMCAV8JAMwIAgkAuQkCBQpuZXdVc2VyTWF0AgFfCQDMCAIJALoJAgULbmV3VXNlclByb2QCAV8FA25pbAIBOgQGYnBTYXZlCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIOdXBkYXRlQmFja3BhY2sJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUIbmV3QnBTdHIFA25pbAUDbmlsBA9kdWNrU3RhdHNSZXN1bHQJAQVhc0ludAEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag91cGRhdGVEdWNrU3RhdHMJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgkAawMFBnhwU2hvcAUIeHBBbW91bnQFBU1VTFQ4BQNuaWwFA25pbAkAlAoCCQDOCAIFCGFjdGlvbnMxBQhhY3Rpb25zMgkAlwoFBQxwcm9sb2dSZXN1bHQFCnNob3BXaFNhdmUFBmJwU2F2ZQUPZHVja1N0YXRzUmVzdWx0BQ5hY2NTdGF0c1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARthY2NlcHRTaG9wT3JkZXJEdWNrRGVsaXZlcnkCCG9yZGVyU3RyD3Nob3BMYW5kQXNzZXRJZAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAAACBQxwcm9sb2dSZXN1bHQFDHByb2xvZ1Jlc3VsdAQGY2FsbGVyCAUBaQxvcmlnaW5DYWxsZXIECmNhbGxlckFkZHIJAKUIAQUGY2FsbGVyBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUKY2FsbGVyQWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkECWJwUmVzTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwQJYnBNYXRMaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBApicFByb2RMaXN0AwkAAAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIABQNuaWwJALwJAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgFfBA0kdDA1ODU5MzU4ODMxCQEVYWNjZXB0U2hvcE9yZGVyQ29tbW9uBgUPc2hvcExhbmRBc3NldElkBQpjYWxsZXJBZGRyBQhvcmRlclN0cgUJYnBSZXNMaXN0BQlicE1hdExpc3QFCmJwUHJvZExpc3QECnNob3BBY3Rpb24IBQ0kdDA1ODU5MzU4ODMxAl8xBApuZXdVc2VyUmVzCAUNJHQwNTg1OTM1ODgzMQJfMgQKbmV3VXNlck1hdAgFDSR0MDU4NTkzNTg4MzECXzMEC25ld1VzZXJQcm9kCAUNJHQwNTg1OTM1ODgzMQJfNAQNdXNkV2gyQnBTYWxkbwgFDSR0MDU4NTkzNTg4MzECXzUEDXVzZEJwMldoU2FsZG8IBQ0kdDA1ODU5MzU4ODMxAl82BAh4cEFtb3VudAgFDSR0MDU4NTkzNTg4MzECXzcEDXNob3BMYW5kT3duZXIIBQ0kdDA1ODU5MzU4ODMxAl84BApzaG9wV2hTYXZlCAUNJHQwNTg1OTM1ODgzMQJfOQQOYWNjU3RhdHNSZXN1bHQIBQ0kdDA1ODU5MzU4ODMxA18xMAQPZGVsaXZlcnlGZWVQYXJ0CQBrAwkAZAIFDXVzZEJwMldoU2FsZG8FDXVzZFdoMkJwU2FsZG8FDERFTElWRVJZX0ZFRQUFTVVMVDYEC2RlbGl2ZXJ5RmVlCQCWAwEJAMwIAgUPZGVsaXZlcnlGZWVQYXJ0CQDMCAIFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQUDbmlsBAhzcGVudEZlZQkAawMFC2RlbGl2ZXJ5RmVlBQ11c2RCcDJXaFNhbGRvCQBkAgUNdXNkQnAyV2hTYWxkbwUNdXNkV2gyQnBTYWxkbwQLcmVjZWl2ZWRGZWUJAGUCBQtkZWxpdmVyeUZlZQUIc3BlbnRGZWUECWZ1bmRUb3RhbAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ9kZWxpdmVyeUZ1bmRLZXkAAAQIYWN0aW9uczEJAMwIAgUKc2hvcEFjdGlvbgkBEHNob3AydXNlckFjdGlvbnMDBQ11c2RXaDJCcFNhbGRvBQpjYWxsZXJBZGRyBQtyZWNlaXZlZEZlZQQIYWN0aW9uczIJARB1c2VyMnNob3BBY3Rpb25zBAUNdXNkQnAyV2hTYWxkbwgFAWkIcGF5bWVudHMFDXNob3BMYW5kT3duZXIFCHNwZW50RmVlBAhuZXdCcFN0cgkAugkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAuQkCBQpuZXdVc2VyUmVzAgFfCQDMCAIJALkJAgUKbmV3VXNlck1hdAIBXwkAzAgCCQC6CQIFC25ld1VzZXJQcm9kAgFfBQNuaWwCAToEBmJwU2F2ZQkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCDnVwZGF0ZUJhY2twYWNrCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIFCG5ld0JwU3RyBQNuaWwFA25pbAQPZHVja1N0YXRzUmVzdWx0CQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIPdXBkYXRlRHVja1N0YXRzCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIJAGsDBQZ4cFNob3AFCHhwQW1vdW50BQVNVUxUOAUDbmlsBQNuaWwJAJQKAgkAzQgCCQDOCAIFCGFjdGlvbnMxBQhhY3Rpb25zMgkBDEludGVnZXJFbnRyeQIFD2RlbGl2ZXJ5RnVuZEtleQkAZAIFCWZ1bmRUb3RhbAULZGVsaXZlcnlGZWUJAJcKBQUMcHJvbG9nUmVzdWx0BQpzaG9wV2hTYXZlBQZicFNhdmUFD2R1Y2tTdGF0c1Jlc3VsdAUOYWNjU3RhdHNSZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEbYWNjZXB0U2hvcE9yZGVyTGFuZERlbGl2ZXJ5AwhvcmRlclN0cg9zaG9wTGFuZEFzc2V0SWQNbXlMYW5kQXNzZXRJZAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAAACBQxwcm9sb2dSZXN1bHQFDHByb2xvZ1Jlc3VsdAQGY2FsbGVyCAUBaQxvcmlnaW5DYWxsZXIECmNhbGxlckFkZHIJAKUIAQUGY2FsbGVyBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFDW15TGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQ1teUxhbmRBc3NldElkCQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQ1teUxhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQpjYWxsZXJBZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAJ3aAkBCGFzU3RyaW5nAQkA/AcEBQ9zdGFraW5nQ29udHJhY3QCFGdldFdhcmVob3VzZVJFQURPTkxZCQDMCAIFDW15TGFuZEFzc2V0SWQFA25pbAUDbmlsBAljdXJyZW50V2gJALwJAgUCd2gCAToEB3Jlc0xpc3QJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfBAdtYXRMaXN0CQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAIBXwQIcHJvZExpc3QDCQAAAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAIABQNuaWwJALwJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAIBXwQNJHQwNjA5NTI2MTE4NAkBFWFjY2VwdFNob3BPcmRlckNvbW1vbgYFD3Nob3BMYW5kQXNzZXRJZAUKY2FsbGVyQWRkcgUIb3JkZXJTdHIFB3Jlc0xpc3QFB21hdExpc3QFCHByb2RMaXN0BApzaG9wQWN0aW9uCAUNJHQwNjA5NTI2MTE4NAJfMQQKbmV3VXNlclJlcwgFDSR0MDYwOTUyNjExODQCXzIECm5ld1VzZXJNYXQIBQ0kdDA2MDk1MjYxMTg0Al8zBAtuZXdVc2VyUHJvZAgFDSR0MDYwOTUyNjExODQCXzQEDXVzZFdoMkJwU2FsZG8IBQ0kdDA2MDk1MjYxMTg0Al81BA11c2RCcDJXaFNhbGRvCAUNJHQwNjA5NTI2MTE4NAJfNgQIeHBBbW91bnQIBQ0kdDA2MDk1MjYxMTg0Al83BA1zaG9wTGFuZE93bmVyCAUNJHQwNjA5NTI2MTE4NAJfOAQKc2hvcFdoU2F2ZQgFDSR0MDYwOTUyNjExODQCXzkEDmFjY1N0YXRzUmVzdWx0CAUNJHQwNjA5NTI2MTE4NANfMTAED2RlbGl2ZXJ5RmVlUGFydAkAawMJAGQCBQ11c2RCcDJXaFNhbGRvBQ11c2RXaDJCcFNhbGRvBQxERUxJVkVSWV9GRUUFBU1VTFQ2BAtkZWxpdmVyeUZlZQkAlgMBCQDMCAIFD2RlbGl2ZXJ5RmVlUGFydAkAzAgCBRVNSU5fVVNEVF9GRUVfREVMSVZFUlkFA25pbAQIc3BlbnRGZWUJAGsDBQtkZWxpdmVyeUZlZQUNdXNkQnAyV2hTYWxkbwkAZAIFDXVzZEJwMldoU2FsZG8FDXVzZFdoMkJwU2FsZG8EC3JlY2VpdmVkRmVlCQBlAgULZGVsaXZlcnlGZWUFCHNwZW50RmVlBAlmdW5kVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUPZGVsaXZlcnlGdW5kS2V5AAAECGFjdGlvbnMxCQDMCAIFCnNob3BBY3Rpb24JARBzaG9wMnVzZXJBY3Rpb25zAwUNdXNkV2gyQnBTYWxkbwUKY2FsbGVyQWRkcgULcmVjZWl2ZWRGZWUECGFjdGlvbnMyCQEQdXNlcjJzaG9wQWN0aW9ucwQFDXVzZEJwMldoU2FsZG8IBQFpCHBheW1lbnRzBQ1zaG9wTGFuZE93bmVyBQhzcGVudEZlZQQFd2hTdHIJALoJAgkAzAgCCQCRAwIFCWN1cnJlbnRXaAULd2hJZHhMZXZlbHMJAMwIAgkAuQkCBQpuZXdVc2VyUmVzAgFfCQDMCAIJALkJAgUKbmV3VXNlck1hdAIBXwkAzAgCCQC5CQIFC25ld1VzZXJQcm9kAgFfCQDMCAIJAJEDAgUJY3VycmVudFdoBQl3aElkeExPRlQFA25pbAIBOgQGd2hTYXZlCQEIYXNTdHJpbmcBCQD8BwQFD3N0YWtpbmdDb250cmFjdAINc2F2ZVdhcmVob3VzZQkAzAgCBQV3aFN0cgkAzAgCBQ1teUxhbmRBc3NldElkBQNuaWwFA25pbAQLc3RhdHNSZXN1bHQJAQVhc0ludAEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0Ag51cGRhdGVBY2NTdGF0cwkAzAgCBQpjYWxsZXJBZGRyCQDMCAIJAGsDBQZ4cFNob3AFCHhwQW1vdW50BQVNVUxUOAUDbmlsBQNuaWwJAJQKAgkAzQgCCQDOCAIFCGFjdGlvbnMxBQhhY3Rpb25zMgkBDEludGVnZXJFbnRyeQIFD2RlbGl2ZXJ5RnVuZEtleQkAZAIFCWZ1bmRUb3RhbAULZGVsaXZlcnlGZWUJAJcKBQUMcHJvbG9nUmVzdWx0BQpzaG9wV2hTYXZlBQZ3aFNhdmUFC3N0YXRzUmVzdWx0BQ5hY2NTdGF0c1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARBzZWxsUHJvZHVjdHNUb0VTAQdhbW91bnRzBAxwcm9sb2dSZXN1bHQJAQZwcm9sb2cAAwkAAAIFDHByb2xvZ1Jlc3VsdAUMcHJvbG9nUmVzdWx0AwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQISTm8gcGF5bWVudHMgbmVlZGVkBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQEC2N1ckxvY2F0aW9uCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgIBXwMJAQIhPQIJAJEDAgULY3VyTG9jYXRpb24FCmxvY0lkeFR5cGUCAUEJAAIBCQCsAgICLUR1Y2sgbG9jYXRpb24gdHlwZSBzaG91bGQgYmUgQWlycG9ydCwgYnV0IGlzIAkAkQMCBQtjdXJMb2NhdGlvbgUKbG9jSWR4VHlwZQQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAhwcm9kTGlzdAMJAAACCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIBXwQFZXNLZXkJAQ5rZXlFc1dhcmVob3VzZQAECGV4aXN0U3RyCQCiCAEFBWVzS2V5BAxleGlzdEFtb3VudHMDCQEJaXNEZWZpbmVkAQUIZXhpc3RTdHIJALwJAgkBBXZhbHVlAQUIZXhpc3RTdHICAV8FA25pbAoBCG1vdmVQcm9kAgNhY2MJcmVjaXBlU3RyBAFqCAUDYWNjAl8xBAhxdWFudGl0eQMJAGYCCQCQAwEFB2Ftb3VudHMFAWoJAJEDAgUHYW1vdW50cwUBagAAAwkAZgIAAAUIcXVhbnRpdHkJAAIBAhtRdWFudGl0eSBjYW5ub3QgYmUgbmVnYXRpdmUEBnJlY2lwZQkAtQkCBQlyZWNpcGVTdHICAV8DCQECIT0CCQCQAwEFBnJlY2lwZQUKUkVDSVBFU0laRQkAAgEJAKwCAgIXRmF0YWw6IHVua25vd24gcmVjaXBlOiAFCXJlY2lwZVN0cgQJbWF4QW1vdW50CQBoAgUNRVNNQVhQQUNLQUdFUwUOUFJPRFVDVFBLR1NJWkUEC2V4aXN0QW1vdW50AwkAZgIJAJADAQUMZXhpc3RBbW91bnRzBQFqCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUMZXhpc3RBbW91bnRzBQFqAAAEBmNhbkJ1eQkAZQIFCW1heEFtb3VudAUL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AgFfCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcggFBm1lcmdlZAJfMgULdXNkdEFzc2V0SWQFA25pbAkAlQoDBQZicFNhdmUFDHByb2xvZ1Jlc3VsdAULc3RhdHNSZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEPdXBkYXRlRXNTdG9yYWdlAQpuZXdTdG9yYWdlAwkBAiE9AggFAWkGY2FsbGVyBQ9zdGFraW5nQ29udHJhY3QJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ5rZXlFc1dhcmVob3VzZQAFCm5ld1N0b3JhZ2UFA25pbAUKbmV3U3RvcmFnZQFpARR1cGRhdGVEZWxpdmVyeUxvY2tlZAEJbmV3QW1vdW50AwkBAiE9AggFAWkGY2FsbGVyBQ9zdGFraW5nQ29udHJhY3QJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFkZWxpdmVyeUxvY2tlZEtleQUJbmV3QW1vdW50BQNuaWwFCW5ld0Ftb3VudAFpARJzZW5kRGVsaXZlcnlSZXdhcmQBBGFkZHIDCQECIT0CCAUBaQZjYWxsZXIFD3N0YWtpbmdDb250cmFjdAkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAlmdW5kVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUPZGVsaXZlcnlGdW5kS2V5AAAEC2xvY2tlZFRvdGFsCQELdmFsdWVPckVsc2UCCQCfCAEFEWRlbGl2ZXJ5TG9ja2VkS2V5AAAEC2FjcmVzQW1vdW50CQBoAgUVTUlOX1VTRFRfRkVFX0RFTElWRVJZBRVVU0RUMkFDUkVTX01VTFRJUExJRVIEC2FjcmVzUmVzdWx0CQD8BwQFDWFjcmVzQ29udHJhY3QCCXNlbmRBY3JlcwkAzAgCBQRhZGRyCQDMCAIFC2FjcmVzQW1vdW50BQNuaWwFA25pbAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9kZWxpdmVyeUZ1bmRLZXkJAGUCBQlmdW5kVG90YWwFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQkAzAgCCQEMSW50ZWdlckVudHJ5AgURZGVsaXZlcnlMb2NrZWRLZXkJAGUCBQtsb2NrZWRUb3RhbAUVTUlOX1VTRFRfRkVFX0RFTElWRVJZBQNuaWwFC2FjcmVzUmVzdWx0AAiBl3E=", "height": 2814490, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 7ALzi2wC8GDNAAek1dKHzwo6FJH5MbWWw29m4W4GqJKg Next: 6mkTN5Top9xkhR4PSRPWV9P8hhpuYd1s4G1FZSvkfBZz Diff:
Old | New | Differences | |
---|---|---|---|
109 | 109 | ||
110 | 110 | func getRecipeMaterials (recipe) = (parseIntValue(recipe[rIdxCoeff]) * COEFF2MAT) | |
111 | 111 | ||
112 | - | ||
113 | - | let KS_ALLOW_DELIVERY = true | |
114 | 112 | ||
115 | 113 | let chain = take(drop(this.bytes, 1), 1) | |
116 | 114 | ||
720 | 718 | $Tuple3((acc._1 ++ x._1), (acc._2 + x._3), (acc._3 + x._4)) | |
721 | 719 | } | |
722 | 720 | ||
723 | - | let $ | |
721 | + | let $t02529225382 = { | |
724 | 722 | let $l = continents | |
725 | 723 | let $s = size($l) | |
726 | 724 | let $acc0 = $Tuple3(nil, 0, 0) | |
734 | 732 | ||
735 | 733 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5) | |
736 | 734 | } | |
737 | - | let factoryActions = $ | |
738 | - | let usdtReceived = $ | |
739 | - | let totalRes = $ | |
735 | + | let factoryActions = $t02529225382._1 | |
736 | + | let usdtReceived = $t02529225382._2 | |
737 | + | let totalRes = $t02529225382._3 | |
740 | 738 | let fee = fraction(usdtReceived, DELIVERY_FEE, MULT6) | |
741 | 739 | let activitiesAmount = (usdtReceived / 100) | |
742 | 740 | let usdtLeft = ((usdtReceived - activitiesAmount) - fee) | |
845 | 843 | else { | |
846 | 844 | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
847 | 845 | let resList = split(currentPack[bpIdxRes], "_") | |
848 | - | let $ | |
849 | - | let factoryActions = $ | |
850 | - | let newRes = $ | |
851 | - | let usdtReceived = $ | |
852 | - | let totalRes = $ | |
846 | + | let $t02891529041 = sellResourcesCommon(resList, curLocation[locIdxId], amounts, minPrices) | |
847 | + | let factoryActions = $t02891529041._1 | |
848 | + | let newRes = $t02891529041._2 | |
849 | + | let usdtReceived = $t02891529041._3 | |
850 | + | let totalRes = $t02891529041._4 | |
853 | 851 | let activitiesAmount = (usdtReceived / 100) | |
854 | 852 | let newPack = makeString_2C([currentPack[bpIdxLevel], makeString(newRes, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":") | |
855 | 853 | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
867 | 865 | func sellResourcesWorld (addr,amount) = if ((i.caller != acresContract)) | |
868 | 866 | then throw("Permission denied") | |
869 | 867 | else { | |
870 | - | let $ | |
871 | - | let factoryActions = $ | |
872 | - | let usdtLeft = $ | |
873 | - | let fee = $ | |
874 | - | let activitiesAmount = $ | |
875 | - | let totalRes = $ | |
868 | + | let $t02983329990 = sellResourcesWorldInternal(amount) | |
869 | + | let factoryActions = $t02983329990._1 | |
870 | + | let usdtLeft = $t02983329990._2 | |
871 | + | let fee = $t02983329990._3 | |
872 | + | let activitiesAmount = $t02983329990._4 | |
873 | + | let totalRes = $t02983329990._5 | |
876 | 874 | if ((0 >= usdtLeft)) | |
877 | 875 | then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6))) | |
878 | 876 | else { | |
892 | 890 | ||
893 | 891 | ||
894 | 892 | @Callable(i) | |
895 | - | func sellResourcesDuckDelivery (amounts,minPrices,factoryContinent) = if (!(KS_ALLOW_DELIVERY)) | |
896 | - | then throw("Delivery feature is turned off!") | |
897 | - | else { | |
898 | - | let prologResult = prolog() | |
899 | - | if ((prologResult == prologResult)) | |
900 | - | then { | |
901 | - | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
902 | - | if ((size(i.payments) != 0)) | |
903 | - | then throw("sellResources doesn't require any payments") | |
904 | - | else { | |
905 | - | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
906 | - | let resList = split(currentPack[bpIdxRes], "_") | |
907 | - | let $t03120431325 = sellResourcesCommon(resList, factoryContinent, amounts, minPrices) | |
908 | - | let factoryActions = $t03120431325._1 | |
909 | - | let newRes = $t03120431325._2 | |
910 | - | let usdtReceived = $t03120431325._3 | |
911 | - | let totalRes = $t03120431325._4 | |
912 | - | let newPack = makeString_2C([currentPack[bpIdxLevel], makeString(newRes, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":") | |
913 | - | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
914 | - | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalRes, MULT8)], nil)) | |
915 | - | let feePart = fraction(usdtReceived, DELIVERY_FEE, MULT6) | |
916 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
917 | - | let activitiesAmount = (usdtReceived / 100) | |
918 | - | if ((fee >= (usdtReceived - activitiesAmount))) | |
919 | - | then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6))) | |
920 | - | else { | |
921 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
922 | - | $Tuple2((((factoryActions :+ ScriptTransfer(i.caller, ((usdtReceived - activitiesAmount) - fee), usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult)) | |
923 | - | } | |
924 | - | } | |
925 | - | } | |
926 | - | else throw("Strict value is not equal to itself.") | |
927 | - | } | |
893 | + | func sellResourcesDuckDelivery (amounts,minPrices,factoryContinent) = { | |
894 | + | let prologResult = prolog() | |
895 | + | if ((prologResult == prologResult)) | |
896 | + | then { | |
897 | + | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
898 | + | if ((size(i.payments) != 0)) | |
899 | + | then throw("sellResources doesn't require any payments") | |
900 | + | else { | |
901 | + | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
902 | + | let resList = split(currentPack[bpIdxRes], "_") | |
903 | + | let $t03114931270 = sellResourcesCommon(resList, factoryContinent, amounts, minPrices) | |
904 | + | let factoryActions = $t03114931270._1 | |
905 | + | let newRes = $t03114931270._2 | |
906 | + | let usdtReceived = $t03114931270._3 | |
907 | + | let totalRes = $t03114931270._4 | |
908 | + | let newPack = makeString_2C([currentPack[bpIdxLevel], makeString(newRes, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":") | |
909 | + | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
910 | + | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalRes, MULT8)], nil)) | |
911 | + | let feePart = fraction(usdtReceived, DELIVERY_FEE, MULT6) | |
912 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
913 | + | let activitiesAmount = (usdtReceived / 100) | |
914 | + | if ((fee >= (usdtReceived - activitiesAmount))) | |
915 | + | then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6))) | |
916 | + | else { | |
917 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
918 | + | $Tuple2((((factoryActions :+ ScriptTransfer(i.caller, ((usdtReceived - activitiesAmount) - fee), usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult)) | |
919 | + | } | |
920 | + | } | |
921 | + | } | |
922 | + | else throw("Strict value is not equal to itself.") | |
923 | + | } | |
928 | 924 | ||
929 | 925 | ||
930 | 926 | ||
931 | 927 | @Callable(i) | |
932 | - | func sellResourcesLandDelivery (amounts,minPrices,landAssetId,factoryContinent) = if (!(KS_ALLOW_DELIVERY)) | |
933 | - | then throw("Delivery feature is turned off!") | |
934 | - | else { | |
935 | - | let prologResult = prolog() | |
936 | - | if ((prologResult == prologResult)) | |
937 | - | then if ((size(i.payments) != 0)) | |
938 | - | then throw("sellResources doesn't require any payments") | |
939 | - | else { | |
940 | - | let user = i.caller | |
941 | - | let addr = toString(user) | |
942 | - | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
943 | - | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
944 | - | then throw((("NFT " + asset.name) + " is not staked")) | |
945 | - | else { | |
946 | - | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
947 | - | if ((owner != addr)) | |
948 | - | then throw((LANDPREFIX + " is not yours")) | |
949 | - | else { | |
950 | - | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
951 | - | let currentWh = split_4C(wh, ":") | |
952 | - | let resList = split(currentWh[whIdxRes], "_") | |
953 | - | let $t03331633437 = sellResourcesCommon(resList, factoryContinent, amounts, minPrices) | |
954 | - | let factoryActions = $t03331633437._1 | |
955 | - | let newRes = $t03331633437._2 | |
956 | - | let usdtReceived = $t03331633437._3 | |
957 | - | let totalRes = $t03331633437._4 | |
958 | - | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newRes, "_"), currentWh[whIdxMat], currentWh[whIdxProd], currentWh[whIdxLOFT]], ":") | |
959 | - | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
960 | - | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalRes, MULT8)], nil)) | |
961 | - | let feePart = fraction(usdtReceived, DELIVERY_FEE, MULT6) | |
962 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
963 | - | let activitiesAmount = (usdtReceived / 100) | |
964 | - | if ((fee >= (usdtReceived - activitiesAmount))) | |
965 | - | then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6))) | |
966 | - | else { | |
967 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
968 | - | $Tuple2((((factoryActions :+ ScriptTransfer(i.caller, ((usdtReceived - activitiesAmount) - fee), usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(whSave, prologResult, statsResult)) | |
969 | - | } | |
970 | - | } | |
971 | - | } | |
972 | - | } | |
973 | - | else throw("Strict value is not equal to itself.") | |
974 | - | } | |
928 | + | func sellResourcesLandDelivery (amounts,minPrices,landAssetId,factoryContinent) = { | |
929 | + | let prologResult = prolog() | |
930 | + | if ((prologResult == prologResult)) | |
931 | + | then if ((size(i.payments) != 0)) | |
932 | + | then throw("sellResources doesn't require any payments") | |
933 | + | else { | |
934 | + | let user = i.caller | |
935 | + | let addr = toString(user) | |
936 | + | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
937 | + | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
938 | + | then throw((("NFT " + asset.name) + " is not staked")) | |
939 | + | else { | |
940 | + | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
941 | + | if ((owner != addr)) | |
942 | + | then throw((LANDPREFIX + " is not yours")) | |
943 | + | else { | |
944 | + | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
945 | + | let currentWh = split_4C(wh, ":") | |
946 | + | let resList = split(currentWh[whIdxRes], "_") | |
947 | + | let $t03318433305 = sellResourcesCommon(resList, factoryContinent, amounts, minPrices) | |
948 | + | let factoryActions = $t03318433305._1 | |
949 | + | let newRes = $t03318433305._2 | |
950 | + | let usdtReceived = $t03318433305._3 | |
951 | + | let totalRes = $t03318433305._4 | |
952 | + | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newRes, "_"), currentWh[whIdxMat], currentWh[whIdxProd], currentWh[whIdxLOFT]], ":") | |
953 | + | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
954 | + | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalRes, MULT8)], nil)) | |
955 | + | let feePart = fraction(usdtReceived, DELIVERY_FEE, MULT6) | |
956 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
957 | + | let activitiesAmount = (usdtReceived / 100) | |
958 | + | if ((fee >= (usdtReceived - activitiesAmount))) | |
959 | + | then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6))) | |
960 | + | else { | |
961 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
962 | + | $Tuple2((((factoryActions :+ ScriptTransfer(i.caller, ((usdtReceived - activitiesAmount) - fee), usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(whSave, prologResult, statsResult)) | |
963 | + | } | |
964 | + | } | |
965 | + | } | |
966 | + | } | |
967 | + | else throw("Strict value is not equal to itself.") | |
968 | + | } | |
975 | 969 | ||
976 | 970 | ||
977 | 971 | ||
997 | 991 | else { | |
998 | 992 | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
999 | 993 | let matList = split(currentPack[bpIdxMat], "_") | |
1000 | - | let $ | |
1001 | - | let factoryActions = $ | |
1002 | - | let newMat = $ | |
1003 | - | let usdtSpent = $ | |
1004 | - | let totalMat = $ | |
994 | + | let $t03512935251 = buyMaterialsCommon(matList, curLocation[locIdxId], amounts, maxPrices) | |
995 | + | let factoryActions = $t03512935251._1 | |
996 | + | let newMat = $t03512935251._2 | |
997 | + | let usdtSpent = $t03512935251._3 | |
998 | + | let totalMat = $t03512935251._4 | |
1005 | 999 | if ((usdtSpent > amt)) | |
1006 | 1000 | then throw(((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6))) | |
1007 | 1001 | else { | |
1024 | 1018 | ||
1025 | 1019 | ||
1026 | 1020 | @Callable(i) | |
1027 | - | func buyMaterialsDuckDelivery (amounts,maxPrices,factoryContinent) = if (!(KS_ALLOW_DELIVERY)) | |
1028 | - | then throw("Delivery feature is turned off!") | |
1029 | - | else { | |
1030 | - | let prologResult = prolog() | |
1031 | - | if ((prologResult == prologResult)) | |
1032 | - | then { | |
1033 | - | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1034 | - | if ((size(i.payments) != 1)) | |
1035 | - | then throw("exactly 1 payment must be attached") | |
1036 | - | else { | |
1037 | - | let pmt = i.payments[0] | |
1038 | - | let amt = pmt.amount | |
1039 | - | if (if (!(isDefined(pmt.assetId))) | |
1040 | - | then true | |
1041 | - | else (value(pmt.assetId) != usdtAssetId)) | |
1042 | - | then throw("USDT payments only!") | |
1043 | - | else { | |
1044 | - | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1045 | - | let matList = split(currentPack[bpIdxMat], "_") | |
1046 | - | let $t03690437021 = buyMaterialsCommon(matList, factoryContinent, amounts, maxPrices) | |
1047 | - | let factoryActions = $t03690437021._1 | |
1048 | - | let newMat = $t03690437021._2 | |
1049 | - | let usdtSpent = $t03690437021._3 | |
1050 | - | let totalMat = $t03690437021._4 | |
1051 | - | let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), currentPack[bpIdxProd]], ":") | |
1052 | - | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1053 | - | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalMat, MULT8)], nil)) | |
1054 | - | let feePart = fraction(usdtSpent, DELIVERY_FEE, MULT6) | |
1055 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1056 | - | let usdtSpentWithFee = (usdtSpent + fee) | |
1057 | - | if ((usdtSpentWithFee > amt)) | |
1058 | - | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1059 | - | else { | |
1060 | - | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1061 | - | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1062 | - | else nil | |
1063 | - | let activitiesAmount = (usdtSpent / 100) | |
1064 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1065 | - | $Tuple2((((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult)) | |
1066 | - | } | |
1067 | - | } | |
1068 | - | } | |
1069 | - | } | |
1070 | - | else throw("Strict value is not equal to itself.") | |
1071 | - | } | |
1072 | - | ||
1073 | - | ||
1074 | - | ||
1075 | - | @Callable(i) | |
1076 | - | func buyMaterialsLandDelivery (amounts,maxPrices,landAssetId,factoryContinent) = if (!(KS_ALLOW_DELIVERY)) | |
1077 | - | then throw("Delivery feature is turned off!") | |
1078 | - | else { | |
1079 | - | let prologResult = prolog() | |
1080 | - | if ((prologResult == prologResult)) | |
1081 | - | then if ((size(i.payments) != 1)) | |
1021 | + | func buyMaterialsDuckDelivery (amounts,maxPrices,factoryContinent) = { | |
1022 | + | let prologResult = prolog() | |
1023 | + | if ((prologResult == prologResult)) | |
1024 | + | then { | |
1025 | + | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1026 | + | if ((size(i.payments) != 1)) | |
1082 | 1027 | then throw("exactly 1 payment must be attached") | |
1083 | 1028 | else { | |
1084 | 1029 | let pmt = i.payments[0] | |
1088 | 1033 | else (value(pmt.assetId) != usdtAssetId)) | |
1089 | 1034 | then throw("USDT payments only!") | |
1090 | 1035 | else { | |
1091 | - | let user = i.caller | |
1092 | - | let addr = toString(user) | |
1093 | - | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1094 | - | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1095 | - | then throw((("NFT " + asset.name) + " is not staked")) | |
1036 | + | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1037 | + | let matList = split(currentPack[bpIdxMat], "_") | |
1038 | + | let $t03669536812 = buyMaterialsCommon(matList, factoryContinent, amounts, maxPrices) | |
1039 | + | let factoryActions = $t03669536812._1 | |
1040 | + | let newMat = $t03669536812._2 | |
1041 | + | let usdtSpent = $t03669536812._3 | |
1042 | + | let totalMat = $t03669536812._4 | |
1043 | + | let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), currentPack[bpIdxProd]], ":") | |
1044 | + | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1045 | + | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalMat, MULT8)], nil)) | |
1046 | + | let feePart = fraction(usdtSpent, DELIVERY_FEE, MULT6) | |
1047 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1048 | + | let usdtSpentWithFee = (usdtSpent + fee) | |
1049 | + | if ((usdtSpentWithFee > amt)) | |
1050 | + | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1096 | 1051 | else { | |
1097 | - | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1098 | - | if ((owner != addr)) | |
1099 | - | then throw((LANDPREFIX + " is not yours")) | |
1100 | - | else { | |
1101 | - | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1102 | - | let currentWh = split_4C(wh, ":") | |
1103 | - | let matList = split(currentWh[whIdxMat], "_") | |
1104 | - | let $t03926339380 = buyMaterialsCommon(matList, factoryContinent, amounts, maxPrices) | |
1105 | - | let factoryActions = $t03926339380._1 | |
1106 | - | let newMat = $t03926339380._2 | |
1107 | - | let usdtSpent = $t03926339380._3 | |
1108 | - | let totalMat = $t03926339380._4 | |
1109 | - | let whStr = makeString_2C([currentWh[whIdxLevels], currentWh[whIdxRes], makeString(newMat, "_"), currentWh[whIdxProd], currentWh[whIdxLOFT]], ":") | |
1110 | - | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1111 | - | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalMat, MULT8)], nil)) | |
1112 | - | let feePart = fraction(usdtSpent, DELIVERY_FEE, MULT6) | |
1113 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1114 | - | let usdtSpentWithFee = (usdtSpent + fee) | |
1115 | - | if ((usdtSpentWithFee > amt)) | |
1116 | - | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1117 | - | else { | |
1118 | - | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1119 | - | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1120 | - | else nil | |
1121 | - | let activitiesAmount = (usdtSpent / 100) | |
1122 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1123 | - | $Tuple2((((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult)) | |
1124 | - | } | |
1125 | - | } | |
1052 | + | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1053 | + | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1054 | + | else nil | |
1055 | + | let activitiesAmount = (usdtSpent / 100) | |
1056 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1057 | + | $Tuple2((((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult)) | |
1126 | 1058 | } | |
1127 | 1059 | } | |
1128 | 1060 | } | |
1129 | - | else throw("Strict value is not equal to itself.") | |
1130 | - | } | |
1061 | + | } | |
1062 | + | else throw("Strict value is not equal to itself.") | |
1063 | + | } | |
1064 | + | ||
1065 | + | ||
1066 | + | ||
1067 | + | @Callable(i) | |
1068 | + | func buyMaterialsLandDelivery (amounts,maxPrices,landAssetId,factoryContinent) = { | |
1069 | + | let prologResult = prolog() | |
1070 | + | if ((prologResult == prologResult)) | |
1071 | + | then if ((size(i.payments) != 1)) | |
1072 | + | then throw("exactly 1 payment must be attached") | |
1073 | + | else { | |
1074 | + | let pmt = i.payments[0] | |
1075 | + | let amt = pmt.amount | |
1076 | + | if (if (!(isDefined(pmt.assetId))) | |
1077 | + | then true | |
1078 | + | else (value(pmt.assetId) != usdtAssetId)) | |
1079 | + | then throw("USDT payments only!") | |
1080 | + | else { | |
1081 | + | let user = i.caller | |
1082 | + | let addr = toString(user) | |
1083 | + | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1084 | + | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1085 | + | then throw((("NFT " + asset.name) + " is not staked")) | |
1086 | + | else { | |
1087 | + | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1088 | + | if ((owner != addr)) | |
1089 | + | then throw((LANDPREFIX + " is not yours")) | |
1090 | + | else { | |
1091 | + | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1092 | + | let currentWh = split_4C(wh, ":") | |
1093 | + | let matList = split(currentWh[whIdxMat], "_") | |
1094 | + | let $t03897739094 = buyMaterialsCommon(matList, factoryContinent, amounts, maxPrices) | |
1095 | + | let factoryActions = $t03897739094._1 | |
1096 | + | let newMat = $t03897739094._2 | |
1097 | + | let usdtSpent = $t03897739094._3 | |
1098 | + | let totalMat = $t03897739094._4 | |
1099 | + | let whStr = makeString_2C([currentWh[whIdxLevels], currentWh[whIdxRes], makeString(newMat, "_"), currentWh[whIdxProd], currentWh[whIdxLOFT]], ":") | |
1100 | + | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1101 | + | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalMat, MULT8)], nil)) | |
1102 | + | let feePart = fraction(usdtSpent, DELIVERY_FEE, MULT6) | |
1103 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1104 | + | let usdtSpentWithFee = (usdtSpent + fee) | |
1105 | + | if ((usdtSpentWithFee > amt)) | |
1106 | + | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1107 | + | else { | |
1108 | + | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1109 | + | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1110 | + | else nil | |
1111 | + | let activitiesAmount = (usdtSpent / 100) | |
1112 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1113 | + | $Tuple2((((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult)) | |
1114 | + | } | |
1115 | + | } | |
1116 | + | } | |
1117 | + | } | |
1118 | + | } | |
1119 | + | else throw("Strict value is not equal to itself.") | |
1120 | + | } | |
1131 | 1121 | ||
1132 | 1122 | ||
1133 | 1123 | ||
1154 | 1144 | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1155 | 1145 | let resList = split(currentPack[bpIdxRes], "_") | |
1156 | 1146 | let matList = split(currentPack[bpIdxMat], "_") | |
1157 | - | let $ | |
1158 | - | let newRes = $ | |
1159 | - | let newMat = $ | |
1160 | - | let usdtSpent = $ | |
1161 | - | let totalAmountConverted = $ | |
1147 | + | let $t04117241278 = exchangeResourcesCommon(resList, matList, amounts) | |
1148 | + | let newRes = $t04117241278._1 | |
1149 | + | let newMat = $t04117241278._2 | |
1150 | + | let usdtSpent = $t04117241278._3 | |
1151 | + | let totalAmountConverted = $t04117241278._4 | |
1162 | 1152 | if ((usdtSpent > amt)) | |
1163 | 1153 | then throw(((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6))) | |
1164 | 1154 | else { | |
1181 | 1171 | ||
1182 | 1172 | ||
1183 | 1173 | @Callable(i) | |
1184 | - | func exchangeResourcesDuckDelivery (amounts) = if (!(KS_ALLOW_DELIVERY)) | |
1185 | - | then throw("Delivery feature is turned off!") | |
1186 | - | else { | |
1187 | - | let prologResult = prolog() | |
1188 | - | if ((prologResult == prologResult)) | |
1189 | - | then { | |
1190 | - | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1191 | - | if ((size(i.payments) != 1)) | |
1192 | - | then throw("exactly 1 payment must be attached") | |
1193 | - | else { | |
1194 | - | let pmt = i.payments[0] | |
1195 | - | let amt = pmt.amount | |
1196 | - | if (if (!(isDefined(pmt.assetId))) | |
1197 | - | then true | |
1198 | - | else (value(pmt.assetId) != usdtAssetId)) | |
1199 | - | then throw("USDT payments only!") | |
1200 | - | else { | |
1201 | - | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1202 | - | let resList = split(currentPack[bpIdxRes], "_") | |
1203 | - | let matList = split(currentPack[bpIdxMat], "_") | |
1204 | - | let $t04307943185 = exchangeResourcesCommon(resList, matList, amounts) | |
1205 | - | let newRes = $t04307943185._1 | |
1206 | - | let newMat = $t04307943185._2 | |
1207 | - | let usdtSpent = $t04307943185._3 | |
1208 | - | let totalAmountConverted = $t04307943185._4 | |
1209 | - | let feePart = fraction(usdtSpent, DELIVERY_FEE15, MULT6) | |
1210 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY15]) | |
1211 | - | let usdtSpentWithFee = (usdtSpent + fee) | |
1212 | - | if ((usdtSpentWithFee > amt)) | |
1213 | - | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1214 | - | else { | |
1215 | - | let newPack = makeString([currentPack[bpIdxLevel], makeString(newRes, "_"), makeString(newMat, "_"), currentPack[bpIdxProd]], ":") | |
1216 | - | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1217 | - | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1218 | - | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1219 | - | else nil | |
1220 | - | let activitiesAmount = (usdtSpent / 100) | |
1221 | - | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalAmountConverted, MULT8)], nil)) | |
1222 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1223 | - | $Tuple2(((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult)) | |
1224 | - | } | |
1225 | - | } | |
1226 | - | } | |
1227 | - | } | |
1228 | - | else throw("Strict value is not equal to itself.") | |
1229 | - | } | |
1230 | - | ||
1231 | - | ||
1232 | - | ||
1233 | - | @Callable(i) | |
1234 | - | func exchangeResourcesLandDelivery (amounts,landAssetId) = if (!(KS_ALLOW_DELIVERY)) | |
1235 | - | then throw("Delivery feature is turned off!") | |
1236 | - | else { | |
1237 | - | let prologResult = prolog() | |
1238 | - | if ((prologResult == prologResult)) | |
1239 | - | then if ((size(i.payments) != 1)) | |
1174 | + | func exchangeResourcesDuckDelivery (amounts) = { | |
1175 | + | let prologResult = prolog() | |
1176 | + | if ((prologResult == prologResult)) | |
1177 | + | then { | |
1178 | + | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1179 | + | if ((size(i.payments) != 1)) | |
1240 | 1180 | then throw("exactly 1 payment must be attached") | |
1241 | 1181 | else { | |
1242 | 1182 | let pmt = i.payments[0] | |
1246 | 1186 | else (value(pmt.assetId) != usdtAssetId)) | |
1247 | 1187 | then throw("USDT payments only!") | |
1248 | 1188 | else { | |
1249 | - | let user = i.caller | |
1250 | - | let addr = toString(user) | |
1251 | - | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1252 | - | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1253 | - | then throw((("NFT " + asset.name) + " is not staked")) | |
1189 | + | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1190 | + | let resList = split(currentPack[bpIdxRes], "_") | |
1191 | + | let matList = split(currentPack[bpIdxMat], "_") | |
1192 | + | let $t04271642822 = exchangeResourcesCommon(resList, matList, amounts) | |
1193 | + | let newRes = $t04271642822._1 | |
1194 | + | let newMat = $t04271642822._2 | |
1195 | + | let usdtSpent = $t04271642822._3 | |
1196 | + | let totalAmountConverted = $t04271642822._4 | |
1197 | + | let feePart = fraction(usdtSpent, DELIVERY_FEE15, MULT6) | |
1198 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY15]) | |
1199 | + | let usdtSpentWithFee = (usdtSpent + fee) | |
1200 | + | if ((usdtSpentWithFee > amt)) | |
1201 | + | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1254 | 1202 | else { | |
1255 | - | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1256 | - | if ((owner != addr)) | |
1257 | - | then throw((LANDPREFIX + " is not yours")) | |
1258 | - | else { | |
1259 | - | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1260 | - | let currentWh = split_4C(wh, ":") | |
1261 | - | let resList = split(currentWh[whIdxRes], "_") | |
1262 | - | let matList = split(currentWh[whIdxMat], "_") | |
1263 | - | let $t04544745553 = exchangeResourcesCommon(resList, matList, amounts) | |
1264 | - | let newRes = $t04544745553._1 | |
1265 | - | let newMat = $t04544745553._2 | |
1266 | - | let usdtSpent = $t04544745553._3 | |
1267 | - | let totalAmountConverted = $t04544745553._4 | |
1268 | - | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newRes, "_"), makeString(newMat, "_"), currentWh[whIdxProd], currentWh[whIdxLOFT]], ":") | |
1269 | - | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1270 | - | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalAmountConverted, MULT8)], nil)) | |
1271 | - | let feePart = fraction(usdtSpent, DELIVERY_FEE15, MULT6) | |
1272 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY15]) | |
1273 | - | let usdtSpentWithFee = (usdtSpent + fee) | |
1274 | - | if ((usdtSpentWithFee > amt)) | |
1275 | - | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1276 | - | else { | |
1277 | - | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1278 | - | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1279 | - | else nil | |
1280 | - | let activitiesAmount = (usdtSpent / 100) | |
1281 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1282 | - | $Tuple2(((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult)) | |
1283 | - | } | |
1284 | - | } | |
1203 | + | let newPack = makeString([currentPack[bpIdxLevel], makeString(newRes, "_"), makeString(newMat, "_"), currentPack[bpIdxProd]], ":") | |
1204 | + | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1205 | + | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1206 | + | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1207 | + | else nil | |
1208 | + | let activitiesAmount = (usdtSpent / 100) | |
1209 | + | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalAmountConverted, MULT8)], nil)) | |
1210 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1211 | + | $Tuple2(((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult)) | |
1285 | 1212 | } | |
1286 | 1213 | } | |
1287 | 1214 | } | |
1288 | - | else throw("Strict value is not equal to itself.") | |
1289 | - | } | |
1215 | + | } | |
1216 | + | else throw("Strict value is not equal to itself.") | |
1217 | + | } | |
1218 | + | ||
1219 | + | ||
1220 | + | ||
1221 | + | @Callable(i) | |
1222 | + | func exchangeResourcesLandDelivery (amounts,landAssetId) = { | |
1223 | + | let prologResult = prolog() | |
1224 | + | if ((prologResult == prologResult)) | |
1225 | + | then if ((size(i.payments) != 1)) | |
1226 | + | then throw("exactly 1 payment must be attached") | |
1227 | + | else { | |
1228 | + | let pmt = i.payments[0] | |
1229 | + | let amt = pmt.amount | |
1230 | + | if (if (!(isDefined(pmt.assetId))) | |
1231 | + | then true | |
1232 | + | else (value(pmt.assetId) != usdtAssetId)) | |
1233 | + | then throw("USDT payments only!") | |
1234 | + | else { | |
1235 | + | let user = i.caller | |
1236 | + | let addr = toString(user) | |
1237 | + | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1238 | + | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1239 | + | then throw((("NFT " + asset.name) + " is not staked")) | |
1240 | + | else { | |
1241 | + | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1242 | + | if ((owner != addr)) | |
1243 | + | then throw((LANDPREFIX + " is not yours")) | |
1244 | + | else { | |
1245 | + | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1246 | + | let currentWh = split_4C(wh, ":") | |
1247 | + | let resList = split(currentWh[whIdxRes], "_") | |
1248 | + | let matList = split(currentWh[whIdxMat], "_") | |
1249 | + | let $t04500745113 = exchangeResourcesCommon(resList, matList, amounts) | |
1250 | + | let newRes = $t04500745113._1 | |
1251 | + | let newMat = $t04500745113._2 | |
1252 | + | let usdtSpent = $t04500745113._3 | |
1253 | + | let totalAmountConverted = $t04500745113._4 | |
1254 | + | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newRes, "_"), makeString(newMat, "_"), currentWh[whIdxProd], currentWh[whIdxLOFT]], ":") | |
1255 | + | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1256 | + | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalAmountConverted, MULT8)], nil)) | |
1257 | + | let feePart = fraction(usdtSpent, DELIVERY_FEE15, MULT6) | |
1258 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY15]) | |
1259 | + | let usdtSpentWithFee = (usdtSpent + fee) | |
1260 | + | if ((usdtSpentWithFee > amt)) | |
1261 | + | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1262 | + | else { | |
1263 | + | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1264 | + | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1265 | + | else nil | |
1266 | + | let activitiesAmount = (usdtSpent / 100) | |
1267 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1268 | + | $Tuple2(((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult)) | |
1269 | + | } | |
1270 | + | } | |
1271 | + | } | |
1272 | + | } | |
1273 | + | } | |
1274 | + | else throw("Strict value is not equal to itself.") | |
1275 | + | } | |
1290 | 1276 | ||
1291 | 1277 | ||
1292 | 1278 | ||
1317 | 1303 | let prodList = if ((currentPack[bpIdxProd] == "")) | |
1318 | 1304 | then nil | |
1319 | 1305 | else split_4C(currentPack[bpIdxProd], "_") | |
1320 | - | let $ | |
1321 | - | let newMat = $ | |
1322 | - | let newProd = $ | |
1323 | - | let matSpent = $ | |
1306 | + | let $t04743847535 = craftGoodsCommon(matList, prodList, cont, productIdx, quantity) | |
1307 | + | let newMat = $t04743847535._1 | |
1308 | + | let newProd = $t04743847535._2 | |
1309 | + | let matSpent = $t04743847535._3 | |
1324 | 1310 | let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), makeString_2C(newProd, "_")], ":") | |
1325 | 1311 | let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1326 | 1312 | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpCraft, matSpent, MULT8)], nil)) | |
1334 | 1320 | ||
1335 | 1321 | ||
1336 | 1322 | @Callable(i) | |
1337 | - | func craftGoodsDuckDelivery (productIdx,quantity,manufactoryContinent) = if (!(KS_ALLOW_DELIVERY)) | |
1338 | - | then throw("Delivery feature is turned off!") | |
1339 | - | else { | |
1340 | - | let prologResult = prolog() | |
1341 | - | if ((prologResult == prologResult)) | |
1342 | - | then { | |
1343 | - | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1344 | - | if ((size(i.payments) != 1)) | |
1345 | - | then throw("exactly 1 payment must be attached") | |
1346 | - | else { | |
1347 | - | let pmt = i.payments[0] | |
1348 | - | let amt = pmt.amount | |
1349 | - | if (if (!(isDefined(pmt.assetId))) | |
1350 | - | then true | |
1351 | - | else (value(pmt.assetId) != usdtAssetId)) | |
1352 | - | then throw("USDT payments only!") | |
1353 | - | else { | |
1354 | - | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1355 | - | let matList = split(currentPack[bpIdxMat], "_") | |
1356 | - | let prodList = if ((currentPack[bpIdxProd] == "")) | |
1357 | - | then nil | |
1358 | - | else split_4C(currentPack[bpIdxProd], "_") | |
1359 | - | let $t04920049313 = craftGoodsCommon(matList, prodList, manufactoryContinent, productIdx, quantity) | |
1360 | - | let newMat = $t04920049313._1 | |
1361 | - | let newProd = $t04920049313._2 | |
1362 | - | let matSpent = $t04920049313._3 | |
1363 | - | let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), makeString_2C(newProd, "_")], ":") | |
1364 | - | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1365 | - | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpCraft, matSpent, MULT8)], nil)) | |
1366 | - | let feePart = fraction(quantity, MIN_USDT_FEE_DELIVERY, CRAFT_DELIVERY_COEFF) | |
1367 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1368 | - | let usdtSpentWithFee = (CRAFT_USDT_COST + fee) | |
1369 | - | if ((usdtSpentWithFee > amt)) | |
1370 | - | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(CRAFT_USDT_COST, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1371 | - | else { | |
1372 | - | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1373 | - | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1374 | - | else nil | |
1375 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1376 | - | $Tuple2((rest :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult)) | |
1377 | - | } | |
1378 | - | } | |
1379 | - | } | |
1380 | - | } | |
1381 | - | else throw("Strict value is not equal to itself.") | |
1382 | - | } | |
1383 | - | ||
1384 | - | ||
1385 | - | ||
1386 | - | @Callable(i) | |
1387 | - | func craftGoodsLandDelivery (productIdx,quantity,landAssetId,manufactoryContinent) = if (!(KS_ALLOW_DELIVERY)) | |
1388 | - | then throw("Delivery feature is turned off!") | |
1389 | - | else { | |
1390 | - | let prologResult = prolog() | |
1391 | - | if ((prologResult == prologResult)) | |
1392 | - | then if ((size(i.payments) != 1)) | |
1323 | + | func craftGoodsDuckDelivery (productIdx,quantity,manufactoryContinent) = { | |
1324 | + | let prologResult = prolog() | |
1325 | + | if ((prologResult == prologResult)) | |
1326 | + | then { | |
1327 | + | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1328 | + | if ((size(i.payments) != 1)) | |
1393 | 1329 | then throw("exactly 1 payment must be attached") | |
1394 | 1330 | else { | |
1395 | 1331 | let pmt = i.payments[0] | |
1399 | 1335 | else (value(pmt.assetId) != usdtAssetId)) | |
1400 | 1336 | then throw("USDT payments only!") | |
1401 | 1337 | else { | |
1402 | - | let user = i.caller | |
1403 | - | let addr = toString(user) | |
1404 | - | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1405 | - | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1406 | - | then throw((("NFT " + asset.name) + " is not staked")) | |
1338 | + | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1339 | + | let matList = split(currentPack[bpIdxMat], "_") | |
1340 | + | let prodList = if ((currentPack[bpIdxProd] == "")) | |
1341 | + | then nil | |
1342 | + | else split_4C(currentPack[bpIdxProd], "_") | |
1343 | + | let $t04868348796 = craftGoodsCommon(matList, prodList, manufactoryContinent, productIdx, quantity) | |
1344 | + | let newMat = $t04868348796._1 | |
1345 | + | let newProd = $t04868348796._2 | |
1346 | + | let matSpent = $t04868348796._3 | |
1347 | + | let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), makeString_2C(newProd, "_")], ":") | |
1348 | + | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1349 | + | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpCraft, matSpent, MULT8)], nil)) | |
1350 | + | let feePart = fraction(quantity, MIN_USDT_FEE_DELIVERY, CRAFT_DELIVERY_COEFF) | |
1351 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1352 | + | let usdtSpentWithFee = (CRAFT_USDT_COST + fee) | |
1353 | + | if ((usdtSpentWithFee > amt)) | |
1354 | + | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(CRAFT_USDT_COST, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1407 | 1355 | else { | |
1408 | - | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1409 | - | if ((owner != addr)) | |
1410 | - | then throw((LANDPREFIX + " is not yours")) | |
1411 | - | else { | |
1412 | - | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1413 | - | let currentWh = split_4C(wh, ":") | |
1414 | - | let matList = split(currentWh[whIdxMat], "_") | |
1415 | - | let prodList = if ((currentWh[whIdxProd] == "")) | |
1416 | - | then nil | |
1417 | - | else split_4C(currentWh[whIdxProd], "_") | |
1418 | - | let $t05155651669 = craftGoodsCommon(matList, prodList, manufactoryContinent, productIdx, quantity) | |
1419 | - | let newMat = $t05155651669._1 | |
1420 | - | let newProd = $t05155651669._2 | |
1421 | - | let matSpent = $t05155651669._3 | |
1422 | - | let whStr = makeString_2C([currentWh[whIdxLevels], currentWh[whIdxRes], makeString(newMat, "_"), makeString_2C(newProd, "_"), currentWh[whIdxLOFT]], ":") | |
1423 | - | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1424 | - | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpCraft, matSpent, MULT8)], nil)) | |
1425 | - | let feePart = fraction(quantity, MIN_USDT_FEE_DELIVERY, CRAFT_DELIVERY_COEFF) | |
1426 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1427 | - | let usdtSpentWithFee = (CRAFT_USDT_COST + fee) | |
1428 | - | if ((usdtSpentWithFee > amt)) | |
1429 | - | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(CRAFT_USDT_COST, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1430 | - | else { | |
1431 | - | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1432 | - | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1433 | - | else nil | |
1434 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1435 | - | $Tuple2((rest :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult)) | |
1436 | - | } | |
1437 | - | } | |
1356 | + | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1357 | + | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1358 | + | else nil | |
1359 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1360 | + | $Tuple2((rest :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult)) | |
1438 | 1361 | } | |
1439 | 1362 | } | |
1440 | 1363 | } | |
1441 | - | else throw("Strict value is not equal to itself.") | |
1442 | - | } | |
1364 | + | } | |
1365 | + | else throw("Strict value is not equal to itself.") | |
1366 | + | } | |
1367 | + | ||
1368 | + | ||
1369 | + | ||
1370 | + | @Callable(i) | |
1371 | + | func craftGoodsLandDelivery (productIdx,quantity,landAssetId,manufactoryContinent) = { | |
1372 | + | let prologResult = prolog() | |
1373 | + | if ((prologResult == prologResult)) | |
1374 | + | then if ((size(i.payments) != 1)) | |
1375 | + | then throw("exactly 1 payment must be attached") | |
1376 | + | else { | |
1377 | + | let pmt = i.payments[0] | |
1378 | + | let amt = pmt.amount | |
1379 | + | if (if (!(isDefined(pmt.assetId))) | |
1380 | + | then true | |
1381 | + | else (value(pmt.assetId) != usdtAssetId)) | |
1382 | + | then throw("USDT payments only!") | |
1383 | + | else { | |
1384 | + | let user = i.caller | |
1385 | + | let addr = toString(user) | |
1386 | + | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1387 | + | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1388 | + | then throw((("NFT " + asset.name) + " is not staked")) | |
1389 | + | else { | |
1390 | + | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1391 | + | if ((owner != addr)) | |
1392 | + | then throw((LANDPREFIX + " is not yours")) | |
1393 | + | else { | |
1394 | + | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1395 | + | let currentWh = split_4C(wh, ":") | |
1396 | + | let matList = split(currentWh[whIdxMat], "_") | |
1397 | + | let prodList = if ((currentWh[whIdxProd] == "")) | |
1398 | + | then nil | |
1399 | + | else split_4C(currentWh[whIdxProd], "_") | |
1400 | + | let $t05096251075 = craftGoodsCommon(matList, prodList, manufactoryContinent, productIdx, quantity) | |
1401 | + | let newMat = $t05096251075._1 | |
1402 | + | let newProd = $t05096251075._2 | |
1403 | + | let matSpent = $t05096251075._3 | |
1404 | + | let whStr = makeString_2C([currentWh[whIdxLevels], currentWh[whIdxRes], makeString(newMat, "_"), makeString_2C(newProd, "_"), currentWh[whIdxLOFT]], ":") | |
1405 | + | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1406 | + | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpCraft, matSpent, MULT8)], nil)) | |
1407 | + | let feePart = fraction(quantity, MIN_USDT_FEE_DELIVERY, CRAFT_DELIVERY_COEFF) | |
1408 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1409 | + | let usdtSpentWithFee = (CRAFT_USDT_COST + fee) | |
1410 | + | if ((usdtSpentWithFee > amt)) | |
1411 | + | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(CRAFT_USDT_COST, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1412 | + | else { | |
1413 | + | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1414 | + | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1415 | + | else nil | |
1416 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1417 | + | $Tuple2((rest :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult)) | |
1418 | + | } | |
1419 | + | } | |
1420 | + | } | |
1421 | + | } | |
1422 | + | } | |
1423 | + | else throw("Strict value is not equal to itself.") | |
1424 | + | } | |
1443 | 1425 | ||
1444 | 1426 | ||
1445 | 1427 | ||
1529 | 1511 | let bpProdList = if ((currentPack[bpIdxProd] == "")) | |
1530 | 1512 | then nil | |
1531 | 1513 | else split_4C(currentPack[bpIdxProd], "_") | |
1532 | - | let $ | |
1533 | - | let shopAction = $ | |
1534 | - | let newUserRes = $ | |
1535 | - | let newUserMat = $ | |
1536 | - | let newUserProd = $ | |
1537 | - | let usdWh2BpSaldo = $ | |
1538 | - | let usdBp2WhSaldo = $ | |
1539 | - | let xpAmount = $ | |
1540 | - | let shopLandOwner = $ | |
1541 | - | let shopWhSave = $ | |
1542 | - | let accStatsResult = $ | |
1514 | + | let $t05698857228 = acceptShopOrderCommon(shopLandAssetId, callerAddr, bpOrderStr, bpResList, bpMatList, bpProdList) | |
1515 | + | let shopAction = $t05698857228._1 | |
1516 | + | let newUserRes = $t05698857228._2 | |
1517 | + | let newUserMat = $t05698857228._3 | |
1518 | + | let newUserProd = $t05698857228._4 | |
1519 | + | let usdWh2BpSaldo = $t05698857228._5 | |
1520 | + | let usdBp2WhSaldo = $t05698857228._6 | |
1521 | + | let xpAmount = $t05698857228._7 | |
1522 | + | let shopLandOwner = $t05698857228._8 | |
1523 | + | let shopWhSave = $t05698857228._9 | |
1524 | + | let accStatsResult = $t05698857228._10 | |
1543 | 1525 | let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, 0)] | |
1544 | 1526 | let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, 0) | |
1545 | 1527 | let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString_2C(newUserProd, "_")], ":") | |
1554 | 1536 | ||
1555 | 1537 | ||
1556 | 1538 | @Callable(i) | |
1557 | - | func acceptShopOrderDuckDelivery (orderStr,shopLandAssetId) = if (!(KS_ALLOW_DELIVERY)) | |
1558 | - | then throw("Delivery feature is turned off!") | |
1559 | - | else { | |
1560 | - | let prologResult = prolog() | |
1561 | - | if ((prologResult == prologResult)) | |
1562 | - | then { | |
1563 | - | let caller = i.originCaller | |
1564 | - | let callerAddr = toString(caller) | |
1565 | - | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(callerAddr)), "You don't have a duck staked") | |
1566 | - | let bpKey = keyBackpackByDuck(duckAssetId) | |
1567 | - | let currentPack = getBackpack(bpKey) | |
1568 | - | let bpResList = split(currentPack[bpIdxRes], "_") | |
1569 | - | let bpMatList = split(currentPack[bpIdxMat], "_") | |
1570 | - | let bpProdList = if ((currentPack[bpIdxProd] == "")) | |
1571 | - | then nil | |
1572 | - | else split_4C(currentPack[bpIdxProd], "_") | |
1573 | - | let $t05926459502 = acceptShopOrderCommon(shopLandAssetId, callerAddr, orderStr, bpResList, bpMatList, bpProdList) | |
1574 | - | let shopAction = $t05926459502._1 | |
1575 | - | let newUserRes = $t05926459502._2 | |
1576 | - | let newUserMat = $t05926459502._3 | |
1577 | - | let newUserProd = $t05926459502._4 | |
1578 | - | let usdWh2BpSaldo = $t05926459502._5 | |
1579 | - | let usdBp2WhSaldo = $t05926459502._6 | |
1580 | - | let xpAmount = $t05926459502._7 | |
1581 | - | let shopLandOwner = $t05926459502._8 | |
1582 | - | let shopWhSave = $t05926459502._9 | |
1583 | - | let accStatsResult = $t05926459502._10 | |
1584 | - | let deliveryFeePart = fraction((usdBp2WhSaldo + usdWh2BpSaldo), DELIVERY_FEE, MULT6) | |
1585 | - | let deliveryFee = max([deliveryFeePart, MIN_USDT_FEE_DELIVERY]) | |
1586 | - | let spentFee = fraction(deliveryFee, usdBp2WhSaldo, (usdBp2WhSaldo + usdWh2BpSaldo)) | |
1587 | - | let receivedFee = (deliveryFee - spentFee) | |
1588 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1589 | - | let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, receivedFee)] | |
1590 | - | let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, spentFee) | |
1591 | - | let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString_2C(newUserProd, "_")], ":") | |
1592 | - | let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil)) | |
1593 | - | let duckStatsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpShop, xpAmount, MULT8)], nil)) | |
1594 | - | $Tuple2(((actions1 ++ actions2) :+ IntegerEntry(deliveryFundKey, (fundTotal + deliveryFee))), $Tuple5(prologResult, shopWhSave, bpSave, duckStatsResult, accStatsResult)) | |
1595 | - | } | |
1596 | - | else throw("Strict value is not equal to itself.") | |
1597 | - | } | |
1539 | + | func acceptShopOrderDuckDelivery (orderStr,shopLandAssetId) = { | |
1540 | + | let prologResult = prolog() | |
1541 | + | if ((prologResult == prologResult)) | |
1542 | + | then { | |
1543 | + | let caller = i.originCaller | |
1544 | + | let callerAddr = toString(caller) | |
1545 | + | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(callerAddr)), "You don't have a duck staked") | |
1546 | + | let bpKey = keyBackpackByDuck(duckAssetId) | |
1547 | + | let currentPack = getBackpack(bpKey) | |
1548 | + | let bpResList = split(currentPack[bpIdxRes], "_") | |
1549 | + | let bpMatList = split(currentPack[bpIdxMat], "_") | |
1550 | + | let bpProdList = if ((currentPack[bpIdxProd] == "")) | |
1551 | + | then nil | |
1552 | + | else split_4C(currentPack[bpIdxProd], "_") | |
1553 | + | let $t05859358831 = acceptShopOrderCommon(shopLandAssetId, callerAddr, orderStr, bpResList, bpMatList, bpProdList) | |
1554 | + | let shopAction = $t05859358831._1 | |
1555 | + | let newUserRes = $t05859358831._2 | |
1556 | + | let newUserMat = $t05859358831._3 | |
1557 | + | let newUserProd = $t05859358831._4 | |
1558 | + | let usdWh2BpSaldo = $t05859358831._5 | |
1559 | + | let usdBp2WhSaldo = $t05859358831._6 | |
1560 | + | let xpAmount = $t05859358831._7 | |
1561 | + | let shopLandOwner = $t05859358831._8 | |
1562 | + | let shopWhSave = $t05859358831._9 | |
1563 | + | let accStatsResult = $t05859358831._10 | |
1564 | + | let deliveryFeePart = fraction((usdBp2WhSaldo + usdWh2BpSaldo), DELIVERY_FEE, MULT6) | |
1565 | + | let deliveryFee = max([deliveryFeePart, MIN_USDT_FEE_DELIVERY]) | |
1566 | + | let spentFee = fraction(deliveryFee, usdBp2WhSaldo, (usdBp2WhSaldo + usdWh2BpSaldo)) | |
1567 | + | let receivedFee = (deliveryFee - spentFee) | |
1568 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1569 | + | let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, receivedFee)] | |
1570 | + | let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, spentFee) | |
1571 | + | let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString_2C(newUserProd, "_")], ":") | |
1572 | + | let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil)) | |
1573 | + | let duckStatsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpShop, xpAmount, MULT8)], nil)) | |
1574 | + | $Tuple2(((actions1 ++ actions2) :+ IntegerEntry(deliveryFundKey, (fundTotal + deliveryFee))), $Tuple5(prologResult, shopWhSave, bpSave, duckStatsResult, accStatsResult)) | |
1575 | + | } | |
1576 | + | else throw("Strict value is not equal to itself.") | |
1577 | + | } | |
1598 | 1578 | ||
1599 | 1579 | ||
1600 | 1580 | ||
1601 | 1581 | @Callable(i) | |
1602 | - | func acceptShopOrderLandDelivery (orderStr,shopLandAssetId,myLandAssetId) = if (!(KS_ALLOW_DELIVERY)) | |
1603 | - | then throw("Delivery feature is turned off!") | |
1604 | - | else { | |
1605 | - | let prologResult = prolog() | |
1606 | - | if ((prologResult == prologResult)) | |
1607 | - | then { | |
1608 | - | let caller = i.originCaller | |
1609 | - | let callerAddr = toString(caller) | |
1610 | - | let asset = value(assetInfo(fromBase58String(myLandAssetId))) | |
1611 | - | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(myLandAssetId))))) | |
1612 | - | then throw((("NFT " + asset.name) + " is not staked")) | |
1613 | - | else { | |
1614 | - | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(myLandAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1615 | - | if ((owner != callerAddr)) | |
1616 | - | then throw((LANDPREFIX + " is not yours")) | |
1617 | - | else { | |
1618 | - | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [myLandAssetId], nil)) | |
1619 | - | let currentWh = split_4C(wh, ":") | |
1620 | - | let resList = split(currentWh[whIdxRes], "_") | |
1621 | - | let matList = split(currentWh[whIdxMat], "_") | |
1622 | - | let prodList = if ((currentWh[whIdxProd] == "")) | |
1623 | - | then nil | |
1624 | - | else split_4C(currentWh[whIdxProd], "_") | |
1625 | - | let $t06170061932 = acceptShopOrderCommon(shopLandAssetId, callerAddr, orderStr, resList, matList, prodList) | |
1626 | - | let shopAction = $t06170061932._1 | |
1627 | - | let newUserRes = $t06170061932._2 | |
1628 | - | let newUserMat = $t06170061932._3 | |
1629 | - | let newUserProd = $t06170061932._4 | |
1630 | - | let usdWh2BpSaldo = $t06170061932._5 | |
1631 | - | let usdBp2WhSaldo = $t06170061932._6 | |
1632 | - | let xpAmount = $t06170061932._7 | |
1633 | - | let shopLandOwner = $t06170061932._8 | |
1634 | - | let shopWhSave = $t06170061932._9 | |
1635 | - | let accStatsResult = $t06170061932._10 | |
1636 | - | let deliveryFeePart = fraction((usdBp2WhSaldo + usdWh2BpSaldo), DELIVERY_FEE, MULT6) | |
1637 | - | let deliveryFee = max([deliveryFeePart, MIN_USDT_FEE_DELIVERY]) | |
1638 | - | let spentFee = fraction(deliveryFee, usdBp2WhSaldo, (usdBp2WhSaldo + usdWh2BpSaldo)) | |
1639 | - | let receivedFee = (deliveryFee - spentFee) | |
1640 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1641 | - | let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, receivedFee)] | |
1642 | - | let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, spentFee) | |
1643 | - | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString(newUserProd, "_"), currentWh[whIdxLOFT]], ":") | |
1644 | - | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, myLandAssetId], nil)) | |
1645 | - | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [callerAddr, fraction(xpShop, xpAmount, MULT8)], nil)) | |
1646 | - | $Tuple2(((actions1 ++ actions2) :+ IntegerEntry(deliveryFundKey, (fundTotal + deliveryFee))), $Tuple5(prologResult, shopWhSave, whSave, statsResult, accStatsResult)) | |
1647 | - | } | |
1648 | - | } | |
1649 | - | } | |
1650 | - | else throw("Strict value is not equal to itself.") | |
1651 | - | } | |
1582 | + | func acceptShopOrderLandDelivery (orderStr,shopLandAssetId,myLandAssetId) = { | |
1583 | + | let prologResult = prolog() | |
1584 | + | if ((prologResult == prologResult)) | |
1585 | + | then { | |
1586 | + | let caller = i.originCaller | |
1587 | + | let callerAddr = toString(caller) | |
1588 | + | let asset = value(assetInfo(fromBase58String(myLandAssetId))) | |
1589 | + | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(myLandAssetId))))) | |
1590 | + | then throw((("NFT " + asset.name) + " is not staked")) | |
1591 | + | else { | |
1592 | + | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(myLandAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1593 | + | if ((owner != callerAddr)) | |
1594 | + | then throw((LANDPREFIX + " is not yours")) | |
1595 | + | else { | |
1596 | + | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [myLandAssetId], nil)) | |
1597 | + | let currentWh = split_4C(wh, ":") | |
1598 | + | let resList = split(currentWh[whIdxRes], "_") | |
1599 | + | let matList = split(currentWh[whIdxMat], "_") | |
1600 | + | let prodList = if ((currentWh[whIdxProd] == "")) | |
1601 | + | then nil | |
1602 | + | else split_4C(currentWh[whIdxProd], "_") | |
1603 | + | let $t06095261184 = acceptShopOrderCommon(shopLandAssetId, callerAddr, orderStr, resList, matList, prodList) | |
1604 | + | let shopAction = $t06095261184._1 | |
1605 | + | let newUserRes = $t06095261184._2 | |
1606 | + | let newUserMat = $t06095261184._3 | |
1607 | + | let newUserProd = $t06095261184._4 | |
1608 | + | let usdWh2BpSaldo = $t06095261184._5 | |
1609 | + | let usdBp2WhSaldo = $t06095261184._6 | |
1610 | + | let xpAmount = $t06095261184._7 | |
1611 | + | let shopLandOwner = $t06095261184._8 | |
1612 | + | let shopWhSave = $t06095261184._9 | |
1613 | + | let accStatsResult = $t06095261184._10 | |
1614 | + | let deliveryFeePart = fraction((usdBp2WhSaldo + usdWh2BpSaldo), DELIVERY_FEE, MULT6) | |
1615 | + | let deliveryFee = max([deliveryFeePart, MIN_USDT_FEE_DELIVERY]) | |
1616 | + | let spentFee = fraction(deliveryFee, usdBp2WhSaldo, (usdBp2WhSaldo + usdWh2BpSaldo)) | |
1617 | + | let receivedFee = (deliveryFee - spentFee) | |
1618 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1619 | + | let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, receivedFee)] | |
1620 | + | let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, spentFee) | |
1621 | + | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString(newUserProd, "_"), currentWh[whIdxLOFT]], ":") | |
1622 | + | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, myLandAssetId], nil)) | |
1623 | + | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [callerAddr, fraction(xpShop, xpAmount, MULT8)], nil)) | |
1624 | + | $Tuple2(((actions1 ++ actions2) :+ IntegerEntry(deliveryFundKey, (fundTotal + deliveryFee))), $Tuple5(prologResult, shopWhSave, whSave, statsResult, accStatsResult)) | |
1625 | + | } | |
1626 | + | } | |
1627 | + | } | |
1628 | + | else throw("Strict value is not equal to itself.") | |
1629 | + | } | |
1652 | 1630 | ||
1653 | 1631 | ||
1654 | 1632 |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 6 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let xpTrade = 10000 | |
5 | 5 | ||
6 | 6 | let xpCraft = 10000 | |
7 | 7 | ||
8 | 8 | let xpSellToEs = 10000 | |
9 | 9 | ||
10 | 10 | let xpShop = 10000 | |
11 | 11 | ||
12 | 12 | let LANDPREFIX = "LAND" | |
13 | 13 | ||
14 | 14 | let NUMRES = 6 | |
15 | 15 | ||
16 | 16 | let DEFAULTLOCATION = "Africa_F_Africa" | |
17 | 17 | ||
18 | 18 | let RESOURCEPRICEMIN = 39637 | |
19 | 19 | ||
20 | 20 | let ESMAXPACKAGES = 10 | |
21 | 21 | ||
22 | 22 | let ESBUYCOEF = 4 | |
23 | 23 | ||
24 | 24 | let MIN_USDT_FEE_DELIVERY = 50000 | |
25 | 25 | ||
26 | 26 | let MIN_USDT_FEE_DELIVERY15 = 75000 | |
27 | 27 | ||
28 | 28 | let CRAFT_USDT_COST = 1000000 | |
29 | 29 | ||
30 | 30 | let CRAFT_DELIVERY_COEFF = 10 | |
31 | 31 | ||
32 | 32 | let USDT2ACRES_MULTIPLIER = 10 | |
33 | 33 | ||
34 | 34 | let resTypes = ["Oil", "Ore", "Wood", "Sand", "Clay", "Organic"] | |
35 | 35 | ||
36 | 36 | let matTypes = ["Fuel", "Metal", "Plank", "Glass", "Plastic", "Protein"] | |
37 | 37 | ||
38 | 38 | 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"] | |
39 | 39 | ||
40 | 40 | let continents = ["Americas", "Europe", "Asia", "Africa", "Oceania"] | |
41 | 41 | ||
42 | 42 | let COEFF2MAT = 10000000 | |
43 | 43 | ||
44 | 44 | 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_"] | |
45 | 45 | ||
46 | 46 | let rIdxCoeff = 6 | |
47 | 47 | ||
48 | 48 | let rIdxContinent = 7 | |
49 | 49 | ||
50 | 50 | let RECIPESIZE = 11 | |
51 | 51 | ||
52 | 52 | let PRODUCTPKGSIZE = 10 | |
53 | 53 | ||
54 | 54 | let whIdxLevels = 0 | |
55 | 55 | ||
56 | 56 | let whIdxRes = 1 | |
57 | 57 | ||
58 | 58 | let whIdxMat = 2 | |
59 | 59 | ||
60 | 60 | let whIdxProd = 3 | |
61 | 61 | ||
62 | 62 | let whIdxLOFT = 4 | |
63 | 63 | ||
64 | 64 | let volLocked = 0 | |
65 | 65 | ||
66 | 66 | let volTotal = 3 | |
67 | 67 | ||
68 | 68 | let bpIdxLevel = 0 | |
69 | 69 | ||
70 | 70 | let bpIdxRes = 1 | |
71 | 71 | ||
72 | 72 | let bpIdxMat = 2 | |
73 | 73 | ||
74 | 74 | let bpIdxProd = 3 | |
75 | 75 | ||
76 | 76 | let locIdxContinent = 0 | |
77 | 77 | ||
78 | 78 | let locIdxType = 1 | |
79 | 79 | ||
80 | 80 | let locIdxId = 2 | |
81 | 81 | ||
82 | 82 | func keyLandAssetIdToOwner (assetId) = ("no_" + assetId) | |
83 | 83 | ||
84 | 84 | ||
85 | 85 | func keyStakedTimeByAssetId (assetId) = ("st_" + assetId) | |
86 | 86 | ||
87 | 87 | ||
88 | 88 | func keyAddressRefBy (addr) = ("accRefBy_" + addr) | |
89 | 89 | ||
90 | 90 | ||
91 | 91 | func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr) | |
92 | 92 | ||
93 | 93 | ||
94 | 94 | func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId) | |
95 | 95 | ||
96 | 96 | ||
97 | 97 | func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId) | |
98 | 98 | ||
99 | 99 | ||
100 | 100 | func keyOrderByLand (landAssetId) = ("landOrder_" + landAssetId) | |
101 | 101 | ||
102 | 102 | ||
103 | 103 | func keyEsWarehouse () = "emergencyWarehouseProducts" | |
104 | 104 | ||
105 | 105 | ||
106 | 106 | let deliveryFundKey = "deliveryFund" | |
107 | 107 | ||
108 | 108 | let deliveryLockedKey = "deliveryLocked" | |
109 | 109 | ||
110 | 110 | func getRecipeMaterials (recipe) = (parseIntValue(recipe[rIdxCoeff]) * COEFF2MAT) | |
111 | 111 | ||
112 | - | ||
113 | - | let KS_ALLOW_DELIVERY = true | |
114 | 112 | ||
115 | 113 | let chain = take(drop(this.bytes, 1), 1) | |
116 | 114 | ||
117 | 115 | let usdtAssetId = match chain { | |
118 | 116 | case _ => | |
119 | 117 | if ((base58'2W' == $match0)) | |
120 | 118 | then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi' | |
121 | 119 | else if ((base58'2T' == $match0)) | |
122 | 120 | then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63' | |
123 | 121 | else throw("Unknown chain") | |
124 | 122 | } | |
125 | 123 | ||
126 | 124 | let defaultRestAddressStr = match chain { | |
127 | 125 | case _ => | |
128 | 126 | if ((base58'2W' == $match0)) | |
129 | 127 | then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv" | |
130 | 128 | else if ((base58'2T' == $match0)) | |
131 | 129 | then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy" | |
132 | 130 | else throw("Unknown chain") | |
133 | 131 | } | |
134 | 132 | ||
135 | 133 | let SEP = "__" | |
136 | 134 | ||
137 | 135 | let MULT5 = 100000 | |
138 | 136 | ||
139 | 137 | let MULT6 = 1000000 | |
140 | 138 | ||
141 | 139 | let MULT8 = 100000000 | |
142 | 140 | ||
143 | 141 | let MULT10 = 10000000000 | |
144 | 142 | ||
145 | 143 | let MINSHOPPAYMENT = 100000 | |
146 | 144 | ||
147 | 145 | let ITER6 = [0, 1, 2, 3, 4, 5] | |
148 | 146 | ||
149 | 147 | func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], "")) | |
150 | 148 | ||
151 | 149 | ||
152 | 150 | let IdxCfgStakingDapp = 1 | |
153 | 151 | ||
154 | 152 | let IdxCfgInvestFundDapp = 6 | |
155 | 153 | ||
156 | 154 | let IdxCfgAcresDapp = 8 | |
157 | 155 | ||
158 | 156 | func keyRestCfg () = "%s__restConfig" | |
159 | 157 | ||
160 | 158 | ||
161 | 159 | func keyRestAddress () = "%s__restAddr" | |
162 | 160 | ||
163 | 161 | ||
164 | 162 | func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP) | |
165 | 163 | ||
166 | 164 | ||
167 | 165 | func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx))) | |
168 | 166 | ||
169 | 167 | ||
170 | 168 | let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr)) | |
171 | 169 | ||
172 | 170 | let restCfg = readRestCfgOrFail(restContract) | |
173 | 171 | ||
174 | 172 | let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp) | |
175 | 173 | ||
176 | 174 | let investFundContract = getContractAddressOrFail(restCfg, IdxCfgInvestFundDapp) | |
177 | 175 | ||
178 | 176 | let acresContract = getContractAddressOrFail(restCfg, IdxCfgAcresDapp) | |
179 | 177 | ||
180 | 178 | func asString (v) = match v { | |
181 | 179 | case s: String => | |
182 | 180 | s | |
183 | 181 | case _ => | |
184 | 182 | throw("fail to cast into String") | |
185 | 183 | } | |
186 | 184 | ||
187 | 185 | ||
188 | 186 | func asInt (v) = match v { | |
189 | 187 | case n: Int => | |
190 | 188 | n | |
191 | 189 | case _ => | |
192 | 190 | throw("fail to cast into Int") | |
193 | 191 | } | |
194 | 192 | ||
195 | 193 | ||
196 | 194 | func keyBlocked () = "contractsBlocked" | |
197 | 195 | ||
198 | 196 | ||
199 | 197 | func fixedPoint (val,decimals) = { | |
200 | 198 | let tenPow = pow(10, 0, decimals, 0, 0, DOWN) | |
201 | 199 | let lowPart = toString((val % tenPow)) | |
202 | 200 | let zeroes = drop(toString(tenPow), (1 + size(lowPart))) | |
203 | 201 | (((toString((val / tenPow)) + ".") + zeroes) + lowPart) | |
204 | 202 | } | |
205 | 203 | ||
206 | 204 | ||
207 | 205 | let FACTORYMAXWAREHOUSE = 10000000000 | |
208 | 206 | ||
209 | 207 | let SELLMULTIPLIER = 200 | |
210 | 208 | ||
211 | 209 | let BUYMULTIPLIER = 300 | |
212 | 210 | ||
213 | 211 | let AUCTIONFEE = 10000 | |
214 | 212 | ||
215 | 213 | let DELIVERY_FEE = 10000 | |
216 | 214 | ||
217 | 215 | let DELIVERY_FEE15 = 15000 | |
218 | 216 | ||
219 | 217 | func keyFactoryWarehouseByIdAndType (factoryId,resType) = ((("factoryWhByContinentAndRes_" + factoryId) + "_") + toString(resType)) | |
220 | 218 | ||
221 | 219 | ||
222 | 220 | let ordIdxRes = 0 | |
223 | 221 | ||
224 | 222 | let ordIdxMat = 1 | |
225 | 223 | ||
226 | 224 | let ordIdxProd = 2 | |
227 | 225 | ||
228 | 226 | func getOrder (ordKey) = { | |
229 | 227 | 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:"), ":") | |
230 | 228 | [if ((size(split(p[ordIdxRes], "_")) == NUMRES)) | |
231 | 229 | then p[ordIdxRes] | |
232 | 230 | else "0@0_0@0_0@0_0@0_0@0_0@0", if ((size(split(p[ordIdxMat], "_")) == NUMRES)) | |
233 | 231 | then p[ordIdxMat] | |
234 | 232 | else "0@0_0@0_0@0_0@0_0@0_0@0", p[ordIdxProd]] | |
235 | 233 | } | |
236 | 234 | ||
237 | 235 | ||
238 | 236 | func toVolume (amount,pkgSize,isProduct) = if (isProduct) | |
239 | 237 | then { | |
240 | 238 | let pkgs = if ((amount >= 0)) | |
241 | 239 | then (((amount + pkgSize) - 1) / pkgSize) | |
242 | 240 | else -((((-(amount) + pkgSize) - 1) / pkgSize)) | |
243 | 241 | (pkgs * MULT8) | |
244 | 242 | } | |
245 | 243 | else amount | |
246 | 244 | ||
247 | 245 | ||
248 | 246 | func sellInternal (locId,resType,amount,minPrice) = { | |
249 | 247 | let whKey = keyFactoryWarehouseByIdAndType(locId, resType) | |
250 | 248 | let w0 = valueOrElse(getInteger(whKey), 0) | |
251 | 249 | let r0 = if ((w0 > FACTORYMAXWAREHOUSE)) | |
252 | 250 | then 0 | |
253 | 251 | else if (((w0 + amount) > FACTORYMAXWAREHOUSE)) | |
254 | 252 | then (FACTORYMAXWAREHOUSE - w0) | |
255 | 253 | else amount | |
256 | 254 | let usdtReceived = (fraction(r0, ((SELLMULTIPLIER * RESOURCEPRICEMIN) - fraction(((100 * w0) + (50 * r0)), RESOURCEPRICEMIN, FACTORYMAXWAREHOUSE)), MULT10) + fraction((amount - r0), RESOURCEPRICEMIN, MULT8)) | |
257 | 255 | let min99 = (minPrice - (minPrice / 100)) | |
258 | 256 | if (((min99 * amount) > (usdtReceived * MULT8))) | |
259 | 257 | then throw((((((((((("Actual price = " + toString(usdtReceived)) + " / ") + toString(amount)) + " < minPrice = ") + toString(minPrice)) + ", (") + locId) + ", ") + resTypes[resType]) + ")")) | |
260 | 258 | else $Tuple2(IntegerEntry(whKey, (w0 + amount)), usdtReceived) | |
261 | 259 | } | |
262 | 260 | ||
263 | 261 | ||
264 | 262 | func buyInternal (locId,matType,amount,maxPrice) = { | |
265 | 263 | let whKey = keyFactoryWarehouseByIdAndType(locId, matType) | |
266 | 264 | let w0 = valueOrElse(getInteger(whKey), 0) | |
267 | 265 | let m1 = if ((w0 > FACTORYMAXWAREHOUSE)) | |
268 | 266 | then min([amount, (w0 - FACTORYMAXWAREHOUSE)]) | |
269 | 267 | else 0 | |
270 | 268 | let m0 = min([w0, (amount - m1)]) | |
271 | 269 | let m = (m0 + m1) | |
272 | 270 | let w0min = min([w0, FACTORYMAXWAREHOUSE]) | |
273 | 271 | let usdtSpent = (fraction(m0, ((BUYMULTIPLIER * RESOURCEPRICEMIN) - fraction(((100 * w0min) - (50 * m0)), RESOURCEPRICEMIN, FACTORYMAXWAREHOUSE)), MULT10) + fraction(m1, (2 * RESOURCEPRICEMIN), MULT8)) | |
274 | 272 | let max101 = (maxPrice + (maxPrice / 100)) | |
275 | 273 | if (((usdtSpent * MULT8) > (max101 * m))) | |
276 | 274 | then throw((((((((((("Actual price = " + toString(usdtSpent)) + " / ") + toString(m)) + " > maxPrice = ") + toString(maxPrice)) + ", (") + locId) + ", ") + matTypes[matType]) + ")")) | |
277 | 275 | else $Tuple3(IntegerEntry(whKey, (w0 - m)), usdtSpent, m) | |
278 | 276 | } | |
279 | 277 | ||
280 | 278 | ||
281 | 279 | func getBackpack (bpKey) = { | |
282 | 280 | let p = split_4C(valueOrElse(getString(stakingContract, bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":") | |
283 | 281 | [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES)) | |
284 | 282 | then p[bpIdxRes] | |
285 | 283 | else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES)) | |
286 | 284 | then p[bpIdxMat] | |
287 | 285 | else "0_0_0_0_0_0", p[bpIdxProd]] | |
288 | 286 | } | |
289 | 287 | ||
290 | 288 | ||
291 | 289 | func checkBlocked () = if (valueOrElse(getBoolean(stakingContract, keyBlocked()), false)) | |
292 | 290 | then throw("Contracts are under maintenance") | |
293 | 291 | else unit | |
294 | 292 | ||
295 | 293 | ||
296 | 294 | func prolog () = asInt(reentrantInvoke(stakingContract, "saveLastTx", nil, nil)) | |
297 | 295 | ||
298 | 296 | ||
299 | 297 | func setCommon (acc,ignoredIterator) = { | |
300 | 298 | let j = acc._1 | |
301 | 299 | let item = if ((size(acc._10) > j)) | |
302 | 300 | then acc._10[j] | |
303 | 301 | else "0@0" | |
304 | 302 | let isProd = acc._8 | |
305 | 303 | let itemParts = split(item, "@") | |
306 | 304 | if ((size(itemParts) != 2)) | |
307 | 305 | then throw("Incorrect order format, should be amount@price") | |
308 | 306 | else { | |
309 | 307 | let newOrdAm = parseIntValue(itemParts[0]) | |
310 | 308 | let newOrdPr = parseIntValue(itemParts[1]) | |
311 | 309 | let newOrdUsd = if (isProd) | |
312 | 310 | then (newOrdAm * newOrdPr) | |
313 | 311 | else fraction(newOrdAm, newOrdPr, MULT8) | |
314 | 312 | let newOrdVol = toVolume(newOrdAm, PRODUCTPKGSIZE, isProd) | |
315 | 313 | let whInit = if ((size(acc._6) > j)) | |
316 | 314 | then parseIntValue(acc._6[j]) | |
317 | 315 | else 0 | |
318 | 316 | let curOrdParts = split(if ((size(acc._7) > j)) | |
319 | 317 | then acc._7[j] | |
320 | 318 | else "0@0", "@") | |
321 | 319 | let curOrdAm = parseIntValue(curOrdParts[0]) | |
322 | 320 | let curOrdPr = parseIntValue(curOrdParts[1]) | |
323 | 321 | if (if ((0 > curOrdPr)) | |
324 | 322 | then true | |
325 | 323 | else (0 > newOrdPr)) | |
326 | 324 | then throw("Price can't be negative") | |
327 | 325 | else { | |
328 | 326 | let curOrdUsd = if (isProd) | |
329 | 327 | then (curOrdAm * curOrdPr) | |
330 | 328 | else fraction(curOrdAm, curOrdPr, MULT8) | |
331 | 329 | if ((newOrdAm == 0)) | |
332 | 330 | then if ((curOrdAm > 0)) | |
333 | 331 | 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) | |
334 | 332 | 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) | |
335 | 333 | else if ((newOrdAm > 0)) | |
336 | 334 | then if ((0 > curOrdAm)) | |
337 | 335 | 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) | |
338 | 336 | 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) | |
339 | 337 | else if ((0 > curOrdAm)) | |
340 | 338 | then { | |
341 | 339 | let amDiff = (curOrdAm - newOrdAm) | |
342 | 340 | if ((0 > (whInit - amDiff))) | |
343 | 341 | then throw((((("Attempt to take " + toString(amDiff)) + " from warehouse, but only ") + toString(whInit)) + " available")) | |
344 | 342 | 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) | |
345 | 343 | } | |
346 | 344 | else if ((0 > (whInit + newOrdAm))) | |
347 | 345 | then throw((((("Attempt to take " + toString(-(newOrdAm))) + " from warehouse, but only ") + toString(whInit)) + " available")) | |
348 | 346 | 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) | |
349 | 347 | } | |
350 | 348 | } | |
351 | 349 | } | |
352 | 350 | ||
353 | 351 | ||
354 | 352 | func setInternal (currentWh,currentOrd,newOrd) = { | |
355 | 353 | let currWhRes = split(currentWh[whIdxRes], "_") | |
356 | 354 | let currWhMat = split(currentWh[whIdxMat], "_") | |
357 | 355 | let currWhProd = if ((currentWh[whIdxProd] == "")) | |
358 | 356 | then nil | |
359 | 357 | else split_4C(currentWh[whIdxProd], "_") | |
360 | 358 | let currentOrdRes = split(currentOrd[ordIdxRes], "_") | |
361 | 359 | let currentOrdMat = split(currentOrd[ordIdxMat], "_") | |
362 | 360 | let currentOrdProd = if ((currentOrd[ordIdxProd] == "")) | |
363 | 361 | then nil | |
364 | 362 | else split_4C(currentOrd[ordIdxProd], "_") | |
365 | 363 | if ((size(newOrd) != 3)) | |
366 | 364 | then throw("newOrderStr should contain exactly 2 ':' separators") | |
367 | 365 | else { | |
368 | 366 | let resParts = split(newOrd[0], "_") | |
369 | 367 | let matParts = split(newOrd[1], "_") | |
370 | 368 | let prodParts = if ((newOrd[2] == "")) | |
371 | 369 | then nil | |
372 | 370 | else split_4C(newOrd[2], "_") | |
373 | 371 | if ((size(resParts) != NUMRES)) | |
374 | 372 | then throw("All 6 resources should be passed") | |
375 | 373 | else if ((size(matParts) != NUMRES)) | |
376 | 374 | then throw("All 6 materials should be passed") | |
377 | 375 | else { | |
378 | 376 | let r = { | |
379 | 377 | let $l = resTypes | |
380 | 378 | let $s = size($l) | |
381 | 379 | let $acc0 = $Tuple10(0, nil, 0, 0, 0, currWhRes, currentOrdRes, false, 0, resParts) | |
382 | 380 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
383 | 381 | then $a | |
384 | 382 | else setCommon($a, $l[$i]) | |
385 | 383 | ||
386 | 384 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
387 | 385 | then $a | |
388 | 386 | else throw("List size exceeds 6") | |
389 | 387 | ||
390 | 388 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
391 | 389 | } | |
392 | 390 | let m = { | |
393 | 391 | let $l = matTypes | |
394 | 392 | let $s = size($l) | |
395 | 393 | let $acc0 = $Tuple10(0, nil, r._3, r._4, r._5, currWhMat, currentOrdMat, false, r._9, matParts) | |
396 | 394 | func $f1_1 ($a,$i) = if (($i >= $s)) | |
397 | 395 | then $a | |
398 | 396 | else setCommon($a, $l[$i]) | |
399 | 397 | ||
400 | 398 | func $f1_2 ($a,$i) = if (($i >= $s)) | |
401 | 399 | then $a | |
402 | 400 | else throw("List size exceeds 6") | |
403 | 401 | ||
404 | 402 | $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
405 | 403 | } | |
406 | 404 | let p = { | |
407 | 405 | let $l = prodTypes | |
408 | 406 | let $s = size($l) | |
409 | 407 | let $acc0 = $Tuple10(0, nil, m._3, m._4, m._5, currWhProd, currentOrdProd, true, m._9, prodParts) | |
410 | 408 | func $f2_1 ($a,$i) = if (($i >= $s)) | |
411 | 409 | then $a | |
412 | 410 | else setCommon($a, $l[$i]) | |
413 | 411 | ||
414 | 412 | func $f2_2 ($a,$i) = if (($i >= $s)) | |
415 | 413 | then $a | |
416 | 414 | else throw("List size exceeds 50") | |
417 | 415 | ||
418 | 416 | $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) | |
419 | 417 | } | |
420 | 418 | $Tuple7(r._2, m._2, p._2, p._3, p._4, p._5, p._9) | |
421 | 419 | } | |
422 | 420 | } | |
423 | 421 | } | |
424 | 422 | ||
425 | 423 | ||
426 | 424 | func acceptCommon (acc,bpOrdItem) = { | |
427 | 425 | let j = acc._7 | |
428 | 426 | let isProd = acc._12 | |
429 | 427 | let bpOrdParts = split(bpOrdItem, "@") | |
430 | 428 | if ((size(bpOrdParts) != 2)) | |
431 | 429 | then throw("Incorrect order format, should be amount@price") | |
432 | 430 | else { | |
433 | 431 | let bpOrdAm = parseIntValue(bpOrdParts[0]) | |
434 | 432 | let bpOrdPr = parseIntValue(bpOrdParts[1]) | |
435 | 433 | if ((0 > bpOrdPr)) | |
436 | 434 | then throw("Price can't be negative") | |
437 | 435 | else { | |
438 | 436 | let bpOrdUsd = if (isProd) | |
439 | 437 | then (bpOrdAm * bpOrdPr) | |
440 | 438 | else fraction(bpOrdAm, bpOrdPr, MULT8) | |
441 | 439 | let bpInit = if ((size(acc._8) > j)) | |
442 | 440 | then parseIntValue(acc._8[j]) | |
443 | 441 | else 0 | |
444 | 442 | let whInit = if ((size(acc._9) > j)) | |
445 | 443 | then parseIntValue(acc._9[j]) | |
446 | 444 | else 0 | |
447 | 445 | let whOrdInit = if ((size(acc._10) > j)) | |
448 | 446 | then acc._10[j] | |
449 | 447 | else "0@0" | |
450 | 448 | let whOrdParts = split(whOrdInit, "@") | |
451 | 449 | let whOrdAm = parseIntValue(whOrdParts[0]) | |
452 | 450 | let whOrdPr = parseIntValue(whOrdParts[1]) | |
453 | 451 | if (if ((bpOrdAm != 0)) | |
454 | 452 | then (bpOrdPr != whOrdPr) | |
455 | 453 | else false) | |
456 | 454 | then throw(((((("Prices of " + acc._11[j]) + " don't match! WH price=") + toString(whOrdPr)) + ", your price=") + toString(bpOrdPr))) | |
457 | 455 | else { | |
458 | 456 | let whOrdUsd = if (isProd) | |
459 | 457 | then (whOrdAm * whOrdPr) | |
460 | 458 | else fraction(whOrdAm, whOrdPr, MULT8) | |
461 | 459 | let deltaVol = toVolume(bpOrdAm, PRODUCTPKGSIZE, isProd) | |
462 | 460 | if ((bpOrdAm == 0)) | |
463 | 461 | 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) | |
464 | 462 | else if ((bpOrdAm > 0)) | |
465 | 463 | then if ((0 > whOrdAm)) | |
466 | 464 | then if ((bpOrdAm > -(whOrdAm))) | |
467 | 465 | then throw(((((("Attempt to buy " + toString(bpOrdAm)) + " of ") + acc._11[j]) + ", but warehouse only sells ") + toString(-(whOrdAm)))) | |
468 | 466 | 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) | |
469 | 467 | then (bpOrdAm * MULT8) | |
470 | 468 | else bpOrdAm))) | |
471 | 469 | else throw((("Attempt to buy " + acc._11[j]) + " while warehouse doesn't sell it")) | |
472 | 470 | else if ((whOrdAm > 0)) | |
473 | 471 | then if ((-(bpOrdAm) > whOrdAm)) | |
474 | 472 | then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + " of ") + acc._11[j]) + ", but warehouse only buys ") + toString(whOrdAm))) | |
475 | 473 | else if ((-(bpOrdAm) > bpInit)) | |
476 | 474 | then throw(((((("Attempt to sell " + toString(-(bpOrdAm))) + ", but you only have ") + toString(bpInit)) + " of ") + acc._11[j])) | |
477 | 475 | 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) | |
478 | 476 | then (bpOrdAm * MULT8) | |
479 | 477 | else bpOrdAm))) | |
480 | 478 | else throw((("Attempt to sell " + acc._11[j]) + " while warehouse doesn't buy it")) | |
481 | 479 | } | |
482 | 480 | } | |
483 | 481 | } | |
484 | 482 | } | |
485 | 483 | ||
486 | 484 | ||
487 | 485 | func sellResourcesCommon (resList,factoryLocId,amounts,minPrices) = { | |
488 | 486 | func adder (acc,j) = if ((amounts[j] > parseIntValue(resList[j]))) | |
489 | 487 | then throw(((((("You have " + resList[j]) + " of ") + resTypes[j]) + ", but tried to sell ") + toString(amounts[j]))) | |
490 | 488 | else if ((0 > amounts[j])) | |
491 | 489 | then throw(((("You tried to sell negative amount of " + resTypes[j]) + ": ") + toString(amounts[j]))) | |
492 | 490 | else if ((amounts[j] > 0)) | |
493 | 491 | then { | |
494 | 492 | let b = sellInternal(factoryLocId, j, amounts[j], minPrices[j]) | |
495 | 493 | $Tuple4((acc._1 :+ b._1), (acc._2 :+ toString((parseIntValue(resList[j]) - amounts[j]))), (acc._3 + b._2), (acc._4 + amounts[j])) | |
496 | 494 | } | |
497 | 495 | else $Tuple4(acc._1, (acc._2 :+ resList[j]), acc._3, acc._4) | |
498 | 496 | ||
499 | 497 | let $l = ITER6 | |
500 | 498 | let $s = size($l) | |
501 | 499 | let $acc0 = $Tuple4(nil, nil, 0, 0) | |
502 | 500 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
503 | 501 | then $a | |
504 | 502 | else adder($a, $l[$i]) | |
505 | 503 | ||
506 | 504 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
507 | 505 | then $a | |
508 | 506 | else throw("List size exceeds 6") | |
509 | 507 | ||
510 | 508 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
511 | 509 | } | |
512 | 510 | ||
513 | 511 | ||
514 | 512 | func buyMaterialsCommon (matList,factoryLocId,amounts,maxPrices) = { | |
515 | 513 | func mUpdater (acc,j) = if ((0 > amounts[j])) | |
516 | 514 | then throw(((("You tried to buy negative amount of " + matTypes[j]) + ": ") + toString(amounts[j]))) | |
517 | 515 | else if ((amounts[j] > 0)) | |
518 | 516 | then { | |
519 | 517 | let b = buyInternal(factoryLocId, j, amounts[j], maxPrices[j]) | |
520 | 518 | $Tuple4((acc._1 :+ b._1), (acc._2 :+ toString((parseIntValue(matList[j]) + b._3))), (acc._3 + b._2), (acc._4 + amounts[j])) | |
521 | 519 | } | |
522 | 520 | else $Tuple4(acc._1, (acc._2 :+ matList[j]), acc._3, acc._4) | |
523 | 521 | ||
524 | 522 | let $l = ITER6 | |
525 | 523 | let $s = size($l) | |
526 | 524 | let $acc0 = $Tuple4(nil, nil, 0, 0) | |
527 | 525 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
528 | 526 | then $a | |
529 | 527 | else mUpdater($a, $l[$i]) | |
530 | 528 | ||
531 | 529 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
532 | 530 | then $a | |
533 | 531 | else throw("List size exceeds 6") | |
534 | 532 | ||
535 | 533 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
536 | 534 | } | |
537 | 535 | ||
538 | 536 | ||
539 | 537 | func exchangeResourcesCommon (resList,matList,amounts) = { | |
540 | 538 | func exchanger (acc,j) = { | |
541 | 539 | let amj = amounts[j] | |
542 | 540 | if ((amj > parseIntValue(resList[j]))) | |
543 | 541 | then throw(((((("You have " + resList[j]) + " of ") + resTypes[j]) + ", but tried to exchange ") + toString(amj))) | |
544 | 542 | else if ((0 > amj)) | |
545 | 543 | then throw(((("You tried to exchange negative amount of " + resTypes[j]) + ": ") + toString(amj))) | |
546 | 544 | else if ((amj > 0)) | |
547 | 545 | 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)) | |
548 | 546 | else $Tuple4((acc._1 :+ resList[j]), (acc._2 :+ matList[j]), acc._3, acc._4) | |
549 | 547 | } | |
550 | 548 | ||
551 | 549 | let $l = ITER6 | |
552 | 550 | let $s = size($l) | |
553 | 551 | let $acc0 = $Tuple4(nil, nil, 0, 0) | |
554 | 552 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
555 | 553 | then $a | |
556 | 554 | else exchanger($a, $l[$i]) | |
557 | 555 | ||
558 | 556 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
559 | 557 | then $a | |
560 | 558 | else throw("List size exceeds 6") | |
561 | 559 | ||
562 | 560 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
563 | 561 | } | |
564 | 562 | ||
565 | 563 | ||
566 | 564 | func shop2userActions (usdWh2BpSaldo,callerAddr,receivedFee) = if ((usdWh2BpSaldo > 0)) | |
567 | 565 | then { | |
568 | 566 | let usdWh2BpFee = fraction(usdWh2BpSaldo, AUCTIONFEE, MULT6) | |
569 | 567 | if ((receivedFee >= (usdWh2BpSaldo - (3 * usdWh2BpFee)))) | |
570 | 568 | then throw(("This trade does not cover delivery cost of " + fixedPoint(receivedFee, 6))) | |
571 | 569 | else { | |
572 | 570 | let refByKey = keyAddressRefBy(callerAddr) | |
573 | 571 | let refBy = getString(stakingContract, refByKey) | |
574 | 572 | let caller = addressFromStringValue(callerAddr) | |
575 | 573 | (((if (isDefined(refBy)) | |
576 | 574 | then [ScriptTransfer(addressFromStringValue(value(refBy)), usdWh2BpFee, usdtAssetId)] | |
577 | 575 | else nil) :+ ScriptTransfer(caller, ((usdWh2BpSaldo - (3 * usdWh2BpFee)) - receivedFee), usdtAssetId)) :+ ScriptTransfer(restContract, usdWh2BpFee, usdtAssetId)) | |
578 | 576 | } | |
579 | 577 | } | |
580 | 578 | else nil | |
581 | 579 | ||
582 | 580 | ||
583 | 581 | func user2shopActions (usdBp2WhSaldo,pmts,shopLandOwner,spentFee) = if ((usdBp2WhSaldo > 0)) | |
584 | 582 | then if ((size(pmts) != 1)) | |
585 | 583 | then throw("exactly 1 payment must be attached") | |
586 | 584 | else { | |
587 | 585 | let pmt = pmts[0] | |
588 | 586 | let amt = pmt.amount | |
589 | 587 | if (if (!(isDefined(pmt.assetId))) | |
590 | 588 | then true | |
591 | 589 | else (value(pmt.assetId) != usdtAssetId)) | |
592 | 590 | then throw("USDT payments only!") | |
593 | 591 | else { | |
594 | 592 | let usdtSpentWithFee = (usdBp2WhSaldo + spentFee) | |
595 | 593 | if ((amt != usdtSpentWithFee)) | |
596 | 594 | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdBp2WhSaldo, 6)) + "+") + fixedPoint(spentFee, 6)) + "(delivery fee)")) | |
597 | 595 | else if ((MINSHOPPAYMENT > usdBp2WhSaldo)) | |
598 | 596 | then throw(("Min shop trade is " + fixedPoint(MINSHOPPAYMENT, 6))) | |
599 | 597 | else { | |
600 | 598 | let usdBp2WhFee = fraction(usdBp2WhSaldo, AUCTIONFEE, MULT6) | |
601 | 599 | let refByKey = keyAddressRefBy(shopLandOwner) | |
602 | 600 | let refBy = getString(stakingContract, refByKey) | |
603 | 601 | (((if (isDefined(refBy)) | |
604 | 602 | then [ScriptTransfer(addressFromStringValue(value(refBy)), usdBp2WhFee, usdtAssetId)] | |
605 | 603 | else nil) :+ ScriptTransfer(addressFromStringValue(shopLandOwner), (usdBp2WhSaldo - (3 * usdBp2WhFee)), usdtAssetId)) :+ ScriptTransfer(restContract, usdBp2WhFee, usdtAssetId)) | |
606 | 604 | } | |
607 | 605 | } | |
608 | 606 | } | |
609 | 607 | else if ((size(pmts) != 0)) | |
610 | 608 | then throw("No payments needed") | |
611 | 609 | else nil | |
612 | 610 | ||
613 | 611 | ||
614 | 612 | func acceptShopOrderCommon (shopLandAssetId,callerAddr,bpOrderStr,bpResList,bpMatList,bpProdList) = { | |
615 | 613 | let landAsset = value(assetInfo(fromBase58String(shopLandAssetId))) | |
616 | 614 | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(shopLandAssetId))))) | |
617 | 615 | then throw((("NFT " + landAsset.name) + " is not staked")) | |
618 | 616 | else { | |
619 | 617 | let shopLandOwner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(shopLandAssetId)), (("NFT " + landAsset.name) + " is orphaned")) | |
620 | 618 | if ((shopLandOwner == callerAddr)) | |
621 | 619 | then throw("You cannot trade with yourself") | |
622 | 620 | else { | |
623 | 621 | let bpOrderParts = split_4C(bpOrderStr, ":") | |
624 | 622 | if ((size(bpOrderParts) != 3)) | |
625 | 623 | then throw("bpOrderStr should contain exactly 2 ':' separators") | |
626 | 624 | else { | |
627 | 625 | let bpOrdRes = split(bpOrderParts[0], "_") | |
628 | 626 | let bpOrdMat = split(bpOrderParts[1], "_") | |
629 | 627 | let bpOrdProd = if ((bpOrderParts[2] == "")) | |
630 | 628 | then nil | |
631 | 629 | else split_4C(bpOrderParts[2], "_") | |
632 | 630 | if ((size(bpOrdRes) != NUMRES)) | |
633 | 631 | then throw("All 6 resources should be passed") | |
634 | 632 | else if ((size(bpOrdMat) != NUMRES)) | |
635 | 633 | then throw("All 6 materials should be passed") | |
636 | 634 | else { | |
637 | 635 | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [shopLandAssetId], nil)) | |
638 | 636 | let currentWh = split_4C(wh, ":") | |
639 | 637 | let currWhRes = split(currentWh[whIdxRes], "_") | |
640 | 638 | let currWhMat = split(currentWh[whIdxMat], "_") | |
641 | 639 | let currWhProd = if ((currentWh[whIdxProd] == "")) | |
642 | 640 | then nil | |
643 | 641 | else split_4C(currentWh[whIdxProd], "_") | |
644 | 642 | let currWhLockedVol = parseIntValue(split(currentWh[whIdxLOFT], "_")[volLocked]) | |
645 | 643 | let ordKey = keyOrderByLand(shopLandAssetId) | |
646 | 644 | let whOrd = getOrder(ordKey) | |
647 | 645 | let whOrdRes = split(whOrd[ordIdxRes], "_") | |
648 | 646 | let whOrdMat = split(whOrd[ordIdxMat], "_") | |
649 | 647 | let whOrdProd = if ((whOrd[ordIdxProd] == "")) | |
650 | 648 | then nil | |
651 | 649 | else split_4C(whOrd[ordIdxProd], "_") | |
652 | 650 | let r = { | |
653 | 651 | let $l = bpOrdRes | |
654 | 652 | let $s = size($l) | |
655 | 653 | let $acc0 = $Tuple13(nil, nil, nil, 0, 0, 0, 0, bpResList, currWhRes, whOrdRes, resTypes, false, 0) | |
656 | 654 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
657 | 655 | then $a | |
658 | 656 | else acceptCommon($a, $l[$i]) | |
659 | 657 | ||
660 | 658 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
661 | 659 | then $a | |
662 | 660 | else throw("List size exceeds 6") | |
663 | 661 | ||
664 | 662 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
665 | 663 | } | |
666 | 664 | let m = { | |
667 | 665 | let $l = bpOrdMat | |
668 | 666 | let $s = size($l) | |
669 | 667 | let $acc0 = $Tuple13(nil, nil, nil, r._4, r._5, r._6, 0, bpMatList, currWhMat, whOrdMat, matTypes, false, r._13) | |
670 | 668 | func $f1_1 ($a,$i) = if (($i >= $s)) | |
671 | 669 | then $a | |
672 | 670 | else acceptCommon($a, $l[$i]) | |
673 | 671 | ||
674 | 672 | func $f1_2 ($a,$i) = if (($i >= $s)) | |
675 | 673 | then $a | |
676 | 674 | else throw("List size exceeds 6") | |
677 | 675 | ||
678 | 676 | $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
679 | 677 | } | |
680 | 678 | let p = if ((size(bpOrdProd) != 0)) | |
681 | 679 | then { | |
682 | 680 | let $l = bpOrdProd | |
683 | 681 | let $s = size($l) | |
684 | 682 | let $acc0 = $Tuple13(nil, nil, nil, m._4, m._5, m._6, 0, bpProdList, currWhProd, whOrdProd, prodTypes, true, m._13) | |
685 | 683 | func $f2_1 ($a,$i) = if (($i >= $s)) | |
686 | 684 | then $a | |
687 | 685 | else acceptCommon($a, $l[$i]) | |
688 | 686 | ||
689 | 687 | func $f2_2 ($a,$i) = if (($i >= $s)) | |
690 | 688 | then $a | |
691 | 689 | else throw("List size exceeds 50") | |
692 | 690 | ||
693 | 691 | $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) | |
694 | 692 | } | |
695 | 693 | else $Tuple13(currWhProd, whOrdProd, bpProdList, m._4, m._5, m._6, 0, bpProdList, currWhProd, whOrdProd, prodTypes, true, m._13) | |
696 | 694 | let volSaldo = p._4 | |
697 | 695 | let newLockedVol = if ((0 > (currWhLockedVol - volSaldo))) | |
698 | 696 | then 0 | |
699 | 697 | else (currWhLockedVol - volSaldo) | |
700 | 698 | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(r._1, "_"), makeString(m._1, "_"), makeString_2C(p._1, "_"), toString(newLockedVol)], ":") | |
701 | 699 | let newWhOrdStr = makeString_2C([makeString(r._2, "_"), makeString(m._2, "_"), makeString_2C(p._2, "_")], ":") | |
702 | 700 | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, shopLandAssetId], nil)) | |
703 | 701 | let accStatsResult = asInt(invoke(stakingContract, "updateAccStats", [shopLandOwner, fraction(xpShop, p._13, MULT8)], nil)) | |
704 | 702 | $Tuple10(StringEntry(ordKey, newWhOrdStr), r._3, m._3, p._3, p._5, p._6, p._13, shopLandOwner, whSave, accStatsResult) | |
705 | 703 | } | |
706 | 704 | } | |
707 | 705 | } | |
708 | 706 | } | |
709 | 707 | } | |
710 | 708 | ||
711 | 709 | ||
712 | 710 | func sellResourcesWorldInternal (amount) = { | |
713 | 711 | let oneRes = (amount / 30) | |
714 | 712 | let oneFactoryAmounts = [oneRes, oneRes, oneRes, oneRes, oneRes, oneRes] | |
715 | 713 | let s = toString(oneRes) | |
716 | 714 | let resList = [s, s, s, s, s, s] | |
717 | 715 | let minPrices = [0, 0, 0, 0, 0, 0] | |
718 | 716 | func oneFactory (acc,continent) = { | |
719 | 717 | let x = sellResourcesCommon(resList, continent, oneFactoryAmounts, minPrices) | |
720 | 718 | $Tuple3((acc._1 ++ x._1), (acc._2 + x._3), (acc._3 + x._4)) | |
721 | 719 | } | |
722 | 720 | ||
723 | - | let $ | |
721 | + | let $t02529225382 = { | |
724 | 722 | let $l = continents | |
725 | 723 | let $s = size($l) | |
726 | 724 | let $acc0 = $Tuple3(nil, 0, 0) | |
727 | 725 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
728 | 726 | then $a | |
729 | 727 | else oneFactory($a, $l[$i]) | |
730 | 728 | ||
731 | 729 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
732 | 730 | then $a | |
733 | 731 | else throw("List size exceeds 5") | |
734 | 732 | ||
735 | 733 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5) | |
736 | 734 | } | |
737 | - | let factoryActions = $ | |
738 | - | let usdtReceived = $ | |
739 | - | let totalRes = $ | |
735 | + | let factoryActions = $t02529225382._1 | |
736 | + | let usdtReceived = $t02529225382._2 | |
737 | + | let totalRes = $t02529225382._3 | |
740 | 738 | let fee = fraction(usdtReceived, DELIVERY_FEE, MULT6) | |
741 | 739 | let activitiesAmount = (usdtReceived / 100) | |
742 | 740 | let usdtLeft = ((usdtReceived - activitiesAmount) - fee) | |
743 | 741 | $Tuple5(factoryActions, usdtLeft, fee, activitiesAmount, totalRes) | |
744 | 742 | } | |
745 | 743 | ||
746 | 744 | ||
747 | 745 | func craftGoodsCommon (matList,prodList,manufactoryContinent,productIdx,quantity) = if ((0 >= quantity)) | |
748 | 746 | then throw("Quantity should be positive") | |
749 | 747 | else if (if ((0 > productIdx)) | |
750 | 748 | then true | |
751 | 749 | else (productIdx >= size(productionMatrix))) | |
752 | 750 | then throw(("Unknown product idx=" + toString(productIdx))) | |
753 | 751 | else { | |
754 | 752 | let recipe = split(productionMatrix[productIdx], "_") | |
755 | 753 | if ((size(recipe) != RECIPESIZE)) | |
756 | 754 | then throw(("Fatal: unknown recipe: " + productionMatrix[productIdx])) | |
757 | 755 | else { | |
758 | 756 | let productContIdx = parseIntValue(recipe[rIdxContinent]) | |
759 | 757 | if ((continents[productContIdx] != manufactoryContinent)) | |
760 | 758 | then throw(((("This product is available in " + continents[productContIdx]) + ", not in ") + manufactoryContinent)) | |
761 | 759 | else { | |
762 | 760 | func filler (acc,ignoredItem) = { | |
763 | 761 | let n = acc._2 | |
764 | 762 | let xs = if ((size(prodList) > n)) | |
765 | 763 | then prodList[n] | |
766 | 764 | else "0" | |
767 | 765 | let x = parseIntValue(xs) | |
768 | 766 | let amount = (quantity * PRODUCTPKGSIZE) | |
769 | 767 | let y = if ((n == productIdx)) | |
770 | 768 | then toString((x + amount)) | |
771 | 769 | else xs | |
772 | 770 | $Tuple2((acc._1 :+ y), (n + 1)) | |
773 | 771 | } | |
774 | 772 | ||
775 | 773 | let newProd = ( let $l = productionMatrix | |
776 | 774 | let $s = size($l) | |
777 | 775 | let $acc0 = $Tuple2(nil, 0) | |
778 | 776 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
779 | 777 | then $a | |
780 | 778 | else filler($a, $l[$i]) | |
781 | 779 | ||
782 | 780 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
783 | 781 | then $a | |
784 | 782 | else throw("List size exceeds 50") | |
785 | 783 | ||
786 | 784 | $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 | |
787 | 785 | func producer (acc,j) = { | |
788 | 786 | let needMat = (((parseIntValue(recipe[j]) * MULT5) * quantity) * parseIntValue(recipe[rIdxCoeff])) | |
789 | 787 | let haveMat = parseIntValue(matList[j]) | |
790 | 788 | if ((needMat > haveMat)) | |
791 | 789 | then throw(((((((("You have " + fixedPoint(haveMat, 8)) + " of ") + matTypes[j]) + ", but recipe requires ") + fixedPoint(needMat, 8)) + " for quantity ") + toString(quantity))) | |
792 | 790 | else if ((needMat > 0)) | |
793 | 791 | then $Tuple2((acc._1 :+ toString((haveMat - needMat))), (acc._2 + needMat)) | |
794 | 792 | else $Tuple2((acc._1 :+ matList[j]), acc._2) | |
795 | 793 | } | |
796 | 794 | ||
797 | 795 | let merged = { | |
798 | 796 | let $l = ITER6 | |
799 | 797 | let $s = size($l) | |
800 | 798 | let $acc0 = $Tuple2(nil, 0) | |
801 | 799 | func $f1_1 ($a,$i) = if (($i >= $s)) | |
802 | 800 | then $a | |
803 | 801 | else producer($a, $l[$i]) | |
804 | 802 | ||
805 | 803 | func $f1_2 ($a,$i) = if (($i >= $s)) | |
806 | 804 | then $a | |
807 | 805 | else throw("List size exceeds 6") | |
808 | 806 | ||
809 | 807 | $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
810 | 808 | } | |
811 | 809 | $Tuple3(merged._1, newProd, merged._2) | |
812 | 810 | } | |
813 | 811 | } | |
814 | 812 | } | |
815 | 813 | ||
816 | 814 | ||
817 | 815 | @Callable(i) | |
818 | 816 | func recalcLockedVolumeREADONLY (landAssetId,wh) = { | |
819 | 817 | let currentOrd = getOrder(keyOrderByLand(landAssetId)) | |
820 | 818 | let z = setInternal(wh, currentOrd, currentOrd) | |
821 | 819 | $Tuple2(nil, (z._4 + z._5)) | |
822 | 820 | } | |
823 | 821 | ||
824 | 822 | ||
825 | 823 | ||
826 | 824 | @Callable(i) | |
827 | 825 | func constructorV1 (restAddr) = if ((i.caller != this)) | |
828 | 826 | then throw("Permission denied") | |
829 | 827 | else [StringEntry(keyRestAddress(), restAddr)] | |
830 | 828 | ||
831 | 829 | ||
832 | 830 | ||
833 | 831 | @Callable(i) | |
834 | 832 | func sellResources (amounts,minPrices) = { | |
835 | 833 | let prologResult = prolog() | |
836 | 834 | if ((prologResult == prologResult)) | |
837 | 835 | then { | |
838 | 836 | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
839 | 837 | if ((size(i.payments) != 0)) | |
840 | 838 | then throw("sellResources doesn't require any payments") | |
841 | 839 | else { | |
842 | 840 | let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_") | |
843 | 841 | if ((curLocation[locIdxType] != "F")) | |
844 | 842 | then throw(("Duck location type should be Factory, but is " + curLocation[locIdxType])) | |
845 | 843 | else { | |
846 | 844 | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
847 | 845 | let resList = split(currentPack[bpIdxRes], "_") | |
848 | - | let $ | |
849 | - | let factoryActions = $ | |
850 | - | let newRes = $ | |
851 | - | let usdtReceived = $ | |
852 | - | let totalRes = $ | |
846 | + | let $t02891529041 = sellResourcesCommon(resList, curLocation[locIdxId], amounts, minPrices) | |
847 | + | let factoryActions = $t02891529041._1 | |
848 | + | let newRes = $t02891529041._2 | |
849 | + | let usdtReceived = $t02891529041._3 | |
850 | + | let totalRes = $t02891529041._4 | |
853 | 851 | let activitiesAmount = (usdtReceived / 100) | |
854 | 852 | let newPack = makeString_2C([currentPack[bpIdxLevel], makeString(newRes, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":") | |
855 | 853 | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
856 | 854 | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalRes, MULT8)], nil)) | |
857 | 855 | $Tuple2(((factoryActions :+ ScriptTransfer(i.caller, (usdtReceived - activitiesAmount), usdtAssetId)) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult)) | |
858 | 856 | } | |
859 | 857 | } | |
860 | 858 | } | |
861 | 859 | else throw("Strict value is not equal to itself.") | |
862 | 860 | } | |
863 | 861 | ||
864 | 862 | ||
865 | 863 | ||
866 | 864 | @Callable(i) | |
867 | 865 | func sellResourcesWorld (addr,amount) = if ((i.caller != acresContract)) | |
868 | 866 | then throw("Permission denied") | |
869 | 867 | else { | |
870 | - | let $ | |
871 | - | let factoryActions = $ | |
872 | - | let usdtLeft = $ | |
873 | - | let fee = $ | |
874 | - | let activitiesAmount = $ | |
875 | - | let totalRes = $ | |
868 | + | let $t02983329990 = sellResourcesWorldInternal(amount) | |
869 | + | let factoryActions = $t02983329990._1 | |
870 | + | let usdtLeft = $t02983329990._2 | |
871 | + | let fee = $t02983329990._3 | |
872 | + | let activitiesAmount = $t02983329990._4 | |
873 | + | let totalRes = $t02983329990._5 | |
876 | 874 | if ((0 >= usdtLeft)) | |
877 | 875 | then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6))) | |
878 | 876 | else { | |
879 | 877 | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalRes, MULT8)], nil)) | |
880 | 878 | $Tuple2((((factoryActions :+ IntegerEntry(deliveryFundKey, (valueOrElse(getInteger(deliveryFundKey), 0) + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ ScriptTransfer(investFundContract, usdtLeft, usdtAssetId)), $Tuple2(usdtLeft, statsResult)) | |
881 | 879 | } | |
882 | 880 | } | |
883 | 881 | ||
884 | 882 | ||
885 | 883 | ||
886 | 884 | @Callable(i) | |
887 | 885 | func sellResourcesWorldREADONLY (amount) = { | |
888 | 886 | let usdtLeft = sellResourcesWorldInternal(amount)._2 | |
889 | 887 | $Tuple2(nil, usdtLeft) | |
890 | 888 | } | |
891 | 889 | ||
892 | 890 | ||
893 | 891 | ||
894 | 892 | @Callable(i) | |
895 | - | func sellResourcesDuckDelivery (amounts,minPrices,factoryContinent) = if (!(KS_ALLOW_DELIVERY)) | |
896 | - | then throw("Delivery feature is turned off!") | |
897 | - | else { | |
898 | - | let prologResult = prolog() | |
899 | - | if ((prologResult == prologResult)) | |
900 | - | then { | |
901 | - | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
902 | - | if ((size(i.payments) != 0)) | |
903 | - | then throw("sellResources doesn't require any payments") | |
904 | - | else { | |
905 | - | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
906 | - | let resList = split(currentPack[bpIdxRes], "_") | |
907 | - | let $t03120431325 = sellResourcesCommon(resList, factoryContinent, amounts, minPrices) | |
908 | - | let factoryActions = $t03120431325._1 | |
909 | - | let newRes = $t03120431325._2 | |
910 | - | let usdtReceived = $t03120431325._3 | |
911 | - | let totalRes = $t03120431325._4 | |
912 | - | let newPack = makeString_2C([currentPack[bpIdxLevel], makeString(newRes, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":") | |
913 | - | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
914 | - | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalRes, MULT8)], nil)) | |
915 | - | let feePart = fraction(usdtReceived, DELIVERY_FEE, MULT6) | |
916 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
917 | - | let activitiesAmount = (usdtReceived / 100) | |
918 | - | if ((fee >= (usdtReceived - activitiesAmount))) | |
919 | - | then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6))) | |
920 | - | else { | |
921 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
922 | - | $Tuple2((((factoryActions :+ ScriptTransfer(i.caller, ((usdtReceived - activitiesAmount) - fee), usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult)) | |
923 | - | } | |
924 | - | } | |
925 | - | } | |
926 | - | else throw("Strict value is not equal to itself.") | |
927 | - | } | |
893 | + | func sellResourcesDuckDelivery (amounts,minPrices,factoryContinent) = { | |
894 | + | let prologResult = prolog() | |
895 | + | if ((prologResult == prologResult)) | |
896 | + | then { | |
897 | + | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
898 | + | if ((size(i.payments) != 0)) | |
899 | + | then throw("sellResources doesn't require any payments") | |
900 | + | else { | |
901 | + | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
902 | + | let resList = split(currentPack[bpIdxRes], "_") | |
903 | + | let $t03114931270 = sellResourcesCommon(resList, factoryContinent, amounts, minPrices) | |
904 | + | let factoryActions = $t03114931270._1 | |
905 | + | let newRes = $t03114931270._2 | |
906 | + | let usdtReceived = $t03114931270._3 | |
907 | + | let totalRes = $t03114931270._4 | |
908 | + | let newPack = makeString_2C([currentPack[bpIdxLevel], makeString(newRes, "_"), currentPack[bpIdxMat], currentPack[bpIdxProd]], ":") | |
909 | + | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
910 | + | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalRes, MULT8)], nil)) | |
911 | + | let feePart = fraction(usdtReceived, DELIVERY_FEE, MULT6) | |
912 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
913 | + | let activitiesAmount = (usdtReceived / 100) | |
914 | + | if ((fee >= (usdtReceived - activitiesAmount))) | |
915 | + | then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6))) | |
916 | + | else { | |
917 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
918 | + | $Tuple2((((factoryActions :+ ScriptTransfer(i.caller, ((usdtReceived - activitiesAmount) - fee), usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult)) | |
919 | + | } | |
920 | + | } | |
921 | + | } | |
922 | + | else throw("Strict value is not equal to itself.") | |
923 | + | } | |
928 | 924 | ||
929 | 925 | ||
930 | 926 | ||
931 | 927 | @Callable(i) | |
932 | - | func sellResourcesLandDelivery (amounts,minPrices,landAssetId,factoryContinent) = if (!(KS_ALLOW_DELIVERY)) | |
933 | - | then throw("Delivery feature is turned off!") | |
934 | - | else { | |
935 | - | let prologResult = prolog() | |
936 | - | if ((prologResult == prologResult)) | |
937 | - | then if ((size(i.payments) != 0)) | |
938 | - | then throw("sellResources doesn't require any payments") | |
939 | - | else { | |
940 | - | let user = i.caller | |
941 | - | let addr = toString(user) | |
942 | - | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
943 | - | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
944 | - | then throw((("NFT " + asset.name) + " is not staked")) | |
945 | - | else { | |
946 | - | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
947 | - | if ((owner != addr)) | |
948 | - | then throw((LANDPREFIX + " is not yours")) | |
949 | - | else { | |
950 | - | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
951 | - | let currentWh = split_4C(wh, ":") | |
952 | - | let resList = split(currentWh[whIdxRes], "_") | |
953 | - | let $t03331633437 = sellResourcesCommon(resList, factoryContinent, amounts, minPrices) | |
954 | - | let factoryActions = $t03331633437._1 | |
955 | - | let newRes = $t03331633437._2 | |
956 | - | let usdtReceived = $t03331633437._3 | |
957 | - | let totalRes = $t03331633437._4 | |
958 | - | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newRes, "_"), currentWh[whIdxMat], currentWh[whIdxProd], currentWh[whIdxLOFT]], ":") | |
959 | - | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
960 | - | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalRes, MULT8)], nil)) | |
961 | - | let feePart = fraction(usdtReceived, DELIVERY_FEE, MULT6) | |
962 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
963 | - | let activitiesAmount = (usdtReceived / 100) | |
964 | - | if ((fee >= (usdtReceived - activitiesAmount))) | |
965 | - | then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6))) | |
966 | - | else { | |
967 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
968 | - | $Tuple2((((factoryActions :+ ScriptTransfer(i.caller, ((usdtReceived - activitiesAmount) - fee), usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(whSave, prologResult, statsResult)) | |
969 | - | } | |
970 | - | } | |
971 | - | } | |
972 | - | } | |
973 | - | else throw("Strict value is not equal to itself.") | |
974 | - | } | |
928 | + | func sellResourcesLandDelivery (amounts,minPrices,landAssetId,factoryContinent) = { | |
929 | + | let prologResult = prolog() | |
930 | + | if ((prologResult == prologResult)) | |
931 | + | then if ((size(i.payments) != 0)) | |
932 | + | then throw("sellResources doesn't require any payments") | |
933 | + | else { | |
934 | + | let user = i.caller | |
935 | + | let addr = toString(user) | |
936 | + | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
937 | + | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
938 | + | then throw((("NFT " + asset.name) + " is not staked")) | |
939 | + | else { | |
940 | + | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
941 | + | if ((owner != addr)) | |
942 | + | then throw((LANDPREFIX + " is not yours")) | |
943 | + | else { | |
944 | + | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
945 | + | let currentWh = split_4C(wh, ":") | |
946 | + | let resList = split(currentWh[whIdxRes], "_") | |
947 | + | let $t03318433305 = sellResourcesCommon(resList, factoryContinent, amounts, minPrices) | |
948 | + | let factoryActions = $t03318433305._1 | |
949 | + | let newRes = $t03318433305._2 | |
950 | + | let usdtReceived = $t03318433305._3 | |
951 | + | let totalRes = $t03318433305._4 | |
952 | + | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newRes, "_"), currentWh[whIdxMat], currentWh[whIdxProd], currentWh[whIdxLOFT]], ":") | |
953 | + | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
954 | + | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalRes, MULT8)], nil)) | |
955 | + | let feePart = fraction(usdtReceived, DELIVERY_FEE, MULT6) | |
956 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
957 | + | let activitiesAmount = (usdtReceived / 100) | |
958 | + | if ((fee >= (usdtReceived - activitiesAmount))) | |
959 | + | then throw(("This trade does not cover delivery cost of " + fixedPoint(fee, 6))) | |
960 | + | else { | |
961 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
962 | + | $Tuple2((((factoryActions :+ ScriptTransfer(i.caller, ((usdtReceived - activitiesAmount) - fee), usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(whSave, prologResult, statsResult)) | |
963 | + | } | |
964 | + | } | |
965 | + | } | |
966 | + | } | |
967 | + | else throw("Strict value is not equal to itself.") | |
968 | + | } | |
975 | 969 | ||
976 | 970 | ||
977 | 971 | ||
978 | 972 | @Callable(i) | |
979 | 973 | func buyMaterials (amounts,maxPrices) = { | |
980 | 974 | let prologResult = prolog() | |
981 | 975 | if ((prologResult == prologResult)) | |
982 | 976 | then { | |
983 | 977 | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
984 | 978 | if ((size(i.payments) != 1)) | |
985 | 979 | then throw("exactly 1 payment must be attached") | |
986 | 980 | else { | |
987 | 981 | let pmt = i.payments[0] | |
988 | 982 | let amt = pmt.amount | |
989 | 983 | if (if (!(isDefined(pmt.assetId))) | |
990 | 984 | then true | |
991 | 985 | else (value(pmt.assetId) != usdtAssetId)) | |
992 | 986 | then throw("USDT payments only!") | |
993 | 987 | else { | |
994 | 988 | let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_") | |
995 | 989 | if ((curLocation[locIdxType] != "F")) | |
996 | 990 | then throw(("Duck location type should be Factory, but is " + curLocation[locIdxType])) | |
997 | 991 | else { | |
998 | 992 | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
999 | 993 | let matList = split(currentPack[bpIdxMat], "_") | |
1000 | - | let $ | |
1001 | - | let factoryActions = $ | |
1002 | - | let newMat = $ | |
1003 | - | let usdtSpent = $ | |
1004 | - | let totalMat = $ | |
994 | + | let $t03512935251 = buyMaterialsCommon(matList, curLocation[locIdxId], amounts, maxPrices) | |
995 | + | let factoryActions = $t03512935251._1 | |
996 | + | let newMat = $t03512935251._2 | |
997 | + | let usdtSpent = $t03512935251._3 | |
998 | + | let totalMat = $t03512935251._4 | |
1005 | 999 | if ((usdtSpent > amt)) | |
1006 | 1000 | then throw(((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6))) | |
1007 | 1001 | else { | |
1008 | 1002 | let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), currentPack[bpIdxProd]], ":") | |
1009 | 1003 | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1010 | 1004 | let rest = if (((amt - usdtSpent) > 0)) | |
1011 | 1005 | then [ScriptTransfer(i.caller, (amt - usdtSpent), usdtAssetId)] | |
1012 | 1006 | else nil | |
1013 | 1007 | let activitiesAmount = (usdtSpent / 100) | |
1014 | 1008 | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalMat, MULT8)], nil)) | |
1015 | 1009 | $Tuple2(((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult)) | |
1016 | 1010 | } | |
1017 | 1011 | } | |
1018 | 1012 | } | |
1019 | 1013 | } | |
1020 | 1014 | } | |
1021 | 1015 | else throw("Strict value is not equal to itself.") | |
1022 | 1016 | } | |
1023 | 1017 | ||
1024 | 1018 | ||
1025 | 1019 | ||
1026 | 1020 | @Callable(i) | |
1027 | - | func buyMaterialsDuckDelivery (amounts,maxPrices,factoryContinent) = if (!(KS_ALLOW_DELIVERY)) | |
1028 | - | then throw("Delivery feature is turned off!") | |
1029 | - | else { | |
1030 | - | let prologResult = prolog() | |
1031 | - | if ((prologResult == prologResult)) | |
1032 | - | then { | |
1033 | - | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1034 | - | if ((size(i.payments) != 1)) | |
1035 | - | then throw("exactly 1 payment must be attached") | |
1036 | - | else { | |
1037 | - | let pmt = i.payments[0] | |
1038 | - | let amt = pmt.amount | |
1039 | - | if (if (!(isDefined(pmt.assetId))) | |
1040 | - | then true | |
1041 | - | else (value(pmt.assetId) != usdtAssetId)) | |
1042 | - | then throw("USDT payments only!") | |
1043 | - | else { | |
1044 | - | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1045 | - | let matList = split(currentPack[bpIdxMat], "_") | |
1046 | - | let $t03690437021 = buyMaterialsCommon(matList, factoryContinent, amounts, maxPrices) | |
1047 | - | let factoryActions = $t03690437021._1 | |
1048 | - | let newMat = $t03690437021._2 | |
1049 | - | let usdtSpent = $t03690437021._3 | |
1050 | - | let totalMat = $t03690437021._4 | |
1051 | - | let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), currentPack[bpIdxProd]], ":") | |
1052 | - | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1053 | - | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalMat, MULT8)], nil)) | |
1054 | - | let feePart = fraction(usdtSpent, DELIVERY_FEE, MULT6) | |
1055 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1056 | - | let usdtSpentWithFee = (usdtSpent + fee) | |
1057 | - | if ((usdtSpentWithFee > amt)) | |
1058 | - | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1059 | - | else { | |
1060 | - | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1061 | - | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1062 | - | else nil | |
1063 | - | let activitiesAmount = (usdtSpent / 100) | |
1064 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1065 | - | $Tuple2((((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult)) | |
1066 | - | } | |
1067 | - | } | |
1068 | - | } | |
1069 | - | } | |
1070 | - | else throw("Strict value is not equal to itself.") | |
1071 | - | } | |
1072 | - | ||
1073 | - | ||
1074 | - | ||
1075 | - | @Callable(i) | |
1076 | - | func buyMaterialsLandDelivery (amounts,maxPrices,landAssetId,factoryContinent) = if (!(KS_ALLOW_DELIVERY)) | |
1077 | - | then throw("Delivery feature is turned off!") | |
1078 | - | else { | |
1079 | - | let prologResult = prolog() | |
1080 | - | if ((prologResult == prologResult)) | |
1081 | - | then if ((size(i.payments) != 1)) | |
1021 | + | func buyMaterialsDuckDelivery (amounts,maxPrices,factoryContinent) = { | |
1022 | + | let prologResult = prolog() | |
1023 | + | if ((prologResult == prologResult)) | |
1024 | + | then { | |
1025 | + | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1026 | + | if ((size(i.payments) != 1)) | |
1082 | 1027 | then throw("exactly 1 payment must be attached") | |
1083 | 1028 | else { | |
1084 | 1029 | let pmt = i.payments[0] | |
1085 | 1030 | let amt = pmt.amount | |
1086 | 1031 | if (if (!(isDefined(pmt.assetId))) | |
1087 | 1032 | then true | |
1088 | 1033 | else (value(pmt.assetId) != usdtAssetId)) | |
1089 | 1034 | then throw("USDT payments only!") | |
1090 | 1035 | else { | |
1091 | - | let user = i.caller | |
1092 | - | let addr = toString(user) | |
1093 | - | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1094 | - | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1095 | - | then throw((("NFT " + asset.name) + " is not staked")) | |
1036 | + | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1037 | + | let matList = split(currentPack[bpIdxMat], "_") | |
1038 | + | let $t03669536812 = buyMaterialsCommon(matList, factoryContinent, amounts, maxPrices) | |
1039 | + | let factoryActions = $t03669536812._1 | |
1040 | + | let newMat = $t03669536812._2 | |
1041 | + | let usdtSpent = $t03669536812._3 | |
1042 | + | let totalMat = $t03669536812._4 | |
1043 | + | let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), currentPack[bpIdxProd]], ":") | |
1044 | + | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1045 | + | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalMat, MULT8)], nil)) | |
1046 | + | let feePart = fraction(usdtSpent, DELIVERY_FEE, MULT6) | |
1047 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1048 | + | let usdtSpentWithFee = (usdtSpent + fee) | |
1049 | + | if ((usdtSpentWithFee > amt)) | |
1050 | + | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1096 | 1051 | else { | |
1097 | - | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1098 | - | if ((owner != addr)) | |
1099 | - | then throw((LANDPREFIX + " is not yours")) | |
1100 | - | else { | |
1101 | - | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1102 | - | let currentWh = split_4C(wh, ":") | |
1103 | - | let matList = split(currentWh[whIdxMat], "_") | |
1104 | - | let $t03926339380 = buyMaterialsCommon(matList, factoryContinent, amounts, maxPrices) | |
1105 | - | let factoryActions = $t03926339380._1 | |
1106 | - | let newMat = $t03926339380._2 | |
1107 | - | let usdtSpent = $t03926339380._3 | |
1108 | - | let totalMat = $t03926339380._4 | |
1109 | - | let whStr = makeString_2C([currentWh[whIdxLevels], currentWh[whIdxRes], makeString(newMat, "_"), currentWh[whIdxProd], currentWh[whIdxLOFT]], ":") | |
1110 | - | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1111 | - | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalMat, MULT8)], nil)) | |
1112 | - | let feePart = fraction(usdtSpent, DELIVERY_FEE, MULT6) | |
1113 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1114 | - | let usdtSpentWithFee = (usdtSpent + fee) | |
1115 | - | if ((usdtSpentWithFee > amt)) | |
1116 | - | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1117 | - | else { | |
1118 | - | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1119 | - | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1120 | - | else nil | |
1121 | - | let activitiesAmount = (usdtSpent / 100) | |
1122 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1123 | - | $Tuple2((((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult)) | |
1124 | - | } | |
1125 | - | } | |
1052 | + | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1053 | + | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1054 | + | else nil | |
1055 | + | let activitiesAmount = (usdtSpent / 100) | |
1056 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1057 | + | $Tuple2((((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult)) | |
1126 | 1058 | } | |
1127 | 1059 | } | |
1128 | 1060 | } | |
1129 | - | else throw("Strict value is not equal to itself.") | |
1130 | - | } | |
1061 | + | } | |
1062 | + | else throw("Strict value is not equal to itself.") | |
1063 | + | } | |
1064 | + | ||
1065 | + | ||
1066 | + | ||
1067 | + | @Callable(i) | |
1068 | + | func buyMaterialsLandDelivery (amounts,maxPrices,landAssetId,factoryContinent) = { | |
1069 | + | let prologResult = prolog() | |
1070 | + | if ((prologResult == prologResult)) | |
1071 | + | then if ((size(i.payments) != 1)) | |
1072 | + | then throw("exactly 1 payment must be attached") | |
1073 | + | else { | |
1074 | + | let pmt = i.payments[0] | |
1075 | + | let amt = pmt.amount | |
1076 | + | if (if (!(isDefined(pmt.assetId))) | |
1077 | + | then true | |
1078 | + | else (value(pmt.assetId) != usdtAssetId)) | |
1079 | + | then throw("USDT payments only!") | |
1080 | + | else { | |
1081 | + | let user = i.caller | |
1082 | + | let addr = toString(user) | |
1083 | + | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1084 | + | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1085 | + | then throw((("NFT " + asset.name) + " is not staked")) | |
1086 | + | else { | |
1087 | + | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1088 | + | if ((owner != addr)) | |
1089 | + | then throw((LANDPREFIX + " is not yours")) | |
1090 | + | else { | |
1091 | + | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1092 | + | let currentWh = split_4C(wh, ":") | |
1093 | + | let matList = split(currentWh[whIdxMat], "_") | |
1094 | + | let $t03897739094 = buyMaterialsCommon(matList, factoryContinent, amounts, maxPrices) | |
1095 | + | let factoryActions = $t03897739094._1 | |
1096 | + | let newMat = $t03897739094._2 | |
1097 | + | let usdtSpent = $t03897739094._3 | |
1098 | + | let totalMat = $t03897739094._4 | |
1099 | + | let whStr = makeString_2C([currentWh[whIdxLevels], currentWh[whIdxRes], makeString(newMat, "_"), currentWh[whIdxProd], currentWh[whIdxLOFT]], ":") | |
1100 | + | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1101 | + | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalMat, MULT8)], nil)) | |
1102 | + | let feePart = fraction(usdtSpent, DELIVERY_FEE, MULT6) | |
1103 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1104 | + | let usdtSpentWithFee = (usdtSpent + fee) | |
1105 | + | if ((usdtSpentWithFee > amt)) | |
1106 | + | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1107 | + | else { | |
1108 | + | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1109 | + | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1110 | + | else nil | |
1111 | + | let activitiesAmount = (usdtSpent / 100) | |
1112 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1113 | + | $Tuple2((((factoryActions ++ rest) :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult)) | |
1114 | + | } | |
1115 | + | } | |
1116 | + | } | |
1117 | + | } | |
1118 | + | } | |
1119 | + | else throw("Strict value is not equal to itself.") | |
1120 | + | } | |
1131 | 1121 | ||
1132 | 1122 | ||
1133 | 1123 | ||
1134 | 1124 | @Callable(i) | |
1135 | 1125 | func exchangeResources (amounts) = { | |
1136 | 1126 | let prologResult = prolog() | |
1137 | 1127 | if ((prologResult == prologResult)) | |
1138 | 1128 | then { | |
1139 | 1129 | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1140 | 1130 | if ((size(i.payments) != 1)) | |
1141 | 1131 | then throw("exactly 1 payment must be attached") | |
1142 | 1132 | else { | |
1143 | 1133 | let pmt = i.payments[0] | |
1144 | 1134 | let amt = pmt.amount | |
1145 | 1135 | if (if (!(isDefined(pmt.assetId))) | |
1146 | 1136 | then true | |
1147 | 1137 | else (value(pmt.assetId) != usdtAssetId)) | |
1148 | 1138 | then throw("USDT payments only!") | |
1149 | 1139 | else { | |
1150 | 1140 | let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_") | |
1151 | 1141 | if ((curLocation[locIdxType] != "F")) | |
1152 | 1142 | then throw(("Duck location type should be Factory, but is " + curLocation[locIdxType])) | |
1153 | 1143 | else { | |
1154 | 1144 | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1155 | 1145 | let resList = split(currentPack[bpIdxRes], "_") | |
1156 | 1146 | let matList = split(currentPack[bpIdxMat], "_") | |
1157 | - | let $ | |
1158 | - | let newRes = $ | |
1159 | - | let newMat = $ | |
1160 | - | let usdtSpent = $ | |
1161 | - | let totalAmountConverted = $ | |
1147 | + | let $t04117241278 = exchangeResourcesCommon(resList, matList, amounts) | |
1148 | + | let newRes = $t04117241278._1 | |
1149 | + | let newMat = $t04117241278._2 | |
1150 | + | let usdtSpent = $t04117241278._3 | |
1151 | + | let totalAmountConverted = $t04117241278._4 | |
1162 | 1152 | if ((usdtSpent > amt)) | |
1163 | 1153 | then throw(((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6))) | |
1164 | 1154 | else { | |
1165 | 1155 | let newPack = makeString([currentPack[bpIdxLevel], makeString(newRes, "_"), makeString(newMat, "_"), currentPack[bpIdxProd]], ":") | |
1166 | 1156 | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1167 | 1157 | let rest = if (((amt - usdtSpent) > 0)) | |
1168 | 1158 | then [ScriptTransfer(i.caller, (amt - usdtSpent), usdtAssetId)] | |
1169 | 1159 | else nil | |
1170 | 1160 | let activitiesAmount = (usdtSpent / 100) | |
1171 | 1161 | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalAmountConverted, MULT8)], nil)) | |
1172 | 1162 | $Tuple2((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)), $Tuple3(backpackResult, prologResult, statsResult)) | |
1173 | 1163 | } | |
1174 | 1164 | } | |
1175 | 1165 | } | |
1176 | 1166 | } | |
1177 | 1167 | } | |
1178 | 1168 | else throw("Strict value is not equal to itself.") | |
1179 | 1169 | } | |
1180 | 1170 | ||
1181 | 1171 | ||
1182 | 1172 | ||
1183 | 1173 | @Callable(i) | |
1184 | - | func exchangeResourcesDuckDelivery (amounts) = if (!(KS_ALLOW_DELIVERY)) | |
1185 | - | then throw("Delivery feature is turned off!") | |
1186 | - | else { | |
1187 | - | let prologResult = prolog() | |
1188 | - | if ((prologResult == prologResult)) | |
1189 | - | then { | |
1190 | - | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1191 | - | if ((size(i.payments) != 1)) | |
1192 | - | then throw("exactly 1 payment must be attached") | |
1193 | - | else { | |
1194 | - | let pmt = i.payments[0] | |
1195 | - | let amt = pmt.amount | |
1196 | - | if (if (!(isDefined(pmt.assetId))) | |
1197 | - | then true | |
1198 | - | else (value(pmt.assetId) != usdtAssetId)) | |
1199 | - | then throw("USDT payments only!") | |
1200 | - | else { | |
1201 | - | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1202 | - | let resList = split(currentPack[bpIdxRes], "_") | |
1203 | - | let matList = split(currentPack[bpIdxMat], "_") | |
1204 | - | let $t04307943185 = exchangeResourcesCommon(resList, matList, amounts) | |
1205 | - | let newRes = $t04307943185._1 | |
1206 | - | let newMat = $t04307943185._2 | |
1207 | - | let usdtSpent = $t04307943185._3 | |
1208 | - | let totalAmountConverted = $t04307943185._4 | |
1209 | - | let feePart = fraction(usdtSpent, DELIVERY_FEE15, MULT6) | |
1210 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY15]) | |
1211 | - | let usdtSpentWithFee = (usdtSpent + fee) | |
1212 | - | if ((usdtSpentWithFee > amt)) | |
1213 | - | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1214 | - | else { | |
1215 | - | let newPack = makeString([currentPack[bpIdxLevel], makeString(newRes, "_"), makeString(newMat, "_"), currentPack[bpIdxProd]], ":") | |
1216 | - | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1217 | - | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1218 | - | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1219 | - | else nil | |
1220 | - | let activitiesAmount = (usdtSpent / 100) | |
1221 | - | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalAmountConverted, MULT8)], nil)) | |
1222 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1223 | - | $Tuple2(((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult)) | |
1224 | - | } | |
1225 | - | } | |
1226 | - | } | |
1227 | - | } | |
1228 | - | else throw("Strict value is not equal to itself.") | |
1229 | - | } | |
1230 | - | ||
1231 | - | ||
1232 | - | ||
1233 | - | @Callable(i) | |
1234 | - | func exchangeResourcesLandDelivery (amounts,landAssetId) = if (!(KS_ALLOW_DELIVERY)) | |
1235 | - | then throw("Delivery feature is turned off!") | |
1236 | - | else { | |
1237 | - | let prologResult = prolog() | |
1238 | - | if ((prologResult == prologResult)) | |
1239 | - | then if ((size(i.payments) != 1)) | |
1174 | + | func exchangeResourcesDuckDelivery (amounts) = { | |
1175 | + | let prologResult = prolog() | |
1176 | + | if ((prologResult == prologResult)) | |
1177 | + | then { | |
1178 | + | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1179 | + | if ((size(i.payments) != 1)) | |
1240 | 1180 | then throw("exactly 1 payment must be attached") | |
1241 | 1181 | else { | |
1242 | 1182 | let pmt = i.payments[0] | |
1243 | 1183 | let amt = pmt.amount | |
1244 | 1184 | if (if (!(isDefined(pmt.assetId))) | |
1245 | 1185 | then true | |
1246 | 1186 | else (value(pmt.assetId) != usdtAssetId)) | |
1247 | 1187 | then throw("USDT payments only!") | |
1248 | 1188 | else { | |
1249 | - | let user = i.caller | |
1250 | - | let addr = toString(user) | |
1251 | - | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1252 | - | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1253 | - | then throw((("NFT " + asset.name) + " is not staked")) | |
1189 | + | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1190 | + | let resList = split(currentPack[bpIdxRes], "_") | |
1191 | + | let matList = split(currentPack[bpIdxMat], "_") | |
1192 | + | let $t04271642822 = exchangeResourcesCommon(resList, matList, amounts) | |
1193 | + | let newRes = $t04271642822._1 | |
1194 | + | let newMat = $t04271642822._2 | |
1195 | + | let usdtSpent = $t04271642822._3 | |
1196 | + | let totalAmountConverted = $t04271642822._4 | |
1197 | + | let feePart = fraction(usdtSpent, DELIVERY_FEE15, MULT6) | |
1198 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY15]) | |
1199 | + | let usdtSpentWithFee = (usdtSpent + fee) | |
1200 | + | if ((usdtSpentWithFee > amt)) | |
1201 | + | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1254 | 1202 | else { | |
1255 | - | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1256 | - | if ((owner != addr)) | |
1257 | - | then throw((LANDPREFIX + " is not yours")) | |
1258 | - | else { | |
1259 | - | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1260 | - | let currentWh = split_4C(wh, ":") | |
1261 | - | let resList = split(currentWh[whIdxRes], "_") | |
1262 | - | let matList = split(currentWh[whIdxMat], "_") | |
1263 | - | let $t04544745553 = exchangeResourcesCommon(resList, matList, amounts) | |
1264 | - | let newRes = $t04544745553._1 | |
1265 | - | let newMat = $t04544745553._2 | |
1266 | - | let usdtSpent = $t04544745553._3 | |
1267 | - | let totalAmountConverted = $t04544745553._4 | |
1268 | - | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newRes, "_"), makeString(newMat, "_"), currentWh[whIdxProd], currentWh[whIdxLOFT]], ":") | |
1269 | - | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1270 | - | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalAmountConverted, MULT8)], nil)) | |
1271 | - | let feePart = fraction(usdtSpent, DELIVERY_FEE15, MULT6) | |
1272 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY15]) | |
1273 | - | let usdtSpentWithFee = (usdtSpent + fee) | |
1274 | - | if ((usdtSpentWithFee > amt)) | |
1275 | - | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1276 | - | else { | |
1277 | - | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1278 | - | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1279 | - | else nil | |
1280 | - | let activitiesAmount = (usdtSpent / 100) | |
1281 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1282 | - | $Tuple2(((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult)) | |
1283 | - | } | |
1284 | - | } | |
1203 | + | let newPack = makeString([currentPack[bpIdxLevel], makeString(newRes, "_"), makeString(newMat, "_"), currentPack[bpIdxProd]], ":") | |
1204 | + | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1205 | + | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1206 | + | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1207 | + | else nil | |
1208 | + | let activitiesAmount = (usdtSpent / 100) | |
1209 | + | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpTrade, totalAmountConverted, MULT8)], nil)) | |
1210 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1211 | + | $Tuple2(((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult)) | |
1285 | 1212 | } | |
1286 | 1213 | } | |
1287 | 1214 | } | |
1288 | - | else throw("Strict value is not equal to itself.") | |
1289 | - | } | |
1215 | + | } | |
1216 | + | else throw("Strict value is not equal to itself.") | |
1217 | + | } | |
1218 | + | ||
1219 | + | ||
1220 | + | ||
1221 | + | @Callable(i) | |
1222 | + | func exchangeResourcesLandDelivery (amounts,landAssetId) = { | |
1223 | + | let prologResult = prolog() | |
1224 | + | if ((prologResult == prologResult)) | |
1225 | + | then if ((size(i.payments) != 1)) | |
1226 | + | then throw("exactly 1 payment must be attached") | |
1227 | + | else { | |
1228 | + | let pmt = i.payments[0] | |
1229 | + | let amt = pmt.amount | |
1230 | + | if (if (!(isDefined(pmt.assetId))) | |
1231 | + | then true | |
1232 | + | else (value(pmt.assetId) != usdtAssetId)) | |
1233 | + | then throw("USDT payments only!") | |
1234 | + | else { | |
1235 | + | let user = i.caller | |
1236 | + | let addr = toString(user) | |
1237 | + | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1238 | + | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1239 | + | then throw((("NFT " + asset.name) + " is not staked")) | |
1240 | + | else { | |
1241 | + | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1242 | + | if ((owner != addr)) | |
1243 | + | then throw((LANDPREFIX + " is not yours")) | |
1244 | + | else { | |
1245 | + | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1246 | + | let currentWh = split_4C(wh, ":") | |
1247 | + | let resList = split(currentWh[whIdxRes], "_") | |
1248 | + | let matList = split(currentWh[whIdxMat], "_") | |
1249 | + | let $t04500745113 = exchangeResourcesCommon(resList, matList, amounts) | |
1250 | + | let newRes = $t04500745113._1 | |
1251 | + | let newMat = $t04500745113._2 | |
1252 | + | let usdtSpent = $t04500745113._3 | |
1253 | + | let totalAmountConverted = $t04500745113._4 | |
1254 | + | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newRes, "_"), makeString(newMat, "_"), currentWh[whIdxProd], currentWh[whIdxLOFT]], ":") | |
1255 | + | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1256 | + | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpTrade, totalAmountConverted, MULT8)], nil)) | |
1257 | + | let feePart = fraction(usdtSpent, DELIVERY_FEE15, MULT6) | |
1258 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY15]) | |
1259 | + | let usdtSpentWithFee = (usdtSpent + fee) | |
1260 | + | if ((usdtSpentWithFee > amt)) | |
1261 | + | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(usdtSpent, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1262 | + | else { | |
1263 | + | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1264 | + | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1265 | + | else nil | |
1266 | + | let activitiesAmount = (usdtSpent / 100) | |
1267 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1268 | + | $Tuple2(((rest :+ ScriptTransfer(restContract, activitiesAmount, usdtAssetId)) :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult)) | |
1269 | + | } | |
1270 | + | } | |
1271 | + | } | |
1272 | + | } | |
1273 | + | } | |
1274 | + | else throw("Strict value is not equal to itself.") | |
1275 | + | } | |
1290 | 1276 | ||
1291 | 1277 | ||
1292 | 1278 | ||
1293 | 1279 | @Callable(i) | |
1294 | 1280 | func craftGoods (productIdx,quantity) = { | |
1295 | 1281 | let prologResult = prolog() | |
1296 | 1282 | if ((prologResult == prologResult)) | |
1297 | 1283 | then if ((size(i.payments) != 1)) | |
1298 | 1284 | then throw("exactly 1 payment must be attached") | |
1299 | 1285 | else { | |
1300 | 1286 | let pmt = i.payments[0] | |
1301 | 1287 | let amt = pmt.amount | |
1302 | 1288 | if (if (!(isDefined(pmt.assetId))) | |
1303 | 1289 | then true | |
1304 | 1290 | else (value(pmt.assetId) != usdtAssetId)) | |
1305 | 1291 | then throw("USDT payments only!") | |
1306 | 1292 | else if ((amt != MULT6)) | |
1307 | 1293 | then throw((("exactly " + fixedPoint(CRAFT_USDT_COST, 6)) + " USDT must be attached as payment")) | |
1308 | 1294 | else { | |
1309 | 1295 | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1310 | 1296 | let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_") | |
1311 | 1297 | if ((curLocation[locIdxType] != "M")) | |
1312 | 1298 | then throw(("Duck location type should be Manufactory, but is " + curLocation[locIdxType])) | |
1313 | 1299 | else { | |
1314 | 1300 | let cont = curLocation[locIdxContinent] | |
1315 | 1301 | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1316 | 1302 | let matList = split(currentPack[bpIdxMat], "_") | |
1317 | 1303 | let prodList = if ((currentPack[bpIdxProd] == "")) | |
1318 | 1304 | then nil | |
1319 | 1305 | else split_4C(currentPack[bpIdxProd], "_") | |
1320 | - | let $ | |
1321 | - | let newMat = $ | |
1322 | - | let newProd = $ | |
1323 | - | let matSpent = $ | |
1306 | + | let $t04743847535 = craftGoodsCommon(matList, prodList, cont, productIdx, quantity) | |
1307 | + | let newMat = $t04743847535._1 | |
1308 | + | let newProd = $t04743847535._2 | |
1309 | + | let matSpent = $t04743847535._3 | |
1324 | 1310 | let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), makeString_2C(newProd, "_")], ":") | |
1325 | 1311 | let result = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1326 | 1312 | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpCraft, matSpent, MULT8)], nil)) | |
1327 | 1313 | $Tuple2(nil, $Tuple3(result, prologResult, statsResult)) | |
1328 | 1314 | } | |
1329 | 1315 | } | |
1330 | 1316 | } | |
1331 | 1317 | else throw("Strict value is not equal to itself.") | |
1332 | 1318 | } | |
1333 | 1319 | ||
1334 | 1320 | ||
1335 | 1321 | ||
1336 | 1322 | @Callable(i) | |
1337 | - | func craftGoodsDuckDelivery (productIdx,quantity,manufactoryContinent) = if (!(KS_ALLOW_DELIVERY)) | |
1338 | - | then throw("Delivery feature is turned off!") | |
1339 | - | else { | |
1340 | - | let prologResult = prolog() | |
1341 | - | if ((prologResult == prologResult)) | |
1342 | - | then { | |
1343 | - | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1344 | - | if ((size(i.payments) != 1)) | |
1345 | - | then throw("exactly 1 payment must be attached") | |
1346 | - | else { | |
1347 | - | let pmt = i.payments[0] | |
1348 | - | let amt = pmt.amount | |
1349 | - | if (if (!(isDefined(pmt.assetId))) | |
1350 | - | then true | |
1351 | - | else (value(pmt.assetId) != usdtAssetId)) | |
1352 | - | then throw("USDT payments only!") | |
1353 | - | else { | |
1354 | - | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1355 | - | let matList = split(currentPack[bpIdxMat], "_") | |
1356 | - | let prodList = if ((currentPack[bpIdxProd] == "")) | |
1357 | - | then nil | |
1358 | - | else split_4C(currentPack[bpIdxProd], "_") | |
1359 | - | let $t04920049313 = craftGoodsCommon(matList, prodList, manufactoryContinent, productIdx, quantity) | |
1360 | - | let newMat = $t04920049313._1 | |
1361 | - | let newProd = $t04920049313._2 | |
1362 | - | let matSpent = $t04920049313._3 | |
1363 | - | let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), makeString_2C(newProd, "_")], ":") | |
1364 | - | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1365 | - | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpCraft, matSpent, MULT8)], nil)) | |
1366 | - | let feePart = fraction(quantity, MIN_USDT_FEE_DELIVERY, CRAFT_DELIVERY_COEFF) | |
1367 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1368 | - | let usdtSpentWithFee = (CRAFT_USDT_COST + fee) | |
1369 | - | if ((usdtSpentWithFee > amt)) | |
1370 | - | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(CRAFT_USDT_COST, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1371 | - | else { | |
1372 | - | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1373 | - | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1374 | - | else nil | |
1375 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1376 | - | $Tuple2((rest :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult)) | |
1377 | - | } | |
1378 | - | } | |
1379 | - | } | |
1380 | - | } | |
1381 | - | else throw("Strict value is not equal to itself.") | |
1382 | - | } | |
1383 | - | ||
1384 | - | ||
1385 | - | ||
1386 | - | @Callable(i) | |
1387 | - | func craftGoodsLandDelivery (productIdx,quantity,landAssetId,manufactoryContinent) = if (!(KS_ALLOW_DELIVERY)) | |
1388 | - | then throw("Delivery feature is turned off!") | |
1389 | - | else { | |
1390 | - | let prologResult = prolog() | |
1391 | - | if ((prologResult == prologResult)) | |
1392 | - | then if ((size(i.payments) != 1)) | |
1323 | + | func craftGoodsDuckDelivery (productIdx,quantity,manufactoryContinent) = { | |
1324 | + | let prologResult = prolog() | |
1325 | + | if ((prologResult == prologResult)) | |
1326 | + | then { | |
1327 | + | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1328 | + | if ((size(i.payments) != 1)) | |
1393 | 1329 | then throw("exactly 1 payment must be attached") | |
1394 | 1330 | else { | |
1395 | 1331 | let pmt = i.payments[0] | |
1396 | 1332 | let amt = pmt.amount | |
1397 | 1333 | if (if (!(isDefined(pmt.assetId))) | |
1398 | 1334 | then true | |
1399 | 1335 | else (value(pmt.assetId) != usdtAssetId)) | |
1400 | 1336 | then throw("USDT payments only!") | |
1401 | 1337 | else { | |
1402 | - | let user = i.caller | |
1403 | - | let addr = toString(user) | |
1404 | - | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1405 | - | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1406 | - | then throw((("NFT " + asset.name) + " is not staked")) | |
1338 | + | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1339 | + | let matList = split(currentPack[bpIdxMat], "_") | |
1340 | + | let prodList = if ((currentPack[bpIdxProd] == "")) | |
1341 | + | then nil | |
1342 | + | else split_4C(currentPack[bpIdxProd], "_") | |
1343 | + | let $t04868348796 = craftGoodsCommon(matList, prodList, manufactoryContinent, productIdx, quantity) | |
1344 | + | let newMat = $t04868348796._1 | |
1345 | + | let newProd = $t04868348796._2 | |
1346 | + | let matSpent = $t04868348796._3 | |
1347 | + | let newPack = makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], makeString(newMat, "_"), makeString_2C(newProd, "_")], ":") | |
1348 | + | let backpackResult = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newPack], nil)) | |
1349 | + | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpCraft, matSpent, MULT8)], nil)) | |
1350 | + | let feePart = fraction(quantity, MIN_USDT_FEE_DELIVERY, CRAFT_DELIVERY_COEFF) | |
1351 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1352 | + | let usdtSpentWithFee = (CRAFT_USDT_COST + fee) | |
1353 | + | if ((usdtSpentWithFee > amt)) | |
1354 | + | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(CRAFT_USDT_COST, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1407 | 1355 | else { | |
1408 | - | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1409 | - | if ((owner != addr)) | |
1410 | - | then throw((LANDPREFIX + " is not yours")) | |
1411 | - | else { | |
1412 | - | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1413 | - | let currentWh = split_4C(wh, ":") | |
1414 | - | let matList = split(currentWh[whIdxMat], "_") | |
1415 | - | let prodList = if ((currentWh[whIdxProd] == "")) | |
1416 | - | then nil | |
1417 | - | else split_4C(currentWh[whIdxProd], "_") | |
1418 | - | let $t05155651669 = craftGoodsCommon(matList, prodList, manufactoryContinent, productIdx, quantity) | |
1419 | - | let newMat = $t05155651669._1 | |
1420 | - | let newProd = $t05155651669._2 | |
1421 | - | let matSpent = $t05155651669._3 | |
1422 | - | let whStr = makeString_2C([currentWh[whIdxLevels], currentWh[whIdxRes], makeString(newMat, "_"), makeString_2C(newProd, "_"), currentWh[whIdxLOFT]], ":") | |
1423 | - | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1424 | - | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpCraft, matSpent, MULT8)], nil)) | |
1425 | - | let feePart = fraction(quantity, MIN_USDT_FEE_DELIVERY, CRAFT_DELIVERY_COEFF) | |
1426 | - | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1427 | - | let usdtSpentWithFee = (CRAFT_USDT_COST + fee) | |
1428 | - | if ((usdtSpentWithFee > amt)) | |
1429 | - | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(CRAFT_USDT_COST, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1430 | - | else { | |
1431 | - | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1432 | - | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1433 | - | else nil | |
1434 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1435 | - | $Tuple2((rest :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult)) | |
1436 | - | } | |
1437 | - | } | |
1356 | + | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1357 | + | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1358 | + | else nil | |
1359 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1360 | + | $Tuple2((rest :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(backpackResult, prologResult, statsResult)) | |
1438 | 1361 | } | |
1439 | 1362 | } | |
1440 | 1363 | } | |
1441 | - | else throw("Strict value is not equal to itself.") | |
1442 | - | } | |
1364 | + | } | |
1365 | + | else throw("Strict value is not equal to itself.") | |
1366 | + | } | |
1367 | + | ||
1368 | + | ||
1369 | + | ||
1370 | + | @Callable(i) | |
1371 | + | func craftGoodsLandDelivery (productIdx,quantity,landAssetId,manufactoryContinent) = { | |
1372 | + | let prologResult = prolog() | |
1373 | + | if ((prologResult == prologResult)) | |
1374 | + | then if ((size(i.payments) != 1)) | |
1375 | + | then throw("exactly 1 payment must be attached") | |
1376 | + | else { | |
1377 | + | let pmt = i.payments[0] | |
1378 | + | let amt = pmt.amount | |
1379 | + | if (if (!(isDefined(pmt.assetId))) | |
1380 | + | then true | |
1381 | + | else (value(pmt.assetId) != usdtAssetId)) | |
1382 | + | then throw("USDT payments only!") | |
1383 | + | else { | |
1384 | + | let user = i.caller | |
1385 | + | let addr = toString(user) | |
1386 | + | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1387 | + | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1388 | + | then throw((("NFT " + asset.name) + " is not staked")) | |
1389 | + | else { | |
1390 | + | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1391 | + | if ((owner != addr)) | |
1392 | + | then throw((LANDPREFIX + " is not yours")) | |
1393 | + | else { | |
1394 | + | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1395 | + | let currentWh = split_4C(wh, ":") | |
1396 | + | let matList = split(currentWh[whIdxMat], "_") | |
1397 | + | let prodList = if ((currentWh[whIdxProd] == "")) | |
1398 | + | then nil | |
1399 | + | else split_4C(currentWh[whIdxProd], "_") | |
1400 | + | let $t05096251075 = craftGoodsCommon(matList, prodList, manufactoryContinent, productIdx, quantity) | |
1401 | + | let newMat = $t05096251075._1 | |
1402 | + | let newProd = $t05096251075._2 | |
1403 | + | let matSpent = $t05096251075._3 | |
1404 | + | let whStr = makeString_2C([currentWh[whIdxLevels], currentWh[whIdxRes], makeString(newMat, "_"), makeString_2C(newProd, "_"), currentWh[whIdxLOFT]], ":") | |
1405 | + | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1406 | + | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [addr, fraction(xpCraft, matSpent, MULT8)], nil)) | |
1407 | + | let feePart = fraction(quantity, MIN_USDT_FEE_DELIVERY, CRAFT_DELIVERY_COEFF) | |
1408 | + | let fee = max([feePart, MIN_USDT_FEE_DELIVERY]) | |
1409 | + | let usdtSpentWithFee = (CRAFT_USDT_COST + fee) | |
1410 | + | if ((usdtSpentWithFee > amt)) | |
1411 | + | then throw((((((("Insufficient payment! Attached=" + fixedPoint(amt, 6)) + ", required=") + fixedPoint(CRAFT_USDT_COST, 6)) + "+") + fixedPoint(fee, 6)) + "(delivery fee)")) | |
1412 | + | else { | |
1413 | + | let rest = if (((amt - usdtSpentWithFee) > 0)) | |
1414 | + | then [ScriptTransfer(i.caller, (amt - usdtSpentWithFee), usdtAssetId)] | |
1415 | + | else nil | |
1416 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1417 | + | $Tuple2((rest :+ IntegerEntry(deliveryFundKey, (fundTotal + fee))), $Tuple3(whSave, prologResult, statsResult)) | |
1418 | + | } | |
1419 | + | } | |
1420 | + | } | |
1421 | + | } | |
1422 | + | } | |
1423 | + | else throw("Strict value is not equal to itself.") | |
1424 | + | } | |
1443 | 1425 | ||
1444 | 1426 | ||
1445 | 1427 | ||
1446 | 1428 | @Callable(i) | |
1447 | 1429 | func setWarehouseOrder (newOrderStr,landAssetId) = { | |
1448 | 1430 | let user = i.originCaller | |
1449 | 1431 | let addr = toString(user) | |
1450 | 1432 | let result = if ((user != restContract)) | |
1451 | 1433 | then checkBlocked() | |
1452 | 1434 | else false | |
1453 | 1435 | let asset = value(assetInfo(fromBase58String(landAssetId))) | |
1454 | 1436 | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(landAssetId))))) | |
1455 | 1437 | then throw((("NFT " + asset.name) + " is not staked")) | |
1456 | 1438 | else { | |
1457 | 1439 | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1458 | 1440 | if (if ((user != restContract)) | |
1459 | 1441 | then (owner != addr) | |
1460 | 1442 | else false) | |
1461 | 1443 | then throw((LANDPREFIX + " is not yours")) | |
1462 | 1444 | else { | |
1463 | 1445 | let newOrder = split_4C(newOrderStr, ":") | |
1464 | 1446 | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [landAssetId], nil)) | |
1465 | 1447 | let currentWh = split_4C(wh, ":") | |
1466 | 1448 | let loft = split(currentWh[whIdxLOFT], "_") | |
1467 | 1449 | let whTotal = parseIntValue(loft[volTotal]) | |
1468 | 1450 | let ordKey = keyOrderByLand(landAssetId) | |
1469 | 1451 | let currentOrd = getOrder(ordKey) | |
1470 | 1452 | let z = setInternal(currentWh, currentOrd, newOrder) | |
1471 | 1453 | let buyVolSaldo = z._4 | |
1472 | 1454 | let sellVolSaldo = z._5 | |
1473 | 1455 | let whOccupied = z._7 | |
1474 | 1456 | let whLocked = (buyVolSaldo + sellVolSaldo) | |
1475 | 1457 | let whFree = ((whTotal - whOccupied) - whLocked) | |
1476 | 1458 | if ((0 > whFree)) | |
1477 | 1459 | 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")) | |
1478 | 1460 | else { | |
1479 | 1461 | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(z._1, "_"), makeString(z._2, "_"), makeString_2C(z._3, "_"), toString(whLocked)], ":") | |
1480 | 1462 | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, landAssetId], nil)) | |
1481 | 1463 | let usdSaldo = z._6 | |
1482 | 1464 | let actions = if ((usdSaldo > 0)) | |
1483 | 1465 | then if ((size(i.payments) != 1)) | |
1484 | 1466 | then throw("exactly 1 payment must be attached") | |
1485 | 1467 | else { | |
1486 | 1468 | let pmt = i.payments[0] | |
1487 | 1469 | let amt = pmt.amount | |
1488 | 1470 | let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WAVES can't be used as payment") | |
1489 | 1471 | if ((pmtAssetId != usdtAssetId)) | |
1490 | 1472 | then throw("USDT payments only!") | |
1491 | 1473 | else if ((amt != usdSaldo)) | |
1492 | 1474 | then throw(("Payment needed is " + toString(usdSaldo))) | |
1493 | 1475 | else [StringEntry(ordKey, newOrderStr)] | |
1494 | 1476 | } | |
1495 | 1477 | else if ((usdSaldo == 0)) | |
1496 | 1478 | then if ((size(i.payments) != 0)) | |
1497 | 1479 | then throw("No payments needed") | |
1498 | 1480 | else [StringEntry(ordKey, newOrderStr)] | |
1499 | 1481 | else if ((size(i.payments) != 0)) | |
1500 | 1482 | then throw("No payments needed") | |
1501 | 1483 | else [ScriptTransfer(addressFromStringValue(owner), -(usdSaldo), usdtAssetId), StringEntry(ordKey, newOrderStr)] | |
1502 | 1484 | $Tuple2(actions, $Tuple2(result, whSave)) | |
1503 | 1485 | } | |
1504 | 1486 | } | |
1505 | 1487 | } | |
1506 | 1488 | } | |
1507 | 1489 | ||
1508 | 1490 | ||
1509 | 1491 | ||
1510 | 1492 | @Callable(i) | |
1511 | 1493 | func acceptWarehouseOrder (bpOrderStr,shopLandAssetId,duckAssetId) = { | |
1512 | 1494 | let prologResult = prolog() | |
1513 | 1495 | if ((prologResult == prologResult)) | |
1514 | 1496 | then { | |
1515 | 1497 | let caller = i.originCaller | |
1516 | 1498 | let callerAddr = toString(caller) | |
1517 | 1499 | let stakedDuckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(callerAddr)), "You don't have a duck staked") | |
1518 | 1500 | let curLocation = valueOrElse(getString(stakingContract, keyDuckLocation(stakedDuckAssetId)), DEFAULTLOCATION) | |
1519 | 1501 | let loc = split(value(curLocation), "_") | |
1520 | 1502 | if ((loc[locIdxType] != "L")) | |
1521 | 1503 | then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L")) | |
1522 | 1504 | else if ((stakedDuckAssetId != duckAssetId)) | |
1523 | 1505 | then throw(((("Your staked duck is " + stakedDuckAssetId) + ", but passed ") + duckAssetId)) | |
1524 | 1506 | else { | |
1525 | 1507 | let bpKey = keyBackpackByDuck(duckAssetId) | |
1526 | 1508 | let currentPack = getBackpack(bpKey) | |
1527 | 1509 | let bpResList = split(currentPack[bpIdxRes], "_") | |
1528 | 1510 | let bpMatList = split(currentPack[bpIdxMat], "_") | |
1529 | 1511 | let bpProdList = if ((currentPack[bpIdxProd] == "")) | |
1530 | 1512 | then nil | |
1531 | 1513 | else split_4C(currentPack[bpIdxProd], "_") | |
1532 | - | let $ | |
1533 | - | let shopAction = $ | |
1534 | - | let newUserRes = $ | |
1535 | - | let newUserMat = $ | |
1536 | - | let newUserProd = $ | |
1537 | - | let usdWh2BpSaldo = $ | |
1538 | - | let usdBp2WhSaldo = $ | |
1539 | - | let xpAmount = $ | |
1540 | - | let shopLandOwner = $ | |
1541 | - | let shopWhSave = $ | |
1542 | - | let accStatsResult = $ | |
1514 | + | let $t05698857228 = acceptShopOrderCommon(shopLandAssetId, callerAddr, bpOrderStr, bpResList, bpMatList, bpProdList) | |
1515 | + | let shopAction = $t05698857228._1 | |
1516 | + | let newUserRes = $t05698857228._2 | |
1517 | + | let newUserMat = $t05698857228._3 | |
1518 | + | let newUserProd = $t05698857228._4 | |
1519 | + | let usdWh2BpSaldo = $t05698857228._5 | |
1520 | + | let usdBp2WhSaldo = $t05698857228._6 | |
1521 | + | let xpAmount = $t05698857228._7 | |
1522 | + | let shopLandOwner = $t05698857228._8 | |
1523 | + | let shopWhSave = $t05698857228._9 | |
1524 | + | let accStatsResult = $t05698857228._10 | |
1543 | 1525 | let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, 0)] | |
1544 | 1526 | let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, 0) | |
1545 | 1527 | let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString_2C(newUserProd, "_")], ":") | |
1546 | 1528 | let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil)) | |
1547 | 1529 | let duckStatsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpShop, xpAmount, MULT8)], nil)) | |
1548 | 1530 | $Tuple2((actions1 ++ actions2), $Tuple5(prologResult, shopWhSave, bpSave, duckStatsResult, accStatsResult)) | |
1549 | 1531 | } | |
1550 | 1532 | } | |
1551 | 1533 | else throw("Strict value is not equal to itself.") | |
1552 | 1534 | } | |
1553 | 1535 | ||
1554 | 1536 | ||
1555 | 1537 | ||
1556 | 1538 | @Callable(i) | |
1557 | - | func acceptShopOrderDuckDelivery (orderStr,shopLandAssetId) = if (!(KS_ALLOW_DELIVERY)) | |
1558 | - | then throw("Delivery feature is turned off!") | |
1559 | - | else { | |
1560 | - | let prologResult = prolog() | |
1561 | - | if ((prologResult == prologResult)) | |
1562 | - | then { | |
1563 | - | let caller = i.originCaller | |
1564 | - | let callerAddr = toString(caller) | |
1565 | - | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(callerAddr)), "You don't have a duck staked") | |
1566 | - | let bpKey = keyBackpackByDuck(duckAssetId) | |
1567 | - | let currentPack = getBackpack(bpKey) | |
1568 | - | let bpResList = split(currentPack[bpIdxRes], "_") | |
1569 | - | let bpMatList = split(currentPack[bpIdxMat], "_") | |
1570 | - | let bpProdList = if ((currentPack[bpIdxProd] == "")) | |
1571 | - | then nil | |
1572 | - | else split_4C(currentPack[bpIdxProd], "_") | |
1573 | - | let $t05926459502 = acceptShopOrderCommon(shopLandAssetId, callerAddr, orderStr, bpResList, bpMatList, bpProdList) | |
1574 | - | let shopAction = $t05926459502._1 | |
1575 | - | let newUserRes = $t05926459502._2 | |
1576 | - | let newUserMat = $t05926459502._3 | |
1577 | - | let newUserProd = $t05926459502._4 | |
1578 | - | let usdWh2BpSaldo = $t05926459502._5 | |
1579 | - | let usdBp2WhSaldo = $t05926459502._6 | |
1580 | - | let xpAmount = $t05926459502._7 | |
1581 | - | let shopLandOwner = $t05926459502._8 | |
1582 | - | let shopWhSave = $t05926459502._9 | |
1583 | - | let accStatsResult = $t05926459502._10 | |
1584 | - | let deliveryFeePart = fraction((usdBp2WhSaldo + usdWh2BpSaldo), DELIVERY_FEE, MULT6) | |
1585 | - | let deliveryFee = max([deliveryFeePart, MIN_USDT_FEE_DELIVERY]) | |
1586 | - | let spentFee = fraction(deliveryFee, usdBp2WhSaldo, (usdBp2WhSaldo + usdWh2BpSaldo)) | |
1587 | - | let receivedFee = (deliveryFee - spentFee) | |
1588 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1589 | - | let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, receivedFee)] | |
1590 | - | let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, spentFee) | |
1591 | - | let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString_2C(newUserProd, "_")], ":") | |
1592 | - | let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil)) | |
1593 | - | let duckStatsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpShop, xpAmount, MULT8)], nil)) | |
1594 | - | $Tuple2(((actions1 ++ actions2) :+ IntegerEntry(deliveryFundKey, (fundTotal + deliveryFee))), $Tuple5(prologResult, shopWhSave, bpSave, duckStatsResult, accStatsResult)) | |
1595 | - | } | |
1596 | - | else throw("Strict value is not equal to itself.") | |
1597 | - | } | |
1539 | + | func acceptShopOrderDuckDelivery (orderStr,shopLandAssetId) = { | |
1540 | + | let prologResult = prolog() | |
1541 | + | if ((prologResult == prologResult)) | |
1542 | + | then { | |
1543 | + | let caller = i.originCaller | |
1544 | + | let callerAddr = toString(caller) | |
1545 | + | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(callerAddr)), "You don't have a duck staked") | |
1546 | + | let bpKey = keyBackpackByDuck(duckAssetId) | |
1547 | + | let currentPack = getBackpack(bpKey) | |
1548 | + | let bpResList = split(currentPack[bpIdxRes], "_") | |
1549 | + | let bpMatList = split(currentPack[bpIdxMat], "_") | |
1550 | + | let bpProdList = if ((currentPack[bpIdxProd] == "")) | |
1551 | + | then nil | |
1552 | + | else split_4C(currentPack[bpIdxProd], "_") | |
1553 | + | let $t05859358831 = acceptShopOrderCommon(shopLandAssetId, callerAddr, orderStr, bpResList, bpMatList, bpProdList) | |
1554 | + | let shopAction = $t05859358831._1 | |
1555 | + | let newUserRes = $t05859358831._2 | |
1556 | + | let newUserMat = $t05859358831._3 | |
1557 | + | let newUserProd = $t05859358831._4 | |
1558 | + | let usdWh2BpSaldo = $t05859358831._5 | |
1559 | + | let usdBp2WhSaldo = $t05859358831._6 | |
1560 | + | let xpAmount = $t05859358831._7 | |
1561 | + | let shopLandOwner = $t05859358831._8 | |
1562 | + | let shopWhSave = $t05859358831._9 | |
1563 | + | let accStatsResult = $t05859358831._10 | |
1564 | + | let deliveryFeePart = fraction((usdBp2WhSaldo + usdWh2BpSaldo), DELIVERY_FEE, MULT6) | |
1565 | + | let deliveryFee = max([deliveryFeePart, MIN_USDT_FEE_DELIVERY]) | |
1566 | + | let spentFee = fraction(deliveryFee, usdBp2WhSaldo, (usdBp2WhSaldo + usdWh2BpSaldo)) | |
1567 | + | let receivedFee = (deliveryFee - spentFee) | |
1568 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1569 | + | let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, receivedFee)] | |
1570 | + | let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, spentFee) | |
1571 | + | let newBpStr = makeString_2C([currentPack[bpIdxLevel], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString_2C(newUserProd, "_")], ":") | |
1572 | + | let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil)) | |
1573 | + | let duckStatsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpShop, xpAmount, MULT8)], nil)) | |
1574 | + | $Tuple2(((actions1 ++ actions2) :+ IntegerEntry(deliveryFundKey, (fundTotal + deliveryFee))), $Tuple5(prologResult, shopWhSave, bpSave, duckStatsResult, accStatsResult)) | |
1575 | + | } | |
1576 | + | else throw("Strict value is not equal to itself.") | |
1577 | + | } | |
1598 | 1578 | ||
1599 | 1579 | ||
1600 | 1580 | ||
1601 | 1581 | @Callable(i) | |
1602 | - | func acceptShopOrderLandDelivery (orderStr,shopLandAssetId,myLandAssetId) = if (!(KS_ALLOW_DELIVERY)) | |
1603 | - | then throw("Delivery feature is turned off!") | |
1604 | - | else { | |
1605 | - | let prologResult = prolog() | |
1606 | - | if ((prologResult == prologResult)) | |
1607 | - | then { | |
1608 | - | let caller = i.originCaller | |
1609 | - | let callerAddr = toString(caller) | |
1610 | - | let asset = value(assetInfo(fromBase58String(myLandAssetId))) | |
1611 | - | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(myLandAssetId))))) | |
1612 | - | then throw((("NFT " + asset.name) + " is not staked")) | |
1613 | - | else { | |
1614 | - | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(myLandAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1615 | - | if ((owner != callerAddr)) | |
1616 | - | then throw((LANDPREFIX + " is not yours")) | |
1617 | - | else { | |
1618 | - | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [myLandAssetId], nil)) | |
1619 | - | let currentWh = split_4C(wh, ":") | |
1620 | - | let resList = split(currentWh[whIdxRes], "_") | |
1621 | - | let matList = split(currentWh[whIdxMat], "_") | |
1622 | - | let prodList = if ((currentWh[whIdxProd] == "")) | |
1623 | - | then nil | |
1624 | - | else split_4C(currentWh[whIdxProd], "_") | |
1625 | - | let $t06170061932 = acceptShopOrderCommon(shopLandAssetId, callerAddr, orderStr, resList, matList, prodList) | |
1626 | - | let shopAction = $t06170061932._1 | |
1627 | - | let newUserRes = $t06170061932._2 | |
1628 | - | let newUserMat = $t06170061932._3 | |
1629 | - | let newUserProd = $t06170061932._4 | |
1630 | - | let usdWh2BpSaldo = $t06170061932._5 | |
1631 | - | let usdBp2WhSaldo = $t06170061932._6 | |
1632 | - | let xpAmount = $t06170061932._7 | |
1633 | - | let shopLandOwner = $t06170061932._8 | |
1634 | - | let shopWhSave = $t06170061932._9 | |
1635 | - | let accStatsResult = $t06170061932._10 | |
1636 | - | let deliveryFeePart = fraction((usdBp2WhSaldo + usdWh2BpSaldo), DELIVERY_FEE, MULT6) | |
1637 | - | let deliveryFee = max([deliveryFeePart, MIN_USDT_FEE_DELIVERY]) | |
1638 | - | let spentFee = fraction(deliveryFee, usdBp2WhSaldo, (usdBp2WhSaldo + usdWh2BpSaldo)) | |
1639 | - | let receivedFee = (deliveryFee - spentFee) | |
1640 | - | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1641 | - | let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, receivedFee)] | |
1642 | - | let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, spentFee) | |
1643 | - | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString(newUserProd, "_"), currentWh[whIdxLOFT]], ":") | |
1644 | - | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, myLandAssetId], nil)) | |
1645 | - | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [callerAddr, fraction(xpShop, xpAmount, MULT8)], nil)) | |
1646 | - | $Tuple2(((actions1 ++ actions2) :+ IntegerEntry(deliveryFundKey, (fundTotal + deliveryFee))), $Tuple5(prologResult, shopWhSave, whSave, statsResult, accStatsResult)) | |
1647 | - | } | |
1648 | - | } | |
1649 | - | } | |
1650 | - | else throw("Strict value is not equal to itself.") | |
1651 | - | } | |
1582 | + | func acceptShopOrderLandDelivery (orderStr,shopLandAssetId,myLandAssetId) = { | |
1583 | + | let prologResult = prolog() | |
1584 | + | if ((prologResult == prologResult)) | |
1585 | + | then { | |
1586 | + | let caller = i.originCaller | |
1587 | + | let callerAddr = toString(caller) | |
1588 | + | let asset = value(assetInfo(fromBase58String(myLandAssetId))) | |
1589 | + | if (!(isDefined(getInteger(stakingContract, keyStakedTimeByAssetId(myLandAssetId))))) | |
1590 | + | then throw((("NFT " + asset.name) + " is not staked")) | |
1591 | + | else { | |
1592 | + | let owner = valueOrErrorMessage(getString(stakingContract, keyLandAssetIdToOwner(myLandAssetId)), (("NFT " + asset.name) + " is orphaned")) | |
1593 | + | if ((owner != callerAddr)) | |
1594 | + | then throw((LANDPREFIX + " is not yours")) | |
1595 | + | else { | |
1596 | + | let wh = asString(invoke(stakingContract, "getWarehouseREADONLY", [myLandAssetId], nil)) | |
1597 | + | let currentWh = split_4C(wh, ":") | |
1598 | + | let resList = split(currentWh[whIdxRes], "_") | |
1599 | + | let matList = split(currentWh[whIdxMat], "_") | |
1600 | + | let prodList = if ((currentWh[whIdxProd] == "")) | |
1601 | + | then nil | |
1602 | + | else split_4C(currentWh[whIdxProd], "_") | |
1603 | + | let $t06095261184 = acceptShopOrderCommon(shopLandAssetId, callerAddr, orderStr, resList, matList, prodList) | |
1604 | + | let shopAction = $t06095261184._1 | |
1605 | + | let newUserRes = $t06095261184._2 | |
1606 | + | let newUserMat = $t06095261184._3 | |
1607 | + | let newUserProd = $t06095261184._4 | |
1608 | + | let usdWh2BpSaldo = $t06095261184._5 | |
1609 | + | let usdBp2WhSaldo = $t06095261184._6 | |
1610 | + | let xpAmount = $t06095261184._7 | |
1611 | + | let shopLandOwner = $t06095261184._8 | |
1612 | + | let shopWhSave = $t06095261184._9 | |
1613 | + | let accStatsResult = $t06095261184._10 | |
1614 | + | let deliveryFeePart = fraction((usdBp2WhSaldo + usdWh2BpSaldo), DELIVERY_FEE, MULT6) | |
1615 | + | let deliveryFee = max([deliveryFeePart, MIN_USDT_FEE_DELIVERY]) | |
1616 | + | let spentFee = fraction(deliveryFee, usdBp2WhSaldo, (usdBp2WhSaldo + usdWh2BpSaldo)) | |
1617 | + | let receivedFee = (deliveryFee - spentFee) | |
1618 | + | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1619 | + | let actions1 = [shopAction, shop2userActions(usdWh2BpSaldo, callerAddr, receivedFee)] | |
1620 | + | let actions2 = user2shopActions(usdBp2WhSaldo, i.payments, shopLandOwner, spentFee) | |
1621 | + | let whStr = makeString_2C([currentWh[whIdxLevels], makeString(newUserRes, "_"), makeString(newUserMat, "_"), makeString(newUserProd, "_"), currentWh[whIdxLOFT]], ":") | |
1622 | + | let whSave = asString(invoke(stakingContract, "saveWarehouse", [whStr, myLandAssetId], nil)) | |
1623 | + | let statsResult = asInt(invoke(stakingContract, "updateAccStats", [callerAddr, fraction(xpShop, xpAmount, MULT8)], nil)) | |
1624 | + | $Tuple2(((actions1 ++ actions2) :+ IntegerEntry(deliveryFundKey, (fundTotal + deliveryFee))), $Tuple5(prologResult, shopWhSave, whSave, statsResult, accStatsResult)) | |
1625 | + | } | |
1626 | + | } | |
1627 | + | } | |
1628 | + | else throw("Strict value is not equal to itself.") | |
1629 | + | } | |
1652 | 1630 | ||
1653 | 1631 | ||
1654 | 1632 | ||
1655 | 1633 | @Callable(i) | |
1656 | 1634 | func sellProductsToES (amounts) = { | |
1657 | 1635 | let prologResult = prolog() | |
1658 | 1636 | if ((prologResult == prologResult)) | |
1659 | 1637 | then if ((size(i.payments) != 0)) | |
1660 | 1638 | then throw("No payments needed") | |
1661 | 1639 | else { | |
1662 | 1640 | let duckAssetId = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked") | |
1663 | 1641 | let curLocation = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_") | |
1664 | 1642 | if ((curLocation[locIdxType] != "A")) | |
1665 | 1643 | then throw(("Duck location type should be Airport, but is " + curLocation[locIdxType])) | |
1666 | 1644 | else { | |
1667 | 1645 | let currentPack = getBackpack(keyBackpackByDuck(duckAssetId)) | |
1668 | 1646 | let prodList = if ((currentPack[bpIdxProd] == "")) | |
1669 | 1647 | then nil | |
1670 | 1648 | else split_4C(currentPack[bpIdxProd], "_") | |
1671 | 1649 | let esKey = keyEsWarehouse() | |
1672 | 1650 | let existStr = getString(esKey) | |
1673 | 1651 | let existAmounts = if (isDefined(existStr)) | |
1674 | 1652 | then split_4C(value(existStr), "_") | |
1675 | 1653 | else nil | |
1676 | 1654 | func moveProd (acc,recipeStr) = { | |
1677 | 1655 | let j = acc._1 | |
1678 | 1656 | let quantity = if ((size(amounts) > j)) | |
1679 | 1657 | then amounts[j] | |
1680 | 1658 | else 0 | |
1681 | 1659 | if ((0 > quantity)) | |
1682 | 1660 | then throw("Quantity cannot be negative") | |
1683 | 1661 | else { | |
1684 | 1662 | let recipe = split(recipeStr, "_") | |
1685 | 1663 | if ((size(recipe) != RECIPESIZE)) | |
1686 | 1664 | then throw(("Fatal: unknown recipe: " + recipeStr)) | |
1687 | 1665 | else { | |
1688 | 1666 | let maxAmount = (ESMAXPACKAGES * PRODUCTPKGSIZE) | |
1689 | 1667 | let existAmount = if ((size(existAmounts) > j)) | |
1690 | 1668 | then parseIntValue(existAmounts[j]) | |
1691 | 1669 | else 0 | |
1692 | 1670 | let canBuy = (maxAmount - existAmount) | |
1693 | 1671 | if ((quantity > canBuy)) | |
1694 | 1672 | then throw(((("Warehouse can buy only " + toString(canBuy)) + " of ") + prodTypes[j])) | |
1695 | 1673 | else { | |
1696 | 1674 | let totalMat = getRecipeMaterials(recipe) | |
1697 | 1675 | let unitPrice = fraction((totalMat * ESBUYCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE)) | |
1698 | 1676 | let bpProdAmount = if ((size(prodList) > j)) | |
1699 | 1677 | then parseIntValue(prodList[j]) | |
1700 | 1678 | else 0 | |
1701 | 1679 | if ((quantity > bpProdAmount)) | |
1702 | 1680 | then throw(((("You have only " + toString(bpProdAmount)) + " of ") + prodTypes[j])) | |
1703 | 1681 | else $Tuple5((j + 1), (acc._2 + (unitPrice * quantity)), (acc._3 :+ toString((bpProdAmount - quantity))), (acc._4 :+ toString((existAmount + quantity))), (acc._5 + (totalMat * quantity))) | |
1704 | 1682 | } | |
1705 | 1683 | } | |
1706 | 1684 | } | |
1707 | 1685 | } | |
1708 | 1686 | ||
1709 | 1687 | let merged = { | |
1710 | 1688 | let $l = productionMatrix | |
1711 | 1689 | let $s = size($l) | |
1712 | 1690 | let $acc0 = $Tuple5(0, 0, nil, nil, 0) | |
1713 | 1691 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
1714 | 1692 | then $a | |
1715 | 1693 | else moveProd($a, $l[$i]) | |
1716 | 1694 | ||
1717 | 1695 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
1718 | 1696 | then $a | |
1719 | 1697 | else throw("List size exceeds 50") | |
1720 | 1698 | ||
1721 | 1699 | $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) | |
1722 | 1700 | } | |
1723 | 1701 | let newBpStr = makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString_2C(merged._3, "_")], ":") | |
1724 | 1702 | let bpSave = asString(invoke(stakingContract, "updateBackpack", [duckAssetId, newBpStr], nil)) | |
1725 | 1703 | let statsResult = asInt(invoke(stakingContract, "updateDuckStats", [duckAssetId, fraction(xpSellToEs, merged._5, (MULT8 * 10))], nil)) | |
1726 | 1704 | $Tuple2([StringEntry(esKey, makeString_2C(merged._4, "_")), ScriptTransfer(i.caller, merged._2, usdtAssetId)], $Tuple3(bpSave, prologResult, statsResult)) | |
1727 | 1705 | } | |
1728 | 1706 | } | |
1729 | 1707 | else throw("Strict value is not equal to itself.") | |
1730 | 1708 | } | |
1731 | 1709 | ||
1732 | 1710 | ||
1733 | 1711 | ||
1734 | 1712 | @Callable(i) | |
1735 | 1713 | func updateEsStorage (newStorage) = if ((i.caller != stakingContract)) | |
1736 | 1714 | then throw("Permission denied") | |
1737 | 1715 | else $Tuple2([StringEntry(keyEsWarehouse(), newStorage)], newStorage) | |
1738 | 1716 | ||
1739 | 1717 | ||
1740 | 1718 | ||
1741 | 1719 | @Callable(i) | |
1742 | 1720 | func updateDeliveryLocked (newAmount) = if ((i.caller != stakingContract)) | |
1743 | 1721 | then throw("Permission denied") | |
1744 | 1722 | else $Tuple2([IntegerEntry(deliveryLockedKey, newAmount)], newAmount) | |
1745 | 1723 | ||
1746 | 1724 | ||
1747 | 1725 | ||
1748 | 1726 | @Callable(i) | |
1749 | 1727 | func sendDeliveryReward (addr) = if ((i.caller != stakingContract)) | |
1750 | 1728 | then throw("Permission denied") | |
1751 | 1729 | else { | |
1752 | 1730 | let fundTotal = valueOrElse(getInteger(deliveryFundKey), 0) | |
1753 | 1731 | let lockedTotal = valueOrElse(getInteger(deliveryLockedKey), 0) | |
1754 | 1732 | let acresAmount = (MIN_USDT_FEE_DELIVERY * USDT2ACRES_MULTIPLIER) | |
1755 | 1733 | let acresResult = invoke(acresContract, "sendAcres", [addr, acresAmount], nil) | |
1756 | 1734 | $Tuple2([IntegerEntry(deliveryFundKey, (fundTotal - MIN_USDT_FEE_DELIVERY)), IntegerEntry(deliveryLockedKey, (lockedTotal - MIN_USDT_FEE_DELIVERY))], acresResult) | |
1757 | 1735 | } | |
1758 | 1736 | ||
1759 | 1737 |
github/deemru/w8io/169f3d6 221.39 ms ◑