LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQogKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovLyBNQVJLRVIodXBkYXRlX3ByZWNvbXAucHkpOiBhdXRvZ2VuIGluY2x1ZGUgc3RhdGVtZW50LCBkbyBub3QgcmVtb3ZlCiNpbmNsdWRlICJwcmVjb21waWxlZF9kYnVpLmh4eCIKCiNpbmNsdWRlICJhZHRhYmRsZy5oeHgiCiNpbmNsdWRlICJicm93c2VyaWRzLmh4eCIKI2luY2x1ZGUgImRidV9xcnkuaHJjIgojaW5jbHVkZSAiZGJ1X3JlZ2hlbHBlci5oeHgiCiNpbmNsdWRlICJkYnVzdHJpbmdzLmhyYyIKI2luY2x1ZGUgImRlZmF1bHRvYmplY3RuYW1lY2hlY2suaHh4IgojaW5jbHVkZSAiZGxnc2F2ZS5oeHgiCiNpbmNsdWRlICJsb2NhbHJlc2FjY2Vzcy5oeHgiCiNpbmNsdWRlICJRVGFibGVXaW5kb3cuaHh4IgojaW5jbHVkZSAiUVRhYmxlV2luZG93RGF0YS5oeHgiCiNpbmNsdWRlICJxdWVyeWNvbnRhaW5lcndpbmRvdy5oeHgiCiNpbmNsdWRlICJxdWVyeWNvbnRyb2xsZXIuaHh4IgojaW5jbHVkZSAiUXVlcnlEZXNpZ25WaWV3Lmh4eCIKI2luY2x1ZGUgIlF1ZXJ5VGFibGVWaWV3Lmh4eCIKI2luY2x1ZGUgIlF1ZXJ5VGV4dFZpZXcuaHh4IgojaW5jbHVkZSAicXVlcnl2aWV3Lmh4eCIKI2luY2x1ZGUgIlF1ZXJ5Vmlld1N3aXRjaC5oeHgiCiNpbmNsdWRlICJzcWxtZXNzYWdlLmh4eCIKI2luY2x1ZGUgIlRhYmxlQ29ubmVjdGlvbkRhdGEuaHh4IgojaW5jbHVkZSAiVGFibGVGaWVsZERlc2NyaXB0aW9uLmh4eCIKI2luY2x1ZGUgIlVJVG9vbHMuaHh4IgoKLyoqID09PSBiZWdpbiBVTk8gaW5jbHVkZXMgPT09ICoqLwojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2JlYW5zL1Byb3BlcnR5QXR0cmlidXRlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9jb250YWluZXIvWENoaWxkLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9jb250YWluZXIvWE5hbWVDb250YWluZXIuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2ZyYW1lL0ZyYW1lU2VhcmNoRmxhZy5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvZnJhbWUvWExvYWRFdmVudExpc3RlbmVyLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9pby9YQWN0aXZlRGF0YVNpbmsuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2lvL1hBY3RpdmVEYXRhU291cmNlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGIvQ29tbWFuZFR5cGUuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYi9TUUxDb250ZXh0LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGIvWFF1ZXJpZXNTdXBwbGllci5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiL1hRdWVyeURlZmluaXRpb25zU3VwcGxpZXIuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYi9YU1FMUXVlcnlDb21wb3NlckZhY3RvcnkuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmMvU1FMV2FybmluZy5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiYy9YUm93LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGJjeC9YQXBwZW5kLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGJjeC9YRGF0YURlc2NyaXB0b3JGYWN0b3J5LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGJjeC9YRHJvcC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiY3gvWFRhYmxlc1N1cHBsaWVyLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGJjeC9YVmlld3NTdXBwbGllci5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvdWkvZGlhbG9ncy9YRXhlY3V0YWJsZURpYWxvZy5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvdXRpbC9YQ2xvc2VhYmxlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci91dGlsL1ZldG9FeGNlcHRpb24uaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2ZyYW1lL1hVbnRpdGxlZE51bWJlcnMuaHBwPgovKiogPT09IGVuZCBVTk8gaW5jbHVkZXMgPT09ICoqLwoKI2luY2x1ZGUgPGNvbXBoZWxwZXIvYmFzaWNpby5oeHg+CiNpbmNsdWRlIDxjb21waGVscGVyL2V4dHJhY3QuaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9wcm9wZXJ0eS5oeHg+CiNpbmNsdWRlIDxjb21waGVscGVyL3NlcXN0cmVhbS5oeHg+CiNpbmNsdWRlIDxjb21waGVscGVyL3N0cmVhbXNlY3Rpb24uaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci90eXBlcy5oeHg+CiNpbmNsdWRlIDxjb25uZWN0aXZpdHkvZGJleGNlcHRpb24uaHh4PgojaW5jbHVkZSA8Y29ubmVjdGl2aXR5L2RidG9vbHMuaHh4PgojaW5jbHVkZSA8Y3BwdWhlbHBlci9leGNfaGxwLmh4eD4KI2luY2x1ZGUgPHNmeDIvc2Z4c2lkcy5ocmM+CiNpbmNsdWRlIDxzdnRvb2xzL2xvY2FscmVzYWNjZXNzLmh4eD4KI2luY2x1ZGUgPHRvb2xraXQvaGVscGVyL3ZjbHVub2hlbHBlci5oeHg+CiNpbmNsdWRlIDx0b29scy9kaWFnbm9zZV9leC5oPgojaW5jbHVkZSA8dmNsL21zZ2JveC5oeHg+CiNpbmNsdWRlIDx2Y2wvc3ZhcHAuaHh4PgojaW5jbHVkZSA8dm9zL211dGV4Lmh4eD4KCmV4dGVybiAiQyIgdm9pZCBTQUxfQ0FMTCBjcmVhdGVSZWdpc3RyeUluZm9fT1F1ZXJ5Q29udHJvbCgpCnsKCXN0YXRpYyA6OmRiYXVpOjpPTXVsdGlJbnN0YW5jZUF1dG9SZWdpc3RyYXRpb248IDo6ZGJhdWk6Ok9RdWVyeUNvbnRyb2xsZXIgPiBhQXV0b1JlZ2lzdHJhdGlvbjsKfQpuYW1lc3BhY2UgZGJhdWkKewogICAgdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnVubzsKICAgIHVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpiZWFuczsKICAgIHVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTsKICAgIHVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOwogICAgdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6Omxhbmc7CgogICAgY2xhc3MgT1ZpZXdDb250cm9sbGVyIDogcHVibGljIE9RdWVyeUNvbnRyb2xsZXIKICAgIHsKICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIHZpcnR1YWwgOjpydGw6Ok9VU3RyaW5nIFNBTF9DQUxMIGdldEltcGxlbWVudGF0aW9uTmFtZSgpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKICAgICAgICB7CgkgICAgICAgIHJldHVybiBnZXRJbXBsZW1lbnRhdGlvbk5hbWVfU3RhdGljKCk7CiAgICAgICAgfQogICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIHZpcnR1YWwgU2VxdWVuY2U8IDo6cnRsOjpPVVN0cmluZz4gU0FMX0NBTEwgZ2V0U3VwcG9ydGVkU2VydmljZU5hbWVzKCkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKICAgICAgICB7CgkgICAgICAgIHJldHVybiBnZXRTdXBwb3J0ZWRTZXJ2aWNlTmFtZXNfU3RhdGljKCk7CiAgICAgICAgfQogICAgcHVibGljOgogICAgICAgIE9WaWV3Q29udHJvbGxlcihjb25zdCBSZWZlcmVuY2U8IFhNdWx0aVNlcnZpY2VGYWN0b3J5ID4mIF9yTSkgOiBPUXVlcnlDb250cm9sbGVyKF9yTSl7fQoKICAgICAgICAvLyBuZWVkIGJ5IHJlZ2lzdHJhdGlvbgoJICAgIHN0YXRpYyA6OnJ0bDo6T1VTdHJpbmcgZ2V0SW1wbGVtZW50YXRpb25OYW1lX1N0YXRpYygpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKICAgICAgICB7CgkgICAgICAgIHJldHVybiA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgib3JnLm9wZW5vZmZpY2UuY29tcC5kYnUuT1ZpZXdEZXNpZ24iKTsKICAgICAgICB9CgkgICAgc3RhdGljIFNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmcgPiBnZXRTdXBwb3J0ZWRTZXJ2aWNlTmFtZXNfU3RhdGljKHZvaWQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKICAgICAgICB7CiAgICAgICAgICAgIFNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmc+IGFTdXBwb3J0ZWQoMSk7CgkgICAgICAgIGFTdXBwb3J0ZWQuZ2V0QXJyYXkoKVswXSA9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJjb20uc3VuLnN0YXIuc2RiLlZpZXdEZXNpZ24iKTsKCSAgICAgICAgcmV0dXJuIGFTdXBwb3J0ZWQ7CiAgICAgICAgfQoJICAgIHN0YXRpYyBSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiBTQUxfQ0FMTCBDcmVhdGUoY29uc3QgUmVmZXJlbmNlPCBYTXVsdGlTZXJ2aWNlRmFjdG9yeSA+JiBfck0pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gKihuZXcgT1ZpZXdDb250cm9sbGVyKF9yTSkpOwogICAgICAgIH0KICAgIH07Cn0KZXh0ZXJuICJDIiB2b2lkIFNBTF9DQUxMIGNyZWF0ZVJlZ2lzdHJ5SW5mb19PVmlld0NvbnRyb2woKQp7CglzdGF0aWMgOjpkYmF1aTo6T011bHRpSW5zdGFuY2VBdXRvUmVnaXN0cmF0aW9uPCA6OmRiYXVpOjpPVmlld0NvbnRyb2xsZXIgPiBhQXV0b1JlZ2lzdHJhdGlvbjsKfQoKbmFtZXNwYWNlIGRiYXVpCnsKCXVzaW5nIG5hbWVzcGFjZSA6OmNvbm5lY3Rpdml0eTsKI2lmIE9TTF9ERUJVR19MRVZFTCA+IDEKCW5hbWVzcGFjZQoJewoJCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkJdm9pZCBpbnNlcnRQYXJzZVRyZWUoU3ZUcmVlTGlzdEJveCogX3BCb3gsOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIF9wTm9kZSxTdkxCb3hFbnRyeSogX3BQYXJlbnQgPSBOVUxMKQoJCXsKCQkJOjpydGw6Ok9VU3RyaW5nIHJTdHJpbmc7CgkJCWlmICghX3BOb2RlLT5pc1Rva2VuKCkpCgkJCXsKCQkJCS8vIFJlZ2VsbmFtZW4gYWxzIHJ1bGU6IC4uLgoJCQkJclN0cmluZyA9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJSVUxFX0lEOiAiKTsKCQkJCXJTdHJpbmcgKz0gOjpydGw6Ok9VU3RyaW5nOjp2YWx1ZU9mKCAoc2FsX0ludDMyKV9wTm9kZS0+Z2V0UnVsZUlEKCkpOwoJCQkJclN0cmluZys9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIoIik7CgkJCQlyU3RyaW5nICs9IE9TUUxQYXJzZXI6OlJ1bGVJRFRvU3RyKF9wTm9kZS0+Z2V0UnVsZUlEKCkpOwoJCQkJclN0cmluZys9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIpIik7CgoKCQkJCV9wUGFyZW50ID0gX3BCb3gtPkluc2VydEVudHJ5KHJTdHJpbmcsX3BQYXJlbnQpOwoKCQkJCS8vIGVpbm1hbCBhdXN3ZXJ0ZW4gd2lldmllbCBTdWJ0cmVlcyBkaWVzZXIgS25vdGVuIGJlc2l0enQKCQkJCXNhbF91SW50MzIgblN0b3AgPSBfcE5vZGUtPmNvdW50KCk7CgkJCQkvLyBob2wgZGlyIGRlbiBlcnN0ZW4gU3VidHJlZQoJCQkJZm9yKHNhbF91SW50MzIgaT0wO2k8blN0b3A7KytpKQoJCQkJCWluc2VydFBhcnNlVHJlZShfcEJveCxfcE5vZGUtPmdldENoaWxkKGkpLF9wUGFyZW50KTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCS8vIGVpbiBUb2tlbiBnZWZ1bmRlbgoJCQkJLy8gdGFicyBmdWVyIGRhcyBFaW5ydWVja2VuIGVudHNwcmVjaGVuZCBuTGV2ZWwKCgkJCQlzd2l0Y2ggKF9wTm9kZS0+Z2V0Tm9kZVR5cGUoKSkKCQkJCXsKCgkJCQljYXNlIFNRTF9OT0RFX0tFWVdPUkQ6CgkJCQkJewoJCQkJCQlyU3RyaW5nKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlNRTF9LRVlXT1JEOiIpOwoJCQkJCQk6OnJ0bDo6T1N0cmluZyBzVCA9IE9TUUxQYXJzZXI6OlRva2VuSURUb1N0cihfcE5vZGUtPmdldFRva2VuSUQoKSk7CgkJCQkJCXJTdHJpbmcgKz0gOjpydGw6Ok9TdHJpbmdUb09VU3RyaW5nKCBzVCwgUlRMX1RFWFRFTkNPRElOR19VVEY4KTsKCQkJCQkgYnJlYWs7fQoKCQkJCWNhc2UgU1FMX05PREVfQ09NUEFSSVNPTjoKCQkJCQl7clN0cmluZys9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJTUUxfQ09NUEFSSVNPTjoiKTsKCQkJCQlyU3RyaW5nICs9IF9wTm9kZS0+Z2V0VG9rZW5WYWx1ZSgpOwkvLyBoYWVuZ2UgTm9kZXZhbHVlIGFuCgkJCQkJCQkvLyB1bmQgYmVnaW5uZSBuZXUgWmVpbGUKCQkJCQlicmVhazt9CgoJCQkJY2FzZSBTUUxfTk9ERV9OQU1FOgoJCQkJCXtyU3RyaW5nKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlNRTF9OQU1FOiIpOwoJCQkJCSByU3RyaW5nKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlwiIik7CgkJCQkJIHJTdHJpbmcgKz0gX3BOb2RlLT5nZXRUb2tlblZhbHVlKCk7CgkJCQkJIHJTdHJpbmcrPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiXCIiKTsKCgkJCQkJIGJyZWFrO30KCgkJCQljYXNlIFNRTF9OT0RFX1NUUklORzoKCQkJCQl7clN0cmluZyArPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiU1FMX1NUUklORzonIik7CgkJCQkJIHJTdHJpbmcgKz0gX3BOb2RlLT5nZXRUb2tlblZhbHVlKCk7CgkJCQkJIGJyZWFrO30KCgkJCQljYXNlIFNRTF9OT0RFX0lOVE5VTToKCQkJCQl7clN0cmluZyArPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiU1FMX0lOVE5VTToiKTsKCQkJCQkgclN0cmluZyArPSBfcE5vZGUtPmdldFRva2VuVmFsdWUoKTsKCQkJCQkgYnJlYWs7fQoKCQkJCWNhc2UgU1FMX05PREVfQVBQUk9YTlVNOgoJCQkJCXtyU3RyaW5nICs9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJTUUxfQVBQUk9YTlVNOiIpOwoJCQkJCSByU3RyaW5nICs9IF9wTm9kZS0+Z2V0VG9rZW5WYWx1ZSgpOwoJCQkJCSBicmVhazt9CgoJCQkJY2FzZSBTUUxfTk9ERV9QVU5DVFVBVElPTjoKCQkJCQl7clN0cmluZyArPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiU1FMX1BVTkNUVUFUSU9OOiIpOwoJCQkJCXJTdHJpbmcgKz0gX3BOb2RlLT5nZXRUb2tlblZhbHVlKCk7CS8vIGhhZW5nZSBOb2RldmFsdWUgYW4KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBTUUxfTk9ERV9BTU1TQzoKCQkJCQl7clN0cmluZyArPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiU1FMX0FNTVNDOiIpOwoJCQkJCXJTdHJpbmcgKz0gX3BOb2RlLT5nZXRUb2tlblZhbHVlKCk7CS8vIGhhZW5nZSBOb2RldmFsdWUgYW4KCgkJCQkJYnJlYWs7fQoKCQkJCWRlZmF1bHQ6CgkJCQkJT1NMX0FTU0VSVCgiT1NRTFBhcnNlcjo6U2hvd1BhcnNlVHJlZTogdW56dWxhZXNzaWdlciBOb2RlVHlwZSIpOwoJCQkJCXJTdHJpbmcgKz0gX3BOb2RlLT5nZXRUb2tlblZhbHVlKCk7CgkJCQl9CgkJCQlfcEJveC0+SW5zZXJ0RW50cnkoclN0cmluZyxfcFBhcmVudCk7CgkJCX0KCQl9Cgl9CiNlbmRpZiAvLyBPU0xfREVCVUdfTEVWRUwKCiAgICBuYW1lc3BhY2UKICAgIHsKCQkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIFN0cmluZyBsY2xfZ2V0T2JqZWN0UmVzb3VyY2VTdHJpbmcoIHNhbF91SW50MTYgX25SZXNJZCwgc2FsX0ludDMyIF9uQ29tbWFuZFR5cGUgKQogICAgICAgIHsKICAgICAgICAgICAgU3RyaW5nIHNNZXNzYWdlVGV4dCA9IFN0cmluZyggTW9kdWxlUmVzKCBfblJlc0lkICkgKTsKICAgICAgICAgICAgU3RyaW5nIHNPYmplY3RUeXBlOwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBMb2NhbFJlc291cmNlQWNjZXNzIGFMb2NhbFJlcyggUlNDX1FVRVJZX09CSkVDVF9UWVBFLCBSU0NfUkVTT1VSQ0UgKTsKICAgICAgICAgICAgICAgIHNPYmplY3RUeXBlID0gU3RyaW5nKCBNb2R1bGVSZXMoIChzYWxfdUludDE2KSggX25Db21tYW5kVHlwZSArIDEgKSApICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc01lc3NhZ2VUZXh0LlNlYXJjaEFuZFJlcGxhY2UoIFN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKCAiJG9iamVjdCQiICksIHNPYmplY3RUeXBlICk7CiAgICAgICAgICAgIHJldHVybiBzTWVzc2FnZVRleHQ7CiAgICAgICAgfQogICAgfQoKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnVubzsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OmlvOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6YmVhbnM7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnV0aWw7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpsYW5nOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6Y29udGFpbmVyOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6c2RiY3g7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpzZGJjOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6c2RiOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6dWk6OmRpYWxvZ3M7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjphd3Q7CnVzaW5nIG5hbWVzcGFjZSA6OmRidG9vbHM7Cgp1c2luZyBuYW1lc3BhY2UgOjpjb21waGVscGVyOwoKbmFtZXNwYWNlCnsKCXZvaWQgZW5zdXJlVG9vbGJhcnMoIE9RdWVyeUNvbnRyb2xsZXImIF9yQ29udHJvbGxlciwgc2FsX0Jvb2wgX2JEZXNpZ24gKQogICAgewogICAgICAgIFJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhMYXlvdXRNYW5hZ2VyID4geExheW91dE1hbmFnZXIgPSBfckNvbnRyb2xsZXIuZ2V0TGF5b3V0TWFuYWdlciggX3JDb250cm9sbGVyLmdldEZyYW1lKCkgKTsKCQlpZiAoIHhMYXlvdXRNYW5hZ2VyLmlzKCkgKQoJCXsKCQkJeExheW91dE1hbmFnZXItPmxvY2soKTsKCQkJc3RhdGljIDo6cnRsOjpPVVN0cmluZyBzX3NEZXNpZ25Ub29sYmFyKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgicHJpdmF0ZTpyZXNvdXJjZS90b29sYmFyL2Rlc2lnbm9iamVjdGJhciIpKTsKCQkJc3RhdGljIDo6cnRsOjpPVVN0cmluZyBzX3NTcWxUb29sYmFyKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgicHJpdmF0ZTpyZXNvdXJjZS90b29sYmFyL3NxbG9iamVjdGJhciIpKTsKCQkJaWYgKCBfYkRlc2lnbiApCgkJCXsKCQkJCXhMYXlvdXRNYW5hZ2VyLT5kZXN0cm95RWxlbWVudCggc19zU3FsVG9vbGJhciApOwoJCQkJeExheW91dE1hbmFnZXItPmNyZWF0ZUVsZW1lbnQoIHNfc0Rlc2lnblRvb2xiYXIgKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCXhMYXlvdXRNYW5hZ2VyLT5kZXN0cm95RWxlbWVudCggc19zRGVzaWduVG9vbGJhciApOwoJCQkJeExheW91dE1hbmFnZXItPmNyZWF0ZUVsZW1lbnQoIHNfc1NxbFRvb2xiYXIgKTsKCQkJfQoJCQl4TGF5b3V0TWFuYWdlci0+dW5sb2NrKCk7CiAgICAgICAgICAgIHhMYXlvdXRNYW5hZ2VyLT5kb0xheW91dCgpOwoJCX0KICAgIH0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpydGw6Ok9VU3RyaW5nIFNBTF9DQUxMIE9RdWVyeUNvbnRyb2xsZXI6OmdldEltcGxlbWVudGF0aW9uTmFtZSgpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJcmV0dXJuIGdldEltcGxlbWVudGF0aW9uTmFtZV9TdGF0aWMoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpydGw6Ok9VU3RyaW5nIE9RdWVyeUNvbnRyb2xsZXI6OmdldEltcGxlbWVudGF0aW9uTmFtZV9TdGF0aWMoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCXJldHVybiA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgib3JnLm9wZW5vZmZpY2UuY29tcC5kYnUuT1F1ZXJ5RGVzaWduIik7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2VxdWVuY2U8IDo6cnRsOjpPVVN0cmluZz4gT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0U3VwcG9ydGVkU2VydmljZU5hbWVzX1N0YXRpYyh2b2lkKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCVNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmc+IGFTdXBwb3J0ZWQoMSk7CglhU3VwcG9ydGVkLmdldEFycmF5KClbMF0gPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiY29tLnN1bi5zdGFyLnNkYi5RdWVyeURlc2lnbiIpOwoJcmV0dXJuIGFTdXBwb3J0ZWQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmc+IFNBTF9DQUxMIE9RdWVyeUNvbnRyb2xsZXI6OmdldFN1cHBvcnRlZFNlcnZpY2VOYW1lcygpIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCnsKCXJldHVybiBnZXRTdXBwb3J0ZWRTZXJ2aWNlTmFtZXNfU3RhdGljKCk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiBTQUxfQ0FMTCBPUXVlcnlDb250cm9sbGVyOjpDcmVhdGUoY29uc3QgUmVmZXJlbmNlPFhNdWx0aVNlcnZpY2VGYWN0b3J5ID4mIF9yeEZhY3RvcnkpCnsKCXJldHVybiAqKG5ldyBPUXVlcnlDb250cm9sbGVyKF9yeEZhY3RvcnkpKTsKfQpEQkdfTkFNRShPUXVlcnlDb250cm9sbGVyKTsKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KT1F1ZXJ5Q29udHJvbGxlcjo6T1F1ZXJ5Q29udHJvbGxlcihjb25zdCBSZWZlcmVuY2U8IFhNdWx0aVNlcnZpY2VGYWN0b3J5ID4mIF9yTSkKICAgIDpPSm9pbkNvbnRyb2xsZXIoX3JNKQogICAgLE9RdWVyeUNvbnRyb2xsZXJfUEJhc2UoIGdldEJyb2FkY2FzdEhlbHBlcigpICkKICAgICxtX3BQYXJzZUNvbnRleHQoIG5ldyBzdnhmb3JtOjpPU3lzdGVtUGFyc2VDb250ZXh0ICkKICAgICxtX2FTcWxQYXJzZXIoIF9yTSwgbV9wUGFyc2VDb250ZXh0ICkKCSxtX3BTcWxJdGVyYXRvcihOVUxMKQoJLG1fblZpc2libGVSb3dzKDB4NDAwKQoJLG1fblNwbGl0UG9zKC0xKQogICAgLG1fbkNvbW1hbmRUeXBlKCBDb21tYW5kVHlwZTo6UVVFUlkgKQogICAgLG1fYkdyYXBoaWNhbERlc2lnbihzYWxfRmFsc2UpCgksbV9iRGlzdGluY3Qoc2FsX0ZhbHNlKQoJLG1fYlZpZXdBbGlhcyhzYWxfRmFsc2UpCiAgICAsbV9iVmlld1RhYmxlKHNhbF9GYWxzZSkKCSxtX2JWaWV3RnVuY3Rpb24oc2FsX0ZhbHNlKQoJLG1fYkVzY2FwZVByb2Nlc3Npbmcoc2FsX1RydWUpCnsKCURCR19DVE9SKE9RdWVyeUNvbnRyb2xsZXIsTlVMTCk7CglJbnZhbGlkYXRlQWxsKCk7CgoJcmVnaXN0ZXJQcm9wZXJ0eSggUFJPUEVSVFlfQUNUSVZFQ09NTUFORCwgUFJPUEVSVFlfSURfQUNUSVZFQ09NTUFORCwgUHJvcGVydHlBdHRyaWJ1dGU6OlJFQURPTkxZIHwgUHJvcGVydHlBdHRyaWJ1dGU6OkJPVU5ELAoJCSZtX3NTdGF0ZW1lbnQsIDo6Z2V0Q3BwdVR5cGUoICZtX3NTdGF0ZW1lbnQgKSApOwoJcmVnaXN0ZXJQcm9wZXJ0eSggUFJPUEVSVFlfRVNDQVBFX1BST0NFU1NJTkcsIFBST1BFUlRZX0lEX0VTQ0FQRV9QUk9DRVNTSU5HLCBQcm9wZXJ0eUF0dHJpYnV0ZTo6UkVBRE9OTFkgfCBQcm9wZXJ0eUF0dHJpYnV0ZTo6Qk9VTkQsCgkJJm1fYkVzY2FwZVByb2Nlc3NpbmcsIDo6Z2V0Q3BwdVR5cGUoICZtX2JFc2NhcGVQcm9jZXNzaW5nICkgKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KT1F1ZXJ5Q29udHJvbGxlcjo6fk9RdWVyeUNvbnRyb2xsZXIoKQp7CglEQkdfRFRPUihPUXVlcnlDb250cm9sbGVyLE5VTEwpOwoJaWYgKCAhZ2V0QnJvYWRjYXN0SGVscGVyKCkuYkRpc3Bvc2VkICYmICFnZXRCcm9hZGNhc3RIZWxwZXIoKS5iSW5EaXNwb3NlICkKCXsKCQlPU0xfRU5TVVJFKDAsIlBsZWFzZSBjaGVjayB3aG8gZG9lc24ndCBkaXNwb3NlIHRoaXMgY29tcG9uZW50ISIpOwogICAgICAgIC8vIGluY3JlbWVudCByZWYgY291bnQgdG8gcHJldmVudCBkb3VibGUgY2FsbCBvZiBEdG9yCiAgICAgICAgb3NsX2luY3JlbWVudEludGVybG9ja2VkQ291bnQoICZtX3JlZkNvdW50ICk7CiAgICAgICAgZGlzcG9zZSgpOwoJfQp9CgpJTVBMRU1FTlRfRk9SV0FSRF9YSU5URVJGQUNFMiggT1F1ZXJ5Q29udHJvbGxlciwgT0pvaW5Db250cm9sbGVyLCBPUXVlcnlDb250cm9sbGVyX1BCYXNlICkKSU1QTEVNRU5UX0ZPUldBUkRfWFRZUEVQUk9WSURFUjIoIE9RdWVyeUNvbnRyb2xsZXIsIE9Kb2luQ29udHJvbGxlciwgT1F1ZXJ5Q29udHJvbGxlcl9QQmFzZSApCgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNlPCBYUHJvcGVydHlTZXRJbmZvID4gU0FMX0NBTEwgT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0UHJvcGVydHlTZXRJbmZvKCkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKewoJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXRJbmZvID4geEluZm8oIGNyZWF0ZVByb3BlcnR5U2V0SW5mbyggZ2V0SW5mb0hlbHBlcigpICkgKTsKCXJldHVybiB4SW5mbzsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9Cb29sIFNBTF9DQUxMIE9RdWVyeUNvbnRyb2xsZXI6OmNvbnZlcnRGYXN0UHJvcGVydHlWYWx1ZSggQW55JiBvX3JDb252ZXJ0ZWRWYWx1ZSwgQW55JiBvX3JPbGRWYWx1ZSwgc2FsX0ludDMyIGlfbkhhbmRsZSwgY29uc3QgQW55JiBpX3JWYWx1ZSApIHRocm93IChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24pCnsKICAgIHJldHVybiBPUHJvcGVydHlDb250YWluZXI6OmNvbnZlcnRGYXN0UHJvcGVydHlWYWx1ZSggb19yQ29udmVydGVkVmFsdWUsIG9fck9sZFZhbHVlLCBpX25IYW5kbGUsIGlfclZhbHVlICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIE9RdWVyeUNvbnRyb2xsZXI6OnNldEZhc3RQcm9wZXJ0eVZhbHVlX05vQnJvYWRjYXN0KCBzYWxfSW50MzIgaV9uSGFuZGxlLCBjb25zdCBBbnkmIGlfclZhbHVlICkgdGhyb3cgKCBFeGNlcHRpb24gKQp7CiAgICBPUHJvcGVydHlDb250YWluZXI6OnNldEZhc3RQcm9wZXJ0eVZhbHVlX05vQnJvYWRjYXN0KCBpX25IYW5kbGUsIGlfclZhbHVlICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIE9RdWVyeUNvbnRyb2xsZXI6OmdldEZhc3RQcm9wZXJ0eVZhbHVlKCBBbnkmIG9fclZhbHVlLCBzYWxfSW50MzIgaV9uSGFuZGxlICkgY29uc3QKewogICAgc3dpdGNoICggaV9uSGFuZGxlICkKICAgIHsKICAgIGNhc2UgUFJPUEVSVFlfSURfQ1VSUkVOVF9RVUVSWV9ERVNJR046CiAgICB7CiAgICAgICAgOjpjb21waGVscGVyOjpOYW1lZFZhbHVlQ29sbGVjdGlvbiBhQ3VycmVudERlc2lnbjsKICAgICAgICBhQ3VycmVudERlc2lnbi5wdXQoICJHcmFwaGljYWxEZXNpZ24iLCBpc0dyYXBoaWNhbERlc2lnbigpICk7CiAgICAgICAgYUN1cnJlbnREZXNpZ24ucHV0KCAoOjpydGw6Ok9VU3RyaW5nKVBST1BFUlRZX0VTQ0FQRV9QUk9DRVNTSU5HLCBtX2JFc2NhcGVQcm9jZXNzaW5nICk7CgogICAgICAgIGlmICggaXNHcmFwaGljYWxEZXNpZ24oKSApCiAgICAgICAgewogICAgICAgICAgICBnZXRDb250YWluZXIoKS0+U2F2ZVVJQ29uZmlnKCk7CgkgICAgICAgIHNhdmVWaWV3U2V0dGluZ3MoIGFDdXJyZW50RGVzaWduLCB0cnVlICk7CiAgICAgICAgICAgIGFDdXJyZW50RGVzaWduLnB1dCggIlN0YXRlbWVudCIsIG1fc1N0YXRlbWVudCApOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBhQ3VycmVudERlc2lnbi5wdXQoICJTdGF0ZW1lbnQiLCBnZXRDb250YWluZXIoKS0+Z2V0U3RhdGVtZW50KCkgKTsKICAgICAgICB9CgogICAgICAgIG9fclZhbHVlIDw8PSBhQ3VycmVudERlc2lnbi5nZXRQcm9wZXJ0eVZhbHVlcygpOwogICAgfQogICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBPUHJvcGVydHlDb250YWluZXI6OmdldEZhc3RQcm9wZXJ0eVZhbHVlKCBvX3JWYWx1ZSwgaV9uSGFuZGxlICk7CiAgICAgICAgYnJlYWs7CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo6OmNwcHU6OklQcm9wZXJ0eUFycmF5SGVscGVyJiBPUXVlcnlDb250cm9sbGVyOjpnZXRJbmZvSGVscGVyKCkKewoJcmV0dXJuICpjb25zdF9jYXN0PCBPUXVlcnlDb250cm9sbGVyKiA+KCB0aGlzICktPmdldEFycmF5SGVscGVyKCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpjcHB1OjpJUHJvcGVydHlBcnJheUhlbHBlciogT1F1ZXJ5Q29udHJvbGxlcjo6Y3JlYXRlQXJyYXlIZWxwZXIoICkgY29uc3QKewoJU2VxdWVuY2U8IFByb3BlcnR5ID4gYVByb3BzOwoJZGVzY3JpYmVQcm9wZXJ0aWVzKCBhUHJvcHMgKTsKCiAgICAvLyBvbmUgYWRkaXRpb25hbCBwcm9wZXJ0eToKICAgIGNvbnN0IHNhbF9JbnQzMiBuTGVuZ3RoID0gYVByb3BzLmdldExlbmd0aCgpOwogICAgYVByb3BzLnJlYWxsb2MoIG5MZW5ndGggKyAxICk7CiAgICBhUHJvcHNbIG5MZW5ndGggXSA9IFByb3BlcnR5KAogICAgICAgIDo6cnRsOjpPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCAiQ3VycmVudFF1ZXJ5RGVzaWduIiApICksCiAgICAgICAgUFJPUEVSVFlfSURfQ1VSUkVOVF9RVUVSWV9ERVNJR04sCiAgICAgICAgOjpjcHB1OjpVbm9UeXBlPCBTZXF1ZW5jZTwgUHJvcGVydHlWYWx1ZSA+ID46OmdldCgpLAogICAgICAgIFByb3BlcnR5QXR0cmlidXRlOjpSRUFET05MWQogICAgKTsKCiAgICA6OnN0ZDo6c29ydCgKICAgICAgICBhUHJvcHMuZ2V0QXJyYXkoKSwKICAgICAgICBhUHJvcHMuZ2V0QXJyYXkoKSArIGFQcm9wcy5nZXRMZW5ndGgoKSwKICAgICAgICA6OmNvbXBoZWxwZXI6OlByb3BlcnR5Q29tcGFyZUJ5TmFtZSgpCiAgICApOwoKCXJldHVybiBuZXcgOjpjcHB1OjpPUHJvcGVydHlBcnJheUhlbHBlcihhUHJvcHMpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OmRlbGV0ZUl0ZXJhdG9yKCkKewoJaWYobV9wU3FsSXRlcmF0b3IpCgl7CgkJZGVsZXRlIG1fcFNxbEl0ZXJhdG9yLT5nZXRQYXJzZVRyZWUoKTsKCQltX3BTcWxJdGVyYXRvci0+ZGlzcG9zZSgpOwoJCWRlbGV0ZSBtX3BTcWxJdGVyYXRvcjsKCQltX3BTcWxJdGVyYXRvciA9IE5VTEw7Cgl9Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpkaXNwb3NpbmcoKQp7CiAgICBPUXVlcnlDb250cm9sbGVyX1BCYXNlOjpkaXNwb3NpbmcoKTsKCglkZWxldGVJdGVyYXRvcigpOwoKCWRlbGV0ZSBtX3BQYXJzZUNvbnRleHQ7CgoJY2xlYXJGaWVsZHMoKTsKCU9UYWJsZUZpZWxkcygpLnN3YXAobV92VW5Vc2VkRmllbGRzRGVzYyk7CgoJOjpjb21waGVscGVyOjpkaXNwb3NlQ29tcG9uZW50KG1feENvbXBvc2VyKTsKCU9Kb2luQ29udHJvbGxlcjo6ZGlzcG9zaW5nKCk7CiAgICBPUXVlcnlDb250cm9sbGVyX1BCYXNlOjpkaXNwb3NpbmcoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OmNsZWFyRmllbGRzKCkKewoJT1RhYmxlRmllbGRzKCkuc3dhcChtX3ZUYWJsZUZpZWxkRGVzYyk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KRmVhdHVyZVN0YXRlIE9RdWVyeUNvbnRyb2xsZXI6OkdldFN0YXRlKHNhbF91SW50MTYgX25JZCkgY29uc3QKewoJRmVhdHVyZVN0YXRlIGFSZXR1cm47CglhUmV0dXJuLmJFbmFibGVkID0gc2FsX1RydWU7CgkJLy8gKGRpc2FibGVkIGF1dG9tYXRpY2FsbHkpCgoJc3dpdGNoIChfbklkKQoJewogICAgICAgIGNhc2UgSURfQlJPV1NFUl9FRElURE9DOgogICAgICAgICAgICBpZiAoIGVkaXRpbmdDb21tYW5kKCkgKQogICAgICAgICAgICAgICAgYVJldHVybi5iRW5hYmxlZCA9IHNhbF9GYWxzZTsKICAgICAgICAgICAgZWxzZSBpZiAoIGVkaXRpbmdWaWV3KCkgJiYgIW1feEFsdGVyVmlldy5pcygpICkKICAgICAgICAgICAgICAgIGFSZXR1cm4uYkVuYWJsZWQgPSBzYWxfRmFsc2U7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGFSZXR1cm4gPSBPSm9pbkNvbnRyb2xsZXI6OkdldFN0YXRlKCBfbklkICk7CiAgICAgICAgICAgIGJyZWFrOwoKCQljYXNlIElEX0JST1dTRVJfRVNBQ1BFUFJPQ0VTU0lORzoKCQkJYVJldHVybi5iQ2hlY2tlZCA9ICFtX2JFc2NhcGVQcm9jZXNzaW5nOwoJCQlhUmV0dXJuLmJFbmFibGVkID0gKCBtX3BTcWxJdGVyYXRvciAhPSBOVUxMICkgJiYgIW1fYkdyYXBoaWNhbERlc2lnbjsKCQkJYnJlYWs7CgkJY2FzZSBTSURfUkVMQVRJT05fQUREX1JFTEFUSU9OOgoJCQlhUmV0dXJuLmJFbmFibGVkID0gaXNFZGl0YWJsZSgpICYmIG1fYkdyYXBoaWNhbERlc2lnbiAmJiBtX3ZUYWJsZURhdGEuc2l6ZSgpID4gMTsKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX1NBVkVBU0RPQzoKCQkJYVJldHVybi5iRW5hYmxlZCA9ICFlZGl0aW5nQ29tbWFuZCgpICYmICFlZGl0aW5nVmlldygpICYmICghbV9iR3JhcGhpY2FsRGVzaWduIHx8ICEobV92VGFibGVGaWVsZERlc2MuZW1wdHkoKSB8fCBtX3ZUYWJsZURhdGEuZW1wdHkoKSkpOwoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfU0FWRURPQzoKCQkJYVJldHVybi5iRW5hYmxlZCA9IGltcGxfaXNNb2RpZmllZCgpICYmICghbV9iR3JhcGhpY2FsRGVzaWduIHx8ICEobV92VGFibGVGaWVsZERlc2MuZW1wdHkoKSB8fCBtX3ZUYWJsZURhdGEuZW1wdHkoKSkpOwoJCQlicmVhazsKCQljYXNlIFNJRF9QUklOVERPQ0RJUkVDVDoKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX0NVVDoKCQkJYVJldHVybi5iRW5hYmxlZCA9IGlzRWRpdGFibGUoKSAmJiBnZXRDb250YWluZXIoKSAmJiBnZXRDb250YWluZXIoKS0+aXNDdXRBbGxvd2VkKCk7CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9DT1BZOgoJCQlhUmV0dXJuLmJFbmFibGVkID0gZ2V0Q29udGFpbmVyKCkgJiYgZ2V0Q29udGFpbmVyKCktPmlzQ29weUFsbG93ZWQoKTsKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX1BBU1RFOgoJCQlhUmV0dXJuLmJFbmFibGVkID0gaXNFZGl0YWJsZSgpICYmIGdldENvbnRhaW5lcigpICYmIGdldENvbnRhaW5lcigpLT5pc1Bhc3RlQWxsb3dlZCgpOwoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfU1FMOgoJCQlhUmV0dXJuLmJFbmFibGVkID0gbV9iRXNjYXBlUHJvY2Vzc2luZyAmJiBtX3BTcWxJdGVyYXRvcjsKCQkJYVJldHVybi5iQ2hlY2tlZCA9IG1fYkdyYXBoaWNhbERlc2lnbjsKCQkJYnJlYWs7CgkJY2FzZSBTSURfQlJPV1NFUl9DTEVBUl9RVUVSWToKCQkJYVJldHVybi5iRW5hYmxlZCA9IGlzRWRpdGFibGUoKSAmJiAobV9zU3RhdGVtZW50LmdldExlbmd0aCgpIHx8ICFtX3ZUYWJsZURhdGEuZW1wdHkoKSk7CgkJCWJyZWFrOwoJCWNhc2UgU0lEX1FVRVJZX1ZJRVdfRlVOQ1RJT05TOgoJCWNhc2UgU0lEX1FVRVJZX1ZJRVdfVEFCTEVTOgoJCWNhc2UgU0lEX1FVRVJZX1ZJRVdfQUxJQVNFUzoKCQkJYVJldHVybi5iQ2hlY2tlZCA9IGdldENvbnRhaW5lcigpICYmIGdldENvbnRhaW5lcigpLT5pc1Nsb3RFbmFibGVkKF9uSWQpOwoJCQlhUmV0dXJuLmJFbmFibGVkID0gbV9iR3JhcGhpY2FsRGVzaWduOwoJCQlicmVhazsKCQljYXNlIFNJRF9RVUVSWV9ESVNUSU5DVF9WQUxVRVM6CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSBtX2JHcmFwaGljYWxEZXNpZ24gJiYgaXNFZGl0YWJsZSgpOwoJCQlhUmV0dXJuLmJDaGVja2VkID0gbV9iRGlzdGluY3Q7CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9RVUVSWV9FWEVDVVRFOgoJCQlhUmV0dXJuLmJFbmFibGVkID0gc2FsX1RydWU7CgkJCWJyZWFrOwoJCWNhc2UgU0lEX0RCX1FVRVJZX1BSRVZJRVc6CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSBzYWxfVHJ1ZTsKCQkJYVJldHVybi5iQ2hlY2tlZCA9IGdldENvbnRhaW5lcigpICYmIGdldENvbnRhaW5lcigpLT5nZXRQcmV2aWV3RnJhbWUoKS5pcygpOwoJCQlicmVhazsKI2lmIE9TTF9ERUJVR19MRVZFTCA+IDEKCQljYXNlIElEX0VESVRfUVVFUllfU1FMOgoJCQlicmVhazsKCQljYXNlIElEX0VESVRfUVVFUllfREVTSUdOOgoJCQlicmVhazsKI2VuZGlmCgkJY2FzZSBJRF9CUk9XU0VSX0FERFRBQkxFOgoJCQlpZiAoICFtX2JHcmFwaGljYWxEZXNpZ24gKQoJCQl7CgkJCQlhUmV0dXJuLmJFbmFibGVkID0gc2FsX0ZhbHNlOwoJCQkJYnJlYWs7CgkJCX0KCQkJLy8gcnVuIHRocm91Z2gKCQlkZWZhdWx0OgoJCQlhUmV0dXJuID0gT0pvaW5Db250cm9sbGVyOjpHZXRTdGF0ZShfbklkKTsKCQkJYnJlYWs7Cgl9CglyZXR1cm4gYVJldHVybjsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OkV4ZWN1dGUoc2FsX3VJbnQxNiBfbklkLCBjb25zdCBTZXF1ZW5jZTwgUHJvcGVydHlWYWx1ZSA+JiBhQXJncykKewoJc3dpdGNoKF9uSWQpCgl7CgkJY2FzZSBJRF9CUk9XU0VSX0VTQUNQRVBST0NFU1NJTkc6CiAgICAgICAgICAgIHNldEVzY2FwZVByb2Nlc3NpbmdfZmlyZUV2ZW50KCAhbV9iRXNjYXBlUHJvY2Vzc2luZyApOwogICAgICAgICAgICBpZiAoICFlZGl0aW5nVmlldygpICkKCQkJICAgIHNldE1vZGlmaWVkKHNhbF9UcnVlKTsKCQkJSW52YWxpZGF0ZUZlYXR1cmUoSURfQlJPV1NFUl9TUUwpOwoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfU0FWRUFTRE9DOgoJCWNhc2UgSURfQlJPV1NFUl9TQVZFRE9DOgoJCQlkb1NhdmVBc0RvYyhJRF9CUk9XU0VSX1NBVkVBU0RPQyA9PSBfbklkKTsKCQkJYnJlYWs7CgkJY2FzZSBTSURfUkVMQVRJT05fQUREX1JFTEFUSU9OOgoJCQl7CgkJCQlPSm9pbkRlc2lnblZpZXcqIHBWaWV3ID0gZ2V0Sm9pblZpZXcoKTsKCQkJCWlmKCBwVmlldyApCgkJCQkJc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVWaWV3Kj4ocFZpZXctPmdldFRhYmxlVmlldygpKS0+Y3JlYXRlTmV3Q29ubmVjdGlvbigpOwoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgU0lEX1BSSU5URE9DRElSRUNUOgoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfQ1VUOgoJCQlnZXRDb250YWluZXIoKS0+Y3V0KCk7CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9DT1BZOgoJCQlnZXRDb250YWluZXIoKS0+Y29weSgpOwoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfUEFTVEU6CgkJCWdldENvbnRhaW5lcigpLT5wYXN0ZSgpOwoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfU1FMOgogICAgICAgIHsKCQkJaWYgKCAhZ2V0Q29udGFpbmVyKCktPmNoZWNrU3RhdGVtZW50KCkgKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbkluZm8gYUVycm9yOwoJCQl0cnkKCQkJewogICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIGFFcnJvck1zZzsKICAgICAgICAgICAgICAgIHNldFN0YXRlbWVudF9maXJlRXZlbnQoIGdldENvbnRhaW5lcigpLT5nZXRTdGF0ZW1lbnQoKSApOwoJCQkJaWYoIW1fc1N0YXRlbWVudC5nZXRMZW5ndGgoKSAmJiBtX3BTcWxJdGVyYXRvcikKCQkJCXsKCQkJCQkvLyBjaGFuZ2UgdGhlIHZpZXcgb2YgdGhlIGRhdGEKCQkJCQlkZWxldGUgbV9wU3FsSXRlcmF0b3ItPmdldFBhcnNlVHJlZSgpOwoJCQkJCW1fcFNxbEl0ZXJhdG9yLT5zZXRQYXJzZVRyZWUoTlVMTCk7CgkJCQkJbV9iR3JhcGhpY2FsRGVzaWduID0gIW1fYkdyYXBoaWNhbERlc2lnbjsKCQkJCQlpbXBsX3NldFZpZXdNb2RlKCAmYUVycm9yICk7CgkJCQl9CgkJCQllbHNlCgkJCQl7CiAgICAgICAgICAgICAgICAgICAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBOb2RlID0gbV9hU3FsUGFyc2VyLnBhcnNlVHJlZShhRXJyb3JNc2csbV9zU3RhdGVtZW50LG1fYkdyYXBoaWNhbERlc2lnbik7CgkJCQkJaWYgKCBwTm9kZSApCgkJCQkJewoJCQkJCQlkZWxldGUgbV9wU3FsSXRlcmF0b3ItPmdldFBhcnNlVHJlZSgpOwoJCQkJCQltX3BTcWxJdGVyYXRvci0+c2V0UGFyc2VUcmVlKHBOb2RlKTsKCQkJCQkJbV9wU3FsSXRlcmF0b3ItPnRyYXZlcnNlQWxsKCk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIG1fcFNxbEl0ZXJhdG9yLT5oYXNFcnJvcnMoKSApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFFcnJvciA9IG1fcFNxbEl0ZXJhdG9yLT5nZXRFcnJvcnMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoJCQkJCQllbHNlCgkJCQkJCXsKCQkJCQkJCWNvbnN0IE9TUUxUYWJsZXMmIHhUYWJzID0gbV9wU3FsSXRlcmF0b3ItPmdldFRhYmxlcygpOwoJCQkJCQkJaWYgKCBtX3BTcWxJdGVyYXRvci0+Z2V0U3RhdGVtZW50VHlwZSgpICE9IFNRTF9TVEFURU1FTlRfU0VMRUNUIHx8IHhUYWJzLmJlZ2luKCkgPT0geFRhYnMuZW5kKCkgKQoJCQkJCQkJewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFFcnJvciA9IFNRTEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nKCBNb2R1bGVSZXMoIFNUUl9RUllfTk9TRUxFQ1QgKSApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSggIlMxMDAwIiApICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFueSgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKCQkJCQkJCX0KCQkJCQkJCWVsc2UKCQkJCQkJCXsKCQkJCQkJCQkvLyBjaGFuZ2UgdGhlIHZpZXcgb2YgdGhlIGRhdGEKCQkJCQkJCQltX2JHcmFwaGljYWxEZXNpZ24gPSAhbV9iR3JhcGhpY2FsRGVzaWduOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZyBzTmV3U3RhdGVtZW50OwoJCQkJCQkJCXBOb2RlLT5wYXJzZU5vZGVUb1N0ciggc05ld1N0YXRlbWVudCwgZ2V0Q29ubmVjdGlvbigpICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U3RhdGVtZW50X2ZpcmVFdmVudCggc05ld1N0YXRlbWVudCApOwoJCQkJCQkJCWdldENvbnRhaW5lcigpLT5TYXZlVUlDb25maWcoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3ZUYWJsZUNvbm5lY3Rpb25EYXRhLmNsZWFyKCk7CgkJCQkJCQkJaW1wbF9zZXRWaWV3TW9kZSggJmFFcnJvciApOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJCWVsc2UKCQkJCQl7CiAgICAgICAgICAgICAgICAgICAgICAgIGFFcnJvciA9IFNRTEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyggTW9kdWxlUmVzKCBTVFJfUVJZX1NZTlRBWCApICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nKCBSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oICJTMTAwMCIgKSApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMTAwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFueSgpCiAgICAgICAgICAgICAgICAgICAgICAgICk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWNhdGNoKGNvbnN0IFNRTEV4Y2VwdGlvbiYgZSkKCQkJewogICAgICAgICAgICAgICAgYUVycm9yID0gOjpjcHB1OjpnZXRDYXVnaHRFeGNlcHRpb24oKTsKCQkJfQoJCQljYXRjaChjb25zdCBFeGNlcHRpb24mKQoJCQl7CiAgICAgICAgICAgICAgICBEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwoJCQl9CgogICAgICAgICAgICBpZiAoIGFFcnJvci5pc1ZhbGlkKCkgKQogICAgICAgICAgICAgICAgc2hvd0Vycm9yKCBhRXJyb3IgKTsKCgkJCWlmKG1fYkdyYXBoaWNhbERlc2lnbikKCQkJewoJCQkJSW52YWxpZGF0ZUZlYXR1cmUoSURfQlJPV1NFUl9BRERUQUJMRSk7CgkJCQlJbnZhbGlkYXRlRmVhdHVyZShTSURfUkVMQVRJT05fQUREX1JFTEFUSU9OKTsKCQkJfQogICAgICAgIH0KICAgICAgICBicmVhazsKCQljYXNlIFNJRF9CUk9XU0VSX0NMRUFSX1FVRVJZOgoJCQl7CgkJCQlHZXRVbmRvTWFuYWdlcigpLkVudGVyTGlzdEFjdGlvbiggU3RyaW5nKCBNb2R1bGVSZXMoU1RSX1FVRVJZX1VORE9fVEFCV0lOREVMRVRFKSApLCBTdHJpbmcoKSApOwoJCQkJZ2V0Q29udGFpbmVyKCktPmNsZWFyKCk7CgkJCQlHZXRVbmRvTWFuYWdlcigpLkxlYXZlTGlzdEFjdGlvbigpOwoKICAgICAgICAgICAgICAgIHNldFN0YXRlbWVudF9maXJlRXZlbnQoIDo6cnRsOjpPVVN0cmluZygpICk7CgkJCQlpZihtX2JHcmFwaGljYWxEZXNpZ24pCgkJCQkJSW52YWxpZGF0ZUZlYXR1cmUoSURfQlJPV1NFUl9BRERUQUJMRSk7CgkJCX0KCQkJLy8JSW52YWxpZGF0ZUZlYXR1cmUoSURfQlJPV1NFUl9RVUVSWV9FWEVDVVRFKTsKCQkJYnJlYWs7CgkJY2FzZSBTSURfUVVFUllfVklFV19GVU5DVElPTlM6CgkJY2FzZSBTSURfUVVFUllfVklFV19UQUJMRVM6CgkJY2FzZSBTSURfUVVFUllfVklFV19BTElBU0VTOgoJCQlnZXRDb250YWluZXIoKS0+c2V0U2xvdEVuYWJsZWQoX25JZCwhZ2V0Q29udGFpbmVyKCktPmlzU2xvdEVuYWJsZWQoX25JZCkpOwoJCQlzZXRNb2RpZmllZChzYWxfVHJ1ZSk7CgkJCWJyZWFrOwoJCWNhc2UgU0lEX1FVRVJZX0RJU1RJTkNUX1ZBTFVFUzoKCQkJbV9iRGlzdGluY3QgPSAhbV9iRGlzdGluY3Q7CgkJCXNldE1vZGlmaWVkKHNhbF9UcnVlKTsKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX1FVRVJZX0VYRUNVVEU6CgkJCWlmICggZ2V0Q29udGFpbmVyKCktPmNoZWNrU3RhdGVtZW50KCkgKQoJCQkJZXhlY3V0ZVF1ZXJ5KCk7CgkJCWJyZWFrOwoJCWNhc2UgU0lEX0RCX1FVRVJZX1BSRVZJRVc6CgkJCXRyeQoJCQl7CiAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlhDbG9zZWFibGUgPiB4Q2xvc2VGcmFtZSggZ2V0Q29udGFpbmVyKCktPmdldFByZXZpZXdGcmFtZSgpLCBVTk9fUVVFUlkgKTsKCQkJCWlmICggeENsb3NlRnJhbWUuaXMoKSApCgkJCQl7CiAgICAgICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB4Q2xvc2VGcmFtZS0+Y2xvc2UoIHNhbF9UcnVlICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNhdGNoKCBjb25zdCBFeGNlcHRpb24mICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgCU9TTF9FTlNVUkUoIHNhbF9GYWxzZSwgIk9RdWVyeUNvbnRyb2xsZXI6OkV4ZWN1dGUoU0lEX0RCX1FVRVJZX1BSRVZJRVcpOiAqbm9ib2R5KiBpcyBleHBlY3RlZCB0byB2ZXRvIGNsb3NpbmcgdGhlIHByZXZpZXcgZnJhbWUhIiApOwogICAgICAgICAgICAgICAgICAgIH0KCQkJCX0KCQkJCWVsc2UKCQkJCQlFeGVjdXRlKElEX0JST1dTRVJfUVVFUllfRVhFQ1VURSxTZXF1ZW5jZTwgUHJvcGVydHlWYWx1ZSA+KCkpOwoJCQl9CgkJCWNhdGNoKEV4Y2VwdGlvbiYpCgkJCXsKCQkJfQoJCQlicmVhazsKCQljYXNlIElEX1FVRVJZX1pPT01fSU46CgkJCXsKLy8JCQkJbV9hWm9vbSAqPSBGcmFjdGlvbigxLDEwKTsKLy8JCQkJc3RhdGljX2Nhc3Q8T1F1ZXJ5Vmlld1N3aXRjaCo+KGdldFZpZXcoKSktPnpvb21UYWJsZVZpZXcobV9hWm9vbSk7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBJRF9RVUVSWV9aT09NX09VVDoKCQkJewovLwkJCQlpZihtX2Fab29tICE9IEZyYWN0aW9uKDEsMSkpCi8vCQkJCQltX2Fab29tIC89IEZyYWN0aW9uKDEsMTApOwovLwkJCQlzdGF0aWNfY2FzdDxPUXVlcnlWaWV3U3dpdGNoKj4oZ2V0VmlldygpKS0+em9vbVRhYmxlVmlldyhtX2Fab29tKTsKCQkJfQoJCQlicmVhazsKI2lmIE9TTF9ERUJVR19MRVZFTCA+IDEKCQljYXNlIElEX0VESVRfUVVFUllfREVTSUdOOgoJCWNhc2UgSURfRURJVF9RVUVSWV9TUUw6CgkJCXsKCQkJCTo6cnRsOjpPVVN0cmluZyBhRXJyb3JNc2c7CiAgICAgICAgICAgICAgICBzZXRTdGF0ZW1lbnRfZmlyZUV2ZW50KCBnZXRDb250YWluZXIoKS0+Z2V0U3RhdGVtZW50KCkgKTsKCQkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwTm9kZSA9IG1fYVNxbFBhcnNlci5wYXJzZVRyZWUoIGFFcnJvck1zZywgbV9zU3RhdGVtZW50LCBtX2JHcmFwaGljYWxEZXNpZ24gKTsKCQkJCWlmICggcE5vZGUgKQoJCQkJewoJCQkJCVdpbmRvdyogcFZpZXcgPSBnZXRWaWV3KCk7CgkJCQkJTW9kYWxEaWFsb2cqIHBXaW5kb3cgPSBuZXcgTW9kYWxEaWFsb2coIHBWaWV3LCBXQl9TVERNT0RBTCB8IFdCX1NJWkVNT1ZFIHwgV0JfQ0VOVEVSICk7CiAgICAgICAgICAgICAgICAgICAgcFdpbmRvdy0+U2V0U2l6ZVBpeGVsKCA6OlNpemUoIHBWaWV3LT5HZXRTaXplUGl4ZWwoKS5XaWR0aCgpIC8gMiwgcFZpZXctPkdldFNpemVQaXhlbCgpLkhlaWdodCgpIC8gMiApICk7CgkJCQkJU3ZUcmVlTGlzdEJveCogcFRyZWVCb3ggPSBuZXcgU3ZUcmVlTGlzdEJveCggcFdpbmRvdywgV0JfQk9SREVSIHwgV0JfSEFTTElORVMgfCBXQl9IQVNCVVRUT05TIHwgV0JfSEFTQlVUVE9OU0FUUk9PVCB8IFdCX0hBU0xJTkVTQVRST09UIHwgV0JfVlNDUk9MTCApOwogICAgICAgICAgICAgICAgICAgIHBUcmVlQm94LT5TZXRQb3NTaXplUGl4ZWwoIDo6UG9pbnQoIDYsIDYgKSwgOjpTaXplKCBwV2luZG93LT5HZXRTaXplUGl4ZWwoKS5XaWR0aCgpIC0gMTIsIHBXaW5kb3ctPkdldFNpemVQaXhlbCgpLkhlaWdodCgpIC0gMTIgKSk7CiAgICAgICAgICAgICAgICAgICAgcFRyZWVCb3gtPlNldE5vZGVEZWZhdWx0SW1hZ2VzKCk7CgoJCQkJCWlmICggX25JZCA9PSBJRF9FRElUX1FVRVJZX0RFU0lHTiApCgkJCQkJewoJCQkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFRlbXAgPSBwTm9kZSA/IHBOb2RlLT5nZXRDaGlsZCgzKS0+Z2V0Q2hpbGQoMSkgOiBOVUxMOwoJCQkJCQkvLyBubyB3aGVyZSBjbGF1c2UgZm91bmQKCQkJCQkJaWYgKCBwVGVtcCAmJiAhcFRlbXAtPmlzTGVhZigpICkKCQkJCQkJewoJCQkJCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKiBwQ29uZGl0aW9uID0gcFRlbXAtPmdldENoaWxkKDEpOwoJCQkJCQkJaWYgKCBwQ29uZGl0aW9uICkgLy8gbm8gd2hlcmUgY2xhdXNlCgkJCQkJCQl7CgkJCQkJCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGU6Om5lZ2F0ZVNlYXJjaENvbmRpdGlvbihwQ29uZGl0aW9uKTsKCQkJCQkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqcE5vZGVUbXAgPSBwVGVtcC0+Z2V0Q2hpbGQoMSk7CgoJCQkJCQkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlOjpkaXNqdW5jdGl2ZU5vcm1hbEZvcm0ocE5vZGVUbXApOwoJCQkJCQkJCXBOb2RlVG1wID0gcFRlbXAtPmdldENoaWxkKDEpOwoJCQkJCQkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlOjphYnNvcnB0aW9ucyhwTm9kZVRtcCk7CgkJCQkJCQkJcE5vZGVUbXAgPSBwVGVtcC0+Z2V0Q2hpbGQoMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT1NRTFBhcnNlTm9kZTo6Y29tcHJlc3MocE5vZGVUbXApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlVG1wID0gcFRlbXAtPmdldENoaWxkKDEpOwoJCQkJCQkJfSAvLyBpZiAoIHBDb25kaXRpb24gKSAvLyBubyB3aGVyZSBjbGF1c2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZyBzVGVtcDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlLT5wYXJzZU5vZGVUb1N0cihzVGVtcCxnZXRDb25uZWN0aW9uKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q29udGFpbmVyKCktPnNldFN0YXRlbWVudChzVGVtcCk7CgoJCQkJCQl9CgkJCQkJfQoKCQkJCQlpbnNlcnRQYXJzZVRyZWUocFRyZWVCb3gscE5vZGUpOwoKCQkJCQlwVHJlZUJveC0+U2hvdygpOwoJCQkJCXBXaW5kb3ctPkV4ZWN1dGUoKTsKCgkJCQkJZGVsZXRlIHBUcmVlQm94OwoJCQkJCWRlbGV0ZSBwV2luZG93OwoJCQkJCWRlbGV0ZSBwTm9kZTsKCQkJCX0KCQkJCWJyZWFrOwoJCQl9CiNlbmRpZgoJCWRlZmF1bHQ6CgkJCU9Kb2luQ29udHJvbGxlcjo6RXhlY3V0ZShfbklkLGFBcmdzKTsKCQkJcmV0dXJuOyAvLyBlbHNlIHdlIHdvdWxkIGludmFsaWRhdGUgdHdpY2UKCX0KCUludmFsaWRhdGVGZWF0dXJlKF9uSWQpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OmltcGxfc2hvd0F1dG9TUUxWaWV3RXJyb3IoIGNvbnN0IDo6Y29tOjpzdW46OnN0YXI6OnVubzo6QW55JiBfckVycm9yRGV0YWlscyApCnsKICAgIFNRTENvbnRleHQgYUVycm9yQ29udGV4dDsKICAgIGFFcnJvckNvbnRleHQuTWVzc2FnZSA9IGxjbF9nZXRPYmplY3RSZXNvdXJjZVN0cmluZyggU1RSX0VSUk9SX1BBUlNJTkdfU1RBVEVNRU5ULCBtX25Db21tYW5kVHlwZSApOwogICAgYUVycm9yQ29udGV4dC5Db250ZXh0ID0gKnRoaXM7CiAgICBhRXJyb3JDb250ZXh0LkRldGFpbHMgPSBsY2xfZ2V0T2JqZWN0UmVzb3VyY2VTdHJpbmcoIFNUUl9JTkZPX09QRU5JTkdfSU5fU1FMX1ZJRVcsIG1fbkNvbW1hbmRUeXBlICk7CiAgICBhRXJyb3JDb250ZXh0Lk5leHRFeGNlcHRpb24gPSBfckVycm9yRGV0YWlsczsKICAgIHNob3dFcnJvciggYUVycm9yQ29udGV4dCApOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpib29sIE9RdWVyeUNvbnRyb2xsZXI6OmltcGxfc2V0Vmlld01vZGUoIDo6ZGJ0b29sczo6U1FMRXhjZXB0aW9uSW5mbyogX3BFcnJvckluZm8gKQp7CiAgICBPU0xfUFJFQ09ORCggZ2V0Q29udGFpbmVyKCksICJPUXVlcnlDb250cm9sbGVyOjppbXBsX3NldFZpZXdNb2RlOiBpbGxlZ2FsIGNhbGwhIiApOwoKICAgIGJvb2wgd2FzTW9kaWZpZWQgPSBpc01vZGlmaWVkKCk7CgogICAgU1FMRXhjZXB0aW9uSW5mbyBhRXJyb3I7CiAgICBib29sIGJTdWNjZXNzID0gZ2V0Q29udGFpbmVyKCktPnN3aXRjaFZpZXcoICZhRXJyb3IgKTsKICAgIGlmICggIWJTdWNjZXNzICkKCXsKCQltX2JHcmFwaGljYWxEZXNpZ24gPSAhbV9iR3JhcGhpY2FsRGVzaWduOwogICAgICAgIC8vIHJlc3RvcmUgb2xkIHN0YXRlCgkJZ2V0Q29udGFpbmVyKCktPnN3aXRjaFZpZXcoIE5VTEwgKTsKICAgICAgICAgICAgLy8gZG9uJ3QgcGFzcyAmYUVycm9yIGhlcmUsIHRoaXMgd291bGQgb3ZlcndyaXRlIHRoZSBlcnJvciB3aGljaCB0aGUgZmlyc3Qgc3dpdGNoVmlldyBjYWxsCiAgICAgICAgICAgIC8vIHJldHVybmVkIGluIHRoaXMgbG9jYXRpb24uCiAgICAgICAgaWYgKCBfcEVycm9ySW5mbyApCiAgICAgICAgICAgICpfcEVycm9ySW5mbyA9IGFFcnJvcjsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHNob3dFcnJvciggYUVycm9yICk7Cgl9CgllbHNlCiAgICB7CiAgICAgICAgZW5zdXJlVG9vbGJhcnMoICp0aGlzLCBtX2JHcmFwaGljYWxEZXNpZ24gKTsKICAgIH0KCiAgICBzZXRNb2RpZmllZCggd2FzTW9kaWZpZWQgKTsKICAgIHJldHVybiBiU3VjY2VzczsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjppbXBsX2luaXRpYWxpemUoKQp7CglPSm9pbkNvbnRyb2xsZXI6OmltcGxfaW5pdGlhbGl6ZSgpOwoKICAgIGNvbnN0IE5hbWVkVmFsdWVDb2xsZWN0aW9uJiByQXJndW1lbnRzKCBnZXRJbml0UGFyYW1zKCkgKTsKCiAgICA6OnJ0bDo6T1VTdHJpbmcgc0NvbW1hbmQ7CiAgICBtX25Db21tYW5kVHlwZSA9IENvbW1hbmRUeXBlOjpRVUVSWTsKCiAgICAvLyCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsAogICAgLy8gsCByZWFkaW5nIHBhcmFtZXRlcnMKICAgIC8vILCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwCiAgICAvLyBsZWdhY3kgcGFyYW1ldGVycyBmaXJzdCAobGF0ZXIgb3ZlcndyaXR0ZW4gYnkgcmVndWxhciBwYXJhbWV0ZXJzKQogICAgOjpydGw6Ok9VU3RyaW5nIHNJbmRlcGVuZGVudFNRTENvbW1hbmQ7CiAgICBpZiAoIHJBcmd1bWVudHMuZ2V0X2Vuc3VyZVR5cGUoICJJbmRlcGVuZGVudFNRTENvbW1hbmQiLCBzSW5kZXBlbmRlbnRTUUxDb21tYW5kICkgKQogICAgewogICAgICAgIE9TTF9FTlNVUkUoIGZhbHNlLCAiT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9pbml0aWFsaXplOiBJbmRlcGVuZGVudFNRTENvbW1hbmQgaXMgcmVnb2duaXplZCBmb3IgY29tcGF0aWJpbGl0eSBvbmx5ISIgKTsKICAgICAgICBzQ29tbWFuZCA9IHNJbmRlcGVuZGVudFNRTENvbW1hbmQ7CiAgICAgICAgbV9uQ29tbWFuZFR5cGUgPSBDb21tYW5kVHlwZTo6Q09NTUFORDsKICAgIH0KCiAgICA6OnJ0bDo6T1VTdHJpbmcgc0N1cnJlbnRRdWVyeTsKICAgIGlmICggckFyZ3VtZW50cy5nZXRfZW5zdXJlVHlwZSggIkN1cnJlbnRRdWVyeSIsIHNDdXJyZW50UXVlcnkgKSApCiAgICB7CiAgICAgICAgT1NMX0VOU1VSRSggZmFsc2UsICJPUXVlcnlDb250cm9sbGVyOjppbXBsX2luaXRpYWxpemU6IEN1cnJlbnRRdWVyeSBpcyByZWdvZ25pemVkIGZvciBjb21wYXRpYmlsaXR5IG9ubHkhIiApOwogICAgICAgIHNDb21tYW5kID0gc0N1cnJlbnRRdWVyeTsKICAgICAgICBtX25Db21tYW5kVHlwZSA9IENvbW1hbmRUeXBlOjpRVUVSWTsKICAgIH0KCiAgICBzYWxfQm9vbCBiQ3JlYXRlVmlldyggc2FsX0ZhbHNlICk7CiAgICBpZiAoIHJBcmd1bWVudHMuZ2V0X2Vuc3VyZVR5cGUoICJDcmVhdGVWaWV3IiwgYkNyZWF0ZVZpZXcgKSAmJiBiQ3JlYXRlVmlldyApCiAgICB7CiAgICAgICAgT1NMX0VOU1VSRSggZmFsc2UsICJPUXVlcnlDb250cm9sbGVyOjppbXBsX2luaXRpYWxpemU6IEN1cnJlbnRRdWVyeSBpcyByZWdvZ25pemVkIGZvciBjb21wYXRpYmlsaXR5IG9ubHkhIiApOwogICAgICAgIG1fbkNvbW1hbmRUeXBlID0gQ29tbWFuZFR5cGU6OlRBQkxFOwogICAgfQoKICAgIC8vIG5vbi1sZWdhY3kgcGFyYW1ldGVycyB3aGljaCBvdmVyd3JpdGUgdGhlIGxlZ2FjeSBwYXJhbWV0ZXJzCiAgICByQXJndW1lbnRzLmdldF9lbnN1cmVUeXBlKCAoOjpydGw6Ok9VU3RyaW5nKVBST1BFUlRZX0NPTU1BTkQsIHNDb21tYW5kICk7CiAgICByQXJndW1lbnRzLmdldF9lbnN1cmVUeXBlKCAoOjpydGw6Ok9VU3RyaW5nKVBST1BFUlRZX0NPTU1BTkRfVFlQRSwgbV9uQ29tbWFuZFR5cGUgKTsKCiAgICAvLyB0cmFuc2xhdGUgQ29tbWFuZC9UeXBlIGludG8gcHJvcGVyIG1lbWJlcnMKICAgIC8vIFRPRE8vTGF0ZXI6IGFsbCB0aGlzIChpbmNsdWRpbmcgdGhvc2UgbWVtYmVycykgc2hvdWxkIGJlIGhpZGRlbiBiZWhpbmQgc29tZSBhYnN0YWN0IGludGVyZmFjZSwKICAgIC8vIHdoaWNoIGlzIGltcGxlbWVudGVkIGZvciBhbGwgdGhlIHRocmVlIGNvbW1hbmRzCiAgICBzd2l0Y2ggKCBtX25Db21tYW5kVHlwZSApCiAgICB7CiAgICBjYXNlIENvbW1hbmRUeXBlOjpRVUVSWToKICAgICAgICBtX3NOYW1lID0gc0NvbW1hbmQ7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENvbW1hbmRUeXBlOjpUQUJMRToKICAgICAgICBtX3NOYW1lID0gc0NvbW1hbmQ7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENvbW1hbmRUeXBlOjpDT01NQU5EOgogICAgICAgIHNldFN0YXRlbWVudF9maXJlRXZlbnQoIHNDb21tYW5kICk7CiAgICAgICAgbV9zTmFtZSA9IDo6cnRsOjpPVVN0cmluZygpOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBPU0xfRU5TVVJFKCBmYWxzZSwgIk9RdWVyeUNvbnRyb2xsZXI6OmltcGxfaW5pdGlhbGl6ZTogbG9naWMgZXJyb3IgaW4gY29kZSEiICk7CiAgICAgICAgdGhyb3cgUnVudGltZUV4Y2VwdGlvbigpOwogICAgfQoKICAgIC8vIG1vcmUgbGVnYWN5IHBhcmFtZXRlcnMKICAgIHNhbF9Cb29sIGJHcmFwaGljYWxEZXNpZ24oIHNhbF9UcnVlICk7CiAgICBpZiAoIHJBcmd1bWVudHMuZ2V0X2Vuc3VyZVR5cGUoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfUVVFUllERVNJR05WSUVXLCBiR3JhcGhpY2FsRGVzaWduICkgKQogICAgewogICAgICAgIE9TTF9FTlNVUkUoIGZhbHNlLCAiT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9pbml0aWFsaXplOiBRdWVyeURlc2lnblZpZXcgaXMgcmVnb2duaXplZCBmb3IgY29tcGF0aWJpbGl0eSBvbmx5ISIgKTsKICAgICAgICBtX2JHcmFwaGljYWxEZXNpZ24gPSBiR3JhcGhpY2FsRGVzaWduOwogICAgfQoKICAgIC8vIG1vcmUgbm9uLWxlZ2FjeQogICAgckFyZ3VtZW50cy5nZXRfZW5zdXJlVHlwZSggKDo6cnRsOjpPVVN0cmluZylQUk9QRVJUWV9HUkFQSElDQUxfREVTSUdOLCBtX2JHcmFwaGljYWxEZXNpZ24gKTsKCiAgICBib29sIGJFc2NhcGVQcm9jZXNzaW5nKCBzYWxfVHJ1ZSApOwogICAgaWYgKCByQXJndW1lbnRzLmdldF9lbnN1cmVUeXBlKCAoOjpydGw6Ok9VU3RyaW5nKVBST1BFUlRZX0VTQ0FQRV9QUk9DRVNTSU5HLCBiRXNjYXBlUHJvY2Vzc2luZyApICkKICAgIHsKICAgICAgICBzZXRFc2NhcGVQcm9jZXNzaW5nX2ZpcmVFdmVudCggYkVzY2FwZVByb2Nlc3NpbmcgKTsKCiAgICAgICAgT1NMX0VOU1VSRSggbV9iRXNjYXBlUHJvY2Vzc2luZyB8fCAhbV9iR3JhcGhpY2FsRGVzaWduLCAiT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9pbml0aWFsaXplOiBjYW4ndCBkbyB0aGUgZ3JhcGhpY2FsIGRlc2lnbiB3aXRob3V0IGVzY2FwZSBwcm9jZXNzaW5nISIgKTsKICAgICAgICBpZiAoICFtX2JFc2NhcGVQcm9jZXNzaW5nICkKICAgICAgICAgICAgbV9iR3JhcGhpY2FsRGVzaWduID0gZmFsc2U7CiAgICB9CgogICAgLy8gLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4KICAgIC8vIC4gaW5pdGlhbCBkZXNpZ24KICAgIGJvb2wgYkZvcmNlSW5pdGlhbERlc2lnbiA9IGZhbHNlOwogICAgU2VxdWVuY2U8IFByb3BlcnR5VmFsdWUgPiBhQ3VycmVudFF1ZXJ5RGVzaWduUHJvcHM7CiAgICBhQ3VycmVudFF1ZXJ5RGVzaWduUHJvcHMgPSByQXJndW1lbnRzLmdldE9yRGVmYXVsdCggIkN1cnJlbnRRdWVyeURlc2lnbiIsIGFDdXJyZW50UXVlcnlEZXNpZ25Qcm9wcyApOwoKICAgIGlmICggYUN1cnJlbnRRdWVyeURlc2lnblByb3BzLmdldExlbmd0aCgpICkKICAgIHsKICAgICAgICA6OmNvbXBoZWxwZXI6Ok5hbWVkVmFsdWVDb2xsZWN0aW9uIGFDdXJyZW50UXVlcnlEZXNpZ24oIGFDdXJyZW50UXVlcnlEZXNpZ25Qcm9wcyApOwogICAgICAgIGlmICggYUN1cnJlbnRRdWVyeURlc2lnbi5oYXMoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfR1JBUEhJQ0FMX0RFU0lHTiApICkKICAgICAgICB7CiAgICAgICAgICAgIGFDdXJyZW50UXVlcnlEZXNpZ24uZ2V0X2Vuc3VyZVR5cGUoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfR1JBUEhJQ0FMX0RFU0lHTiwgbV9iR3JhcGhpY2FsRGVzaWduICk7CiAgICAgICAgfQogICAgICAgIGlmICggYUN1cnJlbnRRdWVyeURlc2lnbi5oYXMoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfRVNDQVBFX1BST0NFU1NJTkcgKSApCiAgICAgICAgewogICAgICAgICAgICBhQ3VycmVudFF1ZXJ5RGVzaWduLmdldF9lbnN1cmVUeXBlKCAoOjpydGw6Ok9VU3RyaW5nKVBST1BFUlRZX0VTQ0FQRV9QUk9DRVNTSU5HLCBtX2JFc2NhcGVQcm9jZXNzaW5nICk7CiAgICAgICAgfQogICAgICAgIGlmICggYUN1cnJlbnRRdWVyeURlc2lnbi5oYXMoICJTdGF0ZW1lbnQiICkgKQogICAgICAgIHsKICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNTdGF0ZW1lbnQ7CiAgICAgICAgICAgIGFDdXJyZW50UXVlcnlEZXNpZ24uZ2V0X2Vuc3VyZVR5cGUoICJTdGF0ZW1lbnQiLCBzU3RhdGVtZW50ICk7CiAgICAgICAgICAgIGFDdXJyZW50UXVlcnlEZXNpZ24ucmVtb3ZlKCAiU3RhdGVtZW50IiApOwogICAgICAgICAgICBzZXRTdGF0ZW1lbnRfZmlyZUV2ZW50KCBzU3RhdGVtZW50ICk7CiAgICAgICAgfQoKICAgICAgICBsb2FkVmlld1NldHRpbmdzKCBhQ3VycmVudFF1ZXJ5RGVzaWduICk7CgogICAgICAgIGJGb3JjZUluaXRpYWxEZXNpZ24gPSB0cnVlOwogICAgfQoKICAgIC8vILCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwCglpZiAoICFlbnN1cmVDb25uZWN0ZWQoIHNhbF9GYWxzZSApICkKCXsJLy8gd2UgaGF2ZSBubyBjb25uZWN0aW9uIHNvIHdoYXQgZWxzZSBzaG91bGQgd2UgZG8KCQltX2JHcmFwaGljYWxEZXNpZ24gPSBzYWxfRmFsc2U7CgkJaWYgKCBlZGl0aW5nVmlldygpICkKCQl7CgkJCWNvbm5lY3Rpb25Mb3N0TWVzc2FnZSgpOwoJCQl0aHJvdyBTUUxFeGNlcHRpb24oKTsKCQl9Cgl9CgogICAgLy8gY2hlY2sgdGhlIHZpZXcgY2FwYWJpbGl0aWVzCglpZiAoIGlzQ29ubmVjdGVkKCkgJiYgZWRpdGluZ1ZpZXcoKSApCgl7CgkJUmVmZXJlbmNlPCBYVmlld3NTdXBwbGllciA+IHhWaWV3c1N1cCggZ2V0Q29ubmVjdGlvbigpLCBVTk9fUVVFUlkgKTsKICAgICAgICBSZWZlcmVuY2U8IFhOYW1lQWNjZXNzID4geFZpZXdzOwogICAgICAgIGlmICggeFZpZXdzU3VwLmlzKCkgKQogICAgICAgICAgICB4Vmlld3MgPSB4Vmlld3NTdXAtPmdldFZpZXdzKCk7CgogICAgICAgIGlmICggIXhWaWV3cy5pcygpICkKCQl7CS8vIHdlIGNhbid0IGNyZWF0ZSB2aWV3cyBzbyB3ZSBhc2sgaWYgdGhlIHVzZXIgd2FudHMgdG8gY3JlYXRlIGEgcXVlcnkgaW5zdGVhZAogICAgICAgICAgICBtX25Db21tYW5kVHlwZSA9IENvbW1hbmRUeXBlOjpRVUVSWTsKCQkJc2FsX0Jvb2wgYkNsb3NlID0gc2FsX0ZhbHNlOwoJCQl7CgkJCQlTdHJpbmcgYVRpdGxlKCBNb2R1bGVSZXMoIFNUUl9RVUVSWURFU0lHTl9OT19WSUVXX1NVUFBPUlQgKSApOwoJCQkJU3RyaW5nIGFNZXNzYWdlKCBNb2R1bGVSZXMoIFNUUl9RVUVSWURFU0lHTl9OT19WSUVXX0FTSyApICk7CgkJCQlPRGF0YVZpZXcqIHBXaW5kb3cgPSBnZXRWaWV3KCk7CgkJCQlPU1FMTWVzc2FnZUJveCBhRGxnKCBwV2luZG93LCBhVGl0bGUsIGFNZXNzYWdlLCBXQl9ZRVNfTk8gfCBXQl9ERUZfWUVTLCBPU1FMTWVzc2FnZUJveDo6UXVlcnkgKTsKCQkJCWJDbG9zZSA9IGFEbGcuRXhlY3V0ZSgpID09IFJFVF9OTzsKCQkJfQoJCQlpZiAoIGJDbG9zZSApCgkJCQl0aHJvdyBWZXRvRXhjZXB0aW9uKCk7CgkJfQoKICAgICAgICAvLyBub3cgaWYgd2UgYXJlIHRvIGVkaXQgYW4gZXhpc3RpbmcgdmlldywgY2hlY2sgd2hldGhlciB0aGlzIGlzIHBvc3NpYmxlCiAgICAgICAgaWYgKCBtX3NOYW1lLmdldExlbmd0aCgpICkKICAgICAgICB7CiAgICAgICAgICAgIEFueSBhVmlldyggeFZpZXdzLT5nZXRCeU5hbWUoIG1fc05hbWUgKSApOwogICAgICAgICAgICAgICAgLy8gd2lsbCB0aHJvdyBpZiB0aGVyZSBpcyBubyBzdWNoIHZpZXcKICAgICAgICAgICAgaWYgKCAhKCBhVmlldyA+Pj0gbV94QWx0ZXJWaWV3ICkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nKCBTdHJpbmcoIE1vZHVsZVJlcyggU1RSX05PX0FMVEVSX1ZJRVdfU1VQUE9SVCApICkgKSwKICAgICAgICAgICAgICAgICAgICAqdGhpcywKICAgICAgICAgICAgICAgICAgICAxCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQoJfQoKCU9TTF9FTlNVUkUoZ2V0RGF0YVNvdXJjZSgpLmlzKCksIk9RdWVyeUNvbnRyb2xsZXI6OmltcGxfaW5pdGlhbGl6ZTogbmVlZCBhIGRhdGFzb3VyY2UhIik7CgoJdHJ5Cgl7CgkJZ2V0Q29udGFpbmVyKCktPmluaXRpYWxpemUoKTsKICAgICAgICBpbXBsX3Jlc2V0KCBiRm9yY2VJbml0aWFsRGVzaWduICk7CgogICAgICAgIFNRTEV4Y2VwdGlvbkluZm8gYUVycm9yOwogICAgICAgIGNvbnN0IGJvb2wgYkF0dGVtcHRlZEdyYXBoaWNhbERlc2lnbiA9IG1fYkdyYXBoaWNhbERlc2lnbjsKCiAgICAgICAgaWYgKCBiRm9yY2VJbml0aWFsRGVzaWduICkKICAgICAgICB7CiAgICAgICAgICAgIGdldENvbnRhaW5lcigpLT5mb3JjZUluaXRpYWxWaWV3KCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGltcGxfc2V0Vmlld01vZGUoICZhRXJyb3IgKTsKICAgICAgICB9CgogICAgICAgIGlmICggYUVycm9yLmlzVmFsaWQoKSAmJiBiQXR0ZW1wdGVkR3JhcGhpY2FsRGVzaWduICYmICFtX2JHcmFwaGljYWxEZXNpZ24gKQogICAgICAgIHsKICAgICAgICAgICAgLy8gd2UgdHJpZWQgaW5pdGlhbGl6aW5nIHRoZSBncmFwaGljYWwgdmlldywgdGhpcyBmYWlsZWQsIGFuZCB3ZSB3ZXJlIGF1dG9tYXRpY2FsbHkgc3dpdGNoZWQgdG8gU1FMCiAgICAgICAgICAgIC8vIHZpZXcgPT4gdGVsbCB0aGlzIHRvIHRoZSB1c2VyCiAgICAgICAgICAgIGlmICggIWVkaXRpbmdWaWV3KCkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbXBsX3Nob3dBdXRvU1FMVmlld0Vycm9yKCBhRXJyb3IuZ2V0KCkgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCgkJQ2xlYXJVbmRvTWFuYWdlcigpOwoKCQlpZiAgKCAgKCBtX2JHcmFwaGljYWxEZXNpZ24gKQogICAgICAgICAgICAmJiAoICAoICFtX3NOYW1lLmdldExlbmd0aCgpICYmICFlZGl0aW5nQ29tbWFuZCgpICkKICAgICAgICAgICAgICAgfHwgKCAhbV9zU3RhdGVtZW50LmdldExlbmd0aCgpICYmIGVkaXRpbmdDb21tYW5kKCkgKQogICAgICAgICAgICAgICApCiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIEFwcGxpY2F0aW9uOjpQb3N0VXNlckV2ZW50KCBMSU5LKCB0aGlzLCBPUXVlcnlDb250cm9sbGVyLCBPbkV4ZWN1dGVBZGRUYWJsZSApICk7CiAgICAgICAgfQoKCQlzZXRNb2RpZmllZChzYWxfRmFsc2UpOwoJfQoJY2F0Y2goU1FMRXhjZXB0aW9uJiBlKQoJewoJCURCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CgkJLy8gd2UgY2F1Z2h0IGFuIGV4Y2VwdGlvbiBzbyB3ZSBzd2l0Y2ggdG8gdGV4dCBvbmx5IG1vZGUKCQl7CgkJCW1fYkdyYXBoaWNhbERlc2lnbiA9IHNhbF9GYWxzZTsKCQkJZ2V0Q29udGFpbmVyKCktPmluaXRpYWxpemUoKTsKCQkJT0RhdGFWaWV3KiBwV2luZG93ID0gZ2V0VmlldygpOwoJCQlPU1FMTWVzc2FnZUJveChwV2luZG93LGUpLkV4ZWN1dGUoKTsKCQl9CgkJdGhyb3c7Cgl9Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6b25Mb2FkZWRNZW51KGNvbnN0IFJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhMYXlvdXRNYW5hZ2VyID4mIC8qX3hMYXlvdXRNYW5hZ2VyKi8pCnsKICAgIGVuc3VyZVRvb2xiYXJzKCAqdGhpcywgbV9iR3JhcGhpY2FsRGVzaWduICk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6cnRsOjpPVVN0cmluZyBPUXVlcnlDb250cm9sbGVyOjpnZXRQcml2YXRlVGl0bGUoICkgY29uc3QKewoJOjpydGw6Ok9VU3RyaW5nIHNOYW1lID0gbV9zTmFtZTsKCWlmICggIXNOYW1lLmdldExlbmd0aCgpICkKCXsKICAgICAgICBpZiAoICFlZGl0aW5nQ29tbWFuZCgpICkKICAgICAgICB7CgkJCTo6dm9zOjpPR3VhcmQgYVNvbGFyR3VhcmQoQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSk7CgkJCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggZ2V0TXV0ZXgoKSApOwogICAgICAgICAgICBTdHJpbmcgYURlZmF1bHROYW1lID0gU3RyaW5nKCBNb2R1bGVSZXMoIGVkaXRpbmdWaWV3KCkgPyBTVFJfVklFV19USVRMRSA6IFNUUl9RUllfVElUTEUgKSApOwoJCQlzTmFtZSA9IGFEZWZhdWx0TmFtZS5HZXRUb2tlbigwLCcgJyk7CiAgICAgICAgICAgIHNOYW1lICs9IDo6cnRsOjpPVVN0cmluZzo6dmFsdWVPZihnZXRDdXJyZW50U3RhcnROdW1iZXIoKSk7CiAgICAgICAgfQoJfQogICAgcmV0dXJuIHNOYW1lOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6c2V0UXVlcnlDb21wb3NlcigpCnsKCWlmKGlzQ29ubmVjdGVkKCkpCgl7CgkJUmVmZXJlbmNlPCBYU1FMUXVlcnlDb21wb3NlckZhY3RvcnkgPiAgeEZhY3RvcnkoZ2V0Q29ubmVjdGlvbigpLCBVTk9fUVVFUlkpOwoJCU9TTF9FTlNVUkUoeEZhY3RvcnkuaXMoKSwiQ29ubmVjdGlvbiBkb2Vzbid0IHN1cHBvcnQgYSBxdWVyeWNvbXBvc2VyIik7CgkJaWYgKCB4RmFjdG9yeS5pcygpICYmIGdldENvbnRhaW5lcigpICkKCQl7CgkJCXRyeQoJCQl7CgkJCQltX3hDb21wb3NlciA9IHhGYWN0b3J5LT5jcmVhdGVRdWVyeUNvbXBvc2VyKCk7CgkJCQlnZXRDb250YWluZXIoKS0+c2V0U3RhdGVtZW50KG1fc1N0YXRlbWVudCk7CgkJCX0KCQkJY2F0Y2ggKEV4Y2VwdGlvbiYpCgkJCXsKCQkJCW1feENvbXBvc2VyID0gTlVMTDsKCQkJfQoJCQlPU0xfRU5TVVJFKG1feENvbXBvc2VyLmlzKCksIk5vIHF1ZXJ5Y29tcG9zZXIgYXZhaWxhYmxlISIpOwoJCQlSZWZlcmVuY2U8WFRhYmxlc1N1cHBsaWVyPiB4VGFibGVzU3VwKGdldENvbm5lY3Rpb24oKSwgVU5PX1FVRVJZKTsKCQkJZGVsZXRlSXRlcmF0b3IoKTsKCQkJbV9wU3FsSXRlcmF0b3IgPSBuZXcgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZVRyZWVJdGVyYXRvciggZ2V0Q29ubmVjdGlvbigpLCB4VGFibGVzU3VwLT5nZXRUYWJsZXMoKSwgbV9hU3FsUGFyc2VyLCBOVUxMICk7CgkJfQoJfQp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9Cb29sIE9RdWVyeUNvbnRyb2xsZXI6OkNvbnN0cnVjdChXaW5kb3cqIHBQYXJlbnQpCnsKCS8vIFRPRE86IHdlIGhhdmUgdG8gY2hlY2sgaWYgd2Ugc2hvdWxkIGNyZWF0ZSB0aGUgdGV4dC0gb3IgdGhlIGRlc2lnbi0gdmlldwoKCXNldFZpZXcoICogbmV3IE9RdWVyeUNvbnRhaW5lcldpbmRvdyggcFBhcmVudCwgKnRoaXMsIGdldE9SQigpICkgKTsKCglyZXR1cm4gT0pvaW5Db250cm9sbGVyOjpDb25zdHJ1Y3QocFBhcmVudCk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk9Kb2luRGVzaWduVmlldyogT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0Sm9pblZpZXcoKQp7CglyZXR1cm4gZ2V0Q29udGFpbmVyKCktPmdldERlc2lnblZpZXcoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OmRlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZXMoKQp7CglPSm9pbkNvbnRyb2xsZXI6OmRlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZXMoKTsKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOlNhdmVBcyIsICAgICAgICAgICAgSURfQlJPV1NFUl9TQVZFQVNET0MsICAgICAgIENvbW1hbmRHcm91cDo6RE9DVU1FTlQgKTsKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOlNiYU5hdGl2ZVNxbCIsICAgICAgSURfQlJPV1NFUl9FU0FDUEVQUk9DRVNTSU5HLENvbW1hbmRHcm91cDo6Rk9STUFUICk7CiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpEQlZpZXdGdW5jdGlvbnMiLCAgIFNJRF9RVUVSWV9WSUVXX0ZVTkNUSU9OUywgICBDb21tYW5kR3JvdXA6OlZJRVcgKTsKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOkRCVmlld1RhYmxlTmFtZXMiLCAgU0lEX1FVRVJZX1ZJRVdfVEFCTEVTLCAgICAgIENvbW1hbmRHcm91cDo6VklFVyApOwogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86REJWaWV3QWxpYXNlcyIsICAgICBTSURfUVVFUllfVklFV19BTElBU0VTLCAgICAgQ29tbWFuZEdyb3VwOjpWSUVXICk7CiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpEQkRpc3RpbmN0VmFsdWVzIiwgIFNJRF9RVUVSWV9ESVNUSU5DVF9WQUxVRVMsICBDb21tYW5kR3JvdXA6OkZPUk1BVCApOwogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86REJDaGFuZ2VEZXNpZ25Nb2RlIixJRF9CUk9XU0VSX1NRTCwgICAgICAgICAgICAgQ29tbWFuZEdyb3VwOjpWSUVXICk7CiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpEQkNsZWFyUXVlcnkiLCAgICAgIFNJRF9CUk9XU0VSX0NMRUFSX1FVRVJZLCAgICBDb21tYW5kR3JvdXA6OkVESVQgKTsKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOlNiYUV4ZWN1dGVTcWwiLCAgICAgSURfQlJPV1NFUl9RVUVSWV9FWEVDVVRFLCAgIENvbW1hbmRHcm91cDo6VklFVyApOwogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86REJBZGRSZWxhdGlvbiIsICAgICBTSURfUkVMQVRJT05fQUREX1JFTEFUSU9OLCAgQ29tbWFuZEdyb3VwOjpFRElUICk7CiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpEQlF1ZXJ5UHJldmlldyIsICAgIFNJRF9EQl9RVUVSWV9QUkVWSUVXLCAgICAgICBDb21tYW5kR3JvdXA6OlZJRVcgKTsKCiNpZiBPU0xfREVCVUdfTEVWRUwgPiAxCiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpEQlNob3dQYXJzZVRyZWUiLCAgIElEX0VESVRfUVVFUllfU1FMICk7CiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpEQk1ha2VEaXNqdW5jdCIsICAgIElEX0VESVRfUVVFUllfREVTSUdOICk7CiNlbmRpZgp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9vbk1vZGlmeUNoYW5nZWQoKQp7CglPSm9pbkNvbnRyb2xsZXI6OmltcGxfb25Nb2RpZnlDaGFuZ2VkKCk7CglJbnZhbGlkYXRlRmVhdHVyZShTSURfQlJPV1NFUl9DTEVBUl9RVUVSWSk7CglJbnZhbGlkYXRlRmVhdHVyZShJRF9CUk9XU0VSX1NBVkVBU0RPQyk7CglJbnZhbGlkYXRlRmVhdHVyZShJRF9CUk9XU0VSX1FVRVJZX0VYRUNVVEUpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgT1F1ZXJ5Q29udHJvbGxlcjo6ZGlzcG9zaW5nKCBjb25zdCBFdmVudE9iamVjdCYgU291cmNlICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKewoJOjp2b3M6Ok9HdWFyZCBhR3VhcmQoQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSk7CgoJaWYgKCBnZXRDb250YWluZXIoKSAmJiBTb3VyY2UuU291cmNlLmlzKCkgKQoJewoJCWlmICggU291cmNlLlNvdXJjZSA9PSBtX2FDdXJyZW50RnJhbWUuZ2V0RnJhbWUoKSApCgkJewkvLyBvdXIgZnJhbWUgaXMgYmVpbmcgZGlzcG9zZWQgLT4gY2xvc2UgdGhlIHByZXZpZXcgd2luZG93IChpZiB3ZSBoYXZlIG9uZSkKICAgICAgICAgICAgUmVmZXJlbmNlPCBYRnJhbWUgPiB4UHJldmlld0ZyYW1lKCBnZXRDb250YWluZXIoKS0+Z2V0UHJldmlld0ZyYW1lKCkgKTsKCQkJOjpjb21waGVscGVyOjpkaXNwb3NlQ29tcG9uZW50KCB4UHJldmlld0ZyYW1lICk7CgkJfQoJCWVsc2UgaWYgKCBTb3VyY2UuU291cmNlID09IGdldENvbnRhaW5lcigpLT5nZXRQcmV2aWV3RnJhbWUoKSApCgkJewoJCQlnZXRDb250YWluZXIoKS0+ZGlzcG9zaW5nUHJldmlldygpOwoJCX0KCX0KCglPSm9pbkNvbnRyb2xsZXI6OmRpc3Bvc2luZyhTb3VyY2UpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6cmVjb25uZWN0KHNhbF9Cb29sIF9iVUkpCnsKCWRlbGV0ZUl0ZXJhdG9yKCk7Cgk6OmNvbXBoZWxwZXI6OmRpc3Bvc2VDb21wb25lbnQobV94Q29tcG9zZXIpOwoKCU9Kb2luQ29udHJvbGxlcjo6cmVjb25uZWN0KCBfYlVJICk7CgoJaWYgKGlzQ29ubmVjdGVkKCkpCgl7CgkJc2V0UXVlcnlDb21wb3NlcigpOwoJfQoJZWxzZQoJewoJCWlmKG1fYkdyYXBoaWNhbERlc2lnbikKCQl7CgkJCW1fYkdyYXBoaWNhbERlc2lnbiA9IHNhbF9GYWxzZTsKCQkJLy8gZG9uJ3QgY2FsbCBFeGVjdXRlKFNRTCkgYmVjYXVzZSB0aGlzIGNoYW5nZXMgdGhlIHNxbCBzdGF0ZW1lbnQKCQkJaW1wbF9zZXRWaWV3TW9kZSggTlVMTCApOwoJCX0KCQlJbnZhbGlkYXRlQWxsKCk7Cgl9Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6c2F2ZVZpZXdTZXR0aW5ncyggOjpjb21waGVscGVyOjpOYW1lZFZhbHVlQ29sbGVjdGlvbiYgb19yVmlld1NldHRpbmdzLCBjb25zdCBib29sIGlfaW5jbHVkaW5nQ3JpdGVyaWEgKSBjb25zdAp7CglzYXZlVGFibGVXaW5kb3dzKCBvX3JWaWV3U2V0dGluZ3MgKTsKCiAgICBPVGFibGVGaWVsZHM6OmNvbnN0X2l0ZXJhdG9yIGZpZWxkID0gbV92VGFibGVGaWVsZERlc2MuYmVnaW4oKTsKICAgIE9UYWJsZUZpZWxkczo6Y29uc3RfaXRlcmF0b3IgZmllbGRFbmQgPSBtX3ZUYWJsZUZpZWxkRGVzYy5lbmQoKTsKCiAgICA6OmNvbXBoZWxwZXI6Ok5hbWVkVmFsdWVDb2xsZWN0aW9uIGFBbGxGaWVsZHNEYXRhOwogICAgOjpjb21waGVscGVyOjpOYW1lZFZhbHVlQ29sbGVjdGlvbiBhRmllbGREYXRhOwoJZm9yICggc2FsX0ludDMyIGkgPSAxOyBmaWVsZCAhPSBmaWVsZEVuZDsgKytmaWVsZCwgKytpICkKCXsKCQlpZiAoICEoKmZpZWxkKS0+SXNFbXB0eSgpICkKCQl7CiAgICAgICAgICAgIGFGaWVsZERhdGEuY2xlYXIoKTsKCQkJKCpmaWVsZCktPlNhdmUoIGFGaWVsZERhdGEsIGlfaW5jbHVkaW5nQ3JpdGVyaWEgKTsKCiAgICAgICAgICAgIGNvbnN0IDo6cnRsOjpPVVN0cmluZyBzRmllbGRTZXR0aW5nTmFtZSA9IDo6cnRsOjpPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCAiRmllbGQiICkgKSArIDo6cnRsOjpPVVN0cmluZzo6dmFsdWVPZiggaSApOwogICAgICAgICAgICBhQWxsRmllbGRzRGF0YS5wdXQoIHNGaWVsZFNldHRpbmdOYW1lLCBhRmllbGREYXRhLmdldFByb3BlcnR5VmFsdWVzKCkgKTsKCQl9Cgl9CgogICAgb19yVmlld1NldHRpbmdzLnB1dCggIkZpZWxkcyIsIGFBbGxGaWVsZHNEYXRhLmdldFByb3BlcnR5VmFsdWVzKCkgKTsKICAgIG9fclZpZXdTZXR0aW5ncy5wdXQoICJTcGxpdHRlclBvc2l0aW9uIiwgbV9uU3BsaXRQb3MgKTsKICAgIG9fclZpZXdTZXR0aW5ncy5wdXQoICJWaXNpYmxlUm93cyIsIG1fblZpc2libGVSb3dzICk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpsb2FkVmlld1NldHRpbmdzKCBjb25zdCA6OmNvbXBoZWxwZXI6Ok5hbWVkVmFsdWVDb2xsZWN0aW9uJiBvX3JWaWV3U2V0dGluZ3MgKQp7Cglsb2FkVGFibGVXaW5kb3dzKCBvX3JWaWV3U2V0dGluZ3MgKTsKCiAgICBtX25TcGxpdFBvcyA9IG9fclZpZXdTZXR0aW5ncy5nZXRPckRlZmF1bHQoICJTcGxpdHRlclBvc2l0aW9uIiwgbV9uU3BsaXRQb3MgKTsKICAgIG1fblZpc2libGVSb3dzID0gb19yVmlld1NldHRpbmdzLmdldE9yRGVmYXVsdCggIlZpc2libGVSb3dzIiwgbV9uVmlzaWJsZVJvd3MgKTsKICAgIG1fYUZpZWxkSW5mb3JtYXRpb24gPSBvX3JWaWV3U2V0dGluZ3MuZ2V0T3JEZWZhdWx0KCAiRmllbGRzIiwgbV9hRmllbGRJbmZvcm1hdGlvbiApOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9JbnQzMiBPUXVlcnlDb250cm9sbGVyOjpnZXRDb2xXaWR0aChzYWxfdUludDE2IF9uQ29sUG9zKSAgY29uc3QKewogICAgaWYgKCBfbkNvbFBvcyA8IG1fYUZpZWxkSW5mb3JtYXRpb24uZ2V0TGVuZ3RoKCkgKQogICAgewogICAgICAgIDo6c3RkOjphdXRvX3B0cjxPVGFibGVGaWVsZERlc2M+IHBGaWVsZCggbmV3IE9UYWJsZUZpZWxkRGVzYygpKTsKICAgICAgICBwRmllbGQtPkxvYWQoIG1fYUZpZWxkSW5mb3JtYXRpb25bIF9uQ29sUG9zIF0sIGZhbHNlICk7CiAgICAgICAgcmV0dXJuIHBGaWVsZC0+R2V0Q29sV2lkdGgoKTsKICAgIH0KICAgIHJldHVybiAwOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTxYTmFtZUFjY2Vzcz4gT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0T2JqZWN0Q29udGFpbmVyKCkgIGNvbnN0CnsKCVJlZmVyZW5jZTwgWE5hbWVBY2Nlc3MgPiB4RWxlbWVudHM7CglpZiAoIGVkaXRpbmdWaWV3KCkgKQoJewoJCVJlZmVyZW5jZTwgWFZpZXdzU3VwcGxpZXIgPiB4Vmlld3NTdXBwKCBnZXRDb25uZWN0aW9uKCksIFVOT19RVUVSWSApOwoJCWlmICggeFZpZXdzU3VwcC5pcygpICkKCQkJeEVsZW1lbnRzID0geFZpZXdzU3VwcC0+Z2V0Vmlld3MoKTsKCX0KCWVsc2UKCXsKCQlSZWZlcmVuY2U8IFhRdWVyaWVzU3VwcGxpZXIgPiB4UXVlcmllc1N1cHAoIGdldENvbm5lY3Rpb24oKSwgVU5PX1FVRVJZICk7CgkJaWYgKCB4UXVlcmllc1N1cHAuaXMoKSApCgkJCXhFbGVtZW50cyA9IHhRdWVyaWVzU3VwcC0+Z2V0UXVlcmllcygpOwoJCWVsc2UKCQl7CgkJCVJlZmVyZW5jZTwgWFF1ZXJ5RGVmaW5pdGlvbnNTdXBwbGllciA+IHhRdWVyeURlZnNTdXBwKCBnZXREYXRhU291cmNlKCksIFVOT19RVUVSWSApOwoJCQlpZiAoIHhRdWVyeURlZnNTdXBwLmlzKCkgKQoJCQkJeEVsZW1lbnRzID0geFF1ZXJ5RGVmc1N1cHAtPmdldFF1ZXJ5RGVmaW5pdGlvbnMoKTsKCQl9Cgl9CgogICAgT1NMX0VOU1VSRSggeEVsZW1lbnRzLmlzKCksICJPUXVlcnlDb250cm9sbGVyOjpnZXRPYmplY3RDb250YWluZXI6IHVuYWJsZSB0byBvYnRhaW4gdGhlIGNvbnRhaW5lciEiICk7CglyZXR1cm4geEVsZW1lbnRzOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OmV4ZWN1dGVRdWVyeSgpCnsKCS8vIHdlIGRvbid0IG5lZWQgdG8gY2hlY2sgdGhlIGNvbm5lY3Rpb24gaGVyZSBiZWNhdXNlIHdlIGFscmVhZHkgY2hlY2sgdGhlIGNvbXBvc2VyCgkvLyB3aGljaCBjYW4ndCBsaXZlIHdpdGhvdXQgaGlzIGNvbm5lY3Rpb24KCTo6cnRsOjpPVVN0cmluZyBzVHJhbnNsYXRlZFN0bXQgPSB0cmFuc2xhdGVTdGF0ZW1lbnQoIGZhbHNlICk7CgoJOjpydGw6Ok9VU3RyaW5nIHNEYXRhU291cmNlTmFtZSA9IGdldERhdGFTb3VyY2VOYW1lKCk7CglpZiAoIHNEYXRhU291cmNlTmFtZS5nZXRMZW5ndGgoKSAmJiBzVHJhbnNsYXRlZFN0bXQuZ2V0TGVuZ3RoKCkgKQoJewoJCXRyeQoJCXsKCQkJZ2V0Q29udGFpbmVyKCktPnNob3dQcmV2aWV3KCBnZXRGcmFtZSgpICk7CgkJCUludmFsaWRhdGVGZWF0dXJlKFNJRF9EQl9RVUVSWV9QUkVWSUVXKTsKCgkJCVVSTCBhV2FudFRvRGlzcGF0Y2g7CgkJCWFXYW50VG9EaXNwYXRjaC5Db21wbGV0ZSA9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIuY29tcG9uZW50OkRCL0RhdGFTb3VyY2VCcm93c2VyIik7CgoJCQk6OnJ0bDo6T1VTdHJpbmcgc0ZyYW1lTmFtZSggRlJBTUVfTkFNRV9RVUVSWV9QUkVWSUVXICk7CgkJCXNhbF9JbnQzMiBuU2VhcmNoRmxhZ3MgPSBGcmFtZVNlYXJjaEZsYWc6OkNISUxEUkVOOwoKCQkJUmVmZXJlbmNlPCBYRGlzcGF0Y2g+IHhEaXNwOwoJCQlSZWZlcmVuY2U8IFhEaXNwYXRjaFByb3ZpZGVyPiB4UHJvdiggZ2V0RnJhbWUoKS0+ZmluZEZyYW1lKCBzRnJhbWVOYW1lLCBuU2VhcmNoRmxhZ3MgKSwgVU5PX1FVRVJZICk7CgkJCWlmKCF4UHJvdi5pcygpKQoJCQl7CgkJCQl4UHJvdi5zZXQoIGdldEZyYW1lKCksIFVOT19RVUVSWSApOwoJCQkJaWYgKHhQcm92LmlzKCkpCgkJCQkJeERpc3AgPSB4UHJvdi0+cXVlcnlEaXNwYXRjaChhV2FudFRvRGlzcGF0Y2gsIHNGcmFtZU5hbWUsIG5TZWFyY2hGbGFncyk7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQl4RGlzcCA9IHhQcm92LT5xdWVyeURpc3BhdGNoKGFXYW50VG9EaXNwYXRjaCwgc0ZyYW1lTmFtZSwgRnJhbWVTZWFyY2hGbGFnOjpTRUxGKTsKCQkJfQoJCQlpZiAoeERpc3AuaXMoKSkKCQkJewoJCQkJU2VxdWVuY2U8IFByb3BlcnR5VmFsdWU+IGFQcm9wcyg5KTsKCQkJCWFQcm9wc1swXS5OYW1lID0gUFJPUEVSVFlfREFUQVNPVVJDRU5BTUU7CgkJCQlhUHJvcHNbMF0uVmFsdWUgPDw9IHNEYXRhU291cmNlTmFtZTsKCgkJCQlhUHJvcHNbMV0uTmFtZSA9IFBST1BFUlRZX0NPTU1BTkRfVFlQRTsKCQkJCWFQcm9wc1sxXS5WYWx1ZSA8PD0gQ29tbWFuZFR5cGU6OkNPTU1BTkQ7CgoJCQkJYVByb3BzWzJdLk5hbWUgPSBQUk9QRVJUWV9DT01NQU5EOwoJCQkJYVByb3BzWzJdLlZhbHVlIDw8PSBzVHJhbnNsYXRlZFN0bXQ7CgoJCQkJYVByb3BzWzNdLk5hbWUgPSBQUk9QRVJUWV9FTkFCTEVfQlJPV1NFUjsKCQkJCWFQcm9wc1szXS5WYWx1ZSA9IDo6Y3BwdTo6Ym9vbDJhbnkoc2FsX0ZhbHNlKTsKCgkJCQlhUHJvcHNbNF0uTmFtZSA9IFBST1BFUlRZX0FDVElWRV9DT05ORUNUSU9OOwoJCQkJYVByb3BzWzRdLlZhbHVlIDw8PSBnZXRDb25uZWN0aW9uKCk7CgoJCQkJYVByb3BzWzVdLk5hbWUgPSBQUk9QRVJUWV9VUERBVEVfQ0FUQUxPR05BTUU7CgkJCQlhUHJvcHNbNV0uVmFsdWUgPDw9IG1fc1VwZGF0ZUNhdGFsb2dOYW1lOwoKCQkJCWFQcm9wc1s2XS5OYW1lID0gUFJPUEVSVFlfVVBEQVRFX1NDSEVNQU5BTUU7CgkJCQlhUHJvcHNbNl0uVmFsdWUgPDw9IG1fc1VwZGF0ZVNjaGVtYU5hbWU7CgoJCQkJYVByb3BzWzddLk5hbWUgPSBQUk9QRVJUWV9VUERBVEVfVEFCTEVOQU1FOwoJCQkJYVByb3BzWzddLlZhbHVlIDw8PSBtX3NVcGRhdGVUYWJsZU5hbWU7CgoJCQkJYVByb3BzWzhdLk5hbWUgPSBQUk9QRVJUWV9FU0NBUEVfUFJPQ0VTU0lORzsKCQkJCWFQcm9wc1s4XS5WYWx1ZSA9IDo6Y3BwdTo6Ym9vbDJhbnkobV9iRXNjYXBlUHJvY2Vzc2luZyk7CgoJCQkJeERpc3AtPmRpc3BhdGNoKGFXYW50VG9EaXNwYXRjaCwgYVByb3BzKTsKCQkJCS8vIGNoZWNrIHRoZSBzdGF0ZSBvZiB0aGUgYmVhbWVyCgkJCQkvLyBiZSBub3RpZmllZCB3aGVuIHRoZSBiZWFtZXIgZnJhbWUgaXMgY2xvc2VkCgkJCQlSZWZlcmVuY2U8IFhDb21wb25lbnQgPiAgeENvbXBvbmVudCggZ2V0RnJhbWUoKS0+ZmluZEZyYW1lKCBzRnJhbWVOYW1lLCBuU2VhcmNoRmxhZ3MgKSwgVU5PX1FVRVJZICk7CgkJCQlpZiAoeENvbXBvbmVudC5pcygpKQoJCQkJewoJCQkJCU9TTF9FTlNVUkUoUmVmZXJlbmNlPCBYRnJhbWUgPih4Q29tcG9uZW50LCBVTk9fUVVFUlkpLmdldCgpID09IGdldENvbnRhaW5lcigpLT5nZXRQcmV2aWV3RnJhbWUoKS5nZXQoKSwKCQkJCQkJIk9RdWVyeUNvbnRyb2xsZXI6OmV4ZWN1dGVRdWVyeTogb29wcyAuLi4gd2hpY2ggd2luZG93IGRvIEkgaGF2ZSBoZXJlPyIpOwoJCQkJCVJlZmVyZW5jZTwgWEV2ZW50TGlzdGVuZXI+IHhFdnRMKCg6OmNwcHU6Ok9XZWFrT2JqZWN0Kil0aGlzLFVOT19RVUVSWSk7CgkJCQkJeENvbXBvbmVudC0+YWRkRXZlbnRMaXN0ZW5lcih4RXZ0TCk7CgkJCQl9CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlPU0xfRU5TVVJFKDAsIkNvdWxkbid0IGNyZWF0ZSBhIGJlYW1lciB3aW5kb3chIik7CgkJCX0KCQl9CgkJY2F0Y2goY29uc3QgRXhjZXB0aW9uJikKCQl7CgkJCU9TTF9FTlNVUkUoMCwiQ291bGRuJ3QgY3JlYXRlIGEgYmVhbWVyIHdpbmRvdyEiKTsKCQl9Cgl9Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgT1F1ZXJ5Q29udHJvbGxlcjo6YXNrRm9yTmV3TmFtZShjb25zdCBSZWZlcmVuY2U8WE5hbWVBY2Nlc3M+JiBfeEVsZW1lbnRzLHNhbF9Cb29sIF9iU2F2ZUFzKQp7CiAgICBPU0xfRU5TVVJFKCAhZWRpdGluZ0NvbW1hbmQoKSwgIk9RdWVyeUNvbnRyb2xsZXI6OmFza0Zvck5ld05hbWU6IG5vdCB0byBiZSBjYWxsZWQgd2hlbiBkZXNpZ25pbmcgYW4gaW5kZXBlbmRlbnQgc3RhdGVtZW50ISIgKTsKICAgIGlmICggZWRpdGluZ0NvbW1hbmQoKSApCiAgICAgICAgcmV0dXJuIHNhbF9GYWxzZTsKCiAgICBPU0xfUFJFQ09ORCggX3hFbGVtZW50cy5pcygpLCAiT1F1ZXJ5Q29udHJvbGxlcjo6YXNrRm9yTmV3TmFtZTogaW52YWxpZCBjb250YWluZXIhIiApOwogICAgaWYgICggIV94RWxlbWVudHMuaXMoKSApCiAgICAgICAgcmV0dXJuIHNhbF9GYWxzZTsKCglzYWxfQm9vbCBiUmV0ID0gc2FsX1RydWU7CglzYWxfQm9vbCBiTmV3ID0gX2JTYXZlQXMgfHwgIV94RWxlbWVudHMtPmhhc0J5TmFtZSggbV9zTmFtZSApOwoJaWYoYk5ldykKCXsKCQlTdHJpbmcgYURlZmF1bHROYW1lOwoJCWlmICggKCBfYlNhdmVBcyAmJiAhYk5ldyApIHx8ICggYk5ldyAmJiBtX3NOYW1lLmdldExlbmd0aCgpICkgKQoJCQlhRGVmYXVsdE5hbWUgPSBTdHJpbmcoIG1fc05hbWUgKTsKCQllbHNlCiAgICAgICAgewogICAgICAgICAgICBTdHJpbmcgc05hbWUgPSBTdHJpbmcoIE1vZHVsZVJlcyggZWRpdGluZ1ZpZXcoKSA/IFNUUl9WSUVXX1RJVExFIDogU1RSX1FSWV9USVRMRSApICk7CgkJCWFEZWZhdWx0TmFtZSA9IHNOYW1lLkdldFRva2VuKDAsJyAnKTsKICAgICAgICAgICAgLy9hRGVmYXVsdE5hbWUgPSBnZXRQcml2YXRlVGl0bGUoICk7CiAgICAgICAgICAgIGFEZWZhdWx0TmFtZSA9IDo6ZGJ0b29sczo6Y3JlYXRlVW5pcXVlTmFtZShfeEVsZW1lbnRzLGFEZWZhdWx0TmFtZSk7CiAgICAgICAgfQoKICAgICAgICBEeW5hbWljVGFibGVPclF1ZXJ5TmFtZUNoZWNrIGFOYW1lQ2hlY2tlciggZ2V0Q29ubmVjdGlvbigpLCBDb21tYW5kVHlwZTo6UVVFUlkgKTsKCQlPU2F2ZUFzRGxnIGFEbGcoCgkJCQlnZXRWaWV3KCksCiAgICAgICAgICAgICAgICBtX25Db21tYW5kVHlwZSwKICAgICAgICAgICAgICAgIGdldE9SQigpLAoJCQkJZ2V0Q29ubmVjdGlvbigpLAoJCQkJYURlZmF1bHROYW1lLAogICAgICAgICAgICAgICAgYU5hbWVDaGVja2VyLAoJCQkJU0FEX0RFRkFVTFQgKTsKCiAgICAgICAgYlJldCA9ICggYURsZy5FeGVjdXRlKCkgPT0gUkVUX09LICk7CgkJaWYgKCBiUmV0ICkKCQl7CgkJCW1fc05hbWUgPSBhRGxnLmdldE5hbWUoKTsKCQkJaWYgKCBlZGl0aW5nVmlldygpICkKCQkJewoJCQkJbV9zVXBkYXRlQ2F0YWxvZ05hbWUJPSBhRGxnLmdldENhdGFsb2coKTsKCQkJCW1fc1VwZGF0ZVNjaGVtYU5hbWUJCT0gYURsZy5nZXRTY2hlbWEoKTsKCQkJfQoJCX0KCX0KCXJldHVybiBiUmV0Owp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgT1F1ZXJ5Q29udHJvbGxlcjo6ZG9TYXZlQXNEb2Moc2FsX0Jvb2wgX2JTYXZlQXMpCnsKCU9TTF9FTlNVUkUoaXNFZGl0YWJsZSgpLCJTbG90IElEX0JST1dTRVJfU0FWRURPQyBzaG91bGQgbm90IGJlIGVuYWJsZWQhIik7CglpZiAoICFlZGl0aW5nQ29tbWFuZCgpICYmICFoYXZlRGF0YVNvdXJjZSgpICkKCXsKCQlTdHJpbmcgYU1lc3NhZ2UoTW9kdWxlUmVzKFNUUl9EQVRBU09VUkNFX0RFTEVURUQpKTsKCQlPU1FMV2FybmluZ0JveCggZ2V0VmlldygpLCBhTWVzc2FnZSApLkV4ZWN1dGUoKTsKICAgICAgICByZXR1cm4gZmFsc2U7Cgl9CgoJUmVmZXJlbmNlPCBYTmFtZUFjY2VzcyA+IHhFbGVtZW50cyA9IGdldE9iamVjdENvbnRhaW5lcigpOwoJaWYgKCAheEVsZW1lbnRzLmlzKCkgKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICBpZiAoICFnZXRDb250YWluZXIoKS0+Y2hlY2tTdGF0ZW1lbnQoKSApCgkJcmV0dXJuIGZhbHNlOwoKCTo6cnRsOjpPVVN0cmluZyBzVHJhbnNsYXRlZFN0bXQgPSB0cmFuc2xhdGVTdGF0ZW1lbnQoKTsKICAgIGlmICggZWRpdGluZ0NvbW1hbmQoKSApCiAgICB7CiAgICAgICAgc2V0TW9kaWZpZWQoIHNhbF9GYWxzZSApOwogICAgICAgIC8vIHRoaXMgaXMgYWxsIHdlIG5lZWQgdG8gZG8gaGVyZS4gdHJhbnNsYXRlU3RhdGVtZW50IGltcGxpY2l0bHkgc2V0IG91ciBtX3NTdGF0ZW1lbnQsIGFuZAogICAgICAgIC8vIG5vdGlmaWVkIGl0LCBhbmQgdGhhdCdzIGFsbAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKCWlmICggIXNUcmFuc2xhdGVkU3RtdC5nZXRMZW5ndGgoKSApCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIC8vIGZpcnN0IHdlIG5lZWQgYSBuYW1lIGZvciBvdXIgcXVlcnkgc28gYXNrIHRoZSB1c2VyCgkvLyBkaWQgd2UgZ2V0IGEgbmFtZQogICAgOjpydGw6Ok9VU3RyaW5nIHNPcmlnaW5hbE5hbWUoIG1fc05hbWUgKTsKICAgIGlmICggIWFza0Zvck5ld05hbWUoIHhFbGVtZW50cywgX2JTYXZlQXMgKSB8fCAhbV9zTmFtZS5nZXRMZW5ndGgoKSApCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIFNRTEV4Y2VwdGlvbkluZm8gYUluZm87CiAgICBib29sIGJTdWNjZXNzID0gZmFsc2U7CiAgICBib29sIGJOZXcgPSBmYWxzZTsKCXRyeQoJewogICAgICAgIGJOZXcgPSAoIF9iU2F2ZUFzICkKICAgICAgICAgICAgfHwgKCAheEVsZW1lbnRzLT5oYXNCeU5hbWUoIG1fc05hbWUgKSApOwoKICAgICAgICBSZWZlcmVuY2U8WFByb3BlcnR5U2V0PiB4UXVlcnk7CgkJaWYgKCBiTmV3ICkgLy8ganVzdCB0byBtYWtlIHN1cmUgdGhlIHF1ZXJ5IGFscmVhZHkgZXhpc3RzCgkJewogICAgICAgICAgICAvLyBkcm9wIHRoZSBxdWVyeSwgaW4gY2FzZSBpdCBhbHJlYWR5IGV4aXN0cwoJCQlpZiAoIHhFbGVtZW50cy0+aGFzQnlOYW1lKCBtX3NOYW1lICkgKQoJCQl7CgkJCQlSZWZlcmVuY2U8IFhEcm9wID4geE5hbWVDb250KCB4RWxlbWVudHMsIFVOT19RVUVSWSApOwoJCQkJaWYgKCB4TmFtZUNvbnQuaXMoKSApCgkJCQkJeE5hbWVDb250LT5kcm9wQnlOYW1lKCBtX3NOYW1lICk7CgkJCQllbHNlCgkJCQl7CgkJCQkJUmVmZXJlbmNlPCBYTmFtZUNvbnRhaW5lciA+IHhDb250KCB4RWxlbWVudHMsIFVOT19RVUVSWSApOwoJCQkJCWlmICggeENvbnQuaXMoKSApCgkJCQkJCXhDb250LT5yZW1vdmVCeU5hbWUoIG1fc05hbWUgKTsKCQkJCX0KCQkJfQoKICAgICAgICAgICAgLy8gY3JlYXRlIGEgbmV3IChlbXB0eSwgdW5pbml0aWFsaXplZCkgcXVlcnkgcmVzcC4gdmlldwoJCQlSZWZlcmVuY2U8IFhEYXRhRGVzY3JpcHRvckZhY3RvcnkgPiB4RmFjdCggeEVsZW1lbnRzLCBVTk9fUVVFUlkgKTsKCQkJaWYgKCB4RmFjdC5pcygpICkKCQkJewoJCQkJeFF1ZXJ5ID0geEZhY3QtPmNyZWF0ZURhdGFEZXNjcmlwdG9yKCk7CgkJCQkvLyB0byBzZXQgdGhlIG5hbWUgaXMgb25seSBhbGxvd2VkIHdoZW4gdGhlIHF1ZXJ5IGlzIG5ldwoJCQkJeFF1ZXJ5LT5zZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9OQU1FLCBtYWtlQW55KCBtX3NOYW1lICkgKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCVJlZmVyZW5jZTwgWFNpbmdsZVNlcnZpY2VGYWN0b3J5ID4geFNpbmdsZUZhYyggeEVsZW1lbnRzLCBVTk9fUVVFUlkgKTsKICAgICAgICAgICAgICAgIGlmICggeFNpbmdsZUZhYy5pcygpICkKCQkJCQl4UXVlcnkgPSB4UXVlcnkucXVlcnkoIHhTaW5nbGVGYWMtPmNyZWF0ZUluc3RhbmNlKCkgKTsKCQkJfQoJCX0KCQllbHNlCgkJewoJCQl4RWxlbWVudHMtPmdldEJ5TmFtZSggbV9zTmFtZSApID4+PSB4UXVlcnk7CgkJfQogICAgICAgIGlmICggIXhRdWVyeS5pcygpICkKICAgICAgICAgICAgdGhyb3cgUnVudGltZUV4Y2VwdGlvbigpOwoKICAgICAgICAvLyB0aGUgbmV3IGNvbW1hbmRzCiAgICAgICAgaWYgKCBlZGl0aW5nVmlldygpICYmICFiTmV3ICkKICAgICAgICB7CiAgICAgICAgICAgIE9TTF9FTlNVUkUoIHhRdWVyeSA9PSBtX3hBbHRlclZpZXcsICJPUXVlcnlDb250cm9sbGVyOjpkb1NhdmVBc0RvYzogYWxyZWFkeSBoYXZlIGFub3RoZXIgYWx0ZXJhYmxlIHZpZXcgLi4uIT8iICk7CiAgICAgICAgICAgIG1feEFsdGVyVmlldy5zZXQoIHhRdWVyeSwgVU5PX1FVRVJZX1RIUk9XICk7CiAgICAgICAgICAgIG1feEFsdGVyVmlldy0+YWx0ZXJDb21tYW5kKCBzVHJhbnNsYXRlZFN0bXQgKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsgICAvLyB3ZSdyZSBjcmVhdGluZyBhIHF1ZXJ5LCBvciBhICpuZXcqIHZpZXcKICAgICAgICAgICAgeFF1ZXJ5LT5zZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9DT01NQU5ELCBtYWtlQW55KCBzVHJhbnNsYXRlZFN0bXQgKSApOwoKICAgICAgICAgICAgaWYgKCBlZGl0aW5nVmlldygpICkKICAgICAgICAgICAgewoJCQkgICAgeFF1ZXJ5LT5zZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9DQVRBTE9HTkFNRSwgbWFrZUFueSggbV9zVXBkYXRlQ2F0YWxvZ05hbWUgKSApOwoJCQkgICAgeFF1ZXJ5LT5zZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9TQ0hFTUFOQU1FLCBtYWtlQW55KCBtX3NVcGRhdGVTY2hlbWFOYW1lICkgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCBlZGl0aW5nUXVlcnkoKSApCgkJCXsKCQkJCXhRdWVyeS0+c2V0UHJvcGVydHlWYWx1ZSggUFJPUEVSVFlfVVBEQVRFX1RBQkxFTkFNRSwgbWFrZUFueSggbV9zVXBkYXRlVGFibGVOYW1lICkgKTsKCQkJCXhRdWVyeS0+c2V0UHJvcGVydHlWYWx1ZSggUFJPUEVSVFlfRVNDQVBFX1BST0NFU1NJTkcsOjpjcHB1Ojpib29sMmFueSggbV9iRXNjYXBlUHJvY2Vzc2luZyApICk7CgoJCQkJeFF1ZXJ5LT5zZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9MQVlPVVRJTkZPUk1BVElPTiwgZ2V0Vmlld0RhdGEoKSApOwoJCQl9CiAgICAgICAgfQoKCQlpZiAoIGJOZXcgKQoJCXsKCQkJUmVmZXJlbmNlPCBYQXBwZW5kID4geEFwcGVuZCggeEVsZW1lbnRzLCBVTk9fUVVFUlkgKTsKCQkJaWYgKCB4QXBwZW5kLmlzKCkgKQoJCQl7CgkJCQl4QXBwZW5kLT5hcHBlbmRCeURlc2NyaXB0b3IoIHhRdWVyeSApOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJUmVmZXJlbmNlPCBYTmFtZUNvbnRhaW5lciA+IHhDb250KCB4RWxlbWVudHMsIFVOT19RVUVSWSApOwoJCQkJaWYgKCB4Q29udC5pcygpICkKCQkJCQl4Q29udC0+aW5zZXJ0QnlOYW1lKCBtX3NOYW1lLCBtYWtlQW55KCB4UXVlcnkgKSApOwoJCQl9CgoJCQlpZiAoIGVkaXRpbmdWaWV3KCkgKQoJCQl7CgkJCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhWaWV3UHJvcHM7CgkJCQlpZiAoIHhFbGVtZW50cy0+aGFzQnlOYW1lKCBtX3NOYW1lICkgKQoJCQkJCXhWaWV3UHJvcHMuc2V0KCB4RWxlbWVudHMtPmdldEJ5TmFtZSggbV9zTmFtZSApLCBVTk9fUVVFUlkgKTsKCgkJCQlpZiAoICF4Vmlld1Byb3BzLmlzKCkgKSAvLyBjb3JyZWN0IG5hbWUgYW5kIHRyeSBhZ2FpbgoJCQkJCW1fc05hbWUgPSA6OmRidG9vbHM6OmNvbXBvc2VUYWJsZU5hbWUoIGdldE1ldGFEYXRhKCksIHhRdWVyeSwgOjpkYnRvb2xzOjplSW5EYXRhTWFuaXB1bGF0aW9uLCBmYWxzZSwgZmFsc2UsIGZhbHNlICk7CgogICAgICAgICAgICAgICAgT1NMX0VOU1VSRSggeEVsZW1lbnRzLT5oYXNCeU5hbWUoIG1fc05hbWUgKSwgIk9RdWVyeUNvbnRyb2xsZXI6OmRvU2F2ZUFzRG9jOiBuZXdseSBjcmVhZWQgdmlldyBkb2VzIG5vdCBleGlzdCEiICk7CgogICAgICAgICAgICAgICAgaWYgKCB4RWxlbWVudHMtPmhhc0J5TmFtZSggbV9zTmFtZSApICkKICAgICAgICAgICAgICAgICAgICBtX3hBbHRlclZpZXcuc2V0KCB4RWxlbWVudHMtPmdldEJ5TmFtZSggbV9zTmFtZSApLCBVTk9fUVVFUlkgKTsKCiAgICAgICAgICAgICAgICAvLyBub3cgY2hlY2sgaWYgb3VyIGRhdGFzb3VyY2UgaGFzIHNldCBhIHRhYmxlZmlsdGVyIGFuZCBpZiBzbywgYXBwZW5kIHRoZSBuZXcgdGFibGUgbmFtZSB0byBpdAoJCQkJOjpkYmF1aTo6YXBwZW5kVG9GaWx0ZXIoIGdldENvbm5lY3Rpb24oKSwgbV9zTmFtZSwgZ2V0T1JCKCksIGdldFZpZXcoKSApOwoJCQl9IC8vIGlmICggZWRpdGluZ1ZpZXcoKSApCiAgICAgICAgICAgIFJlZmVyZW5jZTwgWFRpdGxlQ2hhbmdlTGlzdGVuZXI+IHhFdmVudExpc3RlbmVyKGltcGxfZ2V0VGl0bGVIZWxwZXJfdGhyb3coKSxVTk9fUVVFUlkpOwogICAgICAgICAgICBpZiAoIHhFdmVudExpc3RlbmVyLmlzKCkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBUaXRsZUNoYW5nZWRFdmVudCBhRXZlbnQ7CiAgICAgICAgICAgICAgICB4RXZlbnRMaXN0ZW5lci0+dGl0bGVDaGFuZ2VkKGFFdmVudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVsZWFzZU51bWJlckZvckNvbXBvbmVudCgpOwoJCX0KCgkJc2V0TW9kaWZpZWQoIHNhbF9GYWxzZSApOwogICAgICAgIGJTdWNjZXNzID0gdHJ1ZTsKCgl9CgljYXRjaCggY29uc3QgU1FMRXhjZXB0aW9uJiApCgl7CiAgICAgICAgaWYgKCAhYk5ldyApCiAgICAgICAgICAgIG1fc05hbWUgPSBzT3JpZ2luYWxOYW1lOwogICAgICAgIGFJbmZvID0gU1FMRXhjZXB0aW9uSW5mbyggOjpjcHB1OjpnZXRDYXVnaHRFeGNlcHRpb24oKSApOwoJfQoJY2F0Y2goRXhjZXB0aW9uJikKCXsKICAgICAgICBpZiAoICFiTmV3ICkKICAgICAgICAgICAgbV9zTmFtZSA9IHNPcmlnaW5hbE5hbWU7CiAgICAgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKCX0KCglzaG93RXJyb3IoIGFJbmZvICk7CgogICAgLy8gdXBkYXRlIHRoZSB0aXRsZSBvZiBvdXIgd2luZG93CgkvL3VwZGF0ZVRpdGxlKCk7CgogICAgLy8gaWYgd2Ugc3VjY2Vzc2Z1bGx5IHNhdmVkIGEgdmlldyB3ZSB3ZXJlIGNyZWF0aW5nLCB0aGVuIGNsb3NlIHRoZSBkZXNpZ25lcgogICAgaWYgKCBiU3VjY2VzcyAmJiBlZGl0aW5nVmlldygpICYmICFtX3hBbHRlclZpZXcuaXMoKSApCiAgICB7CgkJY2xvc2VUYXNrKCk7CiAgICB9CgogICAgaWYgKCBiU3VjY2VzcyAmJiBlZGl0aW5nVmlldygpICkKICAgICAgICBJbnZhbGlkYXRlRmVhdHVyZSggSURfQlJPV1NFUl9FRElURE9DICk7CgogICAgcmV0dXJuIGJTdWNjZXNzOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6cnRsOjpPVVN0cmluZyBPUXVlcnlDb250cm9sbGVyOjp0cmFuc2xhdGVTdGF0ZW1lbnQoIGJvb2wgX2JGaXJlU3RhdGVtZW50Q2hhbmdlICkKewoJLy8gbm93IHNldCB0aGUgcHJvcGVydGllcwoJc2V0U3RhdGVtZW50X2ZpcmVFdmVudCggZ2V0Q29udGFpbmVyKCktPmdldFN0YXRlbWVudCgpLCBfYkZpcmVTdGF0ZW1lbnRDaGFuZ2UgKTsKCTo6cnRsOjpPVVN0cmluZyBzVHJhbnNsYXRlZFN0bXQ7CglpZihtX3NTdGF0ZW1lbnQuZ2V0TGVuZ3RoKCkgJiYgbV94Q29tcG9zZXIuaXMoKSAmJiBtX2JFc2NhcGVQcm9jZXNzaW5nKQoJewoJCXRyeQoJCXsKCQkJOjpydGw6Ok9VU3RyaW5nIGFFcnJvck1zZzsKCgkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwTm9kZSA9IG1fYVNxbFBhcnNlci5wYXJzZVRyZWUoIGFFcnJvck1zZywgbV9zU3RhdGVtZW50LCBtX2JHcmFwaGljYWxEZXNpZ24gKTsKCQkJaWYocE5vZGUpCgkJCXsKICAgICAgICAgICAgICAgIHBOb2RlLT5wYXJzZU5vZGVUb1N0ciggc1RyYW5zbGF0ZWRTdG10LCBnZXRDb25uZWN0aW9uKCkgKTsKCQkJCWRlbGV0ZSBwTm9kZTsKCQkJfQoKICAgICAgICAgICAgbV94Q29tcG9zZXItPnNldFF1ZXJ5KHNUcmFuc2xhdGVkU3RtdCk7CgkJCXNUcmFuc2xhdGVkU3RtdCA9IG1feENvbXBvc2VyLT5nZXRDb21wb3NlZFF1ZXJ5KCk7CgkJfQoJCWNhdGNoKFNRTEV4Y2VwdGlvbiYgZSkKCQl7CgkJCTo6ZGJ0b29sczo6U1FMRXhjZXB0aW9uSW5mbyBhSW5mbyhlKTsKCQkJc2hvd0Vycm9yKGFJbmZvKTsKCQkJLy8gYW4gZXJyb3Igb2NjdXJyZWQgc28gd2UgY2xlYXIgdGhlIHN0YXRlbWVudAoJCQlzVHJhbnNsYXRlZFN0bXQgPSA6OnJ0bDo6T1VTdHJpbmcoKTsKCQl9Cgl9CgllbHNlIGlmKCFtX3NTdGF0ZW1lbnQuZ2V0TGVuZ3RoKCkpCgl7CiAgICAgICAgTW9kdWxlUmVzIGFNb2R1bGVSZXMoU1RSX1FSWV9OT1NFTEVDVCk7CiAgICAgICAgU3RyaW5nIHNUbXBTdHIoYU1vZHVsZVJlcyk7CgkJOjpydGw6Ok9VU3RyaW5nIHNFcnJvcihzVG1wU3RyKTsKCQlzaG93RXJyb3IoU1FMRXhjZXB0aW9uKHNFcnJvcixOVUxMLDo6cnRsOjpPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIlMxMDAwIikgKSwxMDAwLEFueSgpKSk7Cgl9CgllbHNlCgkJc1RyYW5zbGF0ZWRTdG10ID0gbV9zU3RhdGVtZW50OwoKCXJldHVybiBzVHJhbnNsYXRlZFN0bXQ7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2hvcnQgT1F1ZXJ5Q29udHJvbGxlcjo6c2F2ZU1vZGlmaWVkKCkKewoJdm9zOjpPR3VhcmQgYVNvbGFyR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggZ2V0TXV0ZXgoKSApOwoJc2hvcnQgblJldCA9IFJFVF9ZRVM7CiAgICBpZiAoICFpc0Nvbm5lY3RlZCgpIHx8ICFpc01vZGlmaWVkKCkgKQogICAgICAgIHJldHVybiBuUmV0OwoKCWlmICAoICAhbV9iR3JhcGhpY2FsRGVzaWduCiAgICAgICAgfHwgKCAgIW1fdlRhYmxlRmllbGREZXNjLmVtcHR5KCkKICAgICAgICAgICAmJiAhbV92VGFibGVEYXRhLmVtcHR5KCkKICAgICAgICAgICApCiAgICAgICAgKQoJewogICAgICAgIFN0cmluZyBzTWVzc2FnZVRleHQoIGxjbF9nZXRPYmplY3RSZXNvdXJjZVN0cmluZyggU1RSX1FVRVJZX1NBVkVNT0RJRklFRCwgbV9uQ29tbWFuZFR5cGUgKSApOwogICAgICAgIFF1ZXJ5Qm94IGFRcnkoIGdldFZpZXcoKSwgV0JfWUVTX05PX0NBTkNFTCB8IFdCX0RFRl9ZRVMsIHNNZXNzYWdlVGV4dCApOwoKICAgICAgICBuUmV0ID0gYVFyeS5FeGVjdXRlKCk7CgkJaWYgICggICAoIG5SZXQgPT0gUkVUX1lFUyApCiAgICAgICAgICAgICYmICAhZG9TYXZlQXNEb2MoIHNhbF9GYWxzZSApCiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIG5SZXQgPSBSRVRfQ0FOQ0VMOwoJCX0KCX0KCXJldHVybiBuUmV0Owp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9yZXNldCggY29uc3QgYm9vbCBpX2JGb3JjZUN1cnJlbnRDb250cm9sbGVyU2V0dGluZ3MgKQp7CiAgICBib29sIGJWYWxpZCA9IGZhbHNlOwoKICAgIFNlcXVlbmNlPCBQcm9wZXJ0eVZhbHVlID4gYUxheW91dEluZm9ybWF0aW9uOwoJLy8gZ2V0IGNvbW1hbmQgZnJvbSB0aGUgcXVlcnkgaWYgYSBxdWVyeSBuYW1lIHdhcyBzdXBwbGllZAogICAgaWYgKCAhaV9iRm9yY2VDdXJyZW50Q29udHJvbGxlclNldHRpbmdzICYmICFlZGl0aW5nQ29tbWFuZCgpICkKICAgIHsKCSAgICBpZiAoIG1fc05hbWUuZ2V0TGVuZ3RoKCkgKQoJICAgIHsKICAgICAgICAgICAgUmVmZXJlbmNlPCBYTmFtZUFjY2VzcyA+IHhRdWVyaWVzID0gZ2V0T2JqZWN0Q29udGFpbmVyKCk7CgkJICAgIGlmICggeFF1ZXJpZXMuaXMoKSApCgkJICAgIHsKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geFByb3A7CgkJCSAgICBpZiggeFF1ZXJpZXMtPmhhc0J5TmFtZSggbV9zTmFtZSApICYmICggeFF1ZXJpZXMtPmdldEJ5TmFtZSggbV9zTmFtZSApID4+PSB4UHJvcCApICYmIHhQcm9wLmlzKCkgKQoJCQkgICAgewogICAgICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZyBzTmV3U3RhdGVtZW50OwoJCQkJICAgIHhQcm9wLT5nZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9DT01NQU5EICkgPj49IHNOZXdTdGF0ZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgc2V0U3RhdGVtZW50X2ZpcmVFdmVudCggc05ld1N0YXRlbWVudCApOwoKICAgICAgICAgICAgICAgICAgICBzYWxfQm9vbCBiTmV3RXNjYXBlUHJvY2Vzc2luZyggc2FsX1RydWUgKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIGVkaXRpbmdRdWVyeSgpICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhQcm9wLT5nZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9FU0NBUEVfUFJPQ0VTU0lORyApID4+PSBiTmV3RXNjYXBlUHJvY2Vzc2luZzsKICAgICAgICAgICAgICAgICAgICAgICAgc2V0RXNjYXBlUHJvY2Vzc2luZ19maXJlRXZlbnQoIGJOZXdFc2NhcGVQcm9jZXNzaW5nICk7CiAgICAgICAgICAgICAgICAgICAgfQoKCQkJCSAgICBtX2JHcmFwaGljYWxEZXNpZ24gPSBtX2JHcmFwaGljYWxEZXNpZ24gJiYgbV9iRXNjYXBlUHJvY2Vzc2luZzsKICAgICAgICAgICAgICAgICAgICBiVmFsaWQgPSB0cnVlOwoKICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggZWRpdGluZ1F1ZXJ5KCkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeFByb3AtPmdldFByb3BlcnR5VmFsdWUoIFBST1BFUlRZX0xBWU9VVElORk9STUFUSU9OICkgPj49IGFMYXlvdXRJbmZvcm1hdGlvbjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAJT1NMX0VOU1VSRSggc2FsX0ZhbHNlLCAiT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9yZXNldDogY291bGQgbm90IHJldHJpZXZlIHRoZSBsYXlvdXQgaW5mb3JtYXRpb24gZnJvbSB0aGUgcXVlcnkhIiApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBiVmFsaWQgPSB0cnVlOwogICAgICAgIC8vIGFzc3VtZSB0aGF0IHdlIGdvdCBhbGwgbmVjZXNzYXJ5IGluZm9ybWF0aW9uIGR1cmluZyBpbml0aWFsaXphdGlvbgogICAgfQoKCWlmICggYlZhbGlkICkKCXsKICAgICAgICAvLyBsb2FkIHRoZSBsYXlvdXRJbmZvcm1hdGlvbgogICAgICAgIGlmICggYUxheW91dEluZm9ybWF0aW9uLmdldExlbmd0aCgpICkKICAgICAgICB7CgkJICAgIHRyeQoJCSAgICB7CgkJCQlsb2FkVmlld1NldHRpbmdzKCBhTGF5b3V0SW5mb3JtYXRpb24gKTsKCQkgICAgfQoJCSAgICBjYXRjaCggY29uc3QgRXhjZXB0aW9uJiApCgkJICAgIHsKICAgICAgICAgICAgICAgIERCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CgkJICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICggbV9zU3RhdGVtZW50LmdldExlbmd0aCgpICkKICAgICAgICB7CiAgICAgICAgICAgIHNldFF1ZXJ5Q29tcG9zZXIoKTsKCiAgICAgICAgICAgIGJvb2wgYkVycm9yKCBmYWxzZSApOwoKICAgICAgICAgICAgaWYgKCAhbV9wU3FsSXRlcmF0b3IgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBiRXJyb3IgPSB0cnVlOwogICAgICAgICAgICB9CgkJICAgIGVsc2UgaWYgKCBtX2JFc2NhcGVQcm9jZXNzaW5nICkKCQkgICAgewoJCQkgICAgOjpydGw6Ok9VU3RyaW5nIGFFcnJvck1zZzsKICAgICAgICAgICAgICAgIDo6c3RkOjphdXRvX3B0cjwgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgPiBwTm9kZSgKICAgICAgICAgICAgICAgICAgICBtX2FTcWxQYXJzZXIucGFyc2VUcmVlKCBhRXJyb3JNc2csIG1fc1N0YXRlbWVudCwgbV9iR3JhcGhpY2FsRGVzaWduICkgKTsKCiAgICAgICAgICAgICAgICBpZiAoIHBOb2RlLmdldCgpICkKCQkJICAgIHsKCQkJCSAgICBkZWxldGUgbV9wU3FsSXRlcmF0b3ItPmdldFBhcnNlVHJlZSgpOwoJCQkJICAgIG1fcFNxbEl0ZXJhdG9yLT5zZXRQYXJzZVRyZWUoIHBOb2RlLnJlbGVhc2UoKSApOwoJCQkJICAgIG1fcFNxbEl0ZXJhdG9yLT50cmF2ZXJzZUFsbCgpOwogICAgICAgICAgICAgICAgICAgIGlmICggbV9wU3FsSXRlcmF0b3ItPmhhc0Vycm9ycygpICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIWlfYkZvcmNlQ3VycmVudENvbnRyb2xsZXJTZXR0aW5ncyAmJiBtX2JHcmFwaGljYWxEZXNpZ24gJiYgIWVkaXRpbmdWaWV3KCkgKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXBsX3Nob3dBdXRvU1FMVmlld0Vycm9yKCBtYWtlQW55KCBtX3BTcWxJdGVyYXRvci0+Z2V0RXJyb3JzKCkgKSApOwogICAgICAgICAgICAgICAgICAgICAgICB9CgkJCQkJICAgIGJFcnJvciA9IHRydWU7CgkJCQkgICAgfQoJCQkgICAgfQoJCQkgICAgZWxzZQoJCQkgICAgewogICAgICAgICAgICAgICAgICAgIGlmICggIWlfYkZvcmNlQ3VycmVudENvbnRyb2xsZXJTZXR0aW5ncyAmJiAhZWRpdGluZ1ZpZXcoKSApCiAgICAgICAgICAgICAgICAgICAgewoJCQkJICAgICAgICBTdHJpbmcgYVRpdGxlKE1vZHVsZVJlcyhTVFJfU1ZUX1NRTF9TWU5UQVhfRVJST1IpKTsKCQkJCSAgICAgICAgT1NRTE1lc3NhZ2VCb3ggYURsZyhnZXRWaWV3KCksYVRpdGxlLGFFcnJvck1zZyk7CgkJCQkgICAgICAgIGFEbGcuRXhlY3V0ZSgpOwogICAgICAgICAgICAgICAgICAgIH0KCQkJCSAgICBiRXJyb3IgPSB0cnVlOwoJCQkgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIGJFcnJvciApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG1fYkdyYXBoaWNhbERlc2lnbiA9IHNhbF9GYWxzZTsKICAgICAgICAgICAgICAgIGlmICggZWRpdGluZ1ZpZXcoKSApCiAgICAgICAgICAgICAgICAgICAgLy8gaWYgd2UncmUgZWRpdGluZyBhIHZpZXcgd2hvc2Ugc3RhdGVtZW50IGNvdWxkIG5vdCBiZSBwYXJzZWQsIGRlZmF1bHQgdG8gIm5vIGVzY2FwZSBwcm9jZXNzaW5nIgogICAgICAgICAgICAgICAgICAgIHNldEVzY2FwZVByb2Nlc3NpbmdfZmlyZUV2ZW50KCBzYWxfRmFsc2UgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCX0KCglpZighbV9wU3FsSXRlcmF0b3IpCgkJc2V0UXVlcnlDb21wb3NlcigpOwoJT1NMX0VOU1VSRShtX3BTcWxJdGVyYXRvciwiTm8gU1FMSXRlcmF0b3Igc2V0ISIpOwoKCWdldENvbnRhaW5lcigpLT5zZXROb25lVmlzYmxlUm93KG1fblZpc2libGVSb3dzKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpyZXNldCgpCnsKCWltcGxfcmVzZXQoKTsKCWdldENvbnRhaW5lcigpLT5yZXNldCggTlVMTCApOwoJQ2xlYXJVbmRvTWFuYWdlcigpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OnNldFN0YXRlbWVudF9maXJlRXZlbnQoIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgX3JOZXdTdGF0ZW1lbnQsIGJvb2wgX2JGaXJlU3RhdGVtZW50Q2hhbmdlICkKewogICAgQW55IGFPbGRWYWx1ZSA9IG1ha2VBbnkoIG1fc1N0YXRlbWVudCApOwogICAgbV9zU3RhdGVtZW50ID0gX3JOZXdTdGF0ZW1lbnQ7CiAgICBBbnkgYU5ld1ZhbHVlID0gbWFrZUFueSggbV9zU3RhdGVtZW50ICk7CgogICAgc2FsX0ludDMyIG5IYW5kbGUgPSBQUk9QRVJUWV9JRF9BQ1RJVkVDT01NQU5EOwogICAgaWYgKCBfYkZpcmVTdGF0ZW1lbnRDaGFuZ2UgKQogICAgICAgIGZpcmUoICZuSGFuZGxlLCAmYU5ld1ZhbHVlLCAmYU9sZFZhbHVlLCAxLCBzYWxfRmFsc2UgKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpzZXRFc2NhcGVQcm9jZXNzaW5nX2ZpcmVFdmVudCggY29uc3Qgc2FsX0Jvb2wgX2JFc2NhcGVQcm9jZXNzaW5nICkKewogICAgaWYgKCBfYkVzY2FwZVByb2Nlc3NpbmcgPT0gbV9iRXNjYXBlUHJvY2Vzc2luZyApCiAgICAgICAgcmV0dXJuOwoKICAgIEFueSBhT2xkVmFsdWUgPSBtYWtlQW55KCBtX2JFc2NhcGVQcm9jZXNzaW5nICk7CiAgICBtX2JFc2NhcGVQcm9jZXNzaW5nID0gX2JFc2NhcGVQcm9jZXNzaW5nOwogICAgQW55IGFOZXdWYWx1ZSA9IG1ha2VBbnkoIG1fYkVzY2FwZVByb2Nlc3NpbmcgKTsKCiAgICBzYWxfSW50MzIgbkhhbmRsZSA9IFBST1BFUlRZX0lEX0VTQ0FQRV9QUk9DRVNTSU5HOwogICAgZmlyZSggJm5IYW5kbGUsICZhTmV3VmFsdWUsICZhT2xkVmFsdWUsIDEsIHNhbF9GYWxzZSApOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpJTVBMX0xJTksoIE9RdWVyeUNvbnRyb2xsZXIsIE9uRXhlY3V0ZUFkZFRhYmxlLCB2b2lkKiwgLypwTm90SW50ZXJlc3RlZEluKi8gKQp7CiAgICBFeGVjdXRlKCBJRF9CUk9XU0VSX0FERFRBQkxFLFNlcXVlbmNlPFByb3BlcnR5VmFsdWU+KCkgKTsKICAgIHJldHVybiAwTDsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYm9vbCBPUXVlcnlDb250cm9sbGVyOjphbGxvd1ZpZXdzKCkgY29uc3QKewogICAgcmV0dXJuIHRydWU7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgT1F1ZXJ5Q29udHJvbGxlcjo6YWxsb3dRdWVyaWVzKCkgY29uc3QKewogICAgREJHX0FTU0VSVCggZ2V0U2RiTWV0YURhdGEoKS5pc0Nvbm5lY3RlZCgpLCAiT1F1ZXJ5Q29udHJvbGxlcjo6YWxsb3dRdWVyaWVzOiBpbGxlZ2FsIGNhbGwhIiApOwogICAgaWYgKCAhZ2V0U2RiTWV0YURhdGEoKS5zdXBwb3J0c1N1YnF1ZXJpZXNJbkZyb20oKSApCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIGNvbnN0IE5hbWVkVmFsdWVDb2xsZWN0aW9uJiByQXJndW1lbnRzKCBnZXRJbml0UGFyYW1zKCkgKTsKICAgIHNhbF9JbnQzMiBuQ29tbWFuZFR5cGUgPSByQXJndW1lbnRzLmdldE9yRGVmYXVsdCggKDo6cnRsOjpPVVN0cmluZylQUk9QRVJUWV9DT01NQU5EX1RZUEUsIChzYWxfSW50MzIpQ29tbWFuZFR5cGU6OlFVRVJZICk7CiAgICBzYWxfQm9vbCBiQ3JlYXRpbmdWaWV3ID0gKCBuQ29tbWFuZFR5cGUgPT0gQ29tbWFuZFR5cGU6OlRBQkxFICk7CiAgICByZXR1cm4gIWJDcmVhdGluZ1ZpZXc7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkFueSBTQUxfQ0FMTCBPUXVlcnlDb250cm9sbGVyOjpnZXRWaWV3RGF0YSgpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBnZXRNdXRleCgpICk7CgogICAgZ2V0Q29udGFpbmVyKCktPlNhdmVVSUNvbmZpZygpOwoKICAgIDo6Y29tcGhlbHBlcjo6TmFtZWRWYWx1ZUNvbGxlY3Rpb24gYVZpZXdTZXR0aW5nczsKCXNhdmVWaWV3U2V0dGluZ3MoIGFWaWV3U2V0dGluZ3MsIGZhbHNlICk7CgoJcmV0dXJuIG1ha2VBbnkoIGFWaWV3U2V0dGluZ3MuZ2V0UHJvcGVydHlWYWx1ZXMoKSApOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgT1F1ZXJ5Q29udHJvbGxlcjo6cmVzdG9yZVZpZXdEYXRhKGNvbnN0IEFueSYgLypEYXRhKi8pIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgLy8gVE9ETwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp9IC8vIG5hbWVzcGFjZSBkYmF1aQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo=