tx · 7MuLPdzs3qR1xJWpXbHvd6tvWFoHPm3h37WQytXpUdbU

3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm:  -0.04900000 Waves

2024.12.03 23:11 [3398924] smart account 3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm > SELF 0.00000000 Waves

{ "type": 13, "id": "7MuLPdzs3qR1xJWpXbHvd6tvWFoHPm3h37WQytXpUdbU", "fee": 4900000, "feeAssetId": null, "timestamp": 1733256700696, "version": 2, "chainId": 84, "sender": "3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm", "senderPublicKey": "EVooykMNV691Venwp1dHUTBd7KWequzUcda57Wd3LQEX", "proofs": [ "PPnZcA74rVjyGnMC5kneTyeHXtFbcyF1g7vQENG6DBhnyW3zpaNcBWkWrAmNPuNQBfHbGx4erareVHk7qhLyMKp" ], "script": "base64:BgKjAQgCEgMKAQgSBAoCCAESAwoBBBIECgIICBIECgIICBIDCgEIEgASBAoCCAgSBAoCCAgSBAoCAQgSBAoCAQgSBAoCCAgSABIDCgEBEgQKAggIEgQKAggIEgUKAwgICBIECgIICBIHCgUBAQEBARIDCgEBEgUKAwEBCBIDCgEIEgMKAQgSABIECgIIARIECgIIARIDCgEIEgASABIDCgEIEgMKAQiyAQAWS1NfU0VQQVJBVEVfUFVCTElDX0tFWQcAE0tTX0FMTE9XX1JPQk9fRFVDS1MHABRPTERfU1RBS0lOR19ERUFETElORQCAqrftuDIABWNoYWluCQDJAQIJAMoBAggFBHRoaXMFYnl0ZXMAAQABAANwdWIEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDADBRZLU19TRVBBUkFURV9QVUJMSUNfS0VZASCrF1ePFWfjWVRBsNZy62abxKPTZl7VmYZQ35g3H7IJCAEgT1PiGj9UqNadUk4THUYnVb2zU/Mse8lUVLD/Q8G0FCgDCQAAAgEBVAUHJG1hdGNoMAEgT1PiGj9UqNadUk4THUYnVb2zU/Mse8lUVLD/Q8G0FCgJAAIBAg1Vbmtub3duIGNoYWluAAt1c2R0QXNzZXRJZAQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAEghNp6sggDP07Ru8qO7ouTvMmC3Qtd+geWqNQj+agP/7kDCQAAAgEBVAUHJG1hdGNoMAEgVbHYn3KHgu/l41uNrAWrZd6aQ6EvFrsF8xq3h6XxxRgJAAIBAg1Vbmtub3duIGNoYWluABVkZWZhdWx0UmVzdEFkZHJlc3NTdHIEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDACIzNQUUN1dkZidmg0TGtQVW5yblUxejNqbmJBMXA5bTNXTmh2AwkAAAIBAVQFByRtYXRjaDACIzNNdW1rR0d6dENLQVhwV0RxeGtkZG9mcVhTVWJxUWt2U0p5CQACAQINVW5rbm93biBjaGFpbgAQYWNyZXMyQWRkcmVzc1N0cgQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAIjM1A0VUgzVDluWHBNTnBVbVNtUWpQbUV6M0c4NXQzem42ZUEDCQAAAgEBVAUHJG1hdGNoMAIjM05CUHgxRmNpdTNKUU5FR1oyMWpTblRkdXRMTkdHQlVTWGgJAAIBAg1Vbmtub3duIGNoYWluAANTRVACAl9fAAVNVUxUNgDAhD0ABU1VTFQ4AIDC1y8ABVNTSVpFABkABU1TSVpFAGQABUxTSVpFAOEBAAZYTFNJWkUAkAMAB1hYTFNJWkUA8QQABUlURVI2CQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwBD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAABFJZHhDZmdFY29ub215RGFwcAACAA1JZHhDZmdXbGdEYXBwAAQAFElkeENmZ1RvdXJuYW1lbnREYXBwAAcAD0lkeENmZ0FjcmVzRGFwcAAIAQprZXlSZXN0Q2ZnAAIOJXNfX3Jlc3RDb25maWcBDmtleVJlc3RBZGRyZXNzAAIMJXNfX3Jlc3RBZGRyARFyZWFkUmVzdENmZ09yRmFpbAEEcmVzdAkAvAkCCQEPZ2V0U3RyaW5nT3JGYWlsAgUEcmVzdAkBCmtleVJlc3RDZmcABQNTRVABGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIHcmVzdENmZwNpZHgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFB3Jlc3RDZmcFA2lkeAkArAICAipSZXN0IGNmZyBkb2Vzbid0IGNvbnRhaW4gYWRkcmVzcyBhdCBpbmRleCAJAKQDAQUDaWR4AAxyZXN0Q29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBDmtleVJlc3RBZGRyZXNzAAUVZGVmYXVsdFJlc3RBZGRyZXNzU3RyAAdyZXN0Q2ZnCQERcmVhZFJlc3RDZmdPckZhaWwBBQxyZXN0Q29udHJhY3QAD2Vjb25vbXlDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFEUlkeENmZ0Vjb25vbXlEYXBwAAt3bGdDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFDUlkeENmZ1dsZ0RhcHAAEnRvdXJuYW1lbnRDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFFElkeENmZ1RvdXJuYW1lbnREYXBwAA1hY3Jlc0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUPSWR4Q2ZnQWNyZXNEYXBwAApyZWNMYW5kTnVtAAAAC3JlY0xhbmRTaXplAAEAC3JlY1RlcnJhaW5zAAIAD2FjcmVzQXNzZXRJZEtleQIMYWNyZXNBc3NldElkAAxhY3Jlc0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnAgCBQ1hY3Jlc0NvbnRyYWN0BQ9hY3Jlc0Fzc2V0SWRLZXkCF0FDUkVTIGlzIG5vdCBpc3N1ZWQgeWV0AAtyYW5kb21EZWxheQACAQlrZXlDb21taXQBB2FkZHJlc3MJAKwCAgIPZmluaXNoQmxvY2tGb3JfBQdhZGRyZXNzARFrZXlSZXNQcm9wb3J0aW9ucwACE3Jlc1R5cGVzUHJvcG9ydGlvbnMBFWtleVN0YWtlZExhbmRzQnlPd25lcgEJb3duZXJBZGRyCQCsAgICE3N0YWtlZExhbmRzQnlPd25lcl8FCW93bmVyQWRkcgEWa2V5U3Rha2VkUGllY2VzQnlPd25lcgEJb3duZXJBZGRyCQCsAgICFHN0YWtlZFBpZWNlc0J5T3duZXJfBQlvd25lckFkZHIBBWFzSW50AQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACA0ludAQBbgUHJG1hdGNoMAUBbgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEJYXNBbnlMaXN0AQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACCUxpc3RbQW55XQQBbAUHJG1hdGNoMAUBbAkAAgECG2ZhaWwgdG8gY2FzdCBpbnRvIExpc3RbQW55XQEPbnVtUGllY2VzQnlTaXplAQhsYW5kU2l6ZQQHJG1hdGNoMAUIbGFuZFNpemUDCQAAAgIBUwUHJG1hdGNoMAUFU1NJWkUDCQAAAgIBTQUHJG1hdGNoMAUFTVNJWkUDCQAAAgIBTAUHJG1hdGNoMAUFTFNJWkUDCQAAAgICWEwFByRtYXRjaDAFBlhMU0laRQMJAAACAgNYWEwFByRtYXRjaDAFB1hYTFNJWkUJAAIBAhFVbmtub3duIGxhbmQgc2l6ZQEKa2V5QmxvY2tlZAACEGNvbnRyYWN0c0Jsb2NrZWQBFWtleUxhc3RXZWVrVHhJZEJ5VXNlcgEEYWRkcgkArAICAhNsYXN0V2Vla1R4SWRCeVVzZXJfBQRhZGRyARRrZXlDdXJXZWVrVHhJZEJ5VXNlcgEEYWRkcgkArAICAhJjdXJXZWVrVHhJZEJ5VXNlcl8FBGFkZHIBCmZpeGVkUG9pbnQCA3ZhbAhkZWNpbWFscwQGdGVuUG93CQBsBgAKAAAFCGRlY2ltYWxzAAAAAAUERE9XTgQHbG93UGFydAkApAMBCQBqAgUDdmFsBQZ0ZW5Qb3cEBnplcm9lcwkAsAICCQCkAwEFBnRlblBvdwkAZAIAAQkAsQIBBQdsb3dQYXJ0CQCsAgIJAKwCAgkArAICCQCkAwEJAGkCBQN2YWwFBnRlblBvdwIBLgUGemVyb2VzBQdsb3dQYXJ0AQ9nZXRSYW5kb21OdW1iZXIDCG1heFZhbHVlBHNhbHQHZW50cm9weQMJAGcCAAAFCG1heFZhbHVlCQACAQIWbWF4VmFsdWUgc2hvdWxkIGJlID4gMAQKcmFuZG9tSGFzaAkA1BYBCQDLAQIFBHNhbHQFB2VudHJvcHkJAGoCCQCxCQEFCnJhbmRvbUhhc2gFCG1heFZhbHVlAQlmaW5hbFRpbWUACQCXAwEJAMwIAggFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgUUT0xEX1NUQUtJTkdfREVBRExJTkUFA25pbAAKTEFORFBSRUZJWAIETEFORAAKRFVDS1BSRUZJWAIERFVDSwALUk9CT19QUkVGSVgCBFJPQk8ACkFSVFBSRVNBTEUCB1BSRVNBTEUABk5VTVJFUwAGAA9EQUlMWVJFU0JZUElFQ0UAgPjSAQAMV0hNVUxUSVBMSUVSAIDIr6AlAA9ERUZBVUxUTE9DQVRJT04CD0FmcmljYV9GX0FmcmljYQAQUkVTT1VSQ0VQUklDRU1JTgDVtQIAFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQDQhgMAFVVTRFQyQUNSRVNfTVVMVElQTElFUgAKABdBTExPV0VEX0ZSRUVfREVMSVZFUklFUwAAABpBQ1JFU19GT1JfREVMSVZFUllfQVRURU1QVACAhK9fAAlwcm9kVHlwZXMJAMwIAgIQRmlyc3QgQWlkIEtpdCBMMQkAzAgCAhBGaXJzdCBBaWQgS2l0IEwyCQDMCAICEEZpcnN0IEFpZCBLaXQgTDMJAMwIAgILQmFja3BhY2sgTDEJAMwIAgILQmFja3BhY2sgTDIJAMwIAgILQmFja3BhY2sgTDMJAMwIAgIORm9vZCBSYXRpb24gTDEJAMwIAgIORm9vZCBSYXRpb24gTDIJAMwIAgIORm9vZCBSYXRpb24gTDMJAMwIAgILSmV0IFBhY2sgTDEJAMwIAgILSmV0IFBhY2sgTDIJAMwIAgILSmV0IFBhY2sgTDMJAMwIAgIJU2hpZWxkIEwxCQDMCAICCVNoaWVsZCBMMgkAzAgCAglTaGllbGQgTDMJAMwIAgIHTWluZSBMMQkAzAgCAgdNaW5lIEwyCQDMCAICB01pbmUgTDMJAMwIAgIHVHJhcCBMMQkAzAgCAgdUcmFwIEwyCQDMCAICB1RyYXAgTDMJAMwIAgILQm9vbS1Eb2cgTDEJAMwIAgILQm9vbS1Eb2cgTDIJAMwIAgILQm9vbS1Eb2cgTDMFA25pbAAQcHJvZHVjdGlvbk1hdHJpeAkAzAgCAiU4XzhfOF8xN18xN180Ml8xMl8wXzMwXzAsMCwwLDAsMCwwLDBfCQDMCAICJThfOF84XzE3XzE3XzQyXzI0XzBfNjBfMCwwLDUsMiwwLDAsMF8JAMwIAgInOF84XzhfMTdfMTdfNDJfMzZfMF8xMjBfMCwwLDEwLDQsMCwwLDBfCQDMCAICKThfMTlfMTlfOF8yN18xOV8yNl8xXzIwXzAsMCwwLDAsMCwwLDBfMDAxCQDMCAICKThfMTlfMTlfOF8yN18xOV81Ml8xXzQwXzAsMCwwLDAsMCwwLDBfMDAxCQDMCAICKThfMTlfMTlfOF8yN18xOV83OF8xXzgwXzAsMCwwLDAsMCwwLDBfMDAxCQDMCAICJThfOF84XzhfOF82MF8xM18yXzJfMCwwLDAsMCwwLDAsMF8wMTEJAMwIAgIlOF84XzhfOF84XzYwXzI2XzJfNF8wLDAsMCwwLDAsMCwwXzAxMQkAzAgCAiU4XzhfOF84XzhfNjBfMzlfMl84XzAsMCwwLDAsMCwwLDBfMDExCQDMCAICKTMwXzMwXzNfMTdfMTdfM18zMF8zXzMwXzAsMCwwLDAsMCwwLDBfMTExCQDMCAICKTMwXzMwXzNfMTdfMTdfM182MF8zXzUwXzAsMCwwLDAsMCwwLDBfMTExCQDMCAICKTMwXzMwXzNfMTdfMTdfM185MF8zXzcwXzAsMCwwLDAsMCwwLDBfMTExCQDMCAICKzE4XzE4XzEwXzE4XzE4XzE4XzExXzRfMTBfMCwwLDAsMCwwLDAsMF8yMDEJAMwIAgIrMThfMThfMTBfMThfMThfMThfMjJfNF8yMF8wLDAsMCwwLDAsMCwwXzIwMQkAzAgCAisxOF8xOF8xMF8xOF8xOF8xOF8zM180XzMwXzAsMCwwLDAsMCwwLDBfMjAxCQDMCAICKjRfMTNfMjJfNF8zNV8yMl8yM18wXzUwLDEsMF8wLDAsMCwwLDAsMCwwXwkAzAgCAio0XzEzXzIyXzRfMzVfMjJfNDZfMF81MCwxLDFfMCwyLDUsMCwwLDAsMF8JAMwIAgIrNF8xM18yMl80XzM1XzIyXzY5XzBfNTAsMiwxXzAsNSwxMCwwLDAsMCwwXwkAzAgCAio1XzI1XzQwXzVfMTBfMTVfMjBfMV8zMCwxLDFfMCwwLDAsMCwwLDAsMF8JAMwIAgIqNV8yNV80MF81XzEwXzE1XzQwXzFfMzAsMSwyXzIsMSwzLDAsMCwwLDBfCQDMCAICKjVfMjVfNDBfNV8xMF8xNV82MF8xXzMwLDEsM181LDIsOCwwLDAsMCwwXwkAzAgCAicyM18yM181XzIwXzIzXzZfMzVfMl8xMDBfMCwwLDAsMCwwLDAsMF8JAMwIAgInMjNfMjNfNV8yMF8yM182XzcwXzJfMTUwXzAsMCwwLDAsMCwwLDBfCQDMCAICKDIzXzIzXzVfMjBfMjNfNl8xMDVfMl8yMDBfMCwwLDAsMCwwLDAsMF8FA25pbAAJcklkeENvZWZmAAYAEHJJZHhSZXF1aXJlbWVudHMACQAJcklkeFNsb3RzAAoADlBST0RVQ1RQS0dTSVpFAAoAC3doSWR4TGV2ZWxzAAAACHdoSWR4UmVzAAEACHdoSWR4TWF0AAIACXdoSWR4UHJvZAADAAl3aElkeExPRlQABAAJdm9sTG9ja2VkAAAAC3ZvbE9jY3VwaWVkAAEAB3ZvbEZyZWUAAgAIdm9sVG90YWwAAwAKYnBJZHhMZXZlbAAAAAhicElkeFJlcwABAAhicElkeE1hdAACAAlicElkeFByb2QAAwAKbG9jSWR4VHlwZQABAAhsb2NJZHhJZAACARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBB2Fzc2V0SWQJAKwCAgIDbm9fBQdhc3NldElkARprZXlMYW5kQXNzZXRJZFRvQ3VzdG9tTmFtZQEHYXNzZXRJZAkArAICAgVsY25hXwUHYXNzZXRJZAEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEHYXNzZXRJZAkArAICAgNzdF8FB2Fzc2V0SWQBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgR0eXBlB2Fzc2V0SWQJALkJAgkAzAgCAgNsYXMJAMwIAgUEdHlwZQkAzAgCBQdhc3NldElkBQNuaWwCAV8BImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDB25mdFR5cGUHYXNzZXRJZAlvd25lckFkZHIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAgZzdHRhb18FB25mdFR5cGUCAV8FB2Fzc2V0SWQCAV8FCW93bmVyQWRkcgESa2V5V2FyZWhvdXNlQnlMYW5kAQtsYW5kQXNzZXRJZAkArAICAgN3aF8FC2xhbmRBc3NldElkARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQdhc3NldElkCQCsAgICC2luZnJhTGV2ZWxfBQdhc3NldElkARprZXlEdWNrQXNzZXRJZFRvQ3VzdG9tTmFtZQEHYXNzZXRJZAkArAICAhhkdWNrQ3VzdG9tTmFtZUJ5QXNzZXRJZF8FB2Fzc2V0SWQBFmtleUFkZHJlc3NUb0N1c3RvbU5hbWUBBGFkZHIJAKwCAgIYYWNjb3VudEN1c3RvbU5hbWVCeUFkZHJfBQRhZGRyAQ9rZXlBZGRyZXNzUmVmQnkBBGFkZHIJAKwCAgIJYWNjUmVmQnlfBQRhZGRyARxrZXlPbmJvYXJkQXJ0QWN0aXZhdGVkT25EdWNrAQtkdWNrQXNzZXRJZAkArAICAhpvbmJvYXJkQXJ0QWN0aXZhdGVkT25EdWNrXwULZHVja0Fzc2V0SWQBHGtleU9uYm9hcmRBcnREdWNrQWN0aXZhdGVkQnkBBGFkZHIJAKwCAgIab25ib2FyZEFydEFjdGl2YXRlZER1Y2tCeV8FBGFkZHIBE2tleUFkZHJlc3NSZWZlcnJhbHMBBGFkZHIJAKwCAgINYWNjUmVmZXJyYWxzXwUEYWRkcgEQa2V5RHVja0lkVG9Pd25lcgEHYXNzZXRJZAkArAICAgpkdWNrT3duZXJfBQdhc3NldElkARRrZXlTdGFrZWREdWNrQnlPd25lcgEJb3duZXJBZGRyCQCsAgICEnN0YWtlZER1Y2tCeU93bmVyXwUJb3duZXJBZGRyARFrZXlCYWNrcGFja0J5RHVjawELZHVja0Fzc2V0SWQJAKwCAgIJYmFja1BhY2tfBQtkdWNrQXNzZXRJZAEPa2V5RHVja0xvY2F0aW9uAQtkdWNrQXNzZXRJZAkArAICAg1kdWNrTG9jYXRpb25fBQtkdWNrQXNzZXRJZAAPZGVsaXZlcnlGdW5kS2V5AgxkZWxpdmVyeUZ1bmQADWxhc3RUb3VySWRLZXkCDiVzX19sYXN0VG91cklkAAZTQ0FMRTgAgMLXLwAMeHBMZXZlbFNjYWxlAIAZAA94cExldmVsUmVjaXBQb3cAoB8AEm51bVBvaW50c09uTGV2ZWxVcAADAAxyZXF1aXJlbWVudHMJAMwIAgIIU3RyZW5ndGgJAMwIAgIIQWNjdXJhY3kJAMwIAgIJSW50ZWxsZWN0CQDMCAICCUVuZHVyYW5jZQkAzAgCAglEZXh0ZXJpdHkJAMwIAgIFTGV2ZWwJAMwIAgIGSGVhbHRoBQNuaWwADGNoYXJTdHJlbmd0aAAAAAxjaGFyQWNjdXJhY3kAAQANY2hhckludGVsbGVjdAACAA1jaGFyRW5kdXJhbmNlAAMADWNoYXJEZXh0ZXJpdHkABAAKTlVNTUFJTkFVWAACAAhNQVhTTE9UUwACAA1NQVhQUk9ESU5TTE9UAB4BDWtleUR1Y2tIZWFsdGgBC2R1Y2tBc3NldElkCQCsAgICC2R1Y2tIZWFsdGhfBQtkdWNrQXNzZXRJZAEMa2V5RHVja0NoYXJzAQtkdWNrQXNzZXRJZAkArAICAgpkdWNrQ2hhcnNfBQtkdWNrQXNzZXRJZAEJa2V5RHVja1hQAQtkdWNrQXNzZXRJZAkArAICAgdkdWNrWFBfBQtkdWNrQXNzZXRJZAEMa2V5RHVja0xldmVsAQtkdWNrQXNzZXRJZAkArAICAgpkdWNrTGV2ZWxfBQtkdWNrQXNzZXRJZAERa2V5RHVja0ZyZWVQb2ludHMBC2R1Y2tBc3NldElkCQCsAgICD2R1Y2tGcmVlUG9pbnRzXwULZHVja0Fzc2V0SWQBEGtleUR1Y2tFcXVpcG1lbnQBC2R1Y2tBc3NldElkCQCsAgICDmR1Y2tFcXVpcG1lbnRfBQtkdWNrQXNzZXRJZAEJa2V5VXNlclhQAQRhZGRyCQCsAgICB3VzZXJYUF8FBGFkZHIBDGtleVVzZXJMZXZlbAEEYWRkcgkArAICAgp1c2VyTGV2ZWxfBQRhZGRyARFrZXlVc2VyRnJlZVBvaW50cwEEYWRkcgkArAICAg91c2VyRnJlZVBvaW50c18FBGFkZHIBDmtleVNhdmVkSGVhbHRoAQtkdWNrQXNzZXRJZAkArAICAgxzYXZlZEhlYWx0aF8FC2R1Y2tBc3NldElkARBrZXlTYXZlZExvY2F0aW9uAQtkdWNrQXNzZXRJZAkArAICAg5zYXZlZExvY2F0aW9uXwULZHVja0Fzc2V0SWQBFGtleUR1Y2tEZWxpdmVyeUNvdW50AQtkdWNrQXNzZXRJZAkArAICAhl0b3RhbERlbGl2ZXJ5Q291bnRCeUR1Y2tfBQtkdWNrQXNzZXRJZAEUa2V5VXNlckRlbGl2ZXJ5Q291bnQBBGFkZHIJAKwCAgISdXNlckRlbGl2ZXJ5Q291bnRfBQRhZGRyARZrZXlVc2VyTGFzdERlbGl2ZXJ5RGF5AQRhZGRyCQCsAgICFHVzZXJMYXN0RGVsaXZlcnlEYXlfBQRhZGRyAAd4cENsYWltAJBOAAx4cEN1c3RvbU5hbWUAwIQ9AAl4cE9uYm9hcmQAwIQ9AQlsZXZlbEJ5WFABAnhwCQBrAwUMeHBMZXZlbFNjYWxlCQBsBgUCeHAABAUPeHBMZXZlbFJlY2lwUG93AAQABAUERE9XTgUGU0NBTEU4AQltYXhIZWFsdGgBBWxldmVsCQBkAgBkBQVsZXZlbAEHbGV2ZWxVcAIJY3VyckxldmVsBW5ld1hQBAhuZXdMZXZlbAkBCWxldmVsQnlYUAEFBW5ld1hQCQDMCAIFCG5ld0xldmVsCQDMCAIJAGgCBRJudW1Qb2ludHNPbkxldmVsVXAJAGUCBQhuZXdMZXZlbAUJY3VyckxldmVsBQNuaWwACURBWU1JTExJUwCAuJkpARprZXlBY3Jlc1N0YWtlZEFtb3VudEJ5VXNlcgEEYWRkcgkArAICAhhhY3Jlc1N0YWtlZEFtb3VudEJ5VXNlcl8FBGFkZHIADFJFTkFNSU5HQ09TVADAlrECAApNQVhOQU1FTEVOADIAD1BSRVNBTEVOVU1MQU5EUwD0AwEaa2V5TGFuZEN1c3RvbU5hbWVUb0Fzc2V0SWQBBG5hbWUJAKwCAgIEbGNuXwUEbmFtZQEaa2V5RHVja0N1c3RvbU5hbWVUb0Fzc2V0SWQBBG5hbWUJAKwCAgIRZHVja0J5Q3VzdG9tTmFtZV8FBG5hbWUBFmtleUN1c3RvbU5hbWVUb0FkZHJlc3MBBG5hbWUJAKwCAgIUYWNjb3VudEJ5Q3VzdG9tTmFtZV8FBG5hbWUBCWtleU9sZGllcwACCm9sZGllc0xpc3QAC2NsYWltTW9kZVdoAAAADWNsYWltTW9kZUR1Y2sAAQATY2xhaW1Nb2RlV2hUaGVuRHVjawACARNkaXN0cmlidXRlQnlXZWlnaHRzAgV0b3RhbAd3ZWlnaHRzBANzdW0JAGQCCQBkAgkAZAIJAGQCCQBkAgkAkQMCBQd3ZWlnaHRzAAAJAJEDAgUHd2VpZ2h0cwABCQCRAwIFB3dlaWdodHMAAgkAkQMCBQd3ZWlnaHRzAAMJAJEDAgUHd2VpZ2h0cwAECQCRAwIFB3dlaWdodHMABQMJAGcCAAAFA3N1bQkAAgECEFplcm8gd2VpZ2h0cyBzdW0EBW5vcm02CQBrAwUFdG90YWwFBU1VTFQ2BQNzdW0KAQpub3JtYWxpemVyAgNhY2MEZWxlbQkAzQgCBQNhY2MJAGsDBQRlbGVtBQVub3JtNgUFTVVMVDYKAAIkbAUHd2VpZ2h0cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEKbm9ybWFsaXplcgIFAiRhCQCRAwIFAiRsBQIkaQoB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JGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDcJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwEIYWRkUHJvZEIHBmlkeENudAVwTGlzdAppc1Bvc2l0aXZlB3NlZ21lbnQHbWFpbkF1eARzbG90CWR1Y2tTdGF0cwQFcGFydHMJALUJAgUGaWR4Q250AgE6AwkBAiE9AgkAkAMBBQVwYXJ0cwACCQACAQIoSW5jb3JyZWN0IGZvcm1hdCwgc2hvdWxkIGJlIGluZGV4OmFtb3VudAMDCQEBIQEFCmlzUG9zaXRpdmUJAQIhPQIJALECAQkAkQMCBQVwYXJ0cwAAAAIHCQACAQIrUHJvZHVjdCBpZHggc2hvdWxkIGJlIDIgZGlnaXRzLCB6ZXJvIHBhZGRlZAQKcHJvZHVjdElkeAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXBhcnRzAAAEBWNvdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAQMDCQBmAgAABQpwcm9kdWN0SWR4BgkAZwIFCnByb2R1Y3RJZHgJAJADAQUQcHJvZHVjdGlvbk1hdHJpeAkAAgECE1Vua25vd24gcHJvZHVjdCBpZHgDCQBmAgAABQVjb3VudAkAAgECF0NvdW50IGNhbid0IGJlIG5lZ2F0aXZlAwkAZgIFBWNvdW50BQ1NQVhQUk9ESU5TTE9UCQACAQkArAICCQCsAgIJAKwCAgIUQ2FuJ3QgcHV0IG1vcmUgdGhhbiAJAKQDAQUNTUFYUFJPRElOU0xPVAIEIG9mIAkAkQMCBQlwcm9kVHlwZXMFCnByb2R1Y3RJZHgDCQAAAgUFY291bnQAAAkAlAoCBQVwTGlzdAcEBGhlYWQJAMkBAgUFcExpc3QJAGgCAAgFCnByb2R1Y3RJZHgEBGN1cnIJALEJAQkAyQECCQDKAQIFBXBMaXN0CQBoAgAIBQpwcm9kdWN0SWR4AAgEBHRhaWwJAMoBAgUFcExpc3QJAGgCAAgJAGQCBQpwcm9kdWN0SWR4AAEEBnJlY2lwZQkAtQkCCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgFCnByb2R1Y3RJZHgCAV8DAwkBASEBBQppc1Bvc2l0aXZlCQBmAgUFY291bnQFBGN1cnIHCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCVlvdSBoYXZlIAkApAMBBQRjdXJyAgQgb2YgCQCRAwIFCXByb2RUeXBlcwUKcHJvZHVjdElkeAITLCBidXQgdHJpZWQgdG8gdXNlIAkApAMBBQVjb3VudAQJaXNCaWdJdGVtAwMJAQEhAQUKaXNQb3NpdGl2ZQkBFWNoZWNrU3RhdFJlcXVpcmVtZW50cwIFCWR1Y2tTdGF0cwkAtQkCCQCRAwIFBnJlY2lwZQUQcklkeFJlcXVpcmVtZW50cwIBLAcEBmNvbXBhdAkAkQMCBQZyZWNpcGUFCXJJZHhTbG90cwMJAAACBQZjb21wYXQCAAkAAgECF0l0ZW0gY2Fubm90IGJlIGVxdWlwcGVkBAFjCQENcGFyc2VJbnRWYWx1ZQEFBmNvbXBhdAQEY1NlZwkAaQIFAWMAZAMJAQIhPQIFB3NlZ21lbnQFBGNTZWcJAAIBAhRTZWdtZW50IGluY29tcGF0aWJsZQQIY01haW5BdXgJAGkCCQBqAgUBYwBkAAoDCQECIT0CBQdtYWluQXV4BQhjTWFpbkF1eAkAAgECEVNsb3QgaW5jb21wYXRpYmxlBAljTnVtU2xvdHMJAGoCBQFjAAoDAwkBAiE9AgUEc2xvdAAACQBmAgUJY051bVNsb3RzAAEHCQACAQIeQmlnIGl0ZW1zIHNob3VsZCBvY2N1cHkgc2xvdCAwCQBmAgUJY051bVNsb3RzAAEHCQCUCgIJAMsBAgkAywECBQRoZWFkCQCaAwEJAGQCBQRjdXJyAwUKaXNQb3NpdGl2ZQUFY291bnQJAQEtAQUFY291bnQFBHRhaWwFCWlzQmlnSXRlbQELc2xvdHNHcm91cEIGAWcEYnBJbgppc1Bvc2l0aXZlB3NlZ21lbnQHbWFpbkF1eAVzdGF0cwMJAQIhPQIFAWcCAAQFc2xvdHMJALUJAgUBZwIBLAMJAGYCCQCQAwEFBXNsb3RzBQhNQVhTTE9UUwkAAgECEldyb25nIHNsb3RzIGZvcm1hdAQCczAJAJEDAgUFc2xvdHMAAAQCczEDCQBmAgkAkAMBBQVzbG90cwABCQCRAwIFBXNsb3RzAAECAAMDCQAAAgUCczACAAkAAAIFAnMxAgAHBQRicEluBAV0bXBTMAMJAQIhPQIFAnMwAgAJAQhhZGRQcm9kQgcFAnMwBQRicEluBQppc1Bvc2l0aXZlBQdzZWdtZW50BQdtYWluQXV4AAAFBXN0YXRzCQCUCgIFBGJwSW4HAwkBAiE9AgUCczECAAMIBQV0bXBTMAJfMgkAAgECHkJpZyBpdGVtIGFscmVhZHkgb2NjdXBpZXMgc2xvdAgJAQhhZGRQcm9kQgcFAnMxCAUFdG1wUzACXzEFCmlzUG9zaXRpdmUFB3NlZ21lbnQFB21haW5BdXgAAQUFc3RhdHMCXzEIBQV0bXBTMAJfMQUEYnBJbgEGZHJlc3NCBAdzZWdMaXN0BnBCeXRlcwppc1Bvc2l0aXZlBXN0YXRzCgEHc2VnbWVudAIDYWNjA3NlZwQBaggFA2FjYwJfMQQHbWFpbkF1eAkAtQkCBQNzZWcCATsDCQECIT0CCQCQAwEFB21haW5BdXgFCk5VTU1BSU5BVVgJAAIBAhRXcm9uZyBzZWdtZW50IGZvcm1hdAQBbQkAkQMCBQdtYWluQXV4AAAEAWEJAJEDAgUHbWFpbkF1eAABAwMJAAACBQFtAgAJAAACBQFhAgAHCQCUCgIJAGQCBQFqAAEIBQNhY2MCXzIEBHRtcE0JAQtzbG90c0dyb3VwQgYFAW0IBQNhY2MCXzIFCmlzUG9zaXRpdmUFAWoAAAUFc3RhdHMJAJQKAgkAZAIFAWoAAQkBC3Nsb3RzR3JvdXBCBgUBYQUEdG1wTQUKaXNQb3NpdGl2ZQUBagABBQVzdGF0cwgKAAIkbAUHc2VnTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgAABQZwQnl0ZXMKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB3NlZ21lbnQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYCXzIBDWNvdW50VGVycmFpbnMBCHRlcnJhaW5zCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUEAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFCAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBQwABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUQAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFFAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBRgABBQNuaWwBBmFkZFJlcwUKY3VycmVudFJlcw10ZXJyYWluQ291bnRzCWRlbHRhVGltZQ1sYW5kU2l6ZUluZGV4F2RhaWx5QnlQaWVjZVdpdGhCb251c2VzCgEFYWRkZXICA2FjYwFpBAlyZXNPZlR5cGUJAGgCCQBoAgkAawMFCWRlbHRhVGltZQUXZGFpbHlCeVBpZWNlV2l0aEJvbnVzZXMFCURBWU1JTExJUwkAkQMCBQ10ZXJyYWluQ291bnRzBQFpBQ1sYW5kU2l6ZUluZGV4CQDNCAIFA2FjYwkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCmN1cnJlbnRSZXMFAWkFCXJlc09mVHlwZQQBcgoAAiRsBQVJVEVSNgoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEFYWRkZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYJALkJAgUBcgIBXwEPdmlydENsYWltQWRkUmVzBQpjdXJyZW50UmVzDXRlcnJhaW5Db3VudHMJZGVsdGFUaW1lDWxhbmRTaXplSW5kZXgXZGFpbHlCeVBpZWNlV2l0aEJvbnVzZXMKAQVhZGRlcgIDYWNjAWkECXJlc09mVHlwZQkAaAIJAGgCCQBrAwUJZGVsdGFUaW1lBRdkYWlseUJ5UGllY2VXaXRo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ZFZvbAEFAndoBAZ3aExvZnQDCQBmAgAFCQCQAwEFAndoCQC5CQIJAMwIAgIBMAkAzAgCCQCkAwEFCndoT2NjdXBpZWQJAMwIAgkApAMBCQBlAgUHd2hUb3RhbAUKd2hPY2N1cGllZAkAzAgCCQCkAwEFB3doVG90YWwFA25pbAIBXwQEbG9mdAkAtQkCCQCRAwIFAndoBQl3aElkeExPRlQCAV8ECHdoTG9ja2VkCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAUJdm9sTG9ja2VkBANvY2MDCQBmAgkAkAMBBQRsb2Z0AAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAUKd2hPY2N1cGllZAkAuQkCCQDMCAIJAKQDAQUId2hMb2NrZWQJAMwIAgkApAMBBQNvY2MJAMwIAgkApAMBCQBlAgkAZQIFB3doVG90YWwFCHdoTG9ja2VkBQNvY2MJAMwIAgkApAMBBQd3aFRvdGFsBQNuaWwCAV8JAMwIAgkAkQMCBQJ3aAULd2hJZHhMZXZlbHMJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQJ3aAUId2hJZHhSZXMCAV8FBk5VTVJFUwkAkQMCBQJ3aAUId2hJZHhSZXMCCzBfMF8wXzBfMF8wCQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUCd2gFCHdoSWR4TWF0AgFfBQZOVU1SRVMJAJEDAgUCd2gFCHdoSWR4TWF0AgswXzBfMF8wXzBfMAkAzAgCCQCRAwIFAndoBQl3aElkeFByb2QJAMwIAgUGd2hMb2Z0BQNuaWwBDGFwcGx5Qm9udXNlcwILbGFuZEFzc2V0SWQGcGllY2VzBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQJYXJ0UGllY2VzCQELdmFsdWVPckVsc2UCCQCfCAEJASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIFCkFSVFBSRVNBTEUFC2xhbmRBc3NldElkAAAEBGFkZDYJAGkCBQppbmZyYUxldmVsAAYEBGFkZDcJAGkCBQppbmZyYUxldmVsAAcJAGQCCQBkAgUPREFJTFlSRVNCWVBJRUNFCQBrAwUPREFJTFlSRVNCWVBJRUNFCQBkAgkAZAIFCmluZnJhTGV2ZWwFBGFkZDYJAGgCAAIFBGFkZDcABQkAawMFD0RBSUxZUkVTQllQSUVDRQUJYXJ0UGllY2VzCQBoAgUGcGllY2VzAAUBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwRhZGRyCWNsYWltTW9kZQ1sYW5kQXNzZXRJZEluBA0kdDAzNDI0NzM0Nzg2AwkAAAIFCWNsYWltTW9kZQULY2xhaW1Nb2RlV2gJAJQKAgUNbGFuZEFzc2V0SWRJbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAgAEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04EA2xvYwkAtQkCCQEFdmFsdWUBBQtjdXJMb2NhdGlvbgIBXwMJAQIhPQIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFMCQACAQkArAICCQCsAgICFkR1Y2sgbG9jYXRpb24gdHlwZSBpcyAJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAhEsIGJ1dCBzaG91bGQgYmUgTAkAlAoCCQCRAwIFA2xvYwUIbG9jSWR4SWQFC2R1Y2tBc3NldElkBAtsYW5kQXNzZXRJZAgFDSR0MDM0MjQ3MzQ3ODYCXzEEBmR1Y2tJZAgFDSR0MDM0MjQ3MzQ3ODYCXzIEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFB3RpbWVLZXkJAKwCAgkArAICAgVMYW5kIAgFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8JAJYKBAUGZHVja0lkBQtsYW5kQXNzZXRJZAUBZAUJc2F2ZWRUaW1lARBjbGFpbVJlc0ludGVybmFsBARhZGRyBmFtb3VudAljbGFpbU1vZGUNbGFuZEFzc2V0SWRJbgMJAGYCAAAFBmFtb3VudAkAAgECD05lZ2F0aXZlIGFtb3VudAQBYwkBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwUEYWRkcgUJY2xhaW1Nb2RlBQ1sYW5kQXNzZXRJZEluBAhsYW5kU2l6ZQkAkQMCCAUBYwJfMwULcmVjTGFuZFNpemUEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCCAUBYwJfMwULcmVjVGVycmFpbnMECWRlbHRhVGltZQkAZQIJAQlmaW5hbFRpbWUACAUBYwJfNAMJAGYCAAAFCWRlbHRhVGltZQkAAgEJAKwCAgkArAICCQCsAgICJlNhdmVkIHRpbWVzdGFtcCBpcyBpbiBmdXR1cmUsIHNhdmVkID0gCQCkAwEIBQFjAl80AgosIGZpbmFsID0gCQCkAwEJAQlmaW5hbFRpbWUABAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBBQhsYW5kU2l6ZQQWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkBDGFwcGx5Qm9udXNlcwIIBQFjAl8yBQZwaWVjZXMECGF2YWlsUmVzCQBrAwUJZGVsdGFUaW1lCQBoAgUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQUGcGllY2VzBQlEQVlNSUxMSVMDCQBmAgUGYW1vdW50BQhhdmFpbFJlcwkAAgEJAKwCAgkArAICCQCsAgICIk5vdCBlbm91Z2ggcmVzb3VyY2VzLCBhdmFpbGFibGUgPSAJAKQDAQUIYXZhaWxSZXMCDiwgcmVxdWVzdGVkID0gCQCkAwEFBmFtb3VudAQMbmV3RGVsdGFUaW1lCQBrAwkAZQIFCGF2YWlsUmVzBQZhbW91bnQFCURBWU1JTExJUwkAaAIFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UFBnBpZWNlcwQMbmV3VGltZXN0YW1wCQBlAgkBCWZpbmFsVGltZQAFDG5ld0RlbHRhVGltZQQJbGFuZEluZGV4CQBpAgUGcGllY2VzBQVTU0laRQQKcmVzVG9DbGFpbQkBCXZpcnRDbGFpbQQFDXRlcnJhaW5Db3VudHMJAGUCBQlkZWx0YVRpbWUFDG5ld0RlbHRhVGltZQUJbGFuZEluZGV4BRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBAV3aEtleQkBEmtleVdhcmVob3VzZUJ5TGFuZAEIBQFjAl8yBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQgFAWMCXzIAAAQJY3VycmVudFdoCQEMZ2V0V2FyZWhvdXNlAwUFd2hLZXkFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAQEbG9mdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhMT0ZUAgFfBAt3aFNwYWNlTGVmdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUDAwkAAAIFCWNsYWltTW9kZQULY2xhaW1Nb2RlV2gJAGYCBQZhbW91bnQFC3doU3BhY2VMZWZ0BwkAAgEJAKwCAgkArAICAgVPbmx5IAkApAMBBQt3aFNwYWNlTGVmdAIYIHNwYWNlIGxlZnQgaW4gd2FyZWhvdXNlBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQgFAWMCXzEEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQOY3VycmVudFBhY2tSZXMJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMCAV8EDGN1cnJlbnRXaFJlcwkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8EDSR0MDM3MTU2MzgwMjcDCQAAAgUJY2xhaW1Nb2RlBQtjbGFpbU1vZGVXaAkAlgoECQEGYWRkUmVzBQUMY3VycmVudFdoUmVzBQ10ZXJyYWluQ291bnRzCQBlAgUJZGVsdGFUaW1lBQxuZXdEZWx0YVRpbWUFCWxhbmRJbmRleAUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQIBQpyZXNUb0NsYWltAl8yCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUIBQpyZXNUb0NsYWltAl8yAwkAAAIFCWNsYWltTW9kZQUNY2xhaW1Nb2RlRHVjawkAlgoECQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMJAQZhZGRSZXMFBQ5jdXJyZW50UGFja1JlcwUNdGVycmFpbkNvdW50cwkAZQIFCWRlbHRhVGltZQUMbmV3RGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUEBWRpc3RyCQENZGlzdHJpYnV0ZVJlcwQFDGN1cnJlbnRXaFJlcwUOY3VycmVudFBhY2tSZXMFCnJlc1RvQ2xhaW0FC3doU3BhY2VMZWZ0BAR3aEFtCQCXAwEJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUJAMwIAggFCnJlc1RvQ2xhaW0CXzIFA25pbAkAlgoECAUFZGlzdHICXzEIBQVkaXN0cgJfMgkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAUEd2hBbQkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlBQR3aEFtBAV3aFJlcwgFDSR0MDM3MTU2MzgwMjcCXzEEBWJwUmVzCAUNJHQwMzcxNTYzODAyNwJfMgQFbG9mdE8IBQ0kdDAzNzE1NjM4MDI3Al8zBAVsb2Z0RggFDSR0MDM3MTU2MzgwMjcCXzQJAJcKBQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBCAUBYwJfMgUMbmV3VGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgIBQFjAl8yBQRhZGRyBQxuZXdUaW1lc3RhbXAFA25pbAUFYnBLZXkJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCBQVicFJlcwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAUFd2hLZXkJAMwIAgkAkQMCBQljdXJyZW50V2gFC3doSWR4TGV2ZWxzCQDMCAIFBXdoUmVzCQDMCAIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAkAzAgCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kCQDMCAIJALkJAgkAzAgCCQCRAwIFBGxvZnQFCXZvbExvY2tlZAkAzAgCCQCkAwEFBWxvZnRPCQDMCAIJAKQDAQUFbG9mdEYJAMwIAgkAkQMCBQRsb2Z0BQh2b2xUb3RhbAUDbmlsAgFfBQNuaWwBCGNsYWltQWxsBARhZGRyC2xhbmRBc3NldElkBnBpZWNlcwljbGFpbU1vZGUEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBBXZhbHVlAQkAnwgBBQd0aW1lS2V5BAhhdmFpbFJlcwkAaAIJAGsDCQBlAgkBCWZpbmFsVGltZQAFCXNhdmVkVGltZQkBDGFwcGx5Qm9udXNlcwIFC2xhbmRBc3NldElkBQZwaWVjZXMFCURBWU1JTExJUwUGcGllY2VzCQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFCGF2YWlsUmVzBQljbGFpbU1vZGUFC2xhbmRBc3NldElkARN1cGRhdGVTdGF0c0ludGVybmFsBAZsdmxLZXkFeHBLZXkJcG9pbnRzS2V5B2RlbHRhWFAEAnhwCQELdmFsdWVPckVsc2UCCQCfCAEFBXhwS2V5AAAEBW5ld1hQCQBkAgUCeHAFB2RlbHRhWFAECWx2bFBvaW50cwkBB2xldmVsVXACCQELdmFsdWVPckVsc2UCCQCfCAEFBmx2bEtleQAABQVuZXdYUAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQZsdmxLZXkJAJEDAgUJbHZsUG9pbnRzAAAJAMwIAgkBDEludGVnZXJFbnRyeQIFBXhwS2V5BQVuZXdYUAkAzAgCCQEMSW50ZWdlckVudHJ5AgUJcG9pbnRzS2V5CQBkAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlwb2ludHNLZXkAAAkAkQMCBQlsdmxQb2ludHMAAQUDbmlsBQVuZXdYUAEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCC2R1Y2tBc3NldElkB2RlbHRhWFAEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULZHVja0Fzc2V0SWQEBGFkZHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEQa2V5RHVja0lkVG9Pd25lcgEFC2R1Y2tBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMDAwUTS1NfQUxMT1dfUk9CT19EVUNLUwkAAAIIBQVhc3NldAZpc3N1ZXIFBHRoaXMHCQEIY29udGFpbnMCCAUFYXNzZXQEbmFtZQULUk9CT19QUkVGSVgHCQETdXBkYXRlU3RhdHNJbnRlcm5hbAQJAQxrZXlVc2VyTGV2ZWwBBQRhZGRyCQEJa2V5VXNlclhQAQUEYWRkcgkBEWtleVVzZXJGcmVlUG9pbnRzAQUEYWRkcgUHZGVsdGFYUAkBE3VwZGF0ZVN0YXRzSW50ZXJuYWwECQEMa2V5RHVja0xldmVsAQULZHVja0Fzc2V0SWQJAQlrZXlEdWNrWFABBQtkdWNrQXNzZXRJZAkBEWtleUR1Y2tGcmVlUG9pbnRzAQULZHVja0Fzc2V0SWQFB2RlbHRhWFABFnVwZGF0ZUFjY1N0YXRzSW50ZXJuYWwCBGFkZHIHZGVsdGFYUAkBE3VwZGF0ZVN0YXRzSW50ZXJuYWwECQEMa2V5VXNlckxldmVsAQUEYWRkcgkBCWtleVVzZXJYUAEFBGFkZHIJARFrZXlVc2VyRnJlZVBvaW50cwEFBGFkZHIFB2RlbHRhWFABEmFjdGl2YXRlT25ib2FyZEFydAEEYWRkcgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAhyZWZCeUtleQkBD2tleUFkZHJlc3NSZWZCeQEFBGFkZHIEBXJlZkJ5CQCiCAEFCHJlZkJ5S2V5AwkBASEBCQEJaXNEZWZpbmVkAQUFcmVmQnkJAAIBAilZb3UgYXJlIG5vdCBlbGlnaWJsZSBmb3IgT05CT0FSRCBhcnRpZmFjdAQGYXJ0S2V5CQEca2V5T25ib2FyZEFydER1Y2tBY3RpdmF0ZWRCeQEFBGFkZHIEB2FydER1Y2sJAKIIAQUGYXJ0S2V5AwkBCWlzRGVmaW5lZAEFB2FydER1Y2sJAAIBCQCsAgICL1lvdSBhbHJlYWR5IHVzZWQgeW91ciBPTkJPQVJEIGFydGlmYWN0IG9uIGR1Y2sgCQEFdmFsdWUBBQdhcnREdWNrBBBkdWNrQWN0aXZhdG9yS2V5CQEca2V5T25ib2FyZEFydEFjdGl2YXRlZE9uRHVjawEFC2R1Y2tBc3NldElkBA1kdWNrQWN0aXZhdG9yCQCiCAEFEGR1Y2tBY3RpdmF0b3JLZXkDCQEJaXNEZWZpbmVkAQUNZHVja0FjdGl2YXRvcgkAAgEJAKwCAgkArAICCQCsAgICCVRoZSBkdWNrIAULZHVja0Fzc2V0SWQCNCBhbHJlYWR5IGdvdCBwb2ludHMgZnJvbSBPTkJPQVJEIGFydGlmYWN0IGZyb20gdXNlciAJAQV2YWx1ZQEFDWR1Y2tBY3RpdmF0b3IJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQZhcnRLZXkFC2R1Y2tBc3NldElkCQDMCAIJAQtTdHJpbmdFbnRyeQIFEGR1Y2tBY3RpdmF0b3JLZXkFBGFkZHIFA25pbAgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkBQl4cE9uYm9hcmQCXzEBEmFjdGl2YXRlUHJlc2FsZUFydAIEYWRkcg1sYW5kQXNzZXRJZEluBAFjCQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBQRhZGRyBRNjbGFpbU1vZGVXaFRoZW5EdWNrBQ1sYW5kQXNzZXRJZEluBAtsYW5kQXNzZXRJZAgFAWMCXzIEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAggFAWMCXzMFC3JlY0xhbmRTaXplBA1hY3RpdmF0aW9uS2V5CQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAMJAGYCCQELdmFsdWVPckVsc2UCCQCfCAEFDWFjdGl2YXRpb25LZXkAAAAACQACAQIlUHJlc2FsZSBhcnRpZmFjdCBpcyBhbHJlYWR5IGFjdGl2YXRlZAMJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAggFAWMCXzMFCnJlY0xhbmROdW0FD1BSRVNBTEVOVU1MQU5EUwkAAgEJAKwCAgkArAICCQCsAgIFCkxBTkRQUkVGSVgCASAFC2xhbmRBc3NldElkAiUgaXMgbm90IGVsaWdpYmxlIGZvciBwcmVzYWxlIGFydGlmYWN0BAtjbGFpbVJlc3VsdAkBCGNsYWltQWxsBAUEYWRkcgULbGFuZEFzc2V0SWQFBnBpZWNlcwUTY2xhaW1Nb2RlV2hUaGVuRHVjawkAzQgCCQDNCAIJAM0IAggFC2NsYWltUmVzdWx0Al8xCQEMSW50ZWdlckVudHJ5AgUNYWN0aXZhdGlvbktleQUGcGllY2VzCQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzIJALkJAggFC2NsYWltUmVzdWx0Al8zAgE6CQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzQJALkJAggFC2NsYWltUmVzdWx0Al81AgE6AQZwcm9sb2cBAWkDAwkBAiE9AggFAWkMb3JpZ2luQ2FsbGVyBQxyZXN0Q29udHJhY3QJAQt2YWx1ZU9yRWxzZQIJAKAIAQkBCmtleUJsb2NrZWQABwcJAAIBAh9Db250cmFjdHMgYXJlIHVuZGVyIG1haW50ZW5hbmNlCQDMCAIJAQtTdHJpbmdFbnRyeQIJARRrZXlDdXJXZWVrVHhJZEJ5VXNlcgEJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQFA25pbAETdW5zdGFrZUxhbmRJbnRlcm5hbAIEYWRkcgtsYW5kQXNzZXRJZAQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAQIbGFuZEluZm8JALUJAggJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAtkZXNjcmlwdGlvbgIBXwQIbGFuZFNpemUJAJEDAgUIbGFuZEluZm8FC3JlY0xhbmRTaXplBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBBQhsYW5kU2l6ZQQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAECWxhbmRJbmRleAkAaQIFBnBpZWNlcwUFU1NJWkUEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQhsYW5kSW5mbwULcmVjVGVycmFpbnMECWN1cnJlbnRXaAkBDGdldFdhcmVob3VzZQMFBXdoS2V5BQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwEDGN1cnJlbnRXaFJlcwkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8EB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBEUBleHRyTmF0aXZlKDEwNTUpAQUHdGltZUtleQQJZGVsdGFUaW1lCQBlAgkBCWZpbmFsVGltZQAFCXNhdmVkVGltZQMJAGYCAAAFCWRlbHRhVGltZQkAAgEJAKwCAgkArAICCQCsAgICJlNhdmVkIHRpbWVzdGFtcCBpcyBpbiBmdXR1cmUsIHNhdmVkID0gCQCkAwEFCXNhdmVkVGltZQIKLCBmaW5hbCA9IAkApAMBCQEJZmluYWxUaW1lAAQWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkBDGFwcGx5Qm9udXNlcwIFC2xhbmRBc3NldElkBQZwaWVjZXMEDXJlc0FmdGVyQ2xhaW0JAQ92aXJ0Q2xhaW1BZGRSZXMFBQxjdXJyZW50V2hSZXMFDXRlcnJhaW5Db3VudHMFCWRlbHRhVGltZQUJbGFuZEluZGV4BRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBAlhcnRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQAAAQPYWNyZXNGcm9tUGllY2VzCQBkAgkAaAIFBnBpZWNlcwUFTVVMVDgJAGkCCQBoAgkAZAIJAGgCBQZwaWVjZXMFCmluZnJhTGV2ZWwFCWFydFBpZWNlcwUFTVVMVDgABQQMYWNyZXNGcm9tUmVzCQBoAgkAawMIBQ1yZXNBZnRlckNsYWltAl8yBRBSRVNPVVJDRVBSSUNFTUlOBQVNVUxUOAUVVVNEVDJBQ1JFU19NVUxUSVBMSUVSCgEGc3VtTWF0AgNhY2MEaXRlbQkAZAIFA2FjYwkBDXBhcnNlSW50VmFsdWUBBQRpdGVtBAV3aE1hdAoAAiRsCQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAIBXwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEGc3VtTWF0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGBAxhY3Jlc0Zyb21NYXQJAGgCCQBrAwUFd2hNYXQJAGgCAAIFEFJFU09VUkNFUFJJQ0VNSU4FBU1VTFQ4BRVVU0RUMkFDUkVTX01VTFRJUExJRVIEBXByb2RzAwkAAAIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAV8KAQdzdW1Qcm9kAgNhY2MEaXRlbQQBaggFA2FjYwJfMgQLcmVjaXBlQ29lZmYJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQC1CQIJAJEDAgUQcHJvZHVjdGlvbk1hdHJpeAUBagIBXwUJcklkeENvZWZmCQCUCgIJAGQCCAUDYWNjAl8xCQBoAgkAaAIJAQ1wYXJzZUludFZhbHVlAQUEaXRlbQULcmVjaXBlQ29lZmYFBU1VTFQ2CQBkAgUBagABBAZ3aFByb2QKAAIkbAUFcHJvZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAAACgEFJGYxXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdzdW1Qcm9kAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAyNAkBBSRmMV8yAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAQNYWNyZXNGcm9tUHJvZAkAaAIJAGsDCAUGd2hQcm9kAl8xCQBoAgACBRBSRVNPVVJDRVBSSUNFTUlOBQVNVUxUOAUVVVNEVDJBQ1JFU19NVUxUSVBMSUVSCQCWCgQFD2FjcmVzRnJvbVBpZWNlcwUMYWNyZXNGcm9tUmVzBQxhY3Jlc0Zyb21NYXQFDWFjcmVzRnJvbVByb2QBE3Vuc3Rha2VEdWNrSW50ZXJuYWwCBGFkZHILZHVja0Fzc2V0SWQEBWVxS2V5CQEQa2V5RHVja0VxdWlwbWVudAEFC2R1Y2tBc3NldElkBAtjdXJyZW50U2VncwkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEFBWVxS2V5AhcsOyxfLDssXyw7LF8sOyxfLDssXyw7LAIBXwQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkECXRlbXBQcm9kQgkBBmRyZXNzQgQFC2N1cnJlbnRTZWdzCQEOcHJvZFN0clRv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bmlsAWkBC3NhdmVJbnRlZ2VyAgNrZXkGYW1vdW50AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIgc2F2ZUludGVnZXIgaXMgbm90IHB1YmxpYyBtZXRob2QJAMwIAgkBDEludGVnZXJFbnRyeQIFA2tleQUGYW1vdW50BQNuaWwBaQEKc2V0QmxvY2tlZAEJaXNCbG9ja2VkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIRcGVybWlzc2lvbiBkZW5pZWQJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQprZXlCbG9ja2VkAAUJaXNCbG9ja2VkBQNuaWwBaQETdW5zdGFrZUxhbmRDYWxsYmFjawILbGFuZEFzc2V0SWQEYWRkcgMJAQIhPQIJAKUIAQgFAWkGY2FsbGVyBRBhY3JlczJBZGRyZXNzU3RyCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEDXVuc3Rha2VSZXN1bHQJARN1bnN0YWtlTGFuZEludGVybmFsAgUEYWRkcgULbGFuZEFzc2V0SWQECXdsZ1Jlc3VsdAkA/AcEBQt3bGdDb250cmFjdAISb25TdGFrZVVuc3Rha2VMYW5kCQDMCAIFBGFkZHIJAMwIAgcFA25pbAUDbmlsCQCUCgIJAMwIAgkBBEJ1cm4CCQDZBAEFC2xhbmRBc3NldElkAAEJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgFC2xhbmRBc3NldElkBQRhZGRyBQNuaWwJAJcKBQgFDXVuc3Rha2VSZXN1bHQCXzEIBQ11bnN0YWtlUmVzdWx0Al8yCAUNdW5zdGFrZVJlc3VsdAJfMwgFDXVuc3Rha2VSZXN1bHQCXzQFCXdsZ1Jlc3VsdAFpARN1bnN0YWtlTGFuZFJFQURPTkxZAgtsYW5kQXNzZXRJZARhZGRyBA11bnN0YWtlUmVzdWx0CQETdW5zdGFrZUxhbmRJbnRlcm5hbAIFBGFkZHIFC2xhbmRBc3NldElkCQCUCgIFA25pbAUNdW5zdGFrZVJlc3VsdAFpARx1bnN0YWtlTGFuZHNGaW5hbGl6ZUNhbGxiYWNrAQRhZGRyAwkBAiE9AgkApQgBCAUBaQZjYWxsZXIFEGFjcmVzMkFkZHJlc3NTdHIJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAkAlAoCCQDMCAIJAQtEZWxldGVFbnRyeQEJARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBBQRhZGRyCQDMCAIJAQtEZWxldGVFbnRyeQEJARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQUEYWRkcgUDbmlsAAABaQEUY29udmVydFVuc3Rha2VkTGFuZHMAAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEB2Fzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIDCQECIT0CCAUDcG10BmFtb3VudAABCQACAQkArAICCQCsAgICBE5GVCAFCkxBTkRQUkVGSVgCJCB0b2tlbiBzaG91bGQgYmUgYXR0YWNoZWQgYXMgcGF5bWVudAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAMJAQIhPQIIBQVhc3NldAZpc3N1ZXIFBHRoaXMJAAIBAhdVbmtub3duIGlzc3VlciBvZiB0b2tlbgMJAQEhAQkBCGNvbnRhaW5zAggFBWFzc2V0BG5hbWUFCkxBTkRQUkVGSVgJAAIBCQCsAgIJAKwCAgIJT25seSBORlQgBQpMQU5EUFJFRklYAhQgdG9rZW5zIGFyZSBhY2NlcHRlZAQLbGFuZEFzc2V0SWQJANgEAQUHYXNzZXRJZAQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8EBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgUBZAULcmVjTGFuZFNpemUECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAlhcnRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQAAAQLYWNyZXNBbW91bnQJAGQCCQBoAgUGcGllY2VzBQVNVUxUOAkAaQIJAGgCCQBkAgkAaAIFBnBpZWNlcwUKaW5mcmFMZXZlbAUJYXJ0UGllY2VzBQVNVUxUOAAFBANyZXEJAPwHBAUNYWNyZXNDb250cmFjdAIUcmVxdWVzdEFjcmVzQ2FsbGJhY2sJAMwIAgULYWNyZXNBbW91bnQFA25pbAUDbmlsAwkAAAIFA3JlcQUDcmVxBAVjYWxsYgkA/AcECQERQGV4dHJOYXRpdmUoMTA2MikBBRBhY3JlczJBZGRyZXNzU3RyAhJzdGFrZUFjcmVzQ2FsbGJhY2sJAMwIAgUHYWRkcmVzcwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQxhY3Jlc0Fzc2V0SWQFC2FjcmVzQW1vdW50BQNuaWwDCQAAAgUFY2FsbGIFBWNhbGxiCQCUCgIJAMwIAgkBBEJ1cm4CCQDZBAEFC2xhbmRBc3NldElkAAEFA25pbAAACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBE3Vuc3Rha2VEdWNrQ2FsbGJhY2sCC2R1Y2tBc3NldElkBGFkZHIDCQECIT0CCQClCAEIBQFpBmNhbGxlcgUQYWNyZXMyQWRkcmVzc1N0cgkAAgECEVBlcm1pc3Npb24gZGVuaWVkBA11bnN0YWtlUmVzdWx0CQETdW5zdGFrZUR1Y2tJbnRlcm5hbAIFBGFkZHIFC2R1Y2tBc3NldElkCQCUCgIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUEYWRkcgABCQDZBAEFC2R1Y2tBc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULZHVja0Fzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBEGtleUR1Y2tJZFRvT3duZXIBBQtkdWNrQXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkRVQ0tQUkVGSVgFC2R1Y2tBc3NldElkBQRhZGRyCQDMCAIJAQtEZWxldGVFbnRyeQEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHIFA25pbAUNdW5zdGFrZVJlc3VsdAFpARN1bnN0YWtlRHVja1JFQURPTkxZAgtkdWNrQXNzZXRJZARhZGRyBA11bnN0YWtlUmVzdWx0CQETdW5zdGFrZUR1Y2tJbnRlcm5hbAIFBGFkZHIFC2R1Y2tBc3NldElkCQCUCgIFA25pbAUNdW5zdGFrZVJlc3VsdAFpAQhjbGFpbVJlcwIGYW1vdW50DmxhbmRBc3NldElkU3RyBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQGcmVzdWx0CQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFBmFtb3VudAUNY2xhaW1Nb2RlRHVjawUObGFuZEFzc2V0SWRTdHIEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAkAlAoCCQDOCAIJAM0IAgkAzQgCCQDOCAIIBQZyZXN1bHQCXzEICQEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCBQtkdWNrQXNzZXRJZAkAawMFB3hwQ2xhaW0FBmFtb3VudAUFTVVMVDgCXzEJAQtTdHJpbmdFbnRyeQIIBQZyZXN1bHQCXzIJALkJAggFBnJlc3VsdAJfMwIBOgkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfNAkAuQkCCAUGcmVzdWx0Al81AgE6BQ1wcm9sb2dBY3Rpb25zCQCRAwIIBQZyZXN1bHQCXzMFCGJwSWR4UmVzAWkBDGNsYWltUmVzVG9XSAIGYW1vdW50DmxhbmRBc3NldElkU3RyBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQGcmVzdWx0CQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFBmFtb3VudAULY2xhaW1Nb2RlV2gFDmxhbmRBc3NldElkU3RyCQCUCgIJAM4IAgkAzQgCCQDNCAIJAM4IAggFBnJlc3VsdAJfMQgJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgUEYWRkcgkAawMFB3hwQ2xhaW0FBmFtb3VudAUFTVVMVDgCXzEJAQtTdHJpbmdFbnRyeQIIBQZyZXN1bHQCXzIJALkJAggFBnJlc3VsdAJfMwIBOgkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfNAkAuQkCCAUGcmVzdWx0Al81AgE6BQ1wcm9sb2dBY3Rpb25zCQCRAwIIBQZyZXN1bHQCXzUFCHdoSWR4UmVzAWkBDnVwZGF0ZUJhY2twYWNrAgtkdWNrQXNzZXRJZAduZXdQYWNrAwkBAiE9AggFAWkGY2FsbGVyBQ9lY29ub215Q29udHJhY3QJAAIBAhFwZXJtaXNzaW9uIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBQduZXdQYWNrBQNuaWwFB25ld1BhY2sBaQEPY29tbWl0Rm9yUmFuZG9tAAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkEC2ZpbmlzaEJsb2NrCQBkAgUGaGVpZ2h0BQtyYW5kb21EZWxheQQEYWRkcgkApQgBCAUBaQZjYWxsZXIJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEJa2V5Q29tbWl0AQUEYWRkcgULZmluaXNoQmxvY2sFA25pbAUNcHJvbG9nQWN0aW9ucwULZmluaXNoQmxvY2sBaQEMcmV2ZWFsUmFuZG9tAQhtYXhWYWx1ZQQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkEBGFkZHIJAKUIAQgFAWkGY2FsbGVyBAlmaW5pc2hLZXkJAQlrZXlDb21taXQBBQRhZGRyBAtmaW5pc2hCbG9jawkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFCWZpbmlzaEtleQIkWW91IGhhdmUgdG8gY29tbWl0Rm9yUmFuZG9tKCkgZmlyc3QhAwkAZgIFC2ZpbmlzaEJsb2NrBQZoZWlnaHQJAAIBCQCsAgICNFJhbmRvbSBudW1iZXIgaXMgbm90IHJlYWR5IHlldCwgd2FpdCB1bnRpbCBoZWlnaHQgPSAJAKQDAQULZmluaXNoQmxvY2sEB2VudHJvcHkJAQV2YWx1ZQEICQEFdmFsdWUBCQDtBwEFC2ZpbmlzaEJsb2NrA3ZyZgQEc2FsdAkAmwMBCQELdmFsdWVPckVsc2UCCQCiCAEJARVrZXlMYXN0V2Vla1R4SWRCeVVzZXIBBQRhZGRyAgAEBHJhbmQJAQ9nZXRSYW5kb21OdW1iZXIDBQhtYXhWYWx1ZQUEc2FsdAUHZW50cm9weQkAlAoCCQDOCAIJAMwIAgkBC0RlbGV0ZUVudHJ5AQUJZmluaXNoS2V5BQNuaWwFDXByb2xvZ0FjdGlvbnMFBHJhbmQBaQEQYWN0aXZhdGVBcnRpZmFjdAIHYXJ0TmFtZQ5sYW5kQXNzZXRJZE9wdAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQZjYWxsZXIEBnJlc3VsdAQHJG1hdGNoMAUHYXJ0TmFtZQMJAAACAgdQUkVTQUxFBQckbWF0Y2gwCQESYWN0aXZhdGVQcmVzYWxlQXJ0AgUEYWRkcgUObGFuZEFzc2V0SWRPcHQDCQAAAgIHT05CT0FSRAUHJG1hdGNoMAkBEmFjdGl2YXRlT25ib2FyZEFydAEFBGFkZHIJAAIBAhBVbmtub3duIGFydGlmYWN0CQDOCAIFBnJlc3VsdAUNcHJvbG9nQWN0aW9ucwFpAQ1zYXZlV2FyZWhvdXNlAgV3aFN0cgtsYW5kQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUPZWNvbm9teUNvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAQCd2gJALwJAgUFd2hTdHICAToDCQECIT0CCQCQAwEFAndoAAUJAAIBAjB3YXJlaG91c2Ugc3RyaW5nIHNob3VsZCBjb250YWluIDQgJzonIHNlcGFyYXRvcnMEBWxvZnRMCQCRAwIJALUJAgkAkQMCBQJ3aAUJd2hJZHhMT0ZUAgFfBQl2b2xMb2NrZWQEBWxvZnRPCQEXZ2V0V2FyZWhvdXNlT2NjdXBpZWRWb2wBBQJ3aAQFbG9mdFQJARdnZXRXYXJlaG91c2VUb3RhbFZvbHVtZQEJAJEDAgUCd2gFC3doSWR4TGV2ZWxzBAVsb2Z0RgkAZQIJAGUCBQVsb2Z0VAkBDXBhcnNlSW50VmFsdWUBBQVsb2Z0TAUFbG9mdE8DCQBmAgAABQVsb2Z0RgkAAgECME9wZXJhdGlvbiBsZWFkcyB0byBuZWdhdGl2ZSBmcmVlIHdhcmVob3VzZSBzcGFjZQQIbmV3V2hTdHIJALoJAgkAzAgCCQCRAwIFAndoBQt3aElkeExldmVscwkAzAgCCQCRAwIFAndoBQh3aElkeFJlcwkAzAgCCQCRAwIFAndoBQh3aElkeE1hdAkAzAgCCQCRAwIFAndoBQl3aElkeFByb2QJAMwIAgkAuQkCCQDMCAIFBWxvZnRMCQDMCAIJAKQDAQUFbG9mdE8JAMwIAgkApAMBBQVsb2Z0RgkAzAgCCQCkAwEFBWxvZnRUBQNuaWwCAV8FA25pbAIBOgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBXdoS2V5BQhuZXdXaFN0cgUDbmlsBQhuZXdXaFN0cgFpAQ1zZXRDdXN0b21OYW1lAwdhc3NldElkCmN1c3RvbU5hbWUEdHlwZQQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhpBbGxvd2VkIFVTRFQgcGF5bWVudCBvbmx5IQMJAQIhPQIIBQNwbXQGYW1vdW50BQxSRU5BTUlOR0NPU1QJAAIBCQCsAgICElBheW1lbnQgc2hvdWxkIGJlIAkApAMBBQxSRU5BTUlOR0NPU1QDCQEIY29udGFpbnMCBQpjdXN0b21OYW1lAgJfXwkAAgEJAKwCAgIeTmFtZSBzaG91bGQgbm90IGNvbnRhaW4gJ19fJzogBQpjdXN0b21OYW1lAwkAZgIJALECAQUKY3VzdG9tTmFtZQUKTUFYTkFNRUxFTgkAAgEJAKwCAgIZTmFtZSB0b28gbG9uZywgbWF4TGVuZ3RoPQkApAMBBQpNQVhOQU1FTEVOBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQHYWN0aW9ucwQHJG1hdGNoMAUEdHlwZQMJAAACAgdBQ0NPVU5UBQckbWF0Y2gwBApyZXZlcnNlS2V5CQEWa2V5Q3VzdG9tTmFtZVRvQWRkcmVzcwEFCmN1c3RvbU5hbWUECW5hbWVPd25lcgkAoggBBQpyZXZlcnNlS2V5AwkBCWlzRGVmaW5lZAEFCW5hbWVPd25lcgkAAgEJAKwCAgIZTmFtZSBhbHJlYWR5IHJlZ2lzdGVyZWQ6IAUKY3VzdG9tTmFtZQQNYWRkclRvTmFtZUtleQkBFmtleUFkZHJlc3NUb0N1c3RvbU5hbWUBBQRhZGRyBAdvbGROYW1lCQCiCAEFDWFkZHJUb05hbWVLZXkEB2ZyZWVPbGQDCQEJaXNEZWZpbmVkAQUHb2xkTmFtZQkAzAgCCQELRGVsZXRlRW50cnkBCQEWa2V5Q3VzdG9tTmFtZVRvQWRkcmVzcwEJAQV2YWx1ZQEFB29sZE5hbWUFA25pbAUDbmlsCQDOCAIJAM0IAgkAzQgCBQdmcmVlT2xkCQELU3RyaW5nRW50cnkCBQ1hZGRyVG9OYW1lS2V5BQpjdXN0b21OYW1lCQELU3RyaW5nRW50cnkCBQpyZXZlcnNlS2V5BQRhZGRyCAkBFnVwZGF0ZUFjY1N0YXRzSW50ZXJuYWwCBQRhZGRyBQx4cEN1c3RvbU5hbWUCXzEDCQAAAgIETEFORAUHJG1hdGNoMAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQdhc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFB2Fzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkJAAIBCQCsAgIIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQUHYXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQKcmV2ZXJzZUtleQkBGmtleUxhbmRDdXN0b21OYW1lVG9Bc3NldElkAQUKY3VzdG9tTmFtZQQJbmFtZU93bmVyCQCiCAEFCnJldmVyc2VLZXkDCQEJaXNEZWZpbmVkAQUJbmFtZU93bmVyCQACAQkArAICAhlOYW1lIGFscmVhZHkgcmVnaXN0ZXJlZDogBQpjdXN0b21OYW1lBA5hc3NldFRvTmFtZUtleQkBGmtleUxhbmRBc3NldElkVG9DdXN0b21OYW1lAQUHYXNzZXRJZAQHb2xkTmFtZQkAoggBBQ5hc3NldFRvTmFtZUtleQQHZnJlZU9sZAMJAQlpc0RlZmluZWQBBQdvbGROYW1lCQDMCAIJAQtEZWxldGVFbnRyeQEJARprZXlMYW5kQ3VzdG9tTmFtZVRvQXNzZXRJZAEJAQV2YWx1ZQEFB29sZE5hbWUFA25pbAUDbmlsCQDOCAIJAM0IAgkAzQgCBQdmcmVlT2xkCQELU3RyaW5nRW50cnkCBQ5hc3NldFRvTmFtZUtleQUKY3VzdG9tTmFtZQkBC1N0cmluZ0VudHJ5AgUKcmV2ZXJzZUtleQUHYXNzZXRJZAgJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgUEYWRkcgUMeHBDdXN0b21OYW1lAl8xAwkAAAICBERVQ0sFByRtYXRjaDAEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQdhc3NldElkAwMJAQEhAQkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQYJAQEhAQkBCWlzRGVmaW5lZAEJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgkAAgEJAKwCAggFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARBrZXlEdWNrSWRUb093bmVyAQUHYXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKRFVDS1BSRUZJWAINIGlzIG5vdCB5b3VycwQKcmV2ZXJzZUtleQkBGmtleUR1Y2tDdXN0b21OYW1lVG9Bc3NldElkAQUKY3VzdG9tTmFtZQQJbmFtZU93bmVyCQCiCAEFCnJldmVyc2VLZXkDCQEJaXNEZWZpbmVkAQUJbmFtZU93bmVyCQACAQkArAICAhlOYW1lIGFscmVhZHkgcmVnaXN0ZXJlZDogBQpjdXN0b21OYW1lBA5hc3NldFRvTmFtZUtleQkBGmtleUR1Y2tBc3NldElkVG9DdXN0b21OYW1lAQUHYXNzZXRJZAQHb2xkTmFtZQkAoggBBQ5hc3NldFRvTmFtZUtleQQHZnJlZU9sZAMJAQlpc0RlZmluZWQBBQdvbGROYW1lCQDMCAIJAQtEZWxldGVFbnRyeQEJARprZXlEdWNrQ3VzdG9tTmFtZVRvQXNzZXRJZAEJAQV2YWx1ZQEFB29sZE5hbWUFA25pbAUDbmlsCQDOCAIJAM0IAgkAzQgCBQdmcmVlT2xkCQELU3RyaW5nRW50cnkCBQ5hc3NldFRvTmFtZUtleQUKY3VzdG9tTmFtZQkBC1N0cmluZ0VudHJ5AgUKcmV2ZXJzZUtleQUHYXNzZXRJZAgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFB2Fzc2V0SWQFDHhwQ3VzdG9tTmFtZQJfMQkAAgECE1Vua25vd24gZW50aXR5IHR5cGUJAJQKAgkAzggCCQDNCAIFB2FjdGlvbnMJAQ5TY3JpcHRUcmFuc2ZlcgMFD2Vjb25vbXlDb250cmFjdAgFA3BtdAZhbW91bnQFC3VzZHRBc3NldElkBQ1wcm9sb2dBY3Rpb25zAAABaQEMc2V0UmVmZXJyYWxzAglvbGRQbGF5ZXIJbmV3UGxheWVyAwkBAiE9AggFAWkPY2FsbGVyUHVibGljS2V5BQNwdWIJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAMJAQEhAQkBCWlzRGVmaW5lZAEJAKYIAQUJb2xkUGxheWVyCQACAQkArAICAhFJbnZhbGlkIGFkZHJlc3M6IAUJb2xkUGxheWVyBApuZXdiaWVBZGRyCQCmCAEFCW5ld1BsYXllcgMJAQEhAQkBCWlzRGVmaW5lZAEFCm5ld2JpZUFkZHIJAAIBCQCsAgICEUludmFsaWQgYWRkcmVzczogBQluZXdQbGF5ZXIECW9sZExhc3RUeAkAoggBCQEVa2V5TGFzdFdlZWtUeElkQnlVc2VyAQUJb2xkUGxheWVyAwkBASEBCQEJaXNEZWZpbmVkAQUJb2xkTGFzdFR4CQACAQIib2xkUGxheWVyIGRpZG4ndCBkbyBhbnkgdHggaW4gZ2FtZQMJAGcCAAAICQDvBwEJAQV2YWx1ZQEFCm5ld2JpZUFkZHIJYXZhaWxhYmxlCQACAQIWbmV3UGxheWVyIGhhcyBubyBXQVZFUwQHb2xkc0tleQkBCWtleU9sZGllcwAEBG9sZHMJAKIIAQUHb2xkc0tleQQGb2xkaWVzAwkBCWlzRGVmaW5lZAEFBG9sZHMJALwJAgkBBXZhbHVlAQUEb2xkcwIBXwUDbmlsAwkBD2NvbnRhaW5zRWxlbWVudAIFBm9sZGllcwUJbmV3UGxheWVyCQACAQkArAICBQluZXdQbGF5ZXICJiBpcyBub3QgbmV3YmllIChhbHJlYWR5IGhhcyByZWZlcnJhbHMpBAhyZWZCeUtleQkBD2tleUFkZHJlc3NSZWZCeQEFCW5ld1BsYXllcgQFcmVmQnkJAKIIAQUIcmVmQnlLZXkDAwkBCWlzRGVmaW5lZAEFBXJlZkJ5CQEJaXNEZWZpbmVkAQkApggBCQEFdmFsdWUBBQVyZWZCeQcJAAIBCQCsAgIJAKwCAgUJbmV3UGxheWVyAhQgYWxyZWFkeSBoYXMgcmVmQnk6IAkBBXZhbHVlAQUFcmVmQnkEB3JlZnNLZXkJARNrZXlBZGRyZXNzUmVmZXJyYWxzAQUJb2xkUGxheWVyBARyZWZzCQCiCAEFB3JlZnNLZXkECXJlZnNBcnJheQMJAQlpc0RlZmluZWQBBQRyZWZzCQC8CQIJAQV2YWx1ZQEFBHJlZnMCAV8FA25pbAMJAQ9jb250YWluc0VsZW1lbnQCBQlyZWZzQXJyYXkFCW5ld1BsYXllcgkAAgEJAKwCAgkArAICCQCsAgIFCW9sZFBsYXllcgISIGFscmVhZHkgY29udGFpbnMgBQluZXdQbGF5ZXICESB3aXRoaW4gcmVmZXJyYWxzBAduZXdSZWZzCQC6CQIJAM0IAgUJcmVmc0FycmF5BQluZXdQbGF5ZXICAV8EB25ld09sZHMDCQEPY29udGFpbnNFbGVtZW50AgUGb2xkaWVzBQlvbGRQbGF5ZXIJAQV2YWx1ZQEFBG9sZHMJALoJAgkAzQgCBQZvbGRpZXMFCW9sZFBsYXllcgIBXwkAlAoCCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUIcmVmQnlLZXkFCW9sZFBsYXllcgkAzAgCCQELU3RyaW5nRW50cnkCBQdyZWZzS2V5BQduZXdSZWZzCQDMCAIJAQtTdHJpbmdFbnRyeQIFB29sZHNLZXkFB25ld09sZHMFA25pbAUNcHJvbG9nQWN0aW9ucwAAAWkBEGRpc3RyaWJ1dGVQb2ludHMFCHN0cmVuZ3RoCGFjY3VyYWN5CWludGVsbGVjdAllbmR1cmFuY2UJZGV4dGVyaXR5BA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQLdmlydFdsZ0RhdGEJAQlhc0FueUxpc3QBCQD8BwQFC3dsZ0NvbnRyYWN0AhJjaGVja1dsZ1hwUkVBRE9OTFkJAMwIAgUEYWRkcgUDbmlsBQNuaWwEDXZpcnRXbGdQb2ludHMJAQVhc0ludAEJAJEDAgULdmlydFdsZ0RhdGEAAQQPJHQwMTAwNDk2MTAwODg2AwkAZwIAAAUNdmlydFdsZ1BvaW50cwkAlAoCAAAFA25pbAQHZGVsdGFYUAkBBWFzSW50AQkA/AcEBQt3bGdDb250cmFjdAIJdGFrZVdsZ1hwCQDMCAIFBGFkZHIFA25pbAUDbmlsAwkAAAIFB2RlbHRhWFAFB2RlbHRhWFAJAJQKAgUNdmlydFdsZ1BvaW50cwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDGtleVVzZXJMZXZlbAEFBGFkZHIJAQVhc0ludAEJAJEDAgULdmlydFdsZ0RhdGEAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBCWtleVVzZXJYUAEFBGFkZHIJAQVhc0ludAEJAJEDAgULdmlydFdsZ0RhdGEAAgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAl3bGdQb2ludHMIBQ8kdDAxMDA0OTYxMDA4ODYCXzEECndsZ0FjdGlvbnMIBQ8kdDAxMDA0OTYxMDA4ODYCXzIEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQKZnJlZUtleUFjYwkBEWtleVVzZXJGcmVlUG9pbnRzAQUEYWRkcgQNZnJlZVBvaW50c0FjYwkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUKZnJlZUtleUFjYwAABQl3bGdQb2ludHMEC2ZyZWVLZXlEdWNrCQERa2V5RHVja0ZyZWVQb2ludHMBBQtkdWNrQXNzZXRJZAQOZnJlZVBvaW50c0R1Y2sJAQt2YWx1ZU9yRWxzZQIJAJ8IAQULZnJlZUtleUR1Y2sAAAQHc3VtRnJlZQkAZAIFDWZyZWVQb2ludHNBY2MFDmZyZWVQb2ludHNEdWNrBA9zdW1Ub0Rpc3RyaWJ1dGUJAGQCCQBkAgkAZAIJAGQCBQhzdHJlbmd0aAUIYWNjdXJhY3kFCWludGVsbGVjdAUJZW5kdXJhbmNlBQlkZXh0ZXJpdHkDCQBmAgUPc3VtVG9EaXN0cmlidXRlBQdzdW1GcmVlCQACAQkArAICCQCsAgICD1RoZXJlIGFyZSBvbmx5IAkApAMBBQdzdW1GcmVlAhogZnJlZSBwb2ludHMgdG8gZGlzdHJpYnV0ZQQIY2hhcnNLZXkJAQxrZXlEdWNrQ2hhcnMBBQtkdWNrQXNzZXRJZAQFY2hhcnMJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQhjaGFyc0tleQIJMF8wXzBfMF8wAgFfBAZuZXdBY2MJAGUCBQ1mcmVlUG9pbnRzQWNjBQ9zdW1Ub0Rpc3RyaWJ1dGUJAJQKAgkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFCmZyZWVLZXlBY2MDCQBmAgAABQZuZXdBY2MAAAUGbmV3QWNjCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQtmcmVlS2V5RHVjawMJAGYCAAAFBm5ld0FjYwkAZAIFDmZyZWVQb2ludHNEdWNrBQZuZXdBY2MFDmZyZWVQb2ludHNEdWNrCQDMCAIJAQtTdHJpbmdFbnRyeQIFCGNoYXJzS2V5CQC5CQIJAMwIAgkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQxjaGFyU3RyZW5ndGgFCHN0cmVuZ3RoCQDMCAIJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUMY2hhckFjY3VyYWN5BQhhY2N1cmFjeQkAzAgCCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDWNoYXJJbnRlbGxlY3QFCWludGVsbGVjdAkAzAgCCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDWNoYXJFbmR1cmFuY2UFCWVuZHVyYW5jZQkAzAgCCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDWNoYXJEZXh0ZXJpdHkFCWRleHRlcml0eQUDbmlsAgFfBQNuaWwFDXByb2xvZ0FjdGlvbnMFCndsZ0FjdGlvbnMAAAFpARxzcGxpdEJ5R2xvYmFsV2VpZ2h0c1JFQURPTkxZAQZhbW91bnQJAJQKAgUDbmlsCQESZ2V0TmVlZGVkTWF0ZXJpYWxzAQUGYW1vdW50AWkBJHNwbGl0QnlHbG9iYWxBbmRMb2NhbFdlaWdodHNSRUFET05MWQMJbWF0QW1vdW50CXJlc0Ftb3VudAh0ZXJyYWlucwQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBBQh0ZXJyYWlucwkAlAoCBQNuaWwJAJQKAgkBEmdldE5lZWRlZE1hdGVyaWFscwEFCW1hdEFtb3VudAkBE2Rpc3RyaWJ1dGVCeVdlaWdodHMCBQlyZXNBbW91bnQFDXRlcnJhaW5Db3VudHMBaQETZ2V0QmFja3BhY2tSRUFET05MWQELZHVja0Fzc2V0SWQJAJQKAgUDbmlsCQC5CQIJAQtnZXRCYWNrcGFjawEJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkAgE6AWkBFGdldFdhcmVob3VzZVJFQURPTkxZAQtsYW5kQXNzZXRJZAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQJbGFuZEluZGV4CQBpAgkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8FC3JlY0xhbmRTaXplBQVTU0laRQQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAJAJQKAgUDbmlsCQC6CQIJAQxnZXRXYXJlaG91c2UDCQESa2V5V2FyZWhvdXNlQnlMYW5kAQULbGFuZEFzc2V0SWQFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAIBOgFpAQpzYXZlTGFzdFR4AAMJAQEhAQkBD2NvbnRhaW5zRWxlbWVudAIJAMwIAgULd2xnQ29udHJhY3QJAMwIAgUPZWNvbm9teUNvbnRyYWN0CQDMCAIFEnRvdXJuYW1lbnRDb250cmFjdAkAzAgCBQ1hY3Jlc0NvbnRyYWN0BQNuaWwIBQFpBmNhbGxlcgkAAgECDUFjY2VzcyBkZW5pZWQJAJQKAgkBBnByb2xvZwEFAWkAKgFpAQ91cGRhdGVEdWNrU3RhdHMCC2R1Y2tBc3NldElkB2RlbHRhWFADCQECIT0CCAUBaQZjYWxsZXIFD2Vjb25vbXlDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkBQdkZWx0YVhQAWkBDnVwZGF0ZUFjY1N0YXRzAgRhZGRyB2RlbHRhWFADCQEBIQEJAQ9jb250YWluc0VsZW1lbnQCCQDMCAIFC3dsZ0NvbnRyYWN0CQDMCAIFD2Vjb25vbXlDb250cmFjdAkAzAgCBQ1hY3Jlc0NvbnRyYWN0BQNuaWwIBQFpBmNhbGxlcgkAAgECDUFjY2VzcyBkZW5pZWQJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgUEYWRkcgUHZGVsdGFYUAFpARNpbml0RHVja1RvdXJBdHRlbXB0AQtkdWNrQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUSdG91cm5hbWVudENvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAVtYXhIUAkBCW1heEhlYWx0aAEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDGtleUR1Y2tMZXZlbAEFC2R1Y2tBc3NldElkAAAECWN1ckhlYWx0aAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgFBW1heEhQBAljdXJMb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQUJY3VyTG9jS2V5BQ9ERUZBVUxUTE9DQVRJT04EBmxhc3RJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBRJ0b3VybmFtZW50Q29udHJhY3QFDWxhc3RUb3VySWRLZXkAAAQMdG91ckxvY2F0aW9uCQCsAgIJAKQDAQUGbGFzdElkAgRfVF8wCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ5rZXlTYXZlZEhlYWx0aAEFC2R1Y2tBc3NldElkBQljdXJIZWFsdGgJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAUFbWF4SFAJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGtleVNhdmVkTG9jYXRpb24BBQtkdWNrQXNzZXRJZAULY3VyTG9jYXRpb24JAMwIAgkBC1N0cmluZ0VudHJ5AgUJY3VyTG9jS2V5BQx0b3VyTG9jYXRpb24FA25pbAUMdG91ckxvY2F0aW9uAWkBDGJyZWFrQXR0ZW1wdAAEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAljdXJMb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQUJY3VyTG9jS2V5BQ9ERUZBVUxUTE9DQVRJT04DCQECIT0CCQCRAwIJALUJAgULY3VyTG9jYXRpb24CAV8FCmxvY0lkeFR5cGUCAVQJAAIBAiJZb3VyIGR1Y2sgaXMgbm90IGluIHRoZSB0b3VybmFtZW50BAtzYXZlZEhlYWx0aAkBEUBleHRyTmF0aXZlKDEwNTUpAQkBDmtleVNhdmVkSGVhbHRoAQULZHVja0Fzc2V0SWQEDXNhdmVkTG9jYXRpb24JARFAZXh0ck5hdGl2ZSgxMDU4KQEJARBrZXlTYXZlZExvY2F0aW9uAQULZHVja0Fzc2V0SWQJAJQKAgkAzQgCCQDNCAIFDXByb2xvZ0FjdGlvbnMJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBQtzYXZlZEhlYWx0aAkBC1N0cmluZ0VudHJ5AgUJY3VyTG9jS2V5BQ1zYXZlZExvY2F0aW9uBQtjdXJMb2NhdGlvbgFpARRicmVha0F0dGVtcHRDYWxsYmFjawADCQECIT0CCAUBaQZjYWxsZXIFEnRvdXJuYW1lbnRDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQxvcmlnaW5DYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAkBEUBleHRyTmF0aXZlKDEwNTUpAQkBDmtleVNhdmVkSGVhbHRoAQULZHVja0Fzc2V0SWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEQa2V5U2F2ZWRMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQNuaWwCFGJyZWFrQXR0ZW1wdENhbGxiYWNrAWkBFmV4aXRUb3VybmFtZW50SW50ZXJuYWwBC2R1Y2tBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQINQWNjZXNzIGRlbmllZAQLc2F2ZWRIZWFsdGgJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAQ5rZXlTYXZlZEhlYWx0aAEFC2R1Y2tBc3NldElkBA1zYXZlZExvY2F0aW9uCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEQa2V5U2F2ZWRMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQFC3NhdmVkSGVhbHRoCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUNc2F2ZWRMb2NhdGlvbgUDbmlsBwFpAQ9wcm9jZXNzRGVsaXZlcnkBC2R1Y2tBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQINQWNjZXNzIGRlbmllZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIECWZ1bmRUb3RhbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9lY29ub215Q29udHJhY3QFD2RlbGl2ZXJ5RnVuZEtleQAAAwkAZgIFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQUJZnVuZFRvdGFsCQACAQkArAICAiBEZWxpdmVyeSBpcyBub3QgYXZhaWxhYmxlLCBmdW5kPQkBCmZpeGVkUG9pbnQCBQlmdW5kVG90YWwABgQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQIY291bnRLZXkJARRrZXlVc2VyRGVsaXZlcnlDb3VudAEFBGFkZHIEB2xhc3REYXkJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleVVzZXJMYXN0RGVsaXZlcnlEYXkBBQRhZGRyAAAEBXRvZGF5CQBpAgUDbm93BQlEQVlNSUxMSVMEBWNvdW50AwkAAAIFB2xhc3REYXkFBXRvZGF5CQELdmFsdWVPckVsc2UCCQCfCAEFCGNvdW50S2V5AAAAAAQFYWNyZXMJAQt2YWx1ZU9yRWxzZQIJAJoIAgUNYWNyZXNDb250cmFjdAkBGmtleUFjcmVzU3Rha2VkQW1vdW50QnlVc2VyAQUEYWRkcgAABBFhbGxvd2VkRGVsaXZlcmllcwkAZAIFF0FMTE9XRURfRlJFRV9ERUxJVkVSSUVTCQBpAgUFYWNyZXMFGkFDUkVTX0ZPUl9ERUxJVkVSWV9BVFRFTVBUAwkAZwIFBWNvdW50BRFhbGxvd2VkRGVsaXZlcmllcwkAAgEJAKwCAgkArAICAhFZb3UgYWxyZWFkeSB1c2VkIAkApAMBBRFhbGxvd2VkRGVsaXZlcmllcwIcIGRlbGl2ZXJ5IGF0dGVtcHRzIGZvciB0b2RheQQOZ2xvYmFsQ291bnRLZXkJARRrZXlEdWNrRGVsaXZlcnlDb3VudAEFC2R1Y2tBc3NldElkBAZyZXdhcmQJAPwHBAUPZWNvbm9teUNvbnRyYWN0AhJzZW5kRGVsaXZlcnlSZXdhcmQJAMwIAgUEYWRkcgUDbmlsBQNuaWwJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUIY291bnRLZXkJAGQCBQVjb3VudAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5VXNlckxhc3REZWxpdmVyeURheQEFBGFkZHIFBXRvZGF5CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5nbG9iYWxDb3VudEtleQkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUOZ2xvYmFsQ291bnRLZXkAAAABBQNuaWwFBnJld2FyZABVFx5g", "height": 3398924, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 45MEatBMriNwvV7iNPWMo7VUycqPKfiHjaKbtTSUcxg6 Next: HfjbSr62YuaABLXhYCboL3J4yoEZPcv71YumgwbGieoT Diff:
OldNewDifferences
44 let KS_SEPARATE_PUBLIC_KEY = false
55
66 let KS_ALLOW_ROBO_DUCKS = false
7-
8-let DAY_MILLIS = 86400000
97
108 let OLD_STAKING_DEADLINE = 1733248800000
119
4947 else throw("Unknown chain")
5048 }
5149
52-let arbitrageDelay = match chain {
53- case _ =>
54- if ((base58'2W' == $match0))
55- then DAY_MILLIS
56- else if ((base58'2T' == $match0))
57- then 60000
58- else throw("Unknown chain")
59-}
60-
6150 let SEP = "__"
6251
6352 let MULT6 = 1000000
8069
8170
8271 let IdxCfgEconomyDapp = 2
83-
84-let IdxCfgGovernanceDapp = 3
8572
8673 let IdxCfgWlgDapp = 4
8774
10794
10895 let economyContract = getContractAddressOrFail(restCfg, IdxCfgEconomyDapp)
10996
110-let govContract = getContractAddressOrFail(restCfg, IdxCfgGovernanceDapp)
111-
11297 let wlgContract = getContractAddressOrFail(restCfg, IdxCfgWlgDapp)
11398
11499 let tournamentContract = getContractAddressOrFail(restCfg, IdxCfgTournamentDapp)
121106
122107 let recTerrains = 2
123108
124-let recContinent = 3
125-
126109 let acresAssetIdKey = "acresAssetId"
127110
128111 let acresAssetId = valueOrErrorMessage(getBinary(acresContract, acresAssetIdKey), "ACRES is not issued yet")
133116
134117
135118 func keyResProportions () = "resTypesProportions"
136-
137-
138-func keyResTypesByContinent (continent) = ("resTypesByContinent_" + continent)
139119
140120
141121 func keyStakedLandsByOwner (ownerAddr) = ("stakedLandsByOwner_" + ownerAddr)
213193 let ARTPRESALE = "PRESALE"
214194
215195 let NUMRES = 6
216-
217-let MAX_LANDS_STAKED_BY_USER = 25
218196
219197 let DAILYRESBYPIECE = 3456000
220198
325303 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
326304
327305
328-func keyUserGwlReleaseTime (userAddr) = ("%s%s__userGwlReleaseTime__" + userAddr)
329-
330-
331306 let deliveryFundKey = "deliveryFund"
332307
333308 let lastTourIdKey = "%s__lastTourId"
420395
421396 let DAYMILLIS = 86400000
422397
423-func keyLastWlgTradeTimeByUser (addr) = ("lastArbTimeUser_" + addr)
424-
425-
426398 func keyAcresStakedAmountByUser (addr) = ("acresStakedAmountByUser_" + addr)
427399
428400
433405 let PRESALENUMLANDS = 500
434406
435407 func keyLandCustomNameToAssetId (name) = ("lcn_" + name)
436-
437-
438-func keyInfraLevelByAssetIdAndOwner (assetId,ownerAddr) = ((("ilao_" + assetId) + "_") + ownerAddr)
439-
440-
441-func keyLandNumToOwner (landNum) = ("lo_" + landNum)
442408
443409
444410 func keyDuckCustomNameToAssetId (name) = ("duckByCustomName_" + name)
696662 else throw("List size exceeds 6")
697663
698664 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6))._2
699- }
700-
701-
702-func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
703- then throw("Wrong proportions data")
704- else {
705- func updater (acc,i) = {
706- let result = (parseIntValue(propList[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
707- if ((0 > result))
708- then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
709- else (acc :+ toString(result))
710- }
711-
712- let $l = ITER6
713- let $s = size($l)
714- let $acc0 = nil
715- func $f0_1 ($a,$i) = if (($i >= $s))
716- then $a
717- else updater($a, $l[$i])
718-
719- func $f0_2 ($a,$i) = if (($i >= $s))
720- then $a
721- else throw("List size exceeds 6")
722-
723- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
724- }
725-
726-
727-func updateProportions (terrainCounts,landSizeIndex,sign) = {
728- let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
729- makeString(updateProportionsInternal(propList, terrainCounts, landSizeIndex, sign), "_")
730665 }
731666
732667
12681203
12691204
12701205 @Callable(i)
1271-func stakeLand () = {
1272- let prologActions = prolog(i)
1273- if ((size(i.payments) != 1))
1274- then throw("Exactly one payment required")
1275- else {
1276- let pmt = value(i.payments[0])
1277- let assetId = value(pmt.assetId)
1278- let address = toString(i.caller)
1279- if ((pmt.amount != 1))
1280- then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
1281- else {
1282- let asset = value(assetInfo(assetId))
1283- if ((asset.issuer != this))
1284- then throw("Unknown issuer of token")
1285- else if (!(contains(asset.name, LANDPREFIX)))
1286- then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
1287- else {
1288- let landNumSize = drop(asset.name, 4)
1289- let landNum = if (contains(landNumSize, "XXL"))
1290- then dropRight(landNumSize, 3)
1291- else if (contains(landNumSize, "XL"))
1292- then dropRight(landNumSize, 2)
1293- else dropRight(landNumSize, 1)
1294- if (!(isDefined(parseInt(landNum))))
1295- then throw(("Cannot parse land number from " + asset.name))
1296- else {
1297- let landAssetId = toBase58String(assetId)
1298- let timeKey = keyStakedTimeByAssetId(landAssetId)
1299- if (isDefined(getInteger(timeKey)))
1300- then throw((("NFT " + asset.name) + " is already staked"))
1301- else {
1302- let d = split(asset.description, "_")
1303- let terrainCounts = countTerrains(d[recTerrains])
1304- let pieces = numPiecesBySize(d[recLandSize])
1305- let landIndex = (pieces / SSIZE)
1306- let props = updateProportions(terrainCounts, landIndex, 1)
1307- let resByContKey = keyResTypesByContinent(d[recContinent])
1308- let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
1309- let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, 1), "_")
1310- let landsKey = keyStakedLandsByOwner(address)
1311- let landsStr = getString(landsKey)
1312- let lands = if (isDefined(landsStr))
1313- then split_51C(value(landsStr), "_")
1314- else nil
1315- if (containsElement(lands, landAssetId))
1316- then throw(("Your staked lands already contain " + landAssetId))
1317- else if ((size(lands) >= MAX_LANDS_STAKED_BY_USER))
1318- then throw((("Your already staked max (" + toString(MAX_LANDS_STAKED_BY_USER)) + ") lands"))
1319- else {
1320- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1321- let piecesKey = keyStakedPiecesByOwner(address)
1322- let oldPieces = valueOrElse(getInteger(piecesKey), 0)
1323- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
1324- $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)
1325- }
1326- }
1327- }
1328- }
1329- }
1330- }
1331- }
1332-
1333-
1334-
1335-@Callable(i)
1336-func unstakeLand (landAssetIdIn) = {
1337- let prologActions = prolog(i)
1338- if ((size(i.payments) != 0))
1339- then throw("No payments required")
1340- else {
1341- let addr = toString(i.caller)
1342- let c = checkClaimConditions(addr, claimModeDuck, landAssetIdIn)
1343- let landAssetId = c._2
1344- let d = c._3
1345- let landsKey = keyStakedLandsByOwner(addr)
1346- let terrainCounts = countTerrains(d[recTerrains])
1347- let pieces = numPiecesBySize(d[recLandSize])
1348- let landIndex = (pieces / SSIZE)
1349- let props = updateProportions(terrainCounts, landIndex, -1)
1350- let resByContKey = keyResTypesByContinent(d[recContinent])
1351- let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
1352- let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, -1), "_")
1353- let claimResult = claimAll(addr, landAssetId, pieces, claimModeDuck)
1354- let lands = split_51C(valueOrElse(getString(landsKey), ""), "_")
1355- let idx = indexOf(lands, landAssetId)
1356- if (!(isDefined(idx)))
1357- then throw(("Your staked lands don't contain " + landAssetId))
1358- else {
1359- let now = lastBlock.timestamp
1360- let govReleaseTime = valueOrElse(getInteger(govContract, keyUserGwlReleaseTime(addr)), 0)
1361- if ((govReleaseTime >= now))
1362- then throw(("Your gWL are taking part in voting, cannot unstake until " + toString(govReleaseTime)))
1363- else {
1364- let arbReleaseTime = (valueOrElse(getInteger(wlgContract, keyLastWlgTradeTimeByUser(addr)), 0) + arbitrageDelay)
1365- if ((arbReleaseTime > now))
1366- then throw(("Your staked lands took part in arbitrage, cannot unstake until " + toString(arbReleaseTime)))
1367- else {
1368- let piecesKey = keyStakedPiecesByOwner(addr)
1369- let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
1370- let newPieces = if ((pieces > stakedPieces))
1371- then 0
1372- else (stakedPieces - pieces)
1373- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr], nil)
1374- $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))
1375- then StringEntry(landsKey, makeString_11C(removeByIndex(lands, value(idx)), "_"))
1376- else DeleteEntry(landsKey), IntegerEntry(piecesKey, newPieces)] ++ prologActions), wlgResult)
1377- }
1378- }
1379- }
1380- }
1381- }
1382-
1383-
1384-
1385-@Callable(i)
13861206 func unstakeLandCallback (landAssetId,addr) = if ((toString(i.caller) != acres2AddressStr))
13871207 then throw("Permission denied")
13881208 else {
13891209 let unstakeResult = unstakeLandInternal(addr, landAssetId)
1390- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr], nil)
1210+ let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr, false], nil)
13911211 $Tuple2([Burn(fromBase58String(landAssetId), 1), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))], $Tuple5(unstakeResult._1, unstakeResult._2, unstakeResult._3, unstakeResult._4, wlgResult))
13921212 }
13931213
17361556 let addr = toString(i.originCaller)
17371557 let virtWlgData = asAnyList(invoke(wlgContract, "checkWlgXpREADONLY", [addr], nil))
17381558 let virtWlgPoints = asInt(virtWlgData[1])
1739- let $t0100244100634 = if ((0 >= virtWlgPoints))
1559+ let $t0100496100886 = if ((0 >= virtWlgPoints))
17401560 then $Tuple2(0, nil)
17411561 else {
17421562 let deltaXP = asInt(invoke(wlgContract, "takeWlgXp", [addr], nil))
17441564 then $Tuple2(virtWlgPoints, [IntegerEntry(keyUserLevel(addr), asInt(virtWlgData[0])), IntegerEntry(keyUserXP(addr), asInt(virtWlgData[2]))])
17451565 else throw("Strict value is not equal to itself.")
17461566 }
1747- let wlgPoints = $t0100244100634._1
1748- let wlgActions = $t0100244100634._2
1567+ let wlgPoints = $t0100496100886._1
1568+ let wlgActions = $t0100496100886._2
17491569 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
17501570 let freeKeyAcc = keyUserFreePoints(addr)
17511571 let freePointsAcc = (valueOrElse(getInteger(freeKeyAcc), 0) + wlgPoints)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let KS_SEPARATE_PUBLIC_KEY = false
55
66 let KS_ALLOW_ROBO_DUCKS = false
7-
8-let DAY_MILLIS = 86400000
97
108 let OLD_STAKING_DEADLINE = 1733248800000
119
1210 let chain = take(drop(this.bytes, 1), 1)
1311
1412 let pub = match chain {
1513 case _ =>
1614 if ((base58'2W' == $match0))
1715 then if (KS_SEPARATE_PUBLIC_KEY)
1816 then base58'CWsMtTZC5BjjoL4Q1ayW4Wwb1ehGACQB6DrKyPgotKfm'
1917 else base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
2018 else if ((base58'2T' == $match0))
2119 then base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
2220 else throw("Unknown chain")
2321 }
2422
2523 let usdtAssetId = match chain {
2624 case _ =>
2725 if ((base58'2W' == $match0))
2826 then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
2927 else if ((base58'2T' == $match0))
3028 then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63'
3129 else throw("Unknown chain")
3230 }
3331
3432 let defaultRestAddressStr = match chain {
3533 case _ =>
3634 if ((base58'2W' == $match0))
3735 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
3836 else if ((base58'2T' == $match0))
3937 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
4038 else throw("Unknown chain")
4139 }
4240
4341 let acres2AddressStr = match chain {
4442 case _ =>
4543 if ((base58'2W' == $match0))
4644 then "3P4UH3T9nXpMNpUmSmQjPmEz3G85t3zn6eA"
4745 else if ((base58'2T' == $match0))
4846 then "3NBPx1Fciu3JQNEGZ21jSnTdutLNGGBUSXh"
4947 else throw("Unknown chain")
5048 }
5149
52-let arbitrageDelay = match chain {
53- case _ =>
54- if ((base58'2W' == $match0))
55- then DAY_MILLIS
56- else if ((base58'2T' == $match0))
57- then 60000
58- else throw("Unknown chain")
59-}
60-
6150 let SEP = "__"
6251
6352 let MULT6 = 1000000
6453
6554 let MULT8 = 100000000
6655
6756 let SSIZE = 25
6857
6958 let MSIZE = 100
7059
7160 let LSIZE = 225
7261
7362 let XLSIZE = 400
7463
7564 let XXLSIZE = 625
7665
7766 let ITER6 = [0, 1, 2, 3, 4, 5]
7867
7968 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
8069
8170
8271 let IdxCfgEconomyDapp = 2
83-
84-let IdxCfgGovernanceDapp = 3
8572
8673 let IdxCfgWlgDapp = 4
8774
8875 let IdxCfgTournamentDapp = 7
8976
9077 let IdxCfgAcresDapp = 8
9178
9279 func keyRestCfg () = "%s__restConfig"
9380
9481
9582 func keyRestAddress () = "%s__restAddr"
9683
9784
9885 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
9986
10087
10188 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
10289
10390
10491 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
10592
10693 let restCfg = readRestCfgOrFail(restContract)
10794
10895 let economyContract = getContractAddressOrFail(restCfg, IdxCfgEconomyDapp)
10996
110-let govContract = getContractAddressOrFail(restCfg, IdxCfgGovernanceDapp)
111-
11297 let wlgContract = getContractAddressOrFail(restCfg, IdxCfgWlgDapp)
11398
11499 let tournamentContract = getContractAddressOrFail(restCfg, IdxCfgTournamentDapp)
115100
116101 let acresContract = getContractAddressOrFail(restCfg, IdxCfgAcresDapp)
117102
118103 let recLandNum = 0
119104
120105 let recLandSize = 1
121106
122107 let recTerrains = 2
123108
124-let recContinent = 3
125-
126109 let acresAssetIdKey = "acresAssetId"
127110
128111 let acresAssetId = valueOrErrorMessage(getBinary(acresContract, acresAssetIdKey), "ACRES is not issued yet")
129112
130113 let randomDelay = 2
131114
132115 func keyCommit (address) = ("finishBlockFor_" + address)
133116
134117
135118 func keyResProportions () = "resTypesProportions"
136-
137-
138-func keyResTypesByContinent (continent) = ("resTypesByContinent_" + continent)
139119
140120
141121 func keyStakedLandsByOwner (ownerAddr) = ("stakedLandsByOwner_" + ownerAddr)
142122
143123
144124 func keyStakedPiecesByOwner (ownerAddr) = ("stakedPiecesByOwner_" + ownerAddr)
145125
146126
147127 func asInt (v) = match v {
148128 case n: Int =>
149129 n
150130 case _ =>
151131 throw("fail to cast into Int")
152132 }
153133
154134
155135 func asAnyList (v) = match v {
156136 case l: List[Any] =>
157137 l
158138 case _ =>
159139 throw("fail to cast into List[Any]")
160140 }
161141
162142
163143 func numPiecesBySize (landSize) = match landSize {
164144 case _ =>
165145 if (("S" == $match0))
166146 then SSIZE
167147 else if (("M" == $match0))
168148 then MSIZE
169149 else if (("L" == $match0))
170150 then LSIZE
171151 else if (("XL" == $match0))
172152 then XLSIZE
173153 else if (("XXL" == $match0))
174154 then XXLSIZE
175155 else throw("Unknown land size")
176156 }
177157
178158
179159 func keyBlocked () = "contractsBlocked"
180160
181161
182162 func keyLastWeekTxIdByUser (addr) = ("lastWeekTxIdByUser_" + addr)
183163
184164
185165 func keyCurWeekTxIdByUser (addr) = ("curWeekTxIdByUser_" + addr)
186166
187167
188168 func fixedPoint (val,decimals) = {
189169 let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
190170 let lowPart = toString((val % tenPow))
191171 let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
192172 (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
193173 }
194174
195175
196176 func getRandomNumber (maxValue,salt,entropy) = if ((0 >= maxValue))
197177 then throw("maxValue should be > 0")
198178 else {
199179 let randomHash = sha256_16Kb((salt + entropy))
200180 (toInt(randomHash) % maxValue)
201181 }
202182
203183
204184 func finalTime () = min([lastBlock.timestamp, OLD_STAKING_DEADLINE])
205185
206186
207187 let LANDPREFIX = "LAND"
208188
209189 let DUCKPREFIX = "DUCK"
210190
211191 let ROBO_PREFIX = "ROBO"
212192
213193 let ARTPRESALE = "PRESALE"
214194
215195 let NUMRES = 6
216-
217-let MAX_LANDS_STAKED_BY_USER = 25
218196
219197 let DAILYRESBYPIECE = 3456000
220198
221199 let WHMULTIPLIER = 10000000000
222200
223201 let DEFAULTLOCATION = "Africa_F_Africa"
224202
225203 let RESOURCEPRICEMIN = 39637
226204
227205 let MIN_USDT_FEE_DELIVERY = 50000
228206
229207 let USDT2ACRES_MULTIPLIER = 10
230208
231209 let ALLOWED_FREE_DELIVERIES = 0
232210
233211 let ACRES_FOR_DELIVERY_ATTEMPT = 200000000
234212
235213 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"]
236214
237215 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_"]
238216
239217 let rIdxCoeff = 6
240218
241219 let rIdxRequirements = 9
242220
243221 let rIdxSlots = 10
244222
245223 let PRODUCTPKGSIZE = 10
246224
247225 let whIdxLevels = 0
248226
249227 let whIdxRes = 1
250228
251229 let whIdxMat = 2
252230
253231 let whIdxProd = 3
254232
255233 let whIdxLOFT = 4
256234
257235 let volLocked = 0
258236
259237 let volOccupied = 1
260238
261239 let volFree = 2
262240
263241 let volTotal = 3
264242
265243 let bpIdxLevel = 0
266244
267245 let bpIdxRes = 1
268246
269247 let bpIdxMat = 2
270248
271249 let bpIdxProd = 3
272250
273251 let locIdxType = 1
274252
275253 let locIdxId = 2
276254
277255 func keyLandAssetIdToOwner (assetId) = ("no_" + assetId)
278256
279257
280258 func keyLandAssetIdToCustomName (assetId) = ("lcna_" + assetId)
281259
282260
283261 func keyStakedTimeByAssetId (assetId) = ("st_" + assetId)
284262
285263
286264 func keyLandArtStatusByTypeAndAssetId (type,assetId) = makeString(["las", type, assetId], "_")
287265
288266
289267 func keyStakedTimeByTypeAssetIdAndOwner (nftType,assetId,ownerAddr) = ((((("sttao_" + nftType) + "_") + assetId) + "_") + ownerAddr)
290268
291269
292270 func keyWarehouseByLand (landAssetId) = ("wh_" + landAssetId)
293271
294272
295273 func keyInfraLevelByAssetId (assetId) = ("infraLevel_" + assetId)
296274
297275
298276 func keyDuckAssetIdToCustomName (assetId) = ("duckCustomNameByAssetId_" + assetId)
299277
300278
301279 func keyAddressToCustomName (addr) = ("accountCustomNameByAddr_" + addr)
302280
303281
304282 func keyAddressRefBy (addr) = ("accRefBy_" + addr)
305283
306284
307285 func keyOnboardArtActivatedOnDuck (duckAssetId) = ("onboardArtActivatedOnDuck_" + duckAssetId)
308286
309287
310288 func keyOnboardArtDuckActivatedBy (addr) = ("onboardArtActivatedDuckBy_" + addr)
311289
312290
313291 func keyAddressReferrals (addr) = ("accReferrals_" + addr)
314292
315293
316294 func keyDuckIdToOwner (assetId) = ("duckOwner_" + assetId)
317295
318296
319297 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
320298
321299
322300 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
323301
324302
325303 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
326304
327305
328-func keyUserGwlReleaseTime (userAddr) = ("%s%s__userGwlReleaseTime__" + userAddr)
329-
330-
331306 let deliveryFundKey = "deliveryFund"
332307
333308 let lastTourIdKey = "%s__lastTourId"
334309
335310 let SCALE8 = 100000000
336311
337312 let xpLevelScale = 3200
338313
339314 let xpLevelRecipPow = 4000
340315
341316 let numPointsOnLevelUp = 3
342317
343318 let requirements = ["Strength", "Accuracy", "Intellect", "Endurance", "Dexterity", "Level", "Health"]
344319
345320 let charStrength = 0
346321
347322 let charAccuracy = 1
348323
349324 let charIntellect = 2
350325
351326 let charEndurance = 3
352327
353328 let charDexterity = 4
354329
355330 let NUMMAINAUX = 2
356331
357332 let MAXSLOTS = 2
358333
359334 let MAXPRODINSLOT = 30
360335
361336 func keyDuckHealth (duckAssetId) = ("duckHealth_" + duckAssetId)
362337
363338
364339 func keyDuckChars (duckAssetId) = ("duckChars_" + duckAssetId)
365340
366341
367342 func keyDuckXP (duckAssetId) = ("duckXP_" + duckAssetId)
368343
369344
370345 func keyDuckLevel (duckAssetId) = ("duckLevel_" + duckAssetId)
371346
372347
373348 func keyDuckFreePoints (duckAssetId) = ("duckFreePoints_" + duckAssetId)
374349
375350
376351 func keyDuckEquipment (duckAssetId) = ("duckEquipment_" + duckAssetId)
377352
378353
379354 func keyUserXP (addr) = ("userXP_" + addr)
380355
381356
382357 func keyUserLevel (addr) = ("userLevel_" + addr)
383358
384359
385360 func keyUserFreePoints (addr) = ("userFreePoints_" + addr)
386361
387362
388363 func keySavedHealth (duckAssetId) = ("savedHealth_" + duckAssetId)
389364
390365
391366 func keySavedLocation (duckAssetId) = ("savedLocation_" + duckAssetId)
392367
393368
394369 func keyDuckDeliveryCount (duckAssetId) = ("totalDeliveryCountByDuck_" + duckAssetId)
395370
396371
397372 func keyUserDeliveryCount (addr) = ("userDeliveryCount_" + addr)
398373
399374
400375 func keyUserLastDeliveryDay (addr) = ("userLastDeliveryDay_" + addr)
401376
402377
403378 let xpClaim = 10000
404379
405380 let xpCustomName = 1000000
406381
407382 let xpOnboard = 1000000
408383
409384 func levelByXP (xp) = fraction(xpLevelScale, pow(xp, 4, xpLevelRecipPow, 4, 4, DOWN), SCALE8)
410385
411386
412387 func maxHealth (level) = (100 + level)
413388
414389
415390 func levelUp (currLevel,newXP) = {
416391 let newLevel = levelByXP(newXP)
417392 [newLevel, (numPointsOnLevelUp * (newLevel - currLevel))]
418393 }
419394
420395
421396 let DAYMILLIS = 86400000
422397
423-func keyLastWlgTradeTimeByUser (addr) = ("lastArbTimeUser_" + addr)
424-
425-
426398 func keyAcresStakedAmountByUser (addr) = ("acresStakedAmountByUser_" + addr)
427399
428400
429401 let RENAMINGCOST = 5000000
430402
431403 let MAXNAMELEN = 50
432404
433405 let PRESALENUMLANDS = 500
434406
435407 func keyLandCustomNameToAssetId (name) = ("lcn_" + name)
436-
437-
438-func keyInfraLevelByAssetIdAndOwner (assetId,ownerAddr) = ((("ilao_" + assetId) + "_") + ownerAddr)
439-
440-
441-func keyLandNumToOwner (landNum) = ("lo_" + landNum)
442408
443409
444410 func keyDuckCustomNameToAssetId (name) = ("duckByCustomName_" + name)
445411
446412
447413 func keyCustomNameToAddress (name) = ("accountByCustomName_" + name)
448414
449415
450416 func keyOldies () = "oldiesList"
451417
452418
453419 let claimModeWh = 0
454420
455421 let claimModeDuck = 1
456422
457423 let claimModeWhThenDuck = 2
458424
459425 func distributeByWeights (total,weights) = {
460426 let sum = (((((weights[0] + weights[1]) + weights[2]) + weights[3]) + weights[4]) + weights[5])
461427 if ((0 >= sum))
462428 then throw("Zero weights sum")
463429 else {
464430 let norm6 = fraction(total, MULT6, sum)
465431 func normalizer (acc,elem) = (acc :+ fraction(elem, norm6, MULT6))
466432
467433 let $l = weights
468434 let $s = size($l)
469435 let $acc0 = nil
470436 func $f0_1 ($a,$i) = if (($i >= $s))
471437 then $a
472438 else normalizer($a, $l[$i])
473439
474440 func $f0_2 ($a,$i) = if (($i >= $s))
475441 then $a
476442 else throw("List size exceeds 6")
477443
478444 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
479445 }
480446 }
481447
482448
483449 func getNeededMaterials (total) = {
484450 let props = split(value(getString(keyResProportions())), "_")
485451 if ((size(props) != NUMRES))
486452 then throw("Wrong proportions data")
487453 else {
488454 let r = [parseIntValue(props[0]), parseIntValue(props[1]), parseIntValue(props[2]), parseIntValue(props[3]), parseIntValue(props[4]), parseIntValue(props[5])]
489455 distributeByWeights(total, r)
490456 }
491457 }
492458
493459
494460 func prodStrToBytes (prodStr) = {
495461 let pList = if ((prodStr == ""))
496462 then nil
497463 else split_4C(prodStr, "_")
498464 func toBV (acc,recipe) = {
499465 let j = (size(acc) / 8)
500466 let curr = if ((size(pList) > j))
501467 then parseIntValue(pList[j])
502468 else 0
503469 (acc + toBytes(curr))
504470 }
505471
506472 let $l = productionMatrix
507473 let $s = size($l)
508474 let $acc0 = base58''
509475 func $f0_1 ($a,$i) = if (($i >= $s))
510476 then $a
511477 else toBV($a, $l[$i])
512478
513479 func $f0_2 ($a,$i) = if (($i >= $s))
514480 then $a
515481 else throw("List size exceeds 50")
516482
517483 $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)
518484 }
519485
520486
521487 func bytesToProdStr (bv) = {
522488 func fromBV (acc,recipe) = {
523489 let j = size(acc)
524490 let b = take(drop(bv, (8 * j)), 8)
525491 (acc :+ toString(toInt(b)))
526492 }
527493
528494 makeString_2C({
529495 let $l = productionMatrix
530496 let $s = size($l)
531497 let $acc0 = nil
532498 func $f0_1 ($a,$i) = if (($i >= $s))
533499 then $a
534500 else fromBV($a, $l[$i])
535501
536502 func $f0_2 ($a,$i) = if (($i >= $s))
537503 then $a
538504 else throw("List size exceeds 50")
539505
540506 $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)
541507 }, "_")
542508 }
543509
544510
545511 func checkStatRequirements (duckStats,reqs) = {
546512 func check (acc,j) = {
547513 let buff = if ((size(duckStats) > (7 + j)))
548514 then duckStats[(7 + j)]
549515 else 0
550516 if ((parseIntValue(reqs[j]) > (duckStats[j] + buff)))
551517 then throw(("Requirement not satisfied: " + requirements[j]))
552518 else true
553519 }
554520
555521 let $l = [0, 1, 2, 3, 4, 5, 6]
556522 let $s = size($l)
557523 let $acc0 = false
558524 func $f0_1 ($a,$i) = if (($i >= $s))
559525 then $a
560526 else check($a, $l[$i])
561527
562528 func $f0_2 ($a,$i) = if (($i >= $s))
563529 then $a
564530 else throw("List size exceeds 7")
565531
566532 $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)
567533 }
568534
569535
570536 func addProdB (idxCnt,pList,isPositive,segment,mainAux,slot,duckStats) = {
571537 let parts = split(idxCnt, ":")
572538 if ((size(parts) != 2))
573539 then throw("Incorrect format, should be index:amount")
574540 else if (if (!(isPositive))
575541 then (size(parts[0]) != 2)
576542 else false)
577543 then throw("Product idx should be 2 digits, zero padded")
578544 else {
579545 let productIdx = parseIntValue(parts[0])
580546 let count = parseIntValue(parts[1])
581547 if (if ((0 > productIdx))
582548 then true
583549 else (productIdx >= size(productionMatrix)))
584550 then throw("Unknown product idx")
585551 else if ((0 > count))
586552 then throw("Count can't be negative")
587553 else if ((count > MAXPRODINSLOT))
588554 then throw(((("Can't put more than " + toString(MAXPRODINSLOT)) + " of ") + prodTypes[productIdx]))
589555 else if ((count == 0))
590556 then $Tuple2(pList, false)
591557 else {
592558 let head = take(pList, (8 * productIdx))
593559 let curr = toInt(take(drop(pList, (8 * productIdx)), 8))
594560 let tail = drop(pList, (8 * (productIdx + 1)))
595561 let recipe = split(productionMatrix[productIdx], "_")
596562 if (if (!(isPositive))
597563 then (count > curr)
598564 else false)
599565 then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[productIdx]) + ", but tried to use ") + toString(count)))
600566 else {
601567 let isBigItem = if (if (!(isPositive))
602568 then checkStatRequirements(duckStats, split(recipe[rIdxRequirements], ","))
603569 else false)
604570 then {
605571 let compat = recipe[rIdxSlots]
606572 if ((compat == ""))
607573 then throw("Item cannot be equipped")
608574 else {
609575 let c = parseIntValue(compat)
610576 let cSeg = (c / 100)
611577 if ((segment != cSeg))
612578 then throw("Segment incompatible")
613579 else {
614580 let cMainAux = ((c % 100) / 10)
615581 if ((mainAux != cMainAux))
616582 then throw("Slot incompatible")
617583 else {
618584 let cNumSlots = (c % 10)
619585 if (if ((slot != 0))
620586 then (cNumSlots > 1)
621587 else false)
622588 then throw("Big items should occupy slot 0")
623589 else (cNumSlots > 1)
624590 }
625591 }
626592 }
627593 }
628594 else false
629595 $Tuple2(((head + toBytes((curr + (if (isPositive)
630596 then count
631597 else -(count))))) + tail), isBigItem)
632598 }
633599 }
634600 }
635601 }
636602
637603
638604 func slotsGroupB (g,bpIn,isPositive,segment,mainAux,stats) = if ((g != ""))
639605 then {
640606 let slots = split(g, ",")
641607 if ((size(slots) > MAXSLOTS))
642608 then throw("Wrong slots format")
643609 else {
644610 let s0 = slots[0]
645611 let s1 = if ((size(slots) > 1))
646612 then slots[1]
647613 else ""
648614 if (if ((s0 == ""))
649615 then (s1 == "")
650616 else false)
651617 then bpIn
652618 else {
653619 let tmpS0 = if ((s0 != ""))
654620 then addProdB(s0, bpIn, isPositive, segment, mainAux, 0, stats)
655621 else $Tuple2(bpIn, false)
656622 if ((s1 != ""))
657623 then if (tmpS0._2)
658624 then throw("Big item already occupies slot")
659625 else addProdB(s1, tmpS0._1, isPositive, segment, mainAux, 1, stats)._1
660626 else tmpS0._1
661627 }
662628 }
663629 }
664630 else bpIn
665631
666632
667633 func dressB (segList,pBytes,isPositive,stats) = {
668634 func segment (acc,seg) = {
669635 let j = acc._1
670636 let mainAux = split(seg, ";")
671637 if ((size(mainAux) != NUMMAINAUX))
672638 then throw("Wrong segment format")
673639 else {
674640 let m = mainAux[0]
675641 let a = mainAux[1]
676642 if (if ((m == ""))
677643 then (a == "")
678644 else false)
679645 then $Tuple2((j + 1), acc._2)
680646 else {
681647 let tmpM = slotsGroupB(m, acc._2, isPositive, j, 0, stats)
682648 $Tuple2((j + 1), slotsGroupB(a, tmpM, isPositive, j, 1, stats))
683649 }
684650 }
685651 }
686652
687653 ( let $l = segList
688654 let $s = size($l)
689655 let $acc0 = $Tuple2(0, pBytes)
690656 func $f0_1 ($a,$i) = if (($i >= $s))
691657 then $a
692658 else segment($a, $l[$i])
693659
694660 func $f0_2 ($a,$i) = if (($i >= $s))
695661 then $a
696662 else throw("List size exceeds 6")
697663
698664 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6))._2
699- }
700-
701-
702-func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
703- then throw("Wrong proportions data")
704- else {
705- func updater (acc,i) = {
706- let result = (parseIntValue(propList[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
707- if ((0 > result))
708- then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
709- else (acc :+ toString(result))
710- }
711-
712- let $l = ITER6
713- let $s = size($l)
714- let $acc0 = nil
715- func $f0_1 ($a,$i) = if (($i >= $s))
716- then $a
717- else updater($a, $l[$i])
718-
719- func $f0_2 ($a,$i) = if (($i >= $s))
720- then $a
721- else throw("List size exceeds 6")
722-
723- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
724- }
725-
726-
727-func updateProportions (terrainCounts,landSizeIndex,sign) = {
728- let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
729- makeString(updateProportionsInternal(propList, terrainCounts, landSizeIndex, sign), "_")
730665 }
731666
732667
733668 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)]
734669
735670
736671 func addRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
737672 func adder (acc,i) = {
738673 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
739674 (acc :+ toString((parseIntValue(currentRes[i]) + resOfType)))
740675 }
741676
742677 let r = {
743678 let $l = ITER6
744679 let $s = size($l)
745680 let $acc0 = nil
746681 func $f0_1 ($a,$i) = if (($i >= $s))
747682 then $a
748683 else adder($a, $l[$i])
749684
750685 func $f0_2 ($a,$i) = if (($i >= $s))
751686 then $a
752687 else throw("List size exceeds 6")
753688
754689 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
755690 }
756691 makeString(r, "_")
757692 }
758693
759694
760695 func virtClaimAddRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
761696 func adder (acc,i) = {
762697 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
763698 let totalResType = (parseIntValue(currentRes[i]) + resOfType)
764699 $Tuple2((acc._1 :+ totalResType), (acc._2 + totalResType))
765700 }
766701
767702 let $l = ITER6
768703 let $s = size($l)
769704 let $acc0 = $Tuple2(nil, 0)
770705 func $f0_1 ($a,$i) = if (($i >= $s))
771706 then $a
772707 else adder($a, $l[$i])
773708
774709 func $f0_2 ($a,$i) = if (($i >= $s))
775710 then $a
776711 else throw("List size exceeds 6")
777712
778713 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
779714 }
780715
781716
782717 func virtClaim (terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
783718 func adder (acc,terrainCount) = {
784719 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCount) * landSizeIndex)
785720 $Tuple2((acc._1 :+ resOfType), (acc._2 + resOfType))
786721 }
787722
788723 let $l = terrainCounts
789724 let $s = size($l)
790725 let $acc0 = $Tuple2(nil, 0)
791726 func $f0_1 ($a,$i) = if (($i >= $s))
792727 then $a
793728 else adder($a, $l[$i])
794729
795730 func $f0_2 ($a,$i) = if (($i >= $s))
796731 then $a
797732 else throw("List size exceeds 6")
798733
799734 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
800735 }
801736
802737
803738 func distributeRes (currentWhRes,currentPackRes,resToClaim,whSpaceLeft) = {
804739 let resListToClaim = resToClaim._1
805740 let resAmToClaim = resToClaim._2
806741 if ((resAmToClaim == 0))
807742 then $Tuple2(makeString(currentWhRes, "_"), makeString(currentPackRes, "_"))
808743 else if ((whSpaceLeft >= resAmToClaim))
809744 then {
810745 func addLists (acc,i) = (acc :+ toString((parseIntValue(currentWhRes[i]) + resListToClaim[i])))
811746
812747 let r = {
813748 let $l = ITER6
814749 let $s = size($l)
815750 let $acc0 = nil
816751 func $f0_1 ($a,$i) = if (($i >= $s))
817752 then $a
818753 else addLists($a, $l[$i])
819754
820755 func $f0_2 ($a,$i) = if (($i >= $s))
821756 then $a
822757 else throw("List size exceeds 6")
823758
824759 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
825760 }
826761 $Tuple2(makeString(r, "_"), makeString(currentPackRes, "_"))
827762 }
828763 else {
829764 func addPartLists (acc,i) = {
830765 let whPart = fraction(resListToClaim[i], whSpaceLeft, resAmToClaim)
831766 $Tuple2((acc._1 :+ toString((parseIntValue(currentWhRes[i]) + whPart))), (acc._2 :+ toString(((parseIntValue(currentPackRes[i]) + resListToClaim[i]) - whPart))))
832767 }
833768
834769 let r = {
835770 let $l = ITER6
836771 let $s = size($l)
837772 let $acc0 = $Tuple2(nil, nil)
838773 func $f0_1 ($a,$i) = if (($i >= $s))
839774 then $a
840775 else addPartLists($a, $l[$i])
841776
842777 func $f0_2 ($a,$i) = if (($i >= $s))
843778 then $a
844779 else throw("List size exceeds 6")
845780
846781 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
847782 }
848783 $Tuple2(makeString(r._1, "_"), makeString(r._2, "_"))
849784 }
850785 }
851786
852787
853788 func getBackpack (bpKey) = {
854789 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
855790 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
856791 then p[bpIdxRes]
857792 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
858793 then p[bpIdxMat]
859794 else "0_0_0_0_0_0", p[bpIdxProd]]
860795 }
861796
862797
863798 func getWarehouseTotalVolume (volPrefix) = {
864799 let parts = split(volPrefix, "_")
865800 ((WHMULTIPLIER * (parseIntValue(parts[1]) + 1)) * parseIntValue(parts[0]))
866801 }
867802
868803
869804 func getWarehouseOccupiedVol (currentWh) = {
870805 let goods = currentWh[whIdxProd]
871806 func sumResMat (acc,item) = (acc + parseIntValue(item))
872807
873808 func sumProd (acc,item) = {
874809 let idx = acc._1
875810 let pkgs = (((parseIntValue(item) + PRODUCTPKGSIZE) - 1) / PRODUCTPKGSIZE)
876811 $Tuple2((idx + 1), (acc._2 + (pkgs * MULT8)))
877812 }
878813
879814 let whResVol = {
880815 let $l = split(currentWh[whIdxRes], "_")
881816 let $s = size($l)
882817 let $acc0 = 0
883818 func $f0_1 ($a,$i) = if (($i >= $s))
884819 then $a
885820 else sumResMat($a, $l[$i])
886821
887822 func $f0_2 ($a,$i) = if (($i >= $s))
888823 then $a
889824 else throw("List size exceeds 6")
890825
891826 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
892827 }
893828 let whMatVol = {
894829 let $l = split(currentWh[whIdxMat], "_")
895830 let $s = size($l)
896831 let $acc0 = 0
897832 func $f1_1 ($a,$i) = if (($i >= $s))
898833 then $a
899834 else sumResMat($a, $l[$i])
900835
901836 func $f1_2 ($a,$i) = if (($i >= $s))
902837 then $a
903838 else throw("List size exceeds 6")
904839
905840 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
906841 }
907842 let whGoodsVol = if ((goods == ""))
908843 then 0
909844 else ( let $l = split_4C(goods, "_")
910845 let $s = size($l)
911846 let $acc0 = $Tuple2(0, 0)
912847 func $f2_1 ($a,$i) = if (($i >= $s))
913848 then $a
914849 else sumProd($a, $l[$i])
915850
916851 func $f2_2 ($a,$i) = if (($i >= $s))
917852 then $a
918853 else throw("List size exceeds 50")
919854
920855 $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
921856 ((whResVol + whMatVol) + whGoodsVol)
922857 }
923858
924859
925860 func getWarehouse (whKey,landIndex,infraLevel) = {
926861 let volPrefix = ((toString(landIndex) + "_") + toString(infraLevel))
927862 let whTotal = getWarehouseTotalVolume(volPrefix)
928863 let whStr = valueOrElse(getString(whKey), (volPrefix + ":0_0_0_0_0_0:0_0_0_0_0_0::0"))
929864 let wh = split_4C(whStr, ":")
930865 let whOccupied = getWarehouseOccupiedVol(wh)
931866 let whLoft = if ((5 > size(wh)))
932867 then makeString(["0", toString(whOccupied), toString((whTotal - whOccupied)), toString(whTotal)], "_")
933868 else {
934869 let loft = split(wh[whIdxLOFT], "_")
935870 let whLocked = parseIntValue(loft[volLocked])
936871 let occ = if ((size(loft) > 1))
937872 then parseIntValue(loft[volOccupied])
938873 else whOccupied
939874 makeString([toString(whLocked), toString(occ), toString(((whTotal - whLocked) - occ)), toString(whTotal)], "_")
940875 }
941876 [wh[whIdxLevels], if ((size(split(wh[whIdxRes], "_")) == NUMRES))
942877 then wh[whIdxRes]
943878 else "0_0_0_0_0_0", if ((size(split(wh[whIdxMat], "_")) == NUMRES))
944879 then wh[whIdxMat]
945880 else "0_0_0_0_0_0", wh[whIdxProd], whLoft]
946881 }
947882
948883
949884 func applyBonuses (landAssetId,pieces) = {
950885 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
951886 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
952887 let add6 = (infraLevel / 6)
953888 let add7 = (infraLevel / 7)
954889 ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, ((infraLevel + add6) + (2 * add7)), 5)) + fraction(DAILYRESBYPIECE, artPieces, (pieces * 5)))
955890 }
956891
957892
958893 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
959894 let $t03424734786 = if ((claimMode == claimModeWh))
960895 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
961896 else {
962897 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
963898 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
964899 let loc = split(value(curLocation), "_")
965900 if ((loc[locIdxType] != "L"))
966901 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
967902 else $Tuple2(loc[locIdxId], duckAssetId)
968903 }
969904 let landAssetId = $t03424734786._1
970905 let duckId = $t03424734786._2
971906 let asset = value(assetInfo(fromBase58String(landAssetId)))
972907 let timeKey = keyStakedTimeByAssetId(landAssetId)
973908 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
974909 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
975910 if ((owner != addr))
976911 then throw((LANDPREFIX + " is not yours"))
977912 else {
978913 let d = split(asset.description, "_")
979914 $Tuple4(duckId, landAssetId, d, savedTime)
980915 }
981916 }
982917
983918
984919 func claimResInternal (addr,amount,claimMode,landAssetIdIn) = if ((0 > amount))
985920 then throw("Negative amount")
986921 else {
987922 let c = checkClaimConditions(addr, claimMode, landAssetIdIn)
988923 let landSize = c._3[recLandSize]
989924 let terrainCounts = countTerrains(c._3[recTerrains])
990925 let deltaTime = (finalTime() - c._4)
991926 if ((0 > deltaTime))
992927 then throw(((("Saved timestamp is in future, saved = " + toString(c._4)) + ", final = ") + toString(finalTime())))
993928 else {
994929 let pieces = numPiecesBySize(landSize)
995930 let dailyProductionByPiece = applyBonuses(c._2, pieces)
996931 let availRes = fraction(deltaTime, (dailyProductionByPiece * pieces), DAYMILLIS)
997932 if ((amount > availRes))
998933 then throw(((("Not enough resources, available = " + toString(availRes)) + ", requested = ") + toString(amount)))
999934 else {
1000935 let newDeltaTime = fraction((availRes - amount), DAYMILLIS, (dailyProductionByPiece * pieces))
1001936 let newTimestamp = (finalTime() - newDeltaTime)
1002937 let landIndex = (pieces / SSIZE)
1003938 let resToClaim = virtClaim(terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece)
1004939 let whKey = keyWarehouseByLand(c._2)
1005940 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(c._2)), 0)
1006941 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
1007942 let loft = split(currentWh[whIdxLOFT], "_")
1008943 let whSpaceLeft = parseIntValue(loft[volFree])
1009944 if (if ((claimMode == claimModeWh))
1010945 then (amount > whSpaceLeft)
1011946 else false)
1012947 then throw((("Only " + toString(whSpaceLeft)) + " space left in warehouse"))
1013948 else {
1014949 let bpKey = keyBackpackByDuck(c._1)
1015950 let currentPack = getBackpack(bpKey)
1016951 let currentPackRes = split(currentPack[bpIdxRes], "_")
1017952 let currentWhRes = split(currentWh[whIdxRes], "_")
1018953 let $t03715638027 = if ((claimMode == claimModeWh))
1019954 then $Tuple4(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes], (parseIntValue(loft[volOccupied]) + resToClaim._2), (parseIntValue(loft[volFree]) - resToClaim._2))
1020955 else if ((claimMode == claimModeDuck))
1021956 then $Tuple4(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), parseIntValue(loft[volOccupied]), parseIntValue(loft[volFree]))
1022957 else {
1023958 let distr = distributeRes(currentWhRes, currentPackRes, resToClaim, whSpaceLeft)
1024959 let whAm = min([parseIntValue(loft[volFree]), resToClaim._2])
1025960 $Tuple4(distr._1, distr._2, (parseIntValue(loft[volOccupied]) + whAm), (parseIntValue(loft[volFree]) - whAm))
1026961 }
1027962 let whRes = $t03715638027._1
1028963 let bpRes = $t03715638027._2
1029964 let loftO = $t03715638027._3
1030965 let loftF = $t03715638027._4
1031966 $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]], "_")])
1032967 }
1033968 }
1034969 }
1035970 }
1036971
1037972
1038973 func claimAll (addr,landAssetId,pieces,claimMode) = {
1039974 let timeKey = keyStakedTimeByAssetId(landAssetId)
1040975 let savedTime = value(getInteger(timeKey))
1041976 let availRes = (fraction((finalTime() - savedTime), applyBonuses(landAssetId, pieces), DAYMILLIS) * pieces)
1042977 claimResInternal(addr, availRes, claimMode, landAssetId)
1043978 }
1044979
1045980
1046981 func updateStatsInternal (lvlKey,xpKey,pointsKey,deltaXP) = {
1047982 let xp = valueOrElse(getInteger(xpKey), 0)
1048983 let newXP = (xp + deltaXP)
1049984 let lvlPoints = levelUp(valueOrElse(getInteger(lvlKey), 0), newXP)
1050985 $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(pointsKey, (valueOrElse(getInteger(pointsKey), 0) + lvlPoints[1]))], newXP)
1051986 }
1052987
1053988
1054989 func updateDuckStatsInternal (duckAssetId,deltaXP) = {
1055990 let asset = value(assetInfo(fromBase58String(duckAssetId)))
1056991 let addr = valueOrErrorMessage(getString(keyDuckIdToOwner(duckAssetId)), (("NFT " + asset.name) + " is orphaned"))
1057992 if (if (if (KS_ALLOW_ROBO_DUCKS)
1058993 then (asset.issuer == this)
1059994 else false)
1060995 then contains(asset.name, ROBO_PREFIX)
1061996 else false)
1062997 then updateStatsInternal(keyUserLevel(addr), keyUserXP(addr), keyUserFreePoints(addr), deltaXP)
1063998 else updateStatsInternal(keyDuckLevel(duckAssetId), keyDuckXP(duckAssetId), keyDuckFreePoints(duckAssetId), deltaXP)
1064999 }
10651000
10661001
10671002 func updateAccStatsInternal (addr,deltaXP) = updateStatsInternal(keyUserLevel(addr), keyUserXP(addr), keyUserFreePoints(addr), deltaXP)
10681003
10691004
10701005 func activateOnboardArt (addr) = {
10711006 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
10721007 let refByKey = keyAddressRefBy(addr)
10731008 let refBy = getString(refByKey)
10741009 if (!(isDefined(refBy)))
10751010 then throw("You are not eligible for ONBOARD artifact")
10761011 else {
10771012 let artKey = keyOnboardArtDuckActivatedBy(addr)
10781013 let artDuck = getString(artKey)
10791014 if (isDefined(artDuck))
10801015 then throw(("You already used your ONBOARD artifact on duck " + value(artDuck)))
10811016 else {
10821017 let duckActivatorKey = keyOnboardArtActivatedOnDuck(duckAssetId)
10831018 let duckActivator = getString(duckActivatorKey)
10841019 if (isDefined(duckActivator))
10851020 then throw(((("The duck " + duckAssetId) + " already got points from ONBOARD artifact from user ") + value(duckActivator)))
10861021 else ([StringEntry(artKey, duckAssetId), StringEntry(duckActivatorKey, addr)] ++ updateDuckStatsInternal(duckAssetId, xpOnboard)._1)
10871022 }
10881023 }
10891024 }
10901025
10911026
10921027 func activatePresaleArt (addr,landAssetIdIn) = {
10931028 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetIdIn)
10941029 let landAssetId = c._2
10951030 let pieces = numPiecesBySize(c._3[recLandSize])
10961031 let activationKey = keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)
10971032 if ((valueOrElse(getInteger(activationKey), 0) > 0))
10981033 then throw("Presale artifact is already activated")
10991034 else if ((parseIntValue(c._3[recLandNum]) > PRESALENUMLANDS))
11001035 then throw((((LANDPREFIX + " ") + landAssetId) + " is not eligible for presale artifact"))
11011036 else {
11021037 let claimResult = claimAll(addr, landAssetId, pieces, claimModeWhThenDuck)
11031038 (((claimResult._1 :+ IntegerEntry(activationKey, pieces)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":"))) :+ StringEntry(claimResult._4, makeString(claimResult._5, ":")))
11041039 }
11051040 }
11061041
11071042
11081043 func prolog (i) = if (if ((i.originCaller != restContract))
11091044 then valueOrElse(getBoolean(keyBlocked()), false)
11101045 else false)
11111046 then throw("Contracts are under maintenance")
11121047 else [StringEntry(keyCurWeekTxIdByUser(toString(i.originCaller)), toBase58String(i.transactionId))]
11131048
11141049
11151050 func unstakeLandInternal (addr,landAssetId) = {
11161051 let whKey = keyWarehouseByLand(landAssetId)
11171052 let landInfo = split(value(assetInfo(fromBase58String(landAssetId))).description, "_")
11181053 let landSize = landInfo[recLandSize]
11191054 let pieces = numPiecesBySize(landSize)
11201055 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
11211056 let landIndex = (pieces / SSIZE)
11221057 let terrainCounts = countTerrains(landInfo[recTerrains])
11231058 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
11241059 let currentWhRes = split(currentWh[whIdxRes], "_")
11251060 let timeKey = keyStakedTimeByAssetId(landAssetId)
11261061 let savedTime = getIntegerValue(timeKey)
11271062 let deltaTime = (finalTime() - savedTime)
11281063 if ((0 > deltaTime))
11291064 then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", final = ") + toString(finalTime())))
11301065 else {
11311066 let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
11321067 let resAfterClaim = virtClaimAddRes(currentWhRes, terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
11331068 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
11341069 let acresFromPieces = ((pieces * MULT8) + ((((pieces * infraLevel) + artPieces) * MULT8) / 5))
11351070 let acresFromRes = (fraction(resAfterClaim._2, RESOURCEPRICEMIN, MULT8) * USDT2ACRES_MULTIPLIER)
11361071 func sumMat (acc,item) = (acc + parseIntValue(item))
11371072
11381073 let whMat = {
11391074 let $l = split(currentWh[whIdxMat], "_")
11401075 let $s = size($l)
11411076 let $acc0 = 0
11421077 func $f0_1 ($a,$i) = if (($i >= $s))
11431078 then $a
11441079 else sumMat($a, $l[$i])
11451080
11461081 func $f0_2 ($a,$i) = if (($i >= $s))
11471082 then $a
11481083 else throw("List size exceeds 6")
11491084
11501085 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
11511086 }
11521087 let acresFromMat = (fraction(whMat, (2 * RESOURCEPRICEMIN), MULT8) * USDT2ACRES_MULTIPLIER)
11531088 let prods = if ((currentWh[whIdxProd] == ""))
11541089 then nil
11551090 else split_4C(currentWh[whIdxProd], "_")
11561091 func sumProd (acc,item) = {
11571092 let j = acc._2
11581093 let recipeCoeff = parseIntValue(split(productionMatrix[j], "_")[rIdxCoeff])
11591094 $Tuple2((acc._1 + ((parseIntValue(item) * recipeCoeff) * MULT6)), (j + 1))
11601095 }
11611096
11621097 let whProd = {
11631098 let $l = prods
11641099 let $s = size($l)
11651100 let $acc0 = $Tuple2(0, 0)
11661101 func $f1_1 ($a,$i) = if (($i >= $s))
11671102 then $a
11681103 else sumProd($a, $l[$i])
11691104
11701105 func $f1_2 ($a,$i) = if (($i >= $s))
11711106 then $a
11721107 else throw("List size exceeds 24")
11731108
11741109 $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($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)
11751110 }
11761111 let acresFromProd = (fraction(whProd._1, (2 * RESOURCEPRICEMIN), MULT8) * USDT2ACRES_MULTIPLIER)
11771112 $Tuple4(acresFromPieces, acresFromRes, acresFromMat, acresFromProd)
11781113 }
11791114 }
11801115
11811116
11821117 func unstakeDuckInternal (addr,duckAssetId) = {
11831118 let eqKey = keyDuckEquipment(duckAssetId)
11841119 let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
11851120 let bpKey = keyBackpackByDuck(duckAssetId)
11861121 let currentPack = getBackpack(bpKey)
11871122 let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
11881123 let newProdStr = bytesToProdStr(tempProdB)
11891124 func sumResMat (acc,item) = (acc + parseIntValue(item))
11901125
11911126 let bpRes = {
11921127 let $l = split(currentPack[bpIdxRes], "_")
11931128 let $s = size($l)
11941129 let $acc0 = 0
11951130 func $f0_1 ($a,$i) = if (($i >= $s))
11961131 then $a
11971132 else sumResMat($a, $l[$i])
11981133
11991134 func $f0_2 ($a,$i) = if (($i >= $s))
12001135 then $a
12011136 else throw("List size exceeds 6")
12021137
12031138 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12041139 }
12051140 let acresFromRes = (fraction(bpRes, RESOURCEPRICEMIN, MULT8) * USDT2ACRES_MULTIPLIER)
12061141 let bpMat = {
12071142 let $l = split(currentPack[bpIdxMat], "_")
12081143 let $s = size($l)
12091144 let $acc0 = 0
12101145 func $f1_1 ($a,$i) = if (($i >= $s))
12111146 then $a
12121147 else sumResMat($a, $l[$i])
12131148
12141149 func $f1_2 ($a,$i) = if (($i >= $s))
12151150 then $a
12161151 else throw("List size exceeds 6")
12171152
12181153 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12191154 }
12201155 let acresFromMat = (fraction(bpMat, (2 * RESOURCEPRICEMIN), MULT8) * USDT2ACRES_MULTIPLIER)
12211156 let prods = if ((newProdStr == ""))
12221157 then nil
12231158 else split_4C(newProdStr, "_")
12241159 func sumProd (acc,item) = {
12251160 let j = acc._2
12261161 let recipeCoeff = parseIntValue(split(productionMatrix[j], "_")[rIdxCoeff])
12271162 $Tuple2((acc._1 + ((parseIntValue(item) * recipeCoeff) * MULT6)), (j + 1))
12281163 }
12291164
12301165 let bpProd = {
12311166 let $l = prods
12321167 let $s = size($l)
12331168 let $acc0 = $Tuple2(0, 0)
12341169 func $f2_1 ($a,$i) = if (($i >= $s))
12351170 then $a
12361171 else sumProd($a, $l[$i])
12371172
12381173 func $f2_2 ($a,$i) = if (($i >= $s))
12391174 then $a
12401175 else throw("List size exceeds 24")
12411176
12421177 $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($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)
12431178 }
12441179 let acresFromProd = (fraction(bpProd._1, (2 * RESOURCEPRICEMIN), MULT8) * USDT2ACRES_MULTIPLIER)
12451180 $Tuple3(acresFromRes, acresFromMat, acresFromProd)
12461181 }
12471182
12481183
12491184 @Callable(i)
12501185 func constructorV1 (restAddr) = if ((i.caller != this))
12511186 then throw("Permission denied")
12521187 else [StringEntry(keyRestAddress(), restAddr)]
12531188
12541189
12551190
12561191 @Callable(i)
12571192 func saveInteger (key,amount) = if ((i.caller != this))
12581193 then throw("saveInteger is not public method")
12591194 else [IntegerEntry(key, amount)]
12601195
12611196
12621197
12631198 @Callable(i)
12641199 func setBlocked (isBlocked) = if ((i.caller != this))
12651200 then throw("permission denied")
12661201 else [BooleanEntry(keyBlocked(), isBlocked)]
12671202
12681203
12691204
12701205 @Callable(i)
1271-func stakeLand () = {
1272- let prologActions = prolog(i)
1273- if ((size(i.payments) != 1))
1274- then throw("Exactly one payment required")
1275- else {
1276- let pmt = value(i.payments[0])
1277- let assetId = value(pmt.assetId)
1278- let address = toString(i.caller)
1279- if ((pmt.amount != 1))
1280- then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
1281- else {
1282- let asset = value(assetInfo(assetId))
1283- if ((asset.issuer != this))
1284- then throw("Unknown issuer of token")
1285- else if (!(contains(asset.name, LANDPREFIX)))
1286- then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
1287- else {
1288- let landNumSize = drop(asset.name, 4)
1289- let landNum = if (contains(landNumSize, "XXL"))
1290- then dropRight(landNumSize, 3)
1291- else if (contains(landNumSize, "XL"))
1292- then dropRight(landNumSize, 2)
1293- else dropRight(landNumSize, 1)
1294- if (!(isDefined(parseInt(landNum))))
1295- then throw(("Cannot parse land number from " + asset.name))
1296- else {
1297- let landAssetId = toBase58String(assetId)
1298- let timeKey = keyStakedTimeByAssetId(landAssetId)
1299- if (isDefined(getInteger(timeKey)))
1300- then throw((("NFT " + asset.name) + " is already staked"))
1301- else {
1302- let d = split(asset.description, "_")
1303- let terrainCounts = countTerrains(d[recTerrains])
1304- let pieces = numPiecesBySize(d[recLandSize])
1305- let landIndex = (pieces / SSIZE)
1306- let props = updateProportions(terrainCounts, landIndex, 1)
1307- let resByContKey = keyResTypesByContinent(d[recContinent])
1308- let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
1309- let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, 1), "_")
1310- let landsKey = keyStakedLandsByOwner(address)
1311- let landsStr = getString(landsKey)
1312- let lands = if (isDefined(landsStr))
1313- then split_51C(value(landsStr), "_")
1314- else nil
1315- if (containsElement(lands, landAssetId))
1316- then throw(("Your staked lands already contain " + landAssetId))
1317- else if ((size(lands) >= MAX_LANDS_STAKED_BY_USER))
1318- then throw((("Your already staked max (" + toString(MAX_LANDS_STAKED_BY_USER)) + ") lands"))
1319- else {
1320- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1321- let piecesKey = keyStakedPiecesByOwner(address)
1322- let oldPieces = valueOrElse(getInteger(piecesKey), 0)
1323- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
1324- $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)
1325- }
1326- }
1327- }
1328- }
1329- }
1330- }
1331- }
1332-
1333-
1334-
1335-@Callable(i)
1336-func unstakeLand (landAssetIdIn) = {
1337- let prologActions = prolog(i)
1338- if ((size(i.payments) != 0))
1339- then throw("No payments required")
1340- else {
1341- let addr = toString(i.caller)
1342- let c = checkClaimConditions(addr, claimModeDuck, landAssetIdIn)
1343- let landAssetId = c._2
1344- let d = c._3
1345- let landsKey = keyStakedLandsByOwner(addr)
1346- let terrainCounts = countTerrains(d[recTerrains])
1347- let pieces = numPiecesBySize(d[recLandSize])
1348- let landIndex = (pieces / SSIZE)
1349- let props = updateProportions(terrainCounts, landIndex, -1)
1350- let resByContKey = keyResTypesByContinent(d[recContinent])
1351- let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
1352- let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, -1), "_")
1353- let claimResult = claimAll(addr, landAssetId, pieces, claimModeDuck)
1354- let lands = split_51C(valueOrElse(getString(landsKey), ""), "_")
1355- let idx = indexOf(lands, landAssetId)
1356- if (!(isDefined(idx)))
1357- then throw(("Your staked lands don't contain " + landAssetId))
1358- else {
1359- let now = lastBlock.timestamp
1360- let govReleaseTime = valueOrElse(getInteger(govContract, keyUserGwlReleaseTime(addr)), 0)
1361- if ((govReleaseTime >= now))
1362- then throw(("Your gWL are taking part in voting, cannot unstake until " + toString(govReleaseTime)))
1363- else {
1364- let arbReleaseTime = (valueOrElse(getInteger(wlgContract, keyLastWlgTradeTimeByUser(addr)), 0) + arbitrageDelay)
1365- if ((arbReleaseTime > now))
1366- then throw(("Your staked lands took part in arbitrage, cannot unstake until " + toString(arbReleaseTime)))
1367- else {
1368- let piecesKey = keyStakedPiecesByOwner(addr)
1369- let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
1370- let newPieces = if ((pieces > stakedPieces))
1371- then 0
1372- else (stakedPieces - pieces)
1373- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr], nil)
1374- $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))
1375- then StringEntry(landsKey, makeString_11C(removeByIndex(lands, value(idx)), "_"))
1376- else DeleteEntry(landsKey), IntegerEntry(piecesKey, newPieces)] ++ prologActions), wlgResult)
1377- }
1378- }
1379- }
1380- }
1381- }
1382-
1383-
1384-
1385-@Callable(i)
13861206 func unstakeLandCallback (landAssetId,addr) = if ((toString(i.caller) != acres2AddressStr))
13871207 then throw("Permission denied")
13881208 else {
13891209 let unstakeResult = unstakeLandInternal(addr, landAssetId)
1390- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr], nil)
1210+ let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr, false], nil)
13911211 $Tuple2([Burn(fromBase58String(landAssetId), 1), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))], $Tuple5(unstakeResult._1, unstakeResult._2, unstakeResult._3, unstakeResult._4, wlgResult))
13921212 }
13931213
13941214
13951215
13961216 @Callable(i)
13971217 func unstakeLandREADONLY (landAssetId,addr) = {
13981218 let unstakeResult = unstakeLandInternal(addr, landAssetId)
13991219 $Tuple2(nil, unstakeResult)
14001220 }
14011221
14021222
14031223
14041224 @Callable(i)
14051225 func unstakeLandsFinalizeCallback (addr) = if ((toString(i.caller) != acres2AddressStr))
14061226 then throw("Permission denied")
14071227 else $Tuple2([DeleteEntry(keyStakedLandsByOwner(addr)), DeleteEntry(keyStakedPiecesByOwner(addr))], 0)
14081228
14091229
14101230
14111231 @Callable(i)
14121232 func convertUnstakedLands () = if ((size(i.payments) != 1))
14131233 then throw("Exactly one payment required")
14141234 else {
14151235 let pmt = value(i.payments[0])
14161236 let assetId = value(pmt.assetId)
14171237 let address = toString(i.caller)
14181238 if ((pmt.amount != 1))
14191239 then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
14201240 else {
14211241 let asset = value(assetInfo(assetId))
14221242 if ((asset.issuer != this))
14231243 then throw("Unknown issuer of token")
14241244 else if (!(contains(asset.name, LANDPREFIX)))
14251245 then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
14261246 else {
14271247 let landAssetId = toBase58String(assetId)
14281248 let d = split(asset.description, "_")
14291249 let pieces = numPiecesBySize(d[recLandSize])
14301250 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
14311251 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
14321252 let acresAmount = ((pieces * MULT8) + ((((pieces * infraLevel) + artPieces) * MULT8) / 5))
14331253 let req = invoke(acresContract, "requestAcresCallback", [acresAmount], nil)
14341254 if ((req == req))
14351255 then {
14361256 let callb = invoke(addressFromStringValue(acres2AddressStr), "stakeAcresCallback", [address], [AttachedPayment(acresAssetId, acresAmount)])
14371257 if ((callb == callb))
14381258 then $Tuple2([Burn(fromBase58String(landAssetId), 1)], 0)
14391259 else throw("Strict value is not equal to itself.")
14401260 }
14411261 else throw("Strict value is not equal to itself.")
14421262 }
14431263 }
14441264 }
14451265
14461266
14471267
14481268 @Callable(i)
14491269 func unstakeDuckCallback (duckAssetId,addr) = if ((toString(i.caller) != acres2AddressStr))
14501270 then throw("Permission denied")
14511271 else {
14521272 let unstakeResult = unstakeDuckInternal(addr, duckAssetId)
14531273 $Tuple2([ScriptTransfer(addressFromStringValue(addr), 1, fromBase58String(duckAssetId)), DeleteEntry(keyStakedTimeByAssetId(duckAssetId)), DeleteEntry(keyDuckIdToOwner(duckAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, duckAssetId, addr)), DeleteEntry(keyStakedDuckByOwner(addr))], unstakeResult)
14541274 }
14551275
14561276
14571277
14581278 @Callable(i)
14591279 func unstakeDuckREADONLY (duckAssetId,addr) = {
14601280 let unstakeResult = unstakeDuckInternal(addr, duckAssetId)
14611281 $Tuple2(nil, unstakeResult)
14621282 }
14631283
14641284
14651285
14661286 @Callable(i)
14671287 func claimRes (amount,landAssetIdStr) = {
14681288 let prologActions = prolog(i)
14691289 if ((size(i.payments) != 0))
14701290 then throw("No payments required")
14711291 else {
14721292 let addr = toString(i.originCaller)
14731293 let result = claimResInternal(addr, amount, claimModeDuck, landAssetIdStr)
14741294 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
14751295 $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])
14761296 }
14771297 }
14781298
14791299
14801300
14811301 @Callable(i)
14821302 func claimResToWH (amount,landAssetIdStr) = {
14831303 let prologActions = prolog(i)
14841304 if ((size(i.payments) != 0))
14851305 then throw("No payments required")
14861306 else {
14871307 let addr = toString(i.originCaller)
14881308 let result = claimResInternal(addr, amount, claimModeWh, landAssetIdStr)
14891309 $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])
14901310 }
14911311 }
14921312
14931313
14941314
14951315 @Callable(i)
14961316 func updateBackpack (duckAssetId,newPack) = if ((i.caller != economyContract))
14971317 then throw("permission denied")
14981318 else $Tuple2([StringEntry(keyBackpackByDuck(duckAssetId), newPack)], newPack)
14991319
15001320
15011321
15021322 @Callable(i)
15031323 func commitForRandom () = {
15041324 let prologActions = prolog(i)
15051325 let finishBlock = (height + randomDelay)
15061326 let addr = toString(i.caller)
15071327 $Tuple2(([IntegerEntry(keyCommit(addr), finishBlock)] ++ prologActions), finishBlock)
15081328 }
15091329
15101330
15111331
15121332 @Callable(i)
15131333 func revealRandom (maxValue) = {
15141334 let prologActions = prolog(i)
15151335 let addr = toString(i.caller)
15161336 let finishKey = keyCommit(addr)
15171337 let finishBlock = valueOrErrorMessage(getInteger(finishKey), "You have to commitForRandom() first!")
15181338 if ((finishBlock > height))
15191339 then throw(("Random number is not ready yet, wait until height = " + toString(finishBlock)))
15201340 else {
15211341 let entropy = value(value(blockInfoByHeight(finishBlock)).vrf)
15221342 let salt = toBytes(valueOrElse(getString(keyLastWeekTxIdByUser(addr)), ""))
15231343 let rand = getRandomNumber(maxValue, salt, entropy)
15241344 $Tuple2(([DeleteEntry(finishKey)] ++ prologActions), rand)
15251345 }
15261346 }
15271347
15281348
15291349
15301350 @Callable(i)
15311351 func activateArtifact (artName,landAssetIdOpt) = {
15321352 let prologActions = prolog(i)
15331353 if ((size(i.payments) != 0))
15341354 then throw("No payments required")
15351355 else {
15361356 let addr = toString(i.caller)
15371357 let result = match artName {
15381358 case _ =>
15391359 if (("PRESALE" == $match0))
15401360 then activatePresaleArt(addr, landAssetIdOpt)
15411361 else if (("ONBOARD" == $match0))
15421362 then activateOnboardArt(addr)
15431363 else throw("Unknown artifact")
15441364 }
15451365 (result ++ prologActions)
15461366 }
15471367 }
15481368
15491369
15501370
15511371 @Callable(i)
15521372 func saveWarehouse (whStr,landAssetId) = if ((i.caller != economyContract))
15531373 then throw("Access denied")
15541374 else {
15551375 let whKey = keyWarehouseByLand(landAssetId)
15561376 let wh = split_4C(whStr, ":")
15571377 if ((size(wh) != 5))
15581378 then throw("warehouse string should contain 4 ':' separators")
15591379 else {
15601380 let loftL = split(wh[whIdxLOFT], "_")[volLocked]
15611381 let loftO = getWarehouseOccupiedVol(wh)
15621382 let loftT = getWarehouseTotalVolume(wh[whIdxLevels])
15631383 let loftF = ((loftT - parseIntValue(loftL)) - loftO)
15641384 if ((0 > loftF))
15651385 then throw("Operation leads to negative free warehouse space")
15661386 else {
15671387 let newWhStr = makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], wh[whIdxProd], makeString([loftL, toString(loftO), toString(loftF), toString(loftT)], "_")], ":")
15681388 $Tuple2([StringEntry(whKey, newWhStr)], newWhStr)
15691389 }
15701390 }
15711391 }
15721392
15731393
15741394
15751395 @Callable(i)
15761396 func setCustomName (assetId,customName,type) = {
15771397 let prologActions = prolog(i)
15781398 if ((size(i.payments) != 1))
15791399 then throw("Exactly one payment required")
15801400 else {
15811401 let pmt = value(i.payments[0])
15821402 if ((pmt.assetId != usdtAssetId))
15831403 then throw("Allowed USDT payment only!")
15841404 else if ((pmt.amount != RENAMINGCOST))
15851405 then throw(("Payment should be " + toString(RENAMINGCOST)))
15861406 else if (contains(customName, "__"))
15871407 then throw(("Name should not contain '__': " + customName))
15881408 else if ((size(customName) > MAXNAMELEN))
15891409 then throw(("Name too long, maxLength=" + toString(MAXNAMELEN)))
15901410 else {
15911411 let addr = toString(i.originCaller)
15921412 let actions = match type {
15931413 case _ =>
15941414 if (("ACCOUNT" == $match0))
15951415 then {
15961416 let reverseKey = keyCustomNameToAddress(customName)
15971417 let nameOwner = getString(reverseKey)
15981418 if (isDefined(nameOwner))
15991419 then throw(("Name already registered: " + customName))
16001420 else {
16011421 let addrToNameKey = keyAddressToCustomName(addr)
16021422 let oldName = getString(addrToNameKey)
16031423 let freeOld = if (isDefined(oldName))
16041424 then [DeleteEntry(keyCustomNameToAddress(value(oldName)))]
16051425 else nil
16061426 (((freeOld :+ StringEntry(addrToNameKey, customName)) :+ StringEntry(reverseKey, addr)) ++ updateAccStatsInternal(addr, xpCustomName)._1)
16071427 }
16081428 }
16091429 else if (("LAND" == $match0))
16101430 then {
16111431 let asset = value(assetInfo(fromBase58String(assetId)))
16121432 let timeKey = keyStakedTimeByAssetId(assetId)
16131433 if (!(isDefined(getInteger(timeKey))))
16141434 then throw((asset.name + " is not staked"))
16151435 else {
16161436 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
16171437 if ((owner != addr))
16181438 then throw((LANDPREFIX + " is not yours"))
16191439 else {
16201440 let reverseKey = keyLandCustomNameToAssetId(customName)
16211441 let nameOwner = getString(reverseKey)
16221442 if (isDefined(nameOwner))
16231443 then throw(("Name already registered: " + customName))
16241444 else {
16251445 let assetToNameKey = keyLandAssetIdToCustomName(assetId)
16261446 let oldName = getString(assetToNameKey)
16271447 let freeOld = if (isDefined(oldName))
16281448 then [DeleteEntry(keyLandCustomNameToAssetId(value(oldName)))]
16291449 else nil
16301450 (((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId)) ++ updateAccStatsInternal(addr, xpCustomName)._1)
16311451 }
16321452 }
16331453 }
16341454 }
16351455 else if (("DUCK" == $match0))
16361456 then {
16371457 let asset = value(assetInfo(fromBase58String(assetId)))
16381458 let timeKey = keyStakedTimeByAssetId(assetId)
16391459 if (if (!(isDefined(getInteger(timeKey))))
16401460 then true
16411461 else !(isDefined(getString(keyStakedDuckByOwner(addr)))))
16421462 then throw((asset.name + " is not staked"))
16431463 else {
16441464 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
16451465 if ((owner != addr))
16461466 then throw((DUCKPREFIX + " is not yours"))
16471467 else {
16481468 let reverseKey = keyDuckCustomNameToAssetId(customName)
16491469 let nameOwner = getString(reverseKey)
16501470 if (isDefined(nameOwner))
16511471 then throw(("Name already registered: " + customName))
16521472 else {
16531473 let assetToNameKey = keyDuckAssetIdToCustomName(assetId)
16541474 let oldName = getString(assetToNameKey)
16551475 let freeOld = if (isDefined(oldName))
16561476 then [DeleteEntry(keyDuckCustomNameToAssetId(value(oldName)))]
16571477 else nil
16581478 (((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId)) ++ updateDuckStatsInternal(assetId, xpCustomName)._1)
16591479 }
16601480 }
16611481 }
16621482 }
16631483 else throw("Unknown entity type")
16641484 }
16651485 $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ prologActions), 0)
16661486 }
16671487 }
16681488 }
16691489
16701490
16711491
16721492 @Callable(i)
16731493 func setReferrals (oldPlayer,newPlayer) = if ((i.callerPublicKey != pub))
16741494 then throw("Permission denied")
16751495 else {
16761496 let prologActions = prolog(i)
16771497 if ((size(i.payments) != 0))
16781498 then throw("No payments required")
16791499 else if (!(isDefined(addressFromString(oldPlayer))))
16801500 then throw(("Invalid address: " + oldPlayer))
16811501 else {
16821502 let newbieAddr = addressFromString(newPlayer)
16831503 if (!(isDefined(newbieAddr)))
16841504 then throw(("Invalid address: " + newPlayer))
16851505 else {
16861506 let oldLastTx = getString(keyLastWeekTxIdByUser(oldPlayer))
16871507 if (!(isDefined(oldLastTx)))
16881508 then throw("oldPlayer didn't do any tx in game")
16891509 else if ((0 >= wavesBalance(value(newbieAddr)).available))
16901510 then throw("newPlayer has no WAVES")
16911511 else {
16921512 let oldsKey = keyOldies()
16931513 let olds = getString(oldsKey)
16941514 let oldies = if (isDefined(olds))
16951515 then split_4C(value(olds), "_")
16961516 else nil
16971517 if (containsElement(oldies, newPlayer))
16981518 then throw((newPlayer + " is not newbie (already has referrals)"))
16991519 else {
17001520 let refByKey = keyAddressRefBy(newPlayer)
17011521 let refBy = getString(refByKey)
17021522 if (if (isDefined(refBy))
17031523 then isDefined(addressFromString(value(refBy)))
17041524 else false)
17051525 then throw(((newPlayer + " already has refBy: ") + value(refBy)))
17061526 else {
17071527 let refsKey = keyAddressReferrals(oldPlayer)
17081528 let refs = getString(refsKey)
17091529 let refsArray = if (isDefined(refs))
17101530 then split_4C(value(refs), "_")
17111531 else nil
17121532 if (containsElement(refsArray, newPlayer))
17131533 then throw((((oldPlayer + " already contains ") + newPlayer) + " within referrals"))
17141534 else {
17151535 let newRefs = makeString_2C((refsArray :+ newPlayer), "_")
17161536 let newOlds = if (containsElement(oldies, oldPlayer))
17171537 then value(olds)
17181538 else makeString_2C((oldies :+ oldPlayer), "_")
17191539 $Tuple2(([StringEntry(refByKey, oldPlayer), StringEntry(refsKey, newRefs), StringEntry(oldsKey, newOlds)] ++ prologActions), 0)
17201540 }
17211541 }
17221542 }
17231543 }
17241544 }
17251545 }
17261546 }
17271547
17281548
17291549
17301550 @Callable(i)
17311551 func distributePoints (strength,accuracy,intellect,endurance,dexterity) = {
17321552 let prologActions = prolog(i)
17331553 if ((size(i.payments) != 0))
17341554 then throw("No payments required")
17351555 else {
17361556 let addr = toString(i.originCaller)
17371557 let virtWlgData = asAnyList(invoke(wlgContract, "checkWlgXpREADONLY", [addr], nil))
17381558 let virtWlgPoints = asInt(virtWlgData[1])
1739- let $t0100244100634 = if ((0 >= virtWlgPoints))
1559+ let $t0100496100886 = if ((0 >= virtWlgPoints))
17401560 then $Tuple2(0, nil)
17411561 else {
17421562 let deltaXP = asInt(invoke(wlgContract, "takeWlgXp", [addr], nil))
17431563 if ((deltaXP == deltaXP))
17441564 then $Tuple2(virtWlgPoints, [IntegerEntry(keyUserLevel(addr), asInt(virtWlgData[0])), IntegerEntry(keyUserXP(addr), asInt(virtWlgData[2]))])
17451565 else throw("Strict value is not equal to itself.")
17461566 }
1747- let wlgPoints = $t0100244100634._1
1748- let wlgActions = $t0100244100634._2
1567+ let wlgPoints = $t0100496100886._1
1568+ let wlgActions = $t0100496100886._2
17491569 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
17501570 let freeKeyAcc = keyUserFreePoints(addr)
17511571 let freePointsAcc = (valueOrElse(getInteger(freeKeyAcc), 0) + wlgPoints)
17521572 let freeKeyDuck = keyDuckFreePoints(duckAssetId)
17531573 let freePointsDuck = valueOrElse(getInteger(freeKeyDuck), 0)
17541574 let sumFree = (freePointsAcc + freePointsDuck)
17551575 let sumToDistribute = ((((strength + accuracy) + intellect) + endurance) + dexterity)
17561576 if ((sumToDistribute > sumFree))
17571577 then throw((("There are only " + toString(sumFree)) + " free points to distribute"))
17581578 else {
17591579 let charsKey = keyDuckChars(duckAssetId)
17601580 let chars = split(valueOrElse(getString(charsKey), "0_0_0_0_0"), "_")
17611581 let newAcc = (freePointsAcc - sumToDistribute)
17621582 $Tuple2((([IntegerEntry(freeKeyAcc, if ((0 > newAcc))
17631583 then 0
17641584 else newAcc), IntegerEntry(freeKeyDuck, if ((0 > newAcc))
17651585 then (freePointsDuck + newAcc)
17661586 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)
17671587 }
17681588 }
17691589 }
17701590
17711591
17721592
17731593 @Callable(i)
17741594 func splitByGlobalWeightsREADONLY (amount) = $Tuple2(nil, getNeededMaterials(amount))
17751595
17761596
17771597
17781598 @Callable(i)
17791599 func splitByGlobalAndLocalWeightsREADONLY (matAmount,resAmount,terrains) = {
17801600 let terrainCounts = countTerrains(terrains)
17811601 $Tuple2(nil, $Tuple2(getNeededMaterials(matAmount), distributeByWeights(resAmount, terrainCounts)))
17821602 }
17831603
17841604
17851605
17861606 @Callable(i)
17871607 func getBackpackREADONLY (duckAssetId) = $Tuple2(nil, makeString(getBackpack(keyBackpackByDuck(duckAssetId)), ":"))
17881608
17891609
17901610
17911611 @Callable(i)
17921612 func getWarehouseREADONLY (landAssetId) = {
17931613 let asset = value(assetInfo(fromBase58String(landAssetId)))
17941614 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
17951615 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
17961616 $Tuple2(nil, makeString_2C(getWarehouse(keyWarehouseByLand(landAssetId), landIndex, infraLevel), ":"))
17971617 }
17981618
17991619
18001620
18011621 @Callable(i)
18021622 func saveLastTx () = if (!(containsElement([wlgContract, economyContract, tournamentContract, acresContract], i.caller)))
18031623 then throw("Access denied")
18041624 else $Tuple2(prolog(i), 42)
18051625
18061626
18071627
18081628 @Callable(i)
18091629 func updateDuckStats (duckAssetId,deltaXP) = if ((i.caller != economyContract))
18101630 then throw("Access denied")
18111631 else updateDuckStatsInternal(duckAssetId, deltaXP)
18121632
18131633
18141634
18151635 @Callable(i)
18161636 func updateAccStats (addr,deltaXP) = if (!(containsElement([wlgContract, economyContract, acresContract], i.caller)))
18171637 then throw("Access denied")
18181638 else updateAccStatsInternal(addr, deltaXP)
18191639
18201640
18211641
18221642 @Callable(i)
18231643 func initDuckTourAttempt (duckAssetId) = if ((i.caller != tournamentContract))
18241644 then throw("Access denied")
18251645 else {
18261646 let keyHealth = keyDuckHealth(duckAssetId)
18271647 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
18281648 let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
18291649 let curLocKey = keyDuckLocation(duckAssetId)
18301650 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
18311651 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
18321652 let tourLocation = (toString(lastId) + "_T_0")
18331653 $Tuple2([IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, tourLocation)], tourLocation)
18341654 }
18351655
18361656
18371657
18381658 @Callable(i)
18391659 func breakAttempt () = {
18401660 let prologActions = prolog(i)
18411661 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
18421662 let curLocKey = keyDuckLocation(duckAssetId)
18431663 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
18441664 if ((split(curLocation, "_")[locIdxType] != "T"))
18451665 then throw("Your duck is not in the tournament")
18461666 else {
18471667 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
18481668 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
18491669 $Tuple2(((prologActions :+ IntegerEntry(keyDuckHealth(duckAssetId), savedHealth)) :+ StringEntry(curLocKey, savedLocation)), curLocation)
18501670 }
18511671 }
18521672
18531673
18541674
18551675 @Callable(i)
18561676 func breakAttemptCallback () = if ((i.caller != tournamentContract))
18571677 then throw("Access denied")
18581678 else {
18591679 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.originCaller))), "You don't have a duck staked")
18601680 $Tuple2([IntegerEntry(keyDuckHealth(duckAssetId), getIntegerValue(keySavedHealth(duckAssetId))), StringEntry(keyDuckLocation(duckAssetId), getStringValue(keySavedLocation(duckAssetId)))], "breakAttemptCallback")
18611681 }
18621682
18631683
18641684
18651685 @Callable(i)
18661686 func exitTournamentInternal (duckAssetId) = if ((i.caller != this))
18671687 then throw("Access denied")
18681688 else {
18691689 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
18701690 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
18711691 $Tuple2([IntegerEntry(keyDuckHealth(duckAssetId), savedHealth), StringEntry(keyDuckLocation(duckAssetId), savedLocation)], false)
18721692 }
18731693
18741694
18751695
18761696 @Callable(i)
18771697 func processDelivery (duckAssetId) = if ((i.caller != this))
18781698 then throw("Access denied")
18791699 else {
18801700 let addr = toString(i.originCaller)
18811701 let fundTotal = valueOrElse(getInteger(economyContract, deliveryFundKey), 0)
18821702 if ((MIN_USDT_FEE_DELIVERY > fundTotal))
18831703 then throw(("Delivery is not available, fund=" + fixedPoint(fundTotal, 6)))
18841704 else {
18851705 let now = lastBlock.timestamp
18861706 let countKey = keyUserDeliveryCount(addr)
18871707 let lastDay = valueOrElse(getInteger(keyUserLastDeliveryDay(addr)), 0)
18881708 let today = (now / DAYMILLIS)
18891709 let count = if ((lastDay == today))
18901710 then valueOrElse(getInteger(countKey), 0)
18911711 else 0
18921712 let acres = valueOrElse(getInteger(acresContract, keyAcresStakedAmountByUser(addr)), 0)
18931713 let allowedDeliveries = (ALLOWED_FREE_DELIVERIES + (acres / ACRES_FOR_DELIVERY_ATTEMPT))
18941714 if ((count >= allowedDeliveries))
18951715 then throw((("You already used " + toString(allowedDeliveries)) + " delivery attempts for today"))
18961716 else {
18971717 let globalCountKey = keyDuckDeliveryCount(duckAssetId)
18981718 let reward = invoke(economyContract, "sendDeliveryReward", [addr], nil)
18991719 $Tuple2([IntegerEntry(countKey, (count + 1)), IntegerEntry(keyUserLastDeliveryDay(addr), today), IntegerEntry(globalCountKey, (valueOrElse(getInteger(globalCountKey), 0) + 1))], reward)
19001720 }
19011721 }
19021722 }
19031723
19041724

github/deemru/w8io/026f985 
191.98 ms