tx · YvQJrPYtMyFqBjPKuqW5JZoANeDdTNmshLh4BUZwabG

3PLncXtS1U83D6cQbFD3H8rBHPLgzxSFKZ1:  -0.10600000 Waves

2023.10.04 19:11 [3849937] smart account 3PLncXtS1U83D6cQbFD3H8rBHPLgzxSFKZ1 > SELF 0.00000000 Waves

{ "type": 13, "id": "YvQJrPYtMyFqBjPKuqW5JZoANeDdTNmshLh4BUZwabG", "fee": 10600000, "feeAssetId": null, "timestamp": 1696435873428, "version": 2, "chainId": 87, "sender": "3PLncXtS1U83D6cQbFD3H8rBHPLgzxSFKZ1", "senderPublicKey": "BtDpFhgHQKHFVqYTMLReuZzqy94CRPSRkrYcSEVyjt4q", "proofs": [ "qrmKiHXRBqnWHP2fVsauYCHDMznwxEuF1Zqr6vTgM2cZ4yJJ96WSmxRyqmZT5HhySmYNeNenuekNhDXf5d5Aned" ], "script": "base64:BgLhAQgCEgMKAQgSBAoCCAESAwoBBBIAEgMKAQgSABIDCgEIEgQKAgEIEgQKAgEIEgQKAgICEgUKAwEBARIAEgQKAggIEgASABIECgICAhIAEgMKAQgSBAoCCAgSAwoBGBIECgIICBIECgIICBIDCgEIEgMKARgSAwoBCBIFCgMICAgSBAoCCAgSBwoFAQEBAQESAwoBARIFCgMBAQgSAwoBCBIDCgEIEgASBAoCCAESBAoCCAESAwoBCBIECgIICBIDCgEIEgASAwoBCBIDCgEIEgMKAQgSBAoCAgISBAoCAgISAJoCAAlEQVlNSUxMSVMAgLiZKQEUa2V5TGFzdEFyYlRpbWVCeVVzZXIBBGFkZHIJAKwCAgIQbGFzdEFyYlRpbWVVc2VyXwUEYWRkcgAGU0NBTEU4AIDC1y8ADHhwTGV2ZWxTY2FsZQCAGQAPeHBMZXZlbFJlY2lwUG93AKAfABJudW1Qb2ludHNPbkxldmVsVXAAAwAOcm9iYmVyeUNvc3RNaW4AgMLXLwAUcm9iYmVyeUNvb2xkb3duQ29lZmYAkAMADHJlcXVpcmVtZW50cwkAzAgCAghTdHJlbmd0aAkAzAgCAghBY2N1cmFjeQkAzAgCAglJbnRlbGxlY3QJAMwIAgIJRW5kdXJhbmNlCQDMCAICCURleHRlcml0eQkAzAgCAgVMZXZlbAkAzAgCAgZIZWFsdGgFA25pbAAMY2hhclN0cmVuZ3RoAAAADGNoYXJBY2N1cmFjeQABAA1jaGFySW50ZWxsZWN0AAIADWNoYXJFbmR1cmFuY2UAAwANY2hhckRleHRlcml0eQAEAAtzZWdCYWNrcGFjawAAAAtOVU1TRUdNRU5UUwAGAApOVU1NQUlOQVVYAAIACE1BWFNMT1RTAAIADU1BWFBST0RJTlNMT1QAHgAQbGFuZFJvYkNvb2xkb3ducwkAzAgCAAAJAMwIAgDAzyQJAMwIAgCg9zYJAMwIAgCA3MwUCQDMCAIAgK6mCgUDbmlsAA5NSU5fUkVTX1RPX1JPQgCA2sQJAAxyb2JJZHhMb2NrZWQAAQALZHVja0lkeEZyZWUAAAAQZHVja0lkeFByZXBhcmluZwABAQ1rZXlEdWNrSGVhbHRoAQtkdWNrQXNzZXRJZAkArAICAgtkdWNrSGVhbHRoXwULZHVja0Fzc2V0SWQBDGtleUR1Y2tDaGFycwELZHVja0Fzc2V0SWQJAKwCAgIKZHVja0NoYXJzXwULZHVja0Fzc2V0SWQBCWtleUR1Y2tYUAELZHVja0Fzc2V0SWQJAKwCAgIHZHVja1hQXwULZHVja0Fzc2V0SWQBDGtleUR1Y2tMZXZlbAELZHVja0Fzc2V0SWQJAKwCAgIKZHVja0xldmVsXwULZHVja0Fzc2V0SWQBEWtleUR1Y2tGcmVlUG9pbnRzAQtkdWNrQXNzZXRJZAkArAICAg9kdWNrRnJlZVBvaW50c18FC2R1Y2tBc3NldElkARBrZXlEdWNrRXF1aXBtZW50AQtkdWNrQXNzZXRJZAkArAICAg5kdWNrRXF1aXBtZW50XwULZHVja0Fzc2V0SWQBCWtleVVzZXJYUAEEYWRkcgkArAICAgd1c2VyWFBfBQRhZGRyAQxrZXlVc2VyTGV2ZWwBBGFkZHIJAKwCAgIKdXNlckxldmVsXwUEYWRkcgERa2V5VXNlckZyZWVQb2ludHMBBGFkZHIJAKwCAgIPdXNlckZyZWVQb2ludHNfBQRhZGRyAQ5rZXlTYXZlZEhlYWx0aAELZHVja0Fzc2V0SWQJAKwCAgIMc2F2ZWRIZWFsdGhfBQtkdWNrQXNzZXRJZAEQa2V5U2F2ZWRMb2NhdGlvbgELZHVja0Fzc2V0SWQJAKwCAgIOc2F2ZWRMb2NhdGlvbl8FC2R1Y2tBc3NldElkAQxrZXlEdWNrQnVmZnMBC2R1Y2tBc3NldElkCQCsAgICCmR1Y2tCdWZmc18FC2R1Y2tBc3NldElkARhrZXlMYXN0Um9iYmVyeVRpbWVCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICEGxhc3RSb2JiZXJ5VGltZV8FC2R1Y2tBc3NldElkARhrZXlMYXN0Um9iYmVyeUNvc3RCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICEGxhc3RSb2JiZXJ5Q29zdF8FC2R1Y2tBc3NldElkARNrZXlMYW5kUm9iYmVyeVN0YXRlAQtsYW5kQXNzZXRJZAkArAICAhFsYW5kUm9iYmVyeVN0YXRlXwULbGFuZEFzc2V0SWQBEmtleUxhbmRDb29sZG93bkVUQQELbGFuZEFzc2V0SWQJAKwCAgIQbGFuZENvb2xkb3duRVRBXwULbGFuZEFzc2V0SWQBE2tleUR1Y2tSb2JiZXJ5U3RhdGUBC2R1Y2tBc3NldElkCQCsAgICEWR1Y2tSb2JiZXJ5U3RhdGVfBQtkdWNrQXNzZXRJZAETa2V5TG9ja2VkTGFuZEJ5RHVjawELZHVja0Fzc2V0SWQJAKwCAgIRbG9ja2VkTGFuZEJ5RHVja18FC2R1Y2tBc3NldElkARZrZXlEZWxpdmVyeURlbGF5QnlEdWNrAQtkdWNrQXNzZXRJZAkArAICAhRkZWxpdmVyeURlbGF5QnlEdWNrXwULZHVja0Fzc2V0SWQAB3hwQ2xhaW0AkE4AD3hwU3VjY2Vzc0ZsaWdodACQTgAMeHBGYWlsRmxpZ2h0ANAPAAh4cENhbGxFUwCgjQYADHhwQ3VzdG9tTmFtZQDAhD0ACnhwTmV3U0xhbmQAwJaxAgAOeHBVcGdyYWRlSW5mcmEAkE4AB3hwTWVyZ2UAwIQ9AAl4cE9uYm9hcmQAwIQ9AAZ4cEhlYWwAkE4BCWxldmVsQnlYUAECeHAJAGsDBQx4cExldmVsU2NhbGUJAGwGBQJ4cAAEBQ94cExldmVsUmVjaXBQb3cABAAEBQRET1dOBQZTQ0FMRTgBCW1heEhlYWx0aAEFbGV2ZWwJAGQCAGQFBWxldmVsAQdsZXZlbFVwAgljdXJyTGV2ZWwFbmV3WFAECG5ld0xldmVsCQEJbGV2ZWxCeVhQAQUFbmV3WFAJAMwIAgUIbmV3TGV2ZWwJAMwIAgkAaAIFEm51bVBvaW50c09uTGV2ZWxVcAkAZQIFCG5ld0xldmVsBQljdXJyTGV2ZWwFA25pbAEMZ2V0RHVja1N0YXRzBA9zdGFraW5nQ29udHJhY3QLZHVja0Fzc2V0SWQKYnVmZkVmZmVjdApmb3JjZUJ1ZmZzBAVjaGFycwkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBDGtleUR1Y2tDaGFycwEFC2R1Y2tBc3NldElkAgkwXzBfMF8wXzACAV8EA2x2bAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9zdGFraW5nQ29udHJhY3QJAQxrZXlEdWNrTGV2ZWwBBQtkdWNrQXNzZXRJZAAABAZoZWFsdGgJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPc3Rha2luZ0NvbnRyYWN0CQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkCQEJbWF4SGVhbHRoAQUDbHZsBApzdGF0ZUJ1ZmZzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEMa2V5RHVja0J1ZmZzAQULZHVja0Fzc2V0SWQCCTBfMF8wXzBfMAIBXwkAzggCCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUMY2hhclN0cmVuZ3RoCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUMY2hhckFjY3VyYWN5CQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUNY2hhckludGVsbGVjdAkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDWNoYXJFbmR1cmFuY2UJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQ1jaGFyRGV4dGVyaXR5CQDMCAIFA2x2bAkAzAgCBQZoZWFsdGgFA25pbAMFCmZvcmNlQnVmZnMJAMwIAgUKYnVmZkVmZmVjdAkAzAgCBQpidWZmRWZmZWN0CQDMCAIFCmJ1ZmZFZmZlY3QJAMwIAgUKYnVmZkVmZmVjdAkAzAgCBQpidWZmRWZmZWN0BQNuaWwJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCnN0YXRlQnVmZnMFDGNoYXJTdHJlbmd0aAkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKc3RhdGVCdWZmcwUMY2hhckFjY3VyYWN5CQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpzdGF0ZUJ1ZmZzBQ1jaGFySW50ZWxsZWN0CQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpzdGF0ZUJ1ZmZzBQ1jaGFyRW5kdXJhbmNlCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpzdGF0ZUJ1ZmZzBQ1jaGFyRGV4dGVyaXR5BQNuaWwBDmdldFJvYmJlcnlEYXRhAg9zdGFraW5nQ29udHJhY3QLZHVja0Fzc2V0SWQEC2xhc3RSb2JDb3N0CQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBGGtleUxhc3RSb2JiZXJ5Q29zdEJ5RHVjawEFC2R1Y2tBc3NldElkAAAEC2xhc3RSb2JUaW1lCQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBGGtleUxhc3RSb2JiZXJ5VGltZUJ5RHVjawEFC2R1Y2tBc3NldElkAAAEA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAEB3JvYkNvc3QJAJYDAQkAzAgCBQ5yb2JiZXJ5Q29zdE1pbgkAzAgCCQBlAgULbGFzdFJvYkNvc3QJAGgCBRRyb2JiZXJ5Q29vbGRvd25Db2VmZgkAZQIFA25vdwULbGFzdFJvYlRpbWUFA25pbAQJZHVja1N0YXRlCQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBE2tleUR1Y2tSb2JiZXJ5U3RhdGUBBQtkdWNrQXNzZXRJZAAABApsb2NrZWRMYW5kCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBE2tleUxvY2tlZExhbmRCeUR1Y2sBBQtkdWNrQXNzZXRJZAIABAdsYW5kRVRBCQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBEmtleUxhbmRDb29sZG93bkVUQQEFCmxvY2tlZExhbmQAAAkAlwoFBQdyb2JDb3N0BQtsYXN0Um9iVGltZQUJZHVja1N0YXRlBQpsb2NrZWRMYW5kBQdsYW5kRVRBAApMQU5EUFJFRklYAgRMQU5EAApEVUNLUFJFRklYAgREVUNLAApBUlRQUkVTQUxFAgdQUkVTQUxFAAZOVU1SRVMABgAYTUFYX0xBTkRTX1NUQUtFRF9CWV9VU0VSABkAD0RBSUxZUkVTQllQSUVDRQCA+NIBAAxXSE1VTFRJUExJRVIAgMivoCUAD0RFRkFVTFRMT0NBVElPTgIPQWZyaWNhX0ZfQWZyaWNhABBSRVNPVVJDRVBSSUNFTUlOANW1AgAKRVNTRUxMQ09FRgAKABVNSU5fVVNEVF9GRUVfREVMSVZFUlkA0IYDABJURU5fTUlOVVRFU19NSUxMSVMAwM8kAAlwcm9kVHlwZXMJAMwIAgIQRmlyc3QgQWlkIEtpdCBMMQkAzAgCAhBGaXJzdCBBaWQgS2l0IEwyCQDMCAICEEZpcnN0IEFpZCBLaXQgTDMJAMwIAgILQmFja3BhY2sgTDEJAMwIAgILQmFja3BhY2sgTDIJAMwIAgILQmFja3BhY2sgTDMJAMwIAgIORm9vZCBSYXRpb24gTDEJAMwIAgIORm9vZCBSYXRpb24gTDIJAMwIAgIORm9vZCBSYXRpb24gTDMJAMwIAgILSmV0IFBhY2sgTDEJAMwIAgILSmV0IFBhY2sgTDIJAMwIAgILSmV0IFBhY2sgTDMJAMwIAgIJU2hpZWxkIEwxCQDMCAICCVNoaWVsZCBMMgkAzAgCAglTaGllbGQgTDMJAMwIAgIHTWluZSBMMQkAzAgCAgdNaW5lIEwyCQDMCAICB01pbmUgTDMJAMwIAgIHVHJhcCBMMQkAzAgCAgdUcmFwIEwyCQDMCAICB1RyYXAgTDMFA25pbAAKY29udGluZW50cwkAzAgCAghBbWVyaWNhcwkAzAgCAgZFdXJvcGUJAMwIAgIEQXNpYQkAzAgCAgZBZnJpY2EJAMwIAgIHT2NlYW5pYQUDbmlsAAlDT0VGRjJNQVQAgK3iBAAQZm9ydEFsbG93ZWRQcm9kcwkAzAgCAA8JAMwIAgAQCQDMCAIAEQkAzAgCABIJAMwIAgATCQDMCAIAFAUDbmlsABBwcm9kdWN0aW9uTWF0cml4CQDMCAICJThfOF84XzE3XzE3XzQyXzEyXzBfMzBfMCwwLDAsMCwwLDAsMF8JAMwIAgIlOF84XzhfMTdfMTdfNDJfMjRfMF82MF8wLDAsNSwyLDAsMCwwXwkAzAgCAic4XzhfOF8xN18xN180Ml8zNl8wXzEyMF8wLDAsMTAsNCwwLDAsMF8JAMwIAgIpOF8xOV8xOV84XzI3XzE5XzI2XzFfMjBfMCwwLDAsMCwwLDAsMF8wMDEJAMwIAgIpOF8xOV8xOV84XzI3XzE5XzUyXzFfNDBfMCwwLDAsMCwwLDAsMF8wMDEJAMwIAgIpOF8xOV8xOV84XzI3XzE5Xzc4XzFfODBfMCwwLDAsMCwwLDAsMF8wMDEJAMwIAgIlOF84XzhfOF84XzYwXzEzXzJfMl8wLDAsMCwwLDAsMCwwXzAxMQkAzAgCAiU4XzhfOF84XzhfNjBfMjZfMl80XzAsMCwwLDAsMCwwLDBfMDExCQDMCAICJThfOF84XzhfOF82MF8zOV8yXzhfMCwwLDAsMCwwLDAsMF8wMTEJAMwIAgIpMzBfMzBfM18xN18xN18zXzMwXzNfMzBfMCwwLDAsMCwwLDAsMF8xMTEJAMwIAgIpMzBfMzBfM18xN18xN18zXzYwXzNfNTBfMCwwLDAsMCwwLDAsMF8xMTEJAMwIAgIpMzBfMzBfM18xN18xN18zXzkwXzNfNzBfMCwwLDAsMCwwLDAsMF8xMTEJAMwIAgIrMThfMThfMTBfMThfMThfMThfMTFfNF8xMF8wLDAsMCwwLDAsMCwwXzIwMQkAzAgCAisxOF8xOF8xMF8xOF8xOF8xOF8yMl80XzIwXzAsMCwwLDAsMCwwLDBfMjAxCQDMCAICKzE4XzE4XzEwXzE4XzE4XzE4XzMzXzRfMzBfMCwwLDAsMCwwLDAsMF8yMDEJAMwIAgIqNF8xM18yMl80XzM1XzIyXzIzXzBfNTAsMSwwXzAsMCwwLDAsMCwwLDBfCQDMCAICKjRfMTNfMjJfNF8zNV8yMl80Nl8wXzUwLDEsMV8wLDIsNSwwLDAsMCwwXwkAzAgCAis0XzEzXzIyXzRfMzVfMjJfNjlfMF81MCwyLDFfMCw1LDEwLDAsMCwwLDBfCQDMCAICKjVfMjVfNDBfNV8xMF8xNV8yMF8xXzMwLDEsMV8wLDAsMCwwLDAsMCwwXwkAzAgCAio1XzI1XzQwXzVfMTBfMTVfNDBfMV8zMCwxLDJfMiwxLDMsMCwwLDAsMF8JAMwIAgIqNV8yNV80MF81XzEwXzE1XzYwXzFfMzAsMSwzXzUsMiw4LDAsMCwwLDBfBQNuaWwACXJJZHhDb2VmZgAGAApySWR4RWZmZWN0AAgAEHJJZHhSZXF1aXJlbWVudHMACQAJcklkeFNsb3RzAAoADlBST0RVQ1RQS0dTSVpFAAoAC3doSWR4TGV2ZWxzAAAACHdoSWR4UmVzAAEACHdoSWR4TWF0AAIACXdoSWR4UHJvZAADAAl3aElkeExPRlQABAAJdm9sTG9ja2VkAAAAC3ZvbE9jY3VwaWVkAAEAB3ZvbEZyZWUAAgAIdm9sVG90YWwAAwAKYnBJZHhMZXZlbAAAAAhicElkeFJlcwABAAhicElkeE1hdAACAAlicElkeFByb2QAAwAPbG9jSWR4Q29udGluZW50AAAACmxvY0lkeFR5cGUAAQAIbG9jSWR4SWQAAgEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQdhc3NldElkCQCsAgICA25vXwUHYXNzZXRJZAEaa2V5TGFuZEFzc2V0SWRUb0N1c3RvbU5hbWUBB2Fzc2V0SWQJAKwCAgIFbGNuYV8FB2Fzc2V0SWQBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBB2Fzc2V0SWQJAKwCAgIDc3RfBQdhc3NldElkASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIEdHlwZQdhc3NldElkCQC5CQIJAMwIAgIDbGFzCQDMCAIFBHR5cGUJAMwIAgUHYXNzZXRJZAUDbmlsAgFfASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwduZnRUeXBlB2Fzc2V0SWQJb3duZXJBZGRyCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIGc3R0YW9fBQduZnRUeXBlAgFfBQdhc3NldElkAgFfBQlvd25lckFkZHIBEmtleVdhcmVob3VzZUJ5TGFuZAELbGFuZEFzc2V0SWQJAKwCAgIDd2hfBQtsYW5kQXNzZXRJZAEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEHYXNzZXRJZAkArAICAgtpbmZyYUxldmVsXwUHYXNzZXRJZAEXa2V5Rm9ydGlmaWNhdGlvbnNCeUxhbmQBC2xhbmRBc3NldElkCQCsAgICD2ZvcnRpZmljYXRpb25zXwULbGFuZEFzc2V0SWQBGmtleUR1Y2tBc3NldElkVG9DdXN0b21OYW1lAQdhc3NldElkCQCsAgICGGR1Y2tDdXN0b21OYW1lQnlBc3NldElkXwUHYXNzZXRJZAEWa2V5QWRkcmVzc1RvQ3VzdG9tTmFtZQEEYWRkcgkArAICAhhhY2NvdW50Q3VzdG9tTmFtZUJ5QWRkcl8FBGFkZHIBD2tleUFkZHJlc3NSZWZCeQEEYWRkcgkArAICAglhY2NSZWZCeV8FBGFkZHIBHGtleU9uYm9hcmRBcnRBY3RpdmF0ZWRPbkR1Y2sBC2R1Y2tBc3NldElkCQCsAgICGm9uYm9hcmRBcnRBY3RpdmF0ZWRPbkR1Y2tfBQtkdWNrQXNzZXRJZAEca2V5T25ib2FyZEFydER1Y2tBY3RpdmF0ZWRCeQEEYWRkcgkArAICAhpvbmJvYXJkQXJ0QWN0aXZhdGVkRHVja0J5XwUEYWRkcgETa2V5QWRkcmVzc1JlZmVycmFscwEEYWRkcgkArAICAg1hY2NSZWZlcnJhbHNfBQRhZGRyARBrZXlEdWNrSWRUb093bmVyAQdhc3NldElkCQCsAgICCmR1Y2tPd25lcl8FB2Fzc2V0SWQBFGtleVN0YWtlZER1Y2tCeU93bmVyAQlvd25lckFkZHIJAKwCAgISc3Rha2VkRHVja0J5T3duZXJfBQlvd25lckFkZHIBEWtleUJhY2twYWNrQnlEdWNrAQtkdWNrQXNzZXRJZAkArAICAgliYWNrUGFja18FC2R1Y2tBc3NldElkAQ9rZXlEdWNrTG9jYXRpb24BC2R1Y2tBc3NldElkCQCsAgICDWR1Y2tMb2NhdGlvbl8FC2R1Y2tBc3NldElkARVrZXlVc2VyR3dsUmVsZWFzZVRpbWUBCHVzZXJBZGRyCQCsAgICGiVzJXNfX3VzZXJHd2xSZWxlYXNlVGltZV9fBQh1c2VyQWRkcgEOa2V5RXNXYXJlaG91c2UAAhplbWVyZ2VuY3lXYXJlaG91c2VQcm9kdWN0cwAPZGVsaXZlcnlGdW5kS2V5AgxkZWxpdmVyeUZ1bmQAEWRlbGl2ZXJ5TG9ja2VkS2V5Ag5kZWxpdmVyeUxvY2tlZAANbGFzdFRvdXJJZEtleQIOJXNfX2xhc3RUb3VySWQBFWtleVRvdXJTdGF0aWNEYXRhQnlJZAEDdElkCQCsAgICFiVzJWRfX3RvdXJTdGF0aWNEYXRhX18JAKQDAQUDdElkARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQN0SWQJAKwCAgIXJXMlZF9fdG91ckR5bmFtaWNEYXRhX18JAKQDAQUDdElkARprZXlCZXN0UmVzdWx0QnlUb3VyQW5kRHVjawIDdElkC2R1Y2tBc3NldElkCQC5CQIJAMwIAgIfJXMlZCVzX19iZXN0UmVzdWx0QnlUb3VyQW5kRHVjawkAzAgCCQCkAwEFA3RJZAkAzAgCBQtkdWNrQXNzZXRJZAUDbmlsAgJfXwAJaWR4U3RhdGljAAAACmlkeER5bmFtaWMAAQAKdFN0YXRpY0VuZAAGAA50RHluYW1pY1N0YXR1cwABAQtnZXRUb3VyRGF0YQIMdG91ckNvbnRyYWN0A3RJZAQGc3RhdGljCQC1CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQx0b3VyQ29udHJhY3QJARVrZXlUb3VyU3RhdGljRGF0YUJ5SWQBBQN0SWQJAKwCAgkArAICAhlFcnJvciByZWFkaW5nIHRvdXJuYW1lbnQgCQCkAwEFA3RJZAIFIGRhdGECAl9fBAdkeW5hbWljCQC8CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQx0b3VyQ29udHJhY3QJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUDdElkCQCsAgIJAKwCAgIZRXJyb3IgcmVhZGluZyB0b3VybmFtZW50IAkApAMBBQN0SWQCBSBkYXRhAgJfXwkAzAgCBQZzdGF0aWMJAMwIAgUHZHluYW1pYwUDbmlsAQ5pc0luVG91cm5hbWVudAIMdG91ckNvbnRyYWN0CGxvY2F0aW9uBAZsYXN0SWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUMdG91ckNvbnRyYWN0BQ1sYXN0VG91cklkS2V5AAAEA2xvYwkAtQkCBQhsb2NhdGlvbgIBXwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFDHRvdXJDb250cmFjdAUGbGFzdElkBAZzdGF0aWMJAJEDAgUFdERhdGEFCWlkeFN0YXRpYwQHZHluYW1pYwkAkQMCBQV0RGF0YQUKaWR4RHluYW1pYwMDAwkAAAIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFUCQAAAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2xvYwUPbG9jSWR4Q29udGluZW50BQZsYXN0SWQHCQAAAgkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwIKSU5QUk9HUkVTUwcJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBQp0U3RhdGljRW5kBQNub3cHAQxpc0luRGVsaXZlcnkBCGxvY2F0aW9uBANsb2MJALUJAgUIbG9jYXRpb24CAV8EA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAECXN0YXJ0VGltZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2xvYwUPbG9jSWR4Q29udGluZW50BAhkaXN0YW5jZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2xvYwUIbG9jSWR4SWQDAwkAAAIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFECQBmAgUDbm93CQBkAgUJc3RhcnRUaW1lBRJURU5fTUlOVVRFU19NSUxMSVMHCQBnAgADBQhkaXN0YW5jZQcBD2lzVXN1YWxMb2NhdGlvbgEIbG9jYXRpb24EB2xvY1R5cGUJAJEDAgkAtQkCBQhsb2NhdGlvbgIBXwUKbG9jSWR4VHlwZQMJAQIhPQIFB2xvY1R5cGUCAVQJAQIhPQIFB2xvY1R5cGUCAUQHAQxub3RPbk1pc3Npb24CDHRvdXJDb250cmFjdAhsb2NhdGlvbgQGbGFzdElkCQELdmFsdWVPckVsc2UCCQCaCAIFDHRvdXJDb250cmFjdAUNbGFzdFRvdXJJZEtleQAABANsb2MJALUJAgUIbG9jYXRpb24CAV8EA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAEBXREYXRhCQELZ2V0VG91ckRhdGECBQx0b3VyQ29udHJhY3QFBmxhc3RJZAQGc3RhdGljCQCRAwIFBXREYXRhBQlpZHhTdGF0aWMEB2R5bmFtaWMJAJEDAgUFdERhdGEFCmlkeER5bmFtaWMEB2xvY1R5cGUJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAwMJAQIhPQIFB2xvY1R5cGUCAVQJAQIhPQIFB2xvY1R5cGUCAUQHBgkBASEBAwMDCQAAAgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAVQJAAACCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDbG9jBQ9sb2NJZHhDb250aW5lbnQFBmxhc3RJZAcJAAACCQCRAwIFB2R5bmFtaWMFDnREeW5hbWljU3RhdHVzAgpJTlBST0dSRVNTBwkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFCnRTdGF0aWNFbmQFA25vdwcBEmdldFJlY2lwZU1hdGVyaWFscwEGcmVjaXBlCQBoAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnJlY2lwZQUJcklkeENvZWZmBQlDT0VGRjJNQVQBDGNoZWF0QXR0ZW1wdAIGb2xkTG9jBm5ld0xvYwkAAgEJAKwCAgkArAICCQCsAgICFkNoZWF0IGF0dGVtcHQ6IG9sZExvYz0FBm9sZExvYwIJLCBuZXdMb2M9BQZuZXdMb2MAFktTX1NFUEFSQVRFX1BVQkxJQ19LRVkHABhLU19BTExPV19CSUdfSU5GUkFfTUVSR0UHABFLU19BTExPV19ERUxJVkVSWQcABWNoYWluCQDJAQIJAMoBAggFBHRoaXMFYnl0ZXMAAQABAAt1c2R0QXNzZXRJZAQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAEghNp6sggDP07Ru8qO7ouTvMmC3Qtd+geWqNQj+agP/7kDCQAAAgEBVAUHJG1hdGNoMAEgVbHYn3KHgu/l41uNrAWrZd6aQ6EvFrsF8xq3h6XxxRgJAAIBAg1Vbmtub3duIGNoYWluABVkZWZhdWx0UmVzdEFkZHJlc3NTdHIEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDACIzNQUUN1dkZidmg0TGtQVW5yblUxejNqbmJBMXA5bTNXTmh2AwkAAAIBAVQFByRtYXRjaDACIzNNdW1rR0d6dENLQVhwV0RxeGtkZG9mcVhTVWJxUWt2U0p5CQACAQINVW5rbm93biBjaGFpbgARSW5mcmFVcGdyYWRlQ29zdFMEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDAAgMivoCUDCQAAAgEBVAUHJG1hdGNoMACAwtcvCQACAQINVW5rbm93biBjaGFpbgAOYXJiaXRyYWdlRGVsYXkEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDAAgLiZKQMJAAACAQFUBQckbWF0Y2gwAODUAwkAAgECDVVua25vd24gY2hhaW4AA1NFUAICX18ABU1VTFQ2AMCEPQAFTVVMVDgAgMLXLwAFU1NJWkUAGQAFTVNJWkUAZAAFTFNJWkUA4QEABlhMU0laRQCQAwAHWFhMU0laRQDxBAAFSVRFUjYJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUFA25pbAEPZ2V0U3RyaW5nT3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFB2FkZHJlc3MFA2tleQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQdhZGRyZXNzCQDMCAICAS4JAMwIAgUDa2V5CQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgAAEUlkeENmZ1N0YWtpbmdEYXBwAAEAEUlkeENmZ0Vjb25vbXlEYXBwAAIAFElkeENmZ0dvdmVybmFuY2VEYXBwAAMADUlkeENmZ1dsZ0RhcHAABAAUSWR4Q2ZnVG91cm5hbWVudERhcHAABwAPSWR4Q2ZnQWNyZXNEYXBwAAgBCmtleVJlc3RDZmcAAg4lc19fcmVzdENvbmZpZwEOa2V5UmVzdEFkZHJlc3MAAgwlc19fcmVzdEFkZHIBEXJlYWRSZXN0Q2ZnT3JGYWlsAQRyZXN0CQC8CQIJAQ9nZXRTdHJpbmdPckZhaWwCBQRyZXN0CQEKa2V5UmVzdENmZwAFA1NFUAEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgdyZXN0Q2ZnA2lkeAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUHcmVzdENmZwUDaWR4CQCsAgICKlJlc3QgY2ZnIGRvZXNuJ3QgY29udGFpbiBhZGRyZXNzIGF0IGluZGV4IAkApAMBBQNpZHgADHJlc3RDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEOa2V5UmVzdEFkZHJlc3MABRVkZWZhdWx0UmVzdEFkZHJlc3NTdHIAB3Jlc3RDZmcJARFyZWFkUmVzdENmZ09yRmFpbAEFDHJlc3RDb250cmFjdAAPc3Rha2luZ0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwURSWR4Q2ZnU3Rha2luZ0RhcHAAD2Vjb25vbXlDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFEUlkeENmZ0Vjb25vbXlEYXBwAAtnb3ZDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFFElkeENmZ0dvdmVybmFuY2VEYXBwAAt3bGdDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFDUlkeENmZ1dsZ0RhcHAAEnRvdXJuYW1lbnRDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFFElkeENmZ1RvdXJuYW1lbnREYXBwAA1hY3Jlc0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUPSWR4Q2ZnQWNyZXNEYXBwAApyZWNMYW5kTnVtAAAAC3JlY0xhbmRTaXplAAEAC3JlY1RlcnJhaW5zAAIADHJlY0NvbnRpbmVudAADAA13bGdBc3NldElkS2V5Agt3bGdfYXNzZXRJZAAKd2xnQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCcCAIFC3dsZ0NvbnRyYWN0BQ13bGdBc3NldElkS2V5AhhXTEdPTEQgaXMgbm90IGlzc3VlZCB5ZXQAD2FjcmVzQXNzZXRJZEtleQIMYWNyZXNBc3NldElkAAxhY3Jlc0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnAgCBQ1hY3Jlc0NvbnRyYWN0BQ9hY3Jlc0Fzc2V0SWRLZXkCF0FDUkVTIGlzIG5vdCBpc3N1ZWQgeWV0AAtyYW5kb21EZWxheQACAQlrZXlDb21taXQBB2FkZHJlc3MJAKwCAgITZmluaXNoQmxvY2tGb3JBZGRyXwUHYWRkcmVzcwERa2V5UmVzUHJvcG9ydGlvbnMAAhNyZXNUeXBlc1Byb3BvcnRpb25zARZrZXlSZXNUeXBlc0J5Q29udGluZW50AQljb250aW5lbnQJAKwCAgIUcmVzVHlwZXNCeUNvbnRpbmVudF8FCWNvbnRpbmVudAEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQlvd25lckFkZHIJAKwCAgITc3Rha2VkTGFuZHNCeU93bmVyXwUJb3duZXJBZGRyARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQlvd25lckFkZHIJAKwCAgIUc3Rha2VkUGllY2VzQnlPd25lcl8FCW93bmVyQWRkcgEIYXNTdHJpbmcBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwBQFzCQACAQIYZmFpbCB0byBjYXN0IGludG8gU3RyaW5nAQVhc0ludAEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgNJbnQEAW4FByRtYXRjaDAFAW4JAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBCWFzQm9vbGVhbgEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgdCb29sZWFuBAFzBQckbWF0Y2gwBQFzCQACAQIZZmFpbCB0byBjYXN0IGludG8gQm9vbGVhbgEQYXNTdHJpbmdJbnRUdXBsZQEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAINKFN0cmluZywgSW50KQQCdDIFByRtYXRjaDAFAnQyCQACAQIfZmFpbCB0byBjYXN0IGludG8gKFN0cmluZywgSW50KQEPbnVtUGllY2VzQnlTaXplAQhsYW5kU2l6ZQQHJG1hdGNoMAUIbGFuZFNpemUDCQAAAgIBUwUHJG1hdGNoMAUFU1NJWkUDCQAAAgIBTQUHJG1hdGNoMAUFTVNJWkUDCQAAAgIBTAUHJG1hdGNoMAUFTFNJWkUDCQAAAgICWEwFByRtYXRjaDAFBlhMU0laRQMJAAACAgNYWEwFByRtYXRjaDAFB1hYTFNJWkUJAAIBAhFVbmtub3duIGxhbmQgc2l6ZQEHaXNEaWdpdAEBcwkBCWlzRGVmaW5lZAEJALYJAQUBcwEKa2V5QmxvY2tlZAACEGNvbnRyYWN0c0Jsb2NrZWQBEWtleUxhc3RUeElkQnlVc2VyAQRhZGRyCQCsAgICD2xhc3RUeElkQnlVc2VyXwUEYWRkcgEKZml4ZWRQb2ludAIDdmFsCGRlY2ltYWxzBAZ0ZW5Qb3cJAGwGAAoAAAUIZGVjaW1hbHMAAAAABQRET1dOBAdsb3dQYXJ0CQCkAwEJAGoCBQN2YWwFBnRlblBvdwQGemVyb2VzCQCwAgIJAKQDAQUGdGVuUG93CQBkAgABCQCxAgEFB2xvd1BhcnQJAKwCAgkArAICCQCsAgIJAKQDAQkAaQIFA3ZhbAUGdGVuUG93AgEuBQZ6ZXJvZXMFB2xvd1BhcnQBD2dldFJhbmRvbU51bWJlcgMIbWF4VmFsdWUMZmluaXNoSGVpZ2h0CmF1eEVudHJvcHkED3JhbmRvbVNlZWRCbG9jawkBBXZhbHVlAQkA7QcBBQxmaW5pc2hIZWlnaHQECnJhbmRvbUhhc2gJAPcDAQkAywECCQEFdmFsdWUBCAUPcmFuZG9tU2VlZEJsb2NrA3ZyZgUKYXV4RW50cm9weQkAagIJALEJAQUKcmFuZG9tSGFzaAUIbWF4VmFsdWUADWluY3ViYXRvckFkZHIEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDAJARFAZXh0ck5hdGl2ZSgxMDYyKQECIzNQRWt0VnV4MlJoY2hTTjYzRHNEbzRiNG16NFFxektTZUR2AwkAAAIBAVQFByRtYXRjaDAFBHRoaXMJAAIBAg1Vbmtub3duIGNoYWluAAticmVlZGVyQWRkcgQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAkBEUBleHRyTmF0aXZlKDEwNjIpAQIjM1BEVnVVNDVIN0VoNWRtdE5iblJOUlN0R3dVTEE3Tlk2SGIDCQAAAgEBVAUHJG1hdGNoMAUEdGhpcwkAAgECDVVua25vd24gY2hhaW4AA3B1YgQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAMFFktTX1NFUEFSQVRFX1BVQkxJQ19LRVkBIKsXV48VZ+NZVEGw1nLrZpvEo9NmXtWZhlDfmDcfsgkIASBPU+IaP1So1p1SThMdRidVvbNT8yx7yVRUsP9DwbQUKAMJAAACAQFUBQckbWF0Y2gwASBPU+IaP1So1p1SThMdRidVvbNT8yx7yVRUsP9DwbQUKAkAAgECDVVua25vd24gY2hhaW4ADEVNUFRZX1BST0Q1MAGQAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEUZJVkVNSU5VVEVTTUlMTElTAOCnEgAMUkVOQU1JTkdDT1NUAMCWsQIACk1BWE5BTUVMRU4AMgAVSW5mcmFVcGdyYWRlQ29zdFNVc2R0AICt4gQADEVYUE1BVEVSSUFMUwQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMACm3YLtqwcDCQAAAgEBVAUHJG1hdGNoMACqp4GzCQkAAgECDVVua25vd24gY2hhaW4AB0VYUFVTRFQEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDAAgOWadwMJAAACAQFUBQckbWF0Y2gwAIDlmncJAAIBAg1Vbmtub3duIGNoYWluAAxTX0NPU1RfQUNSRVMAgPKLqAkABUZJVkVYCQC2AgEABQAHVFdFTlRZWAkAtgIBABQACFRXRU5UWTJYCQC2AgEJAGgCABQAFAAIVFdFTlRZM1gJALYCAQkAaAIJAGgCABQAFAAUAAhUV0VOVFk0WAkAtgIBCQBoAgkAaAIJAGgCABQAFAAUABQACFRXRU5UWTVYCQC2AgEJAGgCCQBoAgkAaAIJAGgCABQAFAAUABQAFAAPUFJFU0FMRU5VTUxBTkRTAPQDARJrZXlOZXh0RnJlZUxhbmROdW0AAgtuZXh0TGFuZE51bQEaa2V5TGFuZEN1c3RvbU5hbWVUb0Fzc2V0SWQBBG5hbWUJAKwCAgIEbGNuXwUEbmFtZQEQa2V5TGFuZFRvQXNzZXRJZAEHbGFuZE51bQkArAICAgNsYV8FB2xhbmROdW0BHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIHYXNzZXRJZAlvd25lckFkZHIJAKwCAgkArAICCQCsAgICBWlsYW9fBQdhc3NldElkAgFfBQlvd25lckFkZHIBEWtleUxhbmROdW1Ub093bmVyAQdsYW5kTnVtCQCsAgICA2xvXwUHbGFuZE51bQEaa2V5RHVja0N1c3RvbU5hbWVUb0Fzc2V0SWQBBG5hbWUJAKwCAgIRZHVja0J5Q3VzdG9tTmFtZV8FBG5hbWUBFmtleUN1c3RvbU5hbWVUb0FkZHJlc3MBBG5hbWUJAKwCAgIUYWNjb3VudEJ5Q3VzdG9tTmFtZV8FBG5hbWUBCWtleU9sZGllcwACCm9sZGllc0xpc3QAC2NsYWltTW9kZVdoAAAADWNsYWltTW9kZUR1Y2sAAQATY2xhaW1Nb2RlV2hUaGVuRHVjawACAAhmbEhlYWx0aAAAAAtmbFRpbWVzdGFtcAAFAAdmbEJvbnVzAAYAC2ZsUHJvZHNVc2VkAAcBB25mdE5hbWUCB2xhbmROdW0IbGFuZFNpemUJAKwCAgkArAICBQpMQU5EUFJFRklYBQdsYW5kTnVtBQhsYW5kU2l6ZQEIdG9Wb2x1bWUCBmFtb3VudAdwa2dTaXplBARwa2dzAwkAZwIFBmFtb3VudAAACQBpAgkAZQIJAGQCBQZhbW91bnQFB3BrZ1NpemUAAQUHcGtnU2l6ZQkBAS0BCQBpAgkAZQIJAGQCCQEBLQEFBmFtb3VudAUHcGtnU2l6ZQABBQdwa2dTaXplCQBoAgUEcGtncwUFTVVMVDgBE2Rpc3RyaWJ1dGVCeVdlaWdodHMCBXRvdGFsB3dlaWdodHMEA3N1bQkAZAIJAGQCCQBkAgkAZAIJAGQCCQCRAwIFB3dlaWdodHMAAAkAkQMCBQd3ZWlnaHRzAAEJAJEDAgUHd2VpZ2h0cwACCQCRAwIFB3dlaWdodHMAAwkAkQMCBQd3ZWlnaHRzAAQJAJEDAgUHd2VpZ2h0cwAFAwkAZwIAAAUDc3VtCQACAQIQWmVybyB3ZWlnaHRzIHN1bQQFbm9ybTYJAGsDBQV0b3RhbAUFTVVMVDYFA3N1bQoBCm5vcm1hbGl6ZXICA2FjYwRlbGVtCQDNCAIFA2FjYwkAawMFBGVsZW0FBW5vcm02BQVNVUxUNgoAAiRsBQd3ZWlnaHRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpub3JtYWxpemVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGARJnZXROZWVkZWRNYXRlcmlhbHMBBXRvdGFsBAVwcm9wcwkAtQkCCQEFdmFsdWUBCQCiCAEJARFrZXlSZXNQcm9wb3J0aW9ucwACAV8DCQECIT0CCQCQAwEFBXByb3BzBQZOVU1SRVMJAAIBAhZXcm9uZyBwcm9wb3J0aW9ucyBkYXRhBAFyCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAACQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwABCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwACCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwADCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAECQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAFBQNuaWwJARNkaXN0cmlidXRlQnlXZWlnaHRzAgUFdG90YWwFAXIBEXN1YnRyYWN0TWF0ZXJpYWxzAwxzaG91bGRVc2VNYXQDaGFzCXRvdGFsTmVlZAQEbmVlZAkBEmdldE5lZWRlZE1hdGVyaWFscwEFCXRvdGFsTmVlZAoBCnN1YnRyYWN0b3ICA2FjYwNpZHgEBnJlc3VsdAkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNoYXMFA2lkeAkAkQMCBQRuZWVkBQNpZHgDCQBmAgAABQZyZXN1bHQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIYTm90IGVub3VnaCBtYXRlcmlhbCBpZHg9CQCkAwEFA2lkeAILLCB5b3UgaGF2ZSAJAJEDAgUDaGFzBQNpZHgCCywgYnV0IG5lZWQgCQCkAwEJAJEDAgUEbmVlZAUDaWR4CQDNCAIFA2FjYwkApAMBBQZyZXN1bHQDBQxzaG91bGRVc2VNYXQKAAIkbAUFSVRFUjYKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCnN1YnRyYWN0b3ICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYFA2hhcwERc3VidHJhY3RFcXVpcG1lbnQCBW9sZEVxBXBVc2VkAwkAAAIFBXBVc2VkAgAJAJQKAgUFb2xkRXEHCgEHc3ViVXNlZAIDYWNjBmlkeEFtdAQFcGFydHMJALUJAgUGaWR4QW10AgEsAwkBAiE9AgkAkAMBBQVwYXJ0cwACCQACAQIoSW5jb3JyZWN0IGZvcm1hdCwgc2hvdWxkIGJlIGluZGV4LGFtb3VudAQDaWR4CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAAMDCQBmAgAABQNpZHgGCQBnAgUDaWR4CQCQAwEFEHByb2R1Y3Rpb25NYXRyaXgJAAIBAhNVbmtub3duIHByb2R1Y3QgaWR4BANhbXQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwYXJ0cwABBAdlcVBhcnRzCQC1CQIIBQNhY2MCXzEJAKwCAgkAkQMCBQVwYXJ0cwAAAgE6AwkBAiE9AgkAkAMBBQdlcVBhcnRzAAIJAAIBCQCsAgIJAKwCAgIPWW91IGRvbid0IGhhdmUgCQCRAwIFCXByb2RUeXBlcwUDaWR4AgkgZXF1aXBwZWQEA3RtcAkAkQMCBQdlcVBhcnRzAAEEBm51bUxlbgMJAQdpc0RpZ2l0AQkArwICCQCwAgIFA3RtcAABAAEAAgABBARjdXJyCQENcGFyc2VJbnRWYWx1ZQEJAK8CAgUDdG1wBQZudW1MZW4EBHRhaWwJALACAgUDdG1wBQZudW1MZW4EBm5ld0FtdAMJAGcCBQRjdXJyBQNhbXQJAGUCBQRjdXJyBQNhbXQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgINWW91IGVxdWlwcGVkIAkApAMBBQRjdXJyAgQgb2YgCQCRAwIFCXByb2RUeXBlcwUDaWR4AhMsIGJ1dCB0cmllZCB0byB1c2UgCQCkAwEFA2FtdAkAlAoCCQCsAgIJAKwCAgkArAICCQCsAgIJAJEDAgUHZXFQYXJ0cwAACQCRAwIFBXBhcnRzAAACAToJAKQDAQUGbmV3QW10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Y2tTdGF0cwhvY2N1cGllZARmcmVlBAVwYXJ0cwkAtQkCBQZpZHhDbnQCAToDCQECIT0CCQCQAwEFBXBhcnRzAAIJAAIBAihJbmNvcnJlY3QgZm9ybWF0LCBzaG91bGQgYmUgaW5kZXg6YW1vdW50AwMJAQEhAQUKaXNQb3NpdGl2ZQkBAiE9AgkAsQIBCQCRAwIFBXBhcnRzAAAAAgcJAAIBAitQcm9kdWN0IGlkeCBzaG91bGQgYmUgMiBkaWdpdHMsIHplcm8gcGFkZGVkBApwcm9kdWN0SWR4CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAAQFY291bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwYXJ0cwABAwkBASEBCQEPY29udGFpbnNFbGVtZW50AgUQZm9ydEFsbG93ZWRQcm9kcwUKcHJvZHVjdElkeAkAAgEJAKwCAgkArAICAglQcm9kdWN0ICcJAJEDAgUJcHJvZFR5cGVzBQpwcm9kdWN0SWR4AiEnIGNhbm5vdCBiZSB1c2VkIGZvciBsYW5kIGRlZmVuc2UDCQBmAgAABQVjb3VudAkAAgECF0NvdW50IGNhbid0IGJlIG5lZ2F0aXZlAwkAZgIFBWNvdW50BQ1NQVhQUk9ESU5TTE9UCQACAQkArAICCQCsAgIJAKwCAgIUQ2FuJ3QgcHV0IG1vcmUgdGhhbiAJAKQDAQUNTUFYUFJPRElOU0xPVAIEIG9mIAkAkQMCBQlwcm9kVHlwZXMFCnByb2R1Y3RJZHgDCQAAAgUFY291bnQAAAkAlQoDBQVwTGlzdAUIb2NjdXBpZWQFBGZyZWUEBGhlYWQJAMkBAgUFcExpc3QJAGgCAAgFCnByb2R1Y3RJZHgEBGN1cnIJALEJAQkAyQECCQDKAQIFBXBMaXN0CQBoAgAIBQpwcm9kdWN0SWR4AAgEBHRhaWwJAMoBAgUFcExpc3QJAGgCAAgJAGQCBQpwcm9kdWN0SWR4AAEEBnJlY2lwZQkAtQkCCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgFCnByb2R1Y3RJZHgCAV8DAwkBASEBBQppc1Bvc2l0aXZlCQBmAgUFY291bnQFBGN1cnIHCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCVlvdSBoYXZlIAkApAMBBQRjdXJyAgQgb2YgCQCRAwIFCXByb2RUeXBlcwUKcHJvZHVjdElkeAITLCBidXQgdHJpZWQgdG8gdXNlIAkApAMBBQVjb3VudAQGbmV3QW10AwMJAQEhAQUKaXNQb3NpdGl2ZQkBFWNoZWNrU3RhdFJlcXVpcmVtZW50cwIFCWR1Y2tTdGF0cwkAtQkCCQCRAwIFBnJlY2lwZQUQcklkeFJlcXVpcmVtZW50cwIBLAcJAGUCBQRjdXJyBQVjb3VudAkAZAIFBGN1cnIFBWNvdW50BAhkZWx0YVZvbAkAZQIJAQh0b1ZvbHVtZQIFBm5ld0FtdAUOUFJPRFVDVFBLR1NJWkUJAQh0b1ZvbHVtZQIFBGN1cnIFDlBST0RVQ1RQS0dTSVpFCQCVCgMJAMsBAgkAywECBQRoZWFkCQCaAwEFBm5ld0FtdAUEdGFpbAkAZAIFCG9jY3VwaWVkBQhkZWx0YVZvbAkAZQIFBGZyZWUFCGRlbHRhVm9sAQhhZGRQcm9kQgcGaWR4Q250BXBMaXN0CmlzUG9zaXRpdmUHc2VnbWVudAdtYWluQXV4BHNsb3QJZHVja1N0YXRzBAVwYXJ0cwkAtQkCBQZpZHhDbnQCAToDCQECIT0CCQCQAwEFBXBhcnRzAAIJAAIBAihJbmNvcnJlY3QgZm9ybWF0LCBzaG91bGQgYmUgaW5kZXg6YW1vdW50AwMJAQEhAQUKaXNQb3NpdGl2ZQkBAiE9AgkAsQIBCQCRAwIFBXBhcnRzAAAAAgcJAAIBAitQcm9kdWN0IGlkeCBzaG91bGQgYmUgMiBkaWdpdHMsIHplcm8gcGFkZGVkBApwcm9kdWN0SWR4CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAAQFY291bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwYXJ0cwABAwMJAGYCAAAFCnByb2R1Y3RJZHgGCQBnAgUKcHJvZHVjdElkeAkAkAMBBRBwcm9kdWN0aW9uTWF0cml4CQACAQITVW5rbm93biBwcm9kdWN0IGlkeAMJAGYCAAAFBWNvdW50CQACAQIXQ291bnQgY2FuJ3QgYmUgbmVnYXRpdmUDCQBmAgUFY291bnQFDU1BWFBST0RJTlNMT1QJAAIBCQCsAgIJAKwCAgkArAICAhRDYW4ndCBwdXQgbW9yZSB0aGFuIAkApAMBBQ1NQVhQUk9ESU5TTE9UAgQgb2YgCQCRAwIFCXByb2RUeXBlcwUKcHJvZHVjdElkeAMJAAACBQVjb3VudAAACQCUCgIFBXBMaXN0BwQEaGVhZAkAyQECBQVwTGlzdAkAaAIACAUKcHJvZHVjdElkeAQEY3VycgkAsQkBCQDJAQIJAMoBAgUFcExpc3QJAGgCAAgFCnByb2R1Y3RJZHgACAQEdGFpbAkAygECBQVwTGlzdAkAaAIACAkAZAIFCnByb2R1Y3RJZHgAAQQGcmVjaXBlCQC1CQIJAJEDAgUQcHJvZHVjdGlvbk1hdHJpeAUKcHJvZHVjdElkeAIBXwMDCQEBIQEFCmlzUG9zaXRpdmUJAGYCBQVjb3VudAUEY3VycgcJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIJWW91IGhhdmUgCQCkAwEFBGN1cnICBCBvZiAJAJEDAgUJcHJvZFR5cGVzBQpwcm9kdWN0SWR4AhMsIGJ1dCB0cmllZCB0byB1c2UgCQCkAwEFBWNvdW50BAlpc0JpZ0l0ZW0DAwkBASEBBQppc1Bvc2l0aXZlCQEVY2hlY2tTdGF0UmVxdWlyZW1lbnRzAgUJZHVja1N0YXRzCQC1CQIJAJEDAgUGcmVjaXBlBRBySWR4UmVxdWlyZW1lbnRzAgEsBwQGY29tcGF0CQCRAwIFBnJlY2lwZQUJcklkeFNsb3RzAwkAAAIFBmNvbXBhdAIACQACAQIXSXRlbSBjYW5ub3QgYmUgZXF1aXBwZWQEAWMJAQ1wYXJzZUludFZhbHVlAQUGY29tcGF0BARjU2VnCQBpAgUBYwBkAwkBAiE9AgUHc2VnbWVudAUEY1NlZwkAAgECFFNlZ21lbnQgaW5jb21wYXRpYmxlBAhjTWFpbkF1eAkAaQIJAGoCBQFjAGQACgMJAQIhPQIFB21haW5BdXgFCGNNYWluQXV4CQACAQIRU2xvdCBpbmNvbXBhdGlibGUECWNOdW1TbG90cwkAagIFAWMACgMDCQECIT0CBQRzbG90AAAJAGYCBQljTnVtU2xvdHMAAQcJAAIBAh5CaWcgaXRlbXMgc2hvdWxkIG9jY3VweSBzbG90IDAJAGYCBQljTnVtU2xvdHMAAQcJAJQKAgkAywECCQDLAQIFBGhlYWQJAJoDAQkAZAIFBGN1cnIDBQppc1Bvc2l0aXZlBQVjb3VudAkBAS0BBQVjb3VudAUEdGFpbAUJaXNCaWdJdGVtAQtzbG90c0dyb3VwQgYBZwRicEluCmlzUG9zaXRpdmUHc2VnbWVudAdtYWluQXV4BXN0YXRzAwkBAiE9AgUBZwIABAVzbG90cwkAtQkCBQFnAgEsAwkAZgIJAJADAQUFc2xvdHMFCE1BWFNMT1RTCQACAQISV3Jvbmcgc2xvdHMgZm9ybWF0BAJzMAkAkQMCBQVzbG90cwAABAJzMQMJAGYCCQCQAwEFBXNsb3RzAAEJAJEDAgUFc2xvdHMAAQIAAwMJAAACBQJzMAIACQAAAgUCczECAAcFBGJwSW4EBXRtcFMwAwkBAiE9AgUCczACAAkBCGFkZFByb2RCBwUCczAFBGJwSW4FCmlzUG9zaXRpdmUFB3NlZ21lbnQFB21haW5BdXgAAAUFc3RhdHMJAJQKAgUEYnBJbgcDCQECIT0CBQJzMQIAAwgFBXRtcFMwAl8yCQACAQIeQmlnIGl0ZW0gYWxyZWFkeSBvY2N1cGllcyBzbG90CAkBCGFkZFByb2RCBwUCczEIBQV0bXBTMAJfMQUKaXNQb3NpdGl2ZQUHc2VnbWVudAUHbWFpbkF1eAABBQVzdGF0cwJfMQgFBXRtcFMwAl8xBQRicEluAQZkcmVzc0IEB3NlZ0xpc3QGcEJ5dGVzCmlzUG9zaXRpdmUFc3RhdHMKAQdzZWdtZW50AgNhY2MDc2VnBAFqCAUDYWNjAl8xBAdtYWluQXV4CQC1CQIFA3NlZwIBOwMJAQIhPQIJAJADAQUHbWFpbkF1eAUKTlVNTUFJTkFVWAkAAgECFFdyb25nIHNlZ21lbnQgZm9ybWF0BAFtCQCRAwIFB21haW5BdXgAAAQBYQkAkQMCBQdtYWluQXV4AAEDAwkAAAIFAW0CAAkAAAIFAWECAAcJAJQKAgkAZAIFAWoAAQgFA2FjYwJfMgQEdG1wTQkBC3Nsb3RzR3JvdXBCBgUBbQgFA2FjYwJfMgUKaXNQb3NpdGl2ZQUBagAABQVzdGF0cwkAlAoCCQBkAgUBagABCQELc2xvdHNHcm91cEIGBQFhBQR0bXBNBQppc1Bvc2l0aXZlBQFqAAEFBXN0YXRzCAoAAiRsBQdzZWdMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCAAAFBnBCeXRlcwoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHc2VnbWVudAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgJfMgEFZm9ydEIGB3NlZ0xpc3QGcEJ5dGVzCG9jY3VwaWVkBGZyZWUKaXNQb3NpdGl2ZQlkdWNrU3RhdHMDCQBmAgADCQCQAwEFB3NlZ0xpc3QJAAIBAjFBdCBsZWFzdCBkdWNrLCBtaW5lcyBhbmQgdHJhcHMgcGFydHMgYXJlIHJlcXVpcmVkCgEHc2VnbWVudAIDYWNjA3NlZwQBaggFA2FjYwJfMQMJAAACBQFqAAAJAJYKBAkAZAIFAWoAAQgFA2FjYwJfMggFA2FjYwJfMwgFA2FjYwJfNAQBcAkBCnBsYWNlUHJvZEIGBQNzZWcIBQNhY2MCXzIFCmlzUG9zaXRpdmUFCWR1Y2tTdGF0cwgFA2FjYwJfMwgFA2FjYwJfNAkAlgoECQBkAgUBagABCAUBcAJfMQgFAXACXzIIBQFwAl8zBAF0CgACJGwFB3NlZ0xpc3QKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCWCgQAAAUGcEJ5dGVzBQhvY2N1cGllZAUEZnJlZQoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHc2VnbWVudAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgkAlQoDCAUBdAJfMggFAXQCXzMIBQF0Al80ARdjYW5XZWFyQ3VycmVudEVxdWlwbWVudAELZHVja0Fzc2V0SWQEBWVxS2V5CQEQa2V5RHVja0VxdWlwbWVudAEFC2R1Y2tBc3NldElkBAZjdXJyRXEJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQVlcUtleQIXLDssXyw7LF8sOyxfLDssXyw7LF8sOywCAV8ECXRlbXBQcm9kQgkBBmRyZXNzQgQFBmN1cnJFcQUMRU1QVFlfUFJPRDUwBgUDbmlsBAhzZWdCcEF1eAkAkQMCCQC1CQIJAJEDAgUGY3VyckVxBQtzZWdCYWNrcGFjawIBOwABBApidWZmRWZmZWN0AwkAAAIFCHNlZ0JwQXV4AgAAAAQEYXV4MAkAkQMCCQC1CQIFCHNlZ0JwQXV4AgEsAAADCQAAAgUEYXV4MAIAAAAEBmlkeENudAkAtQkCBQRhdXgwAgE6BANpZHgJAJEDAgUGaWR4Q250AAAEA2NudAkAkQMCBQZpZHhDbnQAAQMDAwMDCQAAAgUDaWR4AgIwNgYJAAACBQNpZHgCAjA3BgkAAAIFA2lkeAICMDgJAQIhPQIFA2NudAIABwkAZgIJAQ1wYXJzZUludFZhbHVlAQUDY250AAAHCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkAtQkCCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgJAQ1wYXJzZUludFZhbHVlAQUDaWR4AgFfBQpySWR4RWZmZWN0AAAEBXN0YXRzCQEMZ2V0RHVja1N0YXRzBAUEdGhpcwULZHVja0Fzc2V0SWQFCmJ1ZmZFZmZlY3QGBAhuZXdQcm9kQgkBBmRyZXNzQgQFBmN1cnJFcQUJdGVtcFByb2RCBwUFc3RhdHMJAAACBQhuZXdQcm9kQgUIbmV3UHJvZEIBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwECHByb3BMaXN0DXRlcnJhaW5Db3VudHMNbGFuZFNpemVJbmRleARzaWduAwkBAiE9AgkAkAMBBQhwcm9wTGlzdAUGTlVNUkVTCQACAQIWV3JvbmcgcHJvcG9ydGlvbnMgZGF0YQoBB3VwZGF0ZXICA2FjYwFpBAZyZXN1bHQJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIcHJvcExpc3QFAWkJAGgCCQBoAgUEc2lnbgkAkQMCBQ10ZXJy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bG9mdAkAtQkCCQCRAwIFAndoBQl3aElkeExPRlQCAV8ECHdoTG9ja2VkCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAUJdm9sTG9ja2VkBANvY2MDCQBmAgkAkAMBBQRsb2Z0AAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAUKd2hPY2N1cGllZAkAuQkCCQDMCAIJAKQDAQUId2hMb2NrZWQJAMwIAgkApAMBBQNvY2MJAMwIAgkApAMBCQBlAgkAZQIFB3doVG90YWwFCHdoTG9ja2VkBQNvY2MJAMwIAgkApAMBBQd3aFRvdGFsBQNuaWwCAV8JAMwIAgkAkQMCBQJ3aAULd2hJZHhMZXZlbHMJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQJ3aAUId2hJZHhSZXMCAV8FBk5VTVJFUwkAkQMCBQJ3aAUId2hJZHhSZXMCCzBfMF8wXzBfMF8wCQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUCd2gFCHdoSWR4TWF0AgFfBQZOVU1SRVMJAJEDAgUCd2gFCHdoSWR4TWF0AgswXzBfMF8wXzBfMAkAzAgCCQCRAwIFAndoBQl3aElkeFByb2QJAMwIAgUGd2hMb2Z0BQNuaWwBFWdldFdhcmVob3VzZVNwYWNlTGVmdAEJY3VycmVudFdoBAtvY2N1cGllZFZvbAkBF2dldFdhcmVob3VzZU9jY3VwaWVkVm9sAQUJY3VycmVudFdoBA9jdXJyV2hMb2NrZWRWb2wJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQC1CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeExPRlQCAV8FCXZvbExvY2tlZAkAZQIJAGUCCQEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBCQCRAwIFCWN1cnJlbnRXaAULd2hJZHhMZXZlbHMFC29jY3VwaWVkVm9sBQ9jdXJyV2hMb2NrZWRWb2wBCW1vdmVTdHVmZgMKY2FyZ29QYXJ0cwljdXJyZW50V2gLY3VycmVudFBhY2sDCQECIT0CCQCQAwEFCmNhcmdvUGFydHMAAwkAAgECNGNhcmdvTGlzdFN0ciBzaG91bGQgY29udGFpbiBleGFjdGx5IDIgJzonIHNlcGFyYXRvcnMECHJlc1BhcnRzCQC1CQIJAJEDAgUKY2FyZ29QYXJ0cwAAAgFfBAhtYXRQYXJ0cwkAtQkCCQCRAwIFCmNhcmdvUGFydHMAAQIBXwQJcHJvZFBhcnRzAwkAAAIJAJEDAgUKY2FyZ29QYXJ0cwACAgAFA25pbAkAvAkCCQCRAwIFCmNhcmdvUGFydHMAAgIBXwMJAQIhPQIJAJADAQUIcmVzUGFydHMFBk5VTVJFUwkAAgECIEFsbCA2IHJlc291cmNlcyBzaG91bGQgYmUgcGFzc2VkAwkBAiE9AgkAkAMBBQhtYXRQYXJ0cwUGTlVNUkVTCQACAQIgQWxsIDYgbWF0ZXJpYWxzIHNob3VsZCBiZSBwYXNzZWQEC3doU3BhY2VMZWZ0CQEVZ2V0V2FyZWhvdXNlU3BhY2VMZWZ0AQUJY3VycmVudFdoBAljdXJyV2hSZXMJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfBAljdXJyV2hNYXQJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4TWF0AgFfBApjdXJyV2hQcm9kAwkAAAIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAV8EDmN1cnJlbnRQYWNrUmVzCQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzAgFfBA5jdXJyZW50UGFja01hdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQPY3VycmVudFBhY2tQcm9kAwkAAAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIABQNuaWwJALwJAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgFfCgEDbXZSAgNhY2MEaXRlbQQBaQgFA2FjYwJfMQQCYW0JAQ1wYXJzZUludFZhbHVlAQUEaXRlbQQDd2hyCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJY3VycldoUmVzBQFpBANicHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5jdXJyZW50UGFja1JlcwUBaQMJAAACBQJhbQAACQCWCgQJAGQCBQFpAAEJAM0IAggFA2FjYwJfMgkAkQMCBQljdXJyV2hSZXMFAWkJAM0IAggFA2FjYwJfMwkAkQMCBQ5jdXJyZW50UGFja1JlcwUBaQgFA2FjYwJfNAMJAGYCBQJhbQAAAwkAZgIFAmFtBQNicHIJAAIBCQCsAgIJAKwCAgkArAICCQCsAgICEEF0dGVtcHQgdG8gdGFrZSAFBGl0ZW0CGSBmcm9tIGJhY2twYWNrLCBidXQgb25seSAJAKQDAQUDYnByAgogYXZhaWxhYmxlCQCWCgQJAGQCBQFpAAEJAM0IAggFA2FjYwJfMgkApAMBCQBkAgUDd2hyBQJhbQkAzQgCCAUDYWNjAl8zCQCkAwEJAGUCBQNicHIFAmFtCQBkAggFA2FjYwJfNAUCYW0DCQBmAgkBAS0BBQJhbQUDd2hyCQACAQkArAICCQCsAgIJAKwCAgkArAICAhBBdHRlbXB0IHRvIHRha2UgCQCkAwEJAQEtAQUCYW0CGiBmcm9tIHdhcmVob3VzZSwgYnV0IG9ubHkgCQCkAwEFA3docgIKIGF2YWlsYWJsZQkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZAIFA3docgUCYW0JAM0IAggFA2FjYwJfMwkApAMBCQBlAgUDYnByBQJhbQkAZAIIBQNhY2MCXzQFAmFtBAFyCgACJGwFCHJlc1BhcnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlgoEAAAFA25pbAUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBA212UgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgoBA212TQIDYWNjBGl0ZW0EAWkIBQNhY2MCXzEEAmFtCQENcGFyc2VJbnRWYWx1ZQEFBGl0ZW0EA3dobQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWN1cnJXaE1hdAUBaQQDYnBtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOY3VycmVudFBhY2tNYXQFAWkDCQAAAgUCYW0AAAkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAJEDAgUJY3VycldoTWF0BQFpCQDNCAIIBQNhY2MCXzMJAJEDAgUOY3VycmVudFBhY2tNYXQFAWkIBQNhY2MCXzQDCQBmAgUCYW0AAAMJAGYCBQJhbQUDYnBtCQACAQkArAICCQCsAgIJAKwCAgkArAICAhBBdHRlbXB0IHRvIHRha2UgBQRpdGVtAhkgZnJvbSBiYWNrcGFjaywgYnV0IG9ubHkgCQCkAwEFA2JwbQIKIGF2YWlsYWJsZQkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZAIFA3dobQUCYW0JAM0IAggFA2FjYwJfMwkApAMBCQBlAgUDYnBtBQJhbQkAZAIIBQNhY2MCXzQFAmFtAwkAZgIJAQEtAQUCYW0FA3dobQkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byB0YWtlIAkApAMBCQEBLQEFAmFtAhogZnJvbSB3YXJlaG91c2UsIGJ1dCBvbmx5IAkApAMBBQN3aG0CCiBhdmFpbGFibGUJAJYKBAkAZAIFAWkAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGQCBQN3aG0FAmFtCQDNCAIIBQNhY2MCXzMJAKQDAQkAZQIFA2JwbQUCYW0JAGQCCAUDYWNjAl80BQJhbQQBbQoAAiRsBQhtYXRQYXJ0cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJYKBAAABQNuaWwFA25pbAgFAXICXzQKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBA212TQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMV8yAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgoBA212UAIDYWNjBGl0ZW0EAWkIBQNhY2MCXzEEAmFtCQENcGFyc2VJbnRWYWx1ZQEFBGl0ZW0EA3docAMJAGYCCQCQAwEFCmN1cnJXaFByb2QFAWkJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpjdXJyV2hQcm9kBQFpAAAEA2JwcAMJAGYCCQCQAwEFD2N1cnJlbnRQYWNrUHJvZAUBaQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD2N1cnJlbnRQYWNrUHJvZAUBaQAAAwkAAAIFAmFtAAAJAJYKBAkAZAIFAWkAAQkAzQgCCAUDYWNjAl8yCQCkAwEFA3docAkAzQgCCAUDYWNjAl8zCQCkAwEFA2JwcAgFA2FjYwJfNAMJAGYCBQJhbQAAAwkAZgIFAmFtBQNicHAJAAIBCQCsAgIJAKwCAgkArAICCQCsAgICEEF0dGVtcHQgdG8gdGFrZSAFBGl0ZW0CGSBmcm9tIGJhY2twYWNrLCBidXQgb25seSAJAKQDAQUDYnBwAgogYXZhaWxhYmxlBAhkZWx0YVZvbAkAZQIJAQh0b1ZvbHVtZQIJAGQCBQN3aHAFAmFtBQ5QUk9EVUNUUEtHU0laRQkBCHRvVm9sdW1lAgUDd2hwBQ5QUk9EVUNUUEtHU0laRQkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZAIFA3docAUCYW0JAM0IAggFA2FjYwJfMwkApAMBCQBlAgUDYnBwBQJhbQkAZAIIBQNhY2MCXzQFCGRlbHRhVm9sAwkAZgIJAQEtAQUCYW0FA3docAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byB0YWtlIAkApAMBCQEBLQEFAmFtAhogZnJvbSB3YXJlaG91c2UsIGJ1dCBvbmx5IAkApAMBBQN3aHACCiBhdmFpbGFibGUECGRlbHRhVm9sCQBlAgkBCHRvVm9sdW1lAgkAZAIFA3docAUCYW0FDlBST0RVQ1RQS0dTSVpFCQEIdG9Wb2x1bWUCBQN3aHAFDlBST0RVQ1RQS0dTSVpFCQCWCgQJAGQCBQFpAAEJAM0IAggFA2FjYwJfMgkApAMBCQBkAgUDd2hwBQJhbQkAzQgCCAUDYWNjAl8zCQCkAwEJAGUCBQNicHAFAmFtCQBkAggFA2FjYwJfNAUIZGVsdGFWb2wEAXADCQECIT0CCQCQAwEFCXByb2RQYXJ0cwAACgACJGwFCXByb2RQYXJ0cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJYKBAAABQNuaWwFA25pbAgFAW0CXzQKAQUkZjJfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBA212UAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMl8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjJfMgIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyCQCWCgQAAAUKY3VycldoUHJvZAUPY3VycmVudFBhY2tQcm9kCAUBbQJfNAQIdm9sU2FsZG8IBQFwAl80AwkAZgIFCHZvbFNhbGRvBQt3aFNwYWNlTGVmdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIVQXR0ZW1wdCB0byBwdXQgdG90YWwgCQCkAwEFCHZvbFNhbGRvAhEgc3R1ZmYsIGJ1dCBvbmx5IAkApAMBBQt3aFNwYWNlTGVmdAIVIHdhcmVob3VzZSBzcGFjZSBsZWZ0CQCZCgcJALkJAggFAXICXzICAV8JALkJAggFAW0CXzICAV8JALoJAggFAXACXzICAV8JALkJAggFAXICXzMCAV8JALkJAggFAW0CXzMCAV8JALoJAggFAXACXzMCAV8FCHZvbFNhbGRvARJleHBlZGl0aW9uSW50ZXJuYWwCBmNhbGxlcgR0eElkBAh1c2VyQWRkcgkApQgBBQZjYWxsZXIEBmJpZ051bQkBA2FicwEJAJ4DAQUEdHhJZAQHZnJlZU51bQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQESa2V5TmV4dEZyZWVMYW5kTnVtAAkAZAIFD1BSRVNBTEVOVU1MQU5EUwABBAdsYW5kTnVtCQCkAwEFB2ZyZWVOdW0EDGNvbnRpbmVudElkeAkAoAMBCQC7AgIFBmJpZ051bQUFRklWRVgECHRlcnJhaW5zCQELZ2VuVGVycmFpbnMCBQZiaWdOdW0FDGNvbnRpbmVudElkeAQJY29udGluZW50CQCRAwIFCmNvbnRpbmVudHMFDGNvbnRpbmVudElkeAQFaXNzdWUJAMIIBQkBB25mdE5hbWUCBQdsYW5kTnVtAgFTCQC5CQIJAMwIAgUHbGFuZE51bQkAzAgCAgFTCQDMCAIFCHRlcnJhaW5zCQDMCAIFCWNvbnRpbmVudAUDbmlsAgFfAAEAAAcEB2Fzc2V0SWQJALgIAQUFaXNzdWUEAmlkCQDYBAEFB2Fzc2V0SWQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmtleU5leHRGcmVlTGFuZE51bQAJAGQCBQdmcmVlTnVtAAEJAMwIAgUFaXNzdWUJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGtleUxhbmRUb0Fzc2V0SWQBBQdsYW5kTnVtBQJpZAkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQUCaWQFCHVzZXJBZGRyCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlMYW5kTnVtVG9Pd25lcgEFB2xhbmROdW0FCHVzZXJBZGRyCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFAmlkAAAJAMwIAgkBDEludGVnZXJFbnRyeQIJAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICBQJpZAUIdXNlckFkZHIAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZjYWxsZXIAAQUHYXNzZXRJZAUDbmlsCQCUCgIFAmlkBQljb250aW5lbnQBDGZsaWdodENvbW1vbgMIdXNlckFkZHIHbWVzc2FnZQNzaWcDCQEBIQEJAMQTAwUHbWVzc2FnZQUDc2lnBQNwdWIJAAIBAhhzaWduYXR1cmUgZG9lcyBub3QgbWF0Y2gEBXBhcnRzCQC8CQIJALAJAQUHbWVzc2FnZQIBOwQJZmxpZ2h0TG9nCQC8CQIJAJEDAgUFcGFydHMAAAIBfAQCaHAJALUJAgkAkQMCBQlmbGlnaHRMb2cFCGZsSGVhbHRoAgFfBAVjdXJIUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmhwAAAEBW5ld0hQCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCaHAAAQQLbmV3TG9jVHhWZXIJALUJAgkAkQMCBQVwYXJ0cwABAgE6BAtuZXdMb2NhdGlvbgkAkQMCBQtuZXdMb2NUeFZlcgAABAR0aW1lCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZmxpZ2h0TG9nBQtmbFRpbWVzdGFtcAMDCQBmAgUEdGltZQkAZAIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBRFGSVZFTUlOVVRFU01JTExJUwYJAGYCCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFEUZJVkVNSU5VVEVTTUlMTElTBQR0aW1lCQACAQkArAICCQCsAgIJAKwCAgIcc2lnbmF0dXJlIG91dGRhdGVkOiBsb2dUaW1lPQkApAMBBQR0aW1lAgksIGJjVGltZT0JAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAECXR4RnJvbU1zZwkAkQMCBQtuZXdMb2NUeFZlcgABBAZsYXN0VHgJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBEWtleUxhc3RUeElkQnlVc2VyAQUIdXNlckFkZHICAAMJAQIhPQIFBmxhc3RUeAUJdHhGcm9tTXNnCQACAQkArAICCQCsAgIJAKwCAgIeVHggaWRzIGRvbid0IG1hdGNoISBJbiBzdGF0ZTogBQZsYXN0VHgCCiwgaW4gbXNnOiAFCXR4RnJvbU1zZwQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQh1c2VyQWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAVtYXhIUAkBCW1heEhlYWx0aAEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDGtleUR1Y2tMZXZlbAEFC2R1Y2tBc3NldElkAAAEDG9sZEZyb21TdGF0ZQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgFBW1heEhQAwkBAiE9AgUMb2xkRnJvbVN0YXRlBQVjdXJIUAkAAgEJAKwCAgkArAICCQCsAgICCm9sZEhlYWx0aD0JAKQDAQUMb2xkRnJvbVN0YXRlAi8gZnJvbSBzdGF0ZSBkb2VzIG5vdCBtYXRjaCBvbmUgZnJvbSBmbGlnaHQgbG9nPQkApAMBBQVjdXJIUAMJAGcCAAAFBWN1ckhQCQACAQIeWW91IGNhbid0IGZseSB3aXRoIHplcm8gaGVhbHRoAwkBASEBCQEXY2FuV2VhckN1cnJlbnRFcXVpcG1lbnQBBQtkdWNrQXNzZXRJZAkAAgECFkVxdWlwbWVudCBpbmNvbXBhdGlibGUEBWJvbnVzAwkAZgIJAJADAQUJZmxpZ2h0TG9nBQdmbEJvbnVzCQCRAwIFCWZsaWdodExvZwUHZmxCb251cwIABAhwcm9kVXNlZAMJAGYCCQCQAwEFCWZsaWdodExvZwULZmxQcm9kc1VzZWQJAJEDAgUJZmxpZ2h0TG9nBQtmbFByb2RzVXNlZAIABApzZW50QW1vdW50AwMJAGYCBQVuZXdIUAAACQAAAgUFYm9udXMCASQHCQEFYXNJbnQBCQD8BwQFDHJlc3RDb250cmFjdAINc2VuZFVzZHRQcml6ZQkAzAgCBQh1c2VyQWRkcgUDbmlsBQNuaWwAAAkAlwoFBQVuZXdIUAULZHVja0Fzc2V0SWQFCnNlbnRBbW91bnQFC25ld0xvY2F0aW9uBQhwcm9kVXNlZAEMYXBwbHlCb251c2VzAgtsYW5kQXNzZXRJZAZwaWVjZXMECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAlhcnRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQAAAQEYWRkNgkAaQIFCmluZnJhTGV2ZWwABgQEYWRkNwkAaQIFCmluZnJhTGV2ZWwABwkAZAIJAGQCBQ9EQUlMWVJFU0JZUElFQ0UJAGsDBQ9EQUlMWVJFU0JZUElFQ0UJAGQCCQBkAgUKaW5mcmFMZXZlbAUEYWRkNgkAaAIAAgUEYWRkNwAFCQBrAwUPREFJTFlSRVNCWVBJRUNFBQlhcnRQaWVjZXMJAGgCBQZwaWVjZXMABQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBGFkZHIJY2xhaW1Nb2RlDWxhbmRBc3NldElkSW4EDSR0MDMzNzM4MzQyNzcDCQAAAgUJY2xhaW1Nb2RlBQtjbGFpbU1vZGVXaAkAlAoCBQ1sYW5kQXNzZXRJZEluCQELdmFsdWVPckVsc2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgQDbG9jCQC1CQIJAQV2YWx1ZQEFC2N1ckxvY2F0aW9uAgFfAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUwJAAIBCQCsAgIJAKwCAgIWRHVjayBsb2NhdGlvbiB0eXBlIGlzIAkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCESwgYnV0IHNob3VsZCBiZSBMCQCUCgIJAJEDAgUDbG9jBQhsb2NJZHhJZAULZHVja0Fzc2V0SWQEC2xhbmRBc3NldElkCAUNJHQwMzM3MzgzNDI3NwJfMQQGZHVja0lkCAUNJHQwMzM3MzgzNDI3NwJfMgQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAQJc2F2ZWRUaW1lCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUHdGltZUtleQkArAICCQCsAgICBUxhbmQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAFkCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwkAlgoEBQZkdWNrSWQFC2xhbmRBc3NldElkBQFkBQlzYXZlZFRpbWUBEGNsYWltUmVzSW50ZXJuYWwEBGFkZHIGYW1vdW50CWNsYWltTW9kZQ1sYW5kQXNzZXRJZEluAwkAZgIAAAUGYW1vdW50CQACAQIPTmVnYXRpdmUgYW1vdW50BAFjCQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBQRhZGRyBQljbGFpbU1vZGUFDWxhbmRBc3NldElkSW4ECGxhbmRTaXplCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBCQCRAwIIBQFjAl8zBQtyZWNUZXJyYWlucwQJZGVsdGFUaW1lCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAIBQFjAl80AwkAZgIAAAUJZGVsdGFUaW1lCQACAQkArAICCQCsAgIJAKwCAgImU2F2ZWQgdGltZXN0YW1wIGlzIGluIGZ1dHVyZSwgc2F2ZWQgPSAJAKQDAQgFAWMCXzQCDCwgY3VycmVudCA9IAkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQUIbGFuZFNpemUEFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAQxhcHBseUJvbnVzZXMCCAUBYwJfMgUGcGllY2VzBAhhdmFpbFJlcwkAawMFCWRlbHRhVGltZQkAaAIFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UFBnBpZWNlcwUJREFZTUlMTElTAwkAZgIFBmFtb3VudAUIYXZhaWxSZXMJAAIBCQCsAgIJAKwCAgkArAICAiJOb3QgZW5vdWdoIHJlc291cmNlcywgYXZhaWxhYmxlID0gCQCkAwEFCGF2YWlsUmVzAg4sIHJlcXVlc3RlZCA9IAkApAMBBQZhbW91bnQEDG5ld0RlbHRhVGltZQkAawMJAGUCBQhhdmFpbFJlcwUGYW1vdW50BQlEQVlNSUxMSVMJAGgCBRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBQZwaWVjZXMEDG5ld1RpbWVzdGFtcAkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQxuZXdEZWx0YVRpbWUECWxhbmRJbmRleAkAaQIFBnBpZWNlcwUFU1NJWkUECnJlc1RvQ2xhaW0JAQl2aXJ0Q2xhaW0EBQ10ZXJyYWluQ291bnRzCQBlAgUJZGVsdGFUaW1lBQxuZXdEZWx0YVRpbWUFCWxhbmRJbmRleAUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBCAUBYwJfMgQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEIBQFjAl8yAAAECWN1cnJlbnRXaAkBDGdldFdhcmVob3VzZQMFBXdoS2V5BQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwEBGxvZnQJALUJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4TE9GVAIBXwQLd2hTcGFjZUxlZnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlAwMJAAACBQljbGFpbU1vZGUFC2NsYWltTW9kZVdoCQBmAgUGYW1vdW50BQt3aFNwYWNlTGVmdAcJAAIBCQCsAgIJAKwCAgIFT25seSAJAKQDAQULd2hTcGFjZUxlZnQCGCBzcGFjZSBsZWZ0IGluIHdhcmVob3VzZQQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEIBQFjAl8xBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEDmN1cnJlbnRQYWNrUmVzCQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzAgFfBAxjdXJyZW50V2hSZXMJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfBA0kdDAzNjY1MTM3NTIyAwkAAAIFCWNsYWltTW9kZQULY2xhaW1Nb2RlV2gJAJYKBAkBBmFkZFJlcwUFDGN1cnJlbnRXaFJlcwUNdGVycmFpbkNvdW50cwkAZQIFCWRlbHRhVGltZQUMbmV3RGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFC3ZvbE9jY3VwaWVkCAUKcmVzVG9DbGFpbQJfMgkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlCAUKcmVzVG9DbGFpbQJfMgMJAAACBQljbGFpbU1vZGUFDWNsYWltTW9kZUR1Y2sJAJYKBAkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzCQEGYWRkUmVzBQUOY3VycmVudFBhY2tSZXMFDXRlcnJhaW5Db3VudHMJAGUCBQlkZWx0YVRpbWUFDG5ld0RlbHRhVGltZQUJbGFuZEluZGV4BRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlBAVkaXN0cgkBDWRpc3RyaWJ1dGVSZXMEBQxjdXJyZW50V2hSZXMFDmN1cnJlbnRQYWNrUmVzBQpyZXNUb0NsYWltBQt3aFNwYWNlTGVmdAQEd2hBbQkAlwMBCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlCQDMCAIIBQpyZXNUb0NsYWltAl8yBQNuaWwJAJYKBAgFBWRpc3RyAl8xCAUFZGlzdHICXzIJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQFBHdoQW0JAGUCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAUHdm9sRnJlZQUEd2hBbQQFd2hSZXMIBQ0kdDAzNjY1MTM3NTIyAl8xBAVicFJlcwgFDSR0MDM2NjUxMzc1MjICXzIEBWxvZnRPCAUNJHQwMzY2NTEzNzUyMgJfMwQFbG9mdEYIBQ0kdDAzNjY1MTM3NTIyAl80CQCXCgUJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQgFAWMCXzIFDG5ld1RpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYCAUBYwJfMgUEYWRkcgUMbmV3VGltZXN0YW1wBQNuaWwFBWJwS2V5CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgUFYnBSZXMJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwFBXdoS2V5CQDMCAIJAJEDAgUJY3VycmVudFdoBQt3aElkeExldmVscwkAzAgCBQV3aFJlcwkAzAgCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhNYXQJAMwIAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAkAzAgCCQC5CQIJAMwIAgkAkQMCBQRsb2Z0BQl2b2xMb2NrZWQJAMwIAgkApAMBBQVsb2Z0TwkAzAgCCQCkAwEFBWxvZnRGCQDMCAIJAJEDAgUEbG9mdAUIdm9sVG90YWwFA25pbAIBXwUDbmlsAQhjbGFpbUFsbAQEYWRkcgtsYW5kQXNzZXRJZAZwaWVjZXMJY2xhaW1Nb2RlBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBAlzYXZlZFRpbWUJAQV2YWx1ZQEJAJ8IAQUHdGltZUtleQQIYXZhaWxSZXMJAGgCCQBrAwkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQlzYXZlZFRpbWUJAQxhcHBseUJvbnVzZXMCBQtsYW5kQXNzZXRJZAUGcGllY2VzBQlEQVlNSUxMSVMFBnBpZWNlcwkBEGNsYWltUmVzSW50ZXJuYWwEBQRhZGRyBQhhdmFpbFJlcwUJY2xhaW1Nb2RlBQtsYW5kQXNzZXRJZAENdXBJbmZyYUNvbW1vbgQMc2hvdWxkVXNlTWF0BmNhbGxlcg1wYXltZW50QW1vdW50C2xhbmRBc3NldElkBARhZGRyCQClCAEFBmNhbGxlcgQBYwkBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwUEYWRkcgUTY2xhaW1Nb2RlV2hUaGVuRHVjawULbGFuZEFzc2V0SWQEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAggFAWMCXzMFC3JlY0xhbmRTaXplBAhpbmZyYUtleQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBCAUBYwJfMgQIY3VyTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUIaW5mcmFLZXkAAAMDCQEBIQEFGEtTX0FMTE9XX0JJR19JTkZSQV9NRVJHRQkAZwIFCGN1ckxldmVsAAMHCQACAQImQ3VycmVudGx5IG1heCBpbmZyYXN0cnVjdHVyZSBsZXZlbCA9IDMECG1heEluZnJhCQBkAgkAaQIJAQRzcXJ0BAUGcGllY2VzAAAAAAUERE9XTgAFAAIECG5ld0xldmVsCQBkAgUIY3VyTGV2ZWwAAQMDBRhLU19BTExPV19CSUdfSU5GUkFfTUVSR0UJAGYCBQhuZXdMZXZlbAUIbWF4SW5mcmEHCQACAQkArAICAiVDdXJyZW50bHkgbWF4IGluZnJhc3RydWN0dXJlIGxldmVsID0gCQCkAwEFCG1heEluZnJhBARjb3N0CQBrAwUVSW5mcmFVcGdyYWRlQ29zdFNVc2R0CQBoAgUGcGllY2VzBQhuZXdMZXZlbAUFU1NJWkUDAwkBASEBBQxzaG91bGRVc2VNYXQJAQIhPQIFDXBheW1lbnRBbW91bnQFBGNvc3QHCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUEY29zdAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEIBQFjAl8xBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBW1MaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBAdtYXRVc2VkCQBrAwURSW5mcmFVcGdyYWRlQ29zdFMJAGgCBQZwaWVjZXMFCG5ld0xldmVsBQVTU0laRQQGbmV3TWF0CQC5CQIJARFzdWJ0cmFjdE1hdGVyaWFscwMFDHNob3VsZFVzZU1hdAUFbUxpc3QFB21hdFVzZWQCAV8EC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwEBQRhZGRyCAUBYwJfMgUGcGllY2VzBRNjbGFpbU1vZGVXaFRoZW5EdWNrBAZ3aERhdGEIBQtjbGFpbVJlc3VsdAJfNQQGb2xkVm9sCQEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBCQCRAwIFBndoRGF0YQULd2hJZHhMZXZlbHMECm5ld1ZvbERhdGEJALkJAgkAzAgCCQCRAwIJALUJAgkAkQMCBQZ3aERhdGEFC3doSWR4TGV2ZWxzAgFfAAAJAMwIAgkApAMBBQhuZXdMZXZlbAUDbmlsAgFfBAZuZXdWb2wJARdnZXRXYXJlaG91c2VUb3RhbFZvbHVtZQEFCm5ld1ZvbERhdGEEBGxvZnQJALUJAgkAkQMCBQZ3aERhdGEFCXdoSWR4TE9GVAIBXwQKbmV3TG9mdFN0cgkAuQkCCQDMCAIJAJEDAgUEbG9mdAUJdm9sTG9ja2VkCQDMCAIJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQJAMwIAgkApAMBCQBlAgkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlBQZuZXdWb2wFBm9sZFZvbAkAzAgCCQCkAwEFBm5ld1ZvbAUDbmlsAgFfCQCVCgMJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUIaW5mcmFLZXkFCG5ld0xldmVsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAggFAWMCXzIFBGFkZHIFCG5ld0xldmVsCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIIBQtjbGFpbVJlc3VsdAJfMwUIYnBJZHhSZXMJAMwIAgUGbmV3TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6CQDMCAIJAQtTdHJpbmdFbnRyeQIIBQtjbGFpbVJlc3VsdAJfNAkAuQkCCQDMCAIFCm5ld1ZvbERhdGEJAMwIAgkAkQMCBQZ3aERhdGEFCHdoSWR4UmVzCQDMCAIJAJEDAgUGd2hEYXRhBQh3aElkeE1hdAkAzAgCCQCRAwIFBndoRGF0YQUJd2hJZHhQcm9kCQDMCAIFCm5ld0xvZnRTdHIFA25pbAIBOgUDbmlsCAULY2xhaW1SZXN1bHQCXzEFCG5ld0xldmVsBQdtYXRVc2VkARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAILZHVja0Fzc2V0SWQHZGVsdGFYUAQGbHZsS2V5CQEMa2V5RHVja0xldmVsAQULZHVja0Fzc2V0SWQEBXhwS2V5CQEJa2V5RHVja1hQAQULZHVja0Fzc2V0SWQEAnhwCQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAUFeHBLZXkAAAQFbmV3WFAJAGQCBQJ4cAUHZGVsdGFYUAQJbHZsUG9pbnRzCQEHbGV2ZWxVcAIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPc3Rha2luZ0NvbnRyYWN0BQZsdmxLZXkAAAUFbmV3WFAECWtleVBvaW50cwkBEWtleUR1Y2tGcmVlUG9pbnRzAQULZHVja0Fzc2V0SWQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUGbHZsS2V5CQCRAwIFCWx2bFBvaW50cwAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBQV4cEtleQUFbmV3WFAJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleVBvaW50cwkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5UG9pbnRzAAAJAJEDAgUJbHZsUG9pbnRzAAEFA25pbAUFbmV3WFABFnVwZGF0ZUFjY1N0YXRzSW50ZXJuYWwCBGFkZHIHZGVsdGFYUAQGbHZsS2V5CQEMa2V5VXNlckxldmVsAQUEYWRkcgQFeHBLZXkJAQlrZXlVc2VyWFABBQRhZGRyBAJ4cAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9zdGFraW5nQ29udHJhY3QFBXhwS2V5AAAEBW5ld1hQCQBkAgUCeHAFB2RlbHRhWFAECWx2bFBvaW50cwkBB2xldmVsVXACCQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAUGbHZsS2V5AAAFBW5ld1hQBAlrZXlQb2ludHMJARFrZXlVc2VyRnJlZVBvaW50cwEFBGFkZHIJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUGbHZsS2V5CQCRAwIFCWx2bFBvaW50cwAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBQV4cEtleQUFbmV3WFAJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleVBvaW50cwkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5UG9pbnRzAAAJAJEDAgUJbHZsUG9pbnRzAAEFA25pbAUFbmV3WFABEmFjdGl2YXRlT25ib2FyZEFydAEEYWRkcgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAhyZWZCeUtleQkBD2tleUFkZHJlc3NSZWZCeQEFBGFkZHIEBXJlZkJ5CQCiCAEFCHJlZkJ5S2V5AwkBASEBCQEJaXNEZWZpbmVkAQUFcmVmQnkJAAIBAilZb3UgYXJlIG5vdCBlbGlnaWJsZSBmb3IgT05CT0FSRCBhcnRpZmFjdAQGYXJ0S2V5CQEca2V5T25ib2FyZEFydER1Y2tBY3RpdmF0ZWRCeQEFBGFkZHIEB2FydER1Y2sJAKIIAQUGYXJ0S2V5AwkBCWlzRGVmaW5lZAEFB2FydER1Y2sJAAIBCQCsAgICL1lvdSBhbHJlYWR5IHVzZWQgeW91ciBPTkJPQVJEIGFydGlmYWN0IG9uIGR1Y2sgCQEFdmFsdWUBBQdhcnREdWNrBBBkdWNrQWN0aXZhdG9yS2V5CQEca2V5T25ib2FyZEFydEFjdGl2YXRlZE9uRHVjawEFC2R1Y2tBc3NldElkBA1kdWNrQWN0aXZhdG9yCQCiCAEFEGR1Y2tBY3RpdmF0b3JLZXkDCQEJaXNEZWZpbmVkAQUNZHVja0FjdGl2YXRvcgkAAgEJAKwCAgkArAICCQCsAgICCVRoZSBkdWNrIAULZHVja0Fzc2V0SWQCNCBhbHJlYWR5IGdvdCBwb2ludHMgZnJvbSBPTkJPQVJEIGFydGlmYWN0IGZyb20gdXNlciAJAQV2YWx1ZQEFDWR1Y2tBY3RpdmF0b3IJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQZhcnRLZXkFC2R1Y2tBc3NldElkCQDMCAIJAQtTdHJpbmdFbnRyeQIFEGR1Y2tBY3RpdmF0b3JLZXkFBGFkZHIFA25pbAgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkBQl4cE9uYm9hcmQCXzEBEmFjdGl2YXRlUHJlc2FsZUFydAIEYWRkcg1sYW5kQXNzZXRJZEluBAFjCQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBQRhZGRyBRNjbGFpbU1vZGVXaFRoZW5EdWNrBQ1sYW5kQXNzZXRJZEluBAtsYW5kQXNzZXRJZAgFAWMCXzIEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAggFAWMCXzMFC3JlY0xhbmRTaXplBA1hY3RpdmF0aW9uS2V5CQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAMJAGYCCQELdmFsdWVPckVsc2UCCQCfCAEFDWFjdGl2YXRpb25LZXkAAAAACQACAQIlUHJlc2FsZSBhcnRpZmFjdCBpcyBhbHJlYWR5IGFjdGl2YXRlZAMJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAggFAWMCXzMFCnJlY0xhbmROdW0FD1BSRVNBTEVOVU1MQU5EUwkAAgEJAKwCAgkArAICCQCsAgIFCkxBTkRQUkVGSVgCASAFC2xhbmRBc3NldElkAiUgaXMgbm90IGVsaWdpYmxlIGZvciBwcmVzYWxlIGFydGlmYWN0BAtjbGFpbVJlc3VsdAkBCGNsYWltQWxsBAUEYWRkcgULbGFuZEFzc2V0SWQFBnBpZWNlcwUTY2xhaW1Nb2RlV2hUaGVuRHVjawkAzQgCCQDNCAIJAM0IAggFC2NsYWltUmVzdWx0Al8xCQEMSW50ZWdlckVudHJ5AgUNYWN0aXZhdGlvbktleQUGcGllY2VzCQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzIJALkJAggFC2NsYWltUmVzdWx0Al8zAgE6CQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzQJALkJAggFC2NsYWltUmVzdWx0Al81AgE6AQ9jaGVja1RvdXJuYW1lbnQBC2R1Y2tBc3NldElkBAZsYXN0SWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUSdG91cm5hbWVudENvbnRyYWN0BQ1sYXN0VG91cklkS2V5AAAEC2N1ckxvY2F0aW9uCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04CAV8EA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAEBXREYXRhCQELZ2V0VG91ckRhdGECBRJ0b3VybmFtZW50Q29udHJhY3QFBmxhc3RJZAQGc3RhdGljCQCRAwIFBXREYXRhBQlpZHhTdGF0aWMEB2R5bmFtaWMJAJEDAgUFdERhdGEFCmlkeER5bmFtaWMDCQECIT0CCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlAgFUBwMDAwkAAAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQtjdXJMb2NhdGlvbgUPbG9jSWR4Q29udGluZW50BQZsYXN0SWQJAAACCQCRAwIFB2R5bmFtaWMFDnREeW5hbWljU3RhdHVzAgpJTlBST0dSRVNTBwkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFCnRTdGF0aWNFbmQFA25vdwcJAAIBAipZb3VyIGR1Y2sgaXMgdGFraW5nIHBhcnQgaW4gdGhlIHRvdXJuYW1lbnQJAQlhc0Jvb2xlYW4BCQD8BwQFBHRoaXMCFmV4aXRUb3VybmFtZW50SW50ZXJuYWwJAMwIAgULZHVja0Fzc2V0SWQFA25pbAUDbmlsAQ1jaGVja0RlbGl2ZXJ5AQtkdWNrQXNzZXRJZAMJAQEhAQURS1NfQUxMT1dfREVMSVZFUlkHBAtjdXJMb2NhdGlvbgkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OAgFfBANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wAwkBAiE9AgkAkQMCBQtjdXJMb2NhdGlvbgUKbG9jSWR4VHlwZQIBRAcECXN0YXJ0VGltZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFC2N1ckxvY2F0aW9uBQ9sb2NJZHhDb250aW5lbnQECGRpc3RhbmNlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgULY3VyTG9jYXRpb24FCGxvY0lkeElkAwMJAGYCBQNub3cJAGQCBQlzdGFydFRpbWUFElRFTl9NSU5VVEVTX01JTExJUwkAZgIAAwUIZGlzdGFuY2UHCQACAQIgWW91ciBkdWNrIGlzIG9uIGRlbGl2ZXJ5IG1pc3Npb24JAQlhc0Jvb2xlYW4BCQD8BwQFBHRoaXMCFGV4aXREZWxpdmVyeUludGVybmFsCQDMCAIFC2R1Y2tBc3NldElkBQNuaWwFA25pbAESZXhpdERlbGl2ZXJ5Q29tbW9uAQtkdWNrQXNzZXRJZAQLY3VyTG9jYXRpb24JALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgIBXwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQJc3RhcnRUaW1lCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgULY3VyTG9jYXRpb24FD2xvY0lkeENvbnRpbmVudAQIZGlzdGFuY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQtjdXJMb2NhdGlvbgUIbG9jSWR4SWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBEGtleUR1Y2tJZFRvT3duZXIBBQtkdWNrQXNzZXRJZAIUTkZUIGR1Y2sgaXMgb3JwaGFuZWQECWhlYWx0aEtleQkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAQJY3VySGVhbHRoCQERQGV4dHJOYXRpdmUoMTA1NSkBBQloZWFsdGhLZXkEDm91dGNvbWVBY3Rpb25zAwkAZwIFCGRpc3RhbmNlAAMEBnJld2FyZAkA/AcEBQ9lY29ub215Q29udHJhY3QCEnNlbmREZWxpdmVyeVJld2FyZAkAzAgCBQVvd25lcgUDbmlsBQNuaWwDCQAAAgUGcmV3YXJkBQZyZXdhcmQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMJAGYCBQNub3cJAGQCBQlzdGFydFRpbWUFElRFTl9NSU5VVEVTX01JTExJUwkAAgECJllvdXIgZHVjayBpcyBzdGlsbCBvbiBkZWxpdmVyeSBtaXNzaW9uBAtsb2NrZWRUb3RhbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9lY29ub215Q29udHJhY3QFEWRlbGl2ZXJ5TG9ja2VkS2V5AAAEBnVubG9jawkA/AcEBQ9lY29ub215Q29udHJhY3QCFHVwZGF0ZURlbGl2ZXJ5TG9ja2VkCQDMCAIJAGUCBQtsb2NrZWRUb3RhbAUVTUlOX1VTRFRfRkVFX0RFTElWRVJZBQNuaWwFA25pbAMJAAACBQZ1bmxvY2sFBnVubG9jawMJAGcCAAAFCWN1ckhlYWx0aAUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5RGVsaXZlcnlEZWxheUJ5RHVjawEFC2R1Y2tBc3NldElkCQBkAgUJc3RhcnRUaW1lBQlEQVlNSUxMSVMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQLc2F2ZWRIZWFsdGgJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAQ5rZXlTYXZlZEhlYWx0aAEFC2R1Y2tBc3NldElkBA1zYXZlZExvY2F0aW9uCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEQa2V5U2F2ZWRMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQCWCgQFDm91dGNvbWVBY3Rpb25zCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQloZWFsdGhLZXkFC3NhdmVkSGVhbHRoCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUNc2F2ZWRMb2NhdGlvbgUDbmlsBQ1zYXZlZExvY2F0aW9uBQtzYXZlZEhlYWx0aAENbWVyZ2VJbnRlcm5hbAYLbmV3TGFuZFNpemUIbmV3TGV2ZWwHZm9ybXVsYQRhZGRyDGxhbmRBc3NldElkcwduZWVkTWF0BAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQDCQEPY2hlY2tUb3VybmFtZW50AQULZHVja0Fzc2V0SWQJAAIBAh1tZXJnZUludGVybmFsX2NoZWNrVG91cm5hbWVudAMJAQ1jaGVja0RlbGl2ZXJ5AQULZHVja0Fzc2V0SWQJAAIBAhttZXJnZUludGVybmFsX2NoZWNrRGVsaXZlcnkKAQpjaGVja01lcmdlAgNhY2MLbGFuZEFzc2V0SWQEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFB3RpbWVLZXkJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAFkCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwQJY29udGluZW50CQCRAwIFAWQFDHJlY0NvbnRpbmVudAMDCQECIT0CCAUDYWNjAl8zAgAJAQIhPQIIBQNhY2MCXzMFCWNvbnRpbmVudAcJAAIBAi5MYW5kcyBzaG91bGQgYmUgb24gdGhlIHNhbWUgY29udGluZW50IHRvIG1lcmdlBAhsYW5kU2l6ZQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQQHc2l6ZXNJbggFA2FjYwJfMQQBaQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCzCQIFB3NpemVzSW4FCGxhbmRTaXplAidZb3UgaGF2ZW4ndCBwYXNzZWQgYWxsIHRoZSBsYW5kcyBuZWVkZWQECHNpemVzT3V0CQCsAgIJAK8CAgUHc2l6ZXNJbgUBaQkAsAICBQdzaXplc0luCQBkAgUBaQABBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBBQhsYW5kU2l6ZQQEYXJ0cwkAZAIIBQNhY2MCXzIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQAAAQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAECHJlcUxldmVsBAckbWF0Y2gwBQhsYW5kU2l6ZQMJAAACAgFTBQckbWF0Y2gwAAMDCQAAAgIBTQUHJG1hdGNoMAAEAwkAAAICAUwFByRtYXRjaDAABQMJAAACAgJYTAUHJG1hdGNoMAAGCQACAQIaT25seSBTLCBNLCBMLCBYTCBjYW4gbWVyZ2UDCQECIT0CBQppbmZyYUxldmVsBQhyZXFMZXZlbAkAAgECIkFsbCBsYW5kcyBzaG91bGQgYmUgbWF4ZWQgdG8gbWVyZ2UEB2xhbmROdW0JAJEDAgUBZAUKcmVjTGFuZE51bQQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBCQCRAwIFAWQFC3JlY1RlcnJhaW5zBAlkZWx0YVRpbWUJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUJc2F2ZWRUaW1lAwkAZgIAAAUJZGVsdGFUaW1lCQACAQkArAICCQCsAgIJAKwCAgImU2F2ZWQgdGltZXN0YW1wIGlzIGluIGZ1dHVyZSwgc2F2ZWQgPSAJAKQDAQUJc2F2ZWRUaW1lAgwsIGN1cnJlbnQgPSAJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAEFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAQxhcHBseUJvbnVzZXMCBQtsYW5kQXNzZXRJZAUGcGllY2VzBAlsYW5kSW5kZXgJAGkCBQZwaWVjZXMFBVNTSVpFBAVicFJlcwkBBmFkZFJlcwUJALUJAggFA2FjYwJfNAIBXwUNdGVycmFpbkNvdW50cwUJZGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UEBXByb3BzCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQIBQNhY2MCXzYFDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAD///////////8BBAZjUHJvcHMJARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAgFA2FjYwNfMTAFDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAD///////////8BBAtzdW1UZXJyYWlucwkBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwECAUDYWNjAl85BQ10ZXJyYWluQ291bnRzBQlsYW5kSW5kZXgAAQQFbGFuZHMIBQNhY2MCXzcEA2lkeAkAzwgCBQVsYW5kcwULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBBQNpZHgJAAIBCQCsAgICIFlvdXIgc3Rha2VkIGxhbmRzIGRvbid0IGNvbnRhaW4gBQtsYW5kQXNzZXRJZAQJY3VzdG9tS2V5CQEaa2V5TGFuZEFzc2V0SWRUb0N1c3RvbU5hbWUBBQtsYW5kQXNzZXRJZAQKY3VzdG9tTmFtZQkBC3ZhbHVlT3JFbHNlAgkAoggBBQljdXN0b21LZXkCAAkAnAoKBQhzaXplc091dAUEYXJ0cwUJY29udGluZW50BQVicFJlcwkAzggCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAggFA2FjYwJfNQkBC0RlbGV0ZUVudHJ5AQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYBQtsYW5kQXNzZXRJZAUEYWRkcgkBC0RlbGV0ZUVudHJ5AQkBEGtleUxhbmRUb0Fzc2V0SWQBBQdsYW5kTnVtCQELRGVsZXRlRW50cnkBCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICBQtsYW5kQXNzZXRJZAUEYWRkcgkBC0RlbGV0ZUVudHJ5AQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJARFrZXlMYW5kTnVtVG9Pd25lcgEFB2xhbmROdW0JAQtEZWxldGVFbnRyeQEJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQUJY3VzdG9tS2V5CQEEQnVybgIJANkEAQULbGFuZEFzc2V0SWQAAQMJAQIhPQIFCmN1c3RvbU5hbWUCAAkAzAgCCQELRGVsZXRlRW50cnkBCQEaa2V5TGFuZEN1c3RvbU5hbWVUb0Fzc2V0SWQBBQpjdXN0b21OYW1lBQNuaWwFA25pbAUFcHJvcHMJANEIAgUFbGFuZHMJAQV2YWx1ZQEFA2lkeAkAZAIIBQNhY2MCXzgFBnBpZWNlcwULc3VtVGVycmFpbnMFBmNQcm9wcwQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkECHByb3BMaXN0CQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBEWtleVJlc1Byb3BvcnRpb25zAAILMF8wXzBfMF8wXzACAV8ECGxhbmRzS2V5CQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUEYWRkcgQIbGFuZHNTdHIJAKIIAQUIbGFuZHNLZXkEB2xhbmRzSW4DCQEJaXNEZWZpbmVkAQUIbGFuZHNTdHIJAL0JAgkBBXZhbHVlAQUIbGFuZHNTdHICAV8FA25pbAQFY29udDAJAJEDAgkAtQkCCAkBBXZhbHVlAQkA7AcBCQDZBAEJAJEDAgUMbGFuZEFzc2V0SWRzAAALZGVzY3JpcHRpb24CAV8FDHJlY0NvbnRpbmVudAQJY29udFByb3BzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBFmtleVJlc1R5cGVzQnlDb250aW5lbnQBBQVjb250MAILMF8wXzBfMF8wXzACAV8EAXIKAAIkbAUMbGFuZEFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAnAoKBQdmb3JtdWxhAAACAAkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMFA25pbAUIcHJvcExpc3QFB2xhbmRzSW4AAAkAtQkCAgswXzBfMF8wXzBfMAIBXwUJY29udFByb3BzCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpjaGVja01lcmdlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQQJY29udGluZW50CAUBcgJfMwQMY29udGluZW50SWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgUKY29udGluZW50cwUJY29udGluZW50CQCsAgICE1Vua25vd24gY29udGluZW50OiAFCWNvbnRpbmVudAQIdGVycmFpbnMJARNnZW5UZXJyYWluc0Zvck1lcmdlAggFAXICXzkJAGkCCQEPbnVtUGllY2VzQnlTaXplAQULbmV3TGFuZFNpemUFBVNTSVpFBAdmcmVlTnVtCQELdmFsdWVPckVsc2UCCQCfCAEJARJrZXlOZXh0RnJlZUxhbmROdW0ACQBkAgUPUFJFU0FMRU5VTUxBTkRTAAEECm5ld0xhbmROdW0JAKQDAQUHZnJlZU51bQQFaXNzdWUJAMIIBQkBB25mdE5hbWUCBQpuZXdMYW5kTnVtBQtuZXdMYW5kU2l6ZQkAuQkCCQDMCAIFCm5ld0xhbmROdW0JAMwIAgULbmV3TGFuZFNpemUJAMwIAgUIdGVycmFpbnMJAMwIAgUJY29udGluZW50BQNuaWwCAV8AAQAABwQHYXNzZXRJZAkAuAgBBQVpc3N1ZQQObmV3TGFuZEFzc2V0SWQJANgEAQUHYXNzZXRJZAQGbmV3TWF0CQC5CQIJARFzdWJ0cmFjdE1hdGVyaWFscwMJAGYCBQduZWVkTWF0AAAJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8FB25lZWRNYXQCAV8ECXBpZWNlc0tleQkBFmtleVN0YWtlZFBpZWNlc0J5T3duZXIBBQRhZGRyBAxzdGFrZWRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJcGllY2VzS2V5AAAJAJQKAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAggFAXICXzUDCQBmAgkAkAMBCAUBcgJfNwAACQELU3RyaW5nRW50cnkCBQhsYW5kc0tleQkAuwkCCAUBcgJfNwIBXwkBC0RlbGV0ZUVudHJ5AQUIbGFuZHNLZXkJAQxJbnRlZ2VyRW50cnkCBQlwaWVjZXNLZXkDCQBmAggFAXICXzgFDHN0YWtlZFBpZWNlcwAACQBlAgUMc3Rha2VkUGllY2VzCAUBcgJfOAkBDEludGVnZXJFbnRyeQIJARJrZXlOZXh0RnJlZUxhbmROdW0ACQBkAgUHZnJlZU51bQABBQVpc3N1ZQkBC1N0cmluZ0VudHJ5AgkBEGtleUxhbmRUb0Fzc2V0SWQBBQpuZXdMYW5kTnVtBQ5uZXdMYW5kQXNzZXRJZAkBC1N0cmluZ0VudHJ5AgkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFDm5ld0xhbmRBc3NldElkBQRhZGRyCQELU3RyaW5nRW50cnkCCQERa2V5TGFuZE51bVRvT3duZXIBBQpuZXdMYW5kTnVtBQRhZGRyCQEMSW50ZWdlckVudHJ5AgkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQUObmV3TGFuZEFzc2V0SWQIBQFyAl8yCQEMSW50ZWdlckVudHJ5AgkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQ5uZXdMYW5kQXNzZXRJZAUIbmV3TGV2ZWwJAQxJbnRlZ2VyRW50cnkCCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAgUObmV3TGFuZEFzc2V0SWQFBGFkZHIFCG5ld0xldmVsCQELU3RyaW5nRW50cnkCBQVicEtleQkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAggFAXICXzQJAMwIAgUGbmV3TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6CQELU3RyaW5nRW50cnkCCQERa2V5UmVzUHJvcG9ydGlvbnMACQC5CQIIBQFyAl82AgFfCQELU3RyaW5nRW50cnkCCQEWa2V5UmVzVHlwZXNCeUNvbnRpbmVudAEFCWNvbnRpbmVudAkAuQkCCAUBcgNfMTACAV8JAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkAuQkCCQDMCAIFCWNvbnRpbmVudAkAzAgCAgFMCQDMCAIFDm5ld0xhbmRBc3NldElkBQNuaWwCAV8JAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBGFkZHIAAQUHYXNzZXRJZAUObmV3TGFuZEFzc2V0SWQBA3MybQIEYWRkcgxsYW5kQXNzZXRJZHMJAQ1tZXJnZUludGVybmFsBgIBTQADAgRTU1NTBQRhZGRyBQxsYW5kQXNzZXRJZHMAAAEDbTJsAgRhZGRyDGxhbmRBc3NldElkcwkBDW1lcmdlSW50ZXJuYWwGAgFMAAQCA1NNTQUEYWRkcgUMbGFuZEFzc2V0SWRzCQBoAgURSW5mcmFVcGdyYWRlQ29zdFMABAEEbDJ4bAIEYWRkcgxsYW5kQXNzZXRJZHMJAQ1tZXJnZUludGVybmFsBgICWEwABQIFU1NTTUwFBGFkZHIFDGxhbmRBc3NldElkcwkAaAIFEUluZnJhVXBncmFkZUNvc3RTAC8BBnhsMnh4bAIEYWRkcgxsYW5kQXNzZXRJZHMJAQ1tZXJnZUludGVybmFsBgIDWFhMAAYCA0xYTAUEYWRkcgUMbGFuZEFzc2V0SWRzCQBoAgURSW5mcmFVcGdyYWRlQ29zdFMANgELbWVyZ2VDb21tb24CBGFkZHIMbGFuZEFzc2V0SWRzBAckbWF0Y2gwCQCQAwEFDGxhbmRBc3NldElkcwMJAAACAAQFByRtYXRjaDAJAQNzMm0CBQRhZGRyBQxsYW5kQXNzZXRJZHMDCQAAAgADBQckbWF0Y2gwCQEDbTJsAgUEYWRkcgUMbGFuZEFzc2V0SWRzAwkAAAIABQUHJG1hdGNoMAkBBGwyeGwCBQRhZGRyBQxsYW5kQXNzZXRJZHMDCQAAAgACBQckbWF0Y2gwCQEGeGwyeHhsAgUEYWRkcgUMbGFuZEFzc2V0SWRzCQACAQINVW5rbm93biBtZXJnZQEGcHJvbG9nAQFpAwMJAQIhPQIIBQFpDG9yaWdpbkNhbGxlcgUMcmVzdENvbnRyYWN0CQELdmFsdWVPckVsc2UCCQCgCAEJAQprZXlCbG9ja2VkAAcHCQACAQIfQ29udHJhY3RzIGFyZSB1bmRlciBtYWludGVuYW5jZQQIdXNlckFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBARkdWNrCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFCHVzZXJBZGRyCQDNCAIDAwURS1NfQUxMT1dfREVMSVZFUlkJAQlpc0RlZmluZWQBBQRkdWNrBwQLZHVja0Fzc2V0SWQJAQV2YWx1ZQEFBGR1Y2sEBmxvY0tleQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBANsb2MJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQZsb2NLZXkFD0RFRkFVTFRMT0NBVElPTgIBXwQJc3RhcnRUaW1lCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDbG9jBQ9sb2NJZHhDb250aW5lbnQDAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUQGCQBmAggFCWxhc3RCbG9jawl0aW1lc3RhbXAJAGQCBQlzdGFydFRpbWUFElRFTl9NSU5VVEVTX01JTExJUwUDbmlsBAloZWFsdGhLZXkJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQDCQBnAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2xvYwUIbG9jSWR4SWQAAwQGcmV3YXJkCQD8BwQFD2Vjb25vbXlDb250cmFjdAISc2VuZERlbGl2ZXJ5UmV3YXJkCQDMCAIFCHVzZXJBZGRyBQNuaWwFA25pbAMJAAACBQZyZXdhcmQFBnJld2FyZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDNCAIJAM0IAgQLbG9ja2VkVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPZWNvbm9teUNvbnRyYWN0BRFkZWxpdmVyeUxvY2tlZEtleQAABAZ1bmxvY2sJAPwHBAUPZWNvbm9teUNvbnRyYWN0AhR1cGRhdGVEZWxpdmVyeUxvY2tlZAkAzAgCCQBlAgULbG9ja2VkVG90YWwFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQUDbmlsBQNuaWwDCQAAAgUGdW5sb2NrBQZ1bmxvY2sDCQBnAgAACQERQGV4dHJOYXRpdmUoMTA1NSkBBQloZWFsdGhLZXkFA25pbAQKcHVuaXNobWVudAkA/AcEBQR0aGlzAgtzYXZlSW50ZWdlcgkAzAgCCQEWa2V5RGVsaXZlcnlEZWxheUJ5RHVjawEFC2R1Y2tBc3NldElkCQDMCAIJAGQCBQlzdGFydFRpbWUFCURBWU1JTExJUwUDbmlsBQNuaWwDCQAAAgUKcHVuaXNobWVudAUKcHVuaXNobWVudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQEMSW50ZWdlckVudHJ5AgUJaGVhbHRoS2V5CQERQGV4dHJOYXRpdmUoMTA1NSkBCQEOa2V5U2F2ZWRIZWFsdGgBBQtkdWNrQXNzZXRJZAkBC1N0cmluZ0VudHJ5AgUGbG9jS2V5CQERQGV4dHJOYXRpdmUoMTA1OCkBCQEQa2V5U2F2ZWRMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQNuaWwJAQtTdHJpbmdFbnRyeQIJARFrZXlMYXN0VHhJZEJ5VXNlcgEFCHVzZXJBZGRyCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQBDHByb2xvZ0ZsaWdodAEBaQMDCQECIT0CCAUBaQxvcmlnaW5DYWxsZXIFDHJlc3RDb250cmFjdAkBC3ZhbHVlT3JFbHNlAgkAoAgBCQEKa2V5QmxvY2tlZAAHBwkAAgECH0NvbnRyYWN0cyBhcmUgdW5kZXIgbWFpbnRlbmFuY2UJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUxhc3RUeElkQnlVc2VyAQkApQgBCAUBaQxvcmlnaW5DYWxsZXIJANgEAQgFAWkNdHJhbnNhY3Rpb25JZAUDbmlsLQFpAQ1jb25zdHJ1Y3RvclYxAQhyZXN0QWRkcgMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECEVBlcm1pc3Npb24gZGVuaWVkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ5rZXlSZXN0QWRkcmVzcwAFCHJlc3RBZGRyBQNuaWwBaQELc2F2ZUludGVnZXICA2tleQZhbW91bnQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAiBzYXZlSW50ZWdlciBpcyBub3QgcHVibGljIG1ldGhvZAkAzAgCCQEMSW50ZWdlckVudHJ5AgUDa2V5BQZhbW91bnQFA25pbAFpAQpzZXRCbG9ja2VkAQlpc0Jsb2NrZWQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhFwZXJtaXNzaW9uIGRlbmllZAkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBCmtleUJsb2NrZWQABQlpc0Jsb2NrZWQFA25pbAFpAQlzdGFrZUxhbmQABA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHEV4YWN0bHkgb25lIHBheW1lbnQgcmVxdWlyZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAABAdhc3NldElkCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQEB2FkZHJlc3MJAKUIAQgFAWkGY2FsbGVyAwkBAiE9AggFA3BtdAZhbW91bnQAAQkAAgEJAKwCAgkArAICAgRORlQgBQpMQU5EUFJFRklYAiQgdG9rZW4gc2hvdWxkIGJlIGF0dGFjaGVkIGFzIHBheW1lbnQEBWFzc2V0CQEFdmFsdWUBCQDsBwEFB2Fzc2V0SWQDCQECIT0CCAUFYXNzZXQGaXNzdWVyBQR0aGlzCQACAQIXVW5rbm93biBpc3N1ZXIgb2YgdG9rZW4DCQEBIQEJAQhjb250YWlucwIIBQVhc3NldARuYW1lBQpMQU5EUFJFRklYCQACAQkArAICCQCsAgICCU9ubHkgTkZUIAUKTEFORFBSRUZJWAIUIHRva2VucyBhcmUgYWNjZXB0ZWQEC2xhbmROdW1TaXplCQCwAgIIBQVhc3NldARuYW1lAAQEB2xhbmROdW0DCQEIY29udGFpbnMCBQtsYW5kTnVtU2l6ZQIDWFhMCQCzAgIFC2xhbmROdW1TaXplAAMDCQEIY29udGFpbnMCBQtsYW5kTnVtU2l6ZQICWEwJALMCAgULbGFuZE51bVNpemUAAgkAswICBQtsYW5kTnVtU2l6ZQABAwkBASEBCQEJaXNEZWZpbmVkAQkAtgkBBQdsYW5kTnVtCQACAQkArAICAh5DYW5ub3QgcGFyc2UgbGFuZCBudW1iZXIgZnJvbSAIBQVhc3NldARuYW1lBAtsYW5kQXNzZXRJZAkA2AQBBQdhc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAwkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQISIGlzIGFscmVhZHkgc3Rha2VkBAFkCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBCQCRAwIFAWQFC3JlY1RlcnJhaW5zBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIFAWQFC3JlY0xhbmRTaXplBAlsYW5kSW5kZXgJAGkCBQZwaWVjZXMFBVNTSVpFBAVwcm9wcwkBEXVwZGF0ZVByb3BvcnRpb25zAwUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AAEEDHJlc0J5Q29udEtleQkBFmtleVJlc1R5cGVzQnlDb250aW5lbnQBCQCRAwIFAWQFDHJlY0NvbnRpbmVudAQJY29udFByb3BzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUMcmVzQnlDb250S2V5AgswXzBfMF8wXzBfMAIBXwQQdXBkYXRlZENvbnRQcm9wcwkAuQkCCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQFCWNvbnRQcm9wcwUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AAECAV8ECGxhbmRzS2V5CQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUHYWRkcmVzcwQIbGFuZHNTdHIJAKIIAQUIbGFuZHNLZXkEBWxhbmRzAwkBCWlzRGVmaW5lZAEFCGxhbmRzU3RyCQC9CQIJAQV2YWx1ZQEFCGxhbmRzU3RyAgFfBQNuaWwDCQEPY29udGFpbnNFbGVtZW50AgUFbGFuZHMFC2xhbmRBc3NldElkCQACAQkArAICAiJZb3VyIHN0YWtlZCBsYW5kcyBhbHJlYWR5IGNvbnRhaW4gBQtsYW5kQXNzZXRJZAMJAGcCCQCQAwEFBWxhbmRzBRhNQVhfTEFORFNfU1RBS0VEX0JZX1VTRVIJAAIBCQCsAgIJAKwCAgIZWW91ciBhbHJlYWR5IHN0YWtlZCBtYXggKAkApAMBBRhNQVhfTEFORFNfU1RBS0VEX0JZX1VTRVICBykgbGFuZHMECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAlwaWVjZXNLZXkJARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQUHYWRkcmVzcwQJb2xkUGllY2VzCQELdmFsdWVPckVsc2UCCQCfCAEFCXBpZWNlc0tleQAABAl3bGdSZXN1bHQJAPwHBAULd2xnQ29udHJhY3QCEm9uU3Rha2VVbnN0YWtlTGFuZAkAzAgCBQdhZGRyZXNzBQNuaWwFA25pbAkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFB3RpbWVLZXkIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgFC2xhbmRBc3NldElkBQdhZGRyZXNzCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQELU3RyaW5nRW50cnkCBQhsYW5kc0tleQkAuwkCCQDNCAIFBWxhbmRzBQtsYW5kQXNzZXRJZAIBXwkAzAgCCQEMSW50ZWdlckVudHJ5AgUJcGllY2VzS2V5CQBkAgUJb2xkUGllY2VzBQZwaWVjZXMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkBQdhZGRyZXNzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlMYW5kTnVtVG9Pd25lcgEFB2xhbmROdW0FB2FkZHJlc3MJAMwIAgkBDEludGVnZXJFbnRyeQIJAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICBQtsYW5kQXNzZXRJZAUHYWRkcmVzcwUKaW5mcmFMZXZlbAkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5UmVzUHJvcG9ydGlvbnMABQVwcm9wcwkAzAgCCQELU3RyaW5nRW50cnkCBQxyZXNCeUNvbnRLZXkFEHVwZGF0ZWRDb250UHJvcHMFA25pbAUNcHJvbG9nQWN0aW9ucwUJd2xnUmVzdWx0AWkBC3Vuc3Rha2VMYW5kAQ1sYW5kQXNzZXRJZEluBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpBmNhbGxlcgQBYwkBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwUEYWRkcgUNY2xhaW1Nb2RlRHVjawUNbGFuZEFzc2V0SWRJbgQLbGFuZEFzc2V0SWQIBQFjAl8yBAFkCAUBYwJfMwQIbGFuZHNLZXkJARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBBQRhZGRyBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEJAJEDAgUBZAULcmVjVGVycmFpbnMEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgUBZAULcmVjTGFuZFNpemUECWxhbmRJbmRleAkAaQIFBnBpZWNlcwUFU1NJWkUEBXByb3BzCQERdXBkYXRlUHJvcG9ydGlvbnMDBQ10ZXJyYWluQ291bnRzBQlsYW5kSW5kZXgA////////////AQQMcmVzQnlDb250S2V5CQEWa2V5UmVzVHlwZXNCeUNvbnRpbmVudAEJAJEDAgUBZAUMcmVjQ29udGluZW50BAljb250UHJvcHMJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQxyZXNCeUNvbnRLZXkCCzBfMF8wXzBfMF8wAgFfBBB1cGRhdGVkQ29udFByb3BzCQC5CQIJARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAUJY29udFByb3BzBQ10ZXJyYWluQ291bnRzBQlsYW5kSW5kZXgA////////////AQIBXwQLY2xhaW1SZXN1bHQJAQhjbGFpbUFsbAQFBGFkZHIFC2xhbmRBc3NldElkBQZwaWVjZXMFDWNsYWltTW9kZUR1Y2sEBWxhbmRzCQC9CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUIbGFuZHNLZXkCAAIBXwQDaWR4CQDPCAIFBWxhbmRzBQtsYW5kQXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEFA2lkeAkAAgEJAKwCAgIgWW91ciBzdGFrZWQgbGFuZHMgZG9uJ3QgY29udGFpbiAFC2xhbmRBc3NldElkBANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wBA5nb3ZSZWxlYXNlVGltZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQtnb3ZDb250cmFjdAkBFWtleVVzZXJHd2xSZWxlYXNlVGltZQEFBGFkZHIAAAMJAGcCBQ5nb3ZSZWxlYXNlVGltZQUDbm93CQACAQkArAICAjlZb3VyIGdXTCBhcmUgdGFraW5nIHBhcnQgaW4gdm90aW5nLCBjYW5ub3QgdW5zdGFrZSB1bnRpbCAJAKQDAQUOZ292UmVsZWFzZVRpbWUEDmFyYlJlbGVhc2VUaW1lCQBkAgkBC3ZhbHVlT3JFbHNlAgkAmggCBQt3bGdDb250cmFjdAkBFGtleUxhc3RBcmJUaW1lQnlVc2VyAQUEYWRkcgAABQ5hcmJpdHJhZ2VEZWxheQMJAGYCBQ5hcmJSZWxlYXNlVGltZQUDbm93CQACAQkArAICAj9Zb3VyIHN0YWtlZCBsYW5kcyB0b29rIHBhcnQgaW4gYXJiaXRyYWdlLCBjYW5ub3QgdW5zdGFrZSB1bnRpbCAJAKQDAQUOYXJiUmVsZWFzZVRpbWUECXBpZWNlc0tleQkBFmtleVN0YWtlZFBpZWNlc0J5T3duZXIBBQRhZGRyBAxzdGFrZWRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJcGllY2VzS2V5AAAECW5ld1BpZWNlcwMJAGYCBQZwaWVjZXMFDHN0YWtlZFBpZWNlcwAACQBlAgUMc3Rha2VkUGllY2VzBQZwaWVjZXMECXdsZ1Jlc3VsdAkA/AcEBQt3bGdDb250cmFjdAISb25TdGFrZVVuc3Rha2VMYW5kCQDMCAIFBGFkZHIFA25pbAUDbmlsCQCUCgIJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIAAQkA2QQBBQtsYW5kQXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBCQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKTEFORFBSRUZJWAULbGFuZEFzc2V0SWQFBGFkZHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleVJlc1Byb3BvcnRpb25zAAUFcHJvcHMJAMwIAgkBC1N0cmluZ0VudHJ5AgUMcmVzQnlDb250S2V5BRB1cGRhdGVkQ29udFByb3BzCQDMCAIJAQtTdHJpbmdFbnRyeQIIBQtjbGFpbVJlc3VsdAJfMgkAuQkCCAULY2xhaW1SZXN1bHQCXzMCAToJAMwIAgMJAGYCCQCQAwEFBWxhbmRzAAEJAQtTdHJpbmdFbnRyeQIFCGxhbmRzS2V5CQC7CQIJANEIAgUFbGFuZHMJAQV2YWx1ZQEFA2lkeAIBXwkBC0RlbGV0ZUVudHJ5AQUIbGFuZHNLZXkJAMwIAgkBDEludGVnZXJFbnRyeQIFCXBpZWNlc0tleQUJbmV3UGllY2VzBQNuaWwFDXByb2xvZ0FjdGlvbnMFCXdsZ1Jlc3VsdAFpAQlzdGFrZUR1Y2sABA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHEV4YWN0bHkgb25lIHBheW1lbnQgcmVxdWlyZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAABAdhc3NldElkCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQEB2FkZHJlc3MJAKUIAQgFAWkGY2FsbGVyAwkBAiE9AggFA3BtdAZhbW91bnQAAQkAAgEJAKwCAgkArAICAgRORlQgBQpEVUNLUFJFRklYAiQgdG9rZW4gc2hvdWxkIGJlIGF0dGFjaGVkIGFzIHBheW1lbnQEBWFzc2V0CQEFdmFsdWUBCQDsBwEFB2Fzc2V0SWQDAwkBAiE9AggFBWFzc2V0Bmlzc3VlcgUNaW5jdWJhdG9yQWRkcgkBAiE9AggFBWFzc2V0Bmlzc3VlcgULYnJlZWRlckFkZHIHCQACAQkArAICCQCsAgICElVua25vd24gaXNzdWVyIG9mIAUKRFVDS1BSRUZJWAIGIHRva2VuAwkBASEBCQEIY29udGFpbnMCCAUFYXNzZXQEbmFtZQUKRFVDS1BSRUZJWAkAAgEJAKwCAgkArAICAglPbmx5IE5GVCAFCkRVQ0tQUkVGSVgCFCB0b2tlbnMgYXJlIGFjY2VwdGVkBAphc3NldElkU3RyCQDYBAEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQUKYXNzZXRJZFN0cgMJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkJAAIBCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCEiBpcyBhbHJlYWR5IHN0YWtlZAMJAQlpc0RlZmluZWQBCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFB2FkZHJlc3MJAAIBCQCsAgICHVlvdSBhbHJlYWR5IHN0YWtlZCBvbmUgZHVjazogCAUFYXNzZXQEbmFtZQQGbG9jS2V5CQEPa2V5RHVja0xvY2F0aW9uAQUKYXNzZXRJZFN0cgQIbG9jYXRpb24JAKIIAQUGbG9jS2V5BAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQUKYXNzZXRJZFN0cgQIYmFja3BhY2sJAKIIAQUFYnBLZXkECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQphc3NldElkU3RyBAVtYXhIUAkBCW1heEhlYWx0aAEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDGtleUR1Y2tMZXZlbAEFCmFzc2V0SWRTdHIAAAQJY3VySGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aAUFbWF4SFAJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUHdGltZUtleQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKRFVDS1BSRUZJWAkA2AQBBQdhc3NldElkBQdhZGRyZXNzCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5RHVja0lkVG9Pd25lcgEFCmFzc2V0SWRTdHIFB2FkZHJlc3MJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwUKYXNzZXRJZFN0cgUDbmlsAwkBCWlzRGVmaW5lZAEFCGxvY2F0aW9uBQNuaWwJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQZsb2NLZXkFD0RFRkFVTFRMT0NBVElPTgUDbmlsAwkBCWlzRGVmaW5lZAEFCGJhY2twYWNrBQNuaWwJAM4IAgkAzQgCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5AhowOjBfMF8wXzBfMF8wOjBfMF8wXzBfMF8wOgUDbmlsCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoBQljdXJIZWFsdGgFDXByb2xvZ0FjdGlvbnMBaQELdW5zdGFrZUR1Y2sBCmFzc2V0SWRTdHIEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEB2Fzc2V0SWQJANkEAQUKYXNzZXRJZFN0cgQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEBWFzc2V0CQEFdmFsdWUBCQDsBwEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQUKYXNzZXRJZFN0cgMJAQEhAQkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQDCQEBIQEJAQlpc0RlZmluZWQBCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFB2FkZHJlc3MJAAIBCQCsAgIJAKwCAgIJVGhlIGR1Y2sgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBEGtleUR1Y2tJZFRvT3duZXIBBQphc3NldElkU3RyCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQdhZGRyZXNzCQACAQIXU3Rha2VkIE5GVCBpcyBub3QgeW91cnMDCQEPY2hlY2tUb3VybmFtZW50AQUKYXNzZXRJZFN0cgkAAgECG3Vuc3Rha2VEdWNrX2NoZWNrVG91cm5hbWVudAMJAQ1jaGVja0RlbGl2ZXJ5AQUKYXNzZXRJZFN0cgkAAgECGXVuc3Rha2VEdWNrX2NoZWNrRGVsaXZlcnkECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQphc3NldElkU3RyBAVtYXhIUAkBCW1heEhlYWx0aAEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDGtleUR1Y2tMZXZlbAEFCmFzc2V0SWRTdHIAAAQGaGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aAUFbWF4SFADCQBmAgUFbWF4SFAFBmhlYWx0aAkAAgEJAKwCAgkArAICAhlQbGVhc2UgaGVhbCB5b3VyIGR1Y2sgdG8gCQCkAwEFBW1heEhQAhNocCBiZWZvcmUgdW5zdGFraW5nCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyAAEFB2Fzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQUHdGltZUtleQkAzAgCCQELRGVsZXRlRW50cnkBBQlrZXlIZWFsdGgJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBD2tleUR1Y2tMb2NhdGlvbgEFCmFzc2V0SWRTdHIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBEGtleUR1Y2tJZFRvT3duZXIBBQphc3NldElkU3RyCQDMCAIJAQtEZWxldGVFbnRyeQEJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKRFVDS1BSRUZJWAUKYXNzZXRJZFN0cgUHYWRkcmVzcwkAzAgCCQELRGVsZXRlRW50cnkBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzBQNuaWwFDXByb2xvZ0FjdGlvbnMBaQEIY2xhaW1SZXMCBmFtb3VudA5sYW5kQXNzZXRJZFN0cgQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEBnJlc3VsdAkBEGNsYWltUmVzSW50ZXJuYWwEBQRhZGRyBQZhbW91bnQFDWNsYWltTW9kZUR1Y2sFDmxhbmRBc3NldElkU3RyBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQJAJQKAgkAzggCCQDNCAIJAM0IAgkAzggCCAUGcmVzdWx0Al8xCAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgULZHVja0Fzc2V0SWQJAGsDBQd4cENsYWltBQZhbW91bnQFBU1VTFQ4Al8xCQELU3RyaW5nRW50cnkCCAUGcmVzdWx0Al8yCQC5CQIIBQZyZXN1bHQCXzMCAToJAQtTdHJpbmdFbnRyeQIIBQZyZXN1bHQCXzQJALkJAggFBnJlc3VsdAJfNQIBOgUNcHJvbG9nQWN0aW9ucwkAkQMCCAUGcmVzdWx0Al8zBQhicElkeFJlcwFpAQxjbGFpbVJlc1RvV0gCBmFtb3VudA5sYW5kQXNzZXRJZFN0cgQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEBnJlc3VsdAkBEGNsYWltUmVzSW50ZXJuYWwEBQRhZGRyBQZhbW91bnQFC2NsYWltTW9kZVdoBQ5sYW5kQXNzZXRJZFN0cgkAlAoCCQDOCAIJAM0IAgkAzQgCCQDOCAIIBQZyZXN1bHQCXzEICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIFBGFkZHIJAGsDBQd4cENsYWltBQZhbW91bnQFBU1VTFQ4Al8xCQELU3RyaW5nRW50cnkCCAUGcmVzdWx0Al8yCQC5CQIIBQZyZXN1bHQCXzMCAToJAQtTdHJpbmdFbnRyeQIIBQZyZXN1bHQCXzQJALkJAggFBnJlc3VsdAJfNQIBOgUNcHJvbG9nQWN0aW9ucwkAkQMCCAUGcmVzdWx0Al81BQh3aElkeFJlcwFpAQZmbGlnaHQCB21lc3NhZ2UDc2lnBA1wcm9sb2dBY3Rpb25zCQEMcHJvbG9nRmxpZ2h0AQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAh1c2VyQWRkcgkApQgBCAUBaQZjYWxsZXIEAWYJAQxmbGlnaHRDb21tb24DBQh1c2VyQWRkcgUHbWVzc2FnZQUDc2lnBAVuZXdIUAgFAWYCXzEEC2R1Y2tBc3NldElkCAUBZgJfMgQGbG9jS2V5CQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQEC2N1ckxvY2F0aW9uCQELdmFsdWVPckVsc2UCCQCiCAEFBmxvY0tleQUPREVGQVVMVExPQ0FUSU9OBAtuZXdMb2NhdGlvbggFAWYCXzQDCQAAAgULbmV3TG9jYXRpb24FC2N1ckxvY2F0aW9uCQACAQIiWW91IGNhbid0IGZseSB0byB0aGUgc2FtZSBsb2NhdGlvbgQGbmV3TG9jCQC1CQIFC25ld0xvY2F0aW9uAgFfBAZpc1RvdXIJAAACCQCRAwIFBm5ld0xvYwUKbG9jSWR4VHlwZQIBVAQHaXNEZWxpdgkAAAIJAJEDAgUGbmV3TG9jBQpsb2NJZHhUeXBlAgFEBAVlcUtleQkBEGtleUR1Y2tFcXVpcG1lbnQBBQtkdWNrQXNzZXRJZAQJY3VycmVudEVxCQELdmFsdWVPckVsc2UCCQCiCAEFBWVxS2V5AhcsOyxfLDssXyw7LF8sOyxfLDssXyw7LAQNJHQwNzAyMTI3MDMwOQkBEXN1YnRyYWN0RXF1aXBtZW50AgUJY3VycmVudEVxCAUBZgJfNQQFbmV3RXEIBQ0kdDA3MDIxMjcwMzA5Al8xBA9zaG91bGRaZXJvQnVmZnMIBQ0kdDA3MDIxMjcwMzA5Al8yBA0kdDA3MDMxMjczMzUxAwkBDG5vdE9uTWlzc2lvbgIFEnRvdXJuYW1lbnRDb250cmFjdAULY3VyTG9jYXRpb24DCQEBIQEJAQ9pc1VzdWFsTG9jYXRpb24BBQtuZXdMb2NhdGlvbgkBDGNoZWF0QXR0ZW1wdAIFC2N1ckxvY2F0aW9uBQtuZXdMb2NhdGlvbgMJAGYCBQVuZXdIUAAACQCUCgIFC25ld0xvY2F0aW9uBQVuZXdIUAkAlAoCBQtjdXJMb2NhdGlvbgAAAwkBDmlzSW5Ub3VybmFtZW50AgUSdG91cm5hbWVudENvbnRyYWN0BQtjdXJMb2NhdGlvbgMJAQEhAQkBDmlzSW5Ub3VybmFtZW50AgUSdG91cm5hbWVudENvbnRyYWN0BQtuZXdMb2NhdGlvbgkAAgECKllvdXIgZHVjayBpcyB0YWtpbmcgcGFydCBpbiB0aGUgdG91cm5hbWVudAQFc2NvcmUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZuZXdMb2MFCGxvY0lkeElkBAZjdXJMb2MJALUJAgULY3VyTG9jYXRpb24CAV8EBmxhc3RJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBRJ0b3VybmFtZW50Q29udHJhY3QFDWxhc3RUb3VySWRLZXkAAAMJAQIhPQIFBXNjb3JlCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBmN1ckxvYwUIbG9jSWR4SWQAAQkBDGNoZWF0QXR0ZW1wdAIFC2N1ckxvY2F0aW9uBQtuZXdMb2NhdGlvbgMJAGYCBQVuZXdIUAAABAlsb2NhbEJlc3QJAQt2YWx1ZU9yRWxzZQIJAJoIAgUSdG91cm5hbWVudENvbnRyYWN0CQEaa2V5QmVzdFJlc3VsdEJ5VG91ckFuZER1Y2sCBQZsYXN0SWQFC2R1Y2tBc3NldElkAAAECHVwZExvY2FsAwkAZgIFBXNjb3JlBQlsb2NhbEJlc3QJAPwHBAUSdG91cm5hbWVudENvbnRyYWN0Ag5zYXZlRHVja1Jlc3VsdAkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCBQVzY29yZQUDbmlsBQNuaWwFBHVuaXQDCQAAAgUIdXBkTG9jYWwFCHVwZExvY2FsCQCUCgIFC25ld0xvY2F0aW9uBQVuZXdIUAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAlAoCBQtjdXJMb2NhdGlvbgAAAwkBASEBCQEMaXNJbkRlbGl2ZXJ5AQULY3VyTG9jYXRpb24ECWxvY0hlYWx0aAkBEGFzU3RyaW5nSW50VHVwbGUBCQD8BwQFBHRoaXMCEGF1dG9FeGl0RGVsaXZlcnkJAMwIAgULZHVja0Fzc2V0SWQFA25pbAUDbmlsAwkAAAIFCWxvY0hlYWx0aAUJbG9jSGVhbHRoAwUHaXNEZWxpdgUJbG9jSGVhbHRoAwkAZgIFBW5ld0hQAAAJAJQKAgULbmV3TG9jYXRpb24FBW5ld0hQCQCUCgIIBQlsb2NIZWFsdGgCXzEAAAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMJAQEhAQUHaXNEZWxpdgkAAgECJFlvdXIgZHVjayBpcyB0YWtpbmcgcGFydCBpbiBkZWxpdmVyeQMJAQEhAQkBDGlzSW5EZWxpdmVyeQEFC25ld0xvY2F0aW9uCQEMY2hlYXRBdHRlbXB0AgULY3VyTG9jYXRpb24FC25ld0xvY2F0aW9uBAVzY29yZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBm5ld0xvYwUIbG9jSWR4SWQEBmN1ckxvYwkAtQkCBQtjdXJMb2NhdGlvbgIBXwMJAQIhPQIFBXNjb3JlCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBmN1ckxvYwUIbG9jSWR4SWQAAQkBDGNoZWF0QXR0ZW1wdAIFC2N1ckxvY2F0aW9uBQtuZXdMb2NhdGlvbgMDCQBmAgUFbmV3SFAAAAkAZgIAAwUFc2NvcmUHCQCUCgIFC25ld0xvY2F0aW9uBQVuZXdIUAQJbG9jSGVhbHRoCQEQYXNTdHJpbmdJbnRUdXBsZQEJAPwHBAUEdGhpcwIQYXV0b0V4aXREZWxpdmVyeQkAzAgCBQtkdWNrQXNzZXRJZAUDbmlsBQNuaWwDCQAAAgUJbG9jSGVhbHRoBQlsb2NIZWFsdGgFCWxvY0hlYWx0aAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQJbG9jVG9TYXZlCAUNJHQwNzAzMTI3MzM1MQJfMQQIaHBUb1NhdmUIBQ0kdDA3MDMxMjczMzUxAl8yCQCUCgIJAM4IAgkAzggCCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUGbG9jS2V5BQlsb2NUb1NhdmUJAMwIAgkBC1N0cmluZ0VudHJ5AgUFZXFLZXkFBW5ld0VxCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBQVuZXdIUAUDbmlsBQ1wcm9sb2dBY3Rpb25zAwUPc2hvdWxkWmVyb0J1ZmZzCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQxrZXlEdWNrQnVmZnMBBQtkdWNrQXNzZXRJZAIJMF8wXzBfMF8wBQNuaWwFA25pbAgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkAwkAZgIFBW5ld0hQAAAFD3hwU3VjY2Vzc0ZsaWdodAUMeHBGYWlsRmxpZ2h0Al8xCAUBZgJfMwFpAQRoZWFsAwpxdWFudGl0eUwxCnF1YW50aXR5TDIKcXVhbnRpdHlMMwQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDAwMJAGYCAAAFCnF1YW50aXR5TDEGCQBmAgAABQpxdWFudGl0eUwyBgkAZgIAAAUKcXVhbnRpdHlMMwkAAgECG1F1YW50aXR5IGNhbm5vdCBiZSBuZWdhdGl2ZQQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAMJAQ9jaGVja1RvdXJuYW1lbnQBBQtkdWNrQXNzZXRJZAkAAgECFGhlYWxfY2hlY2tUb3VybmFtZW50AwkBDWNoZWNrRGVsaXZlcnkBBQtkdWNrQXNzZXRJZAkAAgECEmhlYWxfY2hlY2tEZWxpdmVyeQQDcXRzCQDMCAIFCnF1YW50aXR5TDEJAMwIAgUKcXVhbnRpdHlMMgkAzAgCBQpxdWFudGl0eUwzBQNuaWwECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAQFbWF4SFAJAQltYXhIZWFsdGgBCQELdmFsdWVPckVsc2UCCQCfCAEJAQxrZXlEdWNrTGV2ZWwBBQtkdWNrQXNzZXRJZAAABAlvbGRIZWFsdGgJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoBQVtYXhIUAMJAGcCBQlvbGRIZWFsdGgFBW1heEhQCQAC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AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQIaQWxsb3dlZCBVU0RUIHBheW1lbnQgb25seSEEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQDCQEPY2hlY2tUb3VybmFtZW50AQULZHVja0Fzc2V0SWQJAAIBAhZoZWFsRVNfY2hlY2tUb3VybmFtZW50AwkBDWNoZWNrRGVsaXZlcnkBBQtkdWNrQXNzZXRJZAkAAgECFGhlYWxFU19jaGVja0RlbGl2ZXJ5BAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEBW1heEhQCQEJbWF4SGVhbHRoAQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEMa2V5RHVja0xldmVsAQULZHVja0Fzc2V0SWQAAAQJb2xkSGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aAUFbWF4SFADCQBmAgUJb2xkSGVhbHRoAAAJAAIBAihIUCBzaG91bGQgYmUgMCB0byBjYWxsIEVtZXJnZW5jeSBTZXJ2aWNlBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQIcHJvZExpc3QDCQAAAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgAFA25pbAkAvAkCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAV8EDW1lZEtpdEFtb3VudDEDCQBmAgkAkAMBBQhwcm9kTGlzdAAACQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIcHJvZExpc3QAAAAABA1tZWRLaXRBbW91bnQyAwkAZgIJAJADAQUIcHJvZExpc3QAAQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCHByb2RMaXN0AAEAAAQNbWVkS2l0QW1vdW50MwMJAGYCCQCQAwEFCHByb2RMaXN0AAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhwcm9kTGlzdAACAAADAwMJAGYCBQ1tZWRLaXRBbW91bnQxAAAGCQBmAgUNbWVkS2l0QW1vdW50MgAABgkAZgIFDW1lZEtpdEFtb3VudDMAAAkAAgECH1lvdSBoYXZlIHRvIHVzZSBvd24gTWVkaWNhbCBLaXQECGV4aXN0U3RyCQCdCAIFD2Vjb25vbXlDb250cmFjdAkBDmtleUVzV2FyZWhvdXNlAAQMZXhpc3RBbW91bnRzAwkBCWlzRGVmaW5lZAEFCGV4aXN0U3RyCQC8CQIJAQV2YWx1ZQEFCGV4aXN0U3RyAgFfBQNuaWwEC2V4aXN0QW1vdW50AwkAZgIJAJADAQUMZXhpc3RBbW91bnRzAAAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQxleGlzdEFtb3VudHMAAAAAAwkAZwIAAAULZXhpc3RBbW91bnQJAAIBAjlUaGVyZSBhcmUgbm8gTWVkaWNhbCBLaXRzIEwxIGF0IEVtZXJnZW5jeSBTZXJ2aWNlIHN0b3JhZ2UECW5ld0hlYWx0aAkAZAIFCW9sZEhlYWx0aAkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgkAkQMCBRBwcm9kdWN0aW9uTWF0cml4AAACAV8FCnJJZHhFZmZlY3QEBW5ld0VTCQC5CQIJAMwIAgkApAMBCQBlAgULZXhpc3RBbW91bnQAAQkA0QgCBQxleGlzdEFtb3VudHMAAAIBXwQGcmVjaXBlCQC1CQIJAJEDAgUQcHJvZHVjdGlvbk1hdHJpeAAAAgFfBAh0b3RhbE1hdAkBEmdldFJlY2lwZU1hdGVyaWFscwEFBnJlY2lwZQQJc2VsbFByaWNlCQBrAwkAaAIFCHRvdGFsTWF0BQpFU1NFTExDT0VGBRBSRVNPVVJDRVBSSUNFTUlOCQBoAgUFTVVMVDgFDlBST0RVQ1RQS0dTSVpFAwkBAiE9AggFA3BtdAZhbW91bnQFCXNlbGxQcmljZQkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFCXNlbGxQcmljZQQGcmVzdWx0CQEIYXNTdHJpbmcBCQD8BwQFD2Vjb25vbXlDb250cmFjdAIPdXBkYXRlRXNTdG9yYWdlCQDMCAIFBW5ld0VTBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFC3VzZHRBc3NldElkBQlzZWxsUHJpY2UFA25pbAkAlAoCCQDOCAIJAM0IAgUNcHJvbG9nQWN0aW9ucwkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAUJbmV3SGVhbHRoCAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgULZHVja0Fzc2V0SWQFCHhwQ2FsbEVTAl8xBQZyZXN1bHQBaQEOdXBkYXRlQmFja3BhY2sCC2R1Y2tBc3NldElkB25ld1BhY2sDCQECIT0CCAUBaQZjYWxsZXIFD2Vjb25vbXlDb250cmFjdAkAAgECEXBlcm1pc3Npb24gZGVuaWVkCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQFB25ld1BhY2sFA25pbAUHbmV3UGFjawFpAQ9jb21taXRGb3JSYW5kb20ABA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQQLZmluaXNoQmxvY2sJAGQCBQZoZWlnaHQFC3JhbmRvbURlbGF5BARhZGRyCQClCAEIBQFpBmNhbGxlcgkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQlrZXlDb21taXQBBQRhZGRyBQtmaW5pc2hCbG9jawUDbmlsBQ1wcm9sb2dBY3Rpb25zBQtmaW5pc2hCbG9jawFpAQhidXlTTGFuZAAEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQIaQWxsb3dlZCBVU0RUIHBheW1lbnQgb25seSEDCQECIT0CCAUDcG10BmFtb3VudAUHRVhQVVNEVAkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFB0VYUFVTRFQEBnJlc3VsdAkBEmV4cGVkaXRpb25JbnRlcm5hbAIIBQFpBmNhbGxlcggFAWkNdHJhbnNhY3Rpb25JZAQLYWNyZXNSZXN1bHQJAQVhc0ludAEJAPwHBAUNYWNyZXNDb250cmFjdAIJYnVybkFjcmVzCQDMCAIFDFNfQ09TVF9BQ1JFUwUDbmlsBQNuaWwJAJQKAgkAzggCCQDOCAIJAM0IAggFBnJlc3VsdAJfMQkBDlNjcmlwdFRyYW5zZmVyAwUPZWNvbm9teUNvbnRyYWN0CAUDcG10BmFtb3VudAULdXNkdEFzc2V0SWQICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIJAKUIAQgFAWkGY2FsbGVyBQp4cE5ld1NMYW5kAl8xBQ1wcm9sb2dBY3Rpb25zCQCUCgIICAUGcmVzdWx0Al8yAl8xBQthY3Jlc1Jlc3VsdAFpAQpleHBlZGl0aW9uAgdtZXNzYWdlA3NpZwQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQIdXNlckFkZHIJAKUIAQgFAWkGY2FsbGVyBAFmCQEMZmxpZ2h0Q29tbW9uAwUIdXNlckFkZHIFB21lc3NhZ2UFA3NpZwQLZHVja0Fzc2V0SWQIBQFmAl8yBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAVtTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQGbmV3TWF0CQC5CQIJARFzdWJ0cmFjdE1hdGVyaWFscwMGBQVtTGlzdAUMRVhQTUFURVJJQUxTAgFfBAVlcUtleQkBEGtleUR1Y2tFcXVpcG1lbnQBBQtkdWNrQXNzZXRJZAQJY3VycmVudEVxCQELdmFsdWVPckVsc2UCCQCiCAEFBWVxS2V5AhcsOyxfLDssXyw7LF8sOyxfLDssXyw7LAQNJHQwODA3ODg4MDg4NQkBEXN1YnRyYWN0RXF1aXBtZW50AgUJY3VycmVudEVxCAUBZgJfNQQFbmV3RXEIBQ0kdDA4MDc4ODgwODg1Al8xBA9zaG91bGRaZXJvQnVmZnMIBQ0kdDA4MDc4ODgwODg1Al8yBAFlCQESZXhwZWRpdGlvbkludGVybmFsAggFAWkGY2FsbGVyCAUBaQ10cmFuc2FjdGlvbklkBAJpZAgIBQFlAl8yAl8xBAZyZXN1bHQDCQBnAgAACAUBZgJfMQkAlQoDCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgAAAkAzAgCCQELU3RyaW5nRW50cnkCBQVlcUtleQUFbmV3RXEFA25pbAIAAAAJAJUKAwkAzggCCAUBZQJfMQMFD3Nob3VsZFplcm9CdWZmcwkAzAgCCQELU3RyaW5nRW50cnkCCQEMa2V5RHVja0J1ZmZzAQULZHVja0Fzc2V0SWQCCTBfMF8wXzBfMAUDbmlsCQDNCAIJAM0IAgkAzQgCCQDNCAIFA25pbAkBC1N0cmluZ0VudHJ5AgkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQC5CQIJAMwIAggIBQFlAl8yAl8yCQDMCAICAUwJAMwIAgUCaWQFA25pbAIBXwkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAgFAWYCXzEJAQtTdHJpbmdFbnRyeQIFBWVxS2V5BQVuZXdFcQkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQDMCAIFBm5ld01hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgUCaWQIBQFmAl8zAwkBD2NoZWNrVG91cm5hbWVudAEFC2R1Y2tBc3NldElkCQACAQIaZXhwZWRpdGlvbl9jaGVja1RvdXJuYW1lbnQDCQENY2hlY2tEZWxpdmVyeQEFC2R1Y2tBc3NldElkCQACAQIYZXhwZWRpdGlvbl9jaGVja0RlbGl2ZXJ5BAthY3Jlc1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ1hY3Jlc0NvbnRyYWN0AglidXJuQWNyZXMJAMwIAgUMU19DT1NUX0FDUkVTBQNuaWwFA25pbAkAlAoCCQDOCAIJAM4IAggFBnJlc3VsdAJfMQgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkBQp4cE5ld1NMYW5kAl8xBQ1wcm9sb2dBY3Rpb25zCQCVCgMIBQZyZXN1bHQCXzIIBQZyZXN1bHQCXzMFC2FjcmVzUmVzdWx0AWkBEGJ1eVNMYW5kRm9yQWNyZXMABA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABANhbXQIBQNwbXQGYW1vdW50AwMJAQEhAQkBCWlzRGVmaW5lZAEIBQNwbXQHYXNzZXRJZAYJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAUMYWNyZXNBc3NldElkCQACAQIUQUNSRVMgcGF5bWVudHMgb25seSEDCQECIT0CBQNhbXQFDFNfQ09TVF9BQ1JFUwkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFDFNfQ09TVF9BQ1JFUwQGcmVzdWx0CQESZXhwZWRpdGlvbkludGVybmFsAggFAWkGY2FsbGVyCAUBaQ10cmFuc2FjdGlvbklkBAthY3Jlc1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ1hY3Jlc0NvbnRyYWN0AglidXJuQWNyZXMJAMwIAgUMU19DT1NUX0FDUkVTBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFDGFjcmVzQXNzZXRJZAUDYW10BQNuaWwJAJQKAgkAzggCCQDOCAIIBQZyZXN1bHQCXzEICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIJAKUIAQgFAWkGY2FsbGVyBQp4cE5ld1NMYW5kAl8xBQ1wcm9sb2dBY3Rpb25zCQCUCgIICAUGcmVzdWx0Al8yAl8xBQthY3Jlc1Jlc3VsdAFpAQx1cGdyYWRlSW5mcmEBC2xhbmRBc3NldElkBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAZyZXN1bHQJAQ11cEluZnJhQ29tbW9uBAYIBQFpBmNhbGxlcgAABQtsYW5kQXNzZXRJZAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAkAlAoCCQDOCAIJAM4IAggFBnJlc3VsdAJfMQUNcHJvbG9nQWN0aW9ucwgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkCQBrAwUOeHBVcGdyYWRlSW5mcmEIBQZyZXN1bHQCXzMFBU1VTFQ4Al8xCAUGcmVzdWx0Al8yAWkBEGFjdGl2YXRlQXJ0aWZhY3QCB2FydE5hbWUObGFuZEFzc2V0SWRPcHQEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBGFkZHIJAKUIAQgFAWkGY2FsbGVyBAZyZXN1bHQEByRtYXRjaDAFB2FydE5hbWUDCQAAAgIHUFJFU0FMRQUHJG1hdGNoMAkBEmFjdGl2YXRlUHJlc2FsZUFydAIFBGFkZHIFDmxhbmRBc3NldElkT3B0AwkAAAICB09OQk9BUkQFByRtYXRjaDAJARJhY3RpdmF0ZU9uYm9hcmRBcnQBBQRhZGRyCQACAQIQVW5rbm93biBhcnRpZmFjdAkAzggCBQZyZXN1bHQFDXByb2xvZ0FjdGlvbnMBaQEKbWVyZ2VMYW5kcwEMbGFuZEFzc2V0SWRzBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAZyZXN1bHQJAQttZXJnZUNvbW1vbgIJAKUIAQgFAWkGY2FsbGVyBQxsYW5kQXNzZXRJZHMJAJQKAgkAzggCCQDOCAIIBQZyZXN1bHQCXzEFDXByb2xvZ0FjdGlvbnMICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIJAKUIAQgFAWkGY2FsbGVyBQd4cE1lcmdlAl8xCAUGcmVzdWx0Al8yAWkBDWNhcmdvRXhjaGFuZ2UCDGNhcmdvTGlzdFN0cgtsYW5kQXNzZXRJZAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQKY2FyZ29QYXJ0cwkAvAkCBQxjYXJnb0xpc3RTdHICAToEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAlsYW5kSW5kZXgJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwULcmVjTGFuZFNpemUFBVNTSVpFBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgQDbG9jCQC1CQIJAQV2YWx1ZQEFC2N1ckxvY2F0aW9uAgFfAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUwJAAIBCQCsAgIJAKwCAgIWRHVjayBsb2NhdGlvbiB0eXBlIGlzIAkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCESwgYnV0IHNob3VsZCBiZSBMAwkBAiE9AgkAkQMCBQNsb2MFCGxvY0lkeElkBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgIbRHVjayBzaG91bGQgYmUgb24gdGhlIGxhbmQgBQtsYW5kQXNzZXRJZAQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAQJY3VycmVudFdoCQEMZ2V0V2FyZWhvdXNlAwUFd2hLZXkFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBnJlc3VsdAkBCW1vdmVTdHVmZgMFCmNhcmdvUGFydHMFCWN1cnJlbnRXaAULY3VycmVudFBhY2sEBGxvZnQJALUJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4TE9GVAIBXwQFbG9mdE8JAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQIBQZyZXN1bHQCXzcEBWxvZnRGCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUIBQZyZXN1bHQCXzcJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQkAugkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAggFBnJlc3VsdAJfNAkAzAgCCAUGcmVzdWx0Al81CQDMCAIIBQZyZXN1bHQCXzYFA25pbAIBOgkAzAgCCQELU3RyaW5nRW50cnkCBQV3aEtleQkAugkCCQDMCAIJAJEDAgUJY3VycmVudFdoBQt3aElkeExldmVscwkAzAgCCAUGcmVzdWx0Al8xCQDMCAIIBQZyZXN1bHQCXzIJAMwIAggFBnJlc3VsdAJfMwkAzAgCCQC5CQIJAMwIAgkAkQMCBQRsb2Z0BQl2b2xMb2NrZWQJAMwIAgkApAMBBQVsb2Z0TwkAzAgCCQCkAwEFBWxvZnRGCQDMCAIJAJEDAgUEbG9mdAUIdm9sVG90YWwFA25pbAIBXwUDbmlsAgE6BQNuaWwFDXByb2xvZ0FjdGlvbnMBaQENc2F2ZVdhcmVob3VzZQIFd2hTdHILbGFuZEFzc2V0SWQDCQECIT0CCAUBaQZjYWxsZXIFD2Vjb25vbXlDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQEBXdoS2V5CQESa2V5V2FyZWhvdXNlQnlMYW5kAQULbGFuZEFzc2V0SWQEAndoCQC8CQIFBXdoU3RyAgE6AwkBAiE9AgkAkAMBBQJ3aAAFCQACAQIwd2FyZWhvdXNlIHN0cmluZyBzaG91bGQgY29udGFpbiA0ICc6JyBzZXBhcmF0b3JzBAVsb2Z0TAkAkQMCCQC1CQIJAJEDAgUCd2gFCXdoSWR4TE9GVAIBXwUJdm9sTG9ja2VkBAVsb2Z0TwkBF2dldFdhcmVob3VzZU9jY3VwaWVkVm9sAQUCd2gEBWxvZnRUCQEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBCQCRAwIFAndoBQt3aElkeExldmVscwQFbG9mdEYJAGUCCQBlAgUFbG9mdFQJAQ1wYXJzZUludFZhbHVlAQUFbG9mdEwFBWxvZnRPBAhuZXdXaFN0cgkAugkCCQDMCAIJAJEDAgUCd2gFC3doSWR4TGV2ZWxzCQDMCAIJAJEDAgUCd2gFCHdoSWR4UmVzCQDMCAIJAJEDAgUCd2gFCHdoSWR4TWF0CQDMCAIJAJEDAgUCd2gFCXdoSWR4UHJvZAkAzAgCCQC5CQIJAMwIAgUFbG9mdEwJAMwIAgkApAMBBQVsb2Z0TwkAzAgCCQCkAwEFBWxvZnRGCQDMCAIJAKQDAQUFbG9mdFQFA25pbAIBXwUDbmlsAgE6CQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUFd2hLZXkFCG5ld1doU3RyBQNuaWwFCG5ld1doU3RyAWkBEmZpeFdhcmVob3VzZUZvcm1hdAELbGFuZEFzc2V0SWQDCQECIT0CCAUBaQZjYWxsZXIFDHJlc3RDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQEBXdoS2V5CQESa2V5V2FyZWhvdXNlQnlMYW5kAQULbGFuZEFzc2V0SWQEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQECWxhbmRJbmRleAkAaQIJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBQtyZWNMYW5kU2l6ZQUFU1NJWkUECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAJ3aAkBDGdldFdhcmVob3VzZQMFBXdoS2V5BQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwEBWxvZnRMCQEFYXNJbnQBCQD8BwQFD2Vjb25vbXlDb250cmFjdAIacmVjYWxjTG9ja2VkVm9sdW1lUkVBRE9OTFkJAMwIAgULbGFuZEFzc2V0SWQJAMwIAgUCd2gFA25pbAUDbmlsBAVsb2Z0TwkBF2dldFdhcmVob3VzZU9jY3VwaWVkVm9sAQUCd2gEBWxvZnRUCQEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBCQCRAwIFAndoBQt3aElkeExldmVscwQFbG9mdEYJAGUCCQBlAgUFbG9mdFQFBWxvZnRMBQVsb2Z0TwQIbmV3V2hTdHIJALoJAgkAzAgCCQCRAwIFAndoBQt3aElkeExldmVscwkAzAgCCQCRAwIFAndoBQh3aElkeFJlcwkAzAgCCQCRAwIFAndoBQh3aElkeE1hdAkAzAgCCQCRAwIFAndoBQl3aElkeFByb2QJAMwIAgkAuQkCCQDMCAIJAKQDAQUFbG9mdEwJAMwIAgkApAMBBQVsb2Z0TwkAzAgCCQCkAwEFBWxvZnRGCQDMCAIJAKQDAQUFbG9mdFQFA25pbAIBXwUDbmlsAgE6CQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUFd2hLZXkFCG5ld1doU3RyBQNuaWwFCG5ld1doU3RyAWkBF2ZpeENvbnRpbmVudFByb3BvcnRpb25zAQxsYW5kQXNzZXRJZHMDCQECIT0CCAUBaQZjYWxsZXIFDHJlc3RDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQKAQhnZXRQcm9wcwIDYWNjBGNvbnQJAM0IAgUDYWNjCQELdmFsdWVPckVsc2UCCQCiCAEJARZrZXlSZXNUeXBlc0J5Q29udGluZW50AQUEY29udAILMF8wXzBfMF8wXzAEAXAKAAIkbAUKY29udGluZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZ2V0UHJvcHMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDUJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFCgEJcHJvY2Vzc29yAgNhY2MLbGFuZEFzc2V0SWQEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQEAWQJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBAlsYW5kSW5kZXgJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQUFU1NJWkUEBGNvbnQJAJEDAgUBZAUMcmVjQ29udGluZW50BA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEJAJEDAgUBZAULcmVjVGVycmFpbnMEDGNvbnRpbmVudElkeAkBBXZhbHVlAQkAzwgCBQpjb250aW5lbnRzBQRjb250BAljb250UHJvcHMJALUJAgkAkQMCBQNhY2MFDGNvbnRpbmVudElkeAIBXwQHdXBkYXRlZAkAuQkCCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQFCWNvbnRQcm9wcwUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AAECAV8EByRtYXRjaDAFBGNvbnQDCQAAAgIIQW1lcmljYXMFByRtYXRjaDAJAMwIAgUHdXBkYXRlZAkAzAgCCQCRAwIFA2FjYwABCQDMCAIJAJEDAgUDYWNjAAIJAMwIAgkAkQMCBQNhY2MAAwkAzAgCCQCRAwIFA2FjYwAEBQNuaWwDCQAAAgIGRXVyb3BlBQckbWF0Y2gwCQDMCAIJAJEDAgUDYWNjAAAJAMwIAgUHdXBkYXRlZAkAzAgCCQCRAwIFA2FjYwACCQDMCAIJAJEDAgUDYWNjAAMJAMwIAgkAkQMCBQNhY2MABAUDbmlsAwkAAAICBEFzaWEFByRtYXRjaDAJAMwIAgkAkQMCBQNhY2MAAAkAzAgCCQCRAwIFA2FjYwABCQDMCAIFB3VwZGF0ZWQJAMwIAgkAkQMCBQNhY2MAAwkAzAgCCQCRAwIFA2FjYwAEBQNuaWwDCQAAAgIGQWZyaWNhBQckbWF0Y2gwCQDMCAIJAJEDAgUDYWNjAAAJAMwIAgkAkQMCBQNhY2MAAQkAzAgCCQCRAwIFA2FjYwACCQDMCAIFB3VwZGF0ZWQJAMwIAgkAkQMCBQNhY2MABAUDbmlsAwkAAAICB09jZWFuaWEFByRtYXRjaDAJAMwIAgkAkQMCBQNhY2MAAAkAzAgCCQCRAwIFA2FjYwABCQDMCAIJAJEDAgUDYWNjAAIJAMwIAgkAkQMCBQNhY2MAAwkAzAgCBQd1cGRhdGVkBQNuaWwJAAIBAg93cm9uZyBjb250aW5lbnQEAXIKAAIkbAUMbGFuZEFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUBcAoBBSRmMV8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEJcHJvY2Vzc29yAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhVMaXN0IHNpemUgZXhjZWVkcyAxMDAJAQUkZjFfMgIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQA+AD8AQABBAEIAQwBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0AXgBfAGAAYQBiAGMAZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlSZXNUeXBlc0J5Q29udGluZW50AQIIQW1lcmljYXMJAJEDAgUBcgAACQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlSZXNUeXBlc0J5Q29udGluZW50AQIGRXVyb3BlCQCRAwIFAXIAAQkAzAgCCQELU3RyaW5nRW50cnkCCQEWa2V5UmVzVHlwZXNCeUNvbnRpbmVudAECBEFzaWEJAJEDAgUBcgACCQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlSZXNUeXBlc0J5Q29udGluZW50AQIGQWZyaWNhCQCRAwIFAXIAAwkAzAgCCQELU3RyaW5nRW50cnkCCQEWa2V5UmVzVHlwZXNCeUNvbnRpbmVudAECB09jZWFuaWEJAJEDAgUBcgAEBQNuaWwAAAFpAQ9maXhTdGFrZWRQaWVjZXMBB2FkZHJlc3MDCQECIT0CCAUBaQZjYWxsZXIFDHJlc3RDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQEDHN0YWtlZFBpZWNlcwMJAAACBQdhZGRyZXNzAgAAAAQIbGFuZHNTdHIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUHYWRkcmVzcwQFbGFuZHMDCQEJaXNEZWZpbmVkAQUIbGFuZHNTdHIJAL0JAgkBBXZhbHVlAQUIbGFuZHNTdHICAV8FA25pbAoBB29uZUxhbmQCA2FjYwtsYW5kQXNzZXRJZAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQIbGFuZFNpemUJAJEDAgkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8FC3JlY0xhbmRTaXplCQBkAgUDYWNjCQEPbnVtUGllY2VzQnlTaXplAQUIbGFuZFNpemUKAAIkbAUFbGFuZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB29uZUxhbmQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFUxpc3Qgc2l6ZSBleGNlZWRzIDEwMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAGIAYwBkCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQUHYWRkcmVzcwUMc3Rha2VkUGllY2VzBQNuaWwFDHN0YWtlZFBpZWNlcwFpAQ1zZXRDdXN0b21OYW1lAwdhc3NldElkCmN1c3RvbU5hbWUEdHlwZQQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhpBbGxvd2VkIFVTRFQgcGF5bWVudCBvbmx5IQMJAQIhPQIIBQNwbXQGYW1vdW50BQxSRU5BTUlOR0NPU1QJAAIBCQCsAgICElBheW1lbnQgc2hvdWxkIGJlIAkApAMBBQxSRU5BTUlOR0NPU1QDCQEIY29udGFpbnMCBQpjdXN0b21OYW1lAgJfXwkAAgEJAKwCAgIeTmFtZSBzaG91bGQgbm90IGNvbnRhaW4gJ19fJzogBQpjdXN0b21OYW1lAwkAZgIJALECAQUKY3VzdG9tTmFtZQUKTUFYTkFNRUxFTgkAAgEJAKwCAgIZTmFtZSB0b28gbG9uZywgbWF4TGVuZ3RoPQkApAMBBQpNQVhOQU1FTEVOBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQHYWN0aW9ucwQHJG1hdGNoMAUEdHlwZQMJAAACAgdBQ0NPVU5UBQckbWF0Y2gwBApyZXZlcnNlS2V5CQEWa2V5Q3VzdG9tTmFtZVRvQWRkcmVzcwEFCmN1c3RvbU5hbWUECW5hbWVPd25lcgkAoggBBQpyZXZlcnNlS2V5AwkBCWlzRGVmaW5lZAEFCW5hbWVPd25lcgkAAgEJAKwCAgIZTmFtZSBhbHJlYWR5IHJlZ2lzdGVyZWQ6IAUKY3VzdG9tTmFtZQQNYWRkclRvTmFtZUtleQkBFmtleUFkZHJlc3NUb0N1c3RvbU5hbWUBBQRhZGRyBAdvbGROYW1lCQCiCAEFDWFkZHJUb05hbWVLZXkEB2ZyZWVPbGQDCQEJaXNEZWZpbmVkAQUHb2xkTmFtZQkAzAgCCQELRGVsZXRlRW50cnkBCQEWa2V5Q3VzdG9tTmFtZVRvQWRkcmVzcwEJAQV2YWx1ZQEFB29sZE5hbWUFA25pbAUDbmlsCQDOCAIJAM0IAgkAzQgCBQdmcmVlT2xkCQELU3RyaW5nRW50cnkCBQ1hZGRyVG9OYW1lS2V5BQpjdXN0b21OYW1lCQELU3RyaW5nRW50cnkCBQpyZXZlcnNlS2V5BQRhZGRyCAkBFnVwZGF0ZUFjY1N0YXRzSW50ZXJuYWwCBQRhZGRyBQx4cEN1c3RvbU5hbWUCXzEDCQAAAgIETEFORAUHJG1hdGNoMAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQdhc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFB2Fzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkJAAIBCQCsAgIIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQUHYXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQKcmV2ZXJzZUtleQkBGmtleUxhbmRDdXN0b21OYW1lVG9Bc3NldElkAQUKY3VzdG9tTmFtZQQJbmFtZU93bmVyCQCiCAEFCnJldmVyc2VLZXkDCQEJaXNEZWZpbmVkAQUJbmFtZU93bmVyCQACAQkArAICAhlOYW1lIGFscmVhZHkgcmVnaXN0ZXJlZDogBQpjdXN0b21OYW1lBA5hc3NldFRvTmFtZUtleQkBGmtleUxhbmRBc3NldElkVG9DdXN0b21OYW1lAQUHYXNzZXRJZAQHb2xkTmFtZQkAoggBBQ5hc3NldFRvTmFtZUtleQQHZnJlZU9sZAMJAQlpc0RlZmluZWQBBQdvbGROYW1lCQDMCAIJAQtEZWxldGVFbnRyeQEJARprZXlMYW5kQ3VzdG9tTmFtZVRvQXNzZXRJZAEJAQV2YWx1ZQEFB29sZE5hbWUFA25pbAUDbmlsCQDOCAIJAM0IAgkAzQgCBQdmcmVlT2xkCQELU3RyaW5nRW50cnkCBQ5hc3NldFRvTmFtZUtleQUKY3VzdG9tTmFtZQkBC1N0cmluZ0VudHJ5AgUKcmV2ZXJzZUtleQUHYXNzZXRJZAgJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgUEYWRkcgUMeHBDdXN0b21OYW1lAl8xAwkAAAICBERVQ0sFByRtYXRjaDAEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQdhc3NldElkAwMJAQEhAQkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQYJAQEhAQkBCWlzRGVmaW5lZAEJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgkAAgEJAKwCAggFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARBrZXlEdWNrSWRUb093bmVyAQUHYXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKRFVDS1BSRUZJWAINIGlzIG5vdCB5b3VycwQKcmV2ZXJzZUtleQkBGmtleUR1Y2tDdXN0b21OYW1lVG9Bc3NldElkAQUKY3VzdG9tTmFtZQQJbmFtZU93bmVyCQCiCAEFCnJldmVyc2VLZXkDCQEJaXNEZWZpbmVkAQUJbmFtZU93bmVyCQACAQkArAICAhlOYW1lIGFscmVhZHkgcmVnaXN0ZXJlZDogBQpjdXN0b21OYW1lBA5hc3NldFRvTmFtZUtleQkBGmtleUR1Y2tBc3NldElkVG9DdXN0b21OYW1lAQUHYXNzZXRJZAQHb2xkTmFtZQkAoggBBQ5hc3NldFRvTmFtZUtleQQHZnJlZU9sZAMJAQlpc0RlZmluZWQBBQdvbGROYW1lCQDMCAIJAQtEZWxldGVFbnRyeQEJARprZXlEdWNrQ3VzdG9tTmFtZVRvQXNzZXRJZAEJAQV2YWx1ZQEFB29sZE5hbWUFA25pbAUDbmlsCQDOCAIJAM0IAgkAzQgCBQdmcmVlT2xkCQELU3RyaW5nRW50cnkCBQ5hc3NldFRvTmFtZUtleQUKY3VzdG9tTmFtZQkBC1N0cmluZ0VudHJ5AgUKcmV2ZXJzZUtleQUHYXNzZXRJZAgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFB2Fzc2V0SWQFDHhwQ3VzdG9tTmFtZQJfMQkAAgECE1Vua25vd24gZW50aXR5IHR5cGUJAJQKAgkAzggCCQDNCAIFB2FjdGlvbnMJAQ5TY3JpcHRUcmFuc2ZlcgMFD2Vjb25vbXlDb250cmFjdAgFA3BtdAZhbW91bnQFC3VzZHRBc3NldElkBQ1wcm9sb2dBY3Rpb25zAAABaQEMc2V0UmVmZXJyYWxzAglvbGRQbGF5ZXIJbmV3UGxheWVyAwkBAiE9AggFAWkPY2FsbGVyUHVibGljS2V5BQNwdWIJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAMJAQEhAQkBCWlzRGVmaW5lZAEJAKYIAQUJb2xkUGxheWVyCQACAQkArAICAhFJbnZhbGlkIGFkZHJlc3M6IAUJb2xkUGxheWVyAwkBASEBCQEJaXNEZWZpbmVkAQkApggBBQluZXdQbGF5ZXIJAAIBCQCsAgICEUludmFsaWQgYWRkcmVzczogBQluZXdQbGF5ZXIEB29sZHNLZXkJAQlrZXlPbGRpZXMABARvbGRzCQCiCAEFB29sZHNLZXkEBm9sZGllcwMJAQlpc0RlZmluZWQBBQRvbGRzCQC8CQIJAQV2YWx1ZQEFBG9sZHMCAV8FA25pbAMJAQ9jb250YWluc0VsZW1lbnQCBQZvbGRpZXMFCW5ld1BsYXllcgkAAgEJAKwCAgUJbmV3UGxheWVyAiYgaXMgbm90IG5ld2JpZSAoYWxyZWFkeSBoYXMgcmVmZXJyYWxzKQQIcmVmQnlLZXkJAQ9rZXlBZGRyZXNzUmVmQnkBBQluZXdQbGF5ZXIEBXJlZkJ5CQCiCAEFCHJlZkJ5S2V5AwMJAQlpc0RlZmluZWQBBQVyZWZCeQkBCWlzRGVmaW5lZAEJAKYIAQkBBXZhbHVlAQUFcmVmQnkHCQACAQkArAICCQCsAgIFCW5ld1BsYXllcgIUIGFscmVhZHkgaGFzIHJlZkJ5OiAJAQV2YWx1ZQEFBXJlZkJ5BAdyZWZzS2V5CQETa2V5QWRkcmVzc1JlZmVycmFscwEFCW9sZFBsYXllcgQEcmVmcwkAoggBBQdyZWZzS2V5BAlyZWZzQXJyYXkDCQEJaXNEZWZpbmVkAQUEcmVmcwkAvAkCCQEFdmFsdWUBBQRyZWZzAgFfBQNuaWwDCQEPY29udGFpbnNFbGVtZW50AgUJcmVmc0FycmF5BQluZXdQbGF5ZXIJAAIBCQCsAgIJAKwCAgkArAICBQlvbGRQbGF5ZXICEiBhbHJlYWR5IGNvbnRhaW5zIAUJbmV3UGxheWVyAhEgd2l0aGluIHJlZmVycmFscwQHbmV3UmVmcwkAugkCCQDNCAIFCXJlZnNBcnJheQUJbmV3UGxheWVyAgFfBAduZXdPbGRzAwkBD2NvbnRhaW5zRWxlbWVudAIFBm9sZGllcwUJb2xkUGxheWVyCQEFdmFsdWUBBQRvbGRzCQC6CQIJAM0IAgUGb2xkaWVzBQlvbGRQbGF5ZXICAV8JAJQKAgkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFCHJlZkJ5S2V5BQlvbGRQbGF5ZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgUHcmVmc0tleQUHbmV3UmVmcwkAzAgCCQELU3RyaW5nRW50cnkCBQdvbGRzS2V5BQduZXdPbGRzBQNuaWwFDXByb2xvZ0FjdGlvbnMAAAFpARBkaXN0cmlidXRlUG9pbnRzBQhzdHJlbmd0aAhhY2N1cmFjeQlpbnRlbGxlY3QJZW5kdXJhbmNlCWRleHRlcml0eQQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQKZnJlZUtleUFjYwkBEWtleVVzZXJGcmVlUG9pbnRzAQUEYWRkcgQNZnJlZVBvaW50c0FjYwkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9zdGFraW5nQ29udHJhY3QFCmZyZWVLZXlBY2MAAAQLZnJlZUtleUR1Y2sJARFrZXlEdWNrRnJlZVBvaW50cwEFC2R1Y2tBc3NldElkBA5mcmVlUG9pbnRzRHVjawkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9zdGFraW5nQ29udHJhY3QFC2ZyZWVLZXlEdWNrAAAEB3N1bUZyZWUJAGQCBQ1mcmVlUG9pbnRzQWNjBQ5mcmVlUG9pbnRzRHVjawQPc3VtVG9EaXN0cmlidXRlCQBkAgkAZAIJAGQCCQBkAgUIc3RyZW5ndGgFCGFjY3VyYWN5BQlpbnRlbGxlY3QFCWVuZHVyYW5jZQUJZGV4dGVyaXR5AwkAZgIFD3N1bVRvRGlzdHJpYnV0ZQUHc3VtRnJlZQkAAgEJAKwCAgkArAICAg9UaGVyZSBhcmUgb25seSAJAKQDAQUHc3VtRnJlZQIaIGZyZWUgcG9pbnRzIHRvIGRpc3RyaWJ1dGUECGNoYXJzS2V5CQEMa2V5RHVja0NoYXJzAQULZHVja0Fzc2V0SWQEBWNoYXJzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0BQhjaGFyc0tleQIJMF8wXzBfMF8wAgFfBAZuZXdBY2MJAGUCBQ1mcmVlUG9pbnRzQWNjBQ9zdW1Ub0Rpc3RyaWJ1dGUJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQpmcmVlS2V5QWNjAwkAZgIAAAUGbmV3QWNjAAAFBm5ld0FjYwkAzAgCCQEMSW50ZWdlckVudHJ5AgULZnJlZUtleUR1Y2sDCQBmAgAABQZuZXdBY2MJAGQCBQ5mcmVlUG9pbnRzRHVjawUGbmV3QWNjBQ5mcmVlUG9pbnRzRHVjawkAzAgCCQELU3RyaW5nRW50cnkCBQhjaGFyc0tleQkAuQkCCQDMCAIJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUMY2hhclN0cmVuZ3RoBQhzdHJlbmd0aAkAzAgCCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDGNoYXJBY2N1cmFjeQUIYWNjdXJhY3kJAMwIAgkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQ1jaGFySW50ZWxsZWN0BQlpbnRlbGxlY3QJAMwIAgkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQ1jaGFyRW5kdXJhbmNlBQllbmR1cmFuY2UJAMwIAgkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQ1jaGFyRGV4dGVyaXR5BQlkZXh0ZXJpdHkFA25pbAIBXwUDbmlsBQ1wcm9sb2dBY3Rpb25zAAABaQEcc3BsaXRCeUdsb2JhbFdlaWdodHNSRUFET05MWQEGYW1vdW50CQCUCgIFA25pbAkBEmdldE5lZWRlZE1hdGVyaWFscwEFBmFtb3VudAFpASRzcGxpdEJ5R2xvYmFsQW5kTG9jYWxXZWlnaHRzUkVBRE9OTFkDCW1hdEFtb3VudAlyZXNBbW91bnQIdGVycmFpbnMEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQUIdGVycmFpbnMJAJQKAgUDbmlsCQCUCgIJARJnZXROZWVkZWRNYXRlcmlhbHMBBQltYXRBbW91bnQJARNkaXN0cmlidXRlQnlXZWlnaHRzAgUJcmVzQW1vdW50BQ10ZXJyYWluQ291bnRzAWkBE2dldEJhY2twYWNrUkVBRE9OTFkBC2R1Y2tBc3NldElkCQCUCgIFA25pbAkAuQkCCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAIBOgFpARRnZXRXYXJlaG91c2VSRUFET05MWQELbGFuZEFzc2V0SWQEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQECWxhbmRJbmRleAkAaQIJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBQtyZWNMYW5kU2l6ZQUFU1NJWkUECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAACQCUCgIFA25pbAkAugkCCQEMZ2V0V2FyZWhvdXNlAwkBEmtleVdhcmVob3VzZUJ5TGFuZAEFC2xhbmRBc3NldElkBQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwCAToBaQEKc2F2ZUxhc3RUeAAEBmNhbGxlcggFAWkGY2FsbGVyAwkBASEBCQEPY29udGFpbnNFbGVtZW50AgkAzAgCBQt3bGdDb250cmFjdAkAzAgCBQ9lY29ub215Q29udHJhY3QJAMwIAgUSdG91cm5hbWVudENvbnRyYWN0CQDMCAIFDWFjcmVzQ29udHJhY3QFA25pbAUGY2FsbGVyCQACAQINQWNjZXNzIGRlbmllZAkAlAoCCQEGcHJvbG9nAQUBaQAqAWkBD3VwZGF0ZUR1Y2tTdGF0cwILZHVja0Fzc2V0SWQHZGVsdGFYUAMJAQIhPQIIBQFpBmNhbGxlcgUPZWNvbm9teUNvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgULZHVja0Fzc2V0SWQFB2RlbHRhWFABaQEOdXBkYXRlQWNjU3RhdHMCBGFkZHIHZGVsdGFYUAMDCQECIT0CCAUBaQZjYWxsZXIFD2Vjb25vbXlDb250cmFjdAkBAiE9AggFAWkGY2FsbGVyBQ1hY3Jlc0NvbnRyYWN0BwkAAgECDUFjY2VzcyBkZW5pZWQJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgUEYWRkcgUHZGVsdGFYUAFpAQllcXVpcER1Y2sBCWVxdWlwbWVudAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAMJAQ9jaGVja1RvdXJuYW1lbnQBBQtkdWNrQXNzZXRJZAkAAgECGWVxdWlwRHVja19jaGVja1RvdXJuYW1lbnQDCQENY2hlY2tEZWxpdmVyeQEFC2R1Y2tBc3NldElkCQACAQIXZXF1aXBEdWNrX2NoZWNrRGVsaXZlcnkEBWVxS2V5CQEQa2V5RHVja0VxdWlwbWVudAEFC2R1Y2tBc3NldElkBAtjdXJyZW50U2VncwkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEFBWVxS2V5AhcsOyxfLDssXyw7LF8sOyxfLDssXyw7LAIBXwQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBW5ld0VxCQC1CQIFCWVxdWlwbWVudAIBXwMJAQIhPQIJAJADAQUFbmV3RXEFC05VTVNFR01FTlRTCQACAQIWV3JvbmcgZXF1aXBtZW50IHN0cmluZwQJdGVtcFByb2RCCQEGZHJlc3NCBAULY3VycmVudFNlZ3MJAQ5wcm9kU3RyVG9CeXRlcwEJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAYFA25pbAQIc2VnQnBBdXgJAJEDAgkAtQkCCQCRAwIFBW5ld0VxBQtzZWdCYWNrcGFjawIBOwABBApidWZmRWZmZWN0AwkAAAIFCHNlZ0JwQXV4AgAAAAQEYXV4MAkAkQMCCQC1CQIFCHNlZ0JwQXV4AgEsAAADCQAAAgUEYXV4MAIAAAAEBmlkeENudAkAtQkCBQRhdXgwAgE6BANpZHgJAJEDAgUGaWR4Q250AAAEA2NudAkAkQMCBQZpZHhDbnQAAQMDAwMDCQAAAgUDaWR4AgIwNgYJAAACBQNpZHgCAjA3BgkAAAIFA2lkeAICMDgJAQIhPQIFA2NudAIABwkAZgIJAQ1wYXJzZUludFZhbHVlAQUDY250AAAHCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkAtQkCCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgJAQ1wYXJzZUludFZhbHVlAQUDaWR4AgFfBQpySWR4RWZmZWN0AAAEBXN0YXRzCQEMZ2V0RHVja1N0YXRzBAUEdGhpcwULZHVja0Fzc2V0SWQFCmJ1ZmZFZmZlY3QGBAhuZXdQcm9kQgkBBmRyZXNzQgQFBW5ld0VxBQl0ZW1wUHJvZEIHBQVzdGF0cwQKbmV3UHJvZFN0cgkBDmJ5dGVzVG9Qcm9kU3RyAQUIbmV3UHJvZEIJAJQKAgkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWVxS2V5BQllcXVpcG1lbnQJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALoJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0CQDMCAIFCm5ld1Byb2RTdHIFA25pbAIBOgkAzAgCCQELU3RyaW5nRW50cnkCCQEMa2V5RHVja0J1ZmZzAQULZHVja0Fzc2V0SWQJALkJAgkAzAgCCQCkAwEJAJEDAgUFc3RhdHMABwkAzAgCCQCkAwEJAJEDAgUFc3RhdHMACAkAzAgCCQCkAwEJAJEDAgUFc3RhdHMACQkAzAgCCQCkAwEJAJEDAgUFc3RhdHMACgkAzAgCCQCkAwEJAJEDAgUFc3RhdHMACwUDbmlsAgFfBQNuaWwFDXByb2xvZ0FjdGlvbnMAAAFpAQ9mb3J0aWZpY2F0ZUxhbmQCC2xhbmRBc3NldElkBHBsYW4EDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAtkdWNrQXNzZXRJZAkBC3ZhbHVlT3JFbHNlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAgAECWR1Y2tTdGF0cwkBDGdldER1Y2tTdGF0cwQFBHRoaXMFC2R1Y2tBc3NldElkAAAHBAdmb3J0S2V5CQEXa2V5Rm9ydGlmaWNhdGlvbnNCeUxhbmQBBQtsYW5kQXNzZXRJZAQMY3VycmVudEZvcnRzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUHZm9ydEtleQIMOjBfMTU6MF8xODowAgFfBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAlsYW5kSW5kZXgJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwULcmVjTGFuZFNpemUFBVNTSVpFBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAQCd2gJAQxnZXRXYXJlaG91c2UDBQV3aEtleQUJbGFuZEluZGV4BQppbmZyYUxldmVsBAdjdXJMb2Z0CQC1CQIJAJEDAgUCd2gFCXdoSWR4TE9GVAIBXwQEY3VyTwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2N1ckxvZnQFC3ZvbE9jY3VwaWVkBARjdXJGCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHY3VyTG9mdAUHdm9sRnJlZQQIbmV3Rm9ydHMJALUJAgUEcGxhbgIBXwQPJHQwMTAyOTk0MTAzMTA5CQEFZm9ydEIGBQxjdXJyZW50Rm9ydHMJAQ5wcm9kU3RyVG9CeXRlcwEJAJEDAgUCd2gFCXdoSWR4UHJvZAUEY3VyTwUEY3VyRgYFA25pbAQJdGVtcFByb2RCCAUPJHQwMTAyOTk0MTAzMTA5Al8xBAV0ZW1wTwgFDyR0MDEwMjk5NDEwMzEwOQJfMgQFdGVtcEYIBQ8kdDAxMDI5OTQxMDMxMDkCXzMEDyR0MDEwMzExMjEwMzIwOAkBBWZvcnRCBgUIbmV3Rm9ydHMFCXRlbXBQcm9kQgUFdGVtcE8FBXRlbXBGBwUJZHVja1N0YXRzBAhuZXdQcm9kQggFDyR0MDEwMzExMjEwMzIwOAJfMQQEbmV3TwgFDyR0MDEwMzExMjEwMzIwOAJfMgQEbmV3RggFDyR0MDEwMzExMjEwMzIwOAJfMwQKbmV3UHJvZFN0cgkBDmJ5dGVzVG9Qcm9kU3RyAQUIbmV3UHJvZEIECm5ld0xvZnRTdHIJALkJAgkAzAgCCQCRAwIFB2N1ckxvZnQFCXZvbExvY2tlZAkAzAgCCQCkAwEFBG5ld08JAMwIAgkApAMBBQRuZXdGCQDMCAIJAJEDAgUHY3VyTG9mdAUIdm9sVG90YWwFA25pbAIBXwkAlAoCCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUHZm9ydEtleQUEcGxhbgkAzAgCCQELU3RyaW5nRW50cnkCBQV3aEtleQkAugkCCQDMCAIJAJEDAgUCd2gFC3doSWR4TGV2ZWxzCQDMCAIJAJEDAgUCd2gFCHdoSWR4UmVzCQDMCAIJAJEDAgUCd2gFCHdoSWR4TWF0CQDMCAIFCm5ld1Byb2RTdHIJAMwIAgUKbmV3TG9mdFN0cgUDbmlsAgE6BQNuaWwFDXByb2xvZ0FjdGlvbnMAAAFpARNpbml0RHVja1RvdXJBdHRlbXB0AQtkdWNrQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUSdG91cm5hbWVudENvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAVtYXhIUAkBCW1heEhlYWx0aAEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDGtleUR1Y2tMZXZlbAEFC2R1Y2tBc3NldElkAAAECWN1ckhlYWx0aAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgFBW1heEhQBAljdXJMb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQUJY3VyTG9jS2V5BQ9ERUZBVUxUTE9DQVRJT04EBmxhc3RJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBRJ0b3VybmFtZW50Q29udHJhY3QFDWxhc3RUb3VySWRLZXkAAAQMdG91ckxvY2F0aW9uCQCsAgIJAKQDAQUGbGFzdElkAgRfVF8wCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ5rZXlTYXZlZEhlYWx0aAEFC2R1Y2tBc3NldElkBQljdXJIZWFsdGgJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAUFbWF4SFAJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGtleVNhdmVkTG9jYXRpb24BBQtkdWNrQXNzZXRJZAULY3VyTG9jYXRpb24JAMwIAgkBC1N0cmluZ0VudHJ5AgUJY3VyTG9jS2V5BQx0b3VyTG9jYXRpb24FA25pbAUMdG91ckxvY2F0aW9uAWkBDGJyZWFrQXR0ZW1wdAAEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAljdXJMb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQUJY3VyTG9jS2V5BQ9ERUZBVUxUTE9DQVRJT04DCQECIT0CCQCRAwIJALUJAgULY3VyTG9jYXRpb24CAV8FCmxvY0lkeFR5cGUCAVQJAAIBAiJZb3VyIGR1Y2sgaXMgbm90IGluIHRoZSB0b3VybmFtZW50BAtzYXZlZEhlYWx0aAkBEUBleHRyTmF0aXZlKDEwNTUpAQkBDmtleVNhdmVkSGVhbHRoAQULZHVja0Fzc2V0SWQEDXNhdmVkTG9jYXRpb24JARFAZXh0ck5hdGl2ZSgxMDU4KQEJARBrZXlTYXZlZExvY2F0aW9uAQULZHVja0Fzc2V0SWQJAJQKAgkAzQgCCQDNCAIFDXByb2xvZ0FjdGlvbnMJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBQtzYXZlZEhlYWx0aAkBC1N0cmluZ0VudHJ5AgUJY3VyTG9jS2V5BQ1zYXZlZExvY2F0aW9uBQtjdXJMb2NhdGlvbgFpARZleGl0VG91cm5hbWVudEludGVybmFsAQtkdWNrQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECDUFjY2VzcyBkZW5pZWQEC3NhdmVkSGVhbHRoCQERQGV4dHJOYXRpdmUoMTA1NSkBCQEOa2V5U2F2ZWRIZWFsdGgBBQtkdWNrQXNzZXRJZAQNc2F2ZWRMb2NhdGlvbgkBEUBleHRyTmF0aXZlKDEwNTgpAQkBEGtleVNhdmVkTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBQtzYXZlZEhlYWx0aAkAzAgCCQELU3RyaW5nRW50cnkCCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFDXNhdmVkTG9jYXRpb24FA25pbAcBaQEUZXhpdERlbGl2ZXJ5SW50ZXJuYWwBC2R1Y2tBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQINQWNjZXNzIGRlbmllZAQBZQkBEmV4aXREZWxpdmVyeUNvbW1vbgEFC2R1Y2tBc3NldElkCQCUCgIJAM4IAggFAWUCXzEIBQFlAl8yBwFpARBhdXRvRXhpdERlbGl2ZXJ5AQtkdWNrQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECDUFjY2VzcyBkZW5pZWQEAWUJARJleGl0RGVsaXZlcnlDb21tb24BBQtkdWNrQXNzZXRJZAkAlAoCCAUBZQJfMQkAlAoCCAUBZQJfMwgFAWUCXzQBaQEOcHJlcGFyZVJvYmJlcnkCB21lc3NhZ2UDc2lnBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQEhAQkAxBMDBQdtZXNzYWdlBQNzaWcFA3B1YgkAAgECGHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABAZ3bGdBbXQIBQNwbXQGYW1vdW50AwMJAQEhAQkBCWlzRGVmaW5lZAEIBQNwbXQHYXNzZXRJZAYJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAUKd2xnQXNzZXRJZAkAAgECFVdMR09MRCBwYXltZW50cyBvbmx5IQQFcGFydHMJALUJAgkAsAkBBQdtZXNzYWdlAgF8AwkBAiE9AgkAkAMBBQVwYXJ0cwACCQACAQIUV3JvbmcgbWVzc2FnZSBmb3JtYXQEC2R1Y2tBc3NldElkCQCRAwIFBXBhcnRzAAADCQEPY2hlY2tUb3VybmFtZW50AQULZHVja0Fzc2V0SWQJAAIBAh5wcmVwYXJlUm9iYmVyeV9jaGVja1RvdXJuYW1lbnQDCQENY2hlY2tEZWxpdmVyeQEFC2R1Y2tBc3NldElkCQACAQIccHJlcGFyZVJvYmJlcnlfY2hlY2tEZWxpdmVyeQQHcm9iQ29zdAgJAQ5nZXRSb2JiZXJ5RGF0YQIFBHRoaXMFC2R1Y2tBc3NldElkAl8xAwkAZgIFB3JvYkNvc3QFBndsZ0FtdAkAAgEJAKwCAgkArAICCQCsAgICCFBheW1lbnQgCQCkAwEFBndsZ0FtdAIMIDwgcmVxdWlyZWQgCQCkAwEFB3JvYkNvc3QECmNhbmRpZGF0ZXMJALUJAgkAkQMCBQVwYXJ0cwABAgFfBANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wBAlkdWNrU3RhdGUJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBE2tleUR1Y2tSb2JiZXJ5U3RhdGUBBQtkdWNrQXNzZXRJZAAABApsb2NrZWRMYW5kCQELdmFsdWVPckVsc2UCCQCiCAEJARNrZXlMb2NrZWRMYW5kQnlEdWNrAQULZHVja0Fzc2V0SWQCAAQHbGFuZEVUQQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQESa2V5TGFuZENvb2xkb3duRVRBAQUKbG9ja2VkTGFuZAAAAwMJAQIhPQIFCWR1Y2tTdGF0ZQULZHVja0lkeEZyZWUJAGYCBQdsYW5kRVRBBQNub3cHCQACAQkArAICAidZb3UgYWxyZWFkeSBzdGFydGVkIHJvYmJpbmcsIHdhaXQgdGlsbCAJAKQDAQUHbGFuZEVUQQoBB2NoZWNrZXICA2FjYwtsYW5kQXNzZXRJZAQFc3RhdGUJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBE2tleUxhbmRSb2JiZXJ5U3RhdGUBBQtsYW5kQXNzZXRJZAAABAtjb29sZG93bkVUQQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQESa2V5TGFuZENvb2xkb3duRVRBAQULbGFuZEFzc2V0SWQAAAMJAGYCBQVzdGF0ZQkAkAMBBRBsYW5kUm9iQ29vbGRvd25zCQACAQINSW52YWxpZCBzdGF0ZQMJAGYCBQNub3cFC2Nvb2xkb3duRVRBBApzdGFrZWRUaW1lCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAMJAGcCAAAFCnN0YWtlZFRpbWUFA2FjYwQBYQkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAFkCQC1CQIIBQFhC2Rlc2NyaXB0aW9uAgFfBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIFAWQFC3JlY0xhbmRTaXplBAxwcm9kdWN0aXZpdHkJAQxhcHBseUJvbnVzZXMCBQtsYW5kQXNzZXRJZAUGcGllY2VzBAlkZWx0YVRpbWUJAGUCBQNub3cFCnN0YWtlZFRpbWUECGF2YWlsUmVzCQBrAwUJZGVsdGFUaW1lCQBoAgUMcHJvZHVjdGl2aXR5BQZwaWVjZXMFCURBWU1JTExJUwMJAGYCBQ5NSU5fUkVTX1RPX1JPQgUIYXZhaWxSZXMFA2FjYwkAzQgCBQNhY2MFC2xhbmRBc3NldElkBQNhY2MECGZpbHRlcmVkCgACJGwFCmNhbmRpZGF0ZXMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2NoZWNrZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoDCQAAAgkAkAMBBQhmaWx0ZXJlZAAACQACAQIZTm8gY2FuZGlkYXRlcyBmb3Igcm9iYmVyeQQGcm5kSWR4CQEPZ2V0UmFuZG9tTnVtYmVyAwkAkAMBBQhmaWx0ZXJlZAUGaGVpZ2h0CQDLAQIFA3NpZwgFAWkNdHJhbnNhY3Rpb25JZAQLbGFuZEFzc2V0SWQJAJEDAgUIZmlsdGVyZWQFBnJuZElkeAkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJARNrZXlMYW5kUm9iYmVyeVN0YXRlAQULbGFuZEFzc2V0SWQFDHJvYklkeExvY2tlZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmtleUxhbmRDb29sZG93bkVUQQEFC2xhbmRBc3NldElkCQBkAgUDbm93CQCRAwIFEGxhbmRSb2JDb29sZG93bnMFDHJvYklkeExvY2tlZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBE2tleUR1Y2tSb2JiZXJ5U3RhdGUBBQtkdWNrQXNzZXRJZAUQZHVja0lkeFByZXBhcmluZwkAzAgCCQELU3RyaW5nRW50cnkCCQETa2V5TG9ja2VkTGFuZEJ5RHVjawEFC2R1Y2tBc3NldElkBQtsYW5kQXNzZXRJZAUDbmlsBQ1wcm9sb2dBY3Rpb25zBQtsYW5kQXNzZXRJZAFpAQdyb2JMYW5kAgdtZXNzYWdlA3NpZwQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQEBIQEJAMQTAwUHbWVzc2FnZQUDc2lnBQNwdWIJAAIBAhhzaWduYXR1cmUgZG9lcyBub3QgbWF0Y2gECHVzZXJBZGRyCQClCAEIBQFpBmNhbGxlcgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQh1c2VyQWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAlAoCCQDNCAIFDXByb2xvZ0FjdGlvbnMJAQxJbnRlZ2VyRW50cnkCCQEYa2V5TGFzdFJvYmJlcnlUaW1lQnlEdWNrAQULZHVja0Fzc2V0SWQFA25vdwAAAWkBDmFjY2VwdERlbGl2ZXJ5AAMJAQEhAQURS1NfQUxMT1dfREVMSVZFUlkJAAIBAh9EZWxpdmVyeSBmZWF0dXJlIGlzIHR1cm5lZCBvZmYhBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQQIdXNlckFkZHIJAKUIAQgFAWkGY2FsbGVyBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFCHVzZXJBZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAlmdW5kVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPZWNvbm9teUNvbnRyYWN0BQ9kZWxpdmVyeUZ1bmRLZXkAAAQLbG9ja2VkVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPZWNvbm9teUNvbnRyYWN0BRFkZWxpdmVyeUxvY2tlZEtleQAAAwkAZgIFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQkAZQIFCWZ1bmRUb3RhbAULbG9ja2VkVG90YWwJAAIBCQCsAgIJAKwCAgkArAICAiBEZWxpdmVyeSBpcyBub3QgYXZhaWxhYmxlLCBmdW5kPQkBCmZpeGVkUG9pbnQCBQlmdW5kVG90YWwABgIJLCBsb2NrZWQ9CQEKZml4ZWRQb2ludAIFC2xvY2tlZFRvdGFsAAYEA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAECGRlbGF5RVRBCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlEZWxpdmVyeURlbGF5QnlEdWNrAQULZHVja0Fzc2V0SWQAAAMJAGYCBQhkZWxheUVUQQUDbm93CQACAQkArAICAipEZWxpdmVyeSBpcyBmb3JiaWRkZW4gZm9yIHlvdXIgZHVjayB1bnRpbCAJAKQDAQUIZGVsYXlFVEEDCQEPY2hlY2tUb3VybmFtZW50AQULZHVja0Fzc2V0SWQJAAIBAh5hY2NlcHREZWxpdmVyeV9jaGVja1RvdXJuYW1lbnQDCQENY2hlY2tEZWxpdmVyeQEFC2R1Y2tBc3NldElkCQACAQIcYWNjZXB0RGVsaXZlcnlfY2hlY2tEZWxpdmVyeQQObmV3TG9ja2VkVG90YWwJAQVhc0ludAEJAPwHBAUPZWNvbm9teUNvbnRyYWN0AhR1cGRhdGVEZWxpdmVyeUxvY2tlZAkAzAgCCQBkAgULbG9ja2VkVG90YWwFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQUDbmlsBQNuaWwECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAQFbWF4SFAJAQltYXhIZWFsdGgBCQELdmFsdWVPckVsc2UCCQCfCAEJAQxrZXlEdWNrTGV2ZWwBBQtkdWNrQXNzZXRJZAAABAljdXJIZWFsdGgJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoBQVtYXhIUAQJY3VyTG9jS2V5CQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQEC2N1ckxvY2F0aW9uCQELdmFsdWVPckVsc2UCCQCiCAEFCWN1ckxvY0tleQUPREVGQVVMVExPQ0FUSU9OBBBkZWxpdmVyeUxvY2F0aW9uCQCsAgIJAKQDAQUDbm93AgRfRF8wCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDmtleVNhdmVkSGVhbHRoAQULZHVja0Fzc2V0SWQFCWN1ckhlYWx0aAkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoBQVtYXhIUAkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5U2F2ZWRMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQtjdXJMb2NhdGlvbgkAzAgCCQELU3RyaW5nRW50cnkCBQljdXJMb2NLZXkFEGRlbGl2ZXJ5TG9jYXRpb24FA25pbAUNcHJvbG9nQWN0aW9ucwkAlAoCBRBkZWxpdmVyeUxvY2F0aW9uBQ5uZXdMb2NrZWRUb3RhbAA2To/T", "height": 3849937, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 6RNhPfQmufLWVgs3EMjAg5xHFruSmrQYTLAjqVVRHF58 Next: HvHzbpAFiGU3ucRJxSUQT7L3sZh2S7bLT63iDdkekPuy Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let DAYMILLIS = 86400000
5+
46 func keyLastArbTimeByUser (addr) = ("lastArbTimeUser_" + addr)
57
68
100102
101103
102104 func keyLockedLandByDuck (duckAssetId) = ("lockedLandByDuck_" + duckAssetId)
105+
106+
107+func keyDeliveryDelayByDuck (duckAssetId) = ("deliveryDelayByDuck_" + duckAssetId)
103108
104109
105110 let xpClaim = 10000
169174
170175 let DAILYRESBYPIECE = 3456000
171176
172-let DAYMILLIS = 86400000
173-
174177 let WHMULTIPLIER = 10000000000
175178
176179 let DEFAULTLOCATION = "Africa_F_Africa"
179182
180183 let ESSELLCOEF = 10
181184
185+let MIN_USDT_FEE_DELIVERY = 50000
186+
187+let TEN_MINUTES_MILLIS = 600000
188+
182189 let prodTypes = ["First Aid Kit L1", "First Aid Kit L2", "First Aid Kit L3", "Backpack L1", "Backpack L2", "Backpack L3", "Food Ration L1", "Food Ration L2", "Food Ration L3", "Jet Pack L1", "Jet Pack L2", "Jet Pack L3", "Shield L1", "Shield L2", "Shield L3", "Mine L1", "Mine L2", "Mine L3", "Trap L1", "Trap L2", "Trap L3"]
183190
184191 let continents = ["Americas", "Europe", "Asia", "Africa", "Oceania"]
290297
291298 func keyEsWarehouse () = "emergencyWarehouseProducts"
292299
300+
301+let deliveryFundKey = "deliveryFund"
302+
303+let deliveryLockedKey = "deliveryLocked"
293304
294305 let lastTourIdKey = "%s__lastTourId"
295306
334345 }
335346
336347
348+func isInDelivery (location) = {
349+ let loc = split(location, "_")
350+ let now = lastBlock.timestamp
351+ let startTime = parseIntValue(loc[locIdxContinent])
352+ let distance = parseIntValue(loc[locIdxId])
353+ if (if ((loc[locIdxType] == "D"))
354+ then (now > (startTime + TEN_MINUTES_MILLIS))
355+ else false)
356+ then (3 >= distance)
357+ else false
358+ }
359+
360+
361+func isUsualLocation (location) = {
362+ let locType = split(location, "_")[locIdxType]
363+ if ((locType != "T"))
364+ then (locType != "D")
365+ else false
366+ }
367+
368+
369+func notOnMission (tourContract,location) = {
370+ let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
371+ let loc = split(location, "_")
372+ let now = lastBlock.timestamp
373+ let tData = getTourData(tourContract, lastId)
374+ let static = tData[idxStatic]
375+ let dynamic = tData[idxDynamic]
376+ let locType = loc[locIdxType]
377+ if (if ((locType != "T"))
378+ then (locType != "D")
379+ else false)
380+ then true
381+ else !(if (if (if ((loc[locIdxType] == "T"))
382+ then (parseIntValue(loc[locIdxContinent]) == lastId)
383+ else false)
384+ then (dynamic[tDynamicStatus] == "INPROGRESS")
385+ else false)
386+ then (parseIntValue(static[tStaticEnd]) > now)
387+ else false)
388+ }
389+
390+
337391 func getRecipeMaterials (recipe) = (parseIntValue(recipe[rIdxCoeff]) * COEFF2MAT)
338392
339393
394+func cheatAttempt (oldLoc,newLoc) = throw(((("Cheat attempt: oldLoc=" + oldLoc) + ", newLoc=") + newLoc))
395+
396+
340397 let KS_SEPARATE_PUBLIC_KEY = false
341398
342399 let KS_ALLOW_BIG_INFRA_MERGE = false
400+
401+let KS_ALLOW_DELIVERY = false
343402
344403 let chain = take(drop(this.bytes, 1), 1)
345404
410469
411470 let IdxCfgTournamentDapp = 7
412471
472+let IdxCfgAcresDapp = 8
473+
413474 func keyRestCfg () = "%s__restConfig"
414475
415476
436497
437498 let tournamentContract = getContractAddressOrFail(restCfg, IdxCfgTournamentDapp)
438499
500+let acresContract = getContractAddressOrFail(restCfg, IdxCfgAcresDapp)
501+
439502 let recLandNum = 0
440503
441504 let recLandSize = 1
446509
447510 let wlgAssetIdKey = "wlg_assetId"
448511
449-let wlgAssetId = valueOrErrorMessage(getBinary(wlgContract, wlgAssetIdKey), "Not initialized yet")
512+let wlgAssetId = valueOrErrorMessage(getBinary(wlgContract, wlgAssetIdKey), "WLGOLD is not issued yet")
513+
514+let acresAssetIdKey = "acresAssetId"
515+
516+let acresAssetId = valueOrErrorMessage(getBinary(acresContract, acresAssetIdKey), "ACRES is not issued yet")
450517
451518 let randomDelay = 2
452519
486553 s
487554 case _ =>
488555 throw("fail to cast into Boolean")
556+}
557+
558+
559+func asStringIntTuple (val) = match val {
560+ case t2: (String, Int) =>
561+ t2
562+ case _ =>
563+ throw("fail to cast into (String, Int)")
489564 }
490565
491566
514589 func keyLastTxIdByUser (addr) = ("lastTxIdByUser_" + addr)
515590
516591
592+func fixedPoint (val,decimals) = {
593+ let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
594+ let lowPart = toString((val % tenPow))
595+ let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
596+ (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
597+ }
598+
599+
517600 func getRandomNumber (maxValue,finishHeight,auxEntropy) = {
518601 let randomSeedBlock = value(blockInfoByHeight(finishHeight))
519602 let randomHash = sha256((value(randomSeedBlock.vrf) + auxEntropy))
577660 then 250000000
578661 else throw("Unknown chain")
579662 }
663+
664+let S_COST_ACRES = 2500000000
580665
581666 let FIVEX = toBigInt(5)
582667
16541739
16551740
16561741 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
1657- let $t03370634245 = if ((claimMode == claimModeWh))
1742+ let $t03373834277 = if ((claimMode == claimModeWh))
16581743 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
16591744 else {
16601745 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
16641749 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
16651750 else $Tuple2(loc[locIdxId], duckAssetId)
16661751 }
1667- let landAssetId = $t03370634245._1
1668- let duckId = $t03370634245._2
1752+ let landAssetId = $t03373834277._1
1753+ let duckId = $t03373834277._2
16691754 let asset = value(assetInfo(fromBase58String(landAssetId)))
16701755 let timeKey = keyStakedTimeByAssetId(landAssetId)
16711756 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
17131798 let currentPack = getBackpack(bpKey)
17141799 let currentPackRes = split(currentPack[bpIdxRes], "_")
17151800 let currentWhRes = split(currentWh[whIdxRes], "_")
1716- let $t03661937490 = if ((claimMode == claimModeWh))
1801+ let $t03665137522 = if ((claimMode == claimModeWh))
17171802 then $Tuple4(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes], (parseIntValue(loft[volOccupied]) + resToClaim._2), (parseIntValue(loft[volFree]) - resToClaim._2))
17181803 else if ((claimMode == claimModeDuck))
17191804 then $Tuple4(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), parseIntValue(loft[volOccupied]), parseIntValue(loft[volFree]))
17221807 let whAm = min([parseIntValue(loft[volFree]), resToClaim._2])
17231808 $Tuple4(distr._1, distr._2, (parseIntValue(loft[volOccupied]) + whAm), (parseIntValue(loft[volFree]) - whAm))
17241809 }
1725- let whRes = $t03661937490._1
1726- let bpRes = $t03661937490._2
1727- let loftO = $t03661937490._3
1728- let loftF = $t03661937490._4
1810+ let whRes = $t03665137522._1
1811+ let bpRes = $t03665137522._2
1812+ let loftO = $t03665137522._3
1813+ let loftF = $t03665137522._4
17291814 $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]], "_")])
17301815 }
17311816 }
18631948 }
18641949
18651950
1951+func checkDelivery (duckAssetId) = if (!(KS_ALLOW_DELIVERY))
1952+ then false
1953+ else {
1954+ let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
1955+ let now = lastBlock.timestamp
1956+ if ((curLocation[locIdxType] != "D"))
1957+ then false
1958+ else {
1959+ let startTime = parseIntValue(curLocation[locIdxContinent])
1960+ let distance = parseIntValue(curLocation[locIdxId])
1961+ if (if ((now > (startTime + TEN_MINUTES_MILLIS)))
1962+ then (3 > distance)
1963+ else false)
1964+ then throw("Your duck is on delivery mission")
1965+ else asBoolean(invoke(this, "exitDeliveryInternal", [duckAssetId], nil))
1966+ }
1967+ }
1968+
1969+
1970+func exitDeliveryCommon (duckAssetId) = {
1971+ let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
1972+ let now = lastBlock.timestamp
1973+ let startTime = parseIntValue(curLocation[locIdxContinent])
1974+ let distance = parseIntValue(curLocation[locIdxId])
1975+ let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(duckAssetId)), "NFT duck is orphaned")
1976+ let healthKey = keyDuckHealth(duckAssetId)
1977+ let curHealth = getIntegerValue(healthKey)
1978+ let outcomeActions = if ((distance >= 3))
1979+ then {
1980+ let reward = invoke(economyContract, "sendDeliveryReward", [owner], nil)
1981+ if ((reward == reward))
1982+ then nil
1983+ else throw("Strict value is not equal to itself.")
1984+ }
1985+ else if ((now > (startTime + TEN_MINUTES_MILLIS)))
1986+ then throw("Your duck is still on delivery mission")
1987+ else {
1988+ let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
1989+ let unlock = invoke(economyContract, "updateDeliveryLocked", [(lockedTotal - MIN_USDT_FEE_DELIVERY)], nil)
1990+ if ((unlock == unlock))
1991+ then if ((0 >= curHealth))
1992+ then nil
1993+ else [IntegerEntry(keyDeliveryDelayByDuck(duckAssetId), (startTime + DAYMILLIS))]
1994+ else throw("Strict value is not equal to itself.")
1995+ }
1996+ let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
1997+ let savedLocation = getStringValue(keySavedLocation(duckAssetId))
1998+ $Tuple4(outcomeActions, [IntegerEntry(healthKey, savedHealth), StringEntry(keyDuckLocation(duckAssetId), savedLocation)], savedLocation, savedHealth)
1999+ }
2000+
2001+
18662002 func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,needMat) = {
18672003 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
18682004 if (checkTournament(duckAssetId))
18692005 then throw("mergeInternal_checkTournament")
1870- else {
1871- func checkMerge (acc,landAssetId) = {
1872- let asset = value(assetInfo(fromBase58String(landAssetId)))
1873- let timeKey = keyStakedTimeByAssetId(landAssetId)
1874- let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
1875- let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
1876- if ((owner != addr))
1877- then throw((LANDPREFIX + " is not yours"))
1878- else {
1879- let d = split(asset.description, "_")
1880- let continent = d[recContinent]
1881- if (if ((acc._3 != ""))
1882- then (acc._3 != continent)
1883- else false)
1884- then throw("Lands should be on the same continent to merge")
1885- else {
1886- let landSize = d[recLandSize]
1887- let sizesIn = acc._1
1888- let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
1889- let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
1890- let pieces = numPiecesBySize(landSize)
1891- let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
1892- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1893- let reqLevel = match landSize {
1894- case _ =>
1895- if (("S" == $match0))
1896- then 3
1897- else if (("M" == $match0))
1898- then 4
1899- else if (("L" == $match0))
1900- then 5
1901- else if (("XL" == $match0))
1902- then 6
1903- else throw("Only S, M, L, XL can merge")
1904- }
1905- if ((infraLevel != reqLevel))
1906- then throw("All lands should be maxed to merge")
1907- else {
1908- let landNum = d[recLandNum]
1909- let terrainCounts = countTerrains(d[recTerrains])
1910- let deltaTime = (lastBlock.timestamp - savedTime)
1911- if ((0 > deltaTime))
1912- then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
1913- else {
1914- let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
1915- let landIndex = (pieces / SSIZE)
1916- let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
1917- let props = updateProportionsInternal(acc._6, terrainCounts, landIndex, -1)
1918- let cProps = updateProportionsInternal(acc._10, terrainCounts, landIndex, -1)
1919- let sumTerrains = updateProportionsInternal(acc._9, terrainCounts, landIndex, 1)
1920- let lands = acc._7
1921- let idx = indexOf(lands, landAssetId)
1922- if (!(isDefined(idx)))
1923- then throw(("Your staked lands don't contain " + landAssetId))
1924- else {
1925- let customKey = keyLandAssetIdToCustomName(landAssetId)
1926- let customName = valueOrElse(getString(customKey), "")
1927- $Tuple10(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(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ Burn(fromBase58String(landAssetId), 1)) ++ (if ((customName != ""))
1928- then [DeleteEntry(keyLandCustomNameToAssetId(customName))]
1929- else nil)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces), sumTerrains, cProps)
1930- }
1931- }
1932- }
1933- }
1934- }
2006+ else if (checkDelivery(duckAssetId))
2007+ then throw("mergeInternal_checkDelivery")
2008+ else {
2009+ func checkMerge (acc,landAssetId) = {
2010+ let asset = value(assetInfo(fromBase58String(landAssetId)))
2011+ let timeKey = keyStakedTimeByAssetId(landAssetId)
2012+ let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
2013+ let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
2014+ if ((owner != addr))
2015+ then throw((LANDPREFIX + " is not yours"))
2016+ else {
2017+ let d = split(asset.description, "_")
2018+ let continent = d[recContinent]
2019+ if (if ((acc._3 != ""))
2020+ then (acc._3 != continent)
2021+ else false)
2022+ then throw("Lands should be on the same continent to merge")
2023+ else {
2024+ let landSize = d[recLandSize]
2025+ let sizesIn = acc._1
2026+ let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
2027+ let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
2028+ let pieces = numPiecesBySize(landSize)
2029+ let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
2030+ let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
2031+ let reqLevel = match landSize {
2032+ case _ =>
2033+ if (("S" == $match0))
2034+ then 3
2035+ else if (("M" == $match0))
2036+ then 4
2037+ else if (("L" == $match0))
2038+ then 5
2039+ else if (("XL" == $match0))
2040+ then 6
2041+ else throw("Only S, M, L, XL can merge")
2042+ }
2043+ if ((infraLevel != reqLevel))
2044+ then throw("All lands should be maxed to merge")
2045+ else {
2046+ let landNum = d[recLandNum]
2047+ let terrainCounts = countTerrains(d[recTerrains])
2048+ let deltaTime = (lastBlock.timestamp - savedTime)
2049+ if ((0 > deltaTime))
2050+ then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
2051+ else {
2052+ let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
2053+ let landIndex = (pieces / SSIZE)
2054+ let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
2055+ let props = updateProportionsInternal(acc._6, terrainCounts, landIndex, -1)
2056+ let cProps = updateProportionsInternal(acc._10, terrainCounts, landIndex, -1)
2057+ let sumTerrains = updateProportionsInternal(acc._9, terrainCounts, landIndex, 1)
2058+ let lands = acc._7
2059+ let idx = indexOf(lands, landAssetId)
2060+ if (!(isDefined(idx)))
2061+ then throw(("Your staked lands don't contain " + landAssetId))
2062+ else {
2063+ let customKey = keyLandAssetIdToCustomName(landAssetId)
2064+ let customName = valueOrElse(getString(customKey), "")
2065+ $Tuple10(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(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ Burn(fromBase58String(landAssetId), 1)) ++ (if ((customName != ""))
2066+ then [DeleteEntry(keyLandCustomNameToAssetId(customName))]
2067+ else nil)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces), sumTerrains, cProps)
2068+ }
2069+ }
2070+ }
2071+ }
2072+ }
2073+ }
2074+
2075+ let bpKey = keyBackpackByDuck(duckAssetId)
2076+ let currentPack = getBackpack(bpKey)
2077+ let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
2078+ let landsKey = keyStakedLandsByOwner(addr)
2079+ let landsStr = getString(landsKey)
2080+ let landsIn = if (isDefined(landsStr))
2081+ then split_51C(value(landsStr), "_")
2082+ else nil
2083+ let cont0 = split(value(assetInfo(fromBase58String(landAssetIds[0]))).description, "_")[recContinent]
2084+ let contProps = split(valueOrElse(getString(keyResTypesByContinent(cont0)), "0_0_0_0_0_0"), "_")
2085+ let r = {
2086+ let $l = landAssetIds
2087+ let $s = size($l)
2088+ let $acc0 = $Tuple10(formula, 0, "", currentPack[bpIdxRes], nil, propList, landsIn, 0, split("0_0_0_0_0_0", "_"), contProps)
2089+ func $f0_1 ($a,$i) = if (($i >= $s))
2090+ then $a
2091+ else checkMerge($a, $l[$i])
2092+
2093+ func $f0_2 ($a,$i) = if (($i >= $s))
2094+ then $a
2095+ else throw("List size exceeds 5")
2096+
2097+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
2098+ }
2099+ let continent = r._3
2100+ let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
2101+ let terrains = genTerrainsForMerge(r._9, (numPiecesBySize(newLandSize) / SSIZE))
2102+ let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
2103+ let newLandNum = toString(freeNum)
2104+ let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
2105+ let assetId = calculateAssetId(issue)
2106+ let newLandAssetId = toBase58String(assetId)
2107+ let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
2108+ let piecesKey = keyStakedPiecesByOwner(addr)
2109+ let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
2110+ $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
2111+ then StringEntry(landsKey, makeString_11C(r._7, "_"))
2112+ else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
2113+ then 0
2114+ 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(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), makeString(r._6, "_"))) :+ StringEntry(keyResTypesByContinent(continent), makeString(r._10, "_"))) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
19352115 }
1936-
1937- let bpKey = keyBackpackByDuck(duckAssetId)
1938- let currentPack = getBackpack(bpKey)
1939- let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
1940- let landsKey = keyStakedLandsByOwner(addr)
1941- let landsStr = getString(landsKey)
1942- let landsIn = if (isDefined(landsStr))
1943- then split_51C(value(landsStr), "_")
1944- else nil
1945- let cont0 = split(value(assetInfo(fromBase58String(landAssetIds[0]))).description, "_")[recContinent]
1946- let contProps = split(valueOrElse(getString(keyResTypesByContinent(cont0)), "0_0_0_0_0_0"), "_")
1947- let r = {
1948- let $l = landAssetIds
1949- let $s = size($l)
1950- let $acc0 = $Tuple10(formula, 0, "", currentPack[bpIdxRes], nil, propList, landsIn, 0, split("0_0_0_0_0_0", "_"), contProps)
1951- func $f0_1 ($a,$i) = if (($i >= $s))
1952- then $a
1953- else checkMerge($a, $l[$i])
1954-
1955- func $f0_2 ($a,$i) = if (($i >= $s))
1956- then $a
1957- else throw("List size exceeds 5")
1958-
1959- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
1960- }
1961- let continent = r._3
1962- let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
1963- let terrains = genTerrainsForMerge(r._9, (numPiecesBySize(newLandSize) / SSIZE))
1964- let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
1965- let newLandNum = toString(freeNum)
1966- let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
1967- let assetId = calculateAssetId(issue)
1968- let newLandAssetId = toBase58String(assetId)
1969- let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
1970- let piecesKey = keyStakedPiecesByOwner(addr)
1971- let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
1972- $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
1973- then StringEntry(landsKey, makeString_11C(r._7, "_"))
1974- else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
1975- then 0
1976- 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(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), makeString(r._6, "_"))) :+ StringEntry(keyResTypesByContinent(continent), makeString(r._10, "_"))) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
1977- }
19782116 }
19792117
19802118
20082146 then valueOrElse(getBoolean(keyBlocked()), false)
20092147 else false)
20102148 then throw("Contracts are under maintenance")
2011- else StringEntry(keyLastTxIdByUser(toString(i.originCaller)), toBase58String(i.transactionId))
2149+ else {
2150+ let userAddr = toString(i.originCaller)
2151+ let duck = getString(keyStakedDuckByOwner(userAddr))
2152+ ((if (if (KS_ALLOW_DELIVERY)
2153+ then isDefined(duck)
2154+ else false)
2155+ then {
2156+ let duckAssetId = value(duck)
2157+ let locKey = keyDuckLocation(duckAssetId)
2158+ let loc = split(valueOrElse(getString(locKey), DEFAULTLOCATION), "_")
2159+ let startTime = parseIntValue(loc[locIdxContinent])
2160+ if (if ((loc[locIdxType] != "D"))
2161+ then true
2162+ else (lastBlock.timestamp > (startTime + TEN_MINUTES_MILLIS)))
2163+ then nil
2164+ else {
2165+ let healthKey = keyDuckHealth(duckAssetId)
2166+ if ((parseIntValue(loc[locIdxId]) >= 3))
2167+ then {
2168+ let reward = invoke(economyContract, "sendDeliveryReward", [userAddr], nil)
2169+ if ((reward == reward))
2170+ then nil
2171+ else throw("Strict value is not equal to itself.")
2172+ }
2173+ else (({
2174+ let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
2175+ let unlock = invoke(economyContract, "updateDeliveryLocked", [(lockedTotal - MIN_USDT_FEE_DELIVERY)], nil)
2176+ if ((unlock == unlock))
2177+ then if ((0 >= getIntegerValue(healthKey)))
2178+ then nil
2179+ else {
2180+ let punishment = invoke(this, "saveInteger", [keyDeliveryDelayByDuck(duckAssetId), (startTime + DAYMILLIS)], nil)
2181+ if ((punishment == punishment))
2182+ then nil
2183+ else throw("Strict value is not equal to itself.")
2184+ }
2185+ else throw("Strict value is not equal to itself.")
2186+ } :+ IntegerEntry(healthKey, getIntegerValue(keySavedHealth(duckAssetId)))) :+ StringEntry(locKey, getStringValue(keySavedLocation(duckAssetId))))
2187+ }
2188+ }
2189+ else nil) :+ StringEntry(keyLastTxIdByUser(userAddr), toBase58String(i.transactionId)))
2190+ }
2191+
2192+
2193+func prologFlight (i) = if (if ((i.originCaller != restContract))
2194+ then valueOrElse(getBoolean(keyBlocked()), false)
2195+ else false)
2196+ then throw("Contracts are under maintenance")
2197+ else [StringEntry(keyLastTxIdByUser(toString(i.originCaller)), toBase58String(i.transactionId))]
20122198
20132199
20142200 @Callable(i)
20192205
20202206
20212207 @Callable(i)
2208+func saveInteger (key,amount) = if ((i.caller != this))
2209+ then throw("saveInteger is not public method")
2210+ else [IntegerEntry(key, amount)]
2211+
2212+
2213+
2214+@Callable(i)
20222215 func setBlocked (isBlocked) = if ((i.caller != this))
20232216 then throw("permission denied")
20242217 else [BooleanEntry(keyBlocked(), isBlocked)]
20272220
20282221 @Callable(i)
20292222 func stakeLand () = {
2030- let prologAction = prolog(i)
2223+ let prologActions = prolog(i)
20312224 if ((size(i.payments) != 1))
20322225 then throw("Exactly one payment required")
20332226 else {
20792272 let piecesKey = keyStakedPiecesByOwner(address)
20802273 let oldPieces = valueOrElse(getInteger(piecesKey), 0)
20812274 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
2082- $Tuple2([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address), lastBlock.timestamp), StringEntry(landsKey, makeString_11C((lands :+ landAssetId), "_")), IntegerEntry(piecesKey, (oldPieces + pieces)), StringEntry(keyLandAssetIdToOwner(landAssetId), address), StringEntry(keyLandNumToOwner(landNum), address), IntegerEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, address), infraLevel), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps), prologAction], wlgResult)
2275+ $Tuple2(([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address), lastBlock.timestamp), StringEntry(landsKey, makeString_11C((lands :+ landAssetId), "_")), IntegerEntry(piecesKey, (oldPieces + pieces)), StringEntry(keyLandAssetIdToOwner(landAssetId), address), StringEntry(keyLandNumToOwner(landNum), address), IntegerEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, address), infraLevel), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps)] ++ prologActions), wlgResult)
20832276 }
20842277 }
20852278 }
20922285
20932286 @Callable(i)
20942287 func unstakeLand (landAssetIdIn) = {
2095- let prologAction = prolog(i)
2288+ let prologActions = prolog(i)
20962289 if ((size(i.payments) != 0))
20972290 then throw("No payments required")
20982291 else {
21292322 then 0
21302323 else (stakedPieces - pieces)
21312324 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr], nil)
2132- $Tuple2([ScriptTransfer(i.caller, 1, fromBase58String(landAssetId)), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr)), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps), StringEntry(claimResult._2, makeString(claimResult._3, ":")), if ((size(lands) > 1))
2325+ $Tuple2(([ScriptTransfer(i.caller, 1, fromBase58String(landAssetId)), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr)), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps), StringEntry(claimResult._2, makeString(claimResult._3, ":")), if ((size(lands) > 1))
21332326 then StringEntry(landsKey, makeString_11C(removeByIndex(lands, value(idx)), "_"))
2134- else DeleteEntry(landsKey), IntegerEntry(piecesKey, newPieces), prologAction], wlgResult)
2327+ else DeleteEntry(landsKey), IntegerEntry(piecesKey, newPieces)] ++ prologActions), wlgResult)
21352328 }
21362329 }
21372330 }
21422335
21432336 @Callable(i)
21442337 func stakeDuck () = {
2145- let prologAction = prolog(i)
2338+ let prologActions = prolog(i)
21462339 if ((size(i.payments) != 1))
21472340 then throw("Exactly one payment required")
21482341 else {
21662359 then throw((("NFT " + asset.name) + " is already staked"))
21672360 else if (isDefined(getString(keyStakedDuckByOwner(address))))
21682361 then throw(("You already staked one duck: " + asset.name))
2169- else if (checkTournament(assetIdStr))
2170- then throw("stakeDuck_checkTournament")
2171- else {
2172- let locKey = keyDuckLocation(assetIdStr)
2173- let location = getString(locKey)
2174- let bpKey = keyBackpackByDuck(assetIdStr)
2175- let backpack = getString(bpKey)
2176- let keyHealth = keyDuckHealth(assetIdStr)
2177- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2178- let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
2179- ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
2362+ else {
2363+ let locKey = keyDuckLocation(assetIdStr)
2364+ let location = getString(locKey)
2365+ let bpKey = keyBackpackByDuck(assetIdStr)
2366+ let backpack = getString(bpKey)
2367+ let keyHealth = keyDuckHealth(assetIdStr)
2368+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2369+ let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
2370+ ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
2371+ then nil
2372+ else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
21802373 then nil
2181- else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
2182- then nil
2183- else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyHealth, curHealth)) :+ prologAction)))))
2184- }
2374+ else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyHealth, curHealth)) ++ prologActions)))))
2375+ }
21852376 }
21862377 }
21872378 }
21912382
21922383 @Callable(i)
21932384 func unstakeDuck (assetIdStr) = {
2194- let prologAction = prolog(i)
2385+ let prologActions = prolog(i)
21952386 if ((size(i.payments) != 0))
21962387 then throw("No payments required")
21972388 else {
22092400 then throw("Staked NFT is not yours")
22102401 else if (checkTournament(assetIdStr))
22112402 then throw("unstakeDuck_checkTournament")
2212- else {
2213- let keyHealth = keyDuckHealth(assetIdStr)
2214- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2215- let health = valueOrElse(getInteger(keyHealth), maxHP)
2216- if ((maxHP > health))
2217- then throw((("Please heal your duck to " + toString(maxHP)) + "hp before unstaking"))
2218- 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]
2219- }
2403+ else if (checkDelivery(assetIdStr))
2404+ then throw("unstakeDuck_checkDelivery")
2405+ else {
2406+ let keyHealth = keyDuckHealth(assetIdStr)
2407+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2408+ let health = valueOrElse(getInteger(keyHealth), maxHP)
2409+ if ((maxHP > health))
2410+ then throw((("Please heal your duck to " + toString(maxHP)) + "hp before unstaking"))
2411+ else ([ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyHealth), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address))] ++ prologActions)
2412+ }
22202413 }
22212414 }
22222415 }
22252418
22262419 @Callable(i)
22272420 func claimRes (amount,landAssetIdStr) = {
2228- let prologAction = prolog(i)
2421+ let prologActions = prolog(i)
22292422 if ((size(i.payments) != 0))
22302423 then throw("No payments required")
22312424 else {
22322425 let addr = toString(i.originCaller)
22332426 let result = claimResInternal(addr, amount, claimModeDuck, landAssetIdStr)
22342427 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
2235- $Tuple2(((((result._1 ++ updateDuckStatsInternal(duckAssetId, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) :+ prologAction), result._3[bpIdxRes])
2428+ $Tuple2(((((result._1 ++ updateDuckStatsInternal(duckAssetId, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) ++ prologActions), result._3[bpIdxRes])
22362429 }
22372430 }
22382431
22402433
22412434 @Callable(i)
22422435 func claimResToWH (amount,landAssetIdStr) = {
2243- let prologAction = prolog(i)
2436+ let prologActions = prolog(i)
22442437 if ((size(i.payments) != 0))
22452438 then throw("No payments required")
22462439 else {
22472440 let addr = toString(i.originCaller)
22482441 let result = claimResInternal(addr, amount, claimModeWh, landAssetIdStr)
2249- $Tuple2(((((result._1 ++ updateAccStatsInternal(addr, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) :+ prologAction), result._5[whIdxRes])
2442+ $Tuple2(((((result._1 ++ updateAccStatsInternal(addr, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) ++ prologActions), result._5[whIdxRes])
22502443 }
22512444 }
22522445
22542447
22552448 @Callable(i)
22562449 func flight (message,sig) = {
2257- let prologAction = prolog(i)
2450+ let prologActions = prologFlight(i)
22582451 if ((size(i.payments) != 0))
22592452 then throw("No payments required")
22602453 else {
22702463 else {
22712464 let newLoc = split(newLocation, "_")
22722465 let isTour = (newLoc[locIdxType] == "T")
2466+ let isDeliv = (newLoc[locIdxType] == "D")
22732467 let eqKey = keyDuckEquipment(duckAssetId)
22742468 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2275- let $t06598166078 = subtractEquipment(currentEq, f._5)
2276- let newEq = $t06598166078._1
2277- let shouldZeroBuffs = $t06598166078._2
2278- let locToSave = if (!(isInTournament(tournamentContract, curLocation)))
2279- then if (isTour)
2280- then throw(((("Cheat attempt: oldLoc=" + curLocation) + ", newLoc=") + newLocation))
2469+ let $t07021270309 = subtractEquipment(currentEq, f._5)
2470+ let newEq = $t07021270309._1
2471+ let shouldZeroBuffs = $t07021270309._2
2472+ let $t07031273351 = if (notOnMission(tournamentContract, curLocation))
2473+ then if (!(isUsualLocation(newLocation)))
2474+ then cheatAttempt(curLocation, newLocation)
22812475 else if ((newHP > 0))
2282- then newLocation
2283- else curLocation
2284- else if (!(isInTournament(tournamentContract, newLocation)))
2285- then throw("Your duck is taking part in the tournament")
2286- else {
2287- let score = parseIntValue(newLoc[locIdxId])
2288- let curLoc = split(curLocation, "_")
2289- let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
2290- if ((score != (parseIntValue(curLoc[locIdxId]) + 1)))
2291- then throw(((("Cheat attempt: oldLoc=" + curLocation) + ", newLoc=") + newLocation))
2292- else if ((newHP > 0))
2293- then {
2294- let localBest = valueOrElse(getInteger(tournamentContract, keyBestResultByTourAndDuck(lastId, duckAssetId)), 0)
2295- let updLocal = if ((score > localBest))
2296- then invoke(tournamentContract, "saveDuckResult", [duckAssetId, score], nil)
2297- else unit
2298- if ((updLocal == updLocal))
2299- then newLocation
2300- else throw("Strict value is not equal to itself.")
2476+ then $Tuple2(newLocation, newHP)
2477+ else $Tuple2(curLocation, 0)
2478+ else if (isInTournament(tournamentContract, curLocation))
2479+ then if (!(isInTournament(tournamentContract, newLocation)))
2480+ then throw("Your duck is taking part in the tournament")
2481+ else {
2482+ let score = parseIntValue(newLoc[locIdxId])
2483+ let curLoc = split(curLocation, "_")
2484+ let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
2485+ if ((score != (parseIntValue(curLoc[locIdxId]) + 1)))
2486+ then cheatAttempt(curLocation, newLocation)
2487+ else if ((newHP > 0))
2488+ then {
2489+ let localBest = valueOrElse(getInteger(tournamentContract, keyBestResultByTourAndDuck(lastId, duckAssetId)), 0)
2490+ let updLocal = if ((score > localBest))
2491+ then invoke(tournamentContract, "saveDuckResult", [duckAssetId, score], nil)
2492+ else unit
2493+ if ((updLocal == updLocal))
2494+ then $Tuple2(newLocation, newHP)
2495+ else throw("Strict value is not equal to itself.")
2496+ }
2497+ else $Tuple2(curLocation, 0)
2498+ }
2499+ else if (!(isInDelivery(curLocation)))
2500+ then {
2501+ let locHealth = asStringIntTuple(invoke(this, "autoExitDelivery", [duckAssetId], nil))
2502+ if ((locHealth == locHealth))
2503+ then if (isDeliv)
2504+ then locHealth
2505+ else if ((newHP > 0))
2506+ then $Tuple2(newLocation, newHP)
2507+ else $Tuple2(locHealth._1, 0)
2508+ else throw("Strict value is not equal to itself.")
2509+ }
2510+ else if (!(isDeliv))
2511+ then throw("Your duck is taking part in delivery")
2512+ else if (!(isInDelivery(newLocation)))
2513+ then cheatAttempt(curLocation, newLocation)
2514+ else {
2515+ let score = parseIntValue(newLoc[locIdxId])
2516+ let curLoc = split(curLocation, "_")
2517+ if ((score != (parseIntValue(curLoc[locIdxId]) + 1)))
2518+ then cheatAttempt(curLocation, newLocation)
2519+ else if (if ((newHP > 0))
2520+ then (3 > score)
2521+ else false)
2522+ then $Tuple2(newLocation, newHP)
2523+ else {
2524+ let locHealth = asStringIntTuple(invoke(this, "autoExitDelivery", [duckAssetId], nil))
2525+ if ((locHealth == locHealth))
2526+ then locHealth
2527+ else throw("Strict value is not equal to itself.")
2528+ }
23012529 }
2302- else curLocation
2303- }
2304- $Tuple2(([StringEntry(locKey, locToSave), StringEntry(eqKey, newEq), IntegerEntry(keyDuckHealth(duckAssetId), newHP), prologAction] ++ (if (shouldZeroBuffs)
2530+ let locToSave = $t07031273351._1
2531+ let hpToSave = $t07031273351._2
2532+ $Tuple2(((([StringEntry(locKey, locToSave), StringEntry(eqKey, newEq), IntegerEntry(keyDuckHealth(duckAssetId), newHP)] ++ prologActions) ++ (if (shouldZeroBuffs)
23052533 then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
2306- else (nil ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
2307- then xpSuccessFlight
2308- else xpFailFlight)._1))), f._3)
2534+ else nil)) ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
2535+ then xpSuccessFlight
2536+ else xpFailFlight)._1), f._3)
23092537 }
23102538 }
23112539 }
23142542
23152543 @Callable(i)
23162544 func heal (quantityL1,quantityL2,quantityL3) = {
2317- let prologAction = prolog(i)
2545+ let prologActions = prolog(i)
23182546 if (if (if ((0 > quantityL1))
23192547 then true
23202548 else (0 > quantityL2))
23252553 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
23262554 if (checkTournament(duckAssetId))
23272555 then throw("heal_checkTournament")
2328- else {
2329- let qts = [quantityL1, quantityL2, quantityL3]
2330- let keyHealth = keyDuckHealth(duckAssetId)
2331- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2332- let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2333- if ((oldHealth >= maxHP))
2334- then throw((("HP should be < " + toString(maxHP)) + " to heal"))
2335- else {
2336- let bpKey = keyBackpackByDuck(duckAssetId)
2337- let currentPack = getBackpack(bpKey)
2338- let prodList = if ((currentPack[bpIdxProd] == ""))
2339- then nil
2340- else split_4C(currentPack[bpIdxProd], "_")
2341- func iterateProd (acc,recipe) = {
2342- let n = acc._2
2343- let x = if ((size(prodList) > n))
2344- then parseIntValue(prodList[n])
2345- else 0
2346- if ((3 > n))
2347- then {
2348- let q = qts[n]
2349- if ((q > x))
2350- then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
2351- else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (parseIntValue(split(recipe, "_")[rIdxEffect]) * q)))
2352- }
2353- else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
2556+ else if (checkDelivery(duckAssetId))
2557+ then throw("heal_checkDelivery")
2558+ else {
2559+ let qts = [quantityL1, quantityL2, quantityL3]
2560+ let keyHealth = keyDuckHealth(duckAssetId)
2561+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2562+ let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2563+ if ((oldHealth >= maxHP))
2564+ then throw((("HP should be < " + toString(maxHP)) + " to heal"))
2565+ else {
2566+ let bpKey = keyBackpackByDuck(duckAssetId)
2567+ let currentPack = getBackpack(bpKey)
2568+ let prodList = if ((currentPack[bpIdxProd] == ""))
2569+ then nil
2570+ else split_4C(currentPack[bpIdxProd], "_")
2571+ func iterateProd (acc,recipe) = {
2572+ let n = acc._2
2573+ let x = if ((size(prodList) > n))
2574+ then parseIntValue(prodList[n])
2575+ else 0
2576+ if ((3 > n))
2577+ then {
2578+ let q = qts[n]
2579+ if ((q > x))
2580+ then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
2581+ else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (parseIntValue(split(recipe, "_")[rIdxEffect]) * q)))
2582+ }
2583+ else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
2584+ }
2585+
2586+ let result = {
2587+ let $l = productionMatrix
2588+ let $s = size($l)
2589+ let $acc0 = $Tuple3(nil, 0, 0)
2590+ func $f0_1 ($a,$i) = if (($i >= $s))
2591+ then $a
2592+ else iterateProd($a, $l[$i])
2593+
2594+ func $f0_2 ($a,$i) = if (($i >= $s))
2595+ then $a
2596+ else throw("List size exceeds 50")
2597+
2598+ $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)
2599+ }
2600+ let newHealth = min([maxHP, (oldHealth + result._3)])
2601+ $Tuple2((([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":"))] ++ prologActions) ++ updateDuckStatsInternal(duckAssetId, (xpHeal * ((quantityL1 + quantityL2) + quantityL3)))._1), newHealth)
23542602 }
2355-
2356- let result = {
2357- let $l = productionMatrix
2358- let $s = size($l)
2359- let $acc0 = $Tuple3(nil, 0, 0)
2360- func $f0_1 ($a,$i) = if (($i >= $s))
2361- then $a
2362- else iterateProd($a, $l[$i])
2363-
2364- func $f0_2 ($a,$i) = if (($i >= $s))
2365- then $a
2366- else throw("List size exceeds 50")
2367-
2368- $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)
2369- }
2370- let newHealth = min([maxHP, (oldHealth + result._3)])
2371- $Tuple2(([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":")), prologAction] ++ updateDuckStatsInternal(duckAssetId, (xpHeal * ((quantityL1 + quantityL2) + quantityL3)))._1), newHealth)
2372- }
2373- }
2603+ }
23742604 }
23752605 }
23762606
23782608
23792609 @Callable(i)
23802610 func healES () = {
2381- let prologAction = prolog(i)
2611+ let prologActions = prolog(i)
23822612 if ((size(i.payments) != 1))
23832613 then throw("Exactly one payment required")
23842614 else {
23892619 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
23902620 if (checkTournament(duckAssetId))
23912621 then throw("healES_checkTournament")
2392- else {
2393- let keyHealth = keyDuckHealth(duckAssetId)
2394- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2395- let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2396- if ((oldHealth > 0))
2397- then throw("HP should be 0 to call Emergency Service")
2398- else {
2399- let bpKey = keyBackpackByDuck(duckAssetId)
2400- let currentPack = getBackpack(bpKey)
2401- let prodList = if ((currentPack[bpIdxProd] == ""))
2402- then nil
2403- else split_4C(currentPack[bpIdxProd], "_")
2404- let medKitAmount1 = if ((size(prodList) > 0))
2405- then parseIntValue(prodList[0])
2406- else 0
2407- let medKitAmount2 = if ((size(prodList) > 1))
2408- then parseIntValue(prodList[1])
2409- else 0
2410- let medKitAmount3 = if ((size(prodList) > 2))
2411- then parseIntValue(prodList[2])
2412- else 0
2413- if (if (if ((medKitAmount1 > 0))
2414- then true
2415- else (medKitAmount2 > 0))
2416- then true
2417- else (medKitAmount3 > 0))
2418- then throw("You have to use own Medical Kit")
2419- else {
2420- let existStr = getString(economyContract, keyEsWarehouse())
2421- let existAmounts = if (isDefined(existStr))
2422- then split_4C(value(existStr), "_")
2423- else nil
2424- let existAmount = if ((size(existAmounts) > 0))
2425- then parseIntValue(existAmounts[0])
2426- else 0
2427- if ((0 >= existAmount))
2428- then throw("There are no Medical Kits L1 at Emergency Service storage")
2429- else {
2430- let newHealth = (oldHealth + parseIntValue(split(productionMatrix[0], "_")[rIdxEffect]))
2431- let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
2432- let recipe = split(productionMatrix[0], "_")
2433- let totalMat = getRecipeMaterials(recipe)
2434- let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
2435- if ((pmt.amount != sellPrice))
2436- then throw(("Payment attached should be " + toString(sellPrice)))
2437- else {
2438- let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
2439- $Tuple2(([IntegerEntry(keyHealth, newHealth), prologAction] ++ updateDuckStatsInternal(duckAssetId, xpCallES)._1), result)
2440- }
2441- }
2442- }
2443- }
2444- }
2622+ else if (checkDelivery(duckAssetId))
2623+ then throw("healES_checkDelivery")
2624+ else {
2625+ let keyHealth = keyDuckHealth(duckAssetId)
2626+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2627+ let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2628+ if ((oldHealth > 0))
2629+ then throw("HP should be 0 to call Emergency Service")
2630+ else {
2631+ let bpKey = keyBackpackByDuck(duckAssetId)
2632+ let currentPack = getBackpack(bpKey)
2633+ let prodList = if ((currentPack[bpIdxProd] == ""))
2634+ then nil
2635+ else split_4C(currentPack[bpIdxProd], "_")
2636+ let medKitAmount1 = if ((size(prodList) > 0))
2637+ then parseIntValue(prodList[0])
2638+ else 0
2639+ let medKitAmount2 = if ((size(prodList) > 1))
2640+ then parseIntValue(prodList[1])
2641+ else 0
2642+ let medKitAmount3 = if ((size(prodList) > 2))
2643+ then parseIntValue(prodList[2])
2644+ else 0
2645+ if (if (if ((medKitAmount1 > 0))
2646+ then true
2647+ else (medKitAmount2 > 0))
2648+ then true
2649+ else (medKitAmount3 > 0))
2650+ then throw("You have to use own Medical Kit")
2651+ else {
2652+ let existStr = getString(economyContract, keyEsWarehouse())
2653+ let existAmounts = if (isDefined(existStr))
2654+ then split_4C(value(existStr), "_")
2655+ else nil
2656+ let existAmount = if ((size(existAmounts) > 0))
2657+ then parseIntValue(existAmounts[0])
2658+ else 0
2659+ if ((0 >= existAmount))
2660+ then throw("There are no Medical Kits L1 at Emergency Service storage")
2661+ else {
2662+ let newHealth = (oldHealth + parseIntValue(split(productionMatrix[0], "_")[rIdxEffect]))
2663+ let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
2664+ let recipe = split(productionMatrix[0], "_")
2665+ let totalMat = getRecipeMaterials(recipe)
2666+ let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
2667+ if ((pmt.amount != sellPrice))
2668+ then throw(("Payment attached should be " + toString(sellPrice)))
2669+ else {
2670+ let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
2671+ $Tuple2(((prologActions :+ IntegerEntry(keyHealth, newHealth)) ++ updateDuckStatsInternal(duckAssetId, xpCallES)._1), result)
2672+ }
2673+ }
2674+ }
2675+ }
2676+ }
24452677 }
24462678 }
24472679 }
24572689
24582690 @Callable(i)
24592691 func commitForRandom () = {
2460- let prologAction = prolog(i)
2692+ let prologActions = prolog(i)
24612693 let finishBlock = (height + randomDelay)
24622694 let addr = toString(i.caller)
2463- $Tuple2(([IntegerEntry(keyCommit(addr), finishBlock)] :+ prologAction), finishBlock)
2464- }
2465-
2466-
2467-
2468-@Callable(i)
2469-func awardSLand (address) = if ((i.caller != tournamentContract))
2470- then throw("Access denied")
2471- else if ((size(i.payments) != 0))
2472- then throw("No payments required")
2473- else {
2474- let result = expeditionInternal(addressFromStringValue(address), i.transactionId)
2475- $Tuple2(result._1, result._2._1)
2476- }
2695+ $Tuple2(([IntegerEntry(keyCommit(addr), finishBlock)] ++ prologActions), finishBlock)
2696+ }
24772697
24782698
24792699
24802700 @Callable(i)
24812701 func buySLand () = {
2482- let prologAction = prolog(i)
2702+ let prologActions = prolog(i)
24832703 if ((size(i.payments) != 1))
24842704 then throw("Exactly one payment required")
24852705 else {
24902710 then throw(("Payment attached should be " + toString(EXPUSDT)))
24912711 else {
24922712 let result = expeditionInternal(i.caller, i.transactionId)
2493- $Tuple2((((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) :+ prologAction), result._2._1)
2713+ let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
2714+ $Tuple2((((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) ++ prologActions), $Tuple2(result._2._1, acresResult))
24942715 }
24952716 }
24962717 }
24992720
25002721 @Callable(i)
25012722 func expedition (message,sig) = {
2502- let prologAction = prolog(i)
2723+ let prologActions = prolog(i)
25032724 if ((size(i.payments) != 0))
25042725 then throw("No payments required")
25052726 else {
25132734 let newMat = makeString(subtractMaterials(true, mList, EXPMATERIALS), "_")
25142735 let eqKey = keyDuckEquipment(duckAssetId)
25152736 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2516- let $t07473874835 = subtractEquipment(currentEq, f._5)
2517- let newEq = $t07473874835._1
2518- let shouldZeroBuffs = $t07473874835._2
2737+ let $t08078880885 = subtractEquipment(currentEq, f._5)
2738+ let newEq = $t08078880885._1
2739+ let shouldZeroBuffs = $t08078880885._2
25192740 let e = expeditionInternal(i.caller, i.transactionId)
25202741 let id = e._2._1
25212742 let result = if ((0 >= f._1))
25252746 else ((((nil :+ StringEntry(keyDuckLocation(duckAssetId), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, f._1)) :+ StringEntry(eqKey, newEq)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))))), id, f._3)
25262747 if (checkTournament(duckAssetId))
25272748 then throw("expedition_checkTournament")
2528- else $Tuple2(((result._1 ++ updateDuckStatsInternal(duckAssetId, xpNewSLand)._1) :+ prologAction), $Tuple2(result._2, result._3))
2749+ else if (checkDelivery(duckAssetId))
2750+ then throw("expedition_checkDelivery")
2751+ else {
2752+ let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
2753+ $Tuple2(((result._1 ++ updateDuckStatsInternal(duckAssetId, xpNewSLand)._1) ++ prologActions), $Tuple3(result._2, result._3, acresResult))
2754+ }
2755+ }
2756+ }
2757+
2758+
2759+
2760+@Callable(i)
2761+func buySLandForAcres () = {
2762+ let prologActions = prolog(i)
2763+ if ((size(i.payments) != 1))
2764+ then throw("exactly 1 payment must be attached")
2765+ else {
2766+ let pmt = i.payments[0]
2767+ let amt = pmt.amount
2768+ if (if (!(isDefined(pmt.assetId)))
2769+ then true
2770+ else (value(pmt.assetId) != acresAssetId))
2771+ then throw("ACRES payments only!")
2772+ else if ((amt != S_COST_ACRES))
2773+ then throw(("Payment attached should be " + toString(S_COST_ACRES)))
2774+ else {
2775+ let result = expeditionInternal(i.caller, i.transactionId)
2776+ let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], [AttachedPayment(acresAssetId, amt)]))
2777+ $Tuple2(((result._1 ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) ++ prologActions), $Tuple2(result._2._1, acresResult))
2778+ }
25292779 }
25302780 }
25312781
25332783
25342784 @Callable(i)
25352785 func upgradeInfra (landAssetId) = {
2536- let prologAction = prolog(i)
2786+ let prologActions = prolog(i)
25372787 if ((size(i.payments) != 0))
25382788 then throw("No payments required")
25392789 else {
25402790 let result = upInfraCommon(true, i.caller, 0, landAssetId)
25412791 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
2542- $Tuple2(((result._1 :+ prologAction) ++ updateDuckStatsInternal(duckAssetId, fraction(xpUpgradeInfra, result._3, MULT8))._1), result._2)
2792+ $Tuple2(((result._1 ++ prologActions) ++ updateDuckStatsInternal(duckAssetId, fraction(xpUpgradeInfra, result._3, MULT8))._1), result._2)
25432793 }
25442794 }
25452795
25472797
25482798 @Callable(i)
25492799 func activateArtifact (artName,landAssetIdOpt) = {
2550- let prologAction = prolog(i)
2800+ let prologActions = prolog(i)
25512801 if ((size(i.payments) != 0))
25522802 then throw("No payments required")
25532803 else {
25602810 then activateOnboardArt(addr)
25612811 else throw("Unknown artifact")
25622812 }
2563- (result :+ prologAction)
2813+ (result ++ prologActions)
25642814 }
25652815 }
25662816
25682818
25692819 @Callable(i)
25702820 func mergeLands (landAssetIds) = {
2571- let prologAction = prolog(i)
2821+ let prologActions = prolog(i)
25722822 if ((size(i.payments) != 0))
25732823 then throw("No payments required")
25742824 else {
25752825 let result = mergeCommon(toString(i.caller), landAssetIds)
2576- $Tuple2(((result._1 :+ prologAction) ++ updateAccStatsInternal(toString(i.caller), xpMerge)._1), result._2)
2826+ $Tuple2(((result._1 ++ prologActions) ++ updateAccStatsInternal(toString(i.caller), xpMerge)._1), result._2)
25772827 }
25782828 }
25792829
25812831
25822832 @Callable(i)
25832833 func cargoExchange (cargoListStr,landAssetId) = {
2584- let prologAction = prolog(i)
2834+ let prologActions = prolog(i)
25852835 if ((size(i.payments) != 0))
25862836 then throw("No payments required")
25872837 else {
26142864 let loft = split(currentWh[whIdxLOFT], "_")
26152865 let loftO = (parseIntValue(loft[volOccupied]) + result._7)
26162866 let loftF = (parseIntValue(loft[volFree]) - result._7)
2617-[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]
2867+ ([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]], "_")], ":"))] ++ prologActions)
26182868 }
26192869 }
26202870 }
27633013
27643014 @Callable(i)
27653015 func setCustomName (assetId,customName,type) = {
2766- let prologAction = prolog(i)
3016+ let prologActions = prolog(i)
27673017 if ((size(i.payments) != 1))
27683018 then throw("Exactly one payment required")
27693019 else {
28513101 }
28523102 else throw("Unknown entity type")
28533103 }
2854- $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), 0)
3104+ $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ prologActions), 0)
28553105 }
28563106 }
28573107 }
28623112 func setReferrals (oldPlayer,newPlayer) = if ((i.callerPublicKey != pub))
28633113 then throw("Permission denied")
28643114 else {
2865- let prologAction = prolog(i)
3115+ let prologActions = prolog(i)
28663116 if ((size(i.payments) != 0))
28673117 then throw("No payments required")
28683118 else if (!(isDefined(addressFromString(oldPlayer))))
28973147 let newOlds = if (containsElement(oldies, oldPlayer))
28983148 then value(olds)
28993149 else makeString_2C((oldies :+ oldPlayer), "_")
2900- $Tuple2([StringEntry(refByKey, oldPlayer), StringEntry(refsKey, newRefs), StringEntry(oldsKey, newOlds), prologAction], 0)
3150+ $Tuple2(([StringEntry(refByKey, oldPlayer), StringEntry(refsKey, newRefs), StringEntry(oldsKey, newOlds)] ++ prologActions), 0)
29013151 }
29023152 }
29033153 }
29083158
29093159 @Callable(i)
29103160 func distributePoints (strength,accuracy,intellect,endurance,dexterity) = {
2911- let prologAction = prolog(i)
3161+ let prologActions = prolog(i)
29123162 if ((size(i.payments) != 0))
29133163 then throw("No payments required")
29143164 else {
29263176 let charsKey = keyDuckChars(duckAssetId)
29273177 let chars = split(valueOrElse(getString(stakingContract, charsKey), "0_0_0_0_0"), "_")
29283178 let newAcc = (freePointsAcc - sumToDistribute)
2929- $Tuple2([IntegerEntry(freeKeyAcc, if ((0 > newAcc))
3179+ $Tuple2(([IntegerEntry(freeKeyAcc, if ((0 > newAcc))
29303180 then 0
29313181 else newAcc), IntegerEntry(freeKeyDuck, if ((0 > newAcc))
29323182 then (freePointsDuck + newAcc)
2933- else freePointsDuck), StringEntry(charsKey, makeString([toString((parseIntValue(chars[charStrength]) + strength)), toString((parseIntValue(chars[charAccuracy]) + accuracy)), toString((parseIntValue(chars[charIntellect]) + intellect)), toString((parseIntValue(chars[charEndurance]) + endurance)), toString((parseIntValue(chars[charDexterity]) + dexterity))], "_")), prologAction], 0)
3183+ else freePointsDuck), StringEntry(charsKey, makeString([toString((parseIntValue(chars[charStrength]) + strength)), toString((parseIntValue(chars[charAccuracy]) + accuracy)), toString((parseIntValue(chars[charIntellect]) + intellect)), toString((parseIntValue(chars[charEndurance]) + endurance)), toString((parseIntValue(chars[charDexterity]) + dexterity))], "_"))] ++ prologActions), 0)
29343184 }
29353185 }
29363186 }
29683218 @Callable(i)
29693219 func saveLastTx () = {
29703220 let caller = i.caller
2971- if (if (if ((caller != wlgContract))
2972- then (caller != economyContract)
2973- else false)
2974- then (caller != tournamentContract)
2975- else false)
3221+ if (!(containsElement([wlgContract, economyContract, tournamentContract, acresContract], caller)))
29763222 then throw("Access denied")
2977- else $Tuple2([prolog(i)], 42)
3223+ else $Tuple2(prolog(i), 42)
29783224 }
29793225
29803226
29873233
29883234
29893235 @Callable(i)
2990-func updateAccStats (addr,deltaXP) = if ((i.caller != economyContract))
3236+func updateAccStats (addr,deltaXP) = if (if ((i.caller != economyContract))
3237+ then (i.caller != acresContract)
3238+ else false)
29913239 then throw("Access denied")
29923240 else updateAccStatsInternal(addr, deltaXP)
29933241
29953243
29963244 @Callable(i)
29973245 func equipDuck (equipment) = {
2998- let prologAction = prolog(i)
3246+ let prologActions = prolog(i)
29993247 if ((size(i.payments) != 0))
30003248 then throw("No payments required")
30013249 else {
30033251 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
30043252 if (checkTournament(duckAssetId))
30053253 then throw("equipDuck_checkTournament")
3006- else {
3007- let eqKey = keyDuckEquipment(duckAssetId)
3008- let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
3009- let bpKey = keyBackpackByDuck(duckAssetId)
3010- let currentPack = getBackpack(bpKey)
3011- let newEq = split(equipment, "_")
3012- if ((size(newEq) != NUMSEGMENTS))
3013- then throw("Wrong equipment string")
3014- else {
3015- let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
3016- let segBpAux = split(newEq[segBackpack], ";")[1]
3017- let buffEffect = if ((segBpAux == ""))
3018- then 0
3019- else {
3020- let aux0 = split(segBpAux, ",")[0]
3021- if ((aux0 == ""))
3022- then 0
3023- else {
3024- let idxCnt = split(aux0, ":")
3025- let idx = idxCnt[0]
3026- let cnt = idxCnt[1]
3027- if (if (if (if (if ((idx == "06"))
3028- then true
3029- else (idx == "07"))
3030- then true
3031- else (idx == "08"))
3032- then (cnt != "")
3033- else false)
3034- then (parseIntValue(cnt) > 0)
3035- else false)
3036- then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
3037- else 0
3038- }
3039- }
3040- let stats = getDuckStats(this, duckAssetId, buffEffect, true)
3041- let newProdB = dressB(newEq, tempProdB, false, stats)
3042- let newProdStr = bytesToProdStr(newProdB)
3043- $Tuple2([StringEntry(eqKey, equipment), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProdStr], ":")), StringEntry(keyDuckBuffs(duckAssetId), makeString([toString(stats[7]), toString(stats[8]), toString(stats[9]), toString(stats[10]), toString(stats[11])], "_")), prologAction], 0)
3044- }
3045- }
3254+ else if (checkDelivery(duckAssetId))
3255+ then throw("equipDuck_checkDelivery")
3256+ else {
3257+ let eqKey = keyDuckEquipment(duckAssetId)
3258+ let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
3259+ let bpKey = keyBackpackByDuck(duckAssetId)
3260+ let currentPack = getBackpack(bpKey)
3261+ let newEq = split(equipment, "_")
3262+ if ((size(newEq) != NUMSEGMENTS))
3263+ then throw("Wrong equipment string")
3264+ else {
3265+ let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
3266+ let segBpAux = split(newEq[segBackpack], ";")[1]
3267+ let buffEffect = if ((segBpAux == ""))
3268+ then 0
3269+ else {
3270+ let aux0 = split(segBpAux, ",")[0]
3271+ if ((aux0 == ""))
3272+ then 0
3273+ else {
3274+ let idxCnt = split(aux0, ":")
3275+ let idx = idxCnt[0]
3276+ let cnt = idxCnt[1]
3277+ if (if (if (if (if ((idx == "06"))
3278+ then true
3279+ else (idx == "07"))
3280+ then true
3281+ else (idx == "08"))
3282+ then (cnt != "")
3283+ else false)
3284+ then (parseIntValue(cnt) > 0)
3285+ else false)
3286+ then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
3287+ else 0
3288+ }
3289+ }
3290+ let stats = getDuckStats(this, duckAssetId, buffEffect, true)
3291+ let newProdB = dressB(newEq, tempProdB, false, stats)
3292+ let newProdStr = bytesToProdStr(newProdB)
3293+ $Tuple2(([StringEntry(eqKey, equipment), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProdStr], ":")), StringEntry(keyDuckBuffs(duckAssetId), makeString([toString(stats[7]), toString(stats[8]), toString(stats[9]), toString(stats[10]), toString(stats[11])], "_"))] ++ prologActions), 0)
3294+ }
3295+ }
30463296 }
30473297 }
30483298
30503300
30513301 @Callable(i)
30523302 func fortificateLand (landAssetId,plan) = {
3053- let prologAction = prolog(i)
3303+ let prologActions = prolog(i)
30543304 if ((size(i.payments) != 0))
30553305 then throw("No payments required")
30563306 else {
30683318 let curO = parseIntValue(curLoft[volOccupied])
30693319 let curF = parseIntValue(curLoft[volFree])
30703320 let newForts = split(plan, "_")
3071- let $t09585095965 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3072- let tempProdB = $t09585095965._1
3073- let tempO = $t09585095965._2
3074- let tempF = $t09585095965._3
3075- let $t09596896064 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3076- let newProdB = $t09596896064._1
3077- let newO = $t09596896064._2
3078- let newF = $t09596896064._3
3321+ let $t0102994103109 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3322+ let tempProdB = $t0102994103109._1
3323+ let tempO = $t0102994103109._2
3324+ let tempF = $t0102994103109._3
3325+ let $t0103112103208 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3326+ let newProdB = $t0103112103208._1
3327+ let newO = $t0103112103208._2
3328+ let newF = $t0103112103208._3
30793329 let newProdStr = bytesToProdStr(newProdB)
30803330 let newLoftStr = makeString([curLoft[volLocked], toString(newO), toString(newF), curLoft[volTotal]], "_")
3081- $Tuple2([StringEntry(fortKey, plan), StringEntry(whKey, makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], newProdStr, newLoftStr], ":")), prologAction], 0)
3331+ $Tuple2(([StringEntry(fortKey, plan), StringEntry(whKey, makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], newProdStr, newLoftStr], ":"))] ++ prologActions), 0)
30823332 }
30833333 }
30843334
30883338 func initDuckTourAttempt (duckAssetId) = if ((i.caller != tournamentContract))
30893339 then throw("Access denied")
30903340 else {
3091- let prologAction = prolog(i)
30923341 let keyHealth = keyDuckHealth(duckAssetId)
30933342 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
30943343 let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
30963345 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
30973346 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
30983347 let tourLocation = (toString(lastId) + "_T_0")
3099- $Tuple2([prologAction, IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, tourLocation)], tourLocation)
3348+ $Tuple2([IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, tourLocation)], tourLocation)
31003349 }
31013350
31023351
31033352
31043353 @Callable(i)
31053354 func breakAttempt () = {
3106- let prologAction = prolog(i)
3355+ let prologActions = prolog(i)
31073356 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
31083357 let curLocKey = keyDuckLocation(duckAssetId)
31093358 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
31123361 else {
31133362 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
31143363 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
3115- $Tuple2([prologAction, IntegerEntry(keyDuckHealth(duckAssetId), savedHealth), StringEntry(curLocKey, savedLocation)], curLocation)
3364+ $Tuple2(((prologActions :+ IntegerEntry(keyDuckHealth(duckAssetId), savedHealth)) :+ StringEntry(curLocKey, savedLocation)), curLocation)
31163365 }
31173366 }
31183367
31303379
31313380
31323381 @Callable(i)
3382+func exitDeliveryInternal (duckAssetId) = if ((i.caller != this))
3383+ then throw("Access denied")
3384+ else {
3385+ let e = exitDeliveryCommon(duckAssetId)
3386+ $Tuple2((e._1 ++ e._2), false)
3387+ }
3388+
3389+
3390+
3391+@Callable(i)
3392+func autoExitDelivery (duckAssetId) = if ((i.caller != this))
3393+ then throw("Access denied")
3394+ else {
3395+ let e = exitDeliveryCommon(duckAssetId)
3396+ $Tuple2(e._1, $Tuple2(e._3, e._4))
3397+ }
3398+
3399+
3400+
3401+@Callable(i)
31333402 func prepareRobbery (message,sig) = {
3134- let prologAction = prolog(i)
3403+ let prologActions = prolog(i)
31353404 if (!(sigVerify_8Kb(message, sig, pub)))
31363405 then throw("signature does not match")
31373406 else if ((size(i.payments) != 1))
31493418 then throw("Wrong message format")
31503419 else {
31513420 let duckAssetId = parts[0]
3152- let robCost = getRobberyData(this, duckAssetId)._1
3153- if ((robCost > wlgAmt))
3154- then throw(((("Payment " + toString(wlgAmt)) + " < required ") + toString(robCost)))
3155- else {
3156- let candidates = split(parts[1], "_")
3157- let now = lastBlock.timestamp
3158- let duckState = valueOrElse(getInteger(keyDuckRobberyState(duckAssetId)), 0)
3159- let lockedLand = valueOrElse(getString(keyLockedLandByDuck(duckAssetId)), "")
3160- let landETA = valueOrElse(getInteger(keyLandCooldownETA(lockedLand)), 0)
3161- if (if ((duckState != duckIdxFree))
3162- then (landETA > now)
3163- else false)
3164- then throw(("You already started robbing, wait till " + toString(landETA)))
3165- else {
3166- func checker (acc,landAssetId) = {
3167- let state = valueOrElse(getInteger(keyLandRobberyState(landAssetId)), 0)
3168- let cooldownETA = valueOrElse(getInteger(keyLandCooldownETA(landAssetId)), 0)
3169- if ((state > size(landRobCooldowns)))
3170- then throw("Invalid state")
3171- else if ((now > cooldownETA))
3172- then {
3173- let stakedTime = valueOrElse(getInteger(keyStakedTimeByAssetId(landAssetId)), 0)
3174- if ((0 >= stakedTime))
3175- then acc
3176- else {
3177- let a = value(assetInfo(fromBase58String(landAssetId)))
3178- let d = split(a.description, "_")
3179- let pieces = numPiecesBySize(d[recLandSize])
3180- let productivity = applyBonuses(landAssetId, pieces)
3181- let deltaTime = (now - stakedTime)
3182- let availRes = fraction(deltaTime, (productivity * pieces), DAYMILLIS)
3183- if ((MIN_RES_TO_ROB > availRes))
3184- then acc
3185- else (acc :+ landAssetId)
3186- }
3421+ if (checkTournament(duckAssetId))
3422+ then throw("prepareRobbery_checkTournament")
3423+ else if (checkDelivery(duckAssetId))
3424+ then throw("prepareRobbery_checkDelivery")
3425+ else {
3426+ let robCost = getRobberyData(this, duckAssetId)._1
3427+ if ((robCost > wlgAmt))
3428+ then throw(((("Payment " + toString(wlgAmt)) + " < required ") + toString(robCost)))
3429+ else {
3430+ let candidates = split(parts[1], "_")
3431+ let now = lastBlock.timestamp
3432+ let duckState = valueOrElse(getInteger(keyDuckRobberyState(duckAssetId)), 0)
3433+ let lockedLand = valueOrElse(getString(keyLockedLandByDuck(duckAssetId)), "")
3434+ let landETA = valueOrElse(getInteger(keyLandCooldownETA(lockedLand)), 0)
3435+ if (if ((duckState != duckIdxFree))
3436+ then (landETA > now)
3437+ else false)
3438+ then throw(("You already started robbing, wait till " + toString(landETA)))
3439+ else {
3440+ func checker (acc,landAssetId) = {
3441+ let state = valueOrElse(getInteger(keyLandRobberyState(landAssetId)), 0)
3442+ let cooldownETA = valueOrElse(getInteger(keyLandCooldownETA(landAssetId)), 0)
3443+ if ((state > size(landRobCooldowns)))
3444+ then throw("Invalid state")
3445+ else if ((now > cooldownETA))
3446+ then {
3447+ let stakedTime = valueOrElse(getInteger(keyStakedTimeByAssetId(landAssetId)), 0)
3448+ if ((0 >= stakedTime))
3449+ then acc
3450+ else {
3451+ let a = value(assetInfo(fromBase58String(landAssetId)))
3452+ let d = split(a.description, "_")
3453+ let pieces = numPiecesBySize(d[recLandSize])
3454+ let productivity = applyBonuses(landAssetId, pieces)
3455+ let deltaTime = (now - stakedTime)
3456+ let availRes = fraction(deltaTime, (productivity * pieces), DAYMILLIS)
3457+ if ((MIN_RES_TO_ROB > availRes))
3458+ then acc
3459+ else (acc :+ landAssetId)
3460+ }
3461+ }
3462+ else acc
31873463 }
3188- else acc
3464+
3465+ let filtered = {
3466+ let $l = candidates
3467+ let $s = size($l)
3468+ let $acc0 = nil
3469+ func $f0_1 ($a,$i) = if (($i >= $s))
3470+ then $a
3471+ else checker($a, $l[$i])
3472+
3473+ func $f0_2 ($a,$i) = if (($i >= $s))
3474+ then $a
3475+ else throw("List size exceeds 10")
3476+
3477+ $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)
3478+ }
3479+ if ((size(filtered) == 0))
3480+ then throw("No candidates for robbery")
3481+ else {
3482+ let rndIdx = getRandomNumber(size(filtered), height, (sig + i.transactionId))
3483+ let landAssetId = filtered[rndIdx]
3484+ $Tuple2(([IntegerEntry(keyLandRobberyState(landAssetId), robIdxLocked), IntegerEntry(keyLandCooldownETA(landAssetId), (now + landRobCooldowns[robIdxLocked])), IntegerEntry(keyDuckRobberyState(duckAssetId), duckIdxPreparing), StringEntry(keyLockedLandByDuck(duckAssetId), landAssetId)] ++ prologActions), landAssetId)
3485+ }
3486+ }
31893487 }
3190-
3191- let filtered = {
3192- let $l = candidates
3193- let $s = size($l)
3194- let $acc0 = nil
3195- func $f0_1 ($a,$i) = if (($i >= $s))
3196- then $a
3197- else checker($a, $l[$i])
3198-
3199- func $f0_2 ($a,$i) = if (($i >= $s))
3200- then $a
3201- else throw("List size exceeds 10")
3202-
3203- $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)
3204- }
3205- if ((size(filtered) == 0))
3206- then throw("No candidates for robbery")
3207- else {
3208- let rndIdx = getRandomNumber(size(filtered), height, (sig + i.transactionId))
3209- let landAssetId = filtered[rndIdx]
3210- $Tuple2([IntegerEntry(keyLandRobberyState(landAssetId), robIdxLocked), IntegerEntry(keyLandCooldownETA(landAssetId), (now + landRobCooldowns[robIdxLocked])), IntegerEntry(keyDuckRobberyState(duckAssetId), duckIdxPreparing), StringEntry(keyLockedLandByDuck(duckAssetId), landAssetId), prologAction], landAssetId)
3211- }
3212- }
3213- }
3488+ }
32143489 }
32153490 }
32163491 }
32203495
32213496 @Callable(i)
32223497 func robLand (message,sig) = {
3223- let prologAction = prolog(i)
3498+ let prologActions = prolog(i)
32243499 if (!(sigVerify_8Kb(message, sig, pub)))
32253500 then throw("signature does not match")
3226- else $Tuple2([prologAction], 0)
3227- }
3501+ else {
3502+ let userAddr = toString(i.caller)
3503+ let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
3504+ let now = lastBlock.timestamp
3505+ $Tuple2((prologActions :+ IntegerEntry(keyLastRobberyTimeByDuck(duckAssetId), now)), 0)
3506+ }
3507+ }
3508+
3509+
3510+
3511+@Callable(i)
3512+func acceptDelivery () = if (!(KS_ALLOW_DELIVERY))
3513+ then throw("Delivery feature is turned off!")
3514+ else {
3515+ let prologActions = prolog(i)
3516+ let userAddr = toString(i.caller)
3517+ let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
3518+ let fundTotal = valueOrElse(getInteger(economyContract, deliveryFundKey), 0)
3519+ let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
3520+ if ((MIN_USDT_FEE_DELIVERY > (fundTotal - lockedTotal)))
3521+ then throw(((("Delivery is not available, fund=" + fixedPoint(fundTotal, 6)) + ", locked=") + fixedPoint(lockedTotal, 6)))
3522+ else {
3523+ let now = lastBlock.timestamp
3524+ let delayETA = valueOrElse(getInteger(keyDeliveryDelayByDuck(duckAssetId)), 0)
3525+ if ((delayETA > now))
3526+ then throw(("Delivery is forbidden for your duck until " + toString(delayETA)))
3527+ else if (checkTournament(duckAssetId))
3528+ then throw("acceptDelivery_checkTournament")
3529+ else if (checkDelivery(duckAssetId))
3530+ then throw("acceptDelivery_checkDelivery")
3531+ else {
3532+ let newLockedTotal = asInt(invoke(economyContract, "updateDeliveryLocked", [(lockedTotal + MIN_USDT_FEE_DELIVERY)], nil))
3533+ let keyHealth = keyDuckHealth(duckAssetId)
3534+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
3535+ let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
3536+ let curLocKey = keyDuckLocation(duckAssetId)
3537+ let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
3538+ let deliveryLocation = (toString(now) + "_D_0")
3539+ $Tuple2(([IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, deliveryLocation)] ++ prologActions), $Tuple2(deliveryLocation, newLockedTotal))
3540+ }
3541+ }
3542+ }
32283543
32293544
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let DAYMILLIS = 86400000
5+
46 func keyLastArbTimeByUser (addr) = ("lastArbTimeUser_" + addr)
57
68
79 let SCALE8 = 100000000
810
911 let xpLevelScale = 3200
1012
1113 let xpLevelRecipPow = 4000
1214
1315 let numPointsOnLevelUp = 3
1416
1517 let robberyCostMin = 100000000
1618
1719 let robberyCooldownCoeff = 400
1820
1921 let requirements = ["Strength", "Accuracy", "Intellect", "Endurance", "Dexterity", "Level", "Health"]
2022
2123 let charStrength = 0
2224
2325 let charAccuracy = 1
2426
2527 let charIntellect = 2
2628
2729 let charEndurance = 3
2830
2931 let charDexterity = 4
3032
3133 let segBackpack = 0
3234
3335 let NUMSEGMENTS = 6
3436
3537 let NUMMAINAUX = 2
3638
3739 let MAXSLOTS = 2
3840
3941 let MAXPRODINSLOT = 30
4042
4143 let landRobCooldowns = [0, 600000, 900000, 43200000, 21600000]
4244
4345 let MIN_RES_TO_ROB = 20000000
4446
4547 let robIdxLocked = 1
4648
4749 let duckIdxFree = 0
4850
4951 let duckIdxPreparing = 1
5052
5153 func keyDuckHealth (duckAssetId) = ("duckHealth_" + duckAssetId)
5254
5355
5456 func keyDuckChars (duckAssetId) = ("duckChars_" + duckAssetId)
5557
5658
5759 func keyDuckXP (duckAssetId) = ("duckXP_" + duckAssetId)
5860
5961
6062 func keyDuckLevel (duckAssetId) = ("duckLevel_" + duckAssetId)
6163
6264
6365 func keyDuckFreePoints (duckAssetId) = ("duckFreePoints_" + duckAssetId)
6466
6567
6668 func keyDuckEquipment (duckAssetId) = ("duckEquipment_" + duckAssetId)
6769
6870
6971 func keyUserXP (addr) = ("userXP_" + addr)
7072
7173
7274 func keyUserLevel (addr) = ("userLevel_" + addr)
7375
7476
7577 func keyUserFreePoints (addr) = ("userFreePoints_" + addr)
7678
7779
7880 func keySavedHealth (duckAssetId) = ("savedHealth_" + duckAssetId)
7981
8082
8183 func keySavedLocation (duckAssetId) = ("savedLocation_" + duckAssetId)
8284
8385
8486 func keyDuckBuffs (duckAssetId) = ("duckBuffs_" + duckAssetId)
8587
8688
8789 func keyLastRobberyTimeByDuck (duckAssetId) = ("lastRobberyTime_" + duckAssetId)
8890
8991
9092 func keyLastRobberyCostByDuck (duckAssetId) = ("lastRobberyCost_" + duckAssetId)
9193
9294
9395 func keyLandRobberyState (landAssetId) = ("landRobberyState_" + landAssetId)
9496
9597
9698 func keyLandCooldownETA (landAssetId) = ("landCooldownETA_" + landAssetId)
9799
98100
99101 func keyDuckRobberyState (duckAssetId) = ("duckRobberyState_" + duckAssetId)
100102
101103
102104 func keyLockedLandByDuck (duckAssetId) = ("lockedLandByDuck_" + duckAssetId)
105+
106+
107+func keyDeliveryDelayByDuck (duckAssetId) = ("deliveryDelayByDuck_" + duckAssetId)
103108
104109
105110 let xpClaim = 10000
106111
107112 let xpSuccessFlight = 10000
108113
109114 let xpFailFlight = 2000
110115
111116 let xpCallES = 100000
112117
113118 let xpCustomName = 1000000
114119
115120 let xpNewSLand = 5000000
116121
117122 let xpUpgradeInfra = 10000
118123
119124 let xpMerge = 1000000
120125
121126 let xpOnboard = 1000000
122127
123128 let xpHeal = 10000
124129
125130 func levelByXP (xp) = fraction(xpLevelScale, pow(xp, 4, xpLevelRecipPow, 4, 4, DOWN), SCALE8)
126131
127132
128133 func maxHealth (level) = (100 + level)
129134
130135
131136 func levelUp (currLevel,newXP) = {
132137 let newLevel = levelByXP(newXP)
133138 [newLevel, (numPointsOnLevelUp * (newLevel - currLevel))]
134139 }
135140
136141
137142 func getDuckStats (stakingContract,duckAssetId,buffEffect,forceBuffs) = {
138143 let chars = split(valueOrElse(getString(stakingContract, keyDuckChars(duckAssetId)), "0_0_0_0_0"), "_")
139144 let lvl = valueOrElse(getInteger(stakingContract, keyDuckLevel(duckAssetId)), 0)
140145 let health = valueOrElse(getInteger(stakingContract, keyDuckHealth(duckAssetId)), maxHealth(lvl))
141146 let stateBuffs = split(valueOrElse(getString(stakingContract, keyDuckBuffs(duckAssetId)), "0_0_0_0_0"), "_")
142147 ([parseIntValue(chars[charStrength]), parseIntValue(chars[charAccuracy]), parseIntValue(chars[charIntellect]), parseIntValue(chars[charEndurance]), parseIntValue(chars[charDexterity]), lvl, health] ++ (if (forceBuffs)
143148 then [buffEffect, buffEffect, buffEffect, buffEffect, buffEffect]
144149 else [parseIntValue(stateBuffs[charStrength]), parseIntValue(stateBuffs[charAccuracy]), parseIntValue(stateBuffs[charIntellect]), parseIntValue(stateBuffs[charEndurance]), parseIntValue(stateBuffs[charDexterity])]))
145150 }
146151
147152
148153 func getRobberyData (stakingContract,duckAssetId) = {
149154 let lastRobCost = valueOrElse(getInteger(stakingContract, keyLastRobberyCostByDuck(duckAssetId)), 0)
150155 let lastRobTime = valueOrElse(getInteger(stakingContract, keyLastRobberyTimeByDuck(duckAssetId)), 0)
151156 let now = lastBlock.timestamp
152157 let robCost = max([robberyCostMin, (lastRobCost - (robberyCooldownCoeff * (now - lastRobTime)))])
153158 let duckState = valueOrElse(getInteger(stakingContract, keyDuckRobberyState(duckAssetId)), 0)
154159 let lockedLand = valueOrElse(getString(stakingContract, keyLockedLandByDuck(duckAssetId)), "")
155160 let landETA = valueOrElse(getInteger(stakingContract, keyLandCooldownETA(lockedLand)), 0)
156161 $Tuple5(robCost, lastRobTime, duckState, lockedLand, landETA)
157162 }
158163
159164
160165 let LANDPREFIX = "LAND"
161166
162167 let DUCKPREFIX = "DUCK"
163168
164169 let ARTPRESALE = "PRESALE"
165170
166171 let NUMRES = 6
167172
168173 let MAX_LANDS_STAKED_BY_USER = 25
169174
170175 let DAILYRESBYPIECE = 3456000
171176
172-let DAYMILLIS = 86400000
173-
174177 let WHMULTIPLIER = 10000000000
175178
176179 let DEFAULTLOCATION = "Africa_F_Africa"
177180
178181 let RESOURCEPRICEMIN = 39637
179182
180183 let ESSELLCOEF = 10
181184
185+let MIN_USDT_FEE_DELIVERY = 50000
186+
187+let TEN_MINUTES_MILLIS = 600000
188+
182189 let prodTypes = ["First Aid Kit L1", "First Aid Kit L2", "First Aid Kit L3", "Backpack L1", "Backpack L2", "Backpack L3", "Food Ration L1", "Food Ration L2", "Food Ration L3", "Jet Pack L1", "Jet Pack L2", "Jet Pack L3", "Shield L1", "Shield L2", "Shield L3", "Mine L1", "Mine L2", "Mine L3", "Trap L1", "Trap L2", "Trap L3"]
183190
184191 let continents = ["Americas", "Europe", "Asia", "Africa", "Oceania"]
185192
186193 let COEFF2MAT = 10000000
187194
188195 let fortAllowedProds = [15, 16, 17, 18, 19, 20]
189196
190197 let productionMatrix = ["8_8_8_17_17_42_12_0_30_0,0,0,0,0,0,0_", "8_8_8_17_17_42_24_0_60_0,0,5,2,0,0,0_", "8_8_8_17_17_42_36_0_120_0,0,10,4,0,0,0_", "8_19_19_8_27_19_26_1_20_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_52_1_40_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_78_1_80_0,0,0,0,0,0,0_001", "8_8_8_8_8_60_13_2_2_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_26_2_4_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_39_2_8_0,0,0,0,0,0,0_011", "30_30_3_17_17_3_30_3_30_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_60_3_50_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_90_3_70_0,0,0,0,0,0,0_111", "18_18_10_18_18_18_11_4_10_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_22_4_20_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_33_4_30_0,0,0,0,0,0,0_201", "4_13_22_4_35_22_23_0_50,1,0_0,0,0,0,0,0,0_", "4_13_22_4_35_22_46_0_50,1,1_0,2,5,0,0,0,0_", "4_13_22_4_35_22_69_0_50,2,1_0,5,10,0,0,0,0_", "5_25_40_5_10_15_20_1_30,1,1_0,0,0,0,0,0,0_", "5_25_40_5_10_15_40_1_30,1,2_2,1,3,0,0,0,0_", "5_25_40_5_10_15_60_1_30,1,3_5,2,8,0,0,0,0_"]
191198
192199 let rIdxCoeff = 6
193200
194201 let rIdxEffect = 8
195202
196203 let rIdxRequirements = 9
197204
198205 let rIdxSlots = 10
199206
200207 let PRODUCTPKGSIZE = 10
201208
202209 let whIdxLevels = 0
203210
204211 let whIdxRes = 1
205212
206213 let whIdxMat = 2
207214
208215 let whIdxProd = 3
209216
210217 let whIdxLOFT = 4
211218
212219 let volLocked = 0
213220
214221 let volOccupied = 1
215222
216223 let volFree = 2
217224
218225 let volTotal = 3
219226
220227 let bpIdxLevel = 0
221228
222229 let bpIdxRes = 1
223230
224231 let bpIdxMat = 2
225232
226233 let bpIdxProd = 3
227234
228235 let locIdxContinent = 0
229236
230237 let locIdxType = 1
231238
232239 let locIdxId = 2
233240
234241 func keyLandAssetIdToOwner (assetId) = ("no_" + assetId)
235242
236243
237244 func keyLandAssetIdToCustomName (assetId) = ("lcna_" + assetId)
238245
239246
240247 func keyStakedTimeByAssetId (assetId) = ("st_" + assetId)
241248
242249
243250 func keyLandArtStatusByTypeAndAssetId (type,assetId) = makeString(["las", type, assetId], "_")
244251
245252
246253 func keyStakedTimeByTypeAssetIdAndOwner (nftType,assetId,ownerAddr) = ((((("sttao_" + nftType) + "_") + assetId) + "_") + ownerAddr)
247254
248255
249256 func keyWarehouseByLand (landAssetId) = ("wh_" + landAssetId)
250257
251258
252259 func keyInfraLevelByAssetId (assetId) = ("infraLevel_" + assetId)
253260
254261
255262 func keyFortificationsByLand (landAssetId) = ("fortifications_" + landAssetId)
256263
257264
258265 func keyDuckAssetIdToCustomName (assetId) = ("duckCustomNameByAssetId_" + assetId)
259266
260267
261268 func keyAddressToCustomName (addr) = ("accountCustomNameByAddr_" + addr)
262269
263270
264271 func keyAddressRefBy (addr) = ("accRefBy_" + addr)
265272
266273
267274 func keyOnboardArtActivatedOnDuck (duckAssetId) = ("onboardArtActivatedOnDuck_" + duckAssetId)
268275
269276
270277 func keyOnboardArtDuckActivatedBy (addr) = ("onboardArtActivatedDuckBy_" + addr)
271278
272279
273280 func keyAddressReferrals (addr) = ("accReferrals_" + addr)
274281
275282
276283 func keyDuckIdToOwner (assetId) = ("duckOwner_" + assetId)
277284
278285
279286 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
280287
281288
282289 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
283290
284291
285292 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
286293
287294
288295 func keyUserGwlReleaseTime (userAddr) = ("%s%s__userGwlReleaseTime__" + userAddr)
289296
290297
291298 func keyEsWarehouse () = "emergencyWarehouseProducts"
292299
300+
301+let deliveryFundKey = "deliveryFund"
302+
303+let deliveryLockedKey = "deliveryLocked"
293304
294305 let lastTourIdKey = "%s__lastTourId"
295306
296307 func keyTourStaticDataById (tId) = ("%s%d__tourStaticData__" + toString(tId))
297308
298309
299310 func keyTourDynamicDataById (tId) = ("%s%d__tourDynamicData__" + toString(tId))
300311
301312
302313 func keyBestResultByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__bestResultByTourAndDuck", toString(tId), duckAssetId], "__")
303314
304315
305316 let idxStatic = 0
306317
307318 let idxDynamic = 1
308319
309320 let tStaticEnd = 6
310321
311322 let tDynamicStatus = 1
312323
313324 func getTourData (tourContract,tId) = {
314325 let static = split(valueOrErrorMessage(getString(tourContract, keyTourStaticDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
315326 let dynamic = split_4C(valueOrErrorMessage(getString(tourContract, keyTourDynamicDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
316327 [static, dynamic]
317328 }
318329
319330
320331 func isInTournament (tourContract,location) = {
321332 let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
322333 let loc = split(location, "_")
323334 let now = lastBlock.timestamp
324335 let tData = getTourData(tourContract, lastId)
325336 let static = tData[idxStatic]
326337 let dynamic = tData[idxDynamic]
327338 if (if (if ((loc[locIdxType] == "T"))
328339 then (parseIntValue(loc[locIdxContinent]) == lastId)
329340 else false)
330341 then (dynamic[tDynamicStatus] == "INPROGRESS")
331342 else false)
332343 then (parseIntValue(static[tStaticEnd]) > now)
333344 else false
334345 }
335346
336347
348+func isInDelivery (location) = {
349+ let loc = split(location, "_")
350+ let now = lastBlock.timestamp
351+ let startTime = parseIntValue(loc[locIdxContinent])
352+ let distance = parseIntValue(loc[locIdxId])
353+ if (if ((loc[locIdxType] == "D"))
354+ then (now > (startTime + TEN_MINUTES_MILLIS))
355+ else false)
356+ then (3 >= distance)
357+ else false
358+ }
359+
360+
361+func isUsualLocation (location) = {
362+ let locType = split(location, "_")[locIdxType]
363+ if ((locType != "T"))
364+ then (locType != "D")
365+ else false
366+ }
367+
368+
369+func notOnMission (tourContract,location) = {
370+ let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
371+ let loc = split(location, "_")
372+ let now = lastBlock.timestamp
373+ let tData = getTourData(tourContract, lastId)
374+ let static = tData[idxStatic]
375+ let dynamic = tData[idxDynamic]
376+ let locType = loc[locIdxType]
377+ if (if ((locType != "T"))
378+ then (locType != "D")
379+ else false)
380+ then true
381+ else !(if (if (if ((loc[locIdxType] == "T"))
382+ then (parseIntValue(loc[locIdxContinent]) == lastId)
383+ else false)
384+ then (dynamic[tDynamicStatus] == "INPROGRESS")
385+ else false)
386+ then (parseIntValue(static[tStaticEnd]) > now)
387+ else false)
388+ }
389+
390+
337391 func getRecipeMaterials (recipe) = (parseIntValue(recipe[rIdxCoeff]) * COEFF2MAT)
338392
339393
394+func cheatAttempt (oldLoc,newLoc) = throw(((("Cheat attempt: oldLoc=" + oldLoc) + ", newLoc=") + newLoc))
395+
396+
340397 let KS_SEPARATE_PUBLIC_KEY = false
341398
342399 let KS_ALLOW_BIG_INFRA_MERGE = false
400+
401+let KS_ALLOW_DELIVERY = false
343402
344403 let chain = take(drop(this.bytes, 1), 1)
345404
346405 let usdtAssetId = match chain {
347406 case _ =>
348407 if ((base58'2W' == $match0))
349408 then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
350409 else if ((base58'2T' == $match0))
351410 then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63'
352411 else throw("Unknown chain")
353412 }
354413
355414 let defaultRestAddressStr = match chain {
356415 case _ =>
357416 if ((base58'2W' == $match0))
358417 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
359418 else if ((base58'2T' == $match0))
360419 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
361420 else throw("Unknown chain")
362421 }
363422
364423 let InfraUpgradeCostS = match chain {
365424 case _ =>
366425 if ((base58'2W' == $match0))
367426 then 10000000000
368427 else if ((base58'2T' == $match0))
369428 then 100000000
370429 else throw("Unknown chain")
371430 }
372431
373432 let arbitrageDelay = match chain {
374433 case _ =>
375434 if ((base58'2W' == $match0))
376435 then 86400000
377436 else if ((base58'2T' == $match0))
378437 then 60000
379438 else throw("Unknown chain")
380439 }
381440
382441 let SEP = "__"
383442
384443 let MULT6 = 1000000
385444
386445 let MULT8 = 100000000
387446
388447 let SSIZE = 25
389448
390449 let MSIZE = 100
391450
392451 let LSIZE = 225
393452
394453 let XLSIZE = 400
395454
396455 let XXLSIZE = 625
397456
398457 let ITER6 = [0, 1, 2, 3, 4, 5]
399458
400459 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
401460
402461
403462 let IdxCfgStakingDapp = 1
404463
405464 let IdxCfgEconomyDapp = 2
406465
407466 let IdxCfgGovernanceDapp = 3
408467
409468 let IdxCfgWlgDapp = 4
410469
411470 let IdxCfgTournamentDapp = 7
412471
472+let IdxCfgAcresDapp = 8
473+
413474 func keyRestCfg () = "%s__restConfig"
414475
415476
416477 func keyRestAddress () = "%s__restAddr"
417478
418479
419480 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
420481
421482
422483 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
423484
424485
425486 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
426487
427488 let restCfg = readRestCfgOrFail(restContract)
428489
429490 let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
430491
431492 let economyContract = getContractAddressOrFail(restCfg, IdxCfgEconomyDapp)
432493
433494 let govContract = getContractAddressOrFail(restCfg, IdxCfgGovernanceDapp)
434495
435496 let wlgContract = getContractAddressOrFail(restCfg, IdxCfgWlgDapp)
436497
437498 let tournamentContract = getContractAddressOrFail(restCfg, IdxCfgTournamentDapp)
438499
500+let acresContract = getContractAddressOrFail(restCfg, IdxCfgAcresDapp)
501+
439502 let recLandNum = 0
440503
441504 let recLandSize = 1
442505
443506 let recTerrains = 2
444507
445508 let recContinent = 3
446509
447510 let wlgAssetIdKey = "wlg_assetId"
448511
449-let wlgAssetId = valueOrErrorMessage(getBinary(wlgContract, wlgAssetIdKey), "Not initialized yet")
512+let wlgAssetId = valueOrErrorMessage(getBinary(wlgContract, wlgAssetIdKey), "WLGOLD is not issued yet")
513+
514+let acresAssetIdKey = "acresAssetId"
515+
516+let acresAssetId = valueOrErrorMessage(getBinary(acresContract, acresAssetIdKey), "ACRES is not issued yet")
450517
451518 let randomDelay = 2
452519
453520 func keyCommit (address) = ("finishBlockForAddr_" + address)
454521
455522
456523 func keyResProportions () = "resTypesProportions"
457524
458525
459526 func keyResTypesByContinent (continent) = ("resTypesByContinent_" + continent)
460527
461528
462529 func keyStakedLandsByOwner (ownerAddr) = ("stakedLandsByOwner_" + ownerAddr)
463530
464531
465532 func keyStakedPiecesByOwner (ownerAddr) = ("stakedPiecesByOwner_" + ownerAddr)
466533
467534
468535 func asString (v) = match v {
469536 case s: String =>
470537 s
471538 case _ =>
472539 throw("fail to cast into String")
473540 }
474541
475542
476543 func asInt (v) = match v {
477544 case n: Int =>
478545 n
479546 case _ =>
480547 throw("fail to cast into Int")
481548 }
482549
483550
484551 func asBoolean (v) = match v {
485552 case s: Boolean =>
486553 s
487554 case _ =>
488555 throw("fail to cast into Boolean")
556+}
557+
558+
559+func asStringIntTuple (val) = match val {
560+ case t2: (String, Int) =>
561+ t2
562+ case _ =>
563+ throw("fail to cast into (String, Int)")
489564 }
490565
491566
492567 func numPiecesBySize (landSize) = match landSize {
493568 case _ =>
494569 if (("S" == $match0))
495570 then SSIZE
496571 else if (("M" == $match0))
497572 then MSIZE
498573 else if (("L" == $match0))
499574 then LSIZE
500575 else if (("XL" == $match0))
501576 then XLSIZE
502577 else if (("XXL" == $match0))
503578 then XXLSIZE
504579 else throw("Unknown land size")
505580 }
506581
507582
508583 func isDigit (s) = isDefined(parseInt(s))
509584
510585
511586 func keyBlocked () = "contractsBlocked"
512587
513588
514589 func keyLastTxIdByUser (addr) = ("lastTxIdByUser_" + addr)
515590
516591
592+func fixedPoint (val,decimals) = {
593+ let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
594+ let lowPart = toString((val % tenPow))
595+ let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
596+ (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
597+ }
598+
599+
517600 func getRandomNumber (maxValue,finishHeight,auxEntropy) = {
518601 let randomSeedBlock = value(blockInfoByHeight(finishHeight))
519602 let randomHash = sha256((value(randomSeedBlock.vrf) + auxEntropy))
520603 (toInt(randomHash) % maxValue)
521604 }
522605
523606
524607 let incubatorAddr = match chain {
525608 case _ =>
526609 if ((base58'2W' == $match0))
527610 then addressFromStringValue("3PEktVux2RhchSN63DsDo4b4mz4QqzKSeDv")
528611 else if ((base58'2T' == $match0))
529612 then this
530613 else throw("Unknown chain")
531614 }
532615
533616 let breederAddr = match chain {
534617 case _ =>
535618 if ((base58'2W' == $match0))
536619 then addressFromStringValue("3PDVuU45H7Eh5dmtNbnRNRStGwULA7NY6Hb")
537620 else if ((base58'2T' == $match0))
538621 then this
539622 else throw("Unknown chain")
540623 }
541624
542625 let pub = match chain {
543626 case _ =>
544627 if ((base58'2W' == $match0))
545628 then if (KS_SEPARATE_PUBLIC_KEY)
546629 then base58'CWsMtTZC5BjjoL4Q1ayW4Wwb1ehGACQB6DrKyPgotKfm'
547630 else base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
548631 else if ((base58'2T' == $match0))
549632 then base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
550633 else throw("Unknown chain")
551634 }
552635
553636 let EMPTY_PROD50 = base64'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='
554637
555638 let FIVEMINUTESMILLIS = 300000
556639
557640 let RENAMINGCOST = 5000000
558641
559642 let MAXNAMELEN = 50
560643
561644 let InfraUpgradeCostSUsdt = 10000000
562645
563646 let EXPMATERIALS = match chain {
564647 case _ =>
565648 if ((base58'2W' == $match0))
566649 then 252289527462
567650 else if ((base58'2T' == $match0))
568651 then 2522895274
569652 else throw("Unknown chain")
570653 }
571654
572655 let EXPUSDT = match chain {
573656 case _ =>
574657 if ((base58'2W' == $match0))
575658 then 250000000
576659 else if ((base58'2T' == $match0))
577660 then 250000000
578661 else throw("Unknown chain")
579662 }
663+
664+let S_COST_ACRES = 2500000000
580665
581666 let FIVEX = toBigInt(5)
582667
583668 let TWENTYX = toBigInt(20)
584669
585670 let TWENTY2X = toBigInt((20 * 20))
586671
587672 let TWENTY3X = toBigInt(((20 * 20) * 20))
588673
589674 let TWENTY4X = toBigInt((((20 * 20) * 20) * 20))
590675
591676 let TWENTY5X = toBigInt(((((20 * 20) * 20) * 20) * 20))
592677
593678 let PRESALENUMLANDS = 500
594679
595680 func keyNextFreeLandNum () = "nextLandNum"
596681
597682
598683 func keyLandCustomNameToAssetId (name) = ("lcn_" + name)
599684
600685
601686 func keyLandToAssetId (landNum) = ("la_" + landNum)
602687
603688
604689 func keyInfraLevelByAssetIdAndOwner (assetId,ownerAddr) = ((("ilao_" + assetId) + "_") + ownerAddr)
605690
606691
607692 func keyLandNumToOwner (landNum) = ("lo_" + landNum)
608693
609694
610695 func keyDuckCustomNameToAssetId (name) = ("duckByCustomName_" + name)
611696
612697
613698 func keyCustomNameToAddress (name) = ("accountByCustomName_" + name)
614699
615700
616701 func keyOldies () = "oldiesList"
617702
618703
619704 let claimModeWh = 0
620705
621706 let claimModeDuck = 1
622707
623708 let claimModeWhThenDuck = 2
624709
625710 let flHealth = 0
626711
627712 let flTimestamp = 5
628713
629714 let flBonus = 6
630715
631716 let flProdsUsed = 7
632717
633718 func nftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
634719
635720
636721 func toVolume (amount,pkgSize) = {
637722 let pkgs = if ((amount >= 0))
638723 then (((amount + pkgSize) - 1) / pkgSize)
639724 else -((((-(amount) + pkgSize) - 1) / pkgSize))
640725 (pkgs * MULT8)
641726 }
642727
643728
644729 func distributeByWeights (total,weights) = {
645730 let sum = (((((weights[0] + weights[1]) + weights[2]) + weights[3]) + weights[4]) + weights[5])
646731 if ((0 >= sum))
647732 then throw("Zero weights sum")
648733 else {
649734 let norm6 = fraction(total, MULT6, sum)
650735 func normalizer (acc,elem) = (acc :+ fraction(elem, norm6, MULT6))
651736
652737 let $l = weights
653738 let $s = size($l)
654739 let $acc0 = nil
655740 func $f0_1 ($a,$i) = if (($i >= $s))
656741 then $a
657742 else normalizer($a, $l[$i])
658743
659744 func $f0_2 ($a,$i) = if (($i >= $s))
660745 then $a
661746 else throw("List size exceeds 6")
662747
663748 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
664749 }
665750 }
666751
667752
668753 func getNeededMaterials (total) = {
669754 let props = split(value(getString(keyResProportions())), "_")
670755 if ((size(props) != NUMRES))
671756 then throw("Wrong proportions data")
672757 else {
673758 let r = [parseIntValue(props[0]), parseIntValue(props[1]), parseIntValue(props[2]), parseIntValue(props[3]), parseIntValue(props[4]), parseIntValue(props[5])]
674759 distributeByWeights(total, r)
675760 }
676761 }
677762
678763
679764 func subtractMaterials (shouldUseMat,has,totalNeed) = {
680765 let need = getNeededMaterials(totalNeed)
681766 func subtractor (acc,idx) = {
682767 let result = (parseIntValue(has[idx]) - need[idx])
683768 if ((0 > result))
684769 then throw(((((("Not enough material idx=" + toString(idx)) + ", you have ") + has[idx]) + ", but need ") + toString(need[idx])))
685770 else (acc :+ toString(result))
686771 }
687772
688773 if (shouldUseMat)
689774 then {
690775 let $l = ITER6
691776 let $s = size($l)
692777 let $acc0 = nil
693778 func $f0_1 ($a,$i) = if (($i >= $s))
694779 then $a
695780 else subtractor($a, $l[$i])
696781
697782 func $f0_2 ($a,$i) = if (($i >= $s))
698783 then $a
699784 else throw("List size exceeds 6")
700785
701786 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
702787 }
703788 else has
704789 }
705790
706791
707792 func subtractEquipment (oldEq,pUsed) = if ((pUsed == ""))
708793 then $Tuple2(oldEq, false)
709794 else {
710795 func subUsed (acc,idxAmt) = {
711796 let parts = split(idxAmt, ",")
712797 if ((size(parts) != 2))
713798 then throw("Incorrect format, should be index,amount")
714799 else {
715800 let idx = parseIntValue(parts[0])
716801 if (if ((0 > idx))
717802 then true
718803 else (idx >= size(productionMatrix)))
719804 then throw("Unknown product idx")
720805 else {
721806 let amt = parseIntValue(parts[1])
722807 let eqParts = split(acc._1, (parts[0] + ":"))
723808 if ((size(eqParts) != 2))
724809 then throw((("You don't have " + prodTypes[idx]) + " equipped"))
725810 else {
726811 let tmp = eqParts[1]
727812 let numLen = if (isDigit(take(drop(tmp, 1), 1)))
728813 then 2
729814 else 1
730815 let curr = parseIntValue(take(tmp, numLen))
731816 let tail = drop(tmp, numLen)
732817 let newAmt = if ((curr >= amt))
733818 then (curr - amt)
734819 else throw(((((("You equipped " + toString(curr)) + " of ") + prodTypes[idx]) + ", but tried to use ") + toString(amt)))
735820 $Tuple2(((((eqParts[0] + parts[0]) + ":") + toString(newAmt)) + tail), if (acc._2)
736821 then true
737822 else if (if ((idx >= 6))
738823 then (8 >= idx)
739824 else false)
740825 then (newAmt == 0)
741826 else false)
742827 }
743828 }
744829 }
745830 }
746831
747832 let $l = split(pUsed, "_")
748833 let $s = size($l)
749834 let $acc0 = $Tuple2(oldEq, false)
750835 func $f0_1 ($a,$i) = if (($i >= $s))
751836 then $a
752837 else subUsed($a, $l[$i])
753838
754839 func $f0_2 ($a,$i) = if (($i >= $s))
755840 then $a
756841 else throw("List size exceeds 10")
757842
758843 $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)
759844 }
760845
761846
762847 func prodStrToBytes (prodStr) = {
763848 let pList = if ((prodStr == ""))
764849 then nil
765850 else split_4C(prodStr, "_")
766851 func toBV (acc,recipe) = {
767852 let j = (size(acc) / 8)
768853 let curr = if ((size(pList) > j))
769854 then parseIntValue(pList[j])
770855 else 0
771856 (acc + toBytes(curr))
772857 }
773858
774859 let $l = productionMatrix
775860 let $s = size($l)
776861 let $acc0 = base58''
777862 func $f0_1 ($a,$i) = if (($i >= $s))
778863 then $a
779864 else toBV($a, $l[$i])
780865
781866 func $f0_2 ($a,$i) = if (($i >= $s))
782867 then $a
783868 else throw("List size exceeds 50")
784869
785870 $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)
786871 }
787872
788873
789874 func bytesToProdStr (bv) = {
790875 func fromBV (acc,recipe) = {
791876 let j = size(acc)
792877 let b = take(drop(bv, (8 * j)), 8)
793878 (acc :+ toString(toInt(b)))
794879 }
795880
796881 makeString_2C({
797882 let $l = productionMatrix
798883 let $s = size($l)
799884 let $acc0 = nil
800885 func $f0_1 ($a,$i) = if (($i >= $s))
801886 then $a
802887 else fromBV($a, $l[$i])
803888
804889 func $f0_2 ($a,$i) = if (($i >= $s))
805890 then $a
806891 else throw("List size exceeds 50")
807892
808893 $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)
809894 }, "_")
810895 }
811896
812897
813898 func checkStatRequirements (duckStats,reqs) = {
814899 func check (acc,j) = {
815900 let buff = if ((size(duckStats) > (7 + j)))
816901 then duckStats[(7 + j)]
817902 else 0
818903 if ((parseIntValue(reqs[j]) > (duckStats[j] + buff)))
819904 then throw(("Requirement not satisfied: " + requirements[j]))
820905 else true
821906 }
822907
823908 let $l = [0, 1, 2, 3, 4, 5, 6]
824909 let $s = size($l)
825910 let $acc0 = false
826911 func $f0_1 ($a,$i) = if (($i >= $s))
827912 then $a
828913 else check($a, $l[$i])
829914
830915 func $f0_2 ($a,$i) = if (($i >= $s))
831916 then $a
832917 else throw("List size exceeds 7")
833918
834919 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
835920 }
836921
837922
838923 func placeProdB (idxCnt,pList,isPositive,duckStats,occupied,free) = {
839924 let parts = split(idxCnt, ":")
840925 if ((size(parts) != 2))
841926 then throw("Incorrect format, should be index:amount")
842927 else if (if (!(isPositive))
843928 then (size(parts[0]) != 2)
844929 else false)
845930 then throw("Product idx should be 2 digits, zero padded")
846931 else {
847932 let productIdx = parseIntValue(parts[0])
848933 let count = parseIntValue(parts[1])
849934 if (!(containsElement(fortAllowedProds, productIdx)))
850935 then throw((("Product '" + prodTypes[productIdx]) + "' cannot be used for land defense"))
851936 else if ((0 > count))
852937 then throw("Count can't be negative")
853938 else if ((count > MAXPRODINSLOT))
854939 then throw(((("Can't put more than " + toString(MAXPRODINSLOT)) + " of ") + prodTypes[productIdx]))
855940 else if ((count == 0))
856941 then $Tuple3(pList, occupied, free)
857942 else {
858943 let head = take(pList, (8 * productIdx))
859944 let curr = toInt(take(drop(pList, (8 * productIdx)), 8))
860945 let tail = drop(pList, (8 * (productIdx + 1)))
861946 let recipe = split(productionMatrix[productIdx], "_")
862947 if (if (!(isPositive))
863948 then (count > curr)
864949 else false)
865950 then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[productIdx]) + ", but tried to use ") + toString(count)))
866951 else {
867952 let newAmt = if (if (!(isPositive))
868953 then checkStatRequirements(duckStats, split(recipe[rIdxRequirements], ","))
869954 else false)
870955 then (curr - count)
871956 else (curr + count)
872957 let deltaVol = (toVolume(newAmt, PRODUCTPKGSIZE) - toVolume(curr, PRODUCTPKGSIZE))
873958 $Tuple3(((head + toBytes(newAmt)) + tail), (occupied + deltaVol), (free - deltaVol))
874959 }
875960 }
876961 }
877962 }
878963
879964
880965 func addProdB (idxCnt,pList,isPositive,segment,mainAux,slot,duckStats) = {
881966 let parts = split(idxCnt, ":")
882967 if ((size(parts) != 2))
883968 then throw("Incorrect format, should be index:amount")
884969 else if (if (!(isPositive))
885970 then (size(parts[0]) != 2)
886971 else false)
887972 then throw("Product idx should be 2 digits, zero padded")
888973 else {
889974 let productIdx = parseIntValue(parts[0])
890975 let count = parseIntValue(parts[1])
891976 if (if ((0 > productIdx))
892977 then true
893978 else (productIdx >= size(productionMatrix)))
894979 then throw("Unknown product idx")
895980 else if ((0 > count))
896981 then throw("Count can't be negative")
897982 else if ((count > MAXPRODINSLOT))
898983 then throw(((("Can't put more than " + toString(MAXPRODINSLOT)) + " of ") + prodTypes[productIdx]))
899984 else if ((count == 0))
900985 then $Tuple2(pList, false)
901986 else {
902987 let head = take(pList, (8 * productIdx))
903988 let curr = toInt(take(drop(pList, (8 * productIdx)), 8))
904989 let tail = drop(pList, (8 * (productIdx + 1)))
905990 let recipe = split(productionMatrix[productIdx], "_")
906991 if (if (!(isPositive))
907992 then (count > curr)
908993 else false)
909994 then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[productIdx]) + ", but tried to use ") + toString(count)))
910995 else {
911996 let isBigItem = if (if (!(isPositive))
912997 then checkStatRequirements(duckStats, split(recipe[rIdxRequirements], ","))
913998 else false)
914999 then {
9151000 let compat = recipe[rIdxSlots]
9161001 if ((compat == ""))
9171002 then throw("Item cannot be equipped")
9181003 else {
9191004 let c = parseIntValue(compat)
9201005 let cSeg = (c / 100)
9211006 if ((segment != cSeg))
9221007 then throw("Segment incompatible")
9231008 else {
9241009 let cMainAux = ((c % 100) / 10)
9251010 if ((mainAux != cMainAux))
9261011 then throw("Slot incompatible")
9271012 else {
9281013 let cNumSlots = (c % 10)
9291014 if (if ((slot != 0))
9301015 then (cNumSlots > 1)
9311016 else false)
9321017 then throw("Big items should occupy slot 0")
9331018 else (cNumSlots > 1)
9341019 }
9351020 }
9361021 }
9371022 }
9381023 else false
9391024 $Tuple2(((head + toBytes((curr + (if (isPositive)
9401025 then count
9411026 else -(count))))) + tail), isBigItem)
9421027 }
9431028 }
9441029 }
9451030 }
9461031
9471032
9481033 func slotsGroupB (g,bpIn,isPositive,segment,mainAux,stats) = if ((g != ""))
9491034 then {
9501035 let slots = split(g, ",")
9511036 if ((size(slots) > MAXSLOTS))
9521037 then throw("Wrong slots format")
9531038 else {
9541039 let s0 = slots[0]
9551040 let s1 = if ((size(slots) > 1))
9561041 then slots[1]
9571042 else ""
9581043 if (if ((s0 == ""))
9591044 then (s1 == "")
9601045 else false)
9611046 then bpIn
9621047 else {
9631048 let tmpS0 = if ((s0 != ""))
9641049 then addProdB(s0, bpIn, isPositive, segment, mainAux, 0, stats)
9651050 else $Tuple2(bpIn, false)
9661051 if ((s1 != ""))
9671052 then if (tmpS0._2)
9681053 then throw("Big item already occupies slot")
9691054 else addProdB(s1, tmpS0._1, isPositive, segment, mainAux, 1, stats)._1
9701055 else tmpS0._1
9711056 }
9721057 }
9731058 }
9741059 else bpIn
9751060
9761061
9771062 func dressB (segList,pBytes,isPositive,stats) = {
9781063 func segment (acc,seg) = {
9791064 let j = acc._1
9801065 let mainAux = split(seg, ";")
9811066 if ((size(mainAux) != NUMMAINAUX))
9821067 then throw("Wrong segment format")
9831068 else {
9841069 let m = mainAux[0]
9851070 let a = mainAux[1]
9861071 if (if ((m == ""))
9871072 then (a == "")
9881073 else false)
9891074 then $Tuple2((j + 1), acc._2)
9901075 else {
9911076 let tmpM = slotsGroupB(m, acc._2, isPositive, j, 0, stats)
9921077 $Tuple2((j + 1), slotsGroupB(a, tmpM, isPositive, j, 1, stats))
9931078 }
9941079 }
9951080 }
9961081
9971082 ( let $l = segList
9981083 let $s = size($l)
9991084 let $acc0 = $Tuple2(0, pBytes)
10001085 func $f0_1 ($a,$i) = if (($i >= $s))
10011086 then $a
10021087 else segment($a, $l[$i])
10031088
10041089 func $f0_2 ($a,$i) = if (($i >= $s))
10051090 then $a
10061091 else throw("List size exceeds 6")
10071092
10081093 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6))._2
10091094 }
10101095
10111096
10121097 func fortB (segList,pBytes,occupied,free,isPositive,duckStats) = if ((3 > size(segList)))
10131098 then throw("At least duck, mines and traps parts are required")
10141099 else {
10151100 func segment (acc,seg) = {
10161101 let j = acc._1
10171102 if ((j == 0))
10181103 then $Tuple4((j + 1), acc._2, acc._3, acc._4)
10191104 else {
10201105 let p = placeProdB(seg, acc._2, isPositive, duckStats, acc._3, acc._4)
10211106 $Tuple4((j + 1), p._1, p._2, p._3)
10221107 }
10231108 }
10241109
10251110 let t = {
10261111 let $l = segList
10271112 let $s = size($l)
10281113 let $acc0 = $Tuple4(0, pBytes, occupied, free)
10291114 func $f0_1 ($a,$i) = if (($i >= $s))
10301115 then $a
10311116 else segment($a, $l[$i])
10321117
10331118 func $f0_2 ($a,$i) = if (($i >= $s))
10341119 then $a
10351120 else throw("List size exceeds 10")
10361121
10371122 $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)
10381123 }
10391124 $Tuple3(t._2, t._3, t._4)
10401125 }
10411126
10421127
10431128 func canWearCurrentEquipment (duckAssetId) = {
10441129 let eqKey = keyDuckEquipment(duckAssetId)
10451130 let currEq = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
10461131 let tempProdB = dressB(currEq, EMPTY_PROD50, true, nil)
10471132 let segBpAux = split(currEq[segBackpack], ";")[1]
10481133 let buffEffect = if ((segBpAux == ""))
10491134 then 0
10501135 else {
10511136 let aux0 = split(segBpAux, ",")[0]
10521137 if ((aux0 == ""))
10531138 then 0
10541139 else {
10551140 let idxCnt = split(aux0, ":")
10561141 let idx = idxCnt[0]
10571142 let cnt = idxCnt[1]
10581143 if (if (if (if (if ((idx == "06"))
10591144 then true
10601145 else (idx == "07"))
10611146 then true
10621147 else (idx == "08"))
10631148 then (cnt != "")
10641149 else false)
10651150 then (parseIntValue(cnt) > 0)
10661151 else false)
10671152 then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
10681153 else 0
10691154 }
10701155 }
10711156 let stats = getDuckStats(this, duckAssetId, buffEffect, true)
10721157 let newProdB = dressB(currEq, tempProdB, false, stats)
10731158 (newProdB == newProdB)
10741159 }
10751160
10761161
10771162 func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
10781163 then throw("Wrong proportions data")
10791164 else {
10801165 func updater (acc,i) = {
10811166 let result = (parseIntValue(propList[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
10821167 if ((0 > result))
10831168 then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
10841169 else (acc :+ toString(result))
10851170 }
10861171
10871172 let $l = ITER6
10881173 let $s = size($l)
10891174 let $acc0 = nil
10901175 func $f0_1 ($a,$i) = if (($i >= $s))
10911176 then $a
10921177 else updater($a, $l[$i])
10931178
10941179 func $f0_2 ($a,$i) = if (($i >= $s))
10951180 then $a
10961181 else throw("List size exceeds 6")
10971182
10981183 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
10991184 }
11001185
11011186
11021187 func updateProportions (terrainCounts,landSizeIndex,sign) = {
11031188 let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
11041189 makeString(updateProportionsInternal(propList, terrainCounts, landSizeIndex, sign), "_")
11051190 }
11061191
11071192
11081193 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)]
11091194
11101195
11111196 func addRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
11121197 func adder (acc,i) = {
11131198 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
11141199 (acc :+ toString((parseIntValue(currentRes[i]) + resOfType)))
11151200 }
11161201
11171202 let r = {
11181203 let $l = ITER6
11191204 let $s = size($l)
11201205 let $acc0 = nil
11211206 func $f0_1 ($a,$i) = if (($i >= $s))
11221207 then $a
11231208 else adder($a, $l[$i])
11241209
11251210 func $f0_2 ($a,$i) = if (($i >= $s))
11261211 then $a
11271212 else throw("List size exceeds 6")
11281213
11291214 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
11301215 }
11311216 makeString(r, "_")
11321217 }
11331218
11341219
11351220 func virtClaim (terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
11361221 func adder (acc,i) = {
11371222 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
11381223 $Tuple2((acc._1 :+ resOfType), (acc._2 + resOfType))
11391224 }
11401225
11411226 let $l = ITER6
11421227 let $s = size($l)
11431228 let $acc0 = $Tuple2(nil, 0)
11441229 func $f0_1 ($a,$i) = if (($i >= $s))
11451230 then $a
11461231 else adder($a, $l[$i])
11471232
11481233 func $f0_2 ($a,$i) = if (($i >= $s))
11491234 then $a
11501235 else throw("List size exceeds 6")
11511236
11521237 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
11531238 }
11541239
11551240
11561241 func distributeRes (currentWhRes,currentPackRes,resToClaim,whSpaceLeft) = {
11571242 let resListToClaim = resToClaim._1
11581243 let resAmToClaim = resToClaim._2
11591244 if ((resAmToClaim == 0))
11601245 then $Tuple2(makeString(currentWhRes, "_"), makeString(currentPackRes, "_"))
11611246 else if ((whSpaceLeft >= resAmToClaim))
11621247 then {
11631248 func addLists (acc,i) = (acc :+ toString((parseIntValue(currentWhRes[i]) + resListToClaim[i])))
11641249
11651250 let r = {
11661251 let $l = ITER6
11671252 let $s = size($l)
11681253 let $acc0 = nil
11691254 func $f0_1 ($a,$i) = if (($i >= $s))
11701255 then $a
11711256 else addLists($a, $l[$i])
11721257
11731258 func $f0_2 ($a,$i) = if (($i >= $s))
11741259 then $a
11751260 else throw("List size exceeds 6")
11761261
11771262 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
11781263 }
11791264 $Tuple2(makeString(r, "_"), makeString(currentPackRes, "_"))
11801265 }
11811266 else {
11821267 func addPartLists (acc,i) = {
11831268 let whPart = fraction(resListToClaim[i], whSpaceLeft, resAmToClaim)
11841269 $Tuple2((acc._1 :+ toString((parseIntValue(currentWhRes[i]) + whPart))), (acc._2 :+ toString(((parseIntValue(currentPackRes[i]) + resListToClaim[i]) - whPart))))
11851270 }
11861271
11871272 let r = {
11881273 let $l = ITER6
11891274 let $s = size($l)
11901275 let $acc0 = $Tuple2(nil, nil)
11911276 func $f0_1 ($a,$i) = if (($i >= $s))
11921277 then $a
11931278 else addPartLists($a, $l[$i])
11941279
11951280 func $f0_2 ($a,$i) = if (($i >= $s))
11961281 then $a
11971282 else throw("List size exceeds 6")
11981283
11991284 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12001285 }
12011286 $Tuple2(makeString(r._1, "_"), makeString(r._2, "_"))
12021287 }
12031288 }
12041289
12051290
12061291 func abs (x) = if ((x >= toBigInt(0)))
12071292 then x
12081293 else -(x)
12091294
12101295
12111296 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]]
12121297
12131298 func genChar (n,freqs) = {
12141299 let rem = toInt((n % TWENTYX))
12151300 let letter = if ((freqs[0] > rem))
12161301 then "A"
12171302 else if ((freqs[1] > rem))
12181303 then "B"
12191304 else if ((freqs[2] > rem))
12201305 then "C"
12211306 else if ((freqs[3] > rem))
12221307 then "D"
12231308 else if ((freqs[4] > rem))
12241309 then "E"
12251310 else "F"
12261311 letter
12271312 }
12281313
12291314
12301315 func genTerrains (seed,continentIdx) = {
12311316 let f = freq[continentIdx]
12321317 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))
12331318
12341319 let t = {
12351320 let $l = [1, 2, 3, 4, 5]
12361321 let $s = size($l)
12371322 let $acc0 = $Tuple2("", (seed / FIVEX))
12381323 func $f0_1 ($a,$i) = if (($i >= $s))
12391324 then $a
12401325 else terrainGenerator($a, $l[$i])
12411326
12421327 func $f0_2 ($a,$i) = if (($i >= $s))
12431328 then $a
12441329 else throw("List size exceeds 5")
12451330
12461331 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
12471332 }
12481333 t._1
12491334 }
12501335
12511336
12521337 let PERM25 = [7, 2, 15, 19, 8, 24, 1, 21, 16, 5, 0, 22, 20, 23, 11, 4, 18, 12, 6, 10, 3, 17, 13, 9, 14]
12531338
12541339 let TCHARS = ["A", "B", "C", "D", "E", "F"]
12551340
12561341 func genTerrainsForMerge (sumTerrains,landSizeIndex) = {
12571342 func step1 (acc,s) = {
12581343 let j = acc._2
12591344 let el = parseIntValue(s)
12601345 let x = if ((el == 0))
12611346 then 0
12621347 else if ((el >= (4 * landSizeIndex)))
12631348 then (el / landSizeIndex)
12641349 else if ((el > (3 * landSizeIndex)))
12651350 then 3
12661351 else (((el - 1) / landSizeIndex) + 1)
12671352 $Tuple3((acc._1 :+ x), (acc._2 + 1), (acc._3 + x))
12681353 }
12691354
12701355 let t = {
12711356 let $l = sumTerrains
12721357 let $s = size($l)
12731358 let $acc0 = $Tuple3(nil, 0, 0)
12741359 func $f0_1 ($a,$i) = if (($i >= $s))
12751360 then $a
12761361 else step1($a, $l[$i])
12771362
12781363 func $f0_2 ($a,$i) = if (($i >= $s))
12791364 then $a
12801365 else throw("List size exceeds 6")
12811366
12821367 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12831368 }
12841369 let arr = t._1
12851370 let maxIdx = value(indexOf(arr, max(arr)))
12861371 let delta = (t._3 - 25)
12871372 func subber (acc,idx) = {
12881373 let val = if ((idx == maxIdx))
12891374 then (arr[idx] - delta)
12901375 else arr[idx]
12911376 let zeroes = if ((val == 0))
12921377 then nil
12931378 else split(drop(toString(pow(10, 0, val, 0, 0, DOWN)), 1), "")
12941379 let c = TCHARS[idx]
12951380 func listGen (ac,ignored) = (ac :+ c)
12961381
12971382 let z = {
12981383 let $l = zeroes
12991384 let $s = size($l)
13001385 let $acc0 = nil
13011386 func $f1_1 ($a,$i) = if (($i >= $s))
13021387 then $a
13031388 else listGen($a, $l[$i])
13041389
13051390 func $f1_2 ($a,$i) = if (($i >= $s))
13061391 then $a
13071392 else throw("List size exceeds 25")
13081393
13091394 $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($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)
13101395 }
13111396 (acc ++ z)
13121397 }
13131398
13141399 let r = {
13151400 let $l = ITER6
13161401 let $s = size($l)
13171402 let $acc0 = nil
13181403 func $f1_1 ($a,$i) = if (($i >= $s))
13191404 then $a
13201405 else subber($a, $l[$i])
13211406
13221407 func $f1_2 ($a,$i) = if (($i >= $s))
13231408 then $a
13241409 else throw("List size exceeds 6")
13251410
13261411 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
13271412 }
13281413 func permut (acc,j) = (acc + r[j])
13291414
13301415 let $l = PERM25
13311416 let $s = size($l)
13321417 let $acc0 = ""
13331418 func $f2_1 ($a,$i) = if (($i >= $s))
13341419 then $a
13351420 else permut($a, $l[$i])
13361421
13371422 func $f2_2 ($a,$i) = if (($i >= $s))
13381423 then $a
13391424 else throw("List size exceeds 25")
13401425
13411426 $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($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)
13421427 }
13431428
13441429
13451430 func getBackpack (bpKey) = {
13461431 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
13471432 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
13481433 then p[bpIdxRes]
13491434 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
13501435 then p[bpIdxMat]
13511436 else "0_0_0_0_0_0", p[bpIdxProd]]
13521437 }
13531438
13541439
13551440 func getWarehouseTotalVolume (volPrefix) = {
13561441 let parts = split(volPrefix, "_")
13571442 ((WHMULTIPLIER * (parseIntValue(parts[1]) + 1)) * parseIntValue(parts[0]))
13581443 }
13591444
13601445
13611446 func getWarehouseOccupiedVol (currentWh) = {
13621447 let goods = currentWh[whIdxProd]
13631448 func sumResMat (acc,item) = (acc + parseIntValue(item))
13641449
13651450 func sumProd (acc,item) = {
13661451 let idx = acc._1
13671452 let pkgs = (((parseIntValue(item) + PRODUCTPKGSIZE) - 1) / PRODUCTPKGSIZE)
13681453 $Tuple2((idx + 1), (acc._2 + (pkgs * MULT8)))
13691454 }
13701455
13711456 let whResVol = {
13721457 let $l = split(currentWh[whIdxRes], "_")
13731458 let $s = size($l)
13741459 let $acc0 = 0
13751460 func $f0_1 ($a,$i) = if (($i >= $s))
13761461 then $a
13771462 else sumResMat($a, $l[$i])
13781463
13791464 func $f0_2 ($a,$i) = if (($i >= $s))
13801465 then $a
13811466 else throw("List size exceeds 6")
13821467
13831468 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
13841469 }
13851470 let whMatVol = {
13861471 let $l = split(currentWh[whIdxMat], "_")
13871472 let $s = size($l)
13881473 let $acc0 = 0
13891474 func $f1_1 ($a,$i) = if (($i >= $s))
13901475 then $a
13911476 else sumResMat($a, $l[$i])
13921477
13931478 func $f1_2 ($a,$i) = if (($i >= $s))
13941479 then $a
13951480 else throw("List size exceeds 6")
13961481
13971482 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
13981483 }
13991484 let whGoodsVol = if ((goods == ""))
14001485 then 0
14011486 else ( let $l = split_4C(goods, "_")
14021487 let $s = size($l)
14031488 let $acc0 = $Tuple2(0, 0)
14041489 func $f2_1 ($a,$i) = if (($i >= $s))
14051490 then $a
14061491 else sumProd($a, $l[$i])
14071492
14081493 func $f2_2 ($a,$i) = if (($i >= $s))
14091494 then $a
14101495 else throw("List size exceeds 50")
14111496
14121497 $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
14131498 ((whResVol + whMatVol) + whGoodsVol)
14141499 }
14151500
14161501
14171502 func getWarehouse (whKey,landIndex,infraLevel) = {
14181503 let volPrefix = ((toString(landIndex) + "_") + toString(infraLevel))
14191504 let whTotal = getWarehouseTotalVolume(volPrefix)
14201505 let whStr = valueOrElse(getString(whKey), (volPrefix + ":0_0_0_0_0_0:0_0_0_0_0_0::0"))
14211506 let wh = split_4C(whStr, ":")
14221507 let whOccupied = getWarehouseOccupiedVol(wh)
14231508 let whLoft = if ((5 > size(wh)))
14241509 then makeString(["0", toString(whOccupied), toString((whTotal - whOccupied)), toString(whTotal)], "_")
14251510 else {
14261511 let loft = split(wh[whIdxLOFT], "_")
14271512 let whLocked = parseIntValue(loft[volLocked])
14281513 let occ = if ((size(loft) > 1))
14291514 then parseIntValue(loft[volOccupied])
14301515 else whOccupied
14311516 makeString([toString(whLocked), toString(occ), toString(((whTotal - whLocked) - occ)), toString(whTotal)], "_")
14321517 }
14331518 [wh[whIdxLevels], if ((size(split(wh[whIdxRes], "_")) == NUMRES))
14341519 then wh[whIdxRes]
14351520 else "0_0_0_0_0_0", if ((size(split(wh[whIdxMat], "_")) == NUMRES))
14361521 then wh[whIdxMat]
14371522 else "0_0_0_0_0_0", wh[whIdxProd], whLoft]
14381523 }
14391524
14401525
14411526 func getWarehouseSpaceLeft (currentWh) = {
14421527 let occupiedVol = getWarehouseOccupiedVol(currentWh)
14431528 let currWhLockedVol = parseIntValue(split(currentWh[whIdxLOFT], "_")[volLocked])
14441529 ((getWarehouseTotalVolume(currentWh[whIdxLevels]) - occupiedVol) - currWhLockedVol)
14451530 }
14461531
14471532
14481533 func moveStuff (cargoParts,currentWh,currentPack) = if ((size(cargoParts) != 3))
14491534 then throw("cargoListStr should contain exactly 2 ':' separators")
14501535 else {
14511536 let resParts = split(cargoParts[0], "_")
14521537 let matParts = split(cargoParts[1], "_")
14531538 let prodParts = if ((cargoParts[2] == ""))
14541539 then nil
14551540 else split_4C(cargoParts[2], "_")
14561541 if ((size(resParts) != NUMRES))
14571542 then throw("All 6 resources should be passed")
14581543 else if ((size(matParts) != NUMRES))
14591544 then throw("All 6 materials should be passed")
14601545 else {
14611546 let whSpaceLeft = getWarehouseSpaceLeft(currentWh)
14621547 let currWhRes = split(currentWh[whIdxRes], "_")
14631548 let currWhMat = split(currentWh[whIdxMat], "_")
14641549 let currWhProd = if ((currentWh[whIdxProd] == ""))
14651550 then nil
14661551 else split_4C(currentWh[whIdxProd], "_")
14671552 let currentPackRes = split(currentPack[bpIdxRes], "_")
14681553 let currentPackMat = split(currentPack[bpIdxMat], "_")
14691554 let currentPackProd = if ((currentPack[bpIdxProd] == ""))
14701555 then nil
14711556 else split_4C(currentPack[bpIdxProd], "_")
14721557 func mvR (acc,item) = {
14731558 let i = acc._1
14741559 let am = parseIntValue(item)
14751560 let whr = parseIntValue(currWhRes[i])
14761561 let bpr = parseIntValue(currentPackRes[i])
14771562 if ((am == 0))
14781563 then $Tuple4((i + 1), (acc._2 :+ currWhRes[i]), (acc._3 :+ currentPackRes[i]), acc._4)
14791564 else if ((am > 0))
14801565 then if ((am > bpr))
14811566 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpr)) + " available"))
14821567 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
14831568 else if ((-(am) > whr))
14841569 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whr)) + " available"))
14851570 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
14861571 }
14871572
14881573 let r = {
14891574 let $l = resParts
14901575 let $s = size($l)
14911576 let $acc0 = $Tuple4(0, nil, nil, 0)
14921577 func $f0_1 ($a,$i) = if (($i >= $s))
14931578 then $a
14941579 else mvR($a, $l[$i])
14951580
14961581 func $f0_2 ($a,$i) = if (($i >= $s))
14971582 then $a
14981583 else throw("List size exceeds 6")
14991584
15001585 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
15011586 }
15021587 func mvM (acc,item) = {
15031588 let i = acc._1
15041589 let am = parseIntValue(item)
15051590 let whm = parseIntValue(currWhMat[i])
15061591 let bpm = parseIntValue(currentPackMat[i])
15071592 if ((am == 0))
15081593 then $Tuple4((i + 1), (acc._2 :+ currWhMat[i]), (acc._3 :+ currentPackMat[i]), acc._4)
15091594 else if ((am > 0))
15101595 then if ((am > bpm))
15111596 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpm)) + " available"))
15121597 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
15131598 else if ((-(am) > whm))
15141599 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whm)) + " available"))
15151600 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
15161601 }
15171602
15181603 let m = {
15191604 let $l = matParts
15201605 let $s = size($l)
15211606 let $acc0 = $Tuple4(0, nil, nil, r._4)
15221607 func $f1_1 ($a,$i) = if (($i >= $s))
15231608 then $a
15241609 else mvM($a, $l[$i])
15251610
15261611 func $f1_2 ($a,$i) = if (($i >= $s))
15271612 then $a
15281613 else throw("List size exceeds 6")
15291614
15301615 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
15311616 }
15321617 func mvP (acc,item) = {
15331618 let i = acc._1
15341619 let am = parseIntValue(item)
15351620 let whp = if ((size(currWhProd) > i))
15361621 then parseIntValue(currWhProd[i])
15371622 else 0
15381623 let bpp = if ((size(currentPackProd) > i))
15391624 then parseIntValue(currentPackProd[i])
15401625 else 0
15411626 if ((am == 0))
15421627 then $Tuple4((i + 1), (acc._2 :+ toString(whp)), (acc._3 :+ toString(bpp)), acc._4)
15431628 else if ((am > 0))
15441629 then if ((am > bpp))
15451630 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpp)) + " available"))
15461631 else {
15471632 let deltaVol = (toVolume((whp + am), PRODUCTPKGSIZE) - toVolume(whp, PRODUCTPKGSIZE))
15481633 $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
15491634 }
15501635 else if ((-(am) > whp))
15511636 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whp)) + " available"))
15521637 else {
15531638 let deltaVol = (toVolume((whp + am), PRODUCTPKGSIZE) - toVolume(whp, PRODUCTPKGSIZE))
15541639 $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
15551640 }
15561641 }
15571642
15581643 let p = if ((size(prodParts) != 0))
15591644 then {
15601645 let $l = prodParts
15611646 let $s = size($l)
15621647 let $acc0 = $Tuple4(0, nil, nil, m._4)
15631648 func $f2_1 ($a,$i) = if (($i >= $s))
15641649 then $a
15651650 else mvP($a, $l[$i])
15661651
15671652 func $f2_2 ($a,$i) = if (($i >= $s))
15681653 then $a
15691654 else throw("List size exceeds 50")
15701655
15711656 $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)
15721657 }
15731658 else $Tuple4(0, currWhProd, currentPackProd, m._4)
15741659 let volSaldo = p._4
15751660 if ((volSaldo > whSpaceLeft))
15761661 then throw((((("Attempt to put total " + toString(volSaldo)) + " stuff, but only ") + toString(whSpaceLeft)) + " warehouse space left"))
15771662 else $Tuple7(makeString(r._2, "_"), makeString(m._2, "_"), makeString_2C(p._2, "_"), makeString(r._3, "_"), makeString(m._3, "_"), makeString_2C(p._3, "_"), volSaldo)
15781663 }
15791664 }
15801665
15811666
15821667 func expeditionInternal (caller,txId) = {
15831668 let userAddr = toString(caller)
15841669 let bigNum = abs(toBigInt(txId))
15851670 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
15861671 let landNum = toString(freeNum)
15871672 let continentIdx = toInt((bigNum % FIVEX))
15881673 let terrains = genTerrains(bigNum, continentIdx)
15891674 let continent = continents[continentIdx]
15901675 let issue = Issue(nftName(landNum, "S"), makeString([landNum, "S", terrains, continent], "_"), 1, 0, false)
15911676 let assetId = calculateAssetId(issue)
15921677 let id = toBase58String(assetId)
15931678 $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))
15941679 }
15951680
15961681
15971682 func flightCommon (userAddr,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
15981683 then throw("signature does not match")
15991684 else {
16001685 let parts = split_4C(toUtf8String(message), ";")
16011686 let flightLog = split_4C(parts[0], "|")
16021687 let hp = split(flightLog[flHealth], "_")
16031688 let curHP = parseIntValue(hp[0])
16041689 let newHP = parseIntValue(hp[1])
16051690 let newLocTxVer = split(parts[1], ":")
16061691 let newLocation = newLocTxVer[0]
16071692 let time = parseIntValue(flightLog[flTimestamp])
16081693 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
16091694 then true
16101695 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
16111696 then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
16121697 else {
16131698 let txFromMsg = newLocTxVer[1]
16141699 let lastTx = valueOrElse(getString(keyLastTxIdByUser(userAddr)), "")
16151700 if ((lastTx != txFromMsg))
16161701 then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
16171702 else {
16181703 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
16191704 let keyHealth = keyDuckHealth(duckAssetId)
16201705 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
16211706 let oldFromState = valueOrElse(getInteger(keyHealth), maxHP)
16221707 if ((oldFromState != curHP))
16231708 then throw(((("oldHealth=" + toString(oldFromState)) + " from state does not match one from flight log=") + toString(curHP)))
16241709 else if ((0 >= curHP))
16251710 then throw("You can't fly with zero health")
16261711 else if (!(canWearCurrentEquipment(duckAssetId)))
16271712 then throw("Equipment incompatible")
16281713 else {
16291714 let bonus = if ((size(flightLog) > flBonus))
16301715 then flightLog[flBonus]
16311716 else ""
16321717 let prodUsed = if ((size(flightLog) > flProdsUsed))
16331718 then flightLog[flProdsUsed]
16341719 else ""
16351720 let sentAmount = if (if ((newHP > 0))
16361721 then (bonus == "$")
16371722 else false)
16381723 then asInt(invoke(restContract, "sendUsdtPrize", [userAddr], nil))
16391724 else 0
16401725 $Tuple5(newHP, duckAssetId, sentAmount, newLocation, prodUsed)
16411726 }
16421727 }
16431728 }
16441729 }
16451730
16461731
16471732 func applyBonuses (landAssetId,pieces) = {
16481733 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
16491734 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
16501735 let add6 = (infraLevel / 6)
16511736 let add7 = (infraLevel / 7)
16521737 ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, ((infraLevel + add6) + (2 * add7)), 5)) + fraction(DAILYRESBYPIECE, artPieces, (pieces * 5)))
16531738 }
16541739
16551740
16561741 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
1657- let $t03370634245 = if ((claimMode == claimModeWh))
1742+ let $t03373834277 = if ((claimMode == claimModeWh))
16581743 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
16591744 else {
16601745 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
16611746 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
16621747 let loc = split(value(curLocation), "_")
16631748 if ((loc[locIdxType] != "L"))
16641749 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
16651750 else $Tuple2(loc[locIdxId], duckAssetId)
16661751 }
1667- let landAssetId = $t03370634245._1
1668- let duckId = $t03370634245._2
1752+ let landAssetId = $t03373834277._1
1753+ let duckId = $t03373834277._2
16691754 let asset = value(assetInfo(fromBase58String(landAssetId)))
16701755 let timeKey = keyStakedTimeByAssetId(landAssetId)
16711756 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
16721757 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
16731758 if ((owner != addr))
16741759 then throw((LANDPREFIX + " is not yours"))
16751760 else {
16761761 let d = split(asset.description, "_")
16771762 $Tuple4(duckId, landAssetId, d, savedTime)
16781763 }
16791764 }
16801765
16811766
16821767 func claimResInternal (addr,amount,claimMode,landAssetIdIn) = if ((0 > amount))
16831768 then throw("Negative amount")
16841769 else {
16851770 let c = checkClaimConditions(addr, claimMode, landAssetIdIn)
16861771 let landSize = c._3[recLandSize]
16871772 let terrainCounts = countTerrains(c._3[recTerrains])
16881773 let deltaTime = (lastBlock.timestamp - c._4)
16891774 if ((0 > deltaTime))
16901775 then throw(((("Saved timestamp is in future, saved = " + toString(c._4)) + ", current = ") + toString(lastBlock.timestamp)))
16911776 else {
16921777 let pieces = numPiecesBySize(landSize)
16931778 let dailyProductionByPiece = applyBonuses(c._2, pieces)
16941779 let availRes = fraction(deltaTime, (dailyProductionByPiece * pieces), DAYMILLIS)
16951780 if ((amount > availRes))
16961781 then throw(((("Not enough resources, available = " + toString(availRes)) + ", requested = ") + toString(amount)))
16971782 else {
16981783 let newDeltaTime = fraction((availRes - amount), DAYMILLIS, (dailyProductionByPiece * pieces))
16991784 let newTimestamp = (lastBlock.timestamp - newDeltaTime)
17001785 let landIndex = (pieces / SSIZE)
17011786 let resToClaim = virtClaim(terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece)
17021787 let whKey = keyWarehouseByLand(c._2)
17031788 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(c._2)), 0)
17041789 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
17051790 let loft = split(currentWh[whIdxLOFT], "_")
17061791 let whSpaceLeft = parseIntValue(loft[volFree])
17071792 if (if ((claimMode == claimModeWh))
17081793 then (amount > whSpaceLeft)
17091794 else false)
17101795 then throw((("Only " + toString(whSpaceLeft)) + " space left in warehouse"))
17111796 else {
17121797 let bpKey = keyBackpackByDuck(c._1)
17131798 let currentPack = getBackpack(bpKey)
17141799 let currentPackRes = split(currentPack[bpIdxRes], "_")
17151800 let currentWhRes = split(currentWh[whIdxRes], "_")
1716- let $t03661937490 = if ((claimMode == claimModeWh))
1801+ let $t03665137522 = if ((claimMode == claimModeWh))
17171802 then $Tuple4(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes], (parseIntValue(loft[volOccupied]) + resToClaim._2), (parseIntValue(loft[volFree]) - resToClaim._2))
17181803 else if ((claimMode == claimModeDuck))
17191804 then $Tuple4(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), parseIntValue(loft[volOccupied]), parseIntValue(loft[volFree]))
17201805 else {
17211806 let distr = distributeRes(currentWhRes, currentPackRes, resToClaim, whSpaceLeft)
17221807 let whAm = min([parseIntValue(loft[volFree]), resToClaim._2])
17231808 $Tuple4(distr._1, distr._2, (parseIntValue(loft[volOccupied]) + whAm), (parseIntValue(loft[volFree]) - whAm))
17241809 }
1725- let whRes = $t03661937490._1
1726- let bpRes = $t03661937490._2
1727- let loftO = $t03661937490._3
1728- let loftF = $t03661937490._4
1810+ let whRes = $t03665137522._1
1811+ let bpRes = $t03665137522._2
1812+ let loftO = $t03665137522._3
1813+ let loftF = $t03665137522._4
17291814 $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]], "_")])
17301815 }
17311816 }
17321817 }
17331818 }
17341819
17351820
17361821 func claimAll (addr,landAssetId,pieces,claimMode) = {
17371822 let timeKey = keyStakedTimeByAssetId(landAssetId)
17381823 let savedTime = value(getInteger(timeKey))
17391824 let availRes = (fraction((lastBlock.timestamp - savedTime), applyBonuses(landAssetId, pieces), DAYMILLIS) * pieces)
17401825 claimResInternal(addr, availRes, claimMode, landAssetId)
17411826 }
17421827
17431828
17441829 func upInfraCommon (shouldUseMat,caller,paymentAmount,landAssetId) = {
17451830 let addr = toString(caller)
17461831 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetId)
17471832 let pieces = numPiecesBySize(c._3[recLandSize])
17481833 let infraKey = keyInfraLevelByAssetId(c._2)
17491834 let curLevel = valueOrElse(getInteger(infraKey), 0)
17501835 if (if (!(KS_ALLOW_BIG_INFRA_MERGE))
17511836 then (curLevel >= 3)
17521837 else false)
17531838 then throw("Currently max infrastructure level = 3")
17541839 else {
17551840 let maxInfra = ((sqrt(pieces, 0, 0, DOWN) / 5) + 2)
17561841 let newLevel = (curLevel + 1)
17571842 if (if (KS_ALLOW_BIG_INFRA_MERGE)
17581843 then (newLevel > maxInfra)
17591844 else false)
17601845 then throw(("Currently max infrastructure level = " + toString(maxInfra)))
17611846 else {
17621847 let cost = fraction(InfraUpgradeCostSUsdt, (pieces * newLevel), SSIZE)
17631848 if (if (!(shouldUseMat))
17641849 then (paymentAmount != cost)
17651850 else false)
17661851 then throw(("Payment attached should be " + toString(cost)))
17671852 else {
17681853 let bpKey = keyBackpackByDuck(c._1)
17691854 let currentPack = getBackpack(bpKey)
17701855 let mList = split(currentPack[bpIdxMat], "_")
17711856 let matUsed = fraction(InfraUpgradeCostS, (pieces * newLevel), SSIZE)
17721857 let newMat = makeString(subtractMaterials(shouldUseMat, mList, matUsed), "_")
17731858 let claimResult = claimAll(addr, c._2, pieces, claimModeWhThenDuck)
17741859 let whData = claimResult._5
17751860 let oldVol = getWarehouseTotalVolume(whData[whIdxLevels])
17761861 let newVolData = makeString([split(whData[whIdxLevels], "_")[0], toString(newLevel)], "_")
17771862 let newVol = getWarehouseTotalVolume(newVolData)
17781863 let loft = split(whData[whIdxLOFT], "_")
17791864 let newLoftStr = makeString([loft[volLocked], loft[volOccupied], toString(((parseIntValue(loft[volFree]) + newVol) - oldVol)), toString(newVol)], "_")
17801865 $Tuple3(([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, matUsed)
17811866 }
17821867 }
17831868 }
17841869 }
17851870
17861871
17871872 func updateDuckStatsInternal (duckAssetId,deltaXP) = {
17881873 let lvlKey = keyDuckLevel(duckAssetId)
17891874 let xpKey = keyDuckXP(duckAssetId)
17901875 let xp = valueOrElse(getInteger(stakingContract, xpKey), 0)
17911876 let newXP = (xp + deltaXP)
17921877 let lvlPoints = levelUp(valueOrElse(getInteger(stakingContract, lvlKey), 0), newXP)
17931878 let keyPoints = keyDuckFreePoints(duckAssetId)
17941879 $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(keyPoints, (valueOrElse(getInteger(keyPoints), 0) + lvlPoints[1]))], newXP)
17951880 }
17961881
17971882
17981883 func updateAccStatsInternal (addr,deltaXP) = {
17991884 let lvlKey = keyUserLevel(addr)
18001885 let xpKey = keyUserXP(addr)
18011886 let xp = valueOrElse(getInteger(stakingContract, xpKey), 0)
18021887 let newXP = (xp + deltaXP)
18031888 let lvlPoints = levelUp(valueOrElse(getInteger(stakingContract, lvlKey), 0), newXP)
18041889 let keyPoints = keyUserFreePoints(addr)
18051890 $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(keyPoints, (valueOrElse(getInteger(keyPoints), 0) + lvlPoints[1]))], newXP)
18061891 }
18071892
18081893
18091894 func activateOnboardArt (addr) = {
18101895 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
18111896 let refByKey = keyAddressRefBy(addr)
18121897 let refBy = getString(refByKey)
18131898 if (!(isDefined(refBy)))
18141899 then throw("You are not eligible for ONBOARD artifact")
18151900 else {
18161901 let artKey = keyOnboardArtDuckActivatedBy(addr)
18171902 let artDuck = getString(artKey)
18181903 if (isDefined(artDuck))
18191904 then throw(("You already used your ONBOARD artifact on duck " + value(artDuck)))
18201905 else {
18211906 let duckActivatorKey = keyOnboardArtActivatedOnDuck(duckAssetId)
18221907 let duckActivator = getString(duckActivatorKey)
18231908 if (isDefined(duckActivator))
18241909 then throw(((("The duck " + duckAssetId) + " already got points from ONBOARD artifact from user ") + value(duckActivator)))
18251910 else ([StringEntry(artKey, duckAssetId), StringEntry(duckActivatorKey, addr)] ++ updateDuckStatsInternal(duckAssetId, xpOnboard)._1)
18261911 }
18271912 }
18281913 }
18291914
18301915
18311916 func activatePresaleArt (addr,landAssetIdIn) = {
18321917 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetIdIn)
18331918 let landAssetId = c._2
18341919 let pieces = numPiecesBySize(c._3[recLandSize])
18351920 let activationKey = keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)
18361921 if ((valueOrElse(getInteger(activationKey), 0) > 0))
18371922 then throw("Presale artifact is already activated")
18381923 else if ((parseIntValue(c._3[recLandNum]) > PRESALENUMLANDS))
18391924 then throw((((LANDPREFIX + " ") + landAssetId) + " is not eligible for presale artifact"))
18401925 else {
18411926 let claimResult = claimAll(addr, landAssetId, pieces, claimModeWhThenDuck)
18421927 (((claimResult._1 :+ IntegerEntry(activationKey, pieces)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":"))) :+ StringEntry(claimResult._4, makeString(claimResult._5, ":")))
18431928 }
18441929 }
18451930
18461931
18471932 func checkTournament (duckAssetId) = {
18481933 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
18491934 let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
18501935 let now = lastBlock.timestamp
18511936 let tData = getTourData(tournamentContract, lastId)
18521937 let static = tData[idxStatic]
18531938 let dynamic = tData[idxDynamic]
18541939 if ((curLocation[locIdxType] != "T"))
18551940 then false
18561941 else if (if (if ((parseIntValue(curLocation[locIdxContinent]) == lastId))
18571942 then (dynamic[tDynamicStatus] == "INPROGRESS")
18581943 else false)
18591944 then (parseIntValue(static[tStaticEnd]) > now)
18601945 else false)
18611946 then throw("Your duck is taking part in the tournament")
18621947 else asBoolean(invoke(this, "exitTournamentInternal", [duckAssetId], nil))
18631948 }
18641949
18651950
1951+func checkDelivery (duckAssetId) = if (!(KS_ALLOW_DELIVERY))
1952+ then false
1953+ else {
1954+ let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
1955+ let now = lastBlock.timestamp
1956+ if ((curLocation[locIdxType] != "D"))
1957+ then false
1958+ else {
1959+ let startTime = parseIntValue(curLocation[locIdxContinent])
1960+ let distance = parseIntValue(curLocation[locIdxId])
1961+ if (if ((now > (startTime + TEN_MINUTES_MILLIS)))
1962+ then (3 > distance)
1963+ else false)
1964+ then throw("Your duck is on delivery mission")
1965+ else asBoolean(invoke(this, "exitDeliveryInternal", [duckAssetId], nil))
1966+ }
1967+ }
1968+
1969+
1970+func exitDeliveryCommon (duckAssetId) = {
1971+ let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
1972+ let now = lastBlock.timestamp
1973+ let startTime = parseIntValue(curLocation[locIdxContinent])
1974+ let distance = parseIntValue(curLocation[locIdxId])
1975+ let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(duckAssetId)), "NFT duck is orphaned")
1976+ let healthKey = keyDuckHealth(duckAssetId)
1977+ let curHealth = getIntegerValue(healthKey)
1978+ let outcomeActions = if ((distance >= 3))
1979+ then {
1980+ let reward = invoke(economyContract, "sendDeliveryReward", [owner], nil)
1981+ if ((reward == reward))
1982+ then nil
1983+ else throw("Strict value is not equal to itself.")
1984+ }
1985+ else if ((now > (startTime + TEN_MINUTES_MILLIS)))
1986+ then throw("Your duck is still on delivery mission")
1987+ else {
1988+ let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
1989+ let unlock = invoke(economyContract, "updateDeliveryLocked", [(lockedTotal - MIN_USDT_FEE_DELIVERY)], nil)
1990+ if ((unlock == unlock))
1991+ then if ((0 >= curHealth))
1992+ then nil
1993+ else [IntegerEntry(keyDeliveryDelayByDuck(duckAssetId), (startTime + DAYMILLIS))]
1994+ else throw("Strict value is not equal to itself.")
1995+ }
1996+ let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
1997+ let savedLocation = getStringValue(keySavedLocation(duckAssetId))
1998+ $Tuple4(outcomeActions, [IntegerEntry(healthKey, savedHealth), StringEntry(keyDuckLocation(duckAssetId), savedLocation)], savedLocation, savedHealth)
1999+ }
2000+
2001+
18662002 func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,needMat) = {
18672003 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
18682004 if (checkTournament(duckAssetId))
18692005 then throw("mergeInternal_checkTournament")
1870- else {
1871- func checkMerge (acc,landAssetId) = {
1872- let asset = value(assetInfo(fromBase58String(landAssetId)))
1873- let timeKey = keyStakedTimeByAssetId(landAssetId)
1874- let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
1875- let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
1876- if ((owner != addr))
1877- then throw((LANDPREFIX + " is not yours"))
1878- else {
1879- let d = split(asset.description, "_")
1880- let continent = d[recContinent]
1881- if (if ((acc._3 != ""))
1882- then (acc._3 != continent)
1883- else false)
1884- then throw("Lands should be on the same continent to merge")
1885- else {
1886- let landSize = d[recLandSize]
1887- let sizesIn = acc._1
1888- let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
1889- let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
1890- let pieces = numPiecesBySize(landSize)
1891- let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
1892- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1893- let reqLevel = match landSize {
1894- case _ =>
1895- if (("S" == $match0))
1896- then 3
1897- else if (("M" == $match0))
1898- then 4
1899- else if (("L" == $match0))
1900- then 5
1901- else if (("XL" == $match0))
1902- then 6
1903- else throw("Only S, M, L, XL can merge")
1904- }
1905- if ((infraLevel != reqLevel))
1906- then throw("All lands should be maxed to merge")
1907- else {
1908- let landNum = d[recLandNum]
1909- let terrainCounts = countTerrains(d[recTerrains])
1910- let deltaTime = (lastBlock.timestamp - savedTime)
1911- if ((0 > deltaTime))
1912- then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
1913- else {
1914- let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
1915- let landIndex = (pieces / SSIZE)
1916- let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
1917- let props = updateProportionsInternal(acc._6, terrainCounts, landIndex, -1)
1918- let cProps = updateProportionsInternal(acc._10, terrainCounts, landIndex, -1)
1919- let sumTerrains = updateProportionsInternal(acc._9, terrainCounts, landIndex, 1)
1920- let lands = acc._7
1921- let idx = indexOf(lands, landAssetId)
1922- if (!(isDefined(idx)))
1923- then throw(("Your staked lands don't contain " + landAssetId))
1924- else {
1925- let customKey = keyLandAssetIdToCustomName(landAssetId)
1926- let customName = valueOrElse(getString(customKey), "")
1927- $Tuple10(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(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ Burn(fromBase58String(landAssetId), 1)) ++ (if ((customName != ""))
1928- then [DeleteEntry(keyLandCustomNameToAssetId(customName))]
1929- else nil)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces), sumTerrains, cProps)
1930- }
1931- }
1932- }
1933- }
1934- }
2006+ else if (checkDelivery(duckAssetId))
2007+ then throw("mergeInternal_checkDelivery")
2008+ else {
2009+ func checkMerge (acc,landAssetId) = {
2010+ let asset = value(assetInfo(fromBase58String(landAssetId)))
2011+ let timeKey = keyStakedTimeByAssetId(landAssetId)
2012+ let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
2013+ let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
2014+ if ((owner != addr))
2015+ then throw((LANDPREFIX + " is not yours"))
2016+ else {
2017+ let d = split(asset.description, "_")
2018+ let continent = d[recContinent]
2019+ if (if ((acc._3 != ""))
2020+ then (acc._3 != continent)
2021+ else false)
2022+ then throw("Lands should be on the same continent to merge")
2023+ else {
2024+ let landSize = d[recLandSize]
2025+ let sizesIn = acc._1
2026+ let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
2027+ let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
2028+ let pieces = numPiecesBySize(landSize)
2029+ let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
2030+ let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
2031+ let reqLevel = match landSize {
2032+ case _ =>
2033+ if (("S" == $match0))
2034+ then 3
2035+ else if (("M" == $match0))
2036+ then 4
2037+ else if (("L" == $match0))
2038+ then 5
2039+ else if (("XL" == $match0))
2040+ then 6
2041+ else throw("Only S, M, L, XL can merge")
2042+ }
2043+ if ((infraLevel != reqLevel))
2044+ then throw("All lands should be maxed to merge")
2045+ else {
2046+ let landNum = d[recLandNum]
2047+ let terrainCounts = countTerrains(d[recTerrains])
2048+ let deltaTime = (lastBlock.timestamp - savedTime)
2049+ if ((0 > deltaTime))
2050+ then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
2051+ else {
2052+ let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
2053+ let landIndex = (pieces / SSIZE)
2054+ let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
2055+ let props = updateProportionsInternal(acc._6, terrainCounts, landIndex, -1)
2056+ let cProps = updateProportionsInternal(acc._10, terrainCounts, landIndex, -1)
2057+ let sumTerrains = updateProportionsInternal(acc._9, terrainCounts, landIndex, 1)
2058+ let lands = acc._7
2059+ let idx = indexOf(lands, landAssetId)
2060+ if (!(isDefined(idx)))
2061+ then throw(("Your staked lands don't contain " + landAssetId))
2062+ else {
2063+ let customKey = keyLandAssetIdToCustomName(landAssetId)
2064+ let customName = valueOrElse(getString(customKey), "")
2065+ $Tuple10(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(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ Burn(fromBase58String(landAssetId), 1)) ++ (if ((customName != ""))
2066+ then [DeleteEntry(keyLandCustomNameToAssetId(customName))]
2067+ else nil)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces), sumTerrains, cProps)
2068+ }
2069+ }
2070+ }
2071+ }
2072+ }
2073+ }
2074+
2075+ let bpKey = keyBackpackByDuck(duckAssetId)
2076+ let currentPack = getBackpack(bpKey)
2077+ let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
2078+ let landsKey = keyStakedLandsByOwner(addr)
2079+ let landsStr = getString(landsKey)
2080+ let landsIn = if (isDefined(landsStr))
2081+ then split_51C(value(landsStr), "_")
2082+ else nil
2083+ let cont0 = split(value(assetInfo(fromBase58String(landAssetIds[0]))).description, "_")[recContinent]
2084+ let contProps = split(valueOrElse(getString(keyResTypesByContinent(cont0)), "0_0_0_0_0_0"), "_")
2085+ let r = {
2086+ let $l = landAssetIds
2087+ let $s = size($l)
2088+ let $acc0 = $Tuple10(formula, 0, "", currentPack[bpIdxRes], nil, propList, landsIn, 0, split("0_0_0_0_0_0", "_"), contProps)
2089+ func $f0_1 ($a,$i) = if (($i >= $s))
2090+ then $a
2091+ else checkMerge($a, $l[$i])
2092+
2093+ func $f0_2 ($a,$i) = if (($i >= $s))
2094+ then $a
2095+ else throw("List size exceeds 5")
2096+
2097+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
2098+ }
2099+ let continent = r._3
2100+ let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
2101+ let terrains = genTerrainsForMerge(r._9, (numPiecesBySize(newLandSize) / SSIZE))
2102+ let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
2103+ let newLandNum = toString(freeNum)
2104+ let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
2105+ let assetId = calculateAssetId(issue)
2106+ let newLandAssetId = toBase58String(assetId)
2107+ let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
2108+ let piecesKey = keyStakedPiecesByOwner(addr)
2109+ let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
2110+ $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
2111+ then StringEntry(landsKey, makeString_11C(r._7, "_"))
2112+ else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
2113+ then 0
2114+ 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(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), makeString(r._6, "_"))) :+ StringEntry(keyResTypesByContinent(continent), makeString(r._10, "_"))) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
19352115 }
1936-
1937- let bpKey = keyBackpackByDuck(duckAssetId)
1938- let currentPack = getBackpack(bpKey)
1939- let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
1940- let landsKey = keyStakedLandsByOwner(addr)
1941- let landsStr = getString(landsKey)
1942- let landsIn = if (isDefined(landsStr))
1943- then split_51C(value(landsStr), "_")
1944- else nil
1945- let cont0 = split(value(assetInfo(fromBase58String(landAssetIds[0]))).description, "_")[recContinent]
1946- let contProps = split(valueOrElse(getString(keyResTypesByContinent(cont0)), "0_0_0_0_0_0"), "_")
1947- let r = {
1948- let $l = landAssetIds
1949- let $s = size($l)
1950- let $acc0 = $Tuple10(formula, 0, "", currentPack[bpIdxRes], nil, propList, landsIn, 0, split("0_0_0_0_0_0", "_"), contProps)
1951- func $f0_1 ($a,$i) = if (($i >= $s))
1952- then $a
1953- else checkMerge($a, $l[$i])
1954-
1955- func $f0_2 ($a,$i) = if (($i >= $s))
1956- then $a
1957- else throw("List size exceeds 5")
1958-
1959- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
1960- }
1961- let continent = r._3
1962- let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
1963- let terrains = genTerrainsForMerge(r._9, (numPiecesBySize(newLandSize) / SSIZE))
1964- let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
1965- let newLandNum = toString(freeNum)
1966- let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
1967- let assetId = calculateAssetId(issue)
1968- let newLandAssetId = toBase58String(assetId)
1969- let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
1970- let piecesKey = keyStakedPiecesByOwner(addr)
1971- let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
1972- $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
1973- then StringEntry(landsKey, makeString_11C(r._7, "_"))
1974- else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
1975- then 0
1976- 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(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), makeString(r._6, "_"))) :+ StringEntry(keyResTypesByContinent(continent), makeString(r._10, "_"))) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
1977- }
19782116 }
19792117
19802118
19812119 func s2m (addr,landAssetIds) = mergeInternal("M", 3, "SSSS", addr, landAssetIds, 0)
19822120
19832121
19842122 func m2l (addr,landAssetIds) = mergeInternal("L", 4, "SMM", addr, landAssetIds, (InfraUpgradeCostS * 4))
19852123
19862124
19872125 func l2xl (addr,landAssetIds) = mergeInternal("XL", 5, "SSSML", addr, landAssetIds, (InfraUpgradeCostS * 47))
19882126
19892127
19902128 func xl2xxl (addr,landAssetIds) = mergeInternal("XXL", 6, "LXL", addr, landAssetIds, (InfraUpgradeCostS * 54))
19912129
19922130
19932131 func mergeCommon (addr,landAssetIds) = match size(landAssetIds) {
19942132 case _ =>
19952133 if ((4 == $match0))
19962134 then s2m(addr, landAssetIds)
19972135 else if ((3 == $match0))
19982136 then m2l(addr, landAssetIds)
19992137 else if ((5 == $match0))
20002138 then l2xl(addr, landAssetIds)
20012139 else if ((2 == $match0))
20022140 then xl2xxl(addr, landAssetIds)
20032141 else throw("Unknown merge")
20042142 }
20052143
20062144
20072145 func prolog (i) = if (if ((i.originCaller != restContract))
20082146 then valueOrElse(getBoolean(keyBlocked()), false)
20092147 else false)
20102148 then throw("Contracts are under maintenance")
2011- else StringEntry(keyLastTxIdByUser(toString(i.originCaller)), toBase58String(i.transactionId))
2149+ else {
2150+ let userAddr = toString(i.originCaller)
2151+ let duck = getString(keyStakedDuckByOwner(userAddr))
2152+ ((if (if (KS_ALLOW_DELIVERY)
2153+ then isDefined(duck)
2154+ else false)
2155+ then {
2156+ let duckAssetId = value(duck)
2157+ let locKey = keyDuckLocation(duckAssetId)
2158+ let loc = split(valueOrElse(getString(locKey), DEFAULTLOCATION), "_")
2159+ let startTime = parseIntValue(loc[locIdxContinent])
2160+ if (if ((loc[locIdxType] != "D"))
2161+ then true
2162+ else (lastBlock.timestamp > (startTime + TEN_MINUTES_MILLIS)))
2163+ then nil
2164+ else {
2165+ let healthKey = keyDuckHealth(duckAssetId)
2166+ if ((parseIntValue(loc[locIdxId]) >= 3))
2167+ then {
2168+ let reward = invoke(economyContract, "sendDeliveryReward", [userAddr], nil)
2169+ if ((reward == reward))
2170+ then nil
2171+ else throw("Strict value is not equal to itself.")
2172+ }
2173+ else (({
2174+ let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
2175+ let unlock = invoke(economyContract, "updateDeliveryLocked", [(lockedTotal - MIN_USDT_FEE_DELIVERY)], nil)
2176+ if ((unlock == unlock))
2177+ then if ((0 >= getIntegerValue(healthKey)))
2178+ then nil
2179+ else {
2180+ let punishment = invoke(this, "saveInteger", [keyDeliveryDelayByDuck(duckAssetId), (startTime + DAYMILLIS)], nil)
2181+ if ((punishment == punishment))
2182+ then nil
2183+ else throw("Strict value is not equal to itself.")
2184+ }
2185+ else throw("Strict value is not equal to itself.")
2186+ } :+ IntegerEntry(healthKey, getIntegerValue(keySavedHealth(duckAssetId)))) :+ StringEntry(locKey, getStringValue(keySavedLocation(duckAssetId))))
2187+ }
2188+ }
2189+ else nil) :+ StringEntry(keyLastTxIdByUser(userAddr), toBase58String(i.transactionId)))
2190+ }
2191+
2192+
2193+func prologFlight (i) = if (if ((i.originCaller != restContract))
2194+ then valueOrElse(getBoolean(keyBlocked()), false)
2195+ else false)
2196+ then throw("Contracts are under maintenance")
2197+ else [StringEntry(keyLastTxIdByUser(toString(i.originCaller)), toBase58String(i.transactionId))]
20122198
20132199
20142200 @Callable(i)
20152201 func constructorV1 (restAddr) = if ((i.caller != this))
20162202 then throw("Permission denied")
20172203 else [StringEntry(keyRestAddress(), restAddr)]
20182204
20192205
20202206
20212207 @Callable(i)
2208+func saveInteger (key,amount) = if ((i.caller != this))
2209+ then throw("saveInteger is not public method")
2210+ else [IntegerEntry(key, amount)]
2211+
2212+
2213+
2214+@Callable(i)
20222215 func setBlocked (isBlocked) = if ((i.caller != this))
20232216 then throw("permission denied")
20242217 else [BooleanEntry(keyBlocked(), isBlocked)]
20252218
20262219
20272220
20282221 @Callable(i)
20292222 func stakeLand () = {
2030- let prologAction = prolog(i)
2223+ let prologActions = prolog(i)
20312224 if ((size(i.payments) != 1))
20322225 then throw("Exactly one payment required")
20332226 else {
20342227 let pmt = value(i.payments[0])
20352228 let assetId = value(pmt.assetId)
20362229 let address = toString(i.caller)
20372230 if ((pmt.amount != 1))
20382231 then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
20392232 else {
20402233 let asset = value(assetInfo(assetId))
20412234 if ((asset.issuer != this))
20422235 then throw("Unknown issuer of token")
20432236 else if (!(contains(asset.name, LANDPREFIX)))
20442237 then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
20452238 else {
20462239 let landNumSize = drop(asset.name, 4)
20472240 let landNum = if (contains(landNumSize, "XXL"))
20482241 then dropRight(landNumSize, 3)
20492242 else if (contains(landNumSize, "XL"))
20502243 then dropRight(landNumSize, 2)
20512244 else dropRight(landNumSize, 1)
20522245 if (!(isDefined(parseInt(landNum))))
20532246 then throw(("Cannot parse land number from " + asset.name))
20542247 else {
20552248 let landAssetId = toBase58String(assetId)
20562249 let timeKey = keyStakedTimeByAssetId(landAssetId)
20572250 if (isDefined(getInteger(timeKey)))
20582251 then throw((("NFT " + asset.name) + " is already staked"))
20592252 else {
20602253 let d = split(asset.description, "_")
20612254 let terrainCounts = countTerrains(d[recTerrains])
20622255 let pieces = numPiecesBySize(d[recLandSize])
20632256 let landIndex = (pieces / SSIZE)
20642257 let props = updateProportions(terrainCounts, landIndex, 1)
20652258 let resByContKey = keyResTypesByContinent(d[recContinent])
20662259 let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
20672260 let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, 1), "_")
20682261 let landsKey = keyStakedLandsByOwner(address)
20692262 let landsStr = getString(landsKey)
20702263 let lands = if (isDefined(landsStr))
20712264 then split_51C(value(landsStr), "_")
20722265 else nil
20732266 if (containsElement(lands, landAssetId))
20742267 then throw(("Your staked lands already contain " + landAssetId))
20752268 else if ((size(lands) >= MAX_LANDS_STAKED_BY_USER))
20762269 then throw((("Your already staked max (" + toString(MAX_LANDS_STAKED_BY_USER)) + ") lands"))
20772270 else {
20782271 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
20792272 let piecesKey = keyStakedPiecesByOwner(address)
20802273 let oldPieces = valueOrElse(getInteger(piecesKey), 0)
20812274 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
2082- $Tuple2([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address), lastBlock.timestamp), StringEntry(landsKey, makeString_11C((lands :+ landAssetId), "_")), IntegerEntry(piecesKey, (oldPieces + pieces)), StringEntry(keyLandAssetIdToOwner(landAssetId), address), StringEntry(keyLandNumToOwner(landNum), address), IntegerEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, address), infraLevel), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps), prologAction], wlgResult)
2275+ $Tuple2(([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address), lastBlock.timestamp), StringEntry(landsKey, makeString_11C((lands :+ landAssetId), "_")), IntegerEntry(piecesKey, (oldPieces + pieces)), StringEntry(keyLandAssetIdToOwner(landAssetId), address), StringEntry(keyLandNumToOwner(landNum), address), IntegerEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, address), infraLevel), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps)] ++ prologActions), wlgResult)
20832276 }
20842277 }
20852278 }
20862279 }
20872280 }
20882281 }
20892282 }
20902283
20912284
20922285
20932286 @Callable(i)
20942287 func unstakeLand (landAssetIdIn) = {
2095- let prologAction = prolog(i)
2288+ let prologActions = prolog(i)
20962289 if ((size(i.payments) != 0))
20972290 then throw("No payments required")
20982291 else {
20992292 let addr = toString(i.caller)
21002293 let c = checkClaimConditions(addr, claimModeDuck, landAssetIdIn)
21012294 let landAssetId = c._2
21022295 let d = c._3
21032296 let landsKey = keyStakedLandsByOwner(addr)
21042297 let terrainCounts = countTerrains(d[recTerrains])
21052298 let pieces = numPiecesBySize(d[recLandSize])
21062299 let landIndex = (pieces / SSIZE)
21072300 let props = updateProportions(terrainCounts, landIndex, -1)
21082301 let resByContKey = keyResTypesByContinent(d[recContinent])
21092302 let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
21102303 let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, -1), "_")
21112304 let claimResult = claimAll(addr, landAssetId, pieces, claimModeDuck)
21122305 let lands = split_51C(valueOrElse(getString(landsKey), ""), "_")
21132306 let idx = indexOf(lands, landAssetId)
21142307 if (!(isDefined(idx)))
21152308 then throw(("Your staked lands don't contain " + landAssetId))
21162309 else {
21172310 let now = lastBlock.timestamp
21182311 let govReleaseTime = valueOrElse(getInteger(govContract, keyUserGwlReleaseTime(addr)), 0)
21192312 if ((govReleaseTime >= now))
21202313 then throw(("Your gWL are taking part in voting, cannot unstake until " + toString(govReleaseTime)))
21212314 else {
21222315 let arbReleaseTime = (valueOrElse(getInteger(wlgContract, keyLastArbTimeByUser(addr)), 0) + arbitrageDelay)
21232316 if ((arbReleaseTime > now))
21242317 then throw(("Your staked lands took part in arbitrage, cannot unstake until " + toString(arbReleaseTime)))
21252318 else {
21262319 let piecesKey = keyStakedPiecesByOwner(addr)
21272320 let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
21282321 let newPieces = if ((pieces > stakedPieces))
21292322 then 0
21302323 else (stakedPieces - pieces)
21312324 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr], nil)
2132- $Tuple2([ScriptTransfer(i.caller, 1, fromBase58String(landAssetId)), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr)), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps), StringEntry(claimResult._2, makeString(claimResult._3, ":")), if ((size(lands) > 1))
2325+ $Tuple2(([ScriptTransfer(i.caller, 1, fromBase58String(landAssetId)), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr)), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps), StringEntry(claimResult._2, makeString(claimResult._3, ":")), if ((size(lands) > 1))
21332326 then StringEntry(landsKey, makeString_11C(removeByIndex(lands, value(idx)), "_"))
2134- else DeleteEntry(landsKey), IntegerEntry(piecesKey, newPieces), prologAction], wlgResult)
2327+ else DeleteEntry(landsKey), IntegerEntry(piecesKey, newPieces)] ++ prologActions), wlgResult)
21352328 }
21362329 }
21372330 }
21382331 }
21392332 }
21402333
21412334
21422335
21432336 @Callable(i)
21442337 func stakeDuck () = {
2145- let prologAction = prolog(i)
2338+ let prologActions = prolog(i)
21462339 if ((size(i.payments) != 1))
21472340 then throw("Exactly one payment required")
21482341 else {
21492342 let pmt = value(i.payments[0])
21502343 let assetId = value(pmt.assetId)
21512344 let address = toString(i.caller)
21522345 if ((pmt.amount != 1))
21532346 then throw((("NFT " + DUCKPREFIX) + " token should be attached as payment"))
21542347 else {
21552348 let asset = value(assetInfo(assetId))
21562349 if (if ((asset.issuer != incubatorAddr))
21572350 then (asset.issuer != breederAddr)
21582351 else false)
21592352 then throw((("Unknown issuer of " + DUCKPREFIX) + " token"))
21602353 else if (!(contains(asset.name, DUCKPREFIX)))
21612354 then throw((("Only NFT " + DUCKPREFIX) + " tokens are accepted"))
21622355 else {
21632356 let assetIdStr = toBase58String(assetId)
21642357 let timeKey = keyStakedTimeByAssetId(assetIdStr)
21652358 if (isDefined(getInteger(timeKey)))
21662359 then throw((("NFT " + asset.name) + " is already staked"))
21672360 else if (isDefined(getString(keyStakedDuckByOwner(address))))
21682361 then throw(("You already staked one duck: " + asset.name))
2169- else if (checkTournament(assetIdStr))
2170- then throw("stakeDuck_checkTournament")
2171- else {
2172- let locKey = keyDuckLocation(assetIdStr)
2173- let location = getString(locKey)
2174- let bpKey = keyBackpackByDuck(assetIdStr)
2175- let backpack = getString(bpKey)
2176- let keyHealth = keyDuckHealth(assetIdStr)
2177- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2178- let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
2179- ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
2362+ else {
2363+ let locKey = keyDuckLocation(assetIdStr)
2364+ let location = getString(locKey)
2365+ let bpKey = keyBackpackByDuck(assetIdStr)
2366+ let backpack = getString(bpKey)
2367+ let keyHealth = keyDuckHealth(assetIdStr)
2368+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2369+ let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
2370+ ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
2371+ then nil
2372+ else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
21802373 then nil
2181- else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
2182- then nil
2183- else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyHealth, curHealth)) :+ prologAction)))))
2184- }
2374+ else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyHealth, curHealth)) ++ prologActions)))))
2375+ }
21852376 }
21862377 }
21872378 }
21882379 }
21892380
21902381
21912382
21922383 @Callable(i)
21932384 func unstakeDuck (assetIdStr) = {
2194- let prologAction = prolog(i)
2385+ let prologActions = prolog(i)
21952386 if ((size(i.payments) != 0))
21962387 then throw("No payments required")
21972388 else {
21982389 let assetId = fromBase58String(assetIdStr)
21992390 let address = toString(i.caller)
22002391 let asset = value(assetInfo(assetId))
22012392 let timeKey = keyStakedTimeByAssetId(assetIdStr)
22022393 if (!(isDefined(getInteger(timeKey))))
22032394 then throw((("NFT " + asset.name) + " is not staked"))
22042395 else if (!(isDefined(getString(keyStakedDuckByOwner(address)))))
22052396 then throw((("The duck " + asset.name) + " is not staked"))
22062397 else {
22072398 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetIdStr)), (("NFT " + asset.name) + " is orphaned"))
22082399 if ((owner != address))
22092400 then throw("Staked NFT is not yours")
22102401 else if (checkTournament(assetIdStr))
22112402 then throw("unstakeDuck_checkTournament")
2212- else {
2213- let keyHealth = keyDuckHealth(assetIdStr)
2214- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2215- let health = valueOrElse(getInteger(keyHealth), maxHP)
2216- if ((maxHP > health))
2217- then throw((("Please heal your duck to " + toString(maxHP)) + "hp before unstaking"))
2218- 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]
2219- }
2403+ else if (checkDelivery(assetIdStr))
2404+ then throw("unstakeDuck_checkDelivery")
2405+ else {
2406+ let keyHealth = keyDuckHealth(assetIdStr)
2407+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2408+ let health = valueOrElse(getInteger(keyHealth), maxHP)
2409+ if ((maxHP > health))
2410+ then throw((("Please heal your duck to " + toString(maxHP)) + "hp before unstaking"))
2411+ else ([ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyHealth), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address))] ++ prologActions)
2412+ }
22202413 }
22212414 }
22222415 }
22232416
22242417
22252418
22262419 @Callable(i)
22272420 func claimRes (amount,landAssetIdStr) = {
2228- let prologAction = prolog(i)
2421+ let prologActions = prolog(i)
22292422 if ((size(i.payments) != 0))
22302423 then throw("No payments required")
22312424 else {
22322425 let addr = toString(i.originCaller)
22332426 let result = claimResInternal(addr, amount, claimModeDuck, landAssetIdStr)
22342427 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
2235- $Tuple2(((((result._1 ++ updateDuckStatsInternal(duckAssetId, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) :+ prologAction), result._3[bpIdxRes])
2428+ $Tuple2(((((result._1 ++ updateDuckStatsInternal(duckAssetId, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) ++ prologActions), result._3[bpIdxRes])
22362429 }
22372430 }
22382431
22392432
22402433
22412434 @Callable(i)
22422435 func claimResToWH (amount,landAssetIdStr) = {
2243- let prologAction = prolog(i)
2436+ let prologActions = prolog(i)
22442437 if ((size(i.payments) != 0))
22452438 then throw("No payments required")
22462439 else {
22472440 let addr = toString(i.originCaller)
22482441 let result = claimResInternal(addr, amount, claimModeWh, landAssetIdStr)
2249- $Tuple2(((((result._1 ++ updateAccStatsInternal(addr, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) :+ prologAction), result._5[whIdxRes])
2442+ $Tuple2(((((result._1 ++ updateAccStatsInternal(addr, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) ++ prologActions), result._5[whIdxRes])
22502443 }
22512444 }
22522445
22532446
22542447
22552448 @Callable(i)
22562449 func flight (message,sig) = {
2257- let prologAction = prolog(i)
2450+ let prologActions = prologFlight(i)
22582451 if ((size(i.payments) != 0))
22592452 then throw("No payments required")
22602453 else {
22612454 let userAddr = toString(i.caller)
22622455 let f = flightCommon(userAddr, message, sig)
22632456 let newHP = f._1
22642457 let duckAssetId = f._2
22652458 let locKey = keyDuckLocation(duckAssetId)
22662459 let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
22672460 let newLocation = f._4
22682461 if ((newLocation == curLocation))
22692462 then throw("You can't fly to the same location")
22702463 else {
22712464 let newLoc = split(newLocation, "_")
22722465 let isTour = (newLoc[locIdxType] == "T")
2466+ let isDeliv = (newLoc[locIdxType] == "D")
22732467 let eqKey = keyDuckEquipment(duckAssetId)
22742468 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2275- let $t06598166078 = subtractEquipment(currentEq, f._5)
2276- let newEq = $t06598166078._1
2277- let shouldZeroBuffs = $t06598166078._2
2278- let locToSave = if (!(isInTournament(tournamentContract, curLocation)))
2279- then if (isTour)
2280- then throw(((("Cheat attempt: oldLoc=" + curLocation) + ", newLoc=") + newLocation))
2469+ let $t07021270309 = subtractEquipment(currentEq, f._5)
2470+ let newEq = $t07021270309._1
2471+ let shouldZeroBuffs = $t07021270309._2
2472+ let $t07031273351 = if (notOnMission(tournamentContract, curLocation))
2473+ then if (!(isUsualLocation(newLocation)))
2474+ then cheatAttempt(curLocation, newLocation)
22812475 else if ((newHP > 0))
2282- then newLocation
2283- else curLocation
2284- else if (!(isInTournament(tournamentContract, newLocation)))
2285- then throw("Your duck is taking part in the tournament")
2286- else {
2287- let score = parseIntValue(newLoc[locIdxId])
2288- let curLoc = split(curLocation, "_")
2289- let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
2290- if ((score != (parseIntValue(curLoc[locIdxId]) + 1)))
2291- then throw(((("Cheat attempt: oldLoc=" + curLocation) + ", newLoc=") + newLocation))
2292- else if ((newHP > 0))
2293- then {
2294- let localBest = valueOrElse(getInteger(tournamentContract, keyBestResultByTourAndDuck(lastId, duckAssetId)), 0)
2295- let updLocal = if ((score > localBest))
2296- then invoke(tournamentContract, "saveDuckResult", [duckAssetId, score], nil)
2297- else unit
2298- if ((updLocal == updLocal))
2299- then newLocation
2300- else throw("Strict value is not equal to itself.")
2476+ then $Tuple2(newLocation, newHP)
2477+ else $Tuple2(curLocation, 0)
2478+ else if (isInTournament(tournamentContract, curLocation))
2479+ then if (!(isInTournament(tournamentContract, newLocation)))
2480+ then throw("Your duck is taking part in the tournament")
2481+ else {
2482+ let score = parseIntValue(newLoc[locIdxId])
2483+ let curLoc = split(curLocation, "_")
2484+ let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
2485+ if ((score != (parseIntValue(curLoc[locIdxId]) + 1)))
2486+ then cheatAttempt(curLocation, newLocation)
2487+ else if ((newHP > 0))
2488+ then {
2489+ let localBest = valueOrElse(getInteger(tournamentContract, keyBestResultByTourAndDuck(lastId, duckAssetId)), 0)
2490+ let updLocal = if ((score > localBest))
2491+ then invoke(tournamentContract, "saveDuckResult", [duckAssetId, score], nil)
2492+ else unit
2493+ if ((updLocal == updLocal))
2494+ then $Tuple2(newLocation, newHP)
2495+ else throw("Strict value is not equal to itself.")
2496+ }
2497+ else $Tuple2(curLocation, 0)
2498+ }
2499+ else if (!(isInDelivery(curLocation)))
2500+ then {
2501+ let locHealth = asStringIntTuple(invoke(this, "autoExitDelivery", [duckAssetId], nil))
2502+ if ((locHealth == locHealth))
2503+ then if (isDeliv)
2504+ then locHealth
2505+ else if ((newHP > 0))
2506+ then $Tuple2(newLocation, newHP)
2507+ else $Tuple2(locHealth._1, 0)
2508+ else throw("Strict value is not equal to itself.")
2509+ }
2510+ else if (!(isDeliv))
2511+ then throw("Your duck is taking part in delivery")
2512+ else if (!(isInDelivery(newLocation)))
2513+ then cheatAttempt(curLocation, newLocation)
2514+ else {
2515+ let score = parseIntValue(newLoc[locIdxId])
2516+ let curLoc = split(curLocation, "_")
2517+ if ((score != (parseIntValue(curLoc[locIdxId]) + 1)))
2518+ then cheatAttempt(curLocation, newLocation)
2519+ else if (if ((newHP > 0))
2520+ then (3 > score)
2521+ else false)
2522+ then $Tuple2(newLocation, newHP)
2523+ else {
2524+ let locHealth = asStringIntTuple(invoke(this, "autoExitDelivery", [duckAssetId], nil))
2525+ if ((locHealth == locHealth))
2526+ then locHealth
2527+ else throw("Strict value is not equal to itself.")
2528+ }
23012529 }
2302- else curLocation
2303- }
2304- $Tuple2(([StringEntry(locKey, locToSave), StringEntry(eqKey, newEq), IntegerEntry(keyDuckHealth(duckAssetId), newHP), prologAction] ++ (if (shouldZeroBuffs)
2530+ let locToSave = $t07031273351._1
2531+ let hpToSave = $t07031273351._2
2532+ $Tuple2(((([StringEntry(locKey, locToSave), StringEntry(eqKey, newEq), IntegerEntry(keyDuckHealth(duckAssetId), newHP)] ++ prologActions) ++ (if (shouldZeroBuffs)
23052533 then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
2306- else (nil ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
2307- then xpSuccessFlight
2308- else xpFailFlight)._1))), f._3)
2534+ else nil)) ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
2535+ then xpSuccessFlight
2536+ else xpFailFlight)._1), f._3)
23092537 }
23102538 }
23112539 }
23122540
23132541
23142542
23152543 @Callable(i)
23162544 func heal (quantityL1,quantityL2,quantityL3) = {
2317- let prologAction = prolog(i)
2545+ let prologActions = prolog(i)
23182546 if (if (if ((0 > quantityL1))
23192547 then true
23202548 else (0 > quantityL2))
23212549 then true
23222550 else (0 > quantityL3))
23232551 then throw("Quantity cannot be negative")
23242552 else {
23252553 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
23262554 if (checkTournament(duckAssetId))
23272555 then throw("heal_checkTournament")
2328- else {
2329- let qts = [quantityL1, quantityL2, quantityL3]
2330- let keyHealth = keyDuckHealth(duckAssetId)
2331- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2332- let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2333- if ((oldHealth >= maxHP))
2334- then throw((("HP should be < " + toString(maxHP)) + " to heal"))
2335- else {
2336- let bpKey = keyBackpackByDuck(duckAssetId)
2337- let currentPack = getBackpack(bpKey)
2338- let prodList = if ((currentPack[bpIdxProd] == ""))
2339- then nil
2340- else split_4C(currentPack[bpIdxProd], "_")
2341- func iterateProd (acc,recipe) = {
2342- let n = acc._2
2343- let x = if ((size(prodList) > n))
2344- then parseIntValue(prodList[n])
2345- else 0
2346- if ((3 > n))
2347- then {
2348- let q = qts[n]
2349- if ((q > x))
2350- then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
2351- else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (parseIntValue(split(recipe, "_")[rIdxEffect]) * q)))
2352- }
2353- else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
2556+ else if (checkDelivery(duckAssetId))
2557+ then throw("heal_checkDelivery")
2558+ else {
2559+ let qts = [quantityL1, quantityL2, quantityL3]
2560+ let keyHealth = keyDuckHealth(duckAssetId)
2561+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2562+ let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2563+ if ((oldHealth >= maxHP))
2564+ then throw((("HP should be < " + toString(maxHP)) + " to heal"))
2565+ else {
2566+ let bpKey = keyBackpackByDuck(duckAssetId)
2567+ let currentPack = getBackpack(bpKey)
2568+ let prodList = if ((currentPack[bpIdxProd] == ""))
2569+ then nil
2570+ else split_4C(currentPack[bpIdxProd], "_")
2571+ func iterateProd (acc,recipe) = {
2572+ let n = acc._2
2573+ let x = if ((size(prodList) > n))
2574+ then parseIntValue(prodList[n])
2575+ else 0
2576+ if ((3 > n))
2577+ then {
2578+ let q = qts[n]
2579+ if ((q > x))
2580+ then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
2581+ else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (parseIntValue(split(recipe, "_")[rIdxEffect]) * q)))
2582+ }
2583+ else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
2584+ }
2585+
2586+ let result = {
2587+ let $l = productionMatrix
2588+ let $s = size($l)
2589+ let $acc0 = $Tuple3(nil, 0, 0)
2590+ func $f0_1 ($a,$i) = if (($i >= $s))
2591+ then $a
2592+ else iterateProd($a, $l[$i])
2593+
2594+ func $f0_2 ($a,$i) = if (($i >= $s))
2595+ then $a
2596+ else throw("List size exceeds 50")
2597+
2598+ $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)
2599+ }
2600+ let newHealth = min([maxHP, (oldHealth + result._3)])
2601+ $Tuple2((([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":"))] ++ prologActions) ++ updateDuckStatsInternal(duckAssetId, (xpHeal * ((quantityL1 + quantityL2) + quantityL3)))._1), newHealth)
23542602 }
2355-
2356- let result = {
2357- let $l = productionMatrix
2358- let $s = size($l)
2359- let $acc0 = $Tuple3(nil, 0, 0)
2360- func $f0_1 ($a,$i) = if (($i >= $s))
2361- then $a
2362- else iterateProd($a, $l[$i])
2363-
2364- func $f0_2 ($a,$i) = if (($i >= $s))
2365- then $a
2366- else throw("List size exceeds 50")
2367-
2368- $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)
2369- }
2370- let newHealth = min([maxHP, (oldHealth + result._3)])
2371- $Tuple2(([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":")), prologAction] ++ updateDuckStatsInternal(duckAssetId, (xpHeal * ((quantityL1 + quantityL2) + quantityL3)))._1), newHealth)
2372- }
2373- }
2603+ }
23742604 }
23752605 }
23762606
23772607
23782608
23792609 @Callable(i)
23802610 func healES () = {
2381- let prologAction = prolog(i)
2611+ let prologActions = prolog(i)
23822612 if ((size(i.payments) != 1))
23832613 then throw("Exactly one payment required")
23842614 else {
23852615 let pmt = value(i.payments[0])
23862616 if ((pmt.assetId != usdtAssetId))
23872617 then throw("Allowed USDT payment only!")
23882618 else {
23892619 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
23902620 if (checkTournament(duckAssetId))
23912621 then throw("healES_checkTournament")
2392- else {
2393- let keyHealth = keyDuckHealth(duckAssetId)
2394- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2395- let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2396- if ((oldHealth > 0))
2397- then throw("HP should be 0 to call Emergency Service")
2398- else {
2399- let bpKey = keyBackpackByDuck(duckAssetId)
2400- let currentPack = getBackpack(bpKey)
2401- let prodList = if ((currentPack[bpIdxProd] == ""))
2402- then nil
2403- else split_4C(currentPack[bpIdxProd], "_")
2404- let medKitAmount1 = if ((size(prodList) > 0))
2405- then parseIntValue(prodList[0])
2406- else 0
2407- let medKitAmount2 = if ((size(prodList) > 1))
2408- then parseIntValue(prodList[1])
2409- else 0
2410- let medKitAmount3 = if ((size(prodList) > 2))
2411- then parseIntValue(prodList[2])
2412- else 0
2413- if (if (if ((medKitAmount1 > 0))
2414- then true
2415- else (medKitAmount2 > 0))
2416- then true
2417- else (medKitAmount3 > 0))
2418- then throw("You have to use own Medical Kit")
2419- else {
2420- let existStr = getString(economyContract, keyEsWarehouse())
2421- let existAmounts = if (isDefined(existStr))
2422- then split_4C(value(existStr), "_")
2423- else nil
2424- let existAmount = if ((size(existAmounts) > 0))
2425- then parseIntValue(existAmounts[0])
2426- else 0
2427- if ((0 >= existAmount))
2428- then throw("There are no Medical Kits L1 at Emergency Service storage")
2429- else {
2430- let newHealth = (oldHealth + parseIntValue(split(productionMatrix[0], "_")[rIdxEffect]))
2431- let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
2432- let recipe = split(productionMatrix[0], "_")
2433- let totalMat = getRecipeMaterials(recipe)
2434- let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
2435- if ((pmt.amount != sellPrice))
2436- then throw(("Payment attached should be " + toString(sellPrice)))
2437- else {
2438- let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
2439- $Tuple2(([IntegerEntry(keyHealth, newHealth), prologAction] ++ updateDuckStatsInternal(duckAssetId, xpCallES)._1), result)
2440- }
2441- }
2442- }
2443- }
2444- }
2622+ else if (checkDelivery(duckAssetId))
2623+ then throw("healES_checkDelivery")
2624+ else {
2625+ let keyHealth = keyDuckHealth(duckAssetId)
2626+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2627+ let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2628+ if ((oldHealth > 0))
2629+ then throw("HP should be 0 to call Emergency Service")
2630+ else {
2631+ let bpKey = keyBackpackByDuck(duckAssetId)
2632+ let currentPack = getBackpack(bpKey)
2633+ let prodList = if ((currentPack[bpIdxProd] == ""))
2634+ then nil
2635+ else split_4C(currentPack[bpIdxProd], "_")
2636+ let medKitAmount1 = if ((size(prodList) > 0))
2637+ then parseIntValue(prodList[0])
2638+ else 0
2639+ let medKitAmount2 = if ((size(prodList) > 1))
2640+ then parseIntValue(prodList[1])
2641+ else 0
2642+ let medKitAmount3 = if ((size(prodList) > 2))
2643+ then parseIntValue(prodList[2])
2644+ else 0
2645+ if (if (if ((medKitAmount1 > 0))
2646+ then true
2647+ else (medKitAmount2 > 0))
2648+ then true
2649+ else (medKitAmount3 > 0))
2650+ then throw("You have to use own Medical Kit")
2651+ else {
2652+ let existStr = getString(economyContract, keyEsWarehouse())
2653+ let existAmounts = if (isDefined(existStr))
2654+ then split_4C(value(existStr), "_")
2655+ else nil
2656+ let existAmount = if ((size(existAmounts) > 0))
2657+ then parseIntValue(existAmounts[0])
2658+ else 0
2659+ if ((0 >= existAmount))
2660+ then throw("There are no Medical Kits L1 at Emergency Service storage")
2661+ else {
2662+ let newHealth = (oldHealth + parseIntValue(split(productionMatrix[0], "_")[rIdxEffect]))
2663+ let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
2664+ let recipe = split(productionMatrix[0], "_")
2665+ let totalMat = getRecipeMaterials(recipe)
2666+ let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
2667+ if ((pmt.amount != sellPrice))
2668+ then throw(("Payment attached should be " + toString(sellPrice)))
2669+ else {
2670+ let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
2671+ $Tuple2(((prologActions :+ IntegerEntry(keyHealth, newHealth)) ++ updateDuckStatsInternal(duckAssetId, xpCallES)._1), result)
2672+ }
2673+ }
2674+ }
2675+ }
2676+ }
24452677 }
24462678 }
24472679 }
24482680
24492681
24502682
24512683 @Callable(i)
24522684 func updateBackpack (duckAssetId,newPack) = if ((i.caller != economyContract))
24532685 then throw("permission denied")
24542686 else $Tuple2([StringEntry(keyBackpackByDuck(duckAssetId), newPack)], newPack)
24552687
24562688
24572689
24582690 @Callable(i)
24592691 func commitForRandom () = {
2460- let prologAction = prolog(i)
2692+ let prologActions = prolog(i)
24612693 let finishBlock = (height + randomDelay)
24622694 let addr = toString(i.caller)
2463- $Tuple2(([IntegerEntry(keyCommit(addr), finishBlock)] :+ prologAction), finishBlock)
2464- }
2465-
2466-
2467-
2468-@Callable(i)
2469-func awardSLand (address) = if ((i.caller != tournamentContract))
2470- then throw("Access denied")
2471- else if ((size(i.payments) != 0))
2472- then throw("No payments required")
2473- else {
2474- let result = expeditionInternal(addressFromStringValue(address), i.transactionId)
2475- $Tuple2(result._1, result._2._1)
2476- }
2695+ $Tuple2(([IntegerEntry(keyCommit(addr), finishBlock)] ++ prologActions), finishBlock)
2696+ }
24772697
24782698
24792699
24802700 @Callable(i)
24812701 func buySLand () = {
2482- let prologAction = prolog(i)
2702+ let prologActions = prolog(i)
24832703 if ((size(i.payments) != 1))
24842704 then throw("Exactly one payment required")
24852705 else {
24862706 let pmt = value(i.payments[0])
24872707 if ((pmt.assetId != usdtAssetId))
24882708 then throw("Allowed USDT payment only!")
24892709 else if ((pmt.amount != EXPUSDT))
24902710 then throw(("Payment attached should be " + toString(EXPUSDT)))
24912711 else {
24922712 let result = expeditionInternal(i.caller, i.transactionId)
2493- $Tuple2((((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) :+ prologAction), result._2._1)
2713+ let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
2714+ $Tuple2((((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) ++ prologActions), $Tuple2(result._2._1, acresResult))
24942715 }
24952716 }
24962717 }
24972718
24982719
24992720
25002721 @Callable(i)
25012722 func expedition (message,sig) = {
2502- let prologAction = prolog(i)
2723+ let prologActions = prolog(i)
25032724 if ((size(i.payments) != 0))
25042725 then throw("No payments required")
25052726 else {
25062727 let userAddr = toString(i.caller)
25072728 let f = flightCommon(userAddr, message, sig)
25082729 let duckAssetId = f._2
25092730 let keyHealth = keyDuckHealth(duckAssetId)
25102731 let bpKey = keyBackpackByDuck(duckAssetId)
25112732 let currentPack = getBackpack(bpKey)
25122733 let mList = split(currentPack[bpIdxMat], "_")
25132734 let newMat = makeString(subtractMaterials(true, mList, EXPMATERIALS), "_")
25142735 let eqKey = keyDuckEquipment(duckAssetId)
25152736 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2516- let $t07473874835 = subtractEquipment(currentEq, f._5)
2517- let newEq = $t07473874835._1
2518- let shouldZeroBuffs = $t07473874835._2
2737+ let $t08078880885 = subtractEquipment(currentEq, f._5)
2738+ let newEq = $t08078880885._1
2739+ let shouldZeroBuffs = $t08078880885._2
25192740 let e = expeditionInternal(i.caller, i.transactionId)
25202741 let id = e._2._1
25212742 let result = if ((0 >= f._1))
25222743 then $Tuple3([IntegerEntry(keyHealth, 0), StringEntry(eqKey, newEq)], "", 0)
25232744 else $Tuple3((e._1 ++ (if (shouldZeroBuffs)
25242745 then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
25252746 else ((((nil :+ StringEntry(keyDuckLocation(duckAssetId), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, f._1)) :+ StringEntry(eqKey, newEq)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))))), id, f._3)
25262747 if (checkTournament(duckAssetId))
25272748 then throw("expedition_checkTournament")
2528- else $Tuple2(((result._1 ++ updateDuckStatsInternal(duckAssetId, xpNewSLand)._1) :+ prologAction), $Tuple2(result._2, result._3))
2749+ else if (checkDelivery(duckAssetId))
2750+ then throw("expedition_checkDelivery")
2751+ else {
2752+ let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
2753+ $Tuple2(((result._1 ++ updateDuckStatsInternal(duckAssetId, xpNewSLand)._1) ++ prologActions), $Tuple3(result._2, result._3, acresResult))
2754+ }
2755+ }
2756+ }
2757+
2758+
2759+
2760+@Callable(i)
2761+func buySLandForAcres () = {
2762+ let prologActions = prolog(i)
2763+ if ((size(i.payments) != 1))
2764+ then throw("exactly 1 payment must be attached")
2765+ else {
2766+ let pmt = i.payments[0]
2767+ let amt = pmt.amount
2768+ if (if (!(isDefined(pmt.assetId)))
2769+ then true
2770+ else (value(pmt.assetId) != acresAssetId))
2771+ then throw("ACRES payments only!")
2772+ else if ((amt != S_COST_ACRES))
2773+ then throw(("Payment attached should be " + toString(S_COST_ACRES)))
2774+ else {
2775+ let result = expeditionInternal(i.caller, i.transactionId)
2776+ let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], [AttachedPayment(acresAssetId, amt)]))
2777+ $Tuple2(((result._1 ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) ++ prologActions), $Tuple2(result._2._1, acresResult))
2778+ }
25292779 }
25302780 }
25312781
25322782
25332783
25342784 @Callable(i)
25352785 func upgradeInfra (landAssetId) = {
2536- let prologAction = prolog(i)
2786+ let prologActions = prolog(i)
25372787 if ((size(i.payments) != 0))
25382788 then throw("No payments required")
25392789 else {
25402790 let result = upInfraCommon(true, i.caller, 0, landAssetId)
25412791 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
2542- $Tuple2(((result._1 :+ prologAction) ++ updateDuckStatsInternal(duckAssetId, fraction(xpUpgradeInfra, result._3, MULT8))._1), result._2)
2792+ $Tuple2(((result._1 ++ prologActions) ++ updateDuckStatsInternal(duckAssetId, fraction(xpUpgradeInfra, result._3, MULT8))._1), result._2)
25432793 }
25442794 }
25452795
25462796
25472797
25482798 @Callable(i)
25492799 func activateArtifact (artName,landAssetIdOpt) = {
2550- let prologAction = prolog(i)
2800+ let prologActions = prolog(i)
25512801 if ((size(i.payments) != 0))
25522802 then throw("No payments required")
25532803 else {
25542804 let addr = toString(i.caller)
25552805 let result = match artName {
25562806 case _ =>
25572807 if (("PRESALE" == $match0))
25582808 then activatePresaleArt(addr, landAssetIdOpt)
25592809 else if (("ONBOARD" == $match0))
25602810 then activateOnboardArt(addr)
25612811 else throw("Unknown artifact")
25622812 }
2563- (result :+ prologAction)
2813+ (result ++ prologActions)
25642814 }
25652815 }
25662816
25672817
25682818
25692819 @Callable(i)
25702820 func mergeLands (landAssetIds) = {
2571- let prologAction = prolog(i)
2821+ let prologActions = prolog(i)
25722822 if ((size(i.payments) != 0))
25732823 then throw("No payments required")
25742824 else {
25752825 let result = mergeCommon(toString(i.caller), landAssetIds)
2576- $Tuple2(((result._1 :+ prologAction) ++ updateAccStatsInternal(toString(i.caller), xpMerge)._1), result._2)
2826+ $Tuple2(((result._1 ++ prologActions) ++ updateAccStatsInternal(toString(i.caller), xpMerge)._1), result._2)
25772827 }
25782828 }
25792829
25802830
25812831
25822832 @Callable(i)
25832833 func cargoExchange (cargoListStr,landAssetId) = {
2584- let prologAction = prolog(i)
2834+ let prologActions = prolog(i)
25852835 if ((size(i.payments) != 0))
25862836 then throw("No payments required")
25872837 else {
25882838 let cargoParts = split_4C(cargoListStr, ":")
25892839 let addr = toString(i.originCaller)
25902840 let asset = value(assetInfo(fromBase58String(landAssetId)))
25912841 let timeKey = keyStakedTimeByAssetId(landAssetId)
25922842 if (!(isDefined(getInteger(timeKey))))
25932843 then throw((asset.name + " is not staked"))
25942844 else {
25952845 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
25962846 if ((owner != addr))
25972847 then throw((LANDPREFIX + " is not yours"))
25982848 else {
25992849 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
26002850 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
26012851 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
26022852 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
26032853 let loc = split(value(curLocation), "_")
26042854 if ((loc[locIdxType] != "L"))
26052855 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
26062856 else if ((loc[locIdxId] != landAssetId))
26072857 then throw(("Duck should be on the land " + landAssetId))
26082858 else {
26092859 let whKey = keyWarehouseByLand(landAssetId)
26102860 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
26112861 let bpKey = keyBackpackByDuck(duckAssetId)
26122862 let currentPack = getBackpack(bpKey)
26132863 let result = moveStuff(cargoParts, currentWh, currentPack)
26142864 let loft = split(currentWh[whIdxLOFT], "_")
26152865 let loftO = (parseIntValue(loft[volOccupied]) + result._7)
26162866 let loftF = (parseIntValue(loft[volFree]) - result._7)
2617-[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]
2867+ ([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]], "_")], ":"))] ++ prologActions)
26182868 }
26192869 }
26202870 }
26212871 }
26222872 }
26232873
26242874
26252875
26262876 @Callable(i)
26272877 func saveWarehouse (whStr,landAssetId) = if ((i.caller != economyContract))
26282878 then throw("Access denied")
26292879 else {
26302880 let whKey = keyWarehouseByLand(landAssetId)
26312881 let wh = split_4C(whStr, ":")
26322882 if ((size(wh) != 5))
26332883 then throw("warehouse string should contain 4 ':' separators")
26342884 else {
26352885 let loftL = split(wh[whIdxLOFT], "_")[volLocked]
26362886 let loftO = getWarehouseOccupiedVol(wh)
26372887 let loftT = getWarehouseTotalVolume(wh[whIdxLevels])
26382888 let loftF = ((loftT - parseIntValue(loftL)) - loftO)
26392889 let newWhStr = makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], wh[whIdxProd], makeString([loftL, toString(loftO), toString(loftF), toString(loftT)], "_")], ":")
26402890 $Tuple2([StringEntry(whKey, newWhStr)], newWhStr)
26412891 }
26422892 }
26432893
26442894
26452895
26462896 @Callable(i)
26472897 func fixWarehouseFormat (landAssetId) = if ((i.caller != restContract))
26482898 then throw("Access denied")
26492899 else {
26502900 let whKey = keyWarehouseByLand(landAssetId)
26512901 let asset = value(assetInfo(fromBase58String(landAssetId)))
26522902 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
26532903 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
26542904 let wh = getWarehouse(whKey, landIndex, infraLevel)
26552905 let loftL = asInt(invoke(economyContract, "recalcLockedVolumeREADONLY", [landAssetId, wh], nil))
26562906 let loftO = getWarehouseOccupiedVol(wh)
26572907 let loftT = getWarehouseTotalVolume(wh[whIdxLevels])
26582908 let loftF = ((loftT - loftL) - loftO)
26592909 let newWhStr = makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], wh[whIdxProd], makeString([toString(loftL), toString(loftO), toString(loftF), toString(loftT)], "_")], ":")
26602910 $Tuple2([StringEntry(whKey, newWhStr)], newWhStr)
26612911 }
26622912
26632913
26642914
26652915 @Callable(i)
26662916 func fixContinentProportions (landAssetIds) = if ((i.caller != restContract))
26672917 then throw("Access denied")
26682918 else {
26692919 func getProps (acc,cont) = (acc :+ valueOrElse(getString(keyResTypesByContinent(cont)), "0_0_0_0_0_0"))
26702920
26712921 let p = {
26722922 let $l = continents
26732923 let $s = size($l)
26742924 let $acc0 = nil
26752925 func $f0_1 ($a,$i) = if (($i >= $s))
26762926 then $a
26772927 else getProps($a, $l[$i])
26782928
26792929 func $f0_2 ($a,$i) = if (($i >= $s))
26802930 then $a
26812931 else throw("List size exceeds 5")
26822932
26832933 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
26842934 }
26852935 func processor (acc,landAssetId) = {
26862936 let asset = value(assetInfo(fromBase58String(landAssetId)))
26872937 let d = split(asset.description, "_")
26882938 let landIndex = (numPiecesBySize(d[recLandSize]) / SSIZE)
26892939 let cont = d[recContinent]
26902940 let terrainCounts = countTerrains(d[recTerrains])
26912941 let continentIdx = value(indexOf(continents, cont))
26922942 let contProps = split(acc[continentIdx], "_")
26932943 let updated = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, 1), "_")
26942944 match cont {
26952945 case _ =>
26962946 if (("Americas" == $match0))
26972947 then [updated, acc[1], acc[2], acc[3], acc[4]]
26982948 else if (("Europe" == $match0))
26992949 then [acc[0], updated, acc[2], acc[3], acc[4]]
27002950 else if (("Asia" == $match0))
27012951 then [acc[0], acc[1], updated, acc[3], acc[4]]
27022952 else if (("Africa" == $match0))
27032953 then [acc[0], acc[1], acc[2], updated, acc[4]]
27042954 else if (("Oceania" == $match0))
27052955 then [acc[0], acc[1], acc[2], acc[3], updated]
27062956 else throw("wrong continent")
27072957 }
27082958 }
27092959
27102960 let r = {
27112961 let $l = landAssetIds
27122962 let $s = size($l)
27132963 let $acc0 = p
27142964 func $f1_1 ($a,$i) = if (($i >= $s))
27152965 then $a
27162966 else processor($a, $l[$i])
27172967
27182968 func $f1_2 ($a,$i) = if (($i >= $s))
27192969 then $a
27202970 else throw("List size exceeds 100")
27212971
27222972 $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)
27232973 }
27242974 $Tuple2([StringEntry(keyResTypesByContinent("Americas"), r[0]), StringEntry(keyResTypesByContinent("Europe"), r[1]), StringEntry(keyResTypesByContinent("Asia"), r[2]), StringEntry(keyResTypesByContinent("Africa"), r[3]), StringEntry(keyResTypesByContinent("Oceania"), r[4])], 0)
27252975 }
27262976
27272977
27282978
27292979 @Callable(i)
27302980 func fixStakedPieces (address) = if ((i.caller != restContract))
27312981 then throw("Access denied")
27322982 else {
27332983 let stakedPieces = if ((address == ""))
27342984 then 0
27352985 else {
27362986 let landsStr = getString(stakingContract, keyStakedLandsByOwner(address))
27372987 let lands = if (isDefined(landsStr))
27382988 then split_51C(value(landsStr), "_")
27392989 else nil
27402990 func oneLand (acc,landAssetId) = {
27412991 let asset = value(assetInfo(fromBase58String(landAssetId)))
27422992 let landSize = split(asset.description, "_")[recLandSize]
27432993 (acc + numPiecesBySize(landSize))
27442994 }
27452995
27462996 let $l = lands
27472997 let $s = size($l)
27482998 let $acc0 = 0
27492999 func $f0_1 ($a,$i) = if (($i >= $s))
27503000 then $a
27513001 else oneLand($a, $l[$i])
27523002
27533003 func $f0_2 ($a,$i) = if (($i >= $s))
27543004 then $a
27553005 else throw("List size exceeds 100")
27563006
27573007 $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)
27583008 }
27593009 $Tuple2([IntegerEntry(keyStakedPiecesByOwner(address), stakedPieces)], stakedPieces)
27603010 }
27613011
27623012
27633013
27643014 @Callable(i)
27653015 func setCustomName (assetId,customName,type) = {
2766- let prologAction = prolog(i)
3016+ let prologActions = prolog(i)
27673017 if ((size(i.payments) != 1))
27683018 then throw("Exactly one payment required")
27693019 else {
27703020 let pmt = value(i.payments[0])
27713021 if ((pmt.assetId != usdtAssetId))
27723022 then throw("Allowed USDT payment only!")
27733023 else if ((pmt.amount != RENAMINGCOST))
27743024 then throw(("Payment should be " + toString(RENAMINGCOST)))
27753025 else if (contains(customName, "__"))
27763026 then throw(("Name should not contain '__': " + customName))
27773027 else if ((size(customName) > MAXNAMELEN))
27783028 then throw(("Name too long, maxLength=" + toString(MAXNAMELEN)))
27793029 else {
27803030 let addr = toString(i.originCaller)
27813031 let actions = match type {
27823032 case _ =>
27833033 if (("ACCOUNT" == $match0))
27843034 then {
27853035 let reverseKey = keyCustomNameToAddress(customName)
27863036 let nameOwner = getString(reverseKey)
27873037 if (isDefined(nameOwner))
27883038 then throw(("Name already registered: " + customName))
27893039 else {
27903040 let addrToNameKey = keyAddressToCustomName(addr)
27913041 let oldName = getString(addrToNameKey)
27923042 let freeOld = if (isDefined(oldName))
27933043 then [DeleteEntry(keyCustomNameToAddress(value(oldName)))]
27943044 else nil
27953045 (((freeOld :+ StringEntry(addrToNameKey, customName)) :+ StringEntry(reverseKey, addr)) ++ updateAccStatsInternal(addr, xpCustomName)._1)
27963046 }
27973047 }
27983048 else if (("LAND" == $match0))
27993049 then {
28003050 let asset = value(assetInfo(fromBase58String(assetId)))
28013051 let timeKey = keyStakedTimeByAssetId(assetId)
28023052 if (!(isDefined(getInteger(timeKey))))
28033053 then throw((asset.name + " is not staked"))
28043054 else {
28053055 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
28063056 if ((owner != addr))
28073057 then throw((LANDPREFIX + " is not yours"))
28083058 else {
28093059 let reverseKey = keyLandCustomNameToAssetId(customName)
28103060 let nameOwner = getString(reverseKey)
28113061 if (isDefined(nameOwner))
28123062 then throw(("Name already registered: " + customName))
28133063 else {
28143064 let assetToNameKey = keyLandAssetIdToCustomName(assetId)
28153065 let oldName = getString(assetToNameKey)
28163066 let freeOld = if (isDefined(oldName))
28173067 then [DeleteEntry(keyLandCustomNameToAssetId(value(oldName)))]
28183068 else nil
28193069 (((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId)) ++ updateAccStatsInternal(addr, xpCustomName)._1)
28203070 }
28213071 }
28223072 }
28233073 }
28243074 else if (("DUCK" == $match0))
28253075 then {
28263076 let asset = value(assetInfo(fromBase58String(assetId)))
28273077 let timeKey = keyStakedTimeByAssetId(assetId)
28283078 if (if (!(isDefined(getInteger(timeKey))))
28293079 then true
28303080 else !(isDefined(getString(keyStakedDuckByOwner(addr)))))
28313081 then throw((asset.name + " is not staked"))
28323082 else {
28333083 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
28343084 if ((owner != addr))
28353085 then throw((DUCKPREFIX + " is not yours"))
28363086 else {
28373087 let reverseKey = keyDuckCustomNameToAssetId(customName)
28383088 let nameOwner = getString(reverseKey)
28393089 if (isDefined(nameOwner))
28403090 then throw(("Name already registered: " + customName))
28413091 else {
28423092 let assetToNameKey = keyDuckAssetIdToCustomName(assetId)
28433093 let oldName = getString(assetToNameKey)
28443094 let freeOld = if (isDefined(oldName))
28453095 then [DeleteEntry(keyDuckCustomNameToAssetId(value(oldName)))]
28463096 else nil
28473097 (((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId)) ++ updateDuckStatsInternal(assetId, xpCustomName)._1)
28483098 }
28493099 }
28503100 }
28513101 }
28523102 else throw("Unknown entity type")
28533103 }
2854- $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), 0)
3104+ $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ prologActions), 0)
28553105 }
28563106 }
28573107 }
28583108
28593109
28603110
28613111 @Callable(i)
28623112 func setReferrals (oldPlayer,newPlayer) = if ((i.callerPublicKey != pub))
28633113 then throw("Permission denied")
28643114 else {
2865- let prologAction = prolog(i)
3115+ let prologActions = prolog(i)
28663116 if ((size(i.payments) != 0))
28673117 then throw("No payments required")
28683118 else if (!(isDefined(addressFromString(oldPlayer))))
28693119 then throw(("Invalid address: " + oldPlayer))
28703120 else if (!(isDefined(addressFromString(newPlayer))))
28713121 then throw(("Invalid address: " + newPlayer))
28723122 else {
28733123 let oldsKey = keyOldies()
28743124 let olds = getString(oldsKey)
28753125 let oldies = if (isDefined(olds))
28763126 then split_4C(value(olds), "_")
28773127 else nil
28783128 if (containsElement(oldies, newPlayer))
28793129 then throw((newPlayer + " is not newbie (already has referrals)"))
28803130 else {
28813131 let refByKey = keyAddressRefBy(newPlayer)
28823132 let refBy = getString(refByKey)
28833133 if (if (isDefined(refBy))
28843134 then isDefined(addressFromString(value(refBy)))
28853135 else false)
28863136 then throw(((newPlayer + " already has refBy: ") + value(refBy)))
28873137 else {
28883138 let refsKey = keyAddressReferrals(oldPlayer)
28893139 let refs = getString(refsKey)
28903140 let refsArray = if (isDefined(refs))
28913141 then split_4C(value(refs), "_")
28923142 else nil
28933143 if (containsElement(refsArray, newPlayer))
28943144 then throw((((oldPlayer + " already contains ") + newPlayer) + " within referrals"))
28953145 else {
28963146 let newRefs = makeString_2C((refsArray :+ newPlayer), "_")
28973147 let newOlds = if (containsElement(oldies, oldPlayer))
28983148 then value(olds)
28993149 else makeString_2C((oldies :+ oldPlayer), "_")
2900- $Tuple2([StringEntry(refByKey, oldPlayer), StringEntry(refsKey, newRefs), StringEntry(oldsKey, newOlds), prologAction], 0)
3150+ $Tuple2(([StringEntry(refByKey, oldPlayer), StringEntry(refsKey, newRefs), StringEntry(oldsKey, newOlds)] ++ prologActions), 0)
29013151 }
29023152 }
29033153 }
29043154 }
29053155 }
29063156
29073157
29083158
29093159 @Callable(i)
29103160 func distributePoints (strength,accuracy,intellect,endurance,dexterity) = {
2911- let prologAction = prolog(i)
3161+ let prologActions = prolog(i)
29123162 if ((size(i.payments) != 0))
29133163 then throw("No payments required")
29143164 else {
29153165 let addr = toString(i.originCaller)
29163166 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
29173167 let freeKeyAcc = keyUserFreePoints(addr)
29183168 let freePointsAcc = valueOrElse(getInteger(stakingContract, freeKeyAcc), 0)
29193169 let freeKeyDuck = keyDuckFreePoints(duckAssetId)
29203170 let freePointsDuck = valueOrElse(getInteger(stakingContract, freeKeyDuck), 0)
29213171 let sumFree = (freePointsAcc + freePointsDuck)
29223172 let sumToDistribute = ((((strength + accuracy) + intellect) + endurance) + dexterity)
29233173 if ((sumToDistribute > sumFree))
29243174 then throw((("There are only " + toString(sumFree)) + " free points to distribute"))
29253175 else {
29263176 let charsKey = keyDuckChars(duckAssetId)
29273177 let chars = split(valueOrElse(getString(stakingContract, charsKey), "0_0_0_0_0"), "_")
29283178 let newAcc = (freePointsAcc - sumToDistribute)
2929- $Tuple2([IntegerEntry(freeKeyAcc, if ((0 > newAcc))
3179+ $Tuple2(([IntegerEntry(freeKeyAcc, if ((0 > newAcc))
29303180 then 0
29313181 else newAcc), IntegerEntry(freeKeyDuck, if ((0 > newAcc))
29323182 then (freePointsDuck + newAcc)
2933- else freePointsDuck), StringEntry(charsKey, makeString([toString((parseIntValue(chars[charStrength]) + strength)), toString((parseIntValue(chars[charAccuracy]) + accuracy)), toString((parseIntValue(chars[charIntellect]) + intellect)), toString((parseIntValue(chars[charEndurance]) + endurance)), toString((parseIntValue(chars[charDexterity]) + dexterity))], "_")), prologAction], 0)
3183+ else freePointsDuck), StringEntry(charsKey, makeString([toString((parseIntValue(chars[charStrength]) + strength)), toString((parseIntValue(chars[charAccuracy]) + accuracy)), toString((parseIntValue(chars[charIntellect]) + intellect)), toString((parseIntValue(chars[charEndurance]) + endurance)), toString((parseIntValue(chars[charDexterity]) + dexterity))], "_"))] ++ prologActions), 0)
29343184 }
29353185 }
29363186 }
29373187
29383188
29393189
29403190 @Callable(i)
29413191 func splitByGlobalWeightsREADONLY (amount) = $Tuple2(nil, getNeededMaterials(amount))
29423192
29433193
29443194
29453195 @Callable(i)
29463196 func splitByGlobalAndLocalWeightsREADONLY (matAmount,resAmount,terrains) = {
29473197 let terrainCounts = countTerrains(terrains)
29483198 $Tuple2(nil, $Tuple2(getNeededMaterials(matAmount), distributeByWeights(resAmount, terrainCounts)))
29493199 }
29503200
29513201
29523202
29533203 @Callable(i)
29543204 func getBackpackREADONLY (duckAssetId) = $Tuple2(nil, makeString(getBackpack(keyBackpackByDuck(duckAssetId)), ":"))
29553205
29563206
29573207
29583208 @Callable(i)
29593209 func getWarehouseREADONLY (landAssetId) = {
29603210 let asset = value(assetInfo(fromBase58String(landAssetId)))
29613211 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
29623212 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
29633213 $Tuple2(nil, makeString_2C(getWarehouse(keyWarehouseByLand(landAssetId), landIndex, infraLevel), ":"))
29643214 }
29653215
29663216
29673217
29683218 @Callable(i)
29693219 func saveLastTx () = {
29703220 let caller = i.caller
2971- if (if (if ((caller != wlgContract))
2972- then (caller != economyContract)
2973- else false)
2974- then (caller != tournamentContract)
2975- else false)
3221+ if (!(containsElement([wlgContract, economyContract, tournamentContract, acresContract], caller)))
29763222 then throw("Access denied")
2977- else $Tuple2([prolog(i)], 42)
3223+ else $Tuple2(prolog(i), 42)
29783224 }
29793225
29803226
29813227
29823228 @Callable(i)
29833229 func updateDuckStats (duckAssetId,deltaXP) = if ((i.caller != economyContract))
29843230 then throw("Access denied")
29853231 else updateDuckStatsInternal(duckAssetId, deltaXP)
29863232
29873233
29883234
29893235 @Callable(i)
2990-func updateAccStats (addr,deltaXP) = if ((i.caller != economyContract))
3236+func updateAccStats (addr,deltaXP) = if (if ((i.caller != economyContract))
3237+ then (i.caller != acresContract)
3238+ else false)
29913239 then throw("Access denied")
29923240 else updateAccStatsInternal(addr, deltaXP)
29933241
29943242
29953243
29963244 @Callable(i)
29973245 func equipDuck (equipment) = {
2998- let prologAction = prolog(i)
3246+ let prologActions = prolog(i)
29993247 if ((size(i.payments) != 0))
30003248 then throw("No payments required")
30013249 else {
30023250 let addr = toString(i.originCaller)
30033251 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
30043252 if (checkTournament(duckAssetId))
30053253 then throw("equipDuck_checkTournament")
3006- else {
3007- let eqKey = keyDuckEquipment(duckAssetId)
3008- let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
3009- let bpKey = keyBackpackByDuck(duckAssetId)
3010- let currentPack = getBackpack(bpKey)
3011- let newEq = split(equipment, "_")
3012- if ((size(newEq) != NUMSEGMENTS))
3013- then throw("Wrong equipment string")
3014- else {
3015- let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
3016- let segBpAux = split(newEq[segBackpack], ";")[1]
3017- let buffEffect = if ((segBpAux == ""))
3018- then 0
3019- else {
3020- let aux0 = split(segBpAux, ",")[0]
3021- if ((aux0 == ""))
3022- then 0
3023- else {
3024- let idxCnt = split(aux0, ":")
3025- let idx = idxCnt[0]
3026- let cnt = idxCnt[1]
3027- if (if (if (if (if ((idx == "06"))
3028- then true
3029- else (idx == "07"))
3030- then true
3031- else (idx == "08"))
3032- then (cnt != "")
3033- else false)
3034- then (parseIntValue(cnt) > 0)
3035- else false)
3036- then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
3037- else 0
3038- }
3039- }
3040- let stats = getDuckStats(this, duckAssetId, buffEffect, true)
3041- let newProdB = dressB(newEq, tempProdB, false, stats)
3042- let newProdStr = bytesToProdStr(newProdB)
3043- $Tuple2([StringEntry(eqKey, equipment), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProdStr], ":")), StringEntry(keyDuckBuffs(duckAssetId), makeString([toString(stats[7]), toString(stats[8]), toString(stats[9]), toString(stats[10]), toString(stats[11])], "_")), prologAction], 0)
3044- }
3045- }
3254+ else if (checkDelivery(duckAssetId))
3255+ then throw("equipDuck_checkDelivery")
3256+ else {
3257+ let eqKey = keyDuckEquipment(duckAssetId)
3258+ let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
3259+ let bpKey = keyBackpackByDuck(duckAssetId)
3260+ let currentPack = getBackpack(bpKey)
3261+ let newEq = split(equipment, "_")
3262+ if ((size(newEq) != NUMSEGMENTS))
3263+ then throw("Wrong equipment string")
3264+ else {
3265+ let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
3266+ let segBpAux = split(newEq[segBackpack], ";")[1]
3267+ let buffEffect = if ((segBpAux == ""))
3268+ then 0
3269+ else {
3270+ let aux0 = split(segBpAux, ",")[0]
3271+ if ((aux0 == ""))
3272+ then 0
3273+ else {
3274+ let idxCnt = split(aux0, ":")
3275+ let idx = idxCnt[0]
3276+ let cnt = idxCnt[1]
3277+ if (if (if (if (if ((idx == "06"))
3278+ then true
3279+ else (idx == "07"))
3280+ then true
3281+ else (idx == "08"))
3282+ then (cnt != "")
3283+ else false)
3284+ then (parseIntValue(cnt) > 0)
3285+ else false)
3286+ then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
3287+ else 0
3288+ }
3289+ }
3290+ let stats = getDuckStats(this, duckAssetId, buffEffect, true)
3291+ let newProdB = dressB(newEq, tempProdB, false, stats)
3292+ let newProdStr = bytesToProdStr(newProdB)
3293+ $Tuple2(([StringEntry(eqKey, equipment), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProdStr], ":")), StringEntry(keyDuckBuffs(duckAssetId), makeString([toString(stats[7]), toString(stats[8]), toString(stats[9]), toString(stats[10]), toString(stats[11])], "_"))] ++ prologActions), 0)
3294+ }
3295+ }
30463296 }
30473297 }
30483298
30493299
30503300
30513301 @Callable(i)
30523302 func fortificateLand (landAssetId,plan) = {
3053- let prologAction = prolog(i)
3303+ let prologActions = prolog(i)
30543304 if ((size(i.payments) != 0))
30553305 then throw("No payments required")
30563306 else {
30573307 let addr = toString(i.originCaller)
30583308 let duckAssetId = valueOrElse(getString(keyStakedDuckByOwner(addr)), "")
30593309 let duckStats = getDuckStats(this, duckAssetId, 0, false)
30603310 let fortKey = keyFortificationsByLand(landAssetId)
30613311 let currentForts = split(valueOrElse(getString(fortKey), ":0_15:0_18:0"), "_")
30623312 let asset = value(assetInfo(fromBase58String(landAssetId)))
30633313 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
30643314 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
30653315 let whKey = keyWarehouseByLand(landAssetId)
30663316 let wh = getWarehouse(whKey, landIndex, infraLevel)
30673317 let curLoft = split(wh[whIdxLOFT], "_")
30683318 let curO = parseIntValue(curLoft[volOccupied])
30693319 let curF = parseIntValue(curLoft[volFree])
30703320 let newForts = split(plan, "_")
3071- let $t09585095965 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3072- let tempProdB = $t09585095965._1
3073- let tempO = $t09585095965._2
3074- let tempF = $t09585095965._3
3075- let $t09596896064 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3076- let newProdB = $t09596896064._1
3077- let newO = $t09596896064._2
3078- let newF = $t09596896064._3
3321+ let $t0102994103109 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3322+ let tempProdB = $t0102994103109._1
3323+ let tempO = $t0102994103109._2
3324+ let tempF = $t0102994103109._3
3325+ let $t0103112103208 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3326+ let newProdB = $t0103112103208._1
3327+ let newO = $t0103112103208._2
3328+ let newF = $t0103112103208._3
30793329 let newProdStr = bytesToProdStr(newProdB)
30803330 let newLoftStr = makeString([curLoft[volLocked], toString(newO), toString(newF), curLoft[volTotal]], "_")
3081- $Tuple2([StringEntry(fortKey, plan), StringEntry(whKey, makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], newProdStr, newLoftStr], ":")), prologAction], 0)
3331+ $Tuple2(([StringEntry(fortKey, plan), StringEntry(whKey, makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], newProdStr, newLoftStr], ":"))] ++ prologActions), 0)
30823332 }
30833333 }
30843334
30853335
30863336
30873337 @Callable(i)
30883338 func initDuckTourAttempt (duckAssetId) = if ((i.caller != tournamentContract))
30893339 then throw("Access denied")
30903340 else {
3091- let prologAction = prolog(i)
30923341 let keyHealth = keyDuckHealth(duckAssetId)
30933342 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
30943343 let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
30953344 let curLocKey = keyDuckLocation(duckAssetId)
30963345 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
30973346 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
30983347 let tourLocation = (toString(lastId) + "_T_0")
3099- $Tuple2([prologAction, IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, tourLocation)], tourLocation)
3348+ $Tuple2([IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, tourLocation)], tourLocation)
31003349 }
31013350
31023351
31033352
31043353 @Callable(i)
31053354 func breakAttempt () = {
3106- let prologAction = prolog(i)
3355+ let prologActions = prolog(i)
31073356 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
31083357 let curLocKey = keyDuckLocation(duckAssetId)
31093358 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
31103359 if ((split(curLocation, "_")[locIdxType] != "T"))
31113360 then throw("Your duck is not in the tournament")
31123361 else {
31133362 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
31143363 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
3115- $Tuple2([prologAction, IntegerEntry(keyDuckHealth(duckAssetId), savedHealth), StringEntry(curLocKey, savedLocation)], curLocation)
3364+ $Tuple2(((prologActions :+ IntegerEntry(keyDuckHealth(duckAssetId), savedHealth)) :+ StringEntry(curLocKey, savedLocation)), curLocation)
31163365 }
31173366 }
31183367
31193368
31203369
31213370 @Callable(i)
31223371 func exitTournamentInternal (duckAssetId) = if ((i.caller != this))
31233372 then throw("Access denied")
31243373 else {
31253374 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
31263375 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
31273376 $Tuple2([IntegerEntry(keyDuckHealth(duckAssetId), savedHealth), StringEntry(keyDuckLocation(duckAssetId), savedLocation)], false)
31283377 }
31293378
31303379
31313380
31323381 @Callable(i)
3382+func exitDeliveryInternal (duckAssetId) = if ((i.caller != this))
3383+ then throw("Access denied")
3384+ else {
3385+ let e = exitDeliveryCommon(duckAssetId)
3386+ $Tuple2((e._1 ++ e._2), false)
3387+ }
3388+
3389+
3390+
3391+@Callable(i)
3392+func autoExitDelivery (duckAssetId) = if ((i.caller != this))
3393+ then throw("Access denied")
3394+ else {
3395+ let e = exitDeliveryCommon(duckAssetId)
3396+ $Tuple2(e._1, $Tuple2(e._3, e._4))
3397+ }
3398+
3399+
3400+
3401+@Callable(i)
31333402 func prepareRobbery (message,sig) = {
3134- let prologAction = prolog(i)
3403+ let prologActions = prolog(i)
31353404 if (!(sigVerify_8Kb(message, sig, pub)))
31363405 then throw("signature does not match")
31373406 else if ((size(i.payments) != 1))
31383407 then throw("exactly 1 payment must be attached")
31393408 else {
31403409 let pmt = i.payments[0]
31413410 let wlgAmt = pmt.amount
31423411 if (if (!(isDefined(pmt.assetId)))
31433412 then true
31443413 else (value(pmt.assetId) != wlgAssetId))
31453414 then throw("WLGOLD payments only!")
31463415 else {
31473416 let parts = split(toUtf8String(message), "|")
31483417 if ((size(parts) != 2))
31493418 then throw("Wrong message format")
31503419 else {
31513420 let duckAssetId = parts[0]
3152- let robCost = getRobberyData(this, duckAssetId)._1
3153- if ((robCost > wlgAmt))
3154- then throw(((("Payment " + toString(wlgAmt)) + " < required ") + toString(robCost)))
3155- else {
3156- let candidates = split(parts[1], "_")
3157- let now = lastBlock.timestamp
3158- let duckState = valueOrElse(getInteger(keyDuckRobberyState(duckAssetId)), 0)
3159- let lockedLand = valueOrElse(getString(keyLockedLandByDuck(duckAssetId)), "")
3160- let landETA = valueOrElse(getInteger(keyLandCooldownETA(lockedLand)), 0)
3161- if (if ((duckState != duckIdxFree))
3162- then (landETA > now)
3163- else false)
3164- then throw(("You already started robbing, wait till " + toString(landETA)))
3165- else {
3166- func checker (acc,landAssetId) = {
3167- let state = valueOrElse(getInteger(keyLandRobberyState(landAssetId)), 0)
3168- let cooldownETA = valueOrElse(getInteger(keyLandCooldownETA(landAssetId)), 0)
3169- if ((state > size(landRobCooldowns)))
3170- then throw("Invalid state")
3171- else if ((now > cooldownETA))
3172- then {
3173- let stakedTime = valueOrElse(getInteger(keyStakedTimeByAssetId(landAssetId)), 0)
3174- if ((0 >= stakedTime))
3175- then acc
3176- else {
3177- let a = value(assetInfo(fromBase58String(landAssetId)))
3178- let d = split(a.description, "_")
3179- let pieces = numPiecesBySize(d[recLandSize])
3180- let productivity = applyBonuses(landAssetId, pieces)
3181- let deltaTime = (now - stakedTime)
3182- let availRes = fraction(deltaTime, (productivity * pieces), DAYMILLIS)
3183- if ((MIN_RES_TO_ROB > availRes))
3184- then acc
3185- else (acc :+ landAssetId)
3186- }
3421+ if (checkTournament(duckAssetId))
3422+ then throw("prepareRobbery_checkTournament")
3423+ else if (checkDelivery(duckAssetId))
3424+ then throw("prepareRobbery_checkDelivery")
3425+ else {
3426+ let robCost = getRobberyData(this, duckAssetId)._1
3427+ if ((robCost > wlgAmt))
3428+ then throw(((("Payment " + toString(wlgAmt)) + " < required ") + toString(robCost)))
3429+ else {
3430+ let candidates = split(parts[1], "_")
3431+ let now = lastBlock.timestamp
3432+ let duckState = valueOrElse(getInteger(keyDuckRobberyState(duckAssetId)), 0)
3433+ let lockedLand = valueOrElse(getString(keyLockedLandByDuck(duckAssetId)), "")
3434+ let landETA = valueOrElse(getInteger(keyLandCooldownETA(lockedLand)), 0)
3435+ if (if ((duckState != duckIdxFree))
3436+ then (landETA > now)
3437+ else false)
3438+ then throw(("You already started robbing, wait till " + toString(landETA)))
3439+ else {
3440+ func checker (acc,landAssetId) = {
3441+ let state = valueOrElse(getInteger(keyLandRobberyState(landAssetId)), 0)
3442+ let cooldownETA = valueOrElse(getInteger(keyLandCooldownETA(landAssetId)), 0)
3443+ if ((state > size(landRobCooldowns)))
3444+ then throw("Invalid state")
3445+ else if ((now > cooldownETA))
3446+ then {
3447+ let stakedTime = valueOrElse(getInteger(keyStakedTimeByAssetId(landAssetId)), 0)
3448+ if ((0 >= stakedTime))
3449+ then acc
3450+ else {
3451+ let a = value(assetInfo(fromBase58String(landAssetId)))
3452+ let d = split(a.description, "_")
3453+ let pieces = numPiecesBySize(d[recLandSize])
3454+ let productivity = applyBonuses(landAssetId, pieces)
3455+ let deltaTime = (now - stakedTime)
3456+ let availRes = fraction(deltaTime, (productivity * pieces), DAYMILLIS)
3457+ if ((MIN_RES_TO_ROB > availRes))
3458+ then acc
3459+ else (acc :+ landAssetId)
3460+ }
3461+ }
3462+ else acc
31873463 }
3188- else acc
3464+
3465+ let filtered = {
3466+ let $l = candidates
3467+ let $s = size($l)
3468+ let $acc0 = nil
3469+ func $f0_1 ($a,$i) = if (($i >= $s))
3470+ then $a
3471+ else checker($a, $l[$i])
3472+
3473+ func $f0_2 ($a,$i) = if (($i >= $s))
3474+ then $a
3475+ else throw("List size exceeds 10")
3476+
3477+ $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)
3478+ }
3479+ if ((size(filtered) == 0))
3480+ then throw("No candidates for robbery")
3481+ else {
3482+ let rndIdx = getRandomNumber(size(filtered), height, (sig + i.transactionId))
3483+ let landAssetId = filtered[rndIdx]
3484+ $Tuple2(([IntegerEntry(keyLandRobberyState(landAssetId), robIdxLocked), IntegerEntry(keyLandCooldownETA(landAssetId), (now + landRobCooldowns[robIdxLocked])), IntegerEntry(keyDuckRobberyState(duckAssetId), duckIdxPreparing), StringEntry(keyLockedLandByDuck(duckAssetId), landAssetId)] ++ prologActions), landAssetId)
3485+ }
3486+ }
31893487 }
3190-
3191- let filtered = {
3192- let $l = candidates
3193- let $s = size($l)
3194- let $acc0 = nil
3195- func $f0_1 ($a,$i) = if (($i >= $s))
3196- then $a
3197- else checker($a, $l[$i])
3198-
3199- func $f0_2 ($a,$i) = if (($i >= $s))
3200- then $a
3201- else throw("List size exceeds 10")
3202-
3203- $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)
3204- }
3205- if ((size(filtered) == 0))
3206- then throw("No candidates for robbery")
3207- else {
3208- let rndIdx = getRandomNumber(size(filtered), height, (sig + i.transactionId))
3209- let landAssetId = filtered[rndIdx]
3210- $Tuple2([IntegerEntry(keyLandRobberyState(landAssetId), robIdxLocked), IntegerEntry(keyLandCooldownETA(landAssetId), (now + landRobCooldowns[robIdxLocked])), IntegerEntry(keyDuckRobberyState(duckAssetId), duckIdxPreparing), StringEntry(keyLockedLandByDuck(duckAssetId), landAssetId), prologAction], landAssetId)
3211- }
3212- }
3213- }
3488+ }
32143489 }
32153490 }
32163491 }
32173492 }
32183493
32193494
32203495
32213496 @Callable(i)
32223497 func robLand (message,sig) = {
3223- let prologAction = prolog(i)
3498+ let prologActions = prolog(i)
32243499 if (!(sigVerify_8Kb(message, sig, pub)))
32253500 then throw("signature does not match")
3226- else $Tuple2([prologAction], 0)
3227- }
3501+ else {
3502+ let userAddr = toString(i.caller)
3503+ let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
3504+ let now = lastBlock.timestamp
3505+ $Tuple2((prologActions :+ IntegerEntry(keyLastRobberyTimeByDuck(duckAssetId), now)), 0)
3506+ }
3507+ }
3508+
3509+
3510+
3511+@Callable(i)
3512+func acceptDelivery () = if (!(KS_ALLOW_DELIVERY))
3513+ then throw("Delivery feature is turned off!")
3514+ else {
3515+ let prologActions = prolog(i)
3516+ let userAddr = toString(i.caller)
3517+ let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
3518+ let fundTotal = valueOrElse(getInteger(economyContract, deliveryFundKey), 0)
3519+ let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
3520+ if ((MIN_USDT_FEE_DELIVERY > (fundTotal - lockedTotal)))
3521+ then throw(((("Delivery is not available, fund=" + fixedPoint(fundTotal, 6)) + ", locked=") + fixedPoint(lockedTotal, 6)))
3522+ else {
3523+ let now = lastBlock.timestamp
3524+ let delayETA = valueOrElse(getInteger(keyDeliveryDelayByDuck(duckAssetId)), 0)
3525+ if ((delayETA > now))
3526+ then throw(("Delivery is forbidden for your duck until " + toString(delayETA)))
3527+ else if (checkTournament(duckAssetId))
3528+ then throw("acceptDelivery_checkTournament")
3529+ else if (checkDelivery(duckAssetId))
3530+ then throw("acceptDelivery_checkDelivery")
3531+ else {
3532+ let newLockedTotal = asInt(invoke(economyContract, "updateDeliveryLocked", [(lockedTotal + MIN_USDT_FEE_DELIVERY)], nil))
3533+ let keyHealth = keyDuckHealth(duckAssetId)
3534+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
3535+ let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
3536+ let curLocKey = keyDuckLocation(duckAssetId)
3537+ let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
3538+ let deliveryLocation = (toString(now) + "_D_0")
3539+ $Tuple2(([IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, deliveryLocation)] ++ prologActions), $Tuple2(deliveryLocation, newLockedTotal))
3540+ }
3541+ }
3542+ }
32283543
32293544

github/deemru/w8io/3ef1775 
331.42 ms