LyoKICogU3RhY2sgd2Fsa2luZwogKgogKiBDb3B5cmlnaHQgMTk5NSBBbGV4YW5kcmUgSnVsbGlhcmQKICogQ29weXJpZ2h0IDE5OTYgRXJpYyBZb3VuZ2RhbGUKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqIENvcHlyaWdodCAyMDA0IEVyaWMgUG91ZWNoCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAiZGJnaGVscF9wcml2YXRlLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIm50c3RhdHVzLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRiZ2hlbHApOwoKZW51bSBzdF9tb2RlIHtzdG1fc3RhcnQsIHN0bV8zMmJpdCwgc3RtXzE2Yml0LCBzdG1fZG9uZX07CgpzdGF0aWMgY29uc3QgY2hhciogd2luZV9kYmdzdHJfYWRkcihjb25zdCBBRERSRVNTKiBhZGRyKQp7CiAgICBpZiAoIWFkZHIpIHJldHVybiAiKG51bGwpIjsKICAgIHN3aXRjaCAoYWRkci0+TW9kZSkKICAgIHsKICAgIGNhc2UgQWRkck1vZGVGbGF0OgogICAgICAgIHJldHVybiB3aW5lX2RiZ19zcHJpbnRmKCJmbGF0PCUwOGx4PiIsIGFkZHItPk9mZnNldCk7CiAgICBjYXNlIEFkZHJNb2RlMTYxNjoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigiMTYxNjwlMDR4OiUwNGx4PiIsIGFkZHItPlNlZ21lbnQsIGFkZHItPk9mZnNldCk7CiAgICBjYXNlIEFkZHJNb2RlMTYzMjoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigiMTYzMjwlMDR4OiUwOGx4PiIsIGFkZHItPlNlZ21lbnQsIGFkZHItPk9mZnNldCk7CiAgICBjYXNlIEFkZHJNb2RlUmVhbDoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigicmVhbDwlMDR4OiUwNGx4PiIsIGFkZHItPlNlZ21lbnQsIGFkZHItPk9mZnNldCk7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiAidW5rbm93biI7CiAgICB9Cn0KCi8qIGluZGV4ZXMgaW4gUmVzZXJ2ZWQgYXJyYXkgKi8KI2RlZmluZSBfX0N1cnJlbnRNb2RlICAgICAwCiNkZWZpbmUgX19DdXJyZW50U3dpdGNoICAgMQojZGVmaW5lIF9fTmV4dFN3aXRjaCAgICAgIDIKCiNkZWZpbmUgY3Vycl9tb2RlICAgKGZyYW1lLT5SZXNlcnZlZFtfX0N1cnJlbnRNb2RlXSkKI2RlZmluZSBjdXJyX3N3aXRjaCAoZnJhbWUtPlJlc2VydmVkW19fQ3VycmVudFN3aXRjaF0pCiNkZWZpbmUgbmV4dF9zd2l0Y2ggKGZyYW1lLT5SZXNlcnZlZFtfX05leHRTd2l0Y2hdKQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTdGFja1dhbGsgKERCR0hFTFAuQCkKICovCkJPT0wgV0lOQVBJIFN0YWNrV2FsayhEV09SRCBNYWNoaW5lVHlwZSwgSEFORExFIGhQcm9jZXNzLCBIQU5ETEUgaFRocmVhZCwKICAgICAgICAgICAgICAgICAgICAgIExQU1RBQ0tGUkFNRSBmcmFtZSwgTFBWT0lEIGN0eCwKICAgICAgICAgICAgICAgICAgICAgIFBSRUFEX1BST0NFU1NfTUVNT1JZX1JPVVRJTkUgZl9yZWFkX21lbSwKICAgICAgICAgICAgICAgICAgICAgIFBGVU5DVElPTl9UQUJMRV9BQ0NFU1NfUk9VVElORSBGdW5jdGlvblRhYmxlQWNjZXNzUm91dGluZSwKICAgICAgICAgICAgICAgICAgICAgIFBHRVRfTU9EVUxFX0JBU0VfUk9VVElORSBHZXRNb2R1bGVCYXNlUm91dGluZSwKICAgICAgICAgICAgICAgICAgICAgIFBUUkFOU0xBVEVfQUREUkVTU19ST1VUSU5FIGZfeGxhdF9hZHIpCnsKICAgIFNUQUNLMzJGUkFNRSAgICAgICAgZnJhbWUzMjsKICAgIFNUQUNLMTZGUkFNRSAgICAgICAgZnJhbWUxNjsKICAgIGNoYXIgICAgICAgICAgICAgICAgY2g7CiAgICBBRERSRVNTICAgICAgICAgICAgIHRtcDsKICAgIERXT1JEICAgICAgICAgICAgICAgcDsKICAgIFdPUkQgICAgICAgICAgICAgICAgdmFsOwogICAgQk9PTCAgICAgICAgICAgICAgICBkb19zd2l0Y2g7CgogICAgVFJBQ0UoIiglbGQsICVwLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcClcbiIsCiAgICAgICAgICBNYWNoaW5lVHlwZSwgaFByb2Nlc3MsIGhUaHJlYWQsIGZyYW1lLCBjdHgsCiAgICAgICAgICBmX3JlYWRfbWVtLCBGdW5jdGlvblRhYmxlQWNjZXNzUm91dGluZSwKICAgICAgICAgIEdldE1vZHVsZUJhc2VSb3V0aW5lLCBmX3hsYXRfYWRyKTsKCiAgICBpZiAoTWFjaGluZVR5cGUgIT0gSU1BR0VfRklMRV9NQUNISU5FX0kzODYpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgLyogc2FuaXR5IGNoZWNrICovCiAgICBpZiAoY3Vycl9tb2RlID49IHN0bV9kb25lKSByZXR1cm4gRkFMU0U7CgogICAgaWYgKCFmX3JlYWRfbWVtKSBmX3JlYWRfbWVtID0gUmVhZFByb2Nlc3NNZW1vcnk7CiAgICBpZiAoIWZfeGxhdF9hZHIpIGZfeGxhdF9hZHIgPSBhZGRyX3RvX2xpbmVhcjsKCiAgICBUUkFDRSgiRW50ZXI6IFBDPSVzIEZyYW1lPSVzIFJldHVybj0lcyBTdGFjaz0lcyBNb2RlPSVzIGNTd2l0Y2g9JTA4bHggblN3aXRjaD0lMDhseFxuIiwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUEMpLCAKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyRnJhbWUpLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJSZXR1cm4pLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJTdGFjayksIAogICAgICAgICAgY3Vycl9tb2RlID09IHN0bV9zdGFydCA/ICJzdGFydCIgOiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCA/ICIxNmJpdCIgOiAiMzJiaXQiKSwKICAgICAgICAgIGN1cnJfc3dpdGNoLCBuZXh0X3N3aXRjaCk7CgogICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fc3RhcnQpCiAgICB7CiAgICAgICAgVEhSRUFEX0JBU0lDX0lORk9STUFUSU9OIGluZm87CgogICAgICAgIGlmICgoZnJhbWUtPkFkZHJQQy5Nb2RlID09IEFkZHJNb2RlRmxhdCkgJiYKICAgICAgICAgICAgKGZyYW1lLT5BZGRyRnJhbWUuTW9kZSAhPSBBZGRyTW9kZUZsYXQpKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiQmFkIEFkZHJQQy5Nb2RlIC8gQWRkckZyYW1lLk1vZGUgY29tYmluYXRpb25cbiIpOwogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIH0KCiAgICAgICAgLyogSW5pdCBkb25lICovCiAgICAgICAgY3Vycl9tb2RlID0gKGZyYW1lLT5BZGRyUEMuTW9kZSA9PSBBZGRyTW9kZUZsYXQpID8gCiAgICAgICAgICAgIHN0bV8zMmJpdCA6IHN0bV8xNmJpdDsKCiAgICAgICAgLyogY3VyX3N3aXRjaCBob2xkcyBhZGRyZXNzIG9mIGN1cnJfc3RhY2sncyBmaWVsZCBpbiBURUIgaW4gZGVidWdnZWUKICAgICAgICAgKiBhZGRyZXNzIHNwYWNlCiAgICAgICAgICovCiAgICAgICAgaWYgKE50UXVlcnlJbmZvcm1hdGlvblRocmVhZChoVGhyZWFkLCBUaHJlYWRCYXNpY0luZm9ybWF0aW9uLCAmaW5mbywgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoaW5mbyksIE5VTEwpICE9IFNUQVRVU19TVUNDRVNTKQogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIGN1cnJfc3dpdGNoID0gKHVuc2lnbmVkIGxvbmcpaW5mby5UZWJCYXNlQWRkcmVzcyArIEZJRUxEX09GRlNFVChURUIsIFdPVzMyUmVzZXJ2ZWQpOwogICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKWN1cnJfc3dpdGNoLCAmbmV4dF9zd2l0Y2gsIAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobmV4dF9zd2l0Y2gpLCBOVUxMKSkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIkNhbid0IHJlYWQgVEVCOmN1cl9zdGFja1xuIik7CiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgfQogICAgICAgIGlmIChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihmcmFtZTMyKSwgTlVMTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMzIuZnJhbWUxNjsKICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihjdXJyX3N3aXRjaCk7CiAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YoY3Vycl9zd2l0Y2gpOwogICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKilmX3hsYXRfYWRyKGhQcm9jZXNzLCBoVGhyZWFkLCAmdG1wKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaCwgc2l6ZW9mKGNoKSwgTlVMTCkpCiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgPSBmcmFtZS0+QWRkclN0YWNrLk1vZGUgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgcCA9IGZfeGxhdF9hZHIoaFByb2Nlc3MsIGhUaHJlYWQsICZ0bXApOwogICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKilwLCAmZnJhbWUxNiwgc2l6ZW9mKGZyYW1lMTYpLCBOVUxMKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIHApOwogICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgfQogICAgICAgICAgICBjdXJyX3N3aXRjaCA9IChEV09SRClmcmFtZTE2LmZyYW1lMzI7CgogICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKiljdXJyX3N3aXRjaCwgJmNoLCBzaXplb2YoY2gpLCBOVUxMKSkKICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gMHhGRkZGRkZGRjsKICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uTW9kZSA9IGZyYW1lLT5BZGRyU3RhY2suTW9kZSA9IEFkZHJNb2RlRmxhdDsKICAgICAgICB9CiAgICAgICAgLyogZG9uJ3Qgc2V0IHVwIEFkZHJTdGFjayBvbiBmaXJzdCBjYWxsLiBFaXRoZXIgdGhlIGNhbGxlciBoYXMgc2V0IGl0IHVwLCBvcgogICAgICAgICAqIHdlIHdpbGwgZ2V0IGl0IGluIHRoZSBuZXh0IGZyYW1lCiAgICAgICAgICovCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID09IDApIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgaWYgKGZyYW1lLT5BZGRyRnJhbWUuTW9kZSA9PSBBZGRyTW9kZUZsYXQpCiAgICAgICAgewogICAgICAgICAgICBhc3NlcnQoY3Vycl9tb2RlID09IHN0bV8zMmJpdCk7CiAgICAgICAgICAgIGRvX3N3aXRjaCA9IGN1cnJfc3dpdGNoICYmIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID49IGN1cnJfc3dpdGNoOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBhc3NlcnQoY3Vycl9tb2RlID09IHN0bV8xNmJpdCk7CiAgICAgICAgICAgIGRvX3N3aXRjaCA9IE9GRlNFVE9GKGN1cnJfc3dpdGNoKSAmJiAKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuU2VnbWVudCA9PSBTRUxFQ1RPUk9GKGN1cnJfc3dpdGNoKSAmJgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgPj0gT0ZGU0VUT0YoY3Vycl9zd2l0Y2gpOwogICAgICAgIH0KCSAgIAogICAgICAgIGlmIChkb19zd2l0Y2gpCiAgICAgICAgewogICAgICAgICAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoZnJhbWUzMiksIE5VTEwpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLk1vZGUgICAgICAgID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5TZWdtZW50ICAgICA9IDA7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLk9mZnNldCAgICAgID0gZnJhbWUzMi5yZXRhZGRyOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5Nb2RlICAgICA9IEFkZHJNb2RlRmxhdDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuU2VnbWVudCAgPSAwOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgICA9IGZyYW1lMzIuZWJwOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suTW9kZSAgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLlNlZ21lbnQgID0gMDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gMDsKCiAgICAgICAgICAgICAgICBuZXh0X3N3aXRjaCA9IGN1cnJfc3dpdGNoOwogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBwID0gZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJnRtcCk7CgogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopcCwgJmZyYW1lMTYsIHNpemVvZihmcmFtZTE2KSwgTlVMTCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIHApOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IChEV09SRClmcmFtZTE2LmZyYW1lMzI7CiAgICAgICAgICAgICAgICBjdXJyX21vZGUgPSBzdG1fMzJiaXQ7CiAgICAgICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKiljdXJyX3N3aXRjaCwgJmNoLCBzaXplb2YoY2gpLCBOVUxMKSkKICAgICAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0bXAuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHAgPSBmX3hsYXRfYWRyKGhQcm9jZXNzLCBoVGhyZWFkLCAmdG1wKTsKCiAgICAgICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKilwLCAmZnJhbWUxNiwgc2l6ZW9mKGZyYW1lMTYpLCBOVUxMKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgcCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBUUkFDRSgiR290IGEgMTYgYml0IHN0YWNrIHN3aXRjaDoiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGZyYW1lMzI6ICUwOGx4IgogICAgICAgICAgICAgICAgICAgICAgIlxuXHRlZHg6JTA4bHggZWN4OiUwOGx4IGVicDolMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZHM6JTA0eCBlczolMDR4IGZzOiUwNHggZ3M6JTA0eCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0Y2FsbF9mcm9tX2lwOiUwOGx4IG1vZHVsZV9jczolMDRseCByZWxheT0lMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZW50cnlfaXA6JTA0eCBlbnRyeV9wb2ludDolMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0YnA6JTA0eCBpcDolMDR4IGNzOiUwNHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZylmcmFtZTE2LmZyYW1lMzIsCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmVkeCwgZnJhbWUxNi5lY3gsIGZyYW1lMTYuZWJwLAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5kcywgZnJhbWUxNi5lcywgZnJhbWUxNi5mcywgZnJhbWUxNi5ncywKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuY2FsbGZyb21faXAsIGZyYW1lMTYubW9kdWxlX2NzLCBmcmFtZTE2LnJlbGF5LAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5lbnRyeV9pcCwgZnJhbWUxNi5lbnRyeV9wb2ludCwKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuYnAsIGZyYW1lMTYuaXAsIGZyYW1lMTYuY3MpOwoKICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5Nb2RlICAgICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5TZWdtZW50ICAgID0gZnJhbWUxNi5jczsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuT2Zmc2V0ICAgICA9IGZyYW1lMTYuaXA7CgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAgPSBmcmFtZTE2LmJwOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gZnJhbWUxNi5jczsKCiAgICAgICAgICAgICAgICBuZXh0X3N3aXRjaCA9IGN1cnJfc3dpdGNoOwogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoZnJhbWUzMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUzMi5mcmFtZTE2OwogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YoY3Vycl9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihjdXJyX3N3aXRjaCk7CgogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJnRtcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNoLCBzaXplb2YoY2gpLCBOVUxMKSkKICAgICAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgICAgICBjdXJyX21vZGUgPSBzdG1fMTZiaXQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgZnJhbWUtPkFkZHJQQyA9IGZyYW1lLT5BZGRyUmV0dXJuOwogICAgICAgICAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5PZmZzZXQgPSBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIDIgKiBzaXplb2YoV09SRCk7CiAgICAgICAgICAgICAgICAvKiAicG9wIHVwIiBwcmV2aW91cyBCUCB2YWx1ZSAqLwogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCopZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJmZyYW1lLT5BZGRyRnJhbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ2YWwsIHNpemVvZihXT1JEKSwgTlVMTCkpCiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID0gdmFsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5PZmZzZXQgPSBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIDIgKiBzaXplb2YoRFdPUkQpOwogICAgICAgICAgICAgICAgLyogInBvcCB1cCIgcHJldmlvdXMgRUJQIHZhbHVlICovCiAgICAgICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKilmcmFtZS0+QWRkckZyYW1lLk9mZnNldCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0LCBzaXplb2YoRFdPUkQpLCBOVUxMKSkKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KQogICAgewogICAgICAgIGludCAgICAgaTsKCiAgICAgICAgcCA9IGZfeGxhdF9hZHIoaFByb2Nlc3MsIGhUaHJlYWQsICZmcmFtZS0+QWRkckZyYW1lKTsKICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKikocCArIHNpemVvZihXT1JEKSksICZ2YWwsIHNpemVvZihXT1JEKSwgTlVMTCkpCiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uT2Zmc2V0ID0gdmFsOwogICAgICAgIC8qIGdldCBwb3RlbnRpYWwgY3MgaWYgYSBmYXIgY2FsbCB3YXMgdXNlZCAqLwogICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKShwICsgMiAqIHNpemVvZihXT1JEKSksIAogICAgICAgICAgICAgICAgICAgICAgICAmdmFsLCBzaXplb2YoV09SRCksIE5VTEwpKQogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIGlmIChmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAmIDEpCiAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLlNlZ21lbnQgPSB2YWw7IC8qIGZhciBjYWxsIGFzc3VtZWQgKi8KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBub3QgZXhwbGljaXRseSBtYXJrZWQgYXMgZmFyIGNhbGwsIAogICAgICAgICAgICAgKiBidXQgY2hlY2sgd2hldGhlciBpdCBjb3VsZCBiZSBhbnl3YXkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgodmFsICYgNykgPT0gNyAmJiB2YWwgIT0gZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTERUX0VOVFJZCWxlOwoKICAgICAgICAgICAgICAgIGlmIChHZXRUaHJlYWRTZWxlY3RvckVudHJ5KGhUaHJlYWQsIHZhbCwgJmxlKSAmJgogICAgICAgICAgICAgICAgICAgIChsZS5IaWdoV29yZC5CaXRzLlR5cGUgJiAweDA4KSkgLyogY29kZSBzZWdtZW50ICovCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogaXQgaXMgdmVyeSB1bmNvbW1vbiB0byBwdXNoIGEgY29kZSBzZWdtZW50IGNzIGFzCiAgICAgICAgICAgICAgICAgICAgICogYSBwYXJhbWV0ZXIsIHNvIHRoaXMgc2hvdWxkIHdvcmsgaW4gbW9zdCBjYXNlcyAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gdmFsOwogICAgICAgICAgICAgICAgfQoJICAgIH0KCX0KICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAmPSB+MTsKICAgICAgICAvKiB3ZSAicG9wIiBwYXJhbWV0ZXJzIGFzIDE2IGJpdCBlbnRpdGllcy4uLiBvZiBjb3Vyc2UsIHRoaXMgd29uJ3QKICAgICAgICAgKiB3b3JrIGlmIHRoZSBwYXJhbWV0ZXIgaXMgaW4gZmFjdCBiaWdnZXIgdGhhbiAxNmJpdCwgYnV0CiAgICAgICAgICogdGhlcmUncyBubyB3YXkgdG8ga25vdyB0aGF0IGhlcmUKICAgICAgICAgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZW9mKGZyYW1lLT5QYXJhbXMpIC8gc2l6ZW9mKGZyYW1lLT5QYXJhbXNbMF0pOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopKHAgKyAoMiArIGkpICogc2l6ZW9mKFdPUkQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgJnZhbCwgc2l6ZW9mKHZhbCksIE5VTEwpOwogICAgICAgICAgICBmcmFtZS0+UGFyYW1zW2ldID0gdmFsOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAodm9pZCopKGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICsgc2l6ZW9mKERXT1JEKSksCiAgICAgICAgICAgICAgICAgICAgICAgICZmcmFtZS0+QWRkclJldHVybi5PZmZzZXQsIHNpemVvZihEV09SRCksIE5VTEwpKQogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIGZfcmVhZF9tZW0oaFByb2Nlc3MsIAogICAgICAgICAgICAgICAgICAgKHZvaWQqKShmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIDIgKiBzaXplb2YoRFdPUkQpKSwgCiAgICAgICAgICAgICAgICAgICBmcmFtZS0+UGFyYW1zLCBzaXplb2YoZnJhbWUtPlBhcmFtcyksIE5VTEwpOwogICAgfQoKICAgIGZyYW1lLT5GYXIgPSBGQUxTRTsKICAgIGZyYW1lLT5WaXJ0dWFsID0gRkFMU0U7CgogICAgVFJBQ0UoIkxlYXZlOiBQQz0lcyBGcmFtZT0lcyBSZXR1cm49JXMgU3RhY2s9JXMgTW9kZT0lcyBjU3dpdGNoPSUwOGx4IG5Td2l0Y2g9JTA4bHhcbiIsCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclBDKSwgCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUmV0dXJuKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyU3RhY2spLCAKICAgICAgICAgIGN1cnJfbW9kZSA9PSBzdG1fc3RhcnQgPyAic3RhcnQiIDogKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQgPyAiMTZiaXQiIDogIjMyYml0IiksCiAgICAgICAgICBjdXJyX3N3aXRjaCwgbmV4dF9zd2l0Y2gpOwoKICAgIHJldHVybiBUUlVFOwpkb25lX2VycjoKICAgIGN1cnJfbW9kZSA9IHN0bV9kb25lOwogICAgcmV0dXJuIEZBTFNFOwp9Cg==