tx · BTYja6QxptZ1NwMXPkixQaRBk3FHwjxbY5y6bjBn3ojP

3MpSqJhv64PR2m7Ywctv1Mp2Kjt3EUk3CSK:  -0.02300000 Waves

2023.03.19 16:39 [2496967] smart account 3MpSqJhv64PR2m7Ywctv1Mp2Kjt3EUk3CSK > SELF 0.00000000 Waves

{ "type": 13, "id": "BTYja6QxptZ1NwMXPkixQaRBk3FHwjxbY5y6bjBn3ojP", "fee": 2300000, "feeAssetId": null, "timestamp": 1679233118221, "version": 2, "chainId": 84, "sender": "3MpSqJhv64PR2m7Ywctv1Mp2Kjt3EUk3CSK", "senderPublicKey": "ErJhyueNNWWr8GEv71cFyhNnAtRC7sZt2TWFo89gdPo8", "proofs": [ "3H1dahVNu2FvHgb29PqvVhNLNXc3XVgRpRpgiizmHngLYcS8jtGKCPJUZZfM9iH3yWQojYUCsLZhr9LAyqGssCEz" ], "script": "base64:BgI6CAISCAoGAQEBCAEIEgYKBAEYAQgSBQoDAQEIEgcKBQEBCAgIEgUKAwEBCBIDCgEIEgMKAQESAwoBCHMACVNFUEFSQVRPUgICX18ACEtFWV9JTklUAgRJTklUAAxLRVlfTVVMVElTSUcCCE1VTFRJU0lHAApLRVlfU1RBVFVTAgZTVEFUVVMAEEtFWV9NSU5fU0VDX0RFUE8CDE1JTl9TRUNfREVQTwAOS0VZX1BVTklTSE1FTlQCClBVTklTSE1FTlQAFUtFWV9SRVNFVF9CTE9DS19ERUxUQQIRUkVTRVRfQkxPQ0tfREVMVEEADEtFWV9TRUNfREVQTwIIU0VDX0RFUE8AGEtFWV9SRVdBUkRfVE9LRU5fQUREUkVTUwIUUkVXQVJEX1RPS0VOX0FERFJFU1MAEUtFWV9SRVdBUkRfQU1PVU5UAg1SRVdBUkRfQU1PVU5UABNLRVlfV0lOVEVTU19BRERSRVNTAg9XSU5URVNTX0FERFJFU1MAEUtFWV9DVVJSRU5UX0VQT0NIAg1DVVJSRU5UX0VQT0NIABVLRVlfU0lHTkVSU19QRVJfRVBPQ0gCEVNJR05FUlNfUEVSX0VQT0NIABBLRVlfRVZFTlRfU1RBVFVTAgxFVkVOVF9TVEFUVVMACUtFWV9MT0NLUwIFTE9DS1MABUtFWV9UAgFUAAVLRVlfUgIBUgAFS0VZX1MCAVMADUtFWV9SX1NJR05FUlMCCVJfU0lHTkVSUwAVS0VZX0VWRU5UX1NUQVJUX0JMT0NLAhFFVkVOVF9TVEFSVF9CTE9DSwALS0VZX1JfU0lHTUECB1JfU0lHTUEAC0tFWV9TX1NJR01BAgdTX1NJR01BAA1LRVlfU19TSUdORVJTAglTX1NJR05FUlMAGUtFWV9TSUdORURfRVZFTlRfRVhFQ1VUT1ICFVNJR05FRF9FVkVOVF9FWEVDVVRPUgAIS0VZX1NJWkUCBFNJWkUAG0tFWV9TSUdORVJfR1JPVVBfUFVCTElDX0tFWQIXU0lHTkVSX0dST1VQX1BVQkxJQ19LRVkADkZVTkNfTUlOVF9NQU5ZAghtaW50TWFueQAXRlVOQ19JU19DT05GSVJNRURfRVZFTlQCEGlzQ29uZmlybWVkRXZlbnQAEkZVTkNfR0VUX1JBV19FVkVOVAILZ2V0UmF3RXZlbnQAEEVWRU5UX1RZUEVfV0FWRVMCBVdBVkVTAA5FVkVOVF9UWVBFX0VWTQIDRVZNABFFVkVOVF9TVEFUVVNfSU5JVAABABFFVkVOVF9TVEFUVVNfU0lHTgACABFFVkVOVF9TVEFUVVNfRE9ORQADAAdNQVhfSU5UAP//////////fwEQX3ZhbGlkYXRlQWRkcmVzcwIIYWRkcmVzc18EZXJyXwQHJG1hdGNoMAkApggBBQhhZGRyZXNzXwMJAAECBQckbWF0Y2gwAgdBZGRyZXNzBAFhBQckbWF0Y2gwBgkAAgEFBGVycl8BDl92YWxpZGF0ZUFzc2V0Aghhc3NldElkXwRlcnJfBAckbWF0Y2gwCQDsBwEJANkEAQUIYXNzZXRJZF8DCQABAgUHJG1hdGNoMAIFQXNzZXQEAWEFByRtYXRjaDAGCQACAQUEZXJyXwEMX3ZhbGlkYXRlSW50BAR2YWxfDmxvd2VyQm91bmRhcnlfDnVwcGVyQm91bmRhcnlfBGVycl8DAwkAZgIFDmxvd2VyQm91bmRhcnlfBQR2YWxfBgkAZgIFBHZhbF8FDnVwcGVyQm91bmRhcnlfCQACAQUEZXJyXwYBD192YWxpZGF0ZVN0cmluZwIEdmFsXwRlcnJfAwMJAGcCAAAJALECAQUEdmFsXwYJAQhjb250YWlucwIFBHZhbF8FCVNFUEFSQVRPUgkAAgEFBGVycl8GARVfdmFsaWRhdGVQYXltZW50c1NpemUDCXBheW1lbnRzXwd0YXJnZXRfBGVycl8DCQECIT0CCQCQAwEFCXBheW1lbnRzXwUHdGFyZ2V0XwkAAgEFBGVycl8GARVfdmFsaWRhdGVQYXltZW50QXNzZXQDCHBheW1lbnRfBmFzc2V0XwRlcnJfAwkBAiE9AggFCHBheW1lbnRfB2Fzc2V0SWQFBmFzc2V0XwkAAgEFBGVycl8GARJfdmFsaWRhdGVQdWJsaWNLZXkCCnB1YmxpY0tleV8EZXJyXwMJAQIhPQIJAMgBAQkA2QQBBQpwdWJsaWNLZXlfACAJAAIBBQRlcnJfBgETX3ZhbGlkYXRlUHVibGljS2V5cwILcHVibGljS2V5c18EZXJyXwoBCGZvbGRGdW5jAgNhY2MEZWxlbQkAlAoCAwgFA2FjYwJfMQkBEl92YWxpZGF0ZVB1YmxpY0tleQIFBGVsZW0IBQNhY2MCXzIHCAUDYWNjAl8yBAZyZXN1bHQKAAIkbAULcHVibGljS2V5c18KAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIGBQRlcnJfCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhmb2xkRnVuYwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACggFBnJlc3VsdAJfMQEJX2xvYWRJbml0AAQHJG1hdGNoMAkAoAgBBQhLRVlfSU5JVAMJAAECBQckbWF0Y2gwAgdCb29sZWFuBAFhBQckbWF0Y2gwBQFhBwEJX3NhdmVJbml0AQdpc0luaXRfCQDMCAIJAQxCb29sZWFuRW50cnkCBQhLRVlfSU5JVAUHaXNJbml0XwUDbmlsAQ1fbG9hZE11bHRpc2lnAAQHJG1hdGNoMAkAoggBBQxLRVlfTVVMVElTSUcDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwCQERQGV4dHJOYXRpdmUoMTA2MikBBQFhCQEHQWRkcmVzcwEBAAENX3NhdmVNdWx0aXNpZwEJbXVsdGlzaWdfCQDMCAIJAQtTdHJpbmdFbnRyeQIFDEtFWV9NVUxUSVNJRwkApQgBBQltdWx0aXNpZ18FA25pbAEPX2xvYWRNaW5TZWNEZXBvAAQHJG1hdGNoMAkAnwgBBRBLRVlfTUlOX1NFQ19ERVBPAwkAAQIFByRtYXRjaDACA0ludAQBYQUHJG1hdGNoMAUBYQAAAQ9fc2F2ZU1pblNlY0RlcG8BBHZhbF8JAMwIAgkBDEludGVnZXJFbnRyeQIFEEtFWV9NSU5fU0VDX0RFUE8FBHZhbF8FA25pbAEMX2xvYWRTZWNEZXBvAQhhY2NvdW50XwQHJG1hdGNoMAkAnwgBCQC5CQIJAMwIAgUMS0VZX1NFQ19ERVBPCQDMCAIJAKUIAQUIYWNjb3VudF8FA25pbAUJU0VQQVJBVE9SAwkAAQIFByRtYXRjaDACA0ludAQBYQUHJG1hdGNoMAUBYQAAAQxfc2F2ZVNlY0RlcG8CCGFjY291bnRfBHZhbF8JAMwIAgkBDEludGVnZXJFbnRyeQIJALkJAgkAzAgCBQxLRVlfU0VDX0RFUE8JAMwIAgkApQgBBQhhY2NvdW50XwUDbmlsBQlTRVBBUkFUT1IFBHZhbF8FA25pbAEPX2xvYWRQdW5pc2htZW50AAQHJG1hdGNoMAkAnwgBBQ5LRVlfUFVOSVNITUVOVAMJAAECBQckbWF0Y2gwAgNJbnQEAWEFByRtYXRjaDAFAWEAAAEPX3NhdmVQdW5pc2htZW50AQR2YWxfCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5LRVlfUFVOSVNITUVOVAUEdmFsXwUDbmlsARRfbG9hZFJlc2V0QmxvY2tEZWx0YQAEByRtYXRjaDAJAJ8IAQUVS0VZX1JFU0VUX0JMT0NLX0RFTFRBAwkAAQIFByRtYXRjaDACA0ludAQBYQUHJG1hdGNoMAUBYQAAARRfc2F2ZVJlc2V0QmxvY2tEZWx0YQEEdmFsXwkAzAgCCQEMSW50ZWdlckVudHJ5AgUVS0VZX1JFU0VUX0JMT0NLX0RFTFRBBQR2YWxfBQNuaWwBF19sb2FkUmV3YXJkVG9rZW5BZGRyZXNzAAQHJG1hdGNoMAkAoggBBRhLRVlfUkVXQVJEX1RPS0VOX0FERFJFU1MDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwCQERQGV4dHJOYXRpdmUoMTA2MikBBQFhCQEHQWRkcmVzcwEBAAEXX3NhdmVSZXdhcmRUb2tlbkFkZHJlc3MBBHZhbF8JAMwIAgkBC1N0cmluZ0VudHJ5AgUYS0VZX1JFV0FSRF9UT0tFTl9BRERSRVNTCQClCAEFBHZhbF8FA25pbAERX2xvYWRSZXdhcmRBbW91bnQABAckbWF0Y2gwCQCfCAEFEUtFWV9SRVdBUkRfQU1PVU5UAwkAAQIFByRtYXRjaDACA0ludAQBYQUHJG1hdGNoMAUBYQAAARFfc2F2ZVJld2FyZEFtb3VudAEEdmFsXwkAzAgCCQEMSW50ZWdlckVudHJ5AgURS0VZX1JFV0FSRF9BTU9VTlQFBHZhbF8FA25pbAETX2xvYWRXaXRuZXNzQWRkcmVzcwAEByRtYXRjaDAJAKIIAQUTS0VZX1dJTlRFU1NfQUREUkVTUwMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWEFByRtYXRjaDAJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAWEJAQdBZGRyZXNzAQEAARNfc2F2ZVdpdG5lc3NBZGRyZXNzAQR2YWxfCQDMCAIJAQtTdHJpbmdFbnRyeQIFE0tFWV9XSU5URVNTX0FERFJFU1MJAKUIAQUEdmFsXwUDbmlsARFfbG9hZEN1cnJlbnRFcG9jaAEMZXhlY0NoYWluSWRfBAckbWF0Y2gwCQCfCAEJALkJAgkAzAgCBRFLRVlfQ1VSUkVOVF9FUE9DSAkAzAgCCQCkAwEFDGV4ZWNDaGFpbklkXwUDbmlsBQlTRVBBUkFUT1IDCQABAgUHJG1hdGNoMAIDSW50BAFhBQckbWF0Y2gwBQFhAAABEV9zYXZlQ3VycmVudEVwb2NoAgxleGVjQ2hhaW5JZF8EdmFsXwkAzAgCCQEMSW50ZWdlckVudHJ5AgkAuQkCCQDMCAIFEUtFWV9DVVJSRU5UX0VQT0NICQDMCAIJAKQDAQUMZXhlY0NoYWluSWRfBQNuaWwFCVNFUEFSQVRPUgUEdmFsXwUDbmlsAQxfbG9hZFNpZ25lcnMCDGV4ZWNDaGFpbklkXwZlcG9jaF8EByRtYXRjaDAJAKIIAQkAuQkCCQDMCAIFFUtFWV9TSUdORVJTX1BFUl9FUE9DSAkAzAgCCQCkAwEFDGV4ZWNDaGFpbklkXwkAzAgCCQCkAwEFBmVwb2NoXwUDbmlsBQlTRVBBUkFUT1IDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwAwkAZgIJALECAQUBYQAACQC1CQIFAWEFCVNFUEFSQVRPUgUDbmlsBQNuaWwBDF9zYXZlU2lnbmVycwMMZXhlY0NoYWluSWRfBmVwb2NoXwhzaWduZXJzXwkAzAgCCQELU3RyaW5nRW50cnkCCQC5CQIJAMwIAgUVS0VZX1NJR05FUlNfUEVSX0VQT0NICQDMCAIJAKQDAQUMZXhlY0NoYWluSWRfCQDMCAIJAKQDAQUGZXBvY2hfBQNuaWwFCVNFUEFSQVRPUgkAuQkCBQhzaWduZXJzXwUJU0VQQVJBVE9SBQNuaWwBEF9sb2FkRXZlbnRTdGF0dXMCDGV4ZWNDaGFpbklkXwhldmVudElkXwQHJG1hdGNoMAkAnwgBCQC5CQIJAMwIAgUQS0VZX0VWRU5UX1NUQVRVUwkAzAgCCQCkAwEFDGV4ZWNDaGFpbklkXwkAzAgCCQCkAwEFCGV2ZW50SWRfBQNuaWwFCVNFUEFSQVRPUgMJAAECBQckbWF0Y2gwAgNJbnQEAWEFByRtYXRjaDAFAWEFEUVWRU5UX1NUQVRVU19JTklUARBfc2F2ZUV2ZW50U3RhdHVzAwxleGVjQ2hhaW5JZF8IZXZlbnRJZF8Hc3RhdHVzXwkAzAgCCQEMSW50ZWdlckVudHJ5AgkAuQkCCQDMCAIFEEtFWV9FVkVOVF9TVEFUVVMJAMwIAgkApAMBBQxleGVjQ2hhaW5JZF8JAMwIAgkApAMBBQhldmVudElkXwUDbmlsBQlTRVBBUkFUT1IFB3N0YXR1c18FA25pbAEJX2xvYWRMb2NrAQpwdWJsaWNLZXlfBAckbWF0Y2gwCQCfCAEJALkJAgkAzAgCBQlLRVlfTE9DS1MJAMwIAgUKcHVibGljS2V5XwUDbmlsBQlTRVBBUkFUT1IDCQABAgUHJG1hdGNoMAIDSW50BAFhBQckbWF0Y2gwBQFhAAABCV9zYXZlTG9jawIKcHVibGljS2V5XwR2YWxfCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQC5CQIJAMwIAgUJS0VZX0xPQ0tTCQDMCAIFCnB1YmxpY0tleV8FA25pbAUJU0VQQVJBVE9SBQR2YWxfBQNuaWwBBl9sb2FkVAIMZXhlY0NoYWluSWRfBmVwb2NoXwQHJG1hdGNoMAkAnwgBCQC5CQIJAMwIAgUFS0VZX1QJAMwIAgkApAMBBQxleGVjQ2hhaW5JZF8JAMwIAgkApAMBBQZlcG9jaF8FA25pbAUJU0VQQVJBVE9SAwkAAQIFByRtYXRjaDACA0ludAQBYQUHJG1hdGNoMAUBYQAAAQZfc2F2ZVQDDGV4ZWNDaGFpbklkXwZlcG9jaF8EdmFsXwkAzAgCCQEMSW50ZWdlckVudHJ5AgkAuQkCCQDMCAIFBUtFWV9UCQDMCAIJAKQDAQUMZXhlY0NoYWluSWRfCQDMCAIJAKQDAQUGZXBvY2hfBQNuaWwFCVNFUEFSQVRPUgUEdmFsXwUDbmlsARlfbG9hZFNpZ25lckdyb3VwUHVibGljS2V5AgxleGVjQ2hhaW5JZF8GZXBvY2hfBAckbWF0Y2gwCQCiCAEJALkJAgkAzAgCBRtLRVlfU0lHTkVSX0dST1VQX1BVQkxJQ19LRVkJAMwIAgkApAMBBQxleGVjQ2hhaW5JZF8JAMwIAgkApAMBBQZlcG9jaF8FA25pbAUJU0VQQVJBVE9SAwkAAQIFByRtYXRjaDACBlN0cmluZwQBYQUHJG1hdGNoMAkA2QQBBQFhAQABGV9zYXZlU2lnbmVyR3JvdXBQdWJsaWNLZXkDDGV4ZWNDaGFpbklkXwZlcG9jaF8Vc2lnbmVyR3JvdXBQdWJsaWNLZXlfCQDMCAIJAQtTdHJpbmdFbnRyeQIJALkJAgkAzAgCBRtLRVlfU0lHTkVSX0dST1VQX1BVQkxJQ19LRVkJAMwIAgkApAMBBQxleGVjQ2hhaW5JZF8JAMwIAgkApAMBBQZlcG9jaF8FA25pbAUJU0VQQVJBVE9SCQDYBAEFFXNpZ25lckdyb3VwUHVibGljS2V5XwUDbmlsAQ5fbG9hZFJzQnlFdmVudAIMZXhlY0NoYWluSWRfCGV2ZW50SWRfBAckbWF0Y2gwCQCiCAEJALkJAgkAzAgCBQVLRVlfUgkAzAgCCQCkAwEFDGV4ZWNDaGFpbklkXwkAzAgCCQCkAwEFCGV2ZW50SWRfBQNuaWwFCVNFUEFSQVRPUgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWEFByRtYXRjaDADCQBmAgkAsQIBBQFhAAAJALUJAgUBYQUJU0VQQVJBVE9SBQNuaWwFA25pbAEOX3NhdmVSc0J5RXZlbnQDDGV4ZWNDaGFpbklkXwhldmVudElkXwNyc18JAMwIAgkBC1N0cmluZ0VudHJ5AgkAuQkCCQDMCAIFBUtFWV9SCQDMCAIJAKQDAQUMZXhlY0NoYWluSWRfCQDMCAIJAKQDAQUIZXZlbnRJZF8FA25pbAUJU0VQQVJBVE9SCQC5CQIFA3JzXwUJU0VQQVJBVE9SBQNuaWwBDl9sb2FkU3NCeUV2ZW50AgxleGVjQ2hhaW5JZF8IZXZlbnRJZF8EByRtYXRjaDAJAKIIAQkAuQkCCQDMCAIFBUtFWV9TCQDMCAIJAKQDAQUMZXhlY0NoYWluSWRfCQDMCAIJAKQDAQUIZXZlbnRJZF8FA25pbAUJU0VQQVJBVE9SAwkAAQIFByRtYXRjaDACBlN0cmluZwQBYQUHJG1hdGNoMAMJAGYCCQCxAgEFAWEAAAkAtQkCBQFhBQlTRVBBUkFUT1IFA25pbAUDbmlsAQ5fc2F2ZVNzQnlFdmVudAMMZXhlY0NoYWluSWRfCGV2ZW50SWRfA3NzXwkAzAgCCQELU3RyaW5nRW50cnkCCQC5CQIJAMwIAgUFS0VZX1MJAMwIAgkApAMBBQxleGVjQ2hhaW5JZF8JAMwIAgkApAMBBQhldmVudElkXwUDbmlsBQlTRVBBUkFUT1IJALkJAgUDc3NfBQlTRVBBUkFUT1IFA25pbAESX2xvYWRSU2lnbWFCeUV2ZW50AgxleGVjQ2hhaW5JZF8IZXZlbnRJZF8EByRtYXRjaDAJAKIIAQkAuQkCCQDMCAIFC0tFWV9SX1NJR01BCQDMCAIJAKQDAQUMZXhlY0NoYWluSWRfCQDMCAIJAKQDAQUIZXZlbnRJZF8FA25pbAUJU0VQQVJBVE9SAwkAAQIFByRtYXRjaDACBlN0cmluZwQBYQUHJG1hdGNoMAUBYQIAARJfc2F2ZVJTaWdtYUJ5RXZlbnQDDGV4ZWNDaGFpbklkXwhldmVudElkXwdyU2lnbWFfCQDMCAIJAQtTdHJpbmdFbnRyeQIJALkJAgkAzAgCBQtLRVlfUl9TSUdNQQkAzAgCCQCkAwEFDGV4ZWNDaGFpbklkXwkAzAgCCQCkAwEFCGV2ZW50SWRfBQNuaWwFCVNFUEFSQVRPUgUHclNpZ21hXwUDbmlsARJfbG9hZFNTaWdtYUJ5RXZlbnQCDGV4ZWNDaGFpbklkXwhldmVudElkXwQHJG1hdGNoMAkAoggBCQC5CQIJAMwIAgULS0VZX1NfU0lHTUEJAMwIAgkApAMBBQxleGVjQ2hhaW5JZF8JAMwIAgkApAMBBQhldmVudElkXwUDbmlsBQlTRVBBUkFUT1IDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwBQFhAgABEl9zYXZlU1NpZ21hQnlFdmVudAMMZXhlY0NoYWluSWRfCGV2ZW50SWRfB3NTaWdtYV8JAMwIAgkBC1N0cmluZ0VudHJ5AgkAuQkCCQDMCAIFC0tFWV9TX1NJR01BCQDMCAIJAKQDAQUMZXhlY0NoYWluSWRfCQDMCAIJAKQDAQUIZXZlbnRJZF8FA25pbAUJU0VQQVJBVE9SBQdzU2lnbWFfBQNuaWwBFl9sb2FkUkJ5RXZlbnRBbmRTaWduZXIDDGV4ZWNDaGFpbklkXwhldmVudElkXwdzaWduZXJfBAckbWF0Y2gwCQCiCAEJALkJAgkAzAgCBQVLRVlfUgkAzAgCCQCkAwEFDGV4ZWNDaGFpbklkXwkAzAgCCQCkAwEFCGV2ZW50SWRfCQDMCAIFB3NpZ25lcl8FA25pbAUJU0VQQVJBVE9SAwkAAQIFByRtYXRjaDACBlN0cmluZwQBYQUHJG1hdGNoMAUBYQIAARZfc2F2ZVJCeUV2ZW50QW5kU2lnbmVyBAxleGVjQ2hhaW5JZF8IZXZlbnRJZF8Hc2lnbmVyXwJyXwkAzAgCCQELU3RyaW5nRW50cnkCCQC5CQIJAMwIAgUFS0VZX1IJAMwIAgkApAMBBQxleGVjQ2hhaW5JZF8JAMwIAgkApAMBBQhldmVudElkXwkAzAgCBQdzaWduZXJfBQNuaWwFCVNFUEFSQVRPUgUCcl8FA25pbAEWX2xvYWRTQnlFdmVudEFuZFNpZ25lcgMMZXhlY0NoYWluSWRfCGV2ZW50SWRfB3NpZ25lcl8EByRtYXRjaDAJAKIIAQkAuQkCCQDMCAIFBUtFWV9TCQDMCAIJAKQDAQUMZXhlY0NoYWluSWRfCQDMCAIJAKQDAQUIZXZlbnRJZF8JAMwIAgUHc2lnbmVyXwUDbmlsBQlTRVBBUkFUT1IDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwBQFhAgABFl9zYXZlU0J5RXZlbnRBbmRTaWduZXIEDGV4ZWNDaGFpbklkXwhldmVudElkXwdzaWduZXJfAnNfCQDMCAIJAQtTdHJpbmdFbnRyeQIJALkJAgkAzAgCBQVLRVlfUwkAzAgCCQCkAwEFDGV4ZWNDaGFpbklkXwkAzAgCCQCkAwEFCGV2ZW50SWRfCQDMCAIFB3NpZ25lcl8FA25pbAUJU0VQQVJBVE9SBQJzXwUDbmlsARhfbG9hZFNpZ25lcnNXaXRoUkJ5RXZlbnQCDGV4ZWNDaGFpbklkXwhldmVudElkXwQHJG1hdGNoMAkAoggBCQC5CQIJAMwIAgUNS0VZX1JfU0lHTkVSUwkAzAgCCQCkAwEFDGV4ZWNDaGFpbklkXwkAzAgCCQCkAwEFCGV2ZW50SWRfBQNuaWwFCVNFUEFSQVRPUgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWEFByRtYXRjaDADCQBmAgkAsQIBBQFhAAAJALUJAgUBYQUJU0VQQVJBVE9SBQNuaWwFA25pbAEYX3NhdmVTaWduZXJzV2l0aFJCeUV2ZW50AwxleGVjQ2hhaW5JZF8IZXZlbnRJZF8DcnNfCQDMCAIJAQtTdHJpbmdFbnRyeQIJALkJAgkAzAgCBQ1LRVlfUl9TSUdORVJTCQDMCAIJAKQDAQUMZXhlY0NoYWluSWRfCQDMCAIJAKQDAQUIZXZlbnRJZF8FA25pbAUJU0VQQVJBVE9SCQC5CQIFA3JzXwUJU0VQQVJBVE9SBQNuaWwBGF9sb2FkU2lnbmVyc1dpdGhTQnlFdmVudAIMZXhlY0NoYWluSWRfCGV2ZW50SWRfBAckbWF0Y2gwCQCiCAEJALkJAgkAzAgCBQ1LRVlfU19TSUdORVJTCQDMCAIJAKQDAQUMZXhlY0NoYWluSWRfCQDMCAIJAKQDAQUIZXZlbnRJZF8FA25pbAUJU0VQQVJBVE9SAwkAAQIFByRtYXRjaDACBlN0cmluZwQBYQUHJG1hdGNoMAMJAGYCCQCxAgEFAWEAAAkAtQkCBQFhBQlTRVBBUkFUT1IFA25pbAUDbmlsARhfc2F2ZVNpZ25lcnNXaXRoU0J5RXZlbnQDDGV4ZWNDaGFpbklkXwhldmVudElkXwNzc18JAMwIAgkBC1N0cmluZ0VudHJ5AgkAuQkCCQDMCAIFDUtFWV9TX1NJR05FUlMJAMwIAgkApAMBBQxleGVjQ2hhaW5JZF8JAMwIAgkApAMBBQhldmVudElkXwUDbmlsBQlTRVBBUkFUT1IJALkJAgUDc3NfBQlTRVBBUkFUT1IFA25pbAEUX2xvYWRFdmVudFN0YXJ0QmxvY2sCDGV4ZWNDaGFpbklkXwhldmVudElkXwQHJG1hdGNoMAkAnwgBCQC5CQIJAMwIAgUVS0VZX0VWRU5UX1NUQVJUX0JMT0NLCQDMCAIJAKQDAQUMZXhlY0NoYWluSWRfCQDMCAIJAKQDAQUIZXZlbnRJZF8FA25pbAUJU0VQQVJBVE9SAwkAAQIFByRtYXRjaDACA0ludAQBYQUHJG1hdGNoMAUBYQAAARRfc2F2ZUV2ZW50U3RhcnRCbG9jawMMZXhlY0NoYWluSWRfCGV2ZW50SWRfBHZhbF8JAMwIAgkBDEludGVnZXJFbnRyeQIJALkJAgkAzAgCBRVLRVlfRVZFTlRfU1RBUlRfQkxPQ0sJAMwIAgkApAMBBQxleGVjQ2hhaW5JZF8JAMwIAgkApAMBBQhldmVudElkXwUDbmlsBQlTRVBBUkFUT1IFBHZhbF8FA25pbAEfX2xvYWRTaWduZWRFdmVudEV4ZWN1dG9ySWR4U2l6ZQERZXhlY3V0aW9uQ2hhaW5JZF8EByRtYXRjaDAJAJ8IAQkAuQkCCQDMCAIFGUtFWV9TSUdORURfRVZFTlRfRVhFQ1VUT1IJAMwIAgkApAMBBRFleGVjdXRpb25DaGFpbklkXwkAzAgCBQhLRVlfU0laRQUDbmlsBQlTRVBBUkFUT1IDCQABAgUHJG1hdGNoMAIDSW50BAFhBQckbWF0Y2gwBQFhAAABH19zYXZlU2lnbmVkRXZlbnRFeGVjdXRvcklkeFNpemUCEWV4ZWN1dGlvbkNoYWluSWRfBHZhbF8JAMwIAgkBDEludGVnZXJFbnRyeQIJALkJAgkAzAgCBRlLRVlfU0lHTkVEX0VWRU5UX0VYRUNVVE9SCQDMCAIJAKQDAQURZXhlY3V0aW9uQ2hhaW5JZF8JAMwIAgUIS0VZX1NJWkUFA25pbAUJU0VQQVJBVE9SBQR2YWxfBQNuaWwBG19sb2FkU2lnbmVkRXZlbnRFeGVjdXRvcklkeAIRZXhlY3V0aW9uQ2hhaW5JZF8EaWR4XwQHJG1hdGNoMAkAnwgBCQC5CQIJAMwIAgUZS0VZX1NJR05FRF9FVkVOVF9FWEVDVVRPUgkAzAgCCQCkAwEFEWV4ZWN1dGlvbkNoYWluSWRfCQDMCAIJAKQDAQUEaWR4XwUDbmlsBQlTRVBBUkFUT1IDCQABAgUHJG1hdGNoMAIDSW50BAFhBQckbWF0Y2gwBQFhAAABG19zYXZlU2lnbmVkRXZlbnRFeGVjdXRvcklkeAMRZXhlY3V0aW9uQ2hhaW5JZF8EaWR4XwR2YWxfCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQC5CQIJAMwIAgUZS0VZX1NJR05FRF9FVkVOVF9FWEVDVVRPUgkAzAgCCQCkAwEFEWV4ZWN1dGlvbkNoYWluSWRfCQDMCAIJAKQDAQUEaWR4XwUDbmlsBQlTRVBBUkFUT1IFBHZhbF8FA25pbAERX29ubHlUaGlzQ29udHJhY3QBB2NhbGxlcl8DCQECIT0CBQdjYWxsZXJfBQR0aGlzCQACAQIZX29ubHlUaGlzQ29udHJhY3Q6IHJldmVydAYBEF93aGVuTXVsdGlzaWdTZXQAAwkAAAIJAQ1fbG9hZE11bHRpc2lnAAkBB0FkZHJlc3MBAQAJAAIBAhhfd2hlbk11bHRpc2lnU2V0OiByZXZlcnQGARNfd2hlbk5vdEluaXRpYWxpemVkAAMJAQlfbG9hZEluaXQACQACAQIbX3doZW5Ob3RJbml0aWFsaXplZDogcmV2ZXJ0BgEQX3doZW5Jbml0aWFsaXplZAADCQEBIQEJAQlfbG9hZEluaXQACQACAQIYX3doZW5Jbml0aWFsaXplZDogcmV2ZXJ0BgERX2lzQ29uZmlybWVkRXZlbnQDCGV2ZW50SWRfDGV4ZWNDaGFpbklkXwRlcnJfBAZyZXN1bHQJAPwHBAkBE19sb2FkV2l0bmVzc0FkZHJlc3MABRdGVU5DX0lTX0NPTkZJUk1FRF9FVkVOVAkAzAgCBQhldmVudElkXwkAzAgCBQxleGVjQ2hhaW5JZF8FA25pbAUDbmlsAwkAAAIFBnJlc3VsdAUGcmVzdWx0BAckbWF0Y2gwBQZyZXN1bHQDCQABAgUHJG1hdGNoMAIHQm9vbGVhbgQBYQUHJG1hdGNoMAMJAQEhAQUBYQkAAgEFBGVycl8GCQACAQUEZXJyXwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEMX2dldFJhd0V2ZW50AghldmVudElkXwxleGVjQ2hhaW5JZF8EBnJlc3VsdAkA/AcECQETX2xvYWRXaXRuZXNzQWRkcmVzcwAFEkZVTkNfR0VUX1JBV19FVkVOVAkAzAgCBQhldmVudElkXwkAzAgCBQxleGVjQ2hhaW5JZF8FA25pbAUDbmlsAwkAAAIFBnJlc3VsdAUGcmVzdWx0BAckbWF0Y2gwBQZyZXN1bHQDCQABAgUHJG1hdGNoMAIUKFN0cmluZywgQnl0ZVZlY3RvcikEAWEFByRtYXRjaDAFAWEJAAIBAhRfZ2V0UmF3RXZlbnQ6IHJldmVydAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEPX2lzQWN0aXZlU2lnbmVyAwpwdWJsaWNLZXlfC3B1YmxpY0tleXNfBGVycl8DCQEBIQEJAQ9jb250YWluc0VsZW1lbnQCBQtwdWJsaWNLZXlzXwUKcHVibGljS2V5XwkAAgEFBGVycl8GAQ1fY2hlY2tTZWNEZXBvAgdzaWduZXJfBGVycl8DCQBmAgkBD19sb2FkTWluU2VjRGVwbwAJAQxfbG9hZFNlY0RlcG8BCQCnCAEJANkEAQUHc2lnbmVyXwkAAgEFBGVycl8GARtfY2hlY2tFdmVudFN0YXR1c0ZvclN1Ym1pdFIDDGV4ZWNDaGFpbklkXwhldmVudElkXwRlcnJfAwkBAiE9AgkBEF9sb2FkRXZlbnRTdGF0dXMCBQxleGVjQ2hhaW5JZF8FCGV2ZW50SWRfBRFFVkVOVF9TVEFUVVNfSU5JVAkAAgEFBGVycl8GARtfY2hlY2tFdmVudFN0YXR1c0ZvclN1Ym1pdFMDDGV4ZWNDaGFpbklkXwhldmVudElkXwRlcnJfAwkBAiE9AgkBEF9sb2FkRXZlbnRTdGF0dXMCBQxleGVjQ2hhaW5JZF8FCGV2ZW50SWRfBRFFVkVOVF9TVEFUVVNfU0lHTgkAAgEFBGVycl8GARlfY2hlY2tFdmVudFN0YXR1c0ZvclJlc2V0AwxleGVjQ2hhaW5JZF8IZXZlbnRJZF8EZXJyXwMDCQECIT0CCQEQX2xvYWRFdmVudFN0YXR1cwIFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8FEUVWRU5UX1NUQVRVU19TSUdOBgkAZgIJAGQCCQEUX2xvYWRFdmVudFN0YXJ0QmxvY2sCBQxleGVjQ2hhaW5JZF8FCGV2ZW50SWRfCQEUX2xvYWRSZXNldEJsb2NrRGVsdGEABQZoZWlnaHQJAAIBBQRlcnJfBgEPX2luY3JlbWVudExvY2tzAQhzaWduZXJzXwoBCGZvbGRGdW5jAgNhY2MEZWxlbQkAzggCBQNhY2MJAQlfc2F2ZUxvY2sCBQRlbGVtCQBkAgkBCV9sb2FkTG9jawEFBGVsZW0AAQoAAiRsBQhzaWduZXJzXwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZm9sZEZ1bmMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoBC19pc1plcm9Mb2NrAgpwdWJsaWNLZXlfBGVycl8DCQBmAgkBCV9sb2FkTG9jawEFCnB1YmxpY0tleV8AAAkAAgEFBGVycl8GAQ5fbm90U3VibWl0dGVkUgQMZXhlY0NoYWluSWRfCGV2ZW50SWRfB3NpZ25lcl8EZXJyXwQBcgkBFl9sb2FkUkJ5RXZlbnRBbmRTaWduZXIDBQxleGVjQ2hhaW5JZF8FCGV2ZW50SWRfBQdzaWduZXJfAwMJAQIhPQIFAXICAAkBD2NvbnRhaW5zRWxlbWVudAIJAQ5fbG9hZFJzQnlFdmVudAIFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8FAXIHCQACAQUEZXJyXwYBDl9ub3RTdWJtaXR0ZWRTBAxleGVjQ2hhaW5JZF8IZXZlbnRJZF8Hc2lnbmVyXwRlcnJfBAFzCQEWX2xvYWRTQnlFdmVudEFuZFNpZ25lcgMFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8FB3NpZ25lcl8DAwkBAiE9AgUBcwIACQEPY29udGFpbnNFbGVtZW50AgkBDl9sb2FkU3NCeUV2ZW50AgUMZXhlY0NoYWluSWRfBQhldmVudElkXwUBcwcJAAIBBQRlcnJfBgELX3N1Ym1pdHRlZFIEDGV4ZWNDaGFpbklkXwhldmVudElkXwdzaWduZXJfBGVycl8EAXIJARZfbG9hZFJCeUV2ZW50QW5kU2lnbmVyAwUMZXhlY0NoYWluSWRfBQhldmVudElkXwUHc2lnbmVyXwMDCQAAAgUBcgIABgkBASEBCQEPY29udGFpbnNFbGVtZW50AgkBDl9sb2FkUnNCeUV2ZW50AgUMZXhlY0NoYWluSWRfBQhldmVudElkXwUBcgkAAgEFBGVycl8GAQ9fc2xhc2hJbmNvcnJlY3QCDXNpZ25lcnNXaXRoUl8Nc2lnbmVyc1dpdGhTXwQKcHVuaXNobWVudAkBD19sb2FkUHVuaXNobWVudAAKAQhmb2xkRnVuYwIDYWNjBGVsZW0DCQEPY29udGFpbnNFbGVtZW50AgUNc2lnbmVyc1dpdGhTXwUEZWxlbQkAlQoDCAUDYWNjAl8xCQDNCAIIBQNhY2MCXzIFBGVsZW0IBQNhY2MCXzMEDXNpZ25lckFkZHJlc3MJAKcIAQkA2QQBBQRlbGVtCQCVCgMJAM4IAggFA2FjYwJfMQkBDF9zYXZlU2VjRGVwbwIFDXNpZ25lckFkZHJlc3MJAGUCCQEMX2xvYWRTZWNEZXBvAQUNc2lnbmVyQWRkcmVzcwUKcHVuaXNobWVudAgFA2FjYwJfMgkAZAIIBQNhY2MCXzMFCnB1bmlzaG1lbnQKAAIkbAUNc2lnbmVyc1dpdGhSXwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJUKAwUDbmlsBQNuaWwAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZm9sZEZ1bmMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoBEl9jb21wZW5zYXRlQ29ycmVjdAIIc2lnbmVyc18NY29tcGVuc2F0aW9uXwQJcGVyU2lnbmVyCQBpAgUNY29tcGVuc2F0aW9uXwkAkAMBBQhzaWduZXJzXwoBCGZvbGRGdW5jAgNhY2MEZWxlbQkAzQgCBQNhY2MJAQ5TY3JpcHRUcmFuc2ZlcgMJAKcIAQkA2QQBBQRlbGVtBQlwZXJTaWduZXIFBHVuaXQKAAIkbAUIc2lnbmVyc18KAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGZvbGRGdW5jAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARBfdmVyaWZ5U2lnbmF0dXJlBgxleGVjQ2hhaW5JZF8GZXBvY2hfCGV2ZW50SWRfB3JTaWdtYV8Hc1NpZ21hXwRlcnJfBAVldmVudAkBDF9nZXRSYXdFdmVudAIFCGV2ZW50SWRfBQxleGVjQ2hhaW5JZF8ECWV2ZW50VHlwZQgFBWV2ZW50Al8xBApldmVudEJ5dGVzCAUFZXZlbnQCXzIEDmdyb3VwUHVibGljS2V5CQEZX2xvYWRTaWduZXJHcm91cFB1YmxpY0tleQIFDGV4ZWNDaGFpbklkXwUGZXBvY2hfAwkAAAIFCWV2ZW50VHlwZQUQRVZFTlRfVFlQRV9XQVZFUwQJc2lnbmF0dXJlCQDLAQIJANkEAQUHclNpZ21hXwkA2QQBBQdzU2lnbWFfAwkBASEBCQD0AwMFCmV2ZW50Qnl0ZXMFCXNpZ25hdHVyZQUOZ3JvdXBQdWJsaWNLZXkJAAIBBQRlcnJfBgMJAAACBQlldmVudFR5cGUFDkVWRU5UX1RZUEVfRVZNBgkAAgEFBGVycl8BFV9wdWJsaWNLZXlzVG9BZGRyc1N0cgELcHVibGljS2V5c18KAQhmb2xkZnVuYwIEYWNjXwVlbGVtXwkAzQgCBQRhY2NfCQClCAEJAKcIAQkA2QQBBQVlbGVtXwoAAiRsBQtwdWJsaWNLZXlzXwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZm9sZGZ1bmMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDUxCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgAzCAFpAQRpbml0BgttaW5TZWNEZXBvXwtwdW5pc2htZW50XxByZXNldEJsb2NrRGVsdGFfE3Jld2FyZFRva2VuQWRkcmVzc18NcmV3YXJkQW1vdW50Xw93aXRuZXNzQWRkcmVzc18EA2VycgMDAwMDAwMDCQERX29ubHlUaGlzQ29udHJhY3QBCAUBaQZjYWxsZXIJARNfd2hlbk5vdEluaXRpYWxpemVkAAcJARBfd2hlbk11bHRpc2lnU2V0AAcJAQxfdmFsaWRhdGVJbnQEBQttaW5TZWNEZXBvXwULcHVuaXNobWVudF8FB01BWF9JTlQCGGluaXQ6IGludmFsaWQgbWluU2VjRGVwbwcJAQxfdmFsaWRhdGVJbnQEBQtwdW5pc2htZW50XwAABQdNQVhfSU5UAhhpbml0OiBpbnZhbGlkIHB1bmlzaG1lbnQHCQEMX3ZhbGlkYXRlSW50BAUQcmVzZXRCbG9ja0RlbHRhXwAABQdNQVhfSU5UAh1pbml0OiBpbnZhbGlkIHJlc2V0QmxvY2tEZWx0YQcJARBfdmFsaWRhdGVBZGRyZXNzAgUTcmV3YXJkVG9rZW5BZGRyZXNzXwIgaW5pdDogaW52YWxpZCByZXdhcmRUb2tlbkFkZHJlc3MHCQEMX3ZhbGlkYXRlSW50BAUNcmV3YXJkQW1vdW50XwAABQdNQVhfSU5UAhppbml0OiBpbnZhbGlkIHJld2FyZEFtb3VudAcJARBfdmFsaWRhdGVBZGRyZXNzAgUPd2l0bmVzc0FkZHJlc3NfAhxpbml0OiBpbnZhbGlkIHdpdG5lc3NBZGRyZXNzBwMJAAACBQNlcnIFA2VycgkAlAoCCQDOCAIJAM4IAgkAzggCCQDOCAIJAM4IAgkAzggCCQEJX3NhdmVJbml0AQYJAQ9fc2F2ZU1pblNlY0RlcG8BBQttaW5TZWNEZXBvXwkBD19zYXZlUHVuaXNobWVudAEFC3B1bmlzaG1lbnRfCQEUX3NhdmVSZXNldEJsb2NrRGVsdGEBBRByZXNldEJsb2NrRGVsdGFfCQEXX3NhdmVSZXdhcmRUb2tlbkFkZHJlc3MBCQERQGV4dHJOYXRpdmUoMTA2MikBBRNyZXdhcmRUb2tlbkFkZHJlc3NfCQERX3NhdmVSZXdhcmRBbW91bnQBBQ1yZXdhcmRBbW91bnRfCQETX3NhdmVXaXRuZXNzQWRkcmVzcwEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFD3dpdG5lc3NBZGRyZXNzXwUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARBzZXRBY3RpdmVTaWduZXJzBAxleGVjQ2hhaW5JZF8Ic2lnbmVyc18CdF8Vc2lnbmVyR3JvdXBQdWJsaWNLZXlfBANlcnIDAwMDCQERX29ubHlUaGlzQ29udHJhY3QBCAUBaQZjYWxsZXIJARBfd2hlbkluaXRpYWxpemVkAAcJARNfdmFsaWRhdGVQdWJsaWNLZXlzAgUIc2lnbmVyc18CIXNldEFjdGl2ZVNpZ25lcnM6IGludmFsaWQgc2lnbmVycwcJAQxfdmFsaWRhdGVJbnQEBQJ0XwACCQCQAwEFCHNpZ25lcnNfAhtzZXRBY3RpdmVTaWduZXJzOiBpbnZhbGlkIFQHCQEPX3ZhbGlkYXRlU3RyaW5nAgUVc2lnbmVyR3JvdXBQdWJsaWNLZXlfAi5zZXRBY3RpdmVTaWduZXJzOiBpbnZhbGlkIHNpZ25lckdyb3VwUHVibGljS2V5BwMJAAACBQNlcnIFA2VycgQFZXBvY2gJARFfbG9hZEN1cnJlbnRFcG9jaAEFDGV4ZWNDaGFpbklkXwkAlAoCCQDOCAIJAM4IAgkAzggCCQDOCAIJARFfc2F2ZUN1cnJlbnRFcG9jaAIFDGV4ZWNDaGFpbklkXwkAZAIFBWVwb2NoAAEJAQZfc2F2ZVQDBQxleGVjQ2hhaW5JZF8JAGQCBQVlcG9jaAABBQJ0XwkBDF9zYXZlU2lnbmVycwMFDGV4ZWNDaGFpbklkXwkAZAIFBWVwb2NoAAEFCHNpZ25lcnNfCQEZX3NhdmVTaWduZXJHcm91cFB1YmxpY0tleQMFDGV4ZWNDaGFpbklkXwkAZAIFBWVwb2NoAAEJANkEAQUVc2lnbmVyR3JvdXBQdWJsaWNLZXlfCQEPX2luY3JlbWVudExvY2tzAQUIc2lnbmVyc18FBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEHc3VibWl0UgMIZXZlbnRJZF8MZXhlY0NoYWluSWRfAnJfBA9jYWxsZXJQdWJsaWNLZXkJANgEAQgFAWkPY2FsbGVyUHVibGljS2V5BAVlcG9jaAkBEV9sb2FkQ3VycmVudEVwb2NoAQUMZXhlY0NoYWluSWRfBAF0CQEGX2xvYWRUAgUMZXhlY0NoYWluSWRfBQVlcG9jaAQDZXJyAwMDAwMDAwMJARBfd2hlbkluaXRpYWxpemVkAAkBDF92YWxpZGF0ZUludAQFCGV2ZW50SWRfAAAFB01BWF9JTlQCGHN1Ym1pdFI6IGludmFsaWQgZXZlbnRJZAcJAQxfdmFsaWRhdGVJbnQEBQxleGVjQ2hhaW5JZF8AAAUHTUFYX0lOVAIcc3VibWl0UjogaW52YWxpZCBleGVjQ2hhaW5JZAcJAQ9fdmFsaWRhdGVTdHJpbmcCBQJyXwISc3VibWl0UjogaW52YWxpZCByBwkBEV9pc0NvbmZpcm1lZEV2ZW50AwUIZXZlbnRJZF8FDGV4ZWNDaGFpbklkXwIcc3VibWl0UjogZXZlbnQgbm90IGNvbmZpcm1lZAcJAQ9faXNBY3RpdmVTaWduZXIDBQ9jYWxsZXJQdWJsaWNLZXkJAQxfbG9hZFNpZ25lcnMCBQxleGVjQ2hhaW5JZF8FBWVwb2NoAhNzdWJtaXRSOiBub3QgYWN0aXZlBwkBDV9jaGVja1NlY0RlcG8CBQ9jYWxsZXJQdWJsaWNLZXkCJHN1Ym1pdFI6IG5vdCBlbm91Z2ggc2VjdXJpdHkgZGVwb3NpdAcJARtfY2hlY2tFdmVudFN0YXR1c0ZvclN1Ym1pdFIDBQxleGVjQ2hhaW5JZF8FCGV2ZW50SWRfAh1zdWJtaXRSOiBpbnZhbGlkIGV2ZW50IHN0YXR1cwcJAQ5fbm90U3VibWl0dGVkUgQFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8FD2NhbGxlclB1YmxpY0tleQIac3VibWl0UjogYWxyZWFkeSBzdWJtaXR0ZWQHAwkAAAIFA2VycgUDZXJyBAZyQXJyYXkJAQ5fbG9hZFJzQnlFdmVudAIFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8EDHNpZ25lcnNBcnJheQkBGF9sb2FkU2lnbmVyc1dpdGhSQnlFdmVudAIFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8EEmV2ZW50U3RhdHVzQWN0aW9ucwMJAAACCQBkAgkAkAMBBQZyQXJyYXkAAQUBdAkAzggCCQEQX3NhdmVFdmVudFN0YXR1cwMFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8FEUVWRU5UX1NUQVRVU19TSUdOCQEUX3NhdmVFdmVudFN0YXJ0QmxvY2sDBQxleGVjQ2hhaW5JZF8FCGV2ZW50SWRfBQZoZWlnaHQFA25pbAkAlAoCCQDOCAIJAM4IAgkAzggCCQEOX3NhdmVSc0J5RXZlbnQDBQxleGVjQ2hhaW5JZF8FCGV2ZW50SWRfCQDNCAIFBnJBcnJheQUCcl8JARZfc2F2ZVJCeUV2ZW50QW5kU2lnbmVyBAUMZXhlY0NoYWluSWRfBQhldmVudElkXwUPY2FsbGVyUHVibGljS2V5BQJyXwkBGF9zYXZlU2lnbmVyc1dpdGhSQnlFdmVudAMFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8JAM0IAgUMc2lnbmVyc0FycmF5BQ9jYWxsZXJQdWJsaWNLZXkFEmV2ZW50U3RhdHVzQWN0aW9ucwUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQdzdWJtaXRTBQhldmVudElkXwxleGVjQ2hhaW5JZF8HclNpZ21hXwJzXwdzU2lnbWFfBA9jYWxsZXJQdWJsaWNLZXkJANgEAQgFAWkPY2FsbGVyUHVibGljS2V5BAVlcG9jaAkBEV9sb2FkQ3VycmVudEVwb2NoAQUMZXhlY0NoYWluSWRfBAF0CQEGX2xvYWRUAgUMZXhlY0NoYWluSWRfBQVlcG9jaAQDZXJyAwMDAwMDAwMDCQEQX3doZW5Jbml0aWFsaXplZAAJAQxfdmFsaWRhdGVJbnQEBQhldmVudElkXwAABQdNQVhfSU5UAhhzdWJtaXRTOiBpbnZhbGlkIGV2ZW50SWQHCQEMX3ZhbGlkYXRlSW50BAUMZXhlY0NoYWluSWRfAAAFB01BWF9JTlQCHHN1Ym1pdFM6IGludmFsaWQgZXhlY0NoYWluSWQHCQEPX3ZhbGlkYXRlU3RyaW5nAgUHclNpZ21hXwIYc3VibWl0UzogaW52YWxpZCByIHNpZ21hBwkBD192YWxpZGF0ZVN0cmluZwIFAnNfAhJzdWJtaXRTOiBpbnZhbGlkIHMHCQEPX2lzQWN0aXZlU2lnbmVyAwUPY2FsbGVyUHVibGljS2V5CQEMX2xvYWRTaWduZXJzAgUMZXhlY0NoYWluSWRfBQVlcG9jaAITc3VibWl0Uzogbm90IGFjdGl2ZQcJAQ1fY2hlY2tTZWNEZXBvAgUPY2FsbGVyUHVibGljS2V5AiRzdWJtaXRTOiBub3QgZW5vdWdoIHNlY3VyaXR5IGRlcG9zaXQHCQEbX2NoZWNrRXZlbnRTdGF0dXNGb3JTdWJtaXRTAwUMZXhlY0NoYWluSWRfBQhldmVudElkXwIdc3VibWl0UzogaW52YWxpZCBldmVudCBzdGF0dXMHCQEOX25vdFN1Ym1pdHRlZFMEBQxleGVjQ2hhaW5JZF8FCGV2ZW50SWRfBQ9jYWxsZXJQdWJsaWNLZXkCGnN1Ym1pdFM6IGFscmVhZHkgc3VibWl0dGVkBwkBC19zdWJtaXR0ZWRSBAUMZXhlY0NoYWluSWRfBQhldmVudElkXwUPY2FsbGVyUHVibGljS2V5AhtzdWJtaXRTOiBSIGlzIG5vdCBzdWJtaXR0ZWQHAwkAAAIFA2VycgUDZXJyBAZzQXJyYXkJAQ5fbG9hZFNzQnlFdmVudAIFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8EDHNpZ25lcnNBcnJheQkBGF9sb2FkU2lnbmVyc1dpdGhTQnlFdmVudAIFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8EEmV2ZW50U3RhdHVzQWN0aW9ucwMJAAACCQBkAgkAkAMBBQZzQXJyYXkAAQUBdAQEZXJyMQMJAQ9fdmFsaWRhdGVTdHJpbmcCBQdzU2lnbWFfAhhzdWJtaXRTOiBpbnZhbGlkIHMgc2lnbWEJARBfdmVyaWZ5U2lnbmF0dXJlBgUMZXhlY0NoYWluSWRfBQVlcG9jaAUIZXZlbnRJZF8FB3JTaWdtYV8FB3NTaWdtYV8CGnN1Ym1pdFM6IGludmFsaWQgc2lnbmF0dXJlBwMJAAACBQRlcnIxBQRlcnIxBA9leGVjdXRvcklkeFNpemUJAR9fbG9hZFNpZ25lZEV2ZW50RXhlY3V0b3JJZHhTaXplAQUMZXhlY0NoYWluSWRfBA9yZXdhcmRBZGRyZXNzZXMJARVfcHVibGljS2V5c1RvQWRkcnNTdHIBCQDNCAIFDHNpZ25lcnNBcnJheQUPY2FsbGVyUHVibGljS2V5BA5zaWduZXJzUmV3YXJkcwkA/AcECQEXX2xvYWRSZXdhcmRUb2tlbkFkZHJlc3MABQ5GVU5DX01JTlRfTUFOWQkAzAgCCQERX2xvYWRSZXdhcmRBbW91bnQACQDMCAIFD3Jld2FyZEFkZHJlc3NlcwUDbmlsBQNuaWwDCQAAAgUOc2lnbmVyc1Jld2FyZHMFDnNpZ25lcnNSZXdhcmRzCQDOCAIJAM4IAgkAzggCCQEQX3NhdmVFdmVudFN0YXR1cwMFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8FEUVWRU5UX1NUQVRVU19ET05FCQEbX3NhdmVTaWduZWRFdmVudEV4ZWN1dG9ySWR4AwUMZXhlY0NoYWluSWRfBQ9leGVjdXRvcklkeFNpemUFCGV2ZW50SWRfCQEfX3NhdmVTaWduZWRFdmVudEV4ZWN1dG9ySWR4U2l6ZQIFDGV4ZWNDaGFpbklkXwkAZAIFD2V4ZWN1dG9ySWR4U2l6ZQABCQESX3NhdmVTU2lnbWFCeUV2ZW50AwUMZXhlY0NoYWluSWRfBQhldmVudElkXwUHc1NpZ21hXwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsCQCUCgIJAM4IAgkAzggCCQDOCAIJAM4IAgkBDl9zYXZlU3NCeUV2ZW50AwUMZXhlY0NoYWluSWRfBQhldmVudElkXwkAzQgCBQZzQXJyYXkFAnNfCQEWX3NhdmVTQnlFdmVudEFuZFNpZ25lcgQFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8FD2NhbGxlclB1YmxpY0tleQUCc18JARhfc2F2ZVNpZ25lcnNXaXRoU0J5RXZlbnQDBQxleGVjQ2hhaW5JZF8FCGV2ZW50SWRfCQDNCAIFDHNpZ25lcnNBcnJheQUPY2FsbGVyUHVibGljS2V5CQESX3NhdmVSU2lnbWFCeUV2ZW50AwUMZXhlY0NoYWluSWRfBQhldmVudElkXwUHclNpZ21hXwUSZXZlbnRTdGF0dXNBY3Rpb25zBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBXJlc2V0AwhldmVudElkXwxleGVjQ2hhaW5JZF8Ccl8ED2NhbGxlclB1YmxpY0tleQkA2AQBCAUBaQ9jYWxsZXJQdWJsaWNLZXkEBWVwb2NoCQERX2xvYWRDdXJyZW50RXBvY2gBBQxleGVjQ2hhaW5JZF8EA2VycgMDAwMDAwkBEF93aGVuSW5pdGlhbGl6ZWQACQEMX3ZhbGlkYXRlSW50BAUIZXZlbnRJZF8AAAUHTUFYX0lOVAIWcmVzZXQ6IGludmFsaWQgZXZlbnRJZAcJAQxfdmFsaWRhdGVJbnQEBQxleGVjQ2hhaW5JZF8AAAUHTUFYX0lOVAIacmVzZXQ6IGludmFsaWQgZXhlY0NoYWluSWQHCQEPX3ZhbGlkYXRlU3RyaW5nAgUCcl8CEHJlc2V0OiBpbnZhbGlkIHIHCQEPX2lzQWN0aXZlU2lnbmVyAwUPY2FsbGVyUHVibGljS2V5CQEMX2xvYWRTaWduZXJzAgUMZXhlY0NoYWluSWRfBQVlcG9jaAIRcmVzZXQ6IG5vdCBhY3RpdmUHCQENX2NoZWNrU2VjRGVwbwIFD2NhbGxlclB1YmxpY0tleQIicmVzZXQ6IG5vdCBlbm91Z2ggc2VjdXJpdHkgZGVwb3NpdAcJARlfY2hlY2tFdmVudFN0YXR1c0ZvclJlc2V0AwUMZXhlY0NoYWluSWRfBQhldmVudElkXwIbcmVzZXQ6IGludmFsaWQgZXZlbnQgc3RhdHVzBwMJAAACBQNlcnIFA2VycgQLc2xhc2hBbW91bnQAAAQMc2lnbmVyc1dpdGhSCQEYX2xvYWRTaWduZXJzV2l0aFJCeUV2ZW50AgUMZXhlY0NoYWluSWRfBQhldmVudElkXwQMc2lnbmVyc1dpdGhTCQEYX2xvYWRTaWduZXJzV2l0aFNCeUV2ZW50AgUMZXhlY0NoYWluSWRfBQhldmVudElkXwQGcmVzdWx0CQEPX3NsYXNoSW5jb3JyZWN0AgUMc2lnbmVyc1dpdGhSBQxzaWduZXJzV2l0aFMED3NsYXNoaW5nQWN0aW9ucwgFBnJlc3VsdAJfMQQSY29tcGVuc2F0ZWRTaWduZXJzCAUGcmVzdWx0Al8yBAxjb21wZW5zYXRpb24IBQZyZXN1bHQCXzMEE2NvbXBlbnNhdGlvbkFjdGlvbnMJARJfY29tcGVuc2F0ZUNvcnJlY3QCBRJjb21wZW5zYXRlZFNpZ25lcnMFDGNvbXBlbnNhdGlvbgkAlAoCCQDOCAIJAM4IAgkAzggCCQDOCAIJAM4IAgkAzggCCQDOCAIJAM4IAgkAzggCCQEQX3NhdmVFdmVudFN0YXR1cwMFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8FEUVWRU5UX1NUQVRVU19JTklUCQEOX3NhdmVSc0J5RXZlbnQDBQxleGVjQ2hhaW5JZF8FCGV2ZW50SWRfCQDMCAIFAnJfBQNuaWwJARZfc2F2ZVJCeUV2ZW50QW5kU2lnbmVyBAUMZXhlY0NoYWluSWRfBQhldmVudElkXwUPY2FsbGVyUHVibGljS2V5BQJyXwkBGF9zYXZlU2lnbmVyc1dpdGhSQnlFdmVudAMFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8JAMwIAgUPY2FsbGVyUHVibGljS2V5BQNuaWwJARJfc2F2ZVJTaWdtYUJ5RXZlbnQDBQxleGVjQ2hhaW5JZF8FCGV2ZW50SWRfAgAJAQ5fc2F2ZVNzQnlFdmVudAMFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8FA25pbAkBGF9zYXZlU2lnbmVyc1dpdGhTQnlFdmVudAMFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8FA25pbAkBEl9zYXZlU1NpZ21hQnlFdmVudAMFDGV4ZWNDaGFpbklkXwUIZXZlbnRJZF8CAAUPc2xhc2hpbmdBY3Rpb25zBRNjb21wZW5zYXRpb25BY3Rpb25zBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEmFkZFNlY3VyaXR5RGVwb3NpdAEKcmVjaXBpZW50XwQJcmVjaXBpZW50AwkAAAIFCnJlY2lwaWVudF8CAAkApQgBCAUBaQZjYWxsZXIFCnJlY2lwaWVudF8EA2VycgMDCQEQX3ZhbGlkYXRlQWRkcmVzcwIFCXJlY2lwaWVudAIlYWRkU2VjdXJpdHlEZXBvc2l0OiBpbnZhbGlkIHJlY2lwaWVudAkBFV92YWxpZGF0ZVBheW1lbnRzU2l6ZQMIBQFpCHBheW1lbnRzAAECHmFkZFNlY3VyaXR5RGVwb3NpdDogbm8gcGF5bWVudAcJARVfdmFsaWRhdGVQYXltZW50QXNzZXQDCQCRAwIIBQFpCHBheW1lbnRzAAAFBHVuaXQCIWFkZFNlY3VyaXR5RGVwb3NpdDogaW52YWxpZCBhc3NldAcDCQAAAgUDZXJyBQNlcnIEDXJlY2lwaWVudEFkZHIJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCXJlY2lwaWVudAQHYmFsYW5jZQkBDF9sb2FkU2VjRGVwbwEFDXJlY2lwaWVudEFkZHIEDnVwZGF0ZWRCYWxhbmNlCQBkAgUHYmFsYW5jZQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQJAJQKAgkBDF9zYXZlU2VjRGVwbwIFDXJlY2lwaWVudEFkZHIFDnVwZGF0ZWRCYWxhbmNlBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEnN1YlNlY3VyaXR5RGVwb3NpdAEHYW1vdW50XwQHYmFsYW5jZQkBDF9sb2FkU2VjRGVwbwEIBQFpBmNhbGxlcgQDZXJyAwkBC19pc1plcm9Mb2NrAgkA2AQBCAUBaQ9jYWxsZXJQdWJsaWNLZXkCGnN1YlNlY3VyaXR5RGVwb3NpdDogbG9ja2VkAwkAZgIFB2Ftb3VudF8FB2JhbGFuY2UJAAIBAihzdWJTZWN1cml0eURlcG9zaXQ6IGluc3VmZmljaWVudCBiYWxhbmNlBgcDCQAAAgUDZXJyBQNlcnIJAJQKAgkAzggCCQEMX3NhdmVTZWNEZXBvAggFAWkGY2FsbGVyCQBlAgUHYmFsYW5jZQUHYW1vdW50XwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFB2Ftb3VudF8FBHVuaXQFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQtzZXRNdWx0aXNpZwEJbXVsdGlzaWdfBANlcnIDCQERX29ubHlUaGlzQ29udHJhY3QBCAUBaQZjYWxsZXIJARBfdmFsaWRhdGVBZGRyZXNzAgUJbXVsdGlzaWdfAiVzZXRNdWx0aXNpZzogaW52YWxpZCBtdWx0aXNpZyBhZGRyZXNzBwMJAAACBQNlcnIFA2VycgkAlAoCCQENX3NhdmVNdWx0aXNpZwEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCW11bHRpc2lnXwUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECdHgBBnZlcmlmeQAEByRtYXRjaDAJAKIIAQUMS0VZX01VTFRJU0lHAwkAAQIFByRtYXRjaDACBlN0cmluZwQIbXVsdGlzaWcFByRtYXRjaDAJAQt2YWx1ZU9yRWxzZQIJAJsIAgkBEUBleHRyTmF0aXZlKDEwNjIpAQUIbXVsdGlzaWcJALkJAgkAzAgCBQpLRVlfU1RBVFVTCQDMCAIJAKUIAQUEdGhpcwkAzAgCCQDYBAEIBQJ0eAJpZAUDbmlsBQlTRVBBUkFUT1IHCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAACAUCdHgPc2VuZGVyUHVibGljS2V5FOoUhQ==", "height": 2496967, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 3nAKnhSedMQtJqsJZrMeQWAwT8JhPG5Mw8XjQaGw5REq Next: EUzpt35SfJdGLyHGQ1sEzhjYJ3FJjbAVPc4CUEd6ye6i Diff:
OldNewDifferences
295295 func _saveT (execChainId_,epoch_,val_) = [IntegerEntry(makeString([KEY_T, toString(execChainId_), toString(epoch_)], SEPARATOR), val_)]
296296
297297
298+func _loadSignerGroupPublicKey (execChainId_,epoch_) = match getString(makeString([KEY_SIGNER_GROUP_PUBLIC_KEY, toString(execChainId_), toString(epoch_)], SEPARATOR)) {
299+ case a: String =>
300+ fromBase58String(a)
301+ case _ =>
302+ base58''
303+}
304+
305+
306+func _saveSignerGroupPublicKey (execChainId_,epoch_,signerGroupPublicKey_) = [StringEntry(makeString([KEY_SIGNER_GROUP_PUBLIC_KEY, toString(execChainId_), toString(epoch_)], SEPARATOR), toBase58String(signerGroupPublicKey_))]
307+
308+
298309 func _loadRsByEvent (execChainId_,eventId_) = match getString(makeString([KEY_R, toString(execChainId_), toString(eventId_)], SEPARATOR)) {
299310 case a: String =>
300311 if ((size(a) > 0))
459470 }
460471
461472
473+func _getRawEvent (eventId_,execChainId_) = {
474+ let result = invoke(_loadWitnessAddress(), FUNC_GET_RAW_EVENT, [eventId_, execChainId_], nil)
475+ if ((result == result))
476+ then match result {
477+ case a: (String, ByteVector) =>
478+ a
479+ case _ =>
480+ throw("_getRawEvent: revert")
481+ }
482+ else throw("Strict value is not equal to itself.")
483+ }
484+
485+
462486 func _isActiveSigner (publicKey_,publicKeys_,err_) = if (!(containsElement(publicKeys_, publicKey_)))
463487 then throw(err_)
464488 else true
582606 }
583607
584608
609+func _verifySignature (execChainId_,epoch_,eventId_,rSigma_,sSigma_,err_) = {
610+ let event = _getRawEvent(eventId_, execChainId_)
611+ let eventType = event._1
612+ let eventBytes = event._2
613+ let groupPublicKey = _loadSignerGroupPublicKey(execChainId_, epoch_)
614+ if ((eventType == EVENT_TYPE_WAVES))
615+ then {
616+ let signature = (fromBase58String(rSigma_) + fromBase58String(sSigma_))
617+ if (!(sigVerify(eventBytes, signature, groupPublicKey)))
618+ then throw(err_)
619+ else true
620+ }
621+ else if ((eventType == EVENT_TYPE_EVM))
622+ then true
623+ else throw(err_)
624+ }
625+
626+
585627 func _publicKeysToAddrsStr (publicKeys_) = {
586628 func foldfunc (acc_,elem_) = (acc_ :+ toString(addressFromPublicKey(fromBase58String(elem_))))
587629
627669
628670
629671 @Callable(i)
630-func setActiveSigners (execChainId_,signers_,t_) = {
631- let err = if (if (if (_onlyThisContract(i.caller))
672+func setActiveSigners (execChainId_,signers_,t_,signerGroupPublicKey_) = {
673+ let err = if (if (if (if (_onlyThisContract(i.caller))
632674 then _whenInitialized()
633675 else false)
634676 then _validatePublicKeys(signers_, "setActiveSigners: invalid signers")
635677 else false)
636678 then _validateInt(t_, 2, size(signers_), "setActiveSigners: invalid T")
679+ else false)
680+ then _validateString(signerGroupPublicKey_, "setActiveSigners: invalid signerGroupPublicKey")
637681 else false
638682 if ((err == err))
639683 then {
640684 let epoch = _loadCurrentEpoch(execChainId_)
641- $Tuple2((((_saveCurrentEpoch(execChainId_, (epoch + 1)) ++ _saveT(execChainId_, (epoch + 1), t_)) ++ _saveSigners(execChainId_, (epoch + 1), signers_)) ++ _incrementLocks(signers_)), unit)
685+ $Tuple2(((((_saveCurrentEpoch(execChainId_, (epoch + 1)) ++ _saveT(execChainId_, (epoch + 1), t_)) ++ _saveSigners(execChainId_, (epoch + 1), signers_)) ++ _saveSignerGroupPublicKey(execChainId_, (epoch + 1), fromBase58String(signerGroupPublicKey_))) ++ _incrementLocks(signers_)), unit)
642686 }
643687 else throw("Strict value is not equal to itself.")
644688 }
711755 let signersArray = _loadSignersWithSByEvent(execChainId_, eventId_)
712756 let eventStatusActions = if (((size(sArray) + 1) == t))
713757 then {
714- let err1 = _validateString(sSigma_, "submitS: invalid s sigma")
758+ let err1 = if (_validateString(sSigma_, "submitS: invalid s sigma"))
759+ then _verifySignature(execChainId_, epoch, eventId_, rSigma_, sSigma_, "submitS: invalid signature")
760+ else false
715761 if ((err1 == err1))
716762 then {
717763 let executorIdxSize = _loadSignedEventExecutorIdxSize(execChainId_)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEPARATOR = "__"
55
66 let KEY_INIT = "INIT"
77
88 let KEY_MULTISIG = "MULTISIG"
99
1010 let KEY_STATUS = "STATUS"
1111
1212 let KEY_MIN_SEC_DEPO = "MIN_SEC_DEPO"
1313
1414 let KEY_PUNISHMENT = "PUNISHMENT"
1515
1616 let KEY_RESET_BLOCK_DELTA = "RESET_BLOCK_DELTA"
1717
1818 let KEY_SEC_DEPO = "SEC_DEPO"
1919
2020 let KEY_REWARD_TOKEN_ADDRESS = "REWARD_TOKEN_ADDRESS"
2121
2222 let KEY_REWARD_AMOUNT = "REWARD_AMOUNT"
2323
2424 let KEY_WINTESS_ADDRESS = "WINTESS_ADDRESS"
2525
2626 let KEY_CURRENT_EPOCH = "CURRENT_EPOCH"
2727
2828 let KEY_SIGNERS_PER_EPOCH = "SIGNERS_PER_EPOCH"
2929
3030 let KEY_EVENT_STATUS = "EVENT_STATUS"
3131
3232 let KEY_LOCKS = "LOCKS"
3333
3434 let KEY_T = "T"
3535
3636 let KEY_R = "R"
3737
3838 let KEY_S = "S"
3939
4040 let KEY_R_SIGNERS = "R_SIGNERS"
4141
4242 let KEY_EVENT_START_BLOCK = "EVENT_START_BLOCK"
4343
4444 let KEY_R_SIGMA = "R_SIGMA"
4545
4646 let KEY_S_SIGMA = "S_SIGMA"
4747
4848 let KEY_S_SIGNERS = "S_SIGNERS"
4949
5050 let KEY_SIGNED_EVENT_EXECUTOR = "SIGNED_EVENT_EXECUTOR"
5151
5252 let KEY_SIZE = "SIZE"
5353
5454 let KEY_SIGNER_GROUP_PUBLIC_KEY = "SIGNER_GROUP_PUBLIC_KEY"
5555
5656 let FUNC_MINT_MANY = "mintMany"
5757
5858 let FUNC_IS_CONFIRMED_EVENT = "isConfirmedEvent"
5959
6060 let FUNC_GET_RAW_EVENT = "getRawEvent"
6161
6262 let EVENT_TYPE_WAVES = "WAVES"
6363
6464 let EVENT_TYPE_EVM = "EVM"
6565
6666 let EVENT_STATUS_INIT = 1
6767
6868 let EVENT_STATUS_SIGN = 2
6969
7070 let EVENT_STATUS_DONE = 3
7171
7272 let MAX_INT = 9223372036854775807
7373
7474 func _validateAddress (address_,err_) = match addressFromString(address_) {
7575 case a: Address =>
7676 true
7777 case _ =>
7878 throw(err_)
7979 }
8080
8181
8282 func _validateAsset (assetId_,err_) = match assetInfo(fromBase58String(assetId_)) {
8383 case a: Asset =>
8484 true
8585 case _ =>
8686 throw(err_)
8787 }
8888
8989
9090 func _validateInt (val_,lowerBoundary_,upperBoundary_,err_) = if (if ((lowerBoundary_ > val_))
9191 then true
9292 else (val_ > upperBoundary_))
9393 then throw(err_)
9494 else true
9595
9696
9797 func _validateString (val_,err_) = if (if ((0 >= size(val_)))
9898 then true
9999 else contains(val_, SEPARATOR))
100100 then throw(err_)
101101 else true
102102
103103
104104 func _validatePaymentsSize (payments_,target_,err_) = if ((size(payments_) != target_))
105105 then throw(err_)
106106 else true
107107
108108
109109 func _validatePaymentAsset (payment_,asset_,err_) = if ((payment_.assetId != asset_))
110110 then throw(err_)
111111 else true
112112
113113
114114 func _validatePublicKey (publicKey_,err_) = if ((size(fromBase58String(publicKey_)) != 32))
115115 then throw(err_)
116116 else true
117117
118118
119119 func _validatePublicKeys (publicKeys_,err_) = {
120120 func foldFunc (acc,elem) = $Tuple2(if (acc._1)
121121 then _validatePublicKey(elem, acc._2)
122122 else false, acc._2)
123123
124124 let result = {
125125 let $l = publicKeys_
126126 let $s = size($l)
127127 let $acc0 = $Tuple2(true, err_)
128128 func $f0_1 ($a,$i) = if (($i >= $s))
129129 then $a
130130 else foldFunc($a, $l[$i])
131131
132132 func $f0_2 ($a,$i) = if (($i >= $s))
133133 then $a
134134 else throw("List size exceeds 10")
135135
136136 $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)
137137 }
138138 result._1
139139 }
140140
141141
142142 func _loadInit () = match getBoolean(KEY_INIT) {
143143 case a: Boolean =>
144144 a
145145 case _ =>
146146 false
147147 }
148148
149149
150150 func _saveInit (isInit_) = [BooleanEntry(KEY_INIT, isInit_)]
151151
152152
153153 func _loadMultisig () = match getString(KEY_MULTISIG) {
154154 case a: String =>
155155 addressFromStringValue(a)
156156 case _ =>
157157 Address(base58'')
158158 }
159159
160160
161161 func _saveMultisig (multisig_) = [StringEntry(KEY_MULTISIG, toString(multisig_))]
162162
163163
164164 func _loadMinSecDepo () = match getInteger(KEY_MIN_SEC_DEPO) {
165165 case a: Int =>
166166 a
167167 case _ =>
168168 0
169169 }
170170
171171
172172 func _saveMinSecDepo (val_) = [IntegerEntry(KEY_MIN_SEC_DEPO, val_)]
173173
174174
175175 func _loadSecDepo (account_) = match getInteger(makeString([KEY_SEC_DEPO, toString(account_)], SEPARATOR)) {
176176 case a: Int =>
177177 a
178178 case _ =>
179179 0
180180 }
181181
182182
183183 func _saveSecDepo (account_,val_) = [IntegerEntry(makeString([KEY_SEC_DEPO, toString(account_)], SEPARATOR), val_)]
184184
185185
186186 func _loadPunishment () = match getInteger(KEY_PUNISHMENT) {
187187 case a: Int =>
188188 a
189189 case _ =>
190190 0
191191 }
192192
193193
194194 func _savePunishment (val_) = [IntegerEntry(KEY_PUNISHMENT, val_)]
195195
196196
197197 func _loadResetBlockDelta () = match getInteger(KEY_RESET_BLOCK_DELTA) {
198198 case a: Int =>
199199 a
200200 case _ =>
201201 0
202202 }
203203
204204
205205 func _saveResetBlockDelta (val_) = [IntegerEntry(KEY_RESET_BLOCK_DELTA, val_)]
206206
207207
208208 func _loadRewardTokenAddress () = match getString(KEY_REWARD_TOKEN_ADDRESS) {
209209 case a: String =>
210210 addressFromStringValue(a)
211211 case _ =>
212212 Address(base58'')
213213 }
214214
215215
216216 func _saveRewardTokenAddress (val_) = [StringEntry(KEY_REWARD_TOKEN_ADDRESS, toString(val_))]
217217
218218
219219 func _loadRewardAmount () = match getInteger(KEY_REWARD_AMOUNT) {
220220 case a: Int =>
221221 a
222222 case _ =>
223223 0
224224 }
225225
226226
227227 func _saveRewardAmount (val_) = [IntegerEntry(KEY_REWARD_AMOUNT, val_)]
228228
229229
230230 func _loadWitnessAddress () = match getString(KEY_WINTESS_ADDRESS) {
231231 case a: String =>
232232 addressFromStringValue(a)
233233 case _ =>
234234 Address(base58'')
235235 }
236236
237237
238238 func _saveWitnessAddress (val_) = [StringEntry(KEY_WINTESS_ADDRESS, toString(val_))]
239239
240240
241241 func _loadCurrentEpoch (execChainId_) = match getInteger(makeString([KEY_CURRENT_EPOCH, toString(execChainId_)], SEPARATOR)) {
242242 case a: Int =>
243243 a
244244 case _ =>
245245 0
246246 }
247247
248248
249249 func _saveCurrentEpoch (execChainId_,val_) = [IntegerEntry(makeString([KEY_CURRENT_EPOCH, toString(execChainId_)], SEPARATOR), val_)]
250250
251251
252252 func _loadSigners (execChainId_,epoch_) = match getString(makeString([KEY_SIGNERS_PER_EPOCH, toString(execChainId_), toString(epoch_)], SEPARATOR)) {
253253 case a: String =>
254254 if ((size(a) > 0))
255255 then split(a, SEPARATOR)
256256 else nil
257257 case _ =>
258258 nil
259259 }
260260
261261
262262 func _saveSigners (execChainId_,epoch_,signers_) = [StringEntry(makeString([KEY_SIGNERS_PER_EPOCH, toString(execChainId_), toString(epoch_)], SEPARATOR), makeString(signers_, SEPARATOR))]
263263
264264
265265 func _loadEventStatus (execChainId_,eventId_) = match getInteger(makeString([KEY_EVENT_STATUS, toString(execChainId_), toString(eventId_)], SEPARATOR)) {
266266 case a: Int =>
267267 a
268268 case _ =>
269269 EVENT_STATUS_INIT
270270 }
271271
272272
273273 func _saveEventStatus (execChainId_,eventId_,status_) = [IntegerEntry(makeString([KEY_EVENT_STATUS, toString(execChainId_), toString(eventId_)], SEPARATOR), status_)]
274274
275275
276276 func _loadLock (publicKey_) = match getInteger(makeString([KEY_LOCKS, publicKey_], SEPARATOR)) {
277277 case a: Int =>
278278 a
279279 case _ =>
280280 0
281281 }
282282
283283
284284 func _saveLock (publicKey_,val_) = [IntegerEntry(makeString([KEY_LOCKS, publicKey_], SEPARATOR), val_)]
285285
286286
287287 func _loadT (execChainId_,epoch_) = match getInteger(makeString([KEY_T, toString(execChainId_), toString(epoch_)], SEPARATOR)) {
288288 case a: Int =>
289289 a
290290 case _ =>
291291 0
292292 }
293293
294294
295295 func _saveT (execChainId_,epoch_,val_) = [IntegerEntry(makeString([KEY_T, toString(execChainId_), toString(epoch_)], SEPARATOR), val_)]
296296
297297
298+func _loadSignerGroupPublicKey (execChainId_,epoch_) = match getString(makeString([KEY_SIGNER_GROUP_PUBLIC_KEY, toString(execChainId_), toString(epoch_)], SEPARATOR)) {
299+ case a: String =>
300+ fromBase58String(a)
301+ case _ =>
302+ base58''
303+}
304+
305+
306+func _saveSignerGroupPublicKey (execChainId_,epoch_,signerGroupPublicKey_) = [StringEntry(makeString([KEY_SIGNER_GROUP_PUBLIC_KEY, toString(execChainId_), toString(epoch_)], SEPARATOR), toBase58String(signerGroupPublicKey_))]
307+
308+
298309 func _loadRsByEvent (execChainId_,eventId_) = match getString(makeString([KEY_R, toString(execChainId_), toString(eventId_)], SEPARATOR)) {
299310 case a: String =>
300311 if ((size(a) > 0))
301312 then split(a, SEPARATOR)
302313 else nil
303314 case _ =>
304315 nil
305316 }
306317
307318
308319 func _saveRsByEvent (execChainId_,eventId_,rs_) = [StringEntry(makeString([KEY_R, toString(execChainId_), toString(eventId_)], SEPARATOR), makeString(rs_, SEPARATOR))]
309320
310321
311322 func _loadSsByEvent (execChainId_,eventId_) = match getString(makeString([KEY_S, toString(execChainId_), toString(eventId_)], SEPARATOR)) {
312323 case a: String =>
313324 if ((size(a) > 0))
314325 then split(a, SEPARATOR)
315326 else nil
316327 case _ =>
317328 nil
318329 }
319330
320331
321332 func _saveSsByEvent (execChainId_,eventId_,ss_) = [StringEntry(makeString([KEY_S, toString(execChainId_), toString(eventId_)], SEPARATOR), makeString(ss_, SEPARATOR))]
322333
323334
324335 func _loadRSigmaByEvent (execChainId_,eventId_) = match getString(makeString([KEY_R_SIGMA, toString(execChainId_), toString(eventId_)], SEPARATOR)) {
325336 case a: String =>
326337 a
327338 case _ =>
328339 ""
329340 }
330341
331342
332343 func _saveRSigmaByEvent (execChainId_,eventId_,rSigma_) = [StringEntry(makeString([KEY_R_SIGMA, toString(execChainId_), toString(eventId_)], SEPARATOR), rSigma_)]
333344
334345
335346 func _loadSSigmaByEvent (execChainId_,eventId_) = match getString(makeString([KEY_S_SIGMA, toString(execChainId_), toString(eventId_)], SEPARATOR)) {
336347 case a: String =>
337348 a
338349 case _ =>
339350 ""
340351 }
341352
342353
343354 func _saveSSigmaByEvent (execChainId_,eventId_,sSigma_) = [StringEntry(makeString([KEY_S_SIGMA, toString(execChainId_), toString(eventId_)], SEPARATOR), sSigma_)]
344355
345356
346357 func _loadRByEventAndSigner (execChainId_,eventId_,signer_) = match getString(makeString([KEY_R, toString(execChainId_), toString(eventId_), signer_], SEPARATOR)) {
347358 case a: String =>
348359 a
349360 case _ =>
350361 ""
351362 }
352363
353364
354365 func _saveRByEventAndSigner (execChainId_,eventId_,signer_,r_) = [StringEntry(makeString([KEY_R, toString(execChainId_), toString(eventId_), signer_], SEPARATOR), r_)]
355366
356367
357368 func _loadSByEventAndSigner (execChainId_,eventId_,signer_) = match getString(makeString([KEY_S, toString(execChainId_), toString(eventId_), signer_], SEPARATOR)) {
358369 case a: String =>
359370 a
360371 case _ =>
361372 ""
362373 }
363374
364375
365376 func _saveSByEventAndSigner (execChainId_,eventId_,signer_,s_) = [StringEntry(makeString([KEY_S, toString(execChainId_), toString(eventId_), signer_], SEPARATOR), s_)]
366377
367378
368379 func _loadSignersWithRByEvent (execChainId_,eventId_) = match getString(makeString([KEY_R_SIGNERS, toString(execChainId_), toString(eventId_)], SEPARATOR)) {
369380 case a: String =>
370381 if ((size(a) > 0))
371382 then split(a, SEPARATOR)
372383 else nil
373384 case _ =>
374385 nil
375386 }
376387
377388
378389 func _saveSignersWithRByEvent (execChainId_,eventId_,rs_) = [StringEntry(makeString([KEY_R_SIGNERS, toString(execChainId_), toString(eventId_)], SEPARATOR), makeString(rs_, SEPARATOR))]
379390
380391
381392 func _loadSignersWithSByEvent (execChainId_,eventId_) = match getString(makeString([KEY_S_SIGNERS, toString(execChainId_), toString(eventId_)], SEPARATOR)) {
382393 case a: String =>
383394 if ((size(a) > 0))
384395 then split(a, SEPARATOR)
385396 else nil
386397 case _ =>
387398 nil
388399 }
389400
390401
391402 func _saveSignersWithSByEvent (execChainId_,eventId_,ss_) = [StringEntry(makeString([KEY_S_SIGNERS, toString(execChainId_), toString(eventId_)], SEPARATOR), makeString(ss_, SEPARATOR))]
392403
393404
394405 func _loadEventStartBlock (execChainId_,eventId_) = match getInteger(makeString([KEY_EVENT_START_BLOCK, toString(execChainId_), toString(eventId_)], SEPARATOR)) {
395406 case a: Int =>
396407 a
397408 case _ =>
398409 0
399410 }
400411
401412
402413 func _saveEventStartBlock (execChainId_,eventId_,val_) = [IntegerEntry(makeString([KEY_EVENT_START_BLOCK, toString(execChainId_), toString(eventId_)], SEPARATOR), val_)]
403414
404415
405416 func _loadSignedEventExecutorIdxSize (executionChainId_) = match getInteger(makeString([KEY_SIGNED_EVENT_EXECUTOR, toString(executionChainId_), KEY_SIZE], SEPARATOR)) {
406417 case a: Int =>
407418 a
408419 case _ =>
409420 0
410421 }
411422
412423
413424 func _saveSignedEventExecutorIdxSize (executionChainId_,val_) = [IntegerEntry(makeString([KEY_SIGNED_EVENT_EXECUTOR, toString(executionChainId_), KEY_SIZE], SEPARATOR), val_)]
414425
415426
416427 func _loadSignedEventExecutorIdx (executionChainId_,idx_) = match getInteger(makeString([KEY_SIGNED_EVENT_EXECUTOR, toString(executionChainId_), toString(idx_)], SEPARATOR)) {
417428 case a: Int =>
418429 a
419430 case _ =>
420431 0
421432 }
422433
423434
424435 func _saveSignedEventExecutorIdx (executionChainId_,idx_,val_) = [IntegerEntry(makeString([KEY_SIGNED_EVENT_EXECUTOR, toString(executionChainId_), toString(idx_)], SEPARATOR), val_)]
425436
426437
427438 func _onlyThisContract (caller_) = if ((caller_ != this))
428439 then throw("_onlyThisContract: revert")
429440 else true
430441
431442
432443 func _whenMultisigSet () = if ((_loadMultisig() == Address(base58'')))
433444 then throw("_whenMultisigSet: revert")
434445 else true
435446
436447
437448 func _whenNotInitialized () = if (_loadInit())
438449 then throw("_whenNotInitialized: revert")
439450 else true
440451
441452
442453 func _whenInitialized () = if (!(_loadInit()))
443454 then throw("_whenInitialized: revert")
444455 else true
445456
446457
447458 func _isConfirmedEvent (eventId_,execChainId_,err_) = {
448459 let result = invoke(_loadWitnessAddress(), FUNC_IS_CONFIRMED_EVENT, [eventId_, execChainId_], nil)
449460 if ((result == result))
450461 then match result {
451462 case a: Boolean =>
452463 if (!(a))
453464 then throw(err_)
454465 else true
455466 case _ =>
456467 throw(err_)
457468 }
458469 else throw("Strict value is not equal to itself.")
459470 }
460471
461472
473+func _getRawEvent (eventId_,execChainId_) = {
474+ let result = invoke(_loadWitnessAddress(), FUNC_GET_RAW_EVENT, [eventId_, execChainId_], nil)
475+ if ((result == result))
476+ then match result {
477+ case a: (String, ByteVector) =>
478+ a
479+ case _ =>
480+ throw("_getRawEvent: revert")
481+ }
482+ else throw("Strict value is not equal to itself.")
483+ }
484+
485+
462486 func _isActiveSigner (publicKey_,publicKeys_,err_) = if (!(containsElement(publicKeys_, publicKey_)))
463487 then throw(err_)
464488 else true
465489
466490
467491 func _checkSecDepo (signer_,err_) = if ((_loadMinSecDepo() > _loadSecDepo(addressFromPublicKey(fromBase58String(signer_)))))
468492 then throw(err_)
469493 else true
470494
471495
472496 func _checkEventStatusForSubmitR (execChainId_,eventId_,err_) = if ((_loadEventStatus(execChainId_, eventId_) != EVENT_STATUS_INIT))
473497 then throw(err_)
474498 else true
475499
476500
477501 func _checkEventStatusForSubmitS (execChainId_,eventId_,err_) = if ((_loadEventStatus(execChainId_, eventId_) != EVENT_STATUS_SIGN))
478502 then throw(err_)
479503 else true
480504
481505
482506 func _checkEventStatusForReset (execChainId_,eventId_,err_) = if (if ((_loadEventStatus(execChainId_, eventId_) != EVENT_STATUS_SIGN))
483507 then true
484508 else ((_loadEventStartBlock(execChainId_, eventId_) + _loadResetBlockDelta()) > height))
485509 then throw(err_)
486510 else true
487511
488512
489513 func _incrementLocks (signers_) = {
490514 func foldFunc (acc,elem) = (acc ++ _saveLock(elem, (_loadLock(elem) + 1)))
491515
492516 let $l = signers_
493517 let $s = size($l)
494518 let $acc0 = nil
495519 func $f0_1 ($a,$i) = if (($i >= $s))
496520 then $a
497521 else foldFunc($a, $l[$i])
498522
499523 func $f0_2 ($a,$i) = if (($i >= $s))
500524 then $a
501525 else throw("List size exceeds 10")
502526
503527 $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)
504528 }
505529
506530
507531 func _isZeroLock (publicKey_,err_) = if ((_loadLock(publicKey_) > 0))
508532 then throw(err_)
509533 else true
510534
511535
512536 func _notSubmittedR (execChainId_,eventId_,signer_,err_) = {
513537 let r = _loadRByEventAndSigner(execChainId_, eventId_, signer_)
514538 if (if ((r != ""))
515539 then containsElement(_loadRsByEvent(execChainId_, eventId_), r)
516540 else false)
517541 then throw(err_)
518542 else true
519543 }
520544
521545
522546 func _notSubmittedS (execChainId_,eventId_,signer_,err_) = {
523547 let s = _loadSByEventAndSigner(execChainId_, eventId_, signer_)
524548 if (if ((s != ""))
525549 then containsElement(_loadSsByEvent(execChainId_, eventId_), s)
526550 else false)
527551 then throw(err_)
528552 else true
529553 }
530554
531555
532556 func _submittedR (execChainId_,eventId_,signer_,err_) = {
533557 let r = _loadRByEventAndSigner(execChainId_, eventId_, signer_)
534558 if (if ((r == ""))
535559 then true
536560 else !(containsElement(_loadRsByEvent(execChainId_, eventId_), r)))
537561 then throw(err_)
538562 else true
539563 }
540564
541565
542566 func _slashIncorrect (signersWithR_,signersWithS_) = {
543567 let punishment = _loadPunishment()
544568 func foldFunc (acc,elem) = if (containsElement(signersWithS_, elem))
545569 then $Tuple3(acc._1, (acc._2 :+ elem), acc._3)
546570 else {
547571 let signerAddress = addressFromPublicKey(fromBase58String(elem))
548572 $Tuple3((acc._1 ++ _saveSecDepo(signerAddress, (_loadSecDepo(signerAddress) - punishment))), acc._2, (acc._3 + punishment))
549573 }
550574
551575 let $l = signersWithR_
552576 let $s = size($l)
553577 let $acc0 = $Tuple3(nil, nil, 0)
554578 func $f0_1 ($a,$i) = if (($i >= $s))
555579 then $a
556580 else foldFunc($a, $l[$i])
557581
558582 func $f0_2 ($a,$i) = if (($i >= $s))
559583 then $a
560584 else throw("List size exceeds 10")
561585
562586 $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)
563587 }
564588
565589
566590 func _compensateCorrect (signers_,compensation_) = {
567591 let perSigner = (compensation_ / size(signers_))
568592 func foldFunc (acc,elem) = (acc :+ ScriptTransfer(addressFromPublicKey(fromBase58String(elem)), perSigner, unit))
569593
570594 let $l = signers_
571595 let $s = size($l)
572596 let $acc0 = nil
573597 func $f0_1 ($a,$i) = if (($i >= $s))
574598 then $a
575599 else foldFunc($a, $l[$i])
576600
577601 func $f0_2 ($a,$i) = if (($i >= $s))
578602 then $a
579603 else throw("List size exceeds 10")
580604
581605 $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)
582606 }
583607
584608
609+func _verifySignature (execChainId_,epoch_,eventId_,rSigma_,sSigma_,err_) = {
610+ let event = _getRawEvent(eventId_, execChainId_)
611+ let eventType = event._1
612+ let eventBytes = event._2
613+ let groupPublicKey = _loadSignerGroupPublicKey(execChainId_, epoch_)
614+ if ((eventType == EVENT_TYPE_WAVES))
615+ then {
616+ let signature = (fromBase58String(rSigma_) + fromBase58String(sSigma_))
617+ if (!(sigVerify(eventBytes, signature, groupPublicKey)))
618+ then throw(err_)
619+ else true
620+ }
621+ else if ((eventType == EVENT_TYPE_EVM))
622+ then true
623+ else throw(err_)
624+ }
625+
626+
585627 func _publicKeysToAddrsStr (publicKeys_) = {
586628 func foldfunc (acc_,elem_) = (acc_ :+ toString(addressFromPublicKey(fromBase58String(elem_))))
587629
588630 let $l = publicKeys_
589631 let $s = size($l)
590632 let $acc0 = nil
591633 func $f0_1 ($a,$i) = if (($i >= $s))
592634 then $a
593635 else foldfunc($a, $l[$i])
594636
595637 func $f0_2 ($a,$i) = if (($i >= $s))
596638 then $a
597639 else throw("List size exceeds 51")
598640
599641 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51)
600642 }
601643
602644
603645 @Callable(i)
604646 func init (minSecDepo_,punishment_,resetBlockDelta_,rewardTokenAddress_,rewardAmount_,witnessAddress_) = {
605647 let err = if (if (if (if (if (if (if (if (_onlyThisContract(i.caller))
606648 then _whenNotInitialized()
607649 else false)
608650 then _whenMultisigSet()
609651 else false)
610652 then _validateInt(minSecDepo_, punishment_, MAX_INT, "init: invalid minSecDepo")
611653 else false)
612654 then _validateInt(punishment_, 0, MAX_INT, "init: invalid punishment")
613655 else false)
614656 then _validateInt(resetBlockDelta_, 0, MAX_INT, "init: invalid resetBlockDelta")
615657 else false)
616658 then _validateAddress(rewardTokenAddress_, "init: invalid rewardTokenAddress")
617659 else false)
618660 then _validateInt(rewardAmount_, 0, MAX_INT, "init: invalid rewardAmount")
619661 else false)
620662 then _validateAddress(witnessAddress_, "init: invalid witnessAddress")
621663 else false
622664 if ((err == err))
623665 then $Tuple2(((((((_saveInit(true) ++ _saveMinSecDepo(minSecDepo_)) ++ _savePunishment(punishment_)) ++ _saveResetBlockDelta(resetBlockDelta_)) ++ _saveRewardTokenAddress(addressFromStringValue(rewardTokenAddress_))) ++ _saveRewardAmount(rewardAmount_)) ++ _saveWitnessAddress(addressFromStringValue(witnessAddress_))), unit)
624666 else throw("Strict value is not equal to itself.")
625667 }
626668
627669
628670
629671 @Callable(i)
630-func setActiveSigners (execChainId_,signers_,t_) = {
631- let err = if (if (if (_onlyThisContract(i.caller))
672+func setActiveSigners (execChainId_,signers_,t_,signerGroupPublicKey_) = {
673+ let err = if (if (if (if (_onlyThisContract(i.caller))
632674 then _whenInitialized()
633675 else false)
634676 then _validatePublicKeys(signers_, "setActiveSigners: invalid signers")
635677 else false)
636678 then _validateInt(t_, 2, size(signers_), "setActiveSigners: invalid T")
679+ else false)
680+ then _validateString(signerGroupPublicKey_, "setActiveSigners: invalid signerGroupPublicKey")
637681 else false
638682 if ((err == err))
639683 then {
640684 let epoch = _loadCurrentEpoch(execChainId_)
641- $Tuple2((((_saveCurrentEpoch(execChainId_, (epoch + 1)) ++ _saveT(execChainId_, (epoch + 1), t_)) ++ _saveSigners(execChainId_, (epoch + 1), signers_)) ++ _incrementLocks(signers_)), unit)
685+ $Tuple2(((((_saveCurrentEpoch(execChainId_, (epoch + 1)) ++ _saveT(execChainId_, (epoch + 1), t_)) ++ _saveSigners(execChainId_, (epoch + 1), signers_)) ++ _saveSignerGroupPublicKey(execChainId_, (epoch + 1), fromBase58String(signerGroupPublicKey_))) ++ _incrementLocks(signers_)), unit)
642686 }
643687 else throw("Strict value is not equal to itself.")
644688 }
645689
646690
647691
648692 @Callable(i)
649693 func submitR (eventId_,execChainId_,r_) = {
650694 let callerPublicKey = toBase58String(i.callerPublicKey)
651695 let epoch = _loadCurrentEpoch(execChainId_)
652696 let t = _loadT(execChainId_, epoch)
653697 let err = if (if (if (if (if (if (if (if (_whenInitialized())
654698 then _validateInt(eventId_, 0, MAX_INT, "submitR: invalid eventId")
655699 else false)
656700 then _validateInt(execChainId_, 0, MAX_INT, "submitR: invalid execChainId")
657701 else false)
658702 then _validateString(r_, "submitR: invalid r")
659703 else false)
660704 then _isConfirmedEvent(eventId_, execChainId_, "submitR: event not confirmed")
661705 else false)
662706 then _isActiveSigner(callerPublicKey, _loadSigners(execChainId_, epoch), "submitR: not active")
663707 else false)
664708 then _checkSecDepo(callerPublicKey, "submitR: not enough security deposit")
665709 else false)
666710 then _checkEventStatusForSubmitR(execChainId_, eventId_, "submitR: invalid event status")
667711 else false)
668712 then _notSubmittedR(execChainId_, eventId_, callerPublicKey, "submitR: already submitted")
669713 else false
670714 if ((err == err))
671715 then {
672716 let rArray = _loadRsByEvent(execChainId_, eventId_)
673717 let signersArray = _loadSignersWithRByEvent(execChainId_, eventId_)
674718 let eventStatusActions = if (((size(rArray) + 1) == t))
675719 then (_saveEventStatus(execChainId_, eventId_, EVENT_STATUS_SIGN) ++ _saveEventStartBlock(execChainId_, eventId_, height))
676720 else nil
677721 $Tuple2((((_saveRsByEvent(execChainId_, eventId_, (rArray :+ r_)) ++ _saveRByEventAndSigner(execChainId_, eventId_, callerPublicKey, r_)) ++ _saveSignersWithRByEvent(execChainId_, eventId_, (signersArray :+ callerPublicKey))) ++ eventStatusActions), unit)
678722 }
679723 else throw("Strict value is not equal to itself.")
680724 }
681725
682726
683727
684728 @Callable(i)
685729 func submitS (eventId_,execChainId_,rSigma_,s_,sSigma_) = {
686730 let callerPublicKey = toBase58String(i.callerPublicKey)
687731 let epoch = _loadCurrentEpoch(execChainId_)
688732 let t = _loadT(execChainId_, epoch)
689733 let err = if (if (if (if (if (if (if (if (if (_whenInitialized())
690734 then _validateInt(eventId_, 0, MAX_INT, "submitS: invalid eventId")
691735 else false)
692736 then _validateInt(execChainId_, 0, MAX_INT, "submitS: invalid execChainId")
693737 else false)
694738 then _validateString(rSigma_, "submitS: invalid r sigma")
695739 else false)
696740 then _validateString(s_, "submitS: invalid s")
697741 else false)
698742 then _isActiveSigner(callerPublicKey, _loadSigners(execChainId_, epoch), "submitS: not active")
699743 else false)
700744 then _checkSecDepo(callerPublicKey, "submitS: not enough security deposit")
701745 else false)
702746 then _checkEventStatusForSubmitS(execChainId_, eventId_, "submitS: invalid event status")
703747 else false)
704748 then _notSubmittedS(execChainId_, eventId_, callerPublicKey, "submitS: already submitted")
705749 else false)
706750 then _submittedR(execChainId_, eventId_, callerPublicKey, "submitS: R is not submitted")
707751 else false
708752 if ((err == err))
709753 then {
710754 let sArray = _loadSsByEvent(execChainId_, eventId_)
711755 let signersArray = _loadSignersWithSByEvent(execChainId_, eventId_)
712756 let eventStatusActions = if (((size(sArray) + 1) == t))
713757 then {
714- let err1 = _validateString(sSigma_, "submitS: invalid s sigma")
758+ let err1 = if (_validateString(sSigma_, "submitS: invalid s sigma"))
759+ then _verifySignature(execChainId_, epoch, eventId_, rSigma_, sSigma_, "submitS: invalid signature")
760+ else false
715761 if ((err1 == err1))
716762 then {
717763 let executorIdxSize = _loadSignedEventExecutorIdxSize(execChainId_)
718764 let rewardAddresses = _publicKeysToAddrsStr((signersArray :+ callerPublicKey))
719765 let signersRewards = invoke(_loadRewardTokenAddress(), FUNC_MINT_MANY, [_loadRewardAmount(), rewardAddresses], nil)
720766 if ((signersRewards == signersRewards))
721767 then (((_saveEventStatus(execChainId_, eventId_, EVENT_STATUS_DONE) ++ _saveSignedEventExecutorIdx(execChainId_, executorIdxSize, eventId_)) ++ _saveSignedEventExecutorIdxSize(execChainId_, (executorIdxSize + 1))) ++ _saveSSigmaByEvent(execChainId_, eventId_, sSigma_))
722768 else throw("Strict value is not equal to itself.")
723769 }
724770 else throw("Strict value is not equal to itself.")
725771 }
726772 else nil
727773 $Tuple2(((((_saveSsByEvent(execChainId_, eventId_, (sArray :+ s_)) ++ _saveSByEventAndSigner(execChainId_, eventId_, callerPublicKey, s_)) ++ _saveSignersWithSByEvent(execChainId_, eventId_, (signersArray :+ callerPublicKey))) ++ _saveRSigmaByEvent(execChainId_, eventId_, rSigma_)) ++ eventStatusActions), unit)
728774 }
729775 else throw("Strict value is not equal to itself.")
730776 }
731777
732778
733779
734780 @Callable(i)
735781 func reset (eventId_,execChainId_,r_) = {
736782 let callerPublicKey = toBase58String(i.callerPublicKey)
737783 let epoch = _loadCurrentEpoch(execChainId_)
738784 let err = if (if (if (if (if (if (_whenInitialized())
739785 then _validateInt(eventId_, 0, MAX_INT, "reset: invalid eventId")
740786 else false)
741787 then _validateInt(execChainId_, 0, MAX_INT, "reset: invalid execChainId")
742788 else false)
743789 then _validateString(r_, "reset: invalid r")
744790 else false)
745791 then _isActiveSigner(callerPublicKey, _loadSigners(execChainId_, epoch), "reset: not active")
746792 else false)
747793 then _checkSecDepo(callerPublicKey, "reset: not enough security deposit")
748794 else false)
749795 then _checkEventStatusForReset(execChainId_, eventId_, "reset: invalid event status")
750796 else false
751797 if ((err == err))
752798 then {
753799 let slashAmount = 0
754800 let signersWithR = _loadSignersWithRByEvent(execChainId_, eventId_)
755801 let signersWithS = _loadSignersWithSByEvent(execChainId_, eventId_)
756802 let result = _slashIncorrect(signersWithR, signersWithS)
757803 let slashingActions = result._1
758804 let compensatedSigners = result._2
759805 let compensation = result._3
760806 let compensationActions = _compensateCorrect(compensatedSigners, compensation)
761807 $Tuple2((((((((((_saveEventStatus(execChainId_, eventId_, EVENT_STATUS_INIT) ++ _saveRsByEvent(execChainId_, eventId_, [r_])) ++ _saveRByEventAndSigner(execChainId_, eventId_, callerPublicKey, r_)) ++ _saveSignersWithRByEvent(execChainId_, eventId_, [callerPublicKey])) ++ _saveRSigmaByEvent(execChainId_, eventId_, "")) ++ _saveSsByEvent(execChainId_, eventId_, nil)) ++ _saveSignersWithSByEvent(execChainId_, eventId_, nil)) ++ _saveSSigmaByEvent(execChainId_, eventId_, "")) ++ slashingActions) ++ compensationActions), unit)
762808 }
763809 else throw("Strict value is not equal to itself.")
764810 }
765811
766812
767813
768814 @Callable(i)
769815 func addSecurityDeposit (recipient_) = {
770816 let recipient = if ((recipient_ == ""))
771817 then toString(i.caller)
772818 else recipient_
773819 let err = if (if (_validateAddress(recipient, "addSecurityDeposit: invalid recipient"))
774820 then _validatePaymentsSize(i.payments, 1, "addSecurityDeposit: no payment")
775821 else false)
776822 then _validatePaymentAsset(i.payments[0], unit, "addSecurityDeposit: invalid asset")
777823 else false
778824 if ((err == err))
779825 then {
780826 let recipientAddr = addressFromStringValue(recipient)
781827 let balance = _loadSecDepo(recipientAddr)
782828 let updatedBalance = (balance + i.payments[0].amount)
783829 $Tuple2(_saveSecDepo(recipientAddr, updatedBalance), unit)
784830 }
785831 else throw("Strict value is not equal to itself.")
786832 }
787833
788834
789835
790836 @Callable(i)
791837 func subSecurityDeposit (amount_) = {
792838 let balance = _loadSecDepo(i.caller)
793839 let err = if (_isZeroLock(toBase58String(i.callerPublicKey), "subSecurityDeposit: locked"))
794840 then if ((amount_ > balance))
795841 then throw("subSecurityDeposit: insufficient balance")
796842 else true
797843 else false
798844 if ((err == err))
799845 then $Tuple2((_saveSecDepo(i.caller, (balance - amount_)) ++ [ScriptTransfer(i.caller, amount_, unit)]), unit)
800846 else throw("Strict value is not equal to itself.")
801847 }
802848
803849
804850
805851 @Callable(i)
806852 func setMultisig (multisig_) = {
807853 let err = if (_onlyThisContract(i.caller))
808854 then _validateAddress(multisig_, "setMultisig: invalid multisig address")
809855 else false
810856 if ((err == err))
811857 then $Tuple2(_saveMultisig(addressFromStringValue(multisig_)), unit)
812858 else throw("Strict value is not equal to itself.")
813859 }
814860
815861
816862 @Verifier(tx)
817863 func verify () = match getString(KEY_MULTISIG) {
818864 case multisig: String =>
819865 valueOrElse(getBoolean(addressFromStringValue(multisig), makeString([KEY_STATUS, toString(this), toBase58String(tx.id)], SEPARATOR)), false)
820866 case _ =>
821867 sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
822868 }
823869

github/deemru/w8io/169f3d6 
105.86 ms