LyoKICogVkdBIGhhcmR3YXJlIGVtdWxhdGlvbgogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4gKHdpdGggc29tZSBoZWxwIGZyb20gTWFyY3VzIE1laXNzbmVyKQogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNkZWZpbmUgTk9OQU1FTEVTU1VOSU9OCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmNvbi5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJ2Z2EuaCIKI2luY2x1ZGUgImRkcmF3LmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkZHJhdyk7CgpzdGF0aWMgSURpcmVjdERyYXcgKmxwZGRyYXcgPSBOVUxMOwpzdGF0aWMgSURpcmVjdERyYXdTdXJmYWNlICpscGRkc3VyZjsKc3RhdGljIElEaXJlY3REcmF3UGFsZXR0ZSAqbHBkZHBhbDsKc3RhdGljIEREU1VSRkFDRURFU0Mgc2Rlc2M7CgpzdGF0aWMgQk9PTCB2Z2FfcmV0cmFjZV92ZXJ0aWNhbDsKc3RhdGljIEJPT0wgdmdhX3JldHJhY2VfaG9yaXpvbnRhbDsKCi8qCiAqIFNpemUgYW5kIGxvY2F0aW9uIG9mIFZHQSBjb250cm9sbGVyIHdpbmRvdyB0byBmcmFtZWJ1ZmZlci4KICoKICogTm90ZTogV2Ugc3VwcG9ydCBvbmx5IHNpbmdsZSB3aW5kb3cgZXZlbiB0aG91Z2ggc29tZQogKiAgICAgICBjb250cm9sbGVycyBzdXBwb3J0IHR3by4gVGhpcyBzaG91bGQgbm90IGJlIGNoYW5nZWQgdW5sZXNzCiAqICAgICAgIHRoZXJlIGFyZSBwcm9ncmFtcyB0aGF0IGRlcGVuZCBvbiBoYXZpbmcgdHdvIHdpbmRvd3MuCiAqLwojZGVmaW5lIFZHQV9XSU5ET1dfU0laRSAgKDY0ICogMTAyNCkKI2RlZmluZSBWR0FfV0lORE9XX1NUQVJUICgoY2hhciAqKTB4YTAwMDApCgovKgogKiBWR0EgY29udHJvbGxlciBtZW1vcnkgaXMgZW11bGF0ZWQgdXNpbmcgbGluZWFyIGZyYW1lYnVmZmVyLgogKiBUaGlzIGZyYW1idWZmZXIgYWxzbyBhY3RzIGFzIGFuIGludGVyZmFjZQogKiBiZXR3ZWVuIFZHQSBjb250cm9sbGVyIGVtdWxhdGlvbiBhbmQgRGlyZWN0RHJhdy4KICoKICogdmdhX2ZiX3dpZHRoOiBEaXNwbGF5IHdpZHRoIGluIHBpeGVscy4gQ2FuIGJlIG1vZGlmaWVkIHdoZW4KICogICAgICAgICAgICAgICBkaXNwbGF5IG1vZGUgaXMgY2hhbmdlZC4KICogdmdhX2ZiX2hlaWdodDogRGlzcGxheSBoZWlnaHQgaW4gcGl4ZWxzLiBDYW4gYmUgbW9kaWZpZWQgd2hlbgogKiAgICAgICAgICAgICAgICBkaXNwbGF5IG1vZGUgaXMgY2hhbmdlZC4KICogdmdhX2ZiX2RlcHRoOiBOdW1iZXIgb2YgYml0cyB1c2VkIHRvIHN0b3JlIHNpbmdsZSBwaXhlbCBjb2xvciBpbmZvcm1hdGlvbi4KICogICAgICAgICAgICAgICBFYWNoIHBpeGVsIHVzZXMgKHZnYV9mYl9kZXB0aCs3KS84IGJ5dGVzIGJlY2F1c2UKICogICAgICAgICAgICAgICAxLTE2IGNvbG9yIG1vZGVzIGFyZSBtYXBwZWQgdG8gMjU2IGNvbG9yIG1vZGUuCiAqICAgICAgICAgICAgICAgQ2FuIGJlIG1vZGlmaWVkIHdoZW4gZGlzcGxheSBtb2RlIGlzIGNoYW5nZWQuCiAqIHZnYV9mYl9waXRjaDogSG93IG1hbnkgYnl0ZXMgdG8gYWRkIHRvIHBvaW50ZXIgaW4gb3JkZXIgdG8gbW92ZQogKiAgICAgICAgICAgICAgIGZyb20gb25lIHJvdyB0byBhbm90aGVyLiBUaGlzIGlzIGZpeGVkIGluIFZHQSBtb2RlcywKICogICAgICAgICAgICAgICBidXQgY2FuIGJlIG1vZGlmaWVkIGluIFNWR0EgbW9kZXMuCiAqIHZnYV9mYl9vZmZzZXQ6IE9mZnNldCBhZGRlZCB0byBmcmFtZWJ1ZmZlciBzdGFydCBhZGRyZXNzIGluIG9yZGVyCiAqICAgICAgICAgICAgICAgIHRvIGZpbmQgdGhlIGRpc3BsYXkgb3JpZ2luLiBQcm9ncmFtcyB1c2UgdGhpcyB0byBkbwogKiAgICAgICAgICAgICAgICBkb3VibGUgYnVmZmVyaW5nIGFuZCB0byBzY3JvbGwgZGlzcGxheS4gVGhlIHZhbHVlIGNhbgogKiAgICAgICAgICAgICAgICBiZSBtb2RpZmllZCBpbiBWR0EgYW5kIFNWR0EgbW9kZXMuCiAqIHZnYV9mYl9zaXplOiBIb3cgbWFueSBieXRlcyBhcmUgYWxsb2NhdGVkIHRvIGZyYW1lYnVmZmVyLgogKiAgICAgICAgICAgICAgVkdBIGZyYW1lYnVmZmVycyBhcmUgYWx3YXlzIGxhcmdlciB0aGFuIGRpc3BsYXkgc2l6ZSBhbmQKICogICAgICAgICAgICAgIFNWR0EgZnJhbWVidWZmZXJzIG1heSBhbHNvIGJlLgogKiB2Z2FfZmJfZGF0YTogUG9pbnRlciB0byBmcmFtZWJ1ZmZlciBzdGFydC4KICogdmdhX2ZiX3dpbmRvdzogT2Zmc2V0IG9mIDY0ayB3aW5kb3cgMHhhMDAwMCBpbiBieXRlcyBmcm9tIGZyYW1lYnVmZmVyIHN0YXJ0LgogKiAgICAgICAgICAgICAgICBUaGlzIHZhbHVlIGlzID49IDAsIGlmIG1vZGUgdXNlcyBsaW5lYXIgZnJhbWVidWZmZXIgYW5kCiAqICAgICAgICAgICAgICAgIC0xLCBpZiBtb2RlIHVzZXMgY29sb3IgcGxhbmVzLiBUaGlzIHZhbHVlIGlzIGZpeGVkCiAqICAgICAgICAgICAgICAgIGluIGFsbCBtb2RlcyBleGNlcHQgMHgxMyAoMjU2IGNvbG9yIFZHQSkgd2hlcmUKICogICAgICAgICAgICAgICAgMCBtZWFucyBub3JtYWwgbW9kZSBhbmQgLTEgbWVhbnMgTW9kZS1YICh1bmNoYWluZWQgbW9kZSkuCiAqLwpzdGF0aWMgaW50ICAgdmdhX2ZiX3dpZHRoOwpzdGF0aWMgaW50ICAgdmdhX2ZiX2hlaWdodDsKc3RhdGljIGludCAgIHZnYV9mYl9kZXB0aDsKc3RhdGljIGludCAgIHZnYV9mYl9waXRjaDsKc3RhdGljIGludCAgIHZnYV9mYl9vZmZzZXQ7CnN0YXRpYyBpbnQgICB2Z2FfZmJfc2l6ZSA9IDA7CnN0YXRpYyBjaGFyICp2Z2FfZmJfZGF0YSA9IDA7CnN0YXRpYyBpbnQgICB2Z2FfZmJfd2luZG93ID0gMDsKCi8qCiAqIFZHQSB0ZXh0IG1vZGUgZGF0YS4KICoKICogdmdhX3RleHRfYXR0cjogQ3VycmVudCBhY3RpdmUgYXR0cmlidXRlLgogKiB2Z2FfdGV4dF9vbGQ6IExhc3QgZGF0YSBzZW50IHRvIGNvbnNvbGUuIAogKiAgICAgICAgICAgICAgIFRoaXMgaXMgdXNlZCB0byBvcHRpbWl6ZSBjb25zb2xlIHVwZGF0ZXMuCiAqIHZnYV90ZXh0X3dpZHRoOiAgV2lkdGggb2YgdGhlIHRleHQgZGlzcGxheSBpbiBjaGFyYWN0ZXJzLgogKiB2Z2FfdGV4dF9oZWlnaHQ6IEhlaWdodCBvZiB0aGUgdGV4dCBkaXNwbGF5IGluIGNoYXJhY3RlcnMuCiAqIHZnYV90ZXh0X3g6IEN1cnJlbnQgY3Vyc29yIFgtcG9zaXRpb24uIFN0YXJ0cyBmcm9tIHplcm8uCiAqIHZnYV90ZXh0X3k6IEN1cnJlbnQgY3Vyc29yIFktcG9zaXRpb24uIFN0YXJ0cyBmcm9tIHplcm8uCiAqIHZnYV90ZXh0X2NvbnNvbGU6IFRSVUUgaWYgc3Rkb3V0IGlzIGNvbnNvbGUsIAogKiAgICAgICAgICAgICAgICAgICBGQUxTRSBpZiBpdCBpcyByZWd1bGFyIGZpbGUuCiAqLwpzdGF0aWMgQllURSAgdmdhX3RleHRfYXR0cjsKc3RhdGljIGNoYXIgKnZnYV90ZXh0X29sZCA9IE5VTEw7CnN0YXRpYyBCWVRFICB2Z2FfdGV4dF93aWR0aDsKc3RhdGljIEJZVEUgIHZnYV90ZXh0X2hlaWdodDsKc3RhdGljIEJZVEUgIHZnYV90ZXh0X3g7CnN0YXRpYyBCWVRFICB2Z2FfdGV4dF95OwpzdGF0aWMgQk9PTCAgdmdhX3RleHRfY29uc29sZTsKCi8qCiAqIFZHQSBjb250cm9sbGVyIHBvcnRzIDB4M2MwLCAweDNjNCwgMHgzY2UgYW5kIDB4M2Q0IGFyZQogKiBpbmRleGVkIHJlZ2lzdGVycy4gVGhlc2UgcG9ydHMgYXJlIHVzZWQgdG8gc2VsZWN0IFZHQSBjb250cm9sbGVyCiAqIHN1YnJlZ2lzdGVyIHRoYXQgY2FuIGJlIHdyaXR0ZW4gdG8gb3IgcmVhZCBmcm9tIHVzaW5nIHBvcnRzIDB4M2MxLAogKiAweDNjNSwgMHgzY2Ygb3IgMHgzZDUuIFNlbGVjdGVkIHN1YnJlZ2lzdGVyIGluZGV4ZXMgYXJlCiAqIHN0b3JlZCBpbiB2YXJpYWJsZXMgdmdhX2luZGV4XyouCiAqCiAqIFBvcnQgMHgzYzAgaXMgc3BlY2lhbCBiZWNhdXNlIGl0IGlzIGJvdGggaW5kZXggYW5kCiAqIGRhdGEtd3JpdGUgcmVnaXN0ZXIuIEZsaXAtZmxvcCB2Z2FfYWRkcmVzc18zYzAgdGVsbHMgd2hldGhlcgogKiB0aGUgcG9ydCBhY3RzIGN1cnJlbnRseSBhcyBhbiBhZGRyZXNzIHJlZ2lzdGVyLiBSZWFkaW5nIGZyb20gcG9ydAogKiAweDNkYSByZXNldHMgdGhlIGZsaXAtZmxvcCB0byBhZGRyZXNzIG1vZGUuCiAqLwpzdGF0aWMgQllURSB2Z2FfaW5kZXhfM2MwOwpzdGF0aWMgQllURSB2Z2FfaW5kZXhfM2M0OwpzdGF0aWMgQllURSB2Z2FfaW5kZXhfM2NlOwpzdGF0aWMgQllURSB2Z2FfaW5kZXhfM2Q0OwpzdGF0aWMgQk9PTCB2Z2FfYWRkcmVzc18zYzAgPSBUUlVFOwoKLyoKICogVGhpcyBtdXRleCBpcyB1c2VkIHRvIHByb3RlY3QgVkdBIHN0YXRlIGR1cmluZyBhc3luY2hyb25vdXMKICogc2NyZWVuIHVwZGF0ZXMgKHNlZSBWR0FfUG9sbCkuIEl0IG1ha2VzIHN1cmUgdGhhdCBWR0Egc3RhdGUgY2hhbmdlcwogKiBhcmUgYXRvbWljIGFuZCB0aGUgdXNlciBpbnRlcmZhY2UgaXMgcHJvdGVjdGVkIGZyb20gZmxpY2tlciBhbmQKICogY29ycnVwdGlvbi4KICoKICogVGhlIG11dGV4IGFjdHVhbGx5IHNlcmlhbGl6ZXMgVkdBIG9wZXJhdGlvbnMgYW5kIHRoZSBzY3JlZW4gdXBkYXRlLiAKICogV2hpY2ggbWVhbnMgdGhhdCB3aGVuZXZlciBWR0FfUG9sbCBvY2N1cnMsIGFwcGxpY2F0aW9uIHN0YWxscyBpZiBpdCAKICogdHJpZXMgdG8gbW9kaWZ5IFZHQSBzdGF0ZS4gVGhpcyBpcyBub3QgaG93IHJlYWwgVkdBIGFkYXB0ZXJzIHdvcmssCiAqIGJ1dCBpdCBtYWtlcyB0aW1pbmcgYW5kIGNvcnJlY3RuZXNzIGlzc3VlcyBtdWNoIGVhc2llciB0byBkZWFsIHdpdGguCiAqLwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiB2Z2FfbG9jazsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT05fREVCVUcgY3JpdHNlY3RfZGVidWcgPQp7CiAgICAwLCAwLCAmdmdhX2xvY2ssCiAgICB7ICZjcml0c2VjdF9kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LCAmY3JpdHNlY3RfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCB9LAogICAgICAwLCAwLCB7IDAsIChEV09SRCkoX19GSUxFX18gIjogdmdhX2xvY2siKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIHZnYV9sb2NrID0geyAmY3JpdHNlY3RfZGVidWcsIC0xLCAwLCAwLCAwLCAwIH07Cgp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqRGlyZWN0RHJhd0NyZWF0ZVByb2MpKExQR1VJRCxMUERJUkVDVERSQVcgKixMUFVOS05PV04pOwpzdGF0aWMgRGlyZWN0RHJhd0NyZWF0ZVByb2MgcERpcmVjdERyYXdDcmVhdGU7CgpzdGF0aWMgdm9pZCBDQUxMQkFDSyBWR0FfUG9sbCggTFBWT0lEIGFyZywgRFdPUkQgbG93LCBEV09SRCBoaWdoICk7CgpzdGF0aWMgSFdORCB2Z2FfaHduZCA9IE5VTEw7CgovKgogKiBGb3Igc2ltcGxpY2l0eSwgSSdtIGNyZWF0aW5nIGEgc2Vjb25kIHBhbGV0dGUuCiAqIDE2IGNvbG9yIGFjY2Vzc2VzIHdpbGwgdXNlIHRoZXNlIHBvaW50ZXJzIGFuZCBpbnNlcnQKICogZW50cmllcyBmcm9tIHRoZSA2NC1jb2xvciBwYWxldHRlIGludG8gdGhlIGRlZmF1bHQKICogcGFsZXR0ZS4gICAtLVJvYmVydCAnQWRtaXJhbCcgQ29leW1hbgogKi8KCnN0YXRpYyBjaGFyIHZnYV8xNl9wYWxldHRlWzE3XT17CiAgMHgwMCwgIC8qIDAgLSBCbGFjayAgICAgICAgICovCiAgMHgwMSwgIC8qIDEgLSBCbHVlICAgICAgICAgICovCiAgMHgwMiwgIC8qIDIgLSBHcmVlbiAgICAgICAgICovCiAgMHgwMywgIC8qIDMgLSBDeWFuICAgICAgICAgICovCiAgMHgwNCwgIC8qIDQgLSBSZWQgICAgICAgICAgICovCiAgMHgwNSwgIC8qIDUgLSBNYWdlbnRhICAgICAgICovCiAgMHgxNCwgIC8qIDYgLSBCcm93biAgICAgICAgICovCiAgMHgwNywgIC8qIDcgLSBMaWdodCBncmF5ICAgICovCiAgMHgzOCwgIC8qIDggLSBEYXJrIGdyYXkgICAgICovCiAgMHgzOSwgIC8qIDkgLSBMaWdodCBibHVlICAgICovCiAgMHgzYSwgIC8qIEEgLSBMaWdodCBncmVlbiAgICovCiAgMHgzYiwgIC8qIEIgLSBMaWdodCBjeWFuICAgICovCiAgMHgzYywgIC8qIEMgLSBMaWdodCByZWQgICAgICovCiAgMHgzZCwgIC8qIEQgLSBMaWdodCBtYWdlbnRhICovCiAgMHgzZSwgIC8qIEUgLSBZZWxsb3cgICAgICAgICovCiAgMHgzZiwgIC8qIEYgLSBXaGl0ZSAgICAgICAgICovCiAgMHgwMCAgIC8qIEJvcmRlciBDb2xvciAgICAgICovCn07CgpzdGF0aWMgUEFMRVRURUVOVFJZIHZnYV9kZWZfcGFsZXR0ZVsyNTZdPXsKLyogcmVkICBncmVlbiAgYmx1ZSAqLwogIHsweDAwLCAweDAwLCAweDAwfSwgLyogMCAtIEJsYWNrICovCiAgezB4MDAsIDB4MDAsIDB4ODB9LCAvKiAxIC0gQmx1ZSAqLwogIHsweDAwLCAweDgwLCAweDAwfSwgLyogMiAtIEdyZWVuICovCiAgezB4MDAsIDB4ODAsIDB4ODB9LCAvKiAzIC0gQ3lhbiAqLwogIHsweDgwLCAweDAwLCAweDAwfSwgLyogNCAtIFJlZCAqLwogIHsweDgwLCAweDAwLCAweDgwfSwgLyogNSAtIE1hZ2VudGEgKi8KICB7MHg4MCwgMHg4MCwgMHgwMH0sIC8qIDYgLSBCcm93biAqLwogIHsweEMwLCAweEMwLCAweEMwfSwgLyogNyAtIExpZ2h0IGdyYXkgKi8KICB7MHg4MCwgMHg4MCwgMHg4MH0sIC8qIDggLSBEYXJrIGdyYXkgKi8KICB7MHgwMCwgMHgwMCwgMHhGRn0sIC8qIDkgLSBMaWdodCBibHVlICovCiAgezB4MDAsIDB4RkYsIDB4MDB9LCAvKiBBIC0gTGlnaHQgZ3JlZW4gKi8KICB7MHgwMCwgMHhGRiwgMHhGRn0sIC8qIEIgLSBMaWdodCBjeWFuICovCiAgezB4RkYsIDB4MDAsIDB4MDB9LCAvKiBDIC0gTGlnaHQgcmVkICovCiAgezB4RkYsIDB4MDAsIDB4RkZ9LCAvKiBEIC0gTGlnaHQgbWFnZW50YSAqLwogIHsweEZGLCAweEZGLCAweDAwfSwgLyogRSAtIFllbGxvdyAqLwogIHsweEZGLCAweEZGLCAweEZGfSwgLyogRiAtIFdoaXRlICovCiAgezAsMCwwfSAvKiBGSVhNRTogYSBzZXJpZXMgb2YgY29udGludW91cyByYWluYm93IGh1ZXMgc2hvdWxkIGZvbGxvdyAqLwp9OwoKLyoKICogICBUaGlzIHBhbGV0dGUgaXMgdGhlIGRvcyBkZWZhdWx0LCBjb252ZXJ0ZWQgZnJvbSAxOCBiaXQgY29sb3IgdG8gMjQuCiAqICAgICAgSXQgY29udGFpbnMgb25seSA2NCBlbnRyaWVzIG9mIGNvbG9ycy0tYWxsIG90aGVycyBhcmUgemVyb3MuCiAqICAgICAgICAgIC0tUm9iZXJ0ICdBZG1pcmFsJyBDb2V5bWFuCiAqLwpzdGF0aWMgUEFMRVRURUVOVFJZIHZnYV9kZWY2NF9wYWxldHRlWzI1Nl09ewovKiByZWQgIGdyZWVuICBibHVlICovCiAgezB4MDAsIDB4MDAsIDB4MDB9LCAvKiAweDAwICAgICAgQmxhY2sgICAgICAqLwogIHsweDAwLCAweDAwLCAweGFhfSwgLyogMHgwMSAgICAgIEJsdWUgICAgICAgKi8KICB7MHgwMCwgMHhhYSwgMHgwMH0sIC8qIDB4MDIgICAgICBHcmVlbiAgICAgICovCiAgezB4MDAsIDB4YWEsIDB4YWF9LCAvKiAweDAzICAgICAgQ3lhbiAgICAgICAqLwogIHsweGFhLCAweDAwLCAweDAwfSwgLyogMHgwNCAgICAgIFJlZCAgICAgICAgKi8KICB7MHhhYSwgMHgwMCwgMHhhYX0sIC8qIDB4MDUgICAgICBNYWdlbnRhICAgICovCiAgezB4YWEsIDB4YWEsIDB4MDB9LCAvKiAweDA2ICAgICAgKi8KICB7MHhhYSwgMHhhYSwgMHhhYX0sIC8qIDB4MDcgICAgICBMaWdodCBHcmF5ICovCiAgezB4MDAsIDB4MDAsIDB4NTV9LCAvKiAweDA4ICAgICAgKi8KICB7MHgwMCwgMHgwMCwgMHhmZn0sIC8qIDB4MDkgICAgICAqLwogIHsweDAwLCAweGFhLCAweDU1fSwgLyogMHgwYSAgICAgICovCiAgezB4MDAsIDB4YWEsIDB4ZmZ9LCAvKiAweDBiICAgICAgKi8KICB7MHhhYSwgMHgwMCwgMHg1NX0sIC8qIDB4MGMgICAgICAqLwogIHsweGFhLCAweDAwLCAweGZmfSwgLyogMHgwZCAgICAgICovCiAgezB4YWEsIDB4YWEsIDB4NTV9LCAvKiAweDBlICAgICAgKi8KICB7MHhhYSwgMHhhYSwgMHhmZn0sIC8qIDB4MGYgICAgICAqLwogIHsweDAwLCAweDU1LCAweDAwfSwgLyogMHgxMCAgICAgICovCiAgezB4MDAsIDB4NTUsIDB4YWF9LCAvKiAweDExICAgICAgKi8KICB7MHgwMCwgMHhmZiwgMHgwMH0sIC8qIDB4MTIgICAgICAqLwogIHsweDAwLCAweGZmLCAweGFhfSwgLyogMHgxMyAgICAgICovCiAgezB4YWEsIDB4NTUsIDB4MDB9LCAvKiAweDE0ICAgICAgQnJvd24gICAgICAqLwogIHsweGFhLCAweDU1LCAweGFhfSwgLyogMHgxNSAgICAgICovCiAgezB4YWEsIDB4ZmYsIDB4MDB9LCAvKiAweDE2ICAgICAgKi8KICB7MHhhYSwgMHhmZiwgMHhhYX0sIC8qIDB4MTcgICAgICAqLwogIHsweDAwLCAweDU1LCAweDU1fSwgLyogMHgxOCAgICAgICovCiAgezB4MDAsIDB4NTUsIDB4ZmZ9LCAvKiAweDE5ICAgICAgKi8KICB7MHgwMCwgMHhmZiwgMHg1NX0sIC8qIDB4MWEgICAgICAqLwogIHsweDAwLCAweGZmLCAweGZmfSwgLyogMHgxYiAgICAgICovCiAgezB4YWEsIDB4NTUsIDB4NTV9LCAvKiAweDFjICAgICAgKi8KICB7MHhhYSwgMHg1NSwgMHhmZn0sIC8qIDB4MWQgICAgICAqLwogIHsweGFhLCAweGZmLCAweDU1fSwgLyogMHgxZSAgICAgICovCiAgezB4YWEsIDB4ZmYsIDB4ZmZ9LCAvKiAweDFmICAgICAgKi8KICB7MHg1NSwgMHgwMCwgMHgwMH0sIC8qIDB4MjAgICAgICAqLwogIHsweDU1LCAweDAwLCAweGFhfSwgLyogMHgyMSAgICAgICovCiAgezB4NTUsIDB4YWEsIDB4MDB9LCAvKiAweDIyICAgICAgKi8KICB7MHg1NSwgMHhhYSwgMHhhYX0sIC8qIDB4MjMgICAgICAqLwogIHsweGZmLCAweDAwLCAweDAwfSwgLyogMHgyNCAgICAgICovCiAgezB4ZmYsIDB4MDAsIDB4YWF9LCAvKiAweDI1ICAgICAgKi8KICB7MHhmZiwgMHhhYSwgMHgwMH0sIC8qIDB4MjYgICAgICAqLwogIHsweGZmLCAweGFhLCAweGFhfSwgLyogMHgyNyAgICAgICovCiAgezB4NTUsIDB4MDAsIDB4NTV9LCAvKiAweDI4ICAgICAgKi8KICB7MHg1NSwgMHgwMCwgMHhmZn0sIC8qIDB4MjkgICAgICAqLwogIHsweDU1LCAweGFhLCAweDU1fSwgLyogMHgyYSAgICAgICovCiAgezB4NTUsIDB4YWEsIDB4ZmZ9LCAvKiAweDJiICAgICAgKi8KICB7MHhmZiwgMHgwMCwgMHg1NX0sIC8qIDB4MmMgICAgICAqLwogIHsweGZmLCAweDAwLCAweGZmfSwgLyogMHgyZCAgICAgICovCiAgezB4ZmYsIDB4YWEsIDB4NTV9LCAvKiAweDJlICAgICAgKi8KICB7MHhmZiwgMHhhYSwgMHhmZn0sIC8qIDB4MmYgICAgICAqLwogIHsweDU1LCAweDU1LCAweDAwfSwgLyogMHgzMCAgICAgICovCiAgezB4NTUsIDB4NTUsIDB4YWF9LCAvKiAweDMxICAgICAgKi8KICB7MHg1NSwgMHhmZiwgMHgwMH0sIC8qIDB4MzIgICAgICAqLwogIHsweDU1LCAweGZmLCAweGFhfSwgLyogMHgzMyAgICAgICovCiAgezB4ZmYsIDB4NTUsIDB4MDB9LCAvKiAweDM0ICAgICAgKi8KICB7MHhmZiwgMHg1NSwgMHhhYX0sIC8qIDB4MzUgICAgICAqLwogIHsweGZmLCAweGZmLCAweDAwfSwgLyogMHgzNiAgICAgICovCiAgezB4ZmYsIDB4ZmYsIDB4YWF9LCAvKiAweDM3ICAgICAgKi8KICB7MHg1NSwgMHg1NSwgMHg1NX0sIC8qIDB4MzggICAgICBEYXJrIEdyYXkgICAgICovCiAgezB4NTUsIDB4NTUsIDB4ZmZ9LCAvKiAweDM5ICAgICAgTGlnaHQgQmx1ZSAgICAqLwogIHsweDU1LCAweGZmLCAweDU1fSwgLyogMHgzYSAgICAgIExpZ2h0IEdyZWVuICAgKi8KICB7MHg1NSwgMHhmZiwgMHhmZn0sIC8qIDB4M2IgICAgICBMaWdodCBDeWFuICAgICovCiAgezB4ZmYsIDB4NTUsIDB4NTV9LCAvKiAweDNjICAgICAgTGlnaHQgUmVkICAgICAqLwogIHsweGZmLCAweDU1LCAweGZmfSwgLyogMHgzZCAgICAgIExpZ2h0IE1hZ2VudGEgKi8KICB7MHhmZiwgMHhmZiwgMHg1NX0sIC8qIDB4M2UgICAgICBZZWxsb3cgICAgICAgICovCiAgezB4ZmYsIDB4ZmYsIDB4ZmZ9LCAvKiAweDNmICAgICAgV2hpdGUgICAgICAgICAqLwogIHswLDAsMH0gLyogVGhlIG5leHQgMTkyIGVudHJpZXMgYXJlIGFsbCB6ZXJvcyAgKi8KfTsKCnN0YXRpYyBIQU5ETEUgVkdBX3RpbWVyOwpzdGF0aWMgSEFORExFIFZHQV90aW1lcl90aHJlYWQ7CgovKiBzZXQgdGhlIHRpbWVyIHJhdGU7IGNhbGxlZCBpbiB0aGUgcG9sbGluZyB0aHJlYWQgY29udGV4dCAqLwpzdGF0aWMgdm9pZCBDQUxMQkFDSyBzZXRfdGltZXJfcmF0ZSggVUxPTkdfUFRSIGFyZyApCnsKICAgIExBUkdFX0lOVEVHRVIgd2hlbjsKCiAgICB3aGVuLnUuTG93UGFydCA9IHdoZW4udS5IaWdoUGFydCA9IDA7CiAgICBTZXRXYWl0YWJsZVRpbWVyKCBWR0FfdGltZXIsICZ3aGVuLCBhcmcsIFZHQV9Qb2xsLCAwLCBGQUxTRSApOwp9CgpzdGF0aWMgRFdPUkQgQ0FMTEJBQ0sgVkdBX1RpbWVyVGhyZWFkKCB2b2lkICpkdW1teSApCnsKICAgIGZvciAoOzspIFNsZWVwRXgoIElORklOSVRFLCBUUlVFICk7Cn0KCnN0YXRpYyB2b2lkIFZHQV9EZWluc3RhbGxUaW1lcih2b2lkKQp7CiAgICBpZiAoVkdBX3RpbWVyX3RocmVhZCkKICAgIHsKICAgICAgICAvKgogICAgICAgICAqIE1ha2Ugc3VyZSB0aGUgdXBkYXRlIHRocmVhZCBpcyBub3QgaG9sZGluZwogICAgICAgICAqIHN5c3RlbSByZXNvdXJjZXMgd2hlbiB3ZSBraWxsIGl0LgogICAgICAgICAqCiAgICAgICAgICogTm93LCB3ZSBvbmx5IG5lZWQgdG8gd29ycnkgYWJvdXQgdXBkYXRlIHRocmVhZAogICAgICAgICAqIGdldHRpbmcgdGVybWluYXRlZCB3aGlsZSBpbiBFbnRlckNyaXRpY2FsU2VjdGlvbiAKICAgICAgICAgKiBvciBXYWl0Rm9yTXVsdGlwbGVPYmplY3RzRXguCiAgICAgICAgICoKICAgICAgICAgKiBGSVhNRTogSXMgdGhpcyBhIHByb2JsZW0/CiAgICAgICAgICovCiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKCiAgICAgICAgQ2FuY2VsV2FpdGFibGVUaW1lciggVkdBX3RpbWVyICk7CiAgICAgICAgQ2xvc2VIYW5kbGUoIFZHQV90aW1lciApOwogICAgICAgIFRlcm1pbmF0ZVRocmVhZCggVkdBX3RpbWVyX3RocmVhZCwgMCApOwogICAgICAgIENsb3NlSGFuZGxlKCBWR0FfdGltZXJfdGhyZWFkICk7CiAgICAgICAgVkdBX3RpbWVyX3RocmVhZCA9IDA7CgogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7CgogICAgICAgIC8qCiAgICAgICAgICogU3luY2hyb25pemUgZGlzcGxheS4gVGhpcyBtYWtlcyBzdXJlIHRoYXQKICAgICAgICAgKiBjaGFuZ2VzIHRvIGRpc3BsYXkgYmVjb21lIHZpc2libGUgZXZlbiBpZiBwcm9ncmFtIAogICAgICAgICAqIHRlcm1pbmF0ZXMgYmVmb3JlIHVwZGF0ZSB0aHJlYWQgaGFkIHRpbWUgdG8gcnVuLgogICAgICAgICAqLwogICAgICAgIFZHQV9Qb2xsKCAwLCAwLCAwICk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIFZHQV9JbnN0YWxsVGltZXIodW5zaWduZWQgUmF0ZSkKewogICAgaWYgKCFWR0FfdGltZXJfdGhyZWFkKQogICAgewogICAgICAgIFZHQV90aW1lciA9IENyZWF0ZVdhaXRhYmxlVGltZXJBKCBOVUxMLCBGQUxTRSwgTlVMTCApOwogICAgICAgIFZHQV90aW1lcl90aHJlYWQgPSBDcmVhdGVUaHJlYWQoIE5VTEwsIDAsIFZHQV9UaW1lclRocmVhZCwgTlVMTCwgMCwgTlVMTCApOwogICAgfQogICAgUXVldWVVc2VyQVBDKCBzZXRfdGltZXJfcmF0ZSwgVkdBX3RpbWVyX3RocmVhZCwgKFVMT05HX1BUUilSYXRlICk7Cn0KCnN0YXRpYyBCT09MIFZHQV9Jc1RpbWVyUnVubmluZyh2b2lkKQp7CiAgICByZXR1cm4gVkdBX3RpbWVyX3RocmVhZCA/IFRSVUUgOiBGQUxTRTsKfQoKSEFORExFIFZHQV9BbHBoYUNvbnNvbGUodm9pZCkKewogICAgLyogdGhpcyBhc3N1bWVzIHRoYXQgbm8gV2luMzIgcmVkaXJlY3Rpb24gaGFzIHRha2VuIHBsYWNlLCBidXQgdGhlbiBhZ2FpbiwKICAgICAqIG9ubHkgMTYtYml0IGFwcHMgYXJlIGxpa2VseSB0byB1c2UgdGhpcyBwYXJ0IG9mIFdpbmUuLi4gKi8KICAgIHJldHVybiBHZXRTdGRIYW5kbGUoU1REX09VVFBVVF9IQU5ETEUpOwp9CgpjaGFyKlZHQV9BbHBoYUJ1ZmZlcih2b2lkKQp7CiAgICByZXR1cm4gKGNoYXIgKikweGI4MDAwOwp9CgovKioqIEdSQVBISUNTIE1PREUgKioqLwoKdHlwZWRlZiBzdHJ1Y3QgewogIHVuc2lnbmVkIFhyZXMsIFlyZXMsIERlcHRoOwogIGludCByZXQ7Cn0gTW9kZVNldDsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgIFZHQV9TeW5jV2luZG93CiAqCiAqIENvcHkgVkdBIHdpbmRvdyBpbnRvIGZyYW1lYnVmZmVyIChpZiBhcmd1bWVudCBpcyBUUlVFKSBvcgogKiBwYXJ0IG9mIGZyYW1lYnVmZmVyIGludG8gVkdBIHdpbmRvdyAoaWYgYXJndW1lbnQgaXMgRkFMU0UpLgogKi8Kc3RhdGljIHZvaWQgVkdBX1N5bmNXaW5kb3coIEJPT0wgdGFyZ2V0X2lzX2ZiICkKewogICAgaW50IHNpemUgPSBWR0FfV0lORE9XX1NJWkU7CgogICAgLyogV2luZG93IGRvZXMgbm90IG92ZXJsYXAgZnJhbWVidWZmZXIuICovCiAgICBpZiAodmdhX2ZiX3dpbmRvdyA+PSB2Z2FfZmJfc2l6ZSkKICAgICAgICByZXR1cm47CgogICAgLyogQ2hlY2sgaWYgd2luZG93IG92ZXJsYXBzIGZyYW1lYnVmZmVyIG9ubHkgcGFydGlhbGx5LiAqLwogICAgaWYgKHZnYV9mYl9zaXplIC0gdmdhX2ZiX3dpbmRvdyA8IFZHQV9XSU5ET1dfU0laRSkKICAgICAgICBzaXplID0gdmdhX2ZiX3NpemUgLSB2Z2FfZmJfd2luZG93OwoKICAgIGlmICh0YXJnZXRfaXNfZmIpCiAgICAgICAgbWVtbW92ZSggdmdhX2ZiX2RhdGEgKyB2Z2FfZmJfd2luZG93LCBWR0FfV0lORE9XX1NUQVJULCBzaXplICk7CiAgICBlbHNlCiAgICAgICAgbWVtbW92ZSggVkdBX1dJTkRPV19TVEFSVCwgdmdhX2ZiX2RhdGEgKyB2Z2FfZmJfd2luZG93LCBzaXplICk7Cn0KCgpzdGF0aWMgdm9pZCBXSU5BUEkgVkdBX0RvRXhpdChVTE9OR19QVFIgYXJnKQp7CiAgICBWR0FfRGVpbnN0YWxsVGltZXIoKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZV9TZXRQYWxldHRlKGxwZGRzdXJmLE5VTEwpOwogICAgSURpcmVjdERyYXdTdXJmYWNlX1JlbGVhc2UobHBkZHN1cmYpOwogICAgbHBkZHN1cmY9TlVMTDsKICAgIElEaXJlY3REcmF3UGFsZXR0ZV9SZWxlYXNlKGxwZGRwYWwpOwogICAgbHBkZHBhbD1OVUxMOwogICAgSURpcmVjdERyYXdfUmVsZWFzZShscGRkcmF3KTsKICAgIGxwZGRyYXc9TlVMTDsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIFZHQV9Eb1NldE1vZGUoVUxPTkdfUFRSIGFyZykKewogICAgTFJFU1VMVAlyZXM7CiAgICBNb2RlU2V0ICpwYXIgPSAoTW9kZVNldCAqKWFyZzsKICAgIHBhci0+cmV0PTE7CgogICAgaWYgKGxwZGRyYXcpIFZHQV9Eb0V4aXQoMCk7CiAgICBpZiAoIWxwZGRyYXcpIHsKICAgICAgICBpZiAoIXBEaXJlY3REcmF3Q3JlYXRlKQogICAgICAgIHsKICAgICAgICAgICAgSE1PRFVMRSBobW9kID0gTG9hZExpYnJhcnlBKCAiZGRyYXcuZGxsIiApOwogICAgICAgICAgICBpZiAoaG1vZCkgcERpcmVjdERyYXdDcmVhdGUgPSAoRGlyZWN0RHJhd0NyZWF0ZVByb2MpR2V0UHJvY0FkZHJlc3MoIGhtb2QsICJEaXJlY3REcmF3Q3JlYXRlIiApOwoJICAgIGlmICghcERpcmVjdERyYXdDcmVhdGUpIHsKCQlFUlIoIkNhbid0IGxvb2t1cCBEaXJlY3REcmF3Q3JlYXRlIGZyb20gZGRyYXcuZGxsLlxuIik7CgkJcmV0dXJuOwoJICAgIH0KICAgICAgICB9CiAgICAgICAgcmVzID0gcERpcmVjdERyYXdDcmVhdGUoTlVMTCwmbHBkZHJhdyxOVUxMKTsKICAgICAgICBpZiAoIWxwZGRyYXcpIHsKICAgICAgICAgICAgRVJSKCJEaXJlY3REcmF3IGlzIG5vdCBhdmFpbGFibGUgKHJlcyA9ICVseClcbiIscmVzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZiAoIXZnYV9od25kKSB7CiAgICAgICAgICAgIHZnYV9od25kID0gQ3JlYXRlV2luZG93RXhBKDAsIlNUQVRJQyIsIldJTkVET1MgVkdBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1NfUE9QVVB8V1NfVklTSUJMRXxTU19OT1RJRlksMCwwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXItPlhyZXMscGFyLT5ZcmVzLDAsMCwwLE5VTEwpOwogICAgICAgICAgICBpZiAoIXZnYV9od25kKSB7CiAgICAgICAgICAgICAgICBFUlIoIkZhaWxlZCB0byBjcmVhdGUgdXNlciB3aW5kb3cuXG4iKTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3X1JlbGVhc2UobHBkZHJhdyk7CiAgICAgICAgICAgICAgICBscGRkcmF3PU5VTEw7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBTZXRXaW5kb3dQb3ModmdhX2h3bmQsMCwwLDAscGFyLT5YcmVzLHBhci0+WXJlcyxTV1BfTk9NT1ZFfFNXUF9OT1pPUkRFUik7CgogICAgICAgIGlmICgocmVzPUlEaXJlY3REcmF3X1NldENvb3BlcmF0aXZlTGV2ZWwobHBkZHJhdyx2Z2FfaHduZCxERFNDTF9GVUxMU0NSRUVOfEREU0NMX0VYQ0xVU0lWRSkpKSB7CgkgICAgRVJSKCJDb3VsZCBub3Qgc2V0IGNvb3BlcmF0aXZlIGxldmVsIHRvIGV4Y2x1c2l2ZSAoJWx4KVxuIixyZXMpOwoJfQoKICAgICAgICBpZiAoKHJlcz1JRGlyZWN0RHJhd19TZXREaXNwbGF5TW9kZShscGRkcmF3LHBhci0+WHJlcyxwYXItPllyZXMscGFyLT5EZXB0aCkpKSB7CiAgICAgICAgICAgIEVSUigiRGlyZWN0RHJhdyBkb2VzIG5vdCBzdXBwb3J0IHJlcXVlc3RlZCBkaXNwbGF5IG1vZGUgKCVkeCVkeCVkKSwgcmVzID0gJWx4IVxuIixwYXItPlhyZXMscGFyLT5ZcmVzLHBhci0+RGVwdGgscmVzKTsKICAgICAgICAgICAgSURpcmVjdERyYXdfUmVsZWFzZShscGRkcmF3KTsKICAgICAgICAgICAgbHBkZHJhdz1OVUxMOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICByZXM9SURpcmVjdERyYXdfQ3JlYXRlUGFsZXR0ZShscGRkcmF3LEREUENBUFNfOEJJVCxOVUxMLCZscGRkcGFsLE5VTEwpOwogICAgICAgIGlmIChyZXMpIHsKCSAgICBFUlIoIkNvdWxkIG5vdCBjcmVhdGUgcGFsZXR0ZSAocmVzID0gJWx4KVxuIixyZXMpOwogICAgICAgICAgICBJRGlyZWN0RHJhd19SZWxlYXNlKGxwZGRyYXcpOwogICAgICAgICAgICBscGRkcmF3PU5VTEw7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKChyZXM9SURpcmVjdERyYXdQYWxldHRlX1NldEVudHJpZXMobHBkZHBhbCwwLDAsMjU2LHZnYV9kZWZfcGFsZXR0ZSkpKSB7CiAgICAgICAgICAgIEVSUigiQ291bGQgbm90IHNldCBkZWZhdWx0IHBhbGV0dGUgZW50cmllcyAocmVzID0gJWx4KVxuIiwgcmVzKTsKICAgICAgICB9CgogICAgICAgIG1lbXNldCgmc2Rlc2MsMCxzaXplb2Yoc2Rlc2MpKTsKICAgICAgICBzZGVzYy5kd1NpemU9c2l6ZW9mKHNkZXNjKTsKCXNkZXNjLmR3RmxhZ3MgPSBERFNEX0NBUFM7CglzZGVzYy5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfUFJJTUFSWVNVUkZBQ0U7CiAgICAgICAgaWYgKElEaXJlY3REcmF3X0NyZWF0ZVN1cmZhY2UobHBkZHJhdywmc2Rlc2MsJmxwZGRzdXJmLE5VTEwpfHwoIWxwZGRzdXJmKSkgewogICAgICAgICAgICBFUlIoIkRpcmVjdERyYXcgc3VyZmFjZSBpcyBub3QgYXZhaWxhYmxlXG4iKTsKICAgICAgICAgICAgSURpcmVjdERyYXdfUmVsZWFzZShscGRkcmF3KTsKICAgICAgICAgICAgbHBkZHJhdz1OVUxMOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZV9TZXRQYWxldHRlKGxwZGRzdXJmLGxwZGRwYWwpOwogICAgICAgIHZnYV9yZXRyYWNlX3ZlcnRpY2FsID0gdmdhX3JldHJhY2VfaG9yaXpvbnRhbCA9IEZBTFNFOwogICAgICAgIC8qIHBvbGwgZXZlcnkgMjBtcyAoNTBmcHMgc2hvdWxkIHByb3ZpZGUgYWRlcXVhdGUgcmVzcG9uc2l2ZW5lc3MpICovCiAgICAgICAgVkdBX0luc3RhbGxUaW1lcigyMCk7CiAgICB9CiAgICBwYXItPnJldD0wOwogICAgcmV0dXJuOwp9CgppbnQgVkdBX1NldE1vZGUodW5zaWduZWQgWHJlcyx1bnNpZ25lZCBZcmVzLHVuc2lnbmVkIERlcHRoKQp7CiAgICBNb2RlU2V0IHBhcjsKICAgIGludCAgICAgbmV3U2l6ZTsKCiAgICB2Z2FfZmJfd2lkdGggPSBYcmVzOwogICAgdmdhX2ZiX2hlaWdodCA9IFlyZXM7CiAgICB2Z2FfZmJfZGVwdGggPSBEZXB0aDsKICAgIHZnYV9mYl9vZmZzZXQgPSAwOwogICAgdmdhX2ZiX3BpdGNoID0gWHJlcyAqICgoRGVwdGggKyA3KSAvIDgpOwoKICAgIG5ld1NpemUgPSBYcmVzICogWXJlcyAqICgoRGVwdGggKyA3KSAvIDgpOwogICAgaWYobmV3U2l6ZSA8IDI1NiAqIDEwMjQpCiAgICAgIG5ld1NpemUgPSAyNTYgKiAxMDI0OwoKICAgIGlmKHZnYV9mYl9zaXplIDwgbmV3U2l6ZSkgewogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCB2Z2FfZmJfZGF0YSk7CiAgICAgIHZnYV9mYl9kYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIG5ld1NpemUpOwogICAgICB2Z2FfZmJfc2l6ZSA9IG5ld1NpemU7CiAgICB9CgogICAgaWYoWHJlcyA+PSA2NDAgfHwgWXJlcyA+PSA0ODApIHsKICAgICAgcGFyLlhyZXMgPSBYcmVzOwogICAgICBwYXIuWXJlcyA9IFlyZXM7CiAgICB9IGVsc2UgewogICAgICBwYXIuWHJlcyA9IDY0MDsKICAgICAgcGFyLllyZXMgPSA0ODA7CiAgICB9CgogICAgVkdBX1NldFdpbmRvd1N0YXJ0KChEZXB0aCA8IDgpID8gLTEgOiAwKTsKCiAgICBwYXIuRGVwdGggPSAoRGVwdGggPCA4KSA/IDggOiBEZXB0aDsKCiAgICBNWl9SdW5JblRocmVhZChWR0FfRG9TZXRNb2RlLCAoVUxPTkdfUFRSKSZwYXIpOwogICAgcmV0dXJuIHBhci5yZXQ7Cn0KCmludCBWR0FfR2V0TW9kZSh1bnNpZ25lZCpIZWlnaHQsdW5zaWduZWQqV2lkdGgsdW5zaWduZWQqRGVwdGgpCnsKICAgIGlmICghbHBkZHJhdykgcmV0dXJuIDE7CiAgICBpZiAoIWxwZGRzdXJmKSByZXR1cm4gMTsKICAgIGlmIChIZWlnaHQpICpIZWlnaHQ9c2Rlc2MuZHdIZWlnaHQ7CiAgICBpZiAoV2lkdGgpICpXaWR0aD1zZGVzYy5kd1dpZHRoOwogICAgaWYgKERlcHRoKSAqRGVwdGg9c2Rlc2MuZGRwZlBpeGVsRm9ybWF0LnUxLmR3UkdCQml0Q291bnQ7CiAgICByZXR1cm4gMDsKfQoKdm9pZCBWR0FfRXhpdCh2b2lkKQp7CiAgICBpZiAobHBkZHJhdykgTVpfUnVuSW5UaHJlYWQoVkdBX0RvRXhpdCwgMCk7Cn0KCnZvaWQgVkdBX1NldFBhbGV0dGUoUEFMRVRURUVOVFJZKnBhbCxpbnQgc3RhcnQsaW50IGxlbikKewogICAgaWYgKCFscGRkcmF3KSByZXR1cm47CiAgICBJRGlyZWN0RHJhd1BhbGV0dGVfU2V0RW50cmllcyhscGRkcGFsLDAsc3RhcnQsbGVuLHBhbCk7Cn0KCi8qIHNldCBhIHNpbmdsZSBbY2hhciB3aWRlXSBjb2xvciBpbiAxNiBjb2xvciBtb2RlLiAqLwp2b2lkIFZHQV9TZXRDb2xvcjE2KGludCByZWcsaW50IGNvbG9yKQp7CglQQUxFVFRFRU5UUlkgKnBhbDsKCiAgICBpZiAoIWxwZGRyYXcpIHJldHVybjsKCXBhbD0gJnZnYV9kZWY2NF9wYWxldHRlW2NvbG9yXTsKICAgICAgICBJRGlyZWN0RHJhd1BhbGV0dGVfU2V0RW50cmllcyhscGRkcGFsLDAscmVnLDEscGFsKTsKCXZnYV8xNl9wYWxldHRlW3JlZ109KGNoYXIpY29sb3I7Cn0KCi8qIEdldCBhIHNpbmdsZSBbY2hhciB3aWRlXSBjb2xvciBpbiAxNiBjb2xvciBtb2RlLiAqLwpjaGFyIFZHQV9HZXRDb2xvcjE2KGludCByZWcpCnsKCiAgICBpZiAoIWxwZGRyYXcpIHJldHVybiAwOwoJcmV0dXJuIChjaGFyKXZnYV8xNl9wYWxldHRlW3JlZ107Cn0KCi8qIHNldCBhbGwgMTcgW2NoYXIgd2lkZV0gY29sb3JzIGF0IG9uY2UgaW4gMTYgY29sb3IgbW9kZS4gKi8Kdm9pZCBWR0FfU2V0MTZQYWxldHRlKGNoYXIgKlRhYmxlKQp7CglQQUxFVFRFRU5UUlkgKnBhbDsKCWludCBjOwoKICAgIGlmICghbHBkZHJhdykgcmV0dXJuOyAgICAgICAgIC8qIHJldHVybiBpZiB3ZSdyZSBpbiB0ZXh0IG9ubHkgbW9kZSAqLwogICAgbWVtY3B5KCBUYWJsZSwgJnZnYV8xNl9wYWxldHRlLCAxNyApOyAvKiBjb3B5IHRoZSBlbnRyaWVzIGludG8gdGhlIHRhYmxlICovCgogICAgZm9yIChjPTA7IGM8MTc7IGMrKykgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogMTcgZW50cmllcyAqLwoJcGFsPSAmdmdhX2RlZjY0X3BhbGV0dGVbKGludCl2Z2FfMTZfcGFsZXR0ZVtjXV07ICAvKiBnZXQgY29sb3IgICovCiAgICAgICAgSURpcmVjdERyYXdQYWxldHRlX1NldEVudHJpZXMobHBkZHBhbCwwLGMsMSxwYWwpOyAvKiBzZXQgZW50cnkgICovCglUUkFDRSgiUGFsZXR0ZSByZWdpc3RlciAlZCBzZXQgdG8gJWRcbiIsYywoaW50KXZnYV8xNl9wYWxldHRlW2NdKTsKICAgfSAvKiBlbmQgb2YgdGhlIGNvdW50aW5nIGxvb3AgKi8KfQoKLyogR2V0IGFsbCAxNyBbIGNoYXIgd2lkZSBdIGNvbG9ycyBhdCBvbmNlIGluIDE2IGNvbG9yIG1vZGUuICovCnZvaWQgVkdBX0dldDE2UGFsZXR0ZShjaGFyICpUYWJsZSkKewoKICAgIGlmICghbHBkZHJhdykgcmV0dXJuOyAgICAgICAgIC8qIHJldHVybiBpZiB3ZSdyZSBpbiB0ZXh0IG9ubHkgbW9kZSAqLwogICAgbWVtY3B5KCAmdmdhXzE2X3BhbGV0dGUsIFRhYmxlLCAxNyApOyAvKiBjb3B5IHRoZSBlbnRyaWVzIGludG8gdGhlIHRhYmxlICovCn0KCnZvaWQgVkdBX1NldFF1YWRQYWxldHRlKFJHQlFVQUQqY29sb3IsaW50IHN0YXJ0LGludCBsZW4pCnsKICAgIFBBTEVUVEVFTlRSWSBwYWxbMjU2XTsKICAgIGludCBjOwoKICAgIGlmICghbHBkZHJhdykgcmV0dXJuOwogICAgZm9yIChjPTA7IGM8bGVuOyBjKyspIHsKICAgICAgICBwYWxbY10ucGVSZWQgID1jb2xvcltjXS5yZ2JSZWQ7CiAgICAgICAgcGFsW2NdLnBlR3JlZW49Y29sb3JbY10ucmdiR3JlZW47CiAgICAgICAgcGFsW2NdLnBlQmx1ZSA9Y29sb3JbY10ucmdiQmx1ZTsKICAgICAgICBwYWxbY10ucGVGbGFncz0wOwogICAgfQogICAgSURpcmVjdERyYXdQYWxldHRlX1NldEVudHJpZXMobHBkZHBhbCwwLHN0YXJ0LGxlbixwYWwpOwp9CgpMUFNUUiBWR0FfTG9jayh1bnNpZ25lZCpQaXRjaCx1bnNpZ25lZCpIZWlnaHQsdW5zaWduZWQqV2lkdGgsdW5zaWduZWQqRGVwdGgpCnsKICAgIGlmICghbHBkZHJhdykgcmV0dXJuIE5VTEw7CiAgICBpZiAoIWxwZGRzdXJmKSByZXR1cm4gTlVMTDsKICAgIGlmIChJRGlyZWN0RHJhd1N1cmZhY2VfTG9jayhscGRkc3VyZixOVUxMLCZzZGVzYywwLDApKSB7CiAgICAgICAgRVJSKCJjb3VsZCBub3QgbG9jayBzdXJmYWNlIVxuIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBpZiAoUGl0Y2gpICpQaXRjaD1zZGVzYy51MS5sUGl0Y2g7CiAgICBpZiAoSGVpZ2h0KSAqSGVpZ2h0PXNkZXNjLmR3SGVpZ2h0OwogICAgaWYgKFdpZHRoKSAqV2lkdGg9c2Rlc2MuZHdXaWR0aDsKICAgIGlmIChEZXB0aCkgKkRlcHRoPXNkZXNjLmRkcGZQaXhlbEZvcm1hdC51MS5kd1JHQkJpdENvdW50OwogICAgcmV0dXJuIHNkZXNjLmxwU3VyZmFjZTsKfQoKdm9pZCBWR0FfVW5sb2NrKHZvaWQpCnsKICAgIElEaXJlY3REcmF3U3VyZmFjZV9VbmxvY2sobHBkZHN1cmYsc2Rlc2MubHBTdXJmYWNlKTsKfQoKLyoKICogU2V0IHN0YXJ0IG9mIDY0ayB3aW5kb3cgYXQgMHhhMDAwMCBpbiBieXRlcy4KICogSWYgdmFsdWUgaXMgLTEsIGluaXRpYWxpemUgY29sb3IgcGxhbmUgc3VwcG9ydC4KICogSWYgdmFsdWUgaXMgPj0gMCwgd2luZG93IGNvbnRhaW5zIGRpcmVjdCBjb3B5IG9mIGZyYW1lYnVmZmVyLgogKi8Kdm9pZCBWR0FfU2V0V2luZG93U3RhcnQoaW50IHN0YXJ0KQp7CiAgICBpZihzdGFydCA9PSB2Z2FfZmJfd2luZG93KQogICAgICAgIHJldHVybjsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwoKICAgIGlmKHZnYV9mYl93aW5kb3cgPT0gLTEpCiAgICAgICAgRklYTUUoIlJlbW92ZSBWR0EgbWVtb3J5IGVtdWxhdGlvbi5cbiIpOwogICAgZWxzZQogICAgICAgIFZHQV9TeW5jV2luZG93KCBUUlVFICk7CgogICAgdmdhX2ZiX3dpbmRvdyA9IHN0YXJ0OwoKICAgIGlmKHZnYV9mYl93aW5kb3cgPT0gLTEpCiAgICAgICAgRklYTUUoIkluc3RhbGwgVkdBIG1lbW9yeSBlbXVsYXRpb24uXG4iKTsKICAgIGVsc2UKICAgICAgICBWR0FfU3luY1dpbmRvdyggRkFMU0UgKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwp9CgovKgogKiBHZXQgc3RhcnQgb2YgNjRrIHdpbmRvdyBhdCAweGEwMDAwIGluIGJ5dGVzLgogKiBWYWx1ZSBpcyAtMSBpbiBjb2xvciBwbGFuZSBtb2Rlcy4KICovCmludCBWR0FfR2V0V2luZG93U3RhcnQoKQp7CiAgICByZXR1cm4gdmdhX2ZiX3dpbmRvdzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgVkdBX0RvU2hvd01vdXNlCiAqCiAqIENhbGxiYWNrIGZvciBWR0FfU2hvd01vdXNlLgogKi8Kc3RhdGljIFdJTkFQSSB2b2lkIFZHQV9Eb1Nob3dNb3VzZSggVUxPTkdfUFRSIHNob3cgKQp7CiAgICBJTlQgcnY7CgogICAgZG8KICAgIHsKICAgICAgICBydiA9IFNob3dDdXJzb3IoIHNob3cgKTsKICAgIH0KICAgIHdoaWxlKCBzaG93ID8gKHJ2IDwgMCkgOiAocnYgPj0gMCkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgVkdBX1Nob3dNb3VzZQogKgogKiBJZiBhcmd1bWVudCBpcyBUUlVFLCB1bmNvbmRpdGlvbmFsbHkgc2hvdyBtb3VzZSBjdXJzb3IuCiAqIElmIGFyZ3VtZW50IGlzIEZBTFNFLCB1bmNvbmRpdGlvbmFsbHkgaGlkZSBtb3VzZSBjdXJzb3IuCiAqIFRoaXMgb25seSB3b3JrcyBpbiBncmFwaGljcyBtb2RlLgogKi8Kdm9pZCBWR0FfU2hvd01vdXNlKCBCT09MIHNob3cgKQp7CiAgICBpZiAobHBkZHJhdykKICAgICAgICBNWl9SdW5JblRocmVhZCggVkdBX0RvU2hvd01vdXNlLCAoVUxPTkdfUFRSKXNob3cgKTsKfQoKCi8qKiogVEVYVCBNT0RFICoqKi8KCi8qIHByZXBhcmUgdGhlIHRleHQgbW9kZSB2aWRlbyBtZW1vcnkgY29weSB0aGF0IGlzIHVzZWQgdG8gb25seQogKiB1cGRhdGUgdGhlIHZpZGVvIG1lbW9yeSBsaW5lIHRoYXQgZGlkIGdldCB1cGRhdGVkLiAqLwp2b2lkIFZHQV9QcmVwYXJlVmlkZW9NZW1Db3B5KHVuc2lnbmVkIFhyZXMsIHVuc2lnbmVkIFlyZXMpCnsKICAgIGNoYXIgKnAsICpwMjsKICAgIHVuc2lnbmVkIGludCBpOwoKICAgIC8qCiAgICAgKiBBbGxvY2F0ZSBzcGFjZSBmb3IgY2hhciArIGF0dHIuCiAgICAgKi8KCiAgICBpZiAodmdhX3RleHRfb2xkKQogICAgICAgIHZnYV90ZXh0X29sZCA9IEhlYXBSZUFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Z2FfdGV4dF9vbGQsIFhyZXMgKiBZcmVzICogMiApOwogICAgZWxzZQogICAgICAgIHZnYV90ZXh0X29sZCA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhyZXMgKiBZcmVzICogMiApOwogICAgcCA9IFZHQV9BbHBoYUJ1ZmZlcigpOwogICAgcDIgPSB2Z2FfdGV4dF9vbGQ7CgogICAgLyogbWFrZSBzdXJlIHRoZSB2aWRlbyBtZW0gY29weSBjb250YWlucyB0aGUgZXhhY3Qgb3Bwb3NpdGUgb2Ygb3VyCiAgICAgKiBhY3R1YWwgdGV4dCBtb2RlIG1lbW9yeSBhcmVhIHRvIG1ha2Ugc3VyZSB0aGUgc2NyZWVuCiAgICAgKiBkb2VzIGdldCB1cGRhdGVkIGZ1bGx5IGluaXRpYWxseSAqLwogICAgZm9yIChpPTA7IGkgPCBYcmVzKllyZXMqMjsgaSsrKQoJKnAyKysgPSAqcCsrIF4gMHhmZjsgLyogWE9SIGl0ICovCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgVkdBX1NldEFscGhhTW9kZQogKgogKiBTZXQgVkdBIGVtdWxhdGlvbiB0byB0ZXh0IG1vZGUuCiAqLwp2b2lkIFZHQV9TZXRBbHBoYU1vZGUodW5zaWduZWQgWHJlcyx1bnNpZ25lZCBZcmVzKQp7CiAgICBWR0FfRXhpdCgpOwogICAgVkdBX0RlaW5zdGFsbFRpbWVyKCk7CiAgICAKICAgIFZHQV9QcmVwYXJlVmlkZW9NZW1Db3B5KFhyZXMsIFlyZXMpOwogICAgdmdhX3RleHRfd2lkdGggPSBYcmVzOwogICAgdmdhX3RleHRfaGVpZ2h0ID0gWXJlczsKCiAgICBpZiAodmdhX3RleHRfeCA+PSB2Z2FfdGV4dF93aWR0aCB8fCB2Z2FfdGV4dF95ID49IHZnYV90ZXh0X2hlaWdodCkKICAgICAgICBWR0FfU2V0Q3Vyc29yUG9zKDAsMCk7CgogICAgaWYodmdhX3RleHRfY29uc29sZSkgewogICAgICAgIENPT1JEIHNpemU7CiAgICAgICAgc2l6ZS5YID0gWHJlczsKICAgICAgICBzaXplLlkgPSBZcmVzOwogICAgICAgIFNldENvbnNvbGVTY3JlZW5CdWZmZXJTaXplKCBWR0FfQWxwaGFDb25zb2xlKCksIHNpemUgKTsKCiAgICAgICAgLyogcG9sbCBldmVyeSAzMG1zICgzM2ZwcyBzaG91bGQgcHJvdmlkZSBhZGVxdWF0ZSByZXNwb25zaXZlbmVzcykgKi8KICAgICAgICBWR0FfSW5zdGFsbFRpbWVyKDMwKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICBWR0FfSW5pdEFscGhhTW9kZQogKgogKiBJbml0aWFsaXplIFZHQSB0ZXh0IG1vZGUgaGFuZGxpbmcgYW5kIHJldHVybiBkZWZhdWx0IHRleHQgbW9kZS4KICogVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBzZXQgVkdBIGVtdWxhdGlvbiB0byB0ZXh0IG1vZGUuCiAqLwp2b2lkIFZHQV9Jbml0QWxwaGFNb2RlKHVuc2lnbmVkKlhyZXMsdW5zaWduZWQqWXJlcykKewogICAgQ09OU09MRV9TQ1JFRU5fQlVGRkVSX0lORk8gaW5mbzsKCiAgICBpZihHZXRDb25zb2xlU2NyZWVuQnVmZmVySW5mbyggVkdBX0FscGhhQ29uc29sZSgpLCAmaW5mbyApKQogICAgewogICAgICAgIHZnYV90ZXh0X2NvbnNvbGUgPSBUUlVFOwogICAgICAgIHZnYV90ZXh0X3ggPSBpbmZvLmR3Q3Vyc29yUG9zaXRpb24uWDsKICAgICAgICB2Z2FfdGV4dF95ID0gaW5mby5kd0N1cnNvclBvc2l0aW9uLlk7CiAgICAgICAgdmdhX3RleHRfYXR0ciA9IGluZm8ud0F0dHJpYnV0ZXM7CiAgICAgICAgKlhyZXMgPSBpbmZvLmR3U2l6ZS5YOwogICAgICAgICpZcmVzID0gaW5mby5kd1NpemUuWTsKICAgIH0gCiAgICBlbHNlCiAgICB7CiAgICAgICAgdmdhX3RleHRfY29uc29sZSA9IEZBTFNFOwogICAgICAgIHZnYV90ZXh0X3ggPSAwOwogICAgICAgIHZnYV90ZXh0X3kgPSAwOwogICAgICAgIHZnYV90ZXh0X2F0dHIgPSAweDBmOwogICAgICAgICpYcmVzID0gODA7CiAgICAgICAgKllyZXMgPSAyNTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICBWR0FfR2V0QWxwaGFNb2RlCiAqCiAqIEdldCBjdXJyZW50IHRleHQgbW9kZS4gUmV0dXJucyBUUlVFIGFuZCBzZXRzIHJlc29sdXRpb24gaWYKICogYW55IFZHQSB0ZXh0IG1vZGUgaGFzIGJlZW4gaW5pdGlhbGl6ZWQuCiAqLwpCT09MIFZHQV9HZXRBbHBoYU1vZGUodW5zaWduZWQqWHJlcyx1bnNpZ25lZCpZcmVzKQp7CiAgICBpZiAodmdhX3RleHRfd2lkdGggIT0gMCAmJiB2Z2FfdGV4dF9oZWlnaHQgIT0gMCkgewogICAgICAgICpYcmVzID0gdmdhX3RleHRfd2lkdGg7CiAgICAgICAgKllyZXMgPSB2Z2FfdGV4dF9oZWlnaHQ7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9IGVsc2UKICAgICAgICByZXR1cm4gRkFMU0U7Cn0KCnZvaWQgVkdBX1NldEN1cnNvclNoYXBlKHVuc2lnbmVkIGNoYXIgc3RhcnRfb3B0aW9ucywgdW5zaWduZWQgY2hhciBlbmQpCnsKICAgIENPTlNPTEVfQ1VSU09SX0lORk8gY2NpOwoKICAgIC8qIHN0YW5kYXJkIGN1cnNvciBzZXR0aW5nczoKICAgICAqIDB4MDYwNyA9PSBDR0EsIDB4MGIwYyA9PSBtb25vY2hyb21lLCAweDBkMGUgPT0gRUdBL1ZHQSAqLwoKICAgIC8qIGNhbGN1bGF0ZSBwZXJjZW50YWdlIGZyb20gYm90dG9tIC0gYXNzdW1pbmcgVkdBIChib3R0b20gMHgwZSkgKi8KICAgIGNjaS5kd1NpemUgPSAoKGVuZCAmIDB4MWYpIC0gKHN0YXJ0X29wdGlvbnMgJiAweDFmKSkvMHgwZSAqIDEwMDsKICAgIGlmICghY2NpLmR3U2l6ZSkgY2NpLmR3U2l6ZSsrOyAvKiBOVUxMIGN1cnNvciB3b3VsZCBtYWtlIFNDQ0koKSBmYWlsICEgKi8KICAgIGNjaS5iVmlzaWJsZSA9ICgoc3RhcnRfb3B0aW9ucyAmIDB4NjApICE9IDB4MjApOyAvKiBpbnZpc2libGUgPyAqLwoKICAgIFNldENvbnNvbGVDdXJzb3JJbmZvKFZHQV9BbHBoYUNvbnNvbGUoKSwmY2NpKTsKfQoKdm9pZCBWR0FfU2V0Q3Vyc29yUG9zKHVuc2lnbmVkIFgsdW5zaWduZWQgWSkKewogICAgdmdhX3RleHRfeCA9IFg7CiAgICB2Z2FfdGV4dF95ID0gWTsKfQoKdm9pZCBWR0FfR2V0Q3Vyc29yUG9zKHVuc2lnbmVkKlgsdW5zaWduZWQqWSkKewogICAgaWYgKFgpICpYID0gdmdhX3RleHRfeDsKICAgIGlmIChZKSAqWSA9IHZnYV90ZXh0X3k7Cn0KCnN0YXRpYyB2b2lkIFZHQV9QdXRDaGFyQXQodW5zaWduZWQgeCwgdW5zaWduZWQgeSwgQllURSBhc2NpaSwgaW50IGF0dHIpCnsKICAgIGNoYXIgKmRhdCA9IFZHQV9BbHBoYUJ1ZmZlcigpICsgKCh2Z2FfdGV4dF93aWR0aCAqIHkgKyB4KSAqIDIpOwogICAgZGF0WzBdID0gYXNjaWk7CiAgICBpZiAoYXR0cj49MCkKICAgICAgICBkYXRbMV0gPSBhdHRyOwp9Cgp2b2lkIFZHQV9Xcml0ZUNoYXJzKHVuc2lnbmVkIFgsdW5zaWduZWQgWSx1bnNpZ25lZCBjaCxpbnQgYXR0cixpbnQgY291bnQpCnsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7CgogICAgd2hpbGUgKGNvdW50LS0pIAogICAgICAgIFZHQV9QdXRDaGFyQXQoWCArIGNvdW50LCBZLCBjaCwgYXR0cik7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKfQoKdm9pZCBWR0FfUHV0Q2hhcihCWVRFIGFzY2lpKQp7CiAgICBEV09SRCB3OwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7CgogICAgc3dpdGNoKGFzY2lpKSB7CiAgICBjYXNlICdcYic6CiAgICAgICAgaWYgKHZnYV90ZXh0X3gpCiAgICAgICAgewogICAgICAgICAgICB2Z2FfdGV4dF94LS07CiAgICAgICAgICAgIFZHQV9QdXRDaGFyQXQodmdhX3RleHRfeCwgdmdhX3RleHRfeSwgJyAnLCAwKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnXHQnOgogICAgICAgIHZnYV90ZXh0X3ggKz0gKCh2Z2FfdGV4dF94ICsgOCkgJiB+NykgLSB2Z2FfdGV4dF94OwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ1xuJzoKICAgICAgICB2Z2FfdGV4dF95Kys7CiAgICAgICAgdmdhX3RleHRfeCA9IDA7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnXGEnOgogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ1xyJzoKICAgICAgICB2Z2FfdGV4dF94ID0gMDsKICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIFZHQV9QdXRDaGFyQXQodmdhX3RleHRfeCwgdmdhX3RleHRfeSwgYXNjaWksIHZnYV90ZXh0X2F0dHIpOwogICAgICAgIHZnYV90ZXh0X3grKzsKICAgIH0KCiAgICBpZiAodmdhX3RleHRfeCA+PSB2Z2FfdGV4dF93aWR0aCkKICAgIHsKICAgICAgICB2Z2FfdGV4dF94ID0gMDsKICAgICAgICB2Z2FfdGV4dF95Kys7CiAgICB9CgogICAgaWYgKHZnYV90ZXh0X3kgPj0gdmdhX3RleHRfaGVpZ2h0KQogICAgewogICAgICAgIHZnYV90ZXh0X3kgPSB2Z2FfdGV4dF9oZWlnaHQgLSAxOwogICAgICAgIFZHQV9TY3JvbGxVcFRleHQoIDAsIDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHZnYV90ZXh0X2hlaWdodCAtIDEsIHZnYV90ZXh0X3dpZHRoIC0gMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgdmdhX3RleHRfYXR0ciApOwogICAgfQoKICAgIC8qCiAgICAgKiBJZiB3ZSBkb24ndCBoYXZlIGEgY29uc29sZSwgd3JpdGUgZGlyZWN0bHkgdG8gc3RhbmRhcmQgb3V0cHV0LgogICAgICovCiAgICBpZighdmdhX3RleHRfY29uc29sZSkKICAgICAgICBXcml0ZUZpbGUoVkdBX0FscGhhQ29uc29sZSgpLCAmYXNjaWksIDEsICZ3LCBOVUxMKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwp9Cgp2b2lkIFZHQV9TZXRUZXh0QXR0cmlidXRlKEJZVEUgYXR0cikKewogICAgdmdhX3RleHRfYXR0ciA9IGF0dHI7Cn0KCnZvaWQgVkdBX0NsZWFyVGV4dCh1bnNpZ25lZCByb3cxLCB1bnNpZ25lZCBjb2wxLAogICAgICAgICAgICAgICAgICAgdW5zaWduZWQgcm93MiwgdW5zaWduZWQgY29sMiwKICAgICAgICAgICAgICAgICAgIEJZVEUgYXR0cikKewogICAgdW5zaWduZWQgeCwgeTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwoKICAgIGZvcih5PXJvdzE7IHk8PXJvdzI7IHkrKykKICAgICAgICBmb3IoeD1jb2wxOyB4PD1jb2wyOyB4KyspCiAgICAgICAgICAgIFZHQV9QdXRDaGFyQXQoeCwgeSwgMHgyMCwgYXR0cik7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKfQoKdm9pZCBWR0FfU2Nyb2xsVXBUZXh0KHVuc2lnbmVkIHJvdzEsICB1bnNpZ25lZCBjb2wxLAogICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgcm93MiwgIHVuc2lnbmVkIGNvbDIsCiAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsaW5lcywgQllURSBhdHRyKQp7CiAgICBjaGFyICAgICpidWZmZXIgPSBWR0FfQWxwaGFCdWZmZXIoKTsKICAgIHVuc2lnbmVkIHk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKCiAgICAvKgogICAgICogU2Nyb2xsIGJ1ZmZlci4KICAgICAqLwogICAgZm9yICh5ID0gcm93MTsgeSA8PSByb3cyIC0gbGluZXM7IHkrKykKICAgICAgICBtZW1tb3ZlKCBidWZmZXIgKyBjb2wxICsgeSAqIHZnYV90ZXh0X3dpZHRoICogMiwKICAgICAgICAgICAgICAgICBidWZmZXIgKyBjb2wxICsgKHkgKyBsaW5lcykgKiB2Z2FfdGV4dF93aWR0aCAqIDIsCiAgICAgICAgICAgICAgICAgKGNvbDIgLSBjb2wxICsgMSkgKiAyICk7CgogICAgLyoKICAgICAqIEZpbGwgZXhwb3NlZCBsaW5lcy4KICAgICAqLwogICAgZm9yICh5ID0gbWF4KHJvdzEsIHJvdzIgLSBsaW5lcyArIDEpOyB5IDw9IHJvdzI7IHkrKykKICAgICAgICBWR0FfV3JpdGVDaGFycyggY29sMSwgeSwgJyAnLCBhdHRyLCBjb2wyIC0gY29sMSArIDEgKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwp9Cgp2b2lkIFZHQV9TY3JvbGxEb3duVGV4dCh1bnNpZ25lZCByb3cxLCAgdW5zaWduZWQgY29sMSwKICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgcm93MiwgIHVuc2lnbmVkIGNvbDIsCiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxpbmVzLCBCWVRFIGF0dHIpCnsKICAgIGNoYXIgICAgKmJ1ZmZlciA9IFZHQV9BbHBoYUJ1ZmZlcigpOwogICAgdW5zaWduZWQgeTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwoKICAgIC8qCiAgICAgKiBTY3JvbGwgYnVmZmVyLgogICAgICovCiAgICBmb3IgKHkgPSByb3cyOyB5ID49IHJvdzEgKyBsaW5lczsgeS0tKQogICAgICAgIG1lbW1vdmUoIGJ1ZmZlciArIGNvbDEgKyB5ICogdmdhX3RleHRfd2lkdGggKiAyLAogICAgICAgICAgICAgICAgIGJ1ZmZlciArIGNvbDEgKyAoeSAtIGxpbmVzKSAqIHZnYV90ZXh0X3dpZHRoICogMiwKICAgICAgICAgICAgICAgICAoY29sMiAtIGNvbDEgKyAxKSAqIDIgKTsKCiAgICAvKgogICAgICogRmlsbCBleHBvc2VkIGxpbmVzLgogICAgICovCiAgICBmb3IgKHkgPSByb3cxOyB5IDw9IG1pbihyb3cxICsgbGluZXMgLSAxLCByb3cyKTsgeSsrKQogICAgICAgIFZHQV9Xcml0ZUNoYXJzKCBjb2wxLCB5LCAnICcsIGF0dHIsIGNvbDIgLSBjb2wxICsgMSApOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7Cn0KCnZvaWQgVkdBX0dldENoYXJhY3RlckF0Q3Vyc29yKEJZVEUgKmFzY2lpLCBCWVRFICphdHRyKQp7CiAgICBjaGFyICpkYXQ7CgogICAgZGF0ID0gVkdBX0FscGhhQnVmZmVyKCkgKyAoKHZnYV90ZXh0X3dpZHRoICogdmdhX3RleHRfeSArIHZnYV90ZXh0X3gpICogMik7CgogICAgKmFzY2lpID0gZGF0WzBdOwogICAgKmF0dHIgPSBkYXRbMV07Cn0KCgovKioqIENPTlRST0wgKioqLwoKLyogRklYTUU6IG9wdGltaXplIGJ5IGRvaW5nIHRoaXMgb25seSBpZiB0aGUgZGF0YSBoYXMgYWN0dWFsbHkgY2hhbmdlZAogKiAgICAgICAgKGluIGEgd2F5IHNpbWlsYXIgdG8gRElCU2VjdGlvbiwgcGVyaGFwcykgKi8Kc3RhdGljIHZvaWQgVkdBX1BvbGxfR3JhcGhpY3Modm9pZCkKewogIHVuc2lnbmVkIGludCBQaXRjaCwgSGVpZ2h0LCBXaWR0aCwgWCwgWTsKICBjaGFyICpzdXJmOwogIGNoYXIgKmRhdCA9IHZnYV9mYl9kYXRhICsgdmdhX2ZiX29mZnNldDsKICBpbnQgICBicHAgPSAodmdhX2ZiX2RlcHRoICsgNykgLyA4OwoKICBzdXJmID0gVkdBX0xvY2soJlBpdGNoLCZIZWlnaHQsJldpZHRoLE5VTEwpOwogIGlmICghc3VyZikgcmV0dXJuOwoKICAvKgogICAqIFN5bmNocm9uaXplIGZyYW1lYnVmZmVyIGNvbnRlbnRzLgogICAqLwogIGlmICh2Z2FfZmJfd2luZG93ICE9IC0xKQogICAgICBWR0FfU3luY1dpbmRvdyggVFJVRSApOwoKICAvKgogICAqIERvdWJsZSBWR0EgZnJhbWVidWZmZXIgKDMyMHgyMDAgLT4gNjQweDQwMCksIGlmIG5lZWRlZC4KICAgKi8KICBpZihIZWlnaHQgPj0gMiAqIHZnYV9mYl9oZWlnaHQgJiYgV2lkdGggPj0gMiAqIHZnYV9mYl93aWR0aCAmJiBicHAgPT0gMSkKICAgIGZvciAoWT0wOyBZPHZnYV9mYl9oZWlnaHQ7IFkrKyxzdXJmKz1QaXRjaCoyLGRhdCs9dmdhX2ZiX3BpdGNoKQogICAgICBmb3IgKFg9MDsgWDx2Z2FfZmJfd2lkdGg7IFgrKykgewogICAgICAgQllURSB2YWx1ZSA9IGRhdFtYXTsKICAgICAgIHN1cmZbWCoyXSA9IHZhbHVlOwogICAgICAgc3VyZltYKjIrMV0gPSB2YWx1ZTsKICAgICAgIHN1cmZbWCoyK1BpdGNoXSA9IHZhbHVlOwogICAgICAgc3VyZltYKjIrUGl0Y2grMV0gPSB2YWx1ZTsKICAgICAgfQogIGVsc2UKICAgIGZvciAoWT0wOyBZPHZnYV9mYl9oZWlnaHQ7IFkrKyxzdXJmKz1QaXRjaCxkYXQrPXZnYV9mYl9waXRjaCkKICAgICAgbWVtY3B5KHN1cmYsIGRhdCwgdmdhX2ZiX3dpZHRoICogYnBwKTsKCiAgVkdBX1VubG9jaygpOwp9CgpzdGF0aWMgdm9pZCBWR0FfUG9sbF9UZXh0KHZvaWQpCnsKICAgIGNoYXIgKmRhdCwgKm9sZCwgKnBfbGluZTsKICAgIHVuc2lnbmVkIGludCBYLCBZOwogICAgQ0hBUl9JTkZPIGNoWzI1Nl07IC8qIHRoYXQgc2hvdWxkIHN1ZmZpY2UgZm9yIHRoZSBsYXJnZXN0IHRleHQgd2lkdGggKi8KICAgIENPT1JEIHNpeiwgb2ZmOwogICAgU01BTExfUkVDVCBkZXN0OwogICAgSEFORExFIGNvbiA9IFZHQV9BbHBoYUNvbnNvbGUoKTsKICAgIEJPT0wgbGluZWNoYW5nZWQgPSBGQUxTRTsgLyogdmlkZW8gbWVtb3J5IGFyZWEgZGlmZmVycyBmcm9tIHN0b3JlZCBjb3B5PyAqLwoKICAgIC8qIFN5bmNocm9uaXplIGN1cnNvciBwb3NpdGlvbi4gKi8KICAgIG9mZi5YID0gdmdhX3RleHRfeDsKICAgIG9mZi5ZID0gdmdhX3RleHRfeTsKICAgIFNldENvbnNvbGVDdXJzb3JQb3NpdGlvbihjb24sb2ZmKTsKCiAgICBkYXQgPSBWR0FfQWxwaGFCdWZmZXIoKTsKICAgIG9sZCA9IHZnYV90ZXh0X29sZDsgLyogcG9pbnRlciB0byBzdG9yZWQgdmlkZW8gbWVtIGNvcHkgKi8KICAgIHNpei5YID0gdmdhX3RleHRfd2lkdGg7IHNpei5ZID0gMTsKICAgIG9mZi5YID0gMDsgb2ZmLlkgPSAwOwoKICAgIC8qIGNvcHkgZnJvbSB2aXJ0dWFsIFZHQSBmcmFtZSBidWZmZXIgdG8gY29uc29sZSAqLwogICAgZm9yIChZPTA7IFk8dmdhX3RleHRfaGVpZ2h0OyBZKyspIHsKCWxpbmVjaGFuZ2VkID0gbWVtY21wKGRhdCwgb2xkLCB2Z2FfdGV4dF93aWR0aCoyKTsKCWlmIChsaW5lY2hhbmdlZCkKCXsKCSAgICAvKlRSQUNFKCJsaW5lICVkIGNoYW5nZWRcbiIsIFkpOyovCgkgICAgcF9saW5lID0gZGF0OwogICAgICAgICAgICBmb3IgKFg9MDsgWDx2Z2FfdGV4dF93aWR0aDsgWCsrKSB7CiAgICAgICAgICAgICAgICBjaFtYXS5DaGFyLkFzY2lpQ2hhciA9ICpwX2xpbmUrKzsKICAgICAgICAgICAgICAgIC8qIFdyaXRlQ29uc29sZU91dHB1dEEgZG9lc24ndCBsaWtlICJkZWFkIiBjaGFycyAqLwogICAgICAgICAgICAgICAgaWYgKGNoW1hdLkNoYXIuQXNjaWlDaGFyID09ICdcMCcpCiAgICAgICAgICAgICAgICAgICAgY2hbWF0uQ2hhci5Bc2NpaUNoYXIgPSAnICc7CiAgICAgICAgICAgICAgICBjaFtYXS5BdHRyaWJ1dGVzID0gKnBfbGluZSsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlc3QuVG9wPVk7IGRlc3QuQm90dG9tPVk7CiAgICAgICAgICAgIGRlc3QuTGVmdD0wOyBkZXN0LlJpZ2h0PXZnYV90ZXh0X3dpZHRoKzE7CiAgICAgICAgICAgIFdyaXRlQ29uc29sZU91dHB1dEEoY29uLCBjaCwgc2l6LCBvZmYsICZkZXN0KTsKCSAgICBtZW1jcHkob2xkLCBkYXQsIHZnYV90ZXh0X3dpZHRoKjIpOwoJfQoJLyogYWR2YW5jZSB0byBuZXh0IHRleHQgbGluZSAqLwoJZGF0ICs9IHZnYV90ZXh0X3dpZHRoKjI7CglvbGQgKz0gdmdhX3RleHRfd2lkdGgqMjsKICAgIH0KfQoKc3RhdGljIHZvaWQgQ0FMTEJBQ0sgVkdBX1BvbGwoIExQVk9JRCBhcmcsIERXT1JEIGxvdywgRFdPUkQgaGlnaCApCnsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7CgogICAgaWYgKGxwZGRyYXcpCiAgICAgICAgVkdBX1BvbGxfR3JhcGhpY3MoKTsKICAgIGVsc2UKICAgICAgICBWR0FfUG9sbF9UZXh0KCk7CgogICAgLyoKICAgICAqIEZha2Ugc3RhcnQgb2YgcmV0cmFjZS4KICAgICAqLwogICAgdmdhX3JldHJhY2VfdmVydGljYWwgPSBUUlVFOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7Cn0KCnN0YXRpYyBCWVRFIHBhbHJlZyxwYWxjbnQ7CnN0YXRpYyBQQUxFVFRFRU5UUlkgcGFsZGF0OwoKdm9pZCBWR0FfaW9wb3J0X291dCggV09SRCBwb3J0LCBCWVRFIHZhbCApCnsKICAgIHN3aXRjaCAocG9ydCkgewogICAgICAgIGNhc2UgMHgzYzA6CiAgICAgICAgICAgaWYgKHZnYV9hZGRyZXNzXzNjMCkKICAgICAgICAgICAgICAgdmdhX2luZGV4XzNjMCA9IHZhbDsKICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCBpbmRleCwgcmVnaXN0ZXIgMHgzYzA6IDB4JTAyeCAodmFsdWUgMHglMDJ4KVxuIiwKICAgICAgICAgICAgICAgICAgICAgdmdhX2luZGV4XzNjMCwgdmFsKTsKICAgICAgICAgICB2Z2FfYWRkcmVzc18zYzAgPSAhdmdhX2FkZHJlc3NfM2MwOwogICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMHgzYzQ6CiAgICAgICAgICAgdmdhX2luZGV4XzNjNCA9IHZhbDsKICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDB4M2M1OgogICAgICAgICAgc3dpdGNoKHZnYV9pbmRleF8zYzQpIHsKICAgICAgICAgICAgICAgY2FzZSAweDA0OiAvKiBTZXF1ZW5jZXI6IE1lbW9yeSBNb2RlIFJlZ2lzdGVyICovCiAgICAgICAgICAgICAgICAgIGlmKHZnYV9mYl9kZXB0aCA9PSA4KQogICAgICAgICAgICAgICAgICAgICAgVkdBX1NldFdpbmRvd1N0YXJ0KCh2YWwgJiA4KSA/IDAgOiAtMSk7CiAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJNZW1vcnkgTW9kZSBSZWdpc3RlciBub3Qgc3VwcG9ydGVkIGluIHRoaXMgbW9kZS5cbiIpOwogICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNjNDogMHglMDJ4ICh2YWx1ZSAweCUwMngpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICB2Z2FfaW5kZXhfM2M0LCB2YWwpOwogICAgICAgICAgIH0KICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDB4M2M4OgogICAgICAgICAgICBwYWxyZWc9dmFsOyBwYWxjbnQ9MDsgYnJlYWs7CiAgICAgICAgY2FzZSAweDNjOToKICAgICAgICAgICAgKChCWVRFKikmcGFsZGF0KVtwYWxjbnQrK109dmFsIDw8IDI7CiAgICAgICAgICAgIGlmIChwYWxjbnQ9PTMpIHsKICAgICAgICAgICAgICAgIFZHQV9TZXRQYWxldHRlKCZwYWxkYXQscGFscmVnKyssMSk7CiAgICAgICAgICAgICAgICBwYWxjbnQ9MDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDB4M2NlOgogICAgICAgICAgICB2Z2FfaW5kZXhfM2NlID0gdmFsOwogICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMHgzY2Y6CiAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNjZTogMHglMDJ4ICh2YWx1ZSAweCUwMngpXG4iLAogICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zY2UsIHZhbCk7CiAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAweDNkNDoKICAgICAgICAgICB2Z2FfaW5kZXhfM2Q0ID0gdmFsOwogICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMHgzZDU6CiAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNkNDogMHglMDJ4ICh2YWx1ZSAweCUwMngpXG4iLAogICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zZDQsIHZhbCk7CiAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIFZHQSByZWdpc3RlcjogMHglMDR4ICh2YWx1ZSAweCUwMngpXG4iLCBwb3J0LCB2YWwpOwogICAgfQp9CgpCWVRFIFZHQV9pb3BvcnRfaW4oIFdPUkQgcG9ydCApCnsKICAgIEJZVEUgcmV0OwoKICAgIHN3aXRjaCAocG9ydCkgewogICAgICAgIGNhc2UgMHgzYzE6CiAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNjMDogMHglMDJ4XG4iLAogICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zYzApOwogICAgICAgICAgIHJldHVybiAweGZmOwogICAgICAgIGNhc2UgMHgzYzU6CiAgICAgICAgICAgc3dpdGNoKHZnYV9pbmRleF8zYzQpIHsKICAgICAgICAgICAgICAgY2FzZSAweDA0OiAvKiBTZXF1ZW5jZXI6IE1lbW9yeSBNb2RlIFJlZ2lzdGVyICovCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChWR0FfR2V0V2luZG93U3RhcnQoKSA9PSAtMSkgPyAweGY3IDogMHhmZjsKICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCBpbmRleCwgcmVnaXN0ZXIgMHgzYzQ6IDB4JTAyeFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zYzQpOwogICAgICAgICAgICAgICAgICAgcmV0dXJuIDB4ZmY7CiAgICAgICAgICAgfQogICAgICAgIGNhc2UgMHgzY2Y6CiAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNjZTogMHglMDJ4XG4iLAogICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zY2UpOwogICAgICAgICAgIHJldHVybiAweGZmOwogICAgICAgIGNhc2UgMHgzZDU6CiAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNkNDogMHglMDJ4XG4iLAogICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zZDQpOwogICAgICAgICAgIHJldHVybiAweGZmOwoKICAgICAgICBjYXNlIDB4M2RhOgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBSZWFkIGZyb20gdGhpcyByZWdpc3RlciByZXNldHMgcmVnaXN0ZXIgMHgzYzAgYWRkcmVzcyBmbGlwLWZsb3AuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB2Z2FfYWRkcmVzc18zYzAgPSBUUlVFOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogUmVhZCBmcm9tIHRoaXMgcmVnaXN0ZXIgcmV0dXJucyBmb2xsb3dpbmcgYml0czoKICAgICAgICAgICAgICogICB4eHh4MXh4eCA9IFZlcnRpY2FsIHJldHJhY2UgaW4gcHJvZ3Jlc3MgaWYgc2V0LgogICAgICAgICAgICAgKiAgIHh4eHh4MXh4ID0gTGlnaHQgcGVuIHN3aXRjaGVkIG9uLgogICAgICAgICAgICAgKiAgIHh4eHh4eDF4ID0gTGlnaHQgcGVuIHRyaWdnZXIgc2V0LgogICAgICAgICAgICAgKiAgIHh4eHh4eHgxID0gRWl0aGVyIHZlcnRpY2FsIG9yIGhvcml6b250YWwgcmV0cmFjZSAKICAgICAgICAgICAgICogICAgICAgICAgICAgIGluIHByb2dyZXNzIGlmIHNldC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgICAgIGlmICh2Z2FfcmV0cmFjZV92ZXJ0aWNhbCkKICAgICAgICAgICAgICAgIHJldCB8PSA5OwogICAgICAgICAgICBpZiAodmdhX3JldHJhY2VfaG9yaXpvbnRhbCkKICAgICAgICAgICAgICAgIHJldCB8PSAzOwogICAgICAgICAgICAKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogSWYgVkdBIG1vZGUgaGFzIGJlZW4gc2V0LCB2ZXJ0aWNhbCByZXRyYWNlIGlzCiAgICAgICAgICAgICAqIHR1cm5lZCBvbiBvbmNlIGEgZnJhbWUgYW5kIGNsZWFyZWQgYWZ0ZXIgZWFjaCByZWFkLgogICAgICAgICAgICAgKiBUaGlzIG1pZ2h0IGNhdXNlIGFwcGxpY2F0aW9ucyB0aGF0IHN5bmNocm9uaXplIHdpdGgKICAgICAgICAgICAgICogdmVydGljYWwgcmV0cmFjZSB0byBhY3R1YWxseSBza2lwIG9uZSBmcmFtZSBidXQgdGhhdAogICAgICAgICAgICAgKiBpcyBwcm9iYWJseSBub3QgYSBwcm9ibGVtLgogICAgICAgICAgICAgKiAKICAgICAgICAgICAgICogSWYgbm8gVkdBIG1vZGUgaGFzIGJlZW4gc2V0LCB2ZXJ0aWNhbCByZXRyYWNlIGlzIGZha2VkCiAgICAgICAgICAgICAqIGJ5IHRvZ2dsaW5nIHRoZSB2YWx1ZSBhZnRlciBldmVyeSByZWFkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKFZHQV9Jc1RpbWVyUnVubmluZygpKQogICAgICAgICAgICAgICAgdmdhX3JldHJhY2VfdmVydGljYWwgPSBGQUxTRTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgdmdhX3JldHJhY2VfdmVydGljYWwgPSAhdmdhX3JldHJhY2VfdmVydGljYWw7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUb2dnbGUgaG9yaXpvbnRhbCByZXRyYWNlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdmdhX3JldHJhY2VfaG9yaXpvbnRhbCA9ICF2Z2FfcmV0cmFjZV9ob3Jpem9udGFsOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0PTB4ZmY7CiAgICAgICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCBWR0EgcmVnaXN0ZXI6IDB4JTA0eFxuIiwgcG9ydCk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9Cgp2b2lkIFZHQV9DbGVhbih2b2lkKQp7CiAgICBWR0FfRXhpdCgpOwogICAgVkdBX0RlaW5zdGFsbFRpbWVyKCk7Cn0K