LyoKICogV2luZWZpbGUKICoKICogQ29weXJpZ2h0IDIwMDAsIDIwMDMsIDIwMDQsIDIwMDUgTWFydGluIEZ1Y2hzCiAqIENvcHlyaWdodCAyMDA2IEphc29uIEdyZWVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpZmRlZiBfX1dJTkVfXwojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKCi8qIGZvciB1bml4IGZpbGVzeXN0ZW0gZnVuY3Rpb24gY2FsbHMgKi8KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPGRpcmVudC5oPgojZW5kaWYKCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgIndpbmVmaWxlLmgiCiNpbmNsdWRlICJyZXNvdXJjZS5oIgoKI2lmZGVmIF9OT19FWFRFTlNJT05TCiN1bmRlZiBfTEVGVF9GSUxFUwojZW5kaWYKCiNpZm5kZWYgX01BWF9QQVRICiNkZWZpbmUgX01BWF9EUklWRSAgICAgICAgICAzCiNkZWZpbmUgX01BWF9GTkFNRSAgICAgICAgICAyNTYKI2RlZmluZSBfTUFYX0RJUiAgICAgICAgICAgIF9NQVhfRk5BTUUKI2RlZmluZSBfTUFYX0VYVCAgICAgICAgICAgIF9NQVhfRk5BTUUKI2RlZmluZSBfTUFYX1BBVEggICAgICAgICAgIDI2MAojZW5kaWYKCiNpZmRlZiBOT05BTUVMRVNTVU5JT04KI2RlZmluZQlVTklPTl9NRU1CRVIoeCkgRFVNTVlVTklPTk5BTUUueAojZWxzZQojZGVmaW5lCVVOSU9OX01FTUJFUih4KSB4CiNlbmRpZgoKCiNpZmRlZiBfU0hFTExfRk9MREVSUwojZGVmaW5lCURFRkFVTFRfU1BMSVRfUE9TCTMwMAojZWxzZQojZGVmaW5lCURFRkFVTFRfU1BMSVRfUE9TCTIwMAojZW5kaWYKCnN0YXRpYyBjb25zdCBXQ0hBUiByZWdpc3RyeV9rZXlbXSA9IHsgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnRicsJ2knLCdsJywnZScsJ1wwJ307CnN0YXRpYyBjb25zdCBXQ0hBUiByZWdfc3RhcnRfeFtdID0geyAncycsJ3QnLCdhJywncicsJ3QnLCdYJywnXDAnfTsKc3RhdGljIGNvbnN0IFdDSEFSIHJlZ19zdGFydF95W10gPSB7ICdzJywndCcsJ2EnLCdyJywndCcsJ1knLCdcMCd9OwpzdGF0aWMgY29uc3QgV0NIQVIgcmVnX3dpZHRoW10gPSB7ICd3JywnaScsJ2QnLCd0JywnaCcsJ1wwJ307CnN0YXRpYyBjb25zdCBXQ0hBUiByZWdfaGVpZ2h0W10gPSB7ICdoJywnZScsJ2knLCdnJywnaCcsJ3QnLCdcMCd9OwoKZW51bSBFTlRSWV9UWVBFIHsKCUVUX1dJTkRPV1MsCglFVF9VTklYLAojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCUVUX1NIRUxMCiNlbmRpZgp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0VudHJ5IHsKCXN0cnVjdCBfRW50cnkqCW5leHQ7CglzdHJ1Y3QgX0VudHJ5Kglkb3duOwoJc3RydWN0IF9FbnRyeSoJdXA7CgoJQk9PTAkJCWV4cGFuZGVkOwoJQk9PTAkJCXNjYW5uZWQ7CglpbnQJCQkJbGV2ZWw7CgoJV0lOMzJfRklORF9EQVRBCWRhdGE7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBiaGZpOwoJQk9PTAkJCWJoZmlfdmFsaWQ7CgllbnVtIEVOVFJZX1RZUEUJZXR5cGU7CiNlbmRpZgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCUxQSVRFTUlETElTVAlwaWRsOwoJSVNoZWxsRm9sZGVyKglmb2xkZXI7CglISUNPTgkJCWhpY29uOwojZW5kaWYKfSBFbnRyeTsKCnR5cGVkZWYgc3RydWN0IHsKCUVudHJ5CWVudHJ5OwoJVENIQVIJcGF0aFtNQVhfUEFUSF07CglUQ0hBUgl2b2xuYW1lW19NQVhfRk5BTUVdOwoJVENIQVIJZnNbX01BWF9ESVJdOwoJRFdPUkQJZHJpdmVfdHlwZTsKCURXT1JECWZzX2ZsYWdzOwp9IFJvb3Q7CgplbnVtIENPTFVNTl9GTEFHUyB7CglDT0xfU0laRQkJPSAweDAxLAoJQ09MX0RBVEUJCT0gMHgwMiwKCUNPTF9USU1FCQk9IDB4MDQsCglDT0xfQVRUUklCVVRFUwk9IDB4MDgsCglDT0xfRE9TTkFNRVMJPSAweDEwLAojaWZkZWYgX05PX0VYVEVOU0lPTlMKCUNPTF9BTEwgPSBDT0xfU0laRXxDT0xfREFURXxDT0xfVElNRXxDT0xfQVRUUklCVVRFU3xDT0xfRE9TTkFNRVMKI2Vsc2UKCUNPTF9JTkRFWAkJPSAweDIwLAoJQ09MX0xJTktTCQk9IDB4NDAsCglDT0xfQUxMID0gQ09MX1NJWkV8Q09MX0RBVEV8Q09MX1RJTUV8Q09MX0FUVFJJQlVURVN8Q09MX0RPU05BTUVTfENPTF9JTkRFWHxDT0xfTElOS1MKI2VuZGlmCn07Cgp0eXBlZGVmIGVudW0gewoJU09SVF9OQU1FLAoJU09SVF9FWFQsCglTT1JUX1NJWkUsCglTT1JUX0RBVEUKfSBTT1JUX09SREVSOwoKdHlwZWRlZiBzdHJ1Y3QgewoJSFdORAlod25kOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglIV05ECWh3bmRIZWFkZXI7CiNlbmRpZgoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwojZGVmaW5lCUNPTFVNTlMJMTAKI2Vsc2UKI2RlZmluZQlDT0xVTU5TCTUKI2VuZGlmCglpbnQJCXdpZHRoc1tDT0xVTU5TXTsKCWludAkJcG9zaXRpb25zW0NPTFVNTlMrMV07CgoJQk9PTAl0cmVlUGFuZTsKCWludAkJdmlzaWJsZV9jb2xzOwoJRW50cnkqCXJvb3Q7CglFbnRyeSoJY3VyOwp9IFBhbmU7Cgp0eXBlZGVmIHN0cnVjdCB7CglIV05ECWh3bmQ7CglQYW5lCWxlZnQ7CglQYW5lCXJpZ2h0OwoJaW50CQlmb2N1c19wYW5lOwkJLyogMDogbGVmdCAgMTogcmlnaHQgKi8KCVdJTkRPV1BMQUNFTUVOVCBwb3M7CglpbnQJCXNwbGl0X3BvczsKCUJPT0wJaGVhZGVyX3dkdGhzX29rOwoKCVRDSEFSCXBhdGhbTUFYX1BBVEhdOwoJVENIQVIJZmlsdGVyX3BhdHRlcm5bTUFYX1BBVEhdOwoJaW50CQlmaWx0ZXJfZmxhZ3M7CglSb290CXJvb3Q7CgoJU09SVF9PUkRFUiBzb3J0T3JkZXI7Cn0gQ2hpbGRXbmQ7CgoKCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5KEVudHJ5KiBkaXIsIExQQ1RTVFIgcGF0aCwgU09SVF9PUkRFUiBzb3J0T3JkZXIsIEhXTkQgaHduZCk7CnN0YXRpYyB2b2lkIHNldF9jdXJkaXIoQ2hpbGRXbmQqIGNoaWxkLCBFbnRyeSogZW50cnksIGludCBpZHgsIEhXTkQgaHduZCk7CnN0YXRpYyB2b2lkIHJlZnJlc2hfY2hpbGQoQ2hpbGRXbmQqIGNoaWxkKTsKc3RhdGljIHZvaWQgcmVmcmVzaF9kcml2ZXModm9pZCk7CnN0YXRpYyB2b2lkIGdldF9wYXRoKEVudHJ5KiBkaXIsIFBUU1RSIHBhdGgpOwpzdGF0aWMgdm9pZCBmb3JtYXRfZGF0ZShjb25zdCBGSUxFVElNRSogZnQsIFRDSEFSKiBidWZmZXIsIGludCB2aXNpYmxlX2NvbHMpOwoKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgRnJhbWVXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKTsKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgQ2hpbGRXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKTsKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgVHJlZVduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pOwoKCi8qIGdsb2JhbHMgKi8KV0lORUZJTEVfR0xPQkFMUyBHbG9iYWxzOwoKc3RhdGljIGludCBsYXN0X3NwbGl0OwoKLyogc29tZSBjb21tb24gc3RyaW5nIGNvbnN0YW50cyAqLwpzdGF0aWMgY29uc3QgVENIQVIgc0VtcHR5W10gPSB7J1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzU3BhY2VbXSA9IHsnICcsICdcMCd9OwpzdGF0aWMgY29uc3QgVENIQVIgc051bUZtdFtdID0geyclJywnZCcsJ1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzUU1hcmtzW10gPSB7Jz8nLCc/JywnPycsJ1wwJ307CgovKiB3aW5kb3cgY2xhc3MgbmFtZXMgKi8Kc3RhdGljIGNvbnN0IFRDSEFSIHNXSU5FRklMRUZSQU1FW10gPSB7J1cnLCdGJywnUycsJ18nLCdGJywncicsJ2EnLCdtJywnZScsJ1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzV0lORUZJTEVUUkVFW10gPSB7J1cnLCdGJywnUycsJ18nLCdUJywncicsJ2UnLCdlJywnXDAnfTsKCiNpZmRlZiBfTVNDX1ZFUgovKiAjZGVmaW5lIExPTkdMT05HQVJHIF9UKCJJNjQiKSAqLwpzdGF0aWMgY29uc3QgVENIQVIgc0xvbmdIZXhGbXRbXSA9IHsnJScsJ0knLCc2JywnNCcsJ1gnLCdcMCd9OwpzdGF0aWMgY29uc3QgVENIQVIgc0xvbmdOdW1GbXRbXSA9IHsnJScsJ0knLCc2JywnNCcsJ2QnLCdcMCd9OwojZWxzZQovKiAjZGVmaW5lIExPTkdMT05HQVJHIF9UKCJMIikgKi8Kc3RhdGljIGNvbnN0IFRDSEFSIHNMb25nSGV4Rm10W10gPSB7JyUnLCdMJywnWCcsJ1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzTG9uZ051bUZtdFtdID0geyclJywnTCcsJ2QnLCdcMCd9OwojZW5kaWYKCgovKiBsb2FkIHJlc291cmNlIHN0cmluZyAqLwpzdGF0aWMgTFBUU1RSIGxvYWRfc3RyaW5nKExQVFNUUiBidWZmZXIsIFVJTlQgaWQpCnsKCUxvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIGlkLCBidWZmZXIsIEJVRkZFUl9MRU4pOwoKCXJldHVybiBidWZmZXI7Cn0KCiNkZWZpbmUgUlMoYiwgaSkgbG9hZF9zdHJpbmcoYiwgaSkKCgovKiBkaXNwbGF5IGVycm9yIG1lc3NhZ2UgZm9yIHRoZSBzcGVjaWZpZWQgV0lOMzIgZXJyb3IgY29kZSAqLwpzdGF0aWMgdm9pZCBkaXNwbGF5X2Vycm9yKEhXTkQgaHduZCwgRFdPUkQgZXJyb3IpCnsKCVRDSEFSIGIxW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCVBUU1RSIG1zZzsKCglpZiAoRm9ybWF0TWVzc2FnZShGT1JNQVRfTUVTU0FHRV9BTExPQ0FURV9CVUZGRVJ8Rk9STUFUX01FU1NBR0VfRlJPTV9TWVNURU0sCgkJMCwgZXJyb3IsIE1BS0VMQU5HSUQoTEFOR19ORVVUUkFMLFNVQkxBTkdfREVGQVVMVCksIChQVFNUUikmbXNnLCAwLCBOVUxMKSkKCQlNZXNzYWdlQm94KGh3bmQsIG1zZywgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwoJZWxzZQoJCU1lc3NhZ2VCb3goaHduZCwgUlMoYjEsSURTX0VSUk9SKSwgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwoKCUxvY2FsRnJlZShtc2cpOwp9CgoKLyogZGlzcGxheSBuZXR3b3JrIGVycm9yIG1lc3NhZ2UgdXNpbmcgV05ldEdldExhc3RFcnJvcigpICovCnN0YXRpYyB2b2lkIGRpc3BsYXlfbmV0d29ya19lcnJvcihIV05EIGh3bmQpCnsKCVRDSEFSIG1zZ1tCVUZGRVJfTEVOXSwgcHJvdmlkZXJbQlVGRkVSX0xFTl0sIGIyW0JVRkZFUl9MRU5dOwoJRFdPUkQgZXJyb3I7CgoJaWYgKFdOZXRHZXRMYXN0RXJyb3IoJmVycm9yLCBtc2csIEJVRkZFUl9MRU4sIHByb3ZpZGVyLCBCVUZGRVJfTEVOKSA9PSBOT19FUlJPUikKCQlNZXNzYWdlQm94KGh3bmQsIG1zZywgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwp9CgpzdGF0aWMgVk9JRCBXaW5lTGljZW5zZShIV05EIFduZCkKewoJVENIQVIgY2FwWzIwXSwgdGV4dFsxMDI0XTsKCUxvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19MSUNFTlNFLCB0ZXh0LCAxMDI0KTsKCUxvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19MSUNFTlNFX0NBUFRJT04sIGNhcCwgMjApOwoJTWVzc2FnZUJveChXbmQsIHRleHQsIGNhcCwgTUJfSUNPTklORk9STUFUSU9OIHwgTUJfT0spOwp9CgpzdGF0aWMgVk9JRCBXaW5lV2FycmFudHkoSFdORCBXbmQpCnsKCVRDSEFSIGNhcFsyMF0sIHRleHRbMTAyNF07CglMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfV0FSUkFOVFksIHRleHQsIDEwMjQpOwoJTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX1dBUlJBTlRZX0NBUFRJT04sIGNhcCwgMjApOwoJTWVzc2FnZUJveChXbmQsIHRleHQsIGNhcCwgTUJfSUNPTkVYQ0xBTUFUSU9OIHwgTUJfT0spOwp9CgpzdGF0aWMgaW5saW5lIEJPT0wgZ2V0X2NoZWNrKEhXTkQgaHduZCwgSU5UIGlkKQp7CglyZXR1cm4gQlNUX0NIRUNLRUQmU2VuZE1lc3NhZ2UoR2V0RGxnSXRlbShod25kLCBpZCksIEJNX0dFVFNUQVRFLCAwLCAwKTsKfQoKc3RhdGljIGlubGluZSBJTlQgc2V0X2NoZWNrKEhXTkQgaHduZCwgSU5UIGlkLCBCT09MIG9uKQp7CglyZXR1cm4gU2VuZE1lc3NhZ2UoR2V0RGxnSXRlbShod25kLCBpZCksIEJNX1NFVENIRUNLLCBvbj9CU1RfQ0hFQ0tFRDpCU1RfVU5DSEVDS0VELCAwKTsKfQoKI2lmZGVmIF9fV0lORV9fCgojaWZkZWYgVU5JQ09ERQoKLyogY2FsbCB2c3dwcmludGYoKSBpbiBtc3ZjcnQuZGxsICovCi8qVE9ETzogZml4IHN3cHJpbnRmKCkgaW4gbm9uLW1zdmNydCBtb2RlLCBzbyB0aGF0IHRoaXMgZHluYW1pYyBsaW5raW5nIGZ1bmN0aW9uIGNhbiBiZSByZW1vdmVkICovCnN0YXRpYyBpbnQgbXN2Y3J0X3N3cHJpbnRmKFdDSEFSKiBidWZmZXIsIGNvbnN0IFdDSEFSKiBmbXQsIC4uLikKewoJc3RhdGljIGludCAoX19jZGVjbCAqcHZzd3ByaW50ZikoV0NIQVIqLCBjb25zdCBXQ0hBUiosIHZhX2xpc3QpID0gTlVMTDsKCXZhX2xpc3QgYXA7CglpbnQgcmV0OwoKCWlmICghcHZzd3ByaW50ZikgewoJCUhNT0RVTEUgaE1vZE1zdmNydCA9IExvYWRMaWJyYXJ5QSgibXN2Y3J0Iik7CgkJcHZzd3ByaW50ZiA9IChpbnQoX19jZGVjbCopKFdDSEFSKixjb25zdCBXQ0hBUiosdmFfbGlzdCkpIEdldFByb2NBZGRyZXNzKGhNb2RNc3ZjcnQsICJ2c3dwcmludGYiKTsKCX0KCgl2YV9zdGFydChhcCwgZm10KTsKCXJldCA9ICgqcHZzd3ByaW50ZikoYnVmZmVyLCBmbXQsIGFwKTsKCXZhX2VuZChhcCk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIExQQ1dTVFIgbXlfd2NzcmNocihMUENXU1RSIHN0ciwgV0NIQVIgYykKewoJTFBDV1NUUiBwID0gc3RyOwoKCXdoaWxlKCpwKQoJCSsrcDsKCglkbyB7CgkJaWYgKC0tcCA8IHN0cikKCQkJcmV0dXJuIE5VTEw7Cgl9IHdoaWxlKCpwICE9IGMpOwoKCXJldHVybiBwOwp9CgojZGVmaW5lIF90Y3NyY2hyIG15X3djc3JjaHIKI2Vsc2UJLyogVU5JQ09ERSAqLwojZGVmaW5lIF90Y3NyY2hyIHN0cnJjaHIKI2VuZGlmCS8qIFVOSUNPREUgKi8KCiNlbmRpZgkvKiBfX1dJTkVfXyAqLwoKCi8qIGFsbG9jYXRlIGFuZCBpbml0aWFsaXNlIGEgZGlyZWN0b3J5IGVudHJ5ICovCnN0YXRpYyBFbnRyeSogYWxsb2NfZW50cnkodm9pZCkKewoJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgbWFsbG9jKHNpemVvZihFbnRyeSkpOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgllbnRyeS0+cGlkbCA9IE5VTEw7CgllbnRyeS0+Zm9sZGVyID0gTlVMTDsKCWVudHJ5LT5oaWNvbiA9IDA7CiNlbmRpZgoKCXJldHVybiBlbnRyeTsKfQoKLyogZnJlZSBhIGRpcmVjdG9yeSBlbnRyeSAqLwpzdGF0aWMgdm9pZCBmcmVlX2VudHJ5KEVudHJ5KiBlbnRyeSkKewojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChlbnRyeS0+aGljb24gJiYgZW50cnktPmhpY29uIT0oSElDT04pLTEpCgkJRGVzdHJveUljb24oZW50cnktPmhpY29uKTsKCglpZiAoZW50cnktPmZvbGRlciAmJiBlbnRyeS0+Zm9sZGVyIT1HbG9iYWxzLmlEZXNrdG9wKQoJCUlTaGVsbEZvbGRlcl9SZWxlYXNlKGVudHJ5LT5mb2xkZXIpOwoKCWlmIChlbnRyeS0+cGlkbCkKCQlJTWFsbG9jX0ZyZWUoR2xvYmFscy5pTWFsbG9jLCBlbnRyeS0+cGlkbCk7CiNlbmRpZgoKCWZyZWUoZW50cnkpOwp9CgovKiByZWN1cnNpdmVseSBmcmVlIGFsbCBjaGlsZCBlbnRyaWVzICovCnN0YXRpYyB2b2lkIGZyZWVfZW50cmllcyhFbnRyeSogZGlyKQp7CglFbnRyeSAqZW50cnksICpuZXh0PWRpci0+ZG93bjsKCglpZiAobmV4dCkgewoJCWRpci0+ZG93biA9IDA7CgoJCWRvIHsKCQkJZW50cnkgPSBuZXh0OwoJCQluZXh0ID0gZW50cnktPm5leHQ7CgoJCQlmcmVlX2VudHJpZXMoZW50cnkpOwoJCQlmcmVlX2VudHJ5KGVudHJ5KTsKCQl9IHdoaWxlKG5leHQpOwoJfQp9CgoKc3RhdGljIHZvaWQgcmVhZF9kaXJlY3Rvcnlfd2luKEVudHJ5KiBkaXIsIExQQ1RTVFIgcGF0aCkKewoJRW50cnkqIGZpcnN0X2VudHJ5ID0gTlVMTDsKCUVudHJ5KiBsYXN0ID0gTlVMTDsKCUVudHJ5KiBlbnRyeTsKCglpbnQgbGV2ZWwgPSBkaXItPmxldmVsICsgMTsKCVdJTjMyX0ZJTkRfREFUQSB3MzJmZDsKCUhBTkRMRSBoRmluZDsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJSEFORExFIGhGaWxlOwojZW5kaWYKCglUQ0hBUiBidWZmZXJbTUFYX1BBVEhdLCAqcDsKCWZvcihwPWJ1ZmZlcjsgKnBhdGg7ICkKCQkqcCsrID0gKnBhdGgrKzsKCgkqcCsrID0gJ1xcJzsKCXBbMF0gPSAnKic7CglwWzFdID0gJ1wwJzsKCgloRmluZCA9IEZpbmRGaXJzdEZpbGUoYnVmZmVyLCAmdzMyZmQpOwoKCWlmIChoRmluZCAhPSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgewoJCWRvIHsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCS8qIGhpZGUgZGlyZWN0b3J5IGVudHJ5ICIuIiAqLwoJCQlpZiAodzMyZmQuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJTFBDVFNUUiBuYW1lID0gdzMyZmQuY0ZpbGVOYW1lOwoKCQkJCWlmIChuYW1lWzBdPT0nLicgJiYgbmFtZVsxXT09J1wwJykKCQkJCQljb250aW51ZTsKCQkJfQojZW5kaWYKCQkJZW50cnkgPSBhbGxvY19lbnRyeSgpOwoKCQkJaWYgKCFmaXJzdF9lbnRyeSkKCQkJCWZpcnN0X2VudHJ5ID0gZW50cnk7CgoJCQlpZiAobGFzdCkKCQkJCWxhc3QtPm5leHQgPSBlbnRyeTsKCgkJCW1lbWNweSgmZW50cnktPmRhdGEsICZ3MzJmZCwgc2l6ZW9mKFdJTjMyX0ZJTkRfREFUQSkpOwoJCQllbnRyeS0+ZG93biA9IE5VTEw7CgkJCWVudHJ5LT51cCA9IGRpcjsKCQkJZW50cnktPmV4cGFuZGVkID0gRkFMU0U7CgkJCWVudHJ5LT5zY2FubmVkID0gRkFMU0U7CgkJCWVudHJ5LT5sZXZlbCA9IGxldmVsOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQllbnRyeS0+ZXR5cGUgPSBFVF9XSU5ET1dTOwoJCQllbnRyeS0+YmhmaV92YWxpZCA9IEZBTFNFOwoKCQkJbHN0cmNweShwLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpOwoKCQkJaEZpbGUgPSBDcmVhdGVGaWxlKGJ1ZmZlciwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUR8RklMRV9TSEFSRV9XUklURXxGSUxFX1NIQVJFX0RFTEVURSwKCQkJCQkJCQkwLCBPUEVOX0VYSVNUSU5HLCBGSUxFX0ZMQUdfQkFDS1VQX1NFTUFOVElDUywgMCk7CgoJCQlpZiAoaEZpbGUgIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHsKCQkJCWlmIChHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoRmlsZSwgJmVudHJ5LT5iaGZpKSkKCQkJCQllbnRyeS0+YmhmaV92YWxpZCA9IFRSVUU7CgoJCQkJQ2xvc2VIYW5kbGUoaEZpbGUpOwoJCQl9CiNlbmRpZgoKCQkJbGFzdCA9IGVudHJ5OwoJCX0gd2hpbGUoRmluZE5leHRGaWxlKGhGaW5kLCAmdzMyZmQpKTsKCgkJaWYgKGxhc3QpCgkJCWxhc3QtPm5leHQgPSBOVUxMOwoKCQlGaW5kQ2xvc2UoaEZpbmQpOwoJfQoKCWRpci0+ZG93biA9IGZpcnN0X2VudHJ5OwoJZGlyLT5zY2FubmVkID0gVFJVRTsKfQoKCnN0YXRpYyBFbnRyeSogZmluZF9lbnRyeV93aW4oRW50cnkqIGRpciwgTFBDVFNUUiBuYW1lKQp7CglFbnRyeSogZW50cnk7CgoJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KSB7CgkJTFBDVFNUUiBwID0gbmFtZTsKCQlMUENUU1RSIHEgPSBlbnRyeS0+ZGF0YS5jRmlsZU5hbWU7CgoJCWRvIHsKCQkJaWYgKCEqcCB8fCAqcD09VEVYVCgnXFwnKSB8fCAqcD09VEVYVCgnLycpKQoJCQkJcmV0dXJuIGVudHJ5OwoJCX0gd2hpbGUodG9sb3dlcigqcCsrKSA9PSB0b2xvd2VyKCpxKyspKTsKCgkJcCA9IG5hbWU7CgkJcSA9IGVudHJ5LT5kYXRhLmNBbHRlcm5hdGVGaWxlTmFtZTsKCgkJZG8gewoJCQlpZiAoISpwIHx8ICpwPT1URVhUKCdcXCcpIHx8ICpwPT1URVhUKCcvJykpCgkJCQlyZXR1cm4gZW50cnk7CgkJfSB3aGlsZSh0b2xvd2VyKCpwKyspID09IHRvbG93ZXIoKnErKykpOwoJfQoKCXJldHVybiAwOwp9CgoKc3RhdGljIEVudHJ5KiByZWFkX3RyZWVfd2luKFJvb3QqIHJvb3QsIExQQ1RTVFIgcGF0aCwgU09SVF9PUkRFUiBzb3J0T3JkZXIsIEhXTkQgaHduZCkKewoJVENIQVIgYnVmZmVyW01BWF9QQVRIXTsKCUVudHJ5KiBlbnRyeSA9ICZyb290LT5lbnRyeTsKCUxQQ1RTVFIgcyA9IHBhdGg7CglQVFNUUiBkID0gYnVmZmVyOwoKCUhDVVJTT1Igb2xkX2N1cnNvciA9IFNldEN1cnNvcihMb2FkQ3Vyc29yKDAsIElEQ19XQUlUKSk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgllbnRyeS0+ZXR5cGUgPSBFVF9XSU5ET1dTOwojZW5kaWYKCgl3aGlsZShlbnRyeSkgewoJCXdoaWxlKCpzICYmICpzIT1URVhUKCdcXCcpICYmICpzIT1URVhUKCcvJykpCgkJCSpkKysgPSAqcysrOwoKCQl3aGlsZSgqcz09VEVYVCgnXFwnKSB8fCAqcz09VEVYVCgnLycpKQoJCQlzKys7CgoJCSpkKysgPSBURVhUKCdcXCcpOwoJCSpkID0gVEVYVCgnXDAnKTsKCgkJcmVhZF9kaXJlY3RvcnkoZW50cnksIGJ1ZmZlciwgc29ydE9yZGVyLCBod25kKTsKCgkJaWYgKGVudHJ5LT5kb3duKQoJCQllbnRyeS0+ZXhwYW5kZWQgPSBUUlVFOwoKCQlpZiAoISpzKQoJCQlicmVhazsKCgkJZW50cnkgPSBmaW5kX2VudHJ5X3dpbihlbnRyeSwgcyk7Cgl9CgoJU2V0Q3Vyc29yKG9sZF9jdXJzb3IpOwoKCXJldHVybiBlbnRyeTsKfQoKCiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCnN0YXRpYyBCT09MIHRpbWVfdG9fZmlsZXRpbWUoY29uc3QgdGltZV90KiB0LCBGSUxFVElNRSogZnRpbWUpCnsKCXN0cnVjdCB0bSogdG0gPSBnbXRpbWUodCk7CglTWVNURU1USU1FIHN0aW1lOwoKCWlmICghdG0pCgkJcmV0dXJuIEZBTFNFOwoKCXN0aW1lLndZZWFyID0gdG0tPnRtX3llYXIrMTkwMDsKCXN0aW1lLndNb250aCA9IHRtLT50bV9tb24rMTsKCS8qCXN0aW1lLndEYXlPZldlZWsgKi8KCXN0aW1lLndEYXkgPSB0bS0+dG1fbWRheTsKCXN0aW1lLndIb3VyID0gdG0tPnRtX2hvdXI7CglzdGltZS53TWludXRlID0gdG0tPnRtX21pbjsKCXN0aW1lLndTZWNvbmQgPSB0bS0+dG1fc2VjOwoKCXJldHVybiBTeXN0ZW1UaW1lVG9GaWxlVGltZSgmc3RpbWUsIGZ0aW1lKTsKfQoKc3RhdGljIHZvaWQgcmVhZF9kaXJlY3RvcnlfdW5peChFbnRyeSogZGlyLCBMUENUU1RSIHBhdGgpCnsKCUVudHJ5KiBmaXJzdF9lbnRyeSA9IE5VTEw7CglFbnRyeSogbGFzdCA9IE5VTEw7CglFbnRyeSogZW50cnk7CglESVIqIHBkaXI7CgoJaW50IGxldmVsID0gZGlyLT5sZXZlbCArIDE7CiNpZmRlZiBVTklDT0RFCgljaGFyIGNwYXRoW01BWF9QQVRIXTsKCglXaWRlQ2hhclRvTXVsdGlCeXRlKENQX1VOSVhDUCwgMCwgcGF0aCwgLTEsIGNwYXRoLCBNQVhfUEFUSCwgTlVMTCwgTlVMTCk7CiNlbHNlCgljb25zdCBjaGFyKiBjcGF0aCA9IHBhdGg7CiNlbmRpZgoKCXBkaXIgPSBvcGVuZGlyKGNwYXRoKTsKCglpZiAocGRpcikgewoJCXN0cnVjdCBzdGF0IHN0OwoJCXN0cnVjdCBkaXJlbnQqIGVudDsKCQljaGFyIGJ1ZmZlcltNQVhfUEFUSF0sICpwOwoJCWNvbnN0IGNoYXIqIHM7CgoJCWZvcihwPWJ1ZmZlcixzPWNwYXRoOyAqczsgKQoJCQkqcCsrID0gKnMrKzsKCgkJaWYgKHA9PWJ1ZmZlciB8fCBwWy0xXSE9Jy8nKQoJCQkqcCsrID0gJy8nOwoKCQl3aGlsZSgoZW50PXJlYWRkaXIocGRpcikpKSB7CgkJCWVudHJ5ID0gYWxsb2NfZW50cnkoKTsKCgkJCWlmICghZmlyc3RfZW50cnkpCgkJCQlmaXJzdF9lbnRyeSA9IGVudHJ5OwoKCQkJaWYgKGxhc3QpCgkJCQlsYXN0LT5uZXh0ID0gZW50cnk7CgoJCQllbnRyeS0+ZXR5cGUgPSBFVF9VTklYOwoKCQkJc3RyY3B5KHAsIGVudC0+ZF9uYW1lKTsKI2lmZGVmIFVOSUNPREUKCQkJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9VTklYQ1AsIDAsIHAsIC0xLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIE1BWF9QQVRIKTsKI2Vsc2UKCQkJbHN0cmNweShlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIHApOwojZW5kaWYKCgkJCWlmICghc3RhdChidWZmZXIsICZzdCkpIHsKCQkJCWVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgPSBwWzBdPT0nLic/IEZJTEVfQVRUUklCVVRFX0hJRERFTjogMDsKCgkJCQlpZiAoU19JU0RJUihzdC5zdF9tb2RlKSkKCQkJCQllbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzIHw9IEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWTsKCgkJCQllbnRyeS0+ZGF0YS5uRmlsZVNpemVMb3cgPSBzdC5zdF9zaXplICYgMHhGRkZGRkZGRjsKCQkJCWVudHJ5LT5kYXRhLm5GaWxlU2l6ZUhpZ2ggPSBzdC5zdF9zaXplID4+IDMyOwoKCQkJCW1lbXNldCgmZW50cnktPmRhdGEuZnRDcmVhdGlvblRpbWUsIDAsIHNpemVvZihGSUxFVElNRSkpOwoJCQkJdGltZV90b19maWxldGltZSgmc3Quc3RfYXRpbWUsICZlbnRyeS0+ZGF0YS5mdExhc3RBY2Nlc3NUaW1lKTsKCQkJCXRpbWVfdG9fZmlsZXRpbWUoJnN0LnN0X210aW1lLCAmZW50cnktPmRhdGEuZnRMYXN0V3JpdGVUaW1lKTsKCgkJCQllbnRyeS0+YmhmaS5uRmlsZUluZGV4TG93ID0gZW50LT5kX2lubzsKCQkJCWVudHJ5LT5iaGZpLm5GaWxlSW5kZXhIaWdoID0gMDsKCgkJCQllbnRyeS0+YmhmaS5uTnVtYmVyT2ZMaW5rcyA9IHN0LnN0X25saW5rOwoKCQkJCWVudHJ5LT5iaGZpX3ZhbGlkID0gVFJVRTsKCQkJfSBlbHNlIHsKCQkJCWVudHJ5LT5kYXRhLm5GaWxlU2l6ZUxvdyA9IDA7CgkJCQllbnRyeS0+ZGF0YS5uRmlsZVNpemVIaWdoID0gMDsKCQkJCWVudHJ5LT5iaGZpX3ZhbGlkID0gRkFMU0U7CgkJCX0KCgkJCWVudHJ5LT5kb3duID0gTlVMTDsKCQkJZW50cnktPnVwID0gZGlyOwoJCQllbnRyeS0+ZXhwYW5kZWQgPSBGQUxTRTsKCQkJZW50cnktPnNjYW5uZWQgPSBGQUxTRTsKCQkJZW50cnktPmxldmVsID0gbGV2ZWw7CgoJCQlsYXN0ID0gZW50cnk7CgkJfQoKCQlpZiAobGFzdCkKCQkJbGFzdC0+bmV4dCA9IE5VTEw7CgoJCWNsb3NlZGlyKHBkaXIpOwoJfQoKCWRpci0+ZG93biA9IGZpcnN0X2VudHJ5OwoJZGlyLT5zY2FubmVkID0gVFJVRTsKfQoKc3RhdGljIEVudHJ5KiBmaW5kX2VudHJ5X3VuaXgoRW50cnkqIGRpciwgTFBDVFNUUiBuYW1lKQp7CglFbnRyeSogZW50cnk7CgoJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KSB7CgkJTFBDVFNUUiBwID0gbmFtZTsKCQlMUENUU1RSIHEgPSBlbnRyeS0+ZGF0YS5jRmlsZU5hbWU7CgoJCWRvIHsKCQkJaWYgKCEqcCB8fCAqcD09VEVYVCgnLycpKQoJCQkJcmV0dXJuIGVudHJ5OwoJCX0gd2hpbGUoKnArKyA9PSAqcSsrKTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIEVudHJ5KiByZWFkX3RyZWVfdW5peChSb290KiByb290LCBMUENUU1RSIHBhdGgsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF07CglFbnRyeSogZW50cnkgPSAmcm9vdC0+ZW50cnk7CglMUENUU1RSIHMgPSBwYXRoOwoJUFRTVFIgZCA9IGJ1ZmZlcjsKCglIQ1VSU09SIG9sZF9jdXJzb3IgPSBTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfV0FJVCkpOwoKCWVudHJ5LT5ldHlwZSA9IEVUX1VOSVg7CgoJd2hpbGUoZW50cnkpIHsKCQl3aGlsZSgqcyAmJiAqcyE9VEVYVCgnLycpKQoJCQkqZCsrID0gKnMrKzsKCgkJd2hpbGUoKnMgPT0gVEVYVCgnLycpKQoJCQlzKys7CgoJCSpkKysgPSBURVhUKCcvJyk7CgkJKmQgPSBURVhUKCdcMCcpOwoKCQlyZWFkX2RpcmVjdG9yeShlbnRyeSwgYnVmZmVyLCBzb3J0T3JkZXIsIGh3bmQpOwoKCQlpZiAoZW50cnktPmRvd24pCgkJCWVudHJ5LT5leHBhbmRlZCA9IFRSVUU7CgoJCWlmICghKnMpCgkJCWJyZWFrOwoKCQllbnRyeSA9IGZpbmRfZW50cnlfdW5peChlbnRyeSwgcyk7Cgl9CgoJU2V0Q3Vyc29yKG9sZF9jdXJzb3IpOwoKCXJldHVybiBlbnRyeTsKfQoKI2VuZGlmIC8qICFkZWZpbmVkKF9OT19FWFRFTlNJT05TKSAmJiBkZWZpbmVkKF9fV0lORV9fKSAqLwoKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoKI2lmZGVmIFVOSUNPREUKI2RlZmluZQlnZXRfc3RycmV0IGdldF9zdHJyZXRXCiNkZWZpbmUJcGF0aF9mcm9tX3BpZGwgcGF0aF9mcm9tX3BpZGxXCiNlbHNlCiNkZWZpbmUJZ2V0X3N0cnJldCBnZXRfc3RycmV0QQojZGVmaW5lCXBhdGhfZnJvbV9waWRsIHBhdGhfZnJvbV9waWRsQQojZW5kaWYKCgpzdGF0aWMgdm9pZCBmcmVlX3N0cnJldChTVFJSRVQqIHN0cikKewoJaWYgKHN0ci0+dVR5cGUgPT0gU1RSUkVUX1dTVFIpCgkJSU1hbGxvY19GcmVlKEdsb2JhbHMuaU1hbGxvYywgc3RyLT5VTklPTl9NRU1CRVIocE9sZVN0cikpOwp9CgoKI2lmbmRlZiBVTklDT0RFCgpzdGF0aWMgTFBTVFIgc3RyY3B5bihMUFNUUiBkZXN0LCBMUENTVFIgc291cmNlLCBzaXplX3QgY291bnQpCnsKIExQQ1NUUiBzOwogTFBTVFIgZCA9IGRlc3Q7CgogZm9yKHM9c291cmNlOyBjb3VudCYmKCpkKys9KnMrKyk7ICkKICBjb3VudC0tOwoKIHJldHVybiBkZXN0Owp9CgpzdGF0aWMgdm9pZCBnZXRfc3RycmV0QShTVFJSRVQqIHN0ciwgY29uc3QgU0hJVEVNSUQqIHNoaWlkLCBMUFNUUiBidWZmZXIsIGludCBsZW4pCnsKIHN3aXRjaChzdHItPnVUeXBlKSB7CiAgY2FzZSBTVFJSRVRfV1NUUjoKCVdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBzdHItPlVOSU9OX01FTUJFUihwT2xlU3RyKSwgLTEsIGJ1ZmZlciwgbGVuLCBOVUxMLCBOVUxMKTsKCWJyZWFrOwoKICBjYXNlIFNUUlJFVF9PRkZTRVQ6CglzdHJjcHluKGJ1ZmZlciwgKExQQ1NUUilzaGlpZCtzdHItPlVOSU9OX01FTUJFUih1T2Zmc2V0KSwgbGVuKTsKCWJyZWFrOwoKICBjYXNlIFNUUlJFVF9DU1RSOgoJc3RyY3B5bihidWZmZXIsIHN0ci0+VU5JT05fTUVNQkVSKGNTdHIpLCBsZW4pOwogfQp9CgpzdGF0aWMgSFJFU1VMVCBwYXRoX2Zyb21fcGlkbEEoSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQSVRFTUlETElTVCBwaWRsLCBMUFNUUiBidWZmZXIsIGludCBsZW4pCnsKCVNUUlJFVCBzdHI7CgoJIC8qIFNIR0ROX0ZPUlBBUlNJTkc6IGdldCBmdWxsIHBhdGggb2YgaWQgbGlzdCAqLwoJSFJFU1VMVCBociA9IElTaGVsbEZvbGRlcl9HZXREaXNwbGF5TmFtZU9mKGZvbGRlciwgcGlkbCwgU0hHRE5fRk9SUEFSU0lORywgJnN0cik7CgoJaWYgKFNVQ0NFRURFRChocikpIHsKCQlnZXRfc3RycmV0QSgmc3RyLCAmcGlkbC0+bWtpZCwgYnVmZmVyLCBsZW4pOwoJCWZyZWVfc3RycmV0KCZzdHIpOwoJfSBlbHNlCgkJYnVmZmVyWzBdID0gJ1wwJzsKCglyZXR1cm4gaHI7Cn0KCiNlbmRpZgoKc3RhdGljIExQV1NUUiB3Y3NjcHluKExQV1NUUiBkZXN0LCBMUENXU1RSIHNvdXJjZSwgc2l6ZV90IGNvdW50KQp7CiBMUENXU1RSIHM7CiBMUFdTVFIgZCA9IGRlc3Q7CgogZm9yKHM9c291cmNlOyBjb3VudCYmKCpkKys9KnMrKyk7ICkKICBjb3VudC0tOwoKIHJldHVybiBkZXN0Owp9CgpzdGF0aWMgdm9pZCBnZXRfc3RycmV0VyhTVFJSRVQqIHN0ciwgY29uc3QgU0hJVEVNSUQqIHNoaWlkLCBMUFdTVFIgYnVmZmVyLCBpbnQgbGVuKQp7CiBzd2l0Y2goc3RyLT51VHlwZSkgewogIGNhc2UgU1RSUkVUX1dTVFI6Cgl3Y3NjcHluKGJ1ZmZlciwgc3RyLT5VTklPTl9NRU1CRVIocE9sZVN0ciksIGxlbik7CglicmVhazsKCiAgY2FzZSBTVFJSRVRfT0ZGU0VUOgoJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIChMUENTVFIpc2hpaWQrc3RyLT5VTklPTl9NRU1CRVIodU9mZnNldCksIC0xLCBidWZmZXIsIGxlbik7CglicmVhazsKCiAgY2FzZSBTVFJSRVRfQ1NUUjoKCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzdHItPlVOSU9OX01FTUJFUihjU3RyKSwgLTEsIGJ1ZmZlciwgbGVuKTsKIH0KfQoKCnN0YXRpYyBIUkVTVUxUIG5hbWVfZnJvbV9waWRsKElTaGVsbEZvbGRlciogZm9sZGVyLCBMUElURU1JRExJU1QgcGlkbCwgTFBUU1RSIGJ1ZmZlciwgaW50IGxlbiwgU0hHRE5GIGZsYWdzKQp7CglTVFJSRVQgc3RyOwoKCUhSRVNVTFQgaHIgPSBJU2hlbGxGb2xkZXJfR2V0RGlzcGxheU5hbWVPZihmb2xkZXIsIHBpZGwsIGZsYWdzLCAmc3RyKTsKCglpZiAoU1VDQ0VFREVEKGhyKSkgewoJCWdldF9zdHJyZXQoJnN0ciwgJnBpZGwtPm1raWQsIGJ1ZmZlciwgbGVuKTsKCQlmcmVlX3N0cnJldCgmc3RyKTsKCX0gZWxzZQoJCWJ1ZmZlclswXSA9ICdcMCc7CgoJcmV0dXJuIGhyOwp9CgoKc3RhdGljIEhSRVNVTFQgcGF0aF9mcm9tX3BpZGxXKElTaGVsbEZvbGRlciogZm9sZGVyLCBMUElURU1JRExJU1QgcGlkbCwgTFBXU1RSIGJ1ZmZlciwgaW50IGxlbikKewoJU1RSUkVUIHN0cjsKCgkgLyogU0hHRE5fRk9SUEFSU0lORzogZ2V0IGZ1bGwgcGF0aCBvZiBpZCBsaXN0ICovCglIUkVTVUxUIGhyID0gSVNoZWxsRm9sZGVyX0dldERpc3BsYXlOYW1lT2YoZm9sZGVyLCBwaWRsLCBTSEdETl9GT1JQQVJTSU5HLCAmc3RyKTsKCglpZiAoU1VDQ0VFREVEKGhyKSkgewoJCWdldF9zdHJyZXRXKCZzdHIsICZwaWRsLT5ta2lkLCBidWZmZXIsIGxlbik7CgkJZnJlZV9zdHJyZXQoJnN0cik7Cgl9IGVsc2UKCQlidWZmZXJbMF0gPSAnXDAnOwoKCXJldHVybiBocjsKfQoKCiAvKiBjcmVhdGUgYW4gaXRlbSBpZCBsaXN0IGZyb20gYSBmaWxlIHN5c3RlbSBwYXRoICovCgpzdGF0aWMgTFBJVEVNSURMSVNUIGdldF9wYXRoX3BpZGwoTFBUU1RSIHBhdGgsIEhXTkQgaHduZCkKewoJTFBJVEVNSURMSVNUIHBpZGw7CglIUkVTVUxUIGhyOwoJVUxPTkcgbGVuOwoKI2lmZGVmIFVOSUNPREUKCUxQV1NUUiBidWZmZXIgPSBwYXRoOwojZWxzZQoJV0NIQVIgYnVmZmVyW01BWF9QQVRIXTsKCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBwYXRoLCAtMSwgYnVmZmVyLCBNQVhfUEFUSCk7CiNlbmRpZgoKCWhyID0gSVNoZWxsRm9sZGVyX1BhcnNlRGlzcGxheU5hbWUoR2xvYmFscy5pRGVza3RvcCwgaHduZCwgTlVMTCwgYnVmZmVyLCAmbGVuLCAmcGlkbCwgTlVMTCk7CglpZiAoRkFJTEVEKGhyKSkKCQlyZXR1cm4gTlVMTDsKCglyZXR1cm4gcGlkbDsKfQoKCiAvKiBjb252ZXJ0IGFuIGl0ZW0gaWQgbGlzdCBmcm9tIHJlbGF0aXZlIHRvIGFic29sdXRlICg9cmVsYXRpdmUgdG8gdGhlIGRlc2t0b3ApIGZvcm1hdCAqLwoKc3RhdGljIExQSVRFTUlETElTVCBnZXRfdG9fYWJzb2x1dGVfcGlkbChFbnRyeSogZW50cnksIEhXTkQgaHduZCkKewoJaWYgKGVudHJ5LT51cCAmJiBlbnRyeS0+dXAtPmV0eXBlPT1FVF9TSEVMTCkgewoJCUlTaGVsbEZvbGRlciogZm9sZGVyID0gZW50cnktPnVwLT5mb2xkZXI7CgkJV0NIQVIgYnVmZmVyW01BWF9QQVRIXTsKCgkJSFJFU1VMVCBociA9IHBhdGhfZnJvbV9waWRsVyhmb2xkZXIsIGVudHJ5LT5waWRsLCBidWZmZXIsIE1BWF9QQVRIKTsKCgkJaWYgKFNVQ0NFRURFRChocikpIHsKCQkJTFBJVEVNSURMSVNUIHBpZGw7CgkJCVVMT05HIGxlbjsKCgkJCWhyID0gSVNoZWxsRm9sZGVyX1BhcnNlRGlzcGxheU5hbWUoR2xvYmFscy5pRGVza3RvcCwgaHduZCwgTlVMTCwgYnVmZmVyLCAmbGVuLCAmcGlkbCwgTlVMTCk7CgoJCQlpZiAoU1VDQ0VFREVEKGhyKSkKCQkJCXJldHVybiBwaWRsOwoJCX0KCX0gZWxzZSBpZiAoZW50cnktPmV0eXBlID09IEVUX1dJTkRPV1MpIHsKCQlUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCgkJZ2V0X3BhdGgoZW50cnksIHBhdGgpOwoKCQlyZXR1cm4gZ2V0X3BhdGhfcGlkbChwYXRoLCBod25kKTsKCX0gZWxzZSBpZiAoZW50cnktPnBpZGwpCgkJcmV0dXJuIElMQ2xvbmUoZW50cnktPnBpZGwpOwoKCXJldHVybiBOVUxMOwp9CgoKc3RhdGljIEhJQ09OIGV4dHJhY3RfaWNvbihJU2hlbGxGb2xkZXIqIGZvbGRlciwgTFBDSVRFTUlETElTVCBwaWRsKQp7CglJRXh0cmFjdEljb24qIHBFeHRyYWN0OwoKCWlmIChTVUNDRUVERUQoSVNoZWxsRm9sZGVyX0dldFVJT2JqZWN0T2YoZm9sZGVyLCAwLCAxLCAoTFBDSVRFTUlETElTVCopJnBpZGwsICZJSURfSUV4dHJhY3RJY29uLCAwLCAoTFBWT0lEKikmcEV4dHJhY3QpKSkgewoJCVRDSEFSIHBhdGhbX01BWF9QQVRIXTsKCQl1bnNpZ25lZCBmbGFnczsKCQlISUNPTiBoaWNvbjsKCQlpbnQgaWR4OwoKCQlpZiAoU1VDQ0VFREVEKElFeHRyYWN0SWNvbldfR2V0SWNvbkxvY2F0aW9uKHBFeHRyYWN0LCBHSUxfRk9SU0hFTEwsIHBhdGgsIF9NQVhfUEFUSCwgJmlkeCwgJmZsYWdzKSkpIHsKCQkJaWYgKCEoZmxhZ3MgJiBHSUxfTk9URklMRU5BTUUpKSB7CgkJCQlpZiAoaWR4ID09IC0xKQoJCQkJCWlkeCA9IDA7CS8qIHNwZWNpYWwgY2FzZSBmb3Igc29tZSBjb250cm9sIHBhbmVsIGFwcGxpY2F0aW9ucyAqLwoKCQkJCWlmICgoaW50KUV4dHJhY3RJY29uRXgocGF0aCwgaWR4LCAwLCAmaGljb24sIDEpID4gMCkKCQkJCQlmbGFncyAmPSB+R0lMX0RPTlRDQUNIRTsKCQkJfSBlbHNlIHsKCQkJCUhJQ09OIGhJY29uTGFyZ2UgPSAwOwoKCQkJCUhSRVNVTFQgaHIgPSBJRXh0cmFjdEljb25XX0V4dHJhY3QocEV4dHJhY3QsIHBhdGgsIGlkeCwgJmhJY29uTGFyZ2UsICZoaWNvbiwgTUFLRUxPTkcoMC8qR2V0U3lzdGVtTWV0cmljcyhTTV9DWElDT04pKi8sR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNNSUNPTikpKTsKCgkJCQlpZiAoU1VDQ0VFREVEKGhyKSkKCQkJCQlEZXN0cm95SWNvbihoSWNvbkxhcmdlKTsKCQkJfQoKCQkJcmV0dXJuIGhpY29uOwoJCX0KCX0KCglyZXR1cm4gMDsKfQoKCnN0YXRpYyBFbnRyeSogZmluZF9lbnRyeV9zaGVsbChFbnRyeSogZGlyLCBMUENJVEVNSURMSVNUIHBpZGwpCnsKCUVudHJ5KiBlbnRyeTsKCglmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpIHsKCQlpZiAoZW50cnktPnBpZGwtPm1raWQuY2IgPT0gcGlkbC0+bWtpZC5jYiAmJgoJCQkhbWVtY21wKGVudHJ5LT5waWRsLCBwaWRsLCBlbnRyeS0+cGlkbC0+bWtpZC5jYikpCgkJCXJldHVybiBlbnRyeTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIEVudHJ5KiByZWFkX3RyZWVfc2hlbGwoUm9vdCogcm9vdCwgTFBJVEVNSURMSVNUIHBpZGwsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCUVudHJ5KiBlbnRyeSA9ICZyb290LT5lbnRyeTsKCUVudHJ5KiBuZXh0OwoJTFBJVEVNSURMSVNUIG5leHRfcGlkbCA9IHBpZGw7CglJU2hlbGxGb2xkZXIqIGZvbGRlcjsKCUlTaGVsbEZvbGRlciogY2hpbGQgPSBOVUxMOwoJSFJFU1VMVCBocjsKCglIQ1VSU09SIG9sZF9jdXJzb3IgPSBTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfV0FJVCkpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJZW50cnktPmV0eXBlID0gRVRfU0hFTEw7CiNlbmRpZgoKCWZvbGRlciA9IEdsb2JhbHMuaURlc2t0b3A7CgoJd2hpbGUoZW50cnkpIHsKCQllbnRyeS0+cGlkbCA9IG5leHRfcGlkbDsKCQllbnRyeS0+Zm9sZGVyID0gZm9sZGVyOwoKCQlpZiAoIXBpZGwtPm1raWQuY2IpCgkJCWJyZWFrOwoKCQkgLyogY29weSBmaXJzdCBlbGVtZW50IG9mIGl0ZW0gaWRsaXN0ICovCgkJbmV4dF9waWRsID0gSU1hbGxvY19BbGxvYyhHbG9iYWxzLmlNYWxsb2MsIHBpZGwtPm1raWQuY2Irc2l6ZW9mKFVTSE9SVCkpOwoJCW1lbWNweShuZXh0X3BpZGwsIHBpZGwsIHBpZGwtPm1raWQuY2IpOwoJCSgoTFBJVEVNSURMSVNUKSgoTFBCWVRFKW5leHRfcGlkbCtwaWRsLT5ta2lkLmNiKSktPm1raWQuY2IgPSAwOwoKCQlociA9IElTaGVsbEZvbGRlcl9CaW5kVG9PYmplY3QoZm9sZGVyLCBuZXh0X3BpZGwsIDAsICZJSURfSVNoZWxsRm9sZGVyLCAodm9pZCoqKSZjaGlsZCk7CgkJaWYgKCFTVUNDRUVERUQoaHIpKQoJCQlicmVhazsKCgkJcmVhZF9kaXJlY3RvcnkoZW50cnksIE5VTEwsIHNvcnRPcmRlciwgaHduZCk7CgoJCWlmIChlbnRyeS0+ZG93bikKCQkJZW50cnktPmV4cGFuZGVkID0gVFJVRTsKCgkJbmV4dCA9IGZpbmRfZW50cnlfc2hlbGwoZW50cnksIG5leHRfcGlkbCk7CgkJaWYgKCFuZXh0KQoJCQlicmVhazsKCgkJZm9sZGVyID0gY2hpbGQ7CgkJZW50cnkgPSBuZXh0OwoKCQkgLyogZ28gdG8gbmV4dCBlbGVtZW50ICovCgkJcGlkbCA9IChMUElURU1JRExJU1QpICgoTFBCWVRFKXBpZGwrcGlkbC0+bWtpZC5jYik7Cgl9CgoJU2V0Q3Vyc29yKG9sZF9jdXJzb3IpOwoKCXJldHVybiBlbnRyeTsKfQoKCnN0YXRpYyB2b2lkIGZpbGxfdzMyZmRhdGFfc2hlbGwoSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQQ0lURU1JRExJU1QgcGlkbCwgU0ZHQU9GIGF0dHJpYnMsIFdJTjMyX0ZJTkRfREFUQSogdzMyZmRhdGEpCnsKCWlmICghKGF0dHJpYnMgJiBTRkdBT19GSUxFU1lTVEVNKSB8fAoJCSAgRkFJTEVEKFNIR2V0RGF0YUZyb21JRExpc3QoZm9sZGVyLCBwaWRsLCBTSEdERklMX0ZJTkREQVRBLCB3MzJmZGF0YSwgc2l6ZW9mKFdJTjMyX0ZJTkRfREFUQSkpKSkgewoJCVdJTjMyX0ZJTEVfQVRUUklCVVRFX0RBVEEgZmFkOwoJCUlEYXRhT2JqZWN0KiBwRGF0YU9iajsKCgkJU1RHTUVESVVNIG1lZGl1bSA9IHswLCB7MH0sIDB9OwoJCUZPUk1BVEVUQyBmbXQgPSB7R2xvYmFscy5jZlN0ckZOYW1lLCAwLCBEVkFTUEVDVF9DT05URU5ULCAtMSwgVFlNRURfSEdMT0JBTH07CgoJCUhSRVNVTFQgaHIgPSBJU2hlbGxGb2xkZXJfR2V0VUlPYmplY3RPZihmb2xkZXIsIDAsIDEsICZwaWRsLCAmSUlEX0lEYXRhT2JqZWN0LCAwLCAoTFBWT0lEKikmcERhdGFPYmopOwoKCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQlociA9IElEYXRhT2JqZWN0X0dldERhdGEocERhdGFPYmosICZmbXQsICZtZWRpdW0pOwoKCQkJSURhdGFPYmplY3RfUmVsZWFzZShwRGF0YU9iaik7CgoJCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQkJTFBDVFNUUiBwYXRoID0gKExQQ1RTVFIpR2xvYmFsTG9jayhtZWRpdW0uVU5JT05fTUVNQkVSKGhHbG9iYWwpKTsKCQkJCVVJTlQgc2VtX29yZyA9IFNldEVycm9yTW9kZShTRU1fRkFJTENSSVRJQ0FMRVJST1JTKTsKCgkJCQlpZiAoR2V0RmlsZUF0dHJpYnV0ZXNFeChwYXRoLCBHZXRGaWxlRXhJbmZvU3RhbmRhcmQsICZmYWQpKSB7CgkJCQkJdzMyZmRhdGEtPmR3RmlsZUF0dHJpYnV0ZXMgPSBmYWQuZHdGaWxlQXR0cmlidXRlczsKCQkJCQl3MzJmZGF0YS0+ZnRDcmVhdGlvblRpbWUgPSBmYWQuZnRDcmVhdGlvblRpbWU7CgkJCQkJdzMyZmRhdGEtPmZ0TGFzdEFjY2Vzc1RpbWUgPSBmYWQuZnRMYXN0QWNjZXNzVGltZTsKCQkJCQl3MzJmZGF0YS0+ZnRMYXN0V3JpdGVUaW1lID0gZmFkLmZ0TGFzdFdyaXRlVGltZTsKCgkJCQkJaWYgKCEoZmFkLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpKSB7CgkJCQkJCXczMmZkYXRhLT5uRmlsZVNpemVMb3cgPSBmYWQubkZpbGVTaXplTG93OwoJCQkJCQl3MzJmZGF0YS0+bkZpbGVTaXplSGlnaCA9IGZhZC5uRmlsZVNpemVIaWdoOwoJCQkJCX0KCQkJCX0KCgkJCQlTZXRFcnJvck1vZGUoc2VtX29yZyk7CgoJCQkJR2xvYmFsVW5sb2NrKG1lZGl1bS5VTklPTl9NRU1CRVIoaEdsb2JhbCkpOwoJCQkJR2xvYmFsRnJlZShtZWRpdW0uVU5JT05fTUVNQkVSKGhHbG9iYWwpKTsKCQkJfQoJCX0KCX0KCglpZiAoYXR0cmlicyAmIChTRkdBT19GT0xERVJ8U0ZHQU9fSEFTU1VCRk9MREVSKSkKCQl3MzJmZGF0YS0+ZHdGaWxlQXR0cmlidXRlcyB8PSBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk7CgoJaWYgKGF0dHJpYnMgJiBTRkdBT19SRUFET05MWSkKCQl3MzJmZGF0YS0+ZHdGaWxlQXR0cmlidXRlcyB8PSBGSUxFX0FUVFJJQlVURV9SRUFET05MWTsKCglpZiAoYXR0cmlicyAmIFNGR0FPX0NPTVBSRVNTRUQpCgkJdzMyZmRhdGEtPmR3RmlsZUF0dHJpYnV0ZXMgfD0gRklMRV9BVFRSSUJVVEVfQ09NUFJFU1NFRDsKfQoKCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5X3NoZWxsKEVudHJ5KiBkaXIsIEhXTkQgaHduZCkKewoJSVNoZWxsRm9sZGVyKiBmb2xkZXIgPSBkaXItPmZvbGRlcjsKCWludCBsZXZlbCA9IGRpci0+bGV2ZWwgKyAxOwoJSFJFU1VMVCBocjsKCglJU2hlbGxGb2xkZXIqIGNoaWxkOwoJSUVudW1JRExpc3QqIGlkbGlzdDsKCglFbnRyeSogZmlyc3RfZW50cnkgPSBOVUxMOwoJRW50cnkqIGxhc3QgPSBOVUxMOwoJRW50cnkqIGVudHJ5OwoKCWlmICghZm9sZGVyKQoJCXJldHVybjsKCglociA9IElTaGVsbEZvbGRlcl9FbnVtT2JqZWN0cyhmb2xkZXIsIGh3bmQsIFNIQ09OVEZfRk9MREVSU3xTSENPTlRGX05PTkZPTERFUlN8U0hDT05URl9JTkNMVURFSElEREVOfFNIQ09OVEZfU0hBUkVBQkxFfFNIQ09OVEZfU1RPUkFHRSwgJmlkbGlzdCk7CgoJaWYgKFNVQ0NFRURFRChocikpIHsKCQlmb3IoOzspIHsKI2RlZmluZQlGRVRDSF9JVEVNX0NPVU5UCTMyCgkJCUxQSVRFTUlETElTVCBwaWRsc1tGRVRDSF9JVEVNX0NPVU5UXTsKCQkJU0ZHQU9GIGF0dHJpYnM7CgkJCVVMT05HIGNudCA9IDA7CgkJCVVMT05HIG47CgoJCQltZW1zZXQocGlkbHMsIDAsIHNpemVvZihwaWRscykpOwoKCQkJaHIgPSBJRW51bUlETGlzdF9OZXh0KGlkbGlzdCwgRkVUQ0hfSVRFTV9DT1VOVCwgcGlkbHMsICZjbnQpOwoJCQlpZiAoIVNVQ0NFRURFRChocikpCgkJCQlicmVhazsKCgkJCWlmIChociA9PSBTX0ZBTFNFKQoJCQkJYnJlYWs7CgoJCQlmb3Iobj0wOyBuPGNudDsgKytuKSB7CgkJCQllbnRyeSA9IGFsbG9jX2VudHJ5KCk7CgoJCQkJaWYgKCFmaXJzdF9lbnRyeSkKCQkJCQlmaXJzdF9lbnRyeSA9IGVudHJ5OwoKCQkJCWlmIChsYXN0KQoJCQkJCWxhc3QtPm5leHQgPSBlbnRyeTsKCgkJCQltZW1zZXQoJmVudHJ5LT5kYXRhLCAwLCBzaXplb2YoV0lOMzJfRklORF9EQVRBKSk7CgkJCQllbnRyeS0+YmhmaV92YWxpZCA9IEZBTFNFOwoKCQkJCWF0dHJpYnMgPSB+U0ZHQU9fRklMRVNZU1RFTTsJLypTRkdBT19IQVNTVUJGT0xERVJ8U0ZHQU9fRk9MREVSOyBTRkdBT19GSUxFU1lTVEVNIHNvcmd0IGRhZvxyLCBkYd8gIk15IERvY3VtZW50cyIgYW5zdGF0dCB2b24gIk1hcnRpbidzIERvY3VtZW50cyIgYW5nZXplaWd0IHdpcmQgKi8KCgkJCQlociA9IElTaGVsbEZvbGRlcl9HZXRBdHRyaWJ1dGVzT2YoZm9sZGVyLCAxLCAoTFBDSVRFTUlETElTVCopJnBpZGxzW25dLCAmYXR0cmlicyk7CgoJCQkJaWYgKFNVQ0NFRURFRChocikpIHsKCQkJCQlpZiAoYXR0cmlicyAhPSAoU0ZHQU9GKX5TRkdBT19GSUxFU1lTVEVNKSB7CgkJCQkJCWZpbGxfdzMyZmRhdGFfc2hlbGwoZm9sZGVyLCBwaWRsc1tuXSwgYXR0cmlicywgJmVudHJ5LT5kYXRhKTsKCgkJCQkJCWVudHJ5LT5iaGZpX3ZhbGlkID0gVFJVRTsKCQkJCQl9IGVsc2UKCQkJCQkJYXR0cmlicyA9IDA7CgkJCQl9IGVsc2UKCQkJCQlhdHRyaWJzID0gMDsKCgkJCQllbnRyeS0+cGlkbCA9IHBpZGxzW25dOwoKCQkJCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCQkJaHIgPSBJU2hlbGxGb2xkZXJfQmluZFRvT2JqZWN0KGZvbGRlciwgcGlkbHNbbl0sIDAsICZJSURfSVNoZWxsRm9sZGVyLCAodm9pZCoqKSZjaGlsZCk7CgoJCQkJCWlmIChTVUNDRUVERUQoaHIpKQoJCQkJCQllbnRyeS0+Zm9sZGVyID0gY2hpbGQ7CgkJCQkJZWxzZQoJCQkJCQllbnRyeS0+Zm9sZGVyID0gTlVMTDsKCQkJCX0KCQkJCWVsc2UKCQkJCQllbnRyeS0+Zm9sZGVyID0gTlVMTDsKCgkJCQlpZiAoIWVudHJ5LT5kYXRhLmNGaWxlTmFtZVswXSkKCQkJCQkvKmhyID0gKi9uYW1lX2Zyb21fcGlkbChmb2xkZXIsIHBpZGxzW25dLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIE1BWF9QQVRILCAvKlNIR0ROX0lORk9MREVSKi8weDIwMDAvKjB4MjAwMD1TSEdETl9JTkNMVURFX05PTkZJTEVTWVMqLyk7CgoJCQkJIC8qIGdldCBkaXNwbGF5IGljb25zIGZvciBmaWxlcyBhbmQgdmlydHVhbCBvYmplY3RzICovCgkJCQlpZiAoIShlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB8fAoJCQkJCSEoYXR0cmlicyAmIFNGR0FPX0ZJTEVTWVNURU0pKSB7CgkJCQkJZW50cnktPmhpY29uID0gZXh0cmFjdF9pY29uKGZvbGRlciwgcGlkbHNbbl0pOwoKCQkJCQlpZiAoIWVudHJ5LT5oaWNvbikKCQkJCQkJZW50cnktPmhpY29uID0gKEhJQ09OKS0xOwkvKiBkb24ndCB0cnkgYWdhaW4gbGF0ZXIgKi8KCQkJCX0KCgkJCQllbnRyeS0+ZG93biA9IE5VTEw7CgkJCQllbnRyeS0+dXAgPSBkaXI7CgkJCQllbnRyeS0+ZXhwYW5kZWQgPSBGQUxTRTsKCQkJCWVudHJ5LT5zY2FubmVkID0gRkFMU0U7CgkJCQllbnRyeS0+bGV2ZWwgPSBsZXZlbDsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJCWVudHJ5LT5ldHlwZSA9IEVUX1NIRUxMOwoJCQkJZW50cnktPmJoZmlfdmFsaWQgPSBGQUxTRTsKI2VuZGlmCgoJCQkJbGFzdCA9IGVudHJ5OwoJCQl9CgkJfQoKCQlJRW51bUlETGlzdF9SZWxlYXNlKGlkbGlzdCk7Cgl9CgoJaWYgKGxhc3QpCgkJbGFzdC0+bmV4dCA9IE5VTEw7CgoJZGlyLT5kb3duID0gZmlyc3RfZW50cnk7CglkaXItPnNjYW5uZWQgPSBUUlVFOwp9CgojZW5kaWYgLyogX1NIRUxMX0ZPTERFUlMgKi8KCgovKiBzb3J0IG9yZGVyIGZvciBkaWZmZXJlbnQgZGlyZWN0b3J5L2ZpbGUgdHlwZXMgKi8KZW51bSBUWVBFX09SREVSIHsKCVRPX0RJUiA9IDAsCglUT19ET1QgPSAxLAoJVE9fRE9URE9UID0gMiwKCVRPX09USEVSX0RJUiA9IDMsCglUT19GSUxFID0gNAp9OwoKLyogZGlzdGluZ3Vpc2ggYmV0d2VlbiAiLiIsICIuLiIgYW5kIGFueSBvdGhlciBkaXJlY3RvcnkgbmFtZXMgKi8Kc3RhdGljIGludCBUeXBlT3JkZXJGcm9tRGlybmFtZShMUENUU1RSIG5hbWUpCnsKCWlmIChuYW1lWzBdID09ICcuJykgewoJCWlmIChuYW1lWzFdID09ICdcMCcpCgkJCXJldHVybiBUT19ET1Q7CS8qICIuIiAqLwoKCQlpZiAobmFtZVsxXT09Jy4nICYmIG5hbWVbMl09PSdcMCcpCgkJCXJldHVybiBUT19ET1RET1Q7CS8qICIuLiIgKi8KCX0KCglyZXR1cm4gVE9fT1RIRVJfRElSOwkvKiBhbnl0aGluZyBlbHNlICovCn0KCi8qIGRpcmVjdG9yaWVzIGZpcnN0Li4uICovCnN0YXRpYyBpbnQgY29tcGFyZVR5cGUoY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDEsIGNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQyKQp7CglpbnQgb3JkZXIxID0gZmQxLT5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZPyBUT19ESVI6IFRPX0ZJTEU7CglpbnQgb3JkZXIyID0gZmQyLT5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZPyBUT19ESVI6IFRPX0ZJTEU7CgoJLyogSGFuZGxlICIuIiBhbmQgIi4uIiBhcyBzcGVjaWFsIGNhc2UgYW5kIG1vdmUgdGhlbSBhdCB0aGUgdmVyeSBmaXJzdCBiZWdpbm5pbmcuICovCglpZiAob3JkZXIxPT1UT19ESVIgJiYgb3JkZXIyPT1UT19ESVIpIHsKCQlvcmRlcjEgPSBUeXBlT3JkZXJGcm9tRGlybmFtZShmZDEtPmNGaWxlTmFtZSk7CgkJb3JkZXIyID0gVHlwZU9yZGVyRnJvbURpcm5hbWUoZmQyLT5jRmlsZU5hbWUpOwoJfQoKCXJldHVybiBvcmRlcjI9PW9yZGVyMT8gMDogb3JkZXIxPG9yZGVyMj8gLTE6IDE7Cn0KCgpzdGF0aWMgaW50IGNvbXBhcmVOYW1lKGNvbnN0IHZvaWQqIGFyZzEsIGNvbnN0IHZvaWQqIGFyZzIpCnsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQxID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMSktPmRhdGE7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMiA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzIpLT5kYXRhOwoKCWludCBjbXAgPSBjb21wYXJlVHlwZShmZDEsIGZkMik7CglpZiAoY21wKQoJCXJldHVybiBjbXA7CgoJcmV0dXJuIGxzdHJjbXBpKGZkMS0+Y0ZpbGVOYW1lLCBmZDItPmNGaWxlTmFtZSk7Cn0KCnN0YXRpYyBpbnQgY29tcGFyZUV4dChjb25zdCB2b2lkKiBhcmcxLCBjb25zdCB2b2lkKiBhcmcyKQp7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMSA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzEpLT5kYXRhOwoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDIgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcyKS0+ZGF0YTsKCWNvbnN0IFRDSEFSICpuYW1lMSwgKm5hbWUyLCAqZXh0MSwgKmV4dDI7CgoJaW50IGNtcCA9IGNvbXBhcmVUeXBlKGZkMSwgZmQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCgluYW1lMSA9IGZkMS0+Y0ZpbGVOYW1lOwoJbmFtZTIgPSBmZDItPmNGaWxlTmFtZTsKCglleHQxID0gX3Rjc3JjaHIobmFtZTEsIFRFWFQoJy4nKSk7CglleHQyID0gX3Rjc3JjaHIobmFtZTIsIFRFWFQoJy4nKSk7CgoJaWYgKGV4dDEpCgkJZXh0MSsrOwoJZWxzZQoJCWV4dDEgPSBzRW1wdHk7CgoJaWYgKGV4dDIpCgkJZXh0MisrOwoJZWxzZQoJCWV4dDIgPSBzRW1wdHk7CgoJY21wID0gbHN0cmNtcGkoZXh0MSwgZXh0Mik7CglpZiAoY21wKQoJCXJldHVybiBjbXA7CgoJcmV0dXJuIGxzdHJjbXBpKG5hbWUxLCBuYW1lMik7Cn0KCnN0YXRpYyBpbnQgY29tcGFyZVNpemUoY29uc3Qgdm9pZCogYXJnMSwgY29uc3Qgdm9pZCogYXJnMikKewoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDEgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcxKS0+ZGF0YTsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQyID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMiktPmRhdGE7CgoJaW50IGNtcCA9IGNvbXBhcmVUeXBlKGZkMSwgZmQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCgljbXAgPSBmZDItPm5GaWxlU2l6ZUhpZ2ggLSBmZDEtPm5GaWxlU2l6ZUhpZ2g7CgoJaWYgKGNtcCA8IDApCgkJcmV0dXJuIC0xOwoJZWxzZSBpZiAoY21wID4gMCkKCQlyZXR1cm4gMTsKCgljbXAgPSBmZDItPm5GaWxlU2l6ZUxvdyAtIGZkMS0+bkZpbGVTaXplTG93OwoKCXJldHVybiBjbXA8MD8gLTE6IGNtcD4wPyAxOiAwOwp9CgpzdGF0aWMgaW50IGNvbXBhcmVEYXRlKGNvbnN0IHZvaWQqIGFyZzEsIGNvbnN0IHZvaWQqIGFyZzIpCnsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQxID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMSktPmRhdGE7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMiA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzIpLT5kYXRhOwoKCWludCBjbXAgPSBjb21wYXJlVHlwZShmZDEsIGZkMik7CglpZiAoY21wKQoJCXJldHVybiBjbXA7CgoJcmV0dXJuIENvbXBhcmVGaWxlVGltZSgmZmQyLT5mdExhc3RXcml0ZVRpbWUsICZmZDEtPmZ0TGFzdFdyaXRlVGltZSk7Cn0KCgpzdGF0aWMgaW50ICgqc29ydEZ1bmN0aW9uc1tdKShjb25zdCB2b2lkKiBhcmcxLCBjb25zdCB2b2lkKiBhcmcyKSA9IHsKCWNvbXBhcmVOYW1lLAkvKiBTT1JUX05BTUUgKi8KCWNvbXBhcmVFeHQsCQkvKiBTT1JUX0VYVCAqLwoJY29tcGFyZVNpemUsCS8qIFNPUlRfU0laRSAqLwoJY29tcGFyZURhdGUJCS8qIFNPUlRfREFURSAqLwp9OwoKCnN0YXRpYyB2b2lkIFNvcnREaXJlY3RvcnkoRW50cnkqIGRpciwgU09SVF9PUkRFUiBzb3J0T3JkZXIpCnsKCUVudHJ5KiBlbnRyeSA9IGRpci0+ZG93bjsKCUVudHJ5KiogYXJyYXksICoqcDsKCWludCBsZW47CgoJbGVuID0gMDsKCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQlsZW4rKzsKCglpZiAobGVuKSB7CgkJYXJyYXkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihFbnRyeSopKTsKCgkJcCA9IGFycmF5OwoJCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQkJKnArKyA9IGVudHJ5OwoKCQkvKiBjYWxsIHFzb3J0IHdpdGggdGhlIGFwcHJvcHJpYXRlIGNvbXBhcmUgZnVuY3Rpb24gKi8KCQlxc29ydChhcnJheSwgbGVuLCBzaXplb2YoYXJyYXlbMF0pLCBzb3J0RnVuY3Rpb25zW3NvcnRPcmRlcl0pOwoKCQlkaXItPmRvd24gPSBhcnJheVswXTsKCgkJZm9yKHA9YXJyYXk7IC0tbGVuOyBwKyspCgkJCXBbMF0tPm5leHQgPSBwWzFdOwoKCQkoKnApLT5uZXh0ID0gMDsKCiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBhcnJheSk7Cgl9Cn0KCgpzdGF0aWMgdm9pZCByZWFkX2RpcmVjdG9yeShFbnRyeSogZGlyLCBMUENUU1RSIHBhdGgsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF07CglFbnRyeSogZW50cnk7CglMUENUU1RSIHM7CglQVFNUUiBkOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglpZiAoZGlyLT5ldHlwZSA9PSBFVF9TSEVMTCkKCXsKCQlyZWFkX2RpcmVjdG9yeV9zaGVsbChkaXIsIGh3bmQpOwoKCQlpZiAoR2xvYmFscy5wcmVzY2FuX25vZGUpIHsKCQkJcyA9IHBhdGg7CgkJCWQgPSBidWZmZXI7CgoJCQl3aGlsZSgqcykKCQkJCSpkKysgPSAqcysrOwoKCQkJKmQrKyA9IFRFWFQoJ1xcJyk7CgoJCQlmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpCgkJCQlpZiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJCXJlYWRfZGlyZWN0b3J5X3NoZWxsKGVudHJ5LCBod25kKTsKCQkJCQlTb3J0RGlyZWN0b3J5KGVudHJ5LCBzb3J0T3JkZXIpOwoJCQkJfQoJCX0KCX0KCWVsc2UKI2VuZGlmCiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCWlmIChkaXItPmV0eXBlID09IEVUX1VOSVgpCgl7CgkJcmVhZF9kaXJlY3RvcnlfdW5peChkaXIsIHBhdGgpOwoKCQlpZiAoR2xvYmFscy5wcmVzY2FuX25vZGUpIHsKCQkJcyA9IHBhdGg7CgkJCWQgPSBidWZmZXI7CgoJCQl3aGlsZSgqcykKCQkJCSpkKysgPSAqcysrOwoKCQkJKmQrKyA9IFRFWFQoJy8nKTsKCgkJCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQkJCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCQkJbHN0cmNweShkLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpOwoJCQkJCXJlYWRfZGlyZWN0b3J5X3VuaXgoZW50cnksIGJ1ZmZlcik7CgkJCQkJU29ydERpcmVjdG9yeShlbnRyeSwgc29ydE9yZGVyKTsKCQkJCX0KCQl9Cgl9CgllbHNlCiNlbmRpZgoJewoJCXJlYWRfZGlyZWN0b3J5X3dpbihkaXIsIHBhdGgpOwoKCQlpZiAoR2xvYmFscy5wcmVzY2FuX25vZGUpIHsKCQkJcyA9IHBhdGg7CgkJCWQgPSBidWZmZXI7CgoJCQl3aGlsZSgqcykKCQkJCSpkKysgPSAqcysrOwoKCQkJKmQrKyA9IFRFWFQoJ1xcJyk7CgoJCQlmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpCgkJCQlpZiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJCWxzdHJjcHkoZCwgZW50cnktPmRhdGEuY0ZpbGVOYW1lKTsKCQkJCQlyZWFkX2RpcmVjdG9yeV93aW4oZW50cnksIGJ1ZmZlcik7CgkJCQkJU29ydERpcmVjdG9yeShlbnRyeSwgc29ydE9yZGVyKTsKCQkJCX0KCQl9Cgl9CgoJU29ydERpcmVjdG9yeShkaXIsIHNvcnRPcmRlcik7Cn0KCgpzdGF0aWMgRW50cnkqIHJlYWRfdHJlZShSb290KiByb290LCBMUENUU1RSIHBhdGgsIExQSVRFTUlETElTVCBwaWRsLCBMUFRTVFIgZHJ2LCBTT1JUX09SREVSIHNvcnRPcmRlciwgSFdORCBod25kKQp7CiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCXN0YXRpYyBjb25zdCBUQ0hBUiBzU2xhc2hbXSA9IHsnLycsICdcMCd9OwojZW5kaWYKCXN0YXRpYyBjb25zdCBUQ0hBUiBzQmFja3NsYXNoW10gPSB7J1xcJywgJ1wwJ307CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChwaWRsKQoJewoJCSAvKiByZWFkIHNoZWxsIG5hbWVzcGFjZSB0cmVlICovCgkJcm9vdC0+ZHJpdmVfdHlwZSA9IERSSVZFX1VOS05PV047CgkJZHJ2WzBdID0gJ1xcJzsKCQlkcnZbMV0gPSAnXDAnOwoJCWxvYWRfc3RyaW5nKHJvb3QtPnZvbG5hbWUsIElEU19ERVNLVE9QKTsKCQlyb290LT5mc19mbGFncyA9IDA7CgkJbG9hZF9zdHJpbmcocm9vdC0+ZnMsIElEU19TSEVMTCk7CgoJCXJldHVybiByZWFkX3RyZWVfc2hlbGwocm9vdCwgcGlkbCwgc29ydE9yZGVyLCBod25kKTsKCX0KCWVsc2UKI2VuZGlmCiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCWlmICgqcGF0aCA9PSAnLycpCgl7CgkJIC8qIHJlYWQgdW5peCBmaWxlIHN5c3RlbSB0cmVlICovCgkJcm9vdC0+ZHJpdmVfdHlwZSA9IEdldERyaXZlVHlwZShwYXRoKTsKCgkJbHN0cmNhdChkcnYsIHNTbGFzaCk7CgkJbG9hZF9zdHJpbmcocm9vdC0+dm9sbmFtZSwgSURTX1JPT1RfRlMpOwoJCXJvb3QtPmZzX2ZsYWdzID0gMDsKCQlsb2FkX3N0cmluZyhyb290LT5mcywgSURTX1VOSVhGUyk7CgoJCWxzdHJjcHkocm9vdC0+cGF0aCwgc1NsYXNoKTsKCgkJcmV0dXJuIHJlYWRfdHJlZV91bml4KHJvb3QsIHBhdGgsIHNvcnRPcmRlciwgaHduZCk7Cgl9CiNlbmRpZgoKCSAvKiByZWFkIFdJTjMyIGZpbGUgc3lzdGVtIHRyZWUgKi8KCXJvb3QtPmRyaXZlX3R5cGUgPSBHZXREcml2ZVR5cGUocGF0aCk7CgoJbHN0cmNhdChkcnYsIHNCYWNrc2xhc2gpOwoJR2V0Vm9sdW1lSW5mb3JtYXRpb24oZHJ2LCByb290LT52b2xuYW1lLCBfTUFYX0ZOQU1FLCAwLCAwLCAmcm9vdC0+ZnNfZmxhZ3MsIHJvb3QtPmZzLCBfTUFYX0RJUik7CgoJbHN0cmNweShyb290LT5wYXRoLCBkcnYpOwoKCXJldHVybiByZWFkX3RyZWVfd2luKHJvb3QsIHBhdGgsIHNvcnRPcmRlciwgaHduZCk7Cn0KCgovKiBmbGFncyB0byBmaWx0ZXIgZGlmZmVyZW50IGZpbGUgdHlwZXMgKi8KZW51bSBUWVBFX0ZJTFRFUiB7CglURl9ESVJFQ1RPUklFUwk9IDB4MDEsCglURl9QUk9HUkFNUwkJPSAweDAyLAoJVEZfRE9DVU1FTlRTCT0gMHgwNCwKCVRGX09USEVSUwkJPSAweDA4LAoJVEZfSElEREVOCQk9IDB4MTAsCglURl9BTEwJCQk9IDB4MUYKfTsKCgpzdGF0aWMgQ2hpbGRXbmQqIGFsbG9jX2NoaWxkX3dpbmRvdyhMUENUU1RSIHBhdGgsIExQSVRFTUlETElTVCBwaWRsLCBIV05EIGh3bmQpCnsKCVRDSEFSIGRydltfTUFYX0RSSVZFKzFdLCBkaXJbX01BWF9ESVJdLCBuYW1lW19NQVhfRk5BTUVdLCBleHRbX01BWF9FWFRdOwoJVENIQVIgZGlyX3BhdGhbTUFYX1BBVEhdOwoJVENIQVIgYjFbQlVGRkVSX0xFTl07CglzdGF0aWMgY29uc3QgVENIQVIgc0FzdGVyaWNzW10gPSB7JyonLCAnXDAnfTsKCglDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBtYWxsb2Moc2l6ZW9mKENoaWxkV25kKSk7CglSb290KiByb290ID0gJmNoaWxkLT5yb290OwoJRW50cnkqIGVudHJ5OwoKCW1lbXNldChjaGlsZCwgMCwgc2l6ZW9mKENoaWxkV25kKSk7CgoJY2hpbGQtPmxlZnQudHJlZVBhbmUgPSBUUlVFOwoJY2hpbGQtPmxlZnQudmlzaWJsZV9jb2xzID0gMDsKCgljaGlsZC0+cmlnaHQudHJlZVBhbmUgPSBGQUxTRTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJY2hpbGQtPnJpZ2h0LnZpc2libGVfY29scyA9IENPTF9TSVpFfENPTF9EQVRFfENPTF9USU1FfENPTF9BVFRSSUJVVEVTfENPTF9JTkRFWHxDT0xfTElOS1M7CiNlbHNlCgljaGlsZC0+cmlnaHQudmlzaWJsZV9jb2xzID0gQ09MX1NJWkV8Q09MX0RBVEV8Q09MX1RJTUV8Q09MX0FUVFJJQlVURVM7CiNlbmRpZgoKCWNoaWxkLT5wb3MubGVuZ3RoID0gc2l6ZW9mKFdJTkRPV1BMQUNFTUVOVCk7CgljaGlsZC0+cG9zLmZsYWdzID0gMDsKCWNoaWxkLT5wb3Muc2hvd0NtZCA9IFNXX1NIT1dOT1JNQUw7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ubGVmdCA9IENXX1VTRURFRkFVTFQ7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24udG9wID0gQ1dfVVNFREVGQVVMVDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5yaWdodCA9IENXX1VTRURFRkFVTFQ7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24uYm90dG9tID0gQ1dfVVNFREVGQVVMVDsKCgljaGlsZC0+Zm9jdXNfcGFuZSA9IDA7CgljaGlsZC0+c3BsaXRfcG9zID0gREVGQVVMVF9TUExJVF9QT1M7CgljaGlsZC0+c29ydE9yZGVyID0gU09SVF9OQU1FOwoJY2hpbGQtPmhlYWRlcl93ZHRoc19vayA9IEZBTFNFOwoKCWlmIChwYXRoKQoJewoJCWxzdHJjcHkoY2hpbGQtPnBhdGgsIHBhdGgpOwoKCQlfdHNwbGl0cGF0aChwYXRoLCBkcnYsIGRpciwgbmFtZSwgZXh0KTsKCX0KCglsc3RyY3B5KGNoaWxkLT5maWx0ZXJfcGF0dGVybiwgc0FzdGVyaWNzKTsKCWNoaWxkLT5maWx0ZXJfZmxhZ3MgPSBURl9BTEw7CgoJcm9vdC0+ZW50cnkubGV2ZWwgPSAwOwoKCWxzdHJjcHkoZGlyX3BhdGgsIGRydik7Cglsc3RyY2F0KGRpcl9wYXRoLCBkaXIpOwoJZW50cnkgPSByZWFkX3RyZWUocm9vdCwgZGlyX3BhdGgsIHBpZGwsIGRydiwgY2hpbGQtPnNvcnRPcmRlciwgaHduZCk7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChyb290LT5lbnRyeS5ldHlwZSA9PSBFVF9TSEVMTCkKCQlsb2FkX3N0cmluZyhyb290LT5lbnRyeS5kYXRhLmNGaWxlTmFtZSwgSURTX0RFU0tUT1ApOwoJZWxzZQojZW5kaWYKCQl3c3ByaW50Zihyb290LT5lbnRyeS5kYXRhLmNGaWxlTmFtZSwgUlMoYjEsSURTX1RJVExFRk1UKSwgZHJ2LCByb290LT5mcyk7CgoJcm9vdC0+ZW50cnkuZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzID0gRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZOwoKCWNoaWxkLT5sZWZ0LnJvb3QgPSAmcm9vdC0+ZW50cnk7CgljaGlsZC0+cmlnaHQucm9vdCA9IE5VTEw7CgoJc2V0X2N1cmRpcihjaGlsZCwgZW50cnksIDAsIGh3bmQpOwoKCXJldHVybiBjaGlsZDsKfQoKCi8qIGZyZWUgYWxsIG1lbW9yeSBhc3NvY2lhdGVkIHdpdGggYSBjaGlsZCB3aW5kb3cgKi8Kc3RhdGljIHZvaWQgZnJlZV9jaGlsZF93aW5kb3coQ2hpbGRXbmQqIGNoaWxkKQp7CglmcmVlX2VudHJpZXMoJmNoaWxkLT5yb290LmVudHJ5KTsKCWZyZWUoY2hpbGQpOwp9CgoKLyogZ2V0IGZ1bGwgcGF0aCBvZiBzcGVjaWZpZWQgZGlyZWN0b3J5IGVudHJ5ICovCnN0YXRpYyB2b2lkIGdldF9wYXRoKEVudHJ5KiBkaXIsIFBUU1RSIHBhdGgpCnsKCUVudHJ5KiBlbnRyeTsKCWludCBsZW4gPSAwOwoJaW50IGxldmVsID0gMDsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGRpci0+ZXR5cGUgPT0gRVRfU0hFTEwpCgl7CgkJU0ZHQU9GIGF0dHJpYnM7CgkJSFJFU1VMVCBociA9IFNfT0s7CgoJCXBhdGhbMF0gPSBURVhUKCdcMCcpOwoKCQlhdHRyaWJzID0gMDsKCgkJaWYgKGRpci0+Zm9sZGVyKQoJCQlociA9IElTaGVsbEZvbGRlcl9HZXRBdHRyaWJ1dGVzT2YoZGlyLT5mb2xkZXIsIDEsIChMUENJVEVNSURMSVNUKikmZGlyLT5waWRsLCAmYXR0cmlicyk7CgoJCWlmIChTVUNDRUVERUQoaHIpICYmIChhdHRyaWJzJlNGR0FPX0ZJTEVTWVNURU0pKSB7CgkJCUlTaGVsbEZvbGRlciogcGFyZW50ID0gZGlyLT51cD8gZGlyLT51cC0+Zm9sZGVyOiBHbG9iYWxzLmlEZXNrdG9wOwoKCQkJaHIgPSBwYXRoX2Zyb21fcGlkbChwYXJlbnQsIGRpci0+cGlkbCwgcGF0aCwgTUFYX1BBVEgpOwoJCX0KCX0KCWVsc2UKI2VuZGlmCgl7CgkJZm9yKGVudHJ5PWRpcjsgZW50cnk7IGxldmVsKyspIHsKCQkJTFBDVFNUUiBuYW1lOwoJCQlpbnQgbDsKCgkJCXsKCQkJCUxQQ1RTVFIgczsKCQkJCW5hbWUgPSBlbnRyeS0+ZGF0YS5jRmlsZU5hbWU7CgkJCQlzID0gbmFtZTsKCgkJCQlmb3IobD0wOyAqcyAmJiAqcyE9VEVYVCgnLycpICYmICpzIT1URVhUKCdcXCcpOyBzKyspCgkJCQkJbCsrOwoJCQl9CgoJCQlpZiAoZW50cnktPnVwKSB7CgkJCQlpZiAobCA+IDApIHsKCQkJCQltZW1tb3ZlKHBhdGgrbCsxLCBwYXRoLCBsZW4qc2l6ZW9mKFRDSEFSKSk7CgkJCQkJbWVtY3B5KHBhdGgrMSwgbmFtZSwgbCpzaXplb2YoVENIQVIpKTsKCQkJCQlsZW4gKz0gbCsxOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCWlmIChlbnRyeS0+ZXR5cGUgPT0gRVRfVU5JWCkKCQkJCQkJcGF0aFswXSA9IFRFWFQoJy8nKTsKCQkJCQllbHNlCiNlbmRpZgoJCQkJCXBhdGhbMF0gPSBURVhUKCdcXCcpOwoJCQkJfQoKCQkJCWVudHJ5ID0gZW50cnktPnVwOwoJCQl9IGVsc2UgewoJCQkJbWVtbW92ZShwYXRoK2wsIHBhdGgsIGxlbipzaXplb2YoVENIQVIpKTsKCQkJCW1lbWNweShwYXRoLCBuYW1lLCBsKnNpemVvZihUQ0hBUikpOwoJCQkJbGVuICs9IGw7CgkJCQlicmVhazsKCQkJfQoJCX0KCgkJaWYgKCFsZXZlbCkgewojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCWlmIChlbnRyeS0+ZXR5cGUgPT0gRVRfVU5JWCkKCQkJCXBhdGhbbGVuKytdID0gVEVYVCgnLycpOwoJCQllbHNlCiNlbmRpZgoJCQkJcGF0aFtsZW4rK10gPSBURVhUKCdcXCcpOwoJCX0KCgkJcGF0aFtsZW5dID0gVEVYVCgnXDAnKTsKCX0KfQoKc3RhdGljIHdpbmRvd09wdGlvbnMgbG9hZF9yZWdpc3RyeV9zZXR0aW5ncyh2b2lkKQp7CglEV09SRCBzaXplOwoJRFdPUkQgdHlwZTsKCUhLRVkgaEtleTsKCXdpbmRvd09wdGlvbnMgb3B0czsKCglSZWdPcGVuS2V5RXgoIEhLRVlfQ1VSUkVOVF9VU0VSLCByZWdpc3RyeV9rZXksCgkgICAgICAgICAgICAgIDAsIEtFWV9RVUVSWV9WQUxVRSwgJmhLZXkgKTsKCglzaXplID0gc2l6ZW9mKERXT1JEKTsKCiAgICAgICAgaWYoIFJlZ1F1ZXJ5VmFsdWVFeCggaEtleSwgcmVnX3N0YXJ0X3gsIE5VTEwsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpICZvcHRzLnN0YXJ0X3gsICZzaXplICkgIT0gRVJST1JfU1VDQ0VTUyApCgkJb3B0cy5zdGFydF94ID0gQ1dfVVNFREVGQVVMVDsKCiAgICAgICAgaWYoIFJlZ1F1ZXJ5VmFsdWVFeCggaEtleSwgcmVnX3N0YXJ0X3ksIE5VTEwsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpICZvcHRzLnN0YXJ0X3ksICZzaXplICkgIT0gRVJST1JfU1VDQ0VTUyApCgkJb3B0cy5zdGFydF95ID0gQ1dfVVNFREVGQVVMVDsKCiAgICAgICAgaWYoIFJlZ1F1ZXJ5VmFsdWVFeCggaEtleSwgcmVnX3dpZHRoLCBOVUxMLCAmdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSAmb3B0cy53aWR0aCwgJnNpemUgKSAhPSBFUlJPUl9TVUNDRVNTICkKCQlvcHRzLndpZHRoID0gQ1dfVVNFREVGQVVMVDsKCiAgICAgICAgaWYoIFJlZ1F1ZXJ5VmFsdWVFeCggaEtleSwgcmVnX2hlaWdodCwgTlVMTCwgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQllURSkgJm9wdHMuaGVpZ2h0LCAmc2l6ZSApICE9IEVSUk9SX1NVQ0NFU1MgKQoJCW9wdHMuaGVpZ2h0ID0gQ1dfVVNFREVGQVVMVDsKCglSZWdDbG9zZUtleSggaEtleSApOwoKCXJldHVybiBvcHRzOwp9CgpzdGF0aWMgdm9pZCBzYXZlX3JlZ2lzdHJ5X3NldHRpbmdzKHZvaWQpCnsKCVdJTkRPV0lORk8gd2k7CglIS0VZIGhLZXk7CglJTlQgd2lkdGgsIGhlaWdodDsKCgl3aS5jYlNpemUgPSBzaXplb2YoIFdJTkRPV0lORk8gKTsKCUdldFdpbmRvd0luZm8oR2xvYmFscy5oTWFpblduZCwgJndpKTsKCXdpZHRoID0gd2kucmNXaW5kb3cucmlnaHQgLSB3aS5yY1dpbmRvdy5sZWZ0OwoJaGVpZ2h0ID0gd2kucmNXaW5kb3cuYm90dG9tIC0gd2kucmNXaW5kb3cudG9wOwoKCWlmICggUmVnT3BlbktleUV4KCBIS0VZX0NVUlJFTlRfVVNFUiwgcmVnaXN0cnlfa2V5LAoJICAgICAgICAgICAgICAgICAgIDAsIEtFWV9TRVRfVkFMVUUsICZoS2V5ICkgIT0gRVJST1JfU1VDQ0VTUyApCgl7CgkJLyogVW5hYmxlIHRvIHNhdmUgcmVnaXN0cnkgc2V0dGluZ3MgLSB0cnkgdG8gY3JlYXRlIGtleSAqLwoJCWlmICggUmVnQ3JlYXRlS2V5RXgoIEhLRVlfQ1VSUkVOVF9VU0VSLCByZWdpc3RyeV9rZXksCgkJICAgICAgICAgICAgICAgICAgICAgMCwgTlVMTCwgUkVHX09QVElPTl9OT05fVk9MQVRJTEUsCgkJICAgICAgICAgICAgICAgICAgICAgS0VZX1NFVF9WQUxVRSwgTlVMTCwgJmhLZXksIE5VTEwgKSAhPSBFUlJPUl9TVUNDRVNTICkKCQl7CgkJCS8qIEZJWE1FOiBDYW5ub3QgY3JlYXRlIGtleSAqLwoJCQlyZXR1cm47CgkJfQoJfQoJLyogU2F2ZSBhbGwgb2YgdGhlIHNldHRpbmdzICovCglSZWdTZXRWYWx1ZUV4KCBoS2V5LCByZWdfc3RhcnRfeCwgMCwgUkVHX0RXT1JELAoJICAgICAgICAgICAgICAgKExQQllURSkgJndpLnJjV2luZG93LmxlZnQsIHNpemVvZihEV09SRCkgKTsKCVJlZ1NldFZhbHVlRXgoIGhLZXksIHJlZ19zdGFydF95LCAwLCBSRUdfRFdPUkQsCgkgICAgICAgICAgICAgICAoTFBCWVRFKSAmd2kucmNXaW5kb3cudG9wLCBzaXplb2YoRFdPUkQpICk7CglSZWdTZXRWYWx1ZUV4KCBoS2V5LCByZWdfd2lkdGgsIDAsIFJFR19EV09SRCwKCSAgICAgICAgICAgICAgIChMUEJZVEUpICZ3aWR0aCwgc2l6ZW9mKERXT1JEKSApOwoJUmVnU2V0VmFsdWVFeCggaEtleSwgcmVnX2hlaWdodCwgMCwgUkVHX0RXT1JELAoJICAgICAgICAgICAgICAgKExQQllURSkgJmhlaWdodCwgc2l6ZW9mKERXT1JEKSApOwoKCS8qIFRPRE86IFNhdmUgbW9yZSBzZXR0aW5ncyBoZXJlIChMaXN0IHZzLiBEZXRhaWxlZCBWaWV3LCBldGMuKSAqLwoJUmVnQ2xvc2VLZXkoIGhLZXkgKTsKfQoKc3RhdGljIHZvaWQgcmVzaXplX2ZyYW1lX3JlY3QoSFdORCBod25kLCBQUkVDVCBwcmVjdCkKewoJaW50IG5ld190b3A7CglSRUNUIHJ0OwoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5odG9vbGJhcikpIHsKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmh0b29sYmFyLCBXTV9TSVpFLCAwLCAwKTsKCQlHZXRDbGllbnRSZWN0KEdsb2JhbHMuaHRvb2xiYXIsICZydCk7CgkJcHJlY3QtPnRvcCA9IHJ0LmJvdHRvbSszOwoJCXByZWN0LT5ib3R0b20gLT0gcnQuYm90dG9tKzM7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmhkcml2ZWJhcikpIHsKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgV01fU0laRSwgMCwgMCk7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmhkcml2ZWJhciwgJnJ0KTsKCQluZXdfdG9wID0gLS1wcmVjdC0+dG9wICsgcnQuYm90dG9tKzM7CgkJTW92ZVdpbmRvdyhHbG9iYWxzLmhkcml2ZWJhciwgMCwgcHJlY3QtPnRvcCwgcnQucmlnaHQsIG5ld190b3AsIFRSVUUpOwoJCXByZWN0LT50b3AgPSBuZXdfdG9wOwoJCXByZWN0LT5ib3R0b20gLT0gcnQuYm90dG9tKzI7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmhzdGF0dXNiYXIpKSB7CgkJaW50IHBhcnRzW10gPSB7MzAwLCA1MDB9OwoKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhzdGF0dXNiYXIsIFdNX1NJWkUsIDAsIDApOwoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaHN0YXR1c2JhciwgU0JfU0VUUEFSVFMsIDIsIChMUEFSQU0pJnBhcnRzKTsKCQlHZXRDbGllbnRSZWN0KEdsb2JhbHMuaHN0YXR1c2JhciwgJnJ0KTsKCQlwcmVjdC0+Ym90dG9tIC09IHJ0LmJvdHRvbTsKCX0KCglNb3ZlV2luZG93KEdsb2JhbHMuaG1kaWNsaWVudCwgcHJlY3QtPmxlZnQtMSxwcmVjdC0+dG9wLTEscHJlY3QtPnJpZ2h0KzIscHJlY3QtPmJvdHRvbSsxLCBUUlVFKTsKfQoKc3RhdGljIHZvaWQgcmVzaXplX2ZyYW1lKEhXTkQgaHduZCwgaW50IGN4LCBpbnQgY3kpCnsKCVJFQ1QgcmVjdDsKCglyZWN0LmxlZnQgICA9IDA7CglyZWN0LnRvcCAgICA9IDA7CglyZWN0LnJpZ2h0ICA9IGN4OwoJcmVjdC5ib3R0b20gPSBjeTsKCglyZXNpemVfZnJhbWVfcmVjdChod25kLCAmcmVjdCk7Cn0KCnN0YXRpYyB2b2lkIHJlc2l6ZV9mcmFtZV9jbGllbnQoSFdORCBod25kKQp7CglSRUNUIHJlY3Q7CgoJR2V0Q2xpZW50UmVjdChod25kLCAmcmVjdCk7CgoJcmVzaXplX2ZyYW1lX3JlY3QoaHduZCwgJnJlY3QpOwp9CgoKc3RhdGljIEhIT09LIGhjYnRob29rOwpzdGF0aWMgQ2hpbGRXbmQqIG5ld2NoaWxkID0gTlVMTDsKCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIENCVFByb2MoaW50IGNvZGUsIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCWlmIChjb2RlPT1IQ0JUX0NSRUFURVdORCAmJiBuZXdjaGlsZCkgewoJCUNoaWxkV25kKiBjaGlsZCA9IG5ld2NoaWxkOwoJCW5ld2NoaWxkID0gTlVMTDsKCgkJY2hpbGQtPmh3bmQgPSAoSFdORCkgd3BhcmFtOwoJCVNldFdpbmRvd0xvbmdQdHIoY2hpbGQtPmh3bmQsIEdXTFBfVVNFUkRBVEEsIChMUEFSQU0pY2hpbGQpOwoJfQoKCXJldHVybiBDYWxsTmV4dEhvb2tFeChoY2J0aG9vaywgY29kZSwgd3BhcmFtLCBscGFyYW0pOwp9CgpzdGF0aWMgSFdORCBjcmVhdGVfY2hpbGRfd2luZG93KENoaWxkV25kKiBjaGlsZCkKewoJTURJQ1JFQVRFU1RSVUNUIG1jczsKCWludCBpZHg7CgoJbWNzLnN6Q2xhc3MgPSBzV0lORUZJTEVUUkVFOwoJbWNzLnN6VGl0bGUgPSAoTFBUU1RSKWNoaWxkLT5wYXRoOwoJbWNzLmhPd25lciAgPSBHbG9iYWxzLmhJbnN0YW5jZTsKCW1jcy54ICAgICAgID0gY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmxlZnQ7CgltY3MueSAgICAgICA9IGNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi50b3A7CgltY3MuY3ggICAgICA9IGNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5yaWdodC1jaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ubGVmdDsKCW1jcy5jeSAgICAgID0gY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmJvdHRvbS1jaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24udG9wOwoJbWNzLnN0eWxlICAgPSAwOwoJbWNzLmxQYXJhbSAgPSAwOwoKCWhjYnRob29rID0gU2V0V2luZG93c0hvb2tFeChXSF9DQlQsIENCVFByb2MsIDAsIEdldEN1cnJlbnRUaHJlYWRJZCgpKTsKCgluZXdjaGlsZCA9IGNoaWxkOwoJY2hpbGQtPmh3bmQgPSAoSFdORCkgU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElDUkVBVEUsIDAsIChMUEFSQU0pJm1jcyk7CglpZiAoIWNoaWxkLT5od25kKSB7CgkJVW5ob29rV2luZG93c0hvb2tFeChoY2J0aG9vayk7CgkJcmV0dXJuIDA7Cgl9CgoJVW5ob29rV2luZG93c0hvb2tFeChoY2J0aG9vayk7CgoJU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZCwgTEJfU0VUSVRFTUhFSUdIVCwgMSwgbWF4KEdsb2JhbHMuc3BhY2VTaXplLmN5LElNQUdFX0hFSUdIVCszKSk7CglTZW5kTWVzc2FnZShjaGlsZC0+cmlnaHQuaHduZCwgTEJfU0VUSVRFTUhFSUdIVCwgMSwgbWF4KEdsb2JhbHMuc3BhY2VTaXplLmN5LElNQUdFX0hFSUdIVCszKSk7CgoJaWR4ID0gU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZCwgTEJfRklORFNUUklORywgMCwgKExQQVJBTSljaGlsZC0+bGVmdC5jdXIpOwoJU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZCwgTEJfU0VUQ1VSU0VMLCBpZHgsIDApOwoKCXJldHVybiBjaGlsZC0+aHduZDsKfQoKCnN0cnVjdCBFeGVjdXRlRGlhbG9nIHsKCVRDSEFSCWNtZFtNQVhfUEFUSF07CglpbnQJCWNtZHNob3c7Cn07CgpzdGF0aWMgSU5UX1BUUiBDQUxMQkFDSyBFeGVjdXRlRGlhbG9nRGxnUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJc3RhdGljIHN0cnVjdCBFeGVjdXRlRGlhbG9nKiBkbGc7CgoJc3dpdGNoKG5tc2cpIHsKCQljYXNlIFdNX0lOSVRESUFMT0c6CgkJCWRsZyA9IChzdHJ1Y3QgRXhlY3V0ZURpYWxvZyopIGxwYXJhbTsKCQkJcmV0dXJuIDE7CgoJCWNhc2UgV01fQ09NTUFORDogewoJCQlpbnQgaWQgPSAoaW50KXdwYXJhbTsKCgkJCWlmIChpZCA9PSBJRE9LKSB7CgkJCQlHZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgMjAxKSwgZGxnLT5jbWQsIE1BWF9QQVRIKTsKCQkJCWRsZy0+Y21kc2hvdyA9IGdldF9jaGVjayhod25kLDIxNCkgPyBTV19TSE9XTUlOSU1JWkVEIDogU1dfU0hPV05PUk1BTDsKCQkJCUVuZERpYWxvZyhod25kLCBpZCk7CgkJCX0gZWxzZSBpZiAoaWQgPT0gSURDQU5DRUwpCgkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoKCQkJcmV0dXJuIDE7fQoJfQoKCXJldHVybiAwOwp9CgoKc3RhdGljIElOVF9QVFIgQ0FMTEJBQ0sgRGVzdGluYXRpb25EbGdQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglUQ0hBUiBiMVtCVUZGRVJfTEVOXSwgYjJbQlVGRkVSX0xFTl07CgoJc3dpdGNoKG5tc2cpIHsKCQljYXNlIFdNX0lOSVRESUFMT0c6CgkJCVNldFdpbmRvd0xvbmdQdHIoaHduZCwgR1dMUF9VU0VSREFUQSwgbHBhcmFtKTsKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIDIwMSksIChMUENUU1RSKWxwYXJhbSk7CgkJCXJldHVybiAxOwoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJaW50IGlkID0gKGludCl3cGFyYW07CgoJCQlzd2l0Y2goaWQpIHsKCQkJICBjYXNlIElET0s6IHsKCQkJCUxQVFNUUiBkZXN0ID0gKExQVFNUUikgR2V0V2luZG93TG9uZ1B0cihod25kLCBHV0xQX1VTRVJEQVRBKTsKCQkJCUdldFdpbmRvd1RleHQoR2V0RGxnSXRlbShod25kLCAyMDEpLCBkZXN0LCBNQVhfUEFUSCk7CgkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoJCQkJYnJlYWs7fQoKCQkJICBjYXNlIElEQ0FOQ0VMOgoJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCQkJCWJyZWFrOwoKCQkJICBjYXNlIDI1NDoKCQkJCU1lc3NhZ2VCb3goaHduZCwgUlMoYjEsSURTX05PX0lNUEwpLCBSUyhiMixJRFNfV0lORUZJTEUpLCBNQl9PSyk7CgkJCQlicmVhazsKCQkJfQoKCQkJcmV0dXJuIDE7CgkJfQoJfQoKCXJldHVybiAwOwp9CgoKc3RydWN0IEZpbHRlckRpYWxvZyB7CglUQ0hBUglwYXR0ZXJuW01BWF9QQVRIXTsKCWludAkJZmxhZ3M7Cn07CgpzdGF0aWMgSU5UX1BUUiBDQUxMQkFDSyBGaWx0ZXJEaWFsb2dEbGdQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglzdGF0aWMgc3RydWN0IEZpbHRlckRpYWxvZyogZGxnOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9JTklURElBTE9HOgoJCQlkbGcgPSAoc3RydWN0IEZpbHRlckRpYWxvZyopIGxwYXJhbTsKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIElEQ19WSUVXX1BBVFRFUk4pLCBkbGctPnBhdHRlcm4pOwoJCQlzZXRfY2hlY2soaHduZCwgSURDX1ZJRVdfVFlQRV9ESVJFQ1RPUklFUywgZGxnLT5mbGFncyZURl9ESVJFQ1RPUklFUyk7CgkJCXNldF9jaGVjayhod25kLCBJRENfVklFV19UWVBFX1BST0dSQU1TLCBkbGctPmZsYWdzJlRGX1BST0dSQU1TKTsKCQkJc2V0X2NoZWNrKGh3bmQsIElEQ19WSUVXX1RZUEVfRE9DVU1FTlRTLCBkbGctPmZsYWdzJlRGX0RPQ1VNRU5UUyk7CgkJCXNldF9jaGVjayhod25kLCBJRENfVklFV19UWVBFX09USEVSUywgZGxnLT5mbGFncyZURl9PVEhFUlMpOwoJCQlzZXRfY2hlY2soaHduZCwgSURDX1ZJRVdfVFlQRV9ISURERU4sIGRsZy0+ZmxhZ3MmVEZfSElEREVOKTsKCQkJcmV0dXJuIDE7CgoJCWNhc2UgV01fQ09NTUFORDogewoJCQlpbnQgaWQgPSAoaW50KXdwYXJhbTsKCgkJCWlmIChpZCA9PSBJRE9LKSB7CgkJCQlpbnQgZmxhZ3MgPSAwOwoKCQkJCUdldFdpbmRvd1RleHQoR2V0RGxnSXRlbShod25kLCBJRENfVklFV19QQVRURVJOKSwgZGxnLT5wYXR0ZXJuLCBNQVhfUEFUSCk7CgoJCQkJZmxhZ3MgfD0gZ2V0X2NoZWNrKGh3bmQsIElEQ19WSUVXX1RZUEVfRElSRUNUT1JJRVMpID8gVEZfRElSRUNUT1JJRVMgOiAwOwoJCQkJZmxhZ3MgfD0gZ2V0X2NoZWNrKGh3bmQsIElEQ19WSUVXX1RZUEVfUFJPR1JBTVMpID8gVEZfUFJPR1JBTVMgOiAwOwoJCQkJZmxhZ3MgfD0gZ2V0X2NoZWNrKGh3bmQsIElEQ19WSUVXX1RZUEVfRE9DVU1FTlRTKSA/IFRGX0RPQ1VNRU5UUyA6IDA7CgkJCQlmbGFncyB8PSBnZXRfY2hlY2soaHduZCwgSURDX1ZJRVdfVFlQRV9PVEhFUlMpID8gVEZfT1RIRVJTIDogMDsKCQkJCWZsYWdzIHw9IGdldF9jaGVjayhod25kLCBJRENfVklFV19UWVBFX0hJRERFTikgPyBURl9ISURERU4gOiAwOwoKCQkJCWRsZy0+ZmxhZ3MgPSBmbGFnczsKCgkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoJCQl9IGVsc2UgaWYgKGlkID09IElEQ0FOQ0VMKQoJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCgkJCXJldHVybiAxO30KCX0KCglyZXR1cm4gMDsKfQoKCnN0cnVjdCBQcm9wZXJ0aWVzRGlhbG9nIHsKCVRDSEFSCXBhdGhbTUFYX1BBVEhdOwoJRW50cnkJZW50cnk7Cgl2b2lkKglwVmVyc2lvbkRhdGE7Cn07CgovKiBTdHJ1Y3R1cmUgdXNlZCB0byBzdG9yZSBlbnVtZXJhdGVkIGxhbmd1YWdlcyBhbmQgY29kZSBwYWdlcy4gKi8Kc3RydWN0IExBTkdBTkRDT0RFUEFHRSB7CglXT1JEIHdMYW5ndWFnZTsKCVdPUkQgd0NvZGVQYWdlOwp9ICpscFRyYW5zbGF0ZTsKCnN0YXRpYyBMUENTVFIgSW5mb1N0cmluZ3NbXSA9IHsKCSJDb21tZW50cyIsCgkiQ29tcGFueU5hbWUiLAoJIkZpbGVEZXNjcmlwdGlvbiIsCgkiRmlsZVZlcnNpb24iLAoJIkludGVybmFsTmFtZSIsCgkiTGVnYWxDb3B5cmlnaHQiLAoJIkxlZ2FsVHJhZGVtYXJrcyIsCgkiT3JpZ2luYWxGaWxlbmFtZSIsCgkiUHJpdmF0ZUJ1aWxkIiwKCSJQcm9kdWN0TmFtZSIsCgkiUHJvZHVjdFZlcnNpb24iLAoJIlNwZWNpYWxCdWlsZCIsCglOVUxMCn07CgpzdGF0aWMgdm9pZCBQcm9wRGxnX0Rpc3BsYXlWYWx1ZShIV05EIGhsYm94LCBIV05EIGhlZGl0KQp7CglpbnQgaWR4ID0gU2VuZE1lc3NhZ2UoaGxib3gsIExCX0dFVENVUlNFTCwgMCwgMCk7CgoJaWYgKGlkeCAhPSBMQl9FUlIpIHsKCQlMUENUU1RSIHBWYWx1ZSA9IChMUENUU1RSKSBTZW5kTWVzc2FnZShobGJveCwgTEJfR0VUSVRFTURBVEEsIGlkeCwgMCk7CgoJCWlmIChwVmFsdWUpCgkJCVNldFdpbmRvd1RleHQoaGVkaXQsIHBWYWx1ZSk7Cgl9Cn0KCnN0YXRpYyB2b2lkIENoZWNrRm9yRmlsZUluZm8oc3RydWN0IFByb3BlcnRpZXNEaWFsb2cqIGRsZywgSFdORCBod25kLCBMUENUU1RSIHN0ckZpbGVuYW1lKQp7CglzdGF0aWMgVENIQVIgc0JhY2tTbGFzaFtdID0geydcXCcsJ1wwJ307CglzdGF0aWMgVENIQVIgc1RyYW5zbGF0aW9uW10gPSB7J1xcJywnVicsJ2EnLCdyJywnRicsJ2knLCdsJywnZScsJ0knLCduJywnZicsJ28nLCdcXCcsJ1QnLCdyJywnYScsJ24nLCdzJywnbCcsJ2EnLCd0JywnaScsJ28nLCduJywnXDAnfTsKCXN0YXRpYyBUQ0hBUiBzU3RyaW5nRmlsZUluZm9bXSA9IHsnXFwnLCdTJywndCcsJ3InLCdpJywnbicsJ2cnLCdGJywnaScsJ2wnLCdlJywnSScsJ24nLCdmJywnbycsJ1xcJywKCQkJCQkJCQkJCSclJywnMCcsJzQnLCd4JywnJScsJzAnLCc0JywneCcsJ1xcJywnJScsJ3MnLCdcMCd9OwoJRFdPUkQgZHdWZXJzaW9uRGF0YUxlbiA9IEdldEZpbGVWZXJzaW9uSW5mb1NpemUoc3RyRmlsZW5hbWUsIE5VTEwpOwoKCWlmIChkd1ZlcnNpb25EYXRhTGVuKSB7CgkJZGxnLT5wVmVyc2lvbkRhdGEgPSBtYWxsb2MoZHdWZXJzaW9uRGF0YUxlbik7CgoJCWlmIChHZXRGaWxlVmVyc2lvbkluZm8oc3RyRmlsZW5hbWUsIDAsIGR3VmVyc2lvbkRhdGFMZW4sIGRsZy0+cFZlcnNpb25EYXRhKSkgewoJCQlMUFZPSUQgcFZhbDsKCQkJVUlOVCBuVmFsTGVuOwoKCQkJaWYgKFZlclF1ZXJ5VmFsdWUoZGxnLT5wVmVyc2lvbkRhdGEsIHNCYWNrU2xhc2gsICZwVmFsLCAmblZhbExlbikpIHsKCQkJCWlmIChuVmFsTGVuID09IHNpemVvZihWU19GSVhFREZJTEVJTkZPKSkgewoJCQkJCVZTX0ZJWEVERklMRUlORk8qIHBGaXhlZEZpbGVJbmZvID0gKFZTX0ZJWEVERklMRUlORk8qKXBWYWw7CgkJCQkJY2hhciBidWZmZXJbQlVGRkVSX0xFTl07CgoJCQkJCXNwcmludGYoYnVmZmVyLCAiJWQuJWQuJWQuJWQiLAoJCQkJCQlISVdPUkQocEZpeGVkRmlsZUluZm8tPmR3RmlsZVZlcnNpb25NUyksIExPV09SRChwRml4ZWRGaWxlSW5mby0+ZHdGaWxlVmVyc2lvbk1TKSwKCQkJCQkJSElXT1JEKHBGaXhlZEZpbGVJbmZvLT5kd0ZpbGVWZXJzaW9uTFMpLCBMT1dPUkQocEZpeGVkRmlsZUluZm8tPmR3RmlsZVZlcnNpb25MUykpOwoKCQkJCQlTZXREbGdJdGVtVGV4dEEoaHduZCwgSURDX1NUQVRJQ19QUk9QX1ZFUlNJT04sIGJ1ZmZlcik7CgkJCQl9CgkJCX0KCgkJCS8qIFJlYWQgdGhlIGxpc3Qgb2YgbGFuZ3VhZ2VzIGFuZCBjb2RlIHBhZ2VzLiAqLwoJCQlpZiAoVmVyUXVlcnlWYWx1ZShkbGctPnBWZXJzaW9uRGF0YSwgc1RyYW5zbGF0aW9uLCAmcFZhbCwgJm5WYWxMZW4pKSB7CgkJCQlzdHJ1Y3QgTEFOR0FORENPREVQQUdFKiBwVHJhbnNsYXRlID0gKHN0cnVjdCBMQU5HQU5EQ09ERVBBR0UqKXBWYWw7CgkJCQlzdHJ1Y3QgTEFOR0FORENPREVQQUdFKiBwRW5kID0gKHN0cnVjdCBMQU5HQU5EQ09ERVBBR0UqKSgoTFBCWVRFKXBWYWwrblZhbExlbik7CgoJCQkJSFdORCBobGJveCA9IEdldERsZ0l0ZW0oaHduZCwgSURDX0xJU1RfUFJPUF9WRVJTSU9OX1RZUEVTKTsKCgkJCQkvKiBSZWFkIHRoZSBmaWxlIGRlc2NyaXB0aW9uIGZvciBlYWNoIGxhbmd1YWdlIGFuZCBjb2RlIHBhZ2UuICovCgkJCQlmb3IoOyBwVHJhbnNsYXRlPHBFbmQ7ICsrcFRyYW5zbGF0ZSkgewoJCQkJCUxQQ1NUUiogcDsKCgkJCQkJZm9yKHA9SW5mb1N0cmluZ3M7ICpwOyArK3ApIHsKCQkJCQkJVENIQVIgc3ViYmxvY2tbMjAwXTsKI2lmZGVmIFVOSUNPREUKCQkJCQkJVENIQVIgaW5mb1N0clsxMDBdOwojZW5kaWYKCQkJCQkJTFBDVFNUUiBwVHh0OwoJCQkJCQlVSU5UIG5WYWxMZW47CgoJCQkJCQlMUENTVFIgcEluZm9TdHJpbmcgPSAqcDsKI2lmZGVmIFVOSUNPREUKCQkJCQkJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHBJbmZvU3RyaW5nLCAtMSwgaW5mb1N0ciwgMTAwKTsKI2Vsc2UKI2RlZmluZQlpbmZvU3RyIHBJbmZvU3RyaW5nCiNlbmRpZgoJCQkJCQl3c3ByaW50ZihzdWJibG9jaywgc1N0cmluZ0ZpbGVJbmZvLCBwVHJhbnNsYXRlLT53TGFuZ3VhZ2UsIHBUcmFuc2xhdGUtPndDb2RlUGFnZSwgaW5mb1N0cik7CgoJCQkJCQkvKiBSZXRyaWV2ZSBmaWxlIGRlc2NyaXB0aW9uIGZvciBsYW5ndWFnZSBhbmQgY29kZSBwYWdlICovCgkJCQkJCWlmIChWZXJRdWVyeVZhbHVlKGRsZy0+cFZlcnNpb25EYXRhLCBzdWJibG9jaywgKFBWT0lEKSZwVHh0LCAmblZhbExlbikpIHsKCQkJCQkJCWludCBpZHggPSBTZW5kTWVzc2FnZShobGJveCwgTEJfQUREU1RSSU5HLCAwTCwgKExQQVJBTSlpbmZvU3RyKTsKCQkJCQkJCVNlbmRNZXNzYWdlKGhsYm94LCBMQl9TRVRJVEVNREFUQSwgaWR4LCAoTFBBUkFNKSBwVHh0KTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCgkJCQlTZW5kTWVzc2FnZShobGJveCwgTEJfU0VUQ1VSU0VMLCAwLCAwKTsKCgkJCQlQcm9wRGxnX0Rpc3BsYXlWYWx1ZShobGJveCwgR2V0RGxnSXRlbShod25kLElEQ19MSVNUX1BST1BfVkVSU0lPTl9WQUxVRVMpKTsKCQkJfQoJCX0KCX0KfQoKc3RhdGljIElOVF9QVFIgQ0FMTEJBQ0sgUHJvcGVydGllc0RpYWxvZ0RsZ1Byb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCXN0YXRpYyBzdHJ1Y3QgUHJvcGVydGllc0RpYWxvZyogZGxnOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9JTklURElBTE9HOiB7CgkJCXN0YXRpYyBjb25zdCBUQ0hBUiBzQnl0ZUZtdFtdID0geyclJywncycsJyAnLCdCJywneScsJ3QnLCdlJywncycsJ1wwJ307CgkJCVRDSEFSIGIxW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCQkJTFBXSU4zMl9GSU5EX0RBVEEgcFdGRDsKCQkJVUxPTkdMT05HIHNpemU7CgoJCQlkbGcgPSAoc3RydWN0IFByb3BlcnRpZXNEaWFsb2cqKSBscGFyYW07CgkJCXBXRkQgPSAoTFBXSU4zMl9GSU5EX0RBVEEpICZkbGctPmVudHJ5LmRhdGE7CgoJCQlHZXRXaW5kb3dUZXh0KGh3bmQsIGIxLCBNQVhfUEFUSCk7CgkJCXdzcHJpbnRmKGIyLCBiMSwgcFdGRC0+Y0ZpbGVOYW1lKTsKCQkJU2V0V2luZG93VGV4dChod25kLCBiMik7CgoJCQlmb3JtYXRfZGF0ZSgmcFdGRC0+ZnRMYXN0V3JpdGVUaW1lLCBiMSwgQ09MX0RBVEV8Q09MX1RJTUUpOwoJCQlTZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgSURDX1NUQVRJQ19QUk9QX0xBU1RDSEFOR0UpLCBiMSk7CgoJCQlzaXplID0gKChVTE9OR0xPTkcpcFdGRC0+bkZpbGVTaXplSGlnaCA8PCAzMikgfCBwV0ZELT5uRmlsZVNpemVMb3c7CgkJCV9zdHByaW50ZihiMSwgc0xvbmdOdW1GbXQsIHNpemUpOwoJCQl3c3ByaW50ZihiMiwgc0J5dGVGbXQsIGIxKTsKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIElEQ19TVEFUSUNfUFJPUF9TSVpFKSwgYjIpOwoKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIElEQ19TVEFUSUNfUFJPUF9GSUxFTkFNRSksIHBXRkQtPmNGaWxlTmFtZSk7CgkJCVNldFdpbmRvd1RleHQoR2V0RGxnSXRlbShod25kLCBJRENfU1RBVElDX1BST1BfUEFUSCksIGRsZy0+cGF0aCk7CgoJCQlzZXRfY2hlY2soaHduZCwgSURDX0NIRUNLX1JFQURPTkxZLCBwV0ZELT5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX1JFQURPTkxZKTsKCQkJc2V0X2NoZWNrKGh3bmQsIElEQ19DSEVDS19BUkNISVZFLCBwV0ZELT5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0FSQ0hJVkUpOwoJCQlzZXRfY2hlY2soaHduZCwgSURDX0NIRUNLX0NPTVBSRVNTRUQsIHBXRkQtPmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfQ09NUFJFU1NFRCk7CgkJCXNldF9jaGVjayhod25kLCBJRENfQ0hFQ0tfSElEREVOLCBwV0ZELT5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0hJRERFTik7CgkJCXNldF9jaGVjayhod25kLCBJRENfQ0hFQ0tfU1lTVEVNLCBwV0ZELT5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX1NZU1RFTSk7CgoJCQlDaGVja0ZvckZpbGVJbmZvKGRsZywgaHduZCwgZGxnLT5wYXRoKTsKCQkJcmV0dXJuIDE7fQoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJaW50IGlkID0gKGludCl3cGFyYW07CgoJCQlzd2l0Y2goSElXT1JEKHdwYXJhbSkpIHsKCQkJICBjYXNlIExCTl9TRUxDSEFOR0U6IHsKCQkJCUhXTkQgaGxib3ggPSBHZXREbGdJdGVtKGh3bmQsIElEQ19MSVNUX1BST1BfVkVSU0lPTl9UWVBFUyk7CgkJCQlQcm9wRGxnX0Rpc3BsYXlWYWx1ZShobGJveCwgR2V0RGxnSXRlbShod25kLElEQ19MSVNUX1BST1BfVkVSU0lPTl9WQUxVRVMpKTsKCQkJCWJyZWFrOwoJCQkgIH0KCgkJCSAgY2FzZSBCTl9DTElDS0VEOgoJCQkJaWYgKGlkPT1JRE9LIHx8IGlkPT1JRENBTkNFTCkKCQkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoJCQl9CgoJCQlyZXR1cm4gMTt9CgoJCWNhc2UgV01fTkNERVNUUk9ZOgoJCQlmcmVlKGRsZy0+cFZlcnNpb25EYXRhKTsKCQkJZGxnLT5wVmVyc2lvbkRhdGEgPSBOVUxMOwoJCQlicmVhazsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgc2hvd19wcm9wZXJ0aWVzX2RsZyhFbnRyeSogZW50cnksIEhXTkQgaHduZCkKewoJc3RydWN0IFByb3BlcnRpZXNEaWFsb2cgZGxnOwoKCW1lbXNldCgmZGxnLCAwLCBzaXplb2Yoc3RydWN0IFByb3BlcnRpZXNEaWFsb2cpKTsKCWdldF9wYXRoKGVudHJ5LCBkbGcucGF0aCk7CgltZW1jcHkoJmRsZy5lbnRyeSwgZW50cnksIHNpemVvZihFbnRyeSkpOwoKCURpYWxvZ0JveFBhcmFtKEdsb2JhbHMuaEluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSUREX0RJQUxPR19QUk9QRVJUSUVTKSwgaHduZCwgUHJvcGVydGllc0RpYWxvZ0RsZ1Byb2MsIChMUEFSQU0pJmRsZyk7Cn0KCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgpzdGF0aWMgc3RydWN0IEZ1bGxTY3JlZW5QYXJhbWV0ZXJzIHsKCUJPT0wJbW9kZTsKCVJFQ1QJb3JnUG9zOwoJQk9PTAl3YXNab29tZWQ7Cn0gZ19mdWxsc2NyZWVuID0gewogICAgRkFMU0UsCS8qIG1vZGUgKi8KCXswLCAwLCAwLCAwfSwKCUZBTFNFCn07CgpzdGF0aWMgdm9pZCBmcmFtZV9nZXRfY2xpZW50c3BhY2UoSFdORCBod25kLCBQUkVDVCBwcmVjdCkKewoJUkVDVCBydDsKCglpZiAoIUlzSWNvbmljKGh3bmQpKQoJCUdldENsaWVudFJlY3QoaHduZCwgcHJlY3QpOwoJZWxzZSB7CgkJV0lORE9XUExBQ0VNRU5UIHdwOwoKCQlHZXRXaW5kb3dQbGFjZW1lbnQoaHduZCwgJndwKTsKCgkJcHJlY3QtPmxlZnQgPSBwcmVjdC0+dG9wID0gMDsKCQlwcmVjdC0+cmlnaHQgPSB3cC5yY05vcm1hbFBvc2l0aW9uLnJpZ2h0LXdwLnJjTm9ybWFsUG9zaXRpb24ubGVmdC0KCQkJCQkJMiooR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkVGUkFNRSkrR2V0U3lzdGVtTWV0cmljcyhTTV9DWEVER0UpKTsKCQlwcmVjdC0+Ym90dG9tID0gd3AucmNOb3JtYWxQb3NpdGlvbi5ib3R0b20td3AucmNOb3JtYWxQb3NpdGlvbi50b3AtCgkJCQkJCTIqKEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFRlJBTUUpK0dldFN5c3RlbU1ldHJpY3MoU01fQ1lFREdFKSktCgkJCQkJCUdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKS1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZTUVOVVNJWkUpOwoJfQoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5odG9vbGJhcikpIHsKCQlHZXRDbGllbnRSZWN0KEdsb2JhbHMuaHRvb2xiYXIsICZydCk7CgkJcHJlY3QtPnRvcCArPSBydC5ib3R0b20rMjsKCX0KCglpZiAoSXNXaW5kb3dWaXNpYmxlKEdsb2JhbHMuaGRyaXZlYmFyKSkgewoJCUdldENsaWVudFJlY3QoR2xvYmFscy5oZHJpdmViYXIsICZydCk7CgkJcHJlY3QtPnRvcCArPSBydC5ib3R0b20rMjsKCX0KCglpZiAoSXNXaW5kb3dWaXNpYmxlKEdsb2JhbHMuaHN0YXR1c2JhcikpIHsKCQlHZXRDbGllbnRSZWN0KEdsb2JhbHMuaHN0YXR1c2JhciwgJnJ0KTsKCQlwcmVjdC0+Ym90dG9tIC09IHJ0LmJvdHRvbTsKCX0KfQoKc3RhdGljIEJPT0wgdG9nZ2xlX2Z1bGxzY3JlZW4oSFdORCBod25kKQp7CglSRUNUIHJ0OwoKCWlmICgoZ19mdWxsc2NyZWVuLm1vZGU9IWdfZnVsbHNjcmVlbi5tb2RlKSkgewoJCUdldFdpbmRvd1JlY3QoaHduZCwgJmdfZnVsbHNjcmVlbi5vcmdQb3MpOwoJCWdfZnVsbHNjcmVlbi53YXNab29tZWQgPSBJc1pvb21lZChod25kKTsKCgkJRnJhbWVfQ2FsY0ZyYW1lQ2xpZW50KGh3bmQsICZydCk7CgkJQ2xpZW50VG9TY3JlZW4oaHduZCwgKExQUE9JTlQpJnJ0LmxlZnQpOwoJCUNsaWVudFRvU2NyZWVuKGh3bmQsIChMUFBPSU5UKSZydC5yaWdodCk7CgoJCXJ0LmxlZnQgPSBnX2Z1bGxzY3JlZW4ub3JnUG9zLmxlZnQtcnQubGVmdDsKCQlydC50b3AgPSBnX2Z1bGxzY3JlZW4ub3JnUG9zLnRvcC1ydC50b3A7CgkJcnQucmlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKStnX2Z1bGxzY3JlZW4ub3JnUG9zLnJpZ2h0LXJ0LnJpZ2h0OwoJCXJ0LmJvdHRvbSA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pK2dfZnVsbHNjcmVlbi5vcmdQb3MuYm90dG9tLXJ0LmJvdHRvbTsKCgkJTW92ZVdpbmRvdyhod25kLCBydC5sZWZ0LCBydC50b3AsIHJ0LnJpZ2h0LXJ0LmxlZnQsIHJ0LmJvdHRvbS1ydC50b3AsIFRSVUUpOwoJfSBlbHNlIHsKCQlNb3ZlV2luZG93KGh3bmQsIGdfZnVsbHNjcmVlbi5vcmdQb3MubGVmdCwgZ19mdWxsc2NyZWVuLm9yZ1Bvcy50b3AsCgkJCQkJCQlnX2Z1bGxzY3JlZW4ub3JnUG9zLnJpZ2h0LWdfZnVsbHNjcmVlbi5vcmdQb3MubGVmdCwKCQkJCQkJCWdfZnVsbHNjcmVlbi5vcmdQb3MuYm90dG9tLWdfZnVsbHNjcmVlbi5vcmdQb3MudG9wLCBUUlVFKTsKCgkJaWYgKGdfZnVsbHNjcmVlbi53YXNab29tZWQpCgkJCVNob3dXaW5kb3coaHduZCwgV1NfTUFYSU1JWkUpOwoJfQoKCXJldHVybiBnX2Z1bGxzY3JlZW4ubW9kZTsKfQoKc3RhdGljIHZvaWQgZnVsbHNjcmVlbl9tb3ZlKEhXTkQgaHduZCkKewoJUkVDVCBydCwgcG9zOwoJR2V0V2luZG93UmVjdChod25kLCAmcG9zKTsKCglGcmFtZV9DYWxjRnJhbWVDbGllbnQoaHduZCwgJnJ0KTsKCUNsaWVudFRvU2NyZWVuKGh3bmQsIChMUFBPSU5UKSZydC5sZWZ0KTsKCUNsaWVudFRvU2NyZWVuKGh3bmQsIChMUFBPSU5UKSZydC5yaWdodCk7CgoJcnQubGVmdCA9IHBvcy5sZWZ0LXJ0LmxlZnQ7CglydC50b3AgPSBwb3MudG9wLXJ0LnRvcDsKCXJ0LnJpZ2h0ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTikrcG9zLnJpZ2h0LXJ0LnJpZ2h0OwoJcnQuYm90dG9tID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTikrcG9zLmJvdHRvbS1ydC5ib3R0b207CgoJTW92ZVdpbmRvdyhod25kLCBydC5sZWZ0LCBydC50b3AsIHJ0LnJpZ2h0LXJ0LmxlZnQsIHJ0LmJvdHRvbS1ydC50b3AsIFRSVUUpOwp9CgojZW5kaWYKCgpzdGF0aWMgdm9pZCB0b2dnbGVfY2hpbGQoSFdORCBod25kLCBVSU5UIGNtZCwgSFdORCBoY2hpbGQpCnsKCUJPT0wgdmlzID0gSXNXaW5kb3dWaXNpYmxlKGhjaGlsZCk7CgoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgY21kLCB2aXM/TUZfQllDT01NQU5EOk1GX0JZQ09NTUFORHxNRl9DSEVDS0VEKTsKCglTaG93V2luZG93KGhjaGlsZCwgdmlzP1NXX0hJREU6U1dfU0hPVyk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCglpZiAoZ19mdWxsc2NyZWVuLm1vZGUpCgkJZnVsbHNjcmVlbl9tb3ZlKGh3bmQpOwojZW5kaWYKCglyZXNpemVfZnJhbWVfY2xpZW50KGh3bmQpOwp9CgpzdGF0aWMgQk9PTCBhY3RpdmF0ZV9kcml2ZV93aW5kb3coTFBDVFNUUiBwYXRoKQp7CglUQ0hBUiBkcnYxW19NQVhfRFJJVkVdLCBkcnYyW19NQVhfRFJJVkVdOwoJSFdORCBjaGlsZF93bmQ7CgoJX3RzcGxpdHBhdGgocGF0aCwgZHJ2MSwgMCwgMCwgMCk7CgoJLyogc2VhcmNoIGZvciBhIGFscmVhZHkgb3BlbiB3aW5kb3cgZm9yIHRoZSBzYW1lIGRyaXZlICovCglmb3IoY2hpbGRfd25kPUdldE5leHRXaW5kb3coR2xvYmFscy5obWRpY2xpZW50LEdXX0NISUxEKTsgY2hpbGRfd25kOyBjaGlsZF93bmQ9R2V0TmV4dFdpbmRvdyhjaGlsZF93bmQsIEdXX0hXTkRORVhUKSkgewoJCUNoaWxkV25kKiBjaGlsZCA9IChDaGlsZFduZCopIEdldFdpbmRvd0xvbmdQdHIoY2hpbGRfd25kLCBHV0xQX1VTRVJEQVRBKTsKCgkJaWYgKGNoaWxkKSB7CgkJCV90c3BsaXRwYXRoKGNoaWxkLT5yb290LnBhdGgsIGRydjIsIDAsIDAsIDApOwoKCQkJaWYgKCFsc3RyY21waShkcnYyLCBkcnYxKSkgewoJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElBQ1RJVkFURSwgKFdQQVJBTSljaGlsZF93bmQsIDApOwoKCQkJCWlmIChJc0ljb25pYyhjaGlsZF93bmQpKQoJCQkJCVNob3dXaW5kb3coY2hpbGRfd25kLCBTV19TSE9XTk9STUFMKTsKCgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBCT09MIGFjdGl2YXRlX2ZzX3dpbmRvdyhMUENUU1RSIGZpbGVzeXMpCnsKCUhXTkQgY2hpbGRfd25kOwoKCS8qIHNlYXJjaCBmb3IgYSBhbHJlYWR5IG9wZW4gd2luZG93IG9mIHRoZSBnaXZlbiBmaWxlIHN5c3RlbSBuYW1lICovCglmb3IoY2hpbGRfd25kPUdldE5leHRXaW5kb3coR2xvYmFscy5obWRpY2xpZW50LEdXX0NISUxEKTsgY2hpbGRfd25kOyBjaGlsZF93bmQ9R2V0TmV4dFdpbmRvdyhjaGlsZF93bmQsIEdXX0hXTkRORVhUKSkgewoJCUNoaWxkV25kKiBjaGlsZCA9IChDaGlsZFduZCopIEdldFdpbmRvd0xvbmdQdHIoY2hpbGRfd25kLCBHV0xQX1VTRVJEQVRBKTsKCgkJaWYgKGNoaWxkKSB7CgkJCWlmICghbHN0cmNtcGkoY2hpbGQtPnJvb3QuZnMsIGZpbGVzeXMpKSB7CgkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESUFDVElWQVRFLCAoV1BBUkFNKWNoaWxkX3duZCwgMCk7CgoJCQkJaWYgKElzSWNvbmljKGNoaWxkX3duZCkpCgkJCQkJU2hvd1dpbmRvdyhjaGlsZF93bmQsIFNXX1NIT1dOT1JNQUwpOwoKCQkJCXJldHVybiBUUlVFOwoJCQl9CgkJfQoJfQoKCXJldHVybiBGQUxTRTsKfQoKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgRnJhbWVXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglUQ0hBUiBiMVtCVUZGRVJfTEVOXSwgYjJbQlVGRkVSX0xFTl07CgoJc3dpdGNoKG5tc2cpIHsKCQljYXNlIFdNX0NMT1NFOgoJCQlpZiAoR2xvYmFscy5zYXZlU2V0dGluZ3MgPT0gVFJVRSkgIAoJCQkJc2F2ZV9yZWdpc3RyeV9zZXR0aW5ncygpOyAgCgkJCQoJCQlEZXN0cm95V2luZG93KGh3bmQpOwoKCQkJIC8qIGNsZWFyIGhhbmRsZSB2YXJpYWJsZXMgKi8KCQkJR2xvYmFscy5oTWVudUZyYW1lID0gMDsKCQkJR2xvYmFscy5oTWVudVZpZXcgPSAwOwoJCQlHbG9iYWxzLmhNZW51T3B0aW9ucyA9IDA7CgkJCUdsb2JhbHMuaE1haW5XbmQgPSAwOwoJCQlHbG9iYWxzLmhtZGljbGllbnQgPSAwOwoJCQlHbG9iYWxzLmhkcml2ZWJhciA9IDA7CgkJCWJyZWFrOwoKCQljYXNlIFdNX0RFU1RST1k6CgkJCVBvc3RRdWl0TWVzc2FnZSgwKTsKCQkJYnJlYWs7CgoJCWNhc2UgV01fSU5JVE1FTlVQT1BVUDogewoJCQlIV05EIGh3bmRDbGllbnQgPSAoSFdORCkgU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElHRVRBQ1RJVkUsIDAsIDApOwoKCQkJaWYgKCFTZW5kTWVzc2FnZShod25kQ2xpZW50LCBXTV9JTklUTUVOVVBPUFVQLCB3cGFyYW0sIGxwYXJhbSkpCgkJCQlyZXR1cm4gMDsKCQkJYnJlYWs7fQoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJVUlOVCBjbWQgPSBMT1dPUkQod3BhcmFtKTsKCQkJSFdORCBod25kQ2xpZW50ID0gKEhXTkQpIFNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJR0VUQUNUSVZFLCAwLCAwKTsKCgkJCWlmIChTZW5kTWVzc2FnZShod25kQ2xpZW50LCBXTV9ESVNQQVRDSF9DT01NQU5ELCB3cGFyYW0sIGxwYXJhbSkpCgkJCQlicmVhazsKCgkJCWlmIChjbWQ+PUlEX0RSSVZFX0ZJUlNUICYmIGNtZDw9SURfRFJJVkVfRklSU1QrMHhGRikgewoJCQkJVENIQVIgZHJ2W19NQVhfRFJJVkVdLCBwYXRoW01BWF9QQVRIXTsKCQkJCUNoaWxkV25kKiBjaGlsZDsKCQkJCUxQQ1RTVFIgcm9vdCA9IEdsb2JhbHMuZHJpdmVzOwoJCQkJaW50IGk7CgoJCQkJZm9yKGk9Y21kLUlEX0RSSVZFX0ZJUlNUOyBpLS07IHJvb3QrKykKCQkJCQl3aGlsZSgqcm9vdCkKCQkJCQkJcm9vdCsrOwoKCQkJCWlmIChhY3RpdmF0ZV9kcml2ZV93aW5kb3cocm9vdCkpCgkJCQkJcmV0dXJuIDA7CgoJCQkJX3RzcGxpdHBhdGgocm9vdCwgZHJ2LCAwLCAwLCAwKTsKCgkJCQlpZiAoIVNldEN1cnJlbnREaXJlY3RvcnkoZHJ2KSkgewoJCQkJCWRpc3BsYXlfZXJyb3IoaHduZCwgR2V0TGFzdEVycm9yKCkpOwoJCQkJCXJldHVybiAwOwoJCQkJfQoKCQkJCUdldEN1cnJlbnREaXJlY3RvcnkoTUFYX1BBVEgsIHBhdGgpOyAvKlRPRE86IHN0b3JlIGxhc3QgZGlyZWN0b3J5IHBlciBkcml2ZSAqLwoJCQkJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgTlVMTCwgaHduZCk7CgoJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQkJCQlmcmVlKGNoaWxkKTsKCQkJfSBlbHNlIHN3aXRjaChjbWQpIHsKCQkJCWNhc2UgSURfRklMRV9FWElUOgoJCQkJCVNlbmRNZXNzYWdlKGh3bmQsIFdNX0NMT1NFLCAwLCAwKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1dJTkRPV19ORVc6IHsKCQkJCQlUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCQkJCQlDaGlsZFduZCogY2hpbGQ7CgoJCQkJCUdldEN1cnJlbnREaXJlY3RvcnkoTUFYX1BBVEgsIHBhdGgpOwoJCQkJCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIE5VTEwsIGh3bmQpOwoKCQkJCQlpZiAoIWNyZWF0ZV9jaGlsZF93aW5kb3coY2hpbGQpKQoJCQkJCQlmcmVlKGNoaWxkKTsKCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9SRUZSRVNIOgoJCQkJCXJlZnJlc2hfZHJpdmVzKCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9XSU5ET1dfQ0FTQ0FERToKCQkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESUNBU0NBREUsIDAsIDApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfV0lORE9XX1RJTEVfSE9SWjoKCQkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESVRJTEUsIE1ESVRJTEVfSE9SSVpPTlRBTCwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9XSU5ET1dfVElMRV9WRVJUOgoJCQkJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJVElMRSwgTURJVElMRV9WRVJUSUNBTCwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9XSU5ET1dfQVJSQU5HRToKCQkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESUlDT05BUlJBTkdFLCAwLCAwKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1NFTEVDVF9GT05UOiB7CgkJCQkJVENIQVIgZGxnX25hbWVbQlVGRkVSX0xFTl0sIGRsZ19pbmZvW0JVRkZFUl9MRU5dOwoJCQkJCUNIT09TRUZPTlQgY2hGb250OwoJCQkJCUxPR0ZPTlQgbEZvbnQ7CgoJCQkJCUhEQyBoZGMgPSBHZXREQyhod25kKTsKCQkJCQljaEZvbnQubFN0cnVjdFNpemUgPSBzaXplb2YoQ0hPT1NFRk9OVCk7CgkJCQkJY2hGb250Lmh3bmRPd25lciA9IGh3bmQ7CgkJCQkJY2hGb250LmhEQyA9IE5VTEw7CgkJCQkJY2hGb250LmxwTG9nRm9udCA9ICZsRm9udDsKCQkJCQljaEZvbnQuRmxhZ3MgPSBDRl9TQ1JFRU5GT05UUyB8IENGX0ZPUkNFRk9OVEVYSVNUIHwgQ0ZfTElNSVRTSVpFIHwgQ0ZfTk9TQ1JJUFRTRUw7CgkJCQkJY2hGb250LnJnYkNvbG9ycyA9IFJHQigwLDAsMCk7CgkJCQkJY2hGb250LmxDdXN0RGF0YSA9IDA7CgkJCQkJY2hGb250LmxwZm5Ib29rID0gTlVMTDsKCQkJCQljaEZvbnQubHBUZW1wbGF0ZU5hbWUgPSBOVUxMOwoJCQkJCWNoRm9udC5oSW5zdGFuY2UgPSBHbG9iYWxzLmhJbnN0YW5jZTsKCQkJCQljaEZvbnQubHBzelN0eWxlID0gTlVMTDsKCQkJCQljaEZvbnQubkZvbnRUeXBlID0gU0lNVUxBVEVEX0ZPTlRUWVBFOwoJCQkJCWNoRm9udC5uU2l6ZU1pbiA9IDA7CgkJCQkJY2hGb250Lm5TaXplTWF4ID0gMjQ7CgoJCQkJCWlmIChDaG9vc2VGb250KCZjaEZvbnQpKSB7CgkJCQkJCUhXTkQgY2hpbGRXbmQ7CgkJCQkJCUhGT05UIGhGb250T2xkOwoKCQkJCQkJRGVsZXRlT2JqZWN0KEdsb2JhbHMuaGZvbnQpOwoJCQkJCQlHbG9iYWxzLmhmb250ID0gQ3JlYXRlRm9udEluZGlyZWN0KCZsRm9udCk7CgkJCQkJCWhGb250T2xkID0gU2VsZWN0T2JqZWN0KGhkYywgR2xvYmFscy5oZm9udCk7CgkJCQkJCUdldFRleHRFeHRlbnRQb2ludDMyKGhkYywgc1NwYWNlLCAxLCAmR2xvYmFscy5zcGFjZVNpemUpOwoKCQkJCQkJLyogY2hhbmdlIGZvbnQgaW4gYWxsIG9wZW4gY2hpbGQgd2luZG93cyAqLwoJCQkJCQlmb3IoY2hpbGRXbmQ9R2V0V2luZG93KEdsb2JhbHMuaG1kaWNsaWVudCxHV19DSElMRCk7IGNoaWxkV25kOyBjaGlsZFduZD1HZXROZXh0V2luZG93KGNoaWxkV25kLEdXX0hXTkRORVhUKSkgewoJCQkJCQkJQ2hpbGRXbmQqIGNoaWxkID0gKENoaWxkV25kKikgR2V0V2luZG93TG9uZ1B0cihjaGlsZFduZCwgR1dMUF9VU0VSREFUQSk7CgkJCQkJCQlTZW5kTWVzc2FnZShjaGlsZC0+bGVmdC5od25kLCBXTV9TRVRGT05ULCAoV1BBUkFNKUdsb2JhbHMuaGZvbnQsIFRSVUUpOwoJCQkJCQkJU2VuZE1lc3NhZ2UoY2hpbGQtPnJpZ2h0Lmh3bmQsIFdNX1NFVEZPTlQsIChXUEFSQU0pR2xvYmFscy5oZm9udCwgVFJVRSk7CgkJCQkJCQlTZW5kTWVzc2FnZShjaGlsZC0+bGVmdC5od25kLCBMQl9TRVRJVEVNSEVJR0hULCAxLCBtYXgoR2xvYmFscy5zcGFjZVNpemUuY3ksSU1BR0VfSEVJR0hUKzMpKTsKCQkJCQkJCVNlbmRNZXNzYWdlKGNoaWxkLT5yaWdodC5od25kLCBMQl9TRVRJVEVNSEVJR0hULCAxLCBtYXgoR2xvYmFscy5zcGFjZVNpemUuY3ksSU1BR0VfSEVJR0hUKzMpKTsKCQkJCQkJCUludmFsaWRhdGVSZWN0KGNoaWxkLT5sZWZ0Lmh3bmQsIE5VTEwsIFRSVUUpOwoJCQkJCQkJSW52YWxpZGF0ZVJlY3QoY2hpbGQtPnJpZ2h0Lmh3bmQsIE5VTEwsIFRSVUUpOwoJCQkJCQl9CgoJCQkJCQlTZWxlY3RPYmplY3QoaGRjLCBoRm9udE9sZCk7CgkJCQkJfQoJCQkJCWVsc2UgaWYgKENvbW1EbGdFeHRlbmRlZEVycm9yKCkpIHsKCQkJCQkJTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX0ZPTlRfU0VMX0RMR19OQU1FLCBkbGdfbmFtZSwgQlVGRkVSX0xFTik7CgkJCQkJCUxvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19GT05UX1NFTF9FUlJPUiwgZGxnX2luZm8sIEJVRkZFUl9MRU4pOwoJCQkJCQlNZXNzYWdlQm94KGh3bmQsIGRsZ19pbmZvLCBkbGdfbmFtZSwgTUJfT0spOwoJCQkJCX0KCgkJCQkJUmVsZWFzZURDKGh3bmQsIGhkYyk7CgkJCQkJYnJlYWs7CgkJCQl9CgoJCQkJY2FzZSBJRF9WSUVXX1RPT0xfQkFSOgoJCQkJCXRvZ2dsZV9jaGlsZChod25kLCBjbWQsIEdsb2JhbHMuaHRvb2xiYXIpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19EUklWRV9CQVI6CgkJCQkJdG9nZ2xlX2NoaWxkKGh3bmQsIGNtZCwgR2xvYmFscy5oZHJpdmViYXIpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19TVEFUVVNCQVI6CgkJCQkJdG9nZ2xlX2NoaWxkKGh3bmQsIGNtZCwgR2xvYmFscy5oc3RhdHVzYmFyKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1ZJRVdfU0FWRVNFVFRJTkdTOgoJCQkJCUdsb2JhbHMuc2F2ZVNldHRpbmdzID0gIUdsb2JhbHMuc2F2ZVNldHRpbmdzOwoJCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudU9wdGlvbnMsIElEX1ZJRVdfU0FWRVNFVFRJTkdTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHbG9iYWxzLnNhdmVTZXR0aW5ncyA9PSBUUlVFID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfRVhFQ1VURTogewoJCQkJCXN0cnVjdCBFeGVjdXRlRGlhbG9nIGRsZzsKCgkJCQkJbWVtc2V0KCZkbGcsIDAsIHNpemVvZihzdHJ1Y3QgRXhlY3V0ZURpYWxvZykpOwoKCQkJCQlpZiAoRGlhbG9nQm94UGFyYW0oR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRERfRVhFQ1VURSksIGh3bmQsIEV4ZWN1dGVEaWFsb2dEbGdQcm9jLCAoTFBBUkFNKSZkbGcpID09IElET0spIHsKCQkJCQkJSElOU1RBTkNFIGhpbnN0ID0gU2hlbGxFeGVjdXRlKGh3bmQsIE5VTEwvKm9wZXJhdGlvbiovLCBkbGcuY21kLypmaWxlKi8sIE5VTEwvKnBhcmFtZXRlcnMqLywgTlVMTC8qZGlyKi8sIGRsZy5jbWRzaG93KTsKCgkJCQkJCWlmICgoaW50KWhpbnN0IDw9IDMyKQoJCQkJCQkJZGlzcGxheV9lcnJvcihod25kLCBHZXRMYXN0RXJyb3IoKSk7CgkJCQkJfQoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX0NPTk5FQ1RfTkVUV09SS19EUklWRTogewoJCQkJCURXT1JEIHJldCA9IFdOZXRDb25uZWN0aW9uRGlhbG9nKGh3bmQsIFJFU09VUkNFVFlQRV9ESVNLKTsKCQkJCQlpZiAocmV0ID09IE5PX0VSUk9SKQoJCQkJCQlyZWZyZXNoX2RyaXZlcygpOwoJCQkJCWVsc2UgaWYgKHJldCAhPSAoRFdPUkQpLTEpIHsKCQkJCQkJaWYgKHJldCA9PSBFUlJPUl9FWFRFTkRFRF9FUlJPUikKCQkJCQkJCWRpc3BsYXlfbmV0d29ya19lcnJvcihod25kKTsKCQkJCQkJZWxzZQoJCQkJCQkJZGlzcGxheV9lcnJvcihod25kLCByZXQpOwoJCQkJCX0KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9ESVNDT05ORUNUX05FVFdPUktfRFJJVkU6IHsKCQkJCQlEV09SRCByZXQgPSBXTmV0RGlzY29ubmVjdERpYWxvZyhod25kLCBSRVNPVVJDRVRZUEVfRElTSyk7CgkJCQkJaWYgKHJldCA9PSBOT19FUlJPUikKCQkJCQkJcmVmcmVzaF9kcml2ZXMoKTsKCQkJCQllbHNlIGlmIChyZXQgIT0gKERXT1JEKS0xKSB7CgkJCQkJCWlmIChyZXQgPT0gRVJST1JfRVhURU5ERURfRVJST1IpCgkJCQkJCQlkaXNwbGF5X25ldHdvcmtfZXJyb3IoaHduZCk7CgkJCQkJCWVsc2UKCQkJCQkJCWRpc3BsYXlfZXJyb3IoaHduZCwgcmV0KTsKCQkJCQl9CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfRk9STUFUX0RJU0s6IHsKCQkJCQlVSU5UIHNlbV9vcmcgPSBTZXRFcnJvck1vZGUoMCk7IC8qIEdldCB0aGUgY3VycmVudCBFcnJvciBNb2RlIHNldHRpbmdzLiAqLwoJCQkJCVNldEVycm9yTW9kZShzZW1fb3JnICYgflNFTV9GQUlMQ1JJVElDQUxFUlJPUlMpOyAvKiBGb3JjZSBPL1MgdG8gaGFuZGxlICovCgkJCQkJU0hGb3JtYXREcml2ZShod25kLCAwIC8qIEE6ICovLCBTSEZNVF9JRF9ERUZBVUxULCAwKTsKCQkJCQlTZXRFcnJvck1vZGUoc2VtX29yZyk7IC8qIFB1dCBpdCBiYWNrIHRoZSB3YXkgaXQgd2FzLiAqLwoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX0hFTFA6CgkJCQkJV2luSGVscChod25kLCBSUyhiMSxJRFNfV0lORUZJTEUpLCBIRUxQX0lOREVYLCAwKTsKCQkJCQlicmVhazsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJCWNhc2UgSURfVklFV19GVUxMU0NSRUVOOgoJCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudU9wdGlvbnMsIGNtZCwgdG9nZ2xlX2Z1bGxzY3JlZW4oaHduZCk/TUZfQ0hFQ0tFRDowKTsKCQkJCQlicmVhazsKCiNpZmRlZiBfX1dJTkVfXwoJCQkJY2FzZSBJRF9EUklWRV9VTklYX0ZTOiB7CgkJCQkJVENIQVIgcGF0aFtNQVhfUEFUSF07CiNpZmRlZiBVTklDT0RFCgkJCQkJY2hhciBjcGF0aFtNQVhfUEFUSF07CiNlbmRpZgoJCQkJCUNoaWxkV25kKiBjaGlsZDsKCgkJCQkJaWYgKGFjdGl2YXRlX2ZzX3dpbmRvdyhSUyhiMSxJRFNfVU5JWEZTKSkpCgkJCQkJCWJyZWFrOwoKI2lmZGVmIFVOSUNPREUKCQkJCQlnZXRjd2QoY3BhdGgsIE1BWF9QQVRIKTsKCQkJCQlNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX1VOSVhDUCwgMCwgY3BhdGgsIC0xLCBwYXRoLCBNQVhfUEFUSCk7CiNlbHNlCgkJCQkJZ2V0Y3dkKHBhdGgsIE1BWF9QQVRIKTsKI2VuZGlmCgkJCQkJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgTlVMTCwgaHduZCk7CgoJCQkJCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhjaGlsZCkpCgkJCQkJCWZyZWUoY2hpbGQpOwoJCQkJCWJyZWFrO30KI2VuZGlmCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJCQkJY2FzZSBJRF9EUklWRV9TSEVMTF9OUzogewoJCQkJCVRDSEFSIHBhdGhbTUFYX1BBVEhdOwoJCQkJCUNoaWxkV25kKiBjaGlsZDsKCgkJCQkJaWYgKGFjdGl2YXRlX2ZzX3dpbmRvdyhSUyhiMSxJRFNfU0hFTEwpKSkKCQkJCQkJYnJlYWs7CgoJCQkJCUdldEN1cnJlbnREaXJlY3RvcnkoTUFYX1BBVEgsIHBhdGgpOwoJCQkJCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIGdldF9wYXRoX3BpZGwocGF0aCxod25kKSwgaHduZCk7CgoJCQkJCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhjaGlsZCkpCgkJCQkJCWZyZWUoY2hpbGQpOwoJCQkJCWJyZWFrO30KI2VuZGlmCiNlbmRpZgoKCQkJCS8qVE9ETzogVGhlcmUgYXJlIGV2ZW4gbW9yZSBtZW51IGl0ZW1zISAqLwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwojaWZkZWYgX19XSU5FX18KCQkJCWNhc2UgSURfTElDRU5TRToKCQkJCQlXaW5lTGljZW5zZShHbG9iYWxzLmhNYWluV25kKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX05PX1dBUlJBTlRZOgoJCQkJCVdpbmVXYXJyYW50eShHbG9iYWxzLmhNYWluV25kKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX0FCT1VUX1dJTkU6CgkJCQkJU2hlbGxBYm91dChod25kLCBSUyhiMixJRFNfV0lORSksIFJTKGIxLElEU19XSU5FRklMRSksIDApOwoJCQkJCWJyZWFrOwojZW5kaWYKCgkJCQljYXNlIElEX0FCT1VUOgoJCQkJCVNoZWxsQWJvdXQoaHduZCwgUlMoYjEsSURTX1dJTkVGSUxFKSwgTlVMTCwgMCk7CgkJCQkJYnJlYWs7CiNlbmRpZgkvKiBfTk9fRVhURU5TSU9OUyAqLwoKCQkJCWRlZmF1bHQ6CgkJCQkJLypUT0RPOiBpZiAod1BhcmFtID49IFBNX0ZJUlNUX0xBTkdVQUdFICYmIHdQYXJhbSA8PSBQTV9MQVNUX0xBTkdVQUdFKQoJCQkJCQlTVFJJTkdfU2VsZWN0TGFuZ3VhZ2VCeU51bWJlcih3UGFyYW0gLSBQTV9GSVJTVF9MQU5HVUFHRSk7CgkJCQkJZWxzZSAqL2lmICgoY21kPElEV19GSVJTVF9DSElMRCB8fCBjbWQ+PUlEV19GSVJTVF9DSElMRCsweDEwMCkgJiYKCQkJCQkJKGNtZDxTQ19TSVpFIHx8IGNtZD5TQ19SRVNUT1JFKSkKCQkJCQkJTWVzc2FnZUJveChod25kLCBSUyhiMixJRFNfTk9fSU1QTCksIFJTKGIxLElEU19XSU5FRklMRSksIE1CX09LKTsKCgkJCQkJcmV0dXJuIERlZkZyYW1lUHJvYyhod25kLCBHbG9iYWxzLmhtZGljbGllbnQsIG5tc2csIHdwYXJhbSwgbHBhcmFtKTsKCQkJfQoJCQlicmVhazt9CgoJCWNhc2UgV01fU0laRToKCQkJcmVzaXplX2ZyYW1lKGh3bmQsIExPV09SRChscGFyYW0pLCBISVdPUkQobHBhcmFtKSk7CgkJCWJyZWFrOwkvKiBkbyBub3QgcGFzcyBtZXNzYWdlIHRvIERlZkZyYW1lUHJvYyAqLwoKCQljYXNlIFdNX0RFVklDRUNIQU5HRToKCQkJU2VuZE1lc3NhZ2UoaHduZCwgV01fQ09NTUFORCwgTUFLRUxPTkcoSURfUkVGUkVTSCwwKSwgMCk7CgkJCWJyZWFrOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fR0VUTUlOTUFYSU5GTzogewoJCQlMUE1JTk1BWElORk8gbHBtbWkgPSAoTFBNSU5NQVhJTkZPKWxwYXJhbTsKCgkJCWxwbW1pLT5wdE1heFRyYWNrU2l6ZS54IDw8PSAxOy8qMipHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKSAvIFNNX0NYVklSVFVBTFNDUkVFTiAqLwoJCQlscG1taS0+cHRNYXhUcmFja1NpemUueSA8PD0gMTsvKjIqR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTikgLyBTTV9DWVZJUlRVQUxTQ1JFRU4gKi8KCQkJYnJlYWs7fQoKCQljYXNlIEZSTV9DQUxDX0NMSUVOVDoKCQkJZnJhbWVfZ2V0X2NsaWVudHNwYWNlKGh3bmQsIChQUkVDVClscGFyYW0pOwoJCQlyZXR1cm4gVFJVRTsKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJCWRlZmF1bHQ6CgkJCXJldHVybiBEZWZGcmFtZVByb2MoaHduZCwgR2xvYmFscy5obWRpY2xpZW50LCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7Cgl9CgoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgVENIQVIgZ19wb3NfbmFtZXNbQ09MVU1OU11bMjBdID0gewoJeydcMCd9CS8qIHN5bWJvbCAqLwp9OwoKc3RhdGljIGNvbnN0IGludCBnX3Bvc19hbGlnbltdID0gewoJMCwKCUhERl9MRUZULAkvKiBOYW1lICovCglIREZfUklHSFQsCS8qIFNpemUgKi8KCUhERl9MRUZULAkvKiBDRGF0ZSAqLwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglIREZfTEVGVCwJLyogQURhdGUgKi8KCUhERl9MRUZULAkvKiBNRGF0ZSAqLwoJSERGX0xFRlQsCS8qIEluZGV4ICovCglIREZfQ0VOVEVSLAkvKiBMaW5rcyAqLwojZW5kaWYKCUhERl9DRU5URVIsCS8qIEF0dHJpYnV0ZXMgKi8KI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJSERGX0xFRlQJLyogU2VjdXJpdHkgKi8KI2VuZGlmCn07CgpzdGF0aWMgdm9pZCByZXNpemVfdHJlZShDaGlsZFduZCogY2hpbGQsIGludCBjeCwgaW50IGN5KQp7CglIRFdQIGhkd3AgPSBCZWdpbkRlZmVyV2luZG93UG9zKDQpOwoJUkVDVCBydDsKCglydC5sZWZ0ICAgPSAwOwoJcnQudG9wICAgID0gMDsKCXJ0LnJpZ2h0ICA9IGN4OwoJcnQuYm90dG9tID0gY3k7CgoJY3ggPSBjaGlsZC0+c3BsaXRfcG9zICsgU1BMSVRfV0lEVEgvMjsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCXsKCQlXSU5ET1dQT1Mgd3A7CgkJSERfTEFZT1VUIGhkbDsKCgkJaGRsLnByYyAgID0gJnJ0OwoJCWhkbC5wd3BvcyA9ICZ3cDsKCgkJU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZEhlYWRlciwgSERNX0xBWU9VVCwgMCwgKExQQVJBTSkmaGRsKTsKCgkJRGVmZXJXaW5kb3dQb3MoaGR3cCwgY2hpbGQtPmxlZnQuaHduZEhlYWRlciwgd3AuaHduZEluc2VydEFmdGVyLAoJCQkJCQl3cC54LTEsIHdwLnksIGNoaWxkLT5zcGxpdF9wb3MtU1BMSVRfV0lEVEgvMisxLCB3cC5jeSwgd3AuZmxhZ3MpOwoJCURlZmVyV2luZG93UG9zKGhkd3AsIGNoaWxkLT5yaWdodC5od25kSGVhZGVyLCB3cC5od25kSW5zZXJ0QWZ0ZXIsCgkJCQkJCXJ0LmxlZnQrY3grMSwgd3AueSwgd3AuY3gtY3grMiwgd3AuY3ksIHdwLmZsYWdzKTsKCX0KI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJRGVmZXJXaW5kb3dQb3MoaGR3cCwgY2hpbGQtPmxlZnQuaHduZCwgMCwgcnQubGVmdCwgcnQudG9wLCBjaGlsZC0+c3BsaXRfcG9zLVNQTElUX1dJRFRILzItcnQubGVmdCwgcnQuYm90dG9tLXJ0LnRvcCwgU1dQX05PWk9SREVSfFNXUF9OT0FDVElWQVRFKTsKCURlZmVyV2luZG93UG9zKGhkd3AsIGNoaWxkLT5yaWdodC5od25kLCAwLCBydC5sZWZ0K2N4KzEsIHJ0LnRvcCwgcnQucmlnaHQtY3gsIHJ0LmJvdHRvbS1ydC50b3AsIFNXUF9OT1pPUkRFUnxTV1BfTk9BQ1RJVkFURSk7CgoJRW5kRGVmZXJXaW5kb3dQb3MoaGR3cCk7Cn0KCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgpzdGF0aWMgSFdORCBjcmVhdGVfaGVhZGVyKEhXTkQgcGFyZW50LCBQYW5lKiBwYW5lLCBpbnQgaWQpCnsKCUhEX0lURU0gaGRpOwoJaW50IGlkeDsKCglIV05EIGh3bmQgPSBDcmVhdGVXaW5kb3coV0NfSEVBREVSLCAwLCBXU19DSElMRHxXU19WSVNJQkxFfEhEU19IT1JaLypUT0RPOiB8SERTX0JVVFRPTlMgKyBzb3J0IG9yZGVycyovLAoJCQkJCQkJCTAsIDAsIDAsIDAsIHBhcmVudCwgKEhNRU5VKWlkLCBHbG9iYWxzLmhJbnN0YW5jZSwgMCk7CglpZiAoIWh3bmQpCgkJcmV0dXJuIDA7CgoJU2VuZE1lc3NhZ2UoaHduZCwgV01fU0VURk9OVCwgKFdQQVJBTSlHZXRTdG9ja09iamVjdChERUZBVUxUX0dVSV9GT05UKSwgRkFMU0UpOwoKCWhkaS5tYXNrID0gSERJX1RFWFR8SERJX1dJRFRIfEhESV9GT1JNQVQ7CgoJZm9yKGlkeD0wOyBpZHg8Q09MVU1OUzsgaWR4KyspIHsKCQloZGkucHN6VGV4dCA9IGdfcG9zX25hbWVzW2lkeF07CgkJaGRpLmZtdCA9IEhERl9TVFJJTkcgfCBnX3Bvc19hbGlnbltpZHhdOwoJCWhkaS5jeHkgPSBwYW5lLT53aWR0aHNbaWR4XTsKCQlTZW5kTWVzc2FnZShod25kLCBIRE1fSU5TRVJUSVRFTSwgaWR4LCAoTFBBUkFNKSAmaGRpKTsKCX0KCglyZXR1cm4gaHduZDsKfQoKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoKc3RhdGljIHZvaWQgaW5pdF9vdXRwdXQoSFdORCBod25kKQp7CglzdGF0aWMgY29uc3QgVENIQVIgczEwMDBbXSA9IHsnMScsJzAnLCcwJywnMCcsJ1wwJ307CgoJVENIQVIgYlsxNl07CglIRk9OVCBvbGRfZm9udDsKCUhEQyBoZGMgPSBHZXREQyhod25kKTsKCglpZiAoR2V0TnVtYmVyRm9ybWF0KExPQ0FMRV9VU0VSX0RFRkFVTFQsIDAsIHMxMDAwLCAwLCBiLCAxNikgPiA0KQoJCUdsb2JhbHMubnVtX3NlcCA9IGJbMV07CgllbHNlCgkJR2xvYmFscy5udW1fc2VwID0gVEVYVCgnLicpOwoKCW9sZF9mb250ID0gU2VsZWN0T2JqZWN0KGhkYywgR2xvYmFscy5oZm9udCk7CglHZXRUZXh0RXh0ZW50UG9pbnQzMihoZGMsIHNTcGFjZSwgMSwgJkdsb2JhbHMuc3BhY2VTaXplKTsKCVNlbGVjdE9iamVjdChoZGMsIG9sZF9mb250KTsKCVJlbGVhc2VEQyhod25kLCBoZGMpOwp9CgpzdGF0aWMgdm9pZCBkcmF3X2l0ZW0oUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIEVudHJ5KiBlbnRyeSwgaW50IGNhbGNXaWR0aENvbCk7CgoKLyogY2FsY3VsYXRlIHByZWZlcnJlZCB3aWR0aCBmb3IgYWxsIHZpc2libGUgY29sdW1ucyAqLwoKc3RhdGljIEJPT0wgY2FsY193aWR0aHMoUGFuZSogcGFuZSwgQk9PTCBhbnl3YXkpCnsKCWludCBjb2wsIHgsIGN4LCBzcGM9MypHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCWludCBlbnRyaWVzID0gU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfR0VUQ09VTlQsIDAsIDApOwoJaW50IG9yZ1dpZHRoc1tDT0xVTU5TXTsKCWludCBvcmdQb3NpdGlvbnNbQ09MVU1OUysxXTsKCUhGT05UIGhmb250T2xkOwoJSERDIGhkYzsKCWludCBjbnQ7CgoJaWYgKCFhbnl3YXkpIHsKCQltZW1jcHkob3JnV2lkdGhzLCBwYW5lLT53aWR0aHMsIHNpemVvZihvcmdXaWR0aHMpKTsKCQltZW1jcHkob3JnUG9zaXRpb25zLCBwYW5lLT5wb3NpdGlvbnMsIHNpemVvZihvcmdQb3NpdGlvbnMpKTsKCX0KCglmb3IoY29sPTA7IGNvbDxDT0xVTU5TOyBjb2wrKykKCQlwYW5lLT53aWR0aHNbY29sXSA9IDA7CgoJaGRjID0gR2V0REMocGFuZS0+aHduZCk7CgloZm9udE9sZCA9IFNlbGVjdE9iamVjdChoZGMsIEdsb2JhbHMuaGZvbnQpOwoKCWZvcihjbnQ9MDsgY250PGVudHJpZXM7IGNudCsrKSB7CgkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfR0VUSVRFTURBVEEsIGNudCwgMCk7CgoJCURSQVdJVEVNU1RSVUNUIGRpczsKCgkJZGlzLkN0bFR5cGUJCSAgPSAwOwoJCWRpcy5DdGxJRAkJICA9IDA7CgkJZGlzLml0ZW1JRAkJICA9IDA7CgkJZGlzLml0ZW1BY3Rpb24JICA9IDA7CgkJZGlzLml0ZW1TdGF0ZQkgID0gMDsKCQlkaXMuaHduZEl0ZW0JICA9IHBhbmUtPmh3bmQ7CgkJZGlzLmhEQwkJCSAgPSBoZGM7CgkJZGlzLnJjSXRlbS5sZWZ0CSAgPSAwOwoJCWRpcy5yY0l0ZW0udG9wICAgID0gMDsKCQlkaXMucmNJdGVtLnJpZ2h0ICA9IDA7CgkJZGlzLnJjSXRlbS5ib3R0b20gPSAwOwoJCS8qZGlzLml0ZW1EYXRhCSAgPSAwOyAqLwoKCQlkcmF3X2l0ZW0ocGFuZSwgJmRpcywgZW50cnksIENPTFVNTlMpOwoJfQoKCVNlbGVjdE9iamVjdChoZGMsIGhmb250T2xkKTsKCVJlbGVhc2VEQyhwYW5lLT5od25kLCBoZGMpOwoKCXggPSAwOwoJZm9yKGNvbD0wOyBjb2w8Q09MVU1OUzsgY29sKyspIHsKCQlwYW5lLT5wb3NpdGlvbnNbY29sXSA9IHg7CgkJY3ggPSBwYW5lLT53aWR0aHNbY29sXTsKCgkJaWYgKGN4KSB7CgkJCWN4ICs9IHNwYzsKCgkJCWlmIChjeCA8IElNQUdFX1dJRFRIKQoJCQkJY3ggPSBJTUFHRV9XSURUSDsKCgkJCXBhbmUtPndpZHRoc1tjb2xdID0gY3g7CgkJfQoKCQl4ICs9IGN4OwoJfQoKCXBhbmUtPnBvc2l0aW9uc1tDT0xVTU5TXSA9IHg7CgoJU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfU0VUSE9SSVpPTlRBTEVYVEVOVCwgeCwgMCk7CgoJLyogbm8gY2hhbmdlPyAqLwoJaWYgKCFtZW1jbXAob3JnV2lkdGhzLCBwYW5lLT53aWR0aHMsIHNpemVvZihvcmdXaWR0aHMpKSkKCQlyZXR1cm4gRkFMU0U7CgoJLyogZG9uJ3QgbW92ZSwgaWYgb25seSBjb2xsYXBzaW5nIGFuIGVudHJ5ICovCglpZiAoIWFueXdheSAmJiBwYW5lLT53aWR0aHNbMF08b3JnV2lkdGhzWzBdICYmCgkJIW1lbWNtcChvcmdXaWR0aHMrMSwgcGFuZS0+d2lkdGhzKzEsIHNpemVvZihvcmdXaWR0aHMpLXNpemVvZihpbnQpKSkgewoJCXBhbmUtPndpZHRoc1swXSA9IG9yZ1dpZHRoc1swXTsKCQltZW1jcHkocGFuZS0+cG9zaXRpb25zLCBvcmdQb3NpdGlvbnMsIHNpemVvZihvcmdQb3NpdGlvbnMpKTsKCgkJcmV0dXJuIEZBTFNFOwoJfQoKCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoKCXJldHVybiBUUlVFOwp9CgoKLyogY2FsY3VsYXRlIG9uZSBwcmVmZXJyZWQgY29sdW1uIHdpZHRoICovCgpzdGF0aWMgdm9pZCBjYWxjX3NpbmdsZV93aWR0aChQYW5lKiBwYW5lLCBpbnQgY29sKQp7CglIRk9OVCBoZm9udE9sZDsKCWludCB4LCBjeDsKCWludCBlbnRyaWVzID0gU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfR0VUQ09VTlQsIDAsIDApOwoJaW50IGNudDsKCUhEQyBoZGM7CgoJcGFuZS0+d2lkdGhzW2NvbF0gPSAwOwoKCWhkYyA9IEdldERDKHBhbmUtPmh3bmQpOwoJaGZvbnRPbGQgPSBTZWxlY3RPYmplY3QoaGRjLCBHbG9iYWxzLmhmb250KTsKCglmb3IoY250PTA7IGNudDxlbnRyaWVzOyBjbnQrKykgewoJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIFNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX0dFVElURU1EQVRBLCBjbnQsIDApOwoJCURSQVdJVEVNU1RSVUNUIGRpczsKCgkJZGlzLkN0bFR5cGUJCSAgPSAwOwoJCWRpcy5DdGxJRAkJICA9IDA7CgkJZGlzLml0ZW1JRAkJICA9IDA7CgkJZGlzLml0ZW1BY3Rpb24JICA9IDA7CgkJZGlzLml0ZW1TdGF0ZQkgID0gMDsKCQlkaXMuaHduZEl0ZW0JICA9IHBhbmUtPmh3bmQ7CgkJZGlzLmhEQwkJCSAgPSBoZGM7CgkJZGlzLnJjSXRlbS5sZWZ0CSAgPSAwOwoJCWRpcy5yY0l0ZW0udG9wICAgID0gMDsKCQlkaXMucmNJdGVtLnJpZ2h0ICA9IDA7CgkJZGlzLnJjSXRlbS5ib3R0b20gPSAwOwoJCS8qZGlzLml0ZW1EYXRhCSAgPSAwOyAqLwoKCQlkcmF3X2l0ZW0ocGFuZSwgJmRpcywgZW50cnksIGNvbCk7Cgl9CgoJU2VsZWN0T2JqZWN0KGhkYywgaGZvbnRPbGQpOwoJUmVsZWFzZURDKHBhbmUtPmh3bmQsIGhkYyk7CgoJY3ggPSBwYW5lLT53aWR0aHNbY29sXTsKCglpZiAoY3gpIHsKCQljeCArPSAzKkdsb2JhbHMuc3BhY2VTaXplLmN4OwoKCQlpZiAoY3ggPCBJTUFHRV9XSURUSCkKCQkJY3ggPSBJTUFHRV9XSURUSDsKCX0KCglwYW5lLT53aWR0aHNbY29sXSA9IGN4OwoKCXggPSBwYW5lLT5wb3NpdGlvbnNbY29sXSArIGN4OwoKCWZvcig7IGNvbDxDT0xVTU5TOyApIHsKCQlwYW5lLT5wb3NpdGlvbnNbKytjb2xdID0geDsKCQl4ICs9IHBhbmUtPndpZHRoc1tjb2xdOwoJfQoKCVNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX1NFVEhPUklaT05UQUxFWFRFTlQsIHgsIDApOwp9CgoKc3RhdGljIEJPT0wgcGF0dGVybl9tYXRjaChMUENUU1RSIHN0ciwgTFBDVFNUUiBwYXR0ZXJuKQp7Cglmb3IoIDsgKnN0ciYmKnBhdHRlcm47IHN0cisrLHBhdHRlcm4rKykgewoJCWlmICgqcGF0dGVybiA9PSAnKicpIHsKCQkJZG8gcGF0dGVybisrOwoJCQl3aGlsZSgqcGF0dGVybiA9PSAnKicpOwoKCQkJaWYgKCEqcGF0dGVybikKCQkJCXJldHVybiBUUlVFOwoKCQkJZm9yKDsgKnN0cjsgc3RyKyspCgkJCQlpZiAoKnN0cj09KnBhdHRlcm4gJiYgcGF0dGVybl9tYXRjaChzdHIsIHBhdHRlcm4pKQoJCQkJCXJldHVybiBUUlVFOwoKCQkJcmV0dXJuIEZBTFNFOwoJCX0KCQllbHNlIGlmICgqc3RyIT0qcGF0dGVybiAmJiAqcGF0dGVybiE9Jz8nKQoJCQlyZXR1cm4gRkFMU0U7Cgl9CgoJaWYgKCpzdHIgfHwgKnBhdHRlcm4pCgkJaWYgKCpwYXR0ZXJuIT0nKicgfHwgcGF0dGVyblsxXSE9J1wwJykKCQkJcmV0dXJuIEZBTFNFOwoKCXJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBwYXR0ZXJuX2ltYXRjaChMUENUU1RSIHN0ciwgTFBDVFNUUiBwYXR0ZXJuKQp7CglUQ0hBUiBiMVtCVUZGRVJfTEVOXSwgYjJbQlVGRkVSX0xFTl07CgoJbHN0cmNweShiMSwgc3RyKTsKCWxzdHJjcHkoYjIsIHBhdHRlcm4pOwoJQ2hhclVwcGVyKGIxKTsKCUNoYXJVcHBlcihiMik7CgoJcmV0dXJuIHBhdHRlcm5fbWF0Y2goYjEsIGIyKTsKfQoKCmVudW0gRklMRV9UWVBFIHsKCUZUX09USEVSCQk9IDAsCglGVF9FWEVDVVRBQkxFCT0gMSwKCUZUX0RPQ1VNRU5UCQk9IDIKfTsKCnN0YXRpYyBlbnVtIEZJTEVfVFlQRSBnZXRfZmlsZV90eXBlKExQQ1RTVFIgZmlsZW5hbWUpOwoKCi8qIGluc2VydCBsaXN0Ym94IGVudHJpZXMgYWZ0ZXIgaW5kZXggaWR4ICovCgpzdGF0aWMgaW50IGluc2VydF9lbnRyaWVzKFBhbmUqIHBhbmUsIEVudHJ5KiBkaXIsIExQQ1RTVFIgcGF0dGVybiwgaW50IGZpbHRlcl9mbGFncywgaW50IGlkeCkKewoJRW50cnkqIGVudHJ5ID0gZGlyOwoKCWlmICghZW50cnkpCgkJcmV0dXJuIGlkeDsKCglTaG93V2luZG93KHBhbmUtPmh3bmQsIFNXX0hJREUpOwoKCWZvcig7IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkgewojaWZuZGVmIF9MRUZUX0ZJTEVTCgkJaWYgKHBhbmUtPnRyZWVQYW5lICYmICEoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpKQoJCQljb250aW51ZTsKI2VuZGlmCgoJCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCS8qIGRvbid0IGRpc3BsYXkgZW50cmllcyAiLiIgYW5kICIuLiIgaW4gdGhlIGxlZnQgcGFuZSAqLwoJCQlpZiAocGFuZS0+dHJlZVBhbmUgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT1URVhUKCcuJykpCgkJCQlpZiAoCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJCQllbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMV09PVRFWFQoJ1wwJykgfHwKI2VuZGlmCgkJCQkJKGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsxXT09VEVYVCgnLicpICYmIGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsyXT09VEVYVCgnXDAnKSkpCgkJCQkJY29udGludWU7CgoJCQkvKiBmaWx0ZXIgZGlyZWN0b3JpZXMgaW4gcmlnaHQgcGFuZSAqLwoJCQlpZiAoIXBhbmUtPnRyZWVQYW5lICYmICEoZmlsdGVyX2ZsYWdzJlRGX0RJUkVDVE9SSUVTKSkKCQkJCWNvbnRpbnVlOwoJCX0KCgkJLyogZmlsdGVyIHVzaW5nIHRoZSBmaWxlIG5hbWUgcGF0dGVybiAqLwoJCWlmIChwYXR0ZXJuKQoJCQlpZiAoIXBhdHRlcm5faW1hdGNoKGVudHJ5LT5kYXRhLmNGaWxlTmFtZSwgcGF0dGVybikpCgkJCQljb250aW51ZTsKCgkJLyogZmlsdGVyIHN5c3RlbSBhbmQgaGlkZGVuIGZpbGVzICovCgkJaWYgKCEoZmlsdGVyX2ZsYWdzJlRGX0hJRERFTikgJiYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMmKEZJTEVfQVRUUklCVVRFX0hJRERFTnxGSUxFX0FUVFJJQlVURV9TWVNURU0pKSkKCQkJY29udGludWU7CgoJCS8qIGZpbHRlciBsb29raW5nIGF0IHRoZSBmaWxlIHR5cGUgKi8KCQlpZiAoKGZpbHRlcl9mbGFncyYoVEZfUFJPR1JBTVN8VEZfRE9DVU1FTlRTfFRGX09USEVSUykpICE9IChURl9QUk9HUkFNU3xURl9ET0NVTUVOVFN8VEZfT1RIRVJTKSkKCQkJc3dpdGNoKGdldF9maWxlX3R5cGUoZW50cnktPmRhdGEuY0ZpbGVOYW1lKSkgewoJCQkgIGNhc2UgRlRfRVhFQ1VUQUJMRToKCQkJICAJaWYgKCEoZmlsdGVyX2ZsYWdzICYgVEZfUFJPR1JBTVMpKQoJCQkJCWNvbnRpbnVlOwoJCQkJYnJlYWs7CgoJCQkgIGNhc2UgRlRfRE9DVU1FTlQ6CgkJCQlpZiAoIShmaWx0ZXJfZmxhZ3MgJiBURl9ET0NVTUVOVFMpKQoJCQkJCWNvbnRpbnVlOwoJCQkJYnJlYWs7CgoJCQkgIGRlZmF1bHQ6IC8qIFRGX09USEVSUyAqLwoJCQkJaWYgKCEoZmlsdGVyX2ZsYWdzICYgVEZfT1RIRVJTKSkKCQkJCQljb250aW51ZTsKCQkJfQoKCQlpZiAoaWR4ICE9IC0xKQoJCQlpZHgrKzsKCgkJU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfSU5TRVJUU1RSSU5HLCBpZHgsIChMUEFSQU0pIGVudHJ5KTsKCgkJaWYgKHBhbmUtPnRyZWVQYW5lICYmIGVudHJ5LT5leHBhbmRlZCkKCQkJaWR4ID0gaW5zZXJ0X2VudHJpZXMocGFuZSwgZW50cnktPmRvd24sIHBhdHRlcm4sIGZpbHRlcl9mbGFncywgaWR4KTsKCX0KCglTaG93V2luZG93KHBhbmUtPmh3bmQsIFNXX1NIT1cpOwoKCXJldHVybiBpZHg7Cn0KCgpzdGF0aWMgdm9pZCBmb3JtYXRfYnl0ZXMoTFBUU1RSIGJ1ZmZlciwgTE9OR0xPTkcgYnl0ZXMpCnsKCXN0YXRpYyBjb25zdCBUQ0hBUiBzRm10R0JbXSA9IHsnJScsICcuJywgJzEnLCAnZicsICcgJywgJ0cnLCAnQicsICdcMCd9OwoJc3RhdGljIGNvbnN0IFRDSEFSIHNGbXRNQltdID0geyclJywgJy4nLCAnMScsICdmJywgJyAnLCAnTScsICdCJywgJ1wwJ307CglzdGF0aWMgY29uc3QgVENIQVIgc0ZtdGtCW10gPSB7JyUnLCAnLicsICcxJywgJ2YnLCAnICcsICdrJywgJ0InLCAnXDAnfTsKCglmbG9hdCBmQnl0ZXMgPSAoZmxvYXQpYnl0ZXM7CgoJaWYgKGJ5dGVzID49IDEwNzM3NDE4MjQpCS8qIDEgR0IgKi8KCQl3c3ByaW50ZihidWZmZXIsIHNGbXRHQiwgZkJ5dGVzLzEwNzM3NDE4MjQuZisuNWYpOwoJZWxzZSBpZiAoYnl0ZXMgPj0gMTA0ODU3NikJLyogMSBNQiAqLwoJCXdzcHJpbnRmKGJ1ZmZlciwgc0ZtdE1CLCBmQnl0ZXMvMTA0ODU3Ni5mKy41Zik7CgllbHNlIGlmIChieXRlcyA+PSAxMDI0KQkJLyogMSBrQiAqLwoJCXdzcHJpbnRmKGJ1ZmZlciwgc0ZtdGtCLCBmQnl0ZXMvMTAyNC5mKy41Zik7CgllbHNlCgkJX3N0cHJpbnRmKGJ1ZmZlciwgc0xvbmdOdW1GbXQsIGJ5dGVzKTsKfQoKc3RhdGljIHZvaWQgc2V0X3NwYWNlX3N0YXR1cyh2b2lkKQp7CglVTEFSR0VfSU5URUdFUiB1bEZyZWVCeXRlc1RvQ2FsbGVyLCB1bFRvdGFsQnl0ZXMsIHVsRnJlZUJ5dGVzOwoJVENIQVIgZm10WzY0XSwgYjFbNjRdLCBiMls2NF0sIGJ1ZmZlcltCVUZGRVJfTEVOXTsKCglpZiAoR2V0RGlza0ZyZWVTcGFjZUV4KE5VTEwsICZ1bEZyZWVCeXRlc1RvQ2FsbGVyLCAmdWxUb3RhbEJ5dGVzLCAmdWxGcmVlQnl0ZXMpKSB7CgkJZm9ybWF0X2J5dGVzKGIxLCB1bEZyZWVCeXRlc1RvQ2FsbGVyLlF1YWRQYXJ0KTsKCQlmb3JtYXRfYnl0ZXMoYjIsIHVsVG90YWxCeXRlcy5RdWFkUGFydCk7CgkJd3NwcmludGYoYnVmZmVyLCBSUyhmbXQsSURTX0ZSRUVfU1BBQ0VfRk1UKSwgYjEsIGIyKTsKCX0gZWxzZQoJCWxzdHJjcHkoYnVmZmVyLCBzUU1hcmtzKTsKCglTZW5kTWVzc2FnZShHbG9iYWxzLmhzdGF0dXNiYXIsIFNCX1NFVFRFWFQsIDAsIChMUEFSQU0pYnVmZmVyKTsKfQoKCnN0YXRpYyBXTkRQUk9DIGdfb3JnVHJlZVduZFByb2M7CgpzdGF0aWMgdm9pZCBjcmVhdGVfdHJlZV93aW5kb3coSFdORCBwYXJlbnQsIFBhbmUqIHBhbmUsIGludCBpZCwgaW50IGlkX2hlYWRlciwgTFBDVFNUUiBwYXR0ZXJuLCBpbnQgZmlsdGVyX2ZsYWdzKQp7CglzdGF0aWMgY29uc3QgVENIQVIgc0xpc3RCb3hbXSA9IHsnTCcsJ2knLCdzJywndCcsJ0InLCdvJywneCcsJ1wwJ307CgoJc3RhdGljIGludCBzX2luaXQgPSAwOwoJRW50cnkqIGVudHJ5ID0gcGFuZS0+cm9vdDsKCglwYW5lLT5od25kID0gQ3JlYXRlV2luZG93KHNMaXN0Qm94LCBzRW1wdHksIFdTX0NISUxEfFdTX1ZJU0lCTEV8V1NfSFNDUk9MTHxXU19WU0NST0xMfAoJCQkJCQkJCUxCU19ESVNBQkxFTk9TQ1JPTEx8TEJTX05PSU5URUdSQUxIRUlHSFR8TEJTX09XTkVSRFJBV0ZJWEVEfExCU19OT1RJRlksCgkJCQkJCQkJMCwgMCwgMCwgMCwgcGFyZW50LCAoSE1FTlUpaWQsIEdsb2JhbHMuaEluc3RhbmNlLCAwKTsKCglTZXRXaW5kb3dMb25nUHRyKHBhbmUtPmh3bmQsIEdXTFBfVVNFUkRBVEEsIChMUEFSQU0pcGFuZSk7CglnX29yZ1RyZWVXbmRQcm9jID0gKFdORFBST0MpIFNldFdpbmRvd0xvbmdQdHIocGFuZS0+aHduZCwgR1dMUF9XTkRQUk9DLCAoTFBBUkFNKVRyZWVXbmRQcm9jKTsKCglTZW5kTWVzc2FnZShwYW5lLT5od25kLCBXTV9TRVRGT05ULCAoV1BBUkFNKUdsb2JhbHMuaGZvbnQsIEZBTFNFKTsKCgkvKiBpbnNlcnQgZW50cmllcyBpbnRvIGxpc3Rib3ggKi8KCWlmIChlbnRyeSkKCQlpbnNlcnRfZW50cmllcyhwYW5lLCBlbnRyeSwgcGF0dGVybiwgZmlsdGVyX2ZsYWdzLCAtMSk7CgoJLyogY2FsY3VsYXRlIGNvbHVtbiB3aWR0aHMgKi8KCWlmICghc19pbml0KSB7CgkJc19pbml0ID0gMTsKCQlpbml0X291dHB1dChwYW5lLT5od25kKTsKCX0KCgljYWxjX3dpZHRocyhwYW5lLCBUUlVFKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCXBhbmUtPmh3bmRIZWFkZXIgPSBjcmVhdGVfaGVhZGVyKHBhcmVudCwgcGFuZSwgaWRfaGVhZGVyKTsKI2VuZGlmCn0KCgpzdGF0aWMgdm9pZCBJbml0Q2hpbGRXaW5kb3coQ2hpbGRXbmQqIGNoaWxkKQp7CgljcmVhdGVfdHJlZV93aW5kb3coY2hpbGQtPmh3bmQsICZjaGlsZC0+bGVmdCwgSURXX1RSRUVfTEVGVCwgSURXX0hFQURFUl9MRUZULCBOVUxMLCBURl9BTEwpOwoJY3JlYXRlX3RyZWVfd2luZG93KGNoaWxkLT5od25kLCAmY2hpbGQtPnJpZ2h0LCBJRFdfVFJFRV9SSUdIVCwgSURXX0hFQURFUl9SSUdIVCwgY2hpbGQtPmZpbHRlcl9wYXR0ZXJuLCBjaGlsZC0+ZmlsdGVyX2ZsYWdzKTsKfQoKCnN0YXRpYyB2b2lkIGZvcm1hdF9kYXRlKGNvbnN0IEZJTEVUSU1FKiBmdCwgVENIQVIqIGJ1ZmZlciwgaW50IHZpc2libGVfY29scykKewoJU1lTVEVNVElNRSBzeXN0aW1lOwoJRklMRVRJTUUgbGZ0OwoJaW50IGxlbiA9IDA7CgoJKmJ1ZmZlciA9IFRFWFQoJ1wwJyk7CgoJaWYgKCFmdC0+ZHdMb3dEYXRlVGltZSAmJiAhZnQtPmR3SGlnaERhdGVUaW1lKQoJCXJldHVybjsKCglpZiAoIUZpbGVUaW1lVG9Mb2NhbEZpbGVUaW1lKGZ0LCAmbGZ0KSkKCQl7ZXJyOiBsc3RyY3B5KGJ1ZmZlcixzUU1hcmtzKTsgcmV0dXJuO30KCglpZiAoIUZpbGVUaW1lVG9TeXN0ZW1UaW1lKCZsZnQsICZzeXN0aW1lKSkKCQlnb3RvIGVycjsKCglpZiAodmlzaWJsZV9jb2xzICYgQ09MX0RBVEUpIHsKCQlsZW4gPSBHZXREYXRlRm9ybWF0KExPQ0FMRV9VU0VSX0RFRkFVTFQsIDAsICZzeXN0aW1lLCAwLCBidWZmZXIsIEJVRkZFUl9MRU4pOwoJCWlmICghbGVuKQoJCQlnb3RvIGVycjsKCX0KCglpZiAodmlzaWJsZV9jb2xzICYgQ09MX1RJTUUpIHsKCQlpZiAobGVuKQoJCQlidWZmZXJbbGVuLTFdID0gJyAnOwoKCQlidWZmZXJbbGVuKytdID0gJyAnOwoKCQlpZiAoIUdldFRpbWVGb3JtYXQoTE9DQUxFX1VTRVJfREVGQVVMVCwgMCwgJnN5c3RpbWUsIDAsIGJ1ZmZlcitsZW4sIEJVRkZFUl9MRU4tbGVuKSkKCQkJYnVmZmVyW2xlbl0gPSBURVhUKCdcMCcpOwoJfQp9CgoKc3RhdGljIHZvaWQgY2FsY193aWR0aChQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgaW50IGNvbCwgTFBDVFNUUiBzdHIpCnsKCVJFQ1QgcnQgPSB7MCwgMCwgMCwgMH07CgoJRHJhd1RleHQoZGlzLT5oREMsIChMUFRTVFIpc3RyLCAtMSwgJnJ0LCBEVF9DQUxDUkVDVHxEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYKTsKCglpZiAocnQucmlnaHQgPiBwYW5lLT53aWR0aHNbY29sXSkKCQlwYW5lLT53aWR0aHNbY29sXSA9IHJ0LnJpZ2h0Owp9CgpzdGF0aWMgdm9pZCBjYWxjX3RhYmJlZF93aWR0aChQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgaW50IGNvbCwgTFBDVFNUUiBzdHIpCnsKCVJFQ1QgcnQgPSB7MCwgMCwgMCwgMH07CgovKglEUkFXVEVYVFBBUkFNUyBkdHAgPSB7c2l6ZW9mKERSQVdURVhUUEFSQU1TKSwgMn07CglEcmF3VGV4dEV4KGRpcy0+aERDLCAoTFBUU1RSKXN0ciwgLTEsICZydCwgRFRfQ0FMQ1JFQ1R8RFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWHxEVF9FWFBBTkRUQUJTfERUX1RBQlNUT1AsICZkdHApOyovCgoJRHJhd1RleHQoZGlzLT5oREMsIChMUFRTVFIpc3RyLCAtMSwgJnJ0LCBEVF9DQUxDUkVDVHxEVF9TSU5HTEVMSU5FfERUX0VYUEFORFRBQlN8RFRfVEFCU1RPUHwoMjw8OCkpOwoJLypGSVhNRSBydCAoMCwwKSA/Pz8gKi8KCglpZiAocnQucmlnaHQgPiBwYW5lLT53aWR0aHNbY29sXSkKCQlwYW5lLT53aWR0aHNbY29sXSA9IHJ0LnJpZ2h0Owp9CgoKc3RhdGljIHZvaWQgb3V0cHV0X3RleHQoUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIGludCBjb2wsIExQQ1RTVFIgc3RyLCBEV09SRCBmbGFncykKewoJaW50IHggPSBkaXMtPnJjSXRlbS5sZWZ0OwoJUkVDVCBydDsKCglydC5sZWZ0ICAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2xdK0dsb2JhbHMuc3BhY2VTaXplLmN4OwoJcnQudG9wICAgID0gZGlzLT5yY0l0ZW0udG9wOwoJcnQucmlnaHQgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sKzFdLUdsb2JhbHMuc3BhY2VTaXplLmN4OwoJcnQuYm90dG9tID0gZGlzLT5yY0l0ZW0uYm90dG9tOwoKCURyYXdUZXh0KGRpcy0+aERDLCAoTFBUU1RSKXN0ciwgLTEsICZydCwgRFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWHxmbGFncyk7Cn0KCnN0YXRpYyB2b2lkIG91dHB1dF90YWJiZWRfdGV4dChQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgaW50IGNvbCwgTFBDVFNUUiBzdHIpCnsKCWludCB4ID0gZGlzLT5yY0l0ZW0ubGVmdDsKCVJFQ1QgcnQ7CgoJcnQubGVmdCAgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sXStHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LnRvcCAgICA9IGRpcy0+cmNJdGVtLnRvcDsKCXJ0LnJpZ2h0ICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbCsxXS1HbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LmJvdHRvbSA9IGRpcy0+cmNJdGVtLmJvdHRvbTsKCi8qCURSQVdURVhUUEFSQU1TIGR0cCA9IHtzaXplb2YoRFJBV1RFWFRQQVJBTVMpLCAyfTsKCURyYXdUZXh0RXgoZGlzLT5oREMsIChMUFRTVFIpc3RyLCAtMSwgJnJ0LCBEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYfERUX0VYUEFORFRBQlN8RFRfVEFCU1RPUCwgJmR0cCk7Ki8KCglEcmF3VGV4dChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX1NJTkdMRUxJTkV8RFRfRVhQQU5EVEFCU3xEVF9UQUJTVE9QfCgyPDw4KSk7Cn0KCnN0YXRpYyB2b2lkIG91dHB1dF9udW1iZXIoUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIGludCBjb2wsIExQQ1RTVFIgc3RyKQp7CglpbnQgeCA9IGRpcy0+cmNJdGVtLmxlZnQ7CglSRUNUIHJ0OwoJTFBDVFNUUiBzID0gc3RyOwoJVENIQVIgYlsxMjhdOwoJTFBUU1RSIGQgPSBiOwoJaW50IHBvczsKCglydC5sZWZ0ICAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2xdK0dsb2JhbHMuc3BhY2VTaXplLmN4OwoJcnQudG9wICAgID0gZGlzLT5yY0l0ZW0udG9wOwoJcnQucmlnaHQgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sKzFdLUdsb2JhbHMuc3BhY2VTaXplLmN4OwoJcnQuYm90dG9tID0gZGlzLT5yY0l0ZW0uYm90dG9tOwoKCWlmICgqcykKCQkqZCsrID0gKnMrKzsKCgkvKiBpbnNlcnQgbnVtYmVyIHNlcGFyYXRvciBjaGFyYWN0ZXJzICovCglwb3MgPSBsc3RybGVuKHMpICUgMzsKCgl3aGlsZSgqcykKCQlpZiAocG9zLS0pCgkJCSpkKysgPSAqcysrOwoJCWVsc2UgewoJCQkqZCsrID0gR2xvYmFscy5udW1fc2VwOwoJCQlwb3MgPSAzOwoJCX0KCglEcmF3VGV4dChkaXMtPmhEQywgYiwgZC1iLCAmcnQsIERUX1JJR0hUfERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVh8RFRfRU5EX0VMTElQU0lTKTsKfQoKCnN0YXRpYyBCT09MIGlzX2V4ZV9maWxlKExQQ1RTVFIgZXh0KQp7CglzdGF0aWMgY29uc3QgVENIQVIgZXhlY3V0YWJsZV9leHRlbnNpb25zW11bNF0gPSB7CgkJeydDJywnTycsJ00nLCdcMCd9LAoJCXsnRScsJ1gnLCdFJywnXDAnfSwKCQl7J0InLCdBJywnVCcsJ1wwJ30sCgkJeydDJywnTScsJ0QnLCdcMCd9LAojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJeydDJywnTScsJ00nLCdcMCd9LAoJCXsnQicsJ1QnLCdNJywnXDAnfSwKCQl7J0EnLCdXJywnSycsJ1wwJ30sCiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoJCXsnXDAnfQoJfTsKCglUQ0hBUiBleHRfYnVmZmVyW19NQVhfRVhUXTsKCWNvbnN0IFRDSEFSICgqcClbNF07CglMUENUU1RSIHM7CglMUFRTVFIgZDsKCglmb3Iocz1leHQrMSxkPWV4dF9idWZmZXI7ICgqZD10b2xvd2VyKCpzKSk7IHMrKykKCQlkKys7CgoJZm9yKHA9ZXhlY3V0YWJsZV9leHRlbnNpb25zOyAoKnApWzBdOyBwKyspCgkJaWYgKCFsc3RyY21waShleHRfYnVmZmVyLCAqcCkpCgkJCXJldHVybiBUUlVFOwoKCXJldHVybiBGQUxTRTsKfQoKc3RhdGljIEJPT0wgaXNfcmVnaXN0ZXJlZF90eXBlKExQQ1RTVFIgZXh0KQp7CgkvKiBjaGVjayBpZiB0aGVyZSBleGlzdHMgYSBjbGFzc25hbWUgZm9yIHRoaXMgZmlsZSBleHRlbnNpb24gaW4gdGhlIHJlZ2lzdHJ5ICovCglpZiAoIVJlZ1F1ZXJ5VmFsdWUoSEtFWV9DTEFTU0VTX1JPT1QsIGV4dCwgTlVMTCwgTlVMTCkpCgkJcmV0dXJuIFRSVUU7CgoJcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgZW51bSBGSUxFX1RZUEUgZ2V0X2ZpbGVfdHlwZShMUENUU1RSIGZpbGVuYW1lKQp7CglMUENUU1RSIGV4dCA9IF90Y3NyY2hyKGZpbGVuYW1lLCAnLicpOwoJaWYgKCFleHQpCgkJZXh0ID0gc0VtcHR5OwoKCWlmIChpc19leGVfZmlsZShleHQpKQoJCXJldHVybiBGVF9FWEVDVVRBQkxFOwoJZWxzZSBpZiAoaXNfcmVnaXN0ZXJlZF90eXBlKGV4dCkpCgkJcmV0dXJuIEZUX0RPQ1VNRU5UOwoJZWxzZQoJCXJldHVybiBGVF9PVEhFUjsKfQoKCnN0YXRpYyB2b2lkIGRyYXdfaXRlbShQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgRW50cnkqIGVudHJ5LCBpbnQgY2FsY1dpZHRoQ29sKQp7CglUQ0hBUiBidWZmZXJbQlVGRkVSX0xFTl07CglEV09SRCBhdHRyczsKCWludCB2aXNpYmxlX2NvbHMgPSBwYW5lLT52aXNpYmxlX2NvbHM7CglDT0xPUlJFRiBia2NvbG9yLCB0ZXh0Y29sb3I7CglSRUNUIGZvY3VzUmVjdCA9IGRpcy0+cmNJdGVtOwoJSEJSVVNIIGhicnVzaDsKCWVudW0gSU1BR0UgaW1nOwoJaW50IGltZ19wb3MsIGN4OwoJaW50IGNvbCA9IDA7CgoJaWYgKGVudHJ5KSB7CgkJYXR0cnMgPSBlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzOwoKCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQkJaWYgKGVudHJ5LT5kYXRhLmNGaWxlTmFtZVswXT09VEVYVCgnLicpICYmIGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsxXT09VEVYVCgnLicpCgkJCQkJJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzJdPT1URVhUKCdcMCcpKQoJCQkJaW1nID0gSU1HX0ZPTERFUl9VUDsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQllbHNlIGlmIChlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF09PVRFWFQoJy4nKSAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMV09PVRFWFQoJ1wwJykpCgkJCQlpbWcgPSBJTUdfRk9MREVSX0NVUjsKI2VuZGlmCgkJCWVsc2UgaWYgKAojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJCQkgZW50cnktPmV4cGFuZGVkIHx8CiNlbmRpZgoJCQkJCSAocGFuZS0+dHJlZVBhbmUgJiYgKGRpcy0+aXRlbVN0YXRlJk9EU19GT0NVUykpKQoJCQkJaW1nID0gSU1HX09QRU5fRk9MREVSOwoJCQllbHNlCgkJCQlpbWcgPSBJTUdfRk9MREVSOwoJCX0gZWxzZSB7CgkJCXN3aXRjaChnZXRfZmlsZV90eXBlKGVudHJ5LT5kYXRhLmNGaWxlTmFtZSkpIHsKCQkJICBjYXNlIEZUX0VYRUNVVEFCTEU6CWltZyA9IElNR19FWEVDVVRBQkxFOwlicmVhazsKCQkJICBjYXNlIEZUX0RPQ1VNRU5UOgkJaW1nID0gSU1HX0RPQ1VNRU5UOwkJYnJlYWs7CgkJCSAgZGVmYXVsdDoJCQkJaW1nID0gSU1HX0ZJTEU7CgkJCX0KCQl9Cgl9IGVsc2UgewoJCWF0dHJzID0gMDsKCQlpbWcgPSBJTUdfTk9ORTsKCX0KCglpZiAocGFuZS0+dHJlZVBhbmUpIHsKCQlpZiAoZW50cnkpIHsKCQkJaW1nX3BvcyA9IGRpcy0+cmNJdGVtLmxlZnQgKyBlbnRyeS0+bGV2ZWwqKElNQUdFX1dJRFRIK1RSRUVfTElORV9EWCk7CgoJCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKSB7CgkJCQlpbnQgeDsKCQkJCWludCB5ID0gZGlzLT5yY0l0ZW0udG9wICsgSU1BR0VfSEVJR0hULzI7CgkJCQlFbnRyeSogdXA7CgkJCQlSRUNUIHJ0X2NsaXA7CgkJCQlIUkdOIGhyZ25fb3JnID0gQ3JlYXRlUmVjdFJnbigwLCAwLCAwLCAwKTsKCQkJCUhSR04gaHJnbjsKCgkJCQlydF9jbGlwLmxlZnQgICA9IGRpcy0+cmNJdGVtLmxlZnQ7CgkJCQlydF9jbGlwLnRvcCAgICA9IGRpcy0+cmNJdGVtLnRvcDsKCQkJCXJ0X2NsaXAucmlnaHQgID0gZGlzLT5yY0l0ZW0ubGVmdCtwYW5lLT53aWR0aHNbY29sXTsKCQkJCXJ0X2NsaXAuYm90dG9tID0gZGlzLT5yY0l0ZW0uYm90dG9tOwoKCQkJCWhyZ24gPSBDcmVhdGVSZWN0UmduSW5kaXJlY3QoJnJ0X2NsaXApOwoKCQkJCWlmICghR2V0Q2xpcFJnbihkaXMtPmhEQywgaHJnbl9vcmcpKSB7CgkJCQkJRGVsZXRlT2JqZWN0KGhyZ25fb3JnKTsKCQkJCQlocmduX29yZyA9IDA7CgkJCQl9CgoJCQkJLyogSEdESU9CSiBob2xkUGVuID0gU2VsZWN0T2JqZWN0KGRpcy0+aERDLCBHZXRTdG9ja09iamVjdChCTEFDS19QRU4pKTsgKi8KCQkJCUV4dFNlbGVjdENsaXBSZ24oZGlzLT5oREMsIGhyZ24sIFJHTl9BTkQpOwoJCQkJRGVsZXRlT2JqZWN0KGhyZ24pOwoKCQkJCWlmICgodXA9ZW50cnktPnVwKSAhPSBOVUxMKSB7CgkJCQkJTW92ZVRvRXgoZGlzLT5oREMsIGltZ19wb3MtSU1BR0VfV0lEVEgvMiwgeSwgMCk7CgkJCQkJTGluZVRvKGRpcy0+aERDLCBpbWdfcG9zLTIsIHkpOwoKCQkJCQl4ID0gaW1nX3BvcyAtIElNQUdFX1dJRFRILzI7CgoJCQkJCWRvIHsKCQkJCQkJeCAtPSBJTUFHRV9XSURUSCtUUkVFX0xJTkVfRFg7CgoJCQkJCQlpZiAodXAtPm5leHQKI2lmbmRlZiBfTEVGVF9GSUxFUwoJCQkJCQkJJiYgKHVwLT5uZXh0LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpCiNlbmRpZgoJCQkJCQkJKSB7CgkJCQkJCQlNb3ZlVG9FeChkaXMtPmhEQywgeCwgZGlzLT5yY0l0ZW0udG9wLCAwKTsKCQkJCQkJCUxpbmVUbyhkaXMtPmhEQywgeCwgZGlzLT5yY0l0ZW0uYm90dG9tKTsKCQkJCQkJfQoJCQkJCX0gd2hpbGUoKHVwPXVwLT51cCkgIT0gTlVMTCk7CgkJCQl9CgoJCQkJeCA9IGltZ19wb3MgLSBJTUFHRV9XSURUSC8yOwoKCQkJCU1vdmVUb0V4KGRpcy0+aERDLCB4LCBkaXMtPnJjSXRlbS50b3AsIDApOwoJCQkJTGluZVRvKGRpcy0+aERDLCB4LCB5KTsKCgkJCQlpZiAoZW50cnktPm5leHQKI2lmbmRlZiBfTEVGVF9GSUxFUwoJCQkJCSYmIChlbnRyeS0+bmV4dC0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkKI2VuZGlmCgkJCQkJKQoJCQkJCUxpbmVUbyhkaXMtPmhEQywgeCwgZGlzLT5yY0l0ZW0uYm90dG9tKTsKCgkJCQlTZWxlY3RDbGlwUmduKGRpcy0+aERDLCBocmduX29yZyk7CgkJCQlpZiAoaHJnbl9vcmcpIERlbGV0ZU9iamVjdChocmduX29yZyk7CgkJCQkvKiBTZWxlY3RPYmplY3QoZGlzLT5oREMsIGhvbGRQZW4pOyAqLwoJCQl9IGVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykgewoJCQkJaW50IHJpZ2h0ID0gaW1nX3BvcyArIElNQUdFX1dJRFRIIC0gVFJFRV9MSU5FX0RYOwoKCQkJCWlmIChyaWdodCA+IHBhbmUtPndpZHRoc1tjb2xdKQoJCQkJCXBhbmUtPndpZHRoc1tjb2xdID0gcmlnaHQ7CgkJCX0KCQl9IGVsc2UgIHsKCQkJaW1nX3BvcyA9IGRpcy0+cmNJdGVtLmxlZnQ7CgkJfQoJfSBlbHNlIHsKCQlpbWdfcG9zID0gZGlzLT5yY0l0ZW0ubGVmdDsKCgkJaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJcGFuZS0+d2lkdGhzW2NvbF0gPSBJTUFHRV9XSURUSDsKCX0KCglpZiAoY2FsY1dpZHRoQ29sID09IC0xKSB7CgkJZm9jdXNSZWN0LmxlZnQgPSBpbWdfcG9zIC0yOwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJaWYgKHBhbmUtPnRyZWVQYW5lICYmIGVudHJ5KSB7CgkJCVJFQ1QgcnQgPSB7MH07CgoJCQlEcmF3VGV4dChkaXMtPmhEQywgZW50cnktPmRhdGEuY0ZpbGVOYW1lLCAtMSwgJnJ0LCBEVF9DQUxDUkVDVHxEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYKTsKCgkJCWZvY3VzUmVjdC5yaWdodCA9IGRpcy0+cmNJdGVtLmxlZnQrcGFuZS0+cG9zaXRpb25zW2NvbCsxXStUUkVFX0xJTkVfRFggKyBydC5yaWdodCArMjsKCQl9CiNlbHNlCgoJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0NPTVBSRVNTRUQpCgkJCXRleHRjb2xvciA9IENPTE9SX0NPTVBSRVNTRUQ7CgkJZWxzZQojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCQkJdGV4dGNvbG9yID0gUkdCKDAsMCwwKTsKCgkJaWYgKGRpcy0+aXRlbVN0YXRlICYgT0RTX0ZPQ1VTKSB7CgkJCXRleHRjb2xvciA9IFJHQigyNTUsMjU1LDI1NSk7CgkJCWJrY29sb3IgPSBDT0xPUl9TRUxFQ1RJT047CgkJfSBlbHNlIHsKCQkJYmtjb2xvciA9IFJHQigyNTUsMjU1LDI1NSk7CgkJfQoKCQloYnJ1c2ggPSBDcmVhdGVTb2xpZEJydXNoKGJrY29sb3IpOwoJCUZpbGxSZWN0KGRpcy0+aERDLCAmZm9jdXNSZWN0LCBoYnJ1c2gpOwoJCURlbGV0ZU9iamVjdChoYnJ1c2gpOwoKCQlTZXRCa01vZGUoZGlzLT5oREMsIFRSQU5TUEFSRU5UKTsKCQlTZXRUZXh0Q29sb3IoZGlzLT5oREMsIHRleHRjb2xvcik7CgoJCWN4ID0gcGFuZS0+d2lkdGhzW2NvbF07CgoJCWlmIChjeCAmJiBpbWchPUlNR19OT05FKSB7CgkJCWlmIChjeCA+IElNQUdFX1dJRFRIKQoJCQkJY3ggPSBJTUFHRV9XSURUSDsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJCQlpZiAoZW50cnktPmhpY29uICYmIGVudHJ5LT5oaWNvbiE9KEhJQ09OKS0xKQoJCQkJRHJhd0ljb25FeChkaXMtPmhEQywgaW1nX3BvcywgZGlzLT5yY0l0ZW0udG9wLCBlbnRyeS0+aGljb24sIGN4LCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01JQ09OKSwgMCwgMCwgRElfTk9STUFMKTsKCQkJZWxzZQojZW5kaWYKCQkJCUltYWdlTGlzdF9EcmF3RXgoR2xvYmFscy5oaW1sLCBpbWcsIGRpcy0+aERDLAoJCQkJCQkJCSBpbWdfcG9zLCBkaXMtPnJjSXRlbS50b3AsIGN4LAoJCQkJCQkJCSBJTUFHRV9IRUlHSFQsIGJrY29sb3IsIENMUl9ERUZBVUxULCBJTERfTk9STUFMKTsKCQl9Cgl9CgoJaWYgKCFlbnRyeSkKCQlyZXR1cm47CgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCWlmIChpbWcgPj0gSU1HX0ZPTERFUl9VUCkKCQlyZXR1cm47CiNlbmRpZgoKCWNvbCsrOwoKCS8qIG91cHV0IGZpbGUgbmFtZSAqLwoJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgZW50cnktPmRhdGEuY0ZpbGVOYW1lLCAwKTsKCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpOwoKCWNvbCsrOwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCiAgaWYgKCFwYW5lLT50cmVlUGFuZSkgewojZW5kaWYKCiAgICAgICAgLyogZGlzcGxheSBmaWxlIHNpemUgKi8KCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfU0laRSkgewojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQlpZiAoIShhdHRycyZGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpKQojZW5kaWYKCQl7CgkJCVVMT05HTE9ORyBzaXplOwoKICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9ICgoVUxPTkdMT05HKWVudHJ5LT5kYXRhLm5GaWxlU2l6ZUhpZ2ggPDwgMzIpIHwgZW50cnktPmRhdGEubkZpbGVTaXplTG93OwoKCQkJX3N0cHJpbnRmKGJ1ZmZlciwgc0xvbmdOdW1GbXQsIHNpemUpOwoKCQkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJCW91dHB1dF9udW1iZXIocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgkJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7LypUT0RPOiBub3QgZXZlciB0aW1lIGVub3VnaCAqLwoJCX0KCgkJY29sKys7Cgl9CgoJLyogZGlzcGxheSBmaWxlIGRhdGUgKi8KCWlmICh2aXNpYmxlX2NvbHMgJiAoQ09MX0RBVEV8Q09MX1RJTUUpKSB7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQlmb3JtYXRfZGF0ZSgmZW50cnktPmRhdGEuZnRDcmVhdGlvblRpbWUsIGJ1ZmZlciwgdmlzaWJsZV9jb2xzKTsKCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyLCAwKTsKCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgkJY29sKys7CgoJCWZvcm1hdF9kYXRlKCZlbnRyeS0+ZGF0YS5mdExhc3RBY2Nlc3NUaW1lLCBidWZmZXIsIHZpc2libGVfY29scyk7CgkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlciwgMCk7CgkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoJCWNvbCsrOwojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgkJZm9ybWF0X2RhdGUoJmVudHJ5LT5kYXRhLmZ0TGFzdFdyaXRlVGltZSwgYnVmZmVyLCB2aXNpYmxlX2NvbHMpOwoJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIsIDApOwoJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCQljb2wrKzsKCX0KCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWlmIChlbnRyeS0+YmhmaV92YWxpZCkgewogICAgICAgICAgICBVTE9OR0xPTkcgaW5kZXggPSAoKFVMT05HTE9ORyllbnRyeS0+YmhmaS5uRmlsZUluZGV4SGlnaCA8PCAzMikgfCBlbnRyeS0+YmhmaS5uRmlsZUluZGV4TG93OwoKCQlpZiAodmlzaWJsZV9jb2xzICYgQ09MX0lOREVYKSB7CgkJCV9zdHByaW50ZihidWZmZXIsIHNMb25nSGV4Rm10LCBpbmRleCk7CgoJCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlciwgRFRfUklHSFQpOwoJCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoKCQkJY29sKys7CgkJfQoKCQlpZiAodmlzaWJsZV9jb2xzICYgQ09MX0xJTktTKSB7CgkJCXdzcHJpbnRmKGJ1ZmZlciwgc051bUZtdCwgZW50cnktPmJoZmkubk51bWJlck9mTGlua3MpOwoKCQkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIsIERUX0NFTlRFUik7CgkJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgoJCQljb2wrKzsKCQl9Cgl9IGVsc2UKCQljb2wgKz0gMjsKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJLyogc2hvdyBmaWxlIGF0dHJpYnV0ZXMgKi8KCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfQVRUUklCVVRFUykgewojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQlzdGF0aWMgY29uc3QgVENIQVIgczRUYWJzW10gPSB7JyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcMCd9OwoJCWxzdHJjcHkoYnVmZmVyLCBzNFRhYnMpOwojZWxzZQoJCXN0YXRpYyBjb25zdCBUQ0hBUiBzMTFUYWJzW10gPSB7JyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcMCd9OwoJCWxzdHJjcHkoYnVmZmVyLCBzMTFUYWJzKTsKI2VuZGlmCgoJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX05PUk1BTCkJCQkJCWJ1ZmZlclsgMF0gPSAnTic7CgkJZWxzZSB7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX1JFQURPTkxZKQkJCWJ1ZmZlclsgMl0gPSAnUic7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0hJRERFTikJCQkJYnVmZmVyWyA0XSA9ICdIJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfU1lTVEVNKQkJCQlidWZmZXJbIDZdID0gJ1MnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9BUkNISVZFKQkJCQlidWZmZXJbIDhdID0gJ0EnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9DT01QUkVTU0VEKQkJCWJ1ZmZlclsxMF0gPSAnQyc7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKQkJCWJ1ZmZlclsxMl0gPSAnRCc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0VOQ1JZUFRFRCkJCQlidWZmZXJbMTRdID0gJ0UnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9URU1QT1JBUlkpCQkJYnVmZmVyWzE2XSA9ICdUJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfU1BBUlNFX0ZJTEUpCQkJYnVmZmVyWzE4XSA9ICdQJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfUkVQQVJTRV9QT0lOVCkJCWJ1ZmZlclsyMF0gPSAnUSc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX09GRkxJTkUpCQkJCWJ1ZmZlclsyMl0gPSAnTyc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX05PVF9DT05URU5UX0lOREVYRUQpCWJ1ZmZlclsyNF0gPSAnWCc7CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoJCX0KCgkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJb3V0cHV0X3RhYmJlZF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJY2FsY190YWJiZWRfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgoJCWNvbCsrOwoJfQoKLypUT0RPCglpZiAoZmxhZ3Muc2VjdXJpdHkpIHsKCQlzdGF0aWMgY29uc3QgVENIQVIgc1NlY1RhYnNbXSA9IHsKCQkJJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLAoJCQknICcsJ1x0JywnICcsCgkJCScgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywKCQkJJyAnLCdcdCcsJyAnLAoJCQknICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsCgkJCSdcMCcKCQl9OwoKCQlEV09SRCByaWdodHMgPSBnZXRfYWNjZXNzX21hc2soKTsKCgkJbHN0cmNweShidWZmZXIsIHNTZWNUYWJzKTsKCgkJaWYgKHJpZ2h0cyAmIEZJTEVfUkVBRF9EQVRBKQkJCWJ1ZmZlclsgMF0gPSAnUic7CgkJaWYgKHJpZ2h0cyAmIEZJTEVfV1JJVEVfREFUQSkJCQlidWZmZXJbIDJdID0gJ1cnOwoJCWlmIChyaWdodHMgJiBGSUxFX0FQUEVORF9EQVRBKQkJCWJ1ZmZlclsgNF0gPSAnQSc7CgkJaWYgKHJpZ2h0cyAmIEZJTEVfUkVBRF9FQSkJCQkJe2J1ZmZlcls2XSA9ICdlbnRyeSc7IGJ1ZmZlclsgN10gPSAnUic7fQoJCWlmIChyaWdodHMgJiBGSUxFX1dSSVRFX0VBKQkJCQl7YnVmZmVyWzldID0gJ2VudHJ5JzsgYnVmZmVyWzEwXSA9ICdXJzt9CgkJaWYgKHJpZ2h0cyAmIEZJTEVfRVhFQ1VURSkJCQkJYnVmZmVyWzEyXSA9ICdYJzsKCQlpZiAocmlnaHRzICYgRklMRV9ERUxFVEVfQ0hJTEQpCQkJYnVmZmVyWzE0XSA9ICdEJzsKCQlpZiAocmlnaHRzICYgRklMRV9SRUFEX0FUVFJJQlVURVMpCQl7YnVmZmVyWzE2XSA9ICdhJzsgYnVmZmVyWzE3XSA9ICdSJzt9CgkJaWYgKHJpZ2h0cyAmIEZJTEVfV1JJVEVfQVRUUklCVVRFUykJCXtidWZmZXJbMTldID0gJ2EnOyBidWZmZXJbMjBdID0gJ1cnO30KCQlpZiAocmlnaHRzICYgV1JJVEVfREFDKQkJCQkJYnVmZmVyWzIyXSA9ICdDJzsKCQlpZiAocmlnaHRzICYgV1JJVEVfT1dORVIpCQkJCWJ1ZmZlclsyNF0gPSAnTyc7CgkJaWYgKHJpZ2h0cyAmIFNZTkNIUk9OSVpFKQkJCQlidWZmZXJbMjZdID0gJ1MnOwoKCQlvdXRwdXRfdGV4dChkaXMsIGNvbCsrLCBidWZmZXIsIERUX0xFRlQsIDMsIHBzaXplKTsKCX0KCglpZiAoZmxhZ3MuZGVzY3JpcHRpb24pIHsKCQlnZXRfZGVzY3JpcHRpb24oYnVmZmVyKTsKCQlvdXRwdXRfdGV4dChkaXMsIGNvbCsrLCBidWZmZXIsIDAsIHBzaXplKTsKCX0KKi8KCiNpZmRlZiBfTk9fRVhURU5TSU9OUwogIH0KCiAgICAgICAgLyogZHJhdyBmb2N1cyBmcmFtZSAqLwoJaWYgKChkaXMtPml0ZW1TdGF0ZSZPRFNfRk9DVVMpICYmIGNhbGNXaWR0aENvbD09LTEpIHsKCSAgICAgICAgLyogQ3VycmVudGx5IFswNC8yMDAwXSBXaW5lIG5laXRoZXIgYmVoYXZlcyBleGFjdGx5IHRoZSBzYW1lICovCgkgICAgICAgIC8qIHdheSBhcyBXSU4gOTUgbm9yIGxpa2UgV2luZG93cyBOVC4uLiAqLwoJCUhHRElPQkogbGFzdEJydXNoOwoJCUhQRU4gbGFzdFBlbjsKCQlIUEVOIGhwZW47CgoJCWlmICghKEdldFZlcnNpb24oKSAmIDB4ODAwMDAwMDApKSB7CS8qIFdpbmRvd3MgTlQ/ICovCgkJCUxPR0JSVVNIIGxiID0ge1BTX1NPTElELCBSR0IoMjU1LDI1NSwyNTUpfTsKCQkJaHBlbiA9IEV4dENyZWF0ZVBlbihQU19DT1NNRVRJQ3xQU19BTFRFUk5BVEUsIDEsICZsYiwgMCwgMCk7CgkJfSBlbHNlCgkJCWhwZW4gPSBDcmVhdGVQZW4oUFNfRE9ULCAwLCBSR0IoMjU1LDI1NSwyNTUpKTsKCgkJbGFzdFBlbiA9IFNlbGVjdFBlbihkaXMtPmhEQywgaHBlbik7CgkJbGFzdEJydXNoID0gU2VsZWN0T2JqZWN0KGRpcy0+aERDLCBHZXRTdG9ja09iamVjdChIT0xMT1dfQlJVU0gpKTsKCQlTZXRST1AyKGRpcy0+aERDLCBSMl9YT1JQRU4pOwoJCVJlY3RhbmdsZShkaXMtPmhEQywgZm9jdXNSZWN0LmxlZnQsIGZvY3VzUmVjdC50b3AsIGZvY3VzUmVjdC5yaWdodCwgZm9jdXNSZWN0LmJvdHRvbSk7CgkJU2VsZWN0T2JqZWN0KGRpcy0+aERDLCBsYXN0QnJ1c2gpOwoJCVNlbGVjdE9iamVjdChkaXMtPmhEQywgbGFzdFBlbik7CgkJRGVsZXRlT2JqZWN0KGhwZW4pOwoJfQojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KfQoKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoKc3RhdGljIHZvaWQgZHJhd19zcGxpdGJhcihIV05EIGh3bmQsIGludCB4KQp7CglSRUNUIHJ0OwoJSERDIGhkYyA9IEdldERDKGh3bmQpOwoKCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCglydC5sZWZ0ID0geCAtIFNQTElUX1dJRFRILzI7CglydC5yaWdodCA9IHggKyBTUExJVF9XSURUSC8yKzE7CgoJSW52ZXJ0UmVjdChoZGMsICZydCk7CgoJUmVsZWFzZURDKGh3bmQsIGhkYyk7Cn0KCiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCnN0YXRpYyB2b2lkIHNldF9oZWFkZXIoUGFuZSogcGFuZSkKewoJSERfSVRFTSBpdGVtOwoJaW50IHNjcm9sbF9wb3MgPSBHZXRTY3JvbGxQb3MocGFuZS0+aHduZCwgU0JfSE9SWik7CglpbnQgaT0wLCB4PTA7CgoJaXRlbS5tYXNrID0gSERJX1dJRFRIOwoJaXRlbS5jeHkgPSAwOwoKCWZvcig7IHgrcGFuZS0+d2lkdGhzW2ldPHNjcm9sbF9wb3MgJiYgaTxDT0xVTU5TOyBpKyspIHsKCQl4ICs9IHBhbmUtPndpZHRoc1tpXTsKCQlTZW5kTWVzc2FnZShwYW5lLT5od25kSGVhZGVyLCBIRE1fU0VUSVRFTSwgaSwgKExQQVJBTSkgJml0ZW0pOwoJfQoKCWlmIChpIDwgQ09MVU1OUykgewoJCXggKz0gcGFuZS0+d2lkdGhzW2ldOwoJCWl0ZW0uY3h5ID0geCAtIHNjcm9sbF9wb3M7CgkJU2VuZE1lc3NhZ2UocGFuZS0+aHduZEhlYWRlciwgSERNX1NFVElURU0sIGkrKywgKExQQVJBTSkgJml0ZW0pOwoKCQlmb3IoOyBpPENPTFVNTlM7IGkrKykgewoJCQlpdGVtLmN4eSA9IHBhbmUtPndpZHRoc1tpXTsKCQkJeCArPSBwYW5lLT53aWR0aHNbaV07CgkJCVNlbmRNZXNzYWdlKHBhbmUtPmh3bmRIZWFkZXIsIEhETV9TRVRJVEVNLCBpLCAoTFBBUkFNKSAmaXRlbSk7CgkJfQoJfQp9CgpzdGF0aWMgTFJFU1VMVCBwYW5lX25vdGlmeShQYW5lKiBwYW5lLCBOTUhEUiogcG5taCkKewoJc3dpdGNoKHBubWgtPmNvZGUpIHsKCQljYXNlIEhETl9UUkFDSzoKCQljYXNlIEhETl9FTkRUUkFDSzogewoJCQlIRF9OT1RJRlkqIHBoZG4gPSAoSERfTk9USUZZKikgcG5taDsKCQkJaW50IGlkeCA9IHBoZG4tPmlJdGVtOwoJCQlpbnQgZHggPSBwaGRuLT5waXRlbS0+Y3h5IC0gcGFuZS0+d2lkdGhzW2lkeF07CgkJCWludCBpOwoKCQkJUkVDVCBjbG50OwoJCQlHZXRDbGllbnRSZWN0KHBhbmUtPmh3bmQsICZjbG50KTsKCgkJCS8qIG1vdmUgaW1tZWRpYXRlIHRvIHNpbXVsYXRlIEhEU19GVUxMRFJBRyAoZm9yIG5vdyBbMDQvMjAwMF0gbm90IHJlYWxseSBuZWVkZWQgd2l0aCBXSU5FTElCKSAqLwoJCQlTZW5kTWVzc2FnZShwYW5lLT5od25kSGVhZGVyLCBIRE1fU0VUSVRFTSwgaWR4LCAoTFBBUkFNKSBwaGRuLT5waXRlbSk7CgoJCQlwYW5lLT53aWR0aHNbaWR4XSArPSBkeDsKCgkJCWZvcihpPWlkeDsgKytpPD1DT0xVTU5TOyApCgkJCQlwYW5lLT5wb3NpdGlvbnNbaV0gKz0gZHg7CgoJCQl7CgkJCQlpbnQgc2Nyb2xsX3BvcyA9IEdldFNjcm9sbFBvcyhwYW5lLT5od25kLCBTQl9IT1JaKTsKCQkJCVJFQ1QgcnRfc2NyOwoJCQkJUkVDVCBydF9jbGlwOwoKCQkJCXJ0X3Njci5sZWZ0ICAgPSBwYW5lLT5wb3NpdGlvbnNbaWR4KzFdLXNjcm9sbF9wb3M7CgkJCQlydF9zY3IudG9wICAgID0gMDsKCQkJCXJ0X3Njci5yaWdodCAgPSBjbG50LnJpZ2h0OwoJCQkJcnRfc2NyLmJvdHRvbSA9IGNsbnQuYm90dG9tOwoKCQkJCXJ0X2NsaXAubGVmdCAgID0gcGFuZS0+cG9zaXRpb25zW2lkeF0tc2Nyb2xsX3BvczsKCQkJCXJ0X2NsaXAudG9wICAgID0gMDsKCQkJCXJ0X2NsaXAucmlnaHQgID0gY2xudC5yaWdodDsKCQkJCXJ0X2NsaXAuYm90dG9tID0gY2xudC5ib3R0b207CgoJCQkJaWYgKHJ0X3Njci5sZWZ0IDwgMCkgcnRfc2NyLmxlZnQgPSAwOwoJCQkJaWYgKHJ0X2NsaXAubGVmdCA8IDApIHJ0X2NsaXAubGVmdCA9IDA7CgoJCQkJU2Nyb2xsV2luZG93RXgocGFuZS0+aHduZCwgZHgsIDAsICZydF9zY3IsICZydF9jbGlwLCAwLCAwLCBTV19JTlZBTElEQVRFKTsKCgkJCQlydF9jbGlwLnJpZ2h0ID0gcGFuZS0+cG9zaXRpb25zW2lkeCsxXTsKCQkJCVJlZHJhd1dpbmRvdyhwYW5lLT5od25kLCAmcnRfY2xpcCwgMCwgUkRXX0lOVkFMSURBVEV8UkRXX1VQREFURU5PVyk7CgoJCQkJaWYgKHBubWgtPmNvZGUgPT0gSEROX0VORFRSQUNLKSB7CgkJCQkJU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfU0VUSE9SSVpPTlRBTEVYVEVOVCwgcGFuZS0+cG9zaXRpb25zW0NPTFVNTlNdLCAwKTsKCgkJCQkJaWYgKEdldFNjcm9sbFBvcyhwYW5lLT5od25kLCBTQl9IT1JaKSAhPSBzY3JvbGxfcG9zKQoJCQkJCQlzZXRfaGVhZGVyKHBhbmUpOwoJCQkJfQoJCQl9CgoJCQlyZXR1cm4gRkFMU0U7CgkJfQoKCQljYXNlIEhETl9ESVZJREVSREJMQ0xJQ0s6IHsKCQkJSERfTk9USUZZKiBwaGRuID0gKEhEX05PVElGWSopIHBubWg7CgkJCUhEX0lURU0gaXRlbTsKCgkJCWNhbGNfc2luZ2xlX3dpZHRoKHBhbmUsIHBoZG4tPmlJdGVtKTsKCQkJaXRlbS5tYXNrID0gSERJX1dJRFRIOwoJCQlpdGVtLmN4eSA9IHBhbmUtPndpZHRoc1twaGRuLT5pSXRlbV07CgoJCQlTZW5kTWVzc2FnZShwYW5lLT5od25kSGVhZGVyLCBIRE1fU0VUSVRFTSwgcGhkbi0+aUl0ZW0sIChMUEFSQU0pICZpdGVtKTsKCQkJSW52YWxpZGF0ZVJlY3QocGFuZS0+aHduZCwgMCwgVFJVRSk7CgkJCWJyZWFrO30KCX0KCglyZXR1cm4gMDsKfQoKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoKc3RhdGljIHZvaWQgc2Nhbl9lbnRyeShDaGlsZFduZCogY2hpbGQsIEVudHJ5KiBlbnRyeSwgaW50IGlkeCwgSFdORCBod25kKQp7CglUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCUhDVVJTT1Igb2xkX2N1cnNvciA9IFNldEN1cnNvcihMb2FkQ3Vyc29yKDAsIElEQ19XQUlUKSk7CgoJLyogZGVsZXRlIHN1YiBlbnRyaWVzIGluIGxlZnQgcGFuZSAqLwoJZm9yKDs7KSB7CgkJTFJFU1VMVCByZXMgPSBTZW5kTWVzc2FnZShjaGlsZC0+bGVmdC5od25kLCBMQl9HRVRJVEVNREFUQSwgaWR4KzEsIDApOwoJCUVudHJ5KiBzdWIgPSAoRW50cnkqKSByZXM7CgoJCWlmIChyZXM9PUxCX0VSUiB8fCAhc3ViIHx8IHN1Yi0+bGV2ZWw8PWVudHJ5LT5sZXZlbCkKCQkJYnJlYWs7CgoJCVNlbmRNZXNzYWdlKGNoaWxkLT5sZWZ0Lmh3bmQsIExCX0RFTEVURVNUUklORywgaWR4KzEsIDApOwoJfQoKCS8qIGVtcHR5IHJpZ2h0IHBhbmUgKi8KCVNlbmRNZXNzYWdlKGNoaWxkLT5yaWdodC5od25kLCBMQl9SRVNFVENPTlRFTlQsIDAsIDApOwoKCS8qIHJlbGVhc2UgbWVtb3J5ICovCglmcmVlX2VudHJpZXMoZW50cnkpOwoKCS8qIHJlYWQgY29udGVudHMgZnJvbSBkaXNrICovCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGVudHJ5LT5ldHlwZSA9PSBFVF9TSEVMTCkKCXsKCQlyZWFkX2RpcmVjdG9yeShlbnRyeSwgTlVMTCwgY2hpbGQtPnNvcnRPcmRlciwgaHduZCk7Cgl9CgllbHNlCiNlbmRpZgoJewoJCWdldF9wYXRoKGVudHJ5LCBwYXRoKTsKCQlyZWFkX2RpcmVjdG9yeShlbnRyeSwgcGF0aCwgY2hpbGQtPnNvcnRPcmRlciwgaHduZCk7Cgl9CgoJLyogaW5zZXJ0IGZvdW5kIGVudHJpZXMgaW4gcmlnaHQgcGFuZSAqLwoJaW5zZXJ0X2VudHJpZXMoJmNoaWxkLT5yaWdodCwgZW50cnktPmRvd24sIGNoaWxkLT5maWx0ZXJfcGF0dGVybiwgY2hpbGQtPmZpbHRlcl9mbGFncywgLTEpOwoJY2FsY193aWR0aHMoJmNoaWxkLT5yaWdodCwgRkFMU0UpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglzZXRfaGVhZGVyKCZjaGlsZC0+cmlnaHQpOwojZW5kaWYKCgljaGlsZC0+aGVhZGVyX3dkdGhzX29rID0gRkFMU0U7CgoJU2V0Q3Vyc29yKG9sZF9jdXJzb3IpOwp9CgoKLyogZXhwYW5kIGEgZGlyZWN0b3J5IGVudHJ5ICovCgpzdGF0aWMgQk9PTCBleHBhbmRfZW50cnkoQ2hpbGRXbmQqIGNoaWxkLCBFbnRyeSogZGlyKQp7CglpbnQgaWR4OwoJRW50cnkqIHA7CgoJaWYgKCFkaXIgfHwgZGlyLT5leHBhbmRlZCB8fCAhZGlyLT5kb3duKQoJCXJldHVybiBGQUxTRTsKCglwID0gZGlyLT5kb3duOwoKCWlmIChwLT5kYXRhLmNGaWxlTmFtZVswXT09Jy4nICYmIHAtPmRhdGEuY0ZpbGVOYW1lWzFdPT0nXDAnICYmIHAtPm5leHQpIHsKCQlwID0gcC0+bmV4dDsKCgkJaWYgKHAtPmRhdGEuY0ZpbGVOYW1lWzBdPT0nLicgJiYgcC0+ZGF0YS5jRmlsZU5hbWVbMV09PScuJyAmJgoJCQkJcC0+ZGF0YS5jRmlsZU5hbWVbMl09PSdcMCcgJiYgcC0+bmV4dCkKCQkJcCA9IHAtPm5leHQ7Cgl9CgoJLyogbm8gc3ViZGlyZWN0b3JpZXMgPyAqLwoJaWYgKCEocC0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkpCgkJcmV0dXJuIEZBTFNFOwoKCWlkeCA9IFNlbmRNZXNzYWdlKGNoaWxkLT5sZWZ0Lmh3bmQsIExCX0ZJTkRTVFJJTkcsIDAsIChMUEFSQU0pZGlyKTsKCglkaXItPmV4cGFuZGVkID0gVFJVRTsKCgkvKiBpbnNlcnQgZW50cmllcyBpbiBsZWZ0IHBhbmUgKi8KCWluc2VydF9lbnRyaWVzKCZjaGlsZC0+bGVmdCwgcCwgTlVMTCwgVEZfQUxMLCBpZHgpOwoKCWlmICghY2hpbGQtPmhlYWRlcl93ZHRoc19vaykgewoJCWlmIChjYWxjX3dpZHRocygmY2hpbGQtPmxlZnQsIEZBTFNFKSkgewojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCXNldF9oZWFkZXIoJmNoaWxkLT5sZWZ0KTsKI2VuZGlmCgoJCQljaGlsZC0+aGVhZGVyX3dkdGhzX29rID0gVFJVRTsKCQl9Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCgpzdGF0aWMgdm9pZCBjb2xsYXBzZV9lbnRyeShQYW5lKiBwYW5lLCBFbnRyeSogZGlyKQp7CglpbnQgaWR4ID0gU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfRklORFNUUklORywgMCwgKExQQVJBTSlkaXIpOwoKCVNob3dXaW5kb3cocGFuZS0+aHduZCwgU1dfSElERSk7CgoJLyogaGlkZSBzdWIgZW50cmllcyAqLwoJZm9yKDs7KSB7CgkJTFJFU1VMVCByZXMgPSBTZW5kTWVzc2FnZShwYW5lLT5od25kLCBMQl9HRVRJVEVNREFUQSwgaWR4KzEsIDApOwoJCUVudHJ5KiBzdWIgPSAoRW50cnkqKSByZXM7CgoJCWlmIChyZXM9PUxCX0VSUiB8fCAhc3ViIHx8IHN1Yi0+bGV2ZWw8PWRpci0+bGV2ZWwpCgkJCWJyZWFrOwoKCQlTZW5kTWVzc2FnZShwYW5lLT5od25kLCBMQl9ERUxFVEVTVFJJTkcsIGlkeCsxLCAwKTsKCX0KCglkaXItPmV4cGFuZGVkID0gRkFMU0U7CgoJU2hvd1dpbmRvdyhwYW5lLT5od25kLCBTV19TSE9XKTsKfQoKCnN0YXRpYyB2b2lkIHJlZnJlc2hfcmlnaHRfcGFuZShDaGlsZFduZCogY2hpbGQpCnsKCVNlbmRNZXNzYWdlKGNoaWxkLT5yaWdodC5od25kLCBMQl9SRVNFVENPTlRFTlQsIDAsIDApOwoJaW5zZXJ0X2VudHJpZXMoJmNoaWxkLT5yaWdodCwgY2hpbGQtPnJpZ2h0LnJvb3QsIGNoaWxkLT5maWx0ZXJfcGF0dGVybiwgY2hpbGQtPmZpbHRlcl9mbGFncywgLTEpOwoJY2FsY193aWR0aHMoJmNoaWxkLT5yaWdodCwgRkFMU0UpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJc2V0X2hlYWRlcigmY2hpbGQtPnJpZ2h0KTsKI2VuZGlmCn0KCnN0YXRpYyB2b2lkIHNldF9jdXJkaXIoQ2hpbGRXbmQqIGNoaWxkLCBFbnRyeSogZW50cnksIGludCBpZHgsIEhXTkQgaHduZCkKewoJVENIQVIgcGF0aFtNQVhfUEFUSF07CgoJaWYgKCFlbnRyeSkKCQlyZXR1cm47CgoJcGF0aFswXSA9ICdcMCc7CgoJY2hpbGQtPmxlZnQuY3VyID0gZW50cnk7CgoJY2hpbGQtPnJpZ2h0LnJvb3QgPSBlbnRyeS0+ZG93bj8gZW50cnktPmRvd246IGVudHJ5OwoJY2hpbGQtPnJpZ2h0LmN1ciA9IGVudHJ5OwoKCWlmICghZW50cnktPnNjYW5uZWQpCgkJc2Nhbl9lbnRyeShjaGlsZCwgZW50cnksIGlkeCwgaHduZCk7CgllbHNlCgkJcmVmcmVzaF9yaWdodF9wYW5lKGNoaWxkKTsKCglnZXRfcGF0aChlbnRyeSwgcGF0aCk7Cglsc3RyY3B5KGNoaWxkLT5wYXRoLCBwYXRoKTsKCglpZiAoY2hpbGQtPmh3bmQpCS8qIG9ubHkgY2hhbmdlIHdpbmRvdyB0aXRsZSwgaWYgdGhlIHdpbmRvdyBhbHJlYWR5IGV4aXN0cyAqLwoJCVNldFdpbmRvd1RleHQoY2hpbGQtPmh3bmQsIHBhdGgpOwoKCWlmIChwYXRoWzBdKQoJCWlmIChTZXRDdXJyZW50RGlyZWN0b3J5KHBhdGgpKQoJCQlzZXRfc3BhY2Vfc3RhdHVzKCk7Cn0KCgpzdGF0aWMgdm9pZCByZWZyZXNoX2NoaWxkKENoaWxkV25kKiBjaGlsZCkKewoJVENIQVIgcGF0aFtNQVhfUEFUSF0sIGRydltfTUFYX0RSSVZFKzFdOwoJRW50cnkqIGVudHJ5OwoJaW50IGlkeDsKCglnZXRfcGF0aChjaGlsZC0+bGVmdC5jdXIsIHBhdGgpOwoJX3RzcGxpdHBhdGgocGF0aCwgZHJ2LCBOVUxMLCBOVUxMLCBOVUxMKTsKCgljaGlsZC0+cmlnaHQucm9vdCA9IE5VTEw7CgoJc2Nhbl9lbnRyeShjaGlsZCwgJmNoaWxkLT5yb290LmVudHJ5LCAwLCBjaGlsZC0+aHduZCk7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChjaGlsZC0+cm9vdC5lbnRyeS5ldHlwZSA9PSBFVF9TSEVMTCkKCQllbnRyeSA9IHJlYWRfdHJlZSgmY2hpbGQtPnJvb3QsIE5VTEwsIGdldF9wYXRoX3BpZGwocGF0aCxjaGlsZC0+aHduZCksIGRydiwgY2hpbGQtPnNvcnRPcmRlciwgY2hpbGQtPmh3bmQpOwoJZWxzZQojZW5kaWYKCQllbnRyeSA9IHJlYWRfdHJlZSgmY2hpbGQtPnJvb3QsIHBhdGgsIE5VTEwsIGRydiwgY2hpbGQtPnNvcnRPcmRlciwgY2hpbGQtPmh3bmQpOwoKCWlmICghZW50cnkpCgkJZW50cnkgPSAmY2hpbGQtPnJvb3QuZW50cnk7CgoJaW5zZXJ0X2VudHJpZXMoJmNoaWxkLT5sZWZ0LCBjaGlsZC0+cm9vdC5lbnRyeS5kb3duLCBOVUxMLCBURl9BTEwsIDApOwoKCXNldF9jdXJkaXIoY2hpbGQsIGVudHJ5LCAwLCBjaGlsZC0+aHduZCk7CgoJaWR4ID0gU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZCwgTEJfRklORFNUUklORywgMCwgKExQQVJBTSljaGlsZC0+bGVmdC5jdXIpOwoJU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZCwgTEJfU0VUQ1VSU0VMLCBpZHgsIDApOwp9CgoKc3RhdGljIHZvaWQgY3JlYXRlX2RyaXZlX2Jhcih2b2lkKQp7CglUQkJVVFRPTiBkcml2ZWJhckJ0biA9IHswLCAwLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9OwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglUQ0hBUiBiMVtCVUZGRVJfTEVOXTsKI2VuZGlmCglpbnQgYnRuID0gMTsKCVBUU1RSIHA7CgoJR2V0TG9naWNhbERyaXZlU3RyaW5ncyhCVUZGRVJfTEVOLCBHbG9iYWxzLmRyaXZlcyk7CgoJR2xvYmFscy5oZHJpdmViYXIgPSBDcmVhdGVUb29sYmFyRXgoR2xvYmFscy5oTWFpblduZCwgV1NfQ0hJTER8V1NfVklTSUJMRXxDQ1NfTk9NT1ZFWXxUQlNUWUxFX0xJU1QsCgkJCQlJRFdfRFJJVkVCQVIsIDIsIEdsb2JhbHMuaEluc3RhbmNlLCBJREJfRFJJVkVCQVIsICZkcml2ZWJhckJ0biwKCQkJCTAsIDE2LCAxMywgMTYsIDEzLCBzaXplb2YoVEJCVVRUT04pKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKI2lmZGVmIF9fV0lORV9fCgkvKiBpbnNlcnQgdW5peCBmaWxlIHN5c3RlbSBidXR0b24gKi8KCWIxWzBdID0gJy8nOwoJYjFbMV0gPSAnXDAnOwoJYjFbMl0gPSAnXDAnOwoJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0FERFNUUklORywgMCwgKExQQVJBTSliMSk7CgoJZHJpdmViYXJCdG4uaWRDb21tYW5kID0gSURfRFJJVkVfVU5JWF9GUzsKCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9JTlNFUlRCVVRUT04sIGJ0bisrLCAoTFBBUkFNKSZkcml2ZWJhckJ0bik7Cglkcml2ZWJhckJ0bi5pU3RyaW5nKys7CiNlbmRpZgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCS8qIGluc2VydCBzaGVsbCBuYW1lc3BhY2UgYnV0dG9uICovCglsb2FkX3N0cmluZyhiMSwgSURTX1NIRUxMKTsKCWIxW2xzdHJsZW4oYjEpKzFdID0gJ1wwJzsKCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9BRERTVFJJTkcsIDAsIChMUEFSQU0pYjEpOwoKCWRyaXZlYmFyQnRuLmlkQ29tbWFuZCA9IElEX0RSSVZFX1NIRUxMX05TOwoJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0lOU0VSVEJVVFRPTiwgYnRuKyssIChMUEFSQU0pJmRyaXZlYmFyQnRuKTsKCWRyaXZlYmFyQnRuLmlTdHJpbmcrKzsKI2VuZGlmCgoJLyogcmVnaXN0ZXIgd2luZG93cyBkcml2ZSByb290IHN0cmluZ3MgKi8KCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9BRERTVFJJTkcsIDAsIChMUEFSQU0pR2xvYmFscy5kcml2ZXMpOwojZW5kaWYKCglkcml2ZWJhckJ0bi5pZENvbW1hbmQgPSBJRF9EUklWRV9GSVJTVDsKCglmb3IocD1HbG9iYWxzLmRyaXZlczsgKnA7ICkgewojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkvKiBpbnNlcnQgZHJpdmUgbGV0dGVyICovCgkJVENIQVIgYlszXSA9IHt0b2xvd2VyKCpwKX07CgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0FERFNUUklORywgMCwgKExQQVJBTSliKTsKI2VuZGlmCgkJc3dpdGNoKEdldERyaXZlVHlwZShwKSkgewoJCQljYXNlIERSSVZFX1JFTU9WQUJMRToJZHJpdmViYXJCdG4uaUJpdG1hcCA9IDE7CWJyZWFrOwoJCQljYXNlIERSSVZFX0NEUk9NOgkJZHJpdmViYXJCdG4uaUJpdG1hcCA9IDM7CWJyZWFrOwoJCQljYXNlIERSSVZFX1JFTU9URToJCWRyaXZlYmFyQnRuLmlCaXRtYXAgPSA0OwlicmVhazsKCQkJY2FzZSBEUklWRV9SQU1ESVNLOgkJZHJpdmViYXJCdG4uaUJpdG1hcCA9IDU7CWJyZWFrOwoJCQlkZWZhdWx0Oi8qRFJJVkVfRklYRUQqLwlkcml2ZWJhckJ0bi5pQml0bWFwID0gMjsKCQl9CgoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9JTlNFUlRCVVRUT04sIGJ0bisrLCAoTFBBUkFNKSZkcml2ZWJhckJ0bik7CgkJZHJpdmViYXJCdG4uaWRDb21tYW5kKys7CgkJZHJpdmViYXJCdG4uaVN0cmluZysrOwoKCQl3aGlsZSgqcCsrKTsKCX0KfQoKc3RhdGljIHZvaWQgcmVmcmVzaF9kcml2ZXModm9pZCkKewoJUkVDVCByZWN0OwoKCS8qIGRlc3Ryb3kgZHJpdmUgYmFyICovCglEZXN0cm95V2luZG93KEdsb2JhbHMuaGRyaXZlYmFyKTsKCUdsb2JhbHMuaGRyaXZlYmFyID0gMDsKCgkvKiByZS1jcmVhdGUgZHJpdmUgYmFyICovCgljcmVhdGVfZHJpdmVfYmFyKCk7CgoJLyogdXBkYXRlIHdpbmRvdyBsYXlvdXQgKi8KCUdldENsaWVudFJlY3QoR2xvYmFscy5oTWFpblduZCwgJnJlY3QpOwoJU2VuZE1lc3NhZ2UoR2xvYmFscy5oTWFpblduZCwgV01fU0laRSwgMCwgTUFLRUxPTkcocmVjdC5yaWdodCwgcmVjdC5ib3R0b20pKTsKfQoKCnN0YXRpYyBCT09MIGxhdW5jaF9maWxlKEhXTkQgaHduZCwgTFBDVFNUUiBjbWQsIFVJTlQgbkNtZFNob3cpCnsKCUhJTlNUQU5DRSBoaW5zdCA9IFNoZWxsRXhlY3V0ZShod25kLCBOVUxMLypvcGVyYXRpb24qLywgY21kLCBOVUxMLypwYXJhbWV0ZXJzKi8sIE5VTEwvKmRpciovLCBuQ21kU2hvdyk7CgoJaWYgKChpbnQpaGluc3QgPD0gMzIpIHsKCQlkaXNwbGF5X2Vycm9yKGh3bmQsIEdldExhc3RFcnJvcigpKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCgpzdGF0aWMgQk9PTCBsYXVuY2hfZW50cnkoRW50cnkqIGVudHJ5LCBIV05EIGh3bmQsIFVJTlQgbkNtZFNob3cpCnsKCVRDSEFSIGNtZFtNQVhfUEFUSF07CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChlbnRyeS0+ZXR5cGUgPT0gRVRfU0hFTEwpIHsKCQlCT09MIHJldCA9IFRSVUU7CgoJCVNIRUxMRVhFQ1VURUlORk8gc2hleGluZm87CgoJCXNoZXhpbmZvLmNiU2l6ZSA9IHNpemVvZihTSEVMTEVYRUNVVEVJTkZPKTsKCQlzaGV4aW5mby5mTWFzayA9IFNFRV9NQVNLX0lETElTVDsKCQlzaGV4aW5mby5od25kID0gaHduZDsKCQlzaGV4aW5mby5scFZlcmIgPSBOVUxMOwoJCXNoZXhpbmZvLmxwRmlsZSA9IE5VTEw7CgkJc2hleGluZm8ubHBQYXJhbWV0ZXJzID0gTlVMTDsKCQlzaGV4aW5mby5scERpcmVjdG9yeSA9IE5VTEw7CgkJc2hleGluZm8ublNob3cgPSBuQ21kU2hvdzsKCQlzaGV4aW5mby5scElETGlzdCA9IGdldF90b19hYnNvbHV0ZV9waWRsKGVudHJ5LCBod25kKTsKCgkJaWYgKCFTaGVsbEV4ZWN1dGVFeCgmc2hleGluZm8pKSB7CgkJCWRpc3BsYXlfZXJyb3IoaHduZCwgR2V0TGFzdEVycm9yKCkpOwoJCQlyZXQgPSBGQUxTRTsKCQl9CgoJCWlmIChzaGV4aW5mby5scElETGlzdCAhPSBlbnRyeS0+cGlkbCkKCQkJSU1hbGxvY19GcmVlKEdsb2JhbHMuaU1hbGxvYywgc2hleGluZm8ubHBJRExpc3QpOwoKCQlyZXR1cm4gcmV0OwoJfQojZW5kaWYKCglnZXRfcGF0aChlbnRyeSwgY21kKTsKCgkgLyogc3RhcnQgcHJvZ3JhbSwgb3BlbiBkb2N1bWVudC4uLiAqLwoJcmV0dXJuIGxhdW5jaF9maWxlKGh3bmQsIGNtZCwgbkNtZFNob3cpOwp9CgoKc3RhdGljIHZvaWQgYWN0aXZhdGVfZW50cnkoQ2hpbGRXbmQqIGNoaWxkLCBQYW5lKiBwYW5lLCBIV05EIGh3bmQpCnsKCUVudHJ5KiBlbnRyeSA9IHBhbmUtPmN1cjsKCglpZiAoIWVudHJ5KQoJCXJldHVybjsKCglpZiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCWludCBzY2FubmVkX29sZCA9IGVudHJ5LT5zY2FubmVkOwoKCQlpZiAoIXNjYW5uZWRfb2xkKQoJCXsKCQkJaW50IGlkeCA9IFNlbmRNZXNzYWdlKGNoaWxkLT5sZWZ0Lmh3bmQsIExCX0dFVENVUlNFTCwgMCwgMCk7CgkJCXNjYW5fZW50cnkoY2hpbGQsIGVudHJ5LCBpZHgsIGh3bmQpOwoJCX0KCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQlpZiAoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT0nLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT0nXDAnKQoJCQlyZXR1cm47CiNlbmRpZgoKCQlpZiAoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT0nLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT0nLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzJdPT0nXDAnKSB7CgkJCWVudHJ5ID0gY2hpbGQtPmxlZnQuY3VyLT51cDsKCQkJY29sbGFwc2VfZW50cnkoJmNoaWxkLT5sZWZ0LCBlbnRyeSk7CgkJCWdvdG8gZm9jdXNfZW50cnk7CgkJfSBlbHNlIGlmIChlbnRyeS0+ZXhwYW5kZWQpCgkJCWNvbGxhcHNlX2VudHJ5KHBhbmUsIGNoaWxkLT5sZWZ0LmN1cik7CgkJZWxzZSB7CgkJCWV4cGFuZF9lbnRyeShjaGlsZCwgY2hpbGQtPmxlZnQuY3VyKTsKCgkJCWlmICghcGFuZS0+dHJlZVBhbmUpIGZvY3VzX2VudHJ5OiB7CgkJCQlpbnQgaWR4c3RhcnQgPSBTZW5kTWVzc2FnZShjaGlsZC0+bGVmdC5od25kLCBMQl9HRVRDVVJTRUwsIDAsIDApOwoJCQkJaW50IGlkeCA9IFNlbmRNZXNzYWdlKGNoaWxkLT5sZWZ0Lmh3bmQsIExCX0ZJTkRTVFJJTkcsIGlkeHN0YXJ0LCAoTFBBUkFNKWVudHJ5KTsKCQkJCVNlbmRNZXNzYWdlKGNoaWxkLT5sZWZ0Lmh3bmQsIExCX1NFVENVUlNFTCwgaWR4LCAwKTsKCQkJCXNldF9jdXJkaXIoY2hpbGQsIGVudHJ5LCBpZHgsIGh3bmQpOwoJCQl9CgkJfQoKCQlpZiAoIXNjYW5uZWRfb2xkKSB7CgkJCWNhbGNfd2lkdGhzKHBhbmUsIEZBTFNFKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJc2V0X2hlYWRlcihwYW5lKTsKI2VuZGlmCgkJfQoJfSBlbHNlIHsKCQlpZiAoR2V0S2V5U3RhdGUoVktfTUVOVSkgPCAwKQoJCQlzaG93X3Byb3BlcnRpZXNfZGxnKGVudHJ5LCBjaGlsZC0+aHduZCk7CgkJZWxzZQoJCQlsYXVuY2hfZW50cnkoZW50cnksIGNoaWxkLT5od25kLCBTV19TSE9XTk9STUFMKTsKCX0KfQoKCnN0YXRpYyBCT09MIHBhbmVfY29tbWFuZChQYW5lKiBwYW5lLCBVSU5UIGNtZCkKewoJc3dpdGNoKGNtZCkgewoJCWNhc2UgSURfVklFV19OQU1FOgoJCQlpZiAocGFuZS0+dmlzaWJsZV9jb2xzKSB7CgkJCQlwYW5lLT52aXNpYmxlX2NvbHMgPSAwOwoJCQkJY2FsY193aWR0aHMocGFuZSwgVFJVRSk7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJCXNldF9oZWFkZXIocGFuZSk7CiNlbmRpZgoJCQkJSW52YWxpZGF0ZVJlY3QocGFuZS0+aHduZCwgMCwgVFJVRSk7CgkJCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX05BTUUsIE1GX0JZQ09NTUFORHxNRl9DSEVDS0VEKTsKCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfQUxMX0FUVFJJQlVURVMsIE1GX0JZQ09NTUFORCk7CgkJCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX1NFTEVDVEVEX0FUVFJJQlVURVMsIE1GX0JZQ09NTUFORCk7CgkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgSURfVklFV19BTExfQVRUUklCVVRFUzoKCQkJaWYgKHBhbmUtPnZpc2libGVfY29scyAhPSBDT0xfQUxMKSB7CgkJCQlwYW5lLT52aXNpYmxlX2NvbHMgPSBDT0xfQUxMOwoJCQkJY2FsY193aWR0aHMocGFuZSwgVFJVRSk7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJCXNldF9oZWFkZXIocGFuZSk7CiNlbmRpZgoJCQkJSW52YWxpZGF0ZVJlY3QocGFuZS0+aHduZCwgMCwgVFJVRSk7CgkJCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX05BTUUsIE1GX0JZQ09NTUFORCk7CgkJCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX0FMTF9BVFRSSUJVVEVTLCBNRl9CWUNPTU1BTkR8TUZfQ0hFQ0tFRCk7CgkJCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX1NFTEVDVEVEX0FUVFJJQlVURVMsIE1GX0JZQ09NTUFORCk7CgkJCX0KCQkJYnJlYWs7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJY2FzZSBJRF9QUkVGRVJSRURfU0laRVM6IHsKCQkJY2FsY193aWR0aHMocGFuZSwgVFJVRSk7CgkJCXNldF9oZWFkZXIocGFuZSk7CgkJCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoJCQlicmVhazt9CiNlbmRpZgoKCQkgICAgICAgIC8qIFRPRE86IG1vcmUgY29tbWFuZCBpZHMuLi4gKi8KCgkJZGVmYXVsdDoKCQkJcmV0dXJuIEZBTFNFOwoJfQoKCXJldHVybiBUUlVFOwp9CgoKc3RhdGljIHZvaWQgc2V0X3NvcnRfb3JkZXIoQ2hpbGRXbmQqIGNoaWxkLCBTT1JUX09SREVSIHNvcnRPcmRlcikKewoJaWYgKGNoaWxkLT5zb3J0T3JkZXIgIT0gc29ydE9yZGVyKSB7CgkJY2hpbGQtPnNvcnRPcmRlciA9IHNvcnRPcmRlcjsKCQlyZWZyZXNoX2NoaWxkKGNoaWxkKTsKCX0KfQoKc3RhdGljIHZvaWQgdXBkYXRlX3ZpZXdfbWVudShDaGlsZFduZCogY2hpbGQpCnsKCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfU09SVF9OQU1FLCBjaGlsZC0+c29ydE9yZGVyPT1TT1JUX05BTUU/IE1GX0NIRUNLRUQ6IE1GX1VOQ0hFQ0tFRCk7CglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX1NPUlRfVFlQRSwgY2hpbGQtPnNvcnRPcmRlcj09U09SVF9FWFQ/IE1GX0NIRUNLRUQ6IE1GX1VOQ0hFQ0tFRCk7CglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX1NPUlRfU0laRSwgY2hpbGQtPnNvcnRPcmRlcj09U09SVF9TSVpFPyBNRl9DSEVDS0VEOiBNRl9VTkNIRUNLRUQpOwoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19TT1JUX0RBVEUsIGNoaWxkLT5zb3J0T3JkZXI9PVNPUlRfREFURT8gTUZfQ0hFQ0tFRDogTUZfVU5DSEVDS0VEKTsKfQoKCnN0YXRpYyBCT09MIGlzX2RpcmVjdG9yeShMUENUU1RSIHRhcmdldCkKewoJLypUT0RPIGNvcnJlY3RseSBoYW5kbGUgVU5JWCBwYXRocyAqLwoJRFdPUkQgdGFyZ2V0X2F0dHIgPSBHZXRGaWxlQXR0cmlidXRlcyh0YXJnZXQpOwoKCWlmICh0YXJnZXRfYXR0ciA9PSBJTlZBTElEX0ZJTEVfQVRUUklCVVRFUykKCQlyZXR1cm4gRkFMU0U7CgoJcmV0dXJuIHRhcmdldF9hdHRyJkZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWT8gVFJVRTogRkFMU0U7Cn0KCQpzdGF0aWMgQk9PTCBwcm9tcHRfdGFyZ2V0KFBhbmUqIHBhbmUsIExQVFNUUiBzb3VyY2UsIExQVFNUUiB0YXJnZXQpCnsKCVRDSEFSIHBhdGhbTUFYX1BBVEhdOwoJaW50IGxlbjsKCglnZXRfcGF0aChwYW5lLT5jdXIsIHBhdGgpOwoKCWlmIChEaWFsb2dCb3hQYXJhbShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElERF9TRUxFQ1RfREVTVElOQVRJT04pLCBwYW5lLT5od25kLCBEZXN0aW5hdGlvbkRsZ1Byb2MsIChMUEFSQU0pcGF0aCkgIT0gSURPSykKCQlyZXR1cm4gRkFMU0U7CgoJZ2V0X3BhdGgocGFuZS0+Y3VyLCBzb3VyY2UpOwoKCS8qIGNvbnZlcnQgcmVsYXRpdmUgdGFyZ2V0cyB0byBhYnNvbHV0ZSBwYXRocyAqLwoJaWYgKHBhdGhbMF0hPScvJyAmJiBwYXRoWzFdIT0nOicpIHsKCQlnZXRfcGF0aChwYW5lLT5jdXItPnVwLCB0YXJnZXQpOwoJCWxlbiA9IGxzdHJsZW4odGFyZ2V0KTsKCgkJaWYgKHRhcmdldFtsZW4tMV0hPSdcXCcgJiYgdGFyZ2V0W2xlbi0xXSE9Jy8nKQoJCQl0YXJnZXRbbGVuKytdID0gJy8nOwoKCQlsc3RyY3B5KHRhcmdldCtsZW4sIHBhdGgpOwoJfSBlbHNlCgkJbHN0cmNweSh0YXJnZXQsIHBhdGgpOwoKCS8qIElmIHRoZSB0YXJnZXQgYWxyZWFkeSBleGlzdHMgYXMgZGlyZWN0b3J5LCBjcmVhdGUgYSBuZXcgdGFyZ2V0IGJlbG93IHRoaXMuICovCglpZiAoaXNfZGlyZWN0b3J5KHBhdGgpKSB7CgkJVENIQVIgZm5hbWVbX01BWF9GTkFNRV0sIGV4dFtfTUFYX0VYVF07CgkJc3RhdGljIGNvbnN0IFRDSEFSIHNBcHBlbmRbXSA9IHsnJScsJ3MnLCcvJywnJScsJ3MnLCclJywncycsJ1wwJ307CgoJCV90c3BsaXRwYXRoKHNvdXJjZSwgTlVMTCwgTlVMTCwgZm5hbWUsIGV4dCk7CgoJCXdzcHJpbnRmKHRhcmdldCwgc0FwcGVuZCwgcGF0aCwgZm5hbWUsIGV4dCk7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCgpzdGF0aWMgSUNvbnRleHRNZW51Miogc19wY3R4bWVudTIgPSBOVUxMOwpzdGF0aWMgSUNvbnRleHRNZW51Myogc19wY3R4bWVudTMgPSBOVUxMOwoKc3RhdGljIHZvaWQgQ3R4TWVudV9yZXNldCh2b2lkKQp7CglzX3BjdHhtZW51MiA9IE5VTEw7CglzX3BjdHhtZW51MyA9IE5VTEw7Cn0KCnN0YXRpYyBJQ29udGV4dE1lbnUqIEN0eE1lbnVfcXVlcnlfaW50ZXJmYWNlcyhJQ29udGV4dE1lbnUqIHBjbTEpCnsKCUlDb250ZXh0TWVudSogcGNtID0gTlVMTDsKCglDdHhNZW51X3Jlc2V0KCk7CgoJaWYgKElDb250ZXh0TWVudV9RdWVyeUludGVyZmFjZShwY20xLCAmSUlEX0lDb250ZXh0TWVudTMsICh2b2lkKiopJnBjbSkgPT0gTk9FUlJPUikKCQlzX3BjdHhtZW51MyA9IChMUENPTlRFWFRNRU5VMylwY207CgllbHNlIGlmIChJQ29udGV4dE1lbnVfUXVlcnlJbnRlcmZhY2UocGNtMSwgJklJRF9JQ29udGV4dE1lbnUyLCAodm9pZCoqKSZwY20pID09IE5PRVJST1IpCgkJc19wY3R4bWVudTIgPSAoTFBDT05URVhUTUVOVTIpcGNtOwoKCWlmIChwY20pIHsKCQlJQ29udGV4dE1lbnVfUmVsZWFzZShwY20xKTsKCQlyZXR1cm4gcGNtOwoJfSBlbHNlCgkJcmV0dXJuIHBjbTE7Cn0KCnN0YXRpYyBCT09MIEN0eE1lbnVfSGFuZGxlTWVudU1zZyhVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCWlmIChzX3BjdHhtZW51MykgewoJCWlmIChTVUNDRUVERUQoSUNvbnRleHRNZW51M19IYW5kbGVNZW51TXNnKHNfcGN0eG1lbnUzLCBubXNnLCB3cGFyYW0sIGxwYXJhbSkpKQoJCQlyZXR1cm4gVFJVRTsKCX0KCglpZiAoc19wY3R4bWVudTIpCgkJaWYgKFNVQ0NFRURFRChJQ29udGV4dE1lbnUyX0hhbmRsZU1lbnVNc2coc19wY3R4bWVudTIsIG5tc2csIHdwYXJhbSwgbHBhcmFtKSkpCgkJCXJldHVybiBUUlVFOwoKCXJldHVybiBGQUxTRTsKfQoKCnN0YXRpYyBIUkVTVUxUIFNoZWxsRm9sZGVyQ29udGV4dE1lbnUoSVNoZWxsRm9sZGVyKiBzaGVsbF9mb2xkZXIsIEhXTkQgaHduZFBhcmVudCwgaW50IGNpZGwsIExQQ0lURU1JRExJU1QqIGFwaWRsLCBpbnQgeCwgaW50IHkpCnsKCUlDb250ZXh0TWVudSogcGNtOwoJQk9PTCBleGVjdXRlZCA9IEZBTFNFOwoKCUhSRVNVTFQgaHIgPSBJU2hlbGxGb2xkZXJfR2V0VUlPYmplY3RPZihzaGVsbF9mb2xkZXIsIGh3bmRQYXJlbnQsIGNpZGwsIGFwaWRsLCAmSUlEX0lDb250ZXh0TWVudSwgTlVMTCwgKExQVk9JRCopJnBjbSk7Ci8qCUhSRVNVTFQgaHIgPSBDRGVmRm9sZGVyTWVudV9DcmVhdGUyKGRpcj9kaXItPl9waWRsOkRlc2t0b3BGb2xkZXIoKSwgaHduZFBhcmVudCwgMSwgJnBpZGwsIHNoZWxsX2ZvbGRlciwgTlVMTCwgMCwgTlVMTCwgJnBjbSk7ICovCgoJaWYgKFNVQ0NFRURFRChocikpIHsKCQlITUVOVSBobWVudSA9IENyZWF0ZVBvcHVwTWVudSgpOwoKCQlwY20gPSBDdHhNZW51X3F1ZXJ5X2ludGVyZmFjZXMocGNtKTsKCgkJaWYgKGhtZW51KSB7CgkJCWhyID0gSUNvbnRleHRNZW51X1F1ZXJ5Q29udGV4dE1lbnUocGNtLCBobWVudSwgMCwgRkNJRE1fU0hWSUVXRklSU1QsIEZDSURNX1NIVklFV0xBU1QsIENNRl9OT1JNQUwpOwoKCQkJaWYgKFNVQ0NFRURFRChocikpIHsKCQkJCVVJTlQgaWRDbWQgPSBUcmFja1BvcHVwTWVudShobWVudSwgVFBNX0xFRlRBTElHTnxUUE1fUkVUVVJOQ01EfFRQTV9SSUdIVEJVVFRPTiwgeCwgeSwgMCwgaHduZFBhcmVudCwgTlVMTCk7CgoJCQkJQ3R4TWVudV9yZXNldCgpOwoKCQkJCWlmIChpZENtZCkgewoJCQkJICBDTUlOVk9LRUNPTU1BTkRJTkZPIGNtaTsKCgkJCQkgIGNtaS5jYlNpemUgPSBzaXplb2YoQ01JTlZPS0VDT01NQU5ESU5GTyk7CgkJCQkgIGNtaS5mTWFzayA9IDA7CgkJCQkgIGNtaS5od25kID0gaHduZFBhcmVudDsKCQkJCSAgY21pLmxwVmVyYiA9IChMUENTVFIpKElOVF9QVFIpKGlkQ21kIC0gRkNJRE1fU0hWSUVXRklSU1QpOwoJCQkJICBjbWkubHBQYXJhbWV0ZXJzID0gTlVMTDsKCQkJCSAgY21pLmxwRGlyZWN0b3J5ID0gTlVMTDsKCQkJCSAgY21pLm5TaG93ID0gU1dfU0hPV05PUk1BTDsKCQkJCSAgY21pLmR3SG90S2V5ID0gMDsKCQkJCSAgY21pLmhJY29uID0gMDsKCgkJCQkgIGhyID0gSUNvbnRleHRNZW51X0ludm9rZUNvbW1hbmQocGNtLCAmY21pKTsKCQkJCQlleGVjdXRlZCA9IFRSVUU7CgkJCQl9CgkJCX0gZWxzZQoJCQkJQ3R4TWVudV9yZXNldCgpOwoJCX0KCgkJSUNvbnRleHRNZW51X1JlbGVhc2UocGNtKTsKCX0KCglyZXR1cm4gRkFJTEVEKGhyKT8gaHI6IGV4ZWN1dGVkPyBTX09LOiBTX0ZBTFNFOwp9CgoKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgQ2hpbGRXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nUHRyKGh3bmQsIEdXTFBfVVNFUkRBVEEpOwoJQVNTRVJUKGNoaWxkKTsKCglzd2l0Y2gobm1zZykgewoJCWNhc2UgV01fRFJBV0lURU06IHsKCQkJTFBEUkFXSVRFTVNUUlVDVCBkaXMgPSAoTFBEUkFXSVRFTVNUUlVDVClscGFyYW07CgkJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIGRpcy0+aXRlbURhdGE7CgoJCQlpZiAoZGlzLT5DdGxJRCA9PSBJRFdfVFJFRV9MRUZUKQoJCQkJZHJhd19pdGVtKCZjaGlsZC0+bGVmdCwgZGlzLCBlbnRyeSwgLTEpOwoJCQllbHNlIGlmIChkaXMtPkN0bElEID09IElEV19UUkVFX1JJR0hUKQoJCQkJZHJhd19pdGVtKCZjaGlsZC0+cmlnaHQsIGRpcywgZW50cnksIC0xKTsKCQkJZWxzZQoJCQkJZ290byBkcmF3X21lbnVfaXRlbTsKCgkJCXJldHVybiBUUlVFO30KCgkJY2FzZSBXTV9DUkVBVEU6CgkJCUluaXRDaGlsZFdpbmRvdyhjaGlsZCk7CgkJCWJyZWFrOwoKCQljYXNlIFdNX05DREVTVFJPWToKCQkJZnJlZV9jaGlsZF93aW5kb3coY2hpbGQpOwoJCQlTZXRXaW5kb3dMb25nUHRyKGh3bmQsIEdXTFBfVVNFUkRBVEEsIDApOwoJCQlicmVhazsKCgkJY2FzZSBXTV9QQUlOVDogewoJCQlQQUlOVFNUUlVDVCBwczsKCQkJSEJSVVNIIGxhc3RCcnVzaDsKCQkJUkVDVCBydDsKCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoJCQlCZWdpblBhaW50KGh3bmQsICZwcyk7CgkJCXJ0LmxlZnQgPSBjaGlsZC0+c3BsaXRfcG9zLVNQTElUX1dJRFRILzI7CgkJCXJ0LnJpZ2h0ID0gY2hpbGQtPnNwbGl0X3BvcytTUExJVF9XSURUSC8yKzE7CgkJCWxhc3RCcnVzaCA9IFNlbGVjdE9iamVjdChwcy5oZGMsIEdldFN0b2NrT2JqZWN0KENPTE9SX1NQTElUQkFSKSk7CgkJCVJlY3RhbmdsZShwcy5oZGMsIHJ0LmxlZnQsIHJ0LnRvcC0xLCBydC5yaWdodCwgcnQuYm90dG9tKzEpOwoJCQlTZWxlY3RPYmplY3QocHMuaGRjLCBsYXN0QnJ1c2gpOwojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJcnQudG9wID0gcnQuYm90dG9tIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpOwoJCQlGaWxsUmVjdChwcy5oZGMsICZydCwgR2V0U3RvY2tPYmplY3QoQkxBQ0tfQlJVU0gpKTsKI2VuZGlmCgkJCUVuZFBhaW50KGh3bmQsICZwcyk7CgkJCWJyZWFrO30KCgkJY2FzZSBXTV9TRVRDVVJTT1I6CgkJCWlmIChMT1dPUkQobHBhcmFtKSA9PSBIVENMSUVOVCkgewoJCQkJUE9JTlQgcHQ7CgkJCQlHZXRDdXJzb3JQb3MoJnB0KTsKCQkJCVNjcmVlblRvQ2xpZW50KGh3bmQsICZwdCk7CgoJCQkJaWYgKHB0Lng+PWNoaWxkLT5zcGxpdF9wb3MtU1BMSVRfV0lEVEgvMiAmJiBwdC54PGNoaWxkLT5zcGxpdF9wb3MrU1BMSVRfV0lEVEgvMisxKSB7CgkJCQkJU2V0Q3Vyc29yKExvYWRDdXJzb3IoMCwgSURDX1NJWkVXRSkpOwoJCQkJCXJldHVybiBUUlVFOwoJCQkJfQoJCQl9CgkJCWdvdG8gZGVmOwoKCQljYXNlIFdNX0xCVVRUT05ET1dOOiB7CgkJCVJFQ1QgcnQ7CgkJCWludCB4ID0gTE9XT1JEKGxwYXJhbSk7CgoJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJCQlpZiAoeD49Y2hpbGQtPnNwbGl0X3Bvcy1TUExJVF9XSURUSC8yICYmIHg8Y2hpbGQtPnNwbGl0X3BvcytTUExJVF9XSURUSC8yKzEpIHsKCQkJCWxhc3Rfc3BsaXQgPSBjaGlsZC0+c3BsaXRfcG9zOwojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CiNlbmRpZgoJCQkJU2V0Q2FwdHVyZShod25kKTsKCQkJfQoKCQkJYnJlYWs7fQoKCQljYXNlIFdNX0xCVVRUT05VUDoKCQkJaWYgKEdldENhcHR1cmUoKSA9PSBod25kKSB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJUkVDVCBydDsKCQkJCWludCB4ID0gTE9XT1JEKGxwYXJhbSk7CgkJCQlkcmF3X3NwbGl0YmFyKGh3bmQsIGxhc3Rfc3BsaXQpOwoJCQkJbGFzdF9zcGxpdCA9IC0xOwoJCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoJCQkJY2hpbGQtPnNwbGl0X3BvcyA9IHg7CgkJCQlyZXNpemVfdHJlZShjaGlsZCwgcnQucmlnaHQsIHJ0LmJvdHRvbSk7CiNlbmRpZgoJCQkJUmVsZWFzZUNhcHR1cmUoKTsKCQkJfQoJCQlicmVhazsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fQ0FQVFVSRUNIQU5HRUQ6CgkJCWlmIChHZXRDYXB0dXJlKCk9PWh3bmQgJiYgbGFzdF9zcGxpdD49MCkKCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CgkJCWJyZWFrOwojZW5kaWYKCgkJY2FzZSBXTV9LRVlET1dOOgoJCQlpZiAod3BhcmFtID09IFZLX0VTQ0FQRSkKCQkJCWlmIChHZXRDYXB0dXJlKCkgPT0gaHduZCkgewoJCQkJCVJFQ1QgcnQ7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CiNlbHNlCgkJCQkJY2hpbGQtPnNwbGl0X3BvcyA9IGxhc3Rfc3BsaXQ7CiNlbmRpZgoJCQkJCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCQkJCQlyZXNpemVfdHJlZShjaGlsZCwgcnQucmlnaHQsIHJ0LmJvdHRvbSk7CgkJCQkJbGFzdF9zcGxpdCA9IC0xOwoJCQkJCVJlbGVhc2VDYXB0dXJlKCk7CgkJCQkJU2V0Q3Vyc29yKExvYWRDdXJzb3IoMCwgSURDX0FSUk9XKSk7CgkJCQl9CgkJCWJyZWFrOwoKCQljYXNlIFdNX01PVVNFTU9WRToKCQkJaWYgKEdldENhcHR1cmUoKSA9PSBod25kKSB7CgkJCQlSRUNUIHJ0OwoJCQkJaW50IHggPSBMT1dPUkQobHBhcmFtKTsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJSERDIGhkYyA9IEdldERDKGh3bmQpOwoJCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoKCQkJCXJ0LmxlZnQgPSBsYXN0X3NwbGl0LVNQTElUX1dJRFRILzI7CgkJCQlydC5yaWdodCA9IGxhc3Rfc3BsaXQrU1BMSVRfV0lEVEgvMisxOwoJCQkJSW52ZXJ0UmVjdChoZGMsICZydCk7CgoJCQkJbGFzdF9zcGxpdCA9IHg7CgkJCQlydC5sZWZ0ID0geC1TUExJVF9XSURUSC8yOwoJCQkJcnQucmlnaHQgPSB4K1NQTElUX1dJRFRILzIrMTsKCQkJCUludmVydFJlY3QoaGRjLCAmcnQpOwoKCQkJCVJlbGVhc2VEQyhod25kLCBoZGMpOwojZWxzZQoJCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoKCQkJCWlmICh4Pj0wICYmIHg8cnQucmlnaHQpIHsKCQkJCQljaGlsZC0+c3BsaXRfcG9zID0geDsKCQkJCQlyZXNpemVfdHJlZShjaGlsZCwgcnQucmlnaHQsIHJ0LmJvdHRvbSk7CgkJCQkJcnQubGVmdCA9IHgtU1BMSVRfV0lEVEgvMjsKCQkJCQlydC5yaWdodCA9IHgrU1BMSVRfV0lEVEgvMisxOwoJCQkJCUludmFsaWRhdGVSZWN0KGh3bmQsICZydCwgRkFMU0UpOwoJCQkJCVVwZGF0ZVdpbmRvdyhjaGlsZC0+bGVmdC5od25kKTsKCQkJCQlVcGRhdGVXaW5kb3coaHduZCk7CgkJCQkJVXBkYXRlV2luZG93KGNoaWxkLT5yaWdodC5od25kKTsKCQkJCX0KI2VuZGlmCgkJCX0KCQkJYnJlYWs7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJY2FzZSBXTV9HRVRNSU5NQVhJTkZPOgoJCQlEZWZNRElDaGlsZFByb2MoaHduZCwgbm1zZywgd3BhcmFtLCBscGFyYW0pOwoKCQkJe0xQTUlOTUFYSU5GTyBscG1taSA9IChMUE1JTk1BWElORk8pbHBhcmFtOwoKCQkJbHBtbWktPnB0TWF4VHJhY2tTaXplLnggPDw9IDE7LyoyKkdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pIC8gU01fQ1hWSVJUVUFMU0NSRUVOICovCgkJCWxwbW1pLT5wdE1heFRyYWNrU2l6ZS55IDw8PSAxOy8qMipHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKSAvIFNNX0NZVklSVFVBTFNDUkVFTiAqLwoJCQlicmVhazt9CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCQljYXNlIFdNX1NFVEZPQ1VTOgoJCQlpZiAoU2V0Q3VycmVudERpcmVjdG9yeShjaGlsZC0+cGF0aCkpCgkJCQlzZXRfc3BhY2Vfc3RhdHVzKCk7CgkJCVNldEZvY3VzKGNoaWxkLT5mb2N1c19wYW5lPyBjaGlsZC0+cmlnaHQuaHduZDogY2hpbGQtPmxlZnQuaHduZCk7CgkJCWJyZWFrOwoKCQljYXNlIFdNX0RJU1BBVENIX0NPTU1BTkQ6IHsKCQkJUGFuZSogcGFuZSA9IEdldEZvY3VzKCk9PWNoaWxkLT5sZWZ0Lmh3bmQ/ICZjaGlsZC0+bGVmdDogJmNoaWxkLT5yaWdodDsKCgkJCXN3aXRjaChMT1dPUkQod3BhcmFtKSkgewoJCQkJY2FzZSBJRF9XSU5ET1dfTkVXOiB7CgkJCQkJQ2hpbGRXbmQqIG5ld19jaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhjaGlsZC0+cGF0aCwgTlVMTCwgaHduZCk7CgoJCQkJCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhuZXdfY2hpbGQpKQoJCQkJCQlmcmVlKG5ld19jaGlsZCk7CgoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX1JFRlJFU0g6CgkJCQkJcmVmcmVzaF9kcml2ZXMoKTsKCQkJCQlyZWZyZXNoX2NoaWxkKGNoaWxkKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX0FDVElWQVRFOgoJCQkJCWFjdGl2YXRlX2VudHJ5KGNoaWxkLCBwYW5lLCBod25kKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX0ZJTEVfTU9WRTogewoJCQkJCVRDSEFSIHNvdXJjZVtCVUZGRVJfTEVOXSwgdGFyZ2V0W0JVRkZFUl9MRU5dOwoKCQkJCQlpZiAocHJvbXB0X3RhcmdldChwYW5lLCBzb3VyY2UsIHRhcmdldCkpIHsKCQkJCQkJU0hGSUxFT1BTVFJVQ1Qgc2hmbyA9IHtod25kLCBGT19NT1ZFLCBzb3VyY2UsIHRhcmdldH07CgoJCQkJCQlzb3VyY2VbbHN0cmxlbihzb3VyY2UpKzFdID0gJ1wwJzsKCQkJCQkJdGFyZ2V0W2xzdHJsZW4odGFyZ2V0KSsxXSA9ICdcMCc7CgoJCQkJCQlpZiAoIVNIRmlsZU9wZXJhdGlvbigmc2hmbykpCgkJCQkJCQlyZWZyZXNoX2NoaWxkKGNoaWxkKTsKCQkJCQl9CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfRklMRV9DT1BZOiB7CgkJCQkJVENIQVIgc291cmNlW0JVRkZFUl9MRU5dLCB0YXJnZXRbQlVGRkVSX0xFTl07CgoJCQkJCWlmIChwcm9tcHRfdGFyZ2V0KHBhbmUsIHNvdXJjZSwgdGFyZ2V0KSkgewoJCQkJCQlTSEZJTEVPUFNUUlVDVCBzaGZvID0ge2h3bmQsIEZPX0NPUFksIHNvdXJjZSwgdGFyZ2V0fTsKCgkJCQkJCXNvdXJjZVtsc3RybGVuKHNvdXJjZSkrMV0gPSAnXDAnOwoJCQkJCQl0YXJnZXRbbHN0cmxlbih0YXJnZXQpKzFdID0gJ1wwJzsKCgkJCQkJCWlmICghU0hGaWxlT3BlcmF0aW9uKCZzaGZvKSkKCQkJCQkJCXJlZnJlc2hfY2hpbGQoY2hpbGQpOwoJCQkJCX0KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9GSUxFX0RFTEVURTogewoJCQkJCVRDSEFSIHBhdGhbQlVGRkVSX0xFTl07CgkJCQkJU0hGSUxFT1BTVFJVQ1Qgc2hmbyA9IHtod25kLCBGT19ERUxFVEUsIHBhdGh9OwoKCQkJCQlnZXRfcGF0aChwYW5lLT5jdXIsIHBhdGgpOwoKCQkJCQlwYXRoW2xzdHJsZW4ocGF0aCkrMV0gPSAnXDAnOwoKCQkJCQlpZiAoIVNIRmlsZU9wZXJhdGlvbigmc2hmbykpCgkJCQkJCXJlZnJlc2hfY2hpbGQoY2hpbGQpOwoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX1ZJRVdfU09SVF9OQU1FOgoJCQkJCXNldF9zb3J0X29yZGVyKGNoaWxkLCBTT1JUX05BTUUpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19TT1JUX1RZUEU6CgkJCQkJc2V0X3NvcnRfb3JkZXIoY2hpbGQsIFNPUlRfRVhUKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1ZJRVdfU09SVF9TSVpFOgoJCQkJCXNldF9zb3J0X29yZGVyKGNoaWxkLCBTT1JUX1NJWkUpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19TT1JUX0RBVEU6CgkJCQkJc2V0X3NvcnRfb3JkZXIoY2hpbGQsIFNPUlRfREFURSk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9WSUVXX0ZJTFRFUjogewoJCQkJCXN0cnVjdCBGaWx0ZXJEaWFsb2cgZGxnOwoKCQkJCQltZW1zZXQoJmRsZywgMCwgc2l6ZW9mKHN0cnVjdCBGaWx0ZXJEaWFsb2cpKTsKCQkJCQlsc3RyY3B5KGRsZy5wYXR0ZXJuLCBjaGlsZC0+ZmlsdGVyX3BhdHRlcm4pOwoJCQkJCWRsZy5mbGFncyA9IGNoaWxkLT5maWx0ZXJfZmxhZ3M7CgoJCQkJCWlmIChEaWFsb2dCb3hQYXJhbShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElERF9ESUFMT0dfVklFV19UWVBFKSwgaHduZCwgRmlsdGVyRGlhbG9nRGxnUHJvYywgKExQQVJBTSkmZGxnKSA9PSBJRE9LKSB7CgkJCQkJCWxzdHJjcHkoY2hpbGQtPmZpbHRlcl9wYXR0ZXJuLCBkbGcucGF0dGVybik7CgkJCQkJCWNoaWxkLT5maWx0ZXJfZmxhZ3MgPSBkbGcuZmxhZ3M7CgkJCQkJCXJlZnJlc2hfcmlnaHRfcGFuZShjaGlsZCk7CgkJCQkJfQoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX1ZJRVdfU1BMSVQ6IHsKCQkJCQlsYXN0X3NwbGl0ID0gY2hpbGQtPnNwbGl0X3BvczsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQkJZHJhd19zcGxpdGJhcihod25kLCBsYXN0X3NwbGl0KTsKI2VuZGlmCgkJCQkJU2V0Q2FwdHVyZShod25kKTsKCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9FRElUX1BST1BFUlRJRVM6CgkJCQkJc2hvd19wcm9wZXJ0aWVzX2RsZyhwYW5lLT5jdXIsIGNoaWxkLT5od25kKTsKCQkJCQlicmVhazsKCgkJCQlkZWZhdWx0OgoJCQkJCXJldHVybiBwYW5lX2NvbW1hbmQocGFuZSwgTE9XT1JEKHdwYXJhbSkpOwoJCQl9CgoJCQlyZXR1cm4gVFJVRTt9CgoJCWNhc2UgV01fQ09NTUFORDogewoJCQlQYW5lKiBwYW5lID0gR2V0Rm9jdXMoKT09Y2hpbGQtPmxlZnQuaHduZD8gJmNoaWxkLT5sZWZ0OiAmY2hpbGQtPnJpZ2h0OwoKCQkJc3dpdGNoKEhJV09SRCh3cGFyYW0pKSB7CgkJCQljYXNlIExCTl9TRUxDSEFOR0U6IHsKCQkJCQlpbnQgaWR4ID0gU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfR0VUQ1VSU0VMLCAwLCAwKTsKCQkJCQlFbnRyeSogZW50cnkgPSAoRW50cnkqKSBTZW5kTWVzc2FnZShwYW5lLT5od25kLCBMQl9HRVRJVEVNREFUQSwgaWR4LCAwKTsKCgkJCQkJaWYgKHBhbmUgPT0gJmNoaWxkLT5sZWZ0KQoJCQkJCQlzZXRfY3VyZGlyKGNoaWxkLCBlbnRyeSwgaWR4LCBod25kKTsKCQkJCQllbHNlCgkJCQkJCXBhbmUtPmN1ciA9IGVudHJ5OwoJCQkJCWJyZWFrO30KCgkJCQljYXNlIExCTl9EQkxDTEs6CgkJCQkJYWN0aXZhdGVfZW50cnkoY2hpbGQsIHBhbmUsIGh3bmQpOwoJCQkJCWJyZWFrOwoJCQl9CgkJCWJyZWFrO30KCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQljYXNlIFdNX05PVElGWTogewoJCQlOTUhEUiogcG5taCA9IChOTUhEUiopIGxwYXJhbTsKCQkJcmV0dXJuIHBhbmVfbm90aWZ5KHBubWgtPmlkRnJvbT09SURXX0hFQURFUl9MRUZUPyAmY2hpbGQtPmxlZnQ6ICZjaGlsZC0+cmlnaHQsIHBubWgpO30KI2VuZGlmCgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCQljYXNlIFdNX0NPTlRFWFRNRU5VOiB7CgkJCVBPSU5UIHB0LCBwdF9jbG50OwoJCQlQYW5lKiBwYW5lOwoJCQlpbnQgaWR4OwoKCQkJIC8qIGZpcnN0IHNlbGVjdCB0aGUgY3VycmVudCBpdGVtIGluIHRoZSBsaXN0Ym94ICovCgkJCUhXTkQgaHBhbmVsID0gKEhXTkQpIHdwYXJhbTsKCQkJcHRfY2xudC54ID0gcHQueCA9IChzaG9ydClMT1dPUkQobHBhcmFtKTsKCQkJcHRfY2xudC55ID0gcHQueSA9IChzaG9ydClISVdPUkQobHBhcmFtKTsKCQkJU2NyZWVuVG9DbGllbnQoaHBhbmVsLCAmcHRfY2xudCk7CgkJCVNlbmRNZXNzYWdlKGhwYW5lbCwgV01fTEJVVFRPTkRPV04sIDAsIE1BS0VMT05HKHB0X2NsbnQueCwgcHRfY2xudC55KSk7CgkJCVNlbmRNZXNzYWdlKGhwYW5lbCwgV01fTEJVVFRPTlVQLCAwLCBNQUtFTE9ORyhwdF9jbG50LngsIHB0X2NsbnQueSkpOwoKCQkJIC8qIG5vdyBjcmVhdGUgdGhlIHBvcHVwIG1lbnUgdXNpbmcgc2hlbGwgbmFtZXNwYWNlIGFuZCBJQ29udGV4dE1lbnUgKi8KCQkJcGFuZSA9IEdldEZvY3VzKCk9PWNoaWxkLT5sZWZ0Lmh3bmQ/ICZjaGlsZC0+bGVmdDogJmNoaWxkLT5yaWdodDsKCQkJaWR4ID0gU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfR0VUQ1VSU0VMLCAwLCAwKTsKCgkJCWlmIChpZHggIT0gLTEpIHsKCQkJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIFNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX0dFVElURU1EQVRBLCBpZHgsIDApOwoKCQkJCUxQSVRFTUlETElTVCBwaWRsX2FicyA9IGdldF90b19hYnNvbHV0ZV9waWRsKGVudHJ5LCBod25kKTsKCgkJCQlpZiAocGlkbF9hYnMpIHsKCQkJCQlJU2hlbGxGb2xkZXIqIHBhcmVudEZvbGRlcjsKCQkJCQlMUENJVEVNSURMSVNUIHBpZGxMYXN0OwoKCQkJCQkgLyogZ2V0IGFuZCB1c2UgdGhlIHBhcmVudCBmb2xkZXIgdG8gZGlzcGxheSBjb3JyZWN0IGNvbnRleHQgbWVudSBpbiBhbGwgY2FzZXMgKi8KCQkJCQlpZiAoU1VDQ0VFREVEKFNIQmluZFRvUGFyZW50KHBpZGxfYWJzLCAmSUlEX0lTaGVsbEZvbGRlciwgKExQVk9JRCopJnBhcmVudEZvbGRlciwgJnBpZGxMYXN0KSkpIHsKCQkJCQkJaWYgKFNoZWxsRm9sZGVyQ29udGV4dE1lbnUocGFyZW50Rm9sZGVyLCBod25kLCAxLCAmcGlkbExhc3QsIHB0LngsIHB0LnkpID09IFNfT0spCgkJCQkJCQlyZWZyZXNoX2NoaWxkKGNoaWxkKTsKCgkJCQkJCUlTaGVsbEZvbGRlcl9SZWxlYXNlKHBhcmVudEZvbGRlcik7CgkJCQkJfQoKCQkJCQlJTWFsbG9jX0ZyZWUoR2xvYmFscy5pTWFsbG9jLCBwaWRsX2Ficyk7CgkJCQl9CgkJCX0KCQkJYnJlYWs7fQojZW5kaWYKCgkJICBjYXNlIFdNX01FQVNVUkVJVEVNOgoJCSAgZHJhd19tZW51X2l0ZW06CgkJCWlmICghd3BhcmFtKQkvKiBJcyB0aGUgbWVzc2FnZSBtZW51LXJlbGF0ZWQ/ICovCgkJCQlpZiAoQ3R4TWVudV9IYW5kbGVNZW51TXNnKG5tc2csIHdwYXJhbSwgbHBhcmFtKSkKCQkJCQlyZXR1cm4gVFJVRTsKCgkJCWJyZWFrOwoKCQkgIGNhc2UgV01fSU5JVE1FTlVQT1BVUDoKCQkJaWYgKEN0eE1lbnVfSGFuZGxlTWVudU1zZyhubXNnLCB3cGFyYW0sIGxwYXJhbSkpCgkJCQlyZXR1cm4gMDsKCgkJCXVwZGF0ZV92aWV3X21lbnUoY2hpbGQpOwoJCQlicmVhazsKCgkJICBjYXNlIFdNX01FTlVDSEFSOgkvKiBvbmx5IHN1cHBvcnRlZCBieSBJQ29udGV4dE1lbnUzICovCgkJICAgaWYgKHNfcGN0eG1lbnUzKSB7CgkJCSAgIExSRVNVTFQgbFJlc3VsdCA9IDA7CgoJCQkgICBJQ29udGV4dE1lbnUzX0hhbmRsZU1lbnVNc2cyKHNfcGN0eG1lbnUzLCBubXNnLCB3cGFyYW0sIGxwYXJhbSwgJmxSZXN1bHQpOwoKCQkJICAgcmV0dXJuIGxSZXN1bHQ7CgkJICAgfQoKCQkgICBicmVhazsKCgkJY2FzZSBXTV9TSVpFOgoJCQlpZiAod3BhcmFtICE9IFNJWkVfTUlOSU1JWkVEKQoJCQkJcmVzaXplX3RyZWUoY2hpbGQsIExPV09SRChscGFyYW0pLCBISVdPUkQobHBhcmFtKSk7CgkJCS8qIGZhbGwgdGhyb3VnaCAqLwoKCQlkZWZhdWx0OiBkZWY6CgkJCXJldHVybiBEZWZNRElDaGlsZFByb2MoaHduZCwgbm1zZywgd3BhcmFtLCBscGFyYW0pOwoJfQoKCXJldHVybiAwOwp9CgoKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgVHJlZVduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCUNoaWxkV25kKiBjaGlsZCA9IChDaGlsZFduZCopIEdldFdpbmRvd0xvbmdQdHIoR2V0UGFyZW50KGh3bmQpLCBHV0xQX1VTRVJEQVRBKTsKCVBhbmUqIHBhbmUgPSAoUGFuZSopIEdldFdpbmRvd0xvbmdQdHIoaHduZCwgR1dMUF9VU0VSREFUQSk7CglBU1NFUlQoY2hpbGQpOwoKCXN3aXRjaChubXNnKSB7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQljYXNlIFdNX0hTQ1JPTEw6CgkJCXNldF9oZWFkZXIocGFuZSk7CgkJCWJyZWFrOwojZW5kaWYKCgkJY2FzZSBXTV9TRVRGT0NVUzoKCQkJY2hpbGQtPmZvY3VzX3BhbmUgPSBwYW5lPT0mY2hpbGQtPnJpZ2h0PyAxOiAwOwoJCQlTZW5kTWVzc2FnZShod25kLCBMQl9TRVRTRUwsIFRSVUUsIDEpOwoJCQkvKlRPRE86IGNoZWNrIG1lbnUgaXRlbXMgKi8KCQkJYnJlYWs7CgoJCWNhc2UgV01fS0VZRE9XTjoKCQkJaWYgKHdwYXJhbSA9PSBWS19UQUIpIHsKCQkJCS8qVE9ETzogU2V0Rm9jdXMoR2xvYmFscy5oZHJpdmViYXIpICovCgkJCQlTZXRGb2N1cyhjaGlsZC0+Zm9jdXNfcGFuZT8gY2hpbGQtPmxlZnQuaHduZDogY2hpbGQtPnJpZ2h0Lmh3bmQpOwoJCQl9Cgl9CgoJcmV0dXJuIENhbGxXaW5kb3dQcm9jKGdfb3JnVHJlZVduZFByb2MsIGh3bmQsIG5tc2csIHdwYXJhbSwgbHBhcmFtKTsKfQoKCnN0YXRpYyB2b2lkIEluaXRJbnN0YW5jZShISU5TVEFOQ0UgaGluc3RhbmNlKQp7CglzdGF0aWMgY29uc3QgVENIQVIgc0ZvbnRbXSA9IHsnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnICcsJ1MnLCdhJywnbicsJ3MnLCcgJywnUycsJ2UnLCdyJywnaScsJ2YnLCdcMCd9OwoKCVdORENMQVNTRVggd2NGcmFtZTsKCVdORENMQVNTIHdjQ2hpbGQ7CglBVE9NIGhDaGlsZENsYXNzOwoJaW50IGNvbDsKCglJTklUQ09NTU9OQ09OVFJPTFNFWCBpY2MgPSB7CgkJc2l6ZW9mKElOSVRDT01NT05DT05UUk9MU0VYKSwKCQlJQ0NfQkFSX0NMQVNTRVMKCX07CgoJSERDIGhkYyA9IEdldERDKDApOwoKCXNldGxvY2FsZShMQ19DT0xMQVRFLCAiIik7CS8qIHNldCBjb2xsYXRpbmcgcnVsZXMgdG8gbG9jYWwgc2V0dGluZ3MgZm9yIGNvbXBhcmVOYW1lICovCgoJSW5pdENvbW1vbkNvbnRyb2xzRXgoJmljYyk7CgoKCS8qIHJlZ2lzdGVyIGZyYW1lIHdpbmRvdyBjbGFzcyAqLwoKCXdjRnJhbWUuY2JTaXplICAgICAgICA9IHNpemVvZihXTkRDTEFTU0VYKTsKCXdjRnJhbWUuc3R5bGUgICAgICAgICA9IDA7Cgl3Y0ZyYW1lLmxwZm5XbmRQcm9jICAgPSBGcmFtZVduZFByb2M7Cgl3Y0ZyYW1lLmNiQ2xzRXh0cmEgICAgPSAwOwoJd2NGcmFtZS5jYlduZEV4dHJhICAgID0gMDsKCXdjRnJhbWUuaEluc3RhbmNlICAgICA9IGhpbnN0YW5jZTsKCXdjRnJhbWUuaEljb24gICAgICAgICA9IExvYWRJY29uKGhpbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElESV9XSU5FRklMRSkpOwoJd2NGcmFtZS5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvcigwLCBJRENfQVJST1cpOwoJd2NGcmFtZS5oYnJCYWNrZ3JvdW5kID0gMDsKCXdjRnJhbWUubHBzek1lbnVOYW1lICA9IDA7Cgl3Y0ZyYW1lLmxwc3pDbGFzc05hbWUgPSBzV0lORUZJTEVGUkFNRTsKCXdjRnJhbWUuaEljb25TbSAgICAgICA9IChISUNPTilMb2FkSW1hZ2UoaGluc3RhbmNlLAoJCQkJCQkJCQkJCSBNQUtFSU5UUkVTT1VSQ0UoSURJX1dJTkVGSUxFKSwKCQkJCQkJCQkJCQkgSU1BR0VfSUNPTiwKCQkJCQkJCQkJCQkgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNNSUNPTiksCgkJCQkJCQkJCQkJIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUlDT04pLAoJCQkJCQkJCQkJCSBMUl9TSEFSRUQpOwoKCUdsb2JhbHMuaGZyYW1lQ2xhc3MgPSBSZWdpc3RlckNsYXNzRXgoJndjRnJhbWUpOwoKCgkvKiByZWdpc3RlciB0cmVlIHdpbmRvd3MgY2xhc3MgKi8KCgl3Y0NoaWxkLnN0eWxlICAgICAgICAgPSBDU19DTEFTU0RDfENTX0RCTENMS1N8Q1NfVlJFRFJBVzsKCXdjQ2hpbGQubHBmblduZFByb2MgICA9IENoaWxkV25kUHJvYzsKCXdjQ2hpbGQuY2JDbHNFeHRyYSAgICA9IDA7Cgl3Y0NoaWxkLmNiV25kRXh0cmEgICAgPSAwOwoJd2NDaGlsZC5oSW5zdGFuY2UgICAgID0gaGluc3RhbmNlOwoJd2NDaGlsZC5oSWNvbiAgICAgICAgID0gMDsKCXdjQ2hpbGQuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3IoMCwgSURDX0FSUk9XKTsKCXdjQ2hpbGQuaGJyQmFja2dyb3VuZCA9IDA7Cgl3Y0NoaWxkLmxwc3pNZW51TmFtZSAgPSAwOwoJd2NDaGlsZC5scHN6Q2xhc3NOYW1lID0gc1dJTkVGSUxFVFJFRTsKCgloQ2hpbGRDbGFzcyA9IFJlZ2lzdGVyQ2xhc3MoJndjQ2hpbGQpOwoKCglHbG9iYWxzLmhhY2NlbCA9IExvYWRBY2NlbGVyYXRvcnMoaGluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSURBX1dJTkVGSUxFKSk7CgoJR2xvYmFscy5oZm9udCA9IENyZWF0ZUZvbnQoLU11bERpdig4LEdldERldmljZUNhcHMoaGRjLExPR1BJWEVMU1kpLDcyKSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgc0ZvbnQpOwoKCVJlbGVhc2VEQygwLCBoZGMpOwoKCUdsb2JhbHMuaEluc3RhbmNlID0gaGluc3RhbmNlOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglDb0luaXRpYWxpemUoTlVMTCk7CglDb0dldE1hbGxvYyhNRU1DVFhfVEFTSywgJkdsb2JhbHMuaU1hbGxvYyk7CglTSEdldERlc2t0b3BGb2xkZXIoJkdsb2JhbHMuaURlc2t0b3ApOwojaWZkZWYgX19XSU5FX18KCUdsb2JhbHMuY2ZTdHJGTmFtZSA9IFJlZ2lzdGVyQ2xpcGJvYXJkRm9ybWF0QShDRlNUUl9GSUxFTkFNRSk7CiNlbHNlCglHbG9iYWxzLmNmU3RyRk5hbWUgPSBSZWdpc3RlckNsaXBib2FyZEZvcm1hdChDRlNUUl9GSUxFTkFNRSk7CiNlbmRpZgojZW5kaWYKCgkvKiBsb2FkIGNvbHVtbiBzdHJpbmdzICovCgljb2wgPSAxOwoKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9OQU1FKTsKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9TSVpFKTsKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9DREFURSk7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9BREFURSk7Cglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfTURBVEUpOwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX0lEWCk7Cglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfTElOS1MpOwojZW5kaWYKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9BVFRSKTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX1NFQyk7CiNlbmRpZgp9CgoKc3RhdGljIHZvaWQgc2hvd19mcmFtZShIV05EIGh3bmRQYXJlbnQsIGludCBjbWRzaG93LCBMUENUU1RSIHBhdGgpCnsKCXN0YXRpYyBjb25zdCBUQ0hBUiBzTURJQ0xJRU5UW10gPSB7J00nLCdEJywnSScsJ0MnLCdMJywnSScsJ0UnLCdOJywnVCcsJ1wwJ307CgoJVENIQVIgYnVmZmVyW01BWF9QQVRIXSwgYjFbQlVGRkVSX0xFTl07CglDaGlsZFduZCogY2hpbGQ7CglITUVOVSBoTWVudUZyYW1lLCBoTWVudVdpbmRvdzsKCXdpbmRvd09wdGlvbnMgb3B0czsKCglDTElFTlRDUkVBVEVTVFJVQ1QgY2NzOwoKCWlmIChHbG9iYWxzLmhNYWluV25kKQoJCXJldHVybjsKCglvcHRzID0gbG9hZF9yZWdpc3RyeV9zZXR0aW5ncygpOwoJaE1lbnVGcmFtZSA9IExvYWRNZW51KEdsb2JhbHMuaEluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSURNX1dJTkVGSUxFKSk7CgloTWVudVdpbmRvdyA9IEdldFN1Yk1lbnUoaE1lbnVGcmFtZSwgR2V0TWVudUl0ZW1Db3VudChoTWVudUZyYW1lKS0yKTsKCglHbG9iYWxzLmhNZW51RnJhbWUgPSBoTWVudUZyYW1lOwoJR2xvYmFscy5oTWVudVZpZXcgPSBHZXRTdWJNZW51KGhNZW51RnJhbWUsIDMpOwoJR2xvYmFscy5oTWVudU9wdGlvbnMgPSBHZXRTdWJNZW51KGhNZW51RnJhbWUsIDQpOwoKCWNjcy5oV2luZG93TWVudSAgPSBoTWVudVdpbmRvdzsKCWNjcy5pZEZpcnN0Q2hpbGQgPSBJRFdfRklSU1RfQ0hJTEQ7CgoKCS8qIGNyZWF0ZSBtYWluIHdpbmRvdyAqLwoJR2xvYmFscy5oTWFpblduZCA9IENyZWF0ZVdpbmRvd0V4KDAsIChMUENUU1RSKShpbnQpR2xvYmFscy5oZnJhbWVDbGFzcywgUlMoYjEsSURTX1dJTkVfRklMRSksIFdTX09WRVJMQVBQRURXSU5ET1csCgkJCQkJb3B0cy5zdGFydF94LCBvcHRzLnN0YXJ0X3ksIG9wdHMud2lkdGgsIG9wdHMuaGVpZ2h0LAoJCQkJCWh3bmRQYXJlbnQsIEdsb2JhbHMuaE1lbnVGcmFtZSwgR2xvYmFscy5oSW5zdGFuY2UsIDAvKmxwUGFyYW0qLyk7CgoKCUdsb2JhbHMuaG1kaWNsaWVudCA9IENyZWF0ZVdpbmRvd0V4KDAsIHNNRElDTElFTlQsIE5VTEwsCgkJCQkJV1NfQ0hJTER8V1NfQ0xJUENISUxEUkVOfFdTX1ZTQ1JPTEx8V1NfSFNDUk9MTHxXU19WSVNJQkxFfFdTX0JPUkRFUiwKCQkJCQkwLCAwLCAwLCAwLAoJCQkJCUdsb2JhbHMuaE1haW5XbmQsIDAsIEdsb2JhbHMuaEluc3RhbmNlLCAmY2NzKTsKICAKCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudU9wdGlvbnMsIElEX1ZJRVdfRFJJVkVfQkFSLCBNRl9CWUNPTU1BTkR8TUZfQ0hFQ0tFRCk7CglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBJRF9WSUVXX1NBVkVTRVRUSU5HUywgTUZfQllDT01NQU5EKTsKCgljcmVhdGVfZHJpdmVfYmFyKCk7CgoJewoJCVRCQlVUVE9OIHRvb2xiYXJCdG5zW10gPSB7CgkJCXswLCAwLCAwLCBCVE5TX1NFUCwgezAsIDB9LCAwLCAwfSwKCQkJezAsIElEX1dJTkRPV19ORVcsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH0sCgkJCXsxLCBJRF9XSU5ET1dfQ0FTQ0FERSwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKCQkJezIsIElEX1dJTkRPV19USUxFX0hPUlosIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH0sCgkJCXszLCBJRF9XSU5ET1dfVElMRV9WRVJULCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9LAovKlRPRE8KCQkJezQsIElEXy4uLiAsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH0sCgkJCXs1LCBJRF8uLi4gLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9LAoqLwkJfTsKCgkJR2xvYmFscy5odG9vbGJhciA9IENyZWF0ZVRvb2xiYXJFeChHbG9iYWxzLmhNYWluV25kLCBXU19DSElMRHxXU19WSVNJQkxFLAoJCQlJRFdfVE9PTEJBUiwgMiwgR2xvYmFscy5oSW5zdGFuY2UsIElEQl9UT09MQkFSLCB0b29sYmFyQnRucywKCQkJc2l6ZW9mKHRvb2xiYXJCdG5zKS9zaXplb2YoVEJCVVRUT04pLCAxNiwgMTUsIDE2LCAxNSwgc2l6ZW9mKFRCQlVUVE9OKSk7CgkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgSURfVklFV19UT09MX0JBUiwgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoJfQoKCUdsb2JhbHMuaHN0YXR1c2JhciA9IENyZWF0ZVN0YXR1c1dpbmRvdyhXU19DSElMRHxXU19WSVNJQkxFLCAwLCBHbG9iYWxzLmhNYWluV25kLCBJRFdfU1RBVFVTQkFSKTsKCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudU9wdGlvbnMsIElEX1ZJRVdfU1RBVFVTQkFSLCBNRl9CWUNPTU1BTkR8TUZfQ0hFQ0tFRCk7CgovKiBDcmVhdGVTdGF0dXNXaW5kb3cgZG9lcyBub3QgYWNjZXB0IFdTX0JPUkRFUgoJR2xvYmFscy5oc3RhdHVzYmFyID0gQ3JlYXRlV2luZG93RXgoV1NfRVhfTk9QQVJFTlROT1RJRlksIFNUQVRVU0NMQVNTTkFNRSwgMCwKCQkJCQlXU19DSElMRHxXU19WSVNJQkxFfFdTX0NMSVBTSUJMSU5HU3xXU19CT1JERVJ8Q0NTX05PRElWSURFUiwgMCwwLDAsMCwKCQkJCQlHbG9iYWxzLmhNYWluV25kLCAoSE1FTlUpSURXX1NUQVRVU0JBUiwgaGluc3RhbmNlLCAwKTsqLwoKCS8qVE9ETzogcmVhZCBwYXRocyBmcm9tIHJlZ2lzdHJ5ICovCgoJaWYgKCFwYXRoIHx8ICEqcGF0aCkgewoJCUdldEN1cnJlbnREaXJlY3RvcnkoTUFYX1BBVEgsIGJ1ZmZlcik7CgkJcGF0aCA9IGJ1ZmZlcjsKCX0KCglTaG93V2luZG93KEdsb2JhbHMuaE1haW5XbmQsIGNtZHNob3cpOwoKI2lmIGRlZmluZWQoX1NIRUxMX0ZPTERFUlMpICYmICFkZWZpbmVkKF9fV0lORV9fKQoJIC8qIFNoZWxsIE5hbWVzcGFjZSBhcyBkZWZhdWx0OiAqLwoJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgZ2V0X3BhdGhfcGlkbChwYXRoLEdsb2JhbHMuaE1haW5XbmQpLCBHbG9iYWxzLmhNYWluV25kKTsKI2Vsc2UKCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIE5VTEwsIEdsb2JhbHMuaE1haW5XbmQpOwojZW5kaWYKCgljaGlsZC0+cG9zLnNob3dDbWQgPSBTV19TSE9XTUFYSU1JWkVEOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmxlZnQgPSAwOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLnRvcCA9IDA7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ucmlnaHQgPSAzMjA7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24uYm90dG9tID0gMjgwOwoKCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhjaGlsZCkpCgkJZnJlZShjaGlsZCk7CgoJU2V0V2luZG93UGxhY2VtZW50KGNoaWxkLT5od25kLCAmY2hpbGQtPnBvcyk7CgoJR2xvYmFscy5oaW1sID0gSW1hZ2VMaXN0X0xvYWRCaXRtYXAoR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJREJfSU1BR0VTKSwgMTYsIDAsIFJHQigwLDI1NSwwKSk7CgoJR2xvYmFscy5wcmVzY2FuX25vZGUgPSBGQUxTRTsKCglVcGRhdGVXaW5kb3coR2xvYmFscy5oTWFpblduZCk7CgoJaWYgKHBhdGggJiYgcGF0aFswXSkKCXsKCQlpbnQgaW5kZXgsY291bnQ7CgkJVENIQVIgZHJ2W19NQVhfRFJJVkUrMV0sIGRpcltfTUFYX0RJUl0sIG5hbWVbX01BWF9GTkFNRV0sIGV4dFtfTUFYX0VYVF07CgkJVENIQVIgZnVsbG5hbWVbX01BWF9GTkFNRStfTUFYX0VYVCsxXTsKCgkJbWVtc2V0KG5hbWUsMCxzaXplb2YobmFtZSkpOwoJCW1lbXNldChuYW1lLDAsc2l6ZW9mKGV4dCkpOwoJCV90c3BsaXRwYXRoKHBhdGgsIGRydiwgZGlyLCBuYW1lLCBleHQpOwoJCWlmIChuYW1lWzBdKQoJCXsKCQkJY291bnQgPSBTZW5kTWVzc2FnZShjaGlsZC0+cmlnaHQuaHduZCwgTEJfR0VUQ09VTlQsIDAsIDApOwoJCQlsc3RyY3B5KGZ1bGxuYW1lLG5hbWUpOwoJCQlsc3RyY2F0KGZ1bGxuYW1lLGV4dCk7CgoJCQlmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBjb3VudDsgaW5kZXggKyspCgkJCXsKCQkJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIFNlbmRNZXNzYWdlKGNoaWxkLT5yaWdodC5od25kLCBMQl9HRVRJVEVNREFUQSwgaW5kZXgsIDApOwoJCQkJaWYgKGxzdHJjbXAoZW50cnktPmRhdGEuY0ZpbGVOYW1lLGZ1bGxuYW1lKT09MCB8fAoJCQkJCQlsc3RyY21wKGVudHJ5LT5kYXRhLmNBbHRlcm5hdGVGaWxlTmFtZSxmdWxsbmFtZSk9PTApCgkJCQl7CgkJCQkJU2VuZE1lc3NhZ2UoY2hpbGQtPnJpZ2h0Lmh3bmQsIExCX1NFVENVUlNFTCwgaW5kZXgsIDApOwoJCQkJCVNldEZvY3VzKGNoaWxkLT5yaWdodC5od25kKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCX0KfQoKc3RhdGljIHZvaWQgRXhpdEluc3RhbmNlKHZvaWQpCnsKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglJU2hlbGxGb2xkZXJfUmVsZWFzZShHbG9iYWxzLmlEZXNrdG9wKTsKCUlNYWxsb2NfUmVsZWFzZShHbG9iYWxzLmlNYWxsb2MpOwoJQ29VbmluaXRpYWxpemUoKTsKI2VuZGlmCgoJRGVsZXRlT2JqZWN0KEdsb2JhbHMuaGZvbnQpOwoJSW1hZ2VMaXN0X0Rlc3Ryb3koR2xvYmFscy5oaW1sKTsKfQoKI2lmZGVmIF9OT19FWFRFTlNJT05TCgovKiBzZWFyY2ggZm9yIGFscmVhZHkgcnVubmluZyB3aW5bZV1maWxlcyAqLwoKc3RhdGljIGludCBnX2ZvdW5kUHJldkluc3RhbmNlID0gMDsKCnN0YXRpYyBCT09MIENBTExCQUNLIEVudW1XbmRQcm9jKEhXTkQgaHduZCwgTFBBUkFNIGxwYXJhbSkKewoJVENIQVIgY2xzWzEyOF07CgoJR2V0Q2xhc3NOYW1lKGh3bmQsIGNscywgMTI4KTsKCglpZiAoIWxzdHJjbXAoY2xzLCAoTFBDVFNUUilscGFyYW0pKSB7CgkJZ19mb3VuZFByZXZJbnN0YW5jZSsrOwoJCXJldHVybiBGQUxTRTsKCX0KCglyZXR1cm4gVFJVRTsKfQoKLyogc2VhcmNoIGZvciB3aW5kb3cgb2YgZ2l2ZW4gY2xhc3MgbmFtZSB0byBhbGxvdyBvbmx5IG9uZSBydW5uaW5nIGluc3RhbmNlICovCnN0YXRpYyBpbnQgZmluZF93aW5kb3dfY2xhc3MoTFBDVFNUUiBjbGFzc25hbWUpCnsKCUVudW1XaW5kb3dzKEVudW1XbmRQcm9jLCAoTFBBUkFNKWNsYXNzbmFtZSk7CgoJaWYgKGdfZm91bmRQcmV2SW5zdGFuY2UpCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCiNlbmRpZgoKc3RhdGljIGludCB3aW5lZmlsZV9tYWluKEhJTlNUQU5DRSBoaW5zdGFuY2UsIGludCBjbWRzaG93LCBMUENUU1RSIHBhdGgpCnsKCU1TRyBtc2c7CiAgCglJbml0SW5zdGFuY2UoaGluc3RhbmNlKTsKCglzaG93X2ZyYW1lKDAsIGNtZHNob3csIHBhdGgpOwoKCXdoaWxlKEdldE1lc3NhZ2UoJm1zZywgMCwgMCwgMCkpIHsKCQlpZiAoR2xvYmFscy5obWRpY2xpZW50ICYmIFRyYW5zbGF0ZU1ESVN5c0FjY2VsKEdsb2JhbHMuaG1kaWNsaWVudCwgJm1zZykpCgkJCWNvbnRpbnVlOwoKCQlpZiAoR2xvYmFscy5oTWFpblduZCAmJiBUcmFuc2xhdGVBY2NlbGVyYXRvcihHbG9iYWxzLmhNYWluV25kLCBHbG9iYWxzLmhhY2NlbCwgJm1zZykpCgkJCWNvbnRpbnVlOwoKCQlUcmFuc2xhdGVNZXNzYWdlKCZtc2cpOwoJCURpc3BhdGNoTWVzc2FnZSgmbXNnKTsKCX0KCglFeGl0SW5zdGFuY2UoKTsKCglyZXR1cm4gbXNnLndQYXJhbTsKfQoKCiNpZiBkZWZpbmVkKFVOSUNPREUpICYmIGRlZmluZWQoX01TQ19WRVIpCmludCBBUElFTlRSWSB3V2luTWFpbihISU5TVEFOQ0UgaGluc3RhbmNlLCBISU5TVEFOQ0UgcHJldmluc3RhbmNlLCBMUFdTVFIgY21kbGluZSwgaW50IGNtZHNob3cpCiNlbHNlCmludCBBUElFTlRSWSBXaW5NYWluKEhJTlNUQU5DRSBoaW5zdGFuY2UsIEhJTlNUQU5DRSBwcmV2aW5zdGFuY2UsIExQU1RSIGNtZGxpbmUsIGludCBjbWRzaG93KQojZW5kaWYKewojaWZkZWYgX05PX0VYVEVOU0lPTlMKCWlmIChmaW5kX3dpbmRvd19jbGFzcyhzV0lORUZJTEVGUkFNRSkpCgkJcmV0dXJuIDE7CiNlbmRpZgoKI2lmIGRlZmluZWQoVU5JQ09ERSkgJiYgIWRlZmluZWQoX01TQ19WRVIpCgl7IC8qIGNvbnZlcnQgQU5TSSBjbWRsaW5lIGludG8gV0NTIHBhdGggc3RyaW5nICovCglUQ0hBUiBidWZmZXJbTUFYX1BBVEhdOwoJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIGNtZGxpbmUsIC0xLCBidWZmZXIsIE1BWF9QQVRIKTsKCXdpbmVmaWxlX21haW4oaGluc3RhbmNlLCBjbWRzaG93LCBidWZmZXIpOwoJfQojZWxzZQoJd2luZWZpbGVfbWFpbihoaW5zdGFuY2UsIGNtZHNob3csIGNtZGxpbmUpOwojZW5kaWYKCglyZXR1cm4gMDsKfQo=