LyoKICogV2luZWZpbGUKICoKICogQ29weXJpZ2h0IDIwMDAsIDIwMDMsIDIwMDQsIDIwMDUgTWFydGluIEZ1Y2hzCiAqIENvcHlyaWdodCAyMDA2IEphc29uIEdyZWVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpZmRlZiBfX1dJTkVfXwojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKCi8qIGZvciB1bml4IGZpbGVzeXN0ZW0gZnVuY3Rpb24gY2FsbHMgKi8KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPGRpcmVudC5oPgojZW5kaWYKCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgIndpbmVmaWxlLmgiCiNpbmNsdWRlICJyZXNvdXJjZS5oIgoKI2lmZGVmIF9OT19FWFRFTlNJT05TCiN1bmRlZiBfTEVGVF9GSUxFUwojZW5kaWYKCiNpZm5kZWYgX01BWF9QQVRICiNkZWZpbmUgX01BWF9EUklWRSAgICAgICAgICAzCiNkZWZpbmUgX01BWF9GTkFNRSAgICAgICAgICAyNTYKI2RlZmluZSBfTUFYX0RJUiAgICAgICAgICAgIF9NQVhfRk5BTUUKI2RlZmluZSBfTUFYX0VYVCAgICAgICAgICAgIF9NQVhfRk5BTUUKI2RlZmluZSBfTUFYX1BBVEggICAgICAgICAgIDI2MAojZW5kaWYKCiNpZmRlZiBOT05BTUVMRVNTVU5JT04KI2RlZmluZQlVTklPTl9NRU1CRVIoeCkgRFVNTVlVTklPTk5BTUUueAojZWxzZQojZGVmaW5lCVVOSU9OX01FTUJFUih4KSB4CiNlbmRpZgoKCiNpZmRlZiBfU0hFTExfRk9MREVSUwojZGVmaW5lCURFRkFVTFRfU1BMSVRfUE9TCTMwMAojZWxzZQojZGVmaW5lCURFRkFVTFRfU1BMSVRfUE9TCTIwMAojZW5kaWYKCnN0YXRpYyBjb25zdCBXQ0hBUiByZWdpc3RyeV9rZXlbXSA9IHsgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnRicsJ2knLCdsJywnZScsJ1wwJ307CnN0YXRpYyBjb25zdCBXQ0hBUiByZWdfc3RhcnRfeFtdID0geyAncycsJ3QnLCdhJywncicsJ3QnLCdYJywnXDAnfTsKc3RhdGljIGNvbnN0IFdDSEFSIHJlZ19zdGFydF95W10gPSB7ICdzJywndCcsJ2EnLCdyJywndCcsJ1knLCdcMCd9OwpzdGF0aWMgY29uc3QgV0NIQVIgcmVnX3dpZHRoW10gPSB7ICd3JywnaScsJ2QnLCd0JywnaCcsJ1wwJ307CnN0YXRpYyBjb25zdCBXQ0hBUiByZWdfaGVpZ2h0W10gPSB7ICdoJywnZScsJ2knLCdnJywnaCcsJ3QnLCdcMCd9OwpzdGF0aWMgY29uc3QgV0NIQVIgcmVnX2xvZ2ZvbnRbXSA9IHsgJ2wnLCdvJywnZycsJ2YnLCdvJywnbicsJ3QnLCdcMCd9OwoKZW51bSBFTlRSWV9UWVBFIHsKCUVUX1dJTkRPV1MsCglFVF9VTklYLAojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCUVUX1NIRUxMCiNlbmRpZgp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0VudHJ5IHsKCXN0cnVjdCBfRW50cnkqCW5leHQ7CglzdHJ1Y3QgX0VudHJ5Kglkb3duOwoJc3RydWN0IF9FbnRyeSoJdXA7CgoJQk9PTAkJCWV4cGFuZGVkOwoJQk9PTAkJCXNjYW5uZWQ7CglpbnQJCQkJbGV2ZWw7CgoJV0lOMzJfRklORF9EQVRBCWRhdGE7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBiaGZpOwoJQk9PTAkJCWJoZmlfdmFsaWQ7CgllbnVtIEVOVFJZX1RZUEUJZXR5cGU7CiNlbmRpZgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCUxQSVRFTUlETElTVAlwaWRsOwoJSVNoZWxsRm9sZGVyKglmb2xkZXI7CglISUNPTgkJCWhpY29uOwojZW5kaWYKfSBFbnRyeTsKCnR5cGVkZWYgc3RydWN0IHsKCUVudHJ5CWVudHJ5OwoJVENIQVIJcGF0aFtNQVhfUEFUSF07CglUQ0hBUgl2b2xuYW1lW19NQVhfRk5BTUVdOwoJVENIQVIJZnNbX01BWF9ESVJdOwoJRFdPUkQJZHJpdmVfdHlwZTsKCURXT1JECWZzX2ZsYWdzOwp9IFJvb3Q7CgplbnVtIENPTFVNTl9GTEFHUyB7CglDT0xfU0laRQkJPSAweDAxLAoJQ09MX0RBVEUJCT0gMHgwMiwKCUNPTF9USU1FCQk9IDB4MDQsCglDT0xfQVRUUklCVVRFUwk9IDB4MDgsCglDT0xfRE9TTkFNRVMJPSAweDEwLAojaWZkZWYgX05PX0VYVEVOU0lPTlMKCUNPTF9BTEwgPSBDT0xfU0laRXxDT0xfREFURXxDT0xfVElNRXxDT0xfQVRUUklCVVRFU3xDT0xfRE9TTkFNRVMKI2Vsc2UKCUNPTF9JTkRFWAkJPSAweDIwLAoJQ09MX0xJTktTCQk9IDB4NDAsCglDT0xfQUxMID0gQ09MX1NJWkV8Q09MX0RBVEV8Q09MX1RJTUV8Q09MX0FUVFJJQlVURVN8Q09MX0RPU05BTUVTfENPTF9JTkRFWHxDT0xfTElOS1MKI2VuZGlmCn07Cgp0eXBlZGVmIGVudW0gewoJU09SVF9OQU1FLAoJU09SVF9FWFQsCglTT1JUX1NJWkUsCglTT1JUX0RBVEUKfSBTT1JUX09SREVSOwoKdHlwZWRlZiBzdHJ1Y3QgewoJSFdORAlod25kOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglIV05ECWh3bmRIZWFkZXI7CiNlbmRpZgoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwojZGVmaW5lCUNPTFVNTlMJMTAKI2Vsc2UKI2RlZmluZQlDT0xVTU5TCTUKI2VuZGlmCglpbnQJCXdpZHRoc1tDT0xVTU5TXTsKCWludAkJcG9zaXRpb25zW0NPTFVNTlMrMV07CgoJQk9PTAl0cmVlUGFuZTsKCWludAkJdmlzaWJsZV9jb2xzOwoJRW50cnkqCXJvb3Q7CglFbnRyeSoJY3VyOwp9IFBhbmU7Cgp0eXBlZGVmIHN0cnVjdCB7CglIV05ECWh3bmQ7CglQYW5lCWxlZnQ7CglQYW5lCXJpZ2h0OwoJaW50CQlmb2N1c19wYW5lOwkJLyogMDogbGVmdCAgMTogcmlnaHQgKi8KCVdJTkRPV1BMQUNFTUVOVCBwb3M7CglpbnQJCXNwbGl0X3BvczsKCUJPT0wJaGVhZGVyX3dkdGhzX29rOwoKCVRDSEFSCXBhdGhbTUFYX1BBVEhdOwoJVENIQVIJZmlsdGVyX3BhdHRlcm5bTUFYX1BBVEhdOwoJaW50CQlmaWx0ZXJfZmxhZ3M7CglSb290CXJvb3Q7CgoJU09SVF9PUkRFUiBzb3J0T3JkZXI7Cn0gQ2hpbGRXbmQ7CgoKCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5KEVudHJ5KiBkaXIsIExQQ1RTVFIgcGF0aCwgU09SVF9PUkRFUiBzb3J0T3JkZXIsIEhXTkQgaHduZCk7CnN0YXRpYyB2b2lkIHNldF9jdXJkaXIoQ2hpbGRXbmQqIGNoaWxkLCBFbnRyeSogZW50cnksIGludCBpZHgsIEhXTkQgaHduZCk7CnN0YXRpYyB2b2lkIHJlZnJlc2hfY2hpbGQoQ2hpbGRXbmQqIGNoaWxkKTsKc3RhdGljIHZvaWQgcmVmcmVzaF9kcml2ZXModm9pZCk7CnN0YXRpYyB2b2lkIGdldF9wYXRoKEVudHJ5KiBkaXIsIFBUU1RSIHBhdGgpOwpzdGF0aWMgdm9pZCBmb3JtYXRfZGF0ZShjb25zdCBGSUxFVElNRSogZnQsIFRDSEFSKiBidWZmZXIsIGludCB2aXNpYmxlX2NvbHMpOwoKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgRnJhbWVXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKTsKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgQ2hpbGRXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKTsKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgVHJlZVduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pOwoKCi8qIGdsb2JhbHMgKi8KV0lORUZJTEVfR0xPQkFMUyBHbG9iYWxzOwoKc3RhdGljIGludCBsYXN0X3NwbGl0OwoKLyogc29tZSBjb21tb24gc3RyaW5nIGNvbnN0YW50cyAqLwpzdGF0aWMgY29uc3QgVENIQVIgc0VtcHR5W10gPSB7J1wwJ307CnN0YXRpYyBjb25zdCBXQ0hBUiBzU3BhY2VbXSA9IHsnICcsICdcMCd9OwpzdGF0aWMgY29uc3QgVENIQVIgc051bUZtdFtdID0geyclJywnZCcsJ1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzUU1hcmtzW10gPSB7Jz8nLCc/JywnPycsJ1wwJ307CgovKiB3aW5kb3cgY2xhc3MgbmFtZXMgKi8Kc3RhdGljIGNvbnN0IFRDSEFSIHNXSU5FRklMRUZSQU1FW10gPSB7J1cnLCdGJywnUycsJ18nLCdGJywncicsJ2EnLCdtJywnZScsJ1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzV0lORUZJTEVUUkVFW10gPSB7J1cnLCdGJywnUycsJ18nLCdUJywncicsJ2UnLCdlJywnXDAnfTsKCnN0YXRpYyBjb25zdCBUQ0hBUiBzTG9uZ0hleEZtdFtdID0geyclJywnSScsJzYnLCc0JywnWCcsJ1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzTG9uZ051bUZtdFtdID0geyclJywnSScsJzYnLCc0JywndScsJ1wwJ307CgoKLyogbG9hZCByZXNvdXJjZSBzdHJpbmcgKi8Kc3RhdGljIExQVFNUUiBsb2FkX3N0cmluZyhMUFRTVFIgYnVmZmVyLCBVSU5UIGlkKQp7CglMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBpZCwgYnVmZmVyLCBCVUZGRVJfTEVOKTsKCglyZXR1cm4gYnVmZmVyOwp9CgojZGVmaW5lIFJTKGIsIGkpIGxvYWRfc3RyaW5nKGIsIGkpCgoKLyogZGlzcGxheSBlcnJvciBtZXNzYWdlIGZvciB0aGUgc3BlY2lmaWVkIFdJTjMyIGVycm9yIGNvZGUgKi8Kc3RhdGljIHZvaWQgZGlzcGxheV9lcnJvcihIV05EIGh3bmQsIERXT1JEIGVycm9yKQp7CglUQ0hBUiBiMVtCVUZGRVJfTEVOXSwgYjJbQlVGRkVSX0xFTl07CglQVFNUUiBtc2c7CgoJaWYgKEZvcm1hdE1lc3NhZ2UoRk9STUFUX01FU1NBR0VfQUxMT0NBVEVfQlVGRkVSfEZPUk1BVF9NRVNTQUdFX0ZST01fU1lTVEVNLAoJCTAsIGVycm9yLCBNQUtFTEFOR0lEKExBTkdfTkVVVFJBTCxTVUJMQU5HX0RFRkFVTFQpLCAoUFRTVFIpJm1zZywgMCwgTlVMTCkpCgkJTWVzc2FnZUJveChod25kLCBtc2csIFJTKGIyLElEU19XSU5FRklMRSksIE1CX09LKTsKCWVsc2UKCQlNZXNzYWdlQm94KGh3bmQsIFJTKGIxLElEU19FUlJPUiksIFJTKGIyLElEU19XSU5FRklMRSksIE1CX09LKTsKCglMb2NhbEZyZWUobXNnKTsKfQoKCi8qIGRpc3BsYXkgbmV0d29yayBlcnJvciBtZXNzYWdlIHVzaW5nIFdOZXRHZXRMYXN0RXJyb3IoKSAqLwpzdGF0aWMgdm9pZCBkaXNwbGF5X25ldHdvcmtfZXJyb3IoSFdORCBod25kKQp7CglUQ0hBUiBtc2dbQlVGRkVSX0xFTl0sIHByb3ZpZGVyW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCURXT1JEIGVycm9yOwoKCWlmIChXTmV0R2V0TGFzdEVycm9yKCZlcnJvciwgbXNnLCBCVUZGRVJfTEVOLCBwcm92aWRlciwgQlVGRkVSX0xFTikgPT0gTk9fRVJST1IpCgkJTWVzc2FnZUJveChod25kLCBtc2csIFJTKGIyLElEU19XSU5FRklMRSksIE1CX09LKTsKfQoKc3RhdGljIGlubGluZSBCT09MIGdldF9jaGVjayhIV05EIGh3bmQsIElOVCBpZCkKewoJcmV0dXJuIEJTVF9DSEVDS0VEJlNlbmRNZXNzYWdlVyhHZXREbGdJdGVtKGh3bmQsIGlkKSwgQk1fR0VUU1RBVEUsIDAsIDApOwp9CgpzdGF0aWMgaW5saW5lIElOVCBzZXRfY2hlY2soSFdORCBod25kLCBJTlQgaWQsIEJPT0wgb24pCnsKCXJldHVybiBTZW5kTWVzc2FnZVcoR2V0RGxnSXRlbShod25kLCBpZCksIEJNX1NFVENIRUNLLCBvbj9CU1RfQ0hFQ0tFRDpCU1RfVU5DSEVDS0VELCAwKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIGNob29zZV9mb250KEhXTkQgaHduZCkKewogICAgICAgIFdDSEFSIGRsZ19uYW1lW0JVRkZFUl9MRU5dLCBkbGdfaW5mb1tCVUZGRVJfTEVOXTsKICAgICAgICBDSE9PU0VGT05UVyBjaEZvbnQ7CiAgICAgICAgTE9HRk9OVFcgbEZvbnQ7CgogICAgICAgIEhEQyBoZGMgPSBHZXREQyhod25kKTsKICAgICAgICBjaEZvbnQubFN0cnVjdFNpemUgPSBzaXplb2YoQ0hPT1NFRk9OVCk7CiAgICAgICAgY2hGb250Lmh3bmRPd25lciA9IGh3bmQ7CiAgICAgICAgY2hGb250LmhEQyA9IE5VTEw7CiAgICAgICAgY2hGb250LmxwTG9nRm9udCA9ICZsRm9udDsKICAgICAgICBjaEZvbnQuRmxhZ3MgPSBDRl9TQ1JFRU5GT05UUyB8IENGX0ZPUkNFRk9OVEVYSVNUIHwgQ0ZfTElNSVRTSVpFIHwgQ0ZfTk9TQ1JJUFRTRUw7CiAgICAgICAgY2hGb250LnJnYkNvbG9ycyA9IFJHQigwLDAsMCk7CiAgICAgICAgY2hGb250LmxDdXN0RGF0YSA9IDA7CiAgICAgICAgY2hGb250LmxwZm5Ib29rID0gTlVMTDsKICAgICAgICBjaEZvbnQubHBUZW1wbGF0ZU5hbWUgPSBOVUxMOwogICAgICAgIGNoRm9udC5oSW5zdGFuY2UgPSBHbG9iYWxzLmhJbnN0YW5jZTsKICAgICAgICBjaEZvbnQubHBzelN0eWxlID0gTlVMTDsKICAgICAgICBjaEZvbnQubkZvbnRUeXBlID0gU0lNVUxBVEVEX0ZPTlRUWVBFOwogICAgICAgIGNoRm9udC5uU2l6ZU1pbiA9IDA7CiAgICAgICAgY2hGb250Lm5TaXplTWF4ID0gMjQ7CgogICAgICAgIGlmIChDaG9vc2VGb250VygmY2hGb250KSkgewogICAgICAgICAgICAgICAgSFdORCBjaGlsZFduZDsKICAgICAgICAgICAgICAgIEhGT05UIGhGb250T2xkOwoKICAgICAgICAgICAgICAgIERlbGV0ZU9iamVjdChHbG9iYWxzLmhmb250KTsKICAgICAgICAgICAgICAgIEdsb2JhbHMuaGZvbnQgPSBDcmVhdGVGb250SW5kaXJlY3RXKCZsRm9udCk7CiAgICAgICAgICAgICAgICBoRm9udE9sZCA9IFNlbGVjdE9iamVjdChoZGMsIEdsb2JhbHMuaGZvbnQpOwogICAgICAgICAgICAgICAgR2V0VGV4dEV4dGVudFBvaW50MzJXKGhkYywgc1NwYWNlLCAxLCAmR2xvYmFscy5zcGFjZVNpemUpOwoKICAgICAgICAgICAgICAgIC8qIGNoYW5nZSBmb250IGluIGFsbCBvcGVuIGNoaWxkIHdpbmRvd3MgKi8KICAgICAgICAgICAgICAgIGZvcihjaGlsZFduZD1HZXRXaW5kb3coR2xvYmFscy5obWRpY2xpZW50LEdXX0NISUxEKTsgY2hpbGRXbmQ7IGNoaWxkV25kPUdldE5leHRXaW5kb3coY2hpbGRXbmQsR1dfSFdORE5FWFQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIENoaWxkV25kKiBjaGlsZCA9IChDaGlsZFduZCopIEdldFdpbmRvd0xvbmdQdHJXKGNoaWxkV25kLCBHV0xQX1VTRVJEQVRBKTsKICAgICAgICAgICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VXKGNoaWxkLT5sZWZ0Lmh3bmQsIFdNX1NFVEZPTlQsIChXUEFSQU0pR2xvYmFscy5oZm9udCwgVFJVRSk7CiAgICAgICAgICAgICAgICAgICAgICAgIFNlbmRNZXNzYWdlVyhjaGlsZC0+cmlnaHQuaHduZCwgV01fU0VURk9OVCwgKFdQQVJBTSlHbG9iYWxzLmhmb250LCBUUlVFKTsKICAgICAgICAgICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VXKGNoaWxkLT5sZWZ0Lmh3bmQsIExCX1NFVElURU1IRUlHSFQsIDEsIG1heChHbG9iYWxzLnNwYWNlU2l6ZS5jeSxJTUFHRV9IRUlHSFQrMykpOwogICAgICAgICAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZVcoY2hpbGQtPnJpZ2h0Lmh3bmQsIExCX1NFVElURU1IRUlHSFQsIDEsIG1heChHbG9iYWxzLnNwYWNlU2l6ZS5jeSxJTUFHRV9IRUlHSFQrMykpOwogICAgICAgICAgICAgICAgICAgICAgICBJbnZhbGlkYXRlUmVjdChjaGlsZC0+bGVmdC5od25kLCBOVUxMLCBUUlVFKTsKICAgICAgICAgICAgICAgICAgICAgICAgSW52YWxpZGF0ZVJlY3QoY2hpbGQtPnJpZ2h0Lmh3bmQsIE5VTEwsIFRSVUUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIFNlbGVjdE9iamVjdChoZGMsIGhGb250T2xkKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoQ29tbURsZ0V4dGVuZGVkRXJyb3IoKSkgewogICAgICAgICAgICAgICAgTG9hZFN0cmluZ1coR2xvYmFscy5oSW5zdGFuY2UsIElEU19GT05UX1NFTF9ETEdfTkFNRSwgZGxnX25hbWUsIEJVRkZFUl9MRU4pOwogICAgICAgICAgICAgICAgTG9hZFN0cmluZ1coR2xvYmFscy5oSW5zdGFuY2UsIElEU19GT05UX1NFTF9FUlJPUiwgZGxnX2luZm8sIEJVRkZFUl9MRU4pOwogICAgICAgICAgICAgICAgTWVzc2FnZUJveFcoaHduZCwgZGxnX2luZm8sIGRsZ19uYW1lLCBNQl9PSyk7CiAgICAgICAgfQoKICAgICAgICBSZWxlYXNlREMoaHduZCwgaGRjKTsKfQoKI2lmZGVmIF9fV0lORV9fCgojaWZkZWYgVU5JQ09ERQoKLyogY2FsbCB2c3dwcmludGYoKSBpbiBtc3ZjcnQuZGxsICovCi8qVE9ETzogZml4IHN3cHJpbnRmKCkgaW4gbm9uLW1zdmNydCBtb2RlLCBzbyB0aGF0IHRoaXMgZHluYW1pYyBsaW5raW5nIGZ1bmN0aW9uIGNhbiBiZSByZW1vdmVkICovCnN0YXRpYyBpbnQgbXN2Y3J0X3N3cHJpbnRmKFdDSEFSKiBidWZmZXIsIGNvbnN0IFdDSEFSKiBmbXQsIC4uLikKewoJc3RhdGljIGludCAoX19jZGVjbCAqcHZzd3ByaW50ZikoV0NIQVIqLCBjb25zdCBXQ0hBUiosIHZhX2xpc3QpID0gTlVMTDsKCXZhX2xpc3QgYXA7CglpbnQgcmV0OwoKCWlmICghcHZzd3ByaW50ZikgewoJCUhNT0RVTEUgaE1vZE1zdmNydCA9IExvYWRMaWJyYXJ5QSgibXN2Y3J0Iik7CgkJcHZzd3ByaW50ZiA9IChpbnQoX19jZGVjbCopKFdDSEFSKixjb25zdCBXQ0hBUiosdmFfbGlzdCkpIEdldFByb2NBZGRyZXNzKGhNb2RNc3ZjcnQsICJ2c3dwcmludGYiKTsKCX0KCgl2YV9zdGFydChhcCwgZm10KTsKCXJldCA9ICgqcHZzd3ByaW50ZikoYnVmZmVyLCBmbXQsIGFwKTsKCXZhX2VuZChhcCk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIExQQ1dTVFIgbXlfd2NzcmNocihMUENXU1RSIHN0ciwgV0NIQVIgYykKewoJTFBDV1NUUiBwID0gc3RyOwoKCXdoaWxlKCpwKQoJCSsrcDsKCglkbyB7CgkJaWYgKC0tcCA8IHN0cikKCQkJcmV0dXJuIE5VTEw7Cgl9IHdoaWxlKCpwICE9IGMpOwoKCXJldHVybiBwOwp9CgojZGVmaW5lIF90Y3NyY2hyIG15X3djc3JjaHIKI2Vsc2UJLyogVU5JQ09ERSAqLwojZGVmaW5lIF90Y3NyY2hyIHN0cnJjaHIKI2VuZGlmCS8qIFVOSUNPREUgKi8KCiNlbmRpZgkvKiBfX1dJTkVfXyAqLwoKCi8qIGFsbG9jYXRlIGFuZCBpbml0aWFsaXNlIGEgZGlyZWN0b3J5IGVudHJ5ICovCnN0YXRpYyBFbnRyeSogYWxsb2NfZW50cnkodm9pZCkKewoJRW50cnkqIGVudHJ5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihFbnRyeSkpOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgllbnRyeS0+cGlkbCA9IE5VTEw7CgllbnRyeS0+Zm9sZGVyID0gTlVMTDsKCWVudHJ5LT5oaWNvbiA9IDA7CiNlbmRpZgoKCXJldHVybiBlbnRyeTsKfQoKLyogZnJlZSBhIGRpcmVjdG9yeSBlbnRyeSAqLwpzdGF0aWMgdm9pZCBmcmVlX2VudHJ5KEVudHJ5KiBlbnRyeSkKewojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChlbnRyeS0+aGljb24gJiYgZW50cnktPmhpY29uIT0oSElDT04pLTEpCgkJRGVzdHJveUljb24oZW50cnktPmhpY29uKTsKCglpZiAoZW50cnktPmZvbGRlciAmJiBlbnRyeS0+Zm9sZGVyIT1HbG9iYWxzLmlEZXNrdG9wKQoJCUlTaGVsbEZvbGRlcl9SZWxlYXNlKGVudHJ5LT5mb2xkZXIpOwoKCWlmIChlbnRyeS0+cGlkbCkKCQlJTWFsbG9jX0ZyZWUoR2xvYmFscy5pTWFsbG9jLCBlbnRyeS0+cGlkbCk7CiNlbmRpZgoKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGVudHJ5KTsKfQoKLyogcmVjdXJzaXZlbHkgZnJlZSBhbGwgY2hpbGQgZW50cmllcyAqLwpzdGF0aWMgdm9pZCBmcmVlX2VudHJpZXMoRW50cnkqIGRpcikKewoJRW50cnkgKmVudHJ5LCAqbmV4dD1kaXItPmRvd247CgoJaWYgKG5leHQpIHsKCQlkaXItPmRvd24gPSAwOwoKCQlkbyB7CgkJCWVudHJ5ID0gbmV4dDsKCQkJbmV4dCA9IGVudHJ5LT5uZXh0OwoKCQkJZnJlZV9lbnRyaWVzKGVudHJ5KTsKCQkJZnJlZV9lbnRyeShlbnRyeSk7CgkJfSB3aGlsZShuZXh0KTsKCX0KfQoKCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5X3dpbihFbnRyeSogZGlyLCBMUENUU1RSIHBhdGgpCnsKCUVudHJ5KiBmaXJzdF9lbnRyeSA9IE5VTEw7CglFbnRyeSogbGFzdCA9IE5VTEw7CglFbnRyeSogZW50cnk7CgoJaW50IGxldmVsID0gZGlyLT5sZXZlbCArIDE7CglXSU4zMl9GSU5EX0RBVEEgdzMyZmQ7CglIQU5ETEUgaEZpbmQ7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCUhBTkRMRSBoRmlsZTsKI2VuZGlmCgoJVENIQVIgYnVmZmVyW01BWF9QQVRIXSwgKnA7Cglmb3IocD1idWZmZXI7ICpwYXRoOyApCgkJKnArKyA9ICpwYXRoKys7CgoJKnArKyA9ICdcXCc7CglwWzBdID0gJyonOwoJcFsxXSA9ICdcMCc7CgoJaEZpbmQgPSBGaW5kRmlyc3RGaWxlKGJ1ZmZlciwgJnczMmZkKTsKCglpZiAoaEZpbmQgIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHsKCQlkbyB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkvKiBoaWRlIGRpcmVjdG9yeSBlbnRyeSAiLiIgKi8KCQkJaWYgKHczMmZkLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQkJCUxQQ1RTVFIgbmFtZSA9IHczMmZkLmNGaWxlTmFtZTsKCgkJCQlpZiAobmFtZVswXT09Jy4nICYmIG5hbWVbMV09PSdcMCcpCgkJCQkJY29udGludWU7CgkJCX0KI2VuZGlmCgkJCWVudHJ5ID0gYWxsb2NfZW50cnkoKTsKCgkJCWlmICghZmlyc3RfZW50cnkpCgkJCQlmaXJzdF9lbnRyeSA9IGVudHJ5OwoKCQkJaWYgKGxhc3QpCgkJCQlsYXN0LT5uZXh0ID0gZW50cnk7CgoJCQltZW1jcHkoJmVudHJ5LT5kYXRhLCAmdzMyZmQsIHNpemVvZihXSU4zMl9GSU5EX0RBVEEpKTsKCQkJZW50cnktPmRvd24gPSBOVUxMOwoJCQllbnRyeS0+dXAgPSBkaXI7CgkJCWVudHJ5LT5leHBhbmRlZCA9IEZBTFNFOwoJCQllbnRyeS0+c2Nhbm5lZCA9IEZBTFNFOwoJCQllbnRyeS0+bGV2ZWwgPSBsZXZlbDsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJZW50cnktPmV0eXBlID0gRVRfV0lORE9XUzsKCQkJZW50cnktPmJoZmlfdmFsaWQgPSBGQUxTRTsKCgkJCWxzdHJjcHkocCwgZW50cnktPmRhdGEuY0ZpbGVOYW1lKTsKCgkJCWhGaWxlID0gQ3JlYXRlRmlsZShidWZmZXIsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFEfEZJTEVfU0hBUkVfV1JJVEV8RklMRV9TSEFSRV9ERUxFVEUsCgkJCQkJCQkJMCwgT1BFTl9FWElTVElORywgRklMRV9GTEFHX0JBQ0tVUF9TRU1BTlRJQ1MsIDApOwoKCQkJaWYgKGhGaWxlICE9IElOVkFMSURfSEFORExFX1ZBTFVFKSB7CgkJCQlpZiAoR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaEZpbGUsICZlbnRyeS0+YmhmaSkpCgkJCQkJZW50cnktPmJoZmlfdmFsaWQgPSBUUlVFOwoKCQkJCUNsb3NlSGFuZGxlKGhGaWxlKTsKCQkJfQojZW5kaWYKCgkJCWxhc3QgPSBlbnRyeTsKCQl9IHdoaWxlKEZpbmROZXh0RmlsZShoRmluZCwgJnczMmZkKSk7CgoJCWlmIChsYXN0KQoJCQlsYXN0LT5uZXh0ID0gTlVMTDsKCgkJRmluZENsb3NlKGhGaW5kKTsKCX0KCglkaXItPmRvd24gPSBmaXJzdF9lbnRyeTsKCWRpci0+c2Nhbm5lZCA9IFRSVUU7Cn0KCgpzdGF0aWMgRW50cnkqIGZpbmRfZW50cnlfd2luKEVudHJ5KiBkaXIsIExQQ1RTVFIgbmFtZSkKewoJRW50cnkqIGVudHJ5OwoKCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkgewoJCUxQQ1RTVFIgcCA9IG5hbWU7CgkJTFBDVFNUUiBxID0gZW50cnktPmRhdGEuY0ZpbGVOYW1lOwoKCQlkbyB7CgkJCWlmICghKnAgfHwgKnAgPT0gJ1xcJyB8fCAqcCA9PSAnLycpCgkJCQlyZXR1cm4gZW50cnk7CgkJfSB3aGlsZSh0b2xvd2VyKCpwKyspID09IHRvbG93ZXIoKnErKykpOwoKCQlwID0gbmFtZTsKCQlxID0gZW50cnktPmRhdGEuY0FsdGVybmF0ZUZpbGVOYW1lOwoKCQlkbyB7CgkJCWlmICghKnAgfHwgKnAgPT0gJ1xcJyB8fCAqcCA9PSAnLycpCgkJCQlyZXR1cm4gZW50cnk7CgkJfSB3aGlsZSh0b2xvd2VyKCpwKyspID09IHRvbG93ZXIoKnErKykpOwoJfQoKCXJldHVybiAwOwp9CgoKc3RhdGljIEVudHJ5KiByZWFkX3RyZWVfd2luKFJvb3QqIHJvb3QsIExQQ1RTVFIgcGF0aCwgU09SVF9PUkRFUiBzb3J0T3JkZXIsIEhXTkQgaHduZCkKewoJVENIQVIgYnVmZmVyW01BWF9QQVRIXTsKCUVudHJ5KiBlbnRyeSA9ICZyb290LT5lbnRyeTsKCUxQQ1RTVFIgcyA9IHBhdGg7CglQVFNUUiBkID0gYnVmZmVyOwoKCUhDVVJTT1Igb2xkX2N1cnNvciA9IFNldEN1cnNvcihMb2FkQ3Vyc29yKDAsIElEQ19XQUlUKSk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgllbnRyeS0+ZXR5cGUgPSBFVF9XSU5ET1dTOwojZW5kaWYKCgl3aGlsZShlbnRyeSkgewoJCXdoaWxlKCpzICYmICpzICE9ICdcXCcgJiYgKnMgIT0gJy8nKQoJCQkqZCsrID0gKnMrKzsKCgkJd2hpbGUoKnMgPT0gJ1xcJyB8fCAqcyA9PSAnLycpCgkJCXMrKzsKCgkJKmQrKyA9ICdcXCc7CgkJKmQgPSAnXDAnOwoKCQlyZWFkX2RpcmVjdG9yeShlbnRyeSwgYnVmZmVyLCBzb3J0T3JkZXIsIGh3bmQpOwoKCQlpZiAoZW50cnktPmRvd24pCgkJCWVudHJ5LT5leHBhbmRlZCA9IFRSVUU7CgoJCWlmICghKnMpCgkJCWJyZWFrOwoKCQllbnRyeSA9IGZpbmRfZW50cnlfd2luKGVudHJ5LCBzKTsKCX0KCglTZXRDdXJzb3Iob2xkX2N1cnNvcik7CgoJcmV0dXJuIGVudHJ5Owp9CgoKI2lmICFkZWZpbmVkKF9OT19FWFRFTlNJT05TKSAmJiBkZWZpbmVkKF9fV0lORV9fKQoKc3RhdGljIEJPT0wgdGltZV90b19maWxldGltZShjb25zdCB0aW1lX3QqIHQsIEZJTEVUSU1FKiBmdGltZSkKewoJc3RydWN0IHRtKiB0bSA9IGdtdGltZSh0KTsKCVNZU1RFTVRJTUUgc3RpbWU7CgoJaWYgKCF0bSkKCQlyZXR1cm4gRkFMU0U7CgoJc3RpbWUud1llYXIgPSB0bS0+dG1feWVhcisxOTAwOwoJc3RpbWUud01vbnRoID0gdG0tPnRtX21vbisxOwoJLyoJc3RpbWUud0RheU9mV2VlayAqLwoJc3RpbWUud0RheSA9IHRtLT50bV9tZGF5OwoJc3RpbWUud0hvdXIgPSB0bS0+dG1faG91cjsKCXN0aW1lLndNaW51dGUgPSB0bS0+dG1fbWluOwoJc3RpbWUud1NlY29uZCA9IHRtLT50bV9zZWM7CgoJcmV0dXJuIFN5c3RlbVRpbWVUb0ZpbGVUaW1lKCZzdGltZSwgZnRpbWUpOwp9CgpzdGF0aWMgdm9pZCByZWFkX2RpcmVjdG9yeV91bml4KEVudHJ5KiBkaXIsIExQQ1RTVFIgcGF0aCkKewoJRW50cnkqIGZpcnN0X2VudHJ5ID0gTlVMTDsKCUVudHJ5KiBsYXN0ID0gTlVMTDsKCUVudHJ5KiBlbnRyeTsKCURJUiogcGRpcjsKCglpbnQgbGV2ZWwgPSBkaXItPmxldmVsICsgMTsKI2lmZGVmIFVOSUNPREUKCWNoYXIgY3BhdGhbTUFYX1BBVEhdOwoKCVdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfVU5JWENQLCAwLCBwYXRoLCAtMSwgY3BhdGgsIE1BWF9QQVRILCBOVUxMLCBOVUxMKTsKI2Vsc2UKCWNvbnN0IGNoYXIqIGNwYXRoID0gcGF0aDsKI2VuZGlmCgoJcGRpciA9IG9wZW5kaXIoY3BhdGgpOwoKCWlmIChwZGlyKSB7CgkJc3RydWN0IHN0YXQgc3Q7CgkJc3RydWN0IGRpcmVudCogZW50OwoJCWNoYXIgYnVmZmVyW01BWF9QQVRIXSwgKnA7CgkJY29uc3QgY2hhciogczsKCgkJZm9yKHA9YnVmZmVyLHM9Y3BhdGg7ICpzOyApCgkJCSpwKysgPSAqcysrOwoKCQlpZiAocD09YnVmZmVyIHx8IHBbLTFdIT0nLycpCgkJCSpwKysgPSAnLyc7CgoJCXdoaWxlKChlbnQ9cmVhZGRpcihwZGlyKSkpIHsKCQkJZW50cnkgPSBhbGxvY19lbnRyeSgpOwoKCQkJaWYgKCFmaXJzdF9lbnRyeSkKCQkJCWZpcnN0X2VudHJ5ID0gZW50cnk7CgoJCQlpZiAobGFzdCkKCQkJCWxhc3QtPm5leHQgPSBlbnRyeTsKCgkJCWVudHJ5LT5ldHlwZSA9IEVUX1VOSVg7CgoJCQlzdHJjcHkocCwgZW50LT5kX25hbWUpOwojaWZkZWYgVU5JQ09ERQoJCQlNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX1VOSVhDUCwgMCwgcCwgLTEsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSwgTUFYX1BBVEgpOwojZWxzZQoJCQlsc3RyY3B5KGVudHJ5LT5kYXRhLmNGaWxlTmFtZSwgcCk7CiNlbmRpZgoKCQkJaWYgKCFzdGF0KGJ1ZmZlciwgJnN0KSkgewoJCQkJZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyA9IHBbMF09PScuJz8gRklMRV9BVFRSSUJVVEVfSElEREVOOiAwOwoKCQkJCWlmIChTX0lTRElSKHN0LnN0X21vZGUpKQoJCQkJCWVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgfD0gRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZOwoKCQkJCWVudHJ5LT5kYXRhLm5GaWxlU2l6ZUxvdyA9IHN0LnN0X3NpemUgJiAweEZGRkZGRkZGOwoJCQkJZW50cnktPmRhdGEubkZpbGVTaXplSGlnaCA9IHN0LnN0X3NpemUgPj4gMzI7CgoJCQkJbWVtc2V0KCZlbnRyeS0+ZGF0YS5mdENyZWF0aW9uVGltZSwgMCwgc2l6ZW9mKEZJTEVUSU1FKSk7CgkJCQl0aW1lX3RvX2ZpbGV0aW1lKCZzdC5zdF9hdGltZSwgJmVudHJ5LT5kYXRhLmZ0TGFzdEFjY2Vzc1RpbWUpOwoJCQkJdGltZV90b19maWxldGltZSgmc3Quc3RfbXRpbWUsICZlbnRyeS0+ZGF0YS5mdExhc3RXcml0ZVRpbWUpOwoKCQkJCWVudHJ5LT5iaGZpLm5GaWxlSW5kZXhMb3cgPSBlbnQtPmRfaW5vOwoJCQkJZW50cnktPmJoZmkubkZpbGVJbmRleEhpZ2ggPSAwOwoKCQkJCWVudHJ5LT5iaGZpLm5OdW1iZXJPZkxpbmtzID0gc3Quc3Rfbmxpbms7CgoJCQkJZW50cnktPmJoZmlfdmFsaWQgPSBUUlVFOwoJCQl9IGVsc2UgewoJCQkJZW50cnktPmRhdGEubkZpbGVTaXplTG93ID0gMDsKCQkJCWVudHJ5LT5kYXRhLm5GaWxlU2l6ZUhpZ2ggPSAwOwoJCQkJZW50cnktPmJoZmlfdmFsaWQgPSBGQUxTRTsKCQkJfQoKCQkJZW50cnktPmRvd24gPSBOVUxMOwoJCQllbnRyeS0+dXAgPSBkaXI7CgkJCWVudHJ5LT5leHBhbmRlZCA9IEZBTFNFOwoJCQllbnRyeS0+c2Nhbm5lZCA9IEZBTFNFOwoJCQllbnRyeS0+bGV2ZWwgPSBsZXZlbDsKCgkJCWxhc3QgPSBlbnRyeTsKCQl9CgoJCWlmIChsYXN0KQoJCQlsYXN0LT5uZXh0ID0gTlVMTDsKCgkJY2xvc2VkaXIocGRpcik7Cgl9CgoJZGlyLT5kb3duID0gZmlyc3RfZW50cnk7CglkaXItPnNjYW5uZWQgPSBUUlVFOwp9CgpzdGF0aWMgRW50cnkqIGZpbmRfZW50cnlfdW5peChFbnRyeSogZGlyLCBMUENUU1RSIG5hbWUpCnsKCUVudHJ5KiBlbnRyeTsKCglmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpIHsKCQlMUENUU1RSIHAgPSBuYW1lOwoJCUxQQ1RTVFIgcSA9IGVudHJ5LT5kYXRhLmNGaWxlTmFtZTsKCgkJZG8gewoJCQlpZiAoISpwIHx8ICpwID09ICcvJykKCQkJCXJldHVybiBlbnRyeTsKCQl9IHdoaWxlKCpwKysgPT0gKnErKyk7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBFbnRyeSogcmVhZF90cmVlX3VuaXgoUm9vdCogcm9vdCwgTFBDVFNUUiBwYXRoLCBTT1JUX09SREVSIHNvcnRPcmRlciwgSFdORCBod25kKQp7CglUQ0hBUiBidWZmZXJbTUFYX1BBVEhdOwoJRW50cnkqIGVudHJ5ID0gJnJvb3QtPmVudHJ5OwoJTFBDVFNUUiBzID0gcGF0aDsKCVBUU1RSIGQgPSBidWZmZXI7CgoJSENVUlNPUiBvbGRfY3Vyc29yID0gU2V0Q3Vyc29yKExvYWRDdXJzb3IoMCwgSURDX1dBSVQpKTsKCgllbnRyeS0+ZXR5cGUgPSBFVF9VTklYOwoKCXdoaWxlKGVudHJ5KSB7CgkJd2hpbGUoKnMgJiYgKnMgIT0gJy8nKQoJCQkqZCsrID0gKnMrKzsKCgkJd2hpbGUoKnMgPT0gJy8nKQoJCQlzKys7CgoJCSpkKysgPSAnLyc7CgkJKmQgPSAnXDAnOwoKCQlyZWFkX2RpcmVjdG9yeShlbnRyeSwgYnVmZmVyLCBzb3J0T3JkZXIsIGh3bmQpOwoKCQlpZiAoZW50cnktPmRvd24pCgkJCWVudHJ5LT5leHBhbmRlZCA9IFRSVUU7CgoJCWlmICghKnMpCgkJCWJyZWFrOwoKCQllbnRyeSA9IGZpbmRfZW50cnlfdW5peChlbnRyeSwgcyk7Cgl9CgoJU2V0Q3Vyc29yKG9sZF9jdXJzb3IpOwoKCXJldHVybiBlbnRyeTsKfQoKI2VuZGlmIC8qICFkZWZpbmVkKF9OT19FWFRFTlNJT05TKSAmJiBkZWZpbmVkKF9fV0lORV9fKSAqLwoKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoKI2lmZGVmIFVOSUNPREUKI2RlZmluZQlnZXRfc3RycmV0IGdldF9zdHJyZXRXCiNkZWZpbmUJcGF0aF9mcm9tX3BpZGwgcGF0aF9mcm9tX3BpZGxXCiNlbHNlCiNkZWZpbmUJZ2V0X3N0cnJldCBnZXRfc3RycmV0QQojZGVmaW5lCXBhdGhfZnJvbV9waWRsIHBhdGhfZnJvbV9waWRsQQojZW5kaWYKCgpzdGF0aWMgdm9pZCBmcmVlX3N0cnJldChTVFJSRVQqIHN0cikKewoJaWYgKHN0ci0+dVR5cGUgPT0gU1RSUkVUX1dTVFIpCgkJSU1hbGxvY19GcmVlKEdsb2JhbHMuaU1hbGxvYywgc3RyLT5VTklPTl9NRU1CRVIocE9sZVN0cikpOwp9CgoKI2lmbmRlZiBVTklDT0RFCgpzdGF0aWMgTFBTVFIgc3RyY3B5bihMUFNUUiBkZXN0LCBMUENTVFIgc291cmNlLCBzaXplX3QgY291bnQpCnsKIExQQ1NUUiBzOwogTFBTVFIgZCA9IGRlc3Q7CgogZm9yKHM9c291cmNlOyBjb3VudCYmKCpkKys9KnMrKyk7ICkKICBjb3VudC0tOwoKIHJldHVybiBkZXN0Owp9CgpzdGF0aWMgdm9pZCBnZXRfc3RycmV0QShTVFJSRVQqIHN0ciwgY29uc3QgU0hJVEVNSUQqIHNoaWlkLCBMUFNUUiBidWZmZXIsIGludCBsZW4pCnsKIHN3aXRjaChzdHItPnVUeXBlKSB7CiAgY2FzZSBTVFJSRVRfV1NUUjoKCVdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBzdHItPlVOSU9OX01FTUJFUihwT2xlU3RyKSwgLTEsIGJ1ZmZlciwgbGVuLCBOVUxMLCBOVUxMKTsKCWJyZWFrOwoKICBjYXNlIFNUUlJFVF9PRkZTRVQ6CglzdHJjcHluKGJ1ZmZlciwgKExQQ1NUUilzaGlpZCtzdHItPlVOSU9OX01FTUJFUih1T2Zmc2V0KSwgbGVuKTsKCWJyZWFrOwoKICBjYXNlIFNUUlJFVF9DU1RSOgoJc3RyY3B5bihidWZmZXIsIHN0ci0+VU5JT05fTUVNQkVSKGNTdHIpLCBsZW4pOwogfQp9CgpzdGF0aWMgSFJFU1VMVCBwYXRoX2Zyb21fcGlkbEEoSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQSVRFTUlETElTVCBwaWRsLCBMUFNUUiBidWZmZXIsIGludCBsZW4pCnsKCVNUUlJFVCBzdHI7CgoJIC8qIFNIR0ROX0ZPUlBBUlNJTkc6IGdldCBmdWxsIHBhdGggb2YgaWQgbGlzdCAqLwoJSFJFU1VMVCBociA9IElTaGVsbEZvbGRlcl9HZXREaXNwbGF5TmFtZU9mKGZvbGRlciwgcGlkbCwgU0hHRE5fRk9SUEFSU0lORywgJnN0cik7CgoJaWYgKFNVQ0NFRURFRChocikpIHsKCQlnZXRfc3RycmV0QSgmc3RyLCAmcGlkbC0+bWtpZCwgYnVmZmVyLCBsZW4pOwoJCWZyZWVfc3RycmV0KCZzdHIpOwoJfSBlbHNlCgkJYnVmZmVyWzBdID0gJ1wwJzsKCglyZXR1cm4gaHI7Cn0KCiNlbmRpZgoKc3RhdGljIExQV1NUUiB3Y3NjcHluKExQV1NUUiBkZXN0LCBMUENXU1RSIHNvdXJjZSwgc2l6ZV90IGNvdW50KQp7CiBMUENXU1RSIHM7CiBMUFdTVFIgZCA9IGRlc3Q7CgogZm9yKHM9c291cmNlOyBjb3VudCYmKCpkKys9KnMrKyk7ICkKICBjb3VudC0tOwoKIHJldHVybiBkZXN0Owp9CgpzdGF0aWMgdm9pZCBnZXRfc3RycmV0VyhTVFJSRVQqIHN0ciwgY29uc3QgU0hJVEVNSUQqIHNoaWlkLCBMUFdTVFIgYnVmZmVyLCBpbnQgbGVuKQp7CiBzd2l0Y2goc3RyLT51VHlwZSkgewogIGNhc2UgU1RSUkVUX1dTVFI6Cgl3Y3NjcHluKGJ1ZmZlciwgc3RyLT5VTklPTl9NRU1CRVIocE9sZVN0ciksIGxlbik7CglicmVhazsKCiAgY2FzZSBTVFJSRVRfT0ZGU0VUOgoJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIChMUENTVFIpc2hpaWQrc3RyLT5VTklPTl9NRU1CRVIodU9mZnNldCksIC0xLCBidWZmZXIsIGxlbik7CglicmVhazsKCiAgY2FzZSBTVFJSRVRfQ1NUUjoKCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzdHItPlVOSU9OX01FTUJFUihjU3RyKSwgLTEsIGJ1ZmZlciwgbGVuKTsKIH0KfQoKCnN0YXRpYyBIUkVTVUxUIG5hbWVfZnJvbV9waWRsKElTaGVsbEZvbGRlciogZm9sZGVyLCBMUElURU1JRExJU1QgcGlkbCwgTFBUU1RSIGJ1ZmZlciwgaW50IGxlbiwgU0hHRE5GIGZsYWdzKQp7CglTVFJSRVQgc3RyOwoKCUhSRVNVTFQgaHIgPSBJU2hlbGxGb2xkZXJfR2V0RGlzcGxheU5hbWVPZihmb2xkZXIsIHBpZGwsIGZsYWdzLCAmc3RyKTsKCglpZiAoU1VDQ0VFREVEKGhyKSkgewoJCWdldF9zdHJyZXQoJnN0ciwgJnBpZGwtPm1raWQsIGJ1ZmZlciwgbGVuKTsKCQlmcmVlX3N0cnJldCgmc3RyKTsKCX0gZWxzZQoJCWJ1ZmZlclswXSA9ICdcMCc7CgoJcmV0dXJuIGhyOwp9CgoKc3RhdGljIEhSRVNVTFQgcGF0aF9mcm9tX3BpZGxXKElTaGVsbEZvbGRlciogZm9sZGVyLCBMUElURU1JRExJU1QgcGlkbCwgTFBXU1RSIGJ1ZmZlciwgaW50IGxlbikKewoJU1RSUkVUIHN0cjsKCgkgLyogU0hHRE5fRk9SUEFSU0lORzogZ2V0IGZ1bGwgcGF0aCBvZiBpZCBsaXN0ICovCglIUkVTVUxUIGhyID0gSVNoZWxsRm9sZGVyX0dldERpc3BsYXlOYW1lT2YoZm9sZGVyLCBwaWRsLCBTSEdETl9GT1JQQVJTSU5HLCAmc3RyKTsKCglpZiAoU1VDQ0VFREVEKGhyKSkgewoJCWdldF9zdHJyZXRXKCZzdHIsICZwaWRsLT5ta2lkLCBidWZmZXIsIGxlbik7CgkJZnJlZV9zdHJyZXQoJnN0cik7Cgl9IGVsc2UKCQlidWZmZXJbMF0gPSAnXDAnOwoKCXJldHVybiBocjsKfQoKCiAvKiBjcmVhdGUgYW4gaXRlbSBpZCBsaXN0IGZyb20gYSBmaWxlIHN5c3RlbSBwYXRoICovCgpzdGF0aWMgTFBJVEVNSURMSVNUIGdldF9wYXRoX3BpZGwoTFBUU1RSIHBhdGgsIEhXTkQgaHduZCkKewoJTFBJVEVNSURMSVNUIHBpZGw7CglIUkVTVUxUIGhyOwoJVUxPTkcgbGVuOwoKI2lmZGVmIFVOSUNPREUKCUxQV1NUUiBidWZmZXIgPSBwYXRoOwojZWxzZQoJV0NIQVIgYnVmZmVyW01BWF9QQVRIXTsKCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBwYXRoLCAtMSwgYnVmZmVyLCBNQVhfUEFUSCk7CiNlbmRpZgoKCWhyID0gSVNoZWxsRm9sZGVyX1BhcnNlRGlzcGxheU5hbWUoR2xvYmFscy5pRGVza3RvcCwgaHduZCwgTlVMTCwgYnVmZmVyLCAmbGVuLCAmcGlkbCwgTlVMTCk7CglpZiAoRkFJTEVEKGhyKSkKCQlyZXR1cm4gTlVMTDsKCglyZXR1cm4gcGlkbDsKfQoKCiAvKiBjb252ZXJ0IGFuIGl0ZW0gaWQgbGlzdCBmcm9tIHJlbGF0aXZlIHRvIGFic29sdXRlICg9cmVsYXRpdmUgdG8gdGhlIGRlc2t0b3ApIGZvcm1hdCAqLwoKc3RhdGljIExQSVRFTUlETElTVCBnZXRfdG9fYWJzb2x1dGVfcGlkbChFbnRyeSogZW50cnksIEhXTkQgaHduZCkKewoJaWYgKGVudHJ5LT51cCAmJiBlbnRyeS0+dXAtPmV0eXBlPT1FVF9TSEVMTCkgewoJCUlTaGVsbEZvbGRlciogZm9sZGVyID0gZW50cnktPnVwLT5mb2xkZXI7CgkJV0NIQVIgYnVmZmVyW01BWF9QQVRIXTsKCgkJSFJFU1VMVCBociA9IHBhdGhfZnJvbV9waWRsVyhmb2xkZXIsIGVudHJ5LT5waWRsLCBidWZmZXIsIE1BWF9QQVRIKTsKCgkJaWYgKFNVQ0NFRURFRChocikpIHsKCQkJTFBJVEVNSURMSVNUIHBpZGw7CgkJCVVMT05HIGxlbjsKCgkJCWhyID0gSVNoZWxsRm9sZGVyX1BhcnNlRGlzcGxheU5hbWUoR2xvYmFscy5pRGVza3RvcCwgaHduZCwgTlVMTCwgYnVmZmVyLCAmbGVuLCAmcGlkbCwgTlVMTCk7CgoJCQlpZiAoU1VDQ0VFREVEKGhyKSkKCQkJCXJldHVybiBwaWRsOwoJCX0KCX0gZWxzZSBpZiAoZW50cnktPmV0eXBlID09IEVUX1dJTkRPV1MpIHsKCQlUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCgkJZ2V0X3BhdGgoZW50cnksIHBhdGgpOwoKCQlyZXR1cm4gZ2V0X3BhdGhfcGlkbChwYXRoLCBod25kKTsKCX0gZWxzZSBpZiAoZW50cnktPnBpZGwpCgkJcmV0dXJuIElMQ2xvbmUoZW50cnktPnBpZGwpOwoKCXJldHVybiBOVUxMOwp9CgoKc3RhdGljIEhJQ09OIGV4dHJhY3RfaWNvbihJU2hlbGxGb2xkZXIqIGZvbGRlciwgTFBDSVRFTUlETElTVCBwaWRsKQp7CglJRXh0cmFjdEljb24qIHBFeHRyYWN0OwoKCWlmIChTVUNDRUVERUQoSVNoZWxsRm9sZGVyX0dldFVJT2JqZWN0T2YoZm9sZGVyLCAwLCAxLCAoTFBDSVRFTUlETElTVCopJnBpZGwsICZJSURfSUV4dHJhY3RJY29uLCAwLCAoTFBWT0lEKikmcEV4dHJhY3QpKSkgewoJCVRDSEFSIHBhdGhbX01BWF9QQVRIXTsKCQl1bnNpZ25lZCBmbGFnczsKCQlISUNPTiBoaWNvbjsKCQlpbnQgaWR4OwoKCQlpZiAoU1VDQ0VFREVEKElFeHRyYWN0SWNvbldfR2V0SWNvbkxvY2F0aW9uKHBFeHRyYWN0LCBHSUxfRk9SU0hFTEwsIHBhdGgsIF9NQVhfUEFUSCwgJmlkeCwgJmZsYWdzKSkpIHsKCQkJaWYgKCEoZmxhZ3MgJiBHSUxfTk9URklMRU5BTUUpKSB7CgkJCQlpZiAoaWR4ID09IC0xKQoJCQkJCWlkeCA9IDA7CS8qIHNwZWNpYWwgY2FzZSBmb3Igc29tZSBjb250cm9sIHBhbmVsIGFwcGxpY2F0aW9ucyAqLwoKCQkJCWlmICgoaW50KUV4dHJhY3RJY29uRXgocGF0aCwgaWR4LCAwLCAmaGljb24sIDEpID4gMCkKCQkJCQlmbGFncyAmPSB+R0lMX0RPTlRDQUNIRTsKCQkJfSBlbHNlIHsKCQkJCUhJQ09OIGhJY29uTGFyZ2UgPSAwOwoKCQkJCUhSRVNVTFQgaHIgPSBJRXh0cmFjdEljb25XX0V4dHJhY3QocEV4dHJhY3QsIHBhdGgsIGlkeCwgJmhJY29uTGFyZ2UsICZoaWNvbiwgTUFLRUxPTkcoMC8qR2V0U3lzdGVtTWV0cmljcyhTTV9DWElDT04pKi8sR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNNSUNPTikpKTsKCgkJCQlpZiAoU1VDQ0VFREVEKGhyKSkKCQkJCQlEZXN0cm95SWNvbihoSWNvbkxhcmdlKTsKCQkJfQoKCQkJcmV0dXJuIGhpY29uOwoJCX0KCX0KCglyZXR1cm4gMDsKfQoKCnN0YXRpYyBFbnRyeSogZmluZF9lbnRyeV9zaGVsbChFbnRyeSogZGlyLCBMUENJVEVNSURMSVNUIHBpZGwpCnsKCUVudHJ5KiBlbnRyeTsKCglmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpIHsKCQlpZiAoZW50cnktPnBpZGwtPm1raWQuY2IgPT0gcGlkbC0+bWtpZC5jYiAmJgoJCQkhbWVtY21wKGVudHJ5LT5waWRsLCBwaWRsLCBlbnRyeS0+cGlkbC0+bWtpZC5jYikpCgkJCXJldHVybiBlbnRyeTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIEVudHJ5KiByZWFkX3RyZWVfc2hlbGwoUm9vdCogcm9vdCwgTFBJVEVNSURMSVNUIHBpZGwsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCUVudHJ5KiBlbnRyeSA9ICZyb290LT5lbnRyeTsKCUVudHJ5KiBuZXh0OwoJTFBJVEVNSURMSVNUIG5leHRfcGlkbCA9IHBpZGw7CglJU2hlbGxGb2xkZXIqIGZvbGRlcjsKCUlTaGVsbEZvbGRlciogY2hpbGQgPSBOVUxMOwoJSFJFU1VMVCBocjsKCglIQ1VSU09SIG9sZF9jdXJzb3IgPSBTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfV0FJVCkpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJZW50cnktPmV0eXBlID0gRVRfU0hFTEw7CiNlbmRpZgoKCWZvbGRlciA9IEdsb2JhbHMuaURlc2t0b3A7CgoJd2hpbGUoZW50cnkpIHsKCQllbnRyeS0+cGlkbCA9IG5leHRfcGlkbDsKCQllbnRyeS0+Zm9sZGVyID0gZm9sZGVyOwoKCQlpZiAoIXBpZGwtPm1raWQuY2IpCgkJCWJyZWFrOwoKCQkgLyogY29weSBmaXJzdCBlbGVtZW50IG9mIGl0ZW0gaWRsaXN0ICovCgkJbmV4dF9waWRsID0gSU1hbGxvY19BbGxvYyhHbG9iYWxzLmlNYWxsb2MsIHBpZGwtPm1raWQuY2Irc2l6ZW9mKFVTSE9SVCkpOwoJCW1lbWNweShuZXh0X3BpZGwsIHBpZGwsIHBpZGwtPm1raWQuY2IpOwoJCSgoTFBJVEVNSURMSVNUKSgoTFBCWVRFKW5leHRfcGlkbCtwaWRsLT5ta2lkLmNiKSktPm1raWQuY2IgPSAwOwoKCQlociA9IElTaGVsbEZvbGRlcl9CaW5kVG9PYmplY3QoZm9sZGVyLCBuZXh0X3BpZGwsIDAsICZJSURfSVNoZWxsRm9sZGVyLCAodm9pZCoqKSZjaGlsZCk7CgkJaWYgKCFTVUNDRUVERUQoaHIpKQoJCQlicmVhazsKCgkJcmVhZF9kaXJlY3RvcnkoZW50cnksIE5VTEwsIHNvcnRPcmRlciwgaHduZCk7CgoJCWlmIChlbnRyeS0+ZG93bikKCQkJZW50cnktPmV4cGFuZGVkID0gVFJVRTsKCgkJbmV4dCA9IGZpbmRfZW50cnlfc2hlbGwoZW50cnksIG5leHRfcGlkbCk7CgkJaWYgKCFuZXh0KQoJCQlicmVhazsKCgkJZm9sZGVyID0gY2hpbGQ7CgkJZW50cnkgPSBuZXh0OwoKCQkgLyogZ28gdG8gbmV4dCBlbGVtZW50ICovCgkJcGlkbCA9IChMUElURU1JRExJU1QpICgoTFBCWVRFKXBpZGwrcGlkbC0+bWtpZC5jYik7Cgl9CgoJU2V0Q3Vyc29yKG9sZF9jdXJzb3IpOwoKCXJldHVybiBlbnRyeTsKfQoKCnN0YXRpYyB2b2lkIGZpbGxfdzMyZmRhdGFfc2hlbGwoSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQQ0lURU1JRExJU1QgcGlkbCwgU0ZHQU9GIGF0dHJpYnMsIFdJTjMyX0ZJTkRfREFUQSogdzMyZmRhdGEpCnsKCWlmICghKGF0dHJpYnMgJiBTRkdBT19GSUxFU1lTVEVNKSB8fAoJCSAgRkFJTEVEKFNIR2V0RGF0YUZyb21JRExpc3QoZm9sZGVyLCBwaWRsLCBTSEdERklMX0ZJTkREQVRBLCB3MzJmZGF0YSwgc2l6ZW9mKFdJTjMyX0ZJTkRfREFUQSkpKSkgewoJCVdJTjMyX0ZJTEVfQVRUUklCVVRFX0RBVEEgZmFkOwoJCUlEYXRhT2JqZWN0KiBwRGF0YU9iajsKCgkJU1RHTUVESVVNIG1lZGl1bSA9IHswLCB7MH0sIDB9OwoJCUZPUk1BVEVUQyBmbXQgPSB7R2xvYmFscy5jZlN0ckZOYW1lLCAwLCBEVkFTUEVDVF9DT05URU5ULCAtMSwgVFlNRURfSEdMT0JBTH07CgoJCUhSRVNVTFQgaHIgPSBJU2hlbGxGb2xkZXJfR2V0VUlPYmplY3RPZihmb2xkZXIsIDAsIDEsICZwaWRsLCAmSUlEX0lEYXRhT2JqZWN0LCAwLCAoTFBWT0lEKikmcERhdGFPYmopOwoKCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQlociA9IElEYXRhT2JqZWN0X0dldERhdGEocERhdGFPYmosICZmbXQsICZtZWRpdW0pOwoKCQkJSURhdGFPYmplY3RfUmVsZWFzZShwRGF0YU9iaik7CgoJCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQkJTFBDVFNUUiBwYXRoID0gKExQQ1RTVFIpR2xvYmFsTG9jayhtZWRpdW0uVU5JT05fTUVNQkVSKGhHbG9iYWwpKTsKCQkJCVVJTlQgc2VtX29yZyA9IFNldEVycm9yTW9kZShTRU1fRkFJTENSSVRJQ0FMRVJST1JTKTsKCgkJCQlpZiAoR2V0RmlsZUF0dHJpYnV0ZXNFeChwYXRoLCBHZXRGaWxlRXhJbmZvU3RhbmRhcmQsICZmYWQpKSB7CgkJCQkJdzMyZmRhdGEtPmR3RmlsZUF0dHJpYnV0ZXMgPSBmYWQuZHdGaWxlQXR0cmlidXRlczsKCQkJCQl3MzJmZGF0YS0+ZnRDcmVhdGlvblRpbWUgPSBmYWQuZnRDcmVhdGlvblRpbWU7CgkJCQkJdzMyZmRhdGEtPmZ0TGFzdEFjY2Vzc1RpbWUgPSBmYWQuZnRMYXN0QWNjZXNzVGltZTsKCQkJCQl3MzJmZGF0YS0+ZnRMYXN0V3JpdGVUaW1lID0gZmFkLmZ0TGFzdFdyaXRlVGltZTsKCgkJCQkJaWYgKCEoZmFkLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpKSB7CgkJCQkJCXczMmZkYXRhLT5uRmlsZVNpemVMb3cgPSBmYWQubkZpbGVTaXplTG93OwoJCQkJCQl3MzJmZGF0YS0+bkZpbGVTaXplSGlnaCA9IGZhZC5uRmlsZVNpemVIaWdoOwoJCQkJCX0KCQkJCX0KCgkJCQlTZXRFcnJvck1vZGUoc2VtX29yZyk7CgoJCQkJR2xvYmFsVW5sb2NrKG1lZGl1bS5VTklPTl9NRU1CRVIoaEdsb2JhbCkpOwoJCQkJR2xvYmFsRnJlZShtZWRpdW0uVU5JT05fTUVNQkVSKGhHbG9iYWwpKTsKCQkJfQoJCX0KCX0KCglpZiAoYXR0cmlicyAmIChTRkdBT19GT0xERVJ8U0ZHQU9fSEFTU1VCRk9MREVSKSkKCQl3MzJmZGF0YS0+ZHdGaWxlQXR0cmlidXRlcyB8PSBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk7CgoJaWYgKGF0dHJpYnMgJiBTRkdBT19SRUFET05MWSkKCQl3MzJmZGF0YS0+ZHdGaWxlQXR0cmlidXRlcyB8PSBGSUxFX0FUVFJJQlVURV9SRUFET05MWTsKCglpZiAoYXR0cmlicyAmIFNGR0FPX0NPTVBSRVNTRUQpCgkJdzMyZmRhdGEtPmR3RmlsZUF0dHJpYnV0ZXMgfD0gRklMRV9BVFRSSUJVVEVfQ09NUFJFU1NFRDsKfQoKCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5X3NoZWxsKEVudHJ5KiBkaXIsIEhXTkQgaHduZCkKewoJSVNoZWxsRm9sZGVyKiBmb2xkZXIgPSBkaXItPmZvbGRlcjsKCWludCBsZXZlbCA9IGRpci0+bGV2ZWwgKyAxOwoJSFJFU1VMVCBocjsKCglJU2hlbGxGb2xkZXIqIGNoaWxkOwoJSUVudW1JRExpc3QqIGlkbGlzdDsKCglFbnRyeSogZmlyc3RfZW50cnkgPSBOVUxMOwoJRW50cnkqIGxhc3QgPSBOVUxMOwoJRW50cnkqIGVudHJ5OwoKCWlmICghZm9sZGVyKQoJCXJldHVybjsKCglociA9IElTaGVsbEZvbGRlcl9FbnVtT2JqZWN0cyhmb2xkZXIsIGh3bmQsIFNIQ09OVEZfRk9MREVSU3xTSENPTlRGX05PTkZPTERFUlN8U0hDT05URl9JTkNMVURFSElEREVOfFNIQ09OVEZfU0hBUkVBQkxFfFNIQ09OVEZfU1RPUkFHRSwgJmlkbGlzdCk7CgoJaWYgKFNVQ0NFRURFRChocikpIHsKCQlmb3IoOzspIHsKI2RlZmluZQlGRVRDSF9JVEVNX0NPVU5UCTMyCgkJCUxQSVRFTUlETElTVCBwaWRsc1tGRVRDSF9JVEVNX0NPVU5UXTsKCQkJU0ZHQU9GIGF0dHJpYnM7CgkJCVVMT05HIGNudCA9IDA7CgkJCVVMT05HIG47CgoJCQltZW1zZXQocGlkbHMsIDAsIHNpemVvZihwaWRscykpOwoKCQkJaHIgPSBJRW51bUlETGlzdF9OZXh0KGlkbGlzdCwgRkVUQ0hfSVRFTV9DT1VOVCwgcGlkbHMsICZjbnQpOwoJCQlpZiAoIVNVQ0NFRURFRChocikpCgkJCQlicmVhazsKCgkJCWlmIChociA9PSBTX0ZBTFNFKQoJCQkJYnJlYWs7CgoJCQlmb3Iobj0wOyBuPGNudDsgKytuKSB7CgkJCQllbnRyeSA9IGFsbG9jX2VudHJ5KCk7CgoJCQkJaWYgKCFmaXJzdF9lbnRyeSkKCQkJCQlmaXJzdF9lbnRyeSA9IGVudHJ5OwoKCQkJCWlmIChsYXN0KQoJCQkJCWxhc3QtPm5leHQgPSBlbnRyeTsKCgkJCQltZW1zZXQoJmVudHJ5LT5kYXRhLCAwLCBzaXplb2YoV0lOMzJfRklORF9EQVRBKSk7CgkJCQllbnRyeS0+YmhmaV92YWxpZCA9IEZBTFNFOwoKCQkJCWF0dHJpYnMgPSB+U0ZHQU9fRklMRVNZU1RFTTsJLypTRkdBT19IQVNTVUJGT0xERVJ8U0ZHQU9fRk9MREVSOyBTRkdBT19GSUxFU1lTVEVNIHNvcmd0IGRhZvxyLCBkYd8gIk15IERvY3VtZW50cyIgYW5zdGF0dCB2b24gIk1hcnRpbidzIERvY3VtZW50cyIgYW5nZXplaWd0IHdpcmQgKi8KCgkJCQlociA9IElTaGVsbEZvbGRlcl9HZXRBdHRyaWJ1dGVzT2YoZm9sZGVyLCAxLCAoTFBDSVRFTUlETElTVCopJnBpZGxzW25dLCAmYXR0cmlicyk7CgoJCQkJaWYgKFNVQ0NFRURFRChocikpIHsKCQkJCQlpZiAoYXR0cmlicyAhPSAoU0ZHQU9GKX5TRkdBT19GSUxFU1lTVEVNKSB7CgkJCQkJCWZpbGxfdzMyZmRhdGFfc2hlbGwoZm9sZGVyLCBwaWRsc1tuXSwgYXR0cmlicywgJmVudHJ5LT5kYXRhKTsKCgkJCQkJCWVudHJ5LT5iaGZpX3ZhbGlkID0gVFJVRTsKCQkJCQl9IGVsc2UKCQkJCQkJYXR0cmlicyA9IDA7CgkJCQl9IGVsc2UKCQkJCQlhdHRyaWJzID0gMDsKCgkJCQllbnRyeS0+cGlkbCA9IHBpZGxzW25dOwoKCQkJCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCQkJaHIgPSBJU2hlbGxGb2xkZXJfQmluZFRvT2JqZWN0KGZvbGRlciwgcGlkbHNbbl0sIDAsICZJSURfSVNoZWxsRm9sZGVyLCAodm9pZCoqKSZjaGlsZCk7CgoJCQkJCWlmIChTVUNDRUVERUQoaHIpKQoJCQkJCQllbnRyeS0+Zm9sZGVyID0gY2hpbGQ7CgkJCQkJZWxzZQoJCQkJCQllbnRyeS0+Zm9sZGVyID0gTlVMTDsKCQkJCX0KCQkJCWVsc2UKCQkJCQllbnRyeS0+Zm9sZGVyID0gTlVMTDsKCgkJCQlpZiAoIWVudHJ5LT5kYXRhLmNGaWxlTmFtZVswXSkKCQkJCQkvKmhyID0gKi9uYW1lX2Zyb21fcGlkbChmb2xkZXIsIHBpZGxzW25dLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIE1BWF9QQVRILCAvKlNIR0ROX0lORk9MREVSKi8weDIwMDAvKjB4MjAwMD1TSEdETl9JTkNMVURFX05PTkZJTEVTWVMqLyk7CgoJCQkJIC8qIGdldCBkaXNwbGF5IGljb25zIGZvciBmaWxlcyBhbmQgdmlydHVhbCBvYmplY3RzICovCgkJCQlpZiAoIShlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB8fAoJCQkJCSEoYXR0cmlicyAmIFNGR0FPX0ZJTEVTWVNURU0pKSB7CgkJCQkJZW50cnktPmhpY29uID0gZXh0cmFjdF9pY29uKGZvbGRlciwgcGlkbHNbbl0pOwoKCQkJCQlpZiAoIWVudHJ5LT5oaWNvbikKCQkJCQkJZW50cnktPmhpY29uID0gKEhJQ09OKS0xOwkvKiBkb24ndCB0cnkgYWdhaW4gbGF0ZXIgKi8KCQkJCX0KCgkJCQllbnRyeS0+ZG93biA9IE5VTEw7CgkJCQllbnRyeS0+dXAgPSBkaXI7CgkJCQllbnRyeS0+ZXhwYW5kZWQgPSBGQUxTRTsKCQkJCWVudHJ5LT5zY2FubmVkID0gRkFMU0U7CgkJCQllbnRyeS0+bGV2ZWwgPSBsZXZlbDsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJCWVudHJ5LT5ldHlwZSA9IEVUX1NIRUxMOwoJCQkJZW50cnktPmJoZmlfdmFsaWQgPSBGQUxTRTsKI2VuZGlmCgoJCQkJbGFzdCA9IGVudHJ5OwoJCQl9CgkJfQoKCQlJRW51bUlETGlzdF9SZWxlYXNlKGlkbGlzdCk7Cgl9CgoJaWYgKGxhc3QpCgkJbGFzdC0+bmV4dCA9IE5VTEw7CgoJZGlyLT5kb3duID0gZmlyc3RfZW50cnk7CglkaXItPnNjYW5uZWQgPSBUUlVFOwp9CgojZW5kaWYgLyogX1NIRUxMX0ZPTERFUlMgKi8KCgovKiBzb3J0IG9yZGVyIGZvciBkaWZmZXJlbnQgZGlyZWN0b3J5L2ZpbGUgdHlwZXMgKi8KZW51bSBUWVBFX09SREVSIHsKCVRPX0RJUiA9IDAsCglUT19ET1QgPSAxLAoJVE9fRE9URE9UID0gMiwKCVRPX09USEVSX0RJUiA9IDMsCglUT19GSUxFID0gNAp9OwoKLyogZGlzdGluZ3Vpc2ggYmV0d2VlbiAiLiIsICIuLiIgYW5kIGFueSBvdGhlciBkaXJlY3RvcnkgbmFtZXMgKi8Kc3RhdGljIGludCBUeXBlT3JkZXJGcm9tRGlybmFtZShMUENUU1RSIG5hbWUpCnsKCWlmIChuYW1lWzBdID09ICcuJykgewoJCWlmIChuYW1lWzFdID09ICdcMCcpCgkJCXJldHVybiBUT19ET1Q7CS8qICIuIiAqLwoKCQlpZiAobmFtZVsxXT09Jy4nICYmIG5hbWVbMl09PSdcMCcpCgkJCXJldHVybiBUT19ET1RET1Q7CS8qICIuLiIgKi8KCX0KCglyZXR1cm4gVE9fT1RIRVJfRElSOwkvKiBhbnl0aGluZyBlbHNlICovCn0KCi8qIGRpcmVjdG9yaWVzIGZpcnN0Li4uICovCnN0YXRpYyBpbnQgY29tcGFyZVR5cGUoY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDEsIGNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQyKQp7CglpbnQgb3JkZXIxID0gZmQxLT5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZPyBUT19ESVI6IFRPX0ZJTEU7CglpbnQgb3JkZXIyID0gZmQyLT5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZPyBUT19ESVI6IFRPX0ZJTEU7CgoJLyogSGFuZGxlICIuIiBhbmQgIi4uIiBhcyBzcGVjaWFsIGNhc2UgYW5kIG1vdmUgdGhlbSBhdCB0aGUgdmVyeSBmaXJzdCBiZWdpbm5pbmcuICovCglpZiAob3JkZXIxPT1UT19ESVIgJiYgb3JkZXIyPT1UT19ESVIpIHsKCQlvcmRlcjEgPSBUeXBlT3JkZXJGcm9tRGlybmFtZShmZDEtPmNGaWxlTmFtZSk7CgkJb3JkZXIyID0gVHlwZU9yZGVyRnJvbURpcm5hbWUoZmQyLT5jRmlsZU5hbWUpOwoJfQoKCXJldHVybiBvcmRlcjI9PW9yZGVyMT8gMDogb3JkZXIxPG9yZGVyMj8gLTE6IDE7Cn0KCgpzdGF0aWMgaW50IGNvbXBhcmVOYW1lKGNvbnN0IHZvaWQqIGFyZzEsIGNvbnN0IHZvaWQqIGFyZzIpCnsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQxID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMSktPmRhdGE7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMiA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzIpLT5kYXRhOwoKCWludCBjbXAgPSBjb21wYXJlVHlwZShmZDEsIGZkMik7CglpZiAoY21wKQoJCXJldHVybiBjbXA7CgoJcmV0dXJuIGxzdHJjbXBpKGZkMS0+Y0ZpbGVOYW1lLCBmZDItPmNGaWxlTmFtZSk7Cn0KCnN0YXRpYyBpbnQgY29tcGFyZUV4dChjb25zdCB2b2lkKiBhcmcxLCBjb25zdCB2b2lkKiBhcmcyKQp7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMSA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzEpLT5kYXRhOwoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDIgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcyKS0+ZGF0YTsKCWNvbnN0IFRDSEFSICpuYW1lMSwgKm5hbWUyLCAqZXh0MSwgKmV4dDI7CgoJaW50IGNtcCA9IGNvbXBhcmVUeXBlKGZkMSwgZmQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCgluYW1lMSA9IGZkMS0+Y0ZpbGVOYW1lOwoJbmFtZTIgPSBmZDItPmNGaWxlTmFtZTsKCglleHQxID0gX3Rjc3JjaHIobmFtZTEsICcuJyk7CglleHQyID0gX3Rjc3JjaHIobmFtZTIsICcuJyk7CgoJaWYgKGV4dDEpCgkJZXh0MSsrOwoJZWxzZQoJCWV4dDEgPSBzRW1wdHk7CgoJaWYgKGV4dDIpCgkJZXh0MisrOwoJZWxzZQoJCWV4dDIgPSBzRW1wdHk7CgoJY21wID0gbHN0cmNtcGkoZXh0MSwgZXh0Mik7CglpZiAoY21wKQoJCXJldHVybiBjbXA7CgoJcmV0dXJuIGxzdHJjbXBpKG5hbWUxLCBuYW1lMik7Cn0KCnN0YXRpYyBpbnQgY29tcGFyZVNpemUoY29uc3Qgdm9pZCogYXJnMSwgY29uc3Qgdm9pZCogYXJnMikKewoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDEgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcxKS0+ZGF0YTsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQyID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMiktPmRhdGE7CgoJaW50IGNtcCA9IGNvbXBhcmVUeXBlKGZkMSwgZmQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCgljbXAgPSBmZDItPm5GaWxlU2l6ZUhpZ2ggLSBmZDEtPm5GaWxlU2l6ZUhpZ2g7CgoJaWYgKGNtcCA8IDApCgkJcmV0dXJuIC0xOwoJZWxzZSBpZiAoY21wID4gMCkKCQlyZXR1cm4gMTsKCgljbXAgPSBmZDItPm5GaWxlU2l6ZUxvdyAtIGZkMS0+bkZpbGVTaXplTG93OwoKCXJldHVybiBjbXA8MD8gLTE6IGNtcD4wPyAxOiAwOwp9CgpzdGF0aWMgaW50IGNvbXBhcmVEYXRlKGNvbnN0IHZvaWQqIGFyZzEsIGNvbnN0IHZvaWQqIGFyZzIpCnsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQxID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMSktPmRhdGE7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMiA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzIpLT5kYXRhOwoKCWludCBjbXAgPSBjb21wYXJlVHlwZShmZDEsIGZkMik7CglpZiAoY21wKQoJCXJldHVybiBjbXA7CgoJcmV0dXJuIENvbXBhcmVGaWxlVGltZSgmZmQyLT5mdExhc3RXcml0ZVRpbWUsICZmZDEtPmZ0TGFzdFdyaXRlVGltZSk7Cn0KCgpzdGF0aWMgaW50ICgqc29ydEZ1bmN0aW9uc1tdKShjb25zdCB2b2lkKiBhcmcxLCBjb25zdCB2b2lkKiBhcmcyKSA9IHsKCWNvbXBhcmVOYW1lLAkvKiBTT1JUX05BTUUgKi8KCWNvbXBhcmVFeHQsCQkvKiBTT1JUX0VYVCAqLwoJY29tcGFyZVNpemUsCS8qIFNPUlRfU0laRSAqLwoJY29tcGFyZURhdGUJCS8qIFNPUlRfREFURSAqLwp9OwoKCnN0YXRpYyB2b2lkIFNvcnREaXJlY3RvcnkoRW50cnkqIGRpciwgU09SVF9PUkRFUiBzb3J0T3JkZXIpCnsKCUVudHJ5KiBlbnRyeSA9IGRpci0+ZG93bjsKCUVudHJ5KiogYXJyYXksICoqcDsKCWludCBsZW47CgoJbGVuID0gMDsKCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQlsZW4rKzsKCglpZiAobGVuKSB7CgkJYXJyYXkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihFbnRyeSopKTsKCgkJcCA9IGFycmF5OwoJCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQkJKnArKyA9IGVudHJ5OwoKCQkvKiBjYWxsIHFzb3J0IHdpdGggdGhlIGFwcHJvcHJpYXRlIGNvbXBhcmUgZnVuY3Rpb24gKi8KCQlxc29ydChhcnJheSwgbGVuLCBzaXplb2YoYXJyYXlbMF0pLCBzb3J0RnVuY3Rpb25zW3NvcnRPcmRlcl0pOwoKCQlkaXItPmRvd24gPSBhcnJheVswXTsKCgkJZm9yKHA9YXJyYXk7IC0tbGVuOyBwKyspCgkJCXBbMF0tPm5leHQgPSBwWzFdOwoKCQkoKnApLT5uZXh0ID0gMDsKCiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBhcnJheSk7Cgl9Cn0KCgpzdGF0aWMgdm9pZCByZWFkX2RpcmVjdG9yeShFbnRyeSogZGlyLCBMUENUU1RSIHBhdGgsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF07CglFbnRyeSogZW50cnk7CglMUENUU1RSIHM7CglQVFNUUiBkOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglpZiAoZGlyLT5ldHlwZSA9PSBFVF9TSEVMTCkKCXsKCQlyZWFkX2RpcmVjdG9yeV9zaGVsbChkaXIsIGh3bmQpOwoKCQlpZiAoR2xvYmFscy5wcmVzY2FuX25vZGUpIHsKCQkJcyA9IHBhdGg7CgkJCWQgPSBidWZmZXI7CgoJCQl3aGlsZSgqcykKCQkJCSpkKysgPSAqcysrOwoKCQkJKmQrKyA9ICdcXCc7CgoJCQlmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpCgkJCQlpZiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJCXJlYWRfZGlyZWN0b3J5X3NoZWxsKGVudHJ5LCBod25kKTsKCQkJCQlTb3J0RGlyZWN0b3J5KGVudHJ5LCBzb3J0T3JkZXIpOwoJCQkJfQoJCX0KCX0KCWVsc2UKI2VuZGlmCiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCWlmIChkaXItPmV0eXBlID09IEVUX1VOSVgpCgl7CgkJcmVhZF9kaXJlY3RvcnlfdW5peChkaXIsIHBhdGgpOwoKCQlpZiAoR2xvYmFscy5wcmVzY2FuX25vZGUpIHsKCQkJcyA9IHBhdGg7CgkJCWQgPSBidWZmZXI7CgoJCQl3aGlsZSgqcykKCQkJCSpkKysgPSAqcysrOwoKCQkJKmQrKyA9ICcvJzsKCgkJCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQkJCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCQkJbHN0cmNweShkLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpOwoJCQkJCXJlYWRfZGlyZWN0b3J5X3VuaXgoZW50cnksIGJ1ZmZlcik7CgkJCQkJU29ydERpcmVjdG9yeShlbnRyeSwgc29ydE9yZGVyKTsKCQkJCX0KCQl9Cgl9CgllbHNlCiNlbmRpZgoJewoJCXJlYWRfZGlyZWN0b3J5X3dpbihkaXIsIHBhdGgpOwoKCQlpZiAoR2xvYmFscy5wcmVzY2FuX25vZGUpIHsKCQkJcyA9IHBhdGg7CgkJCWQgPSBidWZmZXI7CgoJCQl3aGlsZSgqcykKCQkJCSpkKysgPSAqcysrOwoKCQkJKmQrKyA9ICdcXCc7CgoJCQlmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpCgkJCQlpZiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJCWxzdHJjcHkoZCwgZW50cnktPmRhdGEuY0ZpbGVOYW1lKTsKCQkJCQlyZWFkX2RpcmVjdG9yeV93aW4oZW50cnksIGJ1ZmZlcik7CgkJCQkJU29ydERpcmVjdG9yeShlbnRyeSwgc29ydE9yZGVyKTsKCQkJCX0KCQl9Cgl9CgoJU29ydERpcmVjdG9yeShkaXIsIHNvcnRPcmRlcik7Cn0KCgpzdGF0aWMgRW50cnkqIHJlYWRfdHJlZShSb290KiByb290LCBMUENUU1RSIHBhdGgsIExQSVRFTUlETElTVCBwaWRsLCBMUFRTVFIgZHJ2LCBTT1JUX09SREVSIHNvcnRPcmRlciwgSFdORCBod25kKQp7CiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCXN0YXRpYyBjb25zdCBUQ0hBUiBzU2xhc2hbXSA9IHsnLycsICdcMCd9OwojZW5kaWYKCXN0YXRpYyBjb25zdCBUQ0hBUiBzQmFja3NsYXNoW10gPSB7J1xcJywgJ1wwJ307CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChwaWRsKQoJewoJCSAvKiByZWFkIHNoZWxsIG5hbWVzcGFjZSB0cmVlICovCgkJcm9vdC0+ZHJpdmVfdHlwZSA9IERSSVZFX1VOS05PV047CgkJZHJ2WzBdID0gJ1xcJzsKCQlkcnZbMV0gPSAnXDAnOwoJCWxvYWRfc3RyaW5nKHJvb3QtPnZvbG5hbWUsIElEU19ERVNLVE9QKTsKCQlyb290LT5mc19mbGFncyA9IDA7CgkJbG9hZF9zdHJpbmcocm9vdC0+ZnMsIElEU19TSEVMTCk7CgoJCXJldHVybiByZWFkX3RyZWVfc2hlbGwocm9vdCwgcGlkbCwgc29ydE9yZGVyLCBod25kKTsKCX0KCWVsc2UKI2VuZGlmCiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCWlmICgqcGF0aCA9PSAnLycpCgl7CgkJIC8qIHJlYWQgdW5peCBmaWxlIHN5c3RlbSB0cmVlICovCgkJcm9vdC0+ZHJpdmVfdHlwZSA9IEdldERyaXZlVHlwZShwYXRoKTsKCgkJbHN0cmNhdChkcnYsIHNTbGFzaCk7CgkJbG9hZF9zdHJpbmcocm9vdC0+dm9sbmFtZSwgSURTX1JPT1RfRlMpOwoJCXJvb3QtPmZzX2ZsYWdzID0gMDsKCQlsb2FkX3N0cmluZyhyb290LT5mcywgSURTX1VOSVhGUyk7CgoJCWxzdHJjcHkocm9vdC0+cGF0aCwgc1NsYXNoKTsKCgkJcmV0dXJuIHJlYWRfdHJlZV91bml4KHJvb3QsIHBhdGgsIHNvcnRPcmRlciwgaHduZCk7Cgl9CiNlbmRpZgoKCSAvKiByZWFkIFdJTjMyIGZpbGUgc3lzdGVtIHRyZWUgKi8KCXJvb3QtPmRyaXZlX3R5cGUgPSBHZXREcml2ZVR5cGUocGF0aCk7CgoJbHN0cmNhdChkcnYsIHNCYWNrc2xhc2gpOwoJR2V0Vm9sdW1lSW5mb3JtYXRpb24oZHJ2LCByb290LT52b2xuYW1lLCBfTUFYX0ZOQU1FLCAwLCAwLCAmcm9vdC0+ZnNfZmxhZ3MsIHJvb3QtPmZzLCBfTUFYX0RJUik7CgoJbHN0cmNweShyb290LT5wYXRoLCBkcnYpOwoKCXJldHVybiByZWFkX3RyZWVfd2luKHJvb3QsIHBhdGgsIHNvcnRPcmRlciwgaHduZCk7Cn0KCgovKiBmbGFncyB0byBmaWx0ZXIgZGlmZmVyZW50IGZpbGUgdHlwZXMgKi8KZW51bSBUWVBFX0ZJTFRFUiB7CglURl9ESVJFQ1RPUklFUwk9IDB4MDEsCglURl9QUk9HUkFNUwkJPSAweDAyLAoJVEZfRE9DVU1FTlRTCT0gMHgwNCwKCVRGX09USEVSUwkJPSAweDA4LAoJVEZfSElEREVOCQk9IDB4MTAsCglURl9BTEwJCQk9IDB4MUYKfTsKCgpzdGF0aWMgQ2hpbGRXbmQqIGFsbG9jX2NoaWxkX3dpbmRvdyhMUENUU1RSIHBhdGgsIExQSVRFTUlETElTVCBwaWRsLCBIV05EIGh3bmQpCnsKCVRDSEFSIGRydltfTUFYX0RSSVZFKzFdLCBkaXJbX01BWF9ESVJdLCBuYW1lW19NQVhfRk5BTUVdLCBleHRbX01BWF9FWFRdOwoJVENIQVIgZGlyX3BhdGhbTUFYX1BBVEhdOwoJVENIQVIgYjFbQlVGRkVSX0xFTl07CglzdGF0aWMgY29uc3QgVENIQVIgc0FzdGVyaWNzW10gPSB7JyonLCAnXDAnfTsKCglDaGlsZFduZCogY2hpbGQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKENoaWxkV25kKSk7CglSb290KiByb290ID0gJmNoaWxkLT5yb290OwoJRW50cnkqIGVudHJ5OwoKCW1lbXNldChjaGlsZCwgMCwgc2l6ZW9mKENoaWxkV25kKSk7CgoJY2hpbGQtPmxlZnQudHJlZVBhbmUgPSBUUlVFOwoJY2hpbGQtPmxlZnQudmlzaWJsZV9jb2xzID0gMDsKCgljaGlsZC0+cmlnaHQudHJlZVBhbmUgPSBGQUxTRTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJY2hpbGQtPnJpZ2h0LnZpc2libGVfY29scyA9IENPTF9TSVpFfENPTF9EQVRFfENPTF9USU1FfENPTF9BVFRSSUJVVEVTfENPTF9JTkRFWHxDT0xfTElOS1M7CiNlbHNlCgljaGlsZC0+cmlnaHQudmlzaWJsZV9jb2xzID0gQ09MX1NJWkV8Q09MX0RBVEV8Q09MX1RJTUV8Q09MX0FUVFJJQlVURVM7CiNlbmRpZgoKCWNoaWxkLT5wb3MubGVuZ3RoID0gc2l6ZW9mKFdJTkRPV1BMQUNFTUVOVCk7CgljaGlsZC0+cG9zLmZsYWdzID0gMDsKCWNoaWxkLT5wb3Muc2hvd0NtZCA9IFNXX1NIT1dOT1JNQUw7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ubGVmdCA9IENXX1VTRURFRkFVTFQ7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24udG9wID0gQ1dfVVNFREVGQVVMVDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5yaWdodCA9IENXX1VTRURFRkFVTFQ7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24uYm90dG9tID0gQ1dfVVNFREVGQVVMVDsKCgljaGlsZC0+Zm9jdXNfcGFuZSA9IDA7CgljaGlsZC0+c3BsaXRfcG9zID0gREVGQVVMVF9TUExJVF9QT1M7CgljaGlsZC0+c29ydE9yZGVyID0gU09SVF9OQU1FOwoJY2hpbGQtPmhlYWRlcl93ZHRoc19vayA9IEZBTFNFOwoKCWlmIChwYXRoKQoJewoJCWxzdHJjcHkoY2hpbGQtPnBhdGgsIHBhdGgpOwoKCQlfdHNwbGl0cGF0aChwYXRoLCBkcnYsIGRpciwgbmFtZSwgZXh0KTsKCX0KCglsc3RyY3B5KGNoaWxkLT5maWx0ZXJfcGF0dGVybiwgc0FzdGVyaWNzKTsKCWNoaWxkLT5maWx0ZXJfZmxhZ3MgPSBURl9BTEw7CgoJcm9vdC0+ZW50cnkubGV2ZWwgPSAwOwoKCWxzdHJjcHkoZGlyX3BhdGgsIGRydik7Cglsc3RyY2F0KGRpcl9wYXRoLCBkaXIpOwoJZW50cnkgPSByZWFkX3RyZWUocm9vdCwgZGlyX3BhdGgsIHBpZGwsIGRydiwgY2hpbGQtPnNvcnRPcmRlciwgaHduZCk7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChyb290LT5lbnRyeS5ldHlwZSA9PSBFVF9TSEVMTCkKCQlsb2FkX3N0cmluZyhyb290LT5lbnRyeS5kYXRhLmNGaWxlTmFtZSwgSURTX0RFU0tUT1ApOwoJZWxzZQojZW5kaWYKCQl3c3ByaW50Zihyb290LT5lbnRyeS5kYXRhLmNGaWxlTmFtZSwgUlMoYjEsSURTX1RJVExFRk1UKSwgZHJ2LCByb290LT5mcyk7CgoJcm9vdC0+ZW50cnkuZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzID0gRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZOwoKCWNoaWxkLT5sZWZ0LnJvb3QgPSAmcm9vdC0+ZW50cnk7CgljaGlsZC0+cmlnaHQucm9vdCA9IE5VTEw7CgoJc2V0X2N1cmRpcihjaGlsZCwgZW50cnksIDAsIGh3bmQpOwoKCXJldHVybiBjaGlsZDsKfQoKCi8qIGZyZWUgYWxsIG1lbW9yeSBhc3NvY2lhdGVkIHdpdGggYSBjaGlsZCB3aW5kb3cgKi8Kc3RhdGljIHZvaWQgZnJlZV9jaGlsZF93aW5kb3coQ2hpbGRXbmQqIGNoaWxkKQp7CglmcmVlX2VudHJpZXMoJmNoaWxkLT5yb290LmVudHJ5KTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGNoaWxkKTsKfQoKCi8qIGdldCBmdWxsIHBhdGggb2Ygc3BlY2lmaWVkIGRpcmVjdG9yeSBlbnRyeSAqLwpzdGF0aWMgdm9pZCBnZXRfcGF0aChFbnRyeSogZGlyLCBQVFNUUiBwYXRoKQp7CglFbnRyeSogZW50cnk7CglpbnQgbGVuID0gMDsKCWludCBsZXZlbCA9IDA7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChkaXItPmV0eXBlID09IEVUX1NIRUxMKQoJewoJCVNGR0FPRiBhdHRyaWJzOwoJCUhSRVNVTFQgaHIgPSBTX09LOwoKCQlwYXRoWzBdID0gJ1wwJzsKCgkJYXR0cmlicyA9IDA7CgoJCWlmIChkaXItPmZvbGRlcikKCQkJaHIgPSBJU2hlbGxGb2xkZXJfR2V0QXR0cmlidXRlc09mKGRpci0+Zm9sZGVyLCAxLCAoTFBDSVRFTUlETElTVCopJmRpci0+cGlkbCwgJmF0dHJpYnMpOwoKCQlpZiAoU1VDQ0VFREVEKGhyKSAmJiAoYXR0cmlicyZTRkdBT19GSUxFU1lTVEVNKSkgewoJCQlJU2hlbGxGb2xkZXIqIHBhcmVudCA9IGRpci0+dXA/IGRpci0+dXAtPmZvbGRlcjogR2xvYmFscy5pRGVza3RvcDsKCgkJCWhyID0gcGF0aF9mcm9tX3BpZGwocGFyZW50LCBkaXItPnBpZGwsIHBhdGgsIE1BWF9QQVRIKTsKCQl9Cgl9CgllbHNlCiNlbmRpZgoJewoJCWZvcihlbnRyeT1kaXI7IGVudHJ5OyBsZXZlbCsrKSB7CgkJCUxQQ1RTVFIgbmFtZTsKCQkJaW50IGw7CgoJCQl7CgkJCQlMUENUU1RSIHM7CgkJCQluYW1lID0gZW50cnktPmRhdGEuY0ZpbGVOYW1lOwoJCQkJcyA9IG5hbWU7CgoJCQkJZm9yKGw9MDsgKnMgJiYgKnMgIT0gJy8nICYmICpzICE9ICdcXCc7IHMrKykKCQkJCQlsKys7CgkJCX0KCgkJCWlmIChlbnRyeS0+dXApIHsKCQkJCWlmIChsID4gMCkgewoJCQkJCW1lbW1vdmUocGF0aCtsKzEsIHBhdGgsIGxlbipzaXplb2YoVENIQVIpKTsKCQkJCQltZW1jcHkocGF0aCsxLCBuYW1lLCBsKnNpemVvZihUQ0hBUikpOwoJCQkJCWxlbiArPSBsKzE7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCQkJaWYgKGVudHJ5LT5ldHlwZSA9PSBFVF9VTklYKQoJCQkJCQlwYXRoWzBdID0gJy8nOwoJCQkJCWVsc2UKI2VuZGlmCgkJCQkJcGF0aFswXSA9ICdcXCc7CgkJCQl9CgoJCQkJZW50cnkgPSBlbnRyeS0+dXA7CgkJCX0gZWxzZSB7CgkJCQltZW1tb3ZlKHBhdGgrbCwgcGF0aCwgbGVuKnNpemVvZihUQ0hBUikpOwoJCQkJbWVtY3B5KHBhdGgsIG5hbWUsIGwqc2l6ZW9mKFRDSEFSKSk7CgkJCQlsZW4gKz0gbDsKCQkJCWJyZWFrOwoJCQl9CgkJfQoKCQlpZiAoIWxldmVsKSB7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJaWYgKGVudHJ5LT5ldHlwZSA9PSBFVF9VTklYKQoJCQkJcGF0aFtsZW4rK10gPSAnLyc7CgkJCWVsc2UKI2VuZGlmCgkJCQlwYXRoW2xlbisrXSA9ICdcXCc7CgkJfQoKCQlwYXRoW2xlbl0gPSAnXDAnOwoJfQp9CgpzdGF0aWMgd2luZG93T3B0aW9ucyBsb2FkX3JlZ2lzdHJ5X3NldHRpbmdzKHZvaWQpCnsKCURXT1JEIHNpemU7CglEV09SRCB0eXBlOwoJSEtFWSBoS2V5OwoJd2luZG93T3B0aW9ucyBvcHRzOwoJTE9HRk9OVCBsb2dmb250OwoKICAgICAgICBSZWdPcGVuS2V5RXhXKCBIS0VZX0NVUlJFTlRfVVNFUiwgcmVnaXN0cnlfa2V5LAogICAgICAgICAgICAgICAgICAgICAgIDAsIEtFWV9RVUVSWV9WQUxVRSwgJmhLZXkgKTsKCglzaXplID0gc2l6ZW9mKERXT1JEKTsKCiAgICAgICAgaWYoIFJlZ1F1ZXJ5VmFsdWVFeFcoIGhLZXksIHJlZ19zdGFydF94LCBOVUxMLCAmdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQllURSkgJm9wdHMuc3RhcnRfeCwgJnNpemUgKSAhPSBFUlJPUl9TVUNDRVNTICkKCQlvcHRzLnN0YXJ0X3ggPSBDV19VU0VERUZBVUxUOwoKICAgICAgICBpZiggUmVnUXVlcnlWYWx1ZUV4VyggaEtleSwgcmVnX3N0YXJ0X3ksIE5VTEwsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSAmb3B0cy5zdGFydF95LCAmc2l6ZSApICE9IEVSUk9SX1NVQ0NFU1MgKQoJCW9wdHMuc3RhcnRfeSA9IENXX1VTRURFRkFVTFQ7CgogICAgICAgIGlmKCBSZWdRdWVyeVZhbHVlRXhXKCBoS2V5LCByZWdfd2lkdGgsIE5VTEwsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSAmb3B0cy53aWR0aCwgJnNpemUgKSAhPSBFUlJPUl9TVUNDRVNTICkKCQlvcHRzLndpZHRoID0gQ1dfVVNFREVGQVVMVDsKCiAgICAgICAgaWYoIFJlZ1F1ZXJ5VmFsdWVFeFcoIGhLZXksIHJlZ19oZWlnaHQsIE5VTEwsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSAmb3B0cy5oZWlnaHQsICZzaXplICkgIT0gRVJST1JfU1VDQ0VTUyApCgkJb3B0cy5oZWlnaHQgPSBDV19VU0VERUZBVUxUOwoJc2l6ZT1zaXplb2YobG9nZm9udCk7CglpZiggUmVnUXVlcnlWYWx1ZUV4VyggaEtleSwgcmVnX2xvZ2ZvbnQsIE5VTEwsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSAmbG9nZm9udCwgJnNpemUgKSAhPSBFUlJPUl9TVUNDRVNTICkKCQlHZXRPYmplY3QoR2V0U3RvY2tPYmplY3QoREVGQVVMVF9HVUlfRk9OVCksc2l6ZW9mKGxvZ2ZvbnQpLCZsb2dmb250KTsKCglSZWdDbG9zZUtleSggaEtleSApOwoKCUdsb2JhbHMuaGZvbnQgPSBDcmVhdGVGb250SW5kaXJlY3QoJmxvZ2ZvbnQpOwoJcmV0dXJuIG9wdHM7Cn0KCnN0YXRpYyB2b2lkIHNhdmVfcmVnaXN0cnlfc2V0dGluZ3Modm9pZCkKewoJV0lORE9XSU5GTyB3aTsKCUhLRVkgaEtleTsKCUlOVCB3aWR0aCwgaGVpZ2h0OwoJTE9HRk9OVCBsb2dmb250OwoKCXdpLmNiU2l6ZSA9IHNpemVvZiggV0lORE9XSU5GTyApOwoJR2V0V2luZG93SW5mbyhHbG9iYWxzLmhNYWluV25kLCAmd2kpOwoJd2lkdGggPSB3aS5yY1dpbmRvdy5yaWdodCAtIHdpLnJjV2luZG93LmxlZnQ7CgloZWlnaHQgPSB3aS5yY1dpbmRvdy5ib3R0b20gLSB3aS5yY1dpbmRvdy50b3A7CgoJaWYgKCBSZWdPcGVuS2V5RXhXKCBIS0VZX0NVUlJFTlRfVVNFUiwgcmVnaXN0cnlfa2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgS0VZX1NFVF9WQUxVRSwgJmhLZXkgKSAhPSBFUlJPUl9TVUNDRVNTICkKCXsKCQkvKiBVbmFibGUgdG8gc2F2ZSByZWdpc3RyeSBzZXR0aW5ncyAtIHRyeSB0byBjcmVhdGUga2V5ICovCiAgICAgICAgICAgICAgICBpZiAoIFJlZ0NyZWF0ZUtleUV4VyggSEtFWV9DVVJSRU5UX1VTRVIsIHJlZ2lzdHJ5X2tleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBOVUxMLCBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfU0VUX1ZBTFVFLCBOVUxMLCAmaEtleSwgTlVMTCApICE9IEVSUk9SX1NVQ0NFU1MgKQoJCXsKCQkJLyogRklYTUU6IENhbm5vdCBjcmVhdGUga2V5ICovCgkJCXJldHVybjsKCQl9Cgl9CgkvKiBTYXZlIGFsbCBvZiB0aGUgc2V0dGluZ3MgKi8KICAgICAgICBSZWdTZXRWYWx1ZUV4VyggaEtleSwgcmVnX3N0YXJ0X3gsIDAsIFJFR19EV09SRCwKICAgICAgICAgICAgICAgICAgICAgICAgKExQQllURSkgJndpLnJjV2luZG93LmxlZnQsIHNpemVvZihEV09SRCkgKTsKICAgICAgICBSZWdTZXRWYWx1ZUV4VyggaEtleSwgcmVnX3N0YXJ0X3ksIDAsIFJFR19EV09SRCwKICAgICAgICAgICAgICAgICAgICAgICAgKExQQllURSkgJndpLnJjV2luZG93LnRvcCwgc2l6ZW9mKERXT1JEKSApOwogICAgICAgIFJlZ1NldFZhbHVlRXhXKCBoS2V5LCByZWdfd2lkdGgsIDAsIFJFR19EV09SRCwKICAgICAgICAgICAgICAgICAgICAgICAgKExQQllURSkgJndpZHRoLCBzaXplb2YoRFdPUkQpICk7CiAgICAgICAgUmVnU2V0VmFsdWVFeFcoIGhLZXksIHJlZ19oZWlnaHQsIDAsIFJFR19EV09SRCwKICAgICAgICAgICAgICAgICAgICAgICAgKExQQllURSkgJmhlaWdodCwgc2l6ZW9mKERXT1JEKSApOwogICAgICAgIEdldE9iamVjdChHbG9iYWxzLmhmb250LCBzaXplb2YobG9nZm9udCksICZsb2dmb250KTsKICAgICAgICBSZWdTZXRWYWx1ZUV4VyggaEtleSwgcmVnX2xvZ2ZvbnQsIDAsIFJFR19CSU5BUlksCiAgICAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpICZsb2dmb250LCBzaXplb2YoTE9HRk9OVCkgKTsKCgkvKiBUT0RPOiBTYXZlIG1vcmUgc2V0dGluZ3MgaGVyZSAoTGlzdCB2cy4gRGV0YWlsZWQgVmlldywgZXRjLikgKi8KCVJlZ0Nsb3NlS2V5KCBoS2V5ICk7Cn0KCnN0YXRpYyB2b2lkIHJlc2l6ZV9mcmFtZV9yZWN0KEhXTkQgaHduZCwgUFJFQ1QgcHJlY3QpCnsKCWludCBuZXdfdG9wOwoJUkVDVCBydDsKCglpZiAoSXNXaW5kb3dWaXNpYmxlKEdsb2JhbHMuaHRvb2xiYXIpKSB7CgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5odG9vbGJhciwgV01fU0laRSwgMCwgMCk7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmh0b29sYmFyLCAmcnQpOwoJCXByZWN0LT50b3AgPSBydC5ib3R0b20rMzsKCQlwcmVjdC0+Ym90dG9tIC09IHJ0LmJvdHRvbSszOwoJfQoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5oZHJpdmViYXIpKSB7CgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFdNX1NJWkUsIDAsIDApOwoJCUdldENsaWVudFJlY3QoR2xvYmFscy5oZHJpdmViYXIsICZydCk7CgkJbmV3X3RvcCA9IC0tcHJlY3QtPnRvcCArIHJ0LmJvdHRvbSszOwoJCU1vdmVXaW5kb3coR2xvYmFscy5oZHJpdmViYXIsIDAsIHByZWN0LT50b3AsIHJ0LnJpZ2h0LCBuZXdfdG9wLCBUUlVFKTsKCQlwcmVjdC0+dG9wID0gbmV3X3RvcDsKCQlwcmVjdC0+Ym90dG9tIC09IHJ0LmJvdHRvbSsyOwoJfQoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5oc3RhdHVzYmFyKSkgewoJCWludCBwYXJ0c1tdID0gezMwMCwgNTAwfTsKCgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oc3RhdHVzYmFyLCBXTV9TSVpFLCAwLCAwKTsKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhzdGF0dXNiYXIsIFNCX1NFVFBBUlRTLCAyLCAoTFBBUkFNKSZwYXJ0cyk7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmhzdGF0dXNiYXIsICZydCk7CgkJcHJlY3QtPmJvdHRvbSAtPSBydC5ib3R0b207Cgl9CgoJTW92ZVdpbmRvdyhHbG9iYWxzLmhtZGljbGllbnQsIHByZWN0LT5sZWZ0LTEscHJlY3QtPnRvcC0xLHByZWN0LT5yaWdodCsyLHByZWN0LT5ib3R0b20rMSwgVFJVRSk7Cn0KCnN0YXRpYyB2b2lkIHJlc2l6ZV9mcmFtZShIV05EIGh3bmQsIGludCBjeCwgaW50IGN5KQp7CglSRUNUIHJlY3Q7CgoJcmVjdC5sZWZ0ICAgPSAwOwoJcmVjdC50b3AgICAgPSAwOwoJcmVjdC5yaWdodCAgPSBjeDsKCXJlY3QuYm90dG9tID0gY3k7CgoJcmVzaXplX2ZyYW1lX3JlY3QoaHduZCwgJnJlY3QpOwp9CgpzdGF0aWMgdm9pZCByZXNpemVfZnJhbWVfY2xpZW50KEhXTkQgaHduZCkKewoJUkVDVCByZWN0OwoKCUdldENsaWVudFJlY3QoaHduZCwgJnJlY3QpOwoKCXJlc2l6ZV9mcmFtZV9yZWN0KGh3bmQsICZyZWN0KTsKfQoKCnN0YXRpYyBISE9PSyBoY2J0aG9vazsKc3RhdGljIENoaWxkV25kKiBuZXdjaGlsZCA9IE5VTEw7CgpzdGF0aWMgTFJFU1VMVCBDQUxMQkFDSyBDQlRQcm9jKGludCBjb2RlLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglpZiAoY29kZT09SENCVF9DUkVBVEVXTkQgJiYgbmV3Y2hpbGQpIHsKCQlDaGlsZFduZCogY2hpbGQgPSBuZXdjaGlsZDsKCQluZXdjaGlsZCA9IE5VTEw7CgoJCWNoaWxkLT5od25kID0gKEhXTkQpIHdwYXJhbTsKCQlTZXRXaW5kb3dMb25nUHRyKGNoaWxkLT5od25kLCBHV0xQX1VTRVJEQVRBLCAoTFBBUkFNKWNoaWxkKTsKCX0KCglyZXR1cm4gQ2FsbE5leHRIb29rRXgoaGNidGhvb2ssIGNvZGUsIHdwYXJhbSwgbHBhcmFtKTsKfQoKc3RhdGljIEhXTkQgY3JlYXRlX2NoaWxkX3dpbmRvdyhDaGlsZFduZCogY2hpbGQpCnsKCU1ESUNSRUFURVNUUlVDVCBtY3M7CglpbnQgaWR4OwoKCW1jcy5zekNsYXNzID0gc1dJTkVGSUxFVFJFRTsKCW1jcy5zelRpdGxlID0gKExQVFNUUiljaGlsZC0+cGF0aDsKCW1jcy5oT3duZXIgID0gR2xvYmFscy5oSW5zdGFuY2U7CgltY3MueCAgICAgICA9IGNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5sZWZ0OwoJbWNzLnkgICAgICAgPSBjaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24udG9wOwoJbWNzLmN4ICAgICAgPSBjaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ucmlnaHQtY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmxlZnQ7CgltY3MuY3kgICAgICA9IGNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5ib3R0b20tY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLnRvcDsKCW1jcy5zdHlsZSAgID0gMDsKCW1jcy5sUGFyYW0gID0gMDsKCgloY2J0aG9vayA9IFNldFdpbmRvd3NIb29rRXgoV0hfQ0JULCBDQlRQcm9jLCAwLCBHZXRDdXJyZW50VGhyZWFkSWQoKSk7CgoJbmV3Y2hpbGQgPSBjaGlsZDsKCWNoaWxkLT5od25kID0gKEhXTkQpIFNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJQ1JFQVRFLCAwLCAoTFBBUkFNKSZtY3MpOwoJaWYgKCFjaGlsZC0+aHduZCkgewoJCVVuaG9va1dpbmRvd3NIb29rRXgoaGNidGhvb2spOwoJCXJldHVybiAwOwoJfQoKCVVuaG9va1dpbmRvd3NIb29rRXgoaGNidGhvb2spOwoKCVNlbmRNZXNzYWdlKGNoaWxkLT5sZWZ0Lmh3bmQsIExCX1NFVElURU1IRUlHSFQsIDEsIG1heChHbG9iYWxzLnNwYWNlU2l6ZS5jeSxJTUFHRV9IRUlHSFQrMykpOwoJU2VuZE1lc3NhZ2UoY2hpbGQtPnJpZ2h0Lmh3bmQsIExCX1NFVElURU1IRUlHSFQsIDEsIG1heChHbG9iYWxzLnNwYWNlU2l6ZS5jeSxJTUFHRV9IRUlHSFQrMykpOwoKCWlkeCA9IFNlbmRNZXNzYWdlKGNoaWxkLT5sZWZ0Lmh3bmQsIExCX0ZJTkRTVFJJTkcsIDAsIChMUEFSQU0pY2hpbGQtPmxlZnQuY3VyKTsKCVNlbmRNZXNzYWdlKGNoaWxkLT5sZWZ0Lmh3bmQsIExCX1NFVENVUlNFTCwgaWR4LCAwKTsKCglyZXR1cm4gY2hpbGQtPmh3bmQ7Cn0KCgpzdHJ1Y3QgRXhlY3V0ZURpYWxvZyB7CglUQ0hBUgljbWRbTUFYX1BBVEhdOwoJaW50CQljbWRzaG93Owp9OwoKc3RhdGljIElOVF9QVFIgQ0FMTEJBQ0sgRXhlY3V0ZURpYWxvZ0RsZ1Byb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCXN0YXRpYyBzdHJ1Y3QgRXhlY3V0ZURpYWxvZyogZGxnOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9JTklURElBTE9HOgoJCQlkbGcgPSAoc3RydWN0IEV4ZWN1dGVEaWFsb2cqKSBscGFyYW07CgkJCXJldHVybiAxOwoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJaW50IGlkID0gKGludCl3cGFyYW07CgoJCQlpZiAoaWQgPT0gSURPSykgewoJCQkJR2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIDIwMSksIGRsZy0+Y21kLCBNQVhfUEFUSCk7CgkJCQlkbGctPmNtZHNob3cgPSBnZXRfY2hlY2soaHduZCwyMTQpID8gU1dfU0hPV01JTklNSVpFRCA6IFNXX1NIT1dOT1JNQUw7CgkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoJCQl9IGVsc2UgaWYgKGlkID09IElEQ0FOQ0VMKQoJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCgkJCXJldHVybiAxO30KCX0KCglyZXR1cm4gMDsKfQoKCnN0YXRpYyBJTlRfUFRSIENBTExCQUNLIERlc3RpbmF0aW9uRGxnUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJVENIQVIgYjFbQlVGRkVSX0xFTl0sIGIyW0JVRkZFUl9MRU5dOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9JTklURElBTE9HOgoJCQlTZXRXaW5kb3dMb25nUHRyKGh3bmQsIEdXTFBfVVNFUkRBVEEsIGxwYXJhbSk7CgkJCVNldFdpbmRvd1RleHQoR2V0RGxnSXRlbShod25kLCAyMDEpLCAoTFBDVFNUUilscGFyYW0pOwoJCQlyZXR1cm4gMTsKCgkJY2FzZSBXTV9DT01NQU5EOiB7CgkJCWludCBpZCA9IChpbnQpd3BhcmFtOwoKCQkJc3dpdGNoKGlkKSB7CgkJCSAgY2FzZSBJRE9LOiB7CgkJCQlMUFRTVFIgZGVzdCA9IChMUFRTVFIpIEdldFdpbmRvd0xvbmdQdHIoaHduZCwgR1dMUF9VU0VSREFUQSk7CgkJCQlHZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgMjAxKSwgZGVzdCwgTUFYX1BBVEgpOwoJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCQkJCWJyZWFrO30KCgkJCSAgY2FzZSBJRENBTkNFTDoKCQkJCUVuZERpYWxvZyhod25kLCBpZCk7CgkJCQlicmVhazsKCgkJCSAgY2FzZSAyNTQ6CgkJCQlNZXNzYWdlQm94KGh3bmQsIFJTKGIxLElEU19OT19JTVBMKSwgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwoJCQkJYnJlYWs7CgkJCX0KCgkJCXJldHVybiAxOwoJCX0KCX0KCglyZXR1cm4gMDsKfQoKCnN0cnVjdCBGaWx0ZXJEaWFsb2cgewoJVENIQVIJcGF0dGVybltNQVhfUEFUSF07CglpbnQJCWZsYWdzOwp9OwoKc3RhdGljIElOVF9QVFIgQ0FMTEJBQ0sgRmlsdGVyRGlhbG9nRGxnUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJc3RhdGljIHN0cnVjdCBGaWx0ZXJEaWFsb2cqIGRsZzsKCglzd2l0Y2gobm1zZykgewoJCWNhc2UgV01fSU5JVERJQUxPRzoKCQkJZGxnID0gKHN0cnVjdCBGaWx0ZXJEaWFsb2cqKSBscGFyYW07CgkJCVNldFdpbmRvd1RleHQoR2V0RGxnSXRlbShod25kLCBJRENfVklFV19QQVRURVJOKSwgZGxnLT5wYXR0ZXJuKTsKCQkJc2V0X2NoZWNrKGh3bmQsIElEQ19WSUVXX1RZUEVfRElSRUNUT1JJRVMsIGRsZy0+ZmxhZ3MmVEZfRElSRUNUT1JJRVMpOwoJCQlzZXRfY2hlY2soaHduZCwgSURDX1ZJRVdfVFlQRV9QUk9HUkFNUywgZGxnLT5mbGFncyZURl9QUk9HUkFNUyk7CgkJCXNldF9jaGVjayhod25kLCBJRENfVklFV19UWVBFX0RPQ1VNRU5UUywgZGxnLT5mbGFncyZURl9ET0NVTUVOVFMpOwoJCQlzZXRfY2hlY2soaHduZCwgSURDX1ZJRVdfVFlQRV9PVEhFUlMsIGRsZy0+ZmxhZ3MmVEZfT1RIRVJTKTsKCQkJc2V0X2NoZWNrKGh3bmQsIElEQ19WSUVXX1RZUEVfSElEREVOLCBkbGctPmZsYWdzJlRGX0hJRERFTik7CgkJCXJldHVybiAxOwoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJaW50IGlkID0gKGludCl3cGFyYW07CgoJCQlpZiAoaWQgPT0gSURPSykgewoJCQkJaW50IGZsYWdzID0gMDsKCgkJCQlHZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgSURDX1ZJRVdfUEFUVEVSTiksIGRsZy0+cGF0dGVybiwgTUFYX1BBVEgpOwoKCQkJCWZsYWdzIHw9IGdldF9jaGVjayhod25kLCBJRENfVklFV19UWVBFX0RJUkVDVE9SSUVTKSA/IFRGX0RJUkVDVE9SSUVTIDogMDsKCQkJCWZsYWdzIHw9IGdldF9jaGVjayhod25kLCBJRENfVklFV19UWVBFX1BST0dSQU1TKSA/IFRGX1BST0dSQU1TIDogMDsKCQkJCWZsYWdzIHw9IGdldF9jaGVjayhod25kLCBJRENfVklFV19UWVBFX0RPQ1VNRU5UUykgPyBURl9ET0NVTUVOVFMgOiAwOwoJCQkJZmxhZ3MgfD0gZ2V0X2NoZWNrKGh3bmQsIElEQ19WSUVXX1RZUEVfT1RIRVJTKSA/IFRGX09USEVSUyA6IDA7CgkJCQlmbGFncyB8PSBnZXRfY2hlY2soaHduZCwgSURDX1ZJRVdfVFlQRV9ISURERU4pID8gVEZfSElEREVOIDogMDsKCgkJCQlkbGctPmZsYWdzID0gZmxhZ3M7CgoJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCQkJfSBlbHNlIGlmIChpZCA9PSBJRENBTkNFTCkKCQkJCUVuZERpYWxvZyhod25kLCBpZCk7CgoJCQlyZXR1cm4gMTt9Cgl9CgoJcmV0dXJuIDA7Cn0KCgpzdHJ1Y3QgUHJvcGVydGllc0RpYWxvZyB7CglUQ0hBUglwYXRoW01BWF9QQVRIXTsKCUVudHJ5CWVudHJ5OwoJdm9pZCoJcFZlcnNpb25EYXRhOwp9OwoKLyogU3RydWN0dXJlIHVzZWQgdG8gc3RvcmUgZW51bWVyYXRlZCBsYW5ndWFnZXMgYW5kIGNvZGUgcGFnZXMuICovCnN0cnVjdCBMQU5HQU5EQ09ERVBBR0UgewoJV09SRCB3TGFuZ3VhZ2U7CglXT1JEIHdDb2RlUGFnZTsKfSAqbHBUcmFuc2xhdGU7CgpzdGF0aWMgTFBDU1RSIEluZm9TdHJpbmdzW10gPSB7CgkiQ29tbWVudHMiLAoJIkNvbXBhbnlOYW1lIiwKCSJGaWxlRGVzY3JpcHRpb24iLAoJIkZpbGVWZXJzaW9uIiwKCSJJbnRlcm5hbE5hbWUiLAoJIkxlZ2FsQ29weXJpZ2h0IiwKCSJMZWdhbFRyYWRlbWFya3MiLAoJIk9yaWdpbmFsRmlsZW5hbWUiLAoJIlByaXZhdGVCdWlsZCIsCgkiUHJvZHVjdE5hbWUiLAoJIlByb2R1Y3RWZXJzaW9uIiwKCSJTcGVjaWFsQnVpbGQiLAoJTlVMTAp9OwoKc3RhdGljIHZvaWQgUHJvcERsZ19EaXNwbGF5VmFsdWUoSFdORCBobGJveCwgSFdORCBoZWRpdCkKewoJaW50IGlkeCA9IFNlbmRNZXNzYWdlKGhsYm94LCBMQl9HRVRDVVJTRUwsIDAsIDApOwoKCWlmIChpZHggIT0gTEJfRVJSKSB7CgkJTFBDVFNUUiBwVmFsdWUgPSAoTFBDVFNUUikgU2VuZE1lc3NhZ2UoaGxib3gsIExCX0dFVElURU1EQVRBLCBpZHgsIDApOwoKCQlpZiAocFZhbHVlKQoJCQlTZXRXaW5kb3dUZXh0KGhlZGl0LCBwVmFsdWUpOwoJfQp9CgpzdGF0aWMgdm9pZCBDaGVja0ZvckZpbGVJbmZvKHN0cnVjdCBQcm9wZXJ0aWVzRGlhbG9nKiBkbGcsIEhXTkQgaHduZCwgTFBDVFNUUiBzdHJGaWxlbmFtZSkKewoJc3RhdGljIFRDSEFSIHNCYWNrU2xhc2hbXSA9IHsnXFwnLCdcMCd9OwoJc3RhdGljIFRDSEFSIHNUcmFuc2xhdGlvbltdID0geydcXCcsJ1YnLCdhJywncicsJ0YnLCdpJywnbCcsJ2UnLCdJJywnbicsJ2YnLCdvJywnXFwnLCdUJywncicsJ2EnLCduJywncycsJ2wnLCdhJywndCcsJ2knLCdvJywnbicsJ1wwJ307CglzdGF0aWMgVENIQVIgc1N0cmluZ0ZpbGVJbmZvW10gPSB7J1xcJywnUycsJ3QnLCdyJywnaScsJ24nLCdnJywnRicsJ2knLCdsJywnZScsJ0knLCduJywnZicsJ28nLCdcXCcsCgkJCQkJCQkJCQknJScsJzAnLCc0JywneCcsJyUnLCcwJywnNCcsJ3gnLCdcXCcsJyUnLCdzJywnXDAnfTsKCURXT1JEIGR3VmVyc2lvbkRhdGFMZW4gPSBHZXRGaWxlVmVyc2lvbkluZm9TaXplKHN0ckZpbGVuYW1lLCBOVUxMKTsKCglpZiAoZHdWZXJzaW9uRGF0YUxlbikgewoJCWRsZy0+cFZlcnNpb25EYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGR3VmVyc2lvbkRhdGFMZW4pOwoKCQlpZiAoR2V0RmlsZVZlcnNpb25JbmZvKHN0ckZpbGVuYW1lLCAwLCBkd1ZlcnNpb25EYXRhTGVuLCBkbGctPnBWZXJzaW9uRGF0YSkpIHsKCQkJTFBWT0lEIHBWYWw7CgkJCVVJTlQgblZhbExlbjsKCgkJCWlmIChWZXJRdWVyeVZhbHVlKGRsZy0+cFZlcnNpb25EYXRhLCBzQmFja1NsYXNoLCAmcFZhbCwgJm5WYWxMZW4pKSB7CgkJCQlpZiAoblZhbExlbiA9PSBzaXplb2YoVlNfRklYRURGSUxFSU5GTykpIHsKCQkJCQlWU19GSVhFREZJTEVJTkZPKiBwRml4ZWRGaWxlSW5mbyA9IChWU19GSVhFREZJTEVJTkZPKilwVmFsOwoJCQkJCWNoYXIgYnVmZmVyW0JVRkZFUl9MRU5dOwoKCQkJCQlzcHJpbnRmKGJ1ZmZlciwgIiVkLiVkLiVkLiVkIiwKCQkJCQkJSElXT1JEKHBGaXhlZEZpbGVJbmZvLT5kd0ZpbGVWZXJzaW9uTVMpLCBMT1dPUkQocEZpeGVkRmlsZUluZm8tPmR3RmlsZVZlcnNpb25NUyksCgkJCQkJCUhJV09SRChwRml4ZWRGaWxlSW5mby0+ZHdGaWxlVmVyc2lvbkxTKSwgTE9XT1JEKHBGaXhlZEZpbGVJbmZvLT5kd0ZpbGVWZXJzaW9uTFMpKTsKCgkJCQkJU2V0RGxnSXRlbVRleHRBKGh3bmQsIElEQ19TVEFUSUNfUFJPUF9WRVJTSU9OLCBidWZmZXIpOwoJCQkJfQoJCQl9CgoJCQkvKiBSZWFkIHRoZSBsaXN0IG9mIGxhbmd1YWdlcyBhbmQgY29kZSBwYWdlcy4gKi8KCQkJaWYgKFZlclF1ZXJ5VmFsdWUoZGxnLT5wVmVyc2lvbkRhdGEsIHNUcmFuc2xhdGlvbiwgJnBWYWwsICZuVmFsTGVuKSkgewoJCQkJc3RydWN0IExBTkdBTkRDT0RFUEFHRSogcFRyYW5zbGF0ZSA9IChzdHJ1Y3QgTEFOR0FORENPREVQQUdFKilwVmFsOwoJCQkJc3RydWN0IExBTkdBTkRDT0RFUEFHRSogcEVuZCA9IChzdHJ1Y3QgTEFOR0FORENPREVQQUdFKikoKExQQllURSlwVmFsK25WYWxMZW4pOwoKCQkJCUhXTkQgaGxib3ggPSBHZXREbGdJdGVtKGh3bmQsIElEQ19MSVNUX1BST1BfVkVSU0lPTl9UWVBFUyk7CgoJCQkJLyogUmVhZCB0aGUgZmlsZSBkZXNjcmlwdGlvbiBmb3IgZWFjaCBsYW5ndWFnZSBhbmQgY29kZSBwYWdlLiAqLwoJCQkJZm9yKDsgcFRyYW5zbGF0ZTxwRW5kOyArK3BUcmFuc2xhdGUpIHsKCQkJCQlMUENTVFIqIHA7CgoJCQkJCWZvcihwPUluZm9TdHJpbmdzOyAqcDsgKytwKSB7CgkJCQkJCVRDSEFSIHN1YmJsb2NrWzIwMF07CiNpZmRlZiBVTklDT0RFCgkJCQkJCVRDSEFSIGluZm9TdHJbMTAwXTsKI2VuZGlmCgkJCQkJCUxQQ1RTVFIgcFR4dDsKCQkJCQkJVUlOVCBuVmFsTGVuOwoKCQkJCQkJTFBDU1RSIHBJbmZvU3RyaW5nID0gKnA7CiNpZmRlZiBVTklDT0RFCgkJCQkJCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBwSW5mb1N0cmluZywgLTEsIGluZm9TdHIsIDEwMCk7CiNlbHNlCiNkZWZpbmUJaW5mb1N0ciBwSW5mb1N0cmluZwojZW5kaWYKCQkJCQkJd3NwcmludGYoc3ViYmxvY2ssIHNTdHJpbmdGaWxlSW5mbywgcFRyYW5zbGF0ZS0+d0xhbmd1YWdlLCBwVHJhbnNsYXRlLT53Q29kZVBhZ2UsIGluZm9TdHIpOwoKCQkJCQkJLyogUmV0cmlldmUgZmlsZSBkZXNjcmlwdGlvbiBmb3IgbGFuZ3VhZ2UgYW5kIGNvZGUgcGFnZSAqLwoJCQkJCQlpZiAoVmVyUXVlcnlWYWx1ZShkbGctPnBWZXJzaW9uRGF0YSwgc3ViYmxvY2ssIChQVk9JRCkmcFR4dCwgJm5WYWxMZW4pKSB7CgkJCQkJCQlpbnQgaWR4ID0gU2VuZE1lc3NhZ2UoaGxib3gsIExCX0FERFNUUklORywgMEwsIChMUEFSQU0paW5mb1N0cik7CgkJCQkJCQlTZW5kTWVzc2FnZShobGJveCwgTEJfU0VUSVRFTURBVEEsIGlkeCwgKExQQVJBTSkgcFR4dCk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgoJCQkJU2VuZE1lc3NhZ2UoaGxib3gsIExCX1NFVENVUlNFTCwgMCwgMCk7CgoJCQkJUHJvcERsZ19EaXNwbGF5VmFsdWUoaGxib3gsIEdldERsZ0l0ZW0oaHduZCxJRENfTElTVF9QUk9QX1ZFUlNJT05fVkFMVUVTKSk7CgkJCX0KCQl9Cgl9Cn0KCnN0YXRpYyBJTlRfUFRSIENBTExCQUNLIFByb3BlcnRpZXNEaWFsb2dEbGdQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglzdGF0aWMgc3RydWN0IFByb3BlcnRpZXNEaWFsb2cqIGRsZzsKCglzd2l0Y2gobm1zZykgewoJCWNhc2UgV01fSU5JVERJQUxPRzogewoJCQlzdGF0aWMgY29uc3QgVENIQVIgc0J5dGVGbXRbXSA9IHsnJScsJ3MnLCcgJywnQicsJ3knLCd0JywnZScsJ3MnLCdcMCd9OwoJCQlUQ0hBUiBiMVtCVUZGRVJfTEVOXSwgYjJbQlVGRkVSX0xFTl07CgkJCUxQV0lOMzJfRklORF9EQVRBIHBXRkQ7CgkJCVVMT05HTE9ORyBzaXplOwoKCQkJZGxnID0gKHN0cnVjdCBQcm9wZXJ0aWVzRGlhbG9nKikgbHBhcmFtOwoJCQlwV0ZEID0gKExQV0lOMzJfRklORF9EQVRBKSAmZGxnLT5lbnRyeS5kYXRhOwoKCQkJR2V0V2luZG93VGV4dChod25kLCBiMSwgTUFYX1BBVEgpOwoJCQl3c3ByaW50ZihiMiwgYjEsIHBXRkQtPmNGaWxlTmFtZSk7CgkJCVNldFdpbmRvd1RleHQoaHduZCwgYjIpOwoKCQkJZm9ybWF0X2RhdGUoJnBXRkQtPmZ0TGFzdFdyaXRlVGltZSwgYjEsIENPTF9EQVRFfENPTF9USU1FKTsKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIElEQ19TVEFUSUNfUFJPUF9MQVNUQ0hBTkdFKSwgYjEpOwoKCQkJc2l6ZSA9ICgoVUxPTkdMT05HKXBXRkQtPm5GaWxlU2l6ZUhpZ2ggPDwgMzIpIHwgcFdGRC0+bkZpbGVTaXplTG93OwoJCQlfc3RwcmludGYoYjEsIHNMb25nTnVtRm10LCBzaXplKTsKCQkJd3NwcmludGYoYjIsIHNCeXRlRm10LCBiMSk7CgkJCVNldFdpbmRvd1RleHQoR2V0RGxnSXRlbShod25kLCBJRENfU1RBVElDX1BST1BfU0laRSksIGIyKTsKCgkJCVNldFdpbmRvd1RleHQoR2V0RGxnSXRlbShod25kLCBJRENfU1RBVElDX1BST1BfRklMRU5BTUUpLCBwV0ZELT5jRmlsZU5hbWUpOwoJCQlTZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgSURDX1NUQVRJQ19QUk9QX1BBVEgpLCBkbGctPnBhdGgpOwoKCQkJc2V0X2NoZWNrKGh3bmQsIElEQ19DSEVDS19SRUFET05MWSwgcFdGRC0+ZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9SRUFET05MWSk7CgkJCXNldF9jaGVjayhod25kLCBJRENfQ0hFQ0tfQVJDSElWRSwgcFdGRC0+ZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9BUkNISVZFKTsKCQkJc2V0X2NoZWNrKGh3bmQsIElEQ19DSEVDS19DT01QUkVTU0VELCBwV0ZELT5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0NPTVBSRVNTRUQpOwoJCQlzZXRfY2hlY2soaHduZCwgSURDX0NIRUNLX0hJRERFTiwgcFdGRC0+ZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9ISURERU4pOwoJCQlzZXRfY2hlY2soaHduZCwgSURDX0NIRUNLX1NZU1RFTSwgcFdGRC0+ZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9TWVNURU0pOwoKCQkJQ2hlY2tGb3JGaWxlSW5mbyhkbGcsIGh3bmQsIGRsZy0+cGF0aCk7CgkJCXJldHVybiAxO30KCgkJY2FzZSBXTV9DT01NQU5EOiB7CgkJCWludCBpZCA9IChpbnQpd3BhcmFtOwoKCQkJc3dpdGNoKEhJV09SRCh3cGFyYW0pKSB7CgkJCSAgY2FzZSBMQk5fU0VMQ0hBTkdFOiB7CgkJCQlIV05EIGhsYm94ID0gR2V0RGxnSXRlbShod25kLCBJRENfTElTVF9QUk9QX1ZFUlNJT05fVFlQRVMpOwoJCQkJUHJvcERsZ19EaXNwbGF5VmFsdWUoaGxib3gsIEdldERsZ0l0ZW0oaHduZCxJRENfTElTVF9QUk9QX1ZFUlNJT05fVkFMVUVTKSk7CgkJCQlicmVhazsKCQkJICB9CgoJCQkgIGNhc2UgQk5fQ0xJQ0tFRDoKCQkJCWlmIChpZD09SURPSyB8fCBpZD09SURDQU5DRUwpCgkJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCQkJfQoKCQkJcmV0dXJuIDE7fQoKCQljYXNlIFdNX05DREVTVFJPWToKCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZGxnLT5wVmVyc2lvbkRhdGEpOwoJCQlkbGctPnBWZXJzaW9uRGF0YSA9IE5VTEw7CgkJCWJyZWFrOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBzaG93X3Byb3BlcnRpZXNfZGxnKEVudHJ5KiBlbnRyeSwgSFdORCBod25kKQp7CglzdHJ1Y3QgUHJvcGVydGllc0RpYWxvZyBkbGc7CgoJbWVtc2V0KCZkbGcsIDAsIHNpemVvZihzdHJ1Y3QgUHJvcGVydGllc0RpYWxvZykpOwoJZ2V0X3BhdGgoZW50cnksIGRsZy5wYXRoKTsKCW1lbWNweSgmZGxnLmVudHJ5LCBlbnRyeSwgc2l6ZW9mKEVudHJ5KSk7CgoJRGlhbG9nQm94UGFyYW0oR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRERfRElBTE9HX1BST1BFUlRJRVMpLCBod25kLCBQcm9wZXJ0aWVzRGlhbG9nRGxnUHJvYywgKExQQVJBTSkmZGxnKTsKfQoKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCnN0YXRpYyBzdHJ1Y3QgRnVsbFNjcmVlblBhcmFtZXRlcnMgewoJQk9PTAltb2RlOwoJUkVDVAlvcmdQb3M7CglCT09MCXdhc1pvb21lZDsKfSBnX2Z1bGxzY3JlZW4gPSB7CiAgICBGQUxTRSwJLyogbW9kZSAqLwoJezAsIDAsIDAsIDB9LAoJRkFMU0UKfTsKCnN0YXRpYyB2b2lkIGZyYW1lX2dldF9jbGllbnRzcGFjZShIV05EIGh3bmQsIFBSRUNUIHByZWN0KQp7CglSRUNUIHJ0OwoKCWlmICghSXNJY29uaWMoaHduZCkpCgkJR2V0Q2xpZW50UmVjdChod25kLCBwcmVjdCk7CgllbHNlIHsKCQlXSU5ET1dQTEFDRU1FTlQgd3A7CgoJCUdldFdpbmRvd1BsYWNlbWVudChod25kLCAmd3ApOwoKCQlwcmVjdC0+bGVmdCA9IHByZWN0LT50b3AgPSAwOwoJCXByZWN0LT5yaWdodCA9IHdwLnJjTm9ybWFsUG9zaXRpb24ucmlnaHQtd3AucmNOb3JtYWxQb3NpdGlvbi5sZWZ0LQoJCQkJCQkyKihHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRUZSQU1FKStHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRURHRSkpOwoJCXByZWN0LT5ib3R0b20gPSB3cC5yY05vcm1hbFBvc2l0aW9uLmJvdHRvbS13cC5yY05vcm1hbFBvc2l0aW9uLnRvcC0KCQkJCQkJMiooR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkVGUkFNRSkrR2V0U3lzdGVtTWV0cmljcyhTTV9DWUVER0UpKS0KCQkJCQkJR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lNRU5VU0laRSk7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmh0b29sYmFyKSkgewoJCUdldENsaWVudFJlY3QoR2xvYmFscy5odG9vbGJhciwgJnJ0KTsKCQlwcmVjdC0+dG9wICs9IHJ0LmJvdHRvbSsyOwoJfQoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5oZHJpdmViYXIpKSB7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmhkcml2ZWJhciwgJnJ0KTsKCQlwcmVjdC0+dG9wICs9IHJ0LmJvdHRvbSsyOwoJfQoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5oc3RhdHVzYmFyKSkgewoJCUdldENsaWVudFJlY3QoR2xvYmFscy5oc3RhdHVzYmFyLCAmcnQpOwoJCXByZWN0LT5ib3R0b20gLT0gcnQuYm90dG9tOwoJfQp9CgpzdGF0aWMgQk9PTCB0b2dnbGVfZnVsbHNjcmVlbihIV05EIGh3bmQpCnsKCVJFQ1QgcnQ7CgoJaWYgKChnX2Z1bGxzY3JlZW4ubW9kZT0hZ19mdWxsc2NyZWVuLm1vZGUpKSB7CgkJR2V0V2luZG93UmVjdChod25kLCAmZ19mdWxsc2NyZWVuLm9yZ1Bvcyk7CgkJZ19mdWxsc2NyZWVuLndhc1pvb21lZCA9IElzWm9vbWVkKGh3bmQpOwoKCQlGcmFtZV9DYWxjRnJhbWVDbGllbnQoaHduZCwgJnJ0KTsKCQlDbGllbnRUb1NjcmVlbihod25kLCAoTFBQT0lOVCkmcnQubGVmdCk7CgkJQ2xpZW50VG9TY3JlZW4oaHduZCwgKExQUE9JTlQpJnJ0LnJpZ2h0KTsKCgkJcnQubGVmdCA9IGdfZnVsbHNjcmVlbi5vcmdQb3MubGVmdC1ydC5sZWZ0OwoJCXJ0LnRvcCA9IGdfZnVsbHNjcmVlbi5vcmdQb3MudG9wLXJ0LnRvcDsKCQlydC5yaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pK2dfZnVsbHNjcmVlbi5vcmdQb3MucmlnaHQtcnQucmlnaHQ7CgkJcnQuYm90dG9tID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTikrZ19mdWxsc2NyZWVuLm9yZ1Bvcy5ib3R0b20tcnQuYm90dG9tOwoKCQlNb3ZlV2luZG93KGh3bmQsIHJ0LmxlZnQsIHJ0LnRvcCwgcnQucmlnaHQtcnQubGVmdCwgcnQuYm90dG9tLXJ0LnRvcCwgVFJVRSk7Cgl9IGVsc2UgewoJCU1vdmVXaW5kb3coaHduZCwgZ19mdWxsc2NyZWVuLm9yZ1Bvcy5sZWZ0LCBnX2Z1bGxzY3JlZW4ub3JnUG9zLnRvcCwKCQkJCQkJCWdfZnVsbHNjcmVlbi5vcmdQb3MucmlnaHQtZ19mdWxsc2NyZWVuLm9yZ1Bvcy5sZWZ0LAoJCQkJCQkJZ19mdWxsc2NyZWVuLm9yZ1Bvcy5ib3R0b20tZ19mdWxsc2NyZWVuLm9yZ1Bvcy50b3AsIFRSVUUpOwoKCQlpZiAoZ19mdWxsc2NyZWVuLndhc1pvb21lZCkKCQkJU2hvd1dpbmRvdyhod25kLCBXU19NQVhJTUlaRSk7Cgl9CgoJcmV0dXJuIGdfZnVsbHNjcmVlbi5tb2RlOwp9CgpzdGF0aWMgdm9pZCBmdWxsc2NyZWVuX21vdmUoSFdORCBod25kKQp7CglSRUNUIHJ0LCBwb3M7CglHZXRXaW5kb3dSZWN0KGh3bmQsICZwb3MpOwoKCUZyYW1lX0NhbGNGcmFtZUNsaWVudChod25kLCAmcnQpOwoJQ2xpZW50VG9TY3JlZW4oaHduZCwgKExQUE9JTlQpJnJ0LmxlZnQpOwoJQ2xpZW50VG9TY3JlZW4oaHduZCwgKExQUE9JTlQpJnJ0LnJpZ2h0KTsKCglydC5sZWZ0ID0gcG9zLmxlZnQtcnQubGVmdDsKCXJ0LnRvcCA9IHBvcy50b3AtcnQudG9wOwoJcnQucmlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKStwb3MucmlnaHQtcnQucmlnaHQ7CglydC5ib3R0b20gPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKStwb3MuYm90dG9tLXJ0LmJvdHRvbTsKCglNb3ZlV2luZG93KGh3bmQsIHJ0LmxlZnQsIHJ0LnRvcCwgcnQucmlnaHQtcnQubGVmdCwgcnQuYm90dG9tLXJ0LnRvcCwgVFJVRSk7Cn0KCiNlbmRpZgoKCnN0YXRpYyB2b2lkIHRvZ2dsZV9jaGlsZChIV05EIGh3bmQsIFVJTlQgY21kLCBIV05EIGhjaGlsZCkKewoJQk9PTCB2aXMgPSBJc1dpbmRvd1Zpc2libGUoaGNoaWxkKTsKCglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBjbWQsIHZpcz9NRl9CWUNPTU1BTkQ6TUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoKCVNob3dXaW5kb3coaGNoaWxkLCB2aXM/U1dfSElERTpTV19TSE9XKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWlmIChnX2Z1bGxzY3JlZW4ubW9kZSkKCQlmdWxsc2NyZWVuX21vdmUoaHduZCk7CiNlbmRpZgoKCXJlc2l6ZV9mcmFtZV9jbGllbnQoaHduZCk7Cn0KCnN0YXRpYyBCT09MIGFjdGl2YXRlX2RyaXZlX3dpbmRvdyhMUENUU1RSIHBhdGgpCnsKCVRDSEFSIGRydjFbX01BWF9EUklWRV0sIGRydjJbX01BWF9EUklWRV07CglIV05EIGNoaWxkX3duZDsKCglfdHNwbGl0cGF0aChwYXRoLCBkcnYxLCAwLCAwLCAwKTsKCgkvKiBzZWFyY2ggZm9yIGEgYWxyZWFkeSBvcGVuIHdpbmRvdyBmb3IgdGhlIHNhbWUgZHJpdmUgKi8KCWZvcihjaGlsZF93bmQ9R2V0TmV4dFdpbmRvdyhHbG9iYWxzLmhtZGljbGllbnQsR1dfQ0hJTEQpOyBjaGlsZF93bmQ7IGNoaWxkX3duZD1HZXROZXh0V2luZG93KGNoaWxkX3duZCwgR1dfSFdORE5FWFQpKSB7CgkJQ2hpbGRXbmQqIGNoaWxkID0gKENoaWxkV25kKikgR2V0V2luZG93TG9uZ1B0cihjaGlsZF93bmQsIEdXTFBfVVNFUkRBVEEpOwoKCQlpZiAoY2hpbGQpIHsKCQkJX3RzcGxpdHBhdGgoY2hpbGQtPnJvb3QucGF0aCwgZHJ2MiwgMCwgMCwgMCk7CgoJCQlpZiAoIWxzdHJjbXBpKGRydjIsIGRydjEpKSB7CgkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESUFDVElWQVRFLCAoV1BBUkFNKWNoaWxkX3duZCwgMCk7CgoJCQkJaWYgKElzSWNvbmljKGNoaWxkX3duZCkpCgkJCQkJU2hvd1dpbmRvdyhjaGlsZF93bmQsIFNXX1NIT1dOT1JNQUwpOwoKCQkJCXJldHVybiBUUlVFOwoJCQl9CgkJfQoJfQoKCXJldHVybiBGQUxTRTsKfQoKc3RhdGljIEJPT0wgYWN0aXZhdGVfZnNfd2luZG93KExQQ1RTVFIgZmlsZXN5cykKewoJSFdORCBjaGlsZF93bmQ7CgoJLyogc2VhcmNoIGZvciBhIGFscmVhZHkgb3BlbiB3aW5kb3cgb2YgdGhlIGdpdmVuIGZpbGUgc3lzdGVtIG5hbWUgKi8KCWZvcihjaGlsZF93bmQ9R2V0TmV4dFdpbmRvdyhHbG9iYWxzLmhtZGljbGllbnQsR1dfQ0hJTEQpOyBjaGlsZF93bmQ7IGNoaWxkX3duZD1HZXROZXh0V2luZG93KGNoaWxkX3duZCwgR1dfSFdORE5FWFQpKSB7CgkJQ2hpbGRXbmQqIGNoaWxkID0gKENoaWxkV25kKikgR2V0V2luZG93TG9uZ1B0cihjaGlsZF93bmQsIEdXTFBfVVNFUkRBVEEpOwoKCQlpZiAoY2hpbGQpIHsKCQkJaWYgKCFsc3RyY21waShjaGlsZC0+cm9vdC5mcywgZmlsZXN5cykpIHsKCQkJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJQUNUSVZBVEUsIChXUEFSQU0pY2hpbGRfd25kLCAwKTsKCgkJCQlpZiAoSXNJY29uaWMoY2hpbGRfd25kKSkKCQkJCQlTaG93V2luZG93KGNoaWxkX3duZCwgU1dfU0hPV05PUk1BTCk7CgoJCQkJcmV0dXJuIFRSVUU7CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgTFJFU1VMVCBDQUxMQkFDSyBGcmFtZVduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCVRDSEFSIGIxW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCglzd2l0Y2gobm1zZykgewoJCWNhc2UgV01fQ0xPU0U6CgkJCWlmIChHbG9iYWxzLnNhdmVTZXR0aW5ncykKCQkJCXNhdmVfcmVnaXN0cnlfc2V0dGluZ3MoKTsgIAoJCQkKCQkJRGVzdHJveVdpbmRvdyhod25kKTsKCgkJCSAvKiBjbGVhciBoYW5kbGUgdmFyaWFibGVzICovCgkJCUdsb2JhbHMuaE1lbnVGcmFtZSA9IDA7CgkJCUdsb2JhbHMuaE1lbnVWaWV3ID0gMDsKCQkJR2xvYmFscy5oTWVudU9wdGlvbnMgPSAwOwoJCQlHbG9iYWxzLmhNYWluV25kID0gMDsKCQkJR2xvYmFscy5obWRpY2xpZW50ID0gMDsKCQkJR2xvYmFscy5oZHJpdmViYXIgPSAwOwoJCQlicmVhazsKCgkJY2FzZSBXTV9ERVNUUk9ZOgoJCQlQb3N0UXVpdE1lc3NhZ2UoMCk7CgkJCWJyZWFrOwoKCQljYXNlIFdNX0lOSVRNRU5VUE9QVVA6IHsKCQkJSFdORCBod25kQ2xpZW50ID0gKEhXTkQpIFNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJR0VUQUNUSVZFLCAwLCAwKTsKCgkJCWlmICghU2VuZE1lc3NhZ2UoaHduZENsaWVudCwgV01fSU5JVE1FTlVQT1BVUCwgd3BhcmFtLCBscGFyYW0pKQoJCQkJcmV0dXJuIDA7CgkJCWJyZWFrO30KCgkJY2FzZSBXTV9DT01NQU5EOiB7CgkJCVVJTlQgY21kID0gTE9XT1JEKHdwYXJhbSk7CgkJCUhXTkQgaHduZENsaWVudCA9IChIV05EKSBTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESUdFVEFDVElWRSwgMCwgMCk7CgoJCQlpZiAoU2VuZE1lc3NhZ2UoaHduZENsaWVudCwgV01fRElTUEFUQ0hfQ09NTUFORCwgd3BhcmFtLCBscGFyYW0pKQoJCQkJYnJlYWs7CgoJCQlpZiAoY21kPj1JRF9EUklWRV9GSVJTVCAmJiBjbWQ8PUlEX0RSSVZFX0ZJUlNUKzB4RkYpIHsKCQkJCVRDSEFSIGRydltfTUFYX0RSSVZFXSwgcGF0aFtNQVhfUEFUSF07CgkJCQlDaGlsZFduZCogY2hpbGQ7CgkJCQlMUENUU1RSIHJvb3QgPSBHbG9iYWxzLmRyaXZlczsKCQkJCWludCBpOwoKCQkJCWZvcihpPWNtZC1JRF9EUklWRV9GSVJTVDsgaS0tOyByb290KyspCgkJCQkJd2hpbGUoKnJvb3QpCgkJCQkJCXJvb3QrKzsKCgkJCQlpZiAoYWN0aXZhdGVfZHJpdmVfd2luZG93KHJvb3QpKQoJCQkJCXJldHVybiAwOwoKCQkJCV90c3BsaXRwYXRoKHJvb3QsIGRydiwgMCwgMCwgMCk7CgoJCQkJaWYgKCFTZXRDdXJyZW50RGlyZWN0b3J5KGRydikpIHsKCQkJCQlkaXNwbGF5X2Vycm9yKGh3bmQsIEdldExhc3RFcnJvcigpKTsKCQkJCQlyZXR1cm4gMDsKCQkJCX0KCgkJCQlHZXRDdXJyZW50RGlyZWN0b3J5KE1BWF9QQVRILCBwYXRoKTsgLypUT0RPOiBzdG9yZSBsYXN0IGRpcmVjdG9yeSBwZXIgZHJpdmUgKi8KCQkJCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIE5VTEwsIGh3bmQpOwoKCQkJCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhjaGlsZCkpCgkJCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2hpbGQpOwoJCQl9IGVsc2Ugc3dpdGNoKGNtZCkgewoJCQkJY2FzZSBJRF9GSUxFX0VYSVQ6CgkJCQkJU2VuZE1lc3NhZ2UoaHduZCwgV01fQ0xPU0UsIDAsIDApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfV0lORE9XX05FVzogewoJCQkJCVRDSEFSIHBhdGhbTUFYX1BBVEhdOwoJCQkJCUNoaWxkV25kKiBjaGlsZDsKCgkJCQkJR2V0Q3VycmVudERpcmVjdG9yeShNQVhfUEFUSCwgcGF0aCk7CgkJCQkJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgTlVMTCwgaHduZCk7CgoJCQkJCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhjaGlsZCkpCgkJCQkJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGNoaWxkKTsKCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9SRUZSRVNIOgoJCQkJCXJlZnJlc2hfZHJpdmVzKCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9XSU5ET1dfQ0FTQ0FERToKCQkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESUNBU0NBREUsIDAsIDApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfV0lORE9XX1RJTEVfSE9SWjoKCQkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESVRJTEUsIE1ESVRJTEVfSE9SSVpPTlRBTCwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9XSU5ET1dfVElMRV9WRVJUOgoJCQkJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJVElMRSwgTURJVElMRV9WRVJUSUNBTCwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9XSU5ET1dfQVJSQU5HRToKCQkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESUlDT05BUlJBTkdFLCAwLCAwKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1NFTEVDVF9GT05UOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hvb3NlX2ZvbnQoaHduZCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCgkJCQljYXNlIElEX1ZJRVdfVE9PTF9CQVI6CgkJCQkJdG9nZ2xlX2NoaWxkKGh3bmQsIGNtZCwgR2xvYmFscy5odG9vbGJhcik7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9WSUVXX0RSSVZFX0JBUjoKCQkJCQl0b2dnbGVfY2hpbGQoaHduZCwgY21kLCBHbG9iYWxzLmhkcml2ZWJhcik7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9WSUVXX1NUQVRVU0JBUjoKCQkJCQl0b2dnbGVfY2hpbGQoaHduZCwgY21kLCBHbG9iYWxzLmhzdGF0dXNiYXIpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19TQVZFU0VUVElOR1M6CgkJCQkJR2xvYmFscy5zYXZlU2V0dGluZ3MgPSAhR2xvYmFscy5zYXZlU2V0dGluZ3M7CgkJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgSURfVklFV19TQVZFU0VUVElOR1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdsb2JhbHMuc2F2ZVNldHRpbmdzID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfRVhFQ1VURTogewoJCQkJCXN0cnVjdCBFeGVjdXRlRGlhbG9nIGRsZzsKCgkJCQkJbWVtc2V0KCZkbGcsIDAsIHNpemVvZihzdHJ1Y3QgRXhlY3V0ZURpYWxvZykpOwoKCQkJCQlpZiAoRGlhbG9nQm94UGFyYW0oR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRERfRVhFQ1VURSksIGh3bmQsIEV4ZWN1dGVEaWFsb2dEbGdQcm9jLCAoTFBBUkFNKSZkbGcpID09IElET0spIHsKCQkJCQkJSElOU1RBTkNFIGhpbnN0ID0gU2hlbGxFeGVjdXRlKGh3bmQsIE5VTEwvKm9wZXJhdGlvbiovLCBkbGcuY21kLypmaWxlKi8sIE5VTEwvKnBhcmFtZXRlcnMqLywgTlVMTC8qZGlyKi8sIGRsZy5jbWRzaG93KTsKCgkJCQkJCWlmIChQdHJUb1Vsb25nKGhpbnN0KSA8PSAzMikKCQkJCQkJCWRpc3BsYXlfZXJyb3IoaHduZCwgR2V0TGFzdEVycm9yKCkpOwoJCQkJCX0KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9DT05ORUNUX05FVFdPUktfRFJJVkU6IHsKCQkJCQlEV09SRCByZXQgPSBXTmV0Q29ubmVjdGlvbkRpYWxvZyhod25kLCBSRVNPVVJDRVRZUEVfRElTSyk7CgkJCQkJaWYgKHJldCA9PSBOT19FUlJPUikKCQkJCQkJcmVmcmVzaF9kcml2ZXMoKTsKCQkJCQllbHNlIGlmIChyZXQgIT0gKERXT1JEKS0xKSB7CgkJCQkJCWlmIChyZXQgPT0gRVJST1JfRVhURU5ERURfRVJST1IpCgkJCQkJCQlkaXNwbGF5X25ldHdvcmtfZXJyb3IoaHduZCk7CgkJCQkJCWVsc2UKCQkJCQkJCWRpc3BsYXlfZXJyb3IoaHduZCwgcmV0KTsKCQkJCQl9CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfRElTQ09OTkVDVF9ORVRXT1JLX0RSSVZFOiB7CgkJCQkJRFdPUkQgcmV0ID0gV05ldERpc2Nvbm5lY3REaWFsb2coaHduZCwgUkVTT1VSQ0VUWVBFX0RJU0spOwoJCQkJCWlmIChyZXQgPT0gTk9fRVJST1IpCgkJCQkJCXJlZnJlc2hfZHJpdmVzKCk7CgkJCQkJZWxzZSBpZiAocmV0ICE9IChEV09SRCktMSkgewoJCQkJCQlpZiAocmV0ID09IEVSUk9SX0VYVEVOREVEX0VSUk9SKQoJCQkJCQkJZGlzcGxheV9uZXR3b3JrX2Vycm9yKGh3bmQpOwoJCQkJCQllbHNlCgkJCQkJCQlkaXNwbGF5X2Vycm9yKGh3bmQsIHJldCk7CgkJCQkJfQoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX0ZPUk1BVF9ESVNLOiB7CgkJCQkJVUlOVCBzZW1fb3JnID0gU2V0RXJyb3JNb2RlKDApOyAvKiBHZXQgdGhlIGN1cnJlbnQgRXJyb3IgTW9kZSBzZXR0aW5ncy4gKi8KCQkJCQlTZXRFcnJvck1vZGUoc2VtX29yZyAmIH5TRU1fRkFJTENSSVRJQ0FMRVJST1JTKTsgLyogRm9yY2UgTy9TIHRvIGhhbmRsZSAqLwoJCQkJCVNIRm9ybWF0RHJpdmUoaHduZCwgMCAvKiBBOiAqLywgU0hGTVRfSURfREVGQVVMVCwgMCk7CgkJCQkJU2V0RXJyb3JNb2RlKHNlbV9vcmcpOyAvKiBQdXQgaXQgYmFjayB0aGUgd2F5IGl0IHdhcy4gKi8KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9IRUxQOgoJCQkJCVdpbkhlbHAoaHduZCwgUlMoYjEsSURTX1dJTkVGSUxFKSwgSEVMUF9JTkRFWCwgMCk7CgkJCQkJYnJlYWs7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCQljYXNlIElEX1ZJRVdfRlVMTFNDUkVFTjoKCQkJCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBjbWQsIHRvZ2dsZV9mdWxsc2NyZWVuKGh3bmQpP01GX0NIRUNLRUQ6MCk7CgkJCQkJYnJlYWs7CgojaWZkZWYgX19XSU5FX18KCQkJCWNhc2UgSURfRFJJVkVfVU5JWF9GUzogewoJCQkJCVRDSEFSIHBhdGhbTUFYX1BBVEhdOwojaWZkZWYgVU5JQ09ERQoJCQkJCWNoYXIgY3BhdGhbTUFYX1BBVEhdOwojZW5kaWYKCQkJCQlDaGlsZFduZCogY2hpbGQ7CgoJCQkJCWlmIChhY3RpdmF0ZV9mc193aW5kb3coUlMoYjEsSURTX1VOSVhGUykpKQoJCQkJCQlicmVhazsKCiNpZmRlZiBVTklDT0RFCgkJCQkJZ2V0Y3dkKGNwYXRoLCBNQVhfUEFUSCk7CgkJCQkJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9VTklYQ1AsIDAsIGNwYXRoLCAtMSwgcGF0aCwgTUFYX1BBVEgpOwojZWxzZQoJCQkJCWdldGN3ZChwYXRoLCBNQVhfUEFUSCk7CiNlbmRpZgoJCQkJCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIE5VTEwsIGh3bmQpOwoKCQkJCQlpZiAoIWNyZWF0ZV9jaGlsZF93aW5kb3coY2hpbGQpKQoJCQkJCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBjaGlsZCk7CgkJCQkJYnJlYWs7fQojZW5kaWYKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgkJCQljYXNlIElEX0RSSVZFX1NIRUxMX05TOiB7CgkJCQkJVENIQVIgcGF0aFtNQVhfUEFUSF07CgkJCQkJQ2hpbGRXbmQqIGNoaWxkOwoKCQkJCQlpZiAoYWN0aXZhdGVfZnNfd2luZG93KFJTKGIxLElEU19TSEVMTCkpKQoJCQkJCQlicmVhazsKCgkJCQkJR2V0Q3VycmVudERpcmVjdG9yeShNQVhfUEFUSCwgcGF0aCk7CgkJCQkJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgZ2V0X3BhdGhfcGlkbChwYXRoLGh3bmQpLCBod25kKTsKCgkJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQkJCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2hpbGQpOwoJCQkJCWJyZWFrO30KI2VuZGlmCiNlbmRpZgoKCQkJCS8qVE9ETzogVGhlcmUgYXJlIGV2ZW4gbW9yZSBtZW51IGl0ZW1zISAqLwoKCQkJCWNhc2UgSURfQUJPVVQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaGVsbEFib3V0KGh3bmQsIFJTKGIxLElEU19XSU5FRklMRSksIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvYWRJbWFnZSggR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRElfV0lORUZJTEUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElNQUdFX0lDT04sIDQ4LCA0OCwgTFJfU0hBUkVEICkpOwoJCQkJCWJyZWFrOwoKCQkJCWRlZmF1bHQ6CgkJCQkJLypUT0RPOiBpZiAod1BhcmFtID49IFBNX0ZJUlNUX0xBTkdVQUdFICYmIHdQYXJhbSA8PSBQTV9MQVNUX0xBTkdVQUdFKQoJCQkJCQlTVFJJTkdfU2VsZWN0TGFuZ3VhZ2VCeU51bWJlcih3UGFyYW0gLSBQTV9GSVJTVF9MQU5HVUFHRSk7CgkJCQkJZWxzZSAqL2lmICgoY21kPElEV19GSVJTVF9DSElMRCB8fCBjbWQ+PUlEV19GSVJTVF9DSElMRCsweDEwMCkgJiYKCQkJCQkJKGNtZDxTQ19TSVpFIHx8IGNtZD5TQ19SRVNUT1JFKSkKCQkJCQkJTWVzc2FnZUJveChod25kLCBSUyhiMixJRFNfTk9fSU1QTCksIFJTKGIxLElEU19XSU5FRklMRSksIE1CX09LKTsKCgkJCQkJcmV0dXJuIERlZkZyYW1lUHJvYyhod25kLCBHbG9iYWxzLmhtZGljbGllbnQsIG5tc2csIHdwYXJhbSwgbHBhcmFtKTsKCQkJfQoJCQlicmVhazt9CgoJCWNhc2UgV01fU0laRToKCQkJcmVzaXplX2ZyYW1lKGh3bmQsIExPV09SRChscGFyYW0pLCBISVdPUkQobHBhcmFtKSk7CgkJCWJyZWFrOwkvKiBkbyBub3QgcGFzcyBtZXNzYWdlIHRvIERlZkZyYW1lUHJvYyAqLwoKCQljYXNlIFdNX0RFVklDRUNIQU5HRToKCQkJU2VuZE1lc3NhZ2UoaHduZCwgV01fQ09NTUFORCwgTUFLRUxPTkcoSURfUkVGUkVTSCwwKSwgMCk7CgkJCWJyZWFrOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fR0VUTUlOTUFYSU5GTzogewoJCQlMUE1JTk1BWElORk8gbHBtbWkgPSAoTFBNSU5NQVhJTkZPKWxwYXJhbTsKCgkJCWxwbW1pLT5wdE1heFRyYWNrU2l6ZS54IDw8PSAxOy8qMipHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKSAvIFNNX0NYVklSVFVBTFNDUkVFTiAqLwoJCQlscG1taS0+cHRNYXhUcmFja1NpemUueSA8PD0gMTsvKjIqR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTikgLyBTTV9DWVZJUlRVQUxTQ1JFRU4gKi8KCQkJYnJlYWs7fQoKCQljYXNlIEZSTV9DQUxDX0NMSUVOVDoKCQkJZnJhbWVfZ2V0X2NsaWVudHNwYWNlKGh3bmQsIChQUkVDVClscGFyYW0pOwoJCQlyZXR1cm4gVFJVRTsKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJCWRlZmF1bHQ6CgkJCXJldHVybiBEZWZGcmFtZVByb2MoaHduZCwgR2xvYmFscy5obWRpY2xpZW50LCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7Cgl9CgoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgVENIQVIgZ19wb3NfbmFtZXNbQ09MVU1OU11bMjBdID0gewoJeydcMCd9CS8qIHN5bWJvbCAqLwp9OwoKc3RhdGljIGNvbnN0IGludCBnX3Bvc19hbGlnbltdID0gewoJMCwKCUhERl9MRUZULAkvKiBOYW1lICovCglIREZfUklHSFQsCS8qIFNpemUgKi8KCUhERl9MRUZULAkvKiBDRGF0ZSAqLwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglIREZfTEVGVCwJLyogQURhdGUgKi8KCUhERl9MRUZULAkvKiBNRGF0ZSAqLwoJSERGX0xFRlQsCS8qIEluZGV4ICovCglIREZfQ0VOVEVSLAkvKiBMaW5rcyAqLwojZW5kaWYKCUhERl9DRU5URVIsCS8qIEF0dHJpYnV0ZXMgKi8KI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJSERGX0xFRlQJLyogU2VjdXJpdHkgKi8KI2VuZGlmCn07CgpzdGF0aWMgdm9pZCByZXNpemVfdHJlZShDaGlsZFduZCogY2hpbGQsIGludCBjeCwgaW50IGN5KQp7CglIRFdQIGhkd3AgPSBCZWdpbkRlZmVyV2luZG93UG9zKDQpOwoJUkVDVCBydDsKCglydC5sZWZ0ICAgPSAwOwoJcnQudG9wICAgID0gMDsKCXJ0LnJpZ2h0ICA9IGN4OwoJcnQuYm90dG9tID0gY3k7CgoJY3ggPSBjaGlsZC0+c3BsaXRfcG9zICsgU1BMSVRfV0lEVEgvMjsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCXsKCQlXSU5ET1dQT1Mgd3A7CgkJSERfTEFZT1VUIGhkbDsKCgkJaGRsLnByYyAgID0gJnJ0OwoJCWhkbC5wd3BvcyA9ICZ3cDsKCgkJU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZEhlYWRlciwgSERNX0xBWU9VVCwgMCwgKExQQVJBTSkmaGRsKTsKCgkJRGVmZXJXaW5kb3dQb3MoaGR3cCwgY2hpbGQtPmxlZnQuaHduZEhlYWRlciwgd3AuaHduZEluc2VydEFmdGVyLAoJCQkJCQl3cC54LTEsIHdwLnksIGNoaWxkLT5zcGxpdF9wb3MtU1BMSVRfV0lEVEgvMisxLCB3cC5jeSwgd3AuZmxhZ3MpOwoJCURlZmVyV2luZG93UG9zKGhkd3AsIGNoaWxkLT5yaWdodC5od25kSGVhZGVyLCB3cC5od25kSW5zZXJ0QWZ0ZXIsCgkJCQkJCXJ0LmxlZnQrY3grMSwgd3AueSwgd3AuY3gtY3grMiwgd3AuY3ksIHdwLmZsYWdzKTsKCX0KI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJRGVmZXJXaW5kb3dQb3MoaGR3cCwgY2hpbGQtPmxlZnQuaHduZCwgMCwgcnQubGVmdCwgcnQudG9wLCBjaGlsZC0+c3BsaXRfcG9zLVNQTElUX1dJRFRILzItcnQubGVmdCwgcnQuYm90dG9tLXJ0LnRvcCwgU1dQX05PWk9SREVSfFNXUF9OT0FDVElWQVRFKTsKCURlZmVyV2luZG93UG9zKGhkd3AsIGNoaWxkLT5yaWdodC5od25kLCAwLCBydC5sZWZ0K2N4KzEsIHJ0LnRvcCwgcnQucmlnaHQtY3gsIHJ0LmJvdHRvbS1ydC50b3AsIFNXUF9OT1pPUkRFUnxTV1BfTk9BQ1RJVkFURSk7CgoJRW5kRGVmZXJXaW5kb3dQb3MoaGR3cCk7Cn0KCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgpzdGF0aWMgSFdORCBjcmVhdGVfaGVhZGVyKEhXTkQgcGFyZW50LCBQYW5lKiBwYW5lLCBVSU5UIGlkKQp7CglIRF9JVEVNIGhkaTsKCWludCBpZHg7CgoJSFdORCBod25kID0gQ3JlYXRlV2luZG93KFdDX0hFQURFUiwgMCwgV1NfQ0hJTER8V1NfVklTSUJMRXxIRFNfSE9SWnxIRFNfRlVMTERSQUcvKlRPRE86IHxIRFNfQlVUVE9OUyArIHNvcnQgb3JkZXJzKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIHBhcmVudCwgKEhNRU5VKVVMb25nVG9IYW5kbGUoaWQpLCBHbG9iYWxzLmhJbnN0YW5jZSwgMCk7CglpZiAoIWh3bmQpCgkJcmV0dXJuIDA7CgoJU2VuZE1lc3NhZ2UoaHduZCwgV01fU0VURk9OVCwgKFdQQVJBTSlHZXRTdG9ja09iamVjdChERUZBVUxUX0dVSV9GT05UKSwgRkFMU0UpOwoKCWhkaS5tYXNrID0gSERJX1RFWFR8SERJX1dJRFRIfEhESV9GT1JNQVQ7CgoJZm9yKGlkeD0wOyBpZHg8Q09MVU1OUzsgaWR4KyspIHsKCQloZGkucHN6VGV4dCA9IGdfcG9zX25hbWVzW2lkeF07CgkJaGRpLmZtdCA9IEhERl9TVFJJTkcgfCBnX3Bvc19hbGlnbltpZHhdOwoJCWhkaS5jeHkgPSBwYW5lLT53aWR0aHNbaWR4XTsKCQlTZW5kTWVzc2FnZShod25kLCBIRE1fSU5TRVJUSVRFTSwgaWR4LCAoTFBBUkFNKSAmaGRpKTsKCX0KCglyZXR1cm4gaHduZDsKfQoKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoKc3RhdGljIHZvaWQgaW5pdF9vdXRwdXQoSFdORCBod25kKQp7CglzdGF0aWMgY29uc3QgV0NIQVIgczEwMDBbXSA9IHsnMScsJzAnLCcwJywnMCcsJ1wwJ307CglXQ0hBUiBiWzE2XTsKCUhGT05UIG9sZF9mb250OwoJSERDIGhkYyA9IEdldERDKGh3bmQpOwoKCWlmIChHZXROdW1iZXJGb3JtYXRXKExPQ0FMRV9VU0VSX0RFRkFVTFQsIDAsIHMxMDAwLCAwLCBiLCAxNikgPiA0KQoJCUdsb2JhbHMubnVtX3NlcCA9IGJbMV07CgllbHNlCgkJR2xvYmFscy5udW1fc2VwID0gJy4nOwoKCW9sZF9mb250ID0gU2VsZWN0T2JqZWN0KGhkYywgR2xvYmFscy5oZm9udCk7CglHZXRUZXh0RXh0ZW50UG9pbnQzMlcoaGRjLCBzU3BhY2UsIDEsICZHbG9iYWxzLnNwYWNlU2l6ZSk7CglTZWxlY3RPYmplY3QoaGRjLCBvbGRfZm9udCk7CglSZWxlYXNlREMoaHduZCwgaGRjKTsKfQoKc3RhdGljIHZvaWQgZHJhd19pdGVtKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBFbnRyeSogZW50cnksIGludCBjYWxjV2lkdGhDb2wpOwoKCi8qIGNhbGN1bGF0ZSBwcmVmZXJyZWQgd2lkdGggZm9yIGFsbCB2aXNpYmxlIGNvbHVtbnMgKi8KCnN0YXRpYyBCT09MIGNhbGNfd2lkdGhzKFBhbmUqIHBhbmUsIEJPT0wgYW55d2F5KQp7CglpbnQgY29sLCB4LCBjeCwgc3BjPTMqR2xvYmFscy5zcGFjZVNpemUuY3g7CglpbnQgZW50cmllcyA9IFNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX0dFVENPVU5ULCAwLCAwKTsKCWludCBvcmdXaWR0aHNbQ09MVU1OU107CglpbnQgb3JnUG9zaXRpb25zW0NPTFVNTlMrMV07CglIRk9OVCBoZm9udE9sZDsKCUhEQyBoZGM7CglpbnQgY250OwoKCWlmICghYW55d2F5KSB7CgkJbWVtY3B5KG9yZ1dpZHRocywgcGFuZS0+d2lkdGhzLCBzaXplb2Yob3JnV2lkdGhzKSk7CgkJbWVtY3B5KG9yZ1Bvc2l0aW9ucywgcGFuZS0+cG9zaXRpb25zLCBzaXplb2Yob3JnUG9zaXRpb25zKSk7Cgl9CgoJZm9yKGNvbD0wOyBjb2w8Q09MVU1OUzsgY29sKyspCgkJcGFuZS0+d2lkdGhzW2NvbF0gPSAwOwoKCWhkYyA9IEdldERDKHBhbmUtPmh3bmQpOwoJaGZvbnRPbGQgPSBTZWxlY3RPYmplY3QoaGRjLCBHbG9iYWxzLmhmb250KTsKCglmb3IoY250PTA7IGNudDxlbnRyaWVzOyBjbnQrKykgewoJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIFNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX0dFVElURU1EQVRBLCBjbnQsIDApOwoKCQlEUkFXSVRFTVNUUlVDVCBkaXM7CgoJCWRpcy5DdGxUeXBlCQkgID0gMDsKCQlkaXMuQ3RsSUQJCSAgPSAwOwoJCWRpcy5pdGVtSUQJCSAgPSAwOwoJCWRpcy5pdGVtQWN0aW9uCSAgPSAwOwoJCWRpcy5pdGVtU3RhdGUJICA9IDA7CgkJZGlzLmh3bmRJdGVtCSAgPSBwYW5lLT5od25kOwoJCWRpcy5oREMJCQkgID0gaGRjOwoJCWRpcy5yY0l0ZW0ubGVmdAkgID0gMDsKCQlkaXMucmNJdGVtLnRvcCAgICA9IDA7CgkJZGlzLnJjSXRlbS5yaWdodCAgPSAwOwoJCWRpcy5yY0l0ZW0uYm90dG9tID0gMDsKCQkvKmRpcy5pdGVtRGF0YQkgID0gMDsgKi8KCgkJZHJhd19pdGVtKHBhbmUsICZkaXMsIGVudHJ5LCBDT0xVTU5TKTsKCX0KCglTZWxlY3RPYmplY3QoaGRjLCBoZm9udE9sZCk7CglSZWxlYXNlREMocGFuZS0+aHduZCwgaGRjKTsKCgl4ID0gMDsKCWZvcihjb2w9MDsgY29sPENPTFVNTlM7IGNvbCsrKSB7CgkJcGFuZS0+cG9zaXRpb25zW2NvbF0gPSB4OwoJCWN4ID0gcGFuZS0+d2lkdGhzW2NvbF07CgoJCWlmIChjeCkgewoJCQljeCArPSBzcGM7CgoJCQlpZiAoY3ggPCBJTUFHRV9XSURUSCkKCQkJCWN4ID0gSU1BR0VfV0lEVEg7CgoJCQlwYW5lLT53aWR0aHNbY29sXSA9IGN4OwoJCX0KCgkJeCArPSBjeDsKCX0KCglwYW5lLT5wb3NpdGlvbnNbQ09MVU1OU10gPSB4OwoKCVNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX1NFVEhPUklaT05UQUxFWFRFTlQsIHgsIDApOwoKCS8qIG5vIGNoYW5nZT8gKi8KCWlmICghbWVtY21wKG9yZ1dpZHRocywgcGFuZS0+d2lkdGhzLCBzaXplb2Yob3JnV2lkdGhzKSkpCgkJcmV0dXJuIEZBTFNFOwoKCS8qIGRvbid0IG1vdmUsIGlmIG9ubHkgY29sbGFwc2luZyBhbiBlbnRyeSAqLwoJaWYgKCFhbnl3YXkgJiYgcGFuZS0+d2lkdGhzWzBdPG9yZ1dpZHRoc1swXSAmJgoJCSFtZW1jbXAob3JnV2lkdGhzKzEsIHBhbmUtPndpZHRocysxLCBzaXplb2Yob3JnV2lkdGhzKS1zaXplb2YoaW50KSkpIHsKCQlwYW5lLT53aWR0aHNbMF0gPSBvcmdXaWR0aHNbMF07CgkJbWVtY3B5KHBhbmUtPnBvc2l0aW9ucywgb3JnUG9zaXRpb25zLCBzaXplb2Yob3JnUG9zaXRpb25zKSk7CgoJCXJldHVybiBGQUxTRTsKCX0KCglJbnZhbGlkYXRlUmVjdChwYW5lLT5od25kLCAwLCBUUlVFKTsKCglyZXR1cm4gVFJVRTsKfQoKCi8qIGNhbGN1bGF0ZSBvbmUgcHJlZmVycmVkIGNvbHVtbiB3aWR0aCAqLwoKc3RhdGljIHZvaWQgY2FsY19zaW5nbGVfd2lkdGgoUGFuZSogcGFuZSwgaW50IGNvbCkKewoJSEZPTlQgaGZvbnRPbGQ7CglpbnQgeCwgY3g7CglpbnQgZW50cmllcyA9IFNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX0dFVENPVU5ULCAwLCAwKTsKCWludCBjbnQ7CglIREMgaGRjOwoKCXBhbmUtPndpZHRoc1tjb2xdID0gMDsKCgloZGMgPSBHZXREQyhwYW5lLT5od25kKTsKCWhmb250T2xkID0gU2VsZWN0T2JqZWN0KGhkYywgR2xvYmFscy5oZm9udCk7CgoJZm9yKGNudD0wOyBjbnQ8ZW50cmllczsgY250KyspIHsKCQlFbnRyeSogZW50cnkgPSAoRW50cnkqKSBTZW5kTWVzc2FnZShwYW5lLT5od25kLCBMQl9HRVRJVEVNREFUQSwgY250LCAwKTsKCQlEUkFXSVRFTVNUUlVDVCBkaXM7CgoJCWRpcy5DdGxUeXBlCQkgID0gMDsKCQlkaXMuQ3RsSUQJCSAgPSAwOwoJCWRpcy5pdGVtSUQJCSAgPSAwOwoJCWRpcy5pdGVtQWN0aW9uCSAgPSAwOwoJCWRpcy5pdGVtU3RhdGUJICA9IDA7CgkJZGlzLmh3bmRJdGVtCSAgPSBwYW5lLT5od25kOwoJCWRpcy5oREMJCQkgID0gaGRjOwoJCWRpcy5yY0l0ZW0ubGVmdAkgID0gMDsKCQlkaXMucmNJdGVtLnRvcCAgICA9IDA7CgkJZGlzLnJjSXRlbS5yaWdodCAgPSAwOwoJCWRpcy5yY0l0ZW0uYm90dG9tID0gMDsKCQkvKmRpcy5pdGVtRGF0YQkgID0gMDsgKi8KCgkJZHJhd19pdGVtKHBhbmUsICZkaXMsIGVudHJ5LCBjb2wpOwoJfQoKCVNlbGVjdE9iamVjdChoZGMsIGhmb250T2xkKTsKCVJlbGVhc2VEQyhwYW5lLT5od25kLCBoZGMpOwoKCWN4ID0gcGFuZS0+d2lkdGhzW2NvbF07CgoJaWYgKGN4KSB7CgkJY3ggKz0gMypHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCgkJaWYgKGN4IDwgSU1BR0VfV0lEVEgpCgkJCWN4ID0gSU1BR0VfV0lEVEg7Cgl9CgoJcGFuZS0+d2lkdGhzW2NvbF0gPSBjeDsKCgl4ID0gcGFuZS0+cG9zaXRpb25zW2NvbF0gKyBjeDsKCglmb3IoOyBjb2w8Q09MVU1OUzsgKSB7CgkJcGFuZS0+cG9zaXRpb25zWysrY29sXSA9IHg7CgkJeCArPSBwYW5lLT53aWR0aHNbY29sXTsKCX0KCglTZW5kTWVzc2FnZShwYW5lLT5od25kLCBMQl9TRVRIT1JJWk9OVEFMRVhURU5ULCB4LCAwKTsKfQoKCnN0YXRpYyBCT09MIHBhdHRlcm5fbWF0Y2goTFBDVFNUUiBzdHIsIExQQ1RTVFIgcGF0dGVybikKewoJZm9yKCA7ICpzdHImJipwYXR0ZXJuOyBzdHIrKyxwYXR0ZXJuKyspIHsKCQlpZiAoKnBhdHRlcm4gPT0gJyonKSB7CgkJCWRvIHBhdHRlcm4rKzsKCQkJd2hpbGUoKnBhdHRlcm4gPT0gJyonKTsKCgkJCWlmICghKnBhdHRlcm4pCgkJCQlyZXR1cm4gVFJVRTsKCgkJCWZvcig7ICpzdHI7IHN0cisrKQoJCQkJaWYgKCpzdHI9PSpwYXR0ZXJuICYmIHBhdHRlcm5fbWF0Y2goc3RyLCBwYXR0ZXJuKSkKCQkJCQlyZXR1cm4gVFJVRTsKCgkJCXJldHVybiBGQUxTRTsKCQl9CgkJZWxzZSBpZiAoKnN0ciE9KnBhdHRlcm4gJiYgKnBhdHRlcm4hPSc/JykKCQkJcmV0dXJuIEZBTFNFOwoJfQoKCWlmICgqc3RyIHx8ICpwYXR0ZXJuKQoJCWlmICgqcGF0dGVybiE9JyonIHx8IHBhdHRlcm5bMV0hPSdcMCcpCgkJCXJldHVybiBGQUxTRTsKCglyZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgcGF0dGVybl9pbWF0Y2goTFBDVFNUUiBzdHIsIExQQ1RTVFIgcGF0dGVybikKewoJVENIQVIgYjFbQlVGRkVSX0xFTl0sIGIyW0JVRkZFUl9MRU5dOwoKCWxzdHJjcHkoYjEsIHN0cik7Cglsc3RyY3B5KGIyLCBwYXR0ZXJuKTsKCUNoYXJVcHBlcihiMSk7CglDaGFyVXBwZXIoYjIpOwoKCXJldHVybiBwYXR0ZXJuX21hdGNoKGIxLCBiMik7Cn0KCgplbnVtIEZJTEVfVFlQRSB7CglGVF9PVEhFUgkJPSAwLAoJRlRfRVhFQ1VUQUJMRQk9IDEsCglGVF9ET0NVTUVOVAkJPSAyCn07CgpzdGF0aWMgZW51bSBGSUxFX1RZUEUgZ2V0X2ZpbGVfdHlwZShMUENUU1RSIGZpbGVuYW1lKTsKCgovKiBpbnNlcnQgbGlzdGJveCBlbnRyaWVzIGFmdGVyIGluZGV4IGlkeCAqLwoKc3RhdGljIGludCBpbnNlcnRfZW50cmllcyhQYW5lKiBwYW5lLCBFbnRyeSogZGlyLCBMUENUU1RSIHBhdHRlcm4sIGludCBmaWx0ZXJfZmxhZ3MsIGludCBpZHgpCnsKCUVudHJ5KiBlbnRyeSA9IGRpcjsKCglpZiAoIWVudHJ5KQoJCXJldHVybiBpZHg7CgoJU2hvd1dpbmRvdyhwYW5lLT5od25kLCBTV19ISURFKTsKCglmb3IoOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpIHsKI2lmbmRlZiBfTEVGVF9GSUxFUwoJCWlmIChwYW5lLT50cmVlUGFuZSAmJiAhKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSkKCQkJY29udGludWU7CiNlbmRpZgoKCQlpZiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkvKiBkb24ndCBkaXNwbGF5IGVudHJpZXMgIi4iIGFuZCAiLi4iIGluIHRoZSBsZWZ0IHBhbmUgKi8KCQkJaWYgKHBhbmUtPnRyZWVQYW5lICYmIGVudHJ5LT5kYXRhLmNGaWxlTmFtZVswXSA9PSAnLicpCgkJCQlpZiAoCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJCQllbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMV0gPT0gJ1wwJyB8fAojZW5kaWYKCQkJCQkoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdID09ICcuJyAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMl0gPT0gJ1wwJykpCgkJCQkJY29udGludWU7CgoJCQkvKiBmaWx0ZXIgZGlyZWN0b3JpZXMgaW4gcmlnaHQgcGFuZSAqLwoJCQlpZiAoIXBhbmUtPnRyZWVQYW5lICYmICEoZmlsdGVyX2ZsYWdzJlRGX0RJUkVDVE9SSUVTKSkKCQkJCWNvbnRpbnVlOwoJCX0KCgkJLyogZmlsdGVyIHVzaW5nIHRoZSBmaWxlIG5hbWUgcGF0dGVybiAqLwoJCWlmIChwYXR0ZXJuKQoJCQlpZiAoIXBhdHRlcm5faW1hdGNoKGVudHJ5LT5kYXRhLmNGaWxlTmFtZSwgcGF0dGVybikpCgkJCQljb250aW51ZTsKCgkJLyogZmlsdGVyIHN5c3RlbSBhbmQgaGlkZGVuIGZpbGVzICovCgkJaWYgKCEoZmlsdGVyX2ZsYWdzJlRGX0hJRERFTikgJiYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMmKEZJTEVfQVRUUklCVVRFX0hJRERFTnxGSUxFX0FUVFJJQlVURV9TWVNURU0pKSkKCQkJY29udGludWU7CgoJCS8qIGZpbHRlciBsb29raW5nIGF0IHRoZSBmaWxlIHR5cGUgKi8KCQlpZiAoKGZpbHRlcl9mbGFncyYoVEZfUFJPR1JBTVN8VEZfRE9DVU1FTlRTfFRGX09USEVSUykpICE9IChURl9QUk9HUkFNU3xURl9ET0NVTUVOVFN8VEZfT1RIRVJTKSkKCQkJc3dpdGNoKGdldF9maWxlX3R5cGUoZW50cnktPmRhdGEuY0ZpbGVOYW1lKSkgewoJCQkgIGNhc2UgRlRfRVhFQ1VUQUJMRToKCQkJICAJaWYgKCEoZmlsdGVyX2ZsYWdzICYgVEZfUFJPR1JBTVMpKQoJCQkJCWNvbnRpbnVlOwoJCQkJYnJlYWs7CgoJCQkgIGNhc2UgRlRfRE9DVU1FTlQ6CgkJCQlpZiAoIShmaWx0ZXJfZmxhZ3MgJiBURl9ET0NVTUVOVFMpKQoJCQkJCWNvbnRpbnVlOwoJCQkJYnJlYWs7CgoJCQkgIGRlZmF1bHQ6IC8qIFRGX09USEVSUyAqLwoJCQkJaWYgKCEoZmlsdGVyX2ZsYWdzICYgVEZfT1RIRVJTKSkKCQkJCQljb250aW51ZTsKCQkJfQoKCQlpZiAoaWR4ICE9IC0xKQoJCQlpZHgrKzsKCgkJU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfSU5TRVJUU1RSSU5HLCBpZHgsIChMUEFSQU0pIGVudHJ5KTsKCgkJaWYgKHBhbmUtPnRyZWVQYW5lICYmIGVudHJ5LT5leHBhbmRlZCkKCQkJaWR4ID0gaW5zZXJ0X2VudHJpZXMocGFuZSwgZW50cnktPmRvd24sIHBhdHRlcm4sIGZpbHRlcl9mbGFncywgaWR4KTsKCX0KCglTaG93V2luZG93KHBhbmUtPmh3bmQsIFNXX1NIT1cpOwoKCXJldHVybiBpZHg7Cn0KCgpzdGF0aWMgdm9pZCBmb3JtYXRfYnl0ZXMoTFBUU1RSIGJ1ZmZlciwgTE9OR0xPTkcgYnl0ZXMpCnsKCXN0YXRpYyBjb25zdCBUQ0hBUiBzRm10R0JbXSA9IHsnJScsICcuJywgJzEnLCAnZicsICcgJywgJ0cnLCAnQicsICdcMCd9OwoJc3RhdGljIGNvbnN0IFRDSEFSIHNGbXRNQltdID0geyclJywgJy4nLCAnMScsICdmJywgJyAnLCAnTScsICdCJywgJ1wwJ307CglzdGF0aWMgY29uc3QgVENIQVIgc0ZtdGtCW10gPSB7JyUnLCAnLicsICcxJywgJ2YnLCAnICcsICdrJywgJ0InLCAnXDAnfTsKCglmbG9hdCBmQnl0ZXMgPSAoZmxvYXQpYnl0ZXM7CgoJaWYgKGJ5dGVzID49IDEwNzM3NDE4MjQpCS8qIDEgR0IgKi8KCQlfc3RwcmludGYoYnVmZmVyLCBzRm10R0IsIGZCeXRlcy8xMDczNzQxODI0LmYrLjVmKTsKCWVsc2UgaWYgKGJ5dGVzID49IDEwNDg1NzYpCS8qIDEgTUIgKi8KCQlfc3RwcmludGYoYnVmZmVyLCBzRm10TUIsIGZCeXRlcy8xMDQ4NTc2LmYrLjVmKTsKCWVsc2UgaWYgKGJ5dGVzID49IDEwMjQpCQkvKiAxIGtCICovCgkJX3N0cHJpbnRmKGJ1ZmZlciwgc0ZtdGtCLCBmQnl0ZXMvMTAyNC5mKy41Zik7CgllbHNlCgkJX3N0cHJpbnRmKGJ1ZmZlciwgc0xvbmdOdW1GbXQsIGJ5dGVzKTsKfQoKc3RhdGljIHZvaWQgc2V0X3NwYWNlX3N0YXR1cyh2b2lkKQp7CglVTEFSR0VfSU5URUdFUiB1bEZyZWVCeXRlc1RvQ2FsbGVyLCB1bFRvdGFsQnl0ZXMsIHVsRnJlZUJ5dGVzOwoJVENIQVIgZm10WzY0XSwgYjFbNjRdLCBiMls2NF0sIGJ1ZmZlcltCVUZGRVJfTEVOXTsKCglpZiAoR2V0RGlza0ZyZWVTcGFjZUV4KE5VTEwsICZ1bEZyZWVCeXRlc1RvQ2FsbGVyLCAmdWxUb3RhbEJ5dGVzLCAmdWxGcmVlQnl0ZXMpKSB7CgkJZm9ybWF0X2J5dGVzKGIxLCB1bEZyZWVCeXRlc1RvQ2FsbGVyLlF1YWRQYXJ0KTsKCQlmb3JtYXRfYnl0ZXMoYjIsIHVsVG90YWxCeXRlcy5RdWFkUGFydCk7CgkJd3NwcmludGYoYnVmZmVyLCBSUyhmbXQsSURTX0ZSRUVfU1BBQ0VfRk1UKSwgYjEsIGIyKTsKCX0gZWxzZQoJCWxzdHJjcHkoYnVmZmVyLCBzUU1hcmtzKTsKCglTZW5kTWVzc2FnZShHbG9iYWxzLmhzdGF0dXNiYXIsIFNCX1NFVFRFWFQsIDAsIChMUEFSQU0pYnVmZmVyKTsKfQoKCnN0YXRpYyBXTkRQUk9DIGdfb3JnVHJlZVduZFByb2M7CgpzdGF0aWMgdm9pZCBjcmVhdGVfdHJlZV93aW5kb3coSFdORCBwYXJlbnQsIFBhbmUqIHBhbmUsIFVJTlQgaWQsIFVJTlQgaWRfaGVhZGVyLCBMUENUU1RSIHBhdHRlcm4sIGludCBmaWx0ZXJfZmxhZ3MpCnsKCXN0YXRpYyBjb25zdCBUQ0hBUiBzTGlzdEJveFtdID0geydMJywnaScsJ3MnLCd0JywnQicsJ28nLCd4JywnXDAnfTsKCglzdGF0aWMgaW50IHNfaW5pdCA9IDA7CglFbnRyeSogZW50cnkgPSBwYW5lLT5yb290OwoKCXBhbmUtPmh3bmQgPSBDcmVhdGVXaW5kb3coc0xpc3RCb3gsIHNFbXB0eSwgV1NfQ0hJTER8V1NfVklTSUJMRXxXU19IU0NST0xMfFdTX1ZTQ1JPTEx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMQlNfRElTQUJMRU5PU0NST0xMfExCU19OT0lOVEVHUkFMSEVJR0hUfExCU19PV05FUkRSQVdGSVhFRHxMQlNfTk9USUZZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgcGFyZW50LCAoSE1FTlUpVUxvbmdUb0hhbmRsZShpZCksIEdsb2JhbHMuaEluc3RhbmNlLCAwKTsKCglTZXRXaW5kb3dMb25nUHRyKHBhbmUtPmh3bmQsIEdXTFBfVVNFUkRBVEEsIChMUEFSQU0pcGFuZSk7CglnX29yZ1RyZWVXbmRQcm9jID0gKFdORFBST0MpIFNldFdpbmRvd0xvbmdQdHIocGFuZS0+aHduZCwgR1dMUF9XTkRQUk9DLCAoTFBBUkFNKVRyZWVXbmRQcm9jKTsKCglTZW5kTWVzc2FnZShwYW5lLT5od25kLCBXTV9TRVRGT05ULCAoV1BBUkFNKUdsb2JhbHMuaGZvbnQsIEZBTFNFKTsKCgkvKiBpbnNlcnQgZW50cmllcyBpbnRvIGxpc3Rib3ggKi8KCWlmIChlbnRyeSkKCQlpbnNlcnRfZW50cmllcyhwYW5lLCBlbnRyeSwgcGF0dGVybiwgZmlsdGVyX2ZsYWdzLCAtMSk7CgoJLyogY2FsY3VsYXRlIGNvbHVtbiB3aWR0aHMgKi8KCWlmICghc19pbml0KSB7CgkJc19pbml0ID0gMTsKCQlpbml0X291dHB1dChwYW5lLT5od25kKTsKCX0KCgljYWxjX3dpZHRocyhwYW5lLCBUUlVFKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCXBhbmUtPmh3bmRIZWFkZXIgPSBjcmVhdGVfaGVhZGVyKHBhcmVudCwgcGFuZSwgaWRfaGVhZGVyKTsKI2VuZGlmCn0KCgpzdGF0aWMgdm9pZCBJbml0Q2hpbGRXaW5kb3coQ2hpbGRXbmQqIGNoaWxkKQp7CgljcmVhdGVfdHJlZV93aW5kb3coY2hpbGQtPmh3bmQsICZjaGlsZC0+bGVmdCwgSURXX1RSRUVfTEVGVCwgSURXX0hFQURFUl9MRUZULCBOVUxMLCBURl9BTEwpOwoJY3JlYXRlX3RyZWVfd2luZG93KGNoaWxkLT5od25kLCAmY2hpbGQtPnJpZ2h0LCBJRFdfVFJFRV9SSUdIVCwgSURXX0hFQURFUl9SSUdIVCwgY2hpbGQtPmZpbHRlcl9wYXR0ZXJuLCBjaGlsZC0+ZmlsdGVyX2ZsYWdzKTsKfQoKCnN0YXRpYyB2b2lkIGZvcm1hdF9kYXRlKGNvbnN0IEZJTEVUSU1FKiBmdCwgVENIQVIqIGJ1ZmZlciwgaW50IHZpc2libGVfY29scykKewoJU1lTVEVNVElNRSBzeXN0aW1lOwoJRklMRVRJTUUgbGZ0OwoJaW50IGxlbiA9IDA7CgoJKmJ1ZmZlciA9ICdcMCc7CgoJaWYgKCFmdC0+ZHdMb3dEYXRlVGltZSAmJiAhZnQtPmR3SGlnaERhdGVUaW1lKQoJCXJldHVybjsKCglpZiAoIUZpbGVUaW1lVG9Mb2NhbEZpbGVUaW1lKGZ0LCAmbGZ0KSkKCQl7ZXJyOiBsc3RyY3B5KGJ1ZmZlcixzUU1hcmtzKTsgcmV0dXJuO30KCglpZiAoIUZpbGVUaW1lVG9TeXN0ZW1UaW1lKCZsZnQsICZzeXN0aW1lKSkKCQlnb3RvIGVycjsKCglpZiAodmlzaWJsZV9jb2xzICYgQ09MX0RBVEUpIHsKCQlsZW4gPSBHZXREYXRlRm9ybWF0KExPQ0FMRV9VU0VSX0RFRkFVTFQsIDAsICZzeXN0aW1lLCAwLCBidWZmZXIsIEJVRkZFUl9MRU4pOwoJCWlmICghbGVuKQoJCQlnb3RvIGVycjsKCX0KCglpZiAodmlzaWJsZV9jb2xzICYgQ09MX1RJTUUpIHsKCQlpZiAobGVuKQoJCQlidWZmZXJbbGVuLTFdID0gJyAnOwoKCQlidWZmZXJbbGVuKytdID0gJyAnOwoKCQlpZiAoIUdldFRpbWVGb3JtYXQoTE9DQUxFX1VTRVJfREVGQVVMVCwgMCwgJnN5c3RpbWUsIDAsIGJ1ZmZlcitsZW4sIEJVRkZFUl9MRU4tbGVuKSkKCQkJYnVmZmVyW2xlbl0gPSAnXDAnOwoJfQp9CgoKc3RhdGljIHZvaWQgY2FsY193aWR0aChQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgaW50IGNvbCwgTFBDVFNUUiBzdHIpCnsKCVJFQ1QgcnQgPSB7MCwgMCwgMCwgMH07CgoJRHJhd1RleHQoZGlzLT5oREMsIHN0ciwgLTEsICZydCwgRFRfQ0FMQ1JFQ1R8RFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWCk7CgoJaWYgKHJ0LnJpZ2h0ID4gcGFuZS0+d2lkdGhzW2NvbF0pCgkJcGFuZS0+d2lkdGhzW2NvbF0gPSBydC5yaWdodDsKfQoKc3RhdGljIHZvaWQgY2FsY190YWJiZWRfd2lkdGgoUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIGludCBjb2wsIExQQ1RTVFIgc3RyKQp7CglSRUNUIHJ0ID0gezAsIDAsIDAsIDB9OwoKLyoJRFJBV1RFWFRQQVJBTVMgZHRwID0ge3NpemVvZihEUkFXVEVYVFBBUkFNUyksIDJ9OwoJRHJhd1RleHRFeChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX0NBTENSRUNUfERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVh8RFRfRVhQQU5EVEFCU3xEVF9UQUJTVE9QLCAmZHRwKTsqLwoKCURyYXdUZXh0KGRpcy0+aERDLCBzdHIsIC0xLCAmcnQsIERUX0NBTENSRUNUfERUX1NJTkdMRUxJTkV8RFRfRVhQQU5EVEFCU3xEVF9UQUJTVE9QfCgyPDw4KSk7CgkvKkZJWE1FIHJ0ICgwLDApID8/PyAqLwoKCWlmIChydC5yaWdodCA+IHBhbmUtPndpZHRoc1tjb2xdKQoJCXBhbmUtPndpZHRoc1tjb2xdID0gcnQucmlnaHQ7Cn0KCgpzdGF0aWMgdm9pZCBvdXRwdXRfdGV4dChQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgaW50IGNvbCwgTFBDVFNUUiBzdHIsIERXT1JEIGZsYWdzKQp7CglpbnQgeCA9IGRpcy0+cmNJdGVtLmxlZnQ7CglSRUNUIHJ0OwoKCXJ0LmxlZnQgICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbF0rR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC50b3AgICAgPSBkaXMtPnJjSXRlbS50b3A7CglydC5yaWdodCAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2wrMV0tR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC5ib3R0b20gPSBkaXMtPnJjSXRlbS5ib3R0b207CgoJRHJhd1RleHQoZGlzLT5oREMsIHN0ciwgLTEsICZydCwgRFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWHxmbGFncyk7Cn0KCnN0YXRpYyB2b2lkIG91dHB1dF90YWJiZWRfdGV4dChQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgaW50IGNvbCwgTFBDVFNUUiBzdHIpCnsKCWludCB4ID0gZGlzLT5yY0l0ZW0ubGVmdDsKCVJFQ1QgcnQ7CgoJcnQubGVmdCAgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sXStHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LnRvcCAgICA9IGRpcy0+cmNJdGVtLnRvcDsKCXJ0LnJpZ2h0ICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbCsxXS1HbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LmJvdHRvbSA9IGRpcy0+cmNJdGVtLmJvdHRvbTsKCi8qCURSQVdURVhUUEFSQU1TIGR0cCA9IHtzaXplb2YoRFJBV1RFWFRQQVJBTVMpLCAyfTsKCURyYXdUZXh0RXgoZGlzLT5oREMsIChMUFRTVFIpc3RyLCAtMSwgJnJ0LCBEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYfERUX0VYUEFORFRBQlN8RFRfVEFCU1RPUCwgJmR0cCk7Ki8KCglEcmF3VGV4dChkaXMtPmhEQywgc3RyLCAtMSwgJnJ0LCBEVF9TSU5HTEVMSU5FfERUX0VYUEFORFRBQlN8RFRfVEFCU1RPUHwoMjw8OCkpOwp9CgpzdGF0aWMgdm9pZCBvdXRwdXRfbnVtYmVyKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0cikKewoJaW50IHggPSBkaXMtPnJjSXRlbS5sZWZ0OwoJUkVDVCBydDsKCUxQQ1RTVFIgcyA9IHN0cjsKCVRDSEFSIGJbMTI4XTsKCUxQVFNUUiBkID0gYjsKCWludCBwb3M7CgoJcnQubGVmdCAgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sXStHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LnRvcCAgICA9IGRpcy0+cmNJdGVtLnRvcDsKCXJ0LnJpZ2h0ICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbCsxXS1HbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LmJvdHRvbSA9IGRpcy0+cmNJdGVtLmJvdHRvbTsKCglpZiAoKnMpCgkJKmQrKyA9ICpzKys7CgoJLyogaW5zZXJ0IG51bWJlciBzZXBhcmF0b3IgY2hhcmFjdGVycyAqLwoJcG9zID0gbHN0cmxlbihzKSAlIDM7CgoJd2hpbGUoKnMpCgkJaWYgKHBvcy0tKQoJCQkqZCsrID0gKnMrKzsKCQllbHNlIHsKCQkJKmQrKyA9IEdsb2JhbHMubnVtX3NlcDsKCQkJcG9zID0gMzsKCQl9CgoJRHJhd1RleHQoZGlzLT5oREMsIGIsIGQtYiwgJnJ0LCBEVF9SSUdIVHxEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYfERUX0VORF9FTExJUFNJUyk7Cn0KCgpzdGF0aWMgQk9PTCBpc19leGVfZmlsZShMUENUU1RSIGV4dCkKewoJc3RhdGljIGNvbnN0IFRDSEFSIGV4ZWN1dGFibGVfZXh0ZW5zaW9uc1tdWzRdID0gewoJCXsnQycsJ08nLCdNJywnXDAnfSwKCQl7J0UnLCdYJywnRScsJ1wwJ30sCgkJeydCJywnQScsJ1QnLCdcMCd9LAoJCXsnQycsJ00nLCdEJywnXDAnfSwKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCXsnQycsJ00nLCdNJywnXDAnfSwKCQl7J0InLCdUJywnTScsJ1wwJ30sCgkJeydBJywnVycsJ0snLCdcMCd9LAojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCQl7J1wwJ30KCX07CgoJVENIQVIgZXh0X2J1ZmZlcltfTUFYX0VYVF07Cgljb25zdCBUQ0hBUiAoKnApWzRdOwoJTFBDVFNUUiBzOwoJTFBUU1RSIGQ7CgoJZm9yKHM9ZXh0KzEsZD1leHRfYnVmZmVyOyAoKmQ9dG9sb3dlcigqcykpOyBzKyspCgkJZCsrOwoKCWZvcihwPWV4ZWN1dGFibGVfZXh0ZW5zaW9uczsgKCpwKVswXTsgcCsrKQoJCWlmICghbHN0cmNtcGkoZXh0X2J1ZmZlciwgKnApKQoJCQlyZXR1cm4gVFJVRTsKCglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBCT09MIGlzX3JlZ2lzdGVyZWRfdHlwZShMUENUU1RSIGV4dCkKewoJLyogY2hlY2sgaWYgdGhlcmUgZXhpc3RzIGEgY2xhc3NuYW1lIGZvciB0aGlzIGZpbGUgZXh0ZW5zaW9uIGluIHRoZSByZWdpc3RyeSAqLwoJaWYgKCFSZWdRdWVyeVZhbHVlKEhLRVlfQ0xBU1NFU19ST09ULCBleHQsIE5VTEwsIE5VTEwpKQoJCXJldHVybiBUUlVFOwoKCXJldHVybiBGQUxTRTsKfQoKc3RhdGljIGVudW0gRklMRV9UWVBFIGdldF9maWxlX3R5cGUoTFBDVFNUUiBmaWxlbmFtZSkKewoJTFBDVFNUUiBleHQgPSBfdGNzcmNocihmaWxlbmFtZSwgJy4nKTsKCWlmICghZXh0KQoJCWV4dCA9IHNFbXB0eTsKCglpZiAoaXNfZXhlX2ZpbGUoZXh0KSkKCQlyZXR1cm4gRlRfRVhFQ1VUQUJMRTsKCWVsc2UgaWYgKGlzX3JlZ2lzdGVyZWRfdHlwZShleHQpKQoJCXJldHVybiBGVF9ET0NVTUVOVDsKCWVsc2UKCQlyZXR1cm4gRlRfT1RIRVI7Cn0KCgpzdGF0aWMgdm9pZCBkcmF3X2l0ZW0oUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIEVudHJ5KiBlbnRyeSwgaW50IGNhbGNXaWR0aENvbCkKewoJVENIQVIgYnVmZmVyW0JVRkZFUl9MRU5dOwoJRFdPUkQgYXR0cnM7CglpbnQgdmlzaWJsZV9jb2xzID0gcGFuZS0+dmlzaWJsZV9jb2xzOwoJQ09MT1JSRUYgYmtjb2xvciwgdGV4dGNvbG9yOwoJUkVDVCBmb2N1c1JlY3QgPSBkaXMtPnJjSXRlbTsKCUhCUlVTSCBoYnJ1c2g7CgllbnVtIElNQUdFIGltZzsKCWludCBpbWdfcG9zLCBjeDsKCWludCBjb2wgPSAwOwoKCWlmIChlbnRyeSkgewoJCWF0dHJzID0gZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlczsKCgkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCWlmIChlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF0gPT0gJy4nICYmIGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsxXSA9PSAnLicKCQkJCQkmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMl0gPT0gJ1wwJykKCQkJCWltZyA9IElNR19GT0xERVJfVVA7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJZWxzZSBpZiAoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdID09ICcuJyAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMV0gPT0gJ1wwJykKCQkJCWltZyA9IElNR19GT0xERVJfQ1VSOwojZW5kaWYKCQkJZWxzZSBpZiAoCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCSBlbnRyeS0+ZXhwYW5kZWQgfHwKI2VuZGlmCgkJCQkJIChwYW5lLT50cmVlUGFuZSAmJiAoZGlzLT5pdGVtU3RhdGUmT0RTX0ZPQ1VTKSkpCgkJCQlpbWcgPSBJTUdfT1BFTl9GT0xERVI7CgkJCWVsc2UKCQkJCWltZyA9IElNR19GT0xERVI7CgkJfSBlbHNlIHsKCQkJc3dpdGNoKGdldF9maWxlX3R5cGUoZW50cnktPmRhdGEuY0ZpbGVOYW1lKSkgewoJCQkgIGNhc2UgRlRfRVhFQ1VUQUJMRToJaW1nID0gSU1HX0VYRUNVVEFCTEU7CWJyZWFrOwoJCQkgIGNhc2UgRlRfRE9DVU1FTlQ6CQlpbWcgPSBJTUdfRE9DVU1FTlQ7CQlicmVhazsKCQkJICBkZWZhdWx0OgkJCQlpbWcgPSBJTUdfRklMRTsKCQkJfQoJCX0KCX0gZWxzZSB7CgkJYXR0cnMgPSAwOwoJCWltZyA9IElNR19OT05FOwoJfQoKCWlmIChwYW5lLT50cmVlUGFuZSkgewoJCWlmIChlbnRyeSkgewoJCQlpbWdfcG9zID0gZGlzLT5yY0l0ZW0ubGVmdCArIGVudHJ5LT5sZXZlbCooSU1BR0VfV0lEVEgrVFJFRV9MSU5FX0RYKTsKCgkJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpIHsKCQkJCWludCB4OwoJCQkJaW50IHkgPSBkaXMtPnJjSXRlbS50b3AgKyBJTUFHRV9IRUlHSFQvMjsKCQkJCUVudHJ5KiB1cDsKCQkJCVJFQ1QgcnRfY2xpcDsKCQkJCUhSR04gaHJnbl9vcmcgPSBDcmVhdGVSZWN0UmduKDAsIDAsIDAsIDApOwoJCQkJSFJHTiBocmduOwoKCQkJCXJ0X2NsaXAubGVmdCAgID0gZGlzLT5yY0l0ZW0ubGVmdDsKCQkJCXJ0X2NsaXAudG9wICAgID0gZGlzLT5yY0l0ZW0udG9wOwoJCQkJcnRfY2xpcC5yaWdodCAgPSBkaXMtPnJjSXRlbS5sZWZ0K3BhbmUtPndpZHRoc1tjb2xdOwoJCQkJcnRfY2xpcC5ib3R0b20gPSBkaXMtPnJjSXRlbS5ib3R0b207CgoJCQkJaHJnbiA9IENyZWF0ZVJlY3RSZ25JbmRpcmVjdCgmcnRfY2xpcCk7CgoJCQkJaWYgKCFHZXRDbGlwUmduKGRpcy0+aERDLCBocmduX29yZykpIHsKCQkJCQlEZWxldGVPYmplY3QoaHJnbl9vcmcpOwoJCQkJCWhyZ25fb3JnID0gMDsKCQkJCX0KCgkJCQkvKiBIR0RJT0JKIGhvbGRQZW4gPSBTZWxlY3RPYmplY3QoZGlzLT5oREMsIEdldFN0b2NrT2JqZWN0KEJMQUNLX1BFTikpOyAqLwoJCQkJRXh0U2VsZWN0Q2xpcFJnbihkaXMtPmhEQywgaHJnbiwgUkdOX0FORCk7CgkJCQlEZWxldGVPYmplY3QoaHJnbik7CgoJCQkJaWYgKCh1cD1lbnRyeS0+dXApICE9IE5VTEwpIHsKCQkJCQlNb3ZlVG9FeChkaXMtPmhEQywgaW1nX3Bvcy1JTUFHRV9XSURUSC8yLCB5LCAwKTsKCQkJCQlMaW5lVG8oZGlzLT5oREMsIGltZ19wb3MtMiwgeSk7CgoJCQkJCXggPSBpbWdfcG9zIC0gSU1BR0VfV0lEVEgvMjsKCgkJCQkJZG8gewoJCQkJCQl4IC09IElNQUdFX1dJRFRIK1RSRUVfTElORV9EWDsKCgkJCQkJCWlmICh1cC0+bmV4dAojaWZuZGVmIF9MRUZUX0ZJTEVTCgkJCQkJCQkmJiAodXAtPm5leHQtPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkKI2VuZGlmCgkJCQkJCQkpIHsKCQkJCQkJCU1vdmVUb0V4KGRpcy0+aERDLCB4LCBkaXMtPnJjSXRlbS50b3AsIDApOwoJCQkJCQkJTGluZVRvKGRpcy0+aERDLCB4LCBkaXMtPnJjSXRlbS5ib3R0b20pOwoJCQkJCQl9CgkJCQkJfSB3aGlsZSgodXA9dXAtPnVwKSAhPSBOVUxMKTsKCQkJCX0KCgkJCQl4ID0gaW1nX3BvcyAtIElNQUdFX1dJRFRILzI7CgoJCQkJTW92ZVRvRXgoZGlzLT5oREMsIHgsIGRpcy0+cmNJdGVtLnRvcCwgMCk7CgkJCQlMaW5lVG8oZGlzLT5oREMsIHgsIHkpOwoKCQkJCWlmIChlbnRyeS0+bmV4dAojaWZuZGVmIF9MRUZUX0ZJTEVTCgkJCQkJJiYgKGVudHJ5LT5uZXh0LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKQojZW5kaWYKCQkJCQkpCgkJCQkJTGluZVRvKGRpcy0+aERDLCB4LCBkaXMtPnJjSXRlbS5ib3R0b20pOwoKCQkJCVNlbGVjdENsaXBSZ24oZGlzLT5oREMsIGhyZ25fb3JnKTsKCQkJCWlmIChocmduX29yZykgRGVsZXRlT2JqZWN0KGhyZ25fb3JnKTsKCQkJCS8qIFNlbGVjdE9iamVjdChkaXMtPmhEQywgaG9sZFBlbik7ICovCgkJCX0gZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKSB7CgkJCQlpbnQgcmlnaHQgPSBpbWdfcG9zICsgSU1BR0VfV0lEVEggLSBUUkVFX0xJTkVfRFg7CgoJCQkJaWYgKHJpZ2h0ID4gcGFuZS0+d2lkdGhzW2NvbF0pCgkJCQkJcGFuZS0+d2lkdGhzW2NvbF0gPSByaWdodDsKCQkJfQoJCX0gZWxzZSAgewoJCQlpbWdfcG9zID0gZGlzLT5yY0l0ZW0ubGVmdDsKCQl9Cgl9IGVsc2UgewoJCWltZ19wb3MgPSBkaXMtPnJjSXRlbS5sZWZ0OwoKCQlpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQlwYW5lLT53aWR0aHNbY29sXSA9IElNQUdFX1dJRFRIOwoJfQoKCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpIHsKCQlmb2N1c1JlY3QubGVmdCA9IGltZ19wb3MgLTI7CgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQlpZiAocGFuZS0+dHJlZVBhbmUgJiYgZW50cnkpIHsKCQkJUkVDVCBydCA9IHswfTsKCgkJCURyYXdUZXh0KGRpcy0+aERDLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIC0xLCAmcnQsIERUX0NBTENSRUNUfERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVgpOwoKCQkJZm9jdXNSZWN0LnJpZ2h0ID0gZGlzLT5yY0l0ZW0ubGVmdCtwYW5lLT5wb3NpdGlvbnNbY29sKzFdK1RSRUVfTElORV9EWCArIHJ0LnJpZ2h0ICsyOwoJCX0KI2Vsc2UKCgkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfQ09NUFJFU1NFRCkKCQkJdGV4dGNvbG9yID0gQ09MT1JfQ09NUFJFU1NFRDsKCQllbHNlCiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoJCQl0ZXh0Y29sb3IgPSBSR0IoMCwwLDApOwoKCQlpZiAoZGlzLT5pdGVtU3RhdGUgJiBPRFNfRk9DVVMpIHsKCQkJdGV4dGNvbG9yID0gUkdCKDI1NSwyNTUsMjU1KTsKCQkJYmtjb2xvciA9IENPTE9SX1NFTEVDVElPTjsKCQl9IGVsc2UgewoJCQlia2NvbG9yID0gUkdCKDI1NSwyNTUsMjU1KTsKCQl9CgoJCWhicnVzaCA9IENyZWF0ZVNvbGlkQnJ1c2goYmtjb2xvcik7CgkJRmlsbFJlY3QoZGlzLT5oREMsICZmb2N1c1JlY3QsIGhicnVzaCk7CgkJRGVsZXRlT2JqZWN0KGhicnVzaCk7CgoJCVNldEJrTW9kZShkaXMtPmhEQywgVFJBTlNQQVJFTlQpOwoJCVNldFRleHRDb2xvcihkaXMtPmhEQywgdGV4dGNvbG9yKTsKCgkJY3ggPSBwYW5lLT53aWR0aHNbY29sXTsKCgkJaWYgKGN4ICYmIGltZyE9SU1HX05PTkUpIHsKCQkJaWYgKGN4ID4gSU1BR0VfV0lEVEgpCgkJCQljeCA9IElNQUdFX1dJRFRIOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgkJCWlmIChlbnRyeS0+aGljb24gJiYgZW50cnktPmhpY29uIT0oSElDT04pLTEpCgkJCQlEcmF3SWNvbkV4KGRpcy0+aERDLCBpbWdfcG9zLCBkaXMtPnJjSXRlbS50b3AsIGVudHJ5LT5oaWNvbiwgY3gsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUlDT04pLCAwLCAwLCBESV9OT1JNQUwpOwoJCQllbHNlCiNlbmRpZgoJCQkJSW1hZ2VMaXN0X0RyYXdFeChHbG9iYWxzLmhpbWwsIGltZywgZGlzLT5oREMsCgkJCQkJCQkJIGltZ19wb3MsIGRpcy0+cmNJdGVtLnRvcCwgY3gsCgkJCQkJCQkJIElNQUdFX0hFSUdIVCwgYmtjb2xvciwgQ0xSX0RFRkFVTFQsIElMRF9OT1JNQUwpOwoJCX0KCX0KCglpZiAoIWVudHJ5KQoJCXJldHVybjsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJaWYgKGltZyA+PSBJTUdfRk9MREVSX1VQKQoJCXJldHVybjsKI2VuZGlmCgoJY29sKys7CgoJLyogb3VwdXQgZmlsZSBuYW1lICovCglpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIDApOwoJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSk7CgoJY29sKys7CgojaWZkZWYgX05PX0VYVEVOU0lPTlMKICBpZiAoIXBhbmUtPnRyZWVQYW5lKSB7CiNlbmRpZgoKICAgICAgICAvKiBkaXNwbGF5IGZpbGUgc2l6ZSAqLwoJaWYgKHZpc2libGVfY29scyAmIENPTF9TSVpFKSB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCWlmICghKGF0dHJzJkZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkpCiNlbmRpZgoJCXsKCQkJVUxPTkdMT05HIHNpemU7CgogICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gKChVTE9OR0xPTkcpZW50cnktPmRhdGEubkZpbGVTaXplSGlnaCA8PCAzMikgfCBlbnRyeS0+ZGF0YS5uRmlsZVNpemVMb3c7CgoJCQlfc3RwcmludGYoYnVmZmVyLCBzTG9uZ051bUZtdCwgc2l6ZSk7CgoJCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQkJb3V0cHV0X251bWJlcihwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCQkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsvKlRPRE86IG5vdCBldmVyIHRpbWUgZW5vdWdoICovCgkJfQoKCQljb2wrKzsKCX0KCgkvKiBkaXNwbGF5IGZpbGUgZGF0ZSAqLwoJaWYgKHZpc2libGVfY29scyAmIChDT0xfREFURXxDT0xfVElNRSkpIHsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWZvcm1hdF9kYXRlKCZlbnRyeS0+ZGF0YS5mdENyZWF0aW9uVGltZSwgYnVmZmVyLCB2aXNpYmxlX2NvbHMpOwoJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIsIDApOwoJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCQljb2wrKzsKCgkJZm9ybWF0X2RhdGUoJmVudHJ5LT5kYXRhLmZ0TGFzdEFjY2Vzc1RpbWUsIGJ1ZmZlciwgdmlzaWJsZV9jb2xzKTsKCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyLCAwKTsKCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgkJY29sKys7CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCQlmb3JtYXRfZGF0ZSgmZW50cnktPmRhdGEuZnRMYXN0V3JpdGVUaW1lLCBidWZmZXIsIHZpc2libGVfY29scyk7CgkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlciwgMCk7CgkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoJCWNvbCsrOwoJfQoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJaWYgKGVudHJ5LT5iaGZpX3ZhbGlkKSB7CiAgICAgICAgICAgIFVMT05HTE9ORyBpbmRleCA9ICgoVUxPTkdMT05HKWVudHJ5LT5iaGZpLm5GaWxlSW5kZXhIaWdoIDw8IDMyKSB8IGVudHJ5LT5iaGZpLm5GaWxlSW5kZXhMb3c7CgoJCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfSU5ERVgpIHsKCQkJX3N0cHJpbnRmKGJ1ZmZlciwgc0xvbmdIZXhGbXQsIGluZGV4KTsKCgkJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyLCBEVF9SSUdIVCk7CgkJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgoJCQljb2wrKzsKCQl9CgoJCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfTElOS1MpIHsKCQkJd3NwcmludGYoYnVmZmVyLCBzTnVtRm10LCBlbnRyeS0+YmhmaS5uTnVtYmVyT2ZMaW5rcyk7CgoJCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlciwgRFRfQ0VOVEVSKTsKCQkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCgkJCWNvbCsrOwoJCX0KCX0gZWxzZQoJCWNvbCArPSAyOwojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgkvKiBzaG93IGZpbGUgYXR0cmlidXRlcyAqLwoJaWYgKHZpc2libGVfY29scyAmIENPTF9BVFRSSUJVVEVTKSB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCXN0YXRpYyBjb25zdCBUQ0hBUiBzNFRhYnNbXSA9IHsnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1wwJ307CgkJbHN0cmNweShidWZmZXIsIHM0VGFicyk7CiNlbHNlCgkJc3RhdGljIGNvbnN0IFRDSEFSIHMxMVRhYnNbXSA9IHsnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1wwJ307CgkJbHN0cmNweShidWZmZXIsIHMxMVRhYnMpOwojZW5kaWYKCgkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfTk9STUFMKQkJCQkJYnVmZmVyWyAwXSA9ICdOJzsKCQllbHNlIHsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfUkVBRE9OTFkpCQkJYnVmZmVyWyAyXSA9ICdSJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfSElEREVOKQkJCQlidWZmZXJbIDRdID0gJ0gnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9TWVNURU0pCQkJCWJ1ZmZlclsgNl0gPSAnUyc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0FSQ0hJVkUpCQkJCWJ1ZmZlclsgOF0gPSAnQSc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0NPTVBSRVNTRUQpCQkJYnVmZmVyWzEwXSA9ICdDJzsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpCQkJYnVmZmVyWzEyXSA9ICdEJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfRU5DUllQVEVEKQkJCWJ1ZmZlclsxNF0gPSAnRSc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX1RFTVBPUkFSWSkJCQlidWZmZXJbMTZdID0gJ1QnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9TUEFSU0VfRklMRSkJCQlidWZmZXJbMThdID0gJ1AnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9SRVBBUlNFX1BPSU5UKQkJYnVmZmVyWzIwXSA9ICdRJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfT0ZGTElORSkJCQkJYnVmZmVyWzIyXSA9ICdPJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfTk9UX0NPTlRFTlRfSU5ERVhFRCkJYnVmZmVyWzI0XSA9ICdYJzsKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgkJfQoKCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQlvdXRwdXRfdGFiYmVkX3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQljYWxjX3RhYmJlZF93aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCgkJY29sKys7Cgl9CgovKlRPRE8KCWlmIChmbGFncy5zZWN1cml0eSkgewoJCXN0YXRpYyBjb25zdCBUQ0hBUiBzU2VjVGFic1tdID0gewoJCQknICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsCgkJCScgJywnXHQnLCcgJywKCQkJJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLAoJCQknICcsJ1x0JywnICcsCgkJCScgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywKCQkJJ1wwJwoJCX07CgoJCURXT1JEIHJpZ2h0cyA9IGdldF9hY2Nlc3NfbWFzaygpOwoKCQlsc3RyY3B5KGJ1ZmZlciwgc1NlY1RhYnMpOwoKCQlpZiAocmlnaHRzICYgRklMRV9SRUFEX0RBVEEpCQkJYnVmZmVyWyAwXSA9ICdSJzsKCQlpZiAocmlnaHRzICYgRklMRV9XUklURV9EQVRBKQkJCWJ1ZmZlclsgMl0gPSAnVyc7CgkJaWYgKHJpZ2h0cyAmIEZJTEVfQVBQRU5EX0RBVEEpCQkJYnVmZmVyWyA0XSA9ICdBJzsKCQlpZiAocmlnaHRzICYgRklMRV9SRUFEX0VBKQkJCQl7YnVmZmVyWzZdID0gJ2VudHJ5JzsgYnVmZmVyWyA3XSA9ICdSJzt9CgkJaWYgKHJpZ2h0cyAmIEZJTEVfV1JJVEVfRUEpCQkJCXtidWZmZXJbOV0gPSAnZW50cnknOyBidWZmZXJbMTBdID0gJ1cnO30KCQlpZiAocmlnaHRzICYgRklMRV9FWEVDVVRFKQkJCQlidWZmZXJbMTJdID0gJ1gnOwoJCWlmIChyaWdodHMgJiBGSUxFX0RFTEVURV9DSElMRCkJCQlidWZmZXJbMTRdID0gJ0QnOwoJCWlmIChyaWdodHMgJiBGSUxFX1JFQURfQVRUUklCVVRFUykJCXtidWZmZXJbMTZdID0gJ2EnOyBidWZmZXJbMTddID0gJ1InO30KCQlpZiAocmlnaHRzICYgRklMRV9XUklURV9BVFRSSUJVVEVTKQkJe2J1ZmZlclsxOV0gPSAnYSc7IGJ1ZmZlclsyMF0gPSAnVyc7fQoJCWlmIChyaWdodHMgJiBXUklURV9EQUMpCQkJCQlidWZmZXJbMjJdID0gJ0MnOwoJCWlmIChyaWdodHMgJiBXUklURV9PV05FUikJCQkJYnVmZmVyWzI0XSA9ICdPJzsKCQlpZiAocmlnaHRzICYgU1lOQ0hST05JWkUpCQkJCWJ1ZmZlclsyNl0gPSAnUyc7CgoJCW91dHB1dF90ZXh0KGRpcywgY29sKyssIGJ1ZmZlciwgRFRfTEVGVCwgMywgcHNpemUpOwoJfQoKCWlmIChmbGFncy5kZXNjcmlwdGlvbikgewoJCWdldF9kZXNjcmlwdGlvbihidWZmZXIpOwoJCW91dHB1dF90ZXh0KGRpcywgY29sKyssIGJ1ZmZlciwgMCwgcHNpemUpOwoJfQoqLwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCiAgfQoKICAgICAgICAvKiBkcmF3IGZvY3VzIGZyYW1lICovCglpZiAoKGRpcy0+aXRlbVN0YXRlJk9EU19GT0NVUykgJiYgY2FsY1dpZHRoQ29sPT0tMSkgewoJICAgICAgICAvKiBDdXJyZW50bHkgWzA0LzIwMDBdIFdpbmUgbmVpdGhlciBiZWhhdmVzIGV4YWN0bHkgdGhlIHNhbWUgKi8KCSAgICAgICAgLyogd2F5IGFzIFdJTiA5NSBub3IgbGlrZSBXaW5kb3dzIE5ULi4uICovCgkJSEdESU9CSiBsYXN0QnJ1c2g7CgkJSFBFTiBsYXN0UGVuOwoJCUhQRU4gaHBlbjsKCgkJaWYgKCEoR2V0VmVyc2lvbigpICYgMHg4MDAwMDAwMCkpIHsJLyogV2luZG93cyBOVD8gKi8KCQkJTE9HQlJVU0ggbGIgPSB7UFNfU09MSUQsIFJHQigyNTUsMjU1LDI1NSl9OwoJCQlocGVuID0gRXh0Q3JlYXRlUGVuKFBTX0NPU01FVElDfFBTX0FMVEVSTkFURSwgMSwgJmxiLCAwLCAwKTsKCQl9IGVsc2UKCQkJaHBlbiA9IENyZWF0ZVBlbihQU19ET1QsIDAsIFJHQigyNTUsMjU1LDI1NSkpOwoKCQlsYXN0UGVuID0gU2VsZWN0UGVuKGRpcy0+aERDLCBocGVuKTsKCQlsYXN0QnJ1c2ggPSBTZWxlY3RPYmplY3QoZGlzLT5oREMsIEdldFN0b2NrT2JqZWN0KEhPTExPV19CUlVTSCkpOwoJCVNldFJPUDIoZGlzLT5oREMsIFIyX1hPUlBFTik7CgkJUmVjdGFuZ2xlKGRpcy0+aERDLCBmb2N1c1JlY3QubGVmdCwgZm9jdXNSZWN0LnRvcCwgZm9jdXNSZWN0LnJpZ2h0LCBmb2N1c1JlY3QuYm90dG9tKTsKCQlTZWxlY3RPYmplY3QoZGlzLT5oREMsIGxhc3RCcnVzaCk7CgkJU2VsZWN0T2JqZWN0KGRpcy0+aERDLCBsYXN0UGVuKTsKCQlEZWxldGVPYmplY3QoaHBlbik7Cgl9CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwp9CgoKI2lmZGVmIF9OT19FWFRFTlNJT05TCgpzdGF0aWMgdm9pZCBkcmF3X3NwbGl0YmFyKEhXTkQgaHduZCwgaW50IHgpCnsKCVJFQ1QgcnQ7CglIREMgaGRjID0gR2V0REMoaHduZCk7CgoJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoKCXJ0LmxlZnQgPSB4IC0gU1BMSVRfV0lEVEgvMjsKCXJ0LnJpZ2h0ID0geCArIFNQTElUX1dJRFRILzIrMTsKCglJbnZlcnRSZWN0KGhkYywgJnJ0KTsKCglSZWxlYXNlREMoaHduZCwgaGRjKTsKfQoKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoKc3RhdGljIHZvaWQgc2V0X2hlYWRlcihQYW5lKiBwYW5lKQp7CglIRF9JVEVNIGl0ZW07CglpbnQgc2Nyb2xsX3BvcyA9IEdldFNjcm9sbFBvcyhwYW5lLT5od25kLCBTQl9IT1JaKTsKCWludCBpPTAsIHg9MDsKCglpdGVtLm1hc2sgPSBIRElfV0lEVEg7CglpdGVtLmN4eSA9IDA7CgoJZm9yKDsgeCtwYW5lLT53aWR0aHNbaV08c2Nyb2xsX3BvcyAmJiBpPENPTFVNTlM7IGkrKykgewoJCXggKz0gcGFuZS0+d2lkdGhzW2ldOwoJCVNlbmRNZXNzYWdlKHBhbmUtPmh3bmRIZWFkZXIsIEhETV9TRVRJVEVNLCBpLCAoTFBBUkFNKSAmaXRlbSk7Cgl9CgoJaWYgKGkgPCBDT0xVTU5TKSB7CgkJeCArPSBwYW5lLT53aWR0aHNbaV07CgkJaXRlbS5jeHkgPSB4IC0gc2Nyb2xsX3BvczsKCQlTZW5kTWVzc2FnZShwYW5lLT5od25kSGVhZGVyLCBIRE1fU0VUSVRFTSwgaSsrLCAoTFBBUkFNKSAmaXRlbSk7CgoJCWZvcig7IGk8Q09MVU1OUzsgaSsrKSB7CgkJCWl0ZW0uY3h5ID0gcGFuZS0+d2lkdGhzW2ldOwoJCQl4ICs9IHBhbmUtPndpZHRoc1tpXTsKCQkJU2VuZE1lc3NhZ2UocGFuZS0+aHduZEhlYWRlciwgSERNX1NFVElURU0sIGksIChMUEFSQU0pICZpdGVtKTsKCQl9Cgl9Cn0KCnN0YXRpYyBMUkVTVUxUIHBhbmVfbm90aWZ5KFBhbmUqIHBhbmUsIE5NSERSKiBwbm1oKQp7Cglzd2l0Y2gocG5taC0+Y29kZSkgewoJCWNhc2UgSEROX0lURU1DSEFOR0VEOiB7CgkJCUhEX05PVElGWSogcGhkbiA9IChIRF9OT1RJRlkqKSBwbm1oOwoJCQlpbnQgaWR4ID0gcGhkbi0+aUl0ZW07CgkJCWludCBkeCA9IHBoZG4tPnBpdGVtLT5jeHkgLSBwYW5lLT53aWR0aHNbaWR4XTsKCQkJaW50IGk7CgoJCQlSRUNUIGNsbnQ7CgkJCUdldENsaWVudFJlY3QocGFuZS0+aHduZCwgJmNsbnQpOwoKCQkJcGFuZS0+d2lkdGhzW2lkeF0gKz0gZHg7CgoJCQlmb3IoaT1pZHg7ICsraTw9Q09MVU1OUzsgKQoJCQkJcGFuZS0+cG9zaXRpb25zW2ldICs9IGR4OwoKCQkJewoJCQkJaW50IHNjcm9sbF9wb3MgPSBHZXRTY3JvbGxQb3MocGFuZS0+aHduZCwgU0JfSE9SWik7CgkJCQlSRUNUIHJ0X3NjcjsKCQkJCVJFQ1QgcnRfY2xpcDsKCgkJCQlydF9zY3IubGVmdCAgID0gcGFuZS0+cG9zaXRpb25zW2lkeCsxXS1zY3JvbGxfcG9zOwoJCQkJcnRfc2NyLnRvcCAgICA9IDA7CgkJCQlydF9zY3IucmlnaHQgID0gY2xudC5yaWdodDsKCQkJCXJ0X3Njci5ib3R0b20gPSBjbG50LmJvdHRvbTsKCgkJCQlydF9jbGlwLmxlZnQgICA9IHBhbmUtPnBvc2l0aW9uc1tpZHhdLXNjcm9sbF9wb3M7CgkJCQlydF9jbGlwLnRvcCAgICA9IDA7CgkJCQlydF9jbGlwLnJpZ2h0ICA9IGNsbnQucmlnaHQ7CgkJCQlydF9jbGlwLmJvdHRvbSA9IGNsbnQuYm90dG9tOwoKCQkJCWlmIChydF9zY3IubGVmdCA8IDApIHJ0X3Njci5sZWZ0ID0gMDsKCQkJCWlmIChydF9jbGlwLmxlZnQgPCAwKSBydF9jbGlwLmxlZnQgPSAwOwoKCQkJCVNjcm9sbFdpbmRvd0V4KHBhbmUtPmh3bmQsIGR4LCAwLCAmcnRfc2NyLCAmcnRfY2xpcCwgMCwgMCwgU1dfSU5WQUxJREFURSk7CgoJCQkJcnRfY2xpcC5yaWdodCA9IHBhbmUtPnBvc2l0aW9uc1tpZHgrMV07CgkJCQlSZWRyYXdXaW5kb3cocGFuZS0+aHduZCwgJnJ0X2NsaXAsIDAsIFJEV19JTlZBTElEQVRFfFJEV19VUERBVEVOT1cpOwoKCQkJCWlmIChwbm1oLT5jb2RlID09IEhETl9FTkRUUkFDSykgewoJCQkJCVNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX1NFVEhPUklaT05UQUxFWFRFTlQsIHBhbmUtPnBvc2l0aW9uc1tDT0xVTU5TXSwgMCk7CgoJCQkJCWlmIChHZXRTY3JvbGxQb3MocGFuZS0+aHduZCwgU0JfSE9SWikgIT0gc2Nyb2xsX3BvcykKCQkJCQkJc2V0X2hlYWRlcihwYW5lKTsKCQkJCX0KCQkJfQoKCQkJcmV0dXJuIEZBTFNFOwoJCX0KCgkJY2FzZSBIRE5fRElWSURFUkRCTENMSUNLOiB7CgkJCUhEX05PVElGWSogcGhkbiA9IChIRF9OT1RJRlkqKSBwbm1oOwoJCQlIRF9JVEVNIGl0ZW07CgoJCQljYWxjX3NpbmdsZV93aWR0aChwYW5lLCBwaGRuLT5pSXRlbSk7CgkJCWl0ZW0ubWFzayA9IEhESV9XSURUSDsKCQkJaXRlbS5jeHkgPSBwYW5lLT53aWR0aHNbcGhkbi0+aUl0ZW1dOwoKCQkJU2VuZE1lc3NhZ2UocGFuZS0+aHduZEhlYWRlciwgSERNX1NFVElURU0sIHBoZG4tPmlJdGVtLCAoTFBBUkFNKSAmaXRlbSk7CgkJCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoJCQlicmVhazt9Cgl9CgoJcmV0dXJuIDA7Cn0KCiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCnN0YXRpYyB2b2lkIHNjYW5fZW50cnkoQ2hpbGRXbmQqIGNoaWxkLCBFbnRyeSogZW50cnksIGludCBpZHgsIEhXTkQgaHduZCkKewoJVENIQVIgcGF0aFtNQVhfUEFUSF07CglIQ1VSU09SIG9sZF9jdXJzb3IgPSBTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfV0FJVCkpOwoKCS8qIGRlbGV0ZSBzdWIgZW50cmllcyBpbiBsZWZ0IHBhbmUgKi8KCWZvcig7OykgewoJCUxSRVNVTFQgcmVzID0gU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZCwgTEJfR0VUSVRFTURBVEEsIGlkeCsxLCAwKTsKCQlFbnRyeSogc3ViID0gKEVudHJ5KikgcmVzOwoKCQlpZiAocmVzPT1MQl9FUlIgfHwgIXN1YiB8fCBzdWItPmxldmVsPD1lbnRyeS0+bGV2ZWwpCgkJCWJyZWFrOwoKCQlTZW5kTWVzc2FnZShjaGlsZC0+bGVmdC5od25kLCBMQl9ERUxFVEVTVFJJTkcsIGlkeCsxLCAwKTsKCX0KCgkvKiBlbXB0eSByaWdodCBwYW5lICovCglTZW5kTWVzc2FnZShjaGlsZC0+cmlnaHQuaHduZCwgTEJfUkVTRVRDT05URU5ULCAwLCAwKTsKCgkvKiByZWxlYXNlIG1lbW9yeSAqLwoJZnJlZV9lbnRyaWVzKGVudHJ5KTsKCgkvKiByZWFkIGNvbnRlbnRzIGZyb20gZGlzayAqLwojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChlbnRyeS0+ZXR5cGUgPT0gRVRfU0hFTEwpCgl7CgkJcmVhZF9kaXJlY3RvcnkoZW50cnksIE5VTEwsIGNoaWxkLT5zb3J0T3JkZXIsIGh3bmQpOwoJfQoJZWxzZQojZW5kaWYKCXsKCQlnZXRfcGF0aChlbnRyeSwgcGF0aCk7CgkJcmVhZF9kaXJlY3RvcnkoZW50cnksIHBhdGgsIGNoaWxkLT5zb3J0T3JkZXIsIGh3bmQpOwoJfQoKCS8qIGluc2VydCBmb3VuZCBlbnRyaWVzIGluIHJpZ2h0IHBhbmUgKi8KCWluc2VydF9lbnRyaWVzKCZjaGlsZC0+cmlnaHQsIGVudHJ5LT5kb3duLCBjaGlsZC0+ZmlsdGVyX3BhdHRlcm4sIGNoaWxkLT5maWx0ZXJfZmxhZ3MsIC0xKTsKCWNhbGNfd2lkdGhzKCZjaGlsZC0+cmlnaHQsIEZBTFNFKTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJc2V0X2hlYWRlcigmY2hpbGQtPnJpZ2h0KTsKI2VuZGlmCgoJY2hpbGQtPmhlYWRlcl93ZHRoc19vayA9IEZBTFNFOwoKCVNldEN1cnNvcihvbGRfY3Vyc29yKTsKfQoKCi8qIGV4cGFuZCBhIGRpcmVjdG9yeSBlbnRyeSAqLwoKc3RhdGljIEJPT0wgZXhwYW5kX2VudHJ5KENoaWxkV25kKiBjaGlsZCwgRW50cnkqIGRpcikKewoJaW50IGlkeDsKCUVudHJ5KiBwOwoKCWlmICghZGlyIHx8IGRpci0+ZXhwYW5kZWQgfHwgIWRpci0+ZG93bikKCQlyZXR1cm4gRkFMU0U7CgoJcCA9IGRpci0+ZG93bjsKCglpZiAocC0+ZGF0YS5jRmlsZU5hbWVbMF09PScuJyAmJiBwLT5kYXRhLmNGaWxlTmFtZVsxXT09J1wwJyAmJiBwLT5uZXh0KSB7CgkJcCA9IHAtPm5leHQ7CgoJCWlmIChwLT5kYXRhLmNGaWxlTmFtZVswXT09Jy4nICYmIHAtPmRhdGEuY0ZpbGVOYW1lWzFdPT0nLicgJiYKCQkJCXAtPmRhdGEuY0ZpbGVOYW1lWzJdPT0nXDAnICYmIHAtPm5leHQpCgkJCXAgPSBwLT5uZXh0OwoJfQoKCS8qIG5vIHN1YmRpcmVjdG9yaWVzID8gKi8KCWlmICghKHAtPmRhdGEuZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpKQoJCXJldHVybiBGQUxTRTsKCglpZHggPSBTZW5kTWVzc2FnZShjaGlsZC0+bGVmdC5od25kLCBMQl9GSU5EU1RSSU5HLCAwLCAoTFBBUkFNKWRpcik7CgoJZGlyLT5leHBhbmRlZCA9IFRSVUU7CgoJLyogaW5zZXJ0IGVudHJpZXMgaW4gbGVmdCBwYW5lICovCglpbnNlcnRfZW50cmllcygmY2hpbGQtPmxlZnQsIHAsIE5VTEwsIFRGX0FMTCwgaWR4KTsKCglpZiAoIWNoaWxkLT5oZWFkZXJfd2R0aHNfb2spIHsKCQlpZiAoY2FsY193aWR0aHMoJmNoaWxkLT5sZWZ0LCBGQUxTRSkpIHsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQlzZXRfaGVhZGVyKCZjaGlsZC0+bGVmdCk7CiNlbmRpZgoKCQkJY2hpbGQtPmhlYWRlcl93ZHRoc19vayA9IFRSVUU7CgkJfQoJfQoKCXJldHVybiBUUlVFOwp9CgoKc3RhdGljIHZvaWQgY29sbGFwc2VfZW50cnkoUGFuZSogcGFuZSwgRW50cnkqIGRpcikKewoJaW50IGlkeCA9IFNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX0ZJTkRTVFJJTkcsIDAsIChMUEFSQU0pZGlyKTsKCglTaG93V2luZG93KHBhbmUtPmh3bmQsIFNXX0hJREUpOwoKCS8qIGhpZGUgc3ViIGVudHJpZXMgKi8KCWZvcig7OykgewoJCUxSRVNVTFQgcmVzID0gU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfR0VUSVRFTURBVEEsIGlkeCsxLCAwKTsKCQlFbnRyeSogc3ViID0gKEVudHJ5KikgcmVzOwoKCQlpZiAocmVzPT1MQl9FUlIgfHwgIXN1YiB8fCBzdWItPmxldmVsPD1kaXItPmxldmVsKQoJCQlicmVhazsKCgkJU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfREVMRVRFU1RSSU5HLCBpZHgrMSwgMCk7Cgl9CgoJZGlyLT5leHBhbmRlZCA9IEZBTFNFOwoKCVNob3dXaW5kb3cocGFuZS0+aHduZCwgU1dfU0hPVyk7Cn0KCgpzdGF0aWMgdm9pZCByZWZyZXNoX3JpZ2h0X3BhbmUoQ2hpbGRXbmQqIGNoaWxkKQp7CglTZW5kTWVzc2FnZShjaGlsZC0+cmlnaHQuaHduZCwgTEJfUkVTRVRDT05URU5ULCAwLCAwKTsKCWluc2VydF9lbnRyaWVzKCZjaGlsZC0+cmlnaHQsIGNoaWxkLT5yaWdodC5yb290LCBjaGlsZC0+ZmlsdGVyX3BhdHRlcm4sIGNoaWxkLT5maWx0ZXJfZmxhZ3MsIC0xKTsKCWNhbGNfd2lkdGhzKCZjaGlsZC0+cmlnaHQsIEZBTFNFKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCXNldF9oZWFkZXIoJmNoaWxkLT5yaWdodCk7CiNlbmRpZgp9CgpzdGF0aWMgdm9pZCBzZXRfY3VyZGlyKENoaWxkV25kKiBjaGlsZCwgRW50cnkqIGVudHJ5LCBpbnQgaWR4LCBIV05EIGh3bmQpCnsKCVRDSEFSIHBhdGhbTUFYX1BBVEhdOwoKCWlmICghZW50cnkpCgkJcmV0dXJuOwoKCXBhdGhbMF0gPSAnXDAnOwoKCWNoaWxkLT5sZWZ0LmN1ciA9IGVudHJ5OwoKCWNoaWxkLT5yaWdodC5yb290ID0gZW50cnktPmRvd24/IGVudHJ5LT5kb3duOiBlbnRyeTsKCWNoaWxkLT5yaWdodC5jdXIgPSBlbnRyeTsKCglpZiAoIWVudHJ5LT5zY2FubmVkKQoJCXNjYW5fZW50cnkoY2hpbGQsIGVudHJ5LCBpZHgsIGh3bmQpOwoJZWxzZQoJCXJlZnJlc2hfcmlnaHRfcGFuZShjaGlsZCk7CgoJZ2V0X3BhdGgoZW50cnksIHBhdGgpOwoJbHN0cmNweShjaGlsZC0+cGF0aCwgcGF0aCk7CgoJaWYgKGNoaWxkLT5od25kKQkvKiBvbmx5IGNoYW5nZSB3aW5kb3cgdGl0bGUsIGlmIHRoZSB3aW5kb3cgYWxyZWFkeSBleGlzdHMgKi8KCQlTZXRXaW5kb3dUZXh0KGNoaWxkLT5od25kLCBwYXRoKTsKCglpZiAocGF0aFswXSkKCQlpZiAoU2V0Q3VycmVudERpcmVjdG9yeShwYXRoKSkKCQkJc2V0X3NwYWNlX3N0YXR1cygpOwp9CgoKc3RhdGljIHZvaWQgcmVmcmVzaF9jaGlsZChDaGlsZFduZCogY2hpbGQpCnsKCVRDSEFSIHBhdGhbTUFYX1BBVEhdLCBkcnZbX01BWF9EUklWRSsxXTsKCUVudHJ5KiBlbnRyeTsKCWludCBpZHg7CgoJZ2V0X3BhdGgoY2hpbGQtPmxlZnQuY3VyLCBwYXRoKTsKCV90c3BsaXRwYXRoKHBhdGgsIGRydiwgTlVMTCwgTlVMTCwgTlVMTCk7CgoJY2hpbGQtPnJpZ2h0LnJvb3QgPSBOVUxMOwoKCXNjYW5fZW50cnkoY2hpbGQsICZjaGlsZC0+cm9vdC5lbnRyeSwgMCwgY2hpbGQtPmh3bmQpOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglpZiAoY2hpbGQtPnJvb3QuZW50cnkuZXR5cGUgPT0gRVRfU0hFTEwpCgkJZW50cnkgPSByZWFkX3RyZWUoJmNoaWxkLT5yb290LCBOVUxMLCBnZXRfcGF0aF9waWRsKHBhdGgsY2hpbGQtPmh3bmQpLCBkcnYsIGNoaWxkLT5zb3J0T3JkZXIsIGNoaWxkLT5od25kKTsKCWVsc2UKI2VuZGlmCgkJZW50cnkgPSByZWFkX3RyZWUoJmNoaWxkLT5yb290LCBwYXRoLCBOVUxMLCBkcnYsIGNoaWxkLT5zb3J0T3JkZXIsIGNoaWxkLT5od25kKTsKCglpZiAoIWVudHJ5KQoJCWVudHJ5ID0gJmNoaWxkLT5yb290LmVudHJ5OwoKCWluc2VydF9lbnRyaWVzKCZjaGlsZC0+bGVmdCwgY2hpbGQtPnJvb3QuZW50cnkuZG93biwgTlVMTCwgVEZfQUxMLCAwKTsKCglzZXRfY3VyZGlyKGNoaWxkLCBlbnRyeSwgMCwgY2hpbGQtPmh3bmQpOwoKCWlkeCA9IFNlbmRNZXNzYWdlKGNoaWxkLT5sZWZ0Lmh3bmQsIExCX0ZJTkRTVFJJTkcsIDAsIChMUEFSQU0pY2hpbGQtPmxlZnQuY3VyKTsKCVNlbmRNZXNzYWdlKGNoaWxkLT5sZWZ0Lmh3bmQsIExCX1NFVENVUlNFTCwgaWR4LCAwKTsKfQoKCnN0YXRpYyB2b2lkIGNyZWF0ZV9kcml2ZV9iYXIodm9pZCkKewoJVEJCVVRUT04gZHJpdmViYXJCdG4gPSB7MCwgMCwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJVENIQVIgYjFbQlVGRkVSX0xFTl07CiNlbmRpZgoJaW50IGJ0biA9IDE7CglQVFNUUiBwOwoKCUdldExvZ2ljYWxEcml2ZVN0cmluZ3MoQlVGRkVSX0xFTiwgR2xvYmFscy5kcml2ZXMpOwoKCUdsb2JhbHMuaGRyaXZlYmFyID0gQ3JlYXRlVG9vbGJhckV4KEdsb2JhbHMuaE1haW5XbmQsIFdTX0NISUxEfFdTX1ZJU0lCTEV8Q0NTX05PTU9WRVl8VEJTVFlMRV9MSVNULAoJCQkJSURXX0RSSVZFQkFSLCAyLCBHbG9iYWxzLmhJbnN0YW5jZSwgSURCX0RSSVZFQkFSLCAmZHJpdmViYXJCdG4sCgkJCQkwLCAxNiwgMTMsIDE2LCAxMywgc2l6ZW9mKFRCQlVUVE9OKSk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCiNpZmRlZiBfX1dJTkVfXwoJLyogaW5zZXJ0IHVuaXggZmlsZSBzeXN0ZW0gYnV0dG9uICovCgliMVswXSA9ICcvJzsKCWIxWzFdID0gJ1wwJzsKCWIxWzJdID0gJ1wwJzsKCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9BRERTVFJJTkcsIDAsIChMUEFSQU0pYjEpOwoKCWRyaXZlYmFyQnRuLmlkQ29tbWFuZCA9IElEX0RSSVZFX1VOSVhfRlM7CglTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfSU5TRVJUQlVUVE9OLCBidG4rKywgKExQQVJBTSkmZHJpdmViYXJCdG4pOwoJZHJpdmViYXJCdG4uaVN0cmluZysrOwojZW5kaWYKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgkvKiBpbnNlcnQgc2hlbGwgbmFtZXNwYWNlIGJ1dHRvbiAqLwoJbG9hZF9zdHJpbmcoYjEsIElEU19TSEVMTCk7CgliMVtsc3RybGVuKGIxKSsxXSA9ICdcMCc7CglTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfQUREU1RSSU5HLCAwLCAoTFBBUkFNKWIxKTsKCglkcml2ZWJhckJ0bi5pZENvbW1hbmQgPSBJRF9EUklWRV9TSEVMTF9OUzsKCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9JTlNFUlRCVVRUT04sIGJ0bisrLCAoTFBBUkFNKSZkcml2ZWJhckJ0bik7Cglkcml2ZWJhckJ0bi5pU3RyaW5nKys7CiNlbmRpZgoKCS8qIHJlZ2lzdGVyIHdpbmRvd3MgZHJpdmUgcm9vdCBzdHJpbmdzICovCglTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfQUREU1RSSU5HLCAwLCAoTFBBUkFNKUdsb2JhbHMuZHJpdmVzKTsKI2VuZGlmCgoJZHJpdmViYXJCdG4uaWRDb21tYW5kID0gSURfRFJJVkVfRklSU1Q7CgoJZm9yKHA9R2xvYmFscy5kcml2ZXM7ICpwOyApIHsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJLyogaW5zZXJ0IGRyaXZlIGxldHRlciAqLwoJCVRDSEFSIGJbM10gPSB7dG9sb3dlcigqcCl9OwoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9BRERTVFJJTkcsIDAsIChMUEFSQU0pYik7CiNlbmRpZgoJCXN3aXRjaChHZXREcml2ZVR5cGUocCkpIHsKCQkJY2FzZSBEUklWRV9SRU1PVkFCTEU6CWRyaXZlYmFyQnRuLmlCaXRtYXAgPSAxOwlicmVhazsKCQkJY2FzZSBEUklWRV9DRFJPTToJCWRyaXZlYmFyQnRuLmlCaXRtYXAgPSAzOwlicmVhazsKCQkJY2FzZSBEUklWRV9SRU1PVEU6CQlkcml2ZWJhckJ0bi5pQml0bWFwID0gNDsJYnJlYWs7CgkJCWNhc2UgRFJJVkVfUkFNRElTSzoJCWRyaXZlYmFyQnRuLmlCaXRtYXAgPSA1OwlicmVhazsKCQkJZGVmYXVsdDovKkRSSVZFX0ZJWEVEKi8JZHJpdmViYXJCdG4uaUJpdG1hcCA9IDI7CgkJfQoKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfSU5TRVJUQlVUVE9OLCBidG4rKywgKExQQVJBTSkmZHJpdmViYXJCdG4pOwoJCWRyaXZlYmFyQnRuLmlkQ29tbWFuZCsrOwoJCWRyaXZlYmFyQnRuLmlTdHJpbmcrKzsKCgkJd2hpbGUoKnArKyk7Cgl9Cn0KCnN0YXRpYyB2b2lkIHJlZnJlc2hfZHJpdmVzKHZvaWQpCnsKCVJFQ1QgcmVjdDsKCgkvKiBkZXN0cm95IGRyaXZlIGJhciAqLwoJRGVzdHJveVdpbmRvdyhHbG9iYWxzLmhkcml2ZWJhcik7CglHbG9iYWxzLmhkcml2ZWJhciA9IDA7CgoJLyogcmUtY3JlYXRlIGRyaXZlIGJhciAqLwoJY3JlYXRlX2RyaXZlX2JhcigpOwoKCS8qIHVwZGF0ZSB3aW5kb3cgbGF5b3V0ICovCglHZXRDbGllbnRSZWN0KEdsb2JhbHMuaE1haW5XbmQsICZyZWN0KTsKCVNlbmRNZXNzYWdlKEdsb2JhbHMuaE1haW5XbmQsIFdNX1NJWkUsIDAsIE1BS0VMT05HKHJlY3QucmlnaHQsIHJlY3QuYm90dG9tKSk7Cn0KCgpzdGF0aWMgQk9PTCBsYXVuY2hfZmlsZShIV05EIGh3bmQsIExQQ1RTVFIgY21kLCBVSU5UIG5DbWRTaG93KQp7CglISU5TVEFOQ0UgaGluc3QgPSBTaGVsbEV4ZWN1dGUoaHduZCwgTlVMTC8qb3BlcmF0aW9uKi8sIGNtZCwgTlVMTC8qcGFyYW1ldGVycyovLCBOVUxMLypkaXIqLywgbkNtZFNob3cpOwoKCWlmIChQdHJUb1Vsb25nKGhpbnN0KSA8PSAzMikgewoJCWRpc3BsYXlfZXJyb3IoaHduZCwgR2V0TGFzdEVycm9yKCkpOwoJCXJldHVybiBGQUxTRTsKCX0KCglyZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyBCT09MIGxhdW5jaF9lbnRyeShFbnRyeSogZW50cnksIEhXTkQgaHduZCwgVUlOVCBuQ21kU2hvdykKewoJVENIQVIgY21kW01BWF9QQVRIXTsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGVudHJ5LT5ldHlwZSA9PSBFVF9TSEVMTCkgewoJCUJPT0wgcmV0ID0gVFJVRTsKCgkJU0hFTExFWEVDVVRFSU5GTyBzaGV4aW5mbzsKCgkJc2hleGluZm8uY2JTaXplID0gc2l6ZW9mKFNIRUxMRVhFQ1VURUlORk8pOwoJCXNoZXhpbmZvLmZNYXNrID0gU0VFX01BU0tfSURMSVNUOwoJCXNoZXhpbmZvLmh3bmQgPSBod25kOwoJCXNoZXhpbmZvLmxwVmVyYiA9IE5VTEw7CgkJc2hleGluZm8ubHBGaWxlID0gTlVMTDsKCQlzaGV4aW5mby5scFBhcmFtZXRlcnMgPSBOVUxMOwoJCXNoZXhpbmZvLmxwRGlyZWN0b3J5ID0gTlVMTDsKCQlzaGV4aW5mby5uU2hvdyA9IG5DbWRTaG93OwoJCXNoZXhpbmZvLmxwSURMaXN0ID0gZ2V0X3RvX2Fic29sdXRlX3BpZGwoZW50cnksIGh3bmQpOwoKCQlpZiAoIVNoZWxsRXhlY3V0ZUV4KCZzaGV4aW5mbykpIHsKCQkJZGlzcGxheV9lcnJvcihod25kLCBHZXRMYXN0RXJyb3IoKSk7CgkJCXJldCA9IEZBTFNFOwoJCX0KCgkJaWYgKHNoZXhpbmZvLmxwSURMaXN0ICE9IGVudHJ5LT5waWRsKQoJCQlJTWFsbG9jX0ZyZWUoR2xvYmFscy5pTWFsbG9jLCBzaGV4aW5mby5scElETGlzdCk7CgoJCXJldHVybiByZXQ7Cgl9CiNlbmRpZgoKCWdldF9wYXRoKGVudHJ5LCBjbWQpOwoKCSAvKiBzdGFydCBwcm9ncmFtLCBvcGVuIGRvY3VtZW50Li4uICovCglyZXR1cm4gbGF1bmNoX2ZpbGUoaHduZCwgY21kLCBuQ21kU2hvdyk7Cn0KCgpzdGF0aWMgdm9pZCBhY3RpdmF0ZV9lbnRyeShDaGlsZFduZCogY2hpbGQsIFBhbmUqIHBhbmUsIEhXTkQgaHduZCkKewoJRW50cnkqIGVudHJ5ID0gcGFuZS0+Y3VyOwoKCWlmICghZW50cnkpCgkJcmV0dXJuOwoKCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJaW50IHNjYW5uZWRfb2xkID0gZW50cnktPnNjYW5uZWQ7CgoJCWlmICghc2Nhbm5lZF9vbGQpCgkJewoJCQlpbnQgaWR4ID0gU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZCwgTEJfR0VUQ1VSU0VMLCAwLCAwKTsKCQkJc2Nhbl9lbnRyeShjaGlsZCwgZW50cnksIGlkeCwgaHduZCk7CgkJfQoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWlmIChlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF09PScuJyAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMV09PSdcMCcpCgkJCXJldHVybjsKI2VuZGlmCgoJCWlmIChlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF09PScuJyAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMV09PScuJyAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMl09PSdcMCcpIHsKCQkJZW50cnkgPSBjaGlsZC0+bGVmdC5jdXItPnVwOwoJCQljb2xsYXBzZV9lbnRyeSgmY2hpbGQtPmxlZnQsIGVudHJ5KTsKCQkJZ290byBmb2N1c19lbnRyeTsKCQl9IGVsc2UgaWYgKGVudHJ5LT5leHBhbmRlZCkKCQkJY29sbGFwc2VfZW50cnkocGFuZSwgY2hpbGQtPmxlZnQuY3VyKTsKCQllbHNlIHsKCQkJZXhwYW5kX2VudHJ5KGNoaWxkLCBjaGlsZC0+bGVmdC5jdXIpOwoKCQkJaWYgKCFwYW5lLT50cmVlUGFuZSkgZm9jdXNfZW50cnk6IHsKCQkJCWludCBpZHhzdGFydCA9IFNlbmRNZXNzYWdlKGNoaWxkLT5sZWZ0Lmh3bmQsIExCX0dFVENVUlNFTCwgMCwgMCk7CgkJCQlpbnQgaWR4ID0gU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZCwgTEJfRklORFNUUklORywgaWR4c3RhcnQsIChMUEFSQU0pZW50cnkpOwoJCQkJU2VuZE1lc3NhZ2UoY2hpbGQtPmxlZnQuaHduZCwgTEJfU0VUQ1VSU0VMLCBpZHgsIDApOwoJCQkJc2V0X2N1cmRpcihjaGlsZCwgZW50cnksIGlkeCwgaHduZCk7CgkJCX0KCQl9CgoJCWlmICghc2Nhbm5lZF9vbGQpIHsKCQkJY2FsY193aWR0aHMocGFuZSwgRkFMU0UpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQlzZXRfaGVhZGVyKHBhbmUpOwojZW5kaWYKCQl9Cgl9IGVsc2UgewoJCWlmIChHZXRLZXlTdGF0ZShWS19NRU5VKSA8IDApCgkJCXNob3dfcHJvcGVydGllc19kbGcoZW50cnksIGNoaWxkLT5od25kKTsKCQllbHNlCgkJCWxhdW5jaF9lbnRyeShlbnRyeSwgY2hpbGQtPmh3bmQsIFNXX1NIT1dOT1JNQUwpOwoJfQp9CgoKc3RhdGljIEJPT0wgcGFuZV9jb21tYW5kKFBhbmUqIHBhbmUsIFVJTlQgY21kKQp7Cglzd2l0Y2goY21kKSB7CgkJY2FzZSBJRF9WSUVXX05BTUU6CgkJCWlmIChwYW5lLT52aXNpYmxlX2NvbHMpIHsKCQkJCXBhbmUtPnZpc2libGVfY29scyA9IDA7CgkJCQljYWxjX3dpZHRocyhwYW5lLCBUUlVFKTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJc2V0X2hlYWRlcihwYW5lKTsKI2VuZGlmCgkJCQlJbnZhbGlkYXRlUmVjdChwYW5lLT5od25kLCAwLCBUUlVFKTsKCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfTkFNRSwgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19BTExfQVRUUklCVVRFUywgTUZfQllDT01NQU5EKTsKCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfU0VMRUNURURfQVRUUklCVVRFUywgTUZfQllDT01NQU5EKTsKCQkJfQoJCQlicmVhazsKCgkJY2FzZSBJRF9WSUVXX0FMTF9BVFRSSUJVVEVTOgoJCQlpZiAocGFuZS0+dmlzaWJsZV9jb2xzICE9IENPTF9BTEwpIHsKCQkJCXBhbmUtPnZpc2libGVfY29scyA9IENPTF9BTEw7CgkJCQljYWxjX3dpZHRocyhwYW5lLCBUUlVFKTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJc2V0X2hlYWRlcihwYW5lKTsKI2VuZGlmCgkJCQlJbnZhbGlkYXRlUmVjdChwYW5lLT5od25kLCAwLCBUUlVFKTsKCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfTkFNRSwgTUZfQllDT01NQU5EKTsKCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfQUxMX0FUVFJJQlVURVMsIE1GX0JZQ09NTUFORHxNRl9DSEVDS0VEKTsKCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfU0VMRUNURURfQVRUUklCVVRFUywgTUZfQllDT01NQU5EKTsKCQkJfQoJCQlicmVhazsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQljYXNlIElEX1BSRUZFUlJFRF9TSVpFUzogewoJCQljYWxjX3dpZHRocyhwYW5lLCBUUlVFKTsKCQkJc2V0X2hlYWRlcihwYW5lKTsKCQkJSW52YWxpZGF0ZVJlY3QocGFuZS0+aHduZCwgMCwgVFJVRSk7CgkJCWJyZWFrO30KI2VuZGlmCgoJCSAgICAgICAgLyogVE9ETzogbW9yZSBjb21tYW5kIGlkcy4uLiAqLwoKCQlkZWZhdWx0OgoJCQlyZXR1cm4gRkFMU0U7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCgpzdGF0aWMgdm9pZCBzZXRfc29ydF9vcmRlcihDaGlsZFduZCogY2hpbGQsIFNPUlRfT1JERVIgc29ydE9yZGVyKQp7CglpZiAoY2hpbGQtPnNvcnRPcmRlciAhPSBzb3J0T3JkZXIpIHsKCQljaGlsZC0+c29ydE9yZGVyID0gc29ydE9yZGVyOwoJCXJlZnJlc2hfY2hpbGQoY2hpbGQpOwoJfQp9CgpzdGF0aWMgdm9pZCB1cGRhdGVfdmlld19tZW51KENoaWxkV25kKiBjaGlsZCkKewoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19TT1JUX05BTUUsIGNoaWxkLT5zb3J0T3JkZXI9PVNPUlRfTkFNRT8gTUZfQ0hFQ0tFRDogTUZfVU5DSEVDS0VEKTsKCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfU09SVF9UWVBFLCBjaGlsZC0+c29ydE9yZGVyPT1TT1JUX0VYVD8gTUZfQ0hFQ0tFRDogTUZfVU5DSEVDS0VEKTsKCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfU09SVF9TSVpFLCBjaGlsZC0+c29ydE9yZGVyPT1TT1JUX1NJWkU/IE1GX0NIRUNLRUQ6IE1GX1VOQ0hFQ0tFRCk7CglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX1NPUlRfREFURSwgY2hpbGQtPnNvcnRPcmRlcj09U09SVF9EQVRFPyBNRl9DSEVDS0VEOiBNRl9VTkNIRUNLRUQpOwp9CgoKc3RhdGljIEJPT0wgaXNfZGlyZWN0b3J5KExQQ1RTVFIgdGFyZ2V0KQp7CgkvKlRPRE8gY29ycmVjdGx5IGhhbmRsZSBVTklYIHBhdGhzICovCglEV09SRCB0YXJnZXRfYXR0ciA9IEdldEZpbGVBdHRyaWJ1dGVzKHRhcmdldCk7CgoJaWYgKHRhcmdldF9hdHRyID09IElOVkFMSURfRklMRV9BVFRSSUJVVEVTKQoJCXJldHVybiBGQUxTRTsKCglyZXR1cm4gdGFyZ2V0X2F0dHImRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZPyBUUlVFOiBGQUxTRTsKfQoJCnN0YXRpYyBCT09MIHByb21wdF90YXJnZXQoUGFuZSogcGFuZSwgTFBUU1RSIHNvdXJjZSwgTFBUU1RSIHRhcmdldCkKewoJVENIQVIgcGF0aFtNQVhfUEFUSF07CglpbnQgbGVuOwoKCWdldF9wYXRoKHBhbmUtPmN1ciwgcGF0aCk7CgoJaWYgKERpYWxvZ0JveFBhcmFtKEdsb2JhbHMuaEluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSUREX1NFTEVDVF9ERVNUSU5BVElPTiksIHBhbmUtPmh3bmQsIERlc3RpbmF0aW9uRGxnUHJvYywgKExQQVJBTSlwYXRoKSAhPSBJRE9LKQoJCXJldHVybiBGQUxTRTsKCglnZXRfcGF0aChwYW5lLT5jdXIsIHNvdXJjZSk7CgoJLyogY29udmVydCByZWxhdGl2ZSB0YXJnZXRzIHRvIGFic29sdXRlIHBhdGhzICovCglpZiAocGF0aFswXSE9Jy8nICYmIHBhdGhbMV0hPSc6JykgewoJCWdldF9wYXRoKHBhbmUtPmN1ci0+dXAsIHRhcmdldCk7CgkJbGVuID0gbHN0cmxlbih0YXJnZXQpOwoKCQlpZiAodGFyZ2V0W2xlbi0xXSE9J1xcJyAmJiB0YXJnZXRbbGVuLTFdIT0nLycpCgkJCXRhcmdldFtsZW4rK10gPSAnLyc7CgoJCWxzdHJjcHkodGFyZ2V0K2xlbiwgcGF0aCk7Cgl9IGVsc2UKCQlsc3RyY3B5KHRhcmdldCwgcGF0aCk7CgoJLyogSWYgdGhlIHRhcmdldCBhbHJlYWR5IGV4aXN0cyBhcyBkaXJlY3RvcnksIGNyZWF0ZSBhIG5ldyB0YXJnZXQgYmVsb3cgdGhpcy4gKi8KCWlmIChpc19kaXJlY3RvcnkocGF0aCkpIHsKCQlUQ0hBUiBmbmFtZVtfTUFYX0ZOQU1FXSwgZXh0W19NQVhfRVhUXTsKCQlzdGF0aWMgY29uc3QgVENIQVIgc0FwcGVuZFtdID0geyclJywncycsJy8nLCclJywncycsJyUnLCdzJywnXDAnfTsKCgkJX3RzcGxpdHBhdGgoc291cmNlLCBOVUxMLCBOVUxMLCBmbmFtZSwgZXh0KTsKCgkJd3NwcmludGYodGFyZ2V0LCBzQXBwZW5kLCBwYXRoLCBmbmFtZSwgZXh0KTsKCX0KCglyZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyBJQ29udGV4dE1lbnUyKiBzX3BjdHhtZW51MiA9IE5VTEw7CnN0YXRpYyBJQ29udGV4dE1lbnUzKiBzX3BjdHhtZW51MyA9IE5VTEw7CgpzdGF0aWMgdm9pZCBDdHhNZW51X3Jlc2V0KHZvaWQpCnsKCXNfcGN0eG1lbnUyID0gTlVMTDsKCXNfcGN0eG1lbnUzID0gTlVMTDsKfQoKc3RhdGljIElDb250ZXh0TWVudSogQ3R4TWVudV9xdWVyeV9pbnRlcmZhY2VzKElDb250ZXh0TWVudSogcGNtMSkKewoJSUNvbnRleHRNZW51KiBwY20gPSBOVUxMOwoKCUN0eE1lbnVfcmVzZXQoKTsKCglpZiAoSUNvbnRleHRNZW51X1F1ZXJ5SW50ZXJmYWNlKHBjbTEsICZJSURfSUNvbnRleHRNZW51MywgKHZvaWQqKikmcGNtKSA9PSBOT0VSUk9SKQoJCXNfcGN0eG1lbnUzID0gKExQQ09OVEVYVE1FTlUzKXBjbTsKCWVsc2UgaWYgKElDb250ZXh0TWVudV9RdWVyeUludGVyZmFjZShwY20xLCAmSUlEX0lDb250ZXh0TWVudTIsICh2b2lkKiopJnBjbSkgPT0gTk9FUlJPUikKCQlzX3BjdHhtZW51MiA9IChMUENPTlRFWFRNRU5VMilwY207CgoJaWYgKHBjbSkgewoJCUlDb250ZXh0TWVudV9SZWxlYXNlKHBjbTEpOwoJCXJldHVybiBwY207Cgl9IGVsc2UKCQlyZXR1cm4gcGNtMTsKfQoKc3RhdGljIEJPT0wgQ3R4TWVudV9IYW5kbGVNZW51TXNnKFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJaWYgKHNfcGN0eG1lbnUzKSB7CgkJaWYgKFNVQ0NFRURFRChJQ29udGV4dE1lbnUzX0hhbmRsZU1lbnVNc2coc19wY3R4bWVudTMsIG5tc2csIHdwYXJhbSwgbHBhcmFtKSkpCgkJCXJldHVybiBUUlVFOwoJfQoKCWlmIChzX3BjdHhtZW51MikKCQlpZiAoU1VDQ0VFREVEKElDb250ZXh0TWVudTJfSGFuZGxlTWVudU1zZyhzX3BjdHhtZW51Miwgbm1zZywgd3BhcmFtLCBscGFyYW0pKSkKCQkJcmV0dXJuIFRSVUU7CgoJcmV0dXJuIEZBTFNFOwp9CgoKc3RhdGljIEhSRVNVTFQgU2hlbGxGb2xkZXJDb250ZXh0TWVudShJU2hlbGxGb2xkZXIqIHNoZWxsX2ZvbGRlciwgSFdORCBod25kUGFyZW50LCBpbnQgY2lkbCwgTFBDSVRFTUlETElTVCogYXBpZGwsIGludCB4LCBpbnQgeSkKewoJSUNvbnRleHRNZW51KiBwY207CglCT09MIGV4ZWN1dGVkID0gRkFMU0U7CgoJSFJFU1VMVCBociA9IElTaGVsbEZvbGRlcl9HZXRVSU9iamVjdE9mKHNoZWxsX2ZvbGRlciwgaHduZFBhcmVudCwgY2lkbCwgYXBpZGwsICZJSURfSUNvbnRleHRNZW51LCBOVUxMLCAoTFBWT0lEKikmcGNtKTsKLyoJSFJFU1VMVCBociA9IENEZWZGb2xkZXJNZW51X0NyZWF0ZTIoZGlyP2Rpci0+X3BpZGw6RGVza3RvcEZvbGRlcigpLCBod25kUGFyZW50LCAxLCAmcGlkbCwgc2hlbGxfZm9sZGVyLCBOVUxMLCAwLCBOVUxMLCAmcGNtKTsgKi8KCglpZiAoU1VDQ0VFREVEKGhyKSkgewoJCUhNRU5VIGhtZW51ID0gQ3JlYXRlUG9wdXBNZW51KCk7CgoJCXBjbSA9IEN0eE1lbnVfcXVlcnlfaW50ZXJmYWNlcyhwY20pOwoKCQlpZiAoaG1lbnUpIHsKCQkJaHIgPSBJQ29udGV4dE1lbnVfUXVlcnlDb250ZXh0TWVudShwY20sIGhtZW51LCAwLCBGQ0lETV9TSFZJRVdGSVJTVCwgRkNJRE1fU0hWSUVXTEFTVCwgQ01GX05PUk1BTCk7CgoJCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQkJVUlOVCBpZENtZCA9IFRyYWNrUG9wdXBNZW51KGhtZW51LCBUUE1fTEVGVEFMSUdOfFRQTV9SRVRVUk5DTUR8VFBNX1JJR0hUQlVUVE9OLCB4LCB5LCAwLCBod25kUGFyZW50LCBOVUxMKTsKCgkJCQlDdHhNZW51X3Jlc2V0KCk7CgoJCQkJaWYgKGlkQ21kKSB7CgkJCQkgIENNSU5WT0tFQ09NTUFORElORk8gY21pOwoKCQkJCSAgY21pLmNiU2l6ZSA9IHNpemVvZihDTUlOVk9LRUNPTU1BTkRJTkZPKTsKCQkJCSAgY21pLmZNYXNrID0gMDsKCQkJCSAgY21pLmh3bmQgPSBod25kUGFyZW50OwoJCQkJICBjbWkubHBWZXJiID0gKExQQ1NUUikoSU5UX1BUUikoaWRDbWQgLSBGQ0lETV9TSFZJRVdGSVJTVCk7CgkJCQkgIGNtaS5scFBhcmFtZXRlcnMgPSBOVUxMOwoJCQkJICBjbWkubHBEaXJlY3RvcnkgPSBOVUxMOwoJCQkJICBjbWkublNob3cgPSBTV19TSE9XTk9STUFMOwoJCQkJICBjbWkuZHdIb3RLZXkgPSAwOwoJCQkJICBjbWkuaEljb24gPSAwOwoKCQkJCSAgaHIgPSBJQ29udGV4dE1lbnVfSW52b2tlQ29tbWFuZChwY20sICZjbWkpOwoJCQkJCWV4ZWN1dGVkID0gVFJVRTsKCQkJCX0KCQkJfSBlbHNlCgkJCQlDdHhNZW51X3Jlc2V0KCk7CgkJfQoKCQlJQ29udGV4dE1lbnVfUmVsZWFzZShwY20pOwoJfQoKCXJldHVybiBGQUlMRUQoaHIpPyBocjogZXhlY3V0ZWQ/IFNfT0s6IFNfRkFMU0U7Cn0KCgpzdGF0aWMgTFJFU1VMVCBDQUxMQkFDSyBDaGlsZFduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCUNoaWxkV25kKiBjaGlsZCA9IChDaGlsZFduZCopIEdldFdpbmRvd0xvbmdQdHIoaHduZCwgR1dMUF9VU0VSREFUQSk7CglBU1NFUlQoY2hpbGQpOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9EUkFXSVRFTTogewoJCQlMUERSQVdJVEVNU1RSVUNUIGRpcyA9IChMUERSQVdJVEVNU1RSVUNUKWxwYXJhbTsKCQkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgZGlzLT5pdGVtRGF0YTsKCgkJCWlmIChkaXMtPkN0bElEID09IElEV19UUkVFX0xFRlQpCgkJCQlkcmF3X2l0ZW0oJmNoaWxkLT5sZWZ0LCBkaXMsIGVudHJ5LCAtMSk7CgkJCWVsc2UgaWYgKGRpcy0+Q3RsSUQgPT0gSURXX1RSRUVfUklHSFQpCgkJCQlkcmF3X2l0ZW0oJmNoaWxkLT5yaWdodCwgZGlzLCBlbnRyeSwgLTEpOwoJCQllbHNlCgkJCQlnb3RvIGRyYXdfbWVudV9pdGVtOwoKCQkJcmV0dXJuIFRSVUU7fQoKCQljYXNlIFdNX0NSRUFURToKCQkJSW5pdENoaWxkV2luZG93KGNoaWxkKTsKCQkJYnJlYWs7CgoJCWNhc2UgV01fTkNERVNUUk9ZOgoJCQlmcmVlX2NoaWxkX3dpbmRvdyhjaGlsZCk7CgkJCVNldFdpbmRvd0xvbmdQdHIoaHduZCwgR1dMUF9VU0VSREFUQSwgMCk7CgkJCWJyZWFrOwoKCQljYXNlIFdNX1BBSU5UOiB7CgkJCVBBSU5UU1RSVUNUIHBzOwoJCQlIQlJVU0ggbGFzdEJydXNoOwoJCQlSRUNUIHJ0OwoJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgkJCUJlZ2luUGFpbnQoaHduZCwgJnBzKTsKCQkJcnQubGVmdCA9IGNoaWxkLT5zcGxpdF9wb3MtU1BMSVRfV0lEVEgvMjsKCQkJcnQucmlnaHQgPSBjaGlsZC0+c3BsaXRfcG9zK1NQTElUX1dJRFRILzIrMTsKCQkJbGFzdEJydXNoID0gU2VsZWN0T2JqZWN0KHBzLmhkYywgR2V0U3RvY2tPYmplY3QoQ09MT1JfU1BMSVRCQVIpKTsKCQkJUmVjdGFuZ2xlKHBzLmhkYywgcnQubGVmdCwgcnQudG9wLTEsIHJ0LnJpZ2h0LCBydC5ib3R0b20rMSk7CgkJCVNlbGVjdE9iamVjdChwcy5oZGMsIGxhc3RCcnVzaCk7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQlydC50b3AgPSBydC5ib3R0b20gLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7CgkJCUZpbGxSZWN0KHBzLmhkYywgJnJ0LCBHZXRTdG9ja09iamVjdChCTEFDS19CUlVTSCkpOwojZW5kaWYKCQkJRW5kUGFpbnQoaHduZCwgJnBzKTsKCQkJYnJlYWs7fQoKCQljYXNlIFdNX1NFVENVUlNPUjoKCQkJaWYgKExPV09SRChscGFyYW0pID09IEhUQ0xJRU5UKSB7CgkJCQlQT0lOVCBwdDsKCQkJCUdldEN1cnNvclBvcygmcHQpOwoJCQkJU2NyZWVuVG9DbGllbnQoaHduZCwgJnB0KTsKCgkJCQlpZiAocHQueD49Y2hpbGQtPnNwbGl0X3Bvcy1TUExJVF9XSURUSC8yICYmIHB0Lng8Y2hpbGQtPnNwbGl0X3BvcytTUExJVF9XSURUSC8yKzEpIHsKCQkJCQlTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfU0laRVdFKSk7CgkJCQkJcmV0dXJuIFRSVUU7CgkJCQl9CgkJCX0KCQkJZ290byBkZWY7CgoJCWNhc2UgV01fTEJVVFRPTkRPV046IHsKCQkJUkVDVCBydDsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IHggPSAoc2hvcnQpTE9XT1JEKGxwYXJhbSk7CgoJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJCQlpZiAoeD49Y2hpbGQtPnNwbGl0X3Bvcy1TUExJVF9XSURUSC8yICYmIHg8Y2hpbGQtPnNwbGl0X3BvcytTUExJVF9XSURUSC8yKzEpIHsKCQkJCWxhc3Rfc3BsaXQgPSBjaGlsZC0+c3BsaXRfcG9zOwojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CiNlbmRpZgoJCQkJU2V0Q2FwdHVyZShod25kKTsKCQkJfQoKCQkJYnJlYWs7fQoKCQljYXNlIFdNX0xCVVRUT05VUDoKCQkJaWYgKEdldENhcHR1cmUoKSA9PSBod25kKSB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJUkVDVCBydDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgeCA9IChzaG9ydClMT1dPUkQobHBhcmFtKTsKCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CgkJCQlsYXN0X3NwbGl0ID0gLTE7CgkJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgkJCQljaGlsZC0+c3BsaXRfcG9zID0geDsKCQkJCXJlc2l6ZV90cmVlKGNoaWxkLCBydC5yaWdodCwgcnQuYm90dG9tKTsKI2VuZGlmCgkJCQlSZWxlYXNlQ2FwdHVyZSgpOwoJCQl9CgkJCWJyZWFrOwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJY2FzZSBXTV9DQVBUVVJFQ0hBTkdFRDoKCQkJaWYgKEdldENhcHR1cmUoKT09aHduZCAmJiBsYXN0X3NwbGl0Pj0wKQoJCQkJZHJhd19zcGxpdGJhcihod25kLCBsYXN0X3NwbGl0KTsKCQkJYnJlYWs7CiNlbmRpZgoKCQljYXNlIFdNX0tFWURPV046CgkJCWlmICh3cGFyYW0gPT0gVktfRVNDQVBFKQoJCQkJaWYgKEdldENhcHR1cmUoKSA9PSBod25kKSB7CgkJCQkJUkVDVCBydDsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQkJZHJhd19zcGxpdGJhcihod25kLCBsYXN0X3NwbGl0KTsKI2Vsc2UKCQkJCQljaGlsZC0+c3BsaXRfcG9zID0gbGFzdF9zcGxpdDsKI2VuZGlmCgkJCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoJCQkJCXJlc2l6ZV90cmVlKGNoaWxkLCBydC5yaWdodCwgcnQuYm90dG9tKTsKCQkJCQlsYXN0X3NwbGl0ID0gLTE7CgkJCQkJUmVsZWFzZUNhcHR1cmUoKTsKCQkJCQlTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfQVJST1cpKTsKCQkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgV01fTU9VU0VNT1ZFOgoJCQlpZiAoR2V0Q2FwdHVyZSgpID09IGh3bmQpIHsKCQkJCVJFQ1QgcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHggPSAoc2hvcnQpTE9XT1JEKGxwYXJhbSk7CgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJCUhEQyBoZGMgPSBHZXREQyhod25kKTsKCQkJCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCgkJCQlydC5sZWZ0ID0gbGFzdF9zcGxpdC1TUExJVF9XSURUSC8yOwoJCQkJcnQucmlnaHQgPSBsYXN0X3NwbGl0K1NQTElUX1dJRFRILzIrMTsKCQkJCUludmVydFJlY3QoaGRjLCAmcnQpOwoKCQkJCWxhc3Rfc3BsaXQgPSB4OwoJCQkJcnQubGVmdCA9IHgtU1BMSVRfV0lEVEgvMjsKCQkJCXJ0LnJpZ2h0ID0geCtTUExJVF9XSURUSC8yKzE7CgkJCQlJbnZlcnRSZWN0KGhkYywgJnJ0KTsKCgkJCQlSZWxlYXNlREMoaHduZCwgaGRjKTsKI2Vsc2UKCQkJCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCgkJCQlpZiAoeD49MCAmJiB4PHJ0LnJpZ2h0KSB7CgkJCQkJY2hpbGQtPnNwbGl0X3BvcyA9IHg7CgkJCQkJcmVzaXplX3RyZWUoY2hpbGQsIHJ0LnJpZ2h0LCBydC5ib3R0b20pOwoJCQkJCXJ0LmxlZnQgPSB4LVNQTElUX1dJRFRILzI7CgkJCQkJcnQucmlnaHQgPSB4K1NQTElUX1dJRFRILzIrMTsKCQkJCQlJbnZhbGlkYXRlUmVjdChod25kLCAmcnQsIEZBTFNFKTsKCQkJCQlVcGRhdGVXaW5kb3coY2hpbGQtPmxlZnQuaHduZCk7CgkJCQkJVXBkYXRlV2luZG93KGh3bmQpOwoJCQkJCVVwZGF0ZVdpbmRvdyhjaGlsZC0+cmlnaHQuaHduZCk7CgkJCQl9CiNlbmRpZgoJCQl9CgkJCWJyZWFrOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fR0VUTUlOTUFYSU5GTzoKCQkJRGVmTURJQ2hpbGRQcm9jKGh3bmQsIG5tc2csIHdwYXJhbSwgbHBhcmFtKTsKCgkJCXtMUE1JTk1BWElORk8gbHBtbWkgPSAoTFBNSU5NQVhJTkZPKWxwYXJhbTsKCgkJCWxwbW1pLT5wdE1heFRyYWNrU2l6ZS54IDw8PSAxOy8qMipHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKSAvIFNNX0NYVklSVFVBTFNDUkVFTiAqLwoJCQlscG1taS0+cHRNYXhUcmFja1NpemUueSA8PD0gMTsvKjIqR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTikgLyBTTV9DWVZJUlRVQUxTQ1JFRU4gKi8KCQkJYnJlYWs7fQojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgkJY2FzZSBXTV9TRVRGT0NVUzoKCQkJaWYgKFNldEN1cnJlbnREaXJlY3RvcnkoY2hpbGQtPnBhdGgpKQoJCQkJc2V0X3NwYWNlX3N0YXR1cygpOwoJCQlTZXRGb2N1cyhjaGlsZC0+Zm9jdXNfcGFuZT8gY2hpbGQtPnJpZ2h0Lmh3bmQ6IGNoaWxkLT5sZWZ0Lmh3bmQpOwoJCQlicmVhazsKCgkJY2FzZSBXTV9ESVNQQVRDSF9DT01NQU5EOiB7CgkJCVBhbmUqIHBhbmUgPSBHZXRGb2N1cygpPT1jaGlsZC0+bGVmdC5od25kPyAmY2hpbGQtPmxlZnQ6ICZjaGlsZC0+cmlnaHQ7CgoJCQlzd2l0Y2goTE9XT1JEKHdwYXJhbSkpIHsKCQkJCWNhc2UgSURfV0lORE9XX05FVzogewoJCQkJCUNoaWxkV25kKiBuZXdfY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3coY2hpbGQtPnBhdGgsIE5VTEwsIGh3bmQpOwoKCQkJCQlpZiAoIWNyZWF0ZV9jaGlsZF93aW5kb3cobmV3X2NoaWxkKSkKCQkJCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbmV3X2NoaWxkKTsKCgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfUkVGUkVTSDoKCQkJCQlyZWZyZXNoX2RyaXZlcygpOwoJCQkJCXJlZnJlc2hfY2hpbGQoY2hpbGQpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfQUNUSVZBVEU6CgkJCQkJYWN0aXZhdGVfZW50cnkoY2hpbGQsIHBhbmUsIGh3bmQpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfRklMRV9NT1ZFOiB7CgkJCQkJVENIQVIgc291cmNlW0JVRkZFUl9MRU5dLCB0YXJnZXRbQlVGRkVSX0xFTl07CgoJCQkJCWlmIChwcm9tcHRfdGFyZ2V0KHBhbmUsIHNvdXJjZSwgdGFyZ2V0KSkgewoJCQkJCQlTSEZJTEVPUFNUUlVDVCBzaGZvID0ge2h3bmQsIEZPX01PVkUsIHNvdXJjZSwgdGFyZ2V0fTsKCgkJCQkJCXNvdXJjZVtsc3RybGVuKHNvdXJjZSkrMV0gPSAnXDAnOwoJCQkJCQl0YXJnZXRbbHN0cmxlbih0YXJnZXQpKzFdID0gJ1wwJzsKCgkJCQkJCWlmICghU0hGaWxlT3BlcmF0aW9uKCZzaGZvKSkKCQkJCQkJCXJlZnJlc2hfY2hpbGQoY2hpbGQpOwoJCQkJCX0KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9GSUxFX0NPUFk6IHsKCQkJCQlUQ0hBUiBzb3VyY2VbQlVGRkVSX0xFTl0sIHRhcmdldFtCVUZGRVJfTEVOXTsKCgkJCQkJaWYgKHByb21wdF90YXJnZXQocGFuZSwgc291cmNlLCB0YXJnZXQpKSB7CgkJCQkJCVNIRklMRU9QU1RSVUNUIHNoZm8gPSB7aHduZCwgRk9fQ09QWSwgc291cmNlLCB0YXJnZXR9OwoKCQkJCQkJc291cmNlW2xzdHJsZW4oc291cmNlKSsxXSA9ICdcMCc7CgkJCQkJCXRhcmdldFtsc3RybGVuKHRhcmdldCkrMV0gPSAnXDAnOwoKCQkJCQkJaWYgKCFTSEZpbGVPcGVyYXRpb24oJnNoZm8pKQoJCQkJCQkJcmVmcmVzaF9jaGlsZChjaGlsZCk7CgkJCQkJfQoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX0ZJTEVfREVMRVRFOiB7CgkJCQkJVENIQVIgcGF0aFtCVUZGRVJfTEVOXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNIRklMRU9QU1RSVUNUIHNoZm8gPSB7aHduZCwgRk9fREVMRVRFLCBwYXRoLCBOVUxMLCBGT0ZfQUxMT1dVTkRPfTsKCgkJCQkJZ2V0X3BhdGgocGFuZS0+Y3VyLCBwYXRoKTsKCgkJCQkJcGF0aFtsc3RybGVuKHBhdGgpKzFdID0gJ1wwJzsKCgkJCQkJaWYgKCFTSEZpbGVPcGVyYXRpb24oJnNoZm8pKQoJCQkJCQlyZWZyZXNoX2NoaWxkKGNoaWxkKTsKCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9WSUVXX1NPUlRfTkFNRToKCQkJCQlzZXRfc29ydF9vcmRlcihjaGlsZCwgU09SVF9OQU1FKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1ZJRVdfU09SVF9UWVBFOgoJCQkJCXNldF9zb3J0X29yZGVyKGNoaWxkLCBTT1JUX0VYVCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9WSUVXX1NPUlRfU0laRToKCQkJCQlzZXRfc29ydF9vcmRlcihjaGlsZCwgU09SVF9TSVpFKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1ZJRVdfU09SVF9EQVRFOgoJCQkJCXNldF9zb3J0X29yZGVyKGNoaWxkLCBTT1JUX0RBVEUpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19GSUxURVI6IHsKCQkJCQlzdHJ1Y3QgRmlsdGVyRGlhbG9nIGRsZzsKCgkJCQkJbWVtc2V0KCZkbGcsIDAsIHNpemVvZihzdHJ1Y3QgRmlsdGVyRGlhbG9nKSk7CgkJCQkJbHN0cmNweShkbGcucGF0dGVybiwgY2hpbGQtPmZpbHRlcl9wYXR0ZXJuKTsKCQkJCQlkbGcuZmxhZ3MgPSBjaGlsZC0+ZmlsdGVyX2ZsYWdzOwoKCQkJCQlpZiAoRGlhbG9nQm94UGFyYW0oR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRERfRElBTE9HX1ZJRVdfVFlQRSksIGh3bmQsIEZpbHRlckRpYWxvZ0RsZ1Byb2MsIChMUEFSQU0pJmRsZykgPT0gSURPSykgewoJCQkJCQlsc3RyY3B5KGNoaWxkLT5maWx0ZXJfcGF0dGVybiwgZGxnLnBhdHRlcm4pOwoJCQkJCQljaGlsZC0+ZmlsdGVyX2ZsYWdzID0gZGxnLmZsYWdzOwoJCQkJCQlyZWZyZXNoX3JpZ2h0X3BhbmUoY2hpbGQpOwoJCQkJCX0KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9WSUVXX1NQTElUOiB7CgkJCQkJbGFzdF9zcGxpdCA9IGNoaWxkLT5zcGxpdF9wb3M7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CiNlbmRpZgoJCQkJCVNldENhcHR1cmUoaHduZCk7CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfRURJVF9QUk9QRVJUSUVTOgoJCQkJCXNob3dfcHJvcGVydGllc19kbGcocGFuZS0+Y3VyLCBjaGlsZC0+aHduZCk7CgkJCQkJYnJlYWs7CgoJCQkJZGVmYXVsdDoKCQkJCQlyZXR1cm4gcGFuZV9jb21tYW5kKHBhbmUsIExPV09SRCh3cGFyYW0pKTsKCQkJfQoKCQkJcmV0dXJuIFRSVUU7fQoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJUGFuZSogcGFuZSA9IEdldEZvY3VzKCk9PWNoaWxkLT5sZWZ0Lmh3bmQ/ICZjaGlsZC0+bGVmdDogJmNoaWxkLT5yaWdodDsKCgkJCXN3aXRjaChISVdPUkQod3BhcmFtKSkgewoJCQkJY2FzZSBMQk5fU0VMQ0hBTkdFOiB7CgkJCQkJaW50IGlkeCA9IFNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX0dFVENVUlNFTCwgMCwgMCk7CgkJCQkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgU2VuZE1lc3NhZ2UocGFuZS0+aHduZCwgTEJfR0VUSVRFTURBVEEsIGlkeCwgMCk7CgoJCQkJCWlmIChwYW5lID09ICZjaGlsZC0+bGVmdCkKCQkJCQkJc2V0X2N1cmRpcihjaGlsZCwgZW50cnksIGlkeCwgaHduZCk7CgkJCQkJZWxzZQoJCQkJCQlwYW5lLT5jdXIgPSBlbnRyeTsKCQkJCQlicmVhazt9CgoJCQkJY2FzZSBMQk5fREJMQ0xLOgoJCQkJCWFjdGl2YXRlX2VudHJ5KGNoaWxkLCBwYW5lLCBod25kKTsKCQkJCQlicmVhazsKCQkJfQoJCQlicmVhazt9CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJY2FzZSBXTV9OT1RJRlk6IHsKCQkJTk1IRFIqIHBubWggPSAoTk1IRFIqKSBscGFyYW07CgkJCXJldHVybiBwYW5lX25vdGlmeShwbm1oLT5pZEZyb209PUlEV19IRUFERVJfTEVGVD8gJmNoaWxkLT5sZWZ0OiAmY2hpbGQtPnJpZ2h0LCBwbm1oKTt9CiNlbmRpZgoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgkJY2FzZSBXTV9DT05URVhUTUVOVTogewoJCQlQT0lOVCBwdCwgcHRfY2xudDsKCQkJUGFuZSogcGFuZTsKCQkJaW50IGlkeDsKCgkJCSAvKiBmaXJzdCBzZWxlY3QgdGhlIGN1cnJlbnQgaXRlbSBpbiB0aGUgbGlzdGJveCAqLwoJCQlIV05EIGhwYW5lbCA9IChIV05EKSB3cGFyYW07CgkJCXB0X2NsbnQueCA9IHB0LnggPSAoc2hvcnQpTE9XT1JEKGxwYXJhbSk7CgkJCXB0X2NsbnQueSA9IHB0LnkgPSAoc2hvcnQpSElXT1JEKGxwYXJhbSk7CgkJCVNjcmVlblRvQ2xpZW50KGhwYW5lbCwgJnB0X2NsbnQpOwoJCQlTZW5kTWVzc2FnZShocGFuZWwsIFdNX0xCVVRUT05ET1dOLCAwLCBNQUtFTE9ORyhwdF9jbG50LngsIHB0X2NsbnQueSkpOwoJCQlTZW5kTWVzc2FnZShocGFuZWwsIFdNX0xCVVRUT05VUCwgMCwgTUFLRUxPTkcocHRfY2xudC54LCBwdF9jbG50LnkpKTsKCgkJCSAvKiBub3cgY3JlYXRlIHRoZSBwb3B1cCBtZW51IHVzaW5nIHNoZWxsIG5hbWVzcGFjZSBhbmQgSUNvbnRleHRNZW51ICovCgkJCXBhbmUgPSBHZXRGb2N1cygpPT1jaGlsZC0+bGVmdC5od25kPyAmY2hpbGQtPmxlZnQ6ICZjaGlsZC0+cmlnaHQ7CgkJCWlkeCA9IFNlbmRNZXNzYWdlKHBhbmUtPmh3bmQsIExCX0dFVENVUlNFTCwgMCwgMCk7CgoJCQlpZiAoaWR4ICE9IC0xKSB7CgkJCQlFbnRyeSogZW50cnkgPSAoRW50cnkqKSBTZW5kTWVzc2FnZShwYW5lLT5od25kLCBMQl9HRVRJVEVNREFUQSwgaWR4LCAwKTsKCgkJCQlMUElURU1JRExJU1QgcGlkbF9hYnMgPSBnZXRfdG9fYWJzb2x1dGVfcGlkbChlbnRyeSwgaHduZCk7CgoJCQkJaWYgKHBpZGxfYWJzKSB7CgkJCQkJSVNoZWxsRm9sZGVyKiBwYXJlbnRGb2xkZXI7CgkJCQkJTFBDSVRFTUlETElTVCBwaWRsTGFzdDsKCgkJCQkJIC8qIGdldCBhbmQgdXNlIHRoZSBwYXJlbnQgZm9sZGVyIHRvIGRpc3BsYXkgY29ycmVjdCBjb250ZXh0IG1lbnUgaW4gYWxsIGNhc2VzICovCgkJCQkJaWYgKFNVQ0NFRURFRChTSEJpbmRUb1BhcmVudChwaWRsX2FicywgJklJRF9JU2hlbGxGb2xkZXIsIChMUFZPSUQqKSZwYXJlbnRGb2xkZXIsICZwaWRsTGFzdCkpKSB7CgkJCQkJCWlmIChTaGVsbEZvbGRlckNvbnRleHRNZW51KHBhcmVudEZvbGRlciwgaHduZCwgMSwgJnBpZGxMYXN0LCBwdC54LCBwdC55KSA9PSBTX09LKQoJCQkJCQkJcmVmcmVzaF9jaGlsZChjaGlsZCk7CgoJCQkJCQlJU2hlbGxGb2xkZXJfUmVsZWFzZShwYXJlbnRGb2xkZXIpOwoJCQkJCX0KCgkJCQkJSU1hbGxvY19GcmVlKEdsb2JhbHMuaU1hbGxvYywgcGlkbF9hYnMpOwoJCQkJfQoJCQl9CgkJCWJyZWFrO30KI2VuZGlmCgoJCSAgY2FzZSBXTV9NRUFTVVJFSVRFTToKCQkgIGRyYXdfbWVudV9pdGVtOgoJCQlpZiAoIXdwYXJhbSkJLyogSXMgdGhlIG1lc3NhZ2UgbWVudS1yZWxhdGVkPyAqLwoJCQkJaWYgKEN0eE1lbnVfSGFuZGxlTWVudU1zZyhubXNnLCB3cGFyYW0sIGxwYXJhbSkpCgkJCQkJcmV0dXJuIFRSVUU7CgoJCQlicmVhazsKCgkJICBjYXNlIFdNX0lOSVRNRU5VUE9QVVA6CgkJCWlmIChDdHhNZW51X0hhbmRsZU1lbnVNc2cobm1zZywgd3BhcmFtLCBscGFyYW0pKQoJCQkJcmV0dXJuIDA7CgoJCQl1cGRhdGVfdmlld19tZW51KGNoaWxkKTsKCQkJYnJlYWs7CgoJCSAgY2FzZSBXTV9NRU5VQ0hBUjoJLyogb25seSBzdXBwb3J0ZWQgYnkgSUNvbnRleHRNZW51MyAqLwoJCSAgIGlmIChzX3BjdHhtZW51MykgewoJCQkgICBMUkVTVUxUIGxSZXN1bHQgPSAwOwoKCQkJICAgSUNvbnRleHRNZW51M19IYW5kbGVNZW51TXNnMihzX3BjdHhtZW51Mywgbm1zZywgd3BhcmFtLCBscGFyYW0sICZsUmVzdWx0KTsKCgkJCSAgIHJldHVybiBsUmVzdWx0OwoJCSAgIH0KCgkJICAgYnJlYWs7CgoJCWNhc2UgV01fU0laRToKCQkJaWYgKHdwYXJhbSAhPSBTSVpFX01JTklNSVpFRCkKCQkJCXJlc2l6ZV90cmVlKGNoaWxkLCBMT1dPUkQobHBhcmFtKSwgSElXT1JEKGxwYXJhbSkpOwoJCQkvKiBmYWxsIHRocm91Z2ggKi8KCgkJZGVmYXVsdDogZGVmOgoJCQlyZXR1cm4gRGVmTURJQ2hpbGRQcm9jKGh3bmQsIG5tc2csIHdwYXJhbSwgbHBhcmFtKTsKCX0KCglyZXR1cm4gMDsKfQoKCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIFRyZWVXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nUHRyKEdldFBhcmVudChod25kKSwgR1dMUF9VU0VSREFUQSk7CglQYW5lKiBwYW5lID0gKFBhbmUqKSBHZXRXaW5kb3dMb25nUHRyKGh3bmQsIEdXTFBfVVNFUkRBVEEpOwoJQVNTRVJUKGNoaWxkKTsKCglzd2l0Y2gobm1zZykgewojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJY2FzZSBXTV9IU0NST0xMOgoJCQlzZXRfaGVhZGVyKHBhbmUpOwoJCQlicmVhazsKI2VuZGlmCgoJCWNhc2UgV01fU0VURk9DVVM6CgkJCWNoaWxkLT5mb2N1c19wYW5lID0gcGFuZT09JmNoaWxkLT5yaWdodD8gMTogMDsKCQkJU2VuZE1lc3NhZ2UoaHduZCwgTEJfU0VUU0VMLCBUUlVFLCAxKTsKCQkJLypUT0RPOiBjaGVjayBtZW51IGl0ZW1zICovCgkJCWJyZWFrOwoKCQljYXNlIFdNX0tFWURPV046CgkJCWlmICh3cGFyYW0gPT0gVktfVEFCKSB7CgkJCQkvKlRPRE86IFNldEZvY3VzKEdsb2JhbHMuaGRyaXZlYmFyKSAqLwoJCQkJU2V0Rm9jdXMoY2hpbGQtPmZvY3VzX3BhbmU/IGNoaWxkLT5sZWZ0Lmh3bmQ6IGNoaWxkLT5yaWdodC5od25kKTsKCQkJfQoJfQoKCXJldHVybiBDYWxsV2luZG93UHJvYyhnX29yZ1RyZWVXbmRQcm9jLCBod25kLCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7Cn0KCgpzdGF0aWMgdm9pZCBJbml0SW5zdGFuY2UoSElOU1RBTkNFIGhpbnN0YW5jZSkKewoJc3RhdGljIGNvbnN0IFRDSEFSIHNGb250W10gPSB7J00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJyAnLCdTJywnYScsJ24nLCdzJywnICcsJ1MnLCdlJywncicsJ2knLCdmJywnXDAnfTsKCglXTkRDTEFTU0VYIHdjRnJhbWU7CglXTkRDTEFTUyB3Y0NoaWxkOwoJQVRPTSBoQ2hpbGRDbGFzczsKCWludCBjb2w7CgoJSU5JVENPTU1PTkNPTlRST0xTRVggaWNjID0gewoJCXNpemVvZihJTklUQ09NTU9OQ09OVFJPTFNFWCksCgkJSUNDX0JBUl9DTEFTU0VTCgl9OwoKCUhEQyBoZGMgPSBHZXREQygwKTsKCglzZXRsb2NhbGUoTENfQ09MTEFURSwgIiIpOwkvKiBzZXQgY29sbGF0aW5nIHJ1bGVzIHRvIGxvY2FsIHNldHRpbmdzIGZvciBjb21wYXJlTmFtZSAqLwoKCUluaXRDb21tb25Db250cm9sc0V4KCZpY2MpOwoKCgkvKiByZWdpc3RlciBmcmFtZSB3aW5kb3cgY2xhc3MgKi8KCgl3Y0ZyYW1lLmNiU2l6ZSAgICAgICAgPSBzaXplb2YoV05EQ0xBU1NFWCk7Cgl3Y0ZyYW1lLnN0eWxlICAgICAgICAgPSAwOwoJd2NGcmFtZS5scGZuV25kUHJvYyAgID0gRnJhbWVXbmRQcm9jOwoJd2NGcmFtZS5jYkNsc0V4dHJhICAgID0gMDsKCXdjRnJhbWUuY2JXbmRFeHRyYSAgICA9IDA7Cgl3Y0ZyYW1lLmhJbnN0YW5jZSAgICAgPSBoaW5zdGFuY2U7Cgl3Y0ZyYW1lLmhJY29uICAgICAgICAgPSBMb2FkSWNvbihoaW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRElfV0lORUZJTEUpKTsKCXdjRnJhbWUuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3IoMCwgSURDX0FSUk9XKTsKCXdjRnJhbWUuaGJyQmFja2dyb3VuZCA9IDA7Cgl3Y0ZyYW1lLmxwc3pNZW51TmFtZSAgPSAwOwoJd2NGcmFtZS5scHN6Q2xhc3NOYW1lID0gc1dJTkVGSUxFRlJBTUU7Cgl3Y0ZyYW1lLmhJY29uU20gICAgICAgPSAoSElDT04pTG9hZEltYWdlKGhpbnN0YW5jZSwKCQkJCQkJCQkJCQkgTUFLRUlOVFJFU09VUkNFKElESV9XSU5FRklMRSksCgkJCQkJCQkJCQkJIElNQUdFX0lDT04sCgkJCQkJCQkJCQkJIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTTUlDT04pLAoJCQkJCQkJCQkJCSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01JQ09OKSwKCQkJCQkJCQkJCQkgTFJfU0hBUkVEKTsKCglHbG9iYWxzLmhmcmFtZUNsYXNzID0gUmVnaXN0ZXJDbGFzc0V4KCZ3Y0ZyYW1lKTsKCgoJLyogcmVnaXN0ZXIgdHJlZSB3aW5kb3dzIGNsYXNzICovCgoJd2NDaGlsZC5zdHlsZSAgICAgICAgID0gQ1NfQ0xBU1NEQ3xDU19EQkxDTEtTfENTX1ZSRURSQVc7Cgl3Y0NoaWxkLmxwZm5XbmRQcm9jICAgPSBDaGlsZFduZFByb2M7Cgl3Y0NoaWxkLmNiQ2xzRXh0cmEgICAgPSAwOwoJd2NDaGlsZC5jYlduZEV4dHJhICAgID0gMDsKCXdjQ2hpbGQuaEluc3RhbmNlICAgICA9IGhpbnN0YW5jZTsKCXdjQ2hpbGQuaEljb24gICAgICAgICA9IDA7Cgl3Y0NoaWxkLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yKDAsIElEQ19BUlJPVyk7Cgl3Y0NoaWxkLmhickJhY2tncm91bmQgPSAwOwoJd2NDaGlsZC5scHN6TWVudU5hbWUgID0gMDsKCXdjQ2hpbGQubHBzekNsYXNzTmFtZSA9IHNXSU5FRklMRVRSRUU7CgoJaENoaWxkQ2xhc3MgPSBSZWdpc3RlckNsYXNzKCZ3Y0NoaWxkKTsKCgoJR2xvYmFscy5oYWNjZWwgPSBMb2FkQWNjZWxlcmF0b3JzKGhpbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElEQV9XSU5FRklMRSkpOwoKCUdsb2JhbHMuaGZvbnQgPSBDcmVhdGVGb250KC1NdWxEaXYoOCxHZXREZXZpY2VDYXBzKGhkYyxMT0dQSVhFTFNZKSw3MiksIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIHNGb250KTsKCglSZWxlYXNlREMoMCwgaGRjKTsKCglHbG9iYWxzLmhJbnN0YW5jZSA9IGhpbnN0YW5jZTsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJQ29Jbml0aWFsaXplKE5VTEwpOwoJQ29HZXRNYWxsb2MoTUVNQ1RYX1RBU0ssICZHbG9iYWxzLmlNYWxsb2MpOwoJU0hHZXREZXNrdG9wRm9sZGVyKCZHbG9iYWxzLmlEZXNrdG9wKTsKI2lmZGVmIF9fV0lORV9fCglHbG9iYWxzLmNmU3RyRk5hbWUgPSBSZWdpc3RlckNsaXBib2FyZEZvcm1hdEEoQ0ZTVFJfRklMRU5BTUUpOwojZWxzZQoJR2xvYmFscy5jZlN0ckZOYW1lID0gUmVnaXN0ZXJDbGlwYm9hcmRGb3JtYXQoQ0ZTVFJfRklMRU5BTUUpOwojZW5kaWYKI2VuZGlmCgoJLyogbG9hZCBjb2x1bW4gc3RyaW5ncyAqLwoJY29sID0gMTsKCglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfTkFNRSk7Cglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfU0laRSk7Cglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfQ0RBVEUpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfQURBVEUpOwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX01EQVRFKTsKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9JRFgpOwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX0xJTktTKTsKI2VuZGlmCglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfQVRUUik7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9TRUMpOwojZW5kaWYKfQoKCnN0YXRpYyB2b2lkIHNob3dfZnJhbWUoSFdORCBod25kUGFyZW50LCBpbnQgY21kc2hvdywgTFBDVFNUUiBwYXRoKQp7CglzdGF0aWMgY29uc3QgVENIQVIgc01ESUNMSUVOVFtdID0geydNJywnRCcsJ0knLCdDJywnTCcsJ0knLCdFJywnTicsJ1QnLCdcMCd9OwoKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF0sIGIxW0JVRkZFUl9MRU5dOwoJQ2hpbGRXbmQqIGNoaWxkOwoJSE1FTlUgaE1lbnVGcmFtZSwgaE1lbnVXaW5kb3c7Cgl3aW5kb3dPcHRpb25zIG9wdHM7CgoJQ0xJRU5UQ1JFQVRFU1RSVUNUIGNjczsKCglpZiAoR2xvYmFscy5oTWFpblduZCkKCQlyZXR1cm47CgoJb3B0cyA9IGxvYWRfcmVnaXN0cnlfc2V0dGluZ3MoKTsKCWhNZW51RnJhbWUgPSBMb2FkTWVudShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElETV9XSU5FRklMRSkpOwoJaE1lbnVXaW5kb3cgPSBHZXRTdWJNZW51KGhNZW51RnJhbWUsIEdldE1lbnVJdGVtQ291bnQoaE1lbnVGcmFtZSktMik7CgoJR2xvYmFscy5oTWVudUZyYW1lID0gaE1lbnVGcmFtZTsKCUdsb2JhbHMuaE1lbnVWaWV3ID0gR2V0U3ViTWVudShoTWVudUZyYW1lLCAzKTsKCUdsb2JhbHMuaE1lbnVPcHRpb25zID0gR2V0U3ViTWVudShoTWVudUZyYW1lLCA0KTsKCgljY3MuaFdpbmRvd01lbnUgID0gaE1lbnVXaW5kb3c7CgljY3MuaWRGaXJzdENoaWxkID0gSURXX0ZJUlNUX0NISUxEOwoKCgkvKiBjcmVhdGUgbWFpbiB3aW5kb3cgKi8KCUdsb2JhbHMuaE1haW5XbmQgPSBDcmVhdGVXaW5kb3dFeCgwLCBNQUtFSU5UUkVTT1VSQ0UoR2xvYmFscy5oZnJhbWVDbGFzcyksIFJTKGIxLElEU19XSU5FX0ZJTEUpLCBXU19PVkVSTEFQUEVEV0lORE9XLAoJCQkJCW9wdHMuc3RhcnRfeCwgb3B0cy5zdGFydF95LCBvcHRzLndpZHRoLCBvcHRzLmhlaWdodCwKCQkJCQlod25kUGFyZW50LCBHbG9iYWxzLmhNZW51RnJhbWUsIEdsb2JhbHMuaEluc3RhbmNlLCAwLypscFBhcmFtKi8pOwoKCglHbG9iYWxzLmhtZGljbGllbnQgPSBDcmVhdGVXaW5kb3dFeCgwLCBzTURJQ0xJRU5ULCBOVUxMLAoJCQkJCVdTX0NISUxEfFdTX0NMSVBDSElMRFJFTnxXU19WU0NST0xMfFdTX0hTQ1JPTEx8V1NfVklTSUJMRXxXU19CT1JERVIsCgkJCQkJMCwgMCwgMCwgMCwKCQkJCQlHbG9iYWxzLmhNYWluV25kLCAwLCBHbG9iYWxzLmhJbnN0YW5jZSwgJmNjcyk7CiAgCglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBJRF9WSUVXX0RSSVZFX0JBUiwgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgSURfVklFV19TQVZFU0VUVElOR1MsIE1GX0JZQ09NTUFORCk7CgoJY3JlYXRlX2RyaXZlX2JhcigpOwoKCXsKCQlUQkJVVFRPTiB0b29sYmFyQnRuc1tdID0gewoJCQl7MCwgMCwgMCwgQlROU19TRVAsIHswLCAwfSwgMCwgMH0sCgkJCXswLCBJRF9XSU5ET1dfTkVXLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9LAoJCQl7MSwgSURfV0lORE9XX0NBU0NBREUsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH0sCgkJCXsyLCBJRF9XSU5ET1dfVElMRV9IT1JaLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9LAoJCQl7MywgSURfV0lORE9XX1RJTEVfVkVSVCwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKLypUT0RPCgkJCXs0LCBJRF8uLi4gLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9LAoJCQl7NSwgSURfLi4uICwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKKi8JCX07CgoJCUdsb2JhbHMuaHRvb2xiYXIgPSBDcmVhdGVUb29sYmFyRXgoR2xvYmFscy5oTWFpblduZCwgV1NfQ0hJTER8V1NfVklTSUJMRSwKCQkJSURXX1RPT0xCQVIsIDIsIEdsb2JhbHMuaEluc3RhbmNlLCBJREJfVE9PTEJBUiwgdG9vbGJhckJ0bnMsCgkJCXNpemVvZih0b29sYmFyQnRucykvc2l6ZW9mKFRCQlVUVE9OKSwgMTYsIDE1LCAxNiwgMTUsIHNpemVvZihUQkJVVFRPTikpOwoJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudU9wdGlvbnMsIElEX1ZJRVdfVE9PTF9CQVIsIE1GX0JZQ09NTUFORHxNRl9DSEVDS0VEKTsKCX0KCglHbG9iYWxzLmhzdGF0dXNiYXIgPSBDcmVhdGVTdGF0dXNXaW5kb3coV1NfQ0hJTER8V1NfVklTSUJMRSwgMCwgR2xvYmFscy5oTWFpblduZCwgSURXX1NUQVRVU0JBUik7CglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBJRF9WSUVXX1NUQVRVU0JBUiwgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoKLyogQ3JlYXRlU3RhdHVzV2luZG93IGRvZXMgbm90IGFjY2VwdCBXU19CT1JERVIKCUdsb2JhbHMuaHN0YXR1c2JhciA9IENyZWF0ZVdpbmRvd0V4KFdTX0VYX05PUEFSRU5UTk9USUZZLCBTVEFUVVNDTEFTU05BTUUsIDAsCgkJCQkJV1NfQ0hJTER8V1NfVklTSUJMRXxXU19DTElQU0lCTElOR1N8V1NfQk9SREVSfENDU19OT0RJVklERVIsIDAsMCwwLDAsCgkJCQkJR2xvYmFscy5oTWFpblduZCwgKEhNRU5VKUlEV19TVEFUVVNCQVIsIGhpbnN0YW5jZSwgMCk7Ki8KCgkvKlRPRE86IHJlYWQgcGF0aHMgZnJvbSByZWdpc3RyeSAqLwoKCWlmICghcGF0aCB8fCAhKnBhdGgpIHsKCQlHZXRDdXJyZW50RGlyZWN0b3J5KE1BWF9QQVRILCBidWZmZXIpOwoJCXBhdGggPSBidWZmZXI7Cgl9CgoJU2hvd1dpbmRvdyhHbG9iYWxzLmhNYWluV25kLCBjbWRzaG93KTsKCiNpZiBkZWZpbmVkKF9TSEVMTF9GT0xERVJTKSAmJiAhZGVmaW5lZChfX1dJTkVfXykKCSAvKiBTaGVsbCBOYW1lc3BhY2UgYXMgZGVmYXVsdDogKi8KCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIGdldF9wYXRoX3BpZGwocGF0aCxHbG9iYWxzLmhNYWluV25kKSwgR2xvYmFscy5oTWFpblduZCk7CiNlbHNlCgljaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhwYXRoLCBOVUxMLCBHbG9iYWxzLmhNYWluV25kKTsKI2VuZGlmCgoJY2hpbGQtPnBvcy5zaG93Q21kID0gU1dfU0hPV01BWElNSVpFRDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5sZWZ0ID0gMDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi50b3AgPSAwOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLnJpZ2h0ID0gMzIwOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmJvdHRvbSA9IDI4MDsKCglpZiAoIWNyZWF0ZV9jaGlsZF93aW5kb3coY2hpbGQpKQoJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGNoaWxkKTsKCglTZXRXaW5kb3dQbGFjZW1lbnQoY2hpbGQtPmh3bmQsICZjaGlsZC0+cG9zKTsKCglHbG9iYWxzLmhpbWwgPSBJbWFnZUxpc3RfTG9hZEJpdG1hcChHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElEQl9JTUFHRVMpLCAxNiwgMCwgUkdCKDAsMjU1LDApKTsKCglHbG9iYWxzLnByZXNjYW5fbm9kZSA9IEZBTFNFOwoKCVVwZGF0ZVdpbmRvdyhHbG9iYWxzLmhNYWluV25kKTsKCglpZiAocGF0aCAmJiBwYXRoWzBdKQoJewoJCWludCBpbmRleCxjb3VudDsKCQlUQ0hBUiBkcnZbX01BWF9EUklWRSsxXSwgZGlyW19NQVhfRElSXSwgbmFtZVtfTUFYX0ZOQU1FXSwgZXh0W19NQVhfRVhUXTsKCQlUQ0hBUiBmdWxsbmFtZVtfTUFYX0ZOQU1FK19NQVhfRVhUKzFdOwoKCQltZW1zZXQobmFtZSwwLHNpemVvZihuYW1lKSk7CgkJbWVtc2V0KG5hbWUsMCxzaXplb2YoZXh0KSk7CgkJX3RzcGxpdHBhdGgocGF0aCwgZHJ2LCBkaXIsIG5hbWUsIGV4dCk7CgkJaWYgKG5hbWVbMF0pCgkJewoJCQljb3VudCA9IFNlbmRNZXNzYWdlKGNoaWxkLT5yaWdodC5od25kLCBMQl9HRVRDT1VOVCwgMCwgMCk7CgkJCWxzdHJjcHkoZnVsbG5hbWUsbmFtZSk7CgkJCWxzdHJjYXQoZnVsbG5hbWUsZXh0KTsKCgkJCWZvciAoaW5kZXggPSAwOyBpbmRleCA8IGNvdW50OyBpbmRleCArKykKCQkJewoJCQkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgU2VuZE1lc3NhZ2UoY2hpbGQtPnJpZ2h0Lmh3bmQsIExCX0dFVElURU1EQVRBLCBpbmRleCwgMCk7CgkJCQlpZiAobHN0cmNtcChlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsZnVsbG5hbWUpPT0wIHx8CgkJCQkJCWxzdHJjbXAoZW50cnktPmRhdGEuY0FsdGVybmF0ZUZpbGVOYW1lLGZ1bGxuYW1lKT09MCkKCQkJCXsKCQkJCQlTZW5kTWVzc2FnZShjaGlsZC0+cmlnaHQuaHduZCwgTEJfU0VUQ1VSU0VMLCBpbmRleCwgMCk7CgkJCQkJU2V0Rm9jdXMoY2hpbGQtPnJpZ2h0Lmh3bmQpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJfQoJfQp9CgpzdGF0aWMgdm9pZCBFeGl0SW5zdGFuY2Uodm9pZCkKewojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCUlTaGVsbEZvbGRlcl9SZWxlYXNlKEdsb2JhbHMuaURlc2t0b3ApOwoJSU1hbGxvY19SZWxlYXNlKEdsb2JhbHMuaU1hbGxvYyk7CglDb1VuaW5pdGlhbGl6ZSgpOwojZW5kaWYKCglEZWxldGVPYmplY3QoR2xvYmFscy5oZm9udCk7CglJbWFnZUxpc3RfRGVzdHJveShHbG9iYWxzLmhpbWwpOwp9CgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCi8qIHNlYXJjaCBmb3IgYWxyZWFkeSBydW5uaW5nIHdpbltlXWZpbGVzICovCgpzdGF0aWMgaW50IGdfZm91bmRQcmV2SW5zdGFuY2UgPSAwOwoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgRW51bVduZFByb2MoSFdORCBod25kLCBMUEFSQU0gbHBhcmFtKQp7CglUQ0hBUiBjbHNbMTI4XTsKCglHZXRDbGFzc05hbWUoaHduZCwgY2xzLCAxMjgpOwoKCWlmICghbHN0cmNtcChjbHMsIChMUENUU1RSKWxwYXJhbSkpIHsKCQlnX2ZvdW5kUHJldkluc3RhbmNlKys7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCXJldHVybiBUUlVFOwp9CgovKiBzZWFyY2ggZm9yIHdpbmRvdyBvZiBnaXZlbiBjbGFzcyBuYW1lIHRvIGFsbG93IG9ubHkgb25lIHJ1bm5pbmcgaW5zdGFuY2UgKi8Kc3RhdGljIGludCBmaW5kX3dpbmRvd19jbGFzcyhMUENUU1RSIGNsYXNzbmFtZSkKewoJRW51bVdpbmRvd3MoRW51bVduZFByb2MsIChMUEFSQU0pY2xhc3NuYW1lKTsKCglpZiAoZ19mb3VuZFByZXZJbnN0YW5jZSkKCQlyZXR1cm4gMTsKCglyZXR1cm4gMDsKfQoKI2VuZGlmCgpzdGF0aWMgaW50IHdpbmVmaWxlX21haW4oSElOU1RBTkNFIGhpbnN0YW5jZSwgaW50IGNtZHNob3csIExQQ1RTVFIgcGF0aCkKewoJTVNHIG1zZzsKICAKCUluaXRJbnN0YW5jZShoaW5zdGFuY2UpOwoKCXNob3dfZnJhbWUoMCwgY21kc2hvdywgcGF0aCk7CgoJd2hpbGUoR2V0TWVzc2FnZSgmbXNnLCAwLCAwLCAwKSkgewoJCWlmIChHbG9iYWxzLmhtZGljbGllbnQgJiYgVHJhbnNsYXRlTURJU3lzQWNjZWwoR2xvYmFscy5obWRpY2xpZW50LCAmbXNnKSkKCQkJY29udGludWU7CgoJCWlmIChHbG9iYWxzLmhNYWluV25kICYmIFRyYW5zbGF0ZUFjY2VsZXJhdG9yKEdsb2JhbHMuaE1haW5XbmQsIEdsb2JhbHMuaGFjY2VsLCAmbXNnKSkKCQkJY29udGludWU7CgoJCVRyYW5zbGF0ZU1lc3NhZ2UoJm1zZyk7CgkJRGlzcGF0Y2hNZXNzYWdlKCZtc2cpOwoJfQoKCUV4aXRJbnN0YW5jZSgpOwoKCXJldHVybiBtc2cud1BhcmFtOwp9CgoKI2lmIGRlZmluZWQoVU5JQ09ERSkgJiYgZGVmaW5lZChfTVNDX1ZFUikKaW50IEFQSUVOVFJZIHdXaW5NYWluKEhJTlNUQU5DRSBoaW5zdGFuY2UsIEhJTlNUQU5DRSBwcmV2aW5zdGFuY2UsIExQV1NUUiBjbWRsaW5lLCBpbnQgY21kc2hvdykKI2Vsc2UKaW50IEFQSUVOVFJZIFdpbk1haW4oSElOU1RBTkNFIGhpbnN0YW5jZSwgSElOU1RBTkNFIHByZXZpbnN0YW5jZSwgTFBTVFIgY21kbGluZSwgaW50IGNtZHNob3cpCiNlbmRpZgp7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJaWYgKGZpbmRfd2luZG93X2NsYXNzKHNXSU5FRklMRUZSQU1FKSkKCQlyZXR1cm4gMTsKI2VuZGlmCgojaWYgZGVmaW5lZChVTklDT0RFKSAmJiAhZGVmaW5lZChfTVNDX1ZFUikKCXsgLyogY29udmVydCBBTlNJIGNtZGxpbmUgaW50byBXQ1MgcGF0aCBzdHJpbmcgKi8KCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF07CglNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgY21kbGluZSwgLTEsIGJ1ZmZlciwgTUFYX1BBVEgpOwoJd2luZWZpbGVfbWFpbihoaW5zdGFuY2UsIGNtZHNob3csIGJ1ZmZlcik7Cgl9CiNlbHNlCgl3aW5lZmlsZV9tYWluKGhpbnN0YW5jZSwgY21kc2hvdywgY21kbGluZSk7CiNlbmRpZgoKCXJldHVybiAwOwp9Cg==