tx · HgfTatQtDLFsSdWqvXGPqP5E69XUJ383yz5mdLuxxnAx

3N4nTJ5sSp5X5ChS2bBBmwNMn1eeRzT1FoP:  -0.03600000 Waves

2023.05.04 14:18 [2562940] smart account 3N4nTJ5sSp5X5ChS2bBBmwNMn1eeRzT1FoP > SELF 0.00000000 Waves

{ "type": 13, "id": "HgfTatQtDLFsSdWqvXGPqP5E69XUJ383yz5mdLuxxnAx", "fee": 3600000, "feeAssetId": null, "timestamp": 1683199139086, "version": 2, "chainId": 84, "sender": "3N4nTJ5sSp5X5ChS2bBBmwNMn1eeRzT1FoP", "senderPublicKey": "EsqRXDXnACFAdXz6EPhF1SbKyeV7MVuoyDqmXsMz7ySv", "proofs": [ "5Qok4T3hHQCmiw11mZhvSoF43x6odfMBdRCkpogz1pXY4xmpEqf7BbrGBp1j4AehpLLusz83TDNNqsqNaAwpySUx" ], "script": "base64:BgKlKggCEgUKAwEEARIHCgUBBAEIARIDCgEIEgMKAQgSABIECgIBBBIECgIBBBIDCgEBEgASBAoCCAESABIECgIIARIECgIIARIECgIBARIDCgEBEgUKAwEBARIFCgMBCAESBAoCAQgSBAoCAQgSBAoCCAgSABIDCgEIEgUKAwEBARIECgIIARIECgIBARIECgIICBILCgkIAQECAQIIBAQSBgoECAgBCBIAIgZzY2FsZTgiDHNjYWxlOEJpZ0ludCIHc2NhbGUxOCIKemVyb0JpZ0ludCIEYmlnMCIEYmlnMSIEYmlnMiIEYmlnMyIEYmlnNCILd2F2ZXNTdHJpbmciCmFtcEluaXRpYWwiBUFtdWx0IgNTRVAiClBvb2xQdXREaXMiDlBvb2xNYXRjaGVyRGlzIgxQb29sU2h1dGRvd24iDmlkeFBvb2xBZGRyZXNzIglpZHhQb29sU3QiCWlkeExQQXNJZCIJaWR4QW1Bc0lkIglpZHhQckFzSWQiC2lkeEFtdEFzRGNtIg1pZHhQcmljZUFzRGNtIg9pZHhGYWN0U3Rha0NudHIiEmlkeEZhY3RvcnlSZXN0Q250ciIQaWR4RmFjdFNsaXBwQ250ciIKZmVlRGVmYXVsdCICdDEiB29yaWdWYWwiDW9yaWdTY2FsZU11bHQiCHQxQmlnSW50IgJmMSIDdmFsIg9yZXN1bHRTY2FsZU11bHQiDGZyb21YMThSb3VuZCIFcm91bmQiA2FicyIJYWJzQmlnSW50IgJmYyIDbXBrIgRwbXBrIgJwbCICcGgiAWgiAXQiA3BhdSICdWEiBHR4SWQiA2dhdSICYWEiAnBhIgNhbXAiDWtleUFtcEhpc3RvcnkiDGhlaWdodEJsb2NrcyIUa2V5Q2hhbmdlQW1wTGFzdENhbGwiBmtleUZlZSIDZmVlIgZrZXlETHAiFWtleURMcFJlZnJlc2hlZEhlaWdodCISa2V5RExwUmVmcmVzaERlbGF5IhZkTHBSZWZyZXNoRGVsYXlEZWZhdWx0Ig9kTHBSZWZyZXNoRGVsYXkiBGZjZmciBG10cGsiAnBjIgZpQW10QXMiBWlQckFzIgNtYmEiBWJBU3RyIgNhcHMiHGtleUFsbG93ZWRMcFN0YWJsZVNjcmlwdEhhc2giFmtleUZlZUNvbGxlY3RvckFkZHJlc3MiFmtleVNraXBPcmRlclZhbGlkYXRpb24iC3Bvb2xBZGRyZXNzIg90aHJvd09yZGVyRXJyb3IiCm9yZGVyVmFsaWQiDm9yZGVyVmFsaWRJbmZvIgtzZW5kZXJWYWxpZCIMbWF0Y2hlclZhbGlkIgRzdHJmIgRhZGRyIgNrZXkiBGludGYiCHRocm93RXJyIgNtc2ciBmZtdEVyciIDZmNhIgVpbkZlZSIBQCIGb3V0RmVlIgFBIgNpZ3MiAm1wIhNmZWVDb2xsZWN0b3JBZGRyZXNzIgNncGMiBWFtdEFzIgdwcmljZUFzIghpUHJpY2VBcyIMcGFyc2VBc3NldElkIgVpbnB1dCIPYXNzZXRJZFRvU3RyaW5nIg9wYXJzZVBvb2xDb25maWciCnBvb2xDb25maWciEHBvb2xDb25maWdQYXJzZWQiCyR0MDgwODc4MjczIg1jZmdQb29sU3RhdHVzIgxjZmdMcEFzc2V0SWQiEGNmZ0Ftb3VudEFzc2V0SWQiD2NmZ1ByaWNlQXNzZXRJZCIWY2ZnQW1vdW50QXNzZXREZWNpbWFscyIVY2ZnUHJpY2VBc3NldERlY2ltYWxzIgNnZmMiDWZhY3RvcnlDb25maWciD3N0YWtpbmdDb250cmFjdCIMcmVzdENvbnRyYWN0IhFkYXRhUHV0QWN0aW9uSW5mbyINaW5BbXRBc3NldEFtdCIPaW5QcmljZUFzc2V0QW10IghvdXRMcEFtdCIFcHJpY2UiCnNsaXBCeVVzZXIiDHNsaXBwYWdlUmVhbCIIdHhIZWlnaHQiC3R4VGltZXN0YW1wIgxzbGlwYWdlQW1BbXQiDHNsaXBhZ2VQckFtdCIRZGF0YUdldEFjdGlvbkluZm8iDm91dEFtdEFzc2V0QW10IhBvdXRQcmljZUFzc2V0QW10IgdpbkxwQW10Ig1nZXRBY2NCYWxhbmNlIgdhc3NldElkIgRjcGJpIghwckFtdFgxOCIIYW1BbXRYMTgiBWNwYmlyIgNwY3AiCmFtQXNzZXREY20iCnByQXNzZXREY20iBWFtQW10IgVwckFtdCILYW10QXNBbXRYMTgiCnByQXNBbXRYMTgiCmNhbGNQcmljZXMiBWxwQW10IghhbXRBc0RjbSIHcHJBc0RjbSIIcHJpY2VYMTgiCGxwQW10WDE4Ig1scFBySW5BbUFzWDE4Ig1scFBySW5QckFzWDE4Igd0YWtlRmVlIgZhbW91bnQiCWZlZUFtb3VudCIEZ2V0RCICeHAiA3hwMCIDeHAxIgFzIgFhIgNhbm4iAXAiC3hwMF94cDFfbl9uIgVhbm5fcyIFYW5uXzEiCWNhbGNETmV4dCIBZCICZGQiA2RkZCICZHAiBGNhbGMiA2FjYyIBaSIFZE5leHQiCGREaWZmUmF3IgVkRGlmZiIDYXJyIg0kdDAxMjc3ODEyODI2IgIkbCICJHMiBSRhY2MwIgUkZjBfMSICJGEiAiRpIgUkZjBfMiIFZm91bmQiA2VnbyIGdHhJZDU4IgpwbXRBc3NldElkIghwbXRMcEFtdCILdXNlckFkZHJlc3MiBGxwSWQiBGFtSWQiBHBySWQiBWFtRGNtIgVwckRjbSIDc3RzIgdscEVtaXNzIglhbUJhbGFuY2UiDGFtQmFsYW5jZVgxOCIJcHJCYWxhbmNlIgxwckJhbGFuY2VYMTgiC2N1clByaWNlWDE4IghjdXJQcmljZSILcG10THBBbXRYMTgiCmxwRW1pc3NYMTgiC291dEFtQW10WDE4IgtvdXRQckFtdFgxOCIIb3V0QW1BbXQiCG91dFByQW10IgVzdGF0ZSIDZXBvIghzbGlwcGFnZSIHaW5BbUFtdCIGaW5BbUlkIgdpblByQW10IgZpblBySWQiBmlzRXZhbCIGZW1pdExwIgppc09uZUFzc2V0IhB2YWxpZGF0ZVNsaXBwYWdlIgZwbXRBbXQiBXBtdElkIgdhbUlkU3RyIgdwcklkU3RyIgZhbXREY20iCHByaWNlRGNtIgRscEVtIg9pbkFtQXNzZXRBbXRYMTgiD2luUHJBc3NldEFtdFgxOCIMdXNlclByaWNlWDE4IgJEMCIBciICRDEiBmNoZWNrRCILc2xpcHBhZ2VYMTgiD3NsaXBwYWdlUmVhbFgxOCINbHBFbWlzc2lvblgxOCIKcHJWaWFBbVgxOCIKYW1WaWFQclgxOCIMZXhwZWN0ZWRBbXRzIhFleHBBbXRBc3NldEFtdFgxOCITZXhwUHJpY2VBc3NldEFtdFgxOCIJY2FsY0xwQW10Ig5jYWxjQW1Bc3NldFBtdCIOY2FsY1ByQXNzZXRQbXQiDHNsaXBwYWdlQ2FsYyIJZW1pdExwQW10IgZhbURpZmYiBnByRGlmZiINJHQwMjA1ODgyMDkzMyIKd3JpdGVBbUFtdCIKd3JpdGVQckFtdCILY29tbW9uU3RhdGUiBWdldFlEIgFEIgFuIgF4IgphUHJlY2lzaW9uIgFjIgFiIgNjdXIiDSR0MDIyMTI4MjIxNDgiAXkiBXlOZXh0IgV5RGlmZiINJHQwMjI0NTUyMjUwMiIHY2FsY0RMcCINYW1vdW50QmFsYW5jZSIMcHJpY2VCYWxhbmNlIgpscEVtaXNzaW9uIgp1cGRhdGVkRExwIg5jYWxjQ3VycmVudERMcCIQYW1vdW50QXNzZXREZWx0YSIPcHJpY2VBc3NldERlbHRhIhRscEFzc2V0RW1pc3Npb25EZWx0YSISYW1vdW50QXNzZXRCYWxhbmNlIhFwcmljZUFzc2V0QmFsYW5jZSIPbHBBc3NldEVtaXNzaW9uIgpjdXJyZW50RExwIhJyZWZyZXNoRExwSW50ZXJuYWwiF2Ftb3VudEFzc2V0QmFsYW5jZURlbHRhIhZwcmljZUFzc2V0QmFsYW5jZURlbHRhIgdhY3Rpb25zIhJ2YWxpZGF0ZVVwZGF0ZWRETHAiBm9sZERMcCIbdmFsaWRhdGVNYXRjaGVyT3JkZXJBbGxvd2VkIgVvcmRlciIRYW1vdW50QXNzZXRBbW91bnQiEHByaWNlQXNzZXRBbW91bnQiDSR0MDI0NzAwMjQ5MTIiA2RMcCINJHQwMjUyNTQyNTM1NCINdW51c2VkQWN0aW9ucyIGZExwTmV3Igxpc09yZGVyVmFsaWQiBGluZm8iAmNnIgNwbXQiAmNwIgZjYWxsZXIiB2FtQXNQbXQiB3ByQXNQbXQiDWNhbGNQdXRPbmVUa24iCXBtdEFtdFJhdyILd2l0aFRha2VGZWUiDWNoZWNoRW1pc3Npb24iDSR0MDI4MDEwMjg0NzIiDGFtQmFsYW5jZU9sZCIMcHJCYWxhbmNlT2xkIg0kdDAyODQ3ODI4NjU0IgthbUFtb3VudFJhdyILcHJBbW91bnRSYXciDSR0MDI4NjU4Mjg5MTIiCGFtQW1vdW50IghwckFtb3VudCIMYW1CYWxhbmNlTmV3IgxwckJhbGFuY2VOZXciCGxwQW1vdW50Ig5wb29sUHJvcG9ydGlvbiIPYW1vdW50QXNzZXRQYXJ0Ig5wcmljZUFzc2V0UGFydCIJbHBBbXRCb3RoIgVib251cyITZ2V0T25lVGtuVjJJbnRlcm5hbCIKb3V0QXNzZXRJZCIMbWluT3V0QW1vdW50IghwYXltZW50cyIMb3JpZ2luQ2FsbGVyIg10cmFuc2FjdGlvbklkIgphbURlY2ltYWxzIgpwckRlY2ltYWxzIgpwb29sU3RhdHVzIg0kdDAzMTAyNDMxMTM1Igh0b3RhbEdldCILdG90YWxBbW91bnQiDSR0MDMxMzI1MzE2MzIiBW91dEFtIgVvdXRQciIIY3VyUHJYMTgiBWN1clByIhFvdXRBc3NldElkT3JXYXZlcyIQc2VuZEZlZVRvTWF0Y2hlciIEYnVybiINJHQwMzI0MTczMjc2NyIQZmVlQW1vdW50Rm9yQ2FsYyIQb3V0SW5BbW91bnRBc3NldCINJHQwMzI3NzAzMjg3OCIRcmVmcmVzaERMcEFjdGlvbnMiEWlzVXBkYXRlZERMcFZhbGlkIgFtIgckbWF0Y2gwIgJwbSICcGQiCWlzTWFuYWdlciICcGsiAm1tIgRnZXRZIglpc1JldmVyc2UiE3Bvb2xBbW91bnRJbkJhbGFuY2UiDSR0MDM0MzI1MzQzNDUiDSR0MDM0Njc2MzQ3MjMiE3NraXBPcmRlclZhbGlkYXRpb24iDWNsZWFuQW1vdW50SW4iDWZlZVBvb2xBbW91bnQiDSR0MDM1MDc1MzU0OTkiCGFzc2V0T3V0IgJkeSILdG90YWxHZXRSYXciBW5ld1hwIgRuZXdEIgxhbW91bnRPdXRNaW4iCWFkZHJlc3NUbyILc3dhcENvbnRhY3QiBmNoZWNrcyIHYXNzZXRJbiINJHQwMzY5MzUzNzMyOSIIY2hlY2tNaW4iF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5IgJjbSIDaHBtIgNjcG0iBHNsaXAiCWF1dG9TdGFrZSIHZmFjdENmZyILc3Rha2luZ0NudHIiCHNsaXBDbnRyIgphbUFzc2V0UG10IgpwckFzc2V0UG10IgFlIglscEFzc2V0SWQiAmVsIgZsZWdhY3kiAnNhIgJzcCIIbHBUcm5zZnIiAnNzIg0kdDA0MTk0ODQyMDkwIgVjaGVjayIUbHBBc3NldEVtaXNzaW9uQWZ0ZXIiIGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkIg1pc1B1dERpc2FibGVkIg0kdDA0MzczMTQzODg5Igdlc3RpbUxQIg0kdDA0NDc3NDQ1MTIzIhRwYXltZW50SW5BbW91bnRBc3NldCINJHQwNDUxMjY0NTIzNCIHbWF4U2xwZyIGZXN0UHV0Ig0kdDA0NjI2NDQ2MzI5IglvdXRBbXRBbXQiDSR0MDQ3NTAyNDc1ODQiDWlzR2V0RGlzYWJsZWQiDSR0MDQ4MjAyNDgzNTciGGxhc3RSZWZyZXNoZWRCbG9ja0hlaWdodCIdY2hlY2tMYXN0UmVmcmVzaGVkQmxvY2tIZWlnaHQiDSR0MDQ4ODgxNDg5NDUiEGRMcFVwZGF0ZUFjdGlvbnMiDWxwQXNzZXRBbW91bnQiBWluZGV4IgRuZXdZIg0kdDA0OTk1NTUwMDEwIg0kdDA1MDM4NTUwNTAwIg5zdW1PZkdldEFzc2V0cyISbm9MZXNzVGhlbkFtdEFzc2V0IhRub0xlc3NUaGVuUHJpY2VBc3NldCIUYnVybkxQQXNzZXRPbkZhY3RvcnkiDSR0MDUxNjY2NTE3NDciDWNoZWNrUGF5bWVudHMiCmZhY3RvcnlDZmciB3N0YWtpbmciCnVuc3Rha2VJbnYiAXYiBWJ1cm5BIg0kdDA1Mjc3NDUyODU1Ig11bnN0YWtlQW1vdW50IhVub0xlc3NUaGVuQW1vdW50QXNzZXQiA3JlcyIMY2hlY2tBbW91bnRzIg0kdDA1NDEwNjU0MTg3IhdscEFzc2V0UmVjaXBpZW50QWRkcmVzcyINJHQwNTUyMDk1NTM5NyIQcGF5bWVudEFtb3VudFJhdyIOcGF5bWVudEFzc2V0SWQiDSR0MDU1NTI1NTU2MjgiDSR0MDU1Nzc2NTU4ODAiCGFtdEFzU3RyIgdwckFzU3RyIgJwciIMcmVzU2NhbGVNdWx0Igd1c3JBZGRyIgdwbXRBc0lkIgNjZmciDSR0MDU4Mjg5NTg0ODgiBGxpc3QiBWRlbGF5IgVkZWx0YSIGdGFyZ2V0IgZjdXJBbXAiCW5ld0FtcFJhdyIGbmV3QW1wIghsYXN0Q2FsbCIEd2FpdCICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5IgptYXRjaGVyUHViIg0kdDA1OTQwMDU5NTE3IgduZXdIYXNoIgthbGxvd2VkSGFzaCILY3VycmVudEhhc2h0AAFhAIDC1y8AAWIJALYCAQCAwtcvAAFjCQC2AgEAgICQu7rWrfANAAFkCQC2AgEAAAABZQkAtgIBAAAAAWYJALYCAQABAAFnCQC2AgEAAgABaAkAtgIBAAMAAWkJALYCAQAEAAFqAgVXQVZFUwABawAyAAFsAgMxMDAAAW0CAl9fAAFuAAIAAW8AAwABcAAEAAFxAAEAAXIAAgABcwADAAF0AAQAAXUABQABdgAGAAF3AAcAAXgAAQABeQAGAAF6AAcAAUEJAGsDAAoFAWEAkE4BAUICAUMBRAkAvAIDCQC2AgEFAUMFAWMJALYCAQUBRAEBRQIBQwFECQC8AgMFAUMFAWMFAUQBAUYCAUcBSAkAoAMBCQC8AgMFAUcJALYCAQUBSAUBYwEBSQMBRwFIAUoJAKADAQkAvQIEBQFHCQC2AgEFAUgFAWMFAUoBAUsBAUcDCQC/AgIFAWQFAUcJAL4CAQUBRwUBRwEBTAEBRwMJAL8CAgUBZAUBRwkAvgIBBQFHBQFHAQFNAAITJXNfX2ZhY3RvcnlDb250cmFjdAEBTgACFCVzX19tYW5hZ2VyUHVibGljS2V5AQFPAAIbJXNfX3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AQFQAAIRJXMlc19fcHJpY2VfX2xhc3QBAVECAVIBUwkAuQkCCQDMCAICGCVzJXMlZCVkX19wcmljZV9faGlzdG9yeQkAzAgCCQCkAwEFAVIJAMwIAgkApAMBBQFTBQNuaWwFAW0BAVQCAVUBVgkArAICCQCsAgIJAKwCAgILJXMlcyVzX19QX18FAVUCAl9fBQFWAQFXAgFVAVYJAKwCAgkArAICCQCsAgICCyVzJXMlc19fR19fBQFVAgJfXwUBVgEBWAACDyVzX19hbW91bnRBc3NldAEBWQACDiVzX19wcmljZUFzc2V0AQFaAAIHJXNfX2FtcAECYWEBAmFiCQCsAgICCyVzJWRfX2FtcF9fCQCkAwEFAmFiAQJhYwACFSVzX19jaGFuZ2VBbXBMYXN0Q2FsbAACYWQCByVzX19mZWUAAmFlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAmFkBQFBAAJhZgkAuQkCCQDMCAICAiVzCQDMCAICA2RMcAUDbmlsBQFtAAJhZwkAuQkCCQDMCAICAiVzCQDMCAICEmRMcFJlZnJlc2hlZEhlaWdodAUDbmlsBQFtAAJhaAkAuQkCCQDMCAICAiVzCQDMCAICD3JlZnJlc2hETHBEZWxheQUDbmlsBQFtAAJhaQAeAAJhagkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQJhaAUCYWkBAmFrAAIRJXNfX2ZhY3RvcnlDb25maWcBAmFsAAIYJXMlc19fbWF0Y2hlcl9fcHVibGljS2V5AQJhbQICYW4CYW8JAKwCAgkArAICCQCsAgIJAKwCAgIIJWQlZCVzX18FAmFuAgJfXwUCYW8CCF9fY29uZmlnAQJhcAECYXEJAKwCAgIoJXMlcyVzX19tYXBwaW5nc19fYmFzZUFzc2V0MmludGVybmFsSWRfXwUCYXEBAmFyAAIMJXNfX3NodXRkb3duAQJhcwACHSVzX19hbGxvd2VkTHBTdGFibGVTY3JpcHRIYXNoAQJhdAACFyVzX19mZWVDb2xsZWN0b3JBZGRyZXNzAQJhdQECYXYJAKwCAgIbJXMlc19fc2tpcE9yZGVyVmFsaWRhdGlvbl9fBQJhdgECYXcEAmF4AmF5AmF6AmFBCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICJG9yZGVyIHZhbGlkYXRpb24gZmFpbGVkOiBvcmRlclZhbGlkPQkApQMBBQJheAICICgFAmF5AgEpAg0gc2VuZGVyVmFsaWQ9CQClAwEFAmF6Ag4gbWF0Y2hlclZhbGlkPQkApQMBBQJhQQECYUICAmFDAmFECQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYUMFAmFECQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFDCQDMCAICAS4JAMwIAgUCYUQJAMwIAgIMIG5vdCBkZWZpbmVkBQNuaWwCAAECYUUCAmFDAmFECQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUCYUMFAmFECQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFDCQDMCAICAS4JAMwIAgUCYUQJAMwIAgIMIG5vdCBkZWZpbmVkBQNuaWwCAAECYUYBAmFHCQACAQkAuQkCCQDMCAICD2xwX3N0YWJsZS5yaWRlOgkA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AmJRBAJiUwkBAUICBQJiTwUBYQQCYlQJAQJiQwIFAmJFBQJiUwQCYlUJAQJiQwIFAmJEBQJiUwkAzAgCBQJiUgkAzAgCBQJiVAkAzAgCBQJiVQUDbmlsAQJiVgICYlcCYWUEAmJYAwkAAAIFAmFlAAAAAAkAawMFAmJXBQJhZQUBYQkAlAoCCQBlAgUCYlcFAmJYBQJiWAECYlkBAmJaBAJjYQkAkQMCBQJiWgAABAJjYgkAkQMCBQJiWgABBAJjYwkAtwICBQJjYQUCY2IDCQAAAgUCY2MFAWUFAWUEAmNkCQENcGFyc2VJbnRWYWx1ZQEFAmFNBAJjZQkAaAIFAmNkAAIEAmNmCQC8AgMFAmNhBQJjYgUBZgQCY2cJALwCAwUCY2YFAWkFAWYEAmNoCQC8AgMJALYCAQUCY2UFAmNjBQFmBAJjaQkAtgIBCQBlAgUCY2UAAQoBAmNqAQJjawQCY2wJALwCAwUCY2sFAmNrBQFmBAJjbQkAvAIDBQJjbAUCY2sFAWYEAmNuCQC8AgMFAmNtBQFmBQJjZwkAvAIDCQC3AgIFAmNoCQC8AgMFAmNuBQFnBQFmBQJjawkAtwICCQC8AgMFAmNpBQJjawUBZgkAvAIDBQFoBQJjbgUBZgoBAmNvAgJjcAJjcQMIBQJjcAJfMgUCY3AEAmNrCAUCY3ACXzEEAmNyCQECY2oBBQJjawQCY3MJALgCAgUCY3IJAQV2YWx1ZQEFAmNrBAJjdAMJAL8CAgUBZQUCY3MJAL4CAQUCY3MFAmNzAwkAwAICBQFmBQJjdAkAlAoCBQJjcgYJAJQKAgUCY3IHBAJjdQkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkJAMwIAgAKCQDMCAIACwkAzAgCAAwJAMwIAgANCQDMCAIADgkAzAgCAA8JAMwIAgAQBQNuaWwEAmN2CgACY3cFAmN1CgACY3gJAJADAQUCY3cKAAJjeQkAlAoCBQJjYwcKAQJjegICY0ECY0IDCQBnAgUCY0IFAmN4BQJjQQkBAmNvAgUCY0EJAJEDAgUCY3cFAmNCCgECY0MCAmNBAmNCAwkAZwIFAmNCBQJjeAUCY0EJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxNwkBAmNDAgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgUCY3kAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEEAmNrCAUCY3YCXzEEAmNECAUCY3YCXzIDBQJjRAUCY2sJAAIBCQCsAgICGUQgY2FsY3VsYXRpb24gZXJyb3IsIEQgPSAJAKYDAQUCY2sBAmNFBAJjRgJjRwJjSAJjSQQCY0oFAmJjBAJjSwkA2AQBCQEFdmFsdWUBBQJiZAQCY0wJANgEAQkBBXZhbHVlAQUCYmUEAmNNBQJiZgQCY04FAmJnBAJjTwkApAMBBQJiYgQCY1AICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCY0oCC1dyb25nIExQIGlkCHF1YW50aXR5AwkBAiE9AgkA2AQBBQJjSgUCY0cJAAIBAg9Xcm9uZyBwbXQgYXNzZXQEAmNRCQECYkEBBQJjSwQCY1IJAQFCAgUCY1EFAmNNBAJjUwkBAmJBAQUCY0wEAmNUCQEBQgIFAmNTBQJjTgQCY1UJAQJiQwIFAmNUBQJjUgQCY1YJAQFGAgUCY1UFAWEEAmNXCQEBQgIFAmNIBQFhBAJjWAkBAUICBQJjUAUBYQQCY1kJALwCAwUCY1IFAmNXBQJjWAQCY1oJALwCAwUCY1QFAmNXBQJjWAQCZGEJAQFJAwUCY1kFAmNNBQVGTE9PUgQCZGIJAQFJAwUCY1oFAmNOBQVGTE9PUgQCZGMDCQAAAgUCY0YCAAUDbmlsCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmNJBQJkYQMJAAACBQJjSwIFV0FWRVMFBHVuaXQJANkEAQUCY0sJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCY0kFAmRiAwkAAAIFAmNMAgVXQVZFUwUEdW5pdAkA2QQBBQJjTAkAzAgCCQELU3RyaW5nRW50cnkCCQEBVwIJAKUIAQUCY0kFAmNGCQECYncGBQJkYQUCZGIFAmNIBQJjVgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVAABQJjVgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVECBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJjVgUDbmlsCQCcCgoFAmRhBQJkYgUCY0sFAmNMBQJjUQUCY1MFAmNQBQJjVQUCY08FAmRjAQJkZA0CY0YCZGUCZGYCZGcCZGgCZGkCY0kCZGoCZGsCZGwCZG0CZG4CZG8EAmNKBQJiYwQCZHAJANgEAQkBBXZhbHVlAQUCYmQEAmRxCQDYBAEJAQV2YWx1ZQEFAmJlBAJkcgUCYmYEAmRzBQJiZwQCY08JAKQDAQUCYmIEAmR0CAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmNKAghXciBscCBhcwhxdWFudGl0eQQCY1EDBQJkagkBAmJBAQUCZHADAwUCZGwJAAACBQJkbwUCZHAHCQBlAgkBAmJBAQUCZHAFAmRuAwUCZGwJAQJiQQEFAmRwCQBlAgkBAmJBAQUCZHAFAmRmBAJjUwMFAmRqCQECYkEBBQJkcQMDBQJkbAkAAAIFAmRvBQJkcQcJAGUCCQECYkEBBQJkcQUCZG4DBQJkbAkBAmJBAQUCZHEJAGUCCQECYkEBBQJkcQUCZGgEAmR1CQEBQgIFAmRmBQJkcgQCZHYJAQFCAgUCZGgFAmRzBAJkdwkBAmJDAgUCZHYFAmR1BAJjUgkBAUICBQJjUQUCZHIEAmNUCQEBQgIFAmNTBQJkcwQCZHgJAQJiWQEJAMwIAgUCY1IJAMwIAgUCY1QFA25pbAQCZHkDCQAAAgUCZHQAAAQCZHoJAQJiWQEJAMwIAgkAtwICBQJjUgUCZHUJAMwIAgkAtwICBQJjVAUCZHYFA25pbAQCZEEDCQC/AgIFAmR6BQJkeAYJAAIBAhxEMSBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIEQwAwkAAAIFAmRBBQJkQQQCY1UFAWQEAmRCBQFkBAJiUwUCZHoJAJcKBQkBAUYCBQJiUwUBYQkBAUYCBQJkdQUCZHIJAQFGAgUCZHYFAmRzCQECYkMCCQC3AgIFAmNUBQJkdgkAtwICBQJjUgUCZHUFAmRCCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAJjVQkBAmJDAgUCY1QFAmNSBAJkQwkAvAIDCQEBSwEJALgCAgUCY1UFAmR3BQFjBQJjVQQCZEIJAQFCAgUCZGUFAWEDAwMFAmRtCQECIT0CBQJjVQUBZAcJAL8CAgUCZEMFAmRCBwkAAgEJAKwCAgkArAICCQCsAgICD1ByaWNlIHNsaXBwYWdlIAkApgMBBQJkQwIDID4gCQCmAwEFAmRCBAJkRAkBAUICBQJkdAUBYQQCZEUJAL0CBAUCZHUJAQJiRgMFAmNUBQJjUgUHQ0VJTElORwUBYwUHQ0VJTElORwQCZEYJAL0CBAUCZHYFAWMJAQJiRgMFAmNUBQJjUgUFRkxPT1IFB0NFSUxJTkcEAmRHAwkAvwICBQJkRQUCZHYJAJQKAgUCZEYFAmR2CQCUCgIFAmR1BQJkRQQCZEgIBQJkRwJfMQQCZEkIBQJkRwJfMgQCZHoJAQJiWQEJAMwIAgkAtwICBQJjUgUCZEgJAMwIAgkAtwICBQJjVAUCZEkFA25pbAQCZEEDCQC/AgIFAmR6BQJkeAYJAAIBAhxEMSBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIEQwAwkAAAIFAmRBBQJkQQQCYlMJALwCAwUCZEQJALgCAgUCZHoFAmR4BQJkeAkAlwoFCQEBSQMFAmJTBQFhBQVGTE9PUgkBAUkDBQJkSAUCZHIFB0NFSUxJTkcJAQFJAwUCZEkFAmRzBQdDRUlMSU5HBQJjVQUCZEIJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EAmRKCAUCZHkCXzEEAmRLCAUCZHkCXzIEAmRMCAUCZHkCXzMEAmNWCQEBRgIIBQJkeQJfNAUBYQQCZE0JAQFGAggFAmR5Al81BQFhAwkAZwIAAAUCZEoJAAIBAgdMUCA8PSAwBAJkTgMJAQEhAQUCZGsAAAUCZEoEAmRPCQBlAgUCZGYFAmRLBAJkUAkAZQIFAmRoBQJkTAQCZFEDAwUCZGwJAAACBQJkbwUCZHAHCQCUCgIFAmRuAAADAwUCZGwJAAACBQJkbwUCZHEHCQCUCgIAAAUCZG4JAJQKAgUCZEsFAmRMBAJkUggFAmRRAl8xBAJkUwgFAmRRAl8yBAJkVAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVAABQJjVgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVECBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJjVgkAzAgCCQELU3RyaW5nRW50cnkCCQEBVAIFAmNJBQJjRgkBAmJsCgUCZFIFAmRTBQJkTgUCY1YFAmRlBQJkTQUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZE8FAmRQBQNuaWwJAJ8KDQUCZEoFAmROBQJjVgUCY1EFAmNTBQJkdAUCY0oFAmNPBQJkVAUCZE8FAmRQBQJkZwUCZGkBAmRVAwJiWgJjcQJkVgQCZFcFAWcEAmRYCQCRAwIFAmJaAwkAAAIFAmNxAAAAAQAABAJkWQkApwMBBQFsBAJjZAkAuQICCQCnAwEFAmFNBQJkWQQCY2MFAmRYBAJjZQkAuQICBQJjZAUCZFcEAmRaCQC6AgIJALkCAgkAuQICCQC6AgIJALkCAgUCZFYFAmRWCQC5AgIFAmRYBQJkVwUCZFYFAmRZCQC5AgIFAmNlBQJkVwQCZWEJALgCAgkAtwICBQJjYwkAugICCQC5AgIFAmRWBQJkWQUCY2UFAmRWCgECY28CAmNwAmViBAJlYwUCY3AEAmVkCAUCZWMCXzEEAmNECAUCZWMCXzIDCQECIT0CBQJjRAUEdW5pdAUCY3AEAmVlCQC6AgIJALcCAgkAuQICBQJlZAUCZWQFAmRaCQC3AgIJALkCAgUBZwUCZWQFAmVhBAJlZgkBAUwBCQC4AgIFAmVlCQEFdmFsdWUBBQJlZAMJAMACAgUBZgUCZWYJAJQKAgUCZWUFAmViCQCUCgIFAmVlBQR1bml0BAJjdQkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkJAMwIAgAKCQDMCAIACwkAzAgCAAwJAMwIAgANCQDMCAIADgUDbmlsBAJlZwoAAmN3BQJjdQoAAmN4CQCQAwEFAmN3CgACY3kJAJQKAgUCZFYFBHVuaXQKAQJjegICY0ECY0IDCQBnAgUCY0IFAmN4BQJjQQkBAmNvAgUCY0EJAJEDAgUCY3cFAmNCCgECY0MCAmNBAmNCAwkAZwIFAmNCBQJjeAUCY0EJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxNQkBAmNDAgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgUCY3kAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwQCZWQIBQJlZwJfMQQCY0QIBQJlZwJfMgMJAQIhPQIFAmNEBQR1bml0BQJlZAkAAgEJAKwCAgIZWSBjYWxjdWxhdGlvbiBlcnJvciwgWSA9IAkApgMBBQJlZAECZWgDAmVpAmVqAmVrBAJlbAkAvAIDCQECYlkBCQDMCAIJAQFFAgUCZWkJALYCAQUCYmYJAMwIAgkBAUUCBQJlagkAtgIBBQJiZwUDbmlsBQFjBQJlawMJAAACBQJlawUBZQUBZQUCZWwBAmVtAwJlbgJlbwJlcAQCZXEJALgCAgkAtgIBCQECYkEBCQECYVcBBQJiZAUCZW4EAmVyCQC4AgIJALYCAQkBAmJBAQkBAmFXAQUCYmUFAmVvBAJlcwkAuAICCQC2AgEICQEFdmFsdWUBCQDsBwEFAmJjCHF1YW50aXR5BQJlcAQCZXQJAQJlaAMFAmVxBQJlcgUCZXMFAmV0AQJldQMCZXYCZXcCZXAEAmVxCQBkAgkBAmJBAQkBAmFXAQUCYmQFAmV2BAJlcgkAZAIJAQJiQQEJAQJhVwEFAmJlBQJldwQCZXMJAGQCCAkBBXZhbHVlAQkA7AcBBQJiYwhxdWFudGl0eQUCZXAEAmVsCQECZWgDCQC2AgEFAmVxCQC2AgEFAmVyCQC2AgEFAmVzBAJleAkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYWcFBmhlaWdodAkAzAgCCQELU3RyaW5nRW50cnkCBQJhZgkApgMBBQJlbAUDbmlsCQCUCgIFAmV4BQJlbAECZXkCAmV6AmVsAwkAwAICBQJlbAUCZXoGCQECYUYBAiJ1cGRhdGVkIERMcCBsb3dlciB0aGFuIGN1cnJlbnQgRExwAQJlQQECZUIEAmVxCQECYkEBCQECYVcBBQJiZAQCZXIJAQJiQQEJAQJhVwEFAmJlBAJlQwgFAmVCBmFtb3VudAQCZUQJAG4ECAUCZUIGYW1vdW50CAUCZUIFcHJpY2UFAWEFBUZMT09SBAJlRQMJAAACCAUCZUIJb3JkZXJUeXBlBQNCdXkJAJQKAgUCZUMJAQEtAQUCZUQJAJQKAgkBAS0BBQJlQwUCZUQEAmV2CAUCZUUCXzEEAmV3CAUCZUUCXzIDAwMJAQJhTgAGCQAAAgUCYmIFAW8GCQAAAgUCYmIFAXAJAAIBAg1BZG1pbiBibG9ja2VkAwMJAQIhPQIICAUCZUIJYXNzZXRQYWlyC2Ftb3VudEFzc2V0BQJiZAYJAQIhPQIICAUCZUIJYXNzZXRQYWlyCnByaWNlQXNzZXQFAmJlCQACAQIJV3IgYXNzZXRzBAJlRgkApwMBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAmFmAgEwBAJlRwkBAmV1AwUCZXYFAmV3AAAEAmVICAUCZUcCXzEEAmVJCAUCZUcCXzIEAmVKCQDAAgIFAmVJBQJlRgQCZUsJALkJAgkAzAgCAgRkTHA9CQDMCAIJAKYDAQUCZUYJAMwIAgIIIGRMcE5ldz0JAMwIAgkApgMBBQJlSQkAzAgCAhQgYW1vdW50QXNzZXRCYWxhbmNlPQkAzAgCCQCkAwEFAmVxCQDMCAICEyBwcmljZUFzc2V0QmFsYW5jZT0JAMwIAgkApAMBBQJlcgkAzAgCAhkgYW1vdW50QXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZXYJAMwIAgIYIHByaWNlQXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZXcJAMwIAgIIIGhlaWdodD0JAMwIAgkApAMBBQZoZWlnaHQFA25pbAIACQCUCgIFAmVKBQJlSwECZUwBAmNxAwkBAiE9AgkAkAMBCAUCY3EIcGF5bWVudHMAAQkAAgECCjEgcG1udCBleHAEAmVNCQEFdmFsdWUBCQCRAwIIBQJjcQhwYXltZW50cwAABAJjRwkBBXZhbHVlAQgFAmVNB2Fzc2V0SWQEAmRuCAUCZU0GYW1vdW50BAJkeQkBAmNFBAkA2AQBCAUCY3ENdHJhbnNhY3Rpb25JZAkA2AQBBQJjRwUCZG4IBQJjcQZjYWxsZXIEAmRhCAUCZHkCXzEEAmRiCAUCZHkCXzIEAmNPCQENcGFyc2VJbnRWYWx1ZQEIBQJkeQJfOQQCZGMIBQJkeQNfMTADAwkBAmFOAAYJAAACBQJjTwUBcAkAAgEJAKwCAgIPQWRtaW4gYmxvY2tlZDogCQCkAwEFAmNPCQCXCgUFAmRhBQJkYgUCZG4FAmNHBQJkYwECZU4KAmVPAVYCZVACZVECZGUCZGsCZGwCZG0CZG4CZG8EAmR5CQECZGQNBQFWBQJkZQgJAQV2YWx1ZQEFAmVQBmFtb3VudAgJAQV2YWx1ZQEFAmVQB2Fzc2V0SWQICQEFdmFsdWUBBQJlUQZhbW91bnQICQEFdmFsdWUBBQJlUQdhc3NldElkBQJlTwkAAAIFAVYCAAUCZGsFAmRsBQJkbQUCZG4FAmRvBAJjTwkBDXBhcnNlSW50VmFsdWUBCAUCZHkCXzgDAwMJAQJhTgAGCQAAAgUCY08FAW4GCQAAAgUCY08FAXAJAAIBCQCsAgICCEJsb2NrZWQ6CQCkAwEFAmNPBQJkeQECZVIFAmVTAmNHAmNJAVYCZVQEAmNLCQDYBAEJAQV2YWx1ZQEFAmJkBAJjTAkA2AQBCQEFdmFsdWUBBQJiZQQCY0oFAmJjBAJkcgUCYmYEAmRzBQJiZwQCZXMJALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJjSgIQaW52YWxpZCBscCBhc3NldAhxdWFudGl0eQQCZVUDCQC/AgIFAmVzBQFlBgkAAgECImluaXRpYWwgZGVwb3NpdCByZXF1aXJlcyBhbGwgY29pbnMDCQAAAgUCZVUFAmVVBAJjUQkBAmJBAQUCY0sEAmNTCQECYkEBBQJjTAQCZVYDCQAAAgUBVgIACQCUCgIFAmNRBQJjUwMJAAACBQJjRwUCY0sDCQBmAgUCZVMFAmNRCQACAQIWaW52YWxpZCBwYXltZW50IGFtb3VudAkAlAoCCQBlAgUCY1EFAmVTBQJjUwMJAAACBQJjRwUCY0wDCQBmAgUCZVMFAmNTCQACAQIWaW52YWxpZCBwYXltZW50IGFtb3VudAkAlAoCBQJjUQkAZQIFAmNTBQJlUwkAAgECEHdyb25nIHBtdEFzc2V0SWQEAmVXCAUCZVYCXzEEAmVYCAUCZVYCXzIEAmVZAwkAAAIFAmNHBQJjSwkAlAoCBQJlUwAAAwkAAAIFAmNHBQJjTAkAlAoCAAAFAmVTCQACAQIPaW52YWxpZCBwYXltZW50BAJlWggFAmVZAl8xBAJmYQgFAmVZAl8yBAJmYgMFAmVUCQCVCgMICQECYlYCBQJlWgUCYUoCXzEICQECYlYCBQJmYQUCYUoCXzEICQECYlYCBQJlUwUCYUoCXzIJAJUKAwUCZVoFAmZhAAAEAmZjCAUCZmICXzEEAmZkCAUCZmICXzIEAmJYCAUCZmICXzMEAmZlCQBkAgUCZVcFAmZjBAJmZgkAZAIFAmVYBQJmZAQCZHgJAQJiWQEJAMwIAgkBAUICBQJlVwUCYmYJAMwIAgkBAUICBQJlWAUCYmcFA25pbAQCZHoJAQJiWQEJAMwIAgkBAUICBQJmZQUCYmYJAMwIAgkBAUICBQJmZgUCYmcFA25pbAQCZEEDCQC/AgIFAmR6BQJkeAYJAQV0aHJvdwADCQAAAgUCZEEFAmRBBAJmZwkAvQIEBQJlcwkAuAICBQJkegUCZHgFAmR4BQVGTE9PUgQCY1YJAQFGAgkBAmJDAgkBAUICBQJmZgUCZHMJAQFCAgUCZmUFAmRyBQFhBAJkVAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVAABQJjVgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVECBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJjVgkAzAgCCQELU3RyaW5nRW50cnkCCQEBVAIFAmNJBQFWCQECYmwKBQJlWgUCZmEJAKADAQUCZmcFAmNWAAAAAAUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAAAAAAFA25pbAQCZmgJAGsDBQJlWAUBYQUCZVcEAmZpCQBrAwUCZVMFAWEJAGQCBQJmaAUBYQQCZmoJAGUCBQJlUwUCZmkEAmZrCQC8AgMFAmVzCQC2AgEFAmZqCQC2AgEFAmVYBAJmbAkAoAMBCQC8AgMJALgCAgUCZmcFAmZrBQFiBQJmawkAlgoECQCgAwEFAmZnBQJkVAUCYlgFAmZsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJmbQYCZm4CZm8CZnACZU8CZnECZnIEAmNKCQDYBAEJAQV2YWx1ZQEFAmJjBAJjSwkA2AQBCQEFdmFsdWUBBQJiZAQCY0wJANgEAQkBBXZhbHVlAQUCYmUEAmZzBQJiZgQCZnQFAmJnBAJmdQUCYmIEAmNJAwkAAAIFAmVPBQJiawUCZnEFAmVPBAJlTQkBBXZhbHVlAQkAkQMCBQJmcAAABAJjRwkBBXZhbHVlAQgFAmVNB2Fzc2V0SWQEAmRuCAUCZU0GYW1vdW50BAJldAkBAmVtAwUBZQUBZQUBZQMJAAACBQJldAUCZXQEAmNGCQDYBAEFAmZyAwkBAiE9AgUCY0oJANgEAQUCY0cJAAIBAghXcm9uZyBMUAQCY1EJAQJiQQEFAmNLBAJjUwkBAmJBAQUCY0wEAmZ2CgACYUsJAPwHBAUEdGhpcwITZ2V0T25lVGtuVjJSRUFET05MWQkAzAgCBQJmbgkAzAgCBQJkbgUDbmlsBQNuaWwDCQABAgUCYUsCCihJbnQsIEludCkFAmFLCQACAQkArAICCQADAQUCYUsCHyBjb3VsZG4ndCBiZSBjYXN0IHRvIChJbnQsIEludCkDCQAAAgUCZnYFAmZ2BAJiWAgFAmZ2Al8yBAJmdwgFAmZ2Al8xBAJmeAMDCQBmAgUCZm8AAAkAZgIFAmZvBQJmdwcJAQJhRgEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZm8FA25pbAIABQJmdwQCZnkDCQAAAgUCZm4FAmNLCQCWCgQFAmZ4AAAJAGUCCQBlAgUCY1EFAmZ4BQJiWAUCY1MDCQAAAgUCZm4FAmNMCQCWCgQAAAUCZngFAmNRCQBlAgkAZQIFAmNTBQJmeAUCYlgJAAIBAhRpbnZhbGlkIG91dCBhc3NldCBpZAQCZnoIBQJmeQJfMQQCZkEIBQJmeQJfMgQCZmUIBQJmeQJfMwQCZmYIBQJmeQJfNAQCZkIJAQJiQwIJAQFCAgUCZmYFAmZ0CQEBQgIFAmZlBQJmcwQCZkMJAQFGAgUCZkIFAWEEAmZEAwkAAAIFAmZuAgVXQVZFUwUEdW5pdAkA2QQBBQJmbgQCZkUDCQBmAgUCYlgAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhUAUCYlgFAmZEBQNuaWwFA25pbAQCZGMJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJjSQUCZngFAmZECQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFXAgkApQgBBQJjSQUCY0YJAQJidwYFAmZ6BQJmQQUCZG4FAmZDBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBUAAFAmZDCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBUQIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmZDBQNuaWwFAmZFAwkAAAIFAmRjBQJkYwQCZkYJAPwHBAUCYUkCBGJ1cm4JAMwIAgUCZG4FA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCY0cFAmRuBQNuaWwDCQAAAgUCZkYFAmZGBAJmRwQCZkgDCQAAAgUEdGhpcwUCYVAAAAUCYlgEAmZJAwkAAAIJAQJhVQEFAmZuBQJiZAYHAwUCZkkJAJQKAgkBAS0BCQBkAgUCZncFAmZIAAAJAJQKAgAACQEBLQEJAGQCBQJmdwUCZkgEAmV2CAUCZkcCXzEEAmV3CAUCZkcCXzIEAmZKCQECZXUDBQJldgUCZXcAAAQCZksIBQJmSgJfMQQCZWwIBQJmSgJfMgQCZkwJAQJleQIFAmV0BQJlbAMJAAACBQJmTAUCZkwJAJQKAgkAzggCBQJkYwUCZksFAmZ4CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJmTQAEAmZOCQCiCAEJAQFOAAMJAAECBQJmTgIGU3RyaW5nBAJjYwUCZk4JANkEAQUCY2MDCQABAgUCZk4CBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECZk8ABAJmTgkAoggBCQEBTwADCQABAgUCZk4CBlN0cmluZwQCY2MFAmZOCQDZBAEFAmNjAwkAAQIFAmZOAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IAAmZQCQACAQIRUGVybWlzc2lvbiBkZW5pZWQBAmZRAQJjcQQCZk4JAQJmTQADCQABAgUCZk4CCkJ5dGVWZWN0b3IEAmZSBQJmTgkAAAIIBQJjcQ9jYWxsZXJQdWJsaWNLZXkFAmZSAwkAAQIFAmZOAgRVbml0CQAAAggFAmNxBmNhbGxlcgUEdGhpcwkAAgECC01hdGNoIGVycm9yAQJmUwECY3EEAmZOCQECZk0AAwkAAQIFAmZOAgpCeXRlVmVjdG9yBAJmUgUCZk4DCQAAAggFAmNxD2NhbGxlclB1YmxpY0tleQUCZlIGBQJmUAMJAAECBQJmTgIEVW5pdAMJAAACCAUCY3EGY2FsbGVyBQR0aGlzBgUCZlAJAAIBAgtNYXRjaCBlcnJvcgECZlQDAmZVAmRWAmZWBAJhWQkBAmFRAAQCY0sJAJEDAgUCYVkFAXQEAmNMCQCRAwIFAmFZBQF1BAJkVwUBZwQCZFkJAKcDAQUBbAQCY2QJALkCAgkApwMBBQJhTQUCZFkEAmJaAwkAAAIFAmZVBwkAzAgCCQC3AgIJALYCAQkBAmJBAQUCY0sFAmZWCQDMCAIJALYCAQkBAmJBAQUCY0wFA25pbAkAzAgCCQC3AgIJALYCAQkBAmJBAQUCY0wFAmZWCQDMCAIJALYCAQkBAmJBAQUCY0sFA25pbAQCZFgJAJEDAgUCYloAAAQCY2MFAmRYBAJjZQkAuQICBQJjZAUCZFcEAmRaCQC6AgIJALkCAgkAuQICCQC6AgIJALkCAgUCZFYFAmRWCQC5AgIFAmRYBQJkVwUCZFYFAmRZCQC5AgIFAmNlBQJkVwQCZWEJALgCAgkAtwICBQJjYwkAugICCQC5AgIFAmRWBQJkWQUCY2UFAmRWCgECY28CAmNwAmViBAJmVwUCY3AEAmVkCAUCZlcCXzEEAmNECAUCZlcCXzIDCQECIT0CBQJjRAUEdW5pdAUCY3AEAmVlCQC6AgIJALcCAgkAuQICBQJlZAUCZWQFAmRaCQC3AgIJALkCAgUBZwUCZWQFAmVhBAJlZgkBAUwBCQC4AgIFAmVlCQEFdmFsdWUBBQJlZAMJAMACAgUBZgUCZWYJAJQKAgUCZWUFAmViCQCUCgIFAmVlBQR1bml0BAJjdQkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkJAMwIAgAKCQDMCAIACwkAzAgCAAwJAMwIAgANCQDMCAIADgUDbmlsBAJmWAoAAmN3BQJjdQoAAmN4CQCQAwEFAmN3CgACY3kJAJQKAgUCZFYFBHVuaXQKAQJjegICY0ECY0IDCQBnAgUCY0IFAmN4BQJjQQkBAmNvAgUCY0EJAJEDAgUCY3cFAmNCCgECY0MCAmNBAmNCAwkAZwIFAmNCBQJjeAUCY0EJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxNQkBAmNDAgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgkBAmN6AgUCY3kAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwQCZWQIBQJmWAJfMQQCY0QIBQJmWAJfMgMJAQIhPQIFAmNEBQR1bml0BQJlZAkAAgEJAKwCAgIZWSBjYWxjdWxhdGlvbiBlcnJvciwgWSA9IAkApgMBBQJlZAECZlkACQELdmFsdWVPckVsc2UCCQCbCAIFAmFJCQECYXUBCQClCAEFBHRoaXMHHQJjcQEhY2FsY3VsYXRlQW1vdW50T3V0Rm9yU3dhcFJFQURPTkxZAwJmWgJmVQJnYQQCZ2IDCQAAAgUCZlUHBAJnYwkBAmFCAgUEdGhpcwkBAVkABAJmVgkAtwICCQC2AgEJAQJiQQEJAQJhQgIFBHRoaXMJAQFYAAkAtgIBBQJmWgkAlAoCBQJnYwUCZlYEAmdjCQECYUICBQR0aGlzCQEBWAAEAmZWCQC3AgIJALYCAQkBAmJBAQkBAmFCAgUEdGhpcwkBAVkACQC2AgEFAmZaCQCUCgIFAmdjBQJmVgQCZ2MIBQJnYgJfMQQCZlYIBQJnYgJfMgQCYVkJAQJhUQAEAmNLCQCRAwIFAmFZBQF0BAJjTAkAkQMCBQJhWQUBdQQCYloJAMwIAgkAtgIBCQECYkEBBQJjSwkAzAgCCQC2AgEJAQJiQQEFAmNMBQNuaWwEAmRWCQECYlkBBQJiWgQCZWQJAQJmVAMFAmZVBQJkVgkAtgIBBQJmWgQCZ2QJALgCAgkAuAICCQC2AgEJAQJiQQEFAmdjBQJlZAkAtgIBAAEEAmdlCQCWAwEJAMwIAgAACQDMCAIJAKADAQUCZ2QFA25pbAQCZ2YDCQAAAgUCZlUHCQDMCAIJALcCAgkAtwICCQC2AgEJAQJiQQEFAmNLCQC2AgEFAmZaCQC2AgEFAmdhCQDMCAIJALgCAgkAtgIBCQECYkEBBQJjTAUCZ2QFA25pbAkAzAgCCQC4AgIJALYCAQkBAmJBAQUCY0sFAmdkCQDMCAIJALcCAgkAtwICCQC2AgEJAQJiQQEFAmNMCQC2AgEFAmZaCQC2AgEFAmdhBQNuaWwEAmdnCQECYlkBBQJnZgQCZEEDCQDAAgIFAmdnBQJkVgYJAAIBCQC5CQIJAMwIAgIUbmV3IEQgaXMgZmV3ZXIgZXJyb3IJAMwIAgkApgMBBQJkVgkAzAgCCQCmAwEFAmdnBQNuaWwCAl9fAwkAAAIFAmRBBQJkQQkAlAoCBQNuaWwFAmdlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNxASZjYWxjdWxhdGVBbW91bnRPdXRGb3JTd2FwQW5kU2VuZFRva2VucwUCZloCZlUCZ2gCZ2kCZ2EEAmdqCgACYUsJAPwHBAUCYUkCF2dldFN3YXBDb250cmFjdFJFQURPTkxZBQNuaWwFA25pbAMJAAECBQJhSwIGU3RyaW5nBQJhSwkAAgEJAKwCAgkAAwEFAmFLAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcEAmdrCQDMCAIDCQBnAggJAQV2YWx1ZQEJAJEDAggFAmNxCHBheW1lbnRzAAAGYW1vdW50BQJmWgYJAQJhRgECDFdyb25nIGFtb3VudAkAzAgCAwkAAAIIBQJjcQZjYWxsZXIJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmdqBgkBAmFGAQIRUGVybWlzc2lvbiBkZW5pZWQFA25pbAMJAAACBQJnawUCZ2sEAmVNCQEFdmFsdWUBCQCRAwIIBQJjcQhwYXltZW50cwAABAJnbAkBAmFXAQgFAmVNB2Fzc2V0SWQEAmdtAwkAAAIFAmZVBwQCZ2MJAQJhQgIFBHRoaXMJAQFZAAQCZlYJAGUCCQECYkEBBQJnbAgJAQV2YWx1ZQEJAJEDAggFAmNxCHBheW1lbnRzAAAGYW1vdW50CQCUCgIFAmdjBQJmVgQCZ2MJAQJhQgIFBHRoaXMJAQFYAAQCZlYJAGUCCQECYkEBBQJnbAgJAQV2YWx1ZQEJAJEDAggFAmNxCHBheW1lbnRzAAAGYW1vdW50CQCUCgIFAmdjBQJmVgQCZ2MIBQJnbQJfMQQCZlYIBQJnbQJfMgQCYVkJAQJhUQAEAmNLCQCRAwIFAmFZBQF0BAJjTAkAkQMCBQJhWQUBdQQCYloDCQAAAgUCZlUHCQDMCAIJALgCAgkAtgIBCQECYkEBBQJjSwkAtgIBCAkBBXZhbHVlAQkAkQMCCAUCY3EIcGF5bWVudHMAAAZhbW91bnQJAMwIAgkAtgIBCQECYkEBBQJjTAUDbmlsCQDMCAIJALYCAQkBAmJBAQUCY0sJAMwIAgkAuAICCQC2AgEJAQJiQQEFAmNMCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJjcQhwYXltZW50cwAABmFtb3VudAUDbmlsBAJkVgkBAmJZAQUCYloEAmVkCQECZlQDBQJmVQUCZFYJALYCAQAABAJnZAkAuAICCQC4AgIJALYCAQkBAmJBAQUCZ2MFAmVkCQC2AgEAAQQCZ2UJAJYDAQkAzAgCAAAJAMwIAgkAoAMBBQJnZAUDbmlsBAJnbgMJAGcCBQJnZQUCZ2gGCQACAQIsRXhjaGFuZ2UgcmVzdWx0IGlzIGZld2VyIGNvaW5zIHRoYW4gZXhwZWN0ZWQDCQAAAgUCZ24FAmduBAJnZgMJAAACBQJmVQcJAMwIAgkAtwICCQC2AgEJAQJiQQEFAmNLCQC2AgEFAmdhCQDMCAIJALgCAgkAtgIBCQECYkEBBQJjTAUCZ2QFA25pbAkAzAgCCQC4AgIJALYCAQkBAmJBAQUCY0sFAmdkCQDMCAIJALcCAgkAtgIBCQECYkEBBQJjTAkAtgIBBQJnYQUDbmlsBAJnZwkBAmJZAQUCZ2YEAmRBAwkAwAICBQJnZwUCZFYGCQACAQIUbmV3IEQgaXMgZmV3ZXIgZXJyb3IDCQAAAgUCZEEFAmRBCQCUCgIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUCZ2kFAmdlCQECYVUBBQJnYwUDbmlsBQJnZQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjcQELY29uc3RydWN0b3IBAU0EAmRaCQECZlMBBQJjcQMJAAACBQJkWgUCZFoJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAU0ABQFNBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CY3EBCnNldE1hbmFnZXIBAmdvBAJkWgkBAmZTAQUCY3EDCQAAAgUCZFoFAmRaBAJncAkA2QQBBQJnbwMJAAACBQJncAUCZ3AJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAU8ABQJnbwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNxAQ5jb25maXJtTWFuYWdlcgAEAmNmCQECZk8ABAJncQMJAQlpc0RlZmluZWQBBQJjZgYJAAIBAhJObyBwZW5kaW5nIG1hbmFnZXIDCQAAAgUCZ3EFAmdxBAJncgMJAAACCAUCY3EPY2FsbGVyUHVibGljS2V5CQEFdmFsdWUBBQJjZgYJAAIBAhtZb3UgYXJlIG5vdCBwZW5kaW5nIG1hbmFnZXIDCQAAAgUCZ3IFAmdyCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFOAAkA2AQBCQEFdmFsdWUBBQJjZgkAzAgCCQELRGVsZXRlRW50cnkBCQEBTwAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjcQEDcHV0AgJncwJndAQCZ3UJAQJiaAAEAmd2CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQJndQUBeAIKV3Igc3QgYWRkcgQCZ3cJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmd1BQF6AgpXciBzbCBhZGRyAwkAZgIAAAUCZ3MJAAIBAg5Xcm9uZyBzbGlwcGFnZQMJAQIhPQIJAJADAQgFAmNxCHBheW1lbnRzAAIJAAIBAgwyIHBtbnRzIGV4cGQEAmd4CQC2AgEICQEFdmFsdWUBCQCRAwIIBQJjcQhwYXltZW50cwAABmFtb3VudAQCZ3kJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmNxCHBheW1lbnRzAAEGYW1vdW50BAJlcQkAuAICCQC2AgEJAQJiQQEJAQJhVwEFAmJkBQJneAMJAAACBQJlcQUCZXEEAmVyCQC4AgIJALYCAQkBAmJBAQkBAmFXAQUCYmUFAmd5AwkAAAIFAmVyBQJlcgQCZXMJALYCAQgJAQV2YWx1ZQEJAOwHAQUCYmMIcXVhbnRpdHkDCQAAAgUCZXMFAmVzBAJldAkBAmVtAwUCZ3gFAmd5CQC2AgEAAAMJAAACBQJldAUCZXQEAmd6CQECZU4KCQClCAEIBQJjcQZjYWxsZXIJANgEAQgFAmNxDXRyYW5zYWN0aW9uSWQJAQ9BdHRhY2hlZFBheW1lbnQCCAkBBXZhbHVlAQkAkQMCCAUCY3EIcGF5bWVudHMAAAdhc3NldElkCAkBBXZhbHVlAQkAkQMCCAUCY3EIcGF5bWVudHMAAAZhbW91bnQJAJEDAggFAmNxCHBheW1lbnRzAAEFAmdzBgcGAAACAAQCZE4IBQJnegJfMgQCZ0EIBQJnegJfNwQCZGMIBQJnegJfOQQCZE8IBQJnegNfMTAEAmRQCAUCZ3oDXzExBAJjSwgFAmd6A18xMgQCY0wIBQJnegNfMTMEAmR5CQD8BwQFAmFJAgRlbWl0CQDMCAIFAmROBQNuaWwFA25pbAMJAAACBQJkeQUCZHkEAmdCBAJmTgUCZHkDCQABAgUCZk4CB0FkZHJlc3MEAmdDBQJmTgkA/AcEBQJnQwIEZW1pdAkAzAgCBQJkTgUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZ0IFAmdCBAJnRAMJAGYCBQJkTwAACQD8BwQFAmd3AgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCY0sFAmRPBQNuaWwFA25pbAMJAAACBQJnRAUCZ0QEAmdFAwkAZgIFAmRQAAAJAPwHBAUCZ3cCA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJjTAUCZFAFA25pbAUDbmlsAwkAAAIFAmdFBQJnRQQCZ0YDBQJndAQCZ0cJAPwHBAUCZ3YCBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmdBBQJkTgUDbmlsAwkAAAIFAmdHBQJnRwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJjcQZjYWxsZXIFAmROBQJnQQUDbmlsBAJnSAkBAmV1AwAAAAAAAAQCZksIBQJnSAJfMQQCZWwIBQJnSAJfMgQCZ0kDCQDAAgIFAmVsBQJldAYJAQJhRgEJALkJAgkAzAgCAiJ1cGRhdGVkIERMcCBsb3dlciB0aGFuIGN1cnJlbnQgRExwCQDMCAIJAKYDAQUCZXEJAMwIAgkApgMBBQJlcgkAzAgCCQCmAwEFAmVzCQDMCAIJAKYDAQUCZXQJAMwIAgkApgMBBQJlbAkAzAgCCQCkAwEFAmRPCQDMCAIJAKQDAQUCZFAFA25pbAIBIAMJAAACBQJnSQUCZ0kEAmdKCAkBBXZhbHVlAQkA7AcBBQJiYwhxdWFudGl0eQMJAAACBQJnSgUCZ0oJAM4IAgkAzggCBQJkYwUCZ0YFAmZLCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNxAQtwdXRPbmVUa25WMgICZm8CZ3QEAmdLCgACYUsJAPwHBAUCYUkCKGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhSwIHQm9vbGVhbgUCYUsJAAIBCQCsAgIJAAMBBQJhSwIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCZ0wDAwMJAQJhTgAGCQAAAgUCYmIFAW4GCQAAAgUCYmIFAXAGBQJnSwQCZ2sJAMwIAgMDCQEBIQEFAmdMBgkBAmZRAQUCY3EGCQECYUYBAiFwdXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJjcQhwYXltZW50cwABBgkBAmFGAQIeZXhhY3RseSAxIHBheW1lbnQgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZ2sFAmdrBAJjSwkA2AQBCQEFdmFsdWUBBQJiZAQCY0wJANgEAQkBBXZhbHVlAQUCYmUEAmNKBQJiYwQCZnMFAmJmBAJmdAUCYmcEAmNJAwkAAAIIBQJjcQZjYWxsZXIFBHRoaXMIBQJjcQxvcmlnaW5DYWxsZXIIBQJjcQZjYWxsZXIEAmVNCQEFdmFsdWUBCQCRAwIIBQJjcQhwYXltZW50cwAABAJjRwkA2AQBCQEFdmFsdWUBCAUCZU0HYXNzZXRJZAQCZG4IBQJlTQZhbW91bnQEAmV0AwkAAAIIBQJlTQdhc3NldElkBQJiZAkBAmVtAwkAtgIBBQJkbgkAtgIBAAAJALYCAQAACQECZW0DCQC2AgEAAAkAtgIBBQJkbgkAtgIBAAADCQAAAgUCZXQFAmV0BAJnTQkBAmVSBQUCZG4FAmNHCQClCAEFAmNJCQDYBAEIBQJjcQ10cmFuc2FjdGlvbklkBgMJAAACBQJnTQUCZ00EAmJYCAUCZ00CXzMEAmRjCAUCZ00CXzIEAmdOCAUCZ00CXzEEAmROAwMJAGYCBQJmbwAACQBmAgUCZm8FAmdOBwkBAmFGAQkAuQkCCQDMCAICH2Ftb3VudCB0byByZWNlaXZlIGlzIGxlc3MgdGhhbiAJAMwIAgkApAMBBQJmbwUDbmlsAgAFAmdOBAJnegkA/AcEBQJhSQIEZW1pdAkAzAgCBQJkTgUDbmlsBQNuaWwDCQAAAgUCZ3oFAmd6BAJnQgQCZk4FAmd6AwkAAQIFAmZOAgdBZGRyZXNzBAJnQwUCZk4JAPwHBAUCZ0MCBGVtaXQJAMwIAgUCZE4FA25pbAUDbmlsBQR1bml0AwkAAAIFAmdCBQJnQgQCZ0YDBQJndAQCZ0cJAPwHBAUCYmoCCHN0YWtlRm9yCQDMCAIJAKUIAQgFAmNxBmNhbGxlcgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJjSgUCZE4FA25pbAMJAAACBQJnRwUCZ0cFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCY3EGY2FsbGVyBQJkTgUCY0oFA25pbAQCZkUDCQBmAgUCYlgAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhUAUCYlgJANkEAQUCY0cFA25pbAUDbmlsBAJnTwMJAAACBQR0aGlzBQJhUAkAlAoCAAAAAAQCZ1ADCQAAAggFAmVNB2Fzc2V0SWQFAmJkBgcDBQJnUAkAlAoCCQEBLQEFAmJYAAAJAJQKAgAACQEBLQEFAmJYBAJldggFAmdPAl8xBAJldwgFAmdPAl8yBAJnUQkBAmV1AwUCZXYFAmV3AAAEAmZLCAUCZ1ECXzEEAmVsCAUCZ1ECXzIEAmZMCQECZXkCBQJldAUCZWwDCQAAAgUCZkwFAmZMCQCUCgIJAM4IAgkAzggCCQDOCAIFAmRjBQJnRgUCZkUFAmZLBQJkTgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjcQEKcHV0Rm9yRnJlZQECZ1IDCQBmAgAABQJnUgkAAgECCldyb25nIHNscGcDCQECIT0CCQCQAwEIBQJjcQhwYXltZW50cwACCQACAQIMMiBwbW50cyBleHBkBAJnUwkBAmVOCgkApQgBCAUCY3EGY2FsbGVyCQDYBAEIBQJjcQ10cmFuc2FjdGlvbklkCQEPQXR0YWNoZWRQYXltZW50AggJAQV2YWx1ZQEJAJEDAggFAmNxCHBheW1lbnRzAAAHYXNzZXRJZAgJAQV2YWx1ZQEJAJEDAggFAmNxCHBheW1lbnRzAAAGYW1vdW50CQCRAwIIBQJjcQhwYXltZW50cwABBQJnUgcHBgAAAgAEAmRjCAUCZ1MCXzkEAmd4CQC2AgEICQEFdmFsdWUBCQCRAwIIBQJjcQhwYXltZW50cwAABmFtb3VudAQCZ3kJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmNxCHBheW1lbnRzAAEGYW1vdW50BAJldAkBAmVtAwUCZ3gFAmd5CQC2AgEAAAMJAAACBQJldAUCZXQEAmdUCQECZXUDAAAAAAAABAJmSwgFAmdUAl8xBAJlbAgFAmdUAl8yBAJmTAkBAmV5AgUCZXQFAmVsAwkAAAIFAmZMBQJmTAkAzggCBQJkYwUCZksJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CY3EBA2dldAAEAmV0CQECZW0DCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmV0BQJldAQCZHkJAQJlTAEFAmNxBAJnVQgFAmR5Al8xBAJkYggFAmR5Al8yBAJkbggFAmR5Al8zBAJjRwgFAmR5Al80BAJkYwgFAmR5Al81BAJlYQkA/AcEBQJhSQIEYnVybgkAzAgCBQJkbgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJjRwUCZG4FA25pbAMJAAACBQJlYQUCZWEEAmdWCQECZXUDCQEBLQEFAmdVCQEBLQEFAmRiAAAEAmZLCAUCZ1YCXzEEAmVsCAUCZ1YCXzIEAmZMCQECZXkCBQJldAUCZWwDCQAAAgUCZkwFAmZMCQDOCAIFAmRjBQJmSwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjcQELZ2V0T25lVGtuVjICAmZuAmZvBAJnSwoAAmFLCQD8BwQFAmFJAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYUsCB0Jvb2xlYW4FAmFLCQACAQkArAICCQADAQUCYUsCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmdXAwMJAQJhTgAGCQAAAgUCYmIFAXAGBQJnSwQCZ2sJAMwIAgMDCQEBIQEFAmdXBgkBAmZRAQUCY3EGCQECYUYBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJjcQhwYXltZW50cwABBgkBAmFGAQIeZXhhY3RseSAxIHBheW1lbnQgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZ2sFAmdrBAJnWAkBAmZtBgUCZm4FAmZvCAUCY3EIcGF5bWVudHMIBQJjcQZjYWxsZXIIBQJjcQxvcmlnaW5DYWxsZXIIBQJjcQ10cmFuc2FjdGlvbklkBAJkYwgFAmdYAl8xBAJmeAgFAmdYAl8yCQCUCgIFAmRjBQJmeAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjcQEKcmVmcmVzaERMcAAEAmdZCQELdmFsdWVPckVsc2UCCQCfCAEFAmFnAAAEAmdaAwkAZwIJAGUCBQZoZWlnaHQFAmdZBQJhagUEdW5pdAkBAmFGAQkAuQkCCQDMCAIJAKQDAQUCYWoJAMwIAgIvIGJsb2NrcyBoYXZlIG5vdCBwYXNzZWQgc2luY2UgdGhlIHByZXZpb3VzIGNhbGwFA25pbAIAAwkAAAIFAmdaBQJnWgQCZUYJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAqAMBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAmFmAgEwCQECYUgBAgtpbnZhbGlkIGRMcAQCaGEJAQJldQMAAAAAAAAEAmhiCAUCaGECXzEEAmVsCAUCaGECXzIEAmV4AwkBAiE9AgUCZUYFAmVsBQJoYgkBAmFGAQISbm90aGluZyB0byByZWZyZXNoCQCUCgIFAmV4CQCmAwEFAmVsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNxARNnZXRPbmVUa25WMlJFQURPTkxZAgJmbgJoYwQCY0sJANgEAQkBBXZhbHVlAQUCYmQEAmNMCQDYBAEJAQV2YWx1ZQEFAmJlBAJjSgkA2AQBCQEFdmFsdWUBBQJiYwQCYloJAMwIAgkAtgIBCQECYkEBBQJjSwkAzAgCCQC2AgEJAQJiQQEFAmNMBQNuaWwEAmVrCQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQkA2QQBBQJjSgIQaW52YWxpZCBscCBhc3NldAhxdWFudGl0eQQCZHgJAQJiWQEFAmJaBAJkegkAuAICBQJkeAkAvAIDCQC2AgEFAmhjBQJkeAUCZWsEAmhkAwkAAAIFAmZuBQJjSwAAAwkAAAIFAmZuBQJjTAABCQACAQIUaW52YWxpZCBvdXQgYXNzZXQgaWQEAmhlCQECZFUDBQJiWgUCaGQFAmR6BAJnZAkAuAICCQCRAwIFAmJaBQJoZAUCaGUEAmdlCQCWAwEJAMwIAgAACQDMCAIJAKADAQkAuAICBQJnZAUBZgUDbmlsBAJoZgkBAmJWAgUCZ2UFAmFMBAJmdwgFAmhmAl8xBAJiWAgFAmhmAl8yCQCUCgIFA25pbAkAlAoCBQJmdwUCYlgCY3EBHGdldE9uZVRrblYyV2l0aEJvbnVzUkVBRE9OTFkCAmZuAmhjBAJjSwkA2AQBCQEFdmFsdWUBBQJiZAQCY0wJANgEAQkBBXZhbHVlAQUCYmUEAmNKCQDYBAEJAQV2YWx1ZQEFAmJjBAJjUQkBAmJBAQUCY0sEAmNTCQECYkEBBQJjTAQCaGcKAAJhSwkA/AcEBQR0aGlzAhNnZXRPbmVUa25WMlJFQURPTkxZCQDMCAIFAmZuCQDMCAIFAmhjBQNuaWwFA25pbAMJAAECBQJhSwIKKEludCwgSW50KQUCYUsJAAIBCQCsAgIJAAMBBQJhSwIfIGNvdWxkbid0IGJlIGNhc3QgdG8gKEludCwgSW50KQQCZncIBQJoZwJfMQQCYlgIBQJoZwJfMgQCZHkJAQJjRQQCAAUCY0oFAmhjBQR0aGlzBAJkYQgFAmR5Al8xBAJkYggFAmR5Al8yBAJoaAkAZAIFAmRhBQJkYgQCZmwDCQAAAgUCaGgAAAMJAAACBQJmdwAAAAAJAAIBAhdib251cyBjYWxjdWxhdGlvbiBlcnJvcgkAawMJAGUCBQJmdwUCaGgFAWEFAmhoCQCUCgIFA25pbAkAlQoDBQJmdwUCYlgFAmZsAmNxAQlnZXROb0xlc3MCAmhpAmhqBAJkeQkBAmVMAQUCY3EEAmRhCAUCZHkCXzEEAmRiCAUCZHkCXzIEAmRuCAUCZHkCXzMEAmNHCAUCZHkCXzQEAmRjCAUCZHkCXzUDCQBmAgUCaGkFAmRhCQACAQkArAICCQCsAgIJAKwCAgIJRmFpbGVkOiAgCQCkAwEFAmRhAgMgPCAJAKQDAQUCaGkDCQBmAgUCaGoFAmRiCQACAQkArAICCQCsAgIJAKwCAgIIRmFpbGVkOiAJAKQDAQUCZGICAyA8IAkApAMBBQJoagQCZXQJAQJlbQMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZXQFAmV0BAJoawkA/AcEBQJhSQIEYnVybgkAzAgCBQJkbgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJjRwUCZG4FA25pbAMJAAACBQJoawUCaGsEAmhsCQECZXUDCQEBLQEFAmRhCQEBLQEFAmRiAAAEAmZLCAUCaGwCXzEEAmVsCAUCaGwCXzIEAmZMCQECZXkCBQJldAUCZWwDCQAAAgUCZkwFAmZMCQDOCAIFAmRjBQJmSwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjcQENdW5zdGFrZUFuZEdldAECYlcEAmhtAwkBAiE9AgkAkAMBCAUCY3EIcGF5bWVudHMAAAkAAgECDU5vIHBtbnRzIGV4cGQGAwkAAAIFAmhtBQJobQQCaG4JAQJiaAAEAmdBBQJiYwQCaG8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmhuBQF4AgpXciBzdCBhZGRyBAJldAkBAmVtAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJldAUCZXQEAmhwCQD8BwQFAmhvAgd1bnN0YWtlCQDMCAIJANgEAQUCZ0EJAMwIAgUCYlcFA25pbAUDbmlsAwkAAAIFAmhwBQJocAQCZHkJAQJjRQQJANgEAQgFAmNxDXRyYW5zYWN0aW9uSWQJANgEAQUCZ0EFAmJXCAUCY3EGY2FsbGVyBAJkYQgFAmR5Al8xBAJkYggFAmR5Al8yBAJjTwkBDXBhcnNlSW50VmFsdWUBCAUCZHkCXzkEAmRjCAUCZHkDXzEwBAJocQMDCQECYU4ABgkAAAIFAmNPBQFwCQACAQkArAICAglCbG9ja2VkOiAJAKQDAQUCY08GAwkAAAIFAmhxBQJocQQCaHIJAPwHBAUCYUkCBGJ1cm4JAMwIAgUCYlcFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZ0EFAmJXBQNuaWwDCQAAAgUCaHIFAmhyBAJocwkBAmV1AwkBAS0BBQJkYQkBAS0BBQJkYgAABAJmSwgFAmhzAl8xBAJlbAgFAmhzAl8yBAJmTAkBAmV5AgUCZXQFAmVsAwkAAAIFAmZMBQJmTAkAzggCBQJkYwUCZksJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CY3EBE3Vuc3Rha2VBbmRHZXROb0xlc3MDAmh0Amh1AmhqBAJnVwMJAQJhTgAGCQAAAgUCYmIFAXAEAmdrCQDMCAIDCQEBIQEFAmdXBgkAAgECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmNxCHBheW1lbnRzAAAGCQACAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZ2sFAmdrBAJldAkBAmVtAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJldAUCZXQEAmhwCQD8BwQFAmJqAgd1bnN0YWtlCQDMCAIJANgEAQUCYmMJAMwIAgUCaHQFA25pbAUDbmlsAwkAAAIFAmhwBQJocAQCaHYJAQJjRQQJANgEAQgFAmNxDXRyYW5zYWN0aW9uSWQJANgEAQUCYmMFAmh0CAUCY3EGY2FsbGVyBAJkYQgFAmh2Al8xBAJkYggFAmh2Al8yBAJkYwgFAmh2A18xMAQCaHcJAMwIAgMJAGcCBQJkYQUCaHUGCQACAQkAuQkCCQDMCAICLGFtb3VudCBhc3NldCBhbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCaHUFA25pbAIACQDMCAIDCQBnAgUCZGIFAmhqBgkAAgEJALkJAgkAzAgCAitwcmljZSBhc3NldCBhbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCaGoFA25pbAIABQNuaWwDCQAAAgUCaHcFAmh3BAJoawkA/AcEBQJhSQIEYnVybgkAzAgCBQJodAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiYwUCaHQFA25pbAMJAAACBQJoawUCaGsEAmh4CQECZXUDCQEBLQEFAmRhCQEBLQEFAmRiAAAEAmZLCAUCaHgCXzEEAmVsCAUCaHgCXzIEAmZMCQECZXkCBQJldAUCZWwDCQAAAgUCZkwFAmZMCQDOCAIFAmRjBQJmSwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjcQEVdW5zdGFrZUFuZEdldE9uZVRrblYyAwJodAJmbgJmbwQCZ0sKAAJhSwkA/AcEBQJhSQIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFLAgdCb29sZWFuBQJhSwkAAgEJAKwCAgkAAwEFAmFLAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJnVwMDCQECYU4ABgkAAAIFAmJiBQFwBgUCZ0sEAmdrCQDMCAIDAwkBASEBBQJnVwYJAQJmUQEFAmNxBgkBAmFGAQIhZ2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCY3EIcGF5bWVudHMAAAYJAQJhRgECGG5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmdrBQJnawQCaG4JAQJiaAAEAmdBBQJiYwQCaG8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmhuBQF4AgpXciBzdCBhZGRyBAJjSQgFAmNxBmNhbGxlcgQCaHkFBHRoaXMEAmhwCQD8BwQFAmhvAg91bnN0YWtlSU5URVJOQUwJAMwIAgUCZ0EJAMwIAgUCaHQJAMwIAggFAmNJBWJ5dGVzCQDMCAIIBQJoeQVieXRlcwUDbmlsBQNuaWwDCQAAAgUCaHAFAmhwBAJoegkBAmZtBgUCZm4FAmZvCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJnQQUCaHQFA25pbAgFAmNxBmNhbGxlcggFAmNxDG9yaWdpbkNhbGxlcggFAmNxDXRyYW5zYWN0aW9uSWQEAmRjCAUCaHoCXzEEAmZ4CAUCaHoCXzIJAJQKAgUCZGMFAmZ4CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNxARxwdXRPbmVUa25WMldpdGhCb251c1JFQURPTkxZAgJoQQJoQgQCaEMJAQJlUgUFAmhBBQJoQgIAAgAGBAJmZwgFAmhDAl8xBAJkYwgFAmhDAl8yBAJiWAgFAmhDAl8zBAJmbAgFAmhDAl80CQCUCgIFA25pbAkAlQoDBQJmZwUC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AAIFAmdrBQJnawkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFjAAUGaGVpZ2h0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFaAAkApAMBBQJoUwkAzAgCCQELU3RyaW5nRW50cnkCCQECYWEBBQZoZWlnaHQJAKQDAQUCaFMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECaFYBAmhXAAQCaFgEAmZOCQECZk0AAwkAAQIFAmZOAgpCeXRlVmVjdG9yBAJmUgUCZk4FAmZSAwkAAQIFAmZOAgRVbml0CAUCaFYPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IEAmZOBQJoVgMJAAECBQJmTgIFT3JkZXIEAmVCBQJmTgQCaFkJAQJhTwAEAmhaAwkBAmZZAAkAlAoCBgIACQECZUEBBQJlQgQCYXgIBQJoWgJfMQQCYXkIBQJoWgJfMgQCYXoJAPQDAwgFAmVCCWJvZHlCeXRlcwkAkQMCCAUCZUIGcHJvb2ZzAAAIBQJlQg9zZW5kZXJQdWJsaWNLZXkEAmFBCQD0AwMIBQJlQglib2R5Qnl0ZXMJAJEDAggFAmVCBnByb29mcwABBQJoWQMDAwUCYXgFAmF6BwUCYUEHBgkBAmF3BAUCYXgFAmF5BQJhegUCYUEDCQABAgUCZk4CFFNldFNjcmlwdFRyYW5zYWN0aW9uBAJjYwUCZk4DCQD0AwMIBQJoVglib2R5Qnl0ZXMJAJEDAggFAmhWBnByb29mcwAABQJoWAYEAmlhCQD2AwEJAQV2YWx1ZQEIBQJjYwZzY3JpcHQEAmliCQDbBAEJAQV2YWx1ZQEJAJ0IAgUCYUkJAQJhcwAEAmljCQDxBwEFBHRoaXMDCQAAAgUCaWIFAmlhCQECIT0CBQJpYwUCaWEHCQD0AwMIBQJoVglib2R5Qnl0ZXMJAJEDAggFAmhWBnByb29mcwAABQJoWKTIBrQ=", "height": 2562940, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 7MDyp4EsZYFUWwKuHKFWnXh6z7TAijdLkGNJUVLwgmB3 Next: 8C89DQdGAq2zYL1opkyKEFnEfWauNzuqVwTM4c6FbQCZ Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 6 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let scale8 = 100000000
5+
6+let scale8BigInt = toBigInt(100000000)
7+
8+let scale18 = toBigInt(1000000000000000000)
9+
10+let zeroBigInt = toBigInt(0)
11+
12+let big0 = toBigInt(0)
13+
14+let big1 = toBigInt(1)
15+
16+let big2 = toBigInt(2)
17+
18+let big3 = toBigInt(3)
19+
20+let big4 = toBigInt(4)
21+
22+let wavesString = "WAVES"
23+
24+let ampInitial = 50
25+
26+let Amult = "100"
27+
28+let SEP = "__"
29+
30+let PoolPutDis = 2
31+
32+let PoolMatcherDis = 3
33+
34+let PoolShutdown = 4
35+
36+let idxPoolAddress = 1
37+
38+let idxPoolSt = 2
39+
40+let idxLPAsId = 3
41+
42+let idxAmAsId = 4
43+
44+let idxPrAsId = 5
45+
46+let idxAmtAsDcm = 6
47+
48+let idxPriceAsDcm = 7
49+
50+let idxFactStakCntr = 1
51+
52+let idxFactoryRestCntr = 6
53+
54+let idxFactSlippCntr = 7
55+
56+let feeDefault = fraction(10, scale8, 10000)
57+
58+func t1 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
59+
60+
61+func t1BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
62+
63+
64+func f1 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
65+
66+
67+func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
68+
69+
70+func abs (val) = if ((zeroBigInt > val))
71+ then -(val)
72+ else val
73+
74+
75+func absBigInt (val) = if ((zeroBigInt > val))
76+ then -(val)
77+ else val
78+
79+
80+func fc () = "%s__factoryContract"
81+
82+
83+func mpk () = "%s__managerPublicKey"
84+
85+
86+func pmpk () = "%s__pendingManagerPublicKey"
87+
88+
89+func pl () = "%s%s__price__last"
90+
91+
92+func ph (h,t) = makeString(["%s%s%d%d__price__history", toString(h), toString(t)], SEP)
93+
94+
95+func pau (ua,txId) = ((("%s%s%s__P__" + ua) + "__") + txId)
96+
97+
98+func gau (ua,txId) = ((("%s%s%s__G__" + ua) + "__") + txId)
99+
100+
101+func aa () = "%s__amountAsset"
102+
103+
104+func pa () = "%s__priceAsset"
105+
106+
107+func amp () = "%s__amp"
108+
109+
110+func keyAmpHistory (heightBlocks) = ("%s%d__amp__" + toString(heightBlocks))
111+
112+
113+func keyChangeAmpLastCall () = "%s__changeAmpLastCall"
114+
115+
116+let keyFee = "%s__fee"
117+
118+let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
119+
120+let keyDLp = makeString(["%s", "dLp"], SEP)
121+
122+let keyDLpRefreshedHeight = makeString(["%s", "dLpRefreshedHeight"], SEP)
123+
124+let keyDLpRefreshDelay = makeString(["%s", "refreshDLpDelay"], SEP)
125+
126+let dLpRefreshDelayDefault = 30
127+
128+let dLpRefreshDelay = valueOrElse(getInteger(this, keyDLpRefreshDelay), dLpRefreshDelayDefault)
129+
130+func fcfg () = "%s__factoryConfig"
131+
132+
133+func mtpk () = "%s%s__matcher__publicKey"
134+
135+
136+func pc (iAmtAs,iPrAs) = (((("%d%d%s__" + iAmtAs) + "__") + iPrAs) + "__config")
137+
138+
139+func mba (bAStr) = ("%s%s%s__mappings__baseAsset2internalId__" + bAStr)
140+
141+
142+func aps () = "%s__shutdown"
143+
144+
145+func keyAllowedLpStableScriptHash () = "%s__allowedLpStableScriptHash"
146+
147+
148+func keyFeeCollectorAddress () = "%s__feeCollectorAddress"
149+
150+
151+func keySkipOrderValidation (poolAddress) = ("%s%s__skipOrderValidation__" + poolAddress)
152+
153+
154+func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
155+
156+
157+func strf (addr,key) = valueOrErrorMessage(getString(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
158+
159+
160+func intf (addr,key) = valueOrErrorMessage(getInteger(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
161+
162+
163+func throwErr (msg) = throw(makeString(["lp_stable.ride:", msg], " "))
164+
165+
166+func fmtErr (msg) = makeString(["lp_stable.ride:", msg], " ")
167+
168+
169+let fca = addressFromStringValue(strf(this, fc()))
170+
171+let inFee = {
172+ let @ = invoke(fca, "getInFeeREADONLY", [toString(this)], nil)
173+ if ($isInstanceOf(@, "Int"))
174+ then @
175+ else throw(($getType(@) + " couldn't be cast to Int"))
176+ }
177+
178+let outFee = {
179+ let @ = invoke(fca, "getOutFeeREADONLY", [toString(this)], nil)
180+ if ($isInstanceOf(@, "Int"))
181+ then @
182+ else throw(($getType(@) + " couldn't be cast to Int"))
183+ }
184+
185+let A = strf(this, amp())
186+
187+func igs () = valueOrElse(getBoolean(fca, aps()), false)
188+
189+
190+func mp () = fromBase58String(strf(fca, mtpk()))
191+
192+
193+let feeCollectorAddress = addressFromStringValue(strf(fca, keyFeeCollectorAddress()))
194+
195+func gpc () = {
196+ let amtAs = strf(this, aa())
197+ let priceAs = strf(this, pa())
198+ let iPriceAs = intf(fca, mba(priceAs))
199+ let iAmtAs = intf(fca, mba(amtAs))
200+ split(strf(fca, pc(toString(iAmtAs), toString(iPriceAs))), SEP)
201+ }
202+
203+
204+func parseAssetId (input) = if ((input == wavesString))
205+ then unit
206+ else fromBase58String(input)
207+
208+
209+func assetIdToString (input) = if ((input == unit))
210+ then wavesString
211+ else toBase58String(value(input))
212+
213+
214+func parsePoolConfig (poolConfig) = $Tuple7(addressFromStringValue(poolConfig[idxPoolAddress]), parseIntValue(poolConfig[idxPoolSt]), fromBase58String(poolConfig[idxLPAsId]), parseAssetId(poolConfig[idxAmAsId]), parseAssetId(poolConfig[idxPrAsId]), parseIntValue(poolConfig[idxAmtAsDcm]), parseIntValue(poolConfig[idxPriceAsDcm]))
215+
216+
217+let poolConfigParsed = parsePoolConfig(gpc())
218+
219+let $t080878273 = poolConfigParsed
220+
221+let cfgPoolStatus = $t080878273._2
222+
223+let cfgLpAssetId = $t080878273._3
224+
225+let cfgAmountAssetId = $t080878273._4
226+
227+let cfgPriceAssetId = $t080878273._5
228+
229+let cfgAmountAssetDecimals = $t080878273._6
230+
231+let cfgPriceAssetDecimals = $t080878273._7
232+
233+func gfc () = split(strf(fca, fcfg()), SEP)
234+
235+
236+let factoryConfig = gfc()
237+
238+let stakingContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactStakCntr]), "Invalid staking contract address")
239+
240+let restContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactoryRestCntr]), "Invalid gwx contract address")
241+
242+func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slipByUser,slippageReal,txHeight,txTimestamp,slipageAmAmt,slipagePrAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slipByUser), toString(slippageReal), toString(txHeight), toString(txTimestamp), toString(slipageAmAmt), toString(slipagePrAmt)], SEP)
243+
244+
245+func dataGetActionInfo (outAmtAssetAmt,outPriceAssetAmt,inLpAmt,price,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d", toString(outAmtAssetAmt), toString(outPriceAssetAmt), toString(inLpAmt), toString(price), toString(txHeight), toString(txTimestamp)], SEP)
246+
247+
248+func getAccBalance (assetId) = if ((assetId == "WAVES"))
249+ then wavesBalance(this).available
250+ else assetBalance(this, fromBase58String(assetId))
251+
252+
253+func cpbi (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
254+
255+
256+func cpbir (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
257+
258+
259+func pcp (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
260+ let amtAsAmtX18 = t1(amAmt, amAssetDcm)
261+ let prAsAmtX18 = t1(prAmt, prAssetDcm)
262+ cpbi(prAsAmtX18, amtAsAmtX18)
263+ }
264+
265+
266+func calcPrices (amAmt,prAmt,lpAmt) = {
267+ let amtAsDcm = cfgAmountAssetDecimals
268+ let prAsDcm = cfgPriceAssetDecimals
269+ let priceX18 = pcp(amtAsDcm, prAsDcm, amAmt, prAmt)
270+ let amAmtX18 = t1(amAmt, amtAsDcm)
271+ let prAmtX18 = t1(prAmt, prAsDcm)
272+ let lpAmtX18 = t1(lpAmt, scale8)
273+ let lpPrInAmAsX18 = cpbi(amAmtX18, lpAmtX18)
274+ let lpPrInPrAsX18 = cpbi(prAmtX18, lpAmtX18)
275+[priceX18, lpPrInAmAsX18, lpPrInPrAsX18]
276+ }
277+
278+
279+func takeFee (amount,fee) = {
280+ let feeAmount = if ((fee == 0))
281+ then 0
282+ else fraction(amount, fee, scale8)
283+ $Tuple2((amount - feeAmount), feeAmount)
284+ }
285+
286+
287+func getD (xp) = {
288+ let xp0 = xp[0]
289+ let xp1 = xp[1]
290+ let s = (xp0 + xp1)
291+ if ((s == big0))
292+ then big0
293+ else {
294+ let a = parseIntValue(A)
295+ let ann = (a * 2)
296+ let p = fraction(xp0, xp1, big1)
297+ let xp0_xp1_n_n = fraction(p, big4, big1)
298+ let ann_s = fraction(toBigInt(ann), s, big1)
299+ let ann_1 = toBigInt((ann - 1))
300+ func calcDNext (d) = {
301+ let dd = fraction(d, d, big1)
302+ let ddd = fraction(dd, d, big1)
303+ let dp = fraction(ddd, big1, xp0_xp1_n_n)
304+ fraction((ann_s + fraction(dp, big2, big1)), d, (fraction(ann_1, d, big1) + fraction(big3, dp, big1)))
305+ }
306+
307+ func calc (acc,i) = if (acc._2)
308+ then acc
309+ else {
310+ let d = acc._1
311+ let dNext = calcDNext(d)
312+ let dDiffRaw = (dNext - value(d))
313+ let dDiff = if ((big0 > dDiffRaw))
314+ then -(dDiffRaw)
315+ else dDiffRaw
316+ if ((big1 >= dDiff))
317+ then $Tuple2(dNext, true)
318+ else $Tuple2(dNext, false)
319+ }
320+
321+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
322+ let $t01277812826 = {
323+ let $l = arr
324+ let $s = size($l)
325+ let $acc0 = $Tuple2(s, false)
326+ func $f0_1 ($a,$i) = if (($i >= $s))
327+ then $a
328+ else calc($a, $l[$i])
329+
330+ func $f0_2 ($a,$i) = if (($i >= $s))
331+ then $a
332+ else throw("List size exceeds 17")
333+
334+ $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($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17)
335+ }
336+ let d = $t01277812826._1
337+ let found = $t01277812826._2
338+ if (found)
339+ then d
340+ else throw(("D calculation error, D = " + toString(d)))
341+ }
342+ }
343+
344+
345+func ego (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
346+ let lpId = cfgLpAssetId
347+ let amId = toBase58String(value(cfgAmountAssetId))
348+ let prId = toBase58String(value(cfgPriceAssetId))
349+ let amDcm = cfgAmountAssetDecimals
350+ let prDcm = cfgPriceAssetDecimals
351+ let sts = toString(cfgPoolStatus)
352+ let lpEmiss = valueOrErrorMessage(assetInfo(lpId), "Wrong LP id").quantity
353+ if ((toBase58String(lpId) != pmtAssetId))
354+ then throw("Wrong pmt asset")
355+ else {
356+ let amBalance = getAccBalance(amId)
357+ let amBalanceX18 = t1(amBalance, amDcm)
358+ let prBalance = getAccBalance(prId)
359+ let prBalanceX18 = t1(prBalance, prDcm)
360+ let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
361+ let curPrice = f1(curPriceX18, scale8)
362+ let pmtLpAmtX18 = t1(pmtLpAmt, scale8)
363+ let lpEmissX18 = t1(lpEmiss, scale8)
364+ let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissX18)
365+ let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissX18)
366+ let outAmAmt = fromX18Round(outAmAmtX18, amDcm, FLOOR)
367+ let outPrAmt = fromX18Round(outPrAmtX18, prDcm, FLOOR)
368+ let state = if ((txId58 == ""))
369+ then nil
370+ else [ScriptTransfer(userAddress, outAmAmt, if ((amId == "WAVES"))
371+ then unit
372+ else fromBase58String(amId)), ScriptTransfer(userAddress, outPrAmt, if ((prId == "WAVES"))
373+ then unit
374+ else fromBase58String(prId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
375+ $Tuple10(outAmAmt, outPrAmt, amId, prId, amBalance, prBalance, lpEmiss, curPriceX18, sts, state)
376+ }
377+ }
378+
379+
380+func epo (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEval,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
381+ let lpId = cfgLpAssetId
382+ let amIdStr = toBase58String(value(cfgAmountAssetId))
383+ let prIdStr = toBase58String(value(cfgPriceAssetId))
384+ let amtDcm = cfgAmountAssetDecimals
385+ let priceDcm = cfgPriceAssetDecimals
386+ let sts = toString(cfgPoolStatus)
387+ let lpEm = valueOrErrorMessage(assetInfo(lpId), "Wr lp as").quantity
388+ let amBalance = if (isEval)
389+ then getAccBalance(amIdStr)
390+ else if (if (isOneAsset)
391+ then (pmtId == amIdStr)
392+ else false)
393+ then (getAccBalance(amIdStr) - pmtAmt)
394+ else if (isOneAsset)
395+ then getAccBalance(amIdStr)
396+ else (getAccBalance(amIdStr) - inAmAmt)
397+ let prBalance = if (isEval)
398+ then getAccBalance(prIdStr)
399+ else if (if (isOneAsset)
400+ then (pmtId == prIdStr)
401+ else false)
402+ then (getAccBalance(prIdStr) - pmtAmt)
403+ else if (isOneAsset)
404+ then getAccBalance(prIdStr)
405+ else (getAccBalance(prIdStr) - inPrAmt)
406+ let inAmAssetAmtX18 = t1(inAmAmt, amtDcm)
407+ let inPrAssetAmtX18 = t1(inPrAmt, priceDcm)
408+ let userPriceX18 = cpbi(inPrAssetAmtX18, inAmAssetAmtX18)
409+ let amBalanceX18 = t1(amBalance, amtDcm)
410+ let prBalanceX18 = t1(prBalance, priceDcm)
411+ let D0 = getD([amBalanceX18, prBalanceX18])
412+ let r = if ((lpEm == 0))
413+ then {
414+ let D1 = getD([(amBalanceX18 + inAmAssetAmtX18), (prBalanceX18 + inPrAssetAmtX18)])
415+ let checkD = if ((D1 > D0))
416+ then true
417+ else throw("D1 should be greater than D0")
418+ if ((checkD == checkD))
419+ then {
420+ let curPriceX18 = zeroBigInt
421+ let slippageX18 = zeroBigInt
422+ let lpAmtX18 = D1
423+ $Tuple5(f1(lpAmtX18, scale8), f1(inAmAssetAmtX18, amtDcm), f1(inPrAssetAmtX18, priceDcm), cpbi((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
424+ }
425+ else throw("Strict value is not equal to itself.")
426+ }
427+ else {
428+ let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
429+ let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
430+ let slippageX18 = t1(slippage, scale8)
431+ if (if (if (validateSlippage)
432+ then (curPriceX18 != zeroBigInt)
433+ else false)
434+ then (slippageRealX18 > slippageX18)
435+ else false)
436+ then throw(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
437+ else {
438+ let lpEmissionX18 = t1(lpEm, scale8)
439+ let prViaAmX18 = fraction(inAmAssetAmtX18, cpbir(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
440+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, cpbir(prBalanceX18, amBalanceX18, FLOOR), CEILING)
441+ let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
442+ then $Tuple2(amViaPrX18, inPrAssetAmtX18)
443+ else $Tuple2(inAmAssetAmtX18, prViaAmX18)
444+ let expAmtAssetAmtX18 = expectedAmts._1
445+ let expPriceAssetAmtX18 = expectedAmts._2
446+ let D1 = getD([(amBalanceX18 + expAmtAssetAmtX18), (prBalanceX18 + expPriceAssetAmtX18)])
447+ let checkD = if ((D1 > D0))
448+ then true
449+ else throw("D1 should be greater than D0")
450+ if ((checkD == checkD))
451+ then {
452+ let lpAmtX18 = fraction(lpEmissionX18, (D1 - D0), D0)
453+ $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceDcm, CEILING), curPriceX18, slippageX18)
454+ }
455+ else throw("Strict value is not equal to itself.")
456+ }
457+ }
458+ let calcLpAmt = r._1
459+ let calcAmAssetPmt = r._2
460+ let calcPrAssetPmt = r._3
461+ let curPrice = f1(r._4, scale8)
462+ let slippageCalc = f1(r._5, scale8)
463+ if ((0 >= calcLpAmt))
464+ then throw("LP <= 0")
465+ else {
466+ let emitLpAmt = if (!(emitLp))
467+ then 0
468+ else calcLpAmt
469+ let amDiff = (inAmAmt - calcAmAssetPmt)
470+ let prDiff = (inPrAmt - calcPrAssetPmt)
471+ let $t02058820933 = if (if (isOneAsset)
472+ then (pmtId == amIdStr)
473+ else false)
474+ then $Tuple2(pmtAmt, 0)
475+ else if (if (isOneAsset)
476+ then (pmtId == prIdStr)
477+ else false)
478+ then $Tuple2(0, pmtAmt)
479+ else $Tuple2(calcAmAssetPmt, calcPrAssetPmt)
480+ let writeAmAmt = $t02058820933._1
481+ let writePrAmt = $t02058820933._2
482+ let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(writeAmAmt, writePrAmt, emitLpAmt, curPrice, slippage, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
483+ $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEm, lpId, sts, commonState, amDiff, prDiff, inAmId, inPrId)
484+ }
485+ }
486+
487+
488+func getYD (xp,i,D) = {
489+ let n = big2
490+ let x = xp[if ((i == 0))
491+ then 1
492+ else 0]
493+ let aPrecision = parseBigIntValue(Amult)
494+ let a = (parseBigIntValue(A) * aPrecision)
495+ let s = x
496+ let ann = (a * n)
497+ let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
498+ let b = ((s + ((D * aPrecision) / ann)) - D)
499+ func calc (acc,cur) = {
500+ let $t02212822148 = acc
501+ let y = $t02212822148._1
502+ let found = $t02212822148._2
503+ if ((found != unit))
504+ then acc
505+ else {
506+ let yNext = (((y * y) + c) / ((big2 * y) + b))
507+ let yDiff = absBigInt((yNext - value(y)))
508+ if ((big1 >= yDiff))
509+ then $Tuple2(yNext, cur)
510+ else $Tuple2(yNext, unit)
511+ }
512+ }
513+
514+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
515+ let $t02245522502 = {
516+ let $l = arr
517+ let $s = size($l)
518+ let $acc0 = $Tuple2(D, unit)
519+ func $f0_1 ($a,$i) = if (($i >= $s))
520+ then $a
521+ else calc($a, $l[$i])
522+
523+ func $f0_2 ($a,$i) = if (($i >= $s))
524+ then $a
525+ else throw("List size exceeds 15")
526+
527+ $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($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
528+ }
529+ let y = $t02245522502._1
530+ let found = $t02245522502._2
531+ if ((found != unit))
532+ then y
533+ else throw(("Y calculation error, Y = " + toString(y)))
534+ }
535+
536+
537+func calcDLp (amountBalance,priceBalance,lpEmission) = {
538+ let updatedDLp = fraction(getD([t1BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals)), t1BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))]), scale18, lpEmission)
539+ if ((lpEmission == big0))
540+ then big0
541+ else updatedDLp
542+ }
543+
544+
545+func calcCurrentDLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
546+ let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
547+ let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
548+ let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
549+ let currentDLp = calcDLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
550+ currentDLp
551+ }
552+
553+
554+func refreshDLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
555+ let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
556+ let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
557+ let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
558+ let updatedDLp = calcDLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
559+ let actions = [IntegerEntry(keyDLpRefreshedHeight, height), StringEntry(keyDLp, toString(updatedDLp))]
560+ $Tuple2(actions, updatedDLp)
561+ }
562+
563+
564+func validateUpdatedDLp (oldDLp,updatedDLp) = if ((updatedDLp >= oldDLp))
565+ then true
566+ else throwErr("updated DLp lower than current DLp")
567+
568+
569+func validateMatcherOrderAllowed (order) = {
570+ let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
571+ let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
572+ let amountAssetAmount = order.amount
573+ let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
574+ let $t02470024912 = if ((order.orderType == Buy))
575+ then $Tuple2(amountAssetAmount, -(priceAssetAmount))
576+ else $Tuple2(-(amountAssetAmount), priceAssetAmount)
577+ let amountAssetBalanceDelta = $t02470024912._1
578+ let priceAssetBalanceDelta = $t02470024912._2
579+ if (if (if (igs())
580+ then true
581+ else (cfgPoolStatus == PoolMatcherDis))
582+ then true
583+ else (cfgPoolStatus == PoolShutdown))
584+ then throw("Admin blocked")
585+ else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
586+ then true
587+ else (order.assetPair.priceAsset != cfgPriceAssetId))
588+ then throw("Wr assets")
589+ else {
590+ let dLp = parseBigIntValue(valueOrElse(getString(this, keyDLp), "0"))
591+ let $t02525425354 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
592+ let unusedActions = $t02525425354._1
593+ let dLpNew = $t02525425354._2
594+ let isOrderValid = (dLpNew >= dLp)
595+ let info = makeString(["dLp=", toString(dLp), " dLpNew=", toString(dLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
596+ $Tuple2(isOrderValid, info)
597+ }
598+ }
599+
600+
601+func cg (i) = if ((size(i.payments) != 1))
602+ then throw("1 pmnt exp")
603+ else {
604+ let pmt = value(i.payments[0])
605+ let pmtAssetId = value(pmt.assetId)
606+ let pmtAmt = pmt.amount
607+ let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
608+ let outAmAmt = r._1
609+ let outPrAmt = r._2
610+ let sts = parseIntValue(r._9)
611+ let state = r._10
612+ if (if (igs())
613+ then true
614+ else (sts == PoolShutdown))
615+ then throw(("Admin blocked: " + toString(sts)))
616+ else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
617+ }
618+
619+
620+func cp (caller,txId,amAsPmt,prAsPmt,slippage,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
621+ let r = epo(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, (txId == ""), emitLp, isOneAsset, validateSlippage, pmtAmt, pmtId)
622+ let sts = parseIntValue(r._8)
623+ if (if (if (igs())
624+ then true
625+ else (sts == PoolPutDis))
626+ then true
627+ else (sts == PoolShutdown))
628+ then throw(("Blocked:" + toString(sts)))
629+ else r
630+ }
631+
632+
633+func calcPutOneTkn (pmtAmtRaw,pmtAssetId,userAddress,txId,withTakeFee) = {
634+ let amId = toBase58String(value(cfgAmountAssetId))
635+ let prId = toBase58String(value(cfgPriceAssetId))
636+ let lpId = cfgLpAssetId
637+ let amtDcm = cfgAmountAssetDecimals
638+ let priceDcm = cfgPriceAssetDecimals
639+ let lpAssetEmission = toBigInt(valueOrErrorMessage(assetInfo(lpId), "invalid lp asset").quantity)
640+ let chechEmission = if ((lpAssetEmission > big0))
641+ then true
642+ else throw("initial deposit requires all coins")
643+ if ((chechEmission == chechEmission))
644+ then {
645+ let amBalance = getAccBalance(amId)
646+ let prBalance = getAccBalance(prId)
647+ let $t02801028472 = if ((txId == ""))
648+ then $Tuple2(amBalance, prBalance)
649+ else if ((pmtAssetId == amId))
650+ then if ((pmtAmtRaw > amBalance))
651+ then throw("invalid payment amount")
652+ else $Tuple2((amBalance - pmtAmtRaw), prBalance)
653+ else if ((pmtAssetId == prId))
654+ then if ((pmtAmtRaw > prBalance))
655+ then throw("invalid payment amount")
656+ else $Tuple2(amBalance, (prBalance - pmtAmtRaw))
657+ else throw("wrong pmtAssetId")
658+ let amBalanceOld = $t02801028472._1
659+ let prBalanceOld = $t02801028472._2
660+ let $t02847828654 = if ((pmtAssetId == amId))
661+ then $Tuple2(pmtAmtRaw, 0)
662+ else if ((pmtAssetId == prId))
663+ then $Tuple2(0, pmtAmtRaw)
664+ else throw("invalid payment")
665+ let amAmountRaw = $t02847828654._1
666+ let prAmountRaw = $t02847828654._2
667+ let $t02865828912 = if (withTakeFee)
668+ then $Tuple3(takeFee(amAmountRaw, inFee)._1, takeFee(prAmountRaw, inFee)._1, takeFee(pmtAmtRaw, inFee)._2)
669+ else $Tuple3(amAmountRaw, prAmountRaw, 0)
670+ let amAmount = $t02865828912._1
671+ let prAmount = $t02865828912._2
672+ let feeAmount = $t02865828912._3
673+ let amBalanceNew = (amBalanceOld + amAmount)
674+ let prBalanceNew = (prBalanceOld + prAmount)
675+ let D0 = getD([t1(amBalanceOld, cfgAmountAssetDecimals), t1(prBalanceOld, cfgPriceAssetDecimals)])
676+ let D1 = getD([t1(amBalanceNew, cfgAmountAssetDecimals), t1(prBalanceNew, cfgPriceAssetDecimals)])
677+ let checkD = if ((D1 > D0))
678+ then true
679+ else throw()
680+ if ((checkD == checkD))
681+ then {
682+ let lpAmount = fraction(lpAssetEmission, (D1 - D0), D0, FLOOR)
683+ let curPrice = f1(cpbi(t1(prBalanceNew, priceDcm), t1(amBalanceNew, amtDcm)), scale8)
684+ let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId), dataPutActionInfo(amAmountRaw, prAmountRaw, toInt(lpAmount), curPrice, 0, 0, height, lastBlock.timestamp, 0, 0))]
685+ let poolProportion = fraction(prBalanceOld, scale8, amBalanceOld)
686+ let amountAssetPart = fraction(pmtAmtRaw, scale8, (poolProportion + scale8))
687+ let priceAssetPart = (pmtAmtRaw - amountAssetPart)
688+ let lpAmtBoth = fraction(lpAssetEmission, toBigInt(priceAssetPart), toBigInt(prBalanceOld))
689+ let bonus = toInt(fraction((lpAmount - lpAmtBoth), scale8BigInt, lpAmtBoth))
690+ $Tuple4(toInt(lpAmount), commonState, feeAmount, bonus)
691+ }
692+ else throw("Strict value is not equal to itself.")
693+ }
694+ else throw("Strict value is not equal to itself.")
695+ }
696+
697+
698+func getOneTknV2Internal (outAssetId,minOutAmount,payments,caller,originCaller,transactionId) = {
699+ let lpId = toBase58String(value(cfgLpAssetId))
700+ let amId = toBase58String(value(cfgAmountAssetId))
701+ let prId = toBase58String(value(cfgPriceAssetId))
702+ let amDecimals = cfgAmountAssetDecimals
703+ let prDecimals = cfgPriceAssetDecimals
704+ let poolStatus = cfgPoolStatus
705+ let userAddress = if ((caller == restContract))
706+ then originCaller
707+ else caller
708+ let pmt = value(payments[0])
709+ let pmtAssetId = value(pmt.assetId)
710+ let pmtAmt = pmt.amount
711+ let currentDLp = calcCurrentDLp(big0, big0, big0)
712+ if ((currentDLp == currentDLp))
713+ then {
714+ let txId58 = toBase58String(transactionId)
715+ if ((lpId != toBase58String(pmtAssetId)))
716+ then throw("Wrong LP")
717+ else {
718+ let amBalance = getAccBalance(amId)
719+ let prBalance = getAccBalance(prId)
720+ let $t03102431135 = {
721+ let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, pmtAmt], nil)
722+ if ($isInstanceOf(@, "(Int, Int)"))
723+ then @
724+ else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
725+ }
726+ if (($t03102431135 == $t03102431135))
727+ then {
728+ let feeAmount = $t03102431135._2
729+ let totalGet = $t03102431135._1
730+ let totalAmount = if (if ((minOutAmount > 0))
731+ then (minOutAmount > totalGet)
732+ else false)
733+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
734+ else totalGet
735+ let $t03132531632 = if ((outAssetId == amId))
736+ then $Tuple4(totalAmount, 0, ((amBalance - totalAmount) - feeAmount), prBalance)
737+ else if ((outAssetId == prId))
738+ then $Tuple4(0, totalAmount, amBalance, ((prBalance - totalAmount) - feeAmount))
739+ else throw("invalid out asset id")
740+ let outAm = $t03132531632._1
741+ let outPr = $t03132531632._2
742+ let amBalanceNew = $t03132531632._3
743+ let prBalanceNew = $t03132531632._4
744+ let curPrX18 = cpbi(t1(prBalanceNew, prDecimals), t1(amBalanceNew, amDecimals))
745+ let curPr = f1(curPrX18, scale8)
746+ let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
747+ then unit
748+ else fromBase58String(outAssetId)
749+ let sendFeeToMatcher = if ((feeAmount > 0))
750+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetIdOrWaves)]
751+ else nil
752+ let state = ([ScriptTransfer(userAddress, totalAmount, outAssetIdOrWaves), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)] ++ sendFeeToMatcher)
753+ if ((state == state))
754+ then {
755+ let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
756+ if ((burn == burn))
757+ then {
758+ let $t03241732767 = {
759+ let feeAmountForCalc = if ((this == feeCollectorAddress))
760+ then 0
761+ else feeAmount
762+ let outInAmountAsset = if ((parseAssetId(outAssetId) == cfgAmountAssetId))
763+ then true
764+ else false
765+ if (outInAmountAsset)
766+ then $Tuple2(-((totalGet + feeAmountForCalc)), 0)
767+ else $Tuple2(0, -((totalGet + feeAmountForCalc)))
768+ }
769+ let amountAssetBalanceDelta = $t03241732767._1
770+ let priceAssetBalanceDelta = $t03241732767._2
771+ let $t03277032878 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
772+ let refreshDLpActions = $t03277032878._1
773+ let updatedDLp = $t03277032878._2
774+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
775+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
776+ then $Tuple2((state ++ refreshDLpActions), totalAmount)
777+ else throw("Strict value is not equal to itself.")
778+ }
779+ else throw("Strict value is not equal to itself.")
780+ }
781+ else throw("Strict value is not equal to itself.")
782+ }
783+ else throw("Strict value is not equal to itself.")
784+ }
785+ }
786+ else throw("Strict value is not equal to itself.")
787+ }
788+
789+
790+func m () = match getString(mpk()) {
791+ case s: String =>
792+ fromBase58String(s)
793+ case _: Unit =>
794+ unit
795+ case _ =>
796+ throw("Match error")
797+}
798+
799+
800+func pm () = match getString(pmpk()) {
801+ case s: String =>
802+ fromBase58String(s)
803+ case _: Unit =>
804+ unit
805+ case _ =>
806+ throw("Match error")
807+}
808+
809+
810+let pd = throw("Permission denied")
811+
812+func isManager (i) = match m() {
813+ case pk: ByteVector =>
814+ (i.callerPublicKey == pk)
815+ case _: Unit =>
816+ (i.caller == this)
817+ case _ =>
818+ throw("Match error")
819+}
820+
821+
822+func mm (i) = match m() {
823+ case pk: ByteVector =>
824+ if ((i.callerPublicKey == pk))
825+ then true
826+ else pd
827+ case _: Unit =>
828+ if ((i.caller == this))
829+ then true
830+ else pd
831+ case _ =>
832+ throw("Match error")
833+}
834+
835+
836+func getY (isReverse,D,poolAmountInBalance) = {
837+ let poolConfig = gpc()
838+ let amId = poolConfig[idxAmAsId]
839+ let prId = poolConfig[idxPrAsId]
840+ let n = big2
841+ let aPrecision = parseBigIntValue(Amult)
842+ let a = (parseBigIntValue(A) * aPrecision)
843+ let xp = if ((isReverse == false))
844+ then [(toBigInt(getAccBalance(amId)) + poolAmountInBalance), toBigInt(getAccBalance(prId))]
845+ else [(toBigInt(getAccBalance(prId)) + poolAmountInBalance), toBigInt(getAccBalance(amId))]
846+ let x = xp[0]
847+ let s = x
848+ let ann = (a * n)
849+ let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
850+ let b = ((s + ((D * aPrecision) / ann)) - D)
851+ func calc (acc,cur) = {
852+ let $t03432534345 = acc
853+ let y = $t03432534345._1
854+ let found = $t03432534345._2
855+ if ((found != unit))
856+ then acc
857+ else {
858+ let yNext = (((y * y) + c) / ((big2 * y) + b))
859+ let yDiff = absBigInt((yNext - value(y)))
860+ if ((big1 >= yDiff))
861+ then $Tuple2(yNext, cur)
862+ else $Tuple2(yNext, unit)
863+ }
864+ }
865+
866+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
867+ let $t03467634723 = {
868+ let $l = arr
869+ let $s = size($l)
870+ let $acc0 = $Tuple2(D, unit)
871+ func $f0_1 ($a,$i) = if (($i >= $s))
872+ then $a
873+ else calc($a, $l[$i])
874+
875+ func $f0_2 ($a,$i) = if (($i >= $s))
876+ then $a
877+ else throw("List size exceeds 15")
878+
879+ $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($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
880+ }
881+ let y = $t03467634723._1
882+ let found = $t03467634723._2
883+ if ((found != unit))
884+ then y
885+ else throw(("Y calculation error, Y = " + toString(y)))
886+ }
887+
888+
889+func skipOrderValidation () = valueOrElse(getBoolean(fca, keySkipOrderValidation(toString(this))), false)
890+
891+
892+@Callable(i)
893+func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
894+ let $t03507535499 = if ((isReverse == false))
895+ then {
896+ let assetOut = strf(this, pa())
897+ let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, aa()))) + toBigInt(cleanAmountIn))
898+ $Tuple2(assetOut, poolAmountInBalance)
899+ }
900+ else {
901+ let assetOut = strf(this, aa())
902+ let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, pa()))) + toBigInt(cleanAmountIn))
903+ $Tuple2(assetOut, poolAmountInBalance)
904+ }
905+ let assetOut = $t03507535499._1
906+ let poolAmountInBalance = $t03507535499._2
907+ let poolConfig = gpc()
908+ let amId = poolConfig[idxAmAsId]
909+ let prId = poolConfig[idxPrAsId]
910+ let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
911+ let D = getD(xp)
912+ let y = getY(isReverse, D, toBigInt(cleanAmountIn))
913+ let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
914+ let totalGetRaw = max([0, toInt(dy)])
915+ let newXp = if ((isReverse == false))
916+ then [((toBigInt(getAccBalance(amId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
917+ else [(toBigInt(getAccBalance(amId)) - dy), ((toBigInt(getAccBalance(prId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount))]
918+ let newD = getD(newXp)
919+ let checkD = if ((newD >= D))
920+ then true
921+ else throw(makeString(["new D is fewer error", toString(D), toString(newD)], "__"))
922+ if ((checkD == checkD))
923+ then $Tuple2(nil, totalGetRaw)
924+ else throw("Strict value is not equal to itself.")
925+ }
926+
927+
928+
929+@Callable(i)
930+func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo,feePoolAmount) = {
931+ let swapContact = {
932+ let @ = invoke(fca, "getSwapContractREADONLY", nil, nil)
933+ if ($isInstanceOf(@, "String"))
934+ then @
935+ else throw(($getType(@) + " couldn't be cast to String"))
936+ }
937+ let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
938+ then true
939+ else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
940+ then true
941+ else throwErr("Permission denied")]
942+ if ((checks == checks))
943+ then {
944+ let pmt = value(i.payments[0])
945+ let assetIn = assetIdToString(pmt.assetId)
946+ let $t03693537329 = if ((isReverse == false))
947+ then {
948+ let assetOut = strf(this, pa())
949+ let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
950+ $Tuple2(assetOut, poolAmountInBalance)
951+ }
952+ else {
953+ let assetOut = strf(this, aa())
954+ let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
955+ $Tuple2(assetOut, poolAmountInBalance)
956+ }
957+ let assetOut = $t03693537329._1
958+ let poolAmountInBalance = $t03693537329._2
959+ let poolConfig = gpc()
960+ let amId = poolConfig[idxAmAsId]
961+ let prId = poolConfig[idxPrAsId]
962+ let xp = if ((isReverse == false))
963+ then [(toBigInt(getAccBalance(amId)) - toBigInt(value(i.payments[0]).amount)), toBigInt(getAccBalance(prId))]
964+ else [toBigInt(getAccBalance(amId)), (toBigInt(getAccBalance(prId)) - toBigInt(value(i.payments[0]).amount))]
965+ let D = getD(xp)
966+ let y = getY(isReverse, D, toBigInt(0))
967+ let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
968+ let totalGetRaw = max([0, toInt(dy)])
969+ let checkMin = if ((totalGetRaw >= amountOutMin))
970+ then true
971+ else throw("Exchange result is fewer coins than expected")
972+ if ((checkMin == checkMin))
973+ then {
974+ let newXp = if ((isReverse == false))
975+ then [(toBigInt(getAccBalance(amId)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
976+ else [(toBigInt(getAccBalance(amId)) - dy), (toBigInt(getAccBalance(prId)) + toBigInt(feePoolAmount))]
977+ let newD = getD(newXp)
978+ let checkD = if ((newD >= D))
979+ then true
980+ else throw("new D is fewer error")
981+ if ((checkD == checkD))
982+ then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), totalGetRaw, parseAssetId(assetOut))], totalGetRaw)
983+ else throw("Strict value is not equal to itself.")
984+ }
985+ else throw("Strict value is not equal to itself.")
986+ }
987+ else throw("Strict value is not equal to itself.")
988+ }
989+
990+
991+
992+@Callable(i)
993+func constructor (fc) = {
994+ let c = mm(i)
995+ if ((c == c))
996+ then [StringEntry(fc(), fc)]
997+ else throw("Strict value is not equal to itself.")
998+ }
999+
1000+
1001+
1002+@Callable(i)
1003+func setManager (pendingManagerPublicKey) = {
1004+ let c = mm(i)
1005+ if ((c == c))
1006+ then {
1007+ let cm = fromBase58String(pendingManagerPublicKey)
1008+ if ((cm == cm))
1009+ then [StringEntry(pmpk(), pendingManagerPublicKey)]
1010+ else throw("Strict value is not equal to itself.")
1011+ }
1012+ else throw("Strict value is not equal to itself.")
1013+ }
1014+
1015+
1016+
1017+@Callable(i)
1018+func confirmManager () = {
1019+ let p = pm()
1020+ let hpm = if (isDefined(p))
1021+ then true
1022+ else throw("No pending manager")
1023+ if ((hpm == hpm))
1024+ then {
1025+ let cpm = if ((i.callerPublicKey == value(p)))
1026+ then true
1027+ else throw("You are not pending manager")
1028+ if ((cpm == cpm))
1029+ then [StringEntry(mpk(), toBase58String(value(p))), DeleteEntry(pmpk())]
1030+ else throw("Strict value is not equal to itself.")
1031+ }
1032+ else throw("Strict value is not equal to itself.")
1033+ }
1034+
1035+
1036+
1037+@Callable(i)
1038+func put (slip,autoStake) = {
1039+ let factCfg = gfc()
1040+ let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Wr st addr")
1041+ let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Wr sl addr")
1042+ if ((0 > slip))
1043+ then throw("Wrong slippage")
1044+ else if ((size(i.payments) != 2))
1045+ then throw("2 pmnts expd")
1046+ else {
1047+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1048+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1049+ let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amAssetPmt)
1050+ if ((amountAssetBalance == amountAssetBalance))
1051+ then {
1052+ let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - prAssetPmt)
1053+ if ((priceAssetBalance == priceAssetBalance))
1054+ then {
1055+ let lpAssetEmission = toBigInt(value(assetInfo(cfgLpAssetId)).quantity)
1056+ if ((lpAssetEmission == lpAssetEmission))
1057+ then {
1058+ let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1059+ if ((currentDLp == currentDLp))
1060+ then {
1061+ let e = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slip, true, false, true, 0, "")
1062+ let emitLpAmt = e._2
1063+ let lpAssetId = e._7
1064+ let state = e._9
1065+ let amDiff = e._10
1066+ let prDiff = e._11
1067+ let amId = e._12
1068+ let prId = e._13
1069+ let r = invoke(fca, "emit", [emitLpAmt], nil)
1070+ if ((r == r))
1071+ then {
1072+ let el = match r {
1073+ case legacy: Address =>
1074+ invoke(legacy, "emit", [emitLpAmt], nil)
1075+ case _ =>
1076+ unit
1077+ }
1078+ if ((el == el))
1079+ then {
1080+ let sa = if ((amDiff > 0))
1081+ then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
1082+ else nil
1083+ if ((sa == sa))
1084+ then {
1085+ let sp = if ((prDiff > 0))
1086+ then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
1087+ else nil
1088+ if ((sp == sp))
1089+ then {
1090+ let lpTrnsfr = if (autoStake)
1091+ then {
1092+ let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1093+ if ((ss == ss))
1094+ then nil
1095+ else throw("Strict value is not equal to itself.")
1096+ }
1097+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1098+ let $t04194842090 = refreshDLpInternal(0, 0, 0)
1099+ let refreshDLpActions = $t04194842090._1
1100+ let updatedDLp = $t04194842090._2
1101+ let check = if ((updatedDLp >= currentDLp))
1102+ then true
1103+ else throwErr(makeString(["updated DLp lower than current DLp", toString(amountAssetBalance), toString(priceAssetBalance), toString(lpAssetEmission), toString(currentDLp), toString(updatedDLp), toString(amDiff), toString(prDiff)], " "))
1104+ if ((check == check))
1105+ then {
1106+ let lpAssetEmissionAfter = value(assetInfo(cfgLpAssetId)).quantity
1107+ if ((lpAssetEmissionAfter == lpAssetEmissionAfter))
1108+ then ((state ++ lpTrnsfr) ++ refreshDLpActions)
1109+ else throw("Strict value is not equal to itself.")
1110+ }
1111+ else throw("Strict value is not equal to itself.")
1112+ }
1113+ else throw("Strict value is not equal to itself.")
1114+ }
1115+ else throw("Strict value is not equal to itself.")
1116+ }
1117+ else throw("Strict value is not equal to itself.")
1118+ }
1119+ else throw("Strict value is not equal to itself.")
1120+ }
1121+ else throw("Strict value is not equal to itself.")
1122+ }
1123+ else throw("Strict value is not equal to itself.")
1124+ }
1125+ else throw("Strict value is not equal to itself.")
1126+ }
1127+ else throw("Strict value is not equal to itself.")
1128+ }
1129+ }
1130+
1131+
1132+
1133+@Callable(i)
1134+func putOneTknV2 (minOutAmount,autoStake) = {
1135+ let isPoolOneTokenOperationsDisabled = {
1136+ let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1137+ if ($isInstanceOf(@, "Boolean"))
1138+ then @
1139+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1140+ }
1141+ let isPutDisabled = if (if (if (igs())
1142+ then true
1143+ else (cfgPoolStatus == PoolPutDis))
1144+ then true
1145+ else (cfgPoolStatus == PoolShutdown))
1146+ then true
1147+ else isPoolOneTokenOperationsDisabled
1148+ let checks = [if (if (!(isPutDisabled))
1149+ then true
1150+ else isManager(i))
1151+ then true
1152+ else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
1153+ then true
1154+ else throwErr("exactly 1 payment are expected")]
1155+ if ((checks == checks))
1156+ then {
1157+ let amId = toBase58String(value(cfgAmountAssetId))
1158+ let prId = toBase58String(value(cfgPriceAssetId))
1159+ let lpId = cfgLpAssetId
1160+ let amDecimals = cfgAmountAssetDecimals
1161+ let prDecimals = cfgPriceAssetDecimals
1162+ let userAddress = if ((i.caller == this))
1163+ then i.originCaller
1164+ else i.caller
1165+ let pmt = value(i.payments[0])
1166+ let pmtAssetId = toBase58String(value(pmt.assetId))
1167+ let pmtAmt = pmt.amount
1168+ let currentDLp = if ((pmt.assetId == cfgAmountAssetId))
1169+ then calcCurrentDLp(toBigInt(pmtAmt), toBigInt(0), toBigInt(0))
1170+ else calcCurrentDLp(toBigInt(0), toBigInt(pmtAmt), toBigInt(0))
1171+ if ((currentDLp == currentDLp))
1172+ then {
1173+ let $t04373143889 = calcPutOneTkn(pmtAmt, pmtAssetId, toString(userAddress), toBase58String(i.transactionId), true)
1174+ if (($t04373143889 == $t04373143889))
1175+ then {
1176+ let feeAmount = $t04373143889._3
1177+ let state = $t04373143889._2
1178+ let estimLP = $t04373143889._1
1179+ let emitLpAmt = if (if ((minOutAmount > 0))
1180+ then (minOutAmount > estimLP)
1181+ else false)
1182+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1183+ else estimLP
1184+ let e = invoke(fca, "emit", [emitLpAmt], nil)
1185+ if ((e == e))
1186+ then {
1187+ let el = match e {
1188+ case legacy: Address =>
1189+ invoke(legacy, "emit", [emitLpAmt], nil)
1190+ case _ =>
1191+ unit
1192+ }
1193+ if ((el == el))
1194+ then {
1195+ let lpTrnsfr = if (autoStake)
1196+ then {
1197+ let ss = invoke(stakingContract, "stakeFor", [toString(i.caller)], [AttachedPayment(lpId, emitLpAmt)])
1198+ if ((ss == ss))
1199+ then nil
1200+ else throw("Strict value is not equal to itself.")
1201+ }
1202+ else [ScriptTransfer(i.caller, emitLpAmt, lpId)]
1203+ let sendFeeToMatcher = if ((feeAmount > 0))
1204+ then [ScriptTransfer(feeCollectorAddress, feeAmount, fromBase58String(pmtAssetId))]
1205+ else nil
1206+ let $t04477445123 = if ((this == feeCollectorAddress))
1207+ then $Tuple2(0, 0)
1208+ else {
1209+ let paymentInAmountAsset = if ((pmt.assetId == cfgAmountAssetId))
1210+ then true
1211+ else false
1212+ if (paymentInAmountAsset)
1213+ then $Tuple2(-(feeAmount), 0)
1214+ else $Tuple2(0, -(feeAmount))
1215+ }
1216+ let amountAssetBalanceDelta = $t04477445123._1
1217+ let priceAssetBalanceDelta = $t04477445123._2
1218+ let $t04512645234 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1219+ let refreshDLpActions = $t04512645234._1
1220+ let updatedDLp = $t04512645234._2
1221+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1222+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1223+ then $Tuple2((((state ++ lpTrnsfr) ++ sendFeeToMatcher) ++ refreshDLpActions), emitLpAmt)
1224+ else throw("Strict value is not equal to itself.")
1225+ }
1226+ else throw("Strict value is not equal to itself.")
1227+ }
1228+ else throw("Strict value is not equal to itself.")
1229+ }
1230+ else throw("Strict value is not equal to itself.")
1231+ }
1232+ else throw("Strict value is not equal to itself.")
1233+ }
1234+ else throw("Strict value is not equal to itself.")
1235+ }
1236+
1237+
1238+
1239+@Callable(i)
1240+func putForFree (maxSlpg) = if ((0 > maxSlpg))
1241+ then throw("Wrong slpg")
1242+ else if ((size(i.payments) != 2))
1243+ then throw("2 pmnts expd")
1244+ else {
1245+ let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxSlpg, false, false, true, 0, "")
1246+ let state = estPut._9
1247+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1248+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1249+ let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1250+ if ((currentDLp == currentDLp))
1251+ then {
1252+ let $t04626446329 = refreshDLpInternal(0, 0, 0)
1253+ let refreshDLpActions = $t04626446329._1
1254+ let updatedDLp = $t04626446329._2
1255+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1256+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1257+ then (state ++ refreshDLpActions)
1258+ else throw("Strict value is not equal to itself.")
1259+ }
1260+ else throw("Strict value is not equal to itself.")
1261+ }
1262+
1263+
1264+
1265+@Callable(i)
1266+func get () = {
1267+ let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1268+ if ((currentDLp == currentDLp))
1269+ then {
1270+ let r = cg(i)
1271+ let outAmtAmt = r._1
1272+ let outPrAmt = r._2
1273+ let pmtAmt = r._3
1274+ let pmtAssetId = r._4
1275+ let state = r._5
1276+ let b = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1277+ if ((b == b))
1278+ then {
1279+ let $t04750247584 = refreshDLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1280+ let refreshDLpActions = $t04750247584._1
1281+ let updatedDLp = $t04750247584._2
1282+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1283+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1284+ then (state ++ refreshDLpActions)
1285+ else throw("Strict value is not equal to itself.")
1286+ }
1287+ else throw("Strict value is not equal to itself.")
1288+ }
1289+ else throw("Strict value is not equal to itself.")
1290+ }
1291+
1292+
1293+
1294+@Callable(i)
1295+func getOneTknV2 (outAssetId,minOutAmount) = {
1296+ let isPoolOneTokenOperationsDisabled = {
1297+ let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1298+ if ($isInstanceOf(@, "Boolean"))
1299+ then @
1300+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1301+ }
1302+ let isGetDisabled = if (if (igs())
1303+ then true
1304+ else (cfgPoolStatus == PoolShutdown))
1305+ then true
1306+ else isPoolOneTokenOperationsDisabled
1307+ let checks = [if (if (!(isGetDisabled))
1308+ then true
1309+ else isManager(i))
1310+ then true
1311+ else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
1312+ then true
1313+ else throwErr("exactly 1 payment are expected")]
1314+ if ((checks == checks))
1315+ then {
1316+ let $t04820248357 = getOneTknV2Internal(outAssetId, minOutAmount, i.payments, i.caller, i.originCaller, i.transactionId)
1317+ let state = $t04820248357._1
1318+ let totalAmount = $t04820248357._2
1319+ $Tuple2(state, totalAmount)
1320+ }
1321+ else throw("Strict value is not equal to itself.")
1322+ }
1323+
1324+
1325+
1326+@Callable(i)
1327+func refreshDLp () = {
1328+ let lastRefreshedBlockHeight = valueOrElse(getInteger(keyDLpRefreshedHeight), 0)
1329+ let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= dLpRefreshDelay))
1330+ then unit
1331+ else throwErr(makeString([toString(dLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1332+ if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1333+ then {
1334+ let dLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyDLp), "0")), fmtErr("invalid dLp"))
1335+ let $t04888148945 = refreshDLpInternal(0, 0, 0)
1336+ let dLpUpdateActions = $t04888148945._1
1337+ let updatedDLp = $t04888148945._2
1338+ let actions = if ((dLp != updatedDLp))
1339+ then dLpUpdateActions
1340+ else throwErr("nothing to refresh")
1341+ $Tuple2(actions, toString(updatedDLp))
1342+ }
1343+ else throw("Strict value is not equal to itself.")
1344+ }
1345+
1346+
1347+
1348+@Callable(i)
1349+func getOneTknV2READONLY (outAssetId,lpAssetAmount) = {
1350+ let amId = toBase58String(value(cfgAmountAssetId))
1351+ let prId = toBase58String(value(cfgPriceAssetId))
1352+ let lpId = toBase58String(value(cfgLpAssetId))
1353+ let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
1354+ let lpEmission = toBigInt(valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "invalid lp asset").quantity)
1355+ let D0 = getD(xp)
1356+ let D1 = (D0 - fraction(toBigInt(lpAssetAmount), D0, lpEmission))
1357+ let index = if ((outAssetId == amId))
1358+ then 0
1359+ else if ((outAssetId == prId))
1360+ then 1
1361+ else throw("invalid out asset id")
1362+ let newY = getYD(xp, index, D1)
1363+ let dy = (xp[index] - newY)
1364+ let totalGetRaw = max([0, toInt((dy - big1))])
1365+ let $t04995550010 = takeFee(totalGetRaw, outFee)
1366+ let totalGet = $t04995550010._1
1367+ let feeAmount = $t04995550010._2
1368+ $Tuple2(nil, $Tuple2(totalGet, feeAmount))
1369+ }
1370+
1371+
1372+
1373+@Callable(i)
1374+func getOneTknV2WithBonusREADONLY (outAssetId,lpAssetAmount) = {
1375+ let amId = toBase58String(value(cfgAmountAssetId))
1376+ let prId = toBase58String(value(cfgPriceAssetId))
1377+ let lpId = toBase58String(value(cfgLpAssetId))
1378+ let amBalance = getAccBalance(amId)
1379+ let prBalance = getAccBalance(prId)
1380+ let $t05038550500 = {
1381+ let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, lpAssetAmount], nil)
1382+ if ($isInstanceOf(@, "(Int, Int)"))
1383+ then @
1384+ else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
1385+ }
1386+ let totalGet = $t05038550500._1
1387+ let feeAmount = $t05038550500._2
1388+ let r = ego("", lpId, lpAssetAmount, this)
1389+ let outAmAmt = r._1
1390+ let outPrAmt = r._2
1391+ let sumOfGetAssets = (outAmAmt + outPrAmt)
1392+ let bonus = if ((sumOfGetAssets == 0))
1393+ then if ((totalGet == 0))
1394+ then 0
1395+ else throw("bonus calculation error")
1396+ else fraction((totalGet - sumOfGetAssets), scale8, sumOfGetAssets)
1397+ $Tuple2(nil, $Tuple3(totalGet, feeAmount, bonus))
1398+ }
1399+
1400+
1401+
1402+@Callable(i)
1403+func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
1404+ let r = cg(i)
1405+ let outAmAmt = r._1
1406+ let outPrAmt = r._2
1407+ let pmtAmt = r._3
1408+ let pmtAssetId = r._4
1409+ let state = r._5
1410+ if ((noLessThenAmtAsset > outAmAmt))
1411+ then throw(((("Failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
1412+ else if ((noLessThenPriceAsset > outPrAmt))
1413+ then throw(((("Failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
1414+ else {
1415+ let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1416+ if ((currentDLp == currentDLp))
1417+ then {
1418+ let burnLPAssetOnFactory = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1419+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1420+ then {
1421+ let $t05166651747 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1422+ let refreshDLpActions = $t05166651747._1
1423+ let updatedDLp = $t05166651747._2
1424+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1425+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1426+ then (state ++ refreshDLpActions)
1427+ else throw("Strict value is not equal to itself.")
1428+ }
1429+ else throw("Strict value is not equal to itself.")
1430+ }
1431+ else throw("Strict value is not equal to itself.")
1432+ }
1433+ }
1434+
1435+
1436+
1437+@Callable(i)
1438+func unstakeAndGet (amount) = {
1439+ let checkPayments = if ((size(i.payments) != 0))
1440+ then throw("No pmnts expd")
1441+ else true
1442+ if ((checkPayments == checkPayments))
1443+ then {
1444+ let factoryCfg = gfc()
1445+ let lpAssetId = cfgLpAssetId
1446+ let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1447+ let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1448+ if ((currentDLp == currentDLp))
1449+ then {
1450+ let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), amount], nil)
1451+ if ((unstakeInv == unstakeInv))
1452+ then {
1453+ let r = ego(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1454+ let outAmAmt = r._1
1455+ let outPrAmt = r._2
1456+ let sts = parseIntValue(r._9)
1457+ let state = r._10
1458+ let v = if (if (igs())
1459+ then true
1460+ else (sts == PoolShutdown))
1461+ then throw(("Blocked: " + toString(sts)))
1462+ else true
1463+ if ((v == v))
1464+ then {
1465+ let burnA = invoke(fca, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1466+ if ((burnA == burnA))
1467+ then {
1468+ let $t05277452855 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1469+ let refreshDLpActions = $t05277452855._1
1470+ let updatedDLp = $t05277452855._2
1471+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1472+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1473+ then (state ++ refreshDLpActions)
1474+ else throw("Strict value is not equal to itself.")
1475+ }
1476+ else throw("Strict value is not equal to itself.")
1477+ }
1478+ else throw("Strict value is not equal to itself.")
1479+ }
1480+ else throw("Strict value is not equal to itself.")
1481+ }
1482+ else throw("Strict value is not equal to itself.")
1483+ }
1484+ else throw("Strict value is not equal to itself.")
1485+ }
1486+
1487+
1488+
1489+@Callable(i)
1490+func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
1491+ let isGetDisabled = if (igs())
1492+ then true
1493+ else (cfgPoolStatus == PoolShutdown)
1494+ let checks = [if (!(isGetDisabled))
1495+ then true
1496+ else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
1497+ then true
1498+ else throw("no payments are expected")]
1499+ if ((checks == checks))
1500+ then {
1501+ let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1502+ if ((currentDLp == currentDLp))
1503+ then {
1504+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1505+ if ((unstakeInv == unstakeInv))
1506+ then {
1507+ let res = ego(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1508+ let outAmAmt = res._1
1509+ let outPrAmt = res._2
1510+ let state = res._10
1511+ let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
1512+ then true
1513+ else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
1514+ then true
1515+ else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
1516+ if ((checkAmounts == checkAmounts))
1517+ then {
1518+ let burnLPAssetOnFactory = invoke(fca, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1519+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1520+ then {
1521+ let $t05410654187 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1522+ let refreshDLpActions = $t05410654187._1
1523+ let updatedDLp = $t05410654187._2
1524+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1525+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1526+ then (state ++ refreshDLpActions)
1527+ else throw("Strict value is not equal to itself.")
1528+ }
1529+ else throw("Strict value is not equal to itself.")
1530+ }
1531+ else throw("Strict value is not equal to itself.")
1532+ }
1533+ else throw("Strict value is not equal to itself.")
1534+ }
1535+ else throw("Strict value is not equal to itself.")
1536+ }
1537+ else throw("Strict value is not equal to itself.")
1538+ }
1539+
1540+
1541+
1542+@Callable(i)
1543+func unstakeAndGetOneTknV2 (unstakeAmount,outAssetId,minOutAmount) = {
1544+ let isPoolOneTokenOperationsDisabled = {
1545+ let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1546+ if ($isInstanceOf(@, "Boolean"))
1547+ then @
1548+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1549+ }
1550+ let isGetDisabled = if (if (igs())
1551+ then true
1552+ else (cfgPoolStatus == PoolShutdown))
1553+ then true
1554+ else isPoolOneTokenOperationsDisabled
1555+ let checks = [if (if (!(isGetDisabled))
1556+ then true
1557+ else isManager(i))
1558+ then true
1559+ else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1560+ then true
1561+ else throwErr("no payments are expected")]
1562+ if ((checks == checks))
1563+ then {
1564+ let factoryCfg = gfc()
1565+ let lpAssetId = cfgLpAssetId
1566+ let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1567+ let userAddress = i.caller
1568+ let lpAssetRecipientAddress = this
1569+ let unstakeInv = invoke(staking, "unstakeINTERNAL", [lpAssetId, unstakeAmount, userAddress.bytes, lpAssetRecipientAddress.bytes], nil)
1570+ if ((unstakeInv == unstakeInv))
1571+ then {
1572+ let $t05520955397 = getOneTknV2Internal(outAssetId, minOutAmount, [AttachedPayment(lpAssetId, unstakeAmount)], i.caller, i.originCaller, i.transactionId)
1573+ let state = $t05520955397._1
1574+ let totalAmount = $t05520955397._2
1575+ $Tuple2(state, totalAmount)
1576+ }
1577+ else throw("Strict value is not equal to itself.")
1578+ }
1579+ else throw("Strict value is not equal to itself.")
1580+ }
1581+
1582+
1583+
1584+@Callable(i)
1585+func putOneTknV2WithBonusREADONLY (paymentAmountRaw,paymentAssetId) = {
1586+ let $t05552555628 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", true)
1587+ let lpAmount = $t05552555628._1
1588+ let state = $t05552555628._2
1589+ let feeAmount = $t05552555628._3
1590+ let bonus = $t05552555628._4
1591+ $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1592+ }
1593+
1594+
1595+
1596+@Callable(i)
1597+func putOneTknV2WithoutTakeFeeREADONLY (paymentAmountRaw,paymentAssetId) = {
1598+ let $t05577655880 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", false)
1599+ let lpAmount = $t05577655880._1
1600+ let state = $t05577655880._2
1601+ let feeAmount = $t05577655880._3
1602+ let bonus = $t05577655880._4
1603+ $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1604+ }
1605+
1606+
1607+
1608+@Callable(i)
1609+func activate (amtAsStr,prAsStr) = if ((toString(i.caller) != toString(fca)))
1610+ then throw("denied")
1611+ else $Tuple2([StringEntry(aa(), amtAsStr), StringEntry(pa(), prAsStr), StringEntry(amp(), toString(ampInitial))], "success")
1612+
1613+
1614+
1615+@Callable(i)
1616+func getPoolConfigWrapperREADONLY () = $Tuple2(nil, gpc())
1617+
1618+
1619+
1620+@Callable(i)
1621+func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
1622+
1623+
1624+
1625+@Callable(i)
1626+func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
1627+ let pr = calcPrices(amAmt, prAmt, lpAmt)
1628+ $Tuple2(nil, [toString(pr[0]), toString(pr[1]), toString(pr[2])])
1629+ }
1630+
1631+
1632+
1633+@Callable(i)
1634+func fromX18WrapperREADONLY (val,resScaleMult) = $Tuple2(nil, f1(parseBigIntValue(val), resScaleMult))
1635+
1636+
1637+
1638+@Callable(i)
1639+func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(t1(origVal, origScaleMult)))
1640+
1641+
1642+
1643+@Callable(i)
1644+func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(cpbi(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
1645+
1646+
1647+
1648+@Callable(i)
1649+func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,usrAddr,isEval,emitLp) = $Tuple2(nil, epo(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, usrAddr, isEval, emitLp, true, false, 0, ""))
1650+
1651+
1652+
1653+@Callable(i)
1654+func estimateGetOperationWrapperREADONLY (txId58,pmtAsId,pmtLpAmt,usrAddr) = {
1655+ let r = ego(txId58, pmtAsId, pmtLpAmt, addressFromStringValue(usrAddr))
1656+ $Tuple2(nil, $Tuple10(r._1, r._2, r._3, r._4, r._5, r._6, r._7, toString(r._8), r._9, r._10))
1657+ }
1658+
1659+
1660+
1661+@Callable(i)
1662+func changeAmp () = {
1663+ let cfg = invoke(fca, "getChangeAmpConfigREADONLY", [toString(this)], nil)
1664+ let $t05828958488 = match cfg {
1665+ case list: List[Any] =>
1666+ $Tuple3({
1667+ let @ = list[0]
1668+ if ($isInstanceOf(@, "Int"))
1669+ then @
1670+ else throw(($getType(@) + " couldn't be cast to Int"))
1671+ }, {
1672+ let @ = list[1]
1673+ if ($isInstanceOf(@, "Int"))
1674+ then @
1675+ else throw(($getType(@) + " couldn't be cast to Int"))
1676+ }, {
1677+ let @ = list[2]
1678+ if ($isInstanceOf(@, "Int"))
1679+ then @
1680+ else throw(($getType(@) + " couldn't be cast to Int"))
1681+ })
1682+ case _ =>
1683+ throwErr("invalid entry type")
1684+ }
1685+ let delay = $t05828958488._1
1686+ let delta = $t05828958488._2
1687+ let target = $t05828958488._3
1688+ let curAmp = parseIntValue(getStringValue(amp()))
1689+ let newAmpRaw = (curAmp + delta)
1690+ let newAmp = if ((0 > delta))
1691+ then if ((target > newAmpRaw))
1692+ then target
1693+ else newAmpRaw
1694+ else if ((newAmpRaw > target))
1695+ then target
1696+ else newAmpRaw
1697+ let lastCall = valueOrElse(getInteger(keyChangeAmpLastCall()), 0)
1698+ let wait = (lastCall + delay)
1699+ let checks = [if ((height > wait))
1700+ then true
1701+ else throwErr("try again in few blocks"), if ((curAmp != newAmp))
1702+ then true
1703+ else throwErr("already reached target")]
1704+ if ((checks == checks))
1705+ then [IntegerEntry(keyChangeAmpLastCall(), height), StringEntry(amp(), toString(newAmp)), StringEntry(keyAmpHistory(height), toString(newAmp))]
1706+ else throw("Strict value is not equal to itself.")
1707+ }
1708+
1709+
1710+@Verifier(tx)
1711+func verify () = {
1712+ let targetPublicKey = match m() {
1713+ case pk: ByteVector =>
1714+ pk
1715+ case _: Unit =>
1716+ tx.senderPublicKey
1717+ case _ =>
1718+ throw("Match error")
1719+ }
1720+ match tx {
1721+ case order: Order =>
1722+ let matcherPub = mp()
1723+ let $t05940059517 = if (skipOrderValidation())
1724+ then $Tuple2(true, "")
1725+ else validateMatcherOrderAllowed(order)
1726+ let orderValid = $t05940059517._1
1727+ let orderValidInfo = $t05940059517._2
1728+ let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
1729+ let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
1730+ if (if (if (orderValid)
1731+ then senderValid
1732+ else false)
1733+ then matcherValid
1734+ else false)
1735+ then true
1736+ else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
1737+ case s: SetScriptTransaction =>
1738+ if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
1739+ then true
1740+ else {
1741+ let newHash = blake2b256(value(s.script))
1742+ let allowedHash = fromBase64String(value(getString(fca, keyAllowedLpStableScriptHash())))
1743+ let currentHash = scriptHash(this)
1744+ if ((allowedHash == newHash))
1745+ then (currentHash != newHash)
1746+ else false
1747+ }
1748+ case _ =>
1749+ sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
1750+ }
1751+ }
1752+

github/deemru/w8io/026f985 
89.93 ms