LyoKICogU3RhY2sgd2Fsa2luZwogKgogKiBDb3B5cmlnaHQgMTk5NSBBbGV4YW5kcmUgSnVsbGlhcmQKICogQ29weXJpZ2h0IDE5OTYgRXJpYyBZb3VuZ2RhbGUKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqIENvcHlyaWdodCAyMDA0IEVyaWMgUG91ZWNoCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAibnRzdGF0dXMuaCIKI2RlZmluZSBXSU4zMl9OT19TVEFUVVMKI2luY2x1ZGUgImRiZ2hlbHBfcHJpdmF0ZS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRiZ2hlbHApOwoKZW51bSBzdF9tb2RlIHtzdG1fc3RhcnQsIHN0bV8zMmJpdCwgc3RtXzE2Yml0LCBzdG1fZG9uZX07CgpzdGF0aWMgY29uc3QgY2hhciogd2luZV9kYmdzdHJfYWRkcihjb25zdCBBRERSRVNTKiBhZGRyKQp7CiAgICBpZiAoIWFkZHIpIHJldHVybiAiKG51bGwpIjsKICAgIHN3aXRjaCAoYWRkci0+TW9kZSkKICAgIHsKICAgIGNhc2UgQWRkck1vZGVGbGF0OgogICAgICAgIHJldHVybiB3aW5lX2RiZ19zcHJpbnRmKCJmbGF0PCUwOHg+IiwgYWRkci0+T2Zmc2V0KTsKICAgIGNhc2UgQWRkck1vZGUxNjE2OgogICAgICAgIHJldHVybiB3aW5lX2RiZ19zcHJpbnRmKCIxNjE2PCUwNHg6JTA0eD4iLCBhZGRyLT5TZWdtZW50LCBhZGRyLT5PZmZzZXQpOwogICAgY2FzZSBBZGRyTW9kZTE2MzI6CiAgICAgICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoIjE2MzI8JTA0eDolMDh4PiIsIGFkZHItPlNlZ21lbnQsIGFkZHItPk9mZnNldCk7CiAgICBjYXNlIEFkZHJNb2RlUmVhbDoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigicmVhbDwlMDR4OiUwNHg+IiwgYWRkci0+U2VnbWVudCwgYWRkci0+T2Zmc2V0KTsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuICJ1bmtub3duIjsKICAgIH0KfQoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgcmVhZF9tZW0oSEFORExFIGhQcm9jZXNzLCBEV09SRCBhZGRyLCB2b2lkKiBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHNpemUsIExQRFdPUkQgbnJlYWQpCnsKICAgIFNJWkVfVCAgICAgIHI7CiAgICBpZiAoIVJlYWRQcm9jZXNzTWVtb3J5KGhQcm9jZXNzLCAodm9pZCopYWRkciwgYnVmZmVyLCBzaXplLCAmcikpIHJldHVybiBGQUxTRTsKICAgIGlmIChucmVhZCkgKm5yZWFkID0gcjsKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBDQUxMQkFDSyByZWFkX21lbTY0KEhBTkRMRSBoUHJvY2VzcywgRFdPUkQ2NCBhZGRyLCB2b2lkKiBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgc2l6ZSwgTFBEV09SRCBucmVhZCkKewogICAgU0laRV9UICAgICAgcjsKICAgIGlmICghUmVhZFByb2Nlc3NNZW1vcnkoaFByb2Nlc3MsICh2b2lkKikoRFdPUkRfUFRSKWFkZHIsIGJ1ZmZlciwgc2l6ZSwgJnIpKSByZXR1cm4gRkFMU0U7CiAgICBpZiAobnJlYWQpICpucmVhZCA9IHI7CiAgICByZXR1cm4gVFJVRTsKfQoKLyogaW5kZXhlcyBpbiBSZXNlcnZlZCBhcnJheSAqLwojZGVmaW5lIF9fQ3VycmVudE1vZGUgICAgIDAKI2RlZmluZSBfX0N1cnJlbnRTd2l0Y2ggICAxCiNkZWZpbmUgX19OZXh0U3dpdGNoICAgICAgMgoKI2RlZmluZSBjdXJyX21vZGUgICAoZnJhbWUtPlJlc2VydmVkW19fQ3VycmVudE1vZGVdKQojZGVmaW5lIGN1cnJfc3dpdGNoIChmcmFtZS0+UmVzZXJ2ZWRbX19DdXJyZW50U3dpdGNoXSkKI2RlZmluZSBuZXh0X3N3aXRjaCAoZnJhbWUtPlJlc2VydmVkW19fTmV4dFN3aXRjaF0pCgpzdHJ1Y3Qgc3RhY2tfd2Fsa19jYWxsYmFjawp7CiAgICBIQU5ETEUgICAgICBoUHJvY2VzczsKICAgIEhBTkRMRSAgICAgIGhUaHJlYWQ7CiAgICBCT09MICAgICAgICBpczMyOwogICAgdW5pb24KICAgIHsKICAgICAgICBzdHJ1Y3QKICAgICAgICB7CiAgICAgICAgICAgIFBSRUFEX1BST0NFU1NfTUVNT1JZX1JPVVRJTkUgICAgICAgIGZfcmVhZF9tZW07CiAgICAgICAgICAgIFBUUkFOU0xBVEVfQUREUkVTU19ST1VUSU5FICAgICAgICAgIGZfeGxhdF9hZHI7CiAgICAgICAgICAgIFBGVU5DVElPTl9UQUJMRV9BQ0NFU1NfUk9VVElORSAgICAgIGZfdGFibF9hY3M7CiAgICAgICAgICAgIFBHRVRfTU9EVUxFX0JBU0VfUk9VVElORSAgICAgICAgICAgIGZfbW9kbF9iYXM7CiAgICAgICAgfSBzMzI7CiAgICAgICAgc3RydWN0CiAgICAgICAgewogICAgICAgICAgICBQUkVBRF9QUk9DRVNTX01FTU9SWV9ST1VUSU5FNjQgICAgICBmX3JlYWRfbWVtOwogICAgICAgICAgICBQVFJBTlNMQVRFX0FERFJFU1NfUk9VVElORTY0ICAgICAgICBmX3hsYXRfYWRyOwogICAgICAgICAgICBQRlVOQ1RJT05fVEFCTEVfQUNDRVNTX1JPVVRJTkU2NCAgICBmX3RhYmxfYWNzOwogICAgICAgICAgICBQR0VUX01PRFVMRV9CQVNFX1JPVVRJTkU2NCAgICAgICAgICBmX21vZGxfYmFzOwogICAgICAgIH0gczY0OwogICAgfSB1Owp9OwoKc3RhdGljIGlubGluZSB2b2lkIGFkZHJfMzJ0bzY0KGNvbnN0IEFERFJFU1MqIGFkZHIzMiwgQUREUkVTUzY0KiBhZGRyNjQpCnsKICAgIGFkZHI2NC0+T2Zmc2V0ID0gKFVMT05HNjQpYWRkcjMyLT5PZmZzZXQ7CiAgICBhZGRyNjQtPlNlZ21lbnQgPSBhZGRyMzItPlNlZ21lbnQ7CiAgICBhZGRyNjQtPk1vZGUgPSBhZGRyMzItPk1vZGU7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBhZGRyXzY0dG8zMihjb25zdCBBRERSRVNTNjQqIGFkZHI2NCwgQUREUkVTUyogYWRkcjMyKQp7CiAgICBhZGRyMzItPk9mZnNldCA9IChVTE9ORylhZGRyNjQtPk9mZnNldDsKICAgIGFkZHIzMi0+U2VnbWVudCA9IGFkZHI2NC0+U2VnbWVudDsKICAgIGFkZHIzMi0+TW9kZSA9IGFkZHI2NC0+TW9kZTsKfQoKc3RhdGljIGlubGluZSBCT09MIHN3X3JlYWRfbWVtKHN0cnVjdCBzdGFja193YWxrX2NhbGxiYWNrKiBjYiwgRFdPUkQgYWRkciwgdm9pZCogcHRyLCBEV09SRCBzeikKewogICAgaWYgKGNiLT5pczMyKQogICAgICAgIHJldHVybiBjYi0+dS5zMzIuZl9yZWFkX21lbShjYi0+aFByb2Nlc3MsIGFkZHIsIHB0ciwgc3osIE5VTEwpOwogICAgZWxzZQogICAgICAgIHJldHVybiBjYi0+dS5zNjQuZl9yZWFkX21lbShjYi0+aFByb2Nlc3MsIGFkZHIsIHB0ciwgc3osIE5VTEwpOwp9CgpzdGF0aWMgaW5saW5lIERXT1JEIHN3X3hsYXRfYWRkcihzdHJ1Y3Qgc3RhY2tfd2Fsa19jYWxsYmFjayogY2IsIEFERFJFU1MqIGFkZHIpCnsKICAgIGlmIChhZGRyLT5Nb2RlID09IEFkZHJNb2RlRmxhdCkgcmV0dXJuIGFkZHItPk9mZnNldDsKICAgIGlmIChjYi0+aXMzMikgcmV0dXJuIGNiLT51LnMzMi5mX3hsYXRfYWRyKGNiLT5oUHJvY2VzcywgY2ItPmhUaHJlYWQsIGFkZHIpOwogICAgaWYgKGNiLT51LnM2NC5mX3hsYXRfYWRyKQogICAgewogICAgICAgIEFERFJFU1M2NCAgICAgICBhZGRyNjQ7CgogICAgICAgIGFkZHJfMzJ0bzY0KGFkZHIsICZhZGRyNjQpOwogICAgICAgIHJldHVybiBjYi0+dS5zNjQuZl94bGF0X2FkcihjYi0+aFByb2Nlc3MsIGNiLT5oVGhyZWFkLCAmYWRkcjY0KTsKICAgIH0KICAgIHJldHVybiBhZGRyX3RvX2xpbmVhcihjYi0+aFByb2Nlc3MsIGNiLT5oVGhyZWFkLCBhZGRyKTsKfQoKc3RhdGljIGlubGluZSB2b2lkKiBzd190YWJsX2FjcyhzdHJ1Y3Qgc3RhY2tfd2Fsa19jYWxsYmFjayogY2IsIERXT1JEIGFkZHIpCnsKICAgIGlmIChjYi0+aXMzMikKICAgICAgICByZXR1cm4gY2ItPnUuczMyLmZfdGFibF9hY3MoY2ItPmhQcm9jZXNzLCBhZGRyKTsKICAgIGVsc2UKICAgICAgICByZXR1cm4gY2ItPnUuczY0LmZfdGFibF9hY3MoY2ItPmhQcm9jZXNzLCBhZGRyKTsKfQoKc3RhdGljIGlubGluZSBEV09SRCBzd19tb2RsX2JhcyhzdHJ1Y3Qgc3RhY2tfd2Fsa19jYWxsYmFjayogY2IsIERXT1JEIGFkZHIpCnsKICAgIGlmIChjYi0+aXMzMikKICAgICAgICByZXR1cm4gY2ItPnUuczMyLmZfbW9kbF9iYXMoY2ItPmhQcm9jZXNzLCBhZGRyKTsKICAgIGVsc2UKICAgICAgICByZXR1cm4gY2ItPnUuczY0LmZfbW9kbF9iYXMoY2ItPmhQcm9jZXNzLCBhZGRyKTsKfQoKc3RhdGljIEJPT0wgc3RhY2tfd2FsayhzdHJ1Y3Qgc3RhY2tfd2Fsa19jYWxsYmFjayogY2IsIExQU1RBQ0tGUkFNRSBmcmFtZSkKewogICAgU1RBQ0szMkZSQU1FICAgICAgICBmcmFtZTMyOwogICAgU1RBQ0sxNkZSQU1FICAgICAgICBmcmFtZTE2OwogICAgY2hhciAgICAgICAgICAgICAgICBjaDsKICAgIEFERFJFU1MgICAgICAgICAgICAgdG1wOwogICAgRFdPUkQgICAgICAgICAgICAgICBwOwogICAgV09SRCAgICAgICAgICAgICAgICB2YWw7CiAgICBCT09MICAgICAgICAgICAgICAgIGRvX3N3aXRjaDsKCiAgICAvKiBzYW5pdHkgY2hlY2sgKi8KICAgIGlmIChjdXJyX21vZGUgPj0gc3RtX2RvbmUpIHJldHVybiBGQUxTRTsKCiAgICBUUkFDRSgiRW50ZXI6IFBDPSVzIEZyYW1lPSVzIFJldHVybj0lcyBTdGFjaz0lcyBNb2RlPSVzIGNTd2l0Y2g9JTA4eCBuU3dpdGNoPSUwOHhcbiIsCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclBDKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyRnJhbWUpLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJSZXR1cm4pLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJTdGFjayksIAogICAgICAgICAgY3Vycl9tb2RlID09IHN0bV9zdGFydCA/ICJzdGFydCIgOiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCA/ICIxNmJpdCIgOiAiMzJiaXQiKSwKICAgICAgICAgIGN1cnJfc3dpdGNoLCBuZXh0X3N3aXRjaCk7CgogICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fc3RhcnQpCiAgICB7CiAgICAgICAgVEhSRUFEX0JBU0lDX0lORk9STUFUSU9OIGluZm87CgogICAgICAgIGlmICgoZnJhbWUtPkFkZHJQQy5Nb2RlID09IEFkZHJNb2RlRmxhdCkgJiYKICAgICAgICAgICAgKGZyYW1lLT5BZGRyRnJhbWUuTW9kZSAhPSBBZGRyTW9kZUZsYXQpKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiQmFkIEFkZHJQQy5Nb2RlIC8gQWRkckZyYW1lLk1vZGUgY29tYmluYXRpb25cbiIpOwogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIH0KCiAgICAgICAgLyogSW5pdCBkb25lICovCiAgICAgICAgY3Vycl9tb2RlID0gKGZyYW1lLT5BZGRyUEMuTW9kZSA9PSBBZGRyTW9kZUZsYXQpID8gCiAgICAgICAgICAgIHN0bV8zMmJpdCA6IHN0bV8xNmJpdDsKCiAgICAgICAgLyogY3VyX3N3aXRjaCBob2xkcyBhZGRyZXNzIG9mIFdPVzMyUmVzZXJ2ZWQgZmllbGQgaW4gVEVCIGluIGRlYnVnZ2VlCiAgICAgICAgICogYWRkcmVzcyBzcGFjZQogICAgICAgICAqLwogICAgICAgIGlmIChOdFF1ZXJ5SW5mb3JtYXRpb25UaHJlYWQoY2ItPmhUaHJlYWQsIFRocmVhZEJhc2ljSW5mb3JtYXRpb24sICZpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGluZm8pLCBOVUxMKSA9PSBTVEFUVVNfU1VDQ0VTUykKICAgICAgICB7CiAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKHVuc2lnbmVkIGxvbmcpaW5mby5UZWJCYXNlQWRkcmVzcyArIEZJRUxEX09GRlNFVChURUIsIFdPVzMyUmVzZXJ2ZWQpOwogICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBjdXJyX3N3aXRjaCwgJm5leHRfc3dpdGNoLCBzaXplb2YobmV4dF9zd2l0Y2gpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0FSTigiQ2FuJ3QgcmVhZCBURUI6V09XMzJSZXNlcnZlZFxuIik7CiAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBuZXh0X3N3aXRjaCwgJmZyYW1lMzIsIHNpemVvZihmcmFtZTMyKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4eFxuIiwgbmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IChEV09SRClmcmFtZTMyLmZyYW1lMTY7CiAgICAgICAgICAgICAgICB0bXAuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihjdXJyX3N3aXRjaCk7CiAgICAgICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKGN1cnJfc3dpdGNoKTsKICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIHN3X3hsYXRfYWRkcihjYiwgJnRtcCksICZjaCwgc2l6ZW9mKGNoKSkpCiAgICAgICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAweEZGRkZGRkZGOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBwID0gc3dfeGxhdF9hZGRyKGNiLCAmdG1wKTsKICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIHAsICZmcmFtZTE2LCBzaXplb2YoZnJhbWUxNikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOHhcbiIsIHApOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IChEV09SRClmcmFtZTE2LmZyYW1lMzI7CgogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgY3Vycl9zd2l0Y2gsICZjaCwgc2l6ZW9mKGNoKSkpCiAgICAgICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAweEZGRkZGRkZGOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgLyogRklYTUU6IHRoaXMgd2lsbCBhbGxvdyB0byB3b3JrIHdoZW4gd2UncmUgbm90IGF0dGFjaGVkIHRvIGEgbGl2ZSB0YXJnZXQsIAogICAgICAgICAgICAgKiBidXQgdGhlIDE2IDw9PiAzMiBzd2l0Y2ggZmFjaWxpdHkgd29uJ3QgYmUgYXZhaWxhYmxlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAwOwogICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgPSBmcmFtZS0+QWRkclN0YWNrLk1vZGUgPSAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkgPyBBZGRyTW9kZTE2MTYgOiBBZGRyTW9kZUZsYXQ7CiAgICAgICAgLyogZG9uJ3Qgc2V0IHVwIEFkZHJTdGFjayBvbiBmaXJzdCBjYWxsLiBFaXRoZXIgdGhlIGNhbGxlciBoYXMgc2V0IGl0IHVwLCBvcgogICAgICAgICAqIHdlIHdpbGwgZ2V0IGl0IGluIHRoZSBuZXh0IGZyYW1lCiAgICAgICAgICovCiAgICAgICAgbWVtc2V0KCZmcmFtZS0+QWRkckJTdG9yZSwgMCwgc2l6ZW9mKGZyYW1lLT5BZGRyQlN0b3JlKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID09IDApIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgaWYgKGZyYW1lLT5BZGRyRnJhbWUuTW9kZSA9PSBBZGRyTW9kZUZsYXQpCiAgICAgICAgewogICAgICAgICAgICBhc3NlcnQoY3Vycl9tb2RlID09IHN0bV8zMmJpdCk7CiAgICAgICAgICAgIGRvX3N3aXRjaCA9IGN1cnJfc3dpdGNoICYmIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID49IGN1cnJfc3dpdGNoOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBhc3NlcnQoY3Vycl9tb2RlID09IHN0bV8xNmJpdCk7CiAgICAgICAgICAgIGRvX3N3aXRjaCA9IGN1cnJfc3dpdGNoICYmIAogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5TZWdtZW50ID09IFNFTEVDVE9ST0YoY3Vycl9zd2l0Y2gpICYmCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA+PSBPRkZTRVRPRihjdXJyX3N3aXRjaCk7CiAgICAgICAgfQoJICAgCiAgICAgICAgaWYgKGRvX3N3aXRjaCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBuZXh0X3N3aXRjaCwgJmZyYW1lMzIsIHNpemVvZihmcmFtZTMyKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4eFxuIiwgbmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5Nb2RlICAgICAgICA9IEFkZHJNb2RlRmxhdDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuU2VnbWVudCAgICAgPSAwOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5PZmZzZXQgICAgICA9IGZyYW1lMzIucmV0YWRkcjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuTW9kZSAgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLlNlZ21lbnQgID0gMDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICAgPSBmcmFtZTMyLmVicDsKCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLk1vZGUgICAgID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5TZWdtZW50ICA9IDA7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5Nb2RlICAgID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCA9IDA7CgogICAgICAgICAgICAgICAgbmV4dF9zd2l0Y2ggPSBjdXJyX3N3aXRjaDsKICAgICAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgdG1wLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgcCA9IHN3X3hsYXRfYWRkcihjYiwgJnRtcCk7CgogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgcCwgJmZyYW1lMTYsIHNpemVvZihmcmFtZTE2KSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4eFxuIiwgcCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMTYuZnJhbWUzMjsKICAgICAgICAgICAgICAgIGN1cnJfbW9kZSA9IHN0bV8zMmJpdDsKICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIGN1cnJfc3dpdGNoLCAmY2gsIHNpemVvZihjaCkpKQogICAgICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgdG1wLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgcCA9IHN3X3hsYXRfYWRkcihjYiwgJnRtcCk7CgogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgcCwgJmZyYW1lMTYsIHNpemVvZihmcmFtZTE2KSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4eFxuIiwgcCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBUUkFDRSgiR290IGEgMTYgYml0IHN0YWNrIHN3aXRjaDoiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGZyYW1lMzI6ICUwOGx4IgogICAgICAgICAgICAgICAgICAgICAgIlxuXHRlZHg6JTA4eCBlY3g6JTA4eCBlYnA6JTA4eCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZHM6JTA0eCBlczolMDR4IGZzOiUwNHggZ3M6JTA0eCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0Y2FsbF9mcm9tX2lwOiUwOHggbW9kdWxlX2NzOiUwNHggcmVsYXk9JTA4eCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZW50cnlfaXA6JTA0eCBlbnRyeV9wb2ludDolMDh4IgogICAgICAgICAgICAgICAgICAgICAgIlxuXHRicDolMDR4IGlwOiUwNHggY3M6JTA0eFxuIiwKICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBsb25nKWZyYW1lMTYuZnJhbWUzMiwKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuZWR4LCBmcmFtZTE2LmVjeCwgZnJhbWUxNi5lYnAsCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmRzLCBmcmFtZTE2LmVzLCBmcmFtZTE2LmZzLCBmcmFtZTE2LmdzLAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5jYWxsZnJvbV9pcCwgZnJhbWUxNi5tb2R1bGVfY3MsIGZyYW1lMTYucmVsYXksCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmVudHJ5X2lwLCBmcmFtZTE2LmVudHJ5X3BvaW50LAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5icCwgZnJhbWUxNi5pcCwgZnJhbWUxNi5jcyk7CgogICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLk1vZGUgICAgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLlNlZ21lbnQgICAgPSBmcmFtZTE2LmNzOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5PZmZzZXQgICAgID0gZnJhbWUxNi5pcDsKCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICA9IGZyYW1lMTYuYnA7CgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLlNlZ21lbnQgPSBmcmFtZTE2LmNzOwoKICAgICAgICAgICAgICAgIG5leHRfc3dpdGNoID0gY3Vycl9zd2l0Y2g7CiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBuZXh0X3N3aXRjaCwgJmZyYW1lMzIsIHNpemVvZihmcmFtZTMyKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4eFxuIiwgbmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IChEV09SRClmcmFtZTMyLmZyYW1lMTY7CiAgICAgICAgICAgICAgICB0bXAuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihjdXJyX3N3aXRjaCk7CiAgICAgICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKGN1cnJfc3dpdGNoKTsKCiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBzd194bGF0X2FkZHIoY2IsICZ0bXApLCAmY2gsIHNpemVvZihjaCkpKQogICAgICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gMDsKICAgICAgICAgICAgICAgIGN1cnJfbW9kZSA9IHN0bV8xNmJpdDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBmcmFtZS0+QWRkclBDID0gZnJhbWUtPkFkZHJSZXR1cm47CiAgICAgICAgICAgIGlmIChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLk9mZnNldCA9IGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICsgMiAqIHNpemVvZihXT1JEKTsKICAgICAgICAgICAgICAgIC8qICJwb3AgdXAiIHByZXZpb3VzIEJQIHZhbHVlICovCiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBzd194bGF0X2FkZHIoY2IsICZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnZhbCwgc2l6ZW9mKFdPUkQpKSkKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgPSB2YWw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLk9mZnNldCA9IGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICsgMiAqIHNpemVvZihEV09SRCk7CiAgICAgICAgICAgICAgICAvKiAicG9wIHVwIiBwcmV2aW91cyBFQlAgdmFsdWUgKi8KICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0LCBzaXplb2YoRFdPUkQpKSkKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KQogICAgewogICAgICAgIGludCAgICAgaTsKCiAgICAgICAgcCA9IHN3X3hsYXRfYWRkcihjYiwgJmZyYW1lLT5BZGRyRnJhbWUpOwogICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIHAgKyBzaXplb2YoV09SRCksICZ2YWwsIHNpemVvZihXT1JEKSkpCiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uT2Zmc2V0ID0gdmFsOwogICAgICAgIC8qIGdldCBwb3RlbnRpYWwgY3MgaWYgYSBmYXIgY2FsbCB3YXMgdXNlZCAqLwogICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIHAgKyAyICogc2l6ZW9mKFdPUkQpLCAmdmFsLCBzaXplb2YoV09SRCkpKQogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIGlmIChmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAmIDEpCiAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLlNlZ21lbnQgPSB2YWw7IC8qIGZhciBjYWxsIGFzc3VtZWQgKi8KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBub3QgZXhwbGljaXRseSBtYXJrZWQgYXMgZmFyIGNhbGwsIAogICAgICAgICAgICAgKiBidXQgY2hlY2sgd2hldGhlciBpdCBjb3VsZCBiZSBhbnl3YXkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgodmFsICYgNykgPT0gNyAmJiB2YWwgIT0gZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTERUX0VOVFJZCWxlOwoKICAgICAgICAgICAgICAgIGlmIChHZXRUaHJlYWRTZWxlY3RvckVudHJ5KGNiLT5oVGhyZWFkLCB2YWwsICZsZSkgJiYKICAgICAgICAgICAgICAgICAgICAobGUuSGlnaFdvcmQuQml0cy5UeXBlICYgMHgwOCkpIC8qIGNvZGUgc2VnbWVudCAqLwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIGl0IGlzIHZlcnkgdW5jb21tb24gdG8gcHVzaCBhIGNvZGUgc2VnbWVudCBjcyBhcwogICAgICAgICAgICAgICAgICAgICAqIGEgcGFyYW1ldGVyLCBzbyB0aGlzIHNob3VsZCB3b3JrIGluIG1vc3QgY2FzZXMgCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCA9IHZhbDsKICAgICAgICAgICAgICAgIH0KCSAgICB9Cgl9CiAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgJj0gfjE7CiAgICAgICAgLyogd2UgInBvcCIgcGFyYW1ldGVycyBhcyAxNiBiaXQgZW50aXRpZXMuLi4gb2YgY291cnNlLCB0aGlzIHdvbid0CiAgICAgICAgICogd29yayBpZiB0aGUgcGFyYW1ldGVyIGlzIGluIGZhY3QgYmlnZ2VyIHRoYW4gMTZiaXQsIGJ1dAogICAgICAgICAqIHRoZXJlJ3Mgbm8gd2F5IHRvIGtub3cgdGhhdCBoZXJlCiAgICAgICAgICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHNpemVvZihmcmFtZS0+UGFyYW1zKSAvIHNpemVvZihmcmFtZS0+UGFyYW1zWzBdKTsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgc3dfcmVhZF9tZW0oY2IsIHAgKyAoMiArIGkpICogc2l6ZW9mKFdPUkQpLCAmdmFsLCBzaXplb2YodmFsKSk7CiAgICAgICAgICAgIGZyYW1lLT5QYXJhbXNbaV0gPSB2YWw7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICsgc2l6ZW9mKERXT1JEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICZmcmFtZS0+QWRkclJldHVybi5PZmZzZXQsIHNpemVvZihEV09SRCkpKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiQ2Fubm90IHJlYWQgbmV3IGZyYW1lIG9mZnNldCAlMDh4XG4iLCBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIChpbnQpc2l6ZW9mKERXT1JEKSk7CiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgfQogICAgICAgIHN3X3JlYWRfbWVtKGNiLCBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIDIgKiBzaXplb2YoRFdPUkQpLAogICAgICAgICAgICAgICAgICAgIGZyYW1lLT5QYXJhbXMsIHNpemVvZihmcmFtZS0+UGFyYW1zKSk7CiAgICB9CgogICAgZnJhbWUtPkZhciA9IFRSVUU7CiAgICBmcmFtZS0+VmlydHVhbCA9IFRSVUU7CiAgICBwID0gc3dfeGxhdF9hZGRyKGNiLCAmZnJhbWUtPkFkZHJQQyk7CiAgICBpZiAocCAmJiBzd19tb2RsX2JhcyhjYiwgcCkpCiAgICAgICAgZnJhbWUtPkZ1bmNUYWJsZUVudHJ5ID0gc3dfdGFibF9hY3MoY2IsIHApOwogICAgZWxzZQogICAgICAgIGZyYW1lLT5GdW5jVGFibGVFbnRyeSA9IE5VTEw7CgogICAgVFJBQ0UoIkxlYXZlOiBQQz0lcyBGcmFtZT0lcyBSZXR1cm49JXMgU3RhY2s9JXMgTW9kZT0lcyBjU3dpdGNoPSUwOHggblN3aXRjaD0lMDh4IEZ1bmNUYWJsZT0lcFxuIiwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUEMpLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJGcmFtZSksCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclJldHVybiksCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclN0YWNrKSwgCiAgICAgICAgICBjdXJyX21vZGUgPT0gc3RtX3N0YXJ0ID8gInN0YXJ0IiA6IChjdXJyX21vZGUgPT0gc3RtXzE2Yml0ID8gIjE2Yml0IiA6ICIzMmJpdCIpLAogICAgICAgICAgY3Vycl9zd2l0Y2gsIG5leHRfc3dpdGNoLCBmcmFtZS0+RnVuY1RhYmxlRW50cnkpOwoKICAgIHJldHVybiBUUlVFOwpkb25lX2VycjoKICAgIGN1cnJfbW9kZSA9IHN0bV9kb25lOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVN0YWNrV2FsayAoREJHSEVMUC5AKQogKi8KQk9PTCBXSU5BUEkgU3RhY2tXYWxrKERXT1JEIE1hY2hpbmVUeXBlLCBIQU5ETEUgaFByb2Nlc3MsIEhBTkRMRSBoVGhyZWFkLAogICAgICAgICAgICAgICAgICAgICAgTFBTVEFDS0ZSQU1FIGZyYW1lLCBMUFZPSUQgY3R4LAogICAgICAgICAgICAgICAgICAgICAgUFJFQURfUFJPQ0VTU19NRU1PUllfUk9VVElORSBmX3JlYWRfbWVtLAogICAgICAgICAgICAgICAgICAgICAgUEZVTkNUSU9OX1RBQkxFX0FDQ0VTU19ST1VUSU5FIEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lLAogICAgICAgICAgICAgICAgICAgICAgUEdFVF9NT0RVTEVfQkFTRV9ST1VUSU5FIEdldE1vZHVsZUJhc2VSb3V0aW5lLAogICAgICAgICAgICAgICAgICAgICAgUFRSQU5TTEFURV9BRERSRVNTX1JPVVRJTkUgZl94bGF0X2FkcikKewogICAgc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sgIHN3Y2I7CgogICAgVFJBQ0UoIiglZCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwKVxuIiwKICAgICAgICAgIE1hY2hpbmVUeXBlLCBoUHJvY2VzcywgaFRocmVhZCwgZnJhbWUsIGN0eCwKICAgICAgICAgIGZfcmVhZF9tZW0sIEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lLAogICAgICAgICAgR2V0TW9kdWxlQmFzZVJvdXRpbmUsIGZfeGxhdF9hZHIpOwoKICAgIGlmIChNYWNoaW5lVHlwZSAhPSBJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBzd2NiLmhQcm9jZXNzID0gaFByb2Nlc3M7CiAgICBzd2NiLmhUaHJlYWQgPSBoVGhyZWFkOwogICAgc3djYi5pczMyID0gVFJVRTsKICAgIC8qIHNpZ2guLi4gTVMgaXNuJ3QgZXZlbiBjb25zaXN0ZW50IGluIHRoZSBmdW5jIHByb3RvdHlwZXMgKi8KICAgIHN3Y2IudS5zMzIuZl9yZWFkX21lbSA9IChmX3JlYWRfbWVtKSA/IGZfcmVhZF9tZW0gOiByZWFkX21lbTsKICAgIHN3Y2IudS5zMzIuZl94bGF0X2FkciA9IChmX3hsYXRfYWRyKSA/IGZfeGxhdF9hZHIgOiBhZGRyX3RvX2xpbmVhcjsKICAgIHN3Y2IudS5zMzIuZl90YWJsX2FjcyA9IChGdW5jdGlvblRhYmxlQWNjZXNzUm91dGluZSkgPyBGdW5jdGlvblRhYmxlQWNjZXNzUm91dGluZSA6IFN5bUZ1bmN0aW9uVGFibGVBY2Nlc3M7CiAgICBzd2NiLnUuczMyLmZfbW9kbF9iYXMgPSAoR2V0TW9kdWxlQmFzZVJvdXRpbmUpID8gR2V0TW9kdWxlQmFzZVJvdXRpbmUgOiBTeW1HZXRNb2R1bGVCYXNlOwoKICAgIHJldHVybiBzdGFja193YWxrKCZzd2NiLCBmcmFtZSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVN0YWNrV2FsazY0IChEQkdIRUxQLkApCiAqLwpCT09MIFdJTkFQSSBTdGFja1dhbGs2NChEV09SRCBNYWNoaW5lVHlwZSwgSEFORExFIGhQcm9jZXNzLCBIQU5ETEUgaFRocmVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgTFBTVEFDS0ZSQU1FNjQgZnJhbWU2NCwgTFBWT0lEIGN0eCwKICAgICAgICAgICAgICAgICAgICAgICAgUFJFQURfUFJPQ0VTU19NRU1PUllfUk9VVElORTY0IGZfcmVhZF9tZW0sCiAgICAgICAgICAgICAgICAgICAgICAgIFBGVU5DVElPTl9UQUJMRV9BQ0NFU1NfUk9VVElORTY0IEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lLAogICAgICAgICAgICAgICAgICAgICAgICBQR0VUX01PRFVMRV9CQVNFX1JPVVRJTkU2NCBHZXRNb2R1bGVCYXNlUm91dGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgUFRSQU5TTEFURV9BRERSRVNTX1JPVVRJTkU2NCBmX3hsYXRfYWRyKQp7CiAgICBzdHJ1Y3Qgc3RhY2tfd2Fsa19jYWxsYmFjayAgc3djYjsKICAgIFNUQUNLRlJBTUUgICAgICAgICAgICAgICAgICBmcmFtZTMyOwogICAgQk9PTCAgICAgICAgICAgICAgICAgICAgICAgIHJldDsKCiAgICBUUkFDRSgiKCVkLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcCwgJXApXG4iLAogICAgICAgICAgTWFjaGluZVR5cGUsIGhQcm9jZXNzLCBoVGhyZWFkLCBmcmFtZTY0LCBjdHgsCiAgICAgICAgICBmX3JlYWRfbWVtLCBGdW5jdGlvblRhYmxlQWNjZXNzUm91dGluZSwKICAgICAgICAgIEdldE1vZHVsZUJhc2VSb3V0aW5lLCBmX3hsYXRfYWRyKTsKCiAgICBpZiAoTWFjaGluZVR5cGUgIT0gSU1BR0VfRklMRV9NQUNISU5FX0kzODYpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgYWRkcl82NHRvMzIoJmZyYW1lNjQtPkFkZHJQQywgICAgICZmcmFtZTMyLkFkZHJQQyk7CiAgICBhZGRyXzY0dG8zMigmZnJhbWU2NC0+QWRkclJldHVybiwgJmZyYW1lMzIuQWRkclJldHVybik7CiAgICBhZGRyXzY0dG8zMigmZnJhbWU2NC0+QWRkckZyYW1lLCAgJmZyYW1lMzIuQWRkckZyYW1lKTsKICAgIGFkZHJfNjR0bzMyKCZmcmFtZTY0LT5BZGRyU3RhY2ssICAmZnJhbWUzMi5BZGRyU3RhY2spOwogICAgYWRkcl82NHRvMzIoJmZyYW1lNjQtPkFkZHJCU3RvcmUsICZmcmFtZTMyLkFkZHJCU3RvcmUpOwogICAgZnJhbWUzMi5GdW5jVGFibGVFbnRyeSA9IGZyYW1lNjQtPkZ1bmNUYWJsZUVudHJ5OyAvKiBGSVhNRSAqLwogICAgZnJhbWUzMi5GYXIgPSBmcmFtZTY0LT5GYXI7CiAgICBmcmFtZTMyLlZpcnR1YWwgPSBmcmFtZTY0LT5WaXJ0dWFsOwogICAgZnJhbWUzMi5SZXNlcnZlZFswXSA9IChVTE9ORylmcmFtZTY0LT5SZXNlcnZlZFswXTsKICAgIGZyYW1lMzIuUmVzZXJ2ZWRbMV0gPSAoVUxPTkcpZnJhbWU2NC0+UmVzZXJ2ZWRbMV07CiAgICBmcmFtZTMyLlJlc2VydmVkWzJdID0gKFVMT05HKWZyYW1lNjQtPlJlc2VydmVkWzJdOwogICAgLyogd2UgZG9uJ3QgaGFuZGxlIEtkSGVscCAqLwoKICAgIHN3Y2IuaFByb2Nlc3MgPSBoUHJvY2VzczsKICAgIHN3Y2IuaFRocmVhZCA9IGhUaHJlYWQ7CiAgICBzd2NiLmlzMzIgPSBGQUxTRTsKICAgIC8qIHNpZ2guLi4gTVMgaXNuJ3QgZXZlbiBjb25zaXN0ZW50IGluIHRoZSBmdW5jIHByb3RvdHlwZXMgKi8KICAgIHN3Y2IudS5zNjQuZl9yZWFkX21lbSA9IChmX3JlYWRfbWVtKSA/IGZfcmVhZF9tZW0gOiByZWFkX21lbTY0OwogICAgc3djYi51LnM2NC5mX3hsYXRfYWRyID0gZl94bGF0X2FkcjsKICAgIHN3Y2IudS5zNjQuZl90YWJsX2FjcyA9IChGdW5jdGlvblRhYmxlQWNjZXNzUm91dGluZSkgPyBGdW5jdGlvblRhYmxlQWNjZXNzUm91dGluZSA6IFN5bUZ1bmN0aW9uVGFibGVBY2Nlc3M2NDsKICAgIHN3Y2IudS5zNjQuZl9tb2RsX2JhcyA9IChHZXRNb2R1bGVCYXNlUm91dGluZSkgPyBHZXRNb2R1bGVCYXNlUm91dGluZSA6IFN5bUdldE1vZHVsZUJhc2U2NDsKCiAgICByZXQgPSBzdGFja193YWxrKCZzd2NiLCAmZnJhbWUzMik7CgogICAgYWRkcl8zMnRvNjQoJmZyYW1lMzIuQWRkclBDLCAgICAgJmZyYW1lNjQtPkFkZHJQQyk7CiAgICBhZGRyXzMydG82NCgmZnJhbWUzMi5BZGRyUmV0dXJuLCAmZnJhbWU2NC0+QWRkclJldHVybik7CiAgICBhZGRyXzMydG82NCgmZnJhbWUzMi5BZGRyRnJhbWUsICAmZnJhbWU2NC0+QWRkckZyYW1lKTsKICAgIGFkZHJfMzJ0bzY0KCZmcmFtZTMyLkFkZHJTdGFjaywgICZmcmFtZTY0LT5BZGRyU3RhY2spOwogICAgYWRkcl8zMnRvNjQoJmZyYW1lMzIuQWRkckJTdG9yZSwgJmZyYW1lNjQtPkFkZHJCU3RvcmUpOwogICAgZnJhbWU2NC0+RnVuY1RhYmxlRW50cnkgPSBmcmFtZTMyLkZ1bmNUYWJsZUVudHJ5OyAvKiBGSVhNRSAqLwogICAgZnJhbWU2NC0+UGFyYW1zWzBdID0gKFVMT05HKWZyYW1lMzIuUGFyYW1zWzBdOwogICAgZnJhbWU2NC0+UGFyYW1zWzFdID0gKFVMT05HKWZyYW1lMzIuUGFyYW1zWzFdOwogICAgZnJhbWU2NC0+UGFyYW1zWzJdID0gKFVMT05HKWZyYW1lMzIuUGFyYW1zWzJdOwogICAgZnJhbWU2NC0+UGFyYW1zWzNdID0gKFVMT05HKWZyYW1lMzIuUGFyYW1zWzNdOwogICAgZnJhbWU2NC0+RmFyID0gZnJhbWUzMi5GYXI7CiAgICBmcmFtZTY0LT5WaXJ0dWFsID0gZnJhbWUzMi5WaXJ0dWFsOwogICAgZnJhbWU2NC0+UmVzZXJ2ZWRbMF0gPSAoVUxPTkcpZnJhbWUzMi5SZXNlcnZlZFswXTsKICAgIGZyYW1lNjQtPlJlc2VydmVkWzFdID0gKFVMT05HKWZyYW1lMzIuUmVzZXJ2ZWRbMV07CiAgICBmcmFtZTY0LT5SZXNlcnZlZFsyXSA9IChVTE9ORylmcmFtZTMyLlJlc2VydmVkWzJdOwogICAgLyogd2UgZG9uJ3QgaGFuZGxlIEtkSGVscCAqLwogICAgZnJhbWU2NC0+S2RIZWxwLlRocmVhZCA9IDB4QzAwMEZBREU7CiAgICBmcmFtZTY0LT5LZEhlbHAuVGhDYWxsYmFja1N0YWNrID0gMHgxMDsKICAgIGZyYW1lNjQtPktkSGVscC5UaENhbGxiYWNrQlN0b3JlID0gMDsKICAgIGZyYW1lNjQtPktkSGVscC5OZXh0Q2FsbGJhY2sgPSAwOwogICAgZnJhbWU2NC0+S2RIZWxwLkZyYW1lUG9pbnRlciA9IDA7CiAgICBmcmFtZTY0LT5LZEhlbHAuS2lDYWxsVXNlck1vZGUgPSAweEQwMDBEQUZFOwogICAgZnJhbWU2NC0+S2RIZWxwLktlVXNlckNhbGxiYWNrRGlzcGF0Y2hlciA9IDB4RTAwMEYwMDA7CiAgICBmcmFtZTY0LT5LZEhlbHAuU3lzdGVtUmFuZ2VTdGFydCA9IDB4QzAwMDAwMDA7CiAgICBmcmFtZTY0LT5LZEhlbHAuUmVzZXJ2ZWRbMF0gLyogS2lVc2VyRXhjZXB0aW9uRGlzcGF0Y2hlciAqLyA9IDB4RTAwMDUwMDA7CgogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU3ltUmVnaXN0ZXJGdW5jdGlvbkVudHJ5Q2FsbGJhY2sgKERCR0hFTFAuQCkKICoKICoKICovCkJPT0wgV0lOQVBJIFN5bVJlZ2lzdGVyRnVuY3Rpb25FbnRyeUNhbGxiYWNrKEhBTkRMRSBoUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNZTUJPTF9GVU5DRU5UUllfQ0FMTEJBQ0sgY2IsIFBWT0lEIHVzZXIpCnsKICAgIEZJWE1FKCIoJXAgJXAgJXApOiBzdHViIVxuIiwgaFByb2MsIGNiLCB1c2VyKTsKICAgIFNldExhc3RFcnJvcihFUlJPUl9DQUxMX05PVF9JTVBMRU1FTlRFRCk7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVN5bVJlZ2lzdGVyRnVuY3Rpb25FbnRyeUNhbGxiYWNrNjQgKERCR0hFTFAuQCkKICoKICoKICovCkJPT0wgV0lOQVBJIFN5bVJlZ2lzdGVyRnVuY3Rpb25FbnRyeUNhbGxiYWNrNjQoSEFORExFIGhQcm9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTWU1CT0xfRlVOQ0VOVFJZX0NBTExCQUNLNjQgY2IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkc2NCB1c2VyKQp7CiAgICBGSVhNRSgiKCVwICVwICVzKTogc3R1YiFcbiIsIGhQcm9jLCBjYiwgd2luZV9kYmdzdHJfbG9uZ2xvbmcodXNlcikpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0NBTExfTk9UX0lNUExFTUVOVEVEKTsKICAgIHJldHVybiBGQUxTRTsKfQo=