LyoKICogQ29weXJpZ2h0IChjKSAyMDExLTIwMTggVGhlIExpbnV4IEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFByZXZpb3VzbHkgbGljZW5zZWQgdW5kZXIgdGhlIElTQyBsaWNlbnNlIGJ5IFF1YWxjb21tIEF0aGVyb3MsIEluYy4KICoKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IKICogYW55IHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUKICogYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsCiAqIGNvcGllcy4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTAogKiBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVECiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKICogQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCwgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SCiAqIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgovKgogKiBUaGlzIGZpbGUgd2FzIG9yaWdpbmFsbHkgZGlzdHJpYnV0ZWQgYnkgUXVhbGNvbW0gQXRoZXJvcywgSW5jLgogKiB1bmRlciBwcm9wcmlldGFyeSB0ZXJtcyBiZWZvcmUgQ29weXJpZ2h0IG93bmVyc2hpcCB3YXMgYXNzaWduZWQKICogdG8gdGhlIExpbnV4IEZvdW5kYXRpb24uCiAqLwoKLyoqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKiAKICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKiAgCgogIAogICAgXGZpbGUgY3NyTmVpZ2hib3JSb2FtLmMKICAKICAgIEltcGxlbWVudGF0aW9uIGZvciB0aGUgc2ltcGxlIHJvYW1pbmcgYWxnb3JpdGhtIGZvciA4MDIuMTFyIEZhc3QgdHJhbnNpdGlvbnMgYW5kIExlZ2FjeSByb2FtaW5nIGZvciBBbmRyb2lkIHBsYXRmb3JtLgogIAogICAgQ29weXJpZ2h0IChDKSAyMDEwIFF1YWxjb21tLCBJbmNvcnBvcmF0ZWQKICAKIAogICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICAgICAgICAgICAgICAgICAgICBFRElUIEhJU1RPUlkgRk9SIEZJTEUKCgogIFRoaXMgc2VjdGlvbiBjb250YWlucyBjb21tZW50cyBkZXNjcmliaW5nIGNoYW5nZXMgbWFkZSB0byB0aGUgbW9kdWxlLgogIE5vdGljZSB0aGF0IGNoYW5nZXMgYXJlIGxpc3RlZCBpbiByZXZlcnNlIGNocm9ub2xvZ2ljYWwgb3JkZXIuCgoKCiAgd2hlbiAgICAgICAgICAgd2hvICAgICAgICAgICAgICAgICB3aGF0LCB3aGVyZSwgd2h5Ci0tLS0tLS0tLS0gICAgICAgLS0tICAgICAgICAgICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjA4LzAxLzEwICAgICAgICAgIE11cmFsaSAgICAgICAgICAgICBDcmVhdGVkCgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwojaWZkZWYgV0xBTl9GRUFUVVJFX05FSUdIQk9SX1JPQU1JTkcKI2luY2x1ZGUgIndsYW5fcWN0X3dkYS5oIgojaW5jbHVkZSAicGFsQXBpLmgiCiNpbmNsdWRlICJjc3JJbnNpZGVBcGkuaCIKI2luY2x1ZGUgInNtc0RlYnVnLmgiCiNpbmNsdWRlICJsb2dEdW1wLmgiCiNpbmNsdWRlICJzbWVRb3NJbnRlcm5hbC5oIgojaW5jbHVkZSAid2xhbl9xY3RfdGwuaCIKI2luY2x1ZGUgInNtZUluc2lkZS5oIgojaW5jbHVkZSAidm9zX2RpYWdfY29yZV9ldmVudC5oIgojaW5jbHVkZSAidm9zX2RpYWdfY29yZV9sb2cuaCIKI2luY2x1ZGUgImNzckFwaS5oIgojaW5jbHVkZSAid2xhbl9xY3RfdGwuaCIKI2luY2x1ZGUgInNtZV9BcGkuaCIKI2luY2x1ZGUgImNzck5laWdoYm9yUm9hbS5oIgojaW5jbHVkZSAibWFjVHJhY2UuaCIKI2lmIGRlZmluZWQoRkVBVFVSRV9XTEFOX0VTRSkgJiYgIWRlZmluZWQoRkVBVFVSRV9XTEFOX0VTRV9VUExPQUQpCiNpbmNsdWRlICJjc3JFc2UuaCIKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfTEZSX01CQgojaW5jbHVkZSAiY3NyX3JvYW1fbWJiLmgiCiNlbmRpZgoKI2RlZmluZSBXTEFOX0ZFQVRVUkVfTkVJR0hCT1JfUk9BTUlOR19ERUJVRyAxCiNpZmRlZiBXTEFOX0ZFQVRVUkVfTkVJR0hCT1JfUk9BTUlOR19ERUJVRwojZGVmaW5lIE5FSUdIQk9SX1JPQU1fREVCVUcgc21zTG9nCiNlbHNlCiNkZWZpbmUgTkVJR0hCT1JfUk9BTV9ERUJVRyh4Li4uKQojZW5kaWYKCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0Q2hhbm5lbEluZm8odHBDc3JOZWlnaGJvclJvYW1DaGFubmVsSW5mbyByQ2hJbmZvKTsKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRDZmdMaXN0Q2hhblNjYW5Db250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjKTsKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRQcmVhdXRoQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYyk7CnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24odHBBbmlTaXJHbG9iYWwgcE1hYyk7CgpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayAodl9QVk9JRF90IHBBZGFwdGVyLCB2X1U4X3QgcnNzaU5vdGlmaWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUFZPSURfdCBwVXNlckN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1M3X3QgYXZnUnNzaSk7ClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgKHZfUFZPSURfdCBwQWRhcHRlciwgdl9VOF90IHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1BWT0lEX3QgcFVzZXJDdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9TN190IGF2Z1Jzc2kpOwp2b2lkIGNzck5laWdoYm9yUm9hbVJSTU5laWdoYm9yUmVwb3J0UmVzdWx0KHZvaWQgKmNvbnRleHQsIFZPU19TVEFUVVMgdm9zU3RhdHVzKTsKZUhhbFN0YXR1cyBjc3JSb2FtQ29weUNvbm5lY3RlZFByb2ZpbGUodHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VMzIgc2Vzc2lvbklkLCB0Q3NyUm9hbVByb2ZpbGUgKnBEc3RQcm9maWxlICk7CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpOwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMpOwojZW5kaWYKCnZfVThfdCAqY3NyTmVpZ2hib3JSb2FtU3RhdGVUb1N0cmluZyh2X1U4X3Qgc3RhdGUpCnsKICAgIHN3aXRjaChzdGF0ZSkKICAgIHsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DTE9TRUQgKTsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyApOwogICAgICAgIENBU0VfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWSApOwogICAgICAgIENBU0VfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkcgKTsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUgKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9MRlJfTUJCCiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9NQkJfUFJFQVVUSF9SRUFTU09DKTsKI2VuZGlmCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuICJlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVU5LTk9XTiI7CiAgICB9Cgp9CgovKiBTdGF0ZSBUcmFuc2l0aW9uIG1hY3JvICovCiNkZWZpbmUgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihuZXdTdGF0ZSlcCntcCiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucHJldk5laWdoYm9yUm9hbVN0YXRlID0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlO1wKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSA9IG5ld1N0YXRlO1wKICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9ERUJVRywgXAogICAgICAgICAgICAgICBGTCgiTmVpZ2hib3IgUm9hbSBUcmFuc2l0aW9uIGZyb20gc3RhdGUgJXMgPT0+ICVzIiksIFwKICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtU3RhdGVUb1N0cmluZyAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnByZXZOZWlnaGJvclJvYW1TdGF0ZSksIFwKICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtU3RhdGVUb1N0cmluZyAobmV3U3RhdGUpKTtcCn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1GcmVlTmVpZ2hib3JSb2FtQlNTTm9kZQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBmcmVlcyBhbGwgdGhlIGludGVybmFsIHBvaW50ZXJzIENTUiBOZWlnaGJvclJvYW0gQlNTIEluZm8gCiAgICAgICAgICAgIGFuZCBhbHNvIGZyZWVzIHRoZSBub2RlIGl0c2VsZgoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgbmVpZ2hib3JSb2FtQlNTTm9kZSAtIE5laWdoYm9yIFJvYW0gQlNTIE5vZGUgdG8gYmUgZnJlZWQKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtRnJlZU5laWdoYm9yUm9hbUJTU05vZGUodHBBbmlTaXJHbG9iYWwgcE1hYywgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIG5laWdoYm9yUm9hbUJTU05vZGUpCnsKICAgIGlmIChuZWlnaGJvclJvYW1CU1NOb2RlKQogICAgewogICAgICAgIGlmIChuZWlnaGJvclJvYW1CU1NOb2RlLT5wQnNzRGVzY3JpcHRpb24pCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2ZyZWUobmVpZ2hib3JSb2FtQlNTTm9kZS0+cEJzc0Rlc2NyaXB0aW9uKTsKICAgICAgICAgICAgbmVpZ2hib3JSb2FtQlNTTm9kZS0+cEJzc0Rlc2NyaXB0aW9uID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgdm9zX21lbV9mcmVlKG5laWdoYm9yUm9hbUJTU05vZGUpOwogICAgICAgIG5laWdoYm9yUm9hbUJTU05vZGUgPSBOVUxMOwogICAgfQoKICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVJlbW92ZVJvYW1hYmxlQVBMaXN0RW50cnkKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmVtb3ZlcyBhIGdpdmVuIGVudHJ5IGZyb20gdGhlIGdpdmVuIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBMaXN0IC0gVGhlIGxpc3QgZnJvbSB3aGljaCB0aGUgZW50cnkgc2hvdWxkIGJlIHJlbW92ZWQKICAgICAgICAgICAgcE5laWdoYm9yRW50cnkgLSBOZWlnaGJvciBSb2FtIEJTUyBOb2RlIHRvIGJlIHJlbW92ZWQKCiAgICBccmV0dXJuIFRSVUUgaWYgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQsIGVsc2UgRkFMU0UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1SZW1vdmVSb2FtYWJsZUFQTGlzdEVudHJ5KHRwQW5pU2lyR2xvYmFsIHBNYWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0RGJsTGlua0xpc3QgKnBMaXN0LCB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gcE5laWdoYm9yRW50cnkpCnsKICAgIGlmKHBMaXN0KQogICAgewogICAgICAgIHJldHVybiBjc3JMTFJlbW92ZUVudHJ5KHBMaXN0LCAmcE5laWdoYm9yRW50cnktPkxpc3QsIExMX0FDQ0VTU19MT0NLKTsKICAgIH0KCiAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlbW92aW5nIG5laWdoYm9yIEJTUyBub2RlIGZyb20gbGlzdCBmYWlsZWQuIEN1cnJlbnQgY291bnQgPSAlZCIpLCBjc3JMTENvdW50KHBMaXN0KSk7CgogICAgcmV0dXJuIGVBTklfQk9PTEVBTl9GQUxTRTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5CgogICAgXGJyaWVmICBHZXRzIHRoZSBlbnRyeSBuZXh0IHRvIHBhc3NlZCBlbnRyeS4gSWYgTlVMTCBpcyBwYXNzZWQsIHJldHVybiB0aGUgZW50cnkgaW4gdGhlIGhlYWQgb2YgdGhlIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBMaXN0IC0gVGhlIGxpc3QgZnJvbSB3aGljaCB0aGUgZW50cnkgc2hvdWxkIGJlIHJldHVybmVkCiAgICAgICAgICAgIHBOZWlnaGJvckVudHJ5IC0gTmVpZ2hib3IgUm9hbSBCU1MgTm9kZSB3aG9zZSBuZXh0IGVudHJ5IHNob3VsZCBiZSByZXR1cm5lZAoKICAgIFxyZXR1cm4gTmVpZ2hib3IgUm9hbSBCU1MgTm9kZSB0byBiZSByZXR1cm5lZAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHRwQW5pU2lyR2xvYmFsIHBNYWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdERibExpbmtMaXN0ICpwTGlzdCwgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBOZWlnaGJvckVudHJ5KQp7CiAgICB0TGlzdEVsZW0gKnBFbnRyeSA9IE5VTEw7CiAgICB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gcFJlc3VsdCA9IE5VTEw7CiAgICAKICAgIGlmKHBMaXN0KQogICAgewogICAgICAgIGlmKE5VTEwgPT0gcE5laWdoYm9yRW50cnkpCiAgICAgICAgewogICAgICAgICAgICBwRW50cnkgPSBjc3JMTFBlZWtIZWFkKHBMaXN0LCBMTF9BQ0NFU1NfTE9DSyk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHBFbnRyeSA9IGNzckxMTmV4dChwTGlzdCwgJnBOZWlnaGJvckVudHJ5LT5MaXN0LCBMTF9BQ0NFU1NfTE9DSyk7CiAgICAgICAgfQogICAgICAgIGlmKHBFbnRyeSkKICAgICAgICB7CiAgICAgICAgICAgIHBSZXN1bHQgPSBHRVRfQkFTRV9BRERSKHBFbnRyeSwgdENzck5laWdoYm9yUm9hbUJTU0luZm8sIExpc3QpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgcmV0dXJuIHBSZXN1bHQ7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0CgogICAgXGJyaWVmICAgRW1wdGllcyBhbmQgZnJlZXMgYWxsIHRoZSBub2RlcyBpbiB0aGUgcm9hbWFibGUgQVAgbGlzdCAKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBMaXN0IC0gTmVpZ2hib3IgUm9hbSBCU1MgTGlzdCB0byBiZSBlbXB0aWVkCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbUZyZWVSb2FtYWJsZUJTU0xpc3QodHBBbmlTaXJHbG9iYWwgcE1hYywgdERibExpbmtMaXN0ICpwTGlzdCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBSZXN1bHQgPSBOVUxMOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkVtcHR5aW5nIHRoZSBCU1MgbGlzdC4gQ3VycmVudCBjb3VudCA9ICVkIiksIGNzckxMQ291bnQocExpc3QpKTsKCiAgICAvKiBQaWNrIHVwIHRoZSBoZWFkLCByZW1vdmUgYW5kIGZyZWUgdGhlIG5vZGUgdGlsbCB0aGUgbGlzdCBiZWNvbWVzIGVtcHR5ICovCiAgICB3aGlsZSAoKHBSZXN1bHQgPSBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeShwTWFjLCBwTGlzdCwgTlVMTCkpICE9IE5VTEwpCiAgICB7CiAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVtb3ZlUm9hbWFibGVBUExpc3RFbnRyeShwTWFjLCBwTGlzdCwgcFJlc3VsdCk7CiAgICAgICAgY3NyTmVpZ2hib3JSb2FtRnJlZU5laWdoYm9yUm9hbUJTU05vZGUocE1hYywgcFJlc3VsdCk7CiAgICB9CiAgICByZXR1cm47Cn0KCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVRyaWdnZXJIYW5kb2ZmKHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8pCnsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfTEZSX01CQgogICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJlbmFibGVfbGZyX21iYiAlZCBpcyBtYmIgc3VwcG9ydGVkICVkIiksCiAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5lbmFibGVfbGZyX21iYiwKICAgICAgICAgICBzbWVfSXNGZWF0dXJlU3VwcG9ydGVkQnlGVyhNQUtFX0JFRk9SRV9CUkVBSykpOwoKICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmVuYWJsZV9sZnJfbWJiCiAgICAgICAgJiYgc21lX0lzRmVhdHVyZVN1cHBvcnRlZEJ5RlcoTUFLRV9CRUZPUkVfQlJFQUspCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgICAgICYmICghcE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpCiNlbmRpZgojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgICAgICYmICghcE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MpCiNlbmRpZgogICAgKSB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsCiAgICAgICAgICAgICAgIEZMKCJJc3N1aW5nIHByZWF1dGggcmVhc3NvYyIpKTsKICAgICAgICBzdGF0dXMgPSBjc3JfbmVpZ2hib3Jfcm9hbV9pc3N1ZV9wcmVhdXRoX3JlYXNzb2MocE1hYyk7CiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgcE1hYy0+ZnQuZnRTbWVDb250ZXh0LmlzX3ByZWF1dGhfbGZyX21iYiA9IGZhbHNlOwogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoImlzX3ByZWF1dGhfbGZyX21iYiAlZCIpLAogICAgICAgICAgICAgICAgICAgIHBNYWMtPmZ0LmZ0U21lQ29udGV4dC5pc19wcmVhdXRoX2xmcl9tYmIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgfQoKCiNlbmRpZgoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgJiYgIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykKI2VuZGlmCiAgICApCiAgICB7CiAgICAgICAgaWYgKChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pKQogICAgICAgIHsKICAgICAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHBNYWMpOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuID0gZVNNRV9ST0FNX1RSSUdHRVJfTk9ORTsKICAgICAgICAgICAgdm9zX21lbV9zZXQoJnBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtYnNzSWRbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbWJzc0lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgMHhGRik7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiMTFSIFJlYXNzb2MgaW5kaWNhdGlvbiByZWNlaXZlZCBpbiIKICAgICAgICAgICAgICAgICAgICJ1bmV4cGVjdGVkIHN0YXRlICVzIiksCiAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICBWT1NfQVNTRVJUKDApOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKI2VuZGlmCgojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAmJiAhY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKQojZW5kaWYKICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHBNYWMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJFU0UgUmVhc3NvYyBpbmRpY2F0aW9uIHJlY2VpdmVkIGluIHVuZXhwZWN0ZWQgc3RhdGUgJXMiKSwKICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZShwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgICAgIFZPU19BU1NFUlQoMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgaWYgKGNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLCBDU1JfU0VTU0lPTl9JRF9JTlZBTElEKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgICB8fCBjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpIHx8CiAgICAgICAgICAgICAgICAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pCiNlbmRpZgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlUHJlYXV0aFJlcShwTWFjKTsKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuID0gZVNNRV9ST0FNX1RSSUdHRVJfTk9ORTsKICAgICAgICAgICAgICAgICAgICB2b3NfbWVtX3NldCgmcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1ic3NJZFswXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1ic3NJZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhGRik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJMRlIgUmVhc3NvYyBpbmRpY2F0aW9uIHJlY2VpdmVkIGluIgogICAgICAgICAgICAgICAgICAgICAgICAgICAidW5leHBlY3RlZCBzdGF0ZSAlcyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICAgICAgVk9TX0FTU0VSVCgwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiNlbmRpZgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVxdWVzdEhhbmRvZmYocE1hYyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOb24tMTFSIFJlYXNzb2MgaW5kaWNhdGlvbiByZWNlaXZlZCBpbiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgInVuZXhwZWN0ZWQgc3RhdGUgJXMgb3IgUm9hbWluZyBpcyBkaXNhYmxlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgIHJldHVybiBzdGF0dXM7Cn0KClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtVXBkYXRlRmFzdFJvYW1pbmdFbmFibGVkKHRwQW5pU2lyR2xvYmFsIHBNYWMsIGNvbnN0IHZfQk9PTF90IGZhc3RSb2FtRW5hYmxlZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBWT1NfU1RBVFVTIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgaWYgKFZPU19UUlVFID09IGZhc3RSb2FtRW5hYmxlZCkKICAgICAgICB7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsIFJFQVNPTl9DT05ORUNUKTsKICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIG5laWdoYm9yIGxvb2t1cCBET1dOIGV2ZW50IHdpdGggVEwsIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKTsKICAgICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBET1dOIGV2ZW50IG9ubHkgKi8KICAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgICBpZiAoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKFZPU19GQUxTRSA9PSBmYXN0Um9hbUVuYWJsZWQpCiAgICAgICAgewogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJDdXJyZW50bHkgaW4gQ09OTkVDVEVEIHN0YXRlLCBzbyBkZXJlZ2lzdGVyIGFsbCBldmVudHMiKSk7CiAgICAgICAgICAgIC8qIERlLXJlZ2lzdGVyIGV4aXN0aW5nIGxvb2t1cCBVUC9ET1dOLCBSc3NpIGluZGljYXRpb25zICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QLCBSRUFTT05fRElTQ09OTkVDVEVEKTsKICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIElOSVQgc3RhdGUsIE5vdGhpbmcgdG8gZG8iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLAogICAgICAgIEZMKCJVbmV4cGVjdGVkIHN0YXRlICVzLCByZXR1cm5pbmcgZmFpbHVyZSIpLAogICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1VcGRhdGVFc2VNb2RlRW5hYmxlZCh0cEFuaVNpckdsb2JhbCBwTWFjLCBjb25zdCB2X0JPT0xfdCBlc2VNb2RlKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIFZPU19TVEFUVVMgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwoKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBpZiAoVk9TX1RSVUUgPT0gZXNlTW9kZSkKICAgICAgICB7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIG5laWdoYm9yIGxvb2t1cCBET1dOIGV2ZW50IHdpdGggVEwsIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwgUkVBU09OX0NPTk5FQ1QpOwogICAgICAgICAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBET1dOIGV2ZW50IG9ubHkgKi8KICAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgICBpZiAoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKFZPU19GQUxTRSA9PSBlc2VNb2RlKQogICAgICAgIHsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIENPTk5FQ1RFRCBzdGF0ZSwgc28gZGVyZWdpc3RlciBhbGwgZXZlbnRzIikpOwogICAgICAgICAgICAvKiBEZS1yZWdpc3RlciBleGlzdGluZyBsb29rdXAgVVAvRE9XTiwgUnNzaSBpbmRpY2F0aW9ucyAqLwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RPUCwgUkVBU09OX0RJU0NPTk5FQ1RFRCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkN1cnJlbnRseSBpbiBJTklUIHN0YXRlLCBOb3RoaW5nIHRvIGRvIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIlVuZXhwZWN0ZWQgc3RhdGUgJWQsIHJldHVybmluZyBmYWlsdXJlIiksIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICB9CiAgICByZXR1cm4gdm9zU3RhdHVzOwp9CgojZW5kaWYKCgpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVNldExvb2t1cFJzc2lUaHJlc2hvbGQodHBBbmlTaXJHbG9iYWwgcE1hYywgdl9VOF90IG5laWdoYm9yTG9va3VwUnNzaVRocmVzaG9sZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBWT1NfU1RBVFVTIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIENPTk5FQ1RFRCBzdGF0ZSwgc28gZGVyZWdpc3RlciBhbGwgYW5kIHJlLXJlZ2lzdGVyIGZvciBET1dOIGV2ZW50IGFnYWluIikpOwoKICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gbmVpZ2hib3JMb29rdXBSc3NpVGhyZXNob2xkOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgPSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkOwoKICAgICAgICAvKiBEZS1yZWdpc3RlciBleGlzdGluZyBsb29rdXAgVVAvRE9XTiwgUnNzaSBpbmRpY2F0aW9ucyAqLwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKQogICAgICAgIHsKICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1VQREFURV9DRkcsIFJFQVNPTl9MT09LVVBfVEhSRVNIX0NIQU5HRUQpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewojZW5kaWYKICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwoKICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsCiAgICAgICAgICAgRkwoIlJlZ2lzdGVyaW5nIG5laWdoYm9yIGxvb2t1cCBET1dOIGV2ZW50IHdpdGggVEwsIFJTU0kgPSAlZCIpLAogICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQpOwogICAgICAgICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCBmb3IgRE9XTiBldmVudCBvbmx5ICovCiAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwKICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiAgICAgICAgICAgaWYgKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgICB7CiAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICB9CiNlbmRpZgogICAgfQogICAgZWxzZSBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkN1cnJlbnRseSBpbiBJTklUIHN0YXRlLCBzYWZlIHRvIHNldCBsb29rdXBSc3NpIHRocmVzaG9sZCIpKTsKICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gbmVpZ2hib3JMb29rdXBSc3NpVGhyZXNob2xkOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgPSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwKICAgICAgICBGTCgiVW5leHBlY3RlZCBzdGF0ZSAlcywgcmV0dXJuaW5nIGZhaWx1cmUiKSwKICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZShwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sKCiAgICBcYnJpZWYgUmVhc3NvYyBjYWxsYmFjayBpbnZva2VkIGJ5IFRMIG9uIGNyb3NzaW5nIHRoZSByZWdpc3RlcmVkIHJlLWFzc29jIHRocmVzaG9sZC4KICAgICAgICAgICBEaXJlY3RseSB0cmlnZ2VyZSBITyBpbiBjYXNlIG9mIG5vbi0xMXIgYXNzb2NpYXRpb24KICAgICAgICAgICBJbiBjYXNlIG9mIDExUiBhc3NvY2lhdGlvbiwgdHJpZ2dlcnMgYSBwcmUtYXV0aCBldmVudHVhbGx5IGZvbGxvd2VkIGJ5IGFjdHVhbCBITwoKICAgIFxwYXJhbSAgcEFkYXB0ZXIgLSBWT1MgQ29udGV4dAogICAgICAgICAgICB0cmFmZmljU3RhdHVzIC0gVVAvRE9XTiBpbmRpY2F0aW9uIGZyb20gVEwKICAgICAgICAgICAgcFVzZXJDdHh0IC0gUGFyYW1ldGVyIGZvciBjYWxsYmFjayByZWdpc3RlcmVkIGR1cmluZyBjYWxsYmFjayByZWdpc3RyYXRpb24uIFNob3VsZCBiZSBwTWFjCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjayh2X1BWT0lEX3QgcEFkYXB0ZXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9VOF90IHRyYWZmaWNTdGF0dXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9QVk9JRF90IHBVc2VyQ3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUzdfdCAgIGF2Z1Jzc2kpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVCggcFVzZXJDdHh0ICk7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIFZPU19TVEFUVVMgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOyAgIAoKICAgIGlmIChlU01FX1JPQU1fVFJJR0dFUl9GQVNUX1JPQU0gIT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJEZXJlZ2lzdGVyaW5nIERPV04gZXZlbnQgcmVhc3NvYyBjYWxsYmFjayB3aXRoIFRMLiBUaHJlc2hvbGQgUlNTSSA9ICVkIFJlcG9ydGVkIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgYXZnUnNzaSk7CgogICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgZGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICB9CgogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJjdmQgcmVhc3NvYyBub3RpZmljYXRpb24tZGVyZWdpc3RlciBVUCBpbmRpY2F0aW9uLiBUaHJlc2hvbGQgUlNTSSA9ICVkIFJlcG9ydGVkIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSwgYXZnUnNzaSk7CiAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX0RlcmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwoKICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgIHsKICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgfQogICAgfQogICAgLyogV2UgZG9udCBuZWVkIHRvIHJ1biB0aGlzIHRpbWVyIGFueSBtb3JlLiAqLwogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIpOwoKICAgIGNzck5laWdoYm9yUm9hbVRyaWdnZXJIYW5kb2ZmKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvKTsKCiAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKkNsZWFuVVAgUm91dGluZXMqLwpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldENoYW5uZWxJbmZvKHRwQ3NyTmVpZ2hib3JSb2FtQ2hhbm5lbEluZm8gckNoSW5mbykKewogICAgICAgIGlmICgockNoSW5mby0+SUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID09IEZBTFNFKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAockNoSW5mby0+Y3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzKSkKICAgICAgICB7CiAgICAgICAgICAgICAgICByQ2hJbmZvLT5jdXJyZW50Q2hhbkluZGV4ID0gQ1NSX05FSUdIQk9SX1JPQU1fSU5WQUxJRF9DSEFOTkVMX0lOREVYOwogICAgICAgICAgICAgICAgckNoSW5mby0+Y3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKCiAgICAgICAgICAgICAgICBpZiAockNoSW5mby0+Y3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCkKICAgICAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHJDaEluZm8tPmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwoKICAgICAgICAgICAgICAgIHJDaEluZm8tPmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgckNoSW5mby0+Y2hhbkxpc3RTY2FuSW5Qcm9ncmVzcyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICB9CiAgICAgICAgZWxzZSAKICAgICAgICB7CiAgICAgICAgICAgICAgICByQ2hJbmZvLT5jdXJyZW50Q2hhbkluZGV4ID0gMDsKICAgICAgICAgICAgICAgIHJDaEluZm8tPmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICB9Cn0KCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0Q2ZnTGlzdENoYW5TY2FuQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgICAgICAvKiBTdG9wIG5laWdoYm9yIHNjYW4gdGltZXIgKi8KICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKCiAgICAgICAgLyogU3RvcCBuZWlnaGJvciBzY2FuIHJlc3VsdHMgcmVmcmVzaCB0aW1lciAqLwogICAgICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKCiAgICAgICAgLyogU3RvcCBlbXB0eSBzY2FuIHJlc3VsdHMgcmVmcmVzaCB0aW1lciAqLwogICAgICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKCiAgICAgICAgLyogQWJvcnQgYW55IG9uZ29pbmcgc2NhbiAqLwogICAgICAgIGlmIChlQU5JX0JPT0xFQU5fVFJVRSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJzcFBlbmRpbmcpCiAgICAgICAgewogICAgICAgICAgICBjc3JTY2FuQWJvcnRNYWNTY2FuKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9TQ0FOX0FCT1JUX0RFRkFVTFQpOwogICAgICAgIH0KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgICAgIC8qIFJlc2V0IHJvYW0gY2hhbm5lbCBsaXN0IGluZm9ybWF0aW9uICovCiAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDaGFubmVsSW5mbygmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mbyk7Cn0KCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0UHJlYXV0aENvbnRyb2xJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgICAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9FU0UpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAvKiBQdXJnZSBwcmUtYXV0aCBmYWlsIGxpc3QgKi8KICAgICAgICBjc3JOZWlnaGJvclJvYW1QdXJnZVByZWF1dGhGYWlsZWRMaXN0KHBNYWMpOwojZW5kaWYKCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlYXV0aFJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPSAwOwojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgICAgICAvKiBEbyBub3QgZnJlZSB1cCB0aGUgcHJlYXV0aCBkb25lIGxpc3QgaGVyZSAqLwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtID0gMDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKICAgICAgICB2b3NfbWVtX3plcm8ocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm8sIHNpemVvZih0Q3NyTmVpZ2hib3JSZXBvcnRCc3NJbmZvKSAqIE1BWF9CU1NfSU5fTkVJR0hCT1JfUlBUKTsKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0ggPSAwOwogICAgdm9zX21lbV96ZXJvKCZwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8sIHNpemVvZih0Q3NySGFuZG9mZlJlcXVlc3QpKTsKI2VuZGlmCgp9CgpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgICAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgICAgICBWT1NfU1RBVFVTICAgICAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CgogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkRlcmVnaXN0ZXIgbmVpZ2hib3IgbG9va3VwIFVQIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSk7CgogICAgICAgIC8qIERlcmVnaXN0ZXIgcmVhc3NvYyBjYWxsYmFjay4gSWdub3JlIHJldHVybiBzdGF0dXMgKi8KICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsIAogICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsIAogICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKCiAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICB9CgogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkRlcmVnaXN0ZXJpbmcgcmVhc3NvYyBET1dOIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpKTsKCiAgICAgICAgLyogRGVyZWdpc3RlciByZWFzc29jIGNhbGxiYWNrLiBJZ25vcmUgcmV0dXJuIHN0YXR1cyAqLwogICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sIAogICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKCiAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCIgQ291bGRuJ3QgZGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sgd2l0aCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgfQoKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsCiAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJEZXJlZ2lzdGVyaW5nIG5laWdoYm9yTG9va3VwIERPV04gY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkIiksIAogICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSk7CgogICAgICAgIC8qIERlcmVnaXN0ZXIgbmVpZ2hib3IgbG9va3VwIGNhbGxiYWNrLiBJZ25vcmUgcmV0dXJuIHN0YXR1cyAqLwogICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CgogICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiIENvdWxkbid0IGRlcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgfQoKICAgICAgICAvKiBSZXNldCB0aHJlc2hvbGRzIG9ubHkgYWZ0ZXIgZGVyZWdpc3RlcmluZyBET1dOIGV2ZW50IGZyb20gVEwgKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSAwOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSA9IDA7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSA9IERFRkFVTFRfU0NBTjsKI2VuZGlmCn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gd2lsbCByZXNldCB0aGUgbmVpZ2hib3Igcm9hbSBjb250cm9sIGluZm8gZGF0YSBzdHJ1Y3R1cmVzLiAKICAgICAgICAgICAgVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgaW52b2tlZCB3aGVuZXZlciB3ZSBtb3ZlIHRvIENPTk5FQ1RFRCBzdGF0ZSBmcm9tIAogICAgICAgICAgICBhbnkgc3RhdGUgb3RoZXIgdGhhbiBJTklUIHN0YXRlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDaGFubmVsSW5mbygmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mbyk7CiAgICBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgCiAvKiBXZSBkb250IG5lZWQgdG8gcnVuIHRoaXMgdGltZXIgYW55IG1vcmUuICovCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIC8qIERvIG5vdCBmcmVlIHVwIHRoZSBwcmVhdXRoIGRvbmUgbGlzdCBoZXJlICovCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlYXV0aFJzcFBlbmRpbmcgPSAwOwogICAgdm9zX21lbV96ZXJvKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvLCBzaXplb2YodENzck5laWdoYm9yUmVwb3J0QnNzSW5mbykgKiBNQVhfQlNTX0lOX05FSUdIQk9SX1JQVCk7CiNlbmRpZgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIID0gMDsKICAgIHZvc19tZW1femVybygmcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLCBzaXplb2YodENzckhhbmRvZmZSZXF1ZXN0KSk7CiNlbmRpZgp9Cgp2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0UmVwb3J0U2NhblN0YXRlQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkICAgICAgICAgICAgPSAgIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQ7CiAgICB2b3NfbWVtX3NldChwTmVpZ2hib3JSb2FtSW5mby0+Y3VyckFQYnNzaWQsIHNpemVvZih0Q3NyQnNzaWQpLCAwKTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmlzVk9BZG1pdHRlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5NaW5RQnNzTG9hZFJlcXVpcmVkID0gMDsKI2VuZGlmCgogICAgLyogU3RvcCBzY2FuIHJlZnJlc2ggdGltZXIgKi8KICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgIC8qIFN0b3AgZW1wdHkgc2NhbiByZXN1bHRzIHJlZnJlc2ggdGltZXIgKi8KICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAvKiBQdXJnZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOyAKICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVJlc2V0SW5pdFN0YXRlQ29udHJvbEluZm8KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gd2lsbCByZXNldCB0aGUgbmVpZ2hib3Igcm9hbSBjb250cm9sIGluZm8gZGF0YSBzdHJ1Y3R1cmVzLiAKICAgICAgICAgICAgVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgaW52b2tlZCB3aGVuZXZlciB3ZSBtb3ZlIHRvIENPTk5FQ1RFRCBzdGF0ZSBmcm9tIAogICAgICAgICAgICBJTklUIHN0YXRlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldEluaXRTdGF0ZUNvbnRyb2xJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKCiAgICAvKiBJbiBhZGRpdGlvbiB0byB0aGUgYWJvdmUgcmVzZXRzLCB3ZSBzaG91bGQgY2xlYXIgb2ZmIHRoZSBjdXJBUEJzc0lkL1Nlc3Npb24gSUQgaW4gdGhlIHRpbWVycyAqLwogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRSZXBvcnRTY2FuU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKfQoKCgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUJzc0lkU2NhbkZpbHRlcgoKICAgIFxicmllZiAgVGhpcyBBUEkgaXMgdXNlZCB0byBwcmVwYXJlIGEgZmlsdGVyIHRvIG9idGFpbiBzY2FuIHJlc3VsdHMgd2hlbiAKICAgICAgICAgICAgd2UgY29tcGxldGUgdGhlIHNjYW4gaW4gdGhlIFJFUE9SVF9TQ0FOIHN0YXRlIGFmdGVyIHJlY2VpdmluZyBhIAogICAgICAgICAgICB2YWxpZCBuZWlnaGJvciByZXBvcnQgZnJvbSBBUC4gVGhpcyBmaWx0ZXIgaW5jbHVkZXMgQlNTSURzIHJlY2VpdmVkIGZyb20gCiAgICAgICAgICAgIHRoZSBuZWlnaGJvciByZXBvcnQgZnJvbSB0aGUgQVAgaW4gYWRkaXRpb24gdG8gdGhlIG90aGVyIGZpbHRlciBwYXJhbWV0ZXJzIAogICAgICAgICAgICBjcmVhdGVkIGZyb20gY29ubmVjdGVkIHByb2ZpbGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBTY2FuRmlsdGVyIC0gU2NhbiBmaWx0ZXIgdG8gYmUgZmlsbGVkIGFuZCByZXR1cm5lZAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNmdWwgZmlsdGVyIGNyZWF0aW9uLCBjb3JyZXNwb25kaW5nIGVycm9yIAogICAgICAgICAgICBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtQnNzSWRTY2FuRmlsdGVyKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRDc3JTY2FuUmVzdWx0RmlsdGVyICpwU2NhbkZpbHRlcikKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0QU5JX1U4IGkgPSAwOwoKICAgIFZPU19BU1NFUlQocFNjYW5GaWx0ZXIgIT0gTlVMTCk7CiAgICBpZiAocFNjYW5GaWx0ZXIgPT0gTlVMTCkKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIHZvc19tZW1femVybyhwU2NhbkZpbHRlciwgc2l6ZW9mKHRDc3JTY2FuUmVzdWx0RmlsdGVyKSk7CgogICAgcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyA9IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydDsKICAgIHBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWQgPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodFNpck1hY0FkZHIpICogcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyk7CiAgICBpZiAoTlVMTCA9PSBwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2NhbiBGaWx0ZXIgQlNTSUQgbWVtIGFsbG9jIGZhaWxlZCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTEVEX0FMTE9DOwogICAgfQoKICAgIHZvc19tZW1femVybyhwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpICogcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyk7CgogICAgLyogUG9wdWxhdGUgdGhlIEJTU0lEIGZyb20gTmVpZ2hib3IgQlNTIGluZm8gcmVjZWl2ZWQgZnJvbSBuZWlnaGJvciByZXBvcnQgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzOyBpKyspCiAgICB7CiAgICAgICAgdm9zX21lbV9jb3B5KCZwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkW2ldLCAKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvW2ldLm5laWdoYm9yQnNzSWQsIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgfQoKICAgIC8qIEZpbGwgb3RoZXIgZ2VuZXJhbCBzY2FuIGZpbHRlciBwYXJhbXMgKi8KICAgIHJldHVybiBjc3JOZWlnaGJvclJvYW1QcmVwYXJlU2NhblByb2ZpbGVGaWx0ZXIocE1hYywgcFNjYW5GaWx0ZXIpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbExpc3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gZW1wdGllcyB0aGUgcHJlYXV0aCBmYWlsIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxMaXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIlB1cmdpbmcgdGhlIHByZWF1dGggZmFpbCBsaXN0IikpOwogICAgd2hpbGUgKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzKQogICAgewogICAgICAgIHZvc19tZW1femVybyhwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubWFjQWRkcmVzc1twTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcy0xXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MtLTsKICAgIH0KICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUFkZEJzc0lkVG9QcmVhdXRoRmFpbExpc3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gYWRkcyB0aGUgZ2l2ZW4gQlNTSUQgdG8gdGhlIFByZWF1dGggZmFpbCBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBic3NJZCAtIEJTU0lEIHRvIGJlIGFkZGVkIHRvIHRoZSBwcmVhdXRoIGZhaWwgbGlzdAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBlSEFMX1NUQVRVU19GQUlMVVJFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1BZGRCc3NJZFRvUHJlYXV0aEZhaWxMaXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRTaXJNYWNBZGRyIGJzc0lkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCIgQWRkZWQgQlNTSUQgIk1BQ19BRERSRVNTX1NUUiIgdG8gUHJlYXV0aCBmYWlsZWQgbGlzdCIpLAogICAgICAgICAgICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShic3NJZCkpOwoKCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzICsgMSkgPgogICAgICAgICAgICBNQVhfTlVNX1BSRUFVVEhfRkFJTF9MSVNUX0FERFJFU1MpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJQcmVhdXRoIGZhaWwgbGlzdCBhbHJlYWR5IGZ1bGwuLiBDYW5ub3QgYWRkIG5ldyBvbmUiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm1hY0FkZHJlc3NbCiAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzXSwKICAgICAgICAgICAgICAgICBic3NJZCwKICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzKys7CiAgICAKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXNQcmVhdXRoQ2FuZGlkYXRlCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGNoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBNQUMgYWRkcmVzcyBpcyBhbHJlYWR5IAogICAgICAgICAgICBwcmVzZW50IGluIHRoZSBwcmVhdXRoIGZhaWwgbGlzdCBhbmQgcmV0dXJucyBUUlVFL0ZBTFNFIGFjY29yZGluZ2x5CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUFOSV9CT09MRUFOX1RSVUUgaWYgcHJlYXV0aCBjYW5kaWRhdGUsIGVBTklfQk9PTEVBTl9GQUxTRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUodHBBbmlTaXJHbG9iYWwgcE1hYywgdFNpck1hY0FkZHIgYnNzSWQpCnsKICAgIHRBTklfVTggaSA9IDA7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIGlmIChjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgewogICAgICAgIHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRTsKICAgIH0KI2VuZGlmCiAgICBpZiAoMCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcykKICAgICAgICByZXR1cm4gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAKICAgIGZvciAoaSA9IDA7IGkgPCBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzczsgaSsrKQogICAgewogICAgICAgIGlmIChWT1NfVFJVRSA9PSB2b3NfbWVtX2NvbXBhcmUocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm1hY0FkZHJlc3NbaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKSkKICAgICAgICB7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkJTU0lEICJNQUNfQUREUkVTU19TVFIiIGFscmVhZHkgcHJlc2VudCBpbiBwcmVhdXRoIGZhaWwgbGlzdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShic3NJZCkpOwogICAgICAgICAgICByZXR1cm4gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gZUFOSV9CT09MRUFOX1RSVUU7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXNzdWVzIHByZWF1dGggcmVxdWVzdCB0byBQRSB3aXRoIHRoZSAxc3QgQVAgZW50cnkgaW4gdGhlIAogICAgICAgICAgICByb2FtYWJsZSBBUCBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBlSEFMX1NUQVRVU19GQUlMVVJFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvICAgIHBOZWlnaGJvckJzc05vZGU7CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICB0Q3NyUm9hbUluZm8gKnJvYW1JbmZvOwojZW5kaWYKICAgIAogICAgLyogVGhpcyBtdXN0IG5vdCBiZSB0cnVlIGhlcmUgKi8KICAgIFZPU19BU1NFUlQocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlYXV0aFJzcFBlbmRpbmcgPT0gZUFOSV9CT09MRUFOX0ZBTFNFKTsKCiAgICAvKiBJc3N1ZSBQcmVhdXRoIHJlcXVlc3QgdG8gUEUgaGVyZSAqLwogICAgLyogTmVlZCB0byBpc3N1ZSB0aGUgcHJlYXV0aCByZXF1ZXN0IHdpdGggdGhlIEJTU0lEIHRoYXQgaXMgdGhlcmUgaW4gdGhlIGhlYWQgb2YgdGhlIHJvYW1hYmxlIEFQIGxpc3QgKi8KICAgIC8qIFBhcmFtZXRlcnMgdGhhdCBzaG91bGQgYmUgcGFzc2VkIGFyZSBCU1NJRCwgQ2hhbm5lbCBudW1iZXIgYW5kIHRoZSBuZWlnaGJvclNjYW5QZXJpb2QocHJvYmFibHkpICovCiAgICAvKiBJZiByb2FtYWJsZUFQTGlzdCBnZXRzIGVtcHR5LCBzaG91bGQgdHJhbnNpdGlvbiB0byBSRVBPUlRfU0NBTiBzdGF0ZSAqLwogICAgcE5laWdoYm9yQnNzTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsIE5VTEwpOwoKICAgIGlmIChOVUxMID09IHBOZWlnaGJvckJzc05vZGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJSb2FtYWJsZSBBUCBsaXN0IGlzIGVtcHR5Li4gIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgZWxzZQogICAgewojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICAgICAgLyogTEZSIG1ldHJpY3MgLSBwcmUtYXV0aCBpbml0aWF0aW9uIG1ldHJpYy4KICAgICAgICAgICBTZW5kIHRoZSBldmVudCB0byBzdXBwbGljYW50IHRoYXQgcHJlLWF1dGggd2FzIGluaXRpYXRlZCAqLwogICAgICAgIHJvYW1JbmZvID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgICAgIGlmIChOVUxMID09IHJvYW1JbmZvKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQhIikpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2NvcHkoKHZvaWQgKilyb2FtSW5mby0+YnNzaWQsCiAgICAgICAgICAgICAgICAodm9pZCAqKXBOZWlnaGJvckJzc05vZGUtPnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQsCiAgICAgICAgICAgICAgICBzaXplb2YodENzckJzc2lkKSk7CiAgICAgICAgICAgIGNzclJvYW1DYWxsQ2FsbGJhY2socE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2FtSW5mbywgMCwgZUNTUl9ST0FNX1BSRUFVVEhfSU5JVF9OT1RJRlksIDApOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocm9hbUluZm8pOwogICAgICAgIH0KI2VuZGlmCgogICAgICAgIHN0YXR1cyA9IGNzclJvYW1FbnF1ZXVlUHJlYXV0aChwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLCBwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24sCiAgICAgICAgICAgICAgICBlQ3NyUGVyZm9ybVByZWF1dGgsIGVBTklfQk9PTEVBTl9UUlVFKTsKCiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJCZWZvcmUgUHJlLUF1dGg6IEJTU0lEICJNQUNfQUREUkVTU19TVFIiLCBDaDolZCIpLAogICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmJzc0lkKSwKICAgICAgICAgICAgICAgKGludClwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmNoYW5uZWxJZCk7CgogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2VuZCBQcmVhdXRoIHJlcXVlc3QgdG8gUEUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIHN0YXR1cyk7CiAgICAgICAgICAgIHJldHVybiBzdGF0dXM7CiAgICAgICAgfQogICAgfQogICAgCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVhdXRoUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9UUlVFOwoKICAgIC8qIEluY3JlbWVudCB0aGUgcHJlYXV0aCByZXRyeSBjb3VudCAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMrKzsKICAgIAogICAgLyogVHJhbnNpdGlvbiB0aGUgc3RhdGUgdG8gcHJlYXV0aGVudGljYXRpbmcgKi8KICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhFTlRJQ0FUSU5HKQogICAgCiAgICByZXR1cm4gc3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHJlYXV0aFJzcEhhbmRsZXIKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaGFuZGxlIHRoZSBQcmVhdXRoIHJlc3BvbnNlIGZyb20gUEUKICAgICAgICAgICAgRXZlcnkgcHJlYXV0aCBpcyBhbGxvd2VkIG1heCAzIHRyaWVzIGlmIGl0IGZhaWxzLiBJZiBhIGJzc2lkIGZhaWxlZCAKICAgICAgICAgICAgZm9yIG1vcmUgdGhhbiBNQVhfVFJJRVMsIHdlIHdpbGwgcmVtb3ZlIGl0IGZyb20gdGhlIGxpc3QgYW5kIHRyeSAKICAgICAgICAgICAgd2l0aCB0aGUgbmV4dCBub2RlIGluIHRoZSByb2FtYWJsZSBBUCBsaXN0IGFuZCBhZGQgdGhlIEJTU0lEIHRvIHByZS1hdXRoIGZhaWxlZCAKICAgICAgICAgICAgbGlzdC4gSWYgbm8gbW9yZSBlbnRyaWVzIHByZXNlbnQgaW4gCiAgICAgICAgICAgIHJvYW1hYmxlIEFQIGxpc3QsIHRyYW5zaXRpb24gdG8gUkVQT1JUX1NDQU4gc3RhdGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIGxpbVN0YXR1cyAtIGVTSVJfU1VDQ0VTUy9lU0lSX0ZBSUxVUkUvZVNJUl9MSU1fTUFYX1NUQV9SRUFDSEVEX0VSUk9SLwogICAgICAgICAgICAgICAgICAgICBlU0lUX0xJTV9BVVRIX1JTUF9USU1FT1VUIHN0YXR1cyBmcm9tIFBFCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MgKGkuZS4gcHJlLWF1dGggcHJvY2Vzc2VkKSwKICAgICAgICAgICAgZUhBTF9TVEFUVVNfRkFJTFVSRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUHJlYXV0aFJzcEhhbmRsZXIodHBBbmlTaXJHbG9iYWwgcE1hYywgdFNpclJldFN0YXR1cyBsaW1TdGF0dXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIFZPU19TVEFUVVMgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIGVIYWxTdGF0dXMgIHByZWF1dGhQcm9jZXNzZWQgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBQcmVhdXRoUnNwTm9kZSA9IE5VTEw7CiAgICB0Q3NyUm9hbVNlc3Npb24gKnBTZXNzaW9uOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICB0Q3NyUm9hbUluZm8gKnJvYW1JbmZvOwojZW5kaWYKCiAgICBpZiAoZUFOSV9CT09MRUFOX0ZBTFNFID09IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nKQogICAgewogICAgICAgICAgICAKICAgICAgICAgICAgLyogVGhpcyBjYW4gaGFwcGVuIHdoZW4gd2UgZGlzY29ubmVjdCBpbW1lZGlhdGVseQogICAgICAgICAgICAgKiBhZnRlciBzZW5kaW5nIGEgcHJlLWF1dGggcmVxdWVzdC4gRHVyaW5nIHByb2Nlc3NpbmcKICAgICAgICAgICAgICogb2YgdGhlIGRpc2Nvbm5lY3QgY29tbWFuZCwgd2Ugd291bGQgaGF2ZSByZXNldAogICAgICAgICAgICAgKiBwcmVhdXRoUnNwUGVuZGluZyBhbmQgdHJhbnNpdGlvbmVkIHRvIElOSVQgc3RhdGUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIlVuZXhwZWN0ZWQgcHJlLWF1dGggcmVzcG9uc2UgaW4gc3RhdGUgJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpOwogICAgICAgICAgICBwcmVhdXRoUHJvY2Vzc2VkID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgZ290byBERVFfUFJFQVVUSDsKICAgIH0gICAgCgogICAgLy8gV2UgY2FuIHJlY2VpdmUgaXQgaW4gdGhlc2UgMiBzdGF0ZXMuCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSAhPSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkcpICYmCiAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSAhPSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4pKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywKICAgICAgICBGTCgiUHJlYXV0aCByZXNwb25zZSByZWNlaXZlZCBpbiBzdGF0ZSAlcyIpLAogICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgIHByZWF1dGhQcm9jZXNzZWQgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIGdvdG8gREVRX1BSRUFVVEg7CiAgICB9CgogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlYXV0aFJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgaWYgKGVTSVJfU1VDQ0VTUyA9PSBsaW1TdGF0dXMpCiAgICB7CiAgICAgICAgcFByZWF1dGhSc3BOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCwgTlVMTCk7CiAgICB9CiAgICBpZiAoKGVTSVJfU1VDQ0VTUyA9PSBsaW1TdGF0dXMpICYmIChOVUxMICE9IHBQcmVhdXRoUnNwTm9kZSkpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiUHJlYXV0aCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5IGFmdGVyICVkIHRyaWVzIiksIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzKTsKCiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJBZnRlciBQcmUtQXV0aDogQlNTSUQgIk1BQ19BRERSRVNTX1NUUiIsIENoOiVkIiksCiAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKHBQcmVhdXRoUnNwTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCksCiAgICAgICAgICAgICAgIChpbnQpcFByZWF1dGhSc3BOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmNoYW5uZWxJZCk7CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICAgICAgLyogTEZSIG1ldHJpY3MgLSBwcmUtYXV0aCBjb21wbGV0aW9uIG1ldHJpYy4KICAgICAgICAgICBTZW5kIHRoZSBldmVudCB0byBzdXBwbGljYW50IHRoYXQgcHJlLWF1dGggc3VjY2Vzc2Z1bGx5IGNvbXBsZXRlZCAqLwogICAgICAgIHJvYW1JbmZvID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgICAgIGlmIChOVUxMID09IHJvYW1JbmZvKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQhIikpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2NvcHkoKHZvaWQgKilyb2FtSW5mby0+YnNzaWQsCiAgICAgICAgICAgICAgICAodm9pZCAqKXBQcmVhdXRoUnNwTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwKICAgICAgICAgICAgICAgIHNpemVvZih0Q3NyQnNzaWQpKTsKICAgICAgICAgICAgY3NyUm9hbUNhbGxDYWxsYmFjayhwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLAogICAgICAgICAgICAgICAgcm9hbUluZm8sIDAsIGVDU1JfUk9BTV9QUkVBVVRIX1NUQVRVU19TVUNDRVNTLCAwKTsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKHJvYW1JbmZvKTsKICAgICAgICB9CiNlbmRpZgoKICAgICAgICAvKiBQcmVhdXRoIGNvbXBldGVyIHN1Y2Nlc3NmdWxseS4gSW5zZXJ0IHRoZSBwcmVhdXRoZW50aWNhdGVkIG5vZGUgdG8gdGFpbCBvZiBwcmVBdXRoRG9uZUxpc3QgKi8KICAgICAgICBjc3JOZWlnaGJvclJvYW1SZW1vdmVSb2FtYWJsZUFQTGlzdEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsIHBQcmVhdXRoUnNwTm9kZSk7CiAgICAgICAgY3NyTExJbnNlcnRUYWlsKCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QsICZwUHJlYXV0aFJzcE5vZGUtPkxpc3QsIExMX0FDQ0VTU19MT0NLKTsKCiAgICAgICAgLyogUHJlLWF1dGggY29tcGxldGVkIHN1Y2Nlc3NmdWxseS4gVHJhbnNpdGlvbiB0byBQUkVBVVRIIERvbmUgc3RhdGUgKi8KICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUpCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPSAwOwoKICAgICAgICAvKiBUaGUgY2FsbGVyIG9mIHRoaXMgZnVuY3Rpb24gd291bGQgc3RhcnQgYSB0aW1lciBhbmQgYnkgdGhlIHRpbWUgaXQgZXhwaXJlcywgc3VwcGxpY2FudCBzaG91bGQgCiAgICAgICAgICAgaGF2ZSBwcm92aWRlZCB0aGUgdXBkYXRlZCBGVElFcyB0byBTTUUuIFNvLCB3aGVuIGl0IGV4cGlyZXMsIGhhbmRvZmYgd2lsbCBiZSB0cmlnZ2VyZWQgdGhlbiAqLwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyAgICBwTmVpZ2hib3JCc3NOb2RlID0gTlVMTDsKICAgICAgICB0TGlzdEVsZW0gICAgICAgICAgICAgICAgICAgKnBFbnRyeTsKICAgICAgICB1aW50MzJfdCAgICAgICAgICAgICAgICAgICAgcmV0cmllczsKCiAgICAgICAgcmV0cmllcyA9IHBNYWMtPnN0YV9hdXRoX3JldHJpZXNfZm9yX2NvZGUxNyA+CiAgICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX01BWF9OVU1fUFJFQVVUSF9SRVRSSUVTID8KICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+c3RhX2F1dGhfcmV0cmllc19mb3JfY29kZTE3IDoKICAgICAgICAgICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fTUFYX05VTV9QUkVBVVRIX1JFVFJJRVM7CgogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUHJlYXV0aCBmYWlsZWQgcmV0cnkgbnVtYmVyICVkLCBzdGF0dXMgPSAweCV4IiksCiAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzLCBsaW1TdGF0dXMpOwogICAgICAgIAogICAgICAgIC8qIFByZWF1dGggZmFpbGVkLiBBZGQgdGhlIGJzc0lkIHRvIHRoZSBwcmVBdXRoIGZhaWxlZCBsaXN0IE1BQyBBZGRyZXNzLiBBbHNvIHJlbW92ZSB0aGUgQVAgZnJvbSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyA+PSByZXRyaWVzKSB8fAogICAgICAgICAgICAgKChlU0lSX0xJTV9NQVhfU1RBX1JFQUNIRURfRVJST1IgPT0gbGltU3RhdHVzKSAmJgogICAgICAgICAgICAgKHBNYWMtPnN0YV9hdXRoX3JldHJpZXNfZm9yX2NvZGUxNyA9PSAwKSkpCiAgICAgICAgewogICAgICAgICAgICAvKiBXZSBhcmUgZ29pbmcgdG8gcmVtb3ZlIHRoZSBub2RlIGFzIGl0IGZhaWxzIGZvciBtb3JlIHRoYW4gTUFYIHRyaWVzLiBSZXNldCB0aGlzIGNvdW50IHRvIDAgKi8KICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPSAwOwoKICAgICAgICAgICAgLyogVGhlIG9uZSBpbiB0aGUgaGVhZCBvZiB0aGUgbGlzdCBzaG91bGQgYmUgb25lIHdpdGggd2hpY2ggd2UgaXNzdWVkIHByZS1hdXRoIGFuZCBmYWlsZWQgKi8KICAgICAgICAgICAgcEVudHJ5ID0gY3NyTExSZW1vdmVIZWFkKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsIExMX0FDQ0VTU19MT0NLKTsKICAgICAgICAgICAgaWYocEVudHJ5KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JCc3NOb2RlID0gR0VUX0JBU0VfQUREUihwRW50cnksIHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvLCBMaXN0KTsKICAgICAgICAgICAgICAgIC8qIEFkZCB0aGUgQlNTSUQgdG8gcHJlLWF1dGggZmFpbCBsaXN0IGlmIGl0IGlzIG5vdCByZXF1ZXN0ZWQgYnkgSEREICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICAgIGlmKCFwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikKI2VuZGlmCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUFkZEJzc0lkVG9QcmVhdXRoRmFpbExpc3QocE1hYywgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCk7CiAgICAgICAgICAgICAgICB9CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICAgICAgICAgICAgICAvKiBMRlIgbWV0cmljcyAtIHByZS1hdXRoIGNvbXBsZXRpb24gbWV0cmljLiBTZW5kIHRoZSBldmVudAogICAgICAgICAgICAgICAgICAgdG8gc3VwcGxpY2FudCB0aGF0IHByZS1hdXRoIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgKi8KICAgICAgICAgICAgICAgIHJvYW1JbmZvID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgICAgICAgICAgICAgaWYgKE5VTEwgPT0gcm9hbUluZm8pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQhIikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fY29weSgodm9pZCAqKXJvYW1JbmZvLT5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKilwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmJzc0lkLAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodENzckJzc2lkKSk7CiAgICAgICAgICAgICAgICAgICAgY3NyUm9hbUNhbGxDYWxsYmFjayhwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICByb2FtSW5mbywgMCwgZUNTUl9ST0FNX1BSRUFVVEhfU1RBVFVTX0ZBSUxVUkUsIDApOwogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShyb2FtSW5mbyk7CiAgICAgICAgICAgICAgICB9CiNlbmRpZgoKICAgICAgICAgICAgLyogTm93IHdlIGNhbiBmcmVlIHRoaXMgbm9kZSAqLwogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1GcmVlTmVpZ2hib3JSb2FtQlNTTm9kZShwTWFjLCBwTmVpZ2hib3JCc3NOb2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwU2Vzc2lvbiA9IENTUl9HRVRfU0VTU0lPTihwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkKTsKICAgICAgICBpZiAoKE5VTEwgIT0gcFNlc3Npb24pICYmIHBTZXNzaW9uLT5hYm9ydENvbm5lY3Rpb24pCiAgICAgICAgewogICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIERlYXV0aCBpbiBwcm9ncmVzcyBBYm9ydCBwcmVhdXRoIikpOwogICAgICAgICAgIGdvdG8gYWJvcnRfcHJlYXV0aDsKICAgICAgICB9CgogICAgICAgIGlmIChwTWFjLT5yb2FtLnBlbmRpbmdfcm9hbV9kaXNhYmxlKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJwcm9jZXNzIHBlbmRpbmcgcm9hbSBkaXNhYmxlIikpOwogICAgICAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzRmFzdFJvYW1JbmlGZWF0dXJlRW5hYmxlZCA9IEZBTFNFOwogICAgICAgICAgICBwTWFjLT5yb2FtLnBlbmRpbmdfcm9hbV9kaXNhYmxlID0gRkFMU0U7CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVVwZGF0ZUZhc3RSb2FtaW5nRW5hYmxlZChwTWFjLCBGQUxTRSk7CiAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CiAgICAgICAgICAgIGdvdG8gREVRX1BSRUFVVEg7CiAgICAgICAgfQoKICAgICAgICAvKiBJc3N1ZSBwcmVhdXRoIHJlcXVlc3QgZm9yIHRoZSBzYW1lL25leHQgZW50cnkgKi8KICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyA9PSBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEocE1hYykpCiAgICAgICAgZ290byBERVFfUFJFQVVUSDsgCgphYm9ydF9wcmVhdXRoOgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgewogICAgICAgICAgaWYocE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpCiAgICAgICAgICB7CiAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsIFJFQVNPTl9QUkVBVVRIX0ZBSUxFRF9GT1JfQUxMKTsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgaWYocE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCkKICAgICAgICAgIHsKICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0ggPSAwOwogICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJGb3JjZWQgNUcgcm9hbWluZyBwcmVhdXRoIGdvdCBmYWlsZWQiCiAgICAgICAgICAgICAgICAgICAgInNlbmQgUlNPIFNUQVJUIGNtZCB0byBmd3IuIikpOwogICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsUkVBU09OX0NPTk5FQ1QpOwogICAgICAgICAgfQogICAgICAgICAgZWxzZQogICAgICAgICAgewogICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1JFU1RBUlQsIFJFQVNPTl9QUkVBVVRIX0ZBSUxFRF9GT1JfQUxMKTsKICAgICAgICAgIH0KICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CiAgICAgICAgfSBlbHNlCiAgICAgICAgewojZW5kaWYKICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOKTsKCiAgICAgICAgICAvKiBSZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgZm9yIFVQIGV2ZW50IG5vdyAqLwogICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiTm8gbW9yZSBwcmUtYXV0aCBjYW5kaWRhdGVzLSIKICAgICAgICAgICAgICAgICAgInJlZ2lzdGVyIFVQIGluZGljYXRpb24gd2l0aCBUTC4gUlNTSSA9ICVkLCIpLCBORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpKTsKCiAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgewogICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwQ2FsbGJhY2sgVVAgZXZlbnQgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgc3RhdHVzKTsKICAgICAgICAgIH0KCiAgICAgICAgICAvKiBTdGFydCB0aGUgbmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIGFuZCB0cmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlIHRvIHBlcmZvcm0gc2NhbiBhZ2FpbiAqLwogICAgICAgICAgc3RhdHVzID0gdm9zX3RpbWVyX3N0YXJ0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZCk7CiAgICAgICAgICBpZiAoIHN0YXR1cyAhPSBlSEFMX1NUQVRVU19TVUNDRVNTICkKICAgICAgICAgIHsKICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIHN0YXJ0IGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBzdGF0dXMpOwogICAgICAgICAgfQogICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgfQojZW5kaWYKCkRFUV9QUkVBVVRIOgogICAgY3NyUm9hbURlcXVldWVQcmVhdXRoKHBNYWMpOwogICAgcmV0dXJuIHByZWF1dGhQcm9jZXNzZWQ7Cn0KI2VuZGlmICAvKiBXTEFOX0ZFQVRVUkVfTkVJR0hCT1JfUk9BTUlORyAqLwoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByZXBhcmVTY2FuUHJvZmlsZUZpbHRlcgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBjcmVhdGVzIGEgc2NhbiBmaWx0ZXIgYmFzZWQgb24gdGhlIGN1cnJlbnRseSBjb25uZWN0ZWQgcHJvZmlsZS4KICAgICAgICAgICAgQmFzZWQgb24gdGhpcyBmaWx0ZXIsIHNjYW4gcmVzdWx0cyBhcmUgb2J0YWluZWQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBTY2FuRmlsdGVyIC0gUG9wdWxhdGVkIHNjYW4gZmlsdGVyIGJhc2VkIG9uIHRoZSBjb25uZWN0ZWQgcHJvZmlsZQoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBlSEFMX1NUQVRVU19GQUlMVVJFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1QcmVwYXJlU2NhblByb2ZpbGVGaWx0ZXIodHBBbmlTaXJHbG9iYWwgcE1hYywgdENzclNjYW5SZXN1bHRGaWx0ZXIgKnBTY2FuRmlsdGVyKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRBTklfVTggc2Vzc2lvbklkICAgPSAodEFOSV9VOClwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkOwogICAgdENzclJvYW1Db25uZWN0ZWRQcm9maWxlICpwQ3VyUHJvZmlsZSA9ICZwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZTsKICAgIHRBTklfVTggaSA9IDA7CiAgICAKICAgIFZPU19BU1NFUlQocFNjYW5GaWx0ZXIgIT0gTlVMTCk7CiAgICBpZiAocFNjYW5GaWx0ZXIgPT0gTlVMTCkKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKCiAgICB2b3NfbWVtX3plcm8ocFNjYW5GaWx0ZXIsIHNpemVvZih0Q3NyU2NhblJlc3VsdEZpbHRlcikpOwoKICAgIC8qIFdlIGRvbnQgd2FudCB0byBzZXQgQlNTSUQgYmFzZWQgRmlsdGVyICovCiAgICBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzID0gMDsKCiAgICAvL29ubHkgZm9yIEhERCByZXF1ZXN0ZWQgaGFuZG9mZiBmaWxsIGluIHRoZSBCU1NJRCBpbiB0aGUgZmlsdGVyCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikKICAgIHsKCiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJPUyBSZXF1ZXN0ZWQgSGFuZG9mZiIpKTsKICAgICAgICBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzID0gMTsKICAgICAgICBwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwogICAgICAgIGlmIChOVUxMID09IHBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWQpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlNjYW4gRmlsdGVyIEJTU0lEIG1lbSBhbGxvYyBmYWlsZWQiKSk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMRURfQUxMT0M7CiAgICAgICAgfQoKICAgICAgICB2b3NfbWVtX3plcm8ocFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwoKICAgICAgICAvKiBQb3B1bGF0ZSB0aGUgQlNTSUQgZnJvbSBoYW5kb2ZmIGluZm8gcmVjZWl2ZWQgZnJvbSBIREQgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEczsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9jb3B5KCZwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICB9CiAgICB9CiNlbmRpZgogICAgLyogUG9wdWxhdGUgYWxsIHRoZSBpbmZvcm1hdGlvbiBmcm9tIHRoZSBjb25uZWN0ZWQgcHJvZmlsZSAqLwogICAgcFNjYW5GaWx0ZXItPlNTSURzLm51bU9mU1NJRHMgPSAxOyAgCiAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QgPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodENzclNTSURJbmZvKSk7CiAgICBpZiAoTlVMTCA9PSBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTY2FuIEZpbHRlciBTU0lEIG1lbSBhbGxvYyBmYWlsZWQiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxFRF9BTExPQzsKICAgIH0KICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+aGFuZG9mZlBlcm1pdHRlZCA9IDE7CiAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPnNzaWRIaWRkZW4gPSAwOwogICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELmxlbmd0aCA9ICBwQ3VyUHJvZmlsZS0+U1NJRC5sZW5ndGg7CiAgICB2b3NfbWVtX2NvcHkoKHZvaWQgKilwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPlNTSUQuc3NJZCwgKHZvaWQgKilwQ3VyUHJvZmlsZS0+U1NJRC5zc0lkLCBwQ3VyUHJvZmlsZS0+U1NJRC5sZW5ndGgpOyAKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJGaWx0ZXJpbmcgZm9yIFNTSUQgJS4qcyBmcm9tIHNjYW4gcmVzdWx0cywiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxlbmd0aCBvZiBTU0lEID0gJXUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPlNTSUQubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+U1NJRC5zc0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+U1NJRC5sZW5ndGgpOwogICAgcFNjYW5GaWx0ZXItPmF1dGhUeXBlLm51bUVudHJpZXMgPSAxOwogICAgcFNjYW5GaWx0ZXItPmF1dGhUeXBlLmF1dGhUeXBlWzBdID0gcEN1clByb2ZpbGUtPkF1dGhUeXBlOwoKICAgIHBTY2FuRmlsdGVyLT5FbmNyeXB0aW9uVHlwZS5udW1FbnRyaWVzID0gMTsgLy9UaGlzIG11c3QgYmUgMQogICAgcFNjYW5GaWx0ZXItPkVuY3J5cHRpb25UeXBlLmVuY3J5cHRpb25UeXBlWzBdID0gcEN1clByb2ZpbGUtPkVuY3J5cHRpb25UeXBlOwoKICAgIHBTY2FuRmlsdGVyLT5tY0VuY3J5cHRpb25UeXBlLm51bUVudHJpZXMgPSAxOwogICAgcFNjYW5GaWx0ZXItPm1jRW5jcnlwdGlvblR5cGUuZW5jcnlwdGlvblR5cGVbMF0gPSBwQ3VyUHJvZmlsZS0+bWNFbmNyeXB0aW9uVHlwZTsKCiAgICBwU2NhbkZpbHRlci0+QlNTVHlwZSA9IHBDdXJQcm9maWxlLT5CU1NUeXBlOwoKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscykKICAgIHsKICAgICAgIC8qIFdlIGFyZSBpbnRyZXN0ZWQgb25seSBpbiB0aGUgc2NhbiByZXN1bHRzIG9uIGNoYW5uZWxzIHRoYXQgd2Ugc2Nhbm5lZCAgKi8KICAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVsczsKICAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9CiAgICAgICAgdm9zX21lbV9tYWxsb2MocFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgKiBzaXplb2YodEFOSV9VOCkpOwogICAgICAgaWYgKE5VTEwgPT0gcFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KQogICAgICAgewogICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTY2FuIEZpbHRlciBDaGFubmVsIGxpc3QgbWVtIGFsbG9jIGZhaWxlZCIpKTsKICAgICAgICAgIHZvc19tZW1fZnJlZShwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QpOwogICAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0ID0gTlVMTDsKICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMRURfQUxMT0M7CiAgICAgICB9CiAgICAgICBmb3IgKGkgPSAwOyBpIDwgcFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHM7IGkrKykKICAgICAgIHsKICAgICAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdFtpXSA9CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdFtpXTsKICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIGlmIChwTWFjLT5QRVJyb2FtQ2FuZGlkYXRlc0NudCkKICAgICAgIHBTY2FuRmlsdGVyLT5pc1BFUlJvYW1TY2FuID0gdHJ1ZTsKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKQogICAgewogICAgICAgIC8qIE1ESUUgc2hvdWxkIGJlIGFkZGVkIGFzIGEgcGFydCBvZiBwcm9maWxlLiBUaGlzIHNob3VsZCBiZSBhZGRlZCBhcyBhIHBhcnQgb2YgZmlsdGVyIGFzIHdlbGwgICovCiAgICAgICAgcFNjYW5GaWx0ZXItPk1ESUQubWRpZVByZXNlbnQgPSBwQ3VyUHJvZmlsZS0+TURJRC5tZGllUHJlc2VudDsKICAgICAgICBwU2NhbkZpbHRlci0+TURJRC5tb2JpbGl0eURvbWFpbiA9IHBDdXJQcm9maWxlLT5NRElELm1vYmlsaXR5RG9tYWluOwogICAgfQojZW5kaWYKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfMTFXCiAgICBwU2NhbkZpbHRlci0+TUZQRW5hYmxlZCA9IHBDdXJQcm9maWxlLT5NRlBFbmFibGVkOwogICAgcFNjYW5GaWx0ZXItPk1GUFJlcXVpcmVkID0gcEN1clByb2ZpbGUtPk1GUFJlcXVpcmVkOwogICAgcFNjYW5GaWx0ZXItPk1GUENhcGFibGUgPSBwQ3VyUHJvZmlsZS0+TUZQQ2FwYWJsZTsKI2VuZGlmCgogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCnRBTklfVTMyIGNzckdldEN1cnJlbnRBUFJzc2kodHBBbmlTaXJHbG9iYWwgcE1hYywgdFNjYW5SZXN1bHRIYW5kbGUgKnBTY2FuUmVzdWx0TGlzdCkKewogICAgICAgIHRDc3JTY2FuUmVzdWx0SW5mbyAqcFNjYW5SZXN1bHQ7CiAgICAgICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgdEFOSV9VMzIgQ3VyckFQUnNzaSA9IHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaTsKI2Vsc2UKICAgICAgICAvKiBXZSBhcmUgc2V0dGluZyB0aGlzIGFzIGRlZmF1bHQgdmFsdWUgdG8gbWFrZSBzdXJlIHdlIHJldHVybiB0aGlzIHZhbHVlLAogICAgICAgIHdoZW4gd2UgZG8gbm90IHNlZSB0aGlzIEFQIGluIHRoZSBzY2FuIHJlc3VsdCBmb3Igc29tZSByZWFzb24uSG93ZXZlcixpdCBpcwogICAgICAgIGxlc3MgbGlrZWx5IHRoYXQgd2UgYXJlIGFzc29jaWF0ZWQgdG8gYW4gQVAgYW5kIGRvIG5vdCBzZWUgaXQgaW4gdGhlIHNjYW4gbGlzdCAqLwogICAgICAgIHRBTklfVTMyIEN1cnJBUFJzc2kgPSAtMTI1OwojZW5kaWYKCiAgICAgICAgd2hpbGUgKE5VTEwgIT0gKHBTY2FuUmVzdWx0ID0gY3NyU2NhblJlc3VsdEdldE5leHQocE1hYywgKnBTY2FuUmVzdWx0TGlzdCkpKQogICAgICAgIHsKCiAgICAgICAgICAgICAgICBpZiAoVk9TX1RSVUUgPT0gdm9zX21lbV9jb21wYXJlKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VyckFQYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBXZSBnb3QgYSBtYXRjaCB3aXRoIHRoZSBjdXJyZW50bHkgYXNzb2NpYXRlZCBBUC4KICAgICAgICAgICAgICAgICAgICAgICAgICogQ2FwdHVyZSB0aGUgUlNTSSB2YWx1ZSBhbmQgY29tcGxldGUgdGhlIHdoaWxlIGxvb3AuCiAgICAgICAgICAgICAgICAgICAgICAgICAqIFRoZSB3aGlsZSBsb29wIGlzIGNvbXBsZXRlZCBpbiBvcmRlciB0byBtYWtlIHRoZSBjdXJyZW50IGVudHJ5IGdvIGJhY2sgdG8gTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICogYW5kIGluIHRoZSBuZXh0IHdoaWxlIGxvb3AsIGl0IHByb3Blcmx5IHN0YXJ0cyBzZWFyY2hpbmcgZnJvbSB0aGUgaGVhZCBvZiB0aGUgbGlzdC4KICAgICAgICAgICAgICAgICAgICAgICAgICogVE9ETzogQ2FuIGFsc28gdHJ5IHNldHRpbmcgdGhlIGN1cnJlbnQgZW50cnkgZGlyZWN0bHkgdG8gTlVMTCBhcyBzb29uIGFzIHdlIGZpbmQgdGhlIG5ldyBBUCovCgogICAgICAgICAgICAgICAgICAgICAgICAgQ3VyckFQUnNzaSA9IChpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSAqICgtMSkgOwoKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIEN1cnJBUFJzc2k7Cgp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5SZXN1bHRzCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGV4dHJhY3RzIHNjYW4gcmVzdWx0cywgc29ydHMgb24gdGhlIGJhc2lzIG9mIG5laWdoYm9yIHNjb3JlKHRvZG8pLiAKICAgICAgICAgICAgQXNzdW1lZCB0aGF0IHRoZSByZXN1bHRzIGFyZSBhbHJlYWR5IHNvcnRlZCBieSBSU1NJIGJ5IGNzclNjYW5HZXRSZXN1bHQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBTY2FuUmVzdWx0TGlzdCAtIFNjYW4gcmVzdWx0IHJlc3VsdCBvYnRhaW5lZCBmcm9tIGNzclNjYW5HZXRSZXN1bHQoKQoKICAgIFxyZXR1cm4gdEFOSV9CT09MRUFOIC0gcmV0dXJuIFRSVUUgaWYgd2UgaGF2ZSBhIGNhbmRpZGF0ZSB3ZSBjYW4gaW1tZWRpYXRlbHkKICAgICAgICAgICAgcm9hbSB0by4gT3RoZXJ3aXNlLCByZXR1cm4gRkFMU0UuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKc3RhdGljIHRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhblJlc3VsdHModHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRTY2FuUmVzdWx0SGFuZGxlICpwU2NhblJlc3VsdExpc3QpCnsKICAgIHRDc3JTY2FuUmVzdWx0SW5mbyAqcFNjYW5SZXN1bHQ7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyAgICBwQnNzSW5mbzsKICAgIHRBTklfVTMyIEN1cnJBUFJzc2k7CiAgICB0QU5JX1U4IFJvYW1Sc3NpRGlmZiA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uUm9hbVJzc2lEaWZmOwojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICB0QU5JX1U4IGltbWVkaWF0ZVJvYW1Sc3NpRGlmZiA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubkltbWVkaWF0ZVJvYW1Sc3NpRGlmZjsKI2VuZGlmCiAgICB0QU5JX0JPT0xFQU4gcm9hbU5vdyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgKiBGaW5kIG91dCB0aGUgQ3VycmVudCBBUCBSU1NJIGFuZCBrZWVwIGl0IGhhbmR5IHRvIGNoZWNrIGlmCiAgICAgKiBpdCBpcyBiZXR0ZXIgdGhhbiB0aGUgUlNTSSBvZiB0aGUgQVAgd2hpY2ggd2UgYXJlCiAgICAgKiBnb2luZyB0byByb2FtLklmIHNvLCB3ZSBhcmUgZ29pbmcgdG8gY29udGludWUgd2l0aCB0aGUKICAgICAqIGN1cnJlbnQgQVAuCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgQ3VyckFQUnNzaSA9IGNzckdldEN1cnJlbnRBUFJzc2kocE1hYywgcFNjYW5SZXN1bHRMaXN0KTsKCiAgICAvKiBFeHBlY3RpbmcgdGhlIHNjYW4gcmVzdWx0IGFscmVhZHkgdG8gYmUgaW4gdGhlIHNvcnRlZCBvcmRlciBiYXNlZCBvbiB0aGUgUlNTSSAqLwogICAgLyogQmFzZWQgb24gdGhlIHByZXZpb3VzIHN0YXRlIHdlIG5lZWQgdG8gY2hlY2sgd2hldGhlciB0aGUgbGlzdCBzaG91bGQgYmUgc29ydGVkIGFnYWluIHRha2luZyBuZWlnaGJvciBzY29yZSBpbnRvIGNvbnNpZGVyYXRpb24gKi8KICAgIC8qIElmIHByZXZpb3VzIHN0YXRlIGlzIENGR19DSEFOX0xJU1RfU0NBTiwgdGhlcmUgc2hvdWxkIG5vdCBiZSBhbnkgbmVpZ2hib3Igc2NvcmUgYXNzb2NpYXRlZCB3aXRoIGFueSBvZiB0aGUgQlNTLgogICAgICAgSWYgdGhlIHByZXZpb3VzIHN0YXRlIGlzIFJFUE9SVF9RVUVSWSwgdGhlbiB0aGVyZSB3aWxsIGJlIG5laWdoYm9yIHNjb3JlIGZvciBlYWNoIG9mIHRoZSBBUHMgKi8KICAgIC8qIEZvciBub3csIGxldCB1cyB0YWtlIHRoZSB0b3Agb2YgdGhlIGxpc3QgcHJvdmlkZWQgYXMgaXQgaXMgYnkgdGhlIENTUiBTY2FuIHJlc3VsdCBBUEkuIFRoaXMgbWVhbnMgaXQgaXMgYXNzdW1lZCB0aGF0IG5laWdoYm9yIHNjb3JlIAogICAgICAgYW5kIHJzc2kgc2NvcmUgYXJlIGluIHRoZSBzYW1lIG9yZGVyLiBUaGlzIHdpbGwgYmUgdGFrZW4gY2FyZSBsYXRlciAqLwoKICAgIHdoaWxlIChOVUxMICE9IChwU2NhblJlc3VsdCA9IGNzclNjYW5SZXN1bHRHZXROZXh0KHBNYWMsICpwU2NhblJlc3VsdExpc3QpKSkKICAgIHsKICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0RFQlVHLAogICAgICAgICAgICBGTCgiU2NhbiByZXN1bHQ6IEJTU0lEICJNQUNfQUREUkVTU19TVFIiIChSc3NpICVsZCwgQ2g6JWQpIiksCiAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkKSwKICAgICAgICAgICAgKGxvbmcpYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpLAogICAgICAgICAgICBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5jaGFubmVsSWQpOwoKICAgICAgIGlmICgoVk9TX1RSVUUgPT0gdm9zX21lbV9jb21wYXJlKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkLAogICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSkpIHx8CiAgICAgICAgICAgKChlU01FX1JPQU1fVFJJR0dFUl9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pICYmCiAgICAgICAgICAgKFZPU19UUlVFICE9IHZvc19tZW1fY29tcGFyZShwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1ic3NJZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSkpKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIGN1cnJlbnRseSBhc3NvY2lhdGVkIEFQLiBEbyBub3QgaGF2ZSB0aGlzIGluIHRoZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICJTS0lQLWN1cnJlbnRseSBhc3NvY2lhdGVkIEFQIik7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICBpZiAodm9zX2NvbmN1cnJlbnRfb3Blbl9zZXNzaW9uc19ydW5uaW5nKCkgJiYKICAgICAgICAgICFwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmZlbmFibGVNQ0NNb2RlICYmCiAgICAgICAgICAgIChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5jaGFubmVsSWQgIT0KICAgICAgICAgICAgY3NyR2V0Q29uY3VycmVudE9wZXJhdGlvbkNoYW5uZWwocE1hYykpKSB7CiAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk1DQyBub3Qgc3VwcG9ydGVkIHNvIElnbm9yZSBBUCBvbiBjaGFubmVsICVkIiksCiAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuY2hhbm5lbElkKTsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgLyogSW4gY2FzZSBvZiByZWFzc29jIHJlcXVlc3RlZCBieSB1cHBlciBsYXllciwgbG9vayBmb3IgZXhhY3QgbWF0Y2ggb2YgYnNzaWQgJiBjaGFubmVsOwogICAgICAgICAgY3NyIGNhY2hlIG1pZ2h0IGhhdmUgZHVwbGljYXRlcyovCiAgICAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmKSAmJgogICAgICAgICAgICgoVk9TX0ZBTFNFID09IHZvc19tZW1fY29tcGFyZShwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uYnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSkpfHwKICAgICAgICAgICAgKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmNoYW5uZWxJZCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uY2hhbm5lbCkpKQoKICAgICAgIHsKICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICJTS0lQLW5vdCBhIGNhbmRpZGF0ZSBBUCBmb3IgT1MgcmVxdWVzdGVkIHJvYW0iKTsKICAgICAgICAgICBjb250aW51ZTsKICAgICAgIH0KI2VuZGlmCiNlbmRpZgoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0gpCiAgICAgICB7CiAgICAgICAgICAgIC8vQmVsb3cgY2hlY2sgaXMgcmVxdWlyZWQgYmVjYXVzZSBzY2FubmluZyBmb3IgZm9yY2VkIGluaXRpYWwgcm9hbWluZyB3ZSBoYXZlIG5vdAogICAgICAgICAgICAvL2ZsdXNoIGFsbCB0aGUgMi40IEdIeiBDaGFubmVsLCBzbyBpdCBtYXkgcG9zc2JpbGUgd2UgbWF5IHJvYW0gYWdhaW4gdG8KICAgICAgICAgICAgLy8yLjQgR2h6IGFwIG9ubHkuCiAgICAgICAgICAgIGlmKEdldFJGQmFuZChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5jaGFubmVsSWQpICE9IFNJUl9CQU5EXzVfR0haKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBGb3JjZWQgUm9hbSB0byA1RyBTa2lwIE5vbiA1RyBTY2FuIHJlc3VsdHMgIiwgX19mdW5jX18pOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vcnNzaSdzIGFyZSAtdmUgdmFsdWUsIHNvIGlmIGFicyBvZiByc3NpIGlzIGdyZWF0ZXIKICAgICAgICAgICAgLy9tZWFucyBuZXcgYXAgaXMgcG9vciB0aGVuIGN1cnJlbnRseSBjb25uZWN0ZWQgYXAuCiAgICAgICAgICAgIC8vQ2hlY2sgaXQgaXMgb25seSBwb29yIHdpdGhpbiBuU2VsZWN0NUdIek1hcmdpbiB2YWx1ZS4KICAgICAgICAgICAgaWYgKGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSA+IGFicyhDdXJyQVBSc3NpKSAmJgogICAgICAgICAgICAgICAoKGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSAtIGFicyhDdXJyQVBSc3NpKSkKICAgICAgICAgICAgICAgID4gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uU2VsZWN0NUdIek1hcmdpbikKICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICIlczogRm9yY2VkIFJvYW0gdG8gNUcgQ3VycmVudCBBUCByc3NpPSVkIG5ldyBhcCByc3NpPSVkIG5vdCBnb29kIGVub3VnaCwgblNlbGVjdDVHSHpNYXJnaW49JWQiLCBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgIEN1cnJBUFJzc2ksCiAgICAgICAgICAgICAgICAgICAgICAoaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uU2VsZWN0NUdIek1hcmdpbik7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgIH0KI2VuZGlmCiNlbmRpZgoKICAgICAgIC8qIFRoaXMgY29uZGl0aW9uIGlzIHRvIGVuc3VyZSB0byByb2FtIHRvIGFuIEFQIHdpdGggYmV0dGVyIFJTU0kuIGlmIHRoZSB2YWx1ZSBvZiBSb2FtUnNzaURpZmYgaXMgWmVybywgdGhpcyBmZWF0dXJlCiAgICAgICAgKiBpcyBkaXNhYmxlZCBhbmQgd2UgY29udGludWUgdG8gcm9hbSB3aXRob3V0IGFueSBjaGVjayovCiAgICAgICBpZiAoKFJvYW1Sc3NpRGlmZiA+IDApCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICYmICFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpCiNlbmRpZgogICAgICAgJiYgKChlU01FX1JPQU1fVFJJR0dFUl9TQ0FOICE9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pICYmCiAgICAgICAgICAgKGVTTUVfUk9BTV9UUklHR0VSX0ZBU1RfUk9BTSAhPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKSkpCiAgICAgICB7CiAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICogSWYgUlNTSSBpcyBsb3dlciB0aGFuIHRoZSBsb29rdXAgdGhyZXNob2xkLCB0aGVuIGNvbnRpbnVlLgogICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICBpZiAoYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpID4KICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQpCiAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXSBuZXcgYXAgcnNzaSAoJWQpIGxvd2VyIHRoYW4gbG9va3VwIHRocmVzaG9sZCAoJWQpIiwKICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAoaW50KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgaWYgKGFicyhDdXJyQVBSc3NpKSA8IGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSkKICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgIC8qRG8gbm90IHJvYW0gdG8gYW4gQVAgd2l0aCB3b3JzZSBSU1NJIHRoYW4gdGhlIGN1cnJlbnQqLwogICAgICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXUN1cnJlbnQgQVAgcnNzaT0lZCBuZXcgYXAgcnNzaSB3b3JzZT0lZCIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDdXJyQVBSc3NpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kgKiAoLTEpICk7CiAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgLypEbyBub3Qgcm9hbSB0byBhbiBBUCB3aGljaCBpcyBoYXZpbmcgYmV0dGVyIFJTU0kgdGhhbiB0aGUgY3VycmVudCBBUCwgYnV0IHN0aWxsIGxlc3MgdGhhbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgKiBtYXJnaW4gdGhhdCBpcyBwcm92aWRlZCBieSB1c2VyIGZyb20gdGhlIGluaSBmaWxlIChSb2FtUnNzaURpZmYpKi8KICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWJzKGFicyhDdXJyQVBSc3NpKSAtIGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSkgPCBSb2FtUnNzaURpZmYpCiAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR11DdXJyZW50IEFQIHJzc2k9JWQgbmV3IGFwIHJzc2k9JWQgbm90IGdvb2QgZW5vdWdoLCByb2FtUnNzaURpZmY9JWQiLCBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3VyckFQUnNzaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUm9hbVJzc2lEaWZmKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogW0lORk9MT0ddQ3VycmVudCBBUCByc3NpPSVkIG5ldyBhcCByc3NpIGJldHRlcj0lZCIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEN1cnJBUFJzc2ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSApOwogICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgfQogICAgICAgfQoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUocE1hYywgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkJTU0lEIHByZXNlbnQgaW4gcHJlLWF1dGggZmFpbCBsaXN0Li4gSWdub3JpbmciKSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgIHsKI2VuZGlmCiAgICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MpCiAgICAgICAgICB7CiAgICAgICAgICAgICAgaWYgKCFjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUocE1hYywgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJCU1NJRCBwcmVzZW50IGluIHByZS1hdXRoIGZhaWwgbGlzdC4uIElnbm9yaW5nIikpOwogICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLlFCU1NMb2FkX3ByZXNlbnQpICYmCiAgICAgICAgICAgICAgIChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5RQlNTTG9hZF9hdmFpbCkpCiAgICAgICAgICB7CiAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc1ZPQWRtaXR0ZWQpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk5ldyBBUCBoYXMgJXggQlcgYXZhaWxhYmxlIiksICh1bnNpZ25lZCBpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfYXZhaWwpOwogICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIldlIG5lZWQgJXggQlcgYXZhaWxhYmxlIiksKHVuc2lnbmVkIGludClwTmVpZ2hib3JSb2FtSW5mby0+TWluUUJzc0xvYWRSZXF1aXJlZCk7CiAgICAgICAgICAgICAgICAgIGlmIChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5RQlNTTG9hZF9hdmFpbCA8IHBOZWlnaGJvclJvYW1JbmZvLT5NaW5RQnNzTG9hZFJlcXVpcmVkKQogICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAiW0lORk9MT0ddQlNTSUQgOiAiTUFDX0FERFJFU1NfU1RSIiBoYXMgbm8gYmFuZHdpZHRoIGlnbm9yaW5nLi5ub3QgYWRkaW5nIHRvIHJvYW0gbGlzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgTUFDX0FERFJfQVJSQVkocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpKTsKICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgZWxzZQogICAgICAgICAgewogICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTm8gUUJzcyAleCAleCIpLCAodW5zaWduZWQgaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLlFCU1NMb2FkX2F2YWlsLCAodW5zaWduZWQgaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLlFCU1NMb2FkX3ByZXNlbnQpOwogICAgICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNWT0FkbWl0dGVkKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAiW0lORk9MT0ddQlNTSUQgOiAiTUFDX0FERFJFU1NfU1RSIiBoYXMgbm8gUUJTU0xvYWQgSUUsIGlnbm9yaW5nLi5ub3QgYWRkaW5nIHRvIHJvYW0gbGlzdCIsCiAgICAgICAgICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCkpOwogICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICB9CiNlbmRpZgojZW5kaWYgLyogRkVBVFVSRV9XTEFOX0VTRSAqLwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAvLyBJZiB3ZSBhcmUgc3VwcG9ydGluZyBsZWdhY3kgcm9hbWluZywgYW5kIAogICAgICAgIC8vIGlmIHRoZSBjYW5kaWRhdGUgaXMgb24gdGhlICJwcmUtYXV0aCBmYWlsZWQiIGxpc3QsIGlnbm9yZSBpdC4gCiAgICAgICAgaWYgKGNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLCBDU1JfU0VTU0lPTl9JRF9JTlZBTElEKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghY3NyTmVpZ2hib3JSb2FtSXNQcmVhdXRoQ2FuZGlkYXRlKHBNYWMsIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJCU1NJRCBwcmVzZW50IGluIHByZS1hdXRoIGZhaWwgbGlzdC4uIElnbm9yaW5nIikpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiNlbmRpZiAvKiBGRUFUVVJFX1dMQU5fTEZSICovCgogICAgICAgIC8qIElmIHRoZSByZWNlaXZlZCB0aW1lc3RhbXAgaW4gQlNTIGRlc2NyaXB0aW9uIGlzIGVhcmxpZXIgdGhhbiB0aGUgc2NhbiByZXF1ZXN0IHRpbWVzdGFtcCwgc2tpcCAKICAgICAgICAgKiB0aGlzIHJlc3VsdCAqLwogICAgICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPnNjYW5SZXF1ZXN0VGltZVN0YW1wID49IHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLm5SZWNlaXZlZFRpbWUpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgJiYgIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykKI2VuZGlmCiAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJZ25vcmluZyBCU1MgYXMgaXQgaXMgb2xkZXIgdGhhbiB0aGUgc2NhbiByZXF1ZXN0IHRpbWVzdGFtcCIpKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBwQnNzSW5mbyA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyTmVpZ2hib3JSb2FtQlNTSW5mbykpOwogICAgICAgIGlmIChOVUxMID09IHBCc3NJbmZvKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgTmVpZ2hib3IgUm9hbSBCU1MgSW5mbyBmYWlsZWQuLiBKdXN0IGlnbm9yaW5nIikpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIHBCc3NJbmZvLT5wQnNzRGVzY3JpcHRpb24gPSB2b3NfbWVtX21hbGxvYyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5sZW5ndGggKyBzaXplb2YocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IubGVuZ3RoKSk7CiAgICAgICAgaWYgKHBCc3NJbmZvLT5wQnNzRGVzY3JpcHRpb24gIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIHZvc19tZW1fY29weShwQnNzSW5mby0+cEJzc0Rlc2NyaXB0aW9uLCAmcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICAgIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmxlbmd0aCArIHNpemVvZihwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5sZW5ndGgpKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgTmVpZ2hib3IgUm9hbSBCU1MgRGVzY3JpcHRvciBmYWlsZWQuLiBKdXN0IGlnbm9yaW5nIikpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocEJzc0luZm8pOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgCiAgICAgICAgfQogICAgICAgIHBCc3NJbmZvLT5hcFByZWZlcmVuY2VWYWwgPSAxMDsgLy9zb21lIHZhbHVlIGZvciBub3cuIE5lZWQgdG8gY2FsY3VsYXRlIHRoZSBhY3R1YWwgc2NvcmUgYmFzZWQgb24gUlNTSSBhbmQgbmVpZ2hib3IgQVAgc2NvcmUKCiAgICAgICAgLyogSnVzdCBhZGQgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdCBhcyBpdCBpcyBhbHJlYWR5IHNvcnRlZCBieSBSU1NJICovCiAgICAgICAgY3NyTExJbnNlcnRUYWlsKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsICZwQnNzSW5mby0+TGlzdCwgTExfQUNDRVNTX0xPQ0spOwoKI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0VTRSkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgICAgIGlmICgoZVNNRV9ST0FNX1RSSUdHRVJfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKSB8fAogICAgICAgICAgICAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pKQogICAgICAgIHsKICAgICAgICAgICByb2FtTm93ID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICgoYWJzKGFicyhDdXJyQVBSc3NpKSAtIGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSkgPj0gaW1tZWRpYXRlUm9hbVJzc2lEaWZmKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICYmICFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpCiNlbmRpZgogICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICIlczogW0lORk9MT0ddIHBvdGVudGlhbCBjYW5kaWRhdGUgdG8gcm9hbSBpbW1lZGlhdGVseSAoZGlmZj0lbGQsIGV4cGVjdGVkPSVkKSIsCiAgICAgICAgICAgICAgICAgICAgICAgX19mdW5jX18sIChsb25nKWFicyhhYnMoQ3VyckFQUnNzaSkgLSBhYnMocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSkpLAogICAgICAgICAgICAgICAgICAgICAgIGltbWVkaWF0ZVJvYW1Sc3NpRGlmZik7CiAgICAgICAgICAgIHJvYW1Ob3cgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAvKiBJZiB3ZSBhcmUgaGVyZSBtZWFucywgRlcgYWxyZWFkeSBmb3VuZCBjYW5kaWRhdGVzIHRvIHJvYW0sIHNvIHdlIGFyZQogICAgICAgICAgIGdvb2QgdG8gZ28gd2l0aCBwcmUtYXV0aCAqLwogICAgICAgIGlmKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgewogICAgICAgICAgICByb2FtTm93ID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgfQojZW5kaWYKI2VuZGlmCiAgICB9CgogICAgLyogTm93IHdlIGhhdmUgYWxsIHRoZSBzY2FuIHJlc3VsdHMgaW4gb3VyIGxvY2FsIGxpc3QuIEdvb2QgdGltZSB0byBmcmVlIHVwIHRoZSB0aGUgbGlzdCB3ZSBnb3QgYXMgYSBwYXJ0IG9mIGNzckdldFNjYW5SZXN1bHQgKi8KICAgIGNzclNjYW5SZXN1bHRQdXJnZShwTWFjLCAqcFNjYW5SZXN1bHRMaXN0KTsKCiAgICByZXR1cm4gcm9hbU5vdzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUhhbmRsZUVtcHR5U2NhblJlc3VsdAoKICAgIFxicmllZiAgICAgIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBpbnZva2VkIGluIENGR19DSEFOX0xJU1RfU0NBTiBzdGF0ZSB3aGVuIAogICAgICAgICAgICAgICAgdGhlcmUgYXJlIG5vIHZhbGlkIEFQcyBpbiB0aGUgc2NhbiByZXN1bHQgZm9yIHJvYW1pbmcuIFRoaXMgbWVhbnMgCiAgICAgICAgICAgICAgICBvdXIgQVAgaXMgdGhlIGJlc3QgYW5kIG5vIG90aGVyIEFQIGlzIGFyb3VuZC4gTm8gcG9pbnQgaW4gc2Nhbm5pbmcKICAgICAgICAgICAgICAgIGFnYWluIGFuZCBhZ2Fpbi4gUGVyZm9ybWluZyB0aGUgZm9sbG93aW5nIGhlcmUuCiAgICAgICAgICAgICAgICAxLiBTdG9wIHRoZSBuZWlnaGJvciBzY2FuIHRpbWVyLgogICAgICAgICAgICAgICAgMmEuIElmIHRoaXMgaXMgdGhlIGZpcnN0IHRpbWUgd2UgZW5jb3VudGVyZWQgZW1wdHkgc2NhbiwgdGhlbgogICAgICAgICAgICAgICAgcmUtcmVnaXN0ZXIgd2l0aCBUTCB3aXRoIG1vZGlmaWVkIGxvb2t1cCB0aHJlc2hvbGQuCiAgICAgICAgICAgICAgICAyYi4gRWxzZSBpZiB0aGlzIGlzIHRoZSBzZWNvbmQgdGltZSB3ZSBlbmNvdW50ZXJlZCBlbXB0eSBzY2FuLAogICAgICAgICAgICAgICAgdGhlbiBzdGFydCBuZWlnaGJvciBzY2FuIHJlc3VsdHMgcmVmcmVzaCB0aW1lciAoMjBzKS4KICAgICAgICAgICAgICAgIDJjLiBFbHNlLCBub3RoaW5nIG1vcmUgdG8gZG8uCiAgICAgICAgICAgICAgICBOT1RFOiBJbiBMRlIsIGNoYW5uZWxzIHNlbGVjdGVkIGZvciBzY2FubmluZyBpcyBkZXJ2aWVkIGZyb20KICAgICAgICAgICAgICAgIHRoZSBvY2N1cGVkIGNoYW5uZWwgbGlzdC4gU2NhbiBjeWNsZSBmb2xsb3dpbmcgb25lIHdoaWNoCiAgICAgICAgICAgICAgICB5aWVsZGVkIGVtcHR5IHJlc3VsdHMgaXMgc3BsaXQgaW50byB0d28gaGFsdmVzOiAoaSkgc2NhbiBvbgogICAgICAgICAgICAgICAgY2hhbm5lbHMgaW4gdGhlIG9jY3VwaWVkIGxpc3QsIGFuZCAoaWkpIHNjYW4gb24gY2hhbm5lbHMgbm90CiAgICAgICAgICAgICAgICBpbiB0aGUgb2NjdXBpZWQgbGlzdC4gVGhpcyBoZWxwcyBjb252ZXJnaW5nIGZhc3RlciAod2hpbGUKICAgICAgICAgICAgICAgIGxvb2tpbmcgZm9yIGNhbmRpZGF0ZXMgaW4gdGhlIG9jY3VwaWVkIGxpc3QgZmlyc3QpLCBhbmQgYWxzbywKICAgICAgICAgICAgICAgIGFkZHMgY2hhbm5lbHMgdG8gdGhlIG9jY3VwaWVkIGNoYW5uZWwgbGlzdCB1cG9uIGZpbmRpbmcgY2FuZGlkYXRlcwogICAgICAgICAgICAgICAgbWF0Y2hpbmcgU1NJRCBwcm9maWxlIG9mIGludGVyZXN0LgoKICAgICAgICAgICAgICAgIHVFbXB0eVNjYW5Db3VudCAgICAgICAgICAgICAgICAgICAgICAgICBDb21tZW50cwogICAgICAgICAgICAgICAgZUZpcnN0RW1wdHlTY2FuICAgICBQcmV2aW91cyBzY2FuIHdhcyBkb25lIG9uIGNoYW5uZWxzIGluIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvY2N1cGllZCBsaXN0IGFuZCB5aWVsZGVkIHBvdGVudGlhbCBjYW5kaWRhdGVzLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIHNjYW4gY3ljbGUgd2FzIGxpa2VseSB0cmlnZ2VyZWQgdGhyb3VnaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXB0IG9mIGxvb2t1cCBET1dOIG5vdGlmaWNhdGlvbiBldmVudC4KICAgICAgICAgICAgICAgIGVTZWNvbmRFbXB0eVNjYW4gICAgUHJldmlvdXMgc2NhbiB3YXMgZG9uZSBvbiBjaGFubmVscyBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2NjdXBpZWQgbGlzdCBhbmQgeWllbGRlZCBubyBjYW5kaWRhdGVzLiBUaGlzIHNjYW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3ljbGUgd2FzIHRyaWdnZXJlZCB0aHJvdWdoIFJTU0kgbm90aWZpY2F0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggbW9kaWZpZWQgbG9va3VwIHRocmVzaG9sZC4KICAgICAgICAgICAgICAgIGVUaGlyZEVtcHR5U2NhbiAgICAgUHJldmlvdXMgc2NhbiB3YXMgZG9uZSBvbiBjaGFubmVscyBOT1QgaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIG9jY3VwaWVkIGxpc3QgYW5kIHlpZWxkZWQgbm8gY2FuZGlkYXRlcy4gVGhpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuIGN5Y2xlIHdhcyB0cmlnZ2VyZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgc2Nhbm5pbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbHMgaW4gdGhlIG9jY3VwaWVkIGxpc3QgYW5kIG5vIGNhbmRpZGF0ZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2VyZSBmb3VuZC4KICAgICAgICAgICAgICAgIGVGb3VydGhFbXB0eVNjYW4gICAgUHJldmlvdXMgc2NhbiB3YXMgZG9uZSBvbiBjaGFubmVscyBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2NjdXBpZWQgbGlzdCBhbmQgeWllbGRlZCBubyBjYW5kaWRhdGVzLiBUaGlzIHNjYW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3ljbGUgd2FzIHRyaWdnZXJlZCB1cG9uIGV4cGlyeSBvZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWlnaGJvclNjYW5SZXN1bHRzUmVmcmVzaFBlcmlvZCAoPTIwcykuCiAgICAgICAgICAgICAgICBlRmlmdGhFbXB0eVNjYW4gICAgIFByZXZpb3VzIHNjYW4gd2FzIGRvbmUgb24gY2hhbm5lbHMgTk9UIGluCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBvY2N1cGllZCBsaXN0IGFuZCB5aWVsZGVkIG5vIGNhbmRpZGF0ZXMuIFRoaXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbiBjeWNsZSB3YXMgdHJpZ2dlcmVkIGltbWVkaWF0ZWx5IGFmdGVyIHNjYW5uaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzIGluIHRoZSBvY2N1cGllZCBsaXN0IGFuZCBubyBjYW5kaWRhdGVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlcmUgZm91bmQuCgogICAgICAgICAgICAgICAgWzFdLCBbMiwzXSBhbmQgWzQsNV0gdG9nZXRoZXIgZm9ybSBvbmUgZGlzY3JldGUgc2V0IG9mIHNjYW4gY3ljbGUuCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnN0YXRpYyBWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbUhhbmRsZUVtcHR5U2NhblJlc3VsdCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICB0QU5JX0JPT0xFQU4gcGVyZm9ybVBlcmlvZGljU2NhbiA9CiAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuZW1wdHlTY2FuUmVmcmVzaFBlcmlvZCkgPyBUUlVFIDogRkFMU0U7CiNlbmRpZgoKICAgIC8qIFN0b3AgbmVpZ2hib3Igc2NhbiB0aW1lciAqLwogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAvKgogICAgICogSW5jcmVhc2UgdGhlIG5laWdoYm9yIGxvb2t1cCB0aHJlc2hvbGQgYnkgMyBkQgogICAgICogYWZ0ZXIgZXZlcnkgc2NhbiBjeWNsZS4gTk9URTogdUVtcHR5U2NhbkNvdW50CiAgICAgKiB3b3VsZCBiZSBlaXRoZXIgMSwgMyBvciA1IGF0IHRoZSBlbmQgb2YgZXZlcnkKICAgICAqIHNjYW4gY3ljbGUuCiAgICAgKi8KI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIGlmICgoKytwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50KSA+IGVGaWZ0aEVtcHR5U2NhbikKICAgIHsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gZUZpZnRoRW1wdHlTY2FuOwogICAgfQogICAgaWYgKCgoMCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpIHx8CiAgICAgICAgIChhYnMocE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpKSA+CiAgICAgICAgIGFicyhwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCkpKSAmJgogICAgICAgICgocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSBlU2Vjb25kRW1wdHlTY2FuKSB8fAogICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSBlRm91cnRoRW1wdHlTY2FuKSkpCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKiBJZiB0aGUgc2NhbiB3YXMgdHJpZ2dlcmVkIGR1ZSB0byBsb29rdXBET1dOUnNzaSA+IHJlYXNzb2MgdGhyZXNob2xkLAogICAgICAgICAqIHRoZW4gaXQgd291bGQgYmUgYSBjb250aWd1b3VzIHNjYW4gb24gYWxsIHZhbGlkIG5vbi1ERlMgY2hhbm5lbHMuCiAgICAgICAgICogSWYgY2hhbm5lbHMgYXJlIGNvbmZpZ3VyZWQgaW4gSU5JLCB0aGVuIG9ubHkgdGhvc2UgY2hhbm5lbHMgbmVlZAogICAgICAgICAqIHRvIGJlIHNjYW5uZWQuCiAgICAgICAgICogSW4gZWl0aGVyIG9mIHRoZXNlIG1vZGVzLCB0aGVyZSBpcyBubyBuZWVkIHRvIHRyaWdnZXIgYW4gaW1tZWRpYXRlCiAgICAgICAgICogc2NhbiB1cG9uIGVtcHR5IHNjYW4gcmVzdWx0cyBmb3IgdGhlIHNlY29uZCBhbmQgZm91cnRoIHRpbWUgKHdoaWNoCiAgICAgICAgICogd291bGQgYmUgZXF1aXZhbGVudCB0byBzY2FubmluZyBvbiBjaGFubmVscyBpbiBub24tb2NjdXBpZWQgbGlzdCkuCiAgICAgICAgICogSW5jcmVtZW50aW5nIHVFbXB0eVNjYW5Db3VudCB3aWxsIGNvcnJlc3BvbmQgdG8gc2tpcHBpbmcgdGhpcyBzdGVwLgogICAgICAgICAqIE5PVEU6IGRvdWJsZSBpbmNyZW1lbnQgb2YgdUVtcHR5U2NhbkNvdW50IGNvcnJlc3BvbmRzIHRvIGNvbXBsZXRpb24KICAgICAgICAgKiBvZiBzY2FucyBvbiBhbGwgdmFsaWQgY2hhbm5lbHMuCiAgICAgICAgICovCiAgICAgICAgKytwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50OwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIkV4dHJhIGluY3JlbWVudCBvZiBlbXB0eSBzY2FuIGNvdW50ICg9JWQpIgogICAgICAgICAgICAiIGluIGNvbnRpZ3VvdXMgc2NhbiBtb2RlIiwgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCk7CiAgICB9CiNlbmRpZgogICAgaWYgKCgocE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCszKSA8CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQpCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgJiYgKChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ICUgMikgPT0gMSkKI2VuZGlmCiAgICAgICAgKQogICAgewogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKz0gMzsKICAgIH0KCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgLyogQ2xlYXIgb2ZmIHRoZSBvbGQgbmVpZ2hib3IgcmVwb3J0IGRldGFpbHMgKi8KICAgIHZvc19tZW1femVybygmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm8sIHNpemVvZih0Q3NyTmVpZ2hib3JSZXBvcnRCc3NJbmZvKSAqIE1BWF9CU1NfSU5fTkVJR0hCT1JfUlBUKTsKI2VuZGlmCgogICAgLyogVHJhbnNpdGlvbiB0byBDT05ORUNURUQgc3RhdGUgKi8KICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CiAgICAgICAgCiAgICAvKiBSZXNldCBhbGwgdGhlIG5lY2Vzc2FyeSB2YXJpYWJsZXMgYmVmb3JlIHRyYW5zaXRpb25pbmcgdG8gdGhlIENPTk5FQ1RFRCBzdGF0ZSAqLwogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwogICAgICAgIAojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPT0gZUZpcnN0RW1wdHlTY2FuKQogICAgewojZW5kaWYKICAgICAgICAvKiBFbXB0eSBzY2FuIHJlc3VsdHMgZm9yIHRoZSBmaXJzdCB0aW1lICovCiAgICAgICAgLyogUmUtcmVnaXN0ZXIgbmVpZ2hib3IgbG9va3VwIERPV04gdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgKi8KICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsCiAgICAgICAgICAgIEZMKCJSZWdpc3RlcmluZyBET1dOIGV2ZW50IG5laWdoYm9yIGxvb2t1cCBjYWxsYmFjayB3aXRoIFRMIGZvciBSU1NJID0gJWQiKSwKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSkpOwoKICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CgogICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgRkwoIkNvdWxkbid0IHJlLXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrIgogICAgICAgICAgICAgICAgICAgICAgIiB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgICAgIH0KI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwogICAgfQogICAgZWxzZSBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPT0gZVNlY29uZEVtcHR5U2NhbikgfHwKICAgICAgICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID09IGVGb3VydGhFbXB0eVNjYW4pKQogICAgewogICAgICAgIC8qIEVtcHR5IHNjYW4gcmVzdWx0cyBmb3IgdGhlIHNlY29uZCBvciBmb3VydGggdGltZSAqLwoKICAgICAgICAvKiBJbW1lZGlhdGVseSBzY2FuIG9uIGNoYW5uZWxzIGluIG5vbi1vY2N1cGllZCBsaXN0ICovCiAgICAgICAgY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4ocE1hYyk7CiAgICB9CiAgICBlbHNlIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID49IGVUaGlyZEVtcHR5U2NhbikKICAgIHsKICAgICAgICAvKiBFbXB0eSBzY2FuIHJlc3VsdHMgZm9yIHRoZSB0aGlyZCB0aW1lICovCiAgICAgICAgaWYgKHBlcmZvcm1QZXJpb2RpY1NjYW4pCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlBlcmZvcm1pbmcgcGVyaW9kaWMgc2NhbiwgdUVtcHR5U2NhbkNvdW50PSVkIiksCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50KTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFNldCB1RW1wdHlTY2FuQ291bnQgdG8gTUFYIHNvIHRoYXQgd2UgYWx3YXlzIGVudGVyIHRoaXMKICAgICAgICAgICAgICogY29uZGl0aW9uIG9uIHN1YnNlcXVlbnQgZW1wdHkgc2NhbiByZXN1bHRzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gZU1heEVtcHR5U2NhbjsKCiAgICAgICAgICAgIC8qIEZyb20gaGVyZSBvbiwgT05MWSBzY2FuIG9uIGNoYW5uZWxzIGluIHRoZSBvY2N1cGllZCBsaXN0ICovCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUgPSBTUExJVF9TQ0FOX09DQ1VQSUVEX0xJU1Q7CgogICAgICAgICAgICAvKiBTdGFydCBlbXB0eSBzY2FuIHJlZnJlc2ggdGltZXIgKi8KICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPQogICAgICAgICAgICAgICAgdm9zX3RpbWVyX3N0YXJ0KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyLAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuZW1wdHlTY2FuUmVmcmVzaFBlcmlvZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRW1wdHkgc2NhbiByZWZyZXNoIHRpbWVyIGZhaWxlZCB0byBzdGFydCAoJWQpIiksCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRW1wdHkgc2NhbiByZWZyZXNoIHRpbWVyIHN0YXJ0ZWQgKCVkIG1zKSIpLAogICAgICAgICAgICAgICAgICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5lbXB0eVNjYW5SZWZyZXNoUGVyaW9kKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoZVRoaXJkRW1wdHlTY2FuID09IHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQpCiAgICAgICAgewogICAgICAgICAgICAvKiBTdGFydCBuZWlnaGJvciBzY2FuIHJlc3VsdHMgcmVmcmVzaCB0aW1lciAqLwogICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9CiAgICAgICAgICAgICAgICAgICAgdm9zX3RpbWVyX3N0YXJ0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyLAogICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2QpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lciBmYWlsZWQgdG8gc3RhcnQgKCVkKSIpLAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpOwogICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMiwgRkwoIk5laWdoYm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lciBzdGFydGVkICglZCBtcykiKSwKICAgICAgICAgICAgICAgICAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZCAqIFBBTF9USU1FUl9UT19NU19VTklUKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCAiTmVpZ2hib3Igcm9hbSBlbXB0eSBzY2FuIGNvdW50PSVkIHNjYW4gbW9kZT0lZCIsCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCwgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSk7CiNlbmRpZgogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuQ29tcGxldGUgKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdENzclNjYW5SZXN1bHRGaWx0ZXIgICAgc2NhbkZpbHRlcjsKICAgIHRTY2FuUmVzdWx0SGFuZGxlICAgICAgIHNjYW5SZXN1bHQ7CiAgICB0QU5JX1UzMiAgICAgICAgICAgICAgICB0ZW1wVmFsID0gMDsKICAgIHRBTklfQk9PTEVBTiAgICAgICAgICAgIHJvYW1Ob3cgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICBlSGFsU3RhdHVzICAgICAgICAgICAgICBoc3RhdHVzOwoKI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0VTRSkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgICAgIC8qIElmIHRoZSBzdGF0ZSBpcyBSRVBPUlRfU0NBTiwgdGhlbiB0aGlzIG11c3QgYmUgdGhlIHNjYW4gYWZ0ZXIgdGhlIFJFUE9SVF9RVUVSWSBzdGF0ZS4gU28sIHdlIAogICAgICAgICAgIHNob3VsZCB1c2UgdGhlIEJTU0lEIGZpbHRlciBtYWRlIG91dCBvZiBuZWlnaGJvciByZXBvcnRzICovCiAgICAgICAgaWYgKChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgJiYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQojZW5kaWYKICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtQnNzSWRTY2FuRmlsdGVyKHBNYWMsICZzY2FuRmlsdGVyKTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiMTFSIG9yIEVTRSBBc3NvY2lhdGlvbjogUHJlcGFyZSBzY2FuIGZpbHRlciBzdGF0dXMgIHdpdGggbmVpZ2hib3IgQVAgPSAlZCIpLCBoc3RhdHVzKTsKICAgICAgICAgICAgdGVtcFZhbCA9IDE7CiAgICAgICAgfQogICAgICAgIGVsc2UKI2VuZGlmCiAgICAgICAgewogICAgICAgICAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJlcGFyZVNjYW5Qcm9maWxlRmlsdGVyKHBNYWMsICZzY2FuRmlsdGVyKTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiMTFSL0VTRS9PdGhlciBBc3NvY2lhdGlvbjogUHJlcGFyZSBzY2FuIHRvIGZpbmQgbmVpZ2hib3IgQVAgZmlsdGVyIHN0YXR1cyAgPSAlZCIpLCBoc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2NhbiBGaWx0ZXIgcHJlcGFyYXRpb24gZmFpbGVkIGZvciBBc3NvYyB0eXBlICVkLi4gQmFpbGluZyBvdXQuLiIpLCB0ZW1wVmFsKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgfQogICAgICAgIGhzdGF0dXMgPSBjc3JTY2FuR2V0UmVzdWx0KHBNYWMsICZzY2FuRmlsdGVyLCAmc2NhblJlc3VsdCk7CiAgICAgICAgaWYgKGhzdGF0dXMgIT0gZUhBTF9TVEFUVVNfU1VDQ0VTUykKICAgICAgICB7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkdldCBTY2FuIFJlc3VsdCBzdGF0dXMgY29kZSAlZCIpLCBoc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgLyogUHJvY2VzcyB0aGUgc2NhbiByZXN1bHRzIGFuZCB1cGRhdGUgcm9hbWFibGUgQVAgbGlzdCAqLwogICAgICAgIHJvYW1Ob3cgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhblJlc3VsdHMocE1hYywgJnNjYW5SZXN1bHQpOwoKICAgICAgICAvKiBGcmVlIHRoZSBzY2FuIGZpbHRlciAqLwogICAgICAgIGNzckZyZWVTY2FuRmlsdGVyKHBNYWMsICZzY2FuRmlsdGVyKTsKCiAgICAgICAgdGVtcFZhbCA9IGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgewojZW5kaWYKICAgICAgICAgc3dpdGNoKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICAgewogICAgICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU46CiAgICAgICAgICAgICAgICBpZiAodGVtcFZhbCkKICAgICAgICAgICAgICAgIHsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIFNpbmNlIHRoZXJlIGFyZSBub24temVybyBjYW5kaWRhdGVzIGZvdW5kCiAgICAgICAgICAgICAgICAgICAgICogYWZ0ZXIgdGhlIHNjYW4sIHJlc2V0IGVtcHR5IHNjYW4gY291bnQuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSA9IERFRkFVTFRfU0NBTjsKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgICAgICAgICAgICAgICAgIC8qIElmIHRoaXMgaXMgYSBub24tMTFyIGFzc29jaWF0aW9uLCB0aGVuIHdlIGNhbiByZWdpc3RlciB0aGUgcmVhc3NvYyBjYWxsYmFjayBoZXJlIGFzIHdlIGhhdmUgc29tZSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFQcyBpbiB0aGUgcm9hbWFibGUgQVAgbGlzdCAqLwogICAgICAgICAgICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFZhbGlkIEFQcyBhcmUgZm91bmQgYWZ0ZXIgc2Nhbi4gTm93IHdlIGNhbiBpbml0aWF0ZSBwcmUtYXV0aGVudGljYXRpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4pCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKI2VuZGlmCiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCiAgICAgICAgICAgICAgICAgICAgLyogSWYgdGhpcyBpcyBhIG5vbi0xMXIgYXNzb2NpYXRpb24sIHRoZW4gd2UgY2FuIHJlZ2lzdGVyIHRoZSByZWFzc29jIGNhbGxiYWNrIGhlcmUgYXMgd2UgaGF2ZSBzb21lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVBzIGluIHRoZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVmFsaWQgQVBzIGFyZSBmb3VuZCBhZnRlciBzY2FuLiBOb3cgd2UgY2FuIGluaXRpYXRlIHByZS1hdXRoZW50aWNhdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTikKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgICAgICAgICAvKiBJZiBMRlIgaXMgZW5hYmxlZCwgdGhlbiB3ZSBjYW4gcmVnaXN0ZXIgdGhlIHJlYXNzb2MgY2FsbGJhY2sgaGVyZSBhcyB3ZSBoYXZlIHNvbWUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBUHMgaW4gdGhlIHJvYW1hYmxlIEFQIGxpc3QgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVmFsaWQgQVBzIGFyZSBmb3VuZCBhZnRlciBzY2FuLiBOb3cgd2UgY2FuIGluaXRpYXRlIHByZS1hdXRoZW50aWNhdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTikKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQojZW5kaWYKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkNvbXBsZXRlZCBzY2FubmluZyBvZiBDRkcgQ0hBTiBMSVNUIGluIG5vbi0xMXIgYXNzb2NpYXRpb24uIFJlZ2lzdGVyaW5nIHJlYXNzb2MgY2FsbGJhY2siKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5vdGhpbmcgbXVjaCB0byBkbyBub3cuIFdpbGwgY29udGludWUgdG8gcmVtYWluIGluIHRoaXMgc3RhdGUgaW4gY2FzZSBvZiBub24tMTFyIGFzc29jaWF0aW9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFN0b3AgdGhlIHRpbWVyLiBCdXQgaG93IGxvbmcgdGhlIHJvYW1hYmxlIEFQIGxpc3Qgd2lsbCBiZSB2YWxpZCBpbiBoZXJlLiBBdCBzb21lIHBvaW50IG9mIHRpbWUsIHdlIAogICAgICAgICAgICAgICAgICAgICAgICAgICBuZWVkIHRvIHJlc3RhcnQgdGhlIENGRyBDSEFOIGxpc3Qgc2NhbiBwcm9jZWR1cmUgaWYgcmVhc3NvYyBjYWxsYmFjayBpcyBub3QgaW52b2tlZCBmcm9tIFRMIAogICAgICAgICAgICAgICAgICAgICAgICAgICB3aXRoaW4gY2VydGFpbiBkdXJhdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAKLy8gICAgICAgICAgICAgICAgICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICAgICAgIEZMKCJObyBjYW5kaWRhdGUgZm91bmQgYWZ0ZXIgc2Nhbm5pbmcgaW4gc3RhdGUgJXMgLi4gIiksCiAgICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICAgICAgLyogSGFuZGxlIGl0IGFwcHJvcHJpYXRlbHkgKi8KICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1IYW5kbGVFbXB0eVNjYW5SZXN1bHQocE1hYyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICAgICAgICAgICAgICAgIAogICAgICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTjoKICAgICAgICAgICAgICAgIGlmICghdGVtcFZhbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5vIGNhbmRpZGF0ZSBmb3VuZCBhZnRlciBzY2FubmluZyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgImluIHN0YXRlICVzIC4uICIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICAgICAgLyogU3RvcCB0aGUgdGltZXIgaGVyZSBhcyB0aGUgc2FtZSB0aW1lciB3aWxsIGJlIHN0YXJ0ZWQgYWdhaW4gaW4gQ0ZHX0NIQU5fU0NBTl9TVEFURSAqLwogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiNlbmRpZiAvKiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAqLwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgLy8gQ2FuIGNvbWUgb25seSBpbiBJTklUIHN0YXRlLiBXaGVyZSBpbiB3ZSBhcmUgYXNzb2NpYXRlZCwgd2Ugc2VudCBzY2FuIGFuZCB1c2VyCiAgICAgICAgICAgICAgICAvLyBpbiB0aGUgbWVhbnRpbWUgZGVjaWRlcyB0byBkaXNhc3NvYywgd2Ugd2lsbCBiZSBpbiBpbml0IHN0YXRlIGFuZCBzdGlsbCByZWNlaXZlZCBjYWxsCiAgICAgICAgICAgICAgICAvLyBiYWNrIGlzc3VlZC4gU2hvdWxkIG5vdCBjb21lIGhlcmUgaW4gYW55IG90aGVyIHN0YXRlLCBwcmludGluZyBqdXN0IGluIGNhc2UKICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIlN0YXRlICVzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKCiAgICAgICAgICAgICAgICAvLyBMZXRzIGp1c3QgZXhpdCBvdXQgc2lsZW50bHkuCiAgICAgICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgfQojZW5kaWYKCiAgICAgICAgaWYgKHRlbXBWYWwpCiAgICAgICAgewogICAgICAgICAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CgogICAgICAgICAgICBpZiAocm9hbU5vdykKICAgICAgICAgICAgewojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgICBpZighY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICAgICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgIEZMKCJJbW1lZGlhdGUgcm9hbS1kZXJlZ2lzdGVyIFVQIGluZGljYXRpb24uIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSk7CgogICAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKCiAgICAgICAgICAgICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkNvdWxkbid0IGRlcmVnaXN0ZXIgbG9va3VwIFVQIGNhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAgICAgfQojZW5kaWYKCiAgICAgICAgICAgICAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtVHJpZ2dlckhhbmRvZmYocE1hYyxwTmVpZ2hib3JSb2FtSW5mbyk7CiAgICAgICAgICAgICAgICBpZihlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJjc3JOZWlnaGJvclJvYW1UcmlnZ2VySGFuZG9mZiBmYWlsIHN0YXR1cyA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGhzdGF0dXMpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgICAgIH0KCiAgICAgICAgaHN0YXR1cyA9IHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lciwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2QpOwoKICAgICAgICAgICAvKiBUaGlzIHRpbWVyIHNob3VsZCBiZSBzdGFydGVkIGJlZm9yZSByZWdpc3RlcmluZyB0aGUgUmVhc3NvYyBjYWxsYmFjayB3aXRoIFRMLiBUaGlzIGlzIGJlY2F1c2UsIGl0IGlzIHZlcnkgbGlrZWx5IAogICAgICAgICAgICAqIHRoYXQgdGhlIGNhbGxiYWNrIGdldHRpbmcgY2FsbGVkIGltbWVkaWF0ZWx5IGFuZCB0aGUgdGltZXIgd291bGQgbmV2ZXIgYmUgc3RvcHBlZCB3aGVuIHByZS1hdXRoIGlzIGluIHByb2dyZXNzICovCiAgICAgICAgaWYoIGhzdGF0dXMgIT0gZUhBTF9TVEFUVVNfU1VDQ0VTUykKICAgICAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lciBmYWlsZWQgdG8gc3RhcnQsIHN0YXR1cyA9ICVkIiksIGhzdGF0dXMpOwogICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIERPV04gZXZlbnQgUmVhc3NvYyBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQiKSwgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpKTsKICAgICAgICAgICAgLyogUmVnaXN0ZXIgYSByZWFzc29jIEluZGljYXRpb24gY2FsbGJhY2sgKi8KICAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCByZWdpc3RlciBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgfQogCiAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIXRlbXBWYWwgfHwgIXJvYW1Ob3cpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKChlU01FX1JPQU1fVFJJR0dFUl9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pIHx8CiAgICAgICAgICAgICAgICAgICAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vVGhpcyBpcyBpb2N0bCBiYXNlZCByb2FtaW5nIGlmIHdlIGRpZCBub3QgZmluZCBhbnkgcm9hbWFibGUKICAgICAgICAgICAgICAgICAgICAvL2NhbmRpZGF0ZSB0aGVuIGp1c3QgbG9nIGl0LgogICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSggVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0ZW1wVmFsID0gJXUsIHJvYW1Ob3cgPSAlZCB1T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gJWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcFZhbCwgcm9hbU5vdywgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UoIFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vIDVHIGNhbmRpZGF0ZSBmb3VuZCB0ZW1wVmFsPSV1LCByb2FtTm93PSVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBWYWwsIHJvYW1Ob3cpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9OT19DQU5EX0ZPVU5EX09SX05PVF9ST0FNSU5HX05PVyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFRoZXJlIGlzIG5vIGNhbmRpZGF0ZSBvciBXZSBhcmUgbm90IHJvYW1pbmcgTm93LgogICAgICAgICAgICAgICAgICAgICAgICAgKiBJbmZvcm0gdGhlIEZXIHRvIHJlc3RhcnQgUm9hbSBPZmZsb2FkIFNjYW4gICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9SRVNUQVJULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVBU09OX05PX0NBTkRfRk9VTkRfT1JfTk9UX1JPQU1JTkdfTk9XKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQpOwogICAgICAgICAgICB9CiAgICAgICAgfQojZW5kaWYKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CgoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVNjYW5SZXF1ZXN0Q2FsbGJhY2sKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHJlZ2lzdGVyZWQgaW4gY3NyU2NhblJlcXVlc3QoKSB0byAKICAgICAgICAgICAgaW5kaWNhdGUgdGhlIGNvbXBsZXRpb24gb2Ygc2Nhbi4gSWYgc2NhbiBpcyBjb21wbGV0ZWQgZm9yIGFsbCB0aGUgY2hhbm5lbHMgaW4gCiAgICAgICAgICAgIHRoZSBjaGFubmVsIGxpc3QsIHRoaXMgZnVuY3Rpb24gZ2V0cyB0aGUgc2NhbiByZXN1bHQgYW5kIHN0YXJ0cyB0aGUgcmVmcmVzaCByZXN1bHRzCiAgICAgICAgICAgIHRpbWVyIHRvIGF2b2lkIGhhdmluZyBzdGFsZSByZXN1bHRzLiBJZiBzY2FuIGlzIG5vdCBjb21wbGV0ZWQgb24gYWxsIHRoZSBjaGFubmVscywKICAgICAgICAgICAgaXQgcmVzdGFydHMgdGhlIG5laWdoYm9yIHNjYW4gdGltZXIgd2hpY2ggb24gZXhwaXJ5IGlzc3VlcyBzY2FuIG9uIHRoZSBuZXh0IAogICAgICAgICAgICBjaGFubmVsCgogICAgXHBhcmFtICBoYWxIYW5kbGUgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBDb250ZXh0IC0gbm90IHVzZWQKICAgICAgICAgICAgc2NhbklkIC0gbm90IHVzZWQKICAgICAgICAgICAgc3RhdHVzIC0gbm90IHVzZWQKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtU2NhblJlcXVlc3RDYWxsYmFjayh0SGFsSGFuZGxlIGhhbEhhbmRsZSwgdm9pZCAqcENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1UzMiBzY2FuSWQsIGVDc3JTY2FuU3RhdHVzIHN0YXR1cykKewogICAgdHBBbmlTaXJHbG9iYWwgICAgICAgICAgICAgICAgICBwTWFjID0gKHRwQW5pU2lyR2xvYmFsKSBoYWxIYW5kbGU7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRBTklfVTggICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudENoYW5JbmRleDsKICAgIGVIYWxTdGF0dXMgICAgICAgICAgICAgIGhzdGF0dXM7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICB0QU5JX1UzMiBzZXNzaW9uSWQgPSBDU1JfU0VTU0lPTl9JRF9JTlZBTElEOwoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgewogICAgICAgIHNlc3Npb25JZCA9ICooKHRBTklfVTMyKilwQ29udGV4dCk7CgogICAgICAgIGlmICghY3NyUm9hbUlzU3RhTW9kZShwTWFjLCBzZXNzaW9uSWQpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJZ25vcmluZyBzY2FuIHJlcXVlc3QgY2FsbGJhY2sgb24gbm9uLWluZnJhIgogICAgICAgICAgICAgICAgICAgInNlc3Npb24gJWQgaW4gc3RhdGUgJXMiKSwKICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQsIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICB9CgogICAgICAgIGlmICghY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsc2Vzc2lvbklkKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgd2hlbiBmYXN0IHJvYW0gaXMgZGlzYWJsZWQuIElnbm9yZSBpdCIpKTsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfQogICAgfQojZW5kaWYKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5zY2FuUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIAogICAgLyogVGhpcyBjYW4gaGFwcGVuIHdoZW4gd2UgcmVjZWl2ZSBhIFVQIGV2ZW50IGZyb20gVEwgaW4gYW55IG9mIHRoZSBzY2FuIHN0YXRlcy4gU2lsZW50bHkgaWdub3JlIGl0ICovCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBDT05ORUNURUQgc3RhdGUuIE11c3QgYmUgYmVjYXVzZSBhIFVQIGV2ZW50IGZyb20gVEwgYWZ0ZXIgaXNzdWluZyBzY2FuIHJlcXVlc3QuIElnbm9yZSBpdCIpKTsKICAgICAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIC8qIC0xIGlzIGRvbmUgYmVjYXVzZSB0aGUgY2hhbkluZGV4IHdvdWxkIGhhdmUgZ290IGluY3JlbWVudGVkIGFmdGVyIGlzc3VpbmcgYSBzdWNjZXNzZnVsIHNjYW4gcmVxdWVzdCAqLwogICAgY3VycmVudENoYW5JbmRleCA9IChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgpID8gKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCAtIDEpIDogMDsKCiAgICAvKiBWYWxpZGF0ZSBpbnB1dHMgKi8KICAgIGlmIChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJjc3JOZWlnaGJvclJvYW1TY2FuUmVxdWVzdENhbGxiYWNrIHJlY2VpdmVkIGZvciBDaGFubmVsID0gJWQsIENoYW5JbmRleCA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0W2N1cnJlbnRDaGFuSW5kZXhdLCBjdXJyZW50Q2hhbkluZGV4KTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIlJlY2VpdmVkIGR1cmluZyBjbGVhbi11cC4gU2lsZW50bHkgaWdub3JlIHNjYW4gY29tcGxldGlvbiBldmVudC4iKSk7CiAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAoZUFOSV9CT09MRUFOX0ZBTFNFID09IHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY2hhbkxpc3RTY2FuSW5Qcm9ncmVzcykKICAgIHsKICAgICAgICAvKiBTY2FuIGlzIGNvbXBsZXRlZCBpbiB0aGUgIENGR19DSEFOX1NDQU4gc3RhdGUuIFdlIGNhbiB0cmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlCiAgICAgICAgICAganVzdCB0byBnZXQgdGhlIHJlc3VsdHMgYW5kIHBlcmZvcm0gUFJFQVVUSCAqLwogICAgICAgIC8qIE5vdyB3ZSBoYXZlIGNvbXBsZXRlZCBzY2FubmluZyB0aGUgY2hhbm5lbCBsaXN0LiBXZSBoYXZlIGdldCB0aGUgcmVzdWx0IGJ5IGFwcGx5aW5nIGFwcHJvcHJpYXRlIGZpbHRlcgogICAgICAgICAgIHNvcnQgdGhlIHJlc3VsdHMgYmFzZWQgb24gbmVpZ2hib3JTY29yZSBhbmQgUlNTSSBhbmQgc2VsZWN0IHRoZSBiZXN0IGNhbmRpZGF0ZSBvdXQgb2YgdGhlIGxpc3QgKi8KICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJDaGFubmVsIGxpc3Qgc2NhbiBjb21wbGV0ZWQuIEN1cnJlbnQgY2hhbiBpbmRleCA9ICVkIiksIGN1cnJlbnRDaGFuSW5kZXgpOwogICAgICAgIFZPU19BU1NFUlQocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4ID09IDApOwoKICAgICAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5Db21wbGV0ZShwTWFjKTsKCiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBwcm9jZXNzIGNvbXBsZXRlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgICAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CgogICAgICAgIC8qIFJlc3RhcnQgdGhlIHRpbWVyIGZvciB0aGUgbmV4dCBzY2FuIHNlcXVlbmNlIGFzIHNjYW5uaW5nIGlzIG5vdCBvdmVyICovCiAgICAgICAgaHN0YXR1cyA9IHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyLAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JTY2FuUGVyaW9kKTsKICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgLyogVGltZXIgc3RhcnQgZmFpbGVkLi4gU2hvdWxkIHdlIEFTU0VSVCBoZXJlPz8/ICovCiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBQQUwgVGltZXIgc3RhcnQgZmFpbGVkLCBzdGF0dXMgPSAlZCwgSWdub3Jpbmcgc3RhdGUgdHJhbnNpdGlvbiIpLCBzdGF0dXMpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgICAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVNjYW5SZXN1bHRSZXF1ZXN0Q2FsbGJhY2sKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHJlZ2lzdGVyZWQgaW4gY3NyU2NhblJlcXVlc3RMZnJSZXN1bHQoKSB0bwogICAgICAgICAgICBpbmRpY2F0ZSB0aGUgY29tcGxldGlvbiBvZiBzY2FuLiBJZiBzY2FuIGlzIGNvbXBsZXRlZCBmb3IgYWxsIHRoZSBjaGFubmVscyBpbgogICAgICAgICAgICB0aGUgY2hhbm5lbCBsaXN0LCB0aGlzIGZ1bmN0aW9uIGdldHMgdGhlIHNjYW4gcmVzdWx0IGFuZCB0cmVhdHMgdGhlbSBhcyBjYW5kaWRhdGVzCgogICAgXHBhcmFtICBoYWxIYW5kbGUgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBDb250ZXh0IC0gbm90IHVzZWQKICAgICAgICAgICAgc2NhbklkIC0gbm90IHVzZWQKICAgICAgICAgICAgc3RhdHVzIC0gbm90IHVzZWQKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtU2NhblJlc3VsdFJlcXVlc3RDYWxsYmFjayh0SGFsSGFuZGxlIGhhbEhhbmRsZSwgdm9pZCAqcENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VMzIgc2NhbklkLCBlQ3NyU2NhblN0YXR1cyBzdGF0dXMpCnsKICAgIHRwQW5pU2lyR2xvYmFsICAgICAgICAgICAgICAgICAgcE1hYyA9ICh0cEFuaVNpckdsb2JhbCkgaGFsSGFuZGxlOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzICAgICAgICAgICAgICBoc3RhdHVzOwoKICAgIHNtc0xvZyhwTWFjLCBMT0cyLCBGTCgiY2FsbGVkICIpKTsKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5zY2FuUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiAgICAvKiB3ZSBtdXN0IGJlIGluIGNvbm5lY3RlZCBzdGF0ZSwgaWYgbm90IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZS4gSWdub3JlIGl0IikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIC8qIE5vdyB3ZSBoYXZlIGNvbXBsZXRlZCBzY2FubmluZyB0aGUgY2hhbm5lbCBsaXN0LiBXZSBoYXZlIGdldCB0aGUgcmVzdWx0IGJ5IGFwcGx5aW5nIGFwcHJvcHJpYXRlIGZpbHRlcgogICAgICAgc29ydCB0aGUgcmVzdWx0cyBiYXNlZCBvbiBuZWlnaGJvclNjb3JlIGFuZCBSU1NJIGFuZCBzZWxlY3QgdGhlIGJlc3QgY2FuZGlkYXRlIG91dCBvZiB0aGUgbGlzdCAqLwoKICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhbkNvbXBsZXRlKHBNYWMpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIHByb2Nlc3MgY29tcGxldGUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIGhzdGF0dXMpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KI2VuZGlmIC8vV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Gb3JjZVJvYW1UbzVHaFNjYW5DYih0SGFsSGFuZGxlIGhhbEhhbmRsZSwKICAgICAgICB2b2lkICpwQ29udGV4dCwgdEFOSV9VMzIgc2NhbklkLCBlQ3NyU2NhblN0YXR1cyBzdGF0dXMpCnsKICAgIHRwQW5pU2lyR2xvYmFsICAgICAgICAgICAgICAgICAgcE1hYyA9ICh0cEFuaVNpckdsb2JhbCkgaGFsSGFuZGxlOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzIGhzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdEFOSV9VMzIgc2Vzc2lvbklkID0gQ1NSX1NFU1NJT05fSURfSU5WQUxJRDsKCiAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgIHsKICAgICAgICBzZXNzaW9uSWQgPSAqKCh0QU5JX1UzMiopcENvbnRleHQpOwogICAgICAgIGlmICghY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsc2Vzc2lvbklkKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgd2hlbiBmYXN0IHJvYW0gaXMgZGlzYWJsZWQuIElnbm9yZSBpdCIpKTsKICAgICAgICAgICAgaHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgIGdvdG8gZW5kOwogICAgICAgIH0KICAgIH0KCiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uc2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU4gIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbmVpZ2hib3JSb2FtU3RhdGUgJWQgLiBJZ25vcmUgaXQiKSwKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICAgICAgaHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgZ290byBlbmQ7CiAgICB9CgogICAgLy9rZWVwIHRyYWNrIG9mIGZvcmNlZCA1RyBzY2FuICYgcm9hbSBpcyBkdWUgdG8gRm9yY2VkIGluaXRpYWwgcm9hbSB0byA1R0h6CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIID0gMTsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICIlczogcHJvY2VzcyBzY2FuIHJlc3VsdHMiLCBfX2Z1bmNfXyk7CiAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5Db21wbGV0ZShwTWFjKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRm9yY2UgUm9hbSBUbyA1R2hTY2FuQ2IgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksCiAgICAgICAgaHN0YXR1cyk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCA9IDA7CiAgICAgICAgLyoKICAgICAgICAgKiBTZW5kIFJTTyBzdGFydCBiZWNhdXNlIGluIGNhc2UgNUcgcm9hbWluZyBob3N0IGhhdmUKICAgICAgICAgKiBub3QgZW5hYmxlZCBhdCBpbml0aWFsIGNvbm5lY3Rpb24KICAgICAgICAgKi8KICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsIFJFQVNPTl9DT05ORUNUKTsKICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQpOwogICAgfQoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICByZXR1cm4gaHN0YXR1czsKCmVuZDoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICByZXR1cm4gaHN0YXR1czsKfQojZW5kaWYKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUNvbnRpZ3VvdXNTY2FuUmVxdWVzdENhbGxiYWNrKHRIYWxIYW5kbGUgaGFsSGFuZGxlLAogICAgICAgIHZvaWQgKnBDb250ZXh0LCB0QU5JX1UzMiBzY2FuSWQsIGVDc3JTY2FuU3RhdHVzIHN0YXR1cykKewogICAgdHBBbmlTaXJHbG9iYWwgICAgICAgICAgICAgICAgICBwTWFjID0gKHRwQW5pU2lyR2xvYmFsKSBoYWxIYW5kbGU7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgaHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB0QU5JX1UzMiBzZXNzaW9uSWQgPSBDU1JfU0VTU0lPTl9JRF9JTlZBTElEOwoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgewogICAgICAgIHNlc3Npb25JZCA9ICooKHRBTklfVTMyKilwQ29udGV4dCk7CiAgICAgICAgaWYgKCFjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYyxzZXNzaW9uSWQpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCB3aGVuIGZhc3Qgcm9hbSBpcyBkaXNhYmxlZC4gSWdub3JlIGl0IikpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICB9CiAgICB9CgogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIC8qIFRoaXMgY2FuIGhhcHBlbiB3aGVuIHdlIHJlY2VpdmUgYSBVUCBldmVudCBmcm9tIFRMIGluIGFueSBvZiB0aGUgc2NhbiBzdGF0ZXMuIFNpbGVudGx5IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gQ09OTkVDVEVEIHN0YXRlLiBNdXN0IGJlIGJlY2F1c2UgYSBVUCBldmVudCBmcm9tIFRMIGFmdGVyIGlzc3Vpbmcgc2NhbiByZXF1ZXN0LiBJZ25vcmUgaXQiKSk7CiAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gSU5JVCBzdGF0ZS4gTXVzdCBoYXZlIGRpc2Nvbm5lY3RlZC4gSWdub3JlIGl0IikpOwogICAgICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCAiJXM6IHByb2Nlc3Mgc2NhbiByZXN1bHRzIiwgX19mdW5jX18pOwogICAgaHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuQ29tcGxldGUocE1hYyk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHNjYW4gcHJvY2VzcyBjb21wbGV0ZSBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgaHN0YXR1cyk7CiAgICB9CgogICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKCiAgICByZXR1cm4gaHN0YXR1czsKfQojZW5kaWYKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jc3N1ZUJnU2NhblJlcXVlc3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXNzdWVzIENTUiBzY2FuIHJlcXVlc3QgYWZ0ZXIgcG9wdWxhdGluZyBhbGwgdGhlIEJHIHNjYW4gcGFyYW1zIAogICAgICAgICAgICBwYXNzZWQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBCZ1NjYW5QYXJhbXMgLSBQYXJhbXMgdGhhdCBuZWVkIHRvIGJlIHBvcHVsYXRlZCBpbnRvIGNzciBTY2FuIHJlcXVlc3QKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Jc3N1ZUJnU2NhblJlcXVlc3QodHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRDc3JCR1NjYW5SZXF1ZXN0ICpwQmdTY2FuUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1UzMiBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzclNjYW5Db21wbGV0ZUNhbGxiYWNrIGNhbGxiYWNrZm4pCnsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRBTklfVTMyIHNjYW5JZDsKICAgIHRDc3JTY2FuUmVxdWVzdCBzY2FuUmVxOwogICAgdEFOSV9VOCBjaGFubmVsOwogICAgdm9pZCAqIHVzZXJEYXRhID0gTlVMTDsKICAgIAogICAgaWYgKDEgPT0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJDaGFubmVsID0gJWQsIENoYW5JbmRleCA9ICVkIiksCiAgICAgICAgICAgIHBCZ1NjYW5QYXJhbXMtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0WzBdLCAKICAgICAgICAgICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4KTsKCiAgICAvL3NlbmQgZG93biB0aGUgc2NhbiByZXEgZm9yIDEgY2hhbm5lbCBvbiB0aGUgYXNzb2NpYXRlZCBTU0lECiAgICB2b3NfbWVtX3NldCgmc2NhblJlcSwgc2l6ZW9mKHRDc3JTY2FuUmVxdWVzdCksIDApOwogICAgLyogRmlsbCBpbiB0aGUgU1NJRCBJbmZvICovCiAgICBzY2FuUmVxLlNTSURzLm51bU9mU1NJRHMgPSAxOwogICAgc2NhblJlcS5TU0lEcy5TU0lETGlzdCA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyU1NJREluZm8pICogc2NhblJlcS5TU0lEcy5udW1PZlNTSURzKTsKICAgIGlmIChOVUxMID09IHNjYW5SZXEuU1NJRHMuU1NJRExpc3QpCiAgICB7CiAgICAgICAvL2VyciBtc2cKICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQ291bGRuJ3QgYWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgU1NJRC4uRnJlZWluZyBtZW1vcnkgYWxsb2NhdGVkIGZvciBDaGFubmVsIExpc3QiKSk7CiAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIHZvc19tZW1femVybyhzY2FuUmVxLlNTSURzLlNTSURMaXN0LCBzaXplb2YodENzclNTSURJbmZvKSAqIHNjYW5SZXEuU1NJRHMubnVtT2ZTU0lEcyk7CgogICAgc2NhblJlcS5TU0lEcy5TU0lETGlzdFswXS5oYW5kb2ZmUGVybWl0dGVkID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICBzY2FuUmVxLlNTSURzLlNTSURMaXN0WzBdLnNzaWRIaWRkZW4gPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgIHZvc19tZW1fY29weSgodm9pZCAqKSZzY2FuUmVxLlNTSURzLlNTSURMaXN0WzBdLlNTSUQsICh2b2lkICopJnBCZ1NjYW5QYXJhbXMtPlNTSUQsIHNpemVvZihwQmdTY2FuUGFyYW1zLT5TU0lEKSk7CiAgICAKICAgIHNjYW5SZXEuQ2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyA9IHBCZ1NjYW5QYXJhbXMtPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHM7CiAgICBpZiAoMSA9PSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzKQogICAgewogICAgICAgIGNoYW5uZWwgPSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdFswXTsKICAgICAgICBzY2FuUmVxLkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gJmNoYW5uZWw7ICAgIAogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHNjYW5SZXEuQ2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdDsKICAgIH0KCiAgICBzY2FuUmVxLkJTU1R5cGUgPSBlQ1NSX0JTU19UWVBFX0lORlJBU1RSVUNUVVJFOwogICAgc2NhblJlcS5zY2FuVHlwZSA9IGVTSVJfQUNUSVZFX1NDQU47CiAgICBzY2FuUmVxLnJlcXVlc3RUeXBlID0gZUNTUl9TQ0FOX0hPX0JHX1NDQU47CiAgICBzY2FuUmVxLm1heENoblRpbWUgPSBwQmdTY2FuUGFyYW1zLT5tYXhDaG5UaW1lOwogICAgc2NhblJlcS5taW5DaG5UaW1lID0gcEJnU2NhblBhcmFtcy0+bWluQ2huVGltZTsKCiAgICB1c2VyRGF0YSA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0QU5JX1UzMikpOwogICAgaWYgKE5VTEwgPT0gdXNlckRhdGEpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJGYWlsZWQgdG8gYWxsb2NhdGUgbWVtb3J5IGZvciBzY2FuIHJlcXVlc3QiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHNjYW5SZXEuU1NJRHMuU1NJRExpc3QpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgKigodEFOSV9VMzIqKXVzZXJEYXRhKSA9IHNlc3Npb25JZDsKICAgIHN0YXR1cyA9IGNzclNjYW5SZXF1ZXN0KHBNYWMsIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQsICZzY2FuUmVxLAogICAgICAgICAgICAgICAgICAgICAgICAmc2NhbklkLCBjYWxsYmFja2ZuLCAodm9pZCAqKSB1c2VyRGF0YSk7CiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJDU1IgU2NhbiBSZXF1ZXN0IGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBzdGF0dXMpOwogICAgICAgIHZvc19tZW1fZnJlZShzY2FuUmVxLlNTSURzLlNTSURMaXN0KTsKICAgICAgICB2b3NfbWVtX2ZyZWUodXNlckRhdGEpOwogICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uc2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKCiAgICB2b3NfbWVtX2ZyZWUoc2NhblJlcS5TU0lEcy5TU0lETGlzdCk7CiAgICBpZiAoMSA9PSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzKQogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIkNoYW5uZWwgTGlzdCBBZGRyZXNzID0gJXBLLCBBY3R1YWwgaW5kZXggPSAlZCIpLAogICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdFswXSwgCiAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgpOwoKICAgIHJldHVybiBzdGF0dXM7Cn0KCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbUZpbGxOb25DaGFubmVsQmdTY2FuUGFyYW1zICh0cEFuaVNpckdsb2JhbCBwTWFjLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwQ3NyQkdTY2FuUmVxdWVzdCBiZ1NjYW5QYXJhbXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCAgICAgICAgICAgICBicm9hZGNhc3RCc3NpZFtdID0geyAweEZGLCAweEZGLCAweEZGLCAweEZGLCAweEZGLCAweEZGIH07CgogICAgdm9zX21lbV9jb3B5KGJnU2NhblBhcmFtcy0+YnNzaWQsIGJyb2FkY2FzdEJzc2lkLCBzaXplb2YodENzckJzc2lkKSk7CiAgICBiZ1NjYW5QYXJhbXMtPlNTSUQubGVuZ3RoID0gcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQubGVuZ3RoOwogICAgdm9zX21lbV9jb3B5KGJnU2NhblBhcmFtcy0+U1NJRC5zc0lkLCAKICAgICAgICBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3BOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuU1NJRC5zc0lkLAogICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5TU0lELmxlbmd0aCk7CgogICAgYmdTY2FuUGFyYW1zLT5taW5DaG5UaW1lID0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5taW5DaGFubmVsU2NhblRpbWU7CiAgICBiZ1NjYW5QYXJhbXMtPm1heENoblRpbWUgPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1heENoYW5uZWxTY2FuVGltZTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVBlcmZvcm1CZ1NjYW4KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgaW52b2tlZCBvbiBldmVyeSBleHBpcnkgb2YgbmVpZ2hib3JTY2FuVGltZXIgdGlsbCBhbGwgCiAgICAgICAgICAgIHRoZSBjaGFubmVscyBpbiB0aGUgY2hhbm5lbCBsaXN0IGFyZSBzY2FubmVkLiBJdCBwb3B1bGF0ZXMgbmVjZXNzYXJ5IAogICAgICAgICAgICBwYXJhbWV0ZXJzIGZvciBCRyBzY2FuIGFuZCBjYWxscyBhcHByb3ByaWF0ZSBBUCB0byBpbnZva2UgdGhlIENTUiBzY2FuIAogICAgICAgICAgICByZXF1ZXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVBlcmZvcm1CZ1NjYW4odHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VMzIgc2Vzc2lvbklkKQp7CiAgICBlSGFsU3RhdHVzICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdENzckJHU2NhblJlcXVlc3QgICBiZ1NjYW5QYXJhbXM7CiAgICB0QU5JX1U4ICAgICAgICAgICAgIGNoYW5uZWwgPSAwOwoKICAgIGlmICggcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ICYmCiAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzICkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJDaGFubmVsIExpc3QgQWRkcmVzcyA9ICVwSyIpLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0WzBdKTsKICAgIH0KICAgIGVsc2UgCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiQ2hhbm5lbCBMaXN0IEVtcHR5IikpOwogICAgICAgIC8vIEdvIGJhY2sgYW5kIHJlc3RhcnQuIE1vc3RseSB0aW1lciBzdGFydCBmYWlsdXJlIGhhcyBvY2N1cnJlZC4KICAgICAgICAvLyBXaGVuIHRpbWVyIHN0YXJ0IGlzIGRlY2xhcmVkIGEgZmFpbHVyZSwgdGhlbiB3ZSBkZWxldGUgdGhlIGxpc3QuCiAgICAgICAgLy8gU2hvdWxkIG5vdCBoYXBwZW4gbm93IGFzIHdlIHN0b3AgYW5kIHRoZW4gb25seSBzdGFydCB0aGUgc2NhbiB0aW1lci4gCiAgICAgICAgLy8gc3RpbGwgaGFuZGxlIHRoZSB1bmxpa2VseSBjYXNlLgogICAgICAgIGNzck5laWdoYm9yUm9hbUhhbmRsZUVtcHR5U2NhblJlc3VsdChwTWFjKTsKICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgfQoKICAgIC8qIFZhbGlkYXRlIHRoZSBjdXJyZW50Q2hhbkluZGV4IHZhbHVlIGJlZm9yZSB1c2luZyBpdCB0byBpbmRleCB0aGUgQ2hhbm5lbExpc3QgYXJyYXkgKi8KICAgIGlmICggcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4CiAgICAgICAgICAgID4gcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiSW52YWxpZCBjaGFubmVsIGluZGV4OiAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgpOwogICAgICAgIC8vIEdvIGJhY2sgYW5kIHJlc3RhcnQuCiAgICAgICAgY3NyTmVpZ2hib3JSb2FtSGFuZGxlRW1wdHlTY2FuUmVzdWx0KHBNYWMpOwogICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CgogICAgLyogTmVlZCB0byBwZXJmb3JtIHNjYW4gaGVyZSBiZWZvcmUgZ2V0dGluZyB0aGUgbGlzdCAqLwoKICAgIHZvc19tZW1fc2V0KCZiZ1NjYW5QYXJhbXMsIHNpemVvZih0Q3NyQkdTY2FuUmVxdWVzdCksIDApOwoKICAgIGNoYW5uZWwgPSBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4XTsKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gMTsKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9ICZjaGFubmVsOwoKICAgIGNzck5laWdoYm9yUm9hbUZpbGxOb25DaGFubmVsQmdTY2FuUGFyYW1zKHBNYWMsICZiZ1NjYW5QYXJhbXMpOwoKICAgIC8qIFVwZGF0ZSB0aGUgcGFzc2l2ZSBzY2FuIHRpbWUgZm9yIERGUyBjaGFubmVsICovCiAgICBpZiAoKFRSVUUgPT0gQ1NSX0lTX0NIQU5ORUxfREZTKGNoYW5uZWwpKSAmJgogICAgICAgICAoVFJVRSA9PSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmFsbG93REZTQ2hhbm5lbFJvYW0pKQogICAgewogICAgICAgICBiZ1NjYW5QYXJhbXMubWluQ2huVGltZSA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ublBhc3NpdmVNaW5DaG5UaW1lOwogICAgICAgICBiZ1NjYW5QYXJhbXMubWF4Q2huVGltZSA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ublBhc3NpdmVNYXhDaG5UaW1lOwogICAgfQoKICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlQmdTY2FuUmVxdWVzdChwTWFjLCAmYmdTY2FuUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCwgY3NyTmVpZ2hib3JSb2FtU2NhblJlcXVlc3RDYWxsYmFjayk7CiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJc3N1ZSBvZiBCRyBTY2FuIHJlcXVlc3QgZmFpbGVkOiBTdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCsrOwogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA+PSAKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICB7ICAgICAgCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiQ29tcGxldGVkIHNjYW5uaW5nIGNoYW5uZWxzIGluIENoYW5uZWwgTGlzdDogQ3VyckNoYW5JbmRleCA9ICVkLCBOdW0gQ2hhbm5lbHMgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpOwogICAgICAgIC8qIFdlIGhhdmUgY29tcGxldGVkIHNjYW5uaW5nIGFsbCB0aGUgY2hhbm5lbHMgKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPSAwOwogICAgICAgIC8qIFdlIGFyZSBubyBsb25nZXIgc2Nhbm5pbmcgdGhlIGNoYW5uZWwgbGlzdC4gTmV4dCB0aW1lciBmaXJpbmcgc2hvdWxkIGJlIHVzZWQgdG8gZ2V0IHRoZSBzY2FuIHJlc3VsdHMgCiAgICAgICAgICAgYW5kIHNlbGVjdCB0aGUgYmVzdCBBUCBpbiB0aGUgbGlzdCAqLwogICAgICAgIGlmIChlQU5JX0JPT0xFQU5fVFJVRSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MpCiAgICAgICAgewogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICAvKgogICAgICAgICAqIElmIHRoZSBzdGF0dXMgaXMgbm90IHN1Y2Nlc3MsIHdlIG5lZWQgdG8gY2FsbCB0aGUgY2FsbGJhY2sKICAgICAgICAgKiByb3V0aW5lIHNvIHRoYXQgdGhlIHN0YXRlIG1hY2hpbmUgZG9lcyBub3QgZ2V0IHN0dWNrLgogICAgICAgICAqLwogICAgICAgIGNzck5laWdoYm9yUm9hbVNjYW5SZXF1ZXN0Q2FsbGJhY2socE1hYywgTlVMTCwgMCwgZUNTUl9TQ0FOX0ZBSUxVUkUpOwogICAgfQoKICAgIHJldHVybiBzdGF0dXM7Cn0KCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtU2NhbkZvckluaXRpYWxGb3JjZWQ1R1JvYW1pbmcodHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VMzIgc2Vzc2lvbklkKQp7CiAgICBlSGFsU3RhdHVzICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRDc3JCR1NjYW5SZXF1ZXN0ICAgYmdTY2FuUGFyYW1zOwogICAgdEFOSV9VOCAgIG51bU9mQ2hhbm5lbHMgPSAwLCBpID0gMDsKICAgIHRBTklfVTggICB0ZW1wQ2hhbm5lbExpc3RbV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOXTsKICAgIHRBTklfVTggICBjaGFubmVsTGlzdFtXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU5dOwogICAgdEFOSV9VOCAgIHRlbXBOdW1PZkNoYW5uZWxzID0gMDsKCiAgICB2b3NfbWVtX3NldCgmYmdTY2FuUGFyYW1zLCBzaXplb2YodENzckJHU2NhblJlcXVlc3QpLCAwKTsKICAgIC8qIENvbnRpZ3VvdXNseSBzY2FuIGFsbCBjaGFubmVscyBmcm9tIHZhbGlkIGxpc3QgKi8KICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIiVzOiBnZXQgdmFsaWQgY2hhbm5lbCBsaXN0IiwgX19mdW5jX18pOwogICAgdGVtcE51bU9mQ2hhbm5lbHMgPSBzaXplb2YocE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0KTsKCiAgICBpZihIQUxfU1RBVFVTX1NVQ0NFU1MoY3NyR2V0Q2ZnVmFsaWRDaGFubmVscyhwTWFjLAogICAgICAgICAgICAgICAgICAgICh0QU5JX1U4ICopcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICh0QU5JX1UzMiAqKSAmdGVtcE51bU9mQ2hhbm5lbHMpKSkKICAgIHsKICAgICAgICAvL01ha2Ugc3VyZSB3ZSBhcmUgc2Nhbm5pbmcgb25seSBmb3IgNUdoeiBBUCBvbmx5CiAgICAgICAgLy9GaWxldHJpbmcgb3V0IHRoZSA1R0haIGJhc2VkIEFQLmZyb20gdmFsaWQgY2hhbm5lbCBsaXN0CiAgICAgICAgY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUJhbmQoCiAgICAgICAgICAgICAgICAgICAgIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgdGVtcE51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgIHRlbXBDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgJnRlbXBOdW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICBTSVJfQkFORF81X0dIWgogICAgICAgICAgICAgICAgICAgICApOwogICAgICAgIGZvciAoaSA9IDA7IChpIDwgdGVtcE51bU9mQ2hhbm5lbHMgJiYoaSA8IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikpOyBpKyspCiAgICAgICAgewogICAgICAgICAgICAvKiBERlMgY2hhbm5lbCB3aWxsIGJlIGFkZGVkIGluIHRoZSBsaXN0IG9ubHkgd2hlbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgREZTIFJvYW1pbmcgc2NhbiBmbGFnIGlzIGVuYWJsZWQqLwogICAgICAgICAgICBpZiAoQ1NSX0lTX0NIQU5ORUxfREZTKHRlbXBDaGFubmVsTGlzdFtpXSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmFsbG93REZTQ2hhbm5lbFJvYW0gPT0gVFJVRSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFtudW1PZkNoYW5uZWxzKytdID0gdGVtcENoYW5uZWxMaXN0W2ldOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2hhbm5lbExpc3RbbnVtT2ZDaGFubmVscysrXSA9IHRlbXBDaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoImNzckdldENmZ1ZhbGlkQ2hhbm5lbHMgZ290IGZhaWxlZCAiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CgogICAgaWYobnVtT2ZDaGFubmVscyA9PSAwKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICBGTCgiIE5vIHZhbGlkIDVHaHogY2hhbm5lbCBwcmVzZW50IHNvIHNraXBwaW5nIEluaXRpYWwgRm9yY2VkIDVHaCByb2FtaW5nIikpOwogICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRU1QVFk7CiAgICB9CiAgICBpZiAobnVtT2ZDaGFubmVscyA+IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgIHsKICAgICAgICBudW1PZkNoYW5uZWxzID0gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOOwogICAgfQoKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gbnVtT2ZDaGFubmVsczsKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IGNoYW5uZWxMaXN0OwogICAgZm9yIChpID0gMDsgaSA8IG51bU9mQ2hhbm5lbHM7IGkrKykKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICIlczogdmFsaWQgY2hhbm5lbCBsaXN0ID0gJWQiLAogICAgICAgICAgICAgICAgX19mdW5jX18sIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5DaGFubmVsTGlzdFtpXSk7CiAgICB9CiAgICBjc3JOZWlnaGJvclJvYW1GaWxsTm9uQ2hhbm5lbEJnU2NhblBhcmFtcyhwTWFjLCAmYmdTY2FuUGFyYW1zKTsKCiAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZUJnU2NhblJlcXVlc3QocE1hYywgJmJnU2NhblBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQsIGNzck5laWdoYm9yUm9hbUZvcmNlUm9hbVRvNUdoU2NhbkNiKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJGb3JjZWQgaW50aWFsIHJvYW0gdG8gNUdoIHJlcXVlc3QgZmFpbGVkOiBTdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQojZW5kaWYKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUNvbnRpZ3VvdXNCZ1NjYW4odHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VMzIgc2Vzc2lvbklkKQp7CiAgICBlSGFsU3RhdHVzICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRDc3JCR1NjYW5SZXF1ZXN0ICAgYmdTY2FuUGFyYW1zOwogICAgdEFOSV9VOCAgIG51bU9mQ2hhbm5lbHMgPSAwLCBpID0gMDsKICAgIHRBTklfVTggICAqY2hhbm5lbExpc3QgPSBOVUxMOwogICAgdEFOSV9VOCAgICpwSW5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICB0QU5JX1U4ICAgdG1wQ2hhbm5lbExpc3RbV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOXTsKCiAgICB2b3NfbWVtX3NldCgmYmdTY2FuUGFyYW1zLCBzaXplb2YodENzckJHU2NhblJlcXVlc3QpLCAwKTsKCiAgICAvKiBDb250aWd1b3VzbHkgc2NhbiBhbGwgY2hhbm5lbHMgZnJvbSB2YWxpZCBsaXN0ICovCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsICIlczogZ2V0IHZhbGlkIGNoYW5uZWwgbGlzdCIsIF9fZnVuY19fKTsKCiAgICBudW1PZkNoYW5uZWxzID0gc2l6ZW9mKHBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCk7CgogICAgaWYoIUhBTF9TVEFUVVNfU1VDQ0VTUyhjc3JHZXRDZmdWYWxpZENoYW5uZWxzKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTMyICopICZudW1PZkNoYW5uZWxzKSkpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJDb3VsZCBub3QgZ2V0IHZhbGlkIGNoYW5uZWwgbGlzdCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIHBJbkNoYW5uZWxMaXN0ID0gcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0OwoKICAgIGlmIChDU1JfSVNfUk9BTV9JTlRSQV9CQU5EX0VOQUJMRUQocE1hYykpCiAgICB7CiAgICAgICAgY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUJhbmQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSW5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFJGQmFuZChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY3VyckFQb3BlcmF0aW9uQ2hhbm5lbCkpOwogICAgICAgIHBJbkNoYW5uZWxMaXN0ID0gdG1wQ2hhbm5lbExpc3Q7CiAgICB9CgogICAgY2hhbm5lbExpc3QgPSB2b3NfbWVtX21hbGxvYyhudW1PZkNoYW5uZWxzKTsKICAgIGlmICggTlVMTCA9PSBjaGFubmVsTGlzdCApCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJjb3VsZCBub3QgYWxsb2NhdGUgbWVtb3J5IGZvciBjaGFubmVsTGlzdCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIHZvc19tZW1fY29weShjaGFubmVsTGlzdCwgKHRBTklfVTggKilwSW5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKCiAgICBiZ1NjYW5QYXJhbXMuQ2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyA9IG51bU9mQ2hhbm5lbHM7CiAgICBiZ1NjYW5QYXJhbXMuQ2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBjaGFubmVsTGlzdDsKICAgIGZvciAoaSA9IDA7IGkgPCBudW1PZkNoYW5uZWxzOyBpKyspCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCAiJXM6IHZhbGlkIGNoYW5uZWwgbGlzdCA9ICVkIiwKICAgICAgICAgICAgICAgIF9fZnVuY19fLCBiZ1NjYW5QYXJhbXMuQ2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbaV0pOwogICAgfQogICAgY3NyTmVpZ2hib3JSb2FtRmlsbE5vbkNoYW5uZWxCZ1NjYW5QYXJhbXMocE1hYywgJmJnU2NhblBhcmFtcyk7CgogICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVCZ1NjYW5SZXF1ZXN0KHBNYWMsICZiZ1NjYW5QYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkLCBjc3JOZWlnaGJvclJvYW1Db250aWd1b3VzU2NhblJlcXVlc3RDYWxsYmFjayk7CgogICAgdm9zX21lbV9mcmVlKGNoYW5uZWxMaXN0KTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJc3N1ZSBvZiBCRyBTY2FuIHJlcXVlc3QgZmFpbGVkOiBTdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgfQoKICAgIHJldHVybiBzdGF0dXM7Cn0KI2VuZGlmCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JTY2FuVGltZXJDYWxsYmFjawoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB0aGUgbmVpZ2hib3Igc2NhbiB0aW1lciBjYWxsYmFjayBmdW5jdGlvbi4gSXQgaW52b2tlcyAKICAgICAgICAgICAgdGhlIEJHIHNjYW4gcmVxdWVzdCBiYXNlZCBvbiB0aGUgY3VycmVudCBhbmQgcHJldmlvdXMgc3RhdGVzCgogICAgXHBhcmFtICBwdiAtIENTUiB0aW1lciBjb250ZXh0IGluZm8gd2hpY2ggaW5jbHVkZXMgcE1hYyBhbmQgc2Vzc2lvbiBJRAoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1OZWlnaGJvclNjYW5UaW1lckNhbGxiYWNrKHZvaWQgKnB2KQp7CiAgICB0cEFuaVNpckdsb2JhbCBwTWFjID0gUE1BQ19TVFJVQ1QoIHB2ICk7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICBwTmVpZ2hib3JSb2FtSW5mbzsKICAgIGlmKCFwTWFjKQogICAgewogICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9FUlJPUiwgRkwoInBNYWMgaXMgTnVsbCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgLy8gY2hlY2sgaWYgYmcgc2NhbiBpcyBvbiBnb2luZywgbm8gbmVlZCB0byBzZW5kIGRvd24gdGhlIG5ldyBwYXJhbXMgaWYgdHJ1ZQogICAgaWYoZUFOSV9CT09MRUFOX1RSVUUgPT0gcE5laWdoYm9yUm9hbUluZm8tPnNjYW5Sc3BQZW5kaW5nKQogICAgewogICAgICAgLy9tc2cKICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiQWxyZWFkeSBCZ1NjYW5Sc3AgaXMgUGVuZGluZyIpKTsKICAgICAgIHJldHVybjsKICAgIH0KCiAgICBzd2l0Y2ggKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU46CiAgICAgICAgICAgIHN3aXRjaChwTmVpZ2hib3JSb2FtSW5mby0+cHJldk5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfUVVFUlk6CiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUJnU2NhbihwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIGNhbGxiYWNrIHJlY2VpdmVkIGluIgogICAgICAgICAgICAgICAgICAgICAgICAgICJzdGF0ZSAlcywgcHJldiBzdGF0ZSA9ICVzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnByZXZOZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU46ICAgICAKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUJnU2NhbihwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuOwp9Cgp2b2lkIGNzck5laWdoYm9yUm9hbUVtcHR5U2NhblJlZnJlc2hUaW1lckNhbGxiYWNrKHZvaWQgKmNvbnRleHQpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVCggY29udGV4dCApOwogICAgVk9TX1NUQVRVUyAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm87CiAgICBpZighcE1hYykKICAgIHsKICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsIEZMKCJwTWFjIGlzIE51bGwiKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIC8qIFJlc2V0IGFsbCB0aGUgdmFyaWFibGVzIGp1c3QgYXMgbm8gc2NhbiBoYWQgaGFwcGVuZWQgYmVmb3JlICovCiAgICBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8ocE1hYyk7CgojaWYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAmJiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRkkKICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpICYmIChwTWFjLT5ycm0ucnJtU21lQ29udGV4dC5ycm1Db25maWcucnJtRW5hYmxlZCkpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiMTFSIEFzc29jaWF0aW9uOk5laWdoYm9yIExvb2t1cCBEb3duIGV2ZW50IHJlY2VpdmVkIGluIENPTk5FQ1RFRCBzdGF0ZSIpKTsKICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZU5laWdoYm9yUnB0UmVxdWVzdChwTWFjKTsKICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVwb3J0IHJlcXVlc3QgZmFpbGVkLiBzdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIC8qIEluY3JlbWVudCB0aGUgbmVpZ2hib3IgcmVwb3J0IHJldHJ5IGNvdW50IGFmdGVyIHNlbmRpbmcgdGhlIG5laWdoYm9yIHJlcXVlc3Qgc3VjY2Vzc2Z1bGx5ICovCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0rKzsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfUVVFUlkpCiAgICB9CiAgICBlbHNlCiNlbmRpZgogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIk5vbiAxMVIgb3IgRVNFIEFzc29jaWF0aW9uOmVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciBleHBpcmVkIikpOwogICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMpOwogICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVJlc3VsdHNSZWZyZXNoVGltZXJDYWxsYmFjawoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB0aGUgdGltZXIgY2FsbGJhY2sgZnVuY3Rpb24gZm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lci4KICAgICAgICAgICAgV2hlbiB0aGlzIGlzIGludm9rZWQsIGl0IGlzIGFzIGdvb2QgYXMgZG93biBldmVudCByZWNlaXZlZCBmcm9tIFRMLiBTbywgCiAgICAgICAgICAgIGNsZWFyIG9mZiB0aGUgcm9hbWFibGUgQVAgbGlzdCBhbmQgc3RhcnQgdGhlIHNjYW4gcHJvY2VkdXJlIGJhc2VkIG9uIDExUiAKICAgICAgICAgICAgb3Igbm9uLTExUiBhc3NvY2lhdGlvbgoKICAgIFxwYXJhbSAgY29udGV4dCAtIENTUiB0aW1lciBjb250ZXh0IGluZm8gd2hpY2ggaW5jbHVkZXMgcE1hYyBhbmQgc2Vzc2lvbiBJRAoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1SZXN1bHRzUmVmcmVzaFRpbWVyQ2FsbGJhY2sodm9pZCAqY29udGV4dCkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKCBjb250ZXh0ICk7CiAgICBWT1NfU1RBVFVTICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICBwTmVpZ2hib3JSb2FtSW5mbzsKCiAgICBpZighcE1hYykKICAgIHsKICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsIEZMKCJwTWFjIGlzIE51bGwiKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkRlcmVnaXN0ZXJpbmcgRE9XTiBldmVudCByZWFzc29jIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSkpOwoKICAgIC8qIERlcmVnaXN0ZXIgcmVhc3NvYyBjYWxsYmFjay4gSWdub3JlIHJldHVybiBzdGF0dXMgKi8KICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgIHsKICAgICAgICAvL2VyciBtc2cKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgfQoKICAgIC8qIFJlc2V0IGFsbCB0aGUgdmFyaWFibGVzIGp1c3QgYXMgbm8gc2NhbiBoYWQgaGFwcGVuZWQgYmVmb3JlICovCiAgICBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8ocE1hYyk7CgojaWYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAmJiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRkkKICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpICYmIChwTWFjLT5ycm0ucnJtU21lQ29udGV4dC5ycm1Db25maWcucnJtRW5hYmxlZCkpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiMTFSIEFzc29jaWF0aW9uOk5laWdoYm9yIExvb2t1cCBEb3duIGV2ZW50IHJlY2VpdmVkIGluIENPTk5FQ1RFRCBzdGF0ZSIpKTsKICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZU5laWdoYm9yUnB0UmVxdWVzdChwTWFjKTsKICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVwb3J0IHJlcXVlc3QgZmFpbGVkLiBzdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIC8qIEluY3JlbWVudCB0aGUgbmVpZ2hib3IgcmVwb3J0IHJldHJ5IGNvdW50IGFmdGVyIHNlbmRpbmcgdGhlIG5laWdoYm9yIHJlcXVlc3Qgc3VjY2Vzc2Z1bGx5ICovCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0rKzsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfUVVFUlkpCiAgICB9CiAgICBlbHNlCiNlbmRpZiAgICAgIAogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIk5vbiAxMVIgb3IgRVNFIEFzc29jaWF0aW9uOnJlc3VsdHMgcmVmcmVzaCB0aW1lciBleHBpcmVkIikpOwogICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMpOwogICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzckZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lckNhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHRoZSB0aW1lciBjYWxsYmFjayBmdW5jdGlvbiBmb3IgdHJpZ2dlcmluZwogICAgICAgICAgICAgIHJvYW1pbmcgdG8gNUdIeiBhZnRlciB0aGUgaW5pdGlhbCBhc3NvY2lhdGlvbi4KCiAgICBccGFyYW0gIGNvbnRleHQgLSBDU1IgdGltZXIgY29udGV4dCBpbmZvIHdoaWNoIGluY2x1ZGVzIHBNYWMgYW5kIHNlc3Npb24gSUQKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgp2b2lkIGNzckZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lckNhbGxiYWNrKHZvaWQgKmNvbnRleHQpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVCggY29udGV4dCApOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm87CiAgICBpZighcE1hYykKICAgIHsKICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsIEZMKCJwTWFjIGlzIE51bGwiKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoImZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lciB0aW1lciBleHBpcmVkIikpOwoKICAgIC8vd2UgZG9uJ3QgbmVlZCB0byBydW4gdGhpcyB0aW1lciBhbnkgbW9yZQogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5mb3JjZWRJbml0aWFsUm9hbVRvNUdIVGltZXIpOwoKICAgIC8vd2UgbXVzdCBiZSBpbiBjb25uZWN0ZWQgc3RhdGUsIGlmIG5vdCBpZ25vcmUgaXQKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIG5vdCBDT05ORUNURUQgc3RhdGUuIElnbm9yZSBpdCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy9pdCBtYXkgcG9zc2libGUgdXNlciByZWNvbm5lY3RlZCAvIERVVCByb2FtZWQgdG8gb3RoZXIgYmFuZCBhcCBidHcKICAgIC8vdGltZXIgc3RhcnRlZCBhbmQgdGltZXIgY2FsbGJhY2sgaGl0LgogICAgaWYoR2V0UkZCYW5kKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jdXJyQVBvcGVyYXRpb25DaGFubmVsKSA9PSBTSVJfQkFORF81X0dIWikKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwKICAgICAgICAgICAgICAgRkwoIkRVVCBpcyBhbHJlYWR5IGNvbm5lY3RlZCB0byA1R0ggYXAsIHNvIG5vIG5lZWQgdG8gdHJpZ2dlciBmb3JjZWQgcm9hbS4iKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUmVxdWVzdFRpbWVTdGFtcCA9IHZvc190aW1lcl9nZXRfc3lzdGVtX3RpbWUoKTsKICAgIC8qCiAgICAgKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlIGZvciBhbGwgdmFsaWQgY2hhbm5sZXMgZm9yIDVHaHoKICAgICAqIHB1cmdlIG5vbi1QMlAgcmVzdWx0cyBmcm9tIHRoZSBwYXN0IGZvciA1R2h6IGJhbmQKICAgICAqLwogICAgY3NyU2NhbkZsdXNoU2VsZWN0aXZlUmVzdWx0Rm9yQmFuZChwTWFjLCBWT1NfRkFMU0UsIFNJUl9CQU5EXzVfR0haKTsKICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVNjYW5Gb3JJbml0aWFsRm9yY2VkNUdSb2FtaW5nKAogICAgICAgICAgICAgICAgIHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQpOwogICAgaWYoc3RhdHVzICE9IGVIQUxfU1RBVFVTX1NVQ0NFU1MpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgIEZMKCJjc3JOZWlnaGJvclJvYW1TY2FuRm9ySW5pdGlhbEZvcmNlZDVHUm9hbWluZyBmYWlsZWQgc3RhdHVzPSVkIiksIHN0YXR1cyk7CiAgICAgICAgLy9TZW5kIFJTTyBzdGFydCBiZWNhdXNlIGluIGNhc2UgNUcgcm9hbWluZyBob3N0IGhhdmUgbm90IGVuYWJsZWQgYXQgaW5pdGlhbCBjb25uZWN0aW9uCiAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fQ09OTkVDVCk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIFRyYW5zaXRpb24gdG8gQ0ZHX0NIQU5fTElTVF9TQ0FOICovCiAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU4pOwp9CgojaWYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAmJiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRkkKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGludm9rZWQgd2hlbiBUTCBpc3N1ZXMgYSBkb3duIGV2ZW50IGFuZCB0aGUgY3VycmVudCBhc3NvYyAKICAgICAgICAgICAgaXMgYSAxMVIgYXNzb2NpYXRpb24uIEl0IGludm9rZXMgU01FIFJSTSBBUEkgdG8gaXNzdWUgdGhlIG5laWdoYm9yIHJlcXVlc3QgdG8gCiAgICAgICAgICAgIHRoZSBjdXJyZW50bHkgYXNzb2NpYXRlZCBBUCB3aXRoIHRoZSBjdXJyZW50IFNTSUQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1Jc3N1ZU5laWdoYm9yUnB0UmVxdWVzdCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0UnJtTmVpZ2hib3JSc3BDYWxsYmFja0luZm8gY2FsbGJhY2tJbmZvOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0UnJtTmVpZ2hib3JSZXEgbmVpZ2hib3JSZXE7CgoKICAgIG5laWdoYm9yUmVxLm5vX3NzaWQgPSAwOwoKICAgIC8qIEZpbGwgaW4gdGhlIFNTSUQgKi8KICAgIG5laWdoYm9yUmVxLnNzaWQubGVuZ3RoID0gcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQubGVuZ3RoOwogICAgdm9zX21lbV9jb3B5KG5laWdoYm9yUmVxLnNzaWQuc3NJZCwgcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQuc3NJZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5TU0lELmxlbmd0aCk7CiAgICAKICAgIGNhbGxiYWNrSW5mby5uZWlnaGJvclJzcENhbGxiYWNrID0gY3NyTmVpZ2hib3JSb2FtUlJNTmVpZ2hib3JSZXBvcnRSZXN1bHQ7CiAgICBjYWxsYmFja0luZm8ubmVpZ2hib3JSc3BDYWxsYmFja0NvbnRleHQgPSBwTWFjOwogICAgY2FsbGJhY2tJbmZvLnRpbWVvdXQgPSBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJlcG9ydFRpbWVvdXQ7CgogICAgcmV0dXJuIHNtZV9OZWlnaGJvclJlcG9ydFJlcXVlc3QocE1hYywodEFOSV9VOCkgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwgJm5laWdoYm9yUmVxLCAmY2FsbGJhY2tJbmZvKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUNoYW5uZWxzRmlsdGVyQnlCYW5kCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZmlsdGVyIG91dCB0aGUgY2hhbm5lbHMKICAgICAgICAgICAgYmFzZWQgb24gdGhlIEJhbmQgZ2l2ZW4gYXMgaW5wdXQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGlucHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBpbnB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIGlucHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBwT3V0cHV0Q2hhbm5lbExpc3QgLSBUaGUgb3V0cHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBvdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIG51bWJlciBvZiBjaGFubmVscyBpbiBvdXRwdXQgY2hhbm5lbCBsaXN0CiAgICBccGFyYW0gIHBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIGZpbmFsIG51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgb3V0cHV0IGNoYW5uZWwgbGlzdC4KICAgIFxwYXJhbSBiYW5kIC0gVGhlICBiYW5kIHdoaWNoIHdpbGwgYmUgZ2V0IGNvbXBhcmVkIHdpdGggdGhlIGlucHV0IGNoYW5uZWwgbGlzdCBiYW5kCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUJhbmQoCiAgICAgICAgICAgICAgICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCogIHBJbnB1dENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCAgIGlucHV0TnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTgqICBwT3V0cHV0Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4KiAgcE1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICB0U2lyUkZCYW5kIGJhbmQKICAgICAgICAgICAgICAgICAgICAgICkKewogICAgdEFOSV9VOCBpID0gMDsKICAgIHRBTklfVTggbnVtQ2hhbm5lbHMgPSAwOwoKICAgIC8vIENoZWNrIGZvciBOVUxMIHBvaW50ZXIKICAgIGlmICghcElucHV0Q2hhbm5lbExpc3QpIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CgogICAgLy8gQ2hlY2sgZm9yIE5VTEwgcG9pbnRlcgogICAgaWYgKCFwT3V0cHV0Q2hhbm5lbExpc3QpIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CgogICAgaWYgKGlucHV0TnVtT2ZDaGFubmVscyA+IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgIHsKICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgIiVzOiBXcm9uZyBOdW1iZXIgb2YgSW5wdXQgQ2hhbm5lbHMgJWQiLAogICAgICAgICAgICAgX19mdW5jX18sIGlucHV0TnVtT2ZDaGFubmVscyk7CiAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgaW5wdXROdW1PZkNoYW5uZWxzOyBpKyspCiAgICB7CiAgICAgICAgaWYgKGJhbmQgPT0gR2V0UkZCYW5kKHBJbnB1dENoYW5uZWxMaXN0W2ldKSkKICAgICAgICB7CiAgICAgICAgICAgIHBPdXRwdXRDaGFubmVsTGlzdFtudW1DaGFubmVsc10gPSBwSW5wdXRDaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgbnVtQ2hhbm5lbHMrKzsKICAgICAgICB9CiAgICB9CgogICAgLy8gUmV0dXJuIGZpbmFsIG51bWJlciBvZiBjaGFubmVscwogICAgKnBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzID0gbnVtQ2hhbm5lbHM7CgogICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbU1lcmdlQ2hhbm5lbExpc3RzIAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIG1lcmdlIHR3byBjaGFubmVsIGxpc3QuCiAgICAgICAgICAgIE5COiBJZiBjYWxsZWQgd2l0aCBvdXRwdXROdW1PZkNoYW5uZWxzID09IDAsIHRoaXMgcm91dGluZXMKICAgICAgICAgICAgICAgIHNpbXBseSBjb3BpZXMgdGhlIGlucHV0IGNoYW5uZWwgbGlzdCB0byB0aGUgb3V0cHV0IGNoYW5uZWwgbGlzdC4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGFkZHRpb25hbCBjaGFubmVscyB0byBtZXJnZSBpbiB0byB0aGUgIm1lcmdlZCIgY2hhbm5lbHMgbGlzdC4KICAgIFxwYXJhbSAgaW5wdXROdW1PZkNoYW5uZWxzIC0gVGhlIG51bWJlciBvZiBhZGRpdGlvbmFsIGNoYW5uZWxzLgogICAgXHBhcmFtICBwT3V0cHV0Q2hhbm5lbExpc3QgLSBUaGUgcGxhY2UgdG8gcHV0IHRoZSAibWVyZ2VkIiBjaGFubmVsIGxpc3QuCiAgICBccGFyYW0gIG91dHB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgb3JpZ2luYWwgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSAibWVyZ2VkIiBjaGFubmVscyBsaXN0LgogICAgXHBhcmFtICBwTWVyZ2VkT3V0cHV0TnVtT2ZDaGFubmVscyAtIFRoZSBmaW5hbCBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlICJtZXJnZWQiIGNoYW5uZWwgbGlzdC4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbU1lcmdlQ2hhbm5lbExpc3RzKCAKICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLCAKICAgICAgICB0QU5JX1U4ICAgKnBJbnB1dENoYW5uZWxMaXN0LCAKICAgICAgICB0QU5JX1U4ICBpbnB1dE51bU9mQ2hhbm5lbHMsCiAgICAgICAgdEFOSV9VOCAgICpwT3V0cHV0Q2hhbm5lbExpc3QsCiAgICAgICAgdEFOSV9VOCAgb3V0cHV0TnVtT2ZDaGFubmVscywKICAgICAgICB0QU5JX1U4ICAqcE1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMKICAgICAgICApCnsKICAgIHRBTklfVTggaSA9IDA7CiAgICB0QU5JX1U4IGogPSAwOwogICAgdEFOSV9VOCBudW1DaGFubmVscyA9IG91dHB1dE51bU9mQ2hhbm5lbHM7CgogICAgLy8gQ2hlY2sgZm9yIE5VTEwgcG9pbnRlcgogICAgaWYgKCFwSW5wdXRDaGFubmVsTGlzdCkgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKCiAgICAvLyBDaGVjayBmb3IgTlVMTCBwb2ludGVyCiAgICBpZiAoIXBPdXRwdXRDaGFubmVsTGlzdCkgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKCiAgICBpZiAoaW5wdXROdW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgewogICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAiJXM6IFdyb25nIE51bWJlciBvZiBJbnB1dCBDaGFubmVscyAlZCIsCiAgICAgICAgICAgICBfX2Z1bmNfXywgaW5wdXROdW1PZkNoYW5uZWxzKTsKICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKICAgIH0KICAgIGlmIChvdXRwdXROdW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgewogICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAiJXM6IFdyb25nIE51bWJlciBvZiBPdXRwdXQgQ2hhbm5lbHMgJWQiLAogICAgICAgICAgICAgX19mdW5jX18sIGlucHV0TnVtT2ZDaGFubmVscyk7CiAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CiAgICB9CgogICAgLyogQWRkIHRoZSAibmV3IiBjaGFubmVscyBpbiB0aGUgaW5wdXQgbGlzdCB0byB0aGUgZW5kIG9mIHRoZSBvdXRwdXQgbGlzdC4KICAgICAgIENoZWNrIGFkZGVkIGluIGZvciBsb29wIHRvIG1ha2Ugc3VyZSBvdXRwdXRsaXN0IGRvZXNuJ3QgZXhjZWVkcyB2YWxpZAogICAgICAgY2hhbm5lbCBsaXN0IGxlbmd0aC4gKi8KICAgIGZvciAoaSA9IDA7IChpIDwgaW5wdXROdW1PZkNoYW5uZWxzKSAmJiAobnVtQ2hhbm5lbHMgPCBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU4pOyBpKyspCiAgICB7CiAgICAgICAgZm9yIChqID0gMDsgaiA8IG91dHB1dE51bU9mQ2hhbm5lbHM7IGorKykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwSW5wdXRDaGFubmVsTGlzdFtpXSA9PSBwT3V0cHV0Q2hhbm5lbExpc3Rbal0pCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKGogPT0gb3V0cHV0TnVtT2ZDaGFubmVscykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwSW5wdXRDaGFubmVsTGlzdFtpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sIAogICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXSBBZGRpbmcgZXh0cmEgJWQgdG8gTmVpZ2hib3IgY2hhbm5lbCBsaXN0IiwgX19mdW5jX18sCiAgICAgICAgICAgICAgICAgICAgICAgIHBJbnB1dENoYW5uZWxMaXN0W2ldKTsgCiAgICAgICAgICAgICAgICBwT3V0cHV0Q2hhbm5lbExpc3RbbnVtQ2hhbm5lbHNdID0gcElucHV0Q2hhbm5lbExpc3RbaV07IAogICAgICAgICAgICAgICAgbnVtQ2hhbm5lbHMrKzsgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gUmV0dXJuIGZpbmFsIG51bWJlciBvZiBjaGFubmVscwogICAgKnBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzID0gbnVtQ2hhbm5lbHM7IAoKICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1DcmVhdGVDaGFuTGlzdEZyb21OZWlnaGJvclJlcG9ydAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBpbnZva2VkIHdoZW4gbmVpZ2hib3IgcmVwb3J0IGlzIHJlY2VpdmVkIGZvciB0aGUgCiAgICAgICAgICAgIG5laWdoYm9yIHJlcXVlc3QuIEJhc2VkIG9uIHRoZSBjaGFubmVscyBwcmVzZW50IGluIHRoZSBuZWlnaGJvciByZXBvcnQsIAogICAgICAgICAgICBpdCBnZW5lcmF0ZXMgY2hhbm5lbCBsaXN0IHdoaWNoIHdpbGwgYmUgdXNlZCBpbiBSRVBPUlRfU0NBTiBzdGF0ZSB0bwogICAgICAgICAgICBzY2FuIGZvciB0aGVzZSBuZWlnaGJvciBBUHMKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1DcmVhdGVDaGFuTGlzdEZyb21OZWlnaGJvclJlcG9ydCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cFJybU5laWdoYm9yUmVwb3J0RGVzYyAgICAgICBwTmVpZ2hib3JCc3NEZXNjOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCAgICAgICAgICAgICAgICAgICAgICAgbnVtQ2hhbm5lbHMgPSAwOwogICAgdEFOSV9VOCAgICAgICAgICAgICAgICAgICAgICAgaSA9IDA7CiAgICB0QU5JX1U4ICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFtNQVhfQlNTX0lOX05FSUdIQk9SX1JQVF07CiAgICB0QU5JX1U4ICAgICAgICAgICAgICAgICAgICAgICBtZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzID0gMDsKCiAgICAvKiBUaGlzIHNob3VsZCBhbHdheXMgc3RhcnQgZnJvbSAwIHdoZW5ldmVyIHdlIGNyZWF0ZSBhIGNoYW5uZWwgbGlzdCBvdXQgb2YgbmVpZ2hib3IgQVAgbGlzdCAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKCiAgICBwTmVpZ2hib3JCc3NEZXNjID0gc21lUnJtR2V0Rmlyc3RCc3NFbnRyeUZyb21OZWlnaGJvckNhY2hlKHBNYWMpOwoKICAgIHdoaWxlIChwTmVpZ2hib3JCc3NEZXNjKQogICAgewogICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPj0gTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpIGJyZWFrOwogICAgICAgIAogICAgICAgIC8qIFVwZGF0ZSB0aGUgbmVpZ2hib3IgQlNTIEluZm8gaW4gdGhlIDExciBGVCBSb2FtIEluZm8gKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mb1twTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnRdLmNoYW5uZWxOdW0gPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWw7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm9bcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0XS5uZWlnaGJvclNjb3JlID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0QU5JX1U4KXBOZWlnaGJvckJzc0Rlc2MtPnJvYW1TY29yZTsKICAgICAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm9bcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0XS5uZWlnaGJvckJzc0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQrKzsKCiAgICAgICAgLyogU2F2aW5nIHRoZSBjaGFubmVsIGxpc3Qgbm9uLXJlZHVuZGFudGx5ICovCiAgICAgICAgZm9yIChpID0gMDsgKGkgPCBudW1DaGFubmVscyAmJiBpIDwgTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBpZiAocE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWwgPT0gY2hhbm5lbExpc3RbaV0pCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmIChpID09IG51bUNoYW5uZWxzICYmIGkgPCBNQVhfQlNTX0lOX05FSUdIQk9SX1JQVCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwTmVpZ2hib3JCc3NEZXNjLT5wTmVpZ2hib3JCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKENTUl9JU19ST0FNX0lOVFJBX0JBTkRfRU5BQkxFRChwTWFjKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdG8gYWRkIG9ubHkgaWYgaXRzIHRoZSBzYW1lIGJhbmQKICAgICAgICAgICAgICAgICAgICBpZiAoR2V0UkZCYW5kKHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBvcGVyYXRpb25DaGFubmVsKSA9PQogICAgICAgICAgICAgICAgICAgICAgICBHZXRSRkJhbmQocE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWwpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR10gQWRkaW5nICVkIHRvIE5laWdoYm9yIGNoYW5uZWwgbGlzdCAoU2FtZSBiYW5kKVxuIiwgX19mdW5jX18sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3RbbnVtQ2hhbm5lbHNdID0gcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWw7CiAgICAgICAgICAgICAgICAgICAgICAgIG51bUNoYW5uZWxzKys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogW0lORk9MT0ddIEFkZGluZyAlZCB0byBOZWlnaGJvciBjaGFubmVsIGxpc3RcbiIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsKTsKICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFtudW1DaGFubmVsc10gPSBwTmVpZ2hib3JCc3NEZXNjLT5wTmVpZ2hib3JCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbDsKICAgICAgICAgICAgICAgICAgICBudW1DaGFubmVscysrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICBwTmVpZ2hib3JCc3NEZXNjID0gc21lUnJtR2V0TmV4dEJzc0VudHJ5RnJvbU5laWdoYm9yQ2FjaGUocE1hYywgcE5laWdoYm9yQnNzRGVzYyk7CiAgICB9CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCkKICAgIHsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgIH0KCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgLyogU3RvcmUgdGhlIG9idGFpbmVkIGNoYW5uZWwgbGlzdCB0byB0aGUgTmVpZ2hib3IgQ29udHJvbCBkYXRhIHN0cnVjdHVyZSAqLwogICAgaWYgKG51bUNoYW5uZWxzKQogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IHZvc19tZW1fbWFsbG9jKChudW1DaGFubmVscykgKiBzaXplb2YodEFOSV9VOCkpOwogICAgaWYgKE5VTEwgPT0gcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZm9yIENoYW5uZWwgbGlzdCBmYWlsZWQuLiBUTCBldmVudCBpZ25vcmVkIikpOwogICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfUkVTT1VSQ0VTOwogICAgfQoKICAgIHZvc19tZW1fY29weShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LCAobnVtQ2hhbm5lbHMpICogc2l6ZW9mKHRBTklfVTgpKTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gbnVtQ2hhbm5lbHM7CiAgICAvKgogICAgICogQ3JlYXRlIGEgVW5pb24gb2Ygb2NjdXBpZWQgY2hhbm5lbCBsaXN0IGxlYXJudCBieSB0aGUgRFVUIGFsb25nIHdpdGggdGhlIE5laWdoYm9yCiAgICAgKiByZXBvcnQgQ2hhbm5lbHMuIFRoaXMgaW5jcmVhc2VzIHRoZSBjaGFuY2VzIG9mIHRoZSBEVVQgdG8gZ2V0IGEgY2FuZGlkYXRlIEFQIHdoaWxlCiAgICAgKiByb2FtaW5nIGV2ZW4gaWYgdGhlIE5laWdoYm9yIFJlcG9ydCBpcyBub3QgYWJsZSB0byBwcm92aWRlIHN1ZmZpY2llbnQgaW5mb3JtYXRpb24uCiAgICAgKiAqLwogICAgaWYgKHBNYWMtPnNjYW4ub2NjdXBpZWRDaGFubmVscy5udW1DaGFubmVscykKICAgIHsKICAgICAgIGNzck5laWdoYm9yUm9hbU1lcmdlQ2hhbm5lbExpc3RzKHBNYWMsCiAgICAgICAgICAgICAgICAgICZwTWFjLT5zY2FuLm9jY3VwaWVkQ2hhbm5lbHMuY2hhbm5lbExpc3RbMF0sCiAgICAgICAgICAgICAgICAgIHBNYWMtPnNjYW4ub2NjdXBpZWRDaGFubmVscy5udW1DaGFubmVscywKICAgICAgICAgICAgICAgICAgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdFswXSwKICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICZtZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzKTsKICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0KICAgICAgICAgICAgICAgICAgbWVyZ2VkT3V0cHV0TnVtT2ZDaGFubmVsczsKCiAgICB9CiAgICAvKkluZGljYXRlIHRoZSBmaXJtd2FyZSBhYm91dCB0aGUgdXBkYXRlIG9ubHkgaWYgYW55IG5ldyBjaGFubmVscyBhcmUgYWRkZWQuCiAgICAgKiBPdGhlcndpc2UsIHRoZSBmaXJtd2FyZSB3b3VsZCBhbHJlYWR5IGJlIGtub3dpbmcgdGhlIG5vbi1JQVBQbmVpZ2hib3JsaXN0CiAgICAgKiBjaGFubmVscy4gVGhlcmUgaXMgbm8gbmVlZCB0byB1cGRhdGUuKi8KICAgIGlmIChudW1DaGFubmVscykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIklBUFAgTmVpZ2hib3IgbGlzdCBjYWxsYmFjayByZWNlaXZlZCBhcyBleHBlY3RlZCIKICAgICAgICAgICAgICAgImluIHN0YXRlICVzLiIpLAogICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fVFJVRTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIGlmIChjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgIHsKICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfVVBEQVRFX0NGRywgUkVBU09OX0NIQU5ORUxfTElTVF9DSEFOR0VEKTsKICAgICAgICB9CiNlbmRpZgogICAgfQogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4ID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY2hhbkxpc3RTY2FuSW5Qcm9ncmVzcyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgCiAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUlJNTmVpZ2hib3JSZXBvcnRSZXN1bHQKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgdGhlIG5laWdoYm9yIHJlcG9ydCBjYWxsYmFjayB0aGF0IHdpbGwgYmUgaW52b2tlZCBieSAKICAgICAgICAgICAgU01FIFJSTSBvbiByZWNlaXZpbmcgYSBuZWlnaGJvciByZXBvcnQgb3Igb2YgbmVpZ2hib3IgcmVwb3J0IGlzIG5vdCAKICAgICAgICAgICAgcmVjZWl2ZWQgYWZ0ZXIgdGltZW91dC4gT24gcmVjZWl2aW5nIGEgdmFsaWQgcmVwb3J0LCBpdCBnZW5lcmF0ZXMgYSAKICAgICAgICAgICAgY2hhbm5lbCBsaXN0IGZyb20gdGhlIG5laWdoYm9yIHJlcG9ydCBhbmQgc3RhcnRzIHRoZSAKICAgICAgICAgICAgbmVpZ2hib3Igc2NhbiB0aW1lcgoKICAgIFxwYXJhbSAgY29udGV4dCAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgdm9zU3RhdHVzIC0gU3RhdHVzIG9mIHRoZSBjYWxsYmFjayhTVUNDRVNTL0ZBSUxVUkUpCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVJSTU5laWdoYm9yUmVwb3J0UmVzdWx0KHZvaWQgKmNvbnRleHQsIFZPU19TVEFUVVMgdm9zU3RhdHVzKQp7CiAgICB0cEFuaVNpckdsb2JhbCBwTWFjID0gUE1BQ19TVFJVQ1QoY29udGV4dCk7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CgogICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJOZWlnaGJvciByZXBvcnQgcmVzdWx0IGNhbGxiYWNrIHdpdGggc3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgIHN3aXRjaCAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWToKICAgICAgICAgICAgLyogUmVzZXQgdGhlIHJlcG9ydCBwZW5kaW5nIHZhcmlhYmxlICovCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyA9PSB2b3NTdGF0dXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIE5lZWQgdG8gY3JlYXRlIGNoYW5uZWwgbGlzdCBiYXNlZCBvbiB0aGUgbmVpZ2hib3IgQVAgbGlzdCBhbmQgdHJhbnNpdGlvbiB0byBSRVBPUlRfU0NBTiBzdGF0ZSAqLwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtQ3JlYXRlQ2hhbkxpc3RGcm9tTmVpZ2hib3JSZXBvcnQocE1hYyk7CiAgICAgICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTID09IHZvc1N0YXR1cykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJDaGFubmVsIExpc3QgY3JlYXRlZCBmcm9tIE5laWdoYm9yIHJlcG9ydCwgVHJhbnNpdGlvbmluZyB0byBORUlHSEJPUl9TQ0FOIHN0YXRlIikpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIFdlIGFyZSBnb25uYSBzY2FuIG5vdy4gUmVtZW1iZXIgdGhlIHRpbWUgc3RhbXAgdG8gZmlsdGVyIG91dCByZXN1bHRzIG9ubHkgYWZ0ZXIgdGhpcyB0aW1lc3RhbXAgKi8KICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUmVxdWVzdFRpbWVTdGFtcCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b3NfdGltZXJfZ2V0X3N5c3RlbV90aW1lKCk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8qIE5vdyByZWFkeSBmb3IgbmVpZ2hib3Igc2NhbiBiYXNlZCBvbiB0aGUgY2hhbm5lbCBsaXN0IGNyZWF0ZWQgKi8KICAgICAgICAgICAgICAgIC8qIFN0YXJ0IE5laWdoYm9yIHNjYW4gdGltZXIgbm93LiBNdWx0aXBsaWNhdGlvbiBieSBQQUxfVElNRVJfVE9fTVNfVU5JVCBpcyB0byBjb252ZXJ0IG1zIHRvIHVzIHdoaWNoIGlzIAogICAgICAgICAgICAgICAgICAgd2hhdCBwYWxUaW1lclN0YXJ0IGV4cGVjdHMgKi8KICAgICAgICAgICAgICAgIHN0YXR1cyA9IHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JTY2FuUGVyaW9kKTsKICAgICAgICAgICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBUaW1lciBzdGFydCBmYWlsZWQuLiBTaG91bGQgd2UgQVNTRVJUIGhlcmU/Pz8gKi8KICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlBBTCBUaW1lciBzdGFydCBmb3IgbmVpZ2hib3Igc2NhbiB0aW1lciBmYWlsZWQsIHN0YXR1cyA9ICVkLCBJZ25vcmluZyBzdGF0ZSB0cmFuc2l0aW9uIiksIHN0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOyAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8qIE5laWdoYm9yIHNjYW4gdGltZXIgc3RhcnRlZC4gVHJhbnNpdGlvbiB0byBSRVBPUlRfU0NBTiBzdGF0ZSAqLwogICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4pCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBOZWlnaGJvciByZXBvcnQgdGltZW91dCBoYXBwZW5lZCBpbiBTTUUgUlJNLiBXZSBjYW4gdHJ5IHNlbmRpbmcgbW9yZSBuZWlnaGJvciByZXF1ZXN0cyB1bnRpbCB3ZSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFjaCB0aGUgbWF4TmVpZ2hib3JSZXRyaWVzIG9yIHJlY2VpdmluZyBhIHN1Y2Nlc3NmdWwgbmVpZ2hib3IgcmVzcG9uc2UgKi8KICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVwb3J0IHJlc3VsdCBmYWlsZWQgYWZ0ZXIgJWQgcmV0cmllcywgTUFYIFJFVFJJRVMgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSwgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5tYXhOZWlnaGJvclJldHJpZXMpOwogICAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtID49IAogICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1heE5laWdoYm9yUmV0cmllcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkJhaWxpbmcgb3V0IHRvIENGRyBDaGFubmVsIGxpc3Qgc2Nhbi4uICIpKTsKICAgICAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1UcmFuc2l0VG9DRkdDaGFuU2NhbihwTWFjKTsKICAgICAgICAgICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiVHJhbnNpdCB0byBDRkcgQ2hhbm5lbCBsaXN0IHNjYW4gc3RhdGUgZmFpbGVkIHdpdGggc3RhdHVzICVkICIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8qIFdlIHRyYW5zaXRpb25lZCB0byBkaWZmZXJlbnQgc3RhdGUgbm93LiBSZXNldCB0aGUgTmVpZ2hib3IgcmVwb3J0IHJldHJ5IGNvdW50ICovCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHBNYWMpOwogICAgICAgICAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXBvcnQgcmVxdWVzdCBmYWlsZWQuIHN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgICAgICAgICAgICAgLyogSW5jcmVtZW50IHRoZSBuZWlnaGJvciByZXBvcnQgcmV0cnkgY291bnQgYWZ0ZXIgc2VuZGluZyB0aGUgbmVpZ2hib3IgcmVxdWVzdCBzdWNjZXNzZnVsbHkgKi8KICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVzdWx0IGNhbGxiYWNrIG5vdCBleHBlY3RlZCBpbiIKICAgICAgICAgICAgICAgICAgICJzdGF0ZSAlcywgSWdub3JpbmcuLiIpLAogICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm47Cn0KI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIgCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1Jc1NzaWRBbmRTZWN1cml0eU1hdGNoKAogICAgICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMsIAogICAgICAgIHRDc3JSb2FtQ29ubmVjdGVkUHJvZmlsZSAqcEN1clByb2ZpbGUsCiAgICAgICAgdFNpckJzc0Rlc2NyaXB0aW9uICpwQnNzRGVzYywKICAgICAgICB0RG90MTFmQmVhY29uSUVzICpwSWVzKQp7CiAgICB0Q3NyQXV0aExpc3QgYXV0aFR5cGU7CiAgICB0Q3NyRW5jcnlwdGlvbkxpc3QgdUNFbmNyeXB0aW9uVHlwZTsKICAgIHRDc3JFbmNyeXB0aW9uTGlzdCBtQ0VuY3J5cHRpb25UeXBlOwogICAgdEFOSV9CT09MRUFOIGZNYXRjaCA9IEZBTFNFOwoKICAgIGF1dGhUeXBlLm51bUVudHJpZXMgPSAxOwogICAgYXV0aFR5cGUuYXV0aFR5cGVbMF0gPSBwQ3VyUHJvZmlsZS0+QXV0aFR5cGU7CiAgICB1Q0VuY3J5cHRpb25UeXBlLm51bUVudHJpZXMgPSAxOwogICAgdUNFbmNyeXB0aW9uVHlwZS5lbmNyeXB0aW9uVHlwZVswXSA9IHBDdXJQcm9maWxlLT5FbmNyeXB0aW9uVHlwZTsKICAgIG1DRW5jcnlwdGlvblR5cGUubnVtRW50cmllcyA9IDE7CiAgICBtQ0VuY3J5cHRpb25UeXBlLmVuY3J5cHRpb25UeXBlWzBdID0gcEN1clByb2ZpbGUtPm1jRW5jcnlwdGlvblR5cGU7CgogICAgaWYoIHBJZXMgKQogICAgewogICAgICAgIGlmKHBJZXMtPlNTSUQucHJlc2VudCkKICAgICAgICB7CiAgICAgICAgICAgIGZNYXRjaCA9IGNzcklzU3NpZE1hdGNoKCBwTWFjLAogICAgICAgICAgICAgICAgICAgICh2b2lkICopcEN1clByb2ZpbGUtPlNTSUQuc3NJZCwgcEN1clByb2ZpbGUtPlNTSUQubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgIHBJZXMtPlNTSUQuc3NpZCwgcEllcy0+U1NJRC5udW1fc3NpZCwKICAgICAgICAgICAgICAgICAgICBlQU5JX0JPT0xFQU5fVFJVRSApOwogICAgICAgICAgICBpZihUUlVFID09IGZNYXRjaCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGZvciBub3cgd2UgYXJlIHNlbmRpbmcgTlVMTCBmb3IgYWxsIFBNRiByZWxhdGVkIGZpbHRlcgogICAgICAgICAgICAgICAgICogcGFyYW1ldGVycyBkdXJpbmcgcm9hbSB0byB0aGUgbmVpZ2hib3IgQVAgYmVjYXVzZQogICAgICAgICAgICAgICAgICogc28gZmFyIDgwMjExVyBzcGVjIGRvZXNuJ3Qgc3BlY2lmeSBhbnl0aGluZyBhYm91dAogICAgICAgICAgICAgICAgICogcm9hbWluZyBzY2VuYXJpby4KICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgKiBPbmNlIHJvYW1pbmcgc2NlbmFyaW8gaXMgZGVmaW5lZCwgd2Ugc2hvdWxkIHJlLXZpc2l0CiAgICAgICAgICAgICAgICAgKiB0aGlzIHNlY3Rpb24gYW5kIHJlbW92ZSB0aGlzIGNvbW1lbnQuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGZNYXRjaCA9IGNzcklzU2VjdXJpdHlNYXRjaChwTWFjLCAmYXV0aFR5cGUsICZ1Q0VuY3J5cHRpb25UeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZtQ0VuY3J5cHRpb25UeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEJzc0Rlc2MsIHBJZXMsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgICAgICAgICAgcmV0dXJuIChmTWF0Y2gpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIChmTWF0Y2gpOwogICAgICAgICAgICB9CgogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRkFMU0U7ICAvLyBUcmVhdCBhIG1pc3NpbmcgU1NJRCBhcyBhIG5vbi1tYXRjaC4KICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOyAgLy8gQWdhaW4sIHRyZWF0IG1pc3NpbmcgcEllcyBhcyBhIG5vbi1tYXRjaC4KICAgIH0KfQoKdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUlzTmV3Q29ubmVjdGVkUHJvZmlsZSgKICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRBTklfVTggc2Vzc2lvbklkICAgPSAodEFOSV9VOClwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkOwogICAgdENzclJvYW1Db25uZWN0ZWRQcm9maWxlICpwQ3VyclByb2ZpbGUgPSBOVUxMOwogICAgdENzclJvYW1Db25uZWN0ZWRQcm9maWxlICpwUHJldlByb2ZpbGUgPSBOVUxMOwogICAgdERvdDExZkJlYWNvbklFcyAqcEllcyA9IE5VTEw7CiAgICB0U2lyQnNzRGVzY3JpcHRpb24gKnBCc3NEZXNjID0gTlVMTDsKICAgIHRBTklfQk9PTEVBTiBmTmV3ID0gVFJVRTsKCiAgICBpZighKHBNYWMtPnJvYW0ucm9hbVNlc3Npb24gJiYgQ1NSX0lTX1NFU1NJT05fVkFMSUQocE1hYywgc2Vzc2lvbklkKSkpCiAgICB7CiAgICAgICAgcmV0dXJuIChmTmV3KTsKICAgIH0KCiAgICBwQ3VyclByb2ZpbGUgPSAmcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGU7CiAgICBpZiggIXBDdXJyUHJvZmlsZSApCiAgICB7CiAgICAgICAgcmV0dXJuIChmTmV3KTsKfQoKICAgIHBQcmV2UHJvZmlsZSA9ICZwTmVpZ2hib3JSb2FtSW5mby0+cHJldkNvbm5Qcm9maWxlOwogICAgaWYoICFwUHJldlByb2ZpbGUgKQogICAgewogICAgICAgIHJldHVybiAoZk5ldyk7CiAgICB9CgogICAgcEJzc0Rlc2MgPSBwUHJldlByb2ZpbGUtPnBCc3NEZXNjOwogICAgaWYgKHBCc3NEZXNjKQogICAgewogICAgICAgIGlmIChIQUxfU1RBVFVTX1NVQ0NFU1MoY3NyR2V0UGFyc2VkQnNzRGVzY3JpcHRpb25JRXMocE1hYywKICAgICAgICAgICAgcEJzc0Rlc2MsICZwSWVzKSkgJiYKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtSXNTc2lkQW5kU2VjdXJpdHlNYXRjaChwTWFjLCBwQ3VyclByb2ZpbGUsIHBCc3NEZXNjLCBwSWVzKSkKICAgICAgICB7CiAgICAgICAgICAgIGZOZXcgPSBGQUxTRTsKICAgICAgICB9CiAgICAgICAgaWYgKHBJZXMpCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocEllcyk7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChmTmV3KQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiUHJldiByb2FtIHByb2ZpbGUgZGlkIG5vdCBtYXRjaCBjdXJyZW50IikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiUHJldiByb2FtIHByb2ZpbGUgbWF0Y2hlcyBjdXJyZW50IikpOwogICAgfQoKICAgIHJldHVybiAoZk5ldyk7Cn0KCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1Db25uZWN0ZWRQcm9maWxlTWF0Y2goCiAgICAgICAgdHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICB0Q3NyU2NhblJlc3VsdCAqcFJlc3VsdCwKICAgICAgICB0RG90MTFmQmVhY29uSUVzICpwSWVzKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRBTklfVTggc2Vzc2lvbklkICAgPSAodEFOSV9VOClwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkOwogICAgdENzclJvYW1Db25uZWN0ZWRQcm9maWxlICpwQ3VyUHJvZmlsZSA9IE5VTEw7CiAgICB0U2lyQnNzRGVzY3JpcHRpb24gKnBCc3NEZXNjID0gJnBSZXN1bHQtPlJlc3VsdC5Cc3NEZXNjcmlwdG9yOwoKICAgIGlmKCAhKHBNYWMtPnJvYW0ucm9hbVNlc3Npb24KICAgICAgICAgICAgJiYgQ1NSX0lTX1NFU1NJT05fVkFMSUQocE1hYywgc2Vzc2lvbklkKSkpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHBDdXJQcm9maWxlID0gJnBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlOwoKICAgIGlmKCAhcEN1clByb2ZpbGUpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBjc3JOZWlnaGJvclJvYW1Jc1NzaWRBbmRTZWN1cml0eU1hdGNoKHBNYWMsIHBDdXJQcm9maWxlLCBwQnNzRGVzYywgcEllcyk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1QcmVwYXJlTm9uT2NjdXBpZWRDaGFubmVsTGlzdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIHByZXBhcmUgYSBjaGFubmVsIGxpc3QgdGhhdCBpcyBkZXJpdmVkIGZyb20KICAgICAgICAgICAgdGhlIGxpc3Qgb2YgdmFsaWQgY2hhbm5lbHMgYW5kIGRvZXMgbm90IGluY2x1ZGUgdGhvc2UgaW4gdGhlIG9jY3VwaWVkCiAgICAgICAgICAgIGxpc3QuCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgXHBhcmFtICBwSW5wdXRDaGFubmVsTGlzdCAtIFRoZSBkZWZhdWx0IGNoYW5uZWxzIGxpc3QuCiAgICBccGFyYW0gIG51bU9mQ2hhbm5lbHMgLSBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSBkZWZhdWx0IGNoYW5uZWxzIGxpc3QuCiAgICBccGFyYW0gIHBPdXRwdXRDaGFubmVsTGlzdCAtIFRoZSBwbGFjZSB0byBwdXQgdGhlIG5vbi1vY2N1cGllZCBjaGFubmVsIGxpc3QuCiAgICBccGFyYW0gIHBPdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIG51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgbm9uLW9jY3VwaWVkIGNoYW5uZWwgbGlzdC4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVByZXBhcmVOb25PY2N1cGllZENoYW5uZWxMaXN0KAogICAgICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMsIAogICAgICAgIHRBTklfVTggICAqcElucHV0Q2hhbm5lbExpc3QsIAogICAgICAgIHRBTklfVTggbnVtT2ZDaGFubmVscywKICAgICAgICB0QU5JX1U4ICAgKnBPdXRwdXRDaGFubmVsTGlzdCwKICAgICAgICB0QU5JX1U4ICpwT3V0cHV0TnVtT2ZDaGFubmVscwogICAgICAgICkKewogICAgdEFOSV9VOCBpID0gMDsKICAgIHRBTklfVTggb3V0cHV0TnVtT2ZDaGFubmVscyAgPSAwOyAvLyBDbGVhciB0aGUgb3V0cHV0IG51bWJlciBvZiBjaGFubmVscwogICAgdEFOSV9VOCBudW1PY2N1cGllZENoYW5uZWxzID0gcE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzLm51bUNoYW5uZWxzOwogICAgdEFOSV9VOCAqcE9jY3VwaWVkQ2hhbm5lbExpc3QgPSBwTWFjLT5zY2FuLm9jY3VwaWVkQ2hhbm5lbHMuY2hhbm5lbExpc3Q7CgogICAgZm9yIChpID0gMDsgKGkgPCBudW1PZkNoYW5uZWxzICYmKGkgPCBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU4pKTsgaSsrKQogICAgewogICAgICAgIGlmICghY3NySXNDaGFubmVsUHJlc2VudEluTGlzdChwT2NjdXBpZWRDaGFubmVsTGlzdCwgbnVtT2NjdXBpZWRDaGFubmVscywKICAgICAgICAgICAgIHBJbnB1dENoYW5uZWxMaXN0W2ldKSkKICAgICAgICB7CiAgICAgICAgICAgLyogREZTIGNoYW5uZWwgd2lsbCBiZSBhZGRlZCBpbiB0aGUgbGlzdCBvbmx5IHdoZW4gdGhlCiAgICAgICAgICAgICAgREZTIFJvYW1pbmcgc2NhbiBmbGFnIGlzIGVuYWJsZWQqLwogICAgICAgICAgICBpZiAoQ1NSX0lTX0NIQU5ORUxfREZTKHBJbnB1dENoYW5uZWxMaXN0W2ldKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uYWxsb3dERlNDaGFubmVsUm9hbSA9PSBUUlVFKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHBPdXRwdXRDaGFubmVsTGlzdFtvdXRwdXROdW1PZkNoYW5uZWxzKytdID0gcElucHV0Q2hhbm5lbExpc3RbaV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwT3V0cHV0Q2hhbm5lbExpc3Rbb3V0cHV0TnVtT2ZDaGFubmVscysrXSA9IHBJbnB1dENoYW5uZWxMaXN0W2ldOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHNtc0xvZyhwTWFjLCBMT0cyLCBGTCgiTnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSB2YWxpZCBjaGFubmVsIGxpc3Q9JWQ7ICIKICAgICAgICAgICAiTnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSBub24tb2NjdXBpZWQgbGlzdCBsaXN0PSVkIiksCiAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMsIG91dHB1dE51bU9mQ2hhbm5lbHMpOwoKICAgIC8vIFJldHVybiB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzCiAgICAqcE91dHB1dE51bU9mQ2hhbm5lbHMgPSBvdXRwdXROdW1PZkNoYW5uZWxzOyAKCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQojZW5kaWYgLyogRkVBVFVSRV9XTEFOX0xGUiAqLwoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuZXZlciB0aGVyZSBpcyBhIHRyYW5zaXRpb24gdG8gQ0ZHIGNoYW4gc2NhbiAKICAgICAgICAgICAgc3RhdGUgZnJvbSBhbnkgc3RhdGUuIEl0IGZyZWVzIHVwIHRoZSBjdXJyZW50IGNoYW5uZWwgbGlzdCBhbmQgYWxsb2NhdGVzIAogICAgICAgICAgICBhIG5ldyBtZW1vcnkgZm9yIHRoZSBjaGFubmVscyByZWNlaXZlZCBmcm9tIENGRyBpdGVtLiBJdCB0aGVuIHN0YXJ0cyB0aGUgCiAgICAgICAgICAgIG5laWdoYm9yIHNjYW4gdGltZXIgdG8gcGVyZm9ybSB0aGUgc2NhbiBvbiBlYWNoIGNoYW5uZWwgb25lIGJ5IG9uZQoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzICA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICBpbnQgaSA9IDA7CiAgICB0QU5JX1U4ICAgbnVtT2ZDaGFubmVscyA9IDA7CiAgICB0QU5JX1U4ICAgY2hhbm5lbExpc3RbV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOXTsKICAgIHRwQ3NyQ2hhbm5lbEluZm8gICAgY3VyckNoYW5uZWxMaXN0SW5mbzsKICAgIHRBTklfVTggICBzY2FuQ2hhbm5lbExpc3RbV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOXTsKICAgIGludCAgICAgICBvdXRwdXROdW1PZkNoYW5uZWxzID0gMDsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHRBTklfVTMyIHNlc3Npb25JZCA9IHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQ7CiNlbmRpZgogICAgY3VyckNoYW5uZWxMaXN0SW5mbyA9ICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm87CgogICAgaWYgKCAKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgICAgICAoKHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jKSAmJgogICAgICAgICAgICAgICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9PSBlQU5JX0JPT0xFQU5fRkFMU0UpKSB8fAogICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYyA9PSBlQU5JX0JPT0xFQU5fRkFMU0UpIHx8CiNlbmRpZiAvLyBFU0UKICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5udW1PZkNoYW5uZWxzID09IDApCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJCdWlsZGluZyBjaGFubmVsIGxpc3QgdG8gc2NhbiIpKTsKCgogICAgICAgIC8qIEZyZWUgdXAgdGhlIGNoYW5uZWwgbGlzdCBhbmQgYWxsb2NhdGUgYSBuZXcgbWVtb3J5LiBUaGlzIGlzIGJlY2F1c2Ugd2UgZG9udCBrbm93IGhvdyBtdWNoIAogICAgICAgICAgICB3YXMgYWxsb2NhdGVkIGxhc3QgdGltZS4gSWYgd2UgZGlyZWN0bHkgY29weSBtb3JlIG51bWJlciBvZiBieXRlcyB0aGFuIGFsbG9jYXRlZCBlYXJsaWVyLCB0aGlzIG1pZ2h0IAogICAgICAgICAgICByZXN1bHQgaW4gbWVtb3J5IGNvcnJ1cHRpb24gKi8KICAgICAgICBpZiAoTlVMTCAhPSBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCkKICAgICAgICB7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+bnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICAgfQoKICAgICAgICAvLyBOb3cgb2J0YWluIHRoZSBjb250ZW50cyBmb3IgImNoYW5uZWxMaXN0IiAodGhlICJkZWZhdWx0IHZhbGlkIGNoYW5uZWwgbGlzdCIpIGZyb20gRUlUSEVSCiAgICAgICAgLy8gdGhlIGdOZWlnaGJvclNjYW5DaGFubmVsTGlzdCBpbiAiY2ZnLmluaSIsIE9SIHRoZSBhY3R1YWwgInZhbGlkIGNoYW5uZWwgbGlzdCIgaW5mb3JtYXRpb24gZm9ybWVkIGJ5IENTUi4KICAgICAgICBpZiAoMCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICAgICAgewogICAgICAgICAgICAvLyBDb3B5IHRoZSAiZGVmYXVsdCB2YWxpZCBjaGFubmVsIGxpc3QiIChjaGFubmVsTGlzdCkgZnJvbSB0aGUgZ05laWdoYm9yU2NhbkNoYW5uZWxMaXN0IGluICJjZmcuaW5pIi4KICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCAiVXNpbmcgdGhlIGNoYW5uZWwgbGlzdCBmcm9tIGNmZy5pbmkiKTsKICAgICAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtTWVyZ2VDaGFubmVsTGlzdHMoIAogICAgICAgICAgICAgICAgICAgIHBNYWMsIAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QsIAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscywgCiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsIAogICAgICAgICAgICAgICAgICAgIDAsIC8vTkI6IElmIDAsIHNpbXBseSBjb3B5IHRoZSBpbnB1dCBjaGFubmVsIGxpc3QgdG8gdGhlIG91dHB1dCBsaXN0LgogICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzICk7CgogICAgICAgICAgICBpZiAoQ1NSX0lTX1JPQU1fSU5UUkFfQkFORF9FTkFCTEVEKHBNYWMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1DaGFubmVsc0ZpbHRlckJ5QmFuZCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5udW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFJGQmFuZChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY3VyckFQb3BlcmF0aW9uQ2hhbm5lbCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKG51bU9mQ2hhbm5lbHMgPiBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU4pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgd3JvbmcgbnVtYmVyIG9mIENoYW5uZWwgbGlzdCIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogUmVtb3ZlIHRoZSBERlMgY2hhbm5lbHMgZnJvbSBDRkcgY2hhbm5lbCBsaXN0IHdoZW4gJwogICAgICAgICAgICAgICAgICAgICAgICBnQWxsb3dSb2FtVG9ERlMgaXMgZGlzYWJsZWQgKi8KICAgICAgICAgICAgaWYgKCBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmFsbG93REZTQ2hhbm5lbFJvYW0gPT0gRkFMU0UpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaT0wOyBpPG51bU9mQ2hhbm5lbHM7IGkrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoICEoQ1NSX0lTX0NIQU5ORUxfREZTKGNoYW5uZWxMaXN0W2ldKSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgc2NhbkNoYW5uZWxMaXN0W291dHB1dE51bU9mQ2hhbm5lbHMrK10gPSBjaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7ICAgLyogTW92ZSBhbGwgdGhlIGNoYW5uZWxzIHRvIHJvYW0gc2NhbiBjaGFubmVsIGxpc3QgKi8KICAgICAgICAgICAgICAgIHZvc19tZW1fY29weShzY2FuQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgICAgICAgICBvdXRwdXROdW1PZkNoYW5uZWxzID0gbnVtT2ZDaGFubmVsczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG91dHB1dE51bU9mQ2hhbm5lbHMgPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJObyBjaGFubmVscyB0byBzY2FuIikpOwogICAgICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0ID0KICAgICAgICAgICAgICAgIHZvc19tZW1fbWFsbG9jKG91dHB1dE51bU9mQ2hhbm5lbHMqc2l6ZW9mKHRBTklfVTgpKTsKICAgICAgICAgICAgaWYgKE5VTEwgPT0gY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZm9yIENoYW5uZWwgbGlzdCBmYWlsZWQiKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX1JFU09VUkNFUzsKICAgICAgICAgICAgfQogICAgICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5udW1PZkNoYW5uZWxzID0gb3V0cHV0TnVtT2ZDaGFubmVsczsKICAgICAgICAgICAgdm9zX21lbV9jb3B5KGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICBzY2FuQ2hhbm5lbExpc3QsIG91dHB1dE51bU9mQ2hhbm5lbHMgKiBzaXplb2YodEFOSV9VOCkpOwogICAgICAgIH0gCgoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICBlbHNlIGlmICgocE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSA9PSBERUZBVUxUX1NDQU4pICYmCiAgICAgICAgICAgICAgICAgKGFicyhwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kpID4KICAgICAgICAgICAgICAgICAgYWJzKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkKSkpCiAgICAgICAgewogICAgICAgICAgICAvKiAKICAgICAgICAgICAgICogVHJpZ2dlciBhIGNvbnRpZ3VvdXMgc2NhbiBvbiBhbGwgY2hhbm5lbHMgd2hlbiB0aGUKICAgICAgICAgICAgICogUlNTSSBpbiB0aGUgbG9va3VwIERPV04gbm90aWZpY2F0aW9uIGlzIGJlbG93IHJlYXNzb2MgCiAgICAgICAgICAgICAqIHRocmVzaG9sZC4gVGhpcyB3aWxsIGhlbHAgdXMgZmluZCB0aGUgYmVzdCBhdmFpbGFibGUgCiAgICAgICAgICAgICAqIGNhbmRpZGF0ZSBhbmQgYWxzbyB1cGRhdGUgdGhlIGNoYW5uZWwgY2FjaGUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICJUcmlnZ2VyaW5nIGNvbnRpZ3VvdXMgc2NhbiAiCiAgICAgICAgICAgICAgICAiKGxvb2t1cERPV05Sc3NpPSVkLHJlYXNzb2NUaHJlc2hvbGQ9JWQpIiwKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSwKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkKigtMSkpOwoKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5SZXF1ZXN0VGltZVN0YW1wID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9zX3RpbWVyX2dldF9zeXN0ZW1fdGltZSgpOwoKICAgICAgICAgICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CgogICAgICAgICAgICAvKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlLCAKICAgICAgICAgICAgICogcHVyZ2Ugbm9uLVAyUCByZXN1bHRzIGZyb20gdGhlIHBhc3QgKi8KICAgICAgICAgICAgY3NyU2NhbkZsdXNoU2VsZWN0aXZlUmVzdWx0KHBNYWMsIFZPU19GQUxTRSk7CgogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1QZXJmb3JtQ29udGlndW91c0JnU2NhbihwTWFjLCBzZXNzaW9uSWQpOwoKICAgICAgICAgICAgLyogVHJhbnNpdGlvbiB0byBDRkdfQ0hBTl9MSVNUX1NDQU4gKi8KICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOKTsKCiAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfQojZW5kaWYKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBudW1PZkNoYW5uZWxzID0gcE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzLm51bUNoYW5uZWxzOwogICAgICAgICAgICBpZiAobnVtT2ZDaGFubmVscyA+IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyA9IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobnVtT2ZDaGFubmVscwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAgICAgJiYgKChwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID09IFNQTElUX1NDQU5fT0NDVVBJRURfTElTVCkgfHwKICAgICAgICAgICAgICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSAwKSB8fAogICAgICAgICAgICAgICAgICAgICgocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCAlIDIpID09IDEpKQojZW5kaWYKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIEFsd2F5cyBzY2FuIGNoYW5uZWxzIGluIHRoZSBvY2N1cGllZCBjaGFubmVsIGxpc3QKICAgICAgICAgICAgICAgICAqIGJlZm9yZSBzY2FubmluZyBvbiB0aGUgbm9uLW9jY3VwaWVkIGxpc3QuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIlN3aXRjaGluZyB0byBvY2N1cGllZCBjaGFubmVsIGxpc3QiCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICAgICAgIi11U2Nhbk1vZGU9JWQsIHVFbXB0eVNjYW5Db3VudD0lZCIsCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50CiNlbmRpZgogICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBpZiAoQ1NSX0lTX1JPQU1fSU5UUkFfQkFORF9FTkFCTEVEKHBNYWMpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUNoYW5uZWxzRmlsdGVyQnlCYW5kKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5zY2FuLm9jY3VwaWVkQ2hhbm5lbHMuY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0UkZCYW5kKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jdXJyQVBvcGVyYXRpb25DaGFubmVsKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9jb3B5KGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzLmNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiBSZW1vdmUgdGhlIERGUyBjaGFubmVscyBmcm9tIENGRyBjaGFubmVsIGxpc3Qgd2hlbiAnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdBbGxvd1JvYW1Ub0RGUyBpcyBkaXNhYmxlZCAqLwogICAgICAgICAgICAgICAgaWYgKCBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmFsbG93REZTQ2hhbm5lbFJvYW0gPT0gRkFMU0UpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICBmb3IgKGk9MDsgaTxudW1PZkNoYW5uZWxzOyBpKyspCiAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAhKENTUl9JU19DSEFOTkVMX0RGUyhjaGFubmVsTGlzdFtpXSkpKQogICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5DaGFubmVsTGlzdFtvdXRwdXROdW1PZkNoYW5uZWxzKytdID0gY2hhbm5lbExpc3RbaV07CiAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fY29weShzY2FuQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgKiBzaXplb2YodEFOSV9VOCkpOwogICAgICAgICAgICAgICAgICAgIG91dHB1dE51bU9mQ2hhbm5lbHMgPSBudW1PZkNoYW5uZWxzOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChvdXRwdXROdW1PZkNoYW5uZWxzID09IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJObyBjaGFubmVscyB0byBzY2FuIikpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0ID0gdm9zX21lbV9tYWxsb2Mob3V0cHV0TnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgICAgICAgICBpZiAoTlVMTCA9PSBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZvciBDaGFubmVsIGxpc3QgZmFpbGVkIikpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfUkVTT1VSQ0VTOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+bnVtT2ZDaGFubmVscyA9IG91dHB1dE51bU9mQ2hhbm5lbHM7CiAgICAgICAgICAgICAgICB2b3NfbWVtX2NvcHkoY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0TnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBTY2FuIGFsbCBjaGFubmVscyBmcm9tIG5vbi1vY2N1cGllZCBsaXN0ICovCiAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsICJHZXQgdmFsaWQgY2hhbm5lbCBsaXN0Iik7CiAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzID0gc2l6ZW9mKHBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCk7CgogICAgICAgICAgICAgICAgaWYoSEFMX1NUQVRVU19TVUNDRVNTKGNzckdldENmZ1ZhbGlkQ2hhbm5lbHMocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VOCAqKXBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VMzIgKikgJm51bU9mQ2hhbm5lbHMpKSkKICAgICAgICAgICAgewojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFByZXBhcmUgbm9uLW9jY3VwaWVkIGNoYW5uZWwgbGlzdCAoY2hhbm5lbExpc3QpCiAgICAgICAgICAgICAgICAgKiBmcm9tIHRoZSBhY3R1YWwgInZhbGlkIGNoYW5uZWwgbGlzdCIgaW5mb3JtYXRpb24KICAgICAgICAgICAgICAgICAqIGZvcm1lZCBieSBDU1IuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgIlN3aXRjaGluZyB0byBub24tb2NjdXBpZWQgY2hhbm5lbCBsaXN0Iik7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1QcmVwYXJlTm9uT2NjdXBpZWRDaGFubmVsTGlzdChwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbnVtT2ZDaGFubmVscyk7CiNlbHNlCiAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsICJNZXJnaW5nIGNoYW5uZWwgbGlzdCIpOwogICAgICAgICAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtTWVyZ2VDaGFubmVsTGlzdHMoIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0QU5JX1U4ICopcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscywgICAvLyBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSB2YWxpZENoYW5uZWxMaXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8vTkI6IElmIDAsIHNpbXBseSBjb3B5IHRoZSBpbnB1dCBjaGFubmVsIGxpc3QgdG8gdGhlIG91dHB1dCBsaXN0LgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJm51bU9mQ2hhbm5lbHMgKTsgLy8gVGhlIGZpbmFsIG51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgb3V0cHV0IGxpc3QuIFdpbGwgYmUgbnVtT2ZDaGFubmVscwojZW5kaWYKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQ291bGQgbm90IGdldCB2YWxpZCBjaGFubmVsIGxpc3QiKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChDU1JfSVNfUk9BTV9JTlRSQV9CQU5EX0VOQUJMRUQocE1hYykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1DaGFubmVsc0ZpbHRlckJ5QmFuZCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0QU5JX1U4ICopcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRSRkJhbmQocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmN1cnJBUG9wZXJhdGlvbkNoYW5uZWwpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG51bU9mQ2hhbm5lbHMgPiBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU4pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgPSBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChudW1PZkNoYW5uZWxzID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTm8gY2hhbm5lbHMgdG8gc2NhbiIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCA9CiAgICAgICAgICAgICAgICB2b3NfbWVtX21hbGxvYyhudW1PZkNoYW5uZWxzKnNpemVvZih0QU5JX1U4KSk7CgogICAgICAgICAgICBpZiAoTlVMTCA9PSBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgQ2hhbm5lbCBsaXN0IGZhaWxlZCIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfUkVTT1VSQ0VTOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMgPSBudW1PZkNoYW5uZWxzOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICB2b3NfbWVtX2NvcHkoY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsIG51bU9mQ2hhbm5lbHMgKiBzaXplb2YodEFOSV9VOCkpOwojZWxzZQogICAgICAgICAgICB2b3NfbWVtX2NvcHkoY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiNlbmRpZgogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIAogICAgICAgICAgICAiTnVtYmVyIG9mIGNoYW5uZWxzIGZyb20gQ0ZHIChvcikgKG5vbi0pb2NjdXBpZWQgbGlzdD0lZCIsCiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBjdXJyQ2hhbm5lbExpc3RJbmZvLT5udW1PZkNoYW5uZWxzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICJDaGFubmVsIExpc3QgZnJvbSBDRkcgKG9yKSAobm9uLSlvY2N1cGllZCBsaXN0IgogICAgICAgICAgICAgICAgICAgICI9ICVkIiwgY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3RbaV0pOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBXZSBhcmUgZ29ubmEgc2NhbiBub3cuIFJlbWVtYmVyIHRoZSB0aW1lIHN0YW1wIHRvIGZpbHRlciBvdXQgcmVzdWx0cyBvbmx5IGFmdGVyIHRoaXMgdGltZXN0YW1wICovCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJlcXVlc3RUaW1lU3RhbXAgPSB2b3NfdGltZXJfZ2V0X3N5c3RlbV90aW1lKCk7CiAgICAKICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgLyogU3RhcnQgTmVpZ2hib3Igc2NhbiB0aW1lciBub3cuIE11bHRpcGxpY2F0aW9uIGJ5IFBBTF9USU1FUl9UT19NU19VTklUIGlzIHRvIGNvbnZlcnQgbXMgdG8gdXMgd2hpY2ggaXMgCiAgICAgICAgICAgIHdoYXQgcGFsVGltZXJTdGFydCBleHBlY3RzICovCiAgICBzdGF0dXMgPSB2b3NfdGltZXJfc3RhcnQoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lciwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yU2NhblBlcmlvZCk7CiAgICAKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICAvKiBUaW1lciBzdGFydCBmYWlsZWQuLiAgKi8KICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHNjYW4gUEFMIFRpbWVyIHN0YXJ0IGZhaWxlZCwgc3RhdHVzID0gJWQsIElnbm9yaW5nIHN0YXRlIHRyYW5zaXRpb24iKSwgc3RhdHVzKTsKICAgICAgICB2b3NfbWVtX2ZyZWUoY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QpOwogICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICB9CiAgICAKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgIC8qIFdlIGFyZSBhYm91dCB0byBzdGFydCBhIGZyZXNoIHNjYW4gY3ljbGUsIAogICAgICogcHVyZ2Ugbm9uLVAyUCByZXN1bHRzIGZyb20gdGhlIHBhc3QgKi8KICAgIGNzclNjYW5GbHVzaFNlbGVjdGl2ZVJlc3VsdChwTWFjLCBWT1NfRkFMU0UpOwoKICAgIC8qIFdlIGFyZSBhYm91dCB0byBzdGFydCBhIGZyZXNoIHNjYW4gY3ljbGUsCiAgICAgKiBwdXJnZSBmYWlsZWQgcHJlLWF1dGggcmVzdWx0cyBmcm9tIHRoZSBwYXN0ICovCiAgICBjc3JOZWlnaGJvclJvYW1QdXJnZVByZWF1dGhGYWlsZWRMaXN0KHBNYWMpOwogICAgCiAgICAvKiBUcmFuc2l0aW9uIHRvIENGR19DSEFOX0xJU1RfU0NBTl9TVEFURSAqLwogICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOKQoKICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVwRXZlbnQKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFzIHNvb24gYXMgVEwgaW5kaWNhdGVzIHRoYXQgdGhlIGN1cnJlbnQgQVAncyAKICAgICAgICAgICAgUlNTSSBpcyBiZXR0ZXIgdGhhbiB0aGUgbmVpZ2hib3IgbG9va3VwIHRocmVzaG9sZC4gSGVyZSwgd2UgdHJhbnNpdGlvbiB0byAKICAgICAgICAgICAgQ09OTkVDVEVEIHN0YXRlIGFuZCByZXNldCBhbGwgdGhlIHNjYW4gcGFyYW1ldGVycwoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVwRXZlbnQodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXM7CiAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwoKICAgIC8qIFJlY2hlY2sgd2hldGhlciB0aGUgYmVsb3cgY2hlY2sgaXMgbmVlZGVkLiAqLwogICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUgIT0gZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCkKICAgICAgICAmJiAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlICE9IGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRUFTU09DSUFUSU5HKSkKICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQpCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBpZiAoIWNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jc3JTZXNzaW9uSWQpKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgd2hlbiBmYXN0IHJvYW0gaXMgZGlzYWJsZWQuIElnbm9yZSBpdCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KI2VuZGlmCiAgICAvKiBSZXNldCBhbGwgdGhlIG5laWdoYm9yIHJvYW0gaW5mbyBjb250cm9sIHZhcmlhYmxlcy4gRnJlZSBhbGwgdGhlIGFsbG9jYXRlZCBtZW1vcnkuIEl0IGlzIGxpa2Ugd2UgYXJlIGp1c3QgYXNzb2NpYXRlZCBub3cgKi8KICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKCiAgICAKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIERPV04gZXZlbnQgbmVpZ2hib3IgbG9va3VwIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCwiKSwgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSkpOwogICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBET1dOIGV2ZW50IG5vdyAqLwogICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwojZW5kaWYKICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgIHsKICAgICAgIC8vZXJyIG1zZwogICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBDYWxsYmFjayBET1dOIGV2ZW50IHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICB9CgoKICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERvd25FdmVudAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYXMgc29vbiBhcyBUTCBpbmRpY2F0ZXMgdGhhdCB0aGUgY3VycmVudCBBUCdzIAogICAgICAgICAgICBSU1NJIGZhbGxzIGJlbG93IHRoZSBjdXJyZW50IGVpZ2hib3IgbG9va3VwIHRocmVzaG9sZC4gSGVyZSwgd2UgdHJhbnNpdGlvbiB0byAKICAgICAgICAgICAgUkVQT1JUX1FVRVJZIGZvciAxMXIgYXNzb2NpYXRpb24gYW5kIENGR19DSEFOX0xJU1RfU0NBTiBzdGF0ZSBpZiB0aGUgYXNzb2MgaXMgCiAgICAgICAgICAgIGEgbm9uLTExUiBhc3NvY2lhdGlvbi4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBEb3duRXZlbnQodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICBlSGFsU3RhdHVzICBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwoKICAgIHN3aXRjaCAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRDoKICAgICAgICAgICAgCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkRlcmVnaXN0ZXJpbmcgRE9XTiBldmVudCBuZWlnaGJvciBsb29rdXAgY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSk7CiAgICAgICAgICAgIC8qIERlLXJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCAqLwogICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCBEZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwQ2FsbGJhY2sgRE9XTiBldmVudCBmcm9tIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICB9CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgIGlmICghY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMscE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNzclNlc3Npb25JZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgd2hlbiBmYXN0IHJvYW0gaXMgZGlzYWJsZWQuIElnbm9yZSBpdCIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgIAojaWYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAmJiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRkkKICAgICAgICAgICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykgJiYgKHBNYWMtPnJybS5ycm1TbWVDb250ZXh0LnJybUNvbmZpZy5ycm1FbmFibGVkKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIjExUiBBc3NvY2lhdGlvbjpOZWlnaGJvciBMb29rdXAgRG93biBldmVudCByZWNlaXZlZCBpbiBDT05ORUNURUQgc3RhdGUiKSk7CiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZU5laWdoYm9yUnB0UmVxdWVzdChwTWFjKTsKICAgICAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVwb3J0IHJlcXVlc3QgZmFpbGVkLiBzdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB2b3NTdGF0dXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiBJbmNyZW1lbnQgdGhlIG5laWdoYm9yIHJlcG9ydCByZXRyeSBjb3VudCBhZnRlciBzZW5kaW5nIHRoZSBuZWlnaGJvciByZXF1ZXN0IHN1Y2Nlc3NmdWxseSAqLwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0rKzsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1FVRVJZKQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKI2VuZGlmICAgICAgCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIk5vbiAxMVIgb3IgRVNFIEFzc29jaWF0aW9uOk5laWdoYm9yIExvb2t1cCBEb3duIGV2ZW50IHJlY2VpdmVkIGluIENPTk5FQ1RFRCBzdGF0ZSIpKTsKCiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1UcmFuc2l0VG9DRkdDaGFuU2NhbihwTWFjKTsKICAgICAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoImNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuIGZhaWxlZCIKICAgICAgICAgICAgICAgICAgICAgICAgIiB3aXRoIHN0YXR1cz0lZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB2b3NTdGF0dXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmVnaXN0ZXJpbmcgVVAgZXZlbnQgbmVpZ2hib3IgbG9va3VwIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCwiKSwgTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSk7CiAgICAgICAgICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCBmb3IgVVAgZXZlbnQgbm93ICovCiAgICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjaywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwQ2FsbGJhY2sgVVAgZXZlbnQgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgc3RhdHVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkRPV04gZXZlbnQgcmVjZWl2ZWQgaW4gaW52YWxpZCIKICAgICAgICAgICAgICAgICAgICJzdGF0ZSAlcyAuLklnbm9yaW5nLi4uIiksCiAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgCiAgICB9CiAgICByZXR1cm4gdm9zU3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHJlZ2lzdGVyZWQgd2l0aCBUTCB0byBpbmRpY2F0ZSB3aGVuZXZlciB0aGUgUlNTSSAKICAgICAgICAgICAgZ2V0cyBiZXR0ZXIgdGhhbiB0aGUgbmVpZ2hib3JMb29rdXAgUlNTSSBUaHJlc2hvbGQKCiAgICBccGFyYW0gIHBBZGFwdGVyIC0gVk9TIENvbnRleHQKICAgICAgICAgICAgdHJhZmZpY1N0YXR1cyAtIFVQL0RPV04gaW5kaWNhdGlvbiBmcm9tIFRMCiAgICAgICAgICAgIHBVc2VyQ3R4dCAtIFBhcmFtZXRlciBmb3IgY2FsbGJhY2sgcmVnaXN0ZXJlZCBkdXJpbmcgY2FsbGJhY2sgcmVnaXN0cmF0aW9uLiBTaG91bGQgYmUgcE1hYwoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrICh2X1BWT0lEX3QgcEFkYXB0ZXIsIHZfVThfdCByc3NpTm90aWZpY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9QVk9JRF90IHBVc2VyQ3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUzdfdCBhdmdSc3NpKQp7CiAgICB0cEFuaVNpckdsb2JhbCBwTWFjID0gUE1BQ19TVFJVQ1QoIHBVc2VyQ3R4dCApOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgRkwoIk5laWdoYm9yIExvb2t1cCBVUCBpbmRpY2F0aW9uIGNhbGxiYWNrIGNhbGxlZCB3aXRoIG5vdGlmaWNhdGlvbiAlZCBSZXBvcnRlZCBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnNzaU5vdGlmaWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZnUnNzaSk7CgogICAgaWYoIWNzcklzQ29ublN0YXRlQ29ubmVjdGVkSW5mcmEocE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCkpCiAgICB7CiAgICAgICBzbXNMb2cocE1hYywgTE9HVywgIklnbm9yaW5nIHRoZSBpbmRpY2F0aW9uIGFzIHdlIGFyZSBub3QgY29ubmVjdGVkIik7CiAgICAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIFZPU19BU1NFUlQoV0xBTlRMX0hPX1RIUkVTSE9MRF9VUCA9PSByc3NpTm90aWZpY2F0aW9uKTsKICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVXBFdmVudChwTWFjKTsKICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjawoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyByZWdpc3RlcmVkIHdpdGggVEwgdG8gaW5kaWNhdGUgd2hlbmV2ZXIgdGhlIFJTU0kgCiAgICAgICAgICAgIGZhbGxzIGJlbG93IHRoZSBjdXJyZW50IG5laWdoYm9yTG9va3VwIFJTU0kgVGhyZXNob2xkCgogICAgXHBhcmFtICBwQWRhcHRlciAtIFZPUyBDb250ZXh0CiAgICAgICAgICAgIHRyYWZmaWNTdGF0dXMgLSBVUC9ET1dOIGluZGljYXRpb24gZnJvbSBUTAogICAgICAgICAgICBwVXNlckN0eHQgLSBQYXJhbWV0ZXIgZm9yIGNhbGxiYWNrIHJlZ2lzdGVyZWQgZHVyaW5nIGNhbGxiYWNrIHJlZ2lzdHJhdGlvbi4gU2hvdWxkIGJlIHBNYWMKCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrICh2X1BWT0lEX3QgcEFkYXB0ZXIsIHZfVThfdCByc3NpTm90aWZpY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9QVk9JRF90IHBVc2VyQ3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUzdfdCBhdmdSc3NpKQp7CiAgICB0cEFuaVNpckdsb2JhbCBwTWFjID0gUE1BQ19TVFJVQ1QoIHBVc2VyQ3R4dCApOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgRkwoIk5laWdoYm9yIExvb2t1cCBET1dOIGluZGljYXRpb24gY2FsbGJhY2sgY2FsbGVkIHdpdGggbm90aWZpY2F0aW9uICVkIFJlcG9ydGVkIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnNzaU5vdGlmaWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2Z1Jzc2kpOwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSA9IGF2Z1Jzc2k7CiNlbmRpZgogICAgaWYoIWNzcklzQ29ublN0YXRlQ29ubmVjdGVkSW5mcmEocE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCkpCiAgICB7CiAgICAgICBzbXNMb2cocE1hYywgTE9HVywgIklnbm9yaW5nIHRoZSBpbmRpY2F0aW9uIGFzIHdlIGFyZSBub3QgY29ubmVjdGVkIik7CiAgICAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIFZPU19BU1NFUlQoV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOID09IHJzc2lOb3RpZmljYXRpb24pOwogICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBEb3duRXZlbnQocE1hYyk7CgogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKI2lmZGVmIFJTU0lfSEFDSwpleHRlcm4gaW50IGR1bXBDbWRSU1NJOwojZW5kaWYKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1JbmRpY2F0ZURpc2Nvbm5lY3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IENTUiBhcyBzb29uIGFzIHRoZSBzdGF0aW9uIGRpc2Nvbm5lY3RzIGZyb20gCiAgICAgICAgICAgIHRoZSBBUC4gVGhpcyBmdW5jdGlvbiBkb2VzIHRoZSBuZWNlc3NhcnkgY2xlYW51cCBvZiBuZWlnaGJvciByb2FtIGRhdGEgCiAgICAgICAgICAgIHN0cnVjdHVyZXMuIE5laWdoYm9yIHJvYW0gc3RhdGUgdHJhbnNpdGlvbnMgdG8gSU5JVCBzdGF0ZSB3aGVuZXZlciB0aGlzIAogICAgICAgICAgICBmdW5jdGlvbiBpcyBjYWxsZWQgZXhjZXB0IGlmIHRoZSBjdXJyZW50IHN0YXRlIGlzIFJFQVNTT0NJQVRJTkcKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHNlc3Npb25JZCAtIENTUiBzZXNzaW9uIGlkIHRoYXQgZ290IGRpc2Nvbm5lY3RlZAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUluZGljYXRlRGlzY29ubmVjdCh0cEFuaVNpckdsb2JhbCBwTWFjLCB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICB0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUgKnBQcmV2UHJvZmlsZSA9ICZwTmVpZ2hib3JSb2FtSW5mby0+cHJldkNvbm5Qcm9maWxlOwojZW5kaWYKICAgIHRDc3JSb2FtU2Vzc2lvbiAqcFNlc3Npb24gPSBDU1JfR0VUX1NFU1NJT04oIHBNYWMsIHNlc3Npb25JZCk7CgogICAgaWYgKE5VTEwgPT0gcFNlc3Npb24pCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJwU2Vzc2lvbiBpcyBOVUxMICIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIFZPU19UUkFDRShWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICBGTCgiRGlzY29ubmVjdCBpbmRpY2F0aW9uIG9uIHNlc3Npb24gJWQgaW4gc3RhdGUgJXMiCiAgICAgICAgICAgICAgICAgICAgICAiZnJvbSBCU1NJRCA6ICIKICAgICAgICAgICAgICAgICAgIE1BQ19BRERSRVNTX1NUUiksIHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSwKICAgICAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKHBTZXNzaW9uLT5jb25uZWN0ZWRQcm9maWxlLmJzc2lkKSk7CiAKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIC8qRnJlZSB0aGUgY3VycmVudCBwcmV2aW91cyBwcm9maWxlIGFuZCBtb3ZlIHRoZSBjdXJyZW50IHByb2ZpbGUgdG8gcHJldiBwcm9maWxlLiovCiAgICBjc3JSb2FtRnJlZUNvbm5lY3RQcm9maWxlKHBNYWMsIHBQcmV2UHJvZmlsZSk7CiAgICBjc3JSb2FtQ29weUNvbm5lY3RQcm9maWxlKHBNYWMsIHNlc3Npb25JZCwgcFByZXZQcm9maWxlKTsKI2VuZGlmCiAgICBpZiAoTlVMTCAhPSBwU2Vzc2lvbikKICAgIHsKICAgICAgICBpZiAoTlVMTCAhPSBwU2Vzc2lvbi0+cEN1clJvYW1Qcm9maWxlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKFZPU19TVEFfTU9ERSAhPSBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0ucEN1clJvYW1Qcm9maWxlLT5jc3JQZXJzb25hKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIklnbm9yaW5nIERpc2Nvbm5lY3QgaW5kaWNhdGlvbiByZWNlaXZlZCBmcm9tIGEgbm9uIFNUQSBwZXJzb25hLiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2Vzc2lvbklkOiAlZCwgY3NyUGVyc29ubmEgJWQiKSwgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgIChpbnQpcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLnBDdXJSb2FtUHJvZmlsZS0+Y3NyUGVyc29uYSk7CiAgICAgICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCiAgICAgICAgaWYgKHBTZXNzaW9uLT5jb25uZWN0ZWRQcm9maWxlLmlzRVNFQXNzb2MpCiAgICAgICAgewogICAgICAgICAgIHZvc19tZW1fY29weSgmcFNlc3Npb24tPnByZXZBcFNTSUQsICZwU2Vzc2lvbi0+Y29ubmVjdGVkUHJvZmlsZS5TU0lELAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY1NTaWQpKTsKICAgICAgICAgICB2b3NfbWVtX2NvcHkocFNlc3Npb24tPnByZXZBcEJzc2lkLCBwU2Vzc2lvbi0+Y29ubmVjdGVkUHJvZmlsZS5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICAgICAgICAgcFNlc3Npb24tPnByZXZPcENoYW5uZWwgPSBwU2Vzc2lvbi0+Y29ubmVjdGVkUHJvZmlsZS5vcGVyYXRpb25DaGFubmVsOwogICAgICAgICAgIHBTZXNzaW9uLT5pc1ByZXZBcEluZm9WYWxpZCA9IFRSVUU7CiAgICAgICAgICAgcFNlc3Npb24tPnJvYW1UUzEgPSB2b3NfdGltZXJfZ2V0X3N5c3RlbV90aW1lKCk7CiAgICAgICAgfQojZW5kaWYKICAgIH0gLy9pZiAoTlVMTCAhPSBwU2Vzc2lvbikKICAgCiNpZmRlZiBSU1NJX0hBQ0sKICAgIGR1bXBDbWRSU1NJID0gLTQwOwojZW5kaWYKICAgIHN3aXRjaCAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFQVNTT0NJQVRJTkc6CiAgICAgICAgICAgIC8vIFN0b3Agc2NhbiBhbmQgbmVpZ2hib3IgcmVmcmVzaCB0aW1lcnMuCiAgICAgICAgICAgIC8vIFRoZXNlIGFyZSBpbmRlZWQgbm90IHJlcXVpcmVkIHdoZW4gd2UgYXJlIGluIHJlYXNzb2NpYXRpbmcKICAgICAgICAgICAgLy8gc3RhdGUuCiAgICAgICAgICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICAgICAgICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAgICAgICAgaWYgKCFDU1JfSVNfUk9BTV9TVUJTVEFURV9ESVNBU1NPQ19ITyggcE1hYywgc2Vzc2lvbklkICkpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBEaXNjb25uZWN0IGluZGljYXRpb24gZHVyaW5nIERpc2Fzc29jIEhhbmRvZmYgc3ViLXN0YXRlCiAgICAgICAgICAgICAgICAgKiBpcyByZWNlaXZlZCB3aGVuIHdlIGFyZSB0cnlpbmcgdG8gZGlzY29ubmVjdCB3aXRoIHRoZSBvbGQKICAgICAgICAgICAgICAgICAqIEFQIGR1cmluZyByb2FtLiBCVVQsIGlmIHJlY2VpdmUgYSBkaXNjb25uZWN0IGluZGljYXRpb24gCiAgICAgICAgICAgICAgICAgKiBvdXRzaWRlIG9mIERpc2Fzc29jIEhhbmRvZmYgc3ViLXN0YXRlLCB0aGVuIGl0IG1lYW5zIHRoYXQgCiAgICAgICAgICAgICAgICAgKiB0aGlzIGlzIGEgZ2VudWluZSBkaXNjb25uZWN0IGFuZCB3ZSBuZWVkIHRvIGNsZWFuIHVwLgogICAgICAgICAgICAgICAgICogT3RoZXJ3aXNlLCB3ZSB3aWxsIGJlIHN0dWNrIGluIHJlYXNzb2Mgc3RhdGUgd2hpY2ggd2lsbAogICAgICAgICAgICAgICAgICogaW4tdHVybiBibG9jayBzY2FucyAoc2VlIGNzcklzU2NhbkFsbG93ZWQpLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKTsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiNlbmRpZgoKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVDoKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRJbml0U3RhdGVDb250cm9sSW5mbyhwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBicmVhazsgCgogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRDoKICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCkKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgoKI2lmZGVmIFdMQU5fRkVBVFVSRV9MRlJfTUJCCiAgICAgICAgICAgIGNzcl9zdG9wX3ByZWF1dGhfcmVhc3NvY19tYmJfdGltZXIocE1hYyk7CiNlbmRpZgogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOOgogICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKTsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q2ZnTGlzdENoYW5TY2FuQ29udHJvbEluZm8ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgICAgICAgICBpZiAoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSF9ET05FOgogICAgICAgICAgICAvKiBTdG9wIHByZS1hdXRoIHRvIHJlYXNzb2MgaW50ZXJ2YWwgdGltZXIgKi8KICAgICAgICAgICAgdm9zX3RpbWVyX3N0b3AoJnBNYWMtPmZ0LmZ0U21lQ29udGV4dC5wcmVBdXRoUmVhc3NvY0ludHZsVGltZXIpOwogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOOgogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhFTlRJQ0FUSU5HOgogICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKQogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRQcmVhdXRoQ29udHJvbEluZm8ocE1hYyk7CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0UmVwb3J0U2NhblN0YXRlQ29udHJvbEluZm8ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgICAgICB7CiNlbmRpZgogICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgRkwoIlJlY2VpdmVkIGRpc2Nvbm5lY3QgZXZlbnQiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImluIHN0YXRlICVzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgRkwoIlRyYW5zaXRpb25pbmcgdG8gSU5JVCBzdGF0ZSIpKTsKICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCkKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwojZW5kaWYKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIC8qSW5mb3JtIHRoZSBGaXJtd2FyZSB0byBTVE9QIFNjYW5uaW5nIGFzIHRoZSBob3N0IGhhcyBhIGRpc2Nvbm5lY3QuKi8KICAgIGlmIChjc3JSb2FtSXNTdGFNb2RlKHBNYWMsIHNlc3Npb25JZCkpCiAgICB7CiAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RPUCwgUkVBU09OX0RJU0NPTk5FQ1RFRCk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1JbmRpY2F0ZUNvbm5lY3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IENTUiBhcyBzb29uIGFzIHRoZSBzdGF0aW9uIGNvbm5lY3RzIHRvIGFuIEFQLgogICAgICAgICAgICBUaGlzIGluaXRpYWxpemVzIGFsbCB0aGUgbmVjZXNzYXJ5IGRhdGEgc3RydWN0dXJlcyByZWxhdGVkIHRvIHRoZSAKICAgICAgICAgICAgYXNzb2NpYXRlZCBBUCBhbmQgdHJhbnNpdGlvbnMgdGhlIHN0YXRlIHRvIENPTk5FQ1RFRCBzdGF0ZQoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgc2Vzc2lvbklkIC0gQ1NSIHNlc3Npb24gaWQgdGhhdCBnb3QgY29ubmVjdGVkCiAgICAgICAgICAgIHZvc1N0YXR1cyAtIGNvbm5lY3Qgc3RhdHVzIFNVQ0NFU1MvRkFJTFVSRQoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUluZGljYXRlQ29ubmVjdCh0cEFuaVNpckdsb2JhbCBwTWFjLCB0QU5JX1U4IHNlc3Npb25JZCwgVk9TX1NUQVRVUyB2b3NTdGF0dXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIFZPU19TVEFUVVMgIHZzdGF0dXM7CgojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICBpbnQgIGluaXRfZnRfZmxhZyA9IEZBTFNFOwojZW5kaWYKCiAgICAvLyBpZiBzZXNzaW9uIGlkIGludmFsaWQgdGhlbiB3ZSBuZWVkIHJldHVybiBmYWlsdXJlCiAgICBpZiAoTlVMTCA9PSBwTmVpZ2hib3JSb2FtSW5mbyB8fCAhQ1NSX0lTX1NFU1NJT05fVkFMSUQocE1hYywgc2Vzc2lvbklkKSB8fAogICAgICAgIChOVUxMID09IHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5wQ3VyUm9hbVByb2ZpbGUpKQogICAgewogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgc21zTG9nKHBNYWMsIExPRzIsIEZMKCJDb25uZWN0IGluZGljYXRpb24gcmVjZWl2ZWQgd2l0aCBzZXNzaW9uIGlkICVkIgogICAgICAgICAgICJpbiBzdGF0ZSAlcyIpLAogICAgICAgICAgIHNlc3Npb25JZCwgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CgogICAgLy8gQmFpbCBvdXQgaWYgdGhpcyBpcyBOT1QgYSBTVEEgcGVyc29uYQogICAgaWYgKHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5wQ3VyUm9hbVByb2ZpbGUtPmNzclBlcnNvbmEgIT0gVk9TX1NUQV9NT0RFKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiSWdub3JpbmcgQ29ubmVjdCBpbmRpY2F0aW9uIHJlY2VpdmVkIGZyb20gYSBub24gU1RBIHBlcnNvbmEuIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2Vzc2lvbklkOiAlZCwgY3NyUGVyc29ubmEgJWQiKSwKICAgICAgICAgICAgICAgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAoaW50KXBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5wQ3VyUm9hbVByb2ZpbGUtPmNzclBlcnNvbmEpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIC8vIGlmIGEgY29uY3VycmVudCBzZXNzaW9uIGlzIHJ1bm5pbmcKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgaWYgKGVBTklfQk9PTEVBTl9GQUxTRSA9PSBDU1JfSVNfRkFTVFJPQU1fSU5fQ09OQ1VSUkVOQ1lfSU5JX0ZFQVRVUkVfRU5BQkxFRChwTWFjKSkKICAgIHsKI2VuZGlmCiAgICAgICAgaWYgKGNzcklzQ29uY3VycmVudFNlc3Npb25SdW5uaW5nKHBNYWMpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJZ25vcmluZyBDb25uZWN0IGluZGljYXRpb24gcmVjZWl2ZWQgaW4gbXVsdGlzZXNzaW9uICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JJc0NvbmN1cnJlbnRTZXNzaW9uUnVubmluZyhwTWFjKSk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgfQojZW5kaWYKCiAgICBzd2l0Y2ggKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKI2lmZGVmIFdMQU5fRkVBVFVSRV9MRlJfTUJCCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfTUJCX1BSRUFVVEhfUkVBU1NPQzoKI2VuZGlmCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORzoKICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEp1c3QgdHJhbnNpdGlvbiB0aGUgc3RhdGUgdG8gSU5JVCBzdGF0ZS4gUmVzdCBvZiB0aGUgY2xlYW4gdXAgaGFwcGVucyB3aGVuIHdlIGdldCBuZXh0IGNvbm5lY3QgaW5kaWNhdGlvbiAqLwogICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCkKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKI2VuZGlmCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBGYWxsIHRocm91Z2ggaWYgdGhlIHN0YXR1cyBpcyBTVUNDRVNTICovCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVDoKICAgICAgICAgICAgLyogUmVzZXQgYWxsIHRoZSBkYXRhIHN0cnVjdHVyZXMgaGVyZSAqLyAKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRJbml0U3RhdGVDb250cm9sSW5mbyhwTWFjKTsKCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQgPSBzZXNzaW9uSWQ7CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJbml0aWFsaXplIHRoZSBvY2N1cGllZCBsaXN0IE9OTFkgaWYgd2UgYXJlCiAgICAgICAgICAgICAqIHRyYW5zaXRpb25pbmcgZnJvbSBJTklUIHN0YXRlIHRvIENPTk5FQ1RFRCBzdGF0ZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgICAgICAgICBjc3JJbml0T2NjdXBpZWRDaGFubmVsc0xpc3QocE1hYyk7CiNlbmRpZgogICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQpOwoKICAgICAgICAgICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgCiAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLmJzc2lkLCBzaXplb2YodENzckJzc2lkKSk7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBvcGVyYXRpb25DaGFubmVsID0gcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUub3BlcmF0aW9uQ2hhbm5lbDsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gMDsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpID0gMDsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSA9IERFRkFVTFRfU0NBTjsKI2VuZGlmCgogICAgICAgICAgICAKI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0VTRSkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgICAgICAgICAvKiBOb3cgd2UgY2FuIGNsZWFyIHRoZSBwcmVhdXRoRG9uZSB0aGF0IHdhcyBzYXZlZCBhcyB3ZSBhcmUgY29ubmVjdGVkIGFmcmVzaCAqLwogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHBNYWMsICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpOwojZW5kaWYKICAgICAgICAgICAgCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgICAgICAgICAvLyBCYXNlZCBvbiB0aGUgYXV0aCBzY2hlbWUgdGVsbCBpZiB3ZSBhcmUgMTFyCiAgICAgICAgICAgIGlmICggY3NySXNBdXRoVHlwZTExciggcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuQXV0aFR5cGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLk1ESUQubWRpZVByZXNlbnQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc0Zhc3RUcmFuc2l0aW9uRW5hYmxlZCkKICAgICAgICAgICAgICAgICAgICBpbml0X2Z0X2ZsYWcgPSBUUlVFOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiMTFyQXNzb2MgaXMgPSAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYyk7CiNlbmRpZgoKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgICAgICAgICAgLy8gQmFzZWQgb24gdGhlIGF1dGggc2NoZW1lIHRlbGwgaWYgd2UgYXJlIDExcgogICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuaXNFU0VBc3NvYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNGYXN0VHJhbnNpdGlvbkVuYWJsZWQpCiAgICAgICAgICAgICAgICAgICAgaW5pdF9mdF9mbGFnID0gVFJVRTsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoImlzRVNFQXNzb2MgaXMgPSAlZCBmdCA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MsIGluaXRfZnRfZmxhZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKI2VuZGlmCgogICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5wZW5kaW5nX3JvYW1fZGlzYWJsZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJwcm9jZXNzIHBlbmRpbmcgcm9hbSBkaXNhYmxlIikpOwogICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc0Zhc3RSb2FtSW5pRmVhdHVyZUVuYWJsZWQgPSBGQUxTRTsKICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ucGVuZGluZ19yb2FtX2Rpc2FibGUgPSBGQUxTRTsKICAgICAgICAgICAgfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgLy8gSWYgIkxlZ2FjeSBGYXN0IFJvYW1pbmciIGlzIGVuYWJsZWQgCiAgICAgICAgICAgIGlmIChjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYywgc2Vzc2lvbklkKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW5pdF9mdF9mbGFnID0gVFJVRTsKICAgICAgICAgICAgfQojZW5kaWYKCiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9FU0UpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgICAgICAgICAgaWYgKCBpbml0X2Z0X2ZsYWcgPT0gVFJVRSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEluaXRpYWxpemUgYWxsIHRoZSBkYXRhIHN0cnVjdHVyZXMgbmVlZGVkIGZvciB0aGUgMTFyIEZUIFByZWF1dGggKi8KICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtID0gMDsKICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxlZExpc3QocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICBpZiAoY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgLypJZiB0aGlzIGlzIG5vdCBhIElORlJBIHR5cGUgQlNTLCB0aGVuIGRvIG5vdCBzZW5kIHRoZSBjb21tYW5kCiAgICAgICAgICAgICAgICAgICogZG93biB0byBmaXJtd2FyZS5EbyBub3Qgc2VuZCB0aGUgU1RBUlQgY29tbWFuZCBmb3Igb3RoZXIgc2Vzc2lvbgogICAgICAgICAgICAgICAgICAqIGNvbm5lY3Rpb25zLiovCiAgICAgICAgICAgICAgICAgaWYoY3NyUm9hbUlzU3RhTW9kZShwTWFjLCBzZXNzaW9uSWQpKQogICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIID0gMDsKICAgICAgICAgICAgICAgICAgICAgaWYocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvckluaXRpYWxGb3JjZWRSb2FtVG81R2hFbmFibGUgJiYKICAgICAgICAgICAgICAgICAgICAgICAoR2V0UkZCYW5kKHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBvcGVyYXRpb25DaGFubmVsKSA9PQogICAgICAgICAgICAgICAgICAgICAgICBTSVJfQkFORF8yXzRfR0haKSkKICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgICAgICAqIEtlZXAgNUcgYW5kIEZ3ciByb2FtaW5nIG11dHVhbGx5IGV4Y2x1c2l2ZSBzbyBkbyBub3QKICAgICAgICAgICAgICAgICAgICAgICAgICAqIHNlbmQgUlNPIHN0YXJ0IE5vdGUgd2UgaGF2ZSB0byBzZW5kIFJTTyBzdGFydCBpbiBhbGwKICAgICAgICAgICAgICAgICAgICAgICAgICAqIGVycnJvIGNhc2UuCiAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJEbyBub3Qgc2VuZCBSU08gc3RhcnQiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJlY2F1c2UgNUcgZm9yY2Ugcm9hbWluZyBpcyBlbmFibGVkIikpOwogICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fQ09OTkVDVCk7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgoKICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIG5laWdoYm9yIGxvb2t1cCBET1dOIGV2ZW50IHdpdGggVEwsIFJTU0kgPSAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKTsKICAgICAgICAgICAgICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCBmb3IgRE9XTiBldmVudCBvbmx5ICovCiAgICAgICAgICAgICAgICB2c3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwojZW5kaWYKICAgICAgICAgICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1ModnN0YXR1cykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZzdGF0dXMpOwogICAgICAgICAgICAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAgIH0KI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRCAqLwogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkNvbm5lY3QgZXZlbnQgcmVjZWl2ZWQgaW4gaW52YWxpZCBzdGF0ZSAlcyIKICAgICAgICAgICAgICAgICAgICIuLklnbm9yaW5nLi4uIiksCiAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiBzdGF0dXM7Cn0KCgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxlZExpc3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcHVyZ2VzIGFsbCB0aGUgTUFDIGFkZHJlc3NlcyBpbiB0aGUgcHJlLWF1dGggZmFpbCBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1QdXJnZVByZWF1dGhGYWlsZWRMaXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRBTklfVTggaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3M7IGkrKykKICAgIHsKICAgICAgICB2b3NfbWVtX3plcm8ocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm1hY0FkZHJlc3NbaV0sIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgfQogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MgPSAwOwoKICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUluaXQxMXJBc3NvY0luZm8KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaW5pdGlhbGl6ZXMgMTFyIHJlbGF0ZWQgbmVpZ2hib3Igcm9hbSBkYXRhIHN0cnVjdHVyZXMKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSW5pdDExckFzc29jSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICBlSGFsU3RhdHVzICBzdGF0dXM7CiAgICB0cENzcjExckFzc29jTmVpZ2hib3JJbmZvICAgcEZUUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm87CgogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmlzMTFyQXNzb2MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY2ZnUGFyYW1zLm1heE5laWdoYm9yUmV0cmllcyA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5NYXhOZWlnaGJvclJldHJpZXM7CiAgICBwRlRSb2FtSW5mby0+bmVpZ2hib3JSZXBvcnRUaW1lb3V0ID0gQ1NSX05FSUdIQk9SX1JPQU1fUkVQT1JUX1FVRVJZX1RJTUVPVVQ7CiAgICBwRlRSb2FtSW5mby0+UEVQcmVhdXRoUmVzcFRpbWVvdXQgPSBDU1JfTkVJR0hCT1JfUk9BTV9QUkVBVVRIX1JTUF9XQUlUX01VTFRJUExJRVIgKiBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY2ZnUGFyYW1zLm5laWdoYm9yU2NhblBlcmlvZDsKICAgIHBGVFJvYW1JbmZvLT5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICBwRlRSb2FtSW5mby0+cHJlYXV0aFJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtID0gMDsKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydCA9IDA7CiAgICB2b3NfbWVtX3plcm8ocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRDc3JOZWlnaGJvclJlcG9ydEJzc0luZm8pICogTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOwoKICAgIAogICAgc3RhdHVzID0gY3NyTExPcGVuKHBNYWMtPmhIZGQsICZwRlRSb2FtSW5mby0+cHJlQXV0aERvbmVMaXN0KTsKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkxMIE9wZW4gb2YgcHJlYXV0aCBkb25lIEFQIExpc3QgZmFpbGVkIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICB9CiAgICByZXR1cm4gc3RhdHVzOwp9CiNlbmRpZiAvKiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAqLwoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUluaXQKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaW5pdGlhbGl6ZXMgbmVpZ2hib3Igcm9hbSBkYXRhIHN0cnVjdHVyZXMKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSW5pdCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICBlSGFsU3RhdHVzIHN0YXR1czsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSAgICAgICA9ICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NMT1NFRDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5wcmV2TmVpZ2hib3JSb2FtU3RhdGUgICA9ICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NMT1NFRDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQgICAgICAgICAgICA9ICAgQ1NSX1NFU1NJT05fSURfSU5WQUxJRDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWF4Q2hhbm5lbFNjYW5UaW1lID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yU2Nhbk1heENoYW5UaW1lOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5taW5DaGFubmVsU2NhblRpbWUgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JTY2FuTWluQ2hhblRpbWU7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1heE5laWdoYm9yUmV0cmllcyA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yTG9va3VwUnNzaVRocmVzaG9sZDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yUmVhc3NvY1Jzc2lUaHJlc2hvbGQ7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yU2NhblBlcmlvZCA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5OZWlnaGJvclNjYW5UaW1lclBlcmlvZDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZCA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5OZWlnaGJvclJlc3VsdHNSZWZyZXNoUGVyaW9kOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5lbXB0eVNjYW5SZWZyZXNoUGVyaW9kID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubkVtcHR5U2NhblJlZnJlc2hQZXJpb2Q7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9ySW5pdGlhbEZvcmNlZFJvYW1UbzVHaEVuYWJsZSA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5OZWlnaGJvckluaXRpYWxGb3JjZWRSb2FtVG81R2hFbmFibGU7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLldlYWtab25lUnNzaVRocmVzaG9sZEZvclJvYW0gPQogICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubldlYWtab25lUnNzaVRocmVzaG9sZEZvclJvYW07CgogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5udW1PZkNoYW5uZWxzICAgPQogICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uZWlnaGJvclNjYW5DaGFuTGlzdC5udW1DaGFubmVsczsKCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5udW1PZkNoYW5uZWxzICE9IDApCiAgICB7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9CiAgICAgICAgICAgICAgICB2b3NfbWVtX21hbGxvYyhwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uZWlnaGJvclNjYW5DaGFuTGlzdC5udW1DaGFubmVscyk7CgogICAgICAgIGlmIChOVUxMID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBBbGxvY2F0aW9uIGZvciBDRkcgQ2hhbm5lbCBMaXN0IGZhaWxlZCIpKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgICAgICB9CgogICAgICAgIC8qIFVwZGF0ZSB0aGUgcm9hbSBnbG9iYWwgc3RydWN0dXJlIGZyb20gQ0ZHICovCiAgICAgICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5laWdoYm9yU2NhbkNoYW5MaXN0LmNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uZWlnaGJvclNjYW5DaGFuTGlzdC5udW1DaGFubmVscyk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgRkwoImludmFsaWQgbmVpZ2hib3Igcm9hbSBjaGFubmVsIGxpc3Q6ICV1IiksCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5udW1PZkNoYW5uZWxzKTsKICAgIH0KCiAgICB2b3NfbWVtX3NldChwTmVpZ2hib3JSb2FtSW5mby0+Y3VyckFQYnNzaWQsIHNpemVvZih0Q3NyQnNzaWQpLCAwKTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgPSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSA9IERFRkFVTFRfU0NBTjsKICAgIHZvc19tZW1fc2V0KCZwTmVpZ2hib3JSb2FtSW5mby0+cHJldkNvbm5Qcm9maWxlLCBzaXplb2YodENzclJvYW1Db25uZWN0ZWRQcm9maWxlKSwgMCk7CiNlbmRpZgogICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIHN0YXR1cyA9IHZvc190aW1lcl9pbml0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIsIFZPU19USU1FUl9UWVBFX1NXLAogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yU2NhblRpbWVyQ2FsbGJhY2ssICh2b2lkICopcE1hYyk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiB0aW1lciBhbGxvY2F0aW9uIGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgIH0KCiAgICBzdGF0dXMgPSB2b3NfdGltZXJfaW5pdCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lciwgVk9TX1RJTUVSX1RZUEVfU1csCiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzdWx0c1JlZnJlc2hUaW1lckNhbGxiYWNrLCAodm9pZCAqKXBNYWMpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lciBhbGxvY2F0aW9uIGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgIH0KCiAgICBzdGF0dXMgPSB2b3NfdGltZXJfaW5pdCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lciwgVk9TX1RJTUVSX1RZUEVfU1csCiAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1FbXB0eVNjYW5SZWZyZXNoVGltZXJDYWxsYmFjaywKICAgICAgICAgICAgICAgICh2b2lkICopcE1hYyk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRW1wdHkgc2NhbiByZWZyZXNoIHRpbWVyIGFsbG9jYXRpb24gZmFpbGVkIikpOwogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgIH0KCiAgICBzdGF0dXMgPSB2b3NfdGltZXJfaW5pdCgmcE5laWdoYm9yUm9hbUluZm8tPmZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lciwgVk9TX1RJTUVSX1RZUEVfU1csCiAgICAgICAgICAgICAgICBjc3JGb3JjZWRJbml0aWFsUm9hbVRvNUdIVGltZXJDYWxsYmFjaywgKHZvaWQgKilwTWFjKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJmb3JjZWRJbml0aWFsUm9hbVRvNUdIVGltZXIgdGltZXIgYWxsb2NhdGlvbiBmYWlsZWQiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgIH0KCiAgICBzdGF0dXMgPSBjc3JMTE9wZW4ocE1hYy0+aEhkZCwgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJMTCBPcGVuIG9mIHJvYW1hYmxlIEFQIExpc3QgZmFpbGVkIikpOwogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+Zm9yY2VkSW5pdGlhbFJvYW1UbzVHSFRpbWVyKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA9IENTUl9ORUlHSEJPUl9ST0FNX0lOVkFMSURfQ0hBTk5FTF9JTkRFWDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSW5pdDExckFzc29jSW5mbyhwTWFjKTsKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkxMIE9wZW4gb2Ygcm9hbWFibGUgQVAgTGlzdCBmYWlsZWQiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5mb3JjZWRJbml0aWFsUm9hbVRvNUdIVGltZXIpOwogICAgICAgIGNzckxMQ2xvc2UoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgIH0KI2VuZGlmCiAgICAvKiBJbml0aWFsaXplIHRoaXMgd2l0aCB0aGUgY3VycmVudCB0aWNrIGNvdW50ICovCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJlcXVlc3RUaW1lU3RhbXAgPSB2b3NfdGltZXJfZ2V0X3N5c3RlbV90aW1lKCk7CgogICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCkKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiNlbmRpZgoKICAgIC8vU2V0IHRoZSBMYXN0IFNlbnQgQ21kIGFzIFJTT19TVE9QCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bGFzdFNlbnRDbWQgPSBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QOwogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1DbG9zZQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBjbG9zZXMvZnJlZXMgYWxsIHRoZSBuZWlnaGJvciByb2FtIGRhdGEgc3RydWN0dXJlcwoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtQ2xvc2UodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DTE9TRUQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiTmVpZ2hib3IgUm9hbSBBbGdvcml0aG0gQWxyZWFkeSBDbG9zZWQiKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KQogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KTsKICAgCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgIAogICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CiAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPmZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lcik7CgogICAgLyogU2hvdWxkIGZyZWUgdXAgdGhlIG5vZGVzIGluIHRoZSBsaXN0IGJlZm9yZSBjbG9zaW5nIHRoZSBkb3VibGUgTGlua2VkIGxpc3QgKi8KICAgIGNzck5laWdoYm9yUm9hbUZyZWVSb2FtYWJsZUJTU0xpc3QocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CiAgICBjc3JMTENsb3NlKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KQogICAgewogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPSBDU1JfTkVJR0hCT1JfUk9BTV9JTlZBTElEX0NIQU5ORUxfSU5ERVg7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jaGFuTGlzdFNjYW5JblByb2dyZXNzID0gZUFOSV9CT09MRUFOX0ZBTFNFOyAgICAKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIC8qIEZyZWUgdGhlIHByb2ZpbGUuLiAqLyAKICAgIGNzclJlbGVhc2VQcm9maWxlKHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+Y3NyTmVpZ2hib3JSb2FtUHJvZmlsZSk7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSICAgIAogICAgY3NyUm9hbUZyZWVDb25uZWN0UHJvZmlsZShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnByZXZDb25uUHJvZmlsZSk7CiNlbmRpZgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtID0gMDsKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydCA9IDA7CiAgICB2b3NfbWVtX3plcm8ocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRDc3JOZWlnaGJvclJlcG9ydEJzc0luZm8pICogTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOwogICAgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdChwTWFjLCAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0KTsKICAgIGNzckxMQ2xvc2UoJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCk7CiNlbmRpZiAvKiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAqLwoKICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NMT1NFRCkKICAgIAogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUmVxdWVzdEhhbmRvZmYKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gdHJpZ2dlcnMgYWN0dWFsIHN3aXRjaGluZyBmcm9tIG9uZSBBUCB0byB0aGUgbmV3IEFQLgogICAgICAgICAgICBJdCBpc3N1ZXMgZGlzYXNzb2NpYXRlIHdpdGggcmVhc29uIGNvZGUgYXMgSGFuZG9mZiBhbmQgQ1NSIGFzIGEgcGFydCBvZiAKICAgICAgICAgICAgaGFuZGxpbmcgZGlzYXNzb2MgcnNwLCBpc3N1ZXMgcmVhc3NvY2lhdGUgdG8gdGhlIG5ldyBBUAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUmVxdWVzdEhhbmRvZmYodHBBbmlTaXJHbG9iYWwgcE1hYykKewoKICAgIHRDc3JSb2FtSW5mbyByb2FtSW5mbzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VMzIgc2Vzc2lvbklkID0gcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZDsKICAgIHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvICAgICBoYW5kb2ZmTm9kZTsKICAgIGV4dGVybiB2b2lkIGNzclJvYW1Sb2FtaW5nU3RhdGVEaXNhc3NvY1JzcFByb2Nlc3NvciggdHBBbmlTaXJHbG9iYWwgcE1hYywgdFNpclNtZURpc2Fzc29jUnNwICpwU21lRGlzYXNzb2NSc3AgKTsKICAgIHRBTklfVTMyIHJvYW1JZCA9IDA7CiAgICBlSGFsU3RhdHVzIHN0YXR1czsKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSX01FVFJJQ1MKICAgIHRDc3JSb2FtSW5mbyAqcm9hbUluZm9NZXRyaWNzOwojZW5kaWYKCiAgICBpZiAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlICE9IGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUpIAogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUm9hbSByZXF1ZXN0ZWQgd2hlbiBOZWlnaGJvciByb2FtIGlzIGluICVzIHN0YXRlIiksCiAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGVBTklfQk9PTEVBTl9GQUxTRSA9PQogICAgICAgICBjc3JOZWlnaGJvclJvYW1HZXRIYW5kb2ZmQVBJbmZvKHBNYWMsICZoYW5kb2ZmTm9kZSkpCiAgICB7CiAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgICAgRkwoImZhaWxlZCB0byBvYnRhaW4gaGFuZG9mZiBBUCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0RFQlVHLAogICAgICAgICAgICAgICBGTCgiSEFORE9GRiBDQU5ESURBVEUgQlNTSUQgIk1BQ19BRERSRVNTX1NUUiksCiAgICAgICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShoYW5kb2ZmTm9kZS5wQnNzRGVzY3JpcHRpb24tPmJzc0lkKSk7CgogICAgdm9zX21lbV96ZXJvKCZyb2FtSW5mbywgc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgY3NyUm9hbUNhbGxDYWxsYmFjayhwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLCAmcm9hbUluZm8sIHJvYW1JZCwgZUNTUl9ST0FNX0ZUX1NUQVJULCAKICAgICAgICAgICAgICAgIGVTSVJfU01FX1NVQ0NFU1MpOwoKICAgIHZvc19tZW1femVybygmcm9hbUluZm8sIHNpemVvZih0Q3NyUm9hbUluZm8pKTsKICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFQVNTT0NJQVRJTkcpCiAgICAKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlJfTUVUUklDUwogICAgLyogTEZSIG1ldHJpY3MgLSBwcmUtYXV0aCBjb21wbGV0aW9uIG1ldHJpYy4KICAgICAgIFNlbmQgdGhlIGV2ZW50IHRvIHN1cHBsaWNhbnQgdGhhdCBwcmUtYXV0aCBzdWNjZXNzZnVsbHkgY29tcGxldGVkICovCiAgICByb2FtSW5mb01ldHJpY3MgPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodENzclJvYW1JbmZvKSk7CiAgICBpZiAoTlVMTCA9PSByb2FtSW5mb01ldHJpY3MpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQhIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHZvc19tZW1fY29weSgodm9pZCAqKXJvYW1JbmZvTWV0cmljcy0+YnNzaWQsCiAgICAgICAgICAgICh2b2lkICopJmhhbmRvZmZOb2RlLnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQsIHNpemVvZih0Q3NyQnNzaWQpKTsKICAgICAgICBjc3JSb2FtQ2FsbENhbGxiYWNrKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgIHJvYW1JbmZvTWV0cmljcywgMCwgZUNTUl9ST0FNX0hBTkRPVkVSX1NVQ0NFU1MsIDApOwogICAgICAgIHZvc19tZW1fZnJlZShyb2FtSW5mb01ldHJpY3MpOwogICAgfQojZW5kaWYKCiAgICAvKiBGcmVlIHRoZSBwcm9maWxlLi4gSnVzdCB0byBtYWtlIHN1cmUgd2UgZG9udCBsZWFrIG1lbW9yeSBoZXJlICovIAogICAgY3NyUmVsZWFzZVByb2ZpbGUocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5jc3JOZWlnaGJvclJvYW1Qcm9maWxlKTsKICAgIC8qIENyZWF0ZSB0aGUgSGFuZG9mZiBBUCBwcm9maWxlLiBDb3B5IHRoZSBjdXJyZW50bHkgY29ubmVjdGVkIHByb2ZpbGUgYW5kIHVwZGF0ZSBvbmx5IHRoZSBCU1NJRCBhbmQgY2hhbm5lbCBudW1iZXIKICAgICAgICBUaGlzIHNob3VsZCBoYXBwZW4gYmVmb3JlIGlzc3VpbmcgZGlzY29ubmVjdCAqLwogICAgc3RhdHVzID0gY3NyUm9hbUNvcHlDb25uZWN0ZWRQcm9maWxlKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE5laWdoYm9yUm9hbUluZm8tPmNzck5laWdoYm9yUm9hbVByb2ZpbGUpOwogICAgaWYoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJjc3JSb2FtQ29weUNvbm5lY3RlZFByb2ZpbGUgcmV0dXJuZWQgZmFpbGVkICVkIiksIHN0YXR1cyk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHZvc19tZW1fY29weShwTmVpZ2hib3JSb2FtSW5mby0+Y3NyTmVpZ2hib3JSb2FtUHJvZmlsZS5CU1NJRHMuYnNzaWQsIGhhbmRvZmZOb2RlLnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQsIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNzck5laWdoYm9yUm9hbVByb2ZpbGUuQ2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbMF0gPSBoYW5kb2ZmTm9kZS5wQnNzRGVzY3JpcHRpb24tPmNoYW5uZWxJZDsKICAgIAogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCAiIGNzclJvYW1IYW5kb2ZmUmVxdWVzdGVkOiBkaXNhc3NvY2lhdGluZyB3aXRoIGN1cnJlbnQgQVAiKTsKCiAgICBpZighSEFMX1NUQVRVU19TVUNDRVNTKGNzclJvYW1Jc3N1ZURpc2Fzc29jaWF0ZUNtZChwTWFjLCBzZXNzaW9uSWQsIGVDU1JfRElTQ09OTkVDVF9SRUFTT05fSEFORE9GRikpKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCAiY3NyUm9hbUhhbmRvZmZSZXF1ZXN0ZWQ6ICBmYWlsIHRvIGlzc3VlIGRpc2Fzc29jaWF0ZSIpOwogICAgICAgIHJldHVybjsKICAgIH0gICAgICAgICAgICAgICAgICAgICAgIAoKICAgIC8vbm90aWZ5IEhERCBmb3IgaGFuZG9mZiwgcHJvdmlkaW5nIHRoZSBCU1NJRCB0b28KICAgIHJvYW1JbmZvLnJlYXNvbkNvZGUgPSBlQ3NyUm9hbVJlYXNvbkJldHRlckFQOwoKICAgIHZvc19tZW1fY29weShyb2FtSW5mby5ic3NpZCwgCiAgICAgICAgICAgICAgICAgaGFuZG9mZk5vZGUucEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwgCiAgICAgICAgICAgICAgICAgc2l6ZW9mKCB0Q3NyQnNzaWQgKSk7CgogICAgY3NyUm9hbUNhbGxDYWxsYmFjayhwTWFjLCBzZXNzaW9uSWQsICZyb2FtSW5mbywgMCwgZUNTUl9ST0FNX1JPQU1JTkdfU1RBUlQsIGVDU1JfUk9BTV9SRVNVTFRfTk9ORSk7CgoKICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUlzSGFuZG9mZkluUHJvZ3Jlc3MKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB3aGV0aGVyIGhhbmRvZmYgaXMgaW4gcHJvZ3Jlc3Mgb3Igbm90IGJhc2VkIG9uIAogICAgICAgICAgICB0aGUgY3VycmVudCBuZWlnaGJvciByb2FtIHN0YXRlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBpczExclJlYXNzb2MgLSBSZXR1cm4gd2hldGhlciByZWFzc29jIGlzIG9mIHR5cGUgODAyLjExciByZWFzc29jCgogICAgXHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRSBpZiByZWFzc29jIGluIHByb2dyZXNzLCBlQU5JX0JPT0xFQU5fRkFMU0Ugb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JSb2FtSXNIYW5kb2ZmSW5Qcm9ncmVzcyh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFQVNTT0NJQVRJTkcgPT0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgIHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRTsKCiAgICByZXR1cm4gZUFOSV9CT09MRUFOX0ZBTFNFOwp9CgojaWYgZGVmaW5lZChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZChXTEFOX0ZFQVRVUkVfTkVJR0hCT1JfUk9BTUlORykKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUlzMTFyQXNzb2MKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB3aGV0aGVyIHRoZSBjdXJyZW50IGFzc29jaWF0aW9uIGlzIGEgMTFyIGFzc29jIG9yIG5vdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFIGlmIGN1cnJlbnQgYXNzb2MgaXMgMTFyLCBlQU5JX0JPT0xFQU5fRkFMU0Ugb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JSb2FtSXMxMXJBc3NvYyh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICByZXR1cm4gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmlzMTFyQXNzb2M7Cn0KI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUdldEhhbmRvZmZBUEluZm8KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgYmVzdCBwb3NzaWJsZSBBUCBmb3IgaGFuZG9mZi4gRm9yIDExUiBjYXNlLCBpdCAKICAgICAgICAgICAgcmV0dXJucyB0aGUgMXN0IGVudHJ5IGZyb20gcHJlLWF1dGggZG9uZSBsaXN0LiBGb3Igbm9uLTExciBjYXNlLCBpdCByZXR1cm5zIAogICAgICAgICAgICB0aGUgMXN0IGVudHJ5IGZyb20gcm9hbWFibGUgQVAgbGlzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcEhhbmRvZmZOb2RlIC0gQVAgbm9kZSB0aGF0IGlzIHRoZSBoYW5kb2ZmIGNhbmRpZGF0ZSByZXR1cm5lZAoKICAgIFxyZXR1cm4gZUFOSV9CT09MRUFOX1RSVUUgaWYgYWJsZSBmaW5kIGhhbmRvZmYgQVAsIGVBTklfQk9PTEVBTl9GQUxTRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1HZXRIYW5kb2ZmQVBJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyBwSGFuZG9mZk5vZGUpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvICAgICAgICBwQnNzTm9kZSA9IE5VTEw7CiAgICAKICAgIFZPU19BU1NFUlQoTlVMTCAhPSBwSGFuZG9mZk5vZGUpOyAKICAgICAgICAKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpCiAgICB7CiAgICAgICAgLyogQWx3YXlzIHRoZSBCU1MgaW5mbyBpbiB0aGUgaGVhZCBpcyB0aGUgaGFuZG9mZiBjYW5kaWRhdGUgKi8KICAgICAgICBwQnNzTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QsIE5VTEwpOwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIk51bWJlciBvZiBIYW5kb2ZmIGNhbmRpZGF0ZXMgPSAlZCIpLCBjc3JMTENvdW50KCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpKTsKICAgIH0KICAgIGVsc2UKI2VuZGlmCiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MpCiAgICB7CiAgICAgICAgLyogQWx3YXlzIHRoZSBCU1MgaW5mbyBpbiB0aGUgaGVhZCBpcyB0aGUgaGFuZG9mZiBjYW5kaWRhdGUgKi8KICAgICAgICBwQnNzTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QsIE5VTEwpOwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIk51bWJlciBvZiBIYW5kb2ZmIGNhbmRpZGF0ZXMgPSAlZCIpLCBjc3JMTENvdW50KCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpKTsKICAgIH0KICAgIGVsc2UKI2VuZGlmCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBpZiAoY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQpKQogICAgewogICAgICAgIC8qIEFsd2F5cyB0aGUgQlNTIGluZm8gaW4gdGhlIGhlYWQgaXMgdGhlIGhhbmRvZmYgY2FuZGlkYXRlICovCiAgICAgICAgcEJzc05vZGUgPSBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0LCBOVUxMKTsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJOdW1iZXIgb2YgSGFuZG9mZiBjYW5kaWRhdGVzID0gJWQiKSwgY3NyTExDb3VudCgmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0KSk7CiAgICB9CiAgICBlbHNlCiNlbmRpZgogICAgewogICAgICAgIHBCc3NOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCwgTlVMTCk7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiTnVtYmVyIG9mIEhhbmRvZmYgY2FuZGlkYXRlcyA9ICVkIiksIGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCkpOwogICAgfQoKICAgIGlmIChOVUxMID09IHBCc3NOb2RlKQogICAgewogICAgICAgIHJldHVybiBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICB9CgogICAgdm9zX21lbV9jb3B5KHBIYW5kb2ZmTm9kZSwgcEJzc05vZGUsIHNpemVvZih0Q3NyTmVpZ2hib3JSb2FtQlNTSW5mbykpOwoKICAgIHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmIHByZWF1dGggaXMgY29tcGxldGVkIAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGJvb2xlYW4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1TdGF0ZVByZWF1dGhEb25lKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHJldHVybiAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlID09IAogICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSF9ET05FKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIEluIHRoZSBldmVudCB0aGF0IHdlIGFyZSBhc3NvY2lhdGVkIHdpdGggQVAxIGFuZCB3ZSBoYXZlCiAgICBjb21wbGV0ZWQgcHJlIGF1dGggd2l0aCBBUDIuIFRoZW4gd2UgcmVjZWl2ZSBhIGRlYXV0aC9kaXNhc3NvYyBmcm9tCiAgICBBUDEuIAogICAgQXQgdGhpcyBwb2ludCBuZWlnaGJvciByb2FtIGlzIGluIHByZSBhdXRoIGRvbmUgc3RhdGUsIHByZSBhdXRoIHRpbWVyCiAgICBpcyBydW5uaW5nLiBXZSBub3cgaGFuZGxlIHRoaXMgY2FzZSBieSBzdG9wcGluZyB0aW1lciBhbmQgY2xlYXJpbmcKICAgIHRoZSBwcmUtYXV0aCBzdGF0ZS4gV2UgYmFzaWNhbGx5IGNsZWFyIHVwIGFuZCBqdXN0IGdvIHRvIGRpc2Nvbm5lY3RlZAogICAgc3RhdGUuIAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGJvb2xlYW4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1UcmFuaXN0aW9uUHJlYXV0aERvbmVUb0Rpc2Nvbm5lY3RlZCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGlmIChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUgIT0gCiAgICAgICAgICAgICAgIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUpIHJldHVybjsKCiAgICAvLyBTdG9wIHRpbWVyCiAgICB2b3NfdGltZXJfc3RvcCgmcE1hYy0+ZnQuZnRTbWVDb250ZXh0LnByZUF1dGhSZWFzc29jSW50dmxUaW1lcik7CgogICAgLy8gVHJhbnNpdGlvbiB0byBpbml0IHN0YXRlCiAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKQogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKI2VuZGlmCn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHJldHVybnMgVFJVRSBpZiBiYWNrZ3JvdW5kIHNjYW4gdHJpZ2dlcmVkIGJ5CiAgICAgICAgICAgIExGUiBpcyBpbiBwcm9ncmVzcy4KCiAgICBccGFyYW0gIGhhbEhhbmRsZSAtIFRoZSBoYW5kbGUgZnJvbSBIREQgY29udGV4dC4KCiAgICBccmV0dXJuIGJvb2xlYW4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1TY2FuUnNwUGVuZGluZyAodEhhbEhhbmRsZSBoSGFsKQp7CiAgICB0cEFuaVNpckdsb2JhbCBwTWFjID0gUE1BQ19TVFJVQ1QoaEhhbCk7CiAgICByZXR1cm4gKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5zY2FuUnNwUGVuZGluZyk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHJldHVybnMgVFJVRSBpZiBTVEEgaXMgaW4gdGhlIG1pZGRsZSBvZiByb2FtaW5nIHN0YXRlcwoKICAgIFxwYXJhbSAgaGFsSGFuZGxlIC0gVGhlIGhhbmRsZSBmcm9tIEhERCBjb250ZXh0LgoKICAgIFxyZXR1cm4gYm9vbGVhbgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yTWlkZGxlT2ZSb2FtaW5nICh0SGFsSGFuZGxlIGhIYWwpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVChoSGFsKTsKICAgIHRBTklfQk9PTEVBTiB2YWwgPSAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFQVNTT0NJQVRJTkcgPT0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAgICAgICAgICAgIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkcgPT0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAgICAgICAgICAgIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSF9ET05FID09IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOID09IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTiA9PSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpCgojaWZkZWYgV0xBTl9GRUFUVVJFX0xGUl9NQkIKICAgICAgICAgICAgICAgICAgICAgICB8fCAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX01CQl9QUkVBVVRIX1JFQVNTT0MgPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpOwojZWxzZQogICAgICAgICAgICAgICAgICAgICAgIDsKI2VuZGlmCiAgICByZXR1cm4gKHZhbCk7Cn0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtQ2FuZGlkYXRlRm91bmRJbmRIZGxyCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSBDU1IgYXMgc29vbiBhcyBUTCBwb3N0cyB0aGUgY2FuZGlkYXRlCiAgICAgICAgICAgIGZvdW5kIGluZGljYXRpb24gdG8gU01FIHZpYSBNQyB0aHJlYWQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBNc2cgLSBNc2cgc2VudCBieSBQRQoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUNhbmRpZGF0ZUZvdW5kSW5kSGRscih0cEFuaVNpckdsb2JhbCBwTWFjLCB2b2lkKiBwTXNnKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgICBpZiAodm9zX2NoZWNrX21vbml0b3Jfc3RhdGUoKSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIklnbm9yZSByYW9tIGNhbmRpZGF0ZSB3aGVuIHJvYW0gc3RhcnRlZCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KCiAgICAvKiB3ZSBtdXN0IGJlIGluIGNvbm5lY3RlZCBzdGF0ZSwgaWYgbm90IGlnbm9yZSBpdCAqLwogICAgaWYgKChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICB8fCAocE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZSBPUiB1T3NSZXF1ZXN0ZWRIYW5kb2ZmIGlzIHNldC4gSWdub3JlIGl0IikpOwogICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogV2UgYXJlIGFib3V0IHRvIHN0YXJ0IGEgZnJlc2ggc2NhbiBjeWNsZSwKICAgICAgICAgKiBwdXJnZSBub24tUDJQIHJlc3VsdHMgZnJvbSB0aGUgcGFzdCAqLwogICAgICAgIGNzclNjYW5GbHVzaFNlbGVjdGl2ZVJlc3VsdChwTWFjLCBWT1NfRkFMU0UpOwogICAgICAgIC8qIE9uY2UgaXQgZ2V0cyB0aGUgY2FuZGlkYXRlcyBmb3VuZCBpbmRpY2F0aW9uIGZyb20gUEUsIHdpbGwgaXNzdWUgYSBzY2FuCiAgICAgICAgIC0gcmVxIHRvIFBFIHdpdGggk2ZyZXNoU2NhbpQgaW4gc2NhbnJlcSBzdHJ1Y3R1cmUgc2V0IGFzIGZvbGxvd3M6CiAgICAgICAgIDB4NDIgLSBSZXR1cm4gJiBwdXJnZSBMRlIgc2NhbiByZXN1bHRzCiAgICAgICAgKi8KICAgICAgICBzdGF0dXMgPSBjc3JTY2FuUmVxdWVzdExmclJlc3VsdChwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVNjYW5SZXN1bHRSZXF1ZXN0Q2FsbGJhY2ssIHBNYWMpOwogICAgfQoKICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzSGFuZG9mZlJlcQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgc3RhcnQgd2l0aCB0aGUgaGFuZG9mZiBwcm9jZXNzLiBGaXJzdCBkbyBhCiAgICBTU0lEIHNjYW4gZm9yIHRoZSBCU1NJRCBwcm92aWRlZAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzSGFuZG9mZlJlcSh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRBTklfVTMyIHJvYW1JZDsKICAgIHRDc3JSb2FtUHJvZmlsZSAqcFByb2ZpbGUgPSBOVUxMOwogICAgdENzclJvYW1TZXNzaW9uICpwU2Vzc2lvbiA9IENTUl9HRVRfU0VTU0lPTiggcE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCApOwogICAgdEFOSV9VOCBpID0gMDsKICAgIHVpbnQ4X3Qgcm9hbV9ub3cgPSAwOwogICAgdWludDhfdCByb2FtYWJsZV9hcF9jb3VudCA9IDA7CiAgICB0Q3NyU2NhblJlc3VsdEZpbHRlciAgICBzY2FuX2ZpbHRlcjsKICAgIHRTY2FuUmVzdWx0SGFuZGxlICAgICAgIHNjYW5fcmVzdWx0OwoKICAgIGlmIChOVUxMID09IHBTZXNzaW9uKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgicFNlc3Npb24gaXMgTlVMTCAiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CgogICAgZG8KICAgIHsKICAgICAgICByb2FtSWQgPSBHRVRfTkVYVF9ST0FNX0lEKCZwTWFjLT5yb2FtKTsKICAgICAgICBwUHJvZmlsZSA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyUm9hbVByb2ZpbGUpKTsKICAgICAgICBpZiAoIE5VTEwgPT0gcFByb2ZpbGUgKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2MgZmFpbGVkIikpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICAgICAgdm9zX21lbV9zZXQocFByb2ZpbGUsIHNpemVvZih0Q3NyUm9hbVByb2ZpbGUpLCAwKTsKICAgICAgICBzdGF0dXMgPSBjc3JSb2FtQ29weVByb2ZpbGUocE1hYywgcFByb2ZpbGUsIHBTZXNzaW9uLT5wQ3VyUm9hbVByb2ZpbGUpOwogICAgICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1Moc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUHJvZmlsZSBjb3B5IGZhaWxlZCIpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICAvL0FkZCB0aGUgQlNTSUQgJiBDaGFubmVsCiAgICAgICAgcFByb2ZpbGUtPkJTU0lEcy5udW1PZkJTU0lEcyA9IDE7CiAgICAgICAgcFByb2ZpbGUtPkJTU0lEcy5ic3NpZCA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0U2lyTWFjQWRkcikgKiBwUHJvZmlsZS0+QlNTSURzLm51bU9mQlNTSURzKTsKICAgICAgICBpZiAoTlVMTCA9PSBwUHJvZmlsZS0+QlNTSURzLmJzc2lkKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJtZW0gYWxsb2MgZmFpbGVkIGZvciBCU1NJRCIpKTsKICAgICAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICB2b3NfbWVtX3plcm8ocFByb2ZpbGUtPkJTU0lEcy5ic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBQcm9maWxlLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwoKICAgICAgICAvKiBQb3B1bGF0ZSB0aGUgQlNTSUQgZnJvbSBoYW5kb2ZmIGluZm8gcmVjZWl2ZWQgZnJvbSBIREQgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcFByb2ZpbGUtPkJTU0lEcy5udW1PZkJTU0lEczsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9jb3B5KCZwUHJvZmlsZS0+QlNTSURzLmJzc2lkW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICB9CgogICAgICAgIHBQcm9maWxlLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gMTsKICAgICAgICBwUHJvZmlsZS0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPQogICAgICAgIHZvc19tZW1fbWFsbG9jKHNpemVvZigqcFByb2ZpbGUtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KSAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQcm9maWxlLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzKTsKICAgICAgICBpZiAoTlVMTCA9PSBwUHJvZmlsZS0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIm1lbSBhbGxvYyBmYWlsZWQgZm9yIENoYW5uZWxMaXN0IikpOwogICAgICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgcFByb2ZpbGUtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0WzBdID0gcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmNoYW5uZWw7CgogICAgICAgIC8qCiAgICAgICAgICogRm9yIFVzZXIgc3BhY2UgY29ubmVjdCByZXF1ZXN0cywgdGhlIHNjYW4gaGFzIGFscmVhZHkgYmVlbiBkb25lLgogICAgICAgICAqIFNvLCBjaGVjayBpZiB0aGUgQlNTIGRlc2NyaXB0b3IgZXhpc3RzIGluIHRoZSBzY2FuIGNhY2hlIGFuZAogICAgICAgICAqIHByb2NlZWQgd2l0aCB0aGUgaGFuZG9mZiBpbnN0ZWFkIG9mIGEgcmVkdW5kYW50IHNjYW4gYWdhaW4uCiAgICAgICAgICovCiAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5zcmMgPT0gQ09OTkVDVF9DTURfVVNFUlNQQUNFKSB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiQ29ubmVjdCBjbWQgd2l0aCBic3NpZCB3aXRoaW4gc2FtZSBFU1MiKSk7CiAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByZXBhcmVTY2FuUHJvZmlsZUZpbHRlcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLCAmc2Nhbl9maWx0ZXIpOwogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIkZpbHRlciBjcmVhdGlvbiBzdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgICAgICAgICBzdGF0dXMgPSBjc3JTY2FuR2V0UmVzdWx0KHBNYWMsICZzY2FuX2ZpbHRlciwgJnNjYW5fcmVzdWx0KTsKICAgICAgICAgICAgcm9hbV9ub3cgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhblJlc3VsdHMocE1hYywgJnNjYW5fcmVzdWx0KTsKICAgICAgICAgICAgcm9hbWFibGVfYXBfY291bnQgPSBjc3JMTENvdW50KCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgICAgICAgICBjc3JGcmVlU2NhbkZpbHRlcihwTWFjLCAmc2Nhbl9maWx0ZXIpOwogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoInJvYW1fbm93PSVkLCByb2FtYWJsZV9hcF9jb3VudD0lZCIpLAogICAgICAgICAgICAgICAgICAgcm9hbV9ub3csIHJvYW1hYmxlX2FwX2NvdW50KTsKICAgICAgICB9CiAgICAgICAgaWYgKHJvYW1fbm93ICYmIHJvYW1hYmxlX2FwX2NvdW50KSB7CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVRyaWdnZXJIYW5kb2ZmKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdGF0dXMgPSBjc3JTY2FuRm9yU1NJRChwTWFjLCBwU2Vzc2lvbi0+c2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFByb2ZpbGUsIHJvYW1JZCwgRkFMU0UpOwogICAgICAgICAgICBpZighSEFMX1NUQVRVU19TVUNDRVNTKHN0YXR1cykpCiAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU1NJRCBzY2FuIGZhaWxlZCIpKTsKICAgICAgICB9CiAgICB9d2hpbGUoMCk7CgogICAgaWYoTlVMTCAhPSBwUHJvZmlsZSkKICAgIHsKICAgICAgICBjc3JSZWxlYXNlUHJvZmlsZShwTWFjLCBwUHJvZmlsZSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHBQcm9maWxlKTsKICAgIH0KCiAgICByZXR1cm4gc3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtU3NzaWRTY2FuRG9uZQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgb25jZSBTU0lEIHNjYW4gaXMgZG9uZS4gSWYgU1NJRCBzY2FuIGZhaWxlZAogICAgdG8gZmluZCBvdXIgY2FuZGlkYXRlIGFkZCBhbiBlbnRyeSB0byBjc3Igc2NhbiBjYWNoZSBvdXJzZWxmIGJlZm9yZSBzdGFydGluZwogICAgdGhlIGhhbmRvZmYgcHJvY2VzcwoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Tc3NpZFNjYW5Eb25lKHRwQW5pU2lyR2xvYmFsIHBNYWMsIGVIYWxTdGF0dXMgc3RhdHVzKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgICAgICAgICAgICAgICAgICAgICAgaHN0YXR1czsKCiAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoImNhbGxlZCAiKSk7CgogICAgLyogd2UgbXVzdCBiZSBpbiBjb25uZWN0ZWQgc3RhdGUsIGlmIG5vdCBpZ25vcmUgaXQgKi8KICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIG5vdCBDT05ORUNURUQgc3RhdGUuIElnbm9yZSBpdCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KCiAgICAvL2lmIFNTSUQgc2NhbiBmYWlsZWQgdG8gZmluZCBvdXIgY2FuZGlkYXRlIGFkZCBhbiBlbnRyeSB0byBjc3Igc2NhbiBjYWNoZSBvdXJzZWxmCiAgICBpZighSEFMX1NUQVRVU19TVUNDRVNTKHN0YXR1cykpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJBZGQgYW4gZW50cnkgdG8gY3NyIHNjYW4gY2FjaGUiKSk7CiAgICAgICAgaHN0YXR1cyA9IGNzclNjYW5DcmVhdGVFbnRyeUluU2NhbkNhY2hlKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmNoYW5uZWwpOwogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoImNzclNjYW5DcmVhdGVFbnRyeUluU2NhbkNhY2hlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgfQogICAgfQoKICAgIC8qIE5vdyB3ZSBoYXZlIGNvbXBsZXRlZCBzY2FubmluZyBmb3IgdGhlIGNhbmRpZGF0ZSBwcm92aWRlZCBieSBIREQuIExldCBtb3ZlIG9uIHRvIEhPKi8KICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhbkNvbXBsZXRlKHBNYWMpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIHByb2Nlc3MgY29tcGxldGUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIGhzdGF0dXMpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qKgogKiBjc3JfbmVpZ2hib3Jfcm9hbV9oYW5kbGVyX2Fzc2lnbl9oYW5kb2ZmX3NyYygpIC0gQXNzaWduIHNvdXJjZSBvZgogKgkJCQkJCQlyb2FtIGhhbmRvZmYKICogQHBOZWlnaGJvclJvYW1JbmZvOiBQb2ludGVyIHRvIGNzciBuZWlnaGJvciByb2FtIGNvbnRyb2wgaW5mbwogKiBAcEhhbmRvZmZSZXFJbmZvOiBQb2ludGVyIHRvIHRoZSBIYW5kb2ZmIHJlcXVlc3QKICoKICogUmV0dXJuOiBOb25lCiAqLwojaWZuZGVmIFFDQV9XSUZJX0lTT0MKc3RhdGljIGlubGluZSB2b2lkIGNzcl9uZWlnaGJvcl9yb2FtX2hhbmRsZXJfYXNzaWduX2hhbmRvZmZfc3JjKAoJCQl0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICBwTmVpZ2hib3JSb2FtSW5mbywKCQkJdEFuaUhhbmRvZmZSZXEgKnBIYW5kb2ZmUmVxSW5mbykKewoJcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLnNyYwoJCT0gcEhhbmRvZmZSZXFJbmZvLT5oYW5kb2ZmX3NyYzsKfQojZWxzZQpzdGF0aWMgaW5saW5lIHZvaWQgY3NyX25laWdoYm9yX3JvYW1faGFuZGxlcl9hc3NpZ25faGFuZG9mZl9zcmMoCgkJCXRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gIHBOZWlnaGJvclJvYW1JbmZvLAoJCQl0QW5pSGFuZG9mZlJlcSAqcEhhbmRvZmZSZXFJbmZvKQp7Cn0KI2VuZGlmCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSGFuZG9mZlJlcUhkbHIKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IENTUiBhcyBzb29uIGFzIGl0IGdldHMgYSBoYW5kb2ZmIHJlcXVlc3QKICAgICAgICAgICAgdG8gU01FIHZpYSBNQyB0aHJlYWQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBNc2cgLSBNc2cgc2VudCBieSBIREQKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1IYW5kb2ZmUmVxSGRscih0cEFuaVNpckdsb2JhbCBwTWFjLCB2b2lkKiBwTXNnKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRBbmlIYW5kb2ZmUmVxICAgICAgICAgICAgICAgICAqcEhhbmRvZmZSZXFJbmZvOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgLyogd2UgbXVzdCBiZSBpbiBjb25uZWN0ZWQgc3RhdGUsIGlmIG5vdCBpZ25vcmUgaXQgKi8KICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIG5vdCBDT05ORUNURUQgc3RhdGUuIElnbm9yZSBpdCIpKTsKICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8vc2F2ZSB0aGUgaGFuZG9mZiBpbmZvIGNhbWUgZnJvbSBIREQgYXMgcGFydCBvZiB0aGUgcmVhc3NvYyByZXEKICAgICAgICBwSGFuZG9mZlJlcUluZm8gPSAodEFuaUhhbmRvZmZSZXEgKilwTXNnOwogICAgICAgIGlmIChOVUxMICE9IHBIYW5kb2ZmUmVxSW5mbykKICAgICAgICB7CiAgICAgICAgICAgIC8vc2FuaXR5IGNoZWNrCiAgICAgICAgICAgIGlmIChWT1NfRkFMU0UgPT0gdm9zX21lbV9jb21wYXJlKHBIYW5kb2ZmUmVxSW5mby0+YnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSkpCiAgICAgICAgICAgIHsKCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uY2hhbm5lbCA9IHBIYW5kb2ZmUmVxSW5mby0+Y2hhbm5lbDsKICAgICAgICAgICAgICAgIGNzcl9uZWlnaGJvcl9yb2FtX2hhbmRsZXJfYXNzaWduX2hhbmRvZmZfc3JjKHBOZWlnaGJvclJvYW1JbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSGFuZG9mZlJlcUluZm8pOwogICAgICAgICAgICAgICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSGFuZG9mZlJlcUluZm8tPmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIDYpOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAxOwogICAgICAgICAgICAgICAgc3RhdHVzID0gY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUT1AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVBU09OX09TX1JFUVVFU1RFRF9ST0FNSU5HX05PVyk7CiAgICAgICAgICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJjc3JSb2FtT2ZmbG9hZFNjYW4gZmFpbGVkIikpOwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgcmVxIGhhcyBzYW1lIEJTU0lEIGFzIGN1cnJlbnQgQVAhISIpKTsKICAgICAgICAgICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBtc2cgaXMgTlVMTCIpKTsKICAgICAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHN0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByb2NlZWRXaXRoSGFuZG9mZlJlcQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgQ1NSIGFzIHNvb24gYXMgaXQgZ2V0cyByc3AgYmFjayBmb3IKICAgICAgICAgICAgUk9BTV9TQ0FOX09GRkxPQURfU1RPUCB3aXRoIHJlYXNvbiBSRUFTT05fT1NfUkVRVUVTVEVEX1JPQU1JTkdfTk9XCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVByb2NlZWRXaXRoSGFuZG9mZlJlcSh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIC8qIHdlIG11c3QgYmUgaW4gY29ubmVjdGVkIHN0YXRlLCBpZiBub3QgaWdub3JlIGl0ICovCiAgICBpZiAoKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgIHx8ICghcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZSBvciB1T3NSZXF1ZXN0ZWRIYW5kb2ZmIGlzIG5vdCBzZXQuIElnbm9yZSBpdCIpKTsKICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8vTGV0J3MgZ28gYWhlYWQgd2l0aCBoYW5kb2ZmCiAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc0hhbmRvZmZSZXEocE1hYyk7CiAgICB9CiAgICBpZighSEFMX1NUQVRVU19TVUNDRVNTKHN0YXR1cykpCiAgICB7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVN0YXJ0TGZyU2NhbgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgaWYgSEREIHJlcXVlc3RlZCBoYW5kb2ZmIGZhaWxlZCBmb3Igc29tZQogICAgcmVhc29uLiBzdGFydCB0aGUgTEZSIGxvZ2ljIGF0IHRoYXQgcG9pbnQuQnkgdGhlIHRpbWUsIHRoaXMgZnVuY3Rpb24gaXMKICAgIGNhbGxlZCwgYSBTVE9QIGNvbW1hbmQgaGFzIGFscmVhZHkgYmVlbiBpc3N1ZWQuCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVN0YXJ0TGZyU2Nhbih0cEFuaVNpckdsb2JhbCBwTWFjLCB0QU5JX1U4IE9mZmxvYWRDbWRTdG9wUmVhc29uKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBzbXNMb2cocE1hYywgTE9HRSwKICAgICAgICAgICBGTCgiIHVPc1JlcXVlc3RlZEhhbmRvZmY9JWQgaXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIPSVkIE9mZmxvYWRDbWRTdG9wUmVhc29uID0gJWQiKSwKICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiwKICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdILAogICAgICAgICAgIE9mZmxvYWRDbWRTdG9wUmVhc29uKTsKCiAgICBpZihPZmZsb2FkQ21kU3RvcFJlYXNvbiA9PSBSRUFTT05fT1NfUkVRVUVTVEVEX1JPQU1JTkdfTk9XKQogICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgaWYoT2ZmbG9hZENtZFN0b3BSZWFzb24gPT0gUkVBU09OX0lOSVRJQUxfRk9SQ0VEX1JPQU1fVE9fNUcpCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCA9IDA7CiAgICAvKiBUaGVyZSBpcyBubyBjYW5kaWRhdGUgb3IgV2UgYXJlIG5vdCByb2FtaW5nIE5vdy4KICAgICAqIEluZm9ybSB0aGUgRlcgdG8gcmVzdGFydCBSb2FtIE9mZmxvYWQgU2NhbiAgKi8KICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwgUkVBU09OX05PX0NBTkRfRk9VTkRfT1JfTk9UX1JPQU1JTkdfTk9XKTsKCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQojZW5kaWYgLy9XTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HICovCg==