tx · eLgyWndWvXPefayPWBtUkyQzhmLjZvMmNXGh18y4sBa

3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm:  -0.04900000 Waves

2023.03.26 01:09 [2506102] smart account 3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm > SELF 0.00000000 Waves

{ "type": 13, "id": "eLgyWndWvXPefayPWBtUkyQzhmLjZvMmNXGh18y4sBa", "fee": 4900000, "feeAssetId": null, "timestamp": 1679782153143, "version": 2, "chainId": 84, "sender": "3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm", "senderPublicKey": "EVooykMNV691Venwp1dHUTBd7KWequzUcda57Wd3LQEX", "proofs": [ "4nBx9ZPgCG5cDjoyvfqpCWLeQ8rGLqZ5UbmnWd32bc6wZYGLMUXZMeCXp6VdfWeXwy7YSijRb4ALdmDz56HRXzt8" ], "script": "base64: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aWwACkFSVFBSRVNBTEUCB1BSRVNBTEUAD1BSRVNBTEVOVU1MQU5EUwD0AwEPZ2V0U3RyaW5nT3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFB2FkZHJlc3MFA2tleQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQdhZGRyZXNzCQDMCAICAS4JAMwIAgUDa2V5CQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABDGdldEludE9yRWxzZQIDa2V5CmRlZmF1bHRWYWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUDa2V5BQpkZWZhdWx0VmFsABFJZHhDZmdTdGFraW5nRGFwcAABABFJZHhDZmdFY29ub215RGFwcAACABRJZHhDZmdHb3Zlcm5hbmNlRGFwcAADAQprZXlSZXN0Q2ZnAAIOJXNfX3Jlc3RDb25maWcBDmtleVJlc3RBZGRyZXNzAAIMJXNfX3Jlc3RBZGRyARFyZWFkUmVzdENmZ09yRmFpbAEEcmVzdAkAvAkCCQEPZ2V0U3RyaW5nT3JGYWlsAgUEcmVzdAkBCmtleVJlc3RDZmcABQNTRVABGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIHcmVzdENmZwNpZHgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFB3Jlc3RDZmcFA2lkeAkArAICAipSZXN0IGNmZyBkb2Vzbid0IGNvbnRhaW4gYWRkcmVzcyBhdCBpbmRleCAJAKQDAQUDaWR4AAxyZXN0Q29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBDmtleVJlc3RBZGRyZXNzAAUVZGVmYXVsdFJlc3RBZGRyZXNzU3RyAAdyZXN0Q2ZnCQERcmVhZFJlc3RDZmdPckZhaWwBBQxyZXN0Q29udHJhY3QAD2Vjb25vbXlDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFEUlkeENmZ0Vjb25vbXlEYXBwAAtnb3ZDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFFElkeENmZ0dvdmVybmFuY2VEYXBwARFrZXlMYXN0VHhJZEJ5VXNlcgEEYWRkcgkArAICAg9sYXN0VHhJZEJ5VXNlcl8FBGFkZHIBEmtleU5leHRGcmVlTGFuZE51bQACC25leHRMYW5kTnVtARBrZXlMYW5kVG9Bc3NldElkAQdsYW5kTnVtCQCsAgICDGxhbmRUb0Fzc2V0XwUHbGFuZE51bQEKa2V5TmZ0TmFtZQIHbGFuZE51bQhsYW5kU2l6ZQkArAICCQCsAgIFCkxBTkRQUkVGSVgFB2xhbmROdW0FCGxhbmRTaXplARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBB2Fzc2V0SWQJAKwCAgIJbmZ0T3duZXJfBQdhc3NldElkARBrZXlEdWNrSWRUb093bmVyAQdhc3NldElkCQCsAgICCmR1Y2tPd25lcl8FB2Fzc2V0SWQBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBB2Fzc2V0SWQJAKwCAgILc3Rha2VkVGltZV8FB2Fzc2V0SWQBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBB2Fzc2V0SWQJAKwCAgILaW5mcmFMZXZlbF8FB2Fzc2V0SWQBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIHYXNzZXRJZAlvd25lckFkZHIJAKwCAgkArAICCQCsAgICHGluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcl8FB2Fzc2V0SWQCAV8FCW93bmVyQWRkcgEfa2V5UHJlc2FsZUFydEFjdGl2YXRlZEJ5QXNzZXRJZAEHYXNzZXRJZAkArAICAhRwcmVzYWxlQXJ0QWN0aXZhdGVkXwUHYXNzZXRJZAEna2V5UHJlc2FsZUFydEFjdGl2YXRlZEJ5QXNzZXRJZEFuZE93bmVyAgdhc3NldElkCW93bmVyQWRkcgkArAICCQCsAgIJAKwCAgIlcHJlc2FsZUFydEFjdGl2YXRlZEJ5QXNzZXRJZEFuZE93bmVyXwUHYXNzZXRJZAIBXwUJb3duZXJBZGRyASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIEdHlwZQdhc3NldElkCQC5CQIJAMwIAgINbGFuZEFydFN0YXR1cwkAzAgCBQR0eXBlCQDMCAIFB2Fzc2V0SWQFA25pbAIBXwEla2V5TGFuZEFydFN0YXR1c0J5VHlwZUFzc2V0SWRBbmRPd25lcgMEdHlwZQdhc3NldElkCW93bmVyQWRkcgkAuQkCCQDMCAICImxhbmRBcnRTdGF0dXNCeVR5cGVBc3NldElkQW5kT3duZXIJAMwIAgUEdHlwZQkAzAgCBQdhc3NldElkCQDMCAIFCW93bmVyQWRkcgUDbmlsAgFfARRrZXlTdGFrZWREdWNrQnlPd25lcgEJb3duZXJBZGRyCQCsAgICEnN0YWtlZER1Y2tCeU93bmVyXwUJb3duZXJBZGRyASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwduZnRUeXBlB2Fzc2V0SWQJb3duZXJBZGRyCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIgc3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcl8FB25mdFR5cGUCAV8FB2Fzc2V0SWQCAV8FCW93bmVyQWRkcgERa2V5TGFuZE51bVRvT3duZXIBB2xhbmROdW0JAKwCAgIKbGFuZE93bmVyXwUHbGFuZE51bQERa2V5QmFja3BhY2tCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICCWJhY2tQYWNrXwULZHVja0Fzc2V0SWQBEmtleVdhcmVob3VzZUJ5TGFuZAELbGFuZEFzc2V0SWQJAKwCAgIKd2FyZUhvdXNlXwULbGFuZEFzc2V0SWQBD2tleUR1Y2tMb2NhdGlvbgELZHVja0Fzc2V0SWQJAKwCAgINZHVja0xvY2F0aW9uXwULZHVja0Fzc2V0SWQBDWtleUR1Y2tIZWFsdGgBC2R1Y2tBc3NldElkCQCsAgICC2R1Y2tIZWFsdGhfBQtkdWNrQXNzZXRJZAERa2V5UmVzUHJvcG9ydGlvbnMAAhNyZXNUeXBlc1Byb3BvcnRpb25zARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBCW93bmVyQWRkcgkArAICAhNzdGFrZWRMYW5kc0J5T3duZXJfBQlvd25lckFkZHIBCmtleUJsb2NrZWQAAhBjb250cmFjdHNCbG9ja2VkARVrZXlVc2VyR3dsUmVsZWFzZVRpbWUBCHVzZXJBZGRyCQCsAgICGiVzJXNfX3VzZXJHd2xSZWxlYXNlVGltZV9fBQh1c2VyQWRkcgAKcmVjTGFuZE51bQAAAAtyZWNMYW5kU2l6ZQABAAtyZWNUZXJyYWlucwACAAxyZWNDb250aW5lbnQAAwAPbG9jSWR4Q29udGluZW50AAAACmxvY0lkeFR5cGUAAQAIbG9jSWR4SWQAAgAKYnBJZHhMZXZlbAAAAAhicElkeFJlcwABAAhicElkeE1hdAACAAlicElkeFByb2QAAwAId2hJZHhWb2wAAAAId2hJZHhSZXMAAQAId2hJZHhNYXQAAgAJd2hJZHhQcm9kAAMADndoSWR4TG9ja2VkVm9sAAQAC2NsYWltTW9kZVdoAAAADWNsYWltTW9kZUR1Y2sAAQATY2xhaW1Nb2RlV2hUaGVuRHVjawACAQhhc1N0cmluZwEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAFAXMJAAIBAhhmYWlsIHRvIGNhc3QgaW50byBTdHJpbmcBE2Rpc3RyaWJ1dGVCeVdlaWdodHMCBXRvdGFsB3dlaWdodHMEA3N1bQkAZAIJAGQCCQBkAgkAZAIJAGQCCQCRAwIFB3dlaWdodHMAAAkAkQMCBQd3ZWlnaHRzAAEJAJEDAgUHd2VpZ2h0cwACCQCRAwIFB3dlaWdodHMAAwkAkQMCBQd3ZWlnaHRzAAQJAJEDAgUHd2VpZ2h0cwAFAwkAZwIAAAUDc3VtCQACAQIQWmVybyB3ZWlnaHRzIHN1bQQFbm9ybTYJAGsDBQV0b3RhbAUFTVVMVDYFA3N1bQoBCm5vcm1hbGl6ZXICA2FjYwRlbGVtCQDNCAIFA2FjYwkAawMFBGVsZW0FBW5vcm02BQVNVUxUNgoAAiRsBQd3ZWlnaHRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpub3JtYWxpemVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGARJnZXROZWVkZWRNYXRlcmlhbHMBBXRvdGFsBAVwcm9wcwkAtQkCCQEFdmFsdWUBCQCiCAEJARFrZXlSZXNQcm9wb3J0aW9ucwACAV8DCQECIT0CCQCQAwEFBXByb3BzBQZOVU1SRVMJAAIBAhZXcm9uZyBwcm9wb3J0aW9ucyBkYXRhBAFyCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAACQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwABCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwACCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwADCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAECQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAFBQNuaWwJARNkaXN0cmlidXRlQnlXZWlnaHRzAgUFdG90YWwFAXIBEXN1YnRyYWN0TWF0ZXJpYWxzAwxzaG91bGRVc2VNYXQDaGFzCXRvdGFsTmVlZAQEbmVlZAkBEmdldE5lZWRlZE1hdGVyaWFscwEFCXRvdGFsTmVlZAoBCnN1YnRyYWN0b3ICA2FjYwNpZHgEBnJlc3VsdAkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNoYXMFA2lkeAkAkQMCBQRuZWVkBQNpZHgDCQBmAgAABQZyZXN1bHQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIYTm90IGVub3VnaCBtYXRlcmlhbCBpZHg9CQCkAwEFA2lkeAILLCB5b3UgaGF2ZSAJAJEDAgUDaGFzBQNpZHgCCywgYnV0IG5lZWQgCQCkAwEJAJEDAgUEbmVlZAUDaWR4CQDNCAIFA2FjYwkApAMBBQZyZXN1bHQDBQxzaG91bGRVc2VNYXQKAAIkbAkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpzdWJ0cmFjdG9yAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGBQNoYXMBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwECHByb3BMaXN0DXRlcnJhaW5Db3VudHMNbGFuZFNpemVJbmRleARzaWduAwkBAiE9AgkAkAMBBQhwcm9wTGlzdAUGTlVNUkVTCQACAQIWV3JvbmcgcHJvcG9ydGlvbnMgZGF0YQoBB3VwZGF0ZXICA2FjYwFpBAZyZXN1bHQJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIcHJvcExpc3QFAWkJAGgCCQBoAgUEc2lnbgkAkQMCBQ10ZXJyYWluQ291bnRzBQFpBQ1sYW5kU2l6ZUluZGV4AwkAZgIAAAUGcmVzdWx0CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhZQYW5pYyEgUGllY2VzIG9mIHR5cGU9CQCkAwEFAWkCBywgc2lnbj0JAKQDAQUEc2lnbgIULCAgdGVycmFpbkNvdW50c1tpXT0JAKQDAQkAkQMCBQ10ZXJyYWluQ291bnRzBQFpAhAsIGxhbmRTaXplSW5kZXg9CQCkAwEFDWxhbmRTaXplSW5kZXgJAM0IAgUDYWNjCQCkAwEFBnJlc3VsdAQBcgoAAiRsCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB3VwZGF0ZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYJALkJAgUBcgIBXwERdXBkYXRlUHJvcG9ydGlvbnMDDXRlcnJhaW5Db3VudHMNbGFuZFNpemVJbmRleARzaWduBAhwcm9wTGlzdAkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEJARFrZXlSZXNQcm9wb3J0aW9ucwACCzBfMF8wXzBfMF8wAgFfCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQFCHByb3BMaXN0BQ10ZXJyYWluQ291bnRzBQ1sYW5kU2l6ZUluZGV4BQRzaWduAQ1jb3VudFRlcnJhaW5zAQh0ZXJyYWlucwkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFBAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBQgABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUMAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFEAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBRQABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUYAAQUDbmlsAQ9udW1QaWVjZXNCeVNpemUBCGxhbmRTaXplBAckbWF0Y2gwBQhsYW5kU2l6ZQMJAAACAgFTBQckbWF0Y2gwBQVTU0laRQMJAAACAgFNBQckbWF0Y2gwBQVNU0laRQMJAAACAgFMBQckbWF0Y2gwBQVMU0laRQMJAAACAgJYTAUHJG1hdGNoMAUGWExTSVpFAwkAAAICA1hYTAUHJG1hdGNoMAUHWFhMU0laRQkAAgECEVVua25vd24gbGFuZCBzaXplAQxzdWJPbmVJbkxpc3QDBWFMaXN0A2lkeAZhbW91bnQKAQZzdWJiZXICA2FjYwFpCQDNCAIFA2FjYwMJAAACBQFpBQNpZHgJAKQDAQkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVhTGlzdAUBaQUGYW1vdW50CQCRAwIFBWFMaXN0BQFpBAFyCgACJGwJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUFA25pbAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEGc3ViYmVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRp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tQkCCQELdmFsdWVPckVsc2UCCQCiCAEFBWJwS2V5AhowOjBfMF8wXzBfMF8wOjBfMF8wXzBfMF8wOgIBOgkAzAgCCQCkAwEJAQt2YWx1ZU9yRWxzZQIJALYJAQkAkQMCBQFwBQpicElkeExldmVsAAAJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQFwBQhicElkeFJlcwIBXwUGTlVNUkVTCQCRAwIFAXAFCGJwSWR4UmVzAgswXzBfMF8wXzBfMAkAzAgCAwkAAAIJAJADAQkAtQkCCQCRAwIFAXAFCGJwSWR4TWF0AgFfBQZOVU1SRVMJAJEDAgUBcAUIYnBJZHhNYXQCCzBfMF8wXzBfMF8wCQDMCAIJAJEDAgUBcAUJYnBJZHhQcm9kBQNuaWwBEmdldFdhcmVob3VzZVZvbHVtZQEJdm9sUHJlZml4BAVwYXJ0cwkAtQkCBQl2b2xQcmVmaXgCAV8JAGgCCQBoAgUMV0hNVUxUSVBMSUVSCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXBhcnRzAAEAAQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXBhcnRzAAABDGdldFdhcmVob3VzZQMFd2hLZXkJbGFuZEluZGV4CmluZnJhTGV2ZWwECXZvbFByZWZpeAkArAICCQCsAgIJAKQDAQUJbGFuZEluZGV4AgFfCQCkAwEFCmluZnJhTGV2ZWwEAXAJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQV3aEtleQkArAICBQl2b2xQcmVmaXgCGzowXzBfMF8wXzBfMDowXzBfMF8wXzBfMDo6MAIBOgkAzAgCCQCRAwIFAXAFCHdoSWR4Vm9sCQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUBcAUId2hJZHhSZXMCAV8FBk5VTVJFUwkAkQMCBQFwBQh3aElkeFJlcwILMF8wXzBfMF8wXzAJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQFwBQh3aElkeE1hdAIBXwUGTlVNUkVTCQCRAwIFAXAFCHdoSWR4TWF0AgswXzBfMF8wXzBfMAkAzAgCCQCRAwIFAXAFCXdoSWR4UHJvZAkAzAgCCQCRAwIFAXAFDndoSWR4TG9ja2VkVm9sBQNuaWwBGWdldFdhcmVob3VzZUN1cnJSZXNWb2x1bWUB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AwkBAiE9AgkAkAMBBQhyZXNQYXJ0cwUGTlVNUkVTCQACAQIgQWxsIDYgcmVzb3VyY2VzIHNob3VsZCBiZSBwYXNzZWQDCQECIT0CCQCQAwEFCG1hdFBhcnRzBQZOVU1SRVMJAAIBAiBBbGwgNiBtYXRlcmlhbHMgc2hvdWxkIGJlIHBhc3NlZAQMY3VycldoUmVzVm9sCQEZZ2V0V2FyZWhvdXNlQ3VyclJlc1ZvbHVtZQEFCWN1cnJlbnRXaAQMY3VycldoTWF0Vm9sCQEZZ2V0V2FyZWhvdXNlQ3Vyck1hdFZvbHVtZQEFCWN1cnJlbnRXaAQOY3VycldoR29vZHNWb2wJARtnZXRXYXJlaG91c2VDdXJyR29vZHNWb2x1bWUBBQljdXJyZW50V2gED2N1cnJXaExvY2tlZFZvbAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWN1cnJlbnRXaAUOd2hJZHhMb2NrZWRWb2wEC3doU3BhY2VMZWZ0CQBlAgkAZQIJAGUCCQBlAgkBEmdldFdhcmVob3VzZVZvbHVtZQEJAJEDAgUJY3VycmVudFdoBQh3aElkeFZvbAUMY3VycldoUmVzVm9sBQxjdXJyV2hNYXRWb2wFDmN1cnJXaEdvb2RzVm9sBQ9jdXJyV2hMb2NrZWRWb2wECWN1cnJXaFJlcwkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8ECWN1cnJXaE1hdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhNYXQCAV8ECmN1cnJXaFByb2QDCQAAAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAIABQNuaWwJALUJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAIBXwQOY3VycmVudFBhY2tSZXMJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMCAV8EDmN1cnJlbnRQYWNrTWF0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBA9jdXJyZW50UGFja1Byb2QDCQAAAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgAFA25pbAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAV8KAQNtdlICA2FjYwRpdGVtBAFpCAUDYWNjAl8xBAJhbQkBDXBhcnNlSW50VmFsdWUBBQRpdGVtBAN3aHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQljdXJyV2hSZXMFAWkEA2JwcgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmN1cnJlbnRQYWNrUmVzBQFpAwkAAAIFAmFtAAAJAJYKBAkAZAIFAWkAAQkAzQgCCAUDYWNjAl8yCQCRAwIFCWN1cnJXaFJlcwUBaQkAzQgCCAUDYWNjAl8zCQCRAwIFDmN1cnJlbnRQYWNrUmVzBQFpCAUDYWNjAl80AwkAZgIFAmFtAAADCQBmAgUCYW0FA2JwcgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byB0YWtlIAUEaXRlbQIZIGZyb20gYmFja3BhY2ssIGJ1dCBvbmx5IAkApAMBBQNicHICCiBhdmFpbGFibGUJAJYKBAkAZAIFAWkAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGQCBQN3aHIFAmFtCQDNCAIIBQNhY2MCXzMJAKQDAQkAZQIFA2JwcgUCYW0JAGQCCAUDYWNjAl80BQJhbQMJAGYCCQEBLQEFAmFtBQN3aHIJAAIBCQCsAgIJAKwCAgkArAICCQCsAgICEEF0dGVtcHQgdG8gdGFrZSAJAKQDAQkBAS0BBQJhbQIaIGZyb20gd2FyZWhvdXNlLCBidXQgb25seSAJAKQDAQUDd2hyAgogYXZhaWxhYmxlCQCWCgQJAGQCBQFpAAEJAM0IAggFA2FjYwJfMgkApAMBCQBkAgUDd2hyBQJhbQkAzQgCCAUDYWNjAl8zCQCkAwEJAGUCBQNicHIFAmFtCQBkAggFA2FjYwJfNAUCYW0EAXIKAAIkbAUIcmVzUGFydHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCWCgQAAAUDbmlsBQNuaWwAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEDbXZSAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGCgEDbXZNAgNhY2MEaXRlbQQBaQgFA2FjYwJfMQQCYW0JAQ1wYXJzZUludFZhbHVlAQUEaXRlbQQDd2htCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJY3VycldoTWF0BQFpBANicG0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5jdXJyZW50UGFja01hdAUBaQMJAAACBQJhbQAACQCWCgQJAGQCBQFpAAEJAM0IAggFA2FjYwJfMgkAkQMCBQljdXJyV2hNYXQFAWkJAM0IAggFA2FjYwJfMwkAkQMCBQ5jdXJyZW50UGFja01hdAUBaQgFA2FjYwJfNAMJAGYCBQJhbQAAAwkAZgIFAmFtBQNicG0JAAIBCQCsAgIJAKwCAgkArAICCQCsAgICEEF0dGVtcHQgdG8gdGFrZSAFBGl0ZW0CGSBmcm9tIGJhY2twYWNrLCBidXQgb25seSAJAKQDAQUDYnBtAgogYXZhaWxhYmxlCQCWCgQJAGQCBQFpAAEJAM0IAggFA2FjYwJfMgkApAMBCQBkAgUDd2htBQJhbQkAzQgCCAUDYWNjAl8zCQCkAwEJAGUCBQNicG0FAmFtCQBkAggFA2FjYwJfNAUCYW0DCQBmAgkBAS0BBQJhbQUDd2htCQACAQkArAICCQCsAgIJAKwCAgkArAICAhBBdHRlbXB0IHRvIHRha2UgCQCkAwEJAQEtAQUCYW0CGiBmcm9tIHdhcmVob3VzZSwgYnV0IG9ubHkgCQCkAwEFA3dobQIKIGF2YWlsYWJsZQkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZAIFA3dobQUCYW0JAM0IAggFA2FjYwJfMwkApAMBCQBlAgUDYnBtBQJhbQkAZAIIBQNhY2MCXzQFAmFtBAFtCgACJGwFCG1hdFBhcnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlgoEAAAFA25pbAUDbmlsCAUBcgJfNAoBBSRmMV8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEDbXZNAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYxXzICCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECBQUkYWNjMAAAAAEAAgADAAQABQAGCgEDbXZQAgNhY2MEaXRlbQQBaQgFA2FjYwJfMQQCYW0JAQ1wYXJzZUludFZhbHVlAQUEaXRlbQQDd2hwCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKY3VycldoUHJvZAUBaQQDYnBwCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPY3VycmVudFBhY2tQcm9kBQFpAwkAAAIFAmFtAAAJAJYKBAkAZAIFAWkAAQkAzQgCCAUDYWNjAl8yCQCRAwIFCmN1cnJXaFByb2QFAWkJAM0IAggFA2FjYwJfMwkAkQMCBQ9jdXJyZW50UGFja1Byb2QFAWkIBQNhY2MCXzQDCQBmAgUCYW0AAAMJAGYCBQJhbQUDYnBwCQACAQkArAICCQCsAgIJAKwCAgkArAICAhBBdHRlbXB0IHRvIHRha2UgBQRpdGVtAhkgZnJvbSBiYWNrcGFjaywgYnV0IG9ubHkgCQCkAwEFA2JwcAIKIGF2YWlsYWJsZQkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZAIFA3docAUCYW0JAM0IAggFA2FjYwJfMwkApAMBCQBlAgUDYnBwBQJhbQkAZAIIBQNhY2MCXzQFAmFtAwkAZgIJAQEtAQUCYW0FA3docAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byB0YWtlIAkApAMBCQEBLQEFAmFtAhogZnJvbSB3YXJlaG91c2UsIGJ1dCBvbmx5IAkApAMBBQN3aHACCiBhdmFpbGFibGUJAJYKBAkAZAIFAWkAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGQCBQN3aHAFAmFtCQDNCAIIBQNhY2MCXzMJAKQDAQkAZQIFA2JwcAUCYW0JAGQCCAUDYWNjAl80BQJhbQQBcAoAAiRsBQlwcm9kUGFydHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCWCgQAAAUDbmlsBQNuaWwIBQFtAl80CgEFJGYyXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQNtdlACBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjJfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDUwCQEFJGYyXzICCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgQIdm9sU2FsZG8IBQFwAl80AwkAZgIFCHZvbFNhbGRvBQt3aFNwYWNlTGVmdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIVQXR0ZW1wdCB0byBwdXQgdG90YWwgCQCkAwEFCHZvbFNhbGRvAhEgc3R1ZmYsIGJ1dCBvbmx5IAkApAMBBQt3aFNwYWNlTGVmdAIVIHdhcmVob3VzZSBzcGFjZSBsZWZ0CQCYCgYJALkJAggFAXICXzICAV8JALkJAggFAW0CXzICAV8JALkJAggFAXACXzICAV8JALkJAggFAXICXzMCAV8JALkJAggFAW0CXzMCAV8JALkJAggFAXACXzMCAV8BEmV4cGVkaXRpb25JbnRlcm5hbAIGY2FsbGVyBHR4SWQECHVzZXJBZGRyCQClCAEFBmNhbGxlcgQGYmlnTnVtCQEDYWJzAQkAngMBBQR0eElkBAdmcmVlTnVtCQELdmFsdWVPckVsc2UCCQCfCAEJARJrZXlOZXh0RnJlZUxhbmROdW0ACQBkAgUPUFJFU0FMRU5VTUxBTkRTAAEEB2xhbmROdW0JAKQDAQUHZnJlZU51bQQMY29udGluZW50SWR4CQCgAwEJALsCAgUGYmlnTnVtBQVGSVZFWAQIdGVycmFpbnMJAQtnZW5UZXJyYWlucwIFBmJpZ051bQUMY29udGluZW50SWR4BAljb250aW5lbnQJAJEDAgUKY29udGluZW50cwUMY29udGluZW50SWR4BAVpc3N1ZQkAwggFCQEKa2V5TmZ0TmFtZQIFB2xhbmROdW0CAVMJALkJAgkAzAgCBQdsYW5kTnVtCQDMCAICAVMJAMwIAgUIdGVycmFpbnMJAMwIAgUJY29udGluZW50BQNuaWwCAV8AAQAABwQHYXNzZXRJZAkAuAgBBQVpc3N1ZQQCaWQJANgEAQUHYXNzZXRJZAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESa2V5TmV4dEZyZWVMYW5kTnVtAAkAZAIFB2ZyZWVOdW0AAQkAzAgCBQVpc3N1ZQkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5TGFuZFRvQXNzZXRJZAEFB2xhbmROdW0FAmlkCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQJpZAUIdXNlckFkZHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUxhbmROdW1Ub093bmVyAQUHbGFuZE51bQUIdXNlckFkZHIJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQUCaWQAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIFAmlkBQh1c2VyQWRkcgAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBmNhbGxlcgABBQdhc3NldElkBQNuaWwJAJQKAgUCaWQFCWNvbnRpbmVudAEQZXhwZWRpdGlvbkNvbW1vbgUMc2hvdWxkVXNlTWF0BmNhbGxlcgR0eElkB21lc3NhZ2UDc2lnAwkBASEBCQDEEwMFB21lc3NhZ2UFA3NpZwUDcHViCQACAQIYc2lnbmF0dXJlIGRvZXMgbm90IG1hdGNoBAVwYXJ0cwkAtQkCCQCwCQEFB21lc3NhZ2UCATsEAmhwCQC1CQIJAJEDAgkAtQkCCQCRAwIFBXBhcnRzAAACAXwAAAIBXwQFY3VySFAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJocAAABAVuZXdIUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmhwAAEECmxvY0FuZFRpbWUJALUJAgkAkQMCBQVwYXJ0cwABAgE6BA50YXJnZXRMb2NhdGlvbgkAtQkCCQCRAwIFCmxvY0FuZFRpbWUAAAIBXwMJAQIhPQIJAJEDAgUOdGFyZ2V0TG9jYXRpb24AAQIBRQkAAgECK2V4cGVkaXRpb24gdGFyZ2V0IGxvY2F0aW9uIHR5cGUgc2hvdWxkIGJlIEUEBHRpbWUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpsb2NBbmRUaW1lAAEDAwkAZgIFBHRpbWUJAGQCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAURRklWRU1JTlVURVNNSUxMSVMGCQBmAgkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBRFGSVZFTUlOVVRFU01JTExJUwUEdGltZQkAAgECEnNpZ25hdHVyZSBvdXRkYXRlZAQIdXNlckFkZHIJAKUIAQUGY2FsbGVyBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFCHVzZXJBZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEDG9sZEZyb21TdGF0ZQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgAZAMJAQIhPQIFDG9sZEZyb21TdGF0ZQUFY3VySFAJAAIBCQCsAgIJAKwCAgkArAICAgpvbGRIZWFsdGg9CQCkAwEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoAGQCLyBmcm9tIHN0YXRlIGRvZXMgbm90IG1hdGNoIG9uZSBmcm9tIGZsaWdodCBsb2c9CQCkAwEFBWN1ckhQAwkAZwIAAAUFY3VySFAJAAIBAh5Zb3UgY2FuJ3QgZmx5IHdpdGggemVybyBoZWFsdGgDCQBnAgAABQVuZXdIUAkAlAoCCQDNCAIDCQEBIQEFDHNob3VsZFVzZU1hdAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZjYWxsZXIFB0VYUFVTRE4FC3VzZG5Bc3NldElkBQNuaWwFA25pbAkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAAAAgAEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAVtTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQGbmV3TWF0CQC5CQIJARFzdWJ0cmFjdE1hdGVyaWFscwMFDHNob3VsZFVzZU1hdAUFbUxpc3QFDEVYUE1BVEVSSUFMUwIBXwQBZQkBEmV4cGVkaXRpb25JbnRlcm5hbAIFBmNhbGxlcgUEdHhJZAQCaWQICAUBZQJfMgJfMQkAlAoCCQDNCAIJAM0IAgkAzQgCCAUBZQJfMQkBC1N0cmluZ0VudHJ5AgkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQC5CQIJAMwIAggIBQFlAl8yAl8yCQDMCAICAUwJAMwIAgUCaWQFA25pbAIBXwkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAUFbmV3SFAJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwkAzAgCBQZuZXdNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwCAToFAmlkAQxhcHBseUJvbnVzZXMCC2xhbmRBc3NldElkBnBpZWNlcwQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAECWFydFBpZWNlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAMJAQt2YWx1ZU9yRWxzZQIJAKAIAQkBH2tleVByZXNhbGVBcnRBY3RpdmF0ZWRCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAcFBnBpZWNlcwAACQBkAgkAZAIFD0RBSUxZUkVTQllQSUVDRQkAawMFD0RBSUxZUkVTQllQSUVDRQUKaW5mcmFMZXZlbAAECQBrAwUPREFJTFlSRVNCWVBJRUNFCQBoAgUJYXJ0UGllY2VzAAMJAGgCBQZwaWVjZXMAFAEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBGFkZHIJY2xhaW1Nb2RlDWxhbmRBc3NldElkSW4EDSR0MDIzNTk4MjQxMzcDCQAAAgUJY2xhaW1Nb2RlBQtjbGFpbU1vZGVXaAkAlAoCBQ1sYW5kQXNzZXRJZEluCQELdmFsdWVPckVsc2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgQDbG9jCQC1CQIJAQV2YWx1ZQEFC2N1ckxvY2F0aW9uAgFfAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUwJAAIBCQCsAgIJAKwCAgIWRHVjayBsb2NhdGlvbiB0eXBlIGlzIAkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCESwgYnV0IHNob3VsZCBiZSBMCQCUCgIJAJEDAgUDbG9jBQhsb2NJZHhJZAULZHVja0Fzc2V0SWQEC2xhbmRBc3NldElkCAUNJHQwMjM1OTgyNDEzNwJfMQQGZHVja0lkCAUNJHQwMjM1OTgyNDEzNwJfMgQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAQJc2F2ZWRUaW1lCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUHdGltZUtleQkArAICCQCsAgICBUxhbmQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAFkCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwkAlgoEBQZkdWNrSWQFC2xhbmRBc3NldElkBQFkBQlzYXZlZFRpbWUBEGNsYWltUmVzSW50ZXJuYWwEBGFkZHIGYW1vdW50CWNsYWltTW9kZQ1sYW5kQXNzZXRJZEluAwkAZgIAAAUGYW1vdW50CQACAQIPTmVnYXRpdmUgYW1vdW50BAFjCQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBQRhZGRyBQljbGFpbU1vZGUFDWxhbmRBc3NldElkSW4ECGxhbmRTaXplCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBCQCRAwIIBQFjAl8zBQtyZWNUZXJyYWlucwQJZGVsdGFUaW1lCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAIBQFjAl80AwkAZgIAAAUJZGVsdGFUaW1lCQACAQkArAICCQCsAgIJAKwCAgImU2F2ZWQgdGltZXN0YW1wIGlzIGluIGZ1dHVyZSwgc2F2ZWQgPSAJAKQDAQgFAWMCXzQCDCwgY3VycmVudCA9IAkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQUIbGFuZFNpemUEFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAQxhcHBseUJvbnVzZXMCCAUBYwJfMgUGcGllY2VzBAhhdmFpbFJlcwkAawMFCWRlbHRhVGltZQkAaAIFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UFBnBpZWNlcwUJREFZTUlMTElTAwkAZgIFBmFtb3VudAUIYXZhaWxSZXMJAAIBCQCsAgIJAKwCAgkArAICAiJOb3QgZW5vdWdoIHJlc291cmNlcywgYXZhaWxhYmxlID0gCQCkAwEFCGF2YWlsUmVzAg4sIHJlcXVlc3RlZCA9IAkApAMBBQZhbW91bnQEDG5ld0RlbHRhVGltZQkAawMJAGUCBQhhdmFpbFJlcwUGYW1vdW50BQlEQVlNSUxMSVMJAGgCBRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBQZwaWVjZXMEDG5ld1RpbWVzdGFtcAkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQxuZXdEZWx0YVRpbWUECWxhbmRJbmRleAkAaQIFBnBpZWNlcwUFU1NJWkUECnJlc1RvQ2xhaW0JAQl2aXJ0Q2xhaW0EBQ10ZXJyYWluQ291bnRzCQBlAgUJZGVsdGFUaW1lBQxuZXdEZWx0YVRpbWUFCWxhbmRJbmRleAUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBCAUBYwJfMgQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEIBQFjAl8yAAAECWN1cnJlbnRXaAkBDGdldFdhcmVob3VzZQMFBXdoS2V5BQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwEDGN1cnJXaFJlc1ZvbAkBGWdldFdhcmVob3VzZUN1cnJSZXNWb2x1bWUBBQljdXJyZW50V2gEDGN1cnJXaE1hdFZvbAkBGWdldFdhcmVob3VzZUN1cnJNYXRWb2x1bWUBBQljdXJyZW50V2gEDmN1cnJXaEdvb2RzVm9sCQEbZ2V0V2FyZWhvdXNlQ3Vyckdvb2RzVm9sdW1lAQUJY3VycmVudFdoBA9jdXJyV2hMb2NrZWRWb2wJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQljdXJyZW50V2gFDndoSWR4TG9ja2VkVm9sBAt3aFNwYWNlTGVmdAkAZQIJAGUCCQBlAgkAZQIJARJnZXRXYXJlaG91c2VWb2x1bWUBCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhWb2wFDGN1cnJXaFJlc1ZvbAUMY3VycldoTWF0Vm9sBQ5jdXJyV2hHb29kc1ZvbAUPY3VycldoTG9ja2VkVm9sAwMJAAACBQljbGFpbU1vZGUFC2NsYWltTW9kZVdoCQBmAgUGYW1vdW50BQt3aFNwYWNlTGVmdAcJAAIBCQCsAgIJAKwCAgIFT25seSAJAKQDAQULd2hTcGFjZUxlZnQCGCBzcGFjZSBsZWZ0IGluIHdhcmVob3VzZQQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEIBQFjAl8xBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEDmN1cnJlbnRQYWNrUmVzCQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzAgFfBAxjdXJyZW50V2hSZXMJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfBA0kdDAyNjc4NTI3Mjg4AwkAAAIFCWNsYWltTW9kZQULY2xhaW1Nb2RlV2gJAJQKAgkBBmFkZFJlcwUFDGN1cnJlbnRXaFJlcwUNdGVycmFpbkNvdW50cwkAZQIFCWRlbHRhVGltZQUMbmV3RGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzAwkAAAIFCWNsYWltTW9kZQUNY2xhaW1Nb2RlRHVjawkAlAoCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMJAQZhZGRSZXMFBQ5jdXJyZW50UGFja1JlcwUNdGVycmFpbkNvdW50cwkAZQIFCWRlbHRhVGltZQUMbmV3RGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAQ1kaXN0cmlidXRlUmVzBAUMY3VycmVudFdoUmVzBQ5jdXJyZW50UGFja1JlcwUKcmVzVG9DbGFpbQULd2hTcGFjZUxlZnQEBXdoUmVzCAUNJHQwMjY3ODUyNzI4OAJfMQQFYnBSZXMIBQ0kdDAyNjc4NTI3Mjg4Al8yCQCXCgUJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQgFAWMCXzIFDG5ld1RpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYCAUBYwJfMgUEYWRkcgUMbmV3VGltZXN0YW1wBQNuaWwFBWJwS2V5CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgUFYnBSZXMJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwFBXdoS2V5CQDMCAIJAJEDAgUJY3VycmVudFdoBQh3aElkeFZvbAkAzAgCBQV3aFJlcwkAzAgCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhNYXQJAMwIAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAkAzAgCCQCRAwIFCWN1cnJlbnRXaAUOd2hJZHhMb2NrZWRWb2wFA25pbAEIY2xhaW1BbGwEBGFkZHILbGFuZEFzc2V0SWQGcGllY2VzCWNsYWltTW9kZQQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAQJc2F2ZWRUaW1lCQEFdmFsdWUBCQCfCAEFB3RpbWVLZXkECGF2YWlsUmVzCQBoAgkAawMJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUJc2F2ZWRUaW1lCQEMYXBwbHlCb251c2VzAgULbGFuZEFzc2V0SWQFBnBpZWNlcwUJREFZTUlMTElTBQZwaWVjZXMJARBjbGFpbVJlc0ludGVybmFsBAUEYWRkcgUIYXZhaWxSZXMFCWNsYWltTW9kZQULbGFuZEFzc2V0SWQBDXVwSW5mcmFDb21tb24EDHNob3VsZFVzZU1hdAZjYWxsZXINcGF5bWVudEFtb3VudAtsYW5kQXNzZXRJZAQEYWRkcgkApQgBBQZjYWxsZXIEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFE2NsYWltTW9kZVdoVGhlbkR1Y2sFC2xhbmRBc3NldElkBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQIaW5mcmFLZXkJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQgFAWMCXzIECGN1ckxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEFCGluZnJhS2V5AAADCQBnAgUIY3VyTGV2ZWwAAwkAAgECJkN1cnJlbnRseSBtYXggaW5mcmFzdHJ1Y3R1cmUgbGV2ZWwgPSAzBAhuZXdMZXZlbAkAZAIFCGN1ckxldmVsAAEEBGNvc3QJAGsDBRVJbmZyYVVwZ3JhZGVDb3N0U1VzZG4JAGgCBQZwaWVjZXMFCG5ld0xldmVsBQVTU0laRQMDCQEBIQEFDHNob3VsZFVzZU1hdAkBAiE9AgUNcGF5bWVudEFtb3VudAUEY29zdAcJAAIBCQCsAgICG1BheW1lbnQgYXR0YWNoZWQgc2hvdWxkIGJlIAkApAMBBQRjb3N0BAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQgFAWMCXzEEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQFbUxpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8EBm5ld01hdAkAuQkCCQERc3VidHJhY3RNYXRlcmlhbHMDBQxzaG91bGRVc2VNYXQFBW1MaXN0CQBrAwURSW5mcmFVcGdyYWRlQ29zdFMJAGgCBQZwaWVjZXMFCG5ld0xldmVsBQVTU0laRQIBXwQLY2xhaW1SZXN1bHQJAQhjbGFpbUFsbAQFBGFkZHIIBQFjAl8yBQZwaWVjZXMFE2NsYWltTW9kZVdoVGhlbkR1Y2sEBndoRGF0YQgFC2NsYWltUmVzdWx0Al81BApuZXdWb2xEYXRhCQC5CQIJAMwIAgkAkQMCCQC1CQIJAJEDAgUGd2hEYXRhBQh3aElkeFZvbAIBXwAACQDMCAIJAKQDAQUIbmV3TGV2ZWwFA25pbAIBXwkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFCGluZnJhS2V5BQhuZXdMZXZlbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIIBQFjAl8yBQRhZGRyBQhuZXdMZXZlbAkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAkQMCCAULY2xhaW1SZXN1bHQCXzMFCGJwSWR4UmVzCQDMCAIFBm5ld01hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgkAzAgCCQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzQJALkJAgkAzAgCBQpuZXdWb2xEYXRhCQDMCAIJAJEDAgUGd2hEYXRhBQh3aElkeFJlcwkAzAgCCQCRAwIFBndoRGF0YQUId2hJZHhNYXQJAMwIAgkAkQMCBQZ3aERhdGEFCXdoSWR4UHJvZAkAzAgCCQCRAwIFBndoRGF0YQUOd2hJZHhMb2NrZWRWb2wFA25pbAIBOgUDbmlsCAULY2xhaW1SZXN1bHQCXzEFCG5ld0xldmVsARJhY3RpdmF0ZVByZXNhbGVBcnQCBGFkZHINbGFuZEFzc2V0SWRJbgQBYwkBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwUEYWRkcgUTY2xhaW1Nb2RlV2hUaGVuRHVjawUNbGFuZEFzc2V0SWRJbgQLbGFuZEFzc2V0SWQIBQFjAl8yBA1hY3RpdmF0aW9uS2V5CQEfa2V5UHJlc2FsZUFydEFjdGl2YXRlZEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAwkBC3ZhbHVlT3JFbHNlAgkAoAgBBQ1hY3RpdmF0aW9uS2V5BwkAAgECJVByZXNhbGUgYXJ0aWZhY3QgaXMgYWxyZWFkeSBhY3RpdmF0ZWQDCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIIBQFjAl8zBQpyZWNMYW5kTnVtBQ9QUkVTQUxFTlVNTEFORFMJAAIBCQCsAgIJAKwCAgkArAICBQpMQU5EUFJFRklYAgEgBQtsYW5kQXNzZXRJZAIlIGlzIG5vdCBlbGlnaWJsZSBmb3IgcHJlc2FsZSBhcnRpZmFjdAQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCAUBYwJfMwULcmVjTGFuZFNpemUEC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwEBQRhZGRyBQtsYW5kQXNzZXRJZAUGcGllY2VzBRNjbGFpbU1vZGVXaFRoZW5EdWNrCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCAULY2xhaW1SZXN1bHQCXzEJAQxCb29sZWFuRW50cnkCBQ1hY3RpdmF0aW9uS2V5BgkBDEJvb2xlYW5FbnRyeQIJASdrZXlQcmVzYWxlQXJ0QWN0aXZhdGVkQnlBc3NldElkQW5kT3duZXICBQtsYW5kQXNzZXRJZAUEYWRkcgYJAQxJbnRlZ2VyRW50cnkCCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAUGcGllY2VzCQEMSW50ZWdlckVudHJ5AgkBJWtleUxhbmRBcnRTdGF0dXNCeVR5cGVBc3NldElkQW5kT3duZXIDBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAUEYWRkcgUGcGllY2VzCQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzIJALkJAggFC2NsYWltUmVzdWx0Al8zAgE6CQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzQJALkJAggFC2NsYWltUmVzdWx0Al81AgE6AQ1tZXJnZUludGVybmFsBwtuZXdMYW5kU2l6ZQhuZXdMZXZlbAdmb3JtdWxhBGFkZHIMbGFuZEFzc2V0SWRzBHR4SWQHbmVlZE1hdAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkCgEKY2hlY2tNZXJnZQIDYWNjC2xhbmRBc3NldElkBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBAlzYXZlZFRpbWUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQd0aW1lS2V5CQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8ECWNvbnRpbmVudAkAkQMCBQFkBQxyZWNDb250aW5lbnQDAwkBAiE9AggFA2FjYwJfMwIACQECIT0CCAUDYWNjAl8zBQljb250aW5lbnQHCQACAQIuTGFuZHMgc2hvdWxkIGJlIG9uIHRoZSBzYW1lIGNvbnRpbmVudCB0byBtZXJnZQQIbGFuZFNpemUJAJEDAgUBZAULcmVjTGFuZFNpemUEB3NpemVzSW4IBQNhY2MCXzEEAWkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAswkCBQdzaXplc0luBQhsYW5kU2l6ZQInWW91IGhhdmVuJ3QgcGFzc2VkIGFsbCB0aGUgbGFuZHMgbmVlZGVkBAhzaXplc091dAkArAICCQCvAgIFB3NpemVzSW4FAWkJALACAgUHc2l6ZXNJbgkAZAIFAWkAAQQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQUIbGFuZFNpemUEBGFydHMJAGQCCAUDYWNjAl8yCQELdmFsdWVPckVsc2UCCQCfCAEJASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIFCkFSVFBSRVNBTEUFC2xhbmRBc3NldElkAwkBC3ZhbHVlT3JFbHNlAgkAoAgBCQEfa2V5UHJlc2FsZUFydEFjdGl2YXRlZEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBwUGcGllY2VzAAAECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAhyZXFMZXZlbAQHJG1hdGNoMAUIbGFuZFNpemUDCQAAAgIBUwUHJG1hdGNoMAADAwkAAAICAU0FByRtYXRjaDAABAMJAAACAgFMBQckbWF0Y2gwAAUDCQAAAgICWEwFByRtYXRjaDAABgkAAgECGk9ubHkgUywgTSwgTCwgWEwgY2FuIG1lcmdlAwkBAiE9AgUKaW5mcmFMZXZlbAUIcmVxTGV2ZWwJAAIBAiJBbGwgbGFuZHMgc2hvdWxkIGJlIG1heGVkIHRvIG1lcmdlBAdsYW5kTnVtCQCRAwIFAWQFCnJlY0xhbmROdW0EDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQJZGVsdGFUaW1lCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFCXNhdmVkVGltZQMJAGYCAAAFCWRlbHRhVGltZQkAAgEJAKwCAgkArAICCQCsAgICJlNhdmVkIHRpbWVzdGFtcCBpcyBpbiBmdXR1cmUsIHNhdmVkID0gCQCkAwEFCXNhdmVkVGltZQIMLCBjdXJyZW50ID0gCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wBBZkYWlseVByb2R1Y3Rpb25CeVBpZWNlCQEMYXBwbHlCb251c2VzAgULbGFuZEFzc2V0SWQFBnBpZWNlcwQJbGFuZEluZGV4CQBpAgUGcGllY2VzBQVTU0laRQQFYnBSZXMJAQZhZGRSZXMFCQC1CQIIBQNhY2MCXzQCAV8FDXRlcnJhaW5Db3VudHMFCWRlbHRhVGltZQUJbGFuZEluZGV4BRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBAVwcm9wcwkBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwECQC1CQIIBQNhY2MCXzYCAV8FDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAD///////////8BBAVsYW5kcwgFA2FjYwJfNwQDaWR4CQDPCAIFBWxhbmRzBQtsYW5kQXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEFA2lkeAkAAgEJAKwCAgIgWW91ciBzdGFrZWQgbGFuZHMgZG9uJ3QgY29udGFpbiAFC2xhbmRBc3NldElkCQCZCgcFCHNpemVzT3V0BQRhcnRzBQljb250aW5lbnQFBWJwUmVzCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAggFA2FjYwJfNQkBC0RlbGV0ZUVudHJ5AQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYBQtsYW5kQXNzZXRJZAUEYWRkcgkBC0RlbGV0ZUVudHJ5AQkBEGtleUxhbmRUb0Fzc2V0SWQBBQdsYW5kTnVtCQELRGVsZXRlRW50cnkBCQEKa2V5TmZ0TmFtZQIFB2xhbmROdW0FCGxhbmRTaXplCQELRGVsZXRlRW50cnkBCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICBQtsYW5kQXNzZXRJZAUEYWRkcgkBC0RlbGV0ZUVudHJ5AQkBH2tleVByZXNhbGVBcnRBY3RpdmF0ZWRCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQkBJ2tleVByZXNhbGVBcnRBY3RpdmF0ZWRCeUFzc2V0SWRBbmRPd25lcgIFC2xhbmRBc3NldElkBQRhZGRyCQELRGVsZXRlRW50cnkBCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQkBJWtleUxhbmRBcnRTdGF0dXNCeVR5cGVBc3NldElkQW5kT3duZXIDBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAUEYWRkcgkBC0RlbGV0ZUVudHJ5AQkBEWtleUxhbmROdW1Ub093bmVyAQUHbGFuZE51bQkBC0RlbGV0ZUVudHJ5AQkBEmtleVdhcmVob3VzZUJ5TGFuZAEFC2xhbmRBc3NldElkCQEEQnVybgIJANkEAQULbGFuZEFzc2V0SWQAAQUFcHJvcHMJANEIAgUFbGFuZHMJAQV2YWx1ZQEFA2lkeAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEB3Byb3BTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBEWtleVJlc1Byb3BvcnRpb25zAAILMF8wXzBfMF8wXzAECGxhbmRzS2V5CQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUEYWRkcgQIbGFuZHNTdHIJAKIIAQUIbGFuZHNLZXkEB2xhbmRzSW4DCQEJaXNEZWZpbmVkAQUIbGFuZHNTdHIJAL0JAgkBBXZhbHVlAQUIbGFuZHNTdHICAV8FA25pbAQBcgoAAiRsBQxsYW5kQXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCZCgcFB2Zvcm11bGEAAAIACQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwUDbmlsBQdwcm9wU3RyBQdsYW5kc0luCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpjaGVja01lcmdlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQQJY29udGluZW50CAUBcgJfMwQMY29udGluZW50SWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgUKY29udGluZW50cwUJY29udGluZW50CQCsAgICE1Vua25vd24gY29udGluZW50OiAFCWNvbnRpbmVudAQIdGVycmFpbnMJAQtnZW5UZXJyYWlucwIJAQNhYnMBCQCeAwEFBHR4SWQFDGNvbnRpbmVudElkeAQHZnJlZU51bQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQESa2V5TmV4dEZyZWVMYW5kTnVtAAkAZAIFD1BSRVNBTEVOVU1MQU5EUwABBApuZXdMYW5kTnVtCQCkAwEFB2ZyZWVOdW0EBWlzc3VlCQDCCAUJAQprZXlOZnROYW1lAgUKbmV3TGFuZE51bQULbmV3TGFuZFNpemUJALkJAgkAzAgCBQpuZXdMYW5kTnVtCQDMCAIFC25ld0xhbmRTaXplCQDMCAIFCHRlcnJhaW5zCQDMCAIFCWNvbnRpbmVudAUDbmlsAgFfAAEAAAcEB2Fzc2V0SWQJALgIAQUFaXNzdWUEDm5ld0xhbmRBc3NldElkCQDYBAEFB2Fzc2V0SWQEBm5ld01hdAkAuQkCCQERc3VidHJhY3RNYXRlcmlhbHMDCQBmAgUHbmVlZE1hdAAACQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBQduZWVkTWF0AgFfCQCUCgIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCAUBcgJfNQMJAGYCCQCQAwEIBQFyAl83AAAJAQtTdHJpbmdFbnRyeQIFCGxhbmRzS2V5CQC7CQIIBQFyAl83AgFfCQELRGVsZXRlRW50cnkBBQhsYW5kc0tleQkBDEludGVnZXJFbnRyeQIJARJrZXlOZXh0RnJlZUxhbmROdW0ACQBkAgUHZnJlZU51bQABBQVpc3N1ZQkBC1N0cmluZ0VudHJ5AgkBEGtleUxhbmRUb0Fzc2V0SWQBBQpuZXdMYW5kTnVtBQ5uZXdMYW5kQXNzZXRJZAkBC1N0cmluZ0VudHJ5AgkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFDm5ld0xhbmRBc3NldElkBQRhZGRyCQELU3RyaW5nRW50cnkCCQERa2V5TGFuZE51bVRvT3duZXIBBQpuZXdMYW5kTnVtBQRhZGRyCQEMSW50ZWdlckVudHJ5AgkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQUObmV3TGFuZEFzc2V0SWQIBQFyAl8yCQEMSW50ZWdlckVudHJ5AgkBJWtleUxhbmRBcnRTdGF0dXNCeVR5cGVBc3NldElkQW5kT3duZXIDBQpBUlRQUkVTQUxFBQ5uZXdMYW5kQXNzZXRJZAUEYWRkcggFAXICXzIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFDm5ld0xhbmRBc3NldElkBQhuZXdMZXZlbAkBDEludGVnZXJFbnRyeQIJAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICBQ5uZXdMYW5kQXNzZXRJZAUEYWRkcgUIbmV3TGV2ZWwJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCAUBcgJfNAkAzAgCBQZuZXdNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwCAToJAQtTdHJpbmdFbnRyeQIJARFrZXlSZXNQcm9wb3J0aW9ucwAIBQFyAl82CQELU3RyaW5nRW50cnkCCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQJALkJAgkAzAgCBQljb250aW5lbnQJAMwIAgIBTAkAzAgCBQ5uZXdMYW5kQXNzZXRJZAUDbmlsAgFfCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQRhZGRyAAEFB2Fzc2V0SWQFDm5ld0xhbmRBc3NldElkAQNzMm0DBGFkZHIMbGFuZEFzc2V0SWRzBHR4SWQJAQ1tZXJnZUludGVybmFsBwIBTQADAgRTU1NTBQRhZGRyBQxsYW5kQXNzZXRJZHMFBHR4SWQAAAEDbTJsBQRhZGRyDGxhbmRBc3NldElkcwR0eElkDHNob3VsZFVzZU1hdA1wYXltZW50QW1vdW50BARjb3N0CQBoAgUVSW5mcmFVcGdyYWRlQ29zdFNVc2RuAAQDAwkBASEBBQxzaG91bGRVc2VNYXQJAQIhPQIFDXBheW1lbnRBbW91bnQFBGNvc3QHCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUEY29zdAkBDW1lcmdlSW50ZXJuYWwHAgFMAAQCA1NNTQUEYWRkcgUMbGFuZEFzc2V0SWRzBQR0eElkCQBoAgURSW5mcmFVcGdyYWRlQ29zdFMABAEEbDJ4bAUEYWRkcgxsYW5kQXNzZXRJZHMEdHhJZAxzaG91bGRVc2VNYXQNcGF5bWVudEFtb3VudAQEY29zdAkAaAIFFUluZnJhVXBncmFkZUNvc3RTVXNkbgAvAwMJAQEhAQUMc2hvdWxkVXNlTWF0CQECIT0CBQ1wYXltZW50QW1vdW50BQRjb3N0BwkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFBGNvc3QJAQ1tZXJnZUludGVybmFsBwICWEwABQIFU1NTTUwFBGFkZHIFDGxhbmRBc3NldElkcwUEdHhJZAkAaAIFEUluZnJhVXBncmFkZUNvc3RTAC8BBnhsMnh4bAUEYWRkcgxsYW5kQXNzZXRJZHMEdHhJZAxzaG91bGRVc2VNYXQNcGF5bWVudEFtb3VudAQEY29zdAkAaAIFFUluZnJhVXBncmFkZUNvc3RTVXNkbgA2AwMJAQEhAQUMc2hvdWxkVXNlTWF0CQECIT0CBQ1wYXltZW50QW1vdW50BQRjb3N0BwkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFBGNvc3QJAQ1tZXJnZUludGVybmFsBwIDWFhMAAYCA0xYTAUEYWRkcgUMbGFuZEFzc2V0SWRzBQR0eElkCQBoAgURSW5mcmFVcGdyYWRlQ29zdFMANgELbWVyZ2VDb21tb24FDHNob3VsZFVzZU1hdARhZGRyDXBheW1lbnRBbW91bnQMbGFuZEFzc2V0SWRzBHR4SWQEC21lcmdlUmVzdWx0BAckbWF0Y2gwCQCQAwEFDGxhbmRBc3NldElkcwMJAAACAAQFByRtYXRjaDAJAQNzMm0DBQRhZGRyBQxsYW5kQXNzZXRJZHMFBHR4SWQDCQAAAgADBQckbWF0Y2gwCQEDbTJsBQUEYWRkcgUMbGFuZEFzc2V0SWRzBQR0eElkBQxzaG91bGRVc2VNYXQFDXBheW1lbnRBbW91bnQDCQAAAgAFBQckbWF0Y2gwCQEEbDJ4bAUFBGFkZHIFDGxhbmRBc3NldElkcwUEdHhJZAUMc2hvdWxkVXNlTWF0BQ1wYXltZW50QW1vdW50AwkAAAIAAgUHJG1hdGNoMAkBBnhsMnh4bAUFBGFkZHIFDGxhbmRBc3NldElkcwUEdHhJZAUMc2hvdWxkVXNlTWF0BQ1wYXltZW50QW1vdW50CQACAQINVW5rbm93biBtZXJnZQULbWVyZ2VSZXN1bHQBBnByb2xvZwEBaQMJAQt2YWx1ZU9yRWxzZQIJAKAIAQkBCmtleUJsb2NrZWQABwkAAgECH0NvbnRyYWN0cyBhcmUgdW5kZXIgbWFpbnRlbmFuY2UJAQtTdHJpbmdFbnRyeQIJARFrZXlMYXN0VHhJZEJ5VXNlcgEJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQZAWkBDWNvbnN0cnVjdG9yVjEBCHJlc3RBZGRyAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIRUGVybWlzc2lvbiBkZW5pZWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDmtleVJlc3RBZGRyZXNzAAUIcmVzdEFkZHIFA25pbAFpAQpzZXRCbG9ja2VkAQlpc0Jsb2NrZWQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhFwZXJtaXNzaW9uIGRlbmllZAkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBCmtleUJsb2NrZWQABQlpc0Jsb2NrZWQFA25pbAFpAQlzdGFrZUxhbmQABAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEB2Fzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIDCQECIT0CCAUDcG10BmFtb3VudAABCQACAQkArAICCQCsAgICBE5GVCAFCkxBTkRQUkVGSVgCJCB0b2tlbiBzaG91bGQgYmUgYXR0YWNoZWQgYXMgcGF5bWVudAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAMJAQIhPQIIBQVhc3NldAZpc3N1ZXIFBHRoaXMJAAIBAhdVbmtub3duIGlzc3VlciBvZiB0b2tlbgMJAQEhAQkBCGNvbnRhaW5zAggFBWFzc2V0BG5hbWUFCkxBTkRQUkVGSVgJAAIBCQCsAgIJAKwCAgIJT25seSBORlQgBQpMQU5EUFJFRklYAhQgdG9rZW5zIGFyZSBhY2NlcHRlZAQLbGFuZE51bVNpemUJALACAggFBWFzc2V0BG5hbWUABAQHbGFuZE51bQMJAQhjb250YWlucwIFC2xhbmROdW1TaXplAgNYWEwJALMCAgULbGFuZE51bVNpemUAAwMJAQhjb250YWlucwIFC2xhbmROdW1TaXplAgJYTAkAswICBQtsYW5kTnVtU2l6ZQACCQCzAgIFC2xhbmROdW1TaXplAAEDCQEBIQEJAQlpc0RlZmluZWQBCQC2CQEFB2xhbmROdW0JAAIBCQCsAgICHkNhbm5vdCBwYXJzZSBsYW5kIG51bWJlciBmcm9tIAgFBWFzc2V0BG5hbWUEC2xhbmRBc3NldElkCQDYBAEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQDCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAhIgaXMgYWxyZWFkeSBzdGFrZWQEAWQJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEJAJEDAgUBZAULcmVjVGVycmFpbnMEBXByb3BzCQERdXBkYXRlUHJvcG9ydGlvbnMDBQ10ZXJyYWluQ291bnRzCQBpAgkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgUBZAULcmVjTGFuZFNpemUFBVNTSVpFAAEECGxhbmRzU3RyCQCiCAEJARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBBQdhZGRyZXNzBAVsYW5kcwMJAQlpc0RlZmluZWQBBQhsYW5kc1N0cgkAvQkCCQEFdmFsdWUBBQhsYW5kc1N0cgIBXwUDbmlsAwkBD2NvbnRhaW5zRWxlbWVudAIFBWxhbmRzBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgIiWW91ciBzdGFrZWQgbGFuZHMgYWxyZWFkeSBjb250YWluIAULbGFuZEFzc2V0SWQJAMwIAgkBDEludGVnZXJFbnRyeQIFB3RpbWVLZXkIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgFC2xhbmRBc3NldElkBQdhZGRyZXNzCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUHYWRkcmVzcwkAuwkCCQDNCAIFBWxhbmRzBQtsYW5kQXNzZXRJZAIBXwkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQFB2FkZHJlc3MJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUxhbmROdW1Ub093bmVyAQUHbGFuZE51bQUHYWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5UmVzUHJvcG9ydGlvbnMABQVwcm9wcwkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAFpAQt1bnN0YWtlTGFuZAENbGFuZEFzc2V0SWRJbgQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECJHVuc3Rha2UgZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50cwQEYWRkcgkApQgBCAUBaQZjYWxsZXIEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFDWNsYWltTW9kZUR1Y2sFDWxhbmRBc3NldElkSW4EC2xhbmRBc3NldElkCAUBYwJfMgQIbGFuZHNLZXkJARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBBQRhZGRyBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEJAJEDAggFAWMCXzMFC3JlY1RlcnJhaW5zBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQFcHJvcHMJARF1cGRhdGVQcm9wb3J0aW9ucwMFDXRlcnJhaW5Db3VudHMJAGkCBQZwaWVjZXMFBVNTSVpFAP///////////wEEC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwEBQRhZGRyBQtsYW5kQXNzZXRJZAUGcGllY2VzBQ1jbGFpbU1vZGVEdWNrBAVsYW5kcwkAvQkCCQELdmFsdWVPckVsc2UCCQCiCAEFCGxhbmRzS2V5AgACAV8EA2lkeAkAzwgCBQVsYW5kcwULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBBQNpZHgJAAIBCQCsAgICIFlvdXIgc3Rha2VkIGxhbmRzIGRvbid0IGNvbnRhaW4gBQtsYW5kQXNzZXRJZAQBdAgJAQV2YWx1ZQEJAO0HAQUGaGVpZ2h0CXRpbWVzdGFtcAQLcmVsZWFzZVRpbWUJAQt2YWx1ZU9yRWxzZQIJAJoIAgULZ292Q29udHJhY3QJARVrZXlVc2VyR3dsUmVsZWFzZVRpbWUBBQRhZGRyAAADCQBnAgULcmVsZWFzZVRpbWUFAXQJAAIBCQCsAgICOVlvdXIgZ1dMIGFyZSB0YWtpbmcgcGFydCBpbiB2b3RpbmcsIGNhbm5vdCB1bnN0YWtlIHVudGlsIAkApAMBBQtyZWxlYXNlVGltZQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIAAQkA2QQBBQtsYW5kQXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBCQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKTEFORFBSRUZJWAULbGFuZEFzc2V0SWQFBGFkZHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleVJlc1Byb3BvcnRpb25zAAUFcHJvcHMJAMwIAgkBC1N0cmluZ0VudHJ5AggFC2NsYWltUmVzdWx0Al8yCQC5CQIIBQtjbGFpbVJlc3VsdAJfMwIBOgkAzAgCAwkAZgIJAJADAQUFbGFuZHMAAQkBC1N0cmluZ0VudHJ5AgUIbGFuZHNLZXkJALsJAgkA0QgCBQVsYW5kcwkBBXZhbHVlAQUDaWR4AgFfCQELRGVsZXRlRW50cnkBBQhsYW5kc0tleQkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAFpAQlzdGFrZUR1Y2sABAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEB2Fzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIDCQECIT0CCAUDcG10BmFtb3VudAABCQACAQkArAICCQCsAgICBE5GVCAFCkRVQ0tQUkVGSVgCJCB0b2tlbiBzaG91bGQgYmUgYXR0YWNoZWQgYXMgcGF5bWVudAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAMDCQECIT0CCAUFYXNzZXQGaXNzdWVyBQ1pbmN1YmF0b3JBZGRyCQECIT0CCAUFYXNzZXQGaXNzdWVyBQticmVlZGVyQWRkcgcJAAIBCQCsAgIJAKwCAgISVW5rbm93biBpc3N1ZXIgb2YgBQpEVUNLUFJFRklYAgYgdG9rZW4DCQEBIQEJAQhjb250YWlucwIIBQVhc3NldARuYW1lBQpEVUNLUFJFRklYCQACAQkArAICCQCsAgICCU9ubHkgTkZUIAUKRFVDS1BSRUZJWAIUIHRva2VucyBhcmUgYWNjZXB0ZWQECmFzc2V0SWRTdHIJANgEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQphc3NldElkU3RyAwkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQISIGlzIGFscmVhZHkgc3Rha2VkAwkBCWlzRGVmaW5lZAEJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwkAAgEJAKwCAgIdWW91IGFscmVhZHkgc3Rha2VkIG9uZSBkdWNrOiAIBQVhc3NldARuYW1lBAZsb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQphc3NldElkU3RyBAhsb2NhdGlvbgkAoggBBQZsb2NLZXkEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQphc3NldElkU3RyBAhiYWNrcGFjawkAoggBBQVicEtleQkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd0aW1lS2V5CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpEVUNLUFJFRklYCQDYBAEFB2Fzc2V0SWQFB2FkZHJlc3MIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQtTdHJpbmdFbnRyeQIJARBrZXlEdWNrSWRUb093bmVyAQUKYXNzZXRJZFN0cgUHYWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzBQphc3NldElkU3RyBQNuaWwDCQEJaXNEZWZpbmVkAQUIbG9jYXRpb24FA25pbAkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBmxvY0tleQUPREVGQVVMVExPQ0FUSU9OBQNuaWwDCQEJaXNEZWZpbmVkAQUIYmFja3BhY2sFA25pbAkAzQgCCQDNCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkCGjA6MF8wXzBfMF8wXzA6MF8wXzBfMF8wXzA6BQNuaWwJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFCmFzc2V0SWRTdHIAZAUMcHJvbG9nQWN0aW9uAWkBC3Vuc3Rha2VEdWNrAQphc3NldElkU3RyBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIkdW5zdGFrZSBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnRzBAdhc3NldElkCQDZBAEFCmFzc2V0SWRTdHIEB2FkZHJlc3MJAKUIAQgFAWkGY2FsbGVyBAVhc3NldAkBBXZhbHVlAQkA7AcBBQdhc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEJANgEAQUHYXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQDCQEBIQEJAQlpc0RlZmluZWQBCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFB2FkZHJlc3MJAAIBCQCsAgIJAKwCAgIJVGhlIGR1Y2sgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBEGtleUR1Y2tJZFRvT3duZXIBCQDYBAEFB2Fzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFB2FkZHJlc3MJAAIBAhdTdGFrZWQgTkZUIGlzIG5vdCB5b3VycwQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFCmFzc2V0SWRTdHIEBmhlYWx0aAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgAZAMJAQIhPQIFBmhlYWx0aABkCQACAQImUGxlYXNlIGhlYWwgeW91ciBkdWNrIGJlZm9yZSB1bnN0YWtpbmcJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyAAEFB2Fzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQUHdGltZUtleQkAzAgCCQELRGVsZXRlRW50cnkBBQlrZXlIZWFsdGgJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBD2tleUR1Y2tMb2NhdGlvbgEFCmFzc2V0SWRTdHIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBEGtleUR1Y2tJZFRvT3duZXIBBQphc3NldElkU3RyCQDMCAIJAQtEZWxldGVFbnRyeQEJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKRFVDS1BSRUZJWAUKYXNzZXRJZFN0cgUHYWRkcmVzcwkAzAgCCQELRGVsZXRlRW50cnkBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzCQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsAWkBCGNsYWltUmVzAgZhbW91bnQObGFuZEFzc2V0SWRTdHIEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAiVjbGFpbVJlcyBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnRzBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQGcmVzdWx0CQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFBmFtb3VudAUNY2xhaW1Nb2RlRHVjawUObGFuZEFzc2V0SWRTdHIJAJQKAgkAzQgCCQDNCAIJAM0IAggFBnJlc3VsdAJfMQkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfMgkAuQkCCAUGcmVzdWx0Al8zAgE6CQELU3RyaW5nRW50cnkCCAUGcmVzdWx0Al80CQC5CQIIBQZyZXN1bHQCXzUCAToFDHByb2xvZ0FjdGlvbgkAkQMCCAUGcmVzdWx0Al8zBQhicElkeFJlcwFpAQxjbGFpbVJlc1RvV0gCBmFtb3VudA5sYW5kQXNzZXRJZFN0cgQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECJWNsYWltUmVzIGRvZXNuJ3QgcmVxdWlyZSBhbnkgcGF5bWVudHMEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAZyZXN1bHQJARBjbGFpbVJlc0ludGVybmFsBAUEYWRkcgUGYW1vdW50BQtjbGFpbU1vZGVXaAUObGFuZEFzc2V0SWRTdHIJAJQKAgkAzQgCCQDNCAIJAM0IAggFBnJlc3VsdAJfMQkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfMgkAuQkCCAUGcmVzdWx0Al8zAgE6CQELU3RyaW5nRW50cnkCCAUGcmVzdWx0Al80CQC5CQIIBQZyZXN1bHQCXzUCAToFDHByb2xvZ0FjdGlvbgkAkQMCCAUGcmVzdWx0Al81BQh3aElkeFJlcwFpAQZmbGlnaHQCB21lc3NhZ2UDc2lnBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBASEBCQDEEwMFB21lc3NhZ2UFA3NpZwUDcHViCQACAQIYc2lnbmF0dXJlIGRvZXMgbm90IG1hdGNoAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIjZmxpZ2h0IGRvZXNuJ3QgcmVxdWlyZSBhbnkgcGF5bWVudHMEBXBhcnRzCQC1CQIJALAJAQUHbWVzc2FnZQIBOwQCaHAJALUJAgkAkQMCCQC1CQIJAJEDAgUFcGFydHMAAAIBfAAAAgFfBAVjdXJIUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmhwAAAEBW5ld0hQCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCaHAAAQQNbmV3TG9jQW5kVGltZQkAtQkCCQCRAwIFBXBhcnRzAAECAToEC25ld0xvY2F0aW9uCQCRAwIFDW5ld0xvY0FuZFRpbWUAAAQEdGltZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDW5ld0xvY0FuZFRpbWUAAQMDCQBmAgUEdGltZQkAZAIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBRFGSVZFTUlOVVRFU01JTExJUwYJAGYCCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFEUZJVkVNSU5VVEVTTUlMTElTBQR0aW1lCQACAQISc2lnbmF0dXJlIG91dGRhdGVkBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEDG9sZEZyb21TdGF0ZQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgAZAMJAQIhPQIFDG9sZEZyb21TdGF0ZQUFY3VySFAJAAIBCQCsAgIJAKwCAgkArAICAgpvbGRIZWFsdGg9CQCkAwEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoAGQCLyBmcm9tIHN0YXRlIGRvZXMgbm90IG1hdGNoIG9uZSBmcm9tIGZsaWdodCBsb2c9CQCkAwEFBWN1ckhQAwkAZwIAAAUFY3VySFAJAAIBAh5Zb3UgY2FuJ3QgZmx5IHdpdGggemVybyBoZWFsdGgEBmxvY0tleQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBBQZsb2NLZXkFD0RFRkFVTFRMT0NBVElPTgMJAAACBQtuZXdMb2NhdGlvbgULY3VyTG9jYXRpb24JAAIBAiJZb3UgY2FuJ3QgZmx5IHRvIHRoZSBzYW1lIGxvY2F0aW9uCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUGbG9jS2V5AwkAZgIFBW5ld0hQAAAFC25ld0xvY2F0aW9uBQtjdXJMb2NhdGlvbgkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoBQVuZXdIUAkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAUEdW5pdAFpAQlzZXRIZWFsdGgCBmhlYWx0aAtkdWNrQXNzZXRJZAQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMDCQBmAgAABQZoZWFsdGgGCQBmAgUGaGVhbHRoAGQJAAIBAhpIUCBzaG91bGQgYmUgd2l0aGluIDAuLjEwMAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAUGaGVhbHRoCQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsAWkBBGhlYWwCB21hdFR5cGUGYW1vdW50BAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwMJAGYCAAAFB21hdFR5cGUGCQBnAgUHbWF0VHlwZQUGTlVNUkVTCQACAQkArAICAhJVbmtub3duIG1hdGVyaWFsOiAJAKQDAQUHbWF0VHlwZQMJAGcCAAAFBmFtb3VudAkAAgEJAKwCAgIbQW1vdW50IHNob3VsZCBiZSBwb3NpdGl2ZSEgCQCkAwEFBmFtb3VudAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAlvbGRIZWFsdGgJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoAGQDCQBnAgUJb2xkSGVhbHRoAGQJAAIBAhpIUCBzaG91bGQgYmUgPCAxMDAgdG8gaGVhbAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBW1MaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBA1jdXJyZW50QW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFbUxpc3QFB21hdFR5cGUEC2RlbHRhSGVhbHRoCQCXAwEJAMwIAgkAaQIFBmFtb3VudAUISEVBTENPU1QJAMwIAgkAZQIAZAUJb2xkSGVhbHRoBQNuaWwEC3NwZW5kQW1vdW50CQBoAgULZGVsdGFIZWFsdGgFCEhFQUxDT1NUAwkAZgIFC3NwZW5kQW1vdW50BQ1jdXJyZW50QW1vdW50CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCVlvdSBuZWVkIAkApAMBBQtzcGVuZEFtb3VudAIEIG9mIAkAkQMCBQhtYXRUeXBlcwUHbWF0VHlwZQIkIHRvIGhlYWwsIGJ1dCB5b3UgYmFja3BhY2sgY29udGFpbnMgCQCkAwEFDWN1cnJlbnRBbW91bnQEBm5ld01hdAkBDHN1Yk9uZUluTGlzdAMFBW1MaXN0BQdtYXRUeXBlBQtzcGVuZEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoCQBkAgUJb2xkSGVhbHRoBQtkZWx0YUhlYWx0aAkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMJAMwIAgUGbmV3TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6CQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsAWkBDnVwZGF0ZUJhY2twYWNrAgtkdWNrQXNzZXRJZAduZXdQYWNrBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AggFAWkGY2FsbGVyBQ9lY29ub215Q29udHJhY3QJAAIBAhFwZXJtaXNzaW9uIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBQduZXdQYWNrCQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsBQduZXdQYWNrAWkBCGJ1eVNMYW5kAAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10B2Fzc2V0SWQFC3VzZG5Bc3NldElkCQACAQIaQWxsb3dlZCBVU0ROIHBheW1lbnQgb25seSEDCQECIT0CCAUDcG10BmFtb3VudAUHRVhQVVNETgkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFB0VYUFVTRE4EBnJlc3VsdAkBEmV4cGVkaXRpb25JbnRlcm5hbAIIBQFpBmNhbGxlcggFAWkNdHJhbnNhY3Rpb25JZAkAlAoCCQDNCAIJAM0IAggFBnJlc3VsdAJfMQkBDlNjcmlwdFRyYW5zZmVyAwUPZWNvbm9teUNvbnRyYWN0CAUDcG10BmFtb3VudAULdXNkbkFzc2V0SWQFDHByb2xvZ0FjdGlvbggIBQZyZXN1bHQCXzICXzEBaQEKZXhwZWRpdGlvbgIHbWVzc2FnZQNzaWcEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAidleHBlZGl0aW9uIGRvZXNuJ3QgcmVxdWlyZSBhbnkgcGF5bWVudHMEBnJlc3VsdAkBEGV4cGVkaXRpb25Db21tb24FBggFAWkGY2FsbGVyCAUBaQ10cmFuc2FjdGlvbklkBQdtZXNzYWdlBQNzaWcJAJQKAgkAzQgCCAUGcmVzdWx0Al8xBQxwcm9sb2dBY3Rpb24IBQZyZXN1bHQCXzIBaQEMdXBncmFkZUluZnJhAQtsYW5kQXNzZXRJZAQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECM0luZnJhc3RydWN0dXJlIHVwZ3JhZGUgZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50cwQGcmVzdWx0CQENdXBJbmZyYUNvbW1vbgQGCAUBaQZjYWxsZXIAAAULbGFuZEFzc2V0SWQJAJQKAgkAzQgCCAUGcmVzdWx0Al8xBQxwcm9sb2dBY3Rpb24IBQZyZXN1bHQCXzIBaQEQdXBncmFkZUluZnJhVXNkbgELbGFuZEFzc2V0SWQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHEV4YWN0bHkgb25lIHBheW1lbnQgcmVxdWlyZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AggFA3BtdAdhc3NldElkBQt1c2RuQXNzZXRJZAkAAgECGkFsbG93ZWQgVVNETiBwYXltZW50IG9ubHkhBAZyZXN1bHQJAQ11cEluZnJhQ29tbW9uBAcIBQFpBmNhbGxlcggFA3BtdAZhbW91bnQFC2xhbmRBc3NldElkCQCUCgIJAM0IAgkAzQgCCAUGcmVzdWx0Al8xCQEOU2NyaXB0VHJhbnNmZXIDBQ9lY29ub215Q29udHJhY3QIBQNwbXQGYW1vdW50BQt1c2RuQXNzZXRJZAUMcHJvbG9nQWN0aW9uCAUGcmVzdWx0Al8yAWkBEGFjdGl2YXRlQXJ0aWZhY3QCB2FydE5hbWULbGFuZEFzc2V0SWQEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAjBBcnRpZmFjdCBhY3RpdmF0aW9uIGRvZXNuJ3QgcmVxdWlyZSBhbnkgcGF5bWVudHMEBnJlc3VsdAQHJG1hdGNoMAUHYXJ0TmFtZQMJAAACAgdQUkVTQUxFBQckbWF0Y2gwCQESYWN0aXZhdGVQcmVzYWxlQXJ0AgkApQgBCAUBaQZjYWxsZXIFC2xhbmRBc3NldElkCQACAQIQVW5rbm93biBhcnRpZmFjdAkAzQgCBQZyZXN1bHQFDHByb2xvZ0FjdGlvbgFpAQptZXJnZUxhbmRzAQxsYW5kQXNzZXRJZHMEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAipMYW5kcyBtZXJnaW5nIGRvZXNuJ3QgcmVxdWlyZSBhbnkgcGF5bWVudHMEBnJlc3VsdAkBC21lcmdlQ29tbW9uBQYJAKUIAQgFAWkGY2FsbGVyAAAFDGxhbmRBc3NldElkcwgFAWkNdHJhbnNhY3Rpb25JZAkAlAoCCQDNCAIIBQZyZXN1bHQCXzEFDHByb2xvZ0FjdGlvbggFBnJlc3VsdAJfMgFpAQ5tZXJnZUxhbmRzVXNkbgEMbGFuZEFzc2V0SWRzBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10B2Fzc2V0SWQFC3VzZG5Bc3NldElkCQACAQIaQWxsb3dlZCBVU0ROIHBheW1lbnQgb25seSEEBnJlc3VsdAkBC21lcmdlQ29tbW9uBQcJAKUIAQgFAWkGY2FsbGVyCAUDcG10BmFtb3VudAUMbGFuZEFzc2V0SWRzCAUBaQ10cmFuc2FjdGlvbklkCQCUCgIJAM0IAgkAzQgCCAUGcmVzdWx0Al8xCQEOU2NyaXB0VHJhbnNmZXIDBQ9lY29ub215Q29udHJhY3QIBQNwbXQGYW1vdW50BQt1c2RuQXNzZXRJZAUMcHJvbG9nQWN0aW9uCAUGcmVzdWx0Al8yAWkBDWNhcmdvRXhjaGFuZ2UCDGNhcmdvTGlzdFN0cgtsYW5kQXNzZXRJZAQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQQKY2FyZ29QYXJ0cwkAvAkCBQxjYXJnb0xpc3RTdHICAToEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAlsYW5kSW5kZXgJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwULcmVjTGFuZFNpemUFBVNTSVpFBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgQDbG9jCQC1CQIJAQV2YWx1ZQEFC2N1ckxvY2F0aW9uAgFfAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUwJAAIBCQCsAgIJAKwCAgIWRHVjayBsb2NhdGlvbiB0eXBlIGlzIAkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCESwgYnV0IHNob3VsZCBiZSBMAwkBAiE9AgkAkQMCBQNsb2MFCGxvY0lkeElkBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgIbRHVjayBzaG91bGQgYmUgb24gdGhlIGxhbmQgBQtsYW5kQXNzZXRJZAQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAQJY3VycmVudFdoCQEMZ2V0V2FyZWhvdXNlAwUFd2hLZXkFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBnJlc3VsdAkBCW1vdmVTdHVmZgMFCmNhcmdvUGFydHMFCWN1cnJlbnRXaAULY3VycmVudFBhY2sJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIIBQZyZXN1bHQCXzQJAMwIAggFBnJlc3VsdAJfNQkAzAgCCAUGcmVzdWx0Al82BQNuaWwCAToJAMwIAgkBC1N0cmluZ0VudHJ5AgUFd2hLZXkJALkJAgkAzAgCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhWb2wJAMwIAggFBnJlc3VsdAJfMQkAzAgCCAUGcmVzdWx0Al8yCQDMCAIIBQZyZXN1bHQCXzMJAMwIAgkAkQMCBQljdXJyZW50V2gFDndoSWR4TG9ja2VkVm9sBQNuaWwCAToJAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwBaQENc2F2ZVdhcmVob3VzZQIFd2hTdHILbGFuZEFzc2V0SWQEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCAUBaQZjYWxsZXIFD2Vjb25vbXlDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQEBXdoS2V5CQESa2V5V2FyZWhvdXNlQnlMYW5kAQULbGFuZEFzc2V0SWQDCQECIT0CCQCQAwEJALwJAgUFd2hTdHICAToABQkAAgECMHdhcmVob3VzZSBzdHJpbmcgc2hvdWxkIGNvbnRhaW4gNCAnOicgc2VwYXJhdG9ycwkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBXdoS2V5BQV3aFN0cgkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAUFd2hTdHIBaQEcc3BsaXRCeUdsb2JhbFdlaWdodHNSRUFET05MWQEGYW1vdW50CQCUCgIFA25pbAkBEmdldE5lZWRlZE1hdGVyaWFscwEFBmFtb3VudAFpASRzcGxpdEJ5R2xvYmFsQW5kTG9jYWxXZWlnaHRzUkVBRE9OTFkDCW1hdEFtb3VudAlyZXNBbW91bnQIdGVycmFpbnMEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQUIdGVycmFpbnMJAJQKAgUDbmlsCQCUCgIJARJnZXROZWVkZWRNYXRlcmlhbHMBBQltYXRBbW91bnQJARNkaXN0cmlidXRlQnlXZWlnaHRzAgUJcmVzQW1vdW50BQ10ZXJyYWluQ291bnRzAWkBE2dldEJhY2twYWNrUkVBRE9OTFkBC2R1Y2tBc3NldElkCQCUCgIFA25pbAkAuQkCCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAIBOgFpARRnZXRXYXJlaG91c2VSRUFET05MWQELbGFuZEFzc2V0SWQEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQECWxhbmRJbmRleAkAaQIJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBQtyZWNMYW5kU2l6ZQUFU1NJWkUECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAACQCUCgIFA25pbAkAugkCCQEMZ2V0V2FyZWhvdXNlAwkBEmtleVdhcmVob3VzZUJ5TGFuZAEFC2xhbmRBc3NldElkBQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwCAToAJRbrfA==", "height": 2506102, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 34XALP9SEcQDHocVWq8qmeRHVjugX2xPESu9QeVVf4oM Next: GwAV9cxRkhWj5wAV9FUkQtd2At4UguZsNn38Av6bA4dt Diff:
OldNewDifferences
264264 let whIdxMat = 2
265265
266266 let whIdxProd = 3
267+
268+let whIdxLockedVol = 4
267269
268270 let claimModeWh = 0
269271
577579
578580 func getWarehouse (whKey,landIndex,infraLevel) = {
579581 let volPrefix = ((toString(landIndex) + "_") + toString(infraLevel))
580- let p = split(valueOrElse(getString(whKey), (volPrefix + ":0_0_0_0_0_0:0_0_0_0_0_0:")), ":")
582+ let p = split(valueOrElse(getString(whKey), (volPrefix + ":0_0_0_0_0_0:0_0_0_0_0_0::0")), ":")
581583 [p[whIdxVol], if ((size(split(p[whIdxRes], "_")) == NUMRES))
582584 then p[whIdxRes]
583585 else "0_0_0_0_0_0", if ((size(split(p[whIdxMat], "_")) == NUMRES))
584586 then p[whIdxMat]
585- else "0_0_0_0_0_0", p[whIdxProd]]
587+ else "0_0_0_0_0_0", p[whIdxProd], p[whIdxLockedVol]]
586588 }
587589
588590
661663 let currWhResVol = getWarehouseCurrResVolume(currentWh)
662664 let currWhMatVol = getWarehouseCurrMatVolume(currentWh)
663665 let currWhGoodsVol = getWarehouseCurrGoodsVolume(currentWh)
664- let whSpaceLeft = (((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol)
666+ let currWhLockedVol = parseIntValue(currentWh[whIdxLockedVol])
667+ let whSpaceLeft = ((((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol) - currWhLockedVol)
665668 let currWhRes = split(currentWh[whIdxRes], "_")
666669 let currWhMat = split(currentWh[whIdxMat], "_")
667- let currWhProd = if ((currentWh[bpIdxProd] == ""))
670+ let currWhProd = if ((currentWh[whIdxProd] == ""))
668671 then nil
669672 else split(currentWh[whIdxProd], "_")
670673 let currentPackRes = split(currentPack[bpIdxRes], "_")
839842
840843
841844 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
842- let $t02340723946 = if ((claimMode == claimModeWh))
845+ let $t02359824137 = if ((claimMode == claimModeWh))
843846 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
844847 else {
845848 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
849852 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
850853 else $Tuple2(loc[locIdxId], duckAssetId)
851854 }
852- let landAssetId = $t02340723946._1
853- let duckId = $t02340723946._2
855+ let landAssetId = $t02359824137._1
856+ let duckId = $t02359824137._2
854857 let asset = value(assetInfo(fromBase58String(landAssetId)))
855858 let timeKey = keyStakedTimeByAssetId(landAssetId)
856859 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
890893 let currWhResVol = getWarehouseCurrResVolume(currentWh)
891894 let currWhMatVol = getWarehouseCurrMatVolume(currentWh)
892895 let currWhGoodsVol = getWarehouseCurrGoodsVolume(currentWh)
893- let whSpaceLeft = (((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol)
896+ let currWhLockedVol = parseIntValue(currentWh[whIdxLockedVol])
897+ let whSpaceLeft = ((((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol) - currWhLockedVol)
894898 if (if ((claimMode == claimModeWh))
895899 then (amount > whSpaceLeft)
896900 else false)
900904 let currentPack = getBackpack(bpKey)
901905 let currentPackRes = split(currentPack[bpIdxRes], "_")
902906 let currentWhRes = split(currentWh[whIdxRes], "_")
903- let $t02651027013 = if ((claimMode == claimModeWh))
907+ let $t02678527288 = if ((claimMode == claimModeWh))
904908 then $Tuple2(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes])
905909 else if ((claimMode == claimModeDuck))
906910 then $Tuple2(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece))
907911 else distributeRes(currentWhRes, currentPackRes, resToClaim, whSpaceLeft)
908- let whRes = $t02651027013._1
909- let bpRes = $t02651027013._2
910- $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxVol], whRes, currentWh[whIdxMat], currentWh[whIdxProd]])
912+ let whRes = $t02678527288._1
913+ let bpRes = $t02678527288._2
914+ $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxVol], whRes, currentWh[whIdxMat], currentWh[whIdxProd], currentWh[whIdxLockedVol]])
911915 }
912916 }
913917 }
945949 let claimResult = claimAll(addr, c._2, pieces, claimModeWhThenDuck)
946950 let whData = claimResult._5
947951 let newVolData = makeString([split(whData[whIdxVol], "_")[0], toString(newLevel)], "_")
948- $Tuple2(([IntegerEntry(infraKey, newLevel), IntegerEntry(keyInfraLevelByAssetIdAndOwner(c._2, addr), newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], claimResult._3[bpIdxRes], newMat, currentPack[bpIdxProd]], ":")), StringEntry(claimResult._4, makeString([newVolData, whData[whIdxRes], whData[whIdxMat], whData[whIdxProd]], ":"))] ++ claimResult._1), newLevel)
952+ $Tuple2(([IntegerEntry(infraKey, newLevel), IntegerEntry(keyInfraLevelByAssetIdAndOwner(c._2, addr), newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], claimResult._3[bpIdxRes], newMat, currentPack[bpIdxProd]], ":")), StringEntry(claimResult._4, makeString([newVolData, whData[whIdxRes], whData[whIdxMat], whData[whIdxProd], whData[whIdxLockedVol]], ":"))] ++ claimResult._1), newLevel)
949953 }
950954 }
951955 }
12721276 let address = toString(i.caller)
12731277 let asset = value(assetInfo(assetId))
12741278 let timeKey = keyStakedTimeByAssetId(toBase58String(assetId))
1275- if (!(isDefined(timeKey)))
1279+ if (!(isDefined(getInteger(timeKey))))
12761280 then throw((("NFT " + asset.name) + " is not staked"))
1277- else if (!(isDefined(keyStakedDuckByOwner(address))))
1281+ else if (!(isDefined(getString(keyStakedDuckByOwner(address)))))
12781282 then throw((("The duck " + asset.name) + " is not staked"))
12791283 else {
12801284 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(toBase58String(assetId))), (("NFT " + asset.name) + " is orphaned"))
14421446
14431447
14441448 @Callable(i)
1445-func expeditionBuy (message,sig) = if ((i.caller != this))
1446- then throw("Permission denied")
1447- else {
1448- let prologAction = prolog(i)
1449- if ((size(i.payments) != 1))
1450- then throw("Exactly one payment required")
1451- else {
1452- let pmt = value(i.payments[0])
1453- if ((pmt.assetId != usdnAssetId))
1454- then throw("Allowed USDN payment only!")
1455- else if ((pmt.amount != EXPUSDN))
1456- then throw(("Payment attached should be " + toString(EXPUSDN)))
1457- else {
1458- let result = expeditionCommon(false, i.caller, i.transactionId, message, sig)
1459- if ((result._2 == ""))
1460- then result
1461- else $Tuple2(((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdnAssetId)) :+ prologAction), result._2)
1462- }
1463- }
1464- }
1465-
1466-
1467-
1468-@Callable(i)
14691449 func expedition (message,sig) = {
14701450 let prologAction = prolog(i)
14711451 if ((size(i.payments) != 0))
15621542
15631543 @Callable(i)
15641544 func cargoExchange (cargoListStr,landAssetId) = {
1545+ let prologAction = prolog(i)
15651546 let cargoParts = split_4C(cargoListStr, ":")
15661547 let addr = toString(i.originCaller)
15671548 let asset = value(assetInfo(fromBase58String(landAssetId)))
15681549 let timeKey = keyStakedTimeByAssetId(landAssetId)
1569- if (!(isDefined(timeKey)))
1550+ if (!(isDefined(getInteger(timeKey))))
15701551 then throw((asset.name + " is not staked"))
15711552 else {
15721553 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
15881569 let bpKey = keyBackpackByDuck(duckAssetId)
15891570 let currentPack = getBackpack(bpKey)
15901571 let result = moveStuff(cargoParts, currentWh, currentPack)
1591-[StringEntry(bpKey, makeString([currentPack[bpIdxLevel], result._4, result._5, result._6], ":")), StringEntry(whKey, makeString([currentWh[whIdxVol], result._1, result._2, result._3], ":"))]
1572+[StringEntry(bpKey, makeString([currentPack[bpIdxLevel], result._4, result._5, result._6], ":")), StringEntry(whKey, makeString([currentWh[whIdxVol], result._1, result._2, result._3, currentWh[whIdxLockedVol]], ":")), prologAction]
15921573 }
15931574 }
1575+ }
1576+ }
1577+
1578+
1579+
1580+@Callable(i)
1581+func saveWarehouse (whStr,landAssetId) = {
1582+ let prologAction = prolog(i)
1583+ if ((i.caller != economyContract))
1584+ then throw("Access denied")
1585+ else {
1586+ let whKey = keyWarehouseByLand(landAssetId)
1587+ if ((size(split_4C(whStr, ":")) != 5))
1588+ then throw("warehouse string should contain 4 ':' separators")
1589+ else $Tuple2([StringEntry(whKey, whStr), prologAction], whStr)
15941590 }
15951591 }
15961592
16191615 let asset = value(assetInfo(fromBase58String(landAssetId)))
16201616 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
16211617 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1622- $Tuple2(nil, makeString(getWarehouse(keyWarehouseByLand(landAssetId), landIndex, infraLevel), ":"))
1618+ $Tuple2(nil, makeString_2C(getWarehouse(keyWarehouseByLand(landAssetId), landIndex, infraLevel), ":"))
16231619 }
16241620
16251621
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let chain = take(drop(this.bytes, 1), 1)
55
66 let usdnAssetId = match chain {
77 case _ =>
88 if ((base58'2W' == $match0))
99 then base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
1010 else if ((base58'2T' == $match0))
1111 then base58'HezsdQuRDtzksAYUy97gfhKy7Z1NW2uXYSHA3bgqenNZ'
1212 else throw("Unknown chain")
1313 }
1414
1515 let incubatorAddr = match chain {
1616 case _ =>
1717 if ((base58'2W' == $match0))
1818 then addressFromStringValue("3PEktVux2RhchSN63DsDo4b4mz4QqzKSeDv")
1919 else if ((base58'2T' == $match0))
2020 then this
2121 else throw("Unknown chain")
2222 }
2323
2424 let breederAddr = match chain {
2525 case _ =>
2626 if ((base58'2W' == $match0))
2727 then addressFromStringValue("3PDVuU45H7Eh5dmtNbnRNRStGwULA7NY6Hb")
2828 else if ((base58'2T' == $match0))
2929 then this
3030 else throw("Unknown chain")
3131 }
3232
3333 let defaultRestAddressStr = match chain {
3434 case _ =>
3535 if ((base58'2W' == $match0))
3636 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
3737 else if ((base58'2T' == $match0))
3838 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
3939 else throw("Unknown chain")
4040 }
4141
4242 let pub = base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
4343
4444 let HEALCOST = 10000
4545
4646 let LANDPREFIX = "LAND"
4747
4848 let DUCKPREFIX = "DUCK"
4949
5050 let DEFAULTLOCATION = "Africa_F_Africa"
5151
5252 let NUMRES = 6
5353
5454 let SSIZE = 25
5555
5656 let MSIZE = 100
5757
5858 let LSIZE = 225
5959
6060 let XLSIZE = 400
6161
6262 let XXLSIZE = 625
6363
6464 let DAILYRESBYPIECE = 3456000
6565
6666 let DAYMILLIS = 86400000
6767
6868 let FIVEMINUTESMILLIS = 300000
6969
7070 let RESOURCEPRICEMIN = 158549
7171
7272 let WHMULTIPLIER = 10000000000
7373
7474 let InfraUpgradeCostS = match chain {
7575 case _ =>
7676 if ((base58'2W' == $match0))
7777 then 6307198406
7878 else if ((base58'2T' == $match0))
7979 then 63071984
8080 else throw("Unknown chain")
8181 }
8282
8383 let InfraUpgradeCostSUsdn = match chain {
8484 case _ =>
8585 if ((base58'2W' == $match0))
8686 then 40000000
8787 else if ((base58'2T' == $match0))
8888 then 400000
8989 else throw("Unknown chain")
9090 }
9191
9292 let EXPMATERIALS = match chain {
9393 case _ =>
9494 if ((base58'2W' == $match0))
9595 then 157679960139
9696 else if ((base58'2T' == $match0))
9797 then 1576799601
9898 else throw("Unknown chain")
9999 }
100100
101101 let EXPUSDN = match chain {
102102 case _ =>
103103 if ((base58'2W' == $match0))
104104 then 1000000000
105105 else if ((base58'2T' == $match0))
106106 then 10000000
107107 else throw("Unknown chain")
108108 }
109109
110110 let SEP = "__"
111111
112112 let MULT6 = 1000000
113113
114114 let FIVEX = toBigInt(5)
115115
116116 let TWENTYX = toBigInt(20)
117117
118118 let TWENTY2X = toBigInt((20 * 20))
119119
120120 let TWENTY3X = toBigInt(((20 * 20) * 20))
121121
122122 let TWENTY4X = toBigInt((((20 * 20) * 20) * 20))
123123
124124 let TWENTY5X = toBigInt(((((20 * 20) * 20) * 20) * 20))
125125
126126 let matTypes = ["Fuel", "Metal", "Plank", "Glass", "Plastic", "Protein"]
127127
128128 let continents = ["Asia", "Europe", "Americas", "Oceania", "Africa"]
129129
130130 let ARTPRESALE = "PRESALE"
131131
132132 let PRESALENUMLANDS = 500
133133
134134 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
135135
136136
137137 func getIntOrElse (key,defaultVal) = valueOrElse(getInteger(this, key), defaultVal)
138138
139139
140140 let IdxCfgStakingDapp = 1
141141
142142 let IdxCfgEconomyDapp = 2
143143
144144 let IdxCfgGovernanceDapp = 3
145145
146146 func keyRestCfg () = "%s__restConfig"
147147
148148
149149 func keyRestAddress () = "%s__restAddr"
150150
151151
152152 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
153153
154154
155155 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
156156
157157
158158 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
159159
160160 let restCfg = readRestCfgOrFail(restContract)
161161
162162 let economyContract = getContractAddressOrFail(restCfg, IdxCfgEconomyDapp)
163163
164164 let govContract = getContractAddressOrFail(restCfg, IdxCfgGovernanceDapp)
165165
166166 func keyLastTxIdByUser (addr) = ("lastTxIdByUser_" + addr)
167167
168168
169169 func keyNextFreeLandNum () = "nextLandNum"
170170
171171
172172 func keyLandToAssetId (landNum) = ("landToAsset_" + landNum)
173173
174174
175175 func keyNftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
176176
177177
178178 func keyLandAssetIdToOwner (assetId) = ("nftOwner_" + assetId)
179179
180180
181181 func keyDuckIdToOwner (assetId) = ("duckOwner_" + assetId)
182182
183183
184184 func keyStakedTimeByAssetId (assetId) = ("stakedTime_" + assetId)
185185
186186
187187 func keyInfraLevelByAssetId (assetId) = ("infraLevel_" + assetId)
188188
189189
190190 func keyInfraLevelByAssetIdAndOwner (assetId,ownerAddr) = ((("infraLevelByAssetIdAndOwner_" + assetId) + "_") + ownerAddr)
191191
192192
193193 func keyPresaleArtActivatedByAssetId (assetId) = ("presaleArtActivated_" + assetId)
194194
195195
196196 func keyPresaleArtActivatedByAssetIdAndOwner (assetId,ownerAddr) = ((("presaleArtActivatedByAssetIdAndOwner_" + assetId) + "_") + ownerAddr)
197197
198198
199199 func keyLandArtStatusByTypeAndAssetId (type,assetId) = makeString(["landArtStatus", type, assetId], "_")
200200
201201
202202 func keyLandArtStatusByTypeAssetIdAndOwner (type,assetId,ownerAddr) = makeString(["landArtStatusByTypeAssetIdAndOwner", type, assetId, ownerAddr], "_")
203203
204204
205205 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
206206
207207
208208 func keyStakedTimeByTypeAssetIdAndOwner (nftType,assetId,ownerAddr) = ((((("stakedTimeByTypeAssetIdAndOwner_" + nftType) + "_") + assetId) + "_") + ownerAddr)
209209
210210
211211 func keyLandNumToOwner (landNum) = ("landOwner_" + landNum)
212212
213213
214214 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
215215
216216
217217 func keyWarehouseByLand (landAssetId) = ("wareHouse_" + landAssetId)
218218
219219
220220 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
221221
222222
223223 func keyDuckHealth (duckAssetId) = ("duckHealth_" + duckAssetId)
224224
225225
226226 func keyResProportions () = "resTypesProportions"
227227
228228
229229 func keyStakedLandsByOwner (ownerAddr) = ("stakedLandsByOwner_" + ownerAddr)
230230
231231
232232 func keyBlocked () = "contractsBlocked"
233233
234234
235235 func keyUserGwlReleaseTime (userAddr) = ("%s%s__userGwlReleaseTime__" + userAddr)
236236
237237
238238 let recLandNum = 0
239239
240240 let recLandSize = 1
241241
242242 let recTerrains = 2
243243
244244 let recContinent = 3
245245
246246 let locIdxContinent = 0
247247
248248 let locIdxType = 1
249249
250250 let locIdxId = 2
251251
252252 let bpIdxLevel = 0
253253
254254 let bpIdxRes = 1
255255
256256 let bpIdxMat = 2
257257
258258 let bpIdxProd = 3
259259
260260 let whIdxVol = 0
261261
262262 let whIdxRes = 1
263263
264264 let whIdxMat = 2
265265
266266 let whIdxProd = 3
267+
268+let whIdxLockedVol = 4
267269
268270 let claimModeWh = 0
269271
270272 let claimModeDuck = 1
271273
272274 let claimModeWhThenDuck = 2
273275
274276 func asString (v) = match v {
275277 case s: String =>
276278 s
277279 case _ =>
278280 throw("fail to cast into String")
279281 }
280282
281283
282284 func distributeByWeights (total,weights) = {
283285 let sum = (((((weights[0] + weights[1]) + weights[2]) + weights[3]) + weights[4]) + weights[5])
284286 if ((0 >= sum))
285287 then throw("Zero weights sum")
286288 else {
287289 let norm6 = fraction(total, MULT6, sum)
288290 func normalizer (acc,elem) = (acc :+ fraction(elem, norm6, MULT6))
289291
290292 let $l = weights
291293 let $s = size($l)
292294 let $acc0 = nil
293295 func $f0_1 ($a,$i) = if (($i >= $s))
294296 then $a
295297 else normalizer($a, $l[$i])
296298
297299 func $f0_2 ($a,$i) = if (($i >= $s))
298300 then $a
299301 else throw("List size exceeds 6")
300302
301303 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
302304 }
303305 }
304306
305307
306308 func getNeededMaterials (total) = {
307309 let props = split(value(getString(keyResProportions())), "_")
308310 if ((size(props) != NUMRES))
309311 then throw("Wrong proportions data")
310312 else {
311313 let r = [parseIntValue(props[0]), parseIntValue(props[1]), parseIntValue(props[2]), parseIntValue(props[3]), parseIntValue(props[4]), parseIntValue(props[5])]
312314 distributeByWeights(total, r)
313315 }
314316 }
315317
316318
317319 func subtractMaterials (shouldUseMat,has,totalNeed) = {
318320 let need = getNeededMaterials(totalNeed)
319321 func subtractor (acc,idx) = {
320322 let result = (parseIntValue(has[idx]) - need[idx])
321323 if ((0 > result))
322324 then throw(((((("Not enough material idx=" + toString(idx)) + ", you have ") + has[idx]) + ", but need ") + toString(need[idx])))
323325 else (acc :+ toString(result))
324326 }
325327
326328 if (shouldUseMat)
327329 then {
328330 let $l = [0, 1, 2, 3, 4, 5]
329331 let $s = size($l)
330332 let $acc0 = nil
331333 func $f0_1 ($a,$i) = if (($i >= $s))
332334 then $a
333335 else subtractor($a, $l[$i])
334336
335337 func $f0_2 ($a,$i) = if (($i >= $s))
336338 then $a
337339 else throw("List size exceeds 6")
338340
339341 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
340342 }
341343 else has
342344 }
343345
344346
345347 func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
346348 then throw("Wrong proportions data")
347349 else {
348350 func updater (acc,i) = {
349351 let result = (parseIntValue(propList[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
350352 if ((0 > result))
351353 then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
352354 else (acc :+ toString(result))
353355 }
354356
355357 let r = {
356358 let $l = [0, 1, 2, 3, 4, 5]
357359 let $s = size($l)
358360 let $acc0 = nil
359361 func $f0_1 ($a,$i) = if (($i >= $s))
360362 then $a
361363 else updater($a, $l[$i])
362364
363365 func $f0_2 ($a,$i) = if (($i >= $s))
364366 then $a
365367 else throw("List size exceeds 6")
366368
367369 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
368370 }
369371 makeString(r, "_")
370372 }
371373
372374
373375 func updateProportions (terrainCounts,landSizeIndex,sign) = {
374376 let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
375377 updateProportionsInternal(propList, terrainCounts, landSizeIndex, sign)
376378 }
377379
378380
379381 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)]
380382
381383
382384 func numPiecesBySize (landSize) = match landSize {
383385 case _ =>
384386 if (("S" == $match0))
385387 then SSIZE
386388 else if (("M" == $match0))
387389 then MSIZE
388390 else if (("L" == $match0))
389391 then LSIZE
390392 else if (("XL" == $match0))
391393 then XLSIZE
392394 else if (("XXL" == $match0))
393395 then XXLSIZE
394396 else throw("Unknown land size")
395397 }
396398
397399
398400 func subOneInList (aList,idx,amount) = {
399401 func subber (acc,i) = (acc :+ (if ((i == idx))
400402 then toString((parseIntValue(aList[i]) - amount))
401403 else aList[i]))
402404
403405 let r = {
404406 let $l = [0, 1, 2, 3, 4, 5]
405407 let $s = size($l)
406408 let $acc0 = nil
407409 func $f0_1 ($a,$i) = if (($i >= $s))
408410 then $a
409411 else subber($a, $l[$i])
410412
411413 func $f0_2 ($a,$i) = if (($i >= $s))
412414 then $a
413415 else throw("List size exceeds 6")
414416
415417 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
416418 }
417419 makeString(r, "_")
418420 }
419421
420422
421423 func addRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
422424 func adder (acc,i) = {
423425 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
424426 (acc :+ toString((parseIntValue(currentRes[i]) + resOfType)))
425427 }
426428
427429 let r = {
428430 let $l = [0, 1, 2, 3, 4, 5]
429431 let $s = size($l)
430432 let $acc0 = nil
431433 func $f0_1 ($a,$i) = if (($i >= $s))
432434 then $a
433435 else adder($a, $l[$i])
434436
435437 func $f0_2 ($a,$i) = if (($i >= $s))
436438 then $a
437439 else throw("List size exceeds 6")
438440
439441 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
440442 }
441443 makeString(r, "_")
442444 }
443445
444446
445447 func virtClaim (terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
446448 func adder (acc,i) = {
447449 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
448450 $Tuple2((acc._1 :+ resOfType), (acc._2 + resOfType))
449451 }
450452
451453 let $l = [0, 1, 2, 3, 4, 5]
452454 let $s = size($l)
453455 let $acc0 = $Tuple2(nil, 0)
454456 func $f0_1 ($a,$i) = if (($i >= $s))
455457 then $a
456458 else adder($a, $l[$i])
457459
458460 func $f0_2 ($a,$i) = if (($i >= $s))
459461 then $a
460462 else throw("List size exceeds 6")
461463
462464 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
463465 }
464466
465467
466468 func distributeRes (currentWhRes,currentPackRes,resToClaim,whSpaceLeft) = {
467469 let resListToClaim = resToClaim._1
468470 let resAmToClaim = resToClaim._2
469471 if ((resAmToClaim == 0))
470472 then $Tuple2(makeString(currentWhRes, "_"), makeString(currentPackRes, "_"))
471473 else if ((whSpaceLeft >= resAmToClaim))
472474 then {
473475 func addLists (acc,i) = (acc :+ toString((parseIntValue(currentWhRes[i]) + resListToClaim[i])))
474476
475477 let r = {
476478 let $l = [0, 1, 2, 3, 4, 5]
477479 let $s = size($l)
478480 let $acc0 = nil
479481 func $f0_1 ($a,$i) = if (($i >= $s))
480482 then $a
481483 else addLists($a, $l[$i])
482484
483485 func $f0_2 ($a,$i) = if (($i >= $s))
484486 then $a
485487 else throw("List size exceeds 6")
486488
487489 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
488490 }
489491 $Tuple2(makeString(r, "_"), makeString(currentPackRes, "_"))
490492 }
491493 else {
492494 func addPartLists (acc,i) = {
493495 let whPart = fraction(resListToClaim[i], whSpaceLeft, resAmToClaim)
494496 $Tuple2((acc._1 :+ toString((parseIntValue(currentWhRes[i]) + whPart))), (acc._2 :+ toString(((parseIntValue(currentPackRes[i]) + resListToClaim[i]) - whPart))))
495497 }
496498
497499 let r = {
498500 let $l = [0, 1, 2, 3, 4, 5]
499501 let $s = size($l)
500502 let $acc0 = $Tuple2(nil, nil)
501503 func $f0_1 ($a,$i) = if (($i >= $s))
502504 then $a
503505 else addPartLists($a, $l[$i])
504506
505507 func $f0_2 ($a,$i) = if (($i >= $s))
506508 then $a
507509 else throw("List size exceeds 6")
508510
509511 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
510512 }
511513 $Tuple2(makeString(r._1, "_"), makeString(r._2, "_"))
512514 }
513515 }
514516
515517
516518 func abs (x) = if ((x >= toBigInt(0)))
517519 then x
518520 else -(x)
519521
520522
521523 let freq = [[1, 4, 9, 10, 15], [5, 8, 13, 14, 15], [6, 9, 14, 15, 16], [4, 7, 8, 13, 18], [1, 6, 7, 15, 19]]
522524
523525 func genChar (n,freqs) = {
524526 let rem = toInt((n % TWENTYX))
525527 let letter = if ((freqs[0] > rem))
526528 then "A"
527529 else if ((freqs[1] > rem))
528530 then "B"
529531 else if ((freqs[2] > rem))
530532 then "C"
531533 else if ((freqs[3] > rem))
532534 then "D"
533535 else if ((freqs[4] > rem))
534536 then "E"
535537 else "F"
536538 letter
537539 }
538540
539541
540542 func genTerrains (seed,continentIdx) = {
541543 let f = freq[continentIdx]
542544 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))
543545
544546 let t = {
545547 let $l = [1, 2, 3, 4, 5]
546548 let $s = size($l)
547549 let $acc0 = $Tuple2("", (seed / FIVEX))
548550 func $f0_1 ($a,$i) = if (($i >= $s))
549551 then $a
550552 else terrainGenerator($a, $l[$i])
551553
552554 func $f0_2 ($a,$i) = if (($i >= $s))
553555 then $a
554556 else throw("List size exceeds 5")
555557
556558 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
557559 }
558560 t._1
559561 }
560562
561563
562564 func getBackpack (bpKey) = {
563565 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
564566 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
565567 then p[bpIdxRes]
566568 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
567569 then p[bpIdxMat]
568570 else "0_0_0_0_0_0", p[bpIdxProd]]
569571 }
570572
571573
572574 func getWarehouseVolume (volPrefix) = {
573575 let parts = split(volPrefix, "_")
574576 ((WHMULTIPLIER * (parseIntValue(parts[1]) + 1)) * parseIntValue(parts[0]))
575577 }
576578
577579
578580 func getWarehouse (whKey,landIndex,infraLevel) = {
579581 let volPrefix = ((toString(landIndex) + "_") + toString(infraLevel))
580- let p = split(valueOrElse(getString(whKey), (volPrefix + ":0_0_0_0_0_0:0_0_0_0_0_0:")), ":")
582+ let p = split(valueOrElse(getString(whKey), (volPrefix + ":0_0_0_0_0_0:0_0_0_0_0_0::0")), ":")
581583 [p[whIdxVol], if ((size(split(p[whIdxRes], "_")) == NUMRES))
582584 then p[whIdxRes]
583585 else "0_0_0_0_0_0", if ((size(split(p[whIdxMat], "_")) == NUMRES))
584586 then p[whIdxMat]
585- else "0_0_0_0_0_0", p[whIdxProd]]
587+ else "0_0_0_0_0_0", p[whIdxProd], p[whIdxLockedVol]]
586588 }
587589
588590
589591 func getWarehouseCurrResVolume (currentWh) = {
590592 func sum (acc,item) = (acc + parseIntValue(item))
591593
592594 let $l = split(currentWh[whIdxRes], "_")
593595 let $s = size($l)
594596 let $acc0 = 0
595597 func $f0_1 ($a,$i) = if (($i >= $s))
596598 then $a
597599 else sum($a, $l[$i])
598600
599601 func $f0_2 ($a,$i) = if (($i >= $s))
600602 then $a
601603 else throw("List size exceeds 6")
602604
603605 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
604606 }
605607
606608
607609 func getWarehouseCurrMatVolume (currentWh) = {
608610 func sum (acc,item) = (acc + parseIntValue(item))
609611
610612 let $l = split(currentWh[whIdxMat], "_")
611613 let $s = size($l)
612614 let $acc0 = 0
613615 func $f0_1 ($a,$i) = if (($i >= $s))
614616 then $a
615617 else sum($a, $l[$i])
616618
617619 func $f0_2 ($a,$i) = if (($i >= $s))
618620 then $a
619621 else throw("List size exceeds 6")
620622
621623 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
622624 }
623625
624626
625627 func getWarehouseCurrGoodsVolume (currentWh) = {
626628 let goods = currentWh[whIdxProd]
627629 if ((goods == ""))
628630 then 0
629631 else {
630632 func sum (acc,item) = (acc + parseIntValue(item))
631633
632634 let $l = split_4C(goods, "_")
633635 let $s = size($l)
634636 let $acc0 = 0
635637 func $f0_1 ($a,$i) = if (($i >= $s))
636638 then $a
637639 else sum($a, $l[$i])
638640
639641 func $f0_2 ($a,$i) = if (($i >= $s))
640642 then $a
641643 else throw("List size exceeds 50")
642644
643645 $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)
644646 }
645647 }
646648
647649
648650 func moveStuff (cargoParts,currentWh,currentPack) = if ((size(cargoParts) != 3))
649651 then throw("cargoListStr should contain exactly 2 ':' separators")
650652 else {
651653 let resParts = split(cargoParts[0], "_")
652654 let matParts = split(cargoParts[1], "_")
653655 let prodParts = if ((cargoParts[2] == ""))
654656 then nil
655657 else split(cargoParts[2], "_")
656658 if ((size(resParts) != NUMRES))
657659 then throw("All 6 resources should be passed")
658660 else if ((size(matParts) != NUMRES))
659661 then throw("All 6 materials should be passed")
660662 else {
661663 let currWhResVol = getWarehouseCurrResVolume(currentWh)
662664 let currWhMatVol = getWarehouseCurrMatVolume(currentWh)
663665 let currWhGoodsVol = getWarehouseCurrGoodsVolume(currentWh)
664- let whSpaceLeft = (((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol)
666+ let currWhLockedVol = parseIntValue(currentWh[whIdxLockedVol])
667+ let whSpaceLeft = ((((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol) - currWhLockedVol)
665668 let currWhRes = split(currentWh[whIdxRes], "_")
666669 let currWhMat = split(currentWh[whIdxMat], "_")
667- let currWhProd = if ((currentWh[bpIdxProd] == ""))
670+ let currWhProd = if ((currentWh[whIdxProd] == ""))
668671 then nil
669672 else split(currentWh[whIdxProd], "_")
670673 let currentPackRes = split(currentPack[bpIdxRes], "_")
671674 let currentPackMat = split(currentPack[bpIdxMat], "_")
672675 let currentPackProd = if ((currentPack[bpIdxProd] == ""))
673676 then nil
674677 else split(currentPack[bpIdxProd], "_")
675678 func mvR (acc,item) = {
676679 let i = acc._1
677680 let am = parseIntValue(item)
678681 let whr = parseIntValue(currWhRes[i])
679682 let bpr = parseIntValue(currentPackRes[i])
680683 if ((am == 0))
681684 then $Tuple4((i + 1), (acc._2 :+ currWhRes[i]), (acc._3 :+ currentPackRes[i]), acc._4)
682685 else if ((am > 0))
683686 then if ((am > bpr))
684687 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpr)) + " available"))
685688 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
686689 else if ((-(am) > whr))
687690 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whr)) + " available"))
688691 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
689692 }
690693
691694 let r = {
692695 let $l = resParts
693696 let $s = size($l)
694697 let $acc0 = $Tuple4(0, nil, nil, 0)
695698 func $f0_1 ($a,$i) = if (($i >= $s))
696699 then $a
697700 else mvR($a, $l[$i])
698701
699702 func $f0_2 ($a,$i) = if (($i >= $s))
700703 then $a
701704 else throw("List size exceeds 6")
702705
703706 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
704707 }
705708 func mvM (acc,item) = {
706709 let i = acc._1
707710 let am = parseIntValue(item)
708711 let whm = parseIntValue(currWhMat[i])
709712 let bpm = parseIntValue(currentPackMat[i])
710713 if ((am == 0))
711714 then $Tuple4((i + 1), (acc._2 :+ currWhMat[i]), (acc._3 :+ currentPackMat[i]), acc._4)
712715 else if ((am > 0))
713716 then if ((am > bpm))
714717 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpm)) + " available"))
715718 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
716719 else if ((-(am) > whm))
717720 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whm)) + " available"))
718721 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
719722 }
720723
721724 let m = {
722725 let $l = matParts
723726 let $s = size($l)
724727 let $acc0 = $Tuple4(0, nil, nil, r._4)
725728 func $f1_1 ($a,$i) = if (($i >= $s))
726729 then $a
727730 else mvM($a, $l[$i])
728731
729732 func $f1_2 ($a,$i) = if (($i >= $s))
730733 then $a
731734 else throw("List size exceeds 6")
732735
733736 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
734737 }
735738 func mvP (acc,item) = {
736739 let i = acc._1
737740 let am = parseIntValue(item)
738741 let whp = parseIntValue(currWhProd[i])
739742 let bpp = parseIntValue(currentPackProd[i])
740743 if ((am == 0))
741744 then $Tuple4((i + 1), (acc._2 :+ currWhProd[i]), (acc._3 :+ currentPackProd[i]), acc._4)
742745 else if ((am > 0))
743746 then if ((am > bpp))
744747 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpp)) + " available"))
745748 else $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + am))
746749 else if ((-(am) > whp))
747750 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whp)) + " available"))
748751 else $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + am))
749752 }
750753
751754 let p = {
752755 let $l = prodParts
753756 let $s = size($l)
754757 let $acc0 = $Tuple4(0, nil, nil, m._4)
755758 func $f2_1 ($a,$i) = if (($i >= $s))
756759 then $a
757760 else mvP($a, $l[$i])
758761
759762 func $f2_2 ($a,$i) = if (($i >= $s))
760763 then $a
761764 else throw("List size exceeds 50")
762765
763766 $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)
764767 }
765768 let volSaldo = p._4
766769 if ((volSaldo > whSpaceLeft))
767770 then throw((((("Attempt to put total " + toString(volSaldo)) + " stuff, but only ") + toString(whSpaceLeft)) + " warehouse space left"))
768771 else $Tuple6(makeString(r._2, "_"), makeString(m._2, "_"), makeString(p._2, "_"), makeString(r._3, "_"), makeString(m._3, "_"), makeString(p._3, "_"))
769772 }
770773 }
771774
772775
773776 func expeditionInternal (caller,txId) = {
774777 let userAddr = toString(caller)
775778 let bigNum = abs(toBigInt(txId))
776779 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
777780 let landNum = toString(freeNum)
778781 let continentIdx = toInt((bigNum % FIVEX))
779782 let terrains = genTerrains(bigNum, continentIdx)
780783 let continent = continents[continentIdx]
781784 let issue = Issue(keyNftName(landNum, "S"), makeString([landNum, "S", terrains, continent], "_"), 1, 0, false)
782785 let assetId = calculateAssetId(issue)
783786 let id = toBase58String(assetId)
784787 $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))
785788 }
786789
787790
788791 func expeditionCommon (shouldUseMat,caller,txId,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
789792 then throw("signature does not match")
790793 else {
791794 let parts = split(toUtf8String(message), ";")
792795 let hp = split(split(parts[0], "|")[0], "_")
793796 let curHP = parseIntValue(hp[0])
794797 let newHP = parseIntValue(hp[1])
795798 let locAndTime = split(parts[1], ":")
796799 let targetLocation = split(locAndTime[0], "_")
797800 if ((targetLocation[1] != "E"))
798801 then throw("expedition target location type should be E")
799802 else {
800803 let time = parseIntValue(locAndTime[1])
801804 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
802805 then true
803806 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
804807 then throw("signature outdated")
805808 else {
806809 let userAddr = toString(caller)
807810 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
808811 let keyHealth = keyDuckHealth(duckAssetId)
809812 let oldFromState = valueOrElse(getInteger(keyHealth), 100)
810813 if ((oldFromState != curHP))
811814 then throw(((("oldHealth=" + toString(valueOrElse(getInteger(keyHealth), 100))) + " from state does not match one from flight log=") + toString(curHP)))
812815 else if ((0 >= curHP))
813816 then throw("You can't fly with zero health")
814817 else if ((0 >= newHP))
815818 then $Tuple2(((if (!(shouldUseMat))
816819 then [ScriptTransfer(caller, EXPUSDN, usdnAssetId)]
817820 else nil) :+ IntegerEntry(keyHealth, 0)), "")
818821 else {
819822 let bpKey = keyBackpackByDuck(duckAssetId)
820823 let currentPack = getBackpack(bpKey)
821824 let mList = split(currentPack[bpIdxMat], "_")
822825 let newMat = makeString(subtractMaterials(shouldUseMat, mList, EXPMATERIALS), "_")
823826 let e = expeditionInternal(caller, txId)
824827 let id = e._2._1
825828 $Tuple2((((e._1 :+ StringEntry(keyDuckLocation(duckAssetId), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, newHP)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))), id)
826829 }
827830 }
828831 }
829832 }
830833
831834
832835 func applyBonuses (landAssetId,pieces) = {
833836 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
834837 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), if (valueOrElse(getBoolean(keyPresaleArtActivatedByAssetId(landAssetId)), false))
835838 then pieces
836839 else 0)
837840 ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, infraLevel, 4)) + fraction(DAILYRESBYPIECE, (artPieces * 3), (pieces * 20)))
838841 }
839842
840843
841844 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
842- let $t02340723946 = if ((claimMode == claimModeWh))
845+ let $t02359824137 = if ((claimMode == claimModeWh))
843846 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
844847 else {
845848 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
846849 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
847850 let loc = split(value(curLocation), "_")
848851 if ((loc[locIdxType] != "L"))
849852 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
850853 else $Tuple2(loc[locIdxId], duckAssetId)
851854 }
852- let landAssetId = $t02340723946._1
853- let duckId = $t02340723946._2
855+ let landAssetId = $t02359824137._1
856+ let duckId = $t02359824137._2
854857 let asset = value(assetInfo(fromBase58String(landAssetId)))
855858 let timeKey = keyStakedTimeByAssetId(landAssetId)
856859 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
857860 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
858861 if ((owner != addr))
859862 then throw((LANDPREFIX + " is not yours"))
860863 else {
861864 let d = split(asset.description, "_")
862865 $Tuple4(duckId, landAssetId, d, savedTime)
863866 }
864867 }
865868
866869
867870 func claimResInternal (addr,amount,claimMode,landAssetIdIn) = if ((0 > amount))
868871 then throw("Negative amount")
869872 else {
870873 let c = checkClaimConditions(addr, claimMode, landAssetIdIn)
871874 let landSize = c._3[recLandSize]
872875 let terrainCounts = countTerrains(c._3[recTerrains])
873876 let deltaTime = (lastBlock.timestamp - c._4)
874877 if ((0 > deltaTime))
875878 then throw(((("Saved timestamp is in future, saved = " + toString(c._4)) + ", current = ") + toString(lastBlock.timestamp)))
876879 else {
877880 let pieces = numPiecesBySize(landSize)
878881 let dailyProductionByPiece = applyBonuses(c._2, pieces)
879882 let availRes = fraction(deltaTime, (dailyProductionByPiece * pieces), DAYMILLIS)
880883 if ((amount > availRes))
881884 then throw(((("Not enough resources, available = " + toString(availRes)) + ", requested = ") + toString(amount)))
882885 else {
883886 let newDeltaTime = fraction((availRes - amount), DAYMILLIS, (dailyProductionByPiece * pieces))
884887 let newTimestamp = (lastBlock.timestamp - newDeltaTime)
885888 let landIndex = (pieces / SSIZE)
886889 let resToClaim = virtClaim(terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece)
887890 let whKey = keyWarehouseByLand(c._2)
888891 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(c._2)), 0)
889892 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
890893 let currWhResVol = getWarehouseCurrResVolume(currentWh)
891894 let currWhMatVol = getWarehouseCurrMatVolume(currentWh)
892895 let currWhGoodsVol = getWarehouseCurrGoodsVolume(currentWh)
893- let whSpaceLeft = (((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol)
896+ let currWhLockedVol = parseIntValue(currentWh[whIdxLockedVol])
897+ let whSpaceLeft = ((((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol) - currWhLockedVol)
894898 if (if ((claimMode == claimModeWh))
895899 then (amount > whSpaceLeft)
896900 else false)
897901 then throw((("Only " + toString(whSpaceLeft)) + " space left in warehouse"))
898902 else {
899903 let bpKey = keyBackpackByDuck(c._1)
900904 let currentPack = getBackpack(bpKey)
901905 let currentPackRes = split(currentPack[bpIdxRes], "_")
902906 let currentWhRes = split(currentWh[whIdxRes], "_")
903- let $t02651027013 = if ((claimMode == claimModeWh))
907+ let $t02678527288 = if ((claimMode == claimModeWh))
904908 then $Tuple2(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes])
905909 else if ((claimMode == claimModeDuck))
906910 then $Tuple2(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece))
907911 else distributeRes(currentWhRes, currentPackRes, resToClaim, whSpaceLeft)
908- let whRes = $t02651027013._1
909- let bpRes = $t02651027013._2
910- $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxVol], whRes, currentWh[whIdxMat], currentWh[whIdxProd]])
912+ let whRes = $t02678527288._1
913+ let bpRes = $t02678527288._2
914+ $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxVol], whRes, currentWh[whIdxMat], currentWh[whIdxProd], currentWh[whIdxLockedVol]])
911915 }
912916 }
913917 }
914918 }
915919
916920
917921 func claimAll (addr,landAssetId,pieces,claimMode) = {
918922 let timeKey = keyStakedTimeByAssetId(landAssetId)
919923 let savedTime = value(getInteger(timeKey))
920924 let availRes = (fraction((lastBlock.timestamp - savedTime), applyBonuses(landAssetId, pieces), DAYMILLIS) * pieces)
921925 claimResInternal(addr, availRes, claimMode, landAssetId)
922926 }
923927
924928
925929 func upInfraCommon (shouldUseMat,caller,paymentAmount,landAssetId) = {
926930 let addr = toString(caller)
927931 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetId)
928932 let pieces = numPiecesBySize(c._3[recLandSize])
929933 let infraKey = keyInfraLevelByAssetId(c._2)
930934 let curLevel = valueOrElse(getInteger(infraKey), 0)
931935 if ((curLevel >= 3))
932936 then throw("Currently max infrastructure level = 3")
933937 else {
934938 let newLevel = (curLevel + 1)
935939 let cost = fraction(InfraUpgradeCostSUsdn, (pieces * newLevel), SSIZE)
936940 if (if (!(shouldUseMat))
937941 then (paymentAmount != cost)
938942 else false)
939943 then throw(("Payment attached should be " + toString(cost)))
940944 else {
941945 let bpKey = keyBackpackByDuck(c._1)
942946 let currentPack = getBackpack(bpKey)
943947 let mList = split(currentPack[bpIdxMat], "_")
944948 let newMat = makeString(subtractMaterials(shouldUseMat, mList, fraction(InfraUpgradeCostS, (pieces * newLevel), SSIZE)), "_")
945949 let claimResult = claimAll(addr, c._2, pieces, claimModeWhThenDuck)
946950 let whData = claimResult._5
947951 let newVolData = makeString([split(whData[whIdxVol], "_")[0], toString(newLevel)], "_")
948- $Tuple2(([IntegerEntry(infraKey, newLevel), IntegerEntry(keyInfraLevelByAssetIdAndOwner(c._2, addr), newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], claimResult._3[bpIdxRes], newMat, currentPack[bpIdxProd]], ":")), StringEntry(claimResult._4, makeString([newVolData, whData[whIdxRes], whData[whIdxMat], whData[whIdxProd]], ":"))] ++ claimResult._1), newLevel)
952+ $Tuple2(([IntegerEntry(infraKey, newLevel), IntegerEntry(keyInfraLevelByAssetIdAndOwner(c._2, addr), newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], claimResult._3[bpIdxRes], newMat, currentPack[bpIdxProd]], ":")), StringEntry(claimResult._4, makeString([newVolData, whData[whIdxRes], whData[whIdxMat], whData[whIdxProd], whData[whIdxLockedVol]], ":"))] ++ claimResult._1), newLevel)
949953 }
950954 }
951955 }
952956
953957
954958 func activatePresaleArt (addr,landAssetIdIn) = {
955959 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetIdIn)
956960 let landAssetId = c._2
957961 let activationKey = keyPresaleArtActivatedByAssetId(landAssetId)
958962 if (valueOrElse(getBoolean(activationKey), false))
959963 then throw("Presale artifact is already activated")
960964 else if ((parseIntValue(c._3[recLandNum]) > PRESALENUMLANDS))
961965 then throw((((LANDPREFIX + " ") + landAssetId) + " is not eligible for presale artifact"))
962966 else {
963967 let pieces = numPiecesBySize(c._3[recLandSize])
964968 let claimResult = claimAll(addr, landAssetId, pieces, claimModeWhThenDuck)
965969 ((((((claimResult._1 :+ BooleanEntry(activationKey, true)) :+ BooleanEntry(keyPresaleArtActivatedByAssetIdAndOwner(landAssetId, addr), true)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId), pieces)) :+ IntegerEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, addr), pieces)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":"))) :+ StringEntry(claimResult._4, makeString(claimResult._5, ":")))
966970 }
967971 }
968972
969973
970974 func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,txId,needMat) = {
971975 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
972976 func checkMerge (acc,landAssetId) = {
973977 let asset = value(assetInfo(fromBase58String(landAssetId)))
974978 let timeKey = keyStakedTimeByAssetId(landAssetId)
975979 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
976980 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
977981 if ((owner != addr))
978982 then throw((LANDPREFIX + " is not yours"))
979983 else {
980984 let d = split(asset.description, "_")
981985 let continent = d[recContinent]
982986 if (if ((acc._3 != ""))
983987 then (acc._3 != continent)
984988 else false)
985989 then throw("Lands should be on the same continent to merge")
986990 else {
987991 let landSize = d[recLandSize]
988992 let sizesIn = acc._1
989993 let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
990994 let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
991995 let pieces = numPiecesBySize(landSize)
992996 let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), if (valueOrElse(getBoolean(keyPresaleArtActivatedByAssetId(landAssetId)), false))
993997 then pieces
994998 else 0))
995999 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
9961000 let reqLevel = match landSize {
9971001 case _ =>
9981002 if (("S" == $match0))
9991003 then 3
10001004 else if (("M" == $match0))
10011005 then 4
10021006 else if (("L" == $match0))
10031007 then 5
10041008 else if (("XL" == $match0))
10051009 then 6
10061010 else throw("Only S, M, L, XL can merge")
10071011 }
10081012 if ((infraLevel != reqLevel))
10091013 then throw("All lands should be maxed to merge")
10101014 else {
10111015 let landNum = d[recLandNum]
10121016 let terrainCounts = countTerrains(d[recTerrains])
10131017 let deltaTime = (lastBlock.timestamp - savedTime)
10141018 if ((0 > deltaTime))
10151019 then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
10161020 else {
10171021 let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
10181022 let landIndex = (pieces / SSIZE)
10191023 let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
10201024 let props = updateProportionsInternal(split(acc._6, "_"), terrainCounts, landIndex, -1)
10211025 let lands = acc._7
10221026 let idx = indexOf(lands, landAssetId)
10231027 if (!(isDefined(idx)))
10241028 then throw(("Your staked lands don't contain " + landAssetId))
10251029 else $Tuple7(sizesOut, arts, continent, bpRes, ((((((((((((((acc._5 :+ DeleteEntry(keyStakedTimeByAssetId(landAssetId))) :+ DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))) :+ DeleteEntry(keyLandToAssetId(landNum))) :+ DeleteEntry(keyNftName(landNum, landSize))) :+ DeleteEntry(keyLandAssetIdToOwner(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetId(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyPresaleArtActivatedByAssetId(landAssetId))) :+ DeleteEntry(keyPresaleArtActivatedByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId))) :+ DeleteEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, addr))) :+ DeleteEntry(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ Burn(fromBase58String(landAssetId), 1)), props, removeByIndex(lands, value(idx)))
10261030 }
10271031 }
10281032 }
10291033 }
10301034 }
10311035
10321036 let bpKey = keyBackpackByDuck(duckAssetId)
10331037 let currentPack = getBackpack(bpKey)
10341038 let propStr = valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0")
10351039 let landsKey = keyStakedLandsByOwner(addr)
10361040 let landsStr = getString(landsKey)
10371041 let landsIn = if (isDefined(landsStr))
10381042 then split_51C(value(landsStr), "_")
10391043 else nil
10401044 let r = {
10411045 let $l = landAssetIds
10421046 let $s = size($l)
10431047 let $acc0 = $Tuple7(formula, 0, "", currentPack[bpIdxRes], nil, propStr, landsIn)
10441048 func $f0_1 ($a,$i) = if (($i >= $s))
10451049 then $a
10461050 else checkMerge($a, $l[$i])
10471051
10481052 func $f0_2 ($a,$i) = if (($i >= $s))
10491053 then $a
10501054 else throw("List size exceeds 5")
10511055
10521056 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
10531057 }
10541058 let continent = r._3
10551059 let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
10561060 let terrains = genTerrains(abs(toBigInt(txId)), continentIdx)
10571061 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
10581062 let newLandNum = toString(freeNum)
10591063 let issue = Issue(keyNftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
10601064 let assetId = calculateAssetId(issue)
10611065 let newLandAssetId = toBase58String(assetId)
10621066 let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
10631067 $Tuple2(((((((((((((((r._5 :+ (if ((size(r._7) > 0))
10641068 then StringEntry(landsKey, makeString_11C(r._7, "_"))
10651069 else DeleteEntry(landsKey))) :+ IntegerEntry(keyNextFreeLandNum(), (freeNum + 1))) :+ issue) :+ StringEntry(keyLandToAssetId(newLandNum), newLandAssetId)) :+ StringEntry(keyLandAssetIdToOwner(newLandAssetId), addr)) :+ StringEntry(keyLandNumToOwner(newLandNum), addr)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, newLandAssetId), r._2)) :+ IntegerEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, newLandAssetId, addr), r._2)) :+ IntegerEntry(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), r._6)) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
10661070 }
10671071
10681072
10691073 func s2m (addr,landAssetIds,txId) = mergeInternal("M", 3, "SSSS", addr, landAssetIds, txId, 0)
10701074
10711075
10721076 func m2l (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
10731077 let cost = (InfraUpgradeCostSUsdn * 4)
10741078 if (if (!(shouldUseMat))
10751079 then (paymentAmount != cost)
10761080 else false)
10771081 then throw(("Payment attached should be " + toString(cost)))
10781082 else mergeInternal("L", 4, "SMM", addr, landAssetIds, txId, (InfraUpgradeCostS * 4))
10791083 }
10801084
10811085
10821086 func l2xl (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
10831087 let cost = (InfraUpgradeCostSUsdn * 47)
10841088 if (if (!(shouldUseMat))
10851089 then (paymentAmount != cost)
10861090 else false)
10871091 then throw(("Payment attached should be " + toString(cost)))
10881092 else mergeInternal("XL", 5, "SSSML", addr, landAssetIds, txId, (InfraUpgradeCostS * 47))
10891093 }
10901094
10911095
10921096 func xl2xxl (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
10931097 let cost = (InfraUpgradeCostSUsdn * 54)
10941098 if (if (!(shouldUseMat))
10951099 then (paymentAmount != cost)
10961100 else false)
10971101 then throw(("Payment attached should be " + toString(cost)))
10981102 else mergeInternal("XXL", 6, "LXL", addr, landAssetIds, txId, (InfraUpgradeCostS * 54))
10991103 }
11001104
11011105
11021106 func mergeCommon (shouldUseMat,addr,paymentAmount,landAssetIds,txId) = {
11031107 let mergeResult = match size(landAssetIds) {
11041108 case _ =>
11051109 if ((4 == $match0))
11061110 then s2m(addr, landAssetIds, txId)
11071111 else if ((3 == $match0))
11081112 then m2l(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
11091113 else if ((5 == $match0))
11101114 then l2xl(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
11111115 else if ((2 == $match0))
11121116 then xl2xxl(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
11131117 else throw("Unknown merge")
11141118 }
11151119 mergeResult
11161120 }
11171121
11181122
11191123 func prolog (i) = if (valueOrElse(getBoolean(keyBlocked()), false))
11201124 then throw("Contracts are under maintenance")
11211125 else StringEntry(keyLastTxIdByUser(toString(i.originCaller)), toBase58String(i.transactionId))
11221126
11231127
11241128 @Callable(i)
11251129 func constructorV1 (restAddr) = if ((i.caller != this))
11261130 then throw("Permission denied")
11271131 else [StringEntry(keyRestAddress(), restAddr)]
11281132
11291133
11301134
11311135 @Callable(i)
11321136 func setBlocked (isBlocked) = if ((i.caller != this))
11331137 then throw("permission denied")
11341138 else [BooleanEntry(keyBlocked(), isBlocked)]
11351139
11361140
11371141
11381142 @Callable(i)
11391143 func stakeLand () = {
11401144 let prologAction = prolog(i)
11411145 if ((size(i.payments) != 1))
11421146 then throw("Exactly one payment required")
11431147 else {
11441148 let pmt = value(i.payments[0])
11451149 let assetId = value(pmt.assetId)
11461150 let address = toString(i.caller)
11471151 if ((pmt.amount != 1))
11481152 then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
11491153 else {
11501154 let asset = value(assetInfo(assetId))
11511155 if ((asset.issuer != this))
11521156 then throw("Unknown issuer of token")
11531157 else if (!(contains(asset.name, LANDPREFIX)))
11541158 then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
11551159 else {
11561160 let landNumSize = drop(asset.name, 4)
11571161 let landNum = if (contains(landNumSize, "XXL"))
11581162 then dropRight(landNumSize, 3)
11591163 else if (contains(landNumSize, "XL"))
11601164 then dropRight(landNumSize, 2)
11611165 else dropRight(landNumSize, 1)
11621166 if (!(isDefined(parseInt(landNum))))
11631167 then throw(("Cannot parse land number from " + asset.name))
11641168 else {
11651169 let landAssetId = toBase58String(assetId)
11661170 let timeKey = keyStakedTimeByAssetId(landAssetId)
11671171 if (isDefined(getInteger(timeKey)))
11681172 then throw((("NFT " + asset.name) + " is already staked"))
11691173 else {
11701174 let d = split(asset.description, "_")
11711175 let terrainCounts = countTerrains(d[recTerrains])
11721176 let props = updateProportions(terrainCounts, (numPiecesBySize(d[recLandSize]) / SSIZE), 1)
11731177 let landsStr = getString(keyStakedLandsByOwner(address))
11741178 let lands = if (isDefined(landsStr))
11751179 then split_51C(value(landsStr), "_")
11761180 else nil
11771181 if (containsElement(lands, landAssetId))
11781182 then throw(("Your staked lands already contain " + landAssetId))
11791183 else [IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address), lastBlock.timestamp), StringEntry(keyStakedLandsByOwner(address), makeString_11C((lands :+ landAssetId), "_")), StringEntry(keyLandAssetIdToOwner(landAssetId), address), StringEntry(keyLandNumToOwner(landNum), address), StringEntry(keyResProportions(), props), prologAction]
11801184 }
11811185 }
11821186 }
11831187 }
11841188 }
11851189 }
11861190
11871191
11881192
11891193 @Callable(i)
11901194 func unstakeLand (landAssetIdIn) = {
11911195 let prologAction = prolog(i)
11921196 if ((size(i.payments) != 0))
11931197 then throw("unstake doesn't require any payments")
11941198 else {
11951199 let addr = toString(i.caller)
11961200 let c = checkClaimConditions(addr, claimModeDuck, landAssetIdIn)
11971201 let landAssetId = c._2
11981202 let landsKey = keyStakedLandsByOwner(addr)
11991203 let terrainCounts = countTerrains(c._3[recTerrains])
12001204 let pieces = numPiecesBySize(c._3[recLandSize])
12011205 let props = updateProportions(terrainCounts, (pieces / SSIZE), -1)
12021206 let claimResult = claimAll(addr, landAssetId, pieces, claimModeDuck)
12031207 let lands = split_51C(valueOrElse(getString(landsKey), ""), "_")
12041208 let idx = indexOf(lands, landAssetId)
12051209 if (!(isDefined(idx)))
12061210 then throw(("Your staked lands don't contain " + landAssetId))
12071211 else {
12081212 let t = value(blockInfoByHeight(height)).timestamp
12091213 let releaseTime = valueOrElse(getInteger(govContract, keyUserGwlReleaseTime(addr)), 0)
12101214 if ((releaseTime >= t))
12111215 then throw(("Your gWL are taking part in voting, cannot unstake until " + toString(releaseTime)))
12121216 else [ScriptTransfer(i.caller, 1, fromBase58String(landAssetId)), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr)), StringEntry(keyResProportions(), props), StringEntry(claimResult._2, makeString(claimResult._3, ":")), if ((size(lands) > 1))
12131217 then StringEntry(landsKey, makeString_11C(removeByIndex(lands, value(idx)), "_"))
12141218 else DeleteEntry(landsKey), prologAction]
12151219 }
12161220 }
12171221 }
12181222
12191223
12201224
12211225 @Callable(i)
12221226 func stakeDuck () = {
12231227 let prologAction = prolog(i)
12241228 if ((size(i.payments) != 1))
12251229 then throw("Exactly one payment required")
12261230 else {
12271231 let pmt = value(i.payments[0])
12281232 let assetId = value(pmt.assetId)
12291233 let address = toString(i.caller)
12301234 if ((pmt.amount != 1))
12311235 then throw((("NFT " + DUCKPREFIX) + " token should be attached as payment"))
12321236 else {
12331237 let asset = value(assetInfo(assetId))
12341238 if (if ((asset.issuer != incubatorAddr))
12351239 then (asset.issuer != breederAddr)
12361240 else false)
12371241 then throw((("Unknown issuer of " + DUCKPREFIX) + " token"))
12381242 else if (!(contains(asset.name, DUCKPREFIX)))
12391243 then throw((("Only NFT " + DUCKPREFIX) + " tokens are accepted"))
12401244 else {
12411245 let assetIdStr = toBase58String(assetId)
12421246 let timeKey = keyStakedTimeByAssetId(assetIdStr)
12431247 if (isDefined(getInteger(timeKey)))
12441248 then throw((("NFT " + asset.name) + " is already staked"))
12451249 else if (isDefined(getString(keyStakedDuckByOwner(address))))
12461250 then throw(("You already staked one duck: " + asset.name))
12471251 else {
12481252 let locKey = keyDuckLocation(assetIdStr)
12491253 let location = getString(locKey)
12501254 let bpKey = keyBackpackByDuck(assetIdStr)
12511255 let backpack = getString(bpKey)
12521256 ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
12531257 then nil
12541258 else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
12551259 then nil
12561260 else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyDuckHealth(assetIdStr), 100)) :+ prologAction)))))
12571261 }
12581262 }
12591263 }
12601264 }
12611265 }
12621266
12631267
12641268
12651269 @Callable(i)
12661270 func unstakeDuck (assetIdStr) = {
12671271 let prologAction = prolog(i)
12681272 if ((size(i.payments) != 0))
12691273 then throw("unstake doesn't require any payments")
12701274 else {
12711275 let assetId = fromBase58String(assetIdStr)
12721276 let address = toString(i.caller)
12731277 let asset = value(assetInfo(assetId))
12741278 let timeKey = keyStakedTimeByAssetId(toBase58String(assetId))
1275- if (!(isDefined(timeKey)))
1279+ if (!(isDefined(getInteger(timeKey))))
12761280 then throw((("NFT " + asset.name) + " is not staked"))
1277- else if (!(isDefined(keyStakedDuckByOwner(address))))
1281+ else if (!(isDefined(getString(keyStakedDuckByOwner(address)))))
12781282 then throw((("The duck " + asset.name) + " is not staked"))
12791283 else {
12801284 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(toBase58String(assetId))), (("NFT " + asset.name) + " is orphaned"))
12811285 if ((owner != address))
12821286 then throw("Staked NFT is not yours")
12831287 else {
12841288 let keyHealth = keyDuckHealth(assetIdStr)
12851289 let health = valueOrElse(getInteger(keyHealth), 100)
12861290 if ((health != 100))
12871291 then throw("Please heal your duck before unstaking")
12881292 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]
12891293 }
12901294 }
12911295 }
12921296 }
12931297
12941298
12951299
12961300 @Callable(i)
12971301 func claimRes (amount,landAssetIdStr) = {
12981302 let prologAction = prolog(i)
12991303 if ((size(i.payments) != 0))
13001304 then throw("claimRes doesn't require any payments")
13011305 else {
13021306 let addr = toString(i.originCaller)
13031307 let result = claimResInternal(addr, amount, claimModeDuck, landAssetIdStr)
13041308 $Tuple2((((result._1 :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) :+ prologAction), result._3[bpIdxRes])
13051309 }
13061310 }
13071311
13081312
13091313
13101314 @Callable(i)
13111315 func claimResToWH (amount,landAssetIdStr) = {
13121316 let prologAction = prolog(i)
13131317 if ((size(i.payments) != 0))
13141318 then throw("claimRes doesn't require any payments")
13151319 else {
13161320 let addr = toString(i.originCaller)
13171321 let result = claimResInternal(addr, amount, claimModeWh, landAssetIdStr)
13181322 $Tuple2((((result._1 :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) :+ prologAction), result._5[whIdxRes])
13191323 }
13201324 }
13211325
13221326
13231327
13241328 @Callable(i)
13251329 func flight (message,sig) = {
13261330 let prologAction = prolog(i)
13271331 if (!(sigVerify_8Kb(message, sig, pub)))
13281332 then throw("signature does not match")
13291333 else if ((size(i.payments) != 0))
13301334 then throw("flight doesn't require any payments")
13311335 else {
13321336 let parts = split(toUtf8String(message), ";")
13331337 let hp = split(split(parts[0], "|")[0], "_")
13341338 let curHP = parseIntValue(hp[0])
13351339 let newHP = parseIntValue(hp[1])
13361340 let newLocAndTime = split(parts[1], ":")
13371341 let newLocation = newLocAndTime[0]
13381342 let time = parseIntValue(newLocAndTime[1])
13391343 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
13401344 then true
13411345 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
13421346 then throw("signature outdated")
13431347 else {
13441348 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
13451349 let keyHealth = keyDuckHealth(duckAssetId)
13461350 let oldFromState = valueOrElse(getInteger(keyHealth), 100)
13471351 if ((oldFromState != curHP))
13481352 then throw(((("oldHealth=" + toString(valueOrElse(getInteger(keyHealth), 100))) + " from state does not match one from flight log=") + toString(curHP)))
13491353 else if ((0 >= curHP))
13501354 then throw("You can't fly with zero health")
13511355 else {
13521356 let locKey = keyDuckLocation(duckAssetId)
13531357 let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
13541358 if ((newLocation == curLocation))
13551359 then throw("You can't fly to the same location")
13561360 else $Tuple2([StringEntry(locKey, if ((newHP > 0))
13571361 then newLocation
13581362 else curLocation), IntegerEntry(keyHealth, newHP), prologAction], unit)
13591363 }
13601364 }
13611365 }
13621366 }
13631367
13641368
13651369
13661370 @Callable(i)
13671371 func setHealth (health,duckAssetId) = {
13681372 let prologAction = prolog(i)
13691373 if (if ((0 > health))
13701374 then true
13711375 else (health > 100))
13721376 then throw("HP should be within 0..100")
13731377 else [IntegerEntry(keyDuckHealth(duckAssetId), health), prologAction]
13741378 }
13751379
13761380
13771381
13781382 @Callable(i)
13791383 func heal (matType,amount) = {
13801384 let prologAction = prolog(i)
13811385 if (if ((0 > matType))
13821386 then true
13831387 else (matType >= NUMRES))
13841388 then throw(("Unknown material: " + toString(matType)))
13851389 else if ((0 >= amount))
13861390 then throw(("Amount should be positive! " + toString(amount)))
13871391 else {
13881392 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
13891393 let keyHealth = keyDuckHealth(duckAssetId)
13901394 let oldHealth = valueOrElse(getInteger(keyHealth), 100)
13911395 if ((oldHealth >= 100))
13921396 then throw("HP should be < 100 to heal")
13931397 else {
13941398 let bpKey = keyBackpackByDuck(duckAssetId)
13951399 let currentPack = getBackpack(bpKey)
13961400 let mList = split(currentPack[bpIdxMat], "_")
13971401 let currentAmount = parseIntValue(mList[matType])
13981402 let deltaHealth = min([(amount / HEALCOST), (100 - oldHealth)])
13991403 let spendAmount = (deltaHealth * HEALCOST)
14001404 if ((spendAmount > currentAmount))
14011405 then throw(((((("You need " + toString(spendAmount)) + " of ") + matTypes[matType]) + " to heal, but you backpack contains ") + toString(currentAmount)))
14021406 else {
14031407 let newMat = subOneInList(mList, matType, spendAmount)
14041408 [IntegerEntry(keyHealth, (oldHealth + deltaHealth)), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":")), prologAction]
14051409 }
14061410 }
14071411 }
14081412 }
14091413
14101414
14111415
14121416 @Callable(i)
14131417 func updateBackpack (duckAssetId,newPack) = {
14141418 let prologAction = prolog(i)
14151419 if ((i.caller != economyContract))
14161420 then throw("permission denied")
14171421 else $Tuple2([StringEntry(keyBackpackByDuck(duckAssetId), newPack), prologAction], newPack)
14181422 }
14191423
14201424
14211425
14221426 @Callable(i)
14231427 func buySLand () = if ((i.caller != this))
14241428 then throw("Permission denied")
14251429 else {
14261430 let prologAction = prolog(i)
14271431 if ((size(i.payments) != 1))
14281432 then throw("Exactly one payment required")
14291433 else {
14301434 let pmt = value(i.payments[0])
14311435 if ((pmt.assetId != usdnAssetId))
14321436 then throw("Allowed USDN payment only!")
14331437 else if ((pmt.amount != EXPUSDN))
14341438 then throw(("Payment attached should be " + toString(EXPUSDN)))
14351439 else {
14361440 let result = expeditionInternal(i.caller, i.transactionId)
14371441 $Tuple2(((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdnAssetId)) :+ prologAction), result._2._1)
14381442 }
14391443 }
14401444 }
14411445
14421446
14431447
14441448 @Callable(i)
1445-func expeditionBuy (message,sig) = if ((i.caller != this))
1446- then throw("Permission denied")
1447- else {
1448- let prologAction = prolog(i)
1449- if ((size(i.payments) != 1))
1450- then throw("Exactly one payment required")
1451- else {
1452- let pmt = value(i.payments[0])
1453- if ((pmt.assetId != usdnAssetId))
1454- then throw("Allowed USDN payment only!")
1455- else if ((pmt.amount != EXPUSDN))
1456- then throw(("Payment attached should be " + toString(EXPUSDN)))
1457- else {
1458- let result = expeditionCommon(false, i.caller, i.transactionId, message, sig)
1459- if ((result._2 == ""))
1460- then result
1461- else $Tuple2(((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdnAssetId)) :+ prologAction), result._2)
1462- }
1463- }
1464- }
1465-
1466-
1467-
1468-@Callable(i)
14691449 func expedition (message,sig) = {
14701450 let prologAction = prolog(i)
14711451 if ((size(i.payments) != 0))
14721452 then throw("expedition doesn't require any payments")
14731453 else {
14741454 let result = expeditionCommon(true, i.caller, i.transactionId, message, sig)
14751455 $Tuple2((result._1 :+ prologAction), result._2)
14761456 }
14771457 }
14781458
14791459
14801460
14811461 @Callable(i)
14821462 func upgradeInfra (landAssetId) = {
14831463 let prologAction = prolog(i)
14841464 if ((size(i.payments) != 0))
14851465 then throw("Infrastructure upgrade doesn't require any payments")
14861466 else {
14871467 let result = upInfraCommon(true, i.caller, 0, landAssetId)
14881468 $Tuple2((result._1 :+ prologAction), result._2)
14891469 }
14901470 }
14911471
14921472
14931473
14941474 @Callable(i)
14951475 func upgradeInfraUsdn (landAssetId) = if ((i.caller != this))
14961476 then throw("Permission denied")
14971477 else {
14981478 let prologAction = prolog(i)
14991479 if ((size(i.payments) != 1))
15001480 then throw("Exactly one payment required")
15011481 else {
15021482 let pmt = value(i.payments[0])
15031483 if ((pmt.assetId != usdnAssetId))
15041484 then throw("Allowed USDN payment only!")
15051485 else {
15061486 let result = upInfraCommon(false, i.caller, pmt.amount, landAssetId)
15071487 $Tuple2(((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdnAssetId)) :+ prologAction), result._2)
15081488 }
15091489 }
15101490 }
15111491
15121492
15131493
15141494 @Callable(i)
15151495 func activateArtifact (artName,landAssetId) = {
15161496 let prologAction = prolog(i)
15171497 if ((size(i.payments) != 0))
15181498 then throw("Artifact activation doesn't require any payments")
15191499 else {
15201500 let result = match artName {
15211501 case _ =>
15221502 if (("PRESALE" == $match0))
15231503 then activatePresaleArt(toString(i.caller), landAssetId)
15241504 else throw("Unknown artifact")
15251505 }
15261506 (result :+ prologAction)
15271507 }
15281508 }
15291509
15301510
15311511
15321512 @Callable(i)
15331513 func mergeLands (landAssetIds) = {
15341514 let prologAction = prolog(i)
15351515 if ((size(i.payments) != 0))
15361516 then throw("Lands merging doesn't require any payments")
15371517 else {
15381518 let result = mergeCommon(true, toString(i.caller), 0, landAssetIds, i.transactionId)
15391519 $Tuple2((result._1 :+ prologAction), result._2)
15401520 }
15411521 }
15421522
15431523
15441524
15451525 @Callable(i)
15461526 func mergeLandsUsdn (landAssetIds) = {
15471527 let prologAction = prolog(i)
15481528 if ((size(i.payments) != 1))
15491529 then throw("Exactly one payment required")
15501530 else {
15511531 let pmt = value(i.payments[0])
15521532 if ((pmt.assetId != usdnAssetId))
15531533 then throw("Allowed USDN payment only!")
15541534 else {
15551535 let result = mergeCommon(false, toString(i.caller), pmt.amount, landAssetIds, i.transactionId)
15561536 $Tuple2(((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdnAssetId)) :+ prologAction), result._2)
15571537 }
15581538 }
15591539 }
15601540
15611541
15621542
15631543 @Callable(i)
15641544 func cargoExchange (cargoListStr,landAssetId) = {
1545+ let prologAction = prolog(i)
15651546 let cargoParts = split_4C(cargoListStr, ":")
15661547 let addr = toString(i.originCaller)
15671548 let asset = value(assetInfo(fromBase58String(landAssetId)))
15681549 let timeKey = keyStakedTimeByAssetId(landAssetId)
1569- if (!(isDefined(timeKey)))
1550+ if (!(isDefined(getInteger(timeKey))))
15701551 then throw((asset.name + " is not staked"))
15711552 else {
15721553 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
15731554 if ((owner != addr))
15741555 then throw((LANDPREFIX + " is not yours"))
15751556 else {
15761557 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
15771558 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
15781559 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
15791560 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
15801561 let loc = split(value(curLocation), "_")
15811562 if ((loc[locIdxType] != "L"))
15821563 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
15831564 else if ((loc[locIdxId] != landAssetId))
15841565 then throw(("Duck should be on the land " + landAssetId))
15851566 else {
15861567 let whKey = keyWarehouseByLand(landAssetId)
15871568 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
15881569 let bpKey = keyBackpackByDuck(duckAssetId)
15891570 let currentPack = getBackpack(bpKey)
15901571 let result = moveStuff(cargoParts, currentWh, currentPack)
1591-[StringEntry(bpKey, makeString([currentPack[bpIdxLevel], result._4, result._5, result._6], ":")), StringEntry(whKey, makeString([currentWh[whIdxVol], result._1, result._2, result._3], ":"))]
1572+[StringEntry(bpKey, makeString([currentPack[bpIdxLevel], result._4, result._5, result._6], ":")), StringEntry(whKey, makeString([currentWh[whIdxVol], result._1, result._2, result._3, currentWh[whIdxLockedVol]], ":")), prologAction]
15921573 }
15931574 }
1575+ }
1576+ }
1577+
1578+
1579+
1580+@Callable(i)
1581+func saveWarehouse (whStr,landAssetId) = {
1582+ let prologAction = prolog(i)
1583+ if ((i.caller != economyContract))
1584+ then throw("Access denied")
1585+ else {
1586+ let whKey = keyWarehouseByLand(landAssetId)
1587+ if ((size(split_4C(whStr, ":")) != 5))
1588+ then throw("warehouse string should contain 4 ':' separators")
1589+ else $Tuple2([StringEntry(whKey, whStr), prologAction], whStr)
15941590 }
15951591 }
15961592
15971593
15981594
15991595 @Callable(i)
16001596 func splitByGlobalWeightsREADONLY (amount) = $Tuple2(nil, getNeededMaterials(amount))
16011597
16021598
16031599
16041600 @Callable(i)
16051601 func splitByGlobalAndLocalWeightsREADONLY (matAmount,resAmount,terrains) = {
16061602 let terrainCounts = countTerrains(terrains)
16071603 $Tuple2(nil, $Tuple2(getNeededMaterials(matAmount), distributeByWeights(resAmount, terrainCounts)))
16081604 }
16091605
16101606
16111607
16121608 @Callable(i)
16131609 func getBackpackREADONLY (duckAssetId) = $Tuple2(nil, makeString(getBackpack(keyBackpackByDuck(duckAssetId)), ":"))
16141610
16151611
16161612
16171613 @Callable(i)
16181614 func getWarehouseREADONLY (landAssetId) = {
16191615 let asset = value(assetInfo(fromBase58String(landAssetId)))
16201616 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
16211617 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1622- $Tuple2(nil, makeString(getWarehouse(keyWarehouseByLand(landAssetId), landIndex, infraLevel), ":"))
1618+ $Tuple2(nil, makeString_2C(getWarehouse(keyWarehouseByLand(landAssetId), landIndex, infraLevel), ":"))
16231619 }
16241620
16251621

github/deemru/w8io/169f3d6 
181.37 ms