tx · Yn7jTiNBWNi5G94z6SCngKNKXUP3d8VDT8A3VAf1UXs

3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm:  -0.06700000 Waves

2023.06.20 21:04 [2631298] smart account 3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm > SELF 0.00000000 Waves

{ "type": 13, "id": "Yn7jTiNBWNi5G94z6SCngKNKXUP3d8VDT8A3VAf1UXs", "fee": 6700000, "feeAssetId": null, "timestamp": 1687284353244, "version": 2, "chainId": 84, "sender": "3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm", "senderPublicKey": "EVooykMNV691Venwp1dHUTBd7KWequzUcda57Wd3LQEX", "proofs": [ "2biwtMw6P5csAgtS8i4bvRDkRDgUPCS94CFL4TJC9GQA1ooFyfNLXb1XnvBAepXaCxS4GXfVYLFD81LBKN9AeiH8" ], "script": "base64:BgKYAQgCEgMKAQgSAwoBBBIAEgMKAQgSABIDCgEIEgQKAgEIEgQKAgEIEgQKAgICEgUKAwEBARIAEgQKAggIEgASBAoCAgISAwoBCBIDCgEIEgQKAggIEgMKARgSAwoBGBIECgIICBIECgIICBIDCgEIEgMKAQgSBQoDCAgIEgQKAggIEgMKAQESBQoDAQEIEgMKAQgSAwoBCBIAwAEABWNoYWluCQDJAQIJAMoBAggFBHRoaXMFYnl0ZXMAAQABAAt1c2R0QXNzZXRJZAQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAEghNp6sggDP07Ru8qO7ouTvMmC3Qtd+geWqNQj+agP/7kDCQAAAgEBVAUHJG1hdGNoMAEgVbHYn3KHgu/l41uNrAWrZd6aQ6EvFrsF8xq3h6XxxRgJAAIBAg1Vbmtub3duIGNoYWluABVkZWZhdWx0UmVzdEFkZHJlc3NTdHIEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDACIzNQUUN1dkZidmg0TGtQVW5yblUxejNqbmJBMXA5bTNXTmh2AwkAAAIBAVQFByRtYXRjaDACIzNNdW1rR0d6dENLQVhwV0RxeGtkZG9mcVhTVWJxUWt2U0p5CQACAQINVW5rbm93biBjaGFpbgARSW5mcmFVcGdyYWRlQ29zdFMEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDAAgMivoCUDCQAAAgEBVAUHJG1hdGNoMACAwtcvCQACAQINVW5rbm93biBjaGFpbgADU0VQAgJfXwAFTVVMVDYAwIQ9AAVNVUxUNwCAreIEAAVNVUxUOACAwtcvAAZNVUxUMTAAgMivoCUACkxBTkRQUkVGSVgCBExBTkQACkRVQ0tQUkVGSVgCBERVQ0sACkFSVFBSRVNBTEUCB1BSRVNBTEUABk5VTVJFUwAGAAVTU0laRQAZAAVNU0laRQBkAAVMU0laRQDhAQAGWExTSVpFAJADAAdYWExTSVpFAPEEAA9EQUlMWVJFU0JZUElFQ0UAgPjSAQAJREFZTUlMTElTAIC4mSkADFdITVVMVElQTElFUgCAyK+gJQAPREVGQVVMVExPQ0FUSU9OAg9BZnJpY2FfRl9BZnJpY2EAEFJFU09VUkNFUFJJQ0VNSU4A1bUCAA1FU01BWFBBQ0tBR0VTAAMACUVTQlVZQ09FRgAEAApFU1NFTExDT0VGAAoABU1BWEhQAGQACHJlc1R5cGVzCQDMCAICA09pbAkAzAgCAgNPcmUJAMwIAgIEV29vZAkAzAgCAgRTYW5kCQDMCAICBENsYXkJAMwIAgIHT3JnYW5pYwUDbmlsAAhtYXRUeXBlcwkAzAgCAgRGdWVsCQDMCAICBU1ldGFsCQDMCAICBVBsYW5rCQDMCAICBUdsYXNzCQDMCAICB1BsYXN0aWMJAMwIAgIHUHJvdGVpbgUDbmlsAAlwcm9kVHlwZXMJAMwIAgIQRmlyc3QgQWlkIEtpdCBMMQkAzAgCAhBGaXJzdCBBaWQgS2l0IEwyCQDMCAICEEZpcnN0IEFpZCBLaXQgTDMJAMwIAgILQmFja3BhY2sgTDEJAMwIAgILQmFja3BhY2sgTDIJAMwIAgILQmFja3BhY2sgTDMJAMwIAgIORm9vZCBSYXRpb24gTDEJAMwIAgIORm9vZCBSYXRpb24gTDIJAMwIAgIORm9vZCBSYXRpb24gTDMJAMwIAgILSmV0IFBhY2sgTDEJAMwIAgILSmV0IFBhY2sgTDIJAMwIAgILSmV0IFBhY2sgTDMJAMwIAgIJU2hpZWxkIEwxCQDMCAICCVNoaWVsZCBMMgkAzAgCAglTaGllbGQgTDMFA25pbAAKY29udGluZW50cwkAzAgCAghBbWVyaWNhcwkAzAgCAgZFdXJvcGUJAMwIAgIEQXNpYQkAzAgCAgZBZnJpY2EJAMwIAgIHT2NlYW5pYQUDbmlsABBwcm9kdWN0aW9uTWF0cml4CQDMCAICEjFfMV8xXzJfMl81XzFfMTBfMAkAzAgCAhMyXzJfMl80XzRfMTBfMV8xMF8wCQDMCAICEzNfM18zXzZfNl8xNV8xXzEwXzAJAMwIAgITMl81XzVfMl83XzVfMl8xMDBfMQkAzAgCAhc0XzEwXzEwXzRfMTRfMTBfMl8xMDBfMQkAzAgCAhc2XzE1XzE1XzZfMjFfMTVfMl8xMDBfMQkAzAgCAhIxXzFfMV8xXzFfOF8xXzEwXzIJAMwIAgITMl8yXzJfMl8yXzE2XzFfMTBfMgkAzAgCAhMzXzNfM18zXzNfMjRfMV8xMF8yCQDMCAICEzlfOV8xXzVfNV8xXzVfMTAwXzMJAMwIAgIXMThfMThfMl8xMF8xMF8yXzVfMTAwXzMJAMwIAgIXMjdfMjdfM18xNV8xNV8zXzVfMTAwXzMJAMwIAgISMl8yXzFfMl8yXzJfMV8xMF80CQDMCAICEjRfNF8yXzRfNF80XzFfMTBfNAkAzAgCAhI2XzZfM182XzZfNl8xXzEwXzQFA25pbAAPY29udElkeEFtZXJpY2FzAAAADWNvbnRJZHhFdXJvcGUAAQALY29udElkeEFzaWEAAgANY29udElkeEFmcmljYQADAA5jb250SWR4T2NlYW5pYQAEAA1yZWNpcGVJZHhGdWVsAAAADnJlY2lwZUlkeE1ldGFsAAEADnJlY2lwZUlkeFBsYW5rAAIADnJlY2lwZUlkeEdsYXNzAAMAEHJlY2lwZUlkeFBsYXN0aWMABAAQcmVjaXBlSWR4UHJvdGVpbgAFAA9yZWNpcGVJZHhXZWlnaHQABgARcmVjaXBlSWR4UGFja3NpemUABwAScmVjaXBlSWR4Q29udGluZW50AAgACnJlY0xhbmROdW0AAAALcmVjTGFuZFNpemUAAQALcmVjVGVycmFpbnMAAgAMcmVjQ29udGluZW50AAMAC3doSWR4TGV2ZWxzAAAACHdoSWR4UmVzAAEACHdoSWR4TWF0AAIACXdoSWR4UHJvZAADAAl3aElkeExPRlQABAAJdm9sTG9ja2VkAAAAC3ZvbE9jY3VwaWVkAAEAB3ZvbEZyZWUAAgAIdm9sVG90YWwAAwAKYnBJZHhMZXZlbAAAAAhicElkeFJlcwABAAhicElkeE1hdAACAAlicElkeFByb2QAAwEKZ2V0UGtnU2l6ZQEHcHJvZElkeAkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgkAkQMCBRBwcm9kdWN0aW9uTWF0cml4BQdwcm9kSWR4AgFfBRFyZWNpcGVJZHhQYWNrc2l6ZQEPZ2V0U3RyaW5nT3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFB2FkZHJlc3MFA2tleQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQdhZGRyZXNzCQDMCAICAS4JAMwIAgUDa2V5CQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABDGdldEludE9yRWxzZQIDa2V5CmRlZmF1bHRWYWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUDa2V5BQpkZWZhdWx0VmFsABFJZHhDZmdTdGFraW5nRGFwcAABABFJZHhDZmdFY29ub215RGFwcAACABRJZHhDZmdHb3Zlcm5hbmNlRGFwcAADAA1JZHhDZmdXbGdEYXBwAAQBCmtleVJlc3RDZmcAAg4lc19fcmVzdENvbmZpZwEOa2V5UmVzdEFkZHJlc3MAAgwlc19fcmVzdEFkZHIBEXJlYWRSZXN0Q2ZnT3JGYWlsAQRyZXN0CQC8CQIJAQ9nZXRTdHJpbmdPckZhaWwCBQRyZXN0CQEKa2V5UmVzdENmZwAFA1NFUAEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgdyZXN0Q2ZnA2lkeAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUHcmVzdENmZwUDaWR4CQCsAgICKlJlc3QgY2ZnIGRvZXNuJ3QgY29udGFpbiBhZGRyZXNzIGF0IGluZGV4IAkApAMBBQNpZHgADHJlc3RDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEOa2V5UmVzdEFkZHJlc3MABRVkZWZhdWx0UmVzdEFkZHJlc3NTdHIAB3Jlc3RDZmcJARFyZWFkUmVzdENmZ09yRmFpbAEFDHJlc3RDb250cmFjdAAPc3Rha2luZ0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwURSWR4Q2ZnU3Rha2luZ0RhcHAAD2Vjb25vbXlDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFEUlkeENmZ0Vjb25vbXlEYXBwAAtnb3ZDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFFElkeENmZ0dvdmVybmFuY2VEYXBwAAt3bGdDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFDUlkeENmZ1dsZ0RhcHABEWtleUxhc3RUeElkQnlVc2VyAQRhZGRyCQCsAgICD2xhc3RUeElkQnlVc2VyXwUEYWRkcgEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQdhc3NldElkCQCsAgICCW5mdE93bmVyXwUHYXNzZXRJZAEaa2V5TGFuZEFzc2V0SWRUb0N1c3RvbU5hbWUBB2Fzc2V0SWQJAKwCAgIYbGFuZEN1c3RvbU5hbWVCeUFzc2V0SWRfBQdhc3NldElkARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQdhc3NldElkCQCsAgICC3N0YWtlZFRpbWVfBQdhc3NldElkARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQdhc3NldElkCQCsAgICC2luZnJhTGV2ZWxfBQdhc3NldElkASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIEdHlwZQdhc3NldElkCQC5CQIJAMwIAgINbGFuZEFydFN0YXR1cwkAzAgCBQR0eXBlCQDMCAIFB2Fzc2V0SWQFA25pbAIBXwEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMHbmZ0VHlwZQdhc3NldElkCW93bmVyQWRkcgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICIHN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXJfBQduZnRUeXBlAgFfBQdhc3NldElkAgFfBQlvd25lckFkZHIBEmtleVdhcmVob3VzZUJ5TGFuZAELbGFuZEFzc2V0SWQJAKwCAgIKd2FyZUhvdXNlXwULbGFuZEFzc2V0SWQBFWtleVN0YWtlZExhbmRzQnlPd25lcgEJb3duZXJBZGRyCQCsAgICE3N0YWtlZExhbmRzQnlPd25lcl8FCW93bmVyQWRkcgEWa2V5U3Rha2VkUGllY2VzQnlPd25lcgEJb3duZXJBZGRyCQCsAgICFHN0YWtlZFBpZWNlc0J5T3duZXJfBQlvd25lckFkZHIBGmtleUR1Y2tBc3NldElkVG9DdXN0b21OYW1lAQdhc3NldElkCQCsAgICGGR1Y2tDdXN0b21OYW1lQnlBc3NldElkXwUHYXNzZXRJZAEWa2V5QWRkcmVzc1RvQ3VzdG9tTmFtZQEEYWRkcgkArAICAhhhY2NvdW50Q3VzdG9tTmFtZUJ5QWRkcl8FBGFkZHIBD2tleUFkZHJlc3NSZWZCeQEEYWRkcgkArAICAglhY2NSZWZCeV8FBGFkZHIBE2tleUFkZHJlc3NSZWZlcnJhbHMBBGFkZHIJAKwCAgINYWNjUmVmZXJyYWxzXwUEYWRkcgEQa2V5RHVja0lkVG9Pd25lcgEHYXNzZXRJZAkArAICAgpkdWNrT3duZXJfBQdhc3NldElkARRrZXlTdGFrZWREdWNrQnlPd25lcgEJb3duZXJBZGRyCQCsAgICEnN0YWtlZER1Y2tCeU93bmVyXwUJb3duZXJBZGRyARFrZXlCYWNrcGFja0J5RHVjawELZHVja0Fzc2V0SWQJAKwCAgIJYmFja1BhY2tfBQtkdWNrQXNzZXRJZAEPa2V5RHVja0xvY2F0aW9uAQtkdWNrQXNzZXRJZAkArAICAg1kdWNrTG9jYXRpb25fBQtkdWNrQXNzZXRJZAENa2V5RHVja0hlYWx0aAELZHVja0Fzc2V0SWQJAKwCAgILZHVja0hlYWx0aF8FC2R1Y2tBc3NldElkARFrZXlSZXNQcm9wb3J0aW9ucwACE3Jlc1R5cGVzUHJvcG9ydGlvbnMBCmtleUJsb2NrZWQAAhBjb250cmFjdHNCbG9ja2VkARVrZXlVc2VyR3dsUmVsZWFzZVRpbWUBCHVzZXJBZGRyCQCsAgICGiVzJXNfX3VzZXJHd2xSZWxlYXNlVGltZV9fBQh1c2VyQWRkcgEOa2V5T3JkZXJCeUxhbmQBC2xhbmRBc3NldElkCQCsAgICCmxhbmRPcmRlcl8FC2xhbmRBc3NldElkAQ5rZXlFc1dhcmVob3VzZQACGmVtZXJnZW5jeVdhcmVob3VzZVByb2R1Y3RzAA9sb2NJZHhDb250aW5lbnQAAAAKbG9jSWR4VHlwZQABAAhsb2NJZHhJZAACAQhhc1N0cmluZwEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAFAXMJAAIBAhhmYWlsIHRvIGNhc3QgaW50byBTdHJpbmcBBWFzSW50AQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACA0ludAQBbgUHJG1hdGNoMAUBbgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEJYXNBbnlMaXN0AQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACCUxpc3RbQW55XQQBbAUHJG1hdGNoMAUBbAkAAgECG2ZhaWwgdG8gY2FzdCBpbnRvIExpc3RbQW55XQEJYXNCb29sZWFuAQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACB0Jvb2xlYW4EAXMFByRtYXRjaDAFAXMJAAIBAhlmYWlsIHRvIGNhc3QgaW50byBCb29sZWFuAQ9udW1QaWVjZXNCeVNpemUBCGxhbmRTaXplBAckbWF0Y2gwBQhsYW5kU2l6ZQMJAAACAgFTBQckbWF0Y2gwBQVTU0laRQMJAAACAgFNBQckbWF0Y2gwBQVNU0laRQMJAAACAgFMBQckbWF0Y2gwBQVMU0laRQMJAAACAgJYTAUHJG1hdGNoMAUGWExTSVpFAwkAAAICA1hYTAUHJG1hdGNoMAUHWFhMU0laRQkAAgECEVVua25vd24gbGFuZCBzaXplAAtJZHhFZmZUb3RhbAAAAApJZHhFZmZVc2VyAAEBDmdldFZvdGluZ1Bvd2VyARJ1c2VyQWRkclN0ck9yRW1wdHkEBXByb3BzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQERa2V5UmVzUHJvcG9ydGlvbnMAAgswXzBfMF8wXzBfMAIBXwoBBWFkZGVyAgNhY2MEaXRlbQkAZAIFA2FjYwkBDXBhcnNlSW50VmFsdWUBBQRpdGVtBAp0b3RhbFBvd2VyCgACJGwFBXByb3BzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQVhZGRlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgQKdXNlcnNQb3dlcgMJAAACBRJ1c2VyQWRkclN0ck9yRW1wdHkCAAAABAhsYW5kc1N0cgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBBRJ1c2VyQWRkclN0ck9yRW1wdHkEBWxh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TkRTAPQDARJrZXlOZXh0RnJlZUxhbmROdW0AAgtuZXh0TGFuZE51bQEQa2V5TGFuZFRvQXNzZXRJZAEHbGFuZE51bQkArAICAgxsYW5kVG9Bc3NldF8FB2xhbmROdW0BGmtleUxhbmRDdXN0b21OYW1lVG9Bc3NldElkAQRuYW1lCQCsAgICEWxhbmRCeUN1c3RvbU5hbWVfBQRuYW1lAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICB2Fzc2V0SWQJb3duZXJBZGRyCQCsAgIJAKwCAgkArAICAhxpbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXJfBQdhc3NldElkAgFfBQlvd25lckFkZHIBJWtleUxhbmRBcnRTdGF0dXNCeVR5cGVBc3NldElkQW5kT3duZXIDBHR5cGUHYXNzZXRJZAlvd25lckFkZHIJALkJAgkAzAgCAiJsYW5kQXJ0U3RhdHVzQnlUeXBlQXNzZXRJZEFuZE93bmVyCQDMCAIFBHR5cGUJAMwIAgUHYXNzZXRJZAkAzAgCBQlvd25lckFkZHIFA25pbAIBXwERa2V5TGFuZE51bVRvT3duZXIBB2xhbmROdW0JAKwCAgIKbGFuZE93bmVyXwUHbGFuZE51bQEaa2V5RHVja0N1c3RvbU5hbWVUb0Fzc2V0SWQBBG5hbWUJAKwCAgIRZHVja0J5Q3VzdG9tTmFtZV8FBG5hbWUBFmtleUN1c3RvbU5hbWVUb0FkZHJlc3MBBG5hbWUJAKwCAgIUYWNjb3VudEJ5Q3VzdG9tTmFtZV8FBG5hbWUBCWtleU9sZGllcwACCm9sZGllc0xpc3QAC2NsYWltTW9kZVdoAAAADWNsYWltTW9kZUR1Y2sAAQATY2xhaW1Nb2RlV2hUaGVuRHVjawACAAhmbEhlYWx0aAAAAAlmbE1pc3Npb24AAQALZmxPYnN0YWNsZXMAAgAHZmxXaW5kcwADAAZmbFBhdGgABAALZmxUaW1lc3RhbXAABQAHZmxCb251cwAGAAtmbFByb2RzVXNlZAAHAQduZnROYW1lAgdsYW5kTnVtCGxhbmRTaXplCQCsAgIJAKwCAgUKTEFORFBSRUZJWAUHbGFuZE51bQUIbGFuZFNpemUBE2Rpc3RyaWJ1dGVCeVdlaWdodHMCBXRvdGFsB3dlaWdodHMEA3N1bQkAZAIJAGQCCQBkAgkAZAIJAGQCCQCRAwIFB3dlaWdodHMAAAkAkQMCBQd3ZWlnaHRzAAEJAJEDAgUHd2VpZ2h0cwACCQCRAwIFB3dlaWdodHMAAwkAkQMCBQd3ZWlnaHRzAAQJAJEDAgUHd2VpZ2h0cwAFAwkAZwIAAAUDc3VtCQACAQIQWmVybyB3ZWlnaHRzIHN1bQQFbm9ybTYJAGsDBQV0b3RhbAUFTVVMVDYFA3N1bQoBCm5vcm1hbGl6ZXICA2FjYwRlbGVtCQDNCAIFA2FjYwkAawMFBGVsZW0FBW5vcm02BQVNVUxUNgoAAiRsBQd3ZWlnaHRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpub3JtYWxpemVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGARJnZXROZWVkZWRNYXRlcmlhbHMBBXRvdGFsBAVwcm9wcwkAtQkCCQEFdmFsdWUBCQCiCAEJARFrZXlSZXNQcm9wb3J0aW9ucwACAV8DCQECIT0CCQCQAwEFBXByb3BzBQZOVU1SRVMJAAIBAhZXcm9uZyBwcm9wb3J0aW9ucyBkYXRhBAFyCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAACQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwABCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwACCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwADCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAECQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAFBQNuaWwJARNkaXN0cmlidXRlQnlXZWlnaHRzAgUFdG90YWwFAXIBEXN1YnRyYWN0TWF0ZXJpYWxzAwxz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cAUIYnBJZHhSZXMCCzBfMF8wXzBfMF8wCQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUBcAUIYnBJZHhNYXQCAV8FBk5VTVJFUwkAkQMCBQFwBQhicElkeE1hdAILMF8wXzBfMF8wXzAJAMwIAgkAkQMCBQFwBQlicElkeFByb2QFA25pbAEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBCXZvbFByZWZpeAQFcGFydHMJALUJAgUJdm9sUHJlZml4AgFfCQBoAgkAaAIFDFdITVVMVElQTElFUgkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwYXJ0cwABAAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwYXJ0cwAAARdnZXRXYXJlaG91c2VPY2N1cGllZFZvbAEJY3VycmVudFdoBAVnb29kcwkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAoBCXN1bVJlc01hdAIDYWNjBGl0ZW0JAGQCBQNhY2MJAQ1wYXJzZUludFZhbHVlAQUEaXRlbQoBB3N1bVByb2QCA2FjYwRpdGVtBANpZHgIBQNhY2MCXzEEB3BrZ1NpemUJAQpnZXRQa2dTaXplAQUDaWR4BARwa2dzCQBpAgkAZQIJAGQCCQENcGFyc2VJbnRWYWx1ZQEFBGl0ZW0FB3BrZ1NpemUAAQUHcGtnU2l6ZQkAlAoCCQBkAgUDaWR4AAEJAGQCCAUDYWNjAl8yCQBoAgUEcGtncwUFTVVMVDgECHdoUmVzVm9sCgACJGwJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQlzdW1SZXNNYXQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYECHdoTWF0Vm9sCgACJGwJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4TWF0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aAUId2hJZHhSZXMCCzBfMF8wXzBfMF8wCQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUCd2gFCHdoSWR4TWF0AgFfBQZOVU1SRVMJAJEDAgUCd2gFCHdoSWR4TWF0AgswXzBfMF8wXzBfMAkAzAgCCQCRAwIFAndoBQl3aElkeFByb2QJAMwIAgUGd2hMb2Z0BQNuaWwBFWdldFdhcmVob3VzZVNwYWNlTGVmdAEJY3VycmVudFdoBAtvY2N1cGllZFZvbAkBF2dldFdhcmVob3VzZU9jY3VwaWVkVm9sAQUJY3VycmVudFdoBA9jdXJyV2hMb2NrZWRWb2wJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQC1CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeExPRlQCAV8FCXZvbExvY2tlZAkAZQIJAGUCCQEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBCQCRAwIFCWN1cnJlbnRXaAULd2hJZHhMZXZlbHMFC29jY3VwaWVkVm9sBQ9jdXJyV2hMb2NrZWRWb2wBCHRvVm9sdW1lAgZhbW91bnQHcGtnU2l6ZQQEcGtncwMJAGcCBQZhbW91bnQAAAkAaQIJAGUCCQBkAgUGYW1vdW50BQdwa2dTaXplAAEFB3BrZ1NpemUJAQEtAQkAaQIJAGUCCQBkAgkBAS0BBQZhbW91bnQFB3BrZ1NpemUAAQUHcGtnU2l6ZQkAaAIFBHBrZ3MFBU1VTFQ4AQltb3ZlU3R1ZmYDCmNhcmdvUGFydHMJY3VycmVudFdoC2N1cnJlbnRQYWNrAwkBAiE9AgkAkAMBBQpjYXJnb1BhcnRzAAMJAAIBAjRjYXJnb0xpc3RTdHIgc2hvdWxkIGNvbnRhaW4gZXhhY3RseSAyICc6JyBzZXBhcmF0b3JzBAhyZXNQYXJ0cwkAtQkCCQCRAwIFCmNhcmdvUGFydHMAAAIBXwQIbWF0UGFydHMJALUJAgkAkQMCBQpjYXJnb1BhcnRzAAECAV8ECXByb2RQYXJ0cwMJAAACCQCRAwIFCmNhcmdvUGFydHMAAgIABQNuaWwJALUJAgkAkQMCBQpjYXJnb1BhcnRzAAICAV8DCQECIT0CCQCQAwEFCHJlc1BhcnRzBQZOVU1SRVMJAAIBAiBBbGwgNiByZXNvdXJjZXMgc2hvdWxkIGJlIHBhc3NlZAMJAQIhPQIJAJADAQUIbWF0UGFydHMFBk5VTVJFUwkAAgECIEFsbCA2IG1hdGVyaWFscyBzaG91bGQgYmUgcGFzc2VkBAt3aFNwYWNlTGVmdAkBFWdldFdhcmVob3VzZVNwYWNlTGVmdAEFCWN1cnJlbnRXaAQJY3VycldoUmVzCQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeFJlcwIBXwQJY3VycldoTWF0CQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAIBXwQKY3VycldoUHJvZAMJAAACCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kAgAFA25pbAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kAgFfBA5jdXJyZW50UGFja1JlcwkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwQOY3VycmVudFBhY2tNYXQJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8ED2N1cnJlbnRQYWNrUHJvZAMJAAACCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAAUDbmlsCQC1CQIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIBXwoBA212UgIDYWNjBGl0ZW0EAWkIBQNhY2MCXzEEAmFtCQENcGFyc2VJbnRWYWx1ZQEFBGl0ZW0EA3docgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWN1cnJXaFJlcwUBaQQDYnByCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOY3VycmVudFBhY2tSZXMFAWkDCQAAAgUCYW0AAAkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAJEDAgUJY3VycldoUmVzBQFpCQDNCAIIBQNhY2MCXzMJAJEDAgUOY3VycmVudFBhY2tSZXMFAWkIBQNhY2MCXzQDCQBmAgUCYW0AAAMJAGYCBQJhbQUDYnByCQACAQkArAICCQCsAgIJAKwCAgkArAICAhBBdHRlbXB0IHRvIHRha2UgBQRpdGVtAhkgZnJvbSBiYWNrcGFjaywgYnV0IG9ubHkgCQCkAwEFA2JwcgIKIGF2YWlsYWJsZQkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAKQD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RnJlZUxhbmROdW0ACQBkAgUPUFJFU0FMRU5VTUxBTkRTAAEEB2xhbmROdW0JAKQDAQUHZnJlZU51bQQMY29udGluZW50SWR4CQCgAwEJALsCAgUGYmlnTnVtBQVGSVZFWAQIdGVycmFpbnMJAQtnZW5UZXJyYWlucwIFBmJpZ051bQUMY29udGluZW50SWR4BAljb250aW5lbnQJAJEDAgUKY29udGluZW50cwUMY29udGluZW50SWR4BAVpc3N1ZQkAwggFCQEHbmZ0TmFtZQIFB2xhbmROdW0CAVMJALkJAgkAzAgCBQdsYW5kTnVtCQDMCAICAVMJAMwIAgUIdGVycmFpbnMJAMwIAgUJY29udGluZW50BQNuaWwCAV8AAQAABwQHYXNzZXRJZAkAuAgBBQVpc3N1ZQQCaWQJANgEAQUHYXNzZXRJZAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESa2V5TmV4dEZyZWVMYW5kTnVtAAkAZAIFB2ZyZWVOdW0AAQkAzAgCBQVpc3N1ZQkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5TGFuZFRvQXNzZXRJZAEFB2xhbmROdW0FAmlkCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQJpZAUIdXNlckFkZHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUxhbmROdW1Ub093bmVyAQUHbGFuZE51bQUIdXNlckFkZHIJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQUCaWQAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIFAmlkBQh1c2VyQWRkcgAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBmNhbGxlcgABBQdhc3NldElkBQNuaWwJAJQKAgUCaWQFCWNvbnRpbmVudAEMZmxpZ2h0Q29tbW9uAwh1c2VyQWRkcgdtZXNzYWdlA3NpZwMJAQEhAQkAxBMDBQdtZXNzYWdlBQNzaWcFA3B1YgkAAgECGHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaAQFcGFydHMJALUJAgkAsAkBBQdtZXNzYWdlAgE7BAlmbGlnaHRMb2cJALUJAgkAkQMCBQVwYXJ0cwAAAgF8BAJocAkAtQkCCQCRAwIFCWZsaWdodExvZwUIZmxIZWFsdGgCAV8EBWN1ckhQCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCaHAAAAQFbmV3SFAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJocAABBAtuZXdMb2NUeFZlcgkAtQkCCQCRAwIFBXBhcnRzAAECAToEC25ld0xvY2F0aW9uCQCRAwIFC25ld0xvY1R4VmVyAAAEBHRpbWUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlmbGlnaHRMb2cFC2ZsVGltZXN0YW1wAwMJAGYCBQR0aW1lCQBkAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFEUZJVkVNSU5VVEVTTUlMTElTBgkAZgIJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAURRklWRU1JTlVURVNNSUxMSVMFBHRpbWUJAAIBCQCsAgIJAKwCAgkArAICAhxzaWduYXR1cmUgb3V0ZGF0ZWQ6IGxvZ1RpbWU9CQCkAwEFBHRpbWUCCSwgYmNUaW1lPQkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQJdHhGcm9tTXNnCQCRAwIFC25ld0xvY1R4VmVyAAEEBmxhc3RUeAkBC3ZhbHVlT3JFbHNlAgkAoggBCQERa2V5TGFzdFR4SWRCeVVzZXIBBQh1c2VyQWRkcgIAAwkBAiE9AgUGbGFzdFR4BQl0eEZyb21Nc2cJAAIBCQCsAgIJAKwCAgkArAICAh5UeCBpZHMgZG9uJ3QgbWF0Y2ghIEluIHN0YXRlOiAFBmxhc3RUeAIKLCBpbiBtc2c6IAUJdHhGcm9tTXNnBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFCHVzZXJBZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEDG9sZEZyb21TdGF0ZQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgAZAMJAQIhPQIFDG9sZEZyb21TdGF0ZQUFY3VySFAJAAIBCQCsAgIJAKwCAgkArAICAgpvbGRIZWFsdGg9CQCkAwEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoAGQCLyBmcm9tIHN0YXRlIGRvZXMgbm90IG1hdGNoIG9uZSBmcm9tIGZsaWdodCBsb2c9CQCkAwEFBWN1ckhQAwkAZwIAAAUFY3VySFAJAAIBAh5Zb3UgY2FuJ3QgZmx5IHdpdGggemVybyBoZWFsdGgEBWJvbnVzAwkAZgIJAJADAQUJZmxpZ2h0TG9nBQdmbEJvbnVzCQCRAwIFCWZsaWdodExvZwUHZmxCb251cwIABAhwcm9kVXNlZAMJAGYCCQCQAwEFCWZsaWdodExvZwULZmxQcm9kc1VzZWQJAJEDAgUJZmxpZ2h0TG9nBQtmbFByb2RzVXNlZAIABApzZW50QW1vdW50AwMJAGYCBQVuZXdIUAAACQAAAgUFYm9udXMCASQHCQEFYXNJbnQBCQD8BwQFDHJlc3RDb250cmFjdAINc2VuZFVzZHRQcml6ZQkAzAgCBQh1c2VyQWRkcgUDbmlsBQNuaWwAAAkAlwoFBQVuZXdIUAULZHVja0Fzc2V0SWQFCnNlbnRBbW91bnQFC25ld0xvY2F0aW9uBQhwcm9kVXNlZAEQZXhwZWRpdGlvbkNvbW1vbgQGY2FsbGVyBHR4SWQHbWVzc2FnZQNzaWcECHVzZXJBZGRyCQClCAEFBmNhbGxlcgQBZgkBDGZsaWdodENvbW1vbgMFCHVzZXJBZGRyBQdtZXNzYWdlBQNzaWcECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBCAUBZgJfMgQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEIBQFmAl8yBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBW1MaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBAZuZXdNYXQJALkJAgkBEXN1YnRyYWN0TWF0ZXJpYWxzAwYFBW1MaXN0BQxFWFBNQVRFUklBTFMCAV8EB25ld1Byb2QJARBzdWJ0cmFjdFByb2R1Y3RzAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kCAUBZgJfNQMJAGcCAAAIBQFmAl8xCQCVCgMJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAAACQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAkAzAgCBQduZXdQcm9kBQNuaWwCAToFA25pbAIAAAAEAWUJARJleHBlZGl0aW9uSW50ZXJuYWwCBQZjYWxsZXIFBHR4SWQEAmlkCAgFAWUCXzICXzEJAJUKAwkAzQgCCQDNCAIJAM0IAggFAWUCXzEJAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BCAUBZgJfMgkAuQkCCQDMCAIICAUBZQJfMgJfMgkAzAgCAgFMCQDMCAIFAmlkBQNuaWwCAV8JAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgIBQFmAl8xCQELU3RyaW5nRW50cnkCBQVicEtleQkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMJAMwIAgUGbmV3TWF0CQDMCAIFB25ld1Byb2QFA25pbAIBOgUCaWQIBQFmAl8zAQxhcHBseUJvbnVzZXMCC2xhbmRBc3NldElkBnBpZWNlcwQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAECWFydFBpZWNlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAAABARhZGQ2CQBpAgUKaW5mcmFMZXZlbAAGBARhZGQ3CQBpAgUKaW5mcmFMZXZlbAAHCQBkAgkAZAIFD0RBSUxZUkVTQllQSUVDRQkAawMFD0RBSUxZUkVTQllQSUVDRQkAZAIJAGQCBQppbmZyYUxldmVsBQRhZGQ2CQBoAgACBQRhZGQ3AAUJAGsDBQ9EQUlMWVJFU0JZUElFQ0UFCWFydFBpZWNlcwkAaAIFBnBpZWNlcwAFARRjaGVja0NsYWltQ29uZGl0aW9ucwMEYWRkcgljbGFpbU1vZGUNbGFuZEFzc2V0SWRJbgQNJHQwMjQ0MjIyNDk2MQMJAAACBQljbGFpbU1vZGUFC2NsYWltTW9kZVdoCQCUCgIFDWxhbmRBc3NldElkSW4JAQt2YWx1ZU9yRWxzZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIABAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQEC2N1ckxvY2F0aW9uCQELdmFsdWVPckVsc2UCCQCiCAEJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OBANsb2MJALUJAgkBBXZhbHVlAQULY3VyTG9jYXRpb24CAV8DCQECIT0CCQCRAwIFA2xvYwUKbG9jSWR4VHlwZQIBTAkAAgEJAKwCAgkArAICAhZEdWNrIGxvY2F0aW9uIHR5cGUgaXMgCQCRAwIFA2xvYwUKbG9jSWR4VHlwZQIRLCBidXQgc2hvdWxkIGJlIEwJAJQKAgkAkQMCBQNsb2MFCGxvY0lkeElkBQtkdWNrQXNzZXRJZAQLbGFuZEFzc2V0SWQIBQ0kdDAyNDQyMjI0OTYxAl8xBAZkdWNrSWQIBQ0kdDAyNDQyMjI0OTYxAl8yBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBAlzYXZlZFRpbWUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQd0aW1lS2V5CQCsAgIJAKwCAgIFTGFuZCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkxBTkRQUkVGSVgCDSBpcyBub3QgeW91cnMEAWQJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfCQCWCgQFBmR1Y2tJZAULbGFuZEFzc2V0SWQFAWQFCXNhdmVkVGltZQEQY2xhaW1SZXNJbnRlcm5hbAQEYWRkcgZhbW91bnQJY2xhaW1Nb2RlDWxhbmRBc3NldElkSW4DCQBmAgAABQZhbW91bnQJAAIBAg9OZWdhdGl2ZSBhbW91bnQEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFCWNsYWltTW9kZQUNbGFuZEFzc2V0SWRJbgQIbGFuZFNpemUJAJEDAggFAWMCXzMFC3JlY0xhbmRTaXplBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEJAJEDAggFAWMCXzMFC3JlY1RlcnJhaW5zBAlkZWx0YVRpbWUJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAgFAWMCXzQDCQBmAgAABQlkZWx0YVRpbWUJAAIBCQCsAgIJAKwCAgkArAICAiZTYXZlZCB0aW1lc3RhbXAgaXMgaW4gZnV0dXJlLCBzYXZlZCA9IAkApAMBCAUBYwJfNAIMLCBjdXJyZW50ID0gCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBBQhsYW5kU2l6ZQQWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkBDGFwcGx5Qm9udXNlcwIIBQFjAl8yBQZwaWVjZXMECGF2YWlsUmVzCQBrAwUJZGVsdGFUaW1lCQBoAgUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQUGcGllY2VzBQlEQVlNSUxMSVMDCQBmAgUGYW1vdW50BQhhdmFpbFJlcwkAAgEJAKwCAgkArAICCQCsAgICIk5vdCBlbm91Z2ggcmVzb3VyY2VzLCBhdmFpbGFibGUgPSAJAKQDAQUIYXZhaWxSZXMCDiwgcmVxdWVzdGVkID0gCQCkAwEFBmFtb3VudAQMbmV3RGVsdGFUaW1lCQBrAwkAZQIFCGF2YWlsUmVzBQZhbW91bnQFCURBWU1JTExJUwkAaAIFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UFBnBpZWNlcwQMbmV3VGltZXN0YW1wCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFDG5ld0RlbHRhVGltZQQJbGFuZEluZGV4CQBpAgUGcGllY2VzBQVTU0laRQQKcmVzVG9DbGFpbQkBCXZpcnRDbGFpbQQFDXRlcnJhaW5Db3VudHMJAGUCBQlkZWx0YVRpbWUFDG5ld0RlbHRhVGltZQUJbGFuZEluZGV4BRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBAV3aEtleQkBEmtleVdhcmVob3VzZUJ5TGFuZAEIBQFjAl8yBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQgFAWMCXzIAAAQJY3VycmVudFdoCQEMZ2V0V2FyZWhvdXNlAwUFd2hLZXkFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAQEbG9mdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhMT0ZUAgFfBAt3aFNwYWNlTGVmdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUDAwkAAAIFCWNsYWltTW9kZQULY2xhaW1Nb2RlV2gJAGYCBQZhbW91bnQFC3doU3BhY2VMZWZ0BwkAAgEJAKwCAgkArAICAgVPbmx5IAkApAMBBQt3aFNwYWNlTGVmdAIYIHNwYWNlIGxlZnQgaW4gd2FyZWhvdXNlBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQgFAWMCXzEEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQOY3VycmVudFBhY2tSZXMJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMCAV8EDGN1cnJlbnRXaFJlcwkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8EDSR0MDI3MzM1MjgyMDYDCQAAAgUJY2xhaW1Nb2RlBQtjbGFpbU1vZGVXaAkAlgoECQEGYWRkUmVzBQUMY3VycmVudFdoUmVzBQ10ZXJyYWluQ291bnRzCQBlAgUJZGVsdGFUaW1lBQxuZXdEZWx0YVRpbWUFCWxhbmRJbmRleAUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQIBQpyZXNUb0NsYWltAl8yCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUIBQpyZXNUb0NsYWltAl8yAwkAAAIFCWNsYWltTW9kZQUNY2xhaW1Nb2RlRHVjawkAlgoECQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMJAQZhZGRSZXMFBQ5jdXJyZW50UGFja1JlcwUNdGVycmFpbkNvdW50cwkAZQIFCWRlbHRhVGltZQUMbmV3RGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUEBWRpc3RyCQENZGlzdHJpYnV0ZVJlcwQFDGN1cnJlbnRXaFJlcwUOY3VycmVudFBhY2tSZXMFCnJlc1RvQ2xhaW0FC3doU3BhY2VMZWZ0BAR3aEFtCQCXAwEJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUJAMwIAggFCnJlc1RvQ2xhaW0CXzIFA25pbAkAlgoECAUFZGlzdHICXzEIBQVkaXN0cgJfMgkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAUEd2hBbQkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlBQR3aEFtBAV3aFJlcwgFDSR0MDI3MzM1MjgyMDYCXzEEBWJwUmVzCAUNJHQwMjczMzUyODIwNgJfMgQFbG9mdE8IBQ0kdDAyNzMzNTI4MjA2Al8zBAVsb2Z0RggFDSR0MDI3MzM1MjgyMDYCXzQJAJcKBQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBCAUBYwJfMgUMbmV3VGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgIBQFjAl8yBQRhZGRyBQxuZXdUaW1lc3RhbXAFA25pbAUFYnBLZXkJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCBQVicFJlcwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAUFd2hLZXkJAMwIAgkAkQMCBQljdXJyZW50V2gFC3doSWR4TGV2ZWxzCQDMCAIFBXdoUmVzCQDMCAIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAkAzAgCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kCQDMCAIJALkJAgkAzAgCCQCRAwIFBGxvZnQFCXZvbExvY2tlZAkAzAgCCQCkAwEFBWxvZnRPCQDMCAIJAKQDAQUFbG9mdEYJAMwIAgkAkQMCBQRsb2Z0BQh2b2xUb3RhbAUDbmlsAgFfBQNuaWwBCGNsYWltQWxsBARhZGRyC2xhbmRBc3NldElkBnBpZWNlcwljbGFpbU1vZGUEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBBXZhbHVlAQkAnwgBBQd0aW1lS2V5BAhhdmFpbFJlcwkAaAIJAGsDCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFCXNhdmVkVGltZQkBDGFwcGx5Qm9udXNlcwIFC2xhbmRBc3NldElkBQZwaWVjZXMFCURBWU1JTExJUwUGcGllY2VzCQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFCGF2YWlsUmVzBQljbGFpbU1vZGUFC2xhbmRBc3NldElkAQ11cEluZnJhQ29tbW9uBAxzaG91bGRVc2VNYXQGY2FsbGVyDXBheW1lbnRBbW91bnQLbGFuZEFzc2V0SWQEBGFkZHIJAKUIAQUGY2FsbGVyBAFjCQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBQRhZGRyBRNjbGFpbU1vZGVXaFRoZW5EdWNrBQtsYW5kQXNzZXRJZAQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCAUBYwJfMwULcmVjTGFuZFNpemUECGluZnJhS2V5CQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEIBQFjAl8yBAhjdXJMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQhpbmZyYUtleQAAAwkAZwIFCGN1ckxldmVsAAMJAAIBAiZDdXJyZW50bHkgbWF4IGluZnJhc3RydWN0dXJlIGxldmVsID0gMwQIbmV3TGV2ZWwJAGQCBQhjdXJMZXZlbAABBARjb3N0CQBrAwUVSW5mcmFVcGdyYWRlQ29zdFNVc2R0CQBoAgUGcGllY2VzBQhuZXdMZXZlbAUFU1NJWkUDAwkBASEBBQxzaG91bGRVc2VNYXQJAQIhPQIFDXBheW1lbnRBbW91bnQFBGNvc3QHCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUEY29zdAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEIBQFjAl8xBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBW1MaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBAZuZXdNYXQJALkJAgkBEXN1YnRyYWN0TWF0ZXJpYWxzAwUMc2hvdWxkVXNlTWF0BQVtTGlzdAkAawMFEUluZnJhVXBncmFkZUNvc3RTCQBoAgUGcGllY2VzBQhuZXdMZXZlbAUFU1NJWkUCAV8EC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwEBQRhZGRyCAUBYwJfMgUGcGllY2VzBRNjbGFpbU1vZGVXaFRoZW5EdWNrBAZ3aERhdGEIBQtjbGFpbVJlc3VsdAJfNQQGb2xkVm9sCQEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBCQCRAwIFBndoRGF0YQULd2hJZHhMZXZlbHMECm5ld1ZvbERhdGEJALkJAgkAzAgCCQCRAwIJALUJAgkAkQMCBQZ3aERhdGEFC3doSWR4TGV2ZWxzAgFfAAAJAMwIAgkApAMBBQhuZXdMZXZlbAUDbmlsAgFfBAZuZXdWb2wJARdnZXRXYXJlaG91c2VUb3RhbFZvbHVtZQEFCm5ld1ZvbERhdGEEBGxvZnQJALUJAgkAkQMCBQZ3aERhdGEFCXdoSWR4TE9GVAIBXwQKbmV3TG9mdFN0cgkAuQkCCQDMCAIJAJEDAgUEbG9mdAUJdm9sTG9ja2VkCQDMCAIJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQJAMwIAgkApAMBCQBlAgkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlBQZuZXdWb2wFBm9sZFZvbAkAzAgCCQCkAwEFBm5ld1ZvbAUDbmlsAgFfCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUIaW5mcmFLZXkFCG5ld0xldmVsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAggFAWMCXzIFBGFkZHIFCG5ld0xldmVsCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIIBQtjbGFpbVJlc3VsdAJfMwUIYnBJZHhSZXMJAMwIAgUGbmV3TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6CQDMCAIJAQtTdHJpbmdFbnRyeQIIBQtjbGFpbVJlc3VsdAJfNAkAuQkCCQDMCAIFCm5ld1ZvbERhdGEJAMwIAgkAkQMCBQZ3aERhdGEFCHdoSWR4UmVzCQDMCAIJAJEDAgUGd2hEYXRhBQh3aElkeE1hdAkAzAgCCQCRAwIFBndoRGF0YQUJd2hJZHhQcm9kCQDMCAIFCm5ld0xvZnRTdHIFA25pbAIBOgUDbmlsCAULY2xhaW1SZXN1bHQCXzEFCG5ld0xldmVsARJhY3RpdmF0ZU9uYm9hcmRBcnQBBGFkZHIAAAESYWN0aXZhdGVQcmVzYWxlQXJ0AgRhZGRyDWxhbmRBc3NldElkSW4EAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFE2NsYWltTW9kZVdoVGhlbkR1Y2sFDWxhbmRBc3NldElkSW4EC2xhbmRBc3NldElkCAUBYwJfMgQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCAUBYwJfMwULcmVjTGFuZFNpemUEDWFjdGl2YXRpb25LZXkJASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIFCkFSVFBSRVNBTEUFC2xhbmRBc3NldElkAwkAZgIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUNYWN0aXZhdGlvbktleQAAAAAJAAIBAiVQcmVzYWxlIGFydGlmYWN0IGlzIGFscmVhZHkgYWN0aXZhdGVkAwkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCCAUBYwJfMwUKcmVjTGFuZE51bQUPUFJFU0FMRU5VTUxBTkRTCQACAQkArAICCQCsAgIJAKwCAgUKTEFORFBSRUZJWAIBIAULbGFuZEFzc2V0SWQCJSBpcyBub3QgZWxpZ2libGUgZm9yIHByZXNhbGUgYXJ0aWZhY3QEC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwEBQRhZGRyBQtsYW5kQXNzZXRJZAUGcGllY2VzBRNjbGFpbU1vZGVXaFRoZW5EdWNrCQDNCAIJAM0IAgkAzQgCCQDNCAIIBQtjbGFpbVJlc3VsdAJfMQkBDEludGVnZXJFbnRyeQIFDWFjdGl2YXRpb25LZXkFBnBpZWNlcwkBDEludGVnZXJFbnRyeQIJASVrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQFBGFkZHIFBnBpZWNlcwkBC1N0cmluZ0VudHJ5AggFC2NsYWltUmVzdWx0Al8yCQC5CQIIBQtjbGFpbVJlc3VsdAJfMwIBOgkBC1N0cmluZ0VudHJ5AggFC2NsYWltUmVzdWx0Al80CQC5CQIIBQtjbGFpbVJlc3VsdAJfNQIBOgENbWVyZ2VJbnRlcm5hbAcLbmV3TGFuZFNpemUIbmV3TGV2ZWwHZm9ybXVsYQRhZGRyDGxhbmRBc3NldElkcwR0eElkB25lZWRNYXQEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAoBCmNoZWNrTWVyZ2UCA2FjYwtsYW5kQXNzZXRJZAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAQJc2F2ZWRUaW1lCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUHdGltZUtleQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkxBTkRQUkVGSVgCDSBpcyBub3QgeW91cnMEAWQJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBAljb250aW5lbnQJAJEDAgUBZAUMcmVjQ29udGluZW50AwMJAQIhPQIIBQNhY2MCXzMCAAkBAiE9AggFA2FjYwJfMwUJY29udGluZW50BwkAAgECLkxhbmRzIHNob3VsZCBiZSBvbiB0aGUgc2FtZSBjb250aW5lbnQgdG8gbWVyZ2UECGxhbmRTaXplCQCRAwIFAWQFC3JlY0xhbmRTaXplBAdzaXplc0luCAUDYWNjAl8xBAFpCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALMJAgUHc2l6ZXNJbgUIbGFuZFNpemUCJ1lvdSBoYXZlbid0IHBhc3NlZCBhbGwgdGhlIGxhbmRzIG5lZWRlZAQIc2l6ZXNPdXQJAKwCAgkArwICBQdzaXplc0luBQFpCQCwAgIFB3NpemVzSW4JAGQCBQFpAAEEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEFCGxhbmRTaXplBARhcnRzCQBkAggFA2FjYwJfMgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAAABAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQIcmVxTGV2ZWwEByRtYXRjaDAFCGxhbmRTaXplAwkAAAICAVMFByRtYXRjaDAAAwMJAAACAgFNBQckbWF0Y2gwAAQDCQAAAgIBTAUHJG1hdGNoMAAFAwkAAAICAlhMBQckbWF0Y2gwAAYJAAIBAhpPbmx5IFMsIE0sIEwsIFhMIGNhbiBtZXJnZQMJAQIhPQIFCmluZnJhTGV2ZWwFCHJlcUxldmVsCQACAQIiQWxsIGxhbmRzIHNob3VsZCBiZSBtYXhlZCB0byBtZXJnZQQHbGFuZE51bQkAkQMCBQFkBQpyZWNMYW5kTnVtBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEJAJEDAgUBZAULcmVjVGVycmFpbnMECWRlbHRhVGltZQkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQlzYXZlZFRpbWUDCQBmAgAABQlkZWx0YVRpbWUJAAIBCQCsAgIJAKwCAgkArAICAiZTYXZlZCB0aW1lc3RhbXAgaXMgaW4gZnV0dXJlLCBzYXZlZCA9IAkApAMBBQlzYXZlZFRpbWUCDCwgY3VycmVudCA9IAkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkBDGFwcGx5Qm9udXNlcwIFC2xhbmRBc3NldElkBQZwaWVjZXMECWxhbmRJbmRleAkAaQIFBnBpZWNlcwUFU1NJWkUEBWJwUmVzCQEGYWRkUmVzBQkAtQkCCAUDYWNjAl80AgFfBQ10ZXJyYWluQ291bnRzBQlkZWx0YVRpbWUFCWxhbmRJbmRleAUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQQFcHJvcHMJARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAkAtQkCCAUDYWNjAl82AgFfBQ10ZXJyYWluQ291bnRzBQlsYW5kSW5kZXgA////////////AQQFbGFuZHMIBQNhY2MCXzcEA2lkeAkAzwgCBQVsYW5kcwULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBBQNpZHgJAAIBCQCsAgICIFlvdXIgc3Rha2VkIGxhbmRzIGRvbid0IGNvbnRhaW4gBQtsYW5kQXNzZXRJZAQJY3VzdG9tS2V5CQEaa2V5TGFuZEFzc2V0SWRUb0N1c3RvbU5hbWUBBQtsYW5kQXNzZXRJZAQKY3VzdG9tTmFtZQkBC3ZhbHVlT3JFbHNlAgkAoggBBQljdXN0b21LZXkCAAkAmgoIBQhzaXplc091dAUEYXJ0cwUJY29udGluZW50BQVicFJlcwkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCAUDYWNjAl81CQELRGVsZXRlRW50cnkBCQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQELRGVsZXRlRW50cnkBCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgFC2xhbmRBc3NldElkBQRhZGRyCQELRGVsZXRlRW50cnkBCQEQa2V5TGFuZFRvQXNzZXRJZAEFB2xhbmROdW0JAQtEZWxldGVFbnRyeQEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIFC2xhbmRBc3NldElkBQRhZGRyCQELRGVsZXRlRW50cnkBCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQkBJWtleUxhbmRBcnRTdGF0dXNCeVR5cGVBc3NldElkQW5kT3duZXIDBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAUEYWRkcgkBC0RlbGV0ZUVudHJ5AQkBEWtleUxhbmROdW1Ub093bmVyAQUHbGFuZE51bQkBC0RlbGV0ZUVudHJ5AQkBEmtleVdhcmVob3VzZUJ5TGFuZAEFC2xhbmRBc3NldElkCQELRGVsZXRlRW50cnkBBQljdXN0b21LZXkJAQtEZWxldGVFbnRyeQEJARprZXlMYW5kQ3VzdG9tTmFtZVRvQXNzZXRJZAEFCmN1c3RvbU5hbWUJAQRCdXJuAgkA2QQBBQtsYW5kQXNzZXRJZAABBQVwcm9wcwkA0QgCBQVsYW5kcwkBBXZhbHVlAQUDaWR4CQBkAggFA2FjYwJfOAUGcGllY2VzBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQHcHJvcFN0cgkBC3ZhbHVlT3JFbHNlAgkAoggBCQERa2V5UmVzUHJvcG9ydGlvbnMAAgswXzBfMF8wXzBfMAQIbGFuZHNLZXkJARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBBQRhZGRyBAhsYW5kc1N0cgkAoggBBQhsYW5kc0tleQQHbGFuZHNJbgMJAQlpc0RlZmluZWQBBQhsYW5kc1N0cgkAvQkCCQEFdmFsdWUBBQhsYW5kc1N0cgIBXwUDbmlsBAFyCgACJGwFDGxhbmRBc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJoKCAUHZm9ybXVsYQAAAgAJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzBQNuaWwFB3Byb3BTdHIFB2xhbmRzSW4AAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEKY2hlY2tNZXJnZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUECWNvbnRpbmVudAgFAXICXzMEDGNvbnRpbmVudElkeAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDPCAIFCmNvbnRpbmVudHMFCWNvbnRpbmVudAkArAICAhNVbmtub3duIGNvbnRpbmVudDogBQljb250aW5lbnQECHRlcnJhaW5zCQELZ2VuVGVycmFpbnMCCQEDYWJzAQkAngMBBQR0eElkBQxjb250aW5lbnRJZHgEB2ZyZWVOdW0JAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBEmtleU5leHRGcmVlTGFuZE51bQAJAGQCBQ9QUkVTQUxFTlVNTEFORFMAAQQKbmV3TGFuZE51bQkApAMBBQdmcmVlTnVtBAVpc3N1ZQkAwggFCQEHbmZ0TmFtZQIFCm5ld0xhbmROdW0FC25ld0xhbmRTaXplCQC5CQIJAMwIAgUKbmV3TGFuZE51bQkAzAgCBQtuZXdMYW5kU2l6ZQkAzAgCBQh0ZXJyYWlucwkAzAgCBQljb250aW5lbnQFA25pbAIBXwABAAAHBAdhc3NldElkCQC4CAEFBWlzc3VlBA5uZXdMYW5kQXNzZXRJZAkA2AQBBQdhc3NldElkBAZuZXdNYXQJALkJAgkBEXN1YnRyYWN0TWF0ZXJpYWxzAwkAZgIFB25lZWRNYXQAAAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwUHbmVlZE1hdAIBXwQJcGllY2VzS2V5CQEWa2V5U3Rha2VkUGllY2VzQnlPd25lcgEFBGFkZHIEDHN0YWtlZFBpZWNlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlwaWVjZXNLZXkAAAkAlAoCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCAUBcgJfNQMJAGYCCQCQAwEIBQFyAl83AAAJAQtTdHJpbmdFbnRyeQIFCGxhbmRzS2V5CQC7CQIIBQFyAl83AgFfCQELRGVsZXRlRW50cnkBBQhsYW5kc0tleQkBDEludGVnZXJFbnRyeQIFCXBpZWNlc0tleQMJAGYCCAUBcgJfOAUMc3Rha2VkUGllY2VzAAAJAGUCBQxzdGFrZWRQaWVjZXMIBQFyAl84CQEMSW50ZWdlckVudHJ5AgkBEmtleU5leHRGcmVlTGFuZE51bQAJAGQCBQdmcmVlTnVtAAEFBWlzc3VlCQELU3RyaW5nRW50cnkCCQEQa2V5TGFuZFRvQXNzZXRJZAEFCm5ld0xhbmROdW0FDm5ld0xhbmRBc3NldElkCQELU3RyaW5nRW50cnkCCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQUObmV3TGFuZEFzc2V0SWQFBGFkZHIJAQtTdHJpbmdFbnRyeQIJARFrZXlMYW5kTnVtVG9Pd25lcgEFCm5ld0xhbmROdW0FBGFkZHIJAQxJbnRlZ2VyRW50cnkCCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQ5uZXdMYW5kQXNzZXRJZAgFAXICXzIJAQxJbnRlZ2VyRW50cnkCCQEla2V5TGFuZEFydFN0YXR1c0J5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkFSVFBSRVNBTEUFDm5ld0xhbmRBc3NldElkBQRhZGRyCAUBcgJfMgkBDEludGVnZXJFbnRyeQIJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQUObmV3TGFuZEFzc2V0SWQFCG5ld0xldmVsCQEMSW50ZWdlckVudHJ5AgkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIFDm5ld0xhbmRBc3NldElkBQRhZGRyBQhuZXdMZXZlbAkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIIBQFyAl80CQDMCAIFBm5ld01hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgkBC1N0cmluZ0VudHJ5AgkBEWtleVJlc1Byb3BvcnRpb25zAAgFAXICXzYJAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkAuQkCCQDMCAIFCWNvbnRpbmVudAkAzAgCAgFMCQDMCAIFDm5ld0xhbmRBc3NldElkBQNuaWwCAV8JAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBGFkZHIAAQUHYXNzZXRJZAUObmV3TGFuZEFzc2V0SWQBA3MybQMEYWRkcgxsYW5kQXNzZXRJZHMEdHhJZAkBDW1lcmdlSW50ZXJuYWwHAgFNAAMCBFNTU1MFBGFkZHIFDGxhbmRBc3NldElkcwUEdHhJZAAAAQNtMmwFBGFkZHIMbGFuZEFzc2V0SWRzBHR4SWQMc2hvdWxkVXNlTWF0DXBheW1lbnRBbW91bnQEBGNvc3QJAGgCBRVJbmZyYVVwZ3JhZGVDb3N0U1VzZHQABAMDCQEBIQEFDHNob3VsZFVzZU1hdAkBAiE9AgUNcGF5bWVudEFtb3VudAUEY29zdAcJAAIBCQCsAgICG1BheW1lbnQgYXR0YWNoZWQgc2hvdWxkIGJlIAkApAMBBQRjb3N0CQENbWVyZ2VJbnRlcm5hbAcCAUwABAIDU01NBQRhZGRyBQxsYW5kQXNzZXRJZHMFBHR4SWQJAGgCBRFJbmZyYVVwZ3JhZGVDb3N0UwAEAQRsMnhsBQRhZGRyDGxhbmRBc3NldElkcwR0eElkDHNob3VsZFVzZU1hdA1wYXltZW50QW1vdW50BARjb3N0CQBoAgUVSW5mcmFVcGdyYWRlQ29zdFNVc2R0AC8DAwkBASEBBQxzaG91bGRVc2VNYXQJAQIhPQIFDXBheW1lbnRBbW91bnQFBGNvc3QHCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUEY29zdAkBDW1lcmdlSW50ZXJuYWwHAgJYTAAFAgVTU1NNTAUEYWRkcgUMbGFuZEFzc2V0SWRzBQR0eElkCQBoAgURSW5mcmFVcGdyYWRlQ29zdFMALwEGeGwyeHhsBQRhZGRyDGxhbmRBc3NldElkcwR0eElkDHNob3VsZFVzZU1hdA1wYXltZW50QW1vdW50BARjb3N0CQBoAgUVSW5mcmFVcGdyYWRlQ29zdFNVc2R0ADYDAwkBASEBBQxzaG91bGRVc2VNYXQJAQIhPQIFDXBheW1lbnRBbW91bnQFBGNvc3QHCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUEY29zdAkBDW1lcmdlSW50ZXJuYWwHAgNYWEwABgIDTFhMBQRhZGRyBQxsYW5kQXNzZXRJZHMFBHR4SWQJAGgCBRFJbmZyYVVwZ3JhZGVDb3N0UwA2AQttZXJnZUNvbW1vbgUMc2hvdWxkVXNlTWF0BGFkZHINcGF5bWVudEFtb3VudAxsYW5kQXNzZXRJZHMEdHhJZAQLbWVyZ2VSZXN1bHQEByRtYXRjaDAJAJADAQUMbGFuZEFzc2V0SWRzAwkAAAIABAUHJG1hdGNoMAkBA3MybQMFBGFkZHIFDGxhbmRBc3NldElkcwUEdHhJZAMJAAACAAMFByRtYXRjaDAJAQNtMmwFBQRhZGRyBQxsYW5kQXNzZXRJZHMFBHR4SWQFDHNob3VsZFVzZU1hdAUNcGF5bWVudEFtb3VudAMJAAACAAUFByRtYXRjaDAJAQRsMnhsBQUEYWRkcgUMbGFuZEFzc2V0SWRzBQR0eElkBQxzaG91bGRVc2VNYXQFDXBheW1lbnRBbW91bnQDCQAAAgACBQckbWF0Y2gwCQEGeGwyeHhsBQUEYWRkcgUMbGFuZEFzc2V0SWRzBQR0eElkBQxzaG91bGRVc2VNYXQFDXBheW1lbnRBbW91bnQJAAIBAg1Vbmtub3duIG1lcmdlBQttZXJnZVJlc3VsdAEGcHJvbG9nAQFpAwMJAQIhPQIIBQFpDG9yaWdpbkNhbGxlcgUMcmVzdENvbnRyYWN0CQELdmFsdWVPckVsc2UCCQCgCAEJAQprZXlCbG9ja2VkAAcHCQACAQIfQ29udHJhY3RzIGFyZSB1bmRlciBtYWludGVuYW5jZQkBC1N0cmluZ0VudHJ5AgkBEWtleUxhc3RUeElkQnlVc2VyAQkApQgBCAUBaQxvcmlnaW5DYWxsZXIJANgEAQgFAWkNdHJhbnNhY3Rpb25JZB4BaQENY29uc3RydWN0b3JWMQEIcmVzdEFkZHIDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAkAzAgCCQELU3RyaW5nRW50cnkCCQEOa2V5UmVzdEFkZHJlc3MABQhyZXN0QWRkcgUDbmlsAWkBCnNldEJsb2NrZWQBCWlzQmxvY2tlZAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECEXBlcm1pc3Npb24gZGVuaWVkCQDMCAIJAQxCb29sZWFuRW50cnkCCQEKa2V5QmxvY2tlZAAFCWlzQmxvY2tlZAUDbmlsAWkBCXN0YWtlTGFuZAAEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAQHYXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgMJAQIhPQIIBQNwbXQGYW1vdW50AAEJAAIBCQCsAgIJAKwCAgIETkZUIAUKTEFORFBSRUZJWAIkIHRva2VuIHNob3VsZCBiZSBhdHRhY2hlZCBhcyBwYXltZW50BAVhc3NldAkBBXZhbHVlAQkA7AcBBQdhc3NldElkAwkBAiE9AggFBWFzc2V0Bmlzc3VlcgUEdGhpcwkAAgECF1Vua25vd24gaXNzdWVyIG9mIHRva2VuAwkBASEBCQEIY29udGFpbnMCCAUFYXNzZXQEbmFtZQUKTEFORFBSRUZJWAkAAgEJAKwCAgkArAICAglPbmx5IE5GVCAFCkxBTkRQUkVGSVgCFCB0b2tlbnMgYXJlIGFjY2VwdGVkBAtsYW5kTnVtU2l6ZQkAsAICCAUFYXNzZXQEbmFtZQAEBAdsYW5kTnVtAwkBCGNvbnRhaW5zAgULbGFuZE51bVNpemUCA1hYTAkAswICBQtsYW5kTnVtU2l6ZQADAwkBCGNvbnRhaW5zAgULbGFuZE51bVNpemUCAlhMCQCzAgIFC2xhbmROdW1TaXplAAIJALMCAgULbGFuZE51bVNpemUAAQMJAQEhAQkBCWlzRGVmaW5lZAEJALYJAQUHbGFuZE51bQkAAgEJAKwCAgIeQ2Fubm90IHBhcnNlIGxhbmQgbnVtYmVyIGZyb20gCAUFYXNzZXQEbmFtZQQLbGFuZEFzc2V0SWQJANgEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAMJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkJAAIBCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCEiBpcyBhbHJlYWR5IHN0YWtlZAQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8EDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQQFcHJvcHMJARF1cGRhdGVQcm9wb3J0aW9ucwMFDXRlcnJhaW5Db3VudHMJAGkCBQZwaWVjZXMFBVNTSVpFAAEECWFydFBpZWNlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAAABAhsYW5kc0tleQkBFWtleVN0YWtlZExhbmRzQnlPd25lcgEFB2FkZHJlc3MECGxhbmRzU3RyCQCiCAEFCGxhbmRzS2V5BAVsYW5kcwMJAQlpc0RlZmluZWQBBQhsYW5kc1N0cgkAvQkCCQEFdmFsdWUBBQhsYW5kc1N0cgIBXwUDbmlsAwkBD2NvbnRhaW5zRWxlbWVudAIFBWxhbmRzBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgIiWW91ciBzdGFrZWQgbGFuZHMgYWxyZWFkeSBjb250YWluIAULbGFuZEFzc2V0SWQECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd0aW1lS2V5CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYBQtsYW5kQXNzZXRJZAUHYWRkcmVzcwgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBC1N0cmluZ0VudHJ5AgUIbGFuZHNLZXkJALsJAgkAzQgCBQVsYW5kcwULbGFuZEFzc2V0SWQCAV8JAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQUHYWRkcmVzcwkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleVN0YWtlZFBpZWNlc0J5T3duZXIBBQdhZGRyZXNzAAAFBnBpZWNlcwkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQFB2FkZHJlc3MJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUxhbmROdW1Ub093bmVyAQUHbGFuZE51bQUHYWRkcmVzcwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBJWtleUxhbmRBcnRTdGF0dXNCeVR5cGVBc3NldElkQW5kT3duZXIDBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAUHYWRkcmVzcwUJYXJ0UGllY2VzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAgULbGFuZEFzc2V0SWQFB2FkZHJlc3MFCmluZnJhTGV2ZWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleVJlc1Byb3BvcnRpb25zAAUFcHJvcHMJAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwBaQELdW5zdGFrZUxhbmQBDWxhbmRBc3NldElkSW4EDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQZjYWxsZXIEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFDWNsYWltTW9kZUR1Y2sFDWxhbmRBc3NldElkSW4EC2xhbmRBc3NldElkCAUBYwJfMgQIbGFuZHNLZXkJARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBBQRhZGRyBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEJAJEDAggFAWMCXzMFC3JlY1RlcnJhaW5zBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQFcHJvcHMJARF1cGRhdGVQcm9wb3J0aW9ucwMFDXRlcnJhaW5Db3VudHMJAGkCBQZwaWVjZXMFBVNTSVpFAP///////////wEEC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwEBQRhZGRyBQtsYW5kQXNzZXRJZAUGcGllY2VzBQ1jbGFpbU1vZGVEdWNrBAVsYW5kcwkAvQkCCQELdmFsdWVPckVsc2UCCQCiCAEFCGxhbmRzS2V5AgACAV8EA2lkeAkAzwgCBQVsYW5kcwULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBBQNpZHgJAAIBCQCsAgICIFlvdXIgc3Rha2VkIGxhbmRzIGRvbid0IGNvbnRhaW4gBQtsYW5kQXNzZXRJZAQBdAgJAQV2YWx1ZQEJAO0HAQUGaGVpZ2h0CXRpbWVzdGFtcAQLcmVsZWFzZVRpbWUJAQt2YWx1ZU9yRWxzZQIJAJoIAgULZ292Q29udHJhY3QJARVrZXlVc2VyR3dsUmVsZWFzZVRpbWUBBQRhZGRyAAADCQBnAgULcmVsZWFzZVRpbWUFAXQJAAIBCQCsAgICOVlvdXIgZ1dMIGFyZSB0YWtpbmcgcGFydCBpbiB2b3RpbmcsIGNhbm5vdCB1bnN0YWtlIHVudGlsIAkApAMBBQtyZWxlYXNlVGltZQQJcGllY2VzS2V5CQEWa2V5U3Rha2VkUGllY2VzQnlPd25lcgEFBGFkZHIEDHN0YWtlZFBpZWNlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlwaWVjZXNLZXkAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIAAQkA2QQBBQtsYW5kQXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBCQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKTEFORFBSRUZJWAULbGFuZEFzc2V0SWQFBGFkZHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleVJlc1Byb3BvcnRpb25zAAUFcHJvcHMJAMwIAgkBC1N0cmluZ0VudHJ5AggFC2NsYWltUmVzdWx0Al8yCQC5CQIIBQtjbGFpbVJlc3VsdAJfMwIBOgkAzAgCAwkAZgIJAJADAQUFbGFuZHMAAQkBC1N0cmluZ0VudHJ5AgUIbGFuZHNLZXkJALsJAgkA0QgCBQVsYW5kcwkBBXZhbHVlAQUDaWR4AgFfCQELRGVsZXRlRW50cnkBBQhsYW5kc0tleQkAzAgCCQEMSW50ZWdlckVudHJ5AgUJcGllY2VzS2V5AwkAZgIFBnBpZWNlcwUMc3Rha2VkUGllY2VzAAAJAGUCBQxzdGFrZWRQaWVjZXMFBnBpZWNlcwkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAFpAQlzdGFrZUR1Y2sABAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEB2Fzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIDCQECIT0CCAUDcG10BmFtb3VudAABCQACAQkArAICCQCsAgICBE5GVCAFCkRVQ0tQUkVGSVgCJCB0b2tlbiBzaG91bGQgYmUgYXR0YWNoZWQgYXMgcGF5bWVudAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAMDCQECIT0CCAUFYXNzZXQGaXNzdWVyBQ1pbmN1YmF0b3JBZGRyCQECIT0CCAUFYXNzZXQGaXNzdWVyBQticmVlZGVyQWRkcgcJAAIBCQCsAgIJAKwCAgISVW5rbm93biBpc3N1ZXIgb2YgBQpEVUNLUFJFRklYAgYgdG9rZW4DCQEBIQEJAQhjb250YWlucwIIBQVhc3NldARuYW1lBQpEVUNLUFJFRklYCQACAQkArAICCQCsAgICCU9ubHkgTkZUIAUKRFVDS1BSRUZJWAIUIHRva2VucyBhcmUgYWNjZXB0ZWQECmFzc2V0SWRTdHIJANgEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQphc3NldElkU3RyAwkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQISIGlzIGFscmVhZHkgc3Rha2VkAwkBCWlzRGVmaW5lZAEJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwkAAgEJAKwCAgIdWW91IGFscmVhZHkgc3Rha2VkIG9uZSBkdWNrOiAIBQVhc3NldARuYW1lBAZsb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQphc3NldElkU3RyBAhsb2NhdGlvbgkAoggBBQZsb2NLZXkEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQphc3NldElkU3RyBAhiYWNrcGFjawkAoggBBQVicEtleQkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd0aW1lS2V5CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpEVUNLUFJFRklYCQDYBAEFB2Fzc2V0SWQFB2FkZHJlc3MIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQtTdHJpbmdFbnRyeQIJARBrZXlEdWNrSWRUb093bmVyAQUKYXNzZXRJZFN0cgUHYWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzBQphc3NldElkU3RyBQNuaWwDCQEJaXNEZWZpbmVkAQUIbG9jYXRpb24FA25pbAkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBmxvY0tleQUPREVGQVVMVExPQ0FUSU9OBQNuaWwDCQEJaXNEZWZpbmVkAQUIYmFja3BhY2sFA25pbAkAzQgCCQDNCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkCGjA6MF8wXzBfMF8wXzA6MF8wXzBfMF8wXzA6BQNuaWwJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFCmFzc2V0SWRTdHIAZAUMcHJvbG9nQWN0aW9uAWkBC3Vuc3Rha2VEdWNrAQphc3NldElkU3RyBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEB2Fzc2V0SWQJANkEAQUKYXNzZXRJZFN0cgQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEBWFzc2V0CQEFdmFsdWUBCQDsBwEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQkA2AQBBQdhc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAMJAQEhAQkBCWlzRGVmaW5lZAEJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwkAAgEJAKwCAgkArAICAglUaGUgZHVjayAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEQa2V5RHVja0lkVG9Pd25lcgEJANgEAQUHYXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUHYWRkcmVzcwkAAgECF1N0YWtlZCBORlQgaXMgbm90IHlvdXJzBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQUKYXNzZXRJZFN0cgQGaGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aABkAwkAZgIAZAUGaGVhbHRoCQACAQImUGxlYXNlIGhlYWwgeW91ciBkdWNrIGJlZm9yZSB1bnN0YWtpbmcJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyAAEFB2Fzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQUHdGltZUtleQkAzAgCCQELRGVsZXRlRW50cnkBBQlrZXlIZWFsdGgJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBD2tleUR1Y2tMb2NhdGlvbgEFCmFzc2V0SWRTdHIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBEGtleUR1Y2tJZFRvT3duZXIBBQphc3NldElkU3RyCQDMCAIJAQtEZWxldGVFbnRyeQEJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKRFVDS1BSRUZJWAUKYXNzZXRJZFN0cgUHYWRkcmVzcwkAzAgCCQELRGVsZXRlRW50cnkBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzCQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsAWkBCGNsYWltUmVzAgZhbW91bnQObGFuZEFzc2V0SWRTdHIEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEBnJlc3VsdAkBEGNsYWltUmVzSW50ZXJuYWwEBQRhZGRyBQZhbW91bnQFDWNsYWltTW9kZUR1Y2sFDmxhbmRBc3NldElkU3RyCQCUCgIJAM0IAgkAzQgCCQDNCAIIBQZyZXN1bHQCXzEJAQtTdHJpbmdFbnRyeQIIBQZyZXN1bHQCXzIJALkJAggFBnJlc3VsdAJfMwIBOgkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfNAkAuQkCCAUGcmVzdWx0Al81AgE6BQxwcm9sb2dBY3Rpb24JAJEDAggFBnJlc3VsdAJfMwUIYnBJZHhSZXMBaQEMY2xhaW1SZXNUb1dIAgZhbW91bnQObGFuZEFzc2V0SWRTdHIEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEBnJlc3VsdAkBEGNsYWltUmVzSW50ZXJuYWwEBQRhZGRyBQZhbW91bnQFC2NsYWltTW9kZVdoBQ5sYW5kQXNzZXRJZFN0cgkAlAoCCQDNCAIJAM0IAgkAzQgCCAUGcmVzdWx0Al8xCQELU3RyaW5nRW50cnkCCAUGcmVzdWx0Al8yCQC5CQIIBQZyZXN1bHQCXzMCAToJAQtTdHJpbmdFbnRyeQIIBQZyZXN1bHQCXzQJALkJAggFBnJlc3VsdAJfNQIBOgUMcHJvbG9nQWN0aW9uCQCRAwIIBQZyZXN1bHQCXzUFCHdoSWR4UmVzAWkBBmZsaWdodAIHbWVzc2FnZQNzaWcEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQIdXNlckFkZHIJAKUIAQgFAWkGY2FsbGVyBAFmCQEMZmxpZ2h0Q29tbW9uAwUIdXNlckFkZHIFB21lc3NhZ2UFA3NpZwQGbG9jS2V5CQEPa2V5RHVja0xvY2F0aW9uAQgFAWYCXzIEC2N1ckxvY2F0aW9uCQELdmFsdWVPckVsc2UCCQCiCAEFBmxvY0tleQUPREVGQVVMVExPQ0FUSU9OAwkAAAIIBQFmAl80BQtjdXJMb2NhdGlvbgkAAgECIllvdSBjYW4ndCBmbHkgdG8gdGhlIHNhbWUgbG9jYXRpb24EBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBCAUBZgJfMgQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAduZXdQcm9kCQEQc3VidHJhY3RQcm9kdWN0cwIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAgFAWYCXzUJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQZsb2NLZXkDCQBmAggFAWYCXzEAAAgFAWYCXzQFC2N1ckxvY2F0aW9uCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAkAzAgCBQduZXdQcm9kBQNuaWwCAToJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ1rZXlEdWNrSGVhbHRoAQgFAWYCXzIIBQFmAl8xCQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsCAUBZgJfMwFpAQRoZWFsAwpxdWFudGl0eUwxCnF1YW50aXR5TDIKcXVhbnRpdHlMMwQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMDAwkAZgIAAAUKcXVhbnRpdHlMMQYJAGYCAAAFCnF1YW50aXR5TDIGCQBmAgAABQpxdWFudGl0eUwzCQACAQIbUXVhbnRpdHkgY2Fubm90IGJlIG5lZ2F0aXZlBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBANxdHMJAMwIAgUKcXVhbnRpdHlMMQkAzAgCBQpxdWFudGl0eUwyCQDMCAIFCnF1YW50aXR5TDMFA25pbAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAlvbGRIZWFsdGgJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoAGQDCQBnAgUJb2xkSGVhbHRoBQVNQVhIUAkAAgEJAKwCAgkArAICAg9IUCBzaG91bGQgYmUgPCAJAKQDAQUFTUFYSFACCCB0byBoZWFsBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtl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IHN0YWtlZAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAlvbGRIZWFsdGgJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoAGQDCQBmAgUJb2xkSGVhbHRoAAAJAAIBAihIUCBzaG91bGQgYmUgMCB0byBjYWxsIEVtZXJnZW5jeSBTZXJ2aWNlBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQIcHJvZExpc3QDCQAAAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgAFA25pbAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAV8EDW1lZEtpdEFtb3VudDEDCQBmAgkAkAMBBQhwcm9kTGlzdAAACQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIcHJvZExpc3QAAAAABA1tZWRLaXRBbW91bnQyAwkAZgIJAJADAQUIcHJvZExpc3QAAQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCHByb2RMaXN0AAEAAAQNbWVkS2l0QW1vdW50MwMJAGYCCQCQAwEFCHByb2RMaXN0AAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhwcm9kTGlzdAACAAADAwMJAGYCBQ1tZWRLaXRBbW91bnQxAAAGCQBmAgUNbWVkS2l0QW1vdW50MgAABgkAZgIFDW1lZEtpdEFtb3VudDMAAAkAAgECH1lvdSBoYXZlIHRvIHVzZSBvd24gTWVkaWNhbCBLaXQECGV4aXN0U3RyCQCdCAIFD2Vjb25vbXlDb250cmFjdAkBDmtleUVzV2FyZWhvdXNlAAQMZXhpc3RBbW91bnRzAwkBCWlzRGVmaW5lZAEFCGV4aXN0U3RyCQC1CQIJAQV2YWx1ZQEFCGV4aXN0U3RyAgFfBQNuaWwEC2V4aXN0QW1vdW50AwkAZgIJAJADAQUMZXhpc3RBbW91bnRzAAAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQxleGlzdEFtb3VudHMAAAAAAwkAZwIAAAULZXhpc3RBbW91bnQJAAIBAjlUaGVyZSBhcmUgbm8gTWVkaWNhbCBLaXRzIEwxIGF0IEVtZXJnZW5jeSBTZXJ2aWNlIHN0b3JhZ2UECW5ld0hlYWx0aAkAZAIFCW9sZEhlYWx0aAkAkQMCBQhtZWRLaXRIcAAABAVuZXdFUwkAuQkCCQDMCAIJAKQDAQkAZQIFC2V4aXN0QW1vdW50AAEJANEIAgUMZXhpc3RBbW91bnRzAAACAV8EBnJlY2lwZQkAtQkCCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgAAAIBXwQIdG90YWxNYXQJARJnZXRSZWNpcGVNYXRlcmlhbHMBBQZyZWNpcGUECHBhY2tTaXplCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcmVjaXBlBRFyZWNpcGVJZHhQYWNrc2l6ZQQJc2VsbFByaWNlCQBrAwkAaAIFCHRvdGFsTWF0BQpFU1NFTExDT0VGBRBSRVNPVVJDRVBSSUNFTUlOCQBoAgAKBQhwYWNrU2l6ZQMJAQIhPQIIBQNwbXQGYW1vdW50BQlzZWxsUHJpY2UJAAIBCQCsAgICG1BheW1lbnQgYXR0YWNoZWQgc2hvdWxkIGJlIAkApAMBBQlzZWxsUHJpY2UEBnJlc3VsdAkBCGFzU3RyaW5nAQkA/AcEBQ9lY29ub215Q29udHJhY3QCD3VwZGF0ZUVzU3RvcmFnZQkAzAgCBQVuZXdFUwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQt1c2R0QXNzZXRJZAUJc2VsbFByaWNlBQNuaWwJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoBQluZXdIZWFsdGgJAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwFBnJlc3VsdAFpAQ51cGRhdGVCYWNrcGFjawILZHVja0Fzc2V0SWQHbmV3UGFjawQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIIBQFpBmNhbGxlcgUPZWNvbm9teUNvbnRyYWN0CQACAQIRcGVybWlzc2lvbiBkZW5pZWQJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAUHbmV3UGFjawkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAUHbmV3UGFjawFpAQhidXlTTGFuZAAEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhpBbGxvd2VkIFVTRFQgcGF5bWVudCBvbmx5IQMJAQIhPQIIBQNwbXQGYW1vdW50BQdFWFBVU0RUCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUHRVhQVVNEVAQGcmVzdWx0CQESZXhwZWRpdGlvbkludGVybmFsAggFAWkGY2FsbGVyCAUBaQ10cmFuc2FjdGlvbklkCQCUCgIJAM0IAgkAzQgCCAUGcmVzdWx0Al8xCQEOU2NyaXB0VHJhbnNmZXIDBQ9lY29ub215Q29udHJhY3QIBQNwbXQGYW1vdW50BQt1c2R0QXNzZXRJZAUMcHJvbG9nQWN0aW9uCAgFBnJlc3VsdAJfMgJfMQFpAQpleHBlZGl0aW9uAgdtZXNzYWdlA3NpZwQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAZyZXN1bHQJARBleHBlZGl0aW9uQ29tbW9uBAgFAWkGY2FsbGVyCAUBaQ10cmFuc2FjdGlvbklkBQdtZXNzYWdlBQNzaWcJAJQKAgkAzQgCCAUGcmVzdWx0Al8xBQxwcm9sb2dBY3Rpb24JAJQKAggFBnJlc3VsdAJfMggFBnJlc3VsdAJfMwFpAQx1cGdyYWRlSW5mcmEBC2xhbmRBc3NldElkBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBnJlc3VsdAkBDXVwSW5mcmFDb21tb24EBggFAWkGY2FsbGVyAAAFC2xhbmRBc3NldElkCQCUCgIJAM0IAggFBnJlc3VsdAJfMQUMcHJvbG9nQWN0aW9uCAUGcmVzdWx0Al8yAWkBEHVwZ3JhZGVJbmZyYVVzZHQBC2xhbmRBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhpBbGxvd2VkIFVTRFQgcGF5bWVudCBvbmx5IQQGcmVzdWx0CQENdXBJbmZyYUNvbW1vbgQHCAUBaQZjYWxsZXIIBQNwbXQGYW1vdW50BQtsYW5kQXNzZXRJZAkAlAoCCQDNCAIJAM0IAggFBnJlc3VsdAJfMQkBDlNjcmlwdFRyYW5zZmVyAwUPZWNvbm9teUNvbnRyYWN0CAUDcG10BmFtb3VudAULdXNkdEFzc2V0SWQFDHByb2xvZ0FjdGlvbggFBnJlc3VsdAJfMgFpARBhY3RpdmF0ZUFydGlmYWN0AgdhcnROYW1lC2xhbmRBc3NldElkBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBnJlc3VsdAQHJG1hdGNoMAUHYXJ0TmFtZQMJAAACAgdQUkVTQUxFBQckbWF0Y2gwCQESYWN0aXZhdGVQcmVzYWxlQXJ0AgkApQgBCAUBaQZjYWxsZXIFC2xhbmRBc3NldElkCQACAQIQVW5rbm93biBhcnRpZmFjdAkAzQgCBQZyZXN1bHQFDHByb2xvZ0FjdGlvbgFpAQptZXJnZUxhbmRzAQxsYW5kQXNzZXRJZHMEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQGcmVzdWx0CQELbWVyZ2VDb21tb24FBgkApQgBCAUBaQZjYWxsZXIAAAUMbGFuZEFzc2V0SWRzCAUBaQ10cmFuc2FjdGlvbklkCQCUCgIJAM0IAggFBnJlc3VsdAJfMQUMcHJvbG9nQWN0aW9uCAUGcmVzdWx0Al8yAWkBDm1lcmdlTGFuZHNVc2R0AQxsYW5kQXNzZXRJZHMEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhpBbGxvd2VkIFVTRFQgcGF5bWVudCBvbmx5IQQGcmVzdWx0CQELbWVyZ2VDb21tb24FBwkApQgBCAUBaQZjYWxsZXIIBQNwbXQGYW1vdW50BQxsYW5kQXNzZXRJZHMIBQFpDXRyYW5zYWN0aW9uSWQJAJQKAgkAzQgCCQDNCAIIBQZyZXN1bHQCXzEJAQ5TY3JpcHRUcmFuc2ZlcgMFD2Vjb25vbXlDb250cmFjdAgFA3BtdAZhbW91bnQFC3VzZHRBc3NldElkBQxwcm9sb2dBY3Rpb24IBQZyZXN1bHQCXzIBaQENY2FyZ29FeGNoYW5nZQIMY2FyZ29MaXN0U3RyC2xhbmRBc3NldElkBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQECmNhcmdvUGFydHMJALwJAgUMY2FyZ29MaXN0U3RyAgE6BARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAggFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQJbGFuZEluZGV4CQBpAgkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8FC3JlY0xhbmRTaXplBQVTU0laRQQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04EA2xvYwkAtQkCCQEFdmFsdWUBBQtjdXJMb2NhdGlvbgIBXwMJAQIhPQIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFMCQACAQkArAICCQCsAgICFkR1Y2sgbG9jYXRpb24gdHlwZSBpcyAJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAhEsIGJ1dCBzaG91bGQgYmUgTAMJAQIhPQIJAJEDAgUDbG9jBQhsb2NJZHhJZAULbGFuZEFzc2V0SWQJAAIBCQCsAgICG0R1Y2sgc2hvdWxkIGJlIG9uIHRoZSBsYW5kIAULbGFuZEFzc2V0SWQEBXdoS2V5CQESa2V5V2FyZWhvdXNlQnlMYW5kAQULbGFuZEFzc2V0SWQECWN1cnJlbnRXaAkBDGdldFdhcmVob3VzZQMFBXdoS2V5BQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAZyZXN1bHQJAQltb3ZlU3R1ZmYDBQpjYXJnb1BhcnRzBQljdXJyZW50V2gFC2N1cnJlbnRQYWNrBARsb2Z0CQC1CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeExPRlQCAV8EBWxvZnRPCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFC3ZvbE9jY3VwaWVkCAUGcmVzdWx0Al83BAVsb2Z0RgkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlCAUGcmVzdWx0Al83CQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC6CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCAUGcmVzdWx0Al80CQDMCAIIBQZyZXN1bHQCXzUJAMwIAggFBnJlc3VsdAJfNgUDbmlsAgE6CQDMCAIJAQtTdHJpbmdFbnRyeQIFBXdoS2V5CQC6CQIJAMwIAgkAkQMCBQljdXJyZW50V2gFC3doSWR4TGV2ZWxzCQDMCAIIBQZyZXN1bHQCXzEJAMwIAggFBnJlc3VsdAJfMgkAzAgCCAUGcmVzdWx0Al8zCQDMCAIJALkJAgkAzAgCCQCRAwIFBGxvZnQFCXZvbExvY2tlZAkAzAgCCQCkAwEFBWxvZnRPCQDMCAIJAKQDAQUFbG9mdEYJAMwIAgkAkQMCBQRsb2Z0BQh2b2xUb3RhbAUDbmlsAgFfBQNuaWwCAToJAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwBaQENc2F2ZVdhcmVob3VzZQIFd2hTdHILbGFuZEFzc2V0SWQEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCAUBaQZjYWxsZXIFD2Vjb25vbXlDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQEBXdoS2V5CQESa2V5V2FyZWhvdXNlQnlMYW5kAQULbGFuZEFzc2V0SWQEAndoCQC8CQIFBXdoU3RyAgE6AwkBAiE9AgkAkAMBBQJ3aAAFCQACAQIwd2FyZWhvdXNlIHN0cmluZyBzaG91bGQgY29udGFpbiA0ICc6JyBzZXBhcmF0b3JzBAVsb2Z0TAkAkQMCCQC1CQIJAJEDAgUCd2gFCXdoSWR4TE9GVAIBXwUJdm9sTG9ja2VkBAVsb2Z0TwkBF2dldFdhcmVob3VzZU9jY3VwaWVkVm9sAQUCd2gEBWxvZnRUCQEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBCQCRAwIFAndoBQt3aElkeExldmVscwQFbG9mdEYJAGUCCQBlAgUFbG9mdFQJAQ1wYXJzZUludFZhbHVlAQUFbG9mdEwFBWxvZnRPBAhuZXdXaFN0cgkAugkCCQDMCAIJAJEDAgUCd2gFC3doSWR4TGV2ZWxzCQDMCAIJAJEDAgUCd2gFCHdoSWR4UmVzCQDMCAIJAJEDAgUCd2gFCHdoSWR4TWF0CQDMCAIJAJEDAgUCd2gFCXdoSWR4UHJvZAkAzAgCCQC5CQIJAMwIAgUFbG9mdEwJAMwIAgkApAMBBQVsb2Z0TwkAzAgCCQCkAwEFBWxvZnRGCQDMCAIJAKQDAQUFbG9mdFQFA25pbAIBXwUDbmlsAgE6CQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUFd2hLZXkFCG5ld1doU3RyCQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsBQhuZXdXaFN0cgFpARJmaXhXYXJlaG91c2VGb3JtYXQBC2xhbmRBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQxyZXN0Q29udHJhY3QJAAIBAg1BY2Nlc3MgZGVuaWVkBAV3aEtleQkBEmtleVdhcmVob3VzZUJ5TGFuZAEFC2xhbmRBc3NldElkBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAlsYW5kSW5kZXgJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwULcmVjTGFuZFNpemUFBVNTSVpFBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQCd2gJAQxnZXRXYXJlaG91c2UDBQV3aEtleQUJbGFuZEluZGV4BQppbmZyYUxldmVsBAVsb2Z0TAkBBWFzSW50AQkA/AcEBQ9lY29ub215Q29udHJhY3QCGnJlY2FsY0xvY2tlZFZvbHVtZVJFQURPTkxZCQDMCAIFC2xhbmRBc3NldElkCQDMCAIFAndoBQNuaWwFA25pbAQFbG9mdE8JARdnZXRXYXJlaG91c2VPY2N1cGllZFZvbAEFAndoBAVsb2Z0VAkBF2dldFdhcmVob3VzZVRvdGFsVm9sdW1lAQkAkQMCBQJ3aAULd2hJZHhMZXZlbHMEBWxvZnRGCQBlAgkAZQIFBWxvZnRUBQVsb2Z0TAUFbG9mdE8ECG5ld1doU3RyCQC6CQIJAMwIAgkAkQMCBQJ3aAULd2hJZHhMZXZlbHMJAMwIAgkAkQMCBQJ3aAUId2hJZHhSZXMJAMwIAgkAkQMCBQJ3aAUId2hJZHhNYXQJAMwIAgkAkQMCBQJ3aAUJd2hJZHhQcm9kCQDMCAIJALkJAgkAzAgCCQCkAwEFBWxvZnRMCQDMCAIJAKQDAQUFbG9mdE8JAMwIAgkApAMBBQVsb2Z0RgkAzAgCCQCkAwEFBWxvZnRUBQNuaWwCAV8FA25pbAIBOgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBXdoS2V5BQhuZXdXaFN0cgUDbmlsBQhuZXdXaFN0cgFpAQ9maXhTdGFrZWRQaWVjZXMBB2FkZHJlc3MDCQECIT0CCAUBaQZjYWxsZXIFDHJlc3RDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQEDHN0YWtlZFBpZWNlcwMJAAACBQdhZGRyZXNzAgAAAAQIbGFuZHNTdHIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUHYWRkcmVzcwQFbGFuZHMDCQEJaXNEZWZpbmVkAQUIbGFuZHNTdHIJAL0JAgkBBXZhbHVlAQUIbGFuZHNTdHICAV8FA25pbAoBB29uZUxhbmQCA2FjYwtsYW5kQXNzZXRJZAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQIbGFuZFNpemUJAJEDAgkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8FC3JlY0xhbmRTaXplCQBkAgUDYWNjCQEPbnVtUGllY2VzQnlTaXplAQUIbGFuZFNpemUKAAIkbAUFbGFuZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB29uZUxhbmQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFUxpc3Qgc2l6ZSBleGNlZWRzIDEwMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAGIAYwBkCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQUHYWRkcmVzcwUMc3Rha2VkUGllY2VzBQNuaWwFDHN0YWtlZFBpZWNlcwFpAQ1zZXRDdXN0b21OYW1lAwdhc3NldElkCmN1c3RvbU5hbWUEdHlwZQQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHEV4YWN0bHkgb25lIHBheW1lbnQgcmVxdWlyZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AggFA3BtdAdhc3NldElkBQt1c2R0QXNzZXRJZAkAAgECGkFsbG93ZWQgVVNEVCBwYXltZW50IG9ubHkhAwkBAiE9AggFA3BtdAZhbW91bnQFDFJFTkFNSU5HQ09TVAkAAgEJAKwCAgISUGF5bWVudCBzaG91bGQgYmUgCQCkAwEFDFJFTkFNSU5HQ09TVAMJAQhjb250YWlucwIFCmN1c3RvbU5hbWUCAl9fCQACAQkArAICAh5OYW1lIHNob3VsZCBub3QgY29udGFpbiAnX18nOiAFCmN1c3RvbU5hbWUDCQBmAgkAsQIBBQpjdXN0b21OYW1lBQpNQVhOQU1FTEVOCQACAQkArAICAhlOYW1lIHRvbyBsb25nLCBtYXhMZW5ndGg9CQCkAwEFCk1BWE5BTUVMRU4EBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAdhY3Rpb25zBAckbWF0Y2gwBQR0eXBlAwkAAAICB0FDQ09VTlQFByRtYXRjaDAECnJldmVyc2VLZXkJARZrZXlDdXN0b21OYW1lVG9BZGRyZXNzAQUKY3VzdG9tTmFtZQQJbmFtZU93bmVyCQCiCAEFCnJldmVyc2VLZXkDCQEJaXNEZWZpbmVkAQUJbmFtZU93bmVyCQACAQkArAICAhlOYW1lIGFscmVhZHkgcmVnaXN0ZXJlZDogBQpjdXN0b21OYW1lBA1hZGRyVG9OYW1lS2V5CQEWa2V5QWRkcmVzc1RvQ3VzdG9tTmFtZQEFBGFkZHIEB29sZE5hbWUJAKIIAQUNYWRkclRvTmFtZUtleQQHZnJlZU9sZAMJAQlpc0RlZmluZWQBBQdvbGROYW1lCQDMCAIJAQtEZWxldGVFbnRyeQEJARZrZXlDdXN0b21OYW1lVG9BZGRyZXNzAQkBBXZhbHVlAQUHb2xkTmFtZQUDbmlsBQNuaWwJAM0IAgkAzQgCBQdmcmVlT2xkCQELU3RyaW5nRW50cnkCBQ1hZGRyVG9OYW1lS2V5BQpjdXN0b21OYW1lCQELU3RyaW5nRW50cnkCBQpyZXZlcnNlS2V5BQRhZGRyAwkAAAICBExBTkQFByRtYXRjaDAEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQdhc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFB2Fzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkxBTkRQUkVGSVgCDSBpcyBub3QgeW91cnMECnJldmVyc2VLZXkJARprZXlMYW5kQ3VzdG9tTmFtZVRvQXNzZXRJZAEFCmN1c3RvbU5hbWUECW5hbWVPd25lcgkAoggBBQpyZXZlcnNlS2V5AwkBCWlzRGVmaW5lZAEFCW5hbWVPd25lcgkAAgEJAKwCAgIZTmFtZSBhbHJlYWR5IHJlZ2lzdGVyZWQ6IAUKY3VzdG9tTmFtZQQOYXNzZXRUb05hbWVLZXkJARprZXlMYW5kQXNzZXRJZFRvQ3VzdG9tTmFtZQEFB2Fzc2V0SWQEB29sZE5hbWUJAKIIAQUOYXNzZXRUb05hbWVLZXkEB2ZyZWVPbGQDCQEJaXNEZWZpbmVkAQUHb2xkTmFtZQkAzAgCCQELRGVsZXRlRW50cnkBCQEaa2V5TGFuZEN1c3RvbU5hbWVUb0Fzc2V0SWQBCQEFdmFsdWUBBQdvbGROYW1lBQNuaWwFA25pbAkAzQgCCQDNCAIFB2ZyZWVPbGQJAQtTdHJpbmdFbnRyeQIFDmFzc2V0VG9OYW1lS2V5BQpjdXN0b21OYW1lCQELU3RyaW5nRW50cnkCBQpyZXZlcnNlS2V5BQdhc3NldElkAwkAAAICBERVQ0sFByRtYXRjaDAEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQdhc3NldElkAwMJAQEhAQkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQYJAQEhAQkBCWlzRGVmaW5lZAEJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgkAAgEJAKwCAggFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARBrZXlEdWNrSWRUb093bmVyAQUHYXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKRFVDS1BSRUZJWAINIGlzIG5vdCB5b3VycwQKcmV2ZXJzZUtleQkBGmtleUR1Y2tDdXN0b21OYW1lVG9Bc3NldElkAQUKY3VzdG9tTmFtZQQJbmFtZU93bmVyCQCiCAEFCnJldmVyc2VLZXkDCQEJaXNEZWZpbmVkAQUJbmFtZU93bmVyCQACAQkArAICAhlOYW1lIGFscmVhZHkgcmVnaXN0ZXJlZDogBQpjdXN0b21OYW1lBA5hc3NldFRvTmFtZUtleQkBGmtleUR1Y2tBc3NldElkVG9DdXN0b21OYW1lAQUHYXNzZXRJZAQHb2xkTmFtZQkAoggBBQ5hc3NldFRvTmFtZUtleQQHZnJlZU9sZAMJAQlpc0RlZmluZWQBBQdvbGROYW1lCQDMCAIJAQtEZWxldGVFbnRyeQEJARprZXlEdWNrQ3VzdG9tTmFtZVRvQXNzZXRJZAEJAQV2YWx1ZQEFB29sZE5hbWUFA25pbAUDbmlsCQDNCAIJAM0IAgUHZnJlZU9sZAkBC1N0cmluZ0VudHJ5AgUOYXNzZXRUb05hbWVLZXkFCmN1c3RvbU5hbWUJAQtTdHJpbmdFbnRyeQIFCnJldmVyc2VLZXkFB2Fzc2V0SWQJAAIBAhNVbmtub3duIGVudGl0eSB0eXBlCQCUCgIJAM0IAgkAzQgCBQdhY3Rpb25zCQEOU2NyaXB0VHJhbnNmZXIDBQ9lY29ub215Q29udHJhY3QIBQNwbXQGYW1vdW50BQt1c2R0QXNzZXRJZAUMcHJvbG9nQWN0aW9uAAABaQEMc2V0UmVmZXJyYWxzAglvbGRQbGF5ZXIJbmV3UGxheWVyAwkBAiE9AggFAWkPY2FsbGVyUHVibGljS2V5BQNwdWIJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkAwkBASEBCQEJaXNEZWZpbmVkAQkApggBBQlvbGRQbGF5ZXIJAAIBCQCsAgICEUludmFsaWQgYWRkcmVzczogBQlvbGRQbGF5ZXIDCQEBIQEJAQlpc0RlZmluZWQBCQCmCAEFCW5ld1BsYXllcgkAAgEJAKwCAgIRSW52YWxpZCBhZGRyZXNzOiAFCW5ld1BsYXllcgQHb2xkc0tleQkBCWtleU9sZGllcwAEBG9sZHMJAKIIAQUHb2xkc0tleQQGb2xkaWVzAwkBCWlzRGVmaW5lZAEFBG9sZHMJALwJAgkBBXZhbHVlAQUEb2xkcwIBXwUDbmlsAwkBD2NvbnRhaW5zRWxlbWVudAIFBm9sZGllcwUJbmV3UGxheWVyCQACAQkArAICBQluZXdQbGF5ZXICJiBpcyBub3QgbmV3YmllIChhbHJlYWR5IGhhcyByZWZlcnJhbHMpBAhyZWZCeUtleQkBD2tleUFkZHJlc3NSZWZCeQEFCW5ld1BsYXllcgQFcmVmQnkJAKIIAQUIcmVmQnlLZXkDAwkBCWlzRGVmaW5lZAEFBXJlZkJ5CQEJaXNEZWZpbmVkAQkApggBCQEFdmFsdWUBBQVyZWZCeQcJAAIBCQCsAgIJAKwCAgUJbmV3UGxheWVyAhQgYWxyZWFkeSBoYXMgcmVmQnk6IAkBBXZhbHVlAQUFcmVmQnkEB3JlZnNLZXkJARNrZXlBZGRyZXNzUmVmZXJyYWxzAQUJb2xkUGxheWVyBARyZWZzCQCiCAEFB3JlZnNLZXkECXJlZnNBcnJheQMJAQlpc0RlZmluZWQBBQRyZWZzCQC8CQIJAQV2YWx1ZQEFBHJlZnMCAV8FA25pbAMJAQ9jb250YWluc0VsZW1lbnQCBQlyZWZzQXJyYXkFCW5ld1BsYXllcgkAAgEJAKwCAgkArAICCQCsAgIFCW9sZFBsYXllcgISIGFscmVhZHkgY29udGFpbnMgBQluZXdQbGF5ZXICESB3aXRoaW4gcmVmZXJyYWxzBAduZXdSZWZzCQC6CQIJAM0IAgUJcmVmc0FycmF5BQluZXdQbGF5ZXICAV8EB25ld09sZHMDCQEPY29udGFpbnNFbGVtZW50AgUGb2xkaWVzBQlvbGRQbGF5ZXIJAQV2YWx1ZQEFBG9sZHMJALoJAgkAzQgCBQZvbGRpZXMFCW9sZFBsYXllcgIBXwkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFCHJlZkJ5S2V5BQlvbGRQbGF5ZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgUHcmVmc0tleQUHbmV3UmVmcwkAzAgCCQELU3RyaW5nRW50cnkCBQdvbGRzS2V5BQduZXdPbGRzCQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsAAABaQEcc3BsaXRCeUdsb2JhbFdlaWdodHNSRUFET05MWQEGYW1vdW50CQCUCgIFA25pbAkBEmdldE5lZWRlZE1hdGVyaWFscwEFBmFtb3VudAFpASRzcGxpdEJ5R2xvYmFsQW5kTG9jYWxXZWlnaHRzUkVBRE9OTFkDCW1hdEFtb3VudAlyZXNBbW91bnQIdGVycmFpbnMEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQUIdGVycmFpbnMJAJQKAgUDbmlsCQCUCgIJARJnZXROZWVkZWRNYXRlcmlhbHMBBQltYXRBbW91bnQJARNkaXN0cmlidXRlQnlXZWlnaHRzAgUJcmVzQW1vdW50BQ10ZXJyYWluQ291bnRzAWkBE2dldEJhY2twYWNrUkVBRE9OTFkBC2R1Y2tBc3NldElkCQCUCgIFA25pbAkAuQkCCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAIBOgFpARRnZXRXYXJlaG91c2VSRUFET05MWQELbGFuZEFzc2V0SWQEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQECWxhbmRJbmRleAkAaQIJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBQtyZWNMYW5kU2l6ZQUFU1NJWkUECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAACQCUCgIFA25pbAkAugkCCQEMZ2V0V2FyZWhvdXNlAwkBEmtleVdhcmVob3VzZUJ5TGFuZAEFC2xhbmRBc3NldElkBQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwCAToBaQEKc2F2ZUxhc3RUeAADCQECIT0CCAUBaQZjYWxsZXIFC3dsZ0NvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAkAlAoCCQDMCAIJAQZwcm9sb2cBBQFpBQNuaWwAKgDSxETy", "height": 2631298, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: DqNMsQaMHFX6VTsFzhcgJCp7Vf9ggPeRWDEAkvV2ZQ6c Next: D29kBp3N4g14JqRFvanaL1j4Q5p1Dcy3VdjVk1cMkr6W Diff:
OldNewDifferences
494494
495495 let flBonus = 6
496496
497+let flProdsUsed = 7
498+
497499 func nftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
498500
499501
558560 }
559561 else has
560562 }
563+
564+
565+func subtractProducts (pHas,pUsed) = if ((pUsed == ""))
566+ then pHas
567+ else {
568+ let pList = if ((pHas == ""))
569+ then nil
570+ else split(pHas, "_")
571+ func subP (acc,item) = {
572+ let j = acc._1
573+ func checkUsed (ac,idxAmt) = {
574+ let parts = split(idxAmt, ",")
575+ if ((size(parts) != 2))
576+ then throw("Incorrect format, should be index,amount")
577+ else {
578+ let idx = parseIntValue(parts[0])
579+ if (if ((0 > idx))
580+ then true
581+ else (idx >= size(productionMatrix)))
582+ then throw("Unknown product idx")
583+ else if ((idx != j))
584+ then ac
585+ else {
586+ let amt = parseIntValue(parts[1])
587+ if ((0 >= amt))
588+ then throw("Pass only positive amounts")
589+ else (ac + amt)
590+ }
591+ }
592+ }
593+
594+ let a = {
595+ let $l = split(pUsed, "_")
596+ let $s = size($l)
597+ let $acc0 = 0
598+ func $f0_1 ($a,$i) = if (($i >= $s))
599+ then $a
600+ else checkUsed($a, $l[$i])
601+
602+ func $f0_2 ($a,$i) = if (($i >= $s))
603+ then $a
604+ else throw("List size exceeds 10")
605+
606+ $f0_2($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)
607+ }
608+ let curr = if ((size(pList) > j))
609+ then parseIntValue(pList[j])
610+ else 0
611+ let newAmt = if ((a > curr))
612+ then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[j]) + ", but tried to use ") + toString(a)))
613+ else (curr - a)
614+ $Tuple2((j + 1), (acc._2 :+ toString(newAmt)))
615+ }
616+
617+ let newProd = {
618+ let $l = productionMatrix
619+ let $s = size($l)
620+ let $acc0 = $Tuple2(0, nil)
621+ func $f0_1 ($a,$i) = if (($i >= $s))
622+ then $a
623+ else subP($a, $l[$i])
624+
625+ func $f0_2 ($a,$i) = if (($i >= $s))
626+ then $a
627+ else throw("List size exceeds 50")
628+
629+ $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)
630+ }
631+ makeString(newProd._2, "_")
632+ }
561633
562634
563635 func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
10001072 }
10011073
10021074
1003-func expeditionCommon (shouldUseMat,caller,txId,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
1075+func flightCommon (userAddr,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
10041076 then throw("signature does not match")
10051077 else {
10061078 let parts = split(toUtf8String(message), ";")
10141086 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
10151087 then true
10161088 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
1017- then throw("signature outdated")
1089+ then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
10181090 else {
10191091 let txFromMsg = newLocTxVer[1]
1020- let userAddr = toString(caller)
10211092 let lastTx = valueOrElse(getString(keyLastTxIdByUser(userAddr)), "")
10221093 if ((lastTx != txFromMsg))
10231094 then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
10291100 then throw(((("oldHealth=" + toString(valueOrElse(getInteger(keyHealth), 100))) + " from state does not match one from flight log=") + toString(curHP)))
10301101 else if ((0 >= curHP))
10311102 then throw("You can't fly with zero health")
1032- else if ((0 >= newHP))
1033- then $Tuple3(((if (!(shouldUseMat))
1034- then [ScriptTransfer(caller, EXPUSDT, usdtAssetId)]
1035- else nil) :+ IntegerEntry(keyHealth, 0)), "", 0)
1036- else {
1037- let bonus = if ((size(flightLog) > flBonus))
1038- then flightLog[flBonus]
1039- else ""
1040- let sentAmount = if ((bonus == "$"))
1041- then asInt(invoke(restContract, "sendUsdtPrize", [userAddr], nil))
1042- else 0
1043- let bpKey = keyBackpackByDuck(duckAssetId)
1044- let currentPack = getBackpack(bpKey)
1045- let mList = split(currentPack[bpIdxMat], "_")
1046- let newMat = makeString(subtractMaterials(shouldUseMat, mList, EXPMATERIALS), "_")
1047- let e = expeditionInternal(caller, txId)
1048- let id = e._2._1
1049- $Tuple3((((e._1 :+ StringEntry(keyDuckLocation(duckAssetId), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, newHP)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))), id, sentAmount)
1050- }
1103+ else {
1104+ let bonus = if ((size(flightLog) > flBonus))
1105+ then flightLog[flBonus]
1106+ else ""
1107+ let prodUsed = if ((size(flightLog) > flProdsUsed))
1108+ then flightLog[flProdsUsed]
1109+ else ""
1110+ let sentAmount = if (if ((newHP > 0))
1111+ then (bonus == "$")
1112+ else false)
1113+ then asInt(invoke(restContract, "sendUsdtPrize", [userAddr], nil))
1114+ else 0
1115+ $Tuple5(newHP, duckAssetId, sentAmount, newLocation, prodUsed)
1116+ }
10511117 }
10521118 }
10531119 }
1120+
1121+
1122+func expeditionCommon (caller,txId,message,sig) = {
1123+ let userAddr = toString(caller)
1124+ let f = flightCommon(userAddr, message, sig)
1125+ let keyHealth = keyDuckHealth(f._2)
1126+ let bpKey = keyBackpackByDuck(f._2)
1127+ let currentPack = getBackpack(bpKey)
1128+ let mList = split(currentPack[bpIdxMat], "_")
1129+ let newMat = makeString(subtractMaterials(true, mList, EXPMATERIALS), "_")
1130+ let newProd = subtractProducts(currentPack[bpIdxProd], f._5)
1131+ if ((0 >= f._1))
1132+ then $Tuple3([IntegerEntry(keyHealth, 0), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProd], ":"))], "", 0)
1133+ else {
1134+ let e = expeditionInternal(caller, txId)
1135+ let id = e._2._1
1136+ $Tuple3((((e._1 :+ StringEntry(keyDuckLocation(f._2), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, f._1)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, newProd], ":"))), id, f._3)
1137+ }
1138+ }
10541139
10551140
10561141 func applyBonuses (landAssetId,pieces) = {
10631148
10641149
10651150 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
1066- let $t02270623245 = if ((claimMode == claimModeWh))
1151+ let $t02442224961 = if ((claimMode == claimModeWh))
10671152 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
10681153 else {
10691154 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
10731158 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
10741159 else $Tuple2(loc[locIdxId], duckAssetId)
10751160 }
1076- let landAssetId = $t02270623245._1
1077- let duckId = $t02270623245._2
1161+ let landAssetId = $t02442224961._1
1162+ let duckId = $t02442224961._2
10781163 let asset = value(assetInfo(fromBase58String(landAssetId)))
10791164 let timeKey = keyStakedTimeByAssetId(landAssetId)
10801165 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
11221207 let currentPack = getBackpack(bpKey)
11231208 let currentPackRes = split(currentPack[bpIdxRes], "_")
11241209 let currentWhRes = split(currentWh[whIdxRes], "_")
1125- let $t02561926490 = if ((claimMode == claimModeWh))
1210+ let $t02733528206 = if ((claimMode == claimModeWh))
11261211 then $Tuple4(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes], (parseIntValue(loft[volOccupied]) + resToClaim._2), (parseIntValue(loft[volFree]) - resToClaim._2))
11271212 else if ((claimMode == claimModeDuck))
11281213 then $Tuple4(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), parseIntValue(loft[volOccupied]), parseIntValue(loft[volFree]))
11311216 let whAm = min([parseIntValue(loft[volFree]), resToClaim._2])
11321217 $Tuple4(distr._1, distr._2, (parseIntValue(loft[volOccupied]) + whAm), (parseIntValue(loft[volFree]) - whAm))
11331218 }
1134- let whRes = $t02561926490._1
1135- let bpRes = $t02561926490._2
1136- let loftO = $t02561926490._3
1137- let loftF = $t02561926490._4
1219+ let whRes = $t02733528206._1
1220+ let bpRes = $t02733528206._2
1221+ let loftO = $t02733528206._3
1222+ let loftF = $t02733528206._4
11381223 $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxLevels], whRes, currentWh[whIdxMat], currentWh[whIdxProd], makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")])
11391224 }
11401225 }
15791664 @Callable(i)
15801665 func flight (message,sig) = {
15811666 let prologAction = prolog(i)
1582- if (!(sigVerify_8Kb(message, sig, pub)))
1583- then throw("signature does not match")
1584- else if ((size(i.payments) != 0))
1585- then throw("No payments required")
1586- else {
1587- let parts = split(toUtf8String(message), ";")
1588- let flightLog = split(parts[0], "|")
1589- let hp = split(flightLog[flHealth], "_")
1590- let curHP = parseIntValue(hp[0])
1591- let newHP = parseIntValue(hp[1])
1592- let newLocTxVer = split(parts[1], ":")
1593- let newLocation = newLocTxVer[0]
1594- let time = parseIntValue(flightLog[flTimestamp])
1595- if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
1596- then true
1597- else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
1598- then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
1599- else {
1600- let txFromMsg = newLocTxVer[1]
1601- let lastTx = valueOrElse(getString(keyLastTxIdByUser(toString(i.originCaller))), "")
1602- if ((lastTx != txFromMsg))
1603- then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
1604- else {
1605- let userAddr = toString(i.caller)
1606- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
1607- let keyHealth = keyDuckHealth(duckAssetId)
1608- let oldFromState = valueOrElse(getInteger(keyHealth), 100)
1609- if ((oldFromState != curHP))
1610- then throw(((("oldHealth=" + toString(valueOrElse(getInteger(keyHealth), 100))) + " from state does not match one from flight log=") + toString(curHP)))
1611- else if ((0 >= curHP))
1612- then throw("You can't fly with zero health")
1613- else {
1614- let locKey = keyDuckLocation(duckAssetId)
1615- let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
1616- if ((newLocation == curLocation))
1617- then throw("You can't fly to the same location")
1618- else {
1619- let bonus = if ((size(flightLog) > flBonus))
1620- then flightLog[flBonus]
1621- else ""
1622- let sentAmount = if (if ((newHP > 0))
1623- then (bonus == "$")
1624- else false)
1625- then asInt(invoke(restContract, "sendUsdtPrize", [userAddr], nil))
1626- else 0
1627- $Tuple2([StringEntry(locKey, if ((newHP > 0))
1628- then newLocation
1629- else curLocation), IntegerEntry(keyHealth, newHP), prologAction], sentAmount)
1630- }
1631- }
1632- }
1633- }
1634- }
1667+ if ((size(i.payments) != 0))
1668+ then throw("No payments required")
1669+ else {
1670+ let userAddr = toString(i.caller)
1671+ let f = flightCommon(userAddr, message, sig)
1672+ let locKey = keyDuckLocation(f._2)
1673+ let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
1674+ if ((f._4 == curLocation))
1675+ then throw("You can't fly to the same location")
1676+ else {
1677+ let bpKey = keyBackpackByDuck(f._2)
1678+ let currentPack = getBackpack(bpKey)
1679+ let newProd = subtractProducts(currentPack[bpIdxProd], f._5)
1680+ $Tuple2([StringEntry(locKey, if ((f._1 > 0))
1681+ then f._4
1682+ else curLocation), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProd], ":")), IntegerEntry(keyDuckHealth(f._2), f._1), prologAction], f._3)
1683+ }
1684+ }
16351685 }
16361686
16371687
17991849 if ((size(i.payments) != 0))
18001850 then throw("No payments required")
18011851 else {
1802- let result = expeditionCommon(true, i.caller, i.transactionId, message, sig)
1852+ let result = expeditionCommon(i.caller, i.transactionId, message, sig)
18031853 $Tuple2((result._1 :+ prologAction), $Tuple2(result._2, result._3))
18041854 }
18051855 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let chain = take(drop(this.bytes, 1), 1)
55
66 let usdtAssetId = match chain {
77 case _ =>
88 if ((base58'2W' == $match0))
99 then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
1010 else if ((base58'2T' == $match0))
1111 then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63'
1212 else throw("Unknown chain")
1313 }
1414
1515 let defaultRestAddressStr = match chain {
1616 case _ =>
1717 if ((base58'2W' == $match0))
1818 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
1919 else if ((base58'2T' == $match0))
2020 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
2121 else throw("Unknown chain")
2222 }
2323
2424 let InfraUpgradeCostS = match chain {
2525 case _ =>
2626 if ((base58'2W' == $match0))
2727 then 10000000000
2828 else if ((base58'2T' == $match0))
2929 then 100000000
3030 else throw("Unknown chain")
3131 }
3232
3333 let SEP = "__"
3434
3535 let MULT6 = 1000000
3636
3737 let MULT7 = 10000000
3838
3939 let MULT8 = 100000000
4040
4141 let MULT10 = 10000000000
4242
4343 let LANDPREFIX = "LAND"
4444
4545 let DUCKPREFIX = "DUCK"
4646
4747 let ARTPRESALE = "PRESALE"
4848
4949 let NUMRES = 6
5050
5151 let SSIZE = 25
5252
5353 let MSIZE = 100
5454
5555 let LSIZE = 225
5656
5757 let XLSIZE = 400
5858
5959 let XXLSIZE = 625
6060
6161 let DAILYRESBYPIECE = 3456000
6262
6363 let DAYMILLIS = 86400000
6464
6565 let WHMULTIPLIER = 10000000000
6666
6767 let DEFAULTLOCATION = "Africa_F_Africa"
6868
6969 let RESOURCEPRICEMIN = 39637
7070
7171 let ESMAXPACKAGES = 3
7272
7373 let ESBUYCOEF = 4
7474
7575 let ESSELLCOEF = 10
7676
7777 let MAXHP = 100
7878
7979 let resTypes = ["Oil", "Ore", "Wood", "Sand", "Clay", "Organic"]
8080
8181 let matTypes = ["Fuel", "Metal", "Plank", "Glass", "Plastic", "Protein"]
8282
8383 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"]
8484
8585 let continents = ["Americas", "Europe", "Asia", "Africa", "Oceania"]
8686
8787 let productionMatrix = ["1_1_1_2_2_5_1_10_0", "2_2_2_4_4_10_1_10_0", "3_3_3_6_6_15_1_10_0", "2_5_5_2_7_5_2_100_1", "4_10_10_4_14_10_2_100_1", "6_15_15_6_21_15_2_100_1", "1_1_1_1_1_8_1_10_2", "2_2_2_2_2_16_1_10_2", "3_3_3_3_3_24_1_10_2", "9_9_1_5_5_1_5_100_3", "18_18_2_10_10_2_5_100_3", "27_27_3_15_15_3_5_100_3", "2_2_1_2_2_2_1_10_4", "4_4_2_4_4_4_1_10_4", "6_6_3_6_6_6_1_10_4"]
8888
8989 let contIdxAmericas = 0
9090
9191 let contIdxEurope = 1
9292
9393 let contIdxAsia = 2
9494
9595 let contIdxAfrica = 3
9696
9797 let contIdxOceania = 4
9898
9999 let recipeIdxFuel = 0
100100
101101 let recipeIdxMetal = 1
102102
103103 let recipeIdxPlank = 2
104104
105105 let recipeIdxGlass = 3
106106
107107 let recipeIdxPlastic = 4
108108
109109 let recipeIdxProtein = 5
110110
111111 let recipeIdxWeight = 6
112112
113113 let recipeIdxPacksize = 7
114114
115115 let recipeIdxContinent = 8
116116
117117 let recLandNum = 0
118118
119119 let recLandSize = 1
120120
121121 let recTerrains = 2
122122
123123 let recContinent = 3
124124
125125 let whIdxLevels = 0
126126
127127 let whIdxRes = 1
128128
129129 let whIdxMat = 2
130130
131131 let whIdxProd = 3
132132
133133 let whIdxLOFT = 4
134134
135135 let volLocked = 0
136136
137137 let volOccupied = 1
138138
139139 let volFree = 2
140140
141141 let volTotal = 3
142142
143143 let bpIdxLevel = 0
144144
145145 let bpIdxRes = 1
146146
147147 let bpIdxMat = 2
148148
149149 let bpIdxProd = 3
150150
151151 func getPkgSize (prodIdx) = parseIntValue(split(productionMatrix[prodIdx], "_")[recipeIdxPacksize])
152152
153153
154154 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
155155
156156
157157 func getIntOrElse (key,defaultVal) = valueOrElse(getInteger(this, key), defaultVal)
158158
159159
160160 let IdxCfgStakingDapp = 1
161161
162162 let IdxCfgEconomyDapp = 2
163163
164164 let IdxCfgGovernanceDapp = 3
165165
166166 let IdxCfgWlgDapp = 4
167167
168168 func keyRestCfg () = "%s__restConfig"
169169
170170
171171 func keyRestAddress () = "%s__restAddr"
172172
173173
174174 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
175175
176176
177177 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
178178
179179
180180 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
181181
182182 let restCfg = readRestCfgOrFail(restContract)
183183
184184 let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
185185
186186 let economyContract = getContractAddressOrFail(restCfg, IdxCfgEconomyDapp)
187187
188188 let govContract = getContractAddressOrFail(restCfg, IdxCfgGovernanceDapp)
189189
190190 let wlgContract = getContractAddressOrFail(restCfg, IdxCfgWlgDapp)
191191
192192 func keyLastTxIdByUser (addr) = ("lastTxIdByUser_" + addr)
193193
194194
195195 func keyLandAssetIdToOwner (assetId) = ("nftOwner_" + assetId)
196196
197197
198198 func keyLandAssetIdToCustomName (assetId) = ("landCustomNameByAssetId_" + assetId)
199199
200200
201201 func keyStakedTimeByAssetId (assetId) = ("stakedTime_" + assetId)
202202
203203
204204 func keyInfraLevelByAssetId (assetId) = ("infraLevel_" + assetId)
205205
206206
207207 func keyLandArtStatusByTypeAndAssetId (type,assetId) = makeString(["landArtStatus", type, assetId], "_")
208208
209209
210210 func keyStakedTimeByTypeAssetIdAndOwner (nftType,assetId,ownerAddr) = ((((("stakedTimeByTypeAssetIdAndOwner_" + nftType) + "_") + assetId) + "_") + ownerAddr)
211211
212212
213213 func keyWarehouseByLand (landAssetId) = ("wareHouse_" + landAssetId)
214214
215215
216216 func keyStakedLandsByOwner (ownerAddr) = ("stakedLandsByOwner_" + ownerAddr)
217217
218218
219219 func keyStakedPiecesByOwner (ownerAddr) = ("stakedPiecesByOwner_" + ownerAddr)
220220
221221
222222 func keyDuckAssetIdToCustomName (assetId) = ("duckCustomNameByAssetId_" + assetId)
223223
224224
225225 func keyAddressToCustomName (addr) = ("accountCustomNameByAddr_" + addr)
226226
227227
228228 func keyAddressRefBy (addr) = ("accRefBy_" + addr)
229229
230230
231231 func keyAddressReferrals (addr) = ("accReferrals_" + addr)
232232
233233
234234 func keyDuckIdToOwner (assetId) = ("duckOwner_" + assetId)
235235
236236
237237 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
238238
239239
240240 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
241241
242242
243243 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
244244
245245
246246 func keyDuckHealth (duckAssetId) = ("duckHealth_" + duckAssetId)
247247
248248
249249 func keyResProportions () = "resTypesProportions"
250250
251251
252252 func keyBlocked () = "contractsBlocked"
253253
254254
255255 func keyUserGwlReleaseTime (userAddr) = ("%s%s__userGwlReleaseTime__" + userAddr)
256256
257257
258258 func keyOrderByLand (landAssetId) = ("landOrder_" + landAssetId)
259259
260260
261261 func keyEsWarehouse () = "emergencyWarehouseProducts"
262262
263263
264264 let locIdxContinent = 0
265265
266266 let locIdxType = 1
267267
268268 let locIdxId = 2
269269
270270 func asString (v) = match v {
271271 case s: String =>
272272 s
273273 case _ =>
274274 throw("fail to cast into String")
275275 }
276276
277277
278278 func asInt (v) = match v {
279279 case n: Int =>
280280 n
281281 case _ =>
282282 throw("fail to cast into Int")
283283 }
284284
285285
286286 func asAnyList (v) = match v {
287287 case l: List[Any] =>
288288 l
289289 case _ =>
290290 throw("fail to cast into List[Any]")
291291 }
292292
293293
294294 func asBoolean (v) = match v {
295295 case s: Boolean =>
296296 s
297297 case _ =>
298298 throw("fail to cast into Boolean")
299299 }
300300
301301
302302 func numPiecesBySize (landSize) = match landSize {
303303 case _ =>
304304 if (("S" == $match0))
305305 then SSIZE
306306 else if (("M" == $match0))
307307 then MSIZE
308308 else if (("L" == $match0))
309309 then LSIZE
310310 else if (("XL" == $match0))
311311 then XLSIZE
312312 else if (("XXL" == $match0))
313313 then XXLSIZE
314314 else throw("Unknown land size")
315315 }
316316
317317
318318 let IdxEffTotal = 0
319319
320320 let IdxEffUser = 1
321321
322322 func getVotingPower (userAddrStrOrEmpty) = {
323323 let props = split(valueOrElse(getString(stakingContract, keyResProportions()), "0_0_0_0_0_0"), "_")
324324 func adder (acc,item) = (acc + parseIntValue(item))
325325
326326 let totalPower = {
327327 let $l = props
328328 let $s = size($l)
329329 let $acc0 = 0
330330 func $f0_1 ($a,$i) = if (($i >= $s))
331331 then $a
332332 else adder($a, $l[$i])
333333
334334 func $f0_2 ($a,$i) = if (($i >= $s))
335335 then $a
336336 else throw("List size exceeds 6")
337337
338338 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
339339 }
340340 let usersPower = if ((userAddrStrOrEmpty == ""))
341341 then 0
342342 else {
343343 let landsStr = getString(stakingContract, keyStakedLandsByOwner(userAddrStrOrEmpty))
344344 let lands = if (isDefined(landsStr))
345345 then split_51C(value(landsStr), "_")
346346 else nil
347347 func oneLand (acc,landAssetId) = {
348348 let asset = value(assetInfo(fromBase58String(landAssetId)))
349349 let landSize = split(asset.description, "_")[recLandSize]
350350 (acc + numPiecesBySize(landSize))
351351 }
352352
353353 let $l = lands
354354 let $s = size($l)
355355 let $acc0 = 0
356356 func $f1_1 ($a,$i) = if (($i >= $s))
357357 then $a
358358 else oneLand($a, $l[$i])
359359
360360 func $f1_2 ($a,$i) = if (($i >= $s))
361361 then $a
362362 else throw("List size exceeds 100")
363363
364364 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_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), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100)
365365 }
366366 [totalPower, usersPower]
367367 }
368368
369369
370370 func getRecipeMaterials (recipe) = {
371371 func addMat (ac,j) = (ac + parseIntValue(recipe[j]))
372372
373373 let $l = [0, 1, 2, 3, 4, 5]
374374 let $s = size($l)
375375 let $acc0 = 0
376376 func $f0_1 ($a,$i) = if (($i >= $s))
377377 then $a
378378 else addMat($a, $l[$i])
379379
380380 func $f0_2 ($a,$i) = if (($i >= $s))
381381 then $a
382382 else throw("List size exceeds 6")
383383
384384 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
385385 }
386386
387387
388388 let incubatorAddr = match chain {
389389 case _ =>
390390 if ((base58'2W' == $match0))
391391 then addressFromStringValue("3PEktVux2RhchSN63DsDo4b4mz4QqzKSeDv")
392392 else if ((base58'2T' == $match0))
393393 then this
394394 else throw("Unknown chain")
395395 }
396396
397397 let breederAddr = match chain {
398398 case _ =>
399399 if ((base58'2W' == $match0))
400400 then addressFromStringValue("3PDVuU45H7Eh5dmtNbnRNRStGwULA7NY6Hb")
401401 else if ((base58'2T' == $match0))
402402 then this
403403 else throw("Unknown chain")
404404 }
405405
406406 let pub = base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
407407
408408 let medKitHp = [30, 60, 120]
409409
410410 let FIVEMINUTESMILLIS = 300000
411411
412412 let RENAMINGCOST = 5000000
413413
414414 let MAXNAMELEN = 50
415415
416416 let InfraUpgradeCostSUsdt = 10000000
417417
418418 let EXPMATERIALS = match chain {
419419 case _ =>
420420 if ((base58'2W' == $match0))
421421 then 252289527462
422422 else if ((base58'2T' == $match0))
423423 then 2522895274
424424 else throw("Unknown chain")
425425 }
426426
427427 let EXPUSDT = match chain {
428428 case _ =>
429429 if ((base58'2W' == $match0))
430430 then 250000000
431431 else if ((base58'2T' == $match0))
432432 then 250000000
433433 else throw("Unknown chain")
434434 }
435435
436436 let FIVEX = toBigInt(5)
437437
438438 let TWENTYX = toBigInt(20)
439439
440440 let TWENTY2X = toBigInt((20 * 20))
441441
442442 let TWENTY3X = toBigInt(((20 * 20) * 20))
443443
444444 let TWENTY4X = toBigInt((((20 * 20) * 20) * 20))
445445
446446 let TWENTY5X = toBigInt(((((20 * 20) * 20) * 20) * 20))
447447
448448 let PRESALENUMLANDS = 500
449449
450450 func keyNextFreeLandNum () = "nextLandNum"
451451
452452
453453 func keyLandToAssetId (landNum) = ("landToAsset_" + landNum)
454454
455455
456456 func keyLandCustomNameToAssetId (name) = ("landByCustomName_" + name)
457457
458458
459459 func keyInfraLevelByAssetIdAndOwner (assetId,ownerAddr) = ((("infraLevelByAssetIdAndOwner_" + assetId) + "_") + ownerAddr)
460460
461461
462462 func keyLandArtStatusByTypeAssetIdAndOwner (type,assetId,ownerAddr) = makeString(["landArtStatusByTypeAssetIdAndOwner", type, assetId, ownerAddr], "_")
463463
464464
465465 func keyLandNumToOwner (landNum) = ("landOwner_" + landNum)
466466
467467
468468 func keyDuckCustomNameToAssetId (name) = ("duckByCustomName_" + name)
469469
470470
471471 func keyCustomNameToAddress (name) = ("accountByCustomName_" + name)
472472
473473
474474 func keyOldies () = "oldiesList"
475475
476476
477477 let claimModeWh = 0
478478
479479 let claimModeDuck = 1
480480
481481 let claimModeWhThenDuck = 2
482482
483483 let flHealth = 0
484484
485485 let flMission = 1
486486
487487 let flObstacles = 2
488488
489489 let flWinds = 3
490490
491491 let flPath = 4
492492
493493 let flTimestamp = 5
494494
495495 let flBonus = 6
496496
497+let flProdsUsed = 7
498+
497499 func nftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
498500
499501
500502 func distributeByWeights (total,weights) = {
501503 let sum = (((((weights[0] + weights[1]) + weights[2]) + weights[3]) + weights[4]) + weights[5])
502504 if ((0 >= sum))
503505 then throw("Zero weights sum")
504506 else {
505507 let norm6 = fraction(total, MULT6, sum)
506508 func normalizer (acc,elem) = (acc :+ fraction(elem, norm6, MULT6))
507509
508510 let $l = weights
509511 let $s = size($l)
510512 let $acc0 = nil
511513 func $f0_1 ($a,$i) = if (($i >= $s))
512514 then $a
513515 else normalizer($a, $l[$i])
514516
515517 func $f0_2 ($a,$i) = if (($i >= $s))
516518 then $a
517519 else throw("List size exceeds 6")
518520
519521 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
520522 }
521523 }
522524
523525
524526 func getNeededMaterials (total) = {
525527 let props = split(value(getString(keyResProportions())), "_")
526528 if ((size(props) != NUMRES))
527529 then throw("Wrong proportions data")
528530 else {
529531 let r = [parseIntValue(props[0]), parseIntValue(props[1]), parseIntValue(props[2]), parseIntValue(props[3]), parseIntValue(props[4]), parseIntValue(props[5])]
530532 distributeByWeights(total, r)
531533 }
532534 }
533535
534536
535537 func subtractMaterials (shouldUseMat,has,totalNeed) = {
536538 let need = getNeededMaterials(totalNeed)
537539 func subtractor (acc,idx) = {
538540 let result = (parseIntValue(has[idx]) - need[idx])
539541 if ((0 > result))
540542 then throw(((((("Not enough material idx=" + toString(idx)) + ", you have ") + has[idx]) + ", but need ") + toString(need[idx])))
541543 else (acc :+ toString(result))
542544 }
543545
544546 if (shouldUseMat)
545547 then {
546548 let $l = [0, 1, 2, 3, 4, 5]
547549 let $s = size($l)
548550 let $acc0 = nil
549551 func $f0_1 ($a,$i) = if (($i >= $s))
550552 then $a
551553 else subtractor($a, $l[$i])
552554
553555 func $f0_2 ($a,$i) = if (($i >= $s))
554556 then $a
555557 else throw("List size exceeds 6")
556558
557559 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
558560 }
559561 else has
560562 }
563+
564+
565+func subtractProducts (pHas,pUsed) = if ((pUsed == ""))
566+ then pHas
567+ else {
568+ let pList = if ((pHas == ""))
569+ then nil
570+ else split(pHas, "_")
571+ func subP (acc,item) = {
572+ let j = acc._1
573+ func checkUsed (ac,idxAmt) = {
574+ let parts = split(idxAmt, ",")
575+ if ((size(parts) != 2))
576+ then throw("Incorrect format, should be index,amount")
577+ else {
578+ let idx = parseIntValue(parts[0])
579+ if (if ((0 > idx))
580+ then true
581+ else (idx >= size(productionMatrix)))
582+ then throw("Unknown product idx")
583+ else if ((idx != j))
584+ then ac
585+ else {
586+ let amt = parseIntValue(parts[1])
587+ if ((0 >= amt))
588+ then throw("Pass only positive amounts")
589+ else (ac + amt)
590+ }
591+ }
592+ }
593+
594+ let a = {
595+ let $l = split(pUsed, "_")
596+ let $s = size($l)
597+ let $acc0 = 0
598+ func $f0_1 ($a,$i) = if (($i >= $s))
599+ then $a
600+ else checkUsed($a, $l[$i])
601+
602+ func $f0_2 ($a,$i) = if (($i >= $s))
603+ then $a
604+ else throw("List size exceeds 10")
605+
606+ $f0_2($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)
607+ }
608+ let curr = if ((size(pList) > j))
609+ then parseIntValue(pList[j])
610+ else 0
611+ let newAmt = if ((a > curr))
612+ then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[j]) + ", but tried to use ") + toString(a)))
613+ else (curr - a)
614+ $Tuple2((j + 1), (acc._2 :+ toString(newAmt)))
615+ }
616+
617+ let newProd = {
618+ let $l = productionMatrix
619+ let $s = size($l)
620+ let $acc0 = $Tuple2(0, nil)
621+ func $f0_1 ($a,$i) = if (($i >= $s))
622+ then $a
623+ else subP($a, $l[$i])
624+
625+ func $f0_2 ($a,$i) = if (($i >= $s))
626+ then $a
627+ else throw("List size exceeds 50")
628+
629+ $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)
630+ }
631+ makeString(newProd._2, "_")
632+ }
561633
562634
563635 func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
564636 then throw("Wrong proportions data")
565637 else {
566638 func updater (acc,i) = {
567639 let result = (parseIntValue(propList[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
568640 if ((0 > result))
569641 then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
570642 else (acc :+ toString(result))
571643 }
572644
573645 let r = {
574646 let $l = [0, 1, 2, 3, 4, 5]
575647 let $s = size($l)
576648 let $acc0 = nil
577649 func $f0_1 ($a,$i) = if (($i >= $s))
578650 then $a
579651 else updater($a, $l[$i])
580652
581653 func $f0_2 ($a,$i) = if (($i >= $s))
582654 then $a
583655 else throw("List size exceeds 6")
584656
585657 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
586658 }
587659 makeString(r, "_")
588660 }
589661
590662
591663 func updateProportions (terrainCounts,landSizeIndex,sign) = {
592664 let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
593665 updateProportionsInternal(propList, terrainCounts, landSizeIndex, sign)
594666 }
595667
596668
597669 func countTerrains (terrains) = [(size(split(terrains, "A")) - 1), (size(split(terrains, "B")) - 1), (size(split(terrains, "C")) - 1), (size(split(terrains, "D")) - 1), (size(split(terrains, "E")) - 1), (size(split(terrains, "F")) - 1)]
598670
599671
600672 func addRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
601673 func adder (acc,i) = {
602674 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
603675 (acc :+ toString((parseIntValue(currentRes[i]) + resOfType)))
604676 }
605677
606678 let r = {
607679 let $l = [0, 1, 2, 3, 4, 5]
608680 let $s = size($l)
609681 let $acc0 = nil
610682 func $f0_1 ($a,$i) = if (($i >= $s))
611683 then $a
612684 else adder($a, $l[$i])
613685
614686 func $f0_2 ($a,$i) = if (($i >= $s))
615687 then $a
616688 else throw("List size exceeds 6")
617689
618690 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
619691 }
620692 makeString(r, "_")
621693 }
622694
623695
624696 func virtClaim (terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
625697 func adder (acc,i) = {
626698 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
627699 $Tuple2((acc._1 :+ resOfType), (acc._2 + resOfType))
628700 }
629701
630702 let $l = [0, 1, 2, 3, 4, 5]
631703 let $s = size($l)
632704 let $acc0 = $Tuple2(nil, 0)
633705 func $f0_1 ($a,$i) = if (($i >= $s))
634706 then $a
635707 else adder($a, $l[$i])
636708
637709 func $f0_2 ($a,$i) = if (($i >= $s))
638710 then $a
639711 else throw("List size exceeds 6")
640712
641713 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
642714 }
643715
644716
645717 func distributeRes (currentWhRes,currentPackRes,resToClaim,whSpaceLeft) = {
646718 let resListToClaim = resToClaim._1
647719 let resAmToClaim = resToClaim._2
648720 if ((resAmToClaim == 0))
649721 then $Tuple2(makeString(currentWhRes, "_"), makeString(currentPackRes, "_"))
650722 else if ((whSpaceLeft >= resAmToClaim))
651723 then {
652724 func addLists (acc,i) = (acc :+ toString((parseIntValue(currentWhRes[i]) + resListToClaim[i])))
653725
654726 let r = {
655727 let $l = [0, 1, 2, 3, 4, 5]
656728 let $s = size($l)
657729 let $acc0 = nil
658730 func $f0_1 ($a,$i) = if (($i >= $s))
659731 then $a
660732 else addLists($a, $l[$i])
661733
662734 func $f0_2 ($a,$i) = if (($i >= $s))
663735 then $a
664736 else throw("List size exceeds 6")
665737
666738 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
667739 }
668740 $Tuple2(makeString(r, "_"), makeString(currentPackRes, "_"))
669741 }
670742 else {
671743 func addPartLists (acc,i) = {
672744 let whPart = fraction(resListToClaim[i], whSpaceLeft, resAmToClaim)
673745 $Tuple2((acc._1 :+ toString((parseIntValue(currentWhRes[i]) + whPart))), (acc._2 :+ toString(((parseIntValue(currentPackRes[i]) + resListToClaim[i]) - whPart))))
674746 }
675747
676748 let r = {
677749 let $l = [0, 1, 2, 3, 4, 5]
678750 let $s = size($l)
679751 let $acc0 = $Tuple2(nil, nil)
680752 func $f0_1 ($a,$i) = if (($i >= $s))
681753 then $a
682754 else addPartLists($a, $l[$i])
683755
684756 func $f0_2 ($a,$i) = if (($i >= $s))
685757 then $a
686758 else throw("List size exceeds 6")
687759
688760 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
689761 }
690762 $Tuple2(makeString(r._1, "_"), makeString(r._2, "_"))
691763 }
692764 }
693765
694766
695767 func abs (x) = if ((x >= toBigInt(0)))
696768 then x
697769 else -(x)
698770
699771
700772 let freq = [[6, 9, 14, 15, 16], [5, 8, 13, 14, 15], [1, 4, 9, 10, 15], [1, 6, 7, 15, 19], [4, 7, 8, 13, 18]]
701773
702774 func genChar (n,freqs) = {
703775 let rem = toInt((n % TWENTYX))
704776 let letter = if ((freqs[0] > rem))
705777 then "A"
706778 else if ((freqs[1] > rem))
707779 then "B"
708780 else if ((freqs[2] > rem))
709781 then "C"
710782 else if ((freqs[3] > rem))
711783 then "D"
712784 else if ((freqs[4] > rem))
713785 then "E"
714786 else "F"
715787 letter
716788 }
717789
718790
719791 func genTerrains (seed,continentIdx) = {
720792 let f = freq[continentIdx]
721793 func terrainGenerator (acc,elem) = $Tuple2((((((acc._1 + genChar(acc._2, f)) + genChar((acc._2 / TWENTYX), f)) + genChar((acc._2 / TWENTY2X), f)) + genChar((acc._2 / TWENTY3X), f)) + genChar((acc._2 / TWENTY4X), f)), (acc._2 / TWENTY5X))
722794
723795 let t = {
724796 let $l = [1, 2, 3, 4, 5]
725797 let $s = size($l)
726798 let $acc0 = $Tuple2("", (seed / FIVEX))
727799 func $f0_1 ($a,$i) = if (($i >= $s))
728800 then $a
729801 else terrainGenerator($a, $l[$i])
730802
731803 func $f0_2 ($a,$i) = if (($i >= $s))
732804 then $a
733805 else throw("List size exceeds 5")
734806
735807 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
736808 }
737809 t._1
738810 }
739811
740812
741813 func getBackpack (bpKey) = {
742814 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
743815 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
744816 then p[bpIdxRes]
745817 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
746818 then p[bpIdxMat]
747819 else "0_0_0_0_0_0", p[bpIdxProd]]
748820 }
749821
750822
751823 func getWarehouseTotalVolume (volPrefix) = {
752824 let parts = split(volPrefix, "_")
753825 ((WHMULTIPLIER * (parseIntValue(parts[1]) + 1)) * parseIntValue(parts[0]))
754826 }
755827
756828
757829 func getWarehouseOccupiedVol (currentWh) = {
758830 let goods = currentWh[whIdxProd]
759831 func sumResMat (acc,item) = (acc + parseIntValue(item))
760832
761833 func sumProd (acc,item) = {
762834 let idx = acc._1
763835 let pkgSize = getPkgSize(idx)
764836 let pkgs = (((parseIntValue(item) + pkgSize) - 1) / pkgSize)
765837 $Tuple2((idx + 1), (acc._2 + (pkgs * MULT8)))
766838 }
767839
768840 let whResVol = {
769841 let $l = split(currentWh[whIdxRes], "_")
770842 let $s = size($l)
771843 let $acc0 = 0
772844 func $f0_1 ($a,$i) = if (($i >= $s))
773845 then $a
774846 else sumResMat($a, $l[$i])
775847
776848 func $f0_2 ($a,$i) = if (($i >= $s))
777849 then $a
778850 else throw("List size exceeds 6")
779851
780852 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
781853 }
782854 let whMatVol = {
783855 let $l = split(currentWh[whIdxMat], "_")
784856 let $s = size($l)
785857 let $acc0 = 0
786858 func $f1_1 ($a,$i) = if (($i >= $s))
787859 then $a
788860 else sumResMat($a, $l[$i])
789861
790862 func $f1_2 ($a,$i) = if (($i >= $s))
791863 then $a
792864 else throw("List size exceeds 6")
793865
794866 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
795867 }
796868 let whGoodsVol = if ((goods == ""))
797869 then 0
798870 else ( let $l = split_4C(goods, "_")
799871 let $s = size($l)
800872 let $acc0 = $Tuple2(0, 0)
801873 func $f2_1 ($a,$i) = if (($i >= $s))
802874 then $a
803875 else sumProd($a, $l[$i])
804876
805877 func $f2_2 ($a,$i) = if (($i >= $s))
806878 then $a
807879 else throw("List size exceeds 50")
808880
809881 $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))._2
810882 ((whResVol + whMatVol) + whGoodsVol)
811883 }
812884
813885
814886 func getWarehouse (whKey,landIndex,infraLevel) = {
815887 let volPrefix = ((toString(landIndex) + "_") + toString(infraLevel))
816888 let whTotal = getWarehouseTotalVolume(volPrefix)
817889 let whStr = valueOrElse(getString(whKey), (volPrefix + ":0_0_0_0_0_0:0_0_0_0_0_0::0"))
818890 let wh = split_4C(whStr, ":")
819891 let whOccupied = getWarehouseOccupiedVol(wh)
820892 let whLoft = if ((5 > size(wh)))
821893 then makeString(["0", toString(whOccupied), toString((whTotal - whOccupied)), toString(whTotal)], "_")
822894 else {
823895 let loft = split(wh[whIdxLOFT], "_")
824896 let whLocked = parseIntValue(loft[volLocked])
825897 let occ = if ((size(loft) > 1))
826898 then parseIntValue(loft[volOccupied])
827899 else whOccupied
828900 makeString([toString(whLocked), toString(occ), toString(((whTotal - whLocked) - occ)), toString(whTotal)], "_")
829901 }
830902 [wh[whIdxLevels], if ((size(split(wh[whIdxRes], "_")) == NUMRES))
831903 then wh[whIdxRes]
832904 else "0_0_0_0_0_0", if ((size(split(wh[whIdxMat], "_")) == NUMRES))
833905 then wh[whIdxMat]
834906 else "0_0_0_0_0_0", wh[whIdxProd], whLoft]
835907 }
836908
837909
838910 func getWarehouseSpaceLeft (currentWh) = {
839911 let occupiedVol = getWarehouseOccupiedVol(currentWh)
840912 let currWhLockedVol = parseIntValue(split(currentWh[whIdxLOFT], "_")[volLocked])
841913 ((getWarehouseTotalVolume(currentWh[whIdxLevels]) - occupiedVol) - currWhLockedVol)
842914 }
843915
844916
845917 func toVolume (amount,pkgSize) = {
846918 let pkgs = if ((amount >= 0))
847919 then (((amount + pkgSize) - 1) / pkgSize)
848920 else -((((-(amount) + pkgSize) - 1) / pkgSize))
849921 (pkgs * MULT8)
850922 }
851923
852924
853925 func moveStuff (cargoParts,currentWh,currentPack) = if ((size(cargoParts) != 3))
854926 then throw("cargoListStr should contain exactly 2 ':' separators")
855927 else {
856928 let resParts = split(cargoParts[0], "_")
857929 let matParts = split(cargoParts[1], "_")
858930 let prodParts = if ((cargoParts[2] == ""))
859931 then nil
860932 else split(cargoParts[2], "_")
861933 if ((size(resParts) != NUMRES))
862934 then throw("All 6 resources should be passed")
863935 else if ((size(matParts) != NUMRES))
864936 then throw("All 6 materials should be passed")
865937 else {
866938 let whSpaceLeft = getWarehouseSpaceLeft(currentWh)
867939 let currWhRes = split(currentWh[whIdxRes], "_")
868940 let currWhMat = split(currentWh[whIdxMat], "_")
869941 let currWhProd = if ((currentWh[whIdxProd] == ""))
870942 then nil
871943 else split(currentWh[whIdxProd], "_")
872944 let currentPackRes = split(currentPack[bpIdxRes], "_")
873945 let currentPackMat = split(currentPack[bpIdxMat], "_")
874946 let currentPackProd = if ((currentPack[bpIdxProd] == ""))
875947 then nil
876948 else split(currentPack[bpIdxProd], "_")
877949 func mvR (acc,item) = {
878950 let i = acc._1
879951 let am = parseIntValue(item)
880952 let whr = parseIntValue(currWhRes[i])
881953 let bpr = parseIntValue(currentPackRes[i])
882954 if ((am == 0))
883955 then $Tuple4((i + 1), (acc._2 :+ currWhRes[i]), (acc._3 :+ currentPackRes[i]), acc._4)
884956 else if ((am > 0))
885957 then if ((am > bpr))
886958 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpr)) + " available"))
887959 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
888960 else if ((-(am) > whr))
889961 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whr)) + " available"))
890962 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
891963 }
892964
893965 let r = {
894966 let $l = resParts
895967 let $s = size($l)
896968 let $acc0 = $Tuple4(0, nil, nil, 0)
897969 func $f0_1 ($a,$i) = if (($i >= $s))
898970 then $a
899971 else mvR($a, $l[$i])
900972
901973 func $f0_2 ($a,$i) = if (($i >= $s))
902974 then $a
903975 else throw("List size exceeds 6")
904976
905977 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
906978 }
907979 func mvM (acc,item) = {
908980 let i = acc._1
909981 let am = parseIntValue(item)
910982 let whm = parseIntValue(currWhMat[i])
911983 let bpm = parseIntValue(currentPackMat[i])
912984 if ((am == 0))
913985 then $Tuple4((i + 1), (acc._2 :+ currWhMat[i]), (acc._3 :+ currentPackMat[i]), acc._4)
914986 else if ((am > 0))
915987 then if ((am > bpm))
916988 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpm)) + " available"))
917989 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
918990 else if ((-(am) > whm))
919991 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whm)) + " available"))
920992 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
921993 }
922994
923995 let m = {
924996 let $l = matParts
925997 let $s = size($l)
926998 let $acc0 = $Tuple4(0, nil, nil, r._4)
927999 func $f1_1 ($a,$i) = if (($i >= $s))
9281000 then $a
9291001 else mvM($a, $l[$i])
9301002
9311003 func $f1_2 ($a,$i) = if (($i >= $s))
9321004 then $a
9331005 else throw("List size exceeds 6")
9341006
9351007 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
9361008 }
9371009 func mvP (acc,item) = {
9381010 let i = acc._1
9391011 let pkgSize = getPkgSize(i)
9401012 let am = parseIntValue(item)
9411013 let whp = if ((size(currWhProd) > i))
9421014 then parseIntValue(currWhProd[i])
9431015 else 0
9441016 let bpp = if ((size(currentPackProd) > i))
9451017 then parseIntValue(currentPackProd[i])
9461018 else 0
9471019 if ((am == 0))
9481020 then $Tuple4((i + 1), (acc._2 :+ toString(whp)), (acc._3 :+ toString(bpp)), acc._4)
9491021 else if ((am > 0))
9501022 then if ((am > bpp))
9511023 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpp)) + " available"))
9521024 else {
9531025 let deltaVol = (toVolume((whp + am), pkgSize) - toVolume(whp, pkgSize))
9541026 $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
9551027 }
9561028 else if ((-(am) > whp))
9571029 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whp)) + " available"))
9581030 else {
9591031 let deltaVol = (toVolume((whp + am), pkgSize) - toVolume(whp, pkgSize))
9601032 $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
9611033 }
9621034 }
9631035
9641036 let p = if ((size(prodParts) != 0))
9651037 then {
9661038 let $l = prodParts
9671039 let $s = size($l)
9681040 let $acc0 = $Tuple4(0, nil, nil, m._4)
9691041 func $f2_1 ($a,$i) = if (($i >= $s))
9701042 then $a
9711043 else mvP($a, $l[$i])
9721044
9731045 func $f2_2 ($a,$i) = if (($i >= $s))
9741046 then $a
9751047 else throw("List size exceeds 50")
9761048
9771049 $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)
9781050 }
9791051 else $Tuple4(0, currWhProd, currentPackProd, m._4)
9801052 let volSaldo = p._4
9811053 if ((volSaldo > whSpaceLeft))
9821054 then throw((((("Attempt to put total " + toString(volSaldo)) + " stuff, but only ") + toString(whSpaceLeft)) + " warehouse space left"))
9831055 else $Tuple7(makeString(r._2, "_"), makeString(m._2, "_"), makeString(p._2, "_"), makeString(r._3, "_"), makeString(m._3, "_"), makeString(p._3, "_"), volSaldo)
9841056 }
9851057 }
9861058
9871059
9881060 func expeditionInternal (caller,txId) = {
9891061 let userAddr = toString(caller)
9901062 let bigNum = abs(toBigInt(txId))
9911063 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
9921064 let landNum = toString(freeNum)
9931065 let continentIdx = toInt((bigNum % FIVEX))
9941066 let terrains = genTerrains(bigNum, continentIdx)
9951067 let continent = continents[continentIdx]
9961068 let issue = Issue(nftName(landNum, "S"), makeString([landNum, "S", terrains, continent], "_"), 1, 0, false)
9971069 let assetId = calculateAssetId(issue)
9981070 let id = toBase58String(assetId)
9991071 $Tuple2([IntegerEntry(keyNextFreeLandNum(), (freeNum + 1)), issue, StringEntry(keyLandToAssetId(landNum), id), StringEntry(keyLandAssetIdToOwner(id), userAddr), StringEntry(keyLandNumToOwner(landNum), userAddr), IntegerEntry(keyInfraLevelByAssetId(id), 0), IntegerEntry(keyInfraLevelByAssetIdAndOwner(id, userAddr), 0), ScriptTransfer(caller, 1, assetId)], $Tuple2(id, continent))
10001072 }
10011073
10021074
1003-func expeditionCommon (shouldUseMat,caller,txId,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
1075+func flightCommon (userAddr,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
10041076 then throw("signature does not match")
10051077 else {
10061078 let parts = split(toUtf8String(message), ";")
10071079 let flightLog = split(parts[0], "|")
10081080 let hp = split(flightLog[flHealth], "_")
10091081 let curHP = parseIntValue(hp[0])
10101082 let newHP = parseIntValue(hp[1])
10111083 let newLocTxVer = split(parts[1], ":")
10121084 let newLocation = newLocTxVer[0]
10131085 let time = parseIntValue(flightLog[flTimestamp])
10141086 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
10151087 then true
10161088 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
1017- then throw("signature outdated")
1089+ then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
10181090 else {
10191091 let txFromMsg = newLocTxVer[1]
1020- let userAddr = toString(caller)
10211092 let lastTx = valueOrElse(getString(keyLastTxIdByUser(userAddr)), "")
10221093 if ((lastTx != txFromMsg))
10231094 then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
10241095 else {
10251096 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
10261097 let keyHealth = keyDuckHealth(duckAssetId)
10271098 let oldFromState = valueOrElse(getInteger(keyHealth), 100)
10281099 if ((oldFromState != curHP))
10291100 then throw(((("oldHealth=" + toString(valueOrElse(getInteger(keyHealth), 100))) + " from state does not match one from flight log=") + toString(curHP)))
10301101 else if ((0 >= curHP))
10311102 then throw("You can't fly with zero health")
1032- else if ((0 >= newHP))
1033- then $Tuple3(((if (!(shouldUseMat))
1034- then [ScriptTransfer(caller, EXPUSDT, usdtAssetId)]
1035- else nil) :+ IntegerEntry(keyHealth, 0)), "", 0)
1036- else {
1037- let bonus = if ((size(flightLog) > flBonus))
1038- then flightLog[flBonus]
1039- else ""
1040- let sentAmount = if ((bonus == "$"))
1041- then asInt(invoke(restContract, "sendUsdtPrize", [userAddr], nil))
1042- else 0
1043- let bpKey = keyBackpackByDuck(duckAssetId)
1044- let currentPack = getBackpack(bpKey)
1045- let mList = split(currentPack[bpIdxMat], "_")
1046- let newMat = makeString(subtractMaterials(shouldUseMat, mList, EXPMATERIALS), "_")
1047- let e = expeditionInternal(caller, txId)
1048- let id = e._2._1
1049- $Tuple3((((e._1 :+ StringEntry(keyDuckLocation(duckAssetId), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, newHP)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))), id, sentAmount)
1050- }
1103+ else {
1104+ let bonus = if ((size(flightLog) > flBonus))
1105+ then flightLog[flBonus]
1106+ else ""
1107+ let prodUsed = if ((size(flightLog) > flProdsUsed))
1108+ then flightLog[flProdsUsed]
1109+ else ""
1110+ let sentAmount = if (if ((newHP > 0))
1111+ then (bonus == "$")
1112+ else false)
1113+ then asInt(invoke(restContract, "sendUsdtPrize", [userAddr], nil))
1114+ else 0
1115+ $Tuple5(newHP, duckAssetId, sentAmount, newLocation, prodUsed)
1116+ }
10511117 }
10521118 }
10531119 }
1120+
1121+
1122+func expeditionCommon (caller,txId,message,sig) = {
1123+ let userAddr = toString(caller)
1124+ let f = flightCommon(userAddr, message, sig)
1125+ let keyHealth = keyDuckHealth(f._2)
1126+ let bpKey = keyBackpackByDuck(f._2)
1127+ let currentPack = getBackpack(bpKey)
1128+ let mList = split(currentPack[bpIdxMat], "_")
1129+ let newMat = makeString(subtractMaterials(true, mList, EXPMATERIALS), "_")
1130+ let newProd = subtractProducts(currentPack[bpIdxProd], f._5)
1131+ if ((0 >= f._1))
1132+ then $Tuple3([IntegerEntry(keyHealth, 0), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProd], ":"))], "", 0)
1133+ else {
1134+ let e = expeditionInternal(caller, txId)
1135+ let id = e._2._1
1136+ $Tuple3((((e._1 :+ StringEntry(keyDuckLocation(f._2), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, f._1)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, newProd], ":"))), id, f._3)
1137+ }
1138+ }
10541139
10551140
10561141 func applyBonuses (landAssetId,pieces) = {
10571142 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
10581143 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
10591144 let add6 = (infraLevel / 6)
10601145 let add7 = (infraLevel / 7)
10611146 ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, ((infraLevel + add6) + (2 * add7)), 5)) + fraction(DAILYRESBYPIECE, artPieces, (pieces * 5)))
10621147 }
10631148
10641149
10651150 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
1066- let $t02270623245 = if ((claimMode == claimModeWh))
1151+ let $t02442224961 = if ((claimMode == claimModeWh))
10671152 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
10681153 else {
10691154 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
10701155 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
10711156 let loc = split(value(curLocation), "_")
10721157 if ((loc[locIdxType] != "L"))
10731158 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
10741159 else $Tuple2(loc[locIdxId], duckAssetId)
10751160 }
1076- let landAssetId = $t02270623245._1
1077- let duckId = $t02270623245._2
1161+ let landAssetId = $t02442224961._1
1162+ let duckId = $t02442224961._2
10781163 let asset = value(assetInfo(fromBase58String(landAssetId)))
10791164 let timeKey = keyStakedTimeByAssetId(landAssetId)
10801165 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
10811166 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
10821167 if ((owner != addr))
10831168 then throw((LANDPREFIX + " is not yours"))
10841169 else {
10851170 let d = split(asset.description, "_")
10861171 $Tuple4(duckId, landAssetId, d, savedTime)
10871172 }
10881173 }
10891174
10901175
10911176 func claimResInternal (addr,amount,claimMode,landAssetIdIn) = if ((0 > amount))
10921177 then throw("Negative amount")
10931178 else {
10941179 let c = checkClaimConditions(addr, claimMode, landAssetIdIn)
10951180 let landSize = c._3[recLandSize]
10961181 let terrainCounts = countTerrains(c._3[recTerrains])
10971182 let deltaTime = (lastBlock.timestamp - c._4)
10981183 if ((0 > deltaTime))
10991184 then throw(((("Saved timestamp is in future, saved = " + toString(c._4)) + ", current = ") + toString(lastBlock.timestamp)))
11001185 else {
11011186 let pieces = numPiecesBySize(landSize)
11021187 let dailyProductionByPiece = applyBonuses(c._2, pieces)
11031188 let availRes = fraction(deltaTime, (dailyProductionByPiece * pieces), DAYMILLIS)
11041189 if ((amount > availRes))
11051190 then throw(((("Not enough resources, available = " + toString(availRes)) + ", requested = ") + toString(amount)))
11061191 else {
11071192 let newDeltaTime = fraction((availRes - amount), DAYMILLIS, (dailyProductionByPiece * pieces))
11081193 let newTimestamp = (lastBlock.timestamp - newDeltaTime)
11091194 let landIndex = (pieces / SSIZE)
11101195 let resToClaim = virtClaim(terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece)
11111196 let whKey = keyWarehouseByLand(c._2)
11121197 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(c._2)), 0)
11131198 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
11141199 let loft = split(currentWh[whIdxLOFT], "_")
11151200 let whSpaceLeft = parseIntValue(loft[volFree])
11161201 if (if ((claimMode == claimModeWh))
11171202 then (amount > whSpaceLeft)
11181203 else false)
11191204 then throw((("Only " + toString(whSpaceLeft)) + " space left in warehouse"))
11201205 else {
11211206 let bpKey = keyBackpackByDuck(c._1)
11221207 let currentPack = getBackpack(bpKey)
11231208 let currentPackRes = split(currentPack[bpIdxRes], "_")
11241209 let currentWhRes = split(currentWh[whIdxRes], "_")
1125- let $t02561926490 = if ((claimMode == claimModeWh))
1210+ let $t02733528206 = if ((claimMode == claimModeWh))
11261211 then $Tuple4(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes], (parseIntValue(loft[volOccupied]) + resToClaim._2), (parseIntValue(loft[volFree]) - resToClaim._2))
11271212 else if ((claimMode == claimModeDuck))
11281213 then $Tuple4(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), parseIntValue(loft[volOccupied]), parseIntValue(loft[volFree]))
11291214 else {
11301215 let distr = distributeRes(currentWhRes, currentPackRes, resToClaim, whSpaceLeft)
11311216 let whAm = min([parseIntValue(loft[volFree]), resToClaim._2])
11321217 $Tuple4(distr._1, distr._2, (parseIntValue(loft[volOccupied]) + whAm), (parseIntValue(loft[volFree]) - whAm))
11331218 }
1134- let whRes = $t02561926490._1
1135- let bpRes = $t02561926490._2
1136- let loftO = $t02561926490._3
1137- let loftF = $t02561926490._4
1219+ let whRes = $t02733528206._1
1220+ let bpRes = $t02733528206._2
1221+ let loftO = $t02733528206._3
1222+ let loftF = $t02733528206._4
11381223 $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxLevels], whRes, currentWh[whIdxMat], currentWh[whIdxProd], makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")])
11391224 }
11401225 }
11411226 }
11421227 }
11431228
11441229
11451230 func claimAll (addr,landAssetId,pieces,claimMode) = {
11461231 let timeKey = keyStakedTimeByAssetId(landAssetId)
11471232 let savedTime = value(getInteger(timeKey))
11481233 let availRes = (fraction((lastBlock.timestamp - savedTime), applyBonuses(landAssetId, pieces), DAYMILLIS) * pieces)
11491234 claimResInternal(addr, availRes, claimMode, landAssetId)
11501235 }
11511236
11521237
11531238 func upInfraCommon (shouldUseMat,caller,paymentAmount,landAssetId) = {
11541239 let addr = toString(caller)
11551240 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetId)
11561241 let pieces = numPiecesBySize(c._3[recLandSize])
11571242 let infraKey = keyInfraLevelByAssetId(c._2)
11581243 let curLevel = valueOrElse(getInteger(infraKey), 0)
11591244 if ((curLevel >= 3))
11601245 then throw("Currently max infrastructure level = 3")
11611246 else {
11621247 let newLevel = (curLevel + 1)
11631248 let cost = fraction(InfraUpgradeCostSUsdt, (pieces * newLevel), SSIZE)
11641249 if (if (!(shouldUseMat))
11651250 then (paymentAmount != cost)
11661251 else false)
11671252 then throw(("Payment attached should be " + toString(cost)))
11681253 else {
11691254 let bpKey = keyBackpackByDuck(c._1)
11701255 let currentPack = getBackpack(bpKey)
11711256 let mList = split(currentPack[bpIdxMat], "_")
11721257 let newMat = makeString(subtractMaterials(shouldUseMat, mList, fraction(InfraUpgradeCostS, (pieces * newLevel), SSIZE)), "_")
11731258 let claimResult = claimAll(addr, c._2, pieces, claimModeWhThenDuck)
11741259 let whData = claimResult._5
11751260 let oldVol = getWarehouseTotalVolume(whData[whIdxLevels])
11761261 let newVolData = makeString([split(whData[whIdxLevels], "_")[0], toString(newLevel)], "_")
11771262 let newVol = getWarehouseTotalVolume(newVolData)
11781263 let loft = split(whData[whIdxLOFT], "_")
11791264 let newLoftStr = makeString([loft[volLocked], loft[volOccupied], toString(((parseIntValue(loft[volFree]) + newVol) - oldVol)), toString(newVol)], "_")
11801265 $Tuple2(([IntegerEntry(infraKey, newLevel), IntegerEntry(keyInfraLevelByAssetIdAndOwner(c._2, addr), newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], claimResult._3[bpIdxRes], newMat, currentPack[bpIdxProd]], ":")), StringEntry(claimResult._4, makeString([newVolData, whData[whIdxRes], whData[whIdxMat], whData[whIdxProd], newLoftStr], ":"))] ++ claimResult._1), newLevel)
11811266 }
11821267 }
11831268 }
11841269
11851270
11861271 func activateOnboardArt (addr) = 0
11871272
11881273
11891274 func activatePresaleArt (addr,landAssetIdIn) = {
11901275 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetIdIn)
11911276 let landAssetId = c._2
11921277 let pieces = numPiecesBySize(c._3[recLandSize])
11931278 let activationKey = keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)
11941279 if ((valueOrElse(getInteger(activationKey), 0) > 0))
11951280 then throw("Presale artifact is already activated")
11961281 else if ((parseIntValue(c._3[recLandNum]) > PRESALENUMLANDS))
11971282 then throw((((LANDPREFIX + " ") + landAssetId) + " is not eligible for presale artifact"))
11981283 else {
11991284 let claimResult = claimAll(addr, landAssetId, pieces, claimModeWhThenDuck)
12001285 ((((claimResult._1 :+ IntegerEntry(activationKey, pieces)) :+ IntegerEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, addr), pieces)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":"))) :+ StringEntry(claimResult._4, makeString(claimResult._5, ":")))
12011286 }
12021287 }
12031288
12041289
12051290 func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,txId,needMat) = {
12061291 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
12071292 func checkMerge (acc,landAssetId) = {
12081293 let asset = value(assetInfo(fromBase58String(landAssetId)))
12091294 let timeKey = keyStakedTimeByAssetId(landAssetId)
12101295 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
12111296 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
12121297 if ((owner != addr))
12131298 then throw((LANDPREFIX + " is not yours"))
12141299 else {
12151300 let d = split(asset.description, "_")
12161301 let continent = d[recContinent]
12171302 if (if ((acc._3 != ""))
12181303 then (acc._3 != continent)
12191304 else false)
12201305 then throw("Lands should be on the same continent to merge")
12211306 else {
12221307 let landSize = d[recLandSize]
12231308 let sizesIn = acc._1
12241309 let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
12251310 let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
12261311 let pieces = numPiecesBySize(landSize)
12271312 let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
12281313 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
12291314 let reqLevel = match landSize {
12301315 case _ =>
12311316 if (("S" == $match0))
12321317 then 3
12331318 else if (("M" == $match0))
12341319 then 4
12351320 else if (("L" == $match0))
12361321 then 5
12371322 else if (("XL" == $match0))
12381323 then 6
12391324 else throw("Only S, M, L, XL can merge")
12401325 }
12411326 if ((infraLevel != reqLevel))
12421327 then throw("All lands should be maxed to merge")
12431328 else {
12441329 let landNum = d[recLandNum]
12451330 let terrainCounts = countTerrains(d[recTerrains])
12461331 let deltaTime = (lastBlock.timestamp - savedTime)
12471332 if ((0 > deltaTime))
12481333 then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
12491334 else {
12501335 let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
12511336 let landIndex = (pieces / SSIZE)
12521337 let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
12531338 let props = updateProportionsInternal(split(acc._6, "_"), terrainCounts, landIndex, -1)
12541339 let lands = acc._7
12551340 let idx = indexOf(lands, landAssetId)
12561341 if (!(isDefined(idx)))
12571342 then throw(("Your staked lands don't contain " + landAssetId))
12581343 else {
12591344 let customKey = keyLandAssetIdToCustomName(landAssetId)
12601345 let customName = valueOrElse(getString(customKey), "")
12611346 $Tuple8(sizesOut, arts, continent, bpRes, (((((((((((((acc._5 :+ DeleteEntry(keyStakedTimeByAssetId(landAssetId))) :+ DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))) :+ DeleteEntry(keyLandToAssetId(landNum))) :+ DeleteEntry(keyLandAssetIdToOwner(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetId(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId))) :+ DeleteEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, addr))) :+ DeleteEntry(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ DeleteEntry(keyLandCustomNameToAssetId(customName))) :+ Burn(fromBase58String(landAssetId), 1)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces))
12621347 }
12631348 }
12641349 }
12651350 }
12661351 }
12671352 }
12681353
12691354 let bpKey = keyBackpackByDuck(duckAssetId)
12701355 let currentPack = getBackpack(bpKey)
12711356 let propStr = valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0")
12721357 let landsKey = keyStakedLandsByOwner(addr)
12731358 let landsStr = getString(landsKey)
12741359 let landsIn = if (isDefined(landsStr))
12751360 then split_51C(value(landsStr), "_")
12761361 else nil
12771362 let r = {
12781363 let $l = landAssetIds
12791364 let $s = size($l)
12801365 let $acc0 = $Tuple8(formula, 0, "", currentPack[bpIdxRes], nil, propStr, landsIn, 0)
12811366 func $f0_1 ($a,$i) = if (($i >= $s))
12821367 then $a
12831368 else checkMerge($a, $l[$i])
12841369
12851370 func $f0_2 ($a,$i) = if (($i >= $s))
12861371 then $a
12871372 else throw("List size exceeds 5")
12881373
12891374 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
12901375 }
12911376 let continent = r._3
12921377 let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
12931378 let terrains = genTerrains(abs(toBigInt(txId)), continentIdx)
12941379 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
12951380 let newLandNum = toString(freeNum)
12961381 let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
12971382 let assetId = calculateAssetId(issue)
12981383 let newLandAssetId = toBase58String(assetId)
12991384 let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
13001385 let piecesKey = keyStakedPiecesByOwner(addr)
13011386 let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
13021387 $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
13031388 then StringEntry(landsKey, makeString_11C(r._7, "_"))
13041389 else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
13051390 then 0
13061391 else (stakedPieces - r._8))) :+ IntegerEntry(keyNextFreeLandNum(), (freeNum + 1))) :+ issue) :+ StringEntry(keyLandToAssetId(newLandNum), newLandAssetId)) :+ StringEntry(keyLandAssetIdToOwner(newLandAssetId), addr)) :+ StringEntry(keyLandNumToOwner(newLandNum), addr)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, newLandAssetId), r._2)) :+ IntegerEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, newLandAssetId, addr), r._2)) :+ IntegerEntry(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), r._6)) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
13071392 }
13081393
13091394
13101395 func s2m (addr,landAssetIds,txId) = mergeInternal("M", 3, "SSSS", addr, landAssetIds, txId, 0)
13111396
13121397
13131398 func m2l (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
13141399 let cost = (InfraUpgradeCostSUsdt * 4)
13151400 if (if (!(shouldUseMat))
13161401 then (paymentAmount != cost)
13171402 else false)
13181403 then throw(("Payment attached should be " + toString(cost)))
13191404 else mergeInternal("L", 4, "SMM", addr, landAssetIds, txId, (InfraUpgradeCostS * 4))
13201405 }
13211406
13221407
13231408 func l2xl (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
13241409 let cost = (InfraUpgradeCostSUsdt * 47)
13251410 if (if (!(shouldUseMat))
13261411 then (paymentAmount != cost)
13271412 else false)
13281413 then throw(("Payment attached should be " + toString(cost)))
13291414 else mergeInternal("XL", 5, "SSSML", addr, landAssetIds, txId, (InfraUpgradeCostS * 47))
13301415 }
13311416
13321417
13331418 func xl2xxl (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
13341419 let cost = (InfraUpgradeCostSUsdt * 54)
13351420 if (if (!(shouldUseMat))
13361421 then (paymentAmount != cost)
13371422 else false)
13381423 then throw(("Payment attached should be " + toString(cost)))
13391424 else mergeInternal("XXL", 6, "LXL", addr, landAssetIds, txId, (InfraUpgradeCostS * 54))
13401425 }
13411426
13421427
13431428 func mergeCommon (shouldUseMat,addr,paymentAmount,landAssetIds,txId) = {
13441429 let mergeResult = match size(landAssetIds) {
13451430 case _ =>
13461431 if ((4 == $match0))
13471432 then s2m(addr, landAssetIds, txId)
13481433 else if ((3 == $match0))
13491434 then m2l(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
13501435 else if ((5 == $match0))
13511436 then l2xl(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
13521437 else if ((2 == $match0))
13531438 then xl2xxl(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
13541439 else throw("Unknown merge")
13551440 }
13561441 mergeResult
13571442 }
13581443
13591444
13601445 func prolog (i) = if (if ((i.originCaller != restContract))
13611446 then valueOrElse(getBoolean(keyBlocked()), false)
13621447 else false)
13631448 then throw("Contracts are under maintenance")
13641449 else StringEntry(keyLastTxIdByUser(toString(i.originCaller)), toBase58String(i.transactionId))
13651450
13661451
13671452 @Callable(i)
13681453 func constructorV1 (restAddr) = if ((i.caller != this))
13691454 then throw("Permission denied")
13701455 else [StringEntry(keyRestAddress(), restAddr)]
13711456
13721457
13731458
13741459 @Callable(i)
13751460 func setBlocked (isBlocked) = if ((i.caller != this))
13761461 then throw("permission denied")
13771462 else [BooleanEntry(keyBlocked(), isBlocked)]
13781463
13791464
13801465
13811466 @Callable(i)
13821467 func stakeLand () = {
13831468 let prologAction = prolog(i)
13841469 if ((size(i.payments) != 1))
13851470 then throw("Exactly one payment required")
13861471 else {
13871472 let pmt = value(i.payments[0])
13881473 let assetId = value(pmt.assetId)
13891474 let address = toString(i.caller)
13901475 if ((pmt.amount != 1))
13911476 then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
13921477 else {
13931478 let asset = value(assetInfo(assetId))
13941479 if ((asset.issuer != this))
13951480 then throw("Unknown issuer of token")
13961481 else if (!(contains(asset.name, LANDPREFIX)))
13971482 then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
13981483 else {
13991484 let landNumSize = drop(asset.name, 4)
14001485 let landNum = if (contains(landNumSize, "XXL"))
14011486 then dropRight(landNumSize, 3)
14021487 else if (contains(landNumSize, "XL"))
14031488 then dropRight(landNumSize, 2)
14041489 else dropRight(landNumSize, 1)
14051490 if (!(isDefined(parseInt(landNum))))
14061491 then throw(("Cannot parse land number from " + asset.name))
14071492 else {
14081493 let landAssetId = toBase58String(assetId)
14091494 let timeKey = keyStakedTimeByAssetId(landAssetId)
14101495 if (isDefined(getInteger(timeKey)))
14111496 then throw((("NFT " + asset.name) + " is already staked"))
14121497 else {
14131498 let d = split(asset.description, "_")
14141499 let terrainCounts = countTerrains(d[recTerrains])
14151500 let pieces = numPiecesBySize(d[recLandSize])
14161501 let props = updateProportions(terrainCounts, (pieces / SSIZE), 1)
14171502 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
14181503 let landsKey = keyStakedLandsByOwner(address)
14191504 let landsStr = getString(landsKey)
14201505 let lands = if (isDefined(landsStr))
14211506 then split_51C(value(landsStr), "_")
14221507 else nil
14231508 if (containsElement(lands, landAssetId))
14241509 then throw(("Your staked lands already contain " + landAssetId))
14251510 else {
14261511 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
14271512 [IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address), lastBlock.timestamp), StringEntry(landsKey, makeString_11C((lands :+ landAssetId), "_")), IntegerEntry(keyStakedPiecesByOwner(address), (valueOrElse(getInteger(keyStakedPiecesByOwner(address)), 0) + pieces)), StringEntry(keyLandAssetIdToOwner(landAssetId), address), StringEntry(keyLandNumToOwner(landNum), address), IntegerEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, address), artPieces), IntegerEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, address), infraLevel), StringEntry(keyResProportions(), props), prologAction]
14281513 }
14291514 }
14301515 }
14311516 }
14321517 }
14331518 }
14341519 }
14351520
14361521
14371522
14381523 @Callable(i)
14391524 func unstakeLand (landAssetIdIn) = {
14401525 let prologAction = prolog(i)
14411526 if ((size(i.payments) != 0))
14421527 then throw("No payments required")
14431528 else {
14441529 let addr = toString(i.caller)
14451530 let c = checkClaimConditions(addr, claimModeDuck, landAssetIdIn)
14461531 let landAssetId = c._2
14471532 let landsKey = keyStakedLandsByOwner(addr)
14481533 let terrainCounts = countTerrains(c._3[recTerrains])
14491534 let pieces = numPiecesBySize(c._3[recLandSize])
14501535 let props = updateProportions(terrainCounts, (pieces / SSIZE), -1)
14511536 let claimResult = claimAll(addr, landAssetId, pieces, claimModeDuck)
14521537 let lands = split_51C(valueOrElse(getString(landsKey), ""), "_")
14531538 let idx = indexOf(lands, landAssetId)
14541539 if (!(isDefined(idx)))
14551540 then throw(("Your staked lands don't contain " + landAssetId))
14561541 else {
14571542 let t = value(blockInfoByHeight(height)).timestamp
14581543 let releaseTime = valueOrElse(getInteger(govContract, keyUserGwlReleaseTime(addr)), 0)
14591544 if ((releaseTime >= t))
14601545 then throw(("Your gWL are taking part in voting, cannot unstake until " + toString(releaseTime)))
14611546 else {
14621547 let piecesKey = keyStakedPiecesByOwner(addr)
14631548 let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
14641549 [ScriptTransfer(i.caller, 1, fromBase58String(landAssetId)), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr)), StringEntry(keyResProportions(), props), StringEntry(claimResult._2, makeString(claimResult._3, ":")), if ((size(lands) > 1))
14651550 then StringEntry(landsKey, makeString_11C(removeByIndex(lands, value(idx)), "_"))
14661551 else DeleteEntry(landsKey), IntegerEntry(piecesKey, if ((pieces > stakedPieces))
14671552 then 0
14681553 else (stakedPieces - pieces)), prologAction]
14691554 }
14701555 }
14711556 }
14721557 }
14731558
14741559
14751560
14761561 @Callable(i)
14771562 func stakeDuck () = {
14781563 let prologAction = prolog(i)
14791564 if ((size(i.payments) != 1))
14801565 then throw("Exactly one payment required")
14811566 else {
14821567 let pmt = value(i.payments[0])
14831568 let assetId = value(pmt.assetId)
14841569 let address = toString(i.caller)
14851570 if ((pmt.amount != 1))
14861571 then throw((("NFT " + DUCKPREFIX) + " token should be attached as payment"))
14871572 else {
14881573 let asset = value(assetInfo(assetId))
14891574 if (if ((asset.issuer != incubatorAddr))
14901575 then (asset.issuer != breederAddr)
14911576 else false)
14921577 then throw((("Unknown issuer of " + DUCKPREFIX) + " token"))
14931578 else if (!(contains(asset.name, DUCKPREFIX)))
14941579 then throw((("Only NFT " + DUCKPREFIX) + " tokens are accepted"))
14951580 else {
14961581 let assetIdStr = toBase58String(assetId)
14971582 let timeKey = keyStakedTimeByAssetId(assetIdStr)
14981583 if (isDefined(getInteger(timeKey)))
14991584 then throw((("NFT " + asset.name) + " is already staked"))
15001585 else if (isDefined(getString(keyStakedDuckByOwner(address))))
15011586 then throw(("You already staked one duck: " + asset.name))
15021587 else {
15031588 let locKey = keyDuckLocation(assetIdStr)
15041589 let location = getString(locKey)
15051590 let bpKey = keyBackpackByDuck(assetIdStr)
15061591 let backpack = getString(bpKey)
15071592 ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
15081593 then nil
15091594 else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
15101595 then nil
15111596 else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyDuckHealth(assetIdStr), 100)) :+ prologAction)))))
15121597 }
15131598 }
15141599 }
15151600 }
15161601 }
15171602
15181603
15191604
15201605 @Callable(i)
15211606 func unstakeDuck (assetIdStr) = {
15221607 let prologAction = prolog(i)
15231608 if ((size(i.payments) != 0))
15241609 then throw("No payments required")
15251610 else {
15261611 let assetId = fromBase58String(assetIdStr)
15271612 let address = toString(i.caller)
15281613 let asset = value(assetInfo(assetId))
15291614 let timeKey = keyStakedTimeByAssetId(toBase58String(assetId))
15301615 if (!(isDefined(getInteger(timeKey))))
15311616 then throw((("NFT " + asset.name) + " is not staked"))
15321617 else if (!(isDefined(getString(keyStakedDuckByOwner(address)))))
15331618 then throw((("The duck " + asset.name) + " is not staked"))
15341619 else {
15351620 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(toBase58String(assetId))), (("NFT " + asset.name) + " is orphaned"))
15361621 if ((owner != address))
15371622 then throw("Staked NFT is not yours")
15381623 else {
15391624 let keyHealth = keyDuckHealth(assetIdStr)
15401625 let health = valueOrElse(getInteger(keyHealth), 100)
15411626 if ((100 > health))
15421627 then throw("Please heal your duck before unstaking")
15431628 else [ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyHealth), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address)), prologAction]
15441629 }
15451630 }
15461631 }
15471632 }
15481633
15491634
15501635
15511636 @Callable(i)
15521637 func claimRes (amount,landAssetIdStr) = {
15531638 let prologAction = prolog(i)
15541639 if ((size(i.payments) != 0))
15551640 then throw("No payments required")
15561641 else {
15571642 let addr = toString(i.originCaller)
15581643 let result = claimResInternal(addr, amount, claimModeDuck, landAssetIdStr)
15591644 $Tuple2((((result._1 :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) :+ prologAction), result._3[bpIdxRes])
15601645 }
15611646 }
15621647
15631648
15641649
15651650 @Callable(i)
15661651 func claimResToWH (amount,landAssetIdStr) = {
15671652 let prologAction = prolog(i)
15681653 if ((size(i.payments) != 0))
15691654 then throw("No payments required")
15701655 else {
15711656 let addr = toString(i.originCaller)
15721657 let result = claimResInternal(addr, amount, claimModeWh, landAssetIdStr)
15731658 $Tuple2((((result._1 :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) :+ prologAction), result._5[whIdxRes])
15741659 }
15751660 }
15761661
15771662
15781663
15791664 @Callable(i)
15801665 func flight (message,sig) = {
15811666 let prologAction = prolog(i)
1582- if (!(sigVerify_8Kb(message, sig, pub)))
1583- then throw("signature does not match")
1584- else if ((size(i.payments) != 0))
1585- then throw("No payments required")
1586- else {
1587- let parts = split(toUtf8String(message), ";")
1588- let flightLog = split(parts[0], "|")
1589- let hp = split(flightLog[flHealth], "_")
1590- let curHP = parseIntValue(hp[0])
1591- let newHP = parseIntValue(hp[1])
1592- let newLocTxVer = split(parts[1], ":")
1593- let newLocation = newLocTxVer[0]
1594- let time = parseIntValue(flightLog[flTimestamp])
1595- if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
1596- then true
1597- else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
1598- then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
1599- else {
1600- let txFromMsg = newLocTxVer[1]
1601- let lastTx = valueOrElse(getString(keyLastTxIdByUser(toString(i.originCaller))), "")
1602- if ((lastTx != txFromMsg))
1603- then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
1604- else {
1605- let userAddr = toString(i.caller)
1606- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
1607- let keyHealth = keyDuckHealth(duckAssetId)
1608- let oldFromState = valueOrElse(getInteger(keyHealth), 100)
1609- if ((oldFromState != curHP))
1610- then throw(((("oldHealth=" + toString(valueOrElse(getInteger(keyHealth), 100))) + " from state does not match one from flight log=") + toString(curHP)))
1611- else if ((0 >= curHP))
1612- then throw("You can't fly with zero health")
1613- else {
1614- let locKey = keyDuckLocation(duckAssetId)
1615- let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
1616- if ((newLocation == curLocation))
1617- then throw("You can't fly to the same location")
1618- else {
1619- let bonus = if ((size(flightLog) > flBonus))
1620- then flightLog[flBonus]
1621- else ""
1622- let sentAmount = if (if ((newHP > 0))
1623- then (bonus == "$")
1624- else false)
1625- then asInt(invoke(restContract, "sendUsdtPrize", [userAddr], nil))
1626- else 0
1627- $Tuple2([StringEntry(locKey, if ((newHP > 0))
1628- then newLocation
1629- else curLocation), IntegerEntry(keyHealth, newHP), prologAction], sentAmount)
1630- }
1631- }
1632- }
1633- }
1634- }
1667+ if ((size(i.payments) != 0))
1668+ then throw("No payments required")
1669+ else {
1670+ let userAddr = toString(i.caller)
1671+ let f = flightCommon(userAddr, message, sig)
1672+ let locKey = keyDuckLocation(f._2)
1673+ let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
1674+ if ((f._4 == curLocation))
1675+ then throw("You can't fly to the same location")
1676+ else {
1677+ let bpKey = keyBackpackByDuck(f._2)
1678+ let currentPack = getBackpack(bpKey)
1679+ let newProd = subtractProducts(currentPack[bpIdxProd], f._5)
1680+ $Tuple2([StringEntry(locKey, if ((f._1 > 0))
1681+ then f._4
1682+ else curLocation), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProd], ":")), IntegerEntry(keyDuckHealth(f._2), f._1), prologAction], f._3)
1683+ }
1684+ }
16351685 }
16361686
16371687
16381688
16391689 @Callable(i)
16401690 func heal (quantityL1,quantityL2,quantityL3) = {
16411691 let prologAction = prolog(i)
16421692 if (if (if ((0 > quantityL1))
16431693 then true
16441694 else (0 > quantityL2))
16451695 then true
16461696 else (0 > quantityL3))
16471697 then throw("Quantity cannot be negative")
16481698 else {
16491699 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
16501700 let qts = [quantityL1, quantityL2, quantityL3]
16511701 let keyHealth = keyDuckHealth(duckAssetId)
16521702 let oldHealth = valueOrElse(getInteger(keyHealth), 100)
16531703 if ((oldHealth >= MAXHP))
16541704 then throw((("HP should be < " + toString(MAXHP)) + " to heal"))
16551705 else {
16561706 let bpKey = keyBackpackByDuck(duckAssetId)
16571707 let currentPack = getBackpack(bpKey)
16581708 let prodList = if ((currentPack[bpIdxProd] == ""))
16591709 then nil
16601710 else split(currentPack[bpIdxProd], "_")
16611711 func iterateProd (acc,ignoredItem) = {
16621712 let n = acc._2
16631713 let x = if ((size(prodList) > n))
16641714 then parseIntValue(prodList[n])
16651715 else 0
16661716 if ((3 > n))
16671717 then {
16681718 let q = qts[n]
16691719 if ((q > x))
16701720 then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
16711721 else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (medKitHp[n] * q)))
16721722 }
16731723 else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
16741724 }
16751725
16761726 let result = {
16771727 let $l = productionMatrix
16781728 let $s = size($l)
16791729 let $acc0 = $Tuple3(nil, 0, 0)
16801730 func $f0_1 ($a,$i) = if (($i >= $s))
16811731 then $a
16821732 else iterateProd($a, $l[$i])
16831733
16841734 func $f0_2 ($a,$i) = if (($i >= $s))
16851735 then $a
16861736 else throw("List size exceeds 50")
16871737
16881738 $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)
16891739 }
16901740 let newHealth = min([MAXHP, (oldHealth + result._3)])
16911741 $Tuple2([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":")), prologAction], newHealth)
16921742 }
16931743 }
16941744 }
16951745
16961746
16971747
16981748 @Callable(i)
16991749 func healES () = {
17001750 let prologAction = prolog(i)
17011751 if ((size(i.payments) != 1))
17021752 then throw("Exactly one payment required")
17031753 else {
17041754 let pmt = value(i.payments[0])
17051755 if ((pmt.assetId != usdtAssetId))
17061756 then throw("Allowed USDT payment only!")
17071757 else {
17081758 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
17091759 let keyHealth = keyDuckHealth(duckAssetId)
17101760 let oldHealth = valueOrElse(getInteger(keyHealth), 100)
17111761 if ((oldHealth > 0))
17121762 then throw("HP should be 0 to call Emergency Service")
17131763 else {
17141764 let bpKey = keyBackpackByDuck(duckAssetId)
17151765 let currentPack = getBackpack(bpKey)
17161766 let prodList = if ((currentPack[bpIdxProd] == ""))
17171767 then nil
17181768 else split(currentPack[bpIdxProd], "_")
17191769 let medKitAmount1 = if ((size(prodList) > 0))
17201770 then parseIntValue(prodList[0])
17211771 else 0
17221772 let medKitAmount2 = if ((size(prodList) > 1))
17231773 then parseIntValue(prodList[1])
17241774 else 0
17251775 let medKitAmount3 = if ((size(prodList) > 2))
17261776 then parseIntValue(prodList[2])
17271777 else 0
17281778 if (if (if ((medKitAmount1 > 0))
17291779 then true
17301780 else (medKitAmount2 > 0))
17311781 then true
17321782 else (medKitAmount3 > 0))
17331783 then throw("You have to use own Medical Kit")
17341784 else {
17351785 let existStr = getString(economyContract, keyEsWarehouse())
17361786 let existAmounts = if (isDefined(existStr))
17371787 then split(value(existStr), "_")
17381788 else nil
17391789 let existAmount = if ((size(existAmounts) > 0))
17401790 then parseIntValue(existAmounts[0])
17411791 else 0
17421792 if ((0 >= existAmount))
17431793 then throw("There are no Medical Kits L1 at Emergency Service storage")
17441794 else {
17451795 let newHealth = (oldHealth + medKitHp[0])
17461796 let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
17471797 let recipe = split(productionMatrix[0], "_")
17481798 let totalMat = getRecipeMaterials(recipe)
17491799 let packSize = parseIntValue(recipe[recipeIdxPacksize])
17501800 let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (10 * packSize))
17511801 if ((pmt.amount != sellPrice))
17521802 then throw(("Payment attached should be " + toString(sellPrice)))
17531803 else {
17541804 let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
17551805 $Tuple2([IntegerEntry(keyHealth, newHealth), prologAction], result)
17561806 }
17571807 }
17581808 }
17591809 }
17601810 }
17611811 }
17621812 }
17631813
17641814
17651815
17661816 @Callable(i)
17671817 func updateBackpack (duckAssetId,newPack) = {
17681818 let prologAction = prolog(i)
17691819 if ((i.caller != economyContract))
17701820 then throw("permission denied")
17711821 else $Tuple2([StringEntry(keyBackpackByDuck(duckAssetId), newPack), prologAction], newPack)
17721822 }
17731823
17741824
17751825
17761826 @Callable(i)
17771827 func buySLand () = {
17781828 let prologAction = prolog(i)
17791829 if ((size(i.payments) != 1))
17801830 then throw("Exactly one payment required")
17811831 else {
17821832 let pmt = value(i.payments[0])
17831833 if ((pmt.assetId != usdtAssetId))
17841834 then throw("Allowed USDT payment only!")
17851835 else if ((pmt.amount != EXPUSDT))
17861836 then throw(("Payment attached should be " + toString(EXPUSDT)))
17871837 else {
17881838 let result = expeditionInternal(i.caller, i.transactionId)
17891839 $Tuple2(((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), result._2._1)
17901840 }
17911841 }
17921842 }
17931843
17941844
17951845
17961846 @Callable(i)
17971847 func expedition (message,sig) = {
17981848 let prologAction = prolog(i)
17991849 if ((size(i.payments) != 0))
18001850 then throw("No payments required")
18011851 else {
1802- let result = expeditionCommon(true, i.caller, i.transactionId, message, sig)
1852+ let result = expeditionCommon(i.caller, i.transactionId, message, sig)
18031853 $Tuple2((result._1 :+ prologAction), $Tuple2(result._2, result._3))
18041854 }
18051855 }
18061856
18071857
18081858
18091859 @Callable(i)
18101860 func upgradeInfra (landAssetId) = {
18111861 let prologAction = prolog(i)
18121862 if ((size(i.payments) != 0))
18131863 then throw("No payments required")
18141864 else {
18151865 let result = upInfraCommon(true, i.caller, 0, landAssetId)
18161866 $Tuple2((result._1 :+ prologAction), result._2)
18171867 }
18181868 }
18191869
18201870
18211871
18221872 @Callable(i)
18231873 func upgradeInfraUsdt (landAssetId) = if ((i.caller != this))
18241874 then throw("Permission denied")
18251875 else {
18261876 let prologAction = prolog(i)
18271877 if ((size(i.payments) != 1))
18281878 then throw("Exactly one payment required")
18291879 else {
18301880 let pmt = value(i.payments[0])
18311881 if ((pmt.assetId != usdtAssetId))
18321882 then throw("Allowed USDT payment only!")
18331883 else {
18341884 let result = upInfraCommon(false, i.caller, pmt.amount, landAssetId)
18351885 $Tuple2(((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), result._2)
18361886 }
18371887 }
18381888 }
18391889
18401890
18411891
18421892 @Callable(i)
18431893 func activateArtifact (artName,landAssetId) = {
18441894 let prologAction = prolog(i)
18451895 if ((size(i.payments) != 0))
18461896 then throw("No payments required")
18471897 else {
18481898 let result = match artName {
18491899 case _ =>
18501900 if (("PRESALE" == $match0))
18511901 then activatePresaleArt(toString(i.caller), landAssetId)
18521902 else throw("Unknown artifact")
18531903 }
18541904 (result :+ prologAction)
18551905 }
18561906 }
18571907
18581908
18591909
18601910 @Callable(i)
18611911 func mergeLands (landAssetIds) = {
18621912 let prologAction = prolog(i)
18631913 if ((size(i.payments) != 0))
18641914 then throw("No payments required")
18651915 else {
18661916 let result = mergeCommon(true, toString(i.caller), 0, landAssetIds, i.transactionId)
18671917 $Tuple2((result._1 :+ prologAction), result._2)
18681918 }
18691919 }
18701920
18711921
18721922
18731923 @Callable(i)
18741924 func mergeLandsUsdt (landAssetIds) = {
18751925 let prologAction = prolog(i)
18761926 if ((size(i.payments) != 1))
18771927 then throw("Exactly one payment required")
18781928 else {
18791929 let pmt = value(i.payments[0])
18801930 if ((pmt.assetId != usdtAssetId))
18811931 then throw("Allowed USDT payment only!")
18821932 else {
18831933 let result = mergeCommon(false, toString(i.caller), pmt.amount, landAssetIds, i.transactionId)
18841934 $Tuple2(((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), result._2)
18851935 }
18861936 }
18871937 }
18881938
18891939
18901940
18911941 @Callable(i)
18921942 func cargoExchange (cargoListStr,landAssetId) = {
18931943 let prologAction = prolog(i)
18941944 if ((size(i.payments) != 0))
18951945 then throw("No payments required")
18961946 else {
18971947 let cargoParts = split_4C(cargoListStr, ":")
18981948 let addr = toString(i.originCaller)
18991949 let asset = value(assetInfo(fromBase58String(landAssetId)))
19001950 let timeKey = keyStakedTimeByAssetId(landAssetId)
19011951 if (!(isDefined(getInteger(timeKey))))
19021952 then throw((asset.name + " is not staked"))
19031953 else {
19041954 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
19051955 if ((owner != addr))
19061956 then throw((LANDPREFIX + " is not yours"))
19071957 else {
19081958 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
19091959 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
19101960 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
19111961 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
19121962 let loc = split(value(curLocation), "_")
19131963 if ((loc[locIdxType] != "L"))
19141964 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
19151965 else if ((loc[locIdxId] != landAssetId))
19161966 then throw(("Duck should be on the land " + landAssetId))
19171967 else {
19181968 let whKey = keyWarehouseByLand(landAssetId)
19191969 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
19201970 let bpKey = keyBackpackByDuck(duckAssetId)
19211971 let currentPack = getBackpack(bpKey)
19221972 let result = moveStuff(cargoParts, currentWh, currentPack)
19231973 let loft = split(currentWh[whIdxLOFT], "_")
19241974 let loftO = (parseIntValue(loft[volOccupied]) + result._7)
19251975 let loftF = (parseIntValue(loft[volFree]) - result._7)
19261976 [StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], result._4, result._5, result._6], ":")), StringEntry(whKey, makeString_2C([currentWh[whIdxLevels], result._1, result._2, result._3, makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")], ":")), prologAction]
19271977 }
19281978 }
19291979 }
19301980 }
19311981 }
19321982
19331983
19341984
19351985 @Callable(i)
19361986 func saveWarehouse (whStr,landAssetId) = {
19371987 let prologAction = prolog(i)
19381988 if ((i.caller != economyContract))
19391989 then throw("Access denied")
19401990 else {
19411991 let whKey = keyWarehouseByLand(landAssetId)
19421992 let wh = split_4C(whStr, ":")
19431993 if ((size(wh) != 5))
19441994 then throw("warehouse string should contain 4 ':' separators")
19451995 else {
19461996 let loftL = split(wh[whIdxLOFT], "_")[volLocked]
19471997 let loftO = getWarehouseOccupiedVol(wh)
19481998 let loftT = getWarehouseTotalVolume(wh[whIdxLevels])
19491999 let loftF = ((loftT - parseIntValue(loftL)) - loftO)
19502000 let newWhStr = makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], wh[whIdxProd], makeString([loftL, toString(loftO), toString(loftF), toString(loftT)], "_")], ":")
19512001 $Tuple2([StringEntry(whKey, newWhStr), prologAction], newWhStr)
19522002 }
19532003 }
19542004 }
19552005
19562006
19572007
19582008 @Callable(i)
19592009 func fixWarehouseFormat (landAssetId) = if ((i.caller != restContract))
19602010 then throw("Access denied")
19612011 else {
19622012 let whKey = keyWarehouseByLand(landAssetId)
19632013 let asset = value(assetInfo(fromBase58String(landAssetId)))
19642014 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
19652015 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
19662016 let wh = getWarehouse(whKey, landIndex, infraLevel)
19672017 let loftL = asInt(invoke(economyContract, "recalcLockedVolumeREADONLY", [landAssetId, wh], nil))
19682018 let loftO = getWarehouseOccupiedVol(wh)
19692019 let loftT = getWarehouseTotalVolume(wh[whIdxLevels])
19702020 let loftF = ((loftT - loftL) - loftO)
19712021 let newWhStr = makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], wh[whIdxProd], makeString([toString(loftL), toString(loftO), toString(loftF), toString(loftT)], "_")], ":")
19722022 $Tuple2([StringEntry(whKey, newWhStr)], newWhStr)
19732023 }
19742024
19752025
19762026
19772027 @Callable(i)
19782028 func fixStakedPieces (address) = if ((i.caller != restContract))
19792029 then throw("Access denied")
19802030 else {
19812031 let stakedPieces = if ((address == ""))
19822032 then 0
19832033 else {
19842034 let landsStr = getString(stakingContract, keyStakedLandsByOwner(address))
19852035 let lands = if (isDefined(landsStr))
19862036 then split_51C(value(landsStr), "_")
19872037 else nil
19882038 func oneLand (acc,landAssetId) = {
19892039 let asset = value(assetInfo(fromBase58String(landAssetId)))
19902040 let landSize = split(asset.description, "_")[recLandSize]
19912041 (acc + numPiecesBySize(landSize))
19922042 }
19932043
19942044 let $l = lands
19952045 let $s = size($l)
19962046 let $acc0 = 0
19972047 func $f0_1 ($a,$i) = if (($i >= $s))
19982048 then $a
19992049 else oneLand($a, $l[$i])
20002050
20012051 func $f0_2 ($a,$i) = if (($i >= $s))
20022052 then $a
20032053 else throw("List size exceeds 100")
20042054
20052055 $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($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), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100)
20062056 }
20072057 $Tuple2([IntegerEntry(keyStakedPiecesByOwner(address), stakedPieces)], stakedPieces)
20082058 }
20092059
20102060
20112061
20122062 @Callable(i)
20132063 func setCustomName (assetId,customName,type) = {
20142064 let prologAction = prolog(i)
20152065 if ((size(i.payments) != 1))
20162066 then throw("Exactly one payment required")
20172067 else {
20182068 let pmt = value(i.payments[0])
20192069 if ((pmt.assetId != usdtAssetId))
20202070 then throw("Allowed USDT payment only!")
20212071 else if ((pmt.amount != RENAMINGCOST))
20222072 then throw(("Payment should be " + toString(RENAMINGCOST)))
20232073 else if (contains(customName, "__"))
20242074 then throw(("Name should not contain '__': " + customName))
20252075 else if ((size(customName) > MAXNAMELEN))
20262076 then throw(("Name too long, maxLength=" + toString(MAXNAMELEN)))
20272077 else {
20282078 let addr = toString(i.originCaller)
20292079 let actions = match type {
20302080 case _ =>
20312081 if (("ACCOUNT" == $match0))
20322082 then {
20332083 let reverseKey = keyCustomNameToAddress(customName)
20342084 let nameOwner = getString(reverseKey)
20352085 if (isDefined(nameOwner))
20362086 then throw(("Name already registered: " + customName))
20372087 else {
20382088 let addrToNameKey = keyAddressToCustomName(addr)
20392089 let oldName = getString(addrToNameKey)
20402090 let freeOld = if (isDefined(oldName))
20412091 then [DeleteEntry(keyCustomNameToAddress(value(oldName)))]
20422092 else nil
20432093 ((freeOld :+ StringEntry(addrToNameKey, customName)) :+ StringEntry(reverseKey, addr))
20442094 }
20452095 }
20462096 else if (("LAND" == $match0))
20472097 then {
20482098 let asset = value(assetInfo(fromBase58String(assetId)))
20492099 let timeKey = keyStakedTimeByAssetId(assetId)
20502100 if (!(isDefined(getInteger(timeKey))))
20512101 then throw((asset.name + " is not staked"))
20522102 else {
20532103 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
20542104 if ((owner != addr))
20552105 then throw((LANDPREFIX + " is not yours"))
20562106 else {
20572107 let reverseKey = keyLandCustomNameToAssetId(customName)
20582108 let nameOwner = getString(reverseKey)
20592109 if (isDefined(nameOwner))
20602110 then throw(("Name already registered: " + customName))
20612111 else {
20622112 let assetToNameKey = keyLandAssetIdToCustomName(assetId)
20632113 let oldName = getString(assetToNameKey)
20642114 let freeOld = if (isDefined(oldName))
20652115 then [DeleteEntry(keyLandCustomNameToAssetId(value(oldName)))]
20662116 else nil
20672117 ((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId))
20682118 }
20692119 }
20702120 }
20712121 }
20722122 else if (("DUCK" == $match0))
20732123 then {
20742124 let asset = value(assetInfo(fromBase58String(assetId)))
20752125 let timeKey = keyStakedTimeByAssetId(assetId)
20762126 if (if (!(isDefined(getInteger(timeKey))))
20772127 then true
20782128 else !(isDefined(getString(keyStakedDuckByOwner(addr)))))
20792129 then throw((asset.name + " is not staked"))
20802130 else {
20812131 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
20822132 if ((owner != addr))
20832133 then throw((DUCKPREFIX + " is not yours"))
20842134 else {
20852135 let reverseKey = keyDuckCustomNameToAssetId(customName)
20862136 let nameOwner = getString(reverseKey)
20872137 if (isDefined(nameOwner))
20882138 then throw(("Name already registered: " + customName))
20892139 else {
20902140 let assetToNameKey = keyDuckAssetIdToCustomName(assetId)
20912141 let oldName = getString(assetToNameKey)
20922142 let freeOld = if (isDefined(oldName))
20932143 then [DeleteEntry(keyDuckCustomNameToAssetId(value(oldName)))]
20942144 else nil
20952145 ((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId))
20962146 }
20972147 }
20982148 }
20992149 }
21002150 else throw("Unknown entity type")
21012151 }
21022152 $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), 0)
21032153 }
21042154 }
21052155 }
21062156
21072157
21082158
21092159 @Callable(i)
21102160 func setReferrals (oldPlayer,newPlayer) = if ((i.callerPublicKey != pub))
21112161 then throw("Permission denied")
21122162 else {
21132163 let prologAction = prolog(i)
21142164 if ((size(i.payments) != 0))
21152165 then throw("No payments required")
21162166 else if (!(isDefined(addressFromString(oldPlayer))))
21172167 then throw(("Invalid address: " + oldPlayer))
21182168 else if (!(isDefined(addressFromString(newPlayer))))
21192169 then throw(("Invalid address: " + newPlayer))
21202170 else {
21212171 let oldsKey = keyOldies()
21222172 let olds = getString(oldsKey)
21232173 let oldies = if (isDefined(olds))
21242174 then split_4C(value(olds), "_")
21252175 else nil
21262176 if (containsElement(oldies, newPlayer))
21272177 then throw((newPlayer + " is not newbie (already has referrals)"))
21282178 else {
21292179 let refByKey = keyAddressRefBy(newPlayer)
21302180 let refBy = getString(refByKey)
21312181 if (if (isDefined(refBy))
21322182 then isDefined(addressFromString(value(refBy)))
21332183 else false)
21342184 then throw(((newPlayer + " already has refBy: ") + value(refBy)))
21352185 else {
21362186 let refsKey = keyAddressReferrals(oldPlayer)
21372187 let refs = getString(refsKey)
21382188 let refsArray = if (isDefined(refs))
21392189 then split_4C(value(refs), "_")
21402190 else nil
21412191 if (containsElement(refsArray, newPlayer))
21422192 then throw((((oldPlayer + " already contains ") + newPlayer) + " within referrals"))
21432193 else {
21442194 let newRefs = makeString_2C((refsArray :+ newPlayer), "_")
21452195 let newOlds = if (containsElement(oldies, oldPlayer))
21462196 then value(olds)
21472197 else makeString_2C((oldies :+ oldPlayer), "_")
21482198 $Tuple2([StringEntry(refByKey, oldPlayer), StringEntry(refsKey, newRefs), StringEntry(oldsKey, newOlds), prologAction], 0)
21492199 }
21502200 }
21512201 }
21522202 }
21532203 }
21542204
21552205
21562206
21572207 @Callable(i)
21582208 func splitByGlobalWeightsREADONLY (amount) = $Tuple2(nil, getNeededMaterials(amount))
21592209
21602210
21612211
21622212 @Callable(i)
21632213 func splitByGlobalAndLocalWeightsREADONLY (matAmount,resAmount,terrains) = {
21642214 let terrainCounts = countTerrains(terrains)
21652215 $Tuple2(nil, $Tuple2(getNeededMaterials(matAmount), distributeByWeights(resAmount, terrainCounts)))
21662216 }
21672217
21682218
21692219
21702220 @Callable(i)
21712221 func getBackpackREADONLY (duckAssetId) = $Tuple2(nil, makeString(getBackpack(keyBackpackByDuck(duckAssetId)), ":"))
21722222
21732223
21742224
21752225 @Callable(i)
21762226 func getWarehouseREADONLY (landAssetId) = {
21772227 let asset = value(assetInfo(fromBase58String(landAssetId)))
21782228 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
21792229 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
21802230 $Tuple2(nil, makeString_2C(getWarehouse(keyWarehouseByLand(landAssetId), landIndex, infraLevel), ":"))
21812231 }
21822232
21832233
21842234
21852235 @Callable(i)
21862236 func saveLastTx () = if ((i.caller != wlgContract))
21872237 then throw("Access denied")
21882238 else $Tuple2([prolog(i)], 42)
21892239
21902240

github/deemru/w8io/03bedc9 
312.82 ms