LyogSGFuZGxlIHR5cGVzIGZvciB0aGUgR05VIGNvbXBpbGVyIGZvciB0aGUgSmF2YShUTSkgbGFuZ3VhZ2UuCiAgIENvcHlyaWdodCAoQykgMTk5NiwgMTk5NywgMTk5OCwgMTk5OSwgMjAwMCwgMjAwMSwgMjAwMywgMjAwNAogICBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4KClRoaXMgZmlsZSBpcyBwYXJ0IG9mIEdDQy4KCkdDQyBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5Cml0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CnRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIsIG9yIChhdCB5b3VyIG9wdGlvbikKYW55IGxhdGVyIHZlcnNpb24uCgpHQ0MgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQpHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgoKWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKYWxvbmcgd2l0aCBHQ0M7IHNlZSB0aGUgZmlsZSBDT1BZSU5HLiAgSWYgbm90LCB3cml0ZSB0bwp0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsCkJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLiAgCgpKYXZhIGFuZCBhbGwgSmF2YS1iYXNlZCBtYXJrcyBhcmUgdHJhZGVtYXJrcyBvciByZWdpc3RlcmVkIHRyYWRlbWFya3MKb2YgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBpbiB0aGUgVW5pdGVkIFN0YXRlcyBhbmQgb3RoZXIgY291bnRyaWVzLgpUaGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGlzIGluZGVwZW5kZW50IG9mIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gICovCgovKiBXcml0dGVuIGJ5IFBlciBCb3RobmVyIDxib3RobmVyQGN5Z251cy5jb20+ICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJzeXN0ZW0uaCIKI2luY2x1ZGUgImNvcmV0eXBlcy5oIgojaW5jbHVkZSAidG0uaCIKI2luY2x1ZGUgInRyZWUuaCIKI2luY2x1ZGUgInJlYWwuaCIKI2luY2x1ZGUgIm9ic3RhY2suaCIKI2luY2x1ZGUgImZsYWdzLmgiCiNpbmNsdWRlICJqYXZhLXRyZWUuaCIKI2luY2x1ZGUgImpjZi5oIgojaW5jbHVkZSAiY29udmVydC5oIgojaW5jbHVkZSAidG9wbGV2LmgiCiNpbmNsdWRlICJnZ2MuaCIKCnN0YXRpYyB0cmVlIGNvbnZlcnRfaWVlZV9yZWFsX3RvX2ludGVnZXIgKHRyZWUsIHRyZWUpOwpzdGF0aWMgdHJlZSBwYXJzZV9zaWduYXR1cmVfdHlwZSAoY29uc3QgdW5zaWduZWQgY2hhciAqKiwKCQkJCSAgY29uc3QgdW5zaWduZWQgY2hhciAqKTsKc3RhdGljIHRyZWUgbG9va3VwX2RvICh0cmVlLCBpbnQsIHRyZWUsIHRyZWUsIHRyZWUgKCopKHRyZWUpKTsKc3RhdGljIHRyZWUgYnVpbGRfbnVsbF9zaWduYXR1cmUgKHRyZWUpOwoKdHJlZSAqIHR5cGVfbWFwOwoKLyogU2V0IHRoZSB0eXBlIG9mIHRoZSBsb2NhbCB2YXJpYWJsZSB3aXRoIGluZGV4IFNMT1QgdG8gVFlQRS4gKi8KCnZvaWQKc2V0X2xvY2FsX3R5cGUgKGludCBzbG90LCB0cmVlIHR5cGUpCnsKICBpbnQgbWF4X2xvY2FscyA9IERFQ0xfTUFYX0xPQ0FMUyhjdXJyZW50X2Z1bmN0aW9uX2RlY2wpOwogIGludCBuc2xvdHMgPSBUWVBFX0lTX1dJREUgKHR5cGUpID8gMiA6IDE7CgogIGlmIChzbG90IDwgMCB8fCBzbG90ICsgbnNsb3RzIC0gMSA+PSBtYXhfbG9jYWxzKQogICAgYWJvcnQgKCk7CgogIHR5cGVfbWFwW3Nsb3RdID0gdHlwZTsKICB3aGlsZSAoLS1uc2xvdHMgPiAwKQogICAgdHlwZV9tYXBbKytzbG90XSA9IHZvaWRfdHlwZV9ub2RlOwp9CgovKiBDb252ZXJ0IGFuIElFRUUgcmVhbCB0byBhbiBpbnRlZ2VyIHR5cGUuICBUaGUgcmVzdWx0IG9mIHN1Y2ggYQogICBjb252ZXJzaW9uIHdoZW4gdGhlIHNvdXJjZSBvcGVyYW5kIGlzIGEgTmFOIGlzbid0IGRlZmluZWQgYnkKICAgSUVFRTc1NCwgYnV0IGJ5IHRoZSBKYXZhIGxhbmd1YWdlIHN0YW5kYXJkOiBpdCBtdXN0IGJlIHplcm8uICBBbHNvLAogICBvdmVyZmxvd3MgbXVzdCBiZSBjbGlwcGVkIHRvIHdpdGhpbiByYW5nZS4gIFRoaXMgY29udmVyc2lvbgogICBwcm9kdWNlcyBzb21ldGhpbmcgbGlrZToKCiAgICAgICgoZXhwciA+PSAoZmxvYXQpTUFYX0lOVCkKICAgICAgID8gTUFYX0lOVCAKICAgICAgIDogKChleHByIDw9IChmbG9hdClNSU5fSU5UKQoJICA/IE1JTl9JTlQKCSAgOiAoKGV4cHIgIT0gZXhwcikKCSAgICAgPyAwIAoJICAgICA6IChpbnQpZXhwcikpKSAqLwoKc3RhdGljIHRyZWUKY29udmVydF9pZWVlX3JlYWxfdG9faW50ZWdlciAodHJlZSB0eXBlLCB0cmVlIGV4cHIpCnsKICB0cmVlIHJlc3VsdDsKICBleHByID0gc2F2ZV9leHByIChleHByKTsKCiAgcmVzdWx0ID0gZm9sZCAoYnVpbGQzIChDT05EX0VYUFIsIHR5cGUsCgkJCSBmb2xkIChidWlsZDIgKE5FX0VYUFIsIGJvb2xlYW5fdHlwZV9ub2RlLCBleHByLCBleHByKSksCgkJCSBjb252ZXJ0ICh0eXBlLCBpbnRlZ2VyX3plcm9fbm9kZSksCgkJCSBjb252ZXJ0X3RvX2ludGVnZXIgKHR5cGUsIGV4cHIpKSk7CiAgCiAgcmVzdWx0ID0gZm9sZCAoYnVpbGQzIChDT05EX0VYUFIsIHR5cGUsIAoJCQkgZm9sZCAoYnVpbGQyIChMRV9FWFBSLCBib29sZWFuX3R5cGVfbm9kZSwgZXhwciwgCgkJCQkgICAgICAgY29udmVydCAoVFJFRV9UWVBFIChleHByKSwgCgkJCQkJCVRZUEVfTUlOX1ZBTFVFICh0eXBlKSkpKSwKCQkJIFRZUEVfTUlOX1ZBTFVFICh0eXBlKSwKCQkJIHJlc3VsdCkpOwogIAogIHJlc3VsdCA9IGZvbGQgKGJ1aWxkMyAoQ09ORF9FWFBSLCB0eXBlLAoJCQkgZm9sZCAoYnVpbGQyIChHRV9FWFBSLCBib29sZWFuX3R5cGVfbm9kZSwgZXhwciwgCgkJCQkgICAgICAgY29udmVydCAoVFJFRV9UWVBFIChleHByKSwgCgkJCQkJCVRZUEVfTUFYX1ZBTFVFICh0eXBlKSkpKSwKCQkJIFRZUEVfTUFYX1ZBTFVFICh0eXBlKSwKCQkJIHJlc3VsdCkpOwoKICByZXR1cm4gcmVzdWx0Owp9ICAKCi8qIENyZWF0ZSBhbiBleHByZXNzaW9uIHdob3NlIHZhbHVlIGlzIHRoYXQgb2YgRVhQUiwKICAgY29udmVydGVkIHRvIHR5cGUgVFlQRS4gIFRoZSBUUkVFX1RZUEUgb2YgdGhlIHZhbHVlCiAgIGlzIGFsd2F5cyBUWVBFLiAgVGhpcyBmdW5jdGlvbiBpbXBsZW1lbnRzIGFsbCByZWFzb25hYmxlCiAgIGNvbnZlcnNpb25zOyBjYWxsZXJzIHNob3VsZCBmaWx0ZXIgb3V0IHRob3NlIHRoYXQgYXJlCiAgIG5vdCBwZXJtaXR0ZWQgYnkgdGhlIGxhbmd1YWdlIGJlaW5nIGNvbXBpbGVkLiAgKi8KCnRyZWUKY29udmVydCAodHJlZSB0eXBlLCB0cmVlIGV4cHIpCnsKICBlbnVtIHRyZWVfY29kZSBjb2RlID0gVFJFRV9DT0RFICh0eXBlKTsKCiAgaWYgKCFleHByKQogICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoKICBpZiAoZG9fbm90X2ZvbGQpCiAgICByZXR1cm4gYnVpbGQxIChOT1BfRVhQUiwgdHlwZSwgZXhwcik7CgogIGlmICh0eXBlID09IFRSRUVfVFlQRSAoZXhwcikKICAgICAgfHwgVFJFRV9DT0RFIChleHByKSA9PSBFUlJPUl9NQVJLKQogICAgcmV0dXJuIGV4cHI7CiAgaWYgKFRSRUVfQ09ERSAoVFJFRV9UWVBFIChleHByKSkgPT0gRVJST1JfTUFSSykKICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CiAgaWYgKGNvZGUgPT0gVk9JRF9UWVBFKQogICAgcmV0dXJuIGJ1aWxkMSAoQ09OVkVSVF9FWFBSLCB0eXBlLCBleHByKTsKICBpZiAoY29kZSA9PSBCT09MRUFOX1RZUEUgfHwgY29kZSA9PSAgQ0hBUl9UWVBFKQogICAgcmV0dXJuIGZvbGRfY29udmVydCAodHlwZSwgZXhwcik7CiAgaWYgKGNvZGUgPT0gSU5URUdFUl9UWVBFKQogICAgewogICAgICBpZiAoKHJlYWxseV9jb25zdGFudF9wIChleHByKQoJICAgfHwgKCEgZmxhZ191bnNhZmVfbWF0aF9vcHRpbWl6YXRpb25zCgkgICAgICAgJiYgISBmbGFnX2VtaXRfY2xhc3NfZmlsZXMpKQoJICAmJiBUUkVFX0NPREUgKFRSRUVfVFlQRSAoZXhwcikpID09IFJFQUxfVFlQRQoJICAmJiBUQVJHRVRfRkxPQVRfRk9STUFUID09IElFRUVfRkxPQVRfRk9STUFUKQoJcmV0dXJuIGZvbGQgKGNvbnZlcnRfaWVlZV9yZWFsX3RvX2ludGVnZXIgKHR5cGUsIGV4cHIpKTsKICAgICAgZWxzZQoJewoJICAvKiBmb2xkIHZlcnkgaGVscGZ1bGx5IHNldHMgdGhlIG92ZXJmbG93IHN0YXR1cyBpZiBhIHR5cGUKCSAgICAgb3ZlcmZsb3dzIGluIGEgbmFycm93aW5nIGludGVnZXIgY29udmVyc2lvbiwgYnV0IEphdmEKCSAgICAgZG9lc24ndCBjYXJlLiAgKi8KCSAgdHJlZSB0bXAgPSBmb2xkIChjb252ZXJ0X3RvX2ludGVnZXIgKHR5cGUsIGV4cHIpKTsKCSAgVFJFRV9PVkVSRkxPVyAodG1wKSA9IDA7CgkgIHJldHVybiB0bXA7Cgl9CiAgICB9CSAgCiAgaWYgKGNvZGUgPT0gUkVBTF9UWVBFKQogICAgcmV0dXJuIGZvbGQgKGNvbnZlcnRfdG9fcmVhbCAodHlwZSwgZXhwcikpOwogIGlmIChjb2RlID09IFBPSU5URVJfVFlQRSkKICAgIHJldHVybiBmb2xkIChjb252ZXJ0X3RvX3BvaW50ZXIgKHR5cGUsIGV4cHIpKTsKICBlcnJvciAoImNvbnZlcnNpb24gdG8gbm9uLXNjYWxhciB0eXBlIHJlcXVlc3RlZCIpOwogIHJldHVybiBlcnJvcl9tYXJrX25vZGU7Cn0KCgovKiBSZXR1cm4gYSBkYXRhIHR5cGUgdGhhdCBoYXMgbWFjaGluZSBtb2RlIE1PREUuCiAgIElmIHRoZSBtb2RlIGlzIGFuIGludGVnZXIsCiAgIHRoZW4gVU5TSUdORURQIHNlbGVjdHMgYmV0d2VlbiBzaWduZWQgYW5kIHVuc2lnbmVkIHR5cGVzLiAgKi8KCnRyZWUKamF2YV90eXBlX2Zvcl9tb2RlIChlbnVtIG1hY2hpbmVfbW9kZSBtb2RlLCBpbnQgdW5zaWduZWRwKQp7CiAgaWYgKG1vZGUgPT0gVFlQRV9NT0RFIChpbnRfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9pbnRfdHlwZV9ub2RlIDogaW50X3R5cGVfbm9kZTsKICBpZiAobW9kZSA9PSBUWVBFX01PREUgKGxvbmdfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9sb25nX3R5cGVfbm9kZSA6IGxvbmdfdHlwZV9ub2RlOwogIGlmIChtb2RlID09IFRZUEVfTU9ERSAoc2hvcnRfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9zaG9ydF90eXBlX25vZGUgOiBzaG9ydF90eXBlX25vZGU7CiAgaWYgKG1vZGUgPT0gVFlQRV9NT0RFIChieXRlX3R5cGVfbm9kZSkpCiAgICByZXR1cm4gdW5zaWduZWRwID8gdW5zaWduZWRfYnl0ZV90eXBlX25vZGUgOiBieXRlX3R5cGVfbm9kZTsKICBpZiAobW9kZSA9PSBUWVBFX01PREUgKGZsb2F0X3R5cGVfbm9kZSkpCiAgICByZXR1cm4gZmxvYXRfdHlwZV9ub2RlOwogIGlmIChtb2RlID09IFRZUEVfTU9ERSAoZG91YmxlX3R5cGVfbm9kZSkpCiAgICByZXR1cm4gZG91YmxlX3R5cGVfbm9kZTsKCiAgcmV0dXJuIDA7Cn0KCi8qIFJldHVybiBhbiBpbnRlZ2VyIHR5cGUgd2l0aCBCSVRTIGJpdHMgb2YgcHJlY2lzaW9uLAogICB0aGF0IGlzIHVuc2lnbmVkIGlmIFVOU0lHTkVEUCBpcyBub256ZXJvLCBvdGhlcndpc2Ugc2lnbmVkLiAgKi8KCnRyZWUKamF2YV90eXBlX2Zvcl9zaXplICh1bnNpZ25lZCBiaXRzLCBpbnQgdW5zaWduZWRwKQp7CiAgaWYgKGJpdHMgPD0gVFlQRV9QUkVDSVNJT04gKGJ5dGVfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9ieXRlX3R5cGVfbm9kZSA6IGJ5dGVfdHlwZV9ub2RlOwogIGlmIChiaXRzIDw9IFRZUEVfUFJFQ0lTSU9OIChzaG9ydF90eXBlX25vZGUpKQogICAgcmV0dXJuIHVuc2lnbmVkcCA/IHVuc2lnbmVkX3Nob3J0X3R5cGVfbm9kZSA6IHNob3J0X3R5cGVfbm9kZTsKICBpZiAoYml0cyA8PSBUWVBFX1BSRUNJU0lPTiAoaW50X3R5cGVfbm9kZSkpCiAgICByZXR1cm4gdW5zaWduZWRwID8gdW5zaWduZWRfaW50X3R5cGVfbm9kZSA6IGludF90eXBlX25vZGU7CiAgaWYgKGJpdHMgPD0gVFlQRV9QUkVDSVNJT04gKGxvbmdfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9sb25nX3R5cGVfbm9kZSA6IGxvbmdfdHlwZV9ub2RlOwogIHJldHVybiAwOwp9CgovKiBSZXR1cm4gYSB0eXBlIHRoZSBzYW1lIGFzIFRZUEUgZXhjZXB0IHVuc2lnbmVkIG9yCiAgIHNpZ25lZCBhY2NvcmRpbmcgdG8gVU5TSUdORURQLiAgKi8KCnRyZWUKamF2YV9zaWduZWRfb3JfdW5zaWduZWRfdHlwZSAoaW50IHVuc2lnbmVkcCwgdHJlZSB0eXBlKQp7CiAgaWYgKCEgSU5URUdSQUxfVFlQRV9QICh0eXBlKSkKICAgIHJldHVybiB0eXBlOwogIGlmIChUWVBFX1BSRUNJU0lPTiAodHlwZSkgPT0gVFlQRV9QUkVDSVNJT04gKGludF90eXBlX25vZGUpKQogICAgcmV0dXJuIHVuc2lnbmVkcCA/IHVuc2lnbmVkX2ludF90eXBlX25vZGUgOiBpbnRfdHlwZV9ub2RlOwogIGlmIChUWVBFX1BSRUNJU0lPTiAodHlwZSkgPT0gVFlQRV9QUkVDSVNJT04gKGJ5dGVfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9ieXRlX3R5cGVfbm9kZSA6IGJ5dGVfdHlwZV9ub2RlOwogIGlmIChUWVBFX1BSRUNJU0lPTiAodHlwZSkgPT0gVFlQRV9QUkVDSVNJT04gKHNob3J0X3R5cGVfbm9kZSkpCiAgICByZXR1cm4gdW5zaWduZWRwID8gdW5zaWduZWRfc2hvcnRfdHlwZV9ub2RlIDogc2hvcnRfdHlwZV9ub2RlOwogIGlmIChUWVBFX1BSRUNJU0lPTiAodHlwZSkgPT0gVFlQRV9QUkVDSVNJT04gKGxvbmdfdHlwZV9ub2RlKSkKICAgIHJldHVybiB1bnNpZ25lZHAgPyB1bnNpZ25lZF9sb25nX3R5cGVfbm9kZSA6IGxvbmdfdHlwZV9ub2RlOwogIHJldHVybiB0eXBlOwp9CgovKiBSZXR1cm4gYSBzaWduZWQgdHlwZSB0aGUgc2FtZSBhcyBUWVBFIGluIG90aGVyIHJlc3BlY3RzLiAgKi8KCnRyZWUKamF2YV9zaWduZWRfdHlwZSAodHJlZSB0eXBlKQp7CiAgcmV0dXJuIGphdmFfc2lnbmVkX29yX3Vuc2lnbmVkX3R5cGUgKDAsIHR5cGUpOwp9CgovKiBSZXR1cm4gYW4gdW5zaWduZWQgdHlwZSB0aGUgc2FtZSBhcyBUWVBFIGluIG90aGVyIHJlc3BlY3RzLiAgKi8KCnRyZWUKamF2YV91bnNpZ25lZF90eXBlICh0cmVlIHR5cGUpCnsKICByZXR1cm4gamF2YV9zaWduZWRfb3JfdW5zaWduZWRfdHlwZSAoMSwgdHlwZSk7Cn0KCi8qIE1hcmsgRVhQIHNheWluZyB0aGF0IHdlIG5lZWQgdG8gYmUgYWJsZSB0byB0YWtlIHRoZQogICBhZGRyZXNzIG9mIGl0OyBpdCBzaG91bGQgbm90IGJlIGFsbG9jYXRlZCBpbiBhIHJlZ2lzdGVyLgogICBWYWx1ZSBpcyB0cnVlIGlmIHN1Y2Nlc3NmdWwuICAqLwoKYm9vbApqYXZhX21hcmtfYWRkcmVzc2FibGUgKHRyZWUgZXhwKQp7CiAgdHJlZSB4ID0gZXhwOwogIHdoaWxlICgxKQogICAgc3dpdGNoIChUUkVFX0NPREUgKHgpKQogICAgICB7CiAgICAgIGNhc2UgQUREUl9FWFBSOgogICAgICBjYXNlIENPTVBPTkVOVF9SRUY6CiAgICAgIGNhc2UgQVJSQVlfUkVGOgogICAgICBjYXNlIFJFQUxQQVJUX0VYUFI6CiAgICAgIGNhc2UgSU1BR1BBUlRfRVhQUjoKCXggPSBUUkVFX09QRVJBTkQgKHgsIDApOwoJYnJlYWs7CgogICAgICBjYXNlIFRSVVRIX0FORElGX0VYUFI6CiAgICAgIGNhc2UgVFJVVEhfT1JJRl9FWFBSOgogICAgICBjYXNlIENPTVBPVU5EX0VYUFI6Cgl4ID0gVFJFRV9PUEVSQU5EICh4LCAxKTsKCWJyZWFrOwoKICAgICAgY2FzZSBDT05EX0VYUFI6CglyZXR1cm4gamF2YV9tYXJrX2FkZHJlc3NhYmxlIChUUkVFX09QRVJBTkQgKHgsIDEpKQoJICAmJiBqYXZhX21hcmtfYWRkcmVzc2FibGUgKFRSRUVfT1BFUkFORCAoeCwgMikpOwoKICAgICAgY2FzZSBDT05TVFJVQ1RPUjoKCVRSRUVfQUREUkVTU0FCTEUgKHgpID0gMTsKCXJldHVybiB0cnVlOwoKICAgICAgY2FzZSBJTkRJUkVDVF9SRUY6CgkvKiBXZSBzb21ldGltZXMgYWRkIGEgY2FzdCAqKFRZUEUqKSZGT08gdG8gaGFuZGxlIHR5cGUgYW5kIG1vZGUKCSAgIGluY29tcGF0aWJpbGl0eSBwcm9ibGVtcy4gIEhhbmRsZSB0aGlzIGNhc2UgYnkgbWFya2luZyBGT08uICAqLwoJaWYgKFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EICh4LCAwKSkgPT0gTk9QX0VYUFIKCSAgICAmJiBUUkVFX0NPREUgKFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EICh4LCAwKSwgMCkpID09IEFERFJfRVhQUikKCSAgewoJICAgIHggPSBUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAoeCwgMCksIDApOwoJICAgIGJyZWFrOwoJICB9CglpZiAoVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKHgsIDApKSA9PSBBRERSX0VYUFIpCgkgIHsKCSAgICB4ID0gVFJFRV9PUEVSQU5EICh4LCAwKTsKCSAgICBicmVhazsKCSAgfQoJcmV0dXJuIHRydWU7CgogICAgICBjYXNlIFZBUl9ERUNMOgogICAgICBjYXNlIENPTlNUX0RFQ0w6CiAgICAgIGNhc2UgUEFSTV9ERUNMOgogICAgICBjYXNlIFJFU1VMVF9ERUNMOgogICAgICBjYXNlIEZVTkNUSU9OX0RFQ0w6CglUUkVFX0FERFJFU1NBQkxFICh4KSA9IDE7CiNpZiAwICAvKiBwb3BsZXZlbCBkZWFscyB3aXRoIHRoaXMgbm93LiAgKi8KCWlmIChERUNMX0NPTlRFWFQgKHgpID09IDApCgkgIFRSRUVfQUREUkVTU0FCTEUgKERFQ0xfQVNTRU1CTEVSX05BTUUgKHgpKSA9IDE7CiNlbmRpZgoJLyogZHJvcHMgdGhyb3VnaCAqLwogICAgICBkZWZhdWx0OgoJcmV0dXJuIHRydWU7CiAgICB9Cn0KCi8qIFRob3JvdWdoIGNoZWNraW5nIG9mIHRoZSBhcnJheW5lc3Mgb2YgVFlQRS4gICovCgppbnQKaXNfYXJyYXlfdHlwZV9wICh0cmVlIHR5cGUpCnsKICByZXR1cm4gVFJFRV9DT0RFICh0eXBlKSA9PSBQT0lOVEVSX1RZUEUKICAgICYmIFRSRUVfQ09ERSAoVFJFRV9UWVBFICh0eXBlKSkgPT0gUkVDT1JEX1RZUEUKICAgICYmIFRZUEVfQVJSQVlfUCAoVFJFRV9UWVBFICh0eXBlKSk7Cn0KCi8qIFJldHVybiB0aGUgbGVuZ3RoIG9mIGEgSmF2YSBhcnJheSB0eXBlLgogICBSZXR1cm4gLTEgaWYgdGhlIGxlbmd0aCBpcyB1bmtub3duIG9yIG5vbi1jb25zdGFudC4gKi8KCkhPU1RfV0lERV9JTlQKamF2YV9hcnJheV90eXBlX2xlbmd0aCAodHJlZSBhcnJheV90eXBlKQp7CiAgdHJlZSBhcmZsZDsKICBpZiAoVFJFRV9DT0RFIChhcnJheV90eXBlKSA9PSBQT0lOVEVSX1RZUEUpCiAgICBhcnJheV90eXBlID0gVFJFRV9UWVBFIChhcnJheV90eXBlKTsKICBhcmZsZCA9IFRSRUVfQ0hBSU4gKFRSRUVfQ0hBSU4gKFRZUEVfRklFTERTIChhcnJheV90eXBlKSkpOwogIGlmIChhcmZsZCAhPSBOVUxMX1RSRUUpCiAgICB7CiAgICAgIHRyZWUgaW5kZXhfdHlwZSA9IFRZUEVfRE9NQUlOIChUUkVFX1RZUEUgKGFyZmxkKSk7CiAgICAgIGlmIChpbmRleF90eXBlICE9IE5VTExfVFJFRSkKCXsKCSAgdHJlZSBoaWdoID0gVFlQRV9NQVhfVkFMVUUgKGluZGV4X3R5cGUpOwoJICBpZiAoVFJFRV9DT0RFIChoaWdoKSA9PSBJTlRFR0VSX0NTVCkKCSAgICByZXR1cm4gVFJFRV9JTlRfQ1NUX0xPVyAoaGlnaCkgKyAxOwoJfQogICAgfQogIHJldHVybiAtMTsKfQoKLyogQW4gYXJyYXkgb2YgdW5rbm93biBsZW5ndGggd2lsbCBiZSB1bHRpbWF0ZWx5IGdpdmVuIGFuIGxlbmd0aCBvZgogICAtMiwgc28gdGhhdCB3ZSBjYW4gc3RpbGwgaGF2ZSBgbGVuZ3RoJyBwcm9kdWNpbmcgYSBuZWdhdGl2ZSB2YWx1ZQogICBldmVuIGlmIGZvdW5kLiBUaGlzIHdhcyBwYXJ0IG9mIGFuIG9wdGltaXphdGlvbiBhaW1pbmcgYXQgcmVtb3ZpbmcKICAgYGxlbmd0aCcgZnJvbSBzdGF0aWMgYXJyYXlzLiBXZSBjb3VsZCByZXN0b3JlIGl0LCBGSVhNRS4gICovCgp0cmVlCmJ1aWxkX3ByaW1fYXJyYXlfdHlwZSAodHJlZSBlbGVtZW50X3R5cGUsIEhPU1RfV0lERV9JTlQgbGVuZ3RoKQp7CiAgdHJlZSBpbmRleCA9IE5VTEw7CgogIGlmIChsZW5ndGggIT0gLTEpCiAgICB7CiAgICAgIHRyZWUgbWF4X2luZGV4ID0gYnVpbGRfaW50X2NzdCAoc2l6ZXR5cGUsIGxlbmd0aCAtIDEpOwogICAgICBpbmRleCA9IGJ1aWxkX2luZGV4X3R5cGUgKG1heF9pbmRleCk7CiAgICB9CiAgcmV0dXJuIGJ1aWxkX2FycmF5X3R5cGUgKGVsZW1lbnRfdHlwZSwgaW5kZXgpOwp9CgovKiBSZXR1cm4gYSBKYXZhIGFycmF5IHR5cGUgd2l0aCBhIGdpdmVuIEVMRU1FTlRfVFlQRSBhbmQgTEVOR1RILgogICBUaGVzZSBhcmUgaGFzaGVkIChzaGFyZWQpIHVzaW5nIElERU5USUZJRVJfU0lHTkFUVVJFX1RZUEUuCiAgIFRoZSBMRU5HVEggaXMgLTEgaWYgdGhlIGxlbmd0aCBpcyB1bmtub3duLiAqLwoKdHJlZQpidWlsZF9qYXZhX2FycmF5X3R5cGUgKHRyZWUgZWxlbWVudF90eXBlLCBIT1NUX1dJREVfSU5UIGxlbmd0aCkKewogIHRyZWUgc2lnLCB0LCBmbGQsIGF0eXBlLCBhcmZsZDsKICBjaGFyIGJ1ZlsxMl07CiAgdHJlZSBlbHNpZyA9IGJ1aWxkX2phdmFfc2lnbmF0dXJlIChlbGVtZW50X3R5cGUpOwogIHRyZWUgZWxfbmFtZSA9IGVsZW1lbnRfdHlwZTsKICBidWZbMF0gPSAnWyc7CiAgaWYgKGxlbmd0aCA+PSAwKQogICAgc3ByaW50ZiAoYnVmKzEsIEhPU1RfV0lERV9JTlRfUFJJTlRfREVDLCBsZW5ndGgpOwogIGVsc2UKICAgIGJ1ZlsxXSA9ICdcMCc7CiAgc2lnID0gaWRlbnRfc3Vic3QgKElERU5USUZJRVJfUE9JTlRFUiAoZWxzaWcpLCBJREVOVElGSUVSX0xFTkdUSCAoZWxzaWcpLAoJCSAgICAgYnVmLCAwLCAwLCAiIik7CiAgdCA9IElERU5USUZJRVJfU0lHTkFUVVJFX1RZUEUgKHNpZyk7CiAgaWYgKHQgIT0gTlVMTF9UUkVFKQogICAgcmV0dXJuIFRSRUVfVFlQRSAodCk7CiAgdCA9IG1ha2VfY2xhc3MgKCk7CiAgSURFTlRJRklFUl9TSUdOQVRVUkVfVFlQRSAoc2lnKSA9IGJ1aWxkX3BvaW50ZXJfdHlwZSAodCk7CiAgVFlQRV9BUlJBWV9QICh0KSA9IDE7CgogIGlmIChUUkVFX0NPREUgKGVsX25hbWUpID09IFBPSU5URVJfVFlQRSkKICAgIGVsX25hbWUgPSBUUkVFX1RZUEUgKGVsX25hbWUpOwogIGVsX25hbWUgPSBUWVBFX05BTUUgKGVsX25hbWUpOwogIGlmIChUUkVFX0NPREUgKGVsX25hbWUpID09IFRZUEVfREVDTCkKICAgIGVsX25hbWUgPSBERUNMX05BTUUgKGVsX25hbWUpOwogIHsKICAgIGNoYXIgc3VmZml4WzEyXTsKICAgIGlmIChsZW5ndGggPj0gMCkKICAgICAgc3ByaW50ZiAoc3VmZml4LCAiWyVkXSIsIChpbnQpbGVuZ3RoKTsgCiAgICBlbHNlCiAgICAgIHN0cmNweSAoc3VmZml4LCAiW10iKTsKICAgIFRZUEVfTkFNRSAodCkgCiAgICAgID0gYnVpbGRfZGVjbCAoVFlQRV9ERUNMLAoJCSAgICBpZGVudGlmaWVyX3N1YnN0IChlbF9uYW1lLCAiIiwgJy4nLCAnLicsIHN1ZmZpeCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdCk7CiAgfQoKICBzZXRfamF2YV9zaWduYXR1cmUgKHQsIHNpZyk7CiAgc2V0X3N1cGVyX2luZm8gKDAsIHQsIG9iamVjdF90eXBlX25vZGUsIDApOwogIGlmIChUUkVFX0NPREUgKGVsZW1lbnRfdHlwZSkgPT0gUkVDT1JEX1RZUEUpCiAgICBlbGVtZW50X3R5cGUgPSBwcm9tb3RlX3R5cGUgKGVsZW1lbnRfdHlwZSk7CiAgVFlQRV9BUlJBWV9FTEVNRU5UICh0KSA9IGVsZW1lbnRfdHlwZTsKCiAgLyogQWRkIGxlbmd0aCBwc2V1ZG8tZmllbGQuICovCiAgZmxkID0gYnVpbGRfZGVjbCAoRklFTERfREVDTCwgZ2V0X2lkZW50aWZpZXIgKCJsZW5ndGgiKSwgaW50X3R5cGVfbm9kZSk7CiAgVFlQRV9GSUVMRFMgKHQpID0gZmxkOwogIERFQ0xfQ09OVEVYVCAoZmxkKSA9IHQ7CiAgRklFTERfUFVCTElDIChmbGQpID0gMTsKICBGSUVMRF9GSU5BTCAoZmxkKSA9IDE7CiAgVFJFRV9SRUFET05MWSAoZmxkKSA9IDE7CgogIGF0eXBlID0gYnVpbGRfcHJpbV9hcnJheV90eXBlIChlbGVtZW50X3R5cGUsIGxlbmd0aCk7CiAgYXJmbGQgPSBidWlsZF9kZWNsIChGSUVMRF9ERUNMLCBnZXRfaWRlbnRpZmllciAoImRhdGEiKSwgYXR5cGUpOwogIERFQ0xfQ09OVEVYVCAoYXJmbGQpID0gdDsKICBUUkVFX0NIQUlOIChmbGQpID0gYXJmbGQ7CiAgREVDTF9BTElHTiAoYXJmbGQpID0gVFlQRV9BTElHTiAoZWxlbWVudF90eXBlKTsKCiAgLyogV2UgY291bGQgbGF5b3V0X2NsYXNzLCBidXQgdGhhdCBsb2FkcyBqYXZhLmxhbmcuT2JqZWN0IHByZW1hdHVyZWx5LgogICAqIFRoaXMgaXMgY2FsbGVkIGJ5IHRoZSBwYXJzZXIsIGFuZCBpdCBpcyBhIGJhZCBpZGVhIHRvIGRvIGxvYWRfY2xhc3MKICAgKiBpbiB0aGUgbWlkZGxlIG9mIHBhcnNpbmcsIGJlY2F1c2Ugb2YgcG9zc2libGUgY2lyY3VsYXJpdHkgcHJvYmxlbXMuICovCiAgcHVzaF9zdXBlcl9maWVsZCAodCwgb2JqZWN0X3R5cGVfbm9kZSk7CiAgbGF5b3V0X3R5cGUgKHQpOwoKICByZXR1cm4gdDsKfQoKLyogUHJvbW90ZSBUWVBFIHRvIHRoZSB0eXBlIGFjdHVhbGx5IHVzZWQgZm9yIGZpZWxkcyBhbmQgcGFyYW1ldGVycy4gKi8KCnRyZWUKcHJvbW90ZV90eXBlICh0cmVlIHR5cGUpCnsKICBzd2l0Y2ggKFRSRUVfQ09ERSAodHlwZSkpCiAgICB7CiAgICBjYXNlIFJFQ09SRF9UWVBFOgogICAgICByZXR1cm4gYnVpbGRfcG9pbnRlcl90eXBlICh0eXBlKTsKICAgIGNhc2UgQk9PTEVBTl9UWVBFOgogICAgICBpZiAodHlwZSA9PSBib29sZWFuX3R5cGVfbm9kZSkKCXJldHVybiBwcm9tb3RlZF9ib29sZWFuX3R5cGVfbm9kZTsKICAgICAgZ290byBoYW5kbGVfaW50OwogICAgY2FzZSBDSEFSX1RZUEU6CiAgICAgIGlmICh0eXBlID09IGNoYXJfdHlwZV9ub2RlKQoJcmV0dXJuIHByb21vdGVkX2NoYXJfdHlwZV9ub2RlOwogICAgICBnb3RvIGhhbmRsZV9pbnQ7CiAgICBjYXNlIElOVEVHRVJfVFlQRToKICAgIGhhbmRsZV9pbnQ6CiAgICAgIGlmIChUWVBFX1BSRUNJU0lPTiAodHlwZSkgPCBUWVBFX1BSRUNJU0lPTiAoaW50X3R5cGVfbm9kZSkpCgl7CgkgIGlmICh0eXBlID09IHNob3J0X3R5cGVfbm9kZSkKCSAgICByZXR1cm4gcHJvbW90ZWRfc2hvcnRfdHlwZV9ub2RlOwoJICBpZiAodHlwZSA9PSBieXRlX3R5cGVfbm9kZSkKCSAgICByZXR1cm4gcHJvbW90ZWRfYnl0ZV90eXBlX25vZGU7CgkgIHJldHVybiBpbnRfdHlwZV9ub2RlOwoJfQogICAgICAvKiAuLi4gZWxzZSBmYWxsIHRocm91Z2ggLi4uICovCiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gdHlwZTsKICAgIH0KfQoKLyogUGFyc2UgYSBzaWduYXR1cmUgc3RyaW5nLCBzdGFydGluZyBhdCAqUFRSIGFuZCBlbmRpbmcgYXQgTElNSVQuCiAgIFJldHVybiB0aGUgc2VlbiBUUkVFX1RZUEUsIHVwZGF0aW5nICpQVFIuICovCgpzdGF0aWMgdHJlZQpwYXJzZV9zaWduYXR1cmVfdHlwZSAoY29uc3QgdW5zaWduZWQgY2hhciAqKnB0ciwgY29uc3QgdW5zaWduZWQgY2hhciAqbGltaXQpCnsKICB0cmVlIHR5cGU7CgogIGlmICgqcHRyID49IGxpbWl0KQogICAgYWJvcnQgKCk7CgogIHN3aXRjaCAoKipwdHIpCiAgICB7CiAgICBjYXNlICdCJzogICgqcHRyKSsrOyAgcmV0dXJuIGJ5dGVfdHlwZV9ub2RlOwogICAgY2FzZSAnQyc6ICAoKnB0cikrKzsgIHJldHVybiBjaGFyX3R5cGVfbm9kZTsKICAgIGNhc2UgJ0QnOiAgKCpwdHIpKys7ICByZXR1cm4gZG91YmxlX3R5cGVfbm9kZTsKICAgIGNhc2UgJ0YnOiAgKCpwdHIpKys7ICByZXR1cm4gZmxvYXRfdHlwZV9ub2RlOwogICAgY2FzZSAnUyc6ICAoKnB0cikrKzsgIHJldHVybiBzaG9ydF90eXBlX25vZGU7CiAgICBjYXNlICdJJzogICgqcHRyKSsrOyAgcmV0dXJuIGludF90eXBlX25vZGU7CiAgICBjYXNlICdKJzogICgqcHRyKSsrOyAgcmV0dXJuIGxvbmdfdHlwZV9ub2RlOwogICAgY2FzZSAnWic6ICAoKnB0cikrKzsgIHJldHVybiBib29sZWFuX3R5cGVfbm9kZTsKICAgIGNhc2UgJ1YnOiAgKCpwdHIpKys7ICByZXR1cm4gdm9pZF90eXBlX25vZGU7CiAgICBjYXNlICdbJzoKICAgICAgZm9yICgoKnB0cikrKzsgKCpwdHIpIDwgbGltaXQgJiYgSVNESUdJVCAoKipwdHIpOyApICgqcHRyKSsrOwogICAgICB0eXBlID0gcGFyc2Vfc2lnbmF0dXJlX3R5cGUgKHB0ciwgbGltaXQpOwogICAgICB0eXBlID0gYnVpbGRfamF2YV9hcnJheV90eXBlICh0eXBlLCAtMSk7IAogICAgICBicmVhazsKICAgIGNhc2UgJ0wnOgogICAgICB7Cgljb25zdCB1bnNpZ25lZCBjaGFyICpzdGFydCA9ICsrKCpwdHIpOwoJY29uc3QgdW5zaWduZWQgY2hhciAqc3RyID0gc3RhcnQ7Cglmb3IgKCA7IDsgc3RyKyspCgkgIHsKCSAgICBpZiAoc3RyID49IGxpbWl0KQoJICAgICAgYWJvcnQgKCk7CgkgICAgaWYgKCpzdHIgPT0gJzsnKQoJICAgICAgYnJlYWs7CgkgIH0KCSpwdHIgPSBzdHIrMTsKCXR5cGUgPSBsb29rdXBfY2xhc3MgKHVubWFuZ2xlX2NsYXNzbmFtZSAoKGNvbnN0IGNoYXIgKikgc3RhcnQsIHN0ciAtIHN0YXJ0KSk7CglicmVhazsKICAgICAgfQogICAgZGVmYXVsdDoKICAgICAgYWJvcnQgKCk7CiAgICB9CiAgcmV0dXJuIHByb21vdGVfdHlwZSAodHlwZSk7Cn0KCi8qIFBhcnNlIGEgSmF2YSAibWFuZ2xlZCIgc2lnbmF0dXJlIHN0cmluZywgc3RhcnRpbmcgYXQgU0lHX1NUUklORywKICAgYW5kIFNJR19MRU5HVEggYnl0ZXMgbG9uZy4KICAgUmV0dXJuIGEgZ2NjIHR5cGUgbm9kZS4gKi8KCnRyZWUKcGFyc2Vfc2lnbmF0dXJlX3N0cmluZyAoY29uc3QgdW5zaWduZWQgY2hhciAqc2lnX3N0cmluZywgaW50IHNpZ19sZW5ndGgpCnsKICB0cmVlIHJlc3VsdF90eXBlOwogIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnN0ciA9IHNpZ19zdHJpbmc7CiAgY29uc3QgdW5zaWduZWQgY2hhciAqbGltaXQgPSBzdHIgKyBzaWdfbGVuZ3RoOwoKICBpZiAoc3RyIDwgbGltaXQgJiYgc3RyWzBdID09ICcoJykKICAgIHsKICAgICAgdHJlZSBhcmd0eXBlX2xpc3QgPSBOVUxMX1RSRUU7CiAgICAgIHN0cisrOwogICAgICB3aGlsZSAoc3RyIDwgbGltaXQgJiYgc3RyWzBdICE9ICcpJykKCXsKCSAgdHJlZSBhcmd0eXBlID0gcGFyc2Vfc2lnbmF0dXJlX3R5cGUgKCZzdHIsIGxpbWl0KTsKCSAgYXJndHlwZV9saXN0ID0gdHJlZV9jb25zIChOVUxMX1RSRUUsIGFyZ3R5cGUsIGFyZ3R5cGVfbGlzdCk7Cgl9CiAgICAgIGlmIChzdHIrKywgc3RyID49IGxpbWl0KQoJYWJvcnQgKCk7CiAgICAgIHJlc3VsdF90eXBlID0gcGFyc2Vfc2lnbmF0dXJlX3R5cGUgKCZzdHIsIGxpbWl0KTsKICAgICAgYXJndHlwZV9saXN0ID0gY2hhaW5vbiAobnJldmVyc2UgKGFyZ3R5cGVfbGlzdCksIGVuZF9wYXJhbXNfbm9kZSk7CiAgICAgIHJlc3VsdF90eXBlID0gYnVpbGRfZnVuY3Rpb25fdHlwZSAocmVzdWx0X3R5cGUsIGFyZ3R5cGVfbGlzdCk7CiAgICB9CiAgZWxzZQogICAgcmVzdWx0X3R5cGUgPSBwYXJzZV9zaWduYXR1cmVfdHlwZSAoJnN0ciwgbGltaXQpOwogIGlmIChzdHIgIT0gbGltaXQpCiAgICBlcnJvciAoImp1bmsgYXQgZW5kIG9mIHNpZ25hdHVyZSBzdHJpbmciKTsKICByZXR1cm4gcmVzdWx0X3R5cGU7Cn0KCi8qIENvbnZlcnQgYSBzaWduYXR1cmUgdG8gaXRzIHR5cGUuCiAqIFVzZXMgSURFTlRJRklFUl9TSUdOQVRVUkVfVFlQRSBhcyBhIGNhY2hlIChleGNlcHQgZm9yIHByaW1pdGl2ZSB0eXBlcykuCiAqLwoKdHJlZQpnZXRfdHlwZV9mcm9tX3NpZ25hdHVyZSAodHJlZSBzaWduYXR1cmUpCnsKICBjb25zdCB1bnNpZ25lZCBjaGFyICpzaWcgPSAoY29uc3QgdW5zaWduZWQgY2hhciAqKSBJREVOVElGSUVSX1BPSU5URVIgKHNpZ25hdHVyZSk7CiAgaW50IGxlbiA9IElERU5USUZJRVJfTEVOR1RIIChzaWduYXR1cmUpOwogIHRyZWUgdHlwZTsKICAvKiBQcmltaXRpdmUgdHlwZXMgYXJlbid0IGNhY2hlZC4gKi8KICBpZiAobGVuIDw9IDEpCiAgICByZXR1cm4gcGFyc2Vfc2lnbmF0dXJlX3N0cmluZyAoc2lnLCBsZW4pOwogIHR5cGUgPSBJREVOVElGSUVSX1NJR05BVFVSRV9UWVBFIChzaWduYXR1cmUpOwogIGlmICh0eXBlID09IE5VTExfVFJFRSkKICAgIHsKICAgICAgdHlwZSA9IHBhcnNlX3NpZ25hdHVyZV9zdHJpbmcgKHNpZywgbGVuKTsKICAgICAgSURFTlRJRklFUl9TSUdOQVRVUkVfVFlQRSAoc2lnbmF0dXJlKSA9IHR5cGU7CiAgICB9CiAgcmV0dXJuIHR5cGU7Cn0KCi8qIElnbm9yZSBzaWduYXR1cmUgYW5kIGFsd2F5cyByZXR1cm4gbnVsbC4gIFVzZWQgYnkgaGFzX21ldGhvZC4gKi8KCnN0YXRpYyB0cmVlCmJ1aWxkX251bGxfc2lnbmF0dXJlICh0cmVlIHR5cGUgQVRUUklCVVRFX1VOVVNFRCkKewogIHJldHVybiBOVUxMX1RSRUU7Cn0KCi8qIFJldHVybiB0aGUgc2lnbmF0dXJlIHN0cmluZyBmb3IgdGhlIGFyZ3VtZW50cyBvZiBtZXRob2QgdHlwZSBUWVBFLiAqLwoKdHJlZQpidWlsZF9qYXZhX2FyZ3VtZW50X3NpZ25hdHVyZSAodHJlZSB0eXBlKQp7CiAgZXh0ZXJuIHN0cnVjdCBvYnN0YWNrIHRlbXBvcmFyeV9vYnN0YWNrOwogIHRyZWUgc2lnID0gVFlQRV9BUkdVTUVOVF9TSUdOQVRVUkUgKHR5cGUpOwogIGlmIChzaWcgPT0gTlVMTF9UUkVFKQogICAgewogICAgICB0cmVlIGFyZ3MgPSBUWVBFX0FSR19UWVBFUyAodHlwZSk7CiAgICAgIGlmIChUUkVFX0NPREUgKHR5cGUpID09IE1FVEhPRF9UWVBFKQoJYXJncyA9IFRSRUVfQ0hBSU4gKGFyZ3MpOyAgLyogU2tpcCAidGhpcyIgYXJndW1lbnQuICovCiAgICAgIGZvciAoOyBhcmdzICE9IGVuZF9wYXJhbXNfbm9kZTsgYXJncyA9IFRSRUVfQ0hBSU4gKGFyZ3MpKQoJewoJICB0cmVlIHQgPSBidWlsZF9qYXZhX3NpZ25hdHVyZSAoVFJFRV9WQUxVRSAoYXJncykpOwoJICBvYnN0YWNrX2dyb3cgKCZ0ZW1wb3Jhcnlfb2JzdGFjaywKCQkJSURFTlRJRklFUl9QT0lOVEVSICh0KSwgSURFTlRJRklFUl9MRU5HVEggKHQpKTsKCX0KICAgICAgb2JzdGFja18xZ3JvdyAoJnRlbXBvcmFyeV9vYnN0YWNrLCAnXDAnKTsKCiAgICAgIHNpZyA9IGdldF9pZGVudGlmaWVyIChvYnN0YWNrX2Jhc2UgKCZ0ZW1wb3Jhcnlfb2JzdGFjaykpOwogICAgICBUWVBFX0FSR1VNRU5UX1NJR05BVFVSRSAodHlwZSkgPSBzaWc7CiAgICAgIG9ic3RhY2tfZnJlZSAoJnRlbXBvcmFyeV9vYnN0YWNrLCBvYnN0YWNrX2Jhc2UgKCZ0ZW1wb3Jhcnlfb2JzdGFjaykpOwogICAgfQogIHJldHVybiBzaWc7Cn0KCi8qIFJldHVybiB0aGUgc2lnbmF0dXJlIG9mIHRoZSBnaXZlbiBUWVBFLiAqLwoKdHJlZQpidWlsZF9qYXZhX3NpZ25hdHVyZSAodHJlZSB0eXBlKQp7CiAgdHJlZSBzaWcsIHQ7CiAgd2hpbGUgKFRSRUVfQ09ERSAodHlwZSkgPT0gUE9JTlRFUl9UWVBFKQogICAgdHlwZSA9IFRSRUVfVFlQRSAodHlwZSk7CiAgTUFZQkVfQ1JFQVRFX1RZUEVfVFlQRV9MQU5HX1NQRUNJRklDICh0eXBlKTsKICBzaWcgPSBUWVBFX1NJR05BVFVSRSAodHlwZSk7CiAgaWYgKHNpZyA9PSBOVUxMX1RSRUUpCiAgICB7CiAgICAgIGNoYXIgc2dbMl07CiAgICAgIHN3aXRjaCAoVFJFRV9DT0RFICh0eXBlKSkKCXsKCWNhc2UgQk9PTEVBTl9UWVBFOiBzZ1swXSA9ICdaJzsgIGdvdG8gbmF0aXZlOwoJY2FzZSBDSEFSX1RZUEU6ICAgIHNnWzBdID0gJ0MnOyAgZ290byBuYXRpdmU7CgljYXNlIFZPSURfVFlQRTogICAgc2dbMF0gPSAnVic7ICBnb3RvIG5hdGl2ZTsKCWNhc2UgSU5URUdFUl9UWVBFOgoJICBzd2l0Y2ggKFRZUEVfUFJFQ0lTSU9OICh0eXBlKSkKCSAgICB7CgkgICAgY2FzZSAgODogICAgICAgc2dbMF0gPSAnQic7ICBnb3RvIG5hdGl2ZTsKCSAgICBjYXNlIDE2OiAgICAgICBzZ1swXSA9ICdTJzsgIGdvdG8gbmF0aXZlOwoJICAgIGNhc2UgMzI6ICAgICAgIHNnWzBdID0gJ0knOyAgZ290byBuYXRpdmU7CgkgICAgY2FzZSA2NDogICAgICAgc2dbMF0gPSAnSic7ICBnb3RvIG5hdGl2ZTsKCSAgICBkZWZhdWx0OiAgZ290byBiYWRfdHlwZTsKCSAgICB9CgljYXNlIFJFQUxfVFlQRToKCSAgc3dpdGNoIChUWVBFX1BSRUNJU0lPTiAodHlwZSkpCgkgICAgewoJICAgIGNhc2UgMzI6ICAgICAgIHNnWzBdID0gJ0YnOyAgZ290byBuYXRpdmU7CgkgICAgY2FzZSA2NDogICAgICAgc2dbMF0gPSAnRCc7ICBnb3RvIG5hdGl2ZTsKCSAgICBkZWZhdWx0OiAgZ290byBiYWRfdHlwZTsKCSAgICB9CgluYXRpdmU6CgkgIHNnWzFdID0gMDsKCSAgc2lnID0gZ2V0X2lkZW50aWZpZXIgKHNnKTsKCSAgYnJlYWs7CgljYXNlIFJFQ09SRF9UWVBFOgoJICBpZiAoVFlQRV9BUlJBWV9QICh0eXBlKSkKCSAgICB7CgkgICAgICB0ID0gYnVpbGRfamF2YV9zaWduYXR1cmUgKFRZUEVfQVJSQVlfRUxFTUVOVCAodHlwZSkpOwoJICAgICAgc2lnID0gaWRlbnRfc3Vic3QgKElERU5USUZJRVJfUE9JTlRFUiAodCksIElERU5USUZJRVJfTEVOR1RIICh0KSwKCQkJCSAiWyIsIDAsIDAsICIiKTsKCSAgICB9CgkgIGVsc2UKCSAgICB7CgkgICAgICB0ID0gREVDTF9OQU1FIChUWVBFX05BTUUgKHR5cGUpKTsKCSAgICAgIHNpZyA9IGlkZW50X3N1YnN0IChJREVOVElGSUVSX1BPSU5URVIgKHQpLCBJREVOVElGSUVSX0xFTkdUSCAodCksCgkJCQkgIkwiLCAnLicsICcvJywgIjsiKTsKCSAgICB9CgkgIGJyZWFrOwoJY2FzZSBNRVRIT0RfVFlQRToKCWNhc2UgRlVOQ1RJT05fVFlQRToKCSAgewoJICAgIGV4dGVybiBzdHJ1Y3Qgb2JzdGFjayB0ZW1wb3Jhcnlfb2JzdGFjazsKCSAgICBzaWcgPSBidWlsZF9qYXZhX2FyZ3VtZW50X3NpZ25hdHVyZSAodHlwZSk7CgkgICAgb2JzdGFja18xZ3JvdyAoJnRlbXBvcmFyeV9vYnN0YWNrLCAnKCcpOwoJICAgIG9ic3RhY2tfZ3JvdyAoJnRlbXBvcmFyeV9vYnN0YWNrLAoJCQkgIElERU5USUZJRVJfUE9JTlRFUiAoc2lnKSwgSURFTlRJRklFUl9MRU5HVEggKHNpZykpOwoJICAgIG9ic3RhY2tfMWdyb3cgKCZ0ZW1wb3Jhcnlfb2JzdGFjaywgJyknKTsKCgkgICAgdCA9IGJ1aWxkX2phdmFfc2lnbmF0dXJlIChUUkVFX1RZUEUgKHR5cGUpKTsKCSAgICBvYnN0YWNrX2dyb3cwICgmdGVtcG9yYXJ5X29ic3RhY2ssCgkJCSAgIElERU5USUZJRVJfUE9JTlRFUiAodCksIElERU5USUZJRVJfTEVOR1RIICh0KSk7CgoJICAgIHNpZyA9IGdldF9pZGVudGlmaWVyIChvYnN0YWNrX2Jhc2UgKCZ0ZW1wb3Jhcnlfb2JzdGFjaykpOwoJICAgIG9ic3RhY2tfZnJlZSAoJnRlbXBvcmFyeV9vYnN0YWNrLAoJCQkgIG9ic3RhY2tfYmFzZSAoJnRlbXBvcmFyeV9vYnN0YWNrKSk7CgkgIH0KCSAgYnJlYWs7CgliYWRfdHlwZToKCWRlZmF1bHQ6CgkgIGFib3J0ICgpOwoJfQogICAgICBUWVBFX1NJR05BVFVSRSAodHlwZSkgPSBzaWc7CiAgICB9CiAgcmV0dXJuIHNpZzsKfQoKLyogU2F2ZSBzaWduYXR1cmUgc3RyaW5nIFNJRyAoYW4gSURFTlRJRklFUl9OT0RFKSBpbiBUWVBFIGZvciBmdXR1cmUgdXNlLiAqLwoKdm9pZApzZXRfamF2YV9zaWduYXR1cmUgKHRyZWUgdHlwZSwgdHJlZSBzaWcpCnsKICB0cmVlIG9sZF9zaWc7CiAgd2hpbGUgKFRSRUVfQ09ERSAodHlwZSkgPT0gUE9JTlRFUl9UWVBFKQogICAgdHlwZSA9IFRSRUVfVFlQRSAodHlwZSk7CiAgTUFZQkVfQ1JFQVRFX1RZUEVfVFlQRV9MQU5HX1NQRUNJRklDICh0eXBlKTsKICBvbGRfc2lnID0gVFlQRV9TSUdOQVRVUkUgKHR5cGUpOwogIGlmIChvbGRfc2lnICE9IE5VTExfVFJFRSAmJiBvbGRfc2lnICE9IHNpZykKICAgIGFib3J0ICgpOwogIFRZUEVfU0lHTkFUVVJFICh0eXBlKSA9IHNpZzsKI2lmIDAgLyogY2FyZWZ1bCBhYm91dCBNRVRIT0RfVFlQRSAqLwogIGlmIChJREVOVElGSUVSX1NJR05BVFVSRV9UWVBFIChzaWcpID09IE5VTExfVFJFRSAmJiBUUkVFX1BFUk1BTkVOVCAodHlwZSkpCiAgICBJREVOVElGSUVSX1NJR05BVFVSRV9UWVBFIChzaWcpID0gdHlwZTsKI2VuZGlmCn0KCi8qIFNlYXJjaCBpbiBTRUFSQ0hFRF9DTEFTUyBhbmQgaXRzIHN1cGVyY2xhc3NlcyBmb3IgYSBtZXRob2QgbWF0Y2hpbmcKICAgTUVUSE9EX05BTUUgYW5kIHNpZ25hdHVyZSBNRVRIT0RfU0lHTkFUVVJFLiAgVGhpcyBmdW5jdGlvbiB3aWxsCiAgIG9ubHkgc2VhcmNoIGZvciBtZXRob2RzIGRlY2xhcmVkIGluIHRoZSBjbGFzcyBoaWVyYXJjaHk7IGludGVyZmFjZXMKICAgd2lsbCBub3QgYmUgY29uc2lkZXJlZC4gIFJldHVybnMgTlVMTF9UUkVFIGlmIHRoZSBtZXRob2QgaXMgbm90CiAgIGZvdW5kLiAgKi8KdHJlZQpsb29rdXBfYXJndW1lbnRfbWV0aG9kICh0cmVlIHNlYXJjaGVkX2NsYXNzLCB0cmVlIG1ldGhvZF9uYW1lLAoJCQl0cmVlIG1ldGhvZF9zaWduYXR1cmUpCnsKICByZXR1cm4gbG9va3VwX2RvIChzZWFyY2hlZF9jbGFzcywgMCwKCQkgICAgbWV0aG9kX25hbWUsIG1ldGhvZF9zaWduYXR1cmUsIAoJCSAgICBidWlsZF9qYXZhX2FyZ3VtZW50X3NpZ25hdHVyZSk7Cn0KCi8qIExpa2UgbG9va3VwX2FyZ3VtZW50X21ldGhvZCwgYnV0IGxldHMgdGhlIGNhbGxlciBzZXQgYW55IGZsYWdzCiAgIGRlc2lyZWQuICAqLwp0cmVlCmxvb2t1cF9hcmd1bWVudF9tZXRob2RfZ2VuZXJpYyAodHJlZSBzZWFyY2hlZF9jbGFzcywgdHJlZSBtZXRob2RfbmFtZSwKCQkJCXRyZWUgbWV0aG9kX3NpZ25hdHVyZSwgaW50IGZsYWdzKQp7CiAgcmV0dXJuIGxvb2t1cF9kbyAoc2VhcmNoZWRfY2xhc3MsIGZsYWdzLAoJCSAgICBtZXRob2RfbmFtZSwgbWV0aG9kX3NpZ25hdHVyZSwgCgkJICAgIGJ1aWxkX2phdmFfYXJndW1lbnRfc2lnbmF0dXJlKTsKfQoKCi8qIFNlYXJjaCBpbiBjbGFzcyBTRUFSQ0hFRF9DTEFTUyAoYW5kIGl0cyBzdXBlcmNsYXNzZXMpIGZvciBhIG1ldGhvZAogICBtYXRjaGluZyBNRVRIT0RfTkFNRSBhbmQgc2lnbmF0dXJlIE1FVEhPRF9TSUdOQVRVUkUuICBSZXR1cm4gYQogICBGVU5DVElPTl9ERUNMIG9uIHN1Y2Nlc3MsIG9yIE5VTExfVFJFRSBpZiBub25lIGZvdW5kLiAgKENvbnRyYXN0CiAgIGxvb2t1cF9hcmd1bWVudF9tZXRob2QsIHdoaWNoIGlnbm9yZXMgcmV0dXJuIHR5cGUuKSAgSWYKICAgU0VBUkNIRURfQ0xBU1MgaXMgYW4gaW50ZXJmYWNlLCBzZWFyY2ggaXQgdG9vLiAqLwp0cmVlCmxvb2t1cF9qYXZhX21ldGhvZCAodHJlZSBzZWFyY2hlZF9jbGFzcywgdHJlZSBtZXRob2RfbmFtZSwKCQkgICAgdHJlZSBtZXRob2Rfc2lnbmF0dXJlKQp7CiAgcmV0dXJuIGxvb2t1cF9kbyAoc2VhcmNoZWRfY2xhc3MsIFNFQVJDSF9JTlRFUkZBQ0UsIG1ldGhvZF9uYW1lLCAKCQkgICAgbWV0aG9kX3NpZ25hdHVyZSwgYnVpbGRfamF2YV9zaWduYXR1cmUpOwp9CgovKiBSZXR1cm4gdHJ1ZSBpZmYgQ0xBU1MgKG9yIGl0cyBhbmNlc3RvcnMpIGhhcyBhIG1ldGhvZCBNRVRIT0RfTkFNRS4goCovCmludApoYXNfbWV0aG9kICh0cmVlIGNsYXNzLCB0cmVlIG1ldGhvZF9uYW1lKQp7CiAgcmV0dXJuIGxvb2t1cF9kbyAoY2xhc3MsIFNFQVJDSF9JTlRFUkZBQ0UsCgkJICAgIG1ldGhvZF9uYW1lLCBOVUxMX1RSRUUsCgkJICAgIGJ1aWxkX251bGxfc2lnbmF0dXJlKSAhPSBOVUxMX1RSRUU7Cn0KCi8qIFNlYXJjaCBpbiBjbGFzcyBTRUFSQ0hFRF9DTEFTUywgYnV0IG5vdCBpdHMgc3VwZXJjbGFzc2VzLCBmb3IgYQogICBtZXRob2QgbWF0Y2hpbmcgTUVUSE9EX05BTUUgYW5kIHNpZ25hdHVyZSBTSUdOQVRVUkUuICBBIHByaXZhdGUKICAgaGVscGVyIGZvciBsb29rdXBfZG8uICAqLwpzdGF0aWMgdHJlZQpzaGFsbG93X2ZpbmRfbWV0aG9kICh0cmVlIHNlYXJjaGVkX2NsYXNzLCBpbnQgZmxhZ3MsIHRyZWUgbWV0aG9kX25hbWUsIAoJICAgICB0cmVlIHNpZ25hdHVyZSwgdHJlZSAoKnNpZ25hdHVyZV9idWlsZGVyKSAodHJlZSkpCnsKICB0cmVlIG1ldGhvZDsKICBmb3IgKG1ldGhvZCA9IFRZUEVfTUVUSE9EUyAoc2VhcmNoZWRfY2xhc3MpOwogICAgICAgbWV0aG9kICE9IE5VTExfVFJFRTsgIG1ldGhvZCA9IFRSRUVfQ0hBSU4gKG1ldGhvZCkpCiAgICB7CiAgICAgIHRyZWUgbWV0aG9kX3NpZyA9ICgqc2lnbmF0dXJlX2J1aWxkZXIpIChUUkVFX1RZUEUgKG1ldGhvZCkpOwogICAgICBpZiAoREVDTF9OQU1FIChtZXRob2QpID09IG1ldGhvZF9uYW1lICYmIG1ldGhvZF9zaWcgPT0gc2lnbmF0dXJlKQoJewoJICAvKiBJZiB0aGUgY2FsbGVyIHJlcXVpcmVzIGEgdmlzaWJsZSBtZXRob2QsIHRoZW4gd2UKCSAgICAgc2tpcCBpbnZpc2libGUgbWV0aG9kcyBoZXJlLiAgKi8KCSAgaWYgKCEgKGZsYWdzICYgU0VBUkNIX1ZJU0lCTEUpCgkgICAgICB8fCAhIE1FVEhPRF9JTlZJU0lCTEUgKG1ldGhvZCkpCgkgICAgcmV0dXJuIG1ldGhvZDsKCX0KICAgIH0KICByZXR1cm4gTlVMTF9UUkVFOwp9CgovKiBTZWFyY2ggaW4gdGhlIHN1cGVyY2xhc3NlcyBvZiBTRUFSQ0hFRF9DTEFTUyBmb3IgYSBtZXRob2QgbWF0Y2hpbmcKICAgTUVUSE9EX05BTUUgYW5kIHNpZ25hdHVyZSBTSUdOQVRVUkUuICBBIHByaXZhdGUgaGVscGVyIGZvcgogICBsb29rdXBfZG8uICAqLwpzdGF0aWMgdHJlZQpmaW5kX21ldGhvZF9pbl9zdXBlcmNsYXNzZXMgKHRyZWUgc2VhcmNoZWRfY2xhc3MsIGludCBmbGFncywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZSBtZXRob2RfbmFtZSwgdHJlZSBzaWduYXR1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZSAoKnNpZ25hdHVyZV9idWlsZGVyKSAodHJlZSkpCnsKICB0cmVlIGtsYXNzOwogIGZvciAoa2xhc3MgPSBDTEFTU1RZUEVfU1VQRVIgKHNlYXJjaGVkX2NsYXNzKTsga2xhc3MgIT0gTlVMTF9UUkVFOwogICAgICAga2xhc3MgPSBDTEFTU1RZUEVfU1VQRVIgKGtsYXNzKSkKICAgIHsKICAgICAgdHJlZSBtZXRob2Q7CiAgICAgIG1ldGhvZCA9IHNoYWxsb3dfZmluZF9tZXRob2QgKGtsYXNzLCBmbGFncywgbWV0aG9kX25hbWUsIAoJCQkJICAgIHNpZ25hdHVyZSwgc2lnbmF0dXJlX2J1aWxkZXIpOwogICAgICBpZiAobWV0aG9kICE9IE5VTExfVFJFRSkKCXJldHVybiBtZXRob2Q7CiAgICB9CgogIHJldHVybiBOVUxMX1RSRUU7Cn0KCi8qIFNlYXJjaCBpbiB0aGUgaW50ZXJmYWNlcyBvZiBTRUFSQ0hFRF9DTEFTUyBhbmQgaXRzIHN1cGVyaW50ZXJmYWNlcwogICBmb3IgYSBtZXRob2QgbWF0Y2hpbmcgTUVUSE9EX05BTUUgYW5kIHNpZ25hdHVyZSBTSUdOQVRVUkUuICBBCiAgIHByaXZhdGUgaGVscGVyIGZvciBsb29rdXBfZG8uICAqLwpzdGF0aWMgdHJlZQpmaW5kX21ldGhvZF9pbl9pbnRlcmZhY2VzICh0cmVlIHNlYXJjaGVkX2NsYXNzLCBpbnQgZmxhZ3MsIHRyZWUgbWV0aG9kX25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUgc2lnbmF0dXJlLCB0cmVlICgqc2lnbmF0dXJlX2J1aWxkZXIpICh0cmVlKSkKewogIGludCBpOwogIHRyZWUgYmluZm8sIGJhc2VfYmluZm87CgogIGZvciAoYmluZm8gPSBUWVBFX0JJTkZPIChzZWFyY2hlZF9jbGFzcyksIGkgPSAxOwogICAgICAgQklORk9fQkFTRV9JVEVSQVRFIChiaW5mbywgaSwgYmFzZV9iaW5mbyk7IGkrKykKICAgIHsKICAgICAgdHJlZSBpY2xhc3MgPSBCSU5GT19UWVBFIChiYXNlX2JpbmZvKTsKICAgICAgdHJlZSBtZXRob2Q7CgkgIAogICAgICAvKiBJZiB0aGUgc3VwZXJpbnRlcmZhY2UgaGFzbid0IGJlZW4gbG9hZGVkIHlldCwgZG8gc28gbm93LiAgKi8KICAgICAgaWYgKENMQVNTX0ZST01fU09VUkNFX1AgKGljbGFzcykpCglzYWZlX2xheW91dF9jbGFzcyAoaWNsYXNzKTsKICAgICAgZWxzZSBpZiAoIUNMQVNTX0xPQURFRF9QIChpY2xhc3MpKQoJbG9hZF9jbGFzcyAoaWNsYXNzLCAxKTsKCSAgCiAgICAgIC8qIEZpcnN0LCB3ZSBsb29rIGluIElDTEFTUy4gIElmIHRoYXQgZG9lc24ndCB3b3JrIHdlJ2xsCgkgcmVjdXJzaXZlbHkgbG9vayB0aHJvdWdoIGFsbCBpdHMgc3VwZXJpbnRlcmZhY2VzLiAgKi8KICAgICAgbWV0aG9kID0gc2hhbGxvd19maW5kX21ldGhvZCAoaWNsYXNzLCBmbGFncywgbWV0aG9kX25hbWUsIAoJCQkJICAgIHNpZ25hdHVyZSwgc2lnbmF0dXJlX2J1aWxkZXIpOyAgICAgIAogICAgICBpZiAobWV0aG9kICE9IE5VTExfVFJFRSkKCXJldHVybiBtZXRob2Q7CiAgCiAgICAgIG1ldGhvZCA9IGZpbmRfbWV0aG9kX2luX2ludGVyZmFjZXMgCgkoaWNsYXNzLCBmbGFncywgbWV0aG9kX25hbWUsIHNpZ25hdHVyZSwgc2lnbmF0dXJlX2J1aWxkZXIpOwogICAgICBpZiAobWV0aG9kICE9IE5VTExfVFJFRSkKCXJldHVybiBtZXRob2Q7CiAgICB9CiAgCiAgcmV0dXJuIE5VTExfVFJFRTsKfQoKCi8qIFNlYXJjaCBpbiBjbGFzcyBTRUFSQ0hFRF9DTEFTUyAoYW5kIGl0cyBzdXBlcmNsYXNzZXMpIGZvciBhIG1ldGhvZAogICBtYXRjaGluZyBNRVRIT0RfTkFNRSBhbmQgc2lnbmF0dXJlIFNJR05BVFVSRS4gIEZMQUdTIGNvbnRyb2wgc29tZQogICBwYXJhbWV0ZXJzIG9mIHRoZSBzZWFyY2guCiAgIAogICBTRUFSQ0hfSU5URVJGQUNFIG1lYW5zIGFsc28gc2VhcmNoIGludGVyZmFjZXMgYW5kIHN1cGVyaW50ZXJmYWNlcwogICBvZiBTRUFSQ0hFRF9DTEFTUy4KICAgCiAgIFNFQVJDSF9TVVBFUiBtZWFucyBza2lwIFNFQVJDSEVEX0NMQVNTIGFuZCBzdGFydCB3aXRoIGl0cwogICBzdXBlcmNsYXNzLgogICAKICAgU0VBUkNIX1ZJU0lCTEUgbWVhbnMgc2tpcCBtZXRob2RzIGZvciB3aGljaCBNRVRIT0RfSU5WSVNJQkxFIGlzCiAgIHNldC4KCiAgIFJldHVybiB0aGUgbWF0Y2hlZCBtZXRob2QgREVDTCBvciBOVUxMX1RSRUUuICBTSUdOQVRVUkVfQlVJTERFUiBpcwogICB1c2VkIG9uIG1ldGhvZCBjYW5kaWRhdGVzIHRvIGJ1aWxkIHRoZWlyIChzb21ldGltZXMgcGFydGlhbCkKICAgc2lnbmF0dXJlLiAgKi8Kc3RhdGljIHRyZWUKbG9va3VwX2RvICh0cmVlIHNlYXJjaGVkX2NsYXNzLCBpbnQgZmxhZ3MsIHRyZWUgbWV0aG9kX25hbWUsCgkgICB0cmVlIHNpZ25hdHVyZSwgdHJlZSAoKnNpZ25hdHVyZV9idWlsZGVyKSAodHJlZSkpCnsKICB0cmVlIG1ldGhvZDsKICAgIAogIGlmIChzZWFyY2hlZF9jbGFzcyA9PSBOVUxMX1RSRUUpCiAgICByZXR1cm4gTlVMTF9UUkVFOwoKICBpZiAoZmxhZ3MgJiBTRUFSQ0hfU1VQRVIpCiAgICB7CiAgICAgIHNlYXJjaGVkX2NsYXNzID0gQ0xBU1NUWVBFX1NVUEVSIChzZWFyY2hlZF9jbGFzcyk7CiAgICAgIGlmIChzZWFyY2hlZF9jbGFzcyA9PSBOVUxMX1RSRUUpCglyZXR1cm4gTlVMTF9UUkVFOwogICAgfQoKICAvKiBGaXJzdCBsb29rIGluIG91ciBvd24gbWV0aG9kcy4gICovCiAgbWV0aG9kID0gc2hhbGxvd19maW5kX21ldGhvZCAoc2VhcmNoZWRfY2xhc3MsIGZsYWdzLCBtZXRob2RfbmFtZSwKCQkJCXNpZ25hdHVyZSwgc2lnbmF0dXJlX2J1aWxkZXIpOyAgCiAgaWYgKG1ldGhvZCkKICAgIHJldHVybiBtZXRob2Q7CgogIC8qIFRoZW4gbG9vayBpbiBvdXIgc3VwZXJjbGFzc2VzLiAgKi8KICBpZiAoISBDTEFTU19JTlRFUkZBQ0UgKFRZUEVfTkFNRSAoc2VhcmNoZWRfY2xhc3MpKSkKICAgIG1ldGhvZCA9IGZpbmRfbWV0aG9kX2luX3N1cGVyY2xhc3NlcyAoc2VhcmNoZWRfY2xhc3MsIGZsYWdzLCBtZXRob2RfbmFtZSwKCQkJCQkgIHNpZ25hdHVyZSwgc2lnbmF0dXJlX2J1aWxkZXIpOyAgCiAgaWYgKG1ldGhvZCkKICAgIHJldHVybiBtZXRob2Q7CiAgCiAgLyogSWYgdGhhdCBkb2Vzbid0IHdvcmssIGxvb2sgaW4gb3VyIGludGVyZmFjZXMuICAqLwogIGlmIChmbGFncyAmIFNFQVJDSF9JTlRFUkZBQ0UpCiAgICBtZXRob2QgPSBmaW5kX21ldGhvZF9pbl9pbnRlcmZhY2VzIChzZWFyY2hlZF9jbGFzcywgZmxhZ3MsIG1ldGhvZF9uYW1lLCAKCQkJCQlzaWduYXR1cmUsIHNpZ25hdHVyZV9idWlsZGVyKTsKICAKICByZXR1cm4gbWV0aG9kOwp9CgovKiBTZWFyY2ggaW4gY2xhc3MgQ0xBUyBmb3IgYSBjb25zdHJ1Y3RvciBtYXRjaGluZyBNRVRIT0RfU0lHTkFUVVJFLgogICBSZXR1cm4gYSBGVU5DVElPTl9ERUNMIG9uIHN1Y2Nlc3MsIG9yIE5VTExfVFJFRSBpZiBub25lIGZvdW5kLiAqLwoKdHJlZQpsb29rdXBfamF2YV9jb25zdHJ1Y3RvciAodHJlZSBjbGFzLCB0cmVlIG1ldGhvZF9zaWduYXR1cmUpCnsKICB0cmVlIG1ldGhvZCA9IFRZUEVfTUVUSE9EUyAoY2xhcyk7CiAgZm9yICggOyBtZXRob2QgIT0gTlVMTF9UUkVFOyAgbWV0aG9kID0gVFJFRV9DSEFJTiAobWV0aG9kKSkKICAgIHsKICAgICAgdHJlZSBtZXRob2Rfc2lnID0gYnVpbGRfamF2YV9zaWduYXR1cmUgKFRSRUVfVFlQRSAobWV0aG9kKSk7CiAgICAgIGlmIChERUNMX0NPTlNUUlVDVE9SX1AgKG1ldGhvZCkgJiYgbWV0aG9kX3NpZyA9PSBtZXRob2Rfc2lnbmF0dXJlKQoJcmV0dXJuIG1ldGhvZDsKICAgIH0KICByZXR1cm4gTlVMTF9UUkVFOwp9CgovKiBSZXR1cm4gYSB0eXBlIHdoaWNoIGlzIHRoZSBCaW5hcnkgTnVtZXJpYyBQcm9tb3Rpb24gb2YgdGhlIHBhaXIgVDEsCiAgIFQyIGFuZCBjb252ZXJ0IEVYUDEgYW5kL29yIEVYUDIuIFNlZSA1LjYuMiBCaW5hcnkgTnVtZXJpYwogICBQcm9tb3Rpb24uIEl0IGFzc3VtZXMgdGhhdCBib3RoIFQxIGFuZCBUMiBhcmUgZWxpZ2libGUgdG8gQk5QLiAqLwoKdHJlZQpiaW5hcnlfbnVtZXJpY19wcm9tb3Rpb24gKHRyZWUgdDEsIHRyZWUgdDIsIHRyZWUgKmV4cDEsIHRyZWUgKmV4cDIpCnsKICBpZiAodDEgPT0gZG91YmxlX3R5cGVfbm9kZSB8fCB0MiA9PSBkb3VibGVfdHlwZV9ub2RlKQogICAgewogICAgICBpZiAodDEgIT0gZG91YmxlX3R5cGVfbm9kZSkKCSpleHAxID0gY29udmVydCAoZG91YmxlX3R5cGVfbm9kZSwgKmV4cDEpOwogICAgICBpZiAodDIgIT0gZG91YmxlX3R5cGVfbm9kZSkKCSpleHAyID0gY29udmVydCAoZG91YmxlX3R5cGVfbm9kZSwgKmV4cDIpOwogICAgICByZXR1cm4gZG91YmxlX3R5cGVfbm9kZTsKICAgIH0KICBpZiAodDEgPT0gZmxvYXRfdHlwZV9ub2RlIHx8IHQyID09IGZsb2F0X3R5cGVfbm9kZSkKICAgIHsKICAgICAgaWYgKHQxICE9IGZsb2F0X3R5cGVfbm9kZSkKCSpleHAxID0gY29udmVydCAoZmxvYXRfdHlwZV9ub2RlLCAqZXhwMSk7CiAgICAgIGlmICh0MiAhPSBmbG9hdF90eXBlX25vZGUpCgkqZXhwMiA9IGNvbnZlcnQgKGZsb2F0X3R5cGVfbm9kZSwgKmV4cDIpOwogICAgICByZXR1cm4gZmxvYXRfdHlwZV9ub2RlOwogICAgfQogIGlmICh0MSA9PSBsb25nX3R5cGVfbm9kZSB8fCB0MiA9PSBsb25nX3R5cGVfbm9kZSkKICAgIHsKICAgICAgaWYgKHQxICE9IGxvbmdfdHlwZV9ub2RlKQoJKmV4cDEgPSBjb252ZXJ0IChsb25nX3R5cGVfbm9kZSwgKmV4cDEpOwogICAgICBpZiAodDIgIT0gbG9uZ190eXBlX25vZGUpCgkqZXhwMiA9IGNvbnZlcnQgKGxvbmdfdHlwZV9ub2RlLCAqZXhwMik7CiAgICAgIHJldHVybiBsb25nX3R5cGVfbm9kZTsKICAgIH0KCiAgaWYgKHQxICE9IGludF90eXBlX25vZGUpCiAgICAqZXhwMSA9IGNvbnZlcnQgKGludF90eXBlX25vZGUsICpleHAxKTsKICBpZiAodDIgIT0gaW50X3R5cGVfbm9kZSkKICAgICpleHAyID0gY29udmVydCAoaW50X3R5cGVfbm9kZSwgKmV4cDIpOwogIHJldHVybiBpbnRfdHlwZV9ub2RlOwp9Cg==