LyoKICogV2luZWZpbGUKICoKICogQ29weXJpZ2h0IDIwMDAsIDIwMDMsIDIwMDQsIDIwMDUgTWFydGluIEZ1Y2hzCiAqIENvcHlyaWdodCAyMDA2IEphc29uIEdyZWVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpZmRlZiBfX1dJTkVfXwojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKCi8qIGZvciB1bml4IGZpbGVzeXN0ZW0gZnVuY3Rpb24gY2FsbHMgKi8KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPGRpcmVudC5oPgojZW5kaWYKCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgIndpbmVmaWxlLmgiCiNpbmNsdWRlICJyZXNvdXJjZS5oIgoKI2lmZGVmIF9OT19FWFRFTlNJT05TCiN1bmRlZiBfTEVGVF9GSUxFUwojZW5kaWYKCiNpZm5kZWYgX01BWF9QQVRICiNkZWZpbmUgX01BWF9EUklWRSAgICAgICAgICAzCiNkZWZpbmUgX01BWF9GTkFNRSAgICAgICAgICAyNTYKI2RlZmluZSBfTUFYX0RJUiAgICAgICAgICAgIF9NQVhfRk5BTUUKI2RlZmluZSBfTUFYX0VYVCAgICAgICAgICAgIF9NQVhfRk5BTUUKI2RlZmluZSBfTUFYX1BBVEggICAgICAgICAgIDI2MAojZW5kaWYKCiNpZmRlZiBOT05BTUVMRVNTVU5JT04KI2RlZmluZQlVTklPTl9NRU1CRVIoeCkgRFVNTVlVTklPTk5BTUUueAojZWxzZQojZGVmaW5lCVVOSU9OX01FTUJFUih4KSB4CiNlbmRpZgoKCiNpZmRlZiBfU0hFTExfRk9MREVSUwojZGVmaW5lCURFRkFVTFRfU1BMSVRfUE9TCTMwMAojZWxzZQojZGVmaW5lCURFRkFVTFRfU1BMSVRfUE9TCTIwMAojZW5kaWYKCnN0YXRpYyBjb25zdCBXQ0hBUiByZWdpc3RyeV9rZXlbXSA9IHsgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnRicsJ2knLCdsJywnZScsJ1wwJ307CnN0YXRpYyBjb25zdCBXQ0hBUiByZWdfc3RhcnRfeFtdID0geyAncycsJ3QnLCdhJywncicsJ3QnLCdYJywnXDAnfTsKc3RhdGljIGNvbnN0IFdDSEFSIHJlZ19zdGFydF95W10gPSB7ICdzJywndCcsJ2EnLCdyJywndCcsJ1knLCdcMCd9OwpzdGF0aWMgY29uc3QgV0NIQVIgcmVnX3dpZHRoW10gPSB7ICd3JywnaScsJ2QnLCd0JywnaCcsJ1wwJ307CnN0YXRpYyBjb25zdCBXQ0hBUiByZWdfaGVpZ2h0W10gPSB7ICdoJywnZScsJ2knLCdnJywnaCcsJ3QnLCdcMCd9OwpzdGF0aWMgY29uc3QgV0NIQVIgcmVnX2xvZ2ZvbnRbXSA9IHsgJ2wnLCdvJywnZycsJ2YnLCdvJywnbicsJ3QnLCdcMCd9OwoKZW51bSBFTlRSWV9UWVBFIHsKCUVUX1dJTkRPV1MsCglFVF9VTklYLAojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCUVUX1NIRUxMCiNlbmRpZgp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0VudHJ5IHsKCXN0cnVjdCBfRW50cnkqCW5leHQ7CglzdHJ1Y3QgX0VudHJ5Kglkb3duOwoJc3RydWN0IF9FbnRyeSoJdXA7CgoJQk9PTAkJCWV4cGFuZGVkOwoJQk9PTAkJCXNjYW5uZWQ7CglpbnQJCQkJbGV2ZWw7CgoJV0lOMzJfRklORF9EQVRBCWRhdGE7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBiaGZpOwoJQk9PTAkJCWJoZmlfdmFsaWQ7CgllbnVtIEVOVFJZX1RZUEUJZXR5cGU7CiNlbmRpZgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCUxQSVRFTUlETElTVAlwaWRsOwoJSVNoZWxsRm9sZGVyKglmb2xkZXI7CglISUNPTgkJCWhpY29uOwojZW5kaWYKfSBFbnRyeTsKCnR5cGVkZWYgc3RydWN0IHsKCUVudHJ5CWVudHJ5OwoJVENIQVIJcGF0aFtNQVhfUEFUSF07CglUQ0hBUgl2b2xuYW1lW19NQVhfRk5BTUVdOwoJVENIQVIJZnNbX01BWF9ESVJdOwoJRFdPUkQJZHJpdmVfdHlwZTsKCURXT1JECWZzX2ZsYWdzOwp9IFJvb3Q7CgplbnVtIENPTFVNTl9GTEFHUyB7CglDT0xfU0laRQkJPSAweDAxLAoJQ09MX0RBVEUJCT0gMHgwMiwKCUNPTF9USU1FCQk9IDB4MDQsCglDT0xfQVRUUklCVVRFUwk9IDB4MDgsCglDT0xfRE9TTkFNRVMJPSAweDEwLAojaWZkZWYgX05PX0VYVEVOU0lPTlMKCUNPTF9BTEwgPSBDT0xfU0laRXxDT0xfREFURXxDT0xfVElNRXxDT0xfQVRUUklCVVRFU3xDT0xfRE9TTkFNRVMKI2Vsc2UKCUNPTF9JTkRFWAkJPSAweDIwLAoJQ09MX0xJTktTCQk9IDB4NDAsCglDT0xfQUxMID0gQ09MX1NJWkV8Q09MX0RBVEV8Q09MX1RJTUV8Q09MX0FUVFJJQlVURVN8Q09MX0RPU05BTUVTfENPTF9JTkRFWHxDT0xfTElOS1MKI2VuZGlmCn07Cgp0eXBlZGVmIGVudW0gewoJU09SVF9OQU1FLAoJU09SVF9FWFQsCglTT1JUX1NJWkUsCglTT1JUX0RBVEUKfSBTT1JUX09SREVSOwoKdHlwZWRlZiBzdHJ1Y3QgewoJSFdORAlod25kOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglIV05ECWh3bmRIZWFkZXI7CiNlbmRpZgoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwojZGVmaW5lCUNPTFVNTlMJMTAKI2Vsc2UKI2RlZmluZQlDT0xVTU5TCTUKI2VuZGlmCglpbnQJCXdpZHRoc1tDT0xVTU5TXTsKCWludAkJcG9zaXRpb25zW0NPTFVNTlMrMV07CgoJQk9PTAl0cmVlUGFuZTsKCWludAkJdmlzaWJsZV9jb2xzOwoJRW50cnkqCXJvb3Q7CglFbnRyeSoJY3VyOwp9IFBhbmU7Cgp0eXBlZGVmIHN0cnVjdCB7CglIV05ECWh3bmQ7CglQYW5lCWxlZnQ7CglQYW5lCXJpZ2h0OwoJaW50CQlmb2N1c19wYW5lOwkJLyogMDogbGVmdCAgMTogcmlnaHQgKi8KCVdJTkRPV1BMQUNFTUVOVCBwb3M7CglpbnQJCXNwbGl0X3BvczsKCUJPT0wJaGVhZGVyX3dkdGhzX29rOwoKCVRDSEFSCXBhdGhbTUFYX1BBVEhdOwoJVENIQVIJZmlsdGVyX3BhdHRlcm5bTUFYX1BBVEhdOwoJaW50CQlmaWx0ZXJfZmxhZ3M7CglSb290CXJvb3Q7CgoJU09SVF9PUkRFUiBzb3J0T3JkZXI7Cn0gQ2hpbGRXbmQ7CgoKCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5KEVudHJ5KiBkaXIsIExQQ1RTVFIgcGF0aCwgU09SVF9PUkRFUiBzb3J0T3JkZXIsIEhXTkQgaHduZCk7CnN0YXRpYyB2b2lkIHNldF9jdXJkaXIoQ2hpbGRXbmQqIGNoaWxkLCBFbnRyeSogZW50cnksIGludCBpZHgsIEhXTkQgaHduZCk7CnN0YXRpYyB2b2lkIHJlZnJlc2hfY2hpbGQoQ2hpbGRXbmQqIGNoaWxkKTsKc3RhdGljIHZvaWQgcmVmcmVzaF9kcml2ZXModm9pZCk7CnN0YXRpYyB2b2lkIGdldF9wYXRoKEVudHJ5KiBkaXIsIFBUU1RSIHBhdGgpOwpzdGF0aWMgdm9pZCBmb3JtYXRfZGF0ZShjb25zdCBGSUxFVElNRSogZnQsIFRDSEFSKiBidWZmZXIsIGludCB2aXNpYmxlX2NvbHMpOwoKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgRnJhbWVXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKTsKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgQ2hpbGRXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKTsKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgVHJlZVduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pOwoKCi8qIGdsb2JhbHMgKi8KV0lORUZJTEVfR0xPQkFMUyBHbG9iYWxzOwoKc3RhdGljIGludCBsYXN0X3NwbGl0OwoKLyogc29tZSBjb21tb24gc3RyaW5nIGNvbnN0YW50cyAqLwpzdGF0aWMgY29uc3QgVENIQVIgc0VtcHR5W10gPSB7J1wwJ307CnN0YXRpYyBjb25zdCBXQ0hBUiBzU3BhY2VbXSA9IHsnICcsICdcMCd9OwpzdGF0aWMgY29uc3QgVENIQVIgc051bUZtdFtdID0geyclJywnZCcsJ1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzUU1hcmtzW10gPSB7Jz8nLCc/JywnPycsJ1wwJ307CgovKiB3aW5kb3cgY2xhc3MgbmFtZXMgKi8Kc3RhdGljIGNvbnN0IFRDSEFSIHNXSU5FRklMRUZSQU1FW10gPSB7J1cnLCdGJywnUycsJ18nLCdGJywncicsJ2EnLCdtJywnZScsJ1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzV0lORUZJTEVUUkVFW10gPSB7J1cnLCdGJywnUycsJ18nLCdUJywncicsJ2UnLCdlJywnXDAnfTsKCiNpZmRlZiBfTVNDX1ZFUgovKiAjZGVmaW5lIExPTkdMT05HQVJHIF9UKCJJNjQiKSAqLwpzdGF0aWMgY29uc3QgVENIQVIgc0xvbmdIZXhGbXRbXSA9IHsnJScsJ0knLCc2JywnNCcsJ1gnLCdcMCd9OwpzdGF0aWMgY29uc3QgVENIQVIgc0xvbmdOdW1GbXRbXSA9IHsnJScsJ0knLCc2JywnNCcsJ2QnLCdcMCd9OwojZWxzZQovKiAjZGVmaW5lIExPTkdMT05HQVJHIF9UKCJMIikgKi8Kc3RhdGljIGNvbnN0IFRDSEFSIHNMb25nSGV4Rm10W10gPSB7JyUnLCdMJywnWCcsJ1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzTG9uZ051bUZtdFtdID0geyclJywnTCcsJ2QnLCdcMCd9OwojZW5kaWYKCgovKiBsb2FkIHJlc291cmNlIHN0cmluZyAqLwpzdGF0aWMgTFBUU1RSIGxvYWRfc3RyaW5nKExQVFNUUiBidWZmZXIsIFVJTlQgaWQpCnsKCUxvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIGlkLCBidWZmZXIsIEJVRkZFUl9MRU4pOwoKCXJldHVybiBidWZmZXI7Cn0KCiNkZWZpbmUgUlMoYiwgaSkgbG9hZF9zdHJpbmcoYiwgaSkKCgovKiBkaXNwbGF5IGVycm9yIG1lc3NhZ2UgZm9yIHRoZSBzcGVjaWZpZWQgV0lOMzIgZXJyb3IgY29kZSAqLwpzdGF0aWMgdm9pZCBkaXNwbGF5X2Vycm9yKEhXTkQgaHduZCwgRFdPUkQgZXJyb3IpCnsKCVRDSEFSIGIxW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCVBUU1RSIG1zZzsKCglpZiAoRm9ybWF0TWVzc2FnZShGT1JNQVRfTUVTU0FHRV9BTExPQ0FURV9CVUZGRVJ8Rk9STUFUX01FU1NBR0VfRlJPTV9TWVNURU0sCgkJMCwgZXJyb3IsIE1BS0VMQU5HSUQoTEFOR19ORVVUUkFMLFNVQkxBTkdfREVGQVVMVCksIChQVFNUUikmbXNnLCAwLCBOVUxMKSkKCQlNZXNzYWdlQm94KGh3bmQsIG1zZywgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwoJZWxzZQoJCU1lc3NhZ2VCb3goaHduZCwgUlMoYjEsSURTX0VSUk9SKSwgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwoKCUxvY2FsRnJlZShtc2cpOwp9CgoKLyogZGlzcGxheSBuZXR3b3JrIGVycm9yIG1lc3NhZ2UgdXNpbmcgV05ldEdldExhc3RFcnJvcigpICovCnN0YXRpYyB2b2lkIGRpc3BsYXlfbmV0d29ya19lcnJvcihIV05EIGh3bmQpCnsKCVRDSEFSIG1zZ1tCVUZGRVJfTEVOXSwgcHJvdmlkZXJbQlVGRkVSX0xFTl0sIGIyW0JVRkZFUl9MRU5dOwoJRFdPUkQgZXJyb3I7CgoJaWYgKFdOZXRHZXRMYXN0RXJyb3IoJmVycm9yLCBtc2csIEJVRkZFUl9MRU4sIHByb3ZpZGVyLCBCVUZGRVJfTEVOKSA9PSBOT19FUlJPUikKCQlNZXNzYWdlQm94KGh3bmQsIG1zZywgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwp9CgpzdGF0aWMgVk9JRCBXaW5lTGljZW5zZShIV05EIFduZCkKewoJV0NIQVIgY2FwWzIwXSwgdGV4dFsxMDI0XTsKCUxvYWRTdHJpbmdXKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfTElDRU5TRSwgdGV4dCwgMTAyNCk7CglMb2FkU3RyaW5nVyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX0xJQ0VOU0VfQ0FQVElPTiwgY2FwLCAyMCk7CglNZXNzYWdlQm94VyhXbmQsIHRleHQsIGNhcCwgTUJfSUNPTklORk9STUFUSU9OIHwgTUJfT0spOwp9CgpzdGF0aWMgVk9JRCBXaW5lV2FycmFudHkoSFdORCBXbmQpCnsKCVdDSEFSIGNhcFsyMF0sIHRleHRbMTAyNF07CglMb2FkU3RyaW5nVyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX1dBUlJBTlRZLCB0ZXh0LCAxMDI0KTsKCUxvYWRTdHJpbmdXKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfV0FSUkFOVFlfQ0FQVElPTiwgY2FwLCAyMCk7CglNZXNzYWdlQm94VyhXbmQsIHRleHQsIGNhcCwgTUJfSUNPTkVYQ0xBTUFUSU9OIHwgTUJfT0spOwp9CgpzdGF0aWMgaW5saW5lIEJPT0wgZ2V0X2NoZWNrKEhXTkQgaHduZCwgSU5UIGlkKQp7CglyZXR1cm4gQlNUX0NIRUNLRUQmU2VuZE1lc3NhZ2VXKEdldERsZ0l0ZW0oaHduZCwgaWQpLCBCTV9HRVRTVEFURSwgMCwgMCk7Cn0KCnN0YXRpYyBpbmxpbmUgSU5UIHNldF9jaGVjayhIV05EIGh3bmQsIElOVCBpZCwgQk9PTCBvbikKewoJcmV0dXJuIFNlbmRNZXNzYWdlVyhHZXREbGdJdGVtKGh3bmQsIGlkKSwgQk1fU0VUQ0hFQ0ssIG9uP0JTVF9DSEVDS0VEOkJTVF9VTkNIRUNLRUQsIDApOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgY2hvb3NlX2ZvbnQoSFdORCBod25kKQp7CiAgICAgICAgV0NIQVIgZGxnX25hbWVbQlVGRkVSX0xFTl0sIGRsZ19pbmZvW0JVRkZFUl9MRU5dOwogICAgICAgIENIT09TRUZPTlRXIGNoRm9udDsKICAgICAgICBMT0dGT05UVyBsRm9udDsKCiAgICAgICAgSERDIGhkYyA9IEdldERDKGh3bmQpOwogICAgICAgIGNoRm9udC5sU3RydWN0U2l6ZSA9IHNpemVvZihDSE9PU0VGT05UKTsKICAgICAgICBjaEZvbnQuaHduZE93bmVyID0gaHduZDsKICAgICAgICBjaEZvbnQuaERDID0gTlVMTDsKICAgICAgICBjaEZvbnQubHBMb2dGb250ID0gJmxGb250OwogICAgICAgIGNoRm9udC5GbGFncyA9IENGX1NDUkVFTkZPTlRTIHwgQ0ZfRk9SQ0VGT05URVhJU1QgfCBDRl9MSU1JVFNJWkUgfCBDRl9OT1NDUklQVFNFTDsKICAgICAgICBjaEZvbnQucmdiQ29sb3JzID0gUkdCKDAsMCwwKTsKICAgICAgICBjaEZvbnQubEN1c3REYXRhID0gMDsKICAgICAgICBjaEZvbnQubHBmbkhvb2sgPSBOVUxMOwogICAgICAgIGNoRm9udC5scFRlbXBsYXRlTmFtZSA9IE5VTEw7CiAgICAgICAgY2hGb250LmhJbnN0YW5jZSA9IEdsb2JhbHMuaEluc3RhbmNlOwogICAgICAgIGNoRm9udC5scHN6U3R5bGUgPSBOVUxMOwogICAgICAgIGNoRm9udC5uRm9udFR5cGUgPSBTSU1VTEFURURfRk9OVFRZUEU7CiAgICAgICAgY2hGb250Lm5TaXplTWluID0gMDsKICAgICAgICBjaEZvbnQublNpemVNYXggPSAyNDsKCiAgICAgICAgaWYgKENob29zZUZvbnRXKCZjaEZvbnQpKSB7CiAgICAgICAgICAgICAgICBIV05EIGNoaWxkV25kOwogICAgICAgICAgICAgICAgSEZPTlQgaEZvbnRPbGQ7CgogICAgICAgICAgICAgICAgRGVsZXRlT2JqZWN0KEdsb2JhbHMuaGZvbnQpOwogICAgICAgICAgICAgICAgR2xvYmFscy5oZm9udCA9IENyZWF0ZUZvbnRJbmRpcmVjdFcoJmxGb250KTsKICAgICAgICAgICAgICAgIGhGb250T2xkID0gU2VsZWN0T2JqZWN0KGhkYywgR2xvYmFscy5oZm9udCk7CiAgICAgICAgICAgICAgICBHZXRUZXh0RXh0ZW50UG9pbnQzMlcoaGRjLCBzU3BhY2UsIDEsICZHbG9iYWxzLnNwYWNlU2l6ZSk7CgogICAgICAgICAgICAgICAgLyogY2hhbmdlIGZvbnQgaW4gYWxsIG9wZW4gY2hpbGQgd2luZG93cyAqLwogICAgICAgICAgICAgICAgZm9yKGNoaWxkV25kPUdldFdpbmRvdyhHbG9iYWxzLmhtZGljbGllbnQsR1dfQ0hJTEQpOyBjaGlsZFduZDsgY2hpbGRXbmQ9R2V0TmV4dFdpbmRvdyhjaGlsZFduZCxHV19IV05ETkVYVCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgQ2hpbGRXbmQqIGNoaWxkID0gKENoaWxkV25kKikgR2V0V2luZG93TG9uZ1B0clcoY2hpbGRXbmQsIEdXTFBfVVNFUkRBVEEpOwogICAgICAgICAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZVcoY2hpbGQtPmxlZnQuaHduZCwgV01fU0VURk9OVCwgKFdQQVJBTSlHbG9iYWxzLmhmb250LCBUUlVFKTsKICAgICAgICAgICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VXKGNoaWxkLT5yaWdodC5od25kLCBXTV9TRVRGT05ULCAoV1BBUkFNKUdsb2JhbHMuaGZvbnQsIFRSVUUpOwogICAgICAgICAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZVcoY2hpbGQtPmxlZnQuaHduZCwgTEJfU0VUSVRFTUhFSUdIVCwgMSwgbWF4KEdsb2JhbHMuc3BhY2VTaXplLmN5LElNQUdFX0hFSUdIVCszKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIFNlbmRNZXNzYWdlVyhjaGlsZC0+cmlnaHQuaHduZCwgTEJfU0VUSVRFTUhFSUdIVCwgMSwgbWF4KEdsb2JhbHMuc3BhY2VTaXplLmN5LElNQUdFX0hFSUdIVCszKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIEludmFsaWRhdGVSZWN0KGNoaWxkLT5sZWZ0Lmh3bmQsIE5VTEwsIFRSVUUpOwogICAgICAgICAgICAgICAgICAgICAgICBJbnZhbGlkYXRlUmVjdChjaGlsZC0+cmlnaHQuaHduZCwgTlVMTCwgVFJVRSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgU2VsZWN0T2JqZWN0KGhkYywgaEZvbnRPbGQpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChDb21tRGxnRXh0ZW5kZWRFcnJvcigpKSB7CiAgICAgICAgICAgICAgICBMb2FkU3RyaW5nVyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX0ZPTlRfU0VMX0RMR19OQU1FLCBkbGdfbmFtZSwgQlVGRkVSX0xFTik7CiAgICAgICAgICAgICAgICBMb2FkU3RyaW5nVyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX0ZPTlRfU0VMX0VSUk9SLCBkbGdfaW5mbywgQlVGRkVSX0xFTik7CiAgICAgICAgICAgICAgICBNZXNzYWdlQm94Vyhod25kLCBkbGdfaW5mbywgZGxnX25hbWUsIE1CX09LKTsKICAgICAgICB9CgogICAgICAgIFJlbGVhc2VEQyhod25kLCBoZGMpOwp9CgojaWZkZWYgX19XSU5FX18KCiNpZmRlZiBVTklDT0RFCgovKiBjYWxsIHZzd3ByaW50ZigpIGluIG1zdmNydC5kbGwgKi8KLypUT0RPOiBmaXggc3dwcmludGYoKSBpbiBub24tbXN2Y3J0IG1vZGUsIHNvIHRoYXQgdGhpcyBkeW5hbWljIGxpbmtpbmcgZnVuY3Rpb24gY2FuIGJlIHJlbW92ZWQgKi8Kc3RhdGljIGludCBtc3ZjcnRfc3dwcmludGYoV0NIQVIqIGJ1ZmZlciwgY29uc3QgV0NIQVIqIGZtdCwgLi4uKQp7CglzdGF0aWMgaW50IChfX2NkZWNsICpwdnN3cHJpbnRmKShXQ0hBUiosIGNvbnN0IFdDSEFSKiwgdmFfbGlzdCkgPSBOVUxMOwoJdmFfbGlzdCBhcDsKCWludCByZXQ7CgoJaWYgKCFwdnN3cHJpbnRmKSB7CgkJSE1PRFVMRSBoTW9kTXN2Y3J0ID0gTG9hZExpYnJhcnlBKCJtc3ZjcnQiKTsKCQlwdnN3cHJpbnRmID0gKGludChfX2NkZWNsKikoV0NIQVIqLGNvbnN0IFdDSEFSKix2YV9saXN0KSkgR2V0UHJvY0FkZHJlc3MoaE1vZE1zdmNydCwgInZzd3ByaW50ZiIpOwoJfQoKCXZhX3N0YXJ0KGFwLCBmbXQpOwoJcmV0ID0gKCpwdnN3cHJpbnRmKShidWZmZXIsIGZtdCwgYXApOwoJdmFfZW5kKGFwKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgTFBDV1NUUiBteV93Y3NyY2hyKExQQ1dTVFIgc3RyLCBXQ0hBUiBjKQp7CglMUENXU1RSIHAgPSBzdHI7CgoJd2hpbGUoKnApCgkJKytwOwoKCWRvIHsKCQlpZiAoLS1wIDwgc3RyKQoJCQlyZXR1cm4gTlVMTDsKCX0gd2hpbGUoKnAgIT0gYyk7CgoJcmV0dXJuIHA7Cn0KCiNkZWZpbmUgX3Rjc3JjaHIgbXlfd2NzcmNocgojZWxzZQkvKiBVTklDT0RFICovCiNkZWZpbmUgX3Rjc3JjaHIgc3RycmNocgojZW5kaWYJLyogVU5JQ09ERSAqLwoKI2VuZGlmCS8qIF9fV0lORV9fICovCgoKLyogYWxsb2NhdGUgYW5kIGluaXRpYWxpc2UgYSBkaXJlY3RvcnkgZW50cnkgKi8Kc3RhdGljIEVudHJ5KiBhbGxvY19lbnRyeSh2b2lkKQp7CglFbnRyeSogZW50cnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKEVudHJ5KSk7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWVudHJ5LT5waWRsID0gTlVMTDsKCWVudHJ5LT5mb2xkZXIgPSBOVUxMOwoJZW50cnktPmhpY29uID0gMDsKI2VuZGlmCgoJcmV0dXJuIGVudHJ5Owp9CgovKiBmcmVlIGEgZGlyZWN0b3J5IGVudHJ5ICovCnN0YXRpYyB2b2lkIGZyZWVfZW50cnkoRW50cnkqIGVudHJ5KQp7CiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGVudHJ5LT5oaWNvbiAmJiBlbnRyeS0+aGljb24hPShISUNPTiktMSkKCQlEZXN0cm95SWNvbihlbnRyeS0+aGljb24pOwoKCWlmIChlbnRyeS0+Zm9sZGVyICYmIGVudHJ5LT5mb2xkZXIhPUdsb2JhbHMuaURlc2t0b3ApCgkJSVNoZWxsRm9sZGVyX1JlbGVhc2UoZW50cnktPmZvbGRlcik7CgoJaWYgKGVudHJ5LT5waWRsKQoJCUlNYWxsb2NfRnJlZShHbG9iYWxzLmlNYWxsb2MsIGVudHJ5LT5waWRsKTsKI2VuZGlmCgoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZW50cnkpOwp9CgovKiByZWN1cnNpdmVseSBmcmVlIGFsbCBjaGlsZCBlbnRyaWVzICovCnN0YXRpYyB2b2lkIGZyZWVfZW50cmllcyhFbnRyeSogZGlyKQp7CglFbnRyeSAqZW50cnksICpuZXh0PWRpci0+ZG93bjsKCglpZiAobmV4dCkgewoJCWRpci0+ZG93biA9IDA7CgoJCWRvIHsKCQkJZW50cnkgPSBuZXh0OwoJCQluZXh0ID0gZW50cnktPm5leHQ7CgoJCQlmcmVlX2VudHJpZXMoZW50cnkpOwoJCQlmcmVlX2VudHJ5KGVudHJ5KTsKCQl9IHdoaWxlKG5leHQpOwoJfQp9CgoKc3RhdGljIHZvaWQgcmVhZF9kaXJlY3Rvcnlfd2luKEVudHJ5KiBkaXIsIExQQ1RTVFIgcGF0aCkKewoJRW50cnkqIGZpcnN0X2VudHJ5ID0gTlVMTDsKCUVudHJ5KiBsYXN0ID0gTlVMTDsKCUVudHJ5KiBlbnRyeTsKCglpbnQgbGV2ZWwgPSBkaXItPmxldmVsICsgMTsKCVdJTjMyX0ZJTkRfREFUQSB3MzJmZDsKCUhBTkRMRSBoRmluZDsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJSEFORExFIGhGaWxlOwojZW5kaWYKCglUQ0hBUiBidWZmZXJbTUFYX1BBVEhdLCAqcDsKCWZvcihwPWJ1ZmZlcjsgKnBhdGg7ICkKCQkqcCsrID0gKnBhdGgrKzsKCgkqcCsrID0gJ1xcJzsKCXBbMF0gPSAnKic7CglwWzFdID0gJ1wwJzsKCgloRmluZCA9IEZpbmRGaXJzdEZpbGUoYnVmZmVyLCAmdzMyZmQpOwoKCWlmIChoRmluZCAhPSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgewoJCWRvIHsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCS8qIGhpZGUgZGlyZWN0b3J5IGVudHJ5ICIuIiAqLwoJCQlpZiAodzMyZmQuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJTFBDVFNUUiBuYW1lID0gdzMyZmQuY0ZpbGVOYW1lOwoKCQkJCWlmIChuYW1lWzBdPT0nLicgJiYgbmFtZVsxXT09J1wwJykKCQkJCQljb250aW51ZTsKCQkJfQojZW5kaWYKCQkJZW50cnkgPSBhbGxvY19lbnRyeSgpOwoKCQkJaWYgKCFmaXJzdF9lbnRyeSkKCQkJCWZpcnN0X2VudHJ5ID0gZW50cnk7CgoJCQlpZiAobGFzdCkKCQkJCWxhc3QtPm5leHQgPSBlbnRyeTsKCgkJCW1lbWNweSgmZW50cnktPmRhdGEsICZ3MzJmZCwgc2l6ZW9mKFdJTjMyX0ZJTkRfREFUQSkpOwoJCQllbnRyeS0+ZG93biA9IE5VTEw7CgkJCWVudHJ5LT51cCA9IGRpcjsKCQkJZW50cnktPmV4cGFuZGVkID0gRkFMU0U7CgkJCWVudHJ5LT5zY2FubmVkID0gRkFMU0U7CgkJCWVudHJ5LT5sZXZlbCA9IGxldmVsOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQllbnRyeS0+ZXR5cGUgPSBFVF9XSU5ET1dTOwoJCQllbnRyeS0+YmhmaV92YWxpZCA9IEZBTFNFOwoKCQkJbHN0cmNweShwLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpOwoKCQkJaEZpbGUgPSBDcmVhdGVGaWxlKGJ1ZmZlciwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUR8RklMRV9TSEFSRV9XUklURXxGSUxFX1NIQVJFX0RFTEVURSwKCQkJCQkJCQkwLCBPUEVOX0VYSVNUSU5HLCBGSUxFX0ZMQUdfQkFDS1VQX1NFTUFOVElDUywgMCk7CgoJCQlpZiAoaEZpbGUgIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHsKCQkJCWlmIChHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoRmlsZSwgJmVudHJ5LT5iaGZpKSkKCQkJCQllbnRyeS0+YmhmaV92YWxpZCA9IFRSVUU7CgoJCQkJQ2xvc2VIYW5kbGUoaEZpbGUpOwoJCQl9CiNlbmRpZgoKCQkJbGFzdCA9IGVudHJ5OwoJCX0gd2hpbGUoRmluZE5leHRGaWxlKGhGaW5kLCAmdzMyZmQpKTsKCgkJaWYgKGxhc3QpCgkJCWxhc3QtPm5leHQgPSBOVUxMOwoKCQlGaW5kQ2xvc2UoaEZpbmQpOwoJfQoKCWRpci0+ZG93biA9IGZpcnN0X2VudHJ5OwoJZGlyLT5zY2FubmVkID0gVFJVRTsKfQoKCnN0YXRpYyBFbnRyeSogZmluZF9lbnRyeV93aW4oRW50cnkqIGRpciwgTFBDVFNUUiBuYW1lKQp7CglFbnRyeSogZW50cnk7CgoJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KSB7CgkJTFBDVFNUUiBwID0gbmFtZTsKCQlMUENUU1RSIHEgPSBlbnRyeS0+ZGF0YS5jRmlsZU5hbWU7CgoJCWRvIHsKCQkJaWYgKCEqcCB8fCAqcCA9PSAnXFwnIHx8ICpwID09ICcvJykKCQkJCXJldHVybiBlbnRyeTsKCQl9IHdoaWxlKHRvbG93ZXIoKnArKykgPT0gdG9sb3dlcigqcSsrKSk7CgoJCXAgPSBuYW1lOwoJCXEgPSBlbnRyeS0+ZGF0YS5jQWx0ZXJuYXRlRmlsZU5hbWU7CgoJCWRvIHsKCQkJaWYgKCEqcCB8fCAqcCA9PSAnXFwnIHx8ICpwID09ICcvJykKCQkJCXJldHVybiBlbnRyeTsKCQl9IHdoaWxlKHRvbG93ZXIoKnArKykgPT0gdG9sb3dlcigqcSsrKSk7Cgl9CgoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgRW50cnkqIHJlYWRfdHJlZV93aW4oUm9vdCogcm9vdCwgTFBDVFNUUiBwYXRoLCBTT1JUX09SREVSIHNvcnRPcmRlciwgSFdORCBod25kKQp7CglUQ0hBUiBidWZmZXJbTUFYX1BBVEhdOwoJRW50cnkqIGVudHJ5ID0gJnJvb3QtPmVudHJ5OwoJTFBDVFNUUiBzID0gcGF0aDsKCVBUU1RSIGQgPSBidWZmZXI7CgoJSENVUlNPUiBvbGRfY3Vyc29yID0gU2V0Q3Vyc29yKExvYWRDdXJzb3IoMCwgSURDX1dBSVQpKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWVudHJ5LT5ldHlwZSA9IEVUX1dJTkRPV1M7CiNlbmRpZgoKCXdoaWxlKGVudHJ5KSB7CgkJd2hpbGUoKnMgJiYgKnMgIT0gJ1xcJyAmJiAqcyAhPSAnLycpCgkJCSpkKysgPSAqcysrOwoKCQl3aGlsZSgqcyA9PSAnXFwnIHx8ICpzID09ICcvJykKCQkJcysrOwoKCQkqZCsrID0gJ1xcJzsKCQkqZCA9ICdcMCc7CgoJCXJlYWRfZGlyZWN0b3J5KGVudHJ5LCBidWZmZXIsIHNvcnRPcmRlciwgaHduZCk7CgoJCWlmIChlbnRyeS0+ZG93bikKCQkJZW50cnktPmV4cGFuZGVkID0gVFJVRTsKCgkJaWYgKCEqcykKCQkJYnJlYWs7CgoJCWVudHJ5ID0gZmluZF9lbnRyeV93aW4oZW50cnksIHMpOwoJfQoKCVNldEN1cnNvcihvbGRfY3Vyc29yKTsKCglyZXR1cm4gZW50cnk7Cn0KCgojaWYgIWRlZmluZWQoX05PX0VYVEVOU0lPTlMpICYmIGRlZmluZWQoX19XSU5FX18pCgpzdGF0aWMgQk9PTCB0aW1lX3RvX2ZpbGV0aW1lKGNvbnN0IHRpbWVfdCogdCwgRklMRVRJTUUqIGZ0aW1lKQp7CglzdHJ1Y3QgdG0qIHRtID0gZ210aW1lKHQpOwoJU1lTVEVNVElNRSBzdGltZTsKCglpZiAoIXRtKQoJCXJldHVybiBGQUxTRTsKCglzdGltZS53WWVhciA9IHRtLT50bV95ZWFyKzE5MDA7CglzdGltZS53TW9udGggPSB0bS0+dG1fbW9uKzE7CgkvKglzdGltZS53RGF5T2ZXZWVrICovCglzdGltZS53RGF5ID0gdG0tPnRtX21kYXk7CglzdGltZS53SG91ciA9IHRtLT50bV9ob3VyOwoJc3RpbWUud01pbnV0ZSA9IHRtLT50bV9taW47CglzdGltZS53U2Vjb25kID0gdG0tPnRtX3NlYzsKCglyZXR1cm4gU3lzdGVtVGltZVRvRmlsZVRpbWUoJnN0aW1lLCBmdGltZSk7Cn0KCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5X3VuaXgoRW50cnkqIGRpciwgTFBDVFNUUiBwYXRoKQp7CglFbnRyeSogZmlyc3RfZW50cnkgPSBOVUxMOwoJRW50cnkqIGxhc3QgPSBOVUxMOwoJRW50cnkqIGVudHJ5OwoJRElSKiBwZGlyOwoKCWludCBsZXZlbCA9IGRpci0+bGV2ZWwgKyAxOwojaWZkZWYgVU5JQ09ERQoJY2hhciBjcGF0aFtNQVhfUEFUSF07CgoJV2lkZUNoYXJUb011bHRpQnl0ZShDUF9VTklYQ1AsIDAsIHBhdGgsIC0xLCBjcGF0aCwgTUFYX1BBVEgsIE5VTEwsIE5VTEwpOwojZWxzZQoJY29uc3QgY2hhciogY3BhdGggPSBwYXRoOwojZW5kaWYKCglwZGlyID0gb3BlbmRpcihjcGF0aCk7CgoJaWYgKHBkaXIpIHsKCQlzdHJ1Y3Qgc3RhdCBzdDsKCQlzdHJ1Y3QgZGlyZW50KiBlbnQ7CgkJY2hhciBidWZmZXJbTUFYX1BBVEhdLCAqcDsKCQljb25zdCBjaGFyKiBzOwoKCQlmb3IocD1idWZmZXIscz1jcGF0aDsgKnM7ICkKCQkJKnArKyA9ICpzKys7CgoJCWlmIChwPT1idWZmZXIgfHwgcFstMV0hPScvJykKCQkJKnArKyA9ICcvJzsKCgkJd2hpbGUoKGVudD1yZWFkZGlyKHBkaXIpKSkgewoJCQllbnRyeSA9IGFsbG9jX2VudHJ5KCk7CgoJCQlpZiAoIWZpcnN0X2VudHJ5KQoJCQkJZmlyc3RfZW50cnkgPSBlbnRyeTsKCgkJCWlmIChsYXN0KQoJCQkJbGFzdC0+bmV4dCA9IGVudHJ5OwoKCQkJZW50cnktPmV0eXBlID0gRVRfVU5JWDsKCgkJCXN0cmNweShwLCBlbnQtPmRfbmFtZSk7CiNpZmRlZiBVTklDT0RFCgkJCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfVU5JWENQLCAwLCBwLCAtMSwgZW50cnktPmRhdGEuY0ZpbGVOYW1lLCBNQVhfUEFUSCk7CiNlbHNlCgkJCWxzdHJjcHkoZW50cnktPmRhdGEuY0ZpbGVOYW1lLCBwKTsKI2VuZGlmCgoJCQlpZiAoIXN0YXQoYnVmZmVyLCAmc3QpKSB7CgkJCQllbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzID0gcFswXT09Jy4nPyBGSUxFX0FUVFJJQlVURV9ISURERU46IDA7CgoJCQkJaWYgKFNfSVNESVIoc3Quc3RfbW9kZSkpCgkJCQkJZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyB8PSBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk7CgoJCQkJZW50cnktPmRhdGEubkZpbGVTaXplTG93ID0gc3Quc3Rfc2l6ZSAmIDB4RkZGRkZGRkY7CgkJCQllbnRyeS0+ZGF0YS5uRmlsZVNpemVIaWdoID0gc3Quc3Rfc2l6ZSA+PiAzMjsKCgkJCQltZW1zZXQoJmVudHJ5LT5kYXRhLmZ0Q3JlYXRpb25UaW1lLCAwLCBzaXplb2YoRklMRVRJTUUpKTsKCQkJCXRpbWVfdG9fZmlsZXRpbWUoJnN0LnN0X2F0aW1lLCAmZW50cnktPmRhdGEuZnRMYXN0QWNjZXNzVGltZSk7CgkJCQl0aW1lX3RvX2ZpbGV0aW1lKCZzdC5zdF9tdGltZSwgJmVudHJ5LT5kYXRhLmZ0TGFzdFdyaXRlVGltZSk7CgoJCQkJZW50cnktPmJoZmkubkZpbGVJbmRleExvdyA9IGVudC0+ZF9pbm87CgkJCQllbnRyeS0+YmhmaS5uRmlsZUluZGV4SGlnaCA9IDA7CgoJCQkJZW50cnktPmJoZmkubk51bWJlck9mTGlua3MgPSBzdC5zdF9ubGluazsKCgkJCQllbnRyeS0+YmhmaV92YWxpZCA9IFRSVUU7CgkJCX0gZWxzZSB7CgkJCQllbnRyeS0+ZGF0YS5uRmlsZVNpemVMb3cgPSAwOwoJCQkJZW50cnktPmRhdGEubkZpbGVTaXplSGlnaCA9IDA7CgkJCQllbnRyeS0+YmhmaV92YWxpZCA9IEZBTFNFOwoJCQl9CgoJCQllbnRyeS0+ZG93biA9IE5VTEw7CgkJCWVudHJ5LT51cCA9IGRpcjsKCQkJZW50cnktPmV4cGFuZGVkID0gRkFMU0U7CgkJCWVudHJ5LT5zY2FubmVkID0gRkFMU0U7CgkJCWVudHJ5LT5sZXZlbCA9IGxldmVsOwoKCQkJbGFzdCA9IGVudHJ5OwoJCX0KCgkJaWYgKGxhc3QpCgkJCWxhc3QtPm5leHQgPSBOVUxMOwoKCQljbG9zZWRpcihwZGlyKTsKCX0KCglkaXItPmRvd24gPSBmaXJzdF9lbnRyeTsKCWRpci0+c2Nhbm5lZCA9IFRSVUU7Cn0KCnN0YXRpYyBFbnRyeSogZmluZF9lbnRyeV91bml4KEVudHJ5KiBkaXIsIExQQ1RTVFIgbmFtZSkKewoJRW50cnkqIGVudHJ5OwoKCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkgewoJCUxQQ1RTVFIgcCA9IG5hbWU7CgkJTFBDVFNUUiBxID0gZW50cnktPmRhdGEuY0ZpbGVOYW1lOwoKCQlkbyB7CgkJCWlmICghKnAgfHwgKnAgPT0gJy8nKQoJCQkJcmV0dXJuIGVudHJ5OwoJCX0gd2hpbGUoKnArKyA9PSAqcSsrKTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIEVudHJ5KiByZWFkX3RyZWVfdW5peChSb290KiByb290LCBMUENUU1RSIHBhdGgsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF07CglFbnRyeSogZW50cnkgPSAmcm9vdC0+ZW50cnk7CglMUENUU1RSIHMgPSBwYXRoOwoJUFRTVFIgZCA9IGJ1ZmZlcjsKCglIQ1VSU09SIG9sZF9jdXJzb3IgPSBTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfV0FJVCkpOwoKCWVudHJ5LT5ldHlwZSA9IEVUX1VOSVg7CgoJd2hpbGUoZW50cnkpIHsKCQl3aGlsZSgqcyAmJiAqcyAhPSAnLycpCgkJCSpkKysgPSAqcysrOwoKCQl3aGlsZSgqcyA9PSAnLycpCgkJCXMrKzsKCgkJKmQrKyA9ICcvJzsKCQkqZCA9ICdcMCc7CgoJCXJlYWRfZGlyZWN0b3J5KGVudHJ5LCBidWZmZXIsIHNvcnRPcmRlciwgaHduZCk7CgoJCWlmIChlbnRyeS0+ZG93bikKCQkJZW50cnktPmV4cGFuZGVkID0gVFJVRTsKCgkJaWYgKCEqcykKCQkJYnJlYWs7CgoJCWVudHJ5ID0gZmluZF9lbnRyeV91bml4KGVudHJ5LCBzKTsKCX0KCglTZXRDdXJzb3Iob2xkX2N1cnNvcik7CgoJcmV0dXJuIGVudHJ5Owp9CgojZW5kaWYgLyogIWRlZmluZWQoX05PX0VYVEVOU0lPTlMpICYmIGRlZmluZWQoX19XSU5FX18pICovCgoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgojaWZkZWYgVU5JQ09ERQojZGVmaW5lCWdldF9zdHJyZXQgZ2V0X3N0cnJldFcKI2RlZmluZQlwYXRoX2Zyb21fcGlkbCBwYXRoX2Zyb21fcGlkbFcKI2Vsc2UKI2RlZmluZQlnZXRfc3RycmV0IGdldF9zdHJyZXRBCiNkZWZpbmUJcGF0aF9mcm9tX3BpZGwgcGF0aF9mcm9tX3BpZGxBCiNlbmRpZgoKCnN0YXRpYyB2b2lkIGZyZWVfc3RycmV0KFNUUlJFVCogc3RyKQp7CglpZiAoc3RyLT51VHlwZSA9PSBTVFJSRVRfV1NUUikKCQlJTWFsbG9jX0ZyZWUoR2xvYmFscy5pTWFsbG9jLCBzdHItPlVOSU9OX01FTUJFUihwT2xlU3RyKSk7Cn0KCgojaWZuZGVmIFVOSUNPREUKCnN0YXRpYyBMUFNUUiBzdHJjcHluKExQU1RSIGRlc3QsIExQQ1NUUiBzb3VyY2UsIHNpemVfdCBjb3VudCkKewogTFBDU1RSIHM7CiBMUFNUUiBkID0gZGVzdDsKCiBmb3Iocz1zb3VyY2U7IGNvdW50JiYoKmQrKz0qcysrKTsgKQogIGNvdW50LS07CgogcmV0dXJuIGRlc3Q7Cn0KCnN0YXRpYyB2b2lkIGdldF9zdHJyZXRBKFNUUlJFVCogc3RyLCBjb25zdCBTSElURU1JRCogc2hpaWQsIExQU1RSIGJ1ZmZlciwgaW50IGxlbikKewogc3dpdGNoKHN0ci0+dVR5cGUpIHsKICBjYXNlIFNUUlJFVF9XU1RSOgoJV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHN0ci0+VU5JT05fTUVNQkVSKHBPbGVTdHIpLCAtMSwgYnVmZmVyLCBsZW4sIE5VTEwsIE5VTEwpOwoJYnJlYWs7CgogIGNhc2UgU1RSUkVUX09GRlNFVDoKCXN0cmNweW4oYnVmZmVyLCAoTFBDU1RSKXNoaWlkK3N0ci0+VU5JT05fTUVNQkVSKHVPZmZzZXQpLCBsZW4pOwoJYnJlYWs7CgogIGNhc2UgU1RSUkVUX0NTVFI6CglzdHJjcHluKGJ1ZmZlciwgc3RyLT5VTklPTl9NRU1CRVIoY1N0ciksIGxlbik7CiB9Cn0KCnN0YXRpYyBIUkVTVUxUIHBhdGhfZnJvbV9waWRsQShJU2hlbGxGb2xkZXIqIGZvbGRlciwgTFBJVEVNSURMSVNUIHBpZGwsIExQU1RSIGJ1ZmZlciwgaW50IGxlbikKewoJU1RSUkVUIHN0cjsKCgkgLyogU0hHRE5fRk9SUEFSU0lORzogZ2V0IGZ1bGwgcGF0aCBvZiBpZCBsaXN0ICovCglIUkVTVUxUIGhyID0gSVNoZWxsRm9sZGVyX0dldERpc3BsYXlOYW1lT2YoZm9sZGVyLCBwaWRsLCBTSEdETl9GT1JQQVJTSU5HLCAmc3RyKTsKCglpZiAoU1VDQ0VFREVEKGhyKSkgewoJCWdldF9zdHJyZXRBKCZzdHIsICZwaWRsLT5ta2lkLCBidWZmZXIsIGxlbik7CgkJZnJlZV9zdHJyZXQoJnN0cik7Cgl9IGVsc2UKCQlidWZmZXJbMF0gPSAnXDAnOwoKCXJldHVybiBocjsKfQoKI2VuZGlmCgpzdGF0aWMgTFBXU1RSIHdjc2NweW4oTFBXU1RSIGRlc3QsIExQQ1dTVFIgc291cmNlLCBzaXplX3QgY291bnQpCnsKIExQQ1dTVFIgczsKIExQV1NUUiBkID0gZGVzdDsKCiBmb3Iocz1zb3VyY2U7IGNvdW50JiYoKmQrKz0qcysrKTsgKQogIGNvdW50LS07CgogcmV0dXJuIGRlc3Q7Cn0KCnN0YXRpYyB2b2lkIGdldF9zdHJyZXRXKFNUUlJFVCogc3RyLCBjb25zdCBTSElURU1JRCogc2hpaWQsIExQV1NUUiBidWZmZXIsIGludCBsZW4pCnsKIHN3aXRjaChzdHItPnVUeXBlKSB7CiAgY2FzZSBTVFJSRVRfV1NUUjoKCXdjc2NweW4oYnVmZmVyLCBzdHItPlVOSU9OX01FTUJFUihwT2xlU3RyKSwgbGVuKTsKCWJyZWFrOwoKICBjYXNlIFNUUlJFVF9PRkZTRVQ6CglNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgKExQQ1NUUilzaGlpZCtzdHItPlVOSU9OX01FTUJFUih1T2Zmc2V0KSwgLTEsIGJ1ZmZlciwgbGVuKTsKCWJyZWFrOwoKICBjYXNlIFNUUlJFVF9DU1RSOgoJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHN0ci0+VU5JT05fTUVNQkVSKGNTdHIpLCAtMSwgYnVmZmVyLCBsZW4pOwogfQp9CgoKc3RhdGljIEhSRVNVTFQgbmFtZV9mcm9tX3BpZGwoSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQSVRFTUlETElTVCBwaWRsLCBMUFRTVFIgYnVmZmVyLCBpbnQgbGVuLCBTSEdETkYgZmxhZ3MpCnsKCVNUUlJFVCBzdHI7CgoJSFJFU1VMVCBociA9IElTaGVsbEZvbGRlcl9HZXREaXNwbGF5TmFtZU9mKGZvbGRlciwgcGlkbCwgZmxhZ3MsICZzdHIpOwoKCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJZ2V0X3N0cnJldCgmc3RyLCAmcGlkbC0+bWtpZCwgYnVmZmVyLCBsZW4pOwoJCWZyZWVfc3RycmV0KCZzdHIpOwoJfSBlbHNlCgkJYnVmZmVyWzBdID0gJ1wwJzsKCglyZXR1cm4gaHI7Cn0KCgpzdGF0aWMgSFJFU1VMVCBwYXRoX2Zyb21fcGlkbFcoSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQSVRFTUlETElTVCBwaWRsLCBMUFdTVFIgYnVmZmVyLCBpbnQgbGVuKQp7CglTVFJSRVQgc3RyOwoKCSAvKiBTSEdETl9GT1JQQVJTSU5HOiBnZXQgZnVsbCBwYXRoIG9mIGlkIGxpc3QgKi8KCUhSRVNVTFQgaHIgPSBJU2hlbGxGb2xkZXJfR2V0RGlzcGxheU5hbWVPZihmb2xkZXIsIHBpZGwsIFNIR0ROX0ZPUlBBUlNJTkcsICZzdHIpOwoKCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJZ2V0X3N0cnJldFcoJnN0ciwgJnBpZGwtPm1raWQsIGJ1ZmZlciwgbGVuKTsKCQlmcmVlX3N0cnJldCgmc3RyKTsKCX0gZWxzZQoJCWJ1ZmZlclswXSA9ICdcMCc7CgoJcmV0dXJuIGhyOwp9CgoKIC8qIGNyZWF0ZSBhbiBpdGVtIGlkIGxpc3QgZnJvbSBhIGZpbGUgc3lzdGVtIHBhdGggKi8KCnN0YXRpYyBMUElURU1JRExJU1QgZ2V0X3BhdGhfcGlkbChMUFRTVFIgcGF0aCwgSFdORCBod25kKQp7CglMUElURU1JRExJU1QgcGlkbDsKCUhSRVNVTFQgaHI7CglVTE9ORyBsZW47CgojaWZkZWYgVU5JQ09ERQoJTFBXU1RSIGJ1ZmZlciA9IHBhdGg7CiNlbHNlCglXQ0hBUiBidWZmZXJbTUFYX1BBVEhdOwoJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHBhdGgsIC0xLCBidWZmZXIsIE1BWF9QQVRIKTsKI2VuZGlmCgoJaHIgPSBJU2hlbGxGb2xkZXJfUGFyc2VEaXNwbGF5TmFtZShHbG9iYWxzLmlEZXNrdG9wLCBod25kLCBOVUxMLCBidWZmZXIsICZsZW4sICZwaWRsLCBOVUxMKTsKCWlmIChGQUlMRUQoaHIpKQoJCXJldHVybiBOVUxMOwoKCXJldHVybiBwaWRsOwp9CgoKIC8qIGNvbnZlcnQgYW4gaXRlbSBpZCBsaXN0IGZyb20gcmVsYXRpdmUgdG8gYWJzb2x1dGUgKD1yZWxhdGl2ZSB0byB0aGUgZGVza3RvcCkgZm9ybWF0ICovCgpzdGF0aWMgTFBJVEVNSURMSVNUIGdldF90b19hYnNvbHV0ZV9waWRsKEVudHJ5KiBlbnRyeSwgSFdORCBod25kKQp7CglpZiAoZW50cnktPnVwICYmIGVudHJ5LT51cC0+ZXR5cGU9PUVUX1NIRUxMKSB7CgkJSVNoZWxsRm9sZGVyKiBmb2xkZXIgPSBlbnRyeS0+dXAtPmZvbGRlcjsKCQlXQ0hBUiBidWZmZXJbTUFYX1BBVEhdOwoKCQlIUkVTVUxUIGhyID0gcGF0aF9mcm9tX3BpZGxXKGZvbGRlciwgZW50cnktPnBpZGwsIGJ1ZmZlciwgTUFYX1BBVEgpOwoKCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQlMUElURU1JRExJU1QgcGlkbDsKCQkJVUxPTkcgbGVuOwoKCQkJaHIgPSBJU2hlbGxGb2xkZXJfUGFyc2VEaXNwbGF5TmFtZShHbG9iYWxzLmlEZXNrdG9wLCBod25kLCBOVUxMLCBidWZmZXIsICZsZW4sICZwaWRsLCBOVUxMKTsKCgkJCWlmIChTVUNDRUVERUQoaHIpKQoJCQkJcmV0dXJuIHBpZGw7CgkJfQoJfSBlbHNlIGlmIChlbnRyeS0+ZXR5cGUgPT0gRVRfV0lORE9XUykgewoJCVRDSEFSIHBhdGhbTUFYX1BBVEhdOwoKCQlnZXRfcGF0aChlbnRyeSwgcGF0aCk7CgoJCXJldHVybiBnZXRfcGF0aF9waWRsKHBhdGgsIGh3bmQpOwoJfSBlbHNlIGlmIChlbnRyeS0+cGlkbCkKCQlyZXR1cm4gSUxDbG9uZShlbnRyeS0+cGlkbCk7CgoJcmV0dXJuIE5VTEw7Cn0KCgpzdGF0aWMgSElDT04gZXh0cmFjdF9pY29uKElTaGVsbEZvbGRlciogZm9sZGVyLCBMUENJVEVNSURMSVNUIHBpZGwpCnsKCUlFeHRyYWN0SWNvbiogcEV4dHJhY3Q7CgoJaWYgKFNVQ0NFRURFRChJU2hlbGxGb2xkZXJfR2V0VUlPYmplY3RPZihmb2xkZXIsIDAsIDEsIChMUENJVEVNSURMSVNUKikmcGlkbCwgJklJRF9JRXh0cmFjdEljb24sIDAsIChMUFZPSUQqKSZwRXh0cmFjdCkpKSB7CgkJVENIQVIgcGF0aFtfTUFYX1BBVEhdOwoJCXVuc2lnbmVkIGZsYWdzOwoJCUhJQ09OIGhpY29uOwoJCWludCBpZHg7CgoJCWlmIChTVUNDRUVERUQoSUV4dHJhY3RJY29uV19HZXRJY29uTG9jYXRpb24ocEV4dHJhY3QsIEdJTF9GT1JTSEVMTCwgcGF0aCwgX01BWF9QQVRILCAmaWR4LCAmZmxhZ3MpKSkgewoJCQlpZiAoIShmbGFncyAmIEdJTF9OT1RGSUxFTkFNRSkpIHsKCQkJCWlmIChpZHggPT0gLTEpCgkJCQkJaWR4ID0gMDsJLyogc3BlY2lhbCBjYXNlIGZvciBzb21lIGNvbnRyb2wgcGFuZWwgYXBwbGljYXRpb25zICovCgoJCQkJaWYgKChpbnQpRXh0cmFjdEljb25FeChwYXRoLCBpZHgsIDAsICZoaWNvbiwgMSkgPiAwKQoJCQkJCWZsYWdzICY9IH5HSUxfRE9OVENBQ0hFOwoJCQl9IGVsc2UgewoJCQkJSElDT04gaEljb25MYXJnZSA9IDA7CgoJCQkJSFJFU1VMVCBociA9IElFeHRyYWN0SWNvbldfRXh0cmFjdChwRXh0cmFjdCwgcGF0aCwgaWR4LCAmaEljb25MYXJnZSwgJmhpY29uLCBNQUtFTE9ORygwLypHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYSUNPTikqLyxHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU01JQ09OKSkpOwoKCQkJCWlmIChTVUNDRUVERUQoaHIpKQoJCQkJCURlc3Ryb3lJY29uKGhJY29uTGFyZ2UpOwoJCQl9CgoJCQlyZXR1cm4gaGljb247CgkJfQoJfQoKCXJldHVybiAwOwp9CgoKc3RhdGljIEVudHJ5KiBmaW5kX2VudHJ5X3NoZWxsKEVudHJ5KiBkaXIsIExQQ0lURU1JRExJU1QgcGlkbCkKewoJRW50cnkqIGVudHJ5OwoKCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkgewoJCWlmIChlbnRyeS0+cGlkbC0+bWtpZC5jYiA9PSBwaWRsLT5ta2lkLmNiICYmCgkJCSFtZW1jbXAoZW50cnktPnBpZGwsIHBpZGwsIGVudHJ5LT5waWRsLT5ta2lkLmNiKSkKCQkJcmV0dXJuIGVudHJ5OwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgRW50cnkqIHJlYWRfdHJlZV9zaGVsbChSb290KiByb290LCBMUElURU1JRExJU1QgcGlkbCwgU09SVF9PUkRFUiBzb3J0T3JkZXIsIEhXTkQgaHduZCkKewoJRW50cnkqIGVudHJ5ID0gJnJvb3QtPmVudHJ5OwoJRW50cnkqIG5leHQ7CglMUElURU1JRExJU1QgbmV4dF9waWRsID0gcGlkbDsKCUlTaGVsbEZvbGRlciogZm9sZGVyOwoJSVNoZWxsRm9sZGVyKiBjaGlsZCA9IE5VTEw7CglIUkVTVUxUIGhyOwoKCUhDVVJTT1Igb2xkX2N1cnNvciA9IFNldEN1cnNvcihMb2FkQ3Vyc29yKDAsIElEQ19XQUlUKSk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgllbnRyeS0+ZXR5cGUgPSBFVF9TSEVMTDsKI2VuZGlmCgoJZm9sZGVyID0gR2xvYmFscy5pRGVza3RvcDsKCgl3aGlsZShlbnRyeSkgewoJCWVudHJ5LT5waWRsID0gbmV4dF9waWRsOwoJCWVudHJ5LT5mb2xkZXIgPSBmb2xkZXI7CgoJCWlmICghcGlkbC0+bWtpZC5jYikKCQkJYnJlYWs7CgoJCSAvKiBjb3B5IGZpcnN0IGVsZW1lbnQgb2YgaXRlbSBpZGxpc3QgKi8KCQluZXh0X3BpZGwgPSBJTWFsbG9jX0FsbG9jKEdsb2JhbHMuaU1hbGxvYywgcGlkbC0+bWtpZC5jYitzaXplb2YoVVNIT1JUKSk7CgkJbWVtY3B5KG5leHRfcGlkbCwgcGlkbCwgcGlkbC0+bWtpZC5jYik7CgkJKChMUElURU1JRExJU1QpKChMUEJZVEUpbmV4dF9waWRsK3BpZGwtPm1raWQuY2IpKS0+bWtpZC5jYiA9IDA7CgoJCWhyID0gSVNoZWxsRm9sZGVyX0JpbmRUb09iamVjdChmb2xkZXIsIG5leHRfcGlkbCwgMCwgJklJRF9JU2hlbGxGb2xkZXIsICh2b2lkKiopJmNoaWxkKTsKCQlpZiAoIVNVQ0NFRURFRChocikpCgkJCWJyZWFrOwoKCQlyZWFkX2RpcmVjdG9yeShlbnRyeSwgTlVMTCwgc29ydE9yZGVyLCBod25kKTsKCgkJaWYgKGVudHJ5LT5kb3duKQoJCQllbnRyeS0+ZXhwYW5kZWQgPSBUUlVFOwoKCQluZXh0ID0gZmluZF9lbnRyeV9zaGVsbChlbnRyeSwgbmV4dF9waWRsKTsKCQlpZiAoIW5leHQpCgkJCWJyZWFrOwoKCQlmb2xkZXIgPSBjaGlsZDsKCQllbnRyeSA9IG5leHQ7CgoJCSAvKiBnbyB0byBuZXh0IGVsZW1lbnQgKi8KCQlwaWRsID0gKExQSVRFTUlETElTVCkgKChMUEJZVEUpcGlkbCtwaWRsLT5ta2lkLmNiKTsKCX0KCglTZXRDdXJzb3Iob2xkX2N1cnNvcik7CgoJcmV0dXJuIGVudHJ5Owp9CgoKc3RhdGljIHZvaWQgZmlsbF93MzJmZGF0YV9zaGVsbChJU2hlbGxGb2xkZXIqIGZvbGRlciwgTFBDSVRFTUlETElTVCBwaWRsLCBTRkdBT0YgYXR0cmlicywgV0lOMzJfRklORF9EQVRBKiB3MzJmZGF0YSkKewoJaWYgKCEoYXR0cmlicyAmIFNGR0FPX0ZJTEVTWVNURU0pIHx8CgkJICBGQUlMRUQoU0hHZXREYXRhRnJvbUlETGlzdChmb2xkZXIsIHBpZGwsIFNIR0RGSUxfRklORERBVEEsIHczMmZkYXRhLCBzaXplb2YoV0lOMzJfRklORF9EQVRBKSkpKSB7CgkJV0lOMzJfRklMRV9BVFRSSUJVVEVfREFUQSBmYWQ7CgkJSURhdGFPYmplY3QqIHBEYXRhT2JqOwoKCQlTVEdNRURJVU0gbWVkaXVtID0gezAsIHswfSwgMH07CgkJRk9STUFURVRDIGZtdCA9IHtHbG9iYWxzLmNmU3RyRk5hbWUsIDAsIERWQVNQRUNUX0NPTlRFTlQsIC0xLCBUWU1FRF9IR0xPQkFMfTsKCgkJSFJFU1VMVCBociA9IElTaGVsbEZvbGRlcl9HZXRVSU9iamVjdE9mKGZvbGRlciwgMCwgMSwgJnBpZGwsICZJSURfSURhdGFPYmplY3QsIDAsIChMUFZPSUQqKSZwRGF0YU9iaik7CgoJCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJCWhyID0gSURhdGFPYmplY3RfR2V0RGF0YShwRGF0YU9iaiwgJmZtdCwgJm1lZGl1bSk7CgoJCQlJRGF0YU9iamVjdF9SZWxlYXNlKHBEYXRhT2JqKTsKCgkJCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJCQlMUENUU1RSIHBhdGggPSAoTFBDVFNUUilHbG9iYWxMb2NrKG1lZGl1bS5VTklPTl9NRU1CRVIoaEdsb2JhbCkpOwoJCQkJVUlOVCBzZW1fb3JnID0gU2V0RXJyb3JNb2RlKFNFTV9GQUlMQ1JJVElDQUxFUlJPUlMpOwoKCQkJCWlmIChHZXRGaWxlQXR0cmlidXRlc0V4KHBhdGgsIEdldEZpbGVFeEluZm9TdGFuZGFyZCwgJmZhZCkpIHsKCQkJCQl3MzJmZGF0YS0+ZHdGaWxlQXR0cmlidXRlcyA9IGZhZC5kd0ZpbGVBdHRyaWJ1dGVzOwoJCQkJCXczMmZkYXRhLT5mdENyZWF0aW9uVGltZSA9IGZhZC5mdENyZWF0aW9uVGltZTsKCQkJCQl3MzJmZGF0YS0+ZnRMYXN0QWNjZXNzVGltZSA9IGZhZC5mdExhc3RBY2Nlc3NUaW1lOwoJCQkJCXczMmZkYXRhLT5mdExhc3RXcml0ZVRpbWUgPSBmYWQuZnRMYXN0V3JpdGVUaW1lOwoKCQkJCQlpZiAoIShmYWQuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkpIHsKCQkJCQkJdzMyZmRhdGEtPm5GaWxlU2l6ZUxvdyA9IGZhZC5uRmlsZVNpemVMb3c7CgkJCQkJCXczMmZkYXRhLT5uRmlsZVNpemVIaWdoID0gZmFkLm5GaWxlU2l6ZUhpZ2g7CgkJCQkJfQoJCQkJfQoKCQkJCVNldEVycm9yTW9kZShzZW1fb3JnKTsKCgkJCQlHbG9iYWxVbmxvY2sobWVkaXVtLlVOSU9OX01FTUJFUihoR2xvYmFsKSk7CgkJCQlHbG9iYWxGcmVlKG1lZGl1bS5VTklPTl9NRU1CRVIoaEdsb2JhbCkpOwoJCQl9CgkJfQoJfQoKCWlmIChhdHRyaWJzICYgKFNGR0FPX0ZPTERFUnxTRkdBT19IQVNTVUJGT0xERVIpKQoJCXczMmZkYXRhLT5kd0ZpbGVBdHRyaWJ1dGVzIHw9IEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWTsKCglpZiAoYXR0cmlicyAmIFNGR0FPX1JFQURPTkxZKQoJCXczMmZkYXRhLT5kd0ZpbGVBdHRyaWJ1dGVzIHw9IEZJTEVfQVRUUklCVVRFX1JFQURPTkxZOwoKCWlmIChhdHRyaWJzICYgU0ZHQU9fQ09NUFJFU1NFRCkKCQl3MzJmZGF0YS0+ZHdGaWxlQXR0cmlidXRlcyB8PSBGSUxFX0FUVFJJQlVURV9DT01QUkVTU0VEOwp9CgoKc3RhdGljIHZvaWQgcmVhZF9kaXJlY3Rvcnlfc2hlbGwoRW50cnkqIGRpciwgSFdORCBod25kKQp7CglJU2hlbGxGb2xkZXIqIGZvbGRlciA9IGRpci0+Zm9sZGVyOwoJaW50IGxldmVsID0gZGlyLT5sZXZlbCArIDE7CglIUkVTVUxUIGhyOwoKCUlTaGVsbEZvbGRlciogY2hpbGQ7CglJRW51bUlETGlzdCogaWRsaXN0OwoKCUVudHJ5KiBmaXJzdF9lbnRyeSA9IE5VTEw7CglFbnRyeSogbGFzdCA9IE5VTEw7CglFbnRyeSogZW50cnk7CgoJaWYgKCFmb2xkZXIpCgkJcmV0dXJuOwoKCWhyID0gSVNoZWxsRm9sZGVyX0VudW1PYmplY3RzKGZvbGRlciwgaHduZCwgU0hDT05URl9GT0xERVJTfFNIQ09OVEZfTk9ORk9MREVSU3xTSENPTlRGX0lOQ0xVREVISURERU58U0hDT05URl9TSEFSRUFCTEV8U0hDT05URl9TVE9SQUdFLCAmaWRsaXN0KTsKCglpZiAoU1VDQ0VFREVEKGhyKSkgewoJCWZvcig7OykgewojZGVmaW5lCUZFVENIX0lURU1fQ09VTlQJMzIKCQkJTFBJVEVNSURMSVNUIHBpZGxzW0ZFVENIX0lURU1fQ09VTlRdOwoJCQlTRkdBT0YgYXR0cmliczsKCQkJVUxPTkcgY250ID0gMDsKCQkJVUxPTkcgbjsKCgkJCW1lbXNldChwaWRscywgMCwgc2l6ZW9mKHBpZGxzKSk7CgoJCQlociA9IElFbnVtSURMaXN0X05leHQoaWRsaXN0LCBGRVRDSF9JVEVNX0NPVU5ULCBwaWRscywgJmNudCk7CgkJCWlmICghU1VDQ0VFREVEKGhyKSkKCQkJCWJyZWFrOwoKCQkJaWYgKGhyID09IFNfRkFMU0UpCgkJCQlicmVhazsKCgkJCWZvcihuPTA7IG48Y250OyArK24pIHsKCQkJCWVudHJ5ID0gYWxsb2NfZW50cnkoKTsKCgkJCQlpZiAoIWZpcnN0X2VudHJ5KQoJCQkJCWZpcnN0X2VudHJ5ID0gZW50cnk7CgoJCQkJaWYgKGxhc3QpCgkJCQkJbGFzdC0+bmV4dCA9IGVudHJ5OwoKCQkJCW1lbXNldCgmZW50cnktPmRhdGEsIDAsIHNpemVvZihXSU4zMl9GSU5EX0RBVEEpKTsKCQkJCWVudHJ5LT5iaGZpX3ZhbGlkID0gRkFMU0U7CgoJCQkJYXR0cmlicyA9IH5TRkdBT19GSUxFU1lTVEVNOwkvKlNGR0FPX0hBU1NVQkZPTERFUnxTRkdBT19GT0xERVI7IFNGR0FPX0ZJTEVTWVNURU0gc29yZ3QgZGFm/HIsIGRh3yAiTXkgRG9jdW1lbnRzIiBhbnN0YXR0IHZvbiAiTWFydGluJ3MgRG9jdW1lbnRzIiBhbmdlemVpZ3Qgd2lyZCAqLwoKCQkJCWhyID0gSVNoZWxsRm9sZGVyX0dldEF0dHJpYnV0ZXNPZihmb2xkZXIsIDEsIChMUENJVEVNSURMSVNUKikmcGlkbHNbbl0sICZhdHRyaWJzKTsKCgkJCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQkJCWlmIChhdHRyaWJzICE9IChTRkdBT0YpflNGR0FPX0ZJTEVTWVNURU0pIHsKCQkJCQkJZmlsbF93MzJmZGF0YV9zaGVsbChmb2xkZXIsIHBpZGxzW25dLCBhdHRyaWJzLCAmZW50cnktPmRhdGEpOwoKCQkJCQkJZW50cnktPmJoZmlfdmFsaWQgPSBUUlVFOwoJCQkJCX0gZWxzZQoJCQkJCQlhdHRyaWJzID0gMDsKCQkJCX0gZWxzZQoJCQkJCWF0dHJpYnMgPSAwOwoKCQkJCWVudHJ5LT5waWRsID0gcGlkbHNbbl07CgoJCQkJaWYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQkJCQlociA9IElTaGVsbEZvbGRlcl9CaW5kVG9PYmplY3QoZm9sZGVyLCBwaWRsc1tuXSwgMCwgJklJRF9JU2hlbGxGb2xkZXIsICh2b2lkKiopJmNoaWxkKTsKCgkJCQkJaWYgKFNVQ0NFRURFRChocikpCgkJCQkJCWVudHJ5LT5mb2xkZXIgPSBjaGlsZDsKCQkJCQllbHNlCgkJCQkJCWVudHJ5LT5mb2xkZXIgPSBOVUxMOwoJCQkJfQoJCQkJZWxzZQoJCQkJCWVudHJ5LT5mb2xkZXIgPSBOVUxMOwoKCQkJCWlmICghZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdKQoJCQkJCS8qaHIgPSAqL25hbWVfZnJvbV9waWRsKGZvbGRlciwgcGlkbHNbbl0sIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSwgTUFYX1BBVEgsIC8qU0hHRE5fSU5GT0xERVIqLzB4MjAwMC8qMHgyMDAwPVNIR0ROX0lOQ0xVREVfTk9ORklMRVNZUyovKTsKCgkJCQkgLyogZ2V0IGRpc3BsYXkgaWNvbnMgZm9yIGZpbGVzIGFuZCB2aXJ0dWFsIG9iamVjdHMgKi8KCQkJCWlmICghKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHx8CgkJCQkJIShhdHRyaWJzICYgU0ZHQU9fRklMRVNZU1RFTSkpIHsKCQkJCQllbnRyeS0+aGljb24gPSBleHRyYWN0X2ljb24oZm9sZGVyLCBwaWRsc1tuXSk7CgoJCQkJCWlmICghZW50cnktPmhpY29uKQoJCQkJCQllbnRyeS0+aGljb24gPSAoSElDT04pLTE7CS8qIGRvbid0IHRyeSBhZ2FpbiBsYXRlciAqLwoJCQkJfQoKCQkJCWVudHJ5LT5kb3duID0gTlVMTDsKCQkJCWVudHJ5LT51cCA9IGRpcjsKCQkJCWVudHJ5LT5leHBhbmRlZCA9IEZBTFNFOwoJCQkJZW50cnktPnNjYW5uZWQgPSBGQUxTRTsKCQkJCWVudHJ5LT5sZXZlbCA9IGxldmVsOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJZW50cnktPmV0eXBlID0gRVRfU0hFTEw7CgkJCQllbnRyeS0+YmhmaV92YWxpZCA9IEZBTFNFOwojZW5kaWYKCgkJCQlsYXN0ID0gZW50cnk7CgkJCX0KCQl9CgoJCUlFbnVtSURMaXN0X1JlbGVhc2UoaWRsaXN0KTsKCX0KCglpZiAobGFzdCkKCQlsYXN0LT5uZXh0ID0gTlVMTDsKCglkaXItPmRvd24gPSBmaXJzdF9lbnRyeTsKCWRpci0+c2Nhbm5lZCA9IFRSVUU7Cn0KCiNlbmRpZiAvKiBfU0hFTExfRk9MREVSUyAqLwoKCi8qIHNvcnQgb3JkZXIgZm9yIGRpZmZlcmVudCBkaXJlY3RvcnkvZmlsZSB0eXBlcyAqLwplbnVtIFRZUEVfT1JERVIgewoJVE9fRElSID0gMCwKCVRPX0RPVCA9IDEsCglUT19ET1RET1QgPSAyLAoJVE9fT1RIRVJfRElSID0gMywKCVRPX0ZJTEUgPSA0Cn07CgovKiBkaXN0aW5ndWlzaCBiZXR3ZWVuICIuIiwgIi4uIiBhbmQgYW55IG90aGVyIGRpcmVjdG9yeSBuYW1lcyAqLwpzdGF0aWMgaW50IFR5cGVPcmRlckZyb21EaXJuYW1lKExQQ1RTVFIgbmFtZSkKewoJaWYgKG5hbWVbMF0gPT0gJy4nKSB7CgkJaWYgKG5hbWVbMV0gPT0gJ1wwJykKCQkJcmV0dXJuIFRPX0RPVDsJLyogIi4iICovCgoJCWlmIChuYW1lWzFdPT0nLicgJiYgbmFtZVsyXT09J1wwJykKCQkJcmV0dXJuIFRPX0RPVERPVDsJLyogIi4uIiAqLwoJfQoKCXJldHVybiBUT19PVEhFUl9ESVI7CS8qIGFueXRoaW5nIGVsc2UgKi8KfQoKLyogZGlyZWN0b3JpZXMgZmlyc3QuLi4gKi8Kc3RhdGljIGludCBjb21wYXJlVHlwZShjb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMSwgY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDIpCnsKCWludCBvcmRlcjEgPSBmZDEtPmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk/IFRPX0RJUjogVE9fRklMRTsKCWludCBvcmRlcjIgPSBmZDItPmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk/IFRPX0RJUjogVE9fRklMRTsKCgkvKiBIYW5kbGUgIi4iIGFuZCAiLi4iIGFzIHNwZWNpYWwgY2FzZSBhbmQgbW92ZSB0aGVtIGF0IHRoZSB2ZXJ5IGZpcnN0IGJlZ2lubmluZy4gKi8KCWlmIChvcmRlcjE9PVRPX0RJUiAmJiBvcmRlcjI9PVRPX0RJUikgewoJCW9yZGVyMSA9IFR5cGVPcmRlckZyb21EaXJuYW1lKGZkMS0+Y0ZpbGVOYW1lKTsKCQlvcmRlcjIgPSBUeXBlT3JkZXJGcm9tRGlybmFtZShmZDItPmNGaWxlTmFtZSk7Cgl9CgoJcmV0dXJuIG9yZGVyMj09b3JkZXIxPyAwOiBvcmRlcjE8b3JkZXIyPyAtMTogMTsKfQoKCnN0YXRpYyBpbnQgY29tcGFyZU5hbWUoY29uc3Qgdm9pZCogYXJnMSwgY29uc3Qgdm9pZCogYXJnMikKewoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDEgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcxKS0+ZGF0YTsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQyID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMiktPmRhdGE7CgoJaW50IGNtcCA9IGNvbXBhcmVUeXBlKGZkMSwgZmQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCglyZXR1cm4gbHN0cmNtcGkoZmQxLT5jRmlsZU5hbWUsIGZkMi0+Y0ZpbGVOYW1lKTsKfQoKc3RhdGljIGludCBjb21wYXJlRXh0KGNvbnN0IHZvaWQqIGFyZzEsIGNvbnN0IHZvaWQqIGFyZzIpCnsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQxID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMSktPmRhdGE7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMiA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzIpLT5kYXRhOwoJY29uc3QgVENIQVIgKm5hbWUxLCAqbmFtZTIsICpleHQxLCAqZXh0MjsKCglpbnQgY21wID0gY29tcGFyZVR5cGUoZmQxLCBmZDIpOwoJaWYgKGNtcCkKCQlyZXR1cm4gY21wOwoKCW5hbWUxID0gZmQxLT5jRmlsZU5hbWU7CgluYW1lMiA9IGZkMi0+Y0ZpbGVOYW1lOwoKCWV4dDEgPSBfdGNzcmNocihuYW1lMSwgJy4nKTsKCWV4dDIgPSBfdGNzcmNocihuYW1lMiwgJy4nKTsKCglpZiAoZXh0MSkKCQlleHQxKys7CgllbHNlCgkJZXh0MSA9IHNFbXB0eTsKCglpZiAoZXh0MikKCQlleHQyKys7CgllbHNlCgkJZXh0MiA9IHNFbXB0eTsKCgljbXAgPSBsc3RyY21waShleHQxLCBleHQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCglyZXR1cm4gbHN0cmNtcGkobmFtZTEsIG5hbWUyKTsKfQoKc3RhdGljIGludCBjb21wYXJlU2l6ZShjb25zdCB2b2lkKiBhcmcxLCBjb25zdCB2b2lkKiBhcmcyKQp7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMSA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzEpLT5kYXRhOwoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDIgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcyKS0+ZGF0YTsKCglpbnQgY21wID0gY29tcGFyZVR5cGUoZmQxLCBmZDIpOwoJaWYgKGNtcCkKCQlyZXR1cm4gY21wOwoKCWNtcCA9IGZkMi0+bkZpbGVTaXplSGlnaCAtIGZkMS0+bkZpbGVTaXplSGlnaDsKCglpZiAoY21wIDwgMCkKCQlyZXR1cm4gLTE7CgllbHNlIGlmIChjbXAgPiAwKQoJCXJldHVybiAxOwoKCWNtcCA9IGZkMi0+bkZpbGVTaXplTG93IC0gZmQxLT5uRmlsZVNpemVMb3c7CgoJcmV0dXJuIGNtcDwwPyAtMTogY21wPjA/IDE6IDA7Cn0KCnN0YXRpYyBpbnQgY29tcGFyZURhdGUoY29uc3Qgdm9pZCogYXJnMSwgY29uc3Qgdm9pZCogYXJnMikKewoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDEgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcxKS0+ZGF0YTsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQyID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMiktPmRhdGE7CgoJaW50IGNtcCA9IGNvbXBhcmVUeXBlKGZkMSwgZmQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCglyZXR1cm4gQ29tcGFyZUZpbGVUaW1lKCZmZDItPmZ0TGFzdFdyaXRlVGltZSwgJmZkMS0+ZnRMYXN0V3JpdGVUaW1lKTsKfQoKCnN0YXRpYyBpbnQgKCpzb3J0RnVuY3Rpb25zW10pKGNvbnN0IHZvaWQqIGFyZzEsIGNvbnN0IHZvaWQqIGFyZzIpID0gewoJY29tcGFyZU5hbWUsCS8qIFNPUlRfTkFNRSAqLwoJY29tcGFyZUV4dCwJCS8qIFNPUlRfRVhUICovCgljb21wYXJlU2l6ZSwJLyogU09SVF9TSVpFICovCgljb21wYXJlRGF0ZQkJLyogU09SVF9EQVRFICovCn07CgoKc3RhdGljIHZvaWQgU29ydERpcmVjdG9yeShFbnRyeSogZGlyLCBTT1JUX09SREVSIHNvcnRPcmRlcikKewoJRW50cnkqIGVudHJ5ID0gZGlyLT5kb3duOwoJRW50cnkqKiBhcnJheSwgKipwOwoJaW50IGxlbjsKCglsZW4gPSAwOwoJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KQoJCWxlbisrOwoKCWlmIChsZW4pIHsKCQlhcnJheSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4qc2l6ZW9mKEVudHJ5KikpOwoKCQlwID0gYXJyYXk7CgkJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KQoJCQkqcCsrID0gZW50cnk7CgoJCS8qIGNhbGwgcXNvcnQgd2l0aCB0aGUgYXBwcm9wcmlhdGUgY29tcGFyZSBmdW5jdGlvbiAqLwoJCXFzb3J0KGFycmF5LCBsZW4sIHNpemVvZihhcnJheVswXSksIHNvcnRGdW5jdGlvbnNbc29ydE9yZGVyXSk7CgoJCWRpci0+ZG93biA9IGFycmF5WzBdOwoKCQlmb3IocD1hcnJheTsgLS1sZW47IHArKykKCQkJcFswXS0+bmV4dCA9IHBbMV07CgoJCSgqcCktPm5leHQgPSAwOwoKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGFycmF5KTsKCX0KfQoKCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5KEVudHJ5KiBkaXIsIExQQ1RTVFIgcGF0aCwgU09SVF9PUkRFUiBzb3J0T3JkZXIsIEhXTkQgaHduZCkKewoJVENIQVIgYnVmZmVyW01BWF9QQVRIXTsKCUVudHJ5KiBlbnRyeTsKCUxQQ1RTVFIgczsKCVBUU1RSIGQ7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChkaXItPmV0eXBlID09IEVUX1NIRUxMKQoJewoJCXJlYWRfZGlyZWN0b3J5X3NoZWxsKGRpciwgaHduZCk7CgoJCWlmIChHbG9iYWxzLnByZXNjYW5fbm9kZSkgewoJCQlzID0gcGF0aDsKCQkJZCA9IGJ1ZmZlcjsKCgkJCXdoaWxlKCpzKQoJCQkJKmQrKyA9ICpzKys7CgoJCQkqZCsrID0gJ1xcJzsKCgkJCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQkJCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCQkJcmVhZF9kaXJlY3Rvcnlfc2hlbGwoZW50cnksIGh3bmQpOwoJCQkJCVNvcnREaXJlY3RvcnkoZW50cnksIHNvcnRPcmRlcik7CgkJCQl9CgkJfQoJfQoJZWxzZQojZW5kaWYKI2lmICFkZWZpbmVkKF9OT19FWFRFTlNJT05TKSAmJiBkZWZpbmVkKF9fV0lORV9fKQoJaWYgKGRpci0+ZXR5cGUgPT0gRVRfVU5JWCkKCXsKCQlyZWFkX2RpcmVjdG9yeV91bml4KGRpciwgcGF0aCk7CgoJCWlmIChHbG9iYWxzLnByZXNjYW5fbm9kZSkgewoJCQlzID0gcGF0aDsKCQkJZCA9IGJ1ZmZlcjsKCgkJCXdoaWxlKCpzKQoJCQkJKmQrKyA9ICpzKys7CgoJCQkqZCsrID0gJy8nOwoKCQkJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KQoJCQkJaWYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQkJCQlsc3RyY3B5KGQsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSk7CgkJCQkJcmVhZF9kaXJlY3RvcnlfdW5peChlbnRyeSwgYnVmZmVyKTsKCQkJCQlTb3J0RGlyZWN0b3J5KGVudHJ5LCBzb3J0T3JkZXIpOwoJCQkJfQoJCX0KCX0KCWVsc2UKI2VuZGlmCgl7CgkJcmVhZF9kaXJlY3Rvcnlfd2luKGRpciwgcGF0aCk7CgoJCWlmIChHbG9iYWxzLnByZXNjYW5fbm9kZSkgewoJCQlzID0gcGF0aDsKCQkJZCA9IGJ1ZmZlcjsKCgkJCXdoaWxlKCpzKQoJCQkJKmQrKyA9ICpzKys7CgoJCQkqZCsrID0gJ1xcJzsKCgkJCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQkJCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCQkJbHN0cmNweShkLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpOwoJCQkJCXJlYWRfZGlyZWN0b3J5X3dpbihlbnRyeSwgYnVmZmVyKTsKCQkJCQlTb3J0RGlyZWN0b3J5KGVudHJ5LCBzb3J0T3JkZXIpOwoJCQkJfQoJCX0KCX0KCglTb3J0RGlyZWN0b3J5KGRpciwgc29ydE9yZGVyKTsKfQoKCnN0YXRpYyBFbnRyeSogcmVhZF90cmVlKFJvb3QqIHJvb3QsIExQQ1RTVFIgcGF0aCwgTFBJVEVNSURMSVNUIHBpZGwsIExQVFNUUiBkcnYsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKI2lmICFkZWZpbmVkKF9OT19FWFRFTlNJT05TKSAmJiBkZWZpbmVkKF9fV0lORV9fKQoJc3RhdGljIGNvbnN0IFRDSEFSIHNTbGFzaFtdID0geycvJywgJ1wwJ307CiNlbmRpZgoJc3RhdGljIGNvbnN0IFRDSEFSIHNCYWNrc2xhc2hbXSA9IHsnXFwnLCAnXDAnfTsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKHBpZGwpCgl7CgkJIC8qIHJlYWQgc2hlbGwgbmFtZXNwYWNlIHRyZWUgKi8KCQlyb290LT5kcml2ZV90eXBlID0gRFJJVkVfVU5LTk9XTjsKCQlkcnZbMF0gPSAnXFwnOwoJCWRydlsxXSA9ICdcMCc7CgkJbG9hZF9zdHJpbmcocm9vdC0+dm9sbmFtZSwgSURTX0RFU0tUT1ApOwoJCXJvb3QtPmZzX2ZsYWdzID0gMDsKCQlsb2FkX3N0cmluZyhyb290LT5mcywgSURTX1NIRUxMKTsKCgkJcmV0dXJuIHJlYWRfdHJlZV9zaGVsbChyb290LCBwaWRsLCBzb3J0T3JkZXIsIGh3bmQpOwoJfQoJZWxzZQojZW5kaWYKI2lmICFkZWZpbmVkKF9OT19FWFRFTlNJT05TKSAmJiBkZWZpbmVkKF9fV0lORV9fKQoJaWYgKCpwYXRoID09ICcvJykKCXsKCQkgLyogcmVhZCB1bml4IGZpbGUgc3lzdGVtIHRyZWUgKi8KCQlyb290LT5kcml2ZV90eXBlID0gR2V0RHJpdmVUeXBlKHBhdGgpOwoKCQlsc3RyY2F0KGRydiwgc1NsYXNoKTsKCQlsb2FkX3N0cmluZyhyb290LT52b2xuYW1lLCBJRFNfUk9PVF9GUyk7CgkJcm9vdC0+ZnNfZmxhZ3MgPSAwOwoJCWxvYWRfc3RyaW5nKHJvb3QtPmZzLCBJRFNfVU5JWEZTKTsKCgkJbHN0cmNweShyb290LT5wYXRoLCBzU2xhc2gpOwoKCQlyZXR1cm4gcmVhZF90cmVlX3VuaXgocm9vdCwgcGF0aCwgc29ydE9yZGVyLCBod25kKTsKCX0KI2VuZGlmCgoJIC8qIHJlYWQgV0lOMzIgZmlsZSBzeXN0ZW0gdHJlZSAqLwoJcm9vdC0+ZHJpdmVfdHlwZSA9IEdldERyaXZlVHlwZShwYXRoKTsKCglsc3RyY2F0KGRydiwgc0JhY2tzbGFzaCk7CglHZXRWb2x1bWVJbmZvcm1hdGlvbihkcnYsIHJvb3QtPnZvbG5hbWUsIF9NQVhfRk5BTUUsIDAsIDAsICZyb290LT5mc19mbGFncywgcm9vdC0+ZnMsIF9NQVhfRElSKTsKCglsc3RyY3B5KHJvb3QtPnBhdGgsIGRydik7CgoJcmV0dXJuIHJlYWRfdHJlZV93aW4ocm9vdCwgcGF0aCwgc29ydE9yZGVyLCBod25kKTsKfQoKCi8qIGZsYWdzIHRvIGZpbHRlciBkaWZmZXJlbnQgZmlsZSB0eXBlcyAqLwplbnVtIFRZUEVfRklMVEVSIHsKCVRGX0RJUkVDVE9SSUVTCT0gMHgwMSwKCVRGX1BST0dSQU1TCQk9IDB4MDIsCglURl9ET0NVTUVOVFMJPSAweDA0LAoJVEZfT1RIRVJTCQk9IDB4MDgsCglURl9ISURERU4JCT0gMHgxMCwKCVRGX0FMTAkJCT0gMHgxRgp9OwoKCnN0YXRpYyBDaGlsZFduZCogYWxsb2NfY2hpbGRfd2luZG93KExQQ1RTVFIgcGF0aCwgTFBJVEVNSURMSVNUIHBpZGwsIEhXTkQgaHduZCkKewoJVENIQVIgZHJ2W19NQVhfRFJJVkUrMV0sIGRpcltfTUFYX0RJUl0sIG5hbWVbX01BWF9GTkFNRV0sIGV4dFtfTUFYX0VYVF07CglUQ0hBUiBkaXJfcGF0aFtNQVhfUEFUSF07CglUQ0hBUiBiMVtCVUZGRVJfTEVOXTsKCXN0YXRpYyBjb25zdCBUQ0hBUiBzQXN0ZXJpY3NbXSA9IHsnKicsICdcMCd9OwoKCUNoaWxkV25kKiBjaGlsZCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoQ2hpbGRXbmQpKTsKCVJvb3QqIHJvb3QgPSAmY2hpbGQtPnJvb3Q7CglFbnRyeSogZW50cnk7CgoJbWVtc2V0KGNoaWxkLCAwLCBzaXplb2YoQ2hpbGRXbmQpKTsKCgljaGlsZC0+bGVmdC50cmVlUGFuZSA9IFRSVUU7CgljaGlsZC0+bGVmdC52aXNpYmxlX2NvbHMgPSAwOwoKCWNoaWxkLT5yaWdodC50cmVlUGFuZSA9IEZBTFNFOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgljaGlsZC0+cmlnaHQudmlzaWJsZV9jb2xzID0gQ09MX1NJWkV8Q09MX0RBVEV8Q09MX1RJTUV8Q09MX0FUVFJJQlVURVN8Q09MX0lOREVYfENPTF9MSU5LUzsKI2Vsc2UKCWNoaWxkLT5yaWdodC52aXNpYmxlX2NvbHMgPSBDT0xfU0laRXxDT0xfREFURXxDT0xfVElNRXxDT0xfQVRUUklCVVRFUzsKI2VuZGlmCgoJY2hpbGQtPnBvcy5sZW5ndGggPSBzaXplb2YoV0lORE9XUExBQ0VNRU5UKTsKCWNoaWxkLT5wb3MuZmxhZ3MgPSAwOwoJY2hpbGQtPnBvcy5zaG93Q21kID0gU1dfU0hPV05PUk1BTDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5sZWZ0ID0gQ1dfVVNFREVGQVVMVDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi50b3AgPSBDV19VU0VERUZBVUxUOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLnJpZ2h0ID0gQ1dfVVNFREVGQVVMVDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5ib3R0b20gPSBDV19VU0VERUZBVUxUOwoKCWNoaWxkLT5mb2N1c19wYW5lID0gMDsKCWNoaWxkLT5zcGxpdF9wb3MgPSBERUZBVUxUX1NQTElUX1BPUzsKCWNoaWxkLT5zb3J0T3JkZXIgPSBTT1JUX05BTUU7CgljaGlsZC0+aGVhZGVyX3dkdGhzX29rID0gRkFMU0U7CgoJaWYgKHBhdGgpCgl7CgkJbHN0cmNweShjaGlsZC0+cGF0aCwgcGF0aCk7CgoJCV90c3BsaXRwYXRoKHBhdGgsIGRydiwgZGlyLCBuYW1lLCBleHQpOwoJfQoKCWxzdHJjcHkoY2hpbGQtPmZpbHRlcl9wYXR0ZXJuLCBzQXN0ZXJpY3MpOwoJY2hpbGQtPmZpbHRlcl9mbGFncyA9IFRGX0FMTDsKCglyb290LT5lbnRyeS5sZXZlbCA9IDA7CgoJbHN0cmNweShkaXJfcGF0aCwgZHJ2KTsKCWxzdHJjYXQoZGlyX3BhdGgsIGRpcik7CgllbnRyeSA9IHJlYWRfdHJlZShyb290LCBkaXJfcGF0aCwgcGlkbCwgZHJ2LCBjaGlsZC0+c29ydE9yZGVyLCBod25kKTsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKHJvb3QtPmVudHJ5LmV0eXBlID09IEVUX1NIRUxMKQoJCWxvYWRfc3RyaW5nKHJvb3QtPmVudHJ5LmRhdGEuY0ZpbGVOYW1lLCBJRFNfREVTS1RPUCk7CgllbHNlCiNlbmRpZgoJCXdzcHJpbnRmKHJvb3QtPmVudHJ5LmRhdGEuY0ZpbGVOYW1lLCBSUyhiMSxJRFNfVElUTEVGTVQpLCBkcnYsIHJvb3QtPmZzKTsKCglyb290LT5lbnRyeS5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgPSBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk7CgoJY2hpbGQtPmxlZnQucm9vdCA9ICZyb290LT5lbnRyeTsKCWNoaWxkLT5yaWdodC5yb290ID0gTlVMTDsKCglzZXRfY3VyZGlyKGNoaWxkLCBlbnRyeSwgMCwgaHduZCk7CgoJcmV0dXJuIGNoaWxkOwp9CgoKLyogZnJlZSBhbGwgbWVtb3J5IGFzc29jaWF0ZWQgd2l0aCBhIGNoaWxkIHdpbmRvdyAqLwpzdGF0aWMgdm9pZCBmcmVlX2NoaWxkX3dpbmRvdyhDaGlsZFduZCogY2hpbGQpCnsKCWZyZWVfZW50cmllcygmY2hpbGQtPnJvb3QuZW50cnkpOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2hpbGQpOwp9CgoKLyogZ2V0IGZ1bGwgcGF0aCBvZiBzcGVjaWZpZWQgZGlyZWN0b3J5IGVudHJ5ICovCnN0YXRpYyB2b2lkIGdldF9wYXRoKEVudHJ5KiBkaXIsIFBUU1RSIHBhdGgpCnsKCUVudHJ5KiBlbnRyeTsKCWludCBsZW4gPSAwOwoJaW50IGxldmVsID0gMDsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGRpci0+ZXR5cGUgPT0gRVRfU0hFTEwpCgl7CgkJU0ZHQU9GIGF0dHJpYnM7CgkJSFJFU1VMVCBociA9IFNfT0s7CgoJCXBhdGhbMF0gPSAnXDAnOwoKCQlhdHRyaWJzID0gMDsKCgkJaWYgKGRpci0+Zm9sZGVyKQoJCQlociA9IElTaGVsbEZvbGRlcl9HZXRBdHRyaWJ1dGVzT2YoZGlyLT5mb2xkZXIsIDEsIChMUENJVEVNSURMSVNUKikmZGlyLT5waWRsLCAmYXR0cmlicyk7CgoJCWlmIChTVUNDRUVERUQoaHIpICYmIChhdHRyaWJzJlNGR0FPX0ZJTEVTWVNURU0pKSB7CgkJCUlTaGVsbEZvbGRlciogcGFyZW50ID0gZGlyLT51cD8gZGlyLT51cC0+Zm9sZGVyOiBHbG9iYWxzLmlEZXNrdG9wOwoKCQkJaHIgPSBwYXRoX2Zyb21fcGlkbChwYXJlbnQsIGRpci0+cGlkbCwgcGF0aCwgTUFYX1BBVEgpOwoJCX0KCX0KCWVsc2UKI2VuZGlmCgl7CgkJZm9yKGVudHJ5PWRpcjsgZW50cnk7IGxldmVsKyspIHsKCQkJTFBDVFNUUiBuYW1lOwoJCQlpbnQgbDsKCgkJCXsKCQkJCUxQQ1RTVFIgczsKCQkJCW5hbWUgPSBlbnRyeS0+ZGF0YS5jRmlsZU5hbWU7CgkJCQlzID0gbmFtZTsKCgkJCQlmb3IobD0wOyAqcyAmJiAqcyAhPSAnLycgJiYgKnMgIT0gJ1xcJzsgcysrKQoJCQkJCWwrKzsKCQkJfQoKCQkJaWYgKGVudHJ5LT51cCkgewoJCQkJaWYgKGwgPiAwKSB7CgkJCQkJbWVtbW92ZShwYXRoK2wrMSwgcGF0aCwgbGVuKnNpemVvZihUQ0hBUikpOwoJCQkJCW1lbWNweShwYXRoKzEsIG5hbWUsIGwqc2l6ZW9mKFRDSEFSKSk7CgkJCQkJbGVuICs9IGwrMTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJCQlpZiAoZW50cnktPmV0eXBlID09IEVUX1VOSVgpCgkJCQkJCXBhdGhbMF0gPSAnLyc7CgkJCQkJZWxzZQojZW5kaWYKCQkJCQlwYXRoWzBdID0gJ1xcJzsKCQkJCX0KCgkJCQllbnRyeSA9IGVudHJ5LT51cDsKCQkJfSBlbHNlIHsKCQkJCW1lbW1vdmUocGF0aCtsLCBwYXRoLCBsZW4qc2l6ZW9mKFRDSEFSKSk7CgkJCQltZW1jcHkocGF0aCwgbmFtZSwgbCpzaXplb2YoVENIQVIpKTsKCQkJCWxlbiArPSBsOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCWlmICghbGV2ZWwpIHsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQlpZiAoZW50cnktPmV0eXBlID09IEVUX1VOSVgpCgkJCQlwYXRoW2xlbisrXSA9ICcvJzsKCQkJZWxzZQojZW5kaWYKCQkJCXBhdGhbbGVuKytdID0gJ1xcJzsKCQl9CgoJCXBhdGhbbGVuXSA9ICdcMCc7Cgl9Cn0KCnN0YXRpYyB3aW5kb3dPcHRpb25zIGxvYWRfcmVnaXN0cnlfc2V0dGluZ3Modm9pZCkKewoJRFdPUkQgc2l6ZTsKCURXT1JEIHR5cGU7CglIS0VZIGhLZXk7Cgl3aW5kb3dPcHRpb25zIG9wdHM7CglMT0dGT05UIGxvZ2ZvbnQ7CgogICAgICAgIFJlZ09wZW5LZXlFeFcoIEhLRVlfQ1VSUkVOVF9VU0VSLCByZWdpc3RyeV9rZXksCiAgICAgICAgICAgICAgICAgICAgICAgMCwgS0VZX1FVRVJZX1ZBTFVFLCAmaEtleSApOwoKCXNpemUgPSBzaXplb2YoRFdPUkQpOwoKICAgICAgICBpZiggUmVnUXVlcnlWYWx1ZUV4VyggaEtleSwgcmVnX3N0YXJ0X3gsIE5VTEwsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSAmb3B0cy5zdGFydF94LCAmc2l6ZSApICE9IEVSUk9SX1NVQ0NFU1MgKQoJCW9wdHMuc3RhcnRfeCA9IENXX1VTRURFRkFVTFQ7CgogICAgICAgIGlmKCBSZWdRdWVyeVZhbHVlRXhXKCBoS2V5LCByZWdfc3RhcnRfeSwgTlVMTCwgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpICZvcHRzLnN0YXJ0X3ksICZzaXplICkgIT0gRVJST1JfU1VDQ0VTUyApCgkJb3B0cy5zdGFydF95ID0gQ1dfVVNFREVGQVVMVDsKCiAgICAgICAgaWYoIFJlZ1F1ZXJ5VmFsdWVFeFcoIGhLZXksIHJlZ193aWR0aCwgTlVMTCwgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpICZvcHRzLndpZHRoLCAmc2l6ZSApICE9IEVSUk9SX1NVQ0NFU1MgKQoJCW9wdHMud2lkdGggPSBDV19VU0VERUZBVUxUOwoKICAgICAgICBpZiggUmVnUXVlcnlWYWx1ZUV4VyggaEtleSwgcmVnX2hlaWdodCwgTlVMTCwgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpICZvcHRzLmhlaWdodCwgJnNpemUgKSAhPSBFUlJPUl9TVUNDRVNTICkKCQlvcHRzLmhlaWdodCA9IENXX1VTRURFRkFVTFQ7CglzaXplPXNpemVvZihsb2dmb250KTsKCWlmKCBSZWdRdWVyeVZhbHVlRXhXKCBoS2V5LCByZWdfbG9nZm9udCwgTlVMTCwgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpICZsb2dmb250LCAmc2l6ZSApICE9IEVSUk9SX1NVQ0NFU1MgKQoJCUdldE9iamVjdChHZXRTdG9ja09iamVjdChERUZBVUxUX0dVSV9GT05UKSxzaXplb2YobG9nZm9udCksJmxvZ2ZvbnQpOwoKCVJlZ0Nsb3NlS2V5KCBoS2V5ICk7CgoJR2xvYmFscy5oZm9udCA9IENyZWF0ZUZvbnRJbmRpcmVjdCgmbG9nZm9udCk7CglyZXR1cm4gb3B0czsKfQoKc3RhdGljIHZvaWQgc2F2ZV9yZWdpc3RyeV9zZXR0aW5ncyh2b2lkKQp7CglXSU5ET1dJTkZPIHdpOwoJSEtFWSBoS2V5OwoJSU5UIHdpZHRoLCBoZWlnaHQ7CglMT0dGT05UIGxvZ2ZvbnQ7CgoJd2kuY2JTaXplID0gc2l6ZW9mKCBXSU5ET1dJTkZPICk7CglHZXRXaW5kb3dJbmZvKEdsb2JhbHMuaE1haW5XbmQsICZ3aSk7Cgl3aWR0aCA9IHdpLnJjV2luZG93LnJpZ2h0IC0gd2kucmNXaW5kb3cubGVmdDsKCWhlaWdodCA9IHdpLnJjV2luZG93LmJvdHRvbSAtIHdpLnJjV2luZG93LnRvcDsKCglpZiAoIFJlZ09wZW5LZXlFeFcoIEhLRVlfQ1VSUkVOVF9VU0VSLCByZWdpc3RyeV9rZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBLRVlfU0VUX1ZBTFVFLCAmaEtleSApICE9IEVSUk9SX1NVQ0NFU1MgKQoJewoJCS8qIFVuYWJsZSB0byBzYXZlIHJlZ2lzdHJ5IHNldHRpbmdzIC0gdHJ5IHRvIGNyZWF0ZSBrZXkgKi8KICAgICAgICAgICAgICAgIGlmICggUmVnQ3JlYXRlS2V5RXhXKCBIS0VZX0NVUlJFTlRfVVNFUiwgcmVnaXN0cnlfa2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIE5VTEwsIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9TRVRfVkFMVUUsIE5VTEwsICZoS2V5LCBOVUxMICkgIT0gRVJST1JfU1VDQ0VTUyApCgkJewoJCQkvKiBGSVhNRTogQ2Fubm90IGNyZWF0ZSBrZXkgKi8KCQkJcmV0dXJuOwoJCX0KCX0KCS8qIFNhdmUgYWxsIG9mIHRoZSBzZXR0aW5ncyAqLwogICAgICAgIFJlZ1NldFZhbHVlRXhXKCBoS2V5LCByZWdfc3RhcnRfeCwgMCwgUkVHX0RXT1JELAogICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSAmd2kucmNXaW5kb3cubGVmdCwgc2l6ZW9mKERXT1JEKSApOwogICAgICAgIFJlZ1NldFZhbHVlRXhXKCBoS2V5LCByZWdfc3RhcnRfeSwgMCwgUkVHX0RXT1JELAogICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSAmd2kucmNXaW5kb3cudG9wLCBzaXplb2YoRFdPUkQpICk7CiAgICAgICAgUmVnU2V0VmFsdWVFeFcoIGhLZXksIHJlZ193aWR0aCwgMCwgUkVHX0RXT1JELAogICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSAmd2lkdGgsIHNpemVvZihEV09SRCkgKTsKICAgICAgICBSZWdTZXRWYWx1ZUV4VyggaEtleSwgcmVnX2hlaWdodCwgMCwgUkVHX0RXT1JELAogICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSAmaGVpZ2h0LCBzaXplb2YoRFdPUkQpICk7CiAgICAgICAgR2V0T2JqZWN0KEdsb2JhbHMuaGZvbnQsIHNpemVvZihsb2dmb250KSwgJmxvZ2ZvbnQpOwogICAgICAgIFJlZ1NldFZhbHVlRXhXKCBoS2V5LCByZWdfbG9nZm9udCwgMCwgUkVHX0JJTkFSWSwKICAgICAgICAgICAgICAgICAgICAgICAgKExQQllURSkgJmxvZ2ZvbnQsIHNpemVvZihMT0dGT05UKSApOwoKCS8qIFRPRE86IFNhdmUgbW9yZSBzZXR0aW5ncyBoZXJlIChMaXN0IHZzLiBEZXRhaWxlZCBWaWV3LCBldGMuKSAqLwoJUmVnQ2xvc2VLZXkoIGhLZXkgKTsKfQoKc3RhdGljIHZvaWQgcmVzaXplX2ZyYW1lX3JlY3QoSFdORCBod25kLCBQUkVDVCBwcmVjdCkKewoJaW50IG5ld190b3A7CglSRUNUIHJ0OwoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5odG9vbGJhcikpIHsKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmh0b29sYmFyLCBXTV9TSVpFLCAwLCAwKTsKCQlHZXRDbGllbnRSZWN0KEdsb2JhbHMuaHRvb2xiYXIsICZydCk7CgkJcHJlY3QtPnRvcCA9IHJ0LmJvdHRvbSszOwoJCXByZWN0LT5ib3R0b20gLT0gcnQuYm90dG9tKzM7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmhkcml2ZWJhcikpIHsKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgV01fU0laRSwgMCwgMCk7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmhkcml2ZWJhciwgJnJ0KTsKCQluZXdfdG9wID0gLS1wcmVjdC0+dG9wICsgcnQuYm90dG9tKzM7CgkJTW92ZVdpbmRvdyhHbG9iYWxzLmhkcml2ZWJhciwgMCwgcHJlY3QtPnRvcCwgcnQucmlnaHQsIG5ld190b3AsIFRSVUUpOwoJCXByZWN0LT50b3AgPSBuZXdfdG9wOwoJCXByZWN0LT5ib3R0b20gLT0gcnQuYm90dG9tKzI7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmhzdGF0dXNiYXIpKSB7CgkJaW50IHBhcnRzW10gPSB7MzAwLCA1MDB9OwoKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhzdGF0dXNiYXIsIFdNX1NJWkUsIDAsIDApOwoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaHN0YXR1c2JhciwgU0JfU0VUUEFSVFMsIDIsIChMUEFSQU0pJnBhcnRzKTsKCQlHZXRDbGllbnRSZWN0KEdsb2JhbHMuaHN0YXR1c2JhciwgJnJ0KTsKCQlwcmVjdC0+Ym90dG9tIC09IHJ0LmJvdHRvbTsKCX0KCglNb3ZlV2luZG93KEdsb2JhbHMuaG1kaWNsaWVudCwgcHJlY3QtPmxlZnQtMSxwcmVjdC0+dG9wLTEscHJlY3QtPnJpZ2h0KzIscHJlY3QtPmJvdHRvbSsxLCBUUlVFKTsKfQoKc3RhdGljIHZvaWQgcmVzaXplX2ZyYW1lKEhXTkQgaHduZCwgaW50IGN4LCBpbnQgY3kpCnsKCVJFQ1QgcmVjdDsKCglyZWN0LmxlZnQgICA9IDA7CglyZWN0LnRvcCAgICA9IDA7CglyZWN0LnJpZ2h0ICA9IGN4OwoJcmVjdC5ib3R0b20gPSBjeTsKCglyZXNpemVfZnJhbWVfcmVjdChod25kLCAmcmVjdCk7Cn0KCnN0YXRpYyB2b2lkIHJlc2l6ZV9mcmFtZV9jbGllbnQoSFdORCBod25kKQp7CglSRUNUIHJlY3Q7CgoJR2V0Q2xpZW50UmVjdChod25kLCAmcmVjdCk7CgoJcmVzaXplX2ZyYW1lX3JlY3QoaHduZCwgJnJlY3QpOwp9CgoKc3RhdGljIEhIT09LIGhjYnRob29rOwpzdGF0aWMgQ2hpbGRXbmQqIG5ld2NoaWxkID0gTlVMTDsKCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIENCVFByb2MoaW50IGNvZGUsIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCWlmIChjb2RlPT1IQ0JUX0NSRUFURVdORCAmJiBuZXdjaGlsZCkgewoJCUNoaWxkV25kKiBjaGlsZCA9IG5ld2NoaWxkOwoJCW5ld2NoaWxkID0gTlVMTDsKCgkJY2hpbGQtPmh3bmQgPSAoSFdORCkgd3BhcmFtOwoJCVNldFdpbmRvd0xvbmdQdHIoY2hpbGQtPmh3bmQsIEdXTFBfVVNFUkRBVEEsIChMUEFSQU0pY2hpbGQpOwoJfQoKCXJldHVybiBDYWxsTmV4dEhvb2tFeChoY2J0aG9vaywgY29kZSwgd3BhcmFtLCBscGFyYW0pOwp9CgpzdGF0aWMgSFdORCBjcmVhdGVfY2hpbGRfd2luZG93KENoaWxkV25kKiBjaGlsZCkKewoJTURJQ1JFQVRFU1RSVUNUIG1jczsKCWludCBpZHg7CgoJbWNzLnN6Q2xhc3MgPSBzV0lORUZJTEVUUkVFOwoJbWNzLnN6VGl0bGUgPSAoTFBUU1RSKWNoaWxkLT5wYXRoOwoJbWNzLmhPd25lciAgPSBHbG9iYWxzLmhJbnN0YW5jZTsKCW1jcy54ICAgICAgID0gY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmxlZnQ7CgltY3MueSAgICAgICA9IGNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi50b3A7CgltY3MuY3ggICAgICA9IGNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5yaWdodC1jaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ubGVmdDsKCW1jcy5jeSAgICAgID0gY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmJvdHRvbS1jaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24udG9wOwoJbWNzLnN0eWxlICAgPSAwOwoJbWNzLmxQYXJhbSAgPSAwOwoKCWhjYnRob29rID0gU2V0V2luZG93c0hvb2tFeChXSF9DQlQsIENCVFByb2MsIDAsIEdldEN1cnJlbnRUaHJlYWRJZCgpKTsKCgluZXdjaGlsZCA9IGNoaWxkOwoJY2hpbGQtPmh3bmQgPSAoSFdORCkgU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElDUkVBVEUsIDAsIChMUEFSQU0pJm1jcyk7CglpZiAoIWNoaWxkLT5od25kKSB7CgkJVW5ob29rV2luZG93c0hvb2tFeChoY2J0aG9vayk7CgkJcmV0dXJuIDA7Cgl9CgoJVW5ob29rV2luZG93c0hvb2tFeChoY2J0aG9vayk7CgoJU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZCwgTEJfU0VUSVRFTUhFSUdIVCwgMSwgbWF4KEdsb2JhbHMuc3BhY2VTaXplLmN5LElNQUdFX0hFSUdIVCszKSk7CglTZW5kTWVzc2FnZShjaGlsZC0+cmlnaHQuaHduZCwgTEJfU0VUSVRFTUhFSUdIVCwgMSwgbWF4KEdsb2JhbHMuc3BhY2VTaXplLmN5LElNQUdFX0hFSUdIVCszKSk7CgoJaWR4ID0gU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZCwgTEJfRklORFNUUklORywgMCwgKExQQVJBTSljaGlsZC0+bGVmdC5jdXIpOwoJU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZCwgTEJfU0VUQ1VSU0VMLCBpZHgsIDApOwoKCXJldHVybiBjaGlsZC0+aHduZDsKfQoKCnN0cnVjdCBFeGVjdXRlRGlhbG9nIHsKCVRDSEFSCWNtZFtNQVhfUEFUSF07CglpbnQJCWNtZHNob3c7Cn07CgpzdGF0aWMgSU5UX1BUUiBDQUxMQkFDSyBFeGVjdXRlRGlhbG9nRGxnUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJc3RhdGljIHN0cnVjdCBFeGVjdXRlRGlhbG9nKiBkbGc7CgoJc3dpdGNoKG5tc2cpIHsKCQljYXNlIFdNX0lOSVRESUFMT0c6CgkJCWRsZyA9IChzdHJ1Y3QgRXhlY3V0ZURpYWxvZyopIGxwYXJhbTsKCQkJcmV0dXJuIDE7CgoJCWNhc2UgV01fQ09NTUFORDogewoJCQlpbnQgaWQgPSAoaW50KXdwYXJhbTsKCgkJCWlmIChpZCA9PSBJRE9LKSB7CgkJCQlHZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgMjAxKSwgZGxnLT5jbWQsIE1BWF9QQVRIKTsKCQkJCWRsZy0+Y21kc2hvdyA9IGdldF9jaGVjayhod25kLDIxNCkgPyBTV19TSE9XTUlOSU1JWkVEIDogU1dfU0hPV05PUk1BTDsKCQkJCUVuZERpYWxvZyhod25kLCBpZCk7CgkJCX0gZWxzZSBpZiAoaWQgPT0gSURDQU5DRUwpCgkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoKCQkJcmV0dXJuIDE7fQoJfQoKCXJldHVybiAwOwp9CgoKc3RhdGljIElOVF9QVFIgQ0FMTEJBQ0sgRGVzdGluYXRpb25EbGdQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglUQ0hBUiBiMVtCVUZGRVJfTEVOXSwgYjJbQlVGRkVSX0xFTl07CgoJc3dpdGNoKG5tc2cpIHsKCQljYXNlIFdNX0lOSVRESUFMT0c6CgkJCVNldFdpbmRvd0xvbmdQdHIoaHduZCwgR1dMUF9VU0VSREFUQSwgbHBhcmFtKTsKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIDIwMSksIChMUENUU1RSKWxwYXJhbSk7CgkJCXJldHVybiAxOwoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJaW50IGlkID0gKGludCl3cGFyYW07CgoJCQlzd2l0Y2goaWQpIHsKCQkJICBjYXNlIElET0s6IHsKCQkJCUxQVFNUUiBkZXN0ID0gKExQVFNUUikgR2V0V2luZG93TG9uZ1B0cihod25kLCBHV0xQX1VTRVJEQVRBKTsKCQkJCUdldFdpbmRvd1RleHQoR2V0RGxnSXRlbShod25kLCAyMDEpLCBkZXN0LCBNQVhfUEFUSCk7CgkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoJCQkJYnJlYWs7fQoKCQkJICBjYXNlIElEQ0FOQ0VMOgoJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCQkJCWJyZWFrOwoKCQkJICBjYXNlIDI1NDoKCQkJCU1lc3NhZ2VCb3goaHduZCwgUlMoYjEsSURTX05PX0lNUEwpLCBSUyhiMixJRFNfV0lORUZJTEUpLCBNQl9PSyk7CgkJCQlicmVhazsKCQkJfQoKCQkJcmV0dXJuIDE7CgkJfQoJfQoKCXJldHVybiAwOwp9CgoKc3RydWN0IEZpbHRlckRpYWxvZyB7CglUQ0hBUglwYXR0ZXJuW01BWF9QQVRIXTsKCWludAkJZmxhZ3M7Cn07CgpzdGF0aWMgSU5UX1BUUiBDQUxMQkFDSyBGaWx0ZXJEaWFsb2dEbGdQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglzdGF0aWMgc3RydWN0IEZpbHRlckRpYWxvZyogZGxnOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9JTklURElBTE9HOgoJCQlkbGcgPSAoc3RydWN0IEZpbHRlckRpYWxvZyopIGxwYXJhbTsKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIElEQ19WSUVXX1BBVFRFUk4pLCBkbGctPnBhdHRlcm4pOwoJCQlzZXRfY2hlY2soaHduZCwgSURDX1ZJRVdfVFlQRV9ESVJFQ1RPUklFUywgZGxnLT5mbGFncyZURl9ESVJFQ1RPUklFUyk7CgkJCXNldF9jaGVjayhod25kLCBJRENfVklFV19UWVBFX1BST0dSQU1TLCBkbGctPmZsYWdzJlRGX1BST0dSQU1TKTsKCQkJc2V0X2NoZWNrKGh3bmQsIElEQ19WSUVXX1RZUEVfRE9DVU1FTlRTLCBkbGctPmZsYWdzJlRGX0RPQ1VNRU5UUyk7CgkJCXNldF9jaGVjayhod25kLCBJRENfVklFV19UWVBFX09USEVSUywgZGxnLT5mbGFncyZURl9PVEhFUlMpOwoJCQlzZXRfY2hlY2soaHduZCwgSURDX1ZJRVdfVFlQRV9ISURERU4sIGRsZy0+ZmxhZ3MmVEZfSElEREVOKTsKCQkJcmV0dXJuIDE7CgoJCWNhc2UgV01fQ09NTUFORDogewoJCQlpbnQgaWQgPSAoaW50KXdwYXJhbTsKCgkJCWlmIChpZCA9PSBJRE9LKSB7CgkJCQlpbnQgZmxhZ3MgPSAwOwoKCQkJCUdldFdpbmRvd1RleHQoR2V0RGxnSXRlbShod25kLCBJRENfVklFV19QQVRURVJOKSwgZGxnLT5wYXR0ZXJuLCBNQVhfUEFUSCk7CgoJCQkJZmxhZ3MgfD0gZ2V0X2NoZWNrKGh3bmQsIElEQ19WSUVXX1RZUEVfRElSRUNUT1JJRVMpID8gVEZfRElSRUNUT1JJRVMgOiAwOwoJCQkJZmxhZ3MgfD0gZ2V0X2NoZWNrKGh3bmQsIElEQ19WSUVXX1RZUEVfUFJPR1JBTVMpID8gVEZfUFJPR1JBTVMgOiAwOwoJCQkJZmxhZ3MgfD0gZ2V0X2NoZWNrKGh3bmQsIElEQ19WSUVXX1RZUEVfRE9DVU1FTlRTKSA/IFRGX0RPQ1VNRU5UUyA6IDA7CgkJCQlmbGFncyB8PSBnZXRfY2hlY2soaHduZCwgSURDX1ZJRVdfVFlQRV9PVEhFUlMpID8gVEZfT1RIRVJTIDogMDsKCQkJCWZsYWdzIHw9IGdldF9jaGVjayhod25kLCBJRENfVklFV19UWVBFX0hJRERFTikgPyBURl9ISURERU4gOiAwOwoKCQkJCWRsZy0+ZmxhZ3MgPSBmbGFnczsKCgkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoJCQl9IGVsc2UgaWYgKGlkID09IElEQ0FOQ0VMKQoJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCgkJCXJldHVybiAxO30KCX0KCglyZXR1cm4gMDsKfQoKCnN0cnVjdCBQcm9wZXJ0aWVzRGlhbG9nIHsKCVRDSEFSCXBhdGhbTUFYX1BBVEhdOwoJRW50cnkJZW50cnk7Cgl2b2lkKglwVmVyc2lvbkRhdGE7Cn07CgovKiBTdHJ1Y3R1cmUgdXNlZCB0byBzdG9yZSBlbnVtZXJhdGVkIGxhbmd1YWdlcyBhbmQgY29kZSBwYWdlcy4gKi8Kc3RydWN0IExBTkdBTkRDT0RFUEFHRSB7CglXT1JEIHdMYW5ndWFnZTsKCVdPUkQgd0NvZGVQYWdlOwp9ICpscFRyYW5zbGF0ZTsKCnN0YXRpYyBMUENTVFIgSW5mb1N0cmluZ3NbXSA9IHsKCSJDb21tZW50cyIsCgkiQ29tcGFueU5hbWUiLAoJIkZpbGVEZXNjcmlwdGlvbiIsCgkiRmlsZVZlcnNpb24iLAoJIkludGVybmFsTmFtZSIsCgkiTGVnYWxDb3B5cmlnaHQiLAoJIkxlZ2FsVHJhZGVtYXJrcyIsCgkiT3JpZ2luYWxGaWxlbmFtZSIsCgkiUHJpdmF0ZUJ1aWxkIiwKCSJQcm9kdWN0TmFtZSIsCgkiUHJvZHVjdFZlcnNpb24iLAoJIlNwZWNpYWxCdWlsZCIsCglOVUxMCn07CgpzdGF0aWMgdm9pZCBQcm9wRGxnX0Rpc3BsYXlWYWx1ZShIV05EIGhsYm94LCBIV05EIGhlZGl0KQp7CglpbnQgaWR4ID0gU2VuZE1lc3NhZ2UoaGxib3gsIExCX0dFVENVUlNFTCwgMCwgMCk7CgoJaWYgKGlkeCAhPSBMQl9FUlIpIHsKCQlMUENUU1RSIHBWYWx1ZSA9IChMUENUU1RSKSBTZW5kTWVzc2FnZShobGJveCwgTEJfR0VUSVRFTURBVEEsIGlkeCwgMCk7CgoJCWlmIChwVmFsdWUpCgkJCVNldFdpbmRvd1RleHQoaGVkaXQsIHBWYWx1ZSk7Cgl9Cn0KCnN0YXRpYyB2b2lkIENoZWNrRm9yRmlsZUluZm8oc3RydWN0IFByb3BlcnRpZXNEaWFsb2cqIGRsZywgSFdORCBod25kLCBMUENUU1RSIHN0ckZpbGVuYW1lKQp7CglzdGF0aWMgVENIQVIgc0JhY2tTbGFzaFtdID0geydcXCcsJ1wwJ307CglzdGF0aWMgVENIQVIgc1RyYW5zbGF0aW9uW10gPSB7J1xcJywnVicsJ2EnLCdyJywnRicsJ2knLCdsJywnZScsJ0knLCduJywnZicsJ28nLCdcXCcsJ1QnLCdyJywnYScsJ24nLCdzJywnbCcsJ2EnLCd0JywnaScsJ28nLCduJywnXDAnfTsKCXN0YXRpYyBUQ0hBUiBzU3RyaW5nRmlsZUluZm9bXSA9IHsnXFwnLCdTJywndCcsJ3InLCdpJywnbicsJ2cnLCdGJywnaScsJ2wnLCdlJywnSScsJ24nLCdmJywnbycsJ1xcJywKCQkJCQkJCQkJCSclJywnMCcsJzQnLCd4JywnJScsJzAnLCc0JywneCcsJ1xcJywnJScsJ3MnLCdcMCd9OwoJRFdPUkQgZHdWZXJzaW9uRGF0YUxlbiA9IEdldEZpbGVWZXJzaW9uSW5mb1NpemUoc3RyRmlsZW5hbWUsIE5VTEwpOwoKCWlmIChkd1ZlcnNpb25EYXRhTGVuKSB7CgkJZGxnLT5wVmVyc2lvbkRhdGEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHdWZXJzaW9uRGF0YUxlbik7CgoJCWlmIChHZXRGaWxlVmVyc2lvbkluZm8oc3RyRmlsZW5hbWUsIDAsIGR3VmVyc2lvbkRhdGFMZW4sIGRsZy0+cFZlcnNpb25EYXRhKSkgewoJCQlMUFZPSUQgcFZhbDsKCQkJVUlOVCBuVmFsTGVuOwoKCQkJaWYgKFZlclF1ZXJ5VmFsdWUoZGxnLT5wVmVyc2lvbkRhdGEsIHNCYWNrU2xhc2gsICZwVmFsLCAmblZhbExlbikpIHsKCQkJCWlmIChuVmFsTGVuID09IHNpemVvZihWU19GSVhFREZJTEVJTkZPKSkgewoJCQkJCVZTX0ZJWEVERklMRUlORk8qIHBGaXhlZEZpbGVJbmZvID0gKFZTX0ZJWEVERklMRUlORk8qKXBWYWw7CgkJCQkJY2hhciBidWZmZXJbQlVGRkVSX0xFTl07CgoJCQkJCXNwcmludGYoYnVmZmVyLCAiJWQuJWQuJWQuJWQiLAoJCQkJCQlISVdPUkQocEZpeGVkRmlsZUluZm8tPmR3RmlsZVZlcnNpb25NUyksIExPV09SRChwRml4ZWRGaWxlSW5mby0+ZHdGaWxlVmVyc2lvbk1TKSwKCQkJCQkJSElXT1JEKHBGaXhlZEZpbGVJbmZvLT5kd0ZpbGVWZXJzaW9uTFMpLCBMT1dPUkQocEZpeGVkRmlsZUluZm8tPmR3RmlsZVZlcnNpb25MUykpOwoKCQkJCQlTZXREbGdJdGVtVGV4dEEoaHduZCwgSURDX1NUQVRJQ19QUk9QX1ZFUlNJT04sIGJ1ZmZlcik7CgkJCQl9CgkJCX0KCgkJCS8qIFJlYWQgdGhlIGxpc3Qgb2YgbGFuZ3VhZ2VzIGFuZCBjb2RlIHBhZ2VzLiAqLwoJCQlpZiAoVmVyUXVlcnlWYWx1ZShkbGctPnBWZXJzaW9uRGF0YSwgc1RyYW5zbGF0aW9uLCAmcFZhbCwgJm5WYWxMZW4pKSB7CgkJCQlzdHJ1Y3QgTEFOR0FORENPREVQQUdFKiBwVHJhbnNsYXRlID0gKHN0cnVjdCBMQU5HQU5EQ09ERVBBR0UqKXBWYWw7CgkJCQlzdHJ1Y3QgTEFOR0FORENPREVQQUdFKiBwRW5kID0gKHN0cnVjdCBMQU5HQU5EQ09ERVBBR0UqKSgoTFBCWVRFKXBWYWwrblZhbExlbik7CgoJCQkJSFdORCBobGJveCA9IEdldERsZ0l0ZW0oaHduZCwgSURDX0xJU1RfUFJPUF9WRVJTSU9OX1RZUEVTKTsKCgkJCQkvKiBSZWFkIHRoZSBmaWxlIGRlc2NyaXB0aW9uIGZvciBlYWNoIGxhbmd1YWdlIGFuZCBjb2RlIHBhZ2UuICovCgkJCQlmb3IoOyBwVHJhbnNsYXRlPHBFbmQ7ICsrcFRyYW5zbGF0ZSkgewoJCQkJCUxQQ1NUUiogcDsKCgkJCQkJZm9yKHA9SW5mb1N0cmluZ3M7ICpwOyArK3ApIHsKCQkJCQkJVENIQVIgc3ViYmxvY2tbMjAwXTsKI2lmZGVmIFVOSUNPREUKCQkJCQkJVENIQVIgaW5mb1N0clsxMDBdOwojZW5kaWYKCQkJCQkJTFBDVFNUUiBwVHh0OwoJCQkJCQlVSU5UIG5WYWxMZW47CgoJCQkJCQlMUENTVFIgcEluZm9TdHJpbmcgPSAqcDsKI2lmZGVmIFVOSUNPREUKCQkJCQkJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHBJbmZvU3RyaW5nLCAtMSwgaW5mb1N0ciwgMTAwKTsKI2Vsc2UKI2RlZmluZQlpbmZvU3RyIHBJbmZvU3RyaW5nCiNlbmRpZgoJCQkJCQl3c3ByaW50ZihzdWJibG9jaywgc1N0cmluZ0ZpbGVJbmZvLCBwVHJhbnNsYXRlLT53TGFuZ3VhZ2UsIHBUcmFuc2xhdGUtPndDb2RlUGFnZSwgaW5mb1N0cik7CgoJCQkJCQkvKiBSZXRyaWV2ZSBmaWxlIGRlc2NyaXB0aW9uIGZvciBsYW5ndWFnZSBhbmQgY29kZSBwYWdlICovCgkJCQkJCWlmIChWZXJRdWVyeVZhbHVlKGRsZy0+cFZlcnNpb25EYXRhLCBzdWJibG9jaywgKFBWT0lEKSZwVHh0LCAmblZhbExlbikpIHsKCQkJCQkJCWludCBpZHggPSBTZW5kTWVzc2FnZShobGJveCwgTEJfQUREU1RSSU5HLCAwTCwgKExQQVJBTSlpbmZvU3RyKTsKCQkJCQkJCVNlbmRNZXNzYWdlKGhsYm94LCBMQl9TRVRJVEVNREFUQSwgaWR4LCAoTFBBUkFNKSBwVHh0KTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCgkJCQlTZW5kTWVzc2FnZShobGJveCwgTEJfU0VUQ1VSU0VMLCAwLCAwKTsKCgkJCQlQcm9wRGxnX0Rpc3BsYXlWYWx1ZShobGJveCwgR2V0RGxnSXRlbShod25kLElEQ19MSVNUX1BST1BfVkVSU0lPTl9WQUxVRVMpKTsKCQkJfQoJCX0KCX0KfQoKc3RhdGljIElOVF9QVFIgQ0FMTEJBQ0sgUHJvcGVydGllc0RpYWxvZ0RsZ1Byb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCXN0YXRpYyBzdHJ1Y3QgUHJvcGVydGllc0RpYWxvZyogZGxnOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9JTklURElBTE9HOiB7CgkJCXN0YXRpYyBjb25zdCBUQ0hBUiBzQnl0ZUZtdFtdID0geyclJywncycsJyAnLCdCJywneScsJ3QnLCdlJywncycsJ1wwJ307CgkJCVRDSEFSIGIxW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCQkJTFBXSU4zMl9GSU5EX0RBVEEgcFdGRDsKCQkJVUxPTkdMT05HIHNpemU7CgoJCQlkbGcgPSAoc3RydWN0IFByb3BlcnRpZXNEaWFsb2cqKSBscGFyYW07CgkJCXBXRkQgPSAoTFBXSU4zMl9GSU5EX0RBVEEpICZkbGctPmVudHJ5LmRhdGE7CgoJCQlHZXRXaW5kb3dUZXh0KGh3bmQsIGIxLCBNQVhfUEFUSCk7CgkJCXdzcHJpbnRmKGIyLCBiMSwgcFdGRC0+Y0ZpbGVOYW1lKTsKCQkJU2V0V2luZG93VGV4dChod25kLCBiMik7CgoJCQlmb3JtYXRfZGF0ZSgmcFdGRC0+ZnRMYXN0V3JpdGVUaW1lLCBiMSwgQ09MX0RBVEV8Q09MX1RJTUUpOwoJCQlTZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgSURDX1NUQVRJQ19QUk9QX0xBU1RDSEFOR0UpLCBiMSk7CgoJCQlzaXplID0gKChVTE9OR0xPTkcpcFdGRC0+bkZpbGVTaXplSGlnaCA8PCAzMikgfCBwV0ZELT5uRmlsZVNpemVMb3c7CgkJCV9zdHByaW50ZihiMSwgc0xvbmdOdW1GbXQsIHNpemUpOwoJCQl3c3ByaW50ZihiMiwgc0J5dGVGbXQsIGIxKTsKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIElEQ19TVEFUSUNfUFJPUF9TSVpFKSwgYjIpOwoKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIElEQ19TVEFUSUNfUFJPUF9GSUxFTkFNRSksIHBXRkQtPmNGaWxlTmFtZSk7CgkJCVNldFdpbmRvd1RleHQoR2V0RGxnSXRlbShod25kLCBJRENfU1RBVElDX1BST1BfUEFUSCksIGRsZy0+cGF0aCk7CgoJCQlzZXRfY2hlY2soaHduZCwgSURDX0NIRUNLX1JFQURPTkxZLCBwV0ZELT5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX1JFQURPTkxZKTsKCQkJc2V0X2NoZWNrKGh3bmQsIElEQ19DSEVDS19BUkNISVZFLCBwV0ZELT5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0FSQ0hJVkUpOwoJCQlzZXRfY2hlY2soaHduZCwgSURDX0NIRUNLX0NPTVBSRVNTRUQsIHBXRkQtPmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfQ09NUFJFU1NFRCk7CgkJCXNldF9jaGVjayhod25kLCBJRENfQ0hFQ0tfSElEREVOLCBwV0ZELT5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0hJRERFTik7CgkJCXNldF9jaGVjayhod25kLCBJRENfQ0hFQ0tfU1lTVEVNLCBwV0ZELT5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX1NZU1RFTSk7CgoJCQlDaGVja0ZvckZpbGVJbmZvKGRsZywgaHduZCwgZGxnLT5wYXRoKTsKCQkJcmV0dXJuIDE7fQoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJaW50IGlkID0gKGludCl3cGFyYW07CgoJCQlzd2l0Y2goSElXT1JEKHdwYXJhbSkpIHsKCQkJICBjYXNlIExCTl9TRUxDSEFOR0U6IHsKCQkJCUhXTkQgaGxib3ggPSBHZXREbGdJdGVtKGh3bmQsIElEQ19MSVNUX1BST1BfVkVSU0lPTl9UWVBFUyk7CgkJCQlQcm9wRGxnX0Rpc3BsYXlWYWx1ZShobGJveCwgR2V0RGxnSXRlbShod25kLElEQ19MSVNUX1BST1BfVkVSU0lPTl9WQUxVRVMpKTsKCQkJCWJyZWFrOwoJCQkgIH0KCgkJCSAgY2FzZSBCTl9DTElDS0VEOgoJCQkJaWYgKGlkPT1JRE9LIHx8IGlkPT1JRENBTkNFTCkKCQkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoJCQl9CgoJCQlyZXR1cm4gMTt9CgoJCWNhc2UgV01fTkNERVNUUk9ZOgoJCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkbGctPnBWZXJzaW9uRGF0YSk7CgkJCWRsZy0+cFZlcnNpb25EYXRhID0gTlVMTDsKCQkJYnJlYWs7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHNob3dfcHJvcGVydGllc19kbGcoRW50cnkqIGVudHJ5LCBIV05EIGh3bmQpCnsKCXN0cnVjdCBQcm9wZXJ0aWVzRGlhbG9nIGRsZzsKCgltZW1zZXQoJmRsZywgMCwgc2l6ZW9mKHN0cnVjdCBQcm9wZXJ0aWVzRGlhbG9nKSk7CglnZXRfcGF0aChlbnRyeSwgZGxnLnBhdGgpOwoJbWVtY3B5KCZkbGcuZW50cnksIGVudHJ5LCBzaXplb2YoRW50cnkpKTsKCglEaWFsb2dCb3hQYXJhbShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElERF9ESUFMT0dfUFJPUEVSVElFUyksIGh3bmQsIFByb3BlcnRpZXNEaWFsb2dEbGdQcm9jLCAoTFBBUkFNKSZkbGcpOwp9CgoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoKc3RhdGljIHN0cnVjdCBGdWxsU2NyZWVuUGFyYW1ldGVycyB7CglCT09MCW1vZGU7CglSRUNUCW9yZ1BvczsKCUJPT0wJd2FzWm9vbWVkOwp9IGdfZnVsbHNjcmVlbiA9IHsKICAgIEZBTFNFLAkvKiBtb2RlICovCgl7MCwgMCwgMCwgMH0sCglGQUxTRQp9OwoKc3RhdGljIHZvaWQgZnJhbWVfZ2V0X2NsaWVudHNwYWNlKEhXTkQgaHduZCwgUFJFQ1QgcHJlY3QpCnsKCVJFQ1QgcnQ7CgoJaWYgKCFJc0ljb25pYyhod25kKSkKCQlHZXRDbGllbnRSZWN0KGh3bmQsIHByZWN0KTsKCWVsc2UgewoJCVdJTkRPV1BMQUNFTUVOVCB3cDsKCgkJR2V0V2luZG93UGxhY2VtZW50KGh3bmQsICZ3cCk7CgoJCXByZWN0LT5sZWZ0ID0gcHJlY3QtPnRvcCA9IDA7CgkJcHJlY3QtPnJpZ2h0ID0gd3AucmNOb3JtYWxQb3NpdGlvbi5yaWdodC13cC5yY05vcm1hbFBvc2l0aW9uLmxlZnQtCgkJCQkJCTIqKEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFRlJBTUUpK0dldFN5c3RlbU1ldHJpY3MoU01fQ1hFREdFKSk7CgkJcHJlY3QtPmJvdHRvbSA9IHdwLnJjTm9ybWFsUG9zaXRpb24uYm90dG9tLXdwLnJjTm9ybWFsUG9zaXRpb24udG9wLQoJCQkJCQkyKihHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRUZSQU1FKStHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSkpLQoJCQkJCQlHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTiktR2V0U3lzdGVtTWV0cmljcyhTTV9DWU1FTlVTSVpFKTsKCX0KCglpZiAoSXNXaW5kb3dWaXNpYmxlKEdsb2JhbHMuaHRvb2xiYXIpKSB7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmh0b29sYmFyLCAmcnQpOwoJCXByZWN0LT50b3AgKz0gcnQuYm90dG9tKzI7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmhkcml2ZWJhcikpIHsKCQlHZXRDbGllbnRSZWN0KEdsb2JhbHMuaGRyaXZlYmFyLCAmcnQpOwoJCXByZWN0LT50b3AgKz0gcnQuYm90dG9tKzI7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmhzdGF0dXNiYXIpKSB7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmhzdGF0dXNiYXIsICZydCk7CgkJcHJlY3QtPmJvdHRvbSAtPSBydC5ib3R0b207Cgl9Cn0KCnN0YXRpYyBCT09MIHRvZ2dsZV9mdWxsc2NyZWVuKEhXTkQgaHduZCkKewoJUkVDVCBydDsKCglpZiAoKGdfZnVsbHNjcmVlbi5tb2RlPSFnX2Z1bGxzY3JlZW4ubW9kZSkpIHsKCQlHZXRXaW5kb3dSZWN0KGh3bmQsICZnX2Z1bGxzY3JlZW4ub3JnUG9zKTsKCQlnX2Z1bGxzY3JlZW4ud2FzWm9vbWVkID0gSXNab29tZWQoaHduZCk7CgoJCUZyYW1lX0NhbGNGcmFtZUNsaWVudChod25kLCAmcnQpOwoJCUNsaWVudFRvU2NyZWVuKGh3bmQsIChMUFBPSU5UKSZydC5sZWZ0KTsKCQlDbGllbnRUb1NjcmVlbihod25kLCAoTFBQT0lOVCkmcnQucmlnaHQpOwoKCQlydC5sZWZ0ID0gZ19mdWxsc2NyZWVuLm9yZ1Bvcy5sZWZ0LXJ0LmxlZnQ7CgkJcnQudG9wID0gZ19mdWxsc2NyZWVuLm9yZ1Bvcy50b3AtcnQudG9wOwoJCXJ0LnJpZ2h0ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTikrZ19mdWxsc2NyZWVuLm9yZ1Bvcy5yaWdodC1ydC5yaWdodDsKCQlydC5ib3R0b20gPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKStnX2Z1bGxzY3JlZW4ub3JnUG9zLmJvdHRvbS1ydC5ib3R0b207CgoJCU1vdmVXaW5kb3coaHduZCwgcnQubGVmdCwgcnQudG9wLCBydC5yaWdodC1ydC5sZWZ0LCBydC5ib3R0b20tcnQudG9wLCBUUlVFKTsKCX0gZWxzZSB7CgkJTW92ZVdpbmRvdyhod25kLCBnX2Z1bGxzY3JlZW4ub3JnUG9zLmxlZnQsIGdfZnVsbHNjcmVlbi5vcmdQb3MudG9wLAoJCQkJCQkJZ19mdWxsc2NyZWVuLm9yZ1Bvcy5yaWdodC1nX2Z1bGxzY3JlZW4ub3JnUG9zLmxlZnQsCgkJCQkJCQlnX2Z1bGxzY3JlZW4ub3JnUG9zLmJvdHRvbS1nX2Z1bGxzY3JlZW4ub3JnUG9zLnRvcCwgVFJVRSk7CgoJCWlmIChnX2Z1bGxzY3JlZW4ud2FzWm9vbWVkKQoJCQlTaG93V2luZG93KGh3bmQsIFdTX01BWElNSVpFKTsKCX0KCglyZXR1cm4gZ19mdWxsc2NyZWVuLm1vZGU7Cn0KCnN0YXRpYyB2b2lkIGZ1bGxzY3JlZW5fbW92ZShIV05EIGh3bmQpCnsKCVJFQ1QgcnQsIHBvczsKCUdldFdpbmRvd1JlY3QoaHduZCwgJnBvcyk7CgoJRnJhbWVfQ2FsY0ZyYW1lQ2xpZW50KGh3bmQsICZydCk7CglDbGllbnRUb1NjcmVlbihod25kLCAoTFBQT0lOVCkmcnQubGVmdCk7CglDbGllbnRUb1NjcmVlbihod25kLCAoTFBQT0lOVCkmcnQucmlnaHQpOwoKCXJ0LmxlZnQgPSBwb3MubGVmdC1ydC5sZWZ0OwoJcnQudG9wID0gcG9zLnRvcC1ydC50b3A7CglydC5yaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pK3Bvcy5yaWdodC1ydC5yaWdodDsKCXJ0LmJvdHRvbSA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pK3Bvcy5ib3R0b20tcnQuYm90dG9tOwoKCU1vdmVXaW5kb3coaHduZCwgcnQubGVmdCwgcnQudG9wLCBydC5yaWdodC1ydC5sZWZ0LCBydC5ib3R0b20tcnQudG9wLCBUUlVFKTsKfQoKI2VuZGlmCgoKc3RhdGljIHZvaWQgdG9nZ2xlX2NoaWxkKEhXTkQgaHduZCwgVUlOVCBjbWQsIEhXTkQgaGNoaWxkKQp7CglCT09MIHZpcyA9IElzV2luZG93VmlzaWJsZShoY2hpbGQpOwoKCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudU9wdGlvbnMsIGNtZCwgdmlzP01GX0JZQ09NTUFORDpNRl9CWUNPTU1BTkR8TUZfQ0hFQ0tFRCk7CgoJU2hvd1dpbmRvdyhoY2hpbGQsIHZpcz9TV19ISURFOlNXX1NIT1cpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJaWYgKGdfZnVsbHNjcmVlbi5tb2RlKQoJCWZ1bGxzY3JlZW5fbW92ZShod25kKTsKI2VuZGlmCgoJcmVzaXplX2ZyYW1lX2NsaWVudChod25kKTsKfQoKc3RhdGljIEJPT0wgYWN0aXZhdGVfZHJpdmVfd2luZG93KExQQ1RTVFIgcGF0aCkKewoJVENIQVIgZHJ2MVtfTUFYX0RSSVZFXSwgZHJ2MltfTUFYX0RSSVZFXTsKCUhXTkQgY2hpbGRfd25kOwoKCV90c3BsaXRwYXRoKHBhdGgsIGRydjEsIDAsIDAsIDApOwoKCS8qIHNlYXJjaCBmb3IgYSBhbHJlYWR5IG9wZW4gd2luZG93IGZvciB0aGUgc2FtZSBkcml2ZSAqLwoJZm9yKGNoaWxkX3duZD1HZXROZXh0V2luZG93KEdsb2JhbHMuaG1kaWNsaWVudCxHV19DSElMRCk7IGNoaWxkX3duZDsgY2hpbGRfd25kPUdldE5leHRXaW5kb3coY2hpbGRfd25kLCBHV19IV05ETkVYVCkpIHsKCQlDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nUHRyKGNoaWxkX3duZCwgR1dMUF9VU0VSREFUQSk7CgoJCWlmIChjaGlsZCkgewoJCQlfdHNwbGl0cGF0aChjaGlsZC0+cm9vdC5wYXRoLCBkcnYyLCAwLCAwLCAwKTsKCgkJCWlmICghbHN0cmNtcGkoZHJ2MiwgZHJ2MSkpIHsKCQkJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJQUNUSVZBVEUsIChXUEFSQU0pY2hpbGRfd25kLCAwKTsKCgkJCQlpZiAoSXNJY29uaWMoY2hpbGRfd25kKSkKCQkJCQlTaG93V2luZG93KGNoaWxkX3duZCwgU1dfU0hPV05PUk1BTCk7CgoJCQkJcmV0dXJuIFRSVUU7CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgQk9PTCBhY3RpdmF0ZV9mc193aW5kb3coTFBDVFNUUiBmaWxlc3lzKQp7CglIV05EIGNoaWxkX3duZDsKCgkvKiBzZWFyY2ggZm9yIGEgYWxyZWFkeSBvcGVuIHdpbmRvdyBvZiB0aGUgZ2l2ZW4gZmlsZSBzeXN0ZW0gbmFtZSAqLwoJZm9yKGNoaWxkX3duZD1HZXROZXh0V2luZG93KEdsb2JhbHMuaG1kaWNsaWVudCxHV19DSElMRCk7IGNoaWxkX3duZDsgY2hpbGRfd25kPUdldE5leHRXaW5kb3coY2hpbGRfd25kLCBHV19IV05ETkVYVCkpIHsKCQlDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nUHRyKGNoaWxkX3duZCwgR1dMUF9VU0VSREFUQSk7CgoJCWlmIChjaGlsZCkgewoJCQlpZiAoIWxzdHJjbXBpKGNoaWxkLT5yb290LmZzLCBmaWxlc3lzKSkgewoJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElBQ1RJVkFURSwgKFdQQVJBTSljaGlsZF93bmQsIDApOwoKCQkJCWlmIChJc0ljb25pYyhjaGlsZF93bmQpKQoJCQkJCVNob3dXaW5kb3coY2hpbGRfd25kLCBTV19TSE9XTk9STUFMKTsKCgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIEZyYW1lV25kUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJVENIQVIgYjFbQlVGRkVSX0xFTl0sIGIyW0JVRkZFUl9MRU5dOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9DTE9TRToKCQkJaWYgKEdsb2JhbHMuc2F2ZVNldHRpbmdzKQoJCQkJc2F2ZV9yZWdpc3RyeV9zZXR0aW5ncygpOyAgCgkJCQoJCQlEZXN0cm95V2luZG93KGh3bmQpOwoKCQkJIC8qIGNsZWFyIGhhbmRsZSB2YXJpYWJsZXMgKi8KCQkJR2xvYmFscy5oTWVudUZyYW1lID0gMDsKCQkJR2xvYmFscy5oTWVudVZpZXcgPSAwOwoJCQlHbG9iYWxzLmhNZW51T3B0aW9ucyA9IDA7CgkJCUdsb2JhbHMuaE1haW5XbmQgPSAwOwoJCQlHbG9iYWxzLmhtZGljbGllbnQgPSAwOwoJCQlHbG9iYWxzLmhkcml2ZWJhciA9IDA7CgkJCWJyZWFrOwoKCQljYXNlIFdNX0RFU1RST1k6CgkJCVBvc3RRdWl0TWVzc2FnZSgwKTsKCQkJYnJlYWs7CgoJCWNhc2UgV01fSU5JVE1FTlVQT1BVUDogewoJCQlIV05EIGh3bmRDbGllbnQgPSAoSFdORCkgU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElHRVRBQ1RJVkUsIDAsIDApOwoKCQkJaWYgKCFTZW5kTWVzc2FnZShod25kQ2xpZW50LCBXTV9JTklUTUVOVVBPUFVQLCB3cGFyYW0sIGxwYXJhbSkpCgkJCQlyZXR1cm4gMDsKCQkJYnJlYWs7fQoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJVUlOVCBjbWQgPSBMT1dPUkQod3BhcmFtKTsKCQkJSFdORCBod25kQ2xpZW50ID0gKEhXTkQpIFNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJR0VUQUNUSVZFLCAwLCAwKTsKCgkJCWlmIChTZW5kTWVzc2FnZShod25kQ2xpZW50LCBXTV9ESVNQQVRDSF9DT01NQU5ELCB3cGFyYW0sIGxwYXJhbSkpCgkJCQlicmVhazsKCgkJCWlmIChjbWQ+PUlEX0RSSVZFX0ZJUlNUICYmIGNtZDw9SURfRFJJVkVfRklSU1QrMHhGRikgewoJCQkJVENIQVIgZHJ2W19NQVhfRFJJVkVdLCBwYXRoW01BWF9QQVRIXTsKCQkJCUNoaWxkV25kKiBjaGlsZDsKCQkJCUxQQ1RTVFIgcm9vdCA9IEdsb2JhbHMuZHJpdmVzOwoJCQkJaW50IGk7CgoJCQkJZm9yKGk9Y21kLUlEX0RSSVZFX0ZJUlNUOyBpLS07IHJvb3QrKykKCQkJCQl3aGlsZSgqcm9vdCkKCQkJCQkJcm9vdCsrOwoKCQkJCWlmIChhY3RpdmF0ZV9kcml2ZV93aW5kb3cocm9vdCkpCgkJCQkJcmV0dXJuIDA7CgoJCQkJX3RzcGxpdHBhdGgocm9vdCwgZHJ2LCAwLCAwLCAwKTsKCgkJCQlpZiAoIVNldEN1cnJlbnREaXJlY3RvcnkoZHJ2KSkgewoJCQkJCWRpc3BsYXlfZXJyb3IoaHduZCwgR2V0TGFzdEVycm9yKCkpOwoJCQkJCXJldHVybiAwOwoJCQkJfQoKCQkJCUdldEN1cnJlbnREaXJlY3RvcnkoTUFYX1BBVEgsIHBhdGgpOyAvKlRPRE86IHN0b3JlIGxhc3QgZGlyZWN0b3J5IHBlciBkcml2ZSAqLwoJCQkJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgTlVMTCwgaHduZCk7CgoJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQkJCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBjaGlsZCk7CgkJCX0gZWxzZSBzd2l0Y2goY21kKSB7CgkJCQljYXNlIElEX0ZJTEVfRVhJVDoKCQkJCQlTZW5kTWVzc2FnZShod25kLCBXTV9DTE9TRSwgMCwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9XSU5ET1dfTkVXOiB7CgkJCQkJVENIQVIgcGF0aFtNQVhfUEFUSF07CgkJCQkJQ2hpbGRXbmQqIGNoaWxkOwoKCQkJCQlHZXRDdXJyZW50RGlyZWN0b3J5KE1BWF9QQVRILCBwYXRoKTsKCQkJCQljaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhwYXRoLCBOVUxMLCBod25kKTsKCgkJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQkJCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2hpbGQpOwoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX1JFRlJFU0g6CgkJCQkJcmVmcmVzaF9kcml2ZXMoKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1dJTkRPV19DQVNDQURFOgoJCQkJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJQ0FTQ0FERSwgMCwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9XSU5ET1dfVElMRV9IT1JaOgoJCQkJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJVElMRSwgTURJVElMRV9IT1JJWk9OVEFMLCAwKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1dJTkRPV19USUxFX1ZFUlQ6CgkJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElUSUxFLCBNRElUSUxFX1ZFUlRJQ0FMLCAwKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1dJTkRPV19BUlJBTkdFOgoJCQkJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJSUNPTkFSUkFOR0UsIDAsIDApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfU0VMRUNUX0ZPTlQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaG9vc2VfZm9udChod25kKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19UT09MX0JBUjoKCQkJCQl0b2dnbGVfY2hpbGQoaHduZCwgY21kLCBHbG9iYWxzLmh0b29sYmFyKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1ZJRVdfRFJJVkVfQkFSOgoJCQkJCXRvZ2dsZV9jaGlsZChod25kLCBjbWQsIEdsb2JhbHMuaGRyaXZlYmFyKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1ZJRVdfU1RBVFVTQkFSOgoJCQkJCXRvZ2dsZV9jaGlsZChod25kLCBjbWQsIEdsb2JhbHMuaHN0YXR1c2Jhcik7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9WSUVXX1NBVkVTRVRUSU5HUzoKCQkJCQlHbG9iYWxzLnNhdmVTZXR0aW5ncyA9ICFHbG9iYWxzLnNhdmVTZXR0aW5nczsKCQkJCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBJRF9WSUVXX1NBVkVTRVRUSU5HUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2xvYmFscy5zYXZlU2V0dGluZ3MgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEICk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9FWEVDVVRFOiB7CgkJCQkJc3RydWN0IEV4ZWN1dGVEaWFsb2cgZGxnOwoKCQkJCQltZW1zZXQoJmRsZywgMCwgc2l6ZW9mKHN0cnVjdCBFeGVjdXRlRGlhbG9nKSk7CgoJCQkJCWlmIChEaWFsb2dCb3hQYXJhbShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElERF9FWEVDVVRFKSwgaHduZCwgRXhlY3V0ZURpYWxvZ0RsZ1Byb2MsIChMUEFSQU0pJmRsZykgPT0gSURPSykgewoJCQkJCQlISU5TVEFOQ0UgaGluc3QgPSBTaGVsbEV4ZWN1dGUoaHduZCwgTlVMTC8qb3BlcmF0aW9uKi8sIGRsZy5jbWQvKmZpbGUqLywgTlVMTC8qcGFyYW1ldGVycyovLCBOVUxMLypkaXIqLywgZGxnLmNtZHNob3cpOwoKCQkJCQkJaWYgKChpbnQpaGluc3QgPD0gMzIpCgkJCQkJCQlkaXNwbGF5X2Vycm9yKGh3bmQsIEdldExhc3RFcnJvcigpKTsKCQkJCQl9CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfQ09OTkVDVF9ORVRXT1JLX0RSSVZFOiB7CgkJCQkJRFdPUkQgcmV0ID0gV05ldENvbm5lY3Rpb25EaWFsb2coaHduZCwgUkVTT1VSQ0VUWVBFX0RJU0spOwoJCQkJCWlmIChyZXQgPT0gTk9fRVJST1IpCgkJCQkJCXJlZnJlc2hfZHJpdmVzKCk7CgkJCQkJZWxzZSBpZiAocmV0ICE9IChEV09SRCktMSkgewoJCQkJCQlpZiAocmV0ID09IEVSUk9SX0VYVEVOREVEX0VSUk9SKQoJCQkJCQkJZGlzcGxheV9uZXR3b3JrX2Vycm9yKGh3bmQpOwoJCQkJCQllbHNlCgkJCQkJCQlkaXNwbGF5X2Vycm9yKGh3bmQsIHJldCk7CgkJCQkJfQoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX0RJU0NPTk5FQ1RfTkVUV09SS19EUklWRTogewoJCQkJCURXT1JEIHJldCA9IFdOZXREaXNjb25uZWN0RGlhbG9nKGh3bmQsIFJFU09VUkNFVFlQRV9ESVNLKTsKCQkJCQlpZiAocmV0ID09IE5PX0VSUk9SKQoJCQkJCQlyZWZyZXNoX2RyaXZlcygpOwoJCQkJCWVsc2UgaWYgKHJldCAhPSAoRFdPUkQpLTEpIHsKCQkJCQkJaWYgKHJldCA9PSBFUlJPUl9FWFRFTkRFRF9FUlJPUikKCQkJCQkJCWRpc3BsYXlfbmV0d29ya19lcnJvcihod25kKTsKCQkJCQkJZWxzZQoJCQkJCQkJZGlzcGxheV9lcnJvcihod25kLCByZXQpOwoJCQkJCX0KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9GT1JNQVRfRElTSzogewoJCQkJCVVJTlQgc2VtX29yZyA9IFNldEVycm9yTW9kZSgwKTsgLyogR2V0IHRoZSBjdXJyZW50IEVycm9yIE1vZGUgc2V0dGluZ3MuICovCgkJCQkJU2V0RXJyb3JNb2RlKHNlbV9vcmcgJiB+U0VNX0ZBSUxDUklUSUNBTEVSUk9SUyk7IC8qIEZvcmNlIE8vUyB0byBoYW5kbGUgKi8KCQkJCQlTSEZvcm1hdERyaXZlKGh3bmQsIDAgLyogQTogKi8sIFNIRk1UX0lEX0RFRkFVTFQsIDApOwoJCQkJCVNldEVycm9yTW9kZShzZW1fb3JnKTsgLyogUHV0IGl0IGJhY2sgdGhlIHdheSBpdCB3YXMuICovCgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfSEVMUDoKCQkJCQlXaW5IZWxwKGh3bmQsIFJTKGIxLElEU19XSU5FRklMRSksIEhFTFBfSU5ERVgsIDApOwoJCQkJCWJyZWFrOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJY2FzZSBJRF9WSUVXX0ZVTExTQ1JFRU46CgkJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgY21kLCB0b2dnbGVfZnVsbHNjcmVlbihod25kKT9NRl9DSEVDS0VEOjApOwoJCQkJCWJyZWFrOwoKI2lmZGVmIF9fV0lORV9fCgkJCQljYXNlIElEX0RSSVZFX1VOSVhfRlM6IHsKCQkJCQlUQ0hBUiBwYXRoW01BWF9QQVRIXTsKI2lmZGVmIFVOSUNPREUKCQkJCQljaGFyIGNwYXRoW01BWF9QQVRIXTsKI2VuZGlmCgkJCQkJQ2hpbGRXbmQqIGNoaWxkOwoKCQkJCQlpZiAoYWN0aXZhdGVfZnNfd2luZG93KFJTKGIxLElEU19VTklYRlMpKSkKCQkJCQkJYnJlYWs7CgojaWZkZWYgVU5JQ09ERQoJCQkJCWdldGN3ZChjcGF0aCwgTUFYX1BBVEgpOwoJCQkJCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfVU5JWENQLCAwLCBjcGF0aCwgLTEsIHBhdGgsIE1BWF9QQVRIKTsKI2Vsc2UKCQkJCQlnZXRjd2QocGF0aCwgTUFYX1BBVEgpOwojZW5kaWYKCQkJCQljaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhwYXRoLCBOVUxMLCBod25kKTsKCgkJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQkJCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2hpbGQpOwoJCQkJCWJyZWFrO30KI2VuZGlmCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJCQkJY2FzZSBJRF9EUklWRV9TSEVMTF9OUzogewoJCQkJCVRDSEFSIHBhdGhbTUFYX1BBVEhdOwoJCQkJCUNoaWxkV25kKiBjaGlsZDsKCgkJCQkJaWYgKGFjdGl2YXRlX2ZzX3dpbmRvdyhSUyhiMSxJRFNfU0hFTEwpKSkKCQkJCQkJYnJlYWs7CgoJCQkJCUdldEN1cnJlbnREaXJlY3RvcnkoTUFYX1BBVEgsIHBhdGgpOwoJCQkJCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIGdldF9wYXRoX3BpZGwocGF0aCxod25kKSwgaHduZCk7CgoJCQkJCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhjaGlsZCkpCgkJCQkJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGNoaWxkKTsKCQkJCQlicmVhazt9CiNlbmRpZgojZW5kaWYKCgkJCQkvKlRPRE86IFRoZXJlIGFyZSBldmVuIG1vcmUgbWVudSBpdGVtcyEgKi8KCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKI2lmZGVmIF9fV0lORV9fCgkJCQljYXNlIElEX0xJQ0VOU0U6CgkJCQkJV2luZUxpY2Vuc2UoR2xvYmFscy5oTWFpblduZCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9OT19XQVJSQU5UWToKCQkJCQlXaW5lV2FycmFudHkoR2xvYmFscy5oTWFpblduZCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9BQk9VVF9XSU5FOgoJCQkJCVNoZWxsQWJvdXQoaHduZCwgUlMoYjIsSURTX1dJTkUpLCBSUyhiMSxJRFNfV0lORUZJTEUpLCAwKTsKCQkJCQlicmVhazsKI2VuZGlmCgoJCQkJY2FzZSBJRF9BQk9VVDoKCQkJCQlTaGVsbEFib3V0KGh3bmQsIFJTKGIxLElEU19XSU5FRklMRSksIE5VTEwsIDApOwoJCQkJCWJyZWFrOwojZW5kaWYJLyogX05PX0VYVEVOU0lPTlMgKi8KCgkJCQlkZWZhdWx0OgoJCQkJCS8qVE9ETzogaWYgKHdQYXJhbSA+PSBQTV9GSVJTVF9MQU5HVUFHRSAmJiB3UGFyYW0gPD0gUE1fTEFTVF9MQU5HVUFHRSkKCQkJCQkJU1RSSU5HX1NlbGVjdExhbmd1YWdlQnlOdW1iZXIod1BhcmFtIC0gUE1fRklSU1RfTEFOR1VBR0UpOwoJCQkJCWVsc2UgKi9pZiAoKGNtZDxJRFdfRklSU1RfQ0hJTEQgfHwgY21kPj1JRFdfRklSU1RfQ0hJTEQrMHgxMDApICYmCgkJCQkJCShjbWQ8U0NfU0laRSB8fCBjbWQ+U0NfUkVTVE9SRSkpCgkJCQkJCU1lc3NhZ2VCb3goaHduZCwgUlMoYjIsSURTX05PX0lNUEwpLCBSUyhiMSxJRFNfV0lORUZJTEUpLCBNQl9PSyk7CgoJCQkJCXJldHVybiBEZWZGcmFtZVByb2MoaHduZCwgR2xvYmFscy5obWRpY2xpZW50LCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7CgkJCX0KCQkJYnJlYWs7fQoKCQljYXNlIFdNX1NJWkU6CgkJCXJlc2l6ZV9mcmFtZShod25kLCBMT1dPUkQobHBhcmFtKSwgSElXT1JEKGxwYXJhbSkpOwoJCQlicmVhazsJLyogZG8gbm90IHBhc3MgbWVzc2FnZSB0byBEZWZGcmFtZVByb2MgKi8KCgkJY2FzZSBXTV9ERVZJQ0VDSEFOR0U6CgkJCVNlbmRNZXNzYWdlKGh3bmQsIFdNX0NPTU1BTkQsIE1BS0VMT05HKElEX1JFRlJFU0gsMCksIDApOwoJCQlicmVhazsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQljYXNlIFdNX0dFVE1JTk1BWElORk86IHsKCQkJTFBNSU5NQVhJTkZPIGxwbW1pID0gKExQTUlOTUFYSU5GTylscGFyYW07CgoJCQlscG1taS0+cHRNYXhUcmFja1NpemUueCA8PD0gMTsvKjIqR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTikgLyBTTV9DWFZJUlRVQUxTQ1JFRU4gKi8KCQkJbHBtbWktPnB0TWF4VHJhY2tTaXplLnkgPDw9IDE7LyoyKkdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pIC8gU01fQ1lWSVJUVUFMU0NSRUVOICovCgkJCWJyZWFrO30KCgkJY2FzZSBGUk1fQ0FMQ19DTElFTlQ6CgkJCWZyYW1lX2dldF9jbGllbnRzcGFjZShod25kLCAoUFJFQ1QpbHBhcmFtKTsKCQkJcmV0dXJuIFRSVUU7CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCQlkZWZhdWx0OgoJCQlyZXR1cm4gRGVmRnJhbWVQcm9jKGh3bmQsIEdsb2JhbHMuaG1kaWNsaWVudCwgbm1zZywgd3BhcmFtLCBscGFyYW0pOwoJfQoKCXJldHVybiAwOwp9CgoKc3RhdGljIFRDSEFSIGdfcG9zX25hbWVzW0NPTFVNTlNdWzIwXSA9IHsKCXsnXDAnfQkvKiBzeW1ib2wgKi8KfTsKCnN0YXRpYyBjb25zdCBpbnQgZ19wb3NfYWxpZ25bXSA9IHsKCTAsCglIREZfTEVGVCwJLyogTmFtZSAqLwoJSERGX1JJR0hULAkvKiBTaXplICovCglIREZfTEVGVCwJLyogQ0RhdGUgKi8KI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJSERGX0xFRlQsCS8qIEFEYXRlICovCglIREZfTEVGVCwJLyogTURhdGUgKi8KCUhERl9MRUZULAkvKiBJbmRleCAqLwoJSERGX0NFTlRFUiwJLyogTGlua3MgKi8KI2VuZGlmCglIREZfQ0VOVEVSLAkvKiBBdHRyaWJ1dGVzICovCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCUhERl9MRUZUCS8qIFNlY3VyaXR5ICovCiNlbmRpZgp9OwoKc3RhdGljIHZvaWQgcmVzaXplX3RyZWUoQ2hpbGRXbmQqIGNoaWxkLCBpbnQgY3gsIGludCBjeSkKewoJSERXUCBoZHdwID0gQmVnaW5EZWZlcldpbmRvd1Bvcyg0KTsKCVJFQ1QgcnQ7CgoJcnQubGVmdCAgID0gMDsKCXJ0LnRvcCAgICA9IDA7CglydC5yaWdodCAgPSBjeDsKCXJ0LmJvdHRvbSA9IGN5OwoKCWN4ID0gY2hpbGQtPnNwbGl0X3BvcyArIFNQTElUX1dJRFRILzI7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgl7CgkJV0lORE9XUE9TIHdwOwoJCUhEX0xBWU9VVCBoZGw7CgoJCWhkbC5wcmMgICA9ICZydDsKCQloZGwucHdwb3MgPSAmd3A7CgoJCVNlbmRNZXNzYWdlKGNoaWxkLT5sZWZ0Lmh3bmRIZWFkZXIsIEhETV9MQVlPVVQsIDAsIChMUEFSQU0pJmhkbCk7CgoJCURlZmVyV2luZG93UG9zKGhkd3AsIGNoaWxkLT5sZWZ0Lmh3bmRIZWFkZXIsIHdwLmh3bmRJbnNlcnRBZnRlciwKCQkJCQkJd3AueC0xLCB3cC55LCBjaGlsZC0+c3BsaXRfcG9zLVNQTElUX1dJRFRILzIrMSwgd3AuY3ksIHdwLmZsYWdzKTsKCQlEZWZlcldpbmRvd1BvcyhoZHdwLCBjaGlsZC0+cmlnaHQuaHduZEhlYWRlciwgd3AuaHduZEluc2VydEFmdGVyLAoJCQkJCQlydC5sZWZ0K2N4KzEsIHdwLnksIHdwLmN4LWN4KzIsIHdwLmN5LCB3cC5mbGFncyk7Cgl9CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCURlZmVyV2luZG93UG9zKGhkd3AsIGNoaWxkLT5sZWZ0Lmh3bmQsIDAsIHJ0LmxlZnQsIHJ0LnRvcCwgY2hpbGQtPnNwbGl0X3Bvcy1TUExJVF9XSURUSC8yLXJ0LmxlZnQsIHJ0LmJvdHRvbS1ydC50b3AsIFNXUF9OT1pPUkRFUnxTV1BfTk9BQ1RJVkFURSk7CglEZWZlcldpbmRvd1BvcyhoZHdwLCBjaGlsZC0+cmlnaHQuaHduZCwgMCwgcnQubGVmdCtjeCsxLCBydC50b3AsIHJ0LnJpZ2h0LWN4LCBydC5ib3R0b20tcnQudG9wLCBTV1BfTk9aT1JERVJ8U1dQX05PQUNUSVZBVEUpOwoKCUVuZERlZmVyV2luZG93UG9zKGhkd3ApOwp9CgoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoKc3RhdGljIEhXTkQgY3JlYXRlX2hlYWRlcihIV05EIHBhcmVudCwgUGFuZSogcGFuZSwgaW50IGlkKQp7CglIRF9JVEVNIGhkaTsKCWludCBpZHg7CgoJSFdORCBod25kID0gQ3JlYXRlV2luZG93KFdDX0hFQURFUiwgMCwgV1NfQ0hJTER8V1NfVklTSUJMRXxIRFNfSE9SWnxIRFNfRlVMTERSQUcvKlRPRE86IHxIRFNfQlVUVE9OUyArIHNvcnQgb3JkZXJzKi8sCgkJCQkJCQkJMCwgMCwgMCwgMCwgcGFyZW50LCAoSE1FTlUpaWQsIEdsb2JhbHMuaEluc3RhbmNlLCAwKTsKCWlmICghaHduZCkKCQlyZXR1cm4gMDsKCglTZW5kTWVzc2FnZShod25kLCBXTV9TRVRGT05ULCAoV1BBUkFNKUdldFN0b2NrT2JqZWN0KERFRkFVTFRfR1VJX0ZPTlQpLCBGQUxTRSk7CgoJaGRpLm1hc2sgPSBIRElfVEVYVHxIRElfV0lEVEh8SERJX0ZPUk1BVDsKCglmb3IoaWR4PTA7IGlkeDxDT0xVTU5TOyBpZHgrKykgewoJCWhkaS5wc3pUZXh0ID0gZ19wb3NfbmFtZXNbaWR4XTsKCQloZGkuZm10ID0gSERGX1NUUklORyB8IGdfcG9zX2FsaWduW2lkeF07CgkJaGRpLmN4eSA9IHBhbmUtPndpZHRoc1tpZHhdOwoJCVNlbmRNZXNzYWdlKGh3bmQsIEhETV9JTlNFUlRJVEVNLCBpZHgsIChMUEFSQU0pICZoZGkpOwoJfQoKCXJldHVybiBod25kOwp9CgojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgpzdGF0aWMgdm9pZCBpbml0X291dHB1dChIV05EIGh3bmQpCnsKCXN0YXRpYyBjb25zdCBXQ0hBUiBzMTAwMFtdID0geycxJywnMCcsJzAnLCcwJywnXDAnfTsKCVdDSEFSIGJbMTZdOwoJSEZPTlQgb2xkX2ZvbnQ7CglIREMgaGRjID0gR2V0REMoaHduZCk7CgoJaWYgKEdldE51bWJlckZvcm1hdFcoTE9DQUxFX1VTRVJfREVGQVVMVCwgMCwgczEwMDAsIDAsIGIsIDE2KSA+IDQpCgkJR2xvYmFscy5udW1fc2VwID0gYlsxXTsKCWVsc2UKCQlHbG9iYWxzLm51bV9zZXAgPSAnLic7CgoJb2xkX2ZvbnQgPSBTZWxlY3RPYmplY3QoaGRjLCBHbG9iYWxzLmhmb250KTsKCUdldFRleHRFeHRlbnRQb2ludDMyVyhoZGMsIHNTcGFjZSwgMSwgJkdsb2JhbHMuc3BhY2VTaXplKTsKCVNlbGVjdE9iamVjdChoZGMsIG9sZF9mb250KTsKCVJlbGVhc2VEQyhod25kLCBoZGMpOwp9CgpzdGF0aWMgdm9pZCBkcmF3X2l0ZW0oUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIEVudHJ5KiBlbnRyeSwgaW50IGNhbGNXaWR0aENvbCk7CgoKLyogY2FsY3VsYXRlIHByZWZlcnJlZCB3aWR0aCBmb3IgYWxsIHZpc2libGUgY29sdW1ucyAqLwoKc3RhdGljIEJPT0wgY2FsY193aWR0aHMoUGFuZSogcGFuZSwgQk9PTCBhbnl3YXkpCnsKCWludCBjb2wsIHgsIGN4LCBzcGM9MypHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCWludCBlbnRyaWVzID0gU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfR0VUQ09VTlQsIDAsIDApOwoJaW50IG9yZ1dpZHRoc1tDT0xVTU5TXTsKCWludCBvcmdQb3NpdGlvbnNbQ09MVU1OUysxXTsKCUhGT05UIGhmb250T2xkOwoJSERDIGhkYzsKCWludCBjbnQ7CgoJaWYgKCFhbnl3YXkpIHsKCQltZW1jcHkob3JnV2lkdGhzLCBwYW5lLT53aWR0aHMsIHNpemVvZihvcmdXaWR0aHMpKTsKCQltZW1jcHkob3JnUG9zaXRpb25zLCBwYW5lLT5wb3NpdGlvbnMsIHNpemVvZihvcmdQb3NpdGlvbnMpKTsKCX0KCglmb3IoY29sPTA7IGNvbDxDT0xVTU5TOyBjb2wrKykKCQlwYW5lLT53aWR0aHNbY29sXSA9IDA7CgoJaGRjID0gR2V0REMocGFuZS0+aHduZCk7CgloZm9udE9sZCA9IFNlbGVjdE9iamVjdChoZGMsIEdsb2JhbHMuaGZvbnQpOwoKCWZvcihjbnQ9MDsgY250PGVudHJpZXM7IGNudCsrKSB7CgkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfR0VUSVRFTURBVEEsIGNudCwgMCk7CgoJCURSQVdJVEVNU1RSVUNUIGRpczsKCgkJZGlzLkN0bFR5cGUJCSAgPSAwOwoJCWRpcy5DdGxJRAkJICA9IDA7CgkJZGlzLml0ZW1JRAkJICA9IDA7CgkJZGlzLml0ZW1BY3Rpb24JICA9IDA7CgkJZGlzLml0ZW1TdGF0ZQkgID0gMDsKCQlkaXMuaHduZEl0ZW0JICA9IHBhbmUtPmh3bmQ7CgkJZGlzLmhEQwkJCSAgPSBoZGM7CgkJZGlzLnJjSXRlbS5sZWZ0CSAgPSAwOwoJCWRpcy5yY0l0ZW0udG9wICAgID0gMDsKCQlkaXMucmNJdGVtLnJpZ2h0ICA9IDA7CgkJZGlzLnJjSXRlbS5ib3R0b20gPSAwOwoJCS8qZGlzLml0ZW1EYXRhCSAgPSAwOyAqLwoKCQlkcmF3X2l0ZW0ocGFuZSwgJmRpcywgZW50cnksIENPTFVNTlMpOwoJfQoKCVNlbGVjdE9iamVjdChoZGMsIGhmb250T2xkKTsKCVJlbGVhc2VEQyhwYW5lLT5od25kLCBoZGMpOwoKCXggPSAwOwoJZm9yKGNvbD0wOyBjb2w8Q09MVU1OUzsgY29sKyspIHsKCQlwYW5lLT5wb3NpdGlvbnNbY29sXSA9IHg7CgkJY3ggPSBwYW5lLT53aWR0aHNbY29sXTsKCgkJaWYgKGN4KSB7CgkJCWN4ICs9IHNwYzsKCgkJCWlmIChjeCA8IElNQUdFX1dJRFRIKQoJCQkJY3ggPSBJTUFHRV9XSURUSDsKCgkJCXBhbmUtPndpZHRoc1tjb2xdID0gY3g7CgkJfQoKCQl4ICs9IGN4OwoJfQoKCXBhbmUtPnBvc2l0aW9uc1tDT0xVTU5TXSA9IHg7CgoJU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfU0VUSE9SSVpPTlRBTEVYVEVOVCwgeCwgMCk7CgoJLyogbm8gY2hhbmdlPyAqLwoJaWYgKCFtZW1jbXAob3JnV2lkdGhzLCBwYW5lLT53aWR0aHMsIHNpemVvZihvcmdXaWR0aHMpKSkKCQlyZXR1cm4gRkFMU0U7CgoJLyogZG9uJ3QgbW92ZSwgaWYgb25seSBjb2xsYXBzaW5nIGFuIGVudHJ5ICovCglpZiAoIWFueXdheSAmJiBwYW5lLT53aWR0aHNbMF08b3JnV2lkdGhzWzBdICYmCgkJIW1lbWNtcChvcmdXaWR0aHMrMSwgcGFuZS0+d2lkdGhzKzEsIHNpemVvZihvcmdXaWR0aHMpLXNpemVvZihpbnQpKSkgewoJCXBhbmUtPndpZHRoc1swXSA9IG9yZ1dpZHRoc1swXTsKCQltZW1jcHkocGFuZS0+cG9zaXRpb25zLCBvcmdQb3NpdGlvbnMsIHNpemVvZihvcmdQb3NpdGlvbnMpKTsKCgkJcmV0dXJuIEZBTFNFOwoJfQoKCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoKCXJldHVybiBUUlVFOwp9CgoKLyogY2FsY3VsYXRlIG9uZSBwcmVmZXJyZWQgY29sdW1uIHdpZHRoICovCgpzdGF0aWMgdm9pZCBjYWxjX3NpbmdsZV93aWR0aChQYW5lKiBwYW5lLCBpbnQgY29sKQp7CglIRk9OVCBoZm9udE9sZDsKCWludCB4LCBjeDsKCWludCBlbnRyaWVzID0gU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfR0VUQ09VTlQsIDAsIDApOwoJaW50IGNudDsKCUhEQyBoZGM7CgoJcGFuZS0+d2lkdGhzW2NvbF0gPSAwOwoKCWhkYyA9IEdldERDKHBhbmUtPmh3bmQpOwoJaGZvbnRPbGQgPSBTZWxlY3RPYmplY3QoaGRjLCBHbG9iYWxzLmhmb250KTsKCglmb3IoY250PTA7IGNudDxlbnRyaWVzOyBjbnQrKykgewoJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIFNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX0dFVElURU1EQVRBLCBjbnQsIDApOwoJCURSQVdJVEVNU1RSVUNUIGRpczsKCgkJZGlzLkN0bFR5cGUJCSAgPSAwOwoJCWRpcy5DdGxJRAkJICA9IDA7CgkJZGlzLml0ZW1JRAkJICA9IDA7CgkJZGlzLml0ZW1BY3Rpb24JICA9IDA7CgkJZGlzLml0ZW1TdGF0ZQkgID0gMDsKCQlkaXMuaHduZEl0ZW0JICA9IHBhbmUtPmh3bmQ7CgkJZGlzLmhEQwkJCSAgPSBoZGM7CgkJZGlzLnJjSXRlbS5sZWZ0CSAgPSAwOwoJCWRpcy5yY0l0ZW0udG9wICAgID0gMDsKCQlkaXMucmNJdGVtLnJpZ2h0ICA9IDA7CgkJZGlzLnJjSXRlbS5ib3R0b20gPSAwOwoJCS8qZGlzLml0ZW1EYXRhCSAgPSAwOyAqLwoKCQlkcmF3X2l0ZW0ocGFuZSwgJmRpcywgZW50cnksIGNvbCk7Cgl9CgoJU2VsZWN0T2JqZWN0KGhkYywgaGZvbnRPbGQpOwoJUmVsZWFzZURDKHBhbmUtPmh3bmQsIGhkYyk7CgoJY3ggPSBwYW5lLT53aWR0aHNbY29sXTsKCglpZiAoY3gpIHsKCQljeCArPSAzKkdsb2JhbHMuc3BhY2VTaXplLmN4OwoKCQlpZiAoY3ggPCBJTUFHRV9XSURUSCkKCQkJY3ggPSBJTUFHRV9XSURUSDsKCX0KCglwYW5lLT53aWR0aHNbY29sXSA9IGN4OwoKCXggPSBwYW5lLT5wb3NpdGlvbnNbY29sXSArIGN4OwoKCWZvcig7IGNvbDxDT0xVTU5TOyApIHsKCQlwYW5lLT5wb3NpdGlvbnNbKytjb2xdID0geDsKCQl4ICs9IHBhbmUtPndpZHRoc1tjb2xdOwoJfQoKCVNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX1NFVEhPUklaT05UQUxFWFRFTlQsIHgsIDApOwp9CgoKc3RhdGljIEJPT0wgcGF0dGVybl9tYXRjaChMUENUU1RSIHN0ciwgTFBDVFNUUiBwYXR0ZXJuKQp7Cglmb3IoIDsgKnN0ciYmKnBhdHRlcm47IHN0cisrLHBhdHRlcm4rKykgewoJCWlmICgqcGF0dGVybiA9PSAnKicpIHsKCQkJZG8gcGF0dGVybisrOwoJCQl3aGlsZSgqcGF0dGVybiA9PSAnKicpOwoKCQkJaWYgKCEqcGF0dGVybikKCQkJCXJldHVybiBUUlVFOwoKCQkJZm9yKDsgKnN0cjsgc3RyKyspCgkJCQlpZiAoKnN0cj09KnBhdHRlcm4gJiYgcGF0dGVybl9tYXRjaChzdHIsIHBhdHRlcm4pKQoJCQkJCXJldHVybiBUUlVFOwoKCQkJcmV0dXJuIEZBTFNFOwoJCX0KCQllbHNlIGlmICgqc3RyIT0qcGF0dGVybiAmJiAqcGF0dGVybiE9Jz8nKQoJCQlyZXR1cm4gRkFMU0U7Cgl9CgoJaWYgKCpzdHIgfHwgKnBhdHRlcm4pCgkJaWYgKCpwYXR0ZXJuIT0nKicgfHwgcGF0dGVyblsxXSE9J1wwJykKCQkJcmV0dXJuIEZBTFNFOwoKCXJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBwYXR0ZXJuX2ltYXRjaChMUENUU1RSIHN0ciwgTFBDVFNUUiBwYXR0ZXJuKQp7CglUQ0hBUiBiMVtCVUZGRVJfTEVOXSwgYjJbQlVGRkVSX0xFTl07CgoJbHN0cmNweShiMSwgc3RyKTsKCWxzdHJjcHkoYjIsIHBhdHRlcm4pOwoJQ2hhclVwcGVyKGIxKTsKCUNoYXJVcHBlcihiMik7CgoJcmV0dXJuIHBhdHRlcm5fbWF0Y2goYjEsIGIyKTsKfQoKCmVudW0gRklMRV9UWVBFIHsKCUZUX09USEVSCQk9IDAsCglGVF9FWEVDVVRBQkxFCT0gMSwKCUZUX0RPQ1VNRU5UCQk9IDIKfTsKCnN0YXRpYyBlbnVtIEZJTEVfVFlQRSBnZXRfZmlsZV90eXBlKExQQ1RTVFIgZmlsZW5hbWUpOwoKCi8qIGluc2VydCBsaXN0Ym94IGVudHJpZXMgYWZ0ZXIgaW5kZXggaWR4ICovCgpzdGF0aWMgaW50IGluc2VydF9lbnRyaWVzKFBhbmUqIHBhbmUsIEVudHJ5KiBkaXIsIExQQ1RTVFIgcGF0dGVybiwgaW50IGZpbHRlcl9mbGFncywgaW50IGlkeCkKewoJRW50cnkqIGVudHJ5ID0gZGlyOwoKCWlmICghZW50cnkpCgkJcmV0dXJuIGlkeDsKCglTaG93V2luZG93KHBhbmUtPmh3bmQsIFNXX0hJREUpOwoKCWZvcig7IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkgewojaWZuZGVmIF9MRUZUX0ZJTEVTCgkJaWYgKHBhbmUtPnRyZWVQYW5lICYmICEoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpKQoJCQljb250aW51ZTsKI2VuZGlmCgoJCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCS8qIGRvbid0IGRpc3BsYXkgZW50cmllcyAiLiIgYW5kICIuLiIgaW4gdGhlIGxlZnQgcGFuZSAqLwoJCQlpZiAocGFuZS0+dHJlZVBhbmUgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdID09ICcuJykKCQkJCWlmICgKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCWVudHJ5LT5kYXRhLmNGaWxlTmFtZVsxXSA9PSAnXDAnIHx8CiNlbmRpZgoJCQkJCShlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMV0gPT0gJy4nICYmIGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsyXSA9PSAnXDAnKSkKCQkJCQljb250aW51ZTsKCgkJCS8qIGZpbHRlciBkaXJlY3RvcmllcyBpbiByaWdodCBwYW5lICovCgkJCWlmICghcGFuZS0+dHJlZVBhbmUgJiYgIShmaWx0ZXJfZmxhZ3MmVEZfRElSRUNUT1JJRVMpKQoJCQkJY29udGludWU7CgkJfQoKCQkvKiBmaWx0ZXIgdXNpbmcgdGhlIGZpbGUgbmFtZSBwYXR0ZXJuICovCgkJaWYgKHBhdHRlcm4pCgkJCWlmICghcGF0dGVybl9pbWF0Y2goZW50cnktPmRhdGEuY0ZpbGVOYW1lLCBwYXR0ZXJuKSkKCQkJCWNvbnRpbnVlOwoKCQkvKiBmaWx0ZXIgc3lzdGVtIGFuZCBoaWRkZW4gZmlsZXMgKi8KCQlpZiAoIShmaWx0ZXJfZmxhZ3MmVEZfSElEREVOKSAmJiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyYoRklMRV9BVFRSSUJVVEVfSElEREVOfEZJTEVfQVRUUklCVVRFX1NZU1RFTSkpKQoJCQljb250aW51ZTsKCgkJLyogZmlsdGVyIGxvb2tpbmcgYXQgdGhlIGZpbGUgdHlwZSAqLwoJCWlmICgoZmlsdGVyX2ZsYWdzJihURl9QUk9HUkFNU3xURl9ET0NVTUVOVFN8VEZfT1RIRVJTKSkgIT0gKFRGX1BST0dSQU1TfFRGX0RPQ1VNRU5UU3xURl9PVEhFUlMpKQoJCQlzd2l0Y2goZ2V0X2ZpbGVfdHlwZShlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpKSB7CgkJCSAgY2FzZSBGVF9FWEVDVVRBQkxFOgoJCQkgIAlpZiAoIShmaWx0ZXJfZmxhZ3MgJiBURl9QUk9HUkFNUykpCgkJCQkJY29udGludWU7CgkJCQlicmVhazsKCgkJCSAgY2FzZSBGVF9ET0NVTUVOVDoKCQkJCWlmICghKGZpbHRlcl9mbGFncyAmIFRGX0RPQ1VNRU5UUykpCgkJCQkJY29udGludWU7CgkJCQlicmVhazsKCgkJCSAgZGVmYXVsdDogLyogVEZfT1RIRVJTICovCgkJCQlpZiAoIShmaWx0ZXJfZmxhZ3MgJiBURl9PVEhFUlMpKQoJCQkJCWNvbnRpbnVlOwoJCQl9CgoJCWlmIChpZHggIT0gLTEpCgkJCWlkeCsrOwoKCQlTZW5kTWVzc2FnZShwYW5lLT5od25kLCBMQl9JTlNFUlRTVFJJTkcsIGlkeCwgKExQQVJBTSkgZW50cnkpOwoKCQlpZiAocGFuZS0+dHJlZVBhbmUgJiYgZW50cnktPmV4cGFuZGVkKQoJCQlpZHggPSBpbnNlcnRfZW50cmllcyhwYW5lLCBlbnRyeS0+ZG93biwgcGF0dGVybiwgZmlsdGVyX2ZsYWdzLCBpZHgpOwoJfQoKCVNob3dXaW5kb3cocGFuZS0+aHduZCwgU1dfU0hPVyk7CgoJcmV0dXJuIGlkeDsKfQoKCnN0YXRpYyB2b2lkIGZvcm1hdF9ieXRlcyhMUFRTVFIgYnVmZmVyLCBMT05HTE9ORyBieXRlcykKewoJc3RhdGljIGNvbnN0IFRDSEFSIHNGbXRHQltdID0geyclJywgJy4nLCAnMScsICdmJywgJyAnLCAnRycsICdCJywgJ1wwJ307CglzdGF0aWMgY29uc3QgVENIQVIgc0ZtdE1CW10gPSB7JyUnLCAnLicsICcxJywgJ2YnLCAnICcsICdNJywgJ0InLCAnXDAnfTsKCXN0YXRpYyBjb25zdCBUQ0hBUiBzRm10a0JbXSA9IHsnJScsICcuJywgJzEnLCAnZicsICcgJywgJ2snLCAnQicsICdcMCd9OwoKCWZsb2F0IGZCeXRlcyA9IChmbG9hdClieXRlczsKCglpZiAoYnl0ZXMgPj0gMTA3Mzc0MTgyNCkJLyogMSBHQiAqLwoJCV9zdHByaW50ZihidWZmZXIsIHNGbXRHQiwgZkJ5dGVzLzEwNzM3NDE4MjQuZisuNWYpOwoJZWxzZSBpZiAoYnl0ZXMgPj0gMTA0ODU3NikJLyogMSBNQiAqLwoJCV9zdHByaW50ZihidWZmZXIsIHNGbXRNQiwgZkJ5dGVzLzEwNDg1NzYuZisuNWYpOwoJZWxzZSBpZiAoYnl0ZXMgPj0gMTAyNCkJCS8qIDEga0IgKi8KCQlfc3RwcmludGYoYnVmZmVyLCBzRm10a0IsIGZCeXRlcy8xMDI0LmYrLjVmKTsKCWVsc2UKCQlfc3RwcmludGYoYnVmZmVyLCBzTG9uZ051bUZtdCwgYnl0ZXMpOwp9CgpzdGF0aWMgdm9pZCBzZXRfc3BhY2Vfc3RhdHVzKHZvaWQpCnsKCVVMQVJHRV9JTlRFR0VSIHVsRnJlZUJ5dGVzVG9DYWxsZXIsIHVsVG90YWxCeXRlcywgdWxGcmVlQnl0ZXM7CglUQ0hBUiBmbXRbNjRdLCBiMVs2NF0sIGIyWzY0XSwgYnVmZmVyW0JVRkZFUl9MRU5dOwoKCWlmIChHZXREaXNrRnJlZVNwYWNlRXgoTlVMTCwgJnVsRnJlZUJ5dGVzVG9DYWxsZXIsICZ1bFRvdGFsQnl0ZXMsICZ1bEZyZWVCeXRlcykpIHsKCQlmb3JtYXRfYnl0ZXMoYjEsIHVsRnJlZUJ5dGVzVG9DYWxsZXIuUXVhZFBhcnQpOwoJCWZvcm1hdF9ieXRlcyhiMiwgdWxUb3RhbEJ5dGVzLlF1YWRQYXJ0KTsKCQl3c3ByaW50ZihidWZmZXIsIFJTKGZtdCxJRFNfRlJFRV9TUEFDRV9GTVQpLCBiMSwgYjIpOwoJfSBlbHNlCgkJbHN0cmNweShidWZmZXIsIHNRTWFya3MpOwoKCVNlbmRNZXNzYWdlKEdsb2JhbHMuaHN0YXR1c2JhciwgU0JfU0VUVEVYVCwgMCwgKExQQVJBTSlidWZmZXIpOwp9CgoKc3RhdGljIFdORFBST0MgZ19vcmdUcmVlV25kUHJvYzsKCnN0YXRpYyB2b2lkIGNyZWF0ZV90cmVlX3dpbmRvdyhIV05EIHBhcmVudCwgUGFuZSogcGFuZSwgaW50IGlkLCBpbnQgaWRfaGVhZGVyLCBMUENUU1RSIHBhdHRlcm4sIGludCBmaWx0ZXJfZmxhZ3MpCnsKCXN0YXRpYyBjb25zdCBUQ0hBUiBzTGlzdEJveFtdID0geydMJywnaScsJ3MnLCd0JywnQicsJ28nLCd4JywnXDAnfTsKCglzdGF0aWMgaW50IHNfaW5pdCA9IDA7CglFbnRyeSogZW50cnkgPSBwYW5lLT5yb290OwoKCXBhbmUtPmh3bmQgPSBDcmVhdGVXaW5kb3coc0xpc3RCb3gsIHNFbXB0eSwgV1NfQ0hJTER8V1NfVklTSUJMRXxXU19IU0NST0xMfFdTX1ZTQ1JPTEx8CgkJCQkJCQkJTEJTX0RJU0FCTEVOT1NDUk9MTHxMQlNfTk9JTlRFR1JBTEhFSUdIVHxMQlNfT1dORVJEUkFXRklYRUR8TEJTX05PVElGWSwKCQkJCQkJCQkwLCAwLCAwLCAwLCBwYXJlbnQsIChITUVOVSlpZCwgR2xvYmFscy5oSW5zdGFuY2UsIDApOwoKCVNldFdpbmRvd0xvbmdQdHIocGFuZS0+aHduZCwgR1dMUF9VU0VSREFUQSwgKExQQVJBTSlwYW5lKTsKCWdfb3JnVHJlZVduZFByb2MgPSAoV05EUFJPQykgU2V0V2luZG93TG9uZ1B0cihwYW5lLT5od25kLCBHV0xQX1dORFBST0MsIChMUEFSQU0pVHJlZVduZFByb2MpOwoKCVNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIFdNX1NFVEZPTlQsIChXUEFSQU0pR2xvYmFscy5oZm9udCwgRkFMU0UpOwoKCS8qIGluc2VydCBlbnRyaWVzIGludG8gbGlzdGJveCAqLwoJaWYgKGVudHJ5KQoJCWluc2VydF9lbnRyaWVzKHBhbmUsIGVudHJ5LCBwYXR0ZXJuLCBmaWx0ZXJfZmxhZ3MsIC0xKTsKCgkvKiBjYWxjdWxhdGUgY29sdW1uIHdpZHRocyAqLwoJaWYgKCFzX2luaXQpIHsKCQlzX2luaXQgPSAxOwoJCWluaXRfb3V0cHV0KHBhbmUtPmh3bmQpOwoJfQoKCWNhbGNfd2lkdGhzKHBhbmUsIFRSVUUpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJcGFuZS0+aHduZEhlYWRlciA9IGNyZWF0ZV9oZWFkZXIocGFyZW50LCBwYW5lLCBpZF9oZWFkZXIpOwojZW5kaWYKfQoKCnN0YXRpYyB2b2lkIEluaXRDaGlsZFdpbmRvdyhDaGlsZFduZCogY2hpbGQpCnsKCWNyZWF0ZV90cmVlX3dpbmRvdyhjaGlsZC0+aHduZCwgJmNoaWxkLT5sZWZ0LCBJRFdfVFJFRV9MRUZULCBJRFdfSEVBREVSX0xFRlQsIE5VTEwsIFRGX0FMTCk7CgljcmVhdGVfdHJlZV93aW5kb3coY2hpbGQtPmh3bmQsICZjaGlsZC0+cmlnaHQsIElEV19UUkVFX1JJR0hULCBJRFdfSEVBREVSX1JJR0hULCBjaGlsZC0+ZmlsdGVyX3BhdHRlcm4sIGNoaWxkLT5maWx0ZXJfZmxhZ3MpOwp9CgoKc3RhdGljIHZvaWQgZm9ybWF0X2RhdGUoY29uc3QgRklMRVRJTUUqIGZ0LCBUQ0hBUiogYnVmZmVyLCBpbnQgdmlzaWJsZV9jb2xzKQp7CglTWVNURU1USU1FIHN5c3RpbWU7CglGSUxFVElNRSBsZnQ7CglpbnQgbGVuID0gMDsKCgkqYnVmZmVyID0gJ1wwJzsKCglpZiAoIWZ0LT5kd0xvd0RhdGVUaW1lICYmICFmdC0+ZHdIaWdoRGF0ZVRpbWUpCgkJcmV0dXJuOwoKCWlmICghRmlsZVRpbWVUb0xvY2FsRmlsZVRpbWUoZnQsICZsZnQpKQoJCXtlcnI6IGxzdHJjcHkoYnVmZmVyLHNRTWFya3MpOyByZXR1cm47fQoKCWlmICghRmlsZVRpbWVUb1N5c3RlbVRpbWUoJmxmdCwgJnN5c3RpbWUpKQoJCWdvdG8gZXJyOwoKCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfREFURSkgewoJCWxlbiA9IEdldERhdGVGb3JtYXQoTE9DQUxFX1VTRVJfREVGQVVMVCwgMCwgJnN5c3RpbWUsIDAsIGJ1ZmZlciwgQlVGRkVSX0xFTik7CgkJaWYgKCFsZW4pCgkJCWdvdG8gZXJyOwoJfQoKCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfVElNRSkgewoJCWlmIChsZW4pCgkJCWJ1ZmZlcltsZW4tMV0gPSAnICc7CgoJCWJ1ZmZlcltsZW4rK10gPSAnICc7CgoJCWlmICghR2V0VGltZUZvcm1hdChMT0NBTEVfVVNFUl9ERUZBVUxULCAwLCAmc3lzdGltZSwgMCwgYnVmZmVyK2xlbiwgQlVGRkVSX0xFTi1sZW4pKQoJCQlidWZmZXJbbGVuXSA9ICdcMCc7Cgl9Cn0KCgpzdGF0aWMgdm9pZCBjYWxjX3dpZHRoKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0cikKewoJUkVDVCBydCA9IHswLCAwLCAwLCAwfTsKCglEcmF3VGV4dChkaXMtPmhEQywgc3RyLCAtMSwgJnJ0LCBEVF9DQUxDUkVDVHxEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYKTsKCglpZiAocnQucmlnaHQgPiBwYW5lLT53aWR0aHNbY29sXSkKCQlwYW5lLT53aWR0aHNbY29sXSA9IHJ0LnJpZ2h0Owp9CgpzdGF0aWMgdm9pZCBjYWxjX3RhYmJlZF93aWR0aChQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgaW50IGNvbCwgTFBDVFNUUiBzdHIpCnsKCVJFQ1QgcnQgPSB7MCwgMCwgMCwgMH07CgovKglEUkFXVEVYVFBBUkFNUyBkdHAgPSB7c2l6ZW9mKERSQVdURVhUUEFSQU1TKSwgMn07CglEcmF3VGV4dEV4KGRpcy0+aERDLCAoTFBUU1RSKXN0ciwgLTEsICZydCwgRFRfQ0FMQ1JFQ1R8RFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWHxEVF9FWFBBTkRUQUJTfERUX1RBQlNUT1AsICZkdHApOyovCgoJRHJhd1RleHQoZGlzLT5oREMsIHN0ciwgLTEsICZydCwgRFRfQ0FMQ1JFQ1R8RFRfU0lOR0xFTElORXxEVF9FWFBBTkRUQUJTfERUX1RBQlNUT1B8KDI8PDgpKTsKCS8qRklYTUUgcnQgKDAsMCkgPz8/ICovCgoJaWYgKHJ0LnJpZ2h0ID4gcGFuZS0+d2lkdGhzW2NvbF0pCgkJcGFuZS0+d2lkdGhzW2NvbF0gPSBydC5yaWdodDsKfQoKCnN0YXRpYyB2b2lkIG91dHB1dF90ZXh0KFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0ciwgRFdPUkQgZmxhZ3MpCnsKCWludCB4ID0gZGlzLT5yY0l0ZW0ubGVmdDsKCVJFQ1QgcnQ7CgoJcnQubGVmdCAgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sXStHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LnRvcCAgICA9IGRpcy0+cmNJdGVtLnRvcDsKCXJ0LnJpZ2h0ICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbCsxXS1HbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LmJvdHRvbSA9IGRpcy0+cmNJdGVtLmJvdHRvbTsKCglEcmF3VGV4dChkaXMtPmhEQywgc3RyLCAtMSwgJnJ0LCBEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYfGZsYWdzKTsKfQoKc3RhdGljIHZvaWQgb3V0cHV0X3RhYmJlZF90ZXh0KFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0cikKewoJaW50IHggPSBkaXMtPnJjSXRlbS5sZWZ0OwoJUkVDVCBydDsKCglydC5sZWZ0ICAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2xdK0dsb2JhbHMuc3BhY2VTaXplLmN4OwoJcnQudG9wICAgID0gZGlzLT5yY0l0ZW0udG9wOwoJcnQucmlnaHQgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sKzFdLUdsb2JhbHMuc3BhY2VTaXplLmN4OwoJcnQuYm90dG9tID0gZGlzLT5yY0l0ZW0uYm90dG9tOwoKLyoJRFJBV1RFWFRQQVJBTVMgZHRwID0ge3NpemVvZihEUkFXVEVYVFBBUkFNUyksIDJ9OwoJRHJhd1RleHRFeChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVh8RFRfRVhQQU5EVEFCU3xEVF9UQUJTVE9QLCAmZHRwKTsqLwoKCURyYXdUZXh0KGRpcy0+aERDLCBzdHIsIC0xLCAmcnQsIERUX1NJTkdMRUxJTkV8RFRfRVhQQU5EVEFCU3xEVF9UQUJTVE9QfCgyPDw4KSk7Cn0KCnN0YXRpYyB2b2lkIG91dHB1dF9udW1iZXIoUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIGludCBjb2wsIExQQ1RTVFIgc3RyKQp7CglpbnQgeCA9IGRpcy0+cmNJdGVtLmxlZnQ7CglSRUNUIHJ0OwoJTFBDVFNUUiBzID0gc3RyOwoJVENIQVIgYlsxMjhdOwoJTFBUU1RSIGQgPSBiOwoJaW50IHBvczsKCglydC5sZWZ0ICAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2xdK0dsb2JhbHMuc3BhY2VTaXplLmN4OwoJcnQudG9wICAgID0gZGlzLT5yY0l0ZW0udG9wOwoJcnQucmlnaHQgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sKzFdLUdsb2JhbHMuc3BhY2VTaXplLmN4OwoJcnQuYm90dG9tID0gZGlzLT5yY0l0ZW0uYm90dG9tOwoKCWlmICgqcykKCQkqZCsrID0gKnMrKzsKCgkvKiBpbnNlcnQgbnVtYmVyIHNlcGFyYXRvciBjaGFyYWN0ZXJzICovCglwb3MgPSBsc3RybGVuKHMpICUgMzsKCgl3aGlsZSgqcykKCQlpZiAocG9zLS0pCgkJCSpkKysgPSAqcysrOwoJCWVsc2UgewoJCQkqZCsrID0gR2xvYmFscy5udW1fc2VwOwoJCQlwb3MgPSAzOwoJCX0KCglEcmF3VGV4dChkaXMtPmhEQywgYiwgZC1iLCAmcnQsIERUX1JJR0hUfERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVh8RFRfRU5EX0VMTElQU0lTKTsKfQoKCnN0YXRpYyBCT09MIGlzX2V4ZV9maWxlKExQQ1RTVFIgZXh0KQp7CglzdGF0aWMgY29uc3QgVENIQVIgZXhlY3V0YWJsZV9leHRlbnNpb25zW11bNF0gPSB7CgkJeydDJywnTycsJ00nLCdcMCd9LAoJCXsnRScsJ1gnLCdFJywnXDAnfSwKCQl7J0InLCdBJywnVCcsJ1wwJ30sCgkJeydDJywnTScsJ0QnLCdcMCd9LAojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJeydDJywnTScsJ00nLCdcMCd9LAoJCXsnQicsJ1QnLCdNJywnXDAnfSwKCQl7J0EnLCdXJywnSycsJ1wwJ30sCiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoJCXsnXDAnfQoJfTsKCglUQ0hBUiBleHRfYnVmZmVyW19NQVhfRVhUXTsKCWNvbnN0IFRDSEFSICgqcClbNF07CglMUENUU1RSIHM7CglMUFRTVFIgZDsKCglmb3Iocz1leHQrMSxkPWV4dF9idWZmZXI7ICgqZD10b2xvd2VyKCpzKSk7IHMrKykKCQlkKys7CgoJZm9yKHA9ZXhlY3V0YWJsZV9leHRlbnNpb25zOyAoKnApWzBdOyBwKyspCgkJaWYgKCFsc3RyY21waShleHRfYnVmZmVyLCAqcCkpCgkJCXJldHVybiBUUlVFOwoKCXJldHVybiBGQUxTRTsKfQoKc3RhdGljIEJPT0wgaXNfcmVnaXN0ZXJlZF90eXBlKExQQ1RTVFIgZXh0KQp7CgkvKiBjaGVjayBpZiB0aGVyZSBleGlzdHMgYSBjbGFzc25hbWUgZm9yIHRoaXMgZmlsZSBleHRlbnNpb24gaW4gdGhlIHJlZ2lzdHJ5ICovCglpZiAoIVJlZ1F1ZXJ5VmFsdWUoSEtFWV9DTEFTU0VTX1JPT1QsIGV4dCwgTlVMTCwgTlVMTCkpCgkJcmV0dXJuIFRSVUU7CgoJcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgZW51bSBGSUxFX1RZUEUgZ2V0X2ZpbGVfdHlwZShMUENUU1RSIGZpbGVuYW1lKQp7CglMUENUU1RSIGV4dCA9IF90Y3NyY2hyKGZpbGVuYW1lLCAnLicpOwoJaWYgKCFleHQpCgkJZXh0ID0gc0VtcHR5OwoKCWlmIChpc19leGVfZmlsZShleHQpKQoJCXJldHVybiBGVF9FWEVDVVRBQkxFOwoJZWxzZSBpZiAoaXNfcmVnaXN0ZXJlZF90eXBlKGV4dCkpCgkJcmV0dXJuIEZUX0RPQ1VNRU5UOwoJZWxzZQoJCXJldHVybiBGVF9PVEhFUjsKfQoKCnN0YXRpYyB2b2lkIGRyYXdfaXRlbShQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgRW50cnkqIGVudHJ5LCBpbnQgY2FsY1dpZHRoQ29sKQp7CglUQ0hBUiBidWZmZXJbQlVGRkVSX0xFTl07CglEV09SRCBhdHRyczsKCWludCB2aXNpYmxlX2NvbHMgPSBwYW5lLT52aXNpYmxlX2NvbHM7CglDT0xPUlJFRiBia2NvbG9yLCB0ZXh0Y29sb3I7CglSRUNUIGZvY3VzUmVjdCA9IGRpcy0+cmNJdGVtOwoJSEJSVVNIIGhicnVzaDsKCWVudW0gSU1BR0UgaW1nOwoJaW50IGltZ19wb3MsIGN4OwoJaW50IGNvbCA9IDA7CgoJaWYgKGVudHJ5KSB7CgkJYXR0cnMgPSBlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzOwoKCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQkJaWYgKGVudHJ5LT5kYXRhLmNGaWxlTmFtZVswXSA9PSAnLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdID09ICcuJwoJCQkJCSYmIGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsyXSA9PSAnXDAnKQoJCQkJaW1nID0gSU1HX0ZPTERFUl9VUDsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQllbHNlIGlmIChlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF0gPT0gJy4nICYmIGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsxXSA9PSAnXDAnKQoJCQkJaW1nID0gSU1HX0ZPTERFUl9DVVI7CiNlbmRpZgoJCQllbHNlIGlmICgKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQkJIGVudHJ5LT5leHBhbmRlZCB8fAojZW5kaWYKCQkJCQkgKHBhbmUtPnRyZWVQYW5lICYmIChkaXMtPml0ZW1TdGF0ZSZPRFNfRk9DVVMpKSkKCQkJCWltZyA9IElNR19PUEVOX0ZPTERFUjsKCQkJZWxzZQoJCQkJaW1nID0gSU1HX0ZPTERFUjsKCQl9IGVsc2UgewoJCQlzd2l0Y2goZ2V0X2ZpbGVfdHlwZShlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpKSB7CgkJCSAgY2FzZSBGVF9FWEVDVVRBQkxFOglpbWcgPSBJTUdfRVhFQ1VUQUJMRTsJYnJlYWs7CgkJCSAgY2FzZSBGVF9ET0NVTUVOVDoJCWltZyA9IElNR19ET0NVTUVOVDsJCWJyZWFrOwoJCQkgIGRlZmF1bHQ6CQkJCWltZyA9IElNR19GSUxFOwoJCQl9CgkJfQoJfSBlbHNlIHsKCQlhdHRycyA9IDA7CgkJaW1nID0gSU1HX05PTkU7Cgl9CgoJaWYgKHBhbmUtPnRyZWVQYW5lKSB7CgkJaWYgKGVudHJ5KSB7CgkJCWltZ19wb3MgPSBkaXMtPnJjSXRlbS5sZWZ0ICsgZW50cnktPmxldmVsKihJTUFHRV9XSURUSCtUUkVFX0xJTkVfRFgpOwoKCQkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkgewoJCQkJaW50IHg7CgkJCQlpbnQgeSA9IGRpcy0+cmNJdGVtLnRvcCArIElNQUdFX0hFSUdIVC8yOwoJCQkJRW50cnkqIHVwOwoJCQkJUkVDVCBydF9jbGlwOwoJCQkJSFJHTiBocmduX29yZyA9IENyZWF0ZVJlY3RSZ24oMCwgMCwgMCwgMCk7CgkJCQlIUkdOIGhyZ247CgoJCQkJcnRfY2xpcC5sZWZ0ICAgPSBkaXMtPnJjSXRlbS5sZWZ0OwoJCQkJcnRfY2xpcC50b3AgICAgPSBkaXMtPnJjSXRlbS50b3A7CgkJCQlydF9jbGlwLnJpZ2h0ICA9IGRpcy0+cmNJdGVtLmxlZnQrcGFuZS0+d2lkdGhzW2NvbF07CgkJCQlydF9jbGlwLmJvdHRvbSA9IGRpcy0+cmNJdGVtLmJvdHRvbTsKCgkJCQlocmduID0gQ3JlYXRlUmVjdFJnbkluZGlyZWN0KCZydF9jbGlwKTsKCgkJCQlpZiAoIUdldENsaXBSZ24oZGlzLT5oREMsIGhyZ25fb3JnKSkgewoJCQkJCURlbGV0ZU9iamVjdChocmduX29yZyk7CgkJCQkJaHJnbl9vcmcgPSAwOwoJCQkJfQoKCQkJCS8qIEhHRElPQkogaG9sZFBlbiA9IFNlbGVjdE9iamVjdChkaXMtPmhEQywgR2V0U3RvY2tPYmplY3QoQkxBQ0tfUEVOKSk7ICovCgkJCQlFeHRTZWxlY3RDbGlwUmduKGRpcy0+aERDLCBocmduLCBSR05fQU5EKTsKCQkJCURlbGV0ZU9iamVjdChocmduKTsKCgkJCQlpZiAoKHVwPWVudHJ5LT51cCkgIT0gTlVMTCkgewoJCQkJCU1vdmVUb0V4KGRpcy0+aERDLCBpbWdfcG9zLUlNQUdFX1dJRFRILzIsIHksIDApOwoJCQkJCUxpbmVUbyhkaXMtPmhEQywgaW1nX3Bvcy0yLCB5KTsKCgkJCQkJeCA9IGltZ19wb3MgLSBJTUFHRV9XSURUSC8yOwoKCQkJCQlkbyB7CgkJCQkJCXggLT0gSU1BR0VfV0lEVEgrVFJFRV9MSU5FX0RYOwoKCQkJCQkJaWYgKHVwLT5uZXh0CiNpZm5kZWYgX0xFRlRfRklMRVMKCQkJCQkJCSYmICh1cC0+bmV4dC0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKQojZW5kaWYKCQkJCQkJCSkgewoJCQkJCQkJTW92ZVRvRXgoZGlzLT5oREMsIHgsIGRpcy0+cmNJdGVtLnRvcCwgMCk7CgkJCQkJCQlMaW5lVG8oZGlzLT5oREMsIHgsIGRpcy0+cmNJdGVtLmJvdHRvbSk7CgkJCQkJCX0KCQkJCQl9IHdoaWxlKCh1cD11cC0+dXApICE9IE5VTEwpOwoJCQkJfQoKCQkJCXggPSBpbWdfcG9zIC0gSU1BR0VfV0lEVEgvMjsKCgkJCQlNb3ZlVG9FeChkaXMtPmhEQywgeCwgZGlzLT5yY0l0ZW0udG9wLCAwKTsKCQkJCUxpbmVUbyhkaXMtPmhEQywgeCwgeSk7CgoJCQkJaWYgKGVudHJ5LT5uZXh0CiNpZm5kZWYgX0xFRlRfRklMRVMKCQkJCQkmJiAoZW50cnktPm5leHQtPmRhdGEuZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpCiNlbmRpZgoJCQkJCSkKCQkJCQlMaW5lVG8oZGlzLT5oREMsIHgsIGRpcy0+cmNJdGVtLmJvdHRvbSk7CgoJCQkJU2VsZWN0Q2xpcFJnbihkaXMtPmhEQywgaHJnbl9vcmcpOwoJCQkJaWYgKGhyZ25fb3JnKSBEZWxldGVPYmplY3QoaHJnbl9vcmcpOwoJCQkJLyogU2VsZWN0T2JqZWN0KGRpcy0+aERDLCBob2xkUGVuKTsgKi8KCQkJfSBlbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpIHsKCQkJCWludCByaWdodCA9IGltZ19wb3MgKyBJTUFHRV9XSURUSCAtIFRSRUVfTElORV9EWDsKCgkJCQlpZiAocmlnaHQgPiBwYW5lLT53aWR0aHNbY29sXSkKCQkJCQlwYW5lLT53aWR0aHNbY29sXSA9IHJpZ2h0OwoJCQl9CgkJfSBlbHNlICB7CgkJCWltZ19wb3MgPSBkaXMtPnJjSXRlbS5sZWZ0OwoJCX0KCX0gZWxzZSB7CgkJaW1nX3BvcyA9IGRpcy0+cmNJdGVtLmxlZnQ7CgoJCWlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCXBhbmUtPndpZHRoc1tjb2xdID0gSU1BR0VfV0lEVEg7Cgl9CgoJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkgewoJCWZvY3VzUmVjdC5sZWZ0ID0gaW1nX3BvcyAtMjsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCWlmIChwYW5lLT50cmVlUGFuZSAmJiBlbnRyeSkgewoJCQlSRUNUIHJ0ID0gezB9OwoKCQkJRHJhd1RleHQoZGlzLT5oREMsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSwgLTEsICZydCwgRFRfQ0FMQ1JFQ1R8RFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWCk7CgoJCQlmb2N1c1JlY3QucmlnaHQgPSBkaXMtPnJjSXRlbS5sZWZ0K3BhbmUtPnBvc2l0aW9uc1tjb2wrMV0rVFJFRV9MSU5FX0RYICsgcnQucmlnaHQgKzI7CgkJfQojZWxzZQoKCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9DT01QUkVTU0VEKQoJCQl0ZXh0Y29sb3IgPSBDT0xPUl9DT01QUkVTU0VEOwoJCWVsc2UKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgkJCXRleHRjb2xvciA9IFJHQigwLDAsMCk7CgoJCWlmIChkaXMtPml0ZW1TdGF0ZSAmIE9EU19GT0NVUykgewoJCQl0ZXh0Y29sb3IgPSBSR0IoMjU1LDI1NSwyNTUpOwoJCQlia2NvbG9yID0gQ09MT1JfU0VMRUNUSU9OOwoJCX0gZWxzZSB7CgkJCWJrY29sb3IgPSBSR0IoMjU1LDI1NSwyNTUpOwoJCX0KCgkJaGJydXNoID0gQ3JlYXRlU29saWRCcnVzaChia2NvbG9yKTsKCQlGaWxsUmVjdChkaXMtPmhEQywgJmZvY3VzUmVjdCwgaGJydXNoKTsKCQlEZWxldGVPYmplY3QoaGJydXNoKTsKCgkJU2V0QmtNb2RlKGRpcy0+aERDLCBUUkFOU1BBUkVOVCk7CgkJU2V0VGV4dENvbG9yKGRpcy0+aERDLCB0ZXh0Y29sb3IpOwoKCQljeCA9IHBhbmUtPndpZHRoc1tjb2xdOwoKCQlpZiAoY3ggJiYgaW1nIT1JTUdfTk9ORSkgewoJCQlpZiAoY3ggPiBJTUFHRV9XSURUSCkKCQkJCWN4ID0gSU1BR0VfV0lEVEg7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCQkJaWYgKGVudHJ5LT5oaWNvbiAmJiBlbnRyeS0+aGljb24hPShISUNPTiktMSkKCQkJCURyYXdJY29uRXgoZGlzLT5oREMsIGltZ19wb3MsIGRpcy0+cmNJdGVtLnRvcCwgZW50cnktPmhpY29uLCBjeCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNSUNPTiksIDAsIDAsIERJX05PUk1BTCk7CgkJCWVsc2UKI2VuZGlmCgkJCQlJbWFnZUxpc3RfRHJhd0V4KEdsb2JhbHMuaGltbCwgaW1nLCBkaXMtPmhEQywKCQkJCQkJCQkgaW1nX3BvcywgZGlzLT5yY0l0ZW0udG9wLCBjeCwKCQkJCQkJCQkgSU1BR0VfSEVJR0hULCBia2NvbG9yLCBDTFJfREVGQVVMVCwgSUxEX05PUk1BTCk7CgkJfQoJfQoKCWlmICghZW50cnkpCgkJcmV0dXJuOwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCglpZiAoaW1nID49IElNR19GT0xERVJfVVApCgkJcmV0dXJuOwojZW5kaWYKCgljb2wrKzsKCgkvKiBvdXB1dCBmaWxlIG5hbWUgKi8KCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSwgMCk7CgllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgZW50cnktPmRhdGEuY0ZpbGVOYW1lKTsKCgljb2wrKzsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwogIGlmICghcGFuZS0+dHJlZVBhbmUpIHsKI2VuZGlmCgogICAgICAgIC8qIGRpc3BsYXkgZmlsZSBzaXplICovCglpZiAodmlzaWJsZV9jb2xzICYgQ09MX1NJWkUpIHsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJaWYgKCEoYXR0cnMmRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSkKI2VuZGlmCgkJewoJCQlVTE9OR0xPTkcgc2l6ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAoKFVMT05HTE9ORyllbnRyeS0+ZGF0YS5uRmlsZVNpemVIaWdoIDw8IDMyKSB8IGVudHJ5LT5kYXRhLm5GaWxlU2l6ZUxvdzsKCgkJCV9zdHByaW50ZihidWZmZXIsIHNMb25nTnVtRm10LCBzaXplKTsKCgkJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCQlvdXRwdXRfbnVtYmVyKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoJCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOy8qVE9ETzogbm90IGV2ZXIgdGltZSBlbm91Z2ggKi8KCQl9CgoJCWNvbCsrOwoJfQoKCS8qIGRpc3BsYXkgZmlsZSBkYXRlICovCglpZiAodmlzaWJsZV9jb2xzICYgKENPTF9EQVRFfENPTF9USU1FKSkgewojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJZm9ybWF0X2RhdGUoJmVudHJ5LT5kYXRhLmZ0Q3JlYXRpb25UaW1lLCBidWZmZXIsIHZpc2libGVfY29scyk7CgkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlciwgMCk7CgkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoJCWNvbCsrOwoKCQlmb3JtYXRfZGF0ZSgmZW50cnktPmRhdGEuZnRMYXN0QWNjZXNzVGltZSwgYnVmZmVyLCB2aXNpYmxlX2NvbHMpOwoJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIsIDApOwoJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCQljb2wrKzsKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJCWZvcm1hdF9kYXRlKCZlbnRyeS0+ZGF0YS5mdExhc3RXcml0ZVRpbWUsIGJ1ZmZlciwgdmlzaWJsZV9jb2xzKTsKCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyLCAwKTsKCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgkJY29sKys7Cgl9CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCglpZiAoZW50cnktPmJoZmlfdmFsaWQpIHsKICAgICAgICAgICAgVUxPTkdMT05HIGluZGV4ID0gKChVTE9OR0xPTkcpZW50cnktPmJoZmkubkZpbGVJbmRleEhpZ2ggPDwgMzIpIHwgZW50cnktPmJoZmkubkZpbGVJbmRleExvdzsKCgkJaWYgKHZpc2libGVfY29scyAmIENPTF9JTkRFWCkgewoJCQlfc3RwcmludGYoYnVmZmVyLCBzTG9uZ0hleEZtdCwgaW5kZXgpOwoKCQkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIsIERUX1JJR0hUKTsKCQkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCgkJCWNvbCsrOwoJCX0KCgkJaWYgKHZpc2libGVfY29scyAmIENPTF9MSU5LUykgewoJCQl3c3ByaW50ZihidWZmZXIsIHNOdW1GbXQsIGVudHJ5LT5iaGZpLm5OdW1iZXJPZkxpbmtzKTsKCgkJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyLCBEVF9DRU5URVIpOwoJCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoKCQkJY29sKys7CgkJfQoJfSBlbHNlCgkJY29sICs9IDI7CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCS8qIHNob3cgZmlsZSBhdHRyaWJ1dGVzICovCglpZiAodmlzaWJsZV9jb2xzICYgQ09MX0FUVFJJQlVURVMpIHsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJc3RhdGljIGNvbnN0IFRDSEFSIHM0VGFic1tdID0geycgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXDAnfTsKCQlsc3RyY3B5KGJ1ZmZlciwgczRUYWJzKTsKI2Vsc2UKCQlzdGF0aWMgY29uc3QgVENIQVIgczExVGFic1tdID0geycgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXDAnfTsKCQlsc3RyY3B5KGJ1ZmZlciwgczExVGFicyk7CiNlbmRpZgoKCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9OT1JNQUwpCQkJCQlidWZmZXJbIDBdID0gJ04nOwoJCWVsc2UgewoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9SRUFET05MWSkJCQlidWZmZXJbIDJdID0gJ1InOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9ISURERU4pCQkJCWJ1ZmZlclsgNF0gPSAnSCc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX1NZU1RFTSkJCQkJYnVmZmVyWyA2XSA9ICdTJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfQVJDSElWRSkJCQkJYnVmZmVyWyA4XSA9ICdBJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfQ09NUFJFU1NFRCkJCQlidWZmZXJbMTBdID0gJ0MnOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkJCQlidWZmZXJbMTJdID0gJ0QnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9FTkNSWVBURUQpCQkJYnVmZmVyWzE0XSA9ICdFJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfVEVNUE9SQVJZKQkJCWJ1ZmZlclsxNl0gPSAnVCc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX1NQQVJTRV9GSUxFKQkJCWJ1ZmZlclsxOF0gPSAnUCc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX1JFUEFSU0VfUE9JTlQpCQlidWZmZXJbMjBdID0gJ1EnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9PRkZMSU5FKQkJCQlidWZmZXJbMjJdID0gJ08nOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9OT1RfQ09OVEVOVF9JTkRFWEVEKQlidWZmZXJbMjRdID0gJ1gnOwojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCQl9CgoJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCW91dHB1dF90YWJiZWRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCWNhbGNfdGFiYmVkX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoKCQljb2wrKzsKCX0KCi8qVE9ETwoJaWYgKGZsYWdzLnNlY3VyaXR5KSB7CgkJc3RhdGljIGNvbnN0IFRDSEFSIHNTZWNUYWJzW10gPSB7CgkJCScgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywKCQkJJyAnLCdcdCcsJyAnLAoJCQknICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsCgkJCScgJywnXHQnLCcgJywKCQkJJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLAoJCQknXDAnCgkJfTsKCgkJRFdPUkQgcmlnaHRzID0gZ2V0X2FjY2Vzc19tYXNrKCk7CgoJCWxzdHJjcHkoYnVmZmVyLCBzU2VjVGFicyk7CgoJCWlmIChyaWdodHMgJiBGSUxFX1JFQURfREFUQSkJCQlidWZmZXJbIDBdID0gJ1InOwoJCWlmIChyaWdodHMgJiBGSUxFX1dSSVRFX0RBVEEpCQkJYnVmZmVyWyAyXSA9ICdXJzsKCQlpZiAocmlnaHRzICYgRklMRV9BUFBFTkRfREFUQSkJCQlidWZmZXJbIDRdID0gJ0EnOwoJCWlmIChyaWdodHMgJiBGSUxFX1JFQURfRUEpCQkJCXtidWZmZXJbNl0gPSAnZW50cnknOyBidWZmZXJbIDddID0gJ1InO30KCQlpZiAocmlnaHRzICYgRklMRV9XUklURV9FQSkJCQkJe2J1ZmZlcls5XSA9ICdlbnRyeSc7IGJ1ZmZlclsxMF0gPSAnVyc7fQoJCWlmIChyaWdodHMgJiBGSUxFX0VYRUNVVEUpCQkJCWJ1ZmZlclsxMl0gPSAnWCc7CgkJaWYgKHJpZ2h0cyAmIEZJTEVfREVMRVRFX0NISUxEKQkJCWJ1ZmZlclsxNF0gPSAnRCc7CgkJaWYgKHJpZ2h0cyAmIEZJTEVfUkVBRF9BVFRSSUJVVEVTKQkJe2J1ZmZlclsxNl0gPSAnYSc7IGJ1ZmZlclsxN10gPSAnUic7fQoJCWlmIChyaWdodHMgJiBGSUxFX1dSSVRFX0FUVFJJQlVURVMpCQl7YnVmZmVyWzE5XSA9ICdhJzsgYnVmZmVyWzIwXSA9ICdXJzt9CgkJaWYgKHJpZ2h0cyAmIFdSSVRFX0RBQykJCQkJCWJ1ZmZlclsyMl0gPSAnQyc7CgkJaWYgKHJpZ2h0cyAmIFdSSVRFX09XTkVSKQkJCQlidWZmZXJbMjRdID0gJ08nOwoJCWlmIChyaWdodHMgJiBTWU5DSFJPTklaRSkJCQkJYnVmZmVyWzI2XSA9ICdTJzsKCgkJb3V0cHV0X3RleHQoZGlzLCBjb2wrKywgYnVmZmVyLCBEVF9MRUZULCAzLCBwc2l6ZSk7Cgl9CgoJaWYgKGZsYWdzLmRlc2NyaXB0aW9uKSB7CgkJZ2V0X2Rlc2NyaXB0aW9uKGJ1ZmZlcik7CgkJb3V0cHV0X3RleHQoZGlzLCBjb2wrKywgYnVmZmVyLCAwLCBwc2l6ZSk7Cgl9CiovCgojaWZkZWYgX05PX0VYVEVOU0lPTlMKICB9CgogICAgICAgIC8qIGRyYXcgZm9jdXMgZnJhbWUgKi8KCWlmICgoZGlzLT5pdGVtU3RhdGUmT0RTX0ZPQ1VTKSAmJiBjYWxjV2lkdGhDb2w9PS0xKSB7CgkgICAgICAgIC8qIEN1cnJlbnRseSBbMDQvMjAwMF0gV2luZSBuZWl0aGVyIGJlaGF2ZXMgZXhhY3RseSB0aGUgc2FtZSAqLwoJICAgICAgICAvKiB3YXkgYXMgV0lOIDk1IG5vciBsaWtlIFdpbmRvd3MgTlQuLi4gKi8KCQlIR0RJT0JKIGxhc3RCcnVzaDsKCQlIUEVOIGxhc3RQZW47CgkJSFBFTiBocGVuOwoKCQlpZiAoIShHZXRWZXJzaW9uKCkgJiAweDgwMDAwMDAwKSkgewkvKiBXaW5kb3dzIE5UPyAqLwoJCQlMT0dCUlVTSCBsYiA9IHtQU19TT0xJRCwgUkdCKDI1NSwyNTUsMjU1KX07CgkJCWhwZW4gPSBFeHRDcmVhdGVQZW4oUFNfQ09TTUVUSUN8UFNfQUxURVJOQVRFLCAxLCAmbGIsIDAsIDApOwoJCX0gZWxzZQoJCQlocGVuID0gQ3JlYXRlUGVuKFBTX0RPVCwgMCwgUkdCKDI1NSwyNTUsMjU1KSk7CgoJCWxhc3RQZW4gPSBTZWxlY3RQZW4oZGlzLT5oREMsIGhwZW4pOwoJCWxhc3RCcnVzaCA9IFNlbGVjdE9iamVjdChkaXMtPmhEQywgR2V0U3RvY2tPYmplY3QoSE9MTE9XX0JSVVNIKSk7CgkJU2V0Uk9QMihkaXMtPmhEQywgUjJfWE9SUEVOKTsKCQlSZWN0YW5nbGUoZGlzLT5oREMsIGZvY3VzUmVjdC5sZWZ0LCBmb2N1c1JlY3QudG9wLCBmb2N1c1JlY3QucmlnaHQsIGZvY3VzUmVjdC5ib3R0b20pOwoJCVNlbGVjdE9iamVjdChkaXMtPmhEQywgbGFzdEJydXNoKTsKCQlTZWxlY3RPYmplY3QoZGlzLT5oREMsIGxhc3RQZW4pOwoJCURlbGV0ZU9iamVjdChocGVuKTsKCX0KI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCn0KCgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCnN0YXRpYyB2b2lkIGRyYXdfc3BsaXRiYXIoSFdORCBod25kLCBpbnQgeCkKewoJUkVDVCBydDsKCUhEQyBoZGMgPSBHZXREQyhod25kKTsKCglHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJcnQubGVmdCA9IHggLSBTUExJVF9XSURUSC8yOwoJcnQucmlnaHQgPSB4ICsgU1BMSVRfV0lEVEgvMisxOwoKCUludmVydFJlY3QoaGRjLCAmcnQpOwoKCVJlbGVhc2VEQyhod25kLCBoZGMpOwp9CgojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgpzdGF0aWMgdm9pZCBzZXRfaGVhZGVyKFBhbmUqIHBhbmUpCnsKCUhEX0lURU0gaXRlbTsKCWludCBzY3JvbGxfcG9zID0gR2V0U2Nyb2xsUG9zKHBhbmUtPmh3bmQsIFNCX0hPUlopOwoJaW50IGk9MCwgeD0wOwoKCWl0ZW0ubWFzayA9IEhESV9XSURUSDsKCWl0ZW0uY3h5ID0gMDsKCglmb3IoOyB4K3BhbmUtPndpZHRoc1tpXTxzY3JvbGxfcG9zICYmIGk8Q09MVU1OUzsgaSsrKSB7CgkJeCArPSBwYW5lLT53aWR0aHNbaV07CgkJU2VuZE1lc3NhZ2UocGFuZS0+aHduZEhlYWRlciwgSERNX1NFVElURU0sIGksIChMUEFSQU0pICZpdGVtKTsKCX0KCglpZiAoaSA8IENPTFVNTlMpIHsKCQl4ICs9IHBhbmUtPndpZHRoc1tpXTsKCQlpdGVtLmN4eSA9IHggLSBzY3JvbGxfcG9zOwoJCVNlbmRNZXNzYWdlKHBhbmUtPmh3bmRIZWFkZXIsIEhETV9TRVRJVEVNLCBpKyssIChMUEFSQU0pICZpdGVtKTsKCgkJZm9yKDsgaTxDT0xVTU5TOyBpKyspIHsKCQkJaXRlbS5jeHkgPSBwYW5lLT53aWR0aHNbaV07CgkJCXggKz0gcGFuZS0+d2lkdGhzW2ldOwoJCQlTZW5kTWVzc2FnZShwYW5lLT5od25kSGVhZGVyLCBIRE1fU0VUSVRFTSwgaSwgKExQQVJBTSkgJml0ZW0pOwoJCX0KCX0KfQoKc3RhdGljIExSRVNVTFQgcGFuZV9ub3RpZnkoUGFuZSogcGFuZSwgTk1IRFIqIHBubWgpCnsKCXN3aXRjaChwbm1oLT5jb2RlKSB7CgkJY2FzZSBIRE5fSVRFTUNIQU5HRUQ6IHsKCQkJSERfTk9USUZZKiBwaGRuID0gKEhEX05PVElGWSopIHBubWg7CgkJCWludCBpZHggPSBwaGRuLT5pSXRlbTsKCQkJaW50IGR4ID0gcGhkbi0+cGl0ZW0tPmN4eSAtIHBhbmUtPndpZHRoc1tpZHhdOwoJCQlpbnQgaTsKCgkJCVJFQ1QgY2xudDsKCQkJR2V0Q2xpZW50UmVjdChwYW5lLT5od25kLCAmY2xudCk7CgoJCQlwYW5lLT53aWR0aHNbaWR4XSArPSBkeDsKCgkJCWZvcihpPWlkeDsgKytpPD1DT0xVTU5TOyApCgkJCQlwYW5lLT5wb3NpdGlvbnNbaV0gKz0gZHg7CgoJCQl7CgkJCQlpbnQgc2Nyb2xsX3BvcyA9IEdldFNjcm9sbFBvcyhwYW5lLT5od25kLCBTQl9IT1JaKTsKCQkJCVJFQ1QgcnRfc2NyOwoJCQkJUkVDVCBydF9jbGlwOwoKCQkJCXJ0X3Njci5sZWZ0ICAgPSBwYW5lLT5wb3NpdGlvbnNbaWR4KzFdLXNjcm9sbF9wb3M7CgkJCQlydF9zY3IudG9wICAgID0gMDsKCQkJCXJ0X3Njci5yaWdodCAgPSBjbG50LnJpZ2h0OwoJCQkJcnRfc2NyLmJvdHRvbSA9IGNsbnQuYm90dG9tOwoKCQkJCXJ0X2NsaXAubGVmdCAgID0gcGFuZS0+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+PWNoaWxkLT5zcGxpdF9wb3MtU1BMSVRfV0lEVEgvMiAmJiBwdC54PGNoaWxkLT5zcGxpdF9wb3MrU1BMSVRfV0lEVEgvMisxKSB7CgkJCQkJU2V0Q3Vyc29yKExvYWRDdXJzb3IoMCwgSURDX1NJWkVXRSkpOwoJCQkJCXJldHVybiBUUlVFOwoJCQkJfQoJCQl9CgkJCWdvdG8gZGVmOwoKCQljYXNlIFdNX0xCVVRUT05ET1dOOiB7CgkJCVJFQ1QgcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCB4ID0gKHNob3J0KUxPV09SRChscGFyYW0pOwoKCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoKCQkJaWYgKHg+PWNoaWxkLT5zcGxpdF9wb3MtU1BMSVRfV0lEVEgvMiAmJiB4PGNoaWxkLT5zcGxpdF9wb3MrU1BMSVRfV0lEVEgvMisxKSB7CgkJCQlsYXN0X3NwbGl0ID0gY2hpbGQtPnNwbGl0X3BvczsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQlkcmF3X3NwbGl0YmFyKGh3bmQsIGxhc3Rfc3BsaXQpOwojZW5kaWYKCQkJCVNldENhcHR1cmUoaHduZCk7CgkJCX0KCgkJCWJyZWFrO30KCgkJY2FzZSBXTV9MQlVUVE9OVVA6CgkJCWlmIChHZXRDYXB0dXJlKCkgPT0gaHduZCkgewojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJCVJFQ1QgcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHggPSAoc2hvcnQpTE9XT1JEKGxwYXJhbSk7CgkJCQlkcmF3X3NwbGl0YmFyKGh3bmQsIGxhc3Rfc3BsaXQpOwoJCQkJbGFzdF9zcGxpdCA9IC0xOwoJCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoJCQkJY2hpbGQtPnNwbGl0X3BvcyA9IHg7CgkJCQlyZXNpemVfdHJlZShjaGlsZCwgcnQucmlnaHQsIHJ0LmJvdHRvbSk7CiNlbmRpZgoJCQkJUmVsZWFzZUNhcHR1cmUoKTsKCQkJfQoJCQlicmVhazsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fQ0FQVFVSRUNIQU5HRUQ6CgkJCWlmIChHZXRDYXB0dXJlKCk9PWh3bmQgJiYgbGFzdF9zcGxpdD49MCkKCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CgkJCWJyZWFrOwojZW5kaWYKCgkJY2FzZSBXTV9LRVlET1dOOgoJCQlpZiAod3BhcmFtID09IFZLX0VTQ0FQRSkKCQkJCWlmIChHZXRDYXB0dXJlKCkgPT0gaHduZCkgewoJCQkJCVJFQ1QgcnQ7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CiNlbHNlCgkJCQkJY2hpbGQtPnNwbGl0X3BvcyA9IGxhc3Rfc3BsaXQ7CiNlbmRpZgoJCQkJCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCQkJCQlyZXNpemVfdHJlZShjaGlsZCwgcnQucmlnaHQsIHJ0LmJvdHRvbSk7CgkJCQkJbGFzdF9zcGxpdCA9IC0xOwoJCQkJCVJlbGVhc2VDYXB0dXJlKCk7CgkJCQkJU2V0Q3Vyc29yKExvYWRDdXJzb3IoMCwgSURDX0FSUk9XKSk7CgkJCQl9CgkJCWJyZWFrOwoKCQljYXNlIFdNX01PVVNFTU9WRToKCQkJaWYgKEdldENhcHR1cmUoKSA9PSBod25kKSB7CgkJCQlSRUNUIHJ0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB4ID0gKHNob3J0KUxPV09SRChscGFyYW0pOwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQlIREMgaGRjID0gR2V0REMoaHduZCk7CgkJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJCQkJcnQubGVmdCA9IGxhc3Rfc3BsaXQtU1BMSVRfV0lEVEgvMjsKCQkJCXJ0LnJpZ2h0ID0gbGFzdF9zcGxpdCtTUExJVF9XSURUSC8yKzE7CgkJCQlJbnZlcnRSZWN0KGhkYywgJnJ0KTsKCgkJCQlsYXN0X3NwbGl0ID0geDsKCQkJCXJ0LmxlZnQgPSB4LVNQTElUX1dJRFRILzI7CgkJCQlydC5yaWdodCA9IHgrU1BMSVRfV0lEVEgvMisxOwoJCQkJSW52ZXJ0UmVjdChoZGMsICZydCk7CgoJCQkJUmVsZWFzZURDKGh3bmQsIGhkYyk7CiNlbHNlCgkJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJCQkJaWYgKHg+PTAgJiYgeDxydC5yaWdodCkgewoJCQkJCWNoaWxkLT5zcGxpdF9wb3MgPSB4OwoJCQkJCXJlc2l6ZV90cmVlKGNoaWxkLCBydC5yaWdodCwgcnQuYm90dG9tKTsKCQkJCQlydC5sZWZ0ID0geC1TUExJVF9XSURUSC8yOwoJCQkJCXJ0LnJpZ2h0ID0geCtTUExJVF9XSURUSC8yKzE7CgkJCQkJSW52YWxpZGF0ZVJlY3QoaHduZCwgJnJ0LCBGQUxTRSk7CgkJCQkJVXBkYXRlV2luZG93KGNoaWxkLT5sZWZ0Lmh3bmQpOwoJCQkJCVVwZGF0ZVdpbmRvdyhod25kKTsKCQkJCQlVcGRhdGVXaW5kb3coY2hpbGQtPnJpZ2h0Lmh3bmQpOwoJCQkJfQojZW5kaWYKCQkJfQoJCQlicmVhazsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQljYXNlIFdNX0dFVE1JTk1BWElORk86CgkJCURlZk1ESUNoaWxkUHJvYyhod25kLCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7CgoJCQl7TFBNSU5NQVhJTkZPIGxwbW1pID0gKExQTUlOTUFYSU5GTylscGFyYW07CgoJCQlscG1taS0+cHRNYXhUcmFja1NpemUueCA8PD0gMTsvKjIqR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTikgLyBTTV9DWFZJUlRVQUxTQ1JFRU4gKi8KCQkJbHBtbWktPnB0TWF4VHJhY2tTaXplLnkgPDw9IDE7LyoyKkdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pIC8gU01fQ1lWSVJUVUFMU0NSRUVOICovCgkJCWJyZWFrO30KI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJCWNhc2UgV01fU0VURk9DVVM6CgkJCWlmIChTZXRDdXJyZW50RGlyZWN0b3J5KGNoaWxkLT5wYXRoKSkKCQkJCXNldF9zcGFjZV9zdGF0dXMoKTsKCQkJU2V0Rm9jdXMoY2hpbGQtPmZvY3VzX3BhbmU/IGNoaWxkLT5yaWdodC5od25kOiBjaGlsZC0+bGVmdC5od25kKTsKCQkJYnJlYWs7CgoJCWNhc2UgV01fRElTUEFUQ0hfQ09NTUFORDogewoJCQlQYW5lKiBwYW5lID0gR2V0Rm9jdXMoKT09Y2hpbGQtPmxlZnQuaHduZD8gJmNoaWxkLT5sZWZ0OiAmY2hpbGQtPnJpZ2h0OwoKCQkJc3dpdGNoKExPV09SRCh3cGFyYW0pKSB7CgkJCQljYXNlIElEX1dJTkRPV19ORVc6IHsKCQkJCQlDaGlsZFduZCogbmV3X2NoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KGNoaWxkLT5wYXRoLCBOVUxMLCBod25kKTsKCgkJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KG5ld19jaGlsZCkpCgkJCQkJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG5ld19jaGlsZCk7CgoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX1JFRlJFU0g6CgkJCQkJcmVmcmVzaF9kcml2ZXMoKTsKCQkJCQlyZWZyZXNoX2NoaWxkKGNoaWxkKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX0FDVElWQVRFOgoJCQkJCWFjdGl2YXRlX2VudHJ5KGNoaWxkLCBwYW5lLCBod25kKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX0ZJTEVfTU9WRTogewoJCQkJCVRDSEFSIHNvdXJjZVtCVUZGRVJfTEVOXSwgdGFyZ2V0W0JVRkZFUl9MRU5dOwoKCQkJCQlpZiAocHJvbXB0X3RhcmdldChwYW5lLCBzb3VyY2UsIHRhcmdldCkpIHsKCQkJCQkJU0hGSUxFT1BTVFJVQ1Qgc2hmbyA9IHtod25kLCBGT19NT1ZFLCBzb3VyY2UsIHRhcmdldH07CgoJCQkJCQlzb3VyY2VbbHN0cmxlbihzb3VyY2UpKzFdID0gJ1wwJzsKCQkJCQkJdGFyZ2V0W2xzdHJsZW4odGFyZ2V0KSsxXSA9ICdcMCc7CgoJCQkJCQlpZiAoIVNIRmlsZU9wZXJhdGlvbigmc2hmbykpCgkJCQkJCQlyZWZyZXNoX2NoaWxkKGNoaWxkKTsKCQkJCQl9CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfRklMRV9DT1BZOiB7CgkJCQkJVENIQVIgc291cmNlW0JVRkZFUl9MRU5dLCB0YXJnZXRbQlVGRkVSX0xFTl07CgoJCQkJCWlmIChwcm9tcHRfdGFyZ2V0KHBhbmUsIHNvdXJjZSwgdGFyZ2V0KSkgewoJCQkJCQlTSEZJTEVPUFNUUlVDVCBzaGZvID0ge2h3bmQsIEZPX0NPUFksIHNvdXJjZSwgdGFyZ2V0fTsKCgkJCQkJCXNvdXJjZVtsc3RybGVuKHNvdXJjZSkrMV0gPSAnXDAnOwoJCQkJCQl0YXJnZXRbbHN0cmxlbih0YXJnZXQpKzFdID0gJ1wwJzsKCgkJCQkJCWlmICghU0hGaWxlT3BlcmF0aW9uKCZzaGZvKSkKCQkJCQkJCXJlZnJlc2hfY2hpbGQoY2hpbGQpOwoJCQkJCX0KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9GSUxFX0RFTEVURTogewoJCQkJCVRDSEFSIHBhdGhbQlVGRkVSX0xFTl07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSEZJTEVPUFNUUlVDVCBzaGZvID0ge2h3bmQsIEZPX0RFTEVURSwgcGF0aCwgTlVMTCwgRk9GX0FMTE9XVU5ET307CgoJCQkJCWdldF9wYXRoKHBhbmUtPmN1ciwgcGF0aCk7CgoJCQkJCXBhdGhbbHN0cmxlbihwYXRoKSsxXSA9ICdcMCc7CgoJCQkJCWlmICghU0hGaWxlT3BlcmF0aW9uKCZzaGZvKSkKCQkJCQkJcmVmcmVzaF9jaGlsZChjaGlsZCk7CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfVklFV19TT1JUX05BTUU6CgkJCQkJc2V0X3NvcnRfb3JkZXIoY2hpbGQsIFNPUlRfTkFNRSk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9WSUVXX1NPUlRfVFlQRToKCQkJCQlzZXRfc29ydF9vcmRlcihjaGlsZCwgU09SVF9FWFQpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19TT1JUX1NJWkU6CgkJCQkJc2V0X3NvcnRfb3JkZXIoY2hpbGQsIFNPUlRfU0laRSk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9WSUVXX1NPUlRfREFURToKCQkJCQlzZXRfc29ydF9vcmRlcihjaGlsZCwgU09SVF9EQVRFKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1ZJRVdfRklMVEVSOiB7CgkJCQkJc3RydWN0IEZpbHRlckRpYWxvZyBkbGc7CgoJCQkJCW1lbXNldCgmZGxnLCAwLCBzaXplb2Yoc3RydWN0IEZpbHRlckRpYWxvZykpOwoJCQkJCWxzdHJjcHkoZGxnLnBhdHRlcm4sIGNoaWxkLT5maWx0ZXJfcGF0dGVybik7CgkJCQkJZGxnLmZsYWdzID0gY2hpbGQtPmZpbHRlcl9mbGFnczsKCgkJCQkJaWYgKERpYWxvZ0JveFBhcmFtKEdsb2JhbHMuaEluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSUREX0RJQUxPR19WSUVXX1RZUEUpLCBod25kLCBGaWx0ZXJEaWFsb2dEbGdQcm9jLCAoTFBBUkFNKSZkbGcpID09IElET0spIHsKCQkJCQkJbHN0cmNweShjaGlsZC0+ZmlsdGVyX3BhdHRlcm4sIGRsZy5wYXR0ZXJuKTsKCQkJCQkJY2hpbGQtPmZpbHRlcl9mbGFncyA9IGRsZy5mbGFnczsKCQkJCQkJcmVmcmVzaF9yaWdodF9wYW5lKGNoaWxkKTsKCQkJCQl9CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfVklFV19TUExJVDogewoJCQkJCWxhc3Rfc3BsaXQgPSBjaGlsZC0+c3BsaXRfcG9zOwojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJCQlkcmF3X3NwbGl0YmFyKGh3bmQsIGxhc3Rfc3BsaXQpOwojZW5kaWYKCQkJCQlTZXRDYXB0dXJlKGh3bmQpOwoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX0VESVRfUFJPUEVSVElFUzoKCQkJCQlzaG93X3Byb3BlcnRpZXNfZGxnKHBhbmUtPmN1ciwgY2hpbGQtPmh3bmQpOwoJCQkJCWJyZWFrOwoKCQkJCWRlZmF1bHQ6CgkJCQkJcmV0dXJuIHBhbmVfY29tbWFuZChwYW5lLCBMT1dPUkQod3BhcmFtKSk7CgkJCX0KCgkJCXJldHVybiBUUlVFO30KCgkJY2FzZSBXTV9DT01NQU5EOiB7CgkJCVBhbmUqIHBhbmUgPSBHZXRGb2N1cygpPT1jaGlsZC0+bGVmdC5od25kPyAmY2hpbGQtPmxlZnQ6ICZjaGlsZC0+cmlnaHQ7CgoJCQlzd2l0Y2goSElXT1JEKHdwYXJhbSkpIHsKCQkJCWNhc2UgTEJOX1NFTENIQU5HRTogewoJCQkJCWludCBpZHggPSBTZW5kTWVzc2FnZShwYW5lLT5od25kLCBMQl9HRVRDVVJTRUwsIDAsIDApOwoJCQkJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIFNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX0dFVElURU1EQVRBLCBpZHgsIDApOwoKCQkJCQlpZiAocGFuZSA9PSAmY2hpbGQtPmxlZnQpCgkJCQkJCXNldF9jdXJkaXIoY2hpbGQsIGVudHJ5LCBpZHgsIGh3bmQpOwoJCQkJCWVsc2UKCQkJCQkJcGFuZS0+Y3VyID0gZW50cnk7CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgTEJOX0RCTENMSzoKCQkJCQlhY3RpdmF0ZV9lbnRyeShjaGlsZCwgcGFuZSwgaHduZCk7CgkJCQkJYnJlYWs7CgkJCX0KCQkJYnJlYWs7fQoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fTk9USUZZOiB7CgkJCU5NSERSKiBwbm1oID0gKE5NSERSKikgbHBhcmFtOwoJCQlyZXR1cm4gcGFuZV9ub3RpZnkocG5taC0+aWRGcm9tPT1JRFdfSEVBREVSX0xFRlQ/ICZjaGlsZC0+bGVmdDogJmNoaWxkLT5yaWdodCwgcG5taCk7fQojZW5kaWYKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJCWNhc2UgV01fQ09OVEVYVE1FTlU6IHsKCQkJUE9JTlQgcHQsIHB0X2NsbnQ7CgkJCVBhbmUqIHBhbmU7CgkJCWludCBpZHg7CgoJCQkgLyogZmlyc3Qgc2VsZWN0IHRoZSBjdXJyZW50IGl0ZW0gaW4gdGhlIGxpc3Rib3ggKi8KCQkJSFdORCBocGFuZWwgPSAoSFdORCkgd3BhcmFtOwoJCQlwdF9jbG50LnggPSBwdC54ID0gKHNob3J0KUxPV09SRChscGFyYW0pOwoJCQlwdF9jbG50LnkgPSBwdC55ID0gKHNob3J0KUhJV09SRChscGFyYW0pOwoJCQlTY3JlZW5Ub0NsaWVudChocGFuZWwsICZwdF9jbG50KTsKCQkJU2VuZE1lc3NhZ2UoaHBhbmVsLCBXTV9MQlVUVE9ORE9XTiwgMCwgTUFLRUxPTkcocHRfY2xudC54LCBwdF9jbG50LnkpKTsKCQkJU2VuZE1lc3NhZ2UoaHBhbmVsLCBXTV9MQlVUVE9OVVAsIDAsIE1BS0VMT05HKHB0X2NsbnQueCwgcHRfY2xudC55KSk7CgoJCQkgLyogbm93IGNyZWF0ZSB0aGUgcG9wdXAgbWVudSB1c2luZyBzaGVsbCBuYW1lc3BhY2UgYW5kIElDb250ZXh0TWVudSAqLwoJCQlwYW5lID0gR2V0Rm9jdXMoKT09Y2hpbGQtPmxlZnQuaHduZD8gJmNoaWxkLT5sZWZ0OiAmY2hpbGQtPnJpZ2h0OwoJCQlpZHggPSBTZW5kTWVzc2FnZShwYW5lLT5od25kLCBMQl9HRVRDVVJTRUwsIDAsIDApOwoKCQkJaWYgKGlkeCAhPSAtMSkgewoJCQkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfR0VUSVRFTURBVEEsIGlkeCwgMCk7CgoJCQkJTFBJVEVNSURMSVNUIHBpZGxfYWJzID0gZ2V0X3RvX2Fic29sdXRlX3BpZGwoZW50cnksIGh3bmQpOwoKCQkJCWlmIChwaWRsX2FicykgewoJCQkJCUlTaGVsbEZvbGRlciogcGFyZW50Rm9sZGVyOwoJCQkJCUxQQ0lURU1JRExJU1QgcGlkbExhc3Q7CgoJCQkJCSAvKiBnZXQgYW5kIHVzZSB0aGUgcGFyZW50IGZvbGRlciB0byBkaXNwbGF5IGNvcnJlY3QgY29udGV4dCBtZW51IGluIGFsbCBjYXNlcyAqLwoJCQkJCWlmIChTVUNDRUVERUQoU0hCaW5kVG9QYXJlbnQocGlkbF9hYnMsICZJSURfSVNoZWxsRm9sZGVyLCAoTFBWT0lEKikmcGFyZW50Rm9sZGVyLCAmcGlkbExhc3QpKSkgewoJCQkJCQlpZiAoU2hlbGxGb2xkZXJDb250ZXh0TWVudShwYXJlbnRGb2xkZXIsIGh3bmQsIDEsICZwaWRsTGFzdCwgcHQueCwgcHQueSkgPT0gU19PSykKCQkJCQkJCXJlZnJlc2hfY2hpbGQoY2hpbGQpOwoKCQkJCQkJSVNoZWxsRm9sZGVyX1JlbGVhc2UocGFyZW50Rm9sZGVyKTsKCQkJCQl9CgoJCQkJCUlNYWxsb2NfRnJlZShHbG9iYWxzLmlNYWxsb2MsIHBpZGxfYWJzKTsKCQkJCX0KCQkJfQoJCQlicmVhazt9CiNlbmRpZgoKCQkgIGNhc2UgV01fTUVBU1VSRUlURU06CgkJICBkcmF3X21lbnVfaXRlbToKCQkJaWYgKCF3cGFyYW0pCS8qIElzIHRoZSBtZXNzYWdlIG1lbnUtcmVsYXRlZD8gKi8KCQkJCWlmIChDdHhNZW51X0hhbmRsZU1lbnVNc2cobm1zZywgd3BhcmFtLCBscGFyYW0pKQoJCQkJCXJldHVybiBUUlVFOwoKCQkJYnJlYWs7CgoJCSAgY2FzZSBXTV9JTklUTUVOVVBPUFVQOgoJCQlpZiAoQ3R4TWVudV9IYW5kbGVNZW51TXNnKG5tc2csIHdwYXJhbSwgbHBhcmFtKSkKCQkJCXJldHVybiAwOwoKCQkJdXBkYXRlX3ZpZXdfbWVudShjaGlsZCk7CgkJCWJyZWFrOwoKCQkgIGNhc2UgV01fTUVOVUNIQVI6CS8qIG9ubHkgc3VwcG9ydGVkIGJ5IElDb250ZXh0TWVudTMgKi8KCQkgICBpZiAoc19wY3R4bWVudTMpIHsKCQkJICAgTFJFU1VMVCBsUmVzdWx0ID0gMDsKCgkJCSAgIElDb250ZXh0TWVudTNfSGFuZGxlTWVudU1zZzIoc19wY3R4bWVudTMsIG5tc2csIHdwYXJhbSwgbHBhcmFtLCAmbFJlc3VsdCk7CgoJCQkgICByZXR1cm4gbFJlc3VsdDsKCQkgICB9CgoJCSAgIGJyZWFrOwoKCQljYXNlIFdNX1NJWkU6CgkJCWlmICh3cGFyYW0gIT0gU0laRV9NSU5JTUlaRUQpCgkJCQlyZXNpemVfdHJlZShjaGlsZCwgTE9XT1JEKGxwYXJhbSksIEhJV09SRChscGFyYW0pKTsKCQkJLyogZmFsbCB0aHJvdWdoICovCgoJCWRlZmF1bHQ6IGRlZjoKCQkJcmV0dXJuIERlZk1ESUNoaWxkUHJvYyhod25kLCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7Cgl9CgoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgTFJFU1VMVCBDQUxMQkFDSyBUcmVlV25kUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJQ2hpbGRXbmQqIGNoaWxkID0gKENoaWxkV25kKikgR2V0V2luZG93TG9uZ1B0cihHZXRQYXJlbnQoaHduZCksIEdXTFBfVVNFUkRBVEEpOwoJUGFuZSogcGFuZSA9IChQYW5lKikgR2V0V2luZG93TG9uZ1B0cihod25kLCBHV0xQX1VTRVJEQVRBKTsKCUFTU0VSVChjaGlsZCk7CgoJc3dpdGNoKG5tc2cpIHsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fSFNDUk9MTDoKCQkJc2V0X2hlYWRlcihwYW5lKTsKCQkJYnJlYWs7CiNlbmRpZgoKCQljYXNlIFdNX1NFVEZPQ1VTOgoJCQljaGlsZC0+Zm9jdXNfcGFuZSA9IHBhbmU9PSZjaGlsZC0+cmlnaHQ/IDE6IDA7CgkJCVNlbmRNZXNzYWdlKGh3bmQsIExCX1NFVFNFTCwgVFJVRSwgMSk7CgkJCS8qVE9ETzogY2hlY2sgbWVudSBpdGVtcyAqLwoJCQlicmVhazsKCgkJY2FzZSBXTV9LRVlET1dOOgoJCQlpZiAod3BhcmFtID09IFZLX1RBQikgewoJCQkJLypUT0RPOiBTZXRGb2N1cyhHbG9iYWxzLmhkcml2ZWJhcikgKi8KCQkJCVNldEZvY3VzKGNoaWxkLT5mb2N1c19wYW5lPyBjaGlsZC0+bGVmdC5od25kOiBjaGlsZC0+cmlnaHQuaHduZCk7CgkJCX0KCX0KCglyZXR1cm4gQ2FsbFdpbmRvd1Byb2MoZ19vcmdUcmVlV25kUHJvYywgaHduZCwgbm1zZywgd3BhcmFtLCBscGFyYW0pOwp9CgoKc3RhdGljIHZvaWQgSW5pdEluc3RhbmNlKEhJTlNUQU5DRSBoaW5zdGFuY2UpCnsKCXN0YXRpYyBjb25zdCBUQ0hBUiBzRm9udFtdID0geydNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCcgJywnUycsJ2EnLCduJywncycsJyAnLCdTJywnZScsJ3InLCdpJywnZicsJ1wwJ307CgoJV05EQ0xBU1NFWCB3Y0ZyYW1lOwoJV05EQ0xBU1Mgd2NDaGlsZDsKCUFUT00gaENoaWxkQ2xhc3M7CglpbnQgY29sOwoKCUlOSVRDT01NT05DT05UUk9MU0VYIGljYyA9IHsKCQlzaXplb2YoSU5JVENPTU1PTkNPTlRST0xTRVgpLAoJCUlDQ19CQVJfQ0xBU1NFUwoJfTsKCglIREMgaGRjID0gR2V0REMoMCk7CgoJc2V0bG9jYWxlKExDX0NPTExBVEUsICIiKTsJLyogc2V0IGNvbGxhdGluZyBydWxlcyB0byBsb2NhbCBzZXR0aW5ncyBmb3IgY29tcGFyZU5hbWUgKi8KCglJbml0Q29tbW9uQ29udHJvbHNFeCgmaWNjKTsKCgoJLyogcmVnaXN0ZXIgZnJhbWUgd2luZG93IGNsYXNzICovCgoJd2NGcmFtZS5jYlNpemUgICAgICAgID0gc2l6ZW9mKFdORENMQVNTRVgpOwoJd2NGcmFtZS5zdHlsZSAgICAgICAgID0gMDsKCXdjRnJhbWUubHBmblduZFByb2MgICA9IEZyYW1lV25kUHJvYzsKCXdjRnJhbWUuY2JDbHNFeHRyYSAgICA9IDA7Cgl3Y0ZyYW1lLmNiV25kRXh0cmEgICAgPSAwOwoJd2NGcmFtZS5oSW5zdGFuY2UgICAgID0gaGluc3RhbmNlOwoJd2NGcmFtZS5oSWNvbiAgICAgICAgID0gTG9hZEljb24oaGluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSURJX1dJTkVGSUxFKSk7Cgl3Y0ZyYW1lLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yKDAsIElEQ19BUlJPVyk7Cgl3Y0ZyYW1lLmhickJhY2tncm91bmQgPSAwOwoJd2NGcmFtZS5scHN6TWVudU5hbWUgID0gMDsKCXdjRnJhbWUubHBzekNsYXNzTmFtZSA9IHNXSU5FRklMRUZSQU1FOwoJd2NGcmFtZS5oSWNvblNtICAgICAgID0gKEhJQ09OKUxvYWRJbWFnZShoaW5zdGFuY2UsCgkJCQkJCQkJCQkJIE1BS0VJTlRSRVNPVVJDRShJRElfV0lORUZJTEUpLAoJCQkJCQkJCQkJCSBJTUFHRV9JQ09OLAoJCQkJCQkJCQkJCSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU01JQ09OKSwKCQkJCQkJCQkJCQkgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNSUNPTiksCgkJCQkJCQkJCQkJIExSX1NIQVJFRCk7CgoJR2xvYmFscy5oZnJhbWVDbGFzcyA9IFJlZ2lzdGVyQ2xhc3NFeCgmd2NGcmFtZSk7CgoKCS8qIHJlZ2lzdGVyIHRyZWUgd2luZG93cyBjbGFzcyAqLwoKCXdjQ2hpbGQuc3R5bGUgICAgICAgICA9IENTX0NMQVNTREN8Q1NfREJMQ0xLU3xDU19WUkVEUkFXOwoJd2NDaGlsZC5scGZuV25kUHJvYyAgID0gQ2hpbGRXbmRQcm9jOwoJd2NDaGlsZC5jYkNsc0V4dHJhICAgID0gMDsKCXdjQ2hpbGQuY2JXbmRFeHRyYSAgICA9IDA7Cgl3Y0NoaWxkLmhJbnN0YW5jZSAgICAgPSBoaW5zdGFuY2U7Cgl3Y0NoaWxkLmhJY29uICAgICAgICAgPSAwOwoJd2NDaGlsZC5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvcigwLCBJRENfQVJST1cpOwoJd2NDaGlsZC5oYnJCYWNrZ3JvdW5kID0gMDsKCXdjQ2hpbGQubHBzek1lbnVOYW1lICA9IDA7Cgl3Y0NoaWxkLmxwc3pDbGFzc05hbWUgPSBzV0lORUZJTEVUUkVFOwoKCWhDaGlsZENsYXNzID0gUmVnaXN0ZXJDbGFzcygmd2NDaGlsZCk7CgoKCUdsb2JhbHMuaGFjY2VsID0gTG9hZEFjY2VsZXJhdG9ycyhoaW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJREFfV0lORUZJTEUpKTsKCglHbG9iYWxzLmhmb250ID0gQ3JlYXRlRm9udCgtTXVsRGl2KDgsR2V0RGV2aWNlQ2FwcyhoZGMsTE9HUElYRUxTWSksNzIpLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCBzRm9udCk7CgoJUmVsZWFzZURDKDAsIGhkYyk7CgoJR2xvYmFscy5oSW5zdGFuY2UgPSBoaW5zdGFuY2U7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCUNvSW5pdGlhbGl6ZShOVUxMKTsKCUNvR2V0TWFsbG9jKE1FTUNUWF9UQVNLLCAmR2xvYmFscy5pTWFsbG9jKTsKCVNIR2V0RGVza3RvcEZvbGRlcigmR2xvYmFscy5pRGVza3RvcCk7CiNpZmRlZiBfX1dJTkVfXwoJR2xvYmFscy5jZlN0ckZOYW1lID0gUmVnaXN0ZXJDbGlwYm9hcmRGb3JtYXRBKENGU1RSX0ZJTEVOQU1FKTsKI2Vsc2UKCUdsb2JhbHMuY2ZTdHJGTmFtZSA9IFJlZ2lzdGVyQ2xpcGJvYXJkRm9ybWF0KENGU1RSX0ZJTEVOQU1FKTsKI2VuZGlmCiNlbmRpZgoKCS8qIGxvYWQgY29sdW1uIHN0cmluZ3MgKi8KCWNvbCA9IDE7CgoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX05BTUUpOwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX1NJWkUpOwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX0NEQVRFKTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX0FEQVRFKTsKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9NREFURSk7Cglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfSURYKTsKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9MSU5LUyk7CiNlbmRpZgoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX0FUVFIpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfU0VDKTsKI2VuZGlmCn0KCgpzdGF0aWMgdm9pZCBzaG93X2ZyYW1lKEhXTkQgaHduZFBhcmVudCwgaW50IGNtZHNob3csIExQQ1RTVFIgcGF0aCkKewoJc3RhdGljIGNvbnN0IFRDSEFSIHNNRElDTElFTlRbXSA9IHsnTScsJ0QnLCdJJywnQycsJ0wnLCdJJywnRScsJ04nLCdUJywnXDAnfTsKCglUQ0hBUiBidWZmZXJbTUFYX1BBVEhdLCBiMVtCVUZGRVJfTEVOXTsKCUNoaWxkV25kKiBjaGlsZDsKCUhNRU5VIGhNZW51RnJhbWUsIGhNZW51V2luZG93OwoJd2luZG93T3B0aW9ucyBvcHRzOwoKCUNMSUVOVENSRUFURVNUUlVDVCBjY3M7CgoJaWYgKEdsb2JhbHMuaE1haW5XbmQpCgkJcmV0dXJuOwoKCW9wdHMgPSBsb2FkX3JlZ2lzdHJ5X3NldHRpbmdzKCk7CgloTWVudUZyYW1lID0gTG9hZE1lbnUoR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRE1fV0lORUZJTEUpKTsKCWhNZW51V2luZG93ID0gR2V0U3ViTWVudShoTWVudUZyYW1lLCBHZXRNZW51SXRlbUNvdW50KGhNZW51RnJhbWUpLTIpOwoKCUdsb2JhbHMuaE1lbnVGcmFtZSA9IGhNZW51RnJhbWU7CglHbG9iYWxzLmhNZW51VmlldyA9IEdldFN1Yk1lbnUoaE1lbnVGcmFtZSwgMyk7CglHbG9iYWxzLmhNZW51T3B0aW9ucyA9IEdldFN1Yk1lbnUoaE1lbnVGcmFtZSwgNCk7CgoJY2NzLmhXaW5kb3dNZW51ICA9IGhNZW51V2luZG93OwoJY2NzLmlkRmlyc3RDaGlsZCA9IElEV19GSVJTVF9DSElMRDsKCgoJLyogY3JlYXRlIG1haW4gd2luZG93ICovCglHbG9iYWxzLmhNYWluV25kID0gQ3JlYXRlV2luZG93RXgoMCwgKExQQ1RTVFIpKGludClHbG9iYWxzLmhmcmFtZUNsYXNzLCBSUyhiMSxJRFNfV0lORV9GSUxFKSwgV1NfT1ZFUkxBUFBFRFdJTkRPVywKCQkJCQlvcHRzLnN0YXJ0X3gsIG9wdHMuc3RhcnRfeSwgb3B0cy53aWR0aCwgb3B0cy5oZWlnaHQsCgkJCQkJaHduZFBhcmVudCwgR2xvYmFscy5oTWVudUZyYW1lLCBHbG9iYWxzLmhJbnN0YW5jZSwgMC8qbHBQYXJhbSovKTsKCgoJR2xvYmFscy5obWRpY2xpZW50ID0gQ3JlYXRlV2luZG93RXgoMCwgc01ESUNMSUVOVCwgTlVMTCwKCQkJCQlXU19DSElMRHxXU19DTElQQ0hJTERSRU58V1NfVlNDUk9MTHxXU19IU0NST0xMfFdTX1ZJU0lCTEV8V1NfQk9SREVSLAoJCQkJCTAsIDAsIDAsIDAsCgkJCQkJR2xvYmFscy5oTWFpblduZCwgMCwgR2xvYmFscy5oSW5zdGFuY2UsICZjY3MpOwogIAoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgSURfVklFV19EUklWRV9CQVIsIE1GX0JZQ09NTUFORHxNRl9DSEVDS0VEKTsKCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudU9wdGlvbnMsIElEX1ZJRVdfU0FWRVNFVFRJTkdTLCBNRl9CWUNPTU1BTkQpOwoKCWNyZWF0ZV9kcml2ZV9iYXIoKTsKCgl7CgkJVEJCVVRUT04gdG9vbGJhckJ0bnNbXSA9IHsKCQkJezAsIDAsIDAsIEJUTlNfU0VQLCB7MCwgMH0sIDAsIDB9LAoJCQl7MCwgSURfV0lORE9XX05FVywgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKCQkJezEsIElEX1dJTkRPV19DQVNDQURFLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9LAoJCQl7MiwgSURfV0lORE9XX1RJTEVfSE9SWiwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKCQkJezMsIElEX1dJTkRPV19USUxFX1ZFUlQsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH0sCi8qVE9ETwoJCQl7NCwgSURfLi4uICwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKCQkJezUsIElEXy4uLiAsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH0sCiovCQl9OwoKCQlHbG9iYWxzLmh0b29sYmFyID0gQ3JlYXRlVG9vbGJhckV4KEdsb2JhbHMuaE1haW5XbmQsIFdTX0NISUxEfFdTX1ZJU0lCTEUsCgkJCUlEV19UT09MQkFSLCAyLCBHbG9iYWxzLmhJbnN0YW5jZSwgSURCX1RPT0xCQVIsIHRvb2xiYXJCdG5zLAoJCQlzaXplb2YodG9vbGJhckJ0bnMpL3NpemVvZihUQkJVVFRPTiksIDE2LCAxNSwgMTYsIDE1LCBzaXplb2YoVEJCVVRUT04pKTsKCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBJRF9WSUVXX1RPT0xfQkFSLCBNRl9CWUNPTU1BTkR8TUZfQ0hFQ0tFRCk7Cgl9CgoJR2xvYmFscy5oc3RhdHVzYmFyID0gQ3JlYXRlU3RhdHVzV2luZG93KFdTX0NISUxEfFdTX1ZJU0lCTEUsIDAsIEdsb2JhbHMuaE1haW5XbmQsIElEV19TVEFUVVNCQVIpOwoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgSURfVklFV19TVEFUVVNCQVIsIE1GX0JZQ09NTUFORHxNRl9DSEVDS0VEKTsKCi8qIENyZWF0ZVN0YXR1c1dpbmRvdyBkb2VzIG5vdCBhY2NlcHQgV1NfQk9SREVSCglHbG9iYWxzLmhzdGF0dXNiYXIgPSBDcmVhdGVXaW5kb3dFeChXU19FWF9OT1BBUkVOVE5PVElGWSwgU1RBVFVTQ0xBU1NOQU1FLCAwLAoJCQkJCVdTX0NISUxEfFdTX1ZJU0lCTEV8V1NfQ0xJUFNJQkxJTkdTfFdTX0JPUkRFUnxDQ1NfTk9ESVZJREVSLCAwLDAsMCwwLAoJCQkJCUdsb2JhbHMuaE1haW5XbmQsIChITUVOVSlJRFdfU1RBVFVTQkFSLCBoaW5zdGFuY2UsIDApOyovCgoJLypUT0RPOiByZWFkIHBhdGhzIGZyb20gcmVnaXN0cnkgKi8KCglpZiAoIXBhdGggfHwgISpwYXRoKSB7CgkJR2V0Q3VycmVudERpcmVjdG9yeShNQVhfUEFUSCwgYnVmZmVyKTsKCQlwYXRoID0gYnVmZmVyOwoJfQoKCVNob3dXaW5kb3coR2xvYmFscy5oTWFpblduZCwgY21kc2hvdyk7CgojaWYgZGVmaW5lZChfU0hFTExfRk9MREVSUykgJiYgIWRlZmluZWQoX19XSU5FX18pCgkgLyogU2hlbGwgTmFtZXNwYWNlIGFzIGRlZmF1bHQ6ICovCgljaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhwYXRoLCBnZXRfcGF0aF9waWRsKHBhdGgsR2xvYmFscy5oTWFpblduZCksIEdsb2JhbHMuaE1haW5XbmQpOwojZWxzZQoJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgTlVMTCwgR2xvYmFscy5oTWFpblduZCk7CiNlbmRpZgoKCWNoaWxkLT5wb3Muc2hvd0NtZCA9IFNXX1NIT1dNQVhJTUlaRUQ7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ubGVmdCA9IDA7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24udG9wID0gMDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5yaWdodCA9IDMyMDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5ib3R0b20gPSAyODA7CgoJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBjaGlsZCk7CgoJU2V0V2luZG93UGxhY2VtZW50KGNoaWxkLT5od25kLCAmY2hpbGQtPnBvcyk7CgoJR2xvYmFscy5oaW1sID0gSW1hZ2VMaXN0X0xvYWRCaXRtYXAoR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJREJfSU1BR0VTKSwgMTYsIDAsIFJHQigwLDI1NSwwKSk7CgoJR2xvYmFscy5wcmVzY2FuX25vZGUgPSBGQUxTRTsKCglVcGRhdGVXaW5kb3coR2xvYmFscy5oTWFpblduZCk7CgoJaWYgKHBhdGggJiYgcGF0aFswXSkKCXsKCQlpbnQgaW5kZXgsY291bnQ7CgkJVENIQVIgZHJ2W19NQVhfRFJJVkUrMV0sIGRpcltfTUFYX0RJUl0sIG5hbWVbX01BWF9GTkFNRV0sIGV4dFtfTUFYX0VYVF07CgkJVENIQVIgZnVsbG5hbWVbX01BWF9GTkFNRStfTUFYX0VYVCsxXTsKCgkJbWVtc2V0KG5hbWUsMCxzaXplb2YobmFtZSkpOwoJCW1lbXNldChuYW1lLDAsc2l6ZW9mKGV4dCkpOwoJCV90c3BsaXRwYXRoKHBhdGgsIGRydiwgZGlyLCBuYW1lLCBleHQpOwoJCWlmIChuYW1lWzBdKQoJCXsKCQkJY291bnQgPSBTZW5kTWVzc2FnZShjaGlsZC0+cmlnaHQuaHduZCwgTEJfR0VUQ09VTlQsIDAsIDApOwoJCQlsc3RyY3B5KGZ1bGxuYW1lLG5hbWUpOwoJCQlsc3RyY2F0KGZ1bGxuYW1lLGV4dCk7CgoJCQlmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBjb3VudDsgaW5kZXggKyspCgkJCXsKCQkJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIFNlbmRNZXNzYWdlKGNoaWxkLT5yaWdodC5od25kLCBMQl9HRVRJVEVNREFUQSwgaW5kZXgsIDApOwoJCQkJaWYgKGxzdHJjbXAoZW50cnktPmRhdGEuY0ZpbGVOYW1lLGZ1bGxuYW1lKT09MCB8fAoJCQkJCQlsc3RyY21wKGVudHJ5LT5kYXRhLmNBbHRlcm5hdGVGaWxlTmFtZSxmdWxsbmFtZSk9PTApCgkJCQl7CgkJCQkJU2VuZE1lc3NhZ2UoY2hpbGQtPnJpZ2h0Lmh3bmQsIExCX1NFVENVUlNFTCwgaW5kZXgsIDApOwoJCQkJCVNldEZvY3VzKGNoaWxkLT5yaWdodC5od25kKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCX0KfQoKc3RhdGljIHZvaWQgRXhpdEluc3RhbmNlKHZvaWQpCnsKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglJU2hlbGxGb2xkZXJfUmVsZWFzZShHbG9iYWxzLmlEZXNrdG9wKTsKCUlNYWxsb2NfUmVsZWFzZShHbG9iYWxzLmlNYWxsb2MpOwoJQ29VbmluaXRpYWxpemUoKTsKI2VuZGlmCgoJRGVsZXRlT2JqZWN0KEdsb2JhbHMuaGZvbnQpOwoJSW1hZ2VMaXN0X0Rlc3Ryb3koR2xvYmFscy5oaW1sKTsKfQoKI2lmZGVmIF9OT19FWFRFTlNJT05TCgovKiBzZWFyY2ggZm9yIGFscmVhZHkgcnVubmluZyB3aW5bZV1maWxlcyAqLwoKc3RhdGljIGludCBnX2ZvdW5kUHJldkluc3RhbmNlID0gMDsKCnN0YXRpYyBCT09MIENBTExCQUNLIEVudW1XbmRQcm9jKEhXTkQgaHduZCwgTFBBUkFNIGxwYXJhbSkKewoJVENIQVIgY2xzWzEyOF07CgoJR2V0Q2xhc3NOYW1lKGh3bmQsIGNscywgMTI4KTsKCglpZiAoIWxzdHJjbXAoY2xzLCAoTFBDVFNUUilscGFyYW0pKSB7CgkJZ19mb3VuZFByZXZJbnN0YW5jZSsrOwoJCXJldHVybiBGQUxTRTsKCX0KCglyZXR1cm4gVFJVRTsKfQoKLyogc2VhcmNoIGZvciB3aW5kb3cgb2YgZ2l2ZW4gY2xhc3MgbmFtZSB0byBhbGxvdyBvbmx5IG9uZSBydW5uaW5nIGluc3RhbmNlICovCnN0YXRpYyBpbnQgZmluZF93aW5kb3dfY2xhc3MoTFBDVFNUUiBjbGFzc25hbWUpCnsKCUVudW1XaW5kb3dzKEVudW1XbmRQcm9jLCAoTFBBUkFNKWNsYXNzbmFtZSk7CgoJaWYgKGdfZm91bmRQcmV2SW5zdGFuY2UpCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCiNlbmRpZgoKc3RhdGljIGludCB3aW5lZmlsZV9tYWluKEhJTlNUQU5DRSBoaW5zdGFuY2UsIGludCBjbWRzaG93LCBMUENUU1RSIHBhdGgpCnsKCU1TRyBtc2c7CiAgCglJbml0SW5zdGFuY2UoaGluc3RhbmNlKTsKCglzaG93X2ZyYW1lKDAsIGNtZHNob3csIHBhdGgpOwoKCXdoaWxlKEdldE1lc3NhZ2UoJm1zZywgMCwgMCwgMCkpIHsKCQlpZiAoR2xvYmFscy5obWRpY2xpZW50ICYmIFRyYW5zbGF0ZU1ESVN5c0FjY2VsKEdsb2JhbHMuaG1kaWNsaWVudCwgJm1zZykpCgkJCWNvbnRpbnVlOwoKCQlpZiAoR2xvYmFscy5oTWFpblduZCAmJiBUcmFuc2xhdGVBY2NlbGVyYXRvcihHbG9iYWxzLmhNYWluV25kLCBHbG9iYWxzLmhhY2NlbCwgJm1zZykpCgkJCWNvbnRpbnVlOwoKCQlUcmFuc2xhdGVNZXNzYWdlKCZtc2cpOwoJCURpc3BhdGNoTWVzc2FnZSgmbXNnKTsKCX0KCglFeGl0SW5zdGFuY2UoKTsKCglyZXR1cm4gbXNnLndQYXJhbTsKfQoKCiNpZiBkZWZpbmVkKFVOSUNPREUpICYmIGRlZmluZWQoX01TQ19WRVIpCmludCBBUElFTlRSWSB3V2luTWFpbihISU5TVEFOQ0UgaGluc3RhbmNlLCBISU5TVEFOQ0UgcHJldmluc3RhbmNlLCBMUFdTVFIgY21kbGluZSwgaW50IGNtZHNob3cpCiNlbHNlCmludCBBUElFTlRSWSBXaW5NYWluKEhJTlNUQU5DRSBoaW5zdGFuY2UsIEhJTlNUQU5DRSBwcmV2aW5zdGFuY2UsIExQU1RSIGNtZGxpbmUsIGludCBjbWRzaG93KQojZW5kaWYKewojaWZkZWYgX05PX0VYVEVOU0lPTlMKCWlmIChmaW5kX3dpbmRvd19jbGFzcyhzV0lORUZJTEVGUkFNRSkpCgkJcmV0dXJuIDE7CiNlbmRpZgoKI2lmIGRlZmluZWQoVU5JQ09ERSkgJiYgIWRlZmluZWQoX01TQ19WRVIpCgl7IC8qIGNvbnZlcnQgQU5TSSBjbWRsaW5lIGludG8gV0NTIHBhdGggc3RyaW5nICovCglUQ0hBUiBidWZmZXJbTUFYX1BBVEhdOwoJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIGNtZGxpbmUsIC0xLCBidWZmZXIsIE1BWF9QQVRIKTsKCXdpbmVmaWxlX21haW4oaGluc3RhbmNlLCBjbWRzaG93LCBidWZmZXIpOwoJfQojZWxzZQoJd2luZWZpbGVfbWFpbihoaW5zdGFuY2UsIGNtZHNob3csIGNtZGxpbmUpOwojZW5kaWYKCglyZXR1cm4gMDsKfQo=