LyoKICogQ29weXJpZ2h0IDE5OTggTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAwIEJyYWRsZXkgQmFldHoKICogQ29weXJpZ2h0IDIwMDMgTWljaGFlbCBH/G5uZXdpZwogKiBDb3B5cmlnaHQgMjAwNSBEbWl0cnkgVGltb3Noa292CiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKgogKiBGSVhNRTogVGhpcyBhbGwgYXNzdW1lcyAzMiBiaXQgY29kZWNzCiAqCQlXaW45NSBhcHBlYXJzIHRvIHByZWZlciAzMiBiaXQgY29kZWNzLCBldmVuIGZyb20gMTYgYml0IGNvZGUuCiAqCQlUaGVyZSBpcyB0aGUgSUNPcGVuRnVuY3Rpb24xNiB0byB3b3JyeSBhYm91dCBzdGlsbCwgdGhvdWdoLgogKiAgICAgIAogKiBUT0RPCiAqICAgICAgLSBubyB0aHJlYWQgc2FmZXR5CiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAiY29tbWRsZy5oIgojaW5jbHVkZSAidmZ3LmgiCiNpbmNsdWRlICJtc3ZpZGVvX3ByaXZhdGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCi8qIERyaXZlcnMzMiBzZXR0aW5ncyAqLwojZGVmaW5lIEhLTE1fRFJJVkVSUzMyICJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzIE5UXFxDdXJyZW50VmVyc2lvblxcRHJpdmVyczMyIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwobXN2aWRlbyk7CgpzdGF0aWMgaW5saW5lIGNvbnN0IGNoYXIgKndpbmVfZGJnc3RyX2ZjYyggRFdPUkQgZmNjICkKewogICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoIiVjJWMlYyVjIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT0JZVEUoTE9XT1JEKGZjYykpLCBISUJZVEUoTE9XT1JEKGZjYykpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9CWVRFKEhJV09SRChmY2MpKSwgSElCWVRFKEhJV09SRChmY2MpKSk7Cn0KCkxSRVNVTFQgKENBTExCQUNLICpwRm5DYWxsVG8xNikoSERSVlIsIEhJQywgVUlOVCwgTFBBUkFNLCBMUEFSQU0pID0gTlVMTDsKCnN0YXRpYyBXSU5FX0hJQyogICAgICAgIE1TVklERU9fRmlyc3RIaWMgLyogPSBOVUxMICovOwoKdHlwZWRlZiBzdHJ1Y3QgX3JlZ19kcml2ZXIgcmVnX2RyaXZlcjsKc3RydWN0IF9yZWdfZHJpdmVyCnsKICAgIERXT1JEICAgICAgIGZjY1R5cGU7CiAgICBEV09SRCAgICAgICBmY2NIYW5kbGVyOwogICAgRFJJVkVSUFJPQyAgcHJvYzsKICAgIExQV1NUUiAgICAgIG5hbWU7CiAgICByZWdfZHJpdmVyKiBuZXh0Owp9OwoKc3RhdGljIHJlZ19kcml2ZXIqIHJlZ19kcml2ZXJfbGlzdCA9IE5VTEw7CgovKiBUaGlzIG9uZSBpcyBhIG1hY3JvIHN1Y2ggdGhhdCBpdCB3b3JrcyBmb3IgYm90aCBBU0NJSSBhbmQgVW5pY29kZSAqLwojZGVmaW5lIGZvdXJjY190b19zdHJpbmcoc3RyLCBmY2MpIGRvIHsgXAoJKHN0cilbMF0gPSBMT0JZVEUoTE9XT1JEKGZjYykpOyBcCgkoc3RyKVsxXSA9IEhJQllURShMT1dPUkQoZmNjKSk7IFwKCShzdHIpWzJdID0gTE9CWVRFKEhJV09SRChmY2MpKTsgXAoJKHN0cilbM10gPSBISUJZVEUoSElXT1JEKGZjYykpOyBcCgl9IHdoaWxlKDApCgpITU9EVUxFIE1TVkZXMzJfaE1vZHVsZTsKCkJPT0wgV0lOQVBJIERsbE1haW4oIEhJTlNUQU5DRSBoaW5zdCwgRFdPUkQgcmVhc29uLCBMUFZPSUQgcmVzZXJ2ZWQgKQp7CiAgICBUUkFDRSgiJXAsJXgsJXBcbiIsIGhpbnN0LCByZWFzb24sIHJlc2VydmVkKTsKCiAgICBzd2l0Y2gocmVhc29uKQogICAgewogICAgICAgIGNhc2UgRExMX1BST0NFU1NfQVRUQUNIOgogICAgICAgICAgICBEaXNhYmxlVGhyZWFkTGlicmFyeUNhbGxzKGhpbnN0KTsKICAgICAgICAgICAgTVNWRlczMl9oTW9kdWxlID0gKEhNT0RVTEUpaGluc3Q7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBpbnQgY29tcGFyZV9mb3VyY2MoRFdPUkQgZmNjMSwgRFdPUkQgZmNjMikKewogIGNoYXIgZmNjX3N0cjFbNF07CiAgY2hhciBmY2Nfc3RyMls0XTsKICBmb3VyY2NfdG9fc3RyaW5nKGZjY19zdHIxLCBmY2MxKTsKICBmb3VyY2NfdG9fc3RyaW5nKGZjY19zdHIyLCBmY2MyKTsKICByZXR1cm4gc3RybmNhc2VjbXAoZmNjX3N0cjEsIGZjY19zdHIyLCA0KTsKfQoKdHlwZWRlZiBCT09MICgqZW51bV9oYW5kbGVyX3QpKGNvbnN0IGNoYXIqLCBpbnQsIHZvaWQqKTsKCnN0YXRpYyBCT09MIGVudW1fZHJpdmVycyhEV09SRCBmY2NUeXBlLCBlbnVtX2hhbmRsZXJfdCBoYW5kbGVyLCB2b2lkKiBwYXJhbSkKewogICAgQ0hBUiBidWZbMjA0OF0sIGZjY1R5cGVTdHJbNV0sICpzOwogICAgRFdPUkQgaSwgY250ID0gMCwgbFJldDsKICAgIEJPT0wgcmVzdWx0ID0gRkFMU0U7CiAgICBIS0VZIGhLZXk7CgogICAgZm91cmNjX3RvX3N0cmluZyhmY2NUeXBlU3RyLCBmY2NUeXBlKTsKICAgIGZjY1R5cGVTdHJbNF0gPSAnLic7CgogICAgLyogZmlyc3QsIGdvIHRocm91Z2ggdGhlIHJlZ2lzdHJ5IGVudHJpZXMgKi8KICAgIGxSZXQgPSBSZWdPcGVuS2V5RXhBKEhLRVlfTE9DQUxfTUFDSElORSwgSEtMTV9EUklWRVJTMzIsIDAsIEtFWV9RVUVSWV9WQUxVRSwgJmhLZXkpOwogICAgaWYgKGxSZXQgPT0gRVJST1JfU1VDQ0VTUykgCiAgICB7CiAgICAgICAgRFdPUkQgbmFtZSwgZGF0YSwgdHlwZTsKICAgICAgICBpID0gMDsKICAgICAgICBmb3IgKDs7KQoJewoJICAgIG5hbWUgPSAxMDsKCSAgICBkYXRhID0gc2l6ZW9mIGJ1ZiAtIG5hbWU7CgkgICAgbFJldCA9IFJlZ0VudW1WYWx1ZUEoaEtleSwgaSsrLCBidWYsICZuYW1lLCAwLCAmdHlwZSwgKExQQllURSkoYnVmK25hbWUpLCAmZGF0YSk7CgkgICAgaWYgKGxSZXQgPT0gRVJST1JfTk9fTU9SRV9JVEVNUykgYnJlYWs7CgkgICAgaWYgKGxSZXQgIT0gRVJST1JfU1VDQ0VTUykgY29udGludWU7CgkgICAgaWYgKG5hbWUgIT0gOSB8fCBzdHJuY2FzZWNtcChidWYsIGZjY1R5cGVTdHIsIDUpKSBjb250aW51ZTsKCSAgICBidWZbbmFtZV0gPSAnPSc7CgkgICAgaWYgKChyZXN1bHQgPSBoYW5kbGVyKGJ1ZiwgY250KyssIHBhcmFtKSkpIGJyZWFrOwoJfQogICAgCVJlZ0Nsb3NlS2V5KCBoS2V5ICk7CiAgICB9CiAgICBpZiAocmVzdWx0KSByZXR1cm4gcmVzdWx0OwoKICAgIC8qIGlmIHRoYXQgZGlkbid0IHdvcmssIGdvIHRocm91Z2ggdGhlIHZhbHVlcyBpbiBzeXN0ZW0uaW5pICovCiAgICBpZiAoR2V0UHJpdmF0ZVByb2ZpbGVTZWN0aW9uQSgiZHJpdmVyczMyIiwgYnVmLCBzaXplb2YoYnVmKSwgInN5c3RlbS5pbmkiKSkgCiAgICB7Cglmb3IgKHMgPSBidWY7ICpzOyBzICs9IHN0cmxlbihzKSArIDEpCgl7CiAgICAgICAgICAgIFRSQUNFKCJnb3QgJXNcbiIsIHMpOwoJICAgIGlmIChzdHJuY2FzZWNtcChzLCBmY2NUeXBlU3RyLCA1KSB8fCBzWzldICE9ICc9JykgY29udGludWU7CgkgICAgaWYgKChyZXN1bHQgPSBoYW5kbGVyKHMsIGNudCsrLCBwYXJhbSkpKSBicmVhazsKCX0KICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNU1ZJREVPX0dldEhpY1B0cgogKgogKgogKi8KV0lORV9ISUMqICAgTVNWSURFT19HZXRIaWNQdHIoSElDIGhpYykKewogICAgV0lORV9ISUMqICAgd2hpYzsKCiAgICBmb3IgKHdoaWMgPSBNU1ZJREVPX0ZpcnN0SGljOyB3aGljICYmIHdoaWMtPmhpYyAhPSBoaWM7IHdoaWMgPSB3aGljLT5uZXh0KTsKICAgIHJldHVybiB3aGljOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVZpZGVvRm9yV2luZG93c1ZlcnNpb24JCVtNU1ZGVzMyLjJdCiAqCQlWaWRlb0ZvcldpbmRvd3NWZXJzaW9uCQlbTVNWSURFTy4yXQogKiBSZXR1cm5zIHRoZSB2ZXJzaW9uIGluIG1ham9yLm1pbm9yIGZvcm0uCiAqIEluIFdpbmRvd3M5NSB0aGlzIHJldHVybnMgMHgwNDAwMDNiNiAoNC45NTApCiAqLwpEV09SRCBXSU5BUEkgVmlkZW9Gb3JXaW5kb3dzVmVyc2lvbih2b2lkKSAKewogICAgcmV0dXJuIDB4MDQwMDAzQjY7IC8qIDQuOTUwICovCn0KCnN0YXRpYyBCT09MIElDSW5mb19lbnVtX2hhbmRsZXIoY29uc3QgY2hhciAqZHJ2LCBpbnQgbnIsIHZvaWQgKnBhcmFtKQp7CiAgICBJQ0lORk8gKmxwaWNpbmZvID0gKElDSU5GTyAqKXBhcmFtOwogICAgRFdPUkQgZmNjSGFuZGxlciA9IG1taW9TdHJpbmdUb0ZPVVJDQ0EoZHJ2ICsgNSwgMCk7CgogICAgLyogZXhhY3QgbWF0Y2ggb2YgZmNjSGFuZGxlciBvciBudGggZHJpdmVyIGZvdW5kICovCiAgICBpZiAoKGxwaWNpbmZvLT5mY2NIYW5kbGVyICE9IG5yKSAmJiAobHBpY2luZm8tPmZjY0hhbmRsZXIgIT0gZmNjSGFuZGxlcikpCglyZXR1cm4gRkFMU0U7CgogICAgbHBpY2luZm8tPmZjY0hhbmRsZXIgPSBmY2NIYW5kbGVyOwogICAgbHBpY2luZm8tPmR3RmxhZ3MgPSAwOwogICAgbHBpY2luZm8tPmR3VmVyc2lvbiA9IDA7CiAgICBscGljaW5mby0+ZHdWZXJzaW9uSUNNID0gSUNWRVJTSU9OOwogICAgbHBpY2luZm8tPnN6TmFtZVswXSA9IDA7CiAgICBscGljaW5mby0+c3pEZXNjcmlwdGlvblswXSA9IDA7CiAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgZHJ2ICsgMTAsIC0xLCBscGljaW5mby0+c3pEcml2ZXIsIAoJCQlzaXplb2YobHBpY2luZm8tPnN6RHJpdmVyKS9zaXplb2YoV0NIQVIpKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ0luZm8JCQkJW01TVkZXMzIuQF0KICogR2V0IGluZm9ybWF0aW9uIGFib3V0IGFuIGluc3RhbGxhYmxlIGNvbXByZXNzb3IuIFJldHVybiBUUlVFIGlmIHRoZXJlCiAqIGlzIG9uZS4KICoKICogUEFSQU1TCiAqICAgZmNjVHlwZSAgICAgW0ldIHR5cGUgb2YgY29tcHJlc3NvciAoZS5nLiAndmlkYycpCiAqICAgZmNjSGFuZGxlciAgW0ldIHJlYWwgZmNjIGZvciBoYW5kbGVyIG9yIDxuPnRoIGNvbXByZXNzb3IKICogICBscGljaW5mbyAgICBbT10gaW5mb3JtYXRpb24gYWJvdXQgY29tcHJlc3NvcgogKi8KQk9PTCBWRldBUEkgSUNJbmZvKCBEV09SRCBmY2NUeXBlLCBEV09SRCBmY2NIYW5kbGVyLCBJQ0lORk8gKmxwaWNpbmZvKQp7CiAgICBUUkFDRSgiKCVzLCVzLyUwOHgsJXApXG4iLAogICAgICAgICAgd2luZV9kYmdzdHJfZmNjKGZjY1R5cGUpLCB3aW5lX2RiZ3N0cl9mY2MoZmNjSGFuZGxlciksIGZjY0hhbmRsZXIsIGxwaWNpbmZvKTsKCiAgICBscGljaW5mby0+ZmNjVHlwZSA9IGZjY1R5cGU7CiAgICBscGljaW5mby0+ZmNjSGFuZGxlciA9IGZjY0hhbmRsZXI7CiAgICByZXR1cm4gZW51bV9kcml2ZXJzKGZjY1R5cGUsIElDSW5mb19lbnVtX2hhbmRsZXIsIGxwaWNpbmZvKTsKfQoKc3RhdGljIERXT1JEIElDX0hhbmRsZVJlZiA9IDE7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlDSW5zdGFsbAkJCVtNU1ZGVzMyLkBdCiAqLwpCT09MIFZGV0FQSSBJQ0luc3RhbGwoRFdPUkQgZmNjVHlwZSwgRFdPUkQgZmNjSGFuZGxlciwgTFBBUkFNIGxQYXJhbSwgTFBTVFIgc3pEZXNjLCBVSU5UIHdGbGFncykgCnsKICAgIHJlZ19kcml2ZXIqIGRyaXZlcjsKICAgIHVuc2lnbmVkIGxlbjsKCiAgICBUUkFDRSgiKCVzLCVzLCVwLCVwLDB4JTA4eClcbiIsIHdpbmVfZGJnc3RyX2ZjYyhmY2NUeXBlKSwgd2luZV9kYmdzdHJfZmNjKGZjY0hhbmRsZXIpLCAodm9pZCopbFBhcmFtLCBzekRlc2MsIHdGbGFncyk7CgogICAgLyogQ2hlY2sgaWYgYSBkcml2ZXIgaXMgYWxyZWFkeSByZWdpc3RlcmVkICovCiAgICBmb3IgKGRyaXZlciA9IHJlZ19kcml2ZXJfbGlzdDsgZHJpdmVyOyBkcml2ZXIgPSBkcml2ZXItPm5leHQpCiAgICB7CiAgICAgICAgaWYgKCFjb21wYXJlX2ZvdXJjYyhmY2NUeXBlLCBkcml2ZXItPmZjY1R5cGUpICYmCiAgICAgICAgICAgICFjb21wYXJlX2ZvdXJjYyhmY2NIYW5kbGVyLCBkcml2ZXItPmZjY0hhbmRsZXIpKQogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGlmIChkcml2ZXIpIHJldHVybiBGQUxTRTsKCiAgICAvKiBSZWdpc3RlciB0aGUgZHJpdmVyICovCiAgICBkcml2ZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKHJlZ19kcml2ZXIpKTsKICAgIGlmICghZHJpdmVyKSBnb3RvIG9vbTsKICAgIGRyaXZlci0+ZmNjVHlwZSA9IGZjY1R5cGU7CiAgICBkcml2ZXItPmZjY0hhbmRsZXIgPSBmY2NIYW5kbGVyOwoKICAgIHN3aXRjaCh3RmxhZ3MpCiAgICB7CiAgICBjYXNlIElDSU5TVEFMTF9GVU5DVElPTjoKICAgICAgICBkcml2ZXItPnByb2MgPSAoRFJJVkVSUFJPQylsUGFyYW07Cglkcml2ZXItPm5hbWUgPSBOVUxMOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBJQ0lOU1RBTExfRFJJVkVSOgoJZHJpdmVyLT5wcm9jID0gTlVMTDsKICAgICAgICBsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgKGNoYXIqKWxQYXJhbSwgLTEsIE5VTEwsIDApOwogICAgICAgIGRyaXZlci0+bmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICAgICAgICBpZiAoIWRyaXZlci0+bmFtZSkgZ290byBvb207CiAgICAgICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIChjaGFyKilsUGFyYW0sIC0xLCBkcml2ZXItPm5hbWUsIGxlbik7CglicmVhazsKICAgIGRlZmF1bHQ6CglFUlIoIkludmFsaWQgZmxhZ3MhXG4iKTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRyaXZlcik7CglyZXR1cm4gRkFMU0U7CiAgIH0KCiAgIC8qIEluc2VydCBvdXIgZHJpdmVyIGluIHRoZSBsaXN0Ki8KICAgZHJpdmVyLT5uZXh0ID0gcmVnX2RyaXZlcl9saXN0OwogICByZWdfZHJpdmVyX2xpc3QgPSBkcml2ZXI7CiAgICAKICAgcmV0dXJuIFRSVUU7Cm9vbToKICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHJpdmVyKTsKICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlDUmVtb3ZlCQkJW01TVkZXMzIuQF0KICovCkJPT0wgVkZXQVBJIElDUmVtb3ZlKERXT1JEIGZjY1R5cGUsIERXT1JEIGZjY0hhbmRsZXIsIFVJTlQgd0ZsYWdzKSAKewogICAgcmVnX2RyaXZlcioqIHBkcml2ZXI7CiAgICByZWdfZHJpdmVyKiAgZHJ2OwoKICAgIFRSQUNFKCIoJXMsJXMsMHglMDh4KVxuIiwgd2luZV9kYmdzdHJfZmNjKGZjY1R5cGUpLCB3aW5lX2RiZ3N0cl9mY2MoZmNjSGFuZGxlciksIHdGbGFncyk7CgogICAgLyogQ2hlY2sgaWYgYSBkcml2ZXIgaXMgYWxyZWFkeSByZWdpc3RlcmVkICovCiAgICBmb3IgKHBkcml2ZXIgPSAmcmVnX2RyaXZlcl9saXN0OyAqcGRyaXZlcjsgcGRyaXZlciA9ICYoKnBkcml2ZXIpLT5uZXh0KQogICAgewogICAgICAgIGlmICghY29tcGFyZV9mb3VyY2MoZmNjVHlwZSwgKCpwZHJpdmVyKS0+ZmNjVHlwZSkgJiYKICAgICAgICAgICAgIWNvbXBhcmVfZm91cmNjKGZjY0hhbmRsZXIsICgqcGRyaXZlciktPmZjY0hhbmRsZXIpKQogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGlmICghKnBkcml2ZXIpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIC8qIFJlbW92ZSB0aGUgZHJpdmVyIGZyb20gdGhlIGxpc3QgKi8KICAgIGRydiA9ICpwZHJpdmVyOwogICAgKnBkcml2ZXIgPSAoKnBkcml2ZXIpLT5uZXh0OwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHJ2LT5uYW1lKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRydik7CiAgICAKICAgIHJldHVybiBUUlVFOyAgCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlDT3BlbgkJCQlbTVNWRlczMi5AXQogKiBPcGVucyBhbiBpbnN0YWxsYWJsZSBjb21wcmVzc29yLiBSZXR1cm4gc3BlY2lhbCBoYW5kbGUuCiAqLwpISUMgVkZXQVBJIElDT3BlbihEV09SRCBmY2NUeXBlLCBEV09SRCBmY2NIYW5kbGVyLCBVSU5UIHdNb2RlKSAKewogICAgV0NIQVIJCWNvZGVjbmFtZVsxMF07CiAgICBJQ09QRU4JCWljb3BlbjsKICAgIEhEUlZSCQloZHJ2OwogICAgV0lORV9ISUMqICAgICAgICAgICB3aGljOwogICAgQk9PTCAgICAgICAgICAgICAgICBiSXMxNjsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiAgZHJ2MzJXW10gPSB7J2QnLCdyJywnaScsJ3YnLCdlJywncicsJ3MnLCczJywnMicsJ1wwJ307CiAgICByZWdfZHJpdmVyKiAgICAgICAgIGRyaXZlcjsKCiAgICBUUkFDRSgiKCVzLCVzLDB4JTA4eClcbiIsIHdpbmVfZGJnc3RyX2ZjYyhmY2NUeXBlKSwgd2luZV9kYmdzdHJfZmNjKGZjY0hhbmRsZXIpLCB3TW9kZSk7CgogICAgLyogQ2hlY2sgaWYgdGhlcmUgaXMgYSByZWdpc3RlcmVkIGRyaXZlciB0aGF0IG1hdGNoZXMgKi8KICAgIGRyaXZlciA9IHJlZ19kcml2ZXJfbGlzdDsKICAgIHdoaWxlKGRyaXZlcikKICAgICAgICBpZiAoIWNvbXBhcmVfZm91cmNjKGZjY1R5cGUsIGRyaXZlci0+ZmNjVHlwZSkgJiYKICAgICAgICAgICAgIWNvbXBhcmVfZm91cmNjKGZjY0hhbmRsZXIsIGRyaXZlci0+ZmNjSGFuZGxlcikpCgkgICAgYnJlYWs7CiAgICAgICAgZWxzZQogICAgICAgICAgICBkcml2ZXIgPSBkcml2ZXItPm5leHQ7CgogICAgaWYgKGRyaXZlciAmJiBkcml2ZXItPnByb2MpCgkvKiBUaGUgZHJpdmVyIGhhcyBiZWVuIHJlZ2lzdGVyZWQgYXQgcnVudGltZSB3aXRoIGl0cyBkcml2ZXJwcm9jICovCiAgICAgICAgcmV0dXJuIE1TVklERU9fT3BlbkZ1bmN0aW9uKGZjY1R5cGUsIGZjY0hhbmRsZXIsIHdNb2RlLCAoRFJJVkVSUFJPQylkcml2ZXItPnByb2MsIChEV09SRClOVUxMKTsKICAKICAgIC8qIFdlbGwsIGxQYXJhbTIgaXMgaW4gZmFjdCBhIExQVklERU9fT1BFTl9QQVJNUywgYnV0IGl0IGhhcyB0aGUKICAgICAqIHNhbWUgbGF5b3V0IGFzIElDT1BFTgogICAgICovCiAgICBpY29wZW4uZHdTaXplCQk9IHNpemVvZihJQ09QRU4pOwogICAgaWNvcGVuLmZjY1R5cGUJCT0gZmNjVHlwZTsKICAgIGljb3Blbi5mY2NIYW5kbGVyCSAgICAgICAgPSBmY2NIYW5kbGVyOwogICAgaWNvcGVuLmR3VmVyc2lvbiAgICAgICAgICAgID0gMHgwMDAwMTAwMDsgLyogRklYTUUgKi8KICAgIGljb3Blbi5kd0ZsYWdzCQk9IHdNb2RlOwogICAgaWNvcGVuLmR3RXJyb3IgICAgICAgICAgICAgID0gMDsKICAgIGljb3Blbi5wVjFSZXNlcnZlZCAgICAgICAgICA9IE5VTEw7CiAgICBpY29wZW4ucFYyUmVzZXJ2ZWQgICAgICAgICAgPSBOVUxMOwogICAgaWNvcGVuLmRuRGV2Tm9kZSAgICAgICAgICAgID0gMDsgLyogRklYTUUgKi8KCQogICAgaWYgKCFkcml2ZXIpIHsKICAgICAgICAvKiBUaGUgZHJpdmVyIGlzIHJlZ2lzdGVyZWQgaW4gdGhlIHJlZ2lzdHJ5ICovCglmb3VyY2NfdG9fc3RyaW5nKGNvZGVjbmFtZSwgZmNjVHlwZSk7CiAgICAgICAgY29kZWNuYW1lWzRdID0gJy4nOwoJZm91cmNjX3RvX3N0cmluZyhjb2RlY25hbWUgKyA1LCBmY2NIYW5kbGVyKTsKICAgICAgICBjb2RlY25hbWVbOV0gPSAnXDAnOwoKICAgICAgICBoZHJ2ID0gT3BlbkRyaXZlcihjb2RlY25hbWUsIGRydjMyVywgKExQQVJBTSkmaWNvcGVuKTsKICAgICAgICBpZiAoIWhkcnYpIAogICAgICAgICAgICByZXR1cm4gMDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogVGhlIGRyaXZlciBoYXMgYmVlbiByZWdpc3RlcmVkIGF0IHJ1bnRpbWUgd2l0aCBpdHMgbmFtZSAqLwogICAgICAgIGhkcnYgPSBPcGVuRHJpdmVyKGRyaXZlci0+bmFtZSwgTlVMTCwgKExQQVJBTSkmaWNvcGVuKTsKICAgICAgICBpZiAoIWhkcnYpIAogICAgICAgICAgICByZXR1cm4gMDsgCiAgICB9CiAgICBiSXMxNiA9IEdldERyaXZlckZsYWdzKGhkcnYpICYgMHgxMDAwMDAwMDsgLyogdW5kb2N1bWVudGVkIGZsYWc6IFdJTkVfR0RGXzE2QklUICovCgogICAgaWYgKGJJczE2ICYmICFwRm5DYWxsVG8xNikKICAgIHsKICAgICAgICBGSVhNRSgiR290IGEgMTYgYml0IGRyaXZlciwgYnV0IG5vIDE2IGJpdCBzdXBwb3J0IGluIG1zdmZ3XG4iKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIHdoaWMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFdJTkVfSElDKSk7CiAgICBpZiAoIXdoaWMpCiAgICB7CiAgICAgICAgQ2xvc2VEcml2ZXIoaGRydiwgMCwgMCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgd2hpYy0+aGRydiAgICAgICAgICA9IGhkcnY7CiAgICAvKiBGSVhNRTogaXMgdGhlIHNpZ25hdHVyZSB0aGUgcmVhbCBvbmUgPyAqLwogICAgd2hpYy0+ZHJpdmVycHJvYyAgICA9IGJJczE2ID8gKERSSVZFUlBST0MpcEZuQ2FsbFRvMTYgOiBOVUxMOwogICAgd2hpYy0+ZHJpdmVycHJvYzE2ICA9IDA7CiAgICB3aGljLT50eXBlICAgICAgICAgID0gZmNjVHlwZTsKICAgIHdoaWMtPmhhbmRsZXIgICAgICAgPSBmY2NIYW5kbGVyOwogICAgd2hpbGUgKE1TVklERU9fR2V0SGljUHRyKEhJQ18zMihJQ19IYW5kbGVSZWYpKSAhPSBOVUxMKSBJQ19IYW5kbGVSZWYrKzsKICAgIHdoaWMtPmhpYyAgICAgICAgICAgPSBISUNfMzIoSUNfSGFuZGxlUmVmKyspOwogICAgd2hpYy0+bmV4dCAgICAgICAgICA9IE1TVklERU9fRmlyc3RIaWM7CiAgICBNU1ZJREVPX0ZpcnN0SGljID0gd2hpYzsKCiAgICBUUkFDRSgiPT4gJXBcbiIsIHdoaWMtPmhpYyk7CiAgICByZXR1cm4gd2hpYy0+aGljOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1TVklERU9fT3BlbkZ1bmN0aW9uCiAqLwpISUMgTVNWSURFT19PcGVuRnVuY3Rpb24oRFdPUkQgZmNjVHlwZSwgRFdPUkQgZmNjSGFuZGxlciwgVUlOVCB3TW9kZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBEUklWRVJQUk9DIGxwZm5IYW5kbGVyLCBEV09SRCBscGZuSGFuZGxlcjE2KSAKewogICAgSUNPUEVOICAgICAgaWNvcGVuOwogICAgV0lORV9ISUMqICAgd2hpYzsKCiAgICBUUkFDRSgiKCVzLCVzLCVkLCVwLCUwOHgpXG4iLAogICAgICAgICAgd2luZV9kYmdzdHJfZmNjKGZjY1R5cGUpLCB3aW5lX2RiZ3N0cl9mY2MoZmNjSGFuZGxlciksIHdNb2RlLCBscGZuSGFuZGxlciwgbHBmbkhhbmRsZXIxNik7CgogICAgaWNvcGVuLmR3U2l6ZQkJPSBzaXplb2YoSUNPUEVOKTsKICAgIGljb3Blbi5mY2NUeXBlCQk9IGZjY1R5cGU7CiAgICBpY29wZW4uZmNjSGFuZGxlcgkgICAgICAgID0gZmNjSGFuZGxlcjsKICAgIGljb3Blbi5kd1ZlcnNpb24gICAgICAgICAgICA9IElDVkVSU0lPTjsKICAgIGljb3Blbi5kd0ZsYWdzCQk9IHdNb2RlOwogICAgaWNvcGVuLmR3RXJyb3IgICAgICAgICAgICAgID0gMDsKICAgIGljb3Blbi5wVjFSZXNlcnZlZCAgICAgICAgICA9IE5VTEw7CiAgICBpY29wZW4ucFYyUmVzZXJ2ZWQgICAgICAgICAgPSBOVUxMOwogICAgaWNvcGVuLmRuRGV2Tm9kZSAgICAgICAgICAgID0gMDsgLyogRklYTUUgKi8KCiAgICB3aGljID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihXSU5FX0hJQykpOwogICAgaWYgKCF3aGljKSByZXR1cm4gMDsKCiAgICB3aGljLT5kcml2ZXJwcm9jICAgPSBscGZuSGFuZGxlcjsKICAgIHdoaWMtPmRyaXZlcnByb2MxNiA9IGxwZm5IYW5kbGVyMTY7CiAgICB3aGlsZSAoTVNWSURFT19HZXRIaWNQdHIoSElDXzMyKElDX0hhbmRsZVJlZikpICE9IE5VTEwpIElDX0hhbmRsZVJlZisrOwogICAgd2hpYy0+aGljICAgICAgICAgID0gSElDXzMyKElDX0hhbmRsZVJlZisrKTsKICAgIHdoaWMtPm5leHQgICAgICAgICA9IE1TVklERU9fRmlyc3RIaWM7CiAgICBNU1ZJREVPX0ZpcnN0SGljID0gd2hpYzsKCiAgICAvKiBOb3cgdHJ5IG9wZW5pbmcvbG9hZGluZyB0aGUgZHJpdmVyLiBUYWtlbiBmcm9tIERSSVZFUl9BZGRUb0xpc3QgKi8KICAgIC8qIFdoYXQgaWYgdGhlIGZ1bmN0aW9uIGlzIHVzZWQgbW9yZSB0aGFuIG9uY2U/ICovCgogICAgaWYgKE1TVklERU9fU2VuZE1lc3NhZ2Uod2hpYywgRFJWX0xPQUQsIDBMLCAwTCkgIT0gRFJWX1NVQ0NFU1MpIAogICAgewogICAgICAgIFdBUk4oIkRSVl9MT0FEIGZhaWxlZCBmb3IgaGljICVwXG4iLCB3aGljLT5oaWMpOwogICAgICAgIE1TVklERU9fRmlyc3RIaWMgPSB3aGljLT5uZXh0OwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHdoaWMpOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgLyogcmV0dXJuIHZhbHVlIGlzIG5vdCBjaGVja2VkICovCiAgICBNU1ZJREVPX1NlbmRNZXNzYWdlKHdoaWMsIERSVl9FTkFCTEUsIDBMLCAwTCk7CgogICAgd2hpYy0+ZHJpdmVySWQgPSAoRFdPUkQpTVNWSURFT19TZW5kTWVzc2FnZSh3aGljLCBEUlZfT1BFTiwgMCwgKERXT1JEX1BUUikmaWNvcGVuKTsKICAgIC8qIEZJWE1FOiBXaGF0IHNob3VsZCB3ZSBwdXQgaGVyZT8gKi8KICAgIHdoaWMtPmhkcnYgPSBOVUxMOwogICAgCiAgICBpZiAod2hpYy0+ZHJpdmVySWQgPT0gMCkgCiAgICB7CiAgICAgICAgV0FSTigiRFJWX09QRU4gZmFpbGVkIGZvciBoaWMgJXBcbiIsIHdoaWMtPmhpYyk7CiAgICAgICAgTVNWSURFT19GaXJzdEhpYyA9IHdoaWMtPm5leHQ7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd2hpYyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgVFJBQ0UoIj0+ICVwXG4iLCB3aGljLT5oaWMpOwogICAgcmV0dXJuIHdoaWMtPmhpYzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ09wZW5GdW5jdGlvbgkJCVtNU1ZGVzMyLkBdCiAqLwpISUMgVkZXQVBJIElDT3BlbkZ1bmN0aW9uKERXT1JEIGZjY1R5cGUsIERXT1JEIGZjY0hhbmRsZXIsIFVJTlQgd01vZGUsIEZBUlBST0MgbHBmbkhhbmRsZXIpIAp7CiAgICByZXR1cm4gTVNWSURFT19PcGVuRnVuY3Rpb24oZmNjVHlwZSwgZmNjSGFuZGxlciwgd01vZGUsIChEUklWRVJQUk9DKWxwZm5IYW5kbGVyLCAwKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ0dldEluZm8JCQlbTVNWRlczMi5AXQogKi8KTFJFU1VMVCBWRldBUEkgSUNHZXRJbmZvKEhJQyBoaWMsIElDSU5GTyAqcGljaW5mbywgRFdPUkQgY2IpIAp7CiAgICBMUkVTVUxUCXJldDsKICAgIFdJTkVfSElDKiAgIHdoaWMgPSBNU1ZJREVPX0dldEhpY1B0cihoaWMpOwoKICAgIFRSQUNFKCIoJXAsJXAsJWQpXG4iLCBoaWMsIHBpY2luZm8sIGNiKTsKCiAgICB3aGljID0gTVNWSURFT19HZXRIaWNQdHIoaGljKTsKICAgIGlmICghd2hpYykgcmV0dXJuIElDRVJSX0JBREhBTkRMRTsKICAgIGlmICghcGljaW5mbykgcmV0dXJuIE1NU1lTRVJSX0lOVkFMUEFSQU07CgogICAgLyogKFdTKSBUaGUgZmllbGQgc3pEcml2ZXIgc2hvdWxkIGJlIGluaXRpYWxpemVkIGJlY2F1c2UgdGhlIGRyaXZlciAKICAgICAqIGlzIG5vdCBvYmxpZ2VkIGFuZCBvZnRlbiB3aWxsIG5vdCBkbyBpdC4gU29tZSBhcHBsaWNhdGlvbnMsIGxpa2UKICAgICAqIFZpcnR1YWxEdWIsIHJlbHkgb24gdGhpcyBmaWVsZCBhbmQgd2lsbCBvY2Nhc2lvbmFsbHkgY3Jhc2ggaWYgaXQKICAgICAqIGdvZXMgdW5pbml0aWFsaXplZC4KICAgICAqLwogICAgaWYgKGNiID49IHNpemVvZihJQ0lORk8pKSBwaWNpbmZvLT5zekRyaXZlclswXSA9ICdcMCc7CgogICAgcmV0ID0gSUNTZW5kTWVzc2FnZShoaWMsIElDTV9HRVRJTkZPLCAoRFdPUkRfUFRSKXBpY2luZm8sIGNiKTsKCiAgICAvKiAoV1MpIFdoZW4gc3pEcml2ZXIgd2FzIG5vdCBzdXBwbGllZCBieSB0aGUgZHJpdmVyIGl0c2VsZiwgYXBwYXJlbnRseSAKICAgICAqIFdpbmRvd3Mgd2lsbCBzZXQgaXRzIHZhbHVlIGVxdWFsIHRvIHRoZSBkcml2ZXIgZmlsZSBuYW1lLiBUaGlzIGNhbgogICAgICogYmUgb2J0YWluZWQgZnJvbSB0aGUgcmVnaXN0cnkgYXMgd2UgZG8gaGVyZS4KICAgICAqLwogICAgaWYgKGNiID49IHNpemVvZihJQ0lORk8pICYmIHBpY2luZm8tPnN6RHJpdmVyWzBdID09IDApCiAgICB7CiAgICAgICAgSUNJTkZPICBpaTsKCiAgICAgICAgbWVtc2V0KCZpaSwgMCwgc2l6ZW9mKGlpKSk7CiAgICAgICAgaWkuZHdTaXplID0gc2l6ZW9mKGlpKTsKICAgICAgICBJQ0luZm8ocGljaW5mby0+ZmNjVHlwZSwgcGljaW5mby0+ZmNjSGFuZGxlciwgJmlpKTsKICAgICAgICBsc3RyY3B5VyhwaWNpbmZvLT5zekRyaXZlciwgaWkuc3pEcml2ZXIpOwogICAgfQoKICAgIFRSQUNFKCIJLT4gMHglMDhseFxuIiwgcmV0KTsKICAgIHJldHVybiByZXQ7Cn0KCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JEIGZjY1R5cGU7CiAgICBEV09SRCBmY2NIYW5kbGVyOwogICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlJbjsKICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0OwogICAgV09SRCB3TW9kZTsKICAgIERXT1JEIHF1ZXJ5bXNnOwogICAgSElDIGhpYzsKfSBkcml2ZXJfaW5mb190OwoKc3RhdGljIEhJQyB0cnlfZHJpdmVyKGRyaXZlcl9pbmZvX3QgKmluZm8pCnsKICAgIEhJQyAgIGhpYzsKCiAgICBpZiAoKGhpYyA9IElDT3BlbihpbmZvLT5mY2NUeXBlLCBpbmZvLT5mY2NIYW5kbGVyLCBpbmZvLT53TW9kZSkpKSAKICAgIHsKCWlmICghSUNTZW5kTWVzc2FnZShoaWMsIGluZm8tPnF1ZXJ5bXNnLCAoRFdPUkRfUFRSKWluZm8tPmxwYmlJbiwgKERXT1JEX1BUUilpbmZvLT5scGJpT3V0KSkKCSAgICByZXR1cm4gaGljOwoJSUNDbG9zZShoaWMpOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBCT09MIElDTG9jYXRlX2VudW1faGFuZGxlcihjb25zdCBjaGFyICpkcnYsIGludCBuciwgdm9pZCAqcGFyYW0pCnsKICAgIGRyaXZlcl9pbmZvX3QgKmluZm8gPSAoZHJpdmVyX2luZm9fdCAqKXBhcmFtOwogICAgaW5mby0+ZmNjSGFuZGxlciA9IG1taW9TdHJpbmdUb0ZPVVJDQ0EoZHJ2ICsgNSwgMCk7CiAgICBpbmZvLT5oaWMgPSB0cnlfZHJpdmVyKGluZm8pOwogICAgcmV0dXJuIGluZm8tPmhpYyAhPSAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlDTG9jYXRlCQkJW01TVkZXMzIuQF0KICovCkhJQyBWRldBUEkgSUNMb2NhdGUoRFdPUkQgZmNjVHlwZSwgRFdPUkQgZmNjSGFuZGxlciwgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKICAgICAgICAgICAgICAgICAgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaU91dCwgV09SRCB3TW9kZSkKewogICAgZHJpdmVyX2luZm9fdCBpbmZvOwoKICAgIFRSQUNFKCIoJXMsJXMsJXAsJXAsMHglMDR4KVxuIiwgCiAgICAgICAgICB3aW5lX2RiZ3N0cl9mY2MoZmNjVHlwZSksIHdpbmVfZGJnc3RyX2ZjYyhmY2NIYW5kbGVyKSwgbHBiaUluLCBscGJpT3V0LCB3TW9kZSk7CgogICAgaW5mby5mY2NUeXBlID0gZmNjVHlwZTsKICAgIGluZm8uZmNjSGFuZGxlciA9IGZjY0hhbmRsZXI7CiAgICBpbmZvLmxwYmlJbiA9IGxwYmlJbjsKICAgIGluZm8ubHBiaU91dCA9IGxwYmlPdXQ7CiAgICBpbmZvLndNb2RlID0gd01vZGU7CgogICAgc3dpdGNoICh3TW9kZSkgCiAgICB7CiAgICBjYXNlIElDTU9ERV9GQVNUQ09NUFJFU1M6CiAgICBjYXNlIElDTU9ERV9DT01QUkVTUzoKICAgICAgICBpbmZvLnF1ZXJ5bXNnID0gSUNNX0NPTVBSRVNTX1FVRVJZOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBJQ01PREVfRkFTVERFQ09NUFJFU1M6CiAgICBjYXNlIElDTU9ERV9ERUNPTVBSRVNTOgogICAgICAgIGluZm8ucXVlcnltc2cgPSBJQ01fREVDT01QUkVTU19RVUVSWTsKICAgICAgICBicmVhazsKICAgIGNhc2UgSUNNT0RFX0RSQVc6CiAgICAgICAgaW5mby5xdWVyeW1zZyA9IElDTV9EUkFXX1FVRVJZOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBXQVJOKCJVbmtub3duIG1vZGUgKCVkKVxuIiwgd01vZGUpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qIEVhc3kgY2FzZTogaGFuZGxlci90eXBlIG1hdGNoLCB3ZSBqdXN0IGZpcmUgYSBxdWVyeSBhbmQgcmV0dXJuICovCiAgICBpbmZvLmhpYyA9IHRyeV9kcml2ZXIoJmluZm8pOwogICAgLyogSWYgaXQgZGlkbid0IHdvcmssIHRyeSBlYWNoIGRyaXZlciBpbiB0dXJuLiAzMiBiaXQgY29kZWNzIG9ubHkuICovCiAgICAvKiBGSVhNRTogTW92ZSB0aGlzIHRvIGFuIGluaXQgcm91dGluZT8gKi8KICAgIGlmICghaW5mby5oaWMpIGVudW1fZHJpdmVycyhmY2NUeXBlLCBJQ0xvY2F0ZV9lbnVtX2hhbmRsZXIsICZpbmZvKTsKCiAgICBpZiAoaW5mby5oaWMpIAogICAgewogICAgICAgIFRSQUNFKCI9PiAlcFxuIiwgaW5mby5oaWMpOwoJcmV0dXJuIGluZm8uaGljOwogICAgfQoKICAgIGlmIChmY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgCiAgICAgICAgcmV0dXJuIElDTG9jYXRlKElDVFlQRV9WSURFTywgZmNjSGFuZGxlciwgbHBiaUluLCBscGJpT3V0LCB3TW9kZSk7CiAgICAKICAgIFdBUk4oIiglcywlcywlcCwlcCwweCUwNHgpIG5vdCBmb3VuZCFcbiIsCiAgICAgICAgIHdpbmVfZGJnc3RyX2ZjYyhmY2NUeXBlKSwgd2luZV9kYmdzdHJfZmNjKGZjY0hhbmRsZXIpLCBscGJpSW4sIGxwYmlPdXQsIHdNb2RlKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlDR2V0RGlzcGxheUZvcm1hdAkJCVtNU1ZGVzMyLkBdCiAqLwpISUMgVkZXQVBJIElDR2V0RGlzcGxheUZvcm1hdCgKCUhJQyBoaWMsTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlJbixMUEJJVE1BUElORk9IRUFERVIgbHBiaU91dCwKCUlOVCBkZXB0aCxJTlQgZHgsSU5UIGR5KQp7CglISUMJdG1waGljID0gaGljOwoKCVRSQUNFKCIoJXAsJXAsJXAsJWQsJWQsJWQpIVxuIixoaWMsbHBiaUluLGxwYmlPdXQsZGVwdGgsZHgsZHkpOwoKCWlmICghdG1waGljKSB7CgkJdG1waGljPUlDTG9jYXRlKElDVFlQRV9WSURFTywwLGxwYmlJbixOVUxMLElDTU9ERV9ERUNPTVBSRVNTKTsKCQlpZiAoIXRtcGhpYykKCQkJcmV0dXJuIHRtcGhpYzsKCX0KCWlmICgoZHkgPT0gbHBiaUluLT5iaUhlaWdodCkgJiYgKGR4ID09IGxwYmlJbi0+YmlXaWR0aCkpCgkJZHkgPSBkeCA9IDA7IC8qIG5vIHJlc2l6ZSBuZWVkZWQgKi8KCgkvKiBDYW4gd2UgZGVjb21wcmVzcyBpdCA/ICovCglpZiAoSUNEZWNvbXByZXNzUXVlcnkodG1waGljLGxwYmlJbixOVUxMKSAhPSAwKQoJCWdvdG8gZXJyb3V0OyAvKiBubywgc29ycnkgKi8KCglJQ1NlbmRNZXNzYWdlKHRtcGhpYywgSUNNX0RFQ09NUFJFU1NfR0VUX0ZPUk1BVCwgKERXT1JEX1BUUilscGJpSW4sIChEV09SRF9QVFIpbHBiaU91dCk7CgoJaWYgKGxwYmlPdXQtPmJpQ29tcHJlc3Npb24gIT0gMCkgewogICAgICAgICAgIEZJWE1FKCJPb2NoLCBob3cgY29tZSBkZWNvbXByZXNzb3Igb3V0cHV0cyBjb21wcmVzc2VkIGRhdGEgKCVkKT8/XG4iLAoJCQkgbHBiaU91dC0+YmlDb21wcmVzc2lvbik7Cgl9CglpZiAobHBiaU91dC0+YmlTaXplIDwgc2l6ZW9mKCpscGJpT3V0KSkgewogICAgICAgICAgIEZJWE1FKCJPb2NoLCBzaXplIG9mIG91dHB1dCBCSUggaXMgdG9vIHNtYWxsICglZClcbiIsCgkJCSBscGJpT3V0LT5iaVNpemUpOwoJICAgbHBiaU91dC0+YmlTaXplID0gc2l6ZW9mKCpscGJpT3V0KTsKCX0KCWlmICghZGVwdGgpIHsKCQlIREMJaGRjOwoKCQloZGMgPSBHZXREQygwKTsKCQlkZXB0aCA9IEdldERldmljZUNhcHMoaGRjLEJJVFNQSVhFTCkqR2V0RGV2aWNlQ2FwcyhoZGMsUExBTkVTKTsKCQlSZWxlYXNlREMoMCxoZGMpOwoJCWlmIChkZXB0aD09MTUpCWRlcHRoID0gMTY7CgkJaWYgKGRlcHRoPDgpCWRlcHRoID0gIDg7Cgl9CglpZiAobHBiaUluLT5iaUJpdENvdW50ID09IDgpCgkJZGVwdGggPSA4OwoKCVRSQUNFKCI9PiAlcFxuIiwgdG1waGljKTsKCXJldHVybiB0bXBoaWM7CmVycm91dDoKCWlmIChoaWMhPXRtcGhpYykKCQlJQ0Nsb3NlKHRtcGhpYyk7CgoJVFJBQ0UoIj0+IDBcbiIpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSUNDb21wcmVzcwkJCVtNU1ZGVzMyLkBdCiAqLwpEV09SRCBWRldBUElWCklDQ29tcHJlc3MoCglISUMgaGljLERXT1JEIGR3RmxhZ3MsTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXRwdXQsTFBWT0lEIGxwRGF0YSwKCUxQQklUTUFQSU5GT0hFQURFUiBscGJpSW5wdXQsTFBWT0lEIGxwQml0cyxMUERXT1JEIGxwY2tpZCwKCUxQRFdPUkQgbHBkd0ZsYWdzLExPTkcgbEZyYW1lTnVtLERXT1JEIGR3RnJhbWVTaXplLERXT1JEIGR3UXVhbGl0eSwKCUxQQklUTUFQSU5GT0hFQURFUiBscGJpUHJldixMUFZPSUQgbHBQcmV2KQp7CglJQ0NPTVBSRVNTCWljY21wOwoKCVRSQUNFKCIoJXAsJWQsJXAsJXAsJXAsJXAsLi4uKVxuIixoaWMsZHdGbGFncyxscGJpT3V0cHV0LGxwRGF0YSxscGJpSW5wdXQsbHBCaXRzKTsKCglpY2NtcC5kd0ZsYWdzCQk9IGR3RmxhZ3M7CgoJaWNjbXAubHBiaU91dHB1dAk9IGxwYmlPdXRwdXQ7CglpY2NtcC5scE91dHB1dAkJPSBscERhdGE7CglpY2NtcC5scGJpSW5wdXQJCT0gbHBiaUlucHV0OwoJaWNjbXAubHBJbnB1dAkJPSBscEJpdHM7CgoJaWNjbXAubHBja2lkCQk9IGxwY2tpZDsKCWljY21wLmxwZHdGbGFncwkJPSBscGR3RmxhZ3M7CglpY2NtcC5sRnJhbWVOdW0JCT0gbEZyYW1lTnVtOwoJaWNjbXAuZHdGcmFtZVNpemUJPSBkd0ZyYW1lU2l6ZTsKCWljY21wLmR3UXVhbGl0eQkJPSBkd1F1YWxpdHk7CglpY2NtcC5scGJpUHJldgkJPSBscGJpUHJldjsKCWljY21wLmxwUHJldgkJPSBscFByZXY7CglyZXR1cm4gSUNTZW5kTWVzc2FnZShoaWMsSUNNX0NPTVBSRVNTLChEV09SRF9QVFIpJmljY21wLHNpemVvZihpY2NtcCkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlDRGVjb21wcmVzcwkJCVtNU1ZGVzMyLkBdCiAqLwpEV09SRCBWRldBUElWICBJQ0RlY29tcHJlc3MoSElDIGhpYyxEV09SRCBkd0ZsYWdzLExQQklUTUFQSU5GT0hFQURFUiBscGJpRm9ybWF0LAoJCQkJTFBWT0lEIGxwRGF0YSxMUEJJVE1BUElORk9IRUFERVIgbHBiaSxMUFZPSUQgbHBCaXRzKQp7CglJQ0RFQ09NUFJFU1MJaWNkOwoJRFdPUkQgcmV0OwoKCVRSQUNFKCIoJXAsJWQsJXAsJXAsJXAsJXApXG4iLGhpYyxkd0ZsYWdzLGxwYmlGb3JtYXQsbHBEYXRhLGxwYmksbHBCaXRzKTsKCglUUkFDRSgibHBCaXRzWzBdID09ICV4XG4iLCgoTFBEV09SRClscEJpdHMpWzBdKTsKCglpY2QuZHdGbGFncwk9IGR3RmxhZ3M7CglpY2QubHBiaUlucHV0CT0gbHBiaUZvcm1hdDsKCWljZC5scElucHV0CT0gbHBEYXRhOwoKCWljZC5scGJpT3V0cHV0CT0gbHBiaTsKCWljZC5scE91dHB1dAk9IGxwQml0czsKCWljZC5ja2lkCT0gMDsKCXJldCA9IElDU2VuZE1lc3NhZ2UoaGljLElDTV9ERUNPTVBSRVNTLChEV09SRF9QVFIpJmljZCxzaXplb2YoSUNERUNPTVBSRVNTKSk7CgoJVFJBQ0UoImxwQml0c1swXSA9PSAleFxuIiwoKExQRFdPUkQpbHBCaXRzKVswXSk7CgoJVFJBQ0UoIi0+ICVkXG4iLHJldCk7CgoJcmV0dXJuIHJldDsKfQoKCnN0cnVjdCBjaG9vc2VfY29tcHJlc3Nvcgp7CiAgICBVSU5UIGZsYWdzOwogICAgTFBDU1RSIHRpdGxlOwogICAgQ09NUFZBUlMgY3Y7Cn07CgpzdHJ1Y3QgY29kZWNfaW5mbwp7CiAgICBISUMgaGljOwogICAgSUNJTkZPIGljaW5mbzsKfTsKCnN0YXRpYyBCT09MIGVudW1fY29tcHJlc3NvcnMoSFdORCBsaXN0LCBDT01QVkFSUyAqcGN2LCBCT09MIGVudW1fYWxsKQp7CiAgICBVSU5UIGlkLCB0b3RhbCA9IDA7CiAgICBJQ0lORk8gaWNpbmZvOwoKICAgIGlkID0gMDsKCiAgICB3aGlsZSAoSUNJbmZvKHBjdi0+ZmNjVHlwZSwgaWQsICZpY2luZm8pKQogICAgewogICAgICAgIHN0cnVjdCBjb2RlY19pbmZvICppYzsKICAgICAgICBEV09SRCBpZHg7CiAgICAgICAgSElDIGhpYzsKCiAgICAgICAgaWQrKzsKCiAgICAgICAgaGljID0gSUNPcGVuKGljaW5mby5mY2NUeXBlLCBpY2luZm8uZmNjSGFuZGxlciwgSUNNT0RFX0NPTVBSRVNTKTsKCiAgICAgICAgaWYgKGhpYykKICAgICAgICB7CiAgICAgICAgICAgIC8qIGZvciB1bmtub3duIHJlYXNvbiBmY2NIYW5kbGVyIHJlcG9ydGVkIGJ5IHRoZSBkcml2ZXIKICAgICAgICAgICAgICogZG9lc24ndCBhbHdheXMgd29yaywgdXNlIHRoZSBvbmUgcmV0dXJuZWQgYnkgSUNJbmZvIGluc3RlYWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBEV09SRCBmY2NIYW5kbGVyID0gaWNpbmZvLmZjY0hhbmRsZXI7CgogICAgICAgICAgICBpZiAoIWVudW1fYWxsICYmIHBjdi0+bHBiaUluKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoSUNDb21wcmVzc1F1ZXJ5KGhpYywgcGN2LT5scGJpSW4sIE5VTEwpICE9IElDRVJSX09LKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJmY2NIYW5kbGVyICVzIGRvZXNuJ3Qgc3VwcG9ydCBpbnB1dCBESUIgZm9ybWF0ICVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmVfZGJnc3RyX2ZjYyhpY2luZm8uZmNjSGFuZGxlciksIHBjdi0+bHBiaUluLT5ibWlIZWFkZXIuYmlDb21wcmVzc2lvbik7CiAgICAgICAgICAgICAgICAgICAgSUNDbG9zZShoaWMpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBJQ0dldEluZm8oaGljLCAmaWNpbmZvLCBzaXplb2YoaWNpbmZvKSk7CiAgICAgICAgICAgIGljaW5mby5mY2NIYW5kbGVyID0gZmNjSGFuZGxlcjsKCiAgICAgICAgICAgIGlkeCA9IFNlbmRNZXNzYWdlVyhsaXN0LCBDQl9BRERTVFJJTkcsIDAsIChMUEFSQU0paWNpbmZvLnN6RGVzY3JpcHRpb24pOwoKICAgICAgICAgICAgaWMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKHN0cnVjdCBjb2RlY19pbmZvKSk7CiAgICAgICAgICAgIG1lbWNweSgmaWMtPmljaW5mbywgJmljaW5mbywgc2l6ZW9mKElDSU5GTykpOwogICAgICAgICAgICBpYy0+aGljID0gaGljOwogICAgICAgICAgICBTZW5kTWVzc2FnZVcobGlzdCwgQ0JfU0VUSVRFTURBVEEsIGlkeCwgKExQQVJBTSlpYyk7CiAgICAgICAgfQogICAgICAgIHRvdGFsKys7CiAgICB9CgogICAgcmV0dXJuIHRvdGFsICE9IDA7Cn0KCnN0YXRpYyBJTlRfUFRSIENBTExCQUNLIGljbV9jaG9vc2VfY29tcHJlc3Nvcl9kbGdwcm9jKEhXTkQgaGRsZywgVUlOVCBtc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKICAgIHN3aXRjaCAobXNnKQogICAgewogICAgY2FzZSBXTV9JTklURElBTE9HOgogICAgewogICAgICAgIHN0cnVjdCBjb2RlY19pbmZvICppYzsKICAgICAgICBXQ0hBUiBidWZbMTI4XTsKICAgICAgICBzdHJ1Y3QgY2hvb3NlX2NvbXByZXNzb3IgKmNob29zZV9jb21wID0gKHN0cnVjdCBjaG9vc2VfY29tcHJlc3NvciAqKWxwYXJhbTsKCiAgICAgICAgU2V0V2luZG93TG9uZ1B0clcoaGRsZywgRFdMUF9VU0VSLCBscGFyYW0pOwoKICAgICAgICAvKiBGSVhNRSAqLwogICAgICAgIGNob29zZV9jb21wLT5mbGFncyAmPSB+KElDTUZfQ0hPT1NFX0RBVEFSQVRFIHwgSUNNRl9DSE9PU0VfS0VZRlJBTUUpOwoKICAgICAgICBpZiAoY2hvb3NlX2NvbXAtPnRpdGxlKQogICAgICAgICAgICBTZXRXaW5kb3dUZXh0QShoZGxnLCBjaG9vc2VfY29tcC0+dGl0bGUpOwoKICAgICAgICBpZiAoIShjaG9vc2VfY29tcC0+ZmxhZ3MgJiBJQ01GX0NIT09TRV9EQVRBUkFURSkpCiAgICAgICAgewogICAgICAgICAgICBTaG93V2luZG93KEdldERsZ0l0ZW0oaGRsZywgSURDX0RBVEFSQVRFX0NIRUNLQk9YKSwgU1dfSElERSk7CiAgICAgICAgICAgIFNob3dXaW5kb3coR2V0RGxnSXRlbShoZGxnLCBJRENfREFUQVJBVEUpLCBTV19ISURFKTsKICAgICAgICAgICAgU2hvd1dpbmRvdyhHZXREbGdJdGVtKGhkbGcsIElEQ19EQVRBUkFURV9LQiksIFNXX0hJREUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEoY2hvb3NlX2NvbXAtPmZsYWdzICYgSUNNRl9DSE9PU0VfS0VZRlJBTUUpKQogICAgICAgIHsKICAgICAgICAgICAgU2hvd1dpbmRvdyhHZXREbGdJdGVtKGhkbGcsIElEQ19LRVlGUkFNRV9DSEVDS0JPWCksIFNXX0hJREUpOwogICAgICAgICAgICBTaG93V2luZG93KEdldERsZ0l0ZW0oaGRsZywgSURDX0tFWUZSQU1FKSwgU1dfSElERSk7CiAgICAgICAgICAgIFNob3dXaW5kb3coR2V0RGxnSXRlbShoZGxnLCBJRENfS0VZRlJBTUVfRlJBTUVTKSwgU1dfSElERSk7CiAgICAgICAgfQoKICAgICAgICAvKiBGSVhNRSAqLwogICAgICAgIEVuYWJsZVdpbmRvdyhHZXREbGdJdGVtKGhkbGcsIElEQ19RVUFMSVRZX1NDUk9MTCksIEZBTFNFKTsKICAgICAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoZGxnLCBJRENfUVVBTElUWV9UWFQpLCBGQUxTRSk7CgogICAgICAgIC8qaWYgKCEoY2hvb3NlX2NvbXAtPmZsYWdzICYgSUNNRl9DSE9PU0VfUFJFVklFVykpCiAgICAgICAgICAgIFNob3dXaW5kb3coR2V0RGxnSXRlbShoZGxnLCBJRENfUFJFVklFVyksIFNXX0hJREUpOyovCgogICAgICAgIExvYWRTdHJpbmdXKE1TVkZXMzJfaE1vZHVsZSwgSURTX0ZVTExGUkFNRVMsIGJ1ZiwgMTI4KTsKICAgICAgICBTZW5kRGxnSXRlbU1lc3NhZ2VXKGhkbGcsIElEQ19DT01QX0xJU1QsIENCX0FERFNUUklORywgMCwgKExQQVJBTSlidWYpOwoKICAgICAgICBpYyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2Yoc3RydWN0IGNvZGVjX2luZm8pKTsKICAgICAgICBpYy0+aWNpbmZvLmZjY1R5cGUgPSBzdHJlYW10eXBlVklERU87CiAgICAgICAgaWMtPmljaW5mby5mY2NIYW5kbGVyID0gY29tcHR5cGVESUI7CiAgICAgICAgaWMtPmhpYyA9IDA7CiAgICAgICAgU2VuZERsZ0l0ZW1NZXNzYWdlVyhoZGxnLCBJRENfQ09NUF9MSVNULCBDQl9TRVRJVEVNREFUQSwgMCwgKExQQVJBTSlpYyk7CgogICAgICAgIGVudW1fY29tcHJlc3NvcnMoR2V0RGxnSXRlbShoZGxnLCBJRENfQ09NUF9MSVNUKSwgJmNob29zZV9jb21wLT5jdiwgY2hvb3NlX2NvbXAtPmZsYWdzICYgSUNNRl9DSE9PU0VfQUxMQ09NUFJFU1NPUlMpOwoKICAgICAgICBTZW5kRGxnSXRlbU1lc3NhZ2VXKGhkbGcsIElEQ19DT01QX0xJU1QsIENCX1NFVENVUlNFTCwgMCwgMCk7CiAgICAgICAgU2V0Rm9jdXMoR2V0RGxnSXRlbShoZGxnLCBJRENfQ09NUF9MSVNUKSk7CgogICAgICAgIFNldFdpbmRvd0xvbmdQdHJXKGhkbGcsIERXTFBfVVNFUiwgKFVMT05HX1BUUiljaG9vc2VfY29tcCk7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgY2FzZSBXTV9DT01NQU5EOgogICAgICAgIHN3aXRjaCAoTE9XT1JEKHdwYXJhbSkpCiAgICAgICAgewogICAgICAgIGNhc2UgSURDX0NPTVBfTElTVDoKICAgICAgICB7CiAgICAgICAgICAgIElOVCBjdXJfc2VsOwogICAgICAgICAgICBzdHJ1Y3QgY29kZWNfaW5mbyAqaWM7CiAgICAgICAgICAgIEJPT0wgY2FuX2NvbmZpZ3VyZSA9IEZBTFNFLCBjYW5fYWJvdXQgPSBGQUxTRTsKICAgICAgICAgICAgc3RydWN0IGNob29zZV9jb21wcmVzc29yICpjaG9vc2VfY29tcDsKCiAgICAgICAgICAgIGlmIChISVdPUkQod3BhcmFtKSAhPSBDQk5fU0VMQ0hBTkdFICYmIEhJV09SRCh3cGFyYW0pICE9IENCTl9TRVRGT0NVUykKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2hvb3NlX2NvbXAgPSAoc3RydWN0IGNob29zZV9jb21wcmVzc29yICopR2V0V2luZG93TG9uZ1B0clcoaGRsZywgRFdMUF9VU0VSKTsKCiAgICAgICAgICAgIGN1cl9zZWwgPSBTZW5kTWVzc2FnZVcoKEhXTkQpbHBhcmFtLCBDQl9HRVRDVVJTRUwsIDAsIDApOwoKICAgICAgICAgICAgaWMgPSAoc3RydWN0IGNvZGVjX2luZm8gKilTZW5kTWVzc2FnZVcoKEhXTkQpbHBhcmFtLCBDQl9HRVRJVEVNREFUQSwgY3VyX3NlbCwgMCk7CiAgICAgICAgICAgIGlmIChpYyAmJiBpYy0+aGljKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoSUNRdWVyeUNvbmZpZ3VyZShpYy0+aGljKSA9PSBEUlZDTkZfT0spCiAgICAgICAgICAgICAgICAgICAgY2FuX2NvbmZpZ3VyZSA9IFRSVUU7CiAgICAgICAgICAgICAgICBpZiAoSUNRdWVyeUFib3V0KGljLT5oaWMpID09IERSVkNORl9PSykKICAgICAgICAgICAgICAgICAgICBjYW5fYWJvdXQgPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEVuYWJsZVdpbmRvdyhHZXREbGdJdGVtKGhkbGcsIElEQ19DT05GSUdVUkUpLCBjYW5fY29uZmlndXJlKTsKICAgICAgICAgICAgRW5hYmxlV2luZG93KEdldERsZ0l0ZW0oaGRsZywgSURDX0FCT1VUKSwgY2FuX2Fib3V0KTsKCiAgICAgICAgICAgIGlmIChjaG9vc2VfY29tcC0+ZmxhZ3MgJiBJQ01GX0NIT09TRV9EQVRBUkFURSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogRklYTUUgKi8KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY2hvb3NlX2NvbXAtPmZsYWdzICYgSUNNRl9DSE9PU0VfS0VZRlJBTUUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEZJWE1FICovCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBJRENfQ09ORklHVVJFOgogICAgICAgIGNhc2UgSURDX0FCT1VUOgogICAgICAgIHsKICAgICAgICAgICAgSFdORCBsaXN0ID0gR2V0RGxnSXRlbShoZGxnLCBJRENfQ09NUF9MSVNUKTsKICAgICAgICAgICAgSU5UIGN1cl9zZWw7CiAgICAgICAgICAgIHN0cnVjdCBjb2RlY19pbmZvICppYzsKCiAgICAgICAgICAgIGlmIChISVdPUkQod3BhcmFtKSAhPSBCTl9DTElDS0VEKQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjdXJfc2VsID0gU2VuZE1lc3NhZ2VXKGxpc3QsIENCX0dFVENVUlNFTCwgMCwgMCk7CgogICAgICAgICAgICBpYyA9IChzdHJ1Y3QgY29kZWNfaW5mbyAqKVNlbmRNZXNzYWdlVyhsaXN0LCBDQl9HRVRJVEVNREFUQSwgY3VyX3NlbCwgMCk7CiAgICAgICAgICAgIGlmIChpYyAmJiBpYy0+aGljKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoTE9XT1JEKHdwYXJhbSkgPT0gSURDX0NPTkZJR1VSRSkKICAgICAgICAgICAgICAgICAgICBJQ0NvbmZpZ3VyZShpYy0+aGljLCBoZGxnKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBJQ0Fib3V0KGljLT5oaWMsIGhkbGcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgSURPSzoKICAgICAgICB7CiAgICAgICAgICAgIEhXTkQgbGlzdCA9IEdldERsZ0l0ZW0oaGRsZywgSURDX0NPTVBfTElTVCk7CiAgICAgICAgICAgIElOVCBjdXJfc2VsOwogICAgICAgICAgICBzdHJ1Y3QgY29kZWNfaW5mbyAqaWM7CgogICAgICAgICAgICBpZiAoSElXT1JEKHdwYXJhbSkgIT0gQk5fQ0xJQ0tFRCkKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY3VyX3NlbCA9IFNlbmRNZXNzYWdlVyhsaXN0LCBDQl9HRVRDVVJTRUwsIDAsIDApOwogICAgICAgICAgICBpYyA9IChzdHJ1Y3QgY29kZWNfaW5mbyAqKVNlbmRNZXNzYWdlVyhsaXN0LCBDQl9HRVRJVEVNREFUQSwgY3VyX3NlbCwgMCk7CiAgICAgICAgICAgIGlmIChpYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RydWN0IGNob29zZV9jb21wcmVzc29yICpjaG9vc2VfY29tcCA9IChzdHJ1Y3QgY2hvb3NlX2NvbXByZXNzb3IgKilHZXRXaW5kb3dMb25nUHRyVyhoZGxnLCBEV0xQX1VTRVIpOwoKICAgICAgICAgICAgICAgIGNob29zZV9jb21wLT5jdi5oaWMgPSBpYy0+aGljOwogICAgICAgICAgICAgICAgY2hvb3NlX2NvbXAtPmN2LmZjY1R5cGUgPSBpYy0+aWNpbmZvLmZjY1R5cGU7CiAgICAgICAgICAgICAgICBjaG9vc2VfY29tcC0+Y3YuZmNjSGFuZGxlciA9IGljLT5pY2luZm8uZmNjSGFuZGxlcjsKICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBmaWxsIGV2ZXJ5dGhpbmcgZWxzZSAqLwoKICAgICAgICAgICAgICAgIC8qIHByZXZlbnQgY2xvc2luZyB0aGUgY29kZWMgaGFuZGxlIGJlbG93ICovCiAgICAgICAgICAgICAgICBpYy0+aGljID0gMDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgICAgICBjYXNlIElEQ0FOQ0VMOgogICAgICAgIHsKICAgICAgICAgICAgSFdORCBsaXN0ID0gR2V0RGxnSXRlbShoZGxnLCBJRENfQ09NUF9MSVNUKTsKICAgICAgICAgICAgSU5UIGlkeCA9IDA7CgogICAgICAgICAgICBpZiAoSElXT1JEKHdwYXJhbSkgIT0gQk5fQ0xJQ0tFRCkKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgd2hpbGUgKDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cnVjdCBjb2RlY19pbmZvICppYzsKICAgIAogICAgICAgICAgICAgICAgaWMgPSAoc3RydWN0IGNvZGVjX2luZm8gKilTZW5kTWVzc2FnZVcobGlzdCwgQ0JfR0VUSVRFTURBVEEsIGlkeCsrLCAwKTsKCiAgICAgICAgICAgICAgICBpZiAoIWljIHx8IChMT05HX1BUUilpYyA9PSBDQl9FUlIpIGJyZWFrOwoKICAgICAgICAgICAgICAgIGlmIChpYy0+aGljKSBJQ0Nsb3NlKGljLT5oaWMpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaWMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBFbmREaWFsb2coaGRsZywgTE9XT1JEKHdwYXJhbSkgPT0gSURPSyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlDQ29tcHJlc3NvckNob29zZSAgIFtNU1ZGVzMyLkBdCiAqLwpCT09MIFZGV0FQSSBJQ0NvbXByZXNzb3JDaG9vc2UoSFdORCBod25kLCBVSU5UIHVpRmxhZ3MsIExQVk9JRCBwdkluLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGxwRGF0YSwgUENPTVBWQVJTIHBjLCBMUFNUUiBscHN6VGl0bGUpCnsKICAgIHN0cnVjdCBjaG9vc2VfY29tcHJlc3NvciBjaG9vc2VfY29tcDsKICAgIEJPT0wgcmV0OwoKICAgIFRSQUNFKCIoJXAsJTA4eCwlcCwlcCwlcCwlcylcbiIsIGh3bmQsIHVpRmxhZ3MsIHB2SW4sIGxwRGF0YSwgcGMsIGxwc3pUaXRsZSk7CgogICAgaWYgKCFwYyB8fCBwYy0+Y2JTaXplICE9IHNpemVvZihDT01QVkFSUykpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmICghKHBjLT5kd0ZsYWdzICYgSUNNRl9DT01QVkFSU19WQUxJRCkpCiAgICB7CiAgICAgICAgcGMtPmR3RmxhZ3MgICA9IDA7CiAgICAgICAgcGMtPmZjY1R5cGUgICA9IHBjLT5mY2NIYW5kbGVyID0gMDsKICAgICAgICBwYy0+aGljICAgICAgID0gTlVMTDsKICAgICAgICBwYy0+bHBiaUluICAgID0gTlVMTDsKICAgICAgICBwYy0+bHBiaU91dCAgID0gTlVMTDsKICAgICAgICBwYy0+bHBCaXRzT3V0ID0gcGMtPmxwQml0c1ByZXYgPSBwYy0+bHBTdGF0ZSA9IE5VTEw7CiAgICAgICAgcGMtPmxRICAgICAgICA9IElDUVVBTElUWV9ERUZBVUxUOwogICAgICAgIHBjLT5sS2V5ICAgICAgPSAtMTsKICAgICAgICBwYy0+bERhdGFSYXRlID0gMzAwOyAvKiBrQiAqLwogICAgICAgIHBjLT5scFN0YXRlICAgPSBOVUxMOwogICAgICAgIHBjLT5jYlN0YXRlICAgPSAwOwogICAgfQogICAgaWYgKHBjLT5mY2NUeXBlID09IDApCiAgICAgICAgcGMtPmZjY1R5cGUgPSBJQ1RZUEVfVklERU87CgogICAgY2hvb3NlX2NvbXAuY3YgPSAqcGM7CiAgICBjaG9vc2VfY29tcC5mbGFncyA9IHVpRmxhZ3M7CiAgICBjaG9vc2VfY29tcC50aXRsZSA9IGxwc3pUaXRsZTsKCiAgICByZXQgPSBEaWFsb2dCb3hQYXJhbVcoTVNWRlczMl9oTW9kdWxlLCBNQUtFSU5UUkVTT1VSQ0VXKElDTV9DSE9PU0VfQ09NUFJFU1NPUiksIGh3bmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWNtX2Nob29zZV9jb21wcmVzc29yX2RsZ3Byb2MsIChMUEFSQU0pJmNob29zZV9jb21wKTsKCiAgICBpZiAocmV0KQogICAgewogICAgICAgICpwYyA9IGNob29zZV9jb21wLmN2OwogICAgICAgIHBjLT5kd0ZsYWdzIHw9IElDTUZfQ09NUFZBUlNfVkFMSUQ7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSUNDb21wcmVzc29yRnJlZSAgIFtNU1ZGVzMyLkBdCiAqLwp2b2lkIFZGV0FQSSBJQ0NvbXByZXNzb3JGcmVlKFBDT01QVkFSUyBwYykKewogIFRSQUNFKCIoJXApXG4iLHBjKTsKCiAgaWYgKHBjICE9IE5VTEwgJiYgcGMtPmNiU2l6ZSA9PSBzaXplb2YoQ09NUFZBUlMpKSB7CiAgICBpZiAocGMtPmhpYyAhPSBOVUxMKSB7CiAgICAgIElDQ2xvc2UocGMtPmhpYyk7CiAgICAgIHBjLT5oaWMgPSBOVUxMOwogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGMtPmxwYmlJbik7CiAgICBwYy0+bHBiaUluID0gTlVMTDsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scEJpdHNPdXQpOwogICAgcGMtPmxwQml0c091dCA9IE5VTEw7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBCaXRzUHJldik7CiAgICBwYy0+bHBCaXRzUHJldiA9IE5VTEw7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBTdGF0ZSk7CiAgICBwYy0+bHBTdGF0ZSA9IE5VTEw7CiAgICBwYy0+ZHdGbGFncyA9IDA7CiAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVNWSURFT19TZW5kTWVzc2FnZQogKgogKgogKi8KTFJFU1VMVCBNU1ZJREVPX1NlbmRNZXNzYWdlKFdJTkVfSElDKiB3aGljLCBVSU5UIG1zZywgRFdPUkRfUFRSIGxQYXJhbTEsIERXT1JEX1BUUiBsUGFyYW0yKQp7CiAgICBMUkVTVUxUICAgICByZXQ7CiAgICAKI2RlZmluZSBYWCh4KSBjYXNlIHg6IFRSQUNFKCIoJXAsIiN4IiwweCUwOGx4LDB4JTA4bHgpXG4iLHdoaWMsbFBhcmFtMSxsUGFyYW0yKTsgYnJlYWs7CiAgICAKICAgIHN3aXRjaCAobXNnKSB7CiAgICAgICAgLyogRFJWXyogKi8KICAgICAgICBYWChEUlZfTE9BRCk7CiAgICAgICAgWFgoRFJWX0VOQUJMRSk7CiAgICAgICAgWFgoRFJWX09QRU4pOwogICAgICAgIFhYKERSVl9DTE9TRSk7CiAgICAgICAgWFgoRFJWX0RJU0FCTEUpOwogICAgICAgIFhYKERSVl9GUkVFKTsKICAgICAgICAvKiBJQ01fUkVTRVJWRUQrWCAqLwogICAgICAgIFhYKElDTV9BQk9VVCk7CiAgICAgICAgWFgoSUNNX0NPTkZJR1VSRSk7CiAgICAgICAgWFgoSUNNX0dFVCk7CiAgICAgICAgWFgoSUNNX0dFVElORk8pOwogICAgICAgIFhYKElDTV9HRVRERUZBVUxUUVVBTElUWSk7CiAgICAgICAgWFgoSUNNX0dFVFFVQUxJVFkpOwogICAgICAgIFhYKElDTV9HRVRTVEFURSk7CiAgICAgICAgWFgoSUNNX1NFVFFVQUxJVFkpOwogICAgICAgIFhYKElDTV9TRVQpOwogICAgICAgIFhYKElDTV9TRVRTVEFURSk7CiAgICAgICAgLyogSUNNX1VTRVIrWCAqLwogICAgICAgIFhYKElDTV9DT01QUkVTU19GUkFNRVNfSU5GTyk7CiAgICAgICAgWFgoSUNNX0NPTVBSRVNTX0dFVF9GT1JNQVQpOwogICAgICAgIFhYKElDTV9DT01QUkVTU19HRVRfU0laRSk7CiAgICAgICAgWFgoSUNNX0NPTVBSRVNTX1FVRVJZKTsKICAgICAgICBYWChJQ01fQ09NUFJFU1NfQkVHSU4pOwogICAgICAgIFhYKElDTV9DT01QUkVTUyk7CiAgICAgICAgWFgoSUNNX0NPTVBSRVNTX0VORCk7CiAgICAgICAgWFgoSUNNX0RFQ09NUFJFU1NfR0VUX0ZPUk1BVCk7CiAgICAgICAgWFgoSUNNX0RFQ09NUFJFU1NfUVVFUlkpOwogICAgICAgIFhYKElDTV9ERUNPTVBSRVNTX0JFR0lOKTsKICAgICAgICBYWChJQ01fREVDT01QUkVTUyk7CiAgICAgICAgWFgoSUNNX0RFQ09NUFJFU1NfRU5EKTsKICAgICAgICBYWChJQ01fREVDT01QUkVTU19TRVRfUEFMRVRURSk7CiAgICAgICAgWFgoSUNNX0RFQ09NUFJFU1NfR0VUX1BBTEVUVEUpOwogICAgICAgIFhYKElDTV9EUkFXX1FVRVJZKTsKICAgICAgICBYWChJQ01fRFJBV19CRUdJTik7CiAgICAgICAgWFgoSUNNX0RSQVdfR0VUX1BBTEVUVEUpOwogICAgICAgIFhYKElDTV9EUkFXX1NUQVJUKTsKICAgICAgICBYWChJQ01fRFJBV19TVE9QKTsKICAgICAgICBYWChJQ01fRFJBV19FTkQpOwogICAgICAgIFhYKElDTV9EUkFXX0dFVFRJTUUpOwogICAgICAgIFhYKElDTV9EUkFXKTsKICAgICAgICBYWChJQ01fRFJBV19XSU5ET1cpOwogICAgICAgIFhYKElDTV9EUkFXX1NFVFRJTUUpOwogICAgICAgIFhYKElDTV9EUkFXX1JFQUxJWkUpOwogICAgICAgIFhYKElDTV9EUkFXX0ZMVVNIKTsKICAgICAgICBYWChJQ01fRFJBV19SRU5ERVJCVUZGRVIpOwogICAgICAgIFhYKElDTV9EUkFXX1NUQVJUX1BMQVkpOwogICAgICAgIFhYKElDTV9EUkFXX1NUT1BfUExBWSk7CiAgICAgICAgWFgoSUNNX0RSQVdfU1VHR0VTVEZPUk1BVCk7CiAgICAgICAgWFgoSUNNX0RSQVdfQ0hBTkdFUEFMRVRURSk7CiAgICAgICAgWFgoSUNNX0dFVEJVRkZFUlNXQU5URUQpOwogICAgICAgIFhYKElDTV9HRVRERUZBVUxUS0VZRlJBTUVSQVRFKTsKICAgICAgICBYWChJQ01fREVDT01QUkVTU0VYX0JFR0lOKTsKICAgICAgICBYWChJQ01fREVDT01QUkVTU0VYX1FVRVJZKTsKICAgICAgICBYWChJQ01fREVDT01QUkVTU0VYKTsKICAgICAgICBYWChJQ01fREVDT01QUkVTU0VYX0VORCk7CiAgICAgICAgWFgoSUNNX1NFVF9TVEFUVVNfUFJPQyk7CiAgICBkZWZhdWx0OgogICAgICAgIEZJWE1FKCIoJXAsMHglMDh4LDB4JTA4bHgsMHglMDhseCkgdW5rbm93biBtZXNzYWdlXG4iLHdoaWMsKERXT1JEKW1zZyxsUGFyYW0xLGxQYXJhbTIpOwogICAgfQogICAgCiN1bmRlZiBYWAogICAgCiAgICBpZiAod2hpYy0+ZHJpdmVycHJvYykgewoJLyogZHdEcml2ZXJJZCBwYXJhbWV0ZXIgaXMgdGhlIHZhbHVlIHJldHVybmVkIGJ5IHRoZSBEUlZfT1BFTiAqLwogICAgICAgIHJldCA9IHdoaWMtPmRyaXZlcnByb2Mod2hpYy0+ZHJpdmVySWQsIHdoaWMtPmhkcnYsIG1zZywgbFBhcmFtMSwgbFBhcmFtMik7CiAgICB9IGVsc2UgewogICAgICAgIHJldCA9IFNlbmREcml2ZXJNZXNzYWdlKHdoaWMtPmhkcnYsIG1zZywgbFBhcmFtMSwgbFBhcmFtMik7CiAgICB9CgogICAgVFJBQ0UoIgktPiAweCUwOGx4XG4iLCByZXQpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ1NlbmRNZXNzYWdlCQkJW01TVkZXMzIuQF0KICovCkxSRVNVTFQgVkZXQVBJIElDU2VuZE1lc3NhZ2UoSElDIGhpYywgVUlOVCBtc2csIERXT1JEX1BUUiBsUGFyYW0xLCBEV09SRF9QVFIgbFBhcmFtMikgCnsKICAgIFdJTkVfSElDKiAgIHdoaWMgPSBNU1ZJREVPX0dldEhpY1B0cihoaWMpOwoKICAgIGlmICghd2hpYykgcmV0dXJuIElDRVJSX0JBREhBTkRMRTsKICAgIHJldHVybiBNU1ZJREVPX1NlbmRNZXNzYWdlKHdoaWMsIG1zZywgbFBhcmFtMSwgbFBhcmFtMik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSUNEcmF3QmVnaW4JCVtNU1ZGVzMyLkBdCiAqLwpEV09SRCBWRldBUElWIElDRHJhd0JlZ2luKAoJSElDICAgICAgICAgICAgICAgIGhpYywgICAgIC8qIFtpbl0gKi8KCURXT1JEICAgICAgICAgICAgICBkd0ZsYWdzLCAvKiBbaW5dIGZsYWdzICovCglIUEFMRVRURSAgICAgICAgICAgaHBhbCwgICAgLyogW2luXSBwYWxldHRlIHRvIGRyYXcgd2l0aCAqLwoJSFdORCAgICAgICAgICAgICAgIGh3bmQsICAgIC8qIFtpbl0gd2luZG93IHRvIGRyYXcgdG8gKi8KCUhEQyAgICAgICAgICAgICAgICBoZGMsICAgICAvKiBbaW5dIEhEQyB0byBkcmF3IHRvICovCglJTlQgICAgICAgICAgICAgICAgeERzdCwgICAgLyogW2luXSBkZXN0aW5hdGlvbiByZWN0YW5nbGUgKi8KCUlOVCAgICAgICAgICAgICAgICB5RHN0LCAgICAvKiBbaW5dICovCglJTlQgICAgICAgICAgICAgICAgZHhEc3QsICAgLyogW2luXSAqLwoJSU5UICAgICAgICAgICAgICAgIGR5RHN0LCAgIC8qIFtpbl0gKi8KCUxQQklUTUFQSU5GT0hFQURFUiBscGJpLCAgICAvKiBbaW5dIGZvcm1hdCBvZiBmcmFtZSB0byBkcmF3ICovCglJTlQgICAgICAgICAgICAgICAgeFNyYywgICAgLyogW2luXSBzb3VyY2UgcmVjdGFuZ2xlICovCglJTlQgICAgICAgICAgICAgICAgeVNyYywgICAgLyogW2luXSAqLwoJSU5UICAgICAgICAgICAgICAgIGR4U3JjLCAgIC8qIFtpbl0gKi8KCUlOVCAgICAgICAgICAgICAgICBkeVNyYywgICAvKiBbaW5dICovCglEV09SRCAgICAgICAgICAgICAgZHdSYXRlLCAgLyogW2luXSBmcmFtZXMvc2Vjb25kID0gKGR3UmF0ZS9kd1NjYWxlKSAqLwoJRFdPUkQgICAgICAgICAgICAgIGR3U2NhbGUpIC8qIFtpbl0gKi8KewoKCUlDRFJBV0JFR0lOCWljZGI7CgoJVFJBQ0UoIiglcCwlZCwlcCwlcCwlcCwldSwldSwldSwldSwlcCwldSwldSwldSwldSwlZCwlZClcbiIsCgkJICBoaWMsIGR3RmxhZ3MsIGhwYWwsIGh3bmQsIGhkYywgeERzdCwgeURzdCwgZHhEc3QsIGR5RHN0LAoJCSAgbHBiaSwgeFNyYywgeVNyYywgZHhTcmMsIGR5U3JjLCBkd1JhdGUsIGR3U2NhbGUpOwoKCWljZGIuZHdGbGFncyA9IGR3RmxhZ3M7CglpY2RiLmhwYWwgPSBocGFsOwoJaWNkYi5od25kID0gaHduZDsKCWljZGIuaGRjID0gaGRjOwoJaWNkYi54RHN0ID0geERzdDsKCWljZGIueURzdCA9IHlEc3Q7CglpY2RiLmR4RHN0ID0gZHhEc3Q7CglpY2RiLmR5RHN0ID0gZHlEc3Q7CglpY2RiLmxwYmkgPSBscGJpOwoJaWNkYi54U3JjID0geFNyYzsKCWljZGIueVNyYyA9IHlTcmM7CglpY2RiLmR4U3JjID0gZHhTcmM7CglpY2RiLmR5U3JjID0gZHlTcmM7CglpY2RiLmR3UmF0ZSA9IGR3UmF0ZTsKCWljZGIuZHdTY2FsZSA9IGR3U2NhbGU7CglyZXR1cm4gSUNTZW5kTWVzc2FnZShoaWMsSUNNX0RSQVdfQkVHSU4sKERXT1JEX1BUUikmaWNkYixzaXplb2YoaWNkYikpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlDRHJhdwkJCVtNU1ZGVzMyLkBdCiAqLwpEV09SRCBWRldBUElWIElDRHJhdyhISUMgaGljLCBEV09SRCBkd0ZsYWdzLCBMUFZPSUQgbHBGb3JtYXQsIExQVk9JRCBscERhdGEsIERXT1JEIGNiRGF0YSwgTE9ORyBsVGltZSkgewoJSUNEUkFXCWljZDsKCglUUkFDRSgiKCVwLCVkLCVwLCVwLCVkLCVkKVxuIixoaWMsZHdGbGFncyxscEZvcm1hdCxscERhdGEsY2JEYXRhLGxUaW1lKTsKCglpY2QuZHdGbGFncyA9IGR3RmxhZ3M7CglpY2QubHBGb3JtYXQgPSBscEZvcm1hdDsKCWljZC5scERhdGEgPSBscERhdGE7CglpY2QuY2JEYXRhID0gY2JEYXRhOwoJaWNkLmxUaW1lID0gbFRpbWU7CgoJcmV0dXJuIElDU2VuZE1lc3NhZ2UoaGljLElDTV9EUkFXLChEV09SRF9QVFIpJmljZCxzaXplb2YoaWNkKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSUNDbG9zZQkJCVtNU1ZGVzMyLkBdCiAqLwpMUkVTVUxUIFdJTkFQSSBJQ0Nsb3NlKEhJQyBoaWMpCnsKICAgIFdJTkVfSElDKiB3aGljID0gTVNWSURFT19HZXRIaWNQdHIoaGljKTsKICAgIFdJTkVfSElDKiogcDsKCiAgICBUUkFDRSgiKCVwKVxuIixoaWMpOwoKICAgIGlmICghd2hpYykgcmV0dXJuIElDRVJSX0JBREhBTkRMRTsKCiAgICBpZiAod2hpYy0+ZHJpdmVycHJvYykgCiAgICB7CiAgICAgICAgTVNWSURFT19TZW5kTWVzc2FnZSh3aGljLCBEUlZfQ0xPU0UsIDAsIDApOwogICAgICAgIE1TVklERU9fU2VuZE1lc3NhZ2Uod2hpYywgRFJWX0RJU0FCTEUsIDAsIDApOwogICAgICAgIE1TVklERU9fU2VuZE1lc3NhZ2Uod2hpYywgRFJWX0ZSRUUsIDAsIDApOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIENsb3NlRHJpdmVyKHdoaWMtPmhkcnYsIDAsIDApOwogICAgfQoKICAgIC8qIHJlbW92ZSB3aGljIGZyb20gbGlzdCAqLwogICAgZm9yIChwID0gJk1TVklERU9fRmlyc3RIaWM7ICpwICE9IE5VTEw7IHAgPSAmKCgqcCktPm5leHQpKQogICAgewogICAgICAgIGlmICgoKnApID09IHdoaWMpCiAgICAgICAgewogICAgICAgICAgICAqcCA9IHdoaWMtPm5leHQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCB3aGljKTsKICAgIHJldHVybiAwOwp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSUNJbWFnZUNvbXByZXNzCVtNU1ZGVzMyLkBdCiAqLwpIQU5ETEUgVkZXQVBJIElDSW1hZ2VDb21wcmVzcygKCUhJQyBoaWMsIFVJTlQgdWlGbGFncywKCUxQQklUTUFQSU5GTyBscGJpSW4sIExQVk9JRCBscEJpdHMsCglMUEJJVE1BUElORk8gbHBiaU91dCwgTE9ORyBsUXVhbGl0eSwKCUxPTkcqIHBsU2l6ZSkKewoJRklYTUUoIiglcCwlMDh4LCVwLCVwLCVwLCVkLCVwKVxuIiwKCQloaWMsIHVpRmxhZ3MsIGxwYmlJbiwgbHBCaXRzLCBscGJpT3V0LCBsUXVhbGl0eSwgcGxTaXplKTsKCglyZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ0ltYWdlRGVjb21wcmVzcwlbTVNWRlczMi5AXQogKi8KCkhBTkRMRSBWRldBUEkgSUNJbWFnZURlY29tcHJlc3MoCglISUMgaGljLCBVSU5UIHVpRmxhZ3MsIExQQklUTUFQSU5GTyBscGJpSW4sCglMUFZPSUQgbHBCaXRzLCBMUEJJVE1BUElORk8gbHBiaU91dCkKewoJSEdMT0JBTAloTWVtID0gTlVMTDsKCUJZVEUqCXBNZW0gPSBOVUxMOwoJQk9PTAliUmVsZWFzZUlDID0gRkFMU0U7CglCWVRFKglwSGRyID0gTlVMTDsKCVVMT05HCWNiSGRyID0gMDsKCUJPT0wJYlN1Y2NlZWRlZCA9IEZBTFNFOwoJQk9PTAliSW5EZWNvbXByZXNzID0gRkFMU0U7CglEV09SRAliaVNpemVJbWFnZTsKCglUUkFDRSgiKCVwLCUwOHgsJXAsJXAsJXApXG4iLAoJCWhpYywgdWlGbGFncywgbHBiaUluLCBscEJpdHMsIGxwYmlPdXQpOwoKCWlmICggaGljID09IE5VTEwgKQoJewoJCWhpYyA9IElDRGVjb21wcmVzc09wZW4oIElDVFlQRV9WSURFTywgMCwgJmxwYmlJbi0+Ym1pSGVhZGVyLCAobHBiaU91dCAhPSBOVUxMKSA/ICZscGJpT3V0LT5ibWlIZWFkZXIgOiBOVUxMICk7CgkJaWYgKCBoaWMgPT0gTlVMTCApCgkJewoJCQlXQVJOKCJubyBoYW5kbGVyXG4iICk7CgkJCWdvdG8gZXJyOwoJCX0KCQliUmVsZWFzZUlDID0gVFJVRTsKCX0KCWlmICggdWlGbGFncyAhPSAwICkKCXsKCQlGSVhNRSggInVua25vd24gZmxhZyAlMDh4XG4iLCB1aUZsYWdzICk7CgkJZ290byBlcnI7Cgl9CglpZiAoIGxwYmlJbiA9PSBOVUxMIHx8IGxwQml0cyA9PSBOVUxMICkKCXsKCQlXQVJOKCJpbnZhbGlkIGFyZ3VtZW50XG4iKTsKCQlnb3RvIGVycjsKCX0KCglpZiAoIGxwYmlPdXQgIT0gTlVMTCApCgl7CgkJaWYgKCBscGJpT3V0LT5ibWlIZWFkZXIuYmlTaXplICE9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSApCgkJCWdvdG8gZXJyOwoJCWNiSGRyID0gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpOwoJCWlmICggbHBiaU91dC0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPT0gMyApCgkJCWNiSGRyICs9IHNpemVvZihEV09SRCkqMzsKCQllbHNlCgkJaWYgKCBscGJpT3V0LT5ibWlIZWFkZXIuYmlCaXRDb3VudCA8PSA4ICkKCQl7CgkJCWlmICggbHBiaU91dC0+Ym1pSGVhZGVyLmJpQ2xyVXNlZCA9PSAwICkKCQkJCWNiSGRyICs9IHNpemVvZihSR0JRVUFEKSAqICgxPDxscGJpT3V0LT5ibWlIZWFkZXIuYmlCaXRDb3VudCk7CgkJCWVsc2UKCQkJCWNiSGRyICs9IHNpemVvZihSR0JRVUFEKSAqIGxwYmlPdXQtPmJtaUhlYWRlci5iaUNsclVzZWQ7CgkJfQoJfQoJZWxzZQoJewoJCVRSQUNFKCAiZ2V0IGZvcm1hdFxuIiApOwoKCQljYkhkciA9IElDRGVjb21wcmVzc0dldEZvcm1hdFNpemUoaGljLGxwYmlJbik7CgkJaWYgKCBjYkhkciA8IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSApCgkJCWdvdG8gZXJyOwoJCXBIZHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLGNiSGRyK3NpemVvZihSR0JRVUFEKSoyNTYpOwoJCWlmICggcEhkciA9PSBOVUxMICkKCQkJZ290byBlcnI7CgkJaWYgKCBJQ0RlY29tcHJlc3NHZXRGb3JtYXQoIGhpYywgbHBiaUluLCAoQklUTUFQSU5GTyopcEhkciApICE9IElDRVJSX09LICkKCQkJZ290byBlcnI7CgkJbHBiaU91dCA9IChCSVRNQVBJTkZPKilwSGRyOwoJCWlmICggbHBiaU91dC0+Ym1pSGVhZGVyLmJpQml0Q291bnQgPD0gOCAmJgoJCQkgSUNEZWNvbXByZXNzR2V0UGFsZXR0ZSggaGljLCBscGJpSW4sIGxwYmlPdXQgKSAhPSBJQ0VSUl9PSyAmJgoJCQkgbHBiaUluLT5ibWlIZWFkZXIuYmlCaXRDb3VudCA9PSBscGJpT3V0LT5ibWlIZWFkZXIuYmlCaXRDb3VudCApCgkJewoJCQlpZiAoIGxwYmlJbi0+Ym1pSGVhZGVyLmJpQ2xyVXNlZCA9PSAwICkKCQkJCW1lbWNweSggbHBiaU91dC0+Ym1pQ29sb3JzLCBscGJpSW4tPmJtaUNvbG9ycywgc2l6ZW9mKFJHQlFVQUQpKigxPDxscGJpT3V0LT5ibWlIZWFkZXIuYmlCaXRDb3VudCkgKTsKCQkJZWxzZQoJCQkJbWVtY3B5KCBscGJpT3V0LT5ibWlDb2xvcnMsIGxwYmlJbi0+Ym1pQ29sb3JzLCBzaXplb2YoUkdCUVVBRCkqbHBiaUluLT5ibWlIZWFkZXIuYmlDbHJVc2VkICk7CgkJfQoJCWlmICggbHBiaU91dC0+Ym1pSGVhZGVyLmJpQml0Q291bnQgPD0gOCAmJgoJCQkgbHBiaU91dC0+Ym1pSGVhZGVyLmJpQ2xyVXNlZCA9PSAwICkKCQkJbHBiaU91dC0+Ym1pSGVhZGVyLmJpQ2xyVXNlZCA9IDE8PGxwYmlPdXQtPmJtaUhlYWRlci5iaUJpdENvdW50OwoKCQlscGJpT3V0LT5ibWlIZWFkZXIuYmlTaXplID0gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpOwoJCWNiSGRyID0gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpICsgc2l6ZW9mKFJHQlFVQUQpKmxwYmlPdXQtPmJtaUhlYWRlci5iaUNsclVzZWQ7Cgl9CgoJYmlTaXplSW1hZ2UgPSBscGJpT3V0LT5ibWlIZWFkZXIuYmlTaXplSW1hZ2U7CglpZiAoIGJpU2l6ZUltYWdlID09IDAgKQoJCWJpU2l6ZUltYWdlID0gKCgoKGxwYmlPdXQtPmJtaUhlYWRlci5iaVdpZHRoICogbHBiaU91dC0+Ym1pSGVhZGVyLmJpQml0Q291bnQgKyA3KSA+PiAzKSArIDMpICYgKH4zKSkgKiBhYnMobHBiaU91dC0+Ym1pSGVhZGVyLmJpSGVpZ2h0KTsKCglUUkFDRSggImNhbGwgSUNEZWNvbXByZXNzQmVnaW5cbiIgKTsKCglpZiAoIElDRGVjb21wcmVzc0JlZ2luKCBoaWMsIGxwYmlJbiwgbHBiaU91dCApICE9IElDRVJSX09LICkKCQlnb3RvIGVycjsKCWJJbkRlY29tcHJlc3MgPSBUUlVFOwoKCVRSQUNFKCAiY2JIZHIgJWQsIGJpU2l6ZUltYWdlICVkXG4iLCBjYkhkciwgYmlTaXplSW1hZ2UgKTsKCgloTWVtID0gR2xvYmFsQWxsb2MoIEdNRU1fTU9WRUFCTEV8R01FTV9aRVJPSU5JVCwgY2JIZHIgKyBiaVNpemVJbWFnZSApOwoJaWYgKCBoTWVtID09IE5VTEwgKQoJewoJCVdBUk4oICJvdXQgb2YgbWVtb3J5XG4iICk7CgkJZ290byBlcnI7Cgl9CglwTWVtID0gKEJZVEUqKUdsb2JhbExvY2soIGhNZW0gKTsKCWlmICggcE1lbSA9PSBOVUxMICkKCQlnb3RvIGVycjsKCW1lbWNweSggcE1lbSwgbHBiaU91dCwgY2JIZHIgKTsKCglUUkFDRSggImNhbGwgSUNEZWNvbXByZXNzXG4iICk7CglpZiAoIElDRGVjb21wcmVzcyggaGljLCAwLCAmbHBiaUluLT5ibWlIZWFkZXIsIGxwQml0cywgJmxwYmlPdXQtPmJtaUhlYWRlciwgcE1lbStjYkhkciApICE9IElDRVJSX09LICkKCQlnb3RvIGVycjsKCgliU3VjY2VlZGVkID0gVFJVRTsKZXJyOgoJaWYgKCBiSW5EZWNvbXByZXNzICkKCQlJQ0RlY29tcHJlc3NFbmQoIGhpYyApOwoJaWYgKCBiUmVsZWFzZUlDICkKCQlJQ0Nsb3NlKGhpYyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLHBIZHIpOwoJaWYgKCBwTWVtICE9IE5VTEwgKQoJCUdsb2JhbFVubG9jayggaE1lbSApOwoJaWYgKCAhYlN1Y2NlZWRlZCAmJiBoTWVtICE9IE5VTEwgKQoJewoJCUdsb2JhbEZyZWUoaE1lbSk7IGhNZW0gPSBOVUxMOwoJfQoKCXJldHVybiAoSEFORExFKWhNZW07Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIElDU2VxQ29tcHJlc3NGcmFtZSAgIFtNU1ZGVzMyLkBdCiAqLwpMUFZPSUQgVkZXQVBJIElDU2VxQ29tcHJlc3NGcmFtZShQQ09NUFZBUlMgcGMsIFVJTlQgdWlGbGFncywgTFBWT0lEIGxwQml0cywgQk9PTCAqcGZLZXksIExPTkcgKnBsU2l6ZSkKewogICAgSUNDT01QUkVTUyogaWNDb21wID0gKElDQ09NUFJFU1MgKilwYy0+bHBTdGF0ZTsKICAgIERXT1JEIHJldDsKICAgIFRSQUNFKCIoJXAsIDB4JTA4eCwgJXAsICVwLCAlcClcbiIsIHBjLCB1aUZsYWdzLCBscEJpdHMsIHBmS2V5LCBwbFNpemUpOwoKICAgIGlmIChwYy0+Y2JTdGF0ZSAhPSBzaXplb2YoSUNDT01QUkVTUykpCiAgICB7CiAgICAgICBFUlIoIkludmFsaWQgY2JTdGF0ZSAlaVxuIiwgcGMtPmNiU3RhdGUpOwogICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKCFwYy0+bEtleUNvdW50KyspCiAgICAgICBpY0NvbXAtPmR3RmxhZ3MgPSBJQ0NPTVBSRVNTX0tFWUZSQU1FOwogICAgZWxzZQogICAgewogICAgICAgIGlmIChwYy0+bEtleSAmJiBwYy0+bEtleUNvdW50ID09IChwYy0+bEtleSAtIDEpKQogICAgICAgIC8qIE5vIGtleSBmcmFtZXMgaWYgcGMtPmxLZXkgPT0gMCAqLwogICAgICAgICAgIHBjLT5sS2V5Q291bnQgPSAwOwoJaWNDb21wLT5kd0ZsYWdzID0gMDsKICAgIH0KCiAgICBpY0NvbXAtPmxwSW5wdXQgPSBscEJpdHM7CiAgICBpY0NvbXAtPmxGcmFtZU51bSA9IHBjLT5sRnJhbWUrKzsKICAgIGljQ29tcC0+bHBPdXRwdXQgPSBwYy0+bHBCaXRzT3V0OwogICAgaWNDb21wLT5scFByZXYgPSBwYy0+bHBCaXRzUHJldjsKICAgIHJldCA9IElDU2VuZE1lc3NhZ2UocGMtPmhpYywgSUNNX0NPTVBSRVNTLCAoRFdPUkRfUFRSKWljQ29tcCwgc2l6ZW9mKGljQ29tcCkpOwoKICAgIGlmIChpY0NvbXAtPmR3RmxhZ3MgJiBBVklJRl9LRVlGUkFNRSkKICAgIHsKICAgICAgIHBjLT5sS2V5Q291bnQgPSAxOwogICAgICAgKnBmS2V5ID0gVFJVRTsKICAgICAgIFRSQUNFKCJLZXkgZnJhbWVcbiIpOwogICAgfQogICAgZWxzZQogICAgICAgKnBmS2V5ID0gRkFMU0U7CgogICAgKnBsU2l6ZSA9IGljQ29tcC0+bHBiaU91dHB1dC0+YmlTaXplSW1hZ2U7CiAgICBUUkFDRSgiIC0tIDB4JTA4eFxuIiwgcmV0KTsKICAgIGlmIChyZXQgPT0gSUNFUlJfT0spCiAgICB7CiAgICAgICBMUFZPSUQgb2xkcHJldiwgb2xkb3V0OwovKiBXZSBzaGlmdCBQcmV2IGFuZCBPdXQsIHNvIHdlIGRvbid0IGhhdmUgdG8gYWxsb2NhdGUgYW5kIHJlbGVhc2UgbWVtb3J5ICovCiAgICAgICBvbGRwcmV2ID0gcGMtPmxwQml0c1ByZXY7CiAgICAgICBvbGRvdXQgPSBwYy0+bHBCaXRzT3V0OwogICAgICAgcGMtPmxwQml0c1ByZXYgPSBvbGRvdXQ7CiAgICAgICBwYy0+bHBCaXRzT3V0ID0gb2xkcHJldjsKCiAgICAgICBUUkFDRSgicmV0dXJuaW5nOiAlcFxuIiwgaWNDb21wLT5scE91dHB1dCk7CiAgICAgICByZXR1cm4gaWNDb21wLT5scE91dHB1dDsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBJQ1NlcUNvbXByZXNzRnJhbWVFbmQgICBbTVNWRlczMi5AXQogKi8Kdm9pZCBWRldBUEkgSUNTZXFDb21wcmVzc0ZyYW1lRW5kKFBDT01QVkFSUyBwYykKewogICAgRFdPUkQgcmV0OwogICAgVFJBQ0UoIiglcClcbiIsIHBjKTsKICAgIHJldCA9IElDU2VuZE1lc3NhZ2UocGMtPmhpYywgSUNNX0NPTVBSRVNTX0VORCwgMCwgMCk7CiAgICBUUkFDRSgiIC0tICV4XG4iLCByZXQpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGMtPmxwYmlJbik7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBCaXRzUHJldik7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBCaXRzT3V0KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scFN0YXRlKTsKICAgIHBjLT5scGJpSW4gPSBwYy0+bHBCaXRzUHJldiA9IHBjLT5scEJpdHNPdXQgPSBwYy0+bHBTdGF0ZSA9IE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIElDU2VxQ29tcHJlc3NGcmFtZVN0YXJ0IFtNU1ZGVzMyLkBdCiAqLwpCT09MIFZGV0FQSSBJQ1NlcUNvbXByZXNzRnJhbWVTdGFydChQQ09NUFZBUlMgcGMsIExQQklUTUFQSU5GTyBscGJpSW4pCnsKICAgIC8qIEknbSBpZ25vcmluZyBibWlDb2xvcnMgYXMgSSBkb24ndCBrbm93IHdoYXQgdG8gZG8gd2l0aCBpdCwKICAgICAqIGl0IGRvZXNuJ3QgYXBwZWFyIHRvIGJlIHVzZWQgdGhvdWdoCiAgICAgKi8KICAgIERXT1JEIHJldDsKICAgIHBjLT5scGJpSW4gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKEJJVE1BUElORk8pKTsKICAgIGlmICghcGMtPmxwYmlJbikKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgbWVtY3B5KHBjLT5scGJpSW4sIGxwYmlJbiwgc2l6ZW9mKEJJVE1BUElORk8pKTsKICAgIHBjLT5scEJpdHNQcmV2ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scGJpSW4tPmJtaUhlYWRlci5iaVNpemVJbWFnZSk7CiAgICBpZiAoIXBjLT5scEJpdHNQcmV2KQogICAgewogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scGJpSW4pOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHBjLT5scFN0YXRlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihJQ0NPTVBSRVNTKSk7CiAgICBpZiAoIXBjLT5scFN0YXRlKQogICAgewogICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGMtPmxwYmlJbik7CiAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBCaXRzUHJldik7CiAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBwYy0+Y2JTdGF0ZSA9IHNpemVvZihJQ0NPTVBSRVNTKTsKCiAgICBwYy0+bHBCaXRzT3V0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scGJpT3V0LT5ibWlIZWFkZXIuYmlTaXplSW1hZ2UpOwogICAgaWYgKCFwYy0+bHBCaXRzT3V0KQogICAgewogICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGMtPmxwYmlJbik7CiAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBCaXRzUHJldik7CiAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBTdGF0ZSk7CiAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBUUkFDRSgiQ29tcHZhcnM6XG4iCiAgICAgICAgICAiXHRwYzpcbiIKICAgICAgICAgICJcdHNpemU6ICVpXG4iCiAgICAgICAgICAiXHRmbGFnczogJWlcbiIKICAgICAgICAgICJcdGhpYzogJXBcbiIKICAgICAgICAgICJcdHR5cGU6ICV4XG4iCiAgICAgICAgICAiXHRoYW5kbGVyOiAleFxuIgogICAgICAgICAgIlx0aW4vb3V0OiAlcC8lcFxuIgogICAgICAgICAgImtleS9kYXRhL3F1YWxpdHk6ICVpLyVpLyVpXG4iLAoJICAgICBwYy0+Y2JTaXplLCBwYy0+ZHdGbGFncywgcGMtPmhpYywgcGMtPmZjY1R5cGUsIHBjLT5mY2NIYW5kbGVyLAoJICAgICBwYy0+bHBiaUluLCBwYy0+bHBiaU91dCwgcGMtPmxLZXksIHBjLT5sRGF0YVJhdGUsIHBjLT5sUSk7CgogICAgcmV0ID0gSUNTZW5kTWVzc2FnZShwYy0+aGljLCBJQ01fQ09NUFJFU1NfQkVHSU4sIChEV09SRF9QVFIpcGMtPmxwYmlJbiwgKERXT1JEX1BUUilwYy0+bHBiaU91dCk7CiAgICBUUkFDRSgiIC0tICV4XG4iLCByZXQpOwogICAgaWYgKHJldCA9PSBJQ0VSUl9PSykKICAgIHsKICAgICAgIElDQ09NUFJFU1MqIGljQ29tcCA9IChJQ0NPTVBSRVNTICopcGMtPmxwU3RhdGU7CiAgICAgICAvKiBJbml0aWFsaXNlIHNvbWUgdmFyaWFibGVzICovCiAgICAgICBwYy0+bEZyYW1lID0gMDsgcGMtPmxLZXlDb3VudCA9IDA7CgogICAgICAgaWNDb21wLT5scGJpT3V0cHV0ID0gJnBjLT5scGJpT3V0LT5ibWlIZWFkZXI7CiAgICAgICBpY0NvbXAtPmxwYmlJbnB1dCA9ICZwYy0+bHBiaUluLT5ibWlIZWFkZXI7CiAgICAgICBpY0NvbXAtPmxwY2tpZCA9IE5VTEw7CiAgICAgICBpY0NvbXAtPmR3RnJhbWVTaXplID0gMDsKICAgICAgIGljQ29tcC0+ZHdRdWFsaXR5ID0gcGMtPmxROwogICAgICAgaWNDb21wLT5scGJpUHJldiA9ICZwYy0+bHBiaUluLT5ibWlIZWFkZXI7CiAgICAgICByZXR1cm4gVFJVRTsKICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scGJpSW4pOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGMtPmxwQml0c1ByZXYpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGMtPmxwU3RhdGUpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGMtPmxwQml0c091dCk7CiAgICBwYy0+bHBCaXRzUHJldiA9IHBjLT5scGJpSW4gPSBwYy0+bHBTdGF0ZSA9IHBjLT5scEJpdHNPdXQgPSBOVUxMOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBHZXRGaWxlTmFtZVByZXZpZXcgICBbTVNWRlczMi5AXQogKi8Kc3RhdGljIEJPT0wgR2V0RmlsZU5hbWVQcmV2aWV3KExQVk9JRCBscG9mbixCT09MIGJTYXZlLEJPT0wgYlVuaWNvZGUpCnsKICBDSEFSICAgIHN6RnVuY3Rpb25OYW1lWzIwXTsKICBCT09MICAgICgqZm5HZXRGaWxlTmFtZSkoTFBWT0lEKTsKICBITU9EVUxFIGhDb21kbGczMjsKICBCT09MICAgIHJldDsKCiAgRklYTUUoIiglcCwlZCwlZCksIHNlbWktc3R1YiFcbiIsbHBvZm4sYlNhdmUsYlVuaWNvZGUpOwoKICBsc3RyY3B5QShzekZ1bmN0aW9uTmFtZSwgKGJTYXZlID8gIkdldFNhdmVGaWxlTmFtZSIgOiAiR2V0T3BlbkZpbGVOYW1lIikpOwogIGxzdHJjYXRBKHN6RnVuY3Rpb25OYW1lLCAoYlVuaWNvZGUgPyAiVyIgOiAiQSIpKTsKCiAgaENvbWRsZzMyID0gTG9hZExpYnJhcnlBKCJDT01ETEczMi5ETEwiKTsKICBpZiAoaENvbWRsZzMyID09IE5VTEwpCiAgICByZXR1cm4gRkFMU0U7CgogIGZuR2V0RmlsZU5hbWUgPSAoTFBWT0lEKUdldFByb2NBZGRyZXNzKGhDb21kbGczMiwgc3pGdW5jdGlvbk5hbWUpOwogIGlmIChmbkdldEZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gRkFMU0U7CgogIC8qIEZJWE1FOiBuZWVkIHRvIGFkZCBPRk5fRU5BQkxFSE9PSyBhbmQgb3VyIG93biBoYW5kbGVyICovCiAgcmV0ID0gZm5HZXRGaWxlTmFtZShscG9mbik7CgogIEZyZWVMaWJyYXJ5KGhDb21kbGczMik7CiAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRPcGVuRmlsZU5hbWVQcmV2aWV3QQlbTVNWRlczMi5AXQogKi8KQk9PTCBXSU5BUEkgR2V0T3BlbkZpbGVOYW1lUHJldmlld0EoTFBPUEVORklMRU5BTUVBIGxwb2ZuKQp7CiAgRklYTUUoIiglcCksIHNlbWktc3R1YiFcbiIsIGxwb2ZuKTsKCiAgcmV0dXJuIEdldEZpbGVOYW1lUHJldmlldyhscG9mbiwgRkFMU0UsIEZBTFNFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRPcGVuRmlsZU5hbWVQcmV2aWV3VwlbTVNWRlczMi5AXQogKi8KQk9PTCBXSU5BUEkgR2V0T3BlbkZpbGVOYW1lUHJldmlld1coTFBPUEVORklMRU5BTUVXIGxwb2ZuKQp7CiAgRklYTUUoIiglcCksIHNlbWktc3R1YiFcbiIsIGxwb2ZuKTsKCiAgcmV0dXJuIEdldEZpbGVOYW1lUHJldmlldyhscG9mbiwgRkFMU0UsIFRSVUUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFNhdmVGaWxlTmFtZVByZXZpZXdBCVtNU1ZGVzMyLkBdCiAqLwpCT09MIFdJTkFQSSBHZXRTYXZlRmlsZU5hbWVQcmV2aWV3QShMUE9QRU5GSUxFTkFNRUEgbHBvZm4pCnsKICBGSVhNRSgiKCVwKSwgc2VtaS1zdHViIVxuIiwgbHBvZm4pOwoKICByZXR1cm4gR2V0RmlsZU5hbWVQcmV2aWV3KGxwb2ZuLCBUUlVFLCBGQUxTRSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0U2F2ZUZpbGVOYW1lUHJldmlld1cJW01TVkZXMzIuQF0KICovCkJPT0wgV0lOQVBJIEdldFNhdmVGaWxlTmFtZVByZXZpZXdXKExQT1BFTkZJTEVOQU1FVyBscG9mbikKewogIEZJWE1FKCIoJXApLCBzZW1pLXN0dWIhXG4iLCBscG9mbik7CgogIHJldHVybiBHZXRGaWxlTmFtZVByZXZpZXcobHBvZm4sIFRSVUUsIFRSVUUpOwp9Cg==