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+IDQpCgkJR2xvYmFscy5udW1fc2VwID0gYlsxXTsKCWVsc2UKCQlHbG9iYWxzLm51bV9zZXAgPSBURVhUKCcuJyk7CgoJb2xkX2ZvbnQgPSBTZWxlY3RGb250KGhkYywgR2xvYmFscy5oZm9udCk7CglHZXRUZXh0RXh0ZW50UG9pbnQzMihoZGMsIHNTcGFjZSwgMSwgJkdsb2JhbHMuc3BhY2VTaXplKTsKCVNlbGVjdEZvbnQoaGRjLCBvbGRfZm9udCk7CglSZWxlYXNlREMoaHduZCwgaGRjKTsKfQoKc3RhdGljIHZvaWQgZHJhd19pdGVtKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBFbnRyeSogZW50cnksIGludCBjYWxjV2lkdGhDb2wpOwoKCi8qIGNhbGN1bGF0ZSBwcmVmZXJyZWQgd2lkdGggZm9yIGFsbCB2aXNpYmxlIGNvbHVtbnMgKi8KCnN0YXRpYyBCT09MIGNhbGNfd2lkdGhzKFBhbmUqIHBhbmUsIEJPT0wgYW55d2F5KQp7CglpbnQgY29sLCB4LCBjeCwgc3BjPTMqR2xvYmFscy5zcGFjZVNpemUuY3g7CglpbnQgZW50cmllcyA9IExpc3RCb3hfR2V0Q291bnQocGFuZS0+aHduZCk7CglpbnQgb3JnV2lkdGhzW0NPTFVNTlNdOwoJaW50IG9yZ1Bvc2l0aW9uc1tDT0xVTU5TKzFdOwoJSEZPTlQgaGZvbnRPbGQ7CglIREMgaGRjOwoJaW50IGNudDsKCglpZiAoIWFueXdheSkgewoJCW1lbWNweShvcmdXaWR0aHMsIHBhbmUtPndpZHRocywgc2l6ZW9mKG9yZ1dpZHRocykpOwoJCW1lbWNweShvcmdQb3NpdGlvbnMsIHBhbmUtPnBvc2l0aW9ucywgc2l6ZW9mKG9yZ1Bvc2l0aW9ucykpOwoJfQoKCWZvcihjb2w9MDsgY29sPENPTFVNTlM7IGNvbCsrKQoJCXBhbmUtPndpZHRoc1tjb2xdID0gMDsKCgloZGMgPSBHZXREQyhwYW5lLT5od25kKTsKCWhmb250T2xkID0gU2VsZWN0Rm9udChoZGMsIEdsb2JhbHMuaGZvbnQpOwoKCWZvcihjbnQ9MDsgY250PGVudHJpZXM7IGNudCsrKSB7CgkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgTGlzdEJveF9HZXRJdGVtRGF0YShwYW5lLT5od25kLCBjbnQpOwoKCQlEUkFXSVRFTVNUUlVDVCBkaXM7CgoJCWRpcy5DdGxUeXBlCQkgID0gMDsKCQlkaXMuQ3RsSUQJCSAgPSAwOwoJCWRpcy5pdGVtSUQJCSAgPSAwOwoJCWRpcy5pdGVtQWN0aW9uCSAgPSAwOwoJCWRpcy5pdGVtU3RhdGUJICA9IDA7CgkJZGlzLmh3bmRJdGVtCSAgPSBwYW5lLT5od25kOwoJCWRpcy5oREMJCQkgID0gaGRjOwoJCWRpcy5yY0l0ZW0ubGVmdAkgID0gMDsKCQlkaXMucmNJdGVtLnRvcCAgICA9IDA7CgkJZGlzLnJjSXRlbS5yaWdodCAgPSAwOwoJCWRpcy5yY0l0ZW0uYm90dG9tID0gMDsKCQkvKmRpcy5pdGVtRGF0YQkgID0gMDsgKi8KCgkJZHJhd19pdGVtKHBhbmUsICZkaXMsIGVudHJ5LCBDT0xVTU5TKTsKCX0KCglTZWxlY3RPYmplY3QoaGRjLCBoZm9udE9sZCk7CglSZWxlYXNlREMocGFuZS0+aHduZCwgaGRjKTsKCgl4ID0gMDsKCWZvcihjb2w9MDsgY29sPENPTFVNTlM7IGNvbCsrKSB7CgkJcGFuZS0+cG9zaXRpb25zW2NvbF0gPSB4OwoJCWN4ID0gcGFuZS0+d2lkdGhzW2NvbF07CgoJCWlmIChjeCkgewoJCQljeCArPSBzcGM7CgoJCQlpZiAoY3ggPCBJTUFHRV9XSURUSCkKCQkJCWN4ID0gSU1BR0VfV0lEVEg7CgoJCQlwYW5lLT53aWR0aHNbY29sXSA9IGN4OwoJCX0KCgkJeCArPSBjeDsKCX0KCglwYW5lLT5wb3NpdGlvbnNbQ09MVU1OU10gPSB4OwoKCUxpc3RCb3hfU2V0SG9yaXpvbnRhbEV4dGVudChwYW5lLT5od25kLCB4KTsKCgkvKiBubyBjaGFuZ2U/ICovCglpZiAoIW1lbWNtcChvcmdXaWR0aHMsIHBhbmUtPndpZHRocywgc2l6ZW9mKG9yZ1dpZHRocykpKQoJCXJldHVybiBGQUxTRTsKCgkvKiBkb24ndCBtb3ZlLCBpZiBvbmx5IGNvbGxhcHNpbmcgYW4gZW50cnkgKi8KCWlmICghYW55d2F5ICYmIHBhbmUtPndpZHRoc1swXTxvcmdXaWR0aHNbMF0gJiYKCQkhbWVtY21wKG9yZ1dpZHRocysxLCBwYW5lLT53aWR0aHMrMSwgc2l6ZW9mKG9yZ1dpZHRocyktc2l6ZW9mKGludCkpKSB7CgkJcGFuZS0+d2lkdGhzWzBdID0gb3JnV2lkdGhzWzBdOwoJCW1lbWNweShwYW5lLT5wb3NpdGlvbnMsIG9yZ1Bvc2l0aW9ucywgc2l6ZW9mKG9yZ1Bvc2l0aW9ucykpOwoKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJSW52YWxpZGF0ZVJlY3QocGFuZS0+aHduZCwgMCwgVFJVRSk7CgoJcmV0dXJuIFRSVUU7Cn0KCgovKiBjYWxjdWxhdGUgb25lIHByZWZlcnJlZCBjb2x1bW4gd2lkdGggKi8KCnN0YXRpYyB2b2lkIGNhbGNfc2luZ2xlX3dpZHRoKFBhbmUqIHBhbmUsIGludCBjb2wpCnsKCUhGT05UIGhmb250T2xkOwoJaW50IHgsIGN4OwoJaW50IGVudHJpZXMgPSBMaXN0Qm94X0dldENvdW50KHBhbmUtPmh3bmQpOwoJaW50IGNudDsKCUhEQyBoZGM7CgoJcGFuZS0+d2lkdGhzW2NvbF0gPSAwOwoKCWhkYyA9IEdldERDKHBhbmUtPmh3bmQpOwoJaGZvbnRPbGQgPSBTZWxlY3RGb250KGhkYywgR2xvYmFscy5oZm9udCk7CgoJZm9yKGNudD0wOyBjbnQ8ZW50cmllczsgY250KyspIHsKCQlFbnRyeSogZW50cnkgPSAoRW50cnkqKSBMaXN0Qm94X0dldEl0ZW1EYXRhKHBhbmUtPmh3bmQsIGNudCk7CgkJRFJBV0lURU1TVFJVQ1QgZGlzOwoKCQlkaXMuQ3RsVHlwZQkJICA9IDA7CgkJZGlzLkN0bElECQkgID0gMDsKCQlkaXMuaXRlbUlECQkgID0gMDsKCQlkaXMuaXRlbUFjdGlvbgkgID0gMDsKCQlkaXMuaXRlbVN0YXRlCSAgPSAwOwoJCWRpcy5od25kSXRlbQkgID0gcGFuZS0+aHduZDsKCQlkaXMuaERDCQkJICA9IGhkYzsKCQlkaXMucmNJdGVtLmxlZnQJICA9IDA7CgkJZGlzLnJjSXRlbS50b3AgICAgPSAwOwoJCWRpcy5yY0l0ZW0ucmlnaHQgID0gMDsKCQlkaXMucmNJdGVtLmJvdHRvbSA9IDA7CgkJLypkaXMuaXRlbURhdGEJICA9IDA7ICovCgoJCWRyYXdfaXRlbShwYW5lLCAmZGlzLCBlbnRyeSwgY29sKTsKCX0KCglTZWxlY3RPYmplY3QoaGRjLCBoZm9udE9sZCk7CglSZWxlYXNlREMocGFuZS0+aHduZCwgaGRjKTsKCgljeCA9IHBhbmUtPndpZHRoc1tjb2xdOwoKCWlmIChjeCkgewoJCWN4ICs9IDMqR2xvYmFscy5zcGFjZVNpemUuY3g7CgoJCWlmIChjeCA8IElNQUdFX1dJRFRIKQoJCQljeCA9IElNQUdFX1dJRFRIOwoJfQoKCXBhbmUtPndpZHRoc1tjb2xdID0gY3g7CgoJeCA9IHBhbmUtPnBvc2l0aW9uc1tjb2xdICsgY3g7CgoJZm9yKDsgY29sPENPTFVNTlM7ICkgewoJCXBhbmUtPnBvc2l0aW9uc1srK2NvbF0gPSB4OwoJCXggKz0gcGFuZS0+d2lkdGhzW2NvbF07Cgl9CgoJTGlzdEJveF9TZXRIb3Jpem9udGFsRXh0ZW50KHBhbmUtPmh3bmQsIHgpOwp9CgoKLyogaW5zZXJ0IGxpc3Rib3ggZW50cmllcyBhZnRlciBpbmRleCBpZHggKi8KCnN0YXRpYyB2b2lkIGluc2VydF9lbnRyaWVzKFBhbmUqIHBhbmUsIEVudHJ5KiBkaXIsIGludCBpZHgpCnsKCUVudHJ5KiBlbnRyeSA9IGRpcjsKCglpZiAoIWVudHJ5KQoJCXJldHVybjsKCglTaG93V2luZG93KHBhbmUtPmh3bmQsIFNXX0hJREUpOwoKCWZvcig7IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkgewojaWZuZGVmIF9MRUZUX0ZJTEVTCgkJaWYgKHBhbmUtPnRyZWVQYW5lICYmICEoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpKQoJCQljb250aW51ZTsKI2VuZGlmCgoJCS8qIGRvbid0IGRpc3BsYXkgZW50cmllcyAiLiIgYW5kICIuLiIgaW4gdGhlIGxlZnQgcGFuZSAqLwoJCWlmIChwYW5lLT50cmVlUGFuZSAmJiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpCgkJCQkmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF09PVRFWFQoJy4nKSkKCQkJaWYgKAojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCQllbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMV09PVRFWFQoJ1wwJykgfHwKI2VuZGlmCgkJCQkoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT1URVhUKCcuJykgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzJdPT1URVhUKCdcMCcpKSkKCQkJCWNvbnRpbnVlOwoKCQlpZiAoaWR4ICE9IC0xKQoJCQlpZHgrKzsKCgkJTGlzdEJveF9JbnNlcnRJdGVtRGF0YShwYW5lLT5od25kLCBpZHgsIGVudHJ5KTsKCgkJaWYgKHBhbmUtPnRyZWVQYW5lICYmIGVudHJ5LT5leHBhbmRlZCkgewoJCQlpbnNlcnRfZW50cmllcyhwYW5lLCBlbnRyeS0+ZG93biwgaWR4KTsKCQkJaWR4ID0gTGlzdEJveF9HZXRDb3VudChwYW5lLT5od25kKS0xOwoJCX0KCX0KCglTaG93V2luZG93KHBhbmUtPmh3bmQsIFNXX1NIT1cpOwp9CgoKc3RhdGljIFdORFBST0MgZ19vcmdUcmVlV25kUHJvYzsKCnN0YXRpYyB2b2lkIGNyZWF0ZV90cmVlX3dpbmRvdyhIV05EIHBhcmVudCwgUGFuZSogcGFuZSwgaW50IGlkLCBpbnQgaWRfaGVhZGVyKQp7Cgljb25zdCBzdGF0aWMgVENIQVIgc0xpc3RCb3hbXSA9IHsnTCcsJ2knLCdzJywndCcsJ0InLCdvJywneCcsJ1wwJ307CgoJc3RhdGljIGludCBzX2luaXQgPSAwOwoJRW50cnkqIGVudHJ5ID0gcGFuZS0+cm9vdDsKCglwYW5lLT5od25kID0gQ3JlYXRlV2luZG93KHNMaXN0Qm94LCBzRW1wdHksIFdTX0NISUxEfFdTX1ZJU0lCTEV8V1NfSFNDUk9MTHxXU19WU0NST0xMfAoJCQkJCQkJCUxCU19ESVNBQkxFTk9TQ1JPTEx8TEJTX05PSU5URUdSQUxIRUlHSFR8TEJTX09XTkVSRFJBV0ZJWEVEfExCU19OT1RJRlksCgkJCQkJCQkJMCwgMCwgMCwgMCwgcGFyZW50LCAoSE1FTlUpaWQsIEdsb2JhbHMuaEluc3RhbmNlLCAwKTsKCglTZXRXaW5kb3dMb25nKHBhbmUtPmh3bmQsIEdXTF9VU0VSREFUQSwgKExQQVJBTSlwYW5lKTsKCWdfb3JnVHJlZVduZFByb2MgPSBTdWJjbGFzc1dpbmRvdyhwYW5lLT5od25kLCBUcmVlV25kUHJvYyk7CgoJU2V0V2luZG93Rm9udChwYW5lLT5od25kLCBHbG9iYWxzLmhmb250LCBGQUxTRSk7CgoJLyogaW5zZXJ0IGVudHJpZXMgaW50byBsaXN0Ym94ICovCglpZiAoZW50cnkpCgkJaW5zZXJ0X2VudHJpZXMocGFuZSwgZW50cnksIC0xKTsKCgkvKiBjYWxjdWxhdGUgY29sdW1uIHdpZHRocyAqLwoJaWYgKCFzX2luaXQpIHsKCQlzX2luaXQgPSAxOwoJCWluaXRfb3V0cHV0KHBhbmUtPmh3bmQpOwoJfQoKCWNhbGNfd2lkdGhzKHBhbmUsIFRSVUUpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJcGFuZS0+aHduZEhlYWRlciA9IGNyZWF0ZV9oZWFkZXIocGFyZW50LCBwYW5lLCBpZF9oZWFkZXIpOwojZW5kaWYKfQoKCnN0YXRpYyB2b2lkIEluaXRDaGlsZFdpbmRvdyhDaGlsZFduZCogY2hpbGQpCnsKCWNyZWF0ZV90cmVlX3dpbmRvdyhjaGlsZC0+aHduZCwgJmNoaWxkLT5sZWZ0LCBJRFdfVFJFRV9MRUZULCBJRFdfSEVBREVSX0xFRlQpOwoJY3JlYXRlX3RyZWVfd2luZG93KGNoaWxkLT5od25kLCAmY2hpbGQtPnJpZ2h0LCBJRFdfVFJFRV9SSUdIVCwgSURXX0hFQURFUl9SSUdIVCk7Cn0KCgpzdGF0aWMgdm9pZCBmb3JtYXRfZGF0ZShjb25zdCBGSUxFVElNRSogZnQsIFRDSEFSKiBidWZmZXIsIGludCB2aXNpYmxlX2NvbHMpCnsKCVNZU1RFTVRJTUUgc3lzdGltZTsKCUZJTEVUSU1FIGxmdDsKCWludCBsZW4gPSAwOwoKCSpidWZmZXIgPSBURVhUKCdcMCcpOwoKCWlmICghZnQtPmR3TG93RGF0ZVRpbWUgJiYgIWZ0LT5kd0hpZ2hEYXRlVGltZSkKCQlyZXR1cm47CgoJaWYgKCFGaWxlVGltZVRvTG9jYWxGaWxlVGltZShmdCwgJmxmdCkpCgkJe2VycjogX3Rjc2NweShidWZmZXIsc1FNYXJrcyk7IHJldHVybjt9CgoJaWYgKCFGaWxlVGltZVRvU3lzdGVtVGltZSgmbGZ0LCAmc3lzdGltZSkpCgkJZ290byBlcnI7CgoJaWYgKHZpc2libGVfY29scyAmIENPTF9EQVRFKSB7CgkJbGVuID0gR2V0RGF0ZUZvcm1hdChMT0NBTEVfVVNFUl9ERUZBVUxULCAwLCAmc3lzdGltZSwgMCwgYnVmZmVyLCBCVUZGRVJfTEVOKTsKCQlpZiAoIWxlbikKCQkJZ290byBlcnI7Cgl9CgoJaWYgKHZpc2libGVfY29scyAmIENPTF9USU1FKSB7CgkJaWYgKGxlbikKCQkJYnVmZmVyW2xlbi0xXSA9ICcgJzsKCgkJYnVmZmVyW2xlbisrXSA9ICcgJzsKCgkJaWYgKCFHZXRUaW1lRm9ybWF0KExPQ0FMRV9VU0VSX0RFRkFVTFQsIDAsICZzeXN0aW1lLCAwLCBidWZmZXIrbGVuLCBCVUZGRVJfTEVOLWxlbikpCgkJCWJ1ZmZlcltsZW5dID0gVEVYVCgnXDAnKTsKCX0KfQoKCnN0YXRpYyB2b2lkIGNhbGNfd2lkdGgoUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIGludCBjb2wsIExQQ1RTVFIgc3RyKQp7CglSRUNUIHJ0ID0gezAsIDAsIDAsIDB9OwoKCURyYXdUZXh0KGRpcy0+aERDLCAoTFBUU1RSKXN0ciwgLTEsICZydCwgRFRfQ0FMQ1JFQ1R8RFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWCk7CgoJaWYgKHJ0LnJpZ2h0ID4gcGFuZS0+d2lkdGhzW2NvbF0pCgkJcGFuZS0+d2lkdGhzW2NvbF0gPSBydC5yaWdodDsKfQoKc3RhdGljIHZvaWQgY2FsY190YWJiZWRfd2lkdGgoUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIGludCBjb2wsIExQQ1RTVFIgc3RyKQp7CglSRUNUIHJ0ID0gezAsIDAsIDAsIDB9OwoKLyoJRFJBV1RFWFRQQVJBTVMgZHRwID0ge3NpemVvZihEUkFXVEVYVFBBUkFNUyksIDJ9OwoJRHJhd1RleHRFeChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX0NBTENSRUNUfERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVh8RFRfRVhQQU5EVEFCU3xEVF9UQUJTVE9QLCAmZHRwKTsqLwoKCURyYXdUZXh0KGRpcy0+aERDLCAoTFBUU1RSKXN0ciwgLTEsICZydCwgRFRfQ0FMQ1JFQ1R8RFRfU0lOR0xFTElORXxEVF9FWFBBTkRUQUJTfERUX1RBQlNUT1B8KDI8PDgpKTsKCS8qRklYTUUgcnQgKDAsMCkgPz8/ICovCgoJaWYgKHJ0LnJpZ2h0ID4gcGFuZS0+d2lkdGhzW2NvbF0pCgkJcGFuZS0+d2lkdGhzW2NvbF0gPSBydC5yaWdodDsKfQoKCnN0YXRpYyB2b2lkIG91dHB1dF90ZXh0KFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0ciwgRFdPUkQgZmxhZ3MpCnsKCWludCB4ID0gZGlzLT5yY0l0ZW0ubGVmdDsKCVJFQ1QgcnQ7CgoJcnQubGVmdCAgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sXStHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LnRvcCAgICA9IGRpcy0+cmNJdGVtLnRvcDsKCXJ0LnJpZ2h0ICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbCsxXS1HbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LmJvdHRvbSA9IGRpcy0+cmNJdGVtLmJvdHRvbTsKCglEcmF3VGV4dChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVh8ZmxhZ3MpOwp9CgpzdGF0aWMgdm9pZCBvdXRwdXRfdGFiYmVkX3RleHQoUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIGludCBjb2wsIExQQ1RTVFIgc3RyKQp7CglpbnQgeCA9IGRpcy0+cmNJdGVtLmxlZnQ7CglSRUNUIHJ0OwoKCXJ0LmxlZnQgICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbF0rR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC50b3AgICAgPSBkaXMtPnJjSXRlbS50b3A7CglydC5yaWdodCAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2wrMV0tR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC5ib3R0b20gPSBkaXMtPnJjSXRlbS5ib3R0b207CgovKglEUkFXVEVYVFBBUkFNUyBkdHAgPSB7c2l6ZW9mKERSQVdURVhUUEFSQU1TKSwgMn07CglEcmF3VGV4dEV4KGRpcy0+aERDLCAoTFBUU1RSKXN0ciwgLTEsICZydCwgRFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWHxEVF9FWFBBTkRUQUJTfERUX1RBQlNUT1AsICZkdHApOyovCgoJRHJhd1RleHQoZGlzLT5oREMsIChMUFRTVFIpc3RyLCAtMSwgJnJ0LCBEVF9TSU5HTEVMSU5FfERUX0VYUEFORFRBQlN8RFRfVEFCU1RPUHwoMjw8OCkpOwp9CgpzdGF0aWMgdm9pZCBvdXRwdXRfbnVtYmVyKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0cikKewoJaW50IHggPSBkaXMtPnJjSXRlbS5sZWZ0OwoJUkVDVCBydDsKCUxQQ1RTVFIgcyA9IHN0cjsKCVRDSEFSIGJbMTI4XTsKCUxQVFNUUiBkID0gYjsKCWludCBwb3M7CgoJcnQubGVmdCAgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sXStHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LnRvcCAgICA9IGRpcy0+cmNJdGVtLnRvcDsKCXJ0LnJpZ2h0ICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbCsxXS1HbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LmJvdHRvbSA9IGRpcy0+cmNJdGVtLmJvdHRvbTsKCglpZiAoKnMpCgkJKmQrKyA9ICpzKys7CgoJLyogaW5zZXJ0IG51bWJlciBzZXBhcmF0b3IgY2hhcmFjdGVycyAqLwoJcG9zID0gbHN0cmxlbihzKSAlIDM7CgoJd2hpbGUoKnMpCgkJaWYgKHBvcy0tKQoJCQkqZCsrID0gKnMrKzsKCQllbHNlIHsKCQkJKmQrKyA9IEdsb2JhbHMubnVtX3NlcDsKCQkJcG9zID0gMzsKCQl9CgoJRHJhd1RleHQoZGlzLT5oREMsIGIsIGQtYiwgJnJ0LCBEVF9SSUdIVHxEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYfERUX0VORF9FTExJUFNJUyk7Cn0KCgpzdGF0aWMgaW50IGlzX2V4ZV9maWxlKExQQ1RTVFIgZXh0KQp7CglzdGF0aWMgY29uc3QgVENIQVIgZXhlY3V0YWJsZV9leHRlbnNpb25zW11bNF0gPSB7CgkJeydDJywnTycsJ00nLCdcMCd9LAoJCXsnRScsJ1gnLCdFJywnXDAnfSwKCQl7J0InLCdBJywnVCcsJ1wwJ30sCgkJeydDJywnTScsJ0QnLCdcMCd9LAojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJeydDJywnTScsJ00nLCdcMCd9LAoJCXsnQicsJ1QnLCdNJywnXDAnfSwKCQl7J0EnLCdXJywnSycsJ1wwJ30sCiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoJCXsnXDAnfQoJfTsKCglUQ0hBUiBleHRfYnVmZmVyW19NQVhfRVhUXTsKCWNvbnN0IFRDSEFSICgqcClbNF07CglMUENUU1RSIHM7CglMUFRTVFIgZDsKCglmb3Iocz1leHQrMSxkPWV4dF9idWZmZXI7ICgqZD10b2xvd2VyKCpzKSk7IHMrKykKCQlkKys7CgoJZm9yKHA9ZXhlY3V0YWJsZV9leHRlbnNpb25zOyAoKnApWzBdOyBwKyspCgkJaWYgKCFfdGNzY21wKGV4dF9idWZmZXIsICpwKSkKCQkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgaXNfcmVnaXN0ZXJlZF90eXBlKExQQ1RTVFIgZXh0KQp7CiAgICAgICAgLyogVE9ETyAqLwoKCXJldHVybiAxOwp9CgoKc3RhdGljIHZvaWQgZHJhd19pdGVtKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBFbnRyeSogZW50cnksIGludCBjYWxjV2lkdGhDb2wpCnsKCVRDSEFSIGJ1ZmZlcltCVUZGRVJfTEVOXTsKCURXT1JEIGF0dHJzOwoJaW50IHZpc2libGVfY29scyA9IHBhbmUtPnZpc2libGVfY29sczsKCUNPTE9SUkVGIGJrY29sb3IsIHRleHRjb2xvcjsKCVJFQ1QgZm9jdXNSZWN0ID0gZGlzLT5yY0l0ZW07CglIQlJVU0ggaGJydXNoOwoJZW51bSBJTUFHRSBpbWc7CglpbnQgaW1nX3BvcywgY3g7CglpbnQgY29sID0gMDsKCglpZiAoZW50cnkpIHsKCQlhdHRycyA9IGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXM7CgoJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQlpZiAoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT1URVhUKCcuJykgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT1URVhUKCcuJykKCQkJCQkmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMl09PVRFWFQoJ1wwJykpCgkJCQlpbWcgPSBJTUdfRk9MREVSX1VQOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCWVsc2UgaWYgKGVudHJ5LT5kYXRhLmNGaWxlTmFtZVswXT09VEVYVCgnLicpICYmIGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsxXT09VEVYVCgnXDAnKSkKCQkJCWltZyA9IElNR19GT0xERVJfQ1VSOwojZW5kaWYKCQkJZWxzZSBpZiAoCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCSBlbnRyeS0+ZXhwYW5kZWQgfHwKI2VuZGlmCgkJCQkJIChwYW5lLT50cmVlUGFuZSAmJiAoZGlzLT5pdGVtU3RhdGUmT0RTX0ZPQ1VTKSkpCgkJCQlpbWcgPSBJTUdfT1BFTl9GT0xERVI7CgkJCWVsc2UKCQkJCWltZyA9IElNR19GT0xERVI7CgkJfSBlbHNlIHsKCQkJTFBDVFNUUiBleHQgPSBfdGNzcmNocihlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsICcuJyk7CgkJCWlmICghZXh0KQoJCQkJZXh0ID0gc0VtcHR5OwoKCQkJaWYgKGlzX2V4ZV9maWxlKGV4dCkpCgkJCQlpbWcgPSBJTUdfRVhFQ1VUQUJMRTsKCQkJZWxzZSBpZiAoaXNfcmVnaXN0ZXJlZF90eXBlKGV4dCkpCgkJCQlpbWcgPSBJTUdfRE9DVU1FTlQ7CgkJCWVsc2UKCQkJCWltZyA9IElNR19GSUxFOwoJCX0KCX0gZWxzZSB7CgkJYXR0cnMgPSAwOwoJCWltZyA9IElNR19OT05FOwoJfQoKCWlmIChwYW5lLT50cmVlUGFuZSkgewoJCWlmIChlbnRyeSkgewoJCQlpbWdfcG9zID0gZGlzLT5yY0l0ZW0ubGVmdCArIGVudHJ5LT5sZXZlbCooSU1BR0VfV0lEVEgrVFJFRV9MSU5FX0RYKTsKCgkJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpIHsKCQkJCWludCB4OwoJCQkJaW50IHkgPSBkaXMtPnJjSXRlbS50b3AgKyBJTUFHRV9IRUlHSFQvMjsKCQkJCUVudHJ5KiB1cDsKCQkJCVJFQ1QgcnRfY2xpcDsKCQkJCUhSR04gaHJnbl9vcmcgPSBDcmVhdGVSZWN0UmduKDAsIDAsIDAsIDApOwoJCQkJSFJHTiBocmduOwoKCQkJCXJ0X2NsaXAubGVmdCAgID0gZGlzLT5yY0l0ZW0ubGVmdDsKCQkJCXJ0X2NsaXAudG9wICAgID0gZGlzLT5yY0l0ZW0udG9wOwoJCQkJcnRfY2xpcC5yaWdodCAgPSBkaXMtPnJjSXRlbS5sZWZ0K3BhbmUtPndpZHRoc1tjb2xdOwoJCQkJcnRfY2xpcC5ib3R0b20gPSBkaXMtPnJjSXRlbS5ib3R0b207CgoJCQkJaHJnbiA9IENyZWF0ZVJlY3RSZ25JbmRpcmVjdCgmcnRfY2xpcCk7CgoJCQkJaWYgKCFHZXRDbGlwUmduKGRpcy0+aERDLCBocmduX29yZykpIHsKCQkJCQlEZWxldGVPYmplY3QoaHJnbl9vcmcpOwoJCQkJCWhyZ25fb3JnID0gMDsKCQkJCX0KCgkJCQkvKiBIR0RJT0JKIGhvbGRQZW4gPSBTZWxlY3RPYmplY3QoZGlzLT5oREMsIEdldFN0b2NrT2JqZWN0KEJMQUNLX1BFTikpOyAqLwoJCQkJRXh0U2VsZWN0Q2xpcFJnbihkaXMtPmhEQywgaHJnbiwgUkdOX0FORCk7CgkJCQlEZWxldGVPYmplY3QoaHJnbik7CgoJCQkJaWYgKCh1cD1lbnRyeS0+dXApICE9IE5VTEwpIHsKCQkJCQlNb3ZlVG9FeChkaXMtPmhEQywgaW1nX3Bvcy1JTUFHRV9XSURUSC8yLCB5LCAwKTsKCQkJCQlMaW5lVG8oZGlzLT5oREMsIGltZ19wb3MtMiwgeSk7CgoJCQkJCXggPSBpbWdfcG9zIC0gSU1BR0VfV0lEVEgvMjsKCgkJCQkJZG8gewoJCQkJCQl4IC09IElNQUdFX1dJRFRIK1RSRUVfTElORV9EWDsKCgkJCQkJCWlmICh1cC0+bmV4dAojaWZuZGVmIF9MRUZUX0ZJTEVTCgkJCQkJCQkmJiAodXAtPm5leHQtPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkKI2VuZGlmCgkJCQkJCQkpIHsKCQkJCQkJCU1vdmVUb0V4KGRpcy0+aERDLCB4LCBkaXMtPnJjSXRlbS50b3AsIDApOwoJCQkJCQkJTGluZVRvKGRpcy0+aERDLCB4LCBkaXMtPnJjSXRlbS5ib3R0b20pOwoJCQkJCQl9CgkJCQkJfSB3aGlsZSgodXA9dXAtPnVwKSAhPSBOVUxMKTsKCQkJCX0KCgkJCQl4ID0gaW1nX3BvcyAtIElNQUdFX1dJRFRILzI7CgoJCQkJTW92ZVRvRXgoZGlzLT5oREMsIHgsIGRpcy0+cmNJdGVtLnRvcCwgMCk7CgkJCQlMaW5lVG8oZGlzLT5oREMsIHgsIHkpOwoKCQkJCWlmIChlbnRyeS0+bmV4dAojaWZuZGVmIF9MRUZUX0ZJTEVTCgkJCQkJJiYgKGVudHJ5LT5uZXh0LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKQojZW5kaWYKCQkJCQkpCgkJCQkJTGluZVRvKGRpcy0+aERDLCB4LCBkaXMtPnJjSXRlbS5ib3R0b20pOwoKCQkJCWlmIChlbnRyeS0+ZG93biAmJiBlbnRyeS0+ZXhwYW5kZWQpIHsKCQkJCQl4ICs9IElNQUdFX1dJRFRIK1RSRUVfTElORV9EWDsKCQkJCQlNb3ZlVG9FeChkaXMtPmhEQywgeCwgZGlzLT5yY0l0ZW0udG9wK0lNQUdFX0hFSUdIVCsyLCAwKTsKCQkJCQlMaW5lVG8oZGlzLT5oREMsIHgsIGRpcy0+cmNJdGVtLmJvdHRvbSk7CgkJCQl9CgoJCQkJU2VsZWN0Q2xpcFJnbihkaXMtPmhEQywgaHJnbl9vcmcpOwoJCQkJaWYgKGhyZ25fb3JnKSBEZWxldGVPYmplY3QoaHJnbl9vcmcpOwoJCQkJLyogU2VsZWN0T2JqZWN0KGRpcy0+aERDLCBob2xkUGVuKTsgKi8KCQkJfSBlbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpIHsKCQkJCWludCByaWdodCA9IGltZ19wb3MgKyBJTUFHRV9XSURUSCAtIFRSRUVfTElORV9EWDsKCgkJCQlpZiAocmlnaHQgPiBwYW5lLT53aWR0aHNbY29sXSkKCQkJCQlwYW5lLT53aWR0aHNbY29sXSA9IHJpZ2h0OwoJCQl9CgkJfSBlbHNlICB7CgkJCWltZ19wb3MgPSBkaXMtPnJjSXRlbS5sZWZ0OwoJCX0KCX0gZWxzZSB7CgkJaW1nX3BvcyA9IGRpcy0+cmNJdGVtLmxlZnQ7CgoJCWlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCXBhbmUtPndpZHRoc1tjb2xdID0gSU1BR0VfV0lEVEg7Cgl9CgoJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkgewoJCWZvY3VzUmVjdC5sZWZ0ID0gaW1nX3BvcyAtMjsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCWlmIChwYW5lLT50cmVlUGFuZSAmJiBlbnRyeSkgewoJCQlSRUNUIHJ0ID0gezB9OwoKCQkJRHJhd1RleHQoZGlzLT5oREMsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSwgLTEsICZydCwgRFRfQ0FMQ1JFQ1R8RFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWCk7CgoJCQlmb2N1c1JlY3QucmlnaHQgPSBkaXMtPnJjSXRlbS5sZWZ0K3BhbmUtPnBvc2l0aW9uc1tjb2wrMV0rVFJFRV9MSU5FX0RYICsgcnQucmlnaHQgKzI7CgkJfQojZWxzZQoKCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9DT01QUkVTU0VEKQoJCQl0ZXh0Y29sb3IgPSBDT0xPUl9DT01QUkVTU0VEOwoJCWVsc2UKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgkJCXRleHRjb2xvciA9IFJHQigwLDAsMCk7CgoJCWlmIChkaXMtPml0ZW1TdGF0ZSAmIE9EU19GT0NVUykgewoJCQl0ZXh0Y29sb3IgPSBSR0IoMjU1LDI1NSwyNTUpOwoJCQlia2NvbG9yID0gQ09MT1JfU0VMRUNUSU9OOwoJCX0gZWxzZSB7CgkJCWJrY29sb3IgPSBSR0IoMjU1LDI1NSwyNTUpOwoJCX0KCgkJaGJydXNoID0gQ3JlYXRlU29saWRCcnVzaChia2NvbG9yKTsKCQlGaWxsUmVjdChkaXMtPmhEQywgJmZvY3VzUmVjdCwgaGJydXNoKTsKCQlEZWxldGVPYmplY3QoaGJydXNoKTsKCgkJU2V0QmtNb2RlKGRpcy0+aERDLCBUUkFOU1BBUkVOVCk7CgkJU2V0VGV4dENvbG9yKGRpcy0+aERDLCB0ZXh0Y29sb3IpOwoKCQljeCA9IHBhbmUtPndpZHRoc1tjb2xdOwoKCQlpZiAoY3ggJiYgaW1nIT1JTUdfTk9ORSkgewoKCQkJaWYgKGN4ID4gSU1BR0VfV0lEVEgpCgkJCQljeCA9IElNQUdFX1dJRFRIOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgkJCWlmIChlbnRyeS0+aGljb24gJiYgZW50cnktPmhpY29uIT0oSElDT04pLTEpCgkJCQlEcmF3SWNvbkV4KGRpcy0+aERDLCBpbWdfcG9zLCBkaXMtPnJjSXRlbS50b3AsIGVudHJ5LT5oaWNvbiwgY3gsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUlDT04pLCAwLCAwLCBESV9OT1JNQUwpOwoJCQllbHNlCiNlbmRpZgoJCQkJSW1hZ2VMaXN0X0RyYXdFeChHbG9iYWxzLmhpbWwsIGltZywgZGlzLT5oREMsCgkJCQkJCQkJIGltZ19wb3MsIGRpcy0+cmNJdGVtLnRvcCwgY3gsCgkJCQkJCQkJIElNQUdFX0hFSUdIVCwgYmtjb2xvciwgQ0xSX0RFRkFVTFQsIElMRF9OT1JNQUwpOwoJCX0KCX0KCglpZiAoIWVudHJ5KQoJCXJldHVybjsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJaWYgKGltZyA+PSBJTUdfRk9MREVSX1VQKQoJCXJldHVybjsKI2VuZGlmCgoJY29sKys7CgoJLyogb3VwdXQgZmlsZSBuYW1lICovCglpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIDApOwoJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSk7CgoJY29sKys7CgojaWZkZWYgX05PX0VYVEVOU0lPTlMKICBpZiAoIXBhbmUtPnRyZWVQYW5lKSB7CiNlbmRpZgoKICAgICAgICAvKiBkaXNwbGF5IGZpbGUgc2l6ZSAqLwoJaWYgKHZpc2libGVfY29scyAmIENPTF9TSVpFKSB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCWlmICghKGF0dHJzJkZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkpCiNlbmRpZgoJCXsKCQkJVUxPTkdMT05HIHNpemU7CgogICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gKChVTE9OR0xPTkcpZW50cnktPmRhdGEubkZpbGVTaXplSGlnaCA8PCAzMikgfCBlbnRyeS0+ZGF0YS5uRmlsZVNpemVMb3c7CgoJCQlfc3RwcmludGYoYnVmZmVyLCBzTG9uZ051bUZtdCwgc2l6ZSk7CgoJCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQkJb3V0cHV0X251bWJlcihwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCQkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsvKlRPRE86IG5vdCBldmVyIHRpbWUgZW5vdWdoICovCgkJfQoKCQljb2wrKzsKCX0KCgkvKiBkaXNwbGF5IGZpbGUgZGF0ZSAqLwoJaWYgKHZpc2libGVfY29scyAmIChDT0xfREFURXxDT0xfVElNRSkpIHsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWZvcm1hdF9kYXRlKCZlbnRyeS0+ZGF0YS5mdENyZWF0aW9uVGltZSwgYnVmZmVyLCB2aXNpYmxlX2NvbHMpOwoJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIsIDApOwoJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCQljb2wrKzsKCgkJZm9ybWF0X2RhdGUoJmVudHJ5LT5kYXRhLmZ0TGFzdEFjY2Vzc1RpbWUsIGJ1ZmZlciwgdmlzaWJsZV9jb2xzKTsKCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyLCAwKTsKCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgkJY29sKys7CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCQlmb3JtYXRfZGF0ZSgmZW50cnktPmRhdGEuZnRMYXN0V3JpdGVUaW1lLCBidWZmZXIsIHZpc2libGVfY29scyk7CgkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlciwgMCk7CgkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoJCWNvbCsrOwoJfQoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJaWYgKGVudHJ5LT5iaGZpX3ZhbGlkKSB7CiAgICAgICAgICAgIFVMT05HTE9ORyBpbmRleCA9ICgoVUxPTkdMT05HKWVudHJ5LT5iaGZpLm5GaWxlSW5kZXhIaWdoIDw8IDMyKSB8IGVudHJ5LT5iaGZpLm5GaWxlSW5kZXhMb3c7CgoJCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfSU5ERVgpIHsKCQkJX3N0cHJpbnRmKGJ1ZmZlciwgc0xvbmdIZXhGbXQsIGluZGV4KTsKCgkJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyLCBEVF9SSUdIVCk7CgkJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgoJCQljb2wrKzsKCQl9CgoJCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfTElOS1MpIHsKCQkJd3NwcmludGYoYnVmZmVyLCBzTnVtRm10LCBlbnRyeS0+YmhmaS5uTnVtYmVyT2ZMaW5rcyk7CgoJCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlciwgRFRfQ0VOVEVSKTsKCQkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCgkJCWNvbCsrOwoJCX0KCX0gZWxzZQoJCWNvbCArPSAyOwojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgkvKiBzaG93IGZpbGUgYXR0cmlidXRlcyAqLwoJaWYgKHZpc2libGVfY29scyAmIENPTF9BVFRSSUJVVEVTKSB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCWNvbnN0IHN0YXRpYyBUQ0hBUiBzNFRhYnNbXSA9IHsnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1wwJ307CgkJX3Rjc2NweShidWZmZXIsIHM0VGFicyk7CiNlbHNlCgkJY29uc3Qgc3RhdGljIFRDSEFSIHMxMVRhYnNbXSA9IHsnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1wwJ307CgkJX3Rjc2NweShidWZmZXIsIHMxMVRhYnMpOwojZW5kaWYKCgkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfTk9STUFMKQkJCQkJYnVmZmVyWyAwXSA9ICdOJzsKCQllbHNlIHsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfUkVBRE9OTFkpCQkJYnVmZmVyWyAyXSA9ICdSJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfSElEREVOKQkJCQlidWZmZXJbIDRdID0gJ0gnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9TWVNURU0pCQkJCWJ1ZmZlclsgNl0gPSAnUyc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0FSQ0hJVkUpCQkJCWJ1ZmZlclsgOF0gPSAnQSc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0NPTVBSRVNTRUQpCQkJYnVmZmVyWzEwXSA9ICdDJzsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpCQkJYnVmZmVyWzEyXSA9ICdEJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfRU5DUllQVEVEKQkJCWJ1ZmZlclsxNF0gPSAnRSc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX1RFTVBPUkFSWSkJCQlidWZmZXJbMTZdID0gJ1QnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9TUEFSU0VfRklMRSkJCQlidWZmZXJbMThdID0gJ1AnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9SRVBBUlNFX1BPSU5UKQkJYnVmZmVyWzIwXSA9ICdRJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfT0ZGTElORSkJCQkJYnVmZmVyWzIyXSA9ICdPJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfTk9UX0NPTlRFTlRfSU5ERVhFRCkJYnVmZmVyWzI0XSA9ICdYJzsKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgkJfQoKCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQlvdXRwdXRfdGFiYmVkX3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQljYWxjX3RhYmJlZF93aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCgkJY29sKys7Cgl9CgovKlRPRE8KCWlmIChmbGFncy5zZWN1cml0eSkgewoJCWNvbnN0IHN0YXRpYyBUQ0hBUiBzU2VjVGFic1tdID0gewoJCQknICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsCgkJCScgJywnXHQnLCcgJywKCQkJJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLAoJCQknICcsJ1x0JywnICcsCgkJCScgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywKCQkJJ1wwJwoJCX07CgoJCURXT1JEIHJpZ2h0cyA9IGdldF9hY2Nlc3NfbWFzaygpOwoKCQl0Y3NjcHkoYnVmZmVyLCBzU2VjVGFicyk7CgoJCWlmIChyaWdodHMgJiBGSUxFX1JFQURfREFUQSkJCQlidWZmZXJbIDBdID0gJ1InOwoJCWlmIChyaWdodHMgJiBGSUxFX1dSSVRFX0RBVEEpCQkJYnVmZmVyWyAyXSA9ICdXJzsKCQlpZiAocmlnaHRzICYgRklMRV9BUFBFTkRfREFUQSkJCQlidWZmZXJbIDRdID0gJ0EnOwoJCWlmIChyaWdodHMgJiBGSUxFX1JFQURfRUEpCQkJCXtidWZmZXJbNl0gPSAnZW50cnknOyBidWZmZXJbIDddID0gJ1InO30KCQlpZiAocmlnaHRzICYgRklMRV9XUklURV9FQSkJCQkJe2J1ZmZlcls5XSA9ICdlbnRyeSc7IGJ1ZmZlclsxMF0gPSAnVyc7fQoJCWlmIChyaWdodHMgJiBGSUxFX0VYRUNVVEUpCQkJCWJ1ZmZlclsxMl0gPSAnWCc7CgkJaWYgKHJpZ2h0cyAmIEZJTEVfREVMRVRFX0NISUxEKQkJCWJ1ZmZlclsxNF0gPSAnRCc7CgkJaWYgKHJpZ2h0cyAmIEZJTEVfUkVBRF9BVFRSSUJVVEVTKQkJe2J1ZmZlclsxNl0gPSAnYSc7IGJ1ZmZlclsxN10gPSAnUic7fQoJCWlmIChyaWdodHMgJiBGSUxFX1dSSVRFX0FUVFJJQlVURVMpCQl7YnVmZmVyWzE5XSA9ICdhJzsgYnVmZmVyWzIwXSA9ICdXJzt9CgkJaWYgKHJpZ2h0cyAmIFdSSVRFX0RBQykJCQkJCWJ1ZmZlclsyMl0gPSAnQyc7CgkJaWYgKHJpZ2h0cyAmIFdSSVRFX09XTkVSKQkJCQlidWZmZXJbMjRdID0gJ08nOwoJCWlmIChyaWdodHMgJiBTWU5DSFJPTklaRSkJCQkJYnVmZmVyWzI2XSA9ICdTJzsKCgkJb3V0cHV0X3RleHQoZGlzLCBjb2wrKywgYnVmZmVyLCBEVF9MRUZULCAzLCBwc2l6ZSk7Cgl9CgoJaWYgKGZsYWdzLmRlc2NyaXB0aW9uKSB7CgkJZ2V0X2Rlc2NyaXB0aW9uKGJ1ZmZlcik7CgkJb3V0cHV0X3RleHQoZGlzLCBjb2wrKywgYnVmZmVyLCAwLCBwc2l6ZSk7Cgl9CiovCgojaWZkZWYgX05PX0VYVEVOU0lPTlMKICB9CgogICAgICAgIC8qIGRyYXcgZm9jdXMgZnJhbWUgKi8KCWlmICgoZGlzLT5pdGVtU3RhdGUmT0RTX0ZPQ1VTKSAmJiBjYWxjV2lkdGhDb2w9PS0xKSB7CgkgICAgICAgIC8qIEN1cnJlbnRseSBbMDQvMjAwMF0gV2luZSBuZWl0aGVyIGJlaGF2ZXMgZXhhY3RseSB0aGUgc2FtZSAqLwoJICAgICAgICAvKiB3YXkgYXMgV0lOIDk1IG5vciBsaWtlIFdpbmRvd3MgTlQuLi4gKi8KCQlIR0RJT0JKIGxhc3RCcnVzaDsKCQlIUEVOIGxhc3RQZW47CgkJSFBFTiBocGVuOwoKCQlpZiAoIShHZXRWZXJzaW9uKCkgJiAweDgwMDAwMDAwKSkgewkvKiBXaW5kb3dzIE5UPyAqLwoJCQlMT0dCUlVTSCBsYiA9IHtQU19TT0xJRCwgUkdCKDI1NSwyNTUsMjU1KX07CgkJCWhwZW4gPSBFeHRDcmVhdGVQZW4oUFNfQ09TTUVUSUN8UFNfQUxURVJOQVRFLCAxLCAmbGIsIDAsIDApOwoJCX0gZWxzZQoJCQlocGVuID0gQ3JlYXRlUGVuKFBTX0RPVCwgMCwgUkdCKDI1NSwyNTUsMjU1KSk7CgoJCWxhc3RQZW4gPSBTZWxlY3RQZW4oZGlzLT5oREMsIGhwZW4pOwoJCWxhc3RCcnVzaCA9IFNlbGVjdE9iamVjdChkaXMtPmhEQywgR2V0U3RvY2tPYmplY3QoSE9MTE9XX0JSVVNIKSk7CgkJU2V0Uk9QMihkaXMtPmhEQywgUjJfWE9SUEVOKTsKCQlSZWN0YW5nbGUoZGlzLT5oREMsIGZvY3VzUmVjdC5sZWZ0LCBmb2N1c1JlY3QudG9wLCBmb2N1c1JlY3QucmlnaHQsIGZvY3VzUmVjdC5ib3R0b20pOwoJCVNlbGVjdE9iamVjdChkaXMtPmhEQywgbGFzdEJydXNoKTsKCQlTZWxlY3RPYmplY3QoZGlzLT5oREMsIGxhc3RQZW4pOwoJCURlbGV0ZU9iamVjdChocGVuKTsKCX0KI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCn0KCgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCnN0YXRpYyB2b2lkIGRyYXdfc3BsaXRiYXIoSFdORCBod25kLCBpbnQgeCkKewoJUkVDVCBydDsKCUhEQyBoZGMgPSBHZXREQyhod25kKTsKCglHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJcnQubGVmdCA9IHggLSBTUExJVF9XSURUSC8yOwoJcnQucmlnaHQgPSB4ICsgU1BMSVRfV0lEVEgvMisxOwoKCUludmVydFJlY3QoaGRjLCAmcnQpOwoKCVJlbGVhc2VEQyhod25kLCBoZGMpOwp9CgojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgpzdGF0aWMgdm9pZCBzZXRfaGVhZGVyKFBhbmUqIHBhbmUpCnsKCUhEX0lURU0gaXRlbTsKCWludCBzY3JvbGxfcG9zID0gR2V0U2Nyb2xsUG9zKHBhbmUtPmh3bmQsIFNCX0hPUlopOwoJaW50IGk9MCwgeD0wOwoKCWl0ZW0ubWFzayA9IEhESV9XSURUSDsKCWl0ZW0uY3h5ID0gMDsKCglmb3IoOyB4K3BhbmUtPndpZHRoc1tpXTxzY3JvbGxfcG9zICYmIGk8Q09MVU1OUzsgaSsrKSB7CgkJeCArPSBwYW5lLT53aWR0aHNbaV07CgkJSGVhZGVyX1NldEl0ZW0ocGFuZS0+aHduZEhlYWRlciwgaSwgJml0ZW0pOwoJfQoKCWlmIChpIDwgQ09MVU1OUykgewoJCXggKz0gcGFuZS0+d2lkdGhzW2ldOwoJCWl0ZW0uY3h5ID0geCAtIHNjcm9sbF9wb3M7CgkJSGVhZGVyX1NldEl0ZW0ocGFuZS0+aHduZEhlYWRlciwgaSsrLCAmaXRlbSk7CgoJCWZvcig7IGk8Q09MVU1OUzsgaSsrKSB7CgkJCWl0ZW0uY3h5ID0gcGFuZS0+d2lkdGhzW2ldOwoJCQl4ICs9IHBhbmUtPndpZHRoc1tpXTsKCQkJSGVhZGVyX1NldEl0ZW0ocGFuZS0+aHduZEhlYWRlciwgaSwgJml0ZW0pOwoJCX0KCX0KfQoKc3RhdGljIExSRVNVTFQgcGFuZV9ub3RpZnkoUGFuZSogcGFuZSwgTk1IRFIqIHBubWgpCnsKCXN3aXRjaChwbm1oLT5jb2RlKSB7CgkJY2FzZSBIRE5fVFJBQ0s6CgkJY2FzZSBIRE5fRU5EVFJBQ0s6IHsKCQkJSERfTk9USUZZKiBwaGRuID0gKEhEX05PVElGWSopIHBubWg7CgkJCWludCBpZHggPSBwaGRuLT5pSXRlbTsKCQkJaW50IGR4ID0gcGhkbi0+cGl0ZW0tPmN4eSAtIHBhbmUtPndpZHRoc1tpZHhdOwoJCQlpbnQgaTsKCgkJCVJFQ1QgY2xudDsKCQkJR2V0Q2xpZW50UmVjdChwYW5lLT5od25kLCAmY2xudCk7CgoJCQkvKiBtb3ZlIGltbWVkaWF0ZSB0byBzaW11bGF0ZSBIRFNfRlVMTERSQUcgKGZvciBub3cgWzA0LzIwMDBdIG5vdCByZWFsbHkgbmVlZGVkIHdpdGggV0lORUxJQikgKi8KCQkJSGVhZGVyX1NldEl0ZW0ocGFuZS0+aHduZEhlYWRlciwgaWR4LCBwaGRuLT5waXRlbSk7CgoJCQlwYW5lLT53aWR0aHNbaWR4XSArPSBkeDsKCgkJCWZvcihpPWlkeDsgKytpPD1DT0xVTU5TOyApCgkJCQlwYW5lLT5wb3NpdGlvbnNbaV0gKz0gZHg7CgoJCQl7CgkJCQlpbnQgc2Nyb2xsX3BvcyA9IEdldFNjcm9sbFBvcyhwYW5lLT5od25kLCBTQl9IT1JaKTsKCQkJCVJFQ1QgcnRfc2NyOwoJCQkJUkVDVCBydF9jbGlwOwoKCQkJCXJ0X3Njci5sZWZ0ICAgPSBwYW5lLT5wb3NpdGlvbnNbaWR4KzFdLXNjcm9sbF9wb3M7CgkJCQlydF9zY3IudG9wICAgID0gMDsKCQkJCXJ0X3Njci5yaWdodCAgPSBjbG50LnJpZ2h0OwoJCQkJcnRfc2NyLmJvdHRvbSA9IGNsbnQuYm90dG9tOwoKCQkJCXJ0X2NsaXAubGVmdCAgID0gcGFuZS0+cG9zaXRpb25zW2lkeF0tc2Nyb2xsX3BvczsKCQkJCXJ0X2NsaXAudG9wICAgID0gMDsKCQkJCXJ0X2NsaXAucmlnaHQgID0gY2xudC5yaWdodDsKCQkJCXJ0X2NsaXAuYm90dG9tID0gY2xudC5ib3R0b207CgoJCQkJaWYgKHJ0X3Njci5sZWZ0IDwgMCkgcnRfc2NyLmxlZnQgPSAwOwoJCQkJaWYgKHJ0X2NsaXAubGVmdCA8IDApIHJ0X2NsaXAubGVmdCA9IDA7CgoJCQkJU2Nyb2xsV2luZG93RXgocGFuZS0+aHduZCwgZHgsIDAsICZydF9zY3IsICZydF9jbGlwLCAwLCAwLCBTV19JTlZBTElEQVRFKTsKCgkJCQlydF9jbGlwLnJpZ2h0ID0gcGFuZS0+cG9zaXRpb25zW2lkeCsxXTsKCQkJCVJlZHJhd1dpbmRvdyhwYW5lLT5od25kLCAmcnRfY2xpcCwgMCwgUkRXX0lOVkFMSURBVEV8UkRXX1VQREFURU5PVyk7CgoJCQkJaWYgKHBubWgtPmNvZGUgPT0gSEROX0VORFRSQUNLKSB7CgkJCQkJTGlzdEJveF9TZXRIb3Jpem9udGFsRXh0ZW50KHBhbmUtPmh3bmQsIHBhbmUtPnBvc2l0aW9uc1tDT0xVTU5TXSk7CgoJCQkJCWlmIChHZXRTY3JvbGxQb3MocGFuZS0+aHduZCwgU0JfSE9SWikgIT0gc2Nyb2xsX3BvcykKCQkJCQkJc2V0X2hlYWRlcihwYW5lKTsKCQkJCX0KCQkJfQoKCQkJcmV0dXJuIEZBTFNFOwoJCX0KCgkJY2FzZSBIRE5fRElWSURFUkRCTENMSUNLOiB7CgkJCUhEX05PVElGWSogcGhkbiA9IChIRF9OT1RJRlkqKSBwbm1oOwoJCQlIRF9JVEVNIGl0ZW07CgoJCQljYWxjX3NpbmdsZV93aWR0aChwYW5lLCBwaGRuLT5pSXRlbSk7CgkJCWl0ZW0ubWFzayA9IEhESV9XSURUSDsKCQkJaXRlbS5jeHkgPSBwYW5lLT53aWR0aHNbcGhkbi0+aUl0ZW1dOwoKCQkJSGVhZGVyX1NldEl0ZW0ocGFuZS0+aHduZEhlYWRlciwgcGhkbi0+aUl0ZW0sICZpdGVtKTsKCQkJSW52YWxpZGF0ZVJlY3QocGFuZS0+aHduZCwgMCwgVFJVRSk7CgkJCWJyZWFrO30KCX0KCglyZXR1cm4gMDsKfQoKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoKc3RhdGljIHZvaWQgc2Nhbl9lbnRyeShDaGlsZFduZCogY2hpbGQsIEVudHJ5KiBlbnRyeSwgSFdORCBod25kKQp7CglUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCWludCBpZHggPSBMaXN0Qm94X0dldEN1clNlbChjaGlsZC0+bGVmdC5od25kKTsKCUhDVVJTT1Igb2xkX2N1cnNvciA9IFNldEN1cnNvcihMb2FkQ3Vyc29yKDAsIElEQ19XQUlUKSk7CgoJLyogZGVsZXRlIHN1YiBlbnRyaWVzIGluIGxlZnQgcGFuZSAqLwoJZm9yKDs7KSB7CgkJTFJFU1VMVCByZXMgPSBMaXN0Qm94X0dldEl0ZW1EYXRhKGNoaWxkLT5sZWZ0Lmh3bmQsIGlkeCsxKTsKCQlFbnRyeSogc3ViID0gKEVudHJ5KikgcmVzOwoKCQlpZiAocmVzPT1MQl9FUlIgfHwgIXN1YiB8fCBzdWItPmxldmVsPD1lbnRyeS0+bGV2ZWwpCgkJCWJyZWFrOwoKCQlMaXN0Qm94X0RlbGV0ZVN0cmluZyhjaGlsZC0+bGVmdC5od25kLCBpZHgrMSk7Cgl9CgoJLyogZW1wdHkgcmlnaHQgcGFuZSAqLwoJTGlzdEJveF9SZXNldENvbnRlbnQoY2hpbGQtPnJpZ2h0Lmh3bmQpOwoKCS8qIHJlbGVhc2UgbWVtb3J5ICovCglmcmVlX2VudHJpZXMoZW50cnkpOwoKCS8qIHJlYWQgY29udGVudHMgZnJvbSBkaXNrICovCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGVudHJ5LT5ldHlwZSA9PSBFVF9TSEVMTCkKCXsKCQlyZWFkX2RpcmVjdG9yeShlbnRyeSwgTlVMTCwgY2hpbGQtPnNvcnRPcmRlciwgaHduZCk7Cgl9CgllbHNlCiNlbmRpZgoJewoJCWdldF9wYXRoKGVudHJ5LCBwYXRoKTsKCQlyZWFkX2RpcmVjdG9yeShlbnRyeSwgcGF0aCwgY2hpbGQtPnNvcnRPcmRlciwgaHduZCk7Cgl9CgoJLyogaW5zZXJ0IGZvdW5kIGVudHJpZXMgaW4gcmlnaHQgcGFuZSAqLwoJaW5zZXJ0X2VudHJpZXMoJmNoaWxkLT5yaWdodCwgZW50cnktPmRvd24sIC0xKTsKCWNhbGNfd2lkdGhzKCZjaGlsZC0+cmlnaHQsIEZBTFNFKTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJc2V0X2hlYWRlcigmY2hpbGQtPnJpZ2h0KTsKI2VuZGlmCgoJY2hpbGQtPmhlYWRlcl93ZHRoc19vayA9IEZBTFNFOwoKCVNldEN1cnNvcihvbGRfY3Vyc29yKTsKfQoKCi8qIGV4cGFuZCBhIGRpcmVjdG9yeSBlbnRyeSAqLwoKc3RhdGljIEJPT0wgZXhwYW5kX2VudHJ5KENoaWxkV25kKiBjaGlsZCwgRW50cnkqIGRpcikKewoJaW50IGlkeDsKCUVudHJ5KiBwOwoKCWlmICghZGlyIHx8IGRpci0+ZXhwYW5kZWQgfHwgIWRpci0+ZG93bikKCQlyZXR1cm4gRkFMU0U7CgoJcCA9IGRpci0+ZG93bjsKCglpZiAocC0+ZGF0YS5jRmlsZU5hbWVbMF09PScuJyAmJiBwLT5kYXRhLmNGaWxlTmFtZVsxXT09J1wwJyAmJiBwLT5uZXh0KSB7CgkJcCA9IHAtPm5leHQ7CgoJCWlmIChwLT5kYXRhLmNGaWxlTmFtZVswXT09Jy4nICYmIHAtPmRhdGEuY0ZpbGVOYW1lWzFdPT0nLicgJiYKCQkJCXAtPmRhdGEuY0ZpbGVOYW1lWzJdPT0nXDAnICYmIHAtPm5leHQpCgkJCXAgPSBwLT5uZXh0OwoJfQoKCS8qIG5vIHN1YmRpcmVjdG9yaWVzID8gKi8KCWlmICghKHAtPmRhdGEuZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpKQoJCXJldHVybiBGQUxTRTsKCglpZHggPSBMaXN0Qm94X0ZpbmRJdGVtRGF0YShjaGlsZC0+bGVmdC5od25kLCAwLCBkaXIpOwoKCWRpci0+ZXhwYW5kZWQgPSBUUlVFOwoKCS8qIGluc2VydCBlbnRyaWVzIGluIGxlZnQgcGFuZSAqLwoJaW5zZXJ0X2VudHJpZXMoJmNoaWxkLT5sZWZ0LCBwLCBpZHgpOwoKCWlmICghY2hpbGQtPmhlYWRlcl93ZHRoc19vaykgewoJCWlmIChjYWxjX3dpZHRocygmY2hpbGQtPmxlZnQsIEZBTFNFKSkgewojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCXNldF9oZWFkZXIoJmNoaWxkLT5sZWZ0KTsKI2VuZGlmCgoJCQljaGlsZC0+aGVhZGVyX3dkdGhzX29rID0gVFJVRTsKCQl9Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCgpzdGF0aWMgdm9pZCBjb2xsYXBzZV9lbnRyeShQYW5lKiBwYW5lLCBFbnRyeSogZGlyKQp7CglpbnQgaWR4ID0gTGlzdEJveF9GaW5kSXRlbURhdGEocGFuZS0+aHduZCwgMCwgZGlyKTsKCglTaG93V2luZG93KHBhbmUtPmh3bmQsIFNXX0hJREUpOwoKCS8qIGhpZGUgc3ViIGVudHJpZXMgKi8KCWZvcig7OykgewoJCUxSRVNVTFQgcmVzID0gTGlzdEJveF9HZXRJdGVtRGF0YShwYW5lLT5od25kLCBpZHgrMSk7CgkJRW50cnkqIHN1YiA9IChFbnRyeSopIHJlczsKCgkJaWYgKHJlcz09TEJfRVJSIHx8ICFzdWIgfHwgc3ViLT5sZXZlbDw9ZGlyLT5sZXZlbCkKCQkJYnJlYWs7CgoJCUxpc3RCb3hfRGVsZXRlU3RyaW5nKHBhbmUtPmh3bmQsIGlkeCsxKTsKCX0KCglkaXItPmV4cGFuZGVkID0gRkFMU0U7CgoJU2hvd1dpbmRvdyhwYW5lLT5od25kLCBTV19TSE9XKTsKfQoKCnN0YXRpYyB2b2lkIHNldF9jdXJkaXIoQ2hpbGRXbmQqIGNoaWxkLCBFbnRyeSogZW50cnksIEhXTkQgaHduZCkKewoJVENIQVIgcGF0aFtNQVhfUEFUSF07CgoJcGF0aFswXSA9ICdcMCc7CgoJY2hpbGQtPmxlZnQuY3VyID0gZW50cnk7CgljaGlsZC0+cmlnaHQucm9vdCA9IGVudHJ5LT5kb3duPyBlbnRyeS0+ZG93bjogZW50cnk7CgljaGlsZC0+cmlnaHQuY3VyID0gZW50cnk7CgoJaWYgKCFlbnRyeS0+c2Nhbm5lZCkKCQlzY2FuX2VudHJ5KGNoaWxkLCBlbnRyeSwgaHduZCk7CgllbHNlIHsKCQlMaXN0Qm94X1Jlc2V0Q29udGVudChjaGlsZC0+cmlnaHQuaHduZCk7CgkJaW5zZXJ0X2VudHJpZXMoJmNoaWxkLT5yaWdodCwgZW50cnktPmRvd24sIC0xKTsKCQljYWxjX3dpZHRocygmY2hpbGQtPnJpZ2h0LCBGQUxTRSk7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQlzZXRfaGVhZGVyKCZjaGlsZC0+cmlnaHQpOwojZW5kaWYKCX0KCglnZXRfcGF0aChlbnRyeSwgcGF0aCk7Cglsc3RyY3B5KGNoaWxkLT5wYXRoLCBwYXRoKTsKCglpZiAoY2hpbGQtPmh3bmQpCS8qIG9ubHkgY2hhbmdlIHdpbmRvdyB0aXRsZSwgaWYgdGhlIHdpbmRvdyBhbHJlYWR5IGV4aXN0cyAqLwoJCVNldFdpbmRvd1RleHQoY2hpbGQtPmh3bmQsIHBhdGgpOwoKCWlmIChwYXRoWzBdKQoJCVNldEN1cnJlbnREaXJlY3RvcnkocGF0aCk7Cn0KCgpCT09MIGxhdW5jaF9maWxlKEhXTkQgaHduZCwgTFBDVFNUUiBjbWQsIFVJTlQgbkNtZFNob3cpCnsKCUhJTlNUQU5DRSBoaW5zdCA9IFNoZWxsRXhlY3V0ZShod25kLCBOVUxMLypvcGVyYXRpb24qLywgY21kLCBOVUxMLypwYXJhbWV0ZXJzKi8sIE5VTEwvKmRpciovLCBuQ21kU2hvdyk7CgoJaWYgKChpbnQpaGluc3QgPD0gMzIpIHsKCQlkaXNwbGF5X2Vycm9yKGh3bmQsIEdldExhc3RFcnJvcigpKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCiNpZmRlZiBVTklDT0RFCkJPT0wgbGF1bmNoX2ZpbGVBKEhXTkQgaHduZCwgTFBTVFIgY21kLCBVSU5UIG5DbWRTaG93KQp7CglISU5TVEFOQ0UgaGluc3QgPSBTaGVsbEV4ZWN1dGVBKGh3bmQsIE5VTEwvKm9wZXJhdGlvbiovLCBjbWQsIE5VTEwvKnBhcmFtZXRlcnMqLywgTlVMTC8qZGlyKi8sIG5DbWRTaG93KTsKCglpZiAoKGludCloaW5zdCA8PSAzMikgewoJCWRpc3BsYXlfZXJyb3IoaHduZCwgR2V0TGFzdEVycm9yKCkpOwoJCXJldHVybiBGQUxTRTsKCX0KCglyZXR1cm4gVFJVRTsKfQojZW5kaWYKCgpCT09MIGxhdW5jaF9lbnRyeShFbnRyeSogZW50cnksIEhXTkQgaHduZCwgVUlOVCBuQ21kU2hvdykKewoJVENIQVIgY21kW01BWF9QQVRIXTsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGVudHJ5LT5ldHlwZSA9PSBFVF9TSEVMTCkgewoJCUJPT0wgcmV0ID0gVFJVRTsKCgkJU0hFTExFWEVDVVRFSU5GTyBzaGV4aW5mbzsKCgkJc2hleGluZm8uY2JTaXplID0gc2l6ZW9mKFNIRUxMRVhFQ1VURUlORk8pOwoJCXNoZXhpbmZvLmZNYXNrID0gU0VFX01BU0tfSURMSVNUOwoJCXNoZXhpbmZvLmh3bmQgPSBod25kOwoJCXNoZXhpbmZvLmxwVmVyYiA9IE5VTEw7CgkJc2hleGluZm8ubHBGaWxlID0gTlVMTDsKCQlzaGV4aW5mby5scFBhcmFtZXRlcnMgPSBOVUxMOwoJCXNoZXhpbmZvLmxwRGlyZWN0b3J5ID0gTlVMTDsKCQlzaGV4aW5mby5uU2hvdyA9IG5DbWRTaG93OwoJCXNoZXhpbmZvLmxwSURMaXN0ID0gZ2V0X3RvX2Fic29sdXRlX3BpZGwoZW50cnksIGh3bmQpOwoKCQlpZiAoIVNoZWxsRXhlY3V0ZUV4KCZzaGV4aW5mbykpIHsKCQkJZGlzcGxheV9lcnJvcihod25kLCBHZXRMYXN0RXJyb3IoKSk7CgkJCXJldCA9IEZBTFNFOwoJCX0KCgkJaWYgKHNoZXhpbmZvLmxwSURMaXN0ICE9IGVudHJ5LT5waWRsKQoJCQkoKkdsb2JhbHMuaU1hbGxvYy0+bHBWdGJsLT5GcmVlKShHbG9iYWxzLmlNYWxsb2MsIHNoZXhpbmZvLmxwSURMaXN0KTsKCgkJcmV0dXJuIHJldDsKCX0KI2VuZGlmCgoJZ2V0X3BhdGgoZW50cnksIGNtZCk7CgoJIC8qIHN0YXJ0IHByb2dyYW0sIG9wZW4gZG9jdW1lbnQuLi4gKi8KCXJldHVybiBsYXVuY2hfZmlsZShod25kLCBjbWQsIG5DbWRTaG93KTsKfQoKCnN0YXRpYyB2b2lkIGFjdGl2YXRlX2VudHJ5KENoaWxkV25kKiBjaGlsZCwgUGFuZSogcGFuZSwgSFdORCBod25kKQp7CglFbnRyeSogZW50cnkgPSBwYW5lLT5jdXI7CgoJaWYgKCFlbnRyeSkKCQlyZXR1cm47CgoJaWYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQlpbnQgc2Nhbm5lZF9vbGQgPSBlbnRyeS0+c2Nhbm5lZDsKCgkJaWYgKCFzY2FubmVkX29sZCkKCQkJc2Nhbl9lbnRyeShjaGlsZCwgZW50cnksIGh3bmQpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWlmIChlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF09PScuJyAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMV09PSdcMCcpCgkJCXJldHVybjsKI2VuZGlmCgoJCWlmIChlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF09PScuJyAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMV09PScuJyAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMl09PSdcMCcpIHsKCQkJZW50cnkgPSBjaGlsZC0+bGVmdC5jdXItPnVwOwoJCQljb2xsYXBzZV9lbnRyeSgmY2hpbGQtPmxlZnQsIGVudHJ5KTsKCQkJZ290byBmb2N1c19lbnRyeTsKCQl9IGVsc2UgaWYgKGVudHJ5LT5leHBhbmRlZCkKCQkJY29sbGFwc2VfZW50cnkocGFuZSwgY2hpbGQtPmxlZnQuY3VyKTsKCQllbHNlIHsKCQkJZXhwYW5kX2VudHJ5KGNoaWxkLCBjaGlsZC0+bGVmdC5jdXIpOwoKCQkJaWYgKCFwYW5lLT50cmVlUGFuZSkgZm9jdXNfZW50cnk6IHsKCQkJCWludCBpZHggPSBMaXN0Qm94X0ZpbmRJdGVtRGF0YShjaGlsZC0+bGVmdC5od25kLCBMaXN0Qm94X0dldEN1clNlbChjaGlsZC0+bGVmdC5od25kKSwgZW50cnkpOwoJCQkJTGlzdEJveF9TZXRDdXJTZWwoY2hpbGQtPmxlZnQuaHduZCwgaWR4KTsKCQkJCXNldF9jdXJkaXIoY2hpbGQsIGVudHJ5LCBod25kKTsKCQkJfQoJCX0KCgkJaWYgKCFzY2FubmVkX29sZCkgewoJCQljYWxjX3dpZHRocyhwYW5lLCBGQUxTRSk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCXNldF9oZWFkZXIocGFuZSk7CiNlbmRpZgoJCX0KCX0gZWxzZSB7CgkJbGF1bmNoX2VudHJ5KGVudHJ5LCBjaGlsZC0+aHduZCwgU1dfU0hPV05PUk1BTCk7Cgl9Cn0KCgpzdGF0aWMgQk9PTCBwYW5lX2NvbW1hbmQoUGFuZSogcGFuZSwgVUlOVCBjbWQpCnsKCXN3aXRjaChjbWQpIHsKCQljYXNlIElEX1ZJRVdfTkFNRToKCQkJaWYgKHBhbmUtPnZpc2libGVfY29scykgewoJCQkJcGFuZS0+dmlzaWJsZV9jb2xzID0gMDsKCQkJCWNhbGNfd2lkdGhzKHBhbmUsIFRSVUUpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCQlzZXRfaGVhZGVyKHBhbmUpOwojZW5kaWYKCQkJCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19OQU1FLCBNRl9CWUNPTU1BTkR8TUZfQ0hFQ0tFRCk7CgkJCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX0FMTF9BVFRSSUJVVEVTLCBNRl9CWUNPTU1BTkQpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19TRUxFQ1RFRF9BVFRSSUJVVEVTLCBNRl9CWUNPTU1BTkQpOwoJCQl9CgkJCWJyZWFrOwoKCQljYXNlIElEX1ZJRVdfQUxMX0FUVFJJQlVURVM6CgkJCWlmIChwYW5lLT52aXNpYmxlX2NvbHMgIT0gQ09MX0FMTCkgewoJCQkJcGFuZS0+dmlzaWJsZV9jb2xzID0gQ09MX0FMTDsKCQkJCWNhbGNfd2lkdGhzKHBhbmUsIFRSVUUpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCQlzZXRfaGVhZGVyKHBhbmUpOwojZW5kaWYKCQkJCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19OQU1FLCBNRl9CWUNPTU1BTkQpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19BTExfQVRUUklCVVRFUywgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19TRUxFQ1RFRF9BVFRSSUJVVEVTLCBNRl9CWUNPTU1BTkQpOwoJCQl9CgkJCWJyZWFrOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgSURfUFJFRkVSRURfU0laRVM6IHsKCQkJY2FsY193aWR0aHMocGFuZSwgVFJVRSk7CgkJCXNldF9oZWFkZXIocGFuZSk7CgkJCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoJCQlicmVhazt9CiNlbmRpZgoKCQkgICAgICAgIC8qIFRPRE86IG1vcmUgY29tbWFuZCBpZHMuLi4gKi8KCgkJZGVmYXVsdDoKCQkJcmV0dXJuIEZBTFNFOwoJfQoKCXJldHVybiBUUlVFOwp9CgoKc3RhdGljIElDb250ZXh0TWVudTIqIHNfcGN0eG1lbnUyID0gTlVMTDsKc3RhdGljIElDb250ZXh0TWVudTMqIHNfcGN0eG1lbnUzID0gTlVMTDsKCnN0YXRpYyB2b2lkIEN0eE1lbnVfcmVzZXQoKQp7CglzX3BjdHhtZW51MiA9IE5VTEw7CglzX3BjdHhtZW51MyA9IE5VTEw7Cn0KCklDb250ZXh0TWVudSogQ3R4TWVudV9xdWVyeV9pbnRlcmZhY2VzKElDb250ZXh0TWVudSogcGNtMSkKewoJSUNvbnRleHRNZW51KiBwY20gPSBOVUxMOwoKCUN0eE1lbnVfcmVzZXQoKTsKCglpZiAoKCpwY20xLT5scFZ0YmwtPlF1ZXJ5SW50ZXJmYWNlKShwY20xLCAmSUlEX0lDb250ZXh0TWVudTMsICh2b2lkKiopJnBjbSkgPT0gTk9FUlJPUikKCQlzX3BjdHhtZW51MyA9IChMUENPTlRFWFRNRU5VMylwY207CgllbHNlIGlmICgoKnBjbTEtPmxwVnRibC0+UXVlcnlJbnRlcmZhY2UpKHBjbTEsICZJSURfSUNvbnRleHRNZW51MiwgKHZvaWQqKikmcGNtKSA9PSBOT0VSUk9SKQoJCXNfcGN0eG1lbnUyID0gKExQQ09OVEVYVE1FTlUyKXBjbTsKCglpZiAocGNtKSB7CgkJKCpwY20xLT5scFZ0YmwtPlJlbGVhc2UpKHBjbTEpOwoJCXJldHVybiBwY207Cgl9IGVsc2UKCQlyZXR1cm4gcGNtMTsKfQoKc3RhdGljIEJPT0wgQ3R4TWVudV9IYW5kbGVNZW51TXNnKFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJaWYgKHNfcGN0eG1lbnUzKSB7CgkJaWYgKFNVQ0NFRURFRCgoKnNfcGN0eG1lbnUzLT5scFZ0YmwtPkhhbmRsZU1lbnVNc2cpKHNfcGN0eG1lbnUzLCBubXNnLCB3cGFyYW0sIGxwYXJhbSkpKQoJCQlyZXR1cm4gVFJVRTsKCX0KCglpZiAoc19wY3R4bWVudTIpCgkJaWYgKFNVQ0NFRURFRCgoKnNfcGN0eG1lbnUyLT5scFZ0YmwtPkhhbmRsZU1lbnVNc2cpKHNfcGN0eG1lbnUyLCBubXNnLCB3cGFyYW0sIGxwYXJhbSkpKQoJCQlyZXR1cm4gVFJVRTsKCglyZXR1cm4gRkFMU0U7Cn0KCgpzdGF0aWMgSFJFU1VMVCBTaGVsbEZvbGRlckNvbnRleHRNZW51KElTaGVsbEZvbGRlciogc2hlbGxfZm9sZGVyLCBIV05EIGh3bmRQYXJlbnQsIGludCBjaWRsLCBMUENJVEVNSURMSVNUKiBhcGlkbCwgaW50IHgsIGludCB5KQp7CglJQ29udGV4dE1lbnUqIHBjbTsKCglIUkVTVUxUIGhyID0gKCpzaGVsbF9mb2xkZXItPmxwVnRibC0+R2V0VUlPYmplY3RPZikoc2hlbGxfZm9sZGVyLCBod25kUGFyZW50LCBjaWRsLCBhcGlkbCwgJklJRF9JQ29udGV4dE1lbnUsIE5VTEwsIChMUFZPSUQqKSZwY20pOwovKglIUkVTVUxUIGhyID0gQ0RlZkZvbGRlck1lbnVfQ3JlYXRlMihkaXI/ZGlyLT5fcGlkbDpEZXNrdG9wRm9sZGVyKCksIGh3bmRQYXJlbnQsIDEsICZwaWRsLCBzaGVsbF9mb2xkZXIsIE5VTEwsIDAsIE5VTEwsICZwY20pOyAqLwoKCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJSE1FTlUgaG1lbnUgPSBDcmVhdGVQb3B1cE1lbnUoKTsKCgkJcGNtID0gQ3R4TWVudV9xdWVyeV9pbnRlcmZhY2VzKHBjbSk7CgoJCWlmIChobWVudSkgewoJCQlociA9ICgqcGNtLT5scFZ0YmwtPlF1ZXJ5Q29udGV4dE1lbnUpKHBjbSwgaG1lbnUsIDAsIEZDSURNX1NIVklFV0ZJUlNULCBGQ0lETV9TSFZJRVdMQVNULCBDTUZfTk9STUFMKTsKCgkJCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJCQlVSU5UIGlkQ21kID0gVHJhY2tQb3B1cE1lbnUoaG1lbnUsIFRQTV9MRUZUQUxJR058VFBNX1JFVFVSTkNNRHxUUE1fUklHSFRCVVRUT04sIHgsIHksIDAsIGh3bmRQYXJlbnQsIE5VTEwpOwoKCQkJCUN0eE1lbnVfcmVzZXQoKTsKCgkJCQlpZiAoaWRDbWQpIHsKCQkJCSAgQ01JTlZPS0VDT01NQU5ESU5GTyBjbWk7CgoJCQkJICBjbWkuY2JTaXplID0gc2l6ZW9mKENNSU5WT0tFQ09NTUFORElORk8pOwoJCQkJICBjbWkuZk1hc2sgPSAwOwoJCQkJICBjbWkuaHduZCA9IGh3bmRQYXJlbnQ7CgkJCQkgIGNtaS5scFZlcmIgPSAoTFBDU1RSKShJTlRfUFRSKShpZENtZCAtIEZDSURNX1NIVklFV0ZJUlNUKTsKCQkJCSAgY21pLmxwUGFyYW1ldGVycyA9IE5VTEw7CgkJCQkgIGNtaS5scERpcmVjdG9yeSA9IE5VTEw7CgkJCQkgIGNtaS5uU2hvdyA9IFNXX1NIT1dOT1JNQUw7CgkJCQkgIGNtaS5kd0hvdEtleSA9IDA7CgkJCQkgIGNtaS5oSWNvbiA9IDA7CgoJCQkJICBociA9ICgqcGNtLT5scFZ0YmwtPkludm9rZUNvbW1hbmQpKHBjbSwgJmNtaSk7CgkJCQl9CgkJCX0KCQl9CgoJCSgqcGNtLT5scFZ0YmwtPlJlbGVhc2UpKHBjbSk7Cgl9CgoJcmV0dXJuIGhyOwp9CgoKTFJFU1VMVCBDQUxMQkFDSyBDaGlsZFduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCXN0YXRpYyBpbnQgbGFzdF9zcGxpdDsKCglDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nKGh3bmQsIEdXTF9VU0VSREFUQSk7CglBU1NFUlQoY2hpbGQpOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9EUkFXSVRFTTogewoJCQlMUERSQVdJVEVNU1RSVUNUIGRpcyA9IChMUERSQVdJVEVNU1RSVUNUKWxwYXJhbTsKCQkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgZGlzLT5pdGVtRGF0YTsKCgkJCWlmIChkaXMtPkN0bElEID09IElEV19UUkVFX0xFRlQpCgkJCQlkcmF3X2l0ZW0oJmNoaWxkLT5sZWZ0LCBkaXMsIGVudHJ5LCAtMSk7CgkJCWVsc2UgaWYgKGRpcy0+Q3RsSUQgPT0gSURXX1RSRUVfUklHSFQpCgkJCQlkcmF3X2l0ZW0oJmNoaWxkLT5yaWdodCwgZGlzLCBlbnRyeSwgLTEpOwoJCQllbHNlCgkJCQlnb3RvIGRyYXdfbWVudV9pdGVtOwoKCQkJcmV0dXJuIFRSVUU7fQoKCQljYXNlIFdNX0NSRUFURToKCQkJSW5pdENoaWxkV2luZG93KGNoaWxkKTsKCQkJYnJlYWs7CgoJCWNhc2UgV01fTkNERVNUUk9ZOgoJCQlmcmVlX2NoaWxkX3dpbmRvdyhjaGlsZCk7CgkJCVNldFdpbmRvd0xvbmcoaHduZCwgR1dMX1VTRVJEQVRBLCAwKTsKCQkJYnJlYWs7CgoJCWNhc2UgV01fUEFJTlQ6IHsKCQkJUEFJTlRTVFJVQ1QgcHM7CgkJCUhCUlVTSCBsYXN0QnJ1c2g7CgkJCVJFQ1QgcnQ7CgkJCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCQkJQmVnaW5QYWludChod25kLCAmcHMpOwoJCQlydC5sZWZ0ID0gY2hpbGQtPnNwbGl0X3Bvcy1TUExJVF9XSURUSC8yOwoJCQlydC5yaWdodCA9IGNoaWxkLT5zcGxpdF9wb3MrU1BMSVRfV0lEVEgvMisxOwoJCQlsYXN0QnJ1c2ggPSBTZWxlY3RCcnVzaChwcy5oZGMsIChIQlJVU0gpR2V0U3RvY2tPYmplY3QoQ09MT1JfU1BMSVRCQVIpKTsKCQkJUmVjdGFuZ2xlKHBzLmhkYywgcnQubGVmdCwgcnQudG9wLTEsIHJ0LnJpZ2h0LCBydC5ib3R0b20rMSk7CgkJCVNlbGVjdE9iamVjdChwcy5oZGMsIGxhc3RCcnVzaCk7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQlydC50b3AgPSBydC5ib3R0b20gLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7CgkJCUZpbGxSZWN0KHBzLmhkYywgJnJ0LCBHZXRTdG9ja09iamVjdChCTEFDS19CUlVTSCkpOwojZW5kaWYKCQkJRW5kUGFpbnQoaHduZCwgJnBzKTsKCQkJYnJlYWs7fQoKCQljYXNlIFdNX1NFVENVUlNPUjoKCQkJaWYgKExPV09SRChscGFyYW0pID09IEhUQ0xJRU5UKSB7CgkJCQlQT0lOVCBwdDsKCQkJCUdldEN1cnNvclBvcygmcHQpOwoJCQkJU2NyZWVuVG9DbGllbnQoaHduZCwgJnB0KTsKCgkJCQlpZiAocHQueD49Y2hpbGQtPnNwbGl0X3Bvcy1TUExJVF9XSURUSC8yICYmIHB0Lng8Y2hpbGQtPnNwbGl0X3BvcytTUExJVF9XSURUSC8yKzEpIHsKCQkJCQlTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfU0laRVdFKSk7CgkJCQkJcmV0dXJuIFRSVUU7CgkJCQl9CgkJCX0KCQkJZ290byBkZWY7CgoJCWNhc2UgV01fTEJVVFRPTkRPV046IHsKCQkJUkVDVCBydDsKCQkJaW50IHggPSBHRVRfWF9MUEFSQU0obHBhcmFtKTsKCgkJCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCgkJCWlmICh4Pj1jaGlsZC0+c3BsaXRfcG9zLVNQTElUX1dJRFRILzIgJiYgeDxjaGlsZC0+c3BsaXRfcG9zK1NQTElUX1dJRFRILzIrMSkgewoJCQkJbGFzdF9zcGxpdCA9IGNoaWxkLT5zcGxpdF9wb3M7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJZHJhd19zcGxpdGJhcihod25kLCBsYXN0X3NwbGl0KTsKI2VuZGlmCgkJCQlTZXRDYXB0dXJlKGh3bmQpOwoJCQl9CgoJCQlicmVhazt9CgoJCWNhc2UgV01fTEJVVFRPTlVQOgoJCQlpZiAoR2V0Q2FwdHVyZSgpID09IGh3bmQpIHsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQlSRUNUIHJ0OwoJCQkJaW50IHggPSBMT1dPUkQobHBhcmFtKTsKCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CgkJCQlsYXN0X3NwbGl0ID0gLTE7CgkJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgkJCQljaGlsZC0+c3BsaXRfcG9zID0geDsKCQkJCXJlc2l6ZV90cmVlKGNoaWxkLCBydC5yaWdodCwgcnQuYm90dG9tKTsKI2VuZGlmCgkJCQlSZWxlYXNlQ2FwdHVyZSgpOwoJCQl9CgkJCWJyZWFrOwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJY2FzZSBXTV9DQVBUVVJFQ0hBTkdFRDoKCQkJaWYgKEdldENhcHR1cmUoKT09aHduZCAmJiBsYXN0X3NwbGl0Pj0wKQoJCQkJZHJhd19zcGxpdGJhcihod25kLCBsYXN0X3NwbGl0KTsKCQkJYnJlYWs7CiNlbmRpZgoKCQljYXNlIFdNX0tFWURPV046CgkJCWlmICh3cGFyYW0gPT0gVktfRVNDQVBFKQoJCQkJaWYgKEdldENhcHR1cmUoKSA9PSBod25kKSB7CgkJCQkJUkVDVCBydDsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQkJZHJhd19zcGxpdGJhcihod25kLCBsYXN0X3NwbGl0KTsKI2Vsc2UKCQkJCQljaGlsZC0+c3BsaXRfcG9zID0gbGFzdF9zcGxpdDsKI2VuZGlmCgkJCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoJCQkJCXJlc2l6ZV90cmVlKGNoaWxkLCBydC5yaWdodCwgcnQuYm90dG9tKTsKCQkJCQlsYXN0X3NwbGl0ID0gLTE7CgkJCQkJUmVsZWFzZUNhcHR1cmUoKTsKCQkJCQlTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfQVJST1cpKTsKCQkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgV01fTU9VU0VNT1ZFOgoJCQlpZiAoR2V0Q2FwdHVyZSgpID09IGh3bmQpIHsKCQkJCVJFQ1QgcnQ7CgkJCQlpbnQgeCA9IExPV09SRChscGFyYW0pOwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQlIREMgaGRjID0gR2V0REMoaHduZCk7CgkJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJCQkJcnQubGVmdCA9IGxhc3Rfc3BsaXQtU1BMSVRfV0lEVEgvMjsKCQkJCXJ0LnJpZ2h0ID0gbGFzdF9zcGxpdCtTUExJVF9XSURUSC8yKzE7CgkJCQlJbnZlcnRSZWN0KGhkYywgJnJ0KTsKCgkJCQlsYXN0X3NwbGl0ID0geDsKCQkJCXJ0LmxlZnQgPSB4LVNQTElUX1dJRFRILzI7CgkJCQlydC5yaWdodCA9IHgrU1BMSVRfV0lEVEgvMisxOwoJCQkJSW52ZXJ0UmVjdChoZGMsICZydCk7CgoJCQkJUmVsZWFzZURDKGh3bmQsIGhkYyk7CiNlbHNlCgkJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJCQkJaWYgKHg+PTAgJiYgeDxydC5yaWdodCkgewoJCQkJCWNoaWxkLT5zcGxpdF9wb3MgPSB4OwoJCQkJCXJlc2l6ZV90cmVlKGNoaWxkLCBydC5yaWdodCwgcnQuYm90dG9tKTsKCQkJCQlydC5sZWZ0ID0geC1TUExJVF9XSURUSC8yOwoJCQkJCXJ0LnJpZ2h0ID0geCtTUExJVF9XSURUSC8yKzE7CgkJCQkJSW52YWxpZGF0ZVJlY3QoaHduZCwgJnJ0LCBGQUxTRSk7CgkJCQkJVXBkYXRlV2luZG93KGNoaWxkLT5sZWZ0Lmh3bmQpOwoJCQkJCVVwZGF0ZVdpbmRvdyhod25kKTsKCQkJCQlVcGRhdGVXaW5kb3coY2hpbGQtPnJpZ2h0Lmh3bmQpOwoJCQkJfQojZW5kaWYKCQkJfQoJCQlicmVhazsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQljYXNlIFdNX0dFVE1JTk1BWElORk86CgkJCURlZk1ESUNoaWxkUHJvYyhod25kLCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7CgoJCQl7TFBNSU5NQVhJTkZPIGxwbW1pID0gKExQTUlOTUFYSU5GTylscGFyYW07CgoJCQlscG1taS0+cHRNYXhUcmFja1NpemUueCA8PD0gMTsvKjIqR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTikgLyBTTV9DWFZJUlRVQUxTQ1JFRU4gKi8KCQkJbHBtbWktPnB0TWF4VHJhY2tTaXplLnkgPDw9IDE7LyoyKkdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pIC8gU01fQ1lWSVJUVUFMU0NSRUVOICovCgkJCWJyZWFrO30KI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJCWNhc2UgV01fU0VURk9DVVM6CgkJCVNldEN1cnJlbnREaXJlY3RvcnkoY2hpbGQtPnBhdGgpOwoJCQlTZXRGb2N1cyhjaGlsZC0+Zm9jdXNfcGFuZT8gY2hpbGQtPnJpZ2h0Lmh3bmQ6IGNoaWxkLT5sZWZ0Lmh3bmQpOwoJCQlicmVhazsKCgkJY2FzZSBXTV9ESVNQQVRDSF9DT01NQU5EOiB7CgkJCVBhbmUqIHBhbmUgPSBHZXRGb2N1cygpPT1jaGlsZC0+bGVmdC5od25kPyAmY2hpbGQtPmxlZnQ6ICZjaGlsZC0+cmlnaHQ7CgoJCQlzd2l0Y2goTE9XT1JEKHdwYXJhbSkpIHsKCQkJCWNhc2UgSURfV0lORE9XX05FVzogewoJCQkJCUNoaWxkV25kKiBuZXdfY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3coY2hpbGQtPnBhdGgsIE5VTEwsIGh3bmQpOwoKCQkJCQlpZiAoIWNyZWF0ZV9jaGlsZF93aW5kb3cobmV3X2NoaWxkKSkKCQkJCQkJZnJlZShuZXdfY2hpbGQpOwoKCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9SRUZSRVNIOgoJCQkJCXNjYW5fZW50cnkoY2hpbGQsIHBhbmUtPmN1ciwgaHduZCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9BQ1RJVkFURToKCQkJCQlhY3RpdmF0ZV9lbnRyeShjaGlsZCwgcGFuZSwgaHduZCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9GSUxFX01PVkU6IHsKCQkJCQlUQ0hBUiBuZXdfbmFtZVtCVUZGRVJfTEVOXSwgb2xkX25hbWVbQlVGRkVSX0xFTl07CgkJCQkJaW50IGxlbjsKCgkJCQkJaW50IHJldCA9IERpYWxvZ0JveFBhcmFtKEdsb2JhbHMuaEluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSUREX1NFTEVDVF9ERVNUSU5BVElPTiksIGh3bmQsIERlc3RpbmF0aW9uRGxnUHJvYywgKExQQVJBTSluZXdfbmFtZSk7CgkJCQkJaWYgKHJldCAhPSBJRE9LKQoJCQkJCQlicmVhazsKCgkJCQkJaWYgKG5ld19uYW1lWzBdIT0nLycgJiYgbmV3X25hbWVbMV0hPSc6JykgewoJCQkJCQlnZXRfcGF0aChwYW5lLT5jdXItPnVwLCBvbGRfbmFtZSk7CgkJCQkJCWxlbiA9IGxzdHJsZW4ob2xkX25hbWUpOwoKCQkJCQkJaWYgKG9sZF9uYW1lW2xlbi0xXSE9J1xcJyAmJiBvbGRfbmFtZVtsZW4tMV0hPScvJykgewoJCQkJCQkJb2xkX25hbWVbbGVuKytdID0gJy8nOwoJCQkJCQkJb2xkX25hbWVbbGVuXSA9ICdcbic7CgkJCQkJCX0KCgkJCQkJCWxzdHJjcHkoJm9sZF9uYW1lW2xlbl0sIG5ld19uYW1lKTsKCQkJCQkJbHN0cmNweShuZXdfbmFtZSwgb2xkX25hbWUpOwoJCQkJCX0KCgkJCQkJZ2V0X3BhdGgocGFuZS0+Y3VyLCBvbGRfbmFtZSk7CgoJCQkJCWlmIChNb3ZlRmlsZUV4KG9sZF9uYW1lLCBuZXdfbmFtZSwgTU9WRUZJTEVfQ09QWV9BTExPV0VEKSkgewoJCQkJCQlpZiAocGFuZS0+dHJlZVBhbmUpIHsKCQkJCQkJCXBhbmUtPnJvb3QtPnNjYW5uZWQgPSBGQUxTRTsKCQkJCQkJCXBhbmUtPmN1ciA9IHBhbmUtPnJvb3Q7CgkJCQkJCQlhY3RpdmF0ZV9lbnRyeShjaGlsZCwgcGFuZSwgaHduZCk7CgkJCQkJCX0KCQkJCQkJZWxzZQoJCQkJCQkJc2Nhbl9lbnRyeShjaGlsZCwgcGFuZS0+cm9vdCwgaHduZCk7CgkJCQkJfQoJCQkJCWVsc2UKCQkJCQkJZGlzcGxheV9lcnJvcihod25kLCBHZXRMYXN0RXJyb3IoKSk7CgkJCQkJYnJlYWs7fQoKCQkJCWRlZmF1bHQ6CgkJCQkJcmV0dXJuIHBhbmVfY29tbWFuZChwYW5lLCBMT1dPUkQod3BhcmFtKSk7CgkJCX0KCgkJCXJldHVybiBUUlVFO30KCgkJY2FzZSBXTV9DT01NQU5EOiB7CgkJCVBhbmUqIHBhbmUgPSBHZXRGb2N1cygpPT1jaGlsZC0+bGVmdC5od25kPyAmY2hpbGQtPmxlZnQ6ICZjaGlsZC0+cmlnaHQ7CgoJCQlzd2l0Y2goSElXT1JEKHdwYXJhbSkpIHsKCQkJCWNhc2UgTEJOX1NFTENIQU5HRTogewoJCQkJCWludCBpZHggPSBMaXN0Qm94X0dldEN1clNlbChwYW5lLT5od25kKTsKCQkJCQlFbnRyeSogZW50cnkgPSAoRW50cnkqKSBMaXN0Qm94X0dldEl0ZW1EYXRhKHBhbmUtPmh3bmQsIGlkeCk7CgoJCQkJCWlmIChwYW5lID09ICZjaGlsZC0+bGVmdCkKCQkJCQkJc2V0X2N1cmRpcihjaGlsZCwgZW50cnksIGh3bmQpOwoJCQkJCWVsc2UKCQkJCQkJcGFuZS0+Y3VyID0gZW50cnk7CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgTEJOX0RCTENMSzoKCQkJCQlhY3RpdmF0ZV9lbnRyeShjaGlsZCwgcGFuZSwgaHduZCk7CgkJCQkJYnJlYWs7CgkJCX0KCQkJYnJlYWs7fQoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fTk9USUZZOiB7CgkJCU5NSERSKiBwbm1oID0gKE5NSERSKikgbHBhcmFtOwoJCQlyZXR1cm4gcGFuZV9ub3RpZnkocG5taC0+aWRGcm9tPT1JRFdfSEVBREVSX0xFRlQ/ICZjaGlsZC0+bGVmdDogJmNoaWxkLT5yaWdodCwgcG5taCk7fQojZW5kaWYKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJCWNhc2UgV01fQ09OVEVYVE1FTlU6IHsKCQkJUGFuZSogcGFuZTsKCQkJaW50IGlkeDsKCgkJCSAvKiBmaXJzdCBzZWxlY3QgdGhlIGN1cnJlbnQgaXRlbSBpbiB0aGUgbGlzdGJveCAqLwoJCQlIV05EIGhwYW5lbCA9IChIV05EKSB3cGFyYW07CgkJCVBPSU5UIHB0OwoJCQlwdC54ID0gKHNob3J0KUxPV09SRChscGFyYW0pOwoJCQlwdC55ID0gKHNob3J0KUhJV09SRChscGFyYW0pOwoJCQlTY3JlZW5Ub0NsaWVudChocGFuZWwsICZwdCk7CgkJCVNlbmRNZXNzYWdlKGhwYW5lbCwgV01fTEJVVFRPTkRPV04sIDAsIE1BS0VMT05HKHB0LngsIHB0LnkpKTsKCQkJU2VuZE1lc3NhZ2UoaHBhbmVsLCBXTV9MQlVUVE9OVVAsIDAsIE1BS0VMT05HKHB0LngsIHB0LnkpKTsKCgkJCSAvKiBub3cgY3JlYXRlIHRoZSBwb3B1cCBtZW51IHVzaW5nIHNoZWxsIG5hbWVzcGFjZSBhbmQgSUNvbnRleHRNZW51ICovCgkJCXBhbmUgPSBHZXRGb2N1cygpPT1jaGlsZC0+bGVmdC5od25kPyAmY2hpbGQtPmxlZnQ6ICZjaGlsZC0+cmlnaHQ7CgkJCWlkeCA9IExpc3RCb3hfR2V0Q3VyU2VsKHBhbmUtPmh3bmQpOwoKCQkJaWYgKGlkeCAhPSAtMSkgewoJCQkJSFJFU1VMVCBocjsKCQkJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIExpc3RCb3hfR2V0SXRlbURhdGEocGFuZS0+aHduZCwgaWR4KTsKCgkJCQlMUElURU1JRExJU1QgcGlkbF9hYnMgPSBnZXRfdG9fYWJzb2x1dGVfcGlkbChlbnRyeSwgaHduZCk7CgoJCQkJaWYgKHBpZGxfYWJzKSB7CgkJCQkJSVNoZWxsRm9sZGVyKiBwYXJlbnRGb2xkZXI7CgkJCQkJTFBDSVRFTUlETElTVCBwaWRsTGFzdDsKCgkJCQkJIC8qIGdldCBhbmQgdXNlIHRoZSBwYXJlbnQgZm9sZGVyIHRvIGRpc3BsYXkgY29ycmVjdCBjb250ZXh0IG1lbnUgaW4gYWxsIGNhc2VzICovCgkJCQkJaWYgKFNVQ0NFRURFRChTSEJpbmRUb1BhcmVudChwaWRsX2FicywgJklJRF9JU2hlbGxGb2xkZXIsIChMUFZPSUQqKSZwYXJlbnRGb2xkZXIsICZwaWRsTGFzdCkpKSB7CgkJCQkJCWhyID0gU2hlbGxGb2xkZXJDb250ZXh0TWVudShwYXJlbnRGb2xkZXIsIGh3bmQsIDEsICZwaWRsTGFzdCwgcHQueCwgcHQueSk7CgoJCQkJCQkoKnBhcmVudEZvbGRlci0+bHBWdGJsLT5SZWxlYXNlKShwYXJlbnRGb2xkZXIpOwoJCQkJCX0KCgkJCQkJKCpHbG9iYWxzLmlNYWxsb2MtPmxwVnRibC0+RnJlZSkoR2xvYmFscy5pTWFsbG9jLCBwaWRsX2Ficyk7CgkJCQl9CgkJCX0KCQkJYnJlYWs7fQojZW5kaWYKCgkJICBjYXNlIFdNX01FQVNVUkVJVEVNOgoJCSAgZHJhd19tZW51X2l0ZW06CgkJCWlmICghd3BhcmFtKQkvKiBJcyB0aGUgbWVzc2FnZSBtZW51LXJlbGF0ZWQ/ICovCgkJCQlpZiAoQ3R4TWVudV9IYW5kbGVNZW51TXNnKG5tc2csIHdwYXJhbSwgbHBhcmFtKSkKCQkJCQlyZXR1cm4gVFJVRTsKCgkJCWJyZWFrOwoKCQkgIGNhc2UgV01fSU5JVE1FTlVQT1BVUDoKCQkJaWYgKEN0eE1lbnVfSGFuZGxlTWVudU1zZyhubXNnLCB3cGFyYW0sIGxwYXJhbSkpCgkJCQlyZXR1cm4gMDsKCgkJCWJyZWFrOwoKCQkgIGNhc2UgV01fTUVOVUNIQVI6CS8qIG9ubHkgc3VwcG9ydGVkIGJ5IElDb250ZXh0TWVudTMgKi8KCQkgICBpZiAoc19wY3R4bWVudTMpIHsKCQkJICAgTFJFU1VMVCBsUmVzdWx0ID0gMDsKCgkJCSAgICgqc19wY3R4bWVudTMtPmxwVnRibC0+SGFuZGxlTWVudU1zZzIpKHNfcGN0eG1lbnUzLCBubXNnLCB3cGFyYW0sIGxwYXJhbSwgJmxSZXN1bHQpOwoKCQkJICAgcmV0dXJuIGxSZXN1bHQ7CgkJICAgfQoKCQkgICBicmVhazsKCgkJY2FzZSBXTV9TSVpFOgoJCQlpZiAod3BhcmFtICE9IFNJWkVfTUlOSU1JWkVEKQoJCQkJcmVzaXplX3RyZWUoY2hpbGQsIExPV09SRChscGFyYW0pLCBISVdPUkQobHBhcmFtKSk7CgkJCS8qIGZhbGwgdGhyb3VnaCAqLwoKCQlkZWZhdWx0OiBkZWY6CgkJCXJldHVybiBEZWZNRElDaGlsZFByb2MoaHduZCwgbm1zZywgd3BhcmFtLCBscGFyYW0pOwoJfQoKCXJldHVybiAwOwp9CgoKTFJFU1VMVCBDQUxMQkFDSyBUcmVlV25kUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJQ2hpbGRXbmQqIGNoaWxkID0gKENoaWxkV25kKikgR2V0V2luZG93TG9uZyhHZXRQYXJlbnQoaHduZCksIEdXTF9VU0VSREFUQSk7CglQYW5lKiBwYW5lID0gKFBhbmUqKSBHZXRXaW5kb3dMb25nKGh3bmQsIEdXTF9VU0VSREFUQSk7CglBU1NFUlQoY2hpbGQpOwoKCXN3aXRjaChubXNnKSB7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQljYXNlIFdNX0hTQ1JPTEw6CgkJCXNldF9oZWFkZXIocGFuZSk7CgkJCWJyZWFrOwojZW5kaWYKCgkJY2FzZSBXTV9TRVRGT0NVUzoKCQkJY2hpbGQtPmZvY3VzX3BhbmUgPSBwYW5lPT0mY2hpbGQtPnJpZ2h0PyAxOiAwOwoJCQlMaXN0Qm94X1NldFNlbChod25kLCBUUlVFLCAxKTsKCQkJLypUT0RPOiBjaGVjayBtZW51IGl0ZW1zICovCgkJCWJyZWFrOwoKCQljYXNlIFdNX0tFWURPV046CgkJCWlmICh3cGFyYW0gPT0gVktfVEFCKSB7CgkJCQkvKlRPRE86IFNldEZvY3VzKEdsb2JhbHMuaGRyaXZlYmFyKSAqLwoJCQkJU2V0Rm9jdXMoY2hpbGQtPmZvY3VzX3BhbmU/IGNoaWxkLT5sZWZ0Lmh3bmQ6IGNoaWxkLT5yaWdodC5od25kKTsKCQkJfQoJfQoKCXJldHVybiBDYWxsV2luZG93UHJvYyhnX29yZ1RyZWVXbmRQcm9jLCBod25kLCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7Cn0KCgpzdGF0aWMgdm9pZCBJbml0SW5zdGFuY2UoSElOU1RBTkNFIGhpbnN0YW5jZSkKewoJY29uc3Qgc3RhdGljIFRDSEFSIHNGb250W10gPSB7J00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJyAnLCdTJywnYScsJ24nLCdzJywnICcsJ1MnLCdlJywncicsJ2knLCdmJywnXDAnfTsKCglXTkRDTEFTU0VYIHdjRnJhbWU7CglXTkRDTEFTUyB3Y0NoaWxkOwoJQVRPTSBoQ2hpbGRDbGFzczsKCWludCBjb2w7CgoJSU5JVENPTU1PTkNPTlRST0xTRVggaWNjID0gewoJCXNpemVvZihJTklUQ09NTU9OQ09OVFJPTFNFWCksCgkJSUNDX0JBUl9DTEFTU0VTCgl9OwoKCUhEQyBoZGMgPSBHZXREQygwKTsKCglzZXRsb2NhbGUoTENfQ09MTEFURSwgIiIpOwkvKiBzZXQgY29sbGF0aW5nIHJ1bGVzIHRvIGxvY2FsIHNldHRpbmdzIGZvciBjb21wYXJlTmFtZSAqLwoKCUluaXRDb21tb25Db250cm9sc0V4KCZpY2MpOwoKCgkvKiByZWdpc3RlciBmcmFtZSB3aW5kb3cgY2xhc3MgKi8KCgl3Y0ZyYW1lLmNiU2l6ZSAgICAgICAgPSBzaXplb2YoV05EQ0xBU1NFWCk7Cgl3Y0ZyYW1lLnN0eWxlICAgICAgICAgPSAwOwoJd2NGcmFtZS5scGZuV25kUHJvYyAgID0gRnJhbWVXbmRQcm9jOwoJd2NGcmFtZS5jYkNsc0V4dHJhICAgID0gMDsKCXdjRnJhbWUuY2JXbmRFeHRyYSAgICA9IDA7Cgl3Y0ZyYW1lLmhJbnN0YW5jZSAgICAgPSBoaW5zdGFuY2U7Cgl3Y0ZyYW1lLmhJY29uICAgICAgICAgPSBMb2FkSWNvbihoaW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRElfV0lORUZJTEUpKTsKCXdjRnJhbWUuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3IoMCwgSURDX0FSUk9XKTsKCXdjRnJhbWUuaGJyQmFja2dyb3VuZCA9IDA7Cgl3Y0ZyYW1lLmxwc3pNZW51TmFtZSAgPSAwOwoJd2NGcmFtZS5scHN6Q2xhc3NOYW1lID0gc1dJTkVGSUxFRlJBTUU7Cgl3Y0ZyYW1lLmhJY29uU20gICAgICAgPSAoSElDT04pTG9hZEltYWdlKGhpbnN0YW5jZSwKCQkJCQkJCQkJCQkgTUFLRUlOVFJFU09VUkNFKElESV9XSU5FRklMRSksCgkJCQkJCQkJCQkJIElNQUdFX0lDT04sCgkJCQkJCQkJCQkJIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTTUlDT04pLAoJCQkJCQkJCQkJCSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01JQ09OKSwKCQkJCQkJCQkJCQkgTFJfU0hBUkVEKTsKCglHbG9iYWxzLmhmcmFtZUNsYXNzID0gUmVnaXN0ZXJDbGFzc0V4KCZ3Y0ZyYW1lKTsKCgoJLyogcmVnaXN0ZXIgdHJlZSB3aW5kb3dzIGNsYXNzICovCgoJd2NDaGlsZC5zdHlsZSAgICAgICAgID0gQ1NfQ0xBU1NEQ3xDU19EQkxDTEtTfENTX1ZSRURSQVc7Cgl3Y0NoaWxkLmxwZm5XbmRQcm9jICAgPSBDaGlsZFduZFByb2M7Cgl3Y0NoaWxkLmNiQ2xzRXh0cmEgICAgPSAwOwoJd2NDaGlsZC5jYlduZEV4dHJhICAgID0gMDsKCXdjQ2hpbGQuaEluc3RhbmNlICAgICA9IGhpbnN0YW5jZTsKCXdjQ2hpbGQuaEljb24gICAgICAgICA9IDA7Cgl3Y0NoaWxkLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yKDAsIElEQ19BUlJPVyk7Cgl3Y0NoaWxkLmhickJhY2tncm91bmQgPSAwOwoJd2NDaGlsZC5scHN6TWVudU5hbWUgID0gMDsKCXdjQ2hpbGQubHBzekNsYXNzTmFtZSA9IHNXSU5FRklMRVRSRUU7CgoJaENoaWxkQ2xhc3MgPSBSZWdpc3RlckNsYXNzKCZ3Y0NoaWxkKTsKCgoJR2xvYmFscy5oYWNjZWwgPSBMb2FkQWNjZWxlcmF0b3JzKGhpbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElEQV9XSU5FRklMRSkpOwoKCUdsb2JhbHMuaGZvbnQgPSBDcmVhdGVGb250KC1NdWxEaXYoOCxHZXREZXZpY2VDYXBzKGhkYyxMT0dQSVhFTFNZKSw3MiksIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIHNGb250KTsKCglSZWxlYXNlREMoMCwgaGRjKTsKCglHbG9iYWxzLmhJbnN0YW5jZSA9IGhpbnN0YW5jZTsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJQ29Jbml0aWFsaXplKE5VTEwpOwoJQ29HZXRNYWxsb2MoTUVNQ1RYX1RBU0ssICZHbG9iYWxzLmlNYWxsb2MpOwoJU0hHZXREZXNrdG9wRm9sZGVyKCZHbG9iYWxzLmlEZXNrdG9wKTsKI2lmZGVmIF9fV0lORV9fCglHbG9iYWxzLmNmU3RyRk5hbWUgPSBSZWdpc3RlckNsaXBib2FyZEZvcm1hdEEoQ0ZTVFJfRklMRU5BTUUpOwojZWxzZQoJR2xvYmFscy5jZlN0ckZOYW1lID0gUmVnaXN0ZXJDbGlwYm9hcmRGb3JtYXQoQ0ZTVFJfRklMRU5BTUUpOwojZW5kaWYKI2VuZGlmCgoJLyogbG9hZCBjb2x1bW4gc3RyaW5ncyAqLwoJY29sID0gMDsKCglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfTkFNRSk7Cglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfU0laRSk7Cglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfQ0RBVEUpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfQURBVEUpOwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX01EQVRFKTsKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9JRFgpOwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX0xJTktTKTsKI2VuZGlmCglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfQVRUUik7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9TRUMpOwojZW5kaWYKfQoKCnZvaWQgc2hvd19mcmFtZShIV05EIGh3bmRQYXJlbnQsIGludCBjbWRzaG93KQp7Cgljb25zdCBzdGF0aWMgVENIQVIgc01ESUNMSUVOVFtdID0geydNJywnRCcsJ0knLCdDJywnTCcsJ0knLCdFJywnTicsJ1QnLCdcMCd9OwoKCVRDSEFSIHBhdGhbTUFYX1BBVEhdLCBiMVtCVUZGRVJfTEVOXTsKCUNoaWxkV25kKiBjaGlsZDsKCUhNRU5VIGhNZW51RnJhbWUsIGhNZW51V2luZG93OwoKCUNMSUVOVENSRUFURVNUUlVDVCBjY3M7CgoJaWYgKEdsb2JhbHMuaE1haW5XbmQpCgkJcmV0dXJuOwoKCUdsb2JhbHMuaHduZFBhcmVudCA9IGh3bmRQYXJlbnQ7CgoJaE1lbnVGcmFtZSA9IExvYWRNZW51KEdsb2JhbHMuaEluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSURNX1dJTkVGSUxFKSk7CgloTWVudVdpbmRvdyA9IEdldFN1Yk1lbnUoaE1lbnVGcmFtZSwgR2V0TWVudUl0ZW1Db3VudChoTWVudUZyYW1lKS0yKTsKCglHbG9iYWxzLmhNZW51RnJhbWUgPSBoTWVudUZyYW1lOwoJR2xvYmFscy5oTWVudVZpZXcgPSBHZXRTdWJNZW51KGhNZW51RnJhbWUsIDMpOwoJR2xvYmFscy5oTWVudU9wdGlvbnMgPSBHZXRTdWJNZW51KGhNZW51RnJhbWUsIDQpOwoKCWNjcy5oV2luZG93TWVudSAgPSBoTWVudVdpbmRvdzsKCWNjcy5pZEZpcnN0Q2hpbGQgPSBJRFdfRklSU1RfQ0hJTEQ7CgoKCS8qIGNyZWF0ZSBtYWluIHdpbmRvdyAqLwoJR2xvYmFscy5oTWFpblduZCA9IENyZWF0ZVdpbmRvd0V4KDAsIChMUENUU1RSKShpbnQpR2xvYmFscy5oZnJhbWVDbGFzcywgUlMoYjEsSURTX1dJTkVfRklMRSksIFdTX09WRVJMQVBQRURXSU5ET1csCgkJCQkJQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwKCQkJCQlod25kUGFyZW50LCBHbG9iYWxzLmhNZW51RnJhbWUsIEdsb2JhbHMuaEluc3RhbmNlLCAwLypscFBhcmFtKi8pOwoKCglHbG9iYWxzLmhtZGljbGllbnQgPSBDcmVhdGVXaW5kb3dFeCgwLCBzTURJQ0xJRU5ULCBOVUxMLAoJCQkJCVdTX0NISUxEfFdTX0NMSVBDSElMRFJFTnxXU19WU0NST0xMfFdTX0hTQ1JPTEx8V1NfVklTSUJMRXxXU19CT1JERVIsCgkJCQkJMCwgMCwgMCwgMCwKCQkJCQlHbG9iYWxzLmhNYWluV25kLCAwLCBHbG9iYWxzLmhJbnN0YW5jZSwgJmNjcyk7CgoKCXsKCQlUQkJVVFRPTiBkcml2ZWJhckJ0biA9IHswLCAwLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfU0VQLCB7MCwgMH0sIDAsIDB9OwoJCWludCBidG4gPSAxOwoJCVBUU1RSIHA7CgoJCUdsb2JhbHMuaGRyaXZlYmFyID0gQ3JlYXRlVG9vbGJhckV4KEdsb2JhbHMuaE1haW5XbmQsIFdTX0NISUxEfFdTX1ZJU0lCTEV8Q0NTX05PTU9WRVl8VEJTVFlMRV9MSVNULAoJCQkJCUlEV19EUklWRUJBUiwgMiwgR2xvYmFscy5oSW5zdGFuY2UsIElEQl9EUklWRUJBUiwgJmRyaXZlYmFyQnRuLAoJCQkJCTEsIDE2LCAxMywgMTYsIDEzLCBzaXplb2YoVEJCVVRUT04pKTsKCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBJRF9WSUVXX0RSSVZFX0JBUiwgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoKCQlHZXRMb2dpY2FsRHJpdmVTdHJpbmdzKEJVRkZFUl9MRU4sIEdsb2JhbHMuZHJpdmVzKTsKCgkJZHJpdmViYXJCdG4uZnNTdHlsZSA9IEJUTlNfQlVUVE9OOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwojaWZkZWYgX19XSU5FX18KCQkvKiBpbnNlcnQgdW5peCBmaWxlIHN5c3RlbSBidXR0b24gKi8KCQliMVswXSA9ICcvJzsKCQliMVsxXSA9ICdcMCc7CgkJYjFbMl0gPSAnXDAnOwoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9BRERTVFJJTkcsIDAsIChMUEFSQU0pYjEpOwoKCQlkcml2ZWJhckJ0bi5pZENvbW1hbmQgPSBJRF9EUklWRV9VTklYX0ZTOwoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9JTlNFUlRCVVRUT04sIGJ0bisrLCAoTFBBUkFNKSZkcml2ZWJhckJ0bik7CgkJZHJpdmViYXJCdG4uaVN0cmluZysrOwojZW5kaWYKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgkJLyogaW5zZXJ0IHNoZWxsIG5hbWVzcGFjZSBidXR0b24gKi8KCQlsb2FkX3N0cmluZyhiMSwgSURTX1NIRUxMKTsKCQliMVtsc3RybGVuKGIxKSsxXSA9ICdcMCc7CgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0FERFNUUklORywgMCwgKExQQVJBTSliMSk7CgoJCWRyaXZlYmFyQnRuLmlkQ29tbWFuZCA9IElEX0RSSVZFX1NIRUxMX05TOwoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9JTlNFUlRCVVRUT04sIGJ0bisrLCAoTFBBUkFNKSZkcml2ZWJhckJ0bik7CgkJZHJpdmViYXJCdG4uaVN0cmluZysrOwojZW5kaWYKCgkJLyogcmVnaXN0ZXIgd2luZG93cyBkcml2ZSByb290IHN0cmluZ3MgKi8KCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfQUREU1RSSU5HLCAwLCAoTFBBUkFNKUdsb2JhbHMuZHJpdmVzKTsKI2VuZGlmCgoJCWRyaXZlYmFyQnRuLmlkQ29tbWFuZCA9IElEX0RSSVZFX0ZJUlNUOwoKCQlmb3IocD1HbG9iYWxzLmRyaXZlczsgKnA7ICkgewojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkgIC8qIGluc2VydCBkcml2ZSBsZXR0ZXIgKi8KCQkJVENIQVIgYlszXSA9IHt0b2xvd2VyKCpwKX07CgkJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9BRERTVFJJTkcsIDAsIChMUEFSQU0pYik7CiNlbmRpZgoJCQlzd2l0Y2goR2V0RHJpdmVUeXBlKHApKSB7CgkJCQljYXNlIERSSVZFX1JFTU9WQUJMRToJZHJpdmViYXJCdG4uaUJpdG1hcCA9IDE7CWJyZWFrOwoJCQkJY2FzZSBEUklWRV9DRFJPTToJCWRyaXZlYmFyQnRuLmlCaXRtYXAgPSAzOwlicmVhazsKCQkJCWNhc2UgRFJJVkVfUkVNT1RFOgkJZHJpdmViYXJCdG4uaUJpdG1hcCA9IDQ7CWJyZWFrOwoJCQkJY2FzZSBEUklWRV9SQU1ESVNLOgkJZHJpdmViYXJCdG4uaUJpdG1hcCA9IDU7CWJyZWFrOwoJCQkJZGVmYXVsdDovKkRSSVZFX0ZJWEVEKi8JZHJpdmViYXJCdG4uaUJpdG1hcCA9IDI7CgkJCX0KCgkJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9JTlNFUlRCVVRUT04sIGJ0bisrLCAoTFBBUkFNKSZkcml2ZWJhckJ0bik7CgkJCWRyaXZlYmFyQnRuLmlkQ29tbWFuZCsrOwoJCQlkcml2ZWJhckJ0bi5pU3RyaW5nKys7CgoJCQl3aGlsZSgqcCsrKTsKCQl9Cgl9CgoJewoJCVRCQlVUVE9OIHRvb2xiYXJCdG5zW10gPSB7CgkJCXswLCAwLCAwLCBCVE5TX1NFUCwgezAsIDB9LCAwLCAwfSwKCQkJezAsIElEX1dJTkRPV19ORVcsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH0sCgkJCXsxLCBJRF9XSU5ET1dfQ0FTQ0FERSwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKCQkJezIsIElEX1dJTkRPV19USUxFX0hPUlosIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH0sCgkJCXszLCBJRF9XSU5ET1dfVElMRV9WRVJULCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9LAovKlRPRE8KCQkJezQsIElEXy4uLiAsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT059LAoJCQl7NSwgSURfLi4uICwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTn0sCiovCQl9OwoKCQlHbG9iYWxzLmh0b29sYmFyID0gQ3JlYXRlVG9vbGJhckV4KEdsb2JhbHMuaE1haW5XbmQsIFdTX0NISUxEfFdTX1ZJU0lCTEUsCgkJCUlEV19UT09MQkFSLCAyLCBHbG9iYWxzLmhJbnN0YW5jZSwgSURCX1RPT0xCQVIsIHRvb2xiYXJCdG5zLAoJCQlzaXplb2YodG9vbGJhckJ0bnMpL3NpemVvZihUQkJVVFRPTiksIDE2LCAxNSwgMTYsIDE1LCBzaXplb2YoVEJCVVRUT04pKTsKCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBJRF9WSUVXX1RPT0xfQkFSLCBNRl9CWUNPTU1BTkR8TUZfQ0hFQ0tFRCk7Cgl9CgoJR2xvYmFscy5oc3RhdHVzYmFyID0gQ3JlYXRlU3RhdHVzV2luZG93KFdTX0NISUxEfFdTX1ZJU0lCTEUsIDAsIEdsb2JhbHMuaE1haW5XbmQsIElEV19TVEFUVVNCQVIpOwoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgSURfVklFV19TVEFUVVNCQVIsIE1GX0JZQ09NTUFORHxNRl9DSEVDS0VEKTsKCi8qIENyZWF0ZVN0YXR1c1dpbmRvdyBkb2VzIG5vdCBhY2NlcHQgV1NfQk9SREVSCglHbG9iYWxzLmhzdGF0dXNiYXIgPSBDcmVhdGVXaW5kb3dFeChXU19FWF9OT1BBUkVOVE5PVElGWSwgU1RBVFVTQ0xBU1NOQU1FLCAwLAoJCQkJCVdTX0NISUxEfFdTX1ZJU0lCTEV8V1NfQ0xJUFNJQkxJTkdTfFdTX0JPUkRFUnxDQ1NfTk9ESVZJREVSLCAwLDAsMCwwLAoJCQkJCUdsb2JhbHMuaE1haW5XbmQsIChITUVOVSlJRFdfU1RBVFVTQkFSLCBoaW5zdGFuY2UsIDApOyovCgoJLypUT0RPOiByZWFkIHBhdGhzIGFuZCB3aW5kb3cgcGxhY2VtZW50cyBmcm9tIHJlZ2lzdHJ5ICovCglHZXRDdXJyZW50RGlyZWN0b3J5KE1BWF9QQVRILCBwYXRoKTsKCglTaG93V2luZG93KEdsb2JhbHMuaE1haW5XbmQsIGNtZHNob3cpOwoKI2lmIGRlZmluZWQoX1NIRUxMX0ZPTERFUlMpICYmICFkZWZpbmVkKF9fV0lORV9fKQoJIC8qIFNoZWxsIE5hbWVzcGFjZSBhcyBkZWZhdWx0OiAqLwoJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgZ2V0X3BhdGhfcGlkbChwYXRoLEdsb2JhbHMuaE1haW5XbmQpLCBHbG9iYWxzLmhNYWluV25kKTsKI2Vsc2UKCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIE5VTEwsIEdsb2JhbHMuaE1haW5XbmQpOwojZW5kaWYKCgljaGlsZC0+cG9zLnNob3dDbWQgPSBTV19TSE9XTUFYSU1JWkVEOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmxlZnQgPSAwOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLnRvcCA9IDA7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ucmlnaHQgPSAzMjA7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24uYm90dG9tID0gMjgwOwoKCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhjaGlsZCkpCgkJZnJlZShjaGlsZCk7CgoJU2V0V2luZG93UGxhY2VtZW50KGNoaWxkLT5od25kLCAmY2hpbGQtPnBvcyk7CgoJR2xvYmFscy5oaW1sID0gSW1hZ2VMaXN0X0xvYWRCaXRtYXAoR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJREJfSU1BR0VTKSwgMTYsIDAsIFJHQigwLDI1NSwwKSk7CgoJR2xvYmFscy5wcmVzY2FuX25vZGUgPSBGQUxTRTsKCglVcGRhdGVXaW5kb3coR2xvYmFscy5oTWFpblduZCk7Cn0KCnZvaWQgRXhpdEluc3RhbmNlKCkKewojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCSgqR2xvYmFscy5pRGVza3RvcC0+bHBWdGJsLT5SZWxlYXNlKShHbG9iYWxzLmlEZXNrdG9wKTsKCSgqR2xvYmFscy5pTWFsbG9jLT5scFZ0YmwtPlJlbGVhc2UpKEdsb2JhbHMuaU1hbGxvYyk7CglDb1VuaW5pdGlhbGl6ZSgpOwojZW5kaWYKCglJbWFnZUxpc3RfRGVzdHJveShHbG9iYWxzLmhpbWwpOwp9CgoKLyogc2VhcmNoIGZvciBhbHJlYWR5IHJ1bm5pbmcgd2luW2VdZmlsZXMgKi8KCnN0YXRpYyBpbnQgZ19mb3VuZFByZXZJbnN0YW5jZSA9IDA7CgpzdGF0aWMgQk9PTCBDQUxMQkFDSyBFbnVtV25kUHJvYyhIV05EIGh3bmQsIExQQVJBTSBscGFyYW0pCnsKCVRDSEFSIGNsc1sxMjhdOwoKCUdldENsYXNzTmFtZShod25kLCBjbHMsIDEyOCk7CgoJaWYgKCFsc3RyY21wKGNscywgKExQQ1RTVFIpbHBhcmFtKSkgewoJCWdfZm91bmRQcmV2SW5zdGFuY2UrKzsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCi8qIHNlYXJjaCBmb3Igd2luZG93IG9mIGdpdmVuIGNsYXNzIG5hbWUgdG8gYWxsb3cgb25seSBvbmUgcnVubmluZyBpbnN0YW5jZSAqLwppbnQgZmluZF93aW5kb3dfY2xhc3MoTFBDVFNUUiBjbGFzc25hbWUpCnsKCUVudW1XaW5kb3dzKEVudW1XbmRQcm9jLCAoTFBBUkFNKWNsYXNzbmFtZSk7CgoJaWYgKGdfZm91bmRQcmV2SW5zdGFuY2UpCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCgppbnQgd2luZWZpbGVfbWFpbihISU5TVEFOQ0UgaGluc3RhbmNlLCBIV05EIGh3bmRQYXJlbnQsIGludCBjbWRzaG93KQp7CglNU0cgbXNnOwoKCUluaXRJbnN0YW5jZShoaW5zdGFuY2UpOwoKCWlmIChjbWRzaG93ID09IFNXX1NIT1dOT1JNQUwpCgkgICAgICAgIC8qVE9ETzogcmVhZCB3aW5kb3cgcGxhY2VtZW50IGZyb20gcmVnaXN0cnkgKi8KCQljbWRzaG93ID0gU1dfTUFYSU1JWkU7CgoJc2hvd19mcmFtZShod25kUGFyZW50LCBjbWRzaG93KTsKCgl3aGlsZShHZXRNZXNzYWdlKCZtc2csIDAsIDAsIDApKSB7CgkJaWYgKEdsb2JhbHMuaG1kaWNsaWVudCAmJiBUcmFuc2xhdGVNRElTeXNBY2NlbChHbG9iYWxzLmhtZGljbGllbnQsICZtc2cpKQoJCQljb250aW51ZTsKCgkJaWYgKEdsb2JhbHMuaE1haW5XbmQgJiYgVHJhbnNsYXRlQWNjZWxlcmF0b3IoR2xvYmFscy5oTWFpblduZCwgR2xvYmFscy5oYWNjZWwsICZtc2cpKQoJCQljb250aW51ZTsKCgkJVHJhbnNsYXRlTWVzc2FnZSgmbXNnKTsKCQlEaXNwYXRjaE1lc3NhZ2UoJm1zZyk7Cgl9CgoJRXhpdEluc3RhbmNlKCk7CgoJcmV0dXJuIG1zZy53UGFyYW07Cn0KCgppbnQgQVBJRU5UUlkgV2luTWFpbihISU5TVEFOQ0UgaGluc3RhbmNlLAoJCQkJCSBISU5TVEFOQ0UgcHJldmluc3RhbmNlLAoJCQkJCSBMUFNUUgkgICBjbWRsaW5lLAoJCQkJCSBpbnQJICAgY21kc2hvdykKewojaWZkZWYgX05PX0VYVEVOU0lPTlMKCWlmIChmaW5kX3dpbmRvd19jbGFzcyhzV0lORUZJTEVGUkFNRSkpCgkJcmV0dXJuIDE7CiNlbmRpZgoKCXdpbmVmaWxlX21haW4oaGluc3RhbmNlLCAwLCBjbWRzaG93KTsKCglyZXR1cm4gMDsKfQo=