tx · 6Ecs2wULeZs81TzNNQfr3ZVrbyYB4eziHytn8vib6ss2

3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm:  -0.09500000 Waves

2023.12.29 23:12 [2908526] smart account 3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm > SELF 0.00000000 Waves

{ "type": 13, "id": "6Ecs2wULeZs81TzNNQfr3ZVrbyYB4eziHytn8vib6ss2", "fee": 9500000, "feeAssetId": null, "timestamp": 1703880790712, "version": 2, "chainId": 84, "sender": "3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm", "senderPublicKey": "EVooykMNV691Venwp1dHUTBd7KWequzUcda57Wd3LQEX", "proofs": [ "4f7DKz1rkqKXEwTaprpeewMxbRZNdNaBjyxEVn9FPapXXTSepnJ1sZkUPSVTTZLin9uc8YLgSZh6m9R392vEjrBg" ], "script": "base64:BgLIAQgCEgMKAQgSBAoCCAESAwoBBBIAEgMKAQgSABIDCgEIEgQKAgEIEgQKAgEIEgQKAgICEgUKAwEBARIAEgQKAggIEgASAwoBARIAEgQKAgICEgASAwoBCBIECgIICBIDCgEYEgQKAggIEgQKAggIEgUKAwgICBIECgIICBIHCgUBAQEBARIDCgEBEgUKAwEBCBIDCgEIEgMKAQgSABIECgIIARIECgIIARIDCgEIEgMKAQgSABIAEgMKAQgSAwoBCBIECgICAhIAmAIACURBWU1JTExJUwCAuJkpARRrZXlMYXN0QXJiVGltZUJ5VXNlcgEEYWRkcgkArAICAhBsYXN0QXJiVGltZVVzZXJfBQRhZGRyARprZXlBY3Jlc1N0YWtlZEFtb3VudEJ5VXNlcgEEYWRkcgkArAICAhhhY3Jlc1N0YWtlZEFtb3VudEJ5VXNlcl8FBGFkZHIABlNDQUxFOACAwtcvAAx4cExldmVsU2NhbGUAgBkAD3hwTGV2ZWxSZWNpcFBvdwCgHwASbnVtUG9pbnRzT25MZXZlbFVwAAMADHJlcXVpcmVtZW50cwkAzAgCAghTdHJlbmd0aAkAzAgCAghBY2N1cmFjeQkAzAgCAglJbnRlbGxlY3QJAMwIAgIJRW5kdXJhbmNlCQDMCAICCURleHRlcml0eQkAzAgCAgVMZXZlbAkAzAgCAgZIZWFsdGgFA25pbAAMY2hhclN0cmVuZ3RoAAAADGNoYXJBY2N1cmFjeQABAA1jaGFySW50ZWxsZWN0AAIADWNoYXJFbmR1cmFuY2UAAwANY2hhckRleHRlcml0eQAEAAtzZWdCYWNrcGFjawAAAAtOVU1TRUdNRU5UUwAGAApOVU1NQUlOQVVYAAIACE1BWFNMT1RTAAIADU1BWFBST0RJTlNMT1QAHgENa2V5RHVja0hlYWx0aAELZHVja0Fzc2V0SWQJAKwCAgILZHVja0hlYWx0aF8FC2R1Y2tBc3NldElkAQxrZXlEdWNrQ2hhcnMBC2R1Y2tBc3NldElkCQCsAgICCmR1Y2tDaGFyc18FC2R1Y2tBc3NldElkAQlrZXlEdWNrWFABC2R1Y2tBc3NldElkCQCsAgICB2R1Y2tYUF8FC2R1Y2tBc3NldElkAQxrZXlEdWNrTGV2ZWwBC2R1Y2tBc3NldElkCQCsAgICCmR1Y2tMZXZlbF8FC2R1Y2tBc3NldElkARFrZXlEdWNrRnJlZVBvaW50cwELZHVja0Fzc2V0SWQJAKwCAgIPZHVja0ZyZWVQb2ludHNfBQtkdWNrQXNzZXRJZAEQa2V5RHVja0VxdWlwbWVudAELZHVja0Fzc2V0SWQJAKwCAgIOZHVja0VxdWlwbWVudF8FC2R1Y2tBc3NldElkAQlrZXlVc2VyWFABBGFkZHIJAKwCAgIHdXNlclhQXwUEYWRkcgEMa2V5VXNlckxldmVsAQRhZGRyCQCsAgICCnVzZXJMZXZlbF8FBGFkZHIBEWtleVVzZXJGcmVlUG9pbnRzAQRhZGRyCQCsAgICD3VzZXJGcmVlUG9pbnRzXwUEYWRkcgEOa2V5U2F2ZWRIZWFsdGgBC2R1Y2tBc3NldElkCQCsAgICDHNhdmVkSGVhbHRoXwULZHVja0Fzc2V0SWQBEGtleVNhdmVkTG9jYXRpb24BC2R1Y2tBc3NldElkCQCsAgICDnNhdmVkTG9jYXRpb25fBQtkdWNrQXNzZXRJZAEMa2V5RHVja0J1ZmZzAQtkdWNrQXNzZXRJZAkArAICAgpkdWNrQnVmZnNfBQtkdWNrQXNzZXRJZAEYa2V5TGFzdFJvYmJlcnlUaW1lQnlEdWNrAQtkdWNrQXNzZXRJZAkArAICAhBsYXN0Um9iYmVyeVRpbWVfBQtkdWNrQXNzZXRJZAETa2V5RHVja1JvYmJlcnlDb3VudAELZHVja0Fzc2V0SWQJAKwCAgIYdG90YWxSb2JiZXJ5Q291bnRCeUR1Y2tfBQtkdWNrQXNzZXRJZAETa2V5VXNlclJvYmJlcnlDb3VudAEEYWRkcgkArAICAhF1c2VyUm9iYmVyeUNvdW50XwUEYWRkcgEVa2V5VXNlckxhc3RSb2JiZXJ5RGF5AQRhZGRyCQCsAgICE3VzZXJMYXN0Um9iYmVyeURheV8FBGFkZHIBFGtleUR1Y2tEZWxpdmVyeUNvdW50AQtkdWNrQXNzZXRJZAkArAICAhl0b3RhbERlbGl2ZXJ5Q291bnRCeUR1Y2tfBQtkdWNrQXNzZXRJZAEUa2V5VXNlckRlbGl2ZXJ5Q291bnQBBGFkZHIJAKwCAgISdXNlckRlbGl2ZXJ5Q291bnRfBQRhZGRyARZrZXlVc2VyTGFzdERlbGl2ZXJ5RGF5AQRhZGRyCQCsAgICFHVzZXJMYXN0RGVsaXZlcnlEYXlfBQRhZGRyAAd4cENsYWltAJBOAA94cFN1Y2Nlc3NGbGlnaHQAkE4ADHhwRmFpbEZsaWdodADQDwAMeHBTdWNjZXNzUm9iAJBOAAl4cEZhaWxSb2IA0A8ACHhwQ2FsbEVTAKCNBgAMeHBDdXN0b21OYW1lAMCEPQAKeHBOZXdTTGFuZADAlrECAA54cFVwZ3JhZGVJbmZyYQCQTgAHeHBNZXJnZQDAhD0ACXhwT25ib2FyZADAhD0ABnhwSGVhbACQTgEJbGV2ZWxCeVhQAQJ4cAkAawMFDHhwTGV2ZWxTY2FsZQkAbAYFAnhwAAQFD3hwTGV2ZWxSZWNpcFBvdwAEAAQFBERPV04FBlNDQUxFOAEJbWF4SGVhbHRoAQVsZXZlbAkAZAIAZAUFbGV2ZWwBB2xldmVsVXACCWN1cnJMZXZlbAVuZXdYUAQIbmV3TGV2ZWwJAQlsZXZlbEJ5WFABBQVuZXdYUAkAzAgCBQhuZXdMZXZlbAkAzAgCCQBoAgUSbnVtUG9pbnRzT25MZXZlbFVwCQBlAgUIbmV3TGV2ZWwFCWN1cnJMZXZlbAUDbmlsAQxnZXREdWNrU3RhdHMED3N0YWtpbmdDb250cmFjdAtkdWNrQXNzZXRJZApidWZmRWZmZWN0CmZvcmNlQnVmZnMEBWNoYXJzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEMa2V5RHVja0NoYXJzAQULZHVja0Fzc2V0SWQCCTBfMF8wXzBfMAIBXwQDbHZsCQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBDGtleUR1Y2tMZXZlbAEFC2R1Y2tBc3NldElkAAAEBmhlYWx0aAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9zdGFraW5nQ29udHJhY3QJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQJAQltYXhIZWFsdGgBBQNsdmwECnN0YXRlQnVmZnMJALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJAQxrZXlEdWNrQnVmZnMBBQtkdWNrQXNzZXRJZAIJMF8wXzBfMF8wAgFfCQDOCAIJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQxjaGFyU3RyZW5ndGgJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQxjaGFyQWNjdXJhY3kJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQ1jaGFySW50ZWxsZWN0CQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUNY2hhckVuZHVyYW5jZQkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDWNoYXJEZXh0ZXJpdHkJAMwIAgUDbHZsCQDMCAIFBmhlYWx0aAUDbmlsAwUKZm9yY2VCdWZmcwkAzAgCBQpidWZmRWZmZWN0CQDMCAIFCmJ1ZmZFZmZlY3QJAMwIAgUKYnVmZkVmZmVjdAkAzAgCBQpidWZmRWZmZWN0CQDMCAIFCmJ1ZmZFZmZlY3QFA25pbAkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKc3RhdGVCdWZmcwUMY2hhclN0cmVuZ3RoCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpzdGF0ZUJ1ZmZzBQxjaGFyQWNjdXJhY3kJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCnN0YXRlQnVmZnMFDWNoYXJJbnRlbGxlY3QJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCnN0YXRlQnVmZnMFDWNoYXJFbmR1cmFuY2UJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCnN0YXRlQnVmZnMFDWNoYXJEZXh0ZXJpdHkFA25pbAAKTEFORFBSRUZJWAIETEFORAAKRFVDS1BSRUZJWAIERFVDSwALUk9CT19QUkVGSVgCBFJPQk8ACkFSVFBSRVNBTEUCB1BSRVNBTEUABk5VTVJFUwAGABhNQVhfTEFORFNfU1RBS0VEX0JZX1VTRVIAGQAPREFJTFlSRVNCWVBJRUNFAID40gEADFdITVVMVElQTElFUgCAyK+gJQAPREVGQVVMVExPQ0FUSU9OAg9BZnJpY2FfRl9BZnJpY2EAEFJFU09VUkNFUFJJQ0VNSU4A1bUCAApFU1NFTExDT0VGAAoAFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQDQhgMAEk1JTl9XTEdPTERfUk9CQkVSWQCAwtcvABZBTExPV0VEX0ZSRUVfUk9CQkVSSUVTAAAAGUFDUkVTX0ZPUl9ST0JCRVJZX0FUVEVNUFQAgISvXwAXQUxMT1dFRF9GUkVFX0RFTElWRVJJRVMAAAAaQUNSRVNfRk9SX0RFTElWRVJZX0FUVEVNUFQAgISvXwAJcHJvZFR5cGVzCQDMCAICEEZpcnN0IEFpZCBLaXQgTDEJAMwIAgIQRmlyc3QgQWlkIEtpdCBMMgkAzAgCAhBGaXJzdCBBaWQgS2l0IEwzCQDMCAICC0JhY2twYWNrIEwxCQDMCAICC0JhY2twYWNrIEwyCQDMCAICC0JhY2twYWNrIEwzCQDMCAICDkZvb2QgUmF0aW9uIEwxCQDMCAICDkZvb2QgUmF0aW9uIEwyCQDMCAICDkZvb2QgUmF0aW9uIEwzCQDMCAICC0pldCBQYWNrIEwxCQDMCAICC0pldCBQYWNrIEwyCQDMCAICC0pldCBQYWNrIEwzCQDMCAICCVNoaWVsZCBMMQkAzAgCAglTaGllbGQgTDIJAMwIAgIJU2hpZWxkIEwzCQDMCAICB01pbmUgTDEJAMwIAgIHTWluZSBMMgkAzAgCAgdNaW5lIEwzCQDMCAICB1RyYXAgTDEJAMwIAgIHVHJhcCBMMgkAzAgCAgdUcmFwIEwzCQDMCAICC0Jvb20tRG9nIEwxCQDMCAICC0Jvb20tRG9nIEwyCQDMCAICC0Jvb20tRG9nIEwzBQNuaWwACmNvbnRpbmVudHMJAMwIAgIIQW1lcmljYXMJAMwIAgIGRXVyb3BlCQDMCAICBEFzaWEJAMwIAgIGQWZyaWNhCQDMCAICB09jZWFuaWEFA25pbAAJQ09FRkYyTUFUAICt4gQAEHByb2R1Y3Rpb25NYXRyaXgJAMwIAgIlOF84XzhfMTdfMTdfNDJfMTJfMF8zMF8wLDAsMCwwLDAsMCwwXwkAzAgCAiU4XzhfOF8xN18xN180Ml8yNF8wXzYwXzAsMCw1LDIsMCwwLDBfCQDMCAICJzhfOF84XzE3XzE3XzQyXzM2XzBfMTIwXzAsMCwxMCw0LDAsMCwwXwkAzAgCAik4XzE5XzE5XzhfMjdfMTlfMjZfMV8yMF8wLDAsMCwwLDAsMCwwXzAwMQkAzAgCAik4XzE5XzE5XzhfMjdfMTlfNTJfMV80MF8wLDAsMCwwLDAsMCwwXzAwMQkAzAgCAik4XzE5XzE5XzhfMjdfMTlfNzhfMV84MF8wLDAsMCwwLDAsMCwwXzAwMQkAzAgCAiU4XzhfOF84XzhfNjBfMTNfMl8yXzAsMCwwLDAsMCwwLDBfMDExCQDMCAICJThfOF84XzhfOF82MF8yNl8yXzRfMCwwLDAsMCwwLDAsMF8wMTEJAMwIAgIlOF84XzhfOF84XzYwXzM5XzJfOF8wLDAsMCwwLDAsMCwwXzAxMQkAzAgCAikzMF8zMF8zXzE3XzE3XzNfMzBfM18zMF8wLDAsMCwwLDAsMCwwXzExMQkAzAgCAikzMF8zMF8zXzE3XzE3XzNfNjBfM181MF8wLDAsMCwwLDAsMCwwXzExMQkAzAgCAikzMF8zMF8zXzE3XzE3XzNfOTBfM183MF8wLDAsMCwwLDAsMCwwXzExMQkAzAgCAisxOF8xOF8xMF8xOF8xOF8xOF8xMV80XzEwXzAsMCwwLDAsMCwwLDBfMjAxCQDMCAICKzE4XzE4XzEwXzE4XzE4XzE4XzIyXzRfMjBfMCwwLDAsMCwwLDAsMF8yMDEJAMwIAgIrMThfMThfMTBfMThfMThfMThfMzNfNF8zMF8wLDAsMCwwLDAsMCwwXzIwMQkAzAgCAio0XzEzXzIyXzRfMzVfMjJfMjNfMF81MCwxLDBfMCwwLDAsMCwwLDAsMF8JAMwIAgIqNF8xM18yMl80XzM1XzIyXzQ2XzBfNTAsMSwxXzAsMiw1LDAsMCwwLDBfCQDMCAICKzRfMTNfMjJfNF8zNV8yMl82OV8wXzUwLDIsMV8wLDUsMTAsMCwwLDAsMF8JAMwIAgIqNV8yNV80MF81XzEwXzE1XzIwXzFfMzAsMSwxXzAsMCwwLDAsMCwwLDBfCQDMCAICKjVfMjVfNDBfNV8xMF8xNV80MF8xXzMwLDEsMl8yLDEsMywwLDAsMCwwXwkAzAgCAio1XzI1XzQwXzVfMTBfMTVfNjBfMV8zMCwxLDNfNSwyLDgsMCwwLDAsMF8JAMwIAgInMjNfMjNfNV8yMF8yM182XzM1XzJfMTAwXzAsMCwwLDAsMCwwLDBfCQDMCAICJzIzXzIzXzVfMjBfMjNfNl83MF8yXzE1MF8wLDAsMCwwLDAsMCwwXwkAzAgCAigyM18yM181XzIwXzIzXzZfMTA1XzJfMjAwXzAsMCwwLDAsMCwwLDBfBQNuaWwACXJJZHhDb2VmZgAGAApySWR4RWZmZWN0AAgAEHJJZHhSZXF1aXJlbWVudHMACQAJcklkeFNsb3RzAAoADlBST0RVQ1RQS0dTSVpFAAoAC3doSWR4TGV2ZWxzAAAACHdoSWR4UmVzAAEACHdoSWR4TWF0AAIACXdoSWR4UHJvZAADAAl3aElkeExPRlQABAAJdm9sTG9ja2VkAAAAC3ZvbE9jY3VwaWVkAAEAB3ZvbEZyZWUAAgAIdm9sVG90YWwAAwAKYnBJZHhMZXZlbAAAAAhicElkeFJlcwABAAhicElkeE1hdAACAAlicElkeFByb2QAAwAPbG9jSWR4Q29udGluZW50AAAACmxvY0lkeFR5cGUAAQAIbG9jSWR4SWQAAgEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQdhc3NldElkCQCsAgICA25vXwUHYXNzZXRJZAEaa2V5TGFuZEFzc2V0SWRUb0N1c3RvbU5hbWUBB2Fzc2V0SWQJAKwCAgIFbGNuYV8FB2Fzc2V0SWQBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBB2Fzc2V0SWQJAKwCAgIDc3RfBQdhc3NldElkASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIEdHlwZQdhc3NldElkCQC5CQIJAMwIAgIDbGFzCQDMCAIFBHR5cGUJAMwIAgUHYXNzZXRJZAUDbmlsAgFfASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwduZnRUeXBlB2Fzc2V0SWQJb3duZXJBZGRyCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIGc3R0YW9fBQduZnRUeXBlAgFfBQdhc3NldElkAgFfBQlvd25lckFkZHIBEmtleVdhcmVob3VzZUJ5TGFuZAELbGFuZEFzc2V0SWQJAKwCAgIDd2hfBQtsYW5kQXNzZXRJZAEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEHYXNzZXRJZAkArAICAgtpbmZyYUxldmVsXwUHYXNzZXRJZAEaa2V5RHVja0Fzc2V0SWRUb0N1c3RvbU5hbWUBB2Fzc2V0SWQJAKwCAgIYZHVja0N1c3RvbU5hbWVCeUFzc2V0SWRfBQdhc3NldElkARZrZXlBZGRyZXNzVG9DdXN0b21OYW1lAQRhZGRyCQCsAgICGGFjY291bnRDdXN0b21OYW1lQnlBZGRyXwUEYWRkcgEPa2V5QWRkcmVzc1JlZkJ5AQRhZGRyCQCsAgICCWFjY1JlZkJ5XwUEYWRkcgEca2V5T25ib2FyZEFydEFjdGl2YXRlZE9uRHVjawELZHVja0Fzc2V0SWQJAKwCAgIab25ib2FyZEFydEFjdGl2YXRlZE9uRHVja18FC2R1Y2tBc3NldElkARxrZXlPbmJvYXJkQXJ0RHVja0FjdGl2YXRlZEJ5AQRhZGRyCQCsAgICGm9uYm9hcmRBcnRBY3RpdmF0ZWREdWNrQnlfBQRhZGRyARNrZXlBZGRyZXNzUmVmZXJyYWxzAQRhZGRyCQCsAgICDWFjY1JlZmVycmFsc18FBGFkZHIBEGtleUR1Y2tJZFRvT3duZXIBB2Fzc2V0SWQJAKwCAgIKZHVja093bmVyXwUHYXNzZXRJZAEUa2V5U3Rha2VkRHVja0J5T3duZXIBCW93bmVyQWRkcgkArAICAhJzdGFrZWREdWNrQnlPd25lcl8FCW93bmVyQWRkcgERa2V5QmFja3BhY2tCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICCWJhY2tQYWNrXwULZHVja0Fzc2V0SWQBD2tleUR1Y2tMb2NhdGlvbgELZHVja0Fzc2V0SWQJAKwCAgINZHVja0xvY2F0aW9uXwULZHVja0Fzc2V0SWQBFWtleVVzZXJHd2xSZWxlYXNlVGltZQEIdXNlckFkZHIJAKwCAgIaJXMlc19fdXNlckd3bFJlbGVhc2VUaW1lX18FCHVzZXJBZGRyAQ5rZXlFc1dhcmVob3VzZQACGmVtZXJnZW5jeVdhcmVob3VzZVByb2R1Y3RzAA9kZWxpdmVyeUZ1bmRLZXkCDGRlbGl2ZXJ5RnVuZAANbGFzdFRvdXJJZEtleQIOJXNfX2xhc3RUb3VySWQBFWtleVRvdXJTdGF0aWNEYXRhQnlJZAEDdElkCQCsAgICFiVzJWRfX3RvdXJTdGF0aWNEYXRhX18JAKQDAQUDdElkARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQN0SWQJAKwCAgIXJXMlZF9fdG91ckR5bmFtaWNEYXRhX18JAKQDAQUDdElkARprZXlCZXN0UmVzdWx0QnlUb3VyQW5kRHVjawIDdElkC2R1Y2tBc3NldElkCQC5CQIJAMwIAgIfJXMlZCVzX19iZXN0UmVzdWx0QnlUb3VyQW5kRHVjawkAzAgCCQCkAwEFA3RJZAkAzAgCBQtkdWNrQXNzZXRJZAUDbmlsAgJfXwAJaWR4U3RhdGljAAAACmlkeER5bmFtaWMAAQAKdFN0YXRpY0VuZAAGAA50RHluYW1pY1N0YXR1cwABAQtnZXRUb3VyRGF0YQIMdG91ckNvbnRyYWN0A3RJZAQGc3RhdGljCQC1CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQx0b3VyQ29udHJhY3QJARVrZXlUb3VyU3RhdGljRGF0YUJ5SWQBBQN0SWQJAKwCAgkArAICAhlFcnJvciByZWFkaW5nIHRvdXJuYW1lbnQgCQCkAwEFA3RJZAIFIGRhdGECAl9fBAdkeW5hbWljCQC8CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQx0b3VyQ29udHJhY3QJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUDdElkCQCsAgIJAKwCAgIZRXJyb3IgcmVhZGluZyB0b3VybmFtZW50IAkApAMBBQN0SWQCBSBkYXRhAgJfXwkAzAgCBQZzdGF0aWMJAMwIAgUHZHluYW1pYwUDbmlsAQ5pc0luVG91cm5hbWVudAIMdG91ckNvbnRyYWN0CGxvY2F0aW9uBAZsYXN0SWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUMdG91ckNvbnRyYWN0BQ1sYXN0VG91cklkS2V5AAAEA2xvYwkAtQkCBQhsb2NhdGlvbgIBXwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFDHRvdXJDb250cmFjdAUGbGFzdElkBAZzdGF0aWMJAJEDAgUFdERhdGEFCWlkeFN0YXRpYwQHZHluYW1pYwkAkQMCBQV0RGF0YQUKaWR4RHluYW1pYwMDAwkAAAIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFUCQAAAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2xvYwUPbG9jSWR4Q29udGluZW50BQZsYXN0SWQHCQAAAgkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwIKSU5QUk9HUkVTUwcJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBQp0U3RhdGljRW5kBQNub3cHAQlvbk1pc3Npb24CDHRvdXJDb250cmFjdAhsb2NhdGlvbgQGbGFzdElkCQELdmFsdWVPckVsc2UCCQCaCAIFDHRvdXJDb250cmFjdAUNbGFzdFRvdXJJZEtleQAABANsb2MJALUJAgUIbG9jYXRpb24CAV8EA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAEBXREYXRhCQELZ2V0VG91ckRhdGECBQx0b3VyQ29udHJhY3QFBmxhc3RJZAQGc3RhdGljCQCRAwIFBXREYXRhBQlpZHhTdGF0aWMEB2R5bmFtaWMJAJEDAgUFdERhdGEFCmlkeER5bmFtaWMEB2xvY1R5cGUJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAwMDCQAAAgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAVQJAAACCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDbG9jBQ9sb2NJZHhDb250aW5lbnQFBmxhc3RJZAcJAAACCQCRAwIFB2R5bmFtaWMFDnREeW5hbWljU3RhdHVzAgpJTlBST0dSRVNTBwkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFCnRTdGF0aWNFbmQFA25vdwcBEmdldFJlY2lwZU1hdGVyaWFscwEGcmVjaXBlCQBoAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnJlY2lwZQUJcklkeENvZWZmBQlDT0VGRjJNQVQBDGNoZWF0QXR0ZW1wdAMGb2xkTG9jBm5ld0xvYwljaGVhdENhc2UJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIWQ2hlYXQgYXR0ZW1wdDogb2xkTG9jPQUGb2xkTG9jAgksIG5ld0xvYz0FBm5ld0xvYwIHLCBjYXNlPQkApAMBBQljaGVhdENhc2UAFktTX1NFUEFSQVRFX1BVQkxJQ19LRVkHABhLU19BTExPV19CSUdfSU5GUkFfTUVSR0UHABNLU19BTExPV19ST0JPX0RVQ0tTBwAKREFZX01JTExJUwCAuJkpAAVjaGFpbgkAyQECCQDKAQIIBQR0aGlzBWJ5dGVzAAEAAQADcHViBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAwUWS1NfU0VQQVJBVEVfUFVCTElDX0tFWQEgqxdXjxVn41lUQbDWcutmm8Sj02Ze1ZmGUN+YNx+yCQgBIE9T4ho/VKjWnVJOEx1GJ1W9s1PzLHvJVFSw/0PBtBQoAwkAAAIBAVQFByRtYXRjaDABIE9T4ho/VKjWnVJOEx1GJ1W9s1PzLHvJVFSw/0PBtBQoCQACAQINVW5rbm93biBjaGFpbgALdXNkdEFzc2V0SWQEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDABIITaerIIAz9O0bvKju6Lk7zJgt0LXfoHlqjUI/moD/+5AwkAAAIBAVQFByRtYXRjaDABIFWx2J9yh4Lv5eNbjawFq2XemkOhLxa7BfMat4el8cUYCQACAQINVW5rbm93biBjaGFpbgAVZGVmYXVsdFJlc3RBZGRyZXNzU3RyBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAiMzUFFDdXZGYnZoNExrUFVucm5VMXozam5iQTFwOW0zV05odgMJAAACAQFUBQckbWF0Y2gwAiMzTXVta0dHenRDS0FYcFdEcXhrZGRvZnFYU1VicVFrdlNKeQkAAgECDVVua25vd24gY2hhaW4AEUluZnJhVXBncmFkZUNvc3RTBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAIDIr6AlAwkAAAIBAVQFByRtYXRjaDAAgMLXLwkAAgECDVVua25vd24gY2hhaW4ADmFyYml0cmFnZURlbGF5BAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwBQpEQVlfTUlMTElTAwkAAAIBAVQFByRtYXRjaDAA4NQDCQACAQINVW5rbm93biBjaGFpbgADU0VQAgJfXwAFTVVMVDYAwIQ9AAVNVUxUOACAwtcvAAVTU0laRQAZAAVNU0laRQBkAAVMU0laRQDhAQAGWExTSVpFAJADAAdYWExTSVpFAPEEAAVJVEVSNgkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQUDbmlsAQ9nZXRTdHJpbmdPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUHYWRkcmVzcwUDa2V5CQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFB2FkZHJlc3MJAMwIAgIBLgkAzAgCBQNrZXkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAARSWR4Q2ZnU3Rha2luZ0RhcHAAAQARSWR4Q2ZnRWNvbm9teURhcHAAAgAUSWR4Q2ZnR292ZXJuYW5jZURhcHAAAwANSWR4Q2ZnV2xnRGFwcAAEABRJZHhDZmdUb3VybmFtZW50RGFwcAAHAA9JZHhDZmdBY3Jlc0RhcHAACAEKa2V5UmVzdENmZwACDiVzX19yZXN0Q29uZmlnAQ5rZXlSZXN0QWRkcmVzcwACDCVzX19yZXN0QWRkcgERcmVhZFJlc3RDZmdPckZhaWwBBHJlc3QJALwJAgkBD2dldFN0cmluZ09yRmFpbAIFBHJlc3QJAQprZXlSZXN0Q2ZnAAUDU0VQARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCB3Jlc3RDZmcDaWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQdyZXN0Q2ZnBQNpZHgJAKwCAgIqUmVzdCBjZmcgZG9lc24ndCBjb250YWluIGFkZHJlc3MgYXQgaW5kZXggCQCkAwEFA2lkeAAMcmVzdENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJAQ5rZXlSZXN0QWRkcmVzcwAFFWRlZmF1bHRSZXN0QWRkcmVzc1N0cgAHcmVzdENmZwkBEXJlYWRSZXN0Q2ZnT3JGYWlsAQUMcmVzdENvbnRyYWN0AA9zdGFraW5nQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBRFJZHhDZmdTdGFraW5nRGFwcAAPZWNvbm9teUNvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwURSWR4Q2ZnRWNvbm9teURhcHAAC2dvdkNvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUUSWR4Q2ZnR292ZXJuYW5jZURhcHAAC3dsZ0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUNSWR4Q2ZnV2xnRGFwcAASdG91cm5hbWVudENvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUUSWR4Q2ZnVG91cm5hbWVudERhcHAADWFjcmVzQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBQ9JZHhDZmdBY3Jlc0RhcHAACnJlY0xhbmROdW0AAAALcmVjTGFuZFNpemUAAQALcmVjVGVycmFpbnMAAgAMcmVjQ29udGluZW50AAMADXdsZ0Fzc2V0SWRLZXkCC3dsZ19hc3NldElkAAp3bGdBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJwIAgULd2xnQ29udHJhY3QFDXdsZ0Fzc2V0SWRLZXkCGFdMR09MRCBpcyBub3QgaXNzdWVkIHlldAAPYWNyZXNBc3NldElkS2V5AgxhY3Jlc0Fzc2V0SWQADGFjcmVzQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCcCAIFDWFjcmVzQ29udHJhY3QFD2FjcmVzQXNzZXRJZEtleQIXQUNSRVMgaXMgbm90IGlzc3VlZCB5ZXQAC3JhbmRvbURlbGF5AAIBCWtleUNvbW1pdAEHYWRkcmVzcwkArAICAg9maW5pc2hCbG9ja0Zvcl8FB2FkZHJlc3MBEWtleVJlc1Byb3BvcnRpb25zAAITcmVzVHlwZXNQcm9wb3J0aW9ucwEWa2V5UmVzVHlwZXNCeUNvbnRpbmVudAEJY29udGluZW50CQCsAgICFHJlc1R5cGVzQnlDb250aW5lbnRfBQljb250aW5lbnQBFWtleVN0YWtlZExhbmRzQnlPd25lcgEJb3duZXJBZGRyCQCsAgICE3N0YWtlZExhbmRzQnlPd25lcl8FCW93bmVyQWRkcgEWa2V5U3Rha2VkUGllY2VzQnlPd25lcgEJb3duZXJBZGRyCQCsAgICFHN0YWtlZFBpZWNlc0J5T3duZXJfBQlvd25lckFkZHIBCGFzU3RyaW5nAQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAUBcwkAAgECGGZhaWwgdG8gY2FzdCBpbnRvIFN0cmluZwEFYXNJbnQBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIDSW50BAFuBQckbWF0Y2gwBQFuCQACAQIVZmFpbCB0byBjYXN0IGludG8gSW50AQlhc0FueUxpc3QBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIJTGlzdFtBbnldBAFsBQckbWF0Y2gwBQFsCQACAQIbZmFpbCB0byBjYXN0IGludG8gTGlzdFtBbnldAQlhc0Jvb2xlYW4BAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIHQm9vbGVhbgQBcwUHJG1hdGNoMAUBcwkAAgECGWZhaWwgdG8gY2FzdCBpbnRvIEJvb2xlYW4BD251bVBpZWNlc0J5U2l6ZQEIbGFuZFNpemUEByRtYXRjaDAFCGxhbmRTaXplAwkAAAICAVMFByRtYXRjaDAFBVNTSVpFAwkAAAICAU0FByRtYXRjaDAFBU1TSVpFAwkAAAICAUwFByRtYXRjaDAFBUxTSVpFAwkAAAICAlhMBQckbWF0Y2gwBQZYTFNJWkUDCQAAAgIDWFhMBQckbWF0Y2gwBQdYWExTSVpFCQACAQIRVW5rbm93biBsYW5kIHNpemUBB2lzRGlnaXQBAXMJAQlpc0RlZmluZWQBCQC2CQEFAXMBCmtleUJsb2NrZWQAAhBjb250cmFjdHNCbG9ja2VkARFrZXlMYXN0VHhJZEJ5VXNlcgEEYWRkcgkArAICAg9sYXN0VHhJZEJ5VXNlcl8FBGFkZHIBCmZpeGVkUG9pbnQCA3ZhbAhkZWNpbWFscwQGdGVuUG93CQBsBgAKAAAFCGRlY2ltYWxzAAAAAAUERE9XTgQHbG93UGFydAkApAMBCQBqAgUDdmFsBQZ0ZW5Qb3cEBnplcm9lcwkAsAICCQCkAwEFBnRlblBvdwkAZAIAAQkAsQIBBQdsb3dQYXJ0CQCsAgIJAKwCAgkArAICCQCkAwEJAGkCBQN2YWwFBnRlblBvdwIBLgUGemVyb2VzBQdsb3dQYXJ0AQ9nZXRSYW5kb21OdW1iZXIDCG1heFZhbHVlBHNhbHQHZW50cm9weQMJAGcCAAAFCG1heFZhbHVlCQACAQIWbWF4VmFsdWUgc2hvdWxkIGJlID4gMAQKcmFuZG9tSGFzaAkA9wMBCQDLAQIFBHNhbHQFB2VudHJvcHkJAGoCCQCxCQEFCnJhbmRvbUhhc2gFCG1heFZhbHVlAA1pbmN1YmF0b3JBZGRyBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwCQERQGV4dHJOYXRpdmUoMTA2MikBAiMzUEVrdFZ1eDJSaGNoU042M0RzRG80YjRtejRRcXpLU2VEdgMJAAACAQFUBQckbWF0Y2gwBQR0aGlzCQACAQINVW5rbm93biBjaGFpbgALYnJlZWRlckFkZHIEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDAJARFAZXh0ck5hdGl2ZSgxMDYyKQECIzNQRFZ1VTQ1SDdFaDVkbXROYm5STlJTdEd3VUxBN05ZNkhiAwkAAAIBAVQFByRtYXRjaDAFBHRoaXMJAAIBAg1Vbmtub3duIGNoYWluABFGSVZFTUlOVVRFU01JTExJUwDgpxIADFJFTkFNSU5HQ09TVADAlrECAApNQVhOQU1FTEVOADIAFUluZnJhVXBncmFkZUNvc3RTVXNkdACAreIEAAxFWFBNQVRFUklBTFMEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDAApt2C7asHAwkAAAIBAVQFByRtYXRjaDAAqqeBswkJAAIBAg1Vbmtub3duIGNoYWluAAdFWFBVU0RUBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAIDlmncDCQAAAgEBVAUHJG1hdGNoMACA5Zp3CQACAQINVW5rbm93biBjaGFpbgAOUk9CT19EVUNLX1VTRFQAoI0GAAxTX0NPU1RfQUNSRVMAgPKLqAkABUZJVkVYCQC2AgEABQAHVFdFTlRZWAkAtgIBABQACFRXRU5UWTJYCQC2AgEJAGgCABQAFAAIVFdFTlRZM1gJALYCAQkAaAIJAGgCABQAFAAUAAhUV0VOVFk0WAkAtgIBCQBoAgkAaAIJAGgCABQAFAAUABQACFRXRU5UWTVYCQC2AgEJAGgCCQBoAgkAaAIJAGgCABQAFAAUABQAFAAPUFJFU0FMRU5VTUxBTkRTAPQDARJrZXlOZXh0RnJlZUxhbmROdW0AAgtuZXh0TGFuZE51bQEaa2V5TGFuZEN1c3RvbU5hbWVUb0Fzc2V0SWQBBG5hbWUJAKwCAgIEbGNuXwUEbmFtZQEQa2V5TGFuZFRvQXNzZXRJZAEHbGFuZE51bQkArAICAgNsYV8FB2xhbmROdW0BHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIHYXNzZXRJZAlvd25lckFkZHIJAKwCAgkArAICCQCsAgICBWlsYW9fBQdhc3NldElkAgFfBQlvd25lckFkZHIBEWtleUxhbmROdW1Ub093bmVyAQdsYW5kTnVtCQCsAgICA2xvXwUHbGFuZE51bQEaa2V5RHVja0N1c3RvbU5hbWVUb0Fzc2V0SWQBBG5hbWUJAKwCAgIRZHVja0J5Q3VzdG9tTmFtZV8FBG5hbWUBFmtleUN1c3RvbU5hbWVUb0FkZHJlc3MBBG5hbWUJAKwCAgIUYWNjb3VudEJ5Q3VzdG9tTmFtZV8FBG5hbWUBCWtleU9sZGllcwACCm9sZGllc0xpc3QBD2tleU5leHRSb2JvRHVjawACDG5leHRSb2JvRHVjawALY2xhaW1Nb2RlV2gAAAANY2xhaW1Nb2RlRHVjawABABNjbGFpbU1vZGVXaFRoZW5EdWNrAAIACGZsSGVhbHRoAAAAC2ZsVGltZXN0YW1wAAUAB2ZsQm9udXMABgALZmxQcm9kc1VzZWQABwAIcmxIZWFsdGgAAAALcmxQcm9kc1VzZWQAAQAGcmxUeXBlAAAACHJsTGFzdFR4AAIAC3JsVGltZXN0YW1wAAMBB25mdE5hbWUCB2xhbmROdW0IbGFuZFNpemUJAKwCAgkArAICBQpMQU5EUFJFRklYBQdsYW5kTnVtBQhsYW5kU2l6ZQEIdG9Wb2x1bWUCBmFtb3VudAdwa2dTaXplBARwa2dzAwkAZwIFBmFtb3VudAAACQBpAgkAZQIJAGQCBQZhbW91bnQFB3BrZ1NpemUAAQUHcGtnU2l6ZQkBAS0BCQBpAgkAZQIJAGQCCQEBLQEFBmFtb3VudAUHcGtnU2l6ZQABBQdwa2dTaXplCQBoAgUEcGtncwUFTVVMVDgBE2Rpc3RyaWJ1dGVCeVdlaWdodHMCBXRvdGFsB3dlaWdodHMEA3N1bQkAZAIJAGQCCQBkAgkAZAIJAGQCCQCRAwIFB3dlaWdodHMAAAkAkQMCBQd3ZWlnaHRzAAEJAJEDAgUHd2VpZ2h0cwACCQCRAwIFB3dlaWdodHMAAwkAkQMCBQd3ZWlnaHRzAAQJAJEDAgUHd2VpZ2h0cwAFAwkAZwIAAAUDc3VtCQACAQIQWmVybyB3ZWlnaHRzIHN1bQQFbm9ybTYJAGsDBQV0b3RhbAUFTVVMVDYFA3N1bQoBCm5vcm1hbGl6ZXICA2FjYwRlbGVtCQDNCAIFA2FjYwkAawMFBGVsZW0FBW5vcm02BQVNVUxUNgoAAiRsBQd3ZWlnaHRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpub3JtYWxpemVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGARJnZXROZWVkZWRNYXRlcmlhbHMBBXRvdGFsBAVwcm9wcwkAtQkCCQEFdmFsdWUBCQCiCAEJARFrZXlSZXNQcm9wb3J0aW9ucwACAV8DCQECIT0CCQCQAwEFBXByb3BzBQZOVU1SRVMJAAIBAhZXcm9uZyBwcm9wb3J0aW9ucyBkYXRhBAFyCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAACQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwABCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwACCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwADCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAECQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAFBQNuaWwJARNkaXN0cmlidXRlQnlXZWlnaHRzAgUFdG90YWwFAXIBEXN1YnRyYWN0TWF0ZXJpYWxzAwxzaG91bGRVc2VNYXQDaGFzCXRvdGFsTmVlZAQEbmVlZAkBEmdldE5lZWRlZE1hdGVyaWFscwEFCXRvdGFs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Uk9ESU5TTE9UCQACAQkArAICCQCsAgIJAKwCAgIUQ2FuJ3QgcHV0IG1vcmUgdGhhbiAJAKQDAQUNTUFYUFJPRElOU0xPVAIEIG9mIAkAkQMCBQlwcm9kVHlwZXMFCnByb2R1Y3RJZHgDCQAAAgUFY291bnQAAAkAlAoCBQVwTGlzdAcEBGhlYWQJAMkBAgUFcExpc3QJAGgCAAgFCnByb2R1Y3RJZHgEBGN1cnIJALEJAQkAyQECCQDKAQIFBXBMaXN0CQBoAgAIBQpwcm9kdWN0SWR4AAgEBHRhaWwJAMoBAgUFcExpc3QJAGgCAAgJAGQCBQpwcm9kdWN0SWR4AAEEBnJlY2lwZQkAtQkCCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgFCnByb2R1Y3RJZHgCAV8DAwkBASEBBQppc1Bvc2l0aXZlCQBmAgUFY291bnQFBGN1cnIHCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCVlvdSBoYXZlIAkApAMBBQRjdXJyAgQgb2YgCQCRAwIFCXByb2RUeXBlcwUKcHJvZHVjdElkeAITLCBidXQgdHJpZWQgdG8gdXNlIAkApAMBBQVjb3VudAQJaXNCaWdJdGVtAwMJAQEhAQUKaXNQb3NpdGl2ZQkBFWNoZWNrU3RhdFJlcXVpcmVtZW50cwIFCWR1Y2tTdGF0cwkAtQkCCQCRAwIFBnJlY2lwZQUQcklkeFJlcXVpcmVtZW50cwIBLAcEBmNvbXBhdAkAkQMCBQZyZWNpcGUFCXJJZHhTbG90cwMJAAACBQZjb21wYXQCAAkAAgECF0l0ZW0gY2Fubm90IGJlIGVxdWlwcGVkBAFjCQENcGFyc2VJbnRWYWx1ZQEFBmNvbXBhdAQEY1NlZwkAaQIFAWMAZAMJAQIhPQIFB3NlZ21lbnQFBGNTZWcJAAIBAhRTZWdtZW50IGluY29tcGF0aWJsZQQIY01haW5BdXgJAGkCCQBqAgUBYwBkAAoDCQECIT0CBQdtYWluQXV4BQhjTWFpbkF1eAkAAgECEVNsb3QgaW5jb21wYXRpYmxlBAljTnVtU2xvdHMJAGoCBQFjAAoDAwkBAiE9AgUEc2xvdAAACQBmAgUJY051bVNsb3RzAAEHCQACAQIeQmlnIGl0ZW1zIHNob3VsZCBvY2N1cHkgc2xvdCAwCQBmAgUJY051bVNsb3RzAAEHCQCUCgIJAMsBAgkAywECBQRoZWFkCQCaAwEJAGQCBQRjdXJyAwUKaXNQb3NpdGl2ZQUFY291bnQJAQEtAQUFY291bnQFBHRhaWwFCWlzQmlnSXRlbQELc2xvdHNHcm91cEIGAWcEYnBJbgppc1Bvc2l0aXZlB3NlZ21lbnQHbWFpbkF1eAVzdGF0cwMJAQIhPQIFAWcCAAQFc2xvdHMJALUJAgUBZwIBLAMJAGYCCQCQAwEFBXNsb3RzBQhNQVhTTE9UUwkAAgECEldyb25nIHNsb3RzIGZvcm1hdAQCczAJAJEDAgUFc2xvdHMAAAQCczEDCQBmAgkAkAMBBQVzbG90cwABCQCRAwIFBXNsb3RzAAECAAMDCQAAAgUCczACAAkAAAIFAnMxAgAHBQRicEluBAV0bXBTMAMJAQIhPQIFAnMwAgAJAQhhZGRQcm9kQgcFAnMwBQRicEluBQppc1Bvc2l0aXZlBQdzZWdtZW50BQdtYWluQXV4AAAFBXN0YXRzCQCUCgIFBGJwSW4HAwkBAiE9AgUCczECAAMIBQV0bXBTMAJfMgkAAgECHkJpZyBpdGVtIGFscmVhZHkgb2NjdXBpZXMgc2xvdAgJAQhhZGRQcm9kQgcFAnMxCAUFdG1wUzACXzEFCmlzUG9zaXRpdmUFB3NlZ21lbnQFB21haW5BdXgAAQUFc3RhdHMCXzEIBQV0bXBTMAJfMQUEYnBJbgEGZHJlc3NCBAdzZWdMaXN0BnBCeXRlcwppc1Bvc2l0aXZlBXN0YXRzCgEHc2VnbWVudAIDYWNjA3NlZwQBaggFA2FjYwJfMQQHbWFpbkF1eAkAtQkCBQNzZWcCATsDCQECIT0CCQCQAwEFB21haW5BdXgFCk5VTU1BSU5BVVgJAAIBAhRXcm9uZyBzZWdtZW50IGZvcm1hdAQBbQkAkQMCBQdtYWluQXV4AAAEAWEJAJEDAgUHbWFpbkF1eAABAwMJAAACBQFtAgAJAAACBQFhAgAHCQCUCgIJAGQCBQFqAAEIBQNhY2MCXzIEBHRtcE0JAQtzbG90c0dyb3VwQgYFAW0IBQNhY2MCXzIFCmlzUG9zaXRpdmUFAWoAAAUFc3RhdHMJAJQKAgkAZAIFAWoAAQkBC3Nsb3RzR3JvdXBCBgUBYQUEdG1wTQUKaXNQb3NpdGl2ZQUBagABBQVzdGF0cwgKAAIkbAUHc2VnTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgAABQZwQnl0ZXMKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB3NlZ21lbnQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYCXzIBF2NhbldlYXJDdXJyZW50RXF1aXBtZW50AQtkdWNrQXNzZXRJZAQFZXFLZXkJARBrZXlEdWNrRXF1aXBtZW50AQULZHVja0Fzc2V0SWQEBmN1cnJFcQkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEFBWVxS2V5AhcsOyxfLDssXyw7LF8sOyxfLDssXyw7LAIBXwQMRU1QVFlfUFJPRDUwAZADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQJdGVtcFByb2RCCQEGZHJlc3NCBAUGY3VyckVxBQxFTVBUWV9QUk9ENTAGBQNuaWwECHNlZ0JwQXV4CQCRAwIJALUJAgkAkQMCBQZjdXJyRXEFC3NlZ0JhY2twYWNrAgE7AAEECmJ1ZmZFZmZlY3QDCQAAAgUIc2VnQnBBdXgCAAAABARhdXgwCQCRAwIJALUJAgUIc2VnQnBBdXgCASwAAAMJAAACBQRhdXgwAgAAAAQGaWR4Q250CQC1CQIFBGF1eDACAToEA2lkeAkAkQMCBQZpZHhDbnQAAAQDY250CQCRAwIFBmlkeENudAABAwMDAwMJAAACBQNpZHgCAjA2BgkAAAIFA2lkeAICMDcGCQAAAgUDaWR4AgIwOAkBAiE9AgUDY250AgAHCQBmAgkBDXBhcnNlSW50VmFsdWUBBQNjbnQAAAcJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQC1CQIJAJEDAgUQcHJvZHVjdGlvbk1hdHJpeAkBDXBhcnNlSW50VmFsdWUBBQNpZHgCAV8FCnJJZHhFZmZlY3QAAAQFc3RhdHMJAQxnZXREdWNrU3RhdHMEBQR0aGlzBQtkdWNrQXNzZXRJZAUKYnVmZkVmZmVjdAYECG5ld1Byb2RCCQEGZHJlc3NCBAUGY3VyckVxBQl0ZW1wUHJvZEIHBQVzdGF0cwkAAAIFCG5ld1Byb2RCBQhuZXdQcm9kQgEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQIcHJvcExpc3QNdGVycmFpbkNvdW50cw1sYW5kU2l6ZUluZGV4BHNpZ24DCQECIT0CCQCQAwEFCHByb3BMaXN0BQZOVU1SRVMJAAIBAhZXcm9uZyBwcm9wb3J0aW9ucyBkYXRhCgEHdXBkYXRlcgIDYWNjAWkEBnJlc3VsdAkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhwcm9wTGlzdAUBaQkAaAIJAGgCBQRzaWduCQCRAwIFDXRlcnJhaW5Db3VudHMFAWkFDWxhbmRTaXplSW5kZXgDCQBmAgAABQZyZXN1bHQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICFlBhbmljISBQaWVjZXMgb2YgdHlwZT0JAKQDAQUBaQIHLCBzaWduPQkApAMBBQRzaWduAhMsIHRlcnJhaW5Db3VudHNbaV09CQCkAwEJAJEDAgUNdGVycmFpbkNvdW50cwUBaQIQLCBsYW5kU2l6ZUluZGV4PQkApAMBBQ1sYW5kU2l6ZUluZGV4CQDNCAIFA2FjYwkApAMBBQZyZXN1bHQKAAIkbAUFSVRFUjYKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB3VwZGF0ZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYBEXVwZGF0ZVByb3BvcnRpb25zAw10ZXJyYWluQ291bnRzDWxhbmRTaXplSW5kZXgEc2lnbgQIcHJvcExpc3QJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBCQERa2V5UmVzUHJvcG9ydGlvbnMAAgswXzBfMF8wXzBfMAIBXwkAuQkCCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQFCHByb3BMaXN0BQ10ZXJyYWluQ291bnRzBQ1sYW5kU2l6ZUluZGV4BQRzaWduAgFfAQ1jb3VudFRlcnJhaW5zAQh0ZXJyYWlucwkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFBAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBQgABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUMAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFEAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBRQABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUYAAQUDbmlsAQZhZGRSZXMFCmN1cnJlbnRSZXMNdGVycmFpbkNvdW50cwlkZWx0YVRpbWUNbGFuZFNpemVJbmRleBdkYWlseUJ5UGllY2VXaXRoQm9udXNlcwoBBWFkZGVyAgNhY2MBaQQJcmVzT2ZUeXBlCQBoAgkAaAIJAGsDBQlkZWx0YVRpbWUFF2RhaWx5QnlQaWVjZVdpdGhCb251c2VzBQlEQVlNSUxMSVMJAJEDAgUNdGVycmFpbkNvdW50cwUBaQUNbGFuZFNpemVJbmRleAkAzQgCBQNhY2MJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpjdXJyZW50UmVzBQFpBQlyZXNPZlR5cGUEAXIKAAIkbAUFSVRFUjYKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBWFkZGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGCQC5CQIFAXICAV8BCXZpcnRDbGFpbQQNdGVycmFpbkNvdW50cwlkZWx0YVRpbWUNbGFuZFNpemVJbmRleBdkYWlseUJ5UGllY2VXaXRoQm9udXNlcwoBBWFkZGVyAgNhY2MBaQQJcmVzT2ZUeXBlCQBoAgkAaAIJAGsDBQlkZWx0YVRpbWUFF2RhaWx5QnlQaWVjZVdpdGhCb251c2VzBQlEQVlNSUxMSVMJAJEDAgUNdGVycmFpbkNvdW50cwUBaQUNbGFuZFNpemVJbmRleAkAlAoCCQDNCAIIBQNhY2MCXzEFCXJlc09mVHlwZQkAZAIIBQNhY2MCXzIFCXJlc09mVHlwZQoAAiRsBQVJVEVSNgoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBWFkZGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAQ1kaXN0cmlidXRlUmVzBAxjdXJyZW50V2hSZXMOY3VycmVudFBhY2tSZXMKcmVzVG9DbGFpbQt3aFNwYWNlTGVmdAQOcmVzTGlzdFRvQ2xhaW0IBQpyZXNUb0NsYWltAl8xBAxyZXNBbVRvQ2xhaW0IBQpyZXNUb0NsYWltAl8yAwkAAAIFDHJlc0FtVG9DbGFpbQAACQCUCgIJALkJAgUMY3VycmVudFdoUmVzAgFfCQC5CQIFDmN1cnJlbnRQYWNrUmVzAgFfAwkAZwIFC3doU3BhY2VMZWZ0BQxyZXNBbVRvQ2xhaW0KAQhhZGRMaXN0cwIDYWNjAWkJAM0IAgUDYWNjCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUMY3VycmVudFdoUmVzBQFpCQCRAwIFDnJlc0xpc3RUb0NsYWltBQFpBAFyCgACJGwFBUlURVI2CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhhZGRMaXN0cwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgkAlAoCCQC5CQIFAXICAV8JALkJAgUOY3VycmVudFBhY2tSZXMCAV8KAQxhZGRQYXJ0TGlzdHMCA2FjYwFpBAZ3aFBhcnQJAGsDCQCRAwIFDnJlc0xpc3RUb0NsYWltBQFpBQt3aFNwYWNlTGVmdAUMcmVzQW1Ub0NsYWltCQCUCgIJAM0IAggFA2FjYwJfMQkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDGN1cnJlbnRXaFJlcwUBaQUGd2hQYXJ0CQDNCAIIBQNhY2MCXzIJAKQDAQkAZQIJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOY3VycmVudFBhY2tSZXMFAWkJAJEDAgUOcmVzTGlzdFRvQ2xhaW0FAWkFBndoUGFydAQBcgoAAiRsBQVJVEVSNgoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDGFkZFBhcnRMaXN0cwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgkAlAoCCQC5CQIIBQFyAl8xAgFfCQC5CQIIBQFyAl8yAgFfAQNhYnMBAXgDCQDAAgIFAXgJALYCAQAABQF4CQC+AgEFAXgABGZyZXEJAMwIAgkAzAgCAAYJAMwIAgAJCQDMCAIADgkAzAgCAA8JAMwIAgAQBQNuaWwJAMwIAgkAzAgCAAUJAMwIAgAICQDMCAIADQkAzAgCAA4JAMwIAgAPBQNuaWwJAMwIAgkAzAgCAAEJAMwIAgAECQDMCAIACQkAzAgCAAoJAMwIAgAPBQNuaWwJAMwIAgkAzAgCAAEJAMwIAgAGCQDMCAIABwkAzAgCAA8JAMwIAgATBQNuaWwJAMwIAgkAzAgCAAQJAMwIAgAHCQDMCAIACAkAzAgCAA0JAMwIAgASBQNuaWwFA25pbAEHZ2VuQ2hhcgIBbgVmcmVxcwQDcmVtCQCgAwEJALsCAgUBbgUHVFdFTlRZWAQGbGV0dGVyAwkAZgIJAJEDAgUFZnJlcXMAAAUDcmVtAgFBAwkAZgIJAJEDAgUFZnJlcXMAAQUDcmVtAgFCAwkAZgIJAJEDAgUFZnJlcXMAAgUDcmVtAgFDAwkAZgIJAJEDAgUFZnJlcXMAAwUDcmVtAgFEAwkAZgIJAJEDAgUFZnJlcXMABAUDcmVtAgFFAgFGBQZsZXR0ZXIBC2dlblRlcnJhaW5zAgRzZWVkDGNvbnRpbmVudElkeAQBZgkAkQMCBQRmcmVxBQxjb250aW5lbnRJZHgKARB0ZXJyYWluR2VuZXJhdG9yAgNhY2MEZWxlbQkAlAoCCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAggFA2FjYwJfMQkBB2dlbkNoYXICCAUDYWNjAl8yBQFmCQEHZ2VuQ2hhcgIJALoCAggFA2FjYwJfMgUHVFdFTlRZWAUBZgkBB2dlbkNoYXICCQC6AgIIBQNhY2MCXzIFCFRXRU5UWTJYBQFmCQEHZ2VuQ2hhcgIJALoCAggFA2FjYwJfMgUIVFdFTlRZM1gFAWYJAQdnZW5DaGFyAgkAugICCAUDYWNjAl8yBQhUV0VOVFk0WAUBZgkAugICCAUDYWNjAl8yBQhUV0VOVFk1WAQBdAoAAiRsCQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUFA25pbAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgIACQC6AgIFBHNlZWQFBUZJVkVYCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARB0ZXJyYWluR2VuZXJhdG9yAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQgFAXQCXzEABlBFUk0yNQkAzAgCAAcJAMwIAgACCQDMCAIADwkAzAgCABMJAMwIAgAICQDMCAIAGAkAzAgCAAEJAMwIAgAVCQDMCAIAEAkAzAgCAAUJAMwIAgAACQDMCAIAFgkAzAgCABQJAMwIAgAXCQDMCAIACwkAzAgCAAQJAMwIAgASCQDMCAIADAkAzAgCAAYJAMwIAgAKCQDMCAIAAwkAzAgCABEJAMwIAgANCQDMCAIACQkAzAgCAA4FA25pbAAGVENIQVJTCQDMCAICAUEJAMwIAgIBQgkAzAgCAgFDCQDMCAICAUQJAMwIAgIBRQkAzAgCAgFGBQNuaWwBE2dlblRlcnJhaW5zRm9yTWVyZ2UCC3N1bVRlcnJhaW5zDWxhbmRTaXplSW5kZXgKAQVzdGVwMQIDYWNjAXMEAWoIBQNhY2MCXzIEAmVsCQENcGFyc2VJbnRWYWx1ZQEFAXMEAXgDCQAAAgUCZWwAAAAAAwkAZwIFAmVsCQBoAgAEBQ1sYW5kU2l6ZUluZGV4CQBpAgUCZWwFDWxhbmRTaXplSW5kZXgDCQBmAgUCZWwJAGgCAAMFDWxhbmRTaXplSW5kZXgAAwkAZAIJAGkCCQBlAgUCZWwAAQUNbGFuZFNpemVJbmRleAABCQCVCgMJAM0IAggFA2FjYwJfMQUBeAkAZAIIBQNhY2MCXzIAAQkAZAIIBQNhY2MCXzMFAXgEAXQKAAIkbAULc3VtVGVycmFpbnMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCVCgMFA25pbAAAAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBXN0ZXAxAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGBANhcnIIBQF0Al8xBAZtYXhJZHgJAQV2YWx1ZQEJAM8IAgUDYXJyCQCWAwEFA2FycgQFZGVsdGEJAGUCCAUBdAJfMwAZCgEGc3ViYmVyAgNhY2MDaWR4BAN2YWwDCQAAAgUDaWR4BQZtYXhJZHgJAGUCCQCRAwIFA2FycgUDaWR4BQVkZWx0YQkAkQMCBQNhcnIFA2lkeAQGemVyb2VzAwkAAAIFA3ZhbAAABQNuaWwJALUJAgkAsAICCQCkAwEJAGwGAAoAAAUDdmFsAAAAAAUERE9XTgABAgAEAWMJAJEDAgUGVENIQVJTBQNpZHgKAQdsaXN0R2VuAgJhYwdpZ25vcmVkCQDNCAIFAmFjBQFjBAF6CgACJGwFBnplcm9lcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMV8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHbGlzdEdlbgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMjUJAQUkZjFfMgIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQkAzggCBQNhY2MFAXoEAXIKAAIkbAUFSVRFUjYKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBnN1YmJlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMV8yAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgoBBnBlcm11dAIDYWNjAWoJAKwCAgUDYWNjCQCRAwIFAXIFAWoKAAIkbAUGUEVSTTI1CgACJHMJAJADAQUCJGwKAAUkYWNjMAIACgEFJGYyXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQZwZXJtdXQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjJfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDI1CQEFJGYyXzICCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECCQEFJGYyXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkBC2dldEJhY2twYWNrAQVicEtleQQBcAkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEFBWJwS2V5AhowOjBfMF8wXzBfMF8wOjBfMF8wXzBfMF8wOgIBOgkAzAgCCQCkAwEJAQt2YWx1ZU9yRWxzZQIJALYJAQkAkQMCBQFwBQpicElkeExldmVsAAAJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQFwBQhicElkeFJlcwIBXwUGTlVNUkVTCQCRAwIFAXAFCGJwSWR4UmVzAgswXzBfMF8wXzBfMAkAzAgCAwkAAAIJAJADAQkAtQkCCQCRAwIFAXAFCGJwSWR4TWF0AgFfBQZOVU1SRVMJAJEDAgUBcAUIYnBJZHhNYXQCCzBfMF8wXzBfMF8wCQDMCAIJAJEDAgUBcAUJYnBJZHhQcm9kBQNuaWwBF2dldFdhcmVob3VzZVRvdGFsVm9sdW1lAQl2b2xQcmVmaXgEBXBhcnRzCQC1CQIFCXZvbFByZWZpeAIBXwkAaAIJAGgCBQxXSE1VTFRJUExJRVIJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAQABCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAAEXZ2V0V2FyZWhvdXNlT2NjdXBpZWRWb2wBCWN1cnJlbnRXaAQFZ29vZHMJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QKAQlzdW1SZXNNYXQCA2FjYwRpdGVtCQBkAgUDYWNjCQENcGFyc2VJbnRWYWx1ZQEFBGl0ZW0KAQdzdW1Qcm9kAgNhY2MEaXRlbQQDaWR4CAUDYWNjAl8xBARwa2dzCQBpAgkAZQIJAGQCCQENcGFyc2VJbnRWYWx1ZQEFBGl0ZW0FDlBST0RVQ1RQS0dTSVpFAAEFDlBST0RVQ1RQS0dTSVpFCQCUCgIJAGQCBQNpZHgAAQkAZAIIBQNhY2MCXzIJAGgCBQRwa2dzBQVNVUxUOAQId2hSZXNWb2wKAAIkbAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8KAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCXN1bVJlc01hdAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIT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CQCkAwEJAGUCCQBlAgUHd2hUb3RhbAUId2hMb2NrZWQFA29jYwkAzAgCCQCkAwEFB3doVG90YWwFA25pbAIBXwkAzAgCCQCRAwIFAndoBQt3aElkeExldmVscwkAzAgCAwkAAAIJAJADAQkAtQkCCQCRAwIFAndoBQh3aElkeFJlcwIBXwUGTlVNUkVTCQCRAwIFAndoBQh3aElkeFJlcwILMF8wXzBfMF8wXzAJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQJ3aAUId2hJZHhNYXQCAV8FBk5VTVJFUwkAkQMCBQJ3aAUId2hJZHhNYXQCCzBfMF8wXzBfMF8wCQDMCAIJAJEDAgUCd2gFCXdoSWR4UHJvZAkAzAgCBQZ3aExvZnQFA25pbAEVZ2V0V2FyZWhvdXNlU3BhY2VMZWZ0AQljdXJyZW50V2gEC29jY3VwaWVkVm9sCQEXZ2V0V2FyZWhvdXNlT2NjdXBpZWRWb2wBBQljdXJyZW50V2gED2N1cnJXaExvY2tlZFZvbAkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4TE9GVAIBXwUJdm9sTG9ja2VkCQBlAgkAZQIJARdnZXRXYXJlaG91c2VUb3RhbFZvbHVtZQEJAJEDAgUJY3VycmVudFdoBQt3aElkeExldmVscwULb2NjdXBpZWRWb2wFD2N1cnJXaExvY2tlZFZvbAEJbW92ZVN0dWZmAwpjYXJnb1BhcnRzCWN1cnJlbnRXaAtjdXJyZW50UGFjawMJAQIhPQIJAJADAQUKY2FyZ29QYXJ0cwADCQACAQI0Y2FyZ29MaXN0U3RyIHNob3VsZCBjb250YWluIGV4YWN0bHkgMiAnOicgc2VwYXJhdG9ycwQIcmVzUGFydHMJALUJAgkAkQMCBQpjYXJnb1BhcnRzAAACAV8ECG1hdFBhcnRzCQC1CQIJAJEDAgUKY2FyZ29QYXJ0cwABAgFfBAlwcm9kUGFydHMDCQAAAgkAkQMCBQpjYXJnb1BhcnRzAAICAAUDbmlsCQC8CQIJAJEDAgUKY2FyZ29QYXJ0cwACAgFfAwkBAiE9AgkAkAMBBQhyZXNQYXJ0cwUGTlVNUkVTCQACAQIgQWxsIDYgcmVzb3VyY2VzIHNob3VsZCBiZSBwYXNzZWQDCQECIT0CCQCQAwEFCG1hdFBhcnRzBQZOVU1SRVMJAAIBAiBBbGwgNiBtYXRlcmlhbHMgc2hvdWxkIGJlIHBhc3NlZAQLd2hTcGFjZUxlZnQJARVnZXRXYXJlaG91c2VTcGFjZUxlZnQBBQljdXJyZW50V2gECWN1cnJXaFJlcwkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8ECWN1cnJXaE1hdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhNYXQCAV8ECmN1cnJXaFByb2QDCQAAAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAIABQNuaWwJALwJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAIBXwQOY3VycmVudFBhY2tSZXMJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMCAV8EDmN1cnJlbnRQYWNrTWF0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBA9jdXJyZW50UGFja1Byb2QDCQAAAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgAFA25pbAkAvAkCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAV8KAQNtdlICA2FjYwRpdGVtBAFpCAUDYWNjAl8xBAJhbQkBDXBhcnNlSW50VmFsdWUBBQRpdGVtBAN3aHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQljdXJyV2hSZXMFAWkEA2JwcgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmN1cnJlbnRQYWNrUmVzBQFpAwkAAAIFAmFtAAAJAJYKBAkAZAIFAWkAAQkAzQgCCAUDYWNjAl8yCQCRAwIFCWN1cnJXaFJlcwUBaQkAzQgCCAUDYWNjAl8zCQCRAwIFDmN1cnJlbnRQYWNrUmVzBQFpCAUDYWNjAl80AwkAZgIFAmFtAAADCQBmAgUCYW0FA2JwcgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byB0YWtlIAUEaXRlbQIZIGZyb20gYmFja3BhY2ssIGJ1dCBvbmx5IAkApAMBBQNicHICCiBhdmFpbGFibGUJAJYKBAkAZAIFAWkAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGQC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ZUxhbmROdW0ACQBkAgUPUFJFU0FMRU5VTUxBTkRTAAEEB2xhbmROdW0JAKQDAQUHZnJlZU51bQQMY29udGluZW50SWR4CQCgAwEJALsCAgUGYmlnTnVtBQVGSVZFWAQIdGVycmFpbnMJAQtnZW5UZXJyYWlucwIFBmJpZ051bQUMY29udGluZW50SWR4BAljb250aW5lbnQJAJEDAgUKY29udGluZW50cwUMY29udGluZW50SWR4BAVpc3N1ZQkAwggFCQEHbmZ0TmFtZQIFB2xhbmROdW0CAVMJALkJAgkAzAgCBQdsYW5kTnVtCQDMCAICAVMJAMwIAgUIdGVycmFpbnMJAMwIAgUJY29udGluZW50BQNuaWwCAV8AAQAABwQHYXNzZXRJZAkAuAgBBQVpc3N1ZQQCaWQJANgEAQUHYXNzZXRJZAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESa2V5TmV4dEZyZWVMYW5kTnVtAAkAZAIFB2ZyZWVOdW0AAQkAzAgCBQVpc3N1ZQkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5TGFuZFRvQXNzZXRJZAEFB2xhbmROdW0FAmlkCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQJpZAUIdXNlckFkZHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUxhbmROdW1Ub093bmVyAQUHbGFuZE51bQUIdXNlckFkZHIJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQUCaWQAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIFAmlkBQh1c2VyQWRkcgAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBmNhbGxlcgABBQdhc3NldElkBQNuaWwJAJQKAgUCaWQFCWNvbnRpbmVudAEMZmxpZ2h0Q29tbW9uAwh1c2VyQWRkcgdtZXNzYWdlA3NpZwMJAQEhAQkAxBMDBQdtZXNzYWdlBQNzaWcFA3B1YgkAAgECGHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaAQFcGFydHMJALwJAgkAsAkBBQdtZXNzYWdlAgE7BAlmbGlnaHRMb2cJALwJAgkAkQMCBQVwYXJ0cwAAAgF8BAJocAkAtQkCCQCRAwIFCWZsaWdodExvZwUIZmxIZWFsdGgCAV8EBWN1ckhQCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCaHAAAAQFbmV3SFAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJocAABBAtuZXdMb2NUeFZlcgkAtQkCCQCRAwIFBXBhcnRzAAECAToEC25ld0xvY2F0aW9uCQCRAwIFC25ld0xvY1R4VmVyAAAEBHRpbWUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlmbGlnaHRMb2cFC2ZsVGltZXN0YW1wAwMJAGYCBQR0aW1lCQBkAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFEUZJVkVNSU5VVEVTTUlMTElTBgkAZgIJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAURRklWRU1JTlVURVNNSUxMSVMFBHRpbWUJAAIBCQCsAgIJAKwCAgkArAICAhxzaWduYXR1cmUgb3V0ZGF0ZWQ6IGxvZ1RpbWU9CQCkAwEFBHRpbWUCCSwgYmNUaW1lPQkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQJdHhGcm9tTXNnCQCRAwIFC25ld0xvY1R4VmVyAAEEBmxhc3RUeAkBC3ZhbHVlT3JFbHNlAgkAoggBCQERa2V5TGFzdFR4SWRCeVVzZXIBBQh1c2VyQWRkcgIAAwkBAiE9AgUGbGFzdFR4BQl0eEZyb21Nc2cJAAIBCQCsAgIJAKwCAgkArAICAh5UeCBpZHMgZG9uJ3QgbWF0Y2ghIEluIHN0YXRlOiAFBmxhc3RUeAIKLCBpbiBtc2c6IAUJdHhGcm9tTXNnBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFCHVzZXJBZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEBW1heEhQCQEJbWF4SGVhbHRoAQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEMa2V5RHVja0xldmVsAQULZHVja0Fzc2V0SWQAAAQMb2xkRnJvbVN0YXRlCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aAUFbWF4SFADCQECIT0CBQxvbGRGcm9tU3RhdGUFBWN1ckhQCQACAQkArAICCQCsAgIJAKwCAgIKb2xkSGVhbHRoPQkApAMBBQxvbGRGcm9tU3RhdGUCLyBmcm9tIHN0YXRlIGRvZXMgbm90IG1hdGNoIG9uZSBmcm9tIGZsaWdodCBsb2c9CQCkAwEFBWN1ckhQAwkAZwIAAAUFY3VySFAJAAIBAh5Zb3UgY2FuJ3QgZmx5IHdpdGggemVybyBoZWFsdGgDCQEBIQEJARdjYW5XZWFyQ3VycmVudEVxdWlwbWVudAEFC2R1Y2tBc3NldElkCQACAQIWRXF1aXBtZW50IGluY29tcGF0aWJsZQQFYm9udXMDCQBmAgkAkAMBBQlmbGlnaHRMb2cFB2ZsQm9udXMJAJEDAgUJZmxpZ2h0TG9nBQdmbEJvbnVzAgAECHByb2RVc2VkAwkAZgIJAJADAQUJZmxpZ2h0TG9nBQtmbFByb2RzVXNlZAkAkQMCBQlmbGlnaHRMb2cFC2ZsUHJvZHNVc2VkAgAECnNlbnRBbW91bnQDAwkAZgIFBW5ld0hQAAAJAAACBQVib251cwIBJAcJAQVhc0ludAEJAPwHBAUMcmVzdENvbnRyYWN0Ag1zZW5kVXNkdFByaXplCQDMCAIFCHVzZXJBZGRyBQNuaWwFA25pbAAACQCXCgUFBW5ld0hQBQtkdWNrQXNzZXRJZAUKc2VudEFtb3VudAULbmV3TG9jYXRpb24FCHByb2RVc2VkAQxhcHBseUJvbnVzZXMCC2xhbmRBc3NldElkBnBpZWNlcwQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAECWFydFBpZWNlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAAABARhZGQ2CQBpAgUKaW5mcmFMZXZlbAAGBARhZGQ3CQBpAgUKaW5mcmFMZXZlbAAHCQBkAgkAZAIFD0RBSUxZUkVTQllQSUVDRQkAawMFD0RBSUxZUkVTQllQSUVDRQkAZAIJAGQCBQppbmZyYUxldmVsBQRhZGQ2CQBoAgACBQRhZGQ3AAUJAGsDBQ9EQUlMWVJFU0JZUElFQ0UFCWFydFBpZWNlcwkAaAIFBnBpZWNlcwAFARRjaGVja0NsYWltQ29uZGl0aW9ucwMEYWRkcgljbGFpbU1vZGUNbGFuZEFzc2V0SWRJbgQNJHQwMzM2NzgzNDIxNwMJAAACBQljbGFpbU1vZGUFC2NsYWltTW9kZVdoCQCUCgIFDWxhbmRBc3NldElkSW4JAQt2YWx1ZU9yRWxzZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIABAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQEC2N1ckxvY2F0aW9uCQELdmFsdWVPckVsc2UCCQCiCAEJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OBANsb2MJALUJAgkBBXZhbHVlAQULY3VyTG9jYXRpb24CAV8DCQECIT0CCQCRAwIFA2xvYwUKbG9jSWR4VHlwZQIBTAkAAgEJAKwCAgkArAICAhZEdWNrIGxvY2F0aW9uIHR5cGUgaXMgCQCRAwIFA2xvYwUKbG9jSWR4VHlwZQIRLCBidXQgc2hvdWxkIGJlIEwJAJQKAgkAkQMCBQNsb2MFCGxvY0lkeElkBQtkdWNrQXNzZXRJZAQLbGFuZEFzc2V0SWQIBQ0kdDAzMzY3ODM0MjE3Al8xBAZkdWNrSWQIBQ0kdDAzMzY3ODM0MjE3Al8yBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBAlzYXZlZFRpbWUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQd0aW1lS2V5CQCsAgIJAKwCAgIFTGFuZCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkxBTkRQUkVGSVgCDSBpcyBub3QgeW91cnMEAWQJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfCQCWCgQFBmR1Y2tJZAULbGFuZEFzc2V0SWQFAWQFCXNhdmVkVGltZQEQY2xhaW1SZXNJbnRlcm5hbAQEYWRkcgZhbW91bnQJY2xhaW1Nb2RlDWxhbmRBc3NldElkSW4DCQBmAgAABQZhbW91bnQJAAIBAg9OZWdhdGl2ZSBhbW91bnQEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFCWNsYWltTW9kZQUNbGFuZEFzc2V0SWRJbgQIbGFuZFNpemUJAJEDAggFAWMCXzMFC3JlY0xhbmRTaXplBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEJAJEDAggFAWMCXzMFC3JlY1RlcnJhaW5zBAlkZWx0YVRpbWUJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAgFAWMCXzQDCQBmAgAABQlkZWx0YVRpbWUJAAIBCQCsAgIJAKwCAgkArAICAiZTYXZlZCB0aW1lc3RhbXAgaXMgaW4gZnV0dXJlLCBzYXZlZCA9IAkApAMBCAUBYwJfNAIMLCBjdXJyZW50ID0gCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBBQhsYW5kU2l6ZQQWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkBDGFwcGx5Qm9udXNlcwIIBQFjAl8yBQZwaWVjZXMECGF2YWlsUmVzCQBrAwUJZGVsdGFUaW1lCQBoAgUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQUGcGllY2VzBQlEQVlNSUxMSVMDCQBmAgUGYW1vdW50BQhhdmFpbFJlcwkAAgEJAKwCAgkArAICCQCsAgICIk5vdCBlbm91Z2ggcmVzb3VyY2VzLCBhdmFpbGFibGUgPSAJAKQDAQUIYXZhaWxSZXMCDiwgcmVxdWVzdGVkID0gCQCkAwEFBmFtb3VudAQMbmV3RGVsdGFUaW1lCQBrAwkAZQIFCGF2YWlsUmVzBQZhbW91bnQFCURBWU1JTExJUwkAaAIFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UFBnBpZWNlcwQMbmV3VGltZXN0YW1wCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFDG5ld0RlbHRhVGltZQQJbGFuZEluZGV4CQBpAgUGcGllY2VzBQVTU0laRQQKcmVzVG9DbGFpbQkBCXZpcnRDbGFpbQQFDXRlcnJhaW5Db3VudHMJAGUCBQlkZWx0YVRpbWUFDG5ld0RlbHRhVGltZQUJbGFuZEluZGV4BRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBAV3aEtleQkBEmtleVdhcmVob3VzZUJ5TGFuZAEIBQFjAl8yBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQgFAWMCXzIAAAQJY3VycmVudFdoCQEMZ2V0V2FyZWhvdXNlAwUFd2hLZXkFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAQEbG9mdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhMT0ZUAgFfBAt3aFNwYWNlTGVmdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUDAwkAAAIFCWNsYWltTW9kZQULY2xhaW1Nb2RlV2gJAGYCBQZhbW91bnQFC3doU3BhY2VMZWZ0BwkAAgEJAKwCAgkArAICAgVPbmx5IAkApAMBBQt3aFNwYWNlTGVmdAIYIHNwYWNlIGxlZnQgaW4gd2FyZWhvdXNlBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQgFAWMCXzEEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQOY3VycmVudFBhY2tSZXMJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMCAV8EDGN1cnJlbnRXaFJlcwkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8EDSR0MDM2NTkxMzc0NjIDCQAAAgUJY2xhaW1Nb2RlBQtjbGFpbU1vZGVXaAkAlgoECQEGYWRkUmVzBQUMY3VycmVudFdoUmVzBQ10ZXJyYWluQ291bnRzCQBlAgUJZGVsdGFUaW1lBQxuZXdEZWx0YVRpbWUFCWxhbmRJbmRleAUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQIBQpyZXNUb0NsYWltAl8yCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUIBQpyZXNUb0NsYWltAl8yAwkAAAIFCWNsYWltTW9kZQUNY2xhaW1Nb2RlRHVjawkAlgoECQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMJAQZhZGRSZXMFBQ5jdXJyZW50UGFja1JlcwUNdGVycmFpbkNvdW50cwkAZQIFCWRlbHRhVGltZQUMbmV3RGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUEBWRpc3RyCQENZGlzdHJpYnV0ZVJlcwQFDGN1cnJlbnRXaFJlcwUOY3VycmVudFBhY2tSZXMFCnJlc1RvQ2xhaW0FC3doU3BhY2VMZWZ0BAR3aEFtCQCXAwEJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUJAMwIAggFCnJlc1RvQ2xhaW0CXzIFA25pbAkAlgoECAUFZGlzdHICXzEIBQVkaXN0cgJfMgkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAUEd2hBbQkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlBQR3aEFtBAV3aFJlcwgFDSR0MDM2NTkxMzc0NjICXzEEBWJwUmVzCAUNJHQwMzY1OTEzNzQ2MgJfMgQFbG9mdE8IBQ0kdDAzNjU5MTM3NDYyAl8zBAVsb2Z0RggFDSR0MDM2NTkxMzc0NjICXzQJAJcKBQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBCAUBYwJfMgUMbmV3VGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgIBQFjAl8yBQRhZGRyBQxuZXdUaW1lc3RhbXAFA25pbAUFYnBLZXkJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCBQVicFJlcwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAUFd2hLZXkJAMwIAgkAkQMCBQljdXJyZW50V2gFC3doSWR4TGV2ZWxzCQDMCAIFBXdoUmVzCQDMCAIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAkAzAgCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kCQDMCAIJALkJAgkAzAgCCQCRAwIFBGxvZnQFCXZvbExvY2tlZAkAzAgCCQCkAwEFBWxvZnRPCQDMCAIJAKQDAQUFbG9mdEYJAMwIAgkAkQMCBQRsb2Z0BQh2b2xUb3RhbAUDbmlsAgFfBQNuaWwBCGNsYWltQWxsBARhZGRyC2xhbmRBc3NldElkBnBpZWNlcwljbGFpbU1vZGUEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBBXZhbHVlAQkAnwgBBQd0aW1lS2V5BAhhdmFpbFJlcwkAaAIJAGsDCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFCXNhdmVkVGltZQkBDGFwcGx5Qm9udXNlcwIFC2xhbmRBc3NldElkBQZwaWVjZXMFCURBWU1JTExJUwUGcGllY2VzCQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFCGF2YWlsUmVzBQljbGFpbU1vZGUFC2xhbmRBc3NldElkAQ11cEluZnJhQ29tbW9uBAxzaG91bGRVc2VNYXQGY2FsbGVyDXBheW1lbnRBbW91bnQLbGFuZEFzc2V0SWQEBGFkZHIJAKUIAQUGY2FsbGVyBAFjCQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBQRhZGRyBRNjbGFpbU1vZGVXaFRoZW5EdWNrBQtsYW5kQXNzZXRJZAQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCAUBYwJfMwULcmVjTGFuZFNpemUECGluZnJhS2V5CQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEIBQFjAl8yBAhjdXJMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQhpbmZyYUtleQAAAwMJAQEhAQUYS1NfQUxMT1dfQklHX0lORlJBX01FUkdFCQBnAgUIY3VyTGV2ZWwAAwcJAAIBAiZDdXJyZW50bHkgbWF4IGluZnJhc3RydWN0dXJlIGxldmVsID0gMwQIbWF4SW5mcmEJAGQCCQBpAgkBBHNxcnQEBQZwaWVjZXMAAAAABQRET1dOAAUAAgQIbmV3TGV2ZWwJAGQCBQhjdXJMZXZlbAABAwMFGEtTX0FMTE9XX0JJR19JTkZSQV9NRVJHRQkAZgIFCG5ld0xldmVsBQhtYXhJbmZyYQcJAAIBCQCsAgICJUN1cnJlbnRseSBtYXggaW5mcmFzdHJ1Y3R1cmUgbGV2ZWwgPSAJAKQDAQUIbWF4SW5mcmEEBGNvc3QJAGsDBRVJbmZyYVVwZ3JhZGVDb3N0U1VzZHQJAGgCBQZwaWVjZXMFCG5ld0xldmVsBQVTU0laRQMDCQEBIQEFDHNob3VsZFVzZU1hdAkBAiE9AgUNcGF5bWVudEFtb3VudAUEY29zdAcJAAIBCQCsAgICG1BheW1lbnQgYXR0YWNoZWQgc2hvdWxkIGJlIAkApAMBBQRjb3N0BAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQgFAWMCXzEEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQFbUxpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8EB21hdFVzZWQJAGsDBRFJbmZyYVVwZ3JhZGVDb3N0UwkAaAIFBnBpZWNlcwUIbmV3TGV2ZWwFBVNTSVpFBAZuZXdNYXQJALkJAgkBEXN1YnRyYWN0TWF0ZXJpYWxzAwUMc2hvdWxkVXNlTWF0BQVtTGlzdAUHbWF0VXNlZAIBXwQLY2xhaW1SZXN1bHQJAQhjbGFpbUFsbAQFBGFkZHIIBQFjAl8yBQZwaWVjZXMFE2NsYWltTW9kZVdoVGhlbkR1Y2sEBndoRGF0YQgFC2NsYWltUmVzdWx0Al81BAZvbGRWb2wJARdnZXRXYXJlaG91c2VUb3RhbFZvbHVtZQEJAJEDAgUGd2hEYXRhBQt3aElkeExldmVscwQKbmV3Vm9sRGF0YQkAuQkCCQDMCAIJAJEDAgkAtQkCCQCRAwIFBndoRGF0YQULd2hJZHhMZXZlbHMCAV8AAAkAzAgCCQCkAwEFCG5ld0xldmVsBQNuaWwCAV8EBm5ld1ZvbAkBF2dldFdhcmVob3VzZVRvdGFsVm9sdW1lAQUKbmV3Vm9sRGF0YQQEbG9mdAkAtQkCCQCRAwIFBndoRGF0YQUJd2hJZHhMT0ZUAgFfBApuZXdMb2Z0U3RyCQC5CQIJAMwIAgkAkQMCBQRsb2Z0BQl2b2xMb2NrZWQJAMwIAgkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAkAzAgCCQCkAwEJAGUCCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUFBm5ld1ZvbAUGb2xkVm9sCQDMCAIJAKQDAQUGbmV3Vm9sBQNuaWwCAV8JAJUKAwkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQhpbmZyYUtleQUIbmV3TGV2ZWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICCAUBYwJfMgUEYWRkcgUIbmV3TGV2ZWwJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAggFC2NsYWltUmVzdWx0Al8zBQhicElkeFJlcwkAzAgCBQZuZXdNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwCAToJAMwIAgkBC1N0cmluZ0VudHJ5AggFC2NsYWltUmVzdWx0Al80CQC5CQIJAMwIAgUKbmV3Vm9sRGF0YQkAzAgCCQCRAwIFBndoRGF0YQUId2hJZHhSZXMJAMwIAgkAkQMCBQZ3aERhdGEFCHdoSWR4TWF0CQDMCAIJAJEDAgUGd2hEYXRhBQl3aElkeFByb2QJAMwIAgUKbmV3TG9mdFN0cgUDbmlsAgE6BQNuaWwIBQtjbGFpbVJlc3VsdAJfMQUIbmV3TGV2ZWwFB21hdFVzZWQBE3VwZGF0ZVN0YXRzSW50ZXJuYWwEBmx2bEtleQV4cEtleQlwb2ludHNLZXkHZGVsdGFYUAQCeHAJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUFeHBLZXkAAAQFbmV3WFAJAGQCBQJ4cAUHZGVsdGFYUAQJbHZsUG9pbnRzCQEHbGV2ZWxVcAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUGbHZsS2V5AAAFBW5ld1hQCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFBmx2bEtleQkAkQMCBQlsdmxQb2ludHMAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUFeHBLZXkFBW5ld1hQCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlwb2ludHNLZXkJAGQCCQELdmFsdWVPckVsc2UCCQCfCAEFCXBvaW50c0tleQAACQCRAwIFCWx2bFBvaW50cwABBQNuaWwFBW5ld1hQARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAILZHVja0Fzc2V0SWQHZGVsdGFYUAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtkdWNrQXNzZXRJZAQEYWRkcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARBrZXlEdWNrSWRUb093bmVyAQULZHVja0Fzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwMDBRNLU19BTExPV19ST0JPX0RVQ0tTCQAAAggFBWFzc2V0Bmlzc3VlcgUEdGhpcwcJAQhjb250YWlucwIIBQVhc3NldARuYW1lBQtST0JPX1BSRUZJWAcJARN1cGRhdGVTdGF0c0ludGVybmFsBAkBDGtleVVzZXJMZXZlbAEFBGFkZHIJAQlrZXlVc2VyWFABBQRhZGRyCQERa2V5VXNlckZyZWVQb2ludHMBBQRhZGRyBQdkZWx0YVhQCQETdXBkYXRlU3RhdHNJbnRlcm5hbAQJAQxrZXlEdWNrTGV2ZWwBBQtkdWNrQXNzZXRJZAkBCWtleUR1Y2tYUAEFC2R1Y2tBc3NldElkCQERa2V5RHVja0ZyZWVQb2ludHMBBQtkdWNrQXNzZXRJZAUHZGVsdGFYUAEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIEYWRkcgdkZWx0YVhQCQETdXBkYXRlU3RhdHNJbnRlcm5hbAQJAQxrZXlVc2VyTGV2ZWwBBQRhZGRyCQEJa2V5VXNlclhQAQUEYWRkcgkBEWtleVVzZXJGcmVlUG9pbnRzAQUEYWRkcgUHZGVsdGFYUAESYWN0aXZhdGVPbmJvYXJkQXJ0AQRhZGRyBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQECHJlZkJ5S2V5CQEPa2V5QWRkcmVzc1JlZkJ5AQUEYWRkcgQFcmVmQnkJAKIIAQUIcmVmQnlLZXkDCQEBIQEJAQlpc0RlZmluZWQBBQVyZWZCeQkAAgECKVlvdSBhcmUgbm90IGVsaWdpYmxlIGZvciBPTkJPQVJEIGFydGlmYWN0BAZhcnRLZXkJARxrZXlPbmJvYXJkQXJ0RHVja0FjdGl2YXRlZEJ5AQUEYWRkcgQHYXJ0RHVjawkAoggBBQZhcnRLZXkDCQEJaXNEZWZpbmVkAQUHYXJ0RHVjawkAAgEJAKwCAgIvWW91IGFscmVhZHkgdXNlZCB5b3VyIE9OQk9BUkQgYXJ0aWZhY3Qgb24gZHVjayAJAQV2YWx1ZQEFB2FydER1Y2sEEGR1Y2tBY3RpdmF0b3JLZXkJARxrZXlPbmJvYXJkQXJ0QWN0aXZhdGVkT25EdWNrAQULZHVja0Fzc2V0SWQEDWR1Y2tBY3RpdmF0b3IJAKIIAQUQZHVja0FjdGl2YXRvcktleQMJAQlpc0RlZmluZWQBBQ1kdWNrQWN0aXZhdG9yCQACAQkArAICCQCsAgIJAKwCAgIJVGhlIGR1Y2sgBQtkdWNrQXNzZXRJZAI0IGFscmVhZHkgZ290IHBvaW50cyBmcm9tIE9OQk9BUkQgYXJ0aWZhY3QgZnJvbSB1c2VyIAkBBXZhbHVlAQUNZHVja0FjdGl2YXRvcgkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBmFydEtleQULZHVja0Fzc2V0SWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUQZHVja0FjdGl2YXRvcktleQUEYWRkcgUDbmlsCAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgULZHVja0Fzc2V0SWQFCXhwT25ib2FyZAJfMQESYWN0aXZhdGVQcmVzYWxlQXJ0AgRhZGRyDWxhbmRBc3NldElkSW4EAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFE2NsYWltTW9kZVdoVGhlbkR1Y2sFDWxhbmRBc3NldElkSW4EC2xhbmRBc3NldElkCAUBYwJfMgQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCAUBYwJfMwULcmVjTGFuZFNpemUEDWFjdGl2YXRpb25LZXkJASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIFCkFSVFBSRVNBTEUFC2xhbmRBc3NldElkAwkAZgIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUNYWN0aXZhdGlvbktleQAAAAAJAAIBAiVQcmVzYWxlIGFydGlmYWN0IGlzIGFscmVhZHkgYWN0aXZhdGVkAwkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCCAUBYwJfMwUKcmVjTGFuZE51bQUPUFJFU0FMRU5VTUxBTkRTCQACAQkArAICCQCsAgIJAKwCAgUKTEFORFBSRUZJWAIBIAULbGFuZEFzc2V0SWQCJSBpcyBub3QgZWxpZ2libGUgZm9yIHByZXNhbGUgYXJ0aWZhY3QEC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwEBQRhZGRyBQtsYW5kQXNzZXRJZAUGcGllY2VzBRNjbGFpbU1vZGVXaFRoZW5EdWNrCQDNCAIJAM0IAgkAzQgCCAULY2xhaW1SZXN1bHQCXzEJAQxJbnRlZ2VyRW50cnkCBQ1hY3RpdmF0aW9uS2V5BQZwaWVjZXMJAQtTdHJpbmdFbnRyeQIIBQtjbGFpbVJlc3VsdAJfMgkAuQkCCAULY2xhaW1SZXN1bHQCXzMCAToJAQtTdHJpbmdFbnRyeQIIBQtjbGFpbVJlc3VsdAJfNAkAuQkCCAULY2xhaW1SZXN1bHQCXzUCAToBD2NoZWNrVG91cm5hbWVudAELZHVja0Fzc2V0SWQEBmxhc3RJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBRJ0b3VybmFtZW50Q29udHJhY3QFDWxhc3RUb3VySWRLZXkAAAQLY3VyTG9jYXRpb24JALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgIBXwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFEnRvdXJuYW1lbnRDb250cmFjdAUGbGFzdElkBAZzdGF0aWMJAJEDAgUFdERhdGEFCWlkeFN0YXRpYwQHZHluYW1pYwkAkQMCBQV0RGF0YQUKaWR4RHluYW1pYwMJAQIhPQIJAJEDAgULY3VyTG9jYXRpb24FCmxvY0lkeFR5cGUCAVQHAwMDCQAAAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFC2N1ckxvY2F0aW9uBQ9sb2NJZHhDb250aW5lbnQFBmxhc3RJZAkAAAIJAJEDAgUHZHluYW1pYwUOdER5bmFtaWNTdGF0dXMCCklOUFJPR1JFU1MHCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUKdFN0YXRpY0VuZAUDbm93BwkAAgECKllvdXIgZHVjayBpcyB0YWtpbmcgcGFydCBpbiB0aGUgdG91cm5hbWVudAkBCWFzQm9vbGVhbgEJAPwHBAUEdGhpcwIWZXhpdFRvdXJuYW1lbnRJbnRlcm5hbAkAzAgCBQtkdWNrQXNzZXRJZAUDbmlsBQNuaWwBDW1lcmdlSW50ZXJuYWwGC25ld0xhbmRTaXplCG5ld0xldmVsB2Zvcm11bGEEYWRkcgxsYW5kQXNzZXRJZHMHbmVlZE1hdAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBD2NoZWNrVG91cm5hbWVudAEFC2R1Y2tBc3NldElkCQACAQIdbWVyZ2VJbnRlcm5hbF9jaGVja1RvdXJuYW1lbnQKAQpjaGVja01lcmdlAgNhY2MLbGFuZEFzc2V0SWQEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFB3RpbWVLZXkJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAFkCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwQJY29udGluZW50CQCRAwIFAWQFDHJlY0NvbnRpbmVudAMDCQECIT0CCAUDYWNjAl8zAgAJAQIhPQIIBQNhY2MCXzMFCWNvbnRpbmVudAcJAAIBAi5MYW5kcyBzaG91bGQgYmUgb24gdGhlIHNhbWUgY29udGluZW50IHRvIG1lcmdlBAhsYW5kU2l6ZQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQQHc2l6ZXNJbggFA2FjYwJfMQQBaQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCzCQIFB3NpemVzSW4FCGxhbmRTaXplAidZb3UgaGF2ZW4ndCBwYXNzZWQgYWxsIHRoZSBsYW5kcyBuZWVkZWQECHNpemVzT3V0CQCsAgIJAK8CAgUHc2l6ZXNJbgUBaQkAsAICBQdzaXplc0luCQBkAgUBaQABBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBBQhsYW5kU2l6ZQQEYXJ0cwkAZAIIBQNhY2MCXzIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQAAAQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAECHJlcUxldmVsBAckbWF0Y2gwBQhsYW5kU2l6ZQMJAAACAgFTBQckbWF0Y2gwAAMDCQAAAgIBTQUHJG1hdGNoMAAEAwkAAAICAUwFByRtYXRjaDAABQMJAAACAgJYTAUHJG1hdGNoMAAGCQACAQIaT25seSBTLCBNLCBMLCBYTCBjYW4gbWVyZ2UDCQECIT0CBQppbmZyYUxldmVsBQhyZXFMZXZlbAkAAgECIkFsbCBsYW5kcyBzaG91bGQgYmUgbWF4ZWQgdG8gbWVyZ2UEB2xhbmROdW0JAJEDAgUBZAUKcmVjTGFuZE51bQQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBCQCRAwIFAWQFC3JlY1RlcnJhaW5zBAlkZWx0YVRpbWUJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUJc2F2ZWRUaW1lAwkAZgIAAAUJZGVsdGFUaW1lCQACAQkArAICCQCsAgIJAKwCAgImU2F2ZWQgdGltZXN0YW1wIGlzIGluIGZ1dHVyZSwgc2F2ZWQgPSAJAKQDAQUJc2F2ZWRUaW1lAgwsIGN1cnJlbnQgPSAJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAEFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAQxhcHBseUJvbnVzZXMCBQtsYW5kQXNzZXRJZAUGcGllY2VzBAlsYW5kSW5kZXgJAGkCBQZwaWVjZXMFBVNTSVpFBAVicFJlcwkBBmFkZFJlcwUJALUJAggFA2FjYwJfNAIBXwUNdGVycmFpbkNvdW50cwUJZGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UEBXByb3BzCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQIBQNhY2MCXzYFDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAD///////////8BBAZjUHJvcHMJARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAgFA2FjYwNfMTAFDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAD///////////8BBAtzdW1UZXJyYWlucwkBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwECAUDYWNjAl85BQ10ZXJyYWluQ291bnRzBQlsYW5kSW5kZXgAAQQFbGFuZHMIBQNhY2MCXzcEA2lkeAkAzwgCBQVsYW5kcwULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBBQNpZHgJAAIBCQCsAgICIFlvdXIgc3Rha2VkIGxhbmRzIGRvbid0IGNvbnRhaW4gBQtsYW5kQXNzZXRJZAQJY3VzdG9tS2V5CQEaa2V5TGFuZEFzc2V0SWRUb0N1c3RvbU5hbWUBBQtsYW5kQXNzZXRJZAQKY3VzdG9tTmFtZQkBC3ZhbHVlT3JFbHNlAgkAoggBBQljdXN0b21LZXkCAAkAnAoKBQhzaXplc091dAUEYXJ0cwUJY29udGluZW50BQVicFJlcwkAzggCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAggFA2FjYwJfNQkBC0RlbGV0ZUVudHJ5AQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYBQtsYW5kQXNzZXRJZAUEYWRkcgkBC0RlbGV0ZUVudHJ5AQkBEGtleUxhbmRUb0Fzc2V0SWQBBQdsYW5kTnVtCQELRGVsZXRlRW50cnkBCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICBQtsYW5kQXNzZXRJZAUEYWRkcgkBC0RlbGV0ZUVudHJ5AQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJARFrZXlMYW5kTnVtVG9Pd25lcgEFB2xhbmROdW0JAQtEZWxldGVFbnRyeQEJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQUJY3VzdG9tS2V5CQEEQnVybgIJANkEAQULbGFuZEFzc2V0SWQAAQMJAQIhPQIFCmN1c3RvbU5hbWUCAAkAzAgCCQELRGVsZXRlRW50cnkBCQEaa2V5TGFuZEN1c3RvbU5hbWVUb0Fzc2V0SWQBBQpjdXN0b21OYW1lBQNuaWwFA25pbAUFcHJvcHMJANEIAgUFbGFuZHMJAQV2YWx1ZQEFA2lkeAkAZAIIBQNhY2MCXzgFBnBpZWNlcwULc3VtVGVycmFpbnMFBmNQcm9wcwQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkECHByb3BMaXN0CQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBEWtleVJlc1Byb3BvcnRpb25zAAILMF8wXzBfMF8wXzACAV8ECGxhbmRzS2V5CQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUEYWRkcgQIbGFuZHNTdHIJAKIIAQUIbGFuZHNLZXkEB2xhbmRzSW4DCQEJaXNEZWZpbmVkAQUIbGFuZHNTdHIJAL0JAgkBBXZhbHVlAQUIbGFuZHNTdHICAV8FA25pbAQFY29udDAJAJEDAgkAtQkCCAkBBXZhbHVlAQkA7AcBCQDZBAEJAJEDAgUMbGFuZEFzc2V0SWRzAAALZGVzY3JpcHRpb24CAV8FDHJlY0NvbnRpbmVudAQJY29udFByb3BzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBFmtleVJlc1R5cGVzQnlDb250aW5lbnQBBQVjb250MAILMF8wXzBfMF8wXzACAV8EAXIKAAIkbAUMbGFuZEFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAnAoKBQdmb3JtdWxhAAACAAkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMFA25pbAUIcHJvcExpc3QFB2xhbmRzSW4AAAkAtQkCAgswXzBfMF8wXzBfMAIBXwUJY29udFByb3BzCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpjaGVja01lcmdlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQQJY29udGluZW50CAUBcgJfMwQMY29udGluZW50SWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgUKY29udGluZW50cwUJY29udGluZW50CQCsAgICE1Vua25vd24gY29udGluZW50OiAFCWNvbnRpbmVudAQIdGVycmFpbnMJARNnZW5UZXJyYWluc0Zvck1lcmdlAggFAXICXzkJAGkCCQEPbnVtUGllY2VzQnlTaXplAQULbmV3TGFuZFNpemUFBVNTSVpFBAdmcmVlTnVtCQELdmFsdWVPckVsc2UCCQCfCAEJARJrZXlOZXh0RnJlZUxhbmROdW0ACQBkAgUPUFJFU0FMRU5VTUxBTkRTAAEECm5ld0xhbmROdW0JAKQDAQUHZnJlZU51bQQFaXNzdWUJAMIIBQkBB25mdE5hbWUCBQpuZXdMYW5kTnVtBQtuZXdMYW5kU2l6ZQkAuQkCCQDMCAIFCm5ld0xhbmROdW0JAMwIAgULbmV3TGFuZFNpemUJAMwIAgUIdGVycmFpbnMJAMwIAgUJY29udGluZW50BQNuaWwCAV8AAQAABwQHYXNzZXRJZAkAuAgBBQVpc3N1ZQQObmV3TGFuZEFzc2V0SWQJANgEAQUHYXNzZXRJZAQGbmV3TWF0CQC5CQIJARFzdWJ0cmFjdE1hdGVyaWFscwMJAGYCBQduZWVkTWF0AAAJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8FB25lZWRNYXQCAV8ECXBpZWNlc0tleQkBFmtleVN0YWtlZFBpZWNlc0J5T3duZXIBBQRhZGRyBAxzdGFrZWRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJcGllY2VzS2V5AAAJAJQKAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAggFAXICXzUDCQBmAgkAkAMBCAUBcgJfNwAACQELU3RyaW5nRW50cnkCBQhsYW5kc0tleQkAuwkCCAUBcgJfNwIBXwkBC0RlbGV0ZUVudHJ5AQUIbGFuZHNLZXkJAQxJbnRlZ2VyRW50cnkCBQlwaWVjZXNLZXkDCQBmAggFAXICXzgFDHN0YWtlZFBpZWNlcwAACQBlAgUMc3Rha2VkUGllY2VzCAUBcgJfOAkBDEludGVnZXJFbnRyeQIJARJrZXlOZXh0RnJlZUxhbmROdW0ACQBkAgUHZnJlZU51bQABBQVpc3N1ZQkBC1N0cmluZ0VudHJ5AgkBEGtleUxhbmRUb0Fzc2V0SWQBBQpuZXdMYW5kTnVtBQ5uZXdMYW5kQXNzZXRJZAkBC1N0cmluZ0VudHJ5AgkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFDm5ld0xhbmRBc3NldElkBQRhZGRyCQELU3RyaW5nRW50cnkCCQERa2V5TGFuZE51bVRvT3duZXIBBQpuZXdMYW5kTnVtBQRhZGRyCQEMSW50ZWdlckVudHJ5AgkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQUObmV3TGFuZEFzc2V0SWQIBQFyAl8yCQEMSW50ZWdlckVudHJ5AgkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQ5uZXdMYW5kQXNzZXRJZAUIbmV3TGV2ZWwJAQxJbnRlZ2VyRW50cnkCCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAgUObmV3TGFuZEFzc2V0SWQFBGFkZHIFCG5ld0xldmVsCQELU3RyaW5nRW50cnkCBQVicEtleQkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAggFAXICXzQJAMwIAgUGbmV3TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6CQELU3RyaW5nRW50cnkCCQERa2V5UmVzUHJvcG9ydGlvbnMACQC5CQIIBQFyAl82AgFfCQELU3RyaW5nRW50cnkCCQEWa2V5UmVzVHlwZXNCeUNvbnRpbmVudAEFCWNvbnRpbmVudAkAuQkCCAUBcgNfMTACAV8JAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkAuQkCCQDMCAIFCWNvbnRpbmVudAkAzAgCAgFMCQDMCAIFDm5ld0xhbmRBc3NldElkBQNuaWwCAV8JAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBGFkZHIAAQUHYXNzZXRJZAUObmV3TGFuZEFzc2V0SWQBA3MybQIEYWRkcgxsYW5kQXNzZXRJZHMJAQ1tZXJnZUludGVybmFsBgIBTQADAgRTU1NTBQRhZGRyBQxsYW5kQXNzZXRJZHMAAAEDbTJsAgRhZGRyDGxhbmRBc3NldElkcwkBDW1lcmdlSW50ZXJuYWwGAgFMAAQCA1NNTQUEYWRkcgUMbGFuZEFzc2V0SWRzCQBoAgURSW5mcmFVcGdyYWRlQ29zdFMABAEEbDJ4bAIEYWRkcgxsYW5kQXNzZXRJZHMJAQ1tZXJnZUludGVybmFsBgICWEwABQIFU1NTTUwFBGFkZHIFDGxhbmRBc3NldElkcwkAaAIFEUluZnJhVXBncmFkZUNvc3RTAC8BBnhsMnh4bAIEYWRkcgxsYW5kQXNzZXRJZHMJAQ1tZXJnZUludGVybmFsBgIDWFhMAAYCA0xYTAUEYWRkcgUMbGFuZEFzc2V0SWRzCQBoAgURSW5mcmFVcGdyYWRlQ29zdFMANgELbWVyZ2VDb21tb24CBGFkZHIMbGFuZEFzc2V0SWRzBAckbWF0Y2gwCQCQAwEFDGxhbmRBc3NldElkcwMJAAACAAQFByRtYXRjaDAJAQNzMm0CBQRhZGRyBQxsYW5kQXNzZXRJZHMDCQAAAgADBQckbWF0Y2gwCQEDbTJsAgUEYWRkcgUMbGFuZEFzc2V0SWRzAwkAAAIABQUHJG1hdGNoMAkBBGwyeGwCBQRhZGRyBQxsYW5kQXNzZXRJZHMDCQAAAgACBQckbWF0Y2gwCQEGeGwyeHhsAgUEYWRkcgUMbGFuZEFzc2V0SWRzCQACAQINVW5rbm93biBtZXJnZQEGcHJvbG9nAQFpAwMJAQIhPQIIBQFpDG9yaWdpbkNhbGxlcgUMcmVzdENvbnRyYWN0CQELdmFsdWVPckVsc2UCCQCgCAEJAQprZXlCbG9ja2VkAAcHCQACAQIfQ29udHJhY3RzIGFyZSB1bmRlciBtYWludGVuYW5jZQkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5TGFzdFR4SWRCeVVzZXIBCQClCAEIBQFpDG9yaWdpbkNhbGxlcgkA2AQBCAUBaQ10cmFuc2FjdGlvbklkBQNuaWwpAWkBDWNvbnN0cnVjdG9yVjEBCHJlc3RBZGRyAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIRUGVybWlzc2lvbiBkZW5pZWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDmtleVJlc3RBZGRyZXNzAAUIcmVzdEFkZHIFA25pbAFpAQtzYXZlSW50ZWdlcgIDa2V5BmFtb3VudAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECIHNhdmVJbnRlZ2VyIGlzIG5vdCBwdWJsaWMgbWV0aG9kCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQNrZXkFBmFtb3VudAUDbmlsAWkBCnNldEJsb2NrZWQBCWlzQmxvY2tlZAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECEXBlcm1pc3Npb24gZGVuaWVkCQDMCAIJAQxCb29sZWFuRW50cnkCCQEKa2V5QmxvY2tlZAAFCWlzQmxvY2tlZAUDbmlsAWkBCXN0YWtlTGFuZAAEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEB2Fzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIDCQECIT0CCAUDcG10BmFtb3VudAABCQACAQkArAICCQCsAgICBE5GVCAFCkxBTkRQUkVGSVgCJCB0b2tlbiBzaG91bGQgYmUgYXR0YWNoZWQgYXMgcGF5bWVudAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAMJAQIhPQIIBQVhc3NldAZpc3N1ZXIFBHRoaXMJAAIBAhdVbmtub3duIGlzc3VlciBvZiB0b2tlbgMJAQEhAQkBCGNvbnRhaW5zAggFBWFzc2V0BG5hbWUFCkxBTkRQUkVGSVgJAAIBCQCsAgIJAKwCAgIJT25seSBORlQgBQpMQU5EUFJFRklYAhQgdG9rZW5zIGFyZSBhY2NlcHRlZAQLbGFuZE51bVNpemUJALACAggFBWFzc2V0BG5hbWUABAQHbGFuZE51bQMJAQhjb250YWlucwIFC2xhbmROdW1TaXplAgNYWEwJALMCAgULbGFuZE51bVNpemUAAwMJAQhjb250YWlucwIFC2xhbmROdW1TaXplAgJYTAkAswICBQtsYW5kTnVtU2l6ZQACCQCzAgIFC2xhbmROdW1TaXplAAEDCQEBIQEJAQlpc0RlZmluZWQBCQC2CQEFB2xhbmROdW0JAAIBCQCsAgICHkNhbm5vdCBwYXJzZSBsYW5kIG51bWJlciBmcm9tIAgFBWFzc2V0BG5hbWUEC2xhbmRBc3NldElkCQDYBAEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQDCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAhIgaXMgYWxyZWFkeSBzdGFrZWQEAWQJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEJAJEDAgUBZAULcmVjVGVycmFpbnMEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgUBZAULcmVjTGFuZFNpemUECWxhbmRJbmRleAkAaQIFBnBpZWNlcwUFU1NJWkUEBXByb3BzCQERdXBkYXRlUHJvcG9ydGlvbnMDBQ10ZXJyYWluQ291bnRzBQlsYW5kSW5kZXgAAQQMcmVzQnlDb250S2V5CQEWa2V5UmVzVHlwZXNCeUNvbnRpbmVudAEJAJEDAgUBZAUMcmVjQ29udGluZW50BAljb250UHJvcHMJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQxyZXNCeUNvbnRLZXkCCzBfMF8wXzBfMF8wAgFfBBB1cGRhdGVkQ29udFByb3BzCQC5CQIJARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAUJY29udFByb3BzBQ10ZXJyYWluQ291bnRzBQlsYW5kSW5kZXgAAQIBXwQIbGFuZHNLZXkJARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBBQdhZGRyZXNzBAhsYW5kc1N0cgkAoggBBQhsYW5kc0tleQQFbGFuZHMDCQEJaXNEZWZpbmVkAQUIbGFuZHNTdHIJAL0JAgkBBXZhbHVlAQUIbGFuZHNTdHICAV8FA25pbAMJAQ9jb250YWluc0VsZW1lbnQCBQVsYW5kcwULbGFuZEFzc2V0SWQJAAIBCQCsAgICIllvdXIgc3Rha2VkIGxhbmRzIGFscmVhZHkgY29udGFpbiAFC2xhbmRBc3NldElkAwkAZwIJAJADAQUFbGFuZHMFGE1BWF9MQU5EU19TVEFLRURfQllfVVNFUgkAAgEJAKwCAgkArAICAhlZb3VyIGFscmVhZHkgc3Rha2VkIG1heCAoCQCkAwEFGE1BWF9MQU5EU19TVEFLRURfQllfVVNFUgIHKSBsYW5kcwQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAECXBpZWNlc0tleQkBFmtleVN0YWtlZFBpZWNlc0J5T3duZXIBBQdhZGRyZXNzBAlvbGRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJcGllY2VzS2V5AAAECXdsZ1Jlc3VsdAkA/AcEBQt3bGdDb250cmFjdAISb25TdGFrZVVuc3Rha2VMYW5kCQDMCAIFB2FkZHJlc3MFA25pbAUDbmlsCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUHdGltZUtleQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKTEFORFBSRUZJWAULbGFuZEFzc2V0SWQFB2FkZHJlc3MIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQtTdHJpbmdFbnRyeQIFCGxhbmRzS2V5CQC7CQIJAM0IAgUFbGFuZHMFC2xhbmRBc3NldElkAgFfCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlwaWVjZXNLZXkJAGQCBQlvbGRQaWVjZXMFBnBpZWNlcwkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQFB2FkZHJlc3MJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUxhbmROdW1Ub093bmVyAQUHbGFuZE51bQUHYWRkcmVzcwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIFC2xhbmRBc3NldElkBQdhZGRyZXNzBQppbmZyYUxldmVsCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlSZXNQcm9wb3J0aW9ucwAFBXByb3BzCQDMCAIJAQtTdHJpbmdFbnRyeQIFDHJlc0J5Q29udEtleQUQdXBkYXRlZENvbnRQcm9wcwUDbmlsBQ1wcm9sb2dBY3Rpb25zBQl3bGdSZXN1bHQBaQELdW5zdGFrZUxhbmQBDWxhbmRBc3NldElkSW4EDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBGFkZHIJAKUIAQgFAWkGY2FsbGVyBAFjCQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBQRhZGRyBQ1jbGFpbU1vZGVEdWNrBQ1sYW5kQXNzZXRJZEluBAtsYW5kQXNzZXRJZAgFAWMCXzIEAWQIBQFjAl8zBAhsYW5kc0tleQkBFWtleVN0YWtlZExhbmRzQnlPd25lcgEFBGFkZHIEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQQJbGFuZEluZGV4CQBpAgUGcGllY2VzBQVTU0laRQQFcHJvcHMJARF1cGRhdGVQcm9wb3J0aW9ucwMFDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAD///////////8BBAxyZXNCeUNvbnRLZXkJARZrZXlSZXNUeXBlc0J5Q29udGluZW50AQkAkQMCBQFkBQxyZWNDb250aW5lbnQECWNvbnRQcm9wcwkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEFDHJlc0J5Q29udEtleQILMF8wXzBfMF8wXzACAV8EEHVwZGF0ZWRDb250UHJvcHMJALkJAgkBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwEBQljb250UHJvcHMFDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAD///////////8BAgFfBAtjbGFpbVJlc3VsdAkBCGNsYWltQWxsBAUEYWRkcgULbGFuZEFzc2V0SWQFBnBpZWNlcwUNY2xhaW1Nb2RlRHVjawQFbGFuZHMJAL0JAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQhsYW5kc0tleQIAAgFfBANpZHgJAM8IAgUFbGFuZHMFC2xhbmRBc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQUDaWR4CQACAQkArAICAiBZb3VyIHN0YWtlZCBsYW5kcyBkb24ndCBjb250YWluIAULbGFuZEFzc2V0SWQEA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAEDmdvdlJlbGVhc2VUaW1lCQELdmFsdWVPckVsc2UCCQCaCAIFC2dvdkNvbnRyYWN0CQEVa2V5VXNlckd3bFJlbGVhc2VUaW1lAQUEYWRkcgAAAwkAZwIFDmdvdlJlbGVhc2VUaW1lBQNub3cJAAIBCQCsAgICOVlvdXIgZ1dMIGFyZSB0YWtpbmcgcGFydCBpbiB2b3RpbmcsIGNhbm5vdCB1bnN0YWtlIHVudGlsIAkApAMBBQ5nb3ZSZWxlYXNlVGltZQQOYXJiUmVsZWFzZVRpbWUJAGQCCQELdmFsdWVPckVsc2UCCQCaCAIFC3dsZ0NvbnRyYWN0CQEUa2V5TGFzdEFyYlRpbWVCeVVzZXIBBQRhZGRyAAAFDmFyYml0cmFnZURlbGF5AwkAZgIFDmFyYlJlbGVhc2VUaW1lBQNub3cJAAIBCQCsAgICP1lvdXIgc3Rha2VkIGxhbmRzIHRvb2sgcGFydCBpbiBhcmJpdHJhZ2UsIGNhbm5vdCB1bnN0YWtlIHVudGlsIAkApAMBBQ5hcmJSZWxlYXNlVGltZQQJcGllY2VzS2V5CQEWa2V5U3Rha2VkUGllY2VzQnlPd25lcgEFBGFkZHIEDHN0YWtlZFBpZWNlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlwaWVjZXNLZXkAAAQJbmV3UGllY2VzAwkAZgIFBnBpZWNlcwUMc3Rha2VkUGllY2VzAAAJAGUCBQxzdGFrZWRQaWVjZXMFBnBpZWNlcwQJd2xnUmVzdWx0CQD8BwQFC3dsZ0NvbnRyYWN0AhJvblN0YWtlVW5zdGFrZUxhbmQJAMwIAgUEYWRkcgUDbmlsBQNuaWwJAJQKAgkAzggCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgABCQDZBAEFC2xhbmRBc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYBQtsYW5kQXNzZXRJZAUEYWRkcgkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5UmVzUHJvcG9ydGlvbnMABQVwcm9wcwkAzAgCCQELU3RyaW5nRW50cnkCBQxyZXNCeUNvbnRLZXkFEHVwZGF0ZWRDb250UHJvcHMJAMwIAgkBC1N0cmluZ0VudHJ5AggFC2NsYWltUmVzdWx0Al8yCQC5CQIIBQtjbGFpbVJlc3VsdAJfMwIBOgkAzAgCAwkAZgIJAJADAQUFbGFuZHMAAQkBC1N0cmluZ0VudHJ5AgUIbGFuZHNLZXkJALsJAgkA0QgCBQVsYW5kcwkBBXZhbHVlAQUDaWR4AgFfCQELRGVsZXRlRW50cnkBBQhsYW5kc0tleQkAzAgCCQEMSW50ZWdlckVudHJ5AgUJcGllY2VzS2V5BQluZXdQaWVjZXMFA25pbAUNcHJvbG9nQWN0aW9ucwUJd2xnUmVzdWx0AWkBCXN0YWtlRHVjawAEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEB2Fzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIDCQECIT0CCAUDcG10BmFtb3VudAABCQACAQkArAICCQCsAgICBE5GVCAFCkRVQ0tQUkVGSVgCJCB0b2tlbiBzaG91bGQgYmUgYXR0YWNoZWQgYXMgcGF5bWVudAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAQGaXNSb2JvAwMFE0tTX0FMTE9XX1JPQk9fRFVDS1MJAAACCAUFYXNzZXQGaXNzdWVyBQR0aGlzBwkBCGNvbnRhaW5zAggFBWFzc2V0BG5hbWUFC1JPQk9fUFJFRklYBwMDAwkBAiE9AggFBWFzc2V0Bmlzc3VlcgUNaW5jdWJhdG9yQWRkcgkBAiE9AggFBWFzc2V0Bmlzc3VlcgULYnJlZWRlckFkZHIHCQEBIQEFBmlzUm9ibwcJAAIBCQCsAgIJAKwCAgkArAICCQCsAgICElVua25vd24gaXNzdWVyIG9mIAUKRFVDS1BSRUZJWAIEIG9yIAULUk9CT19QUkVGSVgCBiB0b2tlbgMDCQEBIQEJAQhjb250YWlucwIIBQVhc3NldARuYW1lBQpEVUNLUFJFRklYCQEBIQEFBmlzUm9ibwcJAAIBCQCsAgIJAKwCAgkArAICCQCsAgICCU9ubHkgTkZUIAUKRFVDS1BSRUZJWAIEIG9yIAULUk9CT19QUkVGSVgCFCB0b2tlbnMgYXJlIGFjY2VwdGVkBAphc3NldElkU3RyCQDYBAEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQUKYXNzZXRJZFN0cgMJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkJAAIBCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCEiBpcyBhbHJlYWR5IHN0YWtlZAMJAQlpc0RlZmluZWQBCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFB2FkZHJlc3MJAAIBCQCsAgICHVlvdSBhbHJlYWR5IHN0YWtlZCBvbmUgZHVjazogCAUFYXNzZXQEbmFtZQQGbG9jS2V5CQEPa2V5RHVja0xvY2F0aW9uAQUKYXNzZXRJZFN0cgQIbG9jYXRpb24JAKIIAQUGbG9jS2V5BAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQUKYXNzZXRJZFN0cgQIYmFja3BhY2sJAKIIAQUFYnBLZXkECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQphc3NldElkU3RyBAVtYXhIUAkBCW1heEhlYWx0aAEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDGtleUR1Y2tMZXZlbAEFCmFzc2V0SWRTdHIAAAQJY3VySGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aAUFbWF4SFAJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUHdGltZUtleQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKRFVDS1BSRUZJWAkA2AQBBQdhc3NldElkBQdhZGRyZXNzCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5RHVja0lkVG9Pd25lcgEFCmFzc2V0SWRTdHIFB2FkZHJlc3MJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwUKYXNzZXRJZFN0cgUDbmlsAwkBCWlzRGVmaW5lZAEFCGxvY2F0aW9uBQNuaWwJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQZsb2NLZXkFD0RFRkFVTFRMT0NBVElPTgUDbmlsAwkBCWlzRGVmaW5lZAEFCGJhY2twYWNrBQNuaWwJAM4IAgkAzQgCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5AhowOjBfMF8wXzBfMF8wOjBfMF8wXzBfMF8wOgUDbmlsCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoBQljdXJIZWFsdGgFDXByb2xvZ0FjdGlvbnMBaQELdW5zdGFrZUR1Y2sBCmFzc2V0SWRTdHIEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEB2Fzc2V0SWQJANkEAQUKYXNzZXRJZFN0cgQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEBWFzc2V0CQEFdmFsdWUBCQDsBwEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQUKYXNzZXRJZFN0cgMJAQEhAQkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQDCQEBIQEJAQlpc0RlZmluZWQBCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFB2FkZHJlc3MJAAIBCQCsAgIJAKwCAgIJVGhlIGR1Y2sgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBEGtleUR1Y2tJZFRvT3duZXIBBQphc3NldElkU3RyCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQdhZGRyZXNzCQACAQIXU3Rha2VkIE5GVCBpcyBub3QgeW91cnMDCQEPY2hlY2tUb3VybmFtZW50AQUKYXNzZXRJZFN0cgkAAgECG3Vuc3Rha2VEdWNrX2NoZWNrVG91cm5hbWVudAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFCmFzc2V0SWRTdHIEBW1heEhQCQEJbWF4SGVhbHRoAQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEMa2V5RHVja0xldmVsAQUKYXNzZXRJZFN0cgAABAZoZWFsdGgJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoBQVtYXhIUAMJAGYCBQVtYXhIUAUGaGVhbHRoCQACAQkArAICCQCsAgICGVBsZWFzZSBoZWFsIHlvdXIgZHVjayB0byAJAKQDAQUFbWF4SFACE2hwIGJlZm9yZSB1bnN0YWtpbmcJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIAAQUHYXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBBQd0aW1lS2V5CQDMCAIJAQtEZWxldGVFbnRyeQEFCWtleUhlYWx0aAkAzAgCCQELRGVsZXRlRW50cnkBCQEPa2V5RHVja0xvY2F0aW9uAQUKYXNzZXRJZFN0cgkAzAgCCQELRGVsZXRlRW50cnkBCQEQa2V5RHVja0lkVG9Pd25lcgEFCmFzc2V0SWRTdHIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpEVUNLUFJFRklYBQphc3NldElkU3RyBQdhZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFB2FkZHJlc3MFA25pbAUNcHJvbG9nQWN0aW9ucwFpAQhjbGFpbVJlcwIGYW1vdW50DmxhbmRBc3NldElkU3RyBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQGcmVzdWx0CQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFBmFtb3VudAUNY2xhaW1Nb2RlRHVjawUObGFuZEFzc2V0SWRTdHIEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAkAlAoCCQDOCAIJAM0IAgkAzQgCCQDOCAIIBQZyZXN1bHQCXzEICQEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCBQtkdWNrQXNzZXRJZAkAawMFB3hwQ2xhaW0FBmFtb3VudAUFTVVMVDgCXzEJAQtTdHJpbmdFbnRyeQIIBQZyZXN1bHQCXzIJALkJAggFBnJlc3VsdAJfMwIBOgkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfNAkAuQkCCAUGcmVzdWx0Al81AgE6BQ1wcm9sb2dBY3Rpb25zCQCRAwIIBQZyZXN1bHQCXzMFCGJwSWR4UmVzAWkBDGNsYWltUmVzVG9XSAIGYW1vdW50DmxhbmRBc3NldElkU3RyBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQGcmVzdWx0CQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFBmFtb3VudAULY2xhaW1Nb2RlV2gFDmxhbmRBc3NldElkU3RyCQCUCgIJAM4IAgkAzQgCCQDNCAIJAM4IAggFBnJlc3VsdAJfMQgJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgUEYWRkcgkAawMFB3hwQ2xhaW0FBmFtb3VudAUFTVVMVDgCXzEJAQtTdHJpbmdFbnRyeQIIBQZyZXN1bHQCXzIJALkJAggFBnJlc3VsdAJfMwIBOgkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfNAkAuQkCCAUGcmVzdWx0Al81AgE6BQ1wcm9sb2dBY3Rpb25zCQCRAwIIBQZyZXN1bHQCXzUFCHdoSWR4UmVzAWkBBmZsaWdodAIHbWVzc2FnZQNzaWcEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQECHVzZXJBZGRyCQClCAEIBQFpBmNhbGxlcgQBZgkBDGZsaWdodENvbW1vbgMFCHVzZXJBZGRyBQdtZXNzYWdlBQNzaWcEBW5ld0hQCAUBZgJfMQQLZHVja0Fzc2V0SWQIBQFmAl8yBAZsb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQUGbG9jS2V5BQ9ERUZBVUxUTE9DQVRJT04EC25ld0xvY2F0aW9uCAUBZgJfNAMJAAACBQtuZXdMb2NhdGlvbgULY3VyTG9jYXRpb24JAAIBAiJZb3UgY2FuJ3QgZmx5IHRvIHRoZSBzYW1lIGxvY2F0aW9uBAZuZXdMb2MJALUJAgULbmV3TG9jYXRpb24CAV8EBmlzVG91cgkAAAIJAJEDAgUGbmV3TG9jBQpsb2NJZHhUeXBlAgFUBAdpc0RlbGl2CQAAAgkAkQMCBQZuZXdMb2MFCmxvY0lkeFR5cGUCAUQEBWVxS2V5CQEQa2V5RHVja0VxdWlwbWVudAEFC2R1Y2tBc3NldElkBAljdXJyZW50RXEJAQt2YWx1ZU9yRWxzZQIJAKIIAQUFZXFLZXkCFyw7LF8sOyxfLDssXyw7LF8sOyxfLDssBA0kdDA2NjM3MDY2NDc2CQERc3VidHJhY3RFcXVpcG1lbnQCBQljdXJyZW50RXEIBQFmAl81BAVuZXdFcQgFDSR0MDY2MzcwNjY0NzYCXzEED3Nob3VsZFplcm9CdWZmcwgFDSR0MDY2MzcwNjY0NzYCXzIEB2lnbm9yZWQIBQ0kdDA2NjM3MDY2NDc2Al8zBA0kdDA2NjQ3OTY4MzExAwkBASEBCQEJb25NaXNzaW9uAgUSdG91cm5hbWVudENvbnRyYWN0BQtjdXJMb2NhdGlvbgMFBmlzVG91cgkBDGNoZWF0QXR0ZW1wdAMFC2N1ckxvY2F0aW9uBQtuZXdMb2NhdGlvbgAFAwkBASEBBQdpc0RlbGl2AwkAZgIFBW5ld0hQAAAJAJQKAgULbmV3TG9jYXRpb24FBW5ld0hQCQCUCgIFC2N1ckxvY2F0aW9uAAADCQBmAgUFbmV3SFAAAAQBcwkA/AcEBQR0aGlzAg9wcm9jZXNzRGVsaXZlcnkJAMwIAgULZHVja0Fzc2V0SWQFA25pbAUDbmlsAwkAAAIFAXMFAXMJAJQKAgULY3VyTG9jYXRpb24FBW5ld0hQCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQCUCgIFC2N1ckxvY2F0aW9uAAADCQEOaXNJblRvdXJuYW1lbnQCBRJ0b3VybmFtZW50Q29udHJhY3QFC2N1ckxvY2F0aW9uAwkBASEBCQEOaXNJblRvdXJuYW1lbnQCBRJ0b3VybmFtZW50Q29udHJhY3QFC25ld0xvY2F0aW9uCQACAQIqWW91ciBkdWNrIGlzIHRha2luZyBwYXJ0IGluIHRoZSB0b3VybmFtZW50BAVzY29yZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBm5ld0xvYwUIbG9jSWR4SWQEBmN1ckxvYwkAtQkCBQtjdXJMb2NhdGlvbgIBXwQGbGFzdElkCQELdmFsdWVPckVsc2UCCQCaCAIFEnRvdXJuYW1lbnRDb250cmFjdAUNbGFzdFRvdXJJZEtleQAAAwkBAiE9AgUFc2NvcmUJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGY3VyTG9jBQhsb2NJZHhJZAABCQEMY2hlYXRBdHRlbXB0AwULY3VyTG9jYXRpb24FC25ld0xvY2F0aW9uAAcDCQBmAgUFbmV3SFAAAAQJbG9jYWxCZXN0CQELdmFsdWVPckVsc2UCCQCaCAIFEnRvdXJuYW1lbnRDb250cmFjdAkBGmtleUJlc3RSZXN1bHRCeVRvdXJBbmREdWNrAgUGbGFzdElkBQtkdWNrQXNzZXRJZAAABAh1cGRMb2NhbAMJAGYCBQVzY29yZQUJbG9jYWxCZXN0CQD8BwQFEnRvdXJuYW1lbnRDb250cmFjdAIOc2F2ZUR1Y2tSZXN1bHQJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUFc2NvcmUFA25pbAUDbmlsBQR1bml0AwkAAAIFCHVwZExvY2FsBQh1cGRMb2NhbAkAlAoCBQtuZXdMb2NhdGlvbgUFbmV3SFAJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAJQKAgULY3VyTG9jYXRpb24AAAkAAgEJAKwCAgIUVW5rbm93biBjdXJMb2NhdGlvbjoFC2N1ckxvY2F0aW9uBAlsb2NUb1NhdmUIBQ0kdDA2NjQ3OTY4MzExAl8xBAhocFRvU2F2ZQgFDSR0MDY2NDc5NjgzMTECXzIJAJQKAgkAzggCCQDOCAIJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQZsb2NLZXkFCWxvY1RvU2F2ZQkAzAgCCQELU3RyaW5nRW50cnkCBQVlcUtleQUFbmV3RXEJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQFCGhwVG9TYXZlBQNuaWwFDXByb2xvZ0FjdGlvbnMDBQ9zaG91bGRaZXJvQnVmZnMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDGtleUR1Y2tCdWZmcwEFC2R1Y2tBc3NldElkAgkwXzBfMF8wXzAFA25pbAUDbmlsCAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgULZHVja0Fzc2V0SWQDCQBmAgUFbmV3SFAAAAUPeHBTdWNjZXNzRmxpZ2h0BQx4cEZhaWxGbGlnaHQCXzEIBQFmAl8zAWkBBGhlYWwDCnF1YW50aXR5TDEKcXVhbnRpdHlMMgpxdWFudGl0eUwzBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMDAwkAZgIAAAUKcXVhbnRpdHlMMQYJAGYCAAAFCnF1YW50aXR5TDIGCQBmAgAABQpxdWFudGl0eUwzCQACAQIbUXVhbnRpdHkgY2Fubm90IGJlIG5lZ2F0aXZlBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBD2NoZWNrVG91cm5hbWVudAEFC2R1Y2tBc3NldElkCQACAQIUaGVhbF9jaGVja1RvdXJuYW1lbnQEA3F0cwkAzAgCBQpxdWFudGl0eUwxCQDMCAIFCnF1YW50aXR5TDIJAMwIAgUKcXVhbnRpdHlMMwUDbmlsBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEBW1heEhQCQEJbWF4SGVhbHRoAQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEMa2V5RHVja0xldmVsAQULZHVja0Fzc2V0SWQAAAQJb2xkSGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aAUFbWF4SFADCQBnAgUJb2xkSGVhbHRoBQVtYXhIUAkAAgEJAKwCAgkArAICAg9IUCBzaG91bGQgYmUgPCAJAKQDAQUFbWF4SFACCCB0byBoZWFsBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQIcHJvZExpc3QDCQAAAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgAFA25pbAkAvAkCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAV8KAQtpdGVyYXRlUHJvZAIDYWNjBnJlY2lwZQQBbggFA2FjYwJfMgQBeAMJAGYCCQCQAwEFCHByb2RMaXN0BQFuCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIcHJvZExpc3QFAW4AAAMJAGYCAAMFAW4EAXEJAJEDAgUDcXRzBQFuAwkAZgIFAXEFAXgJAAIBCQCsAgIJAKwCAgkArAICAg5Zb3UgaGF2ZSBvbmx5IAkApAMBBQF4AgQgb2YgCQCRAwIFCXByb2RUeXBlcwUBbgkAlQoDCQDNCAIIBQNhY2MCXzEJAKQDAQkAZQIFAXgFAXEJAGQCBQFuAAEJAGQCCAUDYWNjAl8zCQBoAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgUGcmVjaXBlAgFfBQpySWR4RWZmZWN0BQFxCQCVCgMJAM0IAggFA2FjYwJfMQkApAMBBQF4CQBkAgUBbgABCAUDYWNjAl8zBAZyZXN1bHQKAAIkbAUQcHJvZHVjdGlvbk1hdHJpeAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJUKAwUDbmlsAAAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQELaXRlcmF0ZVByb2QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDUwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgQJbmV3SGVhbHRoCQCXAwEJAMwIAgUFbWF4SFAJAMwIAgkAZAIFCW9sZEhlYWx0aAgFBnJlc3VsdAJfMwUDbmlsCQCUCgIJAM4IAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgFCW5ld0hlYWx0aAkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQkAugkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQJAMwIAgkAuQkCCAUGcmVzdWx0Al8xAgFfBQNuaWwCAToFA25pbAUNcHJvbG9nQWN0aW9ucwgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkCQBoAgUGeHBIZWFsCQBkAgkAZAIFCnF1YW50aXR5TDEFCnF1YW50aXR5TDIFCnF1YW50aXR5TDMCXzEFCW5ld0hlYWx0aAFpAQZoZWFsRVMABA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHEV4YWN0bHkgb25lIHBheW1lbnQgcmVxdWlyZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AggFA3BtdAdhc3NldElkBQt1c2R0QXNzZXRJZAkAAgECGkFsbG93ZWQgVVNEVCBwYXltZW50IG9ubHkhBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBD2NoZWNrVG91cm5hbWVudAEFC2R1Y2tBc3NldElkCQACAQIWaGVhbEVTX2NoZWNrVG91cm5hbWVudAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAVtYXhIUAkBCW1heEhlYWx0aAEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDGtleUR1Y2tMZXZlbAEFC2R1Y2tBc3NldElkAAAECW9sZEhlYWx0aAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgFBW1heEhQAwkAZgIFCW9sZEhlYWx0aAAACQACAQIoSFAgc2hvdWxkIGJlIDAgdG8gY2FsbCBFbWVyZ2VuY3kgU2VydmljZQQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkECHByb2RMaXN0AwkAAAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIABQNuaWwJALwJAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgFfBA1tZWRLaXRBbW91bnQxAwkAZgIJAJADAQUIcHJvZExpc3QAAAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCHByb2RMaXN0AAAAAAQNbWVkS2l0QW1vdW50MgMJAGYCCQCQAwEFCHByb2RMaXN0AAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhwcm9kTGlzdAABAAAEDW1lZEtpdEFtb3VudDMDCQBmAgkAkAMBBQhwcm9kTGlzdAACCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIcHJvZExpc3QAAgAAAwMDCQBmAgUNbWVkS2l0QW1vdW50MQAABgkAZgIFDW1lZEtpdEFtb3VudDIAAAYJAGYCBQ1tZWRLaXRBbW91bnQzAAAJAAIBAh9Zb3UgaGF2ZSB0byB1c2Ugb3duIE1lZGljYWwgS2l0BAhleGlzdFN0cgkAnQgCBQ9lY29ub215Q29udHJhY3QJAQ5rZXlFc1dhcmVob3VzZQAEDGV4aXN0QW1vdW50cwMJAQlpc0RlZmluZWQBBQhleGlzdFN0cgkAvAkCCQEFdmFsdWUBBQhleGlzdFN0cgIBXwUDbmlsBAtleGlzdEFtb3VudAMJAGYCCQCQAwEFDGV4aXN0QW1vdW50cwAACQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUMZXhpc3RBbW91bnRzAAAAAAMJAGcCAAAFC2V4aXN0QW1vdW50CQACAQI5VGhlcmUgYXJlIG5vIE1lZGljYWwgS2l0cyBMMSBhdCBFbWVyZ2VuY3kgU2VydmljZSBzdG9yYWdlBAluZXdIZWFsdGgJAGQCBQlvbGRIZWFsdGgJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQC1CQIJAJEDAgUQcHJvZHVjdGlvbk1hdHJpeAAAAgFfBQpySWR4RWZmZWN0BAVuZXdFUwkAuQkCCQDMCAIJAKQDAQkAZQIFC2V4aXN0QW1vdW50AAEJANEIAgUMZXhpc3RBbW91bnRzAAACAV8EBnJlY2lwZQkAtQkCCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgAAAIBXwQIdG90YWxNYXQJARJnZXRSZWNpcGVNYXRlcmlhbHMBBQZyZWNpcGUECXNlbGxQcmljZQkAawMJAGgCBQh0b3RhbE1hdAUKRVNTRUxMQ09FRgUQUkVTT1VSQ0VQUklDRU1JTgkAaAIFBU1VTFQ4BQ5QUk9EVUNUUEtHU0laRQMJAQIhPQIIBQNwbXQGYW1vdW50BQlzZWxsUHJpY2UJAAIBCQCsAgICG1BheW1lbnQgYXR0YWNoZWQgc2hvdWxkIGJlIAkApAMBBQlzZWxsUHJpY2UEBnJlc3VsdAkBCGFzU3RyaW5nAQkA/AcEBQ9lY29ub215Q29udHJhY3QCD3VwZGF0ZUVzU3RvcmFnZQkAzAgCBQVuZXdFUwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQt1c2R0QXNzZXRJZAUJc2VsbFByaWNlBQNuaWwJAJQKAgkAzggCCQDNCAIFDXByb2xvZ0FjdGlvbnMJAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgFCW5ld0hlYWx0aAgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkBQh4cENhbGxFUwJfMQUGcmVzdWx0AWkBDnVwZGF0ZUJhY2twYWNrAgtkdWNrQXNzZXRJZAduZXdQYWNrAwkBAiE9AggFAWkGY2FsbGVyBQ9lY29ub215Q29udHJhY3QJAAIBAhFwZXJtaXNzaW9uIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBQduZXdQYWNrBQNuaWwFB25ld1BhY2sBaQEPY29tbWl0Rm9yUmFuZG9tAAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkEC2ZpbmlzaEJsb2NrCQBkAgUGaGVpZ2h0BQtyYW5kb21EZWxheQQEYWRkcgkApQgBCAUBaQZjYWxsZXIJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEJa2V5Q29tbWl0AQUEYWRkcgULZmluaXNoQmxvY2sFA25pbAUNcHJvbG9nQWN0aW9ucwULZmluaXNoQmxvY2sBaQEMcmV2ZWFsUmFuZG9tAQhtYXhWYWx1ZQQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkEBGFkZHIJAKUIAQgFAWkGY2FsbGVyBAlmaW5pc2hLZXkJAQlrZXlDb21taXQBBQRhZGRyBAtmaW5pc2hCbG9jawkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFCWZpbmlzaEtleQIkWW91IGhhdmUgdG8gY29tbWl0Rm9yUmFuZG9tKCkgZmlyc3QhAwkAZgIFC2ZpbmlzaEJsb2NrBQZoZWlnaHQJAAIBCQCsAgICNFJhbmRvbSBudW1iZXIgaXMgbm90IHJlYWR5IHlldCwgd2FpdCB1bnRpbCBoZWlnaHQgPSAJAKQDAQULZmluaXNoQmxvY2sEB2VudHJvcHkJAQV2YWx1ZQEICQEFdmFsdWUBCQDtBwEFC2ZpbmlzaEJsb2NrA3ZyZgQEc2FsdAkAmwMBCQELdmFsdWVPckVsc2UCCQCiCAEJARFrZXlMYXN0VHhJZEJ5VXNlcgEFBGFkZHICAAQEcmFuZAkBD2dldFJhbmRvbU51bWJlcgMFCG1heFZhbHVlBQRzYWx0BQdlbnRyb3B5CQCUCgIJAM4IAgkAzAgCCQELRGVsZXRlRW50cnkBBQlmaW5pc2hLZXkFA25pbAUNcHJvbG9nQWN0aW9ucwUEcmFuZAFpAQhidXlTTGFuZAAEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQIaQWxsb3dlZCBVU0RUIHBheW1lbnQgb25seSEDCQECIT0CCAUDcG10BmFtb3VudAUHRVhQVVNEVAkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFB0VYUFVTRFQEBnJlc3VsdAkBEmV4cGVkaXRpb25JbnRlcm5hbAIIBQFpBmNhbGxlcggFAWkNdHJhbnNhY3Rpb25JZAQLYWNyZXNSZXN1bHQJAQVhc0ludAEJAPwHBAUNYWNyZXNDb250cmFjdAIJYnVybkFjcmVzCQDMCAIFDFNfQ09TVF9BQ1JFUwUDbmlsBQNuaWwJAJQKAgkAzggCCQDOCAIJAM0IAggFBnJlc3VsdAJfMQkBDlNjcmlwdFRyYW5zZmVyAwUPZWNvbm9teUNvbnRyYWN0CAUDcG10BmFtb3VudAULdXNkdEFzc2V0SWQICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIJAKUIAQgFAWkGY2FsbGVyBQp4cE5ld1NMYW5kAl8xBQ1wcm9sb2dBY3Rpb25zCQCUCgIICAUGcmVzdWx0Al8yAl8xBQthY3Jlc1Jlc3VsdAFpAQpleHBlZGl0aW9uAgdtZXNzYWdlA3NpZwQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQIdXNlckFkZHIJAKUIAQgFAWkGY2FsbGVyBAFmCQEMZmxpZ2h0Q29tbW9uAwUIdXNlckFkZHIFB21lc3NhZ2UFA3NpZwQLZHVja0Fzc2V0SWQIBQFmAl8yBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAVtTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQGbmV3TWF0CQC5CQIJARFzdWJ0cmFjdE1hdGVyaWFscwMGBQVtTGlzdAUMRVhQTUFURVJJQUxTAgFfBAVlcUtleQkBEGtleUR1Y2tFcXVpcG1lbnQBBQtkdWNrQXNzZXRJZAQJY3VycmVudEVxCQELdmFsdWVPckVsc2UCCQCiCAEFBWVxS2V5AhcsOyxfLDssXyw7LF8sOyxfLDssXyw7LAQNJHQwNzYyMzE3NjMzNwkBEXN1YnRyYWN0RXF1aXBtZW50AgUJY3VycmVudEVxCAUBZgJfNQQFbmV3RXEIBQ0kdDA3NjIzMTc2MzM3Al8xBA9zaG91bGRaZXJvQnVmZnMIBQ0kdDA3NjIzMTc2MzM3Al8yBAdpZ25vcmVkCAUNJHQwNzYyMzE3NjMzNwJfMwQBZQkBEmV4cGVkaXRpb25JbnRlcm5hbAIIBQFpBmNhbGxlcggFAWkNdHJhbnNhY3Rpb25JZAQCaWQICAUBZQJfMgJfMQQGcmVzdWx0AwkAZwIAAAgFAWYCXzEJAJUKAwkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoAAAJAMwIAgkBC1N0cmluZ0VudHJ5AgUFZXFLZXkFBW5ld0VxBQNuaWwCAAAACQCVCgMJAM4IAggFAWUCXzEDBQ9zaG91bGRaZXJvQnVmZnMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDGtleUR1Y2tCdWZmcwEFC2R1Y2tBc3NldElkAgkwXzBfMF8wXzAFA25pbAkAzQgCCQDNCAIJAM0IAgkAzQgCBQNuaWwJAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkAuQkCCQDMCAIICAUBZQJfMgJfMgkAzAgCAgFMCQDMCAIFAmlkBQNuaWwCAV8JAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgIBQFmAl8xCQELU3RyaW5nRW50cnkCBQVlcUtleQUFbmV3RXEJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwkAzAgCBQZuZXdNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwCAToFAmlkCAUBZgJfMwMJAQ9jaGVja1RvdXJuYW1lbnQBBQtkdWNrQXNzZXRJZAkAAgECGmV4cGVkaXRpb25fY2hlY2tUb3VybmFtZW50BAthY3Jlc1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ1hY3Jlc0NvbnRyYWN0AglidXJuQWNyZXMJAMwIAgUMU19DT1NUX0FDUkVTBQNuaWwFA25pbAkAlAoCCQDOCAIJAM4IAggFBnJlc3VsdAJfMQgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkBQp4cE5ld1NMYW5kAl8xBQ1wcm9sb2dBY3Rpb25zCQCVCgMIBQZyZXN1bHQCXzIIBQZyZXN1bHQCXzMFC2FjcmVzUmVzdWx0AWkBEGJ1eVNMYW5kRm9yQWNyZXMABA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABANhbXQIBQNwbXQGYW1vdW50AwMJAQEhAQkBCWlzRGVmaW5lZAEIBQNwbXQHYXNzZXRJZAYJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAUMYWNyZXNBc3NldElkCQACAQIUQUNSRVMgcGF5bWVudHMgb25seSEDCQECIT0CBQNhbXQFDFNfQ09TVF9BQ1JFUwkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFDFNfQ09TVF9BQ1JFUwQGcmVzdWx0CQESZXhwZWRpdGlvbkludGVybmFsAggFAWkGY2FsbGVyCAUBaQ10cmFuc2FjdGlvbklkBAthY3Jlc1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ1hY3Jlc0NvbnRyYWN0AglidXJuQWNyZXMJAMwIAgUMU19DT1NUX0FDUkVTBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFDGFjcmVzQXNzZXRJZAUDYW10BQNuaWwJAJQKAgkAzggCCQDOCAIIBQZyZXN1bHQCXzEICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIJAKUIAQgFAWkGY2FsbGVyBQp4cE5ld1NMYW5kAl8xBQ1wcm9sb2dBY3Rpb25zCQCUCgIICAUGcmVzdWx0Al8yAl8xBQthY3Jlc1Jlc3VsdAFpAQx1cGdyYWRlSW5mcmEBC2xhbmRBc3NldElkBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAZyZXN1bHQJAQ11cEluZnJhQ29tbW9uBAYIBQFpBmNhbGxlcgAABQtsYW5kQXNzZXRJZAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAkAlAoCCQDOCAIJAM4IAggFBnJlc3VsdAJfMQUNcHJvbG9nQWN0aW9ucwgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkCQBrAwUOeHBVcGdyYWRlSW5mcmEIBQZyZXN1bHQCXzMFBU1VTFQ4Al8xCAUGcmVzdWx0Al8yAWkBEGFjdGl2YXRlQXJ0aWZhY3QCB2FydE5hbWUObGFuZEFzc2V0SWRPcHQEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBGFkZHIJAKUIAQgFAWkGY2FsbGVyBAZyZXN1bHQEByRtYXRjaDAFB2FydE5hbWUDCQAAAgIHUFJFU0FMRQUHJG1hdGNoMAkBEmFjdGl2YXRlUHJlc2FsZUFydAIFBGFkZHIFDmxhbmRBc3NldElkT3B0AwkAAAICB09OQk9BUkQFByRtYXRjaDAJARJhY3RpdmF0ZU9uYm9hcmRBcnQBBQRhZGRyCQACAQIQVW5rbm93biBhcnRpZmFjdAkAzggCBQZyZXN1bHQFDXByb2xvZ0FjdGlvbnMBaQEKbWVyZ2VMYW5kcwEMbGFuZEFzc2V0SWRzBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAZyZXN1bHQJAQttZXJnZUNvbW1vbgIJAKUIAQgFAWkGY2FsbGVyBQxsYW5kQXNzZXRJZHMJAJQKAgkAzggCCQDOCAIIBQZyZXN1bHQCXzEFDXByb2xvZ0FjdGlvbnMICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIJAKUIAQgFAWkGY2FsbGVyBQd4cE1lcmdlAl8xCAUGcmVzdWx0Al8yAWkBDWNhcmdvRXhjaGFuZ2UCDGNhcmdvTGlzdFN0cgtsYW5kQXNzZXRJZAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQKY2FyZ29QYXJ0cwkAvAkCBQxjYXJnb0xpc3RTdHICAToEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAlsYW5kSW5kZXgJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwULcmVjTGFuZFNpemUFBVNTSVpFBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgQDbG9jCQC1CQIJAQV2YWx1ZQEFC2N1ckxvY2F0aW9uAgFfAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUwJAAIBCQCsAgIJAKwCAgIWRHVjayBsb2NhdGlvbiB0eXBlIGlzIAkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCESwgYnV0IHNob3VsZCBiZSBMAwkBAiE9AgkAkQMCBQNsb2MFCGxvY0lkeElkBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgIbRHVjayBzaG91bGQgYmUgb24gdGhlIGxhbmQgBQtsYW5kQXNzZXRJZAQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAQJY3VycmVudFdoCQEMZ2V0V2FyZWhvdXNlAwUFd2hLZXkFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBnJlc3VsdAkBCW1vdmVTdHVmZgMFCmNhcmdvUGFydHMFCWN1cnJlbnRXaAULY3VycmVudFBhY2sEBGxvZnQJALUJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4TE9GVAIBXwQFbG9mdE8JAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQIBQZyZXN1bHQCXzcEBWxvZnRGCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUIBQZyZXN1bHQCXzcJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQkAugkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAggFBnJlc3VsdAJfNAkAzAgCCAUGcmVzdWx0Al81CQDMCAIIBQZyZXN1bHQCXzYFA25pbAIBOgkAzAgCCQELU3RyaW5nRW50cnkCBQV3aEtleQkAugkCCQDMCAIJAJEDAgUJY3VycmVudFdoBQt3aElkeExldmVscwkAzAgCCAUGcmVzdWx0Al8xCQDMCAIIBQZyZXN1bHQCXzIJAMwIAggFBnJlc3VsdAJfMwkAzAgCCQC5CQIJAMwIAgkAkQMCBQRsb2Z0BQl2b2xMb2NrZWQJAMwIAgkApAMBBQVsb2Z0TwkAzAgCCQCkAwEFBWxvZnRGCQDMCAIJAJEDAgUEbG9mdAUIdm9sVG90YWwFA25pbAIBXwUDbmlsAgE6BQNuaWwFDXByb2xvZ0FjdGlvbnMBaQENc2F2ZVdhcmVob3VzZQIFd2hTdHILbGFuZEFzc2V0SWQDCQECIT0CCAUBaQZjYWxsZXIFD2Vjb25vbXlDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQEBXdoS2V5CQESa2V5V2FyZWhvdXNlQnlMYW5kAQULbGFuZEFzc2V0SWQEAndoCQC8CQIFBXdoU3RyAgE6AwkBAiE9AgkAkAMBBQJ3aAAFCQACAQIwd2FyZWhvdXNlIHN0cmluZyBzaG91bGQgY29udGFpbiA0ICc6JyBzZXBhcmF0b3JzBAVsb2Z0TAkAkQMCCQC1CQIJAJEDAgUCd2gFCXdoSWR4TE9GVAIBXwUJdm9sTG9ja2VkBAVsb2Z0TwkBF2dldFdhcmVob3VzZU9jY3VwaWVkVm9sAQUCd2gEBWxvZnRUCQEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBCQCRAwIFAndoBQt3aElkeExldmVscwQFbG9mdEYJAGUCCQBlAgUFbG9mdFQJAQ1wYXJzZUludFZhbHVlAQUFbG9mdEwFBWxvZnRPAwkAZgIAAAUFbG9mdEYJAAIBAjBPcGVyYXRpb24gbGVhZHMgdG8gbmVnYXRpdmUgZnJlZSB3YXJlaG91c2Ugc3BhY2UECG5ld1doU3RyCQC6CQIJAMwIAgkAkQMCBQJ3aAULd2hJZHhMZXZlbHMJAMwIAgkAkQMCBQJ3aAUId2hJZHhSZXMJAMwIAgkAkQMCBQJ3aAUId2hJZHhNYXQJAMwIAgkAkQMCBQJ3aAUJd2hJZHhQcm9kCQDMCAIJALkJAgkAzAgCBQVsb2Z0TAkAzAgCCQCkAwEFBWxvZnRPCQDMCAIJAKQDAQUFbG9mdEYJAMwIAgkApAMBBQVsb2Z0VAUDbmlsAgFfBQNuaWwCAToJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQV3aEtleQUIbmV3V2hTdHIFA25pbAUIbmV3V2hTdHIBaQENc2V0Q3VzdG9tTmFtZQMHYXNzZXRJZApjdXN0b21OYW1lBHR5cGUEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQIaQWxsb3dlZCBVU0RUIHBheW1lbnQgb25seSEDCQECIT0CCAUDcG10BmFtb3VudAUMUkVOQU1JTkdDT1NUCQACAQkArAICAhJQYXltZW50IHNob3VsZCBiZSAJAKQDAQUMUkVOQU1JTkdDT1NUAwkBCGNvbnRhaW5zAgUKY3VzdG9tTmFtZQICX18JAAIBCQCsAgICHk5hbWUgc2hvdWxkIG5vdCBjb250YWluICdfXyc6IAUKY3VzdG9tTmFtZQMJAGYCCQCxAgEFCmN1c3RvbU5hbWUFCk1BWE5BTUVMRU4JAAIBCQCsAgICGU5hbWUgdG9vIGxvbmcsIG1heExlbmd0aD0JAKQDAQUKTUFYTkFNRUxFTgQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEB2FjdGlvbnMEByRtYXRjaDAFBHR5cGUDCQAAAgIHQUNDT1VOVAUHJG1hdGNoMAQKcmV2ZXJzZUtleQkBFmtleUN1c3RvbU5hbWVUb0FkZHJlc3MBBQpjdXN0b21OYW1lBAluYW1lT3duZXIJAKIIAQUKcmV2ZXJzZUtleQMJAQlpc0RlZmluZWQBBQluYW1lT3duZXIJAAIBCQCsAgICGU5hbWUgYWxyZWFkeSByZWdpc3RlcmVkOiAFCmN1c3RvbU5hbWUEDWFkZHJUb05hbWVLZXkJARZrZXlBZGRyZXNzVG9DdXN0b21OYW1lAQUEYWRkcgQHb2xkTmFtZQkAoggBBQ1hZGRyVG9OYW1lS2V5BAdmcmVlT2xkAwkBCWlzRGVmaW5lZAEFB29sZE5hbWUJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBFmtleUN1c3RvbU5hbWVUb0FkZHJlc3MBCQEFdmFsdWUBBQdvbGROYW1lBQNuaWwFA25pbAkAzggCCQDNCAIJAM0IAgUHZnJlZU9sZAkBC1N0cmluZ0VudHJ5AgUNYWRkclRvTmFtZUtleQUKY3VzdG9tTmFtZQkBC1N0cmluZ0VudHJ5AgUKcmV2ZXJzZUtleQUEYWRkcggJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgUEYWRkcgUMeHBDdXN0b21OYW1lAl8xAwkAAAICBExBTkQFByRtYXRjaDAEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQdhc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFB2Fzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkxBTkRQUkVGSVgCDSBpcyBub3QgeW91cnMECnJldmVyc2VLZXkJARprZXlMYW5kQ3VzdG9tTmFtZVRvQXNzZXRJZAEFCmN1c3RvbU5hbWUECW5hbWVPd25lcgkAoggBBQpyZXZlcnNlS2V5AwkBCWlzRGVmaW5lZAEFCW5hbWVPd25lcgkAAgEJAKwCAgIZTmFtZSBhbHJlYWR5IHJlZ2lzdGVyZWQ6IAUKY3VzdG9tTmFtZQQOYXNzZXRUb05hbWVLZXkJARprZXlMYW5kQXNzZXRJZFRvQ3VzdG9tTmFtZQEFB2Fzc2V0SWQEB29sZE5hbWUJAKIIAQUOYXNzZXRUb05hbWVLZXkEB2ZyZWVPbGQDCQEJaXNEZWZpbmVkAQUHb2xkTmFtZQkAzAgCCQELRGVsZXRlRW50cnkBCQEaa2V5TGFuZEN1c3RvbU5hbWVUb0Fzc2V0SWQBCQEFdmFsdWUBBQdvbGROYW1lBQNuaWwFA25pbAkAzggCCQDNCAIJAM0IAgUHZnJlZU9sZAkBC1N0cmluZ0VudHJ5AgUOYXNzZXRUb05hbWVLZXkFCmN1c3RvbU5hbWUJAQtTdHJpbmdFbnRyeQIFCnJldmVyc2VLZXkFB2Fzc2V0SWQICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIFBGFkZHIFDHhwQ3VzdG9tTmFtZQJfMQMJAAACAgREVUNLBQckbWF0Y2gwBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQUHYXNzZXRJZAMDCQEBIQEJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkGCQEBIQEJAQlpc0RlZmluZWQBCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHIJAAIBCQCsAgIIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEQa2V5RHVja0lkVG9Pd25lcgEFB2Fzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkRVQ0tQUkVGSVgCDSBpcyBub3QgeW91cnMECnJldmVyc2VLZXkJARprZXlEdWNrQ3VzdG9tTmFtZVRvQXNzZXRJZAEFCmN1c3RvbU5hbWUECW5hbWVPd25lcgkAoggBBQpyZXZlcnNlS2V5AwkBCWlzRGVmaW5lZAEFCW5hbWVPd25lcgkAAgEJAKwCAgIZTmFtZSBhbHJlYWR5IHJlZ2lzdGVyZWQ6IAUKY3VzdG9tTmFtZQQOYXNzZXRUb05hbWVLZXkJARprZXlEdWNrQXNzZXRJZFRvQ3VzdG9tTmFtZQEFB2Fzc2V0SWQEB29sZE5hbWUJAKIIAQUOYXNzZXRUb05hbWVLZXkEB2ZyZWVPbGQDCQEJaXNEZWZpbmVkAQUHb2xkTmFtZQkAzAgCCQELRGVsZXRlRW50cnkBCQEaa2V5RHVja0N1c3RvbU5hbWVUb0Fzc2V0SWQBCQEFdmFsdWUBBQdvbGROYW1lBQNuaWwFA25pbAkAzggCCQDNCAIJAM0IAgUHZnJlZU9sZAkBC1N0cmluZ0VudHJ5AgUOYXNzZXRUb05hbWVLZXkFCmN1c3RvbU5hbWUJAQtTdHJpbmdFbnRyeQIFCnJldmVyc2VLZXkFB2Fzc2V0SWQICQEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCBQdhc3NldElkBQx4cEN1c3RvbU5hbWUCXzEJAAIBAhNVbmtub3duIGVudGl0eSB0eXBlCQCUCgIJAM4IAgkAzQgCBQdhY3Rpb25zCQEOU2NyaXB0VHJhbnNmZXIDBQ9lY29ub215Q29udHJhY3QIBQNwbXQGYW1vdW50BQt1c2R0QXNzZXRJZAUNcHJvbG9nQWN0aW9ucwAAAWkBDHNldFJlZmVycmFscwIJb2xkUGxheWVyCW5ld1BsYXllcgMJAQIhPQIIBQFpD2NhbGxlclB1YmxpY0tleQUDcHViCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQDCQEBIQEJAQlpc0RlZmluZWQBCQCmCAEFCW9sZFBsYXllcgkAAgEJAKwCAgIRSW52YWxpZCBhZGRyZXNzOiAFCW9sZFBsYXllcgQKbmV3YmllQWRkcgkApggBBQluZXdQbGF5ZXIDCQEBIQEJAQlpc0RlZmluZWQBBQpuZXdiaWVBZGRyCQACAQkArAICAhFJbnZhbGlkIGFkZHJlc3M6IAUJbmV3UGxheWVyBAlvbGRMYXN0VHgJAKIIAQkBEWtleUxhc3RUeElkQnlVc2VyAQUJb2xkUGxheWVyAwkBASEBCQEJaXNEZWZpbmVkAQUJb2xkTGFzdFR4CQACAQIib2xkUGxheWVyIGRpZG4ndCBkbyBhbnkgdHggaW4gZ2FtZQMJAGcCAAAICQDvBwEJAQV2YWx1ZQEFCm5ld2JpZUFkZHIJYXZhaWxhYmxlCQACAQIWbmV3UGxheWVyIGhhcyBubyBXQVZFUwQHb2xkc0tleQkBCWtleU9sZGllcwAEBG9sZHMJAKIIAQUHb2xkc0tleQQGb2xkaWVzAwkBCWlzRGVmaW5lZAEFBG9sZHMJALwJAgkBBXZhbHVlAQUEb2xkcwIBXwUDbmlsAwkBD2NvbnRhaW5zRWxlbWVudAIFBm9sZGllcwUJbmV3UGxheWVyCQACAQkArAICBQluZXdQbGF5ZXICJiBpcyBub3QgbmV3YmllIChhbHJlYWR5IGhhcyByZWZlcnJhbHMpBAhyZWZCeUtleQkBD2tleUFkZHJlc3NSZWZCeQEFCW5ld1BsYXllcgQFcmVmQnkJAKIIAQUIcmVmQnlLZXkDAwkBCWlzRGVmaW5lZAEFBXJlZkJ5CQEJaXNEZWZpbmVkAQkApggBCQEFdmFsdWUBBQVyZWZCeQcJAAIBCQCsAgIJAKwCAgUJbmV3UGxheWVyAhQgYWxyZWFkeSBoYXMgcmVmQnk6IAkBBXZhbHVlAQUFcmVmQnkEB3JlZnNLZXkJARNrZXlBZGRyZXNzUmVmZXJyYWxzAQUJb2xkUGxheWVyBARyZWZzCQCiCAEFB3JlZnNLZXkECXJlZnNBcnJheQMJAQlpc0RlZmluZWQBBQRyZWZzCQC8CQIJAQV2YWx1ZQEFBHJlZnMCAV8FA25pbAMJAQ9jb250YWluc0VsZW1lbnQCBQlyZWZzQXJyYXkFCW5ld1BsYXllcgkAAgEJAKwCAgkArAICCQCsAgIFCW9sZFBsYXllcgISIGFscmVhZHkgY29udGFpbnMgBQluZXdQbGF5ZXICESB3aXRoaW4gcmVmZXJyYWxzBAduZXdSZWZzCQC6CQIJAM0IAgUJcmVmc0FycmF5BQluZXdQbGF5ZXICAV8EB25ld09sZHMDCQEPY29udGFpbnNFbGVtZW50AgUGb2xkaWVzBQlvbGRQbGF5ZXIJAQV2YWx1ZQEFBG9sZHMJALoJAgkAzQgCBQZvbGRpZXMFCW9sZFBsYXllcgIBXwkAlAoCCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUIcmVmQnlLZXkFCW9sZFBsYXllcgkAzAgCCQELU3RyaW5nRW50cnkCBQdyZWZzS2V5BQduZXdSZWZzCQDMCAIJAQtTdHJpbmdFbnRyeQIFB29sZHNLZXkFB25ld09sZHMFA25pbAUNcHJvbG9nQWN0aW9ucwAAAWkBEGRpc3RyaWJ1dGVQb2ludHMFCHN0cmVuZ3RoCGFjY3VyYWN5CWludGVsbGVjdAllbmR1cmFuY2UJZGV4dGVyaXR5BA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQLdmlydFdsZ0RhdGEJAQlhc0FueUxpc3QBCQD8BwQFC3dsZ0NvbnRyYWN0AhJjaGVja1dsZ1hwUkVBRE9OTFkJAMwIAgUEYWRkcgUDbmlsBQNuaWwEDXZpcnRXbGdQb2ludHMJAQVhc0ludAEJAJEDAgULdmlydFdsZ0RhdGEAAQQNJHQwOTIxNDk5MjUzOQMJAGcCAAAFDXZpcnRXbGdQb2ludHMJAJQKAgAABQNuaWwEB2RlbHRhWFAJAQVhc0ludAEJAPwHBAULd2xnQ29udHJhY3QCCXRha2VXbGdYcAkAzAgCBQRhZGRyBQNuaWwFA25pbAMJAAACBQdkZWx0YVhQBQdkZWx0YVhQCQCUCgIFDXZpcnRXbGdQb2ludHMJAMwIAgkBDEludGVnZXJFbnRyeQIJAQxrZXlVc2VyTGV2ZWwBBQRhZGRyCQEFYXNJbnQBCQCRAwIFC3ZpcnRXbGdEYXRhAAAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQlrZXlVc2VyWFABBQRhZGRyCQEFYXNJbnQBCQCRAwIFC3ZpcnRXbGdEYXRhAAIFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQJd2xnUG9pbnRzCAUNJHQwOTIxNDk5MjUzOQJfMQQKd2xnQWN0aW9ucwgFDSR0MDkyMTQ5OTI1MzkCXzIEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQKZnJlZUtleUFjYwkBEWtleVVzZXJGcmVlUG9pbnRzAQUEYWRkcgQNZnJlZVBvaW50c0FjYwkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUKZnJlZUtleUFjYwAABQl3bGdQb2ludHMEC2ZyZWVLZXlEdWNrCQERa2V5RHVja0ZyZWVQb2ludHMBBQtkdWNrQXNzZXRJZAQOZnJlZVBvaW50c0R1Y2sJAQt2YWx1ZU9yRWxzZQIJAJ8IAQULZnJlZUtleUR1Y2sAAAQHc3VtRnJlZQkAZAIFDWZyZWVQb2ludHNBY2MFDmZyZWVQb2ludHNEdWNrBA9zdW1Ub0Rpc3RyaWJ1dGUJAGQCCQBkAgkAZAIJAGQCBQhzdHJlbmd0aAUIYWNjdXJhY3kFCWludGVsbGVjdAUJZW5kdXJhbmNlBQlkZXh0ZXJpdHkDCQBmAgUPc3VtVG9EaXN0cmlidXRlBQdzdW1GcmVlCQACAQkArAICCQCsAgICD1RoZXJlIGFyZSBvbmx5IAkApAMBBQdzdW1GcmVlAhogZnJlZSBwb2ludHMgdG8gZGlzdHJpYnV0ZQQIY2hhcnNLZXkJAQxrZXlEdWNrQ2hhcnMBBQtkdWNrQXNzZXRJZAQFY2hhcnMJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQhjaGFyc0tleQIJMF8wXzBfMF8wAgFfBAZuZXdBY2MJAGUCBQ1mcmVlUG9pbnRzQWNjBQ9zdW1Ub0Rpc3RyaWJ1dGUJAJQKAgkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFCmZyZWVLZXlBY2MDCQBmAgAABQZuZXdBY2MAAAUGbmV3QWNjCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQtmcmVlS2V5RHVjawMJAGYCAAAFBm5ld0FjYwkAZAIFDmZyZWVQb2ludHNEdWNrBQZuZXdBY2MFDmZyZWVQb2ludHNEdWNrCQDMCAIJAQtTdHJpbmdFbnRyeQIFCGNoYXJzS2V5CQC5CQIJAMwIAgkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQxjaGFyU3RyZW5ndGgFCHN0cmVuZ3RoCQDMCAIJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUMY2hhckFjY3VyYWN5BQhhY2N1cmFjeQkAzAgCCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDWNoYXJJbnRlbGxlY3QFCWludGVsbGVjdAkAzAgCCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDWNoYXJFbmR1cmFuY2UFCWVuZHVyYW5jZQkAzAgCCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDWNoYXJEZXh0ZXJpdHkFCWRleHRlcml0eQUDbmlsAgFfBQNuaWwFDXByb2xvZ0FjdGlvbnMFCndsZ0FjdGlvbnMAAAFpARxzcGxpdEJ5R2xvYmFsV2VpZ2h0c1JFQURPTkxZAQZhbW91bnQJAJQKAgUDbmlsCQESZ2V0TmVlZGVkTWF0ZXJpYWxzAQUGYW1vdW50AWkBJHNwbGl0QnlHbG9iYWxBbmRMb2NhbFdlaWdodHNSRUFET05MWQMJbWF0QW1vdW50CXJlc0Ftb3VudAh0ZXJyYWlucwQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBBQh0ZXJyYWlucwkAlAoCBQNuaWwJAJQKAgkBEmdldE5lZWRlZE1hdGVyaWFscwEFCW1hdEFtb3VudAkBE2Rpc3RyaWJ1dGVCeVdlaWdodHMCBQlyZXNBbW91bnQFDXRlcnJhaW5Db3VudHMBaQETZ2V0QmFja3BhY2tSRUFET05MWQELZHVja0Fzc2V0SWQJAJQKAgUDbmlsCQC5CQIJAQtnZXRCYWNrcGFjawEJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkAgE6AWkBFGdldFdhcmVob3VzZVJFQURPTkxZAQtsYW5kQXNzZXRJZAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQJbGFuZEluZGV4CQBpAgkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8FC3JlY0xhbmRTaXplBQVTU0laRQQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAJAJQKAgUDbmlsCQC6CQIJAQxnZXRXYXJlaG91c2UDCQESa2V5V2FyZWhvdXNlQnlMYW5kAQULbGFuZEFzc2V0SWQFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAIBOgFpAQpzYXZlTGFzdFR4AAMJAQEhAQkBD2NvbnRhaW5zRWxlbWVudAIJAMwIAgULd2xnQ29udHJhY3QJAMwIAgUPZWNvbm9teUNvbnRyYWN0CQDMCAIFEnRvdXJuYW1lbnRDb250cmFjdAkAzAgCBQ1hY3Jlc0NvbnRyYWN0BQNuaWwIBQFpBmNhbGxlcgkAAgECDUFjY2VzcyBkZW5pZWQJAJQKAgkBBnByb2xvZwEFAWkAKgFpAQ91cGRhdGVEdWNrU3RhdHMCC2R1Y2tBc3NldElkB2RlbHRhWFADCQECIT0CCAUBaQZjYWxsZXIFD2Vjb25vbXlDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkBQdkZWx0YVhQAWkBDnVwZGF0ZUFjY1N0YXRzAgRhZGRyB2RlbHRhWFADCQEBIQEJAQ9jb250YWluc0VsZW1lbnQCCQDMCAIFC3dsZ0NvbnRyYWN0CQDMCAIFD2Vjb25vbXlDb250cmFjdAkAzAgCBQ1hY3Jlc0NvbnRyYWN0BQNuaWwIBQFpBmNhbGxlcgkAAgECDUFjY2VzcyBkZW5pZWQJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgUEYWRkcgUHZGVsdGFYUAFpAQllcXVpcER1Y2sBCWVxdWlwbWVudAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAMJAQ9jaGVja1RvdXJuYW1lbnQBBQtkdWNrQXNzZXRJZAkAAgECGWVxdWlwRHVja19jaGVja1RvdXJuYW1lbnQEBWVxS2V5CQEQa2V5RHVja0VxdWlwbWVudAEFC2R1Y2tBc3NldElkBAtjdXJyZW50U2VncwkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEFBWVxS2V5AhcsOyxfLDssXyw7LF8sOyxfLDssXyw7LAIBXwQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBW5ld0VxCQC1CQIFCWVxdWlwbWVudAIBXwMJAQIhPQIJAJADAQUFbmV3RXEFC05VTVNFR01FTlRTCQACAQIWV3JvbmcgZXF1aXBtZW50IHN0cmluZwQJdGVtcFByb2RCCQEGZHJlc3NCBAULY3VycmVudFNlZ3MJAQ5wcm9kU3RyVG9CeXRlcwEJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAYFA25pbAQIc2VnQnBBdXgJAJEDAgkAtQkCCQCRAwIFBW5ld0VxBQtzZWdCYWNrcGFjawIBOwABBApidWZmRWZmZWN0AwkAAAIFCHNlZ0JwQXV4AgAAAAQEYXV4MAkAkQMCCQC1CQIFCHNlZ0JwQXV4AgEsAAADCQAAAgUEYXV4MAIAAAAEBmlkeENudAkAtQkCBQRhdXgwAgE6BANpZHgJAJEDAgUGaWR4Q250AAAEA2NudAkAkQMCBQZpZHhDbnQAAQMDAwMDCQAAAgUDaWR4AgIwNgYJAAACBQNpZHgCAjA3BgkAAAIFA2lkeAICMDgJAQIhPQIFA2NudAIABwkAZgIJAQ1wYXJzZUludFZhbHVlAQUDY250AAAHCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkAtQkCCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgJAQ1wYXJzZUludFZhbHVlAQUDaWR4AgFfBQpySWR4RWZmZWN0AAAEBXN0YXRzCQEMZ2V0RHVja1N0YXRzBAUEdGhpcwULZHVja0Fzc2V0SWQFCmJ1ZmZFZmZlY3QGBAhuZXdQcm9kQgkBBmRyZXNzQgQFBW5ld0VxBQl0ZW1wUHJvZEIHBQVzdGF0cwQKbmV3UHJvZFN0cgkBDmJ5dGVzVG9Qcm9kU3RyAQUIbmV3UHJvZEIJAJQKAgkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWVxS2V5BQllcXVpcG1lbnQJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALoJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0CQDMCAIFCm5ld1Byb2RTdHIFA25pbAIBOgkAzAgCCQELU3RyaW5nRW50cnkCCQEMa2V5RHVja0J1ZmZzAQULZHVja0Fzc2V0SWQJALkJAgkAzAgCCQCkAwEJAJEDAgUFc3RhdHMABwkAzAgCCQCkAwEJAJEDAgUFc3RhdHMACAkAzAgCCQCkAwEJAJEDAgUFc3RhdHMACQkAzAgCCQCkAwEJAJEDAgUFc3RhdHMACgkAzAgCCQCkAwEJAJEDAgUFc3RhdHMACwUDbmlsAgFfBQNuaWwFDXByb2xvZ0FjdGlvbnMAAAFpARNpbml0RHVja1RvdXJBdHRlbXB0AQtkdWNrQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUSdG91cm5hbWVudENvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAVtYXhIUAkBCW1heEhlYWx0aAEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDGtleUR1Y2tMZXZlbAEFC2R1Y2tBc3NldElkAAAECWN1ckhlYWx0aAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgFBW1heEhQBAljdXJMb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQUJY3VyTG9jS2V5BQ9ERUZBVUxUTE9DQVRJT04EBmxhc3RJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBRJ0b3VybmFtZW50Q29udHJhY3QFDWxhc3RUb3VySWRLZXkAAAQMdG91ckxvY2F0aW9uCQCsAgIJAKQDAQUGbGFzdElkAgRfVF8wCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ5rZXlTYXZlZEhlYWx0aAEFC2R1Y2tBc3NldElkBQljdXJIZWFsdGgJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAUFbWF4SFAJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGtleVNhdmVkTG9jYXRpb24BBQtkdWNrQXNzZXRJZAULY3VyTG9jYXRpb24JAMwIAgkBC1N0cmluZ0VudHJ5AgUJY3VyTG9jS2V5BQx0b3VyTG9jYXRpb24FA25pbAUMdG91ckxvY2F0aW9uAWkBDGJyZWFrQXR0ZW1wdAAEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAljdXJMb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQUJY3VyTG9jS2V5BQ9ERUZBVUxUTE9DQVRJT04DCQECIT0CCQCRAwIJALUJAgULY3VyTG9jYXRpb24CAV8FCmxvY0lkeFR5cGUCAVQJAAIBAiJZb3VyIGR1Y2sgaXMgbm90IGluIHRoZSB0b3VybmFtZW50BAtzYXZlZEhlYWx0aAkBEUBleHRyTmF0aXZlKDEwNTUpAQkBDmtleVNhdmVkSGVhbHRoAQULZHVja0Fzc2V0SWQEDXNhdmVkTG9jYXRpb24JARFAZXh0ck5hdGl2ZSgxMDU4KQEJARBrZXlTYXZlZExvY2F0aW9uAQULZHVja0Fzc2V0SWQJAJQKAgkAzQgCCQDNCAIFDXByb2xvZ0FjdGlvbnMJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBQtzYXZlZEhlYWx0aAkBC1N0cmluZ0VudHJ5AgUJY3VyTG9jS2V5BQ1zYXZlZExvY2F0aW9uBQtjdXJMb2NhdGlvbgFpARRicmVha0F0dGVtcHRDYWxsYmFjawADCQECIT0CCAUBaQZjYWxsZXIFEnRvdXJuYW1lbnRDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQxvcmlnaW5DYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAkBEUBleHRyTmF0aXZlKDEwNTUpAQkBDmtleVNhdmVkSGVhbHRoAQULZHVja0Fzc2V0SWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEQa2V5U2F2ZWRMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQNuaWwCFGJyZWFrQXR0ZW1wdENhbGxiYWNrAWkBFmV4aXRUb3VybmFtZW50SW50ZXJuYWwBC2R1Y2tBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQINQWNjZXNzIGRlbmllZAQLc2F2ZWRIZWFsdGgJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAQ5rZXlTYXZlZEhlYWx0aAEFC2R1Y2tBc3NldElkBA1zYXZlZExvY2F0aW9uCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEQa2V5U2F2ZWRMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQFC3NhdmVkSGVhbHRoCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUNc2F2ZWRMb2NhdGlvbgUDbmlsBwFpAQ9wcm9jZXNzRGVsaXZlcnkBC2R1Y2tBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQINQWNjZXNzIGRlbmllZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIECWZ1bmRUb3RhbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9lY29ub215Q29udHJhY3QFD2RlbGl2ZXJ5RnVuZEtleQAAAwkAZgIFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQUJZnVuZFRvdGFsCQACAQkArAICAiBEZWxpdmVyeSBpcyBub3QgYXZhaWxhYmxlLCBmdW5kPQkBCmZpeGVkUG9pbnQCBQlmdW5kVG90YWwABgQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQIY291bnRLZXkJARRrZXlVc2VyRGVsaXZlcnlDb3VudAEFBGFkZHIEB2xhc3REYXkJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleVVzZXJMYXN0RGVsaXZlcnlEYXkBBQRhZGRyAAAEBXRvZGF5CQBpAgUDbm93BQlEQVlNSUxMSVMEBWNvdW50AwkAAAIFB2xhc3REYXkFBXRvZGF5CQELdmFsdWVPckVsc2UCCQCfCAEFCGNvdW50S2V5AAAAAAQFYWNyZXMJAQt2YWx1ZU9yRWxzZQIJAJoIAgUNYWNyZXNDb250cmFjdAkBGmtleUFjcmVzU3Rha2VkQW1vdW50QnlVc2VyAQUEYWRkcgAABBFhbGxvd2VkRGVsaXZlcmllcwkAZAIFF0FMTE9XRURfRlJFRV9ERUxJVkVSSUVTCQBpAgUFYWNyZXMFGkFDUkVTX0ZPUl9ERUxJVkVSWV9BVFRFTVBUAwkAZwIFBWNvdW50BRFhbGxvd2VkRGVsaXZlcmllcwkAAgEJAKwCAgkArAICAhFZb3UgYWxyZWFkeSB1c2VkIAkApAMBBRFhbGxvd2VkRGVsaXZlcmllcwIcIGRlbGl2ZXJ5IGF0dGVtcHRzIGZvciB0b2RheQQOZ2xvYmFsQ291bnRLZXkJARRrZXlEdWNrRGVsaXZlcnlDb3VudAEFC2R1Y2tBc3NldElkBAZyZXdhcmQJAPwHBAUPZWNvbm9teUNvbnRyYWN0AhJzZW5kRGVsaXZlcnlSZXdhcmQJAMwIAgUEYWRkcgUDbmlsBQNuaWwJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUIY291bnRLZXkJAGQCBQVjb3VudAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5VXNlckxhc3REZWxpdmVyeURheQEFBGFkZHIFBXRvZGF5CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5nbG9iYWxDb3VudEtleQkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUOZ2xvYmFsQ291bnRLZXkAAAABBQNuaWwFBnJld2FyZAFpAQdyb2JMYW5kAgdtZXNzYWdlA3NpZwQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQGd2xnQW10CAUDcG10BmFtb3VudAMDCQEBIQEJAQlpc0RlZmluZWQBCAUDcG10B2Fzc2V0SWQGCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQFCndsZ0Fzc2V0SWQJAAIBAhVXTEdPTEQgcGF5bWVudHMgb25seSEDCQECIT0CBQZ3bGdBbXQFEk1JTl9XTEdPTERfUk9CQkVSWQkAAgEJAKwCAgkArAICAhJQYXltZW50IHNob3VsZCBiZSAJAQpmaXhlZFBvaW50AgUSTUlOX1dMR09MRF9ST0JCRVJZAAgCByBXTEdPTEQEBGFkZHIJAKUIAQgFAWkGY2FsbGVyAwkBASEBCQDEEwMFB21lc3NhZ2UFA3NpZwUDcHViCQACAQIYc2lnbmF0dXJlIGRvZXMgbm90IG1hdGNoBAVwYXJ0cwkAvAkCCQCwCQEFB21lc3NhZ2UCATsEBnJvYkxvZwkAvAkCCQCRAwIFBXBhcnRzAAACAXwEAmhwCQC1CQIJAJEDAgUGcm9iTG9nBQhybEhlYWx0aAIBXwQFY3VySFAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJocAAABAVuZXdIUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmhwAAEECHByb2RVc2VkCQCRAwIFBnJvYkxvZwULcmxQcm9kc1VzZWQECGxhc3RQYXJ0CQC1CQIJAJEDAgUFcGFydHMAAQIBfAQHcm9iVHlwZQkAkQMCBQhsYXN0UGFydAUGcmxUeXBlAwkBAiE9AgUHcm9iVHlwZQIBQgkAAgECHk9ubHkgYmFuayByb2JiZXJ5IGlzIHN1cHBvcnRlZAQEdGltZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGxhc3RQYXJ0BQtybFRpbWVzdGFtcAMDCQBmAgUEdGltZQkAZAIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBRFGSVZFTUlOVVRFU01JTExJUwYJAGYCCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFEUZJVkVNSU5VVEVTTUlMTElTBQR0aW1lCQACAQkArAICCQCsAgIJAKwCAgIcc2lnbmF0dXJlIG91dGRhdGVkOiBsb2dUaW1lPQkApAMBBQR0aW1lAgksIGJjVGltZT0JAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAECXR4RnJvbU1zZwkAkQMCBQhsYXN0UGFydAUIcmxMYXN0VHgEBmxhc3RUeAkBC3ZhbHVlT3JFbHNlAgkAoggBCQERa2V5TGFzdFR4SWRCeVVzZXIBBQRhZGRyAgADCQECIT0CBQZsYXN0VHgFCXR4RnJvbU1zZwkAAgEJAKwCAgkArAICCQCsAgICHlR4IGlkcyBkb24ndCBtYXRjaCEgSW4gc3RhdGU6IAUGbGFzdFR4AgosIGluIG1zZzogBQl0eEZyb21Nc2cEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQFZXFLZXkJARBrZXlEdWNrRXF1aXBtZW50AQULZHVja0Fzc2V0SWQECWN1cnJlbnRFcQkBC3ZhbHVlT3JFbHNlAgkAoggBBQVlcUtleQIXLDssXyw7LF8sOyxfLDssXyw7LF8sOywEDyR0MDEwOTcxNzEwOTgyOAkBEXN1YnRyYWN0RXF1aXBtZW50AgUJY3VycmVudEVxBQhwcm9kVXNlZAQFbmV3RXEIBQ8kdDAxMDk3MTcxMDk4MjgCXzEED3Nob3VsZFplcm9CdWZmcwgFDyR0MDEwOTcxNzEwOTgyOAJfMgQIaXNCcFVzZWQIBQ8kdDAxMDk3MTcxMDk4MjgCXzMEC2N1ckxvY2F0aW9uCQELdmFsdWVPckVsc2UCCQCiCAEJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OAwkBDmlzSW5Ub3VybmFtZW50AgUSdG91cm5hbWVudENvbnRyYWN0BQtjdXJMb2NhdGlvbgkAAgECKllvdXIgZHVjayBpcyB0YWtpbmcgcGFydCBpbiB0aGUgdG91cm5hbWVudAQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQIY291bnRLZXkJARNrZXlVc2VyUm9iYmVyeUNvdW50AQUEYWRkcgQHbGFzdERheQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEVa2V5VXNlckxhc3RSb2JiZXJ5RGF5AQUEYWRkcgAABAV0b2RheQkAaQIFA25vdwUJREFZTUlMTElTBAVjb3VudAMJAAACBQdsYXN0RGF5BQV0b2RheQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQhjb3VudEtleQAAAAAEBWFjcmVzCQELdmFsdWVPckVsc2UCCQCaCAIFDWFjcmVzQ29udHJhY3QJARprZXlBY3Jlc1N0YWtlZEFtb3VudEJ5VXNlcgEFBGFkZHIAAAQQYWxsb3dlZFJvYmJlcmllcwkAZAIFFkFMTE9XRURfRlJFRV9ST0JCRVJJRVMJAGkCBQVhY3JlcwUZQUNSRVNfRk9SX1JPQkJFUllfQVRURU1QVAMJAGcCBQVjb3VudAUQYWxsb3dlZFJvYmJlcmllcwkAAgEJAKwCAgkArAICAhFZb3UgYWxyZWFkeSB1c2VkIAkApAMBBRBhbGxvd2VkUm9iYmVyaWVzAhsgcm9iYmVyeSBhdHRlbXB0cyBmb3IgdG9kYXkEDmdsb2JhbENvdW50S2V5CQETa2V5RHVja1JvYmJlcnlDb3VudAEFC2R1Y2tBc3NldElkBARsb290AwkAZgIFBW5ld0hQAAAECWZ1bmRUb3RhbAkA8AcCBQR0aGlzBQp3bGdBc3NldElkBAVwcml6ZQMFCGlzQnBVc2VkCQBoAgACBRJNSU5fV0xHT0xEX1JPQkJFUlkJAGgCAAUFEk1JTl9XTEdPTERfUk9CQkVSWQMJAGYCBQVwcml6ZQUJZnVuZFRvdGFsCQACAQkArAICCQCsAgIJAKwCAgIiUm9iYmVyeSBpcyBub3QgYXZhaWxhYmxlLCBmdW5kcyA9IAkBCmZpeGVkUG9pbnQCBQlmdW5kVG90YWwACAIUIFdMR09MRCwgcmVxdWlyZWQgPSAJAQpmaXhlZFBvaW50AgUFcHJpemUACAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFBXByaXplBQp3bGdBc3NldElkBQNuaWwFA25pbAkAlAoCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDOCAIJAM4IAgkAzggCBQ1wcm9sb2dBY3Rpb25zBQRsb290AwUPc2hvdWxkWmVyb0J1ZmZzCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQxrZXlEdWNrQnVmZnMBBQtkdWNrQXNzZXRJZAIJMF8wXzBfMF8wBQNuaWwFA25pbAgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkAwkAZgIFBW5ld0hQAAAFDHhwU3VjY2Vzc1JvYgUJeHBGYWlsUm9iAl8xCQEMSW50ZWdlckVudHJ5AgkBGGtleUxhc3RSb2JiZXJ5VGltZUJ5RHVjawEFC2R1Y2tBc3NldElkBQNub3cJAQxJbnRlZ2VyRW50cnkCBQhjb3VudEtleQkAZAIFBWNvdW50AAEJAQxJbnRlZ2VyRW50cnkCCQEVa2V5VXNlckxhc3RSb2JiZXJ5RGF5AQUEYWRkcgUFdG9kYXkJAQxJbnRlZ2VyRW50cnkCBQ5nbG9iYWxDb3VudEtleQkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUOZ2xvYmFsQ291bnRLZXkAAAABCQELU3RyaW5nRW50cnkCBQVlcUtleQUFbmV3RXEJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkCQCWAwEJAMwIAgUFbmV3SFAJAMwIAgAABQNuaWwAAAFpAQtidXlSb2JvRHVjawADCQEBIQEFE0tTX0FMTE9XX1JPQk9fRFVDS1MJAAIBAhVGZWF0dXJlIGlzIHR1cm5lZCBvZmYEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQIaQWxsb3dlZCBVU0RUIHBheW1lbnQgb25seSEDCQECIT0CCAUDcG10BmFtb3VudAUOUk9CT19EVUNLX1VTRFQJAAIBCQCsAgIJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQEKZml4ZWRQb2ludAIFDlJPQk9fRFVDS19VU0RUAAYCBSBVU0RUBAduZXh0TnVtCQELdmFsdWVPckVsc2UCCQCfCAEJAQ9rZXlOZXh0Um9ib0R1Y2sAAAAEBWJ5dGV6CQCaAwEFB25leHROdW0EBG5hbWUJAKwCAgkArAICBQtST0JPX1BSRUZJWAIBLQkAsgICCQDcBAEFBWJ5dGV6AAgEBWNvbG9yCQCyAgIJANwEAQkA1BYBBQVieXRlegAGBAVpc3N1ZQkAwggFBQRuYW1lCQCsAgICN1JvYm8gRHVjayBORlQgZm9yIFdhdmVzTGFuZHMgZ2FtZSwgYmFja2dyb3VuZCBjb2xvciA9ICMFBWNvbG9yAAEAAAcEB2Fzc2V0SWQJALgIAQUFaXNzdWUJAJQKAgkAzQgCCQDNCAIJAM0IAgkAzQgCBQ1wcm9sb2dBY3Rpb25zCQEMSW50ZWdlckVudHJ5AgkBD2tleU5leHRSb2JvRHVjawAJAGQCBQduZXh0TnVtAAEFBWlzc3VlCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQxvcmlnaW5DYWxsZXIAAQUHYXNzZXRJZAkBDlNjcmlwdFRyYW5zZmVyAwUPZWNvbm9teUNvbnRyYWN0CAUDcG10BmFtb3VudAULdXNkdEFzc2V0SWQJAJQKAgkA2AQBBQdhc3NldElkBQVjb2xvcgBQdjGR", "height": 2908526, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 3SQXtVVxLUUN5jytAaq6AuXuiUGHmAhFhVTyCv3v6nCW Next: 7YtfLVRpbiGN3Dc1uuTqV9RS47mUbvj6fWrGgoCDQrSV Diff:
OldNewDifferences
1717
1818 let numPointsOnLevelUp = 3
1919
20-let robberyCostMin = 100000000
21-
22-let robberyCooldownCoeff = 400
23-
2420 let requirements = ["Strength", "Accuracy", "Intellect", "Endurance", "Dexterity", "Level", "Health"]
2521
2622 let charStrength = 0
4339
4440 let MAXPRODINSLOT = 30
4541
46-let landRobCooldowns = [0, 600000, 900000, 43200000, 21600000]
47-
48-let MIN_RES_TO_ROB = 20000000
49-
50-let robIdxLocked = 1
51-
52-let duckIdxFree = 0
53-
54-let duckIdxPreparing = 1
55-
5642 func keyDuckHealth (duckAssetId) = ("duckHealth_" + duckAssetId)
5743
5844
9278 func keyLastRobberyTimeByDuck (duckAssetId) = ("lastRobberyTime_" + duckAssetId)
9379
9480
95-func keyLastRobberyCostByDuck (duckAssetId) = ("lastRobberyCost_" + duckAssetId)
96-
97-
98-func keyLandRobberyState (landAssetId) = ("landRobberyState_" + landAssetId)
99-
100-
101-func keyLandCooldownETA (landAssetId) = ("landCooldownETA_" + landAssetId)
102-
103-
104-func keyDuckRobberyState (duckAssetId) = ("duckRobberyState_" + duckAssetId)
105-
106-
107-func keyLockedLandByDuck (duckAssetId) = ("lockedLandByDuck_" + duckAssetId)
81+func keyDuckRobberyCount (duckAssetId) = ("totalRobberyCountByDuck_" + duckAssetId)
82+
83+
84+func keyUserRobberyCount (addr) = ("userRobberyCount_" + addr)
85+
86+
87+func keyUserLastRobberyDay (addr) = ("userLastRobberyDay_" + addr)
10888
10989
11090 func keyDuckDeliveryCount (duckAssetId) = ("totalDeliveryCountByDuck_" + duckAssetId)
121101 let xpSuccessFlight = 10000
122102
123103 let xpFailFlight = 2000
104+
105+let xpSuccessRob = 10000
106+
107+let xpFailRob = 2000
124108
125109 let xpCallES = 100000
126110
159143 }
160144
161145
162-func getRobberyData (stakingContract,duckAssetId) = {
163- let lastRobCost = valueOrElse(getInteger(stakingContract, keyLastRobberyCostByDuck(duckAssetId)), 0)
164- let lastRobTime = valueOrElse(getInteger(stakingContract, keyLastRobberyTimeByDuck(duckAssetId)), 0)
165- let now = lastBlock.timestamp
166- let robCost = max([robberyCostMin, (lastRobCost - (robberyCooldownCoeff * (now - lastRobTime)))])
167- let duckState = valueOrElse(getInteger(stakingContract, keyDuckRobberyState(duckAssetId)), 0)
168- let lockedLand = valueOrElse(getString(stakingContract, keyLockedLandByDuck(duckAssetId)), "")
169- let landETA = valueOrElse(getInteger(stakingContract, keyLandCooldownETA(lockedLand)), 0)
170- $Tuple5(robCost, lastRobTime, duckState, lockedLand, landETA)
171- }
172-
173-
174146 let LANDPREFIX = "LAND"
175147
176148 let DUCKPREFIX = "DUCK"
195167
196168 let MIN_USDT_FEE_DELIVERY = 50000
197169
170+let MIN_WLGOLD_ROBBERY = 100000000
171+
172+let ALLOWED_FREE_ROBBERIES = 0
173+
174+let ACRES_FOR_ROBBERY_ATTEMPT = 200000000
175+
198176 let ALLOWED_FREE_DELIVERIES = 0
199177
200178 let ACRES_FOR_DELIVERY_ATTEMPT = 200000000
205183
206184 let COEFF2MAT = 10000000
207185
208-let fortAllowedProds = [15, 16, 17, 18, 19, 20, 21, 22, 23]
209-
210186 let productionMatrix = ["8_8_8_17_17_42_12_0_30_0,0,0,0,0,0,0_", "8_8_8_17_17_42_24_0_60_0,0,5,2,0,0,0_", "8_8_8_17_17_42_36_0_120_0,0,10,4,0,0,0_", "8_19_19_8_27_19_26_1_20_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_52_1_40_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_78_1_80_0,0,0,0,0,0,0_001", "8_8_8_8_8_60_13_2_2_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_26_2_4_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_39_2_8_0,0,0,0,0,0,0_011", "30_30_3_17_17_3_30_3_30_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_60_3_50_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_90_3_70_0,0,0,0,0,0,0_111", "18_18_10_18_18_18_11_4_10_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_22_4_20_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_33_4_30_0,0,0,0,0,0,0_201", "4_13_22_4_35_22_23_0_50,1,0_0,0,0,0,0,0,0_", "4_13_22_4_35_22_46_0_50,1,1_0,2,5,0,0,0,0_", "4_13_22_4_35_22_69_0_50,2,1_0,5,10,0,0,0,0_", "5_25_40_5_10_15_20_1_30,1,1_0,0,0,0,0,0,0_", "5_25_40_5_10_15_40_1_30,1,2_2,1,3,0,0,0,0_", "5_25_40_5_10_15_60_1_30,1,3_5,2,8,0,0,0,0_", "23_23_5_20_23_6_35_2_100_0,0,0,0,0,0,0_", "23_23_5_20_23_6_70_2_150_0,0,0,0,0,0,0_", "23_23_5_20_23_6_105_2_200_0,0,0,0,0,0,0_"]
211187
212188 let rIdxCoeff = 6
270246
271247
272248 func keyInfraLevelByAssetId (assetId) = ("infraLevel_" + assetId)
273-
274-
275-func keyFortificationsByLand (landAssetId) = ("fortifications_" + landAssetId)
276249
277250
278251 func keyDuckAssetIdToCustomName (assetId) = ("duckCustomNameByAssetId_" + assetId)
622595 else throw("Unknown chain")
623596 }
624597
625-let EMPTY_PROD50 = base64'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='
626-
627598 let FIVEMINUTESMILLIS = 300000
628599
629600 let RENAMINGCOST = 5000000
709680
710681 let flProdsUsed = 7
711682
683+let rlHealth = 0
684+
685+let rlProdsUsed = 1
686+
687+let rlType = 0
688+
689+let rlLastTx = 2
690+
691+let rlTimestamp = 3
692+
712693 func nftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
713694
714695
784765
785766
786767 func subtractEquipment (oldEq,pUsed) = if ((pUsed == ""))
787- then $Tuple2(oldEq, false)
768+ then $Tuple3(oldEq, false, false)
788769 else {
789770 func subUsed (acc,idxAmt) = {
790771 let parts = split(idxAmt, ",")
811792 let newAmt = if ((curr >= amt))
812793 then (curr - amt)
813794 else throw(((((("You equipped " + toString(curr)) + " of ") + prodTypes[idx]) + ", but tried to use ") + toString(amt)))
814- $Tuple2(((((eqParts[0] + parts[0]) + ":") + toString(newAmt)) + tail), if (acc._2)
795+ $Tuple3(((((eqParts[0] + parts[0]) + ":") + toString(newAmt)) + tail), if (acc._2)
815796 then true
816797 else if (if ((idx >= 6))
817798 then (8 >= idx)
818799 else false)
819800 then (newAmt == 0)
801+ else false, if (acc._3)
802+ then true
803+ else if (if ((idx >= 3))
804+ then (5 >= idx)
805+ else false)
806+ then (amt > 0)
820807 else false)
821808 }
822809 }
825812
826813 let $l = split(pUsed, "_")
827814 let $s = size($l)
828- let $acc0 = $Tuple2(oldEq, false)
815+ let $acc0 = $Tuple3(oldEq, false, false)
829816 func $f0_1 ($a,$i) = if (($i >= $s))
830817 then $a
831818 else subUsed($a, $l[$i])
911898 else throw("List size exceeds 7")
912899
913900 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
914- }
915-
916-
917-func placeProdB (idxCnt,pList,isPositive,duckStats,occupied,free) = {
918- let parts = split(idxCnt, ":")
919- if ((size(parts) != 2))
920- then throw("Incorrect format, should be index:amount")
921- else if (if (!(isPositive))
922- then (size(parts[0]) != 2)
923- else false)
924- then throw("Product idx should be 2 digits, zero padded")
925- else {
926- let productIdx = parseIntValue(parts[0])
927- let count = parseIntValue(parts[1])
928- if (!(containsElement(fortAllowedProds, productIdx)))
929- then throw((("Product '" + prodTypes[productIdx]) + "' cannot be used for land defense"))
930- else if ((0 > count))
931- then throw("Count can't be negative")
932- else if ((count > MAXPRODINSLOT))
933- then throw(((("Can't put more than " + toString(MAXPRODINSLOT)) + " of ") + prodTypes[productIdx]))
934- else if ((count == 0))
935- then $Tuple3(pList, occupied, free)
936- else {
937- let head = take(pList, (8 * productIdx))
938- let curr = toInt(take(drop(pList, (8 * productIdx)), 8))
939- let tail = drop(pList, (8 * (productIdx + 1)))
940- let recipe = split(productionMatrix[productIdx], "_")
941- if (if (!(isPositive))
942- then (count > curr)
943- else false)
944- then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[productIdx]) + ", but tried to use ") + toString(count)))
945- else {
946- let newAmt = if (if (!(isPositive))
947- then checkStatRequirements(duckStats, split(recipe[rIdxRequirements], ","))
948- else false)
949- then (curr - count)
950- else (curr + count)
951- let deltaVol = (toVolume(newAmt, PRODUCTPKGSIZE) - toVolume(curr, PRODUCTPKGSIZE))
952- $Tuple3(((head + toBytes(newAmt)) + tail), (occupied + deltaVol), (free - deltaVol))
953- }
954- }
955- }
956901 }
957902
958903
10881033 }
10891034
10901035
1091-func fortB (segList,pBytes,occupied,free,isPositive,duckStats) = if ((3 > size(segList)))
1092- then throw("At least duck, mines and traps parts are required")
1093- else {
1094- func segment (acc,seg) = {
1095- let j = acc._1
1096- if ((j == 0))
1097- then $Tuple4((j + 1), acc._2, acc._3, acc._4)
1098- else {
1099- let p = placeProdB(seg, acc._2, isPositive, duckStats, acc._3, acc._4)
1100- $Tuple4((j + 1), p._1, p._2, p._3)
1101- }
1102- }
1103-
1104- let t = {
1105- let $l = segList
1106- let $s = size($l)
1107- let $acc0 = $Tuple4(0, pBytes, occupied, free)
1108- func $f0_1 ($a,$i) = if (($i >= $s))
1109- then $a
1110- else segment($a, $l[$i])
1111-
1112- func $f0_2 ($a,$i) = if (($i >= $s))
1113- then $a
1114- else throw("List size exceeds 10")
1115-
1116- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1117- }
1118- $Tuple3(t._2, t._3, t._4)
1119- }
1120-
1121-
11221036 func canWearCurrentEquipment (duckAssetId) = {
11231037 let eqKey = keyDuckEquipment(duckAssetId)
11241038 let currEq = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
1039+ let EMPTY_PROD50 = base64'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='
11251040 let tempProdB = dressB(currEq, EMPTY_PROD50, true, nil)
11261041 let segBpAux = split(currEq[segBackpack], ";")[1]
11271042 let buffEffect = if ((segBpAux == ""))
17331648
17341649
17351650 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
1736- let $t03334333882 = if ((claimMode == claimModeWh))
1651+ let $t03367834217 = if ((claimMode == claimModeWh))
17371652 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
17381653 else {
17391654 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
17431658 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
17441659 else $Tuple2(loc[locIdxId], duckAssetId)
17451660 }
1746- let landAssetId = $t03334333882._1
1747- let duckId = $t03334333882._2
1661+ let landAssetId = $t03367834217._1
1662+ let duckId = $t03367834217._2
17481663 let asset = value(assetInfo(fromBase58String(landAssetId)))
17491664 let timeKey = keyStakedTimeByAssetId(landAssetId)
17501665 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
17921707 let currentPack = getBackpack(bpKey)
17931708 let currentPackRes = split(currentPack[bpIdxRes], "_")
17941709 let currentWhRes = split(currentWh[whIdxRes], "_")
1795- let $t03625637127 = if ((claimMode == claimModeWh))
1710+ let $t03659137462 = if ((claimMode == claimModeWh))
17961711 then $Tuple4(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes], (parseIntValue(loft[volOccupied]) + resToClaim._2), (parseIntValue(loft[volFree]) - resToClaim._2))
17971712 else if ((claimMode == claimModeDuck))
17981713 then $Tuple4(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), parseIntValue(loft[volOccupied]), parseIntValue(loft[volFree]))
18011716 let whAm = min([parseIntValue(loft[volFree]), resToClaim._2])
18021717 $Tuple4(distr._1, distr._2, (parseIntValue(loft[volOccupied]) + whAm), (parseIntValue(loft[volFree]) - whAm))
18031718 }
1804- let whRes = $t03625637127._1
1805- let bpRes = $t03625637127._2
1806- let loftO = $t03625637127._3
1807- let loftF = $t03625637127._4
1719+ let whRes = $t03659137462._1
1720+ let bpRes = $t03659137462._2
1721+ let loftO = $t03659137462._3
1722+ let loftF = $t03659137462._4
18081723 $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxLevels], whRes, currentWh[whIdxMat], currentWh[whIdxProd], makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")])
18091724 }
18101725 }
23682283 let isDeliv = (newLoc[locIdxType] == "D")
23692284 let eqKey = keyDuckEquipment(duckAssetId)
23702285 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2371- let $t06603566132 = subtractEquipment(currentEq, f._5)
2372- let newEq = $t06603566132._1
2373- let shouldZeroBuffs = $t06603566132._2
2374- let $t06613567967 = if (!(onMission(tournamentContract, curLocation)))
2286+ let $t06637066476 = subtractEquipment(currentEq, f._5)
2287+ let newEq = $t06637066476._1
2288+ let shouldZeroBuffs = $t06637066476._2
2289+ let ignored = $t06637066476._3
2290+ let $t06647968311 = if (!(onMission(tournamentContract, curLocation)))
23752291 then if (isTour)
23762292 then cheatAttempt(curLocation, newLocation, 5)
23772293 else if (!(isDeliv))
24082324 else $Tuple2(curLocation, 0)
24092325 }
24102326 else throw(("Unknown curLocation:" + curLocation))
2411- let locToSave = $t06613567967._1
2412- let hpToSave = $t06613567967._2
2327+ let locToSave = $t06647968311._1
2328+ let hpToSave = $t06647968311._2
24132329 $Tuple2(((([StringEntry(locKey, locToSave), StringEntry(eqKey, newEq), IntegerEntry(keyDuckHealth(duckAssetId), hpToSave)] ++ prologActions) ++ (if (shouldZeroBuffs)
24142330 then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
24152331 else nil)) ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
26292545 let newMat = makeString(subtractMaterials(true, mList, EXPMATERIALS), "_")
26302546 let eqKey = keyDuckEquipment(duckAssetId)
26312547 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2632- let $t07588775984 = subtractEquipment(currentEq, f._5)
2633- let newEq = $t07588775984._1
2634- let shouldZeroBuffs = $t07588775984._2
2548+ let $t07623176337 = subtractEquipment(currentEq, f._5)
2549+ let newEq = $t07623176337._1
2550+ let shouldZeroBuffs = $t07623176337._2
2551+ let ignored = $t07623176337._3
26352552 let e = expeditionInternal(i.caller, i.transactionId)
26362553 let id = e._2._1
26372554 let result = if ((0 >= f._1))
29542871 let addr = toString(i.originCaller)
29552872 let virtWlgData = asAnyList(invoke(wlgContract, "checkWlgXpREADONLY", [addr], nil))
29562873 let virtWlgPoints = asInt(virtWlgData[1])
2957- let $t09179692186 = if ((0 >= virtWlgPoints))
2874+ let $t09214992539 = if ((0 >= virtWlgPoints))
29582875 then $Tuple2(0, nil)
29592876 else {
29602877 let deltaXP = asInt(invoke(wlgContract, "takeWlgXp", [addr], nil))
29622879 then $Tuple2(virtWlgPoints, [IntegerEntry(keyUserLevel(addr), asInt(virtWlgData[0])), IntegerEntry(keyUserXP(addr), asInt(virtWlgData[2]))])
29632880 else throw("Strict value is not equal to itself.")
29642881 }
2965- let wlgPoints = $t09179692186._1
2966- let wlgActions = $t09179692186._2
2882+ let wlgPoints = $t09214992539._1
2883+ let wlgActions = $t09214992539._2
29672884 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
29682885 let freeKeyAcc = keyUserFreePoints(addr)
29692886 let freePointsAcc = (valueOrElse(getInteger(freeKeyAcc), 0) + wlgPoints)
30933010
30943011
30953012 @Callable(i)
3096-func fortificateLand (landAssetId,plan) = {
3097- let prologActions = prolog(i)
3098- if ((size(i.payments) != 0))
3099- then throw("No payments required")
3100- else {
3101- let addr = toString(i.originCaller)
3102- let duckAssetId = valueOrElse(getString(keyStakedDuckByOwner(addr)), "")
3103- let duckStats = getDuckStats(this, duckAssetId, 0, false)
3104- let fortKey = keyFortificationsByLand(landAssetId)
3105- let currentForts = split(valueOrElse(getString(fortKey), ":0_15:0_18:0"), "_")
3106- let asset = value(assetInfo(fromBase58String(landAssetId)))
3107- let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
3108- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
3109- let whKey = keyWarehouseByLand(landAssetId)
3110- let wh = getWarehouse(whKey, landIndex, infraLevel)
3111- let curLoft = split(wh[whIdxLOFT], "_")
3112- let curO = parseIntValue(curLoft[volOccupied])
3113- let curF = parseIntValue(curLoft[volFree])
3114- let newForts = split(plan, "_")
3115- let $t09894799062 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3116- let tempProdB = $t09894799062._1
3117- let tempO = $t09894799062._2
3118- let tempF = $t09894799062._3
3119- let $t09906599161 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3120- let newProdB = $t09906599161._1
3121- let newO = $t09906599161._2
3122- let newF = $t09906599161._3
3123- let newProdStr = bytesToProdStr(newProdB)
3124- let newLoftStr = makeString([curLoft[volLocked], toString(newO), toString(newF), curLoft[volTotal]], "_")
3125- $Tuple2(([StringEntry(fortKey, plan), StringEntry(whKey, makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], newProdStr, newLoftStr], ":"))] ++ prologActions), 0)
3126- }
3127- }
3128-
3129-
3130-
3131-@Callable(i)
31323013 func initDuckTourAttempt (duckAssetId) = if ((i.caller != tournamentContract))
31333014 then throw("Access denied")
31343015 else {
32133094
32143095
32153096 @Callable(i)
3216-func prepareRobbery (message,sig) = {
3097+func robLand (message,sig) = {
32173098 let prologActions = prolog(i)
3218- if (!(sigVerify_8Kb(message, sig, pub)))
3219- then throw("signature does not match")
3220- else if ((size(i.payments) != 1))
3221- then throw("exactly 1 payment must be attached")
3222- else {
3223- let pmt = i.payments[0]
3224- let wlgAmt = pmt.amount
3225- if (if (!(isDefined(pmt.assetId)))
3226- then true
3227- else (value(pmt.assetId) != wlgAssetId))
3228- then throw("WLGOLD payments only!")
3099+ if ((size(i.payments) != 1))
3100+ then throw("exactly 1 payment must be attached")
3101+ else {
3102+ let pmt = i.payments[0]
3103+ let wlgAmt = pmt.amount
3104+ if (if (!(isDefined(pmt.assetId)))
3105+ then true
3106+ else (value(pmt.assetId) != wlgAssetId))
3107+ then throw("WLGOLD payments only!")
3108+ else if ((wlgAmt != MIN_WLGOLD_ROBBERY))
3109+ then throw((("Payment should be " + fixedPoint(MIN_WLGOLD_ROBBERY, 8)) + " WLGOLD"))
32293110 else {
3230- let parts = split(toUtf8String(message), "|")
3231- if ((2 > size(parts)))
3232- then throw("Wrong message format")
3111+ let addr = toString(i.caller)
3112+ if (!(sigVerify_8Kb(message, sig, pub)))
3113+ then throw("signature does not match")
32333114 else {
3234- let txFromMsg = if ((size(parts) >= 2))
3235- then parts[2]
3236- else ""
3237- let userAddr = toString(i.caller)
3238- let lastTx = valueOrElse(getString(keyLastTxIdByUser(userAddr)), "")
3239- if ((lastTx != txFromMsg))
3240- then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
3115+ let parts = split_4C(toUtf8String(message), ";")
3116+ let robLog = split_4C(parts[0], "|")
3117+ let hp = split(robLog[rlHealth], "_")
3118+ let curHP = parseIntValue(hp[0])
3119+ let newHP = parseIntValue(hp[1])
3120+ let prodUsed = robLog[rlProdsUsed]
3121+ let lastPart = split(parts[1], "|")
3122+ let robType = lastPart[rlType]
3123+ if ((robType != "B"))
3124+ then throw("Only bank robbery is supported")
32413125 else {
3242- let duckAssetId = parts[0]
3243- if (checkTournament(duckAssetId))
3244- then throw("prepareRobbery_checkTournament")
3126+ let time = parseIntValue(lastPart[rlTimestamp])
3127+ if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
3128+ then true
3129+ else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
3130+ then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
32453131 else {
3246- let robCost = getRobberyData(this, duckAssetId)._1
3247- if ((robCost > wlgAmt))
3248- then throw(((("Payment " + toString(wlgAmt)) + " < required ") + toString(robCost)))
3132+ let txFromMsg = lastPart[rlLastTx]
3133+ let lastTx = valueOrElse(getString(keyLastTxIdByUser(addr)), "")
3134+ if ((lastTx != txFromMsg))
3135+ then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
32493136 else {
3250- let candidates = split(parts[1], "_")
3251- let now = lastBlock.timestamp
3252- let duckState = valueOrElse(getInteger(keyDuckRobberyState(duckAssetId)), 0)
3253- let lockedLand = valueOrElse(getString(keyLockedLandByDuck(duckAssetId)), "")
3254- let landETA = valueOrElse(getInteger(keyLandCooldownETA(lockedLand)), 0)
3255- if (if ((duckState != duckIdxFree))
3256- then (landETA > now)
3257- else false)
3258- then throw(("You already started robbing, wait till " + toString(landETA)))
3137+ let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
3138+ let eqKey = keyDuckEquipment(duckAssetId)
3139+ let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
3140+ let $t0109717109828 = subtractEquipment(currentEq, prodUsed)
3141+ let newEq = $t0109717109828._1
3142+ let shouldZeroBuffs = $t0109717109828._2
3143+ let isBpUsed = $t0109717109828._3
3144+ let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
3145+ if (isInTournament(tournamentContract, curLocation))
3146+ then throw("Your duck is taking part in the tournament")
32593147 else {
3260- func checker (acc,landAssetId) = {
3261- let state = valueOrElse(getInteger(keyLandRobberyState(landAssetId)), 0)
3262- let cooldownETA = valueOrElse(getInteger(keyLandCooldownETA(landAssetId)), 0)
3263- if ((state > size(landRobCooldowns)))
3264- then throw("Invalid state")
3265- else if ((now > cooldownETA))
3148+ let now = lastBlock.timestamp
3149+ let countKey = keyUserRobberyCount(addr)
3150+ let lastDay = valueOrElse(getInteger(keyUserLastRobberyDay(addr)), 0)
3151+ let today = (now / DAYMILLIS)
3152+ let count = if ((lastDay == today))
3153+ then valueOrElse(getInteger(countKey), 0)
3154+ else 0
3155+ let acres = valueOrElse(getInteger(acresContract, keyAcresStakedAmountByUser(addr)), 0)
3156+ let allowedRobberies = (ALLOWED_FREE_ROBBERIES + (acres / ACRES_FOR_ROBBERY_ATTEMPT))
3157+ if ((count >= allowedRobberies))
3158+ then throw((("You already used " + toString(allowedRobberies)) + " robbery attempts for today"))
3159+ else {
3160+ let globalCountKey = keyDuckRobberyCount(duckAssetId)
3161+ let loot = if ((newHP > 0))
32663162 then {
3267- let stakedTime = valueOrElse(getInteger(keyStakedTimeByAssetId(landAssetId)), 0)
3268- if ((0 >= stakedTime))
3269- then acc
3270- else {
3271- let a = value(assetInfo(fromBase58String(landAssetId)))
3272- let d = split(a.description, "_")
3273- let pieces = numPiecesBySize(d[recLandSize])
3274- let productivity = applyBonuses(landAssetId, pieces)
3275- let deltaTime = (now - stakedTime)
3276- let availRes = fraction(deltaTime, (productivity * pieces), DAYMILLIS)
3277- if ((MIN_RES_TO_ROB > availRes))
3278- then acc
3279- else (acc :+ landAssetId)
3280- }
3163+ let fundTotal = assetBalance(this, wlgAssetId)
3164+ let prize = if (isBpUsed)
3165+ then (2 * MIN_WLGOLD_ROBBERY)
3166+ else (5 * MIN_WLGOLD_ROBBERY)
3167+ if ((prize > fundTotal))
3168+ then throw(((("Robbery is not available, funds = " + fixedPoint(fundTotal, 8)) + " WLGOLD, required = ") + fixedPoint(prize, 8)))
3169+ else [ScriptTransfer(i.caller, prize, wlgAssetId)]
32813170 }
3282- else acc
3283- }
3284-
3285- let filtered = {
3286- let $l = candidates
3287- let $s = size($l)
3288- let $acc0 = nil
3289- func $f0_1 ($a,$i) = if (($i >= $s))
3290- then $a
3291- else checker($a, $l[$i])
3292-
3293- func $f0_2 ($a,$i) = if (($i >= $s))
3294- then $a
3295- else throw("List size exceeds 10")
3296-
3297- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
3298- }
3299- if ((size(filtered) == 0))
3300- then throw("No candidates for robbery")
3301- else {
3302- let rndIdx = getRandomNumber(size(filtered), message, sig)
3303- let landAssetId = filtered[rndIdx]
3304- $Tuple2(([IntegerEntry(keyLandRobberyState(landAssetId), robIdxLocked), IntegerEntry(keyLandCooldownETA(landAssetId), (now + landRobCooldowns[robIdxLocked])), IntegerEntry(keyDuckRobberyState(duckAssetId), duckIdxPreparing), StringEntry(keyLockedLandByDuck(duckAssetId), landAssetId)] ++ prologActions), landAssetId)
3171+ else nil
3172+ $Tuple2((((((((((prologActions ++ loot) ++ (if (shouldZeroBuffs)
3173+ then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
3174+ else nil)) ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
3175+ then xpSuccessRob
3176+ else xpFailRob)._1) :+ IntegerEntry(keyLastRobberyTimeByDuck(duckAssetId), now)) :+ IntegerEntry(countKey, (count + 1))) :+ IntegerEntry(keyUserLastRobberyDay(addr), today)) :+ IntegerEntry(globalCountKey, (valueOrElse(getInteger(globalCountKey), 0) + 1))) :+ StringEntry(eqKey, newEq)) :+ IntegerEntry(keyDuckHealth(duckAssetId), max([newHP, 0]))), 0)
33053177 }
33063178 }
33073179 }
33093181 }
33103182 }
33113183 }
3312- }
3313- }
3314-
3315-
3316-
3317-@Callable(i)
3318-func robLand (message,sig) = {
3319- let prologActions = prolog(i)
3320- if (!(sigVerify_8Kb(message, sig, pub)))
3321- then throw("signature does not match")
3322- else {
3323- let userAddr = toString(i.caller)
3324- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
3325- let now = lastBlock.timestamp
3326- $Tuple2((prologActions :+ IntegerEntry(keyLastRobberyTimeByDuck(duckAssetId), now)), 0)
33273184 }
33283185 }
33293186
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let DAYMILLIS = 86400000
55
66 func keyLastArbTimeByUser (addr) = ("lastArbTimeUser_" + addr)
77
88
99 func keyAcresStakedAmountByUser (addr) = ("acresStakedAmountByUser_" + addr)
1010
1111
1212 let SCALE8 = 100000000
1313
1414 let xpLevelScale = 3200
1515
1616 let xpLevelRecipPow = 4000
1717
1818 let numPointsOnLevelUp = 3
1919
20-let robberyCostMin = 100000000
21-
22-let robberyCooldownCoeff = 400
23-
2420 let requirements = ["Strength", "Accuracy", "Intellect", "Endurance", "Dexterity", "Level", "Health"]
2521
2622 let charStrength = 0
2723
2824 let charAccuracy = 1
2925
3026 let charIntellect = 2
3127
3228 let charEndurance = 3
3329
3430 let charDexterity = 4
3531
3632 let segBackpack = 0
3733
3834 let NUMSEGMENTS = 6
3935
4036 let NUMMAINAUX = 2
4137
4238 let MAXSLOTS = 2
4339
4440 let MAXPRODINSLOT = 30
4541
46-let landRobCooldowns = [0, 600000, 900000, 43200000, 21600000]
47-
48-let MIN_RES_TO_ROB = 20000000
49-
50-let robIdxLocked = 1
51-
52-let duckIdxFree = 0
53-
54-let duckIdxPreparing = 1
55-
5642 func keyDuckHealth (duckAssetId) = ("duckHealth_" + duckAssetId)
5743
5844
5945 func keyDuckChars (duckAssetId) = ("duckChars_" + duckAssetId)
6046
6147
6248 func keyDuckXP (duckAssetId) = ("duckXP_" + duckAssetId)
6349
6450
6551 func keyDuckLevel (duckAssetId) = ("duckLevel_" + duckAssetId)
6652
6753
6854 func keyDuckFreePoints (duckAssetId) = ("duckFreePoints_" + duckAssetId)
6955
7056
7157 func keyDuckEquipment (duckAssetId) = ("duckEquipment_" + duckAssetId)
7258
7359
7460 func keyUserXP (addr) = ("userXP_" + addr)
7561
7662
7763 func keyUserLevel (addr) = ("userLevel_" + addr)
7864
7965
8066 func keyUserFreePoints (addr) = ("userFreePoints_" + addr)
8167
8268
8369 func keySavedHealth (duckAssetId) = ("savedHealth_" + duckAssetId)
8470
8571
8672 func keySavedLocation (duckAssetId) = ("savedLocation_" + duckAssetId)
8773
8874
8975 func keyDuckBuffs (duckAssetId) = ("duckBuffs_" + duckAssetId)
9076
9177
9278 func keyLastRobberyTimeByDuck (duckAssetId) = ("lastRobberyTime_" + duckAssetId)
9379
9480
95-func keyLastRobberyCostByDuck (duckAssetId) = ("lastRobberyCost_" + duckAssetId)
96-
97-
98-func keyLandRobberyState (landAssetId) = ("landRobberyState_" + landAssetId)
99-
100-
101-func keyLandCooldownETA (landAssetId) = ("landCooldownETA_" + landAssetId)
102-
103-
104-func keyDuckRobberyState (duckAssetId) = ("duckRobberyState_" + duckAssetId)
105-
106-
107-func keyLockedLandByDuck (duckAssetId) = ("lockedLandByDuck_" + duckAssetId)
81+func keyDuckRobberyCount (duckAssetId) = ("totalRobberyCountByDuck_" + duckAssetId)
82+
83+
84+func keyUserRobberyCount (addr) = ("userRobberyCount_" + addr)
85+
86+
87+func keyUserLastRobberyDay (addr) = ("userLastRobberyDay_" + addr)
10888
10989
11090 func keyDuckDeliveryCount (duckAssetId) = ("totalDeliveryCountByDuck_" + duckAssetId)
11191
11292
11393 func keyUserDeliveryCount (addr) = ("userDeliveryCount_" + addr)
11494
11595
11696 func keyUserLastDeliveryDay (addr) = ("userLastDeliveryDay_" + addr)
11797
11898
11999 let xpClaim = 10000
120100
121101 let xpSuccessFlight = 10000
122102
123103 let xpFailFlight = 2000
104+
105+let xpSuccessRob = 10000
106+
107+let xpFailRob = 2000
124108
125109 let xpCallES = 100000
126110
127111 let xpCustomName = 1000000
128112
129113 let xpNewSLand = 5000000
130114
131115 let xpUpgradeInfra = 10000
132116
133117 let xpMerge = 1000000
134118
135119 let xpOnboard = 1000000
136120
137121 let xpHeal = 10000
138122
139123 func levelByXP (xp) = fraction(xpLevelScale, pow(xp, 4, xpLevelRecipPow, 4, 4, DOWN), SCALE8)
140124
141125
142126 func maxHealth (level) = (100 + level)
143127
144128
145129 func levelUp (currLevel,newXP) = {
146130 let newLevel = levelByXP(newXP)
147131 [newLevel, (numPointsOnLevelUp * (newLevel - currLevel))]
148132 }
149133
150134
151135 func getDuckStats (stakingContract,duckAssetId,buffEffect,forceBuffs) = {
152136 let chars = split(valueOrElse(getString(stakingContract, keyDuckChars(duckAssetId)), "0_0_0_0_0"), "_")
153137 let lvl = valueOrElse(getInteger(stakingContract, keyDuckLevel(duckAssetId)), 0)
154138 let health = valueOrElse(getInteger(stakingContract, keyDuckHealth(duckAssetId)), maxHealth(lvl))
155139 let stateBuffs = split(valueOrElse(getString(stakingContract, keyDuckBuffs(duckAssetId)), "0_0_0_0_0"), "_")
156140 ([parseIntValue(chars[charStrength]), parseIntValue(chars[charAccuracy]), parseIntValue(chars[charIntellect]), parseIntValue(chars[charEndurance]), parseIntValue(chars[charDexterity]), lvl, health] ++ (if (forceBuffs)
157141 then [buffEffect, buffEffect, buffEffect, buffEffect, buffEffect]
158142 else [parseIntValue(stateBuffs[charStrength]), parseIntValue(stateBuffs[charAccuracy]), parseIntValue(stateBuffs[charIntellect]), parseIntValue(stateBuffs[charEndurance]), parseIntValue(stateBuffs[charDexterity])]))
159143 }
160144
161145
162-func getRobberyData (stakingContract,duckAssetId) = {
163- let lastRobCost = valueOrElse(getInteger(stakingContract, keyLastRobberyCostByDuck(duckAssetId)), 0)
164- let lastRobTime = valueOrElse(getInteger(stakingContract, keyLastRobberyTimeByDuck(duckAssetId)), 0)
165- let now = lastBlock.timestamp
166- let robCost = max([robberyCostMin, (lastRobCost - (robberyCooldownCoeff * (now - lastRobTime)))])
167- let duckState = valueOrElse(getInteger(stakingContract, keyDuckRobberyState(duckAssetId)), 0)
168- let lockedLand = valueOrElse(getString(stakingContract, keyLockedLandByDuck(duckAssetId)), "")
169- let landETA = valueOrElse(getInteger(stakingContract, keyLandCooldownETA(lockedLand)), 0)
170- $Tuple5(robCost, lastRobTime, duckState, lockedLand, landETA)
171- }
172-
173-
174146 let LANDPREFIX = "LAND"
175147
176148 let DUCKPREFIX = "DUCK"
177149
178150 let ROBO_PREFIX = "ROBO"
179151
180152 let ARTPRESALE = "PRESALE"
181153
182154 let NUMRES = 6
183155
184156 let MAX_LANDS_STAKED_BY_USER = 25
185157
186158 let DAILYRESBYPIECE = 3456000
187159
188160 let WHMULTIPLIER = 10000000000
189161
190162 let DEFAULTLOCATION = "Africa_F_Africa"
191163
192164 let RESOURCEPRICEMIN = 39637
193165
194166 let ESSELLCOEF = 10
195167
196168 let MIN_USDT_FEE_DELIVERY = 50000
197169
170+let MIN_WLGOLD_ROBBERY = 100000000
171+
172+let ALLOWED_FREE_ROBBERIES = 0
173+
174+let ACRES_FOR_ROBBERY_ATTEMPT = 200000000
175+
198176 let ALLOWED_FREE_DELIVERIES = 0
199177
200178 let ACRES_FOR_DELIVERY_ATTEMPT = 200000000
201179
202180 let prodTypes = ["First Aid Kit L1", "First Aid Kit L2", "First Aid Kit L3", "Backpack L1", "Backpack L2", "Backpack L3", "Food Ration L1", "Food Ration L2", "Food Ration L3", "Jet Pack L1", "Jet Pack L2", "Jet Pack L3", "Shield L1", "Shield L2", "Shield L3", "Mine L1", "Mine L2", "Mine L3", "Trap L1", "Trap L2", "Trap L3", "Boom-Dog L1", "Boom-Dog L2", "Boom-Dog L3"]
203181
204182 let continents = ["Americas", "Europe", "Asia", "Africa", "Oceania"]
205183
206184 let COEFF2MAT = 10000000
207185
208-let fortAllowedProds = [15, 16, 17, 18, 19, 20, 21, 22, 23]
209-
210186 let productionMatrix = ["8_8_8_17_17_42_12_0_30_0,0,0,0,0,0,0_", "8_8_8_17_17_42_24_0_60_0,0,5,2,0,0,0_", "8_8_8_17_17_42_36_0_120_0,0,10,4,0,0,0_", "8_19_19_8_27_19_26_1_20_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_52_1_40_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_78_1_80_0,0,0,0,0,0,0_001", "8_8_8_8_8_60_13_2_2_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_26_2_4_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_39_2_8_0,0,0,0,0,0,0_011", "30_30_3_17_17_3_30_3_30_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_60_3_50_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_90_3_70_0,0,0,0,0,0,0_111", "18_18_10_18_18_18_11_4_10_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_22_4_20_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_33_4_30_0,0,0,0,0,0,0_201", "4_13_22_4_35_22_23_0_50,1,0_0,0,0,0,0,0,0_", "4_13_22_4_35_22_46_0_50,1,1_0,2,5,0,0,0,0_", "4_13_22_4_35_22_69_0_50,2,1_0,5,10,0,0,0,0_", "5_25_40_5_10_15_20_1_30,1,1_0,0,0,0,0,0,0_", "5_25_40_5_10_15_40_1_30,1,2_2,1,3,0,0,0,0_", "5_25_40_5_10_15_60_1_30,1,3_5,2,8,0,0,0,0_", "23_23_5_20_23_6_35_2_100_0,0,0,0,0,0,0_", "23_23_5_20_23_6_70_2_150_0,0,0,0,0,0,0_", "23_23_5_20_23_6_105_2_200_0,0,0,0,0,0,0_"]
211187
212188 let rIdxCoeff = 6
213189
214190 let rIdxEffect = 8
215191
216192 let rIdxRequirements = 9
217193
218194 let rIdxSlots = 10
219195
220196 let PRODUCTPKGSIZE = 10
221197
222198 let whIdxLevels = 0
223199
224200 let whIdxRes = 1
225201
226202 let whIdxMat = 2
227203
228204 let whIdxProd = 3
229205
230206 let whIdxLOFT = 4
231207
232208 let volLocked = 0
233209
234210 let volOccupied = 1
235211
236212 let volFree = 2
237213
238214 let volTotal = 3
239215
240216 let bpIdxLevel = 0
241217
242218 let bpIdxRes = 1
243219
244220 let bpIdxMat = 2
245221
246222 let bpIdxProd = 3
247223
248224 let locIdxContinent = 0
249225
250226 let locIdxType = 1
251227
252228 let locIdxId = 2
253229
254230 func keyLandAssetIdToOwner (assetId) = ("no_" + assetId)
255231
256232
257233 func keyLandAssetIdToCustomName (assetId) = ("lcna_" + assetId)
258234
259235
260236 func keyStakedTimeByAssetId (assetId) = ("st_" + assetId)
261237
262238
263239 func keyLandArtStatusByTypeAndAssetId (type,assetId) = makeString(["las", type, assetId], "_")
264240
265241
266242 func keyStakedTimeByTypeAssetIdAndOwner (nftType,assetId,ownerAddr) = ((((("sttao_" + nftType) + "_") + assetId) + "_") + ownerAddr)
267243
268244
269245 func keyWarehouseByLand (landAssetId) = ("wh_" + landAssetId)
270246
271247
272248 func keyInfraLevelByAssetId (assetId) = ("infraLevel_" + assetId)
273-
274-
275-func keyFortificationsByLand (landAssetId) = ("fortifications_" + landAssetId)
276249
277250
278251 func keyDuckAssetIdToCustomName (assetId) = ("duckCustomNameByAssetId_" + assetId)
279252
280253
281254 func keyAddressToCustomName (addr) = ("accountCustomNameByAddr_" + addr)
282255
283256
284257 func keyAddressRefBy (addr) = ("accRefBy_" + addr)
285258
286259
287260 func keyOnboardArtActivatedOnDuck (duckAssetId) = ("onboardArtActivatedOnDuck_" + duckAssetId)
288261
289262
290263 func keyOnboardArtDuckActivatedBy (addr) = ("onboardArtActivatedDuckBy_" + addr)
291264
292265
293266 func keyAddressReferrals (addr) = ("accReferrals_" + addr)
294267
295268
296269 func keyDuckIdToOwner (assetId) = ("duckOwner_" + assetId)
297270
298271
299272 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
300273
301274
302275 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
303276
304277
305278 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
306279
307280
308281 func keyUserGwlReleaseTime (userAddr) = ("%s%s__userGwlReleaseTime__" + userAddr)
309282
310283
311284 func keyEsWarehouse () = "emergencyWarehouseProducts"
312285
313286
314287 let deliveryFundKey = "deliveryFund"
315288
316289 let lastTourIdKey = "%s__lastTourId"
317290
318291 func keyTourStaticDataById (tId) = ("%s%d__tourStaticData__" + toString(tId))
319292
320293
321294 func keyTourDynamicDataById (tId) = ("%s%d__tourDynamicData__" + toString(tId))
322295
323296
324297 func keyBestResultByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__bestResultByTourAndDuck", toString(tId), duckAssetId], "__")
325298
326299
327300 let idxStatic = 0
328301
329302 let idxDynamic = 1
330303
331304 let tStaticEnd = 6
332305
333306 let tDynamicStatus = 1
334307
335308 func getTourData (tourContract,tId) = {
336309 let static = split(valueOrErrorMessage(getString(tourContract, keyTourStaticDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
337310 let dynamic = split_4C(valueOrErrorMessage(getString(tourContract, keyTourDynamicDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
338311 [static, dynamic]
339312 }
340313
341314
342315 func isInTournament (tourContract,location) = {
343316 let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
344317 let loc = split(location, "_")
345318 let now = lastBlock.timestamp
346319 let tData = getTourData(tourContract, lastId)
347320 let static = tData[idxStatic]
348321 let dynamic = tData[idxDynamic]
349322 if (if (if ((loc[locIdxType] == "T"))
350323 then (parseIntValue(loc[locIdxContinent]) == lastId)
351324 else false)
352325 then (dynamic[tDynamicStatus] == "INPROGRESS")
353326 else false)
354327 then (parseIntValue(static[tStaticEnd]) > now)
355328 else false
356329 }
357330
358331
359332 func onMission (tourContract,location) = {
360333 let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
361334 let loc = split(location, "_")
362335 let now = lastBlock.timestamp
363336 let tData = getTourData(tourContract, lastId)
364337 let static = tData[idxStatic]
365338 let dynamic = tData[idxDynamic]
366339 let locType = loc[locIdxType]
367340 if (if (if ((loc[locIdxType] == "T"))
368341 then (parseIntValue(loc[locIdxContinent]) == lastId)
369342 else false)
370343 then (dynamic[tDynamicStatus] == "INPROGRESS")
371344 else false)
372345 then (parseIntValue(static[tStaticEnd]) > now)
373346 else false
374347 }
375348
376349
377350 func getRecipeMaterials (recipe) = (parseIntValue(recipe[rIdxCoeff]) * COEFF2MAT)
378351
379352
380353 func cheatAttempt (oldLoc,newLoc,cheatCase) = throw(((((("Cheat attempt: oldLoc=" + oldLoc) + ", newLoc=") + newLoc) + ", case=") + toString(cheatCase)))
381354
382355
383356 let KS_SEPARATE_PUBLIC_KEY = false
384357
385358 let KS_ALLOW_BIG_INFRA_MERGE = false
386359
387360 let KS_ALLOW_ROBO_DUCKS = false
388361
389362 let DAY_MILLIS = 86400000
390363
391364 let chain = take(drop(this.bytes, 1), 1)
392365
393366 let pub = match chain {
394367 case _ =>
395368 if ((base58'2W' == $match0))
396369 then if (KS_SEPARATE_PUBLIC_KEY)
397370 then base58'CWsMtTZC5BjjoL4Q1ayW4Wwb1ehGACQB6DrKyPgotKfm'
398371 else base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
399372 else if ((base58'2T' == $match0))
400373 then base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
401374 else throw("Unknown chain")
402375 }
403376
404377 let usdtAssetId = match chain {
405378 case _ =>
406379 if ((base58'2W' == $match0))
407380 then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
408381 else if ((base58'2T' == $match0))
409382 then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63'
410383 else throw("Unknown chain")
411384 }
412385
413386 let defaultRestAddressStr = match chain {
414387 case _ =>
415388 if ((base58'2W' == $match0))
416389 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
417390 else if ((base58'2T' == $match0))
418391 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
419392 else throw("Unknown chain")
420393 }
421394
422395 let InfraUpgradeCostS = match chain {
423396 case _ =>
424397 if ((base58'2W' == $match0))
425398 then 10000000000
426399 else if ((base58'2T' == $match0))
427400 then 100000000
428401 else throw("Unknown chain")
429402 }
430403
431404 let arbitrageDelay = match chain {
432405 case _ =>
433406 if ((base58'2W' == $match0))
434407 then DAY_MILLIS
435408 else if ((base58'2T' == $match0))
436409 then 60000
437410 else throw("Unknown chain")
438411 }
439412
440413 let SEP = "__"
441414
442415 let MULT6 = 1000000
443416
444417 let MULT8 = 100000000
445418
446419 let SSIZE = 25
447420
448421 let MSIZE = 100
449422
450423 let LSIZE = 225
451424
452425 let XLSIZE = 400
453426
454427 let XXLSIZE = 625
455428
456429 let ITER6 = [0, 1, 2, 3, 4, 5]
457430
458431 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
459432
460433
461434 let IdxCfgStakingDapp = 1
462435
463436 let IdxCfgEconomyDapp = 2
464437
465438 let IdxCfgGovernanceDapp = 3
466439
467440 let IdxCfgWlgDapp = 4
468441
469442 let IdxCfgTournamentDapp = 7
470443
471444 let IdxCfgAcresDapp = 8
472445
473446 func keyRestCfg () = "%s__restConfig"
474447
475448
476449 func keyRestAddress () = "%s__restAddr"
477450
478451
479452 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
480453
481454
482455 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
483456
484457
485458 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
486459
487460 let restCfg = readRestCfgOrFail(restContract)
488461
489462 let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
490463
491464 let economyContract = getContractAddressOrFail(restCfg, IdxCfgEconomyDapp)
492465
493466 let govContract = getContractAddressOrFail(restCfg, IdxCfgGovernanceDapp)
494467
495468 let wlgContract = getContractAddressOrFail(restCfg, IdxCfgWlgDapp)
496469
497470 let tournamentContract = getContractAddressOrFail(restCfg, IdxCfgTournamentDapp)
498471
499472 let acresContract = getContractAddressOrFail(restCfg, IdxCfgAcresDapp)
500473
501474 let recLandNum = 0
502475
503476 let recLandSize = 1
504477
505478 let recTerrains = 2
506479
507480 let recContinent = 3
508481
509482 let wlgAssetIdKey = "wlg_assetId"
510483
511484 let wlgAssetId = valueOrErrorMessage(getBinary(wlgContract, wlgAssetIdKey), "WLGOLD is not issued yet")
512485
513486 let acresAssetIdKey = "acresAssetId"
514487
515488 let acresAssetId = valueOrErrorMessage(getBinary(acresContract, acresAssetIdKey), "ACRES is not issued yet")
516489
517490 let randomDelay = 2
518491
519492 func keyCommit (address) = ("finishBlockFor_" + address)
520493
521494
522495 func keyResProportions () = "resTypesProportions"
523496
524497
525498 func keyResTypesByContinent (continent) = ("resTypesByContinent_" + continent)
526499
527500
528501 func keyStakedLandsByOwner (ownerAddr) = ("stakedLandsByOwner_" + ownerAddr)
529502
530503
531504 func keyStakedPiecesByOwner (ownerAddr) = ("stakedPiecesByOwner_" + ownerAddr)
532505
533506
534507 func asString (v) = match v {
535508 case s: String =>
536509 s
537510 case _ =>
538511 throw("fail to cast into String")
539512 }
540513
541514
542515 func asInt (v) = match v {
543516 case n: Int =>
544517 n
545518 case _ =>
546519 throw("fail to cast into Int")
547520 }
548521
549522
550523 func asAnyList (v) = match v {
551524 case l: List[Any] =>
552525 l
553526 case _ =>
554527 throw("fail to cast into List[Any]")
555528 }
556529
557530
558531 func asBoolean (v) = match v {
559532 case s: Boolean =>
560533 s
561534 case _ =>
562535 throw("fail to cast into Boolean")
563536 }
564537
565538
566539 func numPiecesBySize (landSize) = match landSize {
567540 case _ =>
568541 if (("S" == $match0))
569542 then SSIZE
570543 else if (("M" == $match0))
571544 then MSIZE
572545 else if (("L" == $match0))
573546 then LSIZE
574547 else if (("XL" == $match0))
575548 then XLSIZE
576549 else if (("XXL" == $match0))
577550 then XXLSIZE
578551 else throw("Unknown land size")
579552 }
580553
581554
582555 func isDigit (s) = isDefined(parseInt(s))
583556
584557
585558 func keyBlocked () = "contractsBlocked"
586559
587560
588561 func keyLastTxIdByUser (addr) = ("lastTxIdByUser_" + addr)
589562
590563
591564 func fixedPoint (val,decimals) = {
592565 let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
593566 let lowPart = toString((val % tenPow))
594567 let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
595568 (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
596569 }
597570
598571
599572 func getRandomNumber (maxValue,salt,entropy) = if ((0 >= maxValue))
600573 then throw("maxValue should be > 0")
601574 else {
602575 let randomHash = sha256((salt + entropy))
603576 (toInt(randomHash) % maxValue)
604577 }
605578
606579
607580 let incubatorAddr = match chain {
608581 case _ =>
609582 if ((base58'2W' == $match0))
610583 then addressFromStringValue("3PEktVux2RhchSN63DsDo4b4mz4QqzKSeDv")
611584 else if ((base58'2T' == $match0))
612585 then this
613586 else throw("Unknown chain")
614587 }
615588
616589 let breederAddr = match chain {
617590 case _ =>
618591 if ((base58'2W' == $match0))
619592 then addressFromStringValue("3PDVuU45H7Eh5dmtNbnRNRStGwULA7NY6Hb")
620593 else if ((base58'2T' == $match0))
621594 then this
622595 else throw("Unknown chain")
623596 }
624597
625-let EMPTY_PROD50 = base64'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='
626-
627598 let FIVEMINUTESMILLIS = 300000
628599
629600 let RENAMINGCOST = 5000000
630601
631602 let MAXNAMELEN = 50
632603
633604 let InfraUpgradeCostSUsdt = 10000000
634605
635606 let EXPMATERIALS = match chain {
636607 case _ =>
637608 if ((base58'2W' == $match0))
638609 then 252289527462
639610 else if ((base58'2T' == $match0))
640611 then 2522895274
641612 else throw("Unknown chain")
642613 }
643614
644615 let EXPUSDT = match chain {
645616 case _ =>
646617 if ((base58'2W' == $match0))
647618 then 250000000
648619 else if ((base58'2T' == $match0))
649620 then 250000000
650621 else throw("Unknown chain")
651622 }
652623
653624 let ROBO_DUCK_USDT = 100000
654625
655626 let S_COST_ACRES = 2500000000
656627
657628 let FIVEX = toBigInt(5)
658629
659630 let TWENTYX = toBigInt(20)
660631
661632 let TWENTY2X = toBigInt((20 * 20))
662633
663634 let TWENTY3X = toBigInt(((20 * 20) * 20))
664635
665636 let TWENTY4X = toBigInt((((20 * 20) * 20) * 20))
666637
667638 let TWENTY5X = toBigInt(((((20 * 20) * 20) * 20) * 20))
668639
669640 let PRESALENUMLANDS = 500
670641
671642 func keyNextFreeLandNum () = "nextLandNum"
672643
673644
674645 func keyLandCustomNameToAssetId (name) = ("lcn_" + name)
675646
676647
677648 func keyLandToAssetId (landNum) = ("la_" + landNum)
678649
679650
680651 func keyInfraLevelByAssetIdAndOwner (assetId,ownerAddr) = ((("ilao_" + assetId) + "_") + ownerAddr)
681652
682653
683654 func keyLandNumToOwner (landNum) = ("lo_" + landNum)
684655
685656
686657 func keyDuckCustomNameToAssetId (name) = ("duckByCustomName_" + name)
687658
688659
689660 func keyCustomNameToAddress (name) = ("accountByCustomName_" + name)
690661
691662
692663 func keyOldies () = "oldiesList"
693664
694665
695666 func keyNextRoboDuck () = "nextRoboDuck"
696667
697668
698669 let claimModeWh = 0
699670
700671 let claimModeDuck = 1
701672
702673 let claimModeWhThenDuck = 2
703674
704675 let flHealth = 0
705676
706677 let flTimestamp = 5
707678
708679 let flBonus = 6
709680
710681 let flProdsUsed = 7
711682
683+let rlHealth = 0
684+
685+let rlProdsUsed = 1
686+
687+let rlType = 0
688+
689+let rlLastTx = 2
690+
691+let rlTimestamp = 3
692+
712693 func nftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
713694
714695
715696 func toVolume (amount,pkgSize) = {
716697 let pkgs = if ((amount >= 0))
717698 then (((amount + pkgSize) - 1) / pkgSize)
718699 else -((((-(amount) + pkgSize) - 1) / pkgSize))
719700 (pkgs * MULT8)
720701 }
721702
722703
723704 func distributeByWeights (total,weights) = {
724705 let sum = (((((weights[0] + weights[1]) + weights[2]) + weights[3]) + weights[4]) + weights[5])
725706 if ((0 >= sum))
726707 then throw("Zero weights sum")
727708 else {
728709 let norm6 = fraction(total, MULT6, sum)
729710 func normalizer (acc,elem) = (acc :+ fraction(elem, norm6, MULT6))
730711
731712 let $l = weights
732713 let $s = size($l)
733714 let $acc0 = nil
734715 func $f0_1 ($a,$i) = if (($i >= $s))
735716 then $a
736717 else normalizer($a, $l[$i])
737718
738719 func $f0_2 ($a,$i) = if (($i >= $s))
739720 then $a
740721 else throw("List size exceeds 6")
741722
742723 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
743724 }
744725 }
745726
746727
747728 func getNeededMaterials (total) = {
748729 let props = split(value(getString(keyResProportions())), "_")
749730 if ((size(props) != NUMRES))
750731 then throw("Wrong proportions data")
751732 else {
752733 let r = [parseIntValue(props[0]), parseIntValue(props[1]), parseIntValue(props[2]), parseIntValue(props[3]), parseIntValue(props[4]), parseIntValue(props[5])]
753734 distributeByWeights(total, r)
754735 }
755736 }
756737
757738
758739 func subtractMaterials (shouldUseMat,has,totalNeed) = {
759740 let need = getNeededMaterials(totalNeed)
760741 func subtractor (acc,idx) = {
761742 let result = (parseIntValue(has[idx]) - need[idx])
762743 if ((0 > result))
763744 then throw(((((("Not enough material idx=" + toString(idx)) + ", you have ") + has[idx]) + ", but need ") + toString(need[idx])))
764745 else (acc :+ toString(result))
765746 }
766747
767748 if (shouldUseMat)
768749 then {
769750 let $l = ITER6
770751 let $s = size($l)
771752 let $acc0 = nil
772753 func $f0_1 ($a,$i) = if (($i >= $s))
773754 then $a
774755 else subtractor($a, $l[$i])
775756
776757 func $f0_2 ($a,$i) = if (($i >= $s))
777758 then $a
778759 else throw("List size exceeds 6")
779760
780761 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
781762 }
782763 else has
783764 }
784765
785766
786767 func subtractEquipment (oldEq,pUsed) = if ((pUsed == ""))
787- then $Tuple2(oldEq, false)
768+ then $Tuple3(oldEq, false, false)
788769 else {
789770 func subUsed (acc,idxAmt) = {
790771 let parts = split(idxAmt, ",")
791772 if ((size(parts) != 2))
792773 then throw("Incorrect format, should be index,amount")
793774 else {
794775 let idx = parseIntValue(parts[0])
795776 if (if ((0 > idx))
796777 then true
797778 else (idx >= size(productionMatrix)))
798779 then throw("Unknown product idx")
799780 else {
800781 let amt = parseIntValue(parts[1])
801782 let eqParts = split(acc._1, (parts[0] + ":"))
802783 if ((size(eqParts) != 2))
803784 then throw((("You don't have " + prodTypes[idx]) + " equipped"))
804785 else {
805786 let tmp = eqParts[1]
806787 let numLen = if (isDigit(take(drop(tmp, 1), 1)))
807788 then 2
808789 else 1
809790 let curr = parseIntValue(take(tmp, numLen))
810791 let tail = drop(tmp, numLen)
811792 let newAmt = if ((curr >= amt))
812793 then (curr - amt)
813794 else throw(((((("You equipped " + toString(curr)) + " of ") + prodTypes[idx]) + ", but tried to use ") + toString(amt)))
814- $Tuple2(((((eqParts[0] + parts[0]) + ":") + toString(newAmt)) + tail), if (acc._2)
795+ $Tuple3(((((eqParts[0] + parts[0]) + ":") + toString(newAmt)) + tail), if (acc._2)
815796 then true
816797 else if (if ((idx >= 6))
817798 then (8 >= idx)
818799 else false)
819800 then (newAmt == 0)
801+ else false, if (acc._3)
802+ then true
803+ else if (if ((idx >= 3))
804+ then (5 >= idx)
805+ else false)
806+ then (amt > 0)
820807 else false)
821808 }
822809 }
823810 }
824811 }
825812
826813 let $l = split(pUsed, "_")
827814 let $s = size($l)
828- let $acc0 = $Tuple2(oldEq, false)
815+ let $acc0 = $Tuple3(oldEq, false, false)
829816 func $f0_1 ($a,$i) = if (($i >= $s))
830817 then $a
831818 else subUsed($a, $l[$i])
832819
833820 func $f0_2 ($a,$i) = if (($i >= $s))
834821 then $a
835822 else throw("List size exceeds 10")
836823
837824 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
838825 }
839826
840827
841828 func prodStrToBytes (prodStr) = {
842829 let pList = if ((prodStr == ""))
843830 then nil
844831 else split_4C(prodStr, "_")
845832 func toBV (acc,recipe) = {
846833 let j = (size(acc) / 8)
847834 let curr = if ((size(pList) > j))
848835 then parseIntValue(pList[j])
849836 else 0
850837 (acc + toBytes(curr))
851838 }
852839
853840 let $l = productionMatrix
854841 let $s = size($l)
855842 let $acc0 = base58''
856843 func $f0_1 ($a,$i) = if (($i >= $s))
857844 then $a
858845 else toBV($a, $l[$i])
859846
860847 func $f0_2 ($a,$i) = if (($i >= $s))
861848 then $a
862849 else throw("List size exceeds 50")
863850
864851 $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)
865852 }
866853
867854
868855 func bytesToProdStr (bv) = {
869856 func fromBV (acc,recipe) = {
870857 let j = size(acc)
871858 let b = take(drop(bv, (8 * j)), 8)
872859 (acc :+ toString(toInt(b)))
873860 }
874861
875862 makeString_2C({
876863 let $l = productionMatrix
877864 let $s = size($l)
878865 let $acc0 = nil
879866 func $f0_1 ($a,$i) = if (($i >= $s))
880867 then $a
881868 else fromBV($a, $l[$i])
882869
883870 func $f0_2 ($a,$i) = if (($i >= $s))
884871 then $a
885872 else throw("List size exceeds 50")
886873
887874 $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)
888875 }, "_")
889876 }
890877
891878
892879 func checkStatRequirements (duckStats,reqs) = {
893880 func check (acc,j) = {
894881 let buff = if ((size(duckStats) > (7 + j)))
895882 then duckStats[(7 + j)]
896883 else 0
897884 if ((parseIntValue(reqs[j]) > (duckStats[j] + buff)))
898885 then throw(("Requirement not satisfied: " + requirements[j]))
899886 else true
900887 }
901888
902889 let $l = [0, 1, 2, 3, 4, 5, 6]
903890 let $s = size($l)
904891 let $acc0 = false
905892 func $f0_1 ($a,$i) = if (($i >= $s))
906893 then $a
907894 else check($a, $l[$i])
908895
909896 func $f0_2 ($a,$i) = if (($i >= $s))
910897 then $a
911898 else throw("List size exceeds 7")
912899
913900 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
914- }
915-
916-
917-func placeProdB (idxCnt,pList,isPositive,duckStats,occupied,free) = {
918- let parts = split(idxCnt, ":")
919- if ((size(parts) != 2))
920- then throw("Incorrect format, should be index:amount")
921- else if (if (!(isPositive))
922- then (size(parts[0]) != 2)
923- else false)
924- then throw("Product idx should be 2 digits, zero padded")
925- else {
926- let productIdx = parseIntValue(parts[0])
927- let count = parseIntValue(parts[1])
928- if (!(containsElement(fortAllowedProds, productIdx)))
929- then throw((("Product '" + prodTypes[productIdx]) + "' cannot be used for land defense"))
930- else if ((0 > count))
931- then throw("Count can't be negative")
932- else if ((count > MAXPRODINSLOT))
933- then throw(((("Can't put more than " + toString(MAXPRODINSLOT)) + " of ") + prodTypes[productIdx]))
934- else if ((count == 0))
935- then $Tuple3(pList, occupied, free)
936- else {
937- let head = take(pList, (8 * productIdx))
938- let curr = toInt(take(drop(pList, (8 * productIdx)), 8))
939- let tail = drop(pList, (8 * (productIdx + 1)))
940- let recipe = split(productionMatrix[productIdx], "_")
941- if (if (!(isPositive))
942- then (count > curr)
943- else false)
944- then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[productIdx]) + ", but tried to use ") + toString(count)))
945- else {
946- let newAmt = if (if (!(isPositive))
947- then checkStatRequirements(duckStats, split(recipe[rIdxRequirements], ","))
948- else false)
949- then (curr - count)
950- else (curr + count)
951- let deltaVol = (toVolume(newAmt, PRODUCTPKGSIZE) - toVolume(curr, PRODUCTPKGSIZE))
952- $Tuple3(((head + toBytes(newAmt)) + tail), (occupied + deltaVol), (free - deltaVol))
953- }
954- }
955- }
956901 }
957902
958903
959904 func addProdB (idxCnt,pList,isPositive,segment,mainAux,slot,duckStats) = {
960905 let parts = split(idxCnt, ":")
961906 if ((size(parts) != 2))
962907 then throw("Incorrect format, should be index:amount")
963908 else if (if (!(isPositive))
964909 then (size(parts[0]) != 2)
965910 else false)
966911 then throw("Product idx should be 2 digits, zero padded")
967912 else {
968913 let productIdx = parseIntValue(parts[0])
969914 let count = parseIntValue(parts[1])
970915 if (if ((0 > productIdx))
971916 then true
972917 else (productIdx >= size(productionMatrix)))
973918 then throw("Unknown product idx")
974919 else if ((0 > count))
975920 then throw("Count can't be negative")
976921 else if ((count > MAXPRODINSLOT))
977922 then throw(((("Can't put more than " + toString(MAXPRODINSLOT)) + " of ") + prodTypes[productIdx]))
978923 else if ((count == 0))
979924 then $Tuple2(pList, false)
980925 else {
981926 let head = take(pList, (8 * productIdx))
982927 let curr = toInt(take(drop(pList, (8 * productIdx)), 8))
983928 let tail = drop(pList, (8 * (productIdx + 1)))
984929 let recipe = split(productionMatrix[productIdx], "_")
985930 if (if (!(isPositive))
986931 then (count > curr)
987932 else false)
988933 then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[productIdx]) + ", but tried to use ") + toString(count)))
989934 else {
990935 let isBigItem = if (if (!(isPositive))
991936 then checkStatRequirements(duckStats, split(recipe[rIdxRequirements], ","))
992937 else false)
993938 then {
994939 let compat = recipe[rIdxSlots]
995940 if ((compat == ""))
996941 then throw("Item cannot be equipped")
997942 else {
998943 let c = parseIntValue(compat)
999944 let cSeg = (c / 100)
1000945 if ((segment != cSeg))
1001946 then throw("Segment incompatible")
1002947 else {
1003948 let cMainAux = ((c % 100) / 10)
1004949 if ((mainAux != cMainAux))
1005950 then throw("Slot incompatible")
1006951 else {
1007952 let cNumSlots = (c % 10)
1008953 if (if ((slot != 0))
1009954 then (cNumSlots > 1)
1010955 else false)
1011956 then throw("Big items should occupy slot 0")
1012957 else (cNumSlots > 1)
1013958 }
1014959 }
1015960 }
1016961 }
1017962 else false
1018963 $Tuple2(((head + toBytes((curr + (if (isPositive)
1019964 then count
1020965 else -(count))))) + tail), isBigItem)
1021966 }
1022967 }
1023968 }
1024969 }
1025970
1026971
1027972 func slotsGroupB (g,bpIn,isPositive,segment,mainAux,stats) = if ((g != ""))
1028973 then {
1029974 let slots = split(g, ",")
1030975 if ((size(slots) > MAXSLOTS))
1031976 then throw("Wrong slots format")
1032977 else {
1033978 let s0 = slots[0]
1034979 let s1 = if ((size(slots) > 1))
1035980 then slots[1]
1036981 else ""
1037982 if (if ((s0 == ""))
1038983 then (s1 == "")
1039984 else false)
1040985 then bpIn
1041986 else {
1042987 let tmpS0 = if ((s0 != ""))
1043988 then addProdB(s0, bpIn, isPositive, segment, mainAux, 0, stats)
1044989 else $Tuple2(bpIn, false)
1045990 if ((s1 != ""))
1046991 then if (tmpS0._2)
1047992 then throw("Big item already occupies slot")
1048993 else addProdB(s1, tmpS0._1, isPositive, segment, mainAux, 1, stats)._1
1049994 else tmpS0._1
1050995 }
1051996 }
1052997 }
1053998 else bpIn
1054999
10551000
10561001 func dressB (segList,pBytes,isPositive,stats) = {
10571002 func segment (acc,seg) = {
10581003 let j = acc._1
10591004 let mainAux = split(seg, ";")
10601005 if ((size(mainAux) != NUMMAINAUX))
10611006 then throw("Wrong segment format")
10621007 else {
10631008 let m = mainAux[0]
10641009 let a = mainAux[1]
10651010 if (if ((m == ""))
10661011 then (a == "")
10671012 else false)
10681013 then $Tuple2((j + 1), acc._2)
10691014 else {
10701015 let tmpM = slotsGroupB(m, acc._2, isPositive, j, 0, stats)
10711016 $Tuple2((j + 1), slotsGroupB(a, tmpM, isPositive, j, 1, stats))
10721017 }
10731018 }
10741019 }
10751020
10761021 ( let $l = segList
10771022 let $s = size($l)
10781023 let $acc0 = $Tuple2(0, pBytes)
10791024 func $f0_1 ($a,$i) = if (($i >= $s))
10801025 then $a
10811026 else segment($a, $l[$i])
10821027
10831028 func $f0_2 ($a,$i) = if (($i >= $s))
10841029 then $a
10851030 else throw("List size exceeds 6")
10861031
10871032 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6))._2
10881033 }
10891034
10901035
1091-func fortB (segList,pBytes,occupied,free,isPositive,duckStats) = if ((3 > size(segList)))
1092- then throw("At least duck, mines and traps parts are required")
1093- else {
1094- func segment (acc,seg) = {
1095- let j = acc._1
1096- if ((j == 0))
1097- then $Tuple4((j + 1), acc._2, acc._3, acc._4)
1098- else {
1099- let p = placeProdB(seg, acc._2, isPositive, duckStats, acc._3, acc._4)
1100- $Tuple4((j + 1), p._1, p._2, p._3)
1101- }
1102- }
1103-
1104- let t = {
1105- let $l = segList
1106- let $s = size($l)
1107- let $acc0 = $Tuple4(0, pBytes, occupied, free)
1108- func $f0_1 ($a,$i) = if (($i >= $s))
1109- then $a
1110- else segment($a, $l[$i])
1111-
1112- func $f0_2 ($a,$i) = if (($i >= $s))
1113- then $a
1114- else throw("List size exceeds 10")
1115-
1116- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
1117- }
1118- $Tuple3(t._2, t._3, t._4)
1119- }
1120-
1121-
11221036 func canWearCurrentEquipment (duckAssetId) = {
11231037 let eqKey = keyDuckEquipment(duckAssetId)
11241038 let currEq = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
1039+ let EMPTY_PROD50 = base64'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='
11251040 let tempProdB = dressB(currEq, EMPTY_PROD50, true, nil)
11261041 let segBpAux = split(currEq[segBackpack], ";")[1]
11271042 let buffEffect = if ((segBpAux == ""))
11281043 then 0
11291044 else {
11301045 let aux0 = split(segBpAux, ",")[0]
11311046 if ((aux0 == ""))
11321047 then 0
11331048 else {
11341049 let idxCnt = split(aux0, ":")
11351050 let idx = idxCnt[0]
11361051 let cnt = idxCnt[1]
11371052 if (if (if (if (if ((idx == "06"))
11381053 then true
11391054 else (idx == "07"))
11401055 then true
11411056 else (idx == "08"))
11421057 then (cnt != "")
11431058 else false)
11441059 then (parseIntValue(cnt) > 0)
11451060 else false)
11461061 then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
11471062 else 0
11481063 }
11491064 }
11501065 let stats = getDuckStats(this, duckAssetId, buffEffect, true)
11511066 let newProdB = dressB(currEq, tempProdB, false, stats)
11521067 (newProdB == newProdB)
11531068 }
11541069
11551070
11561071 func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
11571072 then throw("Wrong proportions data")
11581073 else {
11591074 func updater (acc,i) = {
11601075 let result = (parseIntValue(propList[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
11611076 if ((0 > result))
11621077 then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
11631078 else (acc :+ toString(result))
11641079 }
11651080
11661081 let $l = ITER6
11671082 let $s = size($l)
11681083 let $acc0 = nil
11691084 func $f0_1 ($a,$i) = if (($i >= $s))
11701085 then $a
11711086 else updater($a, $l[$i])
11721087
11731088 func $f0_2 ($a,$i) = if (($i >= $s))
11741089 then $a
11751090 else throw("List size exceeds 6")
11761091
11771092 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
11781093 }
11791094
11801095
11811096 func updateProportions (terrainCounts,landSizeIndex,sign) = {
11821097 let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
11831098 makeString(updateProportionsInternal(propList, terrainCounts, landSizeIndex, sign), "_")
11841099 }
11851100
11861101
11871102 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)]
11881103
11891104
11901105 func addRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
11911106 func adder (acc,i) = {
11921107 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
11931108 (acc :+ toString((parseIntValue(currentRes[i]) + resOfType)))
11941109 }
11951110
11961111 let r = {
11971112 let $l = ITER6
11981113 let $s = size($l)
11991114 let $acc0 = nil
12001115 func $f0_1 ($a,$i) = if (($i >= $s))
12011116 then $a
12021117 else adder($a, $l[$i])
12031118
12041119 func $f0_2 ($a,$i) = if (($i >= $s))
12051120 then $a
12061121 else throw("List size exceeds 6")
12071122
12081123 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12091124 }
12101125 makeString(r, "_")
12111126 }
12121127
12131128
12141129 func virtClaim (terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
12151130 func adder (acc,i) = {
12161131 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
12171132 $Tuple2((acc._1 :+ resOfType), (acc._2 + resOfType))
12181133 }
12191134
12201135 let $l = ITER6
12211136 let $s = size($l)
12221137 let $acc0 = $Tuple2(nil, 0)
12231138 func $f0_1 ($a,$i) = if (($i >= $s))
12241139 then $a
12251140 else adder($a, $l[$i])
12261141
12271142 func $f0_2 ($a,$i) = if (($i >= $s))
12281143 then $a
12291144 else throw("List size exceeds 6")
12301145
12311146 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12321147 }
12331148
12341149
12351150 func distributeRes (currentWhRes,currentPackRes,resToClaim,whSpaceLeft) = {
12361151 let resListToClaim = resToClaim._1
12371152 let resAmToClaim = resToClaim._2
12381153 if ((resAmToClaim == 0))
12391154 then $Tuple2(makeString(currentWhRes, "_"), makeString(currentPackRes, "_"))
12401155 else if ((whSpaceLeft >= resAmToClaim))
12411156 then {
12421157 func addLists (acc,i) = (acc :+ toString((parseIntValue(currentWhRes[i]) + resListToClaim[i])))
12431158
12441159 let r = {
12451160 let $l = ITER6
12461161 let $s = size($l)
12471162 let $acc0 = nil
12481163 func $f0_1 ($a,$i) = if (($i >= $s))
12491164 then $a
12501165 else addLists($a, $l[$i])
12511166
12521167 func $f0_2 ($a,$i) = if (($i >= $s))
12531168 then $a
12541169 else throw("List size exceeds 6")
12551170
12561171 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12571172 }
12581173 $Tuple2(makeString(r, "_"), makeString(currentPackRes, "_"))
12591174 }
12601175 else {
12611176 func addPartLists (acc,i) = {
12621177 let whPart = fraction(resListToClaim[i], whSpaceLeft, resAmToClaim)
12631178 $Tuple2((acc._1 :+ toString((parseIntValue(currentWhRes[i]) + whPart))), (acc._2 :+ toString(((parseIntValue(currentPackRes[i]) + resListToClaim[i]) - whPart))))
12641179 }
12651180
12661181 let r = {
12671182 let $l = ITER6
12681183 let $s = size($l)
12691184 let $acc0 = $Tuple2(nil, nil)
12701185 func $f0_1 ($a,$i) = if (($i >= $s))
12711186 then $a
12721187 else addPartLists($a, $l[$i])
12731188
12741189 func $f0_2 ($a,$i) = if (($i >= $s))
12751190 then $a
12761191 else throw("List size exceeds 6")
12771192
12781193 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12791194 }
12801195 $Tuple2(makeString(r._1, "_"), makeString(r._2, "_"))
12811196 }
12821197 }
12831198
12841199
12851200 func abs (x) = if ((x >= toBigInt(0)))
12861201 then x
12871202 else -(x)
12881203
12891204
12901205 let freq = [[6, 9, 14, 15, 16], [5, 8, 13, 14, 15], [1, 4, 9, 10, 15], [1, 6, 7, 15, 19], [4, 7, 8, 13, 18]]
12911206
12921207 func genChar (n,freqs) = {
12931208 let rem = toInt((n % TWENTYX))
12941209 let letter = if ((freqs[0] > rem))
12951210 then "A"
12961211 else if ((freqs[1] > rem))
12971212 then "B"
12981213 else if ((freqs[2] > rem))
12991214 then "C"
13001215 else if ((freqs[3] > rem))
13011216 then "D"
13021217 else if ((freqs[4] > rem))
13031218 then "E"
13041219 else "F"
13051220 letter
13061221 }
13071222
13081223
13091224 func genTerrains (seed,continentIdx) = {
13101225 let f = freq[continentIdx]
13111226 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))
13121227
13131228 let t = {
13141229 let $l = [1, 2, 3, 4, 5]
13151230 let $s = size($l)
13161231 let $acc0 = $Tuple2("", (seed / FIVEX))
13171232 func $f0_1 ($a,$i) = if (($i >= $s))
13181233 then $a
13191234 else terrainGenerator($a, $l[$i])
13201235
13211236 func $f0_2 ($a,$i) = if (($i >= $s))
13221237 then $a
13231238 else throw("List size exceeds 5")
13241239
13251240 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
13261241 }
13271242 t._1
13281243 }
13291244
13301245
13311246 let PERM25 = [7, 2, 15, 19, 8, 24, 1, 21, 16, 5, 0, 22, 20, 23, 11, 4, 18, 12, 6, 10, 3, 17, 13, 9, 14]
13321247
13331248 let TCHARS = ["A", "B", "C", "D", "E", "F"]
13341249
13351250 func genTerrainsForMerge (sumTerrains,landSizeIndex) = {
13361251 func step1 (acc,s) = {
13371252 let j = acc._2
13381253 let el = parseIntValue(s)
13391254 let x = if ((el == 0))
13401255 then 0
13411256 else if ((el >= (4 * landSizeIndex)))
13421257 then (el / landSizeIndex)
13431258 else if ((el > (3 * landSizeIndex)))
13441259 then 3
13451260 else (((el - 1) / landSizeIndex) + 1)
13461261 $Tuple3((acc._1 :+ x), (acc._2 + 1), (acc._3 + x))
13471262 }
13481263
13491264 let t = {
13501265 let $l = sumTerrains
13511266 let $s = size($l)
13521267 let $acc0 = $Tuple3(nil, 0, 0)
13531268 func $f0_1 ($a,$i) = if (($i >= $s))
13541269 then $a
13551270 else step1($a, $l[$i])
13561271
13571272 func $f0_2 ($a,$i) = if (($i >= $s))
13581273 then $a
13591274 else throw("List size exceeds 6")
13601275
13611276 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
13621277 }
13631278 let arr = t._1
13641279 let maxIdx = value(indexOf(arr, max(arr)))
13651280 let delta = (t._3 - 25)
13661281 func subber (acc,idx) = {
13671282 let val = if ((idx == maxIdx))
13681283 then (arr[idx] - delta)
13691284 else arr[idx]
13701285 let zeroes = if ((val == 0))
13711286 then nil
13721287 else split(drop(toString(pow(10, 0, val, 0, 0, DOWN)), 1), "")
13731288 let c = TCHARS[idx]
13741289 func listGen (ac,ignored) = (ac :+ c)
13751290
13761291 let z = {
13771292 let $l = zeroes
13781293 let $s = size($l)
13791294 let $acc0 = nil
13801295 func $f1_1 ($a,$i) = if (($i >= $s))
13811296 then $a
13821297 else listGen($a, $l[$i])
13831298
13841299 func $f1_2 ($a,$i) = if (($i >= $s))
13851300 then $a
13861301 else throw("List size exceeds 25")
13871302
13881303 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25)
13891304 }
13901305 (acc ++ z)
13911306 }
13921307
13931308 let r = {
13941309 let $l = ITER6
13951310 let $s = size($l)
13961311 let $acc0 = nil
13971312 func $f1_1 ($a,$i) = if (($i >= $s))
13981313 then $a
13991314 else subber($a, $l[$i])
14001315
14011316 func $f1_2 ($a,$i) = if (($i >= $s))
14021317 then $a
14031318 else throw("List size exceeds 6")
14041319
14051320 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
14061321 }
14071322 func permut (acc,j) = (acc + r[j])
14081323
14091324 let $l = PERM25
14101325 let $s = size($l)
14111326 let $acc0 = ""
14121327 func $f2_1 ($a,$i) = if (($i >= $s))
14131328 then $a
14141329 else permut($a, $l[$i])
14151330
14161331 func $f2_2 ($a,$i) = if (($i >= $s))
14171332 then $a
14181333 else throw("List size exceeds 25")
14191334
14201335 $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25)
14211336 }
14221337
14231338
14241339 func getBackpack (bpKey) = {
14251340 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
14261341 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
14271342 then p[bpIdxRes]
14281343 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
14291344 then p[bpIdxMat]
14301345 else "0_0_0_0_0_0", p[bpIdxProd]]
14311346 }
14321347
14331348
14341349 func getWarehouseTotalVolume (volPrefix) = {
14351350 let parts = split(volPrefix, "_")
14361351 ((WHMULTIPLIER * (parseIntValue(parts[1]) + 1)) * parseIntValue(parts[0]))
14371352 }
14381353
14391354
14401355 func getWarehouseOccupiedVol (currentWh) = {
14411356 let goods = currentWh[whIdxProd]
14421357 func sumResMat (acc,item) = (acc + parseIntValue(item))
14431358
14441359 func sumProd (acc,item) = {
14451360 let idx = acc._1
14461361 let pkgs = (((parseIntValue(item) + PRODUCTPKGSIZE) - 1) / PRODUCTPKGSIZE)
14471362 $Tuple2((idx + 1), (acc._2 + (pkgs * MULT8)))
14481363 }
14491364
14501365 let whResVol = {
14511366 let $l = split(currentWh[whIdxRes], "_")
14521367 let $s = size($l)
14531368 let $acc0 = 0
14541369 func $f0_1 ($a,$i) = if (($i >= $s))
14551370 then $a
14561371 else sumResMat($a, $l[$i])
14571372
14581373 func $f0_2 ($a,$i) = if (($i >= $s))
14591374 then $a
14601375 else throw("List size exceeds 6")
14611376
14621377 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
14631378 }
14641379 let whMatVol = {
14651380 let $l = split(currentWh[whIdxMat], "_")
14661381 let $s = size($l)
14671382 let $acc0 = 0
14681383 func $f1_1 ($a,$i) = if (($i >= $s))
14691384 then $a
14701385 else sumResMat($a, $l[$i])
14711386
14721387 func $f1_2 ($a,$i) = if (($i >= $s))
14731388 then $a
14741389 else throw("List size exceeds 6")
14751390
14761391 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
14771392 }
14781393 let whGoodsVol = if ((goods == ""))
14791394 then 0
14801395 else ( let $l = split_4C(goods, "_")
14811396 let $s = size($l)
14821397 let $acc0 = $Tuple2(0, 0)
14831398 func $f2_1 ($a,$i) = if (($i >= $s))
14841399 then $a
14851400 else sumProd($a, $l[$i])
14861401
14871402 func $f2_2 ($a,$i) = if (($i >= $s))
14881403 then $a
14891404 else throw("List size exceeds 50")
14901405
14911406 $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50))._2
14921407 ((whResVol + whMatVol) + whGoodsVol)
14931408 }
14941409
14951410
14961411 func getWarehouse (whKey,landIndex,infraLevel) = {
14971412 let volPrefix = ((toString(landIndex) + "_") + toString(infraLevel))
14981413 let whTotal = getWarehouseTotalVolume(volPrefix)
14991414 let whStr = valueOrElse(getString(whKey), (volPrefix + ":0_0_0_0_0_0:0_0_0_0_0_0::0"))
15001415 let wh = split_4C(whStr, ":")
15011416 let whOccupied = getWarehouseOccupiedVol(wh)
15021417 let whLoft = if ((5 > size(wh)))
15031418 then makeString(["0", toString(whOccupied), toString((whTotal - whOccupied)), toString(whTotal)], "_")
15041419 else {
15051420 let loft = split(wh[whIdxLOFT], "_")
15061421 let whLocked = parseIntValue(loft[volLocked])
15071422 let occ = if ((size(loft) > 1))
15081423 then parseIntValue(loft[volOccupied])
15091424 else whOccupied
15101425 makeString([toString(whLocked), toString(occ), toString(((whTotal - whLocked) - occ)), toString(whTotal)], "_")
15111426 }
15121427 [wh[whIdxLevels], if ((size(split(wh[whIdxRes], "_")) == NUMRES))
15131428 then wh[whIdxRes]
15141429 else "0_0_0_0_0_0", if ((size(split(wh[whIdxMat], "_")) == NUMRES))
15151430 then wh[whIdxMat]
15161431 else "0_0_0_0_0_0", wh[whIdxProd], whLoft]
15171432 }
15181433
15191434
15201435 func getWarehouseSpaceLeft (currentWh) = {
15211436 let occupiedVol = getWarehouseOccupiedVol(currentWh)
15221437 let currWhLockedVol = parseIntValue(split(currentWh[whIdxLOFT], "_")[volLocked])
15231438 ((getWarehouseTotalVolume(currentWh[whIdxLevels]) - occupiedVol) - currWhLockedVol)
15241439 }
15251440
15261441
15271442 func moveStuff (cargoParts,currentWh,currentPack) = if ((size(cargoParts) != 3))
15281443 then throw("cargoListStr should contain exactly 2 ':' separators")
15291444 else {
15301445 let resParts = split(cargoParts[0], "_")
15311446 let matParts = split(cargoParts[1], "_")
15321447 let prodParts = if ((cargoParts[2] == ""))
15331448 then nil
15341449 else split_4C(cargoParts[2], "_")
15351450 if ((size(resParts) != NUMRES))
15361451 then throw("All 6 resources should be passed")
15371452 else if ((size(matParts) != NUMRES))
15381453 then throw("All 6 materials should be passed")
15391454 else {
15401455 let whSpaceLeft = getWarehouseSpaceLeft(currentWh)
15411456 let currWhRes = split(currentWh[whIdxRes], "_")
15421457 let currWhMat = split(currentWh[whIdxMat], "_")
15431458 let currWhProd = if ((currentWh[whIdxProd] == ""))
15441459 then nil
15451460 else split_4C(currentWh[whIdxProd], "_")
15461461 let currentPackRes = split(currentPack[bpIdxRes], "_")
15471462 let currentPackMat = split(currentPack[bpIdxMat], "_")
15481463 let currentPackProd = if ((currentPack[bpIdxProd] == ""))
15491464 then nil
15501465 else split_4C(currentPack[bpIdxProd], "_")
15511466 func mvR (acc,item) = {
15521467 let i = acc._1
15531468 let am = parseIntValue(item)
15541469 let whr = parseIntValue(currWhRes[i])
15551470 let bpr = parseIntValue(currentPackRes[i])
15561471 if ((am == 0))
15571472 then $Tuple4((i + 1), (acc._2 :+ currWhRes[i]), (acc._3 :+ currentPackRes[i]), acc._4)
15581473 else if ((am > 0))
15591474 then if ((am > bpr))
15601475 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpr)) + " available"))
15611476 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
15621477 else if ((-(am) > whr))
15631478 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whr)) + " available"))
15641479 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
15651480 }
15661481
15671482 let r = {
15681483 let $l = resParts
15691484 let $s = size($l)
15701485 let $acc0 = $Tuple4(0, nil, nil, 0)
15711486 func $f0_1 ($a,$i) = if (($i >= $s))
15721487 then $a
15731488 else mvR($a, $l[$i])
15741489
15751490 func $f0_2 ($a,$i) = if (($i >= $s))
15761491 then $a
15771492 else throw("List size exceeds 6")
15781493
15791494 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
15801495 }
15811496 func mvM (acc,item) = {
15821497 let i = acc._1
15831498 let am = parseIntValue(item)
15841499 let whm = parseIntValue(currWhMat[i])
15851500 let bpm = parseIntValue(currentPackMat[i])
15861501 if ((am == 0))
15871502 then $Tuple4((i + 1), (acc._2 :+ currWhMat[i]), (acc._3 :+ currentPackMat[i]), acc._4)
15881503 else if ((am > 0))
15891504 then if ((am > bpm))
15901505 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpm)) + " available"))
15911506 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
15921507 else if ((-(am) > whm))
15931508 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whm)) + " available"))
15941509 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
15951510 }
15961511
15971512 let m = {
15981513 let $l = matParts
15991514 let $s = size($l)
16001515 let $acc0 = $Tuple4(0, nil, nil, r._4)
16011516 func $f1_1 ($a,$i) = if (($i >= $s))
16021517 then $a
16031518 else mvM($a, $l[$i])
16041519
16051520 func $f1_2 ($a,$i) = if (($i >= $s))
16061521 then $a
16071522 else throw("List size exceeds 6")
16081523
16091524 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
16101525 }
16111526 func mvP (acc,item) = {
16121527 let i = acc._1
16131528 let am = parseIntValue(item)
16141529 let whp = if ((size(currWhProd) > i))
16151530 then parseIntValue(currWhProd[i])
16161531 else 0
16171532 let bpp = if ((size(currentPackProd) > i))
16181533 then parseIntValue(currentPackProd[i])
16191534 else 0
16201535 if ((am == 0))
16211536 then $Tuple4((i + 1), (acc._2 :+ toString(whp)), (acc._3 :+ toString(bpp)), acc._4)
16221537 else if ((am > 0))
16231538 then if ((am > bpp))
16241539 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpp)) + " available"))
16251540 else {
16261541 let deltaVol = (toVolume((whp + am), PRODUCTPKGSIZE) - toVolume(whp, PRODUCTPKGSIZE))
16271542 $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
16281543 }
16291544 else if ((-(am) > whp))
16301545 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whp)) + " available"))
16311546 else {
16321547 let deltaVol = (toVolume((whp + am), PRODUCTPKGSIZE) - toVolume(whp, PRODUCTPKGSIZE))
16331548 $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
16341549 }
16351550 }
16361551
16371552 let p = if ((size(prodParts) != 0))
16381553 then {
16391554 let $l = prodParts
16401555 let $s = size($l)
16411556 let $acc0 = $Tuple4(0, nil, nil, m._4)
16421557 func $f2_1 ($a,$i) = if (($i >= $s))
16431558 then $a
16441559 else mvP($a, $l[$i])
16451560
16461561 func $f2_2 ($a,$i) = if (($i >= $s))
16471562 then $a
16481563 else throw("List size exceeds 50")
16491564
16501565 $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)
16511566 }
16521567 else $Tuple4(0, currWhProd, currentPackProd, m._4)
16531568 let volSaldo = p._4
16541569 if ((volSaldo > whSpaceLeft))
16551570 then throw((((("Attempt to put total " + toString(volSaldo)) + " stuff, but only ") + toString(whSpaceLeft)) + " warehouse space left"))
16561571 else $Tuple7(makeString(r._2, "_"), makeString(m._2, "_"), makeString_2C(p._2, "_"), makeString(r._3, "_"), makeString(m._3, "_"), makeString_2C(p._3, "_"), volSaldo)
16571572 }
16581573 }
16591574
16601575
16611576 func expeditionInternal (caller,txId) = {
16621577 let userAddr = toString(caller)
16631578 let bigNum = abs(toBigInt(txId))
16641579 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
16651580 let landNum = toString(freeNum)
16661581 let continentIdx = toInt((bigNum % FIVEX))
16671582 let terrains = genTerrains(bigNum, continentIdx)
16681583 let continent = continents[continentIdx]
16691584 let issue = Issue(nftName(landNum, "S"), makeString([landNum, "S", terrains, continent], "_"), 1, 0, false)
16701585 let assetId = calculateAssetId(issue)
16711586 let id = toBase58String(assetId)
16721587 $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))
16731588 }
16741589
16751590
16761591 func flightCommon (userAddr,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
16771592 then throw("signature does not match")
16781593 else {
16791594 let parts = split_4C(toUtf8String(message), ";")
16801595 let flightLog = split_4C(parts[0], "|")
16811596 let hp = split(flightLog[flHealth], "_")
16821597 let curHP = parseIntValue(hp[0])
16831598 let newHP = parseIntValue(hp[1])
16841599 let newLocTxVer = split(parts[1], ":")
16851600 let newLocation = newLocTxVer[0]
16861601 let time = parseIntValue(flightLog[flTimestamp])
16871602 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
16881603 then true
16891604 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
16901605 then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
16911606 else {
16921607 let txFromMsg = newLocTxVer[1]
16931608 let lastTx = valueOrElse(getString(keyLastTxIdByUser(userAddr)), "")
16941609 if ((lastTx != txFromMsg))
16951610 then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
16961611 else {
16971612 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
16981613 let keyHealth = keyDuckHealth(duckAssetId)
16991614 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
17001615 let oldFromState = valueOrElse(getInteger(keyHealth), maxHP)
17011616 if ((oldFromState != curHP))
17021617 then throw(((("oldHealth=" + toString(oldFromState)) + " from state does not match one from flight log=") + toString(curHP)))
17031618 else if ((0 >= curHP))
17041619 then throw("You can't fly with zero health")
17051620 else if (!(canWearCurrentEquipment(duckAssetId)))
17061621 then throw("Equipment incompatible")
17071622 else {
17081623 let bonus = if ((size(flightLog) > flBonus))
17091624 then flightLog[flBonus]
17101625 else ""
17111626 let prodUsed = if ((size(flightLog) > flProdsUsed))
17121627 then flightLog[flProdsUsed]
17131628 else ""
17141629 let sentAmount = if (if ((newHP > 0))
17151630 then (bonus == "$")
17161631 else false)
17171632 then asInt(invoke(restContract, "sendUsdtPrize", [userAddr], nil))
17181633 else 0
17191634 $Tuple5(newHP, duckAssetId, sentAmount, newLocation, prodUsed)
17201635 }
17211636 }
17221637 }
17231638 }
17241639
17251640
17261641 func applyBonuses (landAssetId,pieces) = {
17271642 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
17281643 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
17291644 let add6 = (infraLevel / 6)
17301645 let add7 = (infraLevel / 7)
17311646 ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, ((infraLevel + add6) + (2 * add7)), 5)) + fraction(DAILYRESBYPIECE, artPieces, (pieces * 5)))
17321647 }
17331648
17341649
17351650 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
1736- let $t03334333882 = if ((claimMode == claimModeWh))
1651+ let $t03367834217 = if ((claimMode == claimModeWh))
17371652 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
17381653 else {
17391654 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
17401655 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
17411656 let loc = split(value(curLocation), "_")
17421657 if ((loc[locIdxType] != "L"))
17431658 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
17441659 else $Tuple2(loc[locIdxId], duckAssetId)
17451660 }
1746- let landAssetId = $t03334333882._1
1747- let duckId = $t03334333882._2
1661+ let landAssetId = $t03367834217._1
1662+ let duckId = $t03367834217._2
17481663 let asset = value(assetInfo(fromBase58String(landAssetId)))
17491664 let timeKey = keyStakedTimeByAssetId(landAssetId)
17501665 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
17511666 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
17521667 if ((owner != addr))
17531668 then throw((LANDPREFIX + " is not yours"))
17541669 else {
17551670 let d = split(asset.description, "_")
17561671 $Tuple4(duckId, landAssetId, d, savedTime)
17571672 }
17581673 }
17591674
17601675
17611676 func claimResInternal (addr,amount,claimMode,landAssetIdIn) = if ((0 > amount))
17621677 then throw("Negative amount")
17631678 else {
17641679 let c = checkClaimConditions(addr, claimMode, landAssetIdIn)
17651680 let landSize = c._3[recLandSize]
17661681 let terrainCounts = countTerrains(c._3[recTerrains])
17671682 let deltaTime = (lastBlock.timestamp - c._4)
17681683 if ((0 > deltaTime))
17691684 then throw(((("Saved timestamp is in future, saved = " + toString(c._4)) + ", current = ") + toString(lastBlock.timestamp)))
17701685 else {
17711686 let pieces = numPiecesBySize(landSize)
17721687 let dailyProductionByPiece = applyBonuses(c._2, pieces)
17731688 let availRes = fraction(deltaTime, (dailyProductionByPiece * pieces), DAYMILLIS)
17741689 if ((amount > availRes))
17751690 then throw(((("Not enough resources, available = " + toString(availRes)) + ", requested = ") + toString(amount)))
17761691 else {
17771692 let newDeltaTime = fraction((availRes - amount), DAYMILLIS, (dailyProductionByPiece * pieces))
17781693 let newTimestamp = (lastBlock.timestamp - newDeltaTime)
17791694 let landIndex = (pieces / SSIZE)
17801695 let resToClaim = virtClaim(terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece)
17811696 let whKey = keyWarehouseByLand(c._2)
17821697 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(c._2)), 0)
17831698 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
17841699 let loft = split(currentWh[whIdxLOFT], "_")
17851700 let whSpaceLeft = parseIntValue(loft[volFree])
17861701 if (if ((claimMode == claimModeWh))
17871702 then (amount > whSpaceLeft)
17881703 else false)
17891704 then throw((("Only " + toString(whSpaceLeft)) + " space left in warehouse"))
17901705 else {
17911706 let bpKey = keyBackpackByDuck(c._1)
17921707 let currentPack = getBackpack(bpKey)
17931708 let currentPackRes = split(currentPack[bpIdxRes], "_")
17941709 let currentWhRes = split(currentWh[whIdxRes], "_")
1795- let $t03625637127 = if ((claimMode == claimModeWh))
1710+ let $t03659137462 = if ((claimMode == claimModeWh))
17961711 then $Tuple4(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes], (parseIntValue(loft[volOccupied]) + resToClaim._2), (parseIntValue(loft[volFree]) - resToClaim._2))
17971712 else if ((claimMode == claimModeDuck))
17981713 then $Tuple4(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), parseIntValue(loft[volOccupied]), parseIntValue(loft[volFree]))
17991714 else {
18001715 let distr = distributeRes(currentWhRes, currentPackRes, resToClaim, whSpaceLeft)
18011716 let whAm = min([parseIntValue(loft[volFree]), resToClaim._2])
18021717 $Tuple4(distr._1, distr._2, (parseIntValue(loft[volOccupied]) + whAm), (parseIntValue(loft[volFree]) - whAm))
18031718 }
1804- let whRes = $t03625637127._1
1805- let bpRes = $t03625637127._2
1806- let loftO = $t03625637127._3
1807- let loftF = $t03625637127._4
1719+ let whRes = $t03659137462._1
1720+ let bpRes = $t03659137462._2
1721+ let loftO = $t03659137462._3
1722+ let loftF = $t03659137462._4
18081723 $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxLevels], whRes, currentWh[whIdxMat], currentWh[whIdxProd], makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")])
18091724 }
18101725 }
18111726 }
18121727 }
18131728
18141729
18151730 func claimAll (addr,landAssetId,pieces,claimMode) = {
18161731 let timeKey = keyStakedTimeByAssetId(landAssetId)
18171732 let savedTime = value(getInteger(timeKey))
18181733 let availRes = (fraction((lastBlock.timestamp - savedTime), applyBonuses(landAssetId, pieces), DAYMILLIS) * pieces)
18191734 claimResInternal(addr, availRes, claimMode, landAssetId)
18201735 }
18211736
18221737
18231738 func upInfraCommon (shouldUseMat,caller,paymentAmount,landAssetId) = {
18241739 let addr = toString(caller)
18251740 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetId)
18261741 let pieces = numPiecesBySize(c._3[recLandSize])
18271742 let infraKey = keyInfraLevelByAssetId(c._2)
18281743 let curLevel = valueOrElse(getInteger(infraKey), 0)
18291744 if (if (!(KS_ALLOW_BIG_INFRA_MERGE))
18301745 then (curLevel >= 3)
18311746 else false)
18321747 then throw("Currently max infrastructure level = 3")
18331748 else {
18341749 let maxInfra = ((sqrt(pieces, 0, 0, DOWN) / 5) + 2)
18351750 let newLevel = (curLevel + 1)
18361751 if (if (KS_ALLOW_BIG_INFRA_MERGE)
18371752 then (newLevel > maxInfra)
18381753 else false)
18391754 then throw(("Currently max infrastructure level = " + toString(maxInfra)))
18401755 else {
18411756 let cost = fraction(InfraUpgradeCostSUsdt, (pieces * newLevel), SSIZE)
18421757 if (if (!(shouldUseMat))
18431758 then (paymentAmount != cost)
18441759 else false)
18451760 then throw(("Payment attached should be " + toString(cost)))
18461761 else {
18471762 let bpKey = keyBackpackByDuck(c._1)
18481763 let currentPack = getBackpack(bpKey)
18491764 let mList = split(currentPack[bpIdxMat], "_")
18501765 let matUsed = fraction(InfraUpgradeCostS, (pieces * newLevel), SSIZE)
18511766 let newMat = makeString(subtractMaterials(shouldUseMat, mList, matUsed), "_")
18521767 let claimResult = claimAll(addr, c._2, pieces, claimModeWhThenDuck)
18531768 let whData = claimResult._5
18541769 let oldVol = getWarehouseTotalVolume(whData[whIdxLevels])
18551770 let newVolData = makeString([split(whData[whIdxLevels], "_")[0], toString(newLevel)], "_")
18561771 let newVol = getWarehouseTotalVolume(newVolData)
18571772 let loft = split(whData[whIdxLOFT], "_")
18581773 let newLoftStr = makeString([loft[volLocked], loft[volOccupied], toString(((parseIntValue(loft[volFree]) + newVol) - oldVol)), toString(newVol)], "_")
18591774 $Tuple3(([IntegerEntry(infraKey, newLevel), IntegerEntry(keyInfraLevelByAssetIdAndOwner(c._2, addr), newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], claimResult._3[bpIdxRes], newMat, currentPack[bpIdxProd]], ":")), StringEntry(claimResult._4, makeString([newVolData, whData[whIdxRes], whData[whIdxMat], whData[whIdxProd], newLoftStr], ":"))] ++ claimResult._1), newLevel, matUsed)
18601775 }
18611776 }
18621777 }
18631778 }
18641779
18651780
18661781 func updateStatsInternal (lvlKey,xpKey,pointsKey,deltaXP) = {
18671782 let xp = valueOrElse(getInteger(xpKey), 0)
18681783 let newXP = (xp + deltaXP)
18691784 let lvlPoints = levelUp(valueOrElse(getInteger(lvlKey), 0), newXP)
18701785 $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(pointsKey, (valueOrElse(getInteger(pointsKey), 0) + lvlPoints[1]))], newXP)
18711786 }
18721787
18731788
18741789 func updateDuckStatsInternal (duckAssetId,deltaXP) = {
18751790 let asset = value(assetInfo(fromBase58String(duckAssetId)))
18761791 let addr = valueOrErrorMessage(getString(keyDuckIdToOwner(duckAssetId)), (("NFT " + asset.name) + " is orphaned"))
18771792 if (if (if (KS_ALLOW_ROBO_DUCKS)
18781793 then (asset.issuer == this)
18791794 else false)
18801795 then contains(asset.name, ROBO_PREFIX)
18811796 else false)
18821797 then updateStatsInternal(keyUserLevel(addr), keyUserXP(addr), keyUserFreePoints(addr), deltaXP)
18831798 else updateStatsInternal(keyDuckLevel(duckAssetId), keyDuckXP(duckAssetId), keyDuckFreePoints(duckAssetId), deltaXP)
18841799 }
18851800
18861801
18871802 func updateAccStatsInternal (addr,deltaXP) = updateStatsInternal(keyUserLevel(addr), keyUserXP(addr), keyUserFreePoints(addr), deltaXP)
18881803
18891804
18901805 func activateOnboardArt (addr) = {
18911806 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
18921807 let refByKey = keyAddressRefBy(addr)
18931808 let refBy = getString(refByKey)
18941809 if (!(isDefined(refBy)))
18951810 then throw("You are not eligible for ONBOARD artifact")
18961811 else {
18971812 let artKey = keyOnboardArtDuckActivatedBy(addr)
18981813 let artDuck = getString(artKey)
18991814 if (isDefined(artDuck))
19001815 then throw(("You already used your ONBOARD artifact on duck " + value(artDuck)))
19011816 else {
19021817 let duckActivatorKey = keyOnboardArtActivatedOnDuck(duckAssetId)
19031818 let duckActivator = getString(duckActivatorKey)
19041819 if (isDefined(duckActivator))
19051820 then throw(((("The duck " + duckAssetId) + " already got points from ONBOARD artifact from user ") + value(duckActivator)))
19061821 else ([StringEntry(artKey, duckAssetId), StringEntry(duckActivatorKey, addr)] ++ updateDuckStatsInternal(duckAssetId, xpOnboard)._1)
19071822 }
19081823 }
19091824 }
19101825
19111826
19121827 func activatePresaleArt (addr,landAssetIdIn) = {
19131828 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetIdIn)
19141829 let landAssetId = c._2
19151830 let pieces = numPiecesBySize(c._3[recLandSize])
19161831 let activationKey = keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)
19171832 if ((valueOrElse(getInteger(activationKey), 0) > 0))
19181833 then throw("Presale artifact is already activated")
19191834 else if ((parseIntValue(c._3[recLandNum]) > PRESALENUMLANDS))
19201835 then throw((((LANDPREFIX + " ") + landAssetId) + " is not eligible for presale artifact"))
19211836 else {
19221837 let claimResult = claimAll(addr, landAssetId, pieces, claimModeWhThenDuck)
19231838 (((claimResult._1 :+ IntegerEntry(activationKey, pieces)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":"))) :+ StringEntry(claimResult._4, makeString(claimResult._5, ":")))
19241839 }
19251840 }
19261841
19271842
19281843 func checkTournament (duckAssetId) = {
19291844 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
19301845 let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
19311846 let now = lastBlock.timestamp
19321847 let tData = getTourData(tournamentContract, lastId)
19331848 let static = tData[idxStatic]
19341849 let dynamic = tData[idxDynamic]
19351850 if ((curLocation[locIdxType] != "T"))
19361851 then false
19371852 else if (if (if ((parseIntValue(curLocation[locIdxContinent]) == lastId))
19381853 then (dynamic[tDynamicStatus] == "INPROGRESS")
19391854 else false)
19401855 then (parseIntValue(static[tStaticEnd]) > now)
19411856 else false)
19421857 then throw("Your duck is taking part in the tournament")
19431858 else asBoolean(invoke(this, "exitTournamentInternal", [duckAssetId], nil))
19441859 }
19451860
19461861
19471862 func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,needMat) = {
19481863 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
19491864 if (checkTournament(duckAssetId))
19501865 then throw("mergeInternal_checkTournament")
19511866 else {
19521867 func checkMerge (acc,landAssetId) = {
19531868 let asset = value(assetInfo(fromBase58String(landAssetId)))
19541869 let timeKey = keyStakedTimeByAssetId(landAssetId)
19551870 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
19561871 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
19571872 if ((owner != addr))
19581873 then throw((LANDPREFIX + " is not yours"))
19591874 else {
19601875 let d = split(asset.description, "_")
19611876 let continent = d[recContinent]
19621877 if (if ((acc._3 != ""))
19631878 then (acc._3 != continent)
19641879 else false)
19651880 then throw("Lands should be on the same continent to merge")
19661881 else {
19671882 let landSize = d[recLandSize]
19681883 let sizesIn = acc._1
19691884 let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
19701885 let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
19711886 let pieces = numPiecesBySize(landSize)
19721887 let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
19731888 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
19741889 let reqLevel = match landSize {
19751890 case _ =>
19761891 if (("S" == $match0))
19771892 then 3
19781893 else if (("M" == $match0))
19791894 then 4
19801895 else if (("L" == $match0))
19811896 then 5
19821897 else if (("XL" == $match0))
19831898 then 6
19841899 else throw("Only S, M, L, XL can merge")
19851900 }
19861901 if ((infraLevel != reqLevel))
19871902 then throw("All lands should be maxed to merge")
19881903 else {
19891904 let landNum = d[recLandNum]
19901905 let terrainCounts = countTerrains(d[recTerrains])
19911906 let deltaTime = (lastBlock.timestamp - savedTime)
19921907 if ((0 > deltaTime))
19931908 then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
19941909 else {
19951910 let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
19961911 let landIndex = (pieces / SSIZE)
19971912 let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
19981913 let props = updateProportionsInternal(acc._6, terrainCounts, landIndex, -1)
19991914 let cProps = updateProportionsInternal(acc._10, terrainCounts, landIndex, -1)
20001915 let sumTerrains = updateProportionsInternal(acc._9, terrainCounts, landIndex, 1)
20011916 let lands = acc._7
20021917 let idx = indexOf(lands, landAssetId)
20031918 if (!(isDefined(idx)))
20041919 then throw(("Your staked lands don't contain " + landAssetId))
20051920 else {
20061921 let customKey = keyLandAssetIdToCustomName(landAssetId)
20071922 let customName = valueOrElse(getString(customKey), "")
20081923 $Tuple10(sizesOut, arts, continent, bpRes, ((((((((((((acc._5 :+ DeleteEntry(keyStakedTimeByAssetId(landAssetId))) :+ DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))) :+ DeleteEntry(keyLandToAssetId(landNum))) :+ DeleteEntry(keyLandAssetIdToOwner(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetId(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId))) :+ DeleteEntry(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ Burn(fromBase58String(landAssetId), 1)) ++ (if ((customName != ""))
20091924 then [DeleteEntry(keyLandCustomNameToAssetId(customName))]
20101925 else nil)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces), sumTerrains, cProps)
20111926 }
20121927 }
20131928 }
20141929 }
20151930 }
20161931 }
20171932
20181933 let bpKey = keyBackpackByDuck(duckAssetId)
20191934 let currentPack = getBackpack(bpKey)
20201935 let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
20211936 let landsKey = keyStakedLandsByOwner(addr)
20221937 let landsStr = getString(landsKey)
20231938 let landsIn = if (isDefined(landsStr))
20241939 then split_51C(value(landsStr), "_")
20251940 else nil
20261941 let cont0 = split(value(assetInfo(fromBase58String(landAssetIds[0]))).description, "_")[recContinent]
20271942 let contProps = split(valueOrElse(getString(keyResTypesByContinent(cont0)), "0_0_0_0_0_0"), "_")
20281943 let r = {
20291944 let $l = landAssetIds
20301945 let $s = size($l)
20311946 let $acc0 = $Tuple10(formula, 0, "", currentPack[bpIdxRes], nil, propList, landsIn, 0, split("0_0_0_0_0_0", "_"), contProps)
20321947 func $f0_1 ($a,$i) = if (($i >= $s))
20331948 then $a
20341949 else checkMerge($a, $l[$i])
20351950
20361951 func $f0_2 ($a,$i) = if (($i >= $s))
20371952 then $a
20381953 else throw("List size exceeds 5")
20391954
20401955 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
20411956 }
20421957 let continent = r._3
20431958 let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
20441959 let terrains = genTerrainsForMerge(r._9, (numPiecesBySize(newLandSize) / SSIZE))
20451960 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
20461961 let newLandNum = toString(freeNum)
20471962 let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
20481963 let assetId = calculateAssetId(issue)
20491964 let newLandAssetId = toBase58String(assetId)
20501965 let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
20511966 let piecesKey = keyStakedPiecesByOwner(addr)
20521967 let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
20531968 $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
20541969 then StringEntry(landsKey, makeString_11C(r._7, "_"))
20551970 else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
20561971 then 0
20571972 else (stakedPieces - r._8))) :+ IntegerEntry(keyNextFreeLandNum(), (freeNum + 1))) :+ issue) :+ StringEntry(keyLandToAssetId(newLandNum), newLandAssetId)) :+ StringEntry(keyLandAssetIdToOwner(newLandAssetId), addr)) :+ StringEntry(keyLandNumToOwner(newLandNum), addr)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, newLandAssetId), r._2)) :+ IntegerEntry(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), makeString(r._6, "_"))) :+ StringEntry(keyResTypesByContinent(continent), makeString(r._10, "_"))) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
20581973 }
20591974 }
20601975
20611976
20621977 func s2m (addr,landAssetIds) = mergeInternal("M", 3, "SSSS", addr, landAssetIds, 0)
20631978
20641979
20651980 func m2l (addr,landAssetIds) = mergeInternal("L", 4, "SMM", addr, landAssetIds, (InfraUpgradeCostS * 4))
20661981
20671982
20681983 func l2xl (addr,landAssetIds) = mergeInternal("XL", 5, "SSSML", addr, landAssetIds, (InfraUpgradeCostS * 47))
20691984
20701985
20711986 func xl2xxl (addr,landAssetIds) = mergeInternal("XXL", 6, "LXL", addr, landAssetIds, (InfraUpgradeCostS * 54))
20721987
20731988
20741989 func mergeCommon (addr,landAssetIds) = match size(landAssetIds) {
20751990 case _ =>
20761991 if ((4 == $match0))
20771992 then s2m(addr, landAssetIds)
20781993 else if ((3 == $match0))
20791994 then m2l(addr, landAssetIds)
20801995 else if ((5 == $match0))
20811996 then l2xl(addr, landAssetIds)
20821997 else if ((2 == $match0))
20831998 then xl2xxl(addr, landAssetIds)
20841999 else throw("Unknown merge")
20852000 }
20862001
20872002
20882003 func prolog (i) = if (if ((i.originCaller != restContract))
20892004 then valueOrElse(getBoolean(keyBlocked()), false)
20902005 else false)
20912006 then throw("Contracts are under maintenance")
20922007 else [StringEntry(keyLastTxIdByUser(toString(i.originCaller)), toBase58String(i.transactionId))]
20932008
20942009
20952010 @Callable(i)
20962011 func constructorV1 (restAddr) = if ((i.caller != this))
20972012 then throw("Permission denied")
20982013 else [StringEntry(keyRestAddress(), restAddr)]
20992014
21002015
21012016
21022017 @Callable(i)
21032018 func saveInteger (key,amount) = if ((i.caller != this))
21042019 then throw("saveInteger is not public method")
21052020 else [IntegerEntry(key, amount)]
21062021
21072022
21082023
21092024 @Callable(i)
21102025 func setBlocked (isBlocked) = if ((i.caller != this))
21112026 then throw("permission denied")
21122027 else [BooleanEntry(keyBlocked(), isBlocked)]
21132028
21142029
21152030
21162031 @Callable(i)
21172032 func stakeLand () = {
21182033 let prologActions = prolog(i)
21192034 if ((size(i.payments) != 1))
21202035 then throw("Exactly one payment required")
21212036 else {
21222037 let pmt = value(i.payments[0])
21232038 let assetId = value(pmt.assetId)
21242039 let address = toString(i.caller)
21252040 if ((pmt.amount != 1))
21262041 then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
21272042 else {
21282043 let asset = value(assetInfo(assetId))
21292044 if ((asset.issuer != this))
21302045 then throw("Unknown issuer of token")
21312046 else if (!(contains(asset.name, LANDPREFIX)))
21322047 then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
21332048 else {
21342049 let landNumSize = drop(asset.name, 4)
21352050 let landNum = if (contains(landNumSize, "XXL"))
21362051 then dropRight(landNumSize, 3)
21372052 else if (contains(landNumSize, "XL"))
21382053 then dropRight(landNumSize, 2)
21392054 else dropRight(landNumSize, 1)
21402055 if (!(isDefined(parseInt(landNum))))
21412056 then throw(("Cannot parse land number from " + asset.name))
21422057 else {
21432058 let landAssetId = toBase58String(assetId)
21442059 let timeKey = keyStakedTimeByAssetId(landAssetId)
21452060 if (isDefined(getInteger(timeKey)))
21462061 then throw((("NFT " + asset.name) + " is already staked"))
21472062 else {
21482063 let d = split(asset.description, "_")
21492064 let terrainCounts = countTerrains(d[recTerrains])
21502065 let pieces = numPiecesBySize(d[recLandSize])
21512066 let landIndex = (pieces / SSIZE)
21522067 let props = updateProportions(terrainCounts, landIndex, 1)
21532068 let resByContKey = keyResTypesByContinent(d[recContinent])
21542069 let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
21552070 let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, 1), "_")
21562071 let landsKey = keyStakedLandsByOwner(address)
21572072 let landsStr = getString(landsKey)
21582073 let lands = if (isDefined(landsStr))
21592074 then split_51C(value(landsStr), "_")
21602075 else nil
21612076 if (containsElement(lands, landAssetId))
21622077 then throw(("Your staked lands already contain " + landAssetId))
21632078 else if ((size(lands) >= MAX_LANDS_STAKED_BY_USER))
21642079 then throw((("Your already staked max (" + toString(MAX_LANDS_STAKED_BY_USER)) + ") lands"))
21652080 else {
21662081 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
21672082 let piecesKey = keyStakedPiecesByOwner(address)
21682083 let oldPieces = valueOrElse(getInteger(piecesKey), 0)
21692084 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
21702085 $Tuple2(([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address), lastBlock.timestamp), StringEntry(landsKey, makeString_11C((lands :+ landAssetId), "_")), IntegerEntry(piecesKey, (oldPieces + pieces)), StringEntry(keyLandAssetIdToOwner(landAssetId), address), StringEntry(keyLandNumToOwner(landNum), address), IntegerEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, address), infraLevel), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps)] ++ prologActions), wlgResult)
21712086 }
21722087 }
21732088 }
21742089 }
21752090 }
21762091 }
21772092 }
21782093
21792094
21802095
21812096 @Callable(i)
21822097 func unstakeLand (landAssetIdIn) = {
21832098 let prologActions = prolog(i)
21842099 if ((size(i.payments) != 0))
21852100 then throw("No payments required")
21862101 else {
21872102 let addr = toString(i.caller)
21882103 let c = checkClaimConditions(addr, claimModeDuck, landAssetIdIn)
21892104 let landAssetId = c._2
21902105 let d = c._3
21912106 let landsKey = keyStakedLandsByOwner(addr)
21922107 let terrainCounts = countTerrains(d[recTerrains])
21932108 let pieces = numPiecesBySize(d[recLandSize])
21942109 let landIndex = (pieces / SSIZE)
21952110 let props = updateProportions(terrainCounts, landIndex, -1)
21962111 let resByContKey = keyResTypesByContinent(d[recContinent])
21972112 let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
21982113 let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, -1), "_")
21992114 let claimResult = claimAll(addr, landAssetId, pieces, claimModeDuck)
22002115 let lands = split_51C(valueOrElse(getString(landsKey), ""), "_")
22012116 let idx = indexOf(lands, landAssetId)
22022117 if (!(isDefined(idx)))
22032118 then throw(("Your staked lands don't contain " + landAssetId))
22042119 else {
22052120 let now = lastBlock.timestamp
22062121 let govReleaseTime = valueOrElse(getInteger(govContract, keyUserGwlReleaseTime(addr)), 0)
22072122 if ((govReleaseTime >= now))
22082123 then throw(("Your gWL are taking part in voting, cannot unstake until " + toString(govReleaseTime)))
22092124 else {
22102125 let arbReleaseTime = (valueOrElse(getInteger(wlgContract, keyLastArbTimeByUser(addr)), 0) + arbitrageDelay)
22112126 if ((arbReleaseTime > now))
22122127 then throw(("Your staked lands took part in arbitrage, cannot unstake until " + toString(arbReleaseTime)))
22132128 else {
22142129 let piecesKey = keyStakedPiecesByOwner(addr)
22152130 let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
22162131 let newPieces = if ((pieces > stakedPieces))
22172132 then 0
22182133 else (stakedPieces - pieces)
22192134 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr], nil)
22202135 $Tuple2(([ScriptTransfer(i.caller, 1, fromBase58String(landAssetId)), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr)), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps), StringEntry(claimResult._2, makeString(claimResult._3, ":")), if ((size(lands) > 1))
22212136 then StringEntry(landsKey, makeString_11C(removeByIndex(lands, value(idx)), "_"))
22222137 else DeleteEntry(landsKey), IntegerEntry(piecesKey, newPieces)] ++ prologActions), wlgResult)
22232138 }
22242139 }
22252140 }
22262141 }
22272142 }
22282143
22292144
22302145
22312146 @Callable(i)
22322147 func stakeDuck () = {
22332148 let prologActions = prolog(i)
22342149 if ((size(i.payments) != 1))
22352150 then throw("Exactly one payment required")
22362151 else {
22372152 let pmt = value(i.payments[0])
22382153 let assetId = value(pmt.assetId)
22392154 let address = toString(i.caller)
22402155 if ((pmt.amount != 1))
22412156 then throw((("NFT " + DUCKPREFIX) + " token should be attached as payment"))
22422157 else {
22432158 let asset = value(assetInfo(assetId))
22442159 let isRobo = if (if (KS_ALLOW_ROBO_DUCKS)
22452160 then (asset.issuer == this)
22462161 else false)
22472162 then contains(asset.name, ROBO_PREFIX)
22482163 else false
22492164 if (if (if ((asset.issuer != incubatorAddr))
22502165 then (asset.issuer != breederAddr)
22512166 else false)
22522167 then !(isRobo)
22532168 else false)
22542169 then throw((((("Unknown issuer of " + DUCKPREFIX) + " or ") + ROBO_PREFIX) + " token"))
22552170 else if (if (!(contains(asset.name, DUCKPREFIX)))
22562171 then !(isRobo)
22572172 else false)
22582173 then throw((((("Only NFT " + DUCKPREFIX) + " or ") + ROBO_PREFIX) + " tokens are accepted"))
22592174 else {
22602175 let assetIdStr = toBase58String(assetId)
22612176 let timeKey = keyStakedTimeByAssetId(assetIdStr)
22622177 if (isDefined(getInteger(timeKey)))
22632178 then throw((("NFT " + asset.name) + " is already staked"))
22642179 else if (isDefined(getString(keyStakedDuckByOwner(address))))
22652180 then throw(("You already staked one duck: " + asset.name))
22662181 else {
22672182 let locKey = keyDuckLocation(assetIdStr)
22682183 let location = getString(locKey)
22692184 let bpKey = keyBackpackByDuck(assetIdStr)
22702185 let backpack = getString(bpKey)
22712186 let keyHealth = keyDuckHealth(assetIdStr)
22722187 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
22732188 let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
22742189 ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
22752190 then nil
22762191 else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
22772192 then nil
22782193 else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyHealth, curHealth)) ++ prologActions)))))
22792194 }
22802195 }
22812196 }
22822197 }
22832198 }
22842199
22852200
22862201
22872202 @Callable(i)
22882203 func unstakeDuck (assetIdStr) = {
22892204 let prologActions = prolog(i)
22902205 if ((size(i.payments) != 0))
22912206 then throw("No payments required")
22922207 else {
22932208 let assetId = fromBase58String(assetIdStr)
22942209 let address = toString(i.caller)
22952210 let asset = value(assetInfo(assetId))
22962211 let timeKey = keyStakedTimeByAssetId(assetIdStr)
22972212 if (!(isDefined(getInteger(timeKey))))
22982213 then throw((("NFT " + asset.name) + " is not staked"))
22992214 else if (!(isDefined(getString(keyStakedDuckByOwner(address)))))
23002215 then throw((("The duck " + asset.name) + " is not staked"))
23012216 else {
23022217 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetIdStr)), (("NFT " + asset.name) + " is orphaned"))
23032218 if ((owner != address))
23042219 then throw("Staked NFT is not yours")
23052220 else if (checkTournament(assetIdStr))
23062221 then throw("unstakeDuck_checkTournament")
23072222 else {
23082223 let keyHealth = keyDuckHealth(assetIdStr)
23092224 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
23102225 let health = valueOrElse(getInteger(keyHealth), maxHP)
23112226 if ((maxHP > health))
23122227 then throw((("Please heal your duck to " + toString(maxHP)) + "hp before unstaking"))
23132228 else ([ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyHealth), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address))] ++ prologActions)
23142229 }
23152230 }
23162231 }
23172232 }
23182233
23192234
23202235
23212236 @Callable(i)
23222237 func claimRes (amount,landAssetIdStr) = {
23232238 let prologActions = prolog(i)
23242239 if ((size(i.payments) != 0))
23252240 then throw("No payments required")
23262241 else {
23272242 let addr = toString(i.originCaller)
23282243 let result = claimResInternal(addr, amount, claimModeDuck, landAssetIdStr)
23292244 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
23302245 $Tuple2(((((result._1 ++ updateDuckStatsInternal(duckAssetId, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) ++ prologActions), result._3[bpIdxRes])
23312246 }
23322247 }
23332248
23342249
23352250
23362251 @Callable(i)
23372252 func claimResToWH (amount,landAssetIdStr) = {
23382253 let prologActions = prolog(i)
23392254 if ((size(i.payments) != 0))
23402255 then throw("No payments required")
23412256 else {
23422257 let addr = toString(i.originCaller)
23432258 let result = claimResInternal(addr, amount, claimModeWh, landAssetIdStr)
23442259 $Tuple2(((((result._1 ++ updateAccStatsInternal(addr, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) ++ prologActions), result._5[whIdxRes])
23452260 }
23462261 }
23472262
23482263
23492264
23502265 @Callable(i)
23512266 func flight (message,sig) = {
23522267 let prologActions = prolog(i)
23532268 if ((size(i.payments) != 0))
23542269 then throw("No payments required")
23552270 else {
23562271 let userAddr = toString(i.caller)
23572272 let f = flightCommon(userAddr, message, sig)
23582273 let newHP = f._1
23592274 let duckAssetId = f._2
23602275 let locKey = keyDuckLocation(duckAssetId)
23612276 let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
23622277 let newLocation = f._4
23632278 if ((newLocation == curLocation))
23642279 then throw("You can't fly to the same location")
23652280 else {
23662281 let newLoc = split(newLocation, "_")
23672282 let isTour = (newLoc[locIdxType] == "T")
23682283 let isDeliv = (newLoc[locIdxType] == "D")
23692284 let eqKey = keyDuckEquipment(duckAssetId)
23702285 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2371- let $t06603566132 = subtractEquipment(currentEq, f._5)
2372- let newEq = $t06603566132._1
2373- let shouldZeroBuffs = $t06603566132._2
2374- let $t06613567967 = if (!(onMission(tournamentContract, curLocation)))
2286+ let $t06637066476 = subtractEquipment(currentEq, f._5)
2287+ let newEq = $t06637066476._1
2288+ let shouldZeroBuffs = $t06637066476._2
2289+ let ignored = $t06637066476._3
2290+ let $t06647968311 = if (!(onMission(tournamentContract, curLocation)))
23752291 then if (isTour)
23762292 then cheatAttempt(curLocation, newLocation, 5)
23772293 else if (!(isDeliv))
23782294 then if ((newHP > 0))
23792295 then $Tuple2(newLocation, newHP)
23802296 else $Tuple2(curLocation, 0)
23812297 else if ((newHP > 0))
23822298 then {
23832299 let s = invoke(this, "processDelivery", [duckAssetId], nil)
23842300 if ((s == s))
23852301 then $Tuple2(curLocation, newHP)
23862302 else throw("Strict value is not equal to itself.")
23872303 }
23882304 else $Tuple2(curLocation, 0)
23892305 else if (isInTournament(tournamentContract, curLocation))
23902306 then if (!(isInTournament(tournamentContract, newLocation)))
23912307 then throw("Your duck is taking part in the tournament")
23922308 else {
23932309 let score = parseIntValue(newLoc[locIdxId])
23942310 let curLoc = split(curLocation, "_")
23952311 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
23962312 if ((score != (parseIntValue(curLoc[locIdxId]) + 1)))
23972313 then cheatAttempt(curLocation, newLocation, 7)
23982314 else if ((newHP > 0))
23992315 then {
24002316 let localBest = valueOrElse(getInteger(tournamentContract, keyBestResultByTourAndDuck(lastId, duckAssetId)), 0)
24012317 let updLocal = if ((score > localBest))
24022318 then invoke(tournamentContract, "saveDuckResult", [duckAssetId, score], nil)
24032319 else unit
24042320 if ((updLocal == updLocal))
24052321 then $Tuple2(newLocation, newHP)
24062322 else throw("Strict value is not equal to itself.")
24072323 }
24082324 else $Tuple2(curLocation, 0)
24092325 }
24102326 else throw(("Unknown curLocation:" + curLocation))
2411- let locToSave = $t06613567967._1
2412- let hpToSave = $t06613567967._2
2327+ let locToSave = $t06647968311._1
2328+ let hpToSave = $t06647968311._2
24132329 $Tuple2(((([StringEntry(locKey, locToSave), StringEntry(eqKey, newEq), IntegerEntry(keyDuckHealth(duckAssetId), hpToSave)] ++ prologActions) ++ (if (shouldZeroBuffs)
24142330 then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
24152331 else nil)) ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
24162332 then xpSuccessFlight
24172333 else xpFailFlight)._1), f._3)
24182334 }
24192335 }
24202336 }
24212337
24222338
24232339
24242340 @Callable(i)
24252341 func heal (quantityL1,quantityL2,quantityL3) = {
24262342 let prologActions = prolog(i)
24272343 if (if (if ((0 > quantityL1))
24282344 then true
24292345 else (0 > quantityL2))
24302346 then true
24312347 else (0 > quantityL3))
24322348 then throw("Quantity cannot be negative")
24332349 else {
24342350 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
24352351 if (checkTournament(duckAssetId))
24362352 then throw("heal_checkTournament")
24372353 else {
24382354 let qts = [quantityL1, quantityL2, quantityL3]
24392355 let keyHealth = keyDuckHealth(duckAssetId)
24402356 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
24412357 let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
24422358 if ((oldHealth >= maxHP))
24432359 then throw((("HP should be < " + toString(maxHP)) + " to heal"))
24442360 else {
24452361 let bpKey = keyBackpackByDuck(duckAssetId)
24462362 let currentPack = getBackpack(bpKey)
24472363 let prodList = if ((currentPack[bpIdxProd] == ""))
24482364 then nil
24492365 else split_4C(currentPack[bpIdxProd], "_")
24502366 func iterateProd (acc,recipe) = {
24512367 let n = acc._2
24522368 let x = if ((size(prodList) > n))
24532369 then parseIntValue(prodList[n])
24542370 else 0
24552371 if ((3 > n))
24562372 then {
24572373 let q = qts[n]
24582374 if ((q > x))
24592375 then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
24602376 else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (parseIntValue(split(recipe, "_")[rIdxEffect]) * q)))
24612377 }
24622378 else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
24632379 }
24642380
24652381 let result = {
24662382 let $l = productionMatrix
24672383 let $s = size($l)
24682384 let $acc0 = $Tuple3(nil, 0, 0)
24692385 func $f0_1 ($a,$i) = if (($i >= $s))
24702386 then $a
24712387 else iterateProd($a, $l[$i])
24722388
24732389 func $f0_2 ($a,$i) = if (($i >= $s))
24742390 then $a
24752391 else throw("List size exceeds 50")
24762392
24772393 $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)
24782394 }
24792395 let newHealth = min([maxHP, (oldHealth + result._3)])
24802396 $Tuple2((([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":"))] ++ prologActions) ++ updateDuckStatsInternal(duckAssetId, (xpHeal * ((quantityL1 + quantityL2) + quantityL3)))._1), newHealth)
24812397 }
24822398 }
24832399 }
24842400 }
24852401
24862402
24872403
24882404 @Callable(i)
24892405 func healES () = {
24902406 let prologActions = prolog(i)
24912407 if ((size(i.payments) != 1))
24922408 then throw("Exactly one payment required")
24932409 else {
24942410 let pmt = value(i.payments[0])
24952411 if ((pmt.assetId != usdtAssetId))
24962412 then throw("Allowed USDT payment only!")
24972413 else {
24982414 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
24992415 if (checkTournament(duckAssetId))
25002416 then throw("healES_checkTournament")
25012417 else {
25022418 let keyHealth = keyDuckHealth(duckAssetId)
25032419 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
25042420 let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
25052421 if ((oldHealth > 0))
25062422 then throw("HP should be 0 to call Emergency Service")
25072423 else {
25082424 let bpKey = keyBackpackByDuck(duckAssetId)
25092425 let currentPack = getBackpack(bpKey)
25102426 let prodList = if ((currentPack[bpIdxProd] == ""))
25112427 then nil
25122428 else split_4C(currentPack[bpIdxProd], "_")
25132429 let medKitAmount1 = if ((size(prodList) > 0))
25142430 then parseIntValue(prodList[0])
25152431 else 0
25162432 let medKitAmount2 = if ((size(prodList) > 1))
25172433 then parseIntValue(prodList[1])
25182434 else 0
25192435 let medKitAmount3 = if ((size(prodList) > 2))
25202436 then parseIntValue(prodList[2])
25212437 else 0
25222438 if (if (if ((medKitAmount1 > 0))
25232439 then true
25242440 else (medKitAmount2 > 0))
25252441 then true
25262442 else (medKitAmount3 > 0))
25272443 then throw("You have to use own Medical Kit")
25282444 else {
25292445 let existStr = getString(economyContract, keyEsWarehouse())
25302446 let existAmounts = if (isDefined(existStr))
25312447 then split_4C(value(existStr), "_")
25322448 else nil
25332449 let existAmount = if ((size(existAmounts) > 0))
25342450 then parseIntValue(existAmounts[0])
25352451 else 0
25362452 if ((0 >= existAmount))
25372453 then throw("There are no Medical Kits L1 at Emergency Service storage")
25382454 else {
25392455 let newHealth = (oldHealth + parseIntValue(split(productionMatrix[0], "_")[rIdxEffect]))
25402456 let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
25412457 let recipe = split(productionMatrix[0], "_")
25422458 let totalMat = getRecipeMaterials(recipe)
25432459 let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
25442460 if ((pmt.amount != sellPrice))
25452461 then throw(("Payment attached should be " + toString(sellPrice)))
25462462 else {
25472463 let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
25482464 $Tuple2(((prologActions :+ IntegerEntry(keyHealth, newHealth)) ++ updateDuckStatsInternal(duckAssetId, xpCallES)._1), result)
25492465 }
25502466 }
25512467 }
25522468 }
25532469 }
25542470 }
25552471 }
25562472 }
25572473
25582474
25592475
25602476 @Callable(i)
25612477 func updateBackpack (duckAssetId,newPack) = if ((i.caller != economyContract))
25622478 then throw("permission denied")
25632479 else $Tuple2([StringEntry(keyBackpackByDuck(duckAssetId), newPack)], newPack)
25642480
25652481
25662482
25672483 @Callable(i)
25682484 func commitForRandom () = {
25692485 let prologActions = prolog(i)
25702486 let finishBlock = (height + randomDelay)
25712487 let addr = toString(i.caller)
25722488 $Tuple2(([IntegerEntry(keyCommit(addr), finishBlock)] ++ prologActions), finishBlock)
25732489 }
25742490
25752491
25762492
25772493 @Callable(i)
25782494 func revealRandom (maxValue) = {
25792495 let prologActions = prolog(i)
25802496 let addr = toString(i.caller)
25812497 let finishKey = keyCommit(addr)
25822498 let finishBlock = valueOrErrorMessage(getInteger(finishKey), "You have to commitForRandom() first!")
25832499 if ((finishBlock > height))
25842500 then throw(("Random number is not ready yet, wait until height = " + toString(finishBlock)))
25852501 else {
25862502 let entropy = value(value(blockInfoByHeight(finishBlock)).vrf)
25872503 let salt = toBytes(valueOrElse(getString(keyLastTxIdByUser(addr)), ""))
25882504 let rand = getRandomNumber(maxValue, salt, entropy)
25892505 $Tuple2(([DeleteEntry(finishKey)] ++ prologActions), rand)
25902506 }
25912507 }
25922508
25932509
25942510
25952511 @Callable(i)
25962512 func buySLand () = {
25972513 let prologActions = prolog(i)
25982514 if ((size(i.payments) != 1))
25992515 then throw("Exactly one payment required")
26002516 else {
26012517 let pmt = value(i.payments[0])
26022518 if ((pmt.assetId != usdtAssetId))
26032519 then throw("Allowed USDT payment only!")
26042520 else if ((pmt.amount != EXPUSDT))
26052521 then throw(("Payment attached should be " + toString(EXPUSDT)))
26062522 else {
26072523 let result = expeditionInternal(i.caller, i.transactionId)
26082524 let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
26092525 $Tuple2((((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) ++ prologActions), $Tuple2(result._2._1, acresResult))
26102526 }
26112527 }
26122528 }
26132529
26142530
26152531
26162532 @Callable(i)
26172533 func expedition (message,sig) = {
26182534 let prologActions = prolog(i)
26192535 if ((size(i.payments) != 0))
26202536 then throw("No payments required")
26212537 else {
26222538 let userAddr = toString(i.caller)
26232539 let f = flightCommon(userAddr, message, sig)
26242540 let duckAssetId = f._2
26252541 let keyHealth = keyDuckHealth(duckAssetId)
26262542 let bpKey = keyBackpackByDuck(duckAssetId)
26272543 let currentPack = getBackpack(bpKey)
26282544 let mList = split(currentPack[bpIdxMat], "_")
26292545 let newMat = makeString(subtractMaterials(true, mList, EXPMATERIALS), "_")
26302546 let eqKey = keyDuckEquipment(duckAssetId)
26312547 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2632- let $t07588775984 = subtractEquipment(currentEq, f._5)
2633- let newEq = $t07588775984._1
2634- let shouldZeroBuffs = $t07588775984._2
2548+ let $t07623176337 = subtractEquipment(currentEq, f._5)
2549+ let newEq = $t07623176337._1
2550+ let shouldZeroBuffs = $t07623176337._2
2551+ let ignored = $t07623176337._3
26352552 let e = expeditionInternal(i.caller, i.transactionId)
26362553 let id = e._2._1
26372554 let result = if ((0 >= f._1))
26382555 then $Tuple3([IntegerEntry(keyHealth, 0), StringEntry(eqKey, newEq)], "", 0)
26392556 else $Tuple3((e._1 ++ (if (shouldZeroBuffs)
26402557 then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
26412558 else ((((nil :+ StringEntry(keyDuckLocation(duckAssetId), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, f._1)) :+ StringEntry(eqKey, newEq)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))))), id, f._3)
26422559 if (checkTournament(duckAssetId))
26432560 then throw("expedition_checkTournament")
26442561 else {
26452562 let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
26462563 $Tuple2(((result._1 ++ updateDuckStatsInternal(duckAssetId, xpNewSLand)._1) ++ prologActions), $Tuple3(result._2, result._3, acresResult))
26472564 }
26482565 }
26492566 }
26502567
26512568
26522569
26532570 @Callable(i)
26542571 func buySLandForAcres () = {
26552572 let prologActions = prolog(i)
26562573 if ((size(i.payments) != 1))
26572574 then throw("exactly 1 payment must be attached")
26582575 else {
26592576 let pmt = i.payments[0]
26602577 let amt = pmt.amount
26612578 if (if (!(isDefined(pmt.assetId)))
26622579 then true
26632580 else (value(pmt.assetId) != acresAssetId))
26642581 then throw("ACRES payments only!")
26652582 else if ((amt != S_COST_ACRES))
26662583 then throw(("Payment attached should be " + toString(S_COST_ACRES)))
26672584 else {
26682585 let result = expeditionInternal(i.caller, i.transactionId)
26692586 let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], [AttachedPayment(acresAssetId, amt)]))
26702587 $Tuple2(((result._1 ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) ++ prologActions), $Tuple2(result._2._1, acresResult))
26712588 }
26722589 }
26732590 }
26742591
26752592
26762593
26772594 @Callable(i)
26782595 func upgradeInfra (landAssetId) = {
26792596 let prologActions = prolog(i)
26802597 if ((size(i.payments) != 0))
26812598 then throw("No payments required")
26822599 else {
26832600 let result = upInfraCommon(true, i.caller, 0, landAssetId)
26842601 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
26852602 $Tuple2(((result._1 ++ prologActions) ++ updateDuckStatsInternal(duckAssetId, fraction(xpUpgradeInfra, result._3, MULT8))._1), result._2)
26862603 }
26872604 }
26882605
26892606
26902607
26912608 @Callable(i)
26922609 func activateArtifact (artName,landAssetIdOpt) = {
26932610 let prologActions = prolog(i)
26942611 if ((size(i.payments) != 0))
26952612 then throw("No payments required")
26962613 else {
26972614 let addr = toString(i.caller)
26982615 let result = match artName {
26992616 case _ =>
27002617 if (("PRESALE" == $match0))
27012618 then activatePresaleArt(addr, landAssetIdOpt)
27022619 else if (("ONBOARD" == $match0))
27032620 then activateOnboardArt(addr)
27042621 else throw("Unknown artifact")
27052622 }
27062623 (result ++ prologActions)
27072624 }
27082625 }
27092626
27102627
27112628
27122629 @Callable(i)
27132630 func mergeLands (landAssetIds) = {
27142631 let prologActions = prolog(i)
27152632 if ((size(i.payments) != 0))
27162633 then throw("No payments required")
27172634 else {
27182635 let result = mergeCommon(toString(i.caller), landAssetIds)
27192636 $Tuple2(((result._1 ++ prologActions) ++ updateAccStatsInternal(toString(i.caller), xpMerge)._1), result._2)
27202637 }
27212638 }
27222639
27232640
27242641
27252642 @Callable(i)
27262643 func cargoExchange (cargoListStr,landAssetId) = {
27272644 let prologActions = prolog(i)
27282645 if ((size(i.payments) != 0))
27292646 then throw("No payments required")
27302647 else {
27312648 let cargoParts = split_4C(cargoListStr, ":")
27322649 let addr = toString(i.originCaller)
27332650 let asset = value(assetInfo(fromBase58String(landAssetId)))
27342651 let timeKey = keyStakedTimeByAssetId(landAssetId)
27352652 if (!(isDefined(getInteger(timeKey))))
27362653 then throw((asset.name + " is not staked"))
27372654 else {
27382655 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
27392656 if ((owner != addr))
27402657 then throw((LANDPREFIX + " is not yours"))
27412658 else {
27422659 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
27432660 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
27442661 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
27452662 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
27462663 let loc = split(value(curLocation), "_")
27472664 if ((loc[locIdxType] != "L"))
27482665 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
27492666 else if ((loc[locIdxId] != landAssetId))
27502667 then throw(("Duck should be on the land " + landAssetId))
27512668 else {
27522669 let whKey = keyWarehouseByLand(landAssetId)
27532670 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
27542671 let bpKey = keyBackpackByDuck(duckAssetId)
27552672 let currentPack = getBackpack(bpKey)
27562673 let result = moveStuff(cargoParts, currentWh, currentPack)
27572674 let loft = split(currentWh[whIdxLOFT], "_")
27582675 let loftO = (parseIntValue(loft[volOccupied]) + result._7)
27592676 let loftF = (parseIntValue(loft[volFree]) - result._7)
27602677 ([StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], result._4, result._5, result._6], ":")), StringEntry(whKey, makeString_2C([currentWh[whIdxLevels], result._1, result._2, result._3, makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")], ":"))] ++ prologActions)
27612678 }
27622679 }
27632680 }
27642681 }
27652682 }
27662683
27672684
27682685
27692686 @Callable(i)
27702687 func saveWarehouse (whStr,landAssetId) = if ((i.caller != economyContract))
27712688 then throw("Access denied")
27722689 else {
27732690 let whKey = keyWarehouseByLand(landAssetId)
27742691 let wh = split_4C(whStr, ":")
27752692 if ((size(wh) != 5))
27762693 then throw("warehouse string should contain 4 ':' separators")
27772694 else {
27782695 let loftL = split(wh[whIdxLOFT], "_")[volLocked]
27792696 let loftO = getWarehouseOccupiedVol(wh)
27802697 let loftT = getWarehouseTotalVolume(wh[whIdxLevels])
27812698 let loftF = ((loftT - parseIntValue(loftL)) - loftO)
27822699 if ((0 > loftF))
27832700 then throw("Operation leads to negative free warehouse space")
27842701 else {
27852702 let newWhStr = makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], wh[whIdxProd], makeString([loftL, toString(loftO), toString(loftF), toString(loftT)], "_")], ":")
27862703 $Tuple2([StringEntry(whKey, newWhStr)], newWhStr)
27872704 }
27882705 }
27892706 }
27902707
27912708
27922709
27932710 @Callable(i)
27942711 func setCustomName (assetId,customName,type) = {
27952712 let prologActions = prolog(i)
27962713 if ((size(i.payments) != 1))
27972714 then throw("Exactly one payment required")
27982715 else {
27992716 let pmt = value(i.payments[0])
28002717 if ((pmt.assetId != usdtAssetId))
28012718 then throw("Allowed USDT payment only!")
28022719 else if ((pmt.amount != RENAMINGCOST))
28032720 then throw(("Payment should be " + toString(RENAMINGCOST)))
28042721 else if (contains(customName, "__"))
28052722 then throw(("Name should not contain '__': " + customName))
28062723 else if ((size(customName) > MAXNAMELEN))
28072724 then throw(("Name too long, maxLength=" + toString(MAXNAMELEN)))
28082725 else {
28092726 let addr = toString(i.originCaller)
28102727 let actions = match type {
28112728 case _ =>
28122729 if (("ACCOUNT" == $match0))
28132730 then {
28142731 let reverseKey = keyCustomNameToAddress(customName)
28152732 let nameOwner = getString(reverseKey)
28162733 if (isDefined(nameOwner))
28172734 then throw(("Name already registered: " + customName))
28182735 else {
28192736 let addrToNameKey = keyAddressToCustomName(addr)
28202737 let oldName = getString(addrToNameKey)
28212738 let freeOld = if (isDefined(oldName))
28222739 then [DeleteEntry(keyCustomNameToAddress(value(oldName)))]
28232740 else nil
28242741 (((freeOld :+ StringEntry(addrToNameKey, customName)) :+ StringEntry(reverseKey, addr)) ++ updateAccStatsInternal(addr, xpCustomName)._1)
28252742 }
28262743 }
28272744 else if (("LAND" == $match0))
28282745 then {
28292746 let asset = value(assetInfo(fromBase58String(assetId)))
28302747 let timeKey = keyStakedTimeByAssetId(assetId)
28312748 if (!(isDefined(getInteger(timeKey))))
28322749 then throw((asset.name + " is not staked"))
28332750 else {
28342751 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
28352752 if ((owner != addr))
28362753 then throw((LANDPREFIX + " is not yours"))
28372754 else {
28382755 let reverseKey = keyLandCustomNameToAssetId(customName)
28392756 let nameOwner = getString(reverseKey)
28402757 if (isDefined(nameOwner))
28412758 then throw(("Name already registered: " + customName))
28422759 else {
28432760 let assetToNameKey = keyLandAssetIdToCustomName(assetId)
28442761 let oldName = getString(assetToNameKey)
28452762 let freeOld = if (isDefined(oldName))
28462763 then [DeleteEntry(keyLandCustomNameToAssetId(value(oldName)))]
28472764 else nil
28482765 (((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId)) ++ updateAccStatsInternal(addr, xpCustomName)._1)
28492766 }
28502767 }
28512768 }
28522769 }
28532770 else if (("DUCK" == $match0))
28542771 then {
28552772 let asset = value(assetInfo(fromBase58String(assetId)))
28562773 let timeKey = keyStakedTimeByAssetId(assetId)
28572774 if (if (!(isDefined(getInteger(timeKey))))
28582775 then true
28592776 else !(isDefined(getString(keyStakedDuckByOwner(addr)))))
28602777 then throw((asset.name + " is not staked"))
28612778 else {
28622779 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
28632780 if ((owner != addr))
28642781 then throw((DUCKPREFIX + " is not yours"))
28652782 else {
28662783 let reverseKey = keyDuckCustomNameToAssetId(customName)
28672784 let nameOwner = getString(reverseKey)
28682785 if (isDefined(nameOwner))
28692786 then throw(("Name already registered: " + customName))
28702787 else {
28712788 let assetToNameKey = keyDuckAssetIdToCustomName(assetId)
28722789 let oldName = getString(assetToNameKey)
28732790 let freeOld = if (isDefined(oldName))
28742791 then [DeleteEntry(keyDuckCustomNameToAssetId(value(oldName)))]
28752792 else nil
28762793 (((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId)) ++ updateDuckStatsInternal(assetId, xpCustomName)._1)
28772794 }
28782795 }
28792796 }
28802797 }
28812798 else throw("Unknown entity type")
28822799 }
28832800 $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ prologActions), 0)
28842801 }
28852802 }
28862803 }
28872804
28882805
28892806
28902807 @Callable(i)
28912808 func setReferrals (oldPlayer,newPlayer) = if ((i.callerPublicKey != pub))
28922809 then throw("Permission denied")
28932810 else {
28942811 let prologActions = prolog(i)
28952812 if ((size(i.payments) != 0))
28962813 then throw("No payments required")
28972814 else if (!(isDefined(addressFromString(oldPlayer))))
28982815 then throw(("Invalid address: " + oldPlayer))
28992816 else {
29002817 let newbieAddr = addressFromString(newPlayer)
29012818 if (!(isDefined(newbieAddr)))
29022819 then throw(("Invalid address: " + newPlayer))
29032820 else {
29042821 let oldLastTx = getString(keyLastTxIdByUser(oldPlayer))
29052822 if (!(isDefined(oldLastTx)))
29062823 then throw("oldPlayer didn't do any tx in game")
29072824 else if ((0 >= wavesBalance(value(newbieAddr)).available))
29082825 then throw("newPlayer has no WAVES")
29092826 else {
29102827 let oldsKey = keyOldies()
29112828 let olds = getString(oldsKey)
29122829 let oldies = if (isDefined(olds))
29132830 then split_4C(value(olds), "_")
29142831 else nil
29152832 if (containsElement(oldies, newPlayer))
29162833 then throw((newPlayer + " is not newbie (already has referrals)"))
29172834 else {
29182835 let refByKey = keyAddressRefBy(newPlayer)
29192836 let refBy = getString(refByKey)
29202837 if (if (isDefined(refBy))
29212838 then isDefined(addressFromString(value(refBy)))
29222839 else false)
29232840 then throw(((newPlayer + " already has refBy: ") + value(refBy)))
29242841 else {
29252842 let refsKey = keyAddressReferrals(oldPlayer)
29262843 let refs = getString(refsKey)
29272844 let refsArray = if (isDefined(refs))
29282845 then split_4C(value(refs), "_")
29292846 else nil
29302847 if (containsElement(refsArray, newPlayer))
29312848 then throw((((oldPlayer + " already contains ") + newPlayer) + " within referrals"))
29322849 else {
29332850 let newRefs = makeString_2C((refsArray :+ newPlayer), "_")
29342851 let newOlds = if (containsElement(oldies, oldPlayer))
29352852 then value(olds)
29362853 else makeString_2C((oldies :+ oldPlayer), "_")
29372854 $Tuple2(([StringEntry(refByKey, oldPlayer), StringEntry(refsKey, newRefs), StringEntry(oldsKey, newOlds)] ++ prologActions), 0)
29382855 }
29392856 }
29402857 }
29412858 }
29422859 }
29432860 }
29442861 }
29452862
29462863
29472864
29482865 @Callable(i)
29492866 func distributePoints (strength,accuracy,intellect,endurance,dexterity) = {
29502867 let prologActions = prolog(i)
29512868 if ((size(i.payments) != 0))
29522869 then throw("No payments required")
29532870 else {
29542871 let addr = toString(i.originCaller)
29552872 let virtWlgData = asAnyList(invoke(wlgContract, "checkWlgXpREADONLY", [addr], nil))
29562873 let virtWlgPoints = asInt(virtWlgData[1])
2957- let $t09179692186 = if ((0 >= virtWlgPoints))
2874+ let $t09214992539 = if ((0 >= virtWlgPoints))
29582875 then $Tuple2(0, nil)
29592876 else {
29602877 let deltaXP = asInt(invoke(wlgContract, "takeWlgXp", [addr], nil))
29612878 if ((deltaXP == deltaXP))
29622879 then $Tuple2(virtWlgPoints, [IntegerEntry(keyUserLevel(addr), asInt(virtWlgData[0])), IntegerEntry(keyUserXP(addr), asInt(virtWlgData[2]))])
29632880 else throw("Strict value is not equal to itself.")
29642881 }
2965- let wlgPoints = $t09179692186._1
2966- let wlgActions = $t09179692186._2
2882+ let wlgPoints = $t09214992539._1
2883+ let wlgActions = $t09214992539._2
29672884 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
29682885 let freeKeyAcc = keyUserFreePoints(addr)
29692886 let freePointsAcc = (valueOrElse(getInteger(freeKeyAcc), 0) + wlgPoints)
29702887 let freeKeyDuck = keyDuckFreePoints(duckAssetId)
29712888 let freePointsDuck = valueOrElse(getInteger(freeKeyDuck), 0)
29722889 let sumFree = (freePointsAcc + freePointsDuck)
29732890 let sumToDistribute = ((((strength + accuracy) + intellect) + endurance) + dexterity)
29742891 if ((sumToDistribute > sumFree))
29752892 then throw((("There are only " + toString(sumFree)) + " free points to distribute"))
29762893 else {
29772894 let charsKey = keyDuckChars(duckAssetId)
29782895 let chars = split(valueOrElse(getString(charsKey), "0_0_0_0_0"), "_")
29792896 let newAcc = (freePointsAcc - sumToDistribute)
29802897 $Tuple2((([IntegerEntry(freeKeyAcc, if ((0 > newAcc))
29812898 then 0
29822899 else newAcc), IntegerEntry(freeKeyDuck, if ((0 > newAcc))
29832900 then (freePointsDuck + newAcc)
29842901 else freePointsDuck), StringEntry(charsKey, makeString([toString((parseIntValue(chars[charStrength]) + strength)), toString((parseIntValue(chars[charAccuracy]) + accuracy)), toString((parseIntValue(chars[charIntellect]) + intellect)), toString((parseIntValue(chars[charEndurance]) + endurance)), toString((parseIntValue(chars[charDexterity]) + dexterity))], "_"))] ++ prologActions) ++ wlgActions), 0)
29852902 }
29862903 }
29872904 }
29882905
29892906
29902907
29912908 @Callable(i)
29922909 func splitByGlobalWeightsREADONLY (amount) = $Tuple2(nil, getNeededMaterials(amount))
29932910
29942911
29952912
29962913 @Callable(i)
29972914 func splitByGlobalAndLocalWeightsREADONLY (matAmount,resAmount,terrains) = {
29982915 let terrainCounts = countTerrains(terrains)
29992916 $Tuple2(nil, $Tuple2(getNeededMaterials(matAmount), distributeByWeights(resAmount, terrainCounts)))
30002917 }
30012918
30022919
30032920
30042921 @Callable(i)
30052922 func getBackpackREADONLY (duckAssetId) = $Tuple2(nil, makeString(getBackpack(keyBackpackByDuck(duckAssetId)), ":"))
30062923
30072924
30082925
30092926 @Callable(i)
30102927 func getWarehouseREADONLY (landAssetId) = {
30112928 let asset = value(assetInfo(fromBase58String(landAssetId)))
30122929 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
30132930 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
30142931 $Tuple2(nil, makeString_2C(getWarehouse(keyWarehouseByLand(landAssetId), landIndex, infraLevel), ":"))
30152932 }
30162933
30172934
30182935
30192936 @Callable(i)
30202937 func saveLastTx () = if (!(containsElement([wlgContract, economyContract, tournamentContract, acresContract], i.caller)))
30212938 then throw("Access denied")
30222939 else $Tuple2(prolog(i), 42)
30232940
30242941
30252942
30262943 @Callable(i)
30272944 func updateDuckStats (duckAssetId,deltaXP) = if ((i.caller != economyContract))
30282945 then throw("Access denied")
30292946 else updateDuckStatsInternal(duckAssetId, deltaXP)
30302947
30312948
30322949
30332950 @Callable(i)
30342951 func updateAccStats (addr,deltaXP) = if (!(containsElement([wlgContract, economyContract, acresContract], i.caller)))
30352952 then throw("Access denied")
30362953 else updateAccStatsInternal(addr, deltaXP)
30372954
30382955
30392956
30402957 @Callable(i)
30412958 func equipDuck (equipment) = {
30422959 let prologActions = prolog(i)
30432960 if ((size(i.payments) != 0))
30442961 then throw("No payments required")
30452962 else {
30462963 let addr = toString(i.originCaller)
30472964 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
30482965 if (checkTournament(duckAssetId))
30492966 then throw("equipDuck_checkTournament")
30502967 else {
30512968 let eqKey = keyDuckEquipment(duckAssetId)
30522969 let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
30532970 let bpKey = keyBackpackByDuck(duckAssetId)
30542971 let currentPack = getBackpack(bpKey)
30552972 let newEq = split(equipment, "_")
30562973 if ((size(newEq) != NUMSEGMENTS))
30572974 then throw("Wrong equipment string")
30582975 else {
30592976 let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
30602977 let segBpAux = split(newEq[segBackpack], ";")[1]
30612978 let buffEffect = if ((segBpAux == ""))
30622979 then 0
30632980 else {
30642981 let aux0 = split(segBpAux, ",")[0]
30652982 if ((aux0 == ""))
30662983 then 0
30672984 else {
30682985 let idxCnt = split(aux0, ":")
30692986 let idx = idxCnt[0]
30702987 let cnt = idxCnt[1]
30712988 if (if (if (if (if ((idx == "06"))
30722989 then true
30732990 else (idx == "07"))
30742991 then true
30752992 else (idx == "08"))
30762993 then (cnt != "")
30772994 else false)
30782995 then (parseIntValue(cnt) > 0)
30792996 else false)
30802997 then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
30812998 else 0
30822999 }
30833000 }
30843001 let stats = getDuckStats(this, duckAssetId, buffEffect, true)
30853002 let newProdB = dressB(newEq, tempProdB, false, stats)
30863003 let newProdStr = bytesToProdStr(newProdB)
30873004 $Tuple2(([StringEntry(eqKey, equipment), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProdStr], ":")), StringEntry(keyDuckBuffs(duckAssetId), makeString([toString(stats[7]), toString(stats[8]), toString(stats[9]), toString(stats[10]), toString(stats[11])], "_"))] ++ prologActions), 0)
30883005 }
30893006 }
30903007 }
30913008 }
30923009
30933010
30943011
30953012 @Callable(i)
3096-func fortificateLand (landAssetId,plan) = {
3097- let prologActions = prolog(i)
3098- if ((size(i.payments) != 0))
3099- then throw("No payments required")
3100- else {
3101- let addr = toString(i.originCaller)
3102- let duckAssetId = valueOrElse(getString(keyStakedDuckByOwner(addr)), "")
3103- let duckStats = getDuckStats(this, duckAssetId, 0, false)
3104- let fortKey = keyFortificationsByLand(landAssetId)
3105- let currentForts = split(valueOrElse(getString(fortKey), ":0_15:0_18:0"), "_")
3106- let asset = value(assetInfo(fromBase58String(landAssetId)))
3107- let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
3108- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
3109- let whKey = keyWarehouseByLand(landAssetId)
3110- let wh = getWarehouse(whKey, landIndex, infraLevel)
3111- let curLoft = split(wh[whIdxLOFT], "_")
3112- let curO = parseIntValue(curLoft[volOccupied])
3113- let curF = parseIntValue(curLoft[volFree])
3114- let newForts = split(plan, "_")
3115- let $t09894799062 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3116- let tempProdB = $t09894799062._1
3117- let tempO = $t09894799062._2
3118- let tempF = $t09894799062._3
3119- let $t09906599161 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3120- let newProdB = $t09906599161._1
3121- let newO = $t09906599161._2
3122- let newF = $t09906599161._3
3123- let newProdStr = bytesToProdStr(newProdB)
3124- let newLoftStr = makeString([curLoft[volLocked], toString(newO), toString(newF), curLoft[volTotal]], "_")
3125- $Tuple2(([StringEntry(fortKey, plan), StringEntry(whKey, makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], newProdStr, newLoftStr], ":"))] ++ prologActions), 0)
3126- }
3127- }
3128-
3129-
3130-
3131-@Callable(i)
31323013 func initDuckTourAttempt (duckAssetId) = if ((i.caller != tournamentContract))
31333014 then throw("Access denied")
31343015 else {
31353016 let keyHealth = keyDuckHealth(duckAssetId)
31363017 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
31373018 let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
31383019 let curLocKey = keyDuckLocation(duckAssetId)
31393020 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
31403021 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
31413022 let tourLocation = (toString(lastId) + "_T_0")
31423023 $Tuple2([IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, tourLocation)], tourLocation)
31433024 }
31443025
31453026
31463027
31473028 @Callable(i)
31483029 func breakAttempt () = {
31493030 let prologActions = prolog(i)
31503031 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
31513032 let curLocKey = keyDuckLocation(duckAssetId)
31523033 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
31533034 if ((split(curLocation, "_")[locIdxType] != "T"))
31543035 then throw("Your duck is not in the tournament")
31553036 else {
31563037 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
31573038 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
31583039 $Tuple2(((prologActions :+ IntegerEntry(keyDuckHealth(duckAssetId), savedHealth)) :+ StringEntry(curLocKey, savedLocation)), curLocation)
31593040 }
31603041 }
31613042
31623043
31633044
31643045 @Callable(i)
31653046 func breakAttemptCallback () = if ((i.caller != tournamentContract))
31663047 then throw("Access denied")
31673048 else {
31683049 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.originCaller))), "You don't have a duck staked")
31693050 $Tuple2([IntegerEntry(keyDuckHealth(duckAssetId), getIntegerValue(keySavedHealth(duckAssetId))), StringEntry(keyDuckLocation(duckAssetId), getStringValue(keySavedLocation(duckAssetId)))], "breakAttemptCallback")
31703051 }
31713052
31723053
31733054
31743055 @Callable(i)
31753056 func exitTournamentInternal (duckAssetId) = if ((i.caller != this))
31763057 then throw("Access denied")
31773058 else {
31783059 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
31793060 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
31803061 $Tuple2([IntegerEntry(keyDuckHealth(duckAssetId), savedHealth), StringEntry(keyDuckLocation(duckAssetId), savedLocation)], false)
31813062 }
31823063
31833064
31843065
31853066 @Callable(i)
31863067 func processDelivery (duckAssetId) = if ((i.caller != this))
31873068 then throw("Access denied")
31883069 else {
31893070 let addr = toString(i.originCaller)
31903071 let fundTotal = valueOrElse(getInteger(economyContract, deliveryFundKey), 0)
31913072 if ((MIN_USDT_FEE_DELIVERY > fundTotal))
31923073 then throw(("Delivery is not available, fund=" + fixedPoint(fundTotal, 6)))
31933074 else {
31943075 let now = lastBlock.timestamp
31953076 let countKey = keyUserDeliveryCount(addr)
31963077 let lastDay = valueOrElse(getInteger(keyUserLastDeliveryDay(addr)), 0)
31973078 let today = (now / DAYMILLIS)
31983079 let count = if ((lastDay == today))
31993080 then valueOrElse(getInteger(countKey), 0)
32003081 else 0
32013082 let acres = valueOrElse(getInteger(acresContract, keyAcresStakedAmountByUser(addr)), 0)
32023083 let allowedDeliveries = (ALLOWED_FREE_DELIVERIES + (acres / ACRES_FOR_DELIVERY_ATTEMPT))
32033084 if ((count >= allowedDeliveries))
32043085 then throw((("You already used " + toString(allowedDeliveries)) + " delivery attempts for today"))
32053086 else {
32063087 let globalCountKey = keyDuckDeliveryCount(duckAssetId)
32073088 let reward = invoke(economyContract, "sendDeliveryReward", [addr], nil)
32083089 $Tuple2([IntegerEntry(countKey, (count + 1)), IntegerEntry(keyUserLastDeliveryDay(addr), today), IntegerEntry(globalCountKey, (valueOrElse(getInteger(globalCountKey), 0) + 1))], reward)
32093090 }
32103091 }
32113092 }
32123093
32133094
32143095
32153096 @Callable(i)
3216-func prepareRobbery (message,sig) = {
3097+func robLand (message,sig) = {
32173098 let prologActions = prolog(i)
3218- if (!(sigVerify_8Kb(message, sig, pub)))
3219- then throw("signature does not match")
3220- else if ((size(i.payments) != 1))
3221- then throw("exactly 1 payment must be attached")
3222- else {
3223- let pmt = i.payments[0]
3224- let wlgAmt = pmt.amount
3225- if (if (!(isDefined(pmt.assetId)))
3226- then true
3227- else (value(pmt.assetId) != wlgAssetId))
3228- then throw("WLGOLD payments only!")
3099+ if ((size(i.payments) != 1))
3100+ then throw("exactly 1 payment must be attached")
3101+ else {
3102+ let pmt = i.payments[0]
3103+ let wlgAmt = pmt.amount
3104+ if (if (!(isDefined(pmt.assetId)))
3105+ then true
3106+ else (value(pmt.assetId) != wlgAssetId))
3107+ then throw("WLGOLD payments only!")
3108+ else if ((wlgAmt != MIN_WLGOLD_ROBBERY))
3109+ then throw((("Payment should be " + fixedPoint(MIN_WLGOLD_ROBBERY, 8)) + " WLGOLD"))
32293110 else {
3230- let parts = split(toUtf8String(message), "|")
3231- if ((2 > size(parts)))
3232- then throw("Wrong message format")
3111+ let addr = toString(i.caller)
3112+ if (!(sigVerify_8Kb(message, sig, pub)))
3113+ then throw("signature does not match")
32333114 else {
3234- let txFromMsg = if ((size(parts) >= 2))
3235- then parts[2]
3236- else ""
3237- let userAddr = toString(i.caller)
3238- let lastTx = valueOrElse(getString(keyLastTxIdByUser(userAddr)), "")
3239- if ((lastTx != txFromMsg))
3240- then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
3115+ let parts = split_4C(toUtf8String(message), ";")
3116+ let robLog = split_4C(parts[0], "|")
3117+ let hp = split(robLog[rlHealth], "_")
3118+ let curHP = parseIntValue(hp[0])
3119+ let newHP = parseIntValue(hp[1])
3120+ let prodUsed = robLog[rlProdsUsed]
3121+ let lastPart = split(parts[1], "|")
3122+ let robType = lastPart[rlType]
3123+ if ((robType != "B"))
3124+ then throw("Only bank robbery is supported")
32413125 else {
3242- let duckAssetId = parts[0]
3243- if (checkTournament(duckAssetId))
3244- then throw("prepareRobbery_checkTournament")
3126+ let time = parseIntValue(lastPart[rlTimestamp])
3127+ if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
3128+ then true
3129+ else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
3130+ then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
32453131 else {
3246- let robCost = getRobberyData(this, duckAssetId)._1
3247- if ((robCost > wlgAmt))
3248- then throw(((("Payment " + toString(wlgAmt)) + " < required ") + toString(robCost)))
3132+ let txFromMsg = lastPart[rlLastTx]
3133+ let lastTx = valueOrElse(getString(keyLastTxIdByUser(addr)), "")
3134+ if ((lastTx != txFromMsg))
3135+ then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
32493136 else {
3250- let candidates = split(parts[1], "_")
3251- let now = lastBlock.timestamp
3252- let duckState = valueOrElse(getInteger(keyDuckRobberyState(duckAssetId)), 0)
3253- let lockedLand = valueOrElse(getString(keyLockedLandByDuck(duckAssetId)), "")
3254- let landETA = valueOrElse(getInteger(keyLandCooldownETA(lockedLand)), 0)
3255- if (if ((duckState != duckIdxFree))
3256- then (landETA > now)
3257- else false)
3258- then throw(("You already started robbing, wait till " + toString(landETA)))
3137+ let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
3138+ let eqKey = keyDuckEquipment(duckAssetId)
3139+ let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
3140+ let $t0109717109828 = subtractEquipment(currentEq, prodUsed)
3141+ let newEq = $t0109717109828._1
3142+ let shouldZeroBuffs = $t0109717109828._2
3143+ let isBpUsed = $t0109717109828._3
3144+ let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
3145+ if (isInTournament(tournamentContract, curLocation))
3146+ then throw("Your duck is taking part in the tournament")
32593147 else {
3260- func checker (acc,landAssetId) = {
3261- let state = valueOrElse(getInteger(keyLandRobberyState(landAssetId)), 0)
3262- let cooldownETA = valueOrElse(getInteger(keyLandCooldownETA(landAssetId)), 0)
3263- if ((state > size(landRobCooldowns)))
3264- then throw("Invalid state")
3265- else if ((now > cooldownETA))
3148+ let now = lastBlock.timestamp
3149+ let countKey = keyUserRobberyCount(addr)
3150+ let lastDay = valueOrElse(getInteger(keyUserLastRobberyDay(addr)), 0)
3151+ let today = (now / DAYMILLIS)
3152+ let count = if ((lastDay == today))
3153+ then valueOrElse(getInteger(countKey), 0)
3154+ else 0
3155+ let acres = valueOrElse(getInteger(acresContract, keyAcresStakedAmountByUser(addr)), 0)
3156+ let allowedRobberies = (ALLOWED_FREE_ROBBERIES + (acres / ACRES_FOR_ROBBERY_ATTEMPT))
3157+ if ((count >= allowedRobberies))
3158+ then throw((("You already used " + toString(allowedRobberies)) + " robbery attempts for today"))
3159+ else {
3160+ let globalCountKey = keyDuckRobberyCount(duckAssetId)
3161+ let loot = if ((newHP > 0))
32663162 then {
3267- let stakedTime = valueOrElse(getInteger(keyStakedTimeByAssetId(landAssetId)), 0)
3268- if ((0 >= stakedTime))
3269- then acc
3270- else {
3271- let a = value(assetInfo(fromBase58String(landAssetId)))
3272- let d = split(a.description, "_")
3273- let pieces = numPiecesBySize(d[recLandSize])
3274- let productivity = applyBonuses(landAssetId, pieces)
3275- let deltaTime = (now - stakedTime)
3276- let availRes = fraction(deltaTime, (productivity * pieces), DAYMILLIS)
3277- if ((MIN_RES_TO_ROB > availRes))
3278- then acc
3279- else (acc :+ landAssetId)
3280- }
3163+ let fundTotal = assetBalance(this, wlgAssetId)
3164+ let prize = if (isBpUsed)
3165+ then (2 * MIN_WLGOLD_ROBBERY)
3166+ else (5 * MIN_WLGOLD_ROBBERY)
3167+ if ((prize > fundTotal))
3168+ then throw(((("Robbery is not available, funds = " + fixedPoint(fundTotal, 8)) + " WLGOLD, required = ") + fixedPoint(prize, 8)))
3169+ else [ScriptTransfer(i.caller, prize, wlgAssetId)]
32813170 }
3282- else acc
3283- }
3284-
3285- let filtered = {
3286- let $l = candidates
3287- let $s = size($l)
3288- let $acc0 = nil
3289- func $f0_1 ($a,$i) = if (($i >= $s))
3290- then $a
3291- else checker($a, $l[$i])
3292-
3293- func $f0_2 ($a,$i) = if (($i >= $s))
3294- then $a
3295- else throw("List size exceeds 10")
3296-
3297- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
3298- }
3299- if ((size(filtered) == 0))
3300- then throw("No candidates for robbery")
3301- else {
3302- let rndIdx = getRandomNumber(size(filtered), message, sig)
3303- let landAssetId = filtered[rndIdx]
3304- $Tuple2(([IntegerEntry(keyLandRobberyState(landAssetId), robIdxLocked), IntegerEntry(keyLandCooldownETA(landAssetId), (now + landRobCooldowns[robIdxLocked])), IntegerEntry(keyDuckRobberyState(duckAssetId), duckIdxPreparing), StringEntry(keyLockedLandByDuck(duckAssetId), landAssetId)] ++ prologActions), landAssetId)
3171+ else nil
3172+ $Tuple2((((((((((prologActions ++ loot) ++ (if (shouldZeroBuffs)
3173+ then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
3174+ else nil)) ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
3175+ then xpSuccessRob
3176+ else xpFailRob)._1) :+ IntegerEntry(keyLastRobberyTimeByDuck(duckAssetId), now)) :+ IntegerEntry(countKey, (count + 1))) :+ IntegerEntry(keyUserLastRobberyDay(addr), today)) :+ IntegerEntry(globalCountKey, (valueOrElse(getInteger(globalCountKey), 0) + 1))) :+ StringEntry(eqKey, newEq)) :+ IntegerEntry(keyDuckHealth(duckAssetId), max([newHP, 0]))), 0)
33053177 }
33063178 }
33073179 }
33083180 }
33093181 }
33103182 }
33113183 }
3312- }
3313- }
3314-
3315-
3316-
3317-@Callable(i)
3318-func robLand (message,sig) = {
3319- let prologActions = prolog(i)
3320- if (!(sigVerify_8Kb(message, sig, pub)))
3321- then throw("signature does not match")
3322- else {
3323- let userAddr = toString(i.caller)
3324- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
3325- let now = lastBlock.timestamp
3326- $Tuple2((prologActions :+ IntegerEntry(keyLastRobberyTimeByDuck(duckAssetId), now)), 0)
33273184 }
33283185 }
33293186
33303187
33313188
33323189 @Callable(i)
33333190 func buyRoboDuck () = if (!(KS_ALLOW_ROBO_DUCKS))
33343191 then throw("Feature is turned off")
33353192 else {
33363193 let prologActions = prolog(i)
33373194 if ((size(i.payments) != 1))
33383195 then throw("Exactly one payment required")
33393196 else {
33403197 let pmt = value(i.payments[0])
33413198 if ((pmt.assetId != usdtAssetId))
33423199 then throw("Allowed USDT payment only!")
33433200 else if ((pmt.amount != ROBO_DUCK_USDT))
33443201 then throw((("Payment attached should be " + fixedPoint(ROBO_DUCK_USDT, 6)) + " USDT"))
33453202 else {
33463203 let nextNum = valueOrElse(getInteger(keyNextRoboDuck()), 0)
33473204 let bytez = toBytes(nextNum)
33483205 let name = ((ROBO_PREFIX + "-") + takeRight(toBase16String(bytez), 8))
33493206 let color = takeRight(toBase16String(sha256_16Kb(bytez)), 6)
33503207 let issue = Issue(name, ("Robo Duck NFT for WavesLands game, background color = #" + color), 1, 0, false)
33513208 let assetId = calculateAssetId(issue)
33523209 $Tuple2(((((prologActions :+ IntegerEntry(keyNextRoboDuck(), (nextNum + 1))) :+ issue) :+ ScriptTransfer(i.originCaller, 1, assetId)) :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)), $Tuple2(toBase58String(assetId), color))
33533210 }
33543211 }
33553212 }
33563213
33573214

github/deemru/w8io/169f3d6 
272.09 ms