LyoKICogQ29weXJpZ2h0IChjKSAyMDExLTIwMTcgVGhlIExpbnV4IEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFByZXZpb3VzbHkgbGljZW5zZWQgdW5kZXIgdGhlIElTQyBsaWNlbnNlIGJ5IFF1YWxjb21tIEF0aGVyb3MsIEluYy4KICoKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IKICogYW55IHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUKICogYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsCiAqIGNvcGllcy4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTAogKiBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVECiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKICogQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCwgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SCiAqIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgovKgogKiBUaGlzIGZpbGUgd2FzIG9yaWdpbmFsbHkgZGlzdHJpYnV0ZWQgYnkgUXVhbGNvbW0gQXRoZXJvcywgSW5jLgogKiB1bmRlciBwcm9wcmlldGFyeSB0ZXJtcyBiZWZvcmUgQ29weXJpZ2h0IG93bmVyc2hpcCB3YXMgYXNzaWduZWQKICogdG8gdGhlIExpbnV4IEZvdW5kYXRpb24uCiAqLwoKCi8qKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICoKICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKgoKCiAgICBcZmlsZSBjc3JOZWlnaGJvclJvYW0uYwoKICAgIEltcGxlbWVudGF0aW9uIGZvciB0aGUgc2ltcGxlIHJvYW1pbmcgYWxnb3JpdGhtIGZvciA4MDIuMTFyIEZhc3QgdHJhbnNpdGlvbnMgYW5kIExlZ2FjeSByb2FtaW5nIGZvciBBbmRyb2lkIHBsYXRmb3JtLgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICAgICAgICAgICAgICAgICAgICBFRElUIEhJU1RPUlkgRk9SIEZJTEUKCgogIFRoaXMgc2VjdGlvbiBjb250YWlucyBjb21tZW50cyBkZXNjcmliaW5nIGNoYW5nZXMgbWFkZSB0byB0aGUgbW9kdWxlLgogIE5vdGljZSB0aGF0IGNoYW5nZXMgYXJlIGxpc3RlZCBpbiByZXZlcnNlIGNocm9ub2xvZ2ljYWwgb3JkZXIuCgoKCiAgd2hlbiAgICAgICAgICAgd2hvICAgICAgICAgICAgICAgICB3aGF0LCB3aGVyZSwgd2h5Ci0tLS0tLS0tLS0gICAgICAgLS0tICAgICAgICAgICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjA4LzAxLzEwICAgICAgICAgIE11cmFsaSAgICAgICAgICAgICBDcmVhdGVkCgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwojaWZkZWYgV0xBTl9GRUFUVVJFX05FSUdIQk9SX1JPQU1JTkcKI2luY2x1ZGUgIndsYW5fcWN0X3dkYS5oIgojaW5jbHVkZSAicGFsQXBpLmgiCiNpbmNsdWRlICJjc3JJbnNpZGVBcGkuaCIKI2luY2x1ZGUgInNtc0RlYnVnLmgiCiNpbmNsdWRlICJsb2dEdW1wLmgiCiNpbmNsdWRlICJzbWVRb3NJbnRlcm5hbC5oIgojaW5jbHVkZSAid2xhbl9xY3RfdGwuaCIKI2luY2x1ZGUgInNtZUluc2lkZS5oIgojaW5jbHVkZSAidm9zX2RpYWdfY29yZV9ldmVudC5oIgojaW5jbHVkZSAidm9zX2RpYWdfY29yZV9sb2cuaCIKI2luY2x1ZGUgImNzckFwaS5oIgojaW5jbHVkZSAid2xhbl9xY3RfdGwuaCIKI2luY2x1ZGUgInNtZV9BcGkuaCIKI2luY2x1ZGUgImNzck5laWdoYm9yUm9hbS5oIgojaW5jbHVkZSAibWFjVHJhY2UuaCIKI2lmIGRlZmluZWQoRkVBVFVSRV9XTEFOX0VTRSkgJiYgIWRlZmluZWQoRkVBVFVSRV9XTEFOX0VTRV9VUExPQUQpCiNpbmNsdWRlICJjc3JFc2UuaCIKI2VuZGlmCgojZGVmaW5lIFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HX0RFQlVHIDEKI2lmZGVmIFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HX0RFQlVHCiNkZWZpbmUgTkVJR0hCT1JfUk9BTV9ERUJVRyBzbXNMb2cKI2Vsc2UKI2RlZmluZSBORUlHSEJPUl9ST0FNX0RFQlVHKHguLi4pCiNlbmRpZgoKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRDaGFubmVsSW5mbyh0cENzck5laWdoYm9yUm9hbUNoYW5uZWxJbmZvIHJDaEluZm8pOwpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldENmZ0xpc3RDaGFuU2NhbkNvbnRyb2xJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQpOwpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldFByZWF1dGhDb250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCk7CnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24odHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCk7CgpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayAodl9QVk9JRF90IHBBZGFwdGVyLCB2X1U4X3QgcnNzaU5vdGlmaWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUFZPSURfdCBwVXNlckN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1M3X3QgYXZnUnNzaSk7ClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgKHZfUFZPSURfdCBwQWRhcHRlciwgdl9VOF90IHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUFZPSURfdCBwVXNlckN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUzdfdCBhdmdSc3NpKTsKdm9pZCBjc3JOZWlnaGJvclJvYW1SUk1OZWlnaGJvclJlcG9ydFJlc3VsdCh2b2lkICpjb250ZXh0LCBWT1NfU1RBVFVTIHZvc1N0YXR1cyk7CmVIYWxTdGF0dXMgY3NyUm9hbUNvcHlDb25uZWN0ZWRQcm9maWxlKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRBTklfVTMyIHNlc3Npb25JZCwgdENzclJvYW1Qcm9maWxlICpwRHN0UHJvZmlsZSApOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUlzc3VlUHJlYXV0aFJlcSh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQpOwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQpOwojZW5kaWYKCnZfVThfdCAqY3NyTmVpZ2hib3JSb2FtU3RhdGVUb1N0cmluZyh2X1U4X3Qgc3RhdGUpCnsKICAgIHN3aXRjaChzdGF0ZSkKICAgIHsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DTE9TRUQgKTsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyApOwogICAgICAgIENBU0VfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWSApOwogICAgICAgIENBU0VfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkcgKTsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUgKTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gImVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9VTktOT1dOIjsKICAgIH0KCn0KCi8qIFN0YXRlIFRyYW5zaXRpb24gbWFjcm8gKi8Kdm9pZCBjc3JfbmVpZ2hib3Jfcm9hbV9zdGF0ZV90cmFuc2l0aW9uKHRwQW5pU2lyR2xvYmFsIG1hY19jdHgsCiAgICAgICAgICAgICAgICB1aW50OF90IG5ld3N0YXRlLCB1aW50OF90IHNlc3Npb24pCnsKCW1hY19jdHgtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uXS5wcmV2TmVpZ2hib3JSb2FtU3RhdGUgPQoJCW1hY19jdHgtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uXS5uZWlnaGJvclJvYW1TdGF0ZTsKCW1hY19jdHgtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uXS5uZWlnaGJvclJvYW1TdGF0ZSA9IG5ld3N0YXRlOwoJVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0RFQlVHLAoJCUZMKCJTZXNzaW9uIGlkKCVkKSBOZWlnaGJvclJvYW0gVHJhbnNpdGlvbiBmcm9tICVzID09PiAlcyIpLAoJCXNlc3Npb24sCgkJY3NyTmVpZ2hib3JSb2FtU3RhdGVUb1N0cmluZyAoCgkJbWFjX2N0eC0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25dLnByZXZOZWlnaGJvclJvYW1TdGF0ZSksCgkJY3NyTmVpZ2hib3JSb2FtU3RhdGVUb1N0cmluZyAobmV3c3RhdGUpKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUZyZWVOZWlnaGJvclJvYW1CU1NOb2RlCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGZyZWVzIGFsbCB0aGUgaW50ZXJuYWwgcG9pbnRlcnMgQ1NSIE5laWdoYm9yUm9hbSBCU1MgSW5mbwogICAgICAgICAgICBhbmQgYWxzbyBmcmVlcyB0aGUgbm9kZSBpdHNlbGYKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIG5laWdoYm9yUm9hbUJTU05vZGUgLSBOZWlnaGJvciBSb2FtIEJTUyBOb2RlIHRvIGJlIGZyZWVkCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbUZyZWVOZWlnaGJvclJvYW1CU1NOb2RlKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyBuZWlnaGJvclJvYW1CU1NOb2RlKQp7CiAgICBpZiAobmVpZ2hib3JSb2FtQlNTTm9kZSkKICAgIHsKICAgICAgICBpZiAobmVpZ2hib3JSb2FtQlNTTm9kZS0+cEJzc0Rlc2NyaXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKG5laWdoYm9yUm9hbUJTU05vZGUtPnBCc3NEZXNjcmlwdGlvbik7CiAgICAgICAgICAgIG5laWdoYm9yUm9hbUJTU05vZGUtPnBCc3NEZXNjcmlwdGlvbiA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIHZvc19tZW1fZnJlZShuZWlnaGJvclJvYW1CU1NOb2RlKTsKICAgICAgICBuZWlnaGJvclJvYW1CU1NOb2RlID0gTlVMTDsKICAgIH0KCiAgICByZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SZW1vdmVSb2FtYWJsZUFQTGlzdEVudHJ5CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHJlbW92ZXMgYSBnaXZlbiBlbnRyeSBmcm9tIHRoZSBnaXZlbiBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwTGlzdCAtIFRoZSBsaXN0IGZyb20gd2hpY2ggdGhlIGVudHJ5IHNob3VsZCBiZSByZW1vdmVkCiAgICAgICAgICAgIHBOZWlnaGJvckVudHJ5IC0gTmVpZ2hib3IgUm9hbSBCU1MgTm9kZSB0byBiZSByZW1vdmVkCgogICAgXHJldHVybiBUUlVFIGlmIHN1Y2Nlc3NmdWxseSByZW1vdmVkLCBlbHNlIEZBTFNFCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JSb2FtUmVtb3ZlUm9hbWFibGVBUExpc3RFbnRyeSh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0RGJsTGlua0xpc3QgKnBMaXN0LCB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gcE5laWdoYm9yRW50cnkpCnsKICAgIGlmKHBMaXN0KQogICAgewogICAgICAgIHJldHVybiBjc3JMTFJlbW92ZUVudHJ5KHBMaXN0LCAmcE5laWdoYm9yRW50cnktPkxpc3QsIExMX0FDQ0VTU19MT0NLKTsKICAgIH0KCiAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlbW92aW5nIG5laWdoYm9yIEJTUyBub2RlIGZyb20gbGlzdCBmYWlsZWQuIEN1cnJlbnQgY291bnQgPSAlZCIpLCBjc3JMTENvdW50KHBMaXN0KSk7CgogICAgcmV0dXJuIGVBTklfQk9PTEVBTl9GQUxTRTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5CgogICAgXGJyaWVmICBHZXRzIHRoZSBlbnRyeSBuZXh0IHRvIHBhc3NlZCBlbnRyeS4gSWYgTlVMTCBpcyBwYXNzZWQsIHJldHVybiB0aGUgZW50cnkgaW4gdGhlIGhlYWQgb2YgdGhlIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBMaXN0IC0gVGhlIGxpc3QgZnJvbSB3aGljaCB0aGUgZW50cnkgc2hvdWxkIGJlIHJldHVybmVkCiAgICAgICAgICAgIHBOZWlnaGJvckVudHJ5IC0gTmVpZ2hib3IgUm9hbSBCU1MgTm9kZSB3aG9zZSBuZXh0IGVudHJ5IHNob3VsZCBiZSByZXR1cm5lZAoKICAgIFxyZXR1cm4gTmVpZ2hib3IgUm9hbSBCU1MgTm9kZSB0byBiZSByZXR1cm5lZAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0RGJsTGlua0xpc3QgKnBMaXN0LCB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gcE5laWdoYm9yRW50cnkpCnsKICAgIHRMaXN0RWxlbSAqcEVudHJ5ID0gTlVMTDsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyBwUmVzdWx0ID0gTlVMTDsKCiAgICBpZihwTGlzdCkKICAgIHsKICAgICAgICBpZihOVUxMID09IHBOZWlnaGJvckVudHJ5KQogICAgICAgIHsKICAgICAgICAgICAgcEVudHJ5ID0gY3NyTExQZWVrSGVhZChwTGlzdCwgTExfQUNDRVNTX0xPQ0spOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBwRW50cnkgPSBjc3JMTE5leHQocExpc3QsICZwTmVpZ2hib3JFbnRyeS0+TGlzdCwgTExfQUNDRVNTX0xPQ0spOwogICAgICAgIH0KICAgICAgICBpZihwRW50cnkpCiAgICAgICAgewogICAgICAgICAgICBwUmVzdWx0ID0gR0VUX0JBU0VfQUREUihwRW50cnksIHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvLCBMaXN0KTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHBSZXN1bHQ7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0CgogICAgXGJyaWVmICAgRW1wdGllcyBhbmQgZnJlZXMgYWxsIHRoZSBub2RlcyBpbiB0aGUgcm9hbSBhYmxlIEFQIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBMaXN0IC0gTmVpZ2hib3IgUm9hbSBCU1MgTGlzdCB0byBiZSBlbXB0aWVkCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbUZyZWVSb2FtYWJsZUJTU0xpc3QodHBBbmlTaXJHbG9iYWwgcE1hYywgdERibExpbmtMaXN0ICpwTGlzdCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBSZXN1bHQgPSBOVUxMOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkVtcHR5aW5nIHRoZSBCU1MgbGlzdC4gQ3VycmVudCBjb3VudCA9ICVkIiksIGNzckxMQ291bnQocExpc3QpKTsKCiAgICAvKiBQaWNrIHVwIHRoZSBoZWFkLCByZW1vdmUgYW5kIGZyZWUgdGhlIG5vZGUgdGlsbCB0aGUgbGlzdCBiZWNvbWVzIGVtcHR5ICovCiAgICB3aGlsZSAoKHBSZXN1bHQgPSBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeShwTWFjLCBwTGlzdCwgTlVMTCkpICE9IE5VTEwpCiAgICB7CiAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVtb3ZlUm9hbWFibGVBUExpc3RFbnRyeShwTWFjLCBwTGlzdCwgcFJlc3VsdCk7CiAgICAgICAgY3NyTmVpZ2hib3JSb2FtRnJlZU5laWdoYm9yUm9hbUJTU05vZGUocE1hYywgcFJlc3VsdCk7CiAgICB9CiAgICByZXR1cm47Cn0KCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbVRyaWdnZXJIYW5kb2ZmKHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgJiYgIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykKI2VuZGlmCiAgICApCiAgICB7CiAgICAgICAgaWYgKChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pKQogICAgICAgIHsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHBNYWMsIHNlc3Npb25JZCk7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4gPSBlU01FX1JPQU1fVFJJR0dFUl9OT05FOwogICAgICAgICAgICB2b3NfbWVtX3NldCgmcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1ic3NJZFswXSwKICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtYnNzSWQpLAogICAgICAgICAgICAgICAgICAgICAgICAweEZGKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCIxMVIgUmVhc3NvYyBpbmRpY2F0aW9uIHJlY2VpdmVkIGluIHVuZXhwZWN0ZWQgc3RhdGUgJXMiKSwKICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgIFZPU19BU1NFUlQoMCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQojZW5kaWYKCiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCiAgICAgICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYykKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICYmICFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpCiNlbmRpZgogICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEocE1hYywgc2Vzc2lvbklkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQ0NYIFJlYXNzb2MgaW5kaWNhdGlvbiByZWNlaXZlZCBpbiB1bmV4cGVjdGVkIHN0YXRlICVzIiksCiAgICAgICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICBWT1NfQVNTRVJUKDApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKI2VuZGlmCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgIGlmIChjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYywgc2Vzc2lvbklkKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgICB8fCBjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpIHx8CiAgICAgICAgICAgICAgICAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pCiNlbmRpZgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUlzc3VlUHJlYXV0aFJlcShwTWFjLCBzZXNzaW9uSWQpOwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4gPSBlU01FX1JPQU1fVFJJR0dFUl9OT05FOwogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fc2V0KCZwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbWJzc0lkWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbWJzc0lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweEZGKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkxGUiBSZWFzc29jIGluZGljYXRpb24gcmVjZWl2ZWQgaW4gdW5leHBlY3RlZCBzdGF0ZSAlcyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgICAgICAgICBWT1NfQVNTRVJUKDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKI2VuZGlmCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXF1ZXN0SGFuZG9mZihwTWFjLCBzZXNzaW9uSWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTm9uLTExUiBSZWFzc29jIGluZGljYXRpb24gcmVjZWl2ZWQgaW4gdW5leHBlY3RlZCBzdGF0ZSAlcyBvciBSb2FtaW5nIGlzIGRpc2FibGVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQp9CgpWT1NfU1RBVFVTCmNzck5laWdoYm9yUm9hbVVwZGF0ZUZhc3RSb2FtaW5nRW5hYmxlZCh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCAgICAgICBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2X0JPT0xfdCBmYXN0Um9hbUVuYWJsZWQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgVk9TX1NUQVRVUyB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cEZUUm9hbUNhbGxiYWNrVXNyQ3R4ICAgICBwVXNyQ3R4OwoKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBpZiAoVk9TX1RSVUUgPT0gZmFzdFJvYW1FbmFibGVkKQogICAgICAgIHsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBzZXNzaW9uSWQsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9DT05ORUNUKTsKICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIG5laWdoYm9yIGxvb2t1cCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRE9XTiBldmVudCB3aXRoIFRMLCBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKTsKCiAgICAgICAgICAgIC8qIEJvdGggcE1hYyBhbmQgc2Vzc2lvbklkIGFyZSByZXF1aXJlZCB0byBpZGVudGlmeSBmb3Igd2hpY2gKICAgICAgICAgICAgICogc2Vzc2lvbiB0aGUgaW5kaWNhdGlvbiBpcyBiZWluZyByZWNlaXZlZAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcFVzckN0eCA9IHZvc19tZW1fbWFsbG9jKHNpemVvZigqcFVzckN0eCkpOwogICAgICAgICAgICBpZiAoTlVMTCA9PSBwVXNyQ3R4KSB7CiAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZmFpbHVyZSIpKTsKICAgICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9OT01FTTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwVXNyQ3R4LT5wTWFjID0gcE1hYzsKICAgICAgICAgICAgcFVzckN0eC0+c2Vzc2lvbklkID0gc2Vzc2lvbklkOwoKICAgICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvcgogICAgICAgICAgICAgICBET1dOIGV2ZW50IG9ubHkgKi8KICAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwKICAgICAgICAgICAgICAgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBVc3JDdHgpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocFVzckN0eCk7CiAgICAgICAgICAgIGlmICghVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgICAgIEZMKCJGYWlsZWQgdG8gcmVnaXN0ZXIgUlNTSSBpbmRpY2F0aW9uIGNhbGxiYWNrID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICB2b3NTdGF0dXMpOwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChWT1NfRkFMU0UgPT0gZmFzdFJvYW1FbmFibGVkKQogICAgICAgIHsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIENPTk5FQ1RFRCBzdGF0ZSwgc28gZGVyZWdpc3RlciBhbGwgZXZlbnRzIikpOwogICAgICAgICAgICAvKiBEZS1yZWdpc3RlciBleGlzdGluZyBsb29rdXAgVVAvRE9XTiwgUnNzaSBpbmRpY2F0aW9ucyAqLwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgc2Vzc2lvbklkLCBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVBU09OX0RJU0NPTk5FQ1RFRCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMsIHNlc3Npb25JZCk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIElOSVQgc3RhdGUsIE5vdGhpbmcgdG8gZG8iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIlVuZXhwZWN0ZWQgc3RhdGUgJXMsIHJldHVybmluZyBmYWlsdXJlIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1VcGRhdGVFc2VNb2RlRW5hYmxlZCh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZfQk9PTF90IGVzZU1vZGUpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgVk9TX1NUQVRVUyB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cEZUUm9hbUNhbGxiYWNrVXNyQ3R4ICAgICBwVXNyQ3R4OwoKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBpZiAoVk9TX1RSVUUgPT0gZXNlTW9kZSkKICAgICAgICB7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgRkwoIlJlZ2lzdGVyaW5nIG5laWdoYm9yIGxvb2t1cCBET1dOIGV2ZW50IHdpdGggVEwsIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCk7CgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIHNlc3Npb25JZCwgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVBU09OX0NPTk5FQ1QpOwogICAgICAgICAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICAgICAgLyogVGhpcyB1c2VyIGNvbnRleHQgZGF0YSB3aWxsIGJlIHJldHVybmVkIHdpdGggY2FsbGJhY2sgKi8KICAgICAgICAgICAgcFVzckN0eCA9IHZvc19tZW1fbWFsbG9jKHNpemVvZigqcFVzckN0eCkpOwogICAgICAgICAgICBpZiAoTlVMTCA9PSBwVXNyQ3R4KSB7CiAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZmFpbHVyZSIpKTsKICAgICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9OT01FTTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwVXNyQ3R4LT5wTWFjID0gcE1hYzsKICAgICAgICAgICAgcFVzckN0eC0+c2Vzc2lvbklkID0gc2Vzc2lvbklkOwoKICAgICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBET1dOIGV2ZW50IG9ubHkgKi8KICAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwKICAgICAgICAgICAgICAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcFVzckN0eCk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShwVXNyQ3R4KTsKICAgICAgICAgICAgaWYgKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgRkwoIkZhaWxlZCB0byByZWdpc3RlciBSU1NJIGluZGljYXRpb24gY2FsbGJhY2s6IFN0YXR1cyA9ICVkIiksCiAgICAgICAgICAgICAgICAgdm9zU3RhdHVzKTsKCiAgICAgICAgICAgICAgICAvKiBSZWdpc3RyYXRpb24gZmFpbGVkLCBmcmVlIHRoZSB1c2VyIGNvbnRleHQgKi8KICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoVk9TX0ZBTFNFID09IGVzZU1vZGUpCiAgICAgICAgewogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsCiAgICAgICAgICAgICAgIEZMKCJDdXJyZW50bHkgaW4gQ09OTkVDVEVEIHN0YXRlLCBzbyBkZXJlZ2lzdGVyIGFsbCBldmVudHMiKSk7CgogICAgICAgICAgICAvKiBEZS1yZWdpc3RlciBleGlzdGluZyBsb29rdXAgVVAvRE9XTiwgUnNzaSBpbmRpY2F0aW9ucyAqLwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgc2Vzc2lvbklkLCBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVBU09OX0RJU0NPTk5FQ1RFRCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMsIHNlc3Npb25JZCk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCA9PQogICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLAogICAgICAgICBGTCgiQ3VycmVudGx5IGluIElOSVQgc3RhdGUsIE5vdGhpbmcgdG8gZG8iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLAogICAgICAgICAgICBGTCgiVW5leHBlY3RlZCBzdGF0ZSAlZCwgcmV0dXJuaW5nIGZhaWx1cmUiKSwKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCiNlbmRpZgoKClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtU2V0TG9va3VwUnNzaVRocmVzaG9sZCh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfVThfdCBuZWlnaGJvckxvb2t1cFJzc2lUaHJlc2hvbGQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CiAgICBWT1NfU1RBVFVTIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIHRwRlRSb2FtQ2FsbGJhY2tVc3JDdHggIHBVc3JDdHg7CgogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgPT0KICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgRkwoIkluIENPTk5FQ1RFRCBzdGF0ZSwgcmUtcmVnaXN0ZXIgZm9yIERPV04gZXZlbnQgb25seSIpKTsKCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9CiAgICAgICAgICAgIG5laWdoYm9yTG9va3VwUnNzaVRocmVzaG9sZDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0KICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZDsKCiAgICAgICAgLyogRGUtcmVnaXN0ZXIgZXhpc3RpbmcgbG9va3VwIFVQL0RPV04sIFJzc2kgaW5kaWNhdGlvbnMgKi8KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICB7CiAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBzZXNzaW9uSWQsIFJPQU1fU0NBTl9PRkZMT0FEX1VQREFURV9DRkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUFTT05fTE9PS1VQX1RIUkVTSF9DSEFOR0VEKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjLCBzZXNzaW9uSWQpOwoKICAgICAgICAgICAvKiBUaGlzIHVzZXIgY29udGV4dCBkYXRhIHdpbGwgYmUgcmV0dXJuZWQgd2l0aCBjYWxsYmFjayAqLwogICAgICAgICAgIHBVc3JDdHggPSB2b3NfbWVtX21hbGxvYyhzaXplb2YoKnBVc3JDdHgpKTsKICAgICAgICAgICBpZiAoTlVMTCA9PSBwVXNyQ3R4KSB7CiAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlIikpOwogICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfTk9NRU07CiAgICAgICAgICAgfQogICAgICAgICAgIHBVc3JDdHgtPnBNYWMgPSBwTWFjOwogICAgICAgICAgIHBVc3JDdHgtPnNlc3Npb25JZCA9IHNlc3Npb25JZDsKCiAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLAogICAgICAgICAgIEZMKCJSZWdpc3RlcmluZyBuZWlnaGJvciBsb29rdXAgRE9XTiBldmVudCB3aXRoIFRMLCBSU1NJID0gJWQiKSwKICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKTsKCiAgICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBET1dOIGV2ZW50IG9ubHkgKi8KICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwKICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcFVzckN0eCk7CiAgICAgICAgICAgdm9zX21lbV9mcmVlKHBVc3JDdHgpOwogICAgICAgICAgIGlmICghVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpIHsKICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwKICAgICAgICAgICAgICAgRkwoIkZhaWxlZCB0byByZWdpc3RlciBET1dOIGV2ZW50IHdpdGggVEw6IFN0YXR1cyA9ICVkIiksCiAgICAgICAgICAgICAgIHZvc1N0YXR1cyk7CgogICAgICAgICAgICAgIC8qIFJlZ2lzdHJhdGlvbiBmYWlsZWQsIGZyZWUgdGhlIHVzZXIgY29udGV4dCAqLwogICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIH0KI2VuZGlmCiAgICB9CiAgICBlbHNlIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLAogICAgICAgICBGTCgiQ3VycmVudGx5IGluIElOSVQgc3RhdGUsIHNhZmUgdG8gc2V0IGxvb2t1cFJzc2kgdGhyZXNob2xkIikpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgPQogICAgICAgICBuZWlnaGJvckxvb2t1cFJzc2lUaHJlc2hvbGQ7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9CiAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQ7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICAgIEZMKCJVbmV4cGVjdGVkIHN0YXRlICVzLCByZXR1cm5pbmcgZmFpbHVyZSIpLAogICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKVk9TX1NUQVRVUwpjc3JOZWlnaGJvclJvYW1TZXRPcHBvcnR1bmlzdGljU2NhblRocmVzaG9sZERpZmYodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1U4X3Qgbk9wcG9ydHVuaXN0aWNUaHJlc2hvbGREaWZmKQp7CiAgICBWT1NfU1RBVFVTIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CgogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQKICAgICAgICAgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPRzIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiQ3VycmVudGx5IGluIENPTk5FQ1RFRCBzdGF0ZSwgc28gZGVyZWdpc3RlciAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWxsIGFuZCByZS1yZWdpc3RlciBmb3IgRE9XTiBldmVudCBhZ2FpbiIpKTsKCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uT3Bwb3J0dW5pc3RpY1RocmVzaG9sZERpZmYgPQogICAgICAgICAgIG5PcHBvcnR1bmlzdGljVGhyZXNob2xkRGlmZjsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE9wcG9ydHVuaXN0aWNUaHJlc2hvbGREaWZmID0KICAgICAgICAgICBuT3Bwb3J0dW5pc3RpY1RocmVzaG9sZERpZmY7CgogICAgICAgIC8qIERlLXJlZ2lzdGVyIGV4aXN0aW5nIGxvb2t1cCBVUC9ET1dOLCBSc3NpIGluZGljYXRpb25zICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgewogICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJPQU1fU0NBTl9PRkZMT0FEX1VQREFURV9DRkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUFTT05fT1BQT1JUVU5JU1RJQ19USFJFU0hfRElGRl9DSEFOR0VEKTsKICAgICAgICB9CiNlbmRpZgogICAgfQogICAgZWxzZSBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQKICAgICAgICAgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPRzIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiQ3VycmVudGx5IGluIElOSVQgc3RhdGUsIHNhZmUgdG8gc2V0ICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcHBvcnR1bmlzdGljIHRocmVzaG9sZCBkaWZmIikpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubk9wcG9ydHVuaXN0aWNUaHJlc2hvbGREaWZmID0KICAgICAgICAgICAgbk9wcG9ydHVuaXN0aWNUaHJlc2hvbGREaWZmOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50T3Bwb3J0dW5pc3RpY1RocmVzaG9sZERpZmYgPQogICAgICAgICAgICBuT3Bwb3J0dW5pc3RpY1RocmVzaG9sZERpZmY7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9HRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJVbmV4cGVjdGVkIHN0YXRlICVkIHJldHVybmluZyBmYWlsdXJlIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpOwogICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKVk9TX1NUQVRVUwpjc3JOZWlnaGJvclJvYW1TZXRSb2FtUmVzY2FuUnNzaURpZmYodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9VOF90IG5Sb2FtUmVzY2FuUnNzaURpZmYpCnsKICAgIFZPU19TVEFUVVMgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRAogICAgICAgICA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJDdXJyZW50bHkgaW4gQ09OTkVDVEVEIHN0YXRlLCBzbyBkZXJlZ2lzdGVyICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhbGwgYW5kIHJlLXJlZ2lzdGVyIGZvciBET1dOIGV2ZW50IGFnYWluIikpOwoKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5Sb2FtUmVzY2FuUnNzaURpZmYgPQogICAgICAgICAgICBuUm9hbVJlc2NhblJzc2lEaWZmOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50Um9hbVJlc2NhblJzc2lEaWZmID0KICAgICAgICAgICAgblJvYW1SZXNjYW5Sc3NpRGlmZjsKCiAgICAgICAgLyogRGUtcmVnaXN0ZXIgZXhpc3RpbmcgbG9va3VwIFVQL0RPV04sIFJzc2kgaW5kaWNhdGlvbnMgKi8KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICB7CiAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUk9BTV9TQ0FOX09GRkxPQURfVVBEQVRFX0NGRywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9ST0FNX1JFU0NBTl9SU1NJX0RJRkZfQ0hBTkdFRCk7CiAgICAgICAgfQojZW5kaWYKICAgIH0KICAgIGVsc2UgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUCiAgICAgID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT0cyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkN1cnJlbnRseSBpbiBJTklUIHN0YXRlLCBzYWZlIHRvIHNldCByb2FtICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZXNjYW4gcnNzaSBkaWZmIikpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMublJvYW1SZXNjYW5Sc3NpRGlmZiA9CiAgICAgICAgICAgIG5Sb2FtUmVzY2FuUnNzaURpZmY7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnRSb2FtUmVzY2FuUnNzaURpZmYgPSBuUm9hbVJlc2NhblJzc2lEaWZmOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiVW5leHBlY3RlZCBzdGF0ZSAlZCByZXR1cm5pbmcgZmFpbHVyZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KClZPU19TVEFUVVMKY3NyTmVpZ2hib3JSb2FtU2V0Um9hbUJtaXNzRmlyc3RCY250KHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfVThfdCBuUm9hbUJtaXNzRmlyc3RCY250KQp7CiAgICBWT1NfU1RBVFVTIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwoKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVECiAgICAgICAgID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT0cyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkN1cnJlbnRseSBpbiBDT05ORUNURUQgc3RhdGUsIHNvIGRlcmVnaXN0ZXIgYWxsIGFuZCByZS1yZWdpc3RlciBmb3IgRE9XTiBldmVudCBhZ2FpbiIpKTsKCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uUm9hbUJtaXNzRmlyc3RCY250ID0KICAgICAgICAgICAgblJvYW1CbWlzc0ZpcnN0QmNudDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudFJvYW1CbWlzc0ZpcnN0QmNudCA9IG5Sb2FtQm1pc3NGaXJzdEJjbnQ7CgogICAgICAgIC8qIERlLXJlZ2lzdGVyIGV4aXN0aW5nIGxvb2t1cCBVUC9ET1dOLCBSc3NpIGluZGljYXRpb25zICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgewogICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJPQU1fU0NBTl9PRkZMT0FEX1VQREFURV9DRkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUFTT05fUk9BTV9CTUlTU19GSVJTVF9CQ05UX0NIQU5HRUQpOwogICAgICAgIH0KI2VuZGlmCiAgICB9CiAgICBlbHNlIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVAogICAgICA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJDdXJyZW50bHkgaW4gSU5JVCBzdGF0ZSwgc2FmZSB0byBzZXQgcm9hbSByZXNjYW4gcnNzaSBkaWZmIikpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMublJvYW1CbWlzc0ZpcnN0QmNudCA9CiAgICAgICAgICAgIG5Sb2FtQm1pc3NGaXJzdEJjbnQ7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnRSb2FtQm1pc3NGaXJzdEJjbnQgPSBuUm9hbUJtaXNzRmlyc3RCY250OwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiVW5leHBlY3RlZCBzdGF0ZSAlZCByZXR1cm5pbmcgZmFpbHVyZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KClZPU19TVEFUVVMKY3NyTmVpZ2hib3JSb2FtU2V0Um9hbUJtaXNzRmluYWxCY250KHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfVThfdCBuUm9hbUJtaXNzRmluYWxCY250KQp7CiAgICBWT1NfU1RBVFVTIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwoKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVECiAgICAgICAgID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT0cyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkN1cnJlbnRseSBpbiBDT05ORUNURUQgc3RhdGUsIHNvIGRlcmVnaXN0ZXIgYWxsIGFuZCByZS1yZWdpc3RlciBmb3IgRE9XTiBldmVudCBhZ2FpbiIpKTsKCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uUm9hbUJtaXNzRmluYWxCY250ID0KICAgICAgICAgICAgblJvYW1CbWlzc0ZpbmFsQmNudDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudFJvYW1CbWlzc0ZpbmFsQmNudCA9IG5Sb2FtQm1pc3NGaW5hbEJjbnQ7CgogICAgICAgIC8qIERlLXJlZ2lzdGVyIGV4aXN0aW5nIGxvb2t1cCBVUC9ET1dOLCBSc3NpIGluZGljYXRpb25zICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgewogICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUk9BTV9TQ0FOX09GRkxPQURfVVBEQVRFX0NGRywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9ST0FNX0JNSVNTX0ZJTkFMX0JDTlRfQ0hBTkdFRCk7CiAgICAgICAgfQojZW5kaWYKICAgIH0KICAgIGVsc2UgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUCiAgICAgID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT0cyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkN1cnJlbnRseSBpbiBJTklUIHN0YXRlLCBzYWZlIHRvIHNldCAgcm9hbSByZXNjYW4gcnNzaSBkaWZmIikpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMublJvYW1CbWlzc0ZpbmFsQmNudCA9CiAgICAgICAgICAgIG5Sb2FtQm1pc3NGaW5hbEJjbnQ7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnRSb2FtQm1pc3NGaW5hbEJjbnQgPSBuUm9hbUJtaXNzRmluYWxCY250OwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiVW5leHBlY3RlZCBzdGF0ZSAlZCByZXR1cm5pbmcgZmFpbHVyZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KClZPU19TVEFUVVMKY3NyTmVpZ2hib3JSb2FtU2V0Um9hbUJlYWNvblJzc2lXZWlnaHQodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9VOF90IG5Sb2FtQmVhY29uUnNzaVdlaWdodCkKewogICAgVk9TX1NUQVRVUyB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRAogICAgICAgICA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJDdXJyZW50bHkgaW4gQ09OTkVDVEVEIHN0YXRlLCBzbyBkZXJlZ2lzdGVyIGFsbCBhbmQgcmUtcmVnaXN0ZXIgZm9yIERPV04gZXZlbnQgYWdhaW4iKSk7CgogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMublJvYW1CZWFjb25Sc3NpV2VpZ2h0ID0KICAgICAgICAgICAgblJvYW1CZWFjb25Sc3NpV2VpZ2h0OwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50Um9hbUJlYWNvblJzc2lXZWlnaHQgPSBuUm9hbUJlYWNvblJzc2lXZWlnaHQ7CgogICAgICAgIC8qIERlLXJlZ2lzdGVyIGV4aXN0aW5nIGxvb2t1cCBVUC9ET1dOLCBSc3NpIGluZGljYXRpb25zICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgewogICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUk9BTV9TQ0FOX09GRkxPQURfVVBEQVRFX0NGRywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9ST0FNX0JFQUNPTl9SU1NJX1dFSUdIVF9DSEFOR0VEKTsKICAgICAgICB9CiNlbmRpZgogICAgfQogICAgZWxzZSBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQKICAgICAgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPRzIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiQ3VycmVudGx5IGluIElOSVQgc3RhdGUsIHNhZmUgdG8gc2V0IHJvYW0gcmVzY2FuIHJzc2kgZGlmZiIpKTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5Sb2FtQmVhY29uUnNzaVdlaWdodCA9CiAgICAgICAgICAgIG5Sb2FtQmVhY29uUnNzaVdlaWdodDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudFJvYW1CZWFjb25Sc3NpV2VpZ2h0ID0KICAgICAgICAgICAgblJvYW1CZWFjb25Sc3NpV2VpZ2h0OwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiVW5leHBlY3RlZCBzdGF0ZSAlZCByZXR1cm5pbmcgZmFpbHVyZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjawoKICAgIFxicmllZiBSZWFzc29jIGNhbGxiYWNrIGludm9rZWQgYnkgVEwgb24gY3Jvc3NpbmcgdGhlIHJlZ2lzdGVyZWQgcmUtYXNzb2MgdGhyZXNob2xkLgogICAgICAgICAgIERpcmVjdGx5IHRyaWdnZXIgSE8gaW4gY2FzZSBvZiBub24tMTFyIGFzc29jaWF0aW9uCiAgICAgICAgICAgSW4gY2FzZSBvZiAxMVIgYXNzb2NpYXRpb24sIHRyaWdnZXJzIGEgcHJlLWF1dGggZXZlbnR1YWxseSBmb2xsb3dlZCBieSBhY3R1YWwgSE8KCiAgICBccGFyYW0gIHBBZGFwdGVyIC0gVk9TIENvbnRleHQKICAgICAgICAgICAgdHJhZmZpY1N0YXR1cyAtIFVQL0RPV04gaW5kaWNhdGlvbiBmcm9tIFRMCiAgICAgICAgICAgIHBVc2VyQ3R4dCAtIFBhcmFtZXRlciBmb3IgY2FsbGJhY2sgcmVnaXN0ZXJlZCBkdXJpbmcgY2FsbGJhY2sgcmVnaXN0cmF0aW9uLiBTaG91bGQgYmUgcE1hYwoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sodl9QVk9JRF90IHBBZGFwdGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9VOF90IHRyYWZmaWNTdGF0dXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1BWT0lEX3QgcFVzZXJDdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9TN190ICAgYXZnUnNzaSkKewogICAgdEZUUm9hbUNhbGxiYWNrVXNyQ3R4ICpwVXNyQ3R4ID0gKHRGVFJvYW1DYWxsYmFja1VzckN0eCAqKXBVc2VyQ3R4dDsKICAgIHRBTklfVTggICAgc2Vzc2lvbklkID0gcFVzckN0eC0+c2Vzc2lvbklkOwogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IHBVc3JDdHgtPnBNYWM7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgVk9TX1NUQVRVUyB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CgogICAgaWYgKGVTTUVfUk9BTV9UUklHR0VSX0ZBU1RfUk9BTSAhPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgICAgIEZMKCJEZXJlZ2lzdGVyaW5nIERPV04gZXZlbnQgcmVhc3NvYyBjYWxsYmFjayB3aXRoIFRMLiAiCiAgICAgICAgICAgICAgICAgICAiVGhyZXNob2xkIFJTU0kgPSAlZCBSZXBvcnRlZCBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgIGF2Z1Jzc2kpOwoKICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CgogICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgIH0KCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmN2ZCByZWFzc29jIG5vdGlmaWNhdGlvbi1kZXJlZ2lzdGVyIFVQIGluZGljYXRpb24uIFRocmVzaG9sZCBSU1NJID0gJWQgUmVwb3J0ZWQgUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpLCBhdmdSc3NpKTsKICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9VUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CgogICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgewogICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IGRlcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICB9CiAgICB9CiAgICAvKiBXZSBkb250IG5lZWQgdG8gcnVuIHRoaXMgdGltZXIgYW55IG1vcmUuICovCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CgogICAgY3NyTmVpZ2hib3JSb2FtVHJpZ2dlckhhbmRvZmYocE1hYywgc2Vzc2lvbklkKTsKICAgIHZvc19tZW1fZnJlZShwVXNyQ3R4KTsKCiAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKkNsZWFuVVAgUm91dGluZXMqLwpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldENoYW5uZWxJbmZvKHRwQ3NyTmVpZ2hib3JSb2FtQ2hhbm5lbEluZm8gckNoSW5mbykKewogICAgICAgIGlmICgockNoSW5mby0+SUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID09IEZBTFNFKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAockNoSW5mby0+Y3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzKSkKICAgICAgICB7CiAgICAgICAgICAgICAgICByQ2hJbmZvLT5jdXJyZW50Q2hhbkluZGV4ID0gQ1NSX05FSUdIQk9SX1JPQU1fSU5WQUxJRF9DSEFOTkVMX0lOREVYOwogICAgICAgICAgICAgICAgckNoSW5mby0+Y3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKCiAgICAgICAgICAgICAgICBpZiAockNoSW5mby0+Y3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCkKICAgICAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHJDaEluZm8tPmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwoKICAgICAgICAgICAgICAgIHJDaEluZm8tPmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgckNoSW5mby0+Y2hhbkxpc3RTY2FuSW5Qcm9ncmVzcyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgICAgIHJDaEluZm8tPmN1cnJlbnRDaGFuSW5kZXggPSAwOwogICAgICAgICAgICAgICAgckNoSW5mby0+Y2hhbkxpc3RTY2FuSW5Qcm9ncmVzcyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgIH0KfQoKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRDZmdMaXN0Q2hhblNjYW5Db250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKCiAgICAvKiBTdG9wIG5laWdoYm9yIHNjYW4gdGltZXIgKi8KICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwoKICAgIC8qIFN0b3AgbmVpZ2hib3Igc2NhbiByZXN1bHRzIHJlZnJlc2ggdGltZXIgKi8KICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKCiAgICAvKiBTdG9wIGVtcHR5IHNjYW4gcmVzdWx0cyByZWZyZXNoIHRpbWVyICovCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CgogICAgLyogQWJvcnQgYW55IG9uZ29pbmcgc2NhbiAqLwogICAgaWYgKGVBTklfQk9PTEVBTl9UUlVFID09IHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUnNwUGVuZGluZykKICAgIHsKICAgICAgICBjc3JTY2FuQWJvcnRNYWNTY2FuKHBNYWMsIHNlc3Npb25JZCwgZUNTUl9TQ0FOX0FCT1JUX0RFRkFVTFQpOwogICAgfQogICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIC8qIFJlc2V0IHJvYW0gY2hhbm5lbCBsaXN0IGluZm9ybWF0aW9uICovCiAgICBjc3JOZWlnaGJvclJvYW1SZXNldENoYW5uZWxJbmZvKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvKTsKfQoKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRQcmVhdXRoQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKCiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9FU0UpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgLyogUHVyZ2UgcHJlLWF1dGggZmFpbCBsaXN0ICovCiAgICBjc3JOZWlnaGJvclJvYW1QdXJnZVByZWF1dGhGYWlsZWRMaXN0KHBNYWMpOwojZW5kaWYKCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVhdXRoUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzID0gMDsKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAvKiBEbyBub3QgZnJlZSB1cCB0aGUgcHJlYXV0aCBkb25lIGxpc3QgaGVyZSAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKICAgIHZvc19tZW1femVybyhwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mbywKICAgICAgICAgICAgICAgICBzaXplb2YodENzck5laWdoYm9yUmVwb3J0QnNzSW5mbykgKiBNQVhfQlNTX0lOX05FSUdIQk9SX1JQVCk7CiNlbmRpZgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICB2b3NfbWVtX3plcm8oJnBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mbywKICAgICAgICAgICAgICAgICBzaXplb2YodENzckhhbmRvZmZSZXF1ZXN0KSk7CiNlbmRpZgp9CgpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQpCnsKICAgICAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CiAgICAgICAgVk9TX1NUQVRVUyAgICAgICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwoKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsCiAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJEZXJlZ2lzdGVyIG5laWdoYm9yIGxvb2t1cCBVUCBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSk7CgogICAgICAgIC8qIERlcmVnaXN0ZXIgcmVhc3NvYyBjYWxsYmFjay4gSWdub3JlIHJldHVybiBzdGF0dXMgKi8KICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9VUCwKICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CgogICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiQ291bGRuJ3QgZGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICB2b3NTdGF0dXMpOwogICAgICAgIH0KCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLAogICAgICAgICAgICAgICAgICAgICAgICBGTCgiRGVyZWdpc3RlcmluZyByZWFzc29jIERPV04gY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkICogKC0xKSk7CgogICAgICAgIC8qIERlcmVnaXN0ZXIgcmVhc3NvYyBjYWxsYmFjay4gSWdub3JlIHJldHVybiBzdGF0dXMgKi8KICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwoKICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgICAgICAgRkwoIiBDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgIHZvc1N0YXR1cyk7CiAgICAgICAgfQoKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsCiAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJEZXJlZ2lzdGVyaW5nIG5laWdoYm9yTG9va3VwIERPV04gY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpKTsKCiAgICAgICAgLyogRGVyZWdpc3RlciBuZWlnaGJvciBsb29rdXAgY2FsbGJhY2suIElnbm9yZSByZXR1cm4gc3RhdHVzICovCiAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX0RlcmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CgogICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywKICAgICAgICAgICAgICAgICAgICAgICBGTCgiIENvdWxkbid0IGRlcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICB2b3NTdGF0dXMpOwogICAgICAgIH0KCiAgICAgICAgLyogUmVzZXQgdGhyZXNob2xkcyBvbmx5IGFmdGVyIGRlcmVnaXN0ZXJpbmcgRE9XTiBldmVudCBmcm9tIFRMICovCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50T3Bwb3J0dW5pc3RpY1RocmVzaG9sZERpZmYgPQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uT3Bwb3J0dW5pc3RpY1RocmVzaG9sZERpZmY7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnRSb2FtUmVzY2FuUnNzaURpZmYgPQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uUm9hbVJlc2NhblJzc2lEaWZmOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50Um9hbUJtaXNzRmlyc3RCY250ID0KICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMublJvYW1CbWlzc0ZpcnN0QmNudDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudFJvYW1CbWlzc0ZpbmFsQmNudCA9CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5Sb2FtQm1pc3NGaW5hbEJjbnQ7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnRSb2FtQmVhY29uUnNzaVdlaWdodCA9CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5Sb2FtQmVhY29uUnNzaVdlaWdodDsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gMDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUgPSBERUZBVUxUX1NDQU47CiNlbmRpZgp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHdpbGwgcmVzZXQgdGhlIG5laWdoYm9yIHJvYW0gY29udHJvbCBpbmZvIGRhdGEgc3RydWN0dXJlcy4KICAgICAgICAgICAgVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgaW52b2tlZCB3aGVuZXZlciB3ZSBtb3ZlIHRvIENPTk5FQ1RFRCBzdGF0ZSBmcm9tCiAgICAgICAgICAgIGFueSBzdGF0ZSBvdGhlciB0aGFuIElOSVQgc3RhdGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHNlc3Npb25JZCAtIHNlc3Npb24gaWQKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwoKICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q2hhbm5lbEluZm8oJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8pOwogICAgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdChwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsKCiAvKiBXZSBkb250IG5lZWQgdG8gcnVuIHRoaXMgdGltZXIgYW55IG1vcmUuICovCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIC8qIERvIG5vdCBmcmVlIHVwIHRoZSBwcmVhdXRoIGRvbmUgbGlzdCBoZXJlICovCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlYXV0aFJzcFBlbmRpbmcgPSAwOwogICAgdm9zX21lbV96ZXJvKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvLAogICAgICAgICAgICAgICAgIHNpemVvZih0Q3NyTmVpZ2hib3JSZXBvcnRCc3NJbmZvKSAqIE1BWF9CU1NfSU5fTkVJR0hCT1JfUlBUKTsKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgIHZvc19tZW1femVybygmcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLAogICAgICAgICAgICAgICAgIHNpemVvZih0Q3NySGFuZG9mZlJlcXVlc3QpKTsKI2VuZGlmCn0KCnZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRSZXBvcnRTY2FuU3RhdGVDb250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwoKICAgIHZvc19tZW1fc2V0KHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgc2l6ZW9mKHRDc3JCc3NpZCksIDApOwogICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVySW5mby5wTWFjID0gcE1hYzsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lckluZm8uc2Vzc2lvbklkID0gQ1NSX1NFU1NJT05fSURfSU5WQUxJRDsKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmlzVk9BZG1pdHRlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5NaW5RQnNzTG9hZFJlcXVpcmVkID0gMDsKI2VuZGlmCgogICAgLyogU3RvcCBzY2FuIHJlZnJlc2ggdGltZXIgKi8KICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgIC8qIFN0b3AgZW1wdHkgc2NhbiByZXN1bHRzIHJlZnJlc2ggdGltZXIgKi8KICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgIC8qIFB1cmdlIHJvYW0gYWJsZSBBUCBsaXN0ICovCiAgICBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUmVzZXRJbml0U3RhdGVDb250cm9sSW5mbwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiB3aWxsIHJlc2V0IHRoZSBuZWlnaGJvciByb2FtIGNvbnRyb2wgaW5mbyBkYXRhIHN0cnVjdHVyZXMuCiAgICAgICAgICAgIFRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIGludm9rZWQgd2hlbmV2ZXIgd2UgbW92ZSB0byBDT05ORUNURUQgc3RhdGUgZnJvbQogICAgICAgICAgICBJTklUIHN0YXRlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgXHBhcmFtICBzZXNzaW9uSWQgLSBTZXNzaW9uIElkCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0SW5pdFN0YXRlQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8ocE1hYywgc2Vzc2lvbklkKTsKCiAgICAvKiBJbiBhZGRpdGlvbiB0byB0aGUgYWJvdmUgcmVzZXRzLAogICAgICAgd2Ugc2hvdWxkIGNsZWFyIG9mZiB0aGUgY3VyQVBCc3NJZC9TZXNzaW9uIElEIGluIHRoZSB0aW1lcnMgKi8KICAgIGNzck5laWdoYm9yUm9hbVJlc2V0UmVwb3J0U2NhblN0YXRlQ29udHJvbEluZm8ocE1hYywgc2Vzc2lvbklkKTsKfQoKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtQnNzSWRTY2FuRmlsdGVyCgogICAgXGJyaWVmICBUaGlzIEFQSSBpcyB1c2VkIHRvIHByZXBhcmUgYSBmaWx0ZXIgdG8gb2J0YWluIHNjYW4gcmVzdWx0cyB3aGVuCiAgICAgICAgICAgIHdlIGNvbXBsZXRlIHRoZSBzY2FuIGluIHRoZSBSRVBPUlRfU0NBTiBzdGF0ZSBhZnRlciByZWNlaXZpbmcgYQogICAgICAgICAgICB2YWxpZCBuZWlnaGJvciByZXBvcnQgZnJvbSBBUC4gVGhpcyBmaWx0ZXIgaW5jbHVkZXMgQlNTSURzIHJlY2VpdmVkIGZyb20KICAgICAgICAgICAgdGhlIG5laWdoYm9yIHJlcG9ydCBmcm9tIHRoZSBBUCBpbiBhZGRpdGlvbiB0byB0aGUgb3RoZXIgZmlsdGVyIHBhcmFtZXRlcnMKICAgICAgICAgICAgY3JlYXRlZCBmcm9tIGNvbm5lY3RlZCBwcm9maWxlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwU2NhbkZpbHRlciAtIFNjYW4gZmlsdGVyIHRvIGJlIGZpbGxlZCBhbmQgcmV0dXJuZWQKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2Vzc2Z1bCBmaWx0ZXIgY3JlYXRpb24sIGNvcnJlc3BvbmRpbmcKICAgICAgICAgICAgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUJzc0lkU2NhbkZpbHRlcih0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0Q3NyU2NhblJlc3VsdEZpbHRlciAqcFNjYW5GaWx0ZXIpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgdEFOSV9VOCBpID0gMDsKCiAgICBWT1NfQVNTRVJUKHBTY2FuRmlsdGVyICE9IE5VTEwpOwogICAgaWYgKHBTY2FuRmlsdGVyID09IE5VTEwpCiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB2b3NfbWVtX3plcm8ocFNjYW5GaWx0ZXIsIHNpemVvZih0Q3NyU2NhblJlc3VsdEZpbHRlcikpOwoKICAgIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMgPSBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQ7CiAgICBwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwogICAgaWYgKE5VTEwgPT0gcFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZCkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlNjYW4gRmlsdGVyIEJTU0lEIG1lbSBhbGxvYyBmYWlsZWQiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxFRF9BTExPQzsKICAgIH0KCiAgICB2b3NfbWVtX3plcm8ocFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwoKICAgIC8qIFBvcHVsYXRlIHRoZSBCU1NJRCBmcm9tIE5laWdoYm9yIEJTUyBpbmZvIHJlY2VpdmVkIGZyb20gbmVpZ2hib3IgcmVwb3J0ICovCiAgICBmb3IgKGkgPSAwOyBpIDwgcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEczsgaSsrKSB7CiAgICAgICAgdm9zX21lbV9jb3B5KCZwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkW2ldLAogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mb1tpXS5uZWlnaGJvckJzc0lkLAogICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgIH0KCiAgICAvKiBGaWxsIG90aGVyIGdlbmVyYWwgc2NhbiBmaWx0ZXIgcGFyYW1zICovCiAgICByZXR1cm4gY3NyTmVpZ2hib3JSb2FtUHJlcGFyZVNjYW5Qcm9maWxlRmlsdGVyKHBNYWMsIHBTY2FuRmlsdGVyLCBzZXNzaW9uSWQpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbExpc3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gZW1wdGllcyB0aGUgcHJlYXV0aCBmYWlsIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxMaXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRBTklfVTggaTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gIHBOZWlnaGJvclJvYW1JbmZvID0gTlVMTDsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJQdXJnaW5nIHRoZSBwcmVhdXRoIGZhaWwgbGlzdCIpKTsKICAgIGZvciAoaSA9IDA7IGkgPCBDU1JfUk9BTV9TRVNTSU9OX01BWDsgaSsrKSB7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW2ldOwogICAgICAgIHdoaWxlIChwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcykgewogICAgICAgICAgICB2b3NfbWVtX3plcm8ocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm1hY0FkZHJlc3NbcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MtMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MtLTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1BZGRCc3NJZFRvUHJlYXV0aEZhaWxMaXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGFkZHMgdGhlIGdpdmVuIEJTU0lEIHRvIHRoZSBQcmVhdXRoIGZhaWwgbGlzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgYnNzSWQgLSBCU1NJRCB0byBiZSBhZGRlZCB0byB0aGUgcHJlYXV0aCBmYWlsIGxpc3QKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgZUhBTF9TVEFUVVNfRkFJTFVSRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtQWRkQnNzSWRUb1ByZWF1dGhGYWlsTGlzdCh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0U2lyTWFjQWRkciBic3NJZCkKewogICAgdEFOSV9VOCBpID0gMDsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiQWRkZWQgQlNTSUQgIk1BQ19BRERSRVNTX1NUUgogICAgICAgICAgICAgICAgICAgICAgICAiIHRvIFByZWF1dGggZmFpbGVkIGxpc3QiKSwgTUFDX0FERFJfQVJSQVkoYnNzSWQpKTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3M7CiAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICBpZiAoVk9TX1RSVUUgPT0gdm9zX21lbV9jb21wYXJlKAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5tYWNBZGRyZXNzW2ldLAogICAgICAgICAgICAgICAgICAgIGJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKSkgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIkJTU0lEICJNQUNfQUREUkVTU19TVFIiIGFscmVhZHkgcHJlc2VudCBpbiBwcmVhdXRoIGZhaWwgbGlzdCIpLAogICAgICAgICAgICAgICAgICAgTUFDX0FERFJfQVJSQVkoYnNzSWQpKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfQogICAgfQoKICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MgKyAxKSA+CiAgICAgICAgICAgIE1BWF9OVU1fUFJFQVVUSF9GQUlMX0xJU1RfQUREUkVTUykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlByZWF1dGggZmFpbCBsaXN0IGFscmVhZHkgZnVsbC4uIENhbm5vdCBhZGQgbmV3IG9uZSIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIHZvc19tZW1fY29weShwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubWFjQWRkcmVzc1sKICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzc10sCiAgICAgICAgICAgICAgICAgYnNzSWQsCiAgICAgICAgICAgICAgICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcysrOwoKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXNQcmVhdXRoQ2FuZGlkYXRlCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGNoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBNQUMgYWRkcmVzcyBpcyBhbHJlYWR5CiAgICAgICAgICAgIHByZXNlbnQgaW4gdGhlIHByZWF1dGggZmFpbCBsaXN0IGFuZCByZXR1cm5zIFRSVUUvRkFMU0UgYWNjb3JkaW5nbHkKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRSBpZiBwcmVhdXRoIGNhbmRpZGF0ZSwgZUFOSV9CT09MRUFOX0ZBTFNFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUlzUHJlYXV0aENhbmRpZGF0ZSh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRTaXJNYWNBZGRyIGJzc0lkKQp7CiAgICB0QU5JX1U4IGkgPSAwOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgaWYgKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICB7CiAgICAgICAgcmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFOwogICAgfQojZW5kaWYKICAgIGlmICgwID09IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzKQogICAgICAgIHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3M7IGkrKykKICAgIHsKICAgICAgICBpZiAoVk9TX1RSVUUgPT0gdm9zX21lbV9jb21wYXJlKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5tYWNBZGRyZXNzW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgIGJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKSkKICAgICAgICB7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkJTU0lEICJNQUNfQUREUkVTU19TVFIiIGFscmVhZHkgcHJlc2VudCBpbiBwcmVhdXRoIGZhaWwgbGlzdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShic3NJZCkpOwogICAgICAgICAgICByZXR1cm4gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gZUFOSV9CT09MRUFOX1RSVUU7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXNzdWVzIHByZWF1dGggcmVxdWVzdCB0byBQRSB3aXRoIHRoZSAxc3QgQVAgZW50cnkgaW4gdGhlCiAgICAgICAgICAgIHJvYW0gYWJsZSBBUCBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBlSEFMX1NUQVRVU19GQUlMVVJFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyAgICBwTmVpZ2hib3JCc3NOb2RlOwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlJfTUVUUklDUwogICAgdENzclJvYW1JbmZvICpyb2FtSW5mbzsKI2VuZGlmCgogICAgaWYgKGVBTklfQk9PTEVBTl9GQUxTRSAhPSBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVhdXRoUnNwUGVuZGluZykKICAgIHsKICAgICAgIC8qIFRoaXMgbXVzdCBub3QgYmUgdHJ1ZSBoZXJlICovCiAgICAgICBWT1NfQVNTRVJUKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nID09IGVBTklfQk9PTEVBTl9GQUxTRSk7CiAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KCiAgICAvKiBJc3N1ZSBQcmVhdXRoIHJlcXVlc3QgdG8gUEUgaGVyZSAqLwogICAgLyoKICAgICAqIE5lZWQgdG8gaXNzdWUgdGhlIHByZWF1dGggcmVxdWVzdCB3aXRoIHRoZSBCU1NJRCB0aGF0IGlzIHRoZXJlIGluIHRoZQogICAgICogaGVhZCBvZiB0aGUgcm9hbSBhYmxlIEFQIGxpc3QKICAgICAqIFBhcmFtZXRlcnMgdGhhdCBzaG91bGQgYmUgcGFzc2VkIGFyZSBCU1NJRCwgQ2hhbm5lbCBudW1iZXIgYW5kIHRoZQogICAgICogbmVpZ2hib3JTY2FuUGVyaW9kKHByb2JhYmx5KQogICAgICogSWYgcm9hbWFibGVBUExpc3QgZ2V0cyBlbXB0eSwgc2hvdWxkIHRyYW5zaXRpb24gdG8gUkVQT1JUX1NDQU4gc3RhdGUKICAgICAqLwogICAgcE5laWdoYm9yQnNzTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsIE5VTEwpOwoKICAgIGlmIChOVUxMID09IHBOZWlnaGJvckJzc05vZGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJSb2FtYWJsZSBBUCBsaXN0IGlzIGVtcHR5Li4gIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgZWxzZQogICAgewojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICAgICAgLyogTEZSIG1ldHJpY3MgLSBwcmUtYXV0aCBpbml0aWF0aW9uIG1ldHJpYy4KICAgICAgICAgICBTZW5kIHRoZSBldmVudCB0byBzdXBwbGljYW50IHRoYXQgcHJlLWF1dGggd2FzIGluaXRpYXRlZCAqLwogICAgICAgIHJvYW1JbmZvID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgICAgIGlmIChOVUxMID09IHJvYW1JbmZvKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQhIikpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2NvcHkoKHZvaWQgKilyb2FtSW5mby0+YnNzaWQsCiAgICAgICAgICAgICAgICAodm9pZCAqKXBOZWlnaGJvckJzc05vZGUtPnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQsCiAgICAgICAgICAgICAgICBzaXplb2YodENzckJzc2lkKSk7CiAgICAgICAgICAgIGNzclJvYW1DYWxsQ2FsbGJhY2socE1hYywgc2Vzc2lvbklkLCByb2FtSW5mbywgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX1JPQU1fUFJFQVVUSF9JTklUX05PVElGWSwgMCk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShyb2FtSW5mbyk7CiAgICAgICAgfQojZW5kaWYKCiAgICAgICAgc3RhdHVzID0gY3NyUm9hbUVucXVldWVQcmVhdXRoKHBNYWMsIHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ3NyUGVyZm9ybVByZWF1dGgsIGVBTklfQk9PTEVBTl9UUlVFKTsKCiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJCZWZvcmUgUHJlLUF1dGg6IEJTU0lEICJNQUNfQUREUkVTU19TVFIiLCBDaDolZCIpLAogICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmJzc0lkKSwKICAgICAgICAgICAgICAgKGludClwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmNoYW5uZWxJZCk7CgogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2VuZCBQcmVhdXRoIHJlcXVlc3QgdG8gUEUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIHN0YXR1cyk7CiAgICAgICAgICAgIHJldHVybiBzdGF0dXM7CiAgICAgICAgfQogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX1RSVUU7CgogICAgLyogSW5jcmVtZW50IHRoZSBwcmVhdXRoIHJldHJ5IGNvdW50ICovCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcysrOwoKICAgIC8qIFRyYW5zaXRpb24gdGhlIHN0YXRlIHRvIHByZWF1dGhlbnRpY2F0aW5nICovCiAgICBjc3JfbmVpZ2hib3Jfcm9hbV9zdGF0ZV90cmFuc2l0aW9uKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwoKICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1QcmVhdXRoUnNwSGFuZGxlcgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBoYW5kbGUgdGhlIFByZWF1dGggcmVzcG9uc2UgZnJvbSBQRQogICAgICAgICAgICBFdmVyeSBwcmVhdXRoIGlzIGFsbG93ZWQgbWF4IDMgdHJpZXMgaWYgaXQgZmFpbHMuIElmIGEgYnNzaWQgZmFpbGVkCiAgICAgICAgICAgIGZvciBtb3JlIHRoYW4gTUFYX1RSSUVTLCB3ZSB3aWxsIHJlbW92ZSBpdCBmcm9tIHRoZSBsaXN0IGFuZCB0cnkKICAgICAgICAgICAgd2l0aCB0aGUgbmV4dCBub2RlIGluIHRoZSByb2FtIGFibGUgQVAgbGlzdCBhbmQgYWRkIHRoZSBCU1NJRAogICAgICAgICAgICB0byBwcmUtYXV0aCBmYWlsZWQgbGlzdC4gSWYgbm8gbW9yZSBlbnRyaWVzIHByZXNlbnQgaW4KICAgICAgICAgICAgcm9hbSBhYmxlIEFQIGxpc3QsIHRyYW5zaXRpb24gdG8gUkVQT1JUX1NDQU4gc3RhdGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIGxpbVN0YXR1cyAtIGVTSVJfU1VDQ0VTUy9lU0lSX0ZBSUxVUkUvZVNJUl9MSU1fTUFYX1NUQV9SRUFDSEVEX0VSUk9SLwogICAgICAgICAgICAgICAgICAgICBlU0lUX0xJTV9BVVRIX1JTUF9USU1FT1VUIHN0YXR1cyBmcm9tIFBFCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MgKGkuZS4gcHJlLWF1dGggcHJvY2Vzc2VkKSwKICAgICAgICAgICAgZUhBTF9TVEFUVVNfRkFJTFVSRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUHJlYXV0aFJzcEhhbmRsZXIodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0U2lyUmV0U3RhdHVzIGxpbVN0YXR1cykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIFZPU19TVEFUVVMgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIGVIYWxTdGF0dXMgIHByZWF1dGhQcm9jZXNzZWQgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBQcmVhdXRoUnNwTm9kZSA9IE5VTEw7CiAgICB0cEZUUm9hbUNhbGxiYWNrVXNyQ3R4IHBVc3JDdHg7CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICB0Q3NyUm9hbUluZm8gKnJvYW1JbmZvOwojZW5kaWYKCiAgICBpZiAoZUFOSV9CT09MRUFOX0ZBTFNFID09IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nKQogICAgewoKICAgICAgICAgICAgLyogVGhpcyBjYW4gaGFwcGVuIHdoZW4gd2UgZGlzY29ubmVjdCBpbW1lZGlhdGVseQogICAgICAgICAgICAgKiBhZnRlciBzZW5kaW5nIGEgcHJlLWF1dGggcmVxdWVzdC4gRHVyaW5nIHByb2Nlc3NpbmcKICAgICAgICAgICAgICogb2YgdGhlIGRpc2Nvbm5lY3QgY29tbWFuZCwgd2Ugd291bGQgaGF2ZSByZXNldAogICAgICAgICAgICAgKiBwcmVhdXRoUnNwUGVuZGluZyBhbmQgdHJhbnNpdGlvbmVkIHRvIElOSVQgc3RhdGUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIlVuZXhwZWN0ZWQgcHJlLWF1dGggcmVzcG9uc2UgaW4gc3RhdGUgJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpOwogICAgICAgICAgICBwcmVhdXRoUHJvY2Vzc2VkID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgZ290byBERVFfUFJFQVVUSDsKICAgIH0KCiAgICAvLyBXZSBjYW4gcmVjZWl2ZSBpdCBpbiB0aGVzZSAyIHN0YXRlcy4KICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlICE9IGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIRU5USUNBVElORykgJiYKICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlICE9IGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTikpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIlByZWF1dGggcmVzcG9uc2UgcmVjZWl2ZWQgaW4gc3RhdGUgJXMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVhdXRoUHJvY2Vzc2VkID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICBnb3RvIERFUV9QUkVBVVRIOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIGlmIChlU0lSX1NVQ0NFU1MgPT0gbGltU3RhdHVzKQogICAgewogICAgICAgIHBQcmVhdXRoUnNwTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQogICAgaWYgKChlU0lSX1NVQ0NFU1MgPT0gbGltU3RhdHVzKSAmJiAoTlVMTCAhPSBwUHJlYXV0aFJzcE5vZGUpKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIlByZWF1dGggY29tcGxldGVkIHN1Y2Nlc3NmdWxseSBhZnRlciAlZCB0cmllcyIpLCBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyk7CgogICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiQWZ0ZXIgUHJlLUF1dGg6IEJTU0lEICJNQUNfQUREUkVTU19TVFIiLCBDaDolZCIpLAogICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShwUHJlYXV0aFJzcE5vZGUtPnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQpLAogICAgICAgICAgICAgICAoaW50KXBQcmVhdXRoUnNwTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsSWQpOwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlJfTUVUUklDUwogICAgICAgIC8qIExGUiBtZXRyaWNzIC0gcHJlLWF1dGggY29tcGxldGlvbiBtZXRyaWMuCiAgICAgICAgICAgU2VuZCB0aGUgZXZlbnQgdG8gc3VwcGxpY2FudCB0aGF0IHByZS1hdXRoIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgKi8KICAgICAgICByb2FtSW5mbyA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyUm9hbUluZm8pKTsKICAgICAgICBpZiAoTlVMTCA9PSByb2FtSW5mbykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZmFpbGVkISIpKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9jb3B5KCh2b2lkICopcm9hbUluZm8tPmJzc2lkLAogICAgICAgICAgICAgICAgKHZvaWQgKilwUHJlYXV0aFJzcE5vZGUtPnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQsCiAgICAgICAgICAgICAgICBzaXplb2YodENzckJzc2lkKSk7CiAgICAgICAgICAgIGNzclJvYW1DYWxsQ2FsbGJhY2socE1hYywgc2Vzc2lvbklkLCByb2FtSW5mbywgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX1JPQU1fUFJFQVVUSF9TVEFUVVNfU1VDQ0VTUywgMCk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShyb2FtSW5mbyk7CiAgICAgICAgfQojZW5kaWYKCiAgICAgICAgLyogUHJlYXV0aCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5LiBJbnNlcnQgdGhlIHByZWF1dGhlbnRpY2F0ZWQKICAgICAgICAgICBub2RlIHRvIHRhaWwgb2YgcHJlQXV0aERvbmVMaXN0ICovCiAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVtb3ZlUm9hbWFibGVBUExpc3RFbnRyeShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0LCBwUHJlYXV0aFJzcE5vZGUpOwogICAgICAgIGNzckxMSW5zZXJ0VGFpbCgmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0LCAmcFByZWF1dGhSc3BOb2RlLT5MaXN0LCBMTF9BQ0NFU1NfTE9DSyk7CgogICAgICAgIC8qIFByZS1hdXRoIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkuIFRyYW5zaXRpb24gdG8gUFJFQVVUSCBEb25lIHN0YXRlICovCiAgICAgICAgY3NyX25laWdoYm9yX3JvYW1fc3RhdGVfdHJhbnNpdGlvbihwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSF9ET05FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzID0gMDsKCiAgICAgICAgLyoKICAgICAgICAgKiBUaGUgY2FsbGVyIG9mIHRoaXMgZnVuY3Rpb24gd291bGQgc3RhcnQgYSB0aW1lciBhbmQgYnkgdGhlIHRpbWUgaXQKICAgICAgICAgKiBleHBpcmVzLCBzdXBwbGljYW50IHNob3VsZCBoYXZlIHByb3ZpZGVkIHRoZSB1cGRhdGVkIEZUSUVzIHRvIFNNRS4KICAgICAgICAgKiBTbywgd2hlbiBpdCBleHBpcmVzLCBoYW5kb2ZmIHdpbGwgYmUgdHJpZ2dlcmVkIHRoZW4KICAgICAgICAgKi8KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gICAgcE5laWdoYm9yQnNzTm9kZSA9IE5VTEw7CiAgICAgICAgdExpc3RFbGVtICAgICAgICAgICAgICAgICAgICpwRW50cnk7CiAgICAgICAgYm9vbCBpc19kaXNfcGVuZGluZyA9IGZhbHNlOwogICAgICAgIHVpbnQzMl90ICAgICAgICAgICAgICAgICAgICByZXRyaWVzOwoKICAgICAgICByZXRyaWVzID0gcE1hYy0+c3RhX2F1dGhfcmV0cmllc19mb3JfY29kZTE3ID4KICAgICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fTUFYX05VTV9QUkVBVVRIX1JFVFJJRVMgPwogICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5zdGFfYXV0aF9yZXRyaWVzX2Zvcl9jb2RlMTcgOgogICAgICAgICAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9NQVhfTlVNX1BSRUFVVEhfUkVUUklFUzsKCiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJQcmVhdXRoIGZhaWxlZCByZXRyeSBudW1iZXIgJWQsIHN0YXR1cyA9IDB4JXgiKSwKICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMsIGxpbVN0YXR1cyk7CgogICAgICAgIC8qIFByZWF1dGggZmFpbGVkLiBBZGQgdGhlIGJzc0lkIHRvIHRoZSBwcmVBdXRoIGZhaWxlZCBsaXN0IE1BQyBBZGRyZXNzLgogICAgICAgICAgIEFsc28gcmVtb3ZlIHRoZSBBUCBmcm9tIHJvYW0gYWJsZSBBUCBsaXN0ICovCiAgICAgICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyA+PSByZXRyaWVzKSB8fAogICAgICAgICAgICAoKGVTSVJfTElNX01BWF9TVEFfUkVBQ0hFRF9FUlJPUiA9PSBsaW1TdGF0dXMpICYmCiAgICAgICAgICAgIChwTWFjLT5zdGFfYXV0aF9yZXRyaWVzX2Zvcl9jb2RlMTcgPT0gMCkpKQogICAgICAgIHsKICAgICAgICAgICAgLyogV2UgYXJlIGdvaW5nIHRvIHJlbW92ZSB0aGUgbm9kZSBhcyBpdCBmYWlscyBmb3IgbW9yZSB0aGFuIE1BWCB0cmllcy4gUmVzZXQgdGhpcyBjb3VudCB0byAwICovCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzID0gMDsKCiAgICAgICAgICAgIC8qIFRoZSBvbmUgaW4gdGhlIGhlYWQgb2YgdGhlIGxpc3Qgc2hvdWxkIGJlIG9uZSB3aXRoIHdoaWNoIHdlIGlzc3VlZCBwcmUtYXV0aCBhbmQgZmFpbGVkICovCiAgICAgICAgICAgIHBFbnRyeSA9IGNzckxMUmVtb3ZlSGVhZCgmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0LCBMTF9BQ0NFU1NfTE9DSyk7CiAgICAgICAgICAgIGlmKHBFbnRyeSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzTm9kZSA9IEdFVF9CQVNFX0FERFIocEVudHJ5LCB0Q3NyTmVpZ2hib3JSb2FtQlNTSW5mbywgTGlzdCk7CiAgICAgICAgICAgICAgICAvKiBBZGQgdGhlIEJTU0lEIHRvIHByZS1hdXRoIGZhaWwgbGlzdCBpZiBpdCBpcyBub3QgcmVxdWVzdGVkIGJ5IEhERCAqLwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgICBpZighcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpCiNlbmRpZgogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUFkZEJzc0lkVG9QcmVhdXRoRmFpbExpc3QocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvckJzc05vZGUtPnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQpOwogICAgICAgICAgICAgICAgfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlJfTUVUUklDUwogICAgICAgICAgICAgICAgLyogTEZSIG1ldHJpY3MgLSBwcmUtYXV0aCBjb21wbGV0aW9uIG1ldHJpYy4gU2VuZCB0aGUgZXZlbnQKICAgICAgICAgICAgICAgICAgIHRvIHN1cHBsaWNhbnQgdGhhdCBwcmUtYXV0aCBzdWNjZXNzZnVsbHkgY29tcGxldGVkICovCiAgICAgICAgICAgICAgICByb2FtSW5mbyA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyUm9hbUluZm8pKTsKICAgICAgICAgICAgICAgIGlmIChOVUxMID09IHJvYW1JbmZvKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZmFpbGVkISIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2b3NfbWVtX2NvcHkoKHZvaWQgKilyb2FtSW5mby0+YnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICopcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRDc3JCc3NpZCkpOwogICAgICAgICAgICAgICAgICAgIGNzclJvYW1DYWxsQ2FsbGJhY2socE1hYywgc2Vzc2lvbklkLCByb2FtSW5mbywgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVDU1JfUk9BTV9QUkVBVVRIX1NUQVRVU19GQUlMVVJFLCAwKTsKICAgICAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocm9hbUluZm8pOwogICAgICAgICAgICAgICAgfQojZW5kaWYKCiAgICAgICAgICAgIC8qIE5vdyB3ZSBjYW4gZnJlZSB0aGlzIG5vZGUgKi8KICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRnJlZU5laWdoYm9yUm9hbUJTU05vZGUocE1hYywgcE5laWdoYm9yQnNzTm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlzX2Rpc19wZW5kaW5nID0gaXNfZGlzY29ubmVjdF9wZW5kaW5nKHBNYWMsIHNlc3Npb25JZCk7CiAgICAgICAgaWYgKGlzX2Rpc19wZW5kaW5nKSB7CiAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgRkwoIiBEaXNjb25uZWN0IGluIHByb2dyZXNzLCBBYm9ydCBwcmVhdXRoIikpOwogICAgICAgICAgIGdvdG8gYWJvcnRfcHJlYXV0aDsKICAgICAgICB9CgogICAgICAgIGlmIChwTWFjLT5yb2FtLnBlbmRpbmdfcm9hbV9kaXNhYmxlKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJwcm9jZXNzIHBlbmRpbmcgcm9hbSBkaXNhYmxlIikpOwogICAgICAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzRmFzdFJvYW1JbmlGZWF0dXJlRW5hYmxlZCA9IEZBTFNFOwogICAgICAgICAgICBwTWFjLT5yb2FtLnBlbmRpbmdfcm9hbV9kaXNhYmxlID0gRkFMU0U7CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVVwZGF0ZUZhc3RSb2FtaW5nRW5hYmxlZChwTWFjLCBzZXNzaW9uSWQsIEZBTFNFKTsKICAgICAgICAgICAgY3NyX25laWdoYm9yX3JvYW1fc3RhdGVfdHJhbnNpdGlvbihwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCk7CiAgICAgICAgICAgIGdvdG8gREVRX1BSRUFVVEg7CiAgICAgICAgfQoKICAgICAgICAvKiBJc3N1ZSBwcmVhdXRoIHJlcXVlc3QgZm9yIHRoZSBzYW1lL25leHQgZW50cnkgKi8KICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyA9PSBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkKSkKICAgICAgICBnb3RvIERFUV9QUkVBVVRIOwoKYWJvcnRfcHJlYXV0aDoKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIGlmIChjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgIHsKICAgICAgICAgIGlmKHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmKQogICAgICAgICAgewogICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIDAsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9QUkVBVVRIX0ZBSUxFRF9GT1JfQUxMKTsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UKICAgICAgICAgIHsKICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCAwLCBST0FNX1NDQU5fT0ZGTE9BRF9SRVNUQVJULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9QUkVBVVRIX0ZBSUxFRF9GT1JfQUxMKTsKICAgICAgICAgIH0KICAgICAgICAgIGNzcl9uZWlnaGJvcl9yb2FtX3N0YXRlX3RyYW5zaXRpb24ocE1hYywKICAgICAgICAgICAgICAgIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQsCiAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgICAgIH0gZWxzZQogICAgICAgIHsKI2VuZGlmCiAgICAgICAgICBjc3JfbmVpZ2hib3Jfcm9hbV9zdGF0ZV90cmFuc2l0aW9uKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwoKICAgICAgICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTAogICAgICAgICAgICAgZm9yIFVQIGV2ZW50IG5vdyAqLwogICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiTm8gbW9yZSBwcmUtYXV0aCBjYW5kaWRhdGVzLSIKICAgICAgICAgICAgICAgICAgInJlZ2lzdGVyIFVQIGluZGljYXRpb24gd2l0aCBUTC4gUlNTSSA9ICVkLCIpLAogICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpKTsKCiAgICAgICAgICBwVXNyQ3R4ID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKCpwVXNyQ3R4KSk7CiAgICAgICAgICBpZiAoTlVMTCA9PSBwVXNyQ3R4KSB7CiAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZCBmb3IgcFVzckN0eCIpKTsKICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMRURfQUxMT0M7CiAgICAgICAgICB9CgogICAgICAgICAgcFVzckN0eC0+cE1hYyA9IHBNYWM7CiAgICAgICAgICBwVXNyQ3R4LT5zZXNzaW9uSWQgPSBzZXNzaW9uSWQ7CiAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBVc3JDdHgpOwogICAgICAgICAgdm9zX21lbV9mcmVlKHBVc3JDdHgpOwogICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgewogICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwQ2FsbGJhY2sgVVAgZXZlbnQgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgc3RhdHVzKTsKICAgICAgICAgIH0KCiAgICAgICAgICAvKiBTdGFydCB0aGUgbmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIGFuZCB0cmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlIHRvIHBlcmZvcm0gc2NhbiBhZ2FpbiAqLwogICAgICAgICAgc3RhdHVzID0gdm9zX3RpbWVyX3N0YXJ0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZCk7CiAgICAgICAgICBpZiAoIHN0YXR1cyAhPSBlSEFMX1NUQVRVU19TVUNDRVNTICkKICAgICAgICAgIHsKICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIHN0YXJ0IGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBzdGF0dXMpOwogICAgICAgICAgfQogICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgfQojZW5kaWYKCkRFUV9QUkVBVVRIOgogICAgY3NyRGVxdWV1ZVJvYW1Db21tYW5kKHBNYWMsIGVDc3JQZXJmb3JtUHJlYXV0aCk7CiAgICByZXR1cm4gcHJlYXV0aFByb2Nlc3NlZDsKfQojZW5kaWYgIC8qIFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HICovCgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fT0ZGTE9BRAovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogXGZuICAgICBjc3JOZWlnaGJvclJvYW1PZmZsb2FkVXBkYXRlUHJlYXV0aExpc3QKICogXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGhhbmRsZSB0aGUgUm9hbU9mZmxvYWRTeW5jaCBhbmQgYWRkcyB0aGUKICogICAgICAgICByb2FtZWQgQVAgdG8gdGhlIHByZWF1dGggZG9uZSBsaXN0CiAqIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICogXHBhcmFtICBwU21lUm9hbU9mZmxvYWRTeW5jaEluZCAtIFJvYW0gb2ZmbG9hZCBzeW5jIEluZCBJbmZvCiAqIFxwYXJhbSAgc2Vzc2lvbklkIC0gU2Vzc2lvbiBpZGVudGlmaWVyCiAqIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLAogKiAgICAgICAgIGVIQUxfU1RBVFVTX0ZBSUxVUkUgb3RoZXJ3aXNlCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cwpjc3JOZWlnaGJvclJvYW1PZmZsb2FkVXBkYXRlUHJlYXV0aExpc3QodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgdHBTaXJSb2FtT2ZmbG9hZFN5bmNoSW5kIHBTbWVSb2FtT2ZmbG9hZFN5bmNoSW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBCc3NJbmZvOwogICAgdEFOSV9VMTYgYnNzRGVzY0xlbjsKCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlICE9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgICAgICBGTCgiTEZSMzpSb2FtIE9mZmxvYWQgU3luY2ggSW5kIHJlY2VpdmVkIGluIHN0YXRlICVkIiksCiAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQoKICAgIHBCc3NJbmZvID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvKSk7CiAgICBpZiAoTlVMTCA9PSBwQnNzSW5mbykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwKICAgICAgICAgICAgICAgRkwoIkxGUjM6TWVtb3J5IGFsbG9jYXRpb24gZm9yIE5laWdoYm9yIFJvYW0gQlNTIEluZm8gZmFpbGVkIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgYnNzRGVzY0xlbiA9IHBTbWVSb2FtT2ZmbG9hZFN5bmNoSW5kLT5wYnNzRGVzY3JpcHRpb24tPmxlbmd0aCArCiAgICAgICAgc2l6ZW9mKHBTbWVSb2FtT2ZmbG9hZFN5bmNoSW5kLT5wYnNzRGVzY3JpcHRpb24tPmxlbmd0aCk7CiAgICBwQnNzSW5mby0+cEJzc0Rlc2NyaXB0aW9uID0gdm9zX21lbV9tYWxsb2MoYnNzRGVzY0xlbik7CiAgICBpZiAocEJzc0luZm8tPnBCc3NEZXNjcmlwdGlvbiAhPSBOVUxMKQogICAgewogICAgICAgIHZvc19tZW1fY29weShwQnNzSW5mby0+cEJzc0Rlc2NyaXB0aW9uLAogICAgICAgICAgICAgICAgICAgICBwU21lUm9hbU9mZmxvYWRTeW5jaEluZC0+cGJzc0Rlc2NyaXB0aW9uLAogICAgICAgICAgICAgICAgICAgICBic3NEZXNjTGVuKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwKICAgICAgICAgICAgICBGTCgiTEZSMzpNZW0gYWxsb2MgZm9yIE5laWdoYm9yIFJvYW0gQlNTIERlc2NyaXB0b3IgZmFpbGVkIikpOwogICAgICAgIHZvc19tZW1fZnJlZShwQnNzSW5mbyk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CgogICAgfQogICAgY3NyTExJbnNlcnRUYWlsKCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QsCiAgICAgICAgICAgICAgICAgICAgJnBCc3NJbmZvLT5MaXN0LCBMTF9BQ0NFU1NfTE9DSyk7CgogICAgY3NyX25laWdoYm9yX3JvYW1fc3RhdGVfdHJhbnNpdGlvbihwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSF9ET05FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPSAwOwogICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0RFQlVHLAogICAgICAgICAgICAgICAiTEZSMzpFbnRyeSBhZGRlZCB0byBBdXRoIERvbmUgTGlzdCIpOwoKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CiNlbmRpZgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHJlcGFyZVNjYW5Qcm9maWxlRmlsdGVyCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgYSBzY2FuIGZpbHRlciBiYXNlZCBvbiB0aGUgY3VycmVudGx5IGNvbm5lY3RlZCBwcm9maWxlLgogICAgICAgICAgICBCYXNlZCBvbiB0aGlzIGZpbHRlciwgc2NhbiByZXN1bHRzIGFyZSBvYnRhaW5lZAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcFNjYW5GaWx0ZXIgLSBQb3B1bGF0ZWQgc2NhbiBmaWx0ZXIgYmFzZWQgb24gdGhlIGNvbm5lY3RlZCBwcm9maWxlCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGVIQUxfU1RBVFVTX0ZBSUxVUkUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzCmNzck5laWdoYm9yUm9hbVByZXBhcmVTY2FuUHJvZmlsZUZpbHRlcih0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdENzclNjYW5SZXN1bHRGaWx0ZXIgKnBTY2FuRmlsdGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIHRDc3JSb2FtQ29ubmVjdGVkUHJvZmlsZSAqcEN1clByb2ZpbGUgPSAmcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGU7CiAgICB0QU5JX1U4IGkgPSAwOwogICAgc3RydWN0IHJvYW1fZXh0X3BhcmFtcyAqcm9hbV9wYXJhbXM7CgogICAgVk9TX0FTU0VSVChwU2NhbkZpbHRlciAhPSBOVUxMKTsKICAgIGlmIChwU2NhbkZpbHRlciA9PSBOVUxMKQogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwoKICAgIHZvc19tZW1femVybyhwU2NhbkZpbHRlciwgc2l6ZW9mKHRDc3JTY2FuUmVzdWx0RmlsdGVyKSk7CgogICAgcm9hbV9wYXJhbXMgPSAmcE1hYy0+cm9hbS5jb25maWdQYXJhbS5yb2FtX3BhcmFtczsKICAgIC8qIFdlIGRvbnQgd2FudCB0byBzZXQgQlNTSUQgYmFzZWQgRmlsdGVyICovCiAgICBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzID0gMDsKICAgIHBTY2FuRmlsdGVyLT5zY2FuX2ZpbHRlcl9mb3Jfcm9hbSA9IDE7CiAgICAvL29ubHkgZm9yIEhERCByZXF1ZXN0ZWQgaGFuZG9mZiBmaWxsIGluIHRoZSBCU1NJRCBpbiB0aGUgZmlsdGVyCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikKICAgIHsKCiAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0RFQlVHLAogICAgICAgICAgICAgICAgICAgRkwoIk9TIFJlcXVlc3RlZCBIYW5kb2ZmIikpOwogICAgICAgIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMgPSAxOwogICAgICAgIHBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWQgPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodFNpck1hY0FkZHIpICogcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyk7CiAgICAgICAgaWYgKE5VTEwgPT0gcFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZCkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2NhbiBGaWx0ZXIgQlNTSUQgbWVtIGFsbG9jIGZhaWxlZCIpKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxFRF9BTExPQzsKICAgICAgICB9CgogICAgICAgIHZvc19tZW1femVybyhwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpICogcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyk7CgogICAgICAgIC8qIFBvcHVsYXRlIHRoZSBCU1NJRCBmcm9tIGhhbmRvZmYgaW5mbyByZWNlaXZlZCBmcm9tIEhERCAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2NvcHkoJnBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWRbaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgICAgIH0KICAgIH0KI2VuZGlmCiAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfREVCVUcsCiAgICAgICAgRkwoIk5vIG9mIEFsbG93ZWQgU1NJRCBMaXN0OiVkIiksIHJvYW1fcGFyYW1zLT5udW1fc3NpZF9hbGxvd2VkX2xpc3QpOwogICAgaWYgKHJvYW1fcGFyYW1zLT5udW1fc3NpZF9hbGxvd2VkX2xpc3QpIHsKICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMubnVtT2ZTU0lEcyA9IChyb2FtX3BhcmFtcy0+bnVtX3NzaWRfYWxsb3dlZF9saXN0KTsKICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QgPQogICAgICAgICAgIHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyU1NJREluZm8pICogcFNjYW5GaWx0ZXItPlNTSURzLm51bU9mU1NJRHMpOwogICAgICAgIGlmIChOVUxMID09IHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdCkgewogICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2NhbiBGaWx0ZXIgU1NJRCBtZW0gYWxsb2MgZmFpbGVkIikpOwogICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMRURfQUxMT0M7CiAgICAgICAgfQogICAgICAgIGZvcihpID0gMDsgaSA8IHJvYW1fcGFyYW1zLT5udW1fc3NpZF9hbGxvd2VkX2xpc3Q7IGkrKykgewogICAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0W2ldLmhhbmRvZmZQZXJtaXR0ZWQgPSAxOwogICAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0W2ldLnNzaWRIaWRkZW4gPSAwOwogICAgICAgICAgdm9zX21lbV9jb3B5KCh2b2lkICopcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0W2ldLlNTSUQuc3NJZCwKICAgICAgICAgICAgcm9hbV9wYXJhbXMtPnNzaWRfYWxsb3dlZF9saXN0W2ldLnNzSWQsCiAgICAgICAgICAgIHJvYW1fcGFyYW1zLT5zc2lkX2FsbG93ZWRfbGlzdFtpXS5sZW5ndGgpOwogICAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0W2ldLlNTSUQubGVuZ3RoID0KICAgICAgICAgICAgcm9hbV9wYXJhbXMtPnNzaWRfYWxsb3dlZF9saXN0W2ldLmxlbmd0aDsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qIFBvcHVsYXRlIGFsbCB0aGUgaW5mb3JtYXRpb24gZnJvbSB0aGUgY29ubmVjdGVkIHByb2ZpbGUgKi8KICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMubnVtT2ZTU0lEcyA9IDE7CiAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0ID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JTU0lESW5mbykpOwogICAgICAgIGlmIChOVUxMID09IHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdCkgewogICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTY2FuIEZpbHRlciBTU0lEIG1lbSBhbGxvYyBmYWlsZWQiKSk7CiAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTEVEX0FMTE9DOwogICAgICAgIH0KICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPmhhbmRvZmZQZXJtaXR0ZWQgPSAxOwogICAgICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+c3NpZEhpZGRlbiA9IDA7CiAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELmxlbmd0aCA9ICBwQ3VyUHJvZmlsZS0+U1NJRC5sZW5ndGg7CiAgICAgICAgdm9zX21lbV9jb3B5KCh2b2lkICopcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELnNzSWQsCiAgICAgICAgICAodm9pZCAqKXBDdXJQcm9maWxlLT5TU0lELnNzSWQsIHBDdXJQcm9maWxlLT5TU0lELmxlbmd0aCk7CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiRmlsdGVyaW5nIGZvciBTU0lEICUuKnMgZnJvbSBzY2FuIHJlc3VsdHMsIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsZW5ndGggb2YgU1NJRCA9ICV1IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPlNTSUQuc3NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPlNTSUQubGVuZ3RoKTsKICAgIH0KICAgIHBTY2FuRmlsdGVyLT5hdXRoVHlwZS5udW1FbnRyaWVzID0gMTsKICAgIHBTY2FuRmlsdGVyLT5hdXRoVHlwZS5hdXRoVHlwZVswXSA9IHBDdXJQcm9maWxlLT5BdXRoVHlwZTsKCiAgICBwU2NhbkZpbHRlci0+RW5jcnlwdGlvblR5cGUubnVtRW50cmllcyA9IDE7IC8vVGhpcyBtdXN0IGJlIDEKICAgIHBTY2FuRmlsdGVyLT5FbmNyeXB0aW9uVHlwZS5lbmNyeXB0aW9uVHlwZVswXSA9IHBDdXJQcm9maWxlLT5FbmNyeXB0aW9uVHlwZTsKCiAgICBwU2NhbkZpbHRlci0+bWNFbmNyeXB0aW9uVHlwZS5udW1FbnRyaWVzID0gMTsKICAgIHBTY2FuRmlsdGVyLT5tY0VuY3J5cHRpb25UeXBlLmVuY3J5cHRpb25UeXBlWzBdID0gcEN1clByb2ZpbGUtPm1jRW5jcnlwdGlvblR5cGU7CgogICAgcFNjYW5GaWx0ZXItPkJTU1R5cGUgPSBwQ3VyUHJvZmlsZS0+QlNTVHlwZTsKCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICB7CiAgICAgIC8qIFdlIGFyZSBpbnRlcmVzdGVkIG9ubHkgaW4gdGhlIHNjYW4gcmVzdWx0cyBvbiBjaGFubmVscyB3ZSBzY2FubmVkICovCiAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVsczsKICAgICAgcFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0KICAgICAgIHZvc19tZW1fbWFsbG9jKHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKICAgICAgaWYgKE5VTEwgPT0gcFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KSB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTY2FuIEZpbHRlciBDaGFubmVsIGxpc3QgbWVtIGFsbG9jIGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0KTsKICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QgPSBOVUxMOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMRURfQUxMT0M7CiAgICAgIH0KICAgICAgZm9yIChpID0gMDsgaSA8IHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzOyBpKyspCiAgICAgICBwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbaV0gPQogICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0W2ldOwogICAgfSBlbHNlIHsKICAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICB9CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykKICAgIHsKICAgICAgICAvKiBNRElFIHNob3VsZCBiZSBhZGRlZCBhcyBhIHBhcnQgb2YgcHJvZmlsZS4gVGhpcyBzaG91bGQgYmUgYWRkZWQgYXMgYSBwYXJ0IG9mIGZpbHRlciBhcyB3ZWxsICAqLwogICAgICAgIHBTY2FuRmlsdGVyLT5NRElELm1kaWVQcmVzZW50ID0gcEN1clByb2ZpbGUtPk1ESUQubWRpZVByZXNlbnQ7CiAgICAgICAgcFNjYW5GaWx0ZXItPk1ESUQubW9iaWxpdHlEb21haW4gPSBwQ3VyUHJvZmlsZS0+TURJRC5tb2JpbGl0eURvbWFpbjsKICAgIH0KI2VuZGlmCgojaWZkZWYgV0xBTl9GRUFUVVJFXzExVwogICAgcFNjYW5GaWx0ZXItPk1GUEVuYWJsZWQgPSBwQ3VyUHJvZmlsZS0+TUZQRW5hYmxlZDsKICAgIHBTY2FuRmlsdGVyLT5NRlBSZXF1aXJlZCA9IHBDdXJQcm9maWxlLT5NRlBSZXF1aXJlZDsKICAgIHBTY2FuRmlsdGVyLT5NRlBDYXBhYmxlID0gcEN1clByb2ZpbGUtPk1GUENhcGFibGU7CiNlbmRpZgogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCnRBTklfVTMyIGNzckdldEN1cnJlbnRBUFJzc2kodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICB0U2NhblJlc3VsdEhhbmRsZSAqcFNjYW5SZXN1bHRMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICB0Q3NyU2NhblJlc3VsdEluZm8gKnBTY2FuUmVzdWx0OwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICB0QU5JX1UzMiBDdXJyQVBSc3NpID0gcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpOwojZWxzZQogICAgICAgIC8qIFdlIGFyZSBzZXR0aW5nIHRoaXMgYXMgZGVmYXVsdCB2YWx1ZSB0byBtYWtlIHN1cmUgd2UgcmV0dXJuIHRoaXMgdmFsdWUsCiAgICAgICAgd2hlbiB3ZSBkbyBub3Qgc2VlIHRoaXMgQVAgaW4gdGhlIHNjYW4gcmVzdWx0IGZvciBzb21lIHJlYXNvbi5Ib3dldmVyLGl0IGlzCiAgICAgICAgbGVzcyBsaWtlbHkgdGhhdCB3ZSBhcmUgYXNzb2NpYXRlZCB0byBhbiBBUCBhbmQgZG8gbm90IHNlZSBpdCBpbiB0aGUgc2NhbiBsaXN0ICovCiAgICB0QU5JX1UzMiBDdXJyQVBSc3NpID0gLTEyNTsKI2VuZGlmCgogICAgd2hpbGUgKE5VTEwgIT0gKHBTY2FuUmVzdWx0ID0gY3NyU2NhblJlc3VsdEdldE5leHQocE1hYywgKnBTY2FuUmVzdWx0TGlzdCkpKQogICAgewogICAgICAgICAgICBpZiAoVk9TX1RSVUUgPT0gdm9zX21lbV9jb21wYXJlKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VyckFQYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBXZSBnb3QgYSBtYXRjaCB3aXRoIHRoZSBjdXJyZW50bHkgYXNzb2NpYXRlZCBBUC4KICAgICAgICAgICAgICAgICAqIENhcHR1cmUgdGhlIFJTU0kgdmFsdWUgYW5kIGNvbXBsZXRlIHRoZSB3aGlsZSBsb29wLgogICAgICAgICAgICAgICAgICAgICAgICAgKiBUaGUgd2hpbGUgbG9vcCBpcyBjb21wbGV0ZWQgaW4gb3JkZXIgdG8gbWFrZSB0aGUgY3VycmVudCBlbnRyeSBnbyBiYWNrIHRvIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAqIGFuZCBpbiB0aGUgbmV4dCB3aGlsZSBsb29wLCBpdCBwcm9wZXJseSBzdGFydHMgc2VhcmNoaW5nIGZyb20gdGhlIGhlYWQgb2YgdGhlIGxpc3QuCiAgICAgICAgICAgICAgICAgICAgICAgICAqIFRPRE86IENhbiBhbHNvIHRyeSBzZXR0aW5nIHRoZSBjdXJyZW50IGVudHJ5IGRpcmVjdGx5IHRvIE5VTEwgYXMgc29vbiBhcyB3ZSBmaW5kIHRoZSBuZXcgQVAqLwoKICAgICAgICAgICAgICAgICAgICAgQ3VyckFQUnNzaSA9IChpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSAqICgtMSk7CgogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gQ3VyckFQUnNzaTsKCn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhblJlc3VsdHMKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gZXh0cmFjdHMgc2NhbiByZXN1bHRzLCBzb3J0cyBvbiB0aGUgYmFzaXMgb2YgbmVpZ2hib3Igc2NvcmUodG9kbykuCiAgICAgICAgICAgIEFzc3VtZWQgdGhhdCB0aGUgcmVzdWx0cyBhcmUgYWxyZWFkeSBzb3J0ZWQgYnkgUlNTSSBieSBjc3JTY2FuR2V0UmVzdWx0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwU2NhblJlc3VsdExpc3QgLSBTY2FuIHJlc3VsdCByZXN1bHQgb2J0YWluZWQgZnJvbSBjc3JTY2FuR2V0UmVzdWx0KCkKCiAgICBccmV0dXJuIHRBTklfQk9PTEVBTiAtIHJldHVybiBUUlVFIGlmIHdlIGhhdmUgYSBjYW5kaWRhdGUgd2UgY2FuIGltbWVkaWF0ZWx5CiAgICAgICAgICAgIHJvYW0gdG8uIE90aGVyd2lzZSwgcmV0dXJuIEZBTFNFLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCnN0YXRpYyB0QU5JX0JPT0xFQU4KY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5SZXN1bHRzKHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRTY2FuUmVzdWx0SGFuZGxlICpwU2NhblJlc3VsdExpc3QpCnsKICAgIHRDc3JTY2FuUmVzdWx0SW5mbyAqcFNjYW5SZXN1bHQ7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyAgICBwQnNzSW5mbzsKICAgIHRBTklfVTMyIEN1cnJBUFJzc2k7CiAgICB0QU5JX1U4IFJvYW1Sc3NpRGlmZiA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uUm9hbVJzc2lEaWZmOwojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICB0QU5JX1U4IGltbWVkaWF0ZVJvYW1Sc3NpRGlmZiA9CiAgICAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubkltbWVkaWF0ZVJvYW1Sc3NpRGlmZjsKI2VuZGlmCiAgICB0QU5JX0JPT0xFQU4gcm9hbU5vdyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHRTY2FuUmVzdWx0SGFuZGxlICpwU2NhblJlc3VsdExpc3RTYXZlZCA9IE5VTEw7CiAgICB0QU5JX1UzMiAgYXBBZ2VUaWNrcyA9IDA7CiAgICB0QU5JX1UzMiAgYXBBZ2VMaW1pdFRpY2tzID0gYWRmX29zX21zZWNzX3RvX3RpY2tzKFJPQU1fQVBfQUdFX0xJTUlUX01TKTsKICAgIHRBTklfVTggICBudW1DYW5kaWRhdGVzID0gMDsKICAgIHRBTklfVTggICBudW1BUHNEcm9wcGVkID0gMDsKICAgIC8qCiAgICAgKiBmaXJzdCBpdGVyYXRpb24gb2Ygc2NhbiBsaXN0IHNob3VsZCBjb25zaWRlcgogICAgICogYWdlIGNvbnN0cmFpbnQgZm9yIGNhbmRpZGF0ZXMKICAgICAqLwogICAgdEFOSV9CT09MRUFOIGFnZUNvbnN0cmFpbnQgPSBlQU5JX0JPT0xFQU5fVFJVRTsKCiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgKiBGaW5kIG91dCB0aGUgQ3VycmVudCBBUCBSU1NJIGFuZCBrZWVwIGl0IGhhbmR5IHRvIGNoZWNrIGlmCiAgICAgKiBpdCBpcyBiZXR0ZXIgdGhhbiB0aGUgUlNTSSBvZiB0aGUgQVAgd2hpY2ggd2UgYXJlCiAgICAgKiBnb2luZyB0byByb2FtLklmIHNvLCB3ZSBhcmUgZ29pbmcgdG8gY29udGludWUgd2l0aCB0aGUKICAgICAqIGN1cnJlbnQgQVAuCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgQ3VyckFQUnNzaSA9IGNzckdldEN1cnJlbnRBUFJzc2kocE1hYywgcFNjYW5SZXN1bHRMaXN0LCBzZXNzaW9uSWQpOwoKICAgIC8qCiAgICAgKiBFeHBlY3RpbmcgdGhlIHNjYW4gcmVzdWx0IGFscmVhZHkgdG8gYmUgaW4gdGhlIHNvcnRlZCBvcmRlciBiYXNlZCBvbiB0aGUKICAgICAqIFJTU0kuIEJhc2VkIG9uIHRoZSBwcmV2aW91cyBzdGF0ZSB3ZSBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgdGhlIGxpc3QKICAgICAqIHNob3VsZCBiZSBzb3J0ZWQgYWdhaW4gdGFraW5nIG5laWdoYm9yIHNjb3JlIGludG8gY29uc2lkZXJhdGlvbi4gSWYKICAgICAqIHByZXZpb3VzIHN0YXRlIGlzIENGR19DSEFOX0xJU1RfU0NBTiwgdGhlcmUgc2hvdWxkIG5vdCBiZSBhbnkgbmVpZ2hib3IKICAgICAqIHNjb3JlIGFzc29jaWF0ZWQgd2l0aCBhbnkgb2YgdGhlIEJTUy4gSWYgdGhlIHByZXZpb3VzIHN0YXRlIGlzCiAgICAgKiBSRVBPUlRfUVVFUlksIHRoZW4gdGhlcmUgd2lsbCBiZSBuZWlnaGJvciBzY29yZSBmb3IgZWFjaCBvZiB0aGUgQVBzLiBGb3IKICAgICAqIG5vdywgbGV0IHVzIHRha2UgdGhlIHRvcCBvZiB0aGUgbGlzdCBwcm92aWRlZCBhcyBpdCBpcyBieSB0aGUgQ1NSIFNjYW4KICAgICAqIHJlc3VsdCBBUEkuIFRoaXMgbWVhbnMgaXQgaXMgYXNzdW1lZCB0aGF0IG5laWdoYm9yIHNjb3JlIGFuZCByc3NpIHNjb3JlCiAgICAgKiBhcmUgaW4gdGhlIHNhbWUgb3JkZXIuIFRoaXMgd2lsbCBiZSB0YWtlbiBjYXJlIGxhdGVyCiAgICAgKi8KCiAgICBkbyB7CiAgICAgICAgLyogc2F2ZSB0aGUgc2NhbiByZXN1bHQgcG9pbnRlciBmb3IgbmV4dCBpdGVyYXRpb24gKi8KICAgICAgICBwU2NhblJlc3VsdExpc3RTYXZlZCA9IHBTY2FuUmVzdWx0TGlzdDsKICAgICAgICB3aGlsZSAoTlVMTCAhPSAocFNjYW5SZXN1bHQgPSBjc3JTY2FuUmVzdWx0R2V0TmV4dChwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqcFNjYW5SZXN1bHRMaXN0KSkpIHsKI2lmIChMSU5VWF9WRVJTSU9OX0NPREUgPj0gS0VSTkVMX1ZFUlNJT04oNCwgNSwgMCkpCiAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9ERUJVRywKICAgICAgICAgICAgICAgIEZMKCJTY2FuIHJlc3VsdDogQlNTSUQgIk1BQ19BRERSRVNTX1NUUiIgKFJzc2kgJWQsIENoOiVkKSIpLAogICAgICAgICAgICAgICAgTUFDX0FERFJfQVJSQVkocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpLAogICAgICAgICAgICAgICAgYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpLAogICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuY2hhbm5lbElkKTsKI2Vsc2UKICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0RFQlVHLAogICAgICAgICAgICAgICAgRkwoIlNjYW4gcmVzdWx0OiBCU1NJRCAiTUFDX0FERFJFU1NfU1RSIiAoUnNzaSAlbGQsIENoOiVkKSIpLAogICAgICAgICAgICAgICAgTUFDX0FERFJfQVJSQVkocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpLAogICAgICAgICAgICAgICAgKGxvbmcgaW50KWFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSwKICAgICAgICAgICAgICAgIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmNoYW5uZWxJZCk7CiNlbmRpZgogICAgICAgICAgICBpZiAoKFZPU19UUlVFID09IHZvc19tZW1fY29tcGFyZShwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCwKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSkpIHx8CiAgICAgICAgICAgICAgICAoKGVTTUVfUk9BTV9UUklHR0VSX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikgJiYKICAgICAgICAgICAgICAgIChWT1NfVFJVRSAhPSB2b3NfbWVtX2NvbXBhcmUocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQsCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbWJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKSkpKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogY3VycmVudGx5IGFzc29jaWF0ZWQgQVAuIERvIG5vdCBoYXZlIHRoaXMgaW4gdGhlIHJvYW0gYWJsZSBBUAogICAgICAgICAgICAgICAgICogbGlzdAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNLSVAtY3VycmVudGx5IGFzc29jaWF0ZWQgQVAiKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh2b3NfY29uY3VycmVudF9vcGVuX3Nlc3Npb25zX3J1bm5pbmcoKSAmJgogICAgICAgICAgICAgICAhcE1hYy0+cm9hbS5jb25maWdQYXJhbS5mZW5hYmxlTUNDTW9kZSAmJgogICAgICAgICAgICAgICAocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuY2hhbm5lbElkICE9CiAgICAgICAgICAgICAgIGNzckdldENvbmN1cnJlbnRPcGVyYXRpb25DaGFubmVsKHBNYWMpKSkgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJNQ0Mgbm90IHN1cHBvcnRlZCBzbyBJZ25vcmUgQVAgb24gY2hhbm5lbCAlZCIpLAogICAgICAgICAgICAgICAgICAgIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmNoYW5uZWxJZCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJbiBjYXNlIG9mIHJlYXNzb2MgcmVxdWVzdGVkIGJ5IHVwcGVyIGxheWVyLCBsb29rIGZvciBleGFjdCBtYXRjaAogICAgICAgICAgICAgKiBvZiBic3NpZCAmIGNoYW5uZWwuIGNzciBjYWNoZSBtaWdodCBoYXZlIGR1cGxpY2F0ZXMKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpICYmCiAgICAgICAgICAgICAgICAoKFZPU19GQUxTRSA9PSB2b3NfbWVtX2NvbXBhcmUocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQsCiAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uYnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKSl8fAogICAgICAgICAgICAgICAgIChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5jaGFubmVsSWQgIT0KICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5jaGFubmVsKSkpIHsKICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgIlNLSVAtbm90IGEgY2FuZGlkYXRlIEFQIGZvciBPUyByZXF1ZXN0ZWQgcm9hbSIpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KI2VuZGlmCiNlbmRpZgoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGhpcyBjb25kaXRpb24gaXMgdG8gZW5zdXJlIHRvIHJvYW0gdG8gYW4gQVAgd2l0aCBiZXR0ZXIgUlNTSS4KICAgICAgICAgICAgICogaWYgdGhlIHZhbHVlIG9mIFJvYW1Sc3NpRGlmZiBpcyBaZXJvLCB0aGlzIGZlYXR1cmUKICAgICAgICAgICAgICogaXMgZGlzYWJsZWQgYW5kIHdlIGNvbnRpbnVlIHRvIHJvYW0gd2l0aG91dCBhbnkgY2hlY2sKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgoUm9hbVJzc2lEaWZmID4gMCkKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAgICYmICFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpCiNlbmRpZgogICAgICAgICAgICAgICYmICgoZVNNRV9ST0FNX1RSSUdHRVJfU0NBTiAhPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKSAmJgogICAgICAgICAgICAgICAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNICE9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pKSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIElmIFJTU0kgaXMgbG93ZXIgdGhhbiB0aGUgbG9va3VwIHRocmVzaG9sZCwgdGhlbiBjb250aW51ZS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSA+CiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCkgewogICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgIEZMKCJuZXcgYXAgcnNzaSAoJWQpIGxvd2VyIHRoYW4gbG9va3VwIHRocmVzaG9sZCAoJWQpIiksCiAgICAgICAgICAgICAgICAgICAgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAoaW50KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoYWJzKEN1cnJBUFJzc2kpIDwgYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpKSB7CiAgICAgICAgICAgICAgICAgICAgLyogRG8gbm90IHJvYW0gdG8gYW4gQVAgd2l0aCB3b3JzZSBSU1NJIHRoYW4gdGhlIGN1cnJlbnQgKi8KICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfREVCVUcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXUN1cnJlbnQgQVAgcnNzaT0lZCBuZXcgYXAgcnNzaSAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid29yc2U9JWQiLCBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEN1cnJBUFJzc2ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kgKiAoLTEpICk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogRG8gbm90IHJvYW0gdG8gYW4gQVAgd2hpY2ggaXMgaGF2aW5nIGJldHRlciBSU1NJIHRoYW4gdGhlCiAgICAgICAgICAgICAgICAgICAgICogY3VycmVudCBBUCwgYnV0IHN0aWxsIGxlc3MgdGhhbiB0aGUgbWFyZ2luIHRoYXQgaXMKICAgICAgICAgICAgICAgICAgICAgKiBwcm92aWRlZCBieSB1c2VyIGZyb20gdGhlIGluaSBmaWxlIChSb2FtUnNzaURpZmYpCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGFicyhhYnMoQ3VyckFQUnNzaSkgLQogICAgICAgICAgICAgICAgICAgICAgICAgYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpKSA8IFJvYW1Sc3NpRGlmZikgewogICAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfREVCVUcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR11DdXJyZW50IEFQIHJzc2k9JWQgbmV3IGFwICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicnNzaT0lZCBub3QgZ29vZCBlbm91Z2gsIHJvYW1Sc3NpRGlmZj0lZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEN1cnJBUFJzc2ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSb2FtUnNzaURpZmYpOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9ERUJVRywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR11DdXJyZW50IEFQIHJzc2k9JWQgbmV3IGFwICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJzc2kgYmV0dGVyPSVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDdXJyQVBSc3NpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kgKiAoLTEpICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKSB7CiAgICAgICAgICAgICAgICBpZiAoIWNzck5laWdoYm9yUm9hbUlzUHJlYXV0aENhbmRpZGF0ZShwTWFjLCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpKSB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiQlNTSUQgcHJlc2VudCBpbiBwcmUtYXV0aCBmYWlsIGxpc3QuLiBJZ25vcmluZyIpKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KCiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKSB7CiNlbmRpZgogICAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUocE1hYywgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkJTU0lEIHByZXNlbnQgaW4gcHJlLWF1dGggZmFpbCBsaXN0Li4gSWdub3JpbmciKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfcHJlc2VudCkgJiYKICAgICAgICAgICAgICAgICAgICAgKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLlFCU1NMb2FkX2F2YWlsKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNWT0FkbWl0dGVkKSB7CiAgICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk5ldyBBUCBoYXMgJXggQlcgYXZhaWxhYmxlIiksCiAgICAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5RQlNTTG9hZF9hdmFpbCk7CiAgICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIldlIG5lZWQgJXggQlcgYXZhaWxhYmxlIiksCiAgICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBpbnQpcE5laWdoYm9yUm9hbUluZm8tPk1pblFCc3NMb2FkUmVxdWlyZWQpOwogICAgICAgICAgICAgICAgICAgICAgaWYgKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLlFCU1NMb2FkX2F2YWlsIDwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPk1pblFCc3NMb2FkUmVxdWlyZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJbSU5GT0xPR11CU1NJRCA6ICJNQUNfQUREUkVTU19TVFIiIGhhcyBubyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgYmFuZHdpZHRoIGlnbm9yaW5nLi5ub3QgYWRkaW5nIHRvIHJvYW0iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGxpc3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJObyBRQnNzICV4ICV4IiksCiAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfYXZhaWwsCiAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfcHJlc2VudCk7CiAgICAgICAgICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNWT0FkbWl0dGVkKSB7CiAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiW0lORk9MT0ddQlNTSUQgOiAiTUFDX0FERFJFU1NfU1RSIiBoYXMgbm8gIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUUJTU0xvYWQgSUUsIGlnbm9yaW5nLi5ub3QgYWRkaW5nIHRvIHJvYW0gbGlzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkKSk7CiAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiNlbmRpZiAvKiBGRUFUVVJFX1dMQU5fRVNFICovCgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJZiB3ZSBhcmUgc3VwcG9ydGluZyBsZWdhY3kgcm9hbWluZywgYW5kCiAgICAgICAgICAgICAqIGlmIHRoZSBjYW5kaWRhdGUgaXMgb24gdGhlICJwcmUtYXV0aCBmYWlsZWQiIGxpc3QsIGlnbm9yZSBpdC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYywgc2Vzc2lvbklkKSkgewogICAgICAgICAgICAgICAgaWYgKCFjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUocE1hYywgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkKSkgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICAgICAgICAgRkwoIkJTU0lEIHByZXNlbnQgaW4gcHJlLWF1dGggZmFpbCBsaXN0Li4gSWdub3JpbmciKSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KI2VuZGlmIC8qIEZFQVRVUkVfV0xBTl9MRlIgKi8KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIElmIHRoZSByZWNlaXZlZCB0aW1lcyB0YW1wIGluIEJTUyBkZXNjcmlwdGlvbiBpcyBlYXJsaWVyIHRoYW4gdGhlCiAgICAgICAgICAgICAqIHNjYW4gcmVxdWVzdCB0aW1lIHN0YW1wLCBza2lwIHRoaXMgcmVzdWx0CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUmVxdWVzdFRpbWVTdGFtcCA+PQogICAgICAgICAgICAgICAgICAgICBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5uUmVjZWl2ZWRUaW1lKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgICAmJiAhY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKQojZW5kaWYKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwKICAgICAgICAgICAgICAgICAgICAgICBGTCgiSWdub3JpbmcgQlNTIGFzIGl0IGlzIG9sZGVyIHRoYW4gdGhlIHNjYW4gcmVxdWVzdCAiCiAgICAgICAgICAgICAgICAgICAgICAgInRpbWUgc3RhbXAiKSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcEJzc0luZm8gPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodENzck5laWdoYm9yUm9hbUJTU0luZm8pKTsKICAgICAgICAgICAgaWYgKE5VTEwgPT0gcEJzc0luZm8pIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICAgICAgICAgIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgTmVpZ2hib3IgUm9hbSBCU1MgSW5mbyAiCiAgICAgICAgICAgICAgICAgICAgICAgImZhaWxlZC4uIEp1c3QgaWdub3JpbmciKSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcEJzc0luZm8tPnBCc3NEZXNjcmlwdGlvbiA9CiAgICAgICAgICAgICAgICB2b3NfbWVtX21hbGxvYyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5sZW5ndGggKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmxlbmd0aCkpOwogICAgICAgICAgICBpZiAocEJzc0luZm8tPnBCc3NEZXNjcmlwdGlvbiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICB2b3NfbWVtX2NvcHkocEJzc0luZm8tPnBCc3NEZXNjcmlwdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IubGVuZ3RoICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmxlbmd0aCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgICAgICAgICAgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZvciBOZWlnaGJvciBSb2FtIEJTUyBEZXNjcmlwdG9yICIKICAgICAgICAgICAgICAgICAgICAgICAiZmFpbGVkLi4gSnVzdCBpZ25vcmluZyIpKTsKICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQnNzSW5mbyk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBzb21lIHZhbHVlIGZvciBub3cuIE5lZWQgdG8gY2FsY3VsYXRlIHRoZSBhY3R1YWwgc2NvcmUgYmFzZWQgb24KICAgICAgICAgICAgICogUlNTSSBhbmQgbmVpZ2hib3IgQVAgc2NvcmUKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBCc3NJbmZvLT5hcFByZWZlcmVuY2VWYWwgPSAxMDsKCiAgICAgICAgICAgIGlmIChhZ2VDb25zdHJhaW50ID09IGVBTklfQk9PTEVBTl9GQUxTRSkgewogICAgICAgICAgICAgICAgLyoganVzdCBhZGQgdG8gY2FuZGlkYXRlIGxpc3QsIGlycmVzcGVjdGl2ZSBvZiBhZ2UgKi8KICAgICAgICAgICAgICAgIG51bUNhbmRpZGF0ZXMrKzsKICAgICAgICAgICAgICAgIGNzckxMSW5zZXJ0VGFpbCgmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwQnNzSW5mby0+TGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMTF9BQ0NFU1NfTE9DSyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBjaGVjayB0aGUgYWdlIG9mIHRoZSBBUCBmaXJzdCAqLwogICAgICAgICAgICAgICAgYXBBZ2VUaWNrcyA9ICh0QU5JX1RJTUVTVEFNUClwYWxHZXRUaWNrQ291bnQocE1hYy0+aEhkZCkgLQogICAgICAgICAgICAgICAgICAgICAgICAgICBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5uUmVjZWl2ZWRUaW1lOwogICAgICAgICAgICAgICAgaWYgKGFwQWdlVGlja3MgPCBhcEFnZUxpbWl0VGlja3MpIHsKICAgICAgICAgICAgICAgICAgICBudW1DYW5kaWRhdGVzKys7CiAgICAgICAgICAgICAgICAgICAgY3NyTExJbnNlcnRUYWlsKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwQnNzSW5mby0+TGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTExfQUNDRVNTX0xPQ0spOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBudW1BUHNEcm9wcGVkKys7CiAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFKCBWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX1dBUk4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiU2tpcHBpbmcgYmVjYXVzZSByZWNlaXZlZCBBUCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKHByb2JlIHJzcC9iZWFjb24pIGlzIG9sZC4iKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBCc3NJbmZvLT5wQnNzRGVzY3JpcHRpb24pCiAgICAgICAgICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQnNzSW5mby0+cEJzc0Rlc2NyaXB0aW9uKTsKICAgICAgICAgICAgICAgICAgICBpZiAocEJzc0luZm8pCiAgICAgICAgICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQnNzSW5mbyk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0VTRSkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgICAgICAgICBpZiAoKGVTTUVfUk9BTV9UUklHR0VSX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikgfHwKICAgICAgICAgICAgICAgIChlU01FX1JPQU1fVFJJR0dFUl9GQVNUX1JPQU0gPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikpIHsKICAgICAgICAgICAgICAgcm9hbU5vdyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICgoYWJzKGFicyhDdXJyQVBSc3NpKSAtCiAgICAgICAgICAgICAgICAgICAgICAgICAgYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpKSA+PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbW1lZGlhdGVSb2FtUnNzaURpZmYpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICAgICYmICFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpCiNlbmRpZgogICAgICAgICAgICApIHsKI2lmIChMSU5VWF9WRVJTSU9OX0NPREUgPj0gS0VSTkVMX1ZFUlNJT04oNCwgNSwgMCkpCiAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR10gcG90ZW50aWFsIGNhbmRpZGF0ZSB0byByb2FtICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgImltbWVkaWF0ZWx5IChkaWZmPSVkLCBleHBlY3RlZD0lZCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJzKGFicyhDdXJyQVBSc3NpKSAtCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1tZWRpYXRlUm9hbVJzc2lEaWZmKTsKICAgICAgICAgICAgICAgIHJvYW1Ob3cgPSBlQU5JX0JPT0xFQU5fVFJVRTsKI2Vsc2UKICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXSBwb3RlbnRpYWwgY2FuZGlkYXRlIHRvIHJvYW0gIgogICAgICAgICAgICAgICAgICAgICAgICAgICAiaW1tZWRpYXRlbHkgKGRpZmY9JWxkLCBleHBlY3RlZD0lZCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxvbmcgaW50KWFicyhhYnMoQ3VyckFQUnNzaSkgLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGltbWVkaWF0ZVJvYW1Sc3NpRGlmZik7CiAgICAgICAgICAgICAgICByb2FtTm93ID0gZUFOSV9CT09MRUFOX1RSVUU7CiNlbmRpZgogICAgICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogSWYgd2UgYXJlIGhlcmUgbWVhbnMsIEZXIGFscmVhZHkgZm91bmQgY2FuZGlkYXRlcyB0byByb2FtLAogICAgICAgICAgICAgKiBzbyB3ZSBhcmUgZ29vZCB0byBnbyB3aXRoIHByZS1hdXRoCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZihjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKSB7CiAgICAgICAgICAgICAgICByb2FtTm93ID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgICAgIH0KI2VuZGlmCiNlbmRpZgogICAgICAgIH0gLyogZW5kIG9mIHdoaWxlIChjc3JTY2FuUmVzdWx0R2V0TmV4dCkgKi8KICAgICAgICAvKiBzZXQgdGhlIHNjYW4gcmVzdWx0cyBmb3IgbmV4dCBpdGVyYXRpb24gKi8KICAgICAgICBwU2NhblJlc3VsdExpc3QgPSBwU2NhblJlc3VsdExpc3RTYXZlZDsKCiAgICAgICAgLyogaWYgc29tZSBjYW5kaWRhdGVzIHdlcmUgZm91bmQsIHRoZW4gbm8gbmVlZCB0byByZXBlYXQgKi8KICAgICAgICBpZiAobnVtQ2FuZGlkYXRlcykKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgLyoKICAgICAgICAgKiBpZiBhZ2VDb25zdHJhaW50IGlzIGFscmVhZHkgZmFsc2UsIHdlIGhhdmUgZG9uZSB0d28KICAgICAgICAgKiBpdGVyYXRpb25zIGFuZCBubyBjYW5kaWRhdGUgd2VyZSBmb3VuZCAqLwogICAgICAgIGlmIChhZ2VDb25zdHJhaW50ID09IGVBTklfQk9PTEVBTl9GQUxTRSkgewogICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBObyByb2FtIGFibGUgY2FuZGlkYXRlcyBmb3VuZCIsIF9fZnVuY19fKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogaWYgYWxsIGNhbmRpZGF0ZXMgd2VyZSBkcm9wcGVkIHJlc2NhbiB0aGUgc2NhbgogICAgICAgICAqIGxpc3QgYnV0IHRoaXMgdGltZSB3aXRob3V0IGFnZSBjb25zdHJhaW50LgogICAgICAgICAqLwogICAgICAgIGFnZUNvbnN0cmFpbnQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgLyogaWYgbm8gY2FuZGlkYXRlcyB3ZXJlIGRyb3BwZWQgbm8gbmVlZCB0byByZXBlYXQgKi8KICAgIH0gd2hpbGUgKG51bUFQc0Ryb3BwZWQpOwoKICAgIC8qCiAgICAgKiBOb3cgd2UgaGF2ZSBhbGwgdGhlIHNjYW4gcmVzdWx0cyBpbiBvdXIgbG9jYWwgbGlzdC4gR29vZCB0aW1lIHRvIGZyZWUKICAgICAqIHVwIHRoZSB0aGUgbGlzdCB3ZSBnb3QgYXMgYSBwYXJ0IG9mIGNzckdldFNjYW5SZXN1bHQKICAgICAqLwogICAgY3NyU2NhblJlc3VsdFB1cmdlKHBNYWMsICpwU2NhblJlc3VsdExpc3QpOwoKICAgIHJldHVybiByb2FtTm93Owp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSGFuZGxlRW1wdHlTY2FuUmVzdWx0CgogICAgXGJyaWVmICAgICAgVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGludm9rZWQgaW4gQ0ZHX0NIQU5fTElTVF9TQ0FOIHN0YXRlIHdoZW4KICAgICAgICAgICAgICAgIHRoZXJlIGFyZSBubyB2YWxpZCBBUHMgaW4gdGhlIHNjYW4gcmVzdWx0IGZvciByb2FtaW5nLiBUaGlzIG1lYW5zCiAgICAgICAgICAgICAgICBvdXIgQVAgaXMgdGhlIGJlc3QgYW5kIG5vIG90aGVyIEFQIGlzIGFyb3VuZC4gTm8gcG9pbnQgaW4gc2Nhbm5pbmcKICAgICAgICAgICAgICAgIGFnYWluIGFuZCBhZ2Fpbi4gUGVyZm9ybWluZyB0aGUgZm9sbG93aW5nIGhlcmUuCiAgICAgICAgICAgICAgICAxLiBTdG9wIHRoZSBuZWlnaGJvciBzY2FuIHRpbWVyLgogICAgICAgICAgICAgICAgMmEuIElmIHRoaXMgaXMgdGhlIGZpcnN0IHRpbWUgd2UgZW5jb3VudGVyZWQgZW1wdHkgc2NhbiwgdGhlbgogICAgICAgICAgICAgICAgcmUtcmVnaXN0ZXIgd2l0aCBUTCB3aXRoIG1vZGlmaWVkIGxvb2t1cCB0aHJlc2hvbGQuCiAgICAgICAgICAgICAgICAyYi4gRWxzZSBpZiB0aGlzIGlzIHRoZSBzZWNvbmQgdGltZSB3ZSBlbmNvdW50ZXJlZCBlbXB0eSBzY2FuLAogICAgICAgICAgICAgICAgdGhlbiBzdGFydCBuZWlnaGJvciBzY2FuIHJlc3VsdHMgcmVmcmVzaCB0aW1lciAoMjBzKS4KICAgICAgICAgICAgICAgIDJjLiBFbHNlLCBub3RoaW5nIG1vcmUgdG8gZG8uCiAgICAgICAgICAgICAgICBOT1RFOiBJbiBMRlIsIGNoYW5uZWxzIHNlbGVjdGVkIGZvciBzY2FubmluZyBpcyBkZXJpdmVkIGZyb20KICAgICAgICAgICAgICAgIHRoZSBvY2N1cGllZCBjaGFubmVsIGxpc3QuIFNjYW4gY3ljbGUgZm9sbG93aW5nIG9uZSB3aGljaAogICAgICAgICAgICAgICAgeWllbGRlZCBlbXB0eSByZXN1bHRzIGlzIHNwbGl0IGludG8gdHdvIGhhbHZlczogKGkpIHNjYW4gb24KICAgICAgICAgICAgICAgIGNoYW5uZWxzIGluIHRoZSBvY2N1cGllZCBsaXN0LCBhbmQgKGlpKSBzY2FuIG9uIGNoYW5uZWxzIG5vdAogICAgICAgICAgICAgICAgaW4gdGhlIG9jY3VwaWVkIGxpc3QuIFRoaXMgaGVscHMgY29udmVyZ2luZyBmYXN0ZXIgKHdoaWxlCiAgICAgICAgICAgICAgICBsb29raW5nIGZvciBjYW5kaWRhdGVzIGluIHRoZSBvY2N1cGllZCBsaXN0IGZpcnN0KSwgYW5kIGFsc28sCiAgICAgICAgICAgICAgICBhZGRzIGNoYW5uZWxzIHRvIHRoZSBvY2N1cGllZCBjaGFubmVsIGxpc3QgdXBvbiBmaW5kaW5nIGNhbmRpZGF0ZXMKICAgICAgICAgICAgICAgIG1hdGNoaW5nIFNTSUQgcHJvZmlsZSBvZiBpbnRlcmVzdC4KCiAgICAgICAgICAgICAgICB1RW1wdHlTY2FuQ291bnQgICAgICAgICAgICAgICAgICAgICAgICAgQ29tbWVudHMKICAgICAgICAgICAgICAgIGVGaXJzdEVtcHR5U2NhbiAgICAgUHJldmlvdXMgc2NhbiB3YXMgZG9uZSBvbiBjaGFubmVscyBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2NjdXBpZWQgbGlzdCBhbmQgeWllbGRlZCBwb3RlbnRpYWwgY2FuZGlkYXRlcy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBzY2FuIGN5Y2xlIHdhcyBsaWtlbHkgdHJpZ2dlcmVkIHRocm91Z2gKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWlwdCBvZiBsb29rdXAgRE9XTiBub3RpZmljYXRpb24gZXZlbnQuCiAgICAgICAgICAgICAgICBlU2Vjb25kRW1wdHlTY2FuICAgIFByZXZpb3VzIHNjYW4gd2FzIGRvbmUgb24gY2hhbm5lbHMgaW4gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jY3VwaWVkIGxpc3QgYW5kIHlpZWxkZWQgbm8gY2FuZGlkYXRlcy4gVGhpcyBzY2FuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN5Y2xlIHdhcyB0cmlnZ2VyZWQgdGhyb3VnaCBSU1NJIG5vdGlmaWNhdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXRoIG1vZGlmaWVkIGxvb2t1cCB0aHJlc2hvbGQuCiAgICAgICAgICAgICAgICBlVGhpcmRFbXB0eVNjYW4gICAgIFByZXZpb3VzIHNjYW4gd2FzIGRvbmUgb24gY2hhbm5lbHMgTk9UIGluCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBvY2N1cGllZCBsaXN0IGFuZCB5aWVsZGVkIG5vIGNhbmRpZGF0ZXMuIFRoaXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbiBjeWNsZSB3YXMgdHJpZ2dlcmVkIGltbWVkaWF0ZWx5IGFmdGVyIHNjYW5uaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzIGluIHRoZSBvY2N1cGllZCBsaXN0IGFuZCBubyBjYW5kaWRhdGVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlcmUgZm91bmQuCiAgICAgICAgICAgICAgICBlRm91cnRoRW1wdHlTY2FuICAgIFByZXZpb3VzIHNjYW4gd2FzIGRvbmUgb24gY2hhbm5lbHMgaW4gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jY3VwaWVkIGxpc3QgYW5kIHlpZWxkZWQgbm8gY2FuZGlkYXRlcy4gVGhpcyBzY2FuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN5Y2xlIHdhcyB0cmlnZ2VyZWQgdXBvbiBleHBpcnkgb2YKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmVpZ2hib3JTY2FuUmVzdWx0c1JlZnJlc2hQZXJpb2QgKD0yMHMpLgogICAgICAgICAgICAgICAgZUZpZnRoRW1wdHlTY2FuICAgICBQcmV2aW91cyBzY2FuIHdhcyBkb25lIG9uIGNoYW5uZWxzIE5PVCBpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgb2NjdXBpZWQgbGlzdCBhbmQgeWllbGRlZCBubyBjYW5kaWRhdGVzLiBUaGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW4gY3ljbGUgd2FzIHRyaWdnZXJlZCBpbW1lZGlhdGVseSBhZnRlciBzY2FubmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVscyBpbiB0aGUgb2NjdXBpZWQgbGlzdCBhbmQgbm8gY2FuZGlkYXRlcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZXJlIGZvdW5kLgoKICAgICAgICAgICAgICAgIFsxXSwgWzIsM10gYW5kIFs0LDVdIHRvZ2V0aGVyIGZvcm0gb25lIGRpc2NyZXRlIHNldCBvZiBzY2FuIGN5Y2xlLgoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpzdGF0aWMgVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1IYW5kbGVFbXB0eVNjYW5SZXN1bHQodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIGVIYWxTdGF0dXMgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cEZUUm9hbUNhbGxiYWNrVXNyQ3R4ICBwVXNyQ3R4OwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHRBTklfQk9PTEVBTiBwZXJmb3JtUGVyaW9kaWNTY2FuID0KICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5lbXB0eVNjYW5SZWZyZXNoUGVyaW9kKSA/IFRSVUUgOiBGQUxTRTsKI2VuZGlmCgogICAgLyogU3RvcCBuZWlnaGJvciBzY2FuIHRpbWVyICovCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgIC8qCiAgICAgKiBJbmNyZWFzZSB0aGUgbmVpZ2hib3IgbG9va3VwIHRocmVzaG9sZCBieSAzIGRCCiAgICAgKiBhZnRlciBldmVyeSBzY2FuIGN5Y2xlLiBOT1RFOiB1RW1wdHlTY2FuQ291bnQKICAgICAqIHdvdWxkIGJlIGVpdGhlciAxLCAzIG9yIDUgYXQgdGhlIGVuZCBvZiBldmVyeQogICAgICogc2NhbiBjeWNsZS4KICAgICAqLwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgaWYgKCgrK3BOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQpID4gZUZpZnRoRW1wdHlTY2FuKQogICAgewogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSBlRmlmdGhFbXB0eVNjYW47CiAgICB9CiAgICBpZiAoKCgwICE9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykgfHwKICAgICAgICAgKGFicyhwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kpID4KICAgICAgICAgYWJzKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkKSkpICYmCiAgICAgICAgKChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID09IGVTZWNvbmRFbXB0eVNjYW4pIHx8CiAgICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID09IGVGb3VydGhFbXB0eVNjYW4pKSkKICAgIHsKICAgICAgICAvKgogICAgICAgICAqIElmIHRoZSBzY2FuIHdhcyB0cmlnZ2VyZWQgZHVlIHRvIGxvb2t1cERPV05Sc3NpID4gcmVhc3NvYyB0aHJlc2hvbGQsCiAgICAgICAgICogdGhlbiBpdCB3b3VsZCBiZSBhIGNvbnRpZ3VvdXMgc2NhbiBvbiBhbGwgdmFsaWQgbm9uLURGUyBjaGFubmVscy4KICAgICAgICAgKiBJZiBjaGFubmVscyBhcmUgY29uZmlndXJlZCBpbiBJTkksIHRoZW4gb25seSB0aG9zZSBjaGFubmVscyBuZWVkCiAgICAgICAgICogdG8gYmUgc2Nhbm5lZC4KICAgICAgICAgKiBJbiBlaXRoZXIgb2YgdGhlc2UgbW9kZXMsIHRoZXJlIGlzIG5vIG5lZWQgdG8gdHJpZ2dlciBhbiBpbW1lZGlhdGUKICAgICAgICAgKiBzY2FuIHVwb24gZW1wdHkgc2NhbiByZXN1bHRzIGZvciB0aGUgc2Vjb25kIGFuZCBmb3VydGggdGltZSAod2hpY2gKICAgICAgICAgKiB3b3VsZCBiZSBlcXVpdmFsZW50IHRvIHNjYW5uaW5nIG9uIGNoYW5uZWxzIGluIG5vbi1vY2N1cGllZCBsaXN0KS4KICAgICAgICAgKiBJbmNyZW1lbnRpbmcgdUVtcHR5U2NhbkNvdW50IHdpbGwgY29ycmVzcG9uZCB0byBza2lwcGluZyB0aGlzIHN0ZXAuCiAgICAgICAgICogTk9URTogZG91YmxlIGluY3JlbWVudCBvZiB1RW1wdHlTY2FuQ291bnQgY29ycmVzcG9uZHMgdG8gY29tcGxldGlvbgogICAgICAgICAqIG9mIHNjYW5zIG9uIGFsbCB2YWxpZCBjaGFubmVscy4KICAgICAgICAgKi8KICAgICAgICArK3BOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQ7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCAiRXh0cmEgaW5jcmVtZW50IG9mIGVtcHR5IHNjYW4gY291bnQgKD0lZCkiCiAgICAgICAgICAgICIgaW4gY29udGlndW91cyBzY2FuIG1vZGUiLCBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50KTsKICAgIH0KI2VuZGlmCiAgICBpZiAoKChwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKzMpIDwKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCkKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAmJiAoKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgJSAyKSA9PSAxKQojZW5kaWYKICAgICAgICApCiAgICB7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCArPSAzOwogICAgfQoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAvKiBDbGVhciBvZmYgdGhlIG9sZCBuZWlnaGJvciByZXBvcnQgZGV0YWlscyAqLwogICAgdm9zX21lbV96ZXJvKCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mbywgc2l6ZW9mKHRDc3JOZWlnaGJvclJlcG9ydEJzc0luZm8pICogTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOwojZW5kaWYKCiAgICAvKiBUcmFuc2l0aW9uIHRvIENPTk5FQ1RFRCBzdGF0ZSAqLwogICAgY3NyX25laWdoYm9yX3JvYW1fc3RhdGVfdHJhbnNpdGlvbihwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwoKICAgIC8qIFJlc2V0IGFsbCB0aGUgbmVjZXNzYXJ5IHZhcmlhYmxlcyBiZWZvcmUgdHJhbnNpdGlvbmluZyB0byB0aGUgQ09OTkVDVEVEIHN0YXRlICovCiAgICBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8ocE1hYywgc2Vzc2lvbklkKTsKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSBlRmlyc3RFbXB0eVNjYW4pCiAgICB7CiNlbmRpZgogICAgICAgIC8qIEVtcHR5IHNjYW4gcmVzdWx0cyBmb3IgdGhlIGZpcnN0IHRpbWUgKi8KICAgICAgICAvKiBSZS1yZWdpc3RlciBuZWlnaGJvciBsb29rdXAgRE9XTiB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCAqLwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwKICAgICAgICAgICAgRkwoIlJlZ2lzdGVyaW5nIERPV04gZXZlbnQgbmVpZ2hib3IgbG9va3VwIGNhbGxiYWNrIHdpdGggVEwgZm9yIFJTU0kgPSAlZCIpLAogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSk7CgogICAgICAgIC8qIFRoaXMgdXNlciBjb250ZXh0IGRhdGEgd2lsbCBiZSByZXR1cm5lZCB3aXRoIGNhbGxiYWNrICovCiAgICAgICAgcFVzckN0eCA9IHZvc19tZW1fbWFsbG9jKHNpemVvZigqcFVzckN0eCkpOwogICAgICAgIGlmIChOVUxMID09IHBVc3JDdHgpIHsKICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZhaWx1cmUiKSk7CiAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9OT01FTTsKICAgICAgICB9CiAgICAgICAgcFVzckN0eC0+cE1hYyA9IHBNYWM7CiAgICAgICAgcFVzckN0eC0+c2Vzc2lvbklkID0gc2Vzc2lvbklkOwoKICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcFVzckN0eCk7CgogICAgICAgIHZvc19tZW1fZnJlZShwVXNyQ3R4KTsKICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywKICAgICAgICAgICAgICAgICAgIEZMKCJDb3VsZG4ndCByZS1yZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjayIKICAgICAgICAgICAgICAgICAgICAgICIgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgc3RhdHVzKTsKICAgICAgICB9CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSA9IDA7CiAgICB9CiAgICBlbHNlIGlmICgocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSBlU2Vjb25kRW1wdHlTY2FuKSB8fAogICAgICAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPT0gZUZvdXJ0aEVtcHR5U2NhbikpCiAgICB7CiAgICAgICAgLyogRW1wdHkgc2NhbiByZXN1bHRzIGZvciB0aGUgc2Vjb25kIG9yIGZvdXJ0aCB0aW1lICovCgogICAgICAgIC8qIEltbWVkaWF0ZWx5IHNjYW4gb24gY2hhbm5lbHMgaW4gbm9uLW9jY3VwaWVkIGxpc3QgKi8KICAgICAgICBjc3JOZWlnaGJvclJvYW1UcmFuc2l0VG9DRkdDaGFuU2NhbihwTWFjLCBzZXNzaW9uSWQpOwogICAgfQogICAgZWxzZSBpZiAocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA+PSBlVGhpcmRFbXB0eVNjYW4pCiAgICB7CiAgICAgICAgLyogRW1wdHkgc2NhbiByZXN1bHRzIGZvciB0aGUgdGhpcmQgdGltZSAqLwogICAgICAgIGlmIChwZXJmb3JtUGVyaW9kaWNTY2FuKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJQZXJmb3JtaW5nIHBlcmlvZGljIHNjYW4sIHVFbXB0eVNjYW5Db3VudD0lZCIpLAogICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCk7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTZXQgdUVtcHR5U2NhbkNvdW50IHRvIE1BWCBzbyB0aGF0IHdlIGFsd2F5cyBlbnRlciB0aGlzCiAgICAgICAgICAgICAqIGNvbmRpdGlvbiBvbiBzdWJzZXF1ZW50IGVtcHR5IHNjYW4gcmVzdWx0cwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9IGVNYXhFbXB0eVNjYW47CgogICAgICAgICAgICAvKiBGcm9tIGhlcmUgb24sIE9OTFkgc2NhbiBvbiBjaGFubmVscyBpbiB0aGUgb2NjdXBpZWQgbGlzdCAqLwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID0gU1BMSVRfU0NBTl9PQ0NVUElFRF9MSVNUOwoKICAgICAgICAgICAgLyogU3RhcnQgZW1wdHkgc2NhbiByZWZyZXNoIHRpbWVyICovCiAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0KICAgICAgICAgICAgICAgIHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lciwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmVtcHR5U2NhblJlZnJlc2hQZXJpb2QpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciBmYWlsZWQgdG8gc3RhcnQgKCVkKSIpLAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpOwogICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciBzdGFydGVkICglZCBtcykiKSwKICAgICAgICAgICAgICAgICAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuZW1wdHlTY2FuUmVmcmVzaFBlcmlvZCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGVUaGlyZEVtcHR5U2NhbiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50KQogICAgICAgIHsKICAgICAgICAgICAgLyogU3RhcnQgbmVpZ2hib3Igc2NhbiByZXN1bHRzIHJlZnJlc2ggdGltZXIgKi8KICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPQogICAgICAgICAgICAgICAgICAgIHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lciwKICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlc3VsdHNSZWZyZXNoUGVyaW9kKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXN1bHRzIHJlZnJlc2ggdGltZXIgZmFpbGVkIHRvIHN0YXJ0ICglZCkiKSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzIsIEZMKCJOZWlnaGJvciByZXN1bHRzIHJlZnJlc2ggdGltZXIgc3RhcnRlZCAoJWQgbXMpIiksCiAgICAgICAgICAgICAgICAgICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2QgKiBWT1NfVElNRVJfVE9fTVNfVU5JVCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIk5laWdoYm9yIHJvYW0gZW1wdHkgc2NhbiBjb3VudD0lZCBzY2FuIG1vZGU9JWQiLAogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQsIHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUpOwojZW5kaWYKICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCgpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhbkNvbXBsZXRlICh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgdENzclNjYW5SZXN1bHRGaWx0ZXIgICAgc2NhbkZpbHRlcjsKICAgIHRTY2FuUmVzdWx0SGFuZGxlICAgICAgIHNjYW5SZXN1bHQ7CiAgICB0QU5JX1UzMiAgICAgICAgICAgICAgICB0ZW1wVmFsID0gMDsKICAgIHRBTklfQk9PTEVBTiAgICAgICAgICAgIHJvYW1Ob3cgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICBlSGFsU3RhdHVzICAgICAgICAgICAgICBoc3RhdHVzOwogICAgdHBGVFJvYW1DYWxsYmFja1VzckN0eCAgcFVzckN0eDsKCiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9FU0UpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgICAgICAvKiBJZiB0aGUgc3RhdGUgaXMgUkVQT1JUX1NDQU4sIHRoZW4gdGhpcyBtdXN0IGJlIHRoZSBzY2FuIGFmdGVyIHRoZSBSRVBPUlRfUVVFUlkgc3RhdGUuIFNvLCB3ZQogICAgICAgICAgIHNob3VsZCB1c2UgdGhlIEJTU0lEIGZpbHRlciBtYWRlIG91dCBvZiBuZWlnaGJvciByZXBvcnRzICovCiAgICAgICAgaWYgKChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgJiYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQojZW5kaWYKICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtQnNzSWRTY2FuRmlsdGVyKHBNYWMsIHNlc3Npb25JZCwgJnNjYW5GaWx0ZXIpOwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCIxMVIgb3IgRVNFIEFzc29jaWF0aW9uOiBQcmVwYXJlIHNjYW4gZmlsdGVyIHN0YXR1cyAgd2l0aCBuZWlnaGJvciBBUCA9ICVkIiksIGhzdGF0dXMpOwogICAgICAgICAgICB0ZW1wVmFsID0gMTsKICAgICAgICB9CiAgICAgICAgZWxzZQojZW5kaWYKICAgICAgICB7CiAgICAgICAgICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1QcmVwYXJlU2NhblByb2ZpbGVGaWx0ZXIocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2NhbkZpbHRlciwgc2Vzc2lvbklkKTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiMTFSL0VTRS9PdGhlciBBc3NvY2lhdGlvbjogUHJlcGFyZSBzY2FuIHRvIGZpbmQgbmVpZ2hib3IgQVAgZmlsdGVyIHN0YXR1cyAgPSAlZCIpLCBoc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2NhbiBGaWx0ZXIgcHJlcGFyYXRpb24gZmFpbGVkIGZvciBBc3NvYyB0eXBlICVkLi4gQmFpbGluZyBvdXQuLiIpLCB0ZW1wVmFsKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgfQogICAgICAgIGhzdGF0dXMgPSBjc3JTY2FuR2V0UmVzdWx0KHBNYWMsICZzY2FuRmlsdGVyLCAmc2NhblJlc3VsdCk7CiAgICAgICAgaWYgKGhzdGF0dXMgIT0gZUhBTF9TVEFUVVNfU1VDQ0VTUykKICAgICAgICB7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkdldCBTY2FuIFJlc3VsdCBzdGF0dXMgY29kZSAlZCIpLCBoc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgLyogUHJvY2VzcyB0aGUgc2NhbiByZXN1bHRzIGFuZCB1cGRhdGUgcm9hbSBhYmxlIEFQIGxpc3QgKi8KICAgICAgICByb2FtTm93ID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5SZXN1bHRzKHBNYWMsIHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzY2FuUmVzdWx0KTsKCiAgICAgICAgLyogRnJlZSB0aGUgc2NhbiBmaWx0ZXIgKi8KICAgICAgICBjc3JGcmVlU2NhbkZpbHRlcihwTWFjLCAmc2NhbkZpbHRlcik7CgogICAgICAgIHRlbXBWYWwgPSBjc3JMTENvdW50KCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIGlmKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgIHsKI2VuZGlmCiAgICAgICAgIHN3aXRjaChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOOgogICAgICAgICAgICAgICAgaWYgKHRlbXBWYWwpCiAgICAgICAgICAgICAgICB7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBTaW5jZSB0aGVyZSBhcmUgbm9uLXplcm8gY2FuZGlkYXRlcyBmb3VuZAogICAgICAgICAgICAgICAgICAgICAqIGFmdGVyIHRoZSBzY2FuLCByZXNldCBlbXB0eSBzY2FuIGNvdW50LgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUgPSBERUZBVUxUX1NDQU47CiNlbmRpZgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIElmIHRoaXMgaXMgYSBub24tMTFyIGFzc29jaWF0aW9uLCB0aGVuIHdlIGNhbiByZWdpc3RlcgogICAgICAgICAgICAgICAgICAgICAqIHRoZSByZWFzc29jIGNhbGxiYWNrIGhlcmUgYXMgd2UgaGF2ZSBzb21lIEFQcyBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAgKiByb2FtIGFibGUgQVAgbGlzdAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBWYWxpZCBBUHMgYXJlIGZvdW5kIGFmdGVyIHNjYW4uIE5vdyB3ZSBjYW4gaW5pdGlhdGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlLWF1dGhlbnRpY2F0aW9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNzcl9uZWlnaGJvcl9yb2FtX3N0YXRlX3RyYW5zaXRpb24ocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlCiNlbmRpZgojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogSWYgdGhpcyBpcyBhIG5vbi0xMXIgYXNzb2NpYXRpb24sIHRoZW4gd2UgY2FuIHJlZ2lzdGVyCiAgICAgICAgICAgICAgICAgICAgICogdGhlIHJlYXNzb2MgY2FsbGJhY2sgaGVyZSBhcyB3ZSBoYXZlIHNvbWUgQVBzIGluIHRoZQogICAgICAgICAgICAgICAgICAgICAqIHJvYW0gYWJsZSBBUCBsaXN0CiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFZhbGlkIEFQcyBhcmUgZm91bmQgYWZ0ZXIgc2Nhbi4gTm93IHdlIGNhbiBpbml0aWF0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICBwcmUtYXV0aGVudGljYXRpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgY3NyX25laWdoYm9yX3JvYW1fc3RhdGVfdHJhbnNpdGlvbihwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UKI2VuZGlmCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBJZiBMRlIgaXMgZW5hYmxlZCwgdGhlbiB3ZSBjYW4gcmVnaXN0ZXIgdGhlIHJlYXNzb2MKICAgICAgICAgICAgICAgICAgICAgKiBjYWxsYmFjayBoZXJlIGFzIHdlIGhhdmUgc29tZSBBUHMgaW4gdGhlIHJvYW0gYWJsZQogICAgICAgICAgICAgICAgICAgICAqIEFQIGxpc3QKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsIHNlc3Npb25JZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVmFsaWQgQVBzIGFyZSBmb3VuZCBhZnRlciBzY2FuLiBOb3cgd2UgY2FuIGluaXRpYXRlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZS1hdXRoZW50aWNhdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBjc3JfbmVpZ2hib3Jfcm9hbV9zdGF0ZV90cmFuc2l0aW9uKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZQojZW5kaWYKICAgICAgICAgICAgICAgICAgICB7CgogICAgICAgICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJDb21wbGV0ZWQgc2Nhbm5pbmcgb2YgQ0ZHIENIQU4gTElTVCBpbiBub24tMTFyIGFzc29jaWF0aW9uLiBSZWdpc3RlcmluZyByZWFzc29jIGNhbGxiYWNrIikpOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBOb3RoaW5nIG11Y2ggdG8gZG8gbm93LiBXaWxsIGNvbnRpbnVlIHRvIHJlbWFpbiBpbiB0aGlzIHN0YXRlIGluIGNhc2Ugb2Ygbm9uLTExciBhc3NvY2lhdGlvbiAqLwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJObyBjYW5kaWRhdGUgZm91bmQgYWZ0ZXIiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNjYW5uaW5nIGluIHN0YXRlICVzIC4uICIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICAgICAgICAgIC8qIEhhbmRsZSBpdCBhcHByb3ByaWF0ZWx5ICovCiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtSGFuZGxlRW1wdHlTY2FuUmVzdWx0KHBNYWMsIHNlc3Npb25JZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAgICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOOgogICAgICAgICAgICAgICAgaWYgKCF0ZW1wVmFsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiTm8gY2FuZGlkYXRlIGZvdW5kIGFmdGVyIHNjYW5uaW5nIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgImluIHN0YXRlICVzIC4uICIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICAgICAgLyogU3RvcCB0aGUgdGltZXIgaGVyZSBhcyB0aGUgc2FtZSB0aW1lciB3aWxsIGJlIHN0YXJ0ZWQgYWdhaW4gaW4gQ0ZHX0NIQU5fU0NBTl9TVEFURSAqLwogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMsIHNlc3Npb25JZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvLyBDYW4gY29tZSBvbmx5IGluIElOSVQgc3RhdGUuIFdoZXJlIGluIHdlIGFyZSBhc3NvY2lhdGVkLCB3ZSBzZW50IHNjYW4gYW5kIHVzZXIKICAgICAgICAgICAgICAgIC8vIGluIHRoZSBtZWFudGltZSBkZWNpZGVzIHRvIGRpc2Fzc29jLCB3ZSB3aWxsIGJlIGluIGluaXQgc3RhdGUgYW5kIHN0aWxsIHJlY2VpdmVkIGNhbGwKICAgICAgICAgICAgICAgIC8vIGJhY2sgaXNzdWVkLiBTaG91bGQgbm90IGNvbWUgaGVyZSBpbiBhbnkgb3RoZXIgc3RhdGUsIHByaW50aW5nIGp1c3QgaW4gY2FzZQogICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJTdGF0ZSAlcyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICAvLyBMZXRzIGp1c3QgZXhpdCBvdXQgc2lsZW50bHkuCiAgICAgICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgfQojZW5kaWYKCiAgICAgICAgaWYgKHRlbXBWYWwpCiAgICAgICAgewogICAgICAgICAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CgogICAgICAgICAgICBpZiAocm9hbU5vdykKICAgICAgICAgICAgewojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgICBpZighY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICAgICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgIEZMKCJJbW1lZGlhdGUgcm9hbS1kZXJlZ2lzdGVyIFVQIGluZGljYXRpb24uIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSk7CgogICAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKCiAgICAgICAgICAgICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkNvdWxkbid0IGRlcmVnaXN0ZXIgbG9va3VwIFVQIGNhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAgICAgfQojZW5kaWYKCiAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1UcmlnZ2VySGFuZG9mZihwTWFjLCBzZXNzaW9uSWQpOwogICAgICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgICAgIH0KCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgICAgICB7CiNlbmRpZgogICAgICAgICAgICAgICAgaHN0YXR1cyA9IHZvc190aW1lcl9zdGFydCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyLAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZCk7CgogICAgICAgICAgICAgICAgLyogVGhpcyB0aW1lciBzaG91bGQgYmUgc3RhcnRlZCBiZWZvcmUgcmVnaXN0ZXJpbmcgdGhlIFJlYXNzb2MKICAgICAgICAgICAgICAgICogY2FsbGJhY2sgd2l0aCBUTC4gVGhpcyBpcyBiZWNhdXNlLCBpdCBpcyB2ZXJ5IGxpa2VseSB0aGF0IHRoZQogICAgICAgICAgICAgICAgKiBjYWxsYmFjayBnZXR0aW5nIGNhbGxlZCBpbW1lZGlhdGVseSBhbmQgdGhlIHRpbWVyIHdvdWxkIG5ldmVyCiAgICAgICAgICAgICAgICAqIGJlIHN0b3BwZWQgd2hlbiBwcmUtYXV0aCBpcyBpbiBwcm9ncmVzcyAqLwogICAgICAgICAgICAgICAgaWYgKGhzdGF0dXMgIT0gZUhBTF9TVEFUVVNfU1VDQ0VTUykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoCiAgICAgICAgICAgICAgICAgICAgIk5laWdoYm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lciBmYWlsZWQgdG8gc3RhcnQsIHN0YXR1cyA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHN0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEw7CiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMDsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKAogICAgICAgICAgICAgICAgICJSZWdpc3RlcmluZyBET1dOIGV2ZW50IFJlYXNzb2MgY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpKTsKICAgICAgICAgICAgICAgIHBVc3JDdHggPSB2b3NfbWVtX21hbGxvYyhzaXplb2YoKnBVc3JDdHgpKTsKICAgICAgICAgICAgICAgIGlmIChOVUxMID09IHBVc3JDdHgpIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkFsbG9jYXRpb24gZmFpbGVkIGZvciBwVXNyQ3R4IikpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHBVc3JDdHgtPnBNYWMgPSBwTWFjOwogICAgICAgICAgICAgICAgcFVzckN0eC0+c2Vzc2lvbklkID0gc2Vzc2lvbklkOwogICAgICAgICAgICAgICAgLyogUmVnaXN0ZXIgYSByZWFzc29jIEluZGljYXRpb24gY2FsbGJhY2sgKi8KICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcFVzckN0eCk7CiAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocFVzckN0eCk7CiAgICAgICAgICAgICAgICBpZiAoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgKICAgICAgICAgICAgICAgICAgICAgIkNvdWxkbid0IHJlZ2lzdGVyIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICB9CgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECmlmIChjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICB7CiAgICBpZiAoIXRlbXBWYWwgfHwgIXJvYW1Ob3cpCiAgICB7CiAgICAgICAgaWYgKChlU01FX1JPQU1fVFJJR0dFUl9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pIHx8CiAgICAgICAgICAgIChlU01FX1JPQU1fVFJJR0dFUl9GQVNUX1JPQU0gPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikpCiAgICAgICAgewogICAgICAgICAgIC8qIFRoaXMgaXMgaW9jdGwgYmFzZWQgcm9hbWluZyBpZiB3ZSBkaWQgbm90IGZpbmQgYW55IHJvYW1hYmxlCiAgICAgICAgICAgICogY2FuZGlkYXRlIHRoZW4ganVzdCBsb2cgaXQuICovCiAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgICAgIEZMKCJ0ZW1wVmFsID0gJXUsIHJvYW1Ob3cgPSAlZCB1T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gJWQiKSwKICAgICAgICAgICAgICAgICAgdGVtcFZhbCwgcm9hbU5vdywgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikKICAgICAgICAgICB7CiAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIHNlc3Npb25JZCwgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9OT19DQU5EX0ZPVU5EX09SX05PVF9ST0FNSU5HX05PVyk7CiAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgICAgICAgIH0KICAgICAgICAgICBlbHNlCiAgICAgICAgICAgewogICAgICAgICAgICAvKiBUaGVyZSBpcyBubyBjYW5kaWRhdGUgb3IgV2UgYXJlIG5vdCByb2FtaW5nIE5vdy4KICAgICAgICAgICAgICogSW5mb3JtIHRoZSBGVyB0byByZXN0YXJ0IFJvYW0gT2ZmbG9hZCBTY2FuICAqLwogICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBzZXNzaW9uSWQsIFJPQU1fU0NBTl9PRkZMT0FEX1JFU1RBUlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9OT19DQU5EX0ZPVU5EX09SX05PVF9ST0FNSU5HX05PVyk7CiAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgIGNzcl9uZWlnaGJvcl9yb2FtX3N0YXRlX3RyYW5zaXRpb24ocE1hYywgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkKTsKICAgIH0KICAgfQojZW5kaWYKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwoKfQoKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1TY2FuUmVxdWVzdENhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHRoZSBjYWxsYmFjayBmdW5jdGlvbiByZWdpc3RlcmVkIGluIGNzclNjYW5SZXF1ZXN0KCkgdG8KICAgICAgICAgICAgaW5kaWNhdGUgdGhlIGNvbXBsZXRpb24gb2Ygc2Nhbi4gSWYgc2NhbiBpcyBjb21wbGV0ZWQgZm9yIGFsbCB0aGUgY2hhbm5lbHMgaW4KICAgICAgICAgICAgdGhlIGNoYW5uZWwgbGlzdCwgdGhpcyBmdW5jdGlvbiBnZXRzIHRoZSBzY2FuIHJlc3VsdCBhbmQgc3RhcnRzIHRoZSByZWZyZXNoIHJlc3VsdHMKICAgICAgICAgICAgdGltZXIgdG8gYXZvaWQgaGF2aW5nIHN0YWxlIHJlc3VsdHMuIElmIHNjYW4gaXMgbm90IGNvbXBsZXRlZCBvbiBhbGwgdGhlIGNoYW5uZWxzLAogICAgICAgICAgICBpdCByZXN0YXJ0cyB0aGUgbmVpZ2hib3Igc2NhbiB0aW1lciB3aGljaCBvbiBleHBpcnkgaXNzdWVzIHNjYW4gb24gdGhlIG5leHQKICAgICAgICAgICAgY2hhbm5lbAoKICAgIFxwYXJhbSAgaGFsSGFuZGxlIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwQ29udGV4dCAtIG5vdCB1c2VkCiAgICAgICAgICAgIHNjYW5JZCAtIG5vdCB1c2VkCiAgICAgICAgICAgIHN0YXR1cyAtIG5vdCB1c2VkCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVNjYW5SZXF1ZXN0Q2FsbGJhY2sodEhhbEhhbmRsZSBoYWxIYW5kbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpwQ29udGV4dCwgdEFOSV9VOCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1UzMiBzY2FuSWQsIGVDc3JTY2FuU3RhdHVzIHN0YXR1cykKewogICAgdHBBbmlTaXJHbG9iYWwgICAgICAgICAgICAgICAgICBwTWFjID0gKHRwQW5pU2lyR2xvYmFsKSBoYWxIYW5kbGU7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIHRBTklfVTggICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudENoYW5JbmRleDsKICAgIGVIYWxTdGF0dXMgICAgICAgICAgICAgIGhzdGF0dXM7CgogICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICB7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgaWYgKCFjc3JSb2FtSXNTdGFNb2RlKHBNYWMsIHNlc3Npb25JZCkpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwKICAgICAgICAgICAgICAgICAgIEZMKCJJZ25vcmluZyBzY2FuIHJlcXVlc3QgY2FsbGJhY2sgb24gbm9uLWluZnJhIgogICAgICAgICAgICAgICAgICAgInNlc3Npb24gJWQgaW4gc3RhdGUgJXMiKSwKICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCwgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLHNlc3Npb25JZCkpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIHdoZW4gZmFzdCByb2FtIGlzIGRpc2FibGVkLiBJZ25vcmUgaXQiKSk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgIH0KI2VuZGlmCiAgICB9CgogICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIC8qIFRoaXMgY2FuIGhhcHBlbiB3aGVuIHdlIHJlY2VpdmUgYSBVUCBldmVudCBmcm9tIFRMIGluIGFueSBvZiB0aGUgc2NhbiBzdGF0ZXMuIFNpbGVudGx5IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gQ09OTkVDVEVEIHN0YXRlLiBNdXN0IGJlIGJlY2F1c2UgYSBVUCBldmVudCBmcm9tIFRMIGFmdGVyIGlzc3Vpbmcgc2NhbiByZXF1ZXN0LiBJZ25vcmUgaXQiKSk7CiAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICAvKiAtMSBpcyBkb25lIGJlY2F1c2UgdGhlIGNoYW5JbmRleCB3b3VsZCBoYXZlIGdvdCBpbmNyZW1lbnRlZCBhZnRlcgogICAgICBpc3N1aW5nIGEgc3VjY2Vzc2Z1bCBzY2FuIHJlcXVlc3QgKi8KICAgIGN1cnJlbnRDaGFuSW5kZXggPSAocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4KSA/IChwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggLSAxKSA6IDA7CgogICAgLyogVmFsaWRhdGUgaW5wdXRzICovCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KSB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgRkwoImNzck5laWdoYm9yUm9hbVNjYW5SZXF1ZXN0Q2FsbGJhY2sgcmVjZWl2ZWQgZm9yIENoYW5uZWwgPSAlZCwgIgogICAgICAgICAgICAgICAgIkNoYW5JbmRleCA9ICVkIiksCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbY3VycmVudENoYW5JbmRleF0sCiAgICAgICAgICAgICAgICBjdXJyZW50Q2hhbkluZGV4KTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIlJlY2VpdmVkIGR1cmluZyBjbGVhbi11cC4gU2lsZW50bHkgaWdub3JlIHNjYW4gY29tcGxldGlvbiBldmVudC4iKSk7CiAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAoZUFOSV9CT09MRUFOX0ZBTFNFID09IHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY2hhbkxpc3RTY2FuSW5Qcm9ncmVzcykKICAgIHsKICAgICAgICAvKiBTY2FuIGlzIGNvbXBsZXRlZCBpbiB0aGUgIENGR19DSEFOX1NDQU4gc3RhdGUuIFdlIGNhbiB0cmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlCiAgICAgICAgICAganVzdCB0byBnZXQgdGhlIHJlc3VsdHMgYW5kIHBlcmZvcm0gUFJFQVVUSCAqLwogICAgICAgIC8qIE5vdyB3ZSBoYXZlIGNvbXBsZXRlZCBzY2FubmluZyB0aGUgY2hhbm5lbCBsaXN0LiBXZSBoYXZlIGdldCB0aGUgcmVzdWx0IGJ5IGFwcGx5aW5nIGFwcHJvcHJpYXRlIGZpbHRlcgogICAgICAgICAgIHNvcnQgdGhlIHJlc3VsdHMgYmFzZWQgb24gbmVpZ2hib3JTY29yZSBhbmQgUlNTSSBhbmQgc2VsZWN0IHRoZSBiZXN0IGNhbmRpZGF0ZSBvdXQgb2YgdGhlIGxpc3QgKi8KICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJDaGFubmVsIGxpc3Qgc2NhbiBjb21wbGV0ZWQuIEN1cnJlbnQgY2hhbiBpbmRleCA9ICVkIiksIGN1cnJlbnRDaGFuSW5kZXgpOwoKICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4ICE9IDApCiAgICAgICAgewogICAgICAgICAgIFZPU19BU1NFUlQocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4ID09IDApOwogICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIH0KCiAgICAgICAgaHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuQ29tcGxldGUocE1hYywgc2Vzc2lvbklkKTsKCiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBwcm9jZXNzIGNvbXBsZXRlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgICAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CgogICAgICAgIC8qIFJlc3RhcnQgdGhlIHRpbWVyIGZvciB0aGUgbmV4dCBzY2FuIHNlcXVlbmNlIGFzIHNjYW5uaW5nIGlzIG5vdCBvdmVyICovCiAgICAgICAgaHN0YXR1cyA9IHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyLAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JTY2FuUGVyaW9kKTsKICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgLyogVGltZXIgc3RhcnQgZmFpbGVkLi4gU2hvdWxkIHdlIEFTU0VSVCBoZXJlPz8/ICovCiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBQQUwgVGltZXIgc3RhcnQgZmFpbGVkLCBzdGF0dXMgPSAlZCwgSWdub3Jpbmcgc3RhdGUgdHJhbnNpdGlvbiIpLCBzdGF0dXMpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgICAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVNjYW5SZXN1bHRSZXF1ZXN0Q2FsbGJhY2sKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHJlZ2lzdGVyZWQgaW4gY3NyU2NhblJlcXVlc3RMZnJSZXN1bHQoKSB0bwogICAgICAgICAgICBpbmRpY2F0ZSB0aGUgY29tcGxldGlvbiBvZiBzY2FuLiBJZiBzY2FuIGlzIGNvbXBsZXRlZCBmb3IgYWxsIHRoZSBjaGFubmVscyBpbgogICAgICAgICAgICB0aGUgY2hhbm5lbCBsaXN0LCB0aGlzIGZ1bmN0aW9uIGdldHMgdGhlIHNjYW4gcmVzdWx0IGFuZCB0cmVhdHMgdGhlbSBhcyBjYW5kaWRhdGVzCgogICAgXHBhcmFtICBoYWxIYW5kbGUgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBDb250ZXh0IC0gbm90IHVzZWQKICAgICAgICAgICAgc2NhbklkIC0gbm90IHVzZWQKICAgICAgICAgICAgc3RhdHVzIC0gbm90IHVzZWQKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtU2NhblJlc3VsdFJlcXVlc3RDYWxsYmFjayh0SGFsSGFuZGxlIGhhbEhhbmRsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpwQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1UzMiBzY2FuSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNzclNjYW5TdGF0dXMgc3RhdHVzKQp7CiAgICB0cEFuaVNpckdsb2JhbCAgICAgICAgICAgICAgICBwTWFjID0gKHRwQW5pU2lyR2xvYmFsKSBoYWxIYW5kbGU7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgZUhhbFN0YXR1cyAgICAgICAgICAgICAgaHN0YXR1czsKCiAgICBzbXNMb2cocE1hYywgTE9HMiwgRkwoImNhbGxlZCAiKSk7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgLyogd2UgbXVzdCBiZSBpbiBjb25uZWN0ZWQgc3RhdGUsIGlmIG5vdCBpZ25vcmUgaXQgKi8KICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIlJlY2VpdmVkIGluIG5vdCBDT05ORUNURUQgc3RhdGUuIElnbm9yZSBpdCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICAvKiBOb3cgd2UgaGF2ZSBjb21wbGV0ZWQgc2Nhbm5pbmcgdGhlIGNoYW5uZWwgbGlzdC4gV2UgaGF2ZSBnZXQgdGhlIHJlc3VsdCBieSBhcHBseWluZyBhcHByb3ByaWF0ZSBmaWx0ZXIKICAgICAgIHNvcnQgdGhlIHJlc3VsdHMgYmFzZWQgb24gbmVpZ2hib3JTY29yZSBhbmQgUlNTSSBhbmQgc2VsZWN0IHRoZSBiZXN0IGNhbmRpZGF0ZSBvdXQgb2YgdGhlIGxpc3QgKi8KCiAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5Db21wbGV0ZShwTWFjLCBzZXNzaW9uSWQpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIHByb2Nlc3MgY29tcGxldGUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIGhzdGF0dXMpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KI2VuZGlmIC8vV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Db250aWd1b3VzU2NhblJlcXVlc3RDYWxsYmFjayh0SGFsSGFuZGxlIGhhbEhhbmRsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpwQ29udGV4dCwgdEFOSV9VOCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VMzIgc2NhbklkLCBlQ3NyU2NhblN0YXR1cyBzdGF0dXMpCnsKICAgIHRwQW5pU2lyR2xvYmFsICAgICAgICAgICAgICAgcE1hYyA9ICh0cEFuaVNpckdsb2JhbCkgaGFsSGFuZGxlOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CiAgICBlSGFsU3RhdHVzIGhzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgewogICAgICAgIHNlc3Npb25JZCA9ICooKHRBTklfVTMyKilwQ29udGV4dCk7CiAgICAgICAgaWYgKCFjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYyxzZXNzaW9uSWQpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCB3aGVuIGZhc3Qgcm9hbSBpcyBkaXNhYmxlZC4gSWdub3JlIGl0IikpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICB9CiAgICB9CgogICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIC8qIFRoaXMgY2FuIGhhcHBlbiB3aGVuIHdlIHJlY2VpdmUgYSBVUCBldmVudCBmcm9tIFRMIGluIGFueSBvZiB0aGUgc2NhbiBzdGF0ZXMuIFNpbGVudGx5IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gQ09OTkVDVEVEIHN0YXRlLiBNdXN0IGJlIGJlY2F1c2UgYSBVUCBldmVudCBmcm9tIFRMIGFmdGVyIGlzc3Vpbmcgc2NhbiByZXF1ZXN0LiBJZ25vcmUgaXQiKSk7CiAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gSU5JVCBzdGF0ZS4gTXVzdCBoYXZlIGRpc2Nvbm5lY3RlZC4gSWdub3JlIGl0IikpOwogICAgICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCAiJXM6IHByb2Nlc3Mgc2NhbiByZXN1bHRzIiwgX19mdW5jX18pOwogICAgaHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuQ29tcGxldGUocE1hYywgc2Vzc2lvbklkKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBwcm9jZXNzIGNvbXBsZXRlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgIH0KCiAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwoKICAgIHJldHVybiBoc3RhdHVzOwp9CiNlbmRpZgoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUlzc3VlQmdTY2FuUmVxdWVzdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpc3N1ZXMgQ1NSIHNjYW4gcmVxdWVzdCBhZnRlciBwb3B1bGF0aW5nIGFsbCB0aGUgQkcgc2NhbiBwYXJhbXMKICAgICAgICAgICAgcGFzc2VkCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwQmdTY2FuUGFyYW1zIC0gUGFyYW1zIHRoYXQgbmVlZCB0byBiZSBwb3B1bGF0ZWQgaW50byBjc3IgU2NhbiByZXF1ZXN0CgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSXNzdWVCZ1NjYW5SZXF1ZXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRDc3JCR1NjYW5SZXF1ZXN0ICpwQmdTY2FuUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1UzMiBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzclNjYW5Db21wbGV0ZUNhbGxiYWNrIGNhbGxiYWNrZm4pCnsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRBTklfVTMyIHNjYW5JZDsKICAgIHRDc3JTY2FuUmVxdWVzdCBzY2FuUmVxOwogICAgdEFOSV9VOCBjaGFubmVsOwogICAgdm9pZCAqIHVzZXJEYXRhID0gTlVMTDsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CgogICAgaWYgKDEgPT0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJDaGFubmVsID0gJWQsIENoYW5JbmRleCA9ICVkIiksCiAgICAgICAgICAgIHBCZ1NjYW5QYXJhbXMtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0WzBdLAogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgpOwoKICAgIC8vc2VuZCBkb3duIHRoZSBzY2FuIHJlcSBmb3IgMSBjaGFubmVsIG9uIHRoZSBhc3NvY2lhdGVkIFNTSUQKICAgIHZvc19tZW1fc2V0KCZzY2FuUmVxLCBzaXplb2YodENzclNjYW5SZXF1ZXN0KSwgMCk7CiAgICAvKiBGaWxsIGluIHRoZSBTU0lEIEluZm8gKi8KICAgIHNjYW5SZXEuU1NJRHMubnVtT2ZTU0lEcyA9IDE7CiAgICBzY2FuUmVxLlNTSURzLlNTSURMaXN0ID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JTU0lESW5mbykgKiBzY2FuUmVxLlNTSURzLm51bU9mU1NJRHMpOwogICAgaWYgKE5VTEwgPT0gc2NhblJlcS5TU0lEcy5TU0lETGlzdCkKICAgIHsKICAgICAgIC8vZXJyIG1zZwogICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJDb3VsZG4ndCBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBTU0lELi5GcmVlaW5nIG1lbW9yeSBhbGxvY2F0ZWQgZm9yIENoYW5uZWwgTGlzdCIpKTsKICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgdm9zX21lbV96ZXJvKHNjYW5SZXEuU1NJRHMuU1NJRExpc3QsIHNpemVvZih0Q3NyU1NJREluZm8pICogc2NhblJlcS5TU0lEcy5udW1PZlNTSURzKTsKCiAgICBzY2FuUmVxLlNTSURzLlNTSURMaXN0WzBdLmhhbmRvZmZQZXJtaXR0ZWQgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgIHNjYW5SZXEuU1NJRHMuU1NJRExpc3RbMF0uc3NpZEhpZGRlbiA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgdm9zX21lbV9jb3B5KCh2b2lkICopJnNjYW5SZXEuU1NJRHMuU1NJRExpc3RbMF0uU1NJRCwgKHZvaWQgKikmcEJnU2NhblBhcmFtcy0+U1NJRCwgc2l6ZW9mKHBCZ1NjYW5QYXJhbXMtPlNTSUQpKTsKCiAgICBzY2FuUmVxLkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgPSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzOwogICAgaWYgKDEgPT0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykKICAgIHsKICAgICAgICBjaGFubmVsID0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbMF07CiAgICAgICAgc2NhblJlcS5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9ICZjaGFubmVsOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHNjYW5SZXEuQ2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdDsKICAgIH0KCiAgICBzY2FuUmVxLkJTU1R5cGUgPSBlQ1NSX0JTU19UWVBFX0lORlJBU1RSVUNUVVJFOwogICAgc2NhblJlcS5zY2FuVHlwZSA9IGVTSVJfQUNUSVZFX1NDQU47CiAgICBzY2FuUmVxLnJlcXVlc3RUeXBlID0gZUNTUl9TQ0FOX0hPX0JHX1NDQU47CiAgICBzY2FuUmVxLm1heENoblRpbWUgPSBwQmdTY2FuUGFyYW1zLT5tYXhDaG5UaW1lOwogICAgc2NhblJlcS5taW5DaG5UaW1lID0gcEJnU2NhblBhcmFtcy0+bWluQ2huVGltZTsKCiAgICB1c2VyRGF0YSA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0QU5JX1UzMikpOwogICAgaWYgKE5VTEwgPT0gdXNlckRhdGEpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJGYWlsZWQgdG8gYWxsb2NhdGUgbWVtb3J5IGZvciBzY2FuIHJlcXVlc3QiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHNjYW5SZXEuU1NJRHMuU1NJRExpc3QpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgKigodEFOSV9VMzIqKXVzZXJEYXRhKSA9IHNlc3Npb25JZDsKICAgIHN0YXR1cyA9IGNzclNjYW5SZXF1ZXN0KHBNYWMsIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQsICZzY2FuUmVxLAogICAgICAgICAgICAgICAgICAgICAgICAmc2NhbklkLCBjYWxsYmFja2ZuLCAodm9pZCAqKSB1c2VyRGF0YSk7CiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJDU1IgU2NhbiBSZXF1ZXN0IGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBzdGF0dXMpOwogICAgICAgIHZvc19tZW1fZnJlZShzY2FuUmVxLlNTSURzLlNTSURMaXN0KTsKICAgICAgICB2b3NfbWVtX2ZyZWUodXNlckRhdGEpOwogICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKCiAgICB2b3NfbWVtX2ZyZWUoc2NhblJlcS5TU0lEcy5TU0lETGlzdCk7CiAgICBpZiAoMSA9PSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzKQogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwKICAgICAgICAgICAgICAgIEZMKCJDaGFubmVsIExpc3QgQWRkcmVzcyA9ICVwSywgQWN0dWFsIGluZGV4ID0gJWQiKSwKICAgICAgICAgICAgICAgICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbMF0sCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgpOwoKICAgIHJldHVybiBzdGF0dXM7Cn0KCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbUZpbGxOb25DaGFubmVsQmdTY2FuUGFyYW1zICh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cENzckJHU2NhblJlcXVlc3QgYmdTY2FuUGFyYW1zKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIHRBTklfVTggICAgICAgICAgICAgYnJvYWRjYXN0QnNzaWRbXSA9IHsgMHhGRiwgMHhGRiwgMHhGRiwgMHhGRiwgMHhGRiwgMHhGRiB9OwoKICAgIHZvc19tZW1fY29weShiZ1NjYW5QYXJhbXMtPmJzc2lkLCBicm9hZGNhc3RCc3NpZCwgc2l6ZW9mKHRDc3JCc3NpZCkpOwogICAgYmdTY2FuUGFyYW1zLT5TU0lELmxlbmd0aCA9CiAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuU1NJRC5sZW5ndGg7CiAgICB2b3NfbWVtX2NvcHkoYmdTY2FuUGFyYW1zLT5TU0lELnNzSWQsCiAgICAgICAgcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuU1NJRC5zc0lkLAogICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQubGVuZ3RoKTsKCiAgICBiZ1NjYW5QYXJhbXMtPm1pbkNoblRpbWUgPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1pbkNoYW5uZWxTY2FuVGltZTsKICAgIGJnU2NhblBhcmFtcy0+bWF4Q2huVGltZSA9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWF4Q2hhbm5lbFNjYW5UaW1lOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUJnU2NhbgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBpbnZva2VkIG9uIGV2ZXJ5IGV4cGlyeSBvZiBuZWlnaGJvclNjYW5UaW1lciB0aWxsIGFsbAogICAgICAgICAgICB0aGUgY2hhbm5lbHMgaW4gdGhlIGNoYW5uZWwgbGlzdCBhcmUgc2Nhbm5lZC4gSXQgcG9wdWxhdGVzIG5lY2Vzc2FyeQogICAgICAgICAgICBwYXJhbWV0ZXJzIGZvciBCRyBzY2FuIGFuZCBjYWxscyBhcHByb3ByaWF0ZSBBUCB0byBpbnZva2UgdGhlIENTUiBzY2FuCiAgICAgICAgICAgIHJlcXVlc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUJnU2Nhbih0cEFuaVNpckdsb2JhbCBwTWFjLCB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgZUhhbFN0YXR1cyAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIHRDc3JCR1NjYW5SZXF1ZXN0ICAgYmdTY2FuUGFyYW1zOwogICAgdEFOSV9VOCAgICAgICAgICAgICBjaGFubmVsID0gMDsKCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0CiAgICAgICAgJiYKICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscykgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIkNoYW5uZWwgTGlzdCBBZGRyZXNzID0gJXBLIiksICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbMF0pOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkNoYW5uZWwgTGlzdCBFbXB0eSIpKTsKICAgICAgICAvLyBHbyBiYWNrIGFuZCByZXN0YXJ0LiBNb3N0bHkgdGltZXIgc3RhcnQgZmFpbHVyZSBoYXMgb2NjdXJyZWQuCiAgICAgICAgLy8gV2hlbiB0aW1lciBzdGFydCBpcyBkZWNsYXJlZCBhIGZhaWx1cmUsIHRoZW4gd2UgZGVsZXRlIHRoZSBsaXN0LgogICAgICAgIC8vIFNob3VsZCBub3QgaGFwcGVuIG5vdyBhcyB3ZSBzdG9wIGFuZCB0aGVuIG9ubHkgc3RhcnQgdGhlIHNjYW4gdGltZXIuCiAgICAgICAgLy8gc3RpbGwgaGFuZGxlIHRoZSB1bmxpa2VseSBjYXNlLgogICAgICAgIGNzck5laWdoYm9yUm9hbUhhbmRsZUVtcHR5U2NhblJlc3VsdChwTWFjLCBzZXNzaW9uSWQpOwogICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CgogICAgLyogVmFsaWRhdGUgdGhlIGN1cnJlbnRDaGFuSW5kZXggdmFsdWUgYmVmb3JlIHVzaW5nIGl0IHRvIGluZGV4IHRoZSBDaGFubmVsTGlzdCBhcnJheSAqLwogICAgaWYgKCBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgKICAgICAgICAgICAgPiBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscykKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJJbnZhbGlkIGNoYW5uZWwgaW5kZXg6ICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCk7CiAgICAgICAgLy8gR28gYmFjayBhbmQgcmVzdGFydC4KICAgICAgICBjc3JOZWlnaGJvclJvYW1IYW5kbGVFbXB0eVNjYW5SZXN1bHQocE1hYywgc2Vzc2lvbklkKTsKICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgfQoKICAgIC8qIE5lZWQgdG8gcGVyZm9ybSBzY2FuIGhlcmUgYmVmb3JlIGdldHRpbmcgdGhlIGxpc3QgKi8KCiAgICB2b3NfbWVtX3NldCgmYmdTY2FuUGFyYW1zLCBzaXplb2YodENzckJHU2NhblJlcXVlc3QpLCAwKTsKCiAgICBjaGFubmVsID0gcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0W3BOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleF07CiAgICBiZ1NjYW5QYXJhbXMuQ2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyA9IDE7CiAgICBiZ1NjYW5QYXJhbXMuQ2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSAmY2hhbm5lbDsKCiAgICBjc3JOZWlnaGJvclJvYW1GaWxsTm9uQ2hhbm5lbEJnU2NhblBhcmFtcyhwTWFjLCBzZXNzaW9uSWQsICZiZ1NjYW5QYXJhbXMpOwogICAvKiBVcGRhdGUgdGhlIHBhc3NpdmUgc2NhbiB0aW1lIGZvciBERlMgY2hhbm5lbCAqLwogICBpZiAoKFRSVUUgPT0gQ1NSX0lTX0NIQU5ORUxfREZTKGNoYW5uZWwpKSAmJgogICAgICAgKENTUl9ST0FNSU5HX0RGU19DSEFOTkVMX0RJU0FCTEVEICE9CiAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uYWxsb3dERlNDaGFubmVsUm9hbSkpCiAgIHsKICAgICAgICBiZ1NjYW5QYXJhbXMubWluQ2huVGltZSA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ublBhc3NpdmVNaW5DaG5UaW1lOwogICAgICAgIGJnU2NhblBhcmFtcy5tYXhDaG5UaW1lID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uUGFzc2l2ZU1heENoblRpbWU7CiAgIH0KCiAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZUJnU2NhblJlcXVlc3QocE1hYywgJmJnU2NhblBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQsIGNzck5laWdoYm9yUm9hbVNjYW5SZXF1ZXN0Q2FsbGJhY2spOwogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiSXNzdWUgb2YgQkcgU2NhbiByZXF1ZXN0IGZhaWxlZDogU3RhdHVzID0gJWQiKSwgc3RhdHVzKTsKICAgIH0KCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgrKzsKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPj0KICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiQ29tcGxldGVkIHNjYW5uaW5nIGNoYW5uZWxzIGluIENoYW5uZWwgTGlzdDogQ3VyckNoYW5JbmRleCA9ICVkLCBOdW0gQ2hhbm5lbHMgPSAlZCIpLAogICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCwKICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyk7CiAgICAgICAgLyogV2UgaGF2ZSBjb21wbGV0ZWQgc2Nhbm5pbmcgYWxsIHRoZSBjaGFubmVscyAqLwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA9IDA7CiAgICAgICAgLyogV2UgYXJlIG5vIGxvbmdlciBzY2FubmluZyB0aGUgY2hhbm5lbCBsaXN0LiBOZXh0IHRpbWVyIGZpcmluZyBzaG91bGQgYmUgdXNlZCB0byBnZXQgdGhlIHNjYW4gcmVzdWx0cwogICAgICAgICAgIGFuZCBzZWxlY3QgdGhlIGJlc3QgQVAgaW4gdGhlIGxpc3QgKi8KICAgICAgICBpZiAoZUFOSV9CT09MRUFOX1RSVUUgPT0gcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jaGFuTGlzdFNjYW5JblByb2dyZXNzKQogICAgICAgIHsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jaGFuTGlzdFNjYW5JblByb2dyZXNzID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKiBJZiB0aGUgc3RhdHVzIGlzIG5vdCBzdWNjZXNzLCB3ZSBuZWVkIHRvIGNhbGwgdGhlIGNhbGxiYWNrCiAgICAgICAgICogcm91dGluZSBzbyB0aGF0IHRoZSBzdGF0ZSBtYWNoaW5lIGRvZXMgbm90IGdldCBzdHVjay4KICAgICAgICAgKi8KICAgICAgICBjc3JOZWlnaGJvclJvYW1TY2FuUmVxdWVzdENhbGxiYWNrKHBNYWMsIE5VTEwsIHNlc3Npb25JZCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVDU1JfU0NBTl9GQUlMVVJFKTsKICAgIH0KCiAgICByZXR1cm4gc3RhdHVzOwp9CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVBlcmZvcm1Db250aWd1b3VzQmdTY2FuKHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VMzIgc2Vzc2lvbklkKQp7CiAgICBlSGFsU3RhdHVzICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRDc3JCR1NjYW5SZXF1ZXN0ICAgYmdTY2FuUGFyYW1zOwogICAgdEFOSV9VOCAgIG51bU9mQ2hhbm5lbHMgPSAwLCBpID0gMDsKICAgIHRBTklfVTggICAqY2hhbm5lbExpc3QgPSBOVUxMOwogICAgdEFOSV9VOCAgICpwSW5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICB0QU5JX1U4ICAgdG1wQ2hhbm5lbExpc3RbV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOXTsKCiAgICB2b3NfbWVtX3NldCgmYmdTY2FuUGFyYW1zLCBzaXplb2YodENzckJHU2NhblJlcXVlc3QpLCAwKTsKCiAgICAvKiBDb250aWd1b3VzbHkgc2NhbiBhbGwgY2hhbm5lbHMgZnJvbSB2YWxpZCBsaXN0ICovCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJnZXQgdmFsaWQgY2hhbm5lbCBsaXN0IikpOwoKICAgIG51bU9mQ2hhbm5lbHMgPSBzaXplb2YocE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0KTsKCiAgICBpZighSEFMX1NUQVRVU19TVUNDRVNTKGNzckdldENmZ1ZhbGlkQ2hhbm5lbHMocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VOCAqKXBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VMzIgKikgJm51bU9mQ2hhbm5lbHMpKSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkNvdWxkIG5vdCBnZXQgdmFsaWQgY2hhbm5lbCBsaXN0IikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgcEluQ2hhbm5lbExpc3QgPSBwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3Q7CgogICAgaWYgKENTUl9JU19ST0FNX0lOVFJBX0JBTkRfRU5BQkxFRChwTWFjKSkKICAgIHsKICAgICAgICBjc3JOZWlnaGJvclJvYW1DaGFubmVsc0ZpbHRlckJ5Q3VycmVudEJhbmQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEluQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXBDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbnVtT2ZDaGFubmVscyk7CiAgICAgICAgcEluQ2hhbm5lbExpc3QgPSB0bXBDaGFubmVsTGlzdDsKICAgIH0KCiAgICBjaGFubmVsTGlzdCA9IHZvc19tZW1fbWFsbG9jKG51bU9mQ2hhbm5lbHMpOwogICAgaWYgKCBOVUxMID09IGNoYW5uZWxMaXN0ICkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoImNvdWxkIG5vdCBhbGxvY2F0ZSBtZW1vcnkgZm9yIGNoYW5uZWxMaXN0IikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgdm9zX21lbV9jb3B5KGNoYW5uZWxMaXN0LCAodEFOSV9VOCAqKXBJbkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgKiBzaXplb2YodEFOSV9VOCkpOwoKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gbnVtT2ZDaGFubmVsczsKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IGNoYW5uZWxMaXN0OwogICAgZm9yIChpID0gMDsgaSA8IG51bU9mQ2hhbm5lbHM7IGkrKykKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICIlczogdmFsaWQgY2hhbm5lbCBsaXN0ID0gJWQiLAogICAgICAgICAgICAgICAgX19mdW5jX18sIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5DaGFubmVsTGlzdFtpXSk7CiAgICB9CiAgICBjc3JOZWlnaGJvclJvYW1GaWxsTm9uQ2hhbm5lbEJnU2NhblBhcmFtcyhwTWFjLCBzZXNzaW9uSWQsICZiZ1NjYW5QYXJhbXMpOwoKICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlQmdTY2FuUmVxdWVzdChwTWFjLCAmYmdTY2FuUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCwgY3NyTmVpZ2hib3JSb2FtQ29udGlndW91c1NjYW5SZXF1ZXN0Q2FsbGJhY2spOwoKICAgIHZvc19tZW1fZnJlZShjaGFubmVsTGlzdCk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiSXNzdWUgb2YgQkcgU2NhbiByZXF1ZXN0IGZhaWxlZDogU3RhdHVzID0gJWQiKSwgc3RhdHVzKTsKICAgIH0KCiAgICByZXR1cm4gc3RhdHVzOwp9CiNlbmRpZgoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbU5laWdoYm9yU2NhblRpbWVyQ2FsbGJhY2sKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgdGhlIG5laWdoYm9yIHNjYW4gdGltZXIgY2FsbGJhY2sgZnVuY3Rpb24uIEl0IGludm9rZXMKICAgICAgICAgICAgdGhlIEJHIHNjYW4gcmVxdWVzdCBiYXNlZCBvbiB0aGUgY3VycmVudCBhbmQgcHJldmlvdXMgc3RhdGVzCgogICAgXHBhcmFtICBwdiAtIENTUiB0aW1lciBjb250ZXh0IGluZm8gd2hpY2ggaW5jbHVkZXMgcE1hYyBhbmQgc2Vzc2lvbiBJRAoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1OZWlnaGJvclNjYW5UaW1lckNhbGxiYWNrKHZvaWQgKnB2KQp7CiAgICB0Q3NyVGltZXJJbmZvICpwSW5mbyA9ICh0Q3NyVGltZXJJbmZvICopcHY7CiAgICB0cEFuaVNpckdsb2JhbCBwTWFjID0gcEluZm8tPnBNYWM7CiAgICB0QU5JX1UzMiAgICBzZXNzaW9uSWQgPSBwSW5mby0+c2Vzc2lvbklkOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm87CgogICAgaWYgKCFwTWFjKQogICAgewogICAgICAgIFZPU19UUkFDRShWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0VSUk9SLCBGTCgicE1hYyBpcyBOdWxsIikpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmICgoQ1NSX1NFU1NJT05fSURfSU5WQUxJRCA9PSBzZXNzaW9uSWQpIHx8CiAgICAgICAgKENTUl9ST0FNX1NFU1NJT05fTUFYIDw9IHNlc3Npb25JZCkpIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwKICAgICAgICAgICAgICAgRkwoIkludmFsaWQgc2Vzc2lvbklkL1JlYWNoZWQgbWF4aW11bSBuby5vZiBzZXNzaW9ucyAlZCIpLAogICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKCiAgICAvLyBjaGVjayBpZiBiZyBzY2FuIGlzIG9uIGdvaW5nLCBubyBuZWVkIHRvIHNlbmQgZG93biB0aGUgbmV3IHBhcmFtcyBpZiB0cnVlCiAgICBpZihlQU5JX0JPT0xFQU5fVFJVRSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJzcFBlbmRpbmcpCiAgICB7CiAgICAgICAvL21zZwogICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJBbHJlYWR5IEJnU2NhblJzcCBpcyBQZW5kaW5nIikpOwogICAgICAgcmV0dXJuOwogICAgfQoKICAgIHN3aXRjaCAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTjoKICAgICAgICAgICAgc3dpdGNoKHBOZWlnaGJvclJvYW1JbmZvLT5wcmV2TmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWToKICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1QZXJmb3JtQmdTY2FuKHBNYWMsIHNlc3Npb25JZCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiTmVpZ2hib3Igc2NhbiBjYWxsYmFjayByZWNlaXZlZCBpbiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgInN0YXRlICVzLCBwcmV2IHN0YXRlID0gJXMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cHJldk5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiNlbmRpZiAvKiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAqLwogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTjoKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUJnU2NhbihwTWFjLCBzZXNzaW9uSWQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybjsKfQoKdm9pZCBjc3JOZWlnaGJvclJvYW1FbXB0eVNjYW5SZWZyZXNoVGltZXJDYWxsYmFjayh2b2lkICpjb250ZXh0KQp7CiAgICB0Q3NyVGltZXJJbmZvICpwSW5mbyA9ICh0Q3NyVGltZXJJbmZvICopY29udGV4dDsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBwSW5mby0+cE1hYzsKICAgIFZPU19TVEFUVVMgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIHRBTklfVTMyICAgICAgIHNlc3Npb25JZCA9IHBJbmZvLT5zZXNzaW9uSWQ7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICBwTmVpZ2hib3JSb2FtSW5mbzsKCiAgICBpZiAoIXBNYWMpCiAgICB7CiAgICAgICAgVk9TX1RSQUNFKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsIEZMKCJwTWFjIGlzIE51bGwiKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKChDU1JfU0VTU0lPTl9JRF9JTlZBTElEID09IHNlc3Npb25JZCkgfHwKICAgICAgICAoQ1NSX1JPQU1fU0VTU0lPTl9NQVggPD0gc2Vzc2lvbklkKSkgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICBGTCgiSW52YWxpZCBzZXNzaW9uSWQvUmVhY2hlZCBtYXhpbXVtIG5vLm9mIHNlc3Npb25zICVkIiksCiAgICAgICAgICAgICAgIHNlc3Npb25JZCk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CgogICAgLyogUmVzZXQgYWxsIHRoZSB2YXJpYWJsZXMganVzdCBhcyBubyBzY2FuIGhhZCBoYXBwZW5lZCBiZWZvcmUgKi8KICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyhwTWFjLCBzZXNzaW9uSWQpOwoKI2lmIGRlZmluZWQgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgJiYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKSAmJiAocE1hYy0+cnJtLnJybVNtZUNvbnRleHQucnJtQ29uZmlnLnJybV9lbmFibGVkKSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCIxMVIgQXNzb2NpYXRpb246TmVpZ2hib3IgTG9va3VwIERvd24gZXZlbnQgcmVjZWl2ZWQgaW4gQ09OTkVDVEVEIHN0YXRlIikpOwogICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHBNYWMsIHNlc3Npb25JZCk7CiAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlcG9ydCByZXF1ZXN0IGZhaWxlZC4gc3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAvKiBJbmNyZW1lbnQgdGhlIG5laWdoYm9yIHJlcG9ydCByZXRyeSBjb3VudCBhZnRlciBzZW5kaW5nIHRoZSBuZWlnaGJvciByZXF1ZXN0IHN1Y2Nlc3NmdWxseSAqLwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtKys7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgY3NyX25laWdoYm9yX3JvYW1fc3RhdGVfdHJhbnNpdGlvbihwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1FVRVJZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgfSBlbHNlCiNlbmRpZgogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIk5vbiAxMVIgb3IgRVNFIEFzc29jaWF0aW9uOmVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciBleHBpcmVkIikpOwogICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMsIHNlc3Npb25JZCk7CiAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUmVzdWx0c1JlZnJlc2hUaW1lckNhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHRoZSB0aW1lciBjYWxsYmFjayBmdW5jdGlvbiBmb3IgcmVzdWx0cwogICAgICAgICAgICByZWZyZXNoIHRpbWVyLiBXaGVuIHRoaXMgaXMgaW52b2tlZCwgaXQgaXMgYXMgZ29vZCBhcyBkb3duIGV2ZW50CiAgICAgICAgICAgIHJlY2VpdmVkIGZyb20gVEwuIFNvLCBjbGVhciBvZmYgdGhlIHJvYW0gYWJsZSBBUCBsaXN0IGFuZCBzdGFydAogICAgICAgICAgICB0aGUgc2NhbiBwcm9jZWR1cmUgYmFzZWQgb24gMTFSIG9yIG5vbi0xMVIgYXNzb2NpYXRpb24KCiAgICBccGFyYW0gIGNvbnRleHQgLSBDU1IgdGltZXIgY29udGV4dCBpbmZvIHdoaWNoIGluY2x1ZGVzIHBNYWMgYW5kIHNlc3Npb24gSUQKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzdWx0c1JlZnJlc2hUaW1lckNhbGxiYWNrKHZvaWQgKmNvbnRleHQpCnsKICAgIHRDc3JUaW1lckluZm8gKnBJbmZvID0gKHRDc3JUaW1lckluZm8gKiljb250ZXh0OwogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IHBJbmZvLT5wTWFjOwogICAgVk9TX1NUQVRVUyAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwogICAgdEFOSV9VMzIgc2Vzc2lvbklkID0gcEluZm8tPnNlc3Npb25JZDsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gIHBOZWlnaGJvclJvYW1JbmZvOwoKICAgIGlmICghcE1hYykKICAgIHsKICAgICAgICBWT1NfVFJBQ0UoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9FUlJPUiwgRkwoInBNYWMgaXMgTnVsbCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoKENTUl9TRVNTSU9OX0lEX0lOVkFMSUQgPT0gc2Vzc2lvbklkKSB8fAogICAgICAgIChDU1JfUk9BTV9TRVNTSU9OX01BWCA8PSBzZXNzaW9uSWQpKSB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgIEZMKCJJbnZhbGlkIHNlc3Npb25JZC9SZWFjaGVkIG1heGltdW0gbm8ub2Ygc2Vzc2lvbnMgJWQiKSwKICAgICAgICAgICAgICAgc2Vzc2lvbklkKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJEZXJlZ2lzdGVyaW5nIERPV04gZXZlbnQgcmVhc3NvYyBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQiKSwgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpKTsKCiAgICAvKiBEZXJlZ2lzdGVyIHJlYXNzb2MgY2FsbGJhY2suIElnbm9yZSByZXR1cm4gc3RhdHVzICovCiAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwoKICAgIGlmICghVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICB7CiAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgZGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgIH0KCiAgICAvKiBSZXNldCBhbGwgdGhlIHZhcmlhYmxlcyBqdXN0IGFzIG5vIHNjYW4gaGFkIGhhcHBlbmVkIGJlZm9yZSAqLwogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMsIHBJbmZvLT5zZXNzaW9uSWQpOwoKI2lmIGRlZmluZWQgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgJiYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKSAmJiAocE1hYy0+cnJtLnJybVNtZUNvbnRleHQucnJtQ29uZmlnLnJybV9lbmFibGVkKSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCIxMVIgQXNzb2NpYXRpb246TmVpZ2hib3IgTG9va3VwIERvd24gZXZlbnQgcmVjZWl2ZWQgaW4gQ09OTkVDVEVEIHN0YXRlIikpOwogICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHBNYWMsIHNlc3Npb25JZCk7CiAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlcG9ydCByZXF1ZXN0IGZhaWxlZC4gc3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAvKiBJbmNyZW1lbnQgdGhlIG5laWdoYm9yIHJlcG9ydCByZXRyeSBjb3VudCBhZnRlciBzZW5kaW5nIHRoZSBuZWlnaGJvciByZXF1ZXN0IHN1Y2Nlc3NmdWxseSAqLwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtKys7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgY3NyX25laWdoYm9yX3JvYW1fc3RhdGVfdHJhbnNpdGlvbihwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1FVRVJZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgfQogICAgZWxzZQojZW5kaWYKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJOb24gMTFSIG9yIEVTRSBBc3NvY2lhdGlvbjpyZXN1bHRzIHJlZnJlc2ggdGltZXIgZXhwaXJlZCIpKTsKICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1UcmFuc2l0VG9DRkdDaGFuU2NhbihwTWFjLCBzZXNzaW9uSWQpOwogICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybjsKfQoKI2lmIGRlZmluZWQgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgJiYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jc3N1ZU5laWdoYm9yUnB0UmVxdWVzdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBpbnZva2VkIHdoZW4gVEwgaXNzdWVzIGEgZG93biBldmVudCBhbmQgdGhlIGN1cnJlbnQgYXNzb2MKICAgICAgICAgICAgaXMgYSAxMVIgYXNzb2NpYXRpb24uIEl0IGludm9rZXMgU01FIFJSTSBBUEkgdG8gaXNzdWUgdGhlIG5laWdoYm9yIHJlcXVlc3QgdG8KICAgICAgICAgICAgdGhlIGN1cnJlbnRseSBhc3NvY2lhdGVkIEFQIHdpdGggdGhlIGN1cnJlbnQgU1NJRAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQpCnsKICAgIHRScm1OZWlnaGJvclJzcENhbGxiYWNrSW5mbyBjYWxsYmFja0luZm87CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgdFJybU5laWdoYm9yUmVxIG5laWdoYm9yUmVxOwogICAgdHBGVFJvYW1DYWxsYmFja1VzckN0eCAgICAgcFVzckN0eDsKCiAgICAvKiBUaGlzIHVzZXIgY29udGV4dCBkYXRhIHdpbGwgYmUgcmV0dXJuZWQgd2l0aCBjYWxsYmFjayAqLwogICAgcFVzckN0eCA9IHZvc19tZW1fbWFsbG9jKHNpemVvZigqcFVzckN0eCkpOwogICAgaWYgKE5VTEwgPT0gcFVzckN0eCkgewogICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlIikpOwogICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9OT01FTTsKICAgIH0KICAgIHBVc3JDdHgtPnBNYWMgPSBwTWFjOwogICAgcFVzckN0eC0+c2Vzc2lvbklkID0gc2Vzc2lvbklkOwoKICAgIG5laWdoYm9yUmVxLm5vX3NzaWQgPSAwOwoKICAgIC8qIEZpbGwgaW4gdGhlIFNTSUQgKi8KICAgIG5laWdoYm9yUmVxLnNzaWQubGVuZ3RoID0KICAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5TU0lELmxlbmd0aDsKICAgIHZvc19tZW1fY29weShuZWlnaGJvclJlcS5zc2lkLnNzSWQsCiAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5TU0lELnNzSWQsCiAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5TU0lELmxlbmd0aCk7CgogICAgY2FsbGJhY2tJbmZvLm5laWdoYm9yUnNwQ2FsbGJhY2sgPSBjc3JOZWlnaGJvclJvYW1SUk1OZWlnaGJvclJlcG9ydFJlc3VsdDsKICAgIGNhbGxiYWNrSW5mby5uZWlnaGJvclJzcENhbGxiYWNrQ29udGV4dCA9IHBVc3JDdHg7CiAgICBjYWxsYmFja0luZm8udGltZW91dCA9IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUmVwb3J0VGltZW91dDsKCiAgICByZXR1cm4gc21lX05laWdoYm9yUmVwb3J0UmVxdWVzdChwTWFjLCBzZXNzaW9uSWQsICZuZWlnaGJvclJlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjYWxsYmFja0luZm8pOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUN1cnJlbnRCYW5kCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZmlsdGVyIG91dCB0aGUgY2hhbm5lbHMKICAgICAgICAgICAgYmFzZWQgb24gdGhlIGN1cnJlbnRseSBhc3NvY2lhdGVkIEFQIGNoYW5uZWwKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGlucHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBpbnB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIGlucHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBwT3V0cHV0Q2hhbm5lbExpc3QgLSBUaGUgb3V0cHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBvdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIG51bWJlciBvZiBjaGFubmVscyBpbiBvdXRwdXQgY2hhbm5lbCBsaXN0CiAgICBccGFyYW0gIHBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIGZpbmFsIG51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgb3V0cHV0IGNoYW5uZWwgbGlzdC4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1DaGFubmVsc0ZpbHRlckJ5Q3VycmVudEJhbmQoCiAgICAgICAgICAgICAgICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCAgIHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTgqICBwSW5wdXRDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggICBpbnB1dE51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4KiAgcE91dHB1dENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCogIHBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzCiAgICAgICAgICAgICAgICAgICAgICApCnsKICAgIHRBTklfVTggaSA9IDA7CiAgICB0QU5JX1U4IG51bUNoYW5uZWxzID0gMDsKICAgIHRBTklfVTggICBjdXJyQVBvcGVyYXRpb25DaGFubmVsID0KICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF0uY3VyckFQb3BlcmF0aW9uQ2hhbm5lbDsKICAgIC8vIENoZWNrIGZvciBOVUxMIHBvaW50ZXIKICAgIGlmICghcElucHV0Q2hhbm5lbExpc3QpIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CgogICAgLy8gQ2hlY2sgZm9yIE5VTEwgcG9pbnRlcgogICAgaWYgKCFwT3V0cHV0Q2hhbm5lbExpc3QpIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CgogICAgaWYgKGlucHV0TnVtT2ZDaGFubmVscyA+IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgIHsKICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgIiVzOiBXcm9uZyBOdW1iZXIgb2YgSW5wdXQgQ2hhbm5lbHMgJWQiLAogICAgICAgICAgICAgX19mdW5jX18sIGlucHV0TnVtT2ZDaGFubmVscyk7CiAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgaW5wdXROdW1PZkNoYW5uZWxzOyBpKyspCiAgICB7CiAgICAgICAgaWYgKEdldFJGQmFuZChjdXJyQVBvcGVyYXRpb25DaGFubmVsKSA9PSBHZXRSRkJhbmQocElucHV0Q2hhbm5lbExpc3RbaV0pKQogICAgICAgIHsKICAgICAgICAgICAgcE91dHB1dENoYW5uZWxMaXN0W251bUNoYW5uZWxzXSA9IHBJbnB1dENoYW5uZWxMaXN0W2ldOwogICAgICAgICAgICBudW1DaGFubmVscysrOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBSZXR1cm4gZmluYWwgbnVtYmVyIG9mIGNoYW5uZWxzCiAgICAqcE1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMgPSBudW1DaGFubmVsczsKCiAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtTWVyZ2VDaGFubmVsTGlzdHMKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBtZXJnZSB0d28gY2hhbm5lbCBsaXN0LgogICAgICAgICAgICBOQjogSWYgY2FsbGVkIHdpdGggb3V0cHV0TnVtT2ZDaGFubmVscyA9PSAwLCB0aGlzIHJvdXRpbmVzCiAgICAgICAgICAgICAgICBzaW1wbHkgY29waWVzIHRoZSBpbnB1dCBjaGFubmVsIGxpc3QgdG8gdGhlIG91dHB1dCBjaGFubmVsIGxpc3QuCiAgICAgICAgICAgICAgICBpZiBudW1iZXIgb2YgbWVyZ2VkIGNoYW5uZWxzIGFyZSBtb3JlIHRoYW4gMTAwLCBudW0gb2YgY2hhbm5lbHMKICAgICAgICAgICAgICAgIHNldCB0byAxMDAKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGFkZGl0aW9uYWwgY2hhbm5lbHMgdG8gbWVyZ2UgaW4gdG8gdGhlICJtZXJnZWQiIGNoYW5uZWxzIGxpc3QuCiAgICBccGFyYW0gIGlucHV0TnVtT2ZDaGFubmVscyAtIFRoZSBudW1iZXIgb2YgYWRkaXRpb25hbCBjaGFubmVscy4KICAgIFxwYXJhbSAgcE91dHB1dENoYW5uZWxMaXN0IC0gVGhlIHBsYWNlIHRvIHB1dCB0aGUgIm1lcmdlZCIgY2hhbm5lbCBsaXN0LgogICAgXHBhcmFtICBvdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIG9yaWdpbmFsIG51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgIm1lcmdlZCIgY2hhbm5lbHMgbGlzdC4KICAgIFxwYXJhbSAgcE1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgZmluYWwgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSAibWVyZ2VkIiBjaGFubmVsIGxpc3QuCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1NZXJnZUNoYW5uZWxMaXN0cygKICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgIHRBTklfVTggKnBJbnB1dENoYW5uZWxMaXN0LAogICAgICAgIHRBTklfVTggaW5wdXROdW1PZkNoYW5uZWxzLAogICAgICAgIHRBTklfVTggKnBPdXRwdXRDaGFubmVsTGlzdCwKICAgICAgICB0QU5JX1U4IG91dHB1dE51bU9mQ2hhbm5lbHMsCiAgICAgICAgdEFOSV9VOCAqcE1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMKICAgICAgICApCnsKICAgIHRBTklfVTggaSA9IDA7CiAgICB0QU5JX1U4IGogPSAwOwogICAgdEFOSV9VOCBudW1DaGFubmVscyA9IG91dHB1dE51bU9mQ2hhbm5lbHM7CgogICAgLy8gQ2hlY2sgZm9yIE5VTEwgcG9pbnRlcgogICAgaWYgKCFwSW5wdXRDaGFubmVsTGlzdCkgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKCiAgICAvLyBDaGVjayBmb3IgTlVMTCBwb2ludGVyCiAgICBpZiAoIXBPdXRwdXRDaGFubmVsTGlzdCkgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKCiAgICBpZiAoaW5wdXROdW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgewogICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAiJXM6IFdyb25nIE51bWJlciBvZiBJbnB1dCBDaGFubmVscyAlZCIsCiAgICAgICAgICAgICBfX2Z1bmNfXywgaW5wdXROdW1PZkNoYW5uZWxzKTsKICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKICAgIH0KICAgIGlmIChvdXRwdXROdW1PZkNoYW5uZWxzID49IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgIHsKICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgIiVzOiBXcm9uZyBOdW1iZXIgb2YgT3V0cHV0IENoYW5uZWxzICVkIiwKICAgICAgICAgICAgIF9fZnVuY19fLCBvdXRwdXROdW1PZkNoYW5uZWxzKTsKICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKICAgIH0KICAgIC8vIEFkZCB0aGUgIm5ldyIgY2hhbm5lbHMgaW4gdGhlIGlucHV0IGxpc3QgdG8gdGhlIGVuZCBvZiB0aGUgb3V0cHV0IGxpc3QuCiAgICBmb3IgKGkgPSAwOyBpIDwgaW5wdXROdW1PZkNoYW5uZWxzOyBpKyspCiAgICB7CiAgICAgICAgZm9yIChqID0gMDsgaiA8IG91dHB1dE51bU9mQ2hhbm5lbHM7IGorKykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwSW5wdXRDaGFubmVsTGlzdFtpXSA9PSBwT3V0cHV0Q2hhbm5lbExpc3Rbal0pCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKGogPT0gb3V0cHV0TnVtT2ZDaGFubmVscykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwSW5wdXRDaGFubmVsTGlzdFtpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICIlczogW0lORk9MT0ddIEFkZGluZyBleHRyYSAlZCB0byBOZWlnaGJvciBjaGFubmVsIGxpc3QiLCBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgICAgcElucHV0Q2hhbm5lbExpc3RbaV0pOwogICAgICAgICAgICAgICAgcE91dHB1dENoYW5uZWxMaXN0W251bUNoYW5uZWxzXSA9IHBJbnB1dENoYW5uZWxMaXN0W2ldOwogICAgICAgICAgICAgICAgbnVtQ2hhbm5lbHMrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAobnVtQ2hhbm5lbHMgPj0gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgICAgIHsKICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgIiVzOiBNZXJnZSBOZWlnaGJvciBjaGFubmVsIGxpc3QgcmVhY2hlZCBNYXggIgogICAgICAgICAgICAgICAgICAgICJsaW1pdCAlZCIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgIG51bUNoYW5uZWxzKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIC8vIFJldHVybiBmaW5hbCBudW1iZXIgb2YgY2hhbm5lbHMKICAgICpwTWVyZ2VkT3V0cHV0TnVtT2ZDaGFubmVscyA9IG51bUNoYW5uZWxzOwoKICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1DcmVhdGVDaGFuTGlzdEZyb21OZWlnaGJvclJlcG9ydAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBpbnZva2VkIHdoZW4gbmVpZ2hib3IgcmVwb3J0IGlzIHJlY2VpdmVkIGZvciB0aGUKICAgICAgICAgICAgbmVpZ2hib3IgcmVxdWVzdC4gQmFzZWQgb24gdGhlIGNoYW5uZWxzIHByZXNlbnQgaW4gdGhlIG5laWdoYm9yIHJlcG9ydCwKICAgICAgICAgICAgaXQgZ2VuZXJhdGVzIGNoYW5uZWwgbGlzdCB3aGljaCB3aWxsIGJlIHVzZWQgaW4gUkVQT1JUX1NDQU4gc3RhdGUgdG8KICAgICAgICAgICAgc2NhbiBmb3IgdGhlc2UgbmVpZ2hib3IgQVBzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtQ3JlYXRlQ2hhbkxpc3RGcm9tTmVpZ2hib3JSZXBvcnQodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgdHBScm1OZWlnaGJvclJlcG9ydERlc2MgICAgICAgcE5laWdoYm9yQnNzRGVzYzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CiAgICB0QU5JX1U4ICAgICAgICAgICAgICAgICAgICAgICBudW1DaGFubmVscyA9IDA7CiAgICB0QU5JX1U4ICAgICAgICAgICAgICAgICAgICAgICBpID0gMDsKICAgIHRBTklfVTggICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0W01BWF9CU1NfSU5fTkVJR0hCT1JfUlBUXTsKICAgIHRBTklfVTggICAgICAgICAgICAgICAgICAgICAgIG1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMgPSAwOwoKICAgIC8qIFRoaXMgc2hvdWxkIGFsd2F5cyBzdGFydCBmcm9tIDAgd2hlbmV2ZXIgd2UgY3JlYXRlIGEgY2hhbm5lbCBsaXN0IG91dCBvZiBuZWlnaGJvciBBUCBsaXN0ICovCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPSAwOwoKICAgIHBOZWlnaGJvckJzc0Rlc2MgPSBzbWVScm1HZXRGaXJzdEJzc0VudHJ5RnJvbU5laWdoYm9yQ2FjaGUocE1hYyk7CgogICAgd2hpbGUgKHBOZWlnaGJvckJzc0Rlc2MpCiAgICB7CiAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydCA+PSBNQVhfQlNTX0lOX05FSUdIQk9SX1JQVCkgYnJlYWs7CgogICAgICAgIC8qIFVwZGF0ZSB0aGUgbmVpZ2hib3IgQlNTIEluZm8gaW4gdGhlIDExciBGVCBSb2FtIEluZm8gKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mb1twTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnRdLmNoYW5uZWxOdW0gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JCc3NEZXNjLT5wTmVpZ2hib3JCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mb1twTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnRdLm5laWdoYm9yU2NvcmUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VOClwTmVpZ2hib3JCc3NEZXNjLT5yb2FtU2NvcmU7CiAgICAgICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvW3BOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydF0ubmVpZ2hib3JCc3NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0Kys7CgogICAgICAgIC8qIFNhdmluZyB0aGUgY2hhbm5lbCBsaXN0IG5vbi1yZWR1bmRhbnRseSAqLwogICAgICAgIGZvciAoaSA9IDA7IChpIDwgbnVtQ2hhbm5lbHMgJiYgaSA8IE1BWF9CU1NfSU5fTkVJR0hCT1JfUlBUKTsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsID09IGNoYW5uZWxMaXN0W2ldKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAoKGkgPT0gbnVtQ2hhbm5lbHMpICYmIChudW1DaGFubmVscyA8IE1BWF9CU1NfSU5fTkVJR0hCT1JfUlBUKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwTmVpZ2hib3JCc3NEZXNjLT5wTmVpZ2hib3JCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKENTUl9JU19ST0FNX0lOVFJBX0JBTkRfRU5BQkxFRChwTWFjKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdG8gYWRkIG9ubHkgaWYgaXRzIHRoZSBzYW1lIGJhbmQKICAgICAgICAgICAgICAgICAgICBpZiAoR2V0UkZCYW5kKHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBvcGVyYXRpb25DaGFubmVsKSA9PQogICAgICAgICAgICAgICAgICAgICAgICBHZXRSRkJhbmQocE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWwpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR10gQWRkaW5nICVkIHRvIE5laWdoYm9yIGNoYW5uZWwgbGlzdCAoU2FtZSBiYW5kKVxuIiwgX19mdW5jX18sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3RbbnVtQ2hhbm5lbHNdID0gcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWw7CiAgICAgICAgICAgICAgICAgICAgICAgIG51bUNoYW5uZWxzKys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogW0lORk9MT0ddIEFkZGluZyAlZCB0byBOZWlnaGJvciBjaGFubmVsIGxpc3RcbiIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsKTsKICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFtudW1DaGFubmVsc10gPSBwTmVpZ2hib3JCc3NEZXNjLT5wTmVpZ2hib3JCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbDsKICAgICAgICAgICAgICAgICAgICBudW1DaGFubmVscysrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwTmVpZ2hib3JCc3NEZXNjID0gc21lUnJtR2V0TmV4dEJzc0VudHJ5RnJvbU5laWdoYm9yQ2FjaGUocE1hYywgcE5laWdoYm9yQnNzRGVzYyk7CiAgICB9CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCkKICAgIHsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgIH0KCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgLyogU3RvcmUgdGhlIG9idGFpbmVkIGNoYW5uZWwgbGlzdCB0byB0aGUgTmVpZ2hib3IgQ29udHJvbCBkYXRhIHN0cnVjdHVyZSAqLwogICAgaWYgKG51bUNoYW5uZWxzKQogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IHZvc19tZW1fbWFsbG9jKChudW1DaGFubmVscykgKiBzaXplb2YodEFOSV9VOCkpOwogICAgaWYgKE5VTEwgPT0gcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZm9yIENoYW5uZWwgbGlzdCBmYWlsZWQuLiBUTCBldmVudCBpZ25vcmVkIikpOwogICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfUkVTT1VSQ0VTOwogICAgfQoKICAgIHZvc19tZW1fY29weShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsIChudW1DaGFubmVscykgKiBzaXplb2YodEFOSV9VOCkpOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSBudW1DaGFubmVsczsKICAgIC8qCiAgICAgKiBDcmVhdGUgYSBVbmlvbiBvZiBvY2N1cGllZCBjaGFubmVsIGxpc3QgbGVhcm50IGJ5IHRoZSBEVVQgYWxvbmcgd2l0aCB0aGUgTmVpZ2hib3IKICAgICAqIHJlcG9ydCBDaGFubmVscy4gVGhpcyBpbmNyZWFzZXMgdGhlIGNoYW5jZXMgb2YgdGhlIERVVCB0byBnZXQgYSBjYW5kaWRhdGUgQVAgd2hpbGUKICAgICAqIHJvYW1pbmcgZXZlbiBpZiB0aGUgTmVpZ2hib3IgUmVwb3J0IGlzIG5vdCBhYmxlIHRvIHByb3ZpZGUgc3VmZmljaWVudCBpbmZvcm1hdGlvbi4KICAgICAqICovCiAgICBpZiAocE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzW3Nlc3Npb25JZF0ubnVtQ2hhbm5lbHMpIHsKICAgICAgIGNzck5laWdoYm9yUm9hbU1lcmdlQ2hhbm5lbExpc3RzKHBNYWMsCiAgICAgICAgICAgICAgICAgICZwTWFjLT5zY2FuLm9jY3VwaWVkQ2hhbm5lbHNbc2Vzc2lvbklkXS5jaGFubmVsTGlzdFswXSwKICAgICAgICAgICAgICAgICAgcE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzW3Nlc3Npb25JZF0ubnVtQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbMF0sCiAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAmbWVyZ2VkT3V0cHV0TnVtT2ZDaGFubmVscyk7CiAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9CiAgICAgICAgICAgICAgICAgIG1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHM7CgogICAgfQogICAgLypJbmRpY2F0ZSB0aGUgZmlybXdhcmUgYWJvdXQgdGhlIHVwZGF0ZSBvbmx5IGlmIGFueSBuZXcgY2hhbm5lbHMgYXJlIGFkZGVkLgogICAgICogT3RoZXJ3aXNlLCB0aGUgZmlybXdhcmUgd291bGQgYWxyZWFkeSBiZSBrbm93aW5nIHRoZSBub24tSUFQUG5laWdoYm9ybGlzdAogICAgICogY2hhbm5lbHMuIFRoZXJlIGlzIG5vIG5lZWQgdG8gdXBkYXRlLiovCiAgICBpZiAobnVtQ2hhbm5lbHMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsCiAgICAgICAgICAgICAgIEZMKCJJQVBQIE5laWdoYm9yIGxpc3QgY2FsbGJhY2sgcmVjZWl2ZWQgYXMgZXhwZWN0ZWQiCiAgICAgICAgICAgICAgICJpbiBzdGF0ZSAlcy4iKSwKICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9UUlVFOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgewogICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBzZXNzaW9uSWQsIFJPQU1fU0NBTl9PRkZMT0FEX1VQREFURV9DRkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9DSEFOTkVMX0xJU1RfQ0hBTkdFRCk7CiAgICAgICAgfQojZW5kaWYKICAgIH0KICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fVFJVRTsKCiAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUlJNTmVpZ2hib3JSZXBvcnRSZXN1bHQKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgdGhlIG5laWdoYm9yIHJlcG9ydCBjYWxsYmFjayB0aGF0IHdpbGwgYmUgaW52b2tlZCBieQogICAgICAgICAgICBTTUUgUlJNIG9uIHJlY2VpdmluZyBhIG5laWdoYm9yIHJlcG9ydCBvciBvZiBuZWlnaGJvciByZXBvcnQgaXMgbm90CiAgICAgICAgICAgIHJlY2VpdmVkIGFmdGVyIHRpbWVvdXQuIE9uIHJlY2VpdmluZyBhIHZhbGlkIHJlcG9ydCwgaXQgZ2VuZXJhdGVzIGEKICAgICAgICAgICAgY2hhbm5lbCBsaXN0IGZyb20gdGhlIG5laWdoYm9yIHJlcG9ydCBhbmQgc3RhcnRzIHRoZQogICAgICAgICAgICBuZWlnaGJvciBzY2FuIHRpbWVyCgogICAgXHBhcmFtICBjb250ZXh0IC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICB2b3NTdGF0dXMgLSBTdGF0dXMgb2YgdGhlIGNhbGxiYWNrKFNVQ0NFU1MvRkFJTFVSRSkKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUlJNTmVpZ2hib3JSZXBvcnRSZXN1bHQodm9pZCAqY29udGV4dCwgVk9TX1NUQVRVUyB2b3NTdGF0dXMpCnsKICAgIHRGVFJvYW1DYWxsYmFja1VzckN0eCAqcFVzckN0eCA9ICh0RlRSb2FtQ2FsbGJhY2tVc3JDdHggKiljb250ZXh0OwogICAgdEFOSV9VMzIgICAgc2Vzc2lvbklkID0gcFVzckN0eC0+c2Vzc2lvbklkOwogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IHBVc3JDdHgtPnBNYWM7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIGVIYWxTdGF0dXMgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CgogICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJOZWlnaGJvciByZXBvcnQgcmVzdWx0IGNhbGxiYWNrIHdpdGggc3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgIHN3aXRjaCAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWToKICAgICAgICAgICAgLyogUmVzZXQgdGhlIHJlcG9ydCBwZW5kaW5nIHZhcmlhYmxlICovCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyA9PSB2b3NTdGF0dXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIE5lZWQgdG8gY3JlYXRlIGNoYW5uZWwgbGlzdCBiYXNlZCBvbiB0aGUgbmVpZ2hib3IgQVAgbGlzdCBhbmQgdHJhbnNpdGlvbiB0byBSRVBPUlRfU0NBTiBzdGF0ZSAqLwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtQ3JlYXRlQ2hhbkxpc3RGcm9tTmVpZ2hib3JSZXBvcnQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyA9PSB2b3NTdGF0dXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiQ2hhbm5lbCBMaXN0IGNyZWF0ZWQgZnJvbSBOZWlnaGJvciByZXBvcnQsIFRyYW5zaXRpb25pbmcgdG8gTkVJR0hCT1JfU0NBTiBzdGF0ZSIpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKiBXZSBhcmUgZ29ubmEgc2NhbiBub3cuIFJlbWVtYmVyIHRoZSB0aW1lIHN0YW1wIHRvIGZpbHRlciBvdXQKICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgb25seSBhZnRlciB0aGlzIHRpbWUgc3RhbXAgKi8KICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUmVxdWVzdFRpbWVTdGFtcCA9IHZvc190aW1lcl9nZXRfc3lzdGVtX3RpbWUoKTsKCiAgICAgICAgICAgICAgICAvKiBOb3cgcmVhZHkgZm9yIG5laWdoYm9yIHNjYW4gYmFzZWQgb24gdGhlIGNoYW5uZWwgbGlzdCBjcmVhdGVkICovCiAgICAgICAgICAgICAgICBzdGF0dXMgPSB2b3NfdGltZXJfc3RhcnQoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yU2NhblBlcmlvZCk7CiAgICAgICAgICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogVGltZXIgc3RhcnQgZmFpbGVkLi4gU2hvdWxkIHdlIEFTU0VSVCBoZXJlPz8/ICovCiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJQQUwgVGltZXIgc3RhcnQgZm9yIG5laWdoYm9yIHNjYW4gdGltZXIgZmFpbGVkLCBzdGF0dXMgPSAlZCwgSWdub3Jpbmcgc3RhdGUgdHJhbnNpdGlvbiIpLCBzdGF0dXMpOwogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwVXNyQ3R4KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICAgICAgICAgICAgICAvKiBOZWlnaGJvciBzY2FuIHRpbWVyIHN0YXJ0ZWQuIFRyYW5zaXRpb24gdG8gUkVQT1JUX1NDQU4gc3RhdGUgKi8KICAgICAgICAgICAgICAgIGNzcl9uZWlnaGJvcl9yb2FtX3N0YXRlX3RyYW5zaXRpb24ocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogTmVpZ2hib3IgcmVwb3J0IHRpbWVvdXQgaGFwcGVuZWQgaW4gU01FIFJSTS4gV2UgY2FuIHRyeSBzZW5kaW5nIG1vcmUgbmVpZ2hib3IgcmVxdWVzdHMgdW50aWwgd2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFjaCB0aGUgbWF4TmVpZ2hib3JSZXRyaWVzIG9yIHJlY2VpdmluZyBhIHN1Y2Nlc3NmdWwgbmVpZ2hib3IgcmVzcG9uc2UgKi8KICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVwb3J0IHJlc3VsdCBmYWlsZWQgYWZ0ZXIgJWQgcmV0cmllcywgTUFYIFJFVFJJRVMgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSwgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5tYXhOZWlnaGJvclJldHJpZXMpOwogICAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtID49CiAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWF4TmVpZ2hib3JSZXRyaWVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQmFpbGluZyBvdXQgdG8gQ0ZHIENoYW5uZWwgbGlzdCBzY2FuLi4gIikpOwogICAgICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkKTsKICAgICAgICAgICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiVHJhbnNpdCB0byBDRkcgQ2hhbm5lbCBsaXN0IHNjYW4gc3RhdGUgZmFpbGVkIHdpdGggc3RhdHVzICVkICIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocFVzckN0eCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLyogV2UgdHJhbnNpdGlvbmVkIHRvIGRpZmZlcmVudCBzdGF0ZSBub3cuIFJlc2V0IHRoZSBOZWlnaGJvciByZXBvcnQgcmV0cnkgY291bnQgKi8KICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVOZWlnaGJvclJwdFJlcXVlc3QocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgICAgICAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXBvcnQgcmVxdWVzdCBmYWlsZWQuIHN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwVXNyQ3R4KTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICAgICAgICAgICAgICAvKiBJbmNyZW1lbnQgdGhlIG5laWdoYm9yIHJlcG9ydCByZXRyeSBjb3VudCBhZnRlciBzZW5kaW5nIHRoZSBuZWlnaGJvciByZXF1ZXN0IHN1Y2Nlc3NmdWxseSAqLwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgICAgICBGTCgiTmVpZ2hib3IgcmVzdWx0IGNhbGxiYWNrIG5vdCBleHBlY3RlZCBpbiIKICAgICAgICAgICAgICAgICAgICJzdGF0ZSAlcywgSWdub3JpbmcuLiIpLAogICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICB2b3NfbWVtX2ZyZWUocFVzckN0eCk7CiAgICByZXR1cm47Cn0KI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUlzU3NpZEFuZFNlY3VyaXR5TWF0Y2goCiAgICAgICAgdHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICB0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUgKnBDdXJQcm9maWxlLAogICAgICAgIHRTaXJCc3NEZXNjcmlwdGlvbiAqcEJzc0Rlc2MsCiAgICAgICAgdERvdDExZkJlYWNvbklFcyAqcEllcykKewogICAgdENzckF1dGhMaXN0IGF1dGhUeXBlOwogICAgdENzckVuY3J5cHRpb25MaXN0IHVDRW5jcnlwdGlvblR5cGU7CiAgICB0Q3NyRW5jcnlwdGlvbkxpc3QgbUNFbmNyeXB0aW9uVHlwZTsKICAgIHRBTklfQk9PTEVBTiBmTWF0Y2ggPSBGQUxTRTsKCiAgICBhdXRoVHlwZS5udW1FbnRyaWVzID0gMTsKICAgIGF1dGhUeXBlLmF1dGhUeXBlWzBdID0gcEN1clByb2ZpbGUtPkF1dGhUeXBlOwogICAgdUNFbmNyeXB0aW9uVHlwZS5udW1FbnRyaWVzID0gMTsKICAgIHVDRW5jcnlwdGlvblR5cGUuZW5jcnlwdGlvblR5cGVbMF0gPSBwQ3VyUHJvZmlsZS0+RW5jcnlwdGlvblR5cGU7CiAgICBtQ0VuY3J5cHRpb25UeXBlLm51bUVudHJpZXMgPSAxOwogICAgbUNFbmNyeXB0aW9uVHlwZS5lbmNyeXB0aW9uVHlwZVswXSA9IHBDdXJQcm9maWxlLT5tY0VuY3J5cHRpb25UeXBlOwoKICAgIGlmKCBwSWVzICkKICAgIHsKICAgICAgICBpZihwSWVzLT5TU0lELnByZXNlbnQpCiAgICAgICAgewogICAgICAgICAgICBmTWF0Y2ggPSBjc3JJc1NzaWRNYXRjaCggcE1hYywKICAgICAgICAgICAgICAgICAgICAodm9pZCAqKXBDdXJQcm9maWxlLT5TU0lELnNzSWQsIHBDdXJQcm9maWxlLT5TU0lELmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICBwSWVzLT5TU0lELnNzaWQsIHBJZXMtPlNTSUQubnVtX3NzaWQsCiAgICAgICAgICAgICAgICAgICAgZUFOSV9CT09MRUFOX1RSVUUgKTsKICAgICAgICAgICAgaWYoVFJVRSA9PSBmTWF0Y2gpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBmb3Igbm93IHdlIGFyZSBzZW5kaW5nIE5VTEwgZm9yIGFsbCBQTUYgcmVsYXRlZCBmaWx0ZXIKICAgICAgICAgICAgICAgICAqIHBhcmFtZXRlcnMgZHVyaW5nIHJvYW0gdG8gdGhlIG5laWdoYm9yIEFQIGJlY2F1c2UKICAgICAgICAgICAgICAgICAqIHNvIGZhciA4MDIxMVcgc3BlYyBkb2Vzbid0IHNwZWNpZnkgYW55dGhpbmcgYWJvdXQKICAgICAgICAgICAgICAgICAqIHJvYW1pbmcgc2NlbmFyaW8uCiAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICogT25jZSByb2FtaW5nIHNjZW5hcmlvIGlzIGRlZmluZWQsIHdlIHNob3VsZCByZS12aXNpdAogICAgICAgICAgICAgICAgICogdGhpcyBzZWN0aW9uIGFuZCByZW1vdmUgdGhpcyBjb21tZW50LgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBmTWF0Y2ggPSBjc3JJc1NlY3VyaXR5TWF0Y2gocE1hYywgJmF1dGhUeXBlLCAmdUNFbmNyeXB0aW9uVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbUNFbmNyeXB0aW9uVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBCc3NEZXNjLCBwSWVzLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgICAgIHJldHVybiAoZk1hdGNoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAoZk1hdGNoKTsKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOyAgLy8gVHJlYXQgYSBtaXNzaW5nIFNTSUQgYXMgYSBub24tbWF0Y2guCiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsgIC8vIEFnYWluLCB0cmVhdCBtaXNzaW5nIHBJZXMgYXMgYSBub24tbWF0Y2guCiAgICB9Cn0KCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1Jc05ld0Nvbm5lY3RlZFByb2ZpbGUodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIHRDc3JSb2FtQ29ubmVjdGVkUHJvZmlsZSAqcEN1cnJQcm9maWxlID0gTlVMTDsKICAgIHRDc3JSb2FtQ29ubmVjdGVkUHJvZmlsZSAqcFByZXZQcm9maWxlID0gTlVMTDsKICAgIHREb3QxMWZCZWFjb25JRXMgKnBJZXMgPSBOVUxMOwogICAgdFNpckJzc0Rlc2NyaXB0aW9uICpwQnNzRGVzYyA9IE5VTEw7CiAgICB0QU5JX0JPT0xFQU4gZk5ldyA9IFRSVUU7CgogICAgaWYoIShwTWFjLT5yb2FtLnJvYW1TZXNzaW9uICYmIENTUl9JU19TRVNTSU9OX1ZBTElEKHBNYWMsIHNlc3Npb25JZCkpKQogICAgewogICAgICAgIHJldHVybiAoZk5ldyk7CiAgICB9CgogICAgcEN1cnJQcm9maWxlID0gJnBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlOwogICAgaWYoICFwQ3VyclByb2ZpbGUgKQogICAgewogICAgICAgIHJldHVybiAoZk5ldyk7Cn0KCiAgICBwUHJldlByb2ZpbGUgPSAmcE5laWdoYm9yUm9hbUluZm8tPnByZXZDb25uUHJvZmlsZTsKICAgIGlmKCAhcFByZXZQcm9maWxlICkKICAgIHsKICAgICAgICByZXR1cm4gKGZOZXcpOwogICAgfQoKICAgIHBCc3NEZXNjID0gcFByZXZQcm9maWxlLT5wQnNzRGVzYzsKICAgIGlmIChwQnNzRGVzYykKICAgIHsKICAgICAgICBpZiAoSEFMX1NUQVRVU19TVUNDRVNTKGNzckdldFBhcnNlZEJzc0Rlc2NyaXB0aW9uSUVzKHBNYWMsCiAgICAgICAgICAgIHBCc3NEZXNjLCAmcEllcykpICYmCiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUlzU3NpZEFuZFNlY3VyaXR5TWF0Y2gocE1hYywgcEN1cnJQcm9maWxlLCBwQnNzRGVzYywgcEllcykpCiAgICAgICAgewogICAgICAgICAgICBmTmV3ID0gRkFMU0U7CiAgICAgICAgfQogICAgICAgIGlmIChwSWVzKQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBJZXMpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoZk5ldykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIlByZXYgcm9hbSBwcm9maWxlIGRpZCBub3QgbWF0Y2ggY3VycmVudCIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIlByZXYgcm9hbSBwcm9maWxlIG1hdGNoZXMgY3VycmVudCIpKTsKICAgIH0KCiAgICByZXR1cm4gKGZOZXcpOwp9Cgp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JSb2FtQ29ubmVjdGVkUHJvZmlsZU1hdGNoKAogICAgICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQsCiAgICAgICAgdENzclNjYW5SZXN1bHQgKnBSZXN1bHQsCiAgICAgICAgdERvdDExZkJlYWNvbklFcyAqcEllcykKewogICAgdENzclJvYW1Db25uZWN0ZWRQcm9maWxlICpwQ3VyUHJvZmlsZSA9IE5VTEw7CiAgICB0U2lyQnNzRGVzY3JpcHRpb24gKnBCc3NEZXNjID0gJnBSZXN1bHQtPlJlc3VsdC5Cc3NEZXNjcmlwdG9yOwoKICAgIGlmKCAhKHBNYWMtPnJvYW0ucm9hbVNlc3Npb24KICAgICAgICAgICAgJiYgQ1NSX0lTX1NFU1NJT05fVkFMSUQocE1hYywgc2Vzc2lvbklkKSkpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHBDdXJQcm9maWxlID0gJnBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlOwoKICAgIGlmKCAhcEN1clByb2ZpbGUpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBjc3JOZWlnaGJvclJvYW1Jc1NzaWRBbmRTZWN1cml0eU1hdGNoKHBNYWMsIHBDdXJQcm9maWxlLCBwQnNzRGVzYywgcEllcyk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1QcmVwYXJlTm9uT2NjdXBpZWRDaGFubmVsTGlzdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIHByZXBhcmUgYSBjaGFubmVsIGxpc3QgdGhhdCBpcyBkZXJpdmVkIGZyb20KICAgICAgICAgICAgdGhlIGxpc3Qgb2YgdmFsaWQgY2hhbm5lbHMgYW5kIGRvZXMgbm90IGluY2x1ZGUgdGhvc2UgaW4gdGhlIG9jY3VwaWVkCiAgICAgICAgICAgIGxpc3QuCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgXHBhcmFtICBwSW5wdXRDaGFubmVsTGlzdCAtIFRoZSBkZWZhdWx0IGNoYW5uZWxzIGxpc3QuCiAgICBccGFyYW0gIG51bU9mQ2hhbm5lbHMgLSBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSBkZWZhdWx0IGNoYW5uZWxzIGxpc3QuCiAgICBccGFyYW0gIHBPdXRwdXRDaGFubmVsTGlzdCAtIFRoZSBwbGFjZSB0byBwdXQgdGhlIG5vbi1vY2N1cGllZCBjaGFubmVsIGxpc3QuCiAgICBccGFyYW0gIHBPdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIG51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgbm9uLW9jY3VwaWVkIGNoYW5uZWwgbGlzdC4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVByZXBhcmVOb25PY2N1cGllZENoYW5uZWxMaXN0KAogICAgICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQsCiAgICAgICAgdEFOSV9VOCAqcElucHV0Q2hhbm5lbExpc3QsCiAgICAgICAgdEFOSV9VOCBudW1PZkNoYW5uZWxzLAogICAgICAgIHRBTklfVTggKnBPdXRwdXRDaGFubmVsTGlzdCwKICAgICAgICB0QU5JX1U4ICpwT3V0cHV0TnVtT2ZDaGFubmVscwogICAgICAgICkKewogICAgdEFOSV9VOCBpID0gMDsKICAgIHRBTklfVTggb3V0cHV0TnVtT2ZDaGFubmVscyAgPSAwOyAvLyBDbGVhciB0aGUgb3V0cHV0IG51bWJlciBvZiBjaGFubmVscwogICAgdEFOSV9VOCBudW1PY2N1cGllZENoYW5uZWxzID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5zY2FuLm9jY3VwaWVkQ2hhbm5lbHNbc2Vzc2lvbklkXS5udW1DaGFubmVsczsKICAgIHRBTklfVTggKnBPY2N1cGllZENoYW5uZWxMaXN0ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5zY2FuLm9jY3VwaWVkQ2hhbm5lbHNbc2Vzc2lvbklkXS5jaGFubmVsTGlzdDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtT2ZDaGFubmVsczsgaSsrKQogICAgewogICAgICAgIGlmICghY3NySXNDaGFubmVsUHJlc2VudEluTGlzdChwT2NjdXBpZWRDaGFubmVsTGlzdCwgbnVtT2NjdXBpZWRDaGFubmVscywKICAgICAgICAgICAgIHBJbnB1dENoYW5uZWxMaXN0W2ldKSkKICAgICAgICB7CiAgICAgICAgICAgLyogREZTIGNoYW5uZWwgd2lsbCBiZSBhZGRlZCBpbiB0aGUgbGlzdCBvbmx5IHdoZW4gdGhlCiAgICAgICAgICAgICAgREZTIFJvYW1pbmcgc2NhbiBmbGFnIGlzIGVuYWJsZWQqLwogICAgICAgICAgICBpZiAoQ1NSX0lTX0NIQU5ORUxfREZTKHBJbnB1dENoYW5uZWxMaXN0W2ldKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKENTUl9ST0FNSU5HX0RGU19DSEFOTkVMX0RJU0FCTEVEICE9CiAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uYWxsb3dERlNDaGFubmVsUm9hbSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBwT3V0cHV0Q2hhbm5lbExpc3Rbb3V0cHV0TnVtT2ZDaGFubmVscysrXSA9IHBJbnB1dENoYW5uZWxMaXN0W2ldOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcE91dHB1dENoYW5uZWxMaXN0W291dHB1dE51bU9mQ2hhbm5lbHMrK10gPSBwSW5wdXRDaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBzbXNMb2cocE1hYywgTE9HMiwgRkwoIk51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgdmFsaWQgY2hhbm5lbCBsaXN0PSVkOyAiCiAgICAgICAgICAgIk51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgbm9uLW9jY3VwaWVkIGxpc3QgbGlzdD0lZCIpLAogICAgICAgICAgICBudW1PZkNoYW5uZWxzLCBvdXRwdXROdW1PZkNoYW5uZWxzKTsKCiAgICAvLyBSZXR1cm4gdGhlIG51bWJlciBvZiBjaGFubmVscwogICAgKnBPdXRwdXROdW1PZkNoYW5uZWxzID0gb3V0cHV0TnVtT2ZDaGFubmVsczsKCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQojZW5kaWYgLyogRkVBVFVSRV9XTEFOX0xGUiAqLwoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuZXZlciB0aGVyZSBpcyBhIHRyYW5zaXRpb24gdG8gQ0ZHIGNoYW4gc2NhbgogICAgICAgICAgICBzdGF0ZSBmcm9tIGFueSBzdGF0ZS4gSXQgZnJlZXMgdXAgdGhlIGN1cnJlbnQgY2hhbm5lbCBsaXN0IGFuZCBhbGxvY2F0ZXMKICAgICAgICAgICAgYSBuZXcgbWVtb3J5IGZvciB0aGUgY2hhbm5lbHMgcmVjZWl2ZWQgZnJvbSBDRkcgaXRlbS4gSXQgdGhlbiBzdGFydHMgdGhlCiAgICAgICAgICAgIG5laWdoYm9yIHNjYW4gdGltZXIgdG8gcGVyZm9ybSB0aGUgc2NhbiBvbiBlYWNoIGNoYW5uZWwgb25lIGJ5IG9uZQoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzICA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICBpbnQgaSA9IDA7CiAgICB0QU5JX1U4IG51bU9mQ2hhbm5lbHMgPSAwOwogICAgdEFOSV9VOCAgIGNoYW5uZWxMaXN0W1dOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTl07CiAgICB0cENzckNoYW5uZWxJbmZvICAgIGN1cnJDaGFubmVsTGlzdEluZm87CiAgICB0QU5JX1U4ICAgc2NhbkNoYW5uZWxMaXN0W1dOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTl07CiAgICBpbnQgICAgICAgb3V0cHV0TnVtT2ZDaGFubmVscyA9IDA7CgogICAgY3VyckNoYW5uZWxMaXN0SW5mbyA9ICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm87CgogICAgaWYgKAojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgICAgICgocE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MpICYmCiAgICAgICAgICAgICAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID09IGVBTklfQk9PTEVBTl9GQUxTRSkpIHx8CiAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jID09IGVBTklfQk9PTEVBTl9GQUxTRSkgfHwKI2VuZGlmIC8vIEVTRQogICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMgPT0gMCkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIkJ1aWxkaW5nIGNoYW5uZWwgbGlzdCB0byBzY2FuIikpOwoKCiAgICAgICAgLyogRnJlZSB1cCB0aGUgY2hhbm5lbCBsaXN0IGFuZCBhbGxvY2F0ZSBhIG5ldyBtZW1vcnkuIFRoaXMgaXMgYmVjYXVzZSB3ZSBkb250IGtub3cgaG93IG11Y2gKICAgICAgICAgICAgd2FzIGFsbG9jYXRlZCBsYXN0IHRpbWUuIElmIHdlIGRpcmVjdGx5IGNvcHkgbW9yZSBudW1iZXIgb2YgYnl0ZXMgdGhhbiBhbGxvY2F0ZWQgZWFybGllciwgdGhpcyBtaWdodAogICAgICAgICAgICByZXN1bHQgaW4gbWVtb3J5IGNvcnJ1cHRpb24gKi8KICAgICAgICBpZiAoTlVMTCAhPSBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCkKICAgICAgICB7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+bnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICAgfQoKICAgICAgICAvLyBOb3cgb2J0YWluIHRoZSBjb250ZW50cyBmb3IgImNoYW5uZWxMaXN0IiAodGhlICJkZWZhdWx0IHZhbGlkIGNoYW5uZWwgbGlzdCIpIGZyb20gRUlUSEVSCiAgICAgICAgLy8gdGhlIGdOZWlnaGJvclNjYW5DaGFubmVsTGlzdCBpbiAiY2ZnLmluaSIsIE9SIHRoZSBhY3R1YWwgInZhbGlkIGNoYW5uZWwgbGlzdCIgaW5mb3JtYXRpb24gZm9ybWVkIGJ5IENTUi4KICAgICAgICBpZiAoMCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICAgICAgewogICAgICAgICAgICAvLyBDb3B5IHRoZSAiZGVmYXVsdCB2YWxpZCBjaGFubmVsIGxpc3QiIChjaGFubmVsTGlzdCkgZnJvbSB0aGUgZ05laWdoYm9yU2NhbkNoYW5uZWxMaXN0IGluICJjZmcuaW5pIi4KICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCAiVXNpbmcgdGhlIGNoYW5uZWwgbGlzdCBmcm9tIGNmZy5pbmkiKTsKICAgICAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtTWVyZ2VDaGFubmVsTGlzdHMoCiAgICAgICAgICAgICAgICAgICAgcE1hYywKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAwLCAvL05COiBJZiAwLCBzaW1wbHkgY29weSB0aGUgaW5wdXQgY2hhbm5lbCBsaXN0IHRvIHRoZSBvdXRwdXQgbGlzdC4KICAgICAgICAgICAgICAgICAgICAmbnVtT2ZDaGFubmVscyApOwoKICAgICAgICAgICAgaWYgKENTUl9JU19ST0FNX0lOVFJBX0JBTkRfRU5BQkxFRChwTWFjKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUN1cnJlbnRCYW5kKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5udW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihudW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIHdyb25nIG51bWJlciBvZiBDaGFubmVsIGxpc3QiKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0lOVkFMOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIFJlbW92ZSB0aGUgREZTIGNoYW5uZWxzIGZyb20gQ0ZHIGNoYW5uZWwgbGlzdCB3aGVuICcKICAgICAgICAgICAgICAgICAgICAgICAgZ0FsbG93Um9hbVRvREZTIGlzIGRpc2FibGVkICovCiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmFsbG93REZTQ2hhbm5lbFJvYW0gPT0gRkFMU0UpIHsKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBudW1PZkNoYW5uZWxzOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIShDU1JfSVNfQ0hBTk5FTF9ERlMoY2hhbm5lbExpc3RbaV0pKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgc2NhbkNoYW5uZWxMaXN0W291dHB1dE51bU9mQ2hhbm5lbHMrK10gPSBjaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIE1vdmUgYWxsIHRoZSBjaGFubmVscyB0byByb2FtIHNjYW4gY2hhbm5lbCBsaXN0ICovCiAgICAgICAgICAgICAgICB2b3NfbWVtX2NvcHkoc2NhbkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgKiBzaXplb2YodWludDhfdCkpOwogICAgICAgICAgICAgICAgb3V0cHV0TnVtT2ZDaGFubmVscyA9IG51bU9mQ2hhbm5lbHM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG91dHB1dE51bU9mQ2hhbm5lbHMgPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJObyBjaGFubmVscyB0byBzY2FuIikpOwogICAgICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0ID0KICAgICAgICAgICAgICAgIHZvc19tZW1fbWFsbG9jKG91dHB1dE51bU9mQ2hhbm5lbHMgKiBzaXplb2YodWludDhfdCkpOwogICAgICAgICAgICBpZiAoTlVMTCA9PSBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgQ2hhbm5lbCBsaXN0IGZhaWxlZCIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfUkVTT1VSQ0VTOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMgPSBvdXRwdXROdW1PZkNoYW5uZWxzOwogICAgICAgICAgICB2b3NfbWVtX2NvcHkoY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgIHNjYW5DaGFubmVsTGlzdCwgb3V0cHV0TnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgfQojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgIGVsc2UgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID09IERFRkFVTFRfU0NBTikgJiYKICAgICAgICAgICAgICAgICAoYWJzKHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSkgPgogICAgICAgICAgICAgICAgICBhYnMocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQpKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRyaWdnZXIgYSBjb250aWd1b3VzIHNjYW4gb24gYWxsIGNoYW5uZWxzIHdoZW4gdGhlCiAgICAgICAgICAgICAqIFJTU0kgaW4gdGhlIGxvb2t1cCBET1dOIG5vdGlmaWNhdGlvbiBpcyBiZWxvdyByZWFzc29jCiAgICAgICAgICAgICAqIHRocmVzaG9sZC4gVGhpcyB3aWxsIGhlbHAgdXMgZmluZCB0aGUgYmVzdCBhdmFpbGFibGUKICAgICAgICAgICAgICogY2FuZGlkYXRlIGFuZCBhbHNvIHVwZGF0ZSB0aGUgY2hhbm5lbCBjYWNoZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgIlRyaWdnZXJpbmcgY29udGlndW91cyBzY2FuICIKICAgICAgICAgICAgICAgICIobG9va3VwRE9XTlJzc2k9JWQscmVhc3NvY1RocmVzaG9sZD0lZCkiLAogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpLAogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQqKC0xKSk7CgogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJlcXVlc3RUaW1lU3RhbXAgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b3NfdGltZXJfZ2V0X3N5c3RlbV90aW1lKCk7CgogICAgICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKCiAgICAgICAgICAgIC8qIFdlIGFyZSBhYm91dCB0byBzdGFydCBhIGZyZXNoIHNjYW4gY3ljbGUsCiAgICAgICAgICAgICAqIHB1cmdlIG5vbi1QMlAgcmVzdWx0cyBmcm9tIHRoZSBwYXN0ICovCiAgICAgICAgICAgIGNzclNjYW5GbHVzaFNlbGVjdGl2ZVJlc3VsdChwTWFjLCBWT1NfRkFMU0UpOwoKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUNvbnRpZ3VvdXNCZ1NjYW4ocE1hYywgc2Vzc2lvbklkKTsKCiAgICAgICAgICAgIC8qIFRyYW5zaXRpb24gdG8gQ0ZHX0NIQU5fTElTVF9TQ0FOICovCiAgICAgICAgICAgIGNzcl9uZWlnaGJvcl9yb2FtX3N0YXRlX3RyYW5zaXRpb24ocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkKTsKCiAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfQojZW5kaWYKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBudW1PZkNoYW5uZWxzID0gcE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzW3Nlc3Npb25JZF0ubnVtQ2hhbm5lbHM7CiAgICAgICAgICAgIGlmIChudW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKSB7CiAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzID0gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChudW1PZkNoYW5uZWxzCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICAmJiAoKHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUgPT0gU1BMSVRfU0NBTl9PQ0NVUElFRF9MSVNUKSB8fAogICAgICAgICAgICAgICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID09IDApIHx8CiAgICAgICAgICAgICAgICAgICAgKChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ICUgMikgPT0gMSkpCiNlbmRpZgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogQWx3YXlzIHNjYW4gY2hhbm5lbHMgaW4gdGhlIG9jY3VwaWVkIGNoYW5uZWwgbGlzdAogICAgICAgICAgICAgICAgICogYmVmb3JlIHNjYW5uaW5nIG9uIHRoZSBub24tb2NjdXBpZWQgbGlzdC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCAiU3dpdGNoaW5nIHRvIG9jY3VwaWVkIGNoYW5uZWwgbGlzdCIKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgICAgICAgICAiLXVTY2FuTW9kZT0lZCwgdUVtcHR5U2NhbkNvdW50PSVkIiwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlLAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQKI2VuZGlmCiAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmIChDU1JfSVNfUk9BTV9JTlRSQV9CQU5EX0VOQUJMRUQocE1hYykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUN1cnJlbnRCYW5kKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnNjYW4ub2NjdXBpZWRDaGFubmVsc1tzZXNzaW9uSWRdLmNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm51bU9mQ2hhbm5lbHMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fY29weShjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnNjYW4ub2NjdXBpZWRDaGFubmVsc1tzZXNzaW9uSWRdLmNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyogUmVtb3ZlIHRoZSBERlMgY2hhbm5lbHMgZnJvbSBDRkcgY2hhbm5lbCBsaXN0IHdoZW4KICAgICAgICAgICAgICAgICAqIGdBbGxvd1JvYW1Ub0RGUyBpcyBkaXNhYmxlZAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5hbGxvd0RGU0NoYW5uZWxSb2FtID09IEZBTFNFKSB7CiAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbnVtT2ZDaGFubmVsczsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoQ1NSX0lTX0NIQU5ORUxfREZTKGNoYW5uZWxMaXN0W2ldKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5DaGFubmVsTGlzdFtvdXRwdXROdW1PZkNoYW5uZWxzKytdID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fY29weShzY2FuQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgKiAoc2l6ZW9mKHVpbnQ4X3QpKSk7CiAgICAgICAgICAgICAgICAgICAgb3V0cHV0TnVtT2ZDaGFubmVscyA9IG51bU9mQ2hhbm5lbHM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAob3V0cHV0TnVtT2ZDaGFubmVscyA9PSAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTm8gY2hhbm5lbHMgdG8gc2NhbiIpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCA9CiAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9tYWxsb2Mob3V0cHV0TnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CgogICAgICAgICAgICAgICAgaWYgKE5VTEwgPT0gY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgQ2hhbm5lbCBsaXN0IGZhaWxlZCIpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX1JFU09VUkNFUzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMgPSBvdXRwdXROdW1PZkNoYW5uZWxzOwogICAgICAgICAgICAgICAgdm9zX21lbV9jb3B5KGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICBzY2FuQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dE51bU9mQ2hhbm5lbHMgKiBzaXplb2YodEFOSV9VOCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogU2NhbiBhbGwgY2hhbm5lbHMgZnJvbSBub24tb2NjdXBpZWQgbGlzdCAqLwogICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCAiR2V0IHZhbGlkIGNoYW5uZWwgbGlzdCIpOwogICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyA9IHNpemVvZihwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QpOwoKICAgICAgICAgICAgICAgIGlmKEhBTF9TVEFUVVNfU1VDQ0VTUyhjc3JHZXRDZmdWYWxpZENoYW5uZWxzKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTMyICopICZudW1PZkNoYW5uZWxzKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChudW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgPSBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU47CiAgICAgICAgICAgICAgICB9CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogUHJlcGFyZSBub24tb2NjdXBpZWQgY2hhbm5lbCBsaXN0IChjaGFubmVsTGlzdCkKICAgICAgICAgICAgICAgICAqIGZyb20gdGhlIGFjdHVhbCAidmFsaWQgY2hhbm5lbCBsaXN0IiBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICogZm9ybWVkIGJ5IENTUi4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCAiU3dpdGNoaW5nIHRvIG5vbi1vY2N1cGllZCBjaGFubmVsIGxpc3QiKTsKICAgICAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByZXBhcmVOb25PY2N1cGllZENoYW5uZWxMaXN0KHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VOCAqKXBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzKTsKI2Vsc2UKICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIk1lcmdpbmcgY2hhbm5lbCBsaXN0Iik7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1NZXJnZUNoYW5uZWxMaXN0cygKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VOCAqKXBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMsICAgLy8gVGhlIG51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgdmFsaWRDaGFubmVsTGlzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvL05COiBJZiAwLCBzaW1wbHkgY29weSB0aGUgaW5wdXQgY2hhbm5lbCBsaXN0IHRvIHRoZSBvdXRwdXQgbGlzdC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzICk7IC8vIFRoZSBmaW5hbCBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIG91dHB1dCBsaXN0LiBXaWxsIGJlIG51bU9mQ2hhbm5lbHMKI2VuZGlmCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkNvdWxkIG5vdCBnZXQgdmFsaWQgY2hhbm5lbCBsaXN0IikpOwogICAgICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoQ1NSX0lTX1JPQU1fSU5UUkFfQkFORF9FTkFCTEVEKHBNYWMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1DaGFubmVsc0ZpbHRlckJ5Q3VycmVudEJhbmQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbnVtT2ZDaGFubmVscyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG51bU9mQ2hhbm5lbHMgPiBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU4pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgPSBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG91dHB1dE51bU9mQ2hhbm5lbHMgPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTm8gY2hhbm5lbHMgdG8gc2NhbiIpKTsKICAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QgPQogICAgICAgICAgICAgICAgdm9zX21lbV9tYWxsb2MobnVtT2ZDaGFubmVscypzaXplb2YodEFOSV9VOCkpOwoKICAgICAgICAgICAgaWYgKE5VTEwgPT0gY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZm9yIENoYW5uZWwgbGlzdCBmYWlsZWQiKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX1JFU09VUkNFUzsKICAgICAgICAgICAgfQogICAgICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5udW1PZkNoYW5uZWxzID0gbnVtT2ZDaGFubmVsczsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgdm9zX21lbV9jb3B5KGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LCBudW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKI2Vsc2UKICAgICAgICAgICAgdm9zX21lbV9jb3B5KGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICh0QU5JX1U4ICopcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgKiBzaXplb2YodEFOSV9VOCkpOwojZW5kaWYKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogQWRqdXN0IGZvciB0aGUgYWN0dWFsIG51bWJlciB0aGF0IGFyZSB1c2VkICovCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLAogICAgICAgICAgICAiTnVtYmVyIG9mIGNoYW5uZWxzIGZyb20gQ0ZHIChvcikgKG5vbi0pb2NjdXBpZWQgbGlzdD0lZCIsCiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBjdXJyQ2hhbm5lbExpc3RJbmZvLT5udW1PZkNoYW5uZWxzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICJDaGFubmVsIExpc3QgZnJvbSBDRkcgKG9yKSAobm9uLSlvY2N1cGllZCBsaXN0IgogICAgICAgICAgICAgICAgICAgICI9ICVkIiwgY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3RbaV0pOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBXZSBhcmUgZ29ubmEgc2NhbiBub3cuIFJlbWVtYmVyIHRoZSB0aW1lIHN0YW1wIHRvIGZpbHRlciBvdXQgcmVzdWx0cwogICAgICAgb25seSBhZnRlciB0aGlzIHRpbWUgc3RhbXAgKi8KICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUmVxdWVzdFRpbWVTdGFtcCA9IHZvc190aW1lcl9nZXRfc3lzdGVtX3RpbWUoKTsKCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgIHN0YXR1cyA9IHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyLAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JTY2FuUGVyaW9kKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgLyogVGltZXIgc3RhcnQgZmFpbGVkLi4gICovCiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIFBBTCBUaW1lciBzdGFydCBmYWlsZWQsIHN0YXR1cyA9ICVkLCBJZ25vcmluZyBzdGF0ZSB0cmFuc2l0aW9uIiksIHN0YXR1cyk7CiAgICAgICAgdm9zX21lbV9mcmVlKGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0KTsKICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+bnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgIC8qIFdlIGFyZSBhYm91dCB0byBzdGFydCBhIGZyZXNoIHNjYW4gY3ljbGUsCiAgICAgKiBwdXJnZSBub24tUDJQIHJlc3VsdHMgZnJvbSB0aGUgcGFzdCAqLwogICAgY3NyU2NhbkZsdXNoU2VsZWN0aXZlUmVzdWx0KHBNYWMsIFZPU19GQUxTRSk7CgogICAgLyogV2UgYXJlIGFib3V0IHRvIHN0YXJ0IGEgZnJlc2ggc2NhbiBjeWNsZSwKICAgICAqIHB1cmdlIGZhaWxlZCBwcmUtYXV0aCByZXN1bHRzIGZyb20gdGhlIHBhc3QgKi8KICAgIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxlZExpc3QocE1hYyk7CgogICAgLyogVHJhbnNpdGlvbiB0byBDRkdfQ0hBTl9MSVNUX1NDQU5fU1RBVEUgKi8KICAgIGNzcl9uZWlnaGJvcl9yb2FtX3N0YXRlX3RyYW5zaXRpb24ocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkKTsKCiAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVcEV2ZW50CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhcyBzb29uIGFzIFRMIGluZGljYXRlcyB0aGF0IHRoZSBjdXJyZW50IEFQJ3MKICAgICAgICAgICAgUlNTSSBpcyBiZXR0ZXIgdGhhbiB0aGUgbmVpZ2hib3IgbG9va3VwIHRocmVzaG9sZC4gSGVyZSwgd2UgdHJhbnNpdGlvbiB0bwogICAgICAgICAgICBDT05ORUNURUQgc3RhdGUgYW5kIHJlc2V0IGFsbCB0aGUgc2NhbiBwYXJhbWV0ZXJzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgXHBhcmFtICBzZXNzaW9uSWQgLSBTZXNzaW9uIElECgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVcEV2ZW50KHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CiAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXM7CiAgICB0cEZUUm9hbUNhbGxiYWNrVXNyQ3R4ICBwVXNyQ3R4OwogICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjLCBzZXNzaW9uSWQpOwoKICAgIC8qIFJlY2hlY2sgd2hldGhlciB0aGUgYmVsb3cgY2hlY2sgaXMgbmVlZGVkLiAqLwogICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUgIT0gZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCkKICAgICAgICAmJiAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlICE9IGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRUFTU09DSUFUSU5HKSkKICAgICAgICBjc3JfbmVpZ2hib3Jfcm9hbV9zdGF0ZV90cmFuc2l0aW9uKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkKTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIGlmICghY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsIHNlc3Npb25JZCkpIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkxvb2tVcCBldmVudCByZWNlaXZlZCB3aGVuIGZhc3Qgcm9hbSBpcyAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkaXNhYmxlZC4gSWdub3JlIGl0IikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQojZW5kaWYKICAgIC8qIFJlc2V0IGFsbCB0aGUgbmVpZ2hib3Igcm9hbSBpbmZvIGNvbnRyb2wgdmFyaWFibGVzLiBGcmVlIGFsbCB0aGUgYWxsb2NhdGVkIG1lbW9yeS4gSXQgaXMgbGlrZSB3ZSBhcmUganVzdCBhc3NvY2lhdGVkIG5vdyAqLwogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMsIHNlc3Npb25JZCk7CgogICAgLyogVGhpcyB1c2VyIGNvbnRleHQgZGF0YSB3aWxsIGJlIHJldHVybmVkIHdpdGggY2FsbGJhY2sgKi8KICAgIHBVc3JDdHggPSB2b3NfbWVtX21hbGxvYyhzaXplb2YoKnBVc3JDdHgpKTsKICAgIGlmIChOVUxMID09IHBVc3JDdHgpIHsKICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZmFpbHVyZSIpKTsKICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfTk9NRU07CiAgICB9CiAgICBwVXNyQ3R4LT5wTWFjID0gcE1hYzsKICAgIHBVc3JDdHgtPnNlc3Npb25JZCA9IHNlc3Npb25JZDsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJSZWdpc3RlcmluZyBET1dOIGV2ZW50IG5laWdoYm9yIGxvb2t1cCBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQsIiksIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpKTsKICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCBmb3IgRE9XTiBldmVudCBub3cgKi8KICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FLCBwVXNyQ3R4KTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSA9IDA7CiNlbmRpZgogICAgdm9zX21lbV9mcmVlKHBVc3JDdHgpOwogICAgaWYgKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgIHsKICAgICAgIC8vZXJyIG1zZwogICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBDYWxsYmFjayBET1dOIGV2ZW50IHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICB9CgoKICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERvd25FdmVudAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYXMgc29vbiBhcyBUTCBpbmRpY2F0ZXMgdGhhdCB0aGUgY3VycmVudCBBUCdzCiAgICAgICAgICAgIFJTU0kgZmFsbHMgYmVsb3cgdGhlIGN1cnJlbnQgbmVpZ2hib3IgbG9va3VwIHRocmVzaG9sZC4KICAgICAgICAgICAgSGVyZSwgd2UgdHJhbnNpdGlvbiB0byBSRVBPUlRfUVVFUlkgZm9yIDExciBhc3NvY2lhdGlvbiBhbmQKICAgICAgICAgICAgQ0ZHX0NIQU5fTElTVF9TQ0FOIHN0YXRlIGlmIHRoZSBhc3NvYyBpcyBhIG5vbi0xMVIgYXNzb2NpYXRpb24uCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgXHBhcmFtICBzZXNzaW9uSWQgLSBTZXNzaW9uIElkCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBEb3duRXZlbnQodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CiAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICBlSGFsU3RhdHVzICBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdHBGVFJvYW1DYWxsYmFja1VzckN0eCAgcFVzckN0eDsKCiAgICBzd2l0Y2ggKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQ6CgogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJEZXJlZ2lzdGVyaW5nIERPV04gZXZlbnQgbmVpZ2hib3IgbG9va3VwIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSkpOwogICAgICAgICAgICAvKiBEZS1yZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgKi8KICAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX0RlcmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CgogICAgICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IERlcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBDYWxsYmFjayBET1dOIGV2ZW50IGZyb20gVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgIH0KI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgaWYgKCFjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYywgc2Vzc2lvbklkKSkgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJMb29rRG93biBldmVudCByZWNlaXZlZCB3aGVuIGZhc3Qgcm9hbSAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImlzIGRpc2FibGVkLiBJZ25vcmUgaXQiKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICAgICAgfQojZW5kaWYKCiNpZiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICYmIGRlZmluZWQgV0xBTl9GRUFUVVJFX1ZPV0lGSQogICAgICAgICAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKSAmJiAocE1hYy0+cnJtLnJybVNtZUNvbnRleHQucnJtQ29uZmlnLnJybV9lbmFibGVkKSkKICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIjExUiBBc3NvY2lhdGlvbjpOZWlnaGJvciBMb29rdXAgRG93biBldmVudCByZWNlaXZlZCBpbiBDT05ORUNURUQgc3RhdGUiKSk7CiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZU5laWdoYm9yUnB0UmVxdWVzdChwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkKTsKICAgICAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVwb3J0IHJlcXVlc3QgZmFpbGVkLiBzdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB2b3NTdGF0dXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiBJbmNyZW1lbnQgdGhlIG5laWdoYm9yIHJlcG9ydCByZXRyeSBjb3VudCBhZnRlciBzZW5kaW5nIHRoZSBuZWlnaGJvciByZXF1ZXN0IHN1Y2Nlc3NmdWxseSAqLwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0rKzsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgICAgICAgICAgY3NyX25laWdoYm9yX3JvYW1fc3RhdGVfdHJhbnNpdGlvbihwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1FVRVJZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKI2VuZGlmCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIk5vbiAxMVIgb3IgRVNFIEFzc29jaWF0aW9uOk5laWdoYm9yIExvb2t1cCBEb3duIGV2ZW50IHJlY2VpdmVkIGluIENPTk5FQ1RFRCBzdGF0ZSIpKTsKCiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1UcmFuc2l0VG9DRkdDaGFuU2NhbihwTWFjLCBzZXNzaW9uSWQpOwogICAgICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4gZmFpbGVkIgogICAgICAgICAgICAgICAgICAgICAgICAgICIgd2l0aCBzdGF0dXM9JWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdm9zU3RhdHVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIFVQIGV2ZW50IG5laWdoYm9yIGxvb2t1cCBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQsIiksIE5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSkpOwogICAgICAgICAgICAvKiBSZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgZm9yIFVQIGV2ZW50IG5vdyAqLwogICAgICAgICAgICBwVXNyQ3R4ID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKCpwVXNyQ3R4KSk7CiAgICAgICAgICAgIGlmIChOVUxMID09IHBVc3JDdHgpIHsKICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQiKSk7CiAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMRURfQUxMT0M7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9VUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBVc3JDdHgpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocFVzckN0eCk7CiAgICAgICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgICAgICAgICBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwQ2FsbGJhY2siCiAgICAgICAgICAgICAgICAgICAgICAiVVAgZXZlbnQgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJET1dOIGV2ZW50IHJlY2VpdmVkIGluIGludmFsaWQiCiAgICAgICAgICAgICAgICAgICAic3RhdGUgJXMgLi5JZ25vcmluZy4uLiIpLAogICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgfQogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjawoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyByZWdpc3RlcmVkIHdpdGggVEwgdG8gaW5kaWNhdGUgd2hlbmV2ZXIgdGhlIFJTU0kKICAgICAgICAgICAgZ2V0cyBiZXR0ZXIgdGhhbiB0aGUgbmVpZ2hib3JMb29rdXAgUlNTSSBUaHJlc2hvbGQKCiAgICBccGFyYW0gIHBBZGFwdGVyIC0gVk9TIENvbnRleHQKICAgICAgICAgICAgdHJhZmZpY1N0YXR1cyAtIFVQL0RPV04gaW5kaWNhdGlvbiBmcm9tIFRMCiAgICAgICAgICAgIHBVc2VyQ3R4dCAtIFBhcmFtZXRlciBmb3IgY2FsbGJhY2sgcmVnaXN0ZXJlZCBkdXJpbmcgY2FsbGJhY2sgcmVnaXN0cmF0aW9uLiBTaG91bGQgYmUgcE1hYwoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMKY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrICh2X1BWT0lEX3QgcEFkYXB0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9VOF90IHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9QVk9JRF90IHBVc2VyQ3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1M3X3QgYXZnUnNzaSkKewogICAgdEZUUm9hbUNhbGxiYWNrVXNyQ3R4ICpwVXNyQ3R4ID0gKHRGVFJvYW1DYWxsYmFja1VzckN0eCAqKXBVc2VyQ3R4dDsKICAgIHRBTklfVTMyICAgIHNlc3Npb25JZCA9IHBVc3JDdHgtPnNlc3Npb25JZDsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBwVXNyQ3R4LT5wTWFjOwogICAgVk9TX1NUQVRVUyAgdm9zU3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJOZWlnaGJvciBMb29rdXAgVVAgaW5kaWNhdGlvbiBjYWxsYmFjayBjYWxsZWQgd2l0aCBub3RpZmljYXRpb24gJWQgUmVwb3J0ZWQgUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2Z1Jzc2kpOwoKICAgIGlmICghY3NySXNDb25uU3RhdGVDb25uZWN0ZWRJbmZyYShwTWFjLCBzZXNzaW9uSWQpKSB7CiAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIkxvb2tVcCBFdmVudCByZWNlaXZlZCB3aGVuIHdlIGFyZSBub3QgY29ubmVjdGVkLiAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgIklnbm9yZSBpdCIpKTsKICAgICAgIHZvc19tZW1fZnJlZShwVXNyQ3R4KTsKICAgICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgaWYgKFdMQU5UTF9IT19USFJFU0hPTERfVVAgIT0gcnNzaU5vdGlmaWNhdGlvbikKICAgIHsKICAgICAgIFZPU19BU1NFUlQoV0xBTlRMX0hPX1RIUkVTSE9MRF9VUCA9PSByc3NpTm90aWZpY2F0aW9uKTsKICAgICAgIHZvc19tZW1fZnJlZShwVXNyQ3R4KTsKICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVXBFdmVudChwTWFjLCBzZXNzaW9uSWQpOwogICAgdm9zX21lbV9mcmVlKHBVc3JDdHgpOwogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHJlZ2lzdGVyZWQgd2l0aCBUTCB0byBpbmRpY2F0ZSB3aGVuZXZlciB0aGUgUlNTSQogICAgICAgICAgICBmYWxscyBiZWxvdyB0aGUgY3VycmVudCBuZWlnaGJvckxvb2t1cCBSU1NJIFRocmVzaG9sZAoKICAgIFxwYXJhbSAgcEFkYXB0ZXIgLSBWT1MgQ29udGV4dAogICAgICAgICAgICB0cmFmZmljU3RhdHVzIC0gVVAvRE9XTiBpbmRpY2F0aW9uIGZyb20gVEwKICAgICAgICAgICAgcFVzZXJDdHh0IC0gUGFyYW1ldGVyIGZvciBjYWxsYmFjayByZWdpc3RlcmVkIGR1cmluZyBjYWxsYmFjayByZWdpc3RyYXRpb24uIFNob3VsZCBiZSBwTWFjCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUwpjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjayAodl9QVk9JRF90IHBBZGFwdGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9VOF90IHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1BWT0lEX3QgcFVzZXJDdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9TN190IGF2Z1Jzc2kpCnsKICAgdEZUUm9hbUNhbGxiYWNrVXNyQ3R4ICpwVXNyQ3R4ID0gKHRGVFJvYW1DYWxsYmFja1VzckN0eCAqKXBVc2VyQ3R4dDsKICAgdEFOSV9VMzIgICAgc2Vzc2lvbklkID0gcFVzckN0eC0+c2Vzc2lvbklkOwogICB0cEFuaVNpckdsb2JhbCBwTWFjID0gcFVzckN0eC0+cE1hYzsKICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgVk9TX1NUQVRVUyAgdm9zU3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJOZWlnaGJvciBMb29rdXAgRE9XTiBpbmRpY2F0aW9uIGNhbGxiYWNrIGNhbGxlZCB3aXRoIG5vdGlmaWNhdGlvbiAlZCBSZXBvcnRlZCBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmdSc3NpKTsKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSBhdmdSc3NpOwojZW5kaWYKICAgIGlmICghY3NySXNDb25uU3RhdGVDb25uZWN0ZWRJbmZyYShwTWFjLCBzZXNzaW9uSWQpKSB7CiAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIkxvb2tEb3duIEV2ZW50IHJlY2VpdmVkIHdoZW4gd2UgYXJlIG5vdCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbm5lY3RlZC4gSWdub3JlIGl0IikpOwogICAgICAgdm9zX21lbV9mcmVlKHBVc3JDdHgpOwogICAgICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAoV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOICE9IHJzc2lOb3RpZmljYXRpb24pCiAgICB7CiAgICAgICBWT1NfQVNTRVJUKFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiA9PSByc3NpTm90aWZpY2F0aW9uKTsKICAgICAgIHZvc19tZW1fZnJlZShwVXNyQ3R4KTsKICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRG93bkV2ZW50KHBNYWMsIHNlc3Npb25JZCk7CiAgICB2b3NfbWVtX2ZyZWUocFVzckN0eCk7CgogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKLyoqCiAqIGNzcl9yb2FtX3Jlc2V0X3JvYW1fcGFyYW1zKCkgLSBBUEkgdG8gcmVzZXQgdGhlIHJvYW1pbmcgcGFyYW1ldGVycwogKiBAbWFjX2N0eDogICAgICAgR2xvYmFsIE1BQyBDb250ZXh0IHBvaW50ZXIuCiAqCiAqIFJldHVybjogVk9JRAogKi8Kdm9pZCBjc3Jfcm9hbV9yZXNldF9yb2FtX3BhcmFtcyh0cEFuaVNpckdsb2JhbCBtYWNfY3R4KQp7CglzdHJ1Y3Qgcm9hbV9leHRfcGFyYW1zICpyb2FtX3BhcmFtcyA9IE5VTEw7CgkvKiBjbGVhciBhbGwgdGhlIHdoaXRlbGlzdCBwYXJhbWV0ZXJzLAoJICogcmVtYWluaW5nIG5lZWRzIHRvIGJlIHJldGFpbmVkIGFjcm9zcyBjb25uZWN0aW9ucy4gKi8KCglWT1NfVFJBQ0UoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAoJCQlGTCgiUm9hbWluZyBwYXJhbWV0ZXJzIGFyZSByZXNldCIpKTsKCXJvYW1fcGFyYW1zID0gJm1hY19jdHgtPnJvYW0uY29uZmlnUGFyYW0ucm9hbV9wYXJhbXM7Cglyb2FtX3BhcmFtcy0+bnVtX3NzaWRfYWxsb3dlZF9saXN0ID0gMDsKCXZvc19tZW1fc2V0KCZyb2FtX3BhcmFtcy0+c3NpZF9hbGxvd2VkX2xpc3QsIDAsCgkJc2l6ZW9mKHRTaXJNYWNTU2lkKSAqIE1BWF9TU0lEX0FMTE9XRURfTElTVCk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1JbmRpY2F0ZURpc2Nvbm5lY3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IENTUiBhcyBzb29uIGFzIHRoZSBzdGF0aW9uIGRpc2Nvbm5lY3RzIGZyb20KICAgICAgICAgICAgdGhlIEFQLiBUaGlzIGZ1bmN0aW9uIGRvZXMgdGhlIG5lY2Vzc2FyeSBjbGVhbnVwIG9mIG5laWdoYm9yIHJvYW0gZGF0YQogICAgICAgICAgICBzdHJ1Y3R1cmVzLiBOZWlnaGJvciByb2FtIHN0YXRlIHRyYW5zaXRpb25zIHRvIElOSVQgc3RhdGUgd2hlbmV2ZXIgdGhpcwogICAgICAgICAgICBmdW5jdGlvbiBpcyBjYWxsZWQgZXhjZXB0IGlmIHRoZSBjdXJyZW50IHN0YXRlIGlzIFJFQVNTT0NJQVRJTkcKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHNlc3Npb25JZCAtIENTUiBzZXNzaW9uIGlkIHRoYXQgZ290IGRpc2Nvbm5lY3RlZAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUluZGljYXRlRGlzY29ubmVjdCh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHRDc3JSb2FtQ29ubmVjdGVkUHJvZmlsZSAqcFByZXZQcm9maWxlID0gJnBOZWlnaGJvclJvYW1JbmZvLT5wcmV2Q29ublByb2ZpbGU7CiNlbmRpZgogICAgdENzclJvYW1TZXNzaW9uICpwU2Vzc2lvbiA9IENTUl9HRVRfU0VTU0lPTiggcE1hYywgc2Vzc2lvbklkKTsKCiAgICBpZiAoTlVMTCA9PSBwU2Vzc2lvbikKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoInBTZXNzaW9uIGlzIE5VTEwgIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgVk9TX1RSQUNFKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgIEZMKCJEaXNjb25uZWN0IGluZGljYXRpb24gb24gc2Vzc2lvbiAlZCBpbiBzdGF0ZSAlZCBmcm9tIEJTU0lEIDogIgogICAgICAgICAgICAgICAgICAgTUFDX0FERFJFU1NfU1RSKSwgc2Vzc2lvbklkLCBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUsCiAgICAgICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShwU2Vzc2lvbi0+Y29ubmVjdGVkUHJvZmlsZS5ic3NpZCkpOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgLypGcmVlIHRoZSBjdXJyZW50IHByZXZpb3VzIHByb2ZpbGUgYW5kIG1vdmUgdGhlIGN1cnJlbnQgcHJvZmlsZSB0byBwcmV2IHByb2ZpbGUuKi8KICAgIGNzclJvYW1GcmVlQ29ubmVjdFByb2ZpbGUocE1hYywgcFByZXZQcm9maWxlKTsKICAgIGNzclJvYW1Db3B5Q29ubmVjdFByb2ZpbGUocE1hYywgc2Vzc2lvbklkLCBwUHJldlByb2ZpbGUpOwoKICAgIC8qIGNsZWFyIHRoZSByb2FtaW5nIHBhcmFtZXRlcnMgdGhhdCBhcmUgcGVyIGNvbm5lY3Rpb24uCiAgICAgKiBGb3IgYSBuZXcgY29ubmVjdGlvbiwgdGhleSBoYXZlIHRvIGJlIHByb2dyYW1tZWQgYWdhaW4uICovCiAgICBpZiAoIWNzck5laWdoYm9yTWlkZGxlT2ZSb2FtaW5nKCh0SGFsSGFuZGxlKXBNYWMsIHNlc3Npb25JZCkpCiAgICAgIGNzcl9yb2FtX3Jlc2V0X3JvYW1fcGFyYW1zKHBNYWMpOwojZW5kaWYKICAgIGlmIChOVUxMICE9IHBTZXNzaW9uKQogICAgewogICAgICAgIGlmIChOVUxMICE9IHBTZXNzaW9uLT5wQ3VyUm9hbVByb2ZpbGUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoVk9TX1NUQV9NT0RFICE9IHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5wQ3VyUm9hbVByb2ZpbGUtPmNzclBlcnNvbmEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiSWdub3JpbmcgRGlzY29ubmVjdCBpbmRpY2F0aW9uIHJlY2VpdmVkIGZyb20gYSBub24gU1RBIHBlcnNvbmEuIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXNzaW9uSWQ6ICVkLCBjc3JQZXJzb25uYSAlZCIpLCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgKGludClwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0ucEN1clJvYW1Qcm9maWxlLT5jc3JQZXJzb25hKTsKICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgICAgICB9CiAgICAgICAgfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgICAgICBpZiAocFNlc3Npb24tPmNvbm5lY3RlZFByb2ZpbGUuaXNFU0VBc3NvYykKICAgICAgICB7CiAgICAgICAgICAgdm9zX21lbV9jb3B5KCZwU2Vzc2lvbi0+cHJldkFwU1NJRCwgJnBTZXNzaW9uLT5jb25uZWN0ZWRQcm9maWxlLlNTSUQsCiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih0U2lyTWFjU1NpZCkpOwogICAgICAgICAgIHZvc19tZW1fY29weShwU2Vzc2lvbi0+cHJldkFwQnNzaWQsIHBTZXNzaW9uLT5jb25uZWN0ZWRQcm9maWxlLmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICAgICBwU2Vzc2lvbi0+cHJldk9wQ2hhbm5lbCA9IHBTZXNzaW9uLT5jb25uZWN0ZWRQcm9maWxlLm9wZXJhdGlvbkNoYW5uZWw7CiAgICAgICAgICAgcFNlc3Npb24tPmlzUHJldkFwSW5mb1ZhbGlkID0gVFJVRTsKICAgICAgICAgICBwU2Vzc2lvbi0+cm9hbVRTMSA9IHZvc190aW1lcl9nZXRfc3lzdGVtX3RpbWUoKTsKICAgICAgICB9CiNlbmRpZgogICAgfSAvL2lmIChOVUxMICE9IHBTZXNzaW9uKQoKICAgIHN3aXRjaCAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFQVNTT0NJQVRJTkc6CiAgICAgICAgICAgIC8vIFN0b3Agc2NhbiBhbmQgbmVpZ2hib3IgcmVmcmVzaCB0aW1lcnMuCiAgICAgICAgICAgIC8vIFRoZXNlIGFyZSBpbmRlZWQgbm90IHJlcXVpcmVkIHdoZW4gd2UgYXJlIGluIHJlYXNzb2NpYXRpbmcKICAgICAgICAgICAgLy8gc3RhdGUuCiAgICAgICAgICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICAgICAgICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAgICAgICAgaWYgKCFDU1JfSVNfUk9BTV9TVUJTVEFURV9ESVNBU1NPQ19ITyggcE1hYywgc2Vzc2lvbklkICkpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBEaXNjb25uZWN0IGluZGljYXRpb24gZHVyaW5nIERpc2Fzc29jIEhhbmRvZmYgc3ViLXN0YXRlCiAgICAgICAgICAgICAgICAgKiBpcyByZWNlaXZlZCB3aGVuIHdlIGFyZSB0cnlpbmcgdG8gZGlzY29ubmVjdCB3aXRoIHRoZSBvbGQKICAgICAgICAgICAgICAgICAqIEFQIGR1cmluZyByb2FtLiBCVVQsIGlmIHJlY2VpdmUgYSBkaXNjb25uZWN0IGluZGljYXRpb24KICAgICAgICAgICAgICAgICAqIG91dHNpZGUgb2YgRGlzYXNzb2MgSGFuZG9mZiBzdWItc3RhdGUsIHRoZW4gaXQgbWVhbnMgdGhhdAogICAgICAgICAgICAgICAgICogdGhpcyBpcyBhIGdlbnVpbmUgZGlzY29ubmVjdCBhbmQgd2UgbmVlZCB0byBjbGVhbiB1cC4KICAgICAgICAgICAgICAgICAqIE90aGVyd2lzZSwgd2Ugd2lsbCBiZSBzdHVjayBpbiByZWFzc29jIHN0YXRlIHdoaWNoIHdpbGwKICAgICAgICAgICAgICAgICAqIGluLXR1cm4gYmxvY2sgc2NhbnMuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGNzcl9uZWlnaGJvcl9yb2FtX3N0YXRlX3RyYW5zaXRpb24ocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKI2VuZGlmCiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQ6CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0SW5pdFN0YXRlQ29udHJvbEluZm8ocE1hYywgc2Vzc2lvbklkKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjLCBzZXNzaW9uSWQpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQ6CiAgICAgICAgICAgIGNzcl9uZWlnaGJvcl9yb2FtX3N0YXRlX3RyYW5zaXRpb24ocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMsIHNlc3Npb25JZCk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgICAgICB7CiNlbmRpZgogICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYywgc2Vzc2lvbklkKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOOgogICAgICAgICAgICBjc3JfbmVpZ2hib3Jfcm9hbV9zdGF0ZV90cmFuc2l0aW9uKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkKTsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q2ZnTGlzdENoYW5TY2FuQ29udHJvbEluZm8ocE1hYywgc2Vzc2lvbklkKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICAgICAgICAgIGlmICghY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICAgICAgewojZW5kaWYKICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMsIHNlc3Npb25JZCk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORToKICAgICAgICAgICAgLyogU3RvcCBwcmUtYXV0aCB0byByZWFzc29jIGludGVydmFsIHRpbWVyICovCiAgICAgICAgICAgIHZvc190aW1lcl9zdG9wKCZwU2Vzc2lvbi0+ZnRTbWVDb250ZXh0LnByZUF1dGhSZWFzc29jSW50dmxUaW1lcik7CiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU46CiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkc6CiAgICAgICAgICAgIGNzcl9uZWlnaGJvcl9yb2FtX3N0YXRlX3RyYW5zaXRpb24ocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRQcmVhdXRoQ29udHJvbEluZm8ocE1hYywgc2Vzc2lvbklkKTsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRSZXBvcnRTY2FuU3RhdGVDb250cm9sSW5mbyhwTWFjLCBzZXNzaW9uSWQpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmICghY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICAgICAgewojZW5kaWYKICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMsIHNlc3Npb25JZCk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiUmVjZWl2ZWQgZGlzY29ubmVjdCBldmVudCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW4gc3RhdGUgJXMgIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiVHJhbnNpdGlvbmluZyB0byBJTklUIHN0YXRlIikpOwogICAgICAgICAgICBjc3JfbmVpZ2hib3Jfcm9hbV9zdGF0ZV90cmFuc2l0aW9uKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkKTsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwojZW5kaWYKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIC8qSW5mb3JtIHRoZSBGaXJtd2FyZSB0byBTVE9QIFNjYW5uaW5nIGFzIHRoZSBob3N0IGhhcyBhIGRpc2Nvbm5lY3QuKi8KICAgIGlmIChjc3JSb2FtSXNTdGFNb2RlKHBNYWMsIHNlc3Npb25JZCkpCiAgICB7CiAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgc2Vzc2lvbklkLCBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QLAogICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9ESVNDT05ORUNURUQpOwogICAgfQojZW5kaWYKCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUluZGljYXRlQ29ubmVjdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgQ1NSIGFzIHNvb24gYXMgdGhlIHN0YXRpb24gY29ubmVjdHMgdG8gYW4gQVAuCiAgICAgICAgICAgIFRoaXMgaW5pdGlhbGl6ZXMgYWxsIHRoZSBuZWNlc3NhcnkgZGF0YSBzdHJ1Y3R1cmVzIHJlbGF0ZWQgdG8gdGhlCiAgICAgICAgICAgIGFzc29jaWF0ZWQgQVAgYW5kIHRyYW5zaXRpb25zIHRoZSBzdGF0ZSB0byBDT05ORUNURUQgc3RhdGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHNlc3Npb25JZCAtIENTUiBzZXNzaW9uIGlkIHRoYXQgZ290IGNvbm5lY3RlZAogICAgICAgICAgICB2b3NTdGF0dXMgLSBjb25uZWN0IHN0YXR1cyBTVUNDRVNTL0ZBSUxVUkUKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1JbmRpY2F0ZUNvbm5lY3QodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19TVEFUVVMgdm9zU3RhdHVzKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIGVIYWxTdGF0dXMgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICBWT1NfU1RBVFVTICB2c3RhdHVzOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fT0ZGTE9BRAogICAgdENzclJvYW1JbmZvIHJvYW1JbmZvOwogICAgdENzclJvYW1TZXNzaW9uICpwU2Vzc2lvbiA9ICZwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF07CiNlbmRpZgogICAgdHBGVFJvYW1DYWxsYmFja1VzckN0eCAgcFVzckN0eDsKCiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9FU0UpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgIGludCAgaW5pdF9mdF9mbGFnID0gRkFMU0U7CiNlbmRpZgogICAgLy8gaWYgc2Vzc2lvbiBpZCBpbnZhbGlkIHRoZW4gd2UgbmVlZCByZXR1cm4gZmFpbHVyZQogICAgaWYgKE5VTEwgPT0gcE5laWdoYm9yUm9hbUluZm8gfHwgIUNTUl9JU19TRVNTSU9OX1ZBTElEKHBNYWMsIHNlc3Npb25JZCkgfHwKICAgICAgICAoTlVMTCA9PSBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0ucEN1clJvYW1Qcm9maWxlKSkKICAgIHsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KCiAgICAgc21zTG9nKHBNYWMsIExPRzIsCiAgICAgICAgICAgIEZMKCJDb25uZWN0IGluZGljYXRpb24gcmVjZWl2ZWQgd2l0aCBzZXNzaW9uIGlkICVkIgogICAgICAgICAgICAiaW4gc3RhdGUgJXMiKSwKICAgICAgICAgICAgc2Vzc2lvbklkLCBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CgoKICAgIC8vIEJhaWwgb3V0IGlmIHRoaXMgaXMgTk9UIGEgU1RBIHBlcnNvbmEKICAgIGlmIChwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0ucEN1clJvYW1Qcm9maWxlLT5jc3JQZXJzb25hICE9IFZPU19TVEFfTU9ERSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIklnbm9yaW5nIENvbm5lY3QgaW5kaWNhdGlvbiByZWNlaXZlZCBmcm9tIGEgbm9uIFNUQSBwZXJzb25hLiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNlc3Npb25JZDogJWQsIGNzclBlcnNvbm5hICVkIiksCiAgICAgICAgICAgICAgIHNlc3Npb25JZCwKICAgICAgICAgICAgICAgKGludClwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0ucEN1clJvYW1Qcm9maWxlLT5jc3JQZXJzb25hKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICAvLyBpZiBhIGNvbmN1cnJlbnQgc2Vzc2lvbiBpcyBydW5uaW5nCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIGlmIChlQU5JX0JPT0xFQU5fRkFMU0UgPT0gQ1NSX0lTX0ZBU1RST0FNX0lOX0NPTkNVUlJFTkNZX0lOSV9GRUFUVVJFX0VOQUJMRUQocE1hYykpCiAgICB7CiNlbmRpZgogICAgICAgIGlmIChjc3JJc0NvbmN1cnJlbnRTZXNzaW9uUnVubmluZyhwTWFjKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiSWdub3JpbmcgQ29ubmVjdCBpbmRpY2F0aW9uIHJlY2VpdmVkIGluIG11bHRpc2Vzc2lvbiAlZCIpLAogICAgICAgICAgICAgICAgICBjc3JJc0NvbmN1cnJlbnRTZXNzaW9uUnVubmluZyhwTWFjKSk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgfQojZW5kaWYKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX09GRkxPQUQKICAgIGlmIChwU2Vzc2lvbi0+cm9hbU9mZmxvYWRTeW5jaFBhcmFtcy5iUm9hbVN5bmNoSW5Qcm9ncmVzcyAmJgogICAgICAgKGVTSVJfUk9BTV9BVVRIX1NUQVRVU19BVVRIRU5USUNBVEVEID09CiAgICAgICAgcFNlc3Npb24tPnJvYW1PZmZsb2FkU3luY2hQYXJhbXMuYXV0aFN0YXR1cykpCiAgICB7CiAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfREVCVUcsCiAgICAgICAgICAgICAgICAgICJMRlIzOmNzck5laWdoYm9yUm9hbUluZGljYXRlQ29ubmVjdCIpOwojaWZkZWYgV0xBTl9BQ1RJVkVNT0RFX09GRkxPQURfRkVBVFVSRQogICAgICAgIGlmKElTX0FDVElWRU1PREVfT0ZGTE9BRF9GRUFUVVJFX0VOQUJMRSkKICAgICAgICB7CiAgICAgICAgICAgdHBTaXJTZXRBY3RpdmVNb2RlU2V0Qm5jRmlsdGVyUmVxIHBNc2c7CiAgICAgICAgICAgcE1zZyA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0U2lyU2V0QWN0aXZlTW9kZVNldEJuY0ZpbHRlclJlcSkpOwogICAgICAgICAgIGlmIChwTXNnID09IE5VTEwpCiAgICAgICAgICAgewogICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICJMRlIzOk1lbSBBbGxvYyBmYWlsZWQgZm9yIHRTaXJTZXRBY3RpdmVNb2RlU2V0Qm5jRmlsdGVyUmVxIik7CiAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgIH0KICAgICAgICAgICBwTXNnLT5tZXNzYWdlVHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgIHBhbF9jcHVfdG9fYmUxNigodEFOSV9VMTYpZVdOSV9TTUVfU0VUX0JDTl9GSUxURVJfUkVRKTsKICAgICAgICAgICBwTXNnLT5sZW5ndGggPSBwYWxfY3B1X3RvX2JlMTYoc2l6ZW9mKAogICAgICAgICAgICAgICB0U2lyU2V0QWN0aXZlTW9kZVNldEJuY0ZpbHRlclJlcSkpOwogICAgICAgICAgIHBNc2ctPnNlZXNpb25JZCA9IHNlc3Npb25JZDsKICAgICAgICAgICB2b3NfbWVtX2NvcHkocE1zZy0+YnNzaWQsCiAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLmJzc2lkLAogICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICAgICBzdGF0dXMgPSBwYWxTZW5kTUJNZXNzYWdlKHBNYWMtPmhIZGQsIHBNc2cgKTsKICAgICAgICB9CiNlbmRpZgogICAgICAgIHZvc19tZW1fY29weSgmcm9hbUluZm8ucGVlck1hYywKICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLmJzc2lkLDYpOwogICAgICAgIHJvYW1JbmZvLnJvYW1TeW5jaEluUHJvZ3Jlc3MgPQogICAgICAgICAgICAgICAgICAgcFNlc3Npb24tPnJvYW1PZmZsb2FkU3luY2hQYXJhbXMuYlJvYW1TeW5jaEluUHJvZ3Jlc3M7CiAgICAgICAgY3NyUm9hbUNhbGxDYWxsYmFjayhwTWFjLCBzZXNzaW9uSWQsICZyb2FtSW5mbywgMCwKICAgICAgICAgICAgICAgICAgIGVDU1JfUk9BTV9TRVRfS0VZX0NPTVBMRVRFLCBlQ1NSX1JPQU1fUkVTVUxUX0FVVEhFTlRJQ0FURUQpOwogICAgfQojZW5kaWYKCiAgICBzd2l0Y2ggKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRUFTU09DSUFUSU5HOgogICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogSnVzdCB0cmFuc2l0aW9uIHRoZSBzdGF0ZSB0byBJTklUIHN0YXRlLiBSZXN0IG9mIHRoZSBjbGVhbiB1cCBoYXBwZW5zIHdoZW4gd2UgZ2V0IG5leHQgY29ubmVjdCBpbmRpY2F0aW9uICovCiAgICAgICAgICAgICAgICBjc3JfbmVpZ2hib3Jfcm9hbV9zdGF0ZV90cmFuc2l0aW9uKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkKTsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiNlbmRpZgogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogRmFsbCB0aHJvdWdoIGlmIHRoZSBzdGF0dXMgaXMgU1VDQ0VTUyAqLwogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQ6CiAgICAgICAgICAgIC8qIFJlc2V0IGFsbCB0aGUgZGF0YSBzdHJ1Y3R1cmVzIGhlcmUgKi8KICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRJbml0U3RhdGVDb250cm9sSW5mbyhwTWFjLCBzZXNzaW9uSWQpOwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogSW5pdGlhbGl6ZSB0aGUgb2NjdXBpZWQgbGlzdCBPTkxZIGlmIHdlIGFyZQogICAgICAgICAgICAgKiB0cmFuc2l0aW9uaW5nIGZyb20gSU5JVCBzdGF0ZSB0byBDT05ORUNURUQgc3RhdGUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgICAgICAgICAgY3NySW5pdE9jY3VwaWVkQ2hhbm5lbHNMaXN0KHBNYWMsIHNlc3Npb25JZCk7CiNlbmRpZgogICAgICAgICAgICBjc3JfbmVpZ2hib3Jfcm9hbV9zdGF0ZV90cmFuc2l0aW9uKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCk7CgogICAgICAgICAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUGJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5ic3NpZCwgc2l6ZW9mKHRDc3JCc3NpZCkpOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VyckFQb3BlcmF0aW9uQ2hhbm5lbCA9IHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLm9wZXJhdGlvbkNoYW5uZWw7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lckluZm8ucE1hYyA9IHBNYWM7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lckluZm8uc2Vzc2lvbklkID0gc2Vzc2lvbklkOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0KICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQ7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50T3Bwb3J0dW5pc3RpY1RocmVzaG9sZERpZmYgPQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uT3Bwb3J0dW5pc3RpY1RocmVzaG9sZERpZmY7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50Um9hbVJlc2NhblJzc2lEaWZmID0KICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMublJvYW1SZXNjYW5Sc3NpRGlmZjsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnRSb2FtQm1pc3NGaXJzdEJjbnQgPQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uUm9hbUJtaXNzRmlyc3RCY250OwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudFJvYW1CbWlzc0ZpbmFsQmNudCA9CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5Sb2FtQm1pc3NGaW5hbEJjbnQ7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50Um9hbUJlYWNvblJzc2lXZWlnaHQgPQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uUm9hbUJlYWNvblJzc2lXZWlnaHQ7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSAwOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID0gREVGQVVMVF9TQ0FOOwojZW5kaWYKCgojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICAgICAgICAgIC8qIE5vdyB3ZSBjYW4gY2xlYXIgdGhlIHByZWF1dGhEb25lIHRoYXQgd2FzIHNhdmVkIGFzIHdlIGFyZSBjb25uZWN0ZWQgYWZyZXNoICovCiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUZyZWVSb2FtYWJsZUJTU0xpc3QocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0KTsKI2VuZGlmCgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgICAgICAgICAgLy8gQmFzZWQgb24gdGhlIGF1dGggc2NoZW1lIHRlbGwgaWYgd2UgYXJlIDExcgogICAgICAgICAgICBpZiAoIGNzcklzQXV0aFR5cGUxMXIoIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLkF1dGhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLk1ESUQubWRpZVByZXNlbnQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc0Zhc3RUcmFuc2l0aW9uRW5hYmxlZCkKICAgICAgICAgICAgICAgICAgICBpbml0X2Z0X2ZsYWcgPSBUUlVFOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiMTFyQXNzb2MgaXMgPSAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYyk7CiNlbmRpZgoKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgICAgICAgICAgLy8gQmFzZWQgb24gdGhlIGF1dGggc2NoZW1lIHRlbGwgaWYgd2UgYXJlIDExcgogICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuaXNFU0VBc3NvYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNGYXN0VHJhbnNpdGlvbkVuYWJsZWQpCiAgICAgICAgICAgICAgICAgICAgaW5pdF9mdF9mbGFnID0gVFJVRTsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoImlzRVNFQXNzb2MgaXMgPSAlZCBmdCA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MsIGluaXRfZnRfZmxhZyk7CgojZW5kaWYKCiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLnBlbmRpbmdfcm9hbV9kaXNhYmxlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoInByb2Nlc3MgcGVuZGluZyByb2FtIGRpc2FibGUiKSk7CiAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzRmFzdFJvYW1JbmlGZWF0dXJlRW5hYmxlZCA9IEZBTFNFOwogICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5wZW5kaW5nX3JvYW1fZGlzYWJsZSA9IEZBTFNFOwogICAgICAgICAgICB9CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAvLyBJZiAiTGVnYWN5IEZhc3QgUm9hbWluZyIgaXMgZW5hYmxlZAogICAgICAgICAgICBpZiAoY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsIHNlc3Npb25JZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGluaXRfZnRfZmxhZyA9IFRSVUU7CiAgICAgICAgICAgIH0KI2VuZGlmCgojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICAgICAgICAgIGlmICggaW5pdF9mdF9mbGFnID09IFRSVUUgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBJbml0aWFsaXplIGFsbCB0aGUgZGF0YSBzdHJ1Y3R1cmVzIG5lZWRlZCBmb3IgdGhlIDExciBGVCBQcmVhdXRoICovCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1QdXJnZVByZWF1dGhGYWlsZWRMaXN0KHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgaWYgKCF2b3NfaXNfbXVsdGlwbGVfYWN0aXZlX3N0YV9zZXNzaW9ucygpICYmCiAgICAgICAgICAgICAgICAgIGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIC8qSWYgdGhpcyBpcyBub3QgYSBJTkZSQSB0eXBlIEJTUywgdGhlbiBkbyBub3Qgc2VuZCB0aGUgY29tbWFuZAogICAgICAgICAgICAgICAgICAqIGRvd24gdG8gZmlybXdhcmUuRG8gbm90IHNlbmQgdGhlIFNUQVJUIGNvbW1hbmQgZm9yIG90aGVyIHNlc3Npb24KICAgICAgICAgICAgICAgICAgKiBjb25uZWN0aW9ucy4qLwogICAgICAgICAgICAgICAgIGlmKGNzclJvYW1Jc1N0YU1vZGUocE1hYywgc2Vzc2lvbklkKSkKICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX09GRkxPQUQKICAgICAgICAgICAgICAgICAgICAgaWYgKHBTZXNzaW9uLT5yb2FtT2ZmbG9hZFN5bmNoUGFyYW1zLmJSb2FtU3luY2hJblByb2dyZXNzKQogICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5wUmVhc3NvY1Jlc3AgIT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9ERUJVRywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGcmVlIFJlYXNzb2MgUnNwIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBNYWMtPnJvYW0ucFJlYXNzb2NSZXNwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLnBSZWFzc29jUmVzcCA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9ERUJVRywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMRlIzOlNlbmQgU3luY2hDbmYgYXV0aCBzdGF0dXMgYXV0aGVudGljYXRlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTZW5kU3luY2hDbmYoIHBNYWMsIHNlc3Npb25JZCk7CiAgICAgICAgICAgICAgICAgICAgIH0gZWxzZQojZW5kaWYKICAgICAgICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVBU09OX0NPTk5FQ1QpOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgIEZMKCJSZWdpc3RlcmluZyBuZWlnaGJvciBsb29rdXAgRE9XTiBldmVudCB3aXRoIFRMLCBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQpOwoKICAgICAgICAgICAgICAgIC8qIFRoaXMgdXNlciBjb250ZXh0IGRhdGEgd2lsbCBiZSByZXR1cm5lZCB3aXRoIGNhbGxiYWNrICovCiAgICAgICAgICAgICAgICBwVXNyQ3R4ID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKCpwVXNyQ3R4KSk7CiAgICAgICAgICAgICAgICBpZiAoTlVMTCA9PSBwVXNyQ3R4KSB7CiAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZhaWx1cmUiKSk7CiAgICAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX05PTUVNOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcFVzckN0eC0+cE1hYyA9IHBNYWM7CiAgICAgICAgICAgICAgICBwVXNyQ3R4LT5zZXNzaW9uSWQgPSBzZXNzaW9uSWQ7CgogICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmVnaXN0ZXJpbmcgbmVpZ2hib3IgbG9va3VwIERPV04gZXZlbnQgd2l0aCBUTCwgUlNTSSA9ICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQpOwogICAgICAgICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBET1dOIGV2ZW50IG9ubHkgKi8KICAgICAgICAgICAgICAgIHZzdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcFVzckN0eCk7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwojZW5kaWYKICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwVXNyQ3R4KTsKICAgICAgICAgICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1ModnN0YXR1cykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZzdGF0dXMpOwogICAgICAgICAgICAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAgIH0KI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRCAqLwogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwKICAgICAgICAgICAgICAgICAgIEZMKCJDb25uZWN0IGV2ZW50IHJlY2VpdmVkIGluIGludmFsaWQgc3RhdGUgJXMiCiAgICAgICAgICAgICAgICAgICAiLi5JZ25vcmluZy4uLiIpLAogICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gc3RhdHVzOwp9CgoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1QdXJnZVByZWF1dGhGYWlsZWRMaXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHB1cmdlcyBhbGwgdGhlIE1BQyBhZGRyZXNzZXMgaW4gdGhlIHByZS1hdXRoIGZhaWwgbGlzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbGVkTGlzdCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0QU5JX1U4IGksIGo7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICBwTmVpZ2hib3JSb2FtSW5mbyA9IE5VTEw7CgogICAgZm9yIChqID0gMDsgaiA8IENTUl9ST0FNX1NFU1NJT05fTUFYOyBqKyspIHsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bal07CiAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgIGkgPCBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzczsKICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICB2b3NfbWVtX3plcm8ocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm1hY0FkZHJlc3NbaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICB9CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MgPSAwOwogICAgfQp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSW5pdDExckFzc29jSW5mbwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpbml0aWFsaXplcyAxMXIgcmVsYXRlZCBuZWlnaGJvciByb2FtIGRhdGEgc3RydWN0dXJlcwoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Jbml0MTFyQXNzb2NJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIGVIYWxTdGF0dXMgIHN0YXR1czsKICAgIHRBTklfVTggaTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gIHBOZWlnaGJvclJvYW1JbmZvID0gTlVMTDsKICAgIHRwQ3NyMTFyQXNzb2NOZWlnaGJvckluZm8gICBwRlRSb2FtSW5mbyA9IE5VTEw7CgogICAgZm9yIChpID0gMDsgaSA8IENTUl9ST0FNX1NFU1NJT05fTUFYOyBpKyspIHsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9baV07CiAgICAgICAgcEZUUm9hbUluZm8gPSAmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm87CgogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWF4TmVpZ2hib3JSZXRyaWVzID0KICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk1heE5laWdoYm9yUmV0cmllczsKCiAgICAgICAgcEZUUm9hbUluZm8tPm5laWdoYm9yUmVwb3J0VGltZW91dCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fUkVQT1JUX1FVRVJZX1RJTUVPVVQ7CiAgICAgICAgcEZUUm9hbUluZm8tPlBFUHJlYXV0aFJlc3BUaW1lb3V0ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9QUkVBVVRIX1JTUF9XQUlUX01VTFRJUExJRVIgKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JTY2FuUGVyaW9kOwogICAgICAgIHBGVFJvYW1JbmZvLT5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgcEZUUm9hbUluZm8tPnByZWF1dGhSc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgICAgICBwRlRSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgICAgIHBGVFJvYW1JbmZvLT5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPSAwOwoKICAgICAgICB2b3NfbWVtX3plcm8ocEZUUm9hbUluZm8tPm5laWdoYm9SZXBvcnRCc3NJbmZvLAogICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRDc3JOZWlnaGJvclJlcG9ydEJzc0luZm8pICogTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOwoKICAgICAgICBzdGF0dXMgPSBjc3JMTE9wZW4ocE1hYy0+aEhkZCwgJnBGVFJvYW1JbmZvLT5wcmVBdXRoRG9uZUxpc3QpOwogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkxMIE9wZW4gb2YgcHJlYXV0aCBkb25lIEFQIExpc3QgZmFpbGVkIikpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBzdGF0dXM7Cn0KI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSW5pdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpbml0aWFsaXplcyBuZWlnaGJvciByb2FtIGRhdGEgc3RydWN0dXJlcwoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Jbml0KHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICBlSGFsU3RhdHVzIHN0YXR1czsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSAgICAgICA9ICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NMT1NFRDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5wcmV2TmVpZ2hib3JSb2FtU3RhdGUgICA9ICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NMT1NFRDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWF4Q2hhbm5lbFNjYW5UaW1lID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yU2Nhbk1heENoYW5UaW1lOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5taW5DaGFubmVsU2NhblRpbWUgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JTY2FuTWluQ2hhblRpbWU7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1heE5laWdoYm9yUmV0cmllcyA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yTG9va3VwUnNzaVRocmVzaG9sZDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuZGVsYXlfYmVmb3JlX3ZkZXZfc3RvcCA9CiAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcuZGVsYXlfYmVmb3JlX3ZkZXZfc3RvcDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubk9wcG9ydHVuaXN0aWNUaHJlc2hvbGREaWZmID0KICAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uT3Bwb3J0dW5pc3RpY1RocmVzaG9sZERpZmY7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5Sb2FtUmVzY2FuUnNzaURpZmYgPQogICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5Sb2FtUmVzY2FuUnNzaURpZmY7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5Sb2FtQm1pc3NGaXJzdEJjbnQgPQogICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5Sb2FtQm1pc3NGaXJzdEJjbnQ7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5Sb2FtQm1pc3NGaW5hbEJjbnQgPQogICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5Sb2FtQm1pc3NGaW5hbEJjbnQ7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5Sb2FtQmVhY29uUnNzaVdlaWdodCA9CiAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcublJvYW1CZWFjb25Sc3NpV2VpZ2h0OwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JSZWFzc29jUnNzaVRocmVzaG9sZDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JTY2FuUGVyaW9kID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yU2NhblRpbWVyUGVyaW9kOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlc3VsdHNSZWZyZXNoUGVyaW9kID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2Q7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmVtcHR5U2NhblJlZnJlc2hQZXJpb2QgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uRW1wdHlTY2FuUmVmcmVzaFBlcmlvZDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyAgID0KICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubmVpZ2hib3JTY2FuQ2hhbkxpc3QubnVtQ2hhbm5lbHM7CiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5udW1PZkNoYW5uZWxzICE9IDApIHsKCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9CiAgICAgICAgICAgICAgICB2b3NfbWVtX21hbGxvYyhwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uZWlnaGJvclNjYW5DaGFuTGlzdC5udW1DaGFubmVscyk7CiAgICAgICAgaWYgKE5VTEwgPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCkgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBBbGxvY2F0aW9uIGZvciBDRkcgQ2hhbm5lbCBMaXN0IGZhaWxlZCIpKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgICAgICB9CiAgICAgICAgLyogVXBkYXRlIHRoZSByb2FtIGdsb2JhbCBzdHJ1Y3R1cmUgZnJvbSBDRkcgKi8KICAgICAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubmVpZ2hib3JTY2FuQ2hhbkxpc3QuY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5laWdoYm9yU2NhbkNoYW5MaXN0Lm51bUNoYW5uZWxzKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiaW52YWxpZCBuZWlnaGJvciByb2FtIGNoYW5uZWwgbGlzdDogJXUiKSwKICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5udW1PZkNoYW5uZWxzKTsKICAgIH0KICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuaGlfcnNzaV9zY2FuX21heF9jb3VudCA9CiAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5oaV9yc3NpX3NjYW5fbWF4X2NvdW50OwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5oaV9yc3NpX3NjYW5fcnNzaV9kZWx0YSA9CiAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5oaV9yc3NpX3NjYW5fcnNzaV9kZWx0YTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuaGlfcnNzaV9zY2FuX2RlbGF5ID0KICAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubmhpX3Jzc2lfc2Nhbl9kZWxheTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuaGlfcnNzaV9zY2FuX3Jzc2lfdWIgPQogICAgICAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uaGlfcnNzaV9zY2FuX3Jzc2lfdWI7CgogICAgdm9zX21lbV9zZXQocE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUGJzc2lkLCBzaXplb2YodENzckJzc2lkKSwgMCk7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50T3Bwb3J0dW5pc3RpY1RocmVzaG9sZERpZmYgPQogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubk9wcG9ydHVuaXN0aWNUaHJlc2hvbGREaWZmOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnRSb2FtUmVzY2FuUnNzaURpZmYgPQogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMublJvYW1SZXNjYW5Sc3NpRGlmZjsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50Um9hbUJtaXNzRmlyc3RCY250ID0KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5Sb2FtQm1pc3NGaXJzdEJjbnQ7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudFJvYW1CbWlzc0ZpbmFsQmNudCA9CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uUm9hbUJtaXNzRmluYWxCY250OwogICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnRSb2FtQmVhY29uUnNzaVdlaWdodCA9CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uUm9hbUJlYWNvblJzc2lXZWlnaHQ7CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSA9IERFRkFVTFRfU0NBTjsKICAgIHZvc19tZW1fc2V0KCZwTmVpZ2hib3JSb2FtSW5mby0+cHJldkNvbm5Qcm9maWxlLCBzaXplb2YodENzclJvYW1Db25uZWN0ZWRQcm9maWxlKSwgMCk7CiNlbmRpZgogICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lckluZm8ucE1hYyA9IHBNYWM7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXJJbmZvLnNlc3Npb25JZCA9IENTUl9TRVNTSU9OX0lEX0lOVkFMSUQ7CiAgICBzdGF0dXMgPSB2b3NfdGltZXJfaW5pdCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyLCBWT1NfVElNRVJfVFlQRV9TVywKICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvclNjYW5UaW1lckNhbGxiYWNrLCAodm9pZCAqKSZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXJJbmZvKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIHRpbWVyIGFsbG9jYXRpb24gZmFpbGVkIikpOwogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHN0YXR1cyA9IHZvc190aW1lcl9pbml0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyLCBWT1NfVElNRVJfVFlQRV9TVywKICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXN1bHRzUmVmcmVzaFRpbWVyQ2FsbGJhY2ssICh2b2lkICopJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lckluZm8pOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lciBhbGxvY2F0aW9uIGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgIH0KCiAgICBzdGF0dXMgPSB2b3NfdGltZXJfaW5pdCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lciwgVk9TX1RJTUVSX1RZUEVfU1csCiAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1FbXB0eVNjYW5SZWZyZXNoVGltZXJDYWxsYmFjaywKICAgICAgICAgICAgICAgICh2b2lkICopJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lckluZm8pOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciBhbGxvY2F0aW9uIGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICB9CgogICAgc3RhdHVzID0gY3NyTExPcGVuKHBNYWMtPmhIZGQsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTEwgT3BlbiBvZiByb2FtIGFibGUgQVAgTGlzdCBmYWlsZWQiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgIH0KCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPSBDU1JfTkVJR0hCT1JfUk9BTV9JTlZBTElEX0NIQU5ORUxfSU5ERVg7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jaGFuTGlzdFNjYW5JblByb2dyZXNzID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUluaXQxMXJBc3NvY0luZm8ocE1hYyk7CiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJMTCBPcGVuIG9mIHJvYW0gYWJsZSBBUCBMaXN0IGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAgICBjc3JMTENsb3NlKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICB9CiNlbmRpZgogICAgLyogSW5pdGlhbGl6ZSB0aGlzIHdpdGggdGhlIGN1cnJlbnQgdGljayBjb3VudCAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5SZXF1ZXN0VGltZVN0YW1wID0gdm9zX3RpbWVyX2dldF9zeXN0ZW1fdGltZSgpOwoKICAgIGNzcl9uZWlnaGJvcl9yb2FtX3N0YXRlX3RyYW5zaXRpb24ocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCk7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIC8qIFNldCB0aGUgTGFzdCBTZW50IENtZCBhcyBSU09fU1RPUCAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPmxhc3RTZW50Q21kID0gUk9BTV9TQ0FOX09GRkxPQURfU1RPUDsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwojZW5kaWYKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtQ2xvc2UKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gY2xvc2VzL2ZyZWVzIGFsbCB0aGUgbmVpZ2hib3Igcm9hbSBkYXRhIHN0cnVjdHVyZXMKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHNlc3Npb25JZCAtIFNlc3Npb24gaWRlbnRpZmllcgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbUNsb3NlKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NMT1NFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJOZWlnaGJvciBSb2FtIEFsZ29yaXRobSBBbHJlYWR5IENsb3NlZCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lckluZm8ucE1hYyA9IE5VTEw7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXJJbmZvLnNlc3Npb25JZCA9IENTUl9TRVNTSU9OX0lEX0lOVkFMSUQ7CiAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKCiAgICAvKiBTaG91bGQgZnJlZSB1cCB0aGUgbm9kZXMgaW4gdGhlIGxpc3QgYmVmb3JlIGNsb3NpbmcgdGhlIGRvdWJsZSBMaW5rZWQgbGlzdCAqLwogICAgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdChwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsKICAgIGNzckxMQ2xvc2UoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCkKICAgIHsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgIH0KCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4ID0gQ1NSX05FSUdIQk9SX1JPQU1fSU5WQUxJRF9DSEFOTkVMX0lOREVYOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY2hhbkxpc3RTY2FuSW5Qcm9ncmVzcyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIC8qIEZyZWUgdGhlIHByb2ZpbGUuLiAqLwogICAgY3NyUmVsZWFzZVByb2ZpbGUocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5jc3JOZWlnaGJvclJvYW1Qcm9maWxlKTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIGNzclJvYW1GcmVlQ29ubmVjdFByb2ZpbGUocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5wcmV2Q29ublByb2ZpbGUpOwojZW5kaWYKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPSAwOwogICAgdm9zX21lbV96ZXJvKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvLAogICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRDc3JOZWlnaGJvclJlcG9ydEJzc0luZm8pICogTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOwogICAgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdChwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpOwogICAgY3NyTExDbG9zZSgmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0KTsKI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgogICAgY3NyX25laWdoYm9yX3JvYW1fc3RhdGVfdHJhbnNpdGlvbihwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0xPU0VELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQpOwoKICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVJlcXVlc3RIYW5kb2ZmCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHRyaWdnZXJzIGFjdHVhbCBzd2l0Y2hpbmcgZnJvbSBvbmUgQVAgdG8gdGhlIG5ldyBBUC4KICAgICAgICAgICAgSXQgaXNzdWVzIGRpc2Fzc29jaWF0ZSB3aXRoIHJlYXNvbiBjb2RlIGFzIEhhbmRvZmYgYW5kIENTUiBhcyBhCiAgICAgICAgICAgIHBhcnQgb2YgaGFuZGxpbmcgZGlzYXNzb2MgcnNwLCBpc3N1ZXMgcmVhc3NvY2lhdGUgdG8gdGhlIG5ldyBBUAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUmVxdWVzdEhhbmRvZmYodHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VOCBzZXNzaW9uSWQpCnsKICAgIHRDc3JSb2FtSW5mbyByb2FtSW5mbzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CiAgICB0Q3NyTmVpZ2hib3JSb2FtQlNTSW5mbyAgICAgIGhhbmRvZmZOb2RlOwoKICAgIGV4dGVybiB2b2lkIGNzclJvYW1Sb2FtaW5nU3RhdGVEaXNhc3NvY1JzcFByb2Nlc3NvciggdHBBbmlTaXJHbG9iYWwgcE1hYywgdFNpclNtZURpc2Fzc29jUnNwICpwU21lRGlzYXNzb2NSc3AgKTsKICAgIHRBTklfVTMyIHJvYW1JZCA9IDA7CiAgICBlSGFsU3RhdHVzIHN0YXR1czsKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSX01FVFJJQ1MKICAgIHRDc3JSb2FtSW5mbyAqcm9hbUluZm9NZXRyaWNzOwojZW5kaWYKICAgIFZPU19UUkFDRShWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0RFQlVHLCIlcyBzZXNzaW9uSWQ9JWQiLAogICAgICAgICAgICAgIF9fZnVuY19fLCBzZXNzaW9uSWQpOwoKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUgIT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSF9ET05FKSB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgIEZMKCJSb2FtIHJlcXVlc3RlZCB3aGVuIE5laWdoYm9yIHJvYW0gaXMgaW4gJXMgc3RhdGUiKSwKICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChlQU5JX0JPT0xFQU5fRkFMU0UgPT0KICAgICAgICBjc3JOZWlnaGJvclJvYW1HZXRIYW5kb2ZmQVBJbmZvKHBNYWMsICZoYW5kb2ZmTm9kZSwgc2Vzc2lvbklkKSkgewogICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAgICAgIEZMKCJmYWlsZWQgdG8gb2J0YWluIGhhbmRvZmYgQVAiKSk7CiAgICAgICAgIHJldHVybjsKICAgIH0KICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9ERUJVRywKICAgICAgICAgICAgICAgRkwoIkhBTkRPRkYgQ0FORElEQVRFIEJTU0lEICJNQUNfQUREUkVTU19TVFIpLAogICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShoYW5kb2ZmTm9kZS5wQnNzRGVzY3JpcHRpb24tPmJzc0lkKSk7CgogICAgdm9zX21lbV96ZXJvKCZyb2FtSW5mbywgc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgY3NyUm9hbUNhbGxDYWxsYmFjayhwTWFjLCBzZXNzaW9uSWQsICZyb2FtSW5mbywgcm9hbUlkLCBlQ1NSX1JPQU1fRlRfU1RBUlQsCiAgICAgICAgICAgICAgICAgICAgICAgIGVTSVJfU01FX1NVQ0NFU1MpOwoKICAgIHZvc19tZW1femVybygmcm9hbUluZm8sIHNpemVvZih0Q3NyUm9hbUluZm8pKTsKICAgIGNzcl9uZWlnaGJvcl9yb2FtX3N0YXRlX3RyYW5zaXRpb24ocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFQVNTT0NJQVRJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCk7CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICAvKiBMRlIgbWV0cmljcyAtIHByZS1hdXRoIGNvbXBsZXRpb24gbWV0cmljLgogICAgICAgU2VuZCB0aGUgZXZlbnQgdG8gc3VwcGxpY2FudCB0aGF0IHByZS1hdXRoIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgKi8KICAgIHJvYW1JbmZvTWV0cmljcyA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyUm9hbUluZm8pKTsKICAgIGlmIChOVUxMID09IHJvYW1JbmZvTWV0cmljcykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZCEiKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgdm9zX21lbV9jb3B5KCh2b2lkICopcm9hbUluZm9NZXRyaWNzLT5ic3NpZCwKICAgICAgICAgICAgKHZvaWQgKikmaGFuZG9mZk5vZGUucEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwgc2l6ZW9mKHRDc3JCc3NpZCkpOwogICAgICAgIGNzclJvYW1DYWxsQ2FsbGJhY2socE1hYywgc2Vzc2lvbklkLCByb2FtSW5mb01ldHJpY3MsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX1JPQU1fSEFORE9WRVJfU1VDQ0VTUywgMCk7CiAgICAgICAgdm9zX21lbV9mcmVlKHJvYW1JbmZvTWV0cmljcyk7CiAgICB9CiNlbmRpZgoKICAgIC8qIEZyZWUgdGhlIHByb2ZpbGUuLiBKdXN0IHRvIG1ha2Ugc3VyZSB3ZSBkb250IGxlYWsgbWVtb3J5IGhlcmUgKi8KICAgIGNzclJlbGVhc2VQcm9maWxlKHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+Y3NyTmVpZ2hib3JSb2FtUHJvZmlsZSk7CiAgICAvKgogICAgICogQ3JlYXRlIHRoZSBIYW5kb2ZmIEFQIHByb2ZpbGUuIENvcHkgdGhlIGN1cnJlbnRseSBjb25uZWN0ZWQgcHJvZmlsZSBhbmQKICAgICAqIHVwZGF0ZSBvbmx5IHRoZSBCU1NJRCBhbmQgY2hhbm5lbCBudW1iZXIuIFRoaXMgc2hvdWxkIGhhcHBlbiBiZWZvcmUKICAgICAqIGlzc3VpbmcgZGlzY29ubmVjdC4KICAgICAqLwogICAgc3RhdHVzID0gY3NyUm9hbUNvcHlDb25uZWN0ZWRQcm9maWxlKHBNYWMsIHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE5laWdoYm9yUm9hbUluZm8tPmNzck5laWdoYm9yUm9hbVByb2ZpbGUpOwogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKSB7CiAgICAgICAgVk9TX1RSQUNFKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgIEZMKCJjc3JSb2FtQ29weUNvbm5lY3RlZFByb2ZpbGUgcmV0dXJuZWQgZmFpbGVkICVkIiksIHN0YXR1cyk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5jc3JOZWlnaGJvclJvYW1Qcm9maWxlLkJTU0lEcy5ic3NpZCwgaGFuZG9mZk5vZGUucEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyTmVpZ2hib3JSb2FtUHJvZmlsZS5DaGFubmVsSW5mby5DaGFubmVsTGlzdFswXSA9IGhhbmRvZmZOb2RlLnBCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbElkOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgIiBjc3JSb2FtSGFuZG9mZlJlcXVlc3RlZDogZGlzYXNzb2NpYXRpbmcgd2l0aCBjdXJyZW50IEFQIik7CgogICAgaWYoIUhBTF9TVEFUVVNfU1VDQ0VTUyhjc3JSb2FtSXNzdWVEaXNhc3NvY2lhdGVDbWQocE1hYywgc2Vzc2lvbklkLCBlQ1NSX0RJU0NPTk5FQ1RfUkVBU09OX0hBTkRPRkYpKSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgImNzclJvYW1IYW5kb2ZmUmVxdWVzdGVkOiAgZmFpbCB0byBpc3N1ZSBkaXNhc3NvY2lhdGUiKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLyogTm90aWZ5IEhERCBmb3IgaGFuZG9mZiwgcHJvdmlkaW5nIHRoZSBCU1NJRCB0b28gKi8KICAgIHJvYW1JbmZvLnJlYXNvbkNvZGUgPSBlQ3NyUm9hbVJlYXNvbkJldHRlckFQOwoKICAgIHZvc19tZW1fY29weShyb2FtSW5mby5ic3NpZCwKICAgICAgICAgICAgICAgICBoYW5kb2ZmTm9kZS5wQnNzRGVzY3JpcHRpb24tPmJzc0lkLAogICAgICAgICAgICAgICAgIHNpemVvZiggdENzckJzc2lkICkpOwoKICAgIGNzclJvYW1DYWxsQ2FsbGJhY2socE1hYywgc2Vzc2lvbklkLCAmcm9hbUluZm8sIDAsCiAgICAgICAgICAgICAgICAgICAgICAgIGVDU1JfUk9BTV9ST0FNSU5HX1NUQVJULCBlQ1NSX1JPQU1fUkVTVUxUX05PTkUpOwoKICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUlzSGFuZG9mZkluUHJvZ3Jlc3MKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB3aGV0aGVyIGhhbmQtb2ZmIGlzIGluIHByb2dyZXNzIG9yIG5vdCBiYXNlZAogICAgICAgICAgICBvbiB0aGUgY3VycmVudCBuZWlnaGJvciByb2FtIHN0YXRlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBpczExclJlYXNzb2MgLSBSZXR1cm4gd2hldGhlciByZWFzc29jIGlzIG9mIHR5cGUgODAyLjExciByZWFzc29jCgogICAgXHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRSBpZiByZWFzc29jIGluIHByb2dyZXNzLCBlQU5JX0JPT0xFQU5fRkFMU0Ugb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JSb2FtSXNIYW5kb2ZmSW5Qcm9ncmVzcyh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRUFTU09DSUFUSU5HID09CiAgICAgICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF0ubmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgcmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFOwoKICAgIHJldHVybiBlQU5JX0JPT0xFQU5fRkFMU0U7Cn0KCiNpZiBkZWZpbmVkKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkKFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HKQovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXMxMXJBc3NvYwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHdoZXRoZXIgdGhlIGN1cnJlbnQgYXNzb2NpYXRpb24gaXMgYSAxMXIgYXNzb2Mgb3Igbm90CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUFOSV9CT09MRUFOX1RSVUUgaWYgY3VycmVudCBhc3NvYyBpcyAxMXIsIGVBTklfQk9PTEVBTl9GQUxTRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1JczExckFzc29jKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICByZXR1cm4gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF0uaXMxMXJBc3NvYzsKfQojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtR2V0SGFuZG9mZkFQSW5mbwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBiZXN0IHBvc3NpYmxlIEFQIGZvciBoYW5kb2ZmLgogICAgICAgICAgICBGb3IgMTFSIGNhc2UsIGl0IHJldHVybnMgdGhlIDFzdCBlbnRyeSBmcm9tIHByZS1hdXRoIGRvbmUgbGlzdC4KICAgICAgICAgICAgRm9yIG5vbi0xMXIgY2FzZSwgaXQgcmV0dXJucyB0aGUgMXN0IGVudHJ5IGZyb20gcm9hbSBhYmxlIEFQIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBIYW5kb2ZmTm9kZSAtIEFQIG5vZGUgdGhhdCBpcyB0aGUgaGFuZC1vZmYgY2FuZGlkYXRlIHJldHVybmVkCgogICAgXHJldHVybiB0cnVlIGlmIGFibGUgZmluZCBoYW5kb2ZmIEFQLCBmYWxzZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmJvb2wgY3NyTmVpZ2hib3JSb2FtR2V0SGFuZG9mZkFQSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBIYW5kb2ZmTm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyAgICAgICAgcEJzc05vZGUgPSBOVUxMOwoKICAgaWYgKE5VTEwgPT0gcEhhbmRvZmZOb2RlKQogICB7CiAgICAgIFZPU19BU1NFUlQoTlVMTCAhPSBwSGFuZG9mZk5vZGUpOwogICAgICByZXR1cm4gZmFsc2U7CiAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpCiAgICB7CiAgICAgICAgLyogQWx3YXlzIHRoZSBCU1MgaW5mbyBpbiB0aGUgaGVhZCBpcyB0aGUgaGFuZG9mZiBjYW5kaWRhdGUgKi8KICAgICAgICBwQnNzTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCwgTlVMTCk7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiTnVtYmVyIG9mIEhhbmRvZmYgY2FuZGlkYXRlcyA9ICVkIiksIGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCkpOwogICAgfQogICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYykKICAgIHsKICAgICAgICAvKiBBbHdheXMgdGhlIEJTUyBpbmZvIGluIHRoZSBoZWFkIGlzIHRoZSBoYW5kLW9mZiBjYW5kaWRhdGUgKi8KICAgICAgICBwQnNzTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QsIE5VTEwpOwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwKICAgICAgICAgICAgICAgICAgICBGTCgiTnVtYmVyIG9mIEhhbmRvZmYgY2FuZGlkYXRlcyA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgY3NyTExDb3VudCgmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0KSk7CiAgICB9CiAgICBlbHNlCiNlbmRpZgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgaWYgKGNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLCBzZXNzaW9uSWQpKQogICAgewogICAgICAgIC8qIEFsd2F5cyB0aGUgQlNTIGluZm8gaW4gdGhlIGhlYWQgaXMgdGhlIGhhbmQtb2ZmIGNhbmRpZGF0ZSAqLwogICAgICAgIHBCc3NOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCwgTlVMTCk7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLAogICAgICAgICAgICAgICAgICAgIEZMKCJOdW1iZXIgb2YgSGFuZG9mZiBjYW5kaWRhdGVzID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICBjc3JMTENvdW50KCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpKTsKICAgIH0KICAgIGVsc2UKI2VuZGlmCiAgICB7CiAgICAgICAgcEJzc05vZGUgPSBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0LCBOVUxMKTsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiTnVtYmVyIG9mIEhhbmRvZmYgY2FuZGlkYXRlcyA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JMTENvdW50KCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpKTsKICAgIH0KICAgIGlmIChOVUxMID09IHBCc3NOb2RlKQogICAgICAgcmV0dXJuIGZhbHNlOwogICAgdm9zX21lbV9jb3B5KHBIYW5kb2ZmTm9kZSwgcEJzc05vZGUsIHNpemVvZih0Q3NyTmVpZ2hib3JSb2FtQlNTSW5mbykpOwoKICAgIHJldHVybiB0cnVlOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIFRSVUUgaWYgcHJlYXV0aCBpcyBjb21wbGV0ZWQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBib29sZWFuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JSb2FtU3RhdGVQcmVhdXRoRG9uZSh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgcmV0dXJuIChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXS5uZWlnaGJvclJvYW1TdGF0ZSA9PQogICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSF9ET05FKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIEluIHRoZSBldmVudCB0aGF0IHdlIGFyZSBhc3NvY2lhdGVkIHdpdGggQVAxIGFuZCB3ZSBoYXZlCiAgICBjb21wbGV0ZWQgcHJlIGF1dGggd2l0aCBBUDIuIFRoZW4gd2UgcmVjZWl2ZSBhIGRlYXV0aC9kaXNhc3NvYyBmcm9tCiAgICBBUDEuCiAgICBBdCB0aGlzIHBvaW50IG5laWdoYm9yIHJvYW0gaXMgaW4gcHJlIGF1dGggZG9uZSBzdGF0ZSwgcHJlIGF1dGggdGltZXIKICAgIGlzIHJ1bm5pbmcuIFdlIG5vdyBoYW5kbGUgdGhpcyBjYXNlIGJ5IHN0b3BwaW5nIHRpbWVyIGFuZCBjbGVhcmluZwogICAgdGhlIHByZS1hdXRoIHN0YXRlLiBXZSBiYXNpY2FsbHkgY2xlYXIgdXAgYW5kIGp1c3QgZ28gdG8gZGlzY29ubmVjdGVkCiAgICBzdGF0ZS4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBib29sZWFuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtVHJhbmlzdGlvblByZWF1dGhEb25lVG9EaXNjb25uZWN0ZWQodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgdENzclJvYW1TZXNzaW9uICpwU2Vzc2lvbiA9IENTUl9HRVRfU0VTU0lPTihwTWFjLCBzZXNzaW9uSWQpOwoKICAgIGlmICghcFNlc3Npb24pCiAgICB7CiAgICAgICBWT1NfVFJBQ0UoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9ERUJVRywKICAgICAgICAgICAgICAgRkwoInBTZXNzaW9uIGlzIE5VTEwiKSk7CiAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSAhPQogICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSF9ET05FKSByZXR1cm47CgogICAgLy8gU3RvcCB0aW1lcgogICAgdm9zX3RpbWVyX3N0b3AoJnBTZXNzaW9uLT5mdFNtZUNvbnRleHQucHJlQXV0aFJlYXNzb2NJbnR2bFRpbWVyKTsKCiAgICAvLyBUcmFuc2l0aW9uIHRvIGluaXQgc3RhdGUKICAgIGNzcl9uZWlnaGJvcl9yb2FtX3N0YXRlX3RyYW5zaXRpb24ocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCk7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwojZW5kaWYKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmIGJhY2tncm91bmQgc2NhbiB0cmlnZ2VyZWQgYnkKICAgICAgICAgICAgTEZSIGlzIGluIHByb2dyZXNzLgoKICAgIFxwYXJhbSAgaGFsSGFuZGxlIC0gVGhlIGhhbmRsZSBmcm9tIEhERCBjb250ZXh0LgoKICAgIFxyZXR1cm4gYm9vbGVhbgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbVNjYW5Sc3BQZW5kaW5nKHRIYWxIYW5kbGUgaEhhbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICB0cEFuaVNpckdsb2JhbCBwTWFjID0gUE1BQ19TVFJVQ1QoaEhhbCk7CiAgICByZXR1cm4gKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdLnNjYW5Sc3BQZW5kaW5nKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmIFNUQSBpcyBpbiB0aGUgbWlkZGxlIG9mIHJvYW1pbmcgc3RhdGVzCgogICAgXHBhcmFtICBoYWxIYW5kbGUgLSBUaGUgaGFuZGxlIGZyb20gSEREIGNvbnRleHQuCiAgICBccGFyYW0gIHNlc3Npb25JZCAtIFNlc3Npb24gaWRlbnRpZmllcgoKICAgIFxyZXR1cm4gYm9vbGVhbgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yTWlkZGxlT2ZSb2FtaW5nKHRIYWxIYW5kbGUgaEhhbCwgdEFOSV9VOCBzZXNzaW9uSWQpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVChoSGFsKTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgdEFOSV9CT09MRUFOIHZhbCA9IChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAgICAgICAgICAgIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkcgPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORSA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAgICAgICAgICAgIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTiA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgIHJldHVybiAodmFsKTsKfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1DYW5kaWRhdGVGb3VuZEluZEhkbHIKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IENTUiBhcyBzb29uIGFzIFRMIHBvc3RzIHRoZSBjYW5kaWRhdGUKICAgICAgICAgICAgZm91bmQgaW5kaWNhdGlvbiB0byBTTUUgdmlhIE1DIHRocmVhZAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcE1zZyAtIE1zZyBzZW50IGJ5IFBFCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtQ2FuZGlkYXRlRm91bmRJbmRIZGxyKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHZvaWQqIHBNc2cpCnsKICAgIHRTaXJTbWVDYW5kaWRhdGVGb3VuZEluZCAqcFNpclNtZUNhbmRpZGF0ZUZvdW5kSW5kID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodFNpclNtZUNhbmRpZGF0ZUZvdW5kSW5kICopcE1zZzsKICAgIHRBTklfVTMyIHNlc3Npb25JZCA9IHBTaXJTbWVDYW5kaWRhdGVGb3VuZEluZC0+c2Vzc2lvbklkOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvW3Nlc3Npb25JZF07CiAgICBlSGFsU3RhdHVzIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAvKiB3ZSBtdXN0IGJlIGluIGNvbm5lY3RlZCBzdGF0ZSwgaWYgbm90IGlnbm9yZSBpdCAqLwogICAgaWYgKChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICB8fCAocE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZSBPUiB1T3NSZXF1ZXN0ZWRIYW5kb2ZmIGlzIHNldC4gSWdub3JlIGl0IikpOwogICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogV2UgYXJlIGFib3V0IHRvIHN0YXJ0IGEgZnJlc2ggc2NhbiBjeWNsZSwKICAgICAgICAgKiBwdXJnZSBub24tUDJQIHJlc3VsdHMgZnJvbSB0aGUgcGFzdCAqLwogICAgICAgIGNzclNjYW5GbHVzaFNlbGVjdGl2ZVJlc3VsdChwTWFjLCBWT1NfRkFMU0UpOwogICAgICAgIC8qIE9uY2UgaXQgZ2V0cyB0aGUgY2FuZGlkYXRlcyBmb3VuZCBpbmRpY2F0aW9uIGZyb20gUEUsIHdpbGwgaXNzdWUKICAgICAgICAgKiBhIHNjYW4gcmVxIHRvIFBFIHdpdGggk2ZyZXNoU2NhbpQgaW4gc2NhbnJlcSBzdHJ1Y3R1cmUgc2V0CiAgICAgICAgICogYXMgZm9sbG93czogMHg0MiAtIFJldHVybiAmIHB1cmdlIExGUiBzY2FuIHJlc3VsdHMKICAgICAgICAgKi8KICAgICAgICBzdGF0dXMgPSBjc3JTY2FuUmVxdWVzdExmclJlc3VsdChwTWFjLCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVNjYW5SZXN1bHRSZXF1ZXN0Q2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMpOwogICAgfQoKICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzSGFuZG9mZlJlcQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgc3RhcnQgd2l0aCB0aGUgaGFuZG9mZiBwcm9jZXNzLiBGaXJzdCBkbyBhCiAgICBTU0lEIHNjYW4gZm9yIHRoZSBCU1NJRCBwcm92aWRlZAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzSGFuZG9mZlJlcSh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICBwTmVpZ2hib3JSb2FtSW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRBTklfVTMyIHJvYW1JZDsKICAgIHRDc3JSb2FtUHJvZmlsZSAqcFByb2ZpbGUgPSBOVUxMOwogICAgdENzclJvYW1TZXNzaW9uICpwU2Vzc2lvbiA9IENTUl9HRVRfU0VTU0lPTihwTWFjLCBzZXNzaW9uSWQpOwogICAgdEFOSV9VOCBpID0gMDsKICAgIHVpbnQ4X3Qgcm9hbV9ub3cgPSAwOwogICAgdWludDhfdCByb2FtYWJsZV9hcF9jb3VudCA9IDA7CiAgICB0Q3NyU2NhblJlc3VsdEZpbHRlciAgICBzY2FuX2ZpbHRlcjsKICAgIHRTY2FuUmVzdWx0SGFuZGxlICAgICAgIHNjYW5fcmVzdWx0OwoKICAgIGlmIChOVUxMID09IHBTZXNzaW9uKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgicFNlc3Npb24gaXMgTlVMTCAiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CgogICAgZG8KICAgIHsKICAgICAgICByb2FtSWQgPSBHRVRfTkVYVF9ST0FNX0lEKCZwTWFjLT5yb2FtKTsKICAgICAgICBwUHJvZmlsZSA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyUm9hbVByb2ZpbGUpKTsKICAgICAgICBpZiAoIE5VTEwgPT0gcFByb2ZpbGUgKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2MgZmFpbGVkIikpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICAgICAgdm9zX21lbV9zZXQocFByb2ZpbGUsIHNpemVvZih0Q3NyUm9hbVByb2ZpbGUpLCAwKTsKICAgICAgICBzdGF0dXMgPSBjc3JSb2FtQ29weVByb2ZpbGUocE1hYywgcFByb2ZpbGUsIHBTZXNzaW9uLT5wQ3VyUm9hbVByb2ZpbGUpOwogICAgICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1Moc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUHJvZmlsZSBjb3B5IGZhaWxlZCIpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICAvL0FkZCB0aGUgQlNTSUQgJiBDaGFubmVsCiAgICAgICAgcFByb2ZpbGUtPkJTU0lEcy5udW1PZkJTU0lEcyA9IDE7CgogICAgICAgIGlmIChOVUxMID09IHBQcm9maWxlLT5CU1NJRHMuYnNzaWQpCiAgICAgICAgewogICAgICAgICAgICBwUHJvZmlsZS0+QlNTSURzLmJzc2lkID0KICAgICAgICAgICAgdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBQcm9maWxlLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwogICAgICAgICAgICBpZiAoTlVMTCA9PSBwUHJvZmlsZS0+QlNTSURzLmJzc2lkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIm1lbSBhbGxvYyBmYWlsZWQgZm9yIEJTU0lEIikpOwogICAgICAgICAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB2b3NfbWVtX3plcm8ocFByb2ZpbGUtPkJTU0lEcy5ic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBQcm9maWxlLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwoKICAgICAgICAvKiBQb3B1bGF0ZSB0aGUgQlNTSUQgZnJvbSBoYW5kb2ZmIGluZm8gcmVjZWl2ZWQgZnJvbSBIREQgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcFByb2ZpbGUtPkJTU0lEcy5udW1PZkJTU0lEczsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9jb3B5KCZwUHJvZmlsZS0+QlNTSURzLmJzc2lkW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICB9CgogICAgICAgIHBQcm9maWxlLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gMTsKICAgICAgICBpZiAoTlVMTCA9PSBwUHJvZmlsZS0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICAgewogICAgICAgICAgICBwUHJvZmlsZS0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPQogICAgICAgICAgICAgIHZvc19tZW1fbWFsbG9jKHNpemVvZigqcFByb2ZpbGUtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KSAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFByb2ZpbGUtPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpOwogICAgICAgICAgIGlmIChOVUxMID09IHBQcm9maWxlLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdCkKICAgICAgICAgICB7CiAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgibWVtIGFsbG9jIGZhaWxlZCBmb3IgQ2hhbm5lbExpc3QiKSk7CiAgICAgICAgICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcFByb2ZpbGUtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0WzBdID0gcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmNoYW5uZWw7CgogICAgICAgIC8qCiAgICAgICAgICogRm9yIFVzZXIgc3BhY2UgY29ubmVjdCByZXF1ZXN0cywgdGhlIHNjYW4gaGFzIGFscmVhZHkgYmVlbiBkb25lLgogICAgICAgICAqIFNvLCBjaGVjayBpZiB0aGUgQlNTIGRlc2NyaXB0b3IgZXhpc3RzIGluIHRoZSBzY2FuIGNhY2hlIGFuZAogICAgICAgICAqIHByb2NlZWQgd2l0aCB0aGUgaGFuZG9mZiBpbnN0ZWFkIG9mIGEgcmVkdW5kYW50IHNjYW4gYWdhaW4uCiAgICAgICAgICovCiAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5zcmMgPT0gQ09OTkVDVF9DTURfVVNFUlNQQUNFKSB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiQ29ubmVjdCBjbWQgd2l0aCBic3NpZCB3aXRoaW4gc2FtZSBFU1MiKSk7CiAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByZXBhcmVTY2FuUHJvZmlsZUZpbHRlcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLCAmc2Nhbl9maWx0ZXIsIHNlc3Npb25JZCk7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiRmlsdGVyIGNyZWF0aW9uIHN0YXR1cyA9ICVkIiksIHN0YXR1cyk7CiAgICAgICAgICAgIHN0YXR1cyA9IGNzclNjYW5HZXRSZXN1bHQocE1hYywgJnNjYW5fZmlsdGVyLCAmc2Nhbl9yZXN1bHQpOwogICAgICAgICAgICByb2FtX25vdyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuUmVzdWx0cyhwTWFjLCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2Nhbl9yZXN1bHQpOwogICAgICAgICAgICByb2FtYWJsZV9hcF9jb3VudCA9IGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CiAgICAgICAgICAgIGNzckZyZWVTY2FuRmlsdGVyKHBNYWMsICZzY2FuX2ZpbHRlcik7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgicm9hbV9ub3c9JWQsIHJvYW1hYmxlX2FwX2NvdW50PSVkIiksCiAgICAgICAgICAgICAgICAgICByb2FtX25vdywgcm9hbWFibGVfYXBfY291bnQpOwogICAgICAgIH0KICAgICAgICBpZiAocm9hbV9ub3cgJiYgcm9hbWFibGVfYXBfY291bnQpIHsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtVHJpZ2dlckhhbmRvZmYocE1hYywgc2Vzc2lvbklkKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdGF0dXMgPSBjc3JTY2FuRm9yU1NJRChwTWFjLCBzZXNzaW9uSWQsIHBQcm9maWxlLCByb2FtSWQsIEZBTFNFKTsKICAgICAgICAgICAgaWYoIUhBTF9TVEFUVVNfU1VDQ0VTUyhzdGF0dXMpKQogICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlNTSUQgc2NhbiBmYWlsZWQiKSk7CiAgICAgICAgfQogICAgfXdoaWxlKDApOwoKICAgIGlmKE5VTEwgIT0gcFByb2ZpbGUpCiAgICB7CiAgICAgICAgY3NyUmVsZWFzZVByb2ZpbGUocE1hYywgcFByb2ZpbGUpOwogICAgICAgIHZvc19tZW1fZnJlZShwUHJvZmlsZSk7CiAgICB9CgogICAgcmV0dXJuIHN0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVNzc2lkU2NhbkRvbmUKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG9uY2UgU1NJRCBzY2FuIGlzIGRvbmUuIElmIFNTSUQgc2NhbiBmYWlsZWQKICAgIHRvIGZpbmQgb3VyIGNhbmRpZGF0ZSBhZGQgYW4gZW50cnkgdG8gY3NyIHNjYW4gY2FjaGUgb3Vyc2VsZiBiZWZvcmUgc3RhcnRpbmcKICAgIHRoZSBoYW5kLW9mZiBwcm9jZXNzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVNzc2lkU2NhbkRvbmUodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTggc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUhhbFN0YXR1cyBzdGF0dXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgZUhhbFN0YXR1cyAgICAgICAgICAgICAgICAgICBoc3RhdHVzOwoKICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiY2FsbGVkICIpKTsKCiAgICAvKiB3ZSBtdXN0IGJlIGluIGNvbm5lY3RlZCBzdGF0ZSwgaWYgbm90IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZS4gSWdub3JlIGl0IikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQoKICAgIC8vaWYgU1NJRCBzY2FuIGZhaWxlZCB0byBmaW5kIG91ciBjYW5kaWRhdGUgYWRkIGFuIGVudHJ5IHRvIGNzciBzY2FuIGNhY2hlIG91cnNlbGYKICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1Moc3RhdHVzKSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkFkZCBhbiBlbnRyeSB0byBjc3Igc2NhbiBjYWNoZSIpKTsKICAgICAgICBoc3RhdHVzID0gY3NyU2NhbkNyZWF0ZUVudHJ5SW5TY2FuQ2FjaGUocE1hYywgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmNoYW5uZWwpOwogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoImNzclNjYW5DcmVhdGVFbnRyeUluU2NhbkNhY2hlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgfQogICAgfQoKICAgIC8qIE5vdyB3ZSBoYXZlIGNvbXBsZXRlZCBzY2FubmluZyBmb3IgdGhlIGNhbmRpZGF0ZSBwcm92aWRlZCBieSBIREQuIExldCBtb3ZlIG9uIHRvIEhPKi8KICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhbkNvbXBsZXRlKHBNYWMsIHNlc3Npb25JZCk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHNjYW4gcHJvY2VzcyBjb21wbGV0ZSBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgaHN0YXR1cyk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUhhbmRvZmZSZXFIZGxyCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSBDU1IgYXMgc29vbiBhcyBpdCBnZXRzIGEgaGFuZG9mZiByZXF1ZXN0CiAgICAgICAgICAgIHRvIFNNRSB2aWEgTUMgdGhyZWFkCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwTXNnIC0gTXNnIHNlbnQgYnkgSERECgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSGFuZG9mZlJlcUhkbHIodHBBbmlTaXJHbG9iYWwgcE1hYywgdm9pZCogcE1zZykKewogICAgdEFuaUhhbmRvZmZSZXEgKnBIYW5kb2ZmUmVxSW5mbyA9ICh0QW5pSGFuZG9mZlJlcSAqKXBNc2c7CiAgICB0QU5JX1UzMiBzZXNzaW9uSWQgPSBwSGFuZG9mZlJlcUluZm8tPnNlc3Npb25JZDsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm9bc2Vzc2lvbklkXTsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIC8qIHdlIG11c3QgYmUgaW4gY29ubmVjdGVkIHN0YXRlLCBpZiBub3QgaWdub3JlIGl0ICovCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBub3QgQ09OTkVDVEVEIHN0YXRlLiBJZ25vcmUgaXQiKSk7CiAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvL3NhdmUgdGhlIGhhbmRvZmYgaW5mbyBjYW1lIGZyb20gSEREIGFzIHBhcnQgb2YgdGhlIHJlYXNzb2MgcmVxCiAgICAgICAgcEhhbmRvZmZSZXFJbmZvID0gKHRBbmlIYW5kb2ZmUmVxICopcE1zZzsKICAgICAgICBpZiAoTlVMTCAhPSBwSGFuZG9mZlJlcUluZm8pCiAgICAgICAgewogICAgICAgICAgICAvL3Nhbml0eSBjaGVjawogICAgICAgICAgICBpZiAoVk9TX0ZBTFNFID09IHZvc19tZW1fY29tcGFyZShwSGFuZG9mZlJlcUluZm8tPmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VyckFQYnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih0U2lyTWFjQWRkcikpKQogICAgICAgICAgICB7CgogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmNoYW5uZWwgPSBwSGFuZG9mZlJlcUluZm8tPmNoYW5uZWw7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uc3JjICAgICA9IHBIYW5kb2ZmUmVxSW5mby0+aGFuZG9mZl9zcmM7CiAgICAgICAgICAgICAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBIYW5kb2ZmUmVxSW5mby0+YnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNik7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDE7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJPQU1fU0NBTl9PRkZMT0FEX1NUT1AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVBU09OX09TX1JFUVVFU1RFRF9ST0FNSU5HX05PVyk7CiAgICAgICAgICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJjc3JSb2FtT2ZmbG9hZFNjYW4gZmFpbGVkIikpOwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgcmVxIGhhcyBzYW1lIEJTU0lEIGFzIGN1cnJlbnQgQVAhISIpKTsKICAgICAgICAgICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBtc2cgaXMgTlVMTCIpKTsKICAgICAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHN0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByb2NlZWRXaXRoSGFuZG9mZlJlcQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgQ1NSIGFzIHNvb24gYXMgaXQgZ2V0cyByc3AgYmFjayBmb3IKICAgICAgICAgICAgUk9BTV9TQ0FOX09GRkxPQURfU1RPUCB3aXRoIHJlYXNvbiBSRUFTT05fT1NfUkVRVUVTVEVEX1JPQU1JTkdfTk9XCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVByb2NlZWRXaXRoSGFuZG9mZlJlcSh0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4IHNlc3Npb25JZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgLyogd2UgbXVzdCBiZSBpbiBjb25uZWN0ZWQgc3RhdGUsIGlmIG5vdCBpZ25vcmUgaXQgKi8KICAgIGlmICgoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgfHwgKCFwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBub3QgQ09OTkVDVEVEIHN0YXRlKCVkKSBvciB1T3NSZXF1ZXN0ZWRIYW5kb2ZmKCVkKSBpcyBub3Qgc2V0LiBJZ25vcmUgaXQgIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSwgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpOwogICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLy9MZXQncyBnbyBhaGVhZCB3aXRoIGhhbmRvZmYKICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzSGFuZG9mZlJlcShwTWFjLCBzZXNzaW9uSWQpOwogICAgfQogICAgaWYoIUhBTF9TVEFUVVNfU1VDQ0VTUyhzdGF0dXMpKQogICAgewogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgIH0KICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1TdGFydExmclNjYW4KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGlmIEhERCByZXF1ZXN0ZWQgaGFuZG9mZiBmYWlsZWQgZm9yIHNvbWUKICAgIHJlYXNvbi4gc3RhcnQgdGhlIExGUiBsb2dpYyBhdCB0aGF0IHBvaW50LkJ5IHRoZSB0aW1lLCB0aGlzIGZ1bmN0aW9uIGlzCiAgICBjYWxsZWQsIGEgU1RPUCBjb21tYW5kIGhhcyBhbHJlYWR5IGJlZW4gaXNzdWVkLgoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1TdGFydExmclNjYW4odHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VOCBzZXNzaW9uSWQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mb1tzZXNzaW9uSWRdOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgLyogVGhlcmUgaXMgbm8gY2FuZGlkYXRlIG9yIFdlIGFyZSBub3Qgcm9hbWluZyBOb3cuCiAgICAgKiBJbmZvcm0gdGhlIEZXIHRvIHJlc3RhcnQgUm9hbSBPZmZsb2FkIFNjYW4gICovCiAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgc2Vzc2lvbklkLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwKICAgICAgICAgICAgICAgICAgICAgICBSRUFTT05fTk9fQ0FORF9GT1VORF9PUl9OT1RfUk9BTUlOR19OT1cpOwoKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CiNlbmRpZiAvL1dMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAojZW5kaWYgLyogV0xBTl9GRUFUVVJFX05FSUdIQk9SX1JPQU1JTkcgKi8K