LyogLSotIHRhYi13aWR0aDogODsgYy1iYXNpYy1vZmZzZXQ6IDQgLSotICovCi8qCiAqIEFuaW1hdGlvbiBjb250cm9sCiAqCiAqIENvcHlyaWdodCAxOTk4LCAxOTk5IEVyaWMgS29obAogKiAJCSAgIDE5OTkgRXJpYyBQb3VlY2gKICoKICogTk9URVMKICogICBJIHdpbGwgb25seSBpbXByb3ZlIHRoaXMgY29udHJvbCBvbmNlIGluIGEgd2hpbGUuCiAqICAgICBFcmljIDxla29obEBhYm8ucmhlaW4temVpdHVuZy5kZT4KICoKICogVE9ETzoKICogICAtIGNoZWNrIGZvciB0aGUgJ3JlYyAnIGxpc3QgaW4gc29tZSBBVkkgZmlsZXMKICogICAtIGltcGxlbWVudCBzb21lIG1pc3NpbmcgZmxhZ3MgKEFDU19UUkFOU1BBUkVOVCkKICogICAtIHByb3RlY3Rpb24gYmV0d2VlbiBzZXJ2aWNlIHRocmVhZCBhbmQgd25kcHJvYyBtZXNzYWdlcyBoYW5kbGluZyAKICogICAgIGNvbmN1cnJlbnQgYWNjZXNzIHRvIGluZm9QdHIKICovCgoKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgImNvbW1jdHJsLmgiCiNpbmNsdWRlICJ2ZncuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJzZXJ2aWNlcy5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKGFuaW1hdGUpOwoKdHlwZWRlZiBzdHJ1Y3QKewogICAvKiBwb2ludGVyIHRvIG1zdmlkZW8gZnVuY3Rpb25zLiBpdCdzIGVhc2llciB0byBwdXQgdGhlbSBoZXJlLgogICAgKiB0byBiZSBjb3JyZWN0LCB0aGV5IHNob3VsZCBiZSBkZWZpbmVkIG9uIGEgcGVyIHByb2Nlc3MgYmFzaXMsIGJ1dAogICAgKiB0aGlzIHdvdWxkIHJlcXVpcmVkIGEgcGVyIHByb2Nlc3Mgc3RvcmFnZS4gV2UncmUgdXNpbmcgYSBwZXIgb2JqZWN0CiAgICAqIHN0b3JhZ2UgaW5zdGVhZCwgd2hpY2ggaXMgbm90IGVmZmljaWVudCBvbiBtZW1vcnkgdXNhZ2UsIGJ1dAogICAgKiB3aWxsIGxlYWQgdG8gbGVzcyBidWdzIGluIHRoZSBmdXR1cmUKICAgICovCiAgIEhJQwkgIAlXSU5BUEkgICgqZm5JQ09wZW4pKERXT1JELCBEV09SRCwgVUlOVCk7CiAgIExSRVNVTFQJV0lOQVBJICAoKmZuSUNDbG9zZSkoSElDKTsKICAgTFJFU1VMVAlXSU5BUEkgICgqZm5JQ1NlbmRNZXNzYWdlKShISUMsIFVJTlQsIERXT1JELCBEV09SRCk7CiAgIERXT1JECVdJTkFQSVYgKCpmbklDRGVjb21wcmVzcykoSElDLERXT1JELExQQklUTUFQSU5GT0hFQURFUixMUFZPSUQsTFBCSVRNQVBJTkZPSEVBREVSLExQVk9JRCk7CgogICAgSE1NSU8gV0lOQVBJICgqZm5tbWlvT3BlbkEpKExQU1RSLE1NSU9JTkZPKixEV09SRCk7CiAgICBNTVJFU1VMVCBXSU5BUEkgKCpmbm1taW9DbG9zZSkoSE1NSU8sVUlOVCk7CiAgICBVSU5UICBXSU5BUEkgKCpmbm1taW9Bc2NlbmQpKEhNTUlPLE1NQ0tJTkZPKixVSU5UKTsKICAgIFVJTlQgIFdJTkFQSSAoKmZubW1pb0Rlc2NlbmQpKEhNTUlPLE1NQ0tJTkZPKixjb25zdCBNTUNLSU5GTyosVUlOVCk7CiAgICBMT05HICBXSU5BUEkgKCpmbm1taW9TZWVrKShITU1JTyxMT05HLElOVCk7CiAgICBMT05HICBXSU5BUEkgKCpmbm1taW9SZWFkKShITU1JTyxIUFNUUixMT05HKTsKCiAgIC8qIHJlZmVyZW5jZSB0byBpbnB1dCBzdHJlYW0gKGZpbGUgb3IgcmVzb3VyY2UpICovCiAgIEhHTE9CQUwgCQloUmVzOwogICBITU1JTwkJCWhNTWlvOwkvKiBoYW5kbGUgdG8gbW1pbyBzdHJlYW0gKi8KICAgSFdORAkJCWhXbmQ7CiAgIC8qIGluZm9ybWF0aW9uIG9uIHRoZSBsb2FkZWQgQVZJIGZpbGUgKi8KICAgTWFpbkFWSUhlYWRlcgltYWg7CiAgIEFWSVN0cmVhbUhlYWRlcglhc2g7CiAgIExQQklUTUFQSU5GT0hFQURFUglpbmJpaDsKICAgTFBEV09SRAkJbHBJbmRleDsKICAgLyogZGF0YSBmb3IgdGhlIGRlY29tcHJlc3NvciAqLwogICBISUMJCQloaWM7CiAgIExQQklUTUFQSU5GT0hFQURFUglvdXRiaWg7CiAgIExQVk9JRAkJaW5kYXRhOwogICBMUFZPSUQJCW91dGRhdGE7CiAgIC8qIGRhdGEgZm9yIHRoZSBiYWNrZ3JvdW5kIG1lY2hhbmlzbSAqLwogICBDUklUSUNBTF9TRUNUSU9OCWNzOwogICBIQU5ETEUJCWhTZXJ2aWNlOwogICBVSU5UCQkJdVRpbWVyOwogICAvKiBkYXRhIGZvciBwbGF5aW5nIHRoZSBmaWxlICovCiAgIGludAkJCW5Gcm9tRnJhbWU7CiAgIGludAkJCW5Ub0ZyYW1lOwogICBpbnQJCQluTG9vcDsKICAgaW50CQkJY3VyckZyYW1lOwogICAvKiBCYWNrZ3JvdW5kIGZyYW1lIGluZm8qLwogICBIQklUTUFQCSAgICBia2dGcmFtZWI7CiAgIExQRFdPUkQJCWJrQ29sb3I7Cn0gQU5JTUFURV9JTkZPOwoKI2RlZmluZSBBTklNQVRFX0dldEluZm9QdHIoaFduZCkgKChBTklNQVRFX0lORk8gKilHZXRXaW5kb3dMb25nQShoV25kLCAwKSkKCkhNT0RVTEUgaE1vZFdpbm1tOwoKc3RhdGljIHZvaWQgQU5JTUFURV9Ob3RpZnkoQU5JTUFURV9JTkZPKiBpbmZvUHRyLCBVSU5UIG5vdGlmKQp7CiAgICBTZW5kTWVzc2FnZUEoR2V0UGFyZW50KGluZm9QdHItPmhXbmQpLCBXTV9DT01NQU5ELCAKCQkgTUFLRVdQQVJBTShHZXREbGdDdHJsSUQoaW5mb1B0ci0+aFduZCksIG5vdGlmKSwgCgkJIChMUEFSQU0paW5mb1B0ci0+aFduZCk7Cn0KCnN0YXRpYyBCT09MIEFOSU1BVEVfTG9hZFJlc0EoQU5JTUFURV9JTkZPICppbmZvUHRyLCBISU5TVEFOQ0UgaEluc3QsIExQU1RSIGxwTmFtZSkKewogICAgSFJTUkMgCWhyc3JjOwogICAgTU1JT0lORk8JbW1pbmZvOwogICAgTFBWT0lECWxwQXZpOwogICAgCiAgICBocnNyYyA9IEZpbmRSZXNvdXJjZUEoaEluc3QsIGxwTmFtZSwgIkFWSSIpOwogICAgaWYgKCFocnNyYykKCXJldHVybiBGQUxTRTsKICAgIAogICAgaW5mb1B0ci0+aFJlcyA9IExvYWRSZXNvdXJjZShoSW5zdCwgaHJzcmMpOwogICAgaWYgKCFpbmZvUHRyLT5oUmVzKQogCXJldHVybiBGQUxTRTsKICAgIAogICAgbHBBdmkgPSBMb2NrUmVzb3VyY2UoaW5mb1B0ci0+aFJlcyk7CiAgICBpZiAoIWxwQXZpKQoJcmV0dXJuIEZBTFNFOwogICAgCiAgICBtZW1zZXQoJm1taW5mbywgMCwgc2l6ZW9mKG1taW5mbykpOwogICAgbW1pbmZvLmZjY0lPUHJvYyA9IEZPVVJDQ19NRU07CiAgICBtbWluZm8ucGNoQnVmZmVyID0gKExQU1RSKWxwQXZpOwogICAgbW1pbmZvLmNjaEJ1ZmZlciA9IFNpemVvZlJlc291cmNlKGhJbnN0LCBocnNyYyk7CiAgICBpbmZvUHRyLT5oTU1pbyA9IGluZm9QdHItPmZubW1pb09wZW5BKE5VTEwsICZtbWluZm8sIE1NSU9fUkVBRCk7CiAgICAKICAgIGlmICghaW5mb1B0ci0+aE1NaW8pIHsKCUdsb2JhbEZyZWUoKEhHTE9CQUwpbHBBdmkpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGluZm9QdHItPmJrZ0ZyYW1lYj0oSEJJVE1BUClOVUxMOwogICAgCiAgICByZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyBCT09MIEFOSU1BVEVfTG9hZEZpbGVBKEFOSU1BVEVfSU5GTyAqaW5mb1B0ciwgTFBTVFIgbHBOYW1lKQp7CiAgICBpbmZvUHRyLT5oTU1pbyA9IGluZm9QdHItPmZubW1pb09wZW5BKChMUFNUUilscE5hbWUsIE5VTEwsCgkJCSAgICAgICBNTUlPX0FMTE9DQlVGIHwgTU1JT19SRUFEIHwgTU1JT19ERU5ZV1JJVEUpOwogICAgCiAgICBpZiAoIWluZm9QdHItPmhNTWlvKQoJcmV0dXJuIEZBTFNFOwogICAgCiAgICByZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyBMUkVTVUxUIEFOSU1BVEVfRG9TdG9wKEFOSU1BVEVfSU5GTyAqaW5mb1B0cikKewogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmluZm9QdHItPmNzKTsKCiAgICAvKiBzaG91bGQgc3RvcCBwbGF5aW5nICovCiAgICBpZiAoaW5mb1B0ci0+aFNlcnZpY2UpIHsKCVNFUlZJQ0VfRGVsZXRlKGluZm9QdHItPmhTZXJ2aWNlKTsKCWluZm9QdHItPmhTZXJ2aWNlID0gMDsKICAgIH0KICAgIGlmIChpbmZvUHRyLT51VGltZXIpIHsKCUtpbGxUaW1lcihpbmZvUHRyLT5oV25kLCBpbmZvUHRyLT51VGltZXIpOwoJaW5mb1B0ci0+dVRpbWVyID0gMDsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmaW5mb1B0ci0+Y3MpOwoKICAgIEFOSU1BVEVfTm90aWZ5KGluZm9QdHIsIEFDTl9TVE9QKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyB2b2lkIEFOSU1BVEVfRnJlZShBTklNQVRFX0lORk8gKmluZm9QdHIpCnsKICAgIGlmIChpbmZvUHRyLT5oTU1pbykgewoJQU5JTUFURV9Eb1N0b3AoaW5mb1B0cik7CglpbmZvUHRyLT5mbm1taW9DbG9zZShpbmZvUHRyLT5oTU1pbywgMCk7CiAgICBpZiAoaW5mb1B0ci0+YmtnRnJhbWViKSB7CiAJICAgIERlbGV0ZU9iamVjdChpbmZvUHRyLT5ia2dGcmFtZWIpOwogICAgICAgIGluZm9QdHItPmJrZ0ZyYW1lYj0oSEJJVE1BUClOVUxMOwogICAgICAgIGluZm9QdHItPmJrQ29sb3I9TlVMTDsKCX0KCWlmIChpbmZvUHRyLT5oUmVzKSB7CiAJICAgIEZyZWVSZXNvdXJjZShpbmZvUHRyLT5oUmVzKTsKCSAgICBpbmZvUHRyLT5oUmVzID0gMDsKCX0KCWlmIChpbmZvUHRyLT5scEluZGV4KSB7CgkgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaW5mb1B0ci0+bHBJbmRleCk7CgkgICAgaW5mb1B0ci0+bHBJbmRleCA9IE5VTEw7Cgl9CglpZiAoaW5mb1B0ci0+aGljKSB7CgkgICAgKGluZm9QdHItPmZuSUNDbG9zZSkoaW5mb1B0ci0+aGljKTsKCSAgICBpbmZvUHRyLT5oaWMgPSAwOwoJfQoJaWYgKGluZm9QdHItPmluYmloKSB7CgkgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaW5mb1B0ci0+aW5iaWgpOwoJICAgIGluZm9QdHItPmluYmloID0gTlVMTDsKCX0KCWlmIChpbmZvUHRyLT5vdXRiaWgpIHsKCSAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvUHRyLT5vdXRiaWgpOwoJICAgIGluZm9QdHItPm91dGJpaCA9IE5VTEw7Cgl9CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvUHRyLT5pbmRhdGEpOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaW5mb1B0ci0+b3V0ZGF0YSk7CglpbmZvUHRyLT5pbmRhdGEgPSBpbmZvUHRyLT5vdXRkYXRhID0gTlVMTDsKCWluZm9QdHItPmhXbmQgPSAwOwoJaW5mb1B0ci0+aE1NaW8gPSAwOwoJbWVtc2V0KCZpbmZvUHRyLT5tYWgsIDAsIHNpemVvZihpbmZvUHRyLT5tYWgpKTsKCW1lbXNldCgmaW5mb1B0ci0+YXNoLCAwLCBzaXplb2YoaW5mb1B0ci0+YXNoKSk7CglpbmZvUHRyLT5uRnJvbUZyYW1lID0gaW5mb1B0ci0+blRvRnJhbWUgPSBpbmZvUHRyLT5uTG9vcCA9IGluZm9QdHItPmN1cnJGcmFtZSA9IDA7CiAgICB9Cn0KCgpzdGF0aWMgTFJFU1VMVCBBTklNQVRFX1BhaW50RnJhbWUoQU5JTUFURV9JTkZPKiBpbmZvUHRyLCBIREMgaERDKQp7CiAgICBpZiAoIWhEQyB8fCAhaW5mb1B0ci0+aW5iaWgpCglyZXR1cm4gVFJVRTsKICAgIGlmIChpbmZvUHRyLT5oaWMpewogICAgICAgIGlmIChHZXRXaW5kb3dMb25nQShpbmZvUHRyLT5oV25kLCBHV0xfU1RZTEUpICYgQUNTX1RSQU5TUEFSRU5UKXsKICAgICAgICAgICAgRklYTUUoIlRSQU5TUEFSRU5DWSBOT1QgU1VQUE9SVEVEKE5PVCBURVNURUQpIEZPUiBDT01QUkVTU0VEIElNQUdFXG4iKTsKICAgICAgICB9CglTdHJldGNoRElCaXRzKGhEQywgMCwgMCwgaW5mb1B0ci0+b3V0YmloLT5iaVdpZHRoLCBpbmZvUHRyLT5vdXRiaWgtPmJpSGVpZ2h0LAoJCSAgICAgIDAsIDAsIGluZm9QdHItPm91dGJpaC0+YmlXaWR0aCwgaW5mb1B0ci0+b3V0YmloLT5iaUhlaWdodCwKCQkgICAgICBpbmZvUHRyLT5vdXRkYXRhLCAoTFBCSVRNQVBJTkZPKWluZm9QdHItPm91dGJpaCwgRElCX1JHQl9DT0xPUlMsCiAgICAgICAgICAgICAgU1JDQ09QWSk7CiAgICB9CiAgICBlbHNlewogICAgICAgIGlmIChHZXRXaW5kb3dMb25nQShpbmZvUHRyLT5oV25kLCBHV0xfU1RZTEUpICYgQUNTX1RSQU5TUEFSRU5UKXsKICAgICAgICAgICAgSEJJVE1BUCBoYm1NZW0sIGhibU1lbTIsaGJtTWVtMzsKICAgICAgICAgICAgSERDIGhkY1NyYywgaGRjTWFzaywgaGRjTWVtOwoKICAgIAkgICAgaGRjU3JjID0gQ3JlYXRlQ29tcGF0aWJsZURDKGhEQyk7CiAgICAgICAgICAgIGhkY01hc2sgPSBDcmVhdGVDb21wYXRpYmxlREMoaERDKTsKICAgICAgICAgICAgaGRjTWVtID0gQ3JlYXRlQ29tcGF0aWJsZURDKGhEQyk7CgogICAgICAgICAgICAvKiBjcmVhdGUgYSBCbGFjayBhbmQgd2hpdGUgYml0bWFwICovCiAgICAgICAgICAgIGhibU1lbSA9IENyZWF0ZUNvbXBhdGlibGVCaXRtYXAoIGhEQyxpbmZvUHRyLT5pbmJpaC0+YmlXaWR0aCxpbmZvUHRyLT5pbmJpaC0+YmlIZWlnaHQpOwogICAgICAgICAgICBoYm1NZW0yID0gQ3JlYXRlQml0bWFwKGluZm9QdHItPmluYmloLT5iaVdpZHRoLCBpbmZvUHRyLT5pbmJpaC0+YmlIZWlnaHQsIDEsIDEsIE5VTEwpOwogICAgICAgICAgICBoYm1NZW0zID0gQ3JlYXRlQ29tcGF0aWJsZUJpdG1hcCggaERDLGluZm9QdHItPmluYmloLT5iaVdpZHRoLGluZm9QdHItPmluYmloLT5iaUhlaWdodCk7CgogICAgICAgICAgICBTZWxlY3RPYmplY3QoIGhkY1NyYywgaGJtTWVtKTsKCiAgICAgICAgICAgIFN0cmV0Y2hESUJpdHMoaGRjU3JjLCAwLCAwLCBpbmZvUHRyLT5pbmJpaC0+YmlXaWR0aCwgaW5mb1B0ci0+aW5iaWgtPmJpSGVpZ2h0LAoJCSAgICAgIDAsIDAsIGluZm9QdHItPmluYmloLT5iaVdpZHRoLCBpbmZvUHRyLT5pbmJpaC0+YmlIZWlnaHQsCgkJICAgICAgaW5mb1B0ci0+aW5kYXRhLCAoTFBCSVRNQVBJTkZPKWluZm9QdHItPmluYmloLCBESUJfUkdCX0NPTE9SUywKCQkgICAgICBTUkNDT1BZKTsKCiAgICAgICAgICAgIGlmIChpbmZvUHRyLT5ia2dGcmFtZWI9PShIQklUTUFQKU5VTEwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGluZm9QdHItPmJrZ0ZyYW1lYiA9IENyZWF0ZUNvbXBhdGlibGVCaXRtYXAoIGhEQyxpbmZvUHRyLT5pbmJpaC0+YmlXaWR0aCxpbmZvUHRyLT5pbmJpaC0+YmlIZWlnaHQpOwogICAgICAgICAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGNNZW0sIGluZm9QdHItPmJrZ0ZyYW1lYik7CiAgICAgICAgICAgICAgICBCaXRCbHQoaGRjTWVtLCAwLCAwLCBpbmZvUHRyLT5pbmJpaC0+YmlXaWR0aCwgaW5mb1B0ci0+aW5iaWgtPmJpSGVpZ2h0LCBoREMsIDAsIDAsIFNSQ0NPUFkpOwogICAgICAgICAgICAgICAgLyogR2V0IHRoZSB0cmFuc3BhcmVudCBjb2xvciBmcm9tIHRoZSBmaXJzdCBmcmFtZSovCiAgICAgICAgICAgICAgICBpZiAoaW5mb1B0ci0+aW5iaWgtPmJpQml0Q291bnQ8PTgpCiAgICAgICAgICAgICAgICAgICAgaW5mb1B0ci0+YmtDb2xvciA9IChMUFZPSUQpKChMUFNUUilpbmZvUHRyLT5pbmJpaCArIChXT1JEKSgoKExQQklUTUFQSU5GTylpbmZvUHRyLT5pbmJpaCktPmJtaUhlYWRlci5iaVNpemUpKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBpbmZvUHRyLT5ia0NvbG9yID0gKExQVk9JRClHZXRQaXhlbChoZGNTcmMsIDAsIDApOwoKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBOZWVkIHRoZSBjb3B5IG9mIHRoZSBvcmlnaW5hbCBkZXN0aW5hdGlvbiBIREMqLwogICAgICAgICAgICBTZWxlY3RPYmplY3QoIGhkY1NyYywgaW5mb1B0ci0+YmtnRnJhbWViKTsKICAgICAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGNNZW0sIGhibU1lbTMpOwogICAgICAgICAgICBCaXRCbHQoaGRjTWVtLCAwLCAwLCBpbmZvUHRyLT5pbmJpaC0+YmlXaWR0aCwgaW5mb1B0ci0+aW5iaWgtPmJpSGVpZ2h0LCBoZGNTcmMsIDAsIDAsIFNSQ0NPUFkpOwoKICAgICAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGNTcmMsIGhibU1lbSk7CiAgICAgICAgICAgIFNlbGVjdE9iamVjdCggaGRjTWFzaywgaGJtTWVtMik7CgogICAgICAgICAgICAvKldpbmRvd3MgY29udmVydHMgYSBjb2xvciBzb3VyY2UgaW50byBtb25vY2hyb21lIHdoZW4gdGhlIGRlc3RpbmF0aW9uIGlzCiAgICAgICAgICAgIG1vbm9jaHJvbWUuIEluIHRoaXMgc2l0dWF0aW9uLCBhbGwgcGl4ZWxzIGluIHRoZSBjb2xvciBiaXRtYXAgdGhhdCBhcmUgdGhlIHNhbWUgY29sb3IKICAgICAgICAgICAgYXMgdGhlIGJhY2tncm91bmQgY29sb3IgYmVjb21lIDFzLCBhbmQgYWxsIHRoZSBvdGhlciBwaXhlbHMgYXJlIGNvbnZlcnRlZCB0byAwcy4gKi8KCiAgICAgICAgICAgIGlmIChpbmZvUHRyLT5pbmJpaC0+YmlCaXRDb3VudDw9OCkKICAgICAgICAgICAgICAgIFNldEJrQ29sb3IoaGRjU3JjLCBpbmZvUHRyLT5ia0NvbG9yWygoKEJZVEUqKWluZm9QdHItPmluZGF0YSlbMF0pXSk7CiAgICAgICAgICAgIGVsc2V7IC8qIGhhcyBub3QgYmVlbiB0ZXN0ZWQgd2l0aCBtb3JlIHRoZW4gOCBicHAgKi8KICAgICAgICAgICAgICAgIEZJWE1FKCJIYXMgbm90IGJlZW4gdGVzdCB3aXRoIG1vcmUgdGhhbiA4YnBwLCBlcnJvcnMgYXJlIHBvc3NpYmxlXG4iKTsKICAgICAgICAgICAgICAgIFNldEJrQ29sb3IoaGRjU3JjLCAoQ09MT1JSRUYpaW5mb1B0ci0+YmtDb2xvcik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEJpdEJsdChoZGNNYXNrLCAwLCAwLCBpbmZvUHRyLT5pbmJpaC0+YmlXaWR0aCwgaW5mb1B0ci0+aW5iaWgtPmJpSGVpZ2h0LCBoZGNTcmMsIDAsIDAsIFNSQ0NPUFkpOwoKICAgICAgICAgICAgLypEdXJpbmcgYSBibHQgb3BlcmF0aW9uIHdpdGggYSBjb2xvciBkZXN0aW5hdGlvbiwgYSBtb25vY2hyb21lIHNvdXJjZSBiaXRtYXAKICAgICAgICAgICAgKGFuZC9vciBhIGJydXNoIHdoZW4gYXBwbGljYWJsZSkgaXMgY29udmVydGVkIHRvIGNvbG9yIG9uIHRoZSBmbHkgYmVmb3JlIHRoZQogICAgICAgICAgICBhY3R1YWwgUk9QIGlzIGNhcnJpZWQgb3V0IG9uIHRoZSBiaXRzLiBUaGUgMCAoYmxhY2spIHBpeGVscyBpbiB0aGUgbW9ub2Nocm9tZQogICAgICAgICAgICBiaXRtYXAgYXJlIGNvbnZlcnRlZCB0byB0aGUgZGVzdGluYXRpb24ncyB0ZXh0IChmb3JlZ3JvdW5kKSBjb2xvciwgYW5kIHRoZSAxCiAgICAgICAgICAgICh3aGl0ZSkgcGl4ZWxzIGFyZSBjb252ZXJ0ZWQgdG8gdGhlIGJhY2tncm91bmQgY29sb3IuICovCgogICAgICAgICAgICBTZXRCa0NvbG9yKGhkY1NyYywgUkdCKDAsMCwwKSk7ICAgICAgICAgIC8vIDFzIC0tPiBibGFjayAoMHgwMDAwMDApCiAgICAgICAgICAgIFNldFRleHRDb2xvcihoZGNTcmMsIFJHQigyNTUsMjU1LDI1NSkpOyAgLy8gMHMgLS0+IHdoaXRlICgweEZGRkZGRikKCiAgICAgICAgICAgIEJpdEJsdChoZGNTcmMsIDAsIDAsIGluZm9QdHItPmluYmloLT5iaVdpZHRoLCBpbmZvUHRyLT5pbmJpaC0+YmlIZWlnaHQsIGhkY01hc2ssIDAsIDAsIFNSQ0FORCk7CgogICAgICAgICAgICBTZXRCa0NvbG9yKGhkY01lbSwgUkdCKDI1NSwyNTUsMjU1KSk7ICAvLyAwcyAtLT4gd2hpdGUgKDB4RkZGRkZGKQogICAgICAgICAgICBTZXRUZXh0Q29sb3IoaGRjTWVtLCBSR0IoMCwwLDApKTsgICAgICAgICAgLy8gMXMgLS0+IGJsYWNrICgweDAwMDAwMCkKCiAgICAgICAgICAgIEJpdEJsdChoZGNNZW0sIDAsIDAsIGluZm9QdHItPmluYmloLT5iaVdpZHRoLCBpbmZvUHRyLT5pbmJpaC0+YmlIZWlnaHQsIGhkY01hc2ssIDAsIDAsIFNSQ0FORCk7CgogICAgICAgICAgICBCaXRCbHQoaGRjTWVtLCAwLCAwLCBpbmZvUHRyLT5pbmJpaC0+YmlXaWR0aCwgaW5mb1B0ci0+aW5iaWgtPmJpSGVpZ2h0LCBoZGNTcmMsIDAsIDAsIFNSQ1BBSU5UKTsKCiAgICAgICAgICAgIEJpdEJsdChoREMsIDAsIDAsIGluZm9QdHItPmluYmloLT5iaVdpZHRoLCBpbmZvUHRyLT5pbmJpaC0+YmlIZWlnaHQsIGhkY01lbSwgMCwgMCwgU1JDQ09QWSk7CgogICAgICAgICAgICBEZWxldGVEQyhoZGNNZW0pOwogICAgICAgICAgICBEZWxldGVEQyhoZGNTcmMpOwogICAgICAgICAgICBEZWxldGVEQyhoZGNNYXNrKTsKICAgICAgICAgICAgRGVsZXRlT2JqZWN0KGhibU1lbSk7CiAgICAgICAgICAgIERlbGV0ZU9iamVjdChoYm1NZW0yKTsKICAgICAgICAgICAgRGVsZXRlT2JqZWN0KGhibU1lbTMpOwoKICAgICAgICB9CiAgICAgICAgZWxzZXsKICAgICAgICAgICAgU3RyZXRjaERJQml0cyhoREMsIDAsIDAsIGluZm9QdHItPmluYmloLT5iaVdpZHRoLCBpbmZvUHRyLT5pbmJpaC0+YmlIZWlnaHQsCgkJICAgICAgMCwgMCwgaW5mb1B0ci0+aW5iaWgtPmJpV2lkdGgsIGluZm9QdHItPmluYmloLT5iaUhlaWdodCwKCQkgICAgICBpbmZvUHRyLT5pbmRhdGEsIChMUEJJVE1BUElORk8paW5mb1B0ci0+aW5iaWgsIERJQl9SR0JfQ09MT1JTLAoJCSAgICAgIFNSQ0NPUFkpOwogICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBMUkVTVUxUIEFOSU1BVEVfRHJhd0ZyYW1lKEFOSU1BVEVfSU5GTyogaW5mb1B0cikKewogICAgSERDCQloREM7CgogICAgVFJBQ0UoIkRyYXdpbmcgZnJhbWUgJWQgKGxvb3AgJWQpXG4iLCBpbmZvUHRyLT5jdXJyRnJhbWUsIGluZm9QdHItPm5Mb29wKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmaW5mb1B0ci0+Y3MpOwoKICAgIGluZm9QdHItPmZubW1pb1NlZWsoaW5mb1B0ci0+aE1NaW8sIGluZm9QdHItPmxwSW5kZXhbaW5mb1B0ci0+Y3VyckZyYW1lXSwgU0VFS19TRVQpOwogICAgaW5mb1B0ci0+Zm5tbWlvUmVhZChpbmZvUHRyLT5oTU1pbywgaW5mb1B0ci0+aW5kYXRhLCBpbmZvUHRyLT5hc2guZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKICAgIAogICAgaWYgKGluZm9QdHItPmhpYyAmJgoJKGluZm9QdHItPmZuSUNEZWNvbXByZXNzKShpbmZvUHRyLT5oaWMsIDAsIGluZm9QdHItPmluYmloLCBpbmZvUHRyLT5pbmRhdGEsIAoJCQkJICBpbmZvUHRyLT5vdXRiaWgsIGluZm9QdHItPm91dGRhdGEpICE9IElDRVJSX09LKSB7CglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmaW5mb1B0ci0+Y3MpOwoJV0FSTigiRGVjb21wcmVzc2lvbiBlcnJvclxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKChoREMgPSBHZXREQyhpbmZvUHRyLT5oV25kKSkgIT0gMCkgewoJQU5JTUFURV9QYWludEZyYW1lKGluZm9QdHIsIGhEQyk7CglSZWxlYXNlREMoaW5mb1B0ci0+aFduZCwgaERDKTsKICAgIH0KCiAgICBpZiAoaW5mb1B0ci0+Y3VyckZyYW1lKysgPj0gaW5mb1B0ci0+blRvRnJhbWUpIHsKCWluZm9QdHItPmN1cnJGcmFtZSA9IGluZm9QdHItPm5Gcm9tRnJhbWU7CglpZiAoaW5mb1B0ci0+bkxvb3AgIT0gLTEpIHsKCSAgICBpZiAoLS1pbmZvUHRyLT5uTG9vcCA9PSAwKSB7CgkJQU5JTUFURV9Eb1N0b3AoaW5mb1B0cik7CgkgICAgfQoJfQogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmluZm9QdHItPmNzKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIHZvaWQgQ0FMTEJBQ0sgQU5JTUFURV9TZXJ2aWNlQ2FsbGJhY2soVUxPTkdfUFRSIHB0cl8pCnsKICAgIEFOSU1BVEVfSU5GTyoJaW5mb1B0ciA9IChBTklNQVRFX0lORk8qKXB0cl87CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmluZm9QdHItPmNzKTsKICAgIEFOSU1BVEVfRHJhd0ZyYW1lKGluZm9QdHIpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmluZm9QdHItPmNzKTsKfQoKc3RhdGljIExSRVNVTFQgQU5JTUFURV9QbGF5KEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQU5JTUFURV9JTkZPICppbmZvUHRyID0gQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpOwoKICAgIC8qIG5vdGhpbmcgb3BlbmVkICovCiAgICBpZiAoIWluZm9QdHItPmhNTWlvKQoJcmV0dXJuIEZBTFNFOwoKICAgIGlmIChpbmZvUHRyLT5oU2VydmljZSB8fCBpbmZvUHRyLT51VGltZXIpIHsKCUZJWE1FKCJBbHJlYWR5IHBsYXlpbmcgPyB3aGF0IHNob3VsZCBJIGRvID8/XG4iKTsKCUFOSU1BVEVfRG9TdG9wKGluZm9QdHIpOwogICAgfQoKICAgIGluZm9QdHItPm5Gcm9tRnJhbWUgPSAoSU5UKUxPV09SRChsUGFyYW0pOwogICAgaW5mb1B0ci0+blRvRnJhbWUgICA9IChJTlQpSElXT1JEKGxQYXJhbSk7CiAgICBpbmZvUHRyLT5uTG9vcCAgICAgID0gKElOVCl3UGFyYW07CgogICAgaWYgKGluZm9QdHItPm5Ub0ZyYW1lID09IDB4RkZGRikKCWluZm9QdHItPm5Ub0ZyYW1lID0gaW5mb1B0ci0+bWFoLmR3VG90YWxGcmFtZXMgLSAxOwoKICAgIFRSQUNFKCIocmVwZWF0PSVkIGZyb209JWQgdG89JWQpO1xuIiwgCgkgIGluZm9QdHItPm5Mb29wLCBpbmZvUHRyLT5uRnJvbUZyYW1lLCBpbmZvUHRyLT5uVG9GcmFtZSk7CgogICAgaWYgKGluZm9QdHItPm5Gcm9tRnJhbWUgPj0gaW5mb1B0ci0+blRvRnJhbWUgfHwKCWluZm9QdHItPm5Ub0ZyYW1lID49IGluZm9QdHItPm1haC5kd1RvdGFsRnJhbWVzKQoJcmV0dXJuIEZBTFNFOwoKICAgIGluZm9QdHItPmN1cnJGcmFtZSA9IGluZm9QdHItPm5Gcm9tRnJhbWU7CgogICAgaWYgKEdldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9TVFlMRSkgJiBBQ1NfVElNRVIpIHsKCVRSQUNFKCJVc2luZyBhIHRpbWVyXG4iKTsKCS8qIGNyZWF0ZSBhIHRpbWVyIHRvIGRpc3BsYXkgQVZJICovCglpbmZvUHRyLT51VGltZXIgPSBTZXRUaW1lcihoV25kLCAxLCBpbmZvUHRyLT5tYWguZHdNaWNyb1NlY1BlckZyYW1lIC8gMTAwMCwgTlVMTCk7CiAgICB9IGVsc2UgewoJVFJBQ0UoIlVzaW5nIHRoZSBzZXJ2aWNlIHRocmVhZFxuIik7CgkvKiB0aW1lIGlzIGluILVzICovCglpbmZvUHRyLT5oU2VydmljZSA9IFNFUlZJQ0VfQWRkVGltZXIoaW5mb1B0ci0+bWFoLmR3TWljcm9TZWNQZXJGcmFtZSAvIDEwMDAsIAoJCQkJCSAgICAgQU5JTUFURV9TZXJ2aWNlQ2FsbGJhY2ssIChEV09SRClpbmZvUHRyKTsKICAgIH0KCQogICAgQU5JTUFURV9Ob3RpZnkoaW5mb1B0ciwgQUNOX1NUQVJUKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyBCT09MIEFOSU1BVEVfR2V0QXZpSW5mbyhBTklNQVRFX0lORk8gKmluZm9QdHIpCnsKICAgIE1NQ0tJTkZPCQlja01haW5SSUZGOwogICAgTU1DS0lORk8JCW1tY2tIZWFkOwogICAgTU1DS0lORk8JCW1tY2tMaXN0OwogICAgTU1DS0lORk8JCW1tY2tJbmZvOwogICAgRFdPUkQJCW51bUZyYW1lOwogICAgRFdPUkQJCWluc2l6ZTsKCiAgICBpZiAoaW5mb1B0ci0+Zm5tbWlvRGVzY2VuZChpbmZvUHRyLT5oTU1pbywgJmNrTWFpblJJRkYsIE5VTEwsIDApICE9IDApIHsKCVdBUk4oIkNhbid0IGZpbmQgJ1JJRkYnIGNodW5rXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoKGNrTWFpblJJRkYuY2tpZCAhPSBGT1VSQ0NfUklGRikgfHwKCShja01haW5SSUZGLmZjY1R5cGUgIT0gbW1pb0ZPVVJDQygnQScsICdWJywgJ0knLCAnICcpKSkgewoJV0FSTigiQ2FuJ3QgZmluZCAnQVZJICcgY2h1bmtcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIG1tY2tIZWFkLmZjY1R5cGUgPSBtbWlvRk9VUkNDKCdoJywgJ2QnLCAncicsICdsJyk7CiAgICBpZiAoaW5mb1B0ci0+Zm5tbWlvRGVzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tIZWFkLCAmY2tNYWluUklGRiwgTU1JT19GSU5ETElTVCkgIT0gMCkgewoJV0FSTigiQ2FuJ3QgZmluZCAnaGRybCcgbGlzdFxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbW1ja0luZm8uY2tpZCA9IG1taW9GT1VSQ0MoJ2EnLCAndicsICdpJywgJ2gnKTsKICAgIGlmIChpbmZvUHRyLT5mbm1taW9EZXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0luZm8sICZtbWNrSGVhZCwgTU1JT19GSU5EQ0hVTkspICE9IDApIHsKCVdBUk4oIkNhbid0IGZpbmQgJ2F2aWgnIGNodW5rXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpbmZvUHRyLT5mbm1taW9SZWFkKGluZm9QdHItPmhNTWlvLCAoTFBTVFIpJmluZm9QdHItPm1haCwgc2l6ZW9mKGluZm9QdHItPm1haCkpOwogICAgVFJBQ0UoIm1haC5kd01pY3JvU2VjUGVyRnJhbWU9JWxkXG4iLCAJaW5mb1B0ci0+bWFoLmR3TWljcm9TZWNQZXJGcmFtZSk7CiAgICBUUkFDRSgibWFoLmR3TWF4Qnl0ZXNQZXJTZWM9JWxkXG4iLCAJaW5mb1B0ci0+bWFoLmR3TWF4Qnl0ZXNQZXJTZWMpOwogICAgVFJBQ0UoIm1haC5kd1BhZGRpbmdHcmFudWxhcml0eT0lbGRcbiIsIAlpbmZvUHRyLT5tYWguZHdQYWRkaW5nR3JhbnVsYXJpdHkpOwogICAgVFJBQ0UoIm1haC5kd0ZsYWdzPSVsZFxuIiwgCQkJaW5mb1B0ci0+bWFoLmR3RmxhZ3MpOwogICAgVFJBQ0UoIm1haC5kd1RvdGFsRnJhbWVzPSVsZFxuIiwgCQlpbmZvUHRyLT5tYWguZHdUb3RhbEZyYW1lcyk7CiAgICBUUkFDRSgibWFoLmR3SW5pdGlhbEZyYW1lcz0lbGRcbiIsIAkJaW5mb1B0ci0+bWFoLmR3SW5pdGlhbEZyYW1lcyk7CiAgICBUUkFDRSgibWFoLmR3U3RyZWFtcz0lbGRcbiIsIAkJaW5mb1B0ci0+bWFoLmR3U3RyZWFtcyk7CiAgICBUUkFDRSgibWFoLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZT0lbGRcbiIsCWluZm9QdHItPm1haC5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpOwogICAgVFJBQ0UoIm1haC5kd1dpZHRoPSVsZFxuIiwgCQkJaW5mb1B0ci0+bWFoLmR3V2lkdGgpOwogICAgVFJBQ0UoIm1haC5kd0hlaWdodD0lbGRcbiIsIAkJaW5mb1B0ci0+bWFoLmR3SGVpZ2h0KTsKICAgIGluZm9QdHItPmZubW1pb0FzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tJbmZvLCAwKTsKCiAgICBtbWNrTGlzdC5mY2NUeXBlID0gbW1pb0ZPVVJDQygncycsICd0JywgJ3InLCAnbCcpOwogICAgaWYgKGluZm9QdHItPmZubW1pb0Rlc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrTGlzdCwgJm1tY2tIZWFkLCBNTUlPX0ZJTkRMSVNUKSAhPSAwKSB7CglXQVJOKCJDYW4ndCBmaW5kICdzdHJsJyBsaXN0XG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBtbWNrSW5mby5ja2lkID0gbW1pb0ZPVVJDQygncycsICd0JywgJ3InLCAnaCcpOwogICAgaWYgKGluZm9QdHItPmZubW1pb0Rlc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrSW5mbywgJm1tY2tMaXN0LCBNTUlPX0ZJTkRDSFVOSykgIT0gMCkgewoJV0FSTigiQ2FuJ3QgZmluZCAnc3RyaCcgY2h1bmtcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGluZm9QdHItPmZubW1pb1JlYWQoaW5mb1B0ci0+aE1NaW8sIChMUFNUUikmaW5mb1B0ci0+YXNoLCBzaXplb2YoaW5mb1B0ci0+YXNoKSk7CiAgICBUUkFDRSgiYXNoLmZjY1R5cGU9JyVjJWMlYyVjJ1xuIiwgCQlMT0JZVEUoTE9XT1JEKGluZm9QdHItPmFzaC5mY2NUeXBlKSksIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhJQllURShMT1dPUkQoaW5mb1B0ci0+YXNoLmZjY1R5cGUpKSwgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9CWVRFKEhJV09SRChpbmZvUHRyLT5hc2guZmNjVHlwZSkpLCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBISUJZVEUoSElXT1JEKGluZm9QdHItPmFzaC5mY2NUeXBlKSkpOwogICAgVFJBQ0UoImFzaC5mY2NIYW5kbGVyPSclYyVjJWMlYydcbiIsCUxPQllURShMT1dPUkQoaW5mb1B0ci0+YXNoLmZjY0hhbmRsZXIpKSwgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSElCWVRFKExPV09SRChpbmZvUHRyLT5hc2guZmNjSGFuZGxlcikpLCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT0JZVEUoSElXT1JEKGluZm9QdHItPmFzaC5mY2NIYW5kbGVyKSksIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhJQllURShISVdPUkQoaW5mb1B0ci0+YXNoLmZjY0hhbmRsZXIpKSk7CiAgICBUUkFDRSgiYXNoLmR3RmxhZ3M9JWxkXG4iLCAJCQlpbmZvUHRyLT5hc2guZHdGbGFncyk7CiAgICBUUkFDRSgiYXNoLndQcmlvcml0eT0lZFxuIiwgCQlpbmZvUHRyLT5hc2gud1ByaW9yaXR5KTsKICAgIFRSQUNFKCJhc2gud0xhbmd1YWdlPSVkXG4iLCAJCWluZm9QdHItPmFzaC53TGFuZ3VhZ2UpOwogICAgVFJBQ0UoImFzaC5kd0luaXRpYWxGcmFtZXM9JWxkXG4iLCAJCWluZm9QdHItPmFzaC5kd0luaXRpYWxGcmFtZXMpOwogICAgVFJBQ0UoImFzaC5kd1NjYWxlPSVsZFxuIiwgCQkJaW5mb1B0ci0+YXNoLmR3U2NhbGUpOwogICAgVFJBQ0UoImFzaC5kd1JhdGU9JWxkXG4iLCAJCQlpbmZvUHRyLT5hc2guZHdSYXRlKTsKICAgIFRSQUNFKCJhc2guZHdTdGFydD0lbGRcbiIsIAkJCWluZm9QdHItPmFzaC5kd1N0YXJ0KTsKICAgIFRSQUNFKCJhc2guZHdMZW5ndGg9JWxkXG4iLCAJCWluZm9QdHItPmFzaC5kd0xlbmd0aCk7CiAgICBUUkFDRSgiYXNoLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZT0lbGRcbiIsIAlpbmZvUHRyLT5hc2guZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKICAgIFRSQUNFKCJhc2guZHdRdWFsaXR5PSVsZFxuIiwgCQlpbmZvUHRyLT5hc2guZHdRdWFsaXR5KTsKICAgIFRSQUNFKCJhc2guZHdTYW1wbGVTaXplPSVsZFxuIiwgCQlpbmZvUHRyLT5hc2guZHdTYW1wbGVTaXplKTsKICAgIFRSQUNFKCJhc2gucmNGcmFtZT0oJWQsJWQsJWQsJWQpXG4iLCAJaW5mb1B0ci0+YXNoLnJjRnJhbWUudG9wLCBpbmZvUHRyLT5hc2gucmNGcmFtZS5sZWZ0LCAKCSAgaW5mb1B0ci0+YXNoLnJjRnJhbWUuYm90dG9tLCBpbmZvUHRyLT5hc2gucmNGcmFtZS5yaWdodCk7CiAgICBpbmZvUHRyLT5mbm1taW9Bc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrSW5mbywgMCk7CgogICAgbW1ja0luZm8uY2tpZCA9IG1taW9GT1VSQ0MoJ3MnLCAndCcsICdyJywgJ2YnKTsKICAgIGlmIChpbmZvUHRyLT5mbm1taW9EZXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0luZm8sICZtbWNrTGlzdCwgTU1JT19GSU5EQ0hVTkspICE9IDApIHsKCVdBUk4oIkNhbid0IGZpbmQgJ3N0cmgnIGNodW5rXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpbmZvUHRyLT5pbmJpaCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBtbWNrSW5mby5ja3NpemUpOwogICAgaWYgKCFpbmZvUHRyLT5pbmJpaCkgewoJV0FSTigiQ2FuJ3QgYWxsb2MgaW5wdXQgQklIXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpbmZvUHRyLT5mbm1taW9SZWFkKGluZm9QdHItPmhNTWlvLCAoTFBTVFIpaW5mb1B0ci0+aW5iaWgsIG1tY2tJbmZvLmNrc2l6ZSk7CiAgICBUUkFDRSgiYmloLmJpU2l6ZT0lbGRcbiIsIAkJaW5mb1B0ci0+aW5iaWgtPmJpU2l6ZSk7CiAgICBUUkFDRSgiYmloLmJpV2lkdGg9JWxkXG4iLCAJCWluZm9QdHItPmluYmloLT5iaVdpZHRoKTsKICAgIFRSQUNFKCJiaWguYmlIZWlnaHQ9JWxkXG4iLCAJaW5mb1B0ci0+aW5iaWgtPmJpSGVpZ2h0KTsKICAgIFRSQUNFKCJiaWguYmlQbGFuZXM9JWRcbiIsIAkJaW5mb1B0ci0+aW5iaWgtPmJpUGxhbmVzKTsKICAgIFRSQUNFKCJiaWguYmlCaXRDb3VudD0lZFxuIiwgCWluZm9QdHItPmluYmloLT5iaUJpdENvdW50KTsKICAgIFRSQUNFKCJiaWguYmlDb21wcmVzc2lvbj0lbGRcbiIsIAlpbmZvUHRyLT5pbmJpaC0+YmlDb21wcmVzc2lvbik7CiAgICBUUkFDRSgiYmloLmJpU2l6ZUltYWdlPSVsZFxuIiwgCWluZm9QdHItPmluYmloLT5iaVNpemVJbWFnZSk7CiAgICBUUkFDRSgiYmloLmJpWFBlbHNQZXJNZXRlcj0lbGRcbiIsIAlpbmZvUHRyLT5pbmJpaC0+YmlYUGVsc1Blck1ldGVyKTsKICAgIFRSQUNFKCJiaWguYmlZUGVsc1Blck1ldGVyPSVsZFxuIiwgCWluZm9QdHItPmluYmloLT5iaVlQZWxzUGVyTWV0ZXIpOwogICAgVFJBQ0UoImJpaC5iaUNsclVzZWQ9JWxkXG4iLCAJaW5mb1B0ci0+aW5iaWgtPmJpQ2xyVXNlZCk7CiAgICBUUkFDRSgiYmloLmJpQ2xySW1wb3J0YW50PSVsZFxuIiwgCWluZm9QdHItPmluYmloLT5iaUNsckltcG9ydGFudCk7CiAgICBpbmZvUHRyLT5mbm1taW9Bc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrSW5mbywgMCk7CgogICAgaW5mb1B0ci0+Zm5tbWlvQXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0xpc3QsIDApOwogICAgCiNpZiAwCiAgICAvKiBhbiBBVkkgaGFzIDAgb3IgMSB2aWRlbyBzdHJlYW0sIGFuZCB0byBiZSBhbmltYXRlZCBzaG91bGQgbm90IGNvbnRhaW4KICAgICAqIGFuIGF1ZGlvIHN0cmVhbSwgc28gb25seSBvbmUgc3RybCBpcyBhbGxvd2VkIAogICAgICovCiAgICBtbWNrTGlzdC5mY2NUeXBlID0gbW1pb0ZPVVJDQygncycsICd0JywgJ3InLCAnbCcpOwogICAgaWYgKGluZm9QdHItPmZubW1pb0Rlc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrTGlzdCwgJm1tY2tIZWFkLCBNTUlPX0ZJTkRMSVNUKSA9PSAwKSB7CglXQVJOKCJUaGVyZSBzaG91bGQgYmUgYSBzaW5nbGUgJ3N0cmwnIGxpc3RcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQojZW5kaWYKCiAgICBpbmZvUHRyLT5mbm1taW9Bc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrSGVhZCwgMCk7CgogICAgLyogbm8gbmVlZCB0byByZWFkIG9wdGlvbmFsIEpVTksgY2h1bmsgKi8KCiAgICBtbWNrTGlzdC5mY2NUeXBlID0gbW1pb0ZPVVJDQygnbScsICdvJywgJ3YnLCAnaScpOwogICAgaWYgKGluZm9QdHItPmZubW1pb0Rlc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrTGlzdCwgJmNrTWFpblJJRkYsIE1NSU9fRklORExJU1QpICE9IDApIHsKCVdBUk4oIkNhbid0IGZpbmQgJ21vdmknIGxpc3RcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIEZJWE1FOiBzaG91bGQgaGFuZGxlIHRoZSAncmVjICcgTElTVCB3aGVuIHByZXNlbnQgKi8KCiAgICBpbmZvUHRyLT5scEluZGV4ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIAoJCQkJIGluZm9QdHItPm1haC5kd1RvdGFsRnJhbWVzICogc2l6ZW9mKERXT1JEKSk7CiAgICBpZiAoIWluZm9QdHItPmxwSW5kZXgpIHsKCVdBUk4oIkNhbid0IGFsbG9jIGluZGV4IGFycmF5XG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBudW1GcmFtZSA9IGluc2l6ZSA9IDA7CiAgICB3aGlsZSAoaW5mb1B0ci0+Zm5tbWlvRGVzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tJbmZvLCAmbW1ja0xpc3QsIDApID09IDAgJiYgCgkgICBudW1GcmFtZSA8IGluZm9QdHItPm1haC5kd1RvdGFsRnJhbWVzKSB7CglpbmZvUHRyLT5scEluZGV4W251bUZyYW1lXSA9IG1tY2tJbmZvLmR3RGF0YU9mZnNldDsKCWlmIChpbnNpemUgPCBtbWNrSW5mby5ja3NpemUpCgkgICAgaW5zaXplID0gbW1ja0luZm8uY2tzaXplOwoJbnVtRnJhbWUrKzsKCWluZm9QdHItPmZubW1pb0FzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tJbmZvLCAwKTsKICAgIH0KICAgIGlmIChudW1GcmFtZSAhPSBpbmZvUHRyLT5tYWguZHdUb3RhbEZyYW1lcykgewoJV0FSTigiRm91bmQgJWxkIGZyYW1lcyAoLyVsZClcbiIsIG51bUZyYW1lLCBpbmZvUHRyLT5tYWguZHdUb3RhbEZyYW1lcyk7CglyZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpZiAoaW5zaXplID4gaW5mb1B0ci0+YXNoLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSkgewoJV0FSTigiaW5zaXplPSVsZCBzdWdnZXN0ZWRTaXplPSVsZFxuIiwgaW5zaXplLCBpbmZvUHRyLT5hc2guZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKCWluZm9QdHItPmFzaC5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBpbnNpemU7CiAgICB9CgogICAgaW5mb1B0ci0+aW5kYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGluZm9QdHItPmFzaC5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpOwogICAgaWYgKCFpbmZvUHRyLT5pbmRhdGEpIHsKCVdBUk4oIkNhbid0IGFsbG9jIGlucHV0IGJ1ZmZlclxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCgpzdGF0aWMgQk9PTCAgICBBTklNQVRFX0dldEF2aUNvZGVjKEFOSU1BVEVfSU5GTyAqaW5mb1B0cikKewogICAgRFdPUkQJb3V0U2l6ZTsKCiAgICAvKiBjaGVjayB1bmNvbXByZXNzZWQgQVZJICovCiAgICBpZiAoaW5mb1B0ci0+YXNoLmZjY0hhbmRsZXIgPT0gbW1pb0ZPVVJDQygnRCcsICdJJywgJ0InLCAnICcpIHx8CglpbmZvUHRyLT5hc2guZmNjSGFuZGxlciA9PSBtbWlvRk9VUkNDKCdSJywgJ0wnLCAnRScsICcgJykpIHsKCWluZm9QdHItPmhpYyA9IDA7CglyZXR1cm4gVFJVRTsKICAgIH0KCiAgICAvKiB0cnkgdG8gZ2V0IGEgZGVjb21wcmVzc29yIGZvciB0aGF0IHR5cGUgKi8KICAgIGluZm9QdHItPmhpYyA9IChpbmZvUHRyLT5mbklDT3BlbikoSUNUWVBFX1ZJREVPLCAKCQkJCSAgICAgICBpbmZvUHRyLT5hc2guZmNjSGFuZGxlciwgCgkJCQkgICAgICAgSUNNT0RFX0RFQ09NUFJFU1MpOwogICAgaWYgKCFpbmZvUHRyLT5oaWMpIHsKCVdBUk4oIkNhbid0IGxvYWQgY29kZWMgZm9yIHRoZSBmaWxlXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KICAgIAogICAgb3V0U2l6ZSA9IChpbmZvUHRyLT5mbklDU2VuZE1lc3NhZ2UpKGluZm9QdHItPmhpYywgCgkJCQkJIElDTV9ERUNPTVBSRVNTX0dFVF9GT1JNQVQsIAoJCQkJCSAoRFdPUkQpaW5mb1B0ci0+aW5iaWgsIDBMKTsKICAgIGluZm9QdHItPm91dGJpaCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBvdXRTaXplKTsKICAgIGlmICghaW5mb1B0ci0+b3V0YmloKSB7CglXQVJOKCJDYW4ndCBhbGxvYyBvdXRwdXQgQklIXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoKGluZm9QdHItPmZuSUNTZW5kTWVzc2FnZSkoaW5mb1B0ci0+aGljLCBJQ01fREVDT01QUkVTU19HRVRfRk9STUFULCAKCQkJCSAgIChEV09SRClpbmZvUHRyLT5pbmJpaCwgCgkJCQkgICAoRFdPUkQpaW5mb1B0ci0+b3V0YmloKSAhPSBJQ0VSUl9PSykgewoJV0FSTigiQ2FuJ3QgZ2V0IG91dHB1dCBCSUhcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGluZm9QdHItPm91dGRhdGEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaW5mb1B0ci0+b3V0YmloLT5iaVNpemVJbWFnZSk7CiAgICBpZiAoIWluZm9QdHItPm91dGRhdGEpIHsKCVdBUk4oIkNhbid0IGFsbG9jIG91dHB1dCBidWZmZXJcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICgoaW5mb1B0ci0+Zm5JQ1NlbmRNZXNzYWdlKShpbmZvUHRyLT5oaWMsIElDTV9ERUNPTVBSRVNTX0JFR0lOLCAKCQkJCSAgIChEV09SRClpbmZvUHRyLT5pbmJpaCwgCgkJCQkgICAoRFdPUkQpaW5mb1B0ci0+b3V0YmloKSAhPSBJQ0VSUl9PSykgewoJV0FSTigiQ2FuJ3QgYmVnaW4gZGVjb21wcmVzc2lvblxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyB2b2lkIEFOSU1BVEVfQ2VudGVyKEFOSU1BVEVfSU5GTyAqaW5mb1B0cikKewogICAgaW50IHgseSxkeCxkeTsKICAgIFJFQ1QgUmVjdDsKICAgIEhXTkQgaFduZD1pbmZvUHRyLT5oV25kOwogICAgSFdORCBoV25kUGFyZW50PUdldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9IV05EUEFSRU5UKTsKCiAgICBpZiAoIWhXbmRQYXJlbnQgfHwgIUdldFdpbmRvd1JlY3QoaFduZFBhcmVudCwgJlJlY3QpKSByZXR1cm47CgogICAgZHg9UmVjdC5yaWdodC1SZWN0LmxlZnQrMTsKICAgIGR5PVJlY3QuYm90dG9tLVJlY3QudG9wKzE7CiAgICB4PWluZm9QdHItPm1haC5kd1dpZHRoIDwgZHggPyAoZHgtaW5mb1B0ci0+bWFoLmR3V2lkdGgpID4+IDEgOiAwOwogICAgeT1pbmZvUHRyLT5tYWguZHdIZWlnaHQgPCBkeSA/IChkeS1pbmZvUHRyLT5tYWguZHdIZWlnaHQpID4+IDEgOiAwOwoKICAgIE1vdmVXaW5kb3coaFduZCwgeCwgeSwgaW5mb1B0ci0+bWFoLmR3V2lkdGgsIGluZm9QdHItPm1haC5kd0hlaWdodCwgVFJVRSk7Cn0KCnN0YXRpYyBMUkVTVUxUIEFOSU1BVEVfT3BlbkEoSFdORCBoV25kLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBBTklNQVRFX0lORk8gKmluZm9QdHIgPSBBTklNQVRFX0dldEluZm9QdHIoaFduZCk7CiAgICBISU5TVEFOQ0UgaEluc3RhbmNlID0gKEhJTlNUQU5DRSl3UGFyYW07CgogICAgQU5JTUFURV9GcmVlKGluZm9QdHIpOwoKICAgIGlmICghbFBhcmFtKSB7CglUUkFDRSgiQ2xvc2luZyBhdmkhXG4iKTsKCXJldHVybiBUUlVFOwogICAgfQogICAgCiAgICBpZiAoIWhJbnN0YW5jZSkKICAgICAgIGhJbnN0YW5jZSA9IEdldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9ISU5TVEFOQ0UpOwoKICAgIGlmIChISVdPUkQobFBhcmFtKSkgewoJVFJBQ0UoIihcIiVzXCIpO1xuIiwgKExQU1RSKWxQYXJhbSk7CgoJaWYgKCFBTklNQVRFX0xvYWRSZXNBKGluZm9QdHIsIGhJbnN0YW5jZSwgKExQU1RSKWxQYXJhbSkpIHsKCSAgICBUUkFDRSgiTm8gQVZJIHJlc291cmNlIGZvdW5kIVxuIik7CgkgICAgaWYgKCFBTklNQVRFX0xvYWRGaWxlQShpbmZvUHRyLCAoTFBTVFIpbFBhcmFtKSkgewoJCVdBUk4oIk5vIEFWSSBmaWxlIGZvdW5kIVxuIik7CgkJcmV0dXJuIEZBTFNFOwoJICAgIH0KCX0KICAgIH0gZWxzZSB7CglUUkFDRSgiKCV1KTtcbiIsIChXT1JEKUxPV09SRChsUGFyYW0pKTsKCglpZiAoIUFOSU1BVEVfTG9hZFJlc0EoaW5mb1B0ciwgaEluc3RhbmNlLAoJCQkgICAgICBNQUtFSU5UUkVTT1VSQ0VBKChJTlQpbFBhcmFtKSkpIHsKCSAgICBXQVJOKCJObyBBVkkgcmVzb3VyY2UgZm91bmQhXG4iKTsKCSAgICByZXR1cm4gRkFMU0U7Cgl9CiAgICB9CgogICAgaWYgKCFBTklNQVRFX0dldEF2aUluZm8oaW5mb1B0cikpIHsKCVdBUk4oIkNhbid0IGdldCBBVkkgaW5mb3JtYXRpb25cbiIpOwoJQU5JTUFURV9GcmVlKGluZm9QdHIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICghQU5JTUFURV9HZXRBdmlDb2RlYyhpbmZvUHRyKSkgewoJV0FSTigiQ2FuJ3QgZ2V0IEFWSSBDb2RlY1xuIik7CglBTklNQVRFX0ZyZWUoaW5mb1B0cik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKEdldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9TVFlMRSkgJiBBQ1NfQ0VOVEVSKSB7CgoJQU5JTUFURV9DZW50ZXIoaW5mb1B0cik7CgogICAgfSBlbHNlIHsKCS8qCU1vdmVXaW5kb3coaFduZCwgMCwgMCwgaW5mb1B0ci0+bWFoLmR3V2lkdGgsIGluZm9QdHItPm1haC5kd0hlaWdodCwgRkFMU0UpOyovCglTZXRXaW5kb3dQb3MoaFduZCwgMCwgMCwgMCwgaW5mb1B0ci0+bWFoLmR3V2lkdGgsIGluZm9QdHItPm1haC5kd0hlaWdodCwKCQkgICAgIFNXUF9OT0FDVElWQVRFIHwgU1dQX05PTU9WRSB8IFNXUF9OT1pPUkRFUik7CiAgICB9CgogICAgaWYgKEdldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9TVFlMRSkgJiBBQ1NfVFJBTlNQQVJFTlQpIHsKCUZJWE1FKCJBQ1NfVFJBTlNQQVJFTlQ6IE5JWVxuIik7CiAgICB9CgogICAgaWYgKEdldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9TVFlMRSkgJiBBQ1NfQVVUT1BMQVkpIHsKCXJldHVybiBBTklNQVRFX1BsYXkoaFduZCwgLTEsIChMUEFSQU0pTUFLRUxPTkcoMCwgaW5mb1B0ci0+bWFoLmR3VG90YWxGcmFtZXMtMSkpOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgoKLyogPDwgQU5JTUFURV9PcGVuMzJXID4+ICovCgpzdGF0aWMgTFJFU1VMVCBBTklNQVRFX1N0b3AoSFdORCBoV25kLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBBTklNQVRFX0lORk8gKmluZm9QdHIgPSBBTklNQVRFX0dldEluZm9QdHIoaFduZCk7CgogICAgLyogbm90aGluZyBvcGVuZWQgKi8KICAgIGlmICghaW5mb1B0ci0+aE1NaW8pCglyZXR1cm4gRkFMU0U7CgogICAgQU5JTUFURV9Eb1N0b3AoaW5mb1B0cik7CiAgICByZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyBMUkVTVUxUIEFOSU1BVEVfQ3JlYXRlKEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQU5JTUFURV9JTkZPKglpbmZvUHRyOwogICAgSE1PRFVMRQkJaE1vZHVsZSA9IExvYWRMaWJyYXJ5QSgibXN2ZnczMi5kbGwiKTsKCiAgICBpZiAoIWhNb2R1bGUpCglyZXR1cm4gRkFMU0U7CgogICAgLyogYWxsb2NhdGUgbWVtb3J5IGZvciBpbmZvIHN0cnVjdHVyZSAqLwogICAgaW5mb1B0ciA9IChBTklNQVRFX0lORk8gKilDT01DVEwzMl9BbGxvYyhzaXplb2YoQU5JTUFURV9JTkZPKSk7CiAgICBpZiAoIWluZm9QdHIpIHsKCUVSUigiY291bGQgbm90IGFsbG9jYXRlIGluZm8gbWVtb3J5IVxuIik7CglyZXR1cm4gMDsKICAgIH0KCiAgICAvKiBUZW1wb3JhcnkgaGFjayB1bnRpbCB3ZSBnZXQgZGxsZ2x1ZSB1cCBhbmQgcnVubmluZyAqLwogICAgaW5mb1B0ci0+Zm5JQ09wZW4gICAgICAgID0gKHZvaWQqKUdldFByb2NBZGRyZXNzKGhNb2R1bGUsICJJQ09wZW4iKTsKICAgIGluZm9QdHItPmZuSUNDbG9zZSAgICAgICA9ICh2b2lkKilHZXRQcm9jQWRkcmVzcyhoTW9kdWxlLCAiSUNDbG9zZSIpOwogICAgaW5mb1B0ci0+Zm5JQ1NlbmRNZXNzYWdlID0gKHZvaWQqKUdldFByb2NBZGRyZXNzKGhNb2R1bGUsICJJQ1NlbmRNZXNzYWdlIik7CiAgICBpbmZvUHRyLT5mbklDRGVjb21wcmVzcyAgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZHVsZSwgIklDRGVjb21wcmVzcyIpOwoKICAgIFRSQUNFKCJBbmltYXRlIHN0eWxlPTB4JTA4bHgsIHBhcmVudD0lMDhseFxuIiwgR2V0V2luZG93TG9uZ0EoaFduZCwgR1dMX1NUWUxFKSwgKERXT1JEKUdldFBhcmVudChoV25kKSk7CgogICAgLyogc3RvcmUgY3Jvc3NyZWYgaFduZCA8LT4gaW5mbyBzdHJ1Y3R1cmUgKi8KICAgIFNldFdpbmRvd0xvbmdBKGhXbmQsIDAsIChEV09SRClpbmZvUHRyKTsKICAgIGluZm9QdHItPmhXbmQgPSBoV25kOwoKICAgIGhNb2RXaW5tbSA9IExvYWRMaWJyYXJ5QSgiV0lOTU0iKTsKCiAgICBpbmZvUHRyLT5mbm1taW9PcGVuQSA9ICh2b2lkKilHZXRQcm9jQWRkcmVzcyhoTW9kV2lubW0sICJtbWlvT3BlbkEiKTsKICAgIGluZm9QdHItPmZubW1pb0Nsb3NlID0gKHZvaWQqKUdldFByb2NBZGRyZXNzKGhNb2RXaW5tbSwgIm1taW9DbG9zZSIpOwogICAgaW5mb1B0ci0+Zm5tbWlvQXNjZW5kID0gKHZvaWQqKUdldFByb2NBZGRyZXNzKGhNb2RXaW5tbSwgIm1taW9Bc2NlbmQiKTsKICAgIGluZm9QdHItPmZubW1pb0Rlc2NlbmQgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZFdpbm1tLCAibW1pb0Rlc2NlbmQiKTsKICAgIGluZm9QdHItPmZubW1pb1NlZWsgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZFdpbm1tLCAibW1pb1NlZWsiKTsKICAgIGluZm9QdHItPmZubW1pb1JlYWQgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZFdpbm1tLCAibW1pb1JlYWQiKTsKCiAgICBJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCZpbmZvUHRyLT5jcyk7CiAgICAKICAgIHJldHVybiAwOwp9CgoKc3RhdGljIExSRVNVTFQgQU5JTUFURV9EZXN0cm95KEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQU5JTUFURV9JTkZPICppbmZvUHRyID0gQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpOwoKCiAgICAvKiBmcmVlIGF2aSBkYXRhICovCiAgICBBTklNQVRFX0ZyZWUoaW5mb1B0cik7CgogICAgLyogZnJlZSBhbmltYXRlIGluZm8gZGF0YSAqLwogICAgQ09NQ1RMMzJfRnJlZShpbmZvUHRyKTsKICAgIFNldFdpbmRvd0xvbmdBKGhXbmQsIDAsIDApOwoKICAgIEZyZWVMaWJyYXJ5KGhNb2RXaW5tbSk7CiAgICByZXR1cm4gMDsKfQoKCnN0YXRpYyBMUkVTVUxUIEFOSU1BVEVfRXJhc2VCYWNrZ3JvdW5kKEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgUkVDVCByZWN0OwoKICAgIEdldENsaWVudFJlY3QoaFduZCwgJnJlY3QpOwojaWYgMAogICAgSEJSVVNIIGhCcnVzaCA9IENyZWF0ZVNvbGlkQnJ1c2goaW5mb1B0ci0+Y2xyQmspOwoKICAgIEZpbGxSZWN0KChIREMpd1BhcmFtLCAmcmVjdCwgaEJydXNoKTsKICAgIERlbGV0ZU9iamVjdChoQnJ1c2gpOwojZWxzZQogICAgRmlsbFJlY3QoKEhEQyl3UGFyYW0sICZyZWN0LCBHZXRTeXNDb2xvckJydXNoKENPTE9SX1dJTkRPVykpOwojZW5kaWYKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgTFJFU1VMVCBXSU5BUEkgQU5JTUFURV9TaXplKEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQU5JTUFURV9JTkZPICppbmZvUHRyID0gQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpOwoKICAgIGlmIChHZXRXaW5kb3dMb25nQShoV25kLCBHV0xfU1RZTEUpICYgQUNTX0NFTlRFUikgewoJaWYgKGluZm9QdHItPmhNTWlvKSB7CgkgICAgLyogY2VudGVycyB0aGUgYW5pbWF0aW9uIGluIHRoZSBjb250cm9sLCBpbnZhbGlkYXRlcyB0aGUgY29udHJvbAoJICAgICAqLwoJICAgIEFOSU1BVEVfQ2VudGVyKGluZm9QdHIpOwoJfQoJSW52YWxpZGF0ZVJlY3QoaFduZCwgTlVMTCwgVFJVRSk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIExSRVNVTFQgV0lOQVBJIEFOSU1BVEVfV2luZG93UHJvYyhIV05EIGhXbmQsIFVJTlQgdU1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgVFJBQ0UoImh3bmQ9JXggbXNnPSV4IHdwYXJhbT0leCBscGFyYW09JWx4XG4iLCBoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CiAgICBpZiAoIUFOSU1BVEVfR2V0SW5mb1B0cihoV25kKSAmJiAodU1zZyAhPSBXTV9OQ0NSRUFURSkpCglyZXR1cm4gRGVmV2luZG93UHJvY0EoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgc3dpdGNoICh1TXNnKQogICAgewogICAgY2FzZSBBQ01fT1BFTkE6CglyZXR1cm4gQU5JTUFURV9PcGVuQShoV25kLCB3UGFyYW0sIGxQYXJhbSk7CgkKCS8qCWNhc2UgQUNNX09QRU4zMlc6IEZJWE1FISEgKi8KCS8qCSAgICByZXR1cm4gQU5JTUFURV9PcGVuMzJXKGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsgKi8KCQogICAgY2FzZSBBQ01fUExBWToKCXJldHVybiBBTklNQVRFX1BsYXkoaFduZCwgd1BhcmFtLCBsUGFyYW0pOwoJCiAgICBjYXNlIEFDTV9TVE9QOgoJcmV0dXJuIEFOSU1BVEVfU3RvcChoV25kLCB3UGFyYW0sIGxQYXJhbSk7CgkKICAgIGNhc2UgV01fTkNDUkVBVEU6CglBTklNQVRFX0NyZWF0ZShoV25kLCB3UGFyYW0sIGxQYXJhbSk7CglyZXR1cm4gRGVmV2luZG93UHJvY0EoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJCiAgICBjYXNlIFdNX05DSElUVEVTVDoKCXJldHVybiBIVFRSQU5TUEFSRU5UOwoKICAgIGNhc2UgV01fREVTVFJPWToKCUFOSU1BVEVfRGVzdHJveShoV25kLCB3UGFyYW0sIGxQYXJhbSk7CglyZXR1cm4gRGVmV2luZG93UHJvY0EoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJCiAgICBjYXNlIFdNX0VSQVNFQktHTkQ6CglBTklNQVRFX0VyYXNlQmFja2dyb3VuZChoV25kLCB3UGFyYW0sIGxQYXJhbSk7CglicmVhazsKCiAgICAvKgljYXNlIFdNX1NUWUxFQ0hBTkdFRDogRklYTUUgc2hhbGwgd2UgZG8gc29tZXRoaW5nID8/ICovCgogICAgY2FzZSBXTV9USU1FUjoKCXJldHVybiBBTklNQVRFX0RyYXdGcmFtZShBTklNQVRFX0dldEluZm9QdHIoaFduZCkpOwoJCiAgICBjYXNlIFdNX0NMT1NFOgoJQU5JTUFURV9GcmVlKEFOSU1BVEVfR2V0SW5mb1B0cihoV25kKSk7CglyZXR1cm4gVFJVRTsKCiAgICBjYXNlIFdNX1BBSU5UOgoJaWYgKHdQYXJhbSkgewoJICAgIEFOSU1BVEVfUGFpbnRGcmFtZShBTklNQVRFX0dldEluZm9QdHIoaFduZCksIChIREMpd1BhcmFtKTsKCX0gZWxzZSB7CgkgICAgUEFJTlRTVFJVQ1QgcHM7CiAJICAgIEhEQyBoREMgPSBCZWdpblBhaW50KGhXbmQsICZwcyk7CgkgICAgQU5JTUFURV9QYWludEZyYW1lKEFOSU1BVEVfR2V0SW5mb1B0cihoV25kKSwgaERDKTsKCSAgICBFbmRQYWludChoV25kLCAmcHMpOwoJfQoJYnJlYWs7CgogICAgY2FzZSBXTV9TSVpFOgoJQU5JTUFURV9TaXplKGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsKCXJldHVybiBEZWZXaW5kb3dQcm9jQShoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CgogICAgZGVmYXVsdDoKCWlmICh1TXNnID49IFdNX1VTRVIpCgkgICAgRVJSKCJ1bmtub3duIG1zZyAlMDR4IHdwPSUwOHggbHA9JTA4bHhcbiIsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCQoJcmV0dXJuIERlZldpbmRvd1Byb2NBKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKICAgIH0KICAgIHJldHVybiAwOwp9CgoKdm9pZCBBTklNQVRFX1JlZ2lzdGVyKHZvaWQpCnsKICAgIFdORENMQVNTQSB3bmRDbGFzczsKCiAgICBaZXJvTWVtb3J5KCZ3bmRDbGFzcywgc2l6ZW9mKFdORENMQVNTQSkpOwogICAgd25kQ2xhc3Muc3R5bGUgICAgICAgICA9IENTX0dMT0JBTENMQVNTIHwgQ1NfREJMQ0xLUzsKICAgIHduZENsYXNzLmxwZm5XbmRQcm9jICAgPSAoV05EUFJPQylBTklNQVRFX1dpbmRvd1Byb2M7CiAgICB3bmRDbGFzcy5jYkNsc0V4dHJhICAgID0gMDsKICAgIHduZENsYXNzLmNiV25kRXh0cmEgICAgPSBzaXplb2YoQU5JTUFURV9JTkZPICopOwogICAgd25kQ2xhc3MuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3JBKDAsIElEQ19BUlJPV0EpOwogICAgd25kQ2xhc3MuaGJyQmFja2dyb3VuZCA9IChIQlJVU0gpKENPTE9SX0JUTkZBQ0UgKyAxKTsKICAgIHduZENsYXNzLmxwc3pDbGFzc05hbWUgPSBBTklNQVRFX0NMQVNTQTsKIAogICAgUmVnaXN0ZXJDbGFzc0EoJnduZENsYXNzKTsKfQoKCnZvaWQgQU5JTUFURV9VbnJlZ2lzdGVyKHZvaWQpCnsKICAgIFVucmVnaXN0ZXJDbGFzc0EoQU5JTUFURV9DTEFTU0EsIChISU5TVEFOQ0UpTlVMTCk7Cn0KCg==