LyogLSotIHRhYi13aWR0aDogODsgYy1iYXNpYy1vZmZzZXQ6IDQgLSotICovCi8qCiAqIEFuaW1hdGlvbiBjb250cm9sCiAqCiAqIENvcHlyaWdodCAxOTk4LCAxOTk5IEVyaWMgS29obAogKiAJCSAgIDE5OTkgRXJpYyBQb3VlY2gKICoKICogTk9URVMKICogICBJIHdpbGwgb25seSBpbXByb3ZlIHRoaXMgY29udHJvbCBvbmNlIGluIGEgd2hpbGUuCiAqICAgICBFcmljIDxla29obEBhYm8ucmhlaW4temVpdHVuZy5kZT4KICoKICogVE9ETzoKICogICAtIGNoZWNrIGZvciB0aGUgJ3JlYyAnIGxpc3QgaW4gc29tZSBBVkkgZmlsZXMKICogICAtIGltcGxlbWVudCBzb21lIG1pc3NpbmcgZmxhZ3MgKEFDU19UUkFOU1BBUkVOVCBhbmQgQUNTX0NFTlRFUikKICogICAtIHByb3RlY3Rpb24gYmV0d2VlbiBzZXJ2aWNlIHRocmVhZCBhbmQgd25kcHJvYyBtZXNzYWdlcyBoYW5kbGluZyAKICogICAgIGNvbmN1cnJlbnQgYWNjZXNzIHRvIGluZm9QdHIKICovCgoKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgImNvbW1jdHJsLmgiCiNpbmNsdWRlICJkcml2ZXIuaCIKI2luY2x1ZGUgImFuaW1hdGUuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJzZXJ2aWNlcy5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKGFuaW1hdGUpCgojZGVmaW5lIEFOSU1BVEVfR2V0SW5mb1B0cihoV25kKSAoKEFOSU1BVEVfSU5GTyAqKUdldFdpbmRvd0xvbmdBKGhXbmQsIDApKQoKc3RhdGljIHZvaWQgQU5JTUFURV9Ob3RpZnkoQU5JTUFURV9JTkZPKiBpbmZvUHRyLCBVSU5UIG5vdGlmKQp7CiAgICBTZW5kTWVzc2FnZUEoR2V0UGFyZW50KGluZm9QdHItPmhXbmQpLCBXTV9DT01NQU5ELCAKCQkgTUFLRVdQQVJBTShHZXREbGdDdHJsSUQoaW5mb1B0ci0+aFduZCksIG5vdGlmKSwgCgkJIChMUEFSQU0paW5mb1B0ci0+aFduZCk7Cn0KCnN0YXRpYyBCT09MIEFOSU1BVEVfTG9hZFJlc0EoQU5JTUFURV9JTkZPICppbmZvUHRyLCBISU5TVEFOQ0UgaEluc3QsIExQU1RSIGxwTmFtZSkKewogICAgSFJTUkMgCWhyc3JjOwogICAgTU1JT0lORk8JbW1pbmZvOwogICAgTFBWT0lECWxwQXZpOwogICAgCiAgICBocnNyYyA9IEZpbmRSZXNvdXJjZUEoaEluc3QsIGxwTmFtZSwgIkFWSSIpOwogICAgaWYgKCFocnNyYykKCXJldHVybiBGQUxTRTsKICAgIAogICAgaW5mb1B0ci0+aFJlcyA9IExvYWRSZXNvdXJjZShoSW5zdCwgaHJzcmMpOwogICAgaWYgKCFpbmZvUHRyLT5oUmVzKQogCXJldHVybiBGQUxTRTsKICAgIAogICAgbHBBdmkgPSBMb2NrUmVzb3VyY2UoaW5mb1B0ci0+aFJlcyk7CiAgICBpZiAoIWxwQXZpKQoJcmV0dXJuIEZBTFNFOwogICAgCiAgICBtZW1zZXQoJm1taW5mbywgMCwgc2l6ZW9mKG1taW5mbykpOwogICAgbW1pbmZvLmZjY0lPUHJvYyA9IEZPVVJDQ19NRU07CiAgICBtbWluZm8ucGNoQnVmZmVyID0gKExQU1RSKWxwQXZpOwogICAgbW1pbmZvLmNjaEJ1ZmZlciA9IFNpemVvZlJlc291cmNlKGhJbnN0LCBocnNyYyk7CiAgICBpbmZvUHRyLT5oTU1pbyA9IG1taW9PcGVuQShOVUxMLCAmbW1pbmZvLCBNTUlPX1JFQUQpOwogICAgCiAgICBpZiAoIWluZm9QdHItPmhNTWlvKSB7CglHbG9iYWxGcmVlKChIR0xPQkFMKWxwQXZpKTsKCXJldHVybiBGQUxTRTsKICAgIH0KICAgIAogICAgcmV0dXJuIFRSVUU7Cn0KCgpzdGF0aWMgQk9PTCBBTklNQVRFX0xvYWRGaWxlQShBTklNQVRFX0lORk8gKmluZm9QdHIsIExQU1RSIGxwTmFtZSkKewogICAgaW5mb1B0ci0+aE1NaW8gPSBtbWlvT3BlbkEoKExQU1RSKWxwTmFtZSwgTlVMTCwKCQkJICAgICAgIE1NSU9fQUxMT0NCVUYgfCBNTUlPX1JFQUQgfCBNTUlPX0RFTllXUklURSk7CiAgICAKICAgIGlmICghaW5mb1B0ci0+aE1NaW8pCglyZXR1cm4gRkFMU0U7CiAgICAKICAgIHJldHVybiBUUlVFOwp9CgoKc3RhdGljIHZvaWQgQU5JTUFURV9GcmVlKEFOSU1BVEVfSU5GTyAqaW5mb1B0cikKewogICAgaWYgKGluZm9QdHItPmhNTWlvKSB7CgltbWlvQ2xvc2UoaW5mb1B0ci0+aE1NaW8sIDApOwoJaWYgKGluZm9QdHItPmhSZXMpIHsKIAkgICAgRnJlZVJlc291cmNlKGluZm9QdHItPmhSZXMpOwoJICAgIGluZm9QdHItPmhSZXMgPSAwOwoJfQoJaWYgKGluZm9QdHItPmxwSW5kZXgpIHsKCSAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvUHRyLT5scEluZGV4KTsKCSAgICBpbmZvUHRyLT5scEluZGV4ID0gTlVMTDsKCX0KCWlmIChpbmZvUHRyLT5oaWMpIHsKCSAgICAoaW5mb1B0ci0+Zm5JQ0Nsb3NlKShpbmZvUHRyLT5oaWMpOwoJICAgIGluZm9QdHItPmhpYyA9IDA7Cgl9CglpZiAoaW5mb1B0ci0+aW5iaWgpIHsKCSAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvUHRyLT5pbmJpaCk7CgkgICAgaW5mb1B0ci0+aW5iaWggPSBOVUxMOwoJfQoJaWYgKGluZm9QdHItPm91dGJpaCkgewoJICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGluZm9QdHItPm91dGJpaCk7CgkgICAgaW5mb1B0ci0+b3V0YmloID0gTlVMTDsKCX0KCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGluZm9QdHItPmluZGF0YSk7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvUHRyLT5vdXRkYXRhKTsKCWluZm9QdHItPmluZGF0YSA9IGluZm9QdHItPm91dGRhdGEgPSBOVUxMOwoJaW5mb1B0ci0+aFduZCA9IDA7CglpbmZvUHRyLT5oTU1pbyA9IDA7CgltZW1zZXQoJmluZm9QdHItPm1haCwgMCwgc2l6ZW9mKGluZm9QdHItPm1haCkpOwoJbWVtc2V0KCZpbmZvUHRyLT5hc2gsIDAsIHNpemVvZihpbmZvUHRyLT5hc2gpKTsKCWluZm9QdHItPm5Gcm9tRnJhbWUgPSBpbmZvUHRyLT5uVG9GcmFtZSA9IGluZm9QdHItPm5Mb29wID0gaW5mb1B0ci0+Y3VyckZyYW1lID0gMDsKICAgIH0KfQoKCnN0YXRpYyBMUkVTVUxUIEFOSU1BVEVfRG9TdG9wKEFOSU1BVEVfSU5GTyAqaW5mb1B0cikKewogICAgLyogc2hvdWxkIHN0b3AgcGxheWluZyAqLwogICAgaWYgKGluZm9QdHItPmhTZXJ2aWNlKSB7CglTRVJWSUNFX0RlbGV0ZShpbmZvUHRyLT5oU2VydmljZSk7CglpbmZvUHRyLT5oU2VydmljZSA9IDA7CiAgICB9CiAgICBpZiAoaW5mb1B0ci0+dVRpbWVyKSB7CglLaWxsVGltZXIoaW5mb1B0ci0+aFduZCwgaW5mb1B0ci0+dVRpbWVyKTsKCWluZm9QdHItPnVUaW1lciA9IDA7CiAgICB9CgogICAgQU5JTUFURV9Ob3RpZnkoaW5mb1B0ciwgQUNOX1NUT1ApOwoKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgTFJFU1VMVCBBTklNQVRFX1BhaW50RnJhbWUoQU5JTUFURV9JTkZPKiBpbmZvUHRyLCBIREMgaERDKQp7CiAgICBpZiAoaERDKSB7CglTdHJldGNoRElCaXRzKGhEQywgMCwgMCwgaW5mb1B0ci0+b3V0YmloLT5iaVdpZHRoLCBpbmZvUHRyLT5vdXRiaWgtPmJpSGVpZ2h0LCAKCQkgICAgICAwLCAwLCBpbmZvUHRyLT5vdXRiaWgtPmJpV2lkdGgsIGluZm9QdHItPm91dGJpaC0+YmlIZWlnaHQsIAoJCSAgICAgIGluZm9QdHItPm91dGRhdGEsIChMUEJJVE1BUElORk8paW5mb1B0ci0+b3V0YmloLCBESUJfUkdCX0NPTE9SUywgCgkJICAgICAgU1JDQ09QWSk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIExSRVNVTFQgQU5JTUFURV9EcmF3RnJhbWUoQU5JTUFURV9JTkZPKiBpbmZvUHRyKQp7CiAgICBIREMJCWhEQzsKCiAgICBUUkFDRSgiRHJhd2luZyBmcmFtZSAlZCAobG9vcCAlZClcbiIsIGluZm9QdHItPmN1cnJGcmFtZSwgaW5mb1B0ci0+bkxvb3ApOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZpbmZvUHRyLT5jcyk7CgogICAgbW1pb1NlZWsoaW5mb1B0ci0+aE1NaW8sIGluZm9QdHItPmxwSW5kZXhbaW5mb1B0ci0+Y3VyckZyYW1lXSwgU0VFS19TRVQpOwogICAgbW1pb1JlYWQoaW5mb1B0ci0+aE1NaW8sIGluZm9QdHItPmluZGF0YSwgaW5mb1B0ci0+YXNoLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CiAgICAKICAgIGlmICgoaW5mb1B0ci0+Zm5JQ0RlY29tcHJlc3MpKGluZm9QdHItPmhpYywgMCwgaW5mb1B0ci0+aW5iaWgsIGluZm9QdHItPmluZGF0YSwgCgkJCQkgIGluZm9QdHItPm91dGJpaCwgaW5mb1B0ci0+b3V0ZGF0YSkgIT0gSUNFUlJfT0spIHsKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCZpbmZvUHRyLT5jcyk7CglXQVJOKCJEZWNvbXByZXNzaW9uIGVycm9yXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoKGhEQyA9IEdldERDKGluZm9QdHItPmhXbmQpKSAhPSAwKSB7CglBTklNQVRFX1BhaW50RnJhbWUoaW5mb1B0ciwgaERDKTsKCVJlbGVhc2VEQyhpbmZvUHRyLT5oV25kLCBoREMpOwogICAgfQoKICAgIGlmIChpbmZvUHRyLT5jdXJyRnJhbWUrKyA+PSBpbmZvUHRyLT5uVG9GcmFtZSkgewoJaW5mb1B0ci0+Y3VyckZyYW1lID0gaW5mb1B0ci0+bkZyb21GcmFtZTsKCWlmIChpbmZvUHRyLT5uTG9vcCAhPSAtMSkgewoJICAgIGlmICgtLWluZm9QdHItPm5Mb29wID09IDApIHsKCQlBTklNQVRFX0RvU3RvcChpbmZvUHRyKTsKCSAgICB9Cgl9CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmaW5mb1B0ci0+Y3MpOwoKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgdm9pZCBDQUxMQkFDSyBBTklNQVRFX1NlcnZpY2VDYWxsYmFjayhVTE9OR19QVFIgcHRyXykKewogICAgQU5JTUFURV9JTkZPKglpbmZvUHRyID0gKEFOSU1BVEVfSU5GTyopcHRyXzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmaW5mb1B0ci0+Y3MpOwogICAgQU5JTUFURV9EcmF3RnJhbWUoaW5mb1B0cik7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmaW5mb1B0ci0+Y3MpOwp9CgpzdGF0aWMgTFJFU1VMVCBBTklNQVRFX1BsYXkoSFdORCBoV25kLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBBTklNQVRFX0lORk8gKmluZm9QdHIgPSBBTklNQVRFX0dldEluZm9QdHIoaFduZCk7CgogICAgLyogbm90aGluZyBvcGVuZWQgKi8KICAgIGlmICghaW5mb1B0ci0+aE1NaW8pCglyZXR1cm4gRkFMU0U7CgogICAgaWYgKGluZm9QdHItPmhTZXJ2aWNlIHx8IGluZm9QdHItPnVUaW1lcikgewoJRklYTUUoIkFscmVhZHkgcGxheWluZyA/IHdoYXQgc2hvdWxkIEkgZG8gPz9cbiIpOwoJQU5JTUFURV9Eb1N0b3AoaW5mb1B0cik7CiAgICB9CgogICAgaW5mb1B0ci0+bkZyb21GcmFtZSA9IChJTlQpTE9XT1JEKGxQYXJhbSk7CiAgICBpbmZvUHRyLT5uVG9GcmFtZSAgID0gKElOVClISVdPUkQobFBhcmFtKTsKICAgIGluZm9QdHItPm5Mb29wICAgICAgPSAoSU5UKXdQYXJhbTsKCiAgICBpZiAoaW5mb1B0ci0+blRvRnJhbWUgPT0gMHhGRkZGKQoJaW5mb1B0ci0+blRvRnJhbWUgPSBpbmZvUHRyLT5tYWguZHdUb3RhbEZyYW1lcyAtIDE7CgogICAgVFJBQ0UoIihyZXBlYXQ9JWQgZnJvbT0lZCB0bz0lZCk7XG4iLCAKCSAgaW5mb1B0ci0+bkxvb3AsIGluZm9QdHItPm5Gcm9tRnJhbWUsIGluZm9QdHItPm5Ub0ZyYW1lKTsKCiAgICBpZiAoaW5mb1B0ci0+bkZyb21GcmFtZSA+PSBpbmZvUHRyLT5uVG9GcmFtZSB8fAoJaW5mb1B0ci0+blRvRnJhbWUgPj0gaW5mb1B0ci0+bWFoLmR3VG90YWxGcmFtZXMpCglyZXR1cm4gRkFMU0U7CgogICAgaW5mb1B0ci0+Y3VyckZyYW1lID0gaW5mb1B0ci0+bkZyb21GcmFtZTsKCiAgICBpZiAoR2V0V2luZG93TG9uZ0EoaFduZCwgR1dMX1NUWUxFKSAmIEFDU19USU1FUikgewoJVFJBQ0UoIlVzaW5nIGEgdGltZXJcbiIpOwoJLyogY3JlYXRlIGEgdGltZXIgdG8gZGlzcGxheSBBVkkgKi8KCWluZm9QdHItPnVUaW1lciA9IFNldFRpbWVyKGhXbmQsIDEsIGluZm9QdHItPm1haC5kd01pY3JvU2VjUGVyRnJhbWUgLyAxMDAwLCBOVUxMKTsKICAgIH0gZWxzZSB7CglUUkFDRSgiVXNpbmcgdGhlIHNlcnZpY2UgdGhyZWFkXG4iKTsKCS8qIHRpbWUgaXMgaW4gtXMgKi8KCWluZm9QdHItPmhTZXJ2aWNlID0gU0VSVklDRV9BZGRUaW1lcihpbmZvUHRyLT5tYWguZHdNaWNyb1NlY1BlckZyYW1lLCAKCQkJCQkgICAgIEFOSU1BVEVfU2VydmljZUNhbGxiYWNrLCAoRFdPUkQpaW5mb1B0cik7CiAgICB9CgkKICAgIEFOSU1BVEVfTm90aWZ5KGluZm9QdHIsIEFDTl9TVEFSVCk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCgpzdGF0aWMgQk9PTCBBTklNQVRFX0dldEF2aUluZm8oQU5JTUFURV9JTkZPICppbmZvUHRyKQp7CiAgICBNTUNLSU5GTwkJY2tNYWluUklGRjsKICAgIE1NQ0tJTkZPCQltbWNrSGVhZDsKICAgIE1NQ0tJTkZPCQltbWNrTGlzdDsKICAgIE1NQ0tJTkZPCQltbWNrSW5mbzsKICAgIERXT1JECQludW1GcmFtZTsKICAgIERXT1JECQlpbnNpemU7CgogICAgaWYgKG1taW9EZXNjZW5kKGluZm9QdHItPmhNTWlvLCAmY2tNYWluUklGRiwgTlVMTCwgMCkgIT0gMCkgewoJV0FSTigiQ2FuJ3QgZmluZCAnUklGRicgY2h1bmtcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICgoY2tNYWluUklGRi5ja2lkICE9IEZPVVJDQ19SSUZGKSB8fAoJKGNrTWFpblJJRkYuZmNjVHlwZSAhPSBtbWlvRk9VUkNDKCdBJywgJ1YnLCAnSScsICcgJykpKSB7CglXQVJOKCJDYW4ndCBmaW5kICdBVkkgJyBjaHVua1xuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbW1ja0hlYWQuZmNjVHlwZSA9IG1taW9GT1VSQ0MoJ2gnLCAnZCcsICdyJywgJ2wnKTsKICAgIGlmIChtbWlvRGVzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tIZWFkLCAmY2tNYWluUklGRiwgTU1JT19GSU5ETElTVCkgIT0gMCkgewoJV0FSTigiQ2FuJ3QgZmluZCAnaGRybCcgbGlzdFxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbW1ja0luZm8uY2tpZCA9IG1taW9GT1VSQ0MoJ2EnLCAndicsICdpJywgJ2gnKTsKICAgIGlmIChtbWlvRGVzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tJbmZvLCAmbW1ja0hlYWQsIE1NSU9fRklORENIVU5LKSAhPSAwKSB7CglXQVJOKCJDYW4ndCBmaW5kICdhdmloJyBjaHVua1xuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbW1pb1JlYWQoaW5mb1B0ci0+aE1NaW8sIChMUFNUUikmaW5mb1B0ci0+bWFoLCBzaXplb2YoaW5mb1B0ci0+bWFoKSk7CiAgICBUUkFDRSgibWFoLmR3TWljcm9TZWNQZXJGcmFtZT0lbGRcbiIsIAlpbmZvUHRyLT5tYWguZHdNaWNyb1NlY1BlckZyYW1lKTsKICAgIFRSQUNFKCJtYWguZHdNYXhCeXRlc1BlclNlYz0lbGRcbiIsIAlpbmZvUHRyLT5tYWguZHdNYXhCeXRlc1BlclNlYyk7CiAgICBUUkFDRSgibWFoLmR3UGFkZGluZ0dyYW51bGFyaXR5PSVsZFxuIiwgCWluZm9QdHItPm1haC5kd1BhZGRpbmdHcmFudWxhcml0eSk7CiAgICBUUkFDRSgibWFoLmR3RmxhZ3M9JWxkXG4iLCAJCQlpbmZvUHRyLT5tYWguZHdGbGFncyk7CiAgICBUUkFDRSgibWFoLmR3VG90YWxGcmFtZXM9JWxkXG4iLCAJCWluZm9QdHItPm1haC5kd1RvdGFsRnJhbWVzKTsKICAgIFRSQUNFKCJtYWguZHdJbml0aWFsRnJhbWVzPSVsZFxuIiwgCQlpbmZvUHRyLT5tYWguZHdJbml0aWFsRnJhbWVzKTsKICAgIFRSQUNFKCJtYWguZHdTdHJlYW1zPSVsZFxuIiwgCQlpbmZvUHRyLT5tYWguZHdTdHJlYW1zKTsKICAgIFRSQUNFKCJtYWguZHdTdWdnZXN0ZWRCdWZmZXJTaXplPSVsZFxuIiwJaW5mb1B0ci0+bWFoLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CiAgICBUUkFDRSgibWFoLmR3V2lkdGg9JWxkXG4iLCAJCQlpbmZvUHRyLT5tYWguZHdXaWR0aCk7CiAgICBUUkFDRSgibWFoLmR3SGVpZ2h0PSVsZFxuIiwgCQlpbmZvUHRyLT5tYWguZHdIZWlnaHQpOwogICAgbW1pb0FzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tJbmZvLCAwKTsKCiAgICBtbWNrTGlzdC5mY2NUeXBlID0gbW1pb0ZPVVJDQygncycsICd0JywgJ3InLCAnbCcpOwogICAgaWYgKG1taW9EZXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0xpc3QsICZtbWNrSGVhZCwgTU1JT19GSU5ETElTVCkgIT0gMCkgewoJV0FSTigiQ2FuJ3QgZmluZCAnc3RybCcgbGlzdFxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbW1ja0luZm8uY2tpZCA9IG1taW9GT1VSQ0MoJ3MnLCAndCcsICdyJywgJ2gnKTsKICAgIGlmIChtbWlvRGVzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tJbmZvLCAmbW1ja0xpc3QsIE1NSU9fRklORENIVU5LKSAhPSAwKSB7CglXQVJOKCJDYW4ndCBmaW5kICdzdHJoJyBjaHVua1xuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbW1pb1JlYWQoaW5mb1B0ci0+aE1NaW8sIChMUFNUUikmaW5mb1B0ci0+YXNoLCBzaXplb2YoaW5mb1B0ci0+YXNoKSk7CiAgICBUUkFDRSgiYXNoLmZjY1R5cGU9JyVjJWMlYyVjJ1xuIiwgCQlMT0JZVEUoTE9XT1JEKGluZm9QdHItPmFzaC5mY2NUeXBlKSksIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhJQllURShMT1dPUkQoaW5mb1B0ci0+YXNoLmZjY1R5cGUpKSwgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9CWVRFKEhJV09SRChpbmZvUHRyLT5hc2guZmNjVHlwZSkpLCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBISUJZVEUoSElXT1JEKGluZm9QdHItPmFzaC5mY2NUeXBlKSkpOwogICAgVFJBQ0UoImFzaC5mY2NIYW5kbGVyPSclYyVjJWMlYydcbiIsCUxPQllURShMT1dPUkQoaW5mb1B0ci0+YXNoLmZjY0hhbmRsZXIpKSwgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSElCWVRFKExPV09SRChpbmZvUHRyLT5hc2guZmNjSGFuZGxlcikpLCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT0JZVEUoSElXT1JEKGluZm9QdHItPmFzaC5mY2NIYW5kbGVyKSksIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhJQllURShISVdPUkQoaW5mb1B0ci0+YXNoLmZjY0hhbmRsZXIpKSk7CiAgICBUUkFDRSgiYXNoLmR3RmxhZ3M9JWxkXG4iLCAJCQlpbmZvUHRyLT5hc2guZHdGbGFncyk7CiAgICBUUkFDRSgiYXNoLndQcmlvcml0eT0lZFxuIiwgCQlpbmZvUHRyLT5hc2gud1ByaW9yaXR5KTsKICAgIFRSQUNFKCJhc2gud0xhbmd1YWdlPSVkXG4iLCAJCWluZm9QdHItPmFzaC53TGFuZ3VhZ2UpOwogICAgVFJBQ0UoImFzaC5kd0luaXRpYWxGcmFtZXM9JWxkXG4iLCAJCWluZm9QdHItPmFzaC5kd0luaXRpYWxGcmFtZXMpOwogICAgVFJBQ0UoImFzaC5kd1NjYWxlPSVsZFxuIiwgCQkJaW5mb1B0ci0+YXNoLmR3U2NhbGUpOwogICAgVFJBQ0UoImFzaC5kd1JhdGU9JWxkXG4iLCAJCQlpbmZvUHRyLT5hc2guZHdSYXRlKTsKICAgIFRSQUNFKCJhc2guZHdTdGFydD0lbGRcbiIsIAkJCWluZm9QdHItPmFzaC5kd1N0YXJ0KTsKICAgIFRSQUNFKCJhc2guZHdMZW5ndGg9JWxkXG4iLCAJCWluZm9QdHItPmFzaC5kd0xlbmd0aCk7CiAgICBUUkFDRSgiYXNoLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZT0lbGRcbiIsIAlpbmZvUHRyLT5hc2guZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKICAgIFRSQUNFKCJhc2guZHdRdWFsaXR5PSVsZFxuIiwgCQlpbmZvUHRyLT5hc2guZHdRdWFsaXR5KTsKICAgIFRSQUNFKCJhc2guZHdTYW1wbGVTaXplPSVsZFxuIiwgCQlpbmZvUHRyLT5hc2guZHdTYW1wbGVTaXplKTsKICAgIFRSQUNFKCJhc2gucmNGcmFtZT0oJWQsJWQsJWQsJWQpXG4iLCAJaW5mb1B0ci0+YXNoLnJjRnJhbWUudG9wLCBpbmZvUHRyLT5hc2gucmNGcmFtZS5sZWZ0LCAKCSAgaW5mb1B0ci0+YXNoLnJjRnJhbWUuYm90dG9tLCBpbmZvUHRyLT5hc2gucmNGcmFtZS5yaWdodCk7CiAgICBtbWlvQXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0luZm8sIDApOwoKICAgIG1tY2tJbmZvLmNraWQgPSBtbWlvRk9VUkNDKCdzJywgJ3QnLCAncicsICdmJyk7CiAgICBpZiAobW1pb0Rlc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrSW5mbywgJm1tY2tMaXN0LCBNTUlPX0ZJTkRDSFVOSykgIT0gMCkgewoJV0FSTigiQ2FuJ3QgZmluZCAnc3RyaCcgY2h1bmtcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGluZm9QdHItPmluYmloID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIG1tY2tJbmZvLmNrc2l6ZSk7CiAgICBpZiAoIWluZm9QdHItPmluYmloKSB7CglXQVJOKCJDYW4ndCBhbGxvYyBpbnB1dCBCSUhcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIG1taW9SZWFkKGluZm9QdHItPmhNTWlvLCAoTFBTVFIpaW5mb1B0ci0+aW5iaWgsIG1tY2tJbmZvLmNrc2l6ZSk7CiAgICBUUkFDRSgiYmloLmJpU2l6ZT0lbGRcbiIsIAkJaW5mb1B0ci0+aW5iaWgtPmJpU2l6ZSk7CiAgICBUUkFDRSgiYmloLmJpV2lkdGg9JWxkXG4iLCAJCWluZm9QdHItPmluYmloLT5iaVdpZHRoKTsKICAgIFRSQUNFKCJiaWguYmlIZWlnaHQ9JWxkXG4iLCAJaW5mb1B0ci0+aW5iaWgtPmJpSGVpZ2h0KTsKICAgIFRSQUNFKCJiaWguYmlQbGFuZXM9JWRcbiIsIAkJaW5mb1B0ci0+aW5iaWgtPmJpUGxhbmVzKTsKICAgIFRSQUNFKCJiaWguYmlCaXRDb3VudD0lZFxuIiwgCWluZm9QdHItPmluYmloLT5iaUJpdENvdW50KTsKICAgIFRSQUNFKCJiaWguYmlDb21wcmVzc2lvbj0lbGRcbiIsIAlpbmZvUHRyLT5pbmJpaC0+YmlDb21wcmVzc2lvbik7CiAgICBUUkFDRSgiYmloLmJpU2l6ZUltYWdlPSVsZFxuIiwgCWluZm9QdHItPmluYmloLT5iaVNpemVJbWFnZSk7CiAgICBUUkFDRSgiYmloLmJpWFBlbHNQZXJNZXRlcj0lbGRcbiIsIAlpbmZvUHRyLT5pbmJpaC0+YmlYUGVsc1Blck1ldGVyKTsKICAgIFRSQUNFKCJiaWguYmlZUGVsc1Blck1ldGVyPSVsZFxuIiwgCWluZm9QdHItPmluYmloLT5iaVlQZWxzUGVyTWV0ZXIpOwogICAgVFJBQ0UoImJpaC5iaUNsclVzZWQ9JWxkXG4iLCAJaW5mb1B0ci0+aW5iaWgtPmJpQ2xyVXNlZCk7CiAgICBUUkFDRSgiYmloLmJpQ2xySW1wb3J0YW50PSVsZFxuIiwgCWluZm9QdHItPmluYmloLT5iaUNsckltcG9ydGFudCk7CiAgICBtbWlvQXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0luZm8sIDApOwoKICAgIG1taW9Bc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrTGlzdCwgMCk7CiAgICAKI2lmIDAKICAgIC8qIGFuIEFWSSBoYXMgMCBvciAxIHZpZGVvIHN0cmVhbSwgYW5kIHRvIGJlIGFuaW1hdGVkIHNob3VsZCBub3QgY29udGFpbgogICAgICogYW4gYXVkaW8gc3RyZWFtLCBzbyBvbmx5IG9uZSBzdHJsIGlzIGFsbG93ZWQgCiAgICAgKi8KICAgIG1tY2tMaXN0LmZjY1R5cGUgPSBtbWlvRk9VUkNDKCdzJywgJ3QnLCAncicsICdsJyk7CiAgICBpZiAobW1pb0Rlc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrTGlzdCwgJm1tY2tIZWFkLCBNTUlPX0ZJTkRMSVNUKSA9PSAwKSB7CglXQVJOKCJUaGVyZSBzaG91bGQgYmUgYSBzaW5nbGUgJ3N0cmwnIGxpc3RcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQojZW5kaWYKCiAgICBtbWlvQXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0hlYWQsIDApOwoKICAgIC8qIG5vIG5lZWQgdG8gcmVhZCBvcHRpb25hbCBKVU5LIGNodW5rICovCgogICAgbW1ja0xpc3QuZmNjVHlwZSA9IG1taW9GT1VSQ0MoJ20nLCAnbycsICd2JywgJ2knKTsKICAgIGlmIChtbWlvRGVzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tMaXN0LCAmY2tNYWluUklGRiwgTU1JT19GSU5ETElTVCkgIT0gMCkgewoJV0FSTigiQ2FuJ3QgZmluZCAnbW92aScgbGlzdFxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgLyogRklYTUU6IHNob3VsZCBoYW5kbGUgdGhlICdyZWMgJyBMSVNUIHdoZW4gcHJlc2VudCAqLwoKICAgIGluZm9QdHItPmxwSW5kZXggPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgCgkJCQkgaW5mb1B0ci0+bWFoLmR3VG90YWxGcmFtZXMgKiBzaXplb2YoRFdPUkQpKTsKICAgIGlmICghaW5mb1B0ci0+bHBJbmRleCkgewoJV0FSTigiQ2FuJ3QgYWxsb2MgaW5kZXggYXJyYXlcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIG51bUZyYW1lID0gaW5zaXplID0gMDsKICAgIHdoaWxlIChtbWlvRGVzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tJbmZvLCAmbW1ja0xpc3QsIDApID09IDAgJiYgCgkgICBudW1GcmFtZSA8IGluZm9QdHItPm1haC5kd1RvdGFsRnJhbWVzKSB7CglpbmZvUHRyLT5scEluZGV4W251bUZyYW1lXSA9IG1tY2tJbmZvLmR3RGF0YU9mZnNldDsKCWlmIChpbnNpemUgPCBtbWNrSW5mby5ja3NpemUpCgkgICAgaW5zaXplID0gbW1ja0luZm8uY2tzaXplOwoJbnVtRnJhbWUrKzsKCW1taW9Bc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrSW5mbywgMCk7CiAgICB9CiAgICBpZiAobnVtRnJhbWUgIT0gaW5mb1B0ci0+bWFoLmR3VG90YWxGcmFtZXMpIHsKCVdBUk4oIkZvdW5kICVsZCBmcmFtZXMgKC8lbGQpXG4iLCBudW1GcmFtZSwgaW5mb1B0ci0+bWFoLmR3VG90YWxGcmFtZXMpOwoJcmV0dXJuIEZBTFNFOwogICAgfQogICAgaWYgKGluc2l6ZSA+IGluZm9QdHItPmFzaC5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpIHsKCVdBUk4oImluc2l6ZT0lbGQgc3VnZ2VzdGVkU2l6ZT0lbGRcbiIsIGluc2l6ZSwgaW5mb1B0ci0+YXNoLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CglpbmZvUHRyLT5hc2guZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gaW5zaXplOwogICAgfQoKICAgIGluZm9QdHItPmluZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvUHRyLT5hc2guZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKICAgIGlmICghaW5mb1B0ci0+aW5kYXRhKSB7CglXQVJOKCJDYW4ndCBhbGxvYyBpbnB1dCBidWZmZXJcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgoKc3RhdGljIEJPT0wgICAgQU5JTUFURV9HZXRBdmlDb2RlYyhBTklNQVRFX0lORk8gKmluZm9QdHIpCnsKICAgIERXT1JECW91dFNpemU7CgogICAgaW5mb1B0ci0+aGljID0gKGluZm9QdHItPmZuSUNPcGVuKShJQ1RZUEVfVklERU8sIAoJCQkJICAgICAgIGluZm9QdHItPmFzaC5mY2NIYW5kbGVyLCAKCQkJCSAgICAgICBJQ01PREVfREVDT01QUkVTUyk7CiAgICBpZiAoIWluZm9QdHItPmhpYykgewoJV0FSTigiQ2FuJ3QgbG9hZCBjb2RlYyBmb3IgdGhlIGZpbGVcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQogICAgCiAgICBvdXRTaXplID0gKGluZm9QdHItPmZuSUNTZW5kTWVzc2FnZSkoaW5mb1B0ci0+aGljLCAKCQkJCQkgSUNNX0RFQ09NUFJFU1NfR0VUX0ZPUk1BVCwgCgkJCQkJIChEV09SRClpbmZvUHRyLT5pbmJpaCwgMEwpOwogICAgaW5mb1B0ci0+b3V0YmloID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIG91dFNpemUpOwogICAgaWYgKCFpbmZvUHRyLT5vdXRiaWgpIHsKCVdBUk4oIkNhbid0IGFsbG9jIG91dHB1dCBCSUhcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICgoaW5mb1B0ci0+Zm5JQ1NlbmRNZXNzYWdlKShpbmZvUHRyLT5oaWMsIElDTV9ERUNPTVBSRVNTX0dFVF9GT1JNQVQsIAoJCQkJICAgKERXT1JEKWluZm9QdHItPmluYmloLCAKCQkJCSAgIChEV09SRClpbmZvUHRyLT5vdXRiaWgpICE9IElDRVJSX09LKSB7CglXQVJOKCJDYW4ndCBnZXQgb3V0cHV0IEJJSFxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaW5mb1B0ci0+b3V0ZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvUHRyLT5vdXRiaWgtPmJpU2l6ZUltYWdlKTsKICAgIGlmICghaW5mb1B0ci0+b3V0ZGF0YSkgewoJV0FSTigiQ2FuJ3QgYWxsb2Mgb3V0cHV0IGJ1ZmZlclxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKChpbmZvUHRyLT5mbklDU2VuZE1lc3NhZ2UpKGluZm9QdHItPmhpYywgSUNNX0RFQ09NUFJFU1NfQkVHSU4sIAoJCQkJICAgKERXT1JEKWluZm9QdHItPmluYmloLCAKCQkJCSAgIChEV09SRClpbmZvUHRyLT5vdXRiaWgpICE9IElDRVJSX09LKSB7CglXQVJOKCJDYW4ndCBiZWdpbiBkZWNvbXByZXNzaW9uXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIExSRVNVTFQgQU5JTUFURV9PcGVuQShIV05EIGhXbmQsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIEFOSU1BVEVfSU5GTyAqaW5mb1B0ciA9IEFOSU1BVEVfR2V0SW5mb1B0cihoV25kKTsKICAgIEhJTlNUQU5DRSBoSW5zdGFuY2UgPSAoSElOU1RBTkNFKXdQYXJhbTsKCiAgICBBTklNQVRFX0ZyZWUoaW5mb1B0cik7CgogICAgaWYgKCFsUGFyYW0pIHsKCVRSQUNFKCJDbG9zaW5nIGF2aSFcbiIpOwoJcmV0dXJuIFRSVUU7CiAgICB9CiAgICAKICAgIGlmICghaEluc3RhbmNlKQogICAgICAgaEluc3RhbmNlID0gR2V0V2luZG93TG9uZ0EoaFduZCwgR1dMX0hJTlNUQU5DRSk7CgogICAgaWYgKEhJV09SRChsUGFyYW0pKSB7CglUUkFDRSgiKFwiJXNcIik7XG4iLCAoTFBTVFIpbFBhcmFtKTsKCglpZiAoIUFOSU1BVEVfTG9hZFJlc0EoaW5mb1B0ciwgaEluc3RhbmNlLCAoTFBTVFIpbFBhcmFtKSkgewoJICAgIFRSQUNFKCJObyBBVkkgcmVzb3VyY2UgZm91bmQhXG4iKTsKCSAgICBpZiAoIUFOSU1BVEVfTG9hZEZpbGVBKGluZm9QdHIsIChMUFNUUilsUGFyYW0pKSB7CgkJV0FSTigiTm8gQVZJIGZpbGUgZm91bmQhXG4iKTsKCQlyZXR1cm4gRkFMU0U7CgkgICAgfQoJfQogICAgfSBlbHNlIHsKCVRSQUNFKCIoJXUpO1xuIiwgKFdPUkQpTE9XT1JEKGxQYXJhbSkpOwoKCWlmICghQU5JTUFURV9Mb2FkUmVzQShpbmZvUHRyLCBoSW5zdGFuY2UsCgkJCSAgICAgIE1BS0VJTlRSRVNPVVJDRUEoKElOVClsUGFyYW0pKSkgewoJICAgIFdBUk4oIk5vIEFWSSByZXNvdXJjZSBmb3VuZCFcbiIpOwoJICAgIHJldHVybiBGQUxTRTsKCX0KICAgIH0KCiAgICBpZiAoIUFOSU1BVEVfR2V0QXZpSW5mbyhpbmZvUHRyKSkgewoJV0FSTigiQ2FuJ3QgZ2V0IEFWSSBpbmZvcm1hdGlvblxuIik7CglBTklNQVRFX0ZyZWUoaW5mb1B0cik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKCFBTklNQVRFX0dldEF2aUNvZGVjKGluZm9QdHIpKSB7CglXQVJOKCJDYW4ndCBnZXQgQVZJIENvZGVjXG4iKTsKCUFOSU1BVEVfRnJlZShpbmZvUHRyKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoR2V0V2luZG93TG9uZ0EoaFduZCwgR1dMX1NUWUxFKSAmIEFDU19DRU5URVIpIHsKCUZJWE1FKCJBQ1NfQ0VOVEVSOiBOSVlcbiIpOwogICAgfSBlbHNlIHsKCS8qCU1vdmVXaW5kb3coaFduZCwgMCwgMCwgaW5mb1B0ci0+bWFoLmR3V2lkdGgsIGluZm9QdHItPm1haC5kd0hlaWdodCwgRkFMU0UpOyovCglTZXRXaW5kb3dQb3MoaFduZCwgMCwgMCwgMCwgaW5mb1B0ci0+bWFoLmR3V2lkdGgsIGluZm9QdHItPm1haC5kd0hlaWdodCwKCQkgICAgIFNXUF9OT0FDVElWQVRFIHwgU1dQX05PTU9WRSB8IFNXUF9OT1pPUkRFUik7CiAgICB9CgogICAgaWYgKEdldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9TVFlMRSkgJiBBQ1NfVFJBTlNQQVJFTlQpIHsKCUZJWE1FKCJBQ1NfVFJBTlNQQVJFTlQ6IE5JWVxuIik7CiAgICB9CgogICAgaWYgKEdldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9TVFlMRSkgJiBBQ1NfQVVUT1BMQVkpIHsKCXJldHVybiBBTklNQVRFX1BsYXkoaFduZCwgLTEsIChMUEFSQU0pTUFLRUxPTkcoMCwgaW5mb1B0ci0+bWFoLmR3VG90YWxGcmFtZXMtMSkpOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgoKLyogPDwgQU5JTUFURV9PcGVuMzJXID4+ICovCgpzdGF0aWMgTFJFU1VMVCBBTklNQVRFX1N0b3AoSFdORCBoV25kLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBBTklNQVRFX0lORk8gKmluZm9QdHIgPSBBTklNQVRFX0dldEluZm9QdHIoaFduZCk7CgogICAgLyogbm90aGluZyBvcGVuZWQgKi8KICAgIGlmICghaW5mb1B0ci0+aE1NaW8pCglyZXR1cm4gRkFMU0U7CgogICAgQU5JTUFURV9Eb1N0b3AoaW5mb1B0cik7CiAgICByZXR1cm4gVFJVRTsKfQoKCgpzdGF0aWMgTFJFU1VMVCBBTklNQVRFX0NyZWF0ZShIV05EIGhXbmQsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIEFOSU1BVEVfSU5GTyoJaW5mb1B0cjsKICAgIEhNT0RVTEUJCWhNb2R1bGUgPSBMb2FkTGlicmFyeUEoIm1zdmZ3MzIuZGxsIik7CgogICAgaWYgKCFoTW9kdWxlKQoJcmV0dXJuIEZBTFNFOwoKICAgIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgaW5mbyBzdHJ1Y3R1cmUgKi8KICAgIGluZm9QdHIgPSAoQU5JTUFURV9JTkZPICopQ09NQ1RMMzJfQWxsb2Moc2l6ZW9mKEFOSU1BVEVfSU5GTykpOwogICAgaWYgKCFpbmZvUHRyKSB7CglFUlIoImNvdWxkIG5vdCBhbGxvY2F0ZSBpbmZvIG1lbW9yeSFcbiIpOwoJcmV0dXJuIDA7CiAgICB9CgogICAgLyogVGVtcG9yYXJ5IGhhY2sgdW50aWwgd2UgZ2V0IGRsbGdsdWUgdXAgYW5kIHJ1bm5pbmcgKi8KICAgIGluZm9QdHItPmZuSUNPcGVuICAgICAgICA9ICh2b2lkKilHZXRQcm9jQWRkcmVzcyhoTW9kdWxlLCAiSUNPcGVuIik7CiAgICBpbmZvUHRyLT5mbklDQ2xvc2UgICAgICAgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZHVsZSwgIklDQ2xvc2UiKTsKICAgIGluZm9QdHItPmZuSUNTZW5kTWVzc2FnZSA9ICh2b2lkKilHZXRQcm9jQWRkcmVzcyhoTW9kdWxlLCAiSUNTZW5kTWVzc2FnZSIpOwogICAgaW5mb1B0ci0+Zm5JQ0RlY29tcHJlc3MgID0gKHZvaWQqKUdldFByb2NBZGRyZXNzKGhNb2R1bGUsICJJQ0RlY29tcHJlc3MiKTsKCiAgICBUUkFDRSgiQW5pbWF0ZSBzdHlsZT0weCUwOGx4LCBwYXJlbnQ9JTA4bHhcbiIsIEdldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9TVFlMRSksIChEV09SRClHZXRQYXJlbnQoaFduZCkpOwoKICAgIC8qIHN0b3JlIGNyb3NzcmVmIGhXbmQgPC0+IGluZm8gc3RydWN0dXJlICovCiAgICBTZXRXaW5kb3dMb25nQShoV25kLCAwLCAoRFdPUkQpaW5mb1B0cik7CiAgICBpbmZvUHRyLT5oV25kID0gaFduZDsKCiAgICBJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCZpbmZvUHRyLT5jcyk7CiAgICAKICAgIHJldHVybiAwOwp9CgoKc3RhdGljIExSRVNVTFQgQU5JTUFURV9EZXN0cm95KEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQU5JTUFURV9JTkZPICppbmZvUHRyID0gQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpOwoKCiAgICAvKiBmcmVlIGF2aSBkYXRhICovCiAgICBBTklNQVRFX0ZyZWUoaW5mb1B0cik7CgogICAgLyogZnJlZSBhbmltYXRlIGluZm8gZGF0YSAqLwogICAgQ09NQ1RMMzJfRnJlZShpbmZvUHRyKTsKCiAgICByZXR1cm4gMDsKfQoKCnN0YXRpYyBMUkVTVUxUIEFOSU1BVEVfRXJhc2VCYWNrZ3JvdW5kKEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgUkVDVCByZWN0OwoKICAgIEdldENsaWVudFJlY3QoaFduZCwgJnJlY3QpOwojaWYgMAogICAgSEJSVVNIIGhCcnVzaCA9IENyZWF0ZVNvbGlkQnJ1c2goaW5mb1B0ci0+Y2xyQmspOwoKICAgIEZpbGxSZWN0KChIREMpd1BhcmFtLCAmcmVjdCwgaEJydXNoKTsKICAgIERlbGV0ZU9iamVjdChoQnJ1c2gpOwojZWxzZQogICAgRmlsbFJlY3QoKEhEQyl3UGFyYW0sICZyZWN0LCBHZXRTeXNDb2xvckJydXNoKENPTE9SX1dJTkRPVykpOwojZW5kaWYKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgTFJFU1VMVCBXSU5BUEkgQU5JTUFURV9TaXplKEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQU5JTUFURV9JTkZPICppbmZvUHRyID0gQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpOwoKICAgIGlmIChHZXRXaW5kb3dMb25nQShoV25kLCBHV0xfU1RZTEUpICYgQUNTX0NFTlRFUikgewoJRklYTUUoIk5JWVxuIik7CglpZiAoaW5mb1B0ci0+aE1NaW8pIHsKCSAgICAvKiBjZW50ZXJzIHRoZSBhbmltYXRpb24gaW4gdGhlIGNvbnRyb2wsIGludmFsaWRhdGVzIHRoZSBjb250cm9sCgkgICAgICovCgl9CglJbnZhbGlkYXRlUmVjdChoV25kLCBOVUxMLCBUUlVFKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgTFJFU1VMVCBXSU5BUEkgQU5JTUFURV9XaW5kb3dQcm9jKEhXTkQgaFduZCwgVUlOVCB1TXNnLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBzd2l0Y2ggKHVNc2cpCiAgICB7CiAgICBjYXNlIEFDTV9PUEVOQToKCXJldHVybiBBTklNQVRFX09wZW5BKGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsKCQoJLyoJY2FzZSBBQ01fT1BFTjMyVzogRklYTUUhISAqLwoJLyoJICAgIHJldHVybiBBTklNQVRFX09wZW4zMlcoaFduZCwgd1BhcmFtLCBsUGFyYW0pOyAqLwoJCiAgICBjYXNlIEFDTV9QTEFZOgoJcmV0dXJuIEFOSU1BVEVfUGxheShoV25kLCB3UGFyYW0sIGxQYXJhbSk7CgkKICAgIGNhc2UgQUNNX1NUT1A6CglyZXR1cm4gQU5JTUFURV9TdG9wKGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsKCQogICAgY2FzZSBXTV9OQ0NSRUFURToKCUFOSU1BVEVfQ3JlYXRlKGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsKCXJldHVybiBEZWZXaW5kb3dQcm9jQShoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CgkKICAgIGNhc2UgV01fTkNISVRURVNUOgoJcmV0dXJuIEhUVFJBTlNQQVJFTlQ7CgogICAgY2FzZSBXTV9ERVNUUk9ZOgoJQU5JTUFURV9EZXN0cm95KGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsKCXJldHVybiBEZWZXaW5kb3dQcm9jQShoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CgkKICAgIGNhc2UgV01fRVJBU0VCS0dORDoKCUFOSU1BVEVfRXJhc2VCYWNrZ3JvdW5kKGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsKCWJyZWFrOwoKICAgIC8qCWNhc2UgV01fU1RZTEVDSEFOR0VEOiBGSVhNRSBzaGFsbCB3ZSBkbyBzb21ldGhpbmcgPz8gKi8KCiAgICBjYXNlIFdNX1RJTUVSOgoJcmV0dXJuIEFOSU1BVEVfRHJhd0ZyYW1lKEFOSU1BVEVfR2V0SW5mb1B0cihoV25kKSk7CgkKICAgIGNhc2UgV01fQ0xPU0U6CglBTklNQVRFX0ZyZWUoQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpKTsKCXJldHVybiBUUlVFOwoKICAgIGNhc2UgV01fUEFJTlQ6CglpZiAod1BhcmFtKSB7CgkgICAgQU5JTUFURV9QYWludEZyYW1lKEFOSU1BVEVfR2V0SW5mb1B0cihoV25kKSwgKEhEQyl3UGFyYW0pOwoJfSBlbHNlIHsKCSAgICBQQUlOVFNUUlVDVCBwczsKIAkgICAgSERDIGhEQyA9IEJlZ2luUGFpbnQoaFduZCwgJnBzKTsKCSAgICBBTklNQVRFX1BhaW50RnJhbWUoQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpLCBoREMpOwoJICAgIEVuZFBhaW50KGhXbmQsICZwcyk7Cgl9CglicmVhazsKCiAgICBjYXNlIFdNX1NJWkU6CglBTklNQVRFX1NpemUoaFduZCwgd1BhcmFtLCBsUGFyYW0pOwoJcmV0dXJuIERlZldpbmRvd1Byb2NBKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCiAgICBkZWZhdWx0OgoJaWYgKHVNc2cgPj0gV01fVVNFUikKCSAgICBFUlIoInVua25vd24gbXNnICUwNHggd3A9JTA4eCBscD0lMDhseFxuIiwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJCglyZXR1cm4gRGVmV2luZG93UHJvY0EoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCgp2b2lkIEFOSU1BVEVfUmVnaXN0ZXIodm9pZCkKewogICAgV05EQ0xBU1NBIHduZENsYXNzOwoKICAgIGlmIChHbG9iYWxGaW5kQXRvbUEoQU5JTUFURV9DTEFTU0EpKSByZXR1cm47CgogICAgWmVyb01lbW9yeSgmd25kQ2xhc3MsIHNpemVvZihXTkRDTEFTU0EpKTsKICAgIHduZENsYXNzLnN0eWxlICAgICAgICAgPSBDU19HTE9CQUxDTEFTUyB8IENTX0RCTENMS1M7CiAgICB3bmRDbGFzcy5scGZuV25kUHJvYyAgID0gKFdORFBST0MpQU5JTUFURV9XaW5kb3dQcm9jOwogICAgd25kQ2xhc3MuY2JDbHNFeHRyYSAgICA9IDA7CiAgICB3bmRDbGFzcy5jYlduZEV4dHJhICAgID0gc2l6ZW9mKEFOSU1BVEVfSU5GTyAqKTsKICAgIHduZENsYXNzLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yQSgwLCBJRENfQVJST1dBKTsKICAgIHduZENsYXNzLmhickJhY2tncm91bmQgPSAoSEJSVVNIKShDT0xPUl9CVE5GQUNFICsgMSk7CiAgICB3bmRDbGFzcy5scHN6Q2xhc3NOYW1lID0gQU5JTUFURV9DTEFTU0E7CiAKICAgIFJlZ2lzdGVyQ2xhc3NBKCZ3bmRDbGFzcyk7Cn0KCgp2b2lkIEFOSU1BVEVfVW5yZWdpc3Rlcih2b2lkKQp7CiAgICBpZiAoR2xvYmFsRmluZEF0b21BKEFOSU1BVEVfQ0xBU1NBKSkKCVVucmVnaXN0ZXJDbGFzc0EoQU5JTUFURV9DTEFTU0EsIChISU5TVEFOQ0UpTlVMTCk7Cn0KCg==