LyoKICogU3RhY2sgd2Fsa2luZwogKgogKiBDb3B5cmlnaHQgMTk5NSBBbGV4YW5kcmUgSnVsbGlhcmQKICogQ29weXJpZ2h0IDE5OTYgRXJpYyBZb3VuZ2RhbGUKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqIENvcHlyaWdodCAyMDA0IEVyaWMgUG91ZWNoCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAibnRzdGF0dXMuaCIKI2RlZmluZSBXSU4zMl9OT19TVEFUVVMKI2luY2x1ZGUgImRiZ2hlbHBfcHJpdmF0ZS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRiZ2hlbHApOwoKZW51bSBzdF9tb2RlIHtzdG1fc3RhcnQsIHN0bV8zMmJpdCwgc3RtXzE2Yml0LCBzdG1fZG9uZX07CgpzdGF0aWMgY29uc3QgY2hhciogd2luZV9kYmdzdHJfYWRkcihjb25zdCBBRERSRVNTKiBhZGRyKQp7CiAgICBpZiAoIWFkZHIpIHJldHVybiAiKG51bGwpIjsKICAgIHN3aXRjaCAoYWRkci0+TW9kZSkKICAgIHsKICAgIGNhc2UgQWRkck1vZGVGbGF0OgogICAgICAgIHJldHVybiB3aW5lX2RiZ19zcHJpbnRmKCJmbGF0PCUwOGx4PiIsIGFkZHItPk9mZnNldCk7CiAgICBjYXNlIEFkZHJNb2RlMTYxNjoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigiMTYxNjwlMDR4OiUwNGx4PiIsIGFkZHItPlNlZ21lbnQsIGFkZHItPk9mZnNldCk7CiAgICBjYXNlIEFkZHJNb2RlMTYzMjoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigiMTYzMjwlMDR4OiUwOGx4PiIsIGFkZHItPlNlZ21lbnQsIGFkZHItPk9mZnNldCk7CiAgICBjYXNlIEFkZHJNb2RlUmVhbDoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigicmVhbDwlMDR4OiUwNGx4PiIsIGFkZHItPlNlZ21lbnQsIGFkZHItPk9mZnNldCk7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiAidW5rbm93biI7CiAgICB9Cn0KCnN0YXRpYyBCT09MIENBTExCQUNLIHJlYWRfbWVtKEhBTkRMRSBoUHJvY2VzcywgRFdPUkQgYWRkciwgdm9pZCogYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBzaXplLCBMUERXT1JEIG5yZWFkKQp7CiAgICByZXR1cm4gUmVhZFByb2Nlc3NNZW1vcnkoaFByb2Nlc3MsICh2b2lkKilhZGRyLCBidWZmZXIsIHNpemUsIG5yZWFkKTsKfQoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgcmVhZF9tZW02NChIQU5ETEUgaFByb2Nlc3MsIERXT1JENjQgYWRkciwgdm9pZCogYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHNpemUsIExQRFdPUkQgbnJlYWQpCnsKICAgIHJldHVybiBSZWFkUHJvY2Vzc01lbW9yeShoUHJvY2VzcywgKHZvaWQqKShEV09SRF9QVFIpYWRkciwgYnVmZmVyLCBzaXplLCBucmVhZCk7Cn0KCi8qIGluZGV4ZXMgaW4gUmVzZXJ2ZWQgYXJyYXkgKi8KI2RlZmluZSBfX0N1cnJlbnRNb2RlICAgICAwCiNkZWZpbmUgX19DdXJyZW50U3dpdGNoICAgMQojZGVmaW5lIF9fTmV4dFN3aXRjaCAgICAgIDIKCiNkZWZpbmUgY3Vycl9tb2RlICAgKGZyYW1lLT5SZXNlcnZlZFtfX0N1cnJlbnRNb2RlXSkKI2RlZmluZSBjdXJyX3N3aXRjaCAoZnJhbWUtPlJlc2VydmVkW19fQ3VycmVudFN3aXRjaF0pCiNkZWZpbmUgbmV4dF9zd2l0Y2ggKGZyYW1lLT5SZXNlcnZlZFtfX05leHRTd2l0Y2hdKQoKc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sKewogICAgSEFORExFICAgICAgaFByb2Nlc3M7CiAgICBIQU5ETEUgICAgICBoVGhyZWFkOwogICAgQk9PTCAgICAgICAgaXMzMjsKICAgIHVuaW9uCiAgICB7CiAgICAgICAgc3RydWN0CiAgICAgICAgewogICAgICAgICAgICBQUkVBRF9QUk9DRVNTX01FTU9SWV9ST1VUSU5FICAgICAgICBmX3JlYWRfbWVtOwogICAgICAgICAgICBQVFJBTlNMQVRFX0FERFJFU1NfUk9VVElORSAgICAgICAgICBmX3hsYXRfYWRyOwogICAgICAgICAgICBQRlVOQ1RJT05fVEFCTEVfQUNDRVNTX1JPVVRJTkUgICAgICBmX3RhYmxfYWNzOwogICAgICAgICAgICBQR0VUX01PRFVMRV9CQVNFX1JPVVRJTkUgICAgICAgICAgICBmX21vZGxfYmFzOwogICAgICAgIH0gczMyOwogICAgICAgIHN0cnVjdAogICAgICAgIHsKICAgICAgICAgICAgUFJFQURfUFJPQ0VTU19NRU1PUllfUk9VVElORTY0ICAgICAgZl9yZWFkX21lbTsKICAgICAgICAgICAgUFRSQU5TTEFURV9BRERSRVNTX1JPVVRJTkU2NCAgICAgICAgZl94bGF0X2FkcjsKICAgICAgICAgICAgUEZVTkNUSU9OX1RBQkxFX0FDQ0VTU19ST1VUSU5FNjQgICAgZl90YWJsX2FjczsKICAgICAgICAgICAgUEdFVF9NT0RVTEVfQkFTRV9ST1VUSU5FNjQgICAgICAgICAgZl9tb2RsX2JhczsKICAgICAgICB9IHM2NDsKICAgIH0gdTsKfTsKCnN0YXRpYyBpbmxpbmUgdm9pZCBhZGRyXzMydG82NChjb25zdCBBRERSRVNTKiBhZGRyMzIsIEFERFJFU1M2NCogYWRkcjY0KQp7CiAgICBhZGRyNjQtPk9mZnNldCA9IChVTE9ORzY0KWFkZHIzMi0+T2Zmc2V0OwogICAgYWRkcjY0LT5TZWdtZW50ID0gYWRkcjMyLT5TZWdtZW50OwogICAgYWRkcjY0LT5Nb2RlID0gYWRkcjMyLT5Nb2RlOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgYWRkcl82NHRvMzIoY29uc3QgQUREUkVTUzY0KiBhZGRyNjQsIEFERFJFU1MqIGFkZHIzMikKewogICAgYWRkcjMyLT5PZmZzZXQgPSAoVUxPTkcpYWRkcjY0LT5PZmZzZXQ7CiAgICBhZGRyMzItPlNlZ21lbnQgPSBhZGRyNjQtPlNlZ21lbnQ7CiAgICBhZGRyMzItPk1vZGUgPSBhZGRyNjQtPk1vZGU7Cn0KCnN0YXRpYyBpbmxpbmUgQk9PTCBzd19yZWFkX21lbShzdHJ1Y3Qgc3RhY2tfd2Fsa19jYWxsYmFjayogY2IsIERXT1JEIGFkZHIsIHZvaWQqIHB0ciwgRFdPUkQgc3opCnsKICAgIGlmIChjYi0+aXMzMikKICAgICAgICByZXR1cm4gY2ItPnUuczMyLmZfcmVhZF9tZW0oY2ItPmhQcm9jZXNzLCBhZGRyLCBwdHIsIHN6LCBOVUxMKTsKICAgIGVsc2UKICAgICAgICByZXR1cm4gY2ItPnUuczY0LmZfcmVhZF9tZW0oY2ItPmhQcm9jZXNzLCBhZGRyLCBwdHIsIHN6LCBOVUxMKTsKfQoKc3RhdGljIGlubGluZSBEV09SRCBzd194bGF0X2FkZHIoc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sqIGNiLCBBRERSRVNTKiBhZGRyKQp7CiAgICBpZiAoYWRkci0+TW9kZSA9PSBBZGRyTW9kZUZsYXQpIHJldHVybiBhZGRyLT5PZmZzZXQ7CiAgICBpZiAoY2ItPmlzMzIpIHJldHVybiBjYi0+dS5zMzIuZl94bGF0X2FkcihjYi0+aFByb2Nlc3MsIGNiLT5oVGhyZWFkLCBhZGRyKTsKICAgIGlmIChjYi0+dS5zNjQuZl94bGF0X2FkcikKICAgIHsKICAgICAgICBBRERSRVNTNjQgICAgICAgYWRkcjY0OwoKICAgICAgICBhZGRyXzMydG82NChhZGRyLCAmYWRkcjY0KTsKICAgICAgICByZXR1cm4gY2ItPnUuczY0LmZfeGxhdF9hZHIoY2ItPmhQcm9jZXNzLCBjYi0+aFRocmVhZCwgJmFkZHI2NCk7CiAgICB9CiAgICByZXR1cm4gYWRkcl90b19saW5lYXIoY2ItPmhQcm9jZXNzLCBjYi0+aFRocmVhZCwgYWRkcik7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCogc3dfdGFibF9hY3Moc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sqIGNiLCBEV09SRCBhZGRyKQp7CiAgICBpZiAoY2ItPmlzMzIpCiAgICAgICAgcmV0dXJuIGNiLT51LnMzMi5mX3RhYmxfYWNzKGNiLT5oUHJvY2VzcywgYWRkcik7CiAgICBlbHNlCiAgICAgICAgcmV0dXJuIGNiLT51LnM2NC5mX3RhYmxfYWNzKGNiLT5oUHJvY2VzcywgYWRkcik7Cn0KCnN0YXRpYyBpbmxpbmUgRFdPUkQgc3dfbW9kbF9iYXMoc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sqIGNiLCBEV09SRCBhZGRyKQp7CiAgICBpZiAoY2ItPmlzMzIpCiAgICAgICAgcmV0dXJuIGNiLT51LnMzMi5mX21vZGxfYmFzKGNiLT5oUHJvY2VzcywgYWRkcik7CiAgICBlbHNlCiAgICAgICAgcmV0dXJuIGNiLT51LnM2NC5mX21vZGxfYmFzKGNiLT5oUHJvY2VzcywgYWRkcik7Cn0KCnN0YXRpYyBCT09MIHN0YWNrX3dhbGsoc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sqIGNiLCBMUFNUQUNLRlJBTUUgZnJhbWUpCnsKICAgIFNUQUNLMzJGUkFNRSAgICAgICAgZnJhbWUzMjsKICAgIFNUQUNLMTZGUkFNRSAgICAgICAgZnJhbWUxNjsKICAgIGNoYXIgICAgICAgICAgICAgICAgY2g7CiAgICBBRERSRVNTICAgICAgICAgICAgIHRtcDsKICAgIERXT1JEICAgICAgICAgICAgICAgcDsKICAgIFdPUkQgICAgICAgICAgICAgICAgdmFsOwogICAgQk9PTCAgICAgICAgICAgICAgICBkb19zd2l0Y2g7CgogICAgLyogc2FuaXR5IGNoZWNrICovCiAgICBpZiAoY3Vycl9tb2RlID49IHN0bV9kb25lKSByZXR1cm4gRkFMU0U7CgogICAgVFJBQ0UoIkVudGVyOiBQQz0lcyBGcmFtZT0lcyBSZXR1cm49JXMgU3RhY2s9JXMgTW9kZT0lcyBjU3dpdGNoPSUwOGx4IG5Td2l0Y2g9JTA4bHhcbiIsCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclBDKSwgCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUmV0dXJuKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyU3RhY2spLCAKICAgICAgICAgIGN1cnJfbW9kZSA9PSBzdG1fc3RhcnQgPyAic3RhcnQiIDogKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQgPyAiMTZiaXQiIDogIjMyYml0IiksCiAgICAgICAgICBjdXJyX3N3aXRjaCwgbmV4dF9zd2l0Y2gpOwoKICAgIGlmIChjdXJyX21vZGUgPT0gc3RtX3N0YXJ0KQogICAgewogICAgICAgIFRIUkVBRF9CQVNJQ19JTkZPUk1BVElPTiBpbmZvOwoKICAgICAgICBpZiAoKGZyYW1lLT5BZGRyUEMuTW9kZSA9PSBBZGRyTW9kZUZsYXQpICYmCiAgICAgICAgICAgIChmcmFtZS0+QWRkckZyYW1lLk1vZGUgIT0gQWRkck1vZGVGbGF0KSkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIkJhZCBBZGRyUEMuTW9kZSAvIEFkZHJGcmFtZS5Nb2RlIGNvbWJpbmF0aW9uXG4iKTsKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICB9CgogICAgICAgIC8qIEluaXQgZG9uZSAqLwogICAgICAgIGN1cnJfbW9kZSA9IChmcmFtZS0+QWRkclBDLk1vZGUgPT0gQWRkck1vZGVGbGF0KSA/IAogICAgICAgICAgICBzdG1fMzJiaXQgOiBzdG1fMTZiaXQ7CgogICAgICAgIC8qIGN1cl9zd2l0Y2ggaG9sZHMgYWRkcmVzcyBvZiBXT1czMlJlc2VydmVkIGZpZWxkIGluIFRFQiBpbiBkZWJ1Z2dlZQogICAgICAgICAqIGFkZHJlc3Mgc3BhY2UKICAgICAgICAgKi8KICAgICAgICBpZiAoTnRRdWVyeUluZm9ybWF0aW9uVGhyZWFkKGNiLT5oVGhyZWFkLCBUaHJlYWRCYXNpY0luZm9ybWF0aW9uLCAmaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihpbmZvKSwgTlVMTCkgPT0gU1RBVFVTX1NVQ0NFU1MpCiAgICAgICAgewogICAgICAgICAgICBjdXJyX3N3aXRjaCA9ICh1bnNpZ25lZCBsb25nKWluZm8uVGViQmFzZUFkZHJlc3MgKyBGSUVMRF9PRkZTRVQoVEVCLCBXT1czMlJlc2VydmVkKTsKICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgY3Vycl9zd2l0Y2gsICZuZXh0X3N3aXRjaCwgc2l6ZW9mKG5leHRfc3dpdGNoKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdBUk4oIkNhbid0IHJlYWQgVEVCOldPVzMyUmVzZXJ2ZWRcbiIpOwogICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoZnJhbWUzMikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMzIuZnJhbWUxNjsKICAgICAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgdG1wLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKGN1cnJfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YoY3Vycl9zd2l0Y2gpOwogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgc3dfeGxhdF9hZGRyKGNiLCAmdG1wKSwgJmNoLCBzaXplb2YoY2gpKSkKICAgICAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0bXAuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHAgPSBzd194bGF0X2FkZHIoY2IsICZ0bXApOwogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgcCwgJmZyYW1lMTYsIHNpemVvZihmcmFtZTE2KSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIHApOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IChEV09SRClmcmFtZTE2LmZyYW1lMzI7CgogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgY3Vycl9zd2l0Y2gsICZjaCwgc2l6ZW9mKGNoKSkpCiAgICAgICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAweEZGRkZGRkZGOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgLyogRklYTUU6IHRoaXMgd2lsbCBhbGxvdyB0byB3b3JrIHdoZW4gd2UncmUgbm90IGF0dGFjaGVkIHRvIGEgbGl2ZSB0YXJnZXQsIAogICAgICAgICAgICAgKiBidXQgdGhlIDE2IDw9PiAzMiBzd2l0Y2ggZmFjaWxpdHkgd29uJ3QgYmUgYXZhaWxhYmxlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAwOwogICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgPSBmcmFtZS0+QWRkclN0YWNrLk1vZGUgPSAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkgPyBBZGRyTW9kZTE2MTYgOiBBZGRyTW9kZUZsYXQ7CiAgICAgICAgLyogZG9uJ3Qgc2V0IHVwIEFkZHJTdGFjayBvbiBmaXJzdCBjYWxsLiBFaXRoZXIgdGhlIGNhbGxlciBoYXMgc2V0IGl0IHVwLCBvcgogICAgICAgICAqIHdlIHdpbGwgZ2V0IGl0IGluIHRoZSBuZXh0IGZyYW1lCiAgICAgICAgICovCiAgICAgICAgbWVtc2V0KCZmcmFtZS0+QWRkckJTdG9yZSwgMCwgc2l6ZW9mKGZyYW1lLT5BZGRyQlN0b3JlKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID09IDApIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgaWYgKGZyYW1lLT5BZGRyRnJhbWUuTW9kZSA9PSBBZGRyTW9kZUZsYXQpCiAgICAgICAgewogICAgICAgICAgICBhc3NlcnQoY3Vycl9tb2RlID09IHN0bV8zMmJpdCk7CiAgICAgICAgICAgIGRvX3N3aXRjaCA9IGN1cnJfc3dpdGNoICYmIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID49IGN1cnJfc3dpdGNoOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBhc3NlcnQoY3Vycl9tb2RlID09IHN0bV8xNmJpdCk7CiAgICAgICAgICAgIGRvX3N3aXRjaCA9IGN1cnJfc3dpdGNoICYmIAogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5TZWdtZW50ID09IFNFTEVDVE9ST0YoY3Vycl9zd2l0Y2gpICYmCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA+PSBPRkZTRVRPRihjdXJyX3N3aXRjaCk7CiAgICAgICAgfQoJICAgCiAgICAgICAgaWYgKGRvX3N3aXRjaCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBuZXh0X3N3aXRjaCwgJmZyYW1lMzIsIHNpemVvZihmcmFtZTMyKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuTW9kZSAgICAgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLlNlZ21lbnQgICAgID0gMDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuT2Zmc2V0ICAgICAgPSBmcmFtZTMyLnJldGFkZHI7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk1vZGUgICAgID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5TZWdtZW50ICA9IDA7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAgID0gZnJhbWUzMi5lYnA7CgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5Nb2RlICAgICA9IEFkZHJNb2RlRmxhdDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suU2VnbWVudCAgPSAwOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uTW9kZSAgICA9IEFkZHJNb2RlRmxhdDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLlNlZ21lbnQgPSAwOwoKICAgICAgICAgICAgICAgIG5leHRfc3dpdGNoID0gY3Vycl9zd2l0Y2g7CiAgICAgICAgICAgICAgICB0bXAuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHAgPSBzd194bGF0X2FkZHIoY2IsICZ0bXApOwoKICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIHAsICZmcmFtZTE2LCBzaXplb2YoZnJhbWUxNikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBwKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUxNi5mcmFtZTMyOwogICAgICAgICAgICAgICAgY3Vycl9tb2RlID0gc3RtXzMyYml0OwogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgY3Vycl9zd2l0Y2gsICZjaCwgc2l6ZW9mKGNoKSkpCiAgICAgICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBwID0gc3dfeGxhdF9hZGRyKGNiLCAmdG1wKTsKCiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBwLCAmZnJhbWUxNiwgc2l6ZW9mKGZyYW1lMTYpKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgcCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBUUkFDRSgiR290IGEgMTYgYml0IHN0YWNrIHN3aXRjaDoiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGZyYW1lMzI6ICUwOGx4IgogICAgICAgICAgICAgICAgICAgICAgIlxuXHRlZHg6JTA4bHggZWN4OiUwOGx4IGVicDolMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZHM6JTA0eCBlczolMDR4IGZzOiUwNHggZ3M6JTA0eCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0Y2FsbF9mcm9tX2lwOiUwOGx4IG1vZHVsZV9jczolMDRseCByZWxheT0lMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZW50cnlfaXA6JTA0eCBlbnRyeV9wb2ludDolMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0YnA6JTA0eCBpcDolMDR4IGNzOiUwNHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZylmcmFtZTE2LmZyYW1lMzIsCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmVkeCwgZnJhbWUxNi5lY3gsIGZyYW1lMTYuZWJwLAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5kcywgZnJhbWUxNi5lcywgZnJhbWUxNi5mcywgZnJhbWUxNi5ncywKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuY2FsbGZyb21faXAsIGZyYW1lMTYubW9kdWxlX2NzLCBmcmFtZTE2LnJlbGF5LAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5lbnRyeV9pcCwgZnJhbWUxNi5lbnRyeV9wb2ludCwKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuYnAsIGZyYW1lMTYuaXAsIGZyYW1lMTYuY3MpOwoKICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5Nb2RlICAgICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5TZWdtZW50ICAgID0gZnJhbWUxNi5jczsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuT2Zmc2V0ICAgICA9IGZyYW1lMTYuaXA7CgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAgPSBmcmFtZTE2LmJwOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gZnJhbWUxNi5jczsKCiAgICAgICAgICAgICAgICBuZXh0X3N3aXRjaCA9IGN1cnJfc3dpdGNoOwogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoZnJhbWUzMikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMzIuZnJhbWUxNjsKICAgICAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgdG1wLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKGN1cnJfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YoY3Vycl9zd2l0Y2gpOwoKICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIHN3X3hsYXRfYWRkcihjYiwgJnRtcCksICZjaCwgc2l6ZW9mKGNoKSkpCiAgICAgICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAwOwogICAgICAgICAgICAgICAgY3Vycl9tb2RlID0gc3RtXzE2Yml0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMgPSBmcmFtZS0+QWRkclJldHVybjsKICAgICAgICAgICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suT2Zmc2V0ID0gZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKFdPUkQpOwogICAgICAgICAgICAgICAgLyogInBvcCB1cCIgcHJldmlvdXMgQlAgdmFsdWUgKi8KICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIHN3X3hsYXRfYWRkcihjYiwgJmZyYW1lLT5BZGRyRnJhbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdmFsLCBzaXplb2YoV09SRCkpKQogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA9IHZhbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suT2Zmc2V0ID0gZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIC8qICJwb3AgdXAiIHByZXZpb3VzIEVCUCB2YWx1ZSAqLwogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQsIHNpemVvZihEV09SRCkpKQogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpCiAgICB7CiAgICAgICAgaW50ICAgICBpOwoKICAgICAgICBwID0gc3dfeGxhdF9hZGRyKGNiLCAmZnJhbWUtPkFkZHJGcmFtZSk7CiAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgcCArIHNpemVvZihXT1JEKSwgJnZhbCwgc2l6ZW9mKFdPUkQpKSkKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICBmcmFtZS0+QWRkclJldHVybi5PZmZzZXQgPSB2YWw7CiAgICAgICAgLyogZ2V0IHBvdGVudGlhbCBjcyBpZiBhIGZhciBjYWxsIHdhcyB1c2VkICovCiAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgcCArIDIgKiBzaXplb2YoV09SRCksICZ2YWwsIHNpemVvZihXT1JEKSkpCiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgaWYgKGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICYgMSkKICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCA9IHZhbDsgLyogZmFyIGNhbGwgYXNzdW1lZCAqLwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIG5vdCBleHBsaWNpdGx5IG1hcmtlZCBhcyBmYXIgY2FsbCwgCiAgICAgICAgICAgICAqIGJ1dCBjaGVjayB3aGV0aGVyIGl0IGNvdWxkIGJlIGFueXdheQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCh2YWwgJiA3KSA9PSA3ICYmIHZhbCAhPSBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBMRFRfRU5UUlkJbGU7CgogICAgICAgICAgICAgICAgaWYgKEdldFRocmVhZFNlbGVjdG9yRW50cnkoY2ItPmhUaHJlYWQsIHZhbCwgJmxlKSAmJgogICAgICAgICAgICAgICAgICAgIChsZS5IaWdoV29yZC5CaXRzLlR5cGUgJiAweDA4KSkgLyogY29kZSBzZWdtZW50ICovCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogaXQgaXMgdmVyeSB1bmNvbW1vbiB0byBwdXNoIGEgY29kZSBzZWdtZW50IGNzIGFzCiAgICAgICAgICAgICAgICAgICAgICogYSBwYXJhbWV0ZXIsIHNvIHRoaXMgc2hvdWxkIHdvcmsgaW4gbW9zdCBjYXNlcyAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gdmFsOwogICAgICAgICAgICAgICAgfQoJICAgIH0KCX0KICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAmPSB+MTsKICAgICAgICAvKiB3ZSAicG9wIiBwYXJhbWV0ZXJzIGFzIDE2IGJpdCBlbnRpdGllcy4uLiBvZiBjb3Vyc2UsIHRoaXMgd29uJ3QKICAgICAgICAgKiB3b3JrIGlmIHRoZSBwYXJhbWV0ZXIgaXMgaW4gZmFjdCBiaWdnZXIgdGhhbiAxNmJpdCwgYnV0CiAgICAgICAgICogdGhlcmUncyBubyB3YXkgdG8ga25vdyB0aGF0IGhlcmUKICAgICAgICAgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZW9mKGZyYW1lLT5QYXJhbXMpIC8gc2l6ZW9mKGZyYW1lLT5QYXJhbXNbMF0pOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBzd19yZWFkX21lbShjYiwgcCArICgyICsgaSkgKiBzaXplb2YoV09SRCksICZ2YWwsIHNpemVvZih2YWwpKTsKICAgICAgICAgICAgZnJhbWUtPlBhcmFtc1tpXSA9IHZhbDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyBzaXplb2YoRFdPUkQpLAogICAgICAgICAgICAgICAgICAgICAgICAgJmZyYW1lLT5BZGRyUmV0dXJuLk9mZnNldCwgc2l6ZW9mKERXT1JEKSkpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJDYW5ub3QgcmVhZCBuZXcgZnJhbWUgb2Zmc2V0ICUwOGx4XG4iLCBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIHNpemVvZihEV09SRCkpOwogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIH0KICAgICAgICBzd19yZWFkX21lbShjYiwgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKSwgCiAgICAgICAgICAgICAgICAgICAgZnJhbWUtPlBhcmFtcywgc2l6ZW9mKGZyYW1lLT5QYXJhbXMpKTsKICAgIH0KCiAgICBmcmFtZS0+RmFyID0gVFJVRTsKICAgIGZyYW1lLT5WaXJ0dWFsID0gVFJVRTsKICAgIHAgPSBzd194bGF0X2FkZHIoY2IsICZmcmFtZS0+QWRkclBDKTsKICAgIGlmIChwICYmIHN3X21vZGxfYmFzKGNiLCBwKSkKICAgICAgICBmcmFtZS0+RnVuY1RhYmxlRW50cnkgPSBzd190YWJsX2FjcyhjYiwgcCk7CiAgICBlbHNlCiAgICAgICAgZnJhbWUtPkZ1bmNUYWJsZUVudHJ5ID0gTlVMTDsKCiAgICBUUkFDRSgiTGVhdmU6IFBDPSVzIEZyYW1lPSVzIFJldHVybj0lcyBTdGFjaz0lcyBNb2RlPSVzIGNTd2l0Y2g9JTA4bHggblN3aXRjaD0lMDhseCBGdW5jVGFibGU9JXBcbiIsCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclBDKSwgCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUmV0dXJuKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyU3RhY2spLCAKICAgICAgICAgIGN1cnJfbW9kZSA9PSBzdG1fc3RhcnQgPyAic3RhcnQiIDogKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQgPyAiMTZiaXQiIDogIjMyYml0IiksCiAgICAgICAgICBjdXJyX3N3aXRjaCwgbmV4dF9zd2l0Y2gsIGZyYW1lLT5GdW5jVGFibGVFbnRyeSk7CgogICAgcmV0dXJuIFRSVUU7CmRvbmVfZXJyOgogICAgY3Vycl9tb2RlID0gc3RtX2RvbmU7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU3RhY2tXYWxrIChEQkdIRUxQLkApCiAqLwpCT09MIFdJTkFQSSBTdGFja1dhbGsoRFdPUkQgTWFjaGluZVR5cGUsIEhBTkRMRSBoUHJvY2VzcywgSEFORExFIGhUaHJlYWQsCiAgICAgICAgICAgICAgICAgICAgICBMUFNUQUNLRlJBTUUgZnJhbWUsIExQVk9JRCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICBQUkVBRF9QUk9DRVNTX01FTU9SWV9ST1VUSU5FIGZfcmVhZF9tZW0sCiAgICAgICAgICAgICAgICAgICAgICBQRlVOQ1RJT05fVEFCTEVfQUNDRVNTX1JPVVRJTkUgRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUsCiAgICAgICAgICAgICAgICAgICAgICBQR0VUX01PRFVMRV9CQVNFX1JPVVRJTkUgR2V0TW9kdWxlQmFzZVJvdXRpbmUsCiAgICAgICAgICAgICAgICAgICAgICBQVFJBTlNMQVRFX0FERFJFU1NfUk9VVElORSBmX3hsYXRfYWRyKQp7CiAgICBzdHJ1Y3Qgc3RhY2tfd2Fsa19jYWxsYmFjayAgc3djYjsKCiAgICBUUkFDRSgiKCVsZCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwKVxuIiwKICAgICAgICAgIE1hY2hpbmVUeXBlLCBoUHJvY2VzcywgaFRocmVhZCwgZnJhbWUsIGN0eCwKICAgICAgICAgIGZfcmVhZF9tZW0sIEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lLAogICAgICAgICAgR2V0TW9kdWxlQmFzZVJvdXRpbmUsIGZfeGxhdF9hZHIpOwoKICAgIGlmIChNYWNoaW5lVHlwZSAhPSBJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBzd2NiLmhQcm9jZXNzID0gaFByb2Nlc3M7CiAgICBzd2NiLmhUaHJlYWQgPSBoVGhyZWFkOwogICAgc3djYi5pczMyID0gVFJVRTsKICAgIC8qIHNpZ2guLi4gTVMgaXNuJ3QgZXZlbiBjb25zaXN0ZW50IGluIHRoZSBmdW5jIHByb3RvdHlwZXMgKi8KICAgIHN3Y2IudS5zMzIuZl9yZWFkX21lbSA9IChmX3JlYWRfbWVtKSA/IGZfcmVhZF9tZW0gOiByZWFkX21lbTsKICAgIHN3Y2IudS5zMzIuZl94bGF0X2FkciA9IChmX3hsYXRfYWRyKSA/IGZfeGxhdF9hZHIgOiBhZGRyX3RvX2xpbmVhcjsKICAgIHN3Y2IudS5zMzIuZl90YWJsX2FjcyA9IChGdW5jdGlvblRhYmxlQWNjZXNzUm91dGluZSkgPyBGdW5jdGlvblRhYmxlQWNjZXNzUm91dGluZSA6IFN5bUZ1bmN0aW9uVGFibGVBY2Nlc3M7CiAgICBzd2NiLnUuczMyLmZfbW9kbF9iYXMgPSAoR2V0TW9kdWxlQmFzZVJvdXRpbmUpID8gR2V0TW9kdWxlQmFzZVJvdXRpbmUgOiBTeW1HZXRNb2R1bGVCYXNlOwoKICAgIHJldHVybiBzdGFja193YWxrKCZzd2NiLCBmcmFtZSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVN0YWNrV2FsazY0IChEQkdIRUxQLkApCiAqLwpCT09MIFdJTkFQSSBTdGFja1dhbGs2NChEV09SRCBNYWNoaW5lVHlwZSwgSEFORExFIGhQcm9jZXNzLCBIQU5ETEUgaFRocmVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgTFBTVEFDS0ZSQU1FNjQgZnJhbWU2NCwgTFBWT0lEIGN0eCwKICAgICAgICAgICAgICAgICAgICAgICAgUFJFQURfUFJPQ0VTU19NRU1PUllfUk9VVElORTY0IGZfcmVhZF9tZW0sCiAgICAgICAgICAgICAgICAgICAgICAgIFBGVU5DVElPTl9UQUJMRV9BQ0NFU1NfUk9VVElORTY0IEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lLAogICAgICAgICAgICAgICAgICAgICAgICBQR0VUX01PRFVMRV9CQVNFX1JPVVRJTkU2NCBHZXRNb2R1bGVCYXNlUm91dGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgUFRSQU5TTEFURV9BRERSRVNTX1JPVVRJTkU2NCBmX3hsYXRfYWRyKQp7CiAgICBzdHJ1Y3Qgc3RhY2tfd2Fsa19jYWxsYmFjayAgc3djYjsKICAgIFNUQUNLRlJBTUUgICAgICAgICAgICAgICAgICBmcmFtZTMyOwogICAgQk9PTCAgICAgICAgICAgICAgICAgICAgICAgIHJldDsKCiAgICBUUkFDRSgiKCVsZCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwKVxuIiwKICAgICAgICAgIE1hY2hpbmVUeXBlLCBoUHJvY2VzcywgaFRocmVhZCwgZnJhbWU2NCwgY3R4LAogICAgICAgICAgZl9yZWFkX21lbSwgRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUsCiAgICAgICAgICBHZXRNb2R1bGVCYXNlUm91dGluZSwgZl94bGF0X2Fkcik7CgogICAgaWYgKE1hY2hpbmVUeXBlICE9IElNQUdFX0ZJTEVfTUFDSElORV9JMzg2KQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGFkZHJfNjR0bzMyKCZmcmFtZTY0LT5BZGRyUEMsICAgICAmZnJhbWUzMi5BZGRyUEMpOwogICAgYWRkcl82NHRvMzIoJmZyYW1lNjQtPkFkZHJSZXR1cm4sICZmcmFtZTMyLkFkZHJSZXR1cm4pOwogICAgYWRkcl82NHRvMzIoJmZyYW1lNjQtPkFkZHJGcmFtZSwgICZmcmFtZTMyLkFkZHJGcmFtZSk7CiAgICBhZGRyXzY0dG8zMigmZnJhbWU2NC0+QWRkclN0YWNrLCAgJmZyYW1lMzIuQWRkclN0YWNrKTsKICAgIGFkZHJfNjR0bzMyKCZmcmFtZTY0LT5BZGRyQlN0b3JlLCAmZnJhbWUzMi5BZGRyQlN0b3JlKTsKICAgIGZyYW1lMzIuRnVuY1RhYmxlRW50cnkgPSBmcmFtZTY0LT5GdW5jVGFibGVFbnRyeTsgLyogRklYTUUgKi8KICAgIGZyYW1lMzIuRmFyID0gZnJhbWU2NC0+RmFyOwogICAgZnJhbWUzMi5WaXJ0dWFsID0gZnJhbWU2NC0+VmlydHVhbDsKICAgIGZyYW1lMzIuUmVzZXJ2ZWRbMF0gPSAoVUxPTkcpZnJhbWU2NC0+UmVzZXJ2ZWRbMF07CiAgICBmcmFtZTMyLlJlc2VydmVkWzFdID0gKFVMT05HKWZyYW1lNjQtPlJlc2VydmVkWzFdOwogICAgZnJhbWUzMi5SZXNlcnZlZFsyXSA9IChVTE9ORylmcmFtZTY0LT5SZXNlcnZlZFsyXTsKICAgIC8qIHdlIGRvbid0IGhhbmRsZSBLZEhlbHAgKi8KCiAgICBzd2NiLmhQcm9jZXNzID0gaFByb2Nlc3M7CiAgICBzd2NiLmhUaHJlYWQgPSBoVGhyZWFkOwogICAgc3djYi5pczMyID0gRkFMU0U7CiAgICAvKiBzaWdoLi4uIE1TIGlzbid0IGV2ZW4gY29uc2lzdGVudCBpbiB0aGUgZnVuYyBwcm90b3R5cGVzICovCiAgICBzd2NiLnUuczY0LmZfcmVhZF9tZW0gPSAoZl9yZWFkX21lbSkgPyBmX3JlYWRfbWVtIDogcmVhZF9tZW02NDsKICAgIHN3Y2IudS5zNjQuZl94bGF0X2FkciA9IGZfeGxhdF9hZHI7CiAgICBzd2NiLnUuczY0LmZfdGFibF9hY3MgPSAoRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUpID8gRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUgOiBTeW1GdW5jdGlvblRhYmxlQWNjZXNzNjQ7CiAgICBzd2NiLnUuczY0LmZfbW9kbF9iYXMgPSAoR2V0TW9kdWxlQmFzZVJvdXRpbmUpID8gR2V0TW9kdWxlQmFzZVJvdXRpbmUgOiBTeW1HZXRNb2R1bGVCYXNlNjQ7CgogICAgcmV0ID0gc3RhY2tfd2Fsaygmc3djYiwgJmZyYW1lMzIpOwoKICAgIGFkZHJfMzJ0bzY0KCZmcmFtZTMyLkFkZHJQQywgICAgICZmcmFtZTY0LT5BZGRyUEMpOwogICAgYWRkcl8zMnRvNjQoJmZyYW1lMzIuQWRkclJldHVybiwgJmZyYW1lNjQtPkFkZHJSZXR1cm4pOwogICAgYWRkcl8zMnRvNjQoJmZyYW1lMzIuQWRkckZyYW1lLCAgJmZyYW1lNjQtPkFkZHJGcmFtZSk7CiAgICBhZGRyXzMydG82NCgmZnJhbWUzMi5BZGRyU3RhY2ssICAmZnJhbWU2NC0+QWRkclN0YWNrKTsKICAgIGFkZHJfMzJ0bzY0KCZmcmFtZTMyLkFkZHJCU3RvcmUsICZmcmFtZTY0LT5BZGRyQlN0b3JlKTsKICAgIGZyYW1lNjQtPkZ1bmNUYWJsZUVudHJ5ID0gZnJhbWUzMi5GdW5jVGFibGVFbnRyeTsgLyogRklYTUUgKi8KICAgIGZyYW1lNjQtPlBhcmFtc1swXSA9IChVTE9ORylmcmFtZTMyLlBhcmFtc1swXTsKICAgIGZyYW1lNjQtPlBhcmFtc1sxXSA9IChVTE9ORylmcmFtZTMyLlBhcmFtc1sxXTsKICAgIGZyYW1lNjQtPlBhcmFtc1syXSA9IChVTE9ORylmcmFtZTMyLlBhcmFtc1syXTsKICAgIGZyYW1lNjQtPlBhcmFtc1szXSA9IChVTE9ORylmcmFtZTMyLlBhcmFtc1szXTsKICAgIGZyYW1lNjQtPkZhciA9IGZyYW1lMzIuRmFyOwogICAgZnJhbWU2NC0+VmlydHVhbCA9IGZyYW1lMzIuVmlydHVhbDsKICAgIGZyYW1lNjQtPlJlc2VydmVkWzBdID0gKFVMT05HKWZyYW1lMzIuUmVzZXJ2ZWRbMF07CiAgICBmcmFtZTY0LT5SZXNlcnZlZFsxXSA9IChVTE9ORylmcmFtZTMyLlJlc2VydmVkWzFdOwogICAgZnJhbWU2NC0+UmVzZXJ2ZWRbMl0gPSAoVUxPTkcpZnJhbWUzMi5SZXNlcnZlZFsyXTsKICAgIC8qIHdlIGRvbid0IGhhbmRsZSBLZEhlbHAgKi8KICAgIGZyYW1lNjQtPktkSGVscC5UaHJlYWQgPSAweEMwMDBGQURFOwogICAgZnJhbWU2NC0+S2RIZWxwLlRoQ2FsbGJhY2tTdGFjayA9IDB4MTA7CiAgICBmcmFtZTY0LT5LZEhlbHAuVGhDYWxsYmFja0JTdG9yZSA9IDA7CiAgICBmcmFtZTY0LT5LZEhlbHAuTmV4dENhbGxiYWNrID0gMDsKICAgIGZyYW1lNjQtPktkSGVscC5GcmFtZVBvaW50ZXIgPSAwOwogICAgZnJhbWU2NC0+S2RIZWxwLktpQ2FsbFVzZXJNb2RlID0gMHhEMDAwREFGRTsKICAgIGZyYW1lNjQtPktkSGVscC5LZVVzZXJDYWxsYmFja0Rpc3BhdGNoZXIgPSAweEUwMDBGMDAwOwogICAgZnJhbWU2NC0+S2RIZWxwLlN5c3RlbVJhbmdlU3RhcnQgPSAweEMwMDAwMDAwOwogICAgZnJhbWU2NC0+S2RIZWxwLlJlc2VydmVkWzBdIC8qIEtpVXNlckV4Y2VwdGlvbkRpc3BhdGNoZXIgKi8gPSAweEUwMDA1MDAwOwoKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVN5bVJlZ2lzdGVyRnVuY3Rpb25FbnRyeUNhbGxiYWNrIChEQkdIRUxQLkApCiAqCiAqCiAqLwpCT09MIFdJTkFQSSBTeW1SZWdpc3RlckZ1bmN0aW9uRW50cnlDYWxsYmFjayhIQU5ETEUgaFByb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTWU1CT0xfRlVOQ0VOVFJZX0NBTExCQUNLIGNiLCBQVk9JRCB1c2VyKQp7CiAgICBGSVhNRSgiKCVwICVwICVwKTogc3R1YiFcbiIsIGhQcm9jLCBjYiwgdXNlcik7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfQ0FMTF9OT1RfSU1QTEVNRU5URUQpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTeW1SZWdpc3RlckZ1bmN0aW9uRW50cnlDYWxsYmFjazY0IChEQkdIRUxQLkApCiAqCiAqCiAqLwpCT09MIFdJTkFQSSBTeW1SZWdpc3RlckZ1bmN0aW9uRW50cnlDYWxsYmFjazY0KEhBTkRMRSBoUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU1lNQk9MX0ZVTkNFTlRSWV9DQUxMQkFDSzY0IGNiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HNjQgdXNlcikKewogICAgRklYTUUoIiglcCAlcCAlcyk6IHN0dWIhXG4iLCBoUHJvYywgY2IsIHdpbmVfZGJnc3RyX2xvbmdsb25nKHVzZXIpKTsKICAgIFNldExhc3RFcnJvcihFUlJPUl9DQUxMX05PVF9JTVBMRU1FTlRFRCk7CiAgICByZXR1cm4gRkFMU0U7Cn0K