LyoKICogU3RhY2sgd2Fsa2luZwogKgogKiBDb3B5cmlnaHQgMTk5NSBBbGV4YW5kcmUgSnVsbGlhcmQKICogQ29weXJpZ2h0IDE5OTYgRXJpYyBZb3VuZ2RhbGUKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqIENvcHlyaWdodCAyMDA0IEVyaWMgUG91ZWNoCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAibnRzdGF0dXMuaCIKI2RlZmluZSBXSU4zMl9OT19TVEFUVVMKI2luY2x1ZGUgImRiZ2hlbHBfcHJpdmF0ZS5oIgojaW5jbHVkZSAid2ludGVybmwuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkYmdoZWxwKTsKCmVudW0gc3RfbW9kZSB7c3RtX3N0YXJ0LCBzdG1fMzJiaXQsIHN0bV8xNmJpdCwgc3RtX2RvbmV9OwoKc3RhdGljIGNvbnN0IGNoYXIqIHdpbmVfZGJnc3RyX2FkZHIoY29uc3QgQUREUkVTUyogYWRkcikKewogICAgaWYgKCFhZGRyKSByZXR1cm4gIihudWxsKSI7CiAgICBzd2l0Y2ggKGFkZHItPk1vZGUpCiAgICB7CiAgICBjYXNlIEFkZHJNb2RlRmxhdDoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigiZmxhdDwlMDh4PiIsIGFkZHItPk9mZnNldCk7CiAgICBjYXNlIEFkZHJNb2RlMTYxNjoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigiMTYxNjwlMDR4OiUwNHg+IiwgYWRkci0+U2VnbWVudCwgYWRkci0+T2Zmc2V0KTsKICAgIGNhc2UgQWRkck1vZGUxNjMyOgogICAgICAgIHJldHVybiB3aW5lX2RiZ19zcHJpbnRmKCIxNjMyPCUwNHg6JTA4eD4iLCBhZGRyLT5TZWdtZW50LCBhZGRyLT5PZmZzZXQpOwogICAgY2FzZSBBZGRyTW9kZVJlYWw6CiAgICAgICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoInJlYWw8JTA0eDolMDR4PiIsIGFkZHItPlNlZ21lbnQsIGFkZHItPk9mZnNldCk7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiAidW5rbm93biI7CiAgICB9Cn0KCnN0YXRpYyBCT09MIENBTExCQUNLIHJlYWRfbWVtKEhBTkRMRSBoUHJvY2VzcywgRFdPUkQgYWRkciwgdm9pZCogYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBzaXplLCBMUERXT1JEIG5yZWFkKQp7CiAgICBTSVpFX1QgICAgICByOwogICAgaWYgKCFSZWFkUHJvY2Vzc01lbW9yeShoUHJvY2VzcywgKHZvaWQqKWFkZHIsIGJ1ZmZlciwgc2l6ZSwgJnIpKSByZXR1cm4gRkFMU0U7CiAgICBpZiAobnJlYWQpICpucmVhZCA9IHI7CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgcmVhZF9tZW02NChIQU5ETEUgaFByb2Nlc3MsIERXT1JENjQgYWRkciwgdm9pZCogYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHNpemUsIExQRFdPUkQgbnJlYWQpCnsKICAgIFNJWkVfVCAgICAgIHI7CiAgICBpZiAoIVJlYWRQcm9jZXNzTWVtb3J5KGhQcm9jZXNzLCAodm9pZCopKERXT1JEX1BUUilhZGRyLCBidWZmZXIsIHNpemUsICZyKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKG5yZWFkKSAqbnJlYWQgPSByOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qIGluZGV4ZXMgaW4gUmVzZXJ2ZWQgYXJyYXkgKi8KI2RlZmluZSBfX0N1cnJlbnRNb2RlICAgICAwCiNkZWZpbmUgX19DdXJyZW50U3dpdGNoICAgMQojZGVmaW5lIF9fTmV4dFN3aXRjaCAgICAgIDIKCiNkZWZpbmUgY3Vycl9tb2RlICAgKGZyYW1lLT5SZXNlcnZlZFtfX0N1cnJlbnRNb2RlXSkKI2RlZmluZSBjdXJyX3N3aXRjaCAoZnJhbWUtPlJlc2VydmVkW19fQ3VycmVudFN3aXRjaF0pCiNkZWZpbmUgbmV4dF9zd2l0Y2ggKGZyYW1lLT5SZXNlcnZlZFtfX05leHRTd2l0Y2hdKQoKc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sKewogICAgSEFORExFICAgICAgaFByb2Nlc3M7CiAgICBIQU5ETEUgICAgICBoVGhyZWFkOwogICAgQk9PTCAgICAgICAgaXMzMjsKICAgIHVuaW9uCiAgICB7CiAgICAgICAgc3RydWN0CiAgICAgICAgewogICAgICAgICAgICBQUkVBRF9QUk9DRVNTX01FTU9SWV9ST1VUSU5FICAgICAgICBmX3JlYWRfbWVtOwogICAgICAgICAgICBQVFJBTlNMQVRFX0FERFJFU1NfUk9VVElORSAgICAgICAgICBmX3hsYXRfYWRyOwogICAgICAgICAgICBQRlVOQ1RJT05fVEFCTEVfQUNDRVNTX1JPVVRJTkUgICAgICBmX3RhYmxfYWNzOwogICAgICAgICAgICBQR0VUX01PRFVMRV9CQVNFX1JPVVRJTkUgICAgICAgICAgICBmX21vZGxfYmFzOwogICAgICAgIH0gczMyOwogICAgICAgIHN0cnVjdAogICAgICAgIHsKICAgICAgICAgICAgUFJFQURfUFJPQ0VTU19NRU1PUllfUk9VVElORTY0ICAgICAgZl9yZWFkX21lbTsKICAgICAgICAgICAgUFRSQU5TTEFURV9BRERSRVNTX1JPVVRJTkU2NCAgICAgICAgZl94bGF0X2FkcjsKICAgICAgICAgICAgUEZVTkNUSU9OX1RBQkxFX0FDQ0VTU19ST1VUSU5FNjQgICAgZl90YWJsX2FjczsKICAgICAgICAgICAgUEdFVF9NT0RVTEVfQkFTRV9ST1VUSU5FNjQgICAgICAgICAgZl9tb2RsX2JhczsKICAgICAgICB9IHM2NDsKICAgIH0gdTsKfTsKCnN0YXRpYyBpbmxpbmUgdm9pZCBhZGRyXzMydG82NChjb25zdCBBRERSRVNTKiBhZGRyMzIsIEFERFJFU1M2NCogYWRkcjY0KQp7CiAgICBhZGRyNjQtPk9mZnNldCA9IChVTE9ORzY0KWFkZHIzMi0+T2Zmc2V0OwogICAgYWRkcjY0LT5TZWdtZW50ID0gYWRkcjMyLT5TZWdtZW50OwogICAgYWRkcjY0LT5Nb2RlID0gYWRkcjMyLT5Nb2RlOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgYWRkcl82NHRvMzIoY29uc3QgQUREUkVTUzY0KiBhZGRyNjQsIEFERFJFU1MqIGFkZHIzMikKewogICAgYWRkcjMyLT5PZmZzZXQgPSAoVUxPTkcpYWRkcjY0LT5PZmZzZXQ7CiAgICBhZGRyMzItPlNlZ21lbnQgPSBhZGRyNjQtPlNlZ21lbnQ7CiAgICBhZGRyMzItPk1vZGUgPSBhZGRyNjQtPk1vZGU7Cn0KCnN0YXRpYyBpbmxpbmUgQk9PTCBzd19yZWFkX21lbShzdHJ1Y3Qgc3RhY2tfd2Fsa19jYWxsYmFjayogY2IsIERXT1JEIGFkZHIsIHZvaWQqIHB0ciwgRFdPUkQgc3opCnsKICAgIGlmIChjYi0+aXMzMikKICAgICAgICByZXR1cm4gY2ItPnUuczMyLmZfcmVhZF9tZW0oY2ItPmhQcm9jZXNzLCBhZGRyLCBwdHIsIHN6LCBOVUxMKTsKICAgIGVsc2UKICAgICAgICByZXR1cm4gY2ItPnUuczY0LmZfcmVhZF9tZW0oY2ItPmhQcm9jZXNzLCBhZGRyLCBwdHIsIHN6LCBOVUxMKTsKfQoKc3RhdGljIGlubGluZSBEV09SRCBzd194bGF0X2FkZHIoc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sqIGNiLCBBRERSRVNTKiBhZGRyKQp7CiAgICBpZiAoYWRkci0+TW9kZSA9PSBBZGRyTW9kZUZsYXQpIHJldHVybiBhZGRyLT5PZmZzZXQ7CiAgICBpZiAoY2ItPmlzMzIpIHJldHVybiBjYi0+dS5zMzIuZl94bGF0X2FkcihjYi0+aFByb2Nlc3MsIGNiLT5oVGhyZWFkLCBhZGRyKTsKICAgIGlmIChjYi0+dS5zNjQuZl94bGF0X2FkcikKICAgIHsKICAgICAgICBBRERSRVNTNjQgICAgICAgYWRkcjY0OwoKICAgICAgICBhZGRyXzMydG82NChhZGRyLCAmYWRkcjY0KTsKICAgICAgICByZXR1cm4gY2ItPnUuczY0LmZfeGxhdF9hZHIoY2ItPmhQcm9jZXNzLCBjYi0+aFRocmVhZCwgJmFkZHI2NCk7CiAgICB9CiAgICByZXR1cm4gYWRkcl90b19saW5lYXIoY2ItPmhQcm9jZXNzLCBjYi0+aFRocmVhZCwgYWRkcik7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCogc3dfdGFibF9hY3Moc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sqIGNiLCBEV09SRCBhZGRyKQp7CiAgICBpZiAoY2ItPmlzMzIpCiAgICAgICAgcmV0dXJuIGNiLT51LnMzMi5mX3RhYmxfYWNzKGNiLT5oUHJvY2VzcywgYWRkcik7CiAgICBlbHNlCiAgICAgICAgcmV0dXJuIGNiLT51LnM2NC5mX3RhYmxfYWNzKGNiLT5oUHJvY2VzcywgYWRkcik7Cn0KCnN0YXRpYyBpbmxpbmUgRFdPUkQgc3dfbW9kbF9iYXMoc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sqIGNiLCBEV09SRCBhZGRyKQp7CiAgICBpZiAoY2ItPmlzMzIpCiAgICAgICAgcmV0dXJuIGNiLT51LnMzMi5mX21vZGxfYmFzKGNiLT5oUHJvY2VzcywgYWRkcik7CiAgICBlbHNlCiAgICAgICAgcmV0dXJuIGNiLT51LnM2NC5mX21vZGxfYmFzKGNiLT5oUHJvY2VzcywgYWRkcik7Cn0KCnN0YXRpYyBCT09MIHN0YWNrX3dhbGsoc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sqIGNiLCBMUFNUQUNLRlJBTUUgZnJhbWUpCnsKICAgIFNUQUNLMzJGUkFNRSAgICAgICAgZnJhbWUzMjsKICAgIFNUQUNLMTZGUkFNRSAgICAgICAgZnJhbWUxNjsKICAgIGNoYXIgICAgICAgICAgICAgICAgY2g7CiAgICBBRERSRVNTICAgICAgICAgICAgIHRtcDsKICAgIERXT1JEICAgICAgICAgICAgICAgcDsKICAgIFdPUkQgICAgICAgICAgICAgICAgdmFsOwogICAgQk9PTCAgICAgICAgICAgICAgICBkb19zd2l0Y2g7CgogICAgLyogc2FuaXR5IGNoZWNrICovCiAgICBpZiAoY3Vycl9tb2RlID49IHN0bV9kb25lKSByZXR1cm4gRkFMU0U7CgogICAgVFJBQ0UoIkVudGVyOiBQQz0lcyBGcmFtZT0lcyBSZXR1cm49JXMgU3RhY2s9JXMgTW9kZT0lcyBjU3dpdGNoPSUwOHggblN3aXRjaD0lMDh4XG4iLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJQQyksCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUmV0dXJuKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyU3RhY2spLCAKICAgICAgICAgIGN1cnJfbW9kZSA9PSBzdG1fc3RhcnQgPyAic3RhcnQiIDogKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQgPyAiMTZiaXQiIDogIjMyYml0IiksCiAgICAgICAgICBjdXJyX3N3aXRjaCwgbmV4dF9zd2l0Y2gpOwoKICAgIGlmIChjdXJyX21vZGUgPT0gc3RtX3N0YXJ0KQogICAgewogICAgICAgIFRIUkVBRF9CQVNJQ19JTkZPUk1BVElPTiBpbmZvOwoKICAgICAgICBpZiAoKGZyYW1lLT5BZGRyUEMuTW9kZSA9PSBBZGRyTW9kZUZsYXQpICYmCiAgICAgICAgICAgIChmcmFtZS0+QWRkckZyYW1lLk1vZGUgIT0gQWRkck1vZGVGbGF0KSkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIkJhZCBBZGRyUEMuTW9kZSAvIEFkZHJGcmFtZS5Nb2RlIGNvbWJpbmF0aW9uXG4iKTsKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICB9CgogICAgICAgIC8qIEluaXQgZG9uZSAqLwogICAgICAgIGN1cnJfbW9kZSA9IChmcmFtZS0+QWRkclBDLk1vZGUgPT0gQWRkck1vZGVGbGF0KSA/IAogICAgICAgICAgICBzdG1fMzJiaXQgOiBzdG1fMTZiaXQ7CgogICAgICAgIC8qIGN1cl9zd2l0Y2ggaG9sZHMgYWRkcmVzcyBvZiBXT1czMlJlc2VydmVkIGZpZWxkIGluIFRFQiBpbiBkZWJ1Z2dlZQogICAgICAgICAqIGFkZHJlc3Mgc3BhY2UKICAgICAgICAgKi8KICAgICAgICBpZiAoTnRRdWVyeUluZm9ybWF0aW9uVGhyZWFkKGNiLT5oVGhyZWFkLCBUaHJlYWRCYXNpY0luZm9ybWF0aW9uLCAmaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihpbmZvKSwgTlVMTCkgPT0gU1RBVFVTX1NVQ0NFU1MpCiAgICAgICAgewogICAgICAgICAgICBjdXJyX3N3aXRjaCA9ICh1bnNpZ25lZCBsb25nKWluZm8uVGViQmFzZUFkZHJlc3MgKyBGSUVMRF9PRkZTRVQoVEVCLCBXT1czMlJlc2VydmVkKTsKICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgY3Vycl9zd2l0Y2gsICZuZXh0X3N3aXRjaCwgc2l6ZW9mKG5leHRfc3dpdGNoKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdBUk4oIkNhbid0IHJlYWQgVEVCOldPVzMyUmVzZXJ2ZWRcbiIpOwogICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoZnJhbWUzMikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOHhcbiIsIG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUzMi5mcmFtZTE2OwogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YoY3Vycl9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihjdXJyX3N3aXRjaCk7CiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBzd194bGF0X2FkZHIoY2IsICZ0bXApLCAmY2gsIHNpemVvZihjaCkpKQogICAgICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gMHhGRkZGRkZGRjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgdG1wLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgcCA9IHN3X3hsYXRfYWRkcihjYiwgJnRtcCk7CiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBwLCAmZnJhbWUxNiwgc2l6ZW9mKGZyYW1lMTYpKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDh4XG4iLCBwKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUxNi5mcmFtZTMyOwoKICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIGN1cnJfc3dpdGNoLCAmY2gsIHNpemVvZihjaCkpKQogICAgICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gMHhGRkZGRkZGRjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIC8qIEZJWE1FOiB0aGlzIHdpbGwgYWxsb3cgdG8gd29yayB3aGVuIHdlJ3JlIG5vdCBhdHRhY2hlZCB0byBhIGxpdmUgdGFyZ2V0LCAKICAgICAgICAgICAgICogYnV0IHRoZSAxNiA8PT4gMzIgc3dpdGNoIGZhY2lsaXR5IHdvbid0IGJlIGF2YWlsYWJsZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gMDsKICAgICAgICBmcmFtZS0+QWRkclJldHVybi5Nb2RlID0gZnJhbWUtPkFkZHJTdGFjay5Nb2RlID0gKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpID8gQWRkck1vZGUxNjE2IDogQWRkck1vZGVGbGF0OwogICAgICAgIC8qIGRvbid0IHNldCB1cCBBZGRyU3RhY2sgb24gZmlyc3QgY2FsbC4gRWl0aGVyIHRoZSBjYWxsZXIgaGFzIHNldCBpdCB1cCwgb3IKICAgICAgICAgKiB3ZSB3aWxsIGdldCBpdCBpbiB0aGUgbmV4dCBmcmFtZQogICAgICAgICAqLwogICAgICAgIG1lbXNldCgmZnJhbWUtPkFkZHJCU3RvcmUsIDAsIHNpemVvZihmcmFtZS0+QWRkckJTdG9yZSkpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA9PSAwKSBnb3RvIGRvbmVfZXJyOwogICAgICAgIGlmIChmcmFtZS0+QWRkckZyYW1lLk1vZGUgPT0gQWRkck1vZGVGbGF0KQogICAgICAgIHsKICAgICAgICAgICAgYXNzZXJ0KGN1cnJfbW9kZSA9PSBzdG1fMzJiaXQpOwogICAgICAgICAgICBkb19zd2l0Y2ggPSBjdXJyX3N3aXRjaCAmJiBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA+PSBjdXJyX3N3aXRjaDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgYXNzZXJ0KGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpOwogICAgICAgICAgICBkb19zd2l0Y2ggPSBjdXJyX3N3aXRjaCAmJiAKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuU2VnbWVudCA9PSBTRUxFQ1RPUk9GKGN1cnJfc3dpdGNoKSAmJgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgPj0gT0ZGU0VUT0YoY3Vycl9zd2l0Y2gpOwogICAgICAgIH0KCSAgIAogICAgICAgIGlmIChkb19zd2l0Y2gpCiAgICAgICAgewogICAgICAgICAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoZnJhbWUzMikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOHhcbiIsIG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuTW9kZSAgICAgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLlNlZ21lbnQgICAgID0gMDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuT2Zmc2V0ICAgICAgPSBmcmFtZTMyLnJldGFkZHI7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk1vZGUgICAgID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5TZWdtZW50ICA9IDA7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAgID0gZnJhbWUzMi5lYnA7CgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5Nb2RlICAgICA9IEFkZHJNb2RlRmxhdDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suU2VnbWVudCAgPSAwOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uTW9kZSAgICA9IEFkZHJNb2RlRmxhdDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLlNlZ21lbnQgPSAwOwoKICAgICAgICAgICAgICAgIG5leHRfc3dpdGNoID0gY3Vycl9zd2l0Y2g7CiAgICAgICAgICAgICAgICB0bXAuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHAgPSBzd194bGF0X2FkZHIoY2IsICZ0bXApOwoKICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIHAsICZmcmFtZTE2LCBzaXplb2YoZnJhbWUxNikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOHhcbiIsIHApOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IChEV09SRClmcmFtZTE2LmZyYW1lMzI7CiAgICAgICAgICAgICAgICBjdXJyX21vZGUgPSBzdG1fMzJiaXQ7CiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBjdXJyX3N3aXRjaCwgJmNoLCBzaXplb2YoY2gpKSkKICAgICAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0bXAuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHAgPSBzd194bGF0X2FkZHIoY2IsICZ0bXApOwoKICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIHAsICZmcmFtZTE2LCBzaXplb2YoZnJhbWUxNikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOHhcbiIsIHApOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgVFJBQ0UoIkdvdCBhIDE2IGJpdCBzdGFjayBzd2l0Y2g6IgogICAgICAgICAgICAgICAgICAgICAgIlxuXHRmcmFtZTMyOiAlMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZWR4OiUwOHggZWN4OiUwOHggZWJwOiUwOHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGRzOiUwNHggZXM6JTA0eCBmczolMDR4IGdzOiUwNHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGNhbGxfZnJvbV9pcDolMDh4IG1vZHVsZV9jczolMDR4IHJlbGF5PSUwOHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGVudHJ5X2lwOiUwNHggZW50cnlfcG9pbnQ6JTA4eCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0YnA6JTA0eCBpcDolMDR4IGNzOiUwNHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZylmcmFtZTE2LmZyYW1lMzIsCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmVkeCwgZnJhbWUxNi5lY3gsIGZyYW1lMTYuZWJwLAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5kcywgZnJhbWUxNi5lcywgZnJhbWUxNi5mcywgZnJhbWUxNi5ncywKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuY2FsbGZyb21faXAsIGZyYW1lMTYubW9kdWxlX2NzLCBmcmFtZTE2LnJlbGF5LAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5lbnRyeV9pcCwgZnJhbWUxNi5lbnRyeV9wb2ludCwKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuYnAsIGZyYW1lMTYuaXAsIGZyYW1lMTYuY3MpOwoKICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5Nb2RlICAgICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5TZWdtZW50ICAgID0gZnJhbWUxNi5jczsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuT2Zmc2V0ICAgICA9IGZyYW1lMTYuaXA7CgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAgPSBmcmFtZTE2LmJwOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gZnJhbWUxNi5jczsKCiAgICAgICAgICAgICAgICBuZXh0X3N3aXRjaCA9IGN1cnJfc3dpdGNoOwogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoZnJhbWUzMikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOHhcbiIsIG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUzMi5mcmFtZTE2OwogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YoY3Vycl9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihjdXJyX3N3aXRjaCk7CgogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgc3dfeGxhdF9hZGRyKGNiLCAmdG1wKSwgJmNoLCBzaXplb2YoY2gpKSkKICAgICAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDA7CiAgICAgICAgICAgICAgICBjdXJyX21vZGUgPSBzdG1fMTZiaXQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgZnJhbWUtPkFkZHJQQyA9IGZyYW1lLT5BZGRyUmV0dXJuOwogICAgICAgICAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5PZmZzZXQgPSBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIDIgKiBzaXplb2YoV09SRCk7CiAgICAgICAgICAgICAgICAvKiAicG9wIHVwIiBwcmV2aW91cyBCUCB2YWx1ZSAqLwogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgc3dfeGxhdF9hZGRyKGNiLCAmZnJhbWUtPkFkZHJGcmFtZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ2YWwsIHNpemVvZihXT1JEKSkpCiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID0gdmFsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5PZmZzZXQgPSBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIDIgKiBzaXplb2YoRFdPUkQpOwogICAgICAgICAgICAgICAgLyogInBvcCB1cCIgcHJldmlvdXMgRUJQIHZhbHVlICovCiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmcmFtZS0+QWRkckZyYW1lLk9mZnNldCwgc2l6ZW9mKERXT1JEKSkpCiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgIHsKICAgICAgICBpbnQgICAgIGk7CgogICAgICAgIHAgPSBzd194bGF0X2FkZHIoY2IsICZmcmFtZS0+QWRkckZyYW1lKTsKICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBwICsgc2l6ZW9mKFdPUkQpLCAmdmFsLCBzaXplb2YoV09SRCkpKQogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk9mZnNldCA9IHZhbDsKICAgICAgICAvKiBnZXQgcG90ZW50aWFsIGNzIGlmIGEgZmFyIGNhbGwgd2FzIHVzZWQgKi8KICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBwICsgMiAqIHNpemVvZihXT1JEKSwgJnZhbCwgc2l6ZW9mKFdPUkQpKSkKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICBpZiAoZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgJiAxKQogICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gdmFsOyAvKiBmYXIgY2FsbCBhc3N1bWVkICovCiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyogbm90IGV4cGxpY2l0bHkgbWFya2VkIGFzIGZhciBjYWxsLCAKICAgICAgICAgICAgICogYnV0IGNoZWNrIHdoZXRoZXIgaXQgY291bGQgYmUgYW55d2F5CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoKHZhbCAmIDcpID09IDcgJiYgdmFsICE9IGZyYW1lLT5BZGRyUmV0dXJuLlNlZ21lbnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIExEVF9FTlRSWQlsZTsKCiAgICAgICAgICAgICAgICBpZiAoR2V0VGhyZWFkU2VsZWN0b3JFbnRyeShjYi0+aFRocmVhZCwgdmFsLCAmbGUpICYmCiAgICAgICAgICAgICAgICAgICAgKGxlLkhpZ2hXb3JkLkJpdHMuVHlwZSAmIDB4MDgpKSAvKiBjb2RlIHNlZ21lbnQgKi8KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBpdCBpcyB2ZXJ5IHVuY29tbW9uIHRvIHB1c2ggYSBjb2RlIHNlZ21lbnQgY3MgYXMKICAgICAgICAgICAgICAgICAgICAgKiBhIHBhcmFtZXRlciwgc28gdGhpcyBzaG91bGQgd29yayBpbiBtb3N0IGNhc2VzIAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLlNlZ21lbnQgPSB2YWw7CiAgICAgICAgICAgICAgICB9CgkgICAgfQoJfQogICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICY9IH4xOwogICAgICAgIC8qIHdlICJwb3AiIHBhcmFtZXRlcnMgYXMgMTYgYml0IGVudGl0aWVzLi4uIG9mIGNvdXJzZSwgdGhpcyB3b24ndAogICAgICAgICAqIHdvcmsgaWYgdGhlIHBhcmFtZXRlciBpcyBpbiBmYWN0IGJpZ2dlciB0aGFuIDE2Yml0LCBidXQKICAgICAgICAgKiB0aGVyZSdzIG5vIHdheSB0byBrbm93IHRoYXQgaGVyZQogICAgICAgICAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBzaXplb2YoZnJhbWUtPlBhcmFtcykgLyBzaXplb2YoZnJhbWUtPlBhcmFtc1swXSk7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIHN3X3JlYWRfbWVtKGNiLCBwICsgKDIgKyBpKSAqIHNpemVvZihXT1JEKSwgJnZhbCwgc2l6ZW9mKHZhbCkpOwogICAgICAgICAgICBmcmFtZS0+UGFyYW1zW2ldID0gdmFsOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIHNpemVvZihEV09SRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAmZnJhbWUtPkFkZHJSZXR1cm4uT2Zmc2V0LCBzaXplb2YoRFdPUkQpKSkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIkNhbm5vdCByZWFkIG5ldyBmcmFtZSBvZmZzZXQgJTA4eFxuIiwgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAoaW50KXNpemVvZihEV09SRCkpOwogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIH0KICAgICAgICBzd19yZWFkX21lbShjYiwgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKSwKICAgICAgICAgICAgICAgICAgICBmcmFtZS0+UGFyYW1zLCBzaXplb2YoZnJhbWUtPlBhcmFtcykpOwogICAgfQoKICAgIGZyYW1lLT5GYXIgPSBUUlVFOwogICAgZnJhbWUtPlZpcnR1YWwgPSBUUlVFOwogICAgcCA9IHN3X3hsYXRfYWRkcihjYiwgJmZyYW1lLT5BZGRyUEMpOwogICAgaWYgKHAgJiYgc3dfbW9kbF9iYXMoY2IsIHApKQogICAgICAgIGZyYW1lLT5GdW5jVGFibGVFbnRyeSA9IHN3X3RhYmxfYWNzKGNiLCBwKTsKICAgIGVsc2UKICAgICAgICBmcmFtZS0+RnVuY1RhYmxlRW50cnkgPSBOVUxMOwoKICAgIFRSQUNFKCJMZWF2ZTogUEM9JXMgRnJhbWU9JXMgUmV0dXJuPSVzIFN0YWNrPSVzIE1vZGU9JXMgY1N3aXRjaD0lMDh4IG5Td2l0Y2g9JTA4eCBGdW5jVGFibGU9JXBcbiIsCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclBDKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyRnJhbWUpLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJSZXR1cm4pLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJTdGFjayksIAogICAgICAgICAgY3Vycl9tb2RlID09IHN0bV9zdGFydCA/ICJzdGFydCIgOiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCA/ICIxNmJpdCIgOiAiMzJiaXQiKSwKICAgICAgICAgIGN1cnJfc3dpdGNoLCBuZXh0X3N3aXRjaCwgZnJhbWUtPkZ1bmNUYWJsZUVudHJ5KTsKCiAgICByZXR1cm4gVFJVRTsKZG9uZV9lcnI6CiAgICBjdXJyX21vZGUgPSBzdG1fZG9uZTsKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTdGFja1dhbGsgKERCR0hFTFAuQCkKICovCkJPT0wgV0lOQVBJIFN0YWNrV2FsayhEV09SRCBNYWNoaW5lVHlwZSwgSEFORExFIGhQcm9jZXNzLCBIQU5ETEUgaFRocmVhZCwKICAgICAgICAgICAgICAgICAgICAgIExQU1RBQ0tGUkFNRSBmcmFtZSwgUFZPSUQgY3R4LAogICAgICAgICAgICAgICAgICAgICAgUFJFQURfUFJPQ0VTU19NRU1PUllfUk9VVElORSBmX3JlYWRfbWVtLAogICAgICAgICAgICAgICAgICAgICAgUEZVTkNUSU9OX1RBQkxFX0FDQ0VTU19ST1VUSU5FIEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lLAogICAgICAgICAgICAgICAgICAgICAgUEdFVF9NT0RVTEVfQkFTRV9ST1VUSU5FIEdldE1vZHVsZUJhc2VSb3V0aW5lLAogICAgICAgICAgICAgICAgICAgICAgUFRSQU5TTEFURV9BRERSRVNTX1JPVVRJTkUgZl94bGF0X2FkcikKewogICAgc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sgIHN3Y2I7CgogICAgVFJBQ0UoIiglZCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwKVxuIiwKICAgICAgICAgIE1hY2hpbmVUeXBlLCBoUHJvY2VzcywgaFRocmVhZCwgZnJhbWUsIGN0eCwKICAgICAgICAgIGZfcmVhZF9tZW0sIEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lLAogICAgICAgICAgR2V0TW9kdWxlQmFzZVJvdXRpbmUsIGZfeGxhdF9hZHIpOwoKICAgIGlmIChNYWNoaW5lVHlwZSAhPSBJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBzd2NiLmhQcm9jZXNzID0gaFByb2Nlc3M7CiAgICBzd2NiLmhUaHJlYWQgPSBoVGhyZWFkOwogICAgc3djYi5pczMyID0gVFJVRTsKICAgIC8qIHNpZ2guLi4gTVMgaXNuJ3QgZXZlbiBjb25zaXN0ZW50IGluIHRoZSBmdW5jIHByb3RvdHlwZXMgKi8KICAgIHN3Y2IudS5zMzIuZl9yZWFkX21lbSA9IChmX3JlYWRfbWVtKSA/IGZfcmVhZF9tZW0gOiByZWFkX21lbTsKICAgIHN3Y2IudS5zMzIuZl94bGF0X2FkciA9IChmX3hsYXRfYWRyKSA/IGZfeGxhdF9hZHIgOiBhZGRyX3RvX2xpbmVhcjsKICAgIHN3Y2IudS5zMzIuZl90YWJsX2FjcyA9IChGdW5jdGlvblRhYmxlQWNjZXNzUm91dGluZSkgPyBGdW5jdGlvblRhYmxlQWNjZXNzUm91dGluZSA6IFN5bUZ1bmN0aW9uVGFibGVBY2Nlc3M7CiAgICBzd2NiLnUuczMyLmZfbW9kbF9iYXMgPSAoR2V0TW9kdWxlQmFzZVJvdXRpbmUpID8gR2V0TW9kdWxlQmFzZVJvdXRpbmUgOiBTeW1HZXRNb2R1bGVCYXNlOwoKICAgIHJldHVybiBzdGFja193YWxrKCZzd2NiLCBmcmFtZSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVN0YWNrV2FsazY0IChEQkdIRUxQLkApCiAqLwpCT09MIFdJTkFQSSBTdGFja1dhbGs2NChEV09SRCBNYWNoaW5lVHlwZSwgSEFORExFIGhQcm9jZXNzLCBIQU5ETEUgaFRocmVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgTFBTVEFDS0ZSQU1FNjQgZnJhbWU2NCwgUFZPSUQgY3R4LAogICAgICAgICAgICAgICAgICAgICAgICBQUkVBRF9QUk9DRVNTX01FTU9SWV9ST1VUSU5FNjQgZl9yZWFkX21lbSwKICAgICAgICAgICAgICAgICAgICAgICAgUEZVTkNUSU9OX1RBQkxFX0FDQ0VTU19ST1VUSU5FNjQgRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUsCiAgICAgICAgICAgICAgICAgICAgICAgIFBHRVRfTU9EVUxFX0JBU0VfUk9VVElORTY0IEdldE1vZHVsZUJhc2VSb3V0aW5lLAogICAgICAgICAgICAgICAgICAgICAgICBQVFJBTlNMQVRFX0FERFJFU1NfUk9VVElORTY0IGZfeGxhdF9hZHIpCnsKICAgIHN0cnVjdCBzdGFja193YWxrX2NhbGxiYWNrICBzd2NiOwogICAgU1RBQ0tGUkFNRSAgICAgICAgICAgICAgICAgIGZyYW1lMzI7CiAgICBCT09MICAgICAgICAgICAgICAgICAgICAgICAgcmV0OwoKICAgIFRSQUNFKCIoJWQsICVwLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcClcbiIsCiAgICAgICAgICBNYWNoaW5lVHlwZSwgaFByb2Nlc3MsIGhUaHJlYWQsIGZyYW1lNjQsIGN0eCwKICAgICAgICAgIGZfcmVhZF9tZW0sIEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lLAogICAgICAgICAgR2V0TW9kdWxlQmFzZVJvdXRpbmUsIGZfeGxhdF9hZHIpOwoKICAgIGlmIChNYWNoaW5lVHlwZSAhPSBJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBhZGRyXzY0dG8zMigmZnJhbWU2NC0+QWRkclBDLCAgICAgJmZyYW1lMzIuQWRkclBDKTsKICAgIGFkZHJfNjR0bzMyKCZmcmFtZTY0LT5BZGRyUmV0dXJuLCAmZnJhbWUzMi5BZGRyUmV0dXJuKTsKICAgIGFkZHJfNjR0bzMyKCZmcmFtZTY0LT5BZGRyRnJhbWUsICAmZnJhbWUzMi5BZGRyRnJhbWUpOwogICAgYWRkcl82NHRvMzIoJmZyYW1lNjQtPkFkZHJTdGFjaywgICZmcmFtZTMyLkFkZHJTdGFjayk7CiAgICBhZGRyXzY0dG8zMigmZnJhbWU2NC0+QWRkckJTdG9yZSwgJmZyYW1lMzIuQWRkckJTdG9yZSk7CiAgICBmcmFtZTMyLkZ1bmNUYWJsZUVudHJ5ID0gZnJhbWU2NC0+RnVuY1RhYmxlRW50cnk7IC8qIEZJWE1FICovCiAgICBmcmFtZTMyLkZhciA9IGZyYW1lNjQtPkZhcjsKICAgIGZyYW1lMzIuVmlydHVhbCA9IGZyYW1lNjQtPlZpcnR1YWw7CiAgICBmcmFtZTMyLlJlc2VydmVkWzBdID0gKFVMT05HKWZyYW1lNjQtPlJlc2VydmVkWzBdOwogICAgZnJhbWUzMi5SZXNlcnZlZFsxXSA9IChVTE9ORylmcmFtZTY0LT5SZXNlcnZlZFsxXTsKICAgIGZyYW1lMzIuUmVzZXJ2ZWRbMl0gPSAoVUxPTkcpZnJhbWU2NC0+UmVzZXJ2ZWRbMl07CiAgICAvKiB3ZSBkb24ndCBoYW5kbGUgS2RIZWxwICovCgogICAgc3djYi5oUHJvY2VzcyA9IGhQcm9jZXNzOwogICAgc3djYi5oVGhyZWFkID0gaFRocmVhZDsKICAgIHN3Y2IuaXMzMiA9IEZBTFNFOwogICAgLyogc2lnaC4uLiBNUyBpc24ndCBldmVuIGNvbnNpc3RlbnQgaW4gdGhlIGZ1bmMgcHJvdG90eXBlcyAqLwogICAgc3djYi51LnM2NC5mX3JlYWRfbWVtID0gKGZfcmVhZF9tZW0pID8gZl9yZWFkX21lbSA6IHJlYWRfbWVtNjQ7CiAgICBzd2NiLnUuczY0LmZfeGxhdF9hZHIgPSBmX3hsYXRfYWRyOwogICAgc3djYi51LnM2NC5mX3RhYmxfYWNzID0gKEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lKSA/IEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lIDogU3ltRnVuY3Rpb25UYWJsZUFjY2VzczY0OwogICAgc3djYi51LnM2NC5mX21vZGxfYmFzID0gKEdldE1vZHVsZUJhc2VSb3V0aW5lKSA/IEdldE1vZHVsZUJhc2VSb3V0aW5lIDogU3ltR2V0TW9kdWxlQmFzZTY0OwoKICAgIHJldCA9IHN0YWNrX3dhbGsoJnN3Y2IsICZmcmFtZTMyKTsKCiAgICBhZGRyXzMydG82NCgmZnJhbWUzMi5BZGRyUEMsICAgICAmZnJhbWU2NC0+QWRkclBDKTsKICAgIGFkZHJfMzJ0bzY0KCZmcmFtZTMyLkFkZHJSZXR1cm4sICZmcmFtZTY0LT5BZGRyUmV0dXJuKTsKICAgIGFkZHJfMzJ0bzY0KCZmcmFtZTMyLkFkZHJGcmFtZSwgICZmcmFtZTY0LT5BZGRyRnJhbWUpOwogICAgYWRkcl8zMnRvNjQoJmZyYW1lMzIuQWRkclN0YWNrLCAgJmZyYW1lNjQtPkFkZHJTdGFjayk7CiAgICBhZGRyXzMydG82NCgmZnJhbWUzMi5BZGRyQlN0b3JlLCAmZnJhbWU2NC0+QWRkckJTdG9yZSk7CiAgICBmcmFtZTY0LT5GdW5jVGFibGVFbnRyeSA9IGZyYW1lMzIuRnVuY1RhYmxlRW50cnk7IC8qIEZJWE1FICovCiAgICBmcmFtZTY0LT5QYXJhbXNbMF0gPSBmcmFtZTMyLlBhcmFtc1swXTsKICAgIGZyYW1lNjQtPlBhcmFtc1sxXSA9IGZyYW1lMzIuUGFyYW1zWzFdOwogICAgZnJhbWU2NC0+UGFyYW1zWzJdID0gZnJhbWUzMi5QYXJhbXNbMl07CiAgICBmcmFtZTY0LT5QYXJhbXNbM10gPSBmcmFtZTMyLlBhcmFtc1szXTsKICAgIGZyYW1lNjQtPkZhciA9IGZyYW1lMzIuRmFyOwogICAgZnJhbWU2NC0+VmlydHVhbCA9IGZyYW1lMzIuVmlydHVhbDsKICAgIGZyYW1lNjQtPlJlc2VydmVkWzBdID0gZnJhbWUzMi5SZXNlcnZlZFswXTsKICAgIGZyYW1lNjQtPlJlc2VydmVkWzFdID0gZnJhbWUzMi5SZXNlcnZlZFsxXTsKICAgIGZyYW1lNjQtPlJlc2VydmVkWzJdID0gZnJhbWUzMi5SZXNlcnZlZFsyXTsKICAgIC8qIHdlIGRvbid0IGhhbmRsZSBLZEhlbHAgKi8KICAgIGZyYW1lNjQtPktkSGVscC5UaHJlYWQgPSAweEMwMDBGQURFOwogICAgZnJhbWU2NC0+S2RIZWxwLlRoQ2FsbGJhY2tTdGFjayA9IDB4MTA7CiAgICBmcmFtZTY0LT5LZEhlbHAuVGhDYWxsYmFja0JTdG9yZSA9IDA7CiAgICBmcmFtZTY0LT5LZEhlbHAuTmV4dENhbGxiYWNrID0gMDsKICAgIGZyYW1lNjQtPktkSGVscC5GcmFtZVBvaW50ZXIgPSAwOwogICAgZnJhbWU2NC0+S2RIZWxwLktpQ2FsbFVzZXJNb2RlID0gMHhEMDAwREFGRTsKICAgIGZyYW1lNjQtPktkSGVscC5LZVVzZXJDYWxsYmFja0Rpc3BhdGNoZXIgPSAweEUwMDBGMDAwOwogICAgZnJhbWU2NC0+S2RIZWxwLlN5c3RlbVJhbmdlU3RhcnQgPSAweEMwMDAwMDAwOwogICAgZnJhbWU2NC0+S2RIZWxwLlJlc2VydmVkWzBdIC8qIEtpVXNlckV4Y2VwdGlvbkRpc3BhdGNoZXIgKi8gPSAweEUwMDA1MDAwOwoKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVN5bVJlZ2lzdGVyRnVuY3Rpb25FbnRyeUNhbGxiYWNrIChEQkdIRUxQLkApCiAqCiAqCiAqLwpCT09MIFdJTkFQSSBTeW1SZWdpc3RlckZ1bmN0aW9uRW50cnlDYWxsYmFjayhIQU5ETEUgaFByb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTWU1CT0xfRlVOQ0VOVFJZX0NBTExCQUNLIGNiLCBQVk9JRCB1c2VyKQp7CiAgICBGSVhNRSgiKCVwICVwICVwKTogc3R1YiFcbiIsIGhQcm9jLCBjYiwgdXNlcik7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfQ0FMTF9OT1RfSU1QTEVNRU5URUQpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTeW1SZWdpc3RlckZ1bmN0aW9uRW50cnlDYWxsYmFjazY0IChEQkdIRUxQLkApCiAqCiAqCiAqLwpCT09MIFdJTkFQSSBTeW1SZWdpc3RlckZ1bmN0aW9uRW50cnlDYWxsYmFjazY0KEhBTkRMRSBoUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU1lNQk9MX0ZVTkNFTlRSWV9DQUxMQkFDSzY0IGNiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HNjQgdXNlcikKewogICAgRklYTUUoIiglcCAlcCAlcyk6IHN0dWIhXG4iLCBoUHJvYywgY2IsIHdpbmVfZGJnc3RyX2xvbmdsb25nKHVzZXIpKTsKICAgIFNldExhc3RFcnJvcihFUlJPUl9DQUxMX05PVF9JTVBMRU1FTlRFRCk7CiAgICByZXR1cm4gRkFMU0U7Cn0K