tx · 9UgCWRGapQR88ZwYJMuPTATxTgiQcNany8jBRCmvpHXj

3N3kKNoJohjVQYNLTrYTGTesr3nq3PZNh37:  -0.03100000 Waves

2024.07.31 11:54 [3218047] smart account 3N3kKNoJohjVQYNLTrYTGTesr3nq3PZNh37 > SELF 0.00000000 Waves

{ "type": 13, "id": "9UgCWRGapQR88ZwYJMuPTATxTgiQcNany8jBRCmvpHXj", "fee": 3100000, "feeAssetId": null, "timestamp": 1722416081440, "version": 1, "sender": "3N3kKNoJohjVQYNLTrYTGTesr3nq3PZNh37", "senderPublicKey": "vmMXxwQAMUAoisvL193ptPiTtaWQqL5YNu2zs1ouTbY", "proofs": [ "4ByK7XYw3NsbXLcMWgtBGWcqe63muFuRjqEYyVjg8tNXY6DP7fgmSDu5M4VYTWTDWpyH95ZThSgZd3ZFpQzyP5Rs" ], "script": "base64:BwJbCAISAwoBCBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGF4ACXNlcGFyYXRvcgICX18AB2NoYWluSWQJAMkBAgkAygECCAUEdGhpcwVieXRlcwABAAEACGNoYWluSWRXAQFXABBjb250cmFjdEZpbGVuYW1lAhdmdXR1cmVzX2NhbGN1bGF0b3IucmlkZQAFbXVsdDgAgMLXLwAMbXVsdDE4QmlnSW50CQC2AgEAgICQu7rWrfANAA13YXZlc0RlY2ltYWxzAAgADHVzZHREZWNpbWFscwAGAAt3YXZlc1N0cmluZwIFV0FWRVMADXF1ZXVlSXRlbVNpemUAIAAEYmlnMAkAtgIBAAAACklOREVYX0xJU1QJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUJAMwIAgAGCQDMCAIABwkAzAgCAAgJAMwIAgAJCQDMCAIACgkAzAgCAAsJAMwIAgAMCQDMCAIADQkAzAgCAA4JAMwIAgAPCQDMCAIAEAkAzAgCABEJAMwIAgASCQDMCAIAEwUDbmlsAAlrTXVsdGlzaWcCDCVzX19tdWx0aXNpZwEHa1N0YXR1cwIEZGFwcAR0eElkCQC5CQIJAMwIAgIKJXNfX3N0YXR1cwkAzAgCBQRkYXBwCQDMCAIFBHR4SWQFA25pbAUJc2VwYXJhdG9yAAlrU2h1dGRvd24CDCVzX19zaHV0ZG93bgALa1B1YmxpY0tleXMCDiVzX19wdWJsaWNLZXlzABFrTWF0Y2hlclB1YmxpY0tleQIUJXNfX21hdGNoZXJQdWJsaWNLZXkBBXRvWDE4AgdvcmlnVmFsDW9yaWdTY2FsZU11bHQJALwCAwkAtgIBBQdvcmlnVmFsBQxtdWx0MThCaWdJbnQJALYCAQUNb3JpZ1NjYWxlTXVsdAEHZnJvbVgxOAIDdmFsD3Jlc3VsdFNjYWxlTXVsdAkAoAMBCQC8AgMFA3ZhbAkAtgIBBQ9yZXN1bHRTY2FsZU11bHQFDG11bHQxOEJpZ0ludAEPdmFsaWRhdGVBZGRyZXNzAQdhZGRyZXNzCQEJaXNEZWZpbmVkAQkApggBBQdhZGRyZXNzAQd3cmFwRXJyAQFzCQCsAgIJAKwCAgUQY29udHJhY3RGaWxlbmFtZQICOiAFAXMBCHRocm93RXJyAQFzCQACAQkBB3dyYXBFcnIBBQFzAQ5lbnN1cmVQb3NpdGl2ZQIBdgFzAwkAZwIFAXYAAAUBdgkBCHRocm93RXJyAQkArAICBQFzAhkgdmFsdWUgc2hvdWxkIGJlIHBvc2l0aXZlAQxwYXJzZUFzc2V0SWQBBWlucHV0AwkAAAIFBWlucHV0BQt3YXZlc1N0cmluZwUEdW5pdAkA2QQBBQVpbnB1dAEPYXNzZXRJZFRvU3RyaW5nAQVpbnB1dAMJAAACBQVpbnB1dAUEdW5pdAULd2F2ZXNTdHJpbmcJANgEAQkBBXZhbHVlAQUFaW5wdXQBEmdldEFzc2V0SW5mb09yRmFpbAEHYXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFB2Fzc2V0SWQJAQd3cmFwRXJyAQISaW52YWxpZCBhc3NldCBpbmZvARZnZXRBc3NldERlY2ltYWxzT3JGYWlsAQdhc3NldElkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACBFVuaXQFDXdhdmVzRGVjaW1hbHMDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQHYXNzZXRJZAUHJG1hdGNoMAgJARJnZXRBc3NldEluZm9PckZhaWwBBQdhc3NldElkCGRlY2ltYWxzCQACAQILTWF0Y2ggZXJyb3IBD2dldEFzc2V0QmFsYW5jZQIHYXNzZXRJZAdhZGRyZXNzBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACBFVuaXQICQDvBwEFB2FkZHJlc3MJYXZhaWxhYmxlAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEB2Fzc2V0SWQFByRtYXRjaDAJAPAHAgUHYWRkcmVzcwUHYXNzZXRJZAkAAgECC01hdGNoIGVycm9yAQVwb3cxMAEBbgkAbAYACgAABQFuAAAAAAUERE9XTgENcG93MTBEZWNpbWFscwEHYXNzZXRJZAkBBXBvdzEwAQkBFmdldEFzc2V0RGVjaW1hbHNPckZhaWwBBQdhc3NldElkAA9rRmFjdG9yeUFkZHJlc3MCEiVzX19mYWN0b3J5QWRkcmVzcwAUZmFjdG9yeUFkZHJlc3NPcHRpb24EByRtYXRjaDAJAJ0IAgUEdGhpcwUPa0ZhY3RvcnlBZGRyZXNzAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkApggBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgAOZmFjdG9yeUFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgUUZmFjdG9yeUFkZHJlc3NPcHRpb24JAQd3cmFwRXJyAQIXaW52YWxpZCBmYWN0b3J5IGFkZHJlc3MADGtVc2R0QXNzZXRJZAIPJXNfX3VzZHRBc3NldElkABF1c2R0QXNzZXRJZE9wdGlvbgQHJG1hdGNoMAkAnQgCBQ5mYWN0b3J5QWRkcmVzcwUMa1VzZHRBc3NldElkAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkBDHBhcnNlQXNzZXRJZAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAAt1c2R0QXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBRF1c2R0QXNzZXRJZE9wdGlvbgkBB3dyYXBFcnIBAhVpbnZhbGlkIHVzZHQgYXNzZXQgaWQADmtQcmljZXNBZGRyZXNzAhUlc19fY2FsY3VsYXRvckFkZHJlc3MACHNodXRkb3duCQELdmFsdWVPckVsc2UCCQCbCAIFDmZhY3RvcnlBZGRyZXNzBQlrU2h1dGRvd24HAQttdXN0QWRkcmVzcwIGY2FsbGVyB2FkZHJlc3MDCQAAAgUGY2FsbGVyBQdhZGRyZXNzBgkBCHRocm93RXJyAQIRcGVybWlzc2lvbiBkZW5pZWQBCG11c3RUaGlzAQZjYWxsZXIJAQttdXN0QWRkcmVzcwIFBmNhbGxlcgUEdGhpcwELbXVzdEZhY3RvcnkBBmNhbGxlcgkBC211c3RBZGRyZXNzAgUGY2FsbGVyBQ5mYWN0b3J5QWRkcmVzcwEJbXVzdEFkbWluAQ9jYWxsZXJQdWJsaWNLZXkECG11bHRpc2lnCQERQGV4dHJOYXRpdmUoMTA2MikBCQERQGV4dHJOYXRpdmUoMTA1MykCBQ5mYWN0b3J5QWRkcmVzcwUJa011bHRpc2lnBA5wdWJsaWNLZXlzTGlzdAkAtQkCCQERQGV4dHJOYXRpdmUoMTA1MykCBQhtdWx0aXNpZwULa1B1YmxpY0tleXMFCXNlcGFyYXRvcgMJAQ9jb250YWluc0VsZW1lbnQCBQ5wdWJsaWNLZXlzTGlzdAkA2AQBBQ9jYWxsZXJQdWJsaWNLZXkGCQEIdGhyb3dFcnIBAgtub3QgYWxsb3dlZAAOa0FjY291bnRTY3JpcHQCESVzX19hY2NvdW50U2NyaXB0AQ1hY2NvdW50U2NyaXB0AAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCcCAIFDmZhY3RvcnlBZGRyZXNzBQ5rQWNjb3VudFNjcmlwdAkBB3dyYXBFcnIBAhlhY2NvdW50IHNjcmlwdCBpcyBub3Qgc2V0AA1rUmV3YXJkQW1vdW50AhAlc19fcmV3YXJkQW1vdW50AQxyZXdhcmRBbW91bnQACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUOZmFjdG9yeUFkZHJlc3MFDWtSZXdhcmRBbW91bnQJAQd3cmFwRXJyAQIYcmV3YXJkIGFtb3VudCBpcyBub3Qgc2V0AA5rQWNjb3VudHNMaW1pdAIRJXNfX2FjY291bnRzTGltaXQAFGFjY291bnRzTGltaXREZWZhdWx0ABQBDWFjY291bnRzTGltaXQACQELdmFsdWVPckVsc2UCCQCaCAIFDmZhY3RvcnlBZGRyZXNzBQ5rQWNjb3VudHNMaW1pdAUUYWNjb3VudHNMaW1pdERlZmF1bHQBCmtEZXBvc2l0ZWQBDmFjY291bnRBZGRyZXNzCQC5CQIJAMwIAgIEJXMlcwkAzAgCAglkZXBvc2l0ZWQJAMwIAgkApQgBBQ5hY2NvdW50QWRkcmVzcwUDbmlsBQlzZXBhcmF0b3IBD2RlcG9zaXRlZE9wdGlvbgEOYWNjb3VudEFkZHJlc3MJAJoIAgUOZmFjdG9yeUFkZHJlc3MJAQprRGVwb3NpdGVkAQUOYWNjb3VudEFkZHJlc3MBB2tDcmVkaXQCDmFjY291bnRBZGRyZXNzB2Fzc2V0SWQJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIGY3JlZGl0CQDMCAIJAKUIAQUOYWNjb3VudEFkZHJlc3MJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFB2Fzc2V0SWQFA25pbAUJc2VwYXJhdG9yAQxjcmVkaXRPcHRpb24CDmFjY291bnRBZGRyZXNzB2Fzc2V0SWQJAJoIAgUOZmFjdG9yeUFkZHJlc3MJAQdrQ3JlZGl0AgUOYWNjb3VudEFkZHJlc3MFB2Fzc2V0SWQBCWtMZXZlcmFnZQEOYWNjb3VudEFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAICCGxldmVyYWdlCQDMCAIJAKUIAQUOYWNjb3VudEFkZHJlc3MFA25pbAUJc2VwYXJhdG9yARBrUmVxdWVzdExldmVyYWdlAQlyZXF1ZXN0SWQJALkJAgkAzAgCAgQlcyVzCQDMCAICD3JlcXVlc3RMZXZlcmFnZQkAzAgCCQDYBAEFCXJlcXVlc3RJZAUDbmlsBQlzZXBhcmF0b3IBEWtTeW50aGV0aWNBc3NldElkAQtiYXNlQXNzZXRJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgIQc3ludGhldGljQXNzZXRJZAkAzAgCCQEPYXNzZXRJZFRvU3RyaW5nAQULYmFzZUFzc2V0SWQFA25pbAUJc2VwYXJhdG9yAQxrQmFzZUFzc2V0SWQBEHN5bnRoZXRpY0Fzc2V0SWQJALkJAgkAzAgCAgQlcyVzCQDMCAICC2Jhc2VBc3NldElkCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBRBzeW50aGV0aWNBc3NldElkBQNuaWwFCXNlcGFyYXRvcgAUUkVRVUVTVF9TVEFUVVNfRU1QVFkAAAAUUkVRVUVTVF9TVEFUVVNfUkVBRFkAAQEOa1JlcXVlc3RTdGF0dXMBCXJlcXVlc3RJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgkA2AQBBQlyZXF1ZXN0SWQJAMwIAgIGc3RhdHVzBQNuaWwFCXNlcGFyYXRvcgEYa0FjY291bnRDcmVhdG9yUHVibGljS2V5AQ5hY2NvdW50QWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgkApQgBBQ5hY2NvdW50QWRkcmVzcwkAzAgCAhBjcmVhdG9yUHVibGljS2V5BQNuaWwFCXNlcGFyYXRvcgEWa1JlcXVlc3RPd25lclB1YmxpY0tleQEJcmVxdWVzdElkCQC5CQIJAMwIAgIEJXMlcwkAzAgCCQDYBAEFCXJlcXVlc3RJZAkAzAgCAg5vd25lclB1YmxpY0tleQUDbmlsBQlzZXBhcmF0b3IBFWtSZXF1ZXN0QW1vdW50QXNzZXRJZAEJcmVxdWVzdElkCQC5CQIJAMwIAgIEJXMlcwkAzAgCCQDYBAEFCXJlcXVlc3RJZAkAzAgCAg1hbW91bnRBc3NldElkBQNuaWwFCXNlcGFyYXRvcgEUa1JlcXVlc3RQcmljZUFzc2V0SWQBCXJlcXVlc3RJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgkA2AQBBQlyZXF1ZXN0SWQJAMwIAgIMcHJpY2VBc3NldElkBQNuaWwFCXNlcGFyYXRvcgEca1JlcXVlc3RJZFRvQWNjb3VudFB1YmxpY0tleQEJcmVxdWVzdElkCQC5CQIJAMwIAgIEJXMlcwkAzAgCCQDYBAEFCXJlcXVlc3RJZAkAzAgCAhtyZXF1ZXN0SWRUb0FjY291bnRQdWJsaWNLZXkFA25pbAUJc2VwYXJhdG9yARprQWNjb3VudEFkZHJlc3NUb1JlcXVlc3RJZAEOYWNjb3VudEFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAIJAKUIAQUOYWNjb3VudEFkZHJlc3MJAMwIAgIZYWNjb3VudEFkZHJlc3NUb1JlcXVlc3RJZAUDbmlsBQlzZXBhcmF0b3IBDmtSZXF1ZXN0c1F1ZXVlAAkAuQkCCQDMCAICAiVzCQDMCAICDXJlcXVlc3RzUXVldWUFA25pbAUJc2VwYXJhdG9yAQ1yZXF1ZXN0c1F1ZXVlAAkBC3ZhbHVlT3JFbHNlAgkAnAgCBQ5mYWN0b3J5QWRkcmVzcwkBDmtSZXF1ZXN0c1F1ZXVlAAEAAQ5rQWNjb3VudHNRdWV1ZQAJALkJAgkAzAgCAgIlcwkAzAgCAg1hY2NvdW50c1F1ZXVlBQNuaWwFCXNlcGFyYXRvcgENYWNjb3VudHNRdWV1ZQAJAQt2YWx1ZU9yRWxzZQIJAJwIAgUOZmFjdG9yeUFkZHJlc3MJAQ5rQWNjb3VudHNRdWV1ZQABAAEQa1JlcXVlc3RzQnlPd25lcgEMb3duZXJBZGRyZXNzCQC5CQIJAMwIAgIEJXMlcwkAzAgCAghyZXF1ZXN0cwkAzAgCCQClCAEFDG93bmVyQWRkcmVzcwUDbmlsBQlzZXBhcmF0b3IBD3JlcXVlc3RzQnlPd25lcgEMb3duZXJBZGRyZXNzCQELdmFsdWVPckVsc2UCCQCcCAIFDmZhY3RvcnlBZGRyZXNzCQEQa1JlcXVlc3RzQnlPd25lcgEFDG93bmVyQWRkcmVzcwEAAQxrUGFpckFsbG93ZWQCDWFtb3VudEFzc2V0SWQMcHJpY2VBc3NldElkCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQ1hbW91bnRBc3NldElkCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQxwcmljZUFzc2V0SWQJAMwIAgILcGFpckFsbG93ZWQFA25pbAUJc2VwYXJhdG9yAQtwYWlyQWxsb3dlZAINYW1vdW50QXNzZXRJZAxwcmljZUFzc2V0SWQJAQt2YWx1ZU9yRWxzZQIJAJsIAgUOZmFjdG9yeUFkZHJlc3MJAQxrUGFpckFsbG93ZWQCBQ1hbW91bnRBc3NldElkBQxwcmljZUFzc2V0SWQHAQZrUHJpY2UBB2Fzc2V0SWQJALkJAgkAzAgCAgIlcwkAzAgCCQEPYXNzZXRJZFRvU3RyaW5nAQUHYXNzZXRJZAUDbmlsBQlzZXBhcmF0b3IBEmtQYWlyUHJpY2VzTGlzdEtleQINYW1vdW50QXNzZXRJZAxwcmljZUFzc2V0SWQJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFDWFtb3VudEFzc2V0SWQJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFDHByaWNlQXNzZXRJZAkAzAgCAhFwYWlyU2V0dGluZ1ByaWNlcwUDbmlsBQlzZXBhcmF0b3IBEWdldFBhaXJQcmljZXNMaXN0Ag1hbW91bnRBc3NldElkDHByaWNlQXNzZXRJZAQHJG1hdGNoMAkAnQgCBQ5mYWN0b3J5QWRkcmVzcwkBEmtQYWlyUHJpY2VzTGlzdEtleQIFDWFtb3VudEFzc2V0SWQFDHByaWNlQXNzZXRJZAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJALUJAgUBcwUJc2VwYXJhdG9yBQNuaWwBEGtQYWlyU2V0dGluZ3NLZXkDDWFtb3VudEFzc2V0SWQMcHJpY2VBc3NldElkC3ByaWNlU3RyaW5nCQC5CQIJAMwIAgIIJXMlcyVkJXMJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFDWFtb3VudEFzc2V0SWQJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFDHByaWNlQXNzZXRJZAkAzAgCBQtwcmljZVN0cmluZwkAzAgCAghzZXR0aW5ncwUDbmlsBQlzZXBhcmF0b3IBD2dldEN1cnJlbnRQcmljZQEHYXNzZXRJZAQQbWF0Y2hlclB1YmxpY0tleQkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUOZmFjdG9yeUFkZHJlc3MFEWtNYXRjaGVyUHVibGljS2V5CQEHd3JhcEVycgECGmludmFsaWQgbWF0Y2hlciBwdWJsaWMga2V5BA5tYXRjaGVyQWRkcmVzcwkApwgBBRBtYXRjaGVyUHVibGljS2V5BAVwcmljZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFDm1hdGNoZXJBZGRyZXNzCQEGa1ByaWNlAQUHYXNzZXRJZAkBB3dyYXBFcnIBCQCsAgICGWludmFsaWQgcHJpY2UsIGFzc2V0SWQgPSAJAQ9hc3NldElkVG9TdHJpbmcBBQdhc3NldElkBQVwcmljZQEPY2FsY1RvdGFsQ3JlZGl0AwdjcmVkaXRBB2NyZWRpdEIMY3VycmVudFByaWNlCQC3AgIJALwCAwUHY3JlZGl0QQUMY3VycmVudFByaWNlBQxtdWx0MThCaWdJbnQFB2NyZWRpdEIBEGNhbGNUb3RhbEJhbGFuY2UDCGJhbGFuY2VBCGJhbGFuY2VCDGN1cnJlbnRQcmljZQkAtwICCQC8AgMFCGJhbGFuY2VBBQxjdXJyZW50UHJpY2UFDG11bHQxOEJpZ0ludAUIYmFsYW5jZUIBB2NhbGNQbmwCDHRvdGFsQmFsYW5jZQt0b3RhbENyZWRpdAkAuAICBQx0b3RhbEJhbGFuY2UFC3RvdGFsQ3JlZGl0ARNjYWxjQ3JlZGl0QXZhaWxhYmxlAwdkZXBvc2l0CGxldmVyYWdlC3RvdGFsQ3JlZGl0CQC4AgIJALwCAwUHZGVwb3NpdAUIbGV2ZXJhZ2UFDG11bHQxOEJpZ0ludAULdG90YWxDcmVkaXQBEGNhbGNSZWFsSW5DcmVkaXQCBmNyZWRpdAdiYWxhbmNlAwkAvwICBQZjcmVkaXQFBGJpZzAJALgCAgUGY3JlZGl0BQdiYWxhbmNlBQRiaWcwAQhjYWxjRnJlZQIGY3JlZGl0B2JhbGFuY2UDCQC/AgIFBmNyZWRpdAUEYmlnMAkAuAICBQdiYWxhbmNlBQZjcmVkaXQFBGJpZzABDmNhbGNTaG9ydFByaWNlAgRmcmVlDHJlYWxJbkNyZWRpdAMJAL8CAgUMcmVhbEluQ3JlZGl0BQRiaWcwCQCYAwEJAMwIAgUEYmlnMAkAzAgCCQC8AgMFBGZyZWUFDG11bHQxOEJpZ0ludAUMcmVhbEluQ3JlZGl0BQNuaWwFBGJpZzABDWNhbGNMb25nUHJpY2UCBGZyZWUMcmVhbEluQ3JlZGl0AwkAvwICBQxyZWFsSW5DcmVkaXQFBGJpZzAJAJgDAQkAzAgCBQRiaWcwCQDMCAIJALwCAwUMcmVhbEluQ3JlZGl0BQxtdWx0MThCaWdJbnQFBGZyZWUFA25pbAUEYmlnMAEPY2FsY1N0YXJ0TWFyZ2luBA1yZWFsSW5DcmVkaXRBDXJlYWxJbkNyZWRpdEIMY3VycmVudFByaWNlDnNldHRpbmdzTWFyZ2luCQC8AgMJALcCAgkAvAIDBQ1yZWFsSW5DcmVkaXRBBQxjdXJyZW50UHJpY2UFDG11bHQxOEJpZ0ludAUNcmVhbEluQ3JlZGl0QgUOc2V0dGluZ3NNYXJnaW4FDG11bHQxOEJpZ0ludAEQY2FsY01hcmdpblN1cHBseQMUc2V0dGluZ3NNYXJnaW5TdXBwbHkOc2V0dGluZ3NNYXJnaW4Lc3RhcnRNYXJnaW4JALwCAwUUc2V0dGluZ3NNYXJnaW5TdXBwbHkFC3N0YXJ0TWFyZ2luBQ5zZXR0aW5nc01hcmdpbgEUY2FsY0xpcXVpZGF0aW9uUHJpY2UGB2RlcG9zaXQMbWFyZ2luU3VwcGx5DXJlYWxJbkNyZWRpdEENcmVhbEluQ3JlZGl0QgpzaG9ydFByaWNlCWxvbmdQcmljZQQRbGlxdWlkYXRpb25QcmljZUEDCQC/AgIFDXJlYWxJbkNyZWRpdEEFBGJpZzAJALcCAgkAugICCQC4AgIFB2RlcG9zaXQFDG1hcmdpblN1cHBseQUNcmVhbEluQ3JlZGl0QQUKc2hvcnRQcmljZQUEYmlnMAQRbGlxdWlkYXRpb25QcmljZUIDCQC/AgIFDXJlYWxJbkNyZWRpdEIFBGJpZzAJALgCAgUJbG9uZ1ByaWNlCQC6AgIJALgCAgUHZGVwb3NpdAUMbWFyZ2luU3VwcGx5CQC6AgIFDXJlYWxJbkNyZWRpdEEFCWxvbmdQcmljZQUEYmlnMAkAtwICBRFsaXF1aWRhdGlvblByaWNlQQURbGlxdWlkYXRpb25QcmljZUIBDGdldFJlcXVlc3RJZAEOYWNjb3VudEFkZHJlc3MECXJlcXVlc3RJZAkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUOZmFjdG9yeUFkZHJlc3MJARprQWNjb3VudEFkZHJlc3NUb1JlcXVlc3RJZAEFDmFjY291bnRBZGRyZXNzCQEHd3JhcEVycgECMGludmFsaWQgYWNjb3VudCBhZGRyZXNzOiByZXF1ZXN0IGlkIGlzIHVuZGVmaW5lZAUJcmVxdWVzdElkARBnZXRBY2NvdW50QXNzZXRzAQ5hY2NvdW50QWRkcmVzcwQJcmVxdWVzdElkCQEMZ2V0UmVxdWVzdElkAQUOYWNjb3VudEFkZHJlc3MEDWFtb3VudEFzc2V0SWQJAQxwYXJzZUFzc2V0SWQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUOZmFjdG9yeUFkZHJlc3MJARVrUmVxdWVzdEFtb3VudEFzc2V0SWQBBQlyZXF1ZXN0SWQJAQd3cmFwRXJyAQIXaW52YWxpZCBhbW91bnQgYXNzZXQgaWQEDHByaWNlQXNzZXRJZAkBDHBhcnNlQXNzZXRJZAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ5mYWN0b3J5QWRkcmVzcwkBFGtSZXF1ZXN0UHJpY2VBc3NldElkAQUJcmVxdWVzdElkCQEHd3JhcEVycgECF2ludmFsaWQgYW1vdW50IHByaWNlIGlkCQCUCgIFDWFtb3VudEFzc2V0SWQFDHByaWNlQXNzZXRJZAEYZ2V0QWNjb3VudE93bmVyUHVibGljS2V5AQ5hY2NvdW50QWRkcmVzcwQJcmVxdWVzdElkCQEMZ2V0UmVxdWVzdElkAQUOYWNjb3VudEFkZHJlc3MEFXJlcXVlc3RPd25lclB1YmxpY0tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCcCAIFDmZhY3RvcnlBZGRyZXNzCQEWa1JlcXVlc3RPd25lclB1YmxpY0tleQEFCXJlcXVlc3RJZAkBB3dyYXBFcnIBAhdpbnZhbGlkIGFtb3VudCBhc3NldCBpZAUVcmVxdWVzdE93bmVyUHVibGljS2V5ARZnZXRBY2NvdW50SW5mb0ludGVybmFsAQ5hY2NvdW50QWRkcmVzcwQNJHQwMTExODcxMTI1NQkBEGdldEFjY291bnRBc3NldHMBBQ5hY2NvdW50QWRkcmVzcwQNYW1vdW50QXNzZXRJZAgFDSR0MDExMTg3MTEyNTUCXzEEDHByaWNlQXNzZXRJZAgFDSR0MDExMTg3MTEyNTUCXzIECGxldmVyYWdlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUOZmFjdG9yeUFkZHJlc3MJAQlrTGV2ZXJhZ2UBBQ5hY2NvdW50QWRkcmVzcwkBB3dyYXBFcnIBAhpsZXZlcmFnZSBzaG91bGQgYmUgZGVmaW5lZAQJcmVxdWVzdElkCQEMZ2V0UmVxdWVzdElkAQUOYWNjb3VudEFkZHJlc3MEEGFjY291bnRQdWJsaWNLZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnAgCBQ5mYWN0b3J5QWRkcmVzcwkBHGtSZXF1ZXN0SWRUb0FjY291bnRQdWJsaWNLZXkBBQlyZXF1ZXN0SWQCJmtSZXF1ZXN0SWRUb0FjY291bnRQdWJsaWNLZXkgbm90IGZvdW5kBAlkZXBvc2l0ZWQJAQt2YWx1ZU9yRWxzZQIJAQ9kZXBvc2l0ZWRPcHRpb24BBQ5hY2NvdW50QWRkcmVzcwAABAxjdXJyZW50UHJpY2UJAQV0b1gxOAIJAQ9nZXRDdXJyZW50UHJpY2UBBQ1hbW91bnRBc3NldElkCQENcG93MTBEZWNpbWFscwEFDHByaWNlQXNzZXRJZAQHY3JlZGl0QQkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5mYWN0b3J5QWRkcmVzcwkBB2tDcmVkaXQCBQ5hY2NvdW50QWRkcmVzcwUNYW1vdW50QXNzZXRJZAAABAdjcmVkaXRCCQELdmFsdWVPckVsc2UCCQCaCAIFDmZhY3RvcnlBZGRyZXNzCQEHa0NyZWRpdAIFDmFjY291bnRBZGRyZXNzBQxwcmljZUFzc2V0SWQAAAQGc3RhdHVzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUOZmFjdG9yeUFkZHJlc3MJAQ5rUmVxdWVzdFN0YXR1cwEFCXJlcXVlc3RJZAkArAICAh5zdGF0dXMgbm90IGZvdW5kLiBSZXF1ZXN0SWQgPSAJANgEAQUJcmVxdWVzdElkBBJzeW50aEFtb3VudEFzc2V0SWQJAJ0IAgUOZmFjdG9yeUFkZHJlc3MJARFrU3ludGhldGljQXNzZXRJZAEFDWFtb3VudEFzc2V0SWQEF3N5bnRoQW1vdW50QXNzZXRCYWxhbmNlBAckbWF0Y2gwBRJzeW50aEFtb3VudEFzc2V0SWQDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQEPZ2V0QXNzZXRCYWxhbmNlAgkBDHBhcnNlQXNzZXRJZAEFAXMFDmFjY291bnRBZGRyZXNzAAAEEXN5bnRoUHJpY2VBc3NldElkCQCdCAIFDmZhY3RvcnlBZGRyZXNzCQERa1N5bnRoZXRpY0Fzc2V0SWQBBQxwcmljZUFzc2V0SWQEFnN5bnRoUHJpY2VBc3NldEJhbGFuY2UEByRtYXRjaDAFEXN5bnRoUHJpY2VBc3NldElkAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkBD2dldEFzc2V0QmFsYW5jZQIJAQxwYXJzZUFzc2V0SWQBBQFzBQ5hY2NvdW50QWRkcmVzcwAACQCeCgwJAQ9hc3NldElkVG9TdHJpbmcBBQ1hbW91bnRBc3NldElkCQEPYXNzZXRJZFRvU3RyaW5nAQUMcHJpY2VBc3NldElkCQClCAEFDmFjY291bnRBZGRyZXNzCQDYBAEFEGFjY291bnRQdWJsaWNLZXkFCGxldmVyYWdlCQDYBAEFCXJlcXVlc3RJZAUJZGVwb3NpdGVkBQdjcmVkaXRBBQdjcmVkaXRCBRdzeW50aEFtb3VudEFzc2V0QmFsYW5jZQUWc3ludGhQcmljZUFzc2V0QmFsYW5jZQUGc3RhdHVzDwFpAQRpbml0ARFmYWN0b3J5QWRkcmVzc1N0cgQLY2hlY2tDYWxsZXIJAQhtdXN0VGhpcwEIBQFpBmNhbGxlcgMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQ9rRmFjdG9yeUFkZHJlc3MFEWZhY3RvcnlBZGRyZXNzU3RyBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEOcmVxdWVzdEFjY291bnQCD2NhbGxlclB1YmxpY0tleQRhcmdzBAZja2Vja3MJAMwIAgMJAQEhAQUIc2h1dGRvd24GCQEIdGhyb3dFcnIBAgtub3QgYWxsb3dlZAkAzAgCCQELbXVzdEZhY3RvcnkBCAUBaQZjYWxsZXIFA25pbAMJAAACBQZja2Vja3MFBmNrZWNrcwQQYW1vdW50QXNzZXRJZFN0cgkAkQMCBQRhcmdzAAAED3ByaWNlQXNzZXRJZFN0cgkAkQMCBQRhcmdzAAEECGxldmVyYWdlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQkAkQMCBQRhcmdzAAIJAQd3cmFwRXJyAQIQaW52YWxpZCBsZXZlcmFnZQQLdXNlckFkZHJlc3MJAKcIAQUPY2FsbGVyUHVibGljS2V5BAlyZXF1ZXN0SWQJAPcDAQkAywECCQDLAQIIBQt1c2VyQWRkcmVzcwVieXRlcwkA2QQBBRBhbW91bnRBc3NldElkU3RyCQDZBAEFD3ByaWNlQXNzZXRJZFN0cgQNYW1vdW50QXNzZXRJZAkBDHBhcnNlQXNzZXRJZAEFEGFtb3VudEFzc2V0SWRTdHIEDHByaWNlQXNzZXRJZAkBDHBhcnNlQXNzZXRJZAEFD3ByaWNlQXNzZXRJZFN0cgQSdXNlclJlcXVlc3RzTnVtYmVyCQBpAgkAsQIBCQEQa1JlcXVlc3RzQnlPd25lcgEFC3VzZXJBZGRyZXNzBQ1xdWV1ZUl0ZW1TaXplBAZjaGVja3MJAMwIAgMJAAACCQCQAwEIBQFpCHBheW1lbnRzAAEGCQEIdGhyb3dFcnIBAhUxIHBheW1lbnQgaXMgcmVxdWlyZWQJAMwIAgMJAAACCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQFBHVuaXQGCQEIdGhyb3dFcnIBAg1pbnZhbGlkIGFzc2V0CQDMCAIDCQAAAggJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQJAQxyZXdhcmRBbW91bnQABgkBCHRocm93RXJyAQIOaW52YWxpZCBhbW91bnQJAMwIAgMJAQtwYWlyQWxsb3dlZAIFDWFtb3VudEFzc2V0SWQFDHByaWNlQXNzZXRJZAYJAQh0aHJvd0VycgECE3BhaXIgaXMgbm90IGFsbG93ZWQJAMwIAgMJAAACCQCaCAIFDmZhY3RvcnlBZGRyZXNzCQEOa1JlcXVlc3RTdGF0dXMBBQlyZXF1ZXN0SWQFBHVuaXQGCQEIdGhyb3dFcnIBAhlhY2NvdW50IGlzIGFscmVhZHkgZXhpc3RzCQDMCAIDCQBmAgkBDWFjY291bnRzTGltaXQABRJ1c2VyUmVxdWVzdHNOdW1iZXIGCQEIdGhyb3dFcnIBCQCsAgICEmFjY291bnRzIGxpbWl0IGlzIAkApAMBCQENYWNjb3VudHNMaW1pdAAFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQNJHQwMTQ1MjkxNjA2MgMJAAACCQDIAQEJAQ1hY2NvdW50c1F1ZXVlAAAACQCUCgIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUOZmFjdG9yeUFkZHJlc3MJAQxyZXdhcmRBbW91bnQABQR1bml0BQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIMaW50ZWdlckVudHJ5CQDMCAIJAQ5rUmVxdWVzdFN0YXR1cwEFCXJlcXVlc3RJZAkAzAgCBRRSRVFVRVNUX1NUQVRVU19FTVBUWQUDbmlsBQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILYmluYXJ5RW50cnkJAMwIAgkBDmtSZXF1ZXN0c1F1ZXVlAAkAzAgCCQDLAQIJAQ1yZXF1ZXN0c1F1ZXVlAAUJcmVxdWVzdElkBQNuaWwFA25pbAkAzAgCCQD8BwQFDmZhY3RvcnlBZGRyZXNzAgxpbnRlZ2VyRW50cnkJAMwIAgkBEGtSZXF1ZXN0TGV2ZXJhZ2UBBQlyZXF1ZXN0SWQJAMwIAgUIbGV2ZXJhZ2UFA25pbAUDbmlsBQNuaWwEEGFjY291bnRQdWJsaWNLZXkJAMkBAgkBDWFjY291bnRzUXVldWUABQ1xdWV1ZUl0ZW1TaXplBA5hY2NvdW50QWRkcmVzcwkApwgBBRBhY2NvdW50UHVibGljS2V5BA5jcmVhdG9yQWRkcmVzcwkApwgBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJwIAgUOZmFjdG9yeUFkZHJlc3MJARhrQWNjb3VudENyZWF0b3JQdWJsaWNLZXkBBQ5hY2NvdW50QWRkcmVzcwkBB3dyYXBFcnIBAhppbnZhbGlkIGNyZWF0b3IgcHVibGljIGtleQkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFDmNyZWF0b3JBZGRyZXNzCQEMcmV3YXJkQW1vdW50AAUEdW5pdAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC2JpbmFyeUVudHJ5CQDMCAIJAQ5rQWNjb3VudHNRdWV1ZQAJAMwIAgkAygECCQENYWNjb3VudHNRdWV1ZQAFDXF1ZXVlSXRlbVNpemUFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCDGludGVnZXJFbnRyeQkAzAgCCQEOa1JlcXVlc3RTdGF0dXMBBQlyZXF1ZXN0SWQJAMwIAgUUUkVRVUVTVF9TVEFUVVNfUkVBRFkFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC2JpbmFyeUVudHJ5CQDMCAIJARxrUmVxdWVzdElkVG9BY2NvdW50UHVibGljS2V5AQUJcmVxdWVzdElkCQDMCAIFEGFjY291bnRQdWJsaWNLZXkFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC3N0cmluZ0VudHJ5CQDMCAIJARprQWNjb3VudEFkZHJlc3NUb1JlcXVlc3RJZAEFDmFjY291bnRBZGRyZXNzCQDMCAIJANgEAQUJcmVxdWVzdElkBQNuaWwFA25pbAkAzAgCCQD8BwQFDmZhY3RvcnlBZGRyZXNzAgxpbnRlZ2VyRW50cnkJAMwIAgkBCWtMZXZlcmFnZQEFDmFjY291bnRBZGRyZXNzCQDMCAIFCGxldmVyYWdlBQNuaWwFA25pbAUDbmlsBAdhY3Rpb25zCAUNJHQwMTQ1MjkxNjA2MgJfMQQOZmFjdG9yeUFjdGlvbnMIBQ0kdDAxNDUyOTE2MDYyAl8yCQCUCgIFB2FjdGlvbnMJAM4IAgUOZmFjdG9yeUFjdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILYmluYXJ5RW50cnkJAMwIAgkBFmtSZXF1ZXN0T3duZXJQdWJsaWNLZXkBBQlyZXF1ZXN0SWQJAMwIAgUPY2FsbGVyUHVibGljS2V5BQNuaWwFA25pbAkAzAgCCQD8BwQFDmZhY3RvcnlBZGRyZXNzAgtiaW5hcnlFbnRyeQkAzAgCCQEQa1JlcXVlc3RzQnlPd25lcgEFC3VzZXJBZGRyZXNzCQDMCAIJAMsBAgkBD3JlcXVlc3RzQnlPd25lcgEFC3VzZXJBZGRyZXNzBQlyZXF1ZXN0SWQFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC3N0cmluZ0VudHJ5CQDMCAIJARVrUmVxdWVzdEFtb3VudEFzc2V0SWQBBQlyZXF1ZXN0SWQJAMwIAgUQYW1vdW50QXNzZXRJZFN0cgUDbmlsBQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILc3RyaW5nRW50cnkJAMwIAgkBFGtSZXF1ZXN0UHJpY2VBc3NldElkAQUJcmVxdWVzdElkCQDMCAIFD3ByaWNlQXNzZXRJZFN0cgUDbmlsBQNuaWwFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQphZGRBY2NvdW50Ag9jYWxsZXJQdWJsaWNLZXkEYXJncwQGY2tlY2tzCQDMCAIDCQEBIQEFCHNodXRkb3duBgkBCHRocm93RXJyAQILbm90IGFsbG93ZWQJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyBQNuaWwDCQAAAgUGY2tlY2tzBQZja2Vja3MEEGNyZWF0b3JQdWJsaWNLZXkJANkEAQkAkQMCBQRhcmdzAAAEEGFjY291bnRQdWJsaWNLZXkFD2NhbGxlclB1YmxpY0tleQQOYWNjb3VudEFkZHJlc3MJAKcIAQUPY2FsbGVyUHVibGljS2V5BA5jcmVhdG9yQWRkcmVzcwkApwgBBRBjcmVhdG9yUHVibGljS2V5BAZjaGVja3MJAMwIAgMJAAACCQCcCAIFDmZhY3RvcnlBZGRyZXNzCQEYa0FjY291bnRDcmVhdG9yUHVibGljS2V5AQUOYWNjb3VudEFkZHJlc3MFBHVuaXQGCQEIdGhyb3dFcnIBAhlhY2NvdW50IGlzIGFscmVhZHkgZXhpc3RzCQDMCAIDBAckbWF0Y2gwCQDxBwEFDmFjY291bnRBZGRyZXNzAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWIFByRtYXRjaDAJAAACBQFiCQDxFQEJAQ1hY2NvdW50U2NyaXB0AAcGCQEIdGhyb3dFcnIBAg5pbnZhbGlkIHNjcmlwdAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBA0kdDAxNzMxNzE4NTU4AwkAAAIJAMgBAQkBDXJlcXVlc3RzUXVldWUAAAAJAJQKAgUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC2JpbmFyeUVudHJ5CQDMCAIJAQ5rQWNjb3VudHNRdWV1ZQAJAMwIAgkAywECCQENYWNjb3VudHNRdWV1ZQAFEGFjY291bnRQdWJsaWNLZXkFA25pbAUDbmlsBQNuaWwECXJlcXVlc3RJZAkAyQECCQENcmVxdWVzdHNRdWV1ZQAFDXF1ZXVlSXRlbVNpemUECGxldmVyYWdlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUOZmFjdG9yeUFkZHJlc3MJARBrUmVxdWVzdExldmVyYWdlAQUJcmVxdWVzdElkCQEHd3JhcEVycgECH3JlcXVlc3QncyBsZXZlcmFnZSBpcyB1bmRlZmluZWQJAJQKAgUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCDGludGVnZXJFbnRyeQkAzAgCCQEOa1JlcXVlc3RTdGF0dXMBBQlyZXF1ZXN0SWQJAMwIAgUUUkVRVUVTVF9TVEFUVVNfUkVBRFkFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC2JpbmFyeUVudHJ5CQDMCAIJARxrUmVxdWVzdElkVG9BY2NvdW50UHVibGljS2V5AQUJcmVxdWVzdElkCQDMCAIFEGFjY291bnRQdWJsaWNLZXkFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC2JpbmFyeUVudHJ5CQDMCAIJAQ5rUmVxdWVzdHNRdWV1ZQAJAMwIAgkAygECCQENcmVxdWVzdHNRdWV1ZQAFDXF1ZXVlSXRlbVNpemUFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC3N0cmluZ0VudHJ5CQDMCAIJARprQWNjb3VudEFkZHJlc3NUb1JlcXVlc3RJZAEFDmFjY291bnRBZGRyZXNzCQDMCAIJANgEAQUJcmVxdWVzdElkBQNuaWwFA25pbAkAzAgCCQD8BwQFDmZhY3RvcnlBZGRyZXNzAg10cmFuc2ZlcldhdmVzCQDMCAIIBQ5jcmVhdG9yQWRkcmVzcwVieXRlcwkAzAgCCQEMcmV3YXJkQW1vdW50AAUDbmlsBQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIMaW50ZWdlckVudHJ5CQDMCAIJAQlrTGV2ZXJhZ2UBBQ5hY2NvdW50QWRkcmVzcwkAzAgCBQhsZXZlcmFnZQUDbmlsBQNuaWwFA25pbAQHYWN0aW9ucwgFDSR0MDE3MzE3MTg1NTgCXzEEDmZhY3RvcnlBY3Rpb25zCAUNJHQwMTczMTcxODU1OAJfMgkAlAoCBQdhY3Rpb25zCQDOCAIFDmZhY3RvcnlBY3Rpb25zCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC2JpbmFyeUVudHJ5CQDMCAIJARhrQWNjb3VudENyZWF0b3JQdWJsaWNLZXkBBQ5hY2NvdW50QWRkcmVzcwkAzAgCBRBjcmVhdG9yUHVibGljS2V5BQNuaWwFA25pbAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBB2RlcG9zaXQCD2NhbGxlclB1YmxpY0tleQRhcmdzBAdwYXltZW50CQCRAwIIBQFpCHBheW1lbnRzAAAEDmFjY291bnRBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQRhcmdzAAAJAQd3cmFwRXJyAQIXaW52YWxpZCBhY2NvdW50IGFkZHJlc3MEBmNrZWNrcwkAzAgCAwkBASEBBQhzaHV0ZG93bgYJAQh0aHJvd0VycgECC25vdCBhbGxvd2VkCQDMCAIJAQttdXN0RmFjdG9yeQEIBQFpBmNhbGxlcgkAzAgCAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQYJAQh0aHJvd0VycgECFTEgcGF5bWVudCBpcyByZXF1aXJlZAkAzAgCAwkAAAIIBQdwYXltZW50B2Fzc2V0SWQFC3VzZHRBc3NldElkBgkBCHRocm93RXJyAQINaW52YWxpZCBhc3NldAkAzAgCAwkAAAIJAJoIAgUOZmFjdG9yeUFkZHJlc3MJAQ5rUmVxdWVzdFN0YXR1cwEJAQxnZXRSZXF1ZXN0SWQBBQ5hY2NvdW50QWRkcmVzcwUUUkVRVUVTVF9TVEFUVVNfUkVBRFkGCQEIdGhyb3dFcnIBAhRhY2NvdW50IGlzIG5vdCByZWFkeQUDbmlsAwkAAAIFBmNrZWNrcwUGY2tlY2tzBAdhY3Rpb25zCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFDmFjY291bnRBZGRyZXNzCAUHcGF5bWVudAZhbW91bnQIBQdwYXltZW50B2Fzc2V0SWQFA25pbAQOZmFjdG9yeUFjdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIMaW50ZWdlckVudHJ5CQDMCAIJAQprRGVwb3NpdGVkAQUOYWNjb3VudEFkZHJlc3MJAMwIAgkAZAIJAQt2YWx1ZU9yRWxzZQIJAQ9kZXBvc2l0ZWRPcHRpb24BBQ5hY2NvdW50QWRkcmVzcwAACAUHcGF5bWVudAZhbW91bnQFA25pbAUDbmlsBQNuaWwJAJQKAgUHYWN0aW9ucwUOZmFjdG9yeUFjdGlvbnMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEId2l0aGRyYXcCD2NhbGxlclB1YmxpY0tleQRhcmdzBAZja2Vja3MJAMwIAgMJAQEhAQUIc2h1dGRvd24GCQEIdGhyb3dFcnIBAgtub3QgYWxsb3dlZAkAzAgCCQELbXVzdEZhY3RvcnkBCAUBaQZjYWxsZXIFA25pbAMJAAACBQZja2Vja3MFBmNrZWNrcwQLdXNlckFkZHJlc3MJAKcIAQUPY2FsbGVyUHVibGljS2V5BA5hY2NvdW50QWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUEYXJncwAACQEHd3JhcEVycgECF2ludmFsaWQgYWNjb3VudCBhZGRyZXNzBAZhbW91bnQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAtgkBCQCRAwIFBGFyZ3MAAQkBB3dyYXBFcnIBAg5pbnZhbGlkIGFtb3VudAQHYXNzZXRJZAkBDHBhcnNlQXNzZXRJZAEJAJEDAgUEYXJncwACBAtpbnZvY2F0aW9ucwkAzAgCCQD8BwQFDmFjY291bnRBZGRyZXNzAg10cmFuc2ZlckFzc2V0CQDMCAIIBQt1c2VyQWRkcmVzcwVieXRlcwkAzAgCBQZhbW91bnQJAMwIAgUHYXNzZXRJZAUDbmlsBQNuaWwFA25pbAkAlAoCBQNuaWwFC2ludm9jYXRpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBmJvcnJvdwIPY2FsbGVyUHVibGljS2V5BGFyZ3MEDmFjY291bnRBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQRhcmdzAAAJAQd3cmFwRXJyAQIXaW52YWxpZCBhY2NvdW50IGFkZHJlc3MEEGFzc2V0SWRSZXF1ZXN0ZWQJAQxwYXJzZUFzc2V0SWQBCQCRAwIFBGFyZ3MAAQQPYW1vdW50UmVxdWVzdGVkCQEOZW5zdXJlUG9zaXRpdmUCCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQkAkQMCBQRhcmdzAAIJAQd3cmFwRXJyAQIYaW52YWxpZCByZXF1ZXN0ZWQgYW1vdW50AhByZXF1ZXN0ZWQgYW1vdW50BBVhY2NvdW50T3duZXJQdWJsaWNLZXkJARhnZXRBY2NvdW50T3duZXJQdWJsaWNLZXkBBQ5hY2NvdW50QWRkcmVzcwQLdXNlckFkZHJlc3MJAKcIAQUPY2FsbGVyUHVibGljS2V5BAZja2Vja3MJAMwIAgMJAQEhAQUIc2h1dGRvd24GCQEIdGhyb3dFcnIBAgtub3QgYWxsb3dlZAkAzAgCCQELbXVzdEZhY3RvcnkBCAUBaQZjYWxsZXIJAMwIAgMJAAACBQ9jYWxsZXJQdWJsaWNLZXkFFWFjY291bnRPd25lclB1YmxpY0tleQYJAQh0aHJvd0VycgECI2NhbiBiZSBjYWxsZWQgYnkgYWNjb3VudCBvd25lciBvbmx5BQNuaWwDCQAAAgUGY2tlY2tzBQZja2Vja3MEDWFtb3VudEFzc2V0SWQICQEQZ2V0QWNjb3VudEFzc2V0cwEFDmFjY291bnRBZGRyZXNzAl8xBAlkZXBvc2l0ZWQJAQV0b1gxOAIJAQt2YWx1ZU9yRWxzZQIJAQ9kZXBvc2l0ZWRPcHRpb24BBQ5hY2NvdW50QWRkcmVzcwAACQENcG93MTBEZWNpbWFscwEFC3VzZHRBc3NldElkBAxjdXJyZW50UHJpY2UJAQV0b1gxOAIJAQ9nZXRDdXJyZW50UHJpY2UBBQ1hbW91bnRBc3NldElkCQENcG93MTBEZWNpbWFscwEFC3VzZHRBc3NldElkBAdjcmVkaXRBCQEFdG9YMTgCCQELdmFsdWVPckVsc2UCCQCaCAIFDmZhY3RvcnlBZGRyZXNzCQEHa0NyZWRpdAIFDmFjY291bnRBZGRyZXNzBQ1hbW91bnRBc3NldElkAAAJAQ1wb3cxMERlY2ltYWxzAQUNYW1vdW50QXNzZXRJZAQHY3JlZGl0QgkBBXRvWDE4AgkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5mYWN0b3J5QWRkcmVzcwkBB2tDcmVkaXQCBQ5hY2NvdW50QWRkcmVzcwULdXNkdEFzc2V0SWQAAAkBDXBvdzEwRGVjaW1hbHMBBQt1c2R0QXNzZXRJZAQLdG90YWxDcmVkaXQJAQ9jYWxjVG90YWxDcmVkaXQDBQdjcmVkaXRBBQdjcmVkaXRCBQxjdXJyZW50UHJpY2UECGxldmVyYWdlCQEFdG9YMTgCCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUOZmFjdG9yeUFkZHJlc3MJAQlrTGV2ZXJhZ2UBBQ5hY2NvdW50QWRkcmVzcwkBB3dyYXBFcnIBAhpsZXZlcmFnZSBzaG91bGQgYmUgZGVmaW5lZAABBBNjcmVkaXRBdmFpbGFibGVVc2R0CQETY2FsY0NyZWRpdEF2YWlsYWJsZQMFCWRlcG9zaXRlZAUIbGV2ZXJhZ2UFC3RvdGFsQ3JlZGl0BA9jcmVkaXRBdmFpbGFibGUDCQAAAgUQYXNzZXRJZFJlcXVlc3RlZAUNYW1vdW50QXNzZXRJZAkBB2Zyb21YMTgCCQC8AgMFE2NyZWRpdEF2YWlsYWJsZVVzZHQFDG11bHQxOEJpZ0ludAUMY3VycmVudFByaWNlCQENcG93MTBEZWNpbWFscwEFDWFtb3VudEFzc2V0SWQDCQAAAgUQYXNzZXRJZFJlcXVlc3RlZAULdXNkdEFzc2V0SWQJAQdmcm9tWDE4AgUTY3JlZGl0QXZhaWxhYmxlVXNkdAkBDXBvdzEwRGVjaW1hbHMBBQt1c2R0QXNzZXRJZAkBCHRocm93RXJyAQIaaW52YWxpZCByZXF1ZXN0ZWQgYXNzZXQgaWQEEHN5bnRoZXRpY0Fzc2V0SWQJAQxwYXJzZUFzc2V0SWQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUOZmFjdG9yeUFkZHJlc3MJARFrU3ludGhldGljQXNzZXRJZAEFEGFzc2V0SWRSZXF1ZXN0ZWQJAQd3cmFwRXJyAQIwc3ludGhldGljIGFzc2V0IGZvciByZXF1ZXN0ZWQgYXNzZXQgaXMgdW5kZWZpbmVkBAxhbW91bnRUb1NlbmQDCQBnAgUPY3JlZGl0QXZhaWxhYmxlBQ9hbW91bnRSZXF1ZXN0ZWQFD2Ftb3VudFJlcXVlc3RlZAkBCHRocm93RXJyAQkArAICAhNjcmVkaXQgYXZhaWxhYmxlID0gCQCkAwEFD2NyZWRpdEF2YWlsYWJsZQQOZmFjdG9yeUFjdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIMaW50ZWdlckVudHJ5CQDMCAIJAQdrQ3JlZGl0AgUOYWNjb3VudEFkZHJlc3MFEGFzc2V0SWRSZXF1ZXN0ZWQJAMwIAgkAZAIJAQt2YWx1ZU9yRWxzZQIJAQxjcmVkaXRPcHRpb24CBQ5hY2NvdW50QWRkcmVzcwUQYXNzZXRJZFJlcXVlc3RlZAAABQxhbW91bnRUb1NlbmQFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCDXRyYW5zZmVyQXNzZXQJAMwIAggFC3VzZXJBZGRyZXNzBWJ5dGVzCQDMCAIFDGFtb3VudFRvU2VuZAkAzAgCBRBzeW50aGV0aWNBc3NldElkBQNuaWwFA25pbAUDbmlsCQCUCgIFA25pbAkAzAgCBQ5mYWN0b3J5QWN0aW9ucwkAzAgCBQ9jcmVkaXRBdmFpbGFibGUFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQVyZXBheQIPY2FsbGVyUHVibGljS2V5BGFyZ3MEBmNrZWNrcwkAzAgCAwkBASEBBQhzaHV0ZG93bgYJAQh0aHJvd0VycgECC25vdCBhbGxvd2VkCQDMCAIJAQttdXN0RmFjdG9yeQEIBQFpBmNhbGxlcgUDbmlsAwkAAAIFBmNrZWNrcwUGY2tlY2tzCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARBzZXRQYWlyQWxsb3dhbmNlAg9jYWxsZXJQdWJsaWNLZXkEYXJncwQGY2tlY2tzCQDMCAIDCQEBIQEFCHNodXRkb3duBgkBCHRocm93RXJyAQILbm90IGFsbG93ZWQJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyCQDMCAIJAQltdXN0QWRtaW4BBQ9jYWxsZXJQdWJsaWNLZXkFA25pbAMJAAACBQZja2Vja3MFBmNrZWNrcwQQYW1vdW50QXNzZXRJZFN0cgkAkQMCBQRhcmdzAAAED3ByaWNlQXNzZXRJZFN0cgkAkQMCBQRhcmdzAAEECGFsbG93U3RyCQCRAwIFBGFyZ3MAAgQNYW1vdW50QXNzZXRJZAkBDHBhcnNlQXNzZXRJZAEFEGFtb3VudEFzc2V0SWRTdHIEDHByaWNlQXNzZXRJZAkBDHBhcnNlQXNzZXRJZAEFD3ByaWNlQXNzZXRJZFN0cgQFYWxsb3cJAAACBQhhbGxvd1N0cgIEdHJ1ZQQLaW52b2NhdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIMYm9vbGVhbkVudHJ5CQDMCAIJAQxrUGFpckFsbG93ZWQCBQ1hbW91bnRBc3NldElkBQxwcmljZUFzc2V0SWQJAMwIAgUFYWxsb3cFA25pbAUDbmlsBQNuaWwJAJQKAgUDbmlsBQtpbnZvY2F0aW9ucwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARFhZGRTeW50aGV0aWNBc3NldAIPY2FsbGVyUHVibGljS2V5BGFyZ3MEC2Jhc2VBc3NldElkCQEMcGFyc2VBc3NldElkAQkAkQMCBQRhcmdzAAAEEHN5bnRoZXRpY0Fzc2V0SWQJAQxwYXJzZUFzc2V0SWQBCQCRAwIFBGFyZ3MAAQQGY2tlY2tzCQDMCAIDCQEBIQEFCHNodXRkb3duBgkBCHRocm93RXJyAQILbm90IGFsbG93ZWQJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyCQDMCAIJAQltdXN0QWRtaW4BBQ9jYWxsZXJQdWJsaWNLZXkJAMwIAgMJAAACCQCdCAIFDmZhY3RvcnlBZGRyZXNzCQERa1N5bnRoZXRpY0Fzc2V0SWQBBQtiYXNlQXNzZXRJZAUEdW5pdAYJAQh0aHJvd0VycgECEmludmFsaWQgYmFzZSBhc3NldAkAzAgCAwkAAAIJAJ0IAgUOZmFjdG9yeUFkZHJlc3MJAQxrQmFzZUFzc2V0SWQBBRBzeW50aGV0aWNBc3NldElkBQR1bml0BgkBCHRocm93RXJyAQIXaW52YWxpZCBzeW50aGV0aWMgYXNzZXQFA25pbAMJAAACBQZja2Vja3MFBmNrZWNrcwQLaW52b2NhdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILc3RyaW5nRW50cnkJAMwIAgkBEWtTeW50aGV0aWNBc3NldElkAQULYmFzZUFzc2V0SWQJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFEHN5bnRoZXRpY0Fzc2V0SWQFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC3N0cmluZ0VudHJ5CQDMCAIJAQxrQmFzZUFzc2V0SWQBBRBzeW50aGV0aWNBc3NldElkCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQtiYXNlQXNzZXRJZAUDbmlsBQNuaWwFA25pbAkAlAoCBQNuaWwFC2ludm9jYXRpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCmRvU2h1dGRvd24CD2NhbGxlclB1YmxpY0tleQRhcmdzBAZjaGVja3MJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyCQDMCAIJAQltdXN0QWRtaW4BBQ9jYWxsZXJQdWJsaWNLZXkFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQLaW52b2NhdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIMYm9vbGVhbkVudHJ5CQDMCAIFCWtTaHV0ZG93bgkAzAgCBgUDbmlsBQNuaWwFA25pbAkAlAoCBQNuaWwFC2ludm9jYXRpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBFmdldEFjY291bnRJbmZvUkVBRE9OTFkCD2NhbGxlclB1YmxpY0tleQRhcmdzBAZjaGVja3MJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEDmFjY291bnRBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQRhcmdzAAAJAQd3cmFwRXJyAQIXaW52YWxpZCBhY2NvdW50IGFkZHJlc3MEBGRhdGEJARZnZXRBY2NvdW50SW5mb0ludGVybmFsAQUOYWNjb3VudEFkZHJlc3MJAJQKAgUDbmlsBQRkYXRhCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBE2dldFVzZXJJbmZvUkVBRE9OTFkCD2NhbGxlclB1YmxpY0tleQRhcmdzBAZjaGVja3MJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEC3VzZXJBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQRhcmdzAAAJAQd3cmFwRXJyAQIUaW52YWxpZCB1c2VyIGFkZHJlc3MEDHVzZXJSZXF1ZXN0cwkBC3ZhbHVlT3JFbHNlAgkAnAgCBQ5mYWN0b3J5QWRkcmVzcwkBEGtSZXF1ZXN0c0J5T3duZXIBBQt1c2VyQWRkcmVzcwEABBJ1c2VyUmVxdWVzdHNOdW1iZXIJAGkCCQDIAQEFDHVzZXJSZXF1ZXN0cwUNcXVldWVJdGVtU2l6ZQoBD2dldEFjY291bnRzRGF0YQIDYWNjBWNvdW50BA0kdDAyNTk5NDI2MDM2BQNhY2MEC2FjY0RhdGFMaXN0CAUNJHQwMjU5OTQyNjAzNgJfMQQIcmF3Qnl0ZXMIBQ0kdDAyNTk5NDI2MDM2Al8yBAdtYXhTaXplCAUNJHQwMjU5OTQyNjAzNgJfMwMJAGYCBQdtYXhTaXplBQVjb3VudAQJcmVxdWVzdElkCQDJAQIFCHJhd0J5dGVzBQ1xdWV1ZUl0ZW1TaXplBAtuZXdSYXdCeXRlcwkAygECBQhyYXdCeXRlcwUNcXVldWVJdGVtU2l6ZQQQYWNjb3VudFB1YmxpY0tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCcCAIFDmZhY3RvcnlBZGRyZXNzCQEca1JlcXVlc3RJZFRvQWNjb3VudFB1YmxpY0tleQEFCXJlcXVlc3RJZAIma1JlcXVlc3RJZFRvQWNjb3VudFB1YmxpY0tleSBub3QgZm91bmQEDmFjY291bnRBZGRyZXNzCQCnCAEFEGFjY291bnRQdWJsaWNLZXkEBGRhdGEJARZnZXRBY2NvdW50SW5mb0ludGVybmFsAQUOYWNjb3VudEFkZHJlc3MJAJUKAwkAzQgCBQthY2NEYXRhTGlzdAUEZGF0YQULbmV3UmF3Qnl0ZXMFB21heFNpemUFA2FjYwQNJHQwMjY1NDAyNjY0NQoAAiRsBQpJTkRFWF9MSVNUCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlQoDBQNuaWwFDHVzZXJSZXF1ZXN0cwUSdXNlclJlcXVlc3RzTnVtYmVyCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQ9nZXRBY2NvdW50c0RhdGECBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDIwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAQLYWNjRGF0YUxpc3QIBQ0kdDAyNjU0MDI2NjQ1Al8xBAJfYQgFDSR0MDI2NTQwMjY2NDUCXzIEAl9iCAUNJHQwMjY1NDAyNjY0NQJfMwkAlAoCBQNuaWwFC2FjY0RhdGFMaXN0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBG2dldFBhaXJTZXR0aW5nc0luZm9SRUFET05MWQIPY2FsbGVyUHVibGljS2V5BGFyZ3MEC2Ftb3VudEFzc2V0CQEMcGFyc2VBc3NldElkAQkAkQMCBQRhcmdzAAAECnByaWNlQXNzZXQJAQxwYXJzZUFzc2V0SWQBCQCRAwIFBGFyZ3MAAQQKcHJpY2VzTGlzdAkBEWdldFBhaXJQcmljZXNMaXN0AgULYW1vdW50QXNzZXQFCnByaWNlQXNzZXQKAQ9nZXRQYWlyU2V0dGluZ3MCA2FjYwxwcmljZXNTdHJpbmcEC3NldHRpbmdzS2V5CQEQa1BhaXJTZXR0aW5nc0tleQMFC2Ftb3VudEFzc2V0BQpwcmljZUFzc2V0BQxwcmljZXNTdHJpbmcEE3NldHRpbmdzU3RyaW5nVmFsdWUJARFAZXh0ck5hdGl2ZSgxMDUzKQIFDmZhY3RvcnlBZGRyZXNzBQtzZXR0aW5nc0tleQQFc0xpc3QJALUJAgUTc2V0dGluZ3NTdHJpbmdWYWx1ZQUJc2VwYXJhdG9yBAVwcmljZQkAtgkBBQxwcmljZXNTdHJpbmcEC21heExldmVyYWdlCQC2CQEJAJEDAgUFc0xpc3QAAQQNaW5pdGlhbE1hcmdpbgkAtgkBCQCRAwIFBXNMaXN0AAIEEW1haW50ZW5hbmNlTWFyZ2luCQC2CQEJAJEDAgUFc0xpc3QAAwkAzQgCBQNhY2MJAJYKBAUFcHJpY2UFC21heExldmVyYWdlBQ1pbml0aWFsTWFyZ2luBRFtYWludGVuYW5jZU1hcmdpbgQEZGF0YQoAAiRsBQpwcmljZXNMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQ9nZXRQYWlyU2V0dGluZ3MCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDIwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAkAlAoCBQNuaWwFBGRhdGEBaQEQZWRpdFBhaXJTZXR0aW5ncwIPY2FsbGVyUHVibGljS2V5BGFyZ3MEBmNoZWNrcwkAzAgCCQELbXVzdEZhY3RvcnkBCAUBaQZjYWxsZXIFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQLYW1vdW50QXNzZXQJAQxwYXJzZUFzc2V0SWQBCQCRAwIFBGFyZ3MAAAQKcHJpY2VBc3NldAkBDHBhcnNlQXNzZXRJZAEJAJEDAgUEYXJncwABBAVwcmljZQkAkQMCBQRhcmdzAAIEC21heExldmVyYWdlCQCRAwIFBGFyZ3MAAwQNaW5pdGlhbE1hcmdpbgkAkQMCBQRhcmdzAAQEEW1haW50ZW5hbmNlTWFyZ2luCQCRAwIFBGFyZ3MABQQRcGFpclByaWNlc0xpc3RLZXkJARJrUGFpclByaWNlc0xpc3RLZXkCBQthbW91bnRBc3NldAUKcHJpY2VBc3NldAQLc2V0dGluZ3NLZXkJARBrUGFpclNldHRpbmdzS2V5AwULYW1vdW50QXNzZXQFCnByaWNlQXNzZXQFBXByaWNlBApwcmljZXNMaXN0CQERZ2V0UGFpclByaWNlc0xpc3QCBQthbW91bnRBc3NldAUKcHJpY2VBc3NldAQHbmV3TGlzdAQHJG1hdGNoMAkAzwgCBQpwcmljZXNMaXN0BQVwcmljZQMJAAECBQckbWF0Y2gwAgNJbnQEA2luZAUHJG1hdGNoMAUKcHJpY2VzTGlzdAkAzQgCBQpwcmljZXNMaXN0BQVwcmljZQQGY2hlY2syCQDMCAIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAtgkBBQVwcmljZQkBB3dyYXBFcnIBAhlwcmljZSB2YWx1ZSBpcyBub3QgYW4gSW50CQDMCAIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgULbWF4TGV2ZXJhZ2UJAQd3cmFwRXJyAQIfbWF4TGV2ZXJhZ2UgdmFsdWUgaXMgbm90IGFuIEludAkAzAgCCQETdmFsdWVPckVycm9yTWVzc2FnZQIFDWluaXRpYWxNYXJnaW4JAQd3cmFwRXJyAQIhaW5pdGlhbE1hcmdpbiB2YWx1ZSBpcyBub3QgYW4gSW50CQDMCAIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgURbWFpbnRlbmFuY2VNYXJnaW4JAQd3cmFwRXJyAQIlbWFpbnRlbmFuY2VNYXJnaW4gdmFsdWUgaXMgbm90IGFuIEludAkAzAgCAwkAZwIAFAkAkAMBBQduZXdMaXN0BgkBCHRocm93RXJyAQIiZXhjZWVkZWQgbWF4IHByaWNlcyBsaXN0IHNpemUgKDIwKQUDbmlsAwkAAAIFBmNoZWNrMgUGY2hlY2syBBBwYWlyU2V0dGluZ1ZhbHVlCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFC21heExldmVyYWdlCQDMCAIFDWluaXRpYWxNYXJnaW4JAMwIAgURbWFpbnRlbmFuY2VNYXJnaW4FA25pbAUJc2VwYXJhdG9yBAtpbnZvY2F0aW9ucwkAzAgCCQD8BwQFDmZhY3RvcnlBZGRyZXNzAgtzdHJpbmdFbnRyeQkAzAgCCQESa1BhaXJQcmljZXNMaXN0S2V5AgULYW1vdW50QXNzZXQFCnByaWNlQXNzZXQJAMwIAgkAuQkCBQduZXdMaXN0BQlzZXBhcmF0b3IFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC3N0cmluZ0VudHJ5CQDMCAIJARBrUGFpclNldHRpbmdzS2V5AwULYW1vdW50QXNzZXQFCnByaWNlQXNzZXQFBXByaWNlCQDMCAIFEHBhaXJTZXR0aW5nVmFsdWUFA25pbAUDbmlsBQNuaWwJAJQKAgUDbmlsBQtpbnZvY2F0aW9ucwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARJkZWxldGVQYWlyU2V0dGluZ3MCD2NhbGxlclB1YmxpY0tleQRhcmdzBAZjaGVja3MJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEC2Ftb3VudEFzc2V0CQEMcGFyc2VBc3NldElkAQkAkQMCBQRhcmdzAAAECnByaWNlQXNzZXQJAQxwYXJzZUFzc2V0SWQBCQCRAwIFBGFyZ3MAAQQFcHJpY2UJAJEDAgUEYXJncwACBAtzZXR0aW5nc0tleQkBEGtQYWlyU2V0dGluZ3NLZXkDBQthbW91bnRBc3NldAUKcHJpY2VBc3NldAUFcHJpY2UEEXBhaXJQcmljZXNMaXN0S2V5CQESa1BhaXJQcmljZXNMaXN0S2V5AgULYW1vdW50QXNzZXQFCnByaWNlQXNzZXQECnByaWNlc0xpc3QJARFnZXRQYWlyUHJpY2VzTGlzdAIFC2Ftb3VudEFzc2V0BQpwcmljZUFzc2V0BAduZXdMaXN0BAckbWF0Y2gwCQDPCAIFCnByaWNlc0xpc3QFBXByaWNlAwkAAQIFByRtYXRjaDACA0ludAQDaW5kBQckbWF0Y2gwCQDRCAIFCnByaWNlc0xpc3QFA2luZAUKcHJpY2VzTGlzdAQLaW52b2NhdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILZGVsZXRlRW50cnkJAMwIAgULc2V0dGluZ3NLZXkFA25pbAUDbmlsCQDMCAIDCQAAAgkAkAMBBQduZXdMaXN0AAAJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC2RlbGV0ZUVudHJ5CQDMCAIJARJrUGFpclByaWNlc0xpc3RLZXkCBQthbW91bnRBc3NldAUKcHJpY2VBc3NldAUDbmlsBQNuaWwJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC3N0cmluZ0VudHJ5CQDMCAIJARJrUGFpclByaWNlc0xpc3RLZXkCBQthbW91bnRBc3NldAUKcHJpY2VBc3NldAkAzAgCCQC5CQIFB25ld0xpc3QFCXNlcGFyYXRvcgUDbmlsBQNuaWwFA25pbAkAlAoCBQNuaWwFC2ludm9jYXRpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJ0eAEGdmVyaWZ5AAMDCQEJaXNEZWZpbmVkAQUUZmFjdG9yeUFkZHJlc3NPcHRpb24JAQlpc0RlZmluZWQBCQCdCAIFDmZhY3RvcnlBZGRyZXNzBQlrTXVsdGlzaWcHBAckbWF0Y2gwCQCdCAIFDmZhY3RvcnlBZGRyZXNzBQlrTXVsdGlzaWcDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAhtdWx0aXNpZwUHJG1hdGNoMAQJc3RhdHVzS2V5CQEHa1N0YXR1cwIJAKUIAQUEdGhpcwkA2AQBCAUCdHgCaWQEBnN0YXR1cwkBC3ZhbHVlT3JFbHNlAgkAmwgCCQERQGV4dHJOYXRpdmUoMTA2MikBBQhtdWx0aXNpZwUJc3RhdHVzS2V5BwUGc3RhdHVzBwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAgFAnR4D3NlbmRlclB1YmxpY0tleZNMXeo=", "chainId": 84, "height": 3218047, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: EAY93SRrPz8yPnVuUTf24j7PrGn6EJkcFZs2YZPGShdQ Next: none Diff:
OldNewDifferences
342342 let creditA = valueOrElse(getInteger(factoryAddress, kCredit(accountAddress, amountAssetId)), 0)
343343 let creditB = valueOrElse(getInteger(factoryAddress, kCredit(accountAddress, priceAssetId)), 0)
344344 let status = valueOrErrorMessage(getInteger(factoryAddress, kRequestStatus(requestId)), ("status not found. RequestId = " + toBase58String(requestId)))
345- $Tuple12(assetIdToString(amountAssetId), assetIdToString(priceAssetId), toString(accountAddress), toBase58String(accountPublicKey), leverage, toBase58String(requestId), deposited, creditA, creditB, getAssetBalance(parseAssetId(getStringValue(kSyntheticAssetId(amountAssetId))), accountAddress), getAssetBalance(parseAssetId(getStringValue(kSyntheticAssetId(priceAssetId))), accountAddress), status)
345+ let synthAmountAssetId = getString(factoryAddress, kSyntheticAssetId(amountAssetId))
346+ let synthAmountAssetBalance = match synthAmountAssetId {
347+ case s: String =>
348+ getAssetBalance(parseAssetId(s), accountAddress)
349+ case _ =>
350+ 0
351+ }
352+ let synthPriceAssetId = getString(factoryAddress, kSyntheticAssetId(priceAssetId))
353+ let synthPriceAssetBalance = match synthPriceAssetId {
354+ case s: String =>
355+ getAssetBalance(parseAssetId(s), accountAddress)
356+ case _ =>
357+ 0
358+ }
359+ $Tuple12(assetIdToString(amountAssetId), assetIdToString(priceAssetId), toString(accountAddress), toBase58String(accountPublicKey), leverage, toBase58String(requestId), deposited, creditA, creditB, synthAmountAssetBalance, synthPriceAssetBalance, status)
346360 }
347361
348362
386400 else throwErr(("accounts limit is " + toString(accountsLimit())))]
387401 if ((checks == checks))
388402 then {
389- let $t01419115724 = if ((size(accountsQueue()) == 0))
403+ let $t01452916062 = if ((size(accountsQueue()) == 0))
390404 then $Tuple2([ScriptTransfer(factoryAddress, rewardAmount(), unit)], [invoke(factoryAddress, "integerEntry", [kRequestStatus(requestId), REQUEST_STATUS_EMPTY], nil), invoke(factoryAddress, "binaryEntry", [kRequestsQueue(), (requestsQueue() + requestId)], nil), invoke(factoryAddress, "integerEntry", [kRequestLeverage(requestId), leverage], nil)])
391405 else {
392406 let accountPublicKey = take(accountsQueue(), queueItemSize)
394408 let creatorAddress = addressFromPublicKey(valueOrErrorMessage(getBinary(factoryAddress, kAccountCreatorPublicKey(accountAddress)), wrapErr("invalid creator public key")))
395409 $Tuple2([ScriptTransfer(creatorAddress, rewardAmount(), unit)], [invoke(factoryAddress, "binaryEntry", [kAccountsQueue(), drop(accountsQueue(), queueItemSize)], nil), invoke(factoryAddress, "integerEntry", [kRequestStatus(requestId), REQUEST_STATUS_READY], nil), invoke(factoryAddress, "binaryEntry", [kRequestIdToAccountPublicKey(requestId), accountPublicKey], nil), invoke(factoryAddress, "stringEntry", [kAccountAddressToRequestId(accountAddress), toBase58String(requestId)], nil), invoke(factoryAddress, "integerEntry", [kLeverage(accountAddress), leverage], nil)])
396410 }
397- let actions = $t01419115724._1
398- let factoryActions = $t01419115724._2
411+ let actions = $t01452916062._1
412+ let factoryActions = $t01452916062._2
399413 $Tuple2(actions, (factoryActions ++ [invoke(factoryAddress, "binaryEntry", [kRequestOwnerPublicKey(requestId), callerPublicKey], nil), invoke(factoryAddress, "binaryEntry", [kRequestsByOwner(userAddress), (requestsByOwner(userAddress) + requestId)], nil), invoke(factoryAddress, "stringEntry", [kRequestAmountAssetId(requestId), amountAssetIdStr], nil), invoke(factoryAddress, "stringEntry", [kRequestPriceAssetId(requestId), priceAssetIdStr], nil)]))
400414 }
401415 else throw("Strict value is not equal to itself.")
428442 else throwErr("invalid script")]
429443 if ((checks == checks))
430444 then {
431- let $t01697918220 = if ((size(requestsQueue()) == 0))
445+ let $t01731718558 = if ((size(requestsQueue()) == 0))
432446 then $Tuple2(nil, [invoke(factoryAddress, "binaryEntry", [kAccountsQueue(), (accountsQueue() + accountPublicKey)], nil)])
433447 else {
434448 let requestId = take(requestsQueue(), queueItemSize)
435449 let leverage = valueOrErrorMessage(getInteger(factoryAddress, kRequestLeverage(requestId)), wrapErr("request's leverage is undefined"))
436450 $Tuple2(nil, [invoke(factoryAddress, "integerEntry", [kRequestStatus(requestId), REQUEST_STATUS_READY], nil), invoke(factoryAddress, "binaryEntry", [kRequestIdToAccountPublicKey(requestId), accountPublicKey], nil), invoke(factoryAddress, "binaryEntry", [kRequestsQueue(), drop(requestsQueue(), queueItemSize)], nil), invoke(factoryAddress, "stringEntry", [kAccountAddressToRequestId(accountAddress), toBase58String(requestId)], nil), invoke(factoryAddress, "transferWaves", [creatorAddress.bytes, rewardAmount()], nil), invoke(factoryAddress, "integerEntry", [kLeverage(accountAddress), leverage], nil)])
437451 }
438- let actions = $t01697918220._1
439- let factoryActions = $t01697918220._2
452+ let actions = $t01731718558._1
453+ let factoryActions = $t01731718558._2
440454 $Tuple2(actions, (factoryActions ++ [invoke(factoryAddress, "binaryEntry", [kAccountCreatorPublicKey(accountAddress), creatorPublicKey], nil)]))
441455 }
442456 else throw("Strict value is not equal to itself.")
618632 let userRequests = valueOrElse(getBinary(factoryAddress, kRequestsByOwner(userAddress)), base58'')
619633 let userRequestsNumber = (size(userRequests) / queueItemSize)
620634 func getAccountsData (acc,count) = {
621- let $t02565625698 = acc
622- let accDataList = $t02565625698._1
623- let rawBytes = $t02565625698._2
624- let maxSize = $t02565625698._3
635+ let $t02599426036 = acc
636+ let accDataList = $t02599426036._1
637+ let rawBytes = $t02599426036._2
638+ let maxSize = $t02599426036._3
625639 if ((maxSize > count))
626640 then {
627641 let requestId = take(rawBytes, queueItemSize)
634648 else acc
635649 }
636650
637- let $t02620226307 = {
651+ let $t02654026645 = {
638652 let $l = INDEX_LIST
639653 let $s = size($l)
640654 let $acc0 = $Tuple3(nil, userRequests, userRequestsNumber)
648662
649663 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
650664 }
651- let accDataList = $t02620226307._1
652- let _a = $t02620226307._2
653- let _b = $t02620226307._3
665+ let accDataList = $t02654026645._1
666+ let _a = $t02654026645._2
667+ let _b = $t02654026645._3
654668 $Tuple2(nil, accDataList)
655669 }
656670 else throw("Strict value is not equal to itself.")
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 7 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
55
66 let chainId = take(drop(this.bytes, 1), 1)
77
88 let chainIdW = base58'2W'
99
1010 let contractFilename = "futures_calculator.ride"
1111
1212 let mult8 = 100000000
1313
1414 let mult18BigInt = toBigInt(1000000000000000000)
1515
1616 let wavesDecimals = 8
1717
1818 let usdtDecimals = 6
1919
2020 let wavesString = "WAVES"
2121
2222 let queueItemSize = 32
2323
2424 let big0 = toBigInt(0)
2525
2626 let INDEX_LIST = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
2727
2828 let kMultisig = "%s__multisig"
2929
3030 func kStatus (dapp,txId) = makeString(["%s__status", dapp, txId], separator)
3131
3232
3333 let kShutdown = "%s__shutdown"
3434
3535 let kPublicKeys = "%s__publicKeys"
3636
3737 let kMatcherPublicKey = "%s__matcherPublicKey"
3838
3939 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), mult18BigInt, toBigInt(origScaleMult))
4040
4141
4242 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), mult18BigInt))
4343
4444
4545 func validateAddress (address) = isDefined(addressFromString(address))
4646
4747
4848 func wrapErr (s) = ((contractFilename + ": ") + s)
4949
5050
5151 func throwErr (s) = throw(wrapErr(s))
5252
5353
5454 func ensurePositive (v,s) = if ((v >= 0))
5555 then v
5656 else throwErr((s + " value should be positive"))
5757
5858
5959 func parseAssetId (input) = if ((input == wavesString))
6060 then unit
6161 else fromBase58String(input)
6262
6363
6464 func assetIdToString (input) = if ((input == unit))
6565 then wavesString
6666 else toBase58String(value(input))
6767
6868
6969 func getAssetInfoOrFail (assetId) = valueOrErrorMessage(assetInfo(assetId), wrapErr("invalid asset info"))
7070
7171
7272 func getAssetDecimalsOrFail (assetId) = match assetId {
7373 case _: Unit =>
7474 wavesDecimals
7575 case assetId: ByteVector =>
7676 getAssetInfoOrFail(assetId).decimals
7777 case _ =>
7878 throw("Match error")
7979 }
8080
8181
8282 func getAssetBalance (assetId,address) = match assetId {
8383 case _: Unit =>
8484 wavesBalance(address).available
8585 case assetId: ByteVector =>
8686 assetBalance(address, assetId)
8787 case _ =>
8888 throw("Match error")
8989 }
9090
9191
9292 func pow10 (n) = pow(10, 0, n, 0, 0, DOWN)
9393
9494
9595 func pow10Decimals (assetId) = pow10(getAssetDecimalsOrFail(assetId))
9696
9797
9898 let kFactoryAddress = "%s__factoryAddress"
9999
100100 let factoryAddressOption = match getString(this, kFactoryAddress) {
101101 case s: String =>
102102 addressFromString(s)
103103 case _: Unit =>
104104 unit
105105 case _ =>
106106 throw("Match error")
107107 }
108108
109109 let factoryAddress = valueOrErrorMessage(factoryAddressOption, wrapErr("invalid factory address"))
110110
111111 let kUsdtAssetId = "%s__usdtAssetId"
112112
113113 let usdtAssetIdOption = match getString(factoryAddress, kUsdtAssetId) {
114114 case s: String =>
115115 parseAssetId(s)
116116 case _: Unit =>
117117 unit
118118 case _ =>
119119 throw("Match error")
120120 }
121121
122122 let usdtAssetId = valueOrErrorMessage(usdtAssetIdOption, wrapErr("invalid usdt asset id"))
123123
124124 let kPricesAddress = "%s__calculatorAddress"
125125
126126 let shutdown = valueOrElse(getBoolean(factoryAddress, kShutdown), false)
127127
128128 func mustAddress (caller,address) = if ((caller == address))
129129 then true
130130 else throwErr("permission denied")
131131
132132
133133 func mustThis (caller) = mustAddress(caller, this)
134134
135135
136136 func mustFactory (caller) = mustAddress(caller, factoryAddress)
137137
138138
139139 func mustAdmin (callerPublicKey) = {
140140 let multisig = addressFromStringValue(getStringValue(factoryAddress, kMultisig))
141141 let publicKeysList = split(getStringValue(multisig, kPublicKeys), separator)
142142 if (containsElement(publicKeysList, toBase58String(callerPublicKey)))
143143 then true
144144 else throwErr("not allowed")
145145 }
146146
147147
148148 let kAccountScript = "%s__accountScript"
149149
150150 func accountScript () = valueOrErrorMessage(getBinary(factoryAddress, kAccountScript), wrapErr("account script is not set"))
151151
152152
153153 let kRewardAmount = "%s__rewardAmount"
154154
155155 func rewardAmount () = valueOrErrorMessage(getInteger(factoryAddress, kRewardAmount), wrapErr("reward amount is not set"))
156156
157157
158158 let kAccountsLimit = "%s__accountsLimit"
159159
160160 let accountsLimitDefault = 20
161161
162162 func accountsLimit () = valueOrElse(getInteger(factoryAddress, kAccountsLimit), accountsLimitDefault)
163163
164164
165165 func kDeposited (accountAddress) = makeString(["%s%s", "deposited", toString(accountAddress)], separator)
166166
167167
168168 func depositedOption (accountAddress) = getInteger(factoryAddress, kDeposited(accountAddress))
169169
170170
171171 func kCredit (accountAddress,assetId) = makeString(["%s%s%s", "credit", toString(accountAddress), assetIdToString(assetId)], separator)
172172
173173
174174 func creditOption (accountAddress,assetId) = getInteger(factoryAddress, kCredit(accountAddress, assetId))
175175
176176
177177 func kLeverage (accountAddress) = makeString(["%s%s", "leverage", toString(accountAddress)], separator)
178178
179179
180180 func kRequestLeverage (requestId) = makeString(["%s%s", "requestLeverage", toBase58String(requestId)], separator)
181181
182182
183183 func kSyntheticAssetId (baseAssetId) = makeString(["%s%s", "syntheticAssetId", assetIdToString(baseAssetId)], separator)
184184
185185
186186 func kBaseAssetId (syntheticAssetId) = makeString(["%s%s", "baseAssetId", assetIdToString(syntheticAssetId)], separator)
187187
188188
189189 let REQUEST_STATUS_EMPTY = 0
190190
191191 let REQUEST_STATUS_READY = 1
192192
193193 func kRequestStatus (requestId) = makeString(["%s%s", toBase58String(requestId), "status"], separator)
194194
195195
196196 func kAccountCreatorPublicKey (accountAddress) = makeString(["%s%s", toString(accountAddress), "creatorPublicKey"], separator)
197197
198198
199199 func kRequestOwnerPublicKey (requestId) = makeString(["%s%s", toBase58String(requestId), "ownerPublicKey"], separator)
200200
201201
202202 func kRequestAmountAssetId (requestId) = makeString(["%s%s", toBase58String(requestId), "amountAssetId"], separator)
203203
204204
205205 func kRequestPriceAssetId (requestId) = makeString(["%s%s", toBase58String(requestId), "priceAssetId"], separator)
206206
207207
208208 func kRequestIdToAccountPublicKey (requestId) = makeString(["%s%s", toBase58String(requestId), "requestIdToAccountPublicKey"], separator)
209209
210210
211211 func kAccountAddressToRequestId (accountAddress) = makeString(["%s%s", toString(accountAddress), "accountAddressToRequestId"], separator)
212212
213213
214214 func kRequestsQueue () = makeString(["%s", "requestsQueue"], separator)
215215
216216
217217 func requestsQueue () = valueOrElse(getBinary(factoryAddress, kRequestsQueue()), base58'')
218218
219219
220220 func kAccountsQueue () = makeString(["%s", "accountsQueue"], separator)
221221
222222
223223 func accountsQueue () = valueOrElse(getBinary(factoryAddress, kAccountsQueue()), base58'')
224224
225225
226226 func kRequestsByOwner (ownerAddress) = makeString(["%s%s", "requests", toString(ownerAddress)], separator)
227227
228228
229229 func requestsByOwner (ownerAddress) = valueOrElse(getBinary(factoryAddress, kRequestsByOwner(ownerAddress)), base58'')
230230
231231
232232 func kPairAllowed (amountAssetId,priceAssetId) = makeString(["%s%s%s", assetIdToString(amountAssetId), assetIdToString(priceAssetId), "pairAllowed"], separator)
233233
234234
235235 func pairAllowed (amountAssetId,priceAssetId) = valueOrElse(getBoolean(factoryAddress, kPairAllowed(amountAssetId, priceAssetId)), false)
236236
237237
238238 func kPrice (assetId) = makeString(["%s", assetIdToString(assetId)], separator)
239239
240240
241241 func kPairPricesListKey (amountAssetId,priceAssetId) = makeString(["%s%s%s", assetIdToString(amountAssetId), assetIdToString(priceAssetId), "pairSettingPrices"], separator)
242242
243243
244244 func getPairPricesList (amountAssetId,priceAssetId) = match getString(factoryAddress, kPairPricesListKey(amountAssetId, priceAssetId)) {
245245 case s: String =>
246246 split(s, separator)
247247 case _ =>
248248 nil
249249 }
250250
251251
252252 func kPairSettingsKey (amountAssetId,priceAssetId,priceString) = makeString(["%s%s%d%s", assetIdToString(amountAssetId), assetIdToString(priceAssetId), priceString, "settings"], separator)
253253
254254
255255 func getCurrentPrice (assetId) = {
256256 let matcherPublicKey = fromBase58String(valueOrErrorMessage(getString(factoryAddress, kMatcherPublicKey), wrapErr("invalid matcher public key")))
257257 let matcherAddress = addressFromPublicKey(matcherPublicKey)
258258 let price = valueOrErrorMessage(getInteger(matcherAddress, kPrice(assetId)), wrapErr(("invalid price, assetId = " + assetIdToString(assetId))))
259259 price
260260 }
261261
262262
263263 func calcTotalCredit (creditA,creditB,currentPrice) = (fraction(creditA, currentPrice, mult18BigInt) + creditB)
264264
265265
266266 func calcTotalBalance (balanceA,balanceB,currentPrice) = (fraction(balanceA, currentPrice, mult18BigInt) + balanceB)
267267
268268
269269 func calcPnl (totalBalance,totalCredit) = (totalBalance - totalCredit)
270270
271271
272272 func calcCreditAvailable (deposit,leverage,totalCredit) = (fraction(deposit, leverage, mult18BigInt) - totalCredit)
273273
274274
275275 func calcRealInCredit (credit,balance) = if ((credit > big0))
276276 then (credit - balance)
277277 else big0
278278
279279
280280 func calcFree (credit,balance) = if ((credit > big0))
281281 then (balance - credit)
282282 else big0
283283
284284
285285 func calcShortPrice (free,realInCredit) = if ((realInCredit > big0))
286286 then max([big0, fraction(free, mult18BigInt, realInCredit)])
287287 else big0
288288
289289
290290 func calcLongPrice (free,realInCredit) = if ((realInCredit > big0))
291291 then max([big0, fraction(realInCredit, mult18BigInt, free)])
292292 else big0
293293
294294
295295 func calcStartMargin (realInCreditA,realInCreditB,currentPrice,settingsMargin) = fraction((fraction(realInCreditA, currentPrice, mult18BigInt) + realInCreditB), settingsMargin, mult18BigInt)
296296
297297
298298 func calcMarginSupply (settingsMarginSupply,settingsMargin,startMargin) = fraction(settingsMarginSupply, startMargin, settingsMargin)
299299
300300
301301 func calcLiquidationPrice (deposit,marginSupply,realInCreditA,realInCreditB,shortPrice,longPrice) = {
302302 let liquidationPriceA = if ((realInCreditA > big0))
303303 then (((deposit - marginSupply) / realInCreditA) + shortPrice)
304304 else big0
305305 let liquidationPriceB = if ((realInCreditB > big0))
306306 then (longPrice - ((deposit - marginSupply) / (realInCreditA / longPrice)))
307307 else big0
308308 (liquidationPriceA + liquidationPriceB)
309309 }
310310
311311
312312 func getRequestId (accountAddress) = {
313313 let requestId = fromBase58String(valueOrErrorMessage(getString(factoryAddress, kAccountAddressToRequestId(accountAddress)), wrapErr("invalid account address: request id is undefined")))
314314 requestId
315315 }
316316
317317
318318 func getAccountAssets (accountAddress) = {
319319 let requestId = getRequestId(accountAddress)
320320 let amountAssetId = parseAssetId(valueOrErrorMessage(getString(factoryAddress, kRequestAmountAssetId(requestId)), wrapErr("invalid amount asset id")))
321321 let priceAssetId = parseAssetId(valueOrErrorMessage(getString(factoryAddress, kRequestPriceAssetId(requestId)), wrapErr("invalid amount price id")))
322322 $Tuple2(amountAssetId, priceAssetId)
323323 }
324324
325325
326326 func getAccountOwnerPublicKey (accountAddress) = {
327327 let requestId = getRequestId(accountAddress)
328328 let requestOwnerPublicKey = valueOrErrorMessage(getBinary(factoryAddress, kRequestOwnerPublicKey(requestId)), wrapErr("invalid amount asset id"))
329329 requestOwnerPublicKey
330330 }
331331
332332
333333 func getAccountInfoInternal (accountAddress) = {
334334 let $t01118711255 = getAccountAssets(accountAddress)
335335 let amountAssetId = $t01118711255._1
336336 let priceAssetId = $t01118711255._2
337337 let leverage = valueOrErrorMessage(getInteger(factoryAddress, kLeverage(accountAddress)), wrapErr("leverage should be defined"))
338338 let requestId = getRequestId(accountAddress)
339339 let accountPublicKey = valueOrErrorMessage(getBinary(factoryAddress, kRequestIdToAccountPublicKey(requestId)), "kRequestIdToAccountPublicKey not found")
340340 let deposited = valueOrElse(depositedOption(accountAddress), 0)
341341 let currentPrice = toX18(getCurrentPrice(amountAssetId), pow10Decimals(priceAssetId))
342342 let creditA = valueOrElse(getInteger(factoryAddress, kCredit(accountAddress, amountAssetId)), 0)
343343 let creditB = valueOrElse(getInteger(factoryAddress, kCredit(accountAddress, priceAssetId)), 0)
344344 let status = valueOrErrorMessage(getInteger(factoryAddress, kRequestStatus(requestId)), ("status not found. RequestId = " + toBase58String(requestId)))
345- $Tuple12(assetIdToString(amountAssetId), assetIdToString(priceAssetId), toString(accountAddress), toBase58String(accountPublicKey), leverage, toBase58String(requestId), deposited, creditA, creditB, getAssetBalance(parseAssetId(getStringValue(kSyntheticAssetId(amountAssetId))), accountAddress), getAssetBalance(parseAssetId(getStringValue(kSyntheticAssetId(priceAssetId))), accountAddress), status)
345+ let synthAmountAssetId = getString(factoryAddress, kSyntheticAssetId(amountAssetId))
346+ let synthAmountAssetBalance = match synthAmountAssetId {
347+ case s: String =>
348+ getAssetBalance(parseAssetId(s), accountAddress)
349+ case _ =>
350+ 0
351+ }
352+ let synthPriceAssetId = getString(factoryAddress, kSyntheticAssetId(priceAssetId))
353+ let synthPriceAssetBalance = match synthPriceAssetId {
354+ case s: String =>
355+ getAssetBalance(parseAssetId(s), accountAddress)
356+ case _ =>
357+ 0
358+ }
359+ $Tuple12(assetIdToString(amountAssetId), assetIdToString(priceAssetId), toString(accountAddress), toBase58String(accountPublicKey), leverage, toBase58String(requestId), deposited, creditA, creditB, synthAmountAssetBalance, synthPriceAssetBalance, status)
346360 }
347361
348362
349363 @Callable(i)
350364 func init (factoryAddressStr) = {
351365 let checkCaller = mustThis(i.caller)
352366 if ((checkCaller == checkCaller))
353367 then $Tuple2([StringEntry(kFactoryAddress, factoryAddressStr)], unit)
354368 else throw("Strict value is not equal to itself.")
355369 }
356370
357371
358372
359373 @Callable(i)
360374 func requestAccount (callerPublicKey,args) = {
361375 let ckecks = [if (!(shutdown))
362376 then true
363377 else throwErr("not allowed"), mustFactory(i.caller)]
364378 if ((ckecks == ckecks))
365379 then {
366380 let amountAssetIdStr = args[0]
367381 let priceAssetIdStr = args[1]
368382 let leverage = valueOrErrorMessage(parseInt(args[2]), wrapErr("invalid leverage"))
369383 let userAddress = addressFromPublicKey(callerPublicKey)
370384 let requestId = sha256(((userAddress.bytes + fromBase58String(amountAssetIdStr)) + fromBase58String(priceAssetIdStr)))
371385 let amountAssetId = parseAssetId(amountAssetIdStr)
372386 let priceAssetId = parseAssetId(priceAssetIdStr)
373387 let userRequestsNumber = (size(kRequestsByOwner(userAddress)) / queueItemSize)
374388 let checks = [if ((size(i.payments) == 1))
375389 then true
376390 else throwErr("1 payment is required"), if ((i.payments[0].assetId == unit))
377391 then true
378392 else throwErr("invalid asset"), if ((i.payments[0].amount == rewardAmount()))
379393 then true
380394 else throwErr("invalid amount"), if (pairAllowed(amountAssetId, priceAssetId))
381395 then true
382396 else throwErr("pair is not allowed"), if ((getInteger(factoryAddress, kRequestStatus(requestId)) == unit))
383397 then true
384398 else throwErr("account is already exists"), if ((accountsLimit() > userRequestsNumber))
385399 then true
386400 else throwErr(("accounts limit is " + toString(accountsLimit())))]
387401 if ((checks == checks))
388402 then {
389- let $t01419115724 = if ((size(accountsQueue()) == 0))
403+ let $t01452916062 = if ((size(accountsQueue()) == 0))
390404 then $Tuple2([ScriptTransfer(factoryAddress, rewardAmount(), unit)], [invoke(factoryAddress, "integerEntry", [kRequestStatus(requestId), REQUEST_STATUS_EMPTY], nil), invoke(factoryAddress, "binaryEntry", [kRequestsQueue(), (requestsQueue() + requestId)], nil), invoke(factoryAddress, "integerEntry", [kRequestLeverage(requestId), leverage], nil)])
391405 else {
392406 let accountPublicKey = take(accountsQueue(), queueItemSize)
393407 let accountAddress = addressFromPublicKey(accountPublicKey)
394408 let creatorAddress = addressFromPublicKey(valueOrErrorMessage(getBinary(factoryAddress, kAccountCreatorPublicKey(accountAddress)), wrapErr("invalid creator public key")))
395409 $Tuple2([ScriptTransfer(creatorAddress, rewardAmount(), unit)], [invoke(factoryAddress, "binaryEntry", [kAccountsQueue(), drop(accountsQueue(), queueItemSize)], nil), invoke(factoryAddress, "integerEntry", [kRequestStatus(requestId), REQUEST_STATUS_READY], nil), invoke(factoryAddress, "binaryEntry", [kRequestIdToAccountPublicKey(requestId), accountPublicKey], nil), invoke(factoryAddress, "stringEntry", [kAccountAddressToRequestId(accountAddress), toBase58String(requestId)], nil), invoke(factoryAddress, "integerEntry", [kLeverage(accountAddress), leverage], nil)])
396410 }
397- let actions = $t01419115724._1
398- let factoryActions = $t01419115724._2
411+ let actions = $t01452916062._1
412+ let factoryActions = $t01452916062._2
399413 $Tuple2(actions, (factoryActions ++ [invoke(factoryAddress, "binaryEntry", [kRequestOwnerPublicKey(requestId), callerPublicKey], nil), invoke(factoryAddress, "binaryEntry", [kRequestsByOwner(userAddress), (requestsByOwner(userAddress) + requestId)], nil), invoke(factoryAddress, "stringEntry", [kRequestAmountAssetId(requestId), amountAssetIdStr], nil), invoke(factoryAddress, "stringEntry", [kRequestPriceAssetId(requestId), priceAssetIdStr], nil)]))
400414 }
401415 else throw("Strict value is not equal to itself.")
402416 }
403417 else throw("Strict value is not equal to itself.")
404418 }
405419
406420
407421
408422 @Callable(i)
409423 func addAccount (callerPublicKey,args) = {
410424 let ckecks = [if (!(shutdown))
411425 then true
412426 else throwErr("not allowed"), mustFactory(i.caller)]
413427 if ((ckecks == ckecks))
414428 then {
415429 let creatorPublicKey = fromBase58String(args[0])
416430 let accountPublicKey = callerPublicKey
417431 let accountAddress = addressFromPublicKey(callerPublicKey)
418432 let creatorAddress = addressFromPublicKey(creatorPublicKey)
419433 let checks = [if ((getBinary(factoryAddress, kAccountCreatorPublicKey(accountAddress)) == unit))
420434 then true
421435 else throwErr("account is already exists"), if ( match scriptHash(accountAddress) {
422436 case b: ByteVector =>
423437 (b == blake2b256_32Kb(accountScript()))
424438 case _ =>
425439 false
426440 })
427441 then true
428442 else throwErr("invalid script")]
429443 if ((checks == checks))
430444 then {
431- let $t01697918220 = if ((size(requestsQueue()) == 0))
445+ let $t01731718558 = if ((size(requestsQueue()) == 0))
432446 then $Tuple2(nil, [invoke(factoryAddress, "binaryEntry", [kAccountsQueue(), (accountsQueue() + accountPublicKey)], nil)])
433447 else {
434448 let requestId = take(requestsQueue(), queueItemSize)
435449 let leverage = valueOrErrorMessage(getInteger(factoryAddress, kRequestLeverage(requestId)), wrapErr("request's leverage is undefined"))
436450 $Tuple2(nil, [invoke(factoryAddress, "integerEntry", [kRequestStatus(requestId), REQUEST_STATUS_READY], nil), invoke(factoryAddress, "binaryEntry", [kRequestIdToAccountPublicKey(requestId), accountPublicKey], nil), invoke(factoryAddress, "binaryEntry", [kRequestsQueue(), drop(requestsQueue(), queueItemSize)], nil), invoke(factoryAddress, "stringEntry", [kAccountAddressToRequestId(accountAddress), toBase58String(requestId)], nil), invoke(factoryAddress, "transferWaves", [creatorAddress.bytes, rewardAmount()], nil), invoke(factoryAddress, "integerEntry", [kLeverage(accountAddress), leverage], nil)])
437451 }
438- let actions = $t01697918220._1
439- let factoryActions = $t01697918220._2
452+ let actions = $t01731718558._1
453+ let factoryActions = $t01731718558._2
440454 $Tuple2(actions, (factoryActions ++ [invoke(factoryAddress, "binaryEntry", [kAccountCreatorPublicKey(accountAddress), creatorPublicKey], nil)]))
441455 }
442456 else throw("Strict value is not equal to itself.")
443457 }
444458 else throw("Strict value is not equal to itself.")
445459 }
446460
447461
448462
449463 @Callable(i)
450464 func deposit (callerPublicKey,args) = {
451465 let payment = i.payments[0]
452466 let accountAddress = valueOrErrorMessage(addressFromString(args[0]), wrapErr("invalid account address"))
453467 let ckecks = [if (!(shutdown))
454468 then true
455469 else throwErr("not allowed"), mustFactory(i.caller), if ((size(i.payments) == 1))
456470 then true
457471 else throwErr("1 payment is required"), if ((payment.assetId == usdtAssetId))
458472 then true
459473 else throwErr("invalid asset"), if ((getInteger(factoryAddress, kRequestStatus(getRequestId(accountAddress))) == REQUEST_STATUS_READY))
460474 then true
461475 else throwErr("account is not ready")]
462476 if ((ckecks == ckecks))
463477 then {
464478 let actions = [ScriptTransfer(accountAddress, payment.amount, payment.assetId)]
465479 let factoryActions = [invoke(factoryAddress, "integerEntry", [kDeposited(accountAddress), (valueOrElse(depositedOption(accountAddress), 0) + payment.amount)], nil)]
466480 $Tuple2(actions, factoryActions)
467481 }
468482 else throw("Strict value is not equal to itself.")
469483 }
470484
471485
472486
473487 @Callable(i)
474488 func withdraw (callerPublicKey,args) = {
475489 let ckecks = [if (!(shutdown))
476490 then true
477491 else throwErr("not allowed"), mustFactory(i.caller)]
478492 if ((ckecks == ckecks))
479493 then {
480494 let userAddress = addressFromPublicKey(callerPublicKey)
481495 let accountAddress = valueOrErrorMessage(addressFromString(args[0]), wrapErr("invalid account address"))
482496 let amount = valueOrErrorMessage(parseInt(args[1]), wrapErr("invalid amount"))
483497 let assetId = parseAssetId(args[2])
484498 let invocations = [invoke(accountAddress, "transferAsset", [userAddress.bytes, amount, assetId], nil)]
485499 $Tuple2(nil, invocations)
486500 }
487501 else throw("Strict value is not equal to itself.")
488502 }
489503
490504
491505
492506 @Callable(i)
493507 func borrow (callerPublicKey,args) = {
494508 let accountAddress = valueOrErrorMessage(addressFromString(args[0]), wrapErr("invalid account address"))
495509 let assetIdRequested = parseAssetId(args[1])
496510 let amountRequested = ensurePositive(valueOrErrorMessage(parseInt(args[2]), wrapErr("invalid requested amount")), "requested amount")
497511 let accountOwnerPublicKey = getAccountOwnerPublicKey(accountAddress)
498512 let userAddress = addressFromPublicKey(callerPublicKey)
499513 let ckecks = [if (!(shutdown))
500514 then true
501515 else throwErr("not allowed"), mustFactory(i.caller), if ((callerPublicKey == accountOwnerPublicKey))
502516 then true
503517 else throwErr("can be called by account owner only")]
504518 if ((ckecks == ckecks))
505519 then {
506520 let amountAssetId = getAccountAssets(accountAddress)._1
507521 let deposited = toX18(valueOrElse(depositedOption(accountAddress), 0), pow10Decimals(usdtAssetId))
508522 let currentPrice = toX18(getCurrentPrice(amountAssetId), pow10Decimals(usdtAssetId))
509523 let creditA = toX18(valueOrElse(getInteger(factoryAddress, kCredit(accountAddress, amountAssetId)), 0), pow10Decimals(amountAssetId))
510524 let creditB = toX18(valueOrElse(getInteger(factoryAddress, kCredit(accountAddress, usdtAssetId)), 0), pow10Decimals(usdtAssetId))
511525 let totalCredit = calcTotalCredit(creditA, creditB, currentPrice)
512526 let leverage = toX18(valueOrErrorMessage(getInteger(factoryAddress, kLeverage(accountAddress)), wrapErr("leverage should be defined")), 1)
513527 let creditAvailableUsdt = calcCreditAvailable(deposited, leverage, totalCredit)
514528 let creditAvailable = if ((assetIdRequested == amountAssetId))
515529 then fromX18(fraction(creditAvailableUsdt, mult18BigInt, currentPrice), pow10Decimals(amountAssetId))
516530 else if ((assetIdRequested == usdtAssetId))
517531 then fromX18(creditAvailableUsdt, pow10Decimals(usdtAssetId))
518532 else throwErr("invalid requested asset id")
519533 let syntheticAssetId = parseAssetId(valueOrErrorMessage(getString(factoryAddress, kSyntheticAssetId(assetIdRequested)), wrapErr("synthetic asset for requested asset is undefined")))
520534 let amountToSend = if ((creditAvailable >= amountRequested))
521535 then amountRequested
522536 else throwErr(("credit available = " + toString(creditAvailable)))
523537 let factoryActions = [invoke(factoryAddress, "integerEntry", [kCredit(accountAddress, assetIdRequested), (valueOrElse(creditOption(accountAddress, assetIdRequested), 0) + amountToSend)], nil), invoke(factoryAddress, "transferAsset", [userAddress.bytes, amountToSend, syntheticAssetId], nil)]
524538 $Tuple2(nil, [factoryActions, creditAvailable])
525539 }
526540 else throw("Strict value is not equal to itself.")
527541 }
528542
529543
530544
531545 @Callable(i)
532546 func repay (callerPublicKey,args) = {
533547 let ckecks = [if (!(shutdown))
534548 then true
535549 else throwErr("not allowed"), mustFactory(i.caller)]
536550 if ((ckecks == ckecks))
537551 then $Tuple2(nil, unit)
538552 else throw("Strict value is not equal to itself.")
539553 }
540554
541555
542556
543557 @Callable(i)
544558 func setPairAllowance (callerPublicKey,args) = {
545559 let ckecks = [if (!(shutdown))
546560 then true
547561 else throwErr("not allowed"), mustFactory(i.caller), mustAdmin(callerPublicKey)]
548562 if ((ckecks == ckecks))
549563 then {
550564 let amountAssetIdStr = args[0]
551565 let priceAssetIdStr = args[1]
552566 let allowStr = args[2]
553567 let amountAssetId = parseAssetId(amountAssetIdStr)
554568 let priceAssetId = parseAssetId(priceAssetIdStr)
555569 let allow = (allowStr == "true")
556570 let invocations = [invoke(factoryAddress, "booleanEntry", [kPairAllowed(amountAssetId, priceAssetId), allow], nil)]
557571 $Tuple2(nil, invocations)
558572 }
559573 else throw("Strict value is not equal to itself.")
560574 }
561575
562576
563577
564578 @Callable(i)
565579 func addSyntheticAsset (callerPublicKey,args) = {
566580 let baseAssetId = parseAssetId(args[0])
567581 let syntheticAssetId = parseAssetId(args[1])
568582 let ckecks = [if (!(shutdown))
569583 then true
570584 else throwErr("not allowed"), mustFactory(i.caller), mustAdmin(callerPublicKey), if ((getString(factoryAddress, kSyntheticAssetId(baseAssetId)) == unit))
571585 then true
572586 else throwErr("invalid base asset"), if ((getString(factoryAddress, kBaseAssetId(syntheticAssetId)) == unit))
573587 then true
574588 else throwErr("invalid synthetic asset")]
575589 if ((ckecks == ckecks))
576590 then {
577591 let invocations = [invoke(factoryAddress, "stringEntry", [kSyntheticAssetId(baseAssetId), assetIdToString(syntheticAssetId)], nil), invoke(factoryAddress, "stringEntry", [kBaseAssetId(syntheticAssetId), assetIdToString(baseAssetId)], nil)]
578592 $Tuple2(nil, invocations)
579593 }
580594 else throw("Strict value is not equal to itself.")
581595 }
582596
583597
584598
585599 @Callable(i)
586600 func doShutdown (callerPublicKey,args) = {
587601 let checks = [mustFactory(i.caller), mustAdmin(callerPublicKey)]
588602 if ((checks == checks))
589603 then {
590604 let invocations = [invoke(factoryAddress, "booleanEntry", [kShutdown, true], nil)]
591605 $Tuple2(nil, invocations)
592606 }
593607 else throw("Strict value is not equal to itself.")
594608 }
595609
596610
597611
598612 @Callable(i)
599613 func getAccountInfoREADONLY (callerPublicKey,args) = {
600614 let checks = [mustFactory(i.caller)]
601615 if ((checks == checks))
602616 then {
603617 let accountAddress = valueOrErrorMessage(addressFromString(args[0]), wrapErr("invalid account address"))
604618 let data = getAccountInfoInternal(accountAddress)
605619 $Tuple2(nil, data)
606620 }
607621 else throw("Strict value is not equal to itself.")
608622 }
609623
610624
611625
612626 @Callable(i)
613627 func getUserInfoREADONLY (callerPublicKey,args) = {
614628 let checks = [mustFactory(i.caller)]
615629 if ((checks == checks))
616630 then {
617631 let userAddress = valueOrErrorMessage(addressFromString(args[0]), wrapErr("invalid user address"))
618632 let userRequests = valueOrElse(getBinary(factoryAddress, kRequestsByOwner(userAddress)), base58'')
619633 let userRequestsNumber = (size(userRequests) / queueItemSize)
620634 func getAccountsData (acc,count) = {
621- let $t02565625698 = acc
622- let accDataList = $t02565625698._1
623- let rawBytes = $t02565625698._2
624- let maxSize = $t02565625698._3
635+ let $t02599426036 = acc
636+ let accDataList = $t02599426036._1
637+ let rawBytes = $t02599426036._2
638+ let maxSize = $t02599426036._3
625639 if ((maxSize > count))
626640 then {
627641 let requestId = take(rawBytes, queueItemSize)
628642 let newRawBytes = drop(rawBytes, queueItemSize)
629643 let accountPublicKey = valueOrErrorMessage(getBinary(factoryAddress, kRequestIdToAccountPublicKey(requestId)), "kRequestIdToAccountPublicKey not found")
630644 let accountAddress = addressFromPublicKey(accountPublicKey)
631645 let data = getAccountInfoInternal(accountAddress)
632646 $Tuple3((accDataList :+ data), newRawBytes, maxSize)
633647 }
634648 else acc
635649 }
636650
637- let $t02620226307 = {
651+ let $t02654026645 = {
638652 let $l = INDEX_LIST
639653 let $s = size($l)
640654 let $acc0 = $Tuple3(nil, userRequests, userRequestsNumber)
641655 func $f0_1 ($a,$i) = if (($i >= $s))
642656 then $a
643657 else getAccountsData($a, $l[$i])
644658
645659 func $f0_2 ($a,$i) = if (($i >= $s))
646660 then $a
647661 else throw("List size exceeds 20")
648662
649663 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
650664 }
651- let accDataList = $t02620226307._1
652- let _a = $t02620226307._2
653- let _b = $t02620226307._3
665+ let accDataList = $t02654026645._1
666+ let _a = $t02654026645._2
667+ let _b = $t02654026645._3
654668 $Tuple2(nil, accDataList)
655669 }
656670 else throw("Strict value is not equal to itself.")
657671 }
658672
659673
660674
661675 @Callable(i)
662676 func getPairSettingsInfoREADONLY (callerPublicKey,args) = {
663677 let amountAsset = parseAssetId(args[0])
664678 let priceAsset = parseAssetId(args[1])
665679 let pricesList = getPairPricesList(amountAsset, priceAsset)
666680 func getPairSettings (acc,pricesString) = {
667681 let settingsKey = kPairSettingsKey(amountAsset, priceAsset, pricesString)
668682 let settingsStringValue = getStringValue(factoryAddress, settingsKey)
669683 let sList = split(settingsStringValue, separator)
670684 let price = parseInt(pricesString)
671685 let maxLeverage = parseInt(sList[1])
672686 let initialMargin = parseInt(sList[2])
673687 let maintenanceMargin = parseInt(sList[3])
674688 (acc :+ $Tuple4(price, maxLeverage, initialMargin, maintenanceMargin))
675689 }
676690
677691 let data = {
678692 let $l = pricesList
679693 let $s = size($l)
680694 let $acc0 = nil
681695 func $f0_1 ($a,$i) = if (($i >= $s))
682696 then $a
683697 else getPairSettings($a, $l[$i])
684698
685699 func $f0_2 ($a,$i) = if (($i >= $s))
686700 then $a
687701 else throw("List size exceeds 20")
688702
689703 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
690704 }
691705 $Tuple2(nil, data)
692706 }
693707
694708
695709
696710 @Callable(i)
697711 func editPairSettings (callerPublicKey,args) = {
698712 let checks = [mustFactory(i.caller)]
699713 if ((checks == checks))
700714 then {
701715 let amountAsset = parseAssetId(args[0])
702716 let priceAsset = parseAssetId(args[1])
703717 let price = args[2]
704718 let maxLeverage = args[3]
705719 let initialMargin = args[4]
706720 let maintenanceMargin = args[5]
707721 let pairPricesListKey = kPairPricesListKey(amountAsset, priceAsset)
708722 let settingsKey = kPairSettingsKey(amountAsset, priceAsset, price)
709723 let pricesList = getPairPricesList(amountAsset, priceAsset)
710724 let newList = match indexOf(pricesList, price) {
711725 case ind: Int =>
712726 pricesList
713727 case _ =>
714728 (pricesList :+ price)
715729 }
716730 let check2 = [valueOrErrorMessage(parseInt(price), wrapErr("price value is not an Int")), valueOrErrorMessage(maxLeverage, wrapErr("maxLeverage value is not an Int")), valueOrErrorMessage(initialMargin, wrapErr("initialMargin value is not an Int")), valueOrErrorMessage(maintenanceMargin, wrapErr("maintenanceMargin value is not an Int")), if ((20 >= size(newList)))
717731 then true
718732 else throwErr("exceeded max prices list size (20)")]
719733 if ((check2 == check2))
720734 then {
721735 let pairSettingValue = makeString(["%s%s%s", maxLeverage, initialMargin, maintenanceMargin], separator)
722736 let invocations = [invoke(factoryAddress, "stringEntry", [kPairPricesListKey(amountAsset, priceAsset), makeString(newList, separator)], nil), invoke(factoryAddress, "stringEntry", [kPairSettingsKey(amountAsset, priceAsset, price), pairSettingValue], nil)]
723737 $Tuple2(nil, invocations)
724738 }
725739 else throw("Strict value is not equal to itself.")
726740 }
727741 else throw("Strict value is not equal to itself.")
728742 }
729743
730744
731745
732746 @Callable(i)
733747 func deletePairSettings (callerPublicKey,args) = {
734748 let checks = [mustFactory(i.caller)]
735749 if ((checks == checks))
736750 then {
737751 let amountAsset = parseAssetId(args[0])
738752 let priceAsset = parseAssetId(args[1])
739753 let price = args[2]
740754 let settingsKey = kPairSettingsKey(amountAsset, priceAsset, price)
741755 let pairPricesListKey = kPairPricesListKey(amountAsset, priceAsset)
742756 let pricesList = getPairPricesList(amountAsset, priceAsset)
743757 let newList = match indexOf(pricesList, price) {
744758 case ind: Int =>
745759 removeByIndex(pricesList, ind)
746760 case _ =>
747761 pricesList
748762 }
749763 let invocations = [invoke(factoryAddress, "deleteEntry", [settingsKey], nil), if ((size(newList) == 0))
750764 then invoke(factoryAddress, "deleteEntry", [kPairPricesListKey(amountAsset, priceAsset)], nil)
751765 else invoke(factoryAddress, "stringEntry", [kPairPricesListKey(amountAsset, priceAsset), makeString(newList, separator)], nil)]
752766 $Tuple2(nil, invocations)
753767 }
754768 else throw("Strict value is not equal to itself.")
755769 }
756770
757771
758772 @Verifier(tx)
759773 func verify () = if (if (isDefined(factoryAddressOption))
760774 then isDefined(getString(factoryAddress, kMultisig))
761775 else false)
762776 then match getString(factoryAddress, kMultisig) {
763777 case multisig: String =>
764778 let statusKey = kStatus(toString(this), toBase58String(tx.id))
765779 let status = valueOrElse(getBoolean(addressFromStringValue(multisig), statusKey), false)
766780 status
767781 case _ =>
768782 false
769783 }
770784 else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
771785

github/deemru/w8io/169f3d6 
101.97 ms