tx · HrvA2fyuXh2wFLNEfwYzVDszX633VY1ycmDS35HK7UAj

3N9be2mwrA52WJho6DiesZkk4351GvpnWuj:  -0.04200000 Waves

2023.02.14 15:40 [2449302] smart account 3N9be2mwrA52WJho6DiesZkk4351GvpnWuj > SELF 0.00000000 Waves

{ "type": 13, "id": "HrvA2fyuXh2wFLNEfwYzVDszX633VY1ycmDS35HK7UAj", "fee": 4200000, "feeAssetId": null, "timestamp": 1676378487508, "version": 2, "chainId": 84, "sender": "3N9be2mwrA52WJho6DiesZkk4351GvpnWuj", "senderPublicKey": "6mzmbCza9iqbzxMEELcEA4Xc9NeF4CYpbTtz1zMK3C7x", "proofs": [ "Hp9EsqrDHWre9G5pB9fAbbXo2Kgr5UDM3KrHA9grzCJfDgJuGdPY2U4BofpEdPUAkkpbAoUexdwcivwXszmTFAQ", "2DKAfsmi8fPdG58bESoXMktu4c6bT36JroErdAK9Cx9j8YexKET7qBqqDHRbzJxebyeGGT6NRLy5LTcKyFzdyYxV", "344w1f7finLDXjsMhcXrKU2wyGfnnXrK9iQ9fKuyQtppMmMcZKorywfo1Qi5WfUZxS2wRKXxZV8WZB4pSegE1doP" ], "script": "base64:BgJhCAISDgoMCAgICAgIAQEBAQEBEgUKAwgIARIHCgUYAQEBARIAEgASBQoDCAEIEgMKAQESBAoCAQgSABIFCgMIAQESBAoCAQESBAoCCAESBgoECAEBCBIGCgQICAEBEgASALABAQ9nZXRTdHJpbmdPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUHYWRkcmVzcwUDa2V5CQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFB2FkZHJlc3MJAMwIAgIBLgkAzAgCBQNrZXkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAEFbGNhbGMBAWwJALkIAQUBbAEOZ2V0TnVtYmVyQnlLZXkBA2tleQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQNrZXkAAAEOZ2V0U3RyaW5nQnlLZXkBA2tleQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQNrZXkCAAEMZ2V0Qm9vbEJ5S2V5AQNrZXkJAQt2YWx1ZU9yRWxzZQIJAJsIAgUEdGhpcwUDa2V5BwEYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AgdhZGRyZXNzA2tleQkBC3ZhbHVlT3JFbHNlAgkAmggCBQdhZGRyZXNzBQNrZXkAAAEYZ2V0U3RyaW5nQnlBZGRyZXNzQW5kS2V5AgdhZGRyZXNzA2tleQkBC3ZhbHVlT3JFbHNlAgkAnQgCCQERQGV4dHJOYXRpdmUoMTA2MikBBQdhZGRyZXNzBQNrZXkCAAEWZ2V0Qm9vbEJ5QWRkcmVzc0FuZEtleQIHYWRkcmVzcwNrZXkJAQt2YWx1ZU9yRWxzZQIJAJsIAgUHYWRkcmVzcwUDa2V5BwEJYXNBbnlMaXN0AQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACCUxpc3RbQW55XQQBbAUHJG1hdGNoMAUBbAkAAgECG2ZhaWwgdG8gY2FzdCBpbnRvIExpc3RbQW55XQEIYXNTdHJpbmcBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwBQFzCQACAQIYZmFpbCB0byBjYXN0IGludG8gU3RyaW5nAQVhc0ludAEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgNJbnQEAWkFByRtYXRjaDAFAWkJAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBB2FzQnl0ZXMBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEB3ZhbEJ5dGUFByRtYXRjaDAFB3ZhbEJ5dGUJAAIBAhxmYWlsIHRvIGNhc3QgaW50byBCeXRlVmVjdG9yAQlhc1BheW1lbnQBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIPQXR0YWNoZWRQYXltZW50BAFwBQckbWF0Y2gwBQFwCQACAQIhZmFpbCB0byBjYXN0IGludG8gQXR0YWNoZWRQYXltZW50ARJhc1N3YXBQYXJhbXNTVFJVQ1QBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIjKEludCwgSW50LCBJbnQsIEludCwgSW50LCBJbnQsIEludCkEBnN0cnVjdAUHJG1hdGNoMAUGc3RydWN0CQACAQIdZmFpbCB0byBjYXN0IGludG8gVHVwbGU1IGludHMAA1NFUAICX18AB0xJU1RTRVACAToABU1VTFQ4AIDC1y8ABU1VTFQ2AMCEPQAOREVGQVVMVFNXQVBGRUUAoJwBAAtCUlBST1RFQ1RFRACgjQYAB1dBVkVTSUQBBBOr2TMAD25NZXRyaWNJZHhQcmljZQAAABtuTWV0cmljSWR4VXNkbkxvY2tlZEJhbGFuY2UAAQAcbk1ldHJpY0lkeFdhdmVzTG9ja2VkQmFsYW5jZQACABFuTWV0cmljSWR4UmVzZXJ2ZQADABduTWV0cmljSWR4UmVzZXJ2ZUluVXNkbgAEABRuTWV0cmljSWR4VXNkblN1cHBseQAFABFuTWV0cmljSWR4U3VycGx1cwAGABhuTWV0cmljSWR4U3VycGx1c1BlcmNlbnQABwAMbk1ldHJpY0lkeEJSAAgAFG5NZXRyaWNJZHhOc2J0U3VwcGx5AAkAF25NZXRyaWNJZHhNYXhOc2J0U3VwcGx5AAoAFG5NZXRyaWNJZHhTdXJmU3VwcGx5AAsAEm5NZXRyaWNVc2RuVXNkdFBlZwAMABZuTWV0cmljQ3VycmVudFByaWNlQWRqAA0AEW5NZXRyaWNCYXNrZXRJbmZvAA4AFG5NZXRyaWNXZWlnaHRlZFByaWNlAA8AF25NZXRyaWNUb3RhbFJlc2VydmVzVXNkABAAGUlkeENvbnRyb2xDZmdOZXV0cmlub0RhcHAAAQAYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwAAIAFElkeENvbnRyb2xDZmdScGREYXBwAAMAFUlkeENvbnRyb2xDZmdNYXRoRGFwcAAEABxJZHhDb250cm9sQ2ZnTGlxdWlkYXRpb25EYXBwAAUAFUlkeENvbnRyb2xDZmdSZXN0RGFwcAAGAB1JZHhDb250cm9sQ2ZnTm9kZVJlZ2lzdHJ5RGFwcAAHABxJZHhDb250cm9sQ2ZnTnNidFN0YWtpbmdEYXBwAAgAGUlkeENvbnRyb2xDZmdNZWRpYXRvckRhcHAACQAcSWR4Q29udHJvbENmZ1N1cmZTdGFraW5nRGFwcAAKACBJZHhDb250cm9sQ2ZnR25zYnRDb250cm9sbGVyRGFwcAALABdJZHhDb250cm9sQ2ZnUmVzdFYyRGFwcAAMABtJZHhDb250cm9sQ2ZnR292ZXJuYW5jZURhcHAADQERa2V5Q29udHJvbEFkZHJlc3MAAhwlcyVzX19jb25maWdfX2NvbnRyb2xBZGRyZXNzAQ1rZXlDb250cm9sQ2ZnAAIRJXNfX2NvbnRyb2xDb25maWcBFHJlYWRDb250cm9sQ2ZnT3JGYWlsAQdjb250cm9sCQC8CQIJAQ9nZXRTdHJpbmdPckZhaWwCBQdjb250cm9sCQENa2V5Q29udHJvbENmZwAFA1NFUAEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgpjb250cm9sQ2ZnA2lkeAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUKY29udHJvbENmZwUDaWR4CQCsAgICLUNvbnRyb2wgY2ZnIGRvZXNuJ3QgY29udGFpbiBhZGRyZXNzIGF0IGluZGV4IAkApAMBBQNpZHgAD2NvbnRyb2xDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQERa2V5Q29udHJvbEFkZHJlc3MAAiMzTjROUzdkNEpvOWE2RjE0TGlGVUtLWVZkVWtrZjJlUDRaeAAKY29udHJvbENmZwkBFHJlYWRDb250cm9sQ2ZnT3JGYWlsAQUPY29udHJvbENvbnRyYWN0AAxtYXRoQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBRVJZHhDb250cm9sQ2ZnTWF0aERhcHAAE25zYnRTdGFraW5nQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBRxJZHhDb250cm9sQ2ZnTnNidFN0YWtpbmdEYXBwABNzdXJmU3Rha2luZ0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUcSWR4Q29udHJvbENmZ1N1cmZTdGFraW5nRGFwcAAXZ25zYnRDb250cm9sbGVyQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBSBJZHhDb250cm9sQ2ZnR25zYnRDb250cm9sbGVyRGFwcAAPYXVjdGlvbkNvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwABRub2RlUmVnaXN0cnlDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFHUlkeENvbnRyb2xDZmdOb2RlUmVnaXN0cnlEYXBwAAtnb3ZDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFG0lkeENvbnRyb2xDZmdHb3Zlcm5hbmNlRGFwcAASTmV1dHJpbm9Bc3NldElkS2V5AhFuZXV0cmlub19hc3NldF9pZAAOQm9uZEFzc2V0SWRLZXkCDWJvbmRfYXNzZXRfaWQAEkF1Y3Rpb25Db250cmFjdEtleQIQYXVjdGlvbl9jb250cmFjdAAWTnNidFN0YWtpbmdDb250cmFjdEtleQITbnNidFN0YWtpbmdDb250cmFjdAAWTGlxdWlkYXRpb25Db250cmFjdEtleQIUbGlxdWlkYXRpb25fY29udHJhY3QADlJQRENvbnRyYWN0S2V5AgxycGRfY29udHJhY3QAEUNvbnRvbENvbnRyYWN0S2V5AhBjb250cm9sX2NvbnRyYWN0AA9NYXRoQ29udHJhY3RLZXkCDW1hdGhfY29udHJhY3QAG0JhbGFuY2VXYXZlc0xvY2tJbnRlcnZhbEtleQIbYmFsYW5jZV93YXZlc19sb2NrX2ludGVydmFsAB5CYWxhbmNlTmV1dHJpbm9Mb2NrSW50ZXJ2YWxLZXkCHmJhbGFuY2VfbmV1dHJpbm9fbG9ja19pbnRlcnZhbAEVTWluVG9rZW5Td2FwQW1vdW50S2V5AQdhc3NldElkCQCsAgICHG1pbl9vdXROZXV0cmlub19zd2FwX2Ftb3VudF8FB2Fzc2V0SWQAGE1pbk5ldXRyaW5vU3dhcEFtb3VudEtleQIYbWluX291dE11bHRpX3N3YXBfYW1vdW50ABtOb2RlT3JhY2xlUHJvdmlkZXJQdWJLZXlLZXkCFG5vZGVfb3JhY2xlX3Byb3ZpZGVyABVOZXV0cmlub091dEZlZVBhcnRLZXkCGG5ldXRyaW5vT3V0X3N3YXBfZmVlUGFydAASV2F2ZXNPdXRGZWVQYXJ0S2V5AhV3YXZlc091dF9zd2FwX2ZlZVBhcnQBD2tleU5vZGVSZWdpc3RyeQEHYWRkcmVzcwkArAICAgQlc19fBQdhZGRyZXNzAAhQcmljZUtleQIFcHJpY2UADVByaWNlSW5kZXhLZXkCC3ByaWNlX2luZGV4AAxJc0Jsb2NrZWRLZXkCCmlzX2Jsb2NrZWQBEmdldFByaWNlSGlzdG9yeUtleQEFYmxvY2sJAKwCAgkArAICBQhQcmljZUtleQIBXwkApAMBBQVibG9jawEYZ2V0SGVpZ2h0UHJpY2VCeUluZGV4S2V5AQVpbmRleAkArAICCQCsAgIFDVByaWNlSW5kZXhLZXkCAV8JAKQDAQUFaW5kZXgBFWdldFN0YWtpbmdOb2RlQnlJbmRleAEDaWR4CQEOZ2V0U3RyaW5nQnlLZXkBCQC5CQIJAMwIAgIGJXMlZCVzCQDMCAICBWxlYXNlCQDMCAIJAKQDAQUDaWR4CQDMCAICC25vZGVBZGRyZXNzBQNuaWwFA1NFUAEcZ2V0U3Rha2luZ05vZGVBZGRyZXNzQnlJbmRleAEDaWR4CQERQGV4dHJOYXRpdmUoMTA2MikBCQEVZ2V0U3Rha2luZ05vZGVCeUluZGV4AQUDaWR4AR9nZXRSZXNlcnZlZEFtb3VudEZvclNwb25zb3JzaGlwAAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgVsZWFzZQkAzAgCAhdzcG9uc29yc2hpcFdhdmVzUmVzZXJ2ZQUDbmlsBQNTRVAJAGgCAOgHBQVNVUxUOAEYZ2V0QmFsYW5jZVVubG9ja0Jsb2NrS2V5AQVvd25lcgkArAICAhViYWxhbmNlX3VubG9ja19ibG9ja18FBW93bmVyAQ1nZXRMZWFzZUlkS2V5AQlub2RlSW5kZXgJALkJAgkAzAgCAgYlcyVkJXMJAMwIAgIFbGVhc2UJAMwIAgkApAMBBQlub2RlSW5kZXgJAMwIAgICaWQFA25pbAUDU0VQARZnZXRMZWFzZUlkQnlBZGRyZXNzS2V5AQtub2RlQWRkcmVzcwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAg5sZWFzZUJ5QWRkcmVzcwkAzAgCBQtub2RlQWRkcmVzcwkAzAgCAgJpZAUDbmlsBQNTRVABEWdldExlYXNlQW1vdW50S2V5AQlub2RlSW5kZXgJALkJAgkAzAgCAgYlcyVkJXMJAMwIAgIFbGVhc2UJAMwIAgkApAMBBQlub2RlSW5kZXgJAMwIAgIGYW1vdW50BQNuaWwFA1NFUAEaZ2V0TGVhc2VBbW91bnRCeUFkZHJlc3NLZXkBC25vZGVBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICDmxlYXNlQnlBZGRyZXNzCQDMCAIFC25vZGVBZGRyZXNzCQDMCAICBmFtb3VudAUDbmlsBQNTRVABGGdldExlYXNlR3JvdXBOb2RlTGlzdEtleQEIZ3JvdXBOdW0JALkJAgkAzAgCAgYlcyVkJXMJAMwIAgIKbGVhc2VHcm91cAkAzAgCCQCkAwEFCGdyb3VwTnVtCQDMCAICCG5vZGVMaXN0BQNuaWwFA1NFUAEQbWluU3dhcEFtb3VudEtFWQEIc3dhcFR5cGUJAKwCAgkArAICAgRtaW5fBQhzd2FwVHlwZQIMX3N3YXBfYW1vdW50AQ50b3RhbExvY2tlZEtFWQIIc3dhcFR5cGUHYXNzZXRJZAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgtiYWxhbmNlTG9jawkAzAgCBQhzd2FwVHlwZQkAzAgCBQdhc3NldElkBQNuaWwFA1NFUAEUdG90YWxMb2NrZWRCeVVzZXJLRVkDCHN3YXBUeXBlBW93bmVyB2Fzc2V0SWQJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCAgtiYWxhbmNlTG9jawkAzAgCBQhzd2FwVHlwZQkAzAgCBQVvd25lcgkAzAgCBQdhc3NldElkBQNuaWwCAV8BFmJhbGFuY2VMb2NrSW50ZXJ2YWxLRVkBCHN3YXBUeXBlAwkAAAIFCHN3YXBUeXBlAghvdXRNdWx0aQUeQmFsYW5jZU5ldXRyaW5vTG9ja0ludGVydmFsS2V5BRtCYWxhbmNlV2F2ZXNMb2NrSW50ZXJ2YWxLZXkBGm5vZGVCYWxhbmNlTG9ja0ludGVydmFsS0VZAAIaYmFsYW5jZV9ub2RlX2xvY2tfaW50ZXJ2YWwBEXN3YXBzVGltZWZyYW1lS0VZAAIPc3dhcHNfdGltZWZyYW1lAQ5iclByb3RlY3RlZEtFWQACF21pbl9CUl9wcm90ZWN0aW9uX2xldmVsAQ9iYXNrZXRBc3NldHNLZXkAAholcyVzX19jb21tb25fX2Jhc2tldEFzc2V0cwEKYmFza2V0REtleQACFSVzJXNfX2NvbW1vbl9fYmFza2V0RAEKYmFza2V0S0tleQACFSVzJXNfX2NvbW1vbl9fYmFza2V0SwEKYmFza2V0QktleQACFSVzJXNfX2NvbW1vbl9fYmFza2V0QgESYmFza2V0TG9nYkRlbHRhS2V5AAIdJXMlc19fY29tbW9uX19iYXNrZXRMb2diRGVsdGEBFmJhc2tldFdlaWdodEJ5QXNzZXRLZXkBB2Fzc2V0SWQJAKwCAgIfJXMlcyVzX19jb21tb25fX3dlaWdodEJ5QXNzZXRfXwUHYXNzZXRJZAERbWluU3dhcEFtb3VudFJFQUQCCHN3YXBUeXBlB2Fzc2V0SWQJAQt2YWx1ZU9yRWxzZQIDCQAAAgUIc3dhcFR5cGUCCG91dE11bHRpCQCfCAEFGE1pbk5ldXRyaW5vU3dhcEFtb3VudEtleQkAnwgBCQEVTWluVG9rZW5Td2FwQW1vdW50S2V5AQUHYXNzZXRJZAAAARJzd2Fwc1RpbWVmcmFtZVJFQUQACQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJARFzd2Fwc1RpbWVmcmFtZUtFWQAAoAsBD3RvdGFsTG9ja2VkUkVBRAIIc3dhcFR5cGUHYXNzZXRJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEOdG90YWxMb2NrZWRLRVkCBQhzd2FwVHlwZQUHYXNzZXRJZAAAARV0b3RhbExvY2tlZEJ5VXNlclJFQUQDCHN3YXBUeXBlBW93bmVyB2Fzc2V0SWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBFHRvdGFsTG9ja2VkQnlVc2VyS0VZAwUIc3dhcFR5cGUFBW93bmVyBQdhc3NldElkAAABF2JhbGFuY2VMb2NrSW50ZXJ2YWxSRUFEAQhzd2FwVHlwZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEWYmFsYW5jZUxvY2tJbnRlcnZhbEtFWQEFCHN3YXBUeXBlAKALARtub2RlQmFsYW5jZUxvY2tJbnRlcnZhbFJFQUQACQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJARpub2RlQmFsYW5jZUxvY2tJbnRlcnZhbEtFWQAAAQEYa2V5U3dhcFVzZXJTcGVudEluUGVyaW9kAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIVc3dhcFVzZXJTcGVudEluUGVyaW9kCQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAEVa2V5VXNlckxhc3RTd2FwSGVpZ2h0AQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgISdXNlckxhc3RTd2FwSGVpZ2h0CQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAEWY29udmVydE5ldXRyaW5vVG9XYXZlcwIGYW1vdW50BXByaWNlCQBrAwUGYW1vdW50BQVNVUxUOAUFcHJpY2UBFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8CBmFtb3VudAVwcmljZQkAawMFBmFtb3VudAUFcHJpY2UFBU1VTFQ4ARJjb252ZXJ0V2F2ZXNUb0JvbmQCBmFtb3VudAVwcmljZQkBFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8CBQZhbW91bnQFBXByaWNlARZjb252ZXJ0SnNvbkFycmF5VG9MaXN0AQlqc29uQXJyYXkJALUJAgUJanNvbkFycmF5AgEsARtjb252ZXJ0QmFza2V0SXRlbVRvTmV1dHJpbm8ECGluQW1vdW50B2luQXNzZXQNYmFza2V0SW5mb1N0cg1uZXV0cmlub1ByaWNlBApiYXNrZXRJbmZvCQC1CQIFDWJhc2tldEluZm9TdHICAV8KAQhmaW5kSXRlbQIDYWNjBGl0ZW0EBWJJdGVtCQC1CQIFBGl0ZW0FB0xJU1RTRVADCQAAAgkAkQMCBQViSXRlbQAABQdpbkFzc2V0BQViSXRlbQUDYWNjBAJpdAoAAiRsBQpiYXNrZXRJbmZvCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhmaW5kSXRlbQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQFZGxvZzYJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBEmJhc2tldExvZ2JEZWx0YUtleQAA3qOD9///////AQQCZDYJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBCmJhc2tldERLZXkAANCGAwQCYjYJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBCmJhc2tldEJLZXkAANClTAQCdzYJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmJhc2tldFdlaWdodEJ5QXNzZXRLZXkBBQdpbkFzc2V0AIqWCgQCcDYJAGQCCQBlAgUFZGxvZzYFAnc2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCaXQAAQQDcHA2CQBsBgUCYjYABgUCcDYABgAGBQZIQUxGVVAEDm91dEFtb3VudEdyb3NzCQBrAwUIaW5BbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJpdAACAwkAAAIFDW5ldXRyaW5vUHJpY2UAAAUFTVVMVDgJAGgCBQ1uZXV0cmlub1ByaWNlAGQECm11bHRpcGxpZXIJAGUCCQBkAgUFTVVMVDYFAmQ2BQNwcDYECW5ldEFtb3VudAkAawMFDm91dEFtb3VudEdyb3NzBQptdWx0aXBsaWVyBQVNVUxUNgQJZmVlQW1vdW50AwkAZwIFCW5ldEFtb3VudAUOb3V0QW1vdW50R3Jvc3MAAAkAZQIFDm91dEFtb3VudEdyb3NzBQluZXRBbW91bnQJAMwIAgUOb3V0QW1vdW50R3Jvc3MJAMwIAgUJbmV0QW1vdW50CQDMCAIFCWZlZUFtb3VudAUDbmlsARdjb252ZXJ0TmV1dHJpbm9Ub0Jhc2tldAMGYW1vdW50DWJhc2tldEluZm9TdHIObmV1dHJpbm9TdXBwbHkECmJhc2tldEluZm8JALUJAgUNYmFza2V0SW5mb1N0cgIBXwoBBGNvbnYCA2FjYwRpdGVtBAVwYXJ0cwkAtQkCBQRpdGVtBQdMSVNUU0VQBAdhc3NldElkCQCRAwIFBXBhcnRzAAAEBXNoYXJlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAQQFcHJpY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwYXJ0cwACBAZyZXNlcnYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwYXJ0cwADAwkAAAIFDm5ldXRyaW5vU3VwcGx5AAAJAAIBAidBdHRlbXB0IHRvIGJ1cm4gbmV1dHJpbm8gYXQgemVybyBzdXBwbHkECW91dEFtb3VudAkAawMFBmFtb3VudAUGcmVzZXJ2BQ5uZXV0cmlub1N1cHBseQQKd2F2ZXNUdXBsZQMJAAACBQdhc3NldElkAgVXQVZFUwkAlAoCBQlvdXRBbW91bnQFBXByaWNlCQCUCgIIBQNhY2MCXzIIBQNhY2MCXzMJAJUKAwkAzQgCCAUDYWNjAl8xCQCWCgQFB2Fzc2V0SWQFCW91dEFtb3VudAUFcHJpY2UFBXNoYXJlCAUKd2F2ZXNUdXBsZQJfMQgFCndhdmVzVHVwbGUCXzIKAAIkbAUKYmFza2V0SW5mbwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJUKAwUDbmlsAAAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEEY29udgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgERbWluU3dhcEFtb3VudEZBSUwCCHN3YXBUeXBlDW1pblN3YXBBbW91bnQJAAIBCQCsAgIJAKwCAgkArAICAhhUaGUgc3BlY2lmaWVkIGFtb3VudCBpbiAFCHN3YXBUeXBlAisgc3dhcCBpcyBsZXNzIHRoYW4gdGhlIHJlcXVpcmVkIG1pbmltdW0gb2YgCQCkAwEFDW1pblN3YXBBbW91bnQBFWVtZXJnZW5jeVNodXRkb3duRkFJTAAJAAIBAlpjb250cmFjdCBpcyBibG9ja2VkIGJ5IEVNRVJHRU5DWSBTSFVURE9XTiBhY3Rpb25zIHVudGlsbCByZWFjdGl2YXRpb24gYnkgZW1lcmdlbmN5IG9yYWNsZXMBDnByaWNlSW5kZXhGQUlMBQVpbmRleApwcmljZUluZGV4C2luZGV4SGVpZ2h0DHVubG9ja0hlaWdodA9wcmV2SW5kZXhIZWlnaHQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAiNpbnZhbGlkIHByaWNlIGhpc3RvcnkgaW5kZXg6IGluZGV4PQkApAMBBQVpbmRleAIMIHByaWNlSW5kZXg9CQCkAwEFCnByaWNlSW5kZXgCDSBpbmRleEhlaWdodD0JAKQDAQULaW5kZXhIZWlnaHQCDiB1bmxvY2tIZWlnaHQ9CQCkAwEFDHVubG9ja0hlaWdodAIRIHByZXZJbmRleEhlaWdodD0JAKQDAQUPcHJldkluZGV4SGVpZ2h0AA9uZXV0cmlub0Fzc2V0SWQJANkEAQkBDmdldFN0cmluZ0J5S2V5AQUSTmV1dHJpbm9Bc3NldElkS2V5AApwcmljZUluZGV4CQEYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AgUPY29udHJvbENvbnRyYWN0BQ1QcmljZUluZGV4S2V5AAlpc0Jsb2NrZWQJARZnZXRCb29sQnlBZGRyZXNzQW5kS2V5AgUPY29udHJvbENvbnRyYWN0BQxJc0Jsb2NrZWRLZXkAGG5vZGVPcmFjbGVQcm92aWRlclB1YktleQkA2QQBCQEOZ2V0U3RyaW5nQnlLZXkBBRtOb2RlT3JhY2xlUHJvdmlkZXJQdWJLZXlLZXkAC2JvbmRBc3NldElkCQDZBAECLEYzaWF4enJ1RmVLdWpmVmZZU1pFa2VqcGpoNjd3bVJmUENSSGlObVdLcDNaABVkZXByZWNhdGVkQm9uZEFzc2V0SWQJANkEAQIsOTc1YWtaQmZuTWo1MTNVN01aYUhLelFybXNFeDVhRTN3ZFdLVHJIQmhiakYAEG5ldXRyaW5vQ29udHJhY3QFBHRoaXMADGN1cnJlbnRQcmljZQkBGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQIFD2NvbnRyb2xDb250cmFjdAUIUHJpY2VLZXkBG2NoZWNrSXNWYWxpZE1pblNwb25zb3JlZEZlZQECdHgEDk1JTlRSQU5TRkVSRkVFAKCNBgQWU3BvbnNvcmVkRmVlVXBwZXJCb3VuZADoBwQPcmVhbE5ldXRyaW5vRmVlCQEWY29udmVydFdhdmVzVG9OZXV0cmlubwIFDk1JTlRSQU5TRkVSRkVFBQxjdXJyZW50UHJpY2UEDm1pbk5ldXRyaW5vRmVlCQBoAgUPcmVhbE5ldXRyaW5vRmVlAAIEDm1heE5ldXRyaW5vRmVlCQBrAwUPcmVhbE5ldXRyaW5vRmVlBRZTcG9uc29yZWRGZWVVcHBlckJvdW5kAGQECGlucHV0RmVlCQEFdmFsdWUBCAUCdHgUbWluU3BvbnNvcmVkQXNzZXRGZWUDAwkAZwIFCGlucHV0RmVlBQ5taW5OZXV0cmlub0ZlZQkAZwIFDm1heE5ldXRyaW5vRmVlBQhpbnB1dEZlZQcJAAACCAUCdHgHYXNzZXRJZAUPbmV1dHJpbm9Bc3NldElkBwEPZ2V0UHJpY2VIaXN0b3J5AQVibG9jawkBGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQIFD2NvbnRyb2xDb250cmFjdAkBEmdldFByaWNlSGlzdG9yeUtleQEFBWJsb2NrARVnZXRIZWlnaHRQcmljZUJ5SW5kZXgBBWluZGV4CQEYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AgUPY29udHJvbENvbnRyYWN0CQEYZ2V0SGVpZ2h0UHJpY2VCeUluZGV4S2V5AQUFaW5kZXgBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICC3BhcmFtQnlVc2VyCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAICBmFtb3VudAUDbmlsBQNTRVAADHNJZHhTd2FwVHlwZQABAApzSWR4U3RhdHVzAAIADHNJZHhJbkFtb3VudAADAA9zSWR4U3RhcnRIZWlnaHQABwASc0lkeFN0YXJ0VGltZXN0YW1wAAgAFHNJZHhTZWxmVW5sb2NrSGVpZ2h0AAsAC3NJZHhNaW5SYW5kAA8AC3NJZHhNYXhSYW5kABAAC3NJZHhJbkFzc2V0ABQBB3N3YXBLRVkCC3VzZXJBZGRyZXNzBHR4SWQJALkJAgkAzAgCAgQlcyVzCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIFBHR4SWQFA25pbAUDU0VQAQtzdHJTd2FwREFUQRQIc3dhcFR5cGUGc3RhdHVzCGluQW1vdW50BXByaWNlDG91dE5ldEFtb3VudAxvdXRGZWVBbW91bnQLc3RhcnRIZWlnaHQOc3RhcnRUaW1lc3RhbXAJZW5kSGVpZ2h0DGVuZFRpbWVzdGFtcBBzZWxmVW5sb2NrSGVpZ2h0EHJhbmRVbmxvY2tIZWlnaHQFaW5kZXgMd2l0aGRyYXdUeElkB3JhbmRNaW4HcmFuZE1heApvdXRTdXJmQW10AmJyCmJhc2tldERhdGEHaW5Bc3NldAkAuQkCCQDMCAICKCVzJXMlZCVkJWQlZCVkJWQlZCVkJWQlZCVkJXMlZCVkJWQlZCVzJXMJAMwIAgUIc3dhcFR5cGUJAMwIAgUGc3RhdHVzCQDMCAIFCGluQW1vdW50CQDMCAIFBXByaWNlCQDMCAIFDG91dE5ldEFtb3VudAkAzAgCBQxvdXRGZWVBbW91bnQJAMwIAgULc3RhcnRIZWlnaHQJAMwIAgUOc3RhcnRUaW1lc3RhbXAJAMwIAgUJZW5kSGVpZ2h0CQDMCAIFDGVuZFRpbWVzdGFtcAkAzAgCBRBzZWxmVW5sb2NrSGVpZ2h0CQDMCAIFEHJhbmRVbmxvY2tIZWlnaHQJAMwIAgUFaW5kZXgJAMwIAgUMd2l0aGRyYXdUeElkCQDMCAIFB3JhbmRNaW4JAMwIAgUHcmFuZE1heAkAzAgCBQpvdXRTdXJmQW10CQDMCAIFAmJyCQDMCAIFCmJhc2tldERhdGEJAMwIAgUHaW5Bc3NldAUDbmlsBQNTRVABD3BlbmRpbmdTd2FwREFUQQQIc3dhcFR5cGUNaW5Bc3NldEFtb3VudBBzZWxmVW5sb2NrSGVpZ2h0B2luQXNzZXQJAQtzdHJTd2FwREFUQRQFCHN3YXBUeXBlAgdQRU5ESU5HCQCkAwEFDWluQXNzZXRBbW91bnQCATACATACATAJAKQDAQUGaGVpZ2h0CQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wAgEwAgEwCQCkAwEFEHNlbGZVbmxvY2tIZWlnaHQCATACATACBE5VTEwCATACATACATACATACAAUHaW5Bc3NldAEOZmluaXNoU3dhcERBVEELCWRhdGFBcnJheQVwcmljZQxvdXROZXRBbW91bnQMb3V0RmVlQW1vdW50EHJhbmRVbmxvY2tIZWlnaHQFaW5kZXgMd2l0aGRyYXdUeElkCm91dFN1cmZBbXQCYnIKYmFza2V0RGF0YQdpbkFzc2V0CQELc3RyU3dhcERBVEEUCQCRAwIFCWRhdGFBcnJheQUMc0lkeFN3YXBUeXBlAghGSU5JU0hFRAkAkQMCBQlkYXRhQXJyYXkFDHNJZHhJbkFtb3VudAkApAMBBQVwcmljZQkApAMBBQxvdXROZXRBbW91bnQJAKQDAQUMb3V0RmVlQW1vdW50CQCRAwIFCWRhdGFBcnJheQUPc0lkeFN0YXJ0SGVpZ2h0CQCRAwIFCWRhdGFBcnJheQUSc0lkeFN0YXJ0VGltZXN0YW1wCQCkAwEFBmhlaWdodAkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAkQMCBQlkYXRhQXJyYXkFFHNJZHhTZWxmVW5sb2NrSGVpZ2h0CQCkAwEFEHJhbmRVbmxvY2tIZWlnaHQJAKQDAQUFaW5kZXgFDHdpdGhkcmF3VHhJZAkAkQMCBQlkYXRhQXJyYXkFC3NJZHhNaW5SYW5kCQCRAwIFCWRhdGFBcnJheQULc0lkeE1heFJhbmQJAKQDAQUKb3V0U3VyZkFtdAkApAMBBQJicgUKYmFza2V0RGF0YQUHaW5Bc3NldAESc3dhcERhdGFGYWlsT3JSRUFEAgt1c2VyQWRkcmVzcwhzd2FwVHhJZAQHc3dhcEtleQkBB3N3YXBLRVkCBQt1c2VyQWRkcmVzcwUIc3dhcFR4SWQJALwJAgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEFB3N3YXBLZXkJAKwCAgIRbm8gc3dhcCBkYXRhIGZvciAFB3N3YXBLZXkFA1NFUAEJYXBwbHlGZWVzAw5hbW91bnRPdXRHcm9zcwtpbkFtdFRvU1VSRgdmZWVQYXJ0BAlmZWVBbW91bnQJAGsDBQ5hbW91bnRPdXRHcm9zcwUHZmVlUGFydAUFTVVMVDYJAMwIAgkAZQIFDmFtb3VudE91dEdyb3NzBQlmZWVBbW91bnQJAMwIAgUJZmVlQW1vdW50BQNuaWwBD2FwcGx5RmVlc0Jhc2tldAEJYmFza2V0T3V0BAJrNgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEKYmFza2V0S0tleQAFBU1VTFQ2BAJkNgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEKYmFza2V0REtleQAA0IYDBAdmZWVQYXJ0CQBrAwUCazYFAmQ2BQVNVUxUNgoBCmZlZUFwcGxpZXICA2FjYwRpdGVtBAlmZWVBbW91bnQJAGsDCAUEaXRlbQJfMgUHZmVlUGFydAUFTVVMVDYJAM0IAgUDYWNjCQC5CQIJAMwIAggFBGl0ZW0CXzEJAMwIAgkApAMBCAUEaXRlbQJfMwkAzAgCCQCkAwEJAGUCCAUEaXRlbQJfMgUJZmVlQW1vdW50CQDMCAIJAKQDAQUJZmVlQW1vdW50CQDMCAIJAKQDAQgFBGl0ZW0CXzQFA25pbAUHTElTVFNFUAQBYQoAAiRsBQliYXNrZXRPdXQKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCmZlZUFwcGxpZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoJALkJAgUBYQUDU0VQAQNhYnMBAXgDCQBmAgAABQF4CQEBLQEFAXgFAXgBCnNlbGVjdE5vZGUBDXVubGVhc2VBbW91bnQEDWFtb3VudFRvTGVhc2UJAGUCCQBlAggJAO8HAQUQbmV1dHJpbm9Db250cmFjdAlhdmFpbGFibGUFDXVubGVhc2VBbW91bnQJAR9nZXRSZXNlcnZlZEFtb3VudEZvclNwb25zb3JzaGlwAAQKb2xkTGVhc2VkMAkBDmdldE51bWJlckJ5S2V5AQkBEWdldExlYXNlQW1vdW50S2V5AQAABApvbGRMZWFzZWQxCQEOZ2V0TnVtYmVyQnlLZXkBCQERZ2V0TGVhc2VBbW91bnRLZXkBAAEECm5ld0xlYXNlZDAJAGQCBQ1hbW91bnRUb0xlYXNlBQpvbGRMZWFzZWQwBApuZXdMZWFzZWQxCQBkAgUNYW1vdW50VG9MZWFzZQUKb2xkTGVhc2VkMQMDCQBmAgUKbmV3TGVhc2VkMAAABgkAZgIFCm5ld0xlYXNlZDEAAAQGZGVsdGEwCQEDYWJzAQkAZQIFCm5ld0xlYXNlZDAFCm9sZExlYXNlZDEEBmRlbHRhMQkBA2FicwEJAGUCBQpuZXdMZWFzZWQxBQpvbGRMZWFzZWQwAwkAZwIFBmRlbHRhMQUGZGVsdGEwCQCUCgIAAAUKbmV3TGVhc2VkMAkAlAoCAAEFCm5ld0xlYXNlZDEJAJQKAgD///////////8BAAABCHRoaXNPbmx5AQFpAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQItUGVybWlzc2lvbiBkZW5pZWQ6IHRoaXMgY29udHJhY3Qgb25seSBhbGxvd2VkBgEWcHJlcGFyZVVubGVhc2VBbmRMZWFzZQENdW5sZWFzZUFtb3VudAQJbm9kZVR1cGxlCQEKc2VsZWN0Tm9kZQEFDXVubGVhc2VBbW91bnQECW5vZGVJbmRleAgFCW5vZGVUdXBsZQJfMQQObmV3TGVhc2VBbW91bnQIBQlub2RlVHVwbGUCXzIDCQBmAgUObmV3TGVhc2VBbW91bnQAAAQKbGVhc2VJZEtleQkBDWdldExlYXNlSWRLZXkBBQlub2RlSW5kZXgECG9sZExlYXNlCQCcCAIFBHRoaXMFCmxlYXNlSWRLZXkEDnVubGVhc2VPckVtcHR5AwkBCWlzRGVmaW5lZAEFCG9sZExlYXNlCQDMCAIJAQtMZWFzZUNhbmNlbAEJAQV2YWx1ZQEFCG9sZExlYXNlBQNuaWwFA25pbAQObGVhc2VBbW91bnRLZXkJARFnZXRMZWFzZUFtb3VudEtleQEFCW5vZGVJbmRleAQFbGVhc2UJAMQIAgkBHGdldFN0YWtpbmdOb2RlQWRkcmVzc0J5SW5kZXgBBQlub2RlSW5kZXgFDm5ld0xlYXNlQW1vdW50CQDOCAIFDnVubGVhc2VPckVtcHR5CQDMCAIFBWxlYXNlCQDMCAIJAQtCaW5hcnlFbnRyeQIFCmxlYXNlSWRLZXkJAQVsY2FsYwEFBWxlYXNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQERZ2V0TGVhc2VBbW91bnRLZXkBBQlub2RlSW5kZXgFDm5ld0xlYXNlQW1vdW50BQNuaWwFA25pbAEMcmVhZE5vZGVJbmZvAQdub2RlSWR4BAtub2RlQWRkcmVzcwkBHGdldFN0YWtpbmdOb2RlQWRkcmVzc0J5SW5kZXgBBQdub2RlSWR4BAxsZWFzZWRBbXRLRVkJARFnZXRMZWFzZUFtb3VudEtleQEFB25vZGVJZHgECWxlYXNlZEFtdAkBDmdldE51bWJlckJ5S2V5AQUMbGVhc2VkQW10S0VZBApsZWFzZUlkS0VZCQENZ2V0TGVhc2VJZEtleQEFB25vZGVJZHgEB2xlYXNlSWQJAQV2YWx1ZQEJAJwIAgUEdGhpcwUKbGVhc2VJZEtFWQkAlwoFBQtub2RlQWRkcmVzcwUMbGVhc2VkQW10S0VZBQlsZWFzZWRBbXQFCmxlYXNlSWRLRVkFB2xlYXNlSWQBCmNvbW1vblN3YXAFCHN3YXBUeXBlCXBtdEFtb3VudAdpbkFzc2V0DnVzZXJBZGRyZXNzU3RyBnR4SWQ1OAQQc3dhcFBhcmFtc1NUUlVDVAkBEmFzU3dhcFBhcmFtc1NUUlVDVAEJAPwHBAUEdGhpcwIbc3dhcFBhcmFtc0J5VXNlclNZU1JFQURPTkxZCQDMCAIFDnVzZXJBZGRyZXNzU3RyCQDMCAIAAAUDbmlsBQNuaWwEDnN3YXBMaW1pdFNwZW50CAUQc3dhcFBhcmFtc1NUUlVDVAJfMgQOYmxja3MyTG10UmVzZXQIBRBzd2FwUGFyYW1zU1RSVUNUAl8zBBF3YXZlc1N3YXBMaW1pdE1heAgFEHN3YXBQYXJhbXNTVFJVQ1QCXzYEEHVzZG5Td2FwTGltaXRNYXgIBRBzd2FwUGFyYW1zU1RSVUNUAl83BA1taW5Td2FwQW1vdW50CQERbWluU3dhcEFtb3VudFJFQUQCBQhzd2FwVHlwZQUHaW5Bc3NldAQLdG90YWxMb2NrZWQJAQ90b3RhbExvY2tlZFJFQUQCBQhzd2FwVHlwZQUHaW5Bc3NldAQRdG90YWxMb2NrZWRCeVVzZXIJARV0b3RhbExvY2tlZEJ5VXNlclJFQUQDBQhzd2FwVHlwZQUOdXNlckFkZHJlc3NTdHIFB2luQXNzZXQEC25vZGVBZGRyZXNzCQEVZ2V0U3Rha2luZ05vZGVCeUluZGV4AQAABAxwcmljZUJ5SW5kZXgJAQ9nZXRQcmljZUhpc3RvcnkBCQEVZ2V0SGVpZ2h0UHJpY2VCeUluZGV4AQUKcHJpY2VJbmRleAQMaXNTd2FwQnlOb2RlCQAAAgULbm9kZUFkZHJlc3MFDnVzZXJBZGRyZXNzU3RyBBZiYWxhbmNlTG9ja01heEludGVydmFsAwUMaXNTd2FwQnlOb2RlCQEbbm9kZUJhbGFuY2VMb2NrSW50ZXJ2YWxSRUFEAAkBF2JhbGFuY2VMb2NrSW50ZXJ2YWxSRUFEAQUIc3dhcFR5cGUEEHNlbGZVbmxvY2tIZWlnaHQJAGQCBQZoZWlnaHQFFmJhbGFuY2VMb2NrTWF4SW50ZXJ2YWwEDnN3YXBVc2RuVm9sdW1lAwkAAAIFCHN3YXBUeXBlAgtvdXROZXV0cmlubwkBFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8CBQlwbXRBbW91bnQFDHByaWNlQnlJbmRleAUJcG10QW1vdW50BAxzd2FwTGltaXRNYXgDCQAAAgUIc3dhcFR5cGUCC291dE5ldXRyaW5vCQEWY29udmVydFdhdmVzVG9OZXV0cmlubwIFEXdhdmVzU3dhcExpbWl0TWF4BQxwcmljZUJ5SW5kZXgFEHVzZG5Td2FwTGltaXRNYXgDCQBmAgUNbWluU3dhcEFtb3VudAUJcG10QW1vdW50CQERbWluU3dhcEFtb3VudEZBSUwCBQhzd2FwVHlwZQUNbWluU3dhcEFtb3VudAMDCQEBIQEFDGlzU3dhcEJ5Tm9kZQkAZgIFDnN3YXBMaW1pdFNwZW50AAAHCQACAQkArAICAjpZb3UgaGF2ZSBleGNlZWRlZCBzd2FwIGxpbWl0ISBOZXh0IGFsbG93ZWQgc3dhcCBoZWlnaHQgaXMgCQCkAwEJAGQCBQZoZWlnaHQFDmJsY2tzMkxtdFJlc2V0AwMJAQEhAQUMaXNTd2FwQnlOb2RlCQBmAgUOc3dhcFVzZG5Wb2x1bWUFDHN3YXBMaW1pdE1heAcJAAIBCQCsAgIJAKwCAgkArAICAi5Zb3UgaGF2ZSBleGNlZWRlZCB5b3VyIHN3YXAgbGltaXQhIFJlcXVlc3RlZDogCQCkAwEFDnN3YXBVc2RuVm9sdW1lAg0sIGF2YWlsYWJsZTogCQCkAwEFDHN3YXBMaW1pdE1heAMFCWlzQmxvY2tlZAkBFWVtZXJnZW5jeVNodXRkb3duRkFJTAAED25ldXRyaW5vTWV0cmljcwkBCWFzQW55TGlzdAEJAPwHBAUMbWF0aENvbnRyYWN0AhpjYWxjTmV1dGlub01ldHJpY3NSRUFET05MWQUDbmlsBQNuaWwECmJhc2tldEluZm8JAQhhc1N0cmluZwEJAJEDAgUPbmV1dHJpbm9NZXRyaWNzBRFuTWV0cmljQmFza2V0SW5mbwQNd2VpZ2h0ZWRQcmljZQkBBWFzSW50AQkAkQMCBQ9uZXV0cmlub01ldHJpY3MFFG5NZXRyaWNXZWlnaHRlZFByaWNlBANvdXQJARtjb252ZXJ0QmFza2V0SXRlbVRvTmV1dHJpbm8EBQlwbXRBbW91bnQFB2luQXNzZXQFCmJhc2tldEluZm8FDXdlaWdodGVkUHJpY2UDAwkAAAIFCHN3YXBUeXBlAgtvdXROZXV0cmlubwkAZwIAAAkAkQMCBQNvdXQAAQcJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAj5OZXQgYW1vdW50IGlzIG5vbi1wb3NpdGl2ZSwgY2Fubm90IHN3YXAuIChncm9zcywgbmV0LCBmZWUpID0gKAkApAMBCQCRAwIFA291dAAAAgIsIAkApAMBCQCRAwIFA291dAABAgIsIAkApAMBCQCRAwIFA291dAACAgEpBAlsZWFzZVBhcnQDAwkAAAIFCHN3YXBUeXBlAgtvdXROZXV0cmlubwkAAAIFB2luQXNzZXQCBVdBVkVTBwkBFnByZXBhcmVVbmxlYXNlQW5kTGVhc2UBAAAFA25pbAkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJARhrZXlTd2FwVXNlclNwZW50SW5QZXJpb2QBBQ51c2VyQWRkcmVzc1N0cgUOc3dhcFVzZG5Wb2x1bWUJAMwIAgkBDEludGVnZXJFbnRyeQIJARVrZXlVc2VyTGFzdFN3YXBIZWlnaHQBBQ51c2VyQWRkcmVzc1N0cgUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEUdG90YWxMb2NrZWRCeVVzZXJLRVkDBQhzd2FwVHlwZQUOdXNlckFkZHJlc3NTdHIFB2luQXNzZXQJAGQCBRF0b3RhbExvY2tlZEJ5VXNlcgUJcG10QW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEYZ2V0QmFsYW5jZVVubG9ja0Jsb2NrS2V5AQUOdXNlckFkZHJlc3NTdHIFEHNlbGZVbmxvY2tIZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b3RhbExvY2tlZEtFWQIFCHN3YXBUeXBlBQdpbkFzc2V0CQBkAgULdG90YWxMb2NrZWQFCXBtdEFtb3VudAkAzAgCCQELU3RyaW5nRW50cnkCCQEHc3dhcEtFWQIFDnVzZXJBZGRyZXNzU3RyBQZ0eElkNTgJAQ9wZW5kaW5nU3dhcERBVEEEBQhzd2FwVHlwZQUJcG10QW1vdW50BRBzZWxmVW5sb2NrSGVpZ2h0BQdpbkFzc2V0BQNuaWwFCWxlYXNlUGFydAUEdW5pdAAMYkZ1bmNJZHhTdXJmAAAADWJGdW5jSWR4V2F2ZXMAAQAMYkZ1bmNJZHhVc2RuAAIAFGJGdW5jSWR4UmVzZXJ2ZVN0YXJ0AAMAE2JGdW5jSWR4U3VwcGx5U3RhcnQABAAPYkZ1bmNJZHhCUlN0YXJ0AAUAEmJGdW5jSWR4UmVzZXJ2ZUVuZAAGABFiRnVuY0lkeFN1cHBseUVuZAAHAA1iRnVuY0lkeEJSRW5kAAgADGJGdW5jSWR4UmVzdAAJABJiRnVuY0lkeFdhdmVzUHJpY2UACgEPY2FsY1dpdGhkcmF3VDJVBAhpbkFtb3VudAdpbkFzc2V0CmJhc2tldEluZm8Nd2VpZ2h0ZWRQcmljZQQGb3V0QW10CQEbY29udmVydEJhc2tldEl0ZW1Ub05ldXRyaW5vBAUIaW5BbW91bnQFB2luQXNzZXQFCmJhc2tldEluZm8FDXdlaWdodGVkUHJpY2UJAJ4KDAkAkQMCBQZvdXRBbXQAAAUPbmV1dHJpbm9Bc3NldElkAAAFB2luQXNzZXQAAAUNd2VpZ2h0ZWRQcmljZQUIaW5BbW91bnQAAAAAAAAFA25pbAkAzAgCCQCRAwIFBm91dEFtdAABCQDMCAIJAJEDAgUGb3V0QW10AAIFA25pbAEUY2FsY1dpdGhkcmF3VTJCYXNrZXQDBnVzZG5JbgpiYXNrZXRJbmZvDm5ldXRyaW5vU3VwcGx5BAtvdXRBbXRHcm9zcwkBF2NvbnZlcnROZXV0cmlub1RvQmFza2V0AwUGdXNkbkluBQpiYXNrZXRJbmZvBQ5uZXV0cmlub1N1cHBseQkAngoMCAULb3V0QW10R3Jvc3MCXzIFBHVuaXQAAAUPbmV1dHJpbm9Bc3NldElkCAULb3V0QW10R3Jvc3MCXzIIBQtvdXRBbXRHcm9zcwJfMwUGdXNkbkluBQ5uZXV0cmlub1N1cHBseQUGdXNkbkluAAAIBQtvdXRBbXRHcm9zcwJfMQUDbmlsAQxjYWxjV2l0aGRyYXcFCHN3YXBUeXBlCGluQW1vdW50BXByaWNlD25ldXRyaW5vTWV0cmljcwdpbkFzc2V0BA5uZXV0cmlub1N1cHBseQkBBWFzSW50AQkAkQMCBQ9uZXV0cmlub01ldHJpY3MFFG5NZXRyaWNJZHhVc2RuU3VwcGx5BApiYXNrZXRJbmZvCQEIYXNTdHJpbmcBCQCRAwIFD25ldXRyaW5vTWV0cmljcwURbk1ldHJpY0Jhc2tldEluZm8EDXdlaWdodGVkUHJpY2UJAQVhc0ludAEJAJEDAgUPbmV1dHJpbm9NZXRyaWNzBRRuTWV0cmljV2VpZ2h0ZWRQcmljZQQMb3V0RGF0YVR1cGxlAwkAAAIFCHN3YXBUeXBlAgtvdXROZXV0cmlubwkBD2NhbGNXaXRoZHJhd1QyVQQFCGluQW1vdW50BQdpbkFzc2V0BQpiYXNrZXRJbmZvBQ13ZWlnaHRlZFByaWNlAwkAAAIFCHN3YXBUeXBlAghvdXRNdWx0aQkBFGNhbGNXaXRoZHJhd1UyQmFza2V0AwUIaW5BbW91bnQFCmJhc2tldEluZm8FDm5ldXRyaW5vU3VwcGx5CQACAQkArAICAhZVbnN1cHBvcnRlZCBzd2FwIHR5cGUgBQhzd2FwVHlwZQQLb3V0QW10R3Jvc3MIBQxvdXREYXRhVHVwbGUCXzEECm91dEFzc2V0SWQIBQxvdXREYXRhVHVwbGUCXzIED2luQW10VG9TdXJmUGFydAgFDG91dERhdGFUdXBsZQJfMwQJaW5Bc3NldElkCAUMb3V0RGF0YVR1cGxlAl80BAp1bmxlYXNlQW10CAUMb3V0RGF0YVR1cGxlAl81BA13aXRoZHJhd1ByaWNlCAUMb3V0RGF0YVR1cGxlAl82BApiYXNrZXREYXRhCAUMb3V0RGF0YVR1cGxlA18xMQQKbmV0RmVlRGF0YQgFDG91dERhdGFUdXBsZQNfMTIECW91dE5ldEFtdAMJAAACBQhzd2FwVHlwZQILb3V0TmV1dHJpbm8JAJEDAgUKbmV0RmVlRGF0YQAAAAAECW91dEZlZUFtdAMJAAACBQhzd2FwVHlwZQILb3V0TmV1dHJpbm8JAJEDAgUKbmV0RmVlRGF0YQABAAAECm91dFN1cmZBbXQDCQBnAgAABQ9pbkFtdFRvU3VyZlBhcnQAAAkBBWFzSW50AQkAkQMCCQEJYXNBbnlMaXN0AQkA/AcEBQxtYXRoQ29udHJhY3QCFHN1cmZGdW5jdGlvblJFQURPTkxZCQDMCAIFD2luQW10VG9TdXJmUGFydAkAzAgCBQlpbkFzc2V0SWQFA25pbAUDbmlsBQxiRnVuY0lkeFN1cmYEDndpdGhkcmF3QmFza2V0AwkAAAIFCHN3YXBUeXBlAghvdXRNdWx0aQkBD2FwcGx5RmVlc0Jhc2tldAEFCmJhc2tldERhdGECAAkAmwoJBQlvdXROZXRBbXQFCm91dEFzc2V0SWQFCm91dFN1cmZBbXQFD2luQW10VG9TdXJmUGFydAUKdW5sZWFzZUFtdAUJb3V0RmVlQW10BQtvdXRBbXRHcm9zcwUNd2l0aGRyYXdQcmljZQUOd2l0aGRyYXdCYXNrZXQBEmtleUFwcGx5SW5Qcm9ncmVzcwACEyVzX19hcHBseUluUHJvZ3Jlc3MBE2tleVByb3Bvc2FsRGF0YUJ5SWQBCnByb3Bvc2FsSWQJAKwCAgIUJXMlZF9fcHJvcG9zYWxEYXRhX18JAKQDAQUKcHJvcG9zYWxJZAALZ292SWR4VHhJZHMACQEOdmFsaWRhdGVVcGRhdGUBAnR4BAckbWF0Y2gwBQJ0eAMJAAECBQckbWF0Y2gwAgVPcmRlcgQBbwUHJG1hdGNoMAkAAgECFU9yZGVycyBhcmVuJ3QgYWxsb3dlZAMDCQABAgUHJG1hdGNoMAIPRGF0YVRyYW5zYWN0aW9uBgMJAAECBQckbWF0Y2gwAhVTcG9uc29yRmVlVHJhbnNhY3Rpb24GAwkAAQIFByRtYXRjaDACFFNldFNjcmlwdFRyYW5zYWN0aW9uBgMJAAECBQckbWF0Y2gwAhZDcmVhdGVBbGlhc1RyYW5zYWN0aW9uBgMJAAECBQckbWF0Y2gwAhZMZWFzZUNhbmNlbFRyYW5zYWN0aW9uBgMJAAECBQckbWF0Y2gwAhBMZWFzZVRyYW5zYWN0aW9uBgMJAAECBQckbWF0Y2gwAhBJc3N1ZVRyYW5zYWN0aW9uBgMJAAECBQckbWF0Y2gwAhtJbnZva2VFeHByZXNzaW9uVHJhbnNhY3Rpb24GAwkAAQIFByRtYXRjaDACGlVwZGF0ZUFzc2V0SW5mb1RyYW5zYWN0aW9uBgMJAAECBQckbWF0Y2gwAhdJbnZva2VTY3JpcHRUcmFuc2FjdGlvbgYDCQABAgUHJG1hdGNoMAIZU2V0QXNzZXRTY3JpcHRUcmFuc2FjdGlvbgYDCQABAgUHJG1hdGNoMAITVHJhbnNmZXJUcmFuc2FjdGlvbgYDCQABAgUHJG1hdGNoMAITRXhjaGFuZ2VUcmFuc2FjdGlvbgYDCQABAgUHJG1hdGNoMAIXTWFzc1RyYW5zZmVyVHJhbnNhY3Rpb24GAwkAAQIFByRtYXRjaDACD0J1cm5UcmFuc2FjdGlvbgYJAAECBQckbWF0Y2gwAhJSZWlzc3VlVHJhbnNhY3Rpb24EAXQFByRtYXRjaDAEBHR4SWQJANgEAQgFAXQCaWQECnByb3Bvc2FsSWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQtnb3ZDb250cmFjdAkBEmtleUFwcGx5SW5Qcm9ncmVzcwACFkFwcGx5IGlzIG5vdCBoYXBwZW5pbmcEBnR4TGlzdAkAtQkCCQCRAwIJALUJAgkBD2dldFN0cmluZ09yRmFpbAIFC2dvdkNvbnRyYWN0CQETa2V5UHJvcG9zYWxEYXRhQnlJZAEFCnByb3Bvc2FsSWQFA1NFUAULZ292SWR4VHhJZHMFB0xJU1RTRVADCQEBIQEJAQlpc0RlZmluZWQBCQDPCAIFBnR4TGlzdAUEdHhJZAkAAgEJAKwCAgkArAICCQCsAgICDlVua25vd24gdHhJZDogBQR0eElkAhAgZm9yIHByb3Bvc2FsSWQ9CQCkAwEFCnByb3Bvc2FsSWQGCQACAQILTWF0Y2ggZXJyb3IQAWkBDWNvbnN0cnVjdG9yVjEMEm5ldXRyaW5vQXNzZXRJZFBybQ5ib25kQXNzZXRJZFBybRJhdWN0aW9uQ29udHJhY3RQcm0WbGlxdWlkYXRpb25Db250cmFjdFBybQ5ycGRDb250cmFjdFBybRtub2RlT3JhY2xlUHJvdmlkZXJQdWJLZXlQcm0bYmFsYW5jZVdhdmVzTG9ja0ludGVydmFsUHJtHmJhbGFuY2VOZXV0cmlub0xvY2tJbnRlcnZhbFBybRVtaW5XYXZlc1N3YXBBbW91bnRQcm0YbWluTmV1dHJpbm9Td2FwQW1vdW50UHJtFW5ldXRyaW5vT3V0RmVlUGFydFBybRJ3YXZlc091dEZlZVBhcnRQcm0EC2NoZWNrQ2FsbGVyCQEIdGhpc09ubHkBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECE25vIHBheW1lbnRzIGFsbG93ZWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUSTmV1dHJpbm9Bc3NldElkS2V5BRJuZXV0cmlub0Fzc2V0SWRQcm0JAMwIAgkBC1N0cmluZ0VudHJ5AgUOQm9uZEFzc2V0SWRLZXkFDmJvbmRBc3NldElkUHJtCQDMCAIJAQtTdHJpbmdFbnRyeQIFEkF1Y3Rpb25Db250cmFjdEtleQUSYXVjdGlvbkNvbnRyYWN0UHJtCQDMCAIJAQtTdHJpbmdFbnRyeQIFFkxpcXVpZGF0aW9uQ29udHJhY3RLZXkFFmxpcXVpZGF0aW9uQ29udHJhY3RQcm0JAMwIAgkBC1N0cmluZ0VudHJ5AgUOUlBEQ29udHJhY3RLZXkFDnJwZENvbnRyYWN0UHJtCQDMCAIJAQtTdHJpbmdFbnRyeQIFG05vZGVPcmFjbGVQcm92aWRlclB1YktleUtleQUbbm9kZU9yYWNsZVByb3ZpZGVyUHViS2V5UHJtCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRtCYWxhbmNlV2F2ZXNMb2NrSW50ZXJ2YWxLZXkFG2JhbGFuY2VXYXZlc0xvY2tJbnRlcnZhbFBybQkAzAgCCQEMSW50ZWdlckVudHJ5AgUeQmFsYW5jZU5ldXRyaW5vTG9ja0ludGVydmFsS2V5BR5iYWxhbmNlTmV1dHJpbm9Mb2NrSW50ZXJ2YWxQcm0JAMwIAgkBDEludGVnZXJFbnRyeQIJARVNaW5Ub2tlblN3YXBBbW91bnRLZXkBAgVXQVZFUwUVbWluV2F2ZXNTd2FwQW1vdW50UHJtCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRhNaW5OZXV0cmlub1N3YXBBbW91bnRLZXkFGG1pbk5ldXRyaW5vU3dhcEFtb3VudFBybQkAzAgCCQEMSW50ZWdlckVudHJ5AgUVTmV1dHJpbm9PdXRGZWVQYXJ0S2V5BRVuZXV0cmlub091dEZlZVBhcnRQcm0JAMwIAgkBDEludGVnZXJFbnRyeQIFEldhdmVzT3V0RmVlUGFydEtleQUSd2F2ZXNPdXRGZWVQYXJ0UHJtBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQENY29uc3RydWN0b3JWMgMMbWF0aENvbnRyYWN0E25zYnRTdGFraW5nQ29udHJhY3QUc3dhcHNUaW1lZnJhbWVCbG9ja3MEC2NoZWNrQ2FsbGVyCQEIdGhpc09ubHkBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECE25vIHBheW1lbnRzIGFsbG93ZWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUPTWF0aENvbnRyYWN0S2V5BQxtYXRoQ29udHJhY3QJAMwIAgkBC1N0cmluZ0VudHJ5AgUWTnNidFN0YWtpbmdDb250cmFjdEtleQUTbnNidFN0YWtpbmdDb250cmFjdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEXN3YXBzVGltZWZyYW1lS0VZAAUUc3dhcHNUaW1lZnJhbWVCbG9ja3MFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ1jb25zdHJ1Y3RvclYzBRFhc3NldHNXZWlnaHRzTWlucwZkUGFyYW0Ga1BhcmFtBmJQYXJhbQpkZWx0YVBhcmFtBAtjaGVja0NhbGxlcgkBCHRoaXNPbmx5AQUBaQMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhNubyBwYXltZW50cyBhbGxvd2VkCgEHcHJlcGFyZQIDYWNjBGl0ZW0EBXBhcnRzCQC1CQIFBGl0ZW0CAV8EB2Fzc2V0SWQJAJEDAgUFcGFydHMAAAQGd2VpZ2h0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAQQGbWluVmFsCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAgkAlAoCCQDNCAIIBQNhY2MCXzEFB2Fzc2V0SWQJAM0IAgkAzQgCCAUDYWNjAl8yCQEMSW50ZWdlckVudHJ5AgkBFmJhc2tldFdlaWdodEJ5QXNzZXRLZXkBBQdhc3NldElkBQZ3ZWlnaHQJAQxJbnRlZ2VyRW50cnkCCQEVTWluVG9rZW5Td2FwQW1vdW50S2V5AQUHYXNzZXRJZAUGbWluVmFsBAFyCgACJGwFEWFzc2V0c1dlaWdodHNNaW5zCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHcHJlcGFyZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIIBQFyAl8yCQEMSW50ZWdlckVudHJ5AgkBCmJhc2tldERLZXkABQZkUGFyYW0JAQxJbnRlZ2VyRW50cnkCCQEKYmFza2V0S0tleQAFBmtQYXJhbQkBDEludGVnZXJFbnRyeQIJAQpiYXNrZXRCS2V5AAUGYlBhcmFtCQEMSW50ZWdlckVudHJ5AgkBEmJhc2tldExvZ2JEZWx0YUtleQAJAG0GBQpkZWx0YVBhcmFtAAYFBmJQYXJhbQAGAAYFBkhBTEZVUAkBC1N0cmluZ0VudHJ5AgkBD2Jhc2tldEFzc2V0c0tleQAJALkJAggFAXICXzEFA1NFUAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARNzd2FwVG9rZW5Ub05ldXRyaW5vAAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECLHN3YXBUb2tlblRvTmV1dHJpbm8gcmVxdWlyZSBvbmx5IG9uZSBwYXltZW50BANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAQMYmFza2V0QXNzZXRzCQELdmFsdWVPckVsc2UCCQCiCAEJAQ9iYXNrZXRBc3NldHNLZXkAAgVXQVZFUwQNcG10QXNzZXRJZFN0cgkA2AQBCQELdmFsdWVPckVsc2UCCAUDcG10B2Fzc2V0SWQFB1dBVkVTSUQDCQEBIQEJAQhjb250YWlucwIFDGJhc2tldEFzc2V0cwUNcG10QXNzZXRJZFN0cgkAAgEJAKwCAgkArAICBQ1wbXRBc3NldElkU3RyAh0gaXMgbm90IG9uZSBvZiBiYXNrZXQgdG9rZW5zOgUMYmFza2V0QXNzZXRzBAt1c2VyQWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEBnR4SWQ1OAkA2AQBCAUBaQ10cmFuc2FjdGlvbklkCQEKY29tbW9uU3dhcAUCC291dE5ldXRyaW5vCAUDcG10BmFtb3VudAUNcG10QXNzZXRJZFN0cgULdXNlckFkZHJlc3MFBnR4SWQ1OAFpARRzd2FwTmV1dHJpbm9Ub0Jhc2tldAADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAi1zd2FwTmV1dHJpbm9Ub0Jhc2tldCByZXF1aXJlIG9ubHkgb25lIHBheW1lbnQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AggFA3BtdAdhc3NldElkBQ9uZXV0cmlub0Fzc2V0SWQJAAIBAjpPbmx5IGFwcHJvcHJpYXRlIE5ldXRyaW5vIHRva2VucyBhcmUgYWxsb3dlZCBmb3Igc3dhcHBpbmcuBAt1c2VyQWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEBnR4SWQ1OAkA2AQBCAUBaQ10cmFuc2FjdGlvbklkCQEKY29tbW9uU3dhcAUCCG91dE11bHRpCAUDcG10BmFtb3VudAkA2AQBBQ9uZXV0cmlub0Fzc2V0SWQFC3VzZXJBZGRyZXNzBQZ0eElkNTgBaQEId2l0aGRyYXcDB2FjY291bnQFaW5kZXgIc3dhcFR4SWQEBHR4SWQJANgEAQgFAWkNdHJhbnNhY3Rpb25JZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECE25vIHBheW1lbnRzIGFsbG93ZWQED25ldXRyaW5vTWV0cmljcwkBCWFzQW55TGlzdAEJAPwHBAUMbWF0aENvbnRyYWN0AhpjYWxjTmV1dGlub01ldHJpY3NSRUFET05MWQUDbmlsBQNuaWwEAkJSCQEFYXNJbnQBCQCRAwIFD25ldXRyaW5vTWV0cmljcwUMbk1ldHJpY0lkeEJSBAt1c2VyQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQUHYWNjb3VudAQJZGF0YUFycmF5CQESc3dhcERhdGFGYWlsT3JSRUFEAgUHYWNjb3VudAUIc3dhcFR4SWQEEHNlbGZVbmxvY2tIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlkYXRhQXJyYXkFFHNJZHhTZWxmVW5sb2NrSGVpZ2h0BAhzd2FwVHlwZQkAkQMCBQlkYXRhQXJyYXkFDHNJZHhTd2FwVHlwZQQIaW5BbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlkYXRhQXJyYXkFDHNJZHhJbkFtb3VudAQKc3dhcFN0YXR1cwkAkQMCBQlkYXRhQXJyYXkFCnNJZHhTdGF0dXMEC3N0YXJ0SGVpZ2h0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZGF0YUFycmF5BQ9zSWR4U3RhcnRIZWlnaHQEB2luQXNzZXQJAJEDAgUJZGF0YUFycmF5BQtzSWR4SW5Bc3NldAQLdG90YWxMb2NrZWQJAQ90b3RhbExvY2tlZFJFQUQCBQhzd2FwVHlwZQUHaW5Bc3NldAQRdG90YWxMb2NrZWRCeVVzZXIJARV0b3RhbExvY2tlZEJ5VXNlclJFQUQDBQhzd2FwVHlwZQUHYWNjb3VudAUHaW5Bc3NldAQMdW5sb2NrSGVpZ2h0BRBzZWxmVW5sb2NrSGVpZ2h0BAtpbmRleEhlaWdodAkBFWdldEhlaWdodFByaWNlQnlJbmRleAEFBWluZGV4BA9wcmV2SW5kZXhIZWlnaHQJARVnZXRIZWlnaHRQcmljZUJ5SW5kZXgBCQBlAgUFaW5kZXgAAQQMcHJpY2VCeUluZGV4CQEPZ2V0UHJpY2VIaXN0b3J5AQULaW5kZXhIZWlnaHQDBQlpc0Jsb2NrZWQJARVlbWVyZ2VuY3lTaHV0ZG93bkZBSUwAAwkBAiE9AgUKc3dhcFN0YXR1cwIHUEVORElORwkAAgECH3N3YXAgaGFzIGJlZW4gYWxyZWFkeSBwcm9jZXNzZWQDCQBmAgUMdW5sb2NrSGVpZ2h0BQZoZWlnaHQJAAIBCQCsAgIJAKwCAgIRcGxlYXNlIHdhaXQgZm9yOiAJAKQDAQUMdW5sb2NrSGVpZ2h0Ah8gYmxvY2sgaGVpZ2h0IHRvIHdpdGhkcmF3IGZ1bmRzAwMDCQBmAgUFaW5kZXgFCnByaWNlSW5kZXgGCQBmAgUMdW5sb2NrSGVpZ2h0BQtpbmRleEhlaWdodAYDCQECIT0CBQ9wcmV2SW5kZXhIZWlnaHQAAAkAZwIFD3ByZXZJbmRleEhlaWdodAUMdW5sb2NrSGVpZ2h0BwkBDnByaWNlSW5kZXhGQUlMBQUFaW5kZXgFCnByaWNlSW5kZXgFC2luZGV4SGVpZ2h0BQx1bmxvY2tIZWlnaHQFD3ByZXZJbmRleEhlaWdodAQNd2l0aGRyYXdUdXBsZQkBDGNhbGNXaXRoZHJhdwUFCHN3YXBUeXBlBQhpbkFtb3VudAUMcHJpY2VCeUluZGV4BQ9uZXV0cmlub01ldHJpY3MFB2luQXNzZXQEDG91dE5ldEFtb3VudAgFDXdpdGhkcmF3VHVwbGUCXzEECm91dEFzc2V0SWQIBQ13aXRoZHJhd1R1cGxlAl8yBApvdXRTdXJmQW10CAUNd2l0aGRyYXdUdXBsZQJfMwQKdW5sZWFzZUFtdAgFDXdpdGhkcmF3VHVwbGUCXzUEDG91dEZlZUFtb3VudAgFDXdpdGhkcmF3VHVwbGUCXzYEC291dEFtdEdyb3NzCAUNd2l0aGRyYXdUdXBsZQJfNwQNd2l0aGRyYXdQcmljZQgFDXdpdGhkcmF3VHVwbGUCXzgEDndpdGhkcmF3QmFza2V0CAUNd2l0aGRyYXdUdXBsZQJfOQMDCQAAAgUIc3dhcFR5cGUCC291dE5ldXRyaW5vCQBnAgAABQtvdXRBbXRHcm9zcwcJAAIBAhNiYWxhbmNlIGVxdWFscyB6ZXJvBA1zdXJmQ29uZGl0aW9uAwkAZgIFCm91dFN1cmZBbXQAAAQLaXNzdWVSZXN1bHQJAPwHBAUPYXVjdGlvbkNvbnRyYWN0Aglpc3N1ZVN1cmYJAMwIAgUKb3V0U3VyZkFtdAkAzAgCBQdhY2NvdW50BQNuaWwFA25pbAMJAAACBQtpc3N1ZVJlc3VsdAULaXNzdWVSZXN1bHQAAAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAwkAAAIFDXN1cmZDb25kaXRpb24FDXN1cmZDb25kaXRpb24EEXVubGVhc2VJbnZPckVtcHR5CQD8BwQFBHRoaXMCF2ludGVybmFsVW5sZWFzZUFuZExlYXNlCQDMCAIFCnVubGVhc2VBbXQFA25pbAUDbmlsAwkAAAIFEXVubGVhc2VJbnZPckVtcHR5BRF1bmxlYXNlSW52T3JFbXB0eQQJZ25zYnREYXRhCQEJYXNBbnlMaXN0AQkA/AcEBRdnbnNidENvbnRyb2xsZXJDb250cmFjdAIUZ25zYnRJbmZvU1lTUkVBRE9OTFkJAMwIAgIACQDMCAIAAAkAzAgCAAAFA25pbAUDbmlsBA1nbnNidEFtdFRvdGFsCQEFYXNJbnQBCQCRAwIFCWduc2J0RGF0YQABBBVnbnNidEFtdEZyb21TdXJmVG90YWwJAQVhc0ludAEJAJEDAgkBCWFzQW55TGlzdAEJAJEDAgUJZ25zYnREYXRhAAMAAwQNY29tbW9uQWN0aW9ucwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFHRvdGFsTG9ja2VkQnlVc2VyS0VZAwUIc3dhcFR5cGUFB2FjY291bnQFB2luQXNzZXQJAGUCBRF0b3RhbExvY2tlZEJ5VXNlcgUIaW5BbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b3RhbExvY2tlZEtFWQIFCHN3YXBUeXBlBQdpbkFzc2V0CQBlAgULdG90YWxMb2NrZWQFCGluQW1vdW50CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQdzd2FwS0VZAgUHYWNjb3VudAUIc3dhcFR4SWQJAQ5maW5pc2hTd2FwREFUQQsFCWRhdGFBcnJheQUNd2l0aGRyYXdQcmljZQUMb3V0TmV0QW1vdW50BQxvdXRGZWVBbW91bnQFDHVubG9ja0hlaWdodAUFaW5kZXgFBHR4SWQFCm91dFN1cmZBbXQFAkJSBQ53aXRoZHJhd0Jhc2tldAUHaW5Bc3NldAUDbmlsAwkAAAIFCHN3YXBUeXBlAghvdXRNdWx0aQQGYmFza2V0CQC1CQIFDndpdGhkcmF3QmFza2V0AgFfCgEGbG9vcGVyAgNhY2MEaXRlbQQCaXQJALUJAgUEaXRlbQUHTElTVFNFUAQLdGVtcEFzc2V0SWQJANkEAQkAkQMCBQJpdAAABAdhc3NldElkAwkAAAIFC3RlbXBBc3NldElkBQdXQVZFU0lEBQR1bml0BQt0ZW1wQXNzZXRJZAQJbmV0QW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCaXQAAgQJZmVlQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCaXQAAwQIc3VyZkFtdDEDCQECIT0CBQ1nbnNidEFtdFRvdGFsAAAJAGsDBQlmZWVBbW91bnQFFWduc2J0QW10RnJvbVN1cmZUb3RhbAUNZ25zYnRBbXRUb3RhbAAABAhzdXJmQW10MgMJAQIhPQIFDWduc2J0QW10VG90YWwAAAkAawMFCWZlZUFtb3VudAkAZQIFBU1VTFQ2BQJCUgUFTVVMVDYAAAQHc3VyZkFtdAkAlgMBCQDMCAIFCHN1cmZBbXQxCQDMCAIFCHN1cmZBbXQyBQNuaWwEB25zYnRBbXQJAGUCBQlmZWVBbW91bnQFB3N1cmZBbXQJAJcKBQkAzQgCCAUDYWNjAl8xCQEOU2NyaXB0VHJhbnNmZXIDBQt1c2VyQWRkcmVzcwUJbmV0QW1vdW50BQdhc3NldElkCQDNCAIIBQNhY2MCXzIJAQ9BdHRhY2hlZFBheW1lbnQCBQdhc3NldElkBQdzdXJmQW10CQDNCAIIBQNhY2MCXzMJAQ9BdHRhY2hlZFBheW1lbnQCBQdhc3NldElkBQduc2J0QW10CQBkAggFA2FjYwJfNAUHc3VyZkFtdAkAZAIIBQNhY2MCXzUFB25zYnRBbXQEAXIKAAIkbAUGYmFza2V0CgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlwoFBQNuaWwFA25pbAUDbmlsAAAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEGbG9vcGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBAtzdXJmRGVwb3NpdAMJAGYCCAUBcgJfNAAABAdzdXJmSW52CQD8BwQFE3N1cmZTdGFraW5nQ29udHJhY3QCB2RlcG9zaXQFA25pbAgFAXICXzIDCQAAAgUHc3VyZkludgUHc3VyZkludgAACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAADCQAAAgULc3VyZkRlcG9zaXQFC3N1cmZEZXBvc2l0BAtuc2J0RGVwb3NpdAMJAGYCCAUBcgJfNQAABAduc2J0SW52CQD8BwQFE25zYnRTdGFraW5nQ29udHJhY3QCB2RlcG9zaXQFA25pbAgFAXICXzMDCQAAAgUHbnNidEludgUHbnNidEludgAACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAADCQAAAgULbnNidERlcG9zaXQFC25zYnREZXBvc2l0CQDOCAIFDWNvbW1vbkFjdGlvbnMIBQFyAl8xCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBANmZWUJAQ9BdHRhY2hlZFBheW1lbnQCBQpvdXRBc3NldElkBQxvdXRGZWVBbW91bnQEC3N1cmZGZWVBbXQxAwkBAiE9AgUNZ25zYnRBbXRUb3RhbAAACQBrAwgFA2ZlZQZhbW91bnQFFWduc2J0QW10RnJvbVN1cmZUb3RhbAUNZ25zYnRBbXRUb3RhbAAABAtzdXJmRmVlQW10MgMJAQIhPQIFDWduc2J0QW10VG90YWwAAAkAawMIBQNmZWUGYW1vdW50CQBlAgUFTVVMVDYFAkJSBQVNVUxUNgAABApzdXJmRmVlQW10CQCWAwEJAMwIAgULc3VyZkZlZUFtdDEJAMwIAgULc3VyZkZlZUFtdDIFA25pbAQKbnNidEZlZUFtdAkAZQIIBQNmZWUGYW1vdW50BQpzdXJmRmVlQW10BAtzdXJmRGVwb3NpdAMJAGYCBQpzdXJmRmVlQW10AAAEB3N1cmZJbnYJAPwHBAUTc3VyZlN0YWtpbmdDb250cmFjdAIHZGVwb3NpdAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCAUDZmVlB2Fzc2V0SWQFCnN1cmZGZWVBbXQFA25pbAMJAAACBQdzdXJmSW52BQdzdXJmSW52BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBQtzdXJmRGVwb3NpdAULc3VyZkRlcG9zaXQEC25zYnREZXBvc2l0AwkAZgIFCm5zYnRGZWVBbXQAAAQHbnNidEludgkA/AcEBRNuc2J0U3Rha2luZ0NvbnRyYWN0AgdkZXBvc2l0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIIBQNmZWUHYXNzZXRJZAUKbnNidEZlZUFtdAUDbmlsAwkAAAIFB25zYnRJbnYFB25zYnRJbnYFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAwkAAAIFC25zYnREZXBvc2l0BQtuc2J0RGVwb3NpdAkAzQgCBQ1jb21tb25BY3Rpb25zCQEOU2NyaXB0VHJhbnNmZXIDBQt1c2VyQWRkcmVzcwUMb3V0TmV0QW1vdW50BQpvdXRBc3NldElkCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBF2ludGVybmFsVW5sZWFzZUFuZExlYXNlAQ11bmxlYXNlQW1vdW50AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIsaW50ZXJuYWxVbmxlYXNlQW5kTGVhc2UgaXMgbm90IHB1YmxpYyBtZXRob2QJARZwcmVwYXJlVW5sZWFzZUFuZExlYXNlAQUNdW5sZWFzZUFtb3VudAFpARJ0cmFuc2ZlclVzZG5Ub1VzZXICBmFtb3VudARhZGRyAwkBAiE9AggFAWkGY2FsbGVyBQ9hdWN0aW9uQ29udHJhY3QJAAIBAiNPbmx5IGF1Y3Rpb24gY29udHJhY3QgaXMgYXV0aG9yaXplZAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQRhZGRyBQZhbW91bnQFD25ldXRyaW5vQXNzZXRJZAUDbmlsAWkBC2FjY2VwdFdhdmVzAAMDCQECIT0CCAUBaQZjYWxsZXIFD2F1Y3Rpb25Db250cmFjdAkBAiE9AggFAWkGY2FsbGVyBQtnb3ZDb250cmFjdAcJAAIBAkNDdXJyZW50bHkgb25seSBhdWN0aW9uIGFuZCBnb3Zlcm5hbmNlIGNvbnRyYWN0cyBhcmUgYWxsb3dlZCB0byBjYWxsCQCUCgIJARZwcmVwYXJlVW5sZWFzZUFuZExlYXNlAQAAAgdzdWNjZXNzAWkBD2FwcHJvdmVMZWFzaW5ncwMGbkxpc3RTCGdyb3VwTnVtBGxBbXQEBW5JZHhzCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFCQDMCAIABgkAzAgCAAcFA25pbAQHbW5nUHViUwkBC3ZhbHVlT3JFbHNlAgkAoggBAhwlcyVzX19jZmdfX2xlYXNpbmdNYW5hZ2VyUHViAiw3QVVNWDU0dWtZTVl2UG1tYTd5b0ZmNU5qWmhzNEJ1NW56M0V6OUVWOHN1cgQGbW5nUHViCQDZBAEFB21uZ1B1YlMEDm5vZGVSZWdBZGRyU3RyCQELdmFsdWVPckVsc2UCCQCiCAECHyVzJXNfX2NmZ19fbm9kZXNSZWdpc3RyeUFkZHJlc3MCIzNQOXZLcVFLalVkbXBYQWZpV2F1OGtyUkVZQVkxWHI2OXBFBAtub2RlUmVnQWRkcgkBEUBleHRyTmF0aXZlKDEwNjIpAQUObm9kZVJlZ0FkZHJTdHIEEWxHcm91cE5vZGVMaXN0S0VZCQEYZ2V0TGVhc2VHcm91cE5vZGVMaXN0S2V5AQUIZ3JvdXBOdW0ECmxHck5vZGVPcHQJAJ0IAgUEdGhpcwURbEdyb3VwTm9kZUxpc3RLRVkDCQEJaXNEZWZpbmVkAQUKbEdyTm9kZU9wdAkAAgEJAKwCAgkArAICAgZncm91cCAJAKQDAQUIZ3JvdXBOdW0CFCBhbHJlYWR5IGluaXRpYWxpemVkBAVuTGlzdAkAtQkCBQZuTGlzdFMFA1NFUAQIZXhwQ291bnQJAJADAQUFbklkeHMDCQECIT0CCAUBaQ9jYWxsZXJQdWJsaWNLZXkFBm1uZ1B1YgkAAgECHmFwcHJvdmVMZWFzaW5ncyBub3QgYXV0aG9yaXplZAQNJHQwNDMwODY0MzE0OAkBDHJlYWROb2RlSW5mbwEAAAQGbkFkZHIwCAUNJHQwNDMwODY0MzE0OAJfMQQIbEFtdEtFWTAIBQ0kdDA0MzA4NjQzMTQ4Al8yBAVsQW10MAgFDSR0MDQzMDg2NDMxNDgCXzMEB2xJZEtFWTAIBQ0kdDA0MzA4NjQzMTQ4Al80BARsSWQwCAUNJHQwNDMwODY0MzE0OAJfNQQFbmV3TDAJAMQIAgUGbkFkZHIwCQBlAgUFbEFtdDAJAGgCBQRsQW10BQhleHBDb3VudAQKdmFsaWRhdGlvbgkA/AcEBQtub2RlUmVnQWRkcgIadmFsaWRhdGVBbmRBcHByb3ZlTGVhc2luZ3MJAMwIAgUGbkxpc3RTBQNuaWwFA25pbAMJAAACBQp2YWxpZGF0aW9uBQp2YWxpZGF0aW9uCgEjZm9yRWFjaE5vZGVWYWxpZGF0ZUFuZEdlbmVyYXRlTGVhc2UCAWEBaQQEbm9kZQkAkQMCBQVuTGlzdAUBaQQCbGEJAMQIAgkBEUBleHRyTmF0aXZlKDEwNjIpAQUEbm9kZQUEbEFtdAkAzggCBQFhCQDMCAIFAmxhCQDMCAIJAQtCaW5hcnlFbnRyeQIJARZnZXRMZWFzZUlkQnlBZGRyZXNzS2V5AQUEbm9kZQkBBWxjYWxjAQUCbGEJAMwIAgkBDEludGVnZXJFbnRyeQIJARpnZXRMZWFzZUFtb3VudEJ5QWRkcmVzc0tleQEFBG5vZGUFBGxBbXQFA25pbAkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFEWxHcm91cE5vZGVMaXN0S0VZBQZuTGlzdFMJAMwIAgkBC0JpbmFyeUVudHJ5AgUHbElkS0VZMAkBBWxjYWxjAQUFbmV3TDAJAMwIAgkBDEludGVnZXJFbnRyeQIFCGxBbXRLRVkwCAUFbmV3TDAGYW1vdW50CQDMCAIJAQtMZWFzZUNhbmNlbAEFBGxJZDAJAMwIAgUFbmV3TDAFA25pbAoAAiRsBQVuSWR4cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEjZm9yRWFjaE5vZGVWYWxpZGF0ZUFuZEdlbmVyYXRlTGVhc2UCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDgJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAICQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEXJlYmFsYW5jZUxlYXNpbmdzAgZhbW91bnQIZ3JvdXBOdW0EBW5JZHhzCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFCQDMCAIABgkAzAgCAAcFA25pbAQHbW5nUHViUwkBC3ZhbHVlT3JFbHNlAgkAoggBAhwlcyVzX19jZmdfX2xlYXNpbmdNYW5hZ2VyUHViAiw3QVVNWDU0dWtZTVl2UG1tYTd5b0ZmNU5qWmhzNEJ1NW56M0V6OUVWOHN1cgQGbW5nUHViCQDZBAEFB21uZ1B1YlMEEWxHcm91cE5vZGVMaXN0S0VZCQEYZ2V0TGVhc2VHcm91cE5vZGVMaXN0S2V5AQUIZ3JvdXBOdW0EBm5MaXN0UwkBD2dldFN0cmluZ09yRmFpbAIFBHRoaXMFEWxHcm91cE5vZGVMaXN0S0VZBAVuTGlzdAkAtQkCBQZuTGlzdFMFA1NFUAMJAQIhPQIIBQFpD2NhbGxlclB1YmxpY0tleQUGbW5nUHViCQACAQIgcmViYWxhbmNlTGVhc2luZ3Mgbm90IGF1dGhvcml6ZWQECnVubGVhc2VBbXQJAGQCCQBpAgUGYW1vdW50CQCQAwEFBW5MaXN0AAEEDSR0MDQ0Mzg4NDQ0NTAJAQxyZWFkTm9kZUluZm8BAAAEBm5BZGRyMAgFDSR0MDQ0Mzg4NDQ0NTACXzEECGxBbXRLRVkwCAUNJHQwNDQzODg0NDQ1MAJfMgQFbEFtdDAIBQ0kdDA0NDM4ODQ0NDUwAl8zBAdsSWRLRVkwCAUNJHQwNDQzODg0NDQ1MAJfNAQEbElkMAgFDSR0MDQ0Mzg4NDQ0NTACXzUEBW5ld0wwCQDECAIFBm5BZGRyMAkAZAIFBWxBbXQwCQBoAgUKdW5sZWFzZUFtdAkAkAMBBQVuTGlzdAoBFGZvckVhY2hOb2RlRG9VbmxlYXNlAgFhAWkEBG5vZGUJAJEDAgUFbkxpc3QFAWkEBmxJZEtFWQkBFmdldExlYXNlSWRCeUFkZHJlc3NLZXkBBQRub2RlBANsSWQJARFAZXh0ck5hdGl2ZSgxMDUyKQIFBHRoaXMFBmxJZEtFWQQHbEFtdEtFWQkBGmdldExlYXNlQW1vdW50QnlBZGRyZXNzS2V5AQUEbm9kZQQEbEFtdAkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwUHbEFtdEtFWQQDdWxhCQELTGVhc2VDYW5jZWwBCQEFdmFsdWUBBQNsSWQEAmxhCQDECAIJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBG5vZGUJAGUCBQRsQW10BQp1bmxlYXNlQW10CQDOCAIFAWEJAMwIAgkBC0xlYXNlQ2FuY2VsAQkBBXZhbHVlAQUDbElkCQDMCAIFAmxhCQDMCAIJAQtCaW5hcnlFbnRyeQIFBmxJZEtFWQkBBWxjYWxjAQUCbGEJAMwIAgkBDEludGVnZXJFbnRyeQIFB2xBbXRLRVkIBQJsYQZhbW91bnQFA25pbAkAzggCCgACJGwFBW5JZHhzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARRmb3JFYWNoTm9kZURvVW5sZWFzZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgOAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgJAMwIAgkBC0JpbmFyeUVudHJ5AgUHbElkS0VZMAkBBWxjYWxjAQUFbmV3TDAJAMwIAgkBDEludGVnZXJFbnRyeQIFCGxBbXRLRVkwCAUFbmV3TDAGYW1vdW50CQDMCAIJAQtMZWFzZUNhbmNlbAEFBGxJZDAJAMwIAgUFbmV3TDAFA25pbAFpARtzd2FwUGFyYW1zQnlVc2VyU1lTUkVBRE9OTFkCDnVzZXJBZGRyZXNzU3RyCWduc2J0RGlmZgQJZ25zYnREYXRhCQEJYXNBbnlMaXN0AQkA/AcEBRdnbnNidENvbnRyb2xsZXJDb250cmFjdAIUZ25zYnRJbmZvU1lTUkVBRE9OTFkJAMwIAgUOdXNlckFkZHJlc3NTdHIJAMwIAgAACQDMCAIAAAUDbmlsBQNuaWwECGduc2J0QW10CQBkAgkBBWFzSW50AQkAkQMCBQlnbnNidERhdGEAAAUJZ25zYnREaWZmBA1nbnNidEFtdFRvdGFsCQBkAgkBBWFzSW50AQkAkQMCBQlnbnNidERhdGEAAQUJZ25zYnREaWZmBA1zd2FwTGltaXREYXRhCQEJYXNBbnlMaXN0AQkA/AcEBQxtYXRoQ29udHJhY3QCFWNhbGNTd2FwTGltaXRSRUFET05MWQkAzAgCBQhnbnNidEFtdAUDbmlsBQNuaWwEF3dhdmVzU3dhcExpbWl0SW5Vc2RuTWF4CQEFYXNJbnQBCQCRAwIFDXN3YXBMaW1pdERhdGEAAAQRd2F2ZXNTd2FwTGltaXRNYXgJAQVhc0ludAEJAJEDAgUNc3dhcExpbWl0RGF0YQABBBB1c2RuU3dhcExpbWl0TWF4CQEFYXNJbnQBCQCRAwIFDXN3YXBMaW1pdERhdGEAAgQObGFzdFN3YXBIZWlnaHQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBFWtleVVzZXJMYXN0U3dhcEhlaWdodAEFDnVzZXJBZGRyZXNzU3RyAAAEF3N3YXBMaW1pdFRpbWVsaWZlQmxvY2tzCQESc3dhcHNUaW1lZnJhbWVSRUFEAAQZcGFzc2VkQmxvY2tzQWZ0ZXJMYXN0U3dhcAkAZQIFBmhlaWdodAUObGFzdFN3YXBIZWlnaHQEEWlzU3dhcFRpbWVsaWZlTmV3CQBnAgUZcGFzc2VkQmxvY2tzQWZ0ZXJMYXN0U3dhcAUXc3dhcExpbWl0VGltZWxpZmVCbG9ja3MEFHN3YXBMaW1pdFNwZW50SW5Vc2RuAwURaXNTd2FwVGltZWxpZmVOZXcAAAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEYa2V5U3dhcFVzZXJTcGVudEluUGVyaW9kAQUOdXNlckFkZHJlc3NTdHIAAAQOYmxja3MyTG10UmVzZXQDBRFpc1N3YXBUaW1lbGlmZU5ldwAACQBlAgUXc3dhcExpbWl0VGltZWxpZmVCbG9ja3MFGXBhc3NlZEJsb2Nrc0FmdGVyTGFzdFN3YXAJAJQKAgUDbmlsCQCZCgcFF3dhdmVzU3dhcExpbWl0SW5Vc2RuTWF4BRRzd2FwTGltaXRTcGVudEluVXNkbgUOYmxja3MyTG10UmVzZXQFCGduc2J0QW10BQ1nbnNidEFtdFRvdGFsBRF3YXZlc1N3YXBMaW1pdE1heAUQdXNkblN3YXBMaW1pdE1heAFpAR1jYWxjV2l0aGRyYXdSZXN1bHRTWVNSRUFET05MWQQIc3dhcFR5cGUIaW5BbW91bnQFcHJpY2UHaW5Bc3NldAQPbmV1dHJpbm9NZXRyaWNzCQEJYXNBbnlMaXN0AQkA/AcEBQxtYXRoQ29udHJhY3QCGmNhbGNOZXV0aW5vTWV0cmljc1JFQURPTkxZBQNuaWwFA25pbAkAlAoCBQNuaWwJAQxjYWxjV2l0aGRyYXcFBQhzd2FwVHlwZQUIaW5BbW91bnQFBXByaWNlBQ9uZXV0cmlub01ldHJpY3MFB2luQXNzZXQBaQEUcmVwbGFjZUNvbW11bml0eU5vZGUECm9sZEFkZHJTdHIKbmV3QWRkclN0cghncm91cE51bQ1wZW5hbHR5QW1vdW50BAdtbmdQdWJTCQELdmFsdWVPckVsc2UCCQCiCAECHCVzJXNfX2NmZ19fbGVhc2luZ01hbmFnZXJQdWICLDdBVU1YNTR1a1lNWXZQbW1hN3lvRmY1TmpaaHM0QnU1bnozRXo5RVY4c3VyBAZtbmdQdWIJANkEAQUHbW5nUHViUwMJAQIhPQIIBQFpD2NhbGxlclB1YmxpY0tleQUGbW5nUHViCQACAQIjcmVwbGFjZUNvbW11bml0eU5vZGUgbm90IGF1dGhvcml6ZWQECGdyb3VwS2V5CQEYZ2V0TGVhc2VHcm91cE5vZGVMaXN0S2V5AQUIZ3JvdXBOdW0EDmdyb3VwTm9kZUxpc3RTCQEPZ2V0U3RyaW5nT3JGYWlsAgUEdGhpcwUIZ3JvdXBLZXkDCQEBIQEJAQhjb250YWlucwIFDmdyb3VwTm9kZUxpc3RTBQpvbGRBZGRyU3RyCQACAQkArAICCQCsAgIJAKwCAgIGR3JvdXAgCQCkAwEFCGdyb3VwTnVtAhogZG9lcyBub3QgY29udGFpbiBhZGRyZXNzIAUKb2xkQWRkclN0cgQJZG9SZXBsYWNlCQD8BwQFFG5vZGVSZWdpc3RyeUNvbnRyYWN0AhNyZXBsYWNlQXBwcm92ZWROb2RlCQDMCAIFCm9sZEFkZHJTdHIJAMwIAgUKbmV3QWRkclN0cgkAzAgCBQhncm91cE51bQkAzAgCBQ1wZW5hbHR5QW1vdW50BQNuaWwFA25pbAMJAAACBQlkb1JlcGxhY2UFCWRvUmVwbGFjZQQNb2xkTGVhc2VJZEtleQkBFmdldExlYXNlSWRCeUFkZHJlc3NLZXkBBQpvbGRBZGRyU3RyBA5vbGRMZWFzZUFtdEtleQkBGmdldExlYXNlQW1vdW50QnlBZGRyZXNzS2V5AQUKb2xkQWRkclN0cgQIbGVhc2VBbXQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFDm9sZExlYXNlQW10S2V5BA1uZXdMZWFzZUlkS2V5CQEWZ2V0TGVhc2VJZEJ5QWRkcmVzc0tleQEFCm5ld0FkZHJTdHIEDm5ld0xlYXNlQW10S2V5CQEaZ2V0TGVhc2VBbW91bnRCeUFkZHJlc3NLZXkBBQpuZXdBZGRyU3RyBAhuZXdMZWFzZQkAxAgCCQERQGV4dHJOYXRpdmUoMTA2MikBBQpuZXdBZGRyU3RyBQhsZWFzZUFtdAQVdXBkYXRlZEdyb3VwTm9kZUxpc3RTCQC5CQIJALUJAgUOZ3JvdXBOb2RlTGlzdFMFCm9sZEFkZHJTdHIFCm5ld0FkZHJTdHIJAJQKAgkAzAgCCQELTGVhc2VDYW5jZWwBCQERQGV4dHJOYXRpdmUoMTA1NykBBQ1vbGRMZWFzZUlkS2V5CQDMCAIJAQtEZWxldGVFbnRyeQEFDW9sZExlYXNlSWRLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUOb2xkTGVhc2VBbXRLZXkJAMwIAgkBC1N0cmluZ0VudHJ5AgUIZ3JvdXBLZXkFFXVwZGF0ZWRHcm91cE5vZGVMaXN0UwkAzAgCBQhuZXdMZWFzZQkAzAgCCQELQmluYXJ5RW50cnkCBQ1uZXdMZWFzZUlkS2V5CQEFbGNhbGMBBQhuZXdMZWFzZQkAzAgCCQEMSW50ZWdlckVudHJ5AgUObmV3TGVhc2VBbXRLZXkFCGxlYXNlQW10BQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEfdXBkYXRlUmVzZXJ2ZXNBbmROZXV0cmlub1N1cHBseQAKARZnZXROdW1iZXJCeUtleUludGVybmFsAQNrZXkEByRtYXRjaDAJAJoIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACA0ludAQBYQUHJG1hdGNoMAUBYQAABAduTWV0cml4CQEJYXNBbnlMaXN0AQkA/AcEBQxtYXRoQ29udHJhY3QCGmNhbGNOZXV0aW5vTWV0cmljc1JFQURPTkxZBQNuaWwFA25pbAQDaWR4CQEWZ2V0TnVtYmVyQnlLZXlJbnRlcm5hbAECInVwZGF0ZVJlc2VydmVzQW5kTmV1dHJpbm9TdXBwbHlJZHgEBm5ld0lkeAkAZAIFA2lkeAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCAiJ1cGRhdGVSZXNlcnZlc0FuZE5ldXRyaW5vU3VwcGx5SWR4BQZuZXdJZHgJAMwIAgkBDEludGVnZXJFbnRyeQICB3Jlc2VydmUJAQVhc0ludAEJAJEDAgUHbk1ldHJpeAADCQDMCAIJAQxJbnRlZ2VyRW50cnkCAg5uZXV0cmlub1N1cHBseQkBBWFzSW50AQkAkQMCBQduTWV0cml4AAUJAMwIAgkBDEludGVnZXJFbnRyeQICDnJlc2VydmVzSW5Vc2RuCQEWY29udmVydFdhdmVzVG9OZXV0cmlubwIJAQVhc0ludAEJAJEDAgUHbk1ldHJpeAADCQEFYXNJbnQBCQCRAwIFB25NZXRyaXgAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgIHc3VycGx1cwkBBWFzSW50AQkAkQMCBQduTWV0cml4AAYJAMwIAgkBDEludGVnZXJFbnRyeQICB2RlZmljaXQJAQEtAQkBBWFzSW50AQkAkQMCBQduTWV0cml4AAYFA25pbAFpARZ3YXZlc0JhbGFuY2VzVnNQYXltZW50AAQBYgkA7wcBBQR0aGlzCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhZ3YXZlc0JhbGFuY2VfYXZhaWxhYmxlCAUBYglhdmFpbGFibGUJAMwIAgkBDEludGVnZXJFbnRyeQICFHdhdmVzQmFsYW5jZV9yZWd1bGFyCAUBYgdyZWd1bGFyCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhd3YXZlc0JhbGFuY2VfZ2VuZXJhdGluZwgFAWIKZ2VuZXJhdGluZwkAzAgCCQEMSW50ZWdlckVudHJ5AgIWd2F2ZXNCYWxhbmNlX2VmZmVjdGl2ZQgFAWIJZWZmZWN0aXZlCQDMCAIJAQxJbnRlZ2VyRW50cnkCAg13YXZlc19wYXltZW50CAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAUDbmlsAQJ0eAEGdmVyaWZ5AAQTcHViS2V5QWRtaW5zTGlzdFN0cgkAuQkCCQDMCAICLEV4dEVFSzE5bm1LajltQ3BuV3l2RUVKRllBVExNY1ZFTXZvaGhVSGt5SE5tCQDMCAICLEV2NXB5NUZmQlFYOWNacFlLbmZRclRCNDlCeWY4UW1wWldlRFZSaW00eVY3CQDMCAICLERVdXVMalh1OThuQndaYzdmcXdDVGp0QTNublJ3Z1Ria01TcjVTVTJObURSCQDMCAICLERVdXVMalh1OThuQndaYzdmcXdDVGp0QTNublJ3Z1Ria01TcjVTVTJObURSBQNuaWwFA1NFUAQQcHViS2V5QWRtaW5zTGlzdAkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFD2NvbnRyb2xDb250cmFjdAIMJXNfX211bHRpc2lnBRNwdWJLZXlBZG1pbnNMaXN0U3RyBQNTRVAEBWNvdW50CQBkAgkAZAIJAGQCAwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAkA2QQBCQCRAwIFEHB1YktleUFkbWluc0xpc3QAAAABAAADCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwABCQDZBAEJAJEDAgUQcHViS2V5QWRtaW5zTGlzdAABAAEAAAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAIJANkEAQkAkQMCBRBwdWJLZXlBZG1pbnNMaXN0AAIAAQAAAwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAwkA2QQBCQCRAwIFEHB1YktleUFkbWluc0xpc3QAAwACAAADAwUJaXNCbG9ja2VkCQAAAgkBEUBleHRyTmF0aXZlKDEwNTMpAgUPY29udHJvbENvbnRyYWN0AhFpc19ibG9ja2VkX2NhbGxlcgkApQgBBQtnb3ZDb250cmFjdAcJAQ52YWxpZGF0ZVVwZGF0ZQEFAnR4BAckbWF0Y2gwBQJ0eAMJAAECBQckbWF0Y2gwAhVTcG9uc29yRmVlVHJhbnNhY3Rpb24ECXNwb25zb3JUeAUHJG1hdGNoMAMJARtjaGVja0lzVmFsaWRNaW5TcG9uc29yZWRGZWUBBQlzcG9uc29yVHgJAGcCBQVjb3VudAADBwkAZwIFBWNvdW50AANqQrSZ", "height": 2449302, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: CoBrjfNs95XfyUDq5Y7tZvkNagsgkxdCcYKPrCHjZz5a Next: 9hTC4fZnts2hDPiKz7Cbne6CWauhDcEAKHVJKL4aQ4Fz Diff:
OldNewDifferences
664664 }
665665
666666
667-func calcWithdrawU2Basket (usdnIn,basketInfo,br,reservesInUsdn,neutrinoSupply) = {
668- let brProtected = valueOrElse(getInteger(this, brProtectedKEY()), BRPROTECTED)
669- let maxAllowedUsdnBeforeMinBr = if ((brProtected >= br))
670- then 0
671- else fraction((reservesInUsdn - fraction(brProtected, neutrinoSupply, MULT6)), MULT6, (MULT6 - brProtected))
672- let allowedUsdnBeforeMinBr = if ((usdnIn > maxAllowedUsdnBeforeMinBr))
673- then maxAllowedUsdnBeforeMinBr
674- else usdnIn
675- let allowedUsdnAfterMinBr = if ((usdnIn > maxAllowedUsdnBeforeMinBr))
676- then fraction((usdnIn - maxAllowedUsdnBeforeMinBr), br, MULT6)
677- else 0
678- let allowedUsdn = (allowedUsdnBeforeMinBr + allowedUsdnAfterMinBr)
679- let usdn2SURF = (usdnIn - allowedUsdn)
680- if ((1 == 1))
681- then throw(((((((((("usdnIn=" + toString(usdnIn)) + "mA") + toString(maxAllowedUsdnBeforeMinBr)) + " aBef=") + toString(allowedUsdnBeforeMinBr)) + " aAft=") + toString(allowedUsdnAfterMinBr)) + " allowedUsdn=") + toString(allowedUsdn)))
682- else {
683- let outAmtGross = convertNeutrinoToBasket(allowedUsdn, basketInfo, neutrinoSupply)
684- $Tuple12(outAmtGross._2, unit, usdn2SURF, neutrinoAssetId, outAmtGross._2, outAmtGross._3, allowedUsdn, maxAllowedUsdnBeforeMinBr, allowedUsdnBeforeMinBr, allowedUsdnAfterMinBr, outAmtGross._1, nil)
685- }
667+func calcWithdrawU2Basket (usdnIn,basketInfo,neutrinoSupply) = {
668+ let outAmtGross = convertNeutrinoToBasket(usdnIn, basketInfo, neutrinoSupply)
669+ $Tuple12(outAmtGross._2, unit, 0, neutrinoAssetId, outAmtGross._2, outAmtGross._3, usdnIn, neutrinoSupply, usdnIn, 0, outAmtGross._1, nil)
686670 }
687671
688672
689673 func calcWithdraw (swapType,inAmount,price,neutrinoMetrics,inAsset) = {
690- let brProtected = valueOrElse(getInteger(this, brProtectedKEY()), BRPROTECTED)
691- let BR = asInt(neutrinoMetrics[nMetricIdxBR])
692- let reservesInUsd = asInt(neutrinoMetrics[nMetricTotalReservesUsd])
693674 let neutrinoSupply = asInt(neutrinoMetrics[nMetricIdxUsdnSupply])
694675 let basketInfo = asString(neutrinoMetrics[nMetricBasketInfo])
695676 let weightedPrice = asInt(neutrinoMetrics[nMetricWeightedPrice])
696677 let outDataTuple = if ((swapType == "outNeutrino"))
697678 then calcWithdrawT2U(inAmount, inAsset, basketInfo, weightedPrice)
698679 else if ((swapType == "outMulti"))
699- then calcWithdrawU2Basket(inAmount, basketInfo, BR, reservesInUsd, neutrinoSupply)
680+ then calcWithdrawU2Basket(inAmount, basketInfo, neutrinoSupply)
700681 else throw(("Unsupported swap type " + swapType))
701682 let outAmtGross = outDataTuple._1
702683 let outAssetId = outDataTuple._2
10521033 if ((i.callerPublicKey != mngPub))
10531034 then throw("approveLeasings not authorized")
10541035 else {
1055- let $t04427444336 = readNodeInfo(0)
1056- let nAddr0 = $t04427444336._1
1057- let lAmtKEY0 = $t04427444336._2
1058- let lAmt0 = $t04427444336._3
1059- let lIdKEY0 = $t04427444336._4
1060- let lId0 = $t04427444336._5
1036+ let $t04308643148 = readNodeInfo(0)
1037+ let nAddr0 = $t04308643148._1
1038+ let lAmtKEY0 = $t04308643148._2
1039+ let lAmt0 = $t04308643148._3
1040+ let lIdKEY0 = $t04308643148._4
1041+ let lId0 = $t04308643148._5
10611042 let newL0 = Lease(nAddr0, (lAmt0 - (lAmt * expCount)))
10621043 let validation = invoke(nodeRegAddr, "validateAndApproveLeasings", [nListS], nil)
10631044 if ((validation == validation))
11021083 then throw("rebalanceLeasings not authorized")
11031084 else {
11041085 let unleaseAmt = ((amount / size(nList)) + 1)
1105- let $t04557645638 = readNodeInfo(0)
1106- let nAddr0 = $t04557645638._1
1107- let lAmtKEY0 = $t04557645638._2
1108- let lAmt0 = $t04557645638._3
1109- let lIdKEY0 = $t04557645638._4
1110- let lId0 = $t04557645638._5
1086+ let $t04438844450 = readNodeInfo(0)
1087+ let nAddr0 = $t04438844450._1
1088+ let lAmtKEY0 = $t04438844450._2
1089+ let lAmt0 = $t04438844450._3
1090+ let lIdKEY0 = $t04438844450._4
1091+ let lId0 = $t04438844450._5
11111092 let newL0 = Lease(nAddr0, (lAmt0 + (unleaseAmt * size(nList))))
11121093 func forEachNodeDoUnlease (a,i) = {
11131094 let node = nList[i]
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
55
66
77 func lcalc (l) = calculateLeaseId(l)
88
99
1010 func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
1111
1212
1313 func getStringByKey (key) = valueOrElse(getString(this, key), "")
1414
1515
1616 func getBoolByKey (key) = valueOrElse(getBoolean(this, key), false)
1717
1818
1919 func getNumberByAddressAndKey (address,key) = valueOrElse(getInteger(address, key), 0)
2020
2121
2222 func getStringByAddressAndKey (address,key) = valueOrElse(getString(addressFromStringValue(address), key), "")
2323
2424
2525 func getBoolByAddressAndKey (address,key) = valueOrElse(getBoolean(address, key), false)
2626
2727
2828 func asAnyList (v) = match v {
2929 case l: List[Any] =>
3030 l
3131 case _ =>
3232 throw("fail to cast into List[Any]")
3333 }
3434
3535
3636 func asString (v) = match v {
3737 case s: String =>
3838 s
3939 case _ =>
4040 throw("fail to cast into String")
4141 }
4242
4343
4444 func asInt (v) = match v {
4545 case i: Int =>
4646 i
4747 case _ =>
4848 throw("fail to cast into Int")
4949 }
5050
5151
5252 func asBytes (val) = match val {
5353 case valByte: ByteVector =>
5454 valByte
5555 case _ =>
5656 throw("fail to cast into ByteVector")
5757 }
5858
5959
6060 func asPayment (v) = match v {
6161 case p: AttachedPayment =>
6262 p
6363 case _ =>
6464 throw("fail to cast into AttachedPayment")
6565 }
6666
6767
6868 func asSwapParamsSTRUCT (v) = match v {
6969 case struct: (Int, Int, Int, Int, Int, Int, Int) =>
7070 struct
7171 case _ =>
7272 throw("fail to cast into Tuple5 ints")
7373 }
7474
7575
7676 let SEP = "__"
7777
7878 let LISTSEP = ":"
7979
8080 let MULT8 = 100000000
8181
8282 let MULT6 = 1000000
8383
8484 let DEFAULTSWAPFEE = 20000
8585
8686 let BRPROTECTED = 100000
8787
8888 let WAVESID = base58'WAVES'
8989
9090 let nMetricIdxPrice = 0
9191
9292 let nMetricIdxUsdnLockedBalance = 1
9393
9494 let nMetricIdxWavesLockedBalance = 2
9595
9696 let nMetricIdxReserve = 3
9797
9898 let nMetricIdxReserveInUsdn = 4
9999
100100 let nMetricIdxUsdnSupply = 5
101101
102102 let nMetricIdxSurplus = 6
103103
104104 let nMetricIdxSurplusPercent = 7
105105
106106 let nMetricIdxBR = 8
107107
108108 let nMetricIdxNsbtSupply = 9
109109
110110 let nMetricIdxMaxNsbtSupply = 10
111111
112112 let nMetricIdxSurfSupply = 11
113113
114114 let nMetricUsdnUsdtPeg = 12
115115
116116 let nMetricCurrentPriceAdj = 13
117117
118118 let nMetricBasketInfo = 14
119119
120120 let nMetricWeightedPrice = 15
121121
122122 let nMetricTotalReservesUsd = 16
123123
124124 let IdxControlCfgNeutrinoDapp = 1
125125
126126 let IdxControlCfgAuctionDapp = 2
127127
128128 let IdxControlCfgRpdDapp = 3
129129
130130 let IdxControlCfgMathDapp = 4
131131
132132 let IdxControlCfgLiquidationDapp = 5
133133
134134 let IdxControlCfgRestDapp = 6
135135
136136 let IdxControlCfgNodeRegistryDapp = 7
137137
138138 let IdxControlCfgNsbtStakingDapp = 8
139139
140140 let IdxControlCfgMediatorDapp = 9
141141
142142 let IdxControlCfgSurfStakingDapp = 10
143143
144144 let IdxControlCfgGnsbtControllerDapp = 11
145145
146146 let IdxControlCfgRestV2Dapp = 12
147147
148148 let IdxControlCfgGovernanceDapp = 13
149149
150150 func keyControlAddress () = "%s%s__config__controlAddress"
151151
152152
153153 func keyControlCfg () = "%s__controlConfig"
154154
155155
156156 func readControlCfgOrFail (control) = split_4C(getStringOrFail(control, keyControlCfg()), SEP)
157157
158158
159159 func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
160160
161161
162162 let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3N4NS7d4Jo9a6F14LiFUKKYVdUkkf2eP4Zx"))
163163
164164 let controlCfg = readControlCfgOrFail(controlContract)
165165
166166 let mathContract = getContractAddressOrFail(controlCfg, IdxControlCfgMathDapp)
167167
168168 let nsbtStakingContract = getContractAddressOrFail(controlCfg, IdxControlCfgNsbtStakingDapp)
169169
170170 let surfStakingContract = getContractAddressOrFail(controlCfg, IdxControlCfgSurfStakingDapp)
171171
172172 let gnsbtControllerContract = getContractAddressOrFail(controlCfg, IdxControlCfgGnsbtControllerDapp)
173173
174174 let auctionContract = getContractAddressOrFail(controlCfg, IdxControlCfgAuctionDapp)
175175
176176 let nodeRegistryContract = getContractAddressOrFail(controlCfg, IdxControlCfgNodeRegistryDapp)
177177
178178 let govContract = getContractAddressOrFail(controlCfg, IdxControlCfgGovernanceDapp)
179179
180180 let NeutrinoAssetIdKey = "neutrino_asset_id"
181181
182182 let BondAssetIdKey = "bond_asset_id"
183183
184184 let AuctionContractKey = "auction_contract"
185185
186186 let NsbtStakingContractKey = "nsbtStakingContract"
187187
188188 let LiquidationContractKey = "liquidation_contract"
189189
190190 let RPDContractKey = "rpd_contract"
191191
192192 let ContolContractKey = "control_contract"
193193
194194 let MathContractKey = "math_contract"
195195
196196 let BalanceWavesLockIntervalKey = "balance_waves_lock_interval"
197197
198198 let BalanceNeutrinoLockIntervalKey = "balance_neutrino_lock_interval"
199199
200200 func MinTokenSwapAmountKey (assetId) = ("min_outNeutrino_swap_amount_" + assetId)
201201
202202
203203 let MinNeutrinoSwapAmountKey = "min_outMulti_swap_amount"
204204
205205 let NodeOracleProviderPubKeyKey = "node_oracle_provider"
206206
207207 let NeutrinoOutFeePartKey = "neutrinoOut_swap_feePart"
208208
209209 let WavesOutFeePartKey = "wavesOut_swap_feePart"
210210
211211 func keyNodeRegistry (address) = ("%s__" + address)
212212
213213
214214 let PriceKey = "price"
215215
216216 let PriceIndexKey = "price_index"
217217
218218 let IsBlockedKey = "is_blocked"
219219
220220 func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block))
221221
222222
223223 func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
224224
225225
226226 func getStakingNodeByIndex (idx) = getStringByKey(makeString(["%s%d%s", "lease", toString(idx), "nodeAddress"], SEP))
227227
228228
229229 func getStakingNodeAddressByIndex (idx) = addressFromStringValue(getStakingNodeByIndex(idx))
230230
231231
232232 func getReservedAmountForSponsorship () = valueOrElse(getInteger(this, makeString(["%s%s", "lease", "sponsorshipWavesReserve"], SEP)), (1000 * MULT8))
233233
234234
235235 func getBalanceUnlockBlockKey (owner) = ("balance_unlock_block_" + owner)
236236
237237
238238 func getLeaseIdKey (nodeIndex) = makeString(["%s%d%s", "lease", toString(nodeIndex), "id"], SEP)
239239
240240
241241 func getLeaseIdByAddressKey (nodeAddress) = makeString(["%s%s%s", "leaseByAddress", nodeAddress, "id"], SEP)
242242
243243
244244 func getLeaseAmountKey (nodeIndex) = makeString(["%s%d%s", "lease", toString(nodeIndex), "amount"], SEP)
245245
246246
247247 func getLeaseAmountByAddressKey (nodeAddress) = makeString(["%s%s%s", "leaseByAddress", nodeAddress, "amount"], SEP)
248248
249249
250250 func getLeaseGroupNodeListKey (groupNum) = makeString(["%s%d%s", "leaseGroup", toString(groupNum), "nodeList"], SEP)
251251
252252
253253 func minSwapAmountKEY (swapType) = (("min_" + swapType) + "_swap_amount")
254254
255255
256256 func totalLockedKEY (swapType,assetId) = makeString(["%s%s%s", "balanceLock", swapType, assetId], SEP)
257257
258258
259259 func totalLockedByUserKEY (swapType,owner,assetId) = makeString(["%s%s%s%s", "balanceLock", swapType, owner, assetId], "_")
260260
261261
262262 func balanceLockIntervalKEY (swapType) = if ((swapType == "outMulti"))
263263 then BalanceNeutrinoLockIntervalKey
264264 else BalanceWavesLockIntervalKey
265265
266266
267267 func nodeBalanceLockIntervalKEY () = "balance_node_lock_interval"
268268
269269
270270 func swapsTimeframeKEY () = "swaps_timeframe"
271271
272272
273273 func brProtectedKEY () = "min_BR_protection_level"
274274
275275
276276 func basketAssetsKey () = "%s%s__common__basketAssets"
277277
278278
279279 func basketDKey () = "%s%s__common__basketD"
280280
281281
282282 func basketKKey () = "%s%s__common__basketK"
283283
284284
285285 func basketBKey () = "%s%s__common__basketB"
286286
287287
288288 func basketLogbDeltaKey () = "%s%s__common__basketLogbDelta"
289289
290290
291291 func basketWeightByAssetKey (assetId) = ("%s%s%s__common__weightByAsset__" + assetId)
292292
293293
294294 func minSwapAmountREAD (swapType,assetId) = valueOrElse(if ((swapType == "outMulti"))
295295 then getInteger(MinNeutrinoSwapAmountKey)
296296 else getInteger(MinTokenSwapAmountKey(assetId)), 0)
297297
298298
299299 func swapsTimeframeREAD () = valueOrElse(getInteger(this, swapsTimeframeKEY()), 1440)
300300
301301
302302 func totalLockedREAD (swapType,assetId) = valueOrElse(getInteger(this, totalLockedKEY(swapType, assetId)), 0)
303303
304304
305305 func totalLockedByUserREAD (swapType,owner,assetId) = valueOrElse(getInteger(this, totalLockedByUserKEY(swapType, owner, assetId)), 0)
306306
307307
308308 func balanceLockIntervalREAD (swapType) = valueOrElse(getInteger(this, balanceLockIntervalKEY(swapType)), 1440)
309309
310310
311311 func nodeBalanceLockIntervalREAD () = valueOrElse(getInteger(this, nodeBalanceLockIntervalKEY()), 1)
312312
313313
314314 func keySwapUserSpentInPeriod (userAddress) = makeString(["%s%s", "swapUserSpentInPeriod", userAddress], SEP)
315315
316316
317317 func keyUserLastSwapHeight (userAddress) = makeString(["%s%s", "userLastSwapHeight", userAddress], SEP)
318318
319319
320320 func convertNeutrinoToWaves (amount,price) = fraction(amount, MULT8, price)
321321
322322
323323 func convertWavesToNeutrino (amount,price) = fraction(amount, price, MULT8)
324324
325325
326326 func convertWavesToBond (amount,price) = convertWavesToNeutrino(amount, price)
327327
328328
329329 func convertJsonArrayToList (jsonArray) = split(jsonArray, ",")
330330
331331
332332 func convertBasketItemToNeutrino (inAmount,inAsset,basketInfoStr,neutrinoPrice) = {
333333 let basketInfo = split(basketInfoStr, "_")
334334 func findItem (acc,item) = {
335335 let bItem = split(item, LISTSEP)
336336 if ((bItem[0] == inAsset))
337337 then bItem
338338 else acc
339339 }
340340
341341 let it = {
342342 let $l = basketInfo
343343 let $s = size($l)
344344 let $acc0 = nil
345345 func $f0_1 ($a,$i) = if (($i >= $s))
346346 then $a
347347 else findItem($a, $l[$i])
348348
349349 func $f0_2 ($a,$i) = if (($i >= $s))
350350 then $a
351351 else throw("List size exceeds 10")
352352
353353 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
354354 }
355355 let dlog6 = valueOrElse(getInteger(basketLogbDeltaKey()), -18820642)
356356 let d6 = valueOrElse(getInteger(basketDKey()), 50000)
357357 let b6 = valueOrElse(getInteger(basketBKey()), 1250000)
358358 let w6 = valueOrElse(getInteger(basketWeightByAssetKey(inAsset)), 166666)
359359 let p6 = ((dlog6 - w6) + parseIntValue(it[1]))
360360 let pp6 = pow(b6, 6, p6, 6, 6, HALFUP)
361361 let outAmountGross = fraction(inAmount, parseIntValue(it[2]), if ((neutrinoPrice == 0))
362362 then MULT8
363363 else (neutrinoPrice * 100))
364364 let multiplier = ((MULT6 + d6) - pp6)
365365 let netAmount = fraction(outAmountGross, multiplier, MULT6)
366366 let feeAmount = if ((netAmount >= outAmountGross))
367367 then 0
368368 else (outAmountGross - netAmount)
369369 [outAmountGross, netAmount, feeAmount]
370370 }
371371
372372
373373 func convertNeutrinoToBasket (amount,basketInfoStr,neutrinoSupply) = {
374374 let basketInfo = split(basketInfoStr, "_")
375375 func conv (acc,item) = {
376376 let parts = split(item, LISTSEP)
377377 let assetId = parts[0]
378378 let share = parseIntValue(parts[1])
379379 let price = parseIntValue(parts[2])
380380 let reserv = parseIntValue(parts[3])
381381 if ((neutrinoSupply == 0))
382382 then throw("Attempt to burn neutrino at zero supply")
383383 else {
384384 let outAmount = fraction(amount, reserv, neutrinoSupply)
385385 let wavesTuple = if ((assetId == "WAVES"))
386386 then $Tuple2(outAmount, price)
387387 else $Tuple2(acc._2, acc._3)
388388 $Tuple3((acc._1 :+ $Tuple4(assetId, outAmount, price, share)), wavesTuple._1, wavesTuple._2)
389389 }
390390 }
391391
392392 let $l = basketInfo
393393 let $s = size($l)
394394 let $acc0 = $Tuple3(nil, 0, 0)
395395 func $f0_1 ($a,$i) = if (($i >= $s))
396396 then $a
397397 else conv($a, $l[$i])
398398
399399 func $f0_2 ($a,$i) = if (($i >= $s))
400400 then $a
401401 else throw("List size exceeds 10")
402402
403403 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
404404 }
405405
406406
407407 func minSwapAmountFAIL (swapType,minSwapAmount) = throw(((("The specified amount in " + swapType) + " swap is less than the required minimum of ") + toString(minSwapAmount)))
408408
409409
410410 func emergencyShutdownFAIL () = throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
411411
412412
413413 func priceIndexFAIL (index,priceIndex,indexHeight,unlockHeight,prevIndexHeight) = throw(((((((((("invalid price history index: index=" + toString(index)) + " priceIndex=") + toString(priceIndex)) + " indexHeight=") + toString(indexHeight)) + " unlockHeight=") + toString(unlockHeight)) + " prevIndexHeight=") + toString(prevIndexHeight)))
414414
415415
416416 let neutrinoAssetId = fromBase58String(getStringByKey(NeutrinoAssetIdKey))
417417
418418 let priceIndex = getNumberByAddressAndKey(controlContract, PriceIndexKey)
419419
420420 let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey)
421421
422422 let nodeOracleProviderPubKey = fromBase58String(getStringByKey(NodeOracleProviderPubKeyKey))
423423
424424 let bondAssetId = fromBase58String("F3iaxzruFeKujfVfYSZEkejpjh67wmRfPCRHiNmWKp3Z")
425425
426426 let deprecatedBondAssetId = fromBase58String("975akZBfnMj513U7MZaHKzQrmsEx5aE3wdWKTrHBhbjF")
427427
428428 let neutrinoContract = this
429429
430430 let currentPrice = getNumberByAddressAndKey(controlContract, PriceKey)
431431
432432 func checkIsValidMinSponsoredFee (tx) = {
433433 let MINTRANSFERFEE = 100000
434434 let SponsoredFeeUpperBound = 1000
435435 let realNeutrinoFee = convertWavesToNeutrino(MINTRANSFERFEE, currentPrice)
436436 let minNeutrinoFee = (realNeutrinoFee * 2)
437437 let maxNeutrinoFee = fraction(realNeutrinoFee, SponsoredFeeUpperBound, 100)
438438 let inputFee = value(tx.minSponsoredAssetFee)
439439 if (if ((inputFee >= minNeutrinoFee))
440440 then (maxNeutrinoFee >= inputFee)
441441 else false)
442442 then (tx.assetId == neutrinoAssetId)
443443 else false
444444 }
445445
446446
447447 func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block))
448448
449449
450450 func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index))
451451
452452
453453 func keyLockParamUserAmount (userAddress) = makeString(["%s%s%s", "paramByUser", userAddress, "amount"], SEP)
454454
455455
456456 let sIdxSwapType = 1
457457
458458 let sIdxStatus = 2
459459
460460 let sIdxInAmount = 3
461461
462462 let sIdxStartHeight = 7
463463
464464 let sIdxStartTimestamp = 8
465465
466466 let sIdxSelfUnlockHeight = 11
467467
468468 let sIdxMinRand = 15
469469
470470 let sIdxMaxRand = 16
471471
472472 let sIdxInAsset = 20
473473
474474 func swapKEY (userAddress,txId) = makeString(["%s%s", userAddress, txId], SEP)
475475
476476
477477 func strSwapDATA (swapType,status,inAmount,price,outNetAmount,outFeeAmount,startHeight,startTimestamp,endHeight,endTimestamp,selfUnlockHeight,randUnlockHeight,index,withdrawTxId,randMin,randMax,outSurfAmt,br,basketData,inAsset) = makeString(["%s%s%d%d%d%d%d%d%d%d%d%d%d%s%d%d%d%d%s%s", swapType, status, inAmount, price, outNetAmount, outFeeAmount, startHeight, startTimestamp, endHeight, endTimestamp, selfUnlockHeight, randUnlockHeight, index, withdrawTxId, randMin, randMax, outSurfAmt, br, basketData, inAsset], SEP)
478478
479479
480480 func pendingSwapDATA (swapType,inAssetAmount,selfUnlockHeight,inAsset) = strSwapDATA(swapType, "PENDING", toString(inAssetAmount), "0", "0", "0", toString(height), toString(lastBlock.timestamp), "0", "0", toString(selfUnlockHeight), "0", "0", "NULL", "0", "0", "0", "0", "", inAsset)
481481
482482
483483 func finishSwapDATA (dataArray,price,outNetAmount,outFeeAmount,randUnlockHeight,index,withdrawTxId,outSurfAmt,br,basketData,inAsset) = strSwapDATA(dataArray[sIdxSwapType], "FINISHED", dataArray[sIdxInAmount], toString(price), toString(outNetAmount), toString(outFeeAmount), dataArray[sIdxStartHeight], dataArray[sIdxStartTimestamp], toString(height), toString(lastBlock.timestamp), dataArray[sIdxSelfUnlockHeight], toString(randUnlockHeight), toString(index), withdrawTxId, dataArray[sIdxMinRand], dataArray[sIdxMaxRand], toString(outSurfAmt), toString(br), basketData, inAsset)
484484
485485
486486 func swapDataFailOrREAD (userAddress,swapTxId) = {
487487 let swapKey = swapKEY(userAddress, swapTxId)
488488 split_4C(valueOrErrorMessage(getString(swapKey), ("no swap data for " + swapKey)), SEP)
489489 }
490490
491491
492492 func applyFees (amountOutGross,inAmtToSURF,feePart) = {
493493 let feeAmount = fraction(amountOutGross, feePart, MULT6)
494494 [(amountOutGross - feeAmount), feeAmount]
495495 }
496496
497497
498498 func applyFeesBasket (basketOut) = {
499499 let k6 = valueOrElse(getInteger(basketKKey()), MULT6)
500500 let d6 = valueOrElse(getInteger(basketDKey()), 50000)
501501 let feePart = fraction(k6, d6, MULT6)
502502 func feeApplier (acc,item) = {
503503 let feeAmount = fraction(item._2, feePart, MULT6)
504504 (acc :+ makeString([item._1, toString(item._3), toString((item._2 - feeAmount)), toString(feeAmount), toString(item._4)], LISTSEP))
505505 }
506506
507507 let a = {
508508 let $l = basketOut
509509 let $s = size($l)
510510 let $acc0 = nil
511511 func $f0_1 ($a,$i) = if (($i >= $s))
512512 then $a
513513 else feeApplier($a, $l[$i])
514514
515515 func $f0_2 ($a,$i) = if (($i >= $s))
516516 then $a
517517 else throw("List size exceeds 10")
518518
519519 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
520520 }
521521 makeString(a, SEP)
522522 }
523523
524524
525525 func abs (x) = if ((0 > x))
526526 then -(x)
527527 else x
528528
529529
530530 func selectNode (unleaseAmount) = {
531531 let amountToLease = ((wavesBalance(neutrinoContract).available - unleaseAmount) - getReservedAmountForSponsorship())
532532 let oldLeased0 = getNumberByKey(getLeaseAmountKey(0))
533533 let oldLeased1 = getNumberByKey(getLeaseAmountKey(1))
534534 let newLeased0 = (amountToLease + oldLeased0)
535535 let newLeased1 = (amountToLease + oldLeased1)
536536 if (if ((newLeased0 > 0))
537537 then true
538538 else (newLeased1 > 0))
539539 then {
540540 let delta0 = abs((newLeased0 - oldLeased1))
541541 let delta1 = abs((newLeased1 - oldLeased0))
542542 if ((delta1 >= delta0))
543543 then $Tuple2(0, newLeased0)
544544 else $Tuple2(1, newLeased1)
545545 }
546546 else $Tuple2(-1, 0)
547547 }
548548
549549
550550 func thisOnly (i) = if ((i.caller != this))
551551 then throw("Permission denied: this contract only allowed")
552552 else true
553553
554554
555555 func prepareUnleaseAndLease (unleaseAmount) = {
556556 let nodeTuple = selectNode(unleaseAmount)
557557 let nodeIndex = nodeTuple._1
558558 let newLeaseAmount = nodeTuple._2
559559 if ((newLeaseAmount > 0))
560560 then {
561561 let leaseIdKey = getLeaseIdKey(nodeIndex)
562562 let oldLease = getBinary(this, leaseIdKey)
563563 let unleaseOrEmpty = if (isDefined(oldLease))
564564 then [LeaseCancel(value(oldLease))]
565565 else nil
566566 let leaseAmountKey = getLeaseAmountKey(nodeIndex)
567567 let lease = Lease(getStakingNodeAddressByIndex(nodeIndex), newLeaseAmount)
568568 (unleaseOrEmpty ++ [lease, BinaryEntry(leaseIdKey, lcalc(lease)), IntegerEntry(getLeaseAmountKey(nodeIndex), newLeaseAmount)])
569569 }
570570 else nil
571571 }
572572
573573
574574 func readNodeInfo (nodeIdx) = {
575575 let nodeAddress = getStakingNodeAddressByIndex(nodeIdx)
576576 let leasedAmtKEY = getLeaseAmountKey(nodeIdx)
577577 let leasedAmt = getNumberByKey(leasedAmtKEY)
578578 let leaseIdKEY = getLeaseIdKey(nodeIdx)
579579 let leaseId = value(getBinary(this, leaseIdKEY))
580580 $Tuple5(nodeAddress, leasedAmtKEY, leasedAmt, leaseIdKEY, leaseId)
581581 }
582582
583583
584584 func commonSwap (swapType,pmtAmount,inAsset,userAddressStr,txId58) = {
585585 let swapParamsSTRUCT = asSwapParamsSTRUCT(invoke(this, "swapParamsByUserSYSREADONLY", [userAddressStr, 0], nil))
586586 let swapLimitSpent = swapParamsSTRUCT._2
587587 let blcks2LmtReset = swapParamsSTRUCT._3
588588 let wavesSwapLimitMax = swapParamsSTRUCT._6
589589 let usdnSwapLimitMax = swapParamsSTRUCT._7
590590 let minSwapAmount = minSwapAmountREAD(swapType, inAsset)
591591 let totalLocked = totalLockedREAD(swapType, inAsset)
592592 let totalLockedByUser = totalLockedByUserREAD(swapType, userAddressStr, inAsset)
593593 let nodeAddress = getStakingNodeByIndex(0)
594594 let priceByIndex = getPriceHistory(getHeightPriceByIndex(priceIndex))
595595 let isSwapByNode = (nodeAddress == userAddressStr)
596596 let balanceLockMaxInterval = if (isSwapByNode)
597597 then nodeBalanceLockIntervalREAD()
598598 else balanceLockIntervalREAD(swapType)
599599 let selfUnlockHeight = (height + balanceLockMaxInterval)
600600 let swapUsdnVolume = if ((swapType == "outNeutrino"))
601601 then convertWavesToNeutrino(pmtAmount, priceByIndex)
602602 else pmtAmount
603603 let swapLimitMax = if ((swapType == "outNeutrino"))
604604 then convertWavesToNeutrino(wavesSwapLimitMax, priceByIndex)
605605 else usdnSwapLimitMax
606606 if ((minSwapAmount > pmtAmount))
607607 then minSwapAmountFAIL(swapType, minSwapAmount)
608608 else if (if (!(isSwapByNode))
609609 then (swapLimitSpent > 0)
610610 else false)
611611 then throw(("You have exceeded swap limit! Next allowed swap height is " + toString((height + blcks2LmtReset))))
612612 else if (if (!(isSwapByNode))
613613 then (swapUsdnVolume > swapLimitMax)
614614 else false)
615615 then throw(((("You have exceeded your swap limit! Requested: " + toString(swapUsdnVolume)) + ", available: ") + toString(swapLimitMax)))
616616 else if (isBlocked)
617617 then emergencyShutdownFAIL()
618618 else {
619619 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
620620 let basketInfo = asString(neutrinoMetrics[nMetricBasketInfo])
621621 let weightedPrice = asInt(neutrinoMetrics[nMetricWeightedPrice])
622622 let out = convertBasketItemToNeutrino(pmtAmount, inAsset, basketInfo, weightedPrice)
623623 if (if ((swapType == "outNeutrino"))
624624 then (0 >= out[1])
625625 else false)
626626 then throw((((((("Net amount is non-positive, cannot swap. (gross, net, fee) = (" + toString(out[0])) + ", ") + toString(out[1])) + ", ") + toString(out[2])) + ")"))
627627 else {
628628 let leasePart = if (if ((swapType == "outNeutrino"))
629629 then (inAsset == "WAVES")
630630 else false)
631631 then prepareUnleaseAndLease(0)
632632 else nil
633633 $Tuple2(([IntegerEntry(keySwapUserSpentInPeriod(userAddressStr), swapUsdnVolume), IntegerEntry(keyUserLastSwapHeight(userAddressStr), height), IntegerEntry(totalLockedByUserKEY(swapType, userAddressStr, inAsset), (totalLockedByUser + pmtAmount)), IntegerEntry(getBalanceUnlockBlockKey(userAddressStr), selfUnlockHeight), IntegerEntry(totalLockedKEY(swapType, inAsset), (totalLocked + pmtAmount)), StringEntry(swapKEY(userAddressStr, txId58), pendingSwapDATA(swapType, pmtAmount, selfUnlockHeight, inAsset))] ++ leasePart), unit)
634634 }
635635 }
636636 }
637637
638638
639639 let bFuncIdxSurf = 0
640640
641641 let bFuncIdxWaves = 1
642642
643643 let bFuncIdxUsdn = 2
644644
645645 let bFuncIdxReserveStart = 3
646646
647647 let bFuncIdxSupplyStart = 4
648648
649649 let bFuncIdxBRStart = 5
650650
651651 let bFuncIdxReserveEnd = 6
652652
653653 let bFuncIdxSupplyEnd = 7
654654
655655 let bFuncIdxBREnd = 8
656656
657657 let bFuncIdxRest = 9
658658
659659 let bFuncIdxWavesPrice = 10
660660
661661 func calcWithdrawT2U (inAmount,inAsset,basketInfo,weightedPrice) = {
662662 let outAmt = convertBasketItemToNeutrino(inAmount, inAsset, basketInfo, weightedPrice)
663663 $Tuple12(outAmt[0], neutrinoAssetId, 0, inAsset, 0, weightedPrice, inAmount, 0, 0, 0, nil, [outAmt[1], outAmt[2]])
664664 }
665665
666666
667-func calcWithdrawU2Basket (usdnIn,basketInfo,br,reservesInUsdn,neutrinoSupply) = {
668- let brProtected = valueOrElse(getInteger(this, brProtectedKEY()), BRPROTECTED)
669- let maxAllowedUsdnBeforeMinBr = if ((brProtected >= br))
670- then 0
671- else fraction((reservesInUsdn - fraction(brProtected, neutrinoSupply, MULT6)), MULT6, (MULT6 - brProtected))
672- let allowedUsdnBeforeMinBr = if ((usdnIn > maxAllowedUsdnBeforeMinBr))
673- then maxAllowedUsdnBeforeMinBr
674- else usdnIn
675- let allowedUsdnAfterMinBr = if ((usdnIn > maxAllowedUsdnBeforeMinBr))
676- then fraction((usdnIn - maxAllowedUsdnBeforeMinBr), br, MULT6)
677- else 0
678- let allowedUsdn = (allowedUsdnBeforeMinBr + allowedUsdnAfterMinBr)
679- let usdn2SURF = (usdnIn - allowedUsdn)
680- if ((1 == 1))
681- then throw(((((((((("usdnIn=" + toString(usdnIn)) + "mA") + toString(maxAllowedUsdnBeforeMinBr)) + " aBef=") + toString(allowedUsdnBeforeMinBr)) + " aAft=") + toString(allowedUsdnAfterMinBr)) + " allowedUsdn=") + toString(allowedUsdn)))
682- else {
683- let outAmtGross = convertNeutrinoToBasket(allowedUsdn, basketInfo, neutrinoSupply)
684- $Tuple12(outAmtGross._2, unit, usdn2SURF, neutrinoAssetId, outAmtGross._2, outAmtGross._3, allowedUsdn, maxAllowedUsdnBeforeMinBr, allowedUsdnBeforeMinBr, allowedUsdnAfterMinBr, outAmtGross._1, nil)
685- }
667+func calcWithdrawU2Basket (usdnIn,basketInfo,neutrinoSupply) = {
668+ let outAmtGross = convertNeutrinoToBasket(usdnIn, basketInfo, neutrinoSupply)
669+ $Tuple12(outAmtGross._2, unit, 0, neutrinoAssetId, outAmtGross._2, outAmtGross._3, usdnIn, neutrinoSupply, usdnIn, 0, outAmtGross._1, nil)
686670 }
687671
688672
689673 func calcWithdraw (swapType,inAmount,price,neutrinoMetrics,inAsset) = {
690- let brProtected = valueOrElse(getInteger(this, brProtectedKEY()), BRPROTECTED)
691- let BR = asInt(neutrinoMetrics[nMetricIdxBR])
692- let reservesInUsd = asInt(neutrinoMetrics[nMetricTotalReservesUsd])
693674 let neutrinoSupply = asInt(neutrinoMetrics[nMetricIdxUsdnSupply])
694675 let basketInfo = asString(neutrinoMetrics[nMetricBasketInfo])
695676 let weightedPrice = asInt(neutrinoMetrics[nMetricWeightedPrice])
696677 let outDataTuple = if ((swapType == "outNeutrino"))
697678 then calcWithdrawT2U(inAmount, inAsset, basketInfo, weightedPrice)
698679 else if ((swapType == "outMulti"))
699- then calcWithdrawU2Basket(inAmount, basketInfo, BR, reservesInUsd, neutrinoSupply)
680+ then calcWithdrawU2Basket(inAmount, basketInfo, neutrinoSupply)
700681 else throw(("Unsupported swap type " + swapType))
701682 let outAmtGross = outDataTuple._1
702683 let outAssetId = outDataTuple._2
703684 let inAmtToSurfPart = outDataTuple._3
704685 let inAssetId = outDataTuple._4
705686 let unleaseAmt = outDataTuple._5
706687 let withdrawPrice = outDataTuple._6
707688 let basketData = outDataTuple._11
708689 let netFeeData = outDataTuple._12
709690 let outNetAmt = if ((swapType == "outNeutrino"))
710691 then netFeeData[0]
711692 else 0
712693 let outFeeAmt = if ((swapType == "outNeutrino"))
713694 then netFeeData[1]
714695 else 0
715696 let outSurfAmt = if ((0 >= inAmtToSurfPart))
716697 then 0
717698 else asInt(asAnyList(invoke(mathContract, "surfFunctionREADONLY", [inAmtToSurfPart, inAssetId], nil))[bFuncIdxSurf])
718699 let withdrawBasket = if ((swapType == "outMulti"))
719700 then applyFeesBasket(basketData)
720701 else ""
721702 $Tuple9(outNetAmt, outAssetId, outSurfAmt, inAmtToSurfPart, unleaseAmt, outFeeAmt, outAmtGross, withdrawPrice, withdrawBasket)
722703 }
723704
724705
725706 func keyApplyInProgress () = "%s__applyInProgress"
726707
727708
728709 func keyProposalDataById (proposalId) = ("%s%d__proposalData__" + toString(proposalId))
729710
730711
731712 let govIdxTxIds = 9
732713
733714 func validateUpdate (tx) = match tx {
734715 case o: Order =>
735716 throw("Orders aren't allowed")
736717 case t: DataTransaction|SponsorFeeTransaction|SetScriptTransaction|CreateAliasTransaction|LeaseCancelTransaction|LeaseTransaction|IssueTransaction|InvokeExpressionTransaction|UpdateAssetInfoTransaction|InvokeScriptTransaction|SetAssetScriptTransaction|TransferTransaction|ExchangeTransaction|MassTransferTransaction|BurnTransaction|ReissueTransaction =>
737718 let txId = toBase58String(t.id)
738719 let proposalId = valueOrErrorMessage(getInteger(govContract, keyApplyInProgress()), "Apply is not happening")
739720 let txList = split(split(getStringOrFail(govContract, keyProposalDataById(proposalId)), SEP)[govIdxTxIds], LISTSEP)
740721 if (!(isDefined(indexOf(txList, txId))))
741722 then throw(((("Unknown txId: " + txId) + " for proposalId=") + toString(proposalId)))
742723 else true
743724 case _ =>
744725 throw("Match error")
745726 }
746727
747728
748729 @Callable(i)
749730 func constructorV1 (neutrinoAssetIdPrm,bondAssetIdPrm,auctionContractPrm,liquidationContractPrm,rpdContractPrm,nodeOracleProviderPubKeyPrm,balanceWavesLockIntervalPrm,balanceNeutrinoLockIntervalPrm,minWavesSwapAmountPrm,minNeutrinoSwapAmountPrm,neutrinoOutFeePartPrm,wavesOutFeePartPrm) = {
750731 let checkCaller = thisOnly(i)
751732 if ((checkCaller == checkCaller))
752733 then if ((size(i.payments) != 0))
753734 then throw("no payments allowed")
754735 else [StringEntry(NeutrinoAssetIdKey, neutrinoAssetIdPrm), StringEntry(BondAssetIdKey, bondAssetIdPrm), StringEntry(AuctionContractKey, auctionContractPrm), StringEntry(LiquidationContractKey, liquidationContractPrm), StringEntry(RPDContractKey, rpdContractPrm), StringEntry(NodeOracleProviderPubKeyKey, nodeOracleProviderPubKeyPrm), IntegerEntry(BalanceWavesLockIntervalKey, balanceWavesLockIntervalPrm), IntegerEntry(BalanceNeutrinoLockIntervalKey, balanceNeutrinoLockIntervalPrm), IntegerEntry(MinTokenSwapAmountKey("WAVES"), minWavesSwapAmountPrm), IntegerEntry(MinNeutrinoSwapAmountKey, minNeutrinoSwapAmountPrm), IntegerEntry(NeutrinoOutFeePartKey, neutrinoOutFeePartPrm), IntegerEntry(WavesOutFeePartKey, wavesOutFeePartPrm)]
755736 else throw("Strict value is not equal to itself.")
756737 }
757738
758739
759740
760741 @Callable(i)
761742 func constructorV2 (mathContract,nsbtStakingContract,swapsTimeframeBlocks) = {
762743 let checkCaller = thisOnly(i)
763744 if ((checkCaller == checkCaller))
764745 then if ((size(i.payments) != 0))
765746 then throw("no payments allowed")
766747 else [StringEntry(MathContractKey, mathContract), StringEntry(NsbtStakingContractKey, nsbtStakingContract), IntegerEntry(swapsTimeframeKEY(), swapsTimeframeBlocks)]
767748 else throw("Strict value is not equal to itself.")
768749 }
769750
770751
771752
772753 @Callable(i)
773754 func constructorV3 (assetsWeightsMins,dParam,kParam,bParam,deltaParam) = {
774755 let checkCaller = thisOnly(i)
775756 if ((checkCaller == checkCaller))
776757 then if ((size(i.payments) != 0))
777758 then throw("no payments allowed")
778759 else {
779760 func prepare (acc,item) = {
780761 let parts = split(item, "_")
781762 let assetId = parts[0]
782763 let weight = parseIntValue(parts[1])
783764 let minVal = parseIntValue(parts[2])
784765 $Tuple2((acc._1 :+ assetId), ((acc._2 :+ IntegerEntry(basketWeightByAssetKey(assetId), weight)) :+ IntegerEntry(MinTokenSwapAmountKey(assetId), minVal)))
785766 }
786767
787768 let r = {
788769 let $l = assetsWeightsMins
789770 let $s = size($l)
790771 let $acc0 = $Tuple2(nil, nil)
791772 func $f0_1 ($a,$i) = if (($i >= $s))
792773 then $a
793774 else prepare($a, $l[$i])
794775
795776 func $f0_2 ($a,$i) = if (($i >= $s))
796777 then $a
797778 else throw("List size exceeds 10")
798779
799780 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
800781 }
801782 (((((r._2 :+ IntegerEntry(basketDKey(), dParam)) :+ IntegerEntry(basketKKey(), kParam)) :+ IntegerEntry(basketBKey(), bParam)) :+ IntegerEntry(basketLogbDeltaKey(), log(deltaParam, 6, bParam, 6, 6, HALFUP))) :+ StringEntry(basketAssetsKey(), makeString(r._1, SEP)))
802783 }
803784 else throw("Strict value is not equal to itself.")
804785 }
805786
806787
807788
808789 @Callable(i)
809790 func swapTokenToNeutrino () = if ((size(i.payments) != 1))
810791 then throw("swapTokenToNeutrino require only one payment")
811792 else {
812793 let pmt = value(i.payments[0])
813794 let basketAssets = valueOrElse(getString(basketAssetsKey()), "WAVES")
814795 let pmtAssetIdStr = toBase58String(valueOrElse(pmt.assetId, WAVESID))
815796 if (!(contains(basketAssets, pmtAssetIdStr)))
816797 then throw(((pmtAssetIdStr + " is not one of basket tokens:") + basketAssets))
817798 else {
818799 let userAddress = toString(i.caller)
819800 let txId58 = toBase58String(i.transactionId)
820801 commonSwap("outNeutrino", pmt.amount, pmtAssetIdStr, userAddress, txId58)
821802 }
822803 }
823804
824805
825806
826807 @Callable(i)
827808 func swapNeutrinoToBasket () = if ((size(i.payments) != 1))
828809 then throw("swapNeutrinoToBasket require only one payment")
829810 else {
830811 let pmt = value(i.payments[0])
831812 if ((pmt.assetId != neutrinoAssetId))
832813 then throw("Only appropriate Neutrino tokens are allowed for swapping.")
833814 else {
834815 let userAddress = toString(i.caller)
835816 let txId58 = toBase58String(i.transactionId)
836817 commonSwap("outMulti", pmt.amount, toBase58String(neutrinoAssetId), userAddress, txId58)
837818 }
838819 }
839820
840821
841822
842823 @Callable(i)
843824 func withdraw (account,index,swapTxId) = {
844825 let txId = toBase58String(i.transactionId)
845826 if ((size(i.payments) != 0))
846827 then throw("no payments allowed")
847828 else {
848829 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
849830 let BR = asInt(neutrinoMetrics[nMetricIdxBR])
850831 let userAddress = addressFromStringValue(account)
851832 let dataArray = swapDataFailOrREAD(account, swapTxId)
852833 let selfUnlockHeight = parseIntValue(dataArray[sIdxSelfUnlockHeight])
853834 let swapType = dataArray[sIdxSwapType]
854835 let inAmount = parseIntValue(dataArray[sIdxInAmount])
855836 let swapStatus = dataArray[sIdxStatus]
856837 let startHeight = parseIntValue(dataArray[sIdxStartHeight])
857838 let inAsset = dataArray[sIdxInAsset]
858839 let totalLocked = totalLockedREAD(swapType, inAsset)
859840 let totalLockedByUser = totalLockedByUserREAD(swapType, account, inAsset)
860841 let unlockHeight = selfUnlockHeight
861842 let indexHeight = getHeightPriceByIndex(index)
862843 let prevIndexHeight = getHeightPriceByIndex((index - 1))
863844 let priceByIndex = getPriceHistory(indexHeight)
864845 if (isBlocked)
865846 then emergencyShutdownFAIL()
866847 else if ((swapStatus != "PENDING"))
867848 then throw("swap has been already processed")
868849 else if ((unlockHeight > height))
869850 then throw((("please wait for: " + toString(unlockHeight)) + " block height to withdraw funds"))
870851 else if (if (if ((index > priceIndex))
871852 then true
872853 else (unlockHeight > indexHeight))
873854 then true
874855 else if ((prevIndexHeight != 0))
875856 then (prevIndexHeight >= unlockHeight)
876857 else false)
877858 then priceIndexFAIL(index, priceIndex, indexHeight, unlockHeight, prevIndexHeight)
878859 else {
879860 let withdrawTuple = calcWithdraw(swapType, inAmount, priceByIndex, neutrinoMetrics, inAsset)
880861 let outNetAmount = withdrawTuple._1
881862 let outAssetId = withdrawTuple._2
882863 let outSurfAmt = withdrawTuple._3
883864 let unleaseAmt = withdrawTuple._5
884865 let outFeeAmount = withdrawTuple._6
885866 let outAmtGross = withdrawTuple._7
886867 let withdrawPrice = withdrawTuple._8
887868 let withdrawBasket = withdrawTuple._9
888869 if (if ((swapType == "outNeutrino"))
889870 then (0 >= outAmtGross)
890871 else false)
891872 then throw("balance equals zero")
892873 else {
893874 let surfCondition = if ((outSurfAmt > 0))
894875 then {
895876 let issueResult = invoke(auctionContract, "issueSurf", [outSurfAmt, account], nil)
896877 if ((issueResult == issueResult))
897878 then 0
898879 else throw("Strict value is not equal to itself.")
899880 }
900881 else 0
901882 if ((surfCondition == surfCondition))
902883 then {
903884 let unleaseInvOrEmpty = invoke(this, "internalUnleaseAndLease", [unleaseAmt], nil)
904885 if ((unleaseInvOrEmpty == unleaseInvOrEmpty))
905886 then {
906887 let gnsbtData = asAnyList(invoke(gnsbtControllerContract, "gnsbtInfoSYSREADONLY", ["", 0, 0], nil))
907888 let gnsbtAmtTotal = asInt(gnsbtData[1])
908889 let gnsbtAmtFromSurfTotal = asInt(asAnyList(gnsbtData[3])[3])
909890 let commonActions = [IntegerEntry(totalLockedByUserKEY(swapType, account, inAsset), (totalLockedByUser - inAmount)), IntegerEntry(totalLockedKEY(swapType, inAsset), (totalLocked - inAmount)), StringEntry(swapKEY(account, swapTxId), finishSwapDATA(dataArray, withdrawPrice, outNetAmount, outFeeAmount, unlockHeight, index, txId, outSurfAmt, BR, withdrawBasket, inAsset))]
910891 if ((swapType == "outMulti"))
911892 then {
912893 let basket = split(withdrawBasket, "_")
913894 func looper (acc,item) = {
914895 let it = split(item, LISTSEP)
915896 let tempAssetId = fromBase58String(it[0])
916897 let assetId = if ((tempAssetId == WAVESID))
917898 then unit
918899 else tempAssetId
919900 let netAmount = parseIntValue(it[2])
920901 let feeAmount = parseIntValue(it[3])
921902 let surfAmt1 = if ((gnsbtAmtTotal != 0))
922903 then fraction(feeAmount, gnsbtAmtFromSurfTotal, gnsbtAmtTotal)
923904 else 0
924905 let surfAmt2 = if ((gnsbtAmtTotal != 0))
925906 then fraction(feeAmount, (MULT6 - BR), MULT6)
926907 else 0
927908 let surfAmt = max([surfAmt1, surfAmt2])
928909 let nsbtAmt = (feeAmount - surfAmt)
929910 $Tuple5((acc._1 :+ ScriptTransfer(userAddress, netAmount, assetId)), (acc._2 :+ AttachedPayment(assetId, surfAmt)), (acc._3 :+ AttachedPayment(assetId, nsbtAmt)), (acc._4 + surfAmt), (acc._5 + nsbtAmt))
930911 }
931912
932913 let r = {
933914 let $l = basket
934915 let $s = size($l)
935916 let $acc0 = $Tuple5(nil, nil, nil, 0, 0)
936917 func $f0_1 ($a,$i) = if (($i >= $s))
937918 then $a
938919 else looper($a, $l[$i])
939920
940921 func $f0_2 ($a,$i) = if (($i >= $s))
941922 then $a
942923 else throw("List size exceeds 10")
943924
944925 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
945926 }
946927 let surfDeposit = if ((r._4 > 0))
947928 then {
948929 let surfInv = invoke(surfStakingContract, "deposit", nil, r._2)
949930 if ((surfInv == surfInv))
950931 then 0
951932 else throw("Strict value is not equal to itself.")
952933 }
953934 else 0
954935 if ((surfDeposit == surfDeposit))
955936 then {
956937 let nsbtDeposit = if ((r._5 > 0))
957938 then {
958939 let nsbtInv = invoke(nsbtStakingContract, "deposit", nil, r._3)
959940 if ((nsbtInv == nsbtInv))
960941 then 0
961942 else throw("Strict value is not equal to itself.")
962943 }
963944 else 0
964945 if ((nsbtDeposit == nsbtDeposit))
965946 then (commonActions ++ r._1)
966947 else throw("Strict value is not equal to itself.")
967948 }
968949 else throw("Strict value is not equal to itself.")
969950 }
970951 else {
971952 let fee = AttachedPayment(outAssetId, outFeeAmount)
972953 let surfFeeAmt1 = if ((gnsbtAmtTotal != 0))
973954 then fraction(fee.amount, gnsbtAmtFromSurfTotal, gnsbtAmtTotal)
974955 else 0
975956 let surfFeeAmt2 = if ((gnsbtAmtTotal != 0))
976957 then fraction(fee.amount, (MULT6 - BR), MULT6)
977958 else 0
978959 let surfFeeAmt = max([surfFeeAmt1, surfFeeAmt2])
979960 let nsbtFeeAmt = (fee.amount - surfFeeAmt)
980961 let surfDeposit = if ((surfFeeAmt > 0))
981962 then {
982963 let surfInv = invoke(surfStakingContract, "deposit", nil, [AttachedPayment(fee.assetId, surfFeeAmt)])
983964 if ((surfInv == surfInv))
984965 then nil
985966 else throw("Strict value is not equal to itself.")
986967 }
987968 else nil
988969 if ((surfDeposit == surfDeposit))
989970 then {
990971 let nsbtDeposit = if ((nsbtFeeAmt > 0))
991972 then {
992973 let nsbtInv = invoke(nsbtStakingContract, "deposit", nil, [AttachedPayment(fee.assetId, nsbtFeeAmt)])
993974 if ((nsbtInv == nsbtInv))
994975 then nil
995976 else throw("Strict value is not equal to itself.")
996977 }
997978 else nil
998979 if ((nsbtDeposit == nsbtDeposit))
999980 then (commonActions :+ ScriptTransfer(userAddress, outNetAmount, outAssetId))
1000981 else throw("Strict value is not equal to itself.")
1001982 }
1002983 else throw("Strict value is not equal to itself.")
1003984 }
1004985 }
1005986 else throw("Strict value is not equal to itself.")
1006987 }
1007988 else throw("Strict value is not equal to itself.")
1008989 }
1009990 }
1010991 }
1011992 }
1012993
1013994
1014995
1015996 @Callable(i)
1016997 func internalUnleaseAndLease (unleaseAmount) = if ((i.caller != this))
1017998 then throw("internalUnleaseAndLease is not public method")
1018999 else prepareUnleaseAndLease(unleaseAmount)
10191000
10201001
10211002
10221003 @Callable(i)
10231004 func transferUsdnToUser (amount,addr) = if ((i.caller != auctionContract))
10241005 then throw("Only auction contract is authorized")
10251006 else [ScriptTransfer(addressFromStringValue(addr), amount, neutrinoAssetId)]
10261007
10271008
10281009
10291010 @Callable(i)
10301011 func acceptWaves () = if (if ((i.caller != auctionContract))
10311012 then (i.caller != govContract)
10321013 else false)
10331014 then throw("Currently only auction and governance contracts are allowed to call")
10341015 else $Tuple2(prepareUnleaseAndLease(0), "success")
10351016
10361017
10371018
10381019 @Callable(i)
10391020 func approveLeasings (nListS,groupNum,lAmt) = {
10401021 let nIdxs = [0, 1, 2, 3, 4, 5, 6, 7]
10411022 let mngPubS = valueOrElse(getString("%s%s__cfg__leasingManagerPub"), "7AUMX54ukYMYvPmma7yoFf5NjZhs4Bu5nz3Ez9EV8sur")
10421023 let mngPub = fromBase58String(mngPubS)
10431024 let nodeRegAddrStr = valueOrElse(getString("%s%s__cfg__nodesRegistryAddress"), "3P9vKqQKjUdmpXAfiWau8krREYAY1Xr69pE")
10441025 let nodeRegAddr = addressFromStringValue(nodeRegAddrStr)
10451026 let lGroupNodeListKEY = getLeaseGroupNodeListKey(groupNum)
10461027 let lGrNodeOpt = getString(this, lGroupNodeListKEY)
10471028 if (isDefined(lGrNodeOpt))
10481029 then throw((("group " + toString(groupNum)) + " already initialized"))
10491030 else {
10501031 let nList = split(nListS, SEP)
10511032 let expCount = size(nIdxs)
10521033 if ((i.callerPublicKey != mngPub))
10531034 then throw("approveLeasings not authorized")
10541035 else {
1055- let $t04427444336 = readNodeInfo(0)
1056- let nAddr0 = $t04427444336._1
1057- let lAmtKEY0 = $t04427444336._2
1058- let lAmt0 = $t04427444336._3
1059- let lIdKEY0 = $t04427444336._4
1060- let lId0 = $t04427444336._5
1036+ let $t04308643148 = readNodeInfo(0)
1037+ let nAddr0 = $t04308643148._1
1038+ let lAmtKEY0 = $t04308643148._2
1039+ let lAmt0 = $t04308643148._3
1040+ let lIdKEY0 = $t04308643148._4
1041+ let lId0 = $t04308643148._5
10611042 let newL0 = Lease(nAddr0, (lAmt0 - (lAmt * expCount)))
10621043 let validation = invoke(nodeRegAddr, "validateAndApproveLeasings", [nListS], nil)
10631044 if ((validation == validation))
10641045 then {
10651046 func forEachNodeValidateAndGenerateLease (a,i) = {
10661047 let node = nList[i]
10671048 let la = Lease(addressFromStringValue(node), lAmt)
10681049 (a ++ [la, BinaryEntry(getLeaseIdByAddressKey(node), lcalc(la)), IntegerEntry(getLeaseAmountByAddressKey(node), lAmt)])
10691050 }
10701051
10711052 ([StringEntry(lGroupNodeListKEY, nListS), BinaryEntry(lIdKEY0, lcalc(newL0)), IntegerEntry(lAmtKEY0, newL0.amount), LeaseCancel(lId0), newL0] ++ {
10721053 let $l = nIdxs
10731054 let $s = size($l)
10741055 let $acc0 = nil
10751056 func $f0_1 ($a,$i) = if (($i >= $s))
10761057 then $a
10771058 else forEachNodeValidateAndGenerateLease($a, $l[$i])
10781059
10791060 func $f0_2 ($a,$i) = if (($i >= $s))
10801061 then $a
10811062 else throw("List size exceeds 8")
10821063
10831064 $f0_2($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)
10841065 })
10851066 }
10861067 else throw("Strict value is not equal to itself.")
10871068 }
10881069 }
10891070 }
10901071
10911072
10921073
10931074 @Callable(i)
10941075 func rebalanceLeasings (amount,groupNum) = {
10951076 let nIdxs = [0, 1, 2, 3, 4, 5, 6, 7]
10961077 let mngPubS = valueOrElse(getString("%s%s__cfg__leasingManagerPub"), "7AUMX54ukYMYvPmma7yoFf5NjZhs4Bu5nz3Ez9EV8sur")
10971078 let mngPub = fromBase58String(mngPubS)
10981079 let lGroupNodeListKEY = getLeaseGroupNodeListKey(groupNum)
10991080 let nListS = getStringOrFail(this, lGroupNodeListKEY)
11001081 let nList = split(nListS, SEP)
11011082 if ((i.callerPublicKey != mngPub))
11021083 then throw("rebalanceLeasings not authorized")
11031084 else {
11041085 let unleaseAmt = ((amount / size(nList)) + 1)
1105- let $t04557645638 = readNodeInfo(0)
1106- let nAddr0 = $t04557645638._1
1107- let lAmtKEY0 = $t04557645638._2
1108- let lAmt0 = $t04557645638._3
1109- let lIdKEY0 = $t04557645638._4
1110- let lId0 = $t04557645638._5
1086+ let $t04438844450 = readNodeInfo(0)
1087+ let nAddr0 = $t04438844450._1
1088+ let lAmtKEY0 = $t04438844450._2
1089+ let lAmt0 = $t04438844450._3
1090+ let lIdKEY0 = $t04438844450._4
1091+ let lId0 = $t04438844450._5
11111092 let newL0 = Lease(nAddr0, (lAmt0 + (unleaseAmt * size(nList))))
11121093 func forEachNodeDoUnlease (a,i) = {
11131094 let node = nList[i]
11141095 let lIdKEY = getLeaseIdByAddressKey(node)
11151096 let lId = getBinaryValue(this, lIdKEY)
11161097 let lAmtKEY = getLeaseAmountByAddressKey(node)
11171098 let lAmt = getIntegerValue(this, lAmtKEY)
11181099 let ula = LeaseCancel(value(lId))
11191100 let la = Lease(addressFromStringValue(node), (lAmt - unleaseAmt))
11201101 (a ++ [LeaseCancel(value(lId)), la, BinaryEntry(lIdKEY, lcalc(la)), IntegerEntry(lAmtKEY, la.amount)])
11211102 }
11221103
11231104 ({
11241105 let $l = nIdxs
11251106 let $s = size($l)
11261107 let $acc0 = nil
11271108 func $f0_1 ($a,$i) = if (($i >= $s))
11281109 then $a
11291110 else forEachNodeDoUnlease($a, $l[$i])
11301111
11311112 func $f0_2 ($a,$i) = if (($i >= $s))
11321113 then $a
11331114 else throw("List size exceeds 8")
11341115
11351116 $f0_2($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)
11361117 } ++ [BinaryEntry(lIdKEY0, lcalc(newL0)), IntegerEntry(lAmtKEY0, newL0.amount), LeaseCancel(lId0), newL0])
11371118 }
11381119 }
11391120
11401121
11411122
11421123 @Callable(i)
11431124 func swapParamsByUserSYSREADONLY (userAddressStr,gnsbtDiff) = {
11441125 let gnsbtData = asAnyList(invoke(gnsbtControllerContract, "gnsbtInfoSYSREADONLY", [userAddressStr, 0, 0], nil))
11451126 let gnsbtAmt = (asInt(gnsbtData[0]) + gnsbtDiff)
11461127 let gnsbtAmtTotal = (asInt(gnsbtData[1]) + gnsbtDiff)
11471128 let swapLimitData = asAnyList(invoke(mathContract, "calcSwapLimitREADONLY", [gnsbtAmt], nil))
11481129 let wavesSwapLimitInUsdnMax = asInt(swapLimitData[0])
11491130 let wavesSwapLimitMax = asInt(swapLimitData[1])
11501131 let usdnSwapLimitMax = asInt(swapLimitData[2])
11511132 let lastSwapHeight = valueOrElse(getInteger(this, keyUserLastSwapHeight(userAddressStr)), 0)
11521133 let swapLimitTimelifeBlocks = swapsTimeframeREAD()
11531134 let passedBlocksAfterLastSwap = (height - lastSwapHeight)
11541135 let isSwapTimelifeNew = (passedBlocksAfterLastSwap >= swapLimitTimelifeBlocks)
11551136 let swapLimitSpentInUsdn = if (isSwapTimelifeNew)
11561137 then 0
11571138 else valueOrElse(getInteger(this, keySwapUserSpentInPeriod(userAddressStr)), 0)
11581139 let blcks2LmtReset = if (isSwapTimelifeNew)
11591140 then 0
11601141 else (swapLimitTimelifeBlocks - passedBlocksAfterLastSwap)
11611142 $Tuple2(nil, $Tuple7(wavesSwapLimitInUsdnMax, swapLimitSpentInUsdn, blcks2LmtReset, gnsbtAmt, gnsbtAmtTotal, wavesSwapLimitMax, usdnSwapLimitMax))
11621143 }
11631144
11641145
11651146
11661147 @Callable(i)
11671148 func calcWithdrawResultSYSREADONLY (swapType,inAmount,price,inAsset) = {
11681149 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
11691150 $Tuple2(nil, calcWithdraw(swapType, inAmount, price, neutrinoMetrics, inAsset))
11701151 }
11711152
11721153
11731154
11741155 @Callable(i)
11751156 func replaceCommunityNode (oldAddrStr,newAddrStr,groupNum,penaltyAmount) = {
11761157 let mngPubS = valueOrElse(getString("%s%s__cfg__leasingManagerPub"), "7AUMX54ukYMYvPmma7yoFf5NjZhs4Bu5nz3Ez9EV8sur")
11771158 let mngPub = fromBase58String(mngPubS)
11781159 if ((i.callerPublicKey != mngPub))
11791160 then throw("replaceCommunityNode not authorized")
11801161 else {
11811162 let groupKey = getLeaseGroupNodeListKey(groupNum)
11821163 let groupNodeListS = getStringOrFail(this, groupKey)
11831164 if (!(contains(groupNodeListS, oldAddrStr)))
11841165 then throw(((("Group " + toString(groupNum)) + " does not contain address ") + oldAddrStr))
11851166 else {
11861167 let doReplace = invoke(nodeRegistryContract, "replaceApprovedNode", [oldAddrStr, newAddrStr, groupNum, penaltyAmount], nil)
11871168 if ((doReplace == doReplace))
11881169 then {
11891170 let oldLeaseIdKey = getLeaseIdByAddressKey(oldAddrStr)
11901171 let oldLeaseAmtKey = getLeaseAmountByAddressKey(oldAddrStr)
11911172 let leaseAmt = getIntegerValue(oldLeaseAmtKey)
11921173 let newLeaseIdKey = getLeaseIdByAddressKey(newAddrStr)
11931174 let newLeaseAmtKey = getLeaseAmountByAddressKey(newAddrStr)
11941175 let newLease = Lease(addressFromStringValue(newAddrStr), leaseAmt)
11951176 let updatedGroupNodeListS = makeString(split(groupNodeListS, oldAddrStr), newAddrStr)
11961177 $Tuple2([LeaseCancel(getBinaryValue(oldLeaseIdKey)), DeleteEntry(oldLeaseIdKey), DeleteEntry(oldLeaseAmtKey), StringEntry(groupKey, updatedGroupNodeListS), newLease, BinaryEntry(newLeaseIdKey, lcalc(newLease)), IntegerEntry(newLeaseAmtKey, leaseAmt)], unit)
11971178 }
11981179 else throw("Strict value is not equal to itself.")
11991180 }
12001181 }
12011182 }
12021183
12031184
12041185
12051186 @Callable(i)
12061187 func updateReservesAndNeutrinoSupply () = {
12071188 func getNumberByKeyInternal (key) = match getInteger(this, key) {
12081189 case a: Int =>
12091190 a
12101191 case _ =>
12111192 0
12121193 }
12131194
12141195 let nMetrix = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
12151196 let idx = getNumberByKeyInternal("updateReservesAndNeutrinoSupplyIdx")
12161197 let newIdx = (idx + 1)
12171198 [IntegerEntry("updateReservesAndNeutrinoSupplyIdx", newIdx), IntegerEntry("reserve", asInt(nMetrix[3])), IntegerEntry("neutrinoSupply", asInt(nMetrix[5])), IntegerEntry("reservesInUsdn", convertWavesToNeutrino(asInt(nMetrix[3]), asInt(nMetrix[0]))), IntegerEntry("surplus", asInt(nMetrix[6])), IntegerEntry("deficit", -(asInt(nMetrix[6])))]
12181199 }
12191200
12201201
12211202
12221203 @Callable(i)
12231204 func wavesBalancesVsPayment () = {
12241205 let b = wavesBalance(this)
12251206 [IntegerEntry("wavesBalance_available", b.available), IntegerEntry("wavesBalance_regular", b.regular), IntegerEntry("wavesBalance_generating", b.generating), IntegerEntry("wavesBalance_effective", b.effective), IntegerEntry("waves_payment", value(i.payments[0]).amount)]
12261207 }
12271208
12281209
12291210 @Verifier(tx)
12301211 func verify () = {
12311212 let pubKeyAdminsListStr = makeString(["ExtEEK19nmKj9mCpnWyvEEJFYATLMcVEMvohhUHkyHNm", "Ev5py5FfBQX9cZpYKnfQrTB49Byf8QmpZWeDVRim4yV7", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR"], SEP)
12321213 let pubKeyAdminsList = split(valueOrElse(getString(controlContract, "%s__multisig"), pubKeyAdminsListStr), SEP)
12331214 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
12341215 then 1
12351216 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
12361217 then 1
12371218 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
12381219 then 1
12391220 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3])))
12401221 then 2
12411222 else 0))
12421223 if (if (isBlocked)
12431224 then (getStringValue(controlContract, "is_blocked_caller") == toString(govContract))
12441225 else false)
12451226 then validateUpdate(tx)
12461227 else match tx {
12471228 case sponsorTx: SponsorFeeTransaction =>
12481229 if (checkIsValidMinSponsoredFee(sponsorTx))
12491230 then (count >= 3)
12501231 else false
12511232 case _ =>
12521233 (count >= 3)
12531234 }
12541235 }
12551236

github/deemru/w8io/026f985 
139.55 ms