LyoKICogV2luZWZpbGUKICoKICogQ29weXJpZ2h0IDIwMDAsIDIwMDMsIDIwMDQgTWFydGluIEZ1Y2hzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpZmRlZiBfX1dJTkVfXwojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKI2VuZGlmCgojaW5jbHVkZSA8bG9jYWxlLmg+CgojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojaW5jbHVkZSAid2luZWZpbGUuaCIKI2luY2x1ZGUgInJlc291cmNlLmgiCgovKiBmb3IgcmVhZF9kaXJlY3RvcnlfdW5peCgpICovCiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKI2luY2x1ZGUgPGRpcmVudC5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDx0aW1lLmg+CiNlbmRpZgoKI2lmZGVmIF9OT19FWFRFTlNJT05TCiN1bmRlZiBfTEVGVF9GSUxFUwojZW5kaWYKCiNpZm5kZWYgX01BWF9QQVRICiNkZWZpbmUgX01BWF9EUklWRSAgICAgICAgICAzCiNkZWZpbmUgX01BWF9GTkFNRSAgICAgICAgICAyNTYKI2RlZmluZSBfTUFYX0RJUiAgICAgICAgICAgIF9NQVhfRk5BTUUKI2RlZmluZSBfTUFYX0VYVCAgICAgICAgICAgIF9NQVhfRk5BTUUKI2RlZmluZSBfTUFYX1BBVEggICAgICAgICAgIDI2MAojZW5kaWYKCiNpZmRlZiBOT05BTUVMRVNTVU5JT04KI2RlZmluZQlVTklPTl9NRU1CRVIoeCkgRFVNTVlVTklPTk5BTUUueAojZWxzZQojZGVmaW5lCVVOSU9OX01FTUJFUih4KSB4CiNlbmRpZgoKCiNpZmRlZiBfU0hFTExfRk9MREVSUwojZGVmaW5lCURFRkFVTFRfU1BMSVRfUE9TCTMwMAojZWxzZQojZGVmaW5lCURFRkFVTFRfU1BMSVRfUE9TCTIwMAojZW5kaWYKCgplbnVtIEVOVFJZX1RZUEUgewoJRVRfV0lORE9XUywKCUVUX1VOSVgsCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJRVRfU0hFTEwKI2VuZGlmCn07Cgp0eXBlZGVmIHN0cnVjdCBfRW50cnkgewoJc3RydWN0IF9FbnRyeSoJbmV4dDsKCXN0cnVjdCBfRW50cnkqCWRvd247CglzdHJ1Y3QgX0VudHJ5Kgl1cDsKCglCT09MCQkJZXhwYW5kZWQ7CglCT09MCQkJc2Nhbm5lZDsKCWludAkJCQlsZXZlbDsKCglXSU4zMl9GSU5EX0RBVEEJZGF0YTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGJoZmk7CglCT09MCQkJYmhmaV92YWxpZDsKCWVudW0gRU5UUllfVFlQRQlldHlwZTsKI2VuZGlmCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJTFBJVEVNSURMSVNUCXBpZGw7CglJU2hlbGxGb2xkZXIqCWZvbGRlcjsKCUhJQ09OCQkJaGljb247CiNlbmRpZgp9IEVudHJ5OwoKdHlwZWRlZiBzdHJ1Y3QgewoJRW50cnkJZW50cnk7CglUQ0hBUglwYXRoW01BWF9QQVRIXTsKCVRDSEFSCXZvbG5hbWVbX01BWF9GTkFNRV07CglUQ0hBUglmc1tfTUFYX0RJUl07CglEV09SRAlkcml2ZV90eXBlOwoJRFdPUkQJZnNfZmxhZ3M7Cn0gUm9vdDsKCmVudW0gQ09MVU1OX0ZMQUdTIHsKCUNPTF9TSVpFCQk9IDB4MDEsCglDT0xfREFURQkJPSAweDAyLAoJQ09MX1RJTUUJCT0gMHgwNCwKCUNPTF9BVFRSSUJVVEVTCT0gMHgwOCwKCUNPTF9ET1NOQU1FUwk9IDB4MTAsCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJQ09MX0FMTCA9IENPTF9TSVpFfENPTF9EQVRFfENPTF9USU1FfENPTF9BVFRSSUJVVEVTfENPTF9ET1NOQU1FUwojZWxzZQoJQ09MX0lOREVYCQk9IDB4MjAsCglDT0xfTElOS1MJCT0gMHg0MCwKCUNPTF9BTEwgPSBDT0xfU0laRXxDT0xfREFURXxDT0xfVElNRXxDT0xfQVRUUklCVVRFU3xDT0xfRE9TTkFNRVN8Q09MX0lOREVYfENPTF9MSU5LUwojZW5kaWYKfTsKCnR5cGVkZWYgZW51bSB7CglTT1JUX05BTUUsCglTT1JUX0VYVCwKCVNPUlRfU0laRSwKCVNPUlRfREFURQp9IFNPUlRfT1JERVI7Cgp0eXBlZGVmIHN0cnVjdCB7CglIV05ECWh3bmQ7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCUhXTkQJaHduZEhlYWRlcjsKI2VuZGlmCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCiNkZWZpbmUJQ09MVU1OUwkxMAojZWxzZQojZGVmaW5lCUNPTFVNTlMJNQojZW5kaWYKCWludAkJd2lkdGhzW0NPTFVNTlNdOwoJaW50CQlwb3NpdGlvbnNbQ09MVU1OUysxXTsKCglCT09MCXRyZWVQYW5lOwoJaW50CQl2aXNpYmxlX2NvbHM7CglFbnRyeSoJcm9vdDsKCUVudHJ5KgljdXI7Cn0gUGFuZTsKCnR5cGVkZWYgc3RydWN0IHsKCUhXTkQJaHduZDsKCVBhbmUJbGVmdDsKCVBhbmUJcmlnaHQ7CglpbnQJCWZvY3VzX3BhbmU7CQkvKiAwOiBsZWZ0ICAxOiByaWdodCAqLwoJV0lORE9XUExBQ0VNRU5UIHBvczsKCWludAkJc3BsaXRfcG9zOwoJQk9PTAloZWFkZXJfd2R0aHNfb2s7CgoJVENIQVIJcGF0aFtNQVhfUEFUSF07CglSb290CXJvb3Q7CgoJU09SVF9PUkRFUiBzb3J0T3JkZXI7Cn0gQ2hpbGRXbmQ7CgoKZXh0ZXJuIHZvaWQgV2luZUxpY2Vuc2UoSFdORCBod25kKTsKZXh0ZXJuIHZvaWQgV2luZVdhcnJhbnR5KEhXTkQgaHduZCk7CgoKc3RhdGljIHZvaWQgcmVhZF9kaXJlY3RvcnkoRW50cnkqIGRpciwgTFBDVFNUUiBwYXRoLCBTT1JUX09SREVSIHNvcnRPcmRlciwgSFdORCBod25kKTsKc3RhdGljIHZvaWQgc2V0X2N1cmRpcihDaGlsZFduZCogY2hpbGQsIEVudHJ5KiBlbnRyeSwgSFdORCBod25kKTsKc3RhdGljIHZvaWQgZ2V0X3BhdGgoRW50cnkqIGRpciwgUFRTVFIgcGF0aCk7CgpMUkVTVUxUIENBTExCQUNLIEZyYW1lV25kUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSk7CkxSRVNVTFQgQ0FMTEJBQ0sgQ2hpbGRXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKTsKTFJFU1VMVCBDQUxMQkFDSyBUcmVlV25kUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSk7CgoKLyogZ2xvYmFscyAqLwpXSU5FRklMRV9HTE9CQUxTIEdsb2JhbHM7CgovKiBzb21lIGNvbW1vbiBzdHJpbmcgY29uc3RhbnRzICovCmNvbnN0IHN0YXRpYyBUQ0hBUiBzRW1wdHlbXSA9IHsnXDAnfTsKY29uc3Qgc3RhdGljIFRDSEFSIHNTcGFjZVtdID0geycgJywgJ1wwJ307CmNvbnN0IHN0YXRpYyBUQ0hBUiBzTnVtRm10W10gPSB7JyUnLCdkJywnXDAnfTsKY29uc3Qgc3RhdGljIFRDSEFSIHNRTWFya3NbXSA9IHsnPycsJz8nLCc/JywnXDAnfTsKCi8qIHdpbmRvdyBjbGFzcyBuYW1lcyAqLwpjb25zdCBzdGF0aWMgVENIQVIgc1dJTkVGSUxFRlJBTUVbXSA9IHsnVycsJ0YnLCdTJywnXycsJ0YnLCdyJywnYScsJ20nLCdlJywnXDAnfTsKY29uc3Qgc3RhdGljIFRDSEFSIHNXSU5FRklMRVRSRUVbXSA9IHsnVycsJ0YnLCdTJywnXycsJ1QnLCdyJywnZScsJ2UnLCdcMCd9OwoKI2lmZGVmIF9NU0NfVkVSCi8qICNkZWZpbmUgTE9OR0xPTkdBUkcgX1QoIkk2NCIpICovCmNvbnN0IHN0YXRpYyBUQ0hBUiBzTG9uZ0hleEZtdFtdID0geyclJywnSScsJzYnLCc0JywnWCcsJ1wwJ307CmNvbnN0IHN0YXRpYyBUQ0hBUiBzTG9uZ051bUZtdFtdID0geyclJywnSScsJzYnLCc0JywnZCcsJ1wwJ307CiNlbHNlCi8qICNkZWZpbmUgTE9OR0xPTkdBUkcgX1QoIkwiKSAqLwpjb25zdCBzdGF0aWMgVENIQVIgc0xvbmdIZXhGbXRbXSA9IHsnJScsJ0wnLCdYJywnXDAnfTsKY29uc3Qgc3RhdGljIFRDSEFSIHNMb25nTnVtRm10W10gPSB7JyUnLCdMJywnZCcsJ1wwJ307CiNlbmRpZgoKCi8qIGxvYWQgcmVzb3VyY2Ugc3RyaW5nICovCnN0YXRpYyBMUFRTVFIgbG9hZF9zdHJpbmcoTFBUU1RSIGJ1ZmZlciwgVUlOVCBpZCkKewoJTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgaWQsIGJ1ZmZlciwgQlVGRkVSX0xFTik7CgoJcmV0dXJuIGJ1ZmZlcjsKfQoKI2RlZmluZSBSUyhiLCBpKSBsb2FkX3N0cmluZyhiLCBpKQoKCi8qIGRpc3BsYXkgZXJyb3IgbWVzc2FnZSBmb3IgdGhlIHNwZWNpZmllZCBXSU4zMiBlcnJvciBjb2RlICovCnN0YXRpYyB2b2lkIGRpc3BsYXlfZXJyb3IoSFdORCBod25kLCBEV09SRCBlcnJvcikKewoJVENIQVIgYjFbQlVGRkVSX0xFTl0sIGIyW0JVRkZFUl9MRU5dOwoJUFRTVFIgbXNnOwoKCWlmIChGb3JtYXRNZXNzYWdlKEZPUk1BVF9NRVNTQUdFX0FMTE9DQVRFX0JVRkZFUnxGT1JNQVRfTUVTU0FHRV9GUk9NX1NZU1RFTSwKCQkwLCBlcnJvciwgTUFLRUxBTkdJRChMQU5HX05FVVRSQUwsU1VCTEFOR19ERUZBVUxUKSwgKFBUU1RSKSZtc2csIDAsIE5VTEwpKQoJCU1lc3NhZ2VCb3goaHduZCwgbXNnLCBSUyhiMixJRFNfV0lORUZJTEUpLCBNQl9PSyk7CgllbHNlCgkJTWVzc2FnZUJveChod25kLCBSUyhiMSxJRFNfRVJST1IpLCBSUyhiMixJRFNfV0lORUZJTEUpLCBNQl9PSyk7CgoJTG9jYWxGcmVlKG1zZyk7Cn0KCi8qIGFsbG9jYXRlIGFuZCBpbml0aWFsaXNlIGEgZGlyZWN0b3J5IGVudHJ5ICovCnN0YXRpYyBFbnRyeSogYWxsb2NfZW50cnkoKQp7CglFbnRyeSogZW50cnkgPSAoRW50cnkqKSBtYWxsb2Moc2l6ZW9mKEVudHJ5KSk7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWVudHJ5LT5waWRsID0gTlVMTDsKCWVudHJ5LT5mb2xkZXIgPSBOVUxMOwoJZW50cnktPmhpY29uID0gMDsKI2VuZGlmCgoJcmV0dXJuIGVudHJ5Owp9CgovKiBmcmVlIGEgZGlyZWN0b3J5IGVudHJ5ICovCnN0YXRpYyB2b2lkIGZyZWVfZW50cnkoRW50cnkqIGVudHJ5KQp7CiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGVudHJ5LT5oaWNvbiAmJiBlbnRyeS0+aGljb24hPShISUNPTiktMSkKCQlEZXN0cm95SWNvbihlbnRyeS0+aGljb24pOwoKCWlmIChlbnRyeS0+Zm9sZGVyICYmIGVudHJ5LT5mb2xkZXIhPUdsb2JhbHMuaURlc2t0b3ApCgkJKCplbnRyeS0+Zm9sZGVyLT5scFZ0YmwtPlJlbGVhc2UpKGVudHJ5LT5mb2xkZXIpOwoKCWlmIChlbnRyeS0+cGlkbCkKCQkoKkdsb2JhbHMuaU1hbGxvYy0+bHBWdGJsLT5GcmVlKShHbG9iYWxzLmlNYWxsb2MsIGVudHJ5LT5waWRsKTsKI2VuZGlmCgoJZnJlZShlbnRyeSk7Cn0KCi8qIHJlY3Vyc2l2ZWx5IGZyZWUgYWxsIGNoaWxkIGVudHJpZXMgKi8Kc3RhdGljIHZvaWQgZnJlZV9lbnRyaWVzKEVudHJ5KiBkaXIpCnsKCUVudHJ5ICplbnRyeSwgKm5leHQ9ZGlyLT5kb3duOwoKCWlmIChuZXh0KSB7CgkJZGlyLT5kb3duID0gMDsKCgkJZG8gewoJCQllbnRyeSA9IG5leHQ7CgkJCW5leHQgPSBlbnRyeS0+bmV4dDsKCgkJCWZyZWVfZW50cmllcyhlbnRyeSk7CgkJCWZyZWVfZW50cnkoZW50cnkpOwoJCX0gd2hpbGUobmV4dCk7Cgl9Cn0KCgpzdGF0aWMgdm9pZCByZWFkX2RpcmVjdG9yeV93aW4oRW50cnkqIGRpciwgTFBDVFNUUiBwYXRoKQp7CglFbnRyeSogZmlyc3RfZW50cnkgPSBOVUxMOwoJRW50cnkqIGxhc3QgPSBOVUxMOwoJRW50cnkqIGVudHJ5OwoKCWludCBsZXZlbCA9IGRpci0+bGV2ZWwgKyAxOwoJV0lOMzJfRklORF9EQVRBIHczMmZkOwoJSEFORExFIGhGaW5kOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglIQU5ETEUgaEZpbGU7CiNlbmRpZgoKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF0sICpwOwoJZm9yKHA9YnVmZmVyOyAqcGF0aDsgKQoJCSpwKysgPSAqcGF0aCsrOwoKCSpwKysgPSAnXFwnOwoJcFswXSA9ICcqJzsKCXBbMV0gPSAnXDAnOwoKCWhGaW5kID0gRmluZEZpcnN0RmlsZShidWZmZXIsICZ3MzJmZCk7CgoJaWYgKGhGaW5kICE9IElOVkFMSURfSEFORExFX1ZBTFVFKSB7CgkJZG8gewoJCQllbnRyeSA9IGFsbG9jX2VudHJ5KCk7CgoJCQlpZiAoIWZpcnN0X2VudHJ5KQoJCQkJZmlyc3RfZW50cnkgPSBlbnRyeTsKCgkJCWlmIChsYXN0KQoJCQkJbGFzdC0+bmV4dCA9IGVudHJ5OwoKCQkJbWVtY3B5KCZlbnRyeS0+ZGF0YSwgJnczMmZkLCBzaXplb2YoV0lOMzJfRklORF9EQVRBKSk7CgkJCWVudHJ5LT5kb3duID0gTlVMTDsKCQkJZW50cnktPnVwID0gZGlyOwoJCQllbnRyeS0+ZXhwYW5kZWQgPSBGQUxTRTsKCQkJZW50cnktPnNjYW5uZWQgPSBGQUxTRTsKCQkJZW50cnktPmxldmVsID0gbGV2ZWw7CgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJLyogaGlkZSBkaXJlY3RvcnkgZW50cnkgIi4iICovCgkJCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCQlMUENUU1RSIG5hbWUgPSBlbnRyeS0+ZGF0YS5jRmlsZU5hbWU7CgoJCQkJaWYgKG5hbWVbMF09PScuJyAmJiBuYW1lWzFdPT0nXDAnKQoJCQkJCWNvbnRpbnVlOwoJCQl9CiNlbHNlCgkJCWVudHJ5LT5ldHlwZSA9IEVUX1dJTkRPV1M7CgkJCWVudHJ5LT5iaGZpX3ZhbGlkID0gRkFMU0U7CgoJCQlsc3RyY3B5KHAsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSk7CgoJCQloRmlsZSA9IENyZWF0ZUZpbGUoYnVmZmVyLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRHxGSUxFX1NIQVJFX1dSSVRFfEZJTEVfU0hBUkVfREVMRVRFLAoJCQkJCQkJCTAsIE9QRU5fRVhJU1RJTkcsIEZJTEVfRkxBR19CQUNLVVBfU0VNQU5USUNTLCAwKTsKCgkJCWlmIChoRmlsZSAhPSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgewoJCQkJaWYgKEdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhGaWxlLCAmZW50cnktPmJoZmkpKQoJCQkJCWVudHJ5LT5iaGZpX3ZhbGlkID0gVFJVRTsKCgkJCQlDbG9zZUhhbmRsZShoRmlsZSk7CgkJCX0KI2VuZGlmCgoJCQlsYXN0ID0gZW50cnk7CgkJfSB3aGlsZShGaW5kTmV4dEZpbGUoaEZpbmQsICZlbnRyeS0+ZGF0YSkpOwoKCQlsYXN0LT5uZXh0ID0gTlVMTDsKCgkJRmluZENsb3NlKGhGaW5kKTsKCX0KCglkaXItPmRvd24gPSBmaXJzdF9lbnRyeTsKCWRpci0+c2Nhbm5lZCA9IFRSVUU7Cn0KCgpzdGF0aWMgRW50cnkqIGZpbmRfZW50cnlfd2luKEVudHJ5KiBkaXIsIExQQ1RTVFIgbmFtZSkKewoJRW50cnkqIGVudHJ5OwoKCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkgewoJCUxQQ1RTVFIgcCA9IG5hbWU7CgkJTFBDVFNUUiBxID0gZW50cnktPmRhdGEuY0ZpbGVOYW1lOwoKCQlkbyB7CgkJCWlmICghKnAgfHwgKnA9PVRFWFQoJ1xcJykgfHwgKnA9PVRFWFQoJy8nKSkKCQkJCXJldHVybiBlbnRyeTsKCQl9IHdoaWxlKHRvbG93ZXIoKnArKykgPT0gdG9sb3dlcigqcSsrKSk7CgoJCXAgPSBuYW1lOwoJCXEgPSBlbnRyeS0+ZGF0YS5jQWx0ZXJuYXRlRmlsZU5hbWU7CgoJCWRvIHsKCQkJaWYgKCEqcCB8fCAqcD09VEVYVCgnXFwnKSB8fCAqcD09VEVYVCgnLycpKQoJCQkJcmV0dXJuIGVudHJ5OwoJCX0gd2hpbGUodG9sb3dlcigqcCsrKSA9PSB0b2xvd2VyKCpxKyspKTsKCX0KCglyZXR1cm4gMDsKfQoKCnN0YXRpYyBFbnRyeSogcmVhZF90cmVlX3dpbihSb290KiByb290LCBMUENUU1RSIHBhdGgsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF07CglFbnRyeSogZW50cnkgPSAmcm9vdC0+ZW50cnk7CglMUENUU1RSIHMgPSBwYXRoOwoJUFRTVFIgZCA9IGJ1ZmZlcjsKCglIQ1VSU09SIG9sZF9jdXJzb3IgPSBTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfV0FJVCkpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJZW50cnktPmV0eXBlID0gRVRfV0lORE9XUzsKI2VuZGlmCgoJd2hpbGUoZW50cnkpIHsKCQl3aGlsZSgqcyAmJiAqcyE9VEVYVCgnXFwnKSAmJiAqcyE9VEVYVCgnLycpKQoJCQkqZCsrID0gKnMrKzsKCgkJd2hpbGUoKnM9PVRFWFQoJ1xcJykgfHwgKnM9PVRFWFQoJy8nKSkKCQkJcysrOwoKCQkqZCsrID0gVEVYVCgnXFwnKTsKCQkqZCA9IFRFWFQoJ1wwJyk7CgoJCXJlYWRfZGlyZWN0b3J5KGVudHJ5LCBidWZmZXIsIHNvcnRPcmRlciwgaHduZCk7CgoJCWlmIChlbnRyeS0+ZG93bikKCQkJZW50cnktPmV4cGFuZGVkID0gVFJVRTsKCgkJaWYgKCEqcykKCQkJYnJlYWs7CgoJCWVudHJ5ID0gZmluZF9lbnRyeV93aW4oZW50cnksIHMpOwoJfQoKCVNldEN1cnNvcihvbGRfY3Vyc29yKTsKCglyZXR1cm4gZW50cnk7Cn0KCgojaWYgIWRlZmluZWQoX05PX0VYVEVOU0lPTlMpICYmIGRlZmluZWQoX19XSU5FX18pCgpzdGF0aWMgQk9PTCB0aW1lX3RvX2ZpbGV0aW1lKGNvbnN0IHRpbWVfdCogdCwgRklMRVRJTUUqIGZ0aW1lKQp7CglzdHJ1Y3QgdG0qIHRtID0gZ210aW1lKHQpOwoJU1lTVEVNVElNRSBzdGltZTsKCglpZiAoIXRtKQoJCXJldHVybiBGQUxTRTsKCglzdGltZS53WWVhciA9IHRtLT50bV95ZWFyKzE5MDA7CglzdGltZS53TW9udGggPSB0bS0+dG1fbW9uKzE7CgkvKglzdGltZS53RGF5T2ZXZWVrICovCglzdGltZS53RGF5ID0gdG0tPnRtX21kYXk7CglzdGltZS53SG91ciA9IHRtLT50bV9ob3VyOwoJc3RpbWUud01pbnV0ZSA9IHRtLT50bV9taW47CglzdGltZS53U2Vjb25kID0gdG0tPnRtX3NlYzsKCglyZXR1cm4gU3lzdGVtVGltZVRvRmlsZVRpbWUoJnN0aW1lLCBmdGltZSk7Cn0KCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5X3VuaXgoRW50cnkqIGRpciwgTFBDVFNUUiBwYXRoKQp7CglFbnRyeSogZmlyc3RfZW50cnkgPSBOVUxMOwoJRW50cnkqIGxhc3QgPSBOVUxMOwoJRW50cnkqIGVudHJ5OwoKCWludCBsZXZlbCA9IGRpci0+bGV2ZWwgKyAxOwoKCURJUiogcGRpciA9IG9wZW5kaXIocGF0aCk7CgoJaWYgKHBkaXIpIHsKCQlzdHJ1Y3Qgc3RhdCBzdDsKCQlzdHJ1Y3QgZGlyZW50KiBlbnQ7CgkJVENIQVIgYnVmZmVyW01BWF9QQVRIXSwgKnA7CgoJCWZvcihwPWJ1ZmZlcjsgKnBhdGg7ICkKCQkJKnArKyA9ICpwYXRoKys7CgoJCWlmIChwPT1idWZmZXIgfHwgcFstMV0hPScvJykKCQkJKnArKyA9ICcvJzsKCgkJd2hpbGUoKGVudD1yZWFkZGlyKHBkaXIpKSkgewoJCQllbnRyeSA9IGFsbG9jX2VudHJ5KCk7CgoJCQlpZiAoIWZpcnN0X2VudHJ5KQoJCQkJZmlyc3RfZW50cnkgPSBlbnRyeTsKCgkJCWlmIChsYXN0KQoJCQkJbGFzdC0+bmV4dCA9IGVudHJ5OwoKCQkJZW50cnktPmV0eXBlID0gRVRfVU5JWDsKCgkJCWxzdHJjcHkoZW50cnktPmRhdGEuY0ZpbGVOYW1lLCBlbnQtPmRfbmFtZSk7CgkJCWVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgPSBlbnQtPmRfbmFtZVswXT09Jy4nPyBGSUxFX0FUVFJJQlVURV9ISURERU46IDA7CgoJCQlzdHJjcHkocCwgZW50LT5kX25hbWUpOwoKCQkJaWYgKCFzdGF0KGJ1ZmZlciwgJnN0KSkgewoJCQkJaWYgKFNfSVNESVIoc3Quc3RfbW9kZSkpCgkJCQkJZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyB8PSBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk7CgoJCQkJZW50cnktPmRhdGEubkZpbGVTaXplTG93ID0gc3Quc3Rfc2l6ZSAmIDB4RkZGRkZGRkY7CgkJCQllbnRyeS0+ZGF0YS5uRmlsZVNpemVIaWdoID0gc3Quc3Rfc2l6ZSA+PiAzMjsKCgkJCQltZW1zZXQoJmVudHJ5LT5kYXRhLmZ0Q3JlYXRpb25UaW1lLCAwLCBzaXplb2YoRklMRVRJTUUpKTsKCQkJCXRpbWVfdG9fZmlsZXRpbWUoJnN0LnN0X2F0aW1lLCAmZW50cnktPmRhdGEuZnRMYXN0QWNjZXNzVGltZSk7CgkJCQl0aW1lX3RvX2ZpbGV0aW1lKCZzdC5zdF9tdGltZSwgJmVudHJ5LT5kYXRhLmZ0TGFzdFdyaXRlVGltZSk7CgoJCQkJZW50cnktPmJoZmkubkZpbGVJbmRleExvdyA9IGVudC0+ZF9pbm87CgkJCQllbnRyeS0+YmhmaS5uRmlsZUluZGV4SGlnaCA9IDA7CgoJCQkJZW50cnktPmJoZmkubk51bWJlck9mTGlua3MgPSBzdC5zdF9ubGluazsKCgkJCQllbnRyeS0+YmhmaV92YWxpZCA9IFRSVUU7CgkJCX0gZWxzZSB7CgkJCQllbnRyeS0+ZGF0YS5uRmlsZVNpemVMb3cgPSAwOwoJCQkJZW50cnktPmRhdGEubkZpbGVTaXplSGlnaCA9IDA7CgkJCQllbnRyeS0+YmhmaV92YWxpZCA9IEZBTFNFOwoJCQl9CgoJCQllbnRyeS0+ZG93biA9IE5VTEw7CgkJCWVudHJ5LT51cCA9IGRpcjsKCQkJZW50cnktPmV4cGFuZGVkID0gRkFMU0U7CgkJCWVudHJ5LT5zY2FubmVkID0gRkFMU0U7CgkJCWVudHJ5LT5sZXZlbCA9IGxldmVsOwoKCQkJbGFzdCA9IGVudHJ5OwoJCX0KCgkJbGFzdC0+bmV4dCA9IE5VTEw7CgoJCWNsb3NlZGlyKHBkaXIpOwoJfQoKCWRpci0+ZG93biA9IGZpcnN0X2VudHJ5OwoJZGlyLT5zY2FubmVkID0gVFJVRTsKfQoKc3RhdGljIEVudHJ5KiBmaW5kX2VudHJ5X3VuaXgoRW50cnkqIGRpciwgTFBDVFNUUiBuYW1lKQp7CglFbnRyeSogZW50cnk7CgoJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KSB7CgkJTFBDVFNUUiBwID0gbmFtZTsKCQlMUENUU1RSIHEgPSBlbnRyeS0+ZGF0YS5jRmlsZU5hbWU7CgoJCWRvIHsKCQkJaWYgKCEqcCB8fCAqcD09VEVYVCgnLycpKQoJCQkJcmV0dXJuIGVudHJ5OwoJCX0gd2hpbGUoKnArKyA9PSAqcSsrKTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIEVudHJ5KiByZWFkX3RyZWVfdW5peChSb290KiByb290LCBMUENUU1RSIHBhdGgsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF07CglFbnRyeSogZW50cnkgPSAmcm9vdC0+ZW50cnk7CglMUENUU1RSIHMgPSBwYXRoOwoJUFRTVFIgZCA9IGJ1ZmZlcjsKCglIQ1VSU09SIG9sZF9jdXJzb3IgPSBTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfV0FJVCkpOwoKCWVudHJ5LT5ldHlwZSA9IEVUX1VOSVg7CgoJd2hpbGUoZW50cnkpIHsKCQl3aGlsZSgqcyAmJiAqcyE9VEVYVCgnLycpKQoJCQkqZCsrID0gKnMrKzsKCgkJd2hpbGUoKnMgPT0gVEVYVCgnLycpKQoJCQlzKys7CgoJCSpkKysgPSBURVhUKCcvJyk7CgkJKmQgPSBURVhUKCdcMCcpOwoKCQlyZWFkX2RpcmVjdG9yeShlbnRyeSwgYnVmZmVyLCBzb3J0T3JkZXIsIGh3bmQpOwoKCQlpZiAoZW50cnktPmRvd24pCgkJCWVudHJ5LT5leHBhbmRlZCA9IFRSVUU7CgoJCWlmICghKnMpCgkJCWJyZWFrOwoKCQllbnRyeSA9IGZpbmRfZW50cnlfdW5peChlbnRyeSwgcyk7Cgl9CgoJU2V0Q3Vyc29yKG9sZF9jdXJzb3IpOwoKCXJldHVybiBlbnRyeTsKfQoKI2VuZGlmIC8qICFkZWZpbmVkKF9OT19FWFRFTlNJT05TKSAmJiBkZWZpbmVkKF9fV0lORV9fKSAqLwoKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoKI2lmZGVmIFVOSUNPREUKI2RlZmluZQl0Y3NjcHluIHN0cmNweW4KI2RlZmluZQlnZXRfc3RycmV0IGdldF9zdHJyZXRXCiNkZWZpbmUJcGF0aF9mcm9tX3BpZGwgcGF0aF9mcm9tX3BpZGxXCiNlbHNlCiNkZWZpbmUJdGNzY3B5biB3Y3NjcHluCiNkZWZpbmUJZ2V0X3N0cnJldCBnZXRfc3RycmV0QQojZGVmaW5lCXBhdGhfZnJvbV9waWRsIHBhdGhfZnJvbV9waWRsQQojZW5kaWYKCgpzdGF0aWMgTFBTVFIgc3RyY3B5bihMUFNUUiBkZXN0LCBMUENTVFIgc291cmNlLCBzaXplX3QgY291bnQpCnsKIExQQ1NUUiBzOwogTFBTVFIgZCA9IGRlc3Q7CgogZm9yKHM9c291cmNlOyBjb3VudCYmKCpkKys9KnMrKyk7ICkKICBjb3VudC0tOwoKIHJldHVybiBkZXN0Owp9CgpzdGF0aWMgTFBXU1RSIHdjc2NweW4oTFBXU1RSIGRlc3QsIExQQ1dTVFIgc291cmNlLCBzaXplX3QgY291bnQpCnsKIExQQ1dTVFIgczsKIExQV1NUUiBkID0gZGVzdDsKCiBmb3Iocz1zb3VyY2U7IGNvdW50JiYoKmQrKz0qcysrKTsgKQogIGNvdW50LS07CgogcmV0dXJuIGRlc3Q7Cn0KCgpzdGF0aWMgdm9pZCBnZXRfc3RycmV0QShTVFJSRVQqIHN0ciwgY29uc3QgU0hJVEVNSUQqIHNoaWlkLCBMUFNUUiBidWZmZXIsIGludCBsZW4pCnsKIHN3aXRjaChzdHItPnVUeXBlKSB7CiAgY2FzZSBTVFJSRVRfV1NUUjoKCVdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBzdHItPlVOSU9OX01FTUJFUihwT2xlU3RyKSwgLTEsIGJ1ZmZlciwgbGVuLCBOVUxMLCBOVUxMKTsKCWJyZWFrOwoKICBjYXNlIFNUUlJFVF9PRkZTRVQ6CglzdHJjcHluKGJ1ZmZlciwgKExQQ1NUUilzaGlpZCtzdHItPlVOSU9OX01FTUJFUih1T2Zmc2V0KSwgbGVuKTsKCWJyZWFrOwoKICBjYXNlIFNUUlJFVF9DU1RSOgoJc3RyY3B5bihidWZmZXIsIHN0ci0+VU5JT05fTUVNQkVSKGNTdHIpLCBsZW4pOwogfQp9CgpzdGF0aWMgdm9pZCBnZXRfc3RycmV0VyhTVFJSRVQqIHN0ciwgY29uc3QgU0hJVEVNSUQqIHNoaWlkLCBMUFdTVFIgYnVmZmVyLCBpbnQgbGVuKQp7CiBzd2l0Y2goc3RyLT51VHlwZSkgewogIGNhc2UgU1RSUkVUX1dTVFI6Cgl3Y3NjcHluKGJ1ZmZlciwgc3RyLT5VTklPTl9NRU1CRVIocE9sZVN0ciksIGxlbik7CglicmVhazsKCiAgY2FzZSBTVFJSRVRfT0ZGU0VUOgoJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIChMUENTVFIpc2hpaWQrc3RyLT5VTklPTl9NRU1CRVIodU9mZnNldCksIC0xLCBidWZmZXIsIGxlbik7CglicmVhazsKCiAgY2FzZSBTVFJSRVRfQ1NUUjoKCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzdHItPlVOSU9OX01FTUJFUihjU3RyKSwgLTEsIGJ1ZmZlciwgbGVuKTsKIH0KfQoKCnN0YXRpYyB2b2lkIGZyZWVfc3RycmV0KFNUUlJFVCogc3RyKQp7CglpZiAoc3RyLT51VHlwZSA9PSBTVFJSRVRfV1NUUikKCQkoKkdsb2JhbHMuaU1hbGxvYy0+bHBWdGJsLT5GcmVlKShHbG9iYWxzLmlNYWxsb2MsIHN0ci0+VU5JT05fTUVNQkVSKHBPbGVTdHIpKTsKfQoKCkhSRVNVTFQgbmFtZV9mcm9tX3BpZGwoSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQSVRFTUlETElTVCBwaWRsLCBMUFRTVFIgYnVmZmVyLCBpbnQgbGVuLCBTSEdETkYgZmxhZ3MpCnsKCVNUUlJFVCBzdHI7CgoJSFJFU1VMVCBociA9ICgqZm9sZGVyLT5scFZ0YmwtPkdldERpc3BsYXlOYW1lT2YpKGZvbGRlciwgcGlkbCwgZmxhZ3MsICZzdHIpOwoKCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJZ2V0X3N0cnJldCgmc3RyLCAmcGlkbC0+bWtpZCwgYnVmZmVyLCBsZW4pOwoJCWZyZWVfc3RycmV0KCZzdHIpOwoJfSBlbHNlCgkJYnVmZmVyWzBdID0gJ1wwJzsKCglyZXR1cm4gaHI7Cn0KCgpIUkVTVUxUIHBhdGhfZnJvbV9waWRsQShJU2hlbGxGb2xkZXIqIGZvbGRlciwgTFBJVEVNSURMSVNUIHBpZGwsIExQU1RSIGJ1ZmZlciwgaW50IGxlbikKewoJU1RSUkVUIHN0cjsKCgkgLyogU0hHRE5fRk9SUEFSU0lORzogZ2V0IGZ1bGwgcGF0aCBvZiBpZCBsaXN0ICovCglIUkVTVUxUIGhyID0gKCpmb2xkZXItPmxwVnRibC0+R2V0RGlzcGxheU5hbWVPZikoZm9sZGVyLCBwaWRsLCBTSEdETl9GT1JQQVJTSU5HLCAmc3RyKTsKCglpZiAoU1VDQ0VFREVEKGhyKSkgewoJCWdldF9zdHJyZXRBKCZzdHIsICZwaWRsLT5ta2lkLCBidWZmZXIsIGxlbik7CgkJZnJlZV9zdHJyZXQoJnN0cik7Cgl9IGVsc2UKCQlidWZmZXJbMF0gPSAnXDAnOwoKCXJldHVybiBocjsKfQoKSFJFU1VMVCBwYXRoX2Zyb21fcGlkbFcoSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQSVRFTUlETElTVCBwaWRsLCBMUFdTVFIgYnVmZmVyLCBpbnQgbGVuKQp7CglTVFJSRVQgc3RyOwoKCSAvKiBTSEdETl9GT1JQQVJTSU5HOiBnZXQgZnVsbCBwYXRoIG9mIGlkIGxpc3QgKi8KCUhSRVNVTFQgaHIgPSAoKmZvbGRlci0+bHBWdGJsLT5HZXREaXNwbGF5TmFtZU9mKShmb2xkZXIsIHBpZGwsIFNIR0ROX0ZPUlBBUlNJTkcsICZzdHIpOwoKCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJZ2V0X3N0cnJldFcoJnN0ciwgJnBpZGwtPm1raWQsIGJ1ZmZlciwgbGVuKTsKCQlmcmVlX3N0cnJldCgmc3RyKTsKCX0gZWxzZQoJCWJ1ZmZlclswXSA9ICdcMCc7CgoJcmV0dXJuIGhyOwp9CgoKIC8qIGNyZWF0ZSBhbiBpdGVtIGlkIGxpc3QgZnJvbSBhIGZpbGUgc3lzdGVtIHBhdGggKi8KCnN0YXRpYyBMUElURU1JRExJU1QgZ2V0X3BhdGhfcGlkbChMUFRTVFIgcGF0aCwgSFdORCBod25kKQp7CglMUElURU1JRExJU1QgcGlkbDsKCUhSRVNVTFQgaHI7CglVTE9ORyBsZW47CgojaWZkZWYgVU5JQ09ERQoJTFBXU1RSIGJ1ZmZlciA9IHBhdGg7CiNlbHNlCglXQ0hBUiBidWZmZXJbTUFYX1BBVEhdOwoJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHBhdGgsIC0xLCBidWZmZXIsIE1BWF9QQVRIKTsKI2VuZGlmCgoJaHIgPSAoKkdsb2JhbHMuaURlc2t0b3AtPmxwVnRibC0+UGFyc2VEaXNwbGF5TmFtZSkoR2xvYmFscy5pRGVza3RvcCwgaHduZCwgTlVMTCwgYnVmZmVyLCAmbGVuLCAmcGlkbCwgTlVMTCk7CglpZiAoRkFJTEVEKGhyKSkKCQlyZXR1cm4gTlVMTDsKCglyZXR1cm4gcGlkbDsKfQoKCiAvKiBjb252ZXJ0IGFuIGl0ZW0gaWQgbGlzdCBmcm9tIHJlbGF0aXZlIHRvIGFic29sdXRlICg9cmVsYXRpdmUgdG8gdGhlIGRlc2t0b3ApIGZvcm1hdCAqLwoKc3RhdGljIExQSVRFTUlETElTVCBnZXRfdG9fYWJzb2x1dGVfcGlkbChFbnRyeSogZW50cnksIEhXTkQgaHduZCkKewoJaWYgKGVudHJ5LT51cCAmJiBlbnRyeS0+dXAtPmV0eXBlPT1FVF9TSEVMTCkgewoJCUlTaGVsbEZvbGRlciogZm9sZGVyID0gZW50cnktPnVwLT5mb2xkZXI7CgkJV0NIQVIgYnVmZmVyW01BWF9QQVRIXTsKCgkJSFJFU1VMVCBociA9IHBhdGhfZnJvbV9waWRsVyhmb2xkZXIsIGVudHJ5LT5waWRsLCBidWZmZXIsIE1BWF9QQVRIKTsKCgkJaWYgKFNVQ0NFRURFRChocikpIHsKCQkJTFBJVEVNSURMSVNUIHBpZGw7CgkJCVVMT05HIGxlbjsKCgkJCWhyID0gKCpHbG9iYWxzLmlEZXNrdG9wLT5scFZ0YmwtPlBhcnNlRGlzcGxheU5hbWUpKEdsb2JhbHMuaURlc2t0b3AsIGh3bmQsIE5VTEwsIGJ1ZmZlciwgJmxlbiwgJnBpZGwsIE5VTEwpOwoKCQkJaWYgKFNVQ0NFRURFRChocikpCgkJCQlyZXR1cm4gcGlkbDsKCQl9Cgl9IGVsc2UgaWYgKGVudHJ5LT5ldHlwZSA9PSBFVF9XSU5ET1dTKSB7CgkJVENIQVIgcGF0aFtNQVhfUEFUSF07CgoJCWdldF9wYXRoKGVudHJ5LCBwYXRoKTsKCgkJcmV0dXJuIGdldF9wYXRoX3BpZGwocGF0aCwgaHduZCk7Cgl9IGVsc2UgaWYgKGVudHJ5LT5waWRsKQoJCXJldHVybiBJTENsb25lKGVudHJ5LT5waWRsKTsKCglyZXR1cm4gTlVMTDsKfQoKCkhJQ09OIGV4dHJhY3RfaWNvbihJU2hlbGxGb2xkZXIqIGZvbGRlciwgTFBDSVRFTUlETElTVCBwaWRsKQp7CglJRXh0cmFjdEljb24qIHBFeHRyYWN0OwoKCWlmIChTVUNDRUVERUQoKCpmb2xkZXItPmxwVnRibC0+R2V0VUlPYmplY3RPZikoZm9sZGVyLCAwLCAxLCAoTFBDSVRFTUlETElTVCopJnBpZGwsICZJSURfSUV4dHJhY3RJY29uLCAwLCAoTFBWT0lEKikmcEV4dHJhY3QpKSkgewoJCVRDSEFSIHBhdGhbX01BWF9QQVRIXTsKCQl1bnNpZ25lZCBmbGFnczsKCQlISUNPTiBoaWNvbjsKCQlpbnQgaWR4OwoKCQlpZiAoU1VDQ0VFREVEKCgqcEV4dHJhY3QtPmxwVnRibC0+R2V0SWNvbkxvY2F0aW9uKShwRXh0cmFjdCwgR0lMX0ZPUlNIRUxMLCBwYXRoLCBfTUFYX1BBVEgsICZpZHgsICZmbGFncykpKSB7CgkJCWlmICghKGZsYWdzICYgR0lMX05PVEZJTEVOQU1FKSkgewoJCQkJaWYgKGlkeCA9PSAtMSkKCQkJCQlpZHggPSAwOwkvKiBzcGVjaWFsIGNhc2UgZm9yIHNvbWUgY29udHJvbCBwYW5lbCBhcHBsaWNhdGlvbnMgKi8KCgkJCQlpZiAoKGludClFeHRyYWN0SWNvbkV4KHBhdGgsIGlkeCwgMCwgJmhpY29uLCAxKSA+IDApCgkJCQkJZmxhZ3MgJj0gfkdJTF9ET05UQ0FDSEU7CgkJCX0gZWxzZSB7CgkJCQlISUNPTiBoSWNvbkxhcmdlID0gMDsKCgkJCQlIUkVTVUxUIGhyID0gKCpwRXh0cmFjdC0+bHBWdGJsLT5FeHRyYWN0KShwRXh0cmFjdCwgcGF0aCwgaWR4LCAmaEljb25MYXJnZSwgJmhpY29uLCBNQUtFTE9ORygwLypHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYSUNPTikqLyxHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU01JQ09OKSkpOwoKCQkJCWlmIChTVUNDRUVERUQoaHIpKQoJCQkJCURlc3Ryb3lJY29uKGhJY29uTGFyZ2UpOwoJCQl9CgoJCQlyZXR1cm4gaGljb247CgkJfQoJfQoKCXJldHVybiAwOwp9CgoKc3RhdGljIEVudHJ5KiBmaW5kX2VudHJ5X3NoZWxsKEVudHJ5KiBkaXIsIExQSVRFTUlETElTVCBwaWRsKQp7CglFbnRyeSogZW50cnk7CgoJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KSB7CgkJaWYgKGVudHJ5LT5waWRsLT5ta2lkLmNiID09IHBpZGwtPm1raWQuY2IgJiYKCQkJIW1lbWNtcChlbnRyeS0+cGlkbCwgcGlkbCwgZW50cnktPnBpZGwtPm1raWQuY2IpKQoJCQlyZXR1cm4gZW50cnk7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBFbnRyeSogcmVhZF90cmVlX3NoZWxsKFJvb3QqIHJvb3QsIExQSVRFTUlETElTVCBwaWRsLCBTT1JUX09SREVSIHNvcnRPcmRlciwgSFdORCBod25kKQp7CglFbnRyeSogZW50cnkgPSAmcm9vdC0+ZW50cnk7CglFbnRyeSogbmV4dDsKCUxQSVRFTUlETElTVCBuZXh0X3BpZGwgPSBwaWRsOwoJSVNoZWxsRm9sZGVyKiBmb2xkZXI7CglJU2hlbGxGb2xkZXIqIGNoaWxkID0gTlVMTDsKCUhSRVNVTFQgaHI7CgoJSENVUlNPUiBvbGRfY3Vyc29yID0gU2V0Q3Vyc29yKExvYWRDdXJzb3IoMCwgSURDX1dBSVQpKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWVudHJ5LT5ldHlwZSA9IEVUX1NIRUxMOwojZW5kaWYKCglmb2xkZXIgPSBHbG9iYWxzLmlEZXNrdG9wOwoKCXdoaWxlKGVudHJ5KSB7CgkJZW50cnktPnBpZGwgPSBuZXh0X3BpZGw7CgkJZW50cnktPmZvbGRlciA9IGZvbGRlcjsKCgkJaWYgKCFwaWRsLT5ta2lkLmNiKQoJCQlicmVhazsKCgkJIC8qIGNvcHkgZmlyc3QgZWxlbWVudCBvZiBpdGVtIGlkbGlzdCAqLwoJCW5leHRfcGlkbCA9ICgqR2xvYmFscy5pTWFsbG9jLT5scFZ0YmwtPkFsbG9jKShHbG9iYWxzLmlNYWxsb2MsIHBpZGwtPm1raWQuY2Irc2l6ZW9mKFVTSE9SVCkpOwoJCW1lbWNweShuZXh0X3BpZGwsIHBpZGwsIHBpZGwtPm1raWQuY2IpOwoJCSgoTFBJVEVNSURMSVNUKSgoTFBCWVRFKW5leHRfcGlkbCtwaWRsLT5ta2lkLmNiKSktPm1raWQuY2IgPSAwOwoKCQlociA9ICgqZm9sZGVyLT5scFZ0YmwtPkJpbmRUb09iamVjdCkoZm9sZGVyLCBuZXh0X3BpZGwsIDAsICZJSURfSVNoZWxsRm9sZGVyLCAodm9pZCoqKSZjaGlsZCk7CgkJaWYgKCFTVUNDRUVERUQoaHIpKQoJCQlicmVhazsKCgkJcmVhZF9kaXJlY3RvcnkoZW50cnksIE5VTEwsIHNvcnRPcmRlciwgaHduZCk7CgoJCWlmIChlbnRyeS0+ZG93bikKCQkJZW50cnktPmV4cGFuZGVkID0gVFJVRTsKCgkJbmV4dCA9IGZpbmRfZW50cnlfc2hlbGwoZW50cnksIG5leHRfcGlkbCk7CgkJaWYgKCFuZXh0KQoJCQlicmVhazsKCgkJZm9sZGVyID0gY2hpbGQ7CgkJZW50cnkgPSBuZXh0OwoKCQkgLyogZ28gdG8gbmV4dCBlbGVtZW50ICovCgkJcGlkbCA9IChMUElURU1JRExJU1QpICgoTFBCWVRFKXBpZGwrcGlkbC0+bWtpZC5jYik7Cgl9CgoJU2V0Q3Vyc29yKG9sZF9jdXJzb3IpOwoKCXJldHVybiBlbnRyeTsKfQoKCnN0YXRpYyB2b2lkIGZpbGxfdzMyZmRhdGFfc2hlbGwoSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQQ0lURU1JRExJU1QgcGlkbCwgU0ZHQU9GIGF0dHJpYnMsIFdJTjMyX0ZJTkRfREFUQSogdzMyZmRhdGEpCnsKCWlmICghKGF0dHJpYnMgJiBTRkdBT19GSUxFU1lTVEVNKSB8fAoJCSAgRkFJTEVEKFNIR2V0RGF0YUZyb21JRExpc3QoZm9sZGVyLCBwaWRsLCBTSEdERklMX0ZJTkREQVRBLCB3MzJmZGF0YSwgc2l6ZW9mKFdJTjMyX0ZJTkRfREFUQSkpKSkgewoJCVdJTjMyX0ZJTEVfQVRUUklCVVRFX0RBVEEgZmFkOwoJCUlEYXRhT2JqZWN0KiBwRGF0YU9iajsKCgkJU1RHTUVESVVNIG1lZGl1bSA9IHswLCB7MH0sIDB9OwoJCUZPUk1BVEVUQyBmbXQgPSB7R2xvYmFscy5jZlN0ckZOYW1lLCAwLCBEVkFTUEVDVF9DT05URU5ULCAtMSwgVFlNRURfSEdMT0JBTH07CgoJCUhSRVNVTFQgaHIgPSAoKmZvbGRlci0+bHBWdGJsLT5HZXRVSU9iamVjdE9mKShmb2xkZXIsIDAsIDEsICZwaWRsLCAmSUlEX0lEYXRhT2JqZWN0LCAwLCAoTFBWT0lEKikmcERhdGFPYmopOwoKCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQlociA9ICgqcERhdGFPYmotPmxwVnRibC0+R2V0RGF0YSkocERhdGFPYmosICZmbXQsICZtZWRpdW0pOwoKCQkJKCpwRGF0YU9iai0+bHBWdGJsLT5SZWxlYXNlKShwRGF0YU9iaik7CgoJCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQkJTFBDVFNUUiBwYXRoID0gKExQQ1RTVFIpR2xvYmFsTG9jayhtZWRpdW0uVU5JT05fTUVNQkVSKGhHbG9iYWwpKTsKCQkJCVVJTlQgc2VtX29yZyA9IFNldEVycm9yTW9kZShTRU1fRkFJTENSSVRJQ0FMRVJST1JTKTsKCgkJCQlpZiAoR2V0RmlsZUF0dHJpYnV0ZXNFeChwYXRoLCBHZXRGaWxlRXhJbmZvU3RhbmRhcmQsICZmYWQpKSB7CgkJCQkJdzMyZmRhdGEtPmR3RmlsZUF0dHJpYnV0ZXMgPSBmYWQuZHdGaWxlQXR0cmlidXRlczsKCQkJCQl3MzJmZGF0YS0+ZnRDcmVhdGlvblRpbWUgPSBmYWQuZnRDcmVhdGlvblRpbWU7CgkJCQkJdzMyZmRhdGEtPmZ0TGFzdEFjY2Vzc1RpbWUgPSBmYWQuZnRMYXN0QWNjZXNzVGltZTsKCQkJCQl3MzJmZGF0YS0+ZnRMYXN0V3JpdGVUaW1lID0gZmFkLmZ0TGFzdFdyaXRlVGltZTsKCgkJCQkJaWYgKCEoZmFkLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpKSB7CgkJCQkJCXczMmZkYXRhLT5uRmlsZVNpemVMb3cgPSBmYWQubkZpbGVTaXplTG93OwoJCQkJCQl3MzJmZGF0YS0+bkZpbGVTaXplSGlnaCA9IGZhZC5uRmlsZVNpemVIaWdoOwoJCQkJCX0KCQkJCX0KCgkJCQlTZXRFcnJvck1vZGUoc2VtX29yZyk7CgoJCQkJR2xvYmFsVW5sb2NrKG1lZGl1bS5VTklPTl9NRU1CRVIoaEdsb2JhbCkpOwoJCQkJR2xvYmFsRnJlZShtZWRpdW0uVU5JT05fTUVNQkVSKGhHbG9iYWwpKTsKCQkJfQoJCX0KCX0KCglpZiAoYXR0cmlicyAmIChTRkdBT19GT0xERVJ8U0ZHQU9fSEFTU1VCRk9MREVSKSkKCQl3MzJmZGF0YS0+ZHdGaWxlQXR0cmlidXRlcyB8PSBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk7CgoJaWYgKGF0dHJpYnMgJiBTRkdBT19SRUFET05MWSkKCQl3MzJmZGF0YS0+ZHdGaWxlQXR0cmlidXRlcyB8PSBGSUxFX0FUVFJJQlVURV9SRUFET05MWTsKCglpZiAoYXR0cmlicyAmIFNGR0FPX0NPTVBSRVNTRUQpCgkJdzMyZmRhdGEtPmR3RmlsZUF0dHJpYnV0ZXMgfD0gRklMRV9BVFRSSUJVVEVfQ09NUFJFU1NFRDsKfQoKCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5X3NoZWxsKEVudHJ5KiBkaXIsIEhXTkQgaHduZCkKewoJSVNoZWxsRm9sZGVyKiBmb2xkZXIgPSBkaXItPmZvbGRlcjsKCWludCBsZXZlbCA9IGRpci0+bGV2ZWwgKyAxOwoJSFJFU1VMVCBocjsKCglJU2hlbGxGb2xkZXIqIGNoaWxkOwoJSUVudW1JRExpc3QqIGlkbGlzdDsKCglFbnRyeSogZmlyc3RfZW50cnkgPSBOVUxMOwoJRW50cnkqIGxhc3QgPSBOVUxMOwoJRW50cnkqIGVudHJ5OwoKCWlmICghZm9sZGVyKQoJCXJldHVybjsKCglociA9ICgqZm9sZGVyLT5scFZ0YmwtPkVudW1PYmplY3RzKShmb2xkZXIsIGh3bmQsIFNIQ09OVEZfRk9MREVSU3xTSENPTlRGX05PTkZPTERFUlN8U0hDT05URl9JTkNMVURFSElEREVOfFNIQ09OVEZfU0hBUkVBQkxFfFNIQ09OVEZfU1RPUkFHRSwgJmlkbGlzdCk7CgoJaWYgKFNVQ0NFRURFRChocikpIHsKCQlmb3IoOzspIHsKI2RlZmluZQlGRVRDSF9JVEVNX0NPVU5UCTMyCgkJCUxQSVRFTUlETElTVCBwaWRsc1tGRVRDSF9JVEVNX0NPVU5UXTsKCQkJU0ZHQU9GIGF0dHJpYnM7CgkJCVVMT05HIGNudCA9IDA7CgkJCVVMT05HIG47CgoJCQltZW1zZXQocGlkbHMsIDAsIHNpemVvZihwaWRscykpOwoKCQkJaHIgPSAoKmlkbGlzdC0+bHBWdGJsLT5OZXh0KShpZGxpc3QsIEZFVENIX0lURU1fQ09VTlQsIHBpZGxzLCAmY250KTsKCQkJaWYgKCFTVUNDRUVERUQoaHIpKQoJCQkJYnJlYWs7CgoJCQlpZiAoaHIgPT0gU19GQUxTRSkKCQkJCWJyZWFrOwoKCQkJZm9yKG49MDsgbjxjbnQ7ICsrbikgewoJCQkJZW50cnkgPSBhbGxvY19lbnRyeSgpOwoKCQkJCWlmICghZmlyc3RfZW50cnkpCgkJCQkJZmlyc3RfZW50cnkgPSBlbnRyeTsKCgkJCQlpZiAobGFzdCkKCQkJCQlsYXN0LT5uZXh0ID0gZW50cnk7CgoJCQkJbWVtc2V0KCZlbnRyeS0+ZGF0YSwgMCwgc2l6ZW9mKFdJTjMyX0ZJTkRfREFUQSkpOwoJCQkJZW50cnktPmJoZmlfdmFsaWQgPSBGQUxTRTsKCgkJCQlhdHRyaWJzID0gflNGR0FPX0ZJTEVTWVNURU07CS8qU0ZHQU9fSEFTU1VCRk9MREVSfFNGR0FPX0ZPTERFUjsgU0ZHQU9fRklMRVNZU1RFTSBzb3JndCBkYWb8ciwgZGHfICJNeSBEb2N1bWVudHMiIGFuc3RhdHQgdm9uICJNYXJ0aW4ncyBEb2N1bWVudHMiIGFuZ2V6ZWlndCB3aXJkICovCgoJCQkJaHIgPSAoKmZvbGRlci0+bHBWdGJsLT5HZXRBdHRyaWJ1dGVzT2YpKGZvbGRlciwgMSwgKExQQ0lURU1JRExJU1QqKSZwaWRsc1tuXSwgJmF0dHJpYnMpOwoKCQkJCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJCQkJaWYgKGF0dHJpYnMgIT0gKFNGR0FPRil+U0ZHQU9fRklMRVNZU1RFTSkgewoJCQkJCQlmaWxsX3czMmZkYXRhX3NoZWxsKGZvbGRlciwgcGlkbHNbbl0sIGF0dHJpYnMsICZlbnRyeS0+ZGF0YSk7CgoJCQkJCQllbnRyeS0+YmhmaV92YWxpZCA9IFRSVUU7CgkJCQkJfSBlbHNlCgkJCQkJCWF0dHJpYnMgPSAwOwoJCQkJfSBlbHNlCgkJCQkJYXR0cmlicyA9IDA7CgoJCQkJZW50cnktPnBpZGwgPSBwaWRsc1tuXTsKCgkJCQlpZiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJCWhyID0gKCpmb2xkZXItPmxwVnRibC0+QmluZFRvT2JqZWN0KShmb2xkZXIsIHBpZGxzW25dLCAwLCAmSUlEX0lTaGVsbEZvbGRlciwgKHZvaWQqKikmY2hpbGQpOwoKCQkJCQlpZiAoU1VDQ0VFREVEKGhyKSkKCQkJCQkJZW50cnktPmZvbGRlciA9IGNoaWxkOwoJCQkJCWVsc2UKCQkJCQkJZW50cnktPmZvbGRlciA9IE5VTEw7CgkJCQl9CgkJCQllbHNlCgkJCQkJZW50cnktPmZvbGRlciA9IE5VTEw7CgoJCQkJaWYgKCFlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF0pCgkJCQkJLypociA9ICovbmFtZV9mcm9tX3BpZGwoZm9sZGVyLCBwaWRsc1tuXSwgZW50cnktPmRhdGEuY0ZpbGVOYW1lLCBNQVhfUEFUSCwgLypTSEdETl9JTkZPTERFUiovMHgyMDAwLyoweDIwMDA9U0hHRE5fSU5DTFVERV9OT05GSUxFU1lTKi8pOwoKCQkJCSAvKiBnZXQgZGlzcGxheSBpY29ucyBmb3IgZmlsZXMgYW5kIHZpcnR1YWwgb2JqZWN0cyAqLwoJCQkJaWYgKCEoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgfHwKCQkJCQkhKGF0dHJpYnMgJiBTRkdBT19GSUxFU1lTVEVNKSkgewoJCQkJCWVudHJ5LT5oaWNvbiA9IGV4dHJhY3RfaWNvbihmb2xkZXIsIHBpZGxzW25dKTsKCgkJCQkJaWYgKCFlbnRyeS0+aGljb24pCgkJCQkJCWVudHJ5LT5oaWNvbiA9IChISUNPTiktMTsJLyogZG9uJ3QgdHJ5IGFnYWluIGxhdGVyICovCgkJCQl9CgoJCQkJZW50cnktPmRvd24gPSBOVUxMOwoJCQkJZW50cnktPnVwID0gZGlyOwoJCQkJZW50cnktPmV4cGFuZGVkID0gRkFMU0U7CgkJCQllbnRyeS0+c2Nhbm5lZCA9IEZBTFNFOwoJCQkJZW50cnktPmxldmVsID0gbGV2ZWw7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCQllbnRyeS0+ZXR5cGUgPSBFVF9TSEVMTDsKCQkJCWVudHJ5LT5iaGZpX3ZhbGlkID0gRkFMU0U7CiNlbmRpZgoKCQkJCWxhc3QgPSBlbnRyeTsKCQkJfQoJCX0KCgkJKCppZGxpc3QtPmxwVnRibC0+UmVsZWFzZSkoaWRsaXN0KTsKCX0KCglpZiAobGFzdCkKCQlsYXN0LT5uZXh0ID0gTlVMTDsKCglkaXItPmRvd24gPSBmaXJzdF9lbnRyeTsKCWRpci0+c2Nhbm5lZCA9IFRSVUU7Cn0KCiNlbmRpZiAvKiBfU0hFTExfRk9MREVSUyAqLwoKCi8qIHNvcnQgb3JkZXIgZm9yIGRpZmZlcmVudCBkaXJlY3RvcnkvZmlsZSB0eXBlcyAqLwplbnVtIFRZUEVfT1JERVIgewoJVE9fRElSID0gMCwKCVRPX0RPVCA9IDEsCglUT19ET1RET1QgPSAyLAoJVE9fT1RIRVJfRElSID0gMywKCVRPX0ZJTEUgPSA0Cn07CgovKiBkaXN0aW5ndWlzaCBiZXR3ZWVuICIuIiwgIi4uIiBhbmQgYW55IG90aGVyIGRpcmVjdG9yeSBuYW1lcyAqLwpzdGF0aWMgaW50IFR5cGVPcmRlckZyb21EaXJuYW1lKExQQ1RTVFIgbmFtZSkKewoJaWYgKG5hbWVbMF0gPT0gJy4nKSB7CgkJaWYgKG5hbWVbMV0gPT0gJ1wwJykKCQkJcmV0dXJuIFRPX0RPVDsJLyogIi4iICovCgoJCWlmIChuYW1lWzFdPT0nLicgJiYgbmFtZVsyXT09J1wwJykKCQkJcmV0dXJuIFRPX0RPVERPVDsJLyogIi4uIiAqLwoJfQoKCXJldHVybiBUT19PVEhFUl9ESVI7CS8qIGFueXRoaW5nIGVsc2UgKi8KfQoKLyogZGlyZWN0b3JpZXMgZmlyc3QuLi4gKi8Kc3RhdGljIGludCBjb21wYXJlVHlwZShjb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMSwgY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDIpCnsKCWludCBvcmRlcjEgPSBmZDEtPmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk/IFRPX0RJUjogVE9fRklMRTsKCWludCBvcmRlcjIgPSBmZDItPmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk/IFRPX0RJUjogVE9fRklMRTsKCgkvKiBIYW5kbGUgIi4iIGFuZCAiLi4iIGFzIHNwZWNpYWwgY2FzZSBhbmQgbW92ZSB0aGVtIGF0IHRoZSB2ZXJ5IGZpcnN0IGJlZ2lubmluZy4gKi8KCWlmIChvcmRlcjE9PVRPX0RJUiAmJiBvcmRlcjI9PVRPX0RJUikgewoJCW9yZGVyMSA9IFR5cGVPcmRlckZyb21EaXJuYW1lKGZkMS0+Y0ZpbGVOYW1lKTsKCQlvcmRlcjIgPSBUeXBlT3JkZXJGcm9tRGlybmFtZShmZDItPmNGaWxlTmFtZSk7Cgl9CgoJcmV0dXJuIG9yZGVyMj09b3JkZXIxPyAwOiBvcmRlcjE8b3JkZXIyPyAtMTogMTsKfQoKCnN0YXRpYyBpbnQgY29tcGFyZU5hbWUoY29uc3Qgdm9pZCogYXJnMSwgY29uc3Qgdm9pZCogYXJnMikKewoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDEgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcxKS0+ZGF0YTsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQyID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMiktPmRhdGE7CgoJaW50IGNtcCA9IGNvbXBhcmVUeXBlKGZkMSwgZmQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCglyZXR1cm4gbHN0cmNtcGkoZmQxLT5jRmlsZU5hbWUsIGZkMi0+Y0ZpbGVOYW1lKTsKfQoKc3RhdGljIGludCBjb21wYXJlRXh0KGNvbnN0IHZvaWQqIGFyZzEsIGNvbnN0IHZvaWQqIGFyZzIpCnsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQxID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMSktPmRhdGE7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMiA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzIpLT5kYXRhOwoJY29uc3QgVENIQVIgKm5hbWUxLCAqbmFtZTIsICpleHQxLCAqZXh0MjsKCglpbnQgY21wID0gY29tcGFyZVR5cGUoZmQxLCBmZDIpOwoJaWYgKGNtcCkKCQlyZXR1cm4gY21wOwoKCW5hbWUxID0gZmQxLT5jRmlsZU5hbWU7CgluYW1lMiA9IGZkMi0+Y0ZpbGVOYW1lOwoKCWV4dDEgPSBfdGNzcmNocihuYW1lMSwgVEVYVCgnLicpKTsKCWV4dDIgPSBfdGNzcmNocihuYW1lMiwgVEVYVCgnLicpKTsKCglpZiAoZXh0MSkKCQlleHQxKys7CgllbHNlCgkJZXh0MSA9IHNFbXB0eTsKCglpZiAoZXh0MikKCQlleHQyKys7CgllbHNlCgkJZXh0MiA9IHNFbXB0eTsKCgljbXAgPSBsc3RyY21waShleHQxLCBleHQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCglyZXR1cm4gbHN0cmNtcGkobmFtZTEsIG5hbWUyKTsKfQoKc3RhdGljIGludCBjb21wYXJlU2l6ZShjb25zdCB2b2lkKiBhcmcxLCBjb25zdCB2b2lkKiBhcmcyKQp7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMSA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzEpLT5kYXRhOwoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDIgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcyKS0+ZGF0YTsKCglpbnQgY21wID0gY29tcGFyZVR5cGUoZmQxLCBmZDIpOwoJaWYgKGNtcCkKCQlyZXR1cm4gY21wOwoKCWNtcCA9IGZkMi0+bkZpbGVTaXplSGlnaCAtIGZkMS0+bkZpbGVTaXplSGlnaDsKCglpZiAoY21wIDwgMCkKCQlyZXR1cm4gLTE7CgllbHNlIGlmIChjbXAgPiAwKQoJCXJldHVybiAxOwoKCWNtcCA9IGZkMi0+bkZpbGVTaXplTG93IC0gZmQxLT5uRmlsZVNpemVMb3c7CgoJcmV0dXJuIGNtcDwwPyAtMTogY21wPjA/IDE6IDA7Cn0KCnN0YXRpYyBpbnQgY29tcGFyZURhdGUoY29uc3Qgdm9pZCogYXJnMSwgY29uc3Qgdm9pZCogYXJnMikKewoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDEgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcxKS0+ZGF0YTsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQyID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMiktPmRhdGE7CgoJaW50IGNtcCA9IGNvbXBhcmVUeXBlKGZkMSwgZmQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCglyZXR1cm4gQ29tcGFyZUZpbGVUaW1lKCZmZDItPmZ0TGFzdFdyaXRlVGltZSwgJmZkMS0+ZnRMYXN0V3JpdGVUaW1lKTsKfQoKCnN0YXRpYyBpbnQgKCpzb3J0RnVuY3Rpb25zW10pKGNvbnN0IHZvaWQqIGFyZzEsIGNvbnN0IHZvaWQqIGFyZzIpID0gewoJY29tcGFyZU5hbWUsCS8qIFNPUlRfTkFNRSAqLwoJY29tcGFyZUV4dCwJCS8qIFNPUlRfRVhUICovCgljb21wYXJlU2l6ZSwJLyogU09SVF9TSVpFICovCgljb21wYXJlRGF0ZQkJLyogU09SVF9EQVRFICovCn07CgoKc3RhdGljIHZvaWQgU29ydERpcmVjdG9yeShFbnRyeSogZGlyLCBTT1JUX09SREVSIHNvcnRPcmRlcikKewoJRW50cnkqIGVudHJ5ID0gZGlyLT5kb3duOwoJRW50cnkqKiBhcnJheSwgKipwOwoJaW50IGxlbjsKCglsZW4gPSAwOwoJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KQoJCWxlbisrOwoKCWlmIChsZW4pIHsKCQlhcnJheSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4qc2l6ZW9mKEVudHJ5KikpOwoKCQlwID0gYXJyYXk7CgkJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KQoJCQkqcCsrID0gZW50cnk7CgoJCS8qIGNhbGwgcXNvcnQgd2l0aCB0aGUgYXBwcm9wcmlhdGUgY29tcGFyZSBmdW5jdGlvbiAqLwoJCXFzb3J0KGFycmF5LCBsZW4sIHNpemVvZihhcnJheVswXSksIHNvcnRGdW5jdGlvbnNbc29ydE9yZGVyXSk7CgoJCWRpci0+ZG93biA9IGFycmF5WzBdOwoKCQlmb3IocD1hcnJheTsgLS1sZW47IHArKykKCQkJcFswXS0+bmV4dCA9IHBbMV07CgoJCSgqcCktPm5leHQgPSAwOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGFycmF5ICk7Cgl9Cn0KCgpzdGF0aWMgdm9pZCByZWFkX2RpcmVjdG9yeShFbnRyeSogZGlyLCBMUENUU1RSIHBhdGgsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF07CglFbnRyeSogZW50cnk7CglMUENUU1RSIHM7CglQVFNUUiBkOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglpZiAoZGlyLT5ldHlwZSA9PSBFVF9TSEVMTCkKCXsKCQlyZWFkX2RpcmVjdG9yeV9zaGVsbChkaXIsIGh3bmQpOwoKCQlpZiAoR2xvYmFscy5wcmVzY2FuX25vZGUpIHsKCQkJcyA9IHBhdGg7CgkJCWQgPSBidWZmZXI7CgoJCQl3aGlsZSgqcykKCQkJCSpkKysgPSAqcysrOwoKCQkJKmQrKyA9IFRFWFQoJ1xcJyk7CgoJCQlmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpCgkJCQlpZiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJCXJlYWRfZGlyZWN0b3J5X3NoZWxsKGVudHJ5LCBod25kKTsKCQkJCQlTb3J0RGlyZWN0b3J5KGVudHJ5LCBzb3J0T3JkZXIpOwoJCQkJfQoJCX0KCX0KCWVsc2UKI2VuZGlmCiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCWlmIChkaXItPmV0eXBlID09IEVUX1VOSVgpCgl7CgkJcmVhZF9kaXJlY3RvcnlfdW5peChkaXIsIHBhdGgpOwoKCQlpZiAoR2xvYmFscy5wcmVzY2FuX25vZGUpIHsKCQkJcyA9IHBhdGg7CgkJCWQgPSBidWZmZXI7CgoJCQl3aGlsZSgqcykKCQkJCSpkKysgPSAqcysrOwoKCQkJKmQrKyA9IFRFWFQoJy8nKTsKCgkJCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQkJCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCQkJbHN0cmNweShkLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpOwoJCQkJCXJlYWRfZGlyZWN0b3J5X3VuaXgoZW50cnksIGJ1ZmZlcik7CgkJCQkJU29ydERpcmVjdG9yeShlbnRyeSwgc29ydE9yZGVyKTsKCQkJCX0KCQl9Cgl9CgllbHNlCiNlbmRpZgoJewoJCXJlYWRfZGlyZWN0b3J5X3dpbihkaXIsIHBhdGgpOwoKCQlpZiAoR2xvYmFscy5wcmVzY2FuX25vZGUpIHsKCQkJcyA9IHBhdGg7CgkJCWQgPSBidWZmZXI7CgoJCQl3aGlsZSgqcykKCQkJCSpkKysgPSAqcysrOwoKCQkJKmQrKyA9IFRFWFQoJ1xcJyk7CgoJCQlmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpCgkJCQlpZiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJCWxzdHJjcHkoZCwgZW50cnktPmRhdGEuY0ZpbGVOYW1lKTsKCQkJCQlyZWFkX2RpcmVjdG9yeV93aW4oZW50cnksIGJ1ZmZlcik7CgkJCQkJU29ydERpcmVjdG9yeShlbnRyeSwgc29ydE9yZGVyKTsKCQkJCX0KCQl9Cgl9CgoJU29ydERpcmVjdG9yeShkaXIsIHNvcnRPcmRlcik7Cn0KCgpzdGF0aWMgQ2hpbGRXbmQqIGFsbG9jX2NoaWxkX3dpbmRvdyhMUENUU1RSIHBhdGgsIExQSVRFTUlETElTVCBwaWRsLCBIV05EIGh3bmQpCnsKCWNvbnN0IHN0YXRpYyBUQ0hBUiBzQmFja3NsYXNoW10gPSB7J1xcJywgJ1wwJ307CiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCWNvbnN0IHN0YXRpYyBUQ0hBUiBzU2xhc2hbXSA9IHsnLycsICdcMCd9OwojZW5kaWYKCglUQ0hBUiBkcnZbX01BWF9EUklWRSsxXSwgZGlyW19NQVhfRElSXSwgbmFtZVtfTUFYX0ZOQU1FXSwgZXh0W19NQVhfRVhUXTsKCVRDSEFSIGIxW0JVRkZFUl9MRU5dOwoKCUNoaWxkV25kKiBjaGlsZCA9IChDaGlsZFduZCopIG1hbGxvYyhzaXplb2YoQ2hpbGRXbmQpKTsKCVJvb3QqIHJvb3QgPSAmY2hpbGQtPnJvb3Q7CglFbnRyeSogZW50cnk7CgoJbWVtc2V0KGNoaWxkLCAwLCBzaXplb2YoQ2hpbGRXbmQpKTsKCgljaGlsZC0+bGVmdC50cmVlUGFuZSA9IFRSVUU7CgljaGlsZC0+bGVmdC52aXNpYmxlX2NvbHMgPSAwOwoKCWNoaWxkLT5yaWdodC50cmVlUGFuZSA9IEZBTFNFOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgljaGlsZC0+cmlnaHQudmlzaWJsZV9jb2xzID0gQ09MX1NJWkV8Q09MX0RBVEV8Q09MX1RJTUV8Q09MX0FUVFJJQlVURVN8Q09MX0lOREVYfENPTF9MSU5LUzsKI2Vsc2UKCWNoaWxkLT5yaWdodC52aXNpYmxlX2NvbHMgPSBDT0xfU0laRXxDT0xfREFURXxDT0xfVElNRXxDT0xfQVRUUklCVVRFUzsKI2VuZGlmCgoJY2hpbGQtPnBvcy5sZW5ndGggPSBzaXplb2YoV0lORE9XUExBQ0VNRU5UKTsKCWNoaWxkLT5wb3MuZmxhZ3MgPSAwOwoJY2hpbGQtPnBvcy5zaG93Q21kID0gU1dfU0hPV05PUk1BTDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5sZWZ0ID0gQ1dfVVNFREVGQVVMVDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi50b3AgPSBDV19VU0VERUZBVUxUOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLnJpZ2h0ID0gQ1dfVVNFREVGQVVMVDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5ib3R0b20gPSBDV19VU0VERUZBVUxUOwoKCWNoaWxkLT5mb2N1c19wYW5lID0gMDsKCWNoaWxkLT5zcGxpdF9wb3MgPSBERUZBVUxUX1NQTElUX1BPUzsKCWNoaWxkLT5zb3J0T3JkZXIgPSBTT1JUX05BTUU7CgljaGlsZC0+aGVhZGVyX3dkdGhzX29rID0gRkFMU0U7CgoJaWYgKHBhdGgpCgl7CgkJbHN0cmNweShjaGlsZC0+cGF0aCwgcGF0aCk7CgoJCV90c3BsaXRwYXRoKHBhdGgsIGRydiwgZGlyLCBuYW1lLCBleHQpOwoJfQoKCXJvb3QtPmVudHJ5LmxldmVsID0gMDsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKHBpZGwpCgl7CgkJcm9vdC0+ZHJpdmVfdHlwZSA9IERSSVZFX1VOS05PV047CgkJZHJ2WzBdID0gJ1xcJzsKCQlkcnZbMV0gPSAnXDAnOwoJCWxvYWRfc3RyaW5nKHJvb3QtPnZvbG5hbWUsIElEU19ERVNLVE9QKTsKCQlyb290LT5mc19mbGFncyA9IDA7CgkJbG9hZF9zdHJpbmcocm9vdC0+ZnMsIElEU19TSEVMTCk7CgoJCWVudHJ5ID0gcmVhZF90cmVlX3NoZWxsKHJvb3QsIHBpZGwsIGNoaWxkLT5zb3J0T3JkZXIsIGh3bmQpOwoJfQoJZWxzZQojZW5kaWYKI2lmICFkZWZpbmVkKF9OT19FWFRFTlNJT05TKSAmJiBkZWZpbmVkKF9fV0lORV9fKQoJaWYgKCpwYXRoID09ICcvJykKCXsKCQlyb290LT5kcml2ZV90eXBlID0gR2V0RHJpdmVUeXBlKHBhdGgpOwoKCQlsc3RyY2F0KGRydiwgc1NsYXNoKTsKCQlsb2FkX3N0cmluZyhyb290LT52b2xuYW1lLCBJRFNfUk9PVF9GUyk7CgkJcm9vdC0+ZnNfZmxhZ3MgPSAwOwoJCWxvYWRfc3RyaW5nKHJvb3QtPmZzLCBJRFNfVU5JWEZTKTsKCgkJbHN0cmNweShyb290LT5wYXRoLCBzU2xhc2gpOwoJCWVudHJ5ID0gcmVhZF90cmVlX3VuaXgocm9vdCwgcGF0aCwgY2hpbGQtPnNvcnRPcmRlciwgaHduZCk7Cgl9CgllbHNlCiNlbmRpZgoJewoJCXJvb3QtPmRyaXZlX3R5cGUgPSBHZXREcml2ZVR5cGUocGF0aCk7CgoJCWxzdHJjYXQoZHJ2LCBzQmFja3NsYXNoKTsKCQlHZXRWb2x1bWVJbmZvcm1hdGlvbihkcnYsIHJvb3QtPnZvbG5hbWUsIF9NQVhfRk5BTUUsIDAsIDAsICZyb290LT5mc19mbGFncywgcm9vdC0+ZnMsIF9NQVhfRElSKTsKCgkJbHN0cmNweShyb290LT5wYXRoLCBkcnYpOwoJCWVudHJ5ID0gcmVhZF90cmVlX3dpbihyb290LCBwYXRoLCBjaGlsZC0+c29ydE9yZGVyLCBod25kKTsKCX0KCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKHJvb3QtPmVudHJ5LmV0eXBlID09IEVUX1NIRUxMKQoJCWxvYWRfc3RyaW5nKHJvb3QtPmVudHJ5LmRhdGEuY0ZpbGVOYW1lLCBJRFNfREVTS1RPUCk7CgllbHNlCiNlbmRpZgoJCXdzcHJpbnRmKHJvb3QtPmVudHJ5LmRhdGEuY0ZpbGVOYW1lLCBSUyhiMSxJRFNfVElUTEVGTVQpLCBkcnYsIHJvb3QtPmZzKTsKCglyb290LT5lbnRyeS5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgPSBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk7CgoJY2hpbGQtPmxlZnQucm9vdCA9ICZyb290LT5lbnRyeTsKCWNoaWxkLT5yaWdodC5yb290ID0gTlVMTDsKCglzZXRfY3VyZGlyKGNoaWxkLCBlbnRyeSwgaHduZCk7CgoJcmV0dXJuIGNoaWxkOwp9CgoKLyogZnJlZSBhbGwgbWVtb3J5IGFzc29jaWF0ZWQgd2l0aCBhIGNoaWxkIHdpbmRvdyAqLwpzdGF0aWMgdm9pZCBmcmVlX2NoaWxkX3dpbmRvdyhDaGlsZFduZCogY2hpbGQpCnsKCWZyZWVfZW50cmllcygmY2hpbGQtPnJvb3QuZW50cnkpOwoJZnJlZShjaGlsZCk7Cn0KCgovKiBnZXQgZnVsbCBwYXRoIG9mIHNwZWNpZmllZCBkaXJlY3RvcnkgZW50cnkgKi8Kc3RhdGljIHZvaWQgZ2V0X3BhdGgoRW50cnkqIGRpciwgUFRTVFIgcGF0aCkKewoJRW50cnkqIGVudHJ5OwoJaW50IGxlbiA9IDA7CglpbnQgbGV2ZWwgPSAwOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglpZiAoZGlyLT5ldHlwZSA9PSBFVF9TSEVMTCkKCXsKCQlTRkdBT0YgYXR0cmliczsKCQlIUkVTVUxUIGhyID0gU19PSzsKCgkJcGF0aFswXSA9IFRFWFQoJ1wwJyk7CgoJCWF0dHJpYnMgPSAwOwoKCQlpZiAoZGlyLT5mb2xkZXIpCgkJCWhyID0gKCpkaXItPmZvbGRlci0+bHBWdGJsLT5HZXRBdHRyaWJ1dGVzT2YpKGRpci0+Zm9sZGVyLCAxLCAoTFBDSVRFTUlETElTVCopJmRpci0+cGlkbCwgJmF0dHJpYnMpOwoKCQlpZiAoU1VDQ0VFREVEKGhyKSAmJiAoYXR0cmlicyZTRkdBT19GSUxFU1lTVEVNKSkgewoJCQlJU2hlbGxGb2xkZXIqIHBhcmVudCA9IGRpci0+dXA/IGRpci0+dXAtPmZvbGRlcjogR2xvYmFscy5pRGVza3RvcDsKCgkJCWhyID0gcGF0aF9mcm9tX3BpZGwocGFyZW50LCBkaXItPnBpZGwsIHBhdGgsIE1BWF9QQVRIKTsKCQl9Cgl9CgllbHNlCiNlbmRpZgoJewoJCWZvcihlbnRyeT1kaXI7IGVudHJ5OyBsZXZlbCsrKSB7CgkJCUxQQ1RTVFIgbmFtZTsKCQkJaW50IGw7CgoJCQl7CgkJCQlMUENUU1RSIHM7CgkJCQluYW1lID0gZW50cnktPmRhdGEuY0ZpbGVOYW1lOwoJCQkJcyA9IG5hbWU7CgoJCQkJZm9yKGw9MDsgKnMgJiYgKnMhPVRFWFQoJy8nKSAmJiAqcyE9VEVYVCgnXFwnKTsgcysrKQoJCQkJCWwrKzsKCQkJfQoKCQkJaWYgKGVudHJ5LT51cCkgewoJCQkJaWYgKGwgPiAwKSB7CgkJCQkJbWVtbW92ZShwYXRoK2wrMSwgcGF0aCwgbGVuKnNpemVvZihUQ0hBUikpOwoJCQkJCW1lbWNweShwYXRoKzEsIG5hbWUsIGwqc2l6ZW9mKFRDSEFSKSk7CgkJCQkJbGVuICs9IGwrMTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJCQlpZiAoZW50cnktPmV0eXBlID09IEVUX1VOSVgpCgkJCQkJCXBhdGhbMF0gPSBURVhUKCcvJyk7CgkJCQkJZWxzZQojZW5kaWYKCQkJCQlwYXRoWzBdID0gVEVYVCgnXFwnKTsKCQkJCX0KCgkJCQllbnRyeSA9IGVudHJ5LT51cDsKCQkJfSBlbHNlIHsKCQkJCW1lbW1vdmUocGF0aCtsLCBwYXRoLCBsZW4qc2l6ZW9mKFRDSEFSKSk7CgkJCQltZW1jcHkocGF0aCwgbmFtZSwgbCpzaXplb2YoVENIQVIpKTsKCQkJCWxlbiArPSBsOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCWlmICghbGV2ZWwpIHsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQlpZiAoZW50cnktPmV0eXBlID09IEVUX1VOSVgpCgkJCQlwYXRoW2xlbisrXSA9IFRFWFQoJy8nKTsKCQkJZWxzZQojZW5kaWYKCQkJCXBhdGhbbGVuKytdID0gVEVYVCgnXFwnKTsKCQl9CgoJCXBhdGhbbGVuXSA9IFRFWFQoJ1wwJyk7Cgl9Cn0KCgpzdGF0aWMgdm9pZCByZXNpemVfZnJhbWVfcmVjdChIV05EIGh3bmQsIFBSRUNUIHByZWN0KQp7CglpbnQgbmV3X3RvcDsKCVJFQ1QgcnQ7CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmh0b29sYmFyKSkgewoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaHRvb2xiYXIsIFdNX1NJWkUsIDAsIDApOwoJCUdldENsaWVudFJlY3QoR2xvYmFscy5odG9vbGJhciwgJnJ0KTsKCQlwcmVjdC0+dG9wID0gcnQuYm90dG9tKzM7CgkJcHJlY3QtPmJvdHRvbSAtPSBydC5ib3R0b20rMzsKCX0KCglpZiAoSXNXaW5kb3dWaXNpYmxlKEdsb2JhbHMuaGRyaXZlYmFyKSkgewoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBXTV9TSVpFLCAwLCAwKTsKCQlHZXRDbGllbnRSZWN0KEdsb2JhbHMuaGRyaXZlYmFyLCAmcnQpOwoJCW5ld190b3AgPSAtLXByZWN0LT50b3AgKyBydC5ib3R0b20rMzsKCQlNb3ZlV2luZG93KEdsb2JhbHMuaGRyaXZlYmFyLCAwLCBwcmVjdC0+dG9wLCBydC5yaWdodCwgbmV3X3RvcCwgVFJVRSk7CgkJcHJlY3QtPnRvcCA9IG5ld190b3A7CgkJcHJlY3QtPmJvdHRvbSAtPSBydC5ib3R0b20rMjsKCX0KCglpZiAoSXNXaW5kb3dWaXNpYmxlKEdsb2JhbHMuaHN0YXR1c2JhcikpIHsKCQlpbnQgcGFydHNbXSA9IHszMDAsIDUwMH07CgoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaHN0YXR1c2JhciwgV01fU0laRSwgMCwgMCk7CgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oc3RhdHVzYmFyLCBTQl9TRVRQQVJUUywgMiwgKExQQVJBTSkmcGFydHMpOwoJCUdldENsaWVudFJlY3QoR2xvYmFscy5oc3RhdHVzYmFyLCAmcnQpOwoJCXByZWN0LT5ib3R0b20gLT0gcnQuYm90dG9tOwoJfQoKCU1vdmVXaW5kb3coR2xvYmFscy5obWRpY2xpZW50LCBwcmVjdC0+bGVmdC0xLHByZWN0LT50b3AtMSxwcmVjdC0+cmlnaHQrMixwcmVjdC0+Ym90dG9tKzEsIFRSVUUpOwp9CgpzdGF0aWMgdm9pZCByZXNpemVfZnJhbWUoSFdORCBod25kLCBpbnQgY3gsIGludCBjeSkKewoJUkVDVCByZWN0OwoKCXJlY3QubGVmdCAgID0gMDsKCXJlY3QudG9wICAgID0gMDsKCXJlY3QucmlnaHQgID0gY3g7CglyZWN0LmJvdHRvbSA9IGN5OwoKCXJlc2l6ZV9mcmFtZV9yZWN0KGh3bmQsICZyZWN0KTsKfQoKc3RhdGljIHZvaWQgcmVzaXplX2ZyYW1lX2NsaWVudChIV05EIGh3bmQpCnsKCVJFQ1QgcmVjdDsKCglHZXRDbGllbnRSZWN0KGh3bmQsICZyZWN0KTsKCglyZXNpemVfZnJhbWVfcmVjdChod25kLCAmcmVjdCk7Cn0KCgpzdGF0aWMgSEhPT0sgaGNidGhvb2s7CnN0YXRpYyBDaGlsZFduZCogbmV3Y2hpbGQgPSBOVUxMOwoKTFJFU1VMVCBDQUxMQkFDSyBDQlRQcm9jKGludCBjb2RlLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglpZiAoY29kZT09SENCVF9DUkVBVEVXTkQgJiYgbmV3Y2hpbGQpIHsKCQlDaGlsZFduZCogY2hpbGQgPSBuZXdjaGlsZDsKCQluZXdjaGlsZCA9IE5VTEw7CgoJCWNoaWxkLT5od25kID0gKEhXTkQpIHdwYXJhbTsKCQlTZXRXaW5kb3dMb25nKGNoaWxkLT5od25kLCBHV0xfVVNFUkRBVEEsIChMUEFSQU0pY2hpbGQpOwoJfQoKCXJldHVybiBDYWxsTmV4dEhvb2tFeChoY2J0aG9vaywgY29kZSwgd3BhcmFtLCBscGFyYW0pOwp9CgpzdGF0aWMgSFdORCBjcmVhdGVfY2hpbGRfd2luZG93KENoaWxkV25kKiBjaGlsZCkKewoJTURJQ1JFQVRFU1RSVUNUIG1jczsKCWludCBpZHg7CgoJbWNzLnN6Q2xhc3MgPSBzV0lORUZJTEVUUkVFOwoJbWNzLnN6VGl0bGUgPSAoTFBUU1RSKWNoaWxkLT5wYXRoOwoJbWNzLmhPd25lciAgPSBHbG9iYWxzLmhJbnN0YW5jZTsKCW1jcy54ICAgICAgID0gY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmxlZnQ7CgltY3MueSAgICAgICA9IGNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi50b3A7CgltY3MuY3ggICAgICA9IGNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5yaWdodC1jaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ubGVmdDsKCW1jcy5jeSAgICAgID0gY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmJvdHRvbS1jaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24udG9wOwoJbWNzLnN0eWxlICAgPSAwOwoJbWNzLmxQYXJhbSAgPSAwOwoKCWhjYnRob29rID0gU2V0V2luZG93c0hvb2tFeChXSF9DQlQsIENCVFByb2MsIDAsIEdldEN1cnJlbnRUaHJlYWRJZCgpKTsKCgluZXdjaGlsZCA9IGNoaWxkOwoJY2hpbGQtPmh3bmQgPSAoSFdORCkgU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElDUkVBVEUsIDAsIChMUEFSQU0pJm1jcyk7CglpZiAoIWNoaWxkLT5od25kKSB7CgkJVW5ob29rV2luZG93c0hvb2tFeChoY2J0aG9vayk7CgkJcmV0dXJuIDA7Cgl9CgoJVW5ob29rV2luZG93c0hvb2tFeChoY2J0aG9vayk7CgoJTGlzdEJveF9TZXRJdGVtSGVpZ2h0KGNoaWxkLT5sZWZ0Lmh3bmQsIDEsIG1heChHbG9iYWxzLnNwYWNlU2l6ZS5jeSxJTUFHRV9IRUlHSFQrMykpOwoJTGlzdEJveF9TZXRJdGVtSGVpZ2h0KGNoaWxkLT5yaWdodC5od25kLCAxLCBtYXgoR2xvYmFscy5zcGFjZVNpemUuY3ksSU1BR0VfSEVJR0hUKzMpKTsKCWlkeCA9IExpc3RCb3hfRmluZEl0ZW1EYXRhKGNoaWxkLT5sZWZ0Lmh3bmQsIExpc3RCb3hfR2V0Q3VyU2VsKGNoaWxkLT5sZWZ0Lmh3bmQpLCBjaGlsZC0+bGVmdC5jdXIpOwoJTGlzdEJveF9TZXRDdXJTZWwoY2hpbGQtPmxlZnQuaHduZCwgaWR4KTsKCglyZXR1cm4gY2hpbGQtPmh3bmQ7Cn0KCgpzdHJ1Y3QgRXhlY3V0ZURpYWxvZyB7CglUQ0hBUgljbWRbTUFYX1BBVEhdOwoJaW50CQljbWRzaG93Owp9OwoKCnN0YXRpYyBJTlRfUFRSIENBTExCQUNLIEV4ZWN1dGVEaWFsb2dXbmRQcm9nKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglzdGF0aWMgc3RydWN0IEV4ZWN1dGVEaWFsb2cqIGRsZzsKCglzd2l0Y2gobm1zZykgewoJCWNhc2UgV01fSU5JVERJQUxPRzoKCQkJZGxnID0gKHN0cnVjdCBFeGVjdXRlRGlhbG9nKikgbHBhcmFtOwoJCQlyZXR1cm4gMTsKCgkJY2FzZSBXTV9DT01NQU5EOiB7CgkJCWludCBpZCA9IChpbnQpd3BhcmFtOwoKCQkJaWYgKGlkID09IElET0spIHsKCQkJCUdldFdpbmRvd1RleHQoR2V0RGxnSXRlbShod25kLCAyMDEpLCBkbGctPmNtZCwgTUFYX1BBVEgpOwoJCQkJZGxnLT5jbWRzaG93ID0gQnV0dG9uX0dldFN0YXRlKEdldERsZ0l0ZW0oaHduZCwyMTQpKSZCU1RfQ0hFQ0tFRD8KCQkJCQkJCQkJCQkJU1dfU0hPV01JTklNSVpFRDogU1dfU0hPV05PUk1BTDsKCQkJCUVuZERpYWxvZyhod25kLCBpZCk7CgkJCX0gZWxzZSBpZiAoaWQgPT0gSURDQU5DRUwpCgkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoKCQkJcmV0dXJuIDE7fQoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgSU5UX1BUUiBDQUxMQkFDSyBEZXN0aW5hdGlvbkRsZ1Byb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCVRDSEFSIGIxW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCglzd2l0Y2gobm1zZykgewoJCWNhc2UgV01fSU5JVERJQUxPRzoKCQkJU2V0V2luZG93TG9uZyhod25kLCBHV0xfVVNFUkRBVEEsIGxwYXJhbSk7CgkJCXJldHVybiAxOwoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJaW50IGlkID0gKGludCl3cGFyYW07CgoJCQlzd2l0Y2goaWQpIHsKCQkJICBjYXNlIElET0s6IHsKCQkJCUxQVFNUUiBkZXN0ID0gKExQVFNUUikgR2V0V2luZG93TG9uZyhod25kLCBHV0xfVVNFUkRBVEEpOwoJCQkJR2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIDIwMSksIGRlc3QsIE1BWF9QQVRIKTsKCQkJCUVuZERpYWxvZyhod25kLCBpZCk7CgkJCQlicmVhazt9CgoJCQkgIGNhc2UgSURDQU5DRUw6CgkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoJCQkJYnJlYWs7CgoJCQkgIGNhc2UgMjU0OgoJCQkJTWVzc2FnZUJveChod25kLCBSUyhiMSxJRFNfTk9fSU1QTCksIFJTKGIyLElEU19XSU5FRklMRSksIE1CX09LKTsKCQkJCWJyZWFrOwoJCQl9CgoJCQlyZXR1cm4gMTsKCQl9Cgl9CgoJcmV0dXJuIDA7Cn0KCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgpzdGF0aWMgc3RydWN0IEZ1bGxTY3JlZW5QYXJhbWV0ZXJzIHsKCUJPT0wJbW9kZTsKCVJFQ1QJb3JnUG9zOwoJQk9PTAl3YXNab29tZWQ7Cn0gZ19mdWxsc2NyZWVuID0gewogICAgRkFMU0UsCS8qIG1vZGUgKi8KCXswLCAwLCAwLCAwfSwKCUZBTFNFCn07Cgp2b2lkIGZyYW1lX2dldF9jbGllbnRzcGFjZShIV05EIGh3bmQsIFBSRUNUIHByZWN0KQp7CglSRUNUIHJ0OwoKCWlmICghSXNJY29uaWMoaHduZCkpCgkJR2V0Q2xpZW50UmVjdChod25kLCBwcmVjdCk7CgllbHNlIHsKCQlXSU5ET1dQTEFDRU1FTlQgd3A7CgoJCUdldFdpbmRvd1BsYWNlbWVudChod25kLCAmd3ApOwoKCQlwcmVjdC0+bGVmdCA9IHByZWN0LT50b3AgPSAwOwoJCXByZWN0LT5yaWdodCA9IHdwLnJjTm9ybWFsUG9zaXRpb24ucmlnaHQtd3AucmNOb3JtYWxQb3NpdGlvbi5sZWZ0LQoJCQkJCQkyKihHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRUZSQU1FKStHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRURHRSkpOwoJCXByZWN0LT5ib3R0b20gPSB3cC5yY05vcm1hbFBvc2l0aW9uLmJvdHRvbS13cC5yY05vcm1hbFBvc2l0aW9uLnRvcC0KCQkJCQkJMiooR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkVGUkFNRSkrR2V0U3lzdGVtTWV0cmljcyhTTV9DWUVER0UpKS0KCQkJCQkJR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lNRU5VU0laRSk7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmh0b29sYmFyKSkgewoJCUdldENsaWVudFJlY3QoR2xvYmFscy5odG9vbGJhciwgJnJ0KTsKCQlwcmVjdC0+dG9wICs9IHJ0LmJvdHRvbSsyOwoJfQoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5oZHJpdmViYXIpKSB7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmhkcml2ZWJhciwgJnJ0KTsKCQlwcmVjdC0+dG9wICs9IHJ0LmJvdHRvbSsyOwoJfQoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5oc3RhdHVzYmFyKSkgewoJCUdldENsaWVudFJlY3QoR2xvYmFscy5oc3RhdHVzYmFyLCAmcnQpOwoJCXByZWN0LT5ib3R0b20gLT0gcnQuYm90dG9tOwoJfQp9CgpzdGF0aWMgQk9PTCB0b2dnbGVfZnVsbHNjcmVlbihIV05EIGh3bmQpCnsKCVJFQ1QgcnQ7CgoJaWYgKChnX2Z1bGxzY3JlZW4ubW9kZT0hZ19mdWxsc2NyZWVuLm1vZGUpKSB7CgkJR2V0V2luZG93UmVjdChod25kLCAmZ19mdWxsc2NyZWVuLm9yZ1Bvcyk7CgkJZ19mdWxsc2NyZWVuLndhc1pvb21lZCA9IElzWm9vbWVkKGh3bmQpOwoKCQlGcmFtZV9DYWxjRnJhbWVDbGllbnQoaHduZCwgJnJ0KTsKCQlDbGllbnRUb1NjcmVlbihod25kLCAoTFBQT0lOVCkmcnQubGVmdCk7CgkJQ2xpZW50VG9TY3JlZW4oaHduZCwgKExQUE9JTlQpJnJ0LnJpZ2h0KTsKCgkJcnQubGVmdCA9IGdfZnVsbHNjcmVlbi5vcmdQb3MubGVmdC1ydC5sZWZ0OwoJCXJ0LnRvcCA9IGdfZnVsbHNjcmVlbi5vcmdQb3MudG9wLXJ0LnRvcDsKCQlydC5yaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pK2dfZnVsbHNjcmVlbi5vcmdQb3MucmlnaHQtcnQucmlnaHQ7CgkJcnQuYm90dG9tID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTikrZ19mdWxsc2NyZWVuLm9yZ1Bvcy5ib3R0b20tcnQuYm90dG9tOwoKCQlNb3ZlV2luZG93KGh3bmQsIHJ0LmxlZnQsIHJ0LnRvcCwgcnQucmlnaHQtcnQubGVmdCwgcnQuYm90dG9tLXJ0LnRvcCwgVFJVRSk7Cgl9IGVsc2UgewoJCU1vdmVXaW5kb3coaHduZCwgZ19mdWxsc2NyZWVuLm9yZ1Bvcy5sZWZ0LCBnX2Z1bGxzY3JlZW4ub3JnUG9zLnRvcCwKCQkJCQkJCWdfZnVsbHNjcmVlbi5vcmdQb3MucmlnaHQtZ19mdWxsc2NyZWVuLm9yZ1Bvcy5sZWZ0LAoJCQkJCQkJZ19mdWxsc2NyZWVuLm9yZ1Bvcy5ib3R0b20tZ19mdWxsc2NyZWVuLm9yZ1Bvcy50b3AsIFRSVUUpOwoKCQlpZiAoZ19mdWxsc2NyZWVuLndhc1pvb21lZCkKCQkJU2hvd1dpbmRvdyhod25kLCBXU19NQVhJTUlaRSk7Cgl9CgoJcmV0dXJuIGdfZnVsbHNjcmVlbi5tb2RlOwp9CgpzdGF0aWMgdm9pZCBmdWxsc2NyZWVuX21vdmUoSFdORCBod25kKQp7CglSRUNUIHJ0LCBwb3M7CglHZXRXaW5kb3dSZWN0KGh3bmQsICZwb3MpOwoKCUZyYW1lX0NhbGNGcmFtZUNsaWVudChod25kLCAmcnQpOwoJQ2xpZW50VG9TY3JlZW4oaHduZCwgKExQUE9JTlQpJnJ0LmxlZnQpOwoJQ2xpZW50VG9TY3JlZW4oaHduZCwgKExQUE9JTlQpJnJ0LnJpZ2h0KTsKCglydC5sZWZ0ID0gcG9zLmxlZnQtcnQubGVmdDsKCXJ0LnRvcCA9IHBvcy50b3AtcnQudG9wOwoJcnQucmlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKStwb3MucmlnaHQtcnQucmlnaHQ7CglydC5ib3R0b20gPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKStwb3MuYm90dG9tLXJ0LmJvdHRvbTsKCglNb3ZlV2luZG93KGh3bmQsIHJ0LmxlZnQsIHJ0LnRvcCwgcnQucmlnaHQtcnQubGVmdCwgcnQuYm90dG9tLXJ0LnRvcCwgVFJVRSk7Cn0KCiNlbmRpZgoKCnN0YXRpYyB2b2lkIHRvZ2dsZV9jaGlsZChIV05EIGh3bmQsIFVJTlQgY21kLCBIV05EIGhjaGlsZCkKewoJQk9PTCB2aXMgPSBJc1dpbmRvd1Zpc2libGUoaGNoaWxkKTsKCglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBjbWQsIHZpcz9NRl9CWUNPTU1BTkQ6TUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoKCVNob3dXaW5kb3coaGNoaWxkLCB2aXM/U1dfSElERTpTV19TSE9XKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWlmIChnX2Z1bGxzY3JlZW4ubW9kZSkKCQlmdWxsc2NyZWVuX21vdmUoaHduZCk7CiNlbmRpZgoKCXJlc2l6ZV9mcmFtZV9jbGllbnQoaHduZCk7Cn0KCkJPT0wgYWN0aXZhdGVfZHJpdmVfd2luZG93KExQQ1RTVFIgcGF0aCkKewoJVENIQVIgZHJ2MVtfTUFYX0RSSVZFXSwgZHJ2MltfTUFYX0RSSVZFXTsKCUhXTkQgY2hpbGRfd25kOwoKCV90c3BsaXRwYXRoKHBhdGgsIGRydjEsIDAsIDAsIDApOwoKCS8qIHNlYXJjaCBmb3IgYSBhbHJlYWR5IG9wZW4gd2luZG93IGZvciB0aGUgc2FtZSBkcml2ZSAqLwoJZm9yKGNoaWxkX3duZD1HZXROZXh0V2luZG93KEdsb2JhbHMuaG1kaWNsaWVudCxHV19DSElMRCk7IGNoaWxkX3duZDsgY2hpbGRfd25kPUdldE5leHRXaW5kb3coY2hpbGRfd25kLCBHV19IV05ETkVYVCkpIHsKCQlDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nKGNoaWxkX3duZCwgR1dMX1VTRVJEQVRBKTsKCgkJaWYgKGNoaWxkKSB7CgkJCV90c3BsaXRwYXRoKGNoaWxkLT5yb290LnBhdGgsIGRydjIsIDAsIDAsIDApOwoKCQkJaWYgKCFsc3RyY21waShkcnYyLCBkcnYxKSkgewoJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElBQ1RJVkFURSwgKFdQQVJBTSljaGlsZF93bmQsIDApOwoKCQkJCWlmIChJc01pbmltaXplZChjaGlsZF93bmQpKQoJCQkJCVNob3dXaW5kb3coY2hpbGRfd25kLCBTV19TSE9XTk9STUFMKTsKCgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCkJPT0wgYWN0aXZhdGVfZnNfd2luZG93KExQQ1RTVFIgZmlsZXN5cykKewoJSFdORCBjaGlsZF93bmQ7CgoJLyogc2VhcmNoIGZvciBhIGFscmVhZHkgb3BlbiB3aW5kb3cgb2YgdGhlIGdpdmVuIGZpbGUgc3lzdGVtIG5hbWUgKi8KCWZvcihjaGlsZF93bmQ9R2V0TmV4dFdpbmRvdyhHbG9iYWxzLmhtZGljbGllbnQsR1dfQ0hJTEQpOyBjaGlsZF93bmQ7IGNoaWxkX3duZD1HZXROZXh0V2luZG93KGNoaWxkX3duZCwgR1dfSFdORE5FWFQpKSB7CgkJQ2hpbGRXbmQqIGNoaWxkID0gKENoaWxkV25kKikgR2V0V2luZG93TG9uZyhjaGlsZF93bmQsIEdXTF9VU0VSREFUQSk7CgoJCWlmIChjaGlsZCkgewoJCQlpZiAoIWxzdHJjbXBpKGNoaWxkLT5yb290LmZzLCBmaWxlc3lzKSkgewoJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElBQ1RJVkFURSwgKFdQQVJBTSljaGlsZF93bmQsIDApOwoKCQkJCWlmIChJc01pbmltaXplZChjaGlsZF93bmQpKQoJCQkJCVNob3dXaW5kb3coY2hpbGRfd25kLCBTV19TSE9XTk9STUFMKTsKCgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCkxSRVNVTFQgQ0FMTEJBQ0sgRnJhbWVXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglUQ0hBUiBiMVtCVUZGRVJfTEVOXSwgYjJbQlVGRkVSX0xFTl07CgoJc3dpdGNoKG5tc2cpIHsKCQljYXNlIFdNX0NMT1NFOgoJCQlEZXN0cm95V2luZG93KGh3bmQpOwoKCQkJIC8qIGNsZWFyIGhhbmRsZSB2YXJpYWJsZXMgKi8KCQkJR2xvYmFscy5oTWVudUZyYW1lID0gMDsKCQkJR2xvYmFscy5oTWVudVZpZXcgPSAwOwoJCQlHbG9iYWxzLmhNZW51T3B0aW9ucyA9IDA7CgkJCUdsb2JhbHMuaE1haW5XbmQgPSAwOwoJCQlHbG9iYWxzLmhtZGljbGllbnQgPSAwOwoJCQlHbG9iYWxzLmhkcml2ZWJhciA9IDA7CgkJCWJyZWFrOwoKCQljYXNlIFdNX0RFU1RST1k6CgkJCSAvKiBkb24ndCBleGl0IGRlc2t0b3Agd2hlbiBjbG9zaW5nIGZpbGUgbWFuYWdlciB3aW5kb3cgKi8KCQkJaWYgKCFHbG9iYWxzLmh3bmRQYXJlbnQpCgkJCQlQb3N0UXVpdE1lc3NhZ2UoMCk7CgkJCWJyZWFrOwoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJVUlOVCBjbWQgPSBMT1dPUkQod3BhcmFtKTsKCQkJSFdORCBod25kQ2xpZW50ID0gKEhXTkQpIFNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJR0VUQUNUSVZFLCAwLCAwKTsKCgkJCWlmIChTZW5kTWVzc2FnZShod25kQ2xpZW50LCBXTV9ESVNQQVRDSF9DT01NQU5ELCB3cGFyYW0sIGxwYXJhbSkpCgkJCQlicmVhazsKCgkJCWlmIChjbWQ+PUlEX0RSSVZFX0ZJUlNUICYmIGNtZDw9SURfRFJJVkVfRklSU1QrMHhGRikgewoJCQkJVENIQVIgZHJ2W19NQVhfRFJJVkVdLCBwYXRoW01BWF9QQVRIXTsKCQkJCUNoaWxkV25kKiBjaGlsZDsKCQkJCUxQQ1RTVFIgcm9vdCA9IEdsb2JhbHMuZHJpdmVzOwoJCQkJaW50IGk7CgoJCQkJZm9yKGk9Y21kLUlEX0RSSVZFX0ZJUlNUOyBpLS07IHJvb3QrKykKCQkJCQl3aGlsZSgqcm9vdCkKCQkJCQkJcm9vdCsrOwoKCQkJCWlmIChhY3RpdmF0ZV9kcml2ZV93aW5kb3cocm9vdCkpCgkJCQkJcmV0dXJuIDA7CgoJCQkJX3RzcGxpdHBhdGgocm9vdCwgZHJ2LCAwLCAwLCAwKTsKCgkJCQlpZiAoIVNldEN1cnJlbnREaXJlY3RvcnkoZHJ2KSkgewoJCQkJCWRpc3BsYXlfZXJyb3IoaHduZCwgR2V0TGFzdEVycm9yKCkpOwoJCQkJCXJldHVybiAwOwoJCQkJfQoKCQkJCUdldEN1cnJlbnREaXJlY3RvcnkoTUFYX1BBVEgsIHBhdGgpOyAvKlRPRE86IHN0b3JlIGxhc3QgZGlyZWN0b3J5IHBlciBkcml2ZSAqLwoJCQkJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgTlVMTCwgaHduZCk7CgoJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQkJCQlmcmVlKGNoaWxkKTsKCQkJfSBlbHNlIHN3aXRjaChjbWQpIHsKCQkJCWNhc2UgSURfRklMRV9FWElUOgoJCQkJCVNlbmRNZXNzYWdlKGh3bmQsIFdNX0NMT1NFLCAwLCAwKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1dJTkRPV19ORVc6IHsKCQkJCQlUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCQkJCQlDaGlsZFduZCogY2hpbGQ7CgoJCQkJCUdldEN1cnJlbnREaXJlY3RvcnkoTUFYX1BBVEgsIHBhdGgpOwoJCQkJCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIE5VTEwsIGh3bmQpOwoKCQkJCQlpZiAoIWNyZWF0ZV9jaGlsZF93aW5kb3coY2hpbGQpKQoJCQkJCQlmcmVlKGNoaWxkKTsKCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9XSU5ET1dfQ0FTQ0FERToKCQkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESUNBU0NBREUsIDAsIDApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfV0lORE9XX1RJTEVfSE9SWjoKCQkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESVRJTEUsIE1ESVRJTEVfSE9SSVpPTlRBTCwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9XSU5ET1dfVElMRV9WRVJUOgoJCQkJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJVElMRSwgTURJVElMRV9WRVJUSUNBTCwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9XSU5ET1dfQVJSQU5HRToKCQkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESUlDT05BUlJBTkdFLCAwLCAwKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1NFTEVDVF9GT05UOiB7CgkJCQkJVENIQVIgZGxnX25hbWVbQlVGRkVSX0xFTl0sIGRsZ19pbmZvW0JVRkZFUl9MRU5dOwoJCQkJCUNIT09TRUZPTlQgY2hGb250OwoJCQkJCUxPR0ZPTlQgbEZvbnQ7CgoJCQkJCUhEQyBoZGMgPSBHZXREQyhod25kKTsKCQkJCQljaEZvbnQubFN0cnVjdFNpemUgPSBzaXplb2YoQ0hPT1NFRk9OVCk7CgkJCQkJY2hGb250Lmh3bmRPd25lciA9IGh3bmQ7CgkJCQkJY2hGb250LmhEQyA9IE5VTEw7CgkJCQkJY2hGb250LmxwTG9nRm9udCA9ICZsRm9udDsKCQkJCQljaEZvbnQuRmxhZ3MgPSBDRl9TQ1JFRU5GT05UUyB8IENGX0ZPUkNFRk9OVEVYSVNUIHwgQ0ZfTElNSVRTSVpFIHwgQ0ZfTk9TQ1JJUFRTRUw7CgkJCQkJY2hGb250LnJnYkNvbG9ycyA9IFJHQigwLDAsMCk7CgkJCQkJY2hGb250LmxDdXN0RGF0YSA9IDA7CgkJCQkJY2hGb250LmxwZm5Ib29rID0gTlVMTDsKCQkJCQljaEZvbnQubHBUZW1wbGF0ZU5hbWUgPSBOVUxMOwoJCQkJCWNoRm9udC5oSW5zdGFuY2UgPSBHbG9iYWxzLmhJbnN0YW5jZTsKCQkJCQljaEZvbnQubHBzelN0eWxlID0gTlVMTDsKCQkJCQljaEZvbnQubkZvbnRUeXBlID0gU0lNVUxBVEVEX0ZPTlRUWVBFOwoJCQkJCWNoRm9udC5uU2l6ZU1pbiA9IDA7CgkJCQkJY2hGb250Lm5TaXplTWF4ID0gMjQ7CgoJCQkJCWlmIChDaG9vc2VGb250KCZjaEZvbnQpKSB7CgkJCQkJCUhXTkQgY2hpbGRXbmQ7CgoJCQkJCQlHbG9iYWxzLmhmb250ID0gQ3JlYXRlRm9udEluZGlyZWN0KCZsRm9udCk7CgkJCQkJCVNlbGVjdEZvbnQoaGRjLCBHbG9iYWxzLmhmb250KTsKCQkJCQkJR2V0VGV4dEV4dGVudFBvaW50MzIoaGRjLCBzU3BhY2UsIDEsICZHbG9iYWxzLnNwYWNlU2l6ZSk7CgoJCQkJCQkvKiBjaGFuZ2UgZm9udCBpbiBhbGwgb3BlbiBjaGlsZCB3aW5kb3dzICovCgkJCQkJCWZvcihjaGlsZFduZD1HZXRXaW5kb3coR2xvYmFscy5obWRpY2xpZW50LEdXX0NISUxEKTsgY2hpbGRXbmQ7IGNoaWxkV25kPUdldE5leHRXaW5kb3coY2hpbGRXbmQsR1dfSFdORE5FWFQpKSB7CgkJCQkJCQlDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nKGNoaWxkV25kLCBHV0xfVVNFUkRBVEEpOwoJCQkJCQkJU2V0V2luZG93Rm9udChjaGlsZC0+bGVmdC5od25kLCBHbG9iYWxzLmhmb250LCBUUlVFKTsKCQkJCQkJCVNldFdpbmRvd0ZvbnQoY2hpbGQtPnJpZ2h0Lmh3bmQsIEdsb2JhbHMuaGZvbnQsIFRSVUUpOwoJCQkJCQkJTGlzdEJveF9TZXRJdGVtSGVpZ2h0KGNoaWxkLT5sZWZ0Lmh3bmQsIDEsIG1heChHbG9iYWxzLnNwYWNlU2l6ZS5jeSxJTUFHRV9IRUlHSFQrMykpOwoJCQkJCQkJTGlzdEJveF9TZXRJdGVtSGVpZ2h0KGNoaWxkLT5yaWdodC5od25kLCAxLCBtYXgoR2xvYmFscy5zcGFjZVNpemUuY3ksSU1BR0VfSEVJR0hUKzMpKTsKCQkJCQkJCUludmFsaWRhdGVSZWN0KGNoaWxkLT5sZWZ0Lmh3bmQsIE5VTEwsIFRSVUUpOwoJCQkJCQkJSW52YWxpZGF0ZVJlY3QoY2hpbGQtPnJpZ2h0Lmh3bmQsIE5VTEwsIFRSVUUpOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWVsc2UgaWYgKENvbW1EbGdFeHRlbmRlZEVycm9yKCkpIHsKCQkJCQkJTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX0ZPTlRfU0VMX0RMR19OQU1FLCBkbGdfbmFtZSwgQlVGRkVSX0xFTik7CgkJCQkJCUxvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19GT05UX1NFTF9FUlJPUiwgZGxnX2luZm8sIEJVRkZFUl9MRU4pOwoJCQkJCQlNZXNzYWdlQm94KGh3bmQsIGRsZ19pbmZvLCBkbGdfbmFtZSwgTUJfT0spOwoJCQkJCX0KCgkJCQkJUmVsZWFzZURDKGh3bmQsIGhkYyk7CgkJCQkJYnJlYWs7CgkJCQl9CgoJCQkJY2FzZSBJRF9WSUVXX1RPT0xfQkFSOgoJCQkJCXRvZ2dsZV9jaGlsZChod25kLCBjbWQsIEdsb2JhbHMuaHRvb2xiYXIpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19EUklWRV9CQVI6CgkJCQkJdG9nZ2xlX2NoaWxkKGh3bmQsIGNtZCwgR2xvYmFscy5oZHJpdmViYXIpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19TVEFUVVNCQVI6CgkJCQkJdG9nZ2xlX2NoaWxkKGh3bmQsIGNtZCwgR2xvYmFscy5oc3RhdHVzYmFyKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX0VYRUNVVEU6IHsKCQkJCQlzdHJ1Y3QgRXhlY3V0ZURpYWxvZyBkbGc7CgoJCQkJCW1lbXNldCgmZGxnLCAwLCBzaXplb2Yoc3RydWN0IEV4ZWN1dGVEaWFsb2cpKTsKCgkJCQkJaWYgKERpYWxvZ0JveFBhcmFtKEdsb2JhbHMuaEluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSUREX0VYRUNVVEUpLCBod25kLCBFeGVjdXRlRGlhbG9nV25kUHJvZywgKExQQVJBTSkmZGxnKSA9PSBJRE9LKSB7CgkJCQkJCUhJTlNUQU5DRSBoaW5zdCA9IFNoZWxsRXhlY3V0ZShod25kLCBOVUxMLypvcGVyYXRpb24qLywgZGxnLmNtZC8qZmlsZSovLCBOVUxMLypwYXJhbWV0ZXJzKi8sIE5VTEwvKmRpciovLCBkbGcuY21kc2hvdyk7CgoJCQkJCQlpZiAoKGludCloaW5zdCA8PSAzMikKCQkJCQkJCWRpc3BsYXlfZXJyb3IoaHduZCwgR2V0TGFzdEVycm9yKCkpOwoJCQkJCX0KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9IRUxQOgoJCQkJCVdpbkhlbHAoaHduZCwgUlMoYjEsSURTX1dJTkVGSUxFKSwgSEVMUF9JTkRFWCwgMCk7CgkJCQkJYnJlYWs7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCQljYXNlIElEX1ZJRVdfRlVMTFNDUkVFTjoKCQkJCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBjbWQsIHRvZ2dsZV9mdWxsc2NyZWVuKGh3bmQpP01GX0NIRUNLRUQ6MCk7CgkJCQkJYnJlYWs7CgojaWZkZWYgX19XSU5FX18KCQkJCWNhc2UgSURfRFJJVkVfVU5JWF9GUzogewoJCQkJCVRDSEFSIHBhdGhbTUFYX1BBVEhdOwoJCQkJCUNoaWxkV25kKiBjaGlsZDsKCgkJCQkJaWYgKGFjdGl2YXRlX2ZzX3dpbmRvdyhSUyhiMSxJRFNfVU5JWEZTKSkpCgkJCQkJCWJyZWFrOwoKCQkJCQlnZXRjd2QocGF0aCwgTUFYX1BBVEgpOwoJCQkJCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIE5VTEwsIGh3bmQpOwoKCQkJCQlpZiAoIWNyZWF0ZV9jaGlsZF93aW5kb3coY2hpbGQpKQoJCQkJCQlmcmVlKGNoaWxkKTsKCQkJCQlicmVhazt9CiNlbmRpZgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCQkJCWNhc2UgSURfRFJJVkVfU0hFTExfTlM6IHsKCQkJCQlUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCQkJCQlDaGlsZFduZCogY2hpbGQ7CgoJCQkJCWlmIChhY3RpdmF0ZV9mc193aW5kb3coUlMoYjEsSURTX1NIRUxMKSkpCgkJCQkJCWJyZWFrOwoKCQkJCQlHZXRDdXJyZW50RGlyZWN0b3J5KE1BWF9QQVRILCBwYXRoKTsKCQkJCQljaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhwYXRoLCBnZXRfcGF0aF9waWRsKHBhdGgsaHduZCksIGh3bmQpOwoKCQkJCQlpZiAoIWNyZWF0ZV9jaGlsZF93aW5kb3coY2hpbGQpKQoJCQkJCQlmcmVlKGNoaWxkKTsKCQkJCQlicmVhazt9CiNlbmRpZgojZW5kaWYKCgkJCQkvKlRPRE86IFRoZXJlIGFyZSBldmVuIG1vcmUgbWVudSBpdGVtcyEgKi8KCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKI2lmZGVmIF9fV0lORV9fCgkJCQljYXNlIElEX0xJQ0VOU0U6CgkJCQkJV2luZUxpY2Vuc2UoR2xvYmFscy5oTWFpblduZCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9OT19XQVJSQU5UWToKCQkJCQlXaW5lV2FycmFudHkoR2xvYmFscy5oTWFpblduZCk7CgkJCQkJYnJlYWs7CiNlbmRpZgoKCQkJCWNhc2UgSURfQUJPVVRfV0lORToKCQkJCQlTaGVsbEFib3V0KGh3bmQsIFJTKGIyLElEU19XSU5FKSwgUlMoYjEsSURTX1dJTkVGSUxFKSwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9BQk9VVDoJLypJRF9BQk9VVF9XSU5FOiAqLwoJCQkJCVNoZWxsQWJvdXQoaHduZCwgUlMoYjEsSURTX1dJTkVGSUxFKSwgTlVMTCwgMCk7CgkJCQkJYnJlYWs7CiNlbmRpZgkvKiBfTk9fRVhURU5TSU9OUyAqLwoKCQkJCWRlZmF1bHQ6CgkJCQkJLypUT0RPOiBpZiAod1BhcmFtID49IFBNX0ZJUlNUX0xBTkdVQUdFICYmIHdQYXJhbSA8PSBQTV9MQVNUX0xBTkdVQUdFKQoJCQkJCQlTVFJJTkdfU2VsZWN0TGFuZ3VhZ2VCeU51bWJlcih3UGFyYW0gLSBQTV9GSVJTVF9MQU5HVUFHRSk7CgkJCQkJZWxzZSAqL2lmICgoY21kPElEV19GSVJTVF9DSElMRCB8fCBjbWQ+PUlEV19GSVJTVF9DSElMRCsweDEwMCkgJiYKCQkJCQkJKGNtZDxTQ19TSVpFIHx8IGNtZD5TQ19SRVNUT1JFKSkKCQkJCQkJTWVzc2FnZUJveChod25kLCBSUyhiMixJRFNfTk9fSU1QTCksIFJTKGIxLElEU19XSU5FRklMRSksIE1CX09LKTsKCgkJCQkJcmV0dXJuIERlZkZyYW1lUHJvYyhod25kLCBHbG9iYWxzLmhtZGljbGllbnQsIG5tc2csIHdwYXJhbSwgbHBhcmFtKTsKCQkJfQoJCQlicmVhazt9CgoJCWNhc2UgV01fU0laRToKCQkJcmVzaXplX2ZyYW1lKGh3bmQsIExPV09SRChscGFyYW0pLCBISVdPUkQobHBhcmFtKSk7CgkJCWJyZWFrOwkvKiBkbyBub3QgcGFzcyBtZXNzYWdlIHRvIERlZkZyYW1lUHJvYyAqLwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fR0VUTUlOTUFYSU5GTzogewoJCQlMUE1JTk1BWElORk8gbHBtbWkgPSAoTFBNSU5NQVhJTkZPKWxwYXJhbTsKCgkJCWxwbW1pLT5wdE1heFRyYWNrU2l6ZS54IDw8PSAxOy8qMipHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKSAvIFNNX0NYVklSVFVBTFNDUkVFTiAqLwoJCQlscG1taS0+cHRNYXhUcmFja1NpemUueSA8PD0gMTsvKjIqR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTikgLyBTTV9DWVZJUlRVQUxTQ1JFRU4gKi8KCQkJYnJlYWs7fQoKCQljYXNlIEZSTV9DQUxDX0NMSUVOVDoKCQkJZnJhbWVfZ2V0X2NsaWVudHNwYWNlKGh3bmQsIChQUkVDVClscGFyYW0pOwoJCQlyZXR1cm4gVFJVRTsKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJCWRlZmF1bHQ6CgkJCXJldHVybiBEZWZGcmFtZVByb2MoaHduZCwgR2xvYmFscy5obWRpY2xpZW50LCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7Cgl9CgoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgVENIQVIgZ19wb3NfbmFtZXNbQ09MVU1OU11bMjBdID0gewoJeydcMCd9CS8qIHN5bWJvbCAqLwp9OwoKc3RhdGljIGNvbnN0IGludCBnX3Bvc19hbGlnbltdID0gewoJMCwKCUhERl9MRUZULAkvKiBOYW1lICovCglIREZfUklHSFQsCS8qIFNpemUgKi8KCUhERl9MRUZULAkvKiBDRGF0ZSAqLwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglIREZfTEVGVCwJLyogQURhdGUgKi8KCUhERl9MRUZULAkvKiBNRGF0ZSAqLwoJSERGX0xFRlQsCS8qIEluZGV4ICovCglIREZfQ0VOVEVSLAkvKiBMaW5rcyAqLwojZW5kaWYKCUhERl9DRU5URVIsCS8qIEF0dHJpYnV0ZXMgKi8KI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJSERGX0xFRlQJLyogU2VjdXJpdHkgKi8KI2VuZGlmCn07CgpzdGF0aWMgdm9pZCByZXNpemVfdHJlZShDaGlsZFduZCogY2hpbGQsIGludCBjeCwgaW50IGN5KQp7CglIRFdQIGhkd3AgPSBCZWdpbkRlZmVyV2luZG93UG9zKDQpOwoJUkVDVCBydDsKCglydC5sZWZ0ICAgPSAwOwoJcnQudG9wICAgID0gMDsKCXJ0LnJpZ2h0ICA9IGN4OwoJcnQuYm90dG9tID0gY3k7CgoJY3ggPSBjaGlsZC0+c3BsaXRfcG9zICsgU1BMSVRfV0lEVEgvMjsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCXsKCQlXSU5ET1dQT1Mgd3A7CgkJSERfTEFZT1VUIGhkbDsKCgkJaGRsLnByYyAgID0gJnJ0OwoJCWhkbC5wd3BvcyA9ICZ3cDsKCgkJSGVhZGVyX0xheW91dChjaGlsZC0+bGVmdC5od25kSGVhZGVyLCAmaGRsKTsKCgkJRGVmZXJXaW5kb3dQb3MoaGR3cCwgY2hpbGQtPmxlZnQuaHduZEhlYWRlciwgd3AuaHduZEluc2VydEFmdGVyLAoJCQkJCQl3cC54LTEsIHdwLnksIGNoaWxkLT5zcGxpdF9wb3MtU1BMSVRfV0lEVEgvMisxLCB3cC5jeSwgd3AuZmxhZ3MpOwoJCURlZmVyV2luZG93UG9zKGhkd3AsIGNoaWxkLT5yaWdodC5od25kSGVhZGVyLCB3cC5od25kSW5zZXJ0QWZ0ZXIsCgkJCQkJCXJ0LmxlZnQrY3grMSwgd3AueSwgd3AuY3gtY3grMiwgd3AuY3ksIHdwLmZsYWdzKTsKCX0KI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJRGVmZXJXaW5kb3dQb3MoaGR3cCwgY2hpbGQtPmxlZnQuaHduZCwgMCwgcnQubGVmdCwgcnQudG9wLCBjaGlsZC0+c3BsaXRfcG9zLVNQTElUX1dJRFRILzItcnQubGVmdCwgcnQuYm90dG9tLXJ0LnRvcCwgU1dQX05PWk9SREVSfFNXUF9OT0FDVElWQVRFKTsKCURlZmVyV2luZG93UG9zKGhkd3AsIGNoaWxkLT5yaWdodC5od25kLCAwLCBydC5sZWZ0K2N4KzEsIHJ0LnRvcCwgcnQucmlnaHQtY3gsIHJ0LmJvdHRvbS1ydC50b3AsIFNXUF9OT1pPUkRFUnxTV1BfTk9BQ1RJVkFURSk7CgoJRW5kRGVmZXJXaW5kb3dQb3MoaGR3cCk7Cn0KCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgpzdGF0aWMgSFdORCBjcmVhdGVfaGVhZGVyKEhXTkQgcGFyZW50LCBQYW5lKiBwYW5lLCBpbnQgaWQpCnsKCUhEX0lURU0gaGRpOwoJaW50IGlkeDsKCglIV05EIGh3bmQgPSBDcmVhdGVXaW5kb3coV0NfSEVBREVSLCAwLCBXU19DSElMRHxXU19WSVNJQkxFfEhEU19IT1JaLypUT0RPOiB8SERTX0JVVFRPTlMgKyBzb3J0IG9yZGVycyovLAoJCQkJCQkJCTAsIDAsIDAsIDAsIHBhcmVudCwgKEhNRU5VKWlkLCBHbG9iYWxzLmhJbnN0YW5jZSwgMCk7CglpZiAoIWh3bmQpCgkJcmV0dXJuIDA7CgoJU2V0V2luZG93Rm9udChod25kLCBHZXRTdG9ja09iamVjdChERUZBVUxUX0dVSV9GT05UKSwgRkFMU0UpOwoKCWhkaS5tYXNrID0gSERJX1RFWFR8SERJX1dJRFRIfEhESV9GT1JNQVQ7CgoJZm9yKGlkeD0wOyBpZHg8Q09MVU1OUzsgaWR4KyspIHsKCQloZGkucHN6VGV4dCA9IGdfcG9zX25hbWVzW2lkeF07CgkJaGRpLmZtdCA9IEhERl9TVFJJTkcgfCBnX3Bvc19hbGlnbltpZHhdOwoJCWhkaS5jeHkgPSBwYW5lLT53aWR0aHNbaWR4XTsKCQlIZWFkZXJfSW5zZXJ0SXRlbShod25kLCBpZHgsICZoZGkpOwoJfQoKCXJldHVybiBod25kOwp9CgojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgpzdGF0aWMgdm9pZCBpbml0X291dHB1dChIV05EIGh3bmQpCnsKCWNvbnN0IHN0YXRpYyBUQ0hBUiBzMTAwMFtdID0geycxJywnMCcsJzAnLCcwJywnXDAnfTsKCglUQ0hBUiBiWzE2XTsKCUhGT05UIG9sZF9mb250OwoJSERDIGhkYyA9IEdldERDKGh3bmQpOwoKCWlmIChHZXROdW1iZXJGb3JtYXQoTE9DQUxFX1VTRVJfREVGQVVMVCwgMCwgczEwMDAsIDAsIGIsIDE2KSA+IDQpCgkJR2xvYmFscy5udW1fc2VwID0gYlsxXTsKCWVsc2UKCQlHbG9iYWxzLm51bV9zZXAgPSBURVhUKCcuJyk7CgoJb2xkX2ZvbnQgPSBTZWxlY3RGb250KGhkYywgR2xvYmFscy5oZm9udCk7CglHZXRUZXh0RXh0ZW50UG9pbnQzMihoZGMsIHNTcGFjZSwgMSwgJkdsb2JhbHMuc3BhY2VTaXplKTsKCVNlbGVjdEZvbnQoaGRjLCBvbGRfZm9udCk7CglSZWxlYXNlREMoaHduZCwgaGRjKTsKfQoKc3RhdGljIHZvaWQgZHJhd19pdGVtKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBFbnRyeSogZW50cnksIGludCBjYWxjV2lkdGhDb2wpOwoKCi8qIGNhbGN1bGF0ZSBwcmVmZXJlZCB3aWR0aCBmb3IgYWxsIHZpc2libGUgY29sdW1ucyAqLwoKc3RhdGljIEJPT0wgY2FsY193aWR0aHMoUGFuZSogcGFuZSwgQk9PTCBhbnl3YXkpCnsKCWludCBjb2wsIHgsIGN4LCBzcGM9MypHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCWludCBlbnRyaWVzID0gTGlzdEJveF9HZXRDb3VudChwYW5lLT5od25kKTsKCWludCBvcmdXaWR0aHNbQ09MVU1OU107CglpbnQgb3JnUG9zaXRpb25zW0NPTFVNTlMrMV07CglIRk9OVCBoZm9udE9sZDsKCUhEQyBoZGM7CglpbnQgY250OwoKCWlmICghYW55d2F5KSB7CgkJbWVtY3B5KG9yZ1dpZHRocywgcGFuZS0+d2lkdGhzLCBzaXplb2Yob3JnV2lkdGhzKSk7CgkJbWVtY3B5KG9yZ1Bvc2l0aW9ucywgcGFuZS0+cG9zaXRpb25zLCBzaXplb2Yob3JnUG9zaXRpb25zKSk7Cgl9CgoJZm9yKGNvbD0wOyBjb2w8Q09MVU1OUzsgY29sKyspCgkJcGFuZS0+d2lkdGhzW2NvbF0gPSAwOwoKCWhkYyA9IEdldERDKHBhbmUtPmh3bmQpOwoJaGZvbnRPbGQgPSBTZWxlY3RGb250KGhkYywgR2xvYmFscy5oZm9udCk7CgoJZm9yKGNudD0wOyBjbnQ8ZW50cmllczsgY250KyspIHsKCQlFbnRyeSogZW50cnkgPSAoRW50cnkqKSBMaXN0Qm94X0dldEl0ZW1EYXRhKHBhbmUtPmh3bmQsIGNudCk7CgoJCURSQVdJVEVNU1RSVUNUIGRpczsKCgkJZGlzLkN0bFR5cGUJCSAgPSAwOwoJCWRpcy5DdGxJRAkJICA9IDA7CgkJZGlzLml0ZW1JRAkJICA9IDA7CgkJZGlzLml0ZW1BY3Rpb24JICA9IDA7CgkJZGlzLml0ZW1TdGF0ZQkgID0gMDsKCQlkaXMuaHduZEl0ZW0JICA9IHBhbmUtPmh3bmQ7CgkJZGlzLmhEQwkJCSAgPSBoZGM7CgkJZGlzLnJjSXRlbS5sZWZ0CSAgPSAwOwoJCWRpcy5yY0l0ZW0udG9wICAgID0gMDsKCQlkaXMucmNJdGVtLnJpZ2h0ICA9IDA7CgkJZGlzLnJjSXRlbS5ib3R0b20gPSAwOwoJCS8qZGlzLml0ZW1EYXRhCSAgPSAwOyAqLwoKCQlkcmF3X2l0ZW0ocGFuZSwgJmRpcywgZW50cnksIENPTFVNTlMpOwoJfQoKCVNlbGVjdE9iamVjdChoZGMsIGhmb250T2xkKTsKCVJlbGVhc2VEQyhwYW5lLT5od25kLCBoZGMpOwoKCXggPSAwOwoJZm9yKGNvbD0wOyBjb2w8Q09MVU1OUzsgY29sKyspIHsKCQlwYW5lLT5wb3NpdGlvbnNbY29sXSA9IHg7CgkJY3ggPSBwYW5lLT53aWR0aHNbY29sXTsKCgkJaWYgKGN4KSB7CgkJCWN4ICs9IHNwYzsKCgkJCWlmIChjeCA8IElNQUdFX1dJRFRIKQoJCQkJY3ggPSBJTUFHRV9XSURUSDsKCgkJCXBhbmUtPndpZHRoc1tjb2xdID0gY3g7CgkJfQoKCQl4ICs9IGN4OwoJfQoKCXBhbmUtPnBvc2l0aW9uc1tDT0xVTU5TXSA9IHg7CgoJTGlzdEJveF9TZXRIb3Jpem9udGFsRXh0ZW50KHBhbmUtPmh3bmQsIHgpOwoKCS8qIG5vIGNoYW5nZT8gKi8KCWlmICghbWVtY21wKG9yZ1dpZHRocywgcGFuZS0+d2lkdGhzLCBzaXplb2Yob3JnV2lkdGhzKSkpCgkJcmV0dXJuIEZBTFNFOwoKCS8qIGRvbid0IG1vdmUsIGlmIG9ubHkgY29sbGFwc2luZyBhbiBlbnRyeSAqLwoJaWYgKCFhbnl3YXkgJiYgcGFuZS0+d2lkdGhzWzBdPG9yZ1dpZHRoc1swXSAmJgoJCSFtZW1jbXAob3JnV2lkdGhzKzEsIHBhbmUtPndpZHRocysxLCBzaXplb2Yob3JnV2lkdGhzKS1zaXplb2YoaW50KSkpIHsKCQlwYW5lLT53aWR0aHNbMF0gPSBvcmdXaWR0aHNbMF07CgkJbWVtY3B5KHBhbmUtPnBvc2l0aW9ucywgb3JnUG9zaXRpb25zLCBzaXplb2Yob3JnUG9zaXRpb25zKSk7CgoJCXJldHVybiBGQUxTRTsKCX0KCglJbnZhbGlkYXRlUmVjdChwYW5lLT5od25kLCAwLCBUUlVFKTsKCglyZXR1cm4gVFJVRTsKfQoKCi8qIGNhbGN1bGF0ZSBvbmUgcHJlZmVyZWQgY29sdW1uIHdpZHRoICovCgpzdGF0aWMgdm9pZCBjYWxjX3NpbmdsZV93aWR0aChQYW5lKiBwYW5lLCBpbnQgY29sKQp7CglIRk9OVCBoZm9udE9sZDsKCWludCB4LCBjeDsKCWludCBlbnRyaWVzID0gTGlzdEJveF9HZXRDb3VudChwYW5lLT5od25kKTsKCWludCBjbnQ7CglIREMgaGRjOwoKCXBhbmUtPndpZHRoc1tjb2xdID0gMDsKCgloZGMgPSBHZXREQyhwYW5lLT5od25kKTsKCWhmb250T2xkID0gU2VsZWN0Rm9udChoZGMsIEdsb2JhbHMuaGZvbnQpOwoKCWZvcihjbnQ9MDsgY250PGVudHJpZXM7IGNudCsrKSB7CgkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgTGlzdEJveF9HZXRJdGVtRGF0YShwYW5lLT5od25kLCBjbnQpOwoJCURSQVdJVEVNU1RSVUNUIGRpczsKCgkJZGlzLkN0bFR5cGUJCSAgPSAwOwoJCWRpcy5DdGxJRAkJICA9IDA7CgkJZGlzLml0ZW1JRAkJICA9IDA7CgkJZGlzLml0ZW1BY3Rpb24JICA9IDA7CgkJZGlzLml0ZW1TdGF0ZQkgID0gMDsKCQlkaXMuaHduZEl0ZW0JICA9IHBhbmUtPmh3bmQ7CgkJZGlzLmhEQwkJCSAgPSBoZGM7CgkJZGlzLnJjSXRlbS5sZWZ0CSAgPSAwOwoJCWRpcy5yY0l0ZW0udG9wICAgID0gMDsKCQlkaXMucmNJdGVtLnJpZ2h0ICA9IDA7CgkJZGlzLnJjSXRlbS5ib3R0b20gPSAwOwoJCS8qZGlzLml0ZW1EYXRhCSAgPSAwOyAqLwoKCQlkcmF3X2l0ZW0ocGFuZSwgJmRpcywgZW50cnksIGNvbCk7Cgl9CgoJU2VsZWN0T2JqZWN0KGhkYywgaGZvbnRPbGQpOwoJUmVsZWFzZURDKHBhbmUtPmh3bmQsIGhkYyk7CgoJY3ggPSBwYW5lLT53aWR0aHNbY29sXTsKCglpZiAoY3gpIHsKCQljeCArPSAzKkdsb2JhbHMuc3BhY2VTaXplLmN4OwoKCQlpZiAoY3ggPCBJTUFHRV9XSURUSCkKCQkJY3ggPSBJTUFHRV9XSURUSDsKCX0KCglwYW5lLT53aWR0aHNbY29sXSA9IGN4OwoKCXggPSBwYW5lLT5wb3NpdGlvbnNbY29sXSArIGN4OwoKCWZvcig7IGNvbDxDT0xVTU5TOyApIHsKCQlwYW5lLT5wb3NpdGlvbnNbKytjb2xdID0geDsKCQl4ICs9IHBhbmUtPndpZHRoc1tjb2xdOwoJfQoKCUxpc3RCb3hfU2V0SG9yaXpvbnRhbEV4dGVudChwYW5lLT5od25kLCB4KTsKfQoKCi8qIGluc2VydCBsaXN0Ym94IGVudHJpZXMgYWZ0ZXIgaW5kZXggaWR4ICovCgpzdGF0aWMgdm9pZCBpbnNlcnRfZW50cmllcyhQYW5lKiBwYW5lLCBFbnRyeSogZGlyLCBpbnQgaWR4KQp7CglFbnRyeSogZW50cnkgPSBkaXI7CgoJaWYgKCFlbnRyeSkKCQlyZXR1cm47CgoJU2hvd1dpbmRvdyhwYW5lLT5od25kLCBTV19ISURFKTsKCglmb3IoOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpIHsKI2lmbmRlZiBfTEVGVF9GSUxFUwoJCWlmIChwYW5lLT50cmVlUGFuZSAmJiAhKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSkKCQkJY29udGludWU7CiNlbmRpZgoKCQkvKiBkb24ndCBkaXNwbGF5IGVudHJpZXMgIi4iIGFuZCAiLi4iIGluIHRoZSBsZWZ0IHBhbmUgKi8KCQlpZiAocGFuZS0+dHJlZVBhbmUgJiYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKQoJCQkJJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT1URVhUKCcuJykpCgkJCWlmICgKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT1URVhUKCdcMCcpIHx8CiNlbmRpZgoJCQkJKGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsxXT09VEVYVCgnLicpICYmIGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsyXT09VEVYVCgnXDAnKSkpCgkJCQljb250aW51ZTsKCgkJaWYgKGlkeCAhPSAtMSkKCQkJaWR4Kys7CgoJCUxpc3RCb3hfSW5zZXJ0SXRlbURhdGEocGFuZS0+aHduZCwgaWR4LCBlbnRyeSk7CgoJCWlmIChwYW5lLT50cmVlUGFuZSAmJiBlbnRyeS0+ZXhwYW5kZWQpIHsKCQkJaW5zZXJ0X2VudHJpZXMocGFuZSwgZW50cnktPmRvd24sIGlkeCk7CgkJCWlkeCA9IExpc3RCb3hfR2V0Q291bnQocGFuZS0+aHduZCktMTsKCQl9Cgl9CgoJU2hvd1dpbmRvdyhwYW5lLT5od25kLCBTV19TSE9XKTsKfQoKCnN0YXRpYyBXTkRQUk9DIGdfb3JnVHJlZVduZFByb2M7CgpzdGF0aWMgdm9pZCBjcmVhdGVfdHJlZV93aW5kb3coSFdORCBwYXJlbnQsIFBhbmUqIHBhbmUsIGludCBpZCwgaW50IGlkX2hlYWRlcikKewoJY29uc3Qgc3RhdGljIFRDSEFSIHNMaXN0Qm94W10gPSB7J0wnLCdpJywncycsJ3QnLCdCJywnbycsJ3gnLCdcMCd9OwoKCXN0YXRpYyBpbnQgc19pbml0ID0gMDsKCUVudHJ5KiBlbnRyeSA9IHBhbmUtPnJvb3Q7CgoJcGFuZS0+aHduZCA9IENyZWF0ZVdpbmRvdyhzTGlzdEJveCwgc0VtcHR5LCBXU19DSElMRHxXU19WSVNJQkxFfFdTX0hTQ1JPTEx8V1NfVlNDUk9MTHwKCQkJCQkJCQlMQlNfRElTQUJMRU5PU0NST0xMfExCU19OT0lOVEVHUkFMSEVJR0hUfExCU19PV05FUkRSQVdGSVhFRHxMQlNfTk9USUZZLAoJCQkJCQkJCTAsIDAsIDAsIDAsIHBhcmVudCwgKEhNRU5VKWlkLCBHbG9iYWxzLmhJbnN0YW5jZSwgMCk7CgoJU2V0V2luZG93TG9uZyhwYW5lLT5od25kLCBHV0xfVVNFUkRBVEEsIChMUEFSQU0pcGFuZSk7CglnX29yZ1RyZWVXbmRQcm9jID0gU3ViY2xhc3NXaW5kb3cocGFuZS0+aHduZCwgVHJlZVduZFByb2MpOwoKCVNldFdpbmRvd0ZvbnQocGFuZS0+aHduZCwgR2xvYmFscy5oZm9udCwgRkFMU0UpOwoKCS8qIGluc2VydCBlbnRyaWVzIGludG8gbGlzdGJveCAqLwoJaWYgKGVudHJ5KQoJCWluc2VydF9lbnRyaWVzKHBhbmUsIGVudHJ5LCAtMSk7CgoJLyogY2FsY3VsYXRlIGNvbHVtbiB3aWR0aHMgKi8KCWlmICghc19pbml0KSB7CgkJc19pbml0ID0gMTsKCQlpbml0X291dHB1dChwYW5lLT5od25kKTsKCX0KCgljYWxjX3dpZHRocyhwYW5lLCBUUlVFKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCXBhbmUtPmh3bmRIZWFkZXIgPSBjcmVhdGVfaGVhZGVyKHBhcmVudCwgcGFuZSwgaWRfaGVhZGVyKTsKI2VuZGlmCn0KCgpzdGF0aWMgdm9pZCBJbml0Q2hpbGRXaW5kb3coQ2hpbGRXbmQqIGNoaWxkKQp7CgljcmVhdGVfdHJlZV93aW5kb3coY2hpbGQtPmh3bmQsICZjaGlsZC0+bGVmdCwgSURXX1RSRUVfTEVGVCwgSURXX0hFQURFUl9MRUZUKTsKCWNyZWF0ZV90cmVlX3dpbmRvdyhjaGlsZC0+aHduZCwgJmNoaWxkLT5yaWdodCwgSURXX1RSRUVfUklHSFQsIElEV19IRUFERVJfUklHSFQpOwp9CgoKc3RhdGljIHZvaWQgZm9ybWF0X2RhdGUoY29uc3QgRklMRVRJTUUqIGZ0LCBUQ0hBUiogYnVmZmVyLCBpbnQgdmlzaWJsZV9jb2xzKQp7CglTWVNURU1USU1FIHN5c3RpbWU7CglGSUxFVElNRSBsZnQ7CglpbnQgbGVuID0gMDsKCgkqYnVmZmVyID0gVEVYVCgnXDAnKTsKCglpZiAoIWZ0LT5kd0xvd0RhdGVUaW1lICYmICFmdC0+ZHdIaWdoRGF0ZVRpbWUpCgkJcmV0dXJuOwoKCWlmICghRmlsZVRpbWVUb0xvY2FsRmlsZVRpbWUoZnQsICZsZnQpKQoJCXtlcnI6IF90Y3NjcHkoYnVmZmVyLHNRTWFya3MpOyByZXR1cm47fQoKCWlmICghRmlsZVRpbWVUb1N5c3RlbVRpbWUoJmxmdCwgJnN5c3RpbWUpKQoJCWdvdG8gZXJyOwoKCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfREFURSkgewoJCWxlbiA9IEdldERhdGVGb3JtYXQoTE9DQUxFX1VTRVJfREVGQVVMVCwgMCwgJnN5c3RpbWUsIDAsIGJ1ZmZlciwgQlVGRkVSX0xFTik7CgkJaWYgKCFsZW4pCgkJCWdvdG8gZXJyOwoJfQoKCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfVElNRSkgewoJCWlmIChsZW4pCgkJCWJ1ZmZlcltsZW4tMV0gPSAnICc7CgoJCWJ1ZmZlcltsZW4rK10gPSAnICc7CgoJCWlmICghR2V0VGltZUZvcm1hdChMT0NBTEVfVVNFUl9ERUZBVUxULCAwLCAmc3lzdGltZSwgMCwgYnVmZmVyK2xlbiwgQlVGRkVSX0xFTi1sZW4pKQoJCQlidWZmZXJbbGVuXSA9IFRFWFQoJ1wwJyk7Cgl9Cn0KCgpzdGF0aWMgdm9pZCBjYWxjX3dpZHRoKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0cikKewoJUkVDVCBydCA9IHswLCAwLCAwLCAwfTsKCglEcmF3VGV4dChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX0NBTENSRUNUfERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVgpOwoKCWlmIChydC5yaWdodCA+IHBhbmUtPndpZHRoc1tjb2xdKQoJCXBhbmUtPndpZHRoc1tjb2xdID0gcnQucmlnaHQ7Cn0KCnN0YXRpYyB2b2lkIGNhbGNfdGFiYmVkX3dpZHRoKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0cikKewoJUkVDVCBydCA9IHswLCAwLCAwLCAwfTsKCi8qCURSQVdURVhUUEFSQU1TIGR0cCA9IHtzaXplb2YoRFJBV1RFWFRQQVJBTVMpLCAyfTsKCURyYXdUZXh0RXgoZGlzLT5oREMsIChMUFRTVFIpc3RyLCAtMSwgJnJ0LCBEVF9DQUxDUkVDVHxEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYfERUX0VYUEFORFRBQlN8RFRfVEFCU1RPUCwgJmR0cCk7Ki8KCglEcmF3VGV4dChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX0NBTENSRUNUfERUX1NJTkdMRUxJTkV8RFRfRVhQQU5EVEFCU3xEVF9UQUJTVE9QfCgyPDw4KSk7CgkvKkZJWE1FIHJ0ICgwLDApID8/PyAqLwoKCWlmIChydC5yaWdodCA+IHBhbmUtPndpZHRoc1tjb2xdKQoJCXBhbmUtPndpZHRoc1tjb2xdID0gcnQucmlnaHQ7Cn0KCgpzdGF0aWMgdm9pZCBvdXRwdXRfdGV4dChQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgaW50IGNvbCwgTFBDVFNUUiBzdHIsIERXT1JEIGZsYWdzKQp7CglpbnQgeCA9IGRpcy0+cmNJdGVtLmxlZnQ7CglSRUNUIHJ0OwoKCXJ0LmxlZnQgICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbF0rR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC50b3AgICAgPSBkaXMtPnJjSXRlbS50b3A7CglydC5yaWdodCAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2wrMV0tR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC5ib3R0b20gPSBkaXMtPnJjSXRlbS5ib3R0b207CgoJRHJhd1RleHQoZGlzLT5oREMsIChMUFRTVFIpc3RyLCAtMSwgJnJ0LCBEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYfGZsYWdzKTsKfQoKc3RhdGljIHZvaWQgb3V0cHV0X3RhYmJlZF90ZXh0KFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0cikKewoJaW50IHggPSBkaXMtPnJjSXRlbS5sZWZ0OwoJUkVDVCBydDsKCglydC5sZWZ0ICAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2xdK0dsb2JhbHMuc3BhY2VTaXplLmN4OwoJcnQudG9wICAgID0gZGlzLT5yY0l0ZW0udG9wOwoJcnQucmlnaHQgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sKzFdLUdsb2JhbHMuc3BhY2VTaXplLmN4OwoJcnQuYm90dG9tID0gZGlzLT5yY0l0ZW0uYm90dG9tOwoKLyoJRFJBV1RFWFRQQVJBTVMgZHRwID0ge3NpemVvZihEUkFXVEVYVFBBUkFNUyksIDJ9OwoJRHJhd1RleHRFeChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVh8RFRfRVhQQU5EVEFCU3xEVF9UQUJTVE9QLCAmZHRwKTsqLwoKCURyYXdUZXh0KGRpcy0+aERDLCAoTFBUU1RSKXN0ciwgLTEsICZydCwgRFRfU0lOR0xFTElORXxEVF9FWFBBTkRUQUJTfERUX1RBQlNUT1B8KDI8PDgpKTsKfQoKc3RhdGljIHZvaWQgb3V0cHV0X251bWJlcihQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgaW50IGNvbCwgTFBDVFNUUiBzdHIpCnsKCWludCB4ID0gZGlzLT5yY0l0ZW0ubGVmdDsKCVJFQ1QgcnQ7CglMUENUU1RSIHMgPSBzdHI7CglUQ0hBUiBiWzEyOF07CglMUFRTVFIgZCA9IGI7CglpbnQgcG9zOwoKCXJ0LmxlZnQgICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbF0rR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC50b3AgICAgPSBkaXMtPnJjSXRlbS50b3A7CglydC5yaWdodCAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2wrMV0tR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC5ib3R0b20gPSBkaXMtPnJjSXRlbS5ib3R0b207CgoJaWYgKCpzKQoJCSpkKysgPSAqcysrOwoKCS8qIGluc2VydCBudW1iZXIgc2VwYXJhdG9yIGNoYXJhY3RlcnMgKi8KCXBvcyA9IGxzdHJsZW4ocykgJSAzOwoKCXdoaWxlKCpzKQoJCWlmIChwb3MtLSkKCQkJKmQrKyA9ICpzKys7CgkJZWxzZSB7CgkJCSpkKysgPSBHbG9iYWxzLm51bV9zZXA7CgkJCXBvcyA9IDM7CgkJfQoKCURyYXdUZXh0KGRpcy0+aERDLCBiLCBkLWIsICZydCwgRFRfUklHSFR8RFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWHxEVF9FTkRfRUxMSVBTSVMpOwp9CgoKc3RhdGljIGludCBpc19leGVfZmlsZShMUENUU1RSIGV4dCkKewoJc3RhdGljIGNvbnN0IFRDSEFSIGV4ZWN1dGFibGVfZXh0ZW5zaW9uc1tdWzRdID0gewoJCXsnQycsJ08nLCdNJywnXDAnfSwKCQl7J0UnLCdYJywnRScsJ1wwJ30sCgkJeydCJywnQScsJ1QnLCdcMCd9LAoJCXsnQycsJ00nLCdEJywnXDAnfSwKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCXsnQycsJ00nLCdNJywnXDAnfSwKCQl7J0InLCdUJywnTScsJ1wwJ30sCgkJeydBJywnVycsJ0snLCdcMCd9LAojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCQl7J1wwJ30KCX07CgoJVENIQVIgZXh0X2J1ZmZlcltfTUFYX0VYVF07Cgljb25zdCBUQ0hBUiAoKnApWzRdOwoJTFBDVFNUUiBzOwoJTFBUU1RSIGQ7CgoJZm9yKHM9ZXh0KzEsZD1leHRfYnVmZmVyOyAoKmQ9dG9sb3dlcigqcykpOyBzKyspCgkJZCsrOwoKCWZvcihwPWV4ZWN1dGFibGVfZXh0ZW5zaW9uczsgKCpwKVswXTsgcCsrKQoJCWlmICghX3Rjc2NtcChleHRfYnVmZmVyLCAqcCkpCgkJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGlzX3JlZ2lzdGVyZWRfdHlwZShMUENUU1RSIGV4dCkKewogICAgICAgIC8qIFRPRE8gKi8KCglyZXR1cm4gMTsKfQoKCnN0YXRpYyB2b2lkIGRyYXdfaXRlbShQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgRW50cnkqIGVudHJ5LCBpbnQgY2FsY1dpZHRoQ29sKQp7CglUQ0hBUiBidWZmZXJbQlVGRkVSX0xFTl07CglEV09SRCBhdHRyczsKCWludCB2aXNpYmxlX2NvbHMgPSBwYW5lLT52aXNpYmxlX2NvbHM7CglDT0xPUlJFRiBia2NvbG9yLCB0ZXh0Y29sb3I7CglSRUNUIGZvY3VzUmVjdCA9IGRpcy0+cmNJdGVtOwoJSEJSVVNIIGhicnVzaDsKCWVudW0gSU1BR0UgaW1nOwoJaW50IGltZ19wb3MsIGN4OwoJaW50IGNvbCA9IDA7CgoJaWYgKGVudHJ5KSB7CgkJYXR0cnMgPSBlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzOwoKCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQkJaWYgKGVudHJ5LT5kYXRhLmNGaWxlTmFtZVswXT09VEVYVCgnLicpICYmIGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsxXT09VEVYVCgnLicpCgkJCQkJJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzJdPT1URVhUKCdcMCcpKQoJCQkJaW1nID0gSU1HX0ZPTERFUl9VUDsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQllbHNlIGlmIChlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF09PVRFWFQoJy4nKSAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMV09PVRFWFQoJ1wwJykpCgkJCQlpbWcgPSBJTUdfRk9MREVSX0NVUjsKI2VuZGlmCgkJCWVsc2UgaWYgKAojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJCQkgZW50cnktPmV4cGFuZGVkIHx8CiNlbmRpZgoJCQkJCSAocGFuZS0+dHJlZVBhbmUgJiYgKGRpcy0+aXRlbVN0YXRlJk9EU19GT0NVUykpKQoJCQkJaW1nID0gSU1HX09QRU5fRk9MREVSOwoJCQllbHNlCgkJCQlpbWcgPSBJTUdfRk9MREVSOwoJCX0gZWxzZSB7CgkJCUxQQ1RTVFIgZXh0ID0gX3Rjc3JjaHIoZW50cnktPmRhdGEuY0ZpbGVOYW1lLCAnLicpOwoJCQlpZiAoIWV4dCkKCQkJCWV4dCA9IHNFbXB0eTsKCgkJCWlmIChpc19leGVfZmlsZShleHQpKQoJCQkJaW1nID0gSU1HX0VYRUNVVEFCTEU7CgkJCWVsc2UgaWYgKGlzX3JlZ2lzdGVyZWRfdHlwZShleHQpKQoJCQkJaW1nID0gSU1HX0RPQ1VNRU5UOwoJCQllbHNlCgkJCQlpbWcgPSBJTUdfRklMRTsKCQl9Cgl9IGVsc2UgewoJCWF0dHJzID0gMDsKCQlpbWcgPSBJTUdfTk9ORTsKCX0KCglpZiAocGFuZS0+dHJlZVBhbmUpIHsKCQlpZiAoZW50cnkpIHsKCQkJaW1nX3BvcyA9IGRpcy0+cmNJdGVtLmxlZnQgKyBlbnRyeS0+bGV2ZWwqKElNQUdFX1dJRFRIK1RSRUVfTElORV9EWCk7CgoJCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKSB7CgkJCQlpbnQgeDsKCQkJCWludCB5ID0gZGlzLT5yY0l0ZW0udG9wICsgSU1BR0VfSEVJR0hULzI7CgkJCQlFbnRyeSogdXA7CgkJCQlSRUNUIHJ0X2NsaXA7CgkJCQlIUkdOIGhyZ25fb3JnID0gQ3JlYXRlUmVjdFJnbigwLCAwLCAwLCAwKTsKCQkJCUhSR04gaHJnbjsKCgkJCQlydF9jbGlwLmxlZnQgICA9IGRpcy0+cmNJdGVtLmxlZnQ7CgkJCQlydF9jbGlwLnRvcCAgICA9IGRpcy0+cmNJdGVtLnRvcDsKCQkJCXJ0X2NsaXAucmlnaHQgID0gZGlzLT5yY0l0ZW0ubGVmdCtwYW5lLT53aWR0aHNbY29sXTsKCQkJCXJ0X2NsaXAuYm90dG9tID0gZGlzLT5yY0l0ZW0uYm90dG9tOwoKCQkJCWhyZ24gPSBDcmVhdGVSZWN0UmduSW5kaXJlY3QoJnJ0X2NsaXApOwoKCQkJCWlmICghR2V0Q2xpcFJnbihkaXMtPmhEQywgaHJnbl9vcmcpKSB7CgkJCQkJRGVsZXRlT2JqZWN0KGhyZ25fb3JnKTsKCQkJCQlocmduX29yZyA9IDA7CgkJCQl9CgoJCQkJLyogSEdESU9CSiBob2xkUGVuID0gU2VsZWN0T2JqZWN0KGRpcy0+aERDLCBHZXRTdG9ja09iamVjdChCTEFDS19QRU4pKTsgKi8KCQkJCUV4dFNlbGVjdENsaXBSZ24oZGlzLT5oREMsIGhyZ24sIFJHTl9BTkQpOwoJCQkJRGVsZXRlT2JqZWN0KGhyZ24pOwoKCQkJCWlmICgodXA9ZW50cnktPnVwKSAhPSBOVUxMKSB7CgkJCQkJTW92ZVRvRXgoZGlzLT5oREMsIGltZ19wb3MtSU1BR0VfV0lEVEgvMiwgeSwgMCk7CgkJCQkJTGluZVRvKGRpcy0+aERDLCBpbWdfcG9zLTIsIHkpOwoKCQkJCQl4ID0gaW1nX3BvcyAtIElNQUdFX1dJRFRILzI7CgoJCQkJCWRvIHsKCQkJCQkJeCAtPSBJTUFHRV9XSURUSCtUUkVFX0xJTkVfRFg7CgoJCQkJCQlpZiAodXAtPm5leHQKI2lmbmRlZiBfTEVGVF9GSUxFUwoJCQkJCQkJJiYgKHVwLT5uZXh0LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpCiNlbmRpZgoJCQkJCQkJKSB7CgkJCQkJCQlNb3ZlVG9FeChkaXMtPmhEQywgeCwgZGlzLT5yY0l0ZW0udG9wLCAwKTsKCQkJCQkJCUxpbmVUbyhkaXMtPmhEQywgeCwgZGlzLT5yY0l0ZW0uYm90dG9tKTsKCQkJCQkJfQoJCQkJCX0gd2hpbGUoKHVwPXVwLT51cCkgIT0gTlVMTCk7CgkJCQl9CgoJCQkJeCA9IGltZ19wb3MgLSBJTUFHRV9XSURUSC8yOwoKCQkJCU1vdmVUb0V4KGRpcy0+aERDLCB4LCBkaXMtPnJjSXRlbS50b3AsIDApOwoJCQkJTGluZVRvKGRpcy0+aERDLCB4LCB5KTsKCgkJCQlpZiAoZW50cnktPm5leHQKI2lmbmRlZiBfTEVGVF9GSUxFUwoJCQkJCSYmIChlbnRyeS0+bmV4dC0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkKI2VuZGlmCgkJCQkJKQoJCQkJCUxpbmVUbyhkaXMtPmhEQywgeCwgZGlzLT5yY0l0ZW0uYm90dG9tKTsKCgkJCQlpZiAoZW50cnktPmRvd24gJiYgZW50cnktPmV4cGFuZGVkKSB7CgkJCQkJeCArPSBJTUFHRV9XSURUSCtUUkVFX0xJTkVfRFg7CgkJCQkJTW92ZVRvRXgoZGlzLT5oREMsIHgsIGRpcy0+cmNJdGVtLnRvcCtJTUFHRV9IRUlHSFQrMiwgMCk7CgkJCQkJTGluZVRvKGRpcy0+aERDLCB4LCBkaXMtPnJjSXRlbS5ib3R0b20pOwoJCQkJfQoKCQkJCVNlbGVjdENsaXBSZ24oZGlzLT5oREMsIGhyZ25fb3JnKTsKCQkJCWlmIChocmduX29yZykgRGVsZXRlT2JqZWN0KGhyZ25fb3JnKTsKCQkJCS8qIFNlbGVjdE9iamVjdChkaXMtPmhEQywgaG9sZFBlbik7ICovCgkJCX0gZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKSB7CgkJCQlpbnQgcmlnaHQgPSBpbWdfcG9zICsgSU1BR0VfV0lEVEggLSBUUkVFX0xJTkVfRFg7CgoJCQkJaWYgKHJpZ2h0ID4gcGFuZS0+d2lkdGhzW2NvbF0pCgkJCQkJcGFuZS0+d2lkdGhzW2NvbF0gPSByaWdodDsKCQkJfQoJCX0gZWxzZSAgewoJCQlpbWdfcG9zID0gZGlzLT5yY0l0ZW0ubGVmdDsKCQl9Cgl9IGVsc2UgewoJCWltZ19wb3MgPSBkaXMtPnJjSXRlbS5sZWZ0OwoKCQlpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQlwYW5lLT53aWR0aHNbY29sXSA9IElNQUdFX1dJRFRIOwoJfQoKCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpIHsKCQlmb2N1c1JlY3QubGVmdCA9IGltZ19wb3MgLTI7CgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQlpZiAocGFuZS0+dHJlZVBhbmUgJiYgZW50cnkpIHsKCQkJUkVDVCBydCA9IHswfTsKCgkJCURyYXdUZXh0KGRpcy0+aERDLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIC0xLCAmcnQsIERUX0NBTENSRUNUfERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVgpOwoKCQkJZm9jdXNSZWN0LnJpZ2h0ID0gZGlzLT5yY0l0ZW0ubGVmdCtwYW5lLT5wb3NpdGlvbnNbY29sKzFdK1RSRUVfTElORV9EWCArIHJ0LnJpZ2h0ICsyOwoJCX0KI2Vsc2UKCgkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfQ09NUFJFU1NFRCkKCQkJdGV4dGNvbG9yID0gQ09MT1JfQ09NUFJFU1NFRDsKCQllbHNlCiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoJCQl0ZXh0Y29sb3IgPSBSR0IoMCwwLDApOwoKCQlpZiAoZGlzLT5pdGVtU3RhdGUgJiBPRFNfRk9DVVMpIHsKCQkJdGV4dGNvbG9yID0gUkdCKDI1NSwyNTUsMjU1KTsKCQkJYmtjb2xvciA9IENPTE9SX1NFTEVDVElPTjsKCQl9IGVsc2UgewoJCQlia2NvbG9yID0gUkdCKDI1NSwyNTUsMjU1KTsKCQl9CgoJCWhicnVzaCA9IENyZWF0ZVNvbGlkQnJ1c2goYmtjb2xvcik7CgkJRmlsbFJlY3QoZGlzLT5oREMsICZmb2N1c1JlY3QsIGhicnVzaCk7CgkJRGVsZXRlT2JqZWN0KGhicnVzaCk7CgoJCVNldEJrTW9kZShkaXMtPmhEQywgVFJBTlNQQVJFTlQpOwoJCVNldFRleHRDb2xvcihkaXMtPmhEQywgdGV4dGNvbG9yKTsKCgkJY3ggPSBwYW5lLT53aWR0aHNbY29sXTsKCgkJaWYgKGN4ICYmIGltZyE9SU1HX05PTkUpIHsKCgkJCWlmIChjeCA+IElNQUdFX1dJRFRIKQoJCQkJY3ggPSBJTUFHRV9XSURUSDsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJCQlpZiAoZW50cnktPmhpY29uICYmIGVudHJ5LT5oaWNvbiE9KEhJQ09OKS0xKQoJCQkJRHJhd0ljb25FeChkaXMtPmhEQywgaW1nX3BvcywgZGlzLT5yY0l0ZW0udG9wLCBlbnRyeS0+aGljb24sIGN4LCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01JQ09OKSwgMCwgMCwgRElfTk9STUFMKTsKCQkJZWxzZQojZW5kaWYKCQkJCUltYWdlTGlzdF9EcmF3RXgoR2xvYmFscy5oaW1sLCBpbWcsIGRpcy0+aERDLAoJCQkJCQkJCSBpbWdfcG9zLCBkaXMtPnJjSXRlbS50b3AsIGN4LAoJCQkJCQkJCSBJTUFHRV9IRUlHSFQsIGJrY29sb3IsIENMUl9ERUZBVUxULCBJTERfTk9STUFMKTsKCQl9Cgl9CgoJaWYgKCFlbnRyeSkKCQlyZXR1cm47CgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCWlmIChpbWcgPj0gSU1HX0ZPTERFUl9VUCkKCQlyZXR1cm47CiNlbmRpZgoKCWNvbCsrOwoKCS8qIG91cHV0IGZpbGUgbmFtZSAqLwoJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgZW50cnktPmRhdGEuY0ZpbGVOYW1lLCAwKTsKCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpOwoKCWNvbCsrOwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCiAgaWYgKCFwYW5lLT50cmVlUGFuZSkgewojZW5kaWYKCiAgICAgICAgLyogZGlzcGxheSBmaWxlIHNpemUgKi8KCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfU0laRSkgewojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQlpZiAoIShhdHRycyZGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpKQojZW5kaWYKCQl7CgkJCVVMT05HTE9ORyBzaXplOwoKICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9ICgoVUxPTkdMT05HKWVudHJ5LT5kYXRhLm5GaWxlU2l6ZUhpZ2ggPDwgMzIpIHwgZW50cnktPmRhdGEubkZpbGVTaXplTG93OwoKCQkJX3N0cHJpbnRmKGJ1ZmZlciwgc0xvbmdOdW1GbXQsIHNpemUpOwoKCQkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJCW91dHB1dF9udW1iZXIocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgkJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7LypUT0RPOiBub3QgZXZlciB0aW1lIGVub3VnaCAqLwoJCX0KCgkJY29sKys7Cgl9CgoJLyogZGlzcGxheSBmaWxlIGRhdGUgKi8KCWlmICh2aXNpYmxlX2NvbHMgJiAoQ09MX0RBVEV8Q09MX1RJTUUpKSB7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQlmb3JtYXRfZGF0ZSgmZW50cnktPmRhdGEuZnRDcmVhdGlvblRpbWUsIGJ1ZmZlciwgdmlzaWJsZV9jb2xzKTsKCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyLCAwKTsKCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgkJY29sKys7CgoJCWZvcm1hdF9kYXRlKCZlbnRyeS0+ZGF0YS5mdExhc3RBY2Nlc3NUaW1lLCBidWZmZXIsIHZpc2libGVfY29scyk7CgkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlciwgMCk7CgkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoJCWNvbCsrOwojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgkJZm9ybWF0X2RhdGUoJmVudHJ5LT5kYXRhLmZ0TGFzdFdyaXRlVGltZSwgYnVmZmVyLCB2aXNpYmxlX2NvbHMpOwoJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIsIDApOwoJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCQljb2wrKzsKCX0KCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWlmIChlbnRyeS0+YmhmaV92YWxpZCkgewogICAgICAgICAgICBVTE9OR0xPTkcgaW5kZXggPSAoKFVMT05HTE9ORyllbnRyeS0+YmhmaS5uRmlsZUluZGV4SGlnaCA8PCAzMikgfCBlbnRyeS0+YmhmaS5uRmlsZUluZGV4TG93OwoKCQlpZiAodmlzaWJsZV9jb2xzICYgQ09MX0lOREVYKSB7CgkJCV9zdHByaW50ZihidWZmZXIsIHNMb25nSGV4Rm10LCBpbmRleCk7CgoJCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlciwgRFRfUklHSFQpOwoJCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoKCQkJY29sKys7CgkJfQoKCQlpZiAodmlzaWJsZV9jb2xzICYgQ09MX0xJTktTKSB7CgkJCXdzcHJpbnRmKGJ1ZmZlciwgc051bUZtdCwgZW50cnktPmJoZmkubk51bWJlck9mTGlua3MpOwoKCQkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIsIERUX0NFTlRFUik7CgkJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgoJCQljb2wrKzsKCQl9Cgl9IGVsc2UKCQljb2wgKz0gMjsKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJLyogc2hvdyBmaWxlIGF0dHJpYnV0ZXMgKi8KCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfQVRUUklCVVRFUykgewojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQljb25zdCBzdGF0aWMgVENIQVIgczRUYWJzW10gPSB7JyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcMCd9OwoJCV90Y3NjcHkoYnVmZmVyLCBzNFRhYnMpOwojZWxzZQoJCWNvbnN0IHN0YXRpYyBUQ0hBUiBzMTFUYWJzW10gPSB7JyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcMCd9OwoJCV90Y3NjcHkoYnVmZmVyLCBzMTFUYWJzKTsKI2VuZGlmCgoJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX05PUk1BTCkJCQkJCWJ1ZmZlclsgMF0gPSAnTic7CgkJZWxzZSB7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX1JFQURPTkxZKQkJCWJ1ZmZlclsgMl0gPSAnUic7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0hJRERFTikJCQkJYnVmZmVyWyA0XSA9ICdIJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfU1lTVEVNKQkJCQlidWZmZXJbIDZdID0gJ1MnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9BUkNISVZFKQkJCQlidWZmZXJbIDhdID0gJ0EnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9DT01QUkVTU0VEKQkJCWJ1ZmZlclsxMF0gPSAnQyc7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKQkJCWJ1ZmZlclsxMl0gPSAnRCc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0VOQ1JZUFRFRCkJCQlidWZmZXJbMTRdID0gJ0UnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9URU1QT1JBUlkpCQkJYnVmZmVyWzE2XSA9ICdUJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfU1BBUlNFX0ZJTEUpCQkJYnVmZmVyWzE4XSA9ICdQJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfUkVQQVJTRV9QT0lOVCkJCWJ1ZmZlclsyMF0gPSAnUSc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX09GRkxJTkUpCQkJCWJ1ZmZlclsyMl0gPSAnTyc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX05PVF9DT05URU5UX0lOREVYRUQpCWJ1ZmZlclsyNF0gPSAnWCc7CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoJCX0KCgkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJb3V0cHV0X3RhYmJlZF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJY2FsY190YWJiZWRfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgoJCWNvbCsrOwoJfQoKLypUT0RPCglpZiAoZmxhZ3Muc2VjdXJpdHkpIHsKCQljb25zdCBzdGF0aWMgVENIQVIgc1NlY1RhYnNbXSA9IHsKCQkJJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLAoJCQknICcsJ1x0JywnICcsCgkJCScgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywKCQkJJyAnLCdcdCcsJyAnLAoJCQknICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsCgkJCSdcMCcKCQl9OwoKCQlEV09SRCByaWdodHMgPSBnZXRfYWNjZXNzX21hc2soKTsKCgkJdGNzY3B5KGJ1ZmZlciwgc1NlY1RhYnMpOwoKCQlpZiAocmlnaHRzICYgRklMRV9SRUFEX0RBVEEpCQkJYnVmZmVyWyAwXSA9ICdSJzsKCQlpZiAocmlnaHRzICYgRklMRV9XUklURV9EQVRBKQkJCWJ1ZmZlclsgMl0gPSAnVyc7CgkJaWYgKHJpZ2h0cyAmIEZJTEVfQVBQRU5EX0RBVEEpCQkJYnVmZmVyWyA0XSA9ICdBJzsKCQlpZiAocmlnaHRzICYgRklMRV9SRUFEX0VBKQkJCQl7YnVmZmVyWzZdID0gJ2VudHJ5JzsgYnVmZmVyWyA3XSA9ICdSJzt9CgkJaWYgKHJpZ2h0cyAmIEZJTEVfV1JJVEVfRUEpCQkJCXtidWZmZXJbOV0gPSAnZW50cnknOyBidWZmZXJbMTBdID0gJ1cnO30KCQlpZiAocmlnaHRzICYgRklMRV9FWEVDVVRFKQkJCQlidWZmZXJbMTJdID0gJ1gnOwoJCWlmIChyaWdodHMgJiBGSUxFX0RFTEVURV9DSElMRCkJCQlidWZmZXJbMTRdID0gJ0QnOwoJCWlmIChyaWdodHMgJiBGSUxFX1JFQURfQVRUUklCVVRFUykJCXtidWZmZXJbMTZdID0gJ2EnOyBidWZmZXJbMTddID0gJ1InO30KCQlpZiAocmlnaHRzICYgRklMRV9XUklURV9BVFRSSUJVVEVTKQkJe2J1ZmZlclsxOV0gPSAnYSc7IGJ1ZmZlclsyMF0gPSAnVyc7fQoJCWlmIChyaWdodHMgJiBXUklURV9EQUMpCQkJCQlidWZmZXJbMjJdID0gJ0MnOwoJCWlmIChyaWdodHMgJiBXUklURV9PV05FUikJCQkJYnVmZmVyWzI0XSA9ICdPJzsKCQlpZiAocmlnaHRzICYgU1lOQ0hST05JWkUpCQkJCWJ1ZmZlclsyNl0gPSAnUyc7CgoJCW91dHB1dF90ZXh0KGRpcywgY29sKyssIGJ1ZmZlciwgRFRfTEVGVCwgMywgcHNpemUpOwoJfQoKCWlmIChmbGFncy5kZXNjcmlwdGlvbikgewoJCWdldF9kZXNjcmlwdGlvbihidWZmZXIpOwoJCW91dHB1dF90ZXh0KGRpcywgY29sKyssIGJ1ZmZlciwgMCwgcHNpemUpOwoJfQoqLwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCiAgfQoKICAgICAgICAvKiBkcmF3IGZvY3VzIGZyYW1lICovCglpZiAoKGRpcy0+aXRlbVN0YXRlJk9EU19GT0NVUykgJiYgY2FsY1dpZHRoQ29sPT0tMSkgewoJICAgICAgICAvKiBDdXJyZW50bHkgWzA0LzIwMDBdIFdpbmUgbmVpdGhlciBiZWhhdmVzIGV4YWN0bHkgdGhlIHNhbWUgKi8KCSAgICAgICAgLyogd2F5IGFzIFdJTiA5NSBub3IgbGlrZSBXaW5kb3dzIE5ULi4uICovCgkJSEdESU9CSiBsYXN0QnJ1c2g7CgkJSFBFTiBsYXN0UGVuOwoJCUhQRU4gaHBlbjsKCgkJaWYgKCEoR2V0VmVyc2lvbigpICYgMHg4MDAwMDAwMCkpIHsJLyogV2luZG93cyBOVD8gKi8KCQkJTE9HQlJVU0ggbGIgPSB7UFNfU09MSUQsIFJHQigyNTUsMjU1LDI1NSl9OwoJCQlocGVuID0gRXh0Q3JlYXRlUGVuKFBTX0NPU01FVElDfFBTX0FMVEVSTkFURSwgMSwgJmxiLCAwLCAwKTsKCQl9IGVsc2UKCQkJaHBlbiA9IENyZWF0ZVBlbihQU19ET1QsIDAsIFJHQigyNTUsMjU1LDI1NSkpOwoKCQlsYXN0UGVuID0gU2VsZWN0UGVuKGRpcy0+aERDLCBocGVuKTsKCQlsYXN0QnJ1c2ggPSBTZWxlY3RPYmplY3QoZGlzLT5oREMsIEdldFN0b2NrT2JqZWN0KEhPTExPV19CUlVTSCkpOwoJCVNldFJPUDIoZGlzLT5oREMsIFIyX1hPUlBFTik7CgkJUmVjdGFuZ2xlKGRpcy0+aERDLCBmb2N1c1JlY3QubGVmdCwgZm9jdXNSZWN0LnRvcCwgZm9jdXNSZWN0LnJpZ2h0LCBmb2N1c1JlY3QuYm90dG9tKTsKCQlTZWxlY3RPYmplY3QoZGlzLT5oREMsIGxhc3RCcnVzaCk7CgkJU2VsZWN0T2JqZWN0KGRpcy0+aERDLCBsYXN0UGVuKTsKCQlEZWxldGVPYmplY3QoaHBlbik7Cgl9CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwp9CgoKI2lmZGVmIF9OT19FWFRFTlNJT05TCgpzdGF0aWMgdm9pZCBkcmF3X3NwbGl0YmFyKEhXTkQgaHduZCwgaW50IHgpCnsKCVJFQ1QgcnQ7CglIREMgaGRjID0gR2V0REMoaHduZCk7CgoJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoKCXJ0LmxlZnQgPSB4IC0gU1BMSVRfV0lEVEgvMjsKCXJ0LnJpZ2h0ID0geCArIFNQTElUX1dJRFRILzIrMTsKCglJbnZlcnRSZWN0KGhkYywgJnJ0KTsKCglSZWxlYXNlREMoaHduZCwgaGRjKTsKfQoKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoKc3RhdGljIHZvaWQgc2V0X2hlYWRlcihQYW5lKiBwYW5lKQp7CglIRF9JVEVNIGl0ZW07CglpbnQgc2Nyb2xsX3BvcyA9IEdldFNjcm9sbFBvcyhwYW5lLT5od25kLCBTQl9IT1JaKTsKCWludCBpPTAsIHg9MDsKCglpdGVtLm1hc2sgPSBIRElfV0lEVEg7CglpdGVtLmN4eSA9IDA7CgoJZm9yKDsgeCtwYW5lLT53aWR0aHNbaV08c2Nyb2xsX3BvcyAmJiBpPENPTFVNTlM7IGkrKykgewoJCXggKz0gcGFuZS0+d2lkdGhzW2ldOwoJCUhlYWRlcl9TZXRJdGVtKHBhbmUtPmh3bmRIZWFkZXIsIGksICZpdGVtKTsKCX0KCglpZiAoaSA8IENPTFVNTlMpIHsKCQl4ICs9IHBhbmUtPndpZHRoc1tpXTsKCQlpdGVtLmN4eSA9IHggLSBzY3JvbGxfcG9zOwoJCUhlYWRlcl9TZXRJdGVtKHBhbmUtPmh3bmRIZWFkZXIsIGkrKywgJml0ZW0pOwoKCQlmb3IoOyBpPENPTFVNTlM7IGkrKykgewoJCQlpdGVtLmN4eSA9IHBhbmUtPndpZHRoc1tpXTsKCQkJeCArPSBwYW5lLT53aWR0aHNbaV07CgkJCUhlYWRlcl9TZXRJdGVtKHBhbmUtPmh3bmRIZWFkZXIsIGksICZpdGVtKTsKCQl9Cgl9Cn0KCnN0YXRpYyBMUkVTVUxUIHBhbmVfbm90aWZ5KFBhbmUqIHBhbmUsIE5NSERSKiBwbm1oKQp7Cglzd2l0Y2gocG5taC0+Y29kZSkgewoJCWNhc2UgSEROX1RSQUNLOgoJCWNhc2UgSEROX0VORFRSQUNLOiB7CgkJCUhEX05PVElGWSogcGhkbiA9IChIRF9OT1RJRlkqKSBwbm1oOwoJCQlpbnQgaWR4ID0gcGhkbi0+aUl0ZW07CgkJCWludCBkeCA9IHBoZG4tPnBpdGVtLT5jeHkgLSBwYW5lLT53aWR0aHNbaWR4XTsKCQkJaW50IGk7CgoJCQlSRUNUIGNsbnQ7CgkJCUdldENsaWVudFJlY3QocGFuZS0+aHduZCwgJmNsbnQpOwoKCQkJLyogbW92ZSBpbW1lZGlhdGUgdG8gc2ltdWxhdGUgSERTX0ZVTExEUkFHIChmb3Igbm93IFswNC8yMDAwXSBub3QgcmVhbGx5IG5lZWRlZCB3aXRoIFdJTkVMSUIpICovCgkJCUhlYWRlcl9TZXRJdGVtKHBhbmUtPmh3bmRIZWFkZXIsIGlkeCwgcGhkbi0+cGl0ZW0pOwoKCQkJcGFuZS0+d2lkdGhzW2lkeF0gKz0gZHg7CgoJCQlmb3IoaT1pZHg7ICsraTw9Q09MVU1OUzsgKQoJCQkJcGFuZS0+cG9zaXRpb25zW2ldICs9IGR4OwoKCQkJewoJCQkJaW50IHNjcm9sbF9wb3MgPSBHZXRTY3JvbGxQb3MocGFuZS0+aHduZCwgU0JfSE9SWik7CgkJCQlSRUNUIHJ0X3NjcjsKCQkJCVJFQ1QgcnRfY2xpcDsKCgkJCQlydF9zY3IubGVmdCAgID0gcGFuZS0+cG9zaXRpb25zW2lkeCsxXS1zY3JvbGxfcG9zOwoJCQkJcnRfc2NyLnRvcCAgICA9IDA7CgkJCQlydF9zY3IucmlnaHQgID0gY2xudC5yaWdodDsKCQkJCXJ0X3Njci5ib3R0b20gPSBjbG50LmJvdHRvbTsKCgkJCQlydF9jbGlwLmxlZnQgICA9IHBhbmUtPnBvc2l0aW9uc1tpZHhdLXNjcm9sbF9wb3M7CgkJCQlydF9jbGlwLnRvcCAgICA9IDA7CgkJCQlydF9jbGlwLnJpZ2h0ICA9IGNsbnQucmlnaHQ7CgkJCQlydF9jbGlwLmJvdHRvbSA9IGNsbnQuYm90dG9tOwoKCQkJCWlmIChydF9zY3IubGVmdCA8IDApIHJ0X3Njci5sZWZ0ID0gMDsKCQkJCWlmIChydF9jbGlwLmxlZnQgPCAwKSBydF9jbGlwLmxlZnQgPSAwOwoKCQkJCVNjcm9sbFdpbmRvd0V4KHBhbmUtPmh3bmQsIGR4LCAwLCAmcnRfc2NyLCAmcnRfY2xpcCwgMCwgMCwgU1dfSU5WQUxJREFURSk7CgoJCQkJcnRfY2xpcC5yaWdodCA9IHBhbmUtPnBvc2l0aW9uc1tpZHgrMV07CgkJCQlSZWRyYXdXaW5kb3cocGFuZS0+aHduZCwgJnJ0X2NsaXAsIDAsIFJEV19JTlZBTElEQVRFfFJEV19VUERBVEVOT1cpOwoKCQkJCWlmIChwbm1oLT5jb2RlID09IEhETl9FTkRUUkFDSykgewoJCQkJCUxpc3RCb3hfU2V0SG9yaXpvbnRhbEV4dGVudChwYW5lLT5od25kLCBwYW5lLT5wb3NpdGlvbnNbQ09MVU1OU10pOwoKCQkJCQlpZiAoR2V0U2Nyb2xsUG9zKHBhbmUtPmh3bmQsIFNCX0hPUlopICE9IHNjcm9sbF9wb3MpCgkJCQkJCXNldF9oZWFkZXIocGFuZSk7CgkJCQl9CgkJCX0KCgkJCXJldHVybiBGQUxTRTsKCQl9CgoJCWNhc2UgSEROX0RJVklERVJEQkxDTElDSzogewoJCQlIRF9OT1RJRlkqIHBoZG4gPSAoSERfTk9USUZZKikgcG5taDsKCQkJSERfSVRFTSBpdGVtOwoKCQkJY2FsY19zaW5nbGVfd2lkdGgocGFuZSwgcGhkbi0+aUl0ZW0pOwoJCQlpdGVtLm1hc2sgPSBIRElfV0lEVEg7CgkJCWl0ZW0uY3h5ID0gcGFuZS0+d2lkdGhzW3BoZG4tPmlJdGVtXTsKCgkJCUhlYWRlcl9TZXRJdGVtKHBhbmUtPmh3bmRIZWFkZXIsIHBoZG4tPmlJdGVtLCAmaXRlbSk7CgkJCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoJCQlicmVhazt9Cgl9CgoJcmV0dXJuIDA7Cn0KCiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCnN0YXRpYyB2b2lkIHNjYW5fZW50cnkoQ2hpbGRXbmQqIGNoaWxkLCBFbnRyeSogZW50cnksIEhXTkQgaHduZCkKewoJVENIQVIgcGF0aFtNQVhfUEFUSF07CglpbnQgaWR4ID0gTGlzdEJveF9HZXRDdXJTZWwoY2hpbGQtPmxlZnQuaHduZCk7CglIQ1VSU09SIG9sZF9jdXJzb3IgPSBTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfV0FJVCkpOwoKCS8qIGRlbGV0ZSBzdWIgZW50cmllcyBpbiBsZWZ0IHBhbmUgKi8KCWZvcig7OykgewoJCUxSRVNVTFQgcmVzID0gTGlzdEJveF9HZXRJdGVtRGF0YShjaGlsZC0+bGVmdC5od25kLCBpZHgrMSk7CgkJRW50cnkqIHN1YiA9IChFbnRyeSopIHJlczsKCgkJaWYgKHJlcz09TEJfRVJSIHx8ICFzdWIgfHwgc3ViLT5sZXZlbDw9ZW50cnktPmxldmVsKQoJCQlicmVhazsKCgkJTGlzdEJveF9EZWxldGVTdHJpbmcoY2hpbGQtPmxlZnQuaHduZCwgaWR4KzEpOwoJfQoKCS8qIGVtcHR5IHJpZ2h0IHBhbmUgKi8KCUxpc3RCb3hfUmVzZXRDb250ZW50KGNoaWxkLT5yaWdodC5od25kKTsKCgkvKiByZWxlYXNlIG1lbW9yeSAqLwoJZnJlZV9lbnRyaWVzKGVudHJ5KTsKCgkvKiByZWFkIGNvbnRlbnRzIGZyb20gZGlzayAqLwojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChlbnRyeS0+ZXR5cGUgPT0gRVRfU0hFTEwpCgl7CgkJcmVhZF9kaXJlY3RvcnkoZW50cnksIE5VTEwsIGNoaWxkLT5zb3J0T3JkZXIsIGh3bmQpOwoJfQoJZWxzZQojZW5kaWYKCXsKCQlnZXRfcGF0aChlbnRyeSwgcGF0aCk7CgkJcmVhZF9kaXJlY3RvcnkoZW50cnksIHBhdGgsIGNoaWxkLT5zb3J0T3JkZXIsIGh3bmQpOwoJfQoKCS8qIGluc2VydCBmb3VuZCBlbnRyaWVzIGluIHJpZ2h0IHBhbmUgKi8KCWluc2VydF9lbnRyaWVzKCZjaGlsZC0+cmlnaHQsIGVudHJ5LT5kb3duLCAtMSk7CgljYWxjX3dpZHRocygmY2hpbGQtPnJpZ2h0LCBGQUxTRSk7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCXNldF9oZWFkZXIoJmNoaWxkLT5yaWdodCk7CiNlbmRpZgoKCWNoaWxkLT5oZWFkZXJfd2R0aHNfb2sgPSBGQUxTRTsKCglTZXRDdXJzb3Iob2xkX2N1cnNvcik7Cn0KCgovKiBleHBhbmQgYSBkaXJlY3RvcnkgZW50cnkgKi8KCnN0YXRpYyBCT09MIGV4cGFuZF9lbnRyeShDaGlsZFduZCogY2hpbGQsIEVudHJ5KiBkaXIpCnsKCWludCBpZHg7CglFbnRyeSogcDsKCglpZiAoIWRpciB8fCBkaXItPmV4cGFuZGVkIHx8ICFkaXItPmRvd24pCgkJcmV0dXJuIEZBTFNFOwoKCXAgPSBkaXItPmRvd247CgoJaWYgKHAtPmRhdGEuY0ZpbGVOYW1lWzBdPT0nLicgJiYgcC0+ZGF0YS5jRmlsZU5hbWVbMV09PSdcMCcgJiYgcC0+bmV4dCkgewoJCXAgPSBwLT5uZXh0OwoKCQlpZiAocC0+ZGF0YS5jRmlsZU5hbWVbMF09PScuJyAmJiBwLT5kYXRhLmNGaWxlTmFtZVsxXT09Jy4nICYmCgkJCQlwLT5kYXRhLmNGaWxlTmFtZVsyXT09J1wwJyAmJiBwLT5uZXh0KQoJCQlwID0gcC0+bmV4dDsKCX0KCgkvKiBubyBzdWJkaXJlY3RvcmllcyA/ICovCglpZiAoIShwLT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSkKCQlyZXR1cm4gRkFMU0U7CgoJaWR4ID0gTGlzdEJveF9GaW5kSXRlbURhdGEoY2hpbGQtPmxlZnQuaHduZCwgMCwgZGlyKTsKCglkaXItPmV4cGFuZGVkID0gVFJVRTsKCgkvKiBpbnNlcnQgZW50cmllcyBpbiBsZWZ0IHBhbmUgKi8KCWluc2VydF9lbnRyaWVzKCZjaGlsZC0+bGVmdCwgcCwgaWR4KTsKCglpZiAoIWNoaWxkLT5oZWFkZXJfd2R0aHNfb2spIHsKCQlpZiAoY2FsY193aWR0aHMoJmNoaWxkLT5sZWZ0LCBGQUxTRSkpIHsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQlzZXRfaGVhZGVyKCZjaGlsZC0+bGVmdCk7CiNlbmRpZgoKCQkJY2hpbGQtPmhlYWRlcl93ZHRoc19vayA9IFRSVUU7CgkJfQoJfQoKCXJldHVybiBUUlVFOwp9CgoKc3RhdGljIHZvaWQgY29sbGFwc2VfZW50cnkoUGFuZSogcGFuZSwgRW50cnkqIGRpcikKewoJaW50IGlkeCA9IExpc3RCb3hfRmluZEl0ZW1EYXRhKHBhbmUtPmh3bmQsIDAsIGRpcik7CgoJU2hvd1dpbmRvdyhwYW5lLT5od25kLCBTV19ISURFKTsKCgkvKiBoaWRlIHN1YiBlbnRyaWVzICovCglmb3IoOzspIHsKCQlMUkVTVUxUIHJlcyA9IExpc3RCb3hfR2V0SXRlbURhdGEocGFuZS0+aHduZCwgaWR4KzEpOwoJCUVudHJ5KiBzdWIgPSAoRW50cnkqKSByZXM7CgoJCWlmIChyZXM9PUxCX0VSUiB8fCAhc3ViIHx8IHN1Yi0+bGV2ZWw8PWRpci0+bGV2ZWwpCgkJCWJyZWFrOwoKCQlMaXN0Qm94X0RlbGV0ZVN0cmluZyhwYW5lLT5od25kLCBpZHgrMSk7Cgl9CgoJZGlyLT5leHBhbmRlZCA9IEZBTFNFOwoKCVNob3dXaW5kb3cocGFuZS0+aHduZCwgU1dfU0hPVyk7Cn0KCgpzdGF0aWMgdm9pZCBzZXRfY3VyZGlyKENoaWxkV25kKiBjaGlsZCwgRW50cnkqIGVudHJ5LCBIV05EIGh3bmQpCnsKCVRDSEFSIHBhdGhbTUFYX1BBVEhdOwoKCXBhdGhbMF0gPSAnXDAnOwoKCWNoaWxkLT5sZWZ0LmN1ciA9IGVudHJ5OwoJY2hpbGQtPnJpZ2h0LnJvb3QgPSBlbnRyeS0+ZG93bj8gZW50cnktPmRvd246IGVudHJ5OwoJY2hpbGQtPnJpZ2h0LmN1ciA9IGVudHJ5OwoKCWlmICghZW50cnktPnNjYW5uZWQpCgkJc2Nhbl9lbnRyeShjaGlsZCwgZW50cnksIGh3bmQpOwoJZWxzZSB7CgkJTGlzdEJveF9SZXNldENvbnRlbnQoY2hpbGQtPnJpZ2h0Lmh3bmQpOwoJCWluc2VydF9lbnRyaWVzKCZjaGlsZC0+cmlnaHQsIGVudHJ5LT5kb3duLCAtMSk7CgkJY2FsY193aWR0aHMoJmNoaWxkLT5yaWdodCwgRkFMU0UpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJc2V0X2hlYWRlcigmY2hpbGQtPnJpZ2h0KTsKI2VuZGlmCgl9CgoJZ2V0X3BhdGgoZW50cnksIHBhdGgpOwoJbHN0cmNweShjaGlsZC0+cGF0aCwgcGF0aCk7CgoJaWYgKGNoaWxkLT5od25kKQkvKiBvbmx5IGNoYW5nZSB3aW5kb3cgdGl0bGUsIGlmIHRoZSB3aW5kb3cgYWxyZWFkeSBleGlzdHMgKi8KCQlTZXRXaW5kb3dUZXh0KGNoaWxkLT5od25kLCBwYXRoKTsKCglpZiAocGF0aFswXSkKCQlTZXRDdXJyZW50RGlyZWN0b3J5KHBhdGgpOwp9CgoKQk9PTCBsYXVuY2hfZmlsZShIV05EIGh3bmQsIExQQ1RTVFIgY21kLCBVSU5UIG5DbWRTaG93KQp7CglISU5TVEFOQ0UgaGluc3QgPSBTaGVsbEV4ZWN1dGUoaHduZCwgTlVMTC8qb3BlcmF0aW9uKi8sIGNtZCwgTlVMTC8qcGFyYW1ldGVycyovLCBOVUxMLypkaXIqLywgbkNtZFNob3cpOwoKCWlmICgoaW50KWhpbnN0IDw9IDMyKSB7CgkJZGlzcGxheV9lcnJvcihod25kLCBHZXRMYXN0RXJyb3IoKSk7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCXJldHVybiBUUlVFOwp9CgojaWZkZWYgVU5JQ09ERQpCT09MIGxhdW5jaF9maWxlQShIV05EIGh3bmQsIExQU1RSIGNtZCwgVUlOVCBuQ21kU2hvdykKewoJSElOU1RBTkNFIGhpbnN0ID0gU2hlbGxFeGVjdXRlQShod25kLCBOVUxMLypvcGVyYXRpb24qLywgY21kLCBOVUxMLypwYXJhbWV0ZXJzKi8sIE5VTEwvKmRpciovLCBuQ21kU2hvdyk7CgoJaWYgKChpbnQpaGluc3QgPD0gMzIpIHsKCQlkaXNwbGF5X2Vycm9yKGh3bmQsIEdldExhc3RFcnJvcigpKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KI2VuZGlmCgoKQk9PTCBsYXVuY2hfZW50cnkoRW50cnkqIGVudHJ5LCBIV05EIGh3bmQsIFVJTlQgbkNtZFNob3cpCnsKCVRDSEFSIGNtZFtNQVhfUEFUSF07CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChlbnRyeS0+ZXR5cGUgPT0gRVRfU0hFTEwpIHsKCQlCT09MIHJldCA9IFRSVUU7CgoJCVNIRUxMRVhFQ1VURUlORk8gc2hleGluZm87CgoJCXNoZXhpbmZvLmNiU2l6ZSA9IHNpemVvZihTSEVMTEVYRUNVVEVJTkZPKTsKCQlzaGV4aW5mby5mTWFzayA9IFNFRV9NQVNLX0lETElTVDsKCQlzaGV4aW5mby5od25kID0gaHduZDsKCQlzaGV4aW5mby5scFZlcmIgPSBOVUxMOwoJCXNoZXhpbmZvLmxwRmlsZSA9IE5VTEw7CgkJc2hleGluZm8ubHBQYXJhbWV0ZXJzID0gTlVMTDsKCQlzaGV4aW5mby5scERpcmVjdG9yeSA9IE5VTEw7CgkJc2hleGluZm8ublNob3cgPSBuQ21kU2hvdzsKCQlzaGV4aW5mby5scElETGlzdCA9IGdldF90b19hYnNvbHV0ZV9waWRsKGVudHJ5LCBod25kKTsKCgkJaWYgKCFTaGVsbEV4ZWN1dGVFeCgmc2hleGluZm8pKSB7CgkJCWRpc3BsYXlfZXJyb3IoaHduZCwgR2V0TGFzdEVycm9yKCkpOwoJCQlyZXQgPSBGQUxTRTsKCQl9CgoJCWlmIChzaGV4aW5mby5scElETGlzdCAhPSBlbnRyeS0+cGlkbCkKCQkJKCpHbG9iYWxzLmlNYWxsb2MtPmxwVnRibC0+RnJlZSkoR2xvYmFscy5pTWFsbG9jLCBzaGV4aW5mby5scElETGlzdCk7CgoJCXJldHVybiByZXQ7Cgl9CiNlbmRpZgoKCWdldF9wYXRoKGVudHJ5LCBjbWQpOwoKCSAvKiBzdGFydCBwcm9ncmFtLCBvcGVuIGRvY3VtZW50Li4uICovCglyZXR1cm4gbGF1bmNoX2ZpbGUoaHduZCwgY21kLCBuQ21kU2hvdyk7Cn0KCgpzdGF0aWMgdm9pZCBhY3RpdmF0ZV9lbnRyeShDaGlsZFduZCogY2hpbGQsIFBhbmUqIHBhbmUsIEhXTkQgaHduZCkKewoJRW50cnkqIGVudHJ5ID0gcGFuZS0+Y3VyOwoKCWlmICghZW50cnkpCgkJcmV0dXJuOwoKCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJaW50IHNjYW5uZWRfb2xkID0gZW50cnktPnNjYW5uZWQ7CgoJCWlmICghc2Nhbm5lZF9vbGQpCgkJCXNjYW5fZW50cnkoY2hpbGQsIGVudHJ5LCBod25kKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQlpZiAoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT0nLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT0nXDAnKQoJCQlyZXR1cm47CiNlbmRpZgoKCQlpZiAoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT0nLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT0nLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzJdPT0nXDAnKSB7CgkJCWVudHJ5ID0gY2hpbGQtPmxlZnQuY3VyLT51cDsKCQkJY29sbGFwc2VfZW50cnkoJmNoaWxkLT5sZWZ0LCBlbnRyeSk7CgkJCWdvdG8gZm9jdXNfZW50cnk7CgkJfSBlbHNlIGlmIChlbnRyeS0+ZXhwYW5kZWQpCgkJCWNvbGxhcHNlX2VudHJ5KHBhbmUsIGNoaWxkLT5sZWZ0LmN1cik7CgkJZWxzZSB7CgkJCWV4cGFuZF9lbnRyeShjaGlsZCwgY2hpbGQtPmxlZnQuY3VyKTsKCgkJCWlmICghcGFuZS0+dHJlZVBhbmUpIGZvY3VzX2VudHJ5OiB7CgkJCQlpbnQgaWR4ID0gTGlzdEJveF9GaW5kSXRlbURhdGEoY2hpbGQtPmxlZnQuaHduZCwgTGlzdEJveF9HZXRDdXJTZWwoY2hpbGQtPmxlZnQuaHduZCksIGVudHJ5KTsKCQkJCUxpc3RCb3hfU2V0Q3VyU2VsKGNoaWxkLT5sZWZ0Lmh3bmQsIGlkeCk7CgkJCQlzZXRfY3VyZGlyKGNoaWxkLCBlbnRyeSwgaHduZCk7CgkJCX0KCQl9CgoJCWlmICghc2Nhbm5lZF9vbGQpIHsKCQkJY2FsY193aWR0aHMocGFuZSwgRkFMU0UpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQlzZXRfaGVhZGVyKHBhbmUpOwojZW5kaWYKCQl9Cgl9IGVsc2UgewoJCWxhdW5jaF9lbnRyeShlbnRyeSwgY2hpbGQtPmh3bmQsIFNXX1NIT1dOT1JNQUwpOwoJfQp9CgoKc3RhdGljIEJPT0wgcGFuZV9jb21tYW5kKFBhbmUqIHBhbmUsIFVJTlQgY21kKQp7Cglzd2l0Y2goY21kKSB7CgkJY2FzZSBJRF9WSUVXX05BTUU6CgkJCWlmIChwYW5lLT52aXNpYmxlX2NvbHMpIHsKCQkJCXBhbmUtPnZpc2libGVfY29scyA9IDA7CgkJCQljYWxjX3dpZHRocyhwYW5lLCBUUlVFKTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJc2V0X2hlYWRlcihwYW5lKTsKI2VuZGlmCgkJCQlJbnZhbGlkYXRlUmVjdChwYW5lLT5od25kLCAwLCBUUlVFKTsKCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfTkFNRSwgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19BTExfQVRUUklCVVRFUywgTUZfQllDT01NQU5EKTsKCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfU0VMRUNURURfQVRUUklCVVRFUywgTUZfQllDT01NQU5EKTsKCQkJfQoJCQlicmVhazsKCgkJY2FzZSBJRF9WSUVXX0FMTF9BVFRSSUJVVEVTOgoJCQlpZiAocGFuZS0+dmlzaWJsZV9jb2xzICE9IENPTF9BTEwpIHsKCQkJCXBhbmUtPnZpc2libGVfY29scyA9IENPTF9BTEw7CgkJCQljYWxjX3dpZHRocyhwYW5lLCBUUlVFKTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJc2V0X2hlYWRlcihwYW5lKTsKI2VuZGlmCgkJCQlJbnZhbGlkYXRlUmVjdChwYW5lLT5od25kLCAwLCBUUlVFKTsKCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfTkFNRSwgTUZfQllDT01NQU5EKTsKCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfQUxMX0FUVFJJQlVURVMsIE1GX0JZQ09NTUFORHxNRl9DSEVDS0VEKTsKCQkJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfU0VMRUNURURfQVRUUklCVVRFUywgTUZfQllDT01NQU5EKTsKCQkJfQoJCQlicmVhazsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQljYXNlIElEX1BSRUZFUkVEX1NJWkVTOiB7CgkJCWNhbGNfd2lkdGhzKHBhbmUsIFRSVUUpOwoJCQlzZXRfaGVhZGVyKHBhbmUpOwoJCQlJbnZhbGlkYXRlUmVjdChwYW5lLT5od25kLCAwLCBUUlVFKTsKCQkJYnJlYWs7fQojZW5kaWYKCgkJICAgICAgICAvKiBUT0RPOiBtb3JlIGNvbW1hbmQgaWRzLi4uICovCgoJCWRlZmF1bHQ6CgkJCXJldHVybiBGQUxTRTsKCX0KCglyZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyBIUkVTVUxUIFNoZWxsRm9sZGVyQ29udGV4dE1lbnUoSVNoZWxsRm9sZGVyKiBzaGVsbF9mb2xkZXIsIEhXTkQgaHduZFBhcmVudCwgaW50IGNpZGwsIExQQ0lURU1JRExJU1QqIGFwaWRsLCBpbnQgeCwgaW50IHkpCnsKCUlDb250ZXh0TWVudSogcGNtOwoKCUhSRVNVTFQgaHIgPSAoKnNoZWxsX2ZvbGRlci0+bHBWdGJsLT5HZXRVSU9iamVjdE9mKShzaGVsbF9mb2xkZXIsIGh3bmRQYXJlbnQsIGNpZGwsIGFwaWRsLCAmSUlEX0lDb250ZXh0TWVudSwgTlVMTCwgKExQVk9JRCopJnBjbSk7Ci8qCUhSRVNVTFQgaHIgPSBDRGVmRm9sZGVyTWVudV9DcmVhdGUyKGRpcj9kaXItPl9waWRsOkRlc2t0b3BGb2xkZXIoKSwgaHduZFBhcmVudCwgMSwgJnBpZGwsIHNoZWxsX2ZvbGRlciwgTlVMTCwgMCwgTlVMTCwgJnBjbSk7ICovCgoJaWYgKFNVQ0NFRURFRChocikpIHsKCQlITUVOVSBobWVudSA9IENyZWF0ZVBvcHVwTWVudSgpOwoKCQlpZiAoaG1lbnUpIHsKCQkJaHIgPSAoKnBjbS0+bHBWdGJsLT5RdWVyeUNvbnRleHRNZW51KShwY20sIGhtZW51LCAwLCBGQ0lETV9TSFZJRVdGSVJTVCwgRkNJRE1fU0hWSUVXTEFTVCwgQ01GX05PUk1BTCk7CgoJCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQkJVUlOVCBpZENtZCA9IFRyYWNrUG9wdXBNZW51KGhtZW51LCBUUE1fTEVGVEFMSUdOfFRQTV9SRVRVUk5DTUR8VFBNX1JJR0hUQlVUVE9OLCB4LCB5LCAwLCBod25kUGFyZW50LCBOVUxMKTsKCgkJCQlpZiAoaWRDbWQpIHsKCQkJCSAgQ01JTlZPS0VDT01NQU5ESU5GTyBjbWk7CgoJCQkJICBjbWkuY2JTaXplID0gc2l6ZW9mKENNSU5WT0tFQ09NTUFORElORk8pOwoJCQkJICBjbWkuZk1hc2sgPSAwOwoJCQkJICBjbWkuaHduZCA9IGh3bmRQYXJlbnQ7CgkJCQkgIGNtaS5scFZlcmIgPSAoTFBDU1RSKShJTlRfUFRSKShpZENtZCAtIEZDSURNX1NIVklFV0ZJUlNUKTsKCQkJCSAgY21pLmxwUGFyYW1ldGVycyA9IE5VTEw7CgkJCQkgIGNtaS5scERpcmVjdG9yeSA9IE5VTEw7CgkJCQkgIGNtaS5uU2hvdyA9IFNXX1NIT1dOT1JNQUw7CgkJCQkgIGNtaS5kd0hvdEtleSA9IDA7CgkJCQkgIGNtaS5oSWNvbiA9IDA7CgoJCQkJICBociA9ICgqcGNtLT5scFZ0YmwtPkludm9rZUNvbW1hbmQpKHBjbSwgJmNtaSk7CgkJCQl9CgkJCX0KCQl9CgoJCSgqcGNtLT5scFZ0YmwtPlJlbGVhc2UpKHBjbSk7Cgl9CgoJcmV0dXJuIGhyOwp9CgoKTFJFU1VMVCBDQUxMQkFDSyBDaGlsZFduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCXN0YXRpYyBpbnQgbGFzdF9zcGxpdDsKCglDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nKGh3bmQsIEdXTF9VU0VSREFUQSk7CglBU1NFUlQoY2hpbGQpOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9EUkFXSVRFTTogewoJCQlMUERSQVdJVEVNU1RSVUNUIGRpcyA9IChMUERSQVdJVEVNU1RSVUNUKWxwYXJhbTsKCQkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgZGlzLT5pdGVtRGF0YTsKCgkJCWlmIChkaXMtPkN0bElEID09IElEV19UUkVFX0xFRlQpCgkJCQlkcmF3X2l0ZW0oJmNoaWxkLT5sZWZ0LCBkaXMsIGVudHJ5LCAtMSk7CgkJCWVsc2UKCQkJCWRyYXdfaXRlbSgmY2hpbGQtPnJpZ2h0LCBkaXMsIGVudHJ5LCAtMSk7CgoJCQlyZXR1cm4gVFJVRTt9CgoJCWNhc2UgV01fQ1JFQVRFOgoJCQlJbml0Q2hpbGRXaW5kb3coY2hpbGQpOwoJCQlicmVhazsKCgkJY2FzZSBXTV9OQ0RFU1RST1k6CgkJCWZyZWVfY2hpbGRfd2luZG93KGNoaWxkKTsKCQkJU2V0V2luZG93TG9uZyhod25kLCBHV0xfVVNFUkRBVEEsIDApOwoJCQlicmVhazsKCgkJY2FzZSBXTV9QQUlOVDogewoJCQlQQUlOVFNUUlVDVCBwczsKCQkJSEJSVVNIIGxhc3RCcnVzaDsKCQkJUkVDVCBydDsKCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoJCQlCZWdpblBhaW50KGh3bmQsICZwcyk7CgkJCXJ0LmxlZnQgPSBjaGlsZC0+c3BsaXRfcG9zLVNQTElUX1dJRFRILzI7CgkJCXJ0LnJpZ2h0ID0gY2hpbGQtPnNwbGl0X3BvcytTUExJVF9XSURUSC8yKzE7CgkJCWxhc3RCcnVzaCA9IFNlbGVjdEJydXNoKHBzLmhkYywgKEhCUlVTSClHZXRTdG9ja09iamVjdChDT0xPUl9TUExJVEJBUikpOwoJCQlSZWN0YW5nbGUocHMuaGRjLCBydC5sZWZ0LCBydC50b3AtMSwgcnQucmlnaHQsIHJ0LmJvdHRvbSsxKTsKCQkJU2VsZWN0T2JqZWN0KHBzLmhkYywgbGFzdEJydXNoKTsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCXJ0LnRvcCA9IHJ0LmJvdHRvbSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lIU0NST0xMKTsKCQkJRmlsbFJlY3QocHMuaGRjLCAmcnQsIEdldFN0b2NrT2JqZWN0KEJMQUNLX0JSVVNIKSk7CiNlbmRpZgoJCQlFbmRQYWludChod25kLCAmcHMpOwoJCQlicmVhazt9CgoJCWNhc2UgV01fU0VUQ1VSU09SOgoJCQlpZiAoTE9XT1JEKGxwYXJhbSkgPT0gSFRDTElFTlQpIHsKCQkJCVBPSU5UIHB0OwoJCQkJR2V0Q3Vyc29yUG9zKCZwdCk7CgkJCQlTY3JlZW5Ub0NsaWVudChod25kLCAmcHQpOwoKCQkJCWlmIChwdC54Pj1jaGlsZC0+c3BsaXRfcG9zLVNQTElUX1dJRFRILzIgJiYgcHQueDxjaGlsZC0+c3BsaXRfcG9zK1NQTElUX1dJRFRILzIrMSkgewoJCQkJCVNldEN1cnNvcihMb2FkQ3Vyc29yKDAsIElEQ19TSVpFV0UpKTsKCQkJCQlyZXR1cm4gVFJVRTsKCQkJCX0KCQkJfQoJCQlnb3RvIGRlZjsKCgkJY2FzZSBXTV9MQlVUVE9ORE9XTjogewoJCQlSRUNUIHJ0OwoJCQlpbnQgeCA9IEdFVF9YX0xQQVJBTShscGFyYW0pOwoKCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoKCQkJaWYgKHg+PWNoaWxkLT5zcGxpdF9wb3MtU1BMSVRfV0lEVEgvMiAmJiB4PGNoaWxkLT5zcGxpdF9wb3MrU1BMSVRfV0lEVEgvMisxKSB7CgkJCQlsYXN0X3NwbGl0ID0gY2hpbGQtPnNwbGl0X3BvczsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQlkcmF3X3NwbGl0YmFyKGh3bmQsIGxhc3Rfc3BsaXQpOwojZW5kaWYKCQkJCVNldENhcHR1cmUoaHduZCk7CgkJCX0KCgkJCWJyZWFrO30KCgkJY2FzZSBXTV9MQlVUVE9OVVA6CgkJCWlmIChHZXRDYXB0dXJlKCkgPT0gaHduZCkgewojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJCVJFQ1QgcnQ7CgkJCQlpbnQgeCA9IExPV09SRChscGFyYW0pOwoJCQkJZHJhd19zcGxpdGJhcihod25kLCBsYXN0X3NwbGl0KTsKCQkJCWxhc3Rfc3BsaXQgPSAtMTsKCQkJCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCQkJCWNoaWxkLT5zcGxpdF9wb3MgPSB4OwoJCQkJcmVzaXplX3RyZWUoY2hpbGQsIHJ0LnJpZ2h0LCBydC5ib3R0b20pOwojZW5kaWYKCQkJCVJlbGVhc2VDYXB0dXJlKCk7CgkJCX0KCQkJYnJlYWs7CgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQljYXNlIFdNX0NBUFRVUkVDSEFOR0VEOgoJCQlpZiAoR2V0Q2FwdHVyZSgpPT1od25kICYmIGxhc3Rfc3BsaXQ+PTApCgkJCQlkcmF3X3NwbGl0YmFyKGh3bmQsIGxhc3Rfc3BsaXQpOwoJCQlicmVhazsKI2VuZGlmCgoJCWNhc2UgV01fS0VZRE9XTjoKCQkJaWYgKHdwYXJhbSA9PSBWS19FU0NBUEUpCgkJCQlpZiAoR2V0Q2FwdHVyZSgpID09IGh3bmQpIHsKCQkJCQlSRUNUIHJ0OwojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJCQlkcmF3X3NwbGl0YmFyKGh3bmQsIGxhc3Rfc3BsaXQpOwojZWxzZQoJCQkJCWNoaWxkLT5zcGxpdF9wb3MgPSBsYXN0X3NwbGl0OwojZW5kaWYKCQkJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgkJCQkJcmVzaXplX3RyZWUoY2hpbGQsIHJ0LnJpZ2h0LCBydC5ib3R0b20pOwoJCQkJCWxhc3Rfc3BsaXQgPSAtMTsKCQkJCQlSZWxlYXNlQ2FwdHVyZSgpOwoJCQkJCVNldEN1cnNvcihMb2FkQ3Vyc29yKDAsIElEQ19BUlJPVykpOwoJCQkJfQoJCQlicmVhazsKCgkJY2FzZSBXTV9NT1VTRU1PVkU6CgkJCWlmIChHZXRDYXB0dXJlKCkgPT0gaHduZCkgewoJCQkJUkVDVCBydDsKCQkJCWludCB4ID0gTE9XT1JEKGxwYXJhbSk7CgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJCUhEQyBoZGMgPSBHZXREQyhod25kKTsKCQkJCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCgkJCQlydC5sZWZ0ID0gbGFzdF9zcGxpdC1TUExJVF9XSURUSC8yOwoJCQkJcnQucmlnaHQgPSBsYXN0X3NwbGl0K1NQTElUX1dJRFRILzIrMTsKCQkJCUludmVydFJlY3QoaGRjLCAmcnQpOwoKCQkJCWxhc3Rfc3BsaXQgPSB4OwoJCQkJcnQubGVmdCA9IHgtU1BMSVRfV0lEVEgvMjsKCQkJCXJ0LnJpZ2h0ID0geCtTUExJVF9XSURUSC8yKzE7CgkJCQlJbnZlcnRSZWN0KGhkYywgJnJ0KTsKCgkJCQlSZWxlYXNlREMoaHduZCwgaGRjKTsKI2Vsc2UKCQkJCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCgkJCQlpZiAoeD49MCAmJiB4PHJ0LnJpZ2h0KSB7CgkJCQkJY2hpbGQtPnNwbGl0X3BvcyA9IHg7CgkJCQkJcmVzaXplX3RyZWUoY2hpbGQsIHJ0LnJpZ2h0LCBydC5ib3R0b20pOwoJCQkJCXJ0LmxlZnQgPSB4LVNQTElUX1dJRFRILzI7CgkJCQkJcnQucmlnaHQgPSB4K1NQTElUX1dJRFRILzIrMTsKCQkJCQlJbnZhbGlkYXRlUmVjdChod25kLCAmcnQsIEZBTFNFKTsKCQkJCQlVcGRhdGVXaW5kb3coY2hpbGQtPmxlZnQuaHduZCk7CgkJCQkJVXBkYXRlV2luZG93KGh3bmQpOwoJCQkJCVVwZGF0ZVdpbmRvdyhjaGlsZC0+cmlnaHQuaHduZCk7CgkJCQl9CiNlbmRpZgoJCQl9CgkJCWJyZWFrOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fR0VUTUlOTUFYSU5GTzoKCQkJRGVmTURJQ2hpbGRQcm9jKGh3bmQsIG5tc2csIHdwYXJhbSwgbHBhcmFtKTsKCgkJCXtMUE1JTk1BWElORk8gbHBtbWkgPSAoTFBNSU5NQVhJTkZPKWxwYXJhbTsKCgkJCWxwbW1pLT5wdE1heFRyYWNrU2l6ZS54IDw8PSAxOy8qMipHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKSAvIFNNX0NYVklSVFVBTFNDUkVFTiAqLwoJCQlscG1taS0+cHRNYXhUcmFja1NpemUueSA8PD0gMTsvKjIqR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTikgLyBTTV9DWVZJUlRVQUxTQ1JFRU4gKi8KCQkJYnJlYWs7fQojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgkJY2FzZSBXTV9TRVRGT0NVUzoKCQkJU2V0Q3VycmVudERpcmVjdG9yeShjaGlsZC0+cGF0aCk7CgkJCVNldEZvY3VzKGNoaWxkLT5mb2N1c19wYW5lPyBjaGlsZC0+cmlnaHQuaHduZDogY2hpbGQtPmxlZnQuaHduZCk7CgkJCWJyZWFrOwoKCQljYXNlIFdNX0RJU1BBVENIX0NPTU1BTkQ6IHsKCQkJUGFuZSogcGFuZSA9IEdldEZvY3VzKCk9PWNoaWxkLT5sZWZ0Lmh3bmQ/ICZjaGlsZC0+bGVmdDogJmNoaWxkLT5yaWdodDsKCgkJCXN3aXRjaChMT1dPUkQod3BhcmFtKSkgewoJCQkJY2FzZSBJRF9XSU5ET1dfTkVXOiB7CgkJCQkJQ2hpbGRXbmQqIG5ld19jaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhjaGlsZC0+cGF0aCwgTlVMTCwgaHduZCk7CgoJCQkJCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhuZXdfY2hpbGQpKQoJCQkJCQlmcmVlKG5ld19jaGlsZCk7CgoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX1JFRlJFU0g6CgkJCQkJc2Nhbl9lbnRyeShjaGlsZCwgcGFuZS0+Y3VyLCBod25kKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX0FDVElWQVRFOgoJCQkJCWFjdGl2YXRlX2VudHJ5KGNoaWxkLCBwYW5lLCBod25kKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX0ZJTEVfTU9WRTogewoJCQkJCVRDSEFSIG5ld19uYW1lW0JVRkZFUl9MRU5dLCBvbGRfbmFtZVtCVUZGRVJfTEVOXTsKCQkJCQlpbnQgbGVuOwoKCQkJCQlpbnQgcmV0ID0gRGlhbG9nQm94UGFyYW0oR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRERfU0VMRUNUX0RFU1RJTkFUSU9OKSwgaHduZCwgRGVzdGluYXRpb25EbGdQcm9jLCAoTFBBUkFNKW5ld19uYW1lKTsKCQkJCQlpZiAocmV0ICE9IElET0spCgkJCQkJCWJyZWFrOwoKCQkJCQlpZiAobmV3X25hbWVbMF0hPScvJyAmJiBuZXdfbmFtZVsxXSE9JzonKSB7CgkJCQkJCWdldF9wYXRoKHBhbmUtPmN1ci0+dXAsIG9sZF9uYW1lKTsKCQkJCQkJbGVuID0gbHN0cmxlbihvbGRfbmFtZSk7CgoJCQkJCQlpZiAob2xkX25hbWVbbGVuLTFdIT0nXFwnICYmIG9sZF9uYW1lW2xlbi0xXSE9Jy8nKSB7CgkJCQkJCQlvbGRfbmFtZVtsZW4rK10gPSAnLyc7CgkJCQkJCQlvbGRfbmFtZVtsZW5dID0gJ1xuJzsKCQkJCQkJfQoKCQkJCQkJbHN0cmNweSgmb2xkX25hbWVbbGVuXSwgbmV3X25hbWUpOwoJCQkJCQlsc3RyY3B5KG5ld19uYW1lLCBvbGRfbmFtZSk7CgkJCQkJfQoKCQkJCQlnZXRfcGF0aChwYW5lLT5jdXIsIG9sZF9uYW1lKTsKCgkJCQkJaWYgKE1vdmVGaWxlRXgob2xkX25hbWUsIG5ld19uYW1lLCBNT1ZFRklMRV9DT1BZX0FMTE9XRUQpKSB7CgkJCQkJCWlmIChwYW5lLT50cmVlUGFuZSkgewoJCQkJCQkJcGFuZS0+cm9vdC0+c2Nhbm5lZCA9IEZBTFNFOwoJCQkJCQkJcGFuZS0+Y3VyID0gcGFuZS0+cm9vdDsKCQkJCQkJCWFjdGl2YXRlX2VudHJ5KGNoaWxkLCBwYW5lLCBod25kKTsKCQkJCQkJfQoJCQkJCQllbHNlCgkJCQkJCQlzY2FuX2VudHJ5KGNoaWxkLCBwYW5lLT5yb290LCBod25kKTsKCQkJCQl9CgkJCQkJZWxzZQoJCQkJCQlkaXNwbGF5X2Vycm9yKGh3bmQsIEdldExhc3RFcnJvcigpKTsKCQkJCQlicmVhazt9CgoJCQkJZGVmYXVsdDoKCQkJCQlyZXR1cm4gcGFuZV9jb21tYW5kKHBhbmUsIExPV09SRCh3cGFyYW0pKTsKCQkJfQoKCQkJcmV0dXJuIFRSVUU7fQoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJUGFuZSogcGFuZSA9IEdldEZvY3VzKCk9PWNoaWxkLT5sZWZ0Lmh3bmQ/ICZjaGlsZC0+bGVmdDogJmNoaWxkLT5yaWdodDsKCgkJCXN3aXRjaChISVdPUkQod3BhcmFtKSkgewoJCQkJY2FzZSBMQk5fU0VMQ0hBTkdFOiB7CgkJCQkJaW50IGlkeCA9IExpc3RCb3hfR2V0Q3VyU2VsKHBhbmUtPmh3bmQpOwoJCQkJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIExpc3RCb3hfR2V0SXRlbURhdGEocGFuZS0+aHduZCwgaWR4KTsKCgkJCQkJaWYgKHBhbmUgPT0gJmNoaWxkLT5sZWZ0KQoJCQkJCQlzZXRfY3VyZGlyKGNoaWxkLCBlbnRyeSwgaHduZCk7CgkJCQkJZWxzZQoJCQkJCQlwYW5lLT5jdXIgPSBlbnRyeTsKCQkJCQlicmVhazt9CgoJCQkJY2FzZSBMQk5fREJMQ0xLOgoJCQkJCWFjdGl2YXRlX2VudHJ5KGNoaWxkLCBwYW5lLCBod25kKTsKCQkJCQlicmVhazsKCQkJfQoJCQlicmVhazt9CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJY2FzZSBXTV9OT1RJRlk6IHsKCQkJTk1IRFIqIHBubWggPSAoTk1IRFIqKSBscGFyYW07CgkJCXJldHVybiBwYW5lX25vdGlmeShwbm1oLT5pZEZyb209PUlEV19IRUFERVJfTEVGVD8gJmNoaWxkLT5sZWZ0OiAmY2hpbGQtPnJpZ2h0LCBwbm1oKTt9CiNlbmRpZgoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgkJY2FzZSBXTV9DT05URVhUTUVOVTogewoJCQlQYW5lKiBwYW5lOwoJCQlpbnQgaWR4OwoKCQkJIC8qIGZpcnN0IHNlbGVjdCB0aGUgY3VycmVudCBpdGVtIGluIHRoZSBsaXN0Ym94ICovCgkJCUhXTkQgaHBhbmVsID0gKEhXTkQpIHdwYXJhbTsKCQkJUE9JTlQgcHQ7CgkJCXB0LnggPSAoc2hvcnQpTE9XT1JEKGxwYXJhbSk7CgkJCXB0LnkgPSAoc2hvcnQpSElXT1JEKGxwYXJhbSk7CgkJCVNjcmVlblRvQ2xpZW50KGhwYW5lbCwgJnB0KTsKCQkJU2VuZE1lc3NhZ2UoaHBhbmVsLCBXTV9MQlVUVE9ORE9XTiwgMCwgTUFLRUxPTkcocHQueCwgcHQueSkpOwoJCQlTZW5kTWVzc2FnZShocGFuZWwsIFdNX0xCVVRUT05VUCwgMCwgTUFLRUxPTkcocHQueCwgcHQueSkpOwoKCQkJIC8qIG5vdyBjcmVhdGUgdGhlIHBvcHVwIG1lbnUgdXNpbmcgc2hlbGwgbmFtZXNwYWNlIGFuZCBJQ29udGV4dE1lbnUgKi8KCQkJcGFuZSA9IEdldEZvY3VzKCk9PWNoaWxkLT5sZWZ0Lmh3bmQ/ICZjaGlsZC0+bGVmdDogJmNoaWxkLT5yaWdodDsKCQkJaWR4ID0gTGlzdEJveF9HZXRDdXJTZWwocGFuZS0+aHduZCk7CgoJCQlpZiAoaWR4ICE9IC0xKSB7CgkJCQlIUkVTVUxUIGhyOwoJCQkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgTGlzdEJveF9HZXRJdGVtRGF0YShwYW5lLT5od25kLCBpZHgpOwoKCQkJCUxQSVRFTUlETElTVCBwaWRsX2FicyA9IGdldF90b19hYnNvbHV0ZV9waWRsKGVudHJ5LCBod25kKTsKCgkJCQlpZiAocGlkbF9hYnMpIHsKCQkJCQlJU2hlbGxGb2xkZXIqIHBhcmVudEZvbGRlcjsKCQkJCQlMUENJVEVNSURMSVNUIHBpZGxMYXN0OwoKCQkJCQkgLyogZ2V0IGFuZCB1c2UgdGhlIHBhcmVudCBmb2xkZXIgdG8gZGlzcGxheSBjb3JyZWN0IGNvbnRleHQgbWVudSBpbiBhbGwgY2FzZXMgKi8KCQkJCQlpZiAoU1VDQ0VFREVEKFNIQmluZFRvUGFyZW50KHBpZGxfYWJzLCAmSUlEX0lTaGVsbEZvbGRlciwgKExQVk9JRCopJnBhcmVudEZvbGRlciwgJnBpZGxMYXN0KSkpIHsKCQkJCQkJaHIgPSBTaGVsbEZvbGRlckNvbnRleHRNZW51KHBhcmVudEZvbGRlciwgaHduZCwgMSwgJnBpZGxMYXN0LCBwdC54LCBwdC55KTsKCgkJCQkJCSgqcGFyZW50Rm9sZGVyLT5scFZ0YmwtPlJlbGVhc2UpKHBhcmVudEZvbGRlcik7CgkJCQkJfQoKCQkJCQkoKkdsb2JhbHMuaU1hbGxvYy0+bHBWdGJsLT5GcmVlKShHbG9iYWxzLmlNYWxsb2MsIHBpZGxfYWJzKTsKCQkJCX0KCQkJfQoJCQlicmVhazt9CiNlbmRpZgoKCQljYXNlIFdNX1NJWkU6CgkJCWlmICh3cGFyYW0gIT0gU0laRV9NSU5JTUlaRUQpCgkJCQlyZXNpemVfdHJlZShjaGlsZCwgTE9XT1JEKGxwYXJhbSksIEhJV09SRChscGFyYW0pKTsKCQkJLyogZmFsbCB0aHJvdWdoICovCgoJCWRlZmF1bHQ6IGRlZjoKCQkJcmV0dXJuIERlZk1ESUNoaWxkUHJvYyhod25kLCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7Cgl9CgoJcmV0dXJuIDA7Cn0KCgpMUkVTVUxUIENBTExCQUNLIFRyZWVXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nKEdldFBhcmVudChod25kKSwgR1dMX1VTRVJEQVRBKTsKCVBhbmUqIHBhbmUgPSAoUGFuZSopIEdldFdpbmRvd0xvbmcoaHduZCwgR1dMX1VTRVJEQVRBKTsKCUFTU0VSVChjaGlsZCk7CgoJc3dpdGNoKG5tc2cpIHsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fSFNDUk9MTDoKCQkJc2V0X2hlYWRlcihwYW5lKTsKCQkJYnJlYWs7CiNlbmRpZgoKCQljYXNlIFdNX1NFVEZPQ1VTOgoJCQljaGlsZC0+Zm9jdXNfcGFuZSA9IHBhbmU9PSZjaGlsZC0+cmlnaHQ/IDE6IDA7CgkJCUxpc3RCb3hfU2V0U2VsKGh3bmQsIFRSVUUsIDEpOwoJCQkvKlRPRE86IGNoZWNrIG1lbnUgaXRlbXMgKi8KCQkJYnJlYWs7CgoJCWNhc2UgV01fS0VZRE9XTjoKCQkJaWYgKHdwYXJhbSA9PSBWS19UQUIpIHsKCQkJCS8qVE9ETzogU2V0Rm9jdXMoR2xvYmFscy5oZHJpdmViYXIpICovCgkJCQlTZXRGb2N1cyhjaGlsZC0+Zm9jdXNfcGFuZT8gY2hpbGQtPmxlZnQuaHduZDogY2hpbGQtPnJpZ2h0Lmh3bmQpOwoJCQl9Cgl9CgoJcmV0dXJuIENhbGxXaW5kb3dQcm9jKGdfb3JnVHJlZVduZFByb2MsIGh3bmQsIG5tc2csIHdwYXJhbSwgbHBhcmFtKTsKfQoKCnN0YXRpYyB2b2lkIEluaXRJbnN0YW5jZShISU5TVEFOQ0UgaGluc3RhbmNlKQp7Cgljb25zdCBzdGF0aWMgVENIQVIgc0ZvbnRbXSA9IHsnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnICcsJ1MnLCdhJywnbicsJ3MnLCcgJywnUycsJ2UnLCdyJywnaScsJ2YnLCdcMCd9OwoKCVdORENMQVNTRVggd2NGcmFtZTsKCVdORENMQVNTIHdjQ2hpbGQ7CglBVE9NIGhDaGlsZENsYXNzOwoJaW50IGNvbDsKCglJTklUQ09NTU9OQ09OVFJPTFNFWCBpY2MgPSB7CgkJc2l6ZW9mKElOSVRDT01NT05DT05UUk9MU0VYKSwKCQlJQ0NfQkFSX0NMQVNTRVMKCX07CgoJSERDIGhkYyA9IEdldERDKDApOwoKCXNldGxvY2FsZShMQ19DT0xMQVRFLCAiIik7CS8qIHNldCBjb2xsYXRpbmcgcnVsZXMgdG8gbG9jYWwgc2V0dGluZ3MgZm9yIGNvbXBhcmVOYW1lICovCgoJSW5pdENvbW1vbkNvbnRyb2xzRXgoJmljYyk7CgoKCS8qIHJlZ2lzdGVyIGZyYW1lIHdpbmRvdyBjbGFzcyAqLwoKCXdjRnJhbWUuY2JTaXplICAgICAgICA9IHNpemVvZihXTkRDTEFTU0VYKTsKCXdjRnJhbWUuc3R5bGUgICAgICAgICA9IDA7Cgl3Y0ZyYW1lLmxwZm5XbmRQcm9jICAgPSBGcmFtZVduZFByb2M7Cgl3Y0ZyYW1lLmNiQ2xzRXh0cmEgICAgPSAwOwoJd2NGcmFtZS5jYlduZEV4dHJhICAgID0gMDsKCXdjRnJhbWUuaEluc3RhbmNlICAgICA9IGhpbnN0YW5jZTsKCXdjRnJhbWUuaEljb24gICAgICAgICA9IExvYWRJY29uKGhpbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElESV9XSU5FRklMRSkpOwoJd2NGcmFtZS5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvcigwLCBJRENfQVJST1cpOwoJd2NGcmFtZS5oYnJCYWNrZ3JvdW5kID0gMDsKCXdjRnJhbWUubHBzek1lbnVOYW1lICA9IDA7Cgl3Y0ZyYW1lLmxwc3pDbGFzc05hbWUgPSBzV0lORUZJTEVGUkFNRTsKCXdjRnJhbWUuaEljb25TbSAgICAgICA9IChISUNPTilMb2FkSW1hZ2UoaGluc3RhbmNlLAoJCQkJCQkJCQkJCSBNQUtFSU5UUkVTT1VSQ0UoSURJX1dJTkVGSUxFKSwKCQkJCQkJCQkJCQkgSU1BR0VfSUNPTiwKCQkJCQkJCQkJCQkgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNNSUNPTiksCgkJCQkJCQkJCQkJIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUlDT04pLAoJCQkJCQkJCQkJCSBMUl9TSEFSRUQpOwoKCUdsb2JhbHMuaGZyYW1lQ2xhc3MgPSBSZWdpc3RlckNsYXNzRXgoJndjRnJhbWUpOwoKCgkvKiByZWdpc3RlciB0cmVlIHdpbmRvd3MgY2xhc3MgKi8KCgl3Y0NoaWxkLnN0eWxlICAgICAgICAgPSBDU19DTEFTU0RDfENTX0RCTENMS1N8Q1NfVlJFRFJBVzsKCXdjQ2hpbGQubHBmblduZFByb2MgICA9IENoaWxkV25kUHJvYzsKCXdjQ2hpbGQuY2JDbHNFeHRyYSAgICA9IDA7Cgl3Y0NoaWxkLmNiV25kRXh0cmEgICAgPSAwOwoJd2NDaGlsZC5oSW5zdGFuY2UgICAgID0gaGluc3RhbmNlOwoJd2NDaGlsZC5oSWNvbiAgICAgICAgID0gMDsKCXdjQ2hpbGQuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3IoMCwgSURDX0FSUk9XKTsKCXdjQ2hpbGQuaGJyQmFja2dyb3VuZCA9IDA7Cgl3Y0NoaWxkLmxwc3pNZW51TmFtZSAgPSAwOwoJd2NDaGlsZC5scHN6Q2xhc3NOYW1lID0gc1dJTkVGSUxFVFJFRTsKCgloQ2hpbGRDbGFzcyA9IFJlZ2lzdGVyQ2xhc3MoJndjQ2hpbGQpOwoKCglHbG9iYWxzLmhhY2NlbCA9IExvYWRBY2NlbGVyYXRvcnMoaGluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSURBX1dJTkVGSUxFKSk7CgoJR2xvYmFscy5oZm9udCA9IENyZWF0ZUZvbnQoLU11bERpdig4LEdldERldmljZUNhcHMoaGRjLExPR1BJWEVMU1kpLDcyKSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgc0ZvbnQpOwoKCVJlbGVhc2VEQygwLCBoZGMpOwoKCUdsb2JhbHMuaEluc3RhbmNlID0gaGluc3RhbmNlOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglDb0luaXRpYWxpemUoTlVMTCk7CglDb0dldE1hbGxvYyhNRU1DVFhfVEFTSywgJkdsb2JhbHMuaU1hbGxvYyk7CglTSEdldERlc2t0b3BGb2xkZXIoJkdsb2JhbHMuaURlc2t0b3ApOwojaWZkZWYgX19XSU5FX18KCUdsb2JhbHMuY2ZTdHJGTmFtZSA9IFJlZ2lzdGVyQ2xpcGJvYXJkRm9ybWF0QShDRlNUUl9GSUxFTkFNRSk7CiNlbHNlCglHbG9iYWxzLmNmU3RyRk5hbWUgPSBSZWdpc3RlckNsaXBib2FyZEZvcm1hdChDRlNUUl9GSUxFTkFNRSk7CiNlbmRpZgojZW5kaWYKCgkvKiBsb2FkIGNvbHVtbiBzdHJpbmdzICovCgljb2wgPSAwOwoKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9OQU1FKTsKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9TSVpFKTsKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9DREFURSk7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9BREFURSk7Cglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfTURBVEUpOwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX0lEWCk7Cglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfTElOS1MpOwojZW5kaWYKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9BVFRSKTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX1NFQyk7CiNlbmRpZgp9CgoKdm9pZCBzaG93X2ZyYW1lKEhXTkQgaHduZFBhcmVudCwgaW50IGNtZHNob3cpCnsKCWNvbnN0IHN0YXRpYyBUQ0hBUiBzTURJQ0xJRU5UW10gPSB7J00nLCdEJywnSScsJ0MnLCdMJywnSScsJ0UnLCdOJywnVCcsJ1wwJ307CgoJVENIQVIgcGF0aFtNQVhfUEFUSF0sIGIxW0JVRkZFUl9MRU5dOwoJQ2hpbGRXbmQqIGNoaWxkOwoJSE1FTlUgaE1lbnVGcmFtZSwgaE1lbnVXaW5kb3c7CgoJQ0xJRU5UQ1JFQVRFU1RSVUNUIGNjczsKCglpZiAoR2xvYmFscy5oTWFpblduZCkKCQlyZXR1cm47CgoJR2xvYmFscy5od25kUGFyZW50ID0gaHduZFBhcmVudDsKCgloTWVudUZyYW1lID0gTG9hZE1lbnUoR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRE1fV0lORUZJTEUpKTsKCWhNZW51V2luZG93ID0gR2V0U3ViTWVudShoTWVudUZyYW1lLCBHZXRNZW51SXRlbUNvdW50KGhNZW51RnJhbWUpLTIpOwoKCUdsb2JhbHMuaE1lbnVGcmFtZSA9IGhNZW51RnJhbWU7CglHbG9iYWxzLmhNZW51VmlldyA9IEdldFN1Yk1lbnUoaE1lbnVGcmFtZSwgMyk7CglHbG9iYWxzLmhNZW51T3B0aW9ucyA9IEdldFN1Yk1lbnUoaE1lbnVGcmFtZSwgNCk7CgoJY2NzLmhXaW5kb3dNZW51ICA9IGhNZW51V2luZG93OwoJY2NzLmlkRmlyc3RDaGlsZCA9IElEV19GSVJTVF9DSElMRDsKCgoJLyogY3JlYXRlIG1haW4gd2luZG93ICovCglHbG9iYWxzLmhNYWluV25kID0gQ3JlYXRlV2luZG93RXgoMCwgKExQQ1RTVFIpKGludClHbG9iYWxzLmhmcmFtZUNsYXNzLCBSUyhiMSxJRFNfV0lORV9GSUxFKSwgV1NfT1ZFUkxBUFBFRFdJTkRPVywKCQkJCQlDV19VU0VERUZBVUxULCBDV19VU0VERUZBVUxULCBDV19VU0VERUZBVUxULCBDV19VU0VERUZBVUxULAoJCQkJCWh3bmRQYXJlbnQsIEdsb2JhbHMuaE1lbnVGcmFtZSwgR2xvYmFscy5oSW5zdGFuY2UsIDAvKmxwUGFyYW0qLyk7CgoKCUdsb2JhbHMuaG1kaWNsaWVudCA9IENyZWF0ZVdpbmRvd0V4KDAsIHNNRElDTElFTlQsIE5VTEwsCgkJCQkJV1NfQ0hJTER8V1NfQ0xJUENISUxEUkVOfFdTX1ZTQ1JPTEx8V1NfSFNDUk9MTHxXU19WSVNJQkxFfFdTX0JPUkRFUiwKCQkJCQkwLCAwLCAwLCAwLAoJCQkJCUdsb2JhbHMuaE1haW5XbmQsIDAsIEdsb2JhbHMuaEluc3RhbmNlLCAmY2NzKTsKCgoJewoJCVRCQlVUVE9OIGRyaXZlYmFyQnRuID0gezAsIDAsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19TRVAsIHswLCAwfSwgMCwgMH07CgkJaW50IGJ0biA9IDE7CgkJUFRTVFIgcDsKCgkJR2xvYmFscy5oZHJpdmViYXIgPSBDcmVhdGVUb29sYmFyRXgoR2xvYmFscy5oTWFpblduZCwgV1NfQ0hJTER8V1NfVklTSUJMRXxDQ1NfTk9NT1ZFWXxUQlNUWUxFX0xJU1QsCgkJCQkJSURXX0RSSVZFQkFSLCAyLCBHbG9iYWxzLmhJbnN0YW5jZSwgSURCX0RSSVZFQkFSLCAmZHJpdmViYXJCdG4sCgkJCQkJMSwgMTYsIDEzLCAxNiwgMTMsIHNpemVvZihUQkJVVFRPTikpOwoJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudU9wdGlvbnMsIElEX1ZJRVdfRFJJVkVfQkFSLCBNRl9CWUNPTU1BTkR8TUZfQ0hFQ0tFRCk7CgoJCUdldExvZ2ljYWxEcml2ZVN0cmluZ3MoQlVGRkVSX0xFTiwgR2xvYmFscy5kcml2ZXMpOwoKCQlkcml2ZWJhckJ0bi5mc1N0eWxlID0gQlROU19CVVRUT047CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCiNpZmRlZiBfX1dJTkVfXwoJCS8qIGluc2VydCB1bml4IGZpbGUgc3lzdGVtIGJ1dHRvbiAqLwoJCWIxWzBdID0gJy8nOwoJCWIxWzFdID0gJ1wwJzsKCQliMVsyXSA9ICdcMCc7CgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0FERFNUUklORywgMCwgKExQQVJBTSliMSk7CgoJCWRyaXZlYmFyQnRuLmlkQ29tbWFuZCA9IElEX0RSSVZFX1VOSVhfRlM7CgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0lOU0VSVEJVVFRPTiwgYnRuKyssIChMUEFSQU0pJmRyaXZlYmFyQnRuKTsKCQlkcml2ZWJhckJ0bi5pU3RyaW5nKys7CiNlbmRpZgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCQkvKiBpbnNlcnQgc2hlbGwgbmFtZXNwYWNlIGJ1dHRvbiAqLwoJCWxvYWRfc3RyaW5nKGIxLCBJRFNfU0hFTEwpOwoJCWIxW2xzdHJsZW4oYjEpKzFdID0gJ1wwJzsKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfQUREU1RSSU5HLCAwLCAoTFBBUkFNKWIxKTsKCgkJZHJpdmViYXJCdG4uaWRDb21tYW5kID0gSURfRFJJVkVfU0hFTExfTlM7CgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0lOU0VSVEJVVFRPTiwgYnRuKyssIChMUEFSQU0pJmRyaXZlYmFyQnRuKTsKCQlkcml2ZWJhckJ0bi5pU3RyaW5nKys7CiNlbmRpZgoKCQkvKiByZWdpc3RlciB3aW5kb3dzIGRyaXZlIHJvb3Qgc3RyaW5ncyAqLwoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9BRERTVFJJTkcsIDAsIChMUEFSQU0pR2xvYmFscy5kcml2ZXMpOwojZW5kaWYKCgkJZHJpdmViYXJCdG4uaWRDb21tYW5kID0gSURfRFJJVkVfRklSU1Q7CgoJCWZvcihwPUdsb2JhbHMuZHJpdmVzOyAqcDsgKSB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCSAgLyogaW5zZXJ0IGRyaXZlIGxldHRlciAqLwoJCQlUQ0hBUiBiWzNdID0ge3RvbG93ZXIoKnApfTsKCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0FERFNUUklORywgMCwgKExQQVJBTSliKTsKI2VuZGlmCgkJCXN3aXRjaChHZXREcml2ZVR5cGUocCkpIHsKCQkJCWNhc2UgRFJJVkVfUkVNT1ZBQkxFOglkcml2ZWJhckJ0bi5pQml0bWFwID0gMTsJYnJlYWs7CgkJCQljYXNlIERSSVZFX0NEUk9NOgkJZHJpdmViYXJCdG4uaUJpdG1hcCA9IDM7CWJyZWFrOwoJCQkJY2FzZSBEUklWRV9SRU1PVEU6CQlkcml2ZWJhckJ0bi5pQml0bWFwID0gNDsJYnJlYWs7CgkJCQljYXNlIERSSVZFX1JBTURJU0s6CQlkcml2ZWJhckJ0bi5pQml0bWFwID0gNTsJYnJlYWs7CgkJCQlkZWZhdWx0Oi8qRFJJVkVfRklYRUQqLwlkcml2ZWJhckJ0bi5pQml0bWFwID0gMjsKCQkJfQoKCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0lOU0VSVEJVVFRPTiwgYnRuKyssIChMUEFSQU0pJmRyaXZlYmFyQnRuKTsKCQkJZHJpdmViYXJCdG4uaWRDb21tYW5kKys7CgkJCWRyaXZlYmFyQnRuLmlTdHJpbmcrKzsKCgkJCXdoaWxlKCpwKyspOwoJCX0KCX0KCgl7CgkJVEJCVVRUT04gdG9vbGJhckJ0bnNbXSA9IHsKCQkJezAsIDAsIDAsIEJUTlNfU0VQLCB7MCwgMH0sIDAsIDB9LAoJCQl7MCwgSURfV0lORE9XX05FVywgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKCQkJezEsIElEX1dJTkRPV19DQVNDQURFLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9LAoJCQl7MiwgSURfV0lORE9XX1RJTEVfSE9SWiwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKCQkJezMsIElEX1dJTkRPV19USUxFX1ZFUlQsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH0sCi8qVE9ETwoJCQl7NCwgSURfLi4uICwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTn0sCgkJCXs1LCBJRF8uLi4gLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OfSwKKi8JCX07CgoJCUdsb2JhbHMuaHRvb2xiYXIgPSBDcmVhdGVUb29sYmFyRXgoR2xvYmFscy5oTWFpblduZCwgV1NfQ0hJTER8V1NfVklTSUJMRSwKCQkJSURXX1RPT0xCQVIsIDIsIEdsb2JhbHMuaEluc3RhbmNlLCBJREJfVE9PTEJBUiwgdG9vbGJhckJ0bnMsCgkJCXNpemVvZih0b29sYmFyQnRucykvc2l6ZW9mKFRCQlVUVE9OKSwgMTYsIDE1LCAxNiwgMTUsIHNpemVvZihUQkJVVFRPTikpOwoJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudU9wdGlvbnMsIElEX1ZJRVdfVE9PTF9CQVIsIE1GX0JZQ09NTUFORHxNRl9DSEVDS0VEKTsKCX0KCglHbG9iYWxzLmhzdGF0dXNiYXIgPSBDcmVhdGVTdGF0dXNXaW5kb3coV1NfQ0hJTER8V1NfVklTSUJMRSwgMCwgR2xvYmFscy5oTWFpblduZCwgSURXX1NUQVRVU0JBUik7CglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBJRF9WSUVXX1NUQVRVU0JBUiwgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoKLyogQ3JlYXRlU3RhdHVzV2luZG93IGRvZXMgbm90IGFjY2VwdCBXU19CT1JERVIKCUdsb2JhbHMuaHN0YXR1c2JhciA9IENyZWF0ZVdpbmRvd0V4KFdTX0VYX05PUEFSRU5UTk9USUZZLCBTVEFUVVNDTEFTU05BTUUsIDAsCgkJCQkJV1NfQ0hJTER8V1NfVklTSUJMRXxXU19DTElQU0lCTElOR1N8V1NfQk9SREVSfENDU19OT0RJVklERVIsIDAsMCwwLDAsCgkJCQkJR2xvYmFscy5oTWFpblduZCwgKEhNRU5VKUlEV19TVEFUVVNCQVIsIGhpbnN0YW5jZSwgMCk7Ki8KCgkvKlRPRE86IHJlYWQgcGF0aHMgYW5kIHdpbmRvdyBwbGFjZW1lbnRzIGZyb20gcmVnaXN0cnkgKi8KCUdldEN1cnJlbnREaXJlY3RvcnkoTUFYX1BBVEgsIHBhdGgpOwoKCVNob3dXaW5kb3coR2xvYmFscy5oTWFpblduZCwgY21kc2hvdyk7CgojaWYgZGVmaW5lZChfU0hFTExfRk9MREVSUykgJiYgIWRlZmluZWQoX19XSU5FX18pCgkgLyogU2hlbGwgTmFtZXNwYWNlIGFzIGRlZmF1bHQ6ICovCgljaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhwYXRoLCBnZXRfcGF0aF9waWRsKHBhdGgsR2xvYmFscy5oTWFpblduZCksIEdsb2JhbHMuaE1haW5XbmQpOwojZWxzZQoJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgTlVMTCwgR2xvYmFscy5oTWFpblduZCk7CiNlbmRpZgoKCWNoaWxkLT5wb3Muc2hvd0NtZCA9IFNXX1NIT1dNQVhJTUlaRUQ7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ubGVmdCA9IDA7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24udG9wID0gMDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5yaWdodCA9IDMyMDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5ib3R0b20gPSAyODA7CgoJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQlmcmVlKGNoaWxkKTsKCglTZXRXaW5kb3dQbGFjZW1lbnQoY2hpbGQtPmh3bmQsICZjaGlsZC0+cG9zKTsKCglHbG9iYWxzLmhpbWwgPSBJbWFnZUxpc3RfTG9hZEJpdG1hcChHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElEQl9JTUFHRVMpLCAxNiwgMCwgUkdCKDAsMjU1LDApKTsKCglHbG9iYWxzLnByZXNjYW5fbm9kZSA9IEZBTFNFOwoKCVVwZGF0ZVdpbmRvdyhHbG9iYWxzLmhNYWluV25kKTsKfQoKdm9pZCBFeGl0SW5zdGFuY2UoKQp7CiNpZmRlZiBfU0hFTExfRk9MREVSUwoJKCpHbG9iYWxzLmlEZXNrdG9wLT5scFZ0YmwtPlJlbGVhc2UpKEdsb2JhbHMuaURlc2t0b3ApOwoJKCpHbG9iYWxzLmlNYWxsb2MtPmxwVnRibC0+UmVsZWFzZSkoR2xvYmFscy5pTWFsbG9jKTsKCUNvVW5pbml0aWFsaXplKCk7CiNlbmRpZgoKCUltYWdlTGlzdF9EZXN0cm95KEdsb2JhbHMuaGltbCk7Cn0KCgovKiBzZWFyY2ggZm9yIGFscmVhZHkgcnVubmluZyB3aW5bZV1maWxlcyAqLwoKc3RhdGljIGludCBnX2ZvdW5kUHJldkluc3RhbmNlID0gMDsKCnN0YXRpYyBCT09MIENBTExCQUNLIEVudW1XbmRQcm9jKEhXTkQgaHduZCwgTFBBUkFNIGxwYXJhbSkKewoJVENIQVIgY2xzWzEyOF07CgoJR2V0Q2xhc3NOYW1lKGh3bmQsIGNscywgMTI4KTsKCglpZiAoIWxzdHJjbXAoY2xzLCAoTFBDVFNUUilscGFyYW0pKSB7CgkJZ19mb3VuZFByZXZJbnN0YW5jZSsrOwoJCXJldHVybiBGQUxTRTsKCX0KCglyZXR1cm4gVFJVRTsKfQoKLyogc2VhcmNoIGZvciB3aW5kb3cgb2YgZ2l2ZW4gY2xhc3MgbmFtZSB0byBhbGxvdyBvbmx5IG9uZSBydW5uaW5nIGluc3RhbmNlICovCmludCBmaW5kX3dpbmRvd19jbGFzcyhMUENUU1RSIGNsYXNzbmFtZSkKewoJRW51bVdpbmRvd3MoRW51bVduZFByb2MsIChMUEFSQU0pY2xhc3NuYW1lKTsKCglpZiAoZ19mb3VuZFByZXZJbnN0YW5jZSkKCQlyZXR1cm4gMTsKCglyZXR1cm4gMDsKfQoKCmludCB3aW5lZmlsZV9tYWluKEhJTlNUQU5DRSBoaW5zdGFuY2UsIEhXTkQgaHduZFBhcmVudCwgaW50IGNtZHNob3cpCnsKCU1TRyBtc2c7CgoJSW5pdEluc3RhbmNlKGhpbnN0YW5jZSk7CgoJaWYgKGNtZHNob3cgPT0gU1dfU0hPV05PUk1BTCkKCSAgICAgICAgLypUT0RPOiByZWFkIHdpbmRvdyBwbGFjZW1lbnQgZnJvbSByZWdpc3RyeSAqLwoJCWNtZHNob3cgPSBTV19NQVhJTUlaRTsKCglzaG93X2ZyYW1lKGh3bmRQYXJlbnQsIGNtZHNob3cpOwoKCXdoaWxlKEdldE1lc3NhZ2UoJm1zZywgMCwgMCwgMCkpIHsKCQlpZiAoR2xvYmFscy5obWRpY2xpZW50ICYmIFRyYW5zbGF0ZU1ESVN5c0FjY2VsKEdsb2JhbHMuaG1kaWNsaWVudCwgJm1zZykpCgkJCWNvbnRpbnVlOwoKCQlpZiAoR2xvYmFscy5oTWFpblduZCAmJiBUcmFuc2xhdGVBY2NlbGVyYXRvcihHbG9iYWxzLmhNYWluV25kLCBHbG9iYWxzLmhhY2NlbCwgJm1zZykpCgkJCWNvbnRpbnVlOwoKCQlUcmFuc2xhdGVNZXNzYWdlKCZtc2cpOwoJCURpc3BhdGNoTWVzc2FnZSgmbXNnKTsKCX0KCglFeGl0SW5zdGFuY2UoKTsKCglyZXR1cm4gbXNnLndQYXJhbTsKfQoKCmludCBBUElFTlRSWSBXaW5NYWluKEhJTlNUQU5DRSBoaW5zdGFuY2UsCgkJCQkJIEhJTlNUQU5DRSBwcmV2aW5zdGFuY2UsCgkJCQkJIExQU1RSCSAgIGNtZGxpbmUsCgkJCQkJIGludAkgICBjbWRzaG93KQp7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJaWYgKGZpbmRfd2luZG93X2NsYXNzKHNXSU5FRklMRUZSQU1FKSkKCQlyZXR1cm4gMTsKI2VuZGlmCgoJd2luZWZpbGVfbWFpbihoaW5zdGFuY2UsIDAsIGNtZHNob3cpOwoKCXJldHVybiAwOwp9Cg==