LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfZGJ1aS5oeHgiCgojaW5jbHVkZSAiYWR0YWJkbGcuaHh4IgojaW5jbHVkZSAiYnJvd3Nlcmlkcy5oeHgiCiNpbmNsdWRlICJkYnVfcXJ5LmhyYyIKI2luY2x1ZGUgImRidV9yZWdoZWxwZXIuaHh4IgojaW5jbHVkZSAiZGJ1c3RyaW5ncy5ocmMiCiNpbmNsdWRlICJkZWZhdWx0b2JqZWN0bmFtZWNoZWNrLmh4eCIKI2luY2x1ZGUgImRsZ3NhdmUuaHh4IgojaW5jbHVkZSAibG9jYWxyZXNhY2Nlc3MuaHh4IgojaW5jbHVkZSAiUVRhYmxlV2luZG93Lmh4eCIKI2luY2x1ZGUgIlFUYWJsZVdpbmRvd0RhdGEuaHh4IgojaW5jbHVkZSAicXVlcnljb250YWluZXJ3aW5kb3cuaHh4IgojaW5jbHVkZSAicXVlcnljb250cm9sbGVyLmh4eCIKI2luY2x1ZGUgIlF1ZXJ5RGVzaWduVmlldy5oeHgiCiNpbmNsdWRlICJRdWVyeVRhYmxlVmlldy5oeHgiCiNpbmNsdWRlICJRdWVyeVRleHRWaWV3Lmh4eCIKI2luY2x1ZGUgInF1ZXJ5dmlldy5oeHgiCiNpbmNsdWRlICJRdWVyeVZpZXdTd2l0Y2guaHh4IgojaW5jbHVkZSAic3FsbWVzc2FnZS5oeHgiCiNpbmNsdWRlICJUYWJsZUNvbm5lY3Rpb25EYXRhLmh4eCIKI2luY2x1ZGUgIlRhYmxlRmllbGREZXNjcmlwdGlvbi5oeHgiCiNpbmNsdWRlICJVSVRvb2xzLmh4eCIKCi8qKiA9PT0gYmVnaW4gVU5PIGluY2x1ZGVzID09PSAqKi8KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9iZWFucy9Qcm9wZXJ0eUF0dHJpYnV0ZS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvY29udGFpbmVyL1hDaGlsZC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvY29udGFpbmVyL1hOYW1lQ29udGFpbmVyLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9mcmFtZS9GcmFtZVNlYXJjaEZsYWcuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2ZyYW1lL1hMb2FkRXZlbnRMaXN0ZW5lci5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvaW8vWEFjdGl2ZURhdGFTaW5rLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9pby9YQWN0aXZlRGF0YVNvdXJjZS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiL0NvbW1hbmRUeXBlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGIvU1FMQ29udGV4dC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiL1hRdWVyaWVzU3VwcGxpZXIuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYi9YUXVlcnlEZWZpbml0aW9uc1N1cHBsaWVyLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGIvWFNRTFF1ZXJ5Q29tcG9zZXJGYWN0b3J5LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGJjL1NRTFdhcm5pbmcuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmMvWFJvdy5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiY3gvWEFwcGVuZC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiY3gvWERhdGFEZXNjcmlwdG9yRmFjdG9yeS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiY3gvWERyb3AuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmN4L1hUYWJsZXNTdXBwbGllci5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiY3gvWFZpZXdzU3VwcGxpZXIuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3VpL2RpYWxvZ3MvWEV4ZWN1dGFibGVEaWFsb2cuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3V0aWwvWENsb3NlYWJsZS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvdXRpbC9WZXRvRXhjZXB0aW9uLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9mcmFtZS9YVW50aXRsZWROdW1iZXJzLmhwcD4KLyoqID09PSBlbmQgVU5PIGluY2x1ZGVzID09PSAqKi8KCiNpbmNsdWRlIDxjb21waGVscGVyL2Jhc2ljaW8uaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9leHRyYWN0Lmh4eD4KI2luY2x1ZGUgPGNvbXBoZWxwZXIvcHJvcGVydHkuaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9zZXFzdHJlYW0uaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9zdHJlYW1zZWN0aW9uLmh4eD4KI2luY2x1ZGUgPGNvbXBoZWxwZXIvdHlwZXMuaHh4PgojaW5jbHVkZSA8Y29ubmVjdGl2aXR5L2RiZXhjZXB0aW9uLmh4eD4KI2luY2x1ZGUgPGNvbm5lY3Rpdml0eS9kYnRvb2xzLmh4eD4KI2luY2x1ZGUgPGNwcHVoZWxwZXIvZXhjX2hscC5oeHg+CiNpbmNsdWRlIDxzZngyL3NmeHNpZHMuaHJjPgojaW5jbHVkZSA8c3Z0b29scy9sb2NhbHJlc2FjY2Vzcy5oeHg+CiNpbmNsdWRlIDx0b29sa2l0L2hlbHBlci92Y2x1bm9oZWxwZXIuaHh4PgojaW5jbHVkZSA8dG9vbHMvZGlhZ25vc2VfZXguaD4KI2luY2x1ZGUgPHZjbC9tc2dib3guaHh4PgojaW5jbHVkZSA8dmNsL3N2YXBwLmh4eD4KI2luY2x1ZGUgPHZvcy9tdXRleC5oeHg+CgpleHRlcm4gIkMiIHZvaWQgU0FMX0NBTEwgY3JlYXRlUmVnaXN0cnlJbmZvX09RdWVyeUNvbnRyb2woKQp7CglzdGF0aWMgOjpkYmF1aTo6T011bHRpSW5zdGFuY2VBdXRvUmVnaXN0cmF0aW9uPCA6OmRiYXVpOjpPUXVlcnlDb250cm9sbGVyID4gYUF1dG9SZWdpc3RyYXRpb247Cn0KbmFtZXNwYWNlIGRiYXVpCnsKICAgIHVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjp1bm87CiAgICB1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6YmVhbnM7CiAgICB1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU7CiAgICB1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDsKICAgIHVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpsYW5nOwoKICAgIGNsYXNzIE9WaWV3Q29udHJvbGxlciA6IHB1YmxpYyBPUXVlcnlDb250cm9sbGVyCiAgICB7CiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICB2aXJ0dWFsIDo6cnRsOjpPVVN0cmluZyBTQUxfQ0FMTCBnZXRJbXBsZW1lbnRhdGlvbk5hbWUoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCiAgICAgICAgewoJICAgICAgICByZXR1cm4gZ2V0SW1wbGVtZW50YXRpb25OYW1lX1N0YXRpYygpOwogICAgICAgIH0KICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICB2aXJ0dWFsIFNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmc+IFNBTF9DQUxMIGdldFN1cHBvcnRlZFNlcnZpY2VOYW1lcygpIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCiAgICAgICAgewoJICAgICAgICByZXR1cm4gZ2V0U3VwcG9ydGVkU2VydmljZU5hbWVzX1N0YXRpYygpOwogICAgICAgIH0KICAgIHB1YmxpYzoKICAgICAgICBPVmlld0NvbnRyb2xsZXIoY29uc3QgUmVmZXJlbmNlPCBYTXVsdGlTZXJ2aWNlRmFjdG9yeSA+JiBfck0pIDogT1F1ZXJ5Q29udHJvbGxlcihfck0pe30KCiAgICAgICAgLy8gbmVlZCBieSByZWdpc3RyYXRpb24KCSAgICBzdGF0aWMgOjpydGw6Ok9VU3RyaW5nIGdldEltcGxlbWVudGF0aW9uTmFtZV9TdGF0aWMoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCiAgICAgICAgewoJICAgICAgICByZXR1cm4gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIm9yZy5vcGVub2ZmaWNlLmNvbXAuZGJ1Lk9WaWV3RGVzaWduIik7CiAgICAgICAgfQoJICAgIHN0YXRpYyBTZXF1ZW5jZTwgOjpydGw6Ok9VU3RyaW5nID4gZ2V0U3VwcG9ydGVkU2VydmljZU5hbWVzX1N0YXRpYyh2b2lkKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCiAgICAgICAgewogICAgICAgICAgICBTZXF1ZW5jZTwgOjpydGw6Ok9VU3RyaW5nPiBhU3VwcG9ydGVkKDEpOwoJICAgICAgICBhU3VwcG9ydGVkLmdldEFycmF5KClbMF0gPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiY29tLnN1bi5zdGFyLnNkYi5WaWV3RGVzaWduIik7CgkgICAgICAgIHJldHVybiBhU3VwcG9ydGVkOwogICAgICAgIH0KCSAgICBzdGF0aWMgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gU0FMX0NBTEwgQ3JlYXRlKGNvbnN0IFJlZmVyZW5jZTwgWE11bHRpU2VydmljZUZhY3RvcnkgPiYgX3JNKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICoobmV3IE9WaWV3Q29udHJvbGxlcihfck0pKTsKICAgICAgICB9CiAgICB9Owp9CmV4dGVybiAiQyIgdm9pZCBTQUxfQ0FMTCBjcmVhdGVSZWdpc3RyeUluZm9fT1ZpZXdDb250cm9sKCkKewoJc3RhdGljIDo6ZGJhdWk6Ok9NdWx0aUluc3RhbmNlQXV0b1JlZ2lzdHJhdGlvbjwgOjpkYmF1aTo6T1ZpZXdDb250cm9sbGVyID4gYUF1dG9SZWdpc3RyYXRpb247Cn0KCm5hbWVzcGFjZSBkYmF1aQp7Cgl1c2luZyBuYW1lc3BhY2UgOjpjb25uZWN0aXZpdHk7CiNpZiBPU0xfREVCVUdfTEVWRUwgPiAxCgluYW1lc3BhY2UKCXsKCQkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCXZvaWQgaW5zZXJ0UGFyc2VUcmVlKFN2VHJlZUxpc3RCb3gqIF9wQm94LDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBfcE5vZGUsU3ZMQm94RW50cnkqIF9wUGFyZW50ID0gTlVMTCkKCQl7CgkJCTo6cnRsOjpPVVN0cmluZyByU3RyaW5nOwoJCQlpZiAoIV9wTm9kZS0+aXNUb2tlbigpKQoJCQl7CgkJCQkvLyBSZWdlbG5hbWVuIGFscyBydWxlOiAuLi4KCQkJCXJTdHJpbmcgPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiUlVMRV9JRDogIik7CgkJCQlyU3RyaW5nICs9IDo6cnRsOjpPVVN0cmluZzo6dmFsdWVPZiggKHNhbF9JbnQzMilfcE5vZGUtPmdldFJ1bGVJRCgpKTsKCQkJCXJTdHJpbmcrPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiKCIpOwoJCQkJclN0cmluZyArPSBPU1FMUGFyc2VyOjpSdWxlSURUb1N0cihfcE5vZGUtPmdldFJ1bGVJRCgpKTsKCQkJCXJTdHJpbmcrPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiKSIpOwoKCgkJCQlfcFBhcmVudCA9IF9wQm94LT5JbnNlcnRFbnRyeShyU3RyaW5nLF9wUGFyZW50KTsKCgkJCQkvLyBlaW5tYWwgYXVzd2VydGVuIHdpZXZpZWwgU3VidHJlZXMgZGllc2VyIEtub3RlbiBiZXNpdHp0CgkJCQlzYWxfdUludDMyIG5TdG9wID0gX3BOb2RlLT5jb3VudCgpOwoJCQkJLy8gaG9sIGRpciBkZW4gZXJzdGVuIFN1YnRyZWUKCQkJCWZvcihzYWxfdUludDMyIGk9MDtpPG5TdG9wOysraSkKCQkJCQlpbnNlcnRQYXJzZVRyZWUoX3BCb3gsX3BOb2RlLT5nZXRDaGlsZChpKSxfcFBhcmVudCk7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQkvLyBlaW4gVG9rZW4gZ2VmdW5kZW4KCQkJCS8vIHRhYnMgZnVlciBkYXMgRWlucnVlY2tlbiBlbnRzcHJlY2hlbmQgbkxldmVsCgoJCQkJc3dpdGNoIChfcE5vZGUtPmdldE5vZGVUeXBlKCkpCgkJCQl7CgoJCQkJY2FzZSBTUUxfTk9ERV9LRVlXT1JEOgoJCQkJCXsKCQkJCQkJclN0cmluZys9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJTUUxfS0VZV09SRDoiKTsKCQkJCQkJOjpydGw6Ok9TdHJpbmcgc1QgPSBPU1FMUGFyc2VyOjpUb2tlbklEVG9TdHIoX3BOb2RlLT5nZXRUb2tlbklEKCkpOwoJCQkJCQlyU3RyaW5nICs9IDo6cnRsOjpPU3RyaW5nVG9PVVN0cmluZyggc1QsIFJUTF9URVhURU5DT0RJTkdfVVRGOCk7CgkJCQkJIGJyZWFrO30KCgkJCQljYXNlIFNRTF9OT0RFX0NPTVBBUklTT046CgkJCQkJe3JTdHJpbmcrPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiU1FMX0NPTVBBUklTT046Iik7CgkJCQkJclN0cmluZyArPSBfcE5vZGUtPmdldFRva2VuVmFsdWUoKTsJLy8gaGFlbmdlIE5vZGV2YWx1ZSBhbgoJCQkJCQkJLy8gdW5kIGJlZ2lubmUgbmV1IFplaWxlCgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgU1FMX05PREVfTkFNRToKCQkJCQl7clN0cmluZys9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJTUUxfTkFNRToiKTsKCQkJCQkgclN0cmluZys9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJcIiIpOwoJCQkJCSByU3RyaW5nICs9IF9wTm9kZS0+Z2V0VG9rZW5WYWx1ZSgpOwoJCQkJCSByU3RyaW5nKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlwiIik7CgoJCQkJCSBicmVhazt9CgoJCQkJY2FzZSBTUUxfTk9ERV9TVFJJTkc6CgkJCQkJe3JTdHJpbmcgKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlNRTF9TVFJJTkc6JyIpOwoJCQkJCSByU3RyaW5nICs9IF9wTm9kZS0+Z2V0VG9rZW5WYWx1ZSgpOwoJCQkJCSBicmVhazt9CgoJCQkJY2FzZSBTUUxfTk9ERV9JTlROVU06CgkJCQkJe3JTdHJpbmcgKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlNRTF9JTlROVU06Iik7CgkJCQkJIHJTdHJpbmcgKz0gX3BOb2RlLT5nZXRUb2tlblZhbHVlKCk7CgkJCQkJIGJyZWFrO30KCgkJCQljYXNlIFNRTF9OT0RFX0FQUFJPWE5VTToKCQkJCQl7clN0cmluZyArPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiU1FMX0FQUFJPWE5VTToiKTsKCQkJCQkgclN0cmluZyArPSBfcE5vZGUtPmdldFRva2VuVmFsdWUoKTsKCQkJCQkgYnJlYWs7fQoKCQkJCWNhc2UgU1FMX05PREVfUFVOQ1RVQVRJT046CgkJCQkJe3JTdHJpbmcgKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlNRTF9QVU5DVFVBVElPTjoiKTsKCQkJCQlyU3RyaW5nICs9IF9wTm9kZS0+Z2V0VG9rZW5WYWx1ZSgpOwkvLyBoYWVuZ2UgTm9kZXZhbHVlIGFuCgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgU1FMX05PREVfQU1NU0M6CgkJCQkJe3JTdHJpbmcgKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlNRTF9BTU1TQzoiKTsKCQkJCQlyU3RyaW5nICs9IF9wTm9kZS0+Z2V0VG9rZW5WYWx1ZSgpOwkvLyBoYWVuZ2UgTm9kZXZhbHVlIGFuCgoJCQkJCWJyZWFrO30KCgkJCQlkZWZhdWx0OgoJCQkJCU9TTF9BU1NFUlQoIk9TUUxQYXJzZXI6OlNob3dQYXJzZVRyZWU6IHVuenVsYWVzc2lnZXIgTm9kZVR5cGUiKTsKCQkJCQlyU3RyaW5nICs9IF9wTm9kZS0+Z2V0VG9rZW5WYWx1ZSgpOwoJCQkJfQoJCQkJX3BCb3gtPkluc2VydEVudHJ5KHJTdHJpbmcsX3BQYXJlbnQpOwoJCQl9CgkJfQoJfQojZW5kaWYgLy8gT1NMX0RFQlVHX0xFVkVMCgogICAgbmFtZXNwYWNlCiAgICB7CgkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICBTdHJpbmcgbGNsX2dldE9iamVjdFJlc291cmNlU3RyaW5nKCBzYWxfdUludDE2IF9uUmVzSWQsIHNhbF9JbnQzMiBfbkNvbW1hbmRUeXBlICkKICAgICAgICB7CiAgICAgICAgICAgIFN0cmluZyBzTWVzc2FnZVRleHQgPSBTdHJpbmcoIE1vZHVsZVJlcyggX25SZXNJZCApICk7CiAgICAgICAgICAgIFN0cmluZyBzT2JqZWN0VHlwZTsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTG9jYWxSZXNvdXJjZUFjY2VzcyBhTG9jYWxSZXMoIFJTQ19RVUVSWV9PQkpFQ1RfVFlQRSwgUlNDX1JFU09VUkNFICk7CiAgICAgICAgICAgICAgICBzT2JqZWN0VHlwZSA9IFN0cmluZyggTW9kdWxlUmVzKCAoc2FsX3VJbnQxNikoIF9uQ29tbWFuZFR5cGUgKyAxICkgKSApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNNZXNzYWdlVGV4dC5TZWFyY2hBbmRSZXBsYWNlKCBTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSggIiRvYmplY3QkIiApLCBzT2JqZWN0VHlwZSApOwogICAgICAgICAgICByZXR1cm4gc01lc3NhZ2VUZXh0OwogICAgICAgIH0KICAgIH0KCnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjp1bm87CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjppbzsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OmJlYW5zOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6bGFuZzsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OmNvbnRhaW5lcjsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnNkYmN4Owp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6c2RiYzsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnNkYjsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnVpOjpkaWFsb2dzOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6YXd0Owp1c2luZyBuYW1lc3BhY2UgOjpkYnRvb2xzOwoKdXNpbmcgbmFtZXNwYWNlIDo6Y29tcGhlbHBlcjsKCm5hbWVzcGFjZQp7Cgl2b2lkIGVuc3VyZVRvb2xiYXJzKCBPUXVlcnlDb250cm9sbGVyJiBfckNvbnRyb2xsZXIsIHNhbF9Cb29sIF9iRGVzaWduICkKICAgIHsKICAgICAgICBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYTGF5b3V0TWFuYWdlciA+IHhMYXlvdXRNYW5hZ2VyID0gX3JDb250cm9sbGVyLmdldExheW91dE1hbmFnZXIoIF9yQ29udHJvbGxlci5nZXRGcmFtZSgpICk7CgkJaWYgKCB4TGF5b3V0TWFuYWdlci5pcygpICkKCQl7CgkJCXhMYXlvdXRNYW5hZ2VyLT5sb2NrKCk7CgkJCXN0YXRpYyA6OnJ0bDo6T1VTdHJpbmcgc19zRGVzaWduVG9vbGJhcihSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oInByaXZhdGU6cmVzb3VyY2UvdG9vbGJhci9kZXNpZ25vYmplY3RiYXIiKSk7CgkJCXN0YXRpYyA6OnJ0bDo6T1VTdHJpbmcgc19zU3FsVG9vbGJhcihSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oInByaXZhdGU6cmVzb3VyY2UvdG9vbGJhci9zcWxvYmplY3RiYXIiKSk7CgkJCWlmICggX2JEZXNpZ24gKQoJCQl7CgkJCQl4TGF5b3V0TWFuYWdlci0+ZGVzdHJveUVsZW1lbnQoIHNfc1NxbFRvb2xiYXIgKTsKCQkJCXhMYXlvdXRNYW5hZ2VyLT5jcmVhdGVFbGVtZW50KCBzX3NEZXNpZ25Ub29sYmFyICk7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQl4TGF5b3V0TWFuYWdlci0+ZGVzdHJveUVsZW1lbnQoIHNfc0Rlc2lnblRvb2xiYXIgKTsKCQkJCXhMYXlvdXRNYW5hZ2VyLT5jcmVhdGVFbGVtZW50KCBzX3NTcWxUb29sYmFyICk7CgkJCX0KCQkJeExheW91dE1hbmFnZXItPnVubG9jaygpOwogICAgICAgICAgICB4TGF5b3V0TWFuYWdlci0+ZG9MYXlvdXQoKTsKCQl9CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6cnRsOjpPVVN0cmluZyBTQUxfQ0FMTCBPUXVlcnlDb250cm9sbGVyOjpnZXRJbXBsZW1lbnRhdGlvbk5hbWUoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCXJldHVybiBnZXRJbXBsZW1lbnRhdGlvbk5hbWVfU3RhdGljKCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6cnRsOjpPVVN0cmluZyBPUXVlcnlDb250cm9sbGVyOjpnZXRJbXBsZW1lbnRhdGlvbk5hbWVfU3RhdGljKCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglyZXR1cm4gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIm9yZy5vcGVub2ZmaWNlLmNvbXAuZGJ1Lk9RdWVyeURlc2lnbiIpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmc+IE9RdWVyeUNvbnRyb2xsZXI6OmdldFN1cHBvcnRlZFNlcnZpY2VOYW1lc19TdGF0aWModm9pZCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglTZXF1ZW5jZTwgOjpydGw6Ok9VU3RyaW5nPiBhU3VwcG9ydGVkKDEpOwoJYVN1cHBvcnRlZC5nZXRBcnJheSgpWzBdID0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoImNvbS5zdW4uc3Rhci5zZGIuUXVlcnlEZXNpZ24iKTsKCXJldHVybiBhU3VwcG9ydGVkOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTZXF1ZW5jZTwgOjpydGw6Ok9VU3RyaW5nPiBTQUxfQ0FMTCBPUXVlcnlDb250cm9sbGVyOjpnZXRTdXBwb3J0ZWRTZXJ2aWNlTmFtZXMoKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQp7CglyZXR1cm4gZ2V0U3VwcG9ydGVkU2VydmljZU5hbWVzX1N0YXRpYygpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gU0FMX0NBTEwgT1F1ZXJ5Q29udHJvbGxlcjo6Q3JlYXRlKGNvbnN0IFJlZmVyZW5jZTxYTXVsdGlTZXJ2aWNlRmFjdG9yeSA+JiBfcnhGYWN0b3J5KQp7CglyZXR1cm4gKihuZXcgT1F1ZXJ5Q29udHJvbGxlcihfcnhGYWN0b3J5KSk7Cn0KREJHX05BTUUoT1F1ZXJ5Q29udHJvbGxlcik7Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk9RdWVyeUNvbnRyb2xsZXI6Ok9RdWVyeUNvbnRyb2xsZXIoY29uc3QgUmVmZXJlbmNlPCBYTXVsdGlTZXJ2aWNlRmFjdG9yeSA+JiBfck0pCiAgICA6T0pvaW5Db250cm9sbGVyKF9yTSkKICAgICxPUXVlcnlDb250cm9sbGVyX1BCYXNlKCBnZXRCcm9hZGNhc3RIZWxwZXIoKSApCiAgICAsbV9wUGFyc2VDb250ZXh0KCBuZXcgc3Z4Zm9ybTo6T1N5c3RlbVBhcnNlQ29udGV4dCApCiAgICAsbV9hU3FsUGFyc2VyKCBfck0sIG1fcFBhcnNlQ29udGV4dCApCgksbV9wU3FsSXRlcmF0b3IoTlVMTCkKCSxtX25WaXNpYmxlUm93cygweDQwMCkKCSxtX25TcGxpdFBvcygtMSkKICAgICxtX25Db21tYW5kVHlwZSggQ29tbWFuZFR5cGU6OlFVRVJZICkKICAgICxtX2JHcmFwaGljYWxEZXNpZ24oc2FsX0ZhbHNlKQoJLG1fYkRpc3RpbmN0KHNhbF9GYWxzZSkKCSxtX2JWaWV3QWxpYXMoc2FsX0ZhbHNlKQogICAgLG1fYlZpZXdUYWJsZShzYWxfRmFsc2UpCgksbV9iVmlld0Z1bmN0aW9uKHNhbF9GYWxzZSkKCSxtX2JFc2NhcGVQcm9jZXNzaW5nKHNhbF9UcnVlKQp7CglEQkdfQ1RPUihPUXVlcnlDb250cm9sbGVyLE5VTEwpOwoJSW52YWxpZGF0ZUFsbCgpOwoKCXJlZ2lzdGVyUHJvcGVydHkoIFBST1BFUlRZX0FDVElWRUNPTU1BTkQsIFBST1BFUlRZX0lEX0FDVElWRUNPTU1BTkQsIFByb3BlcnR5QXR0cmlidXRlOjpSRUFET05MWSB8IFByb3BlcnR5QXR0cmlidXRlOjpCT1VORCwKCQkmbV9zU3RhdGVtZW50LCA6OmdldENwcHVUeXBlKCAmbV9zU3RhdGVtZW50ICkgKTsKCXJlZ2lzdGVyUHJvcGVydHkoIFBST1BFUlRZX0VTQ0FQRV9QUk9DRVNTSU5HLCBQUk9QRVJUWV9JRF9FU0NBUEVfUFJPQ0VTU0lORywgUHJvcGVydHlBdHRyaWJ1dGU6OlJFQURPTkxZIHwgUHJvcGVydHlBdHRyaWJ1dGU6OkJPVU5ELAoJCSZtX2JFc2NhcGVQcm9jZXNzaW5nLCA6OmdldENwcHVUeXBlKCAmbV9iRXNjYXBlUHJvY2Vzc2luZyApICk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk9RdWVyeUNvbnRyb2xsZXI6On5PUXVlcnlDb250cm9sbGVyKCkKewoJREJHX0RUT1IoT1F1ZXJ5Q29udHJvbGxlcixOVUxMKTsKCWlmICggIWdldEJyb2FkY2FzdEhlbHBlcigpLmJEaXNwb3NlZCAmJiAhZ2V0QnJvYWRjYXN0SGVscGVyKCkuYkluRGlzcG9zZSApCgl7CgkJT1NMX0VOU1VSRSgwLCJQbGVhc2UgY2hlY2sgd2hvIGRvZXNuJ3QgZGlzcG9zZSB0aGlzIGNvbXBvbmVudCEiKTsKICAgICAgICAvLyBpbmNyZW1lbnQgcmVmIGNvdW50IHRvIHByZXZlbnQgZG91YmxlIGNhbGwgb2YgRHRvcgogICAgICAgIG9zbF9pbmNyZW1lbnRJbnRlcmxvY2tlZENvdW50KCAmbV9yZWZDb3VudCApOwogICAgICAgIGRpc3Bvc2UoKTsKCX0KfQoKSU1QTEVNRU5UX0ZPUldBUkRfWElOVEVSRkFDRTIoIE9RdWVyeUNvbnRyb2xsZXIsIE9Kb2luQ29udHJvbGxlciwgT1F1ZXJ5Q29udHJvbGxlcl9QQmFzZSApCklNUExFTUVOVF9GT1JXQVJEX1hUWVBFUFJPVklERVIyKCBPUXVlcnlDb250cm9sbGVyLCBPSm9pbkNvbnRyb2xsZXIsIE9RdWVyeUNvbnRyb2xsZXJfUEJhc2UgKQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWFByb3BlcnR5U2V0SW5mbyA+IFNBTF9DQUxMIE9RdWVyeUNvbnRyb2xsZXI6OmdldFByb3BlcnR5U2V0SW5mbygpIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCnsKCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0SW5mbyA+IHhJbmZvKCBjcmVhdGVQcm9wZXJ0eVNldEluZm8oIGdldEluZm9IZWxwZXIoKSApICk7CglyZXR1cm4geEluZm87Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBTQUxfQ0FMTCBPUXVlcnlDb250cm9sbGVyOjpjb252ZXJ0RmFzdFByb3BlcnR5VmFsdWUoIEFueSYgb19yQ29udmVydGVkVmFsdWUsIEFueSYgb19yT2xkVmFsdWUsIHNhbF9JbnQzMiBpX25IYW5kbGUsIGNvbnN0IEFueSYgaV9yVmFsdWUgKSB0aHJvdyAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKQp7CiAgICByZXR1cm4gT1Byb3BlcnR5Q29udGFpbmVyOjpjb252ZXJ0RmFzdFByb3BlcnR5VmFsdWUoIG9fckNvbnZlcnRlZFZhbHVlLCBvX3JPbGRWYWx1ZSwgaV9uSGFuZGxlLCBpX3JWYWx1ZSApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBPUXVlcnlDb250cm9sbGVyOjpzZXRGYXN0UHJvcGVydHlWYWx1ZV9Ob0Jyb2FkY2FzdCggc2FsX0ludDMyIGlfbkhhbmRsZSwgY29uc3QgQW55JiBpX3JWYWx1ZSApIHRocm93ICggRXhjZXB0aW9uICkKewogICAgT1Byb3BlcnR5Q29udGFpbmVyOjpzZXRGYXN0UHJvcGVydHlWYWx1ZV9Ob0Jyb2FkY2FzdCggaV9uSGFuZGxlLCBpX3JWYWx1ZSApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBPUXVlcnlDb250cm9sbGVyOjpnZXRGYXN0UHJvcGVydHlWYWx1ZSggQW55JiBvX3JWYWx1ZSwgc2FsX0ludDMyIGlfbkhhbmRsZSApIGNvbnN0CnsKICAgIHN3aXRjaCAoIGlfbkhhbmRsZSApCiAgICB7CiAgICBjYXNlIFBST1BFUlRZX0lEX0NVUlJFTlRfUVVFUllfREVTSUdOOgogICAgewogICAgICAgIDo6Y29tcGhlbHBlcjo6TmFtZWRWYWx1ZUNvbGxlY3Rpb24gYUN1cnJlbnREZXNpZ247CiAgICAgICAgYUN1cnJlbnREZXNpZ24ucHV0KCAiR3JhcGhpY2FsRGVzaWduIiwgaXNHcmFwaGljYWxEZXNpZ24oKSApOwogICAgICAgIGFDdXJyZW50RGVzaWduLnB1dCggKDo6cnRsOjpPVVN0cmluZylQUk9QRVJUWV9FU0NBUEVfUFJPQ0VTU0lORywgbV9iRXNjYXBlUHJvY2Vzc2luZyApOwoKICAgICAgICBpZiAoIGlzR3JhcGhpY2FsRGVzaWduKCkgKQogICAgICAgIHsKICAgICAgICAgICAgZ2V0Q29udGFpbmVyKCktPlNhdmVVSUNvbmZpZygpOwoJICAgICAgICBzYXZlVmlld1NldHRpbmdzKCBhQ3VycmVudERlc2lnbiwgdHJ1ZSApOwogICAgICAgICAgICBhQ3VycmVudERlc2lnbi5wdXQoICJTdGF0ZW1lbnQiLCBtX3NTdGF0ZW1lbnQgKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgYUN1cnJlbnREZXNpZ24ucHV0KCAiU3RhdGVtZW50IiwgZ2V0Q29udGFpbmVyKCktPmdldFN0YXRlbWVudCgpICk7CiAgICAgICAgfQoKICAgICAgICBvX3JWYWx1ZSA8PD0gYUN1cnJlbnREZXNpZ24uZ2V0UHJvcGVydHlWYWx1ZXMoKTsKICAgIH0KICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgT1Byb3BlcnR5Q29udGFpbmVyOjpnZXRGYXN0UHJvcGVydHlWYWx1ZSggb19yVmFsdWUsIGlfbkhhbmRsZSApOwogICAgICAgIGJyZWFrOwogICAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpjcHB1OjpJUHJvcGVydHlBcnJheUhlbHBlciYgT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0SW5mb0hlbHBlcigpCnsKCXJldHVybiAqY29uc3RfY2FzdDwgT1F1ZXJ5Q29udHJvbGxlciogPiggdGhpcyApLT5nZXRBcnJheUhlbHBlcigpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6Y3BwdTo6SVByb3BlcnR5QXJyYXlIZWxwZXIqIE9RdWVyeUNvbnRyb2xsZXI6OmNyZWF0ZUFycmF5SGVscGVyKCApIGNvbnN0CnsKCVNlcXVlbmNlPCBQcm9wZXJ0eSA+IGFQcm9wczsKCWRlc2NyaWJlUHJvcGVydGllcyggYVByb3BzICk7CgogICAgLy8gb25lIGFkZGl0aW9uYWwgcHJvcGVydHk6CiAgICBjb25zdCBzYWxfSW50MzIgbkxlbmd0aCA9IGFQcm9wcy5nZXRMZW5ndGgoKTsKICAgIGFQcm9wcy5yZWFsbG9jKCBuTGVuZ3RoICsgMSApOwogICAgYVByb3BzWyBuTGVuZ3RoIF0gPSBQcm9wZXJ0eSgKICAgICAgICA6OnJ0bDo6T1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSggIkN1cnJlbnRRdWVyeURlc2lnbiIgKSApLAogICAgICAgIFBST1BFUlRZX0lEX0NVUlJFTlRfUVVFUllfREVTSUdOLAogICAgICAgIDo6Y3BwdTo6VW5vVHlwZTwgU2VxdWVuY2U8IFByb3BlcnR5VmFsdWUgPiA+OjpnZXQoKSwKICAgICAgICBQcm9wZXJ0eUF0dHJpYnV0ZTo6UkVBRE9OTFkKICAgICk7CgogICAgOjpzdGQ6OnNvcnQoCiAgICAgICAgYVByb3BzLmdldEFycmF5KCksCiAgICAgICAgYVByb3BzLmdldEFycmF5KCkgKyBhUHJvcHMuZ2V0TGVuZ3RoKCksCiAgICAgICAgOjpjb21waGVscGVyOjpQcm9wZXJ0eUNvbXBhcmVCeU5hbWUoKQogICAgKTsKCglyZXR1cm4gbmV3IDo6Y3BwdTo6T1Byb3BlcnR5QXJyYXlIZWxwZXIoYVByb3BzKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpkZWxldGVJdGVyYXRvcigpCnsKCWlmKG1fcFNxbEl0ZXJhdG9yKQoJewoJCWRlbGV0ZSBtX3BTcWxJdGVyYXRvci0+Z2V0UGFyc2VUcmVlKCk7CgkJbV9wU3FsSXRlcmF0b3ItPmRpc3Bvc2UoKTsKCQlkZWxldGUgbV9wU3FsSXRlcmF0b3I7CgkJbV9wU3FsSXRlcmF0b3IgPSBOVUxMOwoJfQp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6ZGlzcG9zaW5nKCkKewogICAgT1F1ZXJ5Q29udHJvbGxlcl9QQmFzZTo6ZGlzcG9zaW5nKCk7CgoJZGVsZXRlSXRlcmF0b3IoKTsKCglkZWxldGUgbV9wUGFyc2VDb250ZXh0OwoKCWNsZWFyRmllbGRzKCk7CglPVGFibGVGaWVsZHMoKS5zd2FwKG1fdlVuVXNlZEZpZWxkc0Rlc2MpOwoKCTo6Y29tcGhlbHBlcjo6ZGlzcG9zZUNvbXBvbmVudChtX3hDb21wb3Nlcik7CglPSm9pbkNvbnRyb2xsZXI6OmRpc3Bvc2luZygpOwogICAgT1F1ZXJ5Q29udHJvbGxlcl9QQmFzZTo6ZGlzcG9zaW5nKCk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpjbGVhckZpZWxkcygpCnsKCU9UYWJsZUZpZWxkcygpLnN3YXAobV92VGFibGVGaWVsZERlc2MpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkZlYXR1cmVTdGF0ZSBPUXVlcnlDb250cm9sbGVyOjpHZXRTdGF0ZShzYWxfdUludDE2IF9uSWQpIGNvbnN0CnsKCUZlYXR1cmVTdGF0ZSBhUmV0dXJuOwoJYVJldHVybi5iRW5hYmxlZCA9IHNhbF9UcnVlOwoJCS8vIChkaXNhYmxlZCBhdXRvbWF0aWNhbGx5KQoKCXN3aXRjaCAoX25JZCkKCXsKICAgICAgICBjYXNlIElEX0JST1dTRVJfRURJVERPQzoKICAgICAgICAgICAgaWYgKCBlZGl0aW5nQ29tbWFuZCgpICkKICAgICAgICAgICAgICAgIGFSZXR1cm4uYkVuYWJsZWQgPSBzYWxfRmFsc2U7CiAgICAgICAgICAgIGVsc2UgaWYgKCBlZGl0aW5nVmlldygpICYmICFtX3hBbHRlclZpZXcuaXMoKSApCiAgICAgICAgICAgICAgICBhUmV0dXJuLmJFbmFibGVkID0gc2FsX0ZhbHNlOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBhUmV0dXJuID0gT0pvaW5Db250cm9sbGVyOjpHZXRTdGF0ZSggX25JZCApOwogICAgICAgICAgICBicmVhazsKCgkJY2FzZSBJRF9CUk9XU0VSX0VTQUNQRVBST0NFU1NJTkc6CgkJCWFSZXR1cm4uYkNoZWNrZWQgPSAhbV9iRXNjYXBlUHJvY2Vzc2luZzsKCQkJYVJldHVybi5iRW5hYmxlZCA9ICggbV9wU3FsSXRlcmF0b3IgIT0gTlVMTCApICYmICFtX2JHcmFwaGljYWxEZXNpZ247CgkJCWJyZWFrOwoJCWNhc2UgU0lEX1JFTEFUSU9OX0FERF9SRUxBVElPTjoKCQkJYVJldHVybi5iRW5hYmxlZCA9IGlzRWRpdGFibGUoKSAmJiBtX2JHcmFwaGljYWxEZXNpZ24gJiYgbV92VGFibGVEYXRhLnNpemUoKSA+IDE7CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9TQVZFQVNET0M6CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSAhZWRpdGluZ0NvbW1hbmQoKSAmJiAhZWRpdGluZ1ZpZXcoKSAmJiAoIW1fYkdyYXBoaWNhbERlc2lnbiB8fCAhKG1fdlRhYmxlRmllbGREZXNjLmVtcHR5KCkgfHwgbV92VGFibGVEYXRhLmVtcHR5KCkpKTsKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX1NBVkVET0M6CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSBpbXBsX2lzTW9kaWZpZWQoKSAmJiAoIW1fYkdyYXBoaWNhbERlc2lnbiB8fCAhKG1fdlRhYmxlRmllbGREZXNjLmVtcHR5KCkgfHwgbV92VGFibGVEYXRhLmVtcHR5KCkpKTsKCQkJYnJlYWs7CgkJY2FzZSBTSURfUFJJTlRET0NESVJFQ1Q6CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9DVVQ6CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSBpc0VkaXRhYmxlKCkgJiYgZ2V0Q29udGFpbmVyKCkgJiYgZ2V0Q29udGFpbmVyKCktPmlzQ3V0QWxsb3dlZCgpOwoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfQ09QWToKCQkJYVJldHVybi5iRW5hYmxlZCA9IGdldENvbnRhaW5lcigpICYmIGdldENvbnRhaW5lcigpLT5pc0NvcHlBbGxvd2VkKCk7CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9QQVNURToKCQkJYVJldHVybi5iRW5hYmxlZCA9IGlzRWRpdGFibGUoKSAmJiBnZXRDb250YWluZXIoKSAmJiBnZXRDb250YWluZXIoKS0+aXNQYXN0ZUFsbG93ZWQoKTsKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX1NRTDoKCQkJYVJldHVybi5iRW5hYmxlZCA9IG1fYkVzY2FwZVByb2Nlc3NpbmcgJiYgbV9wU3FsSXRlcmF0b3I7CgkJCWFSZXR1cm4uYkNoZWNrZWQgPSBtX2JHcmFwaGljYWxEZXNpZ247CgkJCWJyZWFrOwoJCWNhc2UgU0lEX0JST1dTRVJfQ0xFQVJfUVVFUlk6CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSBpc0VkaXRhYmxlKCkgJiYgKG1fc1N0YXRlbWVudC5nZXRMZW5ndGgoKSB8fCAhbV92VGFibGVEYXRhLmVtcHR5KCkpOwoJCQlicmVhazsKCQljYXNlIFNJRF9RVUVSWV9WSUVXX0ZVTkNUSU9OUzoKCQljYXNlIFNJRF9RVUVSWV9WSUVXX1RBQkxFUzoKCQljYXNlIFNJRF9RVUVSWV9WSUVXX0FMSUFTRVM6CgkJCWFSZXR1cm4uYkNoZWNrZWQgPSBnZXRDb250YWluZXIoKSAmJiBnZXRDb250YWluZXIoKS0+aXNTbG90RW5hYmxlZChfbklkKTsKCQkJYVJldHVybi5iRW5hYmxlZCA9IG1fYkdyYXBoaWNhbERlc2lnbjsKCQkJYnJlYWs7CgkJY2FzZSBTSURfUVVFUllfRElTVElOQ1RfVkFMVUVTOgoJCQlhUmV0dXJuLmJFbmFibGVkID0gbV9iR3JhcGhpY2FsRGVzaWduICYmIGlzRWRpdGFibGUoKTsKCQkJYVJldHVybi5iQ2hlY2tlZCA9IG1fYkRpc3RpbmN0OwoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfUVVFUllfRVhFQ1VURToKCQkJYVJldHVybi5iRW5hYmxlZCA9IHNhbF9UcnVlOwoJCQlicmVhazsKCQljYXNlIFNJRF9EQl9RVUVSWV9QUkVWSUVXOgoJCQlhUmV0dXJuLmJFbmFibGVkID0gc2FsX1RydWU7CgkJCWFSZXR1cm4uYkNoZWNrZWQgPSBnZXRDb250YWluZXIoKSAmJiBnZXRDb250YWluZXIoKS0+Z2V0UHJldmlld0ZyYW1lKCkuaXMoKTsKCQkJYnJlYWs7CiNpZiBPU0xfREVCVUdfTEVWRUwgPiAxCgkJY2FzZSBJRF9FRElUX1FVRVJZX1NRTDoKCQkJYnJlYWs7CgkJY2FzZSBJRF9FRElUX1FVRVJZX0RFU0lHTjoKCQkJYnJlYWs7CiNlbmRpZgoJCWNhc2UgSURfQlJPV1NFUl9BRERUQUJMRToKCQkJaWYgKCAhbV9iR3JhcGhpY2FsRGVzaWduICkKCQkJewoJCQkJYVJldHVybi5iRW5hYmxlZCA9IHNhbF9GYWxzZTsKCQkJCWJyZWFrOwoJCQl9CgkJCS8vIHJ1biB0aHJvdWdoCgkJZGVmYXVsdDoKCQkJYVJldHVybiA9IE9Kb2luQ29udHJvbGxlcjo6R2V0U3RhdGUoX25JZCk7CgkJCWJyZWFrOwoJfQoJcmV0dXJuIGFSZXR1cm47Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpFeGVjdXRlKHNhbF91SW50MTYgX25JZCwgY29uc3QgU2VxdWVuY2U8IFByb3BlcnR5VmFsdWUgPiYgYUFyZ3MpCnsKCXN3aXRjaChfbklkKQoJewoJCWNhc2UgSURfQlJPV1NFUl9FU0FDUEVQUk9DRVNTSU5HOgogICAgICAgICAgICBzZXRFc2NhcGVQcm9jZXNzaW5nX2ZpcmVFdmVudCggIW1fYkVzY2FwZVByb2Nlc3NpbmcgKTsKICAgICAgICAgICAgaWYgKCAhZWRpdGluZ1ZpZXcoKSApCgkJCSAgICBzZXRNb2RpZmllZChzYWxfVHJ1ZSk7CgkJCUludmFsaWRhdGVGZWF0dXJlKElEX0JST1dTRVJfU1FMKTsKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX1NBVkVBU0RPQzoKCQljYXNlIElEX0JST1dTRVJfU0FWRURPQzoKCQkJZG9TYXZlQXNEb2MoSURfQlJPV1NFUl9TQVZFQVNET0MgPT0gX25JZCk7CgkJCWJyZWFrOwoJCWNhc2UgU0lEX1JFTEFUSU9OX0FERF9SRUxBVElPTjoKCQkJewoJCQkJT0pvaW5EZXNpZ25WaWV3KiBwVmlldyA9IGdldEpvaW5WaWV3KCk7CgkJCQlpZiggcFZpZXcgKQoJCQkJCXN0YXRpY19jYXN0PE9RdWVyeVRhYmxlVmlldyo+KHBWaWV3LT5nZXRUYWJsZVZpZXcoKSktPmNyZWF0ZU5ld0Nvbm5lY3Rpb24oKTsKCQkJfQoJCQlicmVhazsKCQljYXNlIFNJRF9QUklOVERPQ0RJUkVDVDoKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX0NVVDoKCQkJZ2V0Q29udGFpbmVyKCktPmN1dCgpOwoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfQ09QWToKCQkJZ2V0Q29udGFpbmVyKCktPmNvcHkoKTsKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX1BBU1RFOgoJCQlnZXRDb250YWluZXIoKS0+cGFzdGUoKTsKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX1NRTDoKICAgICAgICB7CgkJCWlmICggIWdldENvbnRhaW5lcigpLT5jaGVja1N0YXRlbWVudCgpICkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBTUUxFeGNlcHRpb25JbmZvIGFFcnJvcjsKCQkJdHJ5CgkJCXsKICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZyBhRXJyb3JNc2c7CiAgICAgICAgICAgICAgICBzZXRTdGF0ZW1lbnRfZmlyZUV2ZW50KCBnZXRDb250YWluZXIoKS0+Z2V0U3RhdGVtZW50KCkgKTsKCQkJCWlmKCFtX3NTdGF0ZW1lbnQuZ2V0TGVuZ3RoKCkgJiYgbV9wU3FsSXRlcmF0b3IpCgkJCQl7CgkJCQkJLy8gY2hhbmdlIHRoZSB2aWV3IG9mIHRoZSBkYXRhCgkJCQkJZGVsZXRlIG1fcFNxbEl0ZXJhdG9yLT5nZXRQYXJzZVRyZWUoKTsKCQkJCQltX3BTcWxJdGVyYXRvci0+c2V0UGFyc2VUcmVlKE5VTEwpOwoJCQkJCW1fYkdyYXBoaWNhbERlc2lnbiA9ICFtX2JHcmFwaGljYWxEZXNpZ247CgkJCQkJaW1wbF9zZXRWaWV3TW9kZSggJmFFcnJvciApOwoJCQkJfQoJCQkJZWxzZQoJCQkJewogICAgICAgICAgICAgICAgICAgIDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwTm9kZSA9IG1fYVNxbFBhcnNlci5wYXJzZVRyZWUoYUVycm9yTXNnLG1fc1N0YXRlbWVudCxtX2JHcmFwaGljYWxEZXNpZ24pOwoJCQkJCWlmICggcE5vZGUgKQoJCQkJCXsKCQkJCQkJZGVsZXRlIG1fcFNxbEl0ZXJhdG9yLT5nZXRQYXJzZVRyZWUoKTsKCQkJCQkJbV9wU3FsSXRlcmF0b3ItPnNldFBhcnNlVHJlZShwTm9kZSk7CgkJCQkJCW1fcFNxbEl0ZXJhdG9yLT50cmF2ZXJzZUFsbCgpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBtX3BTcWxJdGVyYXRvci0+aGFzRXJyb3JzKCkgKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhRXJyb3IgPSBtX3BTcWxJdGVyYXRvci0+Z2V0RXJyb3JzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCQkJCQkJZWxzZQoJCQkJCQl7CgkJCQkJCQljb25zdCBPU1FMVGFibGVzJiB4VGFicyA9IG1fcFNxbEl0ZXJhdG9yLT5nZXRUYWJsZXMoKTsKCQkJCQkJCWlmICggbV9wU3FsSXRlcmF0b3ItPmdldFN0YXRlbWVudFR5cGUoKSAhPSBTUUxfU1RBVEVNRU5UX1NFTEVDVCB8fCB4VGFicy5iZWdpbigpID09IHhUYWJzLmVuZCgpICkKCQkJCQkJCXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhRXJyb3IgPSBTUUxFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyggTW9kdWxlUmVzKCBTVFJfUVJZX05PU0VMRUNUICkgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nKCBSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oICJTMTAwMCIgKSApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMDAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbnkoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CgkJCQkJCQl9CgkJCQkJCQllbHNlCgkJCQkJCQl7CgkJCQkJCQkJLy8gY2hhbmdlIHRoZSB2aWV3IG9mIHRoZSBkYXRhCgkJCQkJCQkJbV9iR3JhcGhpY2FsRGVzaWduID0gIW1fYkdyYXBoaWNhbERlc2lnbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc05ld1N0YXRlbWVudDsKCQkJCQkJCQlwTm9kZS0+cGFyc2VOb2RlVG9TdHIoIHNOZXdTdGF0ZW1lbnQsIGdldENvbm5lY3Rpb24oKSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFN0YXRlbWVudF9maXJlRXZlbnQoIHNOZXdTdGF0ZW1lbnQgKTsKCQkJCQkJCQlnZXRDb250YWluZXIoKS0+U2F2ZVVJQ29uZmlnKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV92VGFibGVDb25uZWN0aW9uRGF0YS5jbGVhcigpOwoJCQkJCQkJCWltcGxfc2V0Vmlld01vZGUoICZhRXJyb3IgKTsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCQllbHNlCgkJCQkJewogICAgICAgICAgICAgICAgICAgICAgICBhRXJyb3IgPSBTUUxFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcoIE1vZHVsZVJlcyggU1RSX1FSWV9TWU5UQVggKSApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCAiUzEwMDAiICkgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbnkoKQogICAgICAgICAgICAgICAgICAgICAgICApOwoJCQkJCX0KCQkJCX0KCQkJfQoJCQljYXRjaChjb25zdCBTUUxFeGNlcHRpb24mIGUpCgkJCXsKICAgICAgICAgICAgICAgIGFFcnJvciA9IDo6Y3BwdTo6Z2V0Q2F1Z2h0RXhjZXB0aW9uKCk7CgkJCX0KCQkJY2F0Y2goY29uc3QgRXhjZXB0aW9uJikKCQkJewogICAgICAgICAgICAgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKCQkJfQoKICAgICAgICAgICAgaWYgKCBhRXJyb3IuaXNWYWxpZCgpICkKICAgICAgICAgICAgICAgIHNob3dFcnJvciggYUVycm9yICk7CgoJCQlpZihtX2JHcmFwaGljYWxEZXNpZ24pCgkJCXsKCQkJCUludmFsaWRhdGVGZWF0dXJlKElEX0JST1dTRVJfQUREVEFCTEUpOwoJCQkJSW52YWxpZGF0ZUZlYXR1cmUoU0lEX1JFTEFUSU9OX0FERF9SRUxBVElPTik7CgkJCX0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgkJY2FzZSBTSURfQlJPV1NFUl9DTEVBUl9RVUVSWToKCQkJewoJCQkJR2V0VW5kb01hbmFnZXIoKS5FbnRlckxpc3RBY3Rpb24oIFN0cmluZyggTW9kdWxlUmVzKFNUUl9RVUVSWV9VTkRPX1RBQldJTkRFTEVURSkgKSwgU3RyaW5nKCkgKTsKCQkJCWdldENvbnRhaW5lcigpLT5jbGVhcigpOwoJCQkJR2V0VW5kb01hbmFnZXIoKS5MZWF2ZUxpc3RBY3Rpb24oKTsKCiAgICAgICAgICAgICAgICBzZXRTdGF0ZW1lbnRfZmlyZUV2ZW50KCA6OnJ0bDo6T1VTdHJpbmcoKSApOwoJCQkJaWYobV9iR3JhcGhpY2FsRGVzaWduKQoJCQkJCUludmFsaWRhdGVGZWF0dXJlKElEX0JST1dTRVJfQUREVEFCTEUpOwoJCQl9CgkJCS8vCUludmFsaWRhdGVGZWF0dXJlKElEX0JST1dTRVJfUVVFUllfRVhFQ1VURSk7CgkJCWJyZWFrOwoJCWNhc2UgU0lEX1FVRVJZX1ZJRVdfRlVOQ1RJT05TOgoJCWNhc2UgU0lEX1FVRVJZX1ZJRVdfVEFCTEVTOgoJCWNhc2UgU0lEX1FVRVJZX1ZJRVdfQUxJQVNFUzoKCQkJZ2V0Q29udGFpbmVyKCktPnNldFNsb3RFbmFibGVkKF9uSWQsIWdldENvbnRhaW5lcigpLT5pc1Nsb3RFbmFibGVkKF9uSWQpKTsKCQkJc2V0TW9kaWZpZWQoc2FsX1RydWUpOwoJCQlicmVhazsKCQljYXNlIFNJRF9RVUVSWV9ESVNUSU5DVF9WQUxVRVM6CgkJCW1fYkRpc3RpbmN0ID0gIW1fYkRpc3RpbmN0OwoJCQlzZXRNb2RpZmllZChzYWxfVHJ1ZSk7CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9RVUVSWV9FWEVDVVRFOgoJCQlpZiAoIGdldENvbnRhaW5lcigpLT5jaGVja1N0YXRlbWVudCgpICkKCQkJCWV4ZWN1dGVRdWVyeSgpOwoJCQlicmVhazsKCQljYXNlIFNJRF9EQl9RVUVSWV9QUkVWSUVXOgoJCQl0cnkKCQkJewogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOjpYQ2xvc2VhYmxlID4geENsb3NlRnJhbWUoIGdldENvbnRhaW5lcigpLT5nZXRQcmV2aWV3RnJhbWUoKSwgVU5PX1FVRVJZICk7CgkJCQlpZiAoIHhDbG9zZUZyYW1lLmlzKCkgKQoJCQkJewogICAgICAgICAgICAgICAgICAgIHRyeQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgeENsb3NlRnJhbWUtPmNsb3NlKCBzYWxfVHJ1ZSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXRjaCggY29uc3QgRXhjZXB0aW9uJiApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIAlPU0xfRU5TVVJFKCBzYWxfRmFsc2UsICJPUXVlcnlDb250cm9sbGVyOjpFeGVjdXRlKFNJRF9EQl9RVUVSWV9QUkVWSUVXKTogKm5vYm9keSogaXMgZXhwZWN0ZWQgdG8gdmV0byBjbG9zaW5nIHRoZSBwcmV2aWV3IGZyYW1lISIgKTsKICAgICAgICAgICAgICAgICAgICB9CgkJCQl9CgkJCQllbHNlCgkJCQkJRXhlY3V0ZShJRF9CUk9XU0VSX1FVRVJZX0VYRUNVVEUsU2VxdWVuY2U8IFByb3BlcnR5VmFsdWUgPigpKTsKCQkJfQoJCQljYXRjaChFeGNlcHRpb24mKQoJCQl7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBJRF9RVUVSWV9aT09NX0lOOgoJCQl7Ci8vCQkJCW1fYVpvb20gKj0gRnJhY3Rpb24oMSwxMCk7Ci8vCQkJCXN0YXRpY19jYXN0PE9RdWVyeVZpZXdTd2l0Y2gqPihnZXRWaWV3KCkpLT56b29tVGFibGVWaWV3KG1fYVpvb20pOwoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgSURfUVVFUllfWk9PTV9PVVQ6CgkJCXsKLy8JCQkJaWYobV9hWm9vbSAhPSBGcmFjdGlvbigxLDEpKQovLwkJCQkJbV9hWm9vbSAvPSBGcmFjdGlvbigxLDEwKTsKLy8JCQkJc3RhdGljX2Nhc3Q8T1F1ZXJ5Vmlld1N3aXRjaCo+KGdldFZpZXcoKSktPnpvb21UYWJsZVZpZXcobV9hWm9vbSk7CgkJCX0KCQkJYnJlYWs7CiNpZiBPU0xfREVCVUdfTEVWRUwgPiAxCgkJY2FzZSBJRF9FRElUX1FVRVJZX0RFU0lHTjoKCQljYXNlIElEX0VESVRfUVVFUllfU1FMOgoJCQl7CgkJCQk6OnJ0bDo6T1VTdHJpbmcgYUVycm9yTXNnOwogICAgICAgICAgICAgICAgc2V0U3RhdGVtZW50X2ZpcmVFdmVudCggZ2V0Q29udGFpbmVyKCktPmdldFN0YXRlbWVudCgpICk7CgkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcE5vZGUgPSBtX2FTcWxQYXJzZXIucGFyc2VUcmVlKCBhRXJyb3JNc2csIG1fc1N0YXRlbWVudCwgbV9iR3JhcGhpY2FsRGVzaWduICk7CgkJCQlpZiAoIHBOb2RlICkKCQkJCXsKCQkJCQlXaW5kb3cqIHBWaWV3ID0gZ2V0VmlldygpOwoJCQkJCU1vZGFsRGlhbG9nKiBwV2luZG93ID0gbmV3IE1vZGFsRGlhbG9nKCBwVmlldywgV0JfU1RETU9EQUwgfCBXQl9TSVpFTU9WRSB8IFdCX0NFTlRFUiApOwogICAgICAgICAgICAgICAgICAgIHBXaW5kb3ctPlNldFNpemVQaXhlbCggOjpTaXplKCBwVmlldy0+R2V0U2l6ZVBpeGVsKCkuV2lkdGgoKSAvIDIsIHBWaWV3LT5HZXRTaXplUGl4ZWwoKS5IZWlnaHQoKSAvIDIgKSApOwoJCQkJCVN2VHJlZUxpc3RCb3gqIHBUcmVlQm94ID0gbmV3IFN2VHJlZUxpc3RCb3goIHBXaW5kb3csIFdCX0JPUkRFUiB8IFdCX0hBU0xJTkVTIHwgV0JfSEFTQlVUVE9OUyB8IFdCX0hBU0JVVFRPTlNBVFJPT1QgfCBXQl9IQVNMSU5FU0FUUk9PVCB8IFdCX1ZTQ1JPTEwgKTsKICAgICAgICAgICAgICAgICAgICBwVHJlZUJveC0+U2V0UG9zU2l6ZVBpeGVsKCA6OlBvaW50KCA2LCA2ICksIDo6U2l6ZSggcFdpbmRvdy0+R2V0U2l6ZVBpeGVsKCkuV2lkdGgoKSAtIDEyLCBwV2luZG93LT5HZXRTaXplUGl4ZWwoKS5IZWlnaHQoKSAtIDEyICkpOwogICAgICAgICAgICAgICAgICAgIHBUcmVlQm94LT5TZXROb2RlRGVmYXVsdEltYWdlcygpOwoKCQkJCQlpZiAoIF9uSWQgPT0gSURfRURJVF9RVUVSWV9ERVNJR04gKQoJCQkJCXsKCQkJCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBUZW1wID0gcE5vZGUgPyBwTm9kZS0+Z2V0Q2hpbGQoMyktPmdldENoaWxkKDEpIDogTlVMTDsKCQkJCQkJLy8gbm8gd2hlcmUgY2xhdXNlIGZvdW5kCgkJCQkJCWlmICggcFRlbXAgJiYgIXBUZW1wLT5pc0xlYWYoKSApCgkJCQkJCXsKCQkJCQkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlICogcENvbmRpdGlvbiA9IHBUZW1wLT5nZXRDaGlsZCgxKTsKCQkJCQkJCWlmICggcENvbmRpdGlvbiApIC8vIG5vIHdoZXJlIGNsYXVzZQoJCQkJCQkJewoJCQkJCQkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlOjpuZWdhdGVTZWFyY2hDb25kaXRpb24ocENvbmRpdGlvbik7CgkJCQkJCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKnBOb2RlVG1wID0gcFRlbXAtPmdldENoaWxkKDEpOwoKCQkJCQkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZTo6ZGlzanVuY3RpdmVOb3JtYWxGb3JtKHBOb2RlVG1wKTsKCQkJCQkJCQlwTm9kZVRtcCA9IHBUZW1wLT5nZXRDaGlsZCgxKTsKCQkJCQkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZTo6YWJzb3JwdGlvbnMocE5vZGVUbXApOwoJCQkJCQkJCXBOb2RlVG1wID0gcFRlbXAtPmdldENoaWxkKDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9TUUxQYXJzZU5vZGU6OmNvbXByZXNzKHBOb2RlVG1wKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTm9kZVRtcCA9IHBUZW1wLT5nZXRDaGlsZCgxKTsKCQkJCQkJCX0gLy8gaWYgKCBwQ29uZGl0aW9uICkgLy8gbm8gd2hlcmUgY2xhdXNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc1RlbXA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTm9kZS0+cGFyc2VOb2RlVG9TdHIoc1RlbXAsZ2V0Q29ubmVjdGlvbigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldENvbnRhaW5lcigpLT5zZXRTdGF0ZW1lbnQoc1RlbXApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgCgkJCQkJCX0KCQkJCQl9CgoJCQkJCWluc2VydFBhcnNlVHJlZShwVHJlZUJveCxwTm9kZSk7CgoJCQkJCXBUcmVlQm94LT5TaG93KCk7CgkJCQkJcFdpbmRvdy0+RXhlY3V0ZSgpOwoKCQkJCQlkZWxldGUgcFRyZWVCb3g7CgkJCQkJZGVsZXRlIHBXaW5kb3c7CgkJCQkJZGVsZXRlIHBOb2RlOwoJCQkJfQoJCQkJYnJlYWs7CgkJCX0KI2VuZGlmCgkJZGVmYXVsdDoKCQkJT0pvaW5Db250cm9sbGVyOjpFeGVjdXRlKF9uSWQsYUFyZ3MpOwoJCQlyZXR1cm47IC8vIGVsc2Ugd2Ugd291bGQgaW52YWxpZGF0ZSB0d2ljZQoJfQoJSW52YWxpZGF0ZUZlYXR1cmUoX25JZCk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9zaG93QXV0b1NRTFZpZXdFcnJvciggY29uc3QgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpBbnkmIF9yRXJyb3JEZXRhaWxzICkKewogICAgU1FMQ29udGV4dCBhRXJyb3JDb250ZXh0OwogICAgYUVycm9yQ29udGV4dC5NZXNzYWdlID0gbGNsX2dldE9iamVjdFJlc291cmNlU3RyaW5nKCBTVFJfRVJST1JfUEFSU0lOR19TVEFURU1FTlQsIG1fbkNvbW1hbmRUeXBlICk7CiAgICBhRXJyb3JDb250ZXh0LkNvbnRleHQgPSAqdGhpczsKICAgIGFFcnJvckNvbnRleHQuRGV0YWlscyA9IGxjbF9nZXRPYmplY3RSZXNvdXJjZVN0cmluZyggU1RSX0lORk9fT1BFTklOR19JTl9TUUxfVklFVywgbV9uQ29tbWFuZFR5cGUgKTsKICAgIGFFcnJvckNvbnRleHQuTmV4dEV4Y2VwdGlvbiA9IF9yRXJyb3JEZXRhaWxzOwogICAgc2hvd0Vycm9yKCBhRXJyb3JDb250ZXh0ICk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9zZXRWaWV3TW9kZSggOjpkYnRvb2xzOjpTUUxFeGNlcHRpb25JbmZvKiBfcEVycm9ySW5mbyApCnsKICAgIE9TTF9QUkVDT05EKCBnZXRDb250YWluZXIoKSwgIk9RdWVyeUNvbnRyb2xsZXI6OmltcGxfc2V0Vmlld01vZGU6IGlsbGVnYWwgY2FsbCEiICk7CgogICAgYm9vbCB3YXNNb2RpZmllZCA9IGlzTW9kaWZpZWQoKTsKCiAgICBTUUxFeGNlcHRpb25JbmZvIGFFcnJvcjsKICAgIGJvb2wgYlN1Y2Nlc3MgPSBnZXRDb250YWluZXIoKS0+c3dpdGNoVmlldyggJmFFcnJvciApOwogICAgaWYgKCAhYlN1Y2Nlc3MgKQoJewoJCW1fYkdyYXBoaWNhbERlc2lnbiA9ICFtX2JHcmFwaGljYWxEZXNpZ247CiAgICAgICAgLy8gcmVzdG9yZSBvbGQgc3RhdGUKCQlnZXRDb250YWluZXIoKS0+c3dpdGNoVmlldyggTlVMTCApOwogICAgICAgICAgICAvLyBkb24ndCBwYXNzICZhRXJyb3IgaGVyZSwgdGhpcyB3b3VsZCBvdmVyd3JpdGUgdGhlIGVycm9yIHdoaWNoIHRoZSBmaXJzdCBzd2l0Y2hWaWV3IGNhbGwKICAgICAgICAgICAgLy8gcmV0dXJuZWQgaW4gdGhpcyBsb2NhdGlvbi4KICAgICAgICBpZiAoIF9wRXJyb3JJbmZvICkKICAgICAgICAgICAgKl9wRXJyb3JJbmZvID0gYUVycm9yOwogICAgICAgIGVsc2UKICAgICAgICAgICAgc2hvd0Vycm9yKCBhRXJyb3IgKTsKCX0KCWVsc2UKICAgIHsKICAgICAgICBlbnN1cmVUb29sYmFycyggKnRoaXMsIG1fYkdyYXBoaWNhbERlc2lnbiApOwogICAgfQoKICAgIHNldE1vZGlmaWVkKCB3YXNNb2RpZmllZCApOwogICAgcmV0dXJuIGJTdWNjZXNzOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OmltcGxfaW5pdGlhbGl6ZSgpCnsKCU9Kb2luQ29udHJvbGxlcjo6aW1wbF9pbml0aWFsaXplKCk7CgogICAgY29uc3QgTmFtZWRWYWx1ZUNvbGxlY3Rpb24mIHJBcmd1bWVudHMoIGdldEluaXRQYXJhbXMoKSApOwoKICAgIDo6cnRsOjpPVVN0cmluZyBzQ29tbWFuZDsKICAgIG1fbkNvbW1hbmRUeXBlID0gQ29tbWFuZFR5cGU6OlFVRVJZOwoKICAgIC8vILCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwCiAgICAvLyCwIHJlYWRpbmcgcGFyYW1ldGVycwogICAgLy8gsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLAKICAgIC8vIGxlZ2FjeSBwYXJhbWV0ZXJzIGZpcnN0IChsYXRlciBvdmVyd3JpdHRlbiBieSByZWd1bGFyIHBhcmFtZXRlcnMpCiAgICA6OnJ0bDo6T1VTdHJpbmcgc0luZGVwZW5kZW50U1FMQ29tbWFuZDsKICAgIGlmICggckFyZ3VtZW50cy5nZXRfZW5zdXJlVHlwZSggIkluZGVwZW5kZW50U1FMQ29tbWFuZCIsIHNJbmRlcGVuZGVudFNRTENvbW1hbmQgKSApCiAgICB7CiAgICAgICAgT1NMX0VOU1VSRSggZmFsc2UsICJPUXVlcnlDb250cm9sbGVyOjppbXBsX2luaXRpYWxpemU6IEluZGVwZW5kZW50U1FMQ29tbWFuZCBpcyByZWdvZ25pemVkIGZvciBjb21wYXRpYmlsaXR5IG9ubHkhIiApOwogICAgICAgIHNDb21tYW5kID0gc0luZGVwZW5kZW50U1FMQ29tbWFuZDsKICAgICAgICBtX25Db21tYW5kVHlwZSA9IENvbW1hbmRUeXBlOjpDT01NQU5EOwogICAgfQoKICAgIDo6cnRsOjpPVVN0cmluZyBzQ3VycmVudFF1ZXJ5OwogICAgaWYgKCByQXJndW1lbnRzLmdldF9lbnN1cmVUeXBlKCAiQ3VycmVudFF1ZXJ5Iiwgc0N1cnJlbnRRdWVyeSApICkKICAgIHsKICAgICAgICBPU0xfRU5TVVJFKCBmYWxzZSwgIk9RdWVyeUNvbnRyb2xsZXI6OmltcGxfaW5pdGlhbGl6ZTogQ3VycmVudFF1ZXJ5IGlzIHJlZ29nbml6ZWQgZm9yIGNvbXBhdGliaWxpdHkgb25seSEiICk7CiAgICAgICAgc0NvbW1hbmQgPSBzQ3VycmVudFF1ZXJ5OwogICAgICAgIG1fbkNvbW1hbmRUeXBlID0gQ29tbWFuZFR5cGU6OlFVRVJZOwogICAgfQoKICAgIHNhbF9Cb29sIGJDcmVhdGVWaWV3KCBzYWxfRmFsc2UgKTsKICAgIGlmICggckFyZ3VtZW50cy5nZXRfZW5zdXJlVHlwZSggIkNyZWF0ZVZpZXciLCBiQ3JlYXRlVmlldyApICYmIGJDcmVhdGVWaWV3ICkKICAgIHsKICAgICAgICBPU0xfRU5TVVJFKCBmYWxzZSwgIk9RdWVyeUNvbnRyb2xsZXI6OmltcGxfaW5pdGlhbGl6ZTogQ3VycmVudFF1ZXJ5IGlzIHJlZ29nbml6ZWQgZm9yIGNvbXBhdGliaWxpdHkgb25seSEiICk7CiAgICAgICAgbV9uQ29tbWFuZFR5cGUgPSBDb21tYW5kVHlwZTo6VEFCTEU7CiAgICB9CgogICAgLy8gbm9uLWxlZ2FjeSBwYXJhbWV0ZXJzIHdoaWNoIG92ZXJ3cml0ZSB0aGUgbGVnYWN5IHBhcmFtZXRlcnMKICAgIHJBcmd1bWVudHMuZ2V0X2Vuc3VyZVR5cGUoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfQ09NTUFORCwgc0NvbW1hbmQgKTsKICAgIHJBcmd1bWVudHMuZ2V0X2Vuc3VyZVR5cGUoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfQ09NTUFORF9UWVBFLCBtX25Db21tYW5kVHlwZSApOwoKICAgIC8vIHRyYW5zbGF0ZSBDb21tYW5kL1R5cGUgaW50byBwcm9wZXIgbWVtYmVycwogICAgLy8gVE9ETy9MYXRlcjogYWxsIHRoaXMgKGluY2x1ZGluZyB0aG9zZSBtZW1iZXJzKSBzaG91bGQgYmUgaGlkZGVuIGJlaGluZCBzb21lIGFic3RhY3QgaW50ZXJmYWNlLAogICAgLy8gd2hpY2ggaXMgaW1wbGVtZW50ZWQgZm9yIGFsbCB0aGUgdGhyZWUgY29tbWFuZHMKICAgIHN3aXRjaCAoIG1fbkNvbW1hbmRUeXBlICkKICAgIHsKICAgIGNhc2UgQ29tbWFuZFR5cGU6OlFVRVJZOgogICAgICAgIG1fc05hbWUgPSBzQ29tbWFuZDsKICAgICAgICBicmVhazsKICAgIGNhc2UgQ29tbWFuZFR5cGU6OlRBQkxFOgogICAgICAgIG1fc05hbWUgPSBzQ29tbWFuZDsKICAgICAgICBicmVhazsKICAgIGNhc2UgQ29tbWFuZFR5cGU6OkNPTU1BTkQ6CiAgICAgICAgc2V0U3RhdGVtZW50X2ZpcmVFdmVudCggc0NvbW1hbmQgKTsKICAgICAgICBtX3NOYW1lID0gOjpydGw6Ok9VU3RyaW5nKCk7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIE9TTF9FTlNVUkUoIGZhbHNlLCAiT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9pbml0aWFsaXplOiBsb2dpYyBlcnJvciBpbiBjb2RlISIgKTsKICAgICAgICB0aHJvdyBSdW50aW1lRXhjZXB0aW9uKCk7CiAgICB9CgogICAgLy8gbW9yZSBsZWdhY3kgcGFyYW1ldGVycwogICAgc2FsX0Jvb2wgYkdyYXBoaWNhbERlc2lnbiggc2FsX1RydWUgKTsKICAgIGlmICggckFyZ3VtZW50cy5nZXRfZW5zdXJlVHlwZSggKDo6cnRsOjpPVVN0cmluZylQUk9QRVJUWV9RVUVSWURFU0lHTlZJRVcsIGJHcmFwaGljYWxEZXNpZ24gKSApCiAgICB7CiAgICAgICAgT1NMX0VOU1VSRSggZmFsc2UsICJPUXVlcnlDb250cm9sbGVyOjppbXBsX2luaXRpYWxpemU6IFF1ZXJ5RGVzaWduVmlldyBpcyByZWdvZ25pemVkIGZvciBjb21wYXRpYmlsaXR5IG9ubHkhIiApOwogICAgICAgIG1fYkdyYXBoaWNhbERlc2lnbiA9IGJHcmFwaGljYWxEZXNpZ247CiAgICB9CgogICAgLy8gbW9yZSBub24tbGVnYWN5CiAgICByQXJndW1lbnRzLmdldF9lbnN1cmVUeXBlKCAoOjpydGw6Ok9VU3RyaW5nKVBST1BFUlRZX0dSQVBISUNBTF9ERVNJR04sIG1fYkdyYXBoaWNhbERlc2lnbiApOwoKICAgIGJvb2wgYkVzY2FwZVByb2Nlc3NpbmcoIHNhbF9UcnVlICk7CiAgICBpZiAoIHJBcmd1bWVudHMuZ2V0X2Vuc3VyZVR5cGUoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfRVNDQVBFX1BST0NFU1NJTkcsIGJFc2NhcGVQcm9jZXNzaW5nICkgKQogICAgewogICAgICAgIHNldEVzY2FwZVByb2Nlc3NpbmdfZmlyZUV2ZW50KCBiRXNjYXBlUHJvY2Vzc2luZyApOwoKICAgICAgICBPU0xfRU5TVVJFKCBtX2JFc2NhcGVQcm9jZXNzaW5nIHx8ICFtX2JHcmFwaGljYWxEZXNpZ24sICJPUXVlcnlDb250cm9sbGVyOjppbXBsX2luaXRpYWxpemU6IGNhbid0IGRvIHRoZSBncmFwaGljYWwgZGVzaWduIHdpdGhvdXQgZXNjYXBlIHByb2Nlc3NpbmchIiApOwogICAgICAgIGlmICggIW1fYkVzY2FwZVByb2Nlc3NpbmcgKQogICAgICAgICAgICBtX2JHcmFwaGljYWxEZXNpZ24gPSBmYWxzZTsKICAgIH0KCiAgICAvLyAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLgogICAgLy8gLiBpbml0aWFsIGRlc2lnbgogICAgYm9vbCBiRm9yY2VJbml0aWFsRGVzaWduID0gZmFsc2U7CiAgICBTZXF1ZW5jZTwgUHJvcGVydHlWYWx1ZSA+IGFDdXJyZW50UXVlcnlEZXNpZ25Qcm9wczsKICAgIGFDdXJyZW50UXVlcnlEZXNpZ25Qcm9wcyA9IHJBcmd1bWVudHMuZ2V0T3JEZWZhdWx0KCAiQ3VycmVudFF1ZXJ5RGVzaWduIiwgYUN1cnJlbnRRdWVyeURlc2lnblByb3BzICk7CgogICAgaWYgKCBhQ3VycmVudFF1ZXJ5RGVzaWduUHJvcHMuZ2V0TGVuZ3RoKCkgKQogICAgewogICAgICAgIDo6Y29tcGhlbHBlcjo6TmFtZWRWYWx1ZUNvbGxlY3Rpb24gYUN1cnJlbnRRdWVyeURlc2lnbiggYUN1cnJlbnRRdWVyeURlc2lnblByb3BzICk7CiAgICAgICAgaWYgKCBhQ3VycmVudFF1ZXJ5RGVzaWduLmhhcyggKDo6cnRsOjpPVVN0cmluZylQUk9QRVJUWV9HUkFQSElDQUxfREVTSUdOICkgKQogICAgICAgIHsKICAgICAgICAgICAgYUN1cnJlbnRRdWVyeURlc2lnbi5nZXRfZW5zdXJlVHlwZSggKDo6cnRsOjpPVVN0cmluZylQUk9QRVJUWV9HUkFQSElDQUxfREVTSUdOLCBtX2JHcmFwaGljYWxEZXNpZ24gKTsKICAgICAgICB9CiAgICAgICAgaWYgKCBhQ3VycmVudFF1ZXJ5RGVzaWduLmhhcyggKDo6cnRsOjpPVVN0cmluZylQUk9QRVJUWV9FU0NBUEVfUFJPQ0VTU0lORyApICkKICAgICAgICB7CiAgICAgICAgICAgIGFDdXJyZW50UXVlcnlEZXNpZ24uZ2V0X2Vuc3VyZVR5cGUoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfRVNDQVBFX1BST0NFU1NJTkcsIG1fYkVzY2FwZVByb2Nlc3NpbmcgKTsKICAgICAgICB9CiAgICAgICAgaWYgKCBhQ3VycmVudFF1ZXJ5RGVzaWduLmhhcyggIlN0YXRlbWVudCIgKSApCiAgICAgICAgewogICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc1N0YXRlbWVudDsKICAgICAgICAgICAgYUN1cnJlbnRRdWVyeURlc2lnbi5nZXRfZW5zdXJlVHlwZSggIlN0YXRlbWVudCIsIHNTdGF0ZW1lbnQgKTsKICAgICAgICAgICAgYUN1cnJlbnRRdWVyeURlc2lnbi5yZW1vdmUoICJTdGF0ZW1lbnQiICk7CiAgICAgICAgICAgIHNldFN0YXRlbWVudF9maXJlRXZlbnQoIHNTdGF0ZW1lbnQgKTsKICAgICAgICB9CgogICAgICAgIGxvYWRWaWV3U2V0dGluZ3MoIGFDdXJyZW50UXVlcnlEZXNpZ24gKTsKCiAgICAgICAgYkZvcmNlSW5pdGlhbERlc2lnbiA9IHRydWU7CiAgICB9CgogICAgLy8gsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLAKCWlmICggIWVuc3VyZUNvbm5lY3RlZCggc2FsX0ZhbHNlICkgKQoJewkvLyB3ZSBoYXZlIG5vIGNvbm5lY3Rpb24gc28gd2hhdCBlbHNlIHNob3VsZCB3ZSBkbwoJCW1fYkdyYXBoaWNhbERlc2lnbiA9IHNhbF9GYWxzZTsKCQlpZiAoIGVkaXRpbmdWaWV3KCkgKQoJCXsKCQkJY29ubmVjdGlvbkxvc3RNZXNzYWdlKCk7CgkJCXRocm93IFNRTEV4Y2VwdGlvbigpOwoJCX0KCX0KCiAgICAvLyBjaGVjayB0aGUgdmlldyBjYXBhYmlsaXRpZXMKCWlmICggaXNDb25uZWN0ZWQoKSAmJiBlZGl0aW5nVmlldygpICkKCXsKCQlSZWZlcmVuY2U8IFhWaWV3c1N1cHBsaWVyID4geFZpZXdzU3VwKCBnZXRDb25uZWN0aW9uKCksIFVOT19RVUVSWSApOwogICAgICAgIFJlZmVyZW5jZTwgWE5hbWVBY2Nlc3MgPiB4Vmlld3M7CiAgICAgICAgaWYgKCB4Vmlld3NTdXAuaXMoKSApCiAgICAgICAgICAgIHhWaWV3cyA9IHhWaWV3c1N1cC0+Z2V0Vmlld3MoKTsKCiAgICAgICAgaWYgKCAheFZpZXdzLmlzKCkgKQoJCXsJLy8gd2UgY2FuJ3QgY3JlYXRlIHZpZXdzIHNvIHdlIGFzayBpZiB0aGUgdXNlciB3YW50cyB0byBjcmVhdGUgYSBxdWVyeSBpbnN0ZWFkCiAgICAgICAgICAgIG1fbkNvbW1hbmRUeXBlID0gQ29tbWFuZFR5cGU6OlFVRVJZOwoJCQlzYWxfQm9vbCBiQ2xvc2UgPSBzYWxfRmFsc2U7CgkJCXsKCQkJCVN0cmluZyBhVGl0bGUoIE1vZHVsZVJlcyggU1RSX1FVRVJZREVTSUdOX05PX1ZJRVdfU1VQUE9SVCApICk7CgkJCQlTdHJpbmcgYU1lc3NhZ2UoIE1vZHVsZVJlcyggU1RSX1FVRVJZREVTSUdOX05PX1ZJRVdfQVNLICkgKTsKCQkJCU9EYXRhVmlldyogcFdpbmRvdyA9IGdldFZpZXcoKTsKCQkJCU9TUUxNZXNzYWdlQm94IGFEbGcoIHBXaW5kb3csIGFUaXRsZSwgYU1lc3NhZ2UsIFdCX1lFU19OTyB8IFdCX0RFRl9ZRVMsIE9TUUxNZXNzYWdlQm94OjpRdWVyeSApOwoJCQkJYkNsb3NlID0gYURsZy5FeGVjdXRlKCkgPT0gUkVUX05POwoJCQl9CgkJCWlmICggYkNsb3NlICkKCQkJCXRocm93IFZldG9FeGNlcHRpb24oKTsKCQl9CgogICAgICAgIC8vIG5vdyBpZiB3ZSBhcmUgdG8gZWRpdCBhbiBleGlzdGluZyB2aWV3LCBjaGVjayB3aGV0aGVyIHRoaXMgaXMgcG9zc2libGUKICAgICAgICBpZiAoIG1fc05hbWUuZ2V0TGVuZ3RoKCkgKQogICAgICAgIHsKICAgICAgICAgICAgQW55IGFWaWV3KCB4Vmlld3MtPmdldEJ5TmFtZSggbV9zTmFtZSApICk7CiAgICAgICAgICAgICAgICAvLyB3aWxsIHRocm93IGlmIHRoZXJlIGlzIG5vIHN1Y2ggdmlldwogICAgICAgICAgICBpZiAoICEoIGFWaWV3ID4+PSBtX3hBbHRlclZpZXcgKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcoIFN0cmluZyggTW9kdWxlUmVzKCBTVFJfTk9fQUxURVJfVklFV19TVVBQT1JUICkgKSApLAogICAgICAgICAgICAgICAgICAgICp0aGlzLAogICAgICAgICAgICAgICAgICAgIDEKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9Cgl9CgoJT1NMX0VOU1VSRShnZXREYXRhU291cmNlKCkuaXMoKSwiT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9pbml0aWFsaXplOiBuZWVkIGEgZGF0YXNvdXJjZSEiKTsKCgl0cnkKCXsKCQlnZXRDb250YWluZXIoKS0+aW5pdGlhbGl6ZSgpOwogICAgICAgIGltcGxfcmVzZXQoIGJGb3JjZUluaXRpYWxEZXNpZ24gKTsKCiAgICAgICAgU1FMRXhjZXB0aW9uSW5mbyBhRXJyb3I7CiAgICAgICAgY29uc3QgYm9vbCBiQXR0ZW1wdGVkR3JhcGhpY2FsRGVzaWduID0gbV9iR3JhcGhpY2FsRGVzaWduOwoKICAgICAgICBpZiAoIGJGb3JjZUluaXRpYWxEZXNpZ24gKQogICAgICAgIHsKICAgICAgICAgICAgZ2V0Q29udGFpbmVyKCktPmZvcmNlSW5pdGlhbFZpZXcoKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaW1wbF9zZXRWaWV3TW9kZSggJmFFcnJvciApOwogICAgICAgIH0KCiAgICAgICAgaWYgKCBhRXJyb3IuaXNWYWxpZCgpICYmIGJBdHRlbXB0ZWRHcmFwaGljYWxEZXNpZ24gJiYgIW1fYkdyYXBoaWNhbERlc2lnbiApCiAgICAgICAgewogICAgICAgICAgICAvLyB3ZSB0cmllZCBpbml0aWFsaXppbmcgdGhlIGdyYXBoaWNhbCB2aWV3LCB0aGlzIGZhaWxlZCwgYW5kIHdlIHdlcmUgYXV0b21hdGljYWxseSBzd2l0Y2hlZCB0byBTUUwKICAgICAgICAgICAgLy8gdmlldyA9PiB0ZWxsIHRoaXMgdG8gdGhlIHVzZXIKICAgICAgICAgICAgaWYgKCAhZWRpdGluZ1ZpZXcoKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGltcGxfc2hvd0F1dG9TUUxWaWV3RXJyb3IoIGFFcnJvci5nZXQoKSApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAoJCUNsZWFyVW5kb01hbmFnZXIoKTsKCgkJaWYgICggICggbV9iR3JhcGhpY2FsRGVzaWduICkKICAgICAgICAgICAgJiYgKCAgKCAhbV9zTmFtZS5nZXRMZW5ndGgoKSAmJiAhZWRpdGluZ0NvbW1hbmQoKSApCiAgICAgICAgICAgICAgIHx8ICggIW1fc1N0YXRlbWVudC5nZXRMZW5ndGgoKSAmJiBlZGl0aW5nQ29tbWFuZCgpICkKICAgICAgICAgICAgICAgKQogICAgICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBBcHBsaWNhdGlvbjo6UG9zdFVzZXJFdmVudCggTElOSyggdGhpcywgT1F1ZXJ5Q29udHJvbGxlciwgT25FeGVjdXRlQWRkVGFibGUgKSApOwogICAgICAgIH0KCgkJc2V0TW9kaWZpZWQoc2FsX0ZhbHNlKTsKCX0KCWNhdGNoKFNRTEV4Y2VwdGlvbiYgZSkKCXsKCQlEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwoJCS8vIHdlIGNhdWdodCBhbiBleGNlcHRpb24gc28gd2Ugc3dpdGNoIHRvIHRleHQgb25seSBtb2RlCgkJewoJCQltX2JHcmFwaGljYWxEZXNpZ24gPSBzYWxfRmFsc2U7CgkJCWdldENvbnRhaW5lcigpLT5pbml0aWFsaXplKCk7CgkJCU9EYXRhVmlldyogcFdpbmRvdyA9IGdldFZpZXcoKTsKCQkJT1NRTE1lc3NhZ2VCb3gocFdpbmRvdyxlKS5FeGVjdXRlKCk7CgkJfQoJCXRocm93OwoJfQp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6Om9uTG9hZGVkTWVudShjb25zdCBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYTGF5b3V0TWFuYWdlciA+JiAvKl94TGF5b3V0TWFuYWdlciovKQp7CiAgICBlbnN1cmVUb29sYmFycyggKnRoaXMsIG1fYkdyYXBoaWNhbERlc2lnbiApOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo6OnJ0bDo6T1VTdHJpbmcgT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0UHJpdmF0ZVRpdGxlKCApIGNvbnN0CnsKCTo6cnRsOjpPVVN0cmluZyBzTmFtZSA9IG1fc05hbWU7CglpZiAoICFzTmFtZS5nZXRMZW5ndGgoKSApCgl7CiAgICAgICAgaWYgKCAhZWRpdGluZ0NvbW1hbmQoKSApCiAgICAgICAgewoJCQk6OnZvczo6T0d1YXJkIGFTb2xhckd1YXJkKEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkpOwoJCQk6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIGdldE11dGV4KCkgKTsKICAgICAgICAgICAgU3RyaW5nIGFEZWZhdWx0TmFtZSA9IFN0cmluZyggTW9kdWxlUmVzKCBlZGl0aW5nVmlldygpID8gU1RSX1ZJRVdfVElUTEUgOiBTVFJfUVJZX1RJVExFICkgKTsKCQkJc05hbWUgPSBhRGVmYXVsdE5hbWUuR2V0VG9rZW4oMCwnICcpOwogICAgICAgICAgICBzTmFtZSArPSA6OnJ0bDo6T1VTdHJpbmc6OnZhbHVlT2YoZ2V0Q3VycmVudFN0YXJ0TnVtYmVyKCkpOwogICAgICAgIH0KCX0KICAgIHJldHVybiBzTmFtZTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OnNldFF1ZXJ5Q29tcG9zZXIoKQp7CglpZihpc0Nvbm5lY3RlZCgpKQoJewoJCVJlZmVyZW5jZTwgWFNRTFF1ZXJ5Q29tcG9zZXJGYWN0b3J5ID4gIHhGYWN0b3J5KGdldENvbm5lY3Rpb24oKSwgVU5PX1FVRVJZKTsKCQlPU0xfRU5TVVJFKHhGYWN0b3J5LmlzKCksIkNvbm5lY3Rpb24gZG9lc24ndCBzdXBwb3J0IGEgcXVlcnljb21wb3NlciIpOwoJCWlmICggeEZhY3RvcnkuaXMoKSAmJiBnZXRDb250YWluZXIoKSApCgkJewoJCQl0cnkKCQkJewoJCQkJbV94Q29tcG9zZXIgPSB4RmFjdG9yeS0+Y3JlYXRlUXVlcnlDb21wb3NlcigpOwoJCQkJZ2V0Q29udGFpbmVyKCktPnNldFN0YXRlbWVudChtX3NTdGF0ZW1lbnQpOwoJCQl9CgkJCWNhdGNoIChFeGNlcHRpb24mKQoJCQl7CgkJCQltX3hDb21wb3NlciA9IE5VTEw7CgkJCX0KCQkJT1NMX0VOU1VSRShtX3hDb21wb3Nlci5pcygpLCJObyBxdWVyeWNvbXBvc2VyIGF2YWlsYWJsZSEiKTsKCQkJUmVmZXJlbmNlPFhUYWJsZXNTdXBwbGllcj4geFRhYmxlc1N1cChnZXRDb25uZWN0aW9uKCksIFVOT19RVUVSWSk7CgkJCWRlbGV0ZUl0ZXJhdG9yKCk7CgkJCW1fcFNxbEl0ZXJhdG9yID0gbmV3IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VUcmVlSXRlcmF0b3IoIGdldENvbm5lY3Rpb24oKSwgeFRhYmxlc1N1cC0+Z2V0VGFibGVzKCksIG1fYVNxbFBhcnNlciwgTlVMTCApOwoJCX0KCX0KfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBPUXVlcnlDb250cm9sbGVyOjpDb25zdHJ1Y3QoV2luZG93KiBwUGFyZW50KQp7CgkvLyBUT0RPOiB3ZSBoYXZlIHRvIGNoZWNrIGlmIHdlIHNob3VsZCBjcmVhdGUgdGhlIHRleHQtIG9yIHRoZSBkZXNpZ24tIHZpZXcKCglzZXRWaWV3KCAqIG5ldyBPUXVlcnlDb250YWluZXJXaW5kb3coIHBQYXJlbnQsICp0aGlzLCBnZXRPUkIoKSApICk7CgoJcmV0dXJuIE9Kb2luQ29udHJvbGxlcjo6Q29uc3RydWN0KHBQYXJlbnQpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpPSm9pbkRlc2lnblZpZXcqIE9RdWVyeUNvbnRyb2xsZXI6OmdldEpvaW5WaWV3KCkKewoJcmV0dXJuIGdldENvbnRhaW5lcigpLT5nZXREZXNpZ25WaWV3KCk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpkZXNjcmliZVN1cHBvcnRlZEZlYXR1cmVzKCkKewoJT0pvaW5Db250cm9sbGVyOjpkZXNjcmliZVN1cHBvcnRlZEZlYXR1cmVzKCk7CiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpTYXZlQXMiLCAgICAgICAgICAgIElEX0JST1dTRVJfU0FWRUFTRE9DLCAgICAgICBDb21tYW5kR3JvdXA6OkRPQ1VNRU5UICk7CiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpTYmFOYXRpdmVTcWwiLCAgICAgIElEX0JST1dTRVJfRVNBQ1BFUFJPQ0VTU0lORyxDb21tYW5kR3JvdXA6OkZPUk1BVCApOwogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86REJWaWV3RnVuY3Rpb25zIiwgICBTSURfUVVFUllfVklFV19GVU5DVElPTlMsICAgQ29tbWFuZEdyb3VwOjpWSUVXICk7CiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpEQlZpZXdUYWJsZU5hbWVzIiwgIFNJRF9RVUVSWV9WSUVXX1RBQkxFUywgICAgICBDb21tYW5kR3JvdXA6OlZJRVcgKTsKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOkRCVmlld0FsaWFzZXMiLCAgICAgU0lEX1FVRVJZX1ZJRVdfQUxJQVNFUywgICAgIENvbW1hbmRHcm91cDo6VklFVyApOwogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86REJEaXN0aW5jdFZhbHVlcyIsICBTSURfUVVFUllfRElTVElOQ1RfVkFMVUVTLCAgQ29tbWFuZEdyb3VwOjpGT1JNQVQgKTsKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOkRCQ2hhbmdlRGVzaWduTW9kZSIsSURfQlJPV1NFUl9TUUwsICAgICAgICAgICAgIENvbW1hbmRHcm91cDo6VklFVyApOwogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86REJDbGVhclF1ZXJ5IiwgICAgICBTSURfQlJPV1NFUl9DTEVBUl9RVUVSWSwgICAgQ29tbWFuZEdyb3VwOjpFRElUICk7CiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpTYmFFeGVjdXRlU3FsIiwgICAgIElEX0JST1dTRVJfUVVFUllfRVhFQ1VURSwgICBDb21tYW5kR3JvdXA6OlZJRVcgKTsKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOkRCQWRkUmVsYXRpb24iLCAgICAgU0lEX1JFTEFUSU9OX0FERF9SRUxBVElPTiwgIENvbW1hbmRHcm91cDo6RURJVCApOwogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86REJRdWVyeVByZXZpZXciLCAgICBTSURfREJfUVVFUllfUFJFVklFVywgICAgICAgQ29tbWFuZEdyb3VwOjpWSUVXICk7CgojaWYgT1NMX0RFQlVHX0xFVkVMID4gMQogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86REJTaG93UGFyc2VUcmVlIiwgICBJRF9FRElUX1FVRVJZX1NRTCApOwogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86REJNYWtlRGlzanVuY3QiLCAgICBJRF9FRElUX1FVRVJZX0RFU0lHTiApOwojZW5kaWYKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OmltcGxfb25Nb2RpZnlDaGFuZ2VkKCkKewoJT0pvaW5Db250cm9sbGVyOjppbXBsX29uTW9kaWZ5Q2hhbmdlZCgpOwoJSW52YWxpZGF0ZUZlYXR1cmUoU0lEX0JST1dTRVJfQ0xFQVJfUVVFUlkpOwoJSW52YWxpZGF0ZUZlYXR1cmUoSURfQlJPV1NFUl9TQVZFQVNET0MpOwoJSW52YWxpZGF0ZUZlYXR1cmUoSURfQlJPV1NFUl9RVUVSWV9FWEVDVVRFKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIE9RdWVyeUNvbnRyb2xsZXI6OmRpc3Bvc2luZyggY29uc3QgRXZlbnRPYmplY3QmIFNvdXJjZSApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCnsKCTo6dm9zOjpPR3VhcmQgYUd1YXJkKEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkpOwoKCWlmICggZ2V0Q29udGFpbmVyKCkgJiYgU291cmNlLlNvdXJjZS5pcygpICkKCXsKCQlpZiAoIFNvdXJjZS5Tb3VyY2UgPT0gbV9hQ3VycmVudEZyYW1lLmdldEZyYW1lKCkgKQoJCXsJLy8gb3VyIGZyYW1lIGlzIGJlaW5nIGRpc3Bvc2VkIC0+IGNsb3NlIHRoZSBwcmV2aWV3IHdpbmRvdyAoaWYgd2UgaGF2ZSBvbmUpCiAgICAgICAgICAgIFJlZmVyZW5jZTwgWEZyYW1lID4geFByZXZpZXdGcmFtZSggZ2V0Q29udGFpbmVyKCktPmdldFByZXZpZXdGcmFtZSgpICk7CgkJCTo6Y29tcGhlbHBlcjo6ZGlzcG9zZUNvbXBvbmVudCggeFByZXZpZXdGcmFtZSApOwoJCX0KCQllbHNlIGlmICggU291cmNlLlNvdXJjZSA9PSBnZXRDb250YWluZXIoKS0+Z2V0UHJldmlld0ZyYW1lKCkgKQoJCXsKCQkJZ2V0Q29udGFpbmVyKCktPmRpc3Bvc2luZ1ByZXZpZXcoKTsKCQl9Cgl9CgoJT0pvaW5Db250cm9sbGVyOjpkaXNwb3NpbmcoU291cmNlKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OnJlY29ubmVjdChzYWxfQm9vbCBfYlVJKQp7CglkZWxldGVJdGVyYXRvcigpOwoJOjpjb21waGVscGVyOjpkaXNwb3NlQ29tcG9uZW50KG1feENvbXBvc2VyKTsKCglPSm9pbkNvbnRyb2xsZXI6OnJlY29ubmVjdCggX2JVSSApOwoKCWlmIChpc0Nvbm5lY3RlZCgpKQoJewoJCXNldFF1ZXJ5Q29tcG9zZXIoKTsKCX0KCWVsc2UKCXsKCQlpZihtX2JHcmFwaGljYWxEZXNpZ24pCgkJewoJCQltX2JHcmFwaGljYWxEZXNpZ24gPSBzYWxfRmFsc2U7CgkJCS8vIGRvbid0IGNhbGwgRXhlY3V0ZShTUUwpIGJlY2F1c2UgdGhpcyBjaGFuZ2VzIHRoZSBzcWwgc3RhdGVtZW50CgkJCWltcGxfc2V0Vmlld01vZGUoIE5VTEwgKTsKCQl9CgkJSW52YWxpZGF0ZUFsbCgpOwoJfQp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OnNhdmVWaWV3U2V0dGluZ3MoIDo6Y29tcGhlbHBlcjo6TmFtZWRWYWx1ZUNvbGxlY3Rpb24mIG9fclZpZXdTZXR0aW5ncywgY29uc3QgYm9vbCBpX2luY2x1ZGluZ0NyaXRlcmlhICkgY29uc3QKewoJc2F2ZVRhYmxlV2luZG93cyggb19yVmlld1NldHRpbmdzICk7CgogICAgT1RhYmxlRmllbGRzOjpjb25zdF9pdGVyYXRvciBmaWVsZCA9IG1fdlRhYmxlRmllbGREZXNjLmJlZ2luKCk7CiAgICBPVGFibGVGaWVsZHM6OmNvbnN0X2l0ZXJhdG9yIGZpZWxkRW5kID0gbV92VGFibGVGaWVsZERlc2MuZW5kKCk7CgogICAgOjpjb21waGVscGVyOjpOYW1lZFZhbHVlQ29sbGVjdGlvbiBhQWxsRmllbGRzRGF0YTsKICAgIDo6Y29tcGhlbHBlcjo6TmFtZWRWYWx1ZUNvbGxlY3Rpb24gYUZpZWxkRGF0YTsKCWZvciAoIHNhbF9JbnQzMiBpID0gMTsgZmllbGQgIT0gZmllbGRFbmQ7ICsrZmllbGQsICsraSApCgl7CgkJaWYgKCAhKCpmaWVsZCktPklzRW1wdHkoKSApCgkJewogICAgICAgICAgICBhRmllbGREYXRhLmNsZWFyKCk7CgkJCSgqZmllbGQpLT5TYXZlKCBhRmllbGREYXRhLCBpX2luY2x1ZGluZ0NyaXRlcmlhICk7CgogICAgICAgICAgICBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgc0ZpZWxkU2V0dGluZ05hbWUgPSA6OnJ0bDo6T1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSggIkZpZWxkIiApICkgKyA6OnJ0bDo6T1VTdHJpbmc6OnZhbHVlT2YoIGkgKTsKICAgICAgICAgICAgYUFsbEZpZWxkc0RhdGEucHV0KCBzRmllbGRTZXR0aW5nTmFtZSwgYUZpZWxkRGF0YS5nZXRQcm9wZXJ0eVZhbHVlcygpICk7CgkJfQoJfQoKICAgIG9fclZpZXdTZXR0aW5ncy5wdXQoICJGaWVsZHMiLCBhQWxsRmllbGRzRGF0YS5nZXRQcm9wZXJ0eVZhbHVlcygpICk7CiAgICBvX3JWaWV3U2V0dGluZ3MucHV0KCAiU3BsaXR0ZXJQb3NpdGlvbiIsIG1fblNwbGl0UG9zICk7CiAgICBvX3JWaWV3U2V0dGluZ3MucHV0KCAiVmlzaWJsZVJvd3MiLCBtX25WaXNpYmxlUm93cyApOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6bG9hZFZpZXdTZXR0aW5ncyggY29uc3QgOjpjb21waGVscGVyOjpOYW1lZFZhbHVlQ29sbGVjdGlvbiYgb19yVmlld1NldHRpbmdzICkKewoJbG9hZFRhYmxlV2luZG93cyggb19yVmlld1NldHRpbmdzICk7CgogICAgbV9uU3BsaXRQb3MgPSBvX3JWaWV3U2V0dGluZ3MuZ2V0T3JEZWZhdWx0KCAiU3BsaXR0ZXJQb3NpdGlvbiIsIG1fblNwbGl0UG9zICk7CiAgICBtX25WaXNpYmxlUm93cyA9IG9fclZpZXdTZXR0aW5ncy5nZXRPckRlZmF1bHQoICJWaXNpYmxlUm93cyIsIG1fblZpc2libGVSb3dzICk7CiAgICBtX2FGaWVsZEluZm9ybWF0aW9uID0gb19yVmlld1NldHRpbmdzLmdldE9yRGVmYXVsdCggIkZpZWxkcyIsIG1fYUZpZWxkSW5mb3JtYXRpb24gKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfSW50MzIgT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0Q29sV2lkdGgoc2FsX3VJbnQxNiBfbkNvbFBvcykgIGNvbnN0CnsKICAgIGlmICggX25Db2xQb3MgPCBtX2FGaWVsZEluZm9ybWF0aW9uLmdldExlbmd0aCgpICkKICAgIHsKICAgICAgICA6OnN0ZDo6YXV0b19wdHI8T1RhYmxlRmllbGREZXNjPiBwRmllbGQoIG5ldyBPVGFibGVGaWVsZERlc2MoKSk7CiAgICAgICAgcEZpZWxkLT5Mb2FkKCBtX2FGaWVsZEluZm9ybWF0aW9uWyBfbkNvbFBvcyBdLCBmYWxzZSApOwogICAgICAgIHJldHVybiBwRmllbGQtPkdldENvbFdpZHRoKCk7CiAgICB9CiAgICByZXR1cm4gMDsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpSZWZlcmVuY2U8WE5hbWVBY2Nlc3M+IE9RdWVyeUNvbnRyb2xsZXI6OmdldE9iamVjdENvbnRhaW5lcigpICBjb25zdAp7CglSZWZlcmVuY2U8IFhOYW1lQWNjZXNzID4geEVsZW1lbnRzOwoJaWYgKCBlZGl0aW5nVmlldygpICkKCXsKCQlSZWZlcmVuY2U8IFhWaWV3c1N1cHBsaWVyID4geFZpZXdzU3VwcCggZ2V0Q29ubmVjdGlvbigpLCBVTk9fUVVFUlkgKTsKCQlpZiAoIHhWaWV3c1N1cHAuaXMoKSApCgkJCXhFbGVtZW50cyA9IHhWaWV3c1N1cHAtPmdldFZpZXdzKCk7Cgl9CgllbHNlCgl7CgkJUmVmZXJlbmNlPCBYUXVlcmllc1N1cHBsaWVyID4geFF1ZXJpZXNTdXBwKCBnZXRDb25uZWN0aW9uKCksIFVOT19RVUVSWSApOwoJCWlmICggeFF1ZXJpZXNTdXBwLmlzKCkgKQoJCQl4RWxlbWVudHMgPSB4UXVlcmllc1N1cHAtPmdldFF1ZXJpZXMoKTsKCQllbHNlCgkJewoJCQlSZWZlcmVuY2U8IFhRdWVyeURlZmluaXRpb25zU3VwcGxpZXIgPiB4UXVlcnlEZWZzU3VwcCggZ2V0RGF0YVNvdXJjZSgpLCBVTk9fUVVFUlkgKTsKCQkJaWYgKCB4UXVlcnlEZWZzU3VwcC5pcygpICkKCQkJCXhFbGVtZW50cyA9IHhRdWVyeURlZnNTdXBwLT5nZXRRdWVyeURlZmluaXRpb25zKCk7CgkJfQoJfQoKICAgIE9TTF9FTlNVUkUoIHhFbGVtZW50cy5pcygpLCAiT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0T2JqZWN0Q29udGFpbmVyOiB1bmFibGUgdG8gb2J0YWluIHRoZSBjb250YWluZXIhIiApOwoJcmV0dXJuIHhFbGVtZW50czsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpleGVjdXRlUXVlcnkoKQp7CgkvLyB3ZSBkb24ndCBuZWVkIHRvIGNoZWNrIHRoZSBjb25uZWN0aW9uIGhlcmUgYmVjYXVzZSB3ZSBhbHJlYWR5IGNoZWNrIHRoZSBjb21wb3NlcgoJLy8gd2hpY2ggY2FuJ3QgbGl2ZSB3aXRob3V0IGhpcyBjb25uZWN0aW9uCgk6OnJ0bDo6T1VTdHJpbmcgc1RyYW5zbGF0ZWRTdG10ID0gdHJhbnNsYXRlU3RhdGVtZW50KCBmYWxzZSApOwoKCTo6cnRsOjpPVVN0cmluZyBzRGF0YVNvdXJjZU5hbWUgPSBnZXREYXRhU291cmNlTmFtZSgpOwoJaWYgKCBzRGF0YVNvdXJjZU5hbWUuZ2V0TGVuZ3RoKCkgJiYgc1RyYW5zbGF0ZWRTdG10LmdldExlbmd0aCgpICkKCXsKCQl0cnkKCQl7CgkJCWdldENvbnRhaW5lcigpLT5zaG93UHJldmlldyggZ2V0RnJhbWUoKSApOwoJCQlJbnZhbGlkYXRlRmVhdHVyZShTSURfREJfUVVFUllfUFJFVklFVyk7CgoJCQlVUkwgYVdhbnRUb0Rpc3BhdGNoOwoJCQlhV2FudFRvRGlzcGF0Y2guQ29tcGxldGUgPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiLmNvbXBvbmVudDpEQi9EYXRhU291cmNlQnJvd3NlciIpOwoKCQkJOjpydGw6Ok9VU3RyaW5nIHNGcmFtZU5hbWUoIEZSQU1FX05BTUVfUVVFUllfUFJFVklFVyApOwoJCQlzYWxfSW50MzIgblNlYXJjaEZsYWdzID0gRnJhbWVTZWFyY2hGbGFnOjpDSElMRFJFTjsKCgkJCVJlZmVyZW5jZTwgWERpc3BhdGNoPiB4RGlzcDsKCQkJUmVmZXJlbmNlPCBYRGlzcGF0Y2hQcm92aWRlcj4geFByb3YoIGdldEZyYW1lKCktPmZpbmRGcmFtZSggc0ZyYW1lTmFtZSwgblNlYXJjaEZsYWdzICksIFVOT19RVUVSWSApOwoJCQlpZigheFByb3YuaXMoKSkKCQkJewoJCQkJeFByb3Yuc2V0KCBnZXRGcmFtZSgpLCBVTk9fUVVFUlkgKTsKCQkJCWlmICh4UHJvdi5pcygpKQoJCQkJCXhEaXNwID0geFByb3YtPnF1ZXJ5RGlzcGF0Y2goYVdhbnRUb0Rpc3BhdGNoLCBzRnJhbWVOYW1lLCBuU2VhcmNoRmxhZ3MpOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJeERpc3AgPSB4UHJvdi0+cXVlcnlEaXNwYXRjaChhV2FudFRvRGlzcGF0Y2gsIHNGcmFtZU5hbWUsIEZyYW1lU2VhcmNoRmxhZzo6U0VMRik7CgkJCX0KCQkJaWYgKHhEaXNwLmlzKCkpCgkJCXsKCQkJCVNlcXVlbmNlPCBQcm9wZXJ0eVZhbHVlPiBhUHJvcHMoOSk7CgkJCQlhUHJvcHNbMF0uTmFtZSA9IFBST1BFUlRZX0RBVEFTT1VSQ0VOQU1FOwoJCQkJYVByb3BzWzBdLlZhbHVlIDw8PSBzRGF0YVNvdXJjZU5hbWU7CgoJCQkJYVByb3BzWzFdLk5hbWUgPSBQUk9QRVJUWV9DT01NQU5EX1RZUEU7CgkJCQlhUHJvcHNbMV0uVmFsdWUgPDw9IENvbW1hbmRUeXBlOjpDT01NQU5EOwoKCQkJCWFQcm9wc1syXS5OYW1lID0gUFJPUEVSVFlfQ09NTUFORDsKCQkJCWFQcm9wc1syXS5WYWx1ZSA8PD0gc1RyYW5zbGF0ZWRTdG10OwoKCQkJCWFQcm9wc1szXS5OYW1lID0gUFJPUEVSVFlfRU5BQkxFX0JST1dTRVI7CgkJCQlhUHJvcHNbM10uVmFsdWUgPSA6OmNwcHU6OmJvb2wyYW55KHNhbF9GYWxzZSk7CgoJCQkJYVByb3BzWzRdLk5hbWUgPSBQUk9QRVJUWV9BQ1RJVkVfQ09OTkVDVElPTjsKCQkJCWFQcm9wc1s0XS5WYWx1ZSA8PD0gZ2V0Q29ubmVjdGlvbigpOwoKCQkJCWFQcm9wc1s1XS5OYW1lID0gUFJPUEVSVFlfVVBEQVRFX0NBVEFMT0dOQU1FOwoJCQkJYVByb3BzWzVdLlZhbHVlIDw8PSBtX3NVcGRhdGVDYXRhbG9nTmFtZTsKCgkJCQlhUHJvcHNbNl0uTmFtZSA9IFBST1BFUlRZX1VQREFURV9TQ0hFTUFOQU1FOwoJCQkJYVByb3BzWzZdLlZhbHVlIDw8PSBtX3NVcGRhdGVTY2hlbWFOYW1lOwoKCQkJCWFQcm9wc1s3XS5OYW1lID0gUFJPUEVSVFlfVVBEQVRFX1RBQkxFTkFNRTsKCQkJCWFQcm9wc1s3XS5WYWx1ZSA8PD0gbV9zVXBkYXRlVGFibGVOYW1lOwoKCQkJCWFQcm9wc1s4XS5OYW1lID0gUFJPUEVSVFlfRVNDQVBFX1BST0NFU1NJTkc7CgkJCQlhUHJvcHNbOF0uVmFsdWUgPSA6OmNwcHU6OmJvb2wyYW55KG1fYkVzY2FwZVByb2Nlc3NpbmcpOwoKCQkJCXhEaXNwLT5kaXNwYXRjaChhV2FudFRvRGlzcGF0Y2gsIGFQcm9wcyk7CgkJCQkvLyBjaGVjayB0aGUgc3RhdGUgb2YgdGhlIGJlYW1lcgoJCQkJLy8gYmUgbm90aWZpZWQgd2hlbiB0aGUgYmVhbWVyIGZyYW1lIGlzIGNsb3NlZAoJCQkJUmVmZXJlbmNlPCBYQ29tcG9uZW50ID4gIHhDb21wb25lbnQoIGdldEZyYW1lKCktPmZpbmRGcmFtZSggc0ZyYW1lTmFtZSwgblNlYXJjaEZsYWdzICksIFVOT19RVUVSWSApOwoJCQkJaWYgKHhDb21wb25lbnQuaXMoKSkKCQkJCXsKCQkJCQlPU0xfRU5TVVJFKFJlZmVyZW5jZTwgWEZyYW1lID4oeENvbXBvbmVudCwgVU5PX1FVRVJZKS5nZXQoKSA9PSBnZXRDb250YWluZXIoKS0+Z2V0UHJldmlld0ZyYW1lKCkuZ2V0KCksCgkJCQkJCSJPUXVlcnlDb250cm9sbGVyOjpleGVjdXRlUXVlcnk6IG9vcHMgLi4uIHdoaWNoIHdpbmRvdyBkbyBJIGhhdmUgaGVyZT8iKTsKCQkJCQlSZWZlcmVuY2U8IFhFdmVudExpc3RlbmVyPiB4RXZ0TCgoOjpjcHB1OjpPV2Vha09iamVjdCopdGhpcyxVTk9fUVVFUlkpOwoJCQkJCXhDb21wb25lbnQtPmFkZEV2ZW50TGlzdGVuZXIoeEV2dEwpOwoJCQkJfQoJCQl9CgkJCWVsc2UKCQkJewoJCQkJT1NMX0VOU1VSRSgwLCJDb3VsZG4ndCBjcmVhdGUgYSBiZWFtZXIgd2luZG93ISIpOwoJCQl9CgkJfQoJCWNhdGNoKGNvbnN0IEV4Y2VwdGlvbiYpCgkJewoJCQlPU0xfRU5TVVJFKDAsIkNvdWxkbid0IGNyZWF0ZSBhIGJlYW1lciB3aW5kb3chIik7CgkJfQoJfQp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9Cb29sIE9RdWVyeUNvbnRyb2xsZXI6OmFza0Zvck5ld05hbWUoY29uc3QgUmVmZXJlbmNlPFhOYW1lQWNjZXNzPiYgX3hFbGVtZW50cyxzYWxfQm9vbCBfYlNhdmVBcykKewogICAgT1NMX0VOU1VSRSggIWVkaXRpbmdDb21tYW5kKCksICJPUXVlcnlDb250cm9sbGVyOjphc2tGb3JOZXdOYW1lOiBub3QgdG8gYmUgY2FsbGVkIHdoZW4gZGVzaWduaW5nIGFuIGluZGVwZW5kZW50IHN0YXRlbWVudCEiICk7CiAgICBpZiAoIGVkaXRpbmdDb21tYW5kKCkgKQogICAgICAgIHJldHVybiBzYWxfRmFsc2U7CgogICAgT1NMX1BSRUNPTkQoIF94RWxlbWVudHMuaXMoKSwgIk9RdWVyeUNvbnRyb2xsZXI6OmFza0Zvck5ld05hbWU6IGludmFsaWQgY29udGFpbmVyISIgKTsKICAgIGlmICAoICFfeEVsZW1lbnRzLmlzKCkgKQogICAgICAgIHJldHVybiBzYWxfRmFsc2U7CgoJc2FsX0Jvb2wgYlJldCA9IHNhbF9UcnVlOwoJc2FsX0Jvb2wgYk5ldyA9IF9iU2F2ZUFzIHx8ICFfeEVsZW1lbnRzLT5oYXNCeU5hbWUoIG1fc05hbWUgKTsKCWlmKGJOZXcpCgl7CgkJU3RyaW5nIGFEZWZhdWx0TmFtZTsKCQlpZiAoICggX2JTYXZlQXMgJiYgIWJOZXcgKSB8fCAoIGJOZXcgJiYgbV9zTmFtZS5nZXRMZW5ndGgoKSApICkKCQkJYURlZmF1bHROYW1lID0gU3RyaW5nKCBtX3NOYW1lICk7CgkJZWxzZQogICAgICAgIHsKICAgICAgICAgICAgU3RyaW5nIHNOYW1lID0gU3RyaW5nKCBNb2R1bGVSZXMoIGVkaXRpbmdWaWV3KCkgPyBTVFJfVklFV19USVRMRSA6IFNUUl9RUllfVElUTEUgKSApOwoJCQlhRGVmYXVsdE5hbWUgPSBzTmFtZS5HZXRUb2tlbigwLCcgJyk7CiAgICAgICAgICAgIC8vYURlZmF1bHROYW1lID0gZ2V0UHJpdmF0ZVRpdGxlKCApOwogICAgICAgICAgICBhRGVmYXVsdE5hbWUgPSA6OmRidG9vbHM6OmNyZWF0ZVVuaXF1ZU5hbWUoX3hFbGVtZW50cyxhRGVmYXVsdE5hbWUpOwogICAgICAgIH0KCiAgICAgICAgRHluYW1pY1RhYmxlT3JRdWVyeU5hbWVDaGVjayBhTmFtZUNoZWNrZXIoIGdldENvbm5lY3Rpb24oKSwgQ29tbWFuZFR5cGU6OlFVRVJZICk7CgkJT1NhdmVBc0RsZyBhRGxnKAoJCQkJZ2V0VmlldygpLAogICAgICAgICAgICAgICAgbV9uQ29tbWFuZFR5cGUsCiAgICAgICAgICAgICAgICBnZXRPUkIoKSwKCQkJCWdldENvbm5lY3Rpb24oKSwKCQkJCWFEZWZhdWx0TmFtZSwKICAgICAgICAgICAgICAgIGFOYW1lQ2hlY2tlciwKCQkJCVNBRF9ERUZBVUxUICk7CgogICAgICAgIGJSZXQgPSAoIGFEbGcuRXhlY3V0ZSgpID09IFJFVF9PSyApOwoJCWlmICggYlJldCApCgkJewoJCQltX3NOYW1lID0gYURsZy5nZXROYW1lKCk7CgkJCWlmICggZWRpdGluZ1ZpZXcoKSApCgkJCXsKCQkJCW1fc1VwZGF0ZUNhdGFsb2dOYW1lCT0gYURsZy5nZXRDYXRhbG9nKCk7CgkJCQltX3NVcGRhdGVTY2hlbWFOYW1lCQk9IGFEbGcuZ2V0U2NoZW1hKCk7CgkJCX0KCQl9Cgl9CglyZXR1cm4gYlJldDsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpib29sIE9RdWVyeUNvbnRyb2xsZXI6OmRvU2F2ZUFzRG9jKHNhbF9Cb29sIF9iU2F2ZUFzKQp7CglPU0xfRU5TVVJFKGlzRWRpdGFibGUoKSwiU2xvdCBJRF9CUk9XU0VSX1NBVkVET0Mgc2hvdWxkIG5vdCBiZSBlbmFibGVkISIpOwoJaWYgKCAhZWRpdGluZ0NvbW1hbmQoKSAmJiAhaGF2ZURhdGFTb3VyY2UoKSApCgl7CgkJU3RyaW5nIGFNZXNzYWdlKE1vZHVsZVJlcyhTVFJfREFUQVNPVVJDRV9ERUxFVEVEKSk7CgkJT1NRTFdhcm5pbmdCb3goIGdldFZpZXcoKSwgYU1lc3NhZ2UgKS5FeGVjdXRlKCk7CiAgICAgICAgcmV0dXJuIGZhbHNlOwoJfQoKCVJlZmVyZW5jZTwgWE5hbWVBY2Nlc3MgPiB4RWxlbWVudHMgPSBnZXRPYmplY3RDb250YWluZXIoKTsKCWlmICggIXhFbGVtZW50cy5pcygpICkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgaWYgKCAhZ2V0Q29udGFpbmVyKCktPmNoZWNrU3RhdGVtZW50KCkgKQoJCXJldHVybiBmYWxzZTsKCgk6OnJ0bDo6T1VTdHJpbmcgc1RyYW5zbGF0ZWRTdG10ID0gdHJhbnNsYXRlU3RhdGVtZW50KCk7CiAgICBpZiAoIGVkaXRpbmdDb21tYW5kKCkgKQogICAgewogICAgICAgIHNldE1vZGlmaWVkKCBzYWxfRmFsc2UgKTsKICAgICAgICAvLyB0aGlzIGlzIGFsbCB3ZSBuZWVkIHRvIGRvIGhlcmUuIHRyYW5zbGF0ZVN0YXRlbWVudCBpbXBsaWNpdGx5IHNldCBvdXIgbV9zU3RhdGVtZW50LCBhbmQKICAgICAgICAvLyBub3RpZmllZCBpdCwgYW5kIHRoYXQncyBhbGwKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCglpZiAoICFzVHJhbnNsYXRlZFN0bXQuZ2V0TGVuZ3RoKCkgKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAvLyBmaXJzdCB3ZSBuZWVkIGEgbmFtZSBmb3Igb3VyIHF1ZXJ5IHNvIGFzayB0aGUgdXNlcgoJLy8gZGlkIHdlIGdldCBhIG5hbWUKICAgIDo6cnRsOjpPVVN0cmluZyBzT3JpZ2luYWxOYW1lKCBtX3NOYW1lICk7CiAgICBpZiAoICFhc2tGb3JOZXdOYW1lKCB4RWxlbWVudHMsIF9iU2F2ZUFzICkgfHwgIW1fc05hbWUuZ2V0TGVuZ3RoKCkgKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICBTUUxFeGNlcHRpb25JbmZvIGFJbmZvOwogICAgYm9vbCBiU3VjY2VzcyA9IGZhbHNlOwogICAgYm9vbCBiTmV3ID0gZmFsc2U7Cgl0cnkKCXsKICAgICAgICBiTmV3ID0gKCBfYlNhdmVBcyApCiAgICAgICAgICAgIHx8ICggIXhFbGVtZW50cy0+aGFzQnlOYW1lKCBtX3NOYW1lICkgKTsKCiAgICAgICAgUmVmZXJlbmNlPFhQcm9wZXJ0eVNldD4geFF1ZXJ5OwoJCWlmICggYk5ldyApIC8vIGp1c3QgdG8gbWFrZSBzdXJlIHRoZSBxdWVyeSBhbHJlYWR5IGV4aXN0cwoJCXsKICAgICAgICAgICAgLy8gZHJvcCB0aGUgcXVlcnksIGluIGNhc2UgaXQgYWxyZWFkeSBleGlzdHMKCQkJaWYgKCB4RWxlbWVudHMtPmhhc0J5TmFtZSggbV9zTmFtZSApICkKCQkJewoJCQkJUmVmZXJlbmNlPCBYRHJvcCA+IHhOYW1lQ29udCggeEVsZW1lbnRzLCBVTk9fUVVFUlkgKTsKCQkJCWlmICggeE5hbWVDb250LmlzKCkgKQoJCQkJCXhOYW1lQ29udC0+ZHJvcEJ5TmFtZSggbV9zTmFtZSApOwoJCQkJZWxzZQoJCQkJewoJCQkJCVJlZmVyZW5jZTwgWE5hbWVDb250YWluZXIgPiB4Q29udCggeEVsZW1lbnRzLCBVTk9fUVVFUlkgKTsKCQkJCQlpZiAoIHhDb250LmlzKCkgKQoJCQkJCQl4Q29udC0+cmVtb3ZlQnlOYW1lKCBtX3NOYW1lICk7CgkJCQl9CgkJCX0KCiAgICAgICAgICAgIC8vIGNyZWF0ZSBhIG5ldyAoZW1wdHksIHVuaW5pdGlhbGl6ZWQpIHF1ZXJ5IHJlc3AuIHZpZXcKCQkJUmVmZXJlbmNlPCBYRGF0YURlc2NyaXB0b3JGYWN0b3J5ID4geEZhY3QoIHhFbGVtZW50cywgVU5PX1FVRVJZICk7CgkJCWlmICggeEZhY3QuaXMoKSApCgkJCXsKCQkJCXhRdWVyeSA9IHhGYWN0LT5jcmVhdGVEYXRhRGVzY3JpcHRvcigpOwoJCQkJLy8gdG8gc2V0IHRoZSBuYW1lIGlzIG9ubHkgYWxsb3dlZCB3aGVuIHRoZSBxdWVyeSBpcyBuZXcKCQkJCXhRdWVyeS0+c2V0UHJvcGVydHlWYWx1ZSggUFJPUEVSVFlfTkFNRSwgbWFrZUFueSggbV9zTmFtZSApICk7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlSZWZlcmVuY2U8IFhTaW5nbGVTZXJ2aWNlRmFjdG9yeSA+IHhTaW5nbGVGYWMoIHhFbGVtZW50cywgVU5PX1FVRVJZICk7CiAgICAgICAgICAgICAgICBpZiAoIHhTaW5nbGVGYWMuaXMoKSApCgkJCQkJeFF1ZXJ5ID0geFF1ZXJ5LnF1ZXJ5KCB4U2luZ2xlRmFjLT5jcmVhdGVJbnN0YW5jZSgpICk7CgkJCX0KCQl9CgkJZWxzZQoJCXsKCQkJeEVsZW1lbnRzLT5nZXRCeU5hbWUoIG1fc05hbWUgKSA+Pj0geFF1ZXJ5OwoJCX0KICAgICAgICBpZiAoICF4UXVlcnkuaXMoKSApCiAgICAgICAgICAgIHRocm93IFJ1bnRpbWVFeGNlcHRpb24oKTsKCiAgICAgICAgLy8gdGhlIG5ldyBjb21tYW5kcwogICAgICAgIGlmICggZWRpdGluZ1ZpZXcoKSAmJiAhYk5ldyApCiAgICAgICAgewogICAgICAgICAgICBPU0xfRU5TVVJFKCB4UXVlcnkgPT0gbV94QWx0ZXJWaWV3LCAiT1F1ZXJ5Q29udHJvbGxlcjo6ZG9TYXZlQXNEb2M6IGFscmVhZHkgaGF2ZSBhbm90aGVyIGFsdGVyYWJsZSB2aWV3IC4uLiE/IiApOwogICAgICAgICAgICBtX3hBbHRlclZpZXcuc2V0KCB4UXVlcnksIFVOT19RVUVSWV9USFJPVyApOwogICAgICAgICAgICBtX3hBbHRlclZpZXctPmFsdGVyQ29tbWFuZCggc1RyYW5zbGF0ZWRTdG10ICk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7ICAgLy8gd2UncmUgY3JlYXRpbmcgYSBxdWVyeSwgb3IgYSAqbmV3KiB2aWV3CiAgICAgICAgICAgIHhRdWVyeS0+c2V0UHJvcGVydHlWYWx1ZSggUFJPUEVSVFlfQ09NTUFORCwgbWFrZUFueSggc1RyYW5zbGF0ZWRTdG10ICkgKTsKCiAgICAgICAgICAgIGlmICggZWRpdGluZ1ZpZXcoKSApCiAgICAgICAgICAgIHsKCQkJICAgIHhRdWVyeS0+c2V0UHJvcGVydHlWYWx1ZSggUFJPUEVSVFlfQ0FUQUxPR05BTUUsIG1ha2VBbnkoIG1fc1VwZGF0ZUNhdGFsb2dOYW1lICkgKTsKCQkJICAgIHhRdWVyeS0+c2V0UHJvcGVydHlWYWx1ZSggUFJPUEVSVFlfU0NIRU1BTkFNRSwgbWFrZUFueSggbV9zVXBkYXRlU2NoZW1hTmFtZSApICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICggZWRpdGluZ1F1ZXJ5KCkgKQoJCQl7CgkJCQl4UXVlcnktPnNldFByb3BlcnR5VmFsdWUoIFBST1BFUlRZX1VQREFURV9UQUJMRU5BTUUsIG1ha2VBbnkoIG1fc1VwZGF0ZVRhYmxlTmFtZSApICk7CgkJCQl4UXVlcnktPnNldFByb3BlcnR5VmFsdWUoIFBST1BFUlRZX0VTQ0FQRV9QUk9DRVNTSU5HLDo6Y3BwdTo6Ym9vbDJhbnkoIG1fYkVzY2FwZVByb2Nlc3NpbmcgKSApOwoKCQkJCXhRdWVyeS0+c2V0UHJvcGVydHlWYWx1ZSggUFJPUEVSVFlfTEFZT1VUSU5GT1JNQVRJT04sIGdldFZpZXdEYXRhKCkgKTsKCQkJfQogICAgICAgIH0KCgkJaWYgKCBiTmV3ICkKCQl7CgkJCVJlZmVyZW5jZTwgWEFwcGVuZCA+IHhBcHBlbmQoIHhFbGVtZW50cywgVU5PX1FVRVJZICk7CgkJCWlmICggeEFwcGVuZC5pcygpICkKCQkJewoJCQkJeEFwcGVuZC0+YXBwZW5kQnlEZXNjcmlwdG9yKCB4UXVlcnkgKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCVJlZmVyZW5jZTwgWE5hbWVDb250YWluZXIgPiB4Q29udCggeEVsZW1lbnRzLCBVTk9fUVVFUlkgKTsKCQkJCWlmICggeENvbnQuaXMoKSApCgkJCQkJeENvbnQtPmluc2VydEJ5TmFtZSggbV9zTmFtZSwgbWFrZUFueSggeFF1ZXJ5ICkgKTsKCQkJfQoKCQkJaWYgKCBlZGl0aW5nVmlldygpICkKCQkJewoJCQkJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiB4Vmlld1Byb3BzOwoJCQkJaWYgKCB4RWxlbWVudHMtPmhhc0J5TmFtZSggbV9zTmFtZSApICkKCQkJCQl4Vmlld1Byb3BzLnNldCggeEVsZW1lbnRzLT5nZXRCeU5hbWUoIG1fc05hbWUgKSwgVU5PX1FVRVJZICk7CgoJCQkJaWYgKCAheFZpZXdQcm9wcy5pcygpICkgLy8gY29ycmVjdCBuYW1lIGFuZCB0cnkgYWdhaW4KCQkJCQltX3NOYW1lID0gOjpkYnRvb2xzOjpjb21wb3NlVGFibGVOYW1lKCBnZXRNZXRhRGF0YSgpLCB4UXVlcnksIDo6ZGJ0b29sczo6ZUluRGF0YU1hbmlwdWxhdGlvbiwgZmFsc2UsIGZhbHNlLCBmYWxzZSApOwoKICAgICAgICAgICAgICAgIE9TTF9FTlNVUkUoIHhFbGVtZW50cy0+aGFzQnlOYW1lKCBtX3NOYW1lICksICJPUXVlcnlDb250cm9sbGVyOjpkb1NhdmVBc0RvYzogbmV3bHkgY3JlYWVkIHZpZXcgZG9lcyBub3QgZXhpc3QhIiApOwoKICAgICAgICAgICAgICAgIGlmICggeEVsZW1lbnRzLT5oYXNCeU5hbWUoIG1fc05hbWUgKSApCiAgICAgICAgICAgICAgICAgICAgbV94QWx0ZXJWaWV3LnNldCggeEVsZW1lbnRzLT5nZXRCeU5hbWUoIG1fc05hbWUgKSwgVU5PX1FVRVJZICk7CgogICAgICAgICAgICAgICAgLy8gbm93IGNoZWNrIGlmIG91ciBkYXRhc291cmNlIGhhcyBzZXQgYSB0YWJsZWZpbHRlciBhbmQgaWYgc28sIGFwcGVuZCB0aGUgbmV3IHRhYmxlIG5hbWUgdG8gaXQKCQkJCTo6ZGJhdWk6OmFwcGVuZFRvRmlsdGVyKCBnZXRDb25uZWN0aW9uKCksIG1fc05hbWUsIGdldE9SQigpLCBnZXRWaWV3KCkgKTsKCQkJfSAvLyBpZiAoIGVkaXRpbmdWaWV3KCkgKQogICAgICAgICAgICBSZWZlcmVuY2U8IFhUaXRsZUNoYW5nZUxpc3RlbmVyPiB4RXZlbnRMaXN0ZW5lcihpbXBsX2dldFRpdGxlSGVscGVyX3Rocm93KCksVU5PX1FVRVJZKTsKICAgICAgICAgICAgaWYgKCB4RXZlbnRMaXN0ZW5lci5pcygpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVGl0bGVDaGFuZ2VkRXZlbnQgYUV2ZW50OwogICAgICAgICAgICAgICAgeEV2ZW50TGlzdGVuZXItPnRpdGxlQ2hhbmdlZChhRXZlbnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlbGVhc2VOdW1iZXJGb3JDb21wb25lbnQoKTsKCQl9CgoJCXNldE1vZGlmaWVkKCBzYWxfRmFsc2UgKTsKICAgICAgICBiU3VjY2VzcyA9IHRydWU7CiAgICAgICAgCgl9CgljYXRjaCggY29uc3QgU1FMRXhjZXB0aW9uJiApCgl7CiAgICAgICAgaWYgKCAhYk5ldyApCiAgICAgICAgICAgIG1fc05hbWUgPSBzT3JpZ2luYWxOYW1lOwogICAgICAgIGFJbmZvID0gU1FMRXhjZXB0aW9uSW5mbyggOjpjcHB1OjpnZXRDYXVnaHRFeGNlcHRpb24oKSApOwoJfQoJY2F0Y2goRXhjZXB0aW9uJikKCXsKICAgICAgICBpZiAoICFiTmV3ICkKICAgICAgICAgICAgbV9zTmFtZSA9IHNPcmlnaW5hbE5hbWU7CiAgICAgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKCX0KCglzaG93RXJyb3IoIGFJbmZvICk7CgogICAgLy8gdXBkYXRlIHRoZSB0aXRsZSBvZiBvdXIgd2luZG93CgkvL3VwZGF0ZVRpdGxlKCk7CgogICAgLy8gaWYgd2Ugc3VjY2Vzc2Z1bGx5IHNhdmVkIGEgdmlldyB3ZSB3ZXJlIGNyZWF0aW5nLCB0aGVuIGNsb3NlIHRoZSBkZXNpZ25lcgogICAgaWYgKCBiU3VjY2VzcyAmJiBlZGl0aW5nVmlldygpICYmICFtX3hBbHRlclZpZXcuaXMoKSApCiAgICB7CgkJY2xvc2VUYXNrKCk7CiAgICB9CgogICAgaWYgKCBiU3VjY2VzcyAmJiBlZGl0aW5nVmlldygpICkKICAgICAgICBJbnZhbGlkYXRlRmVhdHVyZSggSURfQlJPV1NFUl9FRElURE9DICk7CgogICAgcmV0dXJuIGJTdWNjZXNzOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6cnRsOjpPVVN0cmluZyBPUXVlcnlDb250cm9sbGVyOjp0cmFuc2xhdGVTdGF0ZW1lbnQoIGJvb2wgX2JGaXJlU3RhdGVtZW50Q2hhbmdlICkKewoJLy8gbm93IHNldCB0aGUgcHJvcGVydGllcwoJc2V0U3RhdGVtZW50X2ZpcmVFdmVudCggZ2V0Q29udGFpbmVyKCktPmdldFN0YXRlbWVudCgpLCBfYkZpcmVTdGF0ZW1lbnRDaGFuZ2UgKTsKCTo6cnRsOjpPVVN0cmluZyBzVHJhbnNsYXRlZFN0bXQ7CglpZihtX3NTdGF0ZW1lbnQuZ2V0TGVuZ3RoKCkgJiYgbV94Q29tcG9zZXIuaXMoKSAmJiBtX2JFc2NhcGVQcm9jZXNzaW5nKQoJewoJCXRyeQoJCXsKCQkJOjpydGw6Ok9VU3RyaW5nIGFFcnJvck1zZzsKCgkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwTm9kZSA9IG1fYVNxbFBhcnNlci5wYXJzZVRyZWUoIGFFcnJvck1zZywgbV9zU3RhdGVtZW50LCBtX2JHcmFwaGljYWxEZXNpZ24gKTsKCQkJaWYocE5vZGUpCgkJCXsKICAgICAgICAgICAgICAgIHBOb2RlLT5wYXJzZU5vZGVUb1N0ciggc1RyYW5zbGF0ZWRTdG10LCBnZXRDb25uZWN0aW9uKCkgKTsKCQkJCWRlbGV0ZSBwTm9kZTsKCQkJfQoKICAgICAgICAgICAgbV94Q29tcG9zZXItPnNldFF1ZXJ5KHNUcmFuc2xhdGVkU3RtdCk7CgkJCXNUcmFuc2xhdGVkU3RtdCA9IG1feENvbXBvc2VyLT5nZXRDb21wb3NlZFF1ZXJ5KCk7CgkJfQoJCWNhdGNoKFNRTEV4Y2VwdGlvbiYgZSkKCQl7CgkJCTo6ZGJ0b29sczo6U1FMRXhjZXB0aW9uSW5mbyBhSW5mbyhlKTsKCQkJc2hvd0Vycm9yKGFJbmZvKTsKCQkJLy8gYW4gZXJyb3Igb2NjdXJyZWQgc28gd2UgY2xlYXIgdGhlIHN0YXRlbWVudAoJCQlzVHJhbnNsYXRlZFN0bXQgPSA6OnJ0bDo6T1VTdHJpbmcoKTsKCQl9Cgl9CgllbHNlIGlmKCFtX3NTdGF0ZW1lbnQuZ2V0TGVuZ3RoKCkpCgl7CiAgICAgICAgTW9kdWxlUmVzIGFNb2R1bGVSZXMoU1RSX1FSWV9OT1NFTEVDVCk7CiAgICAgICAgU3RyaW5nIHNUbXBTdHIoYU1vZHVsZVJlcyk7CgkJOjpydGw6Ok9VU3RyaW5nIHNFcnJvcihzVG1wU3RyKTsKCQlzaG93RXJyb3IoU1FMRXhjZXB0aW9uKHNFcnJvcixOVUxMLDo6cnRsOjpPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIlMxMDAwIikgKSwxMDAwLEFueSgpKSk7Cgl9CgllbHNlCgkJc1RyYW5zbGF0ZWRTdG10ID0gbV9zU3RhdGVtZW50OwoKCXJldHVybiBzVHJhbnNsYXRlZFN0bXQ7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2hvcnQgT1F1ZXJ5Q29udHJvbGxlcjo6c2F2ZU1vZGlmaWVkKCkKewoJdm9zOjpPR3VhcmQgYVNvbGFyR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggZ2V0TXV0ZXgoKSApOwoJc2hvcnQgblJldCA9IFJFVF9ZRVM7CiAgICBpZiAoICFpc0Nvbm5lY3RlZCgpIHx8ICFpc01vZGlmaWVkKCkgKQogICAgICAgIHJldHVybiBuUmV0OwoKCWlmICAoICAhbV9iR3JhcGhpY2FsRGVzaWduCiAgICAgICAgfHwgKCAgIW1fdlRhYmxlRmllbGREZXNjLmVtcHR5KCkKICAgICAgICAgICAmJiAhbV92VGFibGVEYXRhLmVtcHR5KCkKICAgICAgICAgICApCiAgICAgICAgKQoJewogICAgICAgIFN0cmluZyBzTWVzc2FnZVRleHQoIGxjbF9nZXRPYmplY3RSZXNvdXJjZVN0cmluZyggU1RSX1FVRVJZX1NBVkVNT0RJRklFRCwgbV9uQ29tbWFuZFR5cGUgKSApOwogICAgICAgIFF1ZXJ5Qm94IGFRcnkoIGdldFZpZXcoKSwgV0JfWUVTX05PX0NBTkNFTCB8IFdCX0RFRl9ZRVMsIHNNZXNzYWdlVGV4dCApOwoKICAgICAgICBuUmV0ID0gYVFyeS5FeGVjdXRlKCk7CgkJaWYgICggICAoIG5SZXQgPT0gUkVUX1lFUyApCiAgICAgICAgICAgICYmICAhZG9TYXZlQXNEb2MoIHNhbF9GYWxzZSApCiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIG5SZXQgPSBSRVRfQ0FOQ0VMOwoJCX0KCX0KCXJldHVybiBuUmV0Owp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9yZXNldCggY29uc3QgYm9vbCBpX2JGb3JjZUN1cnJlbnRDb250cm9sbGVyU2V0dGluZ3MgKQp7CiAgICBib29sIGJWYWxpZCA9IGZhbHNlOwoKICAgIFNlcXVlbmNlPCBQcm9wZXJ0eVZhbHVlID4gYUxheW91dEluZm9ybWF0aW9uOwoJLy8gZ2V0IGNvbW1hbmQgZnJvbSB0aGUgcXVlcnkgaWYgYSBxdWVyeSBuYW1lIHdhcyBzdXBwbGllZAogICAgaWYgKCAhaV9iRm9yY2VDdXJyZW50Q29udHJvbGxlclNldHRpbmdzICYmICFlZGl0aW5nQ29tbWFuZCgpICkKICAgIHsKCSAgICBpZiAoIG1fc05hbWUuZ2V0TGVuZ3RoKCkgKQoJICAgIHsKICAgICAgICAgICAgUmVmZXJlbmNlPCBYTmFtZUFjY2VzcyA+IHhRdWVyaWVzID0gZ2V0T2JqZWN0Q29udGFpbmVyKCk7CgkJICAgIGlmICggeFF1ZXJpZXMuaXMoKSApCgkJICAgIHsKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geFByb3A7CgkJCSAgICBpZiggeFF1ZXJpZXMtPmhhc0J5TmFtZSggbV9zTmFtZSApICYmICggeFF1ZXJpZXMtPmdldEJ5TmFtZSggbV9zTmFtZSApID4+PSB4UHJvcCApICYmIHhQcm9wLmlzKCkgKQoJCQkgICAgewogICAgICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZyBzTmV3U3RhdGVtZW50OwoJCQkJICAgIHhQcm9wLT5nZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9DT01NQU5EICkgPj49IHNOZXdTdGF0ZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgc2V0U3RhdGVtZW50X2ZpcmVFdmVudCggc05ld1N0YXRlbWVudCApOwoKICAgICAgICAgICAgICAgICAgICBzYWxfQm9vbCBiTmV3RXNjYXBlUHJvY2Vzc2luZyggc2FsX1RydWUgKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIGVkaXRpbmdRdWVyeSgpICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhQcm9wLT5nZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9FU0NBUEVfUFJPQ0VTU0lORyApID4+PSBiTmV3RXNjYXBlUHJvY2Vzc2luZzsKICAgICAgICAgICAgICAgICAgICAgICAgc2V0RXNjYXBlUHJvY2Vzc2luZ19maXJlRXZlbnQoIGJOZXdFc2NhcGVQcm9jZXNzaW5nICk7CiAgICAgICAgICAgICAgICAgICAgfQoKCQkJCSAgICBtX2JHcmFwaGljYWxEZXNpZ24gPSBtX2JHcmFwaGljYWxEZXNpZ24gJiYgbV9iRXNjYXBlUHJvY2Vzc2luZzsKICAgICAgICAgICAgICAgICAgICBiVmFsaWQgPSB0cnVlOwoKICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggZWRpdGluZ1F1ZXJ5KCkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeFByb3AtPmdldFByb3BlcnR5VmFsdWUoIFBST1BFUlRZX0xBWU9VVElORk9STUFUSU9OICkgPj49IGFMYXlvdXRJbmZvcm1hdGlvbjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAJT1NMX0VOU1VSRSggc2FsX0ZhbHNlLCAiT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9yZXNldDogY291bGQgbm90IHJldHJpZXZlIHRoZSBsYXlvdXQgaW5mb3JtYXRpb24gZnJvbSB0aGUgcXVlcnkhIiApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBiVmFsaWQgPSB0cnVlOwogICAgICAgIC8vIGFzc3VtZSB0aGF0IHdlIGdvdCBhbGwgbmVjZXNzYXJ5IGluZm9ybWF0aW9uIGR1cmluZyBpbml0aWFsaXphdGlvbgogICAgfQoKCWlmICggYlZhbGlkICkKCXsKICAgICAgICAvLyBsb2FkIHRoZSBsYXlvdXRJbmZvcm1hdGlvbgogICAgICAgIGlmICggYUxheW91dEluZm9ybWF0aW9uLmdldExlbmd0aCgpICkKICAgICAgICB7CgkJICAgIHRyeQoJCSAgICB7CgkJCQlsb2FkVmlld1NldHRpbmdzKCBhTGF5b3V0SW5mb3JtYXRpb24gKTsKCQkgICAgfQoJCSAgICBjYXRjaCggY29uc3QgRXhjZXB0aW9uJiApCgkJICAgIHsKICAgICAgICAgICAgICAgIERCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CgkJICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICggbV9zU3RhdGVtZW50LmdldExlbmd0aCgpICkKICAgICAgICB7CiAgICAgICAgICAgIHNldFF1ZXJ5Q29tcG9zZXIoKTsKCiAgICAgICAgICAgIGJvb2wgYkVycm9yKCBmYWxzZSApOwoKICAgICAgICAgICAgaWYgKCAhbV9wU3FsSXRlcmF0b3IgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBiRXJyb3IgPSB0cnVlOwogICAgICAgICAgICB9CgkJICAgIGVsc2UgaWYgKCBtX2JFc2NhcGVQcm9jZXNzaW5nICkKCQkgICAgewoJCQkgICAgOjpydGw6Ok9VU3RyaW5nIGFFcnJvck1zZzsKICAgICAgICAgICAgICAgIDo6c3RkOjphdXRvX3B0cjwgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgPiBwTm9kZSgKICAgICAgICAgICAgICAgICAgICBtX2FTcWxQYXJzZXIucGFyc2VUcmVlKCBhRXJyb3JNc2csIG1fc1N0YXRlbWVudCwgbV9iR3JhcGhpY2FsRGVzaWduICkgKTsKCiAgICAgICAgICAgICAgICBpZiAoIHBOb2RlLmdldCgpICkKCQkJICAgIHsKCQkJCSAgICBkZWxldGUgbV9wU3FsSXRlcmF0b3ItPmdldFBhcnNlVHJlZSgpOwoJCQkJICAgIG1fcFNxbEl0ZXJhdG9yLT5zZXRQYXJzZVRyZWUoIHBOb2RlLnJlbGVhc2UoKSApOwoJCQkJICAgIG1fcFNxbEl0ZXJhdG9yLT50cmF2ZXJzZUFsbCgpOwogICAgICAgICAgICAgICAgICAgIGlmICggbV9wU3FsSXRlcmF0b3ItPmhhc0Vycm9ycygpICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIWlfYkZvcmNlQ3VycmVudENvbnRyb2xsZXJTZXR0aW5ncyAmJiBtX2JHcmFwaGljYWxEZXNpZ24gJiYgIWVkaXRpbmdWaWV3KCkgKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXBsX3Nob3dBdXRvU1FMVmlld0Vycm9yKCBtYWtlQW55KCBtX3BTcWxJdGVyYXRvci0+Z2V0RXJyb3JzKCkgKSApOwogICAgICAgICAgICAgICAgICAgICAgICB9CgkJCQkJICAgIGJFcnJvciA9IHRydWU7CgkJCQkgICAgfQoJCQkgICAgfQoJCQkgICAgZWxzZQoJCQkgICAgewogICAgICAgICAgICAgICAgICAgIGlmICggIWlfYkZvcmNlQ3VycmVudENvbnRyb2xsZXJTZXR0aW5ncyAmJiAhZWRpdGluZ1ZpZXcoKSApCiAgICAgICAgICAgICAgICAgICAgewoJCQkJICAgICAgICBTdHJpbmcgYVRpdGxlKE1vZHVsZVJlcyhTVFJfU1ZUX1NRTF9TWU5UQVhfRVJST1IpKTsKCQkJCSAgICAgICAgT1NRTE1lc3NhZ2VCb3ggYURsZyhnZXRWaWV3KCksYVRpdGxlLGFFcnJvck1zZyk7CgkJCQkgICAgICAgIGFEbGcuRXhlY3V0ZSgpOwogICAgICAgICAgICAgICAgICAgIH0KCQkJCSAgICBiRXJyb3IgPSB0cnVlOwoJCQkgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIGJFcnJvciApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG1fYkdyYXBoaWNhbERlc2lnbiA9IHNhbF9GYWxzZTsKICAgICAgICAgICAgICAgIGlmICggZWRpdGluZ1ZpZXcoKSApCiAgICAgICAgICAgICAgICAgICAgLy8gaWYgd2UncmUgZWRpdGluZyBhIHZpZXcgd2hvc2Ugc3RhdGVtZW50IGNvdWxkIG5vdCBiZSBwYXJzZWQsIGRlZmF1bHQgdG8gIm5vIGVzY2FwZSBwcm9jZXNzaW5nIgogICAgICAgICAgICAgICAgICAgIHNldEVzY2FwZVByb2Nlc3NpbmdfZmlyZUV2ZW50KCBzYWxfRmFsc2UgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCX0KCglpZighbV9wU3FsSXRlcmF0b3IpCgkJc2V0UXVlcnlDb21wb3NlcigpOwoJT1NMX0VOU1VSRShtX3BTcWxJdGVyYXRvciwiTm8gU1FMSXRlcmF0b3Igc2V0ISIpOwoKCWdldENvbnRhaW5lcigpLT5zZXROb25lVmlzYmxlUm93KG1fblZpc2libGVSb3dzKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpyZXNldCgpCnsKCWltcGxfcmVzZXQoKTsKCWdldENvbnRhaW5lcigpLT5yZXNldCggTlVMTCApOwoJQ2xlYXJVbmRvTWFuYWdlcigpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OnNldFN0YXRlbWVudF9maXJlRXZlbnQoIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgX3JOZXdTdGF0ZW1lbnQsIGJvb2wgX2JGaXJlU3RhdGVtZW50Q2hhbmdlICkKewogICAgQW55IGFPbGRWYWx1ZSA9IG1ha2VBbnkoIG1fc1N0YXRlbWVudCApOwogICAgbV9zU3RhdGVtZW50ID0gX3JOZXdTdGF0ZW1lbnQ7CiAgICBBbnkgYU5ld1ZhbHVlID0gbWFrZUFueSggbV9zU3RhdGVtZW50ICk7CgogICAgc2FsX0ludDMyIG5IYW5kbGUgPSBQUk9QRVJUWV9JRF9BQ1RJVkVDT01NQU5EOwogICAgaWYgKCBfYkZpcmVTdGF0ZW1lbnRDaGFuZ2UgKQogICAgICAgIGZpcmUoICZuSGFuZGxlLCAmYU5ld1ZhbHVlLCAmYU9sZFZhbHVlLCAxLCBzYWxfRmFsc2UgKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpzZXRFc2NhcGVQcm9jZXNzaW5nX2ZpcmVFdmVudCggY29uc3Qgc2FsX0Jvb2wgX2JFc2NhcGVQcm9jZXNzaW5nICkKewogICAgaWYgKCBfYkVzY2FwZVByb2Nlc3NpbmcgPT0gbV9iRXNjYXBlUHJvY2Vzc2luZyApCiAgICAgICAgcmV0dXJuOwoKICAgIEFueSBhT2xkVmFsdWUgPSBtYWtlQW55KCBtX2JFc2NhcGVQcm9jZXNzaW5nICk7CiAgICBtX2JFc2NhcGVQcm9jZXNzaW5nID0gX2JFc2NhcGVQcm9jZXNzaW5nOwogICAgQW55IGFOZXdWYWx1ZSA9IG1ha2VBbnkoIG1fYkVzY2FwZVByb2Nlc3NpbmcgKTsKCiAgICBzYWxfSW50MzIgbkhhbmRsZSA9IFBST1BFUlRZX0lEX0VTQ0FQRV9QUk9DRVNTSU5HOwogICAgZmlyZSggJm5IYW5kbGUsICZhTmV3VmFsdWUsICZhT2xkVmFsdWUsIDEsIHNhbF9GYWxzZSApOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpJTVBMX0xJTksoIE9RdWVyeUNvbnRyb2xsZXIsIE9uRXhlY3V0ZUFkZFRhYmxlLCB2b2lkKiwgLypwTm90SW50ZXJlc3RlZEluKi8gKQp7CiAgICBFeGVjdXRlKCBJRF9CUk9XU0VSX0FERFRBQkxFLFNlcXVlbmNlPFByb3BlcnR5VmFsdWU+KCkgKTsKICAgIHJldHVybiAwTDsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYm9vbCBPUXVlcnlDb250cm9sbGVyOjphbGxvd1ZpZXdzKCkgY29uc3QKewogICAgcmV0dXJuIHRydWU7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgT1F1ZXJ5Q29udHJvbGxlcjo6YWxsb3dRdWVyaWVzKCkgY29uc3QKewogICAgREJHX0FTU0VSVCggZ2V0U2RiTWV0YURhdGEoKS5pc0Nvbm5lY3RlZCgpLCAiT1F1ZXJ5Q29udHJvbGxlcjo6YWxsb3dRdWVyaWVzOiBpbGxlZ2FsIGNhbGwhIiApOwogICAgaWYgKCAhZ2V0U2RiTWV0YURhdGEoKS5zdXBwb3J0c1N1YnF1ZXJpZXNJbkZyb20oKSApCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIGNvbnN0IE5hbWVkVmFsdWVDb2xsZWN0aW9uJiByQXJndW1lbnRzKCBnZXRJbml0UGFyYW1zKCkgKTsKICAgIHNhbF9JbnQzMiBuQ29tbWFuZFR5cGUgPSByQXJndW1lbnRzLmdldE9yRGVmYXVsdCggKDo6cnRsOjpPVVN0cmluZylQUk9QRVJUWV9DT01NQU5EX1RZUEUsIChzYWxfSW50MzIpQ29tbWFuZFR5cGU6OlFVRVJZICk7CiAgICBzYWxfQm9vbCBiQ3JlYXRpbmdWaWV3ID0gKCBuQ29tbWFuZFR5cGUgPT0gQ29tbWFuZFR5cGU6OlRBQkxFICk7CiAgICByZXR1cm4gIWJDcmVhdGluZ1ZpZXc7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkFueSBTQUxfQ0FMTCBPUXVlcnlDb250cm9sbGVyOjpnZXRWaWV3RGF0YSgpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBnZXRNdXRleCgpICk7CgogICAgZ2V0Q29udGFpbmVyKCktPlNhdmVVSUNvbmZpZygpOwoKICAgIDo6Y29tcGhlbHBlcjo6TmFtZWRWYWx1ZUNvbGxlY3Rpb24gYVZpZXdTZXR0aW5nczsKCXNhdmVWaWV3U2V0dGluZ3MoIGFWaWV3U2V0dGluZ3MsIGZhbHNlICk7CgoJcmV0dXJuIG1ha2VBbnkoIGFWaWV3U2V0dGluZ3MuZ2V0UHJvcGVydHlWYWx1ZXMoKSApOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgT1F1ZXJ5Q29udHJvbGxlcjo6cmVzdG9yZVZpZXdEYXRhKGNvbnN0IEFueSYgLypEYXRhKi8pIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgLy8gVE9ETwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp9IC8vIG5hbWVzcGFjZSBkYmF1aQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoK