LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQogKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovLyBNQVJLRVIodXBkYXRlX3ByZWNvbXAucHkpOiBhdXRvZ2VuIGluY2x1ZGUgc3RhdGVtZW50LCBkbyBub3QgcmVtb3ZlCiNpbmNsdWRlICJwcmVjb21waWxlZF9jb25uZWN0aXZpdHkuaHh4IgojaW5jbHVkZSAiY29ubmVjdGl2aXR5L3NxbGl0ZXJhdG9yLmh4eCIKI2luY2x1ZGUgImNvbm5lY3Rpdml0eS9zZGJjeC9WVGFibGUuaHh4IgojaW5jbHVkZSA8Y29ubmVjdGl2aXR5L3NxbHBhcnNlLmh4eD4KI2luY2x1ZGUgPGNvbm5lY3Rpdml0eS9kYnRvb2xzLmh4eD4KI2luY2x1ZGUgPGNvbm5lY3Rpdml0eS9zcWxlcnJvci5oeHg+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiYy9Db2x1bW5WYWx1ZS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiYy9EYXRhVHlwZS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiYy9YUm93LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGIvWFF1ZXJpZXNTdXBwbGllci5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiL0Vycm9yQ29uZGl0aW9uLmhwcD4KI2lmZGVmIFNRTF9URVNUX1BBUlNFVFJFRUlURVJBVE9SCiNpbmNsdWRlIDxpb3N0cmVhbT4KI2VuZGlmCiNpbmNsdWRlICJjb25uZWN0aXZpdHkvUENvbHVtbi5oeHgiCiNpbmNsdWRlICJjb25uZWN0aXZpdHkvZGJ0b29scy5oeHgiCiNpbmNsdWRlIDx0b29scy9kaWFnbm9zZV9leC5oPgojaW5jbHVkZSAiVENvbm5lY3Rpb24uaHh4IgojaW5jbHVkZSA8Y29tcGhlbHBlci90eXBlcy5oeHg+CiNpbmNsdWRlIDxjb25uZWN0aXZpdHkvZGJtZXRhZGF0YS5oeHg+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiL1NRTEZpbHRlck9wZXJhdG9yLmhwcD4KI2luY2x1ZGUgImRpYWdub3NlX2V4LmgiCiNpbmNsdWRlIDxydGwvbG9nZmlsZS5oeHg+CgojZGVmaW5lIFNRTF9JU1JVTEVPUjIocFBhcnNlTm9kZSwgZTEsZTIpIAkoKHBQYXJzZU5vZGUpLT5pc1J1bGUoKSAmJiAoXAoJCQkJCQkJCQkJCShwUGFyc2VOb2RlKS0+Z2V0UnVsZUlEKCkgPT0gT1NRTFBhcnNlcjo6UnVsZUlEKE9TUUxQYXJzZU5vZGU6OmUxKSB8fCBcCgkJCQkJCQkJCQkJKHBQYXJzZU5vZGUpLT5nZXRSdWxlSUQoKSA9PSBPU1FMUGFyc2VyOjpSdWxlSUQoT1NRTFBhcnNlTm9kZTo6ZTIpKSkKCnVzaW5nIG5hbWVzcGFjZSA6OmNvbXBoZWxwZXI7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbm5lY3Rpdml0eTsKdXNpbmcgbmFtZXNwYWNlIDo6Y29ubmVjdGl2aXR5OjpzZGJjeDsKdXNpbmcgbmFtZXNwYWNlIDo6ZGJ0b29sczsKdXNpbmcgbmFtZXNwYWNlIDo6Y29ubmVjdGl2aXR5OjpwYXJzZTsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjp1bm87CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpjb250YWluZXI7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpzZGJjeDsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OmJlYW5zOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6c2RiYzsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnNkYjsKCm5hbWVzcGFjZSBjb25uZWN0aXZpdHkKewoJc3RydWN0IE9TUUxQYXJzZVRyZWVJdGVyYXRvckltcGwKCXsKICAgICAgICA6OnN0ZDo6dmVjdG9yPCBUTm9kZVBhaXIgPiAgICAgIG1fYUpvaW5Db25kaXRpb25zOwoJCVJlZmVyZW5jZTwgWENvbm5lY3Rpb24gPiAgICAgICAgbV94Q29ubmVjdGlvbjsKCQlSZWZlcmVuY2U8IFhEYXRhYmFzZU1ldGFEYXRhID4gIG1feERhdGFiYXNlTWV0YURhdGE7CgkJUmVmZXJlbmNlPCBYTmFtZUFjY2VzcyA+ICAgICAgICBtX3hUYWJsZUNvbnRhaW5lcjsKICAgICAgICBSZWZlcmVuY2U8IFhOYW1lQWNjZXNzID4gICAgICAgIG1feFF1ZXJ5Q29udGFpbmVyOwoKICAgICAgICA6OmJvb3N0OjpzaGFyZWRfcHRyPCBPU1FMVGFibGVzID4gICBtX3BUYWJsZXM7ICAgICAgLy8vIGFsbCB0YWJsZXMgd2hpY2ggcGFydGljaXBhdGUgaW4gdGhlIFNRTCBzdGF0ZW1lbnQKICAgICAgICA6OmJvb3N0OjpzaGFyZWRfcHRyPCBPU1FMVGFibGVzID4gICBtX3BTdWJUYWJsZXM7ICAgLy8vIGFsbCB0YWJsZXMgZnJvbSBzdWIgcXVlcmllcyBub3QgdGhlIHRhYmxlcyBmcm9tIHRoZSBzZWxlY3QgdGFibGVzCiAgICAgICAgOjpib29zdDo6c2hhcmVkX3B0cjwgUXVlcnlOYW1lU2V0ID4gbV9wRm9yYmlkZGVuUXVlcnlOYW1lczsKCiAgICAgICAgc2FsX3VJbnQzMiAgICAgICAgICAgICAgICAgICAgICBtX25JbmNsdWRlTWFzazsKCiAgICAgICAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2JJc0Nhc2VTZW5zaXRpdmU7CgogICAgICAgIE9TUUxQYXJzZVRyZWVJdGVyYXRvckltcGwoIGNvbnN0IFJlZmVyZW5jZTwgWENvbm5lY3Rpb24gPiYgX3J4Q29ubmVjdGlvbiwgY29uc3QgUmVmZXJlbmNlPCBYTmFtZUFjY2VzcyA+JiBfcnhUYWJsZXMgKQogICAgICAgICAgICA6bV94Q29ubmVjdGlvbiggX3J4Q29ubmVjdGlvbiApCiAgICAgICAgICAgICxtX25JbmNsdWRlTWFzayggT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpBbGwgKQogICAgICAgICAgICAsbV9iSXNDYXNlU2Vuc2l0aXZlKCB0cnVlICkKCQl7CiAgICAgICAgICAgIE9TTF9QUkVDT05EKCBtX3hDb25uZWN0aW9uLmlzKCksICJPU1FMUGFyc2VUcmVlSXRlcmF0b3JJbXBsOjpPU1FMUGFyc2VUcmVlSXRlcmF0b3JJbXBsOiBpbnZhbGlkIGNvbm5lY3Rpb24hIiApOwogICAgICAgICAgICBtX3hEYXRhYmFzZU1ldGFEYXRhID0gbV94Q29ubmVjdGlvbi0+Z2V0TWV0YURhdGEoKTsKCiAgICAgICAgICAgIG1fYklzQ2FzZVNlbnNpdGl2ZSA9IG1feERhdGFiYXNlTWV0YURhdGEuaXMoKSAmJiBtX3hEYXRhYmFzZU1ldGFEYXRhLT5zdXBwb3J0c01peGVkQ2FzZVF1b3RlZElkZW50aWZpZXJzKCk7CiAgICAgICAgICAgIG1fcFRhYmxlcy5yZXNldCggbmV3IE9TUUxUYWJsZXMoIG1fYklzQ2FzZVNlbnNpdGl2ZSApICk7CiAgICAgICAgICAgIG1fcFN1YlRhYmxlcy5yZXNldCggbmV3IE9TUUxUYWJsZXMoIG1fYklzQ2FzZVNlbnNpdGl2ZSApICk7CgogICAgICAgICAgICBtX3hUYWJsZUNvbnRhaW5lciA9IF9yeFRhYmxlczsKCiAgICAgICAgICAgIERhdGFiYXNlTWV0YURhdGEgYU1ldGFEYXRhKCBtX3hDb25uZWN0aW9uICk7CiAgICAgICAgICAgIGlmICggYU1ldGFEYXRhLnN1cHBvcnRzU3VicXVlcmllc0luRnJvbSgpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gY29ubmVjdGlvbnMgbWlnaHQgc3VwcG9ydCB0aGUgWFF1ZXJpZXNTdXBwbGllciBpbnRlcmZhY2UsIGlmIHRoZXkgaW1wbGVtZW50IHRoZSBjc3Muc2RiLkNvbm5lY3Rpb24KICAgICAgICAgICAgICAgIC8vIHNlcnZpY2UKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFF1ZXJpZXNTdXBwbGllciA+IHhTdXBwUXVlcmllcyggbV94Q29ubmVjdGlvbiwgVU5PX1FVRVJZICk7CiAgICAgICAgICAgICAgICBpZiAoIHhTdXBwUXVlcmllcy5pcygpICkKICAgICAgICAgICAgICAgICAgICBtX3hRdWVyeUNvbnRhaW5lciA9IHhTdXBwUXVlcmllcy0+Z2V0UXVlcmllcygpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIHB1YmxpYzoKICAgICAgICBpbmxpbmUgIGJvb2wgICAgaXNRdWVyeUFsbG93ZWQoIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgX3JRdWVyeU5hbWUgKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCAhbV9wRm9yYmlkZGVuUXVlcnlOYW1lcy5nZXQoKSApCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgaWYgKCBtX3BGb3JiaWRkZW5RdWVyeU5hbWVzLT5maW5kKCBfclF1ZXJ5TmFtZSApID09IG1fcEZvcmJpZGRlblF1ZXJ5TmFtZXMtPmVuZCgpICkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoJfTsKCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8qKiBoZWxwZXIgY2xhc3MgZm9yIHRlbXBvcmFyaWx5IGFkZGluZyBhIHF1ZXJ5IG5hbWUgdG8gYSBsaXN0IG9mIGZvcmJpZGRlbiBxdWVyeSBuYW1lcwogICAgKi8KICAgIGNsYXNzIEZvcmJpZFF1ZXJ5TmFtZQogICAgewogICAgICAgIDo6Ym9vc3Q6OnNoYXJlZF9wdHI8IFF1ZXJ5TmFtZVNldCA+JiAgICBtX3JwQWxsRm9yYmlkZGVuTmFtZXM7CiAgICAgICAgOjpydGw6Ok9VU3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAgIG1fc0ZvcmJpZGRlblF1ZXJ5TmFtZTsKCiAgICBwdWJsaWM6CiAgICAgICAgRm9yYmlkUXVlcnlOYW1lKCBPU1FMUGFyc2VUcmVlSXRlcmF0b3JJbXBsJiBfckl0ZXJhdG9ySW1wbCwgY29uc3QgOjpydGw6Ok9VU3RyaW5nIF9yRm9yYmlkZGVuUXVlcnlOYW1lICkKICAgICAgICAgICAgOm1fcnBBbGxGb3JiaWRkZW5OYW1lcyggX3JJdGVyYXRvckltcGwubV9wRm9yYmlkZGVuUXVlcnlOYW1lcyApCiAgICAgICAgICAgICxtX3NGb3JiaWRkZW5RdWVyeU5hbWUoIF9yRm9yYmlkZGVuUXVlcnlOYW1lICkKICAgICAgICB7CiAgICAgICAgICAgIGlmICggIW1fcnBBbGxGb3JiaWRkZW5OYW1lcy5nZXQoKSApCiAgICAgICAgICAgICAgICBtX3JwQWxsRm9yYmlkZGVuTmFtZXMucmVzZXQoIG5ldyBRdWVyeU5hbWVTZXQgKTsKICAgICAgICAgICAgbV9ycEFsbEZvcmJpZGRlbk5hbWVzLT5pbnNlcnQoIG1fc0ZvcmJpZGRlblF1ZXJ5TmFtZSApOwogICAgICAgIH0KCiAgICAgICAgfkZvcmJpZFF1ZXJ5TmFtZSgpCiAgICAgICAgewogICAgICAgICAgICBtX3JwQWxsRm9yYmlkZGVuTmFtZXMtPmVyYXNlKCBtX3NGb3JiaWRkZW5RdWVyeU5hbWUgKTsKICAgICAgICB9CiAgICB9Owp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpPU1FMUGFyc2VUcmVlSXRlcmF0b3IoY29uc3QgUmVmZXJlbmNlPCBYQ29ubmVjdGlvbiA+JiBfcnhDb25uZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZWZlcmVuY2U8IFhOYW1lQWNjZXNzID4mIF9yeFRhYmxlcywKCQkJCQkJCQkJCQkgY29uc3QgT1NRTFBhcnNlciYgX3JQYXJzZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBSb290ICkKICAgIDptX3JQYXJzZXIoIF9yUGFyc2VyICkKICAgICxtX3BJbXBsKCBuZXcgT1NRTFBhcnNlVHJlZUl0ZXJhdG9ySW1wbCggX3J4Q29ubmVjdGlvbiwgX3J4VGFibGVzICkgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6T1NRTFBhcnNlVHJlZUl0ZXJhdG9yIiApOwoJc2V0UGFyc2VUcmVlKHBSb290KTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpPU1FMUGFyc2VUcmVlSXRlcmF0b3I6Ok9TUUxQYXJzZVRyZWVJdGVyYXRvciggY29uc3QgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yJiBfclBhcmVudEl0ZXJhdG9yLCBjb25zdCBPU1FMUGFyc2VyJiBfclBhcnNlciwgY29uc3QgT1NRTFBhcnNlTm9kZSogcFJvb3QgKQoJOm1fclBhcnNlciggX3JQYXJzZXIgKQogICAgLG1fcEltcGwoIG5ldyBPU1FMUGFyc2VUcmVlSXRlcmF0b3JJbXBsKCBfclBhcmVudEl0ZXJhdG9yLm1fcEltcGwtPm1feENvbm5lY3Rpb24sIF9yUGFyZW50SXRlcmF0b3IubV9wSW1wbC0+bV94VGFibGVDb250YWluZXIgKSApCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpPU1FMUGFyc2VUcmVlSXRlcmF0b3IiICk7CiAgICBtX3BJbXBsLT5tX3BGb3JiaWRkZW5RdWVyeU5hbWVzID0gX3JQYXJlbnRJdGVyYXRvci5tX3BJbXBsLT5tX3BGb3JiaWRkZW5RdWVyeU5hbWVzOwoJc2V0UGFyc2VUcmVlKCBwUm9vdCApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6fk9TUUxQYXJzZVRyZWVJdGVyYXRvcigpCnsKCWRpc3Bvc2UoKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY29uc3QgT1NRTFRhYmxlcyYgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRUYWJsZXMoKSBjb25zdAp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0VGFibGVzIiApOwogICAgcmV0dXJuICptX3BJbXBsLT5tX3BUYWJsZXM7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppc0Nhc2VTZW5zaXRpdmUoKSBjb25zdAp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6aXNDYXNlU2Vuc2l0aXZlIiApOwogICAgcmV0dXJuIG1fcEltcGwtPm1fYklzQ2FzZVNlbnNpdGl2ZTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmRpc3Bvc2UoKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6ZGlzcG9zZSIgKTsKCW1fYVNlbGVjdENvbHVtbnMJPSBOVUxMOwoJbV9hR3JvdXBDb2x1bW5zCQk9IE5VTEw7CgltX2FPcmRlckNvbHVtbnMJCT0gTlVMTDsKCW1fYVBhcmFtZXRlcnMJCT0gTlVMTDsKCW1fcEltcGwtPm1feFRhYmxlQ29udGFpbmVyCT0gTlVMTDsKCW1fcEltcGwtPm1feERhdGFiYXNlTWV0YURhdGEgPSBOVUxMOwoJbV9hQ3JlYXRlQ29sdW1ucwk9IE5VTEw7CgltX3BJbXBsLT5tX3BUYWJsZXMtPmNsZWFyKCk7CgltX3BJbXBsLT5tX3BTdWJUYWJsZXMtPmNsZWFyKCk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6c2V0UGFyc2VUcmVlKGNvbnN0IE9TUUxQYXJzZU5vZGUgKiBwTmV3UGFyc2VUcmVlKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6c2V0UGFyc2VUcmVlIiApOwoJbV9wSW1wbC0+bV9wVGFibGVzLT5jbGVhcigpOwoJbV9wSW1wbC0+bV9wU3ViVGFibGVzLT5jbGVhcigpOwoKCW1fYVNlbGVjdENvbHVtbnMgPSBuZXcgT1NRTENvbHVtbnMoKTsKCW1fYUdyb3VwQ29sdW1ucyA9IG5ldyBPU1FMQ29sdW1ucygpOwoJbV9hT3JkZXJDb2x1bW5zID0gbmV3IE9TUUxDb2x1bW5zKCk7CgltX2FQYXJhbWV0ZXJzCSA9IG5ldyBPU1FMQ29sdW1ucygpOwoJbV9hQ3JlYXRlQ29sdW1ucyA9IG5ldyBPU1FMQ29sdW1ucygpOwoKCW1fcFBhcnNlVHJlZSA9IHBOZXdQYXJzZVRyZWU7CglpZiAoIW1fcFBhcnNlVHJlZSkKCXsKCQltX2VTdGF0ZW1lbnRUeXBlID0gU1FMX1NUQVRFTUVOVF9VTktOT1dOOwoJCXJldHVybjsKCX0KCgkvLyBmYWxscyBtX3BQYXJzZVRyZWUgYWJlciBrZWluZSBDb25uZWN0aW9uLCBkYW5uIEZlaGxlcgoJaWYgKCAhbV9wSW1wbC0+bV94VGFibGVDb250YWluZXIuaXMoKSApCgkJcmV0dXJuOwoKCW1fYUVycm9ycyA9IFNRTEV4Y2VwdGlvbigpOwoKCgkvLyBTdGF0ZW1lbnQtVHlwIGVybWl0dGVsbiAuLi4KCWlmIChTUUxfSVNSVUxFKG1fcFBhcnNlVHJlZSxzZWxlY3Rfc3RhdGVtZW50KSB8fCBTUUxfSVNSVUxFKG1fcFBhcnNlVHJlZSx1bmlvbl9zdGF0ZW1lbnQpICkKCXsKCQltX2VTdGF0ZW1lbnRUeXBlID0gU1FMX1NUQVRFTUVOVF9TRUxFQ1Q7Cgl9CgllbHNlIGlmIChTUUxfSVNSVUxFKG1fcFBhcnNlVHJlZSxpbnNlcnRfc3RhdGVtZW50KSkKCXsKCQltX2VTdGF0ZW1lbnRUeXBlID0gU1FMX1NUQVRFTUVOVF9JTlNFUlQ7Cgl9CgllbHNlIGlmIChTUUxfSVNSVUxFKG1fcFBhcnNlVHJlZSx1cGRhdGVfc3RhdGVtZW50X3NlYXJjaGVkKSkKCXsKCQltX2VTdGF0ZW1lbnRUeXBlID0gU1FMX1NUQVRFTUVOVF9VUERBVEU7Cgl9CgllbHNlIGlmIChTUUxfSVNSVUxFKG1fcFBhcnNlVHJlZSxkZWxldGVfc3RhdGVtZW50X3NlYXJjaGVkKSkKCXsKCQltX2VTdGF0ZW1lbnRUeXBlID0gU1FMX1NUQVRFTUVOVF9ERUxFVEU7Cgl9CgllbHNlIGlmIChtX3BQYXJzZVRyZWUtPmNvdW50KCkgPT0gMyAmJiBTUUxfSVNSVUxFKG1fcFBhcnNlVHJlZS0+Z2V0Q2hpbGQoMSksb2RiY19jYWxsX3NwZWMpKQoJewoJCW1fZVN0YXRlbWVudFR5cGUgPSBTUUxfU1RBVEVNRU5UX09EQkNfQ0FMTDsKCX0KCWVsc2UgaWYgKFNRTF9JU1JVTEUobV9wUGFyc2VUcmVlLT5nZXRDaGlsZCgwKSxiYXNlX3RhYmxlX2RlZikpCgl7CiAgICAgICAgbV9lU3RhdGVtZW50VHlwZSA9IFNRTF9TVEFURU1FTlRfQ1JFQVRFX1RBQkxFOwoJCW1fcFBhcnNlVHJlZSA9IG1fcFBhcnNlVHJlZS0+Z2V0Q2hpbGQoMCk7Cgl9CgllbHNlCgl7CgkJbV9lU3RhdGVtZW50VHlwZSA9IFNRTF9TVEFURU1FTlRfVU5LTk9XTjsKCQkvL2FJdGVyYXRvclN0YXR1cy5zZXRJbnZhbGlkU3RhdGVtZW50KCk7CgkJcmV0dXJuOwoJfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCm5hbWVzcGFjZQp7CiAgICAvLy4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4KICAgIHN0YXRpYyB2b2lkIGltcGxfZ2V0Um93U3RyaW5nKCBjb25zdCBSZWZlcmVuY2U8IFhSb3cgPiYgX3J4Um93LCBjb25zdCBzYWxfSW50MzIgX25Db2x1bW5JbmRleCwgOjpydGw6Ok9VU3RyaW5nJiBfb3V0X3JTdHJpbmcgKQogICAgewoJCV9vdXRfclN0cmluZyA9IF9yeFJvdy0+Z2V0U3RyaW5nKCBfbkNvbHVtbkluZGV4ICk7CgkJaWYgKCBfcnhSb3ctPndhc051bGwoKSApCgkJCV9vdXRfclN0cmluZz0gOjpydGw6Ok9VU3RyaW5nKCk7CiAgICB9CgogICAgLy8uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uCiAgICBzdGF0aWMgOjpydGw6Ok9VU3RyaW5nIGxjbF9maW5kVGFibGVJbk1ldGFEYXRhKAogICAgICAgIGNvbnN0IFJlZmVyZW5jZTwgWERhdGFiYXNlTWV0YURhdGEgPiYgX3J4REJNZXRhLCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIF9yQ2F0YWxvZywKICAgICAgICBjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIF9yU2NoZW1hLCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIF9yVGFibGVOYW1lICkKICAgIHsKICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc0NvbXBvc2VkTmFtZTsKCgkJc3RhdGljIGNvbnN0IDo6cnRsOjpPVVN0cmluZyBzX3NUYWJsZVR5cGVWaWV3KFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiVklFVyIpKTsKCQlzdGF0aWMgY29uc3QgOjpydGw6Ok9VU3RyaW5nIHNfc1RhYmxlVHlwZVRhYmxlKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiVEFCTEUiKSk7CgkJc3RhdGljIGNvbnN0IDo6cnRsOjpPVVN0cmluZyBzX3NXaWxkY2FyZCA9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIlIik7CgoJCS8vIHdlIHdhbnQgYWxsIGNhdGFsb2d1ZXMsIGFsbCBzY2hlbWFzLCBhbGwgdGFibGVzCgkJU2VxdWVuY2U8IDo6cnRsOjpPVVN0cmluZyA+IHNUYWJsZVR5cGVzKDMpOwoJCXNUYWJsZVR5cGVzWzBdID0gc19zVGFibGVUeXBlVmlldzsKCQlzVGFibGVUeXBlc1sxXSA9IHNfc1RhYmxlVHlwZVRhYmxlOwoJCXNUYWJsZVR5cGVzWzJdID0gc19zV2lsZGNhcmQ7CS8vIGp1c3QgdG8gYmUgc3VyZSB0byBpbmNsdWRlIGFueXRoaW5nIGVsc2UgLi4uLgoKCQlpZiAoIF9yeERCTWV0YS5pcygpICkKCQl7CgkJCXNDb21wb3NlZE5hbWUgPSA6OnJ0bDo6T1VTdHJpbmcoKTsKCiAgICAgICAgICAgIFJlZmVyZW5jZTwgWFJlc3VsdFNldD4geFJlcyA9IF9yeERCTWV0YS0+Z2V0VGFibGVzKAogICAgICAgICAgICAgICAgX3JDYXRhbG9nLmdldExlbmd0aCgpID8gbWFrZUFueSggX3JDYXRhbG9nICkgOiBBbnkoKSwgX3JTY2hlbWEuZ2V0TGVuZ3RoKCkgPyBfclNjaGVtYSA6IHNfc1dpbGRjYXJkLCBfclRhYmxlTmFtZSwgc1RhYmxlVHlwZXMgKTsKCgkJCVJlZmVyZW5jZTwgWFJvdyA+IHhDdXJyZW50Um93KCB4UmVzLCBVTk9fUVVFUlkgKTsKICAgICAgICAgICAgaWYgKCB4Q3VycmVudFJvdy5pcygpICYmIHhSZXMtPm5leHQoKSApCgkJCXsKCQkJCTo6cnRsOjpPVVN0cmluZyBzQ2F0YWxvZywgc1NjaGVtYSwgc05hbWU7CgogICAgICAgICAgICAgICAgaW1wbF9nZXRSb3dTdHJpbmcoIHhDdXJyZW50Um93LCAxLCBzQ2F0YWxvZyApOwogICAgICAgICAgICAgICAgaW1wbF9nZXRSb3dTdHJpbmcoIHhDdXJyZW50Um93LCAyLCBzU2NoZW1hICk7CiAgICAgICAgICAgICAgICBpbXBsX2dldFJvd1N0cmluZyggeEN1cnJlbnRSb3csIDMsIHNOYW1lICk7CgoJCQkJc0NvbXBvc2VkTmFtZSA9IDo6ZGJ0b29sczo6Y29tcG9zZVRhYmxlTmFtZSgKICAgICAgICAgICAgICAgICAgICBfcnhEQk1ldGEsCiAgICAgICAgICAgICAgICAgICAgc0NhdGFsb2csCgkJCQkJc1NjaGVtYSwKCQkJCQlzTmFtZSwKCQkJCQlzYWxfRmFsc2UsCgkJCQkJOjpkYnRvb2xzOjplSW5EYXRhTWFuaXB1bGF0aW9uCiAgICAgICAgICAgICAgICApOwoJCQl9CgkJfQogICAgICAgIHJldHVybiBzQ29tcG9zZWROYW1lOwogICAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppbXBsX2dldFF1ZXJ5UGFyYW1ldGVyQ29sdW1ucyggY29uc3QgT1NRTFRhYmxlJiBfclF1ZXJ5ICApCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppbXBsX2dldFF1ZXJ5UGFyYW1ldGVyQ29sdW1ucyIgKTsKICAgIGlmICggKCBtX3BJbXBsLT5tX25JbmNsdWRlTWFzayAmIFBhcmFtZXRlcnMgKSAhPSBQYXJhbWV0ZXJzICkKICAgICAgICAvLyBwYXJhbWV0ZXJzIG5vdCB0byBiZSBpbmNsdWRlZCBpbiB0aGUgdHJhdmVyc2FsCiAgICAgICAgcmV0dXJuOwoKICAgIDo6dm9zOjpPUmVmPCBPU1FMQ29sdW1ucyA+IHBTdWJRdWVyeVBhcmFtZXRlckNvbHVtbnMoIG5ldyBPU1FMQ29sdW1ucygpICk7CgogICAgLy8gZ2V0IHRoZSBjb21tYW5kIGFuZCB0aGUgRXNjYXBlUHJvY2Vzc2luZyBwcm9wZXJ0aWVzIGZyb20gdGhlIHN1YiBxdWVyeQogICAgOjpydGw6Ok9VU3RyaW5nIHNTdWJRdWVyeUNvbW1hbmQ7CiAgICBzYWxfQm9vbCBiRXNjYXBlUHJvY2Vzc2luZyA9IHNhbF9GYWxzZTsKICAgIHRyeQogICAgewogICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geFF1ZXJ5UHJvcGVydGllcyggX3JRdWVyeSwgVU5PX1FVRVJZX1RIUk9XICk7CiAgICAgICAgT1NMX1ZFUklGWSggeFF1ZXJ5UHJvcGVydGllcy0+Z2V0UHJvcGVydHlWYWx1ZSggT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoIFBST1BFUlRZX0lEX0NPTU1BTkQgKSApID4+PSBzU3ViUXVlcnlDb21tYW5kICk7CiAgICAgICAgT1NMX1ZFUklGWSggeFF1ZXJ5UHJvcGVydGllcy0+Z2V0UHJvcGVydHlWYWx1ZSggT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoIFBST1BFUlRZX0lEX0VTQ0FQRVBST0NFU1NJTkcgKSApID4+PSBiRXNjYXBlUHJvY2Vzc2luZyApOwogICAgfQogICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgKQogICAgewogICAgICAgIERCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CiAgICB9CgogICAgLy8gcGFyc2UgdGhlIHN1YiBxdWVyeQogICAgZG8gewoKICAgIGlmICggIWJFc2NhcGVQcm9jZXNzaW5nIHx8ICggc1N1YlF1ZXJ5Q29tbWFuZC5nZXRMZW5ndGgoKSA9PSAwICkgKQogICAgICAgIGJyZWFrOwoKICAgIDo6cnRsOjpPVVN0cmluZyBzRXJyb3I7CiAgICA6OnN0ZDo6YXV0b19wdHI8IE9TUUxQYXJzZU5vZGUgPiBwU3ViUXVlcnlOb2RlKCBjb25zdF9jYXN0PCBPU1FMUGFyc2VyJiA+KCBtX3JQYXJzZXIgKS5wYXJzZVRyZWUoIHNFcnJvciwgc1N1YlF1ZXJ5Q29tbWFuZCwgc2FsX0ZhbHNlICkgKTsKICAgIGlmICggIXBTdWJRdWVyeU5vZGUuZ2V0KCkgKQogICAgICAgIGJyZWFrOwoKICAgIE9TUUxQYXJzZVRyZWVJdGVyYXRvciBhU3ViUXVlcnlJdGVyYXRvciggKnRoaXMsIG1fclBhcnNlciwgcFN1YlF1ZXJ5Tm9kZS5nZXQoKSApOwogICAgYVN1YlF1ZXJ5SXRlcmF0b3IudHJhdmVyc2VTb21lKCBQYXJhbWV0ZXJzIHwgU2VsZWN0Q29sdW1ucyApOwogICAgICAgIC8vIFNlbGVjdENvbHVtbnMgbWlnaHQgYWxzbyBjb250YWluIHBhcmFtZXRlcnMKICAgICAgICAvLyAjaTc3NjM1IyAtIDIwMDctMDctMjMgLyBmcmFuay5zY2hvZW5oZWl0QHN1bi5jb20KICAgIHBTdWJRdWVyeVBhcmFtZXRlckNvbHVtbnMgPSBhU3ViUXVlcnlJdGVyYXRvci5nZXRQYXJhbWV0ZXJzKCk7CiAgICBhU3ViUXVlcnlJdGVyYXRvci5kaXNwb3NlKCk7CgogICAgfSB3aGlsZSAoIGZhbHNlICk7CgogICAgLy8gY29weSB0aGUgcGFyYW1ldGVycyBvZiB0aGUgc3ViIHF1ZXJ5IHRvIG91ciBvd24gcGFyYW1ldGVyIGFycmF5CiAgICA6OnN0ZDo6Y29weSggcFN1YlF1ZXJ5UGFyYW1ldGVyQ29sdW1ucy0+Z2V0KCkuYmVnaW4oKSwgcFN1YlF1ZXJ5UGFyYW1ldGVyQ29sdW1ucy0+Z2V0KCkuZW5kKCksCiAgICAgICAgOjpzdGQ6Omluc2VydF9pdGVyYXRvcjwgT1NRTENvbHVtbnM6OlZlY3RvciA+KCBtX2FQYXJhbWV0ZXJzLT5nZXQoKSwgbV9hUGFyYW1ldGVycy0+Z2V0KCkuZW5kKCkgKSApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk9TUUxUYWJsZSBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfbG9jYXRlUmVjb3JkU291cmNlKCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIF9yQ29tcG9zZWROYW1lICkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfbG9jYXRlUmVjb3JkU291cmNlIiApOwogICAgaWYgKCAhX3JDb21wb3NlZE5hbWUuZ2V0TGVuZ3RoKCkgKQogICAgewogICAgICAgIE9TTF9FTlNVUkUoIGZhbHNlLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppbXBsX2xvY2F0ZVJlY29yZFNvdXJjZTogbm8gb2JqZWN0IG5hbWUgYXQgYWxsPyIgKTsKICAgICAgICByZXR1cm4gT1NRTFRhYmxlKCk7CiAgICB9CgogICAgT1NRTFRhYmxlIGFSZXR1cm47CiAgICA6OnJ0bDo6T1VTdHJpbmcgc0NvbXBvc2VkTmFtZSggX3JDb21wb3NlZE5hbWUgKTsKCgl0cnkKCXsKICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc0NhdGFsb2csIHNTY2hlbWEsIHNOYW1lOwogICAgICAgIHF1YWxpZmllZE5hbWVDb21wb25lbnRzKCBtX3BJbXBsLT5tX3hEYXRhYmFzZU1ldGFEYXRhLCBzQ29tcG9zZWROYW1lLCBzQ2F0YWxvZywgc1NjaGVtYSwgc05hbWUsIDo6ZGJ0b29sczo6ZUluRGF0YU1hbmlwdWxhdGlvbiApOwoKICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZXJlIGlzIGEgcXVlcnkgd2l0aCB0aGUgZ2l2ZW4gbmFtZQogICAgICAgIGJvb2wgYlF1ZXJ5RG9lc0V4aXN0ID0gbV9wSW1wbC0+bV94UXVlcnlDb250YWluZXIuaXMoKSAmJiBtX3BJbXBsLT5tX3hRdWVyeUNvbnRhaW5lci0+aGFzQnlOYW1lKCBzQ29tcG9zZWROYW1lICk7CgogICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIHRhYmxlIGNvbnRhaW5lciBjb250YWlucyBhbiBvYmplY3Qgd2l0aCB0aGUgZ2l2ZW4gbmFtZQoJCWlmICggIWJRdWVyeURvZXNFeGlzdCAmJiAhbV9wSW1wbC0+bV94VGFibGVDb250YWluZXItPmhhc0J5TmFtZSggc0NvbXBvc2VkTmFtZSApICkKICAgICAgICAgICAgc0NvbXBvc2VkTmFtZSA9IGxjbF9maW5kVGFibGVJbk1ldGFEYXRhKCBtX3BJbXBsLT5tX3hEYXRhYmFzZU1ldGFEYXRhLCBzQ2F0YWxvZywgc1NjaGVtYSwgc05hbWUgKTsKICAgICAgICBib29sIGJUYWJsZURvZXNFeGlzdCA9IG1fcEltcGwtPm1feFRhYmxlQ29udGFpbmVyLT5oYXNCeU5hbWUoIHNDb21wb3NlZE5hbWUgKTsKCiAgICAgICAgLy8gbm93IG9idGFpbiB0aGUgb2JqZWN0CgogICAgICAgIC8vIGlmIHdlJ3JlIGNyZWF0aW5nIGEgdGFibGUsIGFuZCB0aGVyZSBhbHJlYWR5IGlzIGEgdGFibGUgb3IgcXVlcnkgd2l0aCB0aGUgc2FtZSBuYW1lLAogICAgICAgIC8vIHRoaXMgaXMgd29ydGggYW4gZXJyb3IKICAgICAgICBpZiAoIFNRTF9TVEFURU1FTlRfQ1JFQVRFX1RBQkxFID09IG1fZVN0YXRlbWVudFR5cGUgKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCBiUXVlcnlEb2VzRXhpc3QgKQogICAgICAgICAgICAgICAgaW1wbF9hcHBlbmRFcnJvciggSVBhcnNlQ29udGV4dDo6RVJST1JfSU5WQUxJRF9RVUVSWV9FWElTVCwgJnNOYW1lICk7CiAgICAgICAgICAgIGVsc2UgaWYgKCBiVGFibGVEb2VzRXhpc3QgKQogICAgICAgICAgICAgICAgaW1wbF9hcHBlbmRFcnJvciggSVBhcnNlQ29udGV4dDo6RVJST1JfSU5WQUxJRF9UQUJMRV9FWElTVCwgJnNOYW1lICk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGFSZXR1cm4gPSBpbXBsX2NyZWF0ZVRhYmxlT2JqZWN0KCBzTmFtZSwgc0NhdGFsb2csIHNTY2hlbWEgKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLy8gcXVlcmllcyB3aW4gb3ZlciB0YWJsZXMsIHNvIGlmIHRoZXJlJ3MgYSBxdWVyeSB3aXRoIHRoaXMgbmFtZSwgdGFrZSB0aGlzLCBubyBtYXR0ZXIgaWYKICAgICAgICAgICAgLy8gdGhlcmUncyBhIHRhYmxlLCB0b28KICAgICAgICAgICAgaWYgKCBiUXVlcnlEb2VzRXhpc3QgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAgKCAhbV9wSW1wbC0+aXNRdWVyeUFsbG93ZWQoIHNDb21wb3NlZE5hbWUgKSApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaW1wbF9hcHBlbmRFcnJvciggbV9yUGFyc2VyLmdldEVycm9ySGVscGVyKCkuZ2V0U1FMRXhjZXB0aW9uKCBzZGI6OkVycm9yQ29uZGl0aW9uOjpQQVJTRVJfQ1lDTElDX1NVQl9RVUVSSUVTLCBOVUxMICkgKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBtX3BJbXBsLT5tX3hRdWVyeUNvbnRhaW5lci0+Z2V0QnlOYW1lKCBzQ29tcG9zZWROYW1lICkgPj49IGFSZXR1cm47CgogICAgICAgICAgICAgICAgLy8gY29sbGVjdCB0aGUgcGFyYW1ldGVycyBmcm9tIHRoZSBzdWIgcXVlcnkKICAgICAgICAgICAgICAgIEZvcmJpZFF1ZXJ5TmFtZSBhRm9yYmlkTmFtZSggKm1fcEltcGwsIHNDb21wb3NlZE5hbWUgKTsKICAgICAgICAgICAgICAgIGltcGxfZ2V0UXVlcnlQYXJhbWV0ZXJDb2x1bW5zKCBhUmV0dXJuICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoIGJUYWJsZURvZXNFeGlzdCApCiAgICAgICAgICAgICAgICBtX3BJbXBsLT5tX3hUYWJsZUNvbnRhaW5lci0+Z2V0QnlOYW1lKCBzQ29tcG9zZWROYW1lICkgPj49IGFSZXR1cm47CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCBtX3BJbXBsLT5tX3hRdWVyeUNvbnRhaW5lci5pcygpICkKICAgICAgICAgICAgICAgICAgICAvLyB0aGUgY29ubmVjdGlvbiBvbiB3aGljaCB3ZSdyZSB3b3JraW5nIHN1cHBvcnRzIHN1YiBxdWVyaWVzIGluIGZyb20gKGVsc2UKICAgICAgICAgICAgICAgICAgICAvLyBtX3hRdWVyeUNvbnRhaW5lciB3b3VsZCBub3QgaGF2ZSBiZWVuIHNldCksIHNvIGVtaXQgYSBiZXR0ZXIgZXJyb3IgbWVzc2FnZQogICAgICAgICAgICAgICAgICAgIGltcGxfYXBwZW5kRXJyb3IoIElQYXJzZUNvbnRleHQ6OkVSUk9SX0lOVkFMSURfVEFCTEVfT1JfUVVFUlksICZzTmFtZSApOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGltcGxfYXBwZW5kRXJyb3IoIElQYXJzZUNvbnRleHQ6OkVSUk9SX0lOVkFMSURfVEFCTEUsICZzTmFtZSApOwogICAgICAgICAgICB9CiAgICAgICAgfQoJfQoJY2F0Y2goRXhjZXB0aW9uJikKCXsKICAgICAgICBpbXBsX2FwcGVuZEVycm9yKCBJUGFyc2VDb250ZXh0OjpFUlJPUl9JTlZBTElEX1RBQkxFLCAmc0NvbXBvc2VkTmFtZSApOwoJfQoKICAgIHJldHVybiBhUmV0dXJuOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZU9uZVRhYmxlTmFtZSggT1NRTFRhYmxlcyYgX3JUYWJsZXMsY29uc3QgT1NRTFBhcnNlTm9kZSAqIHBUYWJsZU5hbWUsIGNvbnN0IDo6cnRsOjpPVVN0cmluZyAmIHJUYWJsZVJhbmdlICkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlT25lVGFibGVOYW1lIiApOwogICAgaWYgKCAoIG1fcEltcGwtPm1fbkluY2x1ZGVNYXNrICYgVGFibGVOYW1lcyApICE9IFRhYmxlTmFtZXMgKQogICAgICAgIC8vIHRhYmxlcyBzaG91bGQgbm90IGJlIGluY2x1ZGVkIGluIHRoZSB0cmF2ZXJzYWwKICAgICAgICByZXR1cm47CgoJT1NMX0VOU1VSRShwVGFibGVOYW1lICE9IE5VTEwsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VPbmVUYWJsZU5hbWU6IHBUYWJsZU5hbWUgPT0gTlVMTCIpOwoKCUFueSBhQ2F0YWxvZzsKCTo6cnRsOjpPVVN0cmluZyBhU2NoZW1hLGFUYWJsZU5hbWUsYUNvbXBvc2VkTmFtZTsKCTo6cnRsOjpPVVN0cmluZyBhVGFibGVSYW5nZShyVGFibGVSYW5nZSk7CgoJLy8gVGFiZWxsZW5uYW1lIGFiaG9sZW4KCU9TUUxQYXJzZU5vZGU6OmdldFRhYmxlQ29tcG9uZW50cyhwVGFibGVOYW1lLGFDYXRhbG9nLGFTY2hlbWEsYVRhYmxlTmFtZSxtX3BJbXBsLT5tX3hEYXRhYmFzZU1ldGFEYXRhKTsKCgkvLyBjcmVhdGUgdGhlIGNvbXBvc2VkIG5hbWUgbGlrZSBET01BSU4uVVNFUi5UQUJMRTEKCWFDb21wb3NlZE5hbWUgPSA6OmRidG9vbHM6OmNvbXBvc2VUYWJsZU5hbWUobV9wSW1wbC0+bV94RGF0YWJhc2VNZXRhRGF0YSwKCQkJCQkJCQlhQ2F0YWxvZy5oYXNWYWx1ZSgpID8gOjpjb21waGVscGVyOjpnZXRTdHJpbmcoYUNhdGFsb2cpIDogOjpydGw6Ok9VU3RyaW5nKCksCgkJCQkJCQkJYVNjaGVtYSwKCQkJCQkJCQlhVGFibGVOYW1lLAoJCQkJCQkJCXNhbF9GYWxzZSwKCQkJCQkJCQk6OmRidG9vbHM6OmVJbkRhdGFNYW5pcHVsYXRpb24pOwoKICAgIC8vIGlmIHRoZXJlIGlzIG5vIGFsaWFzIGZvciB0aGUgdGFibGUgbmFtZSBhc3NpZ24gdGhlIG9yaWduYWwgbmFtZSB0byBpdAoJaWYgKCAhYVRhYmxlUmFuZ2UuZ2V0TGVuZ3RoKCkgKQoJCWFUYWJsZVJhbmdlID0gYUNvbXBvc2VkTmFtZTsKCiAgICAvLyBnZXQgdGhlIG9iamVjdCByZXByZXNlbnRpbmcgdGhpcyB0YWJsZS9xdWVyeQogICAgT1NRTFRhYmxlIGFUYWJsZSA9IGltcGxfbG9jYXRlUmVjb3JkU291cmNlKCBhQ29tcG9zZWROYW1lICk7CiAgICBpZiAoIGFUYWJsZS5pcygpICkKICAgICAgICBfclRhYmxlc1sgYVRhYmxlUmFuZ2UgXSA9IGFUYWJsZTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppbXBsX2ZpbGxKb2luQ29uZGl0aW9ucyhjb25zdCBPU1FMUGFyc2VOb2RlKiBpX3BKb2luQ29uZGl0aW9uKQp7CiAgICBpZiAoaV9wSm9pbkNvbmRpdGlvbi0+Y291bnQoKSA9PSAzICYmCS8vIEF1c2RydWNrIGlzIGdla2xhbW1lcnQKCQlTUUxfSVNQVU5DVFVBVElPTihpX3BKb2luQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSwiKCIpICYmCgkJU1FMX0lTUFVOQ1RVQVRJT04oaV9wSm9pbkNvbmRpdGlvbi0+Z2V0Q2hpbGQoMiksIikiKSkKCXsKICAgICAgICBpbXBsX2ZpbGxKb2luQ29uZGl0aW9ucyhpX3BKb2luQ29uZGl0aW9uLT5nZXRDaGlsZCgxKSk7Cgl9CgllbHNlIGlmIChTUUxfSVNSVUxFT1IyKGlfcEpvaW5Db25kaXRpb24sc2VhcmNoX2NvbmRpdGlvbixib29sZWFuX3Rlcm0pCSYmCQkJLy8gQU5EL09SLVZlcmtudWVwZnVuZzoKCQkJIGlfcEpvaW5Db25kaXRpb24tPmNvdW50KCkgPT0gMykKCXsKCQkvLyBudXIgQU5EIFZlcmtu/HBmdW5nIHp1bGFzc2VuCgkJaWYgKCBTUUxfSVNUT0tFTihpX3BKb2luQ29uZGl0aW9uLT5nZXRDaGlsZCgxKSxBTkQpICkKICAgICAgICB7CiAgICAgICAgICAgIGltcGxfZmlsbEpvaW5Db25kaXRpb25zKGlfcEpvaW5Db25kaXRpb24tPmdldENoaWxkKDApKTsKICAgICAgICAgICAgaW1wbF9maWxsSm9pbkNvbmRpdGlvbnMoaV9wSm9pbkNvbmRpdGlvbi0+Z2V0Q2hpbGQoMSkpOwogICAgICAgIH0KCX0KCWVsc2UgaWYgKFNRTF9JU1JVTEUoaV9wSm9pbkNvbmRpdGlvbixjb21wYXJpc29uX3ByZWRpY2F0ZSkpCgl7CgkJLy8gb25seSB0aGUgY29tcGFyaXNvbiBvZiBjb2x1bW5zIGlzIGFsbG93ZWQKCQlPU0xfRU5TVVJFKGlfcEpvaW5Db25kaXRpb24tPmNvdW50KCkgPT0gMywiT1F1ZXJ5RGVzaWduVmlldzo6SW5zZXJ0Sm9pbkNvbm5lY3Rpb246IEZlaGxlciBpbSBQYXJzZSBUcmVlIik7CgkJaWYgKFNRTF9JU1JVTEUoaV9wSm9pbkNvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksY29sdW1uX3JlZikgJiYKCQkJICBTUUxfSVNSVUxFKGlfcEpvaW5Db25kaXRpb24tPmdldENoaWxkKDIpLGNvbHVtbl9yZWYpICYmCgkJCSAgIGlfcEpvaW5Db25kaXRpb24tPmdldENoaWxkKDEpLT5nZXROb2RlVHlwZSgpID09IFNRTF9OT0RFX0VRVUFMKQogICAgICAgIHsKICAgICAgICAgICAgbV9wSW1wbC0+bV9hSm9pbkNvbmRpdGlvbnMucHVzaF9iYWNrKCBUTm9kZVBhaXIoaV9wSm9pbkNvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksaV9wSm9pbkNvbmRpdGlvbi0+Z2V0Q2hpbGQoMikpICk7CiAgICAgICAgfQogICAgfQp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpzdGQ6OnZlY3RvcjwgVE5vZGVQYWlyID4mIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0Sm9pbkNvbmRpdGlvbnMoKSBjb25zdAp7CiAgICByZXR1cm4gbV9wSW1wbC0+bV9hSm9pbkNvbmRpdGlvbnM7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0UXVhbGlmaWVkX2pvaW4oIE9TUUxUYWJsZXMmIF9yVGFibGVzLCBjb25zdCBPU1FMUGFyc2VOb2RlICpwVGFibGVSZWYsIDo6cnRsOjpPVVN0cmluZyYgYVRhYmxlUmFuZ2UgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0UXVhbGlmaWVkX2pvaW4iICk7CiAgICBPU0xfUFJFQ09ORCggU1FMX0lTUlVMRSggcFRhYmxlUmVmLCBjcm9zc191bmlvbiApIHx8IFNRTF9JU1JVTEUoIHBUYWJsZVJlZiwgcXVhbGlmaWVkX2pvaW4gKSAsCiAgICAgICAgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0UXVhbGlmaWVkX2pvaW46IGlsbGVnYWwgbm9kZSEiICk7CgoJYVRhYmxlUmFuZ2UgPSA6OnJ0bDo6T1VTdHJpbmcoKTsKCgljb25zdCBPU1FMUGFyc2VOb2RlKiBwTm9kZSA9IGdldFRhYmxlTm9kZShfclRhYmxlcyxwVGFibGVSZWYtPmdldENoaWxkKDApLGFUYWJsZVJhbmdlKTsKCWlmICggaXNUYWJsZU5vZGUoIHBOb2RlICkgKQoJCXRyYXZlcnNlT25lVGFibGVOYW1lKCBfclRhYmxlcywgcE5vZGUsIGFUYWJsZVJhbmdlICk7CgoJc2FsX3VJbnQzMiBuUG9zID0gNDsKCWlmKCBTUUxfSVNSVUxFKHBUYWJsZVJlZixjcm9zc191bmlvbikgfHwgcFRhYmxlUmVmLT5nZXRDaGlsZCgxKS0+Z2V0VG9rZW5JRCgpICE9IFNRTF9UT0tFTl9OQVRVUkFMKQogICAgewogICAgICAgIG5Qb3MgPSAzOwogICAgICAgIC8vIGpvaW5fY29uZGl0aW9uLG5hbWVkX2NvbHVtbnNfam9pbgogICAgICAgIGlmICggU1FMX0lTUlVMRSggcFRhYmxlUmVmLCBxdWFsaWZpZWRfam9pbiApICkKICAgICAgICB7CiAgICAgICAgICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBKb2luX3NwZWMgPSBwVGFibGVSZWYtPmdldENoaWxkKDQpOwogICAgICAgICAgICBpZiAoIFNRTF9JU1JVTEUoIHBKb2luX3NwZWMsIGpvaW5fY29uZGl0aW9uICkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbXBsX2ZpbGxKb2luQ29uZGl0aW9ucyhwSm9pbl9zcGVjLT5nZXRDaGlsZCgxKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb25zdCBPU1FMUGFyc2VOb2RlKiBwQ29sdW1uQ29tbWFsaXN0ID0gcEpvaW5fc3BlYy0+Z2V0Q2hpbGQoMik7CiAgICAgICAgICAgICAgICAvLyBBbGxlIENvbHVtbnMgaW4gZGVyIGNvbHVtbl9jb21tYWxpc3QgLi4uCgkJCSAgICBmb3IgKHNhbF91SW50MzIgaSA9IDA7IGkgPCBwQ29sdW1uQ29tbWFsaXN0LT5jb3VudCgpOyBpKyspCgkJCSAgICB7CgkJCQkgICAgY29uc3QgT1NRTFBhcnNlTm9kZSAqIHBDb2wgPSBwQ29sdW1uQ29tbWFsaXN0LT5nZXRDaGlsZChpKTsKICAgICAgICAgICAgICAgICAgICAvLyBhZGQgdHdpY2UgYmVjYXVzZSB0aGUgY29sdW1uIG11c3QgZXhpc3RzIGluIGJvdGggdGFibGVzCiAgICAgICAgICAgICAgICAgICAgbV9wSW1wbC0+bV9hSm9pbkNvbmRpdGlvbnMucHVzaF9iYWNrKCBUTm9kZVBhaXIocENvbCxwQ29sKSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKCXBOb2RlID0gZ2V0VGFibGVOb2RlKF9yVGFibGVzLHBUYWJsZVJlZi0+Z2V0Q2hpbGQoblBvcyksYVRhYmxlUmFuZ2UpOwoJaWYgKCBpc1RhYmxlTm9kZSggcE5vZGUgKSApCgkJdHJhdmVyc2VPbmVUYWJsZU5hbWUoIF9yVGFibGVzLCBwTm9kZSwgYVRhYmxlUmFuZ2UgKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmNvbnN0IE9TUUxQYXJzZU5vZGUqIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0VGFibGVOb2RlKCBPU1FMVGFibGVzJiBfclRhYmxlcywgY29uc3QgT1NRTFBhcnNlTm9kZSAqcFRhYmxlUmVmLDo6cnRsOjpPVVN0cmluZyYgclRhYmxlUmFuZ2UgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0VGFibGVOb2RlIiApOwogICAgT1NMX1BSRUNPTkQoIFNRTF9JU1JVTEUoIHBUYWJsZVJlZiwgdGFibGVfcmVmICkgfHwgU1FMX0lTUlVMRSggcFRhYmxlUmVmLCBqb2luZWRfdGFibGUgKQogICAgICAgICAgICAgIHx8IFNRTF9JU1JVTEUoIHBUYWJsZVJlZiwgcXVhbGlmaWVkX2pvaW4gKSB8fCBTUUxfSVNSVUxFKCBwVGFibGVSZWYsIGNyb3NzX3VuaW9uICksCiAgICAgICAgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0VGFibGVOb2RlOiBvbmx5IHRvIGJlIGNhbGxlZCBmb3IgdGFibGVfcmVmIG5vZGVzISIgKTsKCgljb25zdCBPU1FMUGFyc2VOb2RlKiBwVGFibGVOYW1lTm9kZSA9IE5VTEw7CgogICAgaWYgKCBTUUxfSVNSVUxFKCBwVGFibGVSZWYsIGpvaW5lZF90YWJsZSApICkKICAgIHsKICAgICAgICBnZXRRdWFsaWZpZWRfam9pbiggX3JUYWJsZXMsIHBUYWJsZVJlZi0+Z2V0Q2hpbGQoMSksIHJUYWJsZVJhbmdlICk7CiAgICB9CiAgICBpZiAoIFNRTF9JU1JVTEUoIHBUYWJsZVJlZiwgcXVhbGlmaWVkX2pvaW4gKSB8fCBTUUxfSVNSVUxFKCBwVGFibGVSZWYsIGNyb3NzX3VuaW9uICkgKQogICAgewogICAgICAgIGdldFF1YWxpZmllZF9qb2luKCBfclRhYmxlcywgcFRhYmxlUmVmLCByVGFibGVSYW5nZSApOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHJUYWJsZVJhbmdlID0gT1NRTFBhcnNlTm9kZTo6Z2V0VGFibGVSYW5nZShwVGFibGVSZWYpOwogICAgICAgIGlmICAoICAgKCBwVGFibGVSZWYtPmNvdW50KCkgPT0gNCApIC8vICd7JyBTUUxfVE9LRU5fT0ogam9pbmVkX3RhYmxlICd9JwogICAgICAgICAgICB8fCAgKCBwVGFibGVSZWYtPmNvdW50KCkgPT0gNSApIC8vICcoJyBqb2luZWRfdGFibGUgJyknIHJhbmdlX3ZhcmlhYmxlIG9wX2NvbHVtbl9jb21tYWxpc3QKICAgICAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgZ2V0UXVhbGlmaWVkX2pvaW4oIF9yVGFibGVzLCBwVGFibGVSZWYtPmdldENoaWxkKDYgLSBwVGFibGVSZWYtPmNvdW50KCkpLCByVGFibGVSYW5nZSApOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICggcFRhYmxlUmVmLT5jb3VudCgpID09IDMgKSAvLyBzdWJxdWVyeSByYW5nZV92YXJpYWJsZSBvcF9jb2x1bW5fY29tbWFsaXN0IHx8ICcoJyBqb2luZWRfdGFibGUgJyknCiAgICAgICAgewogICAgICAgICAgICBjb25zdCBPU1FMUGFyc2VOb2RlKiBwU3ViUXVlcnkgPSBwVGFibGVSZWYtPmdldENoaWxkKDApOwogICAgICAgICAgICBpZiAoIHBTdWJRdWVyeS0+aXNUb2tlbigpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ2V0UXVhbGlmaWVkX2pvaW4oIF9yVGFibGVzLCBwVGFibGVSZWYtPmdldENoaWxkKDEpLCByVGFibGVSYW5nZSApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgT1NMX0VOU1VSRSggcFN1YlF1ZXJ5LT5jb3VudCgpID09IDMsICJzdWIgcXVlcmllcyBzaG91bGQgaGF2ZSAzIGNoaWxkcmVuISIgKTsKICAgICAgICAgICAgICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBRdWVyeUV4cHJlc3Npb24gPSBwU3ViUXVlcnktPmdldENoaWxkKDEpOwogICAgICAgICAgICAgICAgaWYgKCBTUUxfSVNSVUxFKCBwUXVlcnlFeHByZXNzaW9uLCBzZWxlY3Rfc3RhdGVtZW50ICkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGdldFNlbGVjdF9zdGF0ZW1lbnQoICptX3BJbXBsLT5tX3BTdWJUYWJsZXMsIHBRdWVyeUV4cHJlc3Npb24gKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBPU0xfRU5TVVJFKCBmYWxzZSwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0VGFibGVOb2RlOiBzdWJxdWVyeSB3aGljaCBpcyBubyBzZWxlY3Rfc3RhdGVtZW50OiBub3QgeWV0IGltcGxlbWVudGVkISIgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGlmICggcFRhYmxlUmVmLT5jb3VudCgpID09IDIgKSAvLyB0YWJsZV9ub2RlIHRhYmxlX3ByaW1hcnlfYXNfcmFuZ2VfY29sdW1uCiAgICAgICAgewogICAgICAgICAgICBwVGFibGVOYW1lTm9kZSA9IHBUYWJsZVJlZi0+Z2V0Q2hpbGQoMCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgT1NMX0VOU1VSRSggZmFsc2UsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldFRhYmxlTm9kZTogdW5oYW5kbGVkIGNhc2UhIiApOwogICAgfQoKCXJldHVybiBwVGFibGVOYW1lTm9kZTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTZWxlY3Rfc3RhdGVtZW50KE9TUUxUYWJsZXMmIF9yVGFibGVzLGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBTZWxlY3QpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTZWxlY3Rfc3RhdGVtZW50IiApOwoJaWYoU1FMX0lTUlVMRShwU2VsZWN0LHVuaW9uX3N0YXRlbWVudCkpCgl7CgkJZ2V0U2VsZWN0X3N0YXRlbWVudChfclRhYmxlcyxwU2VsZWN0LT5nZXRDaGlsZCgwKSk7CgkJLy9nZXRTZWxlY3Rfc3RhdGVtZW50KHBTZWxlY3QtPmdldENoaWxkKDMpKTsKCQlyZXR1cm47Cgl9CglPU1FMUGFyc2VOb2RlICogcFRhYmxlUmVmQ29tbWFsaXN0ID0gcFNlbGVjdC0+Z2V0Q2hpbGQoMyktPmdldENoaWxkKDApLT5nZXRDaGlsZCgxKTsKCglPU0xfRU5TVVJFKHBUYWJsZVJlZkNvbW1hbGlzdCAhPSBOVUxMLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CglPU0xfRU5TVVJFKFNRTF9JU1JVTEUocFRhYmxlUmVmQ29tbWFsaXN0LHRhYmxlX3JlZl9jb21tYWxpc3QpLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJY29uc3QgT1NRTFBhcnNlTm9kZSogcFRhYmxlTmFtZSA9IE5VTEw7Cgk6OnJ0bDo6T1VTdHJpbmcgYVRhYmxlUmFuZ2U7Cglmb3IgKHNhbF91SW50MzIgaSA9IDA7IGkgPCBwVGFibGVSZWZDb21tYWxpc3QtPmNvdW50KCk7IGkrKykKCXsgLy8gZnJvbSBjbGF1c2UgZHVyY2hsYXVmZW4KCQlhVGFibGVSYW5nZSA9IDo6cnRsOjpPVVN0cmluZygpOwoKICAgICAgICBjb25zdCBPU1FMUGFyc2VOb2RlKiBwVGFibGVMaXN0RWxlbWVudCA9IHBUYWJsZVJlZkNvbW1hbGlzdC0+Z2V0Q2hpbGQoaSk7CgkJaWYgKCBpc1RhYmxlTm9kZSggcFRhYmxlTGlzdEVsZW1lbnQgKSApCgkJewoJCQl0cmF2ZXJzZU9uZVRhYmxlTmFtZSggX3JUYWJsZXMsIHBUYWJsZUxpc3RFbGVtZW50LCBhVGFibGVSYW5nZSApOwoJCX0KCQllbHNlIGlmICggU1FMX0lTUlVMRSggcFRhYmxlTGlzdEVsZW1lbnQsIHRhYmxlX3JlZiApICkKCQl7CgkJCS8vIFRhYmVsbGVucmVmZXJlbnoga2FubiBhdXMgVGFiZWxsZW5uYW1lbiwgVGFiZWxsZW5uYW1lbiAoKyksJygnam9pbmVkX3RhYmxlJyknKCspIGJlc3RlaGVuCgkJCXBUYWJsZU5hbWUgPSBwVGFibGVMaXN0RWxlbWVudC0+Z2V0Q2hpbGQoMCk7CgkJCWlmKCBpc1RhYmxlTm9kZSggcFRhYmxlTmFtZSApICkKCQkJewkvLyBUYWJlbGxlbm5hbWVuIGdlZnVuZGVuCiAgICAgICAgICAgICAgICBhVGFibGVSYW5nZSA9IE9TUUxQYXJzZU5vZGU6OmdldFRhYmxlUmFuZ2UocFRhYmxlTGlzdEVsZW1lbnQpOwoJCQkJdHJhdmVyc2VPbmVUYWJsZU5hbWUoIF9yVGFibGVzLCBwVGFibGVOYW1lLCBhVGFibGVSYW5nZSApOwoJCQl9CgkJCWVsc2UgaWYoU1FMX0lTUFVOQ1RVQVRJT04ocFRhYmxlTmFtZSwieyIpKQogICAgICAgICAgICB7ICAgLy8gJ3snIFNRTF9UT0tFTl9PSiBqb2luZWRfdGFibGUgJ30nCiAgICAgICAgICAgICAgICBnZXRRdWFsaWZpZWRfam9pbiggX3JUYWJsZXMsIHBUYWJsZUxpc3RFbGVtZW50LT5nZXRDaGlsZCgyKSwgYVRhYmxlUmFuZ2UgKTsKICAgICAgICAgICAgfQoJCQllbHNlCiAgICAgICAgICAgIHsgICAvLyAnKCcgam9pbmVkX3RhYmxlICcpJyByYW5nZV92YXJpYWJsZSBvcF9jb2x1bW5fY29tbWFsaXN0CgkJCQlnZXRUYWJsZU5vZGUoIF9yVGFibGVzLCBwVGFibGVMaXN0RWxlbWVudCwgYVRhYmxlUmFuZ2UgKTsKICAgICAgICAgICAgfQoJCX0KCQllbHNlIGlmIChTUUxfSVNSVUxFKCBwVGFibGVMaXN0RWxlbWVudCwgcXVhbGlmaWVkX2pvaW4gKSB8fCBTUUxfSVNSVUxFKCBwVGFibGVMaXN0RWxlbWVudCwgY3Jvc3NfdW5pb24gKSApCgkJewoJCQlnZXRRdWFsaWZpZWRfam9pbiggX3JUYWJsZXMsIHBUYWJsZUxpc3RFbGVtZW50LCBhVGFibGVSYW5nZSApOwoJCX0KICAgICAgICBlbHNlIGlmICggU1FMX0lTUlVMRSggcFRhYmxlTGlzdEVsZW1lbnQsIGpvaW5lZF90YWJsZSApICkKICAgICAgICB7CiAgICAgICAgICAgIGdldFF1YWxpZmllZF9qb2luKCBfclRhYmxlcywgcFRhYmxlTGlzdEVsZW1lbnQtPmdldENoaWxkKDEpLCBhVGFibGVSYW5nZSApOwogICAgICAgIH0KCgkJLy8JaWYgKCEgYUl0ZXJhdG9yU3RhdHVzLklzU3VjY2Vzc2Z1bCgpKSBicmVhazsKCX0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZVRhYmxlTmFtZXMoT1NRTFRhYmxlcyYgX3JUYWJsZXMpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZVRhYmxlTmFtZXMiICk7CglpZiAoIG1fcFBhcnNlVHJlZSA9PSBOVUxMICkKCQlyZXR1cm4gZmFsc2U7CgoJT1NRTFBhcnNlTm9kZSogcFRhYmxlTmFtZSA9IE5VTEw7CgogICAgc3dpdGNoICggbV9lU3RhdGVtZW50VHlwZSApCiAgICB7CiAgICAgICAgY2FzZSBTUUxfU1RBVEVNRU5UX1NFTEVDVDoKCQkgICAgZ2V0U2VsZWN0X3N0YXRlbWVudCggX3JUYWJsZXMsIG1fcFBhcnNlVHJlZSApOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBTUUxfU1RBVEVNRU5UX0NSRUFURV9UQUJMRToKICAgICAgICBjYXNlIFNRTF9TVEFURU1FTlRfSU5TRVJUOgogICAgICAgIGNhc2UgU1FMX1NUQVRFTUVOVF9ERUxFVEU6CgkJICAgIHBUYWJsZU5hbWUgPSBtX3BQYXJzZVRyZWUtPmdldENoaWxkKDIpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBTUUxfU1RBVEVNRU5UX1VQREFURToKCQkgICAgcFRhYmxlTmFtZSA9IG1fcFBhcnNlVHJlZS0+Z2V0Q2hpbGQoMSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmICggcFRhYmxlTmFtZSApCiAgICB7CiAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNUYWJsZVJhbmdlOwoJICAgIHRyYXZlcnNlT25lVGFibGVOYW1lKCBfclRhYmxlcywgcFRhYmxlTmFtZSwgc1RhYmxlUmFuZ2UgKTsKICAgIH0KCiAgICByZXR1cm4gIWhhc0Vycm9ycygpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpydGw6Ok9VU3RyaW5nIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0Q29sdW1uQWxpYXMoY29uc3QgT1NRTFBhcnNlTm9kZSogX3BEZXJpdmVkQ29sdW1uKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0Q29sdW1uQWxpYXMiICk7CglPU0xfRU5TVVJFKFNRTF9JU1JVTEUoX3BEZXJpdmVkQ29sdW1uLGRlcml2ZWRfY29sdW1uKSwiTm8gZGVyaXZlZCBjb2x1bW4hIik7Cgk6OnJ0bDo6T1VTdHJpbmcgc0NvbHVtbkFsaWFzOwoJaWYoX3BEZXJpdmVkQ29sdW1uLT5nZXRDaGlsZCgxKS0+Y291bnQoKSA9PSAyKQoJCXNDb2x1bW5BbGlhcyA9IF9wRGVyaXZlZENvbHVtbi0+Z2V0Q2hpbGQoMSktPmdldENoaWxkKDEpLT5nZXRUb2tlblZhbHVlKCk7CgllbHNlIGlmKCFfcERlcml2ZWRDb2x1bW4tPmdldENoaWxkKDEpLT5pc1J1bGUoKSkKCQlzQ29sdW1uQWxpYXMgPSBfcERlcml2ZWRDb2x1bW4tPmdldENoaWxkKDEpLT5nZXRUb2tlblZhbHVlKCk7CglyZXR1cm4gc0NvbHVtbkFsaWFzOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpuYW1lc3BhY2UKewogICAgdm9pZCBsY2xfZ2V0Q29sdW1uUmFuZ2UoIGNvbnN0IE9TUUxQYXJzZU5vZGUqIF9wQ29sdW1uUmVmLCBjb25zdCBSZWZlcmVuY2U8IFhDb25uZWN0aW9uID4mIF9yeENvbm5lY3Rpb24sCiAgICAgICAgOjpydGw6Ok9VU3RyaW5nJiBfb3V0X3JDb2x1bW5OYW1lLCA6OnJ0bDo6T1VTdHJpbmcmIF9vdXRfclRhYmxlUmFuZ2UsCiAgICAgICAgY29uc3QgT1NRTENvbHVtbnMqIF9wU2VsZWN0Q29sdW1ucywgOjpydGw6Ok9VU3RyaW5nJiBfb3V0X3JDb2x1bW5BbGlhc0lmUHJlc2VudCApCiAgICB7CgkgICAgX291dF9yQ29sdW1uTmFtZSA9IF9vdXRfclRhYmxlUmFuZ2UgPSBfb3V0X3JDb2x1bW5BbGlhc0lmUHJlc2VudCA9IDo6cnRsOjpPVVN0cmluZygpOwoJICAgIGlmICggU1FMX0lTUlVMRSggX3BDb2x1bW5SZWYsIGNvbHVtbl9yZWYgKSApCgkgICAgewoJCSAgICBpZiggX3BDb2x1bW5SZWYtPmNvdW50KCkgPiAxICkKCQkgICAgewoJCQkgICAgZm9yICggc2FsX0ludDMyIGk9MDsgaTwoKHNhbF9JbnQzMilfcENvbHVtblJlZi0+Y291bnQoKSktMjsgKytpICkKCQkJCSAgICBfcENvbHVtblJlZi0+Z2V0Q2hpbGQoaSktPnBhcnNlTm9kZVRvU3RyKCBfb3V0X3JUYWJsZVJhbmdlLCBfcnhDb25uZWN0aW9uLCBOVUxMLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSApOwogICAgICAgICAgICAgICAgX291dF9yQ29sdW1uTmFtZSA9IF9wQ29sdW1uUmVmLT5nZXRDaGlsZCggX3BDb2x1bW5SZWYtPmNvdW50KCktMSApLT5nZXRDaGlsZCgwKS0+Z2V0VG9rZW5WYWx1ZSgpOwoJCSAgICB9CgkJICAgIGVsc2UKCQkJICAgIF9vdXRfckNvbHVtbk5hbWUgPSBfcENvbHVtblJlZi0+Z2V0Q2hpbGQoMCktPmdldFRva2VuVmFsdWUoKTsKCiAgICAgICAgICAgIC8vIGxvb2sgdXAgdGhlIGNvbHVtbiBpbiB0aGUgc2VsZWN0IGNvbHVtbiwgdG8gZmluZCBhbiBwb3NzaWJsZSBhbGlhcwogICAgICAgICAgICBpZiAoIF9wU2VsZWN0Q29sdW1ucyApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoICAgT1NRTENvbHVtbnM6OlZlY3Rvcjo6Y29uc3RfaXRlcmF0b3IgbG9va3VwQ29sdW1uID0gX3BTZWxlY3RDb2x1bW5zLT5nZXQoKS5iZWdpbigpOwogICAgICAgICAgICAgICAgICAgICAgICBsb29rdXBDb2x1bW4gIT0gX3BTZWxlY3RDb2x1bW5zLT5nZXQoKS5lbmQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgKytsb29rdXBDb2x1bW4KICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiB4Q29sdW1uKCAqbG9va3VwQ29sdW1uICk7CiAgICAgICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc05hbWUsIHNUYWJsZU5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIHhDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoIE9NZXRhQ29ubmVjdGlvbjo6Z2V0UHJvcE1hcCgpLmdldE5hbWVCeUluZGV4KCBQUk9QRVJUWV9JRF9SRUFMTkFNRSApICkgPj49IHNOYW1lOwogICAgICAgICAgICAgICAgICAgICAgICB4Q29sdW1uLT5nZXRQcm9wZXJ0eVZhbHVlKCBPTWV0YUNvbm5lY3Rpb246OmdldFByb3BNYXAoKS5nZXROYW1lQnlJbmRleCggUFJPUEVSVFlfSURfVEFCTEVOQU1FICkgKSA+Pj0gc1RhYmxlTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBzTmFtZSA9PSBfb3V0X3JDb2x1bW5OYW1lICYmIHNUYWJsZU5hbWUgPT0gX291dF9yVGFibGVSYW5nZSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4Q29sdW1uLT5nZXRQcm9wZXJ0eVZhbHVlKCBPTWV0YUNvbm5lY3Rpb246OmdldFByb3BNYXAoKS5nZXROYW1lQnlJbmRleCggUFJPUEVSVFlfSURfTkFNRSApICkgPj49IF9vdXRfckNvbHVtbkFsaWFzSWZQcmVzZW50OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXRjaCggY29uc3QgRXhjZXB0aW9uJiApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAJICAgICAgICBEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoJICAgIH0KCSAgICBlbHNlIGlmKFNRTF9JU1JVTEUoX3BDb2x1bW5SZWYsZ2VuZXJhbF9zZXRfZmN0KSB8fCBTUUxfSVNSVUxFKF9wQ29sdW1uUmVmLHNldF9mY3Rfc3BlYykpCgkgICAgeyAvLyBGdW5rdGlvbgoJCSAgICBfcENvbHVtblJlZi0+cGFyc2VOb2RlVG9TdHIoIF9vdXRfckNvbHVtbk5hbWUsIF9yeENvbm5lY3Rpb24gKTsKCSAgICB9CgkgICAgZWxzZSAgaWYoX3BDb2x1bW5SZWYtPmdldE5vZGVUeXBlKCkgPT0gU1FMX05PREVfTkFNRSkKCQkgICAgX291dF9yQ29sdW1uTmFtZSA9IF9wQ29sdW1uUmVmLT5nZXRUb2tlblZhbHVlKCk7CiAgICB9Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRDb2x1bW5SYW5nZSgJY29uc3QgT1NRTFBhcnNlTm9kZSogX3BDb2x1bW5SZWYsCgkJCQkJCTo6cnRsOjpPVVN0cmluZyYgX3JDb2x1bW5OYW1lLAoJCQkJCQk6OnJ0bDo6T1VTdHJpbmcmIF9yVGFibGVSYW5nZSkgY29uc3QKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldENvbHVtblJhbmdlIiApOwogICAgOjpydGw6Ok9VU3RyaW5nIHNEdW1teTsKCWxjbF9nZXRDb2x1bW5SYW5nZSgJX3BDb2x1bW5SZWYsIG1fcEltcGwtPm1feENvbm5lY3Rpb24sIF9yQ29sdW1uTmFtZSwgX3JUYWJsZVJhbmdlLCBOVUxMLCBzRHVtbXkgKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldENvbHVtblJhbmdlKAljb25zdCBPU1FMUGFyc2VOb2RlKiBfcENvbHVtblJlZiwKCQkJCQkJOjpydGw6Ok9VU3RyaW5nJiBfckNvbHVtbk5hbWUsCgkJCQkJCTo6cnRsOjpPVVN0cmluZyYgX3JUYWJsZVJhbmdlLAogICAgICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcmIF9vdXRfckNvbHVtbkFsaWFzSWZQcmVzZW50ICkgY29uc3QKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldENvbHVtblJhbmdlIiApOwoJbGNsX2dldENvbHVtblJhbmdlKAlfcENvbHVtblJlZiwgbV9wSW1wbC0+bV94Q29ubmVjdGlvbiwgX3JDb2x1bW5OYW1lLCBfclRhYmxlUmFuZ2UsICYqbV9hU2VsZWN0Q29sdW1ucywgX291dF9yQ29sdW1uQWxpYXNJZlByZXNlbnQgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0Q29sdW1uUmFuZ2UoIGNvbnN0IE9TUUxQYXJzZU5vZGUqIF9wQ29sdW1uUmVmLAogICAgY29uc3QgUmVmZXJlbmNlPCBYQ29ubmVjdGlvbiA+JiBfcnhDb25uZWN0aW9uLCA6OnJ0bDo6T1VTdHJpbmcmIF9vdXRfckNvbHVtbk5hbWUsIDo6cnRsOjpPVVN0cmluZyYgX291dF9yVGFibGVSYW5nZSApCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRDb2x1bW5SYW5nZSIgKTsKICAgIDo6cnRsOjpPVVN0cmluZyBzRHVtbXk7CiAgICBsY2xfZ2V0Q29sdW1uUmFuZ2UoIF9wQ29sdW1uUmVmLCBfcnhDb25uZWN0aW9uLCBfb3V0X3JDb2x1bW5OYW1lLCBfb3V0X3JUYWJsZVJhbmdlLCBOVUxMLCBzRHVtbXkgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldENvbHVtblRhYmxlUmFuZ2UoY29uc3QgT1NRTFBhcnNlTm9kZSogcE5vZGUsIDo6cnRsOjpPVVN0cmluZyAmclRhYmxlUmFuZ2UpIGNvbnN0CnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRDb2x1bW5UYWJsZVJhbmdlIiApOwoJLy8gRXJtaXR0ZWxuIG9iIGFsbGUgU3BhbHRlbiB6dSBlaW5lciBUYWJlbGxlIGdlaG9lcmVuCglpZiAoU1FMX0lTUlVMRShwTm9kZSxjb2x1bW5fcmVmKSkKCXsKCQk6OnJ0bDo6T1VTdHJpbmcgYUNvbE5hbWUsIGFUYWJsZVJhbmdlOwoJCWdldENvbHVtblJhbmdlKHBOb2RlLCBhQ29sTmFtZSwgYVRhYmxlUmFuZ2UpOwoJCWlmICghYVRhYmxlUmFuZ2UuZ2V0TGVuZ3RoKCkpCS8vIGtlaW5lbiBnZWZ1bmRlbgoJCXsKCQkJLy8gZGFubiBkaWUgU3BhbHRlIGluIGRlbiBUYWJlbGxlbiBzdWNoZW4KCQkJZm9yIChDb25zdE9TUUxUYWJsZXNJdGVyYXRvciBhSXRlciA9IG1fcEltcGwtPm1fcFRhYmxlcy0+YmVnaW4oKTsgYUl0ZXIgIT0gbV9wSW1wbC0+bV9wVGFibGVzLT5lbmQoKTsgKythSXRlcikKCQkJewoJCQkJaWYgKGFJdGVyLT5zZWNvbmQuaXMoKSkKCQkJCXsKCQkJCQl0cnkKCQkJCQl7CgkJCQkJCVJlZmVyZW5jZTwgWE5hbWVBY2Nlc3MgPiB4Q29sdW1ucyA9IGFJdGVyLT5zZWNvbmQtPmdldENvbHVtbnMoKTsKCQkJCQkJaWYoeENvbHVtbnMtPmhhc0J5TmFtZShhQ29sTmFtZSkpCgkJCQkJCXsKCQkJCQkJCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geENvbHVtbjsKCQkJCQkJCWlmICh4Q29sdW1ucy0+Z2V0QnlOYW1lKGFDb2xOYW1lKSA+Pj0geENvbHVtbikKCQkJCQkJCXsKCQkJCQkJCQlPU0xfRU5TVVJFKHhDb2x1bW4uaXMoKSwiQ29sdW1uIGlzbid0IGEgcHJvcGVydHlzZXQhIik7CgkJCQkJCQkJYVRhYmxlUmFuZ2UgPSBhSXRlci0+Zmlyc3Q7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQkJY2F0Y2goRXhjZXB0aW9uJikKCQkJCQl7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWlmICghYVRhYmxlUmFuZ2UuZ2V0TGVuZ3RoKCkpCgkJCQlyZXR1cm4gc2FsX0ZhbHNlOwoJCX0KCgoJCWlmICghclRhYmxlUmFuZ2UuZ2V0TGVuZ3RoKCkpCgkJCXJUYWJsZVJhbmdlID0gYVRhYmxlUmFuZ2U7CgkJZWxzZSBpZiAoclRhYmxlUmFuZ2UgIT0gYVRhYmxlUmFuZ2UpCgkJCXJldHVybiBzYWxfRmFsc2U7Cgl9CgllbHNlCgl7CgkJZm9yIChzYWxfdUludDMyIGkgPSAwLCBuY291bnQgPSBwTm9kZS0+Y291bnQoKTsgaSA8IG5jb3VudDsgaSsrKQoJCXsKCQkJaWYgKCFnZXRDb2x1bW5UYWJsZVJhbmdlKHBOb2RlLT5nZXRDaGlsZChpKSwgclRhYmxlUmFuZ2UpKQoJCQkJcmV0dXJuIHNhbF9GYWxzZTsKCQl9Cgl9CglyZXR1cm4gc2FsX1RydWU7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlQ3JlYXRlQ29sdW1ucyhjb25zdCBPU1FMUGFyc2VOb2RlKiBwU2VsZWN0Tm9kZSkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlQ3JlYXRlQ29sdW1ucyIgKTsKCS8vCWFJdGVyYXRvclN0YXR1cy5DbGVhcigpOwoKCWlmICghcFNlbGVjdE5vZGUgfHwgbV9lU3RhdGVtZW50VHlwZSAhPSBTUUxfU1RBVEVNRU5UX0NSRUFURV9UQUJMRSB8fCBtX3BJbXBsLT5tX3BUYWJsZXMtPmVtcHR5KCkpCgl7CgkJaW1wbF9hcHBlbmRFcnJvciggSVBhcnNlQ29udGV4dDo6RVJST1JfR0VORVJBTCApOwoJCXJldHVybjsKCX0KICAgIGlmICghU1FMX0lTUlVMRShwU2VsZWN0Tm9kZSxiYXNlX3RhYmxlX2VsZW1lbnRfY29tbWFsaXN0KSkKICAgICAgICByZXR1cm4gOwoKCWZvciAoc2FsX3VJbnQzMiBpID0gMDsgaSA8IHBTZWxlY3ROb2RlLT5jb3VudCgpOyBpKyspCgl7CgkJT1NRTFBhcnNlTm9kZSAqcENvbHVtblJlZiA9IHBTZWxlY3ROb2RlLT5nZXRDaGlsZChpKTsKCgkJaWYgKFNRTF9JU1JVTEUocENvbHVtblJlZixjb2x1bW5fZGVmKSkKCQl7CgkJCTo6cnRsOjpPVVN0cmluZyBhQ29sdW1uTmFtZTsKICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIGFUeXBlTmFtZTsKCQkJOjpydGw6Ok9VU3RyaW5nIGFUYWJsZVJhbmdlOwoJCQlzYWxfSW50MzIgblR5cGUgPSBEYXRhVHlwZTo6VkFSQ0hBUjsKICAgICAgICAgICAgc2FsX0ludDMyIG5MZW4gID0gMDsKCQkJYUNvbHVtbk5hbWUgPSBwQ29sdW1uUmVmLT5nZXRDaGlsZCgwKS0+Z2V0VG9rZW5WYWx1ZSgpOwoKICAgICAgICAgICAgT1NRTFBhcnNlTm9kZSAqcERhdGF0eXBlID0gcENvbHVtblJlZi0+Z2V0Q2hpbGQoMSk7CiAgICAgICAgICAgIGlmIChwRGF0YXR5cGUgJiYgU1FMX0lTUlVMRShwRGF0YXR5cGUsY2hhcmFjdGVyX3N0cmluZ190eXBlKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29uc3QgT1NRTFBhcnNlTm9kZSAqcFR5cGUgPSBwRGF0YXR5cGUtPmdldENoaWxkKDApOwogICAgICAgICAgICAgICAgYVR5cGVOYW1lID0gcFR5cGUtPmdldFRva2VuVmFsdWUoKTsKICAgICAgICAgICAgICAgIGlmIChwRGF0YXR5cGUtPmNvdW50KCkgPT0gMiAmJiAocFR5cGUtPmdldFRva2VuSUQoKSA9PSBTUUxfVE9LRU5fQ0hBUiB8fCBwVHlwZS0+Z2V0VG9rZW5JRCgpID09IFNRTF9UT0tFTl9DSEFSQUNURVIgKSkKICAgICAgICAgICAgICAgICAgICBuVHlwZSA9IERhdGFUeXBlOjpDSEFSOwoKICAgICAgICAgICAgICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUgKnBQYXJhbXMgPSBwRGF0YXR5cGUtPmdldENoaWxkKHBEYXRhdHlwZS0+Y291bnQoKS0xKTsKICAgICAgICAgICAgICAgIGlmICggcFBhcmFtcy0+Y291bnQoKSApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbkxlbiA9IHBQYXJhbXMtPmdldENoaWxkKDEpLT5nZXRUb2tlblZhbHVlKCkudG9JbnQzMigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYocERhdGF0eXBlICYmIHBEYXRhdHlwZS0+Z2V0Tm9kZVR5cGUoKSA9PSBTUUxfTk9ERV9LRVlXT1JEKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhVHlwZU5hbWUgPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiVkFSQ0hBUiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoYVR5cGVOYW1lLmdldExlbmd0aCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvL1RPRE86Q3JlYXRlIGEgbmV3IGNsYXNzIGZvciBjcmVhdGUgc3RhdGVtZW50IHRvIGhhbmRsZSBmaWVsZCBsZW5ndGgKCQkJICAgIE9QYXJzZUNvbHVtbiogcENvbHVtbiA9IG5ldyBPUGFyc2VDb2x1bW4oYUNvbHVtbk5hbWUsYVR5cGVOYW1lLDo6cnRsOjpPVVN0cmluZygpLDo6cnRsOjpPVVN0cmluZygpLAoJCQkJCUNvbHVtblZhbHVlOjpOVUxMQUJMRV9VTktOT1dOLDAsMCxuVHlwZSxzYWxfRmFsc2Usc2FsX0ZhbHNlLGlzQ2FzZVNlbnNpdGl2ZSgpKTsKCQkJCXBDb2x1bW4tPnNldEZ1bmN0aW9uKHNhbF9GYWxzZSk7CgkJCQlwQ29sdW1uLT5zZXRSZWFsTmFtZShhQ29sdW1uTmFtZSk7CgoJCQkJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQ+IHhDb2wgPSBwQ29sdW1uOwoJCQkJbV9hQ3JlYXRlQ29sdW1ucy0+Z2V0KCkucHVzaF9iYWNrKHhDb2wpOwogICAgICAgICAgICB9CgkJfQoKCX0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZVNlbGVjdENvbHVtbk5hbWVzKGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBTZWxlY3ROb2RlKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VTZWxlY3RDb2x1bW5OYW1lcyIgKTsKICAgIGlmICggKCBtX3BJbXBsLT5tX25JbmNsdWRlTWFzayAmIFNlbGVjdENvbHVtbnMgKSAhPSBTZWxlY3RDb2x1bW5zICkKICAgICAgICByZXR1cm4gdHJ1ZTsKCglpZiAoIXBTZWxlY3ROb2RlIHx8IG1fZVN0YXRlbWVudFR5cGUgIT0gU1FMX1NUQVRFTUVOVF9TRUxFQ1QgfHwgbV9wSW1wbC0+bV9wVGFibGVzLT5lbXB0eSgpKQoJewoJCWltcGxfYXBwZW5kRXJyb3IoIElQYXJzZUNvbnRleHQ6OkVSUk9SX0dFTkVSQUwgKTsKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJaWYoU1FMX0lTUlVMRShwU2VsZWN0Tm9kZSx1bmlvbl9zdGF0ZW1lbnQpKQoJewoJCXJldHVybiAgdHJhdmVyc2VTZWxlY3RDb2x1bW5OYW1lcyggcFNlbGVjdE5vZGUtPmdldENoaWxkKCAwICkgKQogICAgICAgICAgICAvKiYmICB0cmF2ZXJzZVNlbGVjdENvbHVtbk5hbWVzKCBwU2VsZWN0Tm9kZS0+Z2V0Q2hpbGQoIDMgKSApKi87Cgl9CgogICAgc3RhdGljIDo6cnRsOjpPVVN0cmluZyBhRW1wdHlTdHJpbmc7CgkvLyBueWk6IG1laHIgUHJ1ZWZ1bmcgYXVmIGtvcnJla3RlIFN0cnVrdHVyIQoJaWYgKHBTZWxlY3ROb2RlLT5nZXRDaGlsZCgyKS0+aXNSdWxlKCkgJiYgU1FMX0lTUFVOQ1RVQVRJT04ocFNlbGVjdE5vZGUtPmdldENoaWxkKDIpLT5nZXRDaGlsZCgwKSwiKiIpKQoJewoJCS8vIFNFTEVDVCAqIC4uLgoJCXNldFNlbGVjdENvbHVtbk5hbWUobV9hU2VsZWN0Q29sdW1ucyw6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiKiIpLCBhRW1wdHlTdHJpbmcsYUVtcHR5U3RyaW5nKTsKCX0KCWVsc2UgaWYgKFNRTF9JU1JVTEUocFNlbGVjdE5vZGUtPmdldENoaWxkKDIpLHNjYWxhcl9leHBfY29tbWFsaXN0KSkKCXsKCQkvLyBTRUxFQ1QgY29sdW1uWyxjb2x1bW5dIG9kZXIgU0VMRUNUIENPVU5UKCopIC4uLgoJCU9TUUxQYXJzZU5vZGUgKiBwU2VsZWN0aW9uID0gcFNlbGVjdE5vZGUtPmdldENoaWxkKDIpOwoKCQlmb3IgKHNhbF91SW50MzIgaSA9IDA7IGkgPCBwU2VsZWN0aW9uLT5jb3VudCgpOyBpKyspCgkJewoJCQlPU1FMUGFyc2VOb2RlICpwQ29sdW1uUmVmID0gcFNlbGVjdGlvbi0+Z2V0Q2hpbGQoaSk7CgoJCQkvL2lmIChTUUxfSVNSVUxFKHBDb2x1bW5SZWYsc2VsZWN0X3N1Ymxpc3QpKQoJCQlpZiAoU1FMX0lTUlVMRShwQ29sdW1uUmVmLGRlcml2ZWRfY29sdW1uKSAmJgoJCQkJU1FMX0lTUlVMRShwQ29sdW1uUmVmLT5nZXRDaGlsZCgwKSxjb2x1bW5fcmVmKSAmJgoJCQkJcENvbHVtblJlZi0+Z2V0Q2hpbGQoMCktPmNvdW50KCkgPT0gMyAmJgoJCQkJU1FMX0lTUFVOQ1RVQVRJT04ocENvbHVtblJlZi0+Z2V0Q2hpbGQoMCktPmdldENoaWxkKDIpLCIqIikpCgkJCXsKCQkJCS8vIGFsbGUgU3BhbHRlbiBkZXIgVGFiZWxsZQoJCQkJOjpydGw6Ok9VU3RyaW5nIGFUYWJsZVJhbmdlOwoJCQkJcENvbHVtblJlZi0+Z2V0Q2hpbGQoMCktPnBhcnNlTm9kZVRvU3RyKCBhVGFibGVSYW5nZSwgbV9wSW1wbC0+bV94Q29ubmVjdGlvbiwgTlVMTCwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgKTsKCQkJCXNldFNlbGVjdENvbHVtbk5hbWUobV9hU2VsZWN0Q29sdW1ucyw6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiKiIpLCBhRW1wdHlTdHJpbmcsYVRhYmxlUmFuZ2UpOwoJCQkJY29udGludWU7CgkJCX0KCQkJZWxzZSBpZiAoU1FMX0lTUlVMRShwQ29sdW1uUmVmLGRlcml2ZWRfY29sdW1uKSkKCQkJewoJCQkJOjpydGw6Ok9VU3RyaW5nIGFDb2x1bW5BbGlhcyhnZXRDb2x1bW5BbGlhcyhwQ29sdW1uUmVmKSk7IC8vIGthbm4gbGVlciBzZWluCgkJCQk6OnJ0bDo6T1VTdHJpbmcgc0NvbHVtbk5hbWU7CgkJCQk6OnJ0bDo6T1VTdHJpbmcgYVRhYmxlUmFuZ2U7CgkJCQlzYWxfSW50MzIgblR5cGUgPSBEYXRhVHlwZTo6VkFSQ0hBUjsKCQkJCXNhbF9Cb29sIGJGa3Qoc2FsX0ZhbHNlKTsKCQkJCXBDb2x1bW5SZWYgPSBwQ29sdW1uUmVmLT5nZXRDaGlsZCgwKTsKCQkJCWlmICgKCQkJCQkJcENvbHVtblJlZi0+Y291bnQoKSA9PSAzICYmCgkJCQkJCVNRTF9JU1BVTkNUVUFUSU9OKHBDb2x1bW5SZWYtPmdldENoaWxkKDApLCIoIikgJiYKCQkJCQkJU1FMX0lTUFVOQ1RVQVRJT04ocENvbHVtblJlZi0+Z2V0Q2hpbGQoMiksIikiKQoJCQkJCSkKCQkJCQlwQ29sdW1uUmVmID0gcENvbHVtblJlZi0+Z2V0Q2hpbGQoMSk7CgoJCQkJaWYgKFNRTF9JU1JVTEUocENvbHVtblJlZixjb2x1bW5fcmVmKSkKCQkJCXsKCQkJCQlnZXRDb2x1bW5SYW5nZShwQ29sdW1uUmVmLHNDb2x1bW5OYW1lLGFUYWJsZVJhbmdlKTsKCQkJCQlPU0xfRU5TVVJFKHNDb2x1bW5OYW1lLmdldExlbmd0aCgpLCJDb2x1bW5uYW1lIGRhcmYgbmljaHQgbGVlciBzZWluIik7CgkJCQl9CgkJCQllbHNlIC8qaWYgKFNRTF9JU1JVTEUocENvbHVtblJlZixnZW5lcmFsX3NldF9mY3QpIHx8IFNRTF9JU1JVTEUocENvbHVtblJlZixzZXRfZmN0X3NwZWMpCXx8CgkJCQkJCSBTUUxfSVNSVUxFKHBDb2x1bW5SZWYscG9zaXRpb25fZXhwKQl8fCBTUUxfSVNSVUxFKHBDb2x1bW5SZWYsZXh0cmFjdF9leHApCXx8CgkJCQkJCSBTUUxfSVNSVUxFKHBDb2x1bW5SZWYsbGVuZ3RoX2V4cCkJCXx8IFNRTF9JU1JVTEUocENvbHVtblJlZixjaGFyX3ZhbHVlX2ZjdCl8fAoJCQkJCQkgU1FMX0lTUlVMRShwQ29sdW1uUmVmLG51bV92YWx1ZV9leHApCXx8IFNRTF9JU1JVTEUocENvbHVtblJlZix0ZXJtKSkqLwoJCQkJewoJCQkJCS8qIEZ1bmt0aW9uc2F1ZnJ1ZiB2b3JoYW5kZW4gKi8KCQkJCQlwQ29sdW1uUmVmLT5wYXJzZU5vZGVUb1N0ciggc0NvbHVtbk5hbWUsIG1fcEltcGwtPm1feENvbm5lY3Rpb24sIE5VTEwsIHNhbF9GYWxzZSwgc2FsX1RydWUgKTsKCQkJCQk6OnJ0bDo6T1VTdHJpbmcgc1RhYmxlUmFuZ2U7CgkJCQkJLy8gY2hlY2sgaWYgdGhlIGNvbHVtbiBpcyBhbHNvIGEgcGFyYW1ldGVyCgkJCQkJdHJhdmVyc2VPUkNyaXRlcmlhKHBDb2x1bW5SZWYpOyAvLyBudW1fdmFsdWVfZXhwCgoJCQkJCS8vIGdlaG9lcmVuIGFsbGUgYmV0ZWlsaWd0ZW4gU3BhbHRlbiBkZXIgRnVua3Rpb24genUgZWluZXIgVGFiZWxsZQoJCQkJCWlmIChtX3BJbXBsLT5tX3BUYWJsZXMtPnNpemUoKSA9PSAxKQoJCQkJCXsKCQkJCQkJYVRhYmxlUmFuZ2UgPSBtX3BJbXBsLT5tX3BUYWJsZXMtPmJlZ2luKCktPmZpcnN0OwoJCQkJCX0KCQkJCQllbHNlCgkJCQkJewoJCQkJCQlnZXRDb2x1bW5UYWJsZVJhbmdlKHBDb2x1bW5SZWYsYVRhYmxlUmFuZ2UpOwoJCQkJCX0KCQkJCQlpZiAoIHBDb2x1bW5SZWYtPmlzUnVsZSgpICkKCQkJCQl7CgkJCQkJCWJGa3QgPSBzYWxfVHJ1ZTsKCQkJCQkJblR5cGUgPSBnZXRGdW5jdGlvblJldHVyblR5cGUocENvbHVtblJlZik7CgkJCQkJfQoJCQkJfQoJCQkJLyoKCQkJCWVsc2UKCQkJCXsKCQkJCQlhSXRlcmF0b3JTdGF0dXMuc2V0U3RhdGVtZW50VG9vQ29tcGxleCgpOwoJCQkJCXJldHVybjsKCQkJCX0KCQkJCSovCgkJCQlpZighYUNvbHVtbkFsaWFzLmdldExlbmd0aCgpKQoJCQkJCWFDb2x1bW5BbGlhcyA9IHNDb2x1bW5OYW1lOwoJCQkJc2V0U2VsZWN0Q29sdW1uTmFtZShtX2FTZWxlY3RDb2x1bW5zLHNDb2x1bW5OYW1lLGFDb2x1bW5BbGlhcyxhVGFibGVSYW5nZSxiRmt0LG5UeXBlLFNRTF9JU1JVTEUocENvbHVtblJlZixnZW5lcmFsX3NldF9mY3QpIHx8IFNRTF9JU1JVTEUocENvbHVtblJlZixzZXRfZmN0X3NwZWMpKTsKCQkJfQoJCX0KCX0KCiAgICByZXR1cm4gIWhhc0Vycm9ycygpOwp9CgoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpib29sIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VPcmRlckJ5Q29sdW1uTmFtZXMoY29uc3QgT1NRTFBhcnNlTm9kZSogcFNlbGVjdE5vZGUpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZU9yZGVyQnlDb2x1bW5OYW1lcyIgKTsKCXRyYXZlcnNlQnlDb2x1bW5OYW1lcyggcFNlbGVjdE5vZGUsIHNhbF9UcnVlICk7CiAgICByZXR1cm4gIWhhc0Vycm9ycygpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlQnlDb2x1bW5OYW1lcyhjb25zdCBPU1FMUGFyc2VOb2RlKiBwU2VsZWN0Tm9kZSxzYWxfQm9vbCBfYk9yZGVyKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VCeUNvbHVtbk5hbWVzIiApOwoJLy8JYUl0ZXJhdG9yU3RhdHVzLkNsZWFyKCk7CgoJaWYgKHBTZWxlY3ROb2RlID09IE5VTEwpCgl7CgkJLy9hSXRlcmF0b3JTdGF0dXMuc2V0SW52YWxpZFN0YXRlbWVudCgpOwoJCXJldHVybjsKCX0KCglpZiAobV9lU3RhdGVtZW50VHlwZSAhPSBTUUxfU1RBVEVNRU5UX1NFTEVDVCkKCXsKCQkvL2FJdGVyYXRvclN0YXR1cy5zZXRJbnZhbGlkU3RhdGVtZW50KCk7CgkJcmV0dXJuOwoJfQoKCWlmKFNRTF9JU1JVTEUocFNlbGVjdE5vZGUsdW5pb25fc3RhdGVtZW50KSkKCXsKCQl0cmF2ZXJzZUJ5Q29sdW1uTmFtZXMocFNlbGVjdE5vZGUtPmdldENoaWxkKDApLF9iT3JkZXIpOwoJCXJldHVybjsKCX0KCglPU0xfRU5TVVJFKHBTZWxlY3ROb2RlLT5jb3VudCgpID49IDQsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCglPU1FMUGFyc2VOb2RlICogcFRhYmxlRXhwID0gcFNlbGVjdE5vZGUtPmdldENoaWxkKDMpOwoJT1NMX0VOU1VSRShwVGFibGVFeHAgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJT1NMX0VOU1VSRShTUUxfSVNSVUxFKHBUYWJsZUV4cCx0YWJsZV9leHApLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6dGFibGVfZXhwIGVycm9yIGluIHBhcnNlIHRyZWUhIik7CglPU0xfRU5TVVJFKHBUYWJsZUV4cC0+Y291bnQoKSA9PSBUQUJMRV9FWFBSRVNTSU9OX0NISUxEX0NPVU5ULCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJc2FsX3VJbnQzMiBuUG9zID0gKCBfYk9yZGVyID8gT1JERVJfQllfQ0hJTERfUE9TIDogMiApOwoKCU9TUUxQYXJzZU5vZGUgKiBwT3B0QnlDbGF1c2UgPSBwVGFibGVFeHAtPmdldENoaWxkKG5Qb3MpOwoJT1NMX0VOU1VSRShwT3B0QnlDbGF1c2UgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJaWYgKCBwT3B0QnlDbGF1c2UtPmNvdW50KCkgPT0gMCApCgkJcmV0dXJuOwoKCU9TTF9FTlNVUkUocE9wdEJ5Q2xhdXNlLT5jb3VudCgpID09IDMsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCglPU1FMUGFyc2VOb2RlICogcE9yZGVyaW5nU3BlY0NvbW1hbGlzdCA9IHBPcHRCeUNsYXVzZS0+Z2V0Q2hpbGQoMik7CglPU0xfRU5TVVJFKHBPcmRlcmluZ1NwZWNDb21tYWxpc3QgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJT1NMX0VOU1VSRSghX2JPcmRlciB8fCBTUUxfSVNSVUxFKHBPcmRlcmluZ1NwZWNDb21tYWxpc3Qsb3JkZXJpbmdfc3BlY19jb21tYWxpc3QpLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6b3JkZXJpbmdfc3BlY19jb21tYWxpc3QgZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCU9TTF9FTlNVUkUocE9yZGVyaW5nU3BlY0NvbW1hbGlzdC0+Y291bnQoKSA+IDAsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCgk6OnJ0bDo6T1VTdHJpbmcgc0NvbHVtbk5hbWUsYUNvbHVtbkFsaWFzOwoJOjpydGw6Ok9VU3RyaW5nIGFUYWJsZVJhbmdlOwoJc2FsX3VJbnQzMiBuQ291bnQgPSBwT3JkZXJpbmdTcGVjQ29tbWFsaXN0LT5jb3VudCgpOwoJZm9yIChzYWxfdUludDMyIGkgPSAwOyBpIDwgbkNvdW50OyArK2kpCgl7CgkJT1NRTFBhcnNlTm9kZSogcENvbHVtblJlZiAgPSBwT3JkZXJpbmdTcGVjQ29tbWFsaXN0LT5nZXRDaGlsZChpKTsKCQlPU0xfRU5TVVJFKHBDb2x1bW5SZWYgICE9IE5VTEwsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCQlpZiAoIF9iT3JkZXIgKQoJCXsKCQkJT1NMX0VOU1VSRShTUUxfSVNSVUxFKHBDb2x1bW5SZWYsb3JkZXJpbmdfc3BlYyksIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjpvcmRlcmluZ19zcGVjIGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgkJCU9TTF9FTlNVUkUocENvbHVtblJlZi0+Y291bnQoKSA9PSAyLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJCQlwQ29sdW1uUmVmID0gcENvbHVtblJlZi0+Z2V0Q2hpbGQoMCk7CgkJfQoJCWFUYWJsZVJhbmdlID0gOjpydGw6Ok9VU3RyaW5nKCk7CgkJc0NvbHVtbk5hbWUgPSA6OnJ0bDo6T1VTdHJpbmcoKTsKCQlpZiAoIFNRTF9JU1JVTEUocENvbHVtblJlZixjb2x1bW5fcmVmKSApCgkJewoJCQkvLyBDb2x1bW4tTmFtZSAodW5kIFRhYmxlUmFuZ2UpOgoJCQlpZihTUUxfSVNSVUxFKHBDb2x1bW5SZWYsY29sdW1uX3JlZikpCgkJCQlnZXRDb2x1bW5SYW5nZShwQ29sdW1uUmVmLHNDb2x1bW5OYW1lLGFUYWJsZVJhbmdlKTsKCQkJZWxzZSAvLyBlaW5lIEV4cHJlc3Npb24KCQkJCXBDb2x1bW5SZWYtPnBhcnNlTm9kZVRvU3RyKCBzQ29sdW1uTmFtZSwgbV9wSW1wbC0+bV94Q29ubmVjdGlvbiwgTlVMTCwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgKTsKCgkJCU9TTF9FTlNVUkUoc0NvbHVtbk5hbWUuZ2V0TGVuZ3RoKCksInNDb2x1bW5OYW1lIGRhcmYgbmljaHQgbGVlciBzZWluIik7CgkJfQoJCWVsc2UKCQl7CS8vIGhlcmUgSSBmb3VuZCBhIHByZWRpY2F0ZQoJCQlwQ29sdW1uUmVmLT5wYXJzZU5vZGVUb1N0ciggc0NvbHVtbk5hbWUsIG1fcEltcGwtPm1feENvbm5lY3Rpb24sIE5VTEwsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlICk7CgkJfQoJCU9TTF9FTlNVUkUocENvbHVtblJlZiAhPSBOVUxMLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgkJaWYgKCBfYk9yZGVyICkKCQl7CgkJCS8vIEFzY2VuZGluZy9EZXNjZW5kaW5nCgkJCU9TUUxQYXJzZU5vZGUgKiBwT3B0QXNjRGVzYyA9IHBDb2x1bW5SZWYtPmdldFBhcmVudCgpLT5nZXRDaGlsZCgxKTsKCQkJT1NMX0VOU1VSRShwT3B0QXNjRGVzYyAhPSBOVUxMLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJCQlzYWxfQm9vbCBiQXNjZW5kaW5nID0gcE9wdEFzY0Rlc2MgJiYgU1FMX0lTVE9LRU4ocE9wdEFzY0Rlc2MsQVNDKTsKCQkJc2V0T3JkZXJCeUNvbHVtbk5hbWUoc0NvbHVtbk5hbWUsIGFUYWJsZVJhbmdlLGJBc2NlbmRpbmcpOwoJCX0KCQllbHNlCgkJCXNldEdyb3VwQnlDb2x1bW5OYW1lKHNDb2x1bW5OYW1lLCBhVGFibGVSYW5nZSk7Cgl9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpib29sIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VHcm91cEJ5Q29sdW1uTmFtZXMoY29uc3QgT1NRTFBhcnNlTm9kZSogcFNlbGVjdE5vZGUpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZUdyb3VwQnlDb2x1bW5OYW1lcyIgKTsKCXRyYXZlcnNlQnlDb2x1bW5OYW1lcyggcFNlbGVjdE5vZGUsIHNhbF9GYWxzZSApOwogICAgcmV0dXJuICFoYXNFcnJvcnMoKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KbmFtZXNwYWNlCnsKICAgIDo6cnRsOjpPVVN0cmluZyBsY2xfZ2VuZXJhdGVQYXJhbWV0ZXJOYW1lKCBjb25zdCBPU1FMUGFyc2VOb2RlJiBfclBhcmVudE5vZGUsIGNvbnN0IE9TUUxQYXJzZU5vZGUmIF9yUGFyYW1Ob2RlICkKICAgIHsKICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc0NvbHVtbk5hbWUoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSggInBhcmFtIiApICk7CiAgICAgICAgY29uc3Qgc2FsX0ludDMyIG5Db3VudCA9IChzYWxfSW50MzIpX3JQYXJlbnROb2RlLmNvdW50KCk7CiAgICAgICAgZm9yICggc2FsX0ludDMyIGkgPSAwOyBpIDwgbkNvdW50OyArK2kgKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCBfclBhcmVudE5vZGUuZ2V0Q2hpbGQoaSkgPT0gJl9yUGFyYW1Ob2RlICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc0NvbHVtbk5hbWUgKz0gOjpydGw6Ok9VU3RyaW5nOjp2YWx1ZU9mKCBpKzEgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBzQ29sdW1uTmFtZTsKICAgIH0KfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlUGFyYW1ldGVycyhjb25zdCBPU1FMUGFyc2VOb2RlKiBfcE5vZGUpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZVBhcmFtZXRlcnMiICk7CiAgICBpZiAoIF9wTm9kZSA9PSBOVUxMICkKICAgICAgICByZXR1cm47CgogICAgOjpydGw6Ok9VU3RyaW5nIHNDb2x1bW5OYW1lLCBzVGFibGVSYW5nZSwgYUNvbHVtbkFsaWFzOwogICAgY29uc3QgT1NRTFBhcnNlTm9kZSogcFBhcmVudCA9IF9wTm9kZS0+Z2V0UGFyZW50KCk7CiAgICBpZiAoIHBQYXJlbnQgIT0gTlVMTCApCiAgICB7CiAgICAgICAgaWYgKCBTUUxfSVNSVUxFKHBQYXJlbnQsY29tcGFyaXNvbl9wcmVkaWNhdGUpICkgLy8geCA9IFgKICAgICAgICB7CiAgICAgICAgICAgIHNhbF91SW50MzIgblBvcyA9IDA7CiAgICAgICAgICAgIGlmICggcFBhcmVudC0+Z2V0Q2hpbGQoblBvcykgPT0gX3BOb2RlICkKICAgICAgICAgICAgICAgIG5Qb3MgPSAyOwogICAgICAgICAgICBjb25zdCBPU1FMUGFyc2VOb2RlKiBwT3RoZXIgPSBwUGFyZW50LT5nZXRDaGlsZChuUG9zKTsKICAgICAgICAgICAgaWYgKCBTUUxfSVNSVUxFKCBwT3RoZXIsIGNvbHVtbl9yZWYgKSApCiAgICAgICAgICAgICAgICBnZXRDb2x1bW5SYW5nZSggcE90aGVyLCBzQ29sdW1uTmFtZSwgc1RhYmxlUmFuZ2UsIGFDb2x1bW5BbGlhcyk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBPdGhlci0+cGFyc2VOb2RlVG9TdHIoIHNDb2x1bW5OYW1lLCBtX3BJbXBsLT5tX3hDb25uZWN0aW9uLCBOVUxMLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSApOwogICAgICAgIH0gLy8gaWYgKCBTUUxfSVNSVUxFKHBQYXJlbnQsY29tcGFyaXNvbl9wcmVkaWNhdGUpICkgLy8geCA9IFgKICAgICAgICBlbHNlIGlmICggU1FMX0lTUlVMRShwUGFyZW50LG90aGVyX2xpa2VfcHJlZGljYXRlX3BhcnRfMikgKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgT1NRTFBhcnNlTm9kZSogcE90aGVyID0gcFBhcmVudC0+Z2V0UGFyZW50KCktPmdldENoaWxkKDApOwogICAgICAgICAgICBpZiAoIFNRTF9JU1JVTEUoIHBPdGhlciwgY29sdW1uX3JlZiApICkKICAgICAgICAgICAgICAgIGdldENvbHVtblJhbmdlKCBwT3RoZXIsIHNDb2x1bW5OYW1lLCBzVGFibGVSYW5nZSwgYUNvbHVtbkFsaWFzKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcE90aGVyLT5wYXJzZU5vZGVUb1N0ciggc0NvbHVtbk5hbWUsIG1fcEltcGwtPm1feENvbm5lY3Rpb24sIE5VTEwsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlICk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKCBTUUxfSVNSVUxFKHBQYXJlbnQsYmV0d2Vlbl9wcmVkaWNhdGVfcGFydF8yKSApCiAgICAgICAgewogICAgICAgICAgICBjb25zdCBPU1FMUGFyc2VOb2RlKiBwT3RoZXIgPSBwUGFyZW50LT5nZXRQYXJlbnQoKS0+Z2V0Q2hpbGQoMCk7CiAgICAgICAgICAgIGlmICggU1FMX0lTUlVMRSggcE90aGVyLCBjb2x1bW5fcmVmICkgKQogICAgICAgICAgICAgICAgZ2V0Q29sdW1uUmFuZ2UoIHBPdGhlciwgc0NvbHVtbk5hbWUsIHNUYWJsZVJhbmdlLCBhQ29sdW1uQWxpYXMpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHBPdGhlci0+cGFyc2VOb2RlVG9TdHIoIHNDb2x1bW5OYW1lLCBtX3BJbXBsLT5tX3hDb25uZWN0aW9uLCBOVUxMLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSApOwogICAgICAgICAgICAgICAgbGNsX2dlbmVyYXRlUGFyYW1ldGVyTmFtZSggKnBQYXJlbnQsICpfcE5vZGUgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGlmICggcFBhcmVudC0+Z2V0Tm9kZVR5cGUoKSA9PSBTUUxfTk9ERV9DT01NQUxJU1RSVUxFICkKICAgICAgICB7CiAgICAgICAgICAgIGxjbF9nZW5lcmF0ZVBhcmFtZXRlck5hbWUoICpwUGFyZW50LCAqX3BOb2RlICk7CiAgICAgICAgfQogICAgfQogICAgdHJhdmVyc2VQYXJhbWV0ZXIoIF9wTm9kZSwgcFBhcmVudCwgc0NvbHVtbk5hbWUsIHNUYWJsZVJhbmdlLCBhQ29sdW1uQWxpYXMgKTsKICAgIGNvbnN0IHNhbF91SW50MzIgbkNvdW50ID0gX3BOb2RlLT5jb3VudCgpOwogICAgZm9yIChzYWxfdUludDMyIGkgPSAwOyBpIDwgbkNvdW50OyArK2kpCiAgICB7CiAgICAgICAgY29uc3QgT1NRTFBhcnNlTm9kZSogcENoaWxkICA9IF9wTm9kZS0+Z2V0Q2hpbGQoaSk7CiAgICAgICAgdHJhdmVyc2VQYXJhbWV0ZXJzKCBwQ2hpbGQgKTsKICAgIH0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZVNlbGVjdGlvbkNyaXRlcmlhKGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBTZWxlY3ROb2RlKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VTZWxlY3Rpb25Dcml0ZXJpYSIgKTsKCWlmICggcFNlbGVjdE5vZGUgPT0gTlVMTCApCgkJcmV0dXJuIGZhbHNlOwoKCgkvLyBQYXJzZSBUcmVlIGFuYWx5c2llcmVuIChqZSBuYWNoIFN0YXRlbWVudC1UeXApCgkvLyB1bmQgWmVpZ2VyIGF1ZiBXSEVSRS1LbGF1c2VsIHNldHplbjoKCU9TUUxQYXJzZU5vZGUgKiBwV2hlcmVDbGF1c2UgPSBOVUxMOwoKCWlmIChtX2VTdGF0ZW1lbnRUeXBlID09IFNRTF9TVEFURU1FTlRfU0VMRUNUKQoJewoJCWlmKFNRTF9JU1JVTEUocFNlbGVjdE5vZGUsdW5pb25fc3RhdGVtZW50KSkKCQl7CgkJCXJldHVybiAgdHJhdmVyc2VTZWxlY3Rpb25Dcml0ZXJpYSggcFNlbGVjdE5vZGUtPmdldENoaWxkKCAwICkgKQogICAgICAgICAgICAgICAgJiYgIHRyYXZlcnNlU2VsZWN0aW9uQ3JpdGVyaWEoIHBTZWxlY3ROb2RlLT5nZXRDaGlsZCggMyApICk7CgkJfQoJCU9TTF9FTlNVUkUocFNlbGVjdE5vZGUtPmNvdW50KCkgPj0gNCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoKCQlPU1FMUGFyc2VOb2RlICogcFRhYmxlRXhwID0gcFNlbGVjdE5vZGUtPmdldENoaWxkKDMpOwoJCU9TTF9FTlNVUkUocFRhYmxlRXhwICE9IE5VTEwsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCQlPU0xfRU5TVVJFKFNRTF9JU1JVTEUocFRhYmxlRXhwLHRhYmxlX2V4cCksIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCQlPU0xfRU5TVVJFKHBUYWJsZUV4cC0+Y291bnQoKSA9PSBUQUJMRV9FWFBSRVNTSU9OX0NISUxEX0NPVU5ULCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJCXBXaGVyZUNsYXVzZSA9IHBUYWJsZUV4cC0+Z2V0Q2hpbGQoMSk7Cgl9IGVsc2UgaWYgKFNRTF9JU1JVTEUocFNlbGVjdE5vZGUsdXBkYXRlX3N0YXRlbWVudF9zZWFyY2hlZCkpIHsKCQlPU0xfRU5TVVJFKHBTZWxlY3ROb2RlLT5jb3VudCgpID09IDUsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCQlwV2hlcmVDbGF1c2UgPSBwU2VsZWN0Tm9kZS0+Z2V0Q2hpbGQoNCk7Cgl9IGVsc2UgaWYgKFNRTF9JU1JVTEUocFNlbGVjdE5vZGUsZGVsZXRlX3N0YXRlbWVudF9zZWFyY2hlZCkpIHsKCQlPU0xfRU5TVVJFKHBTZWxlY3ROb2RlLT5jb3VudCgpID09IDQsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCQlwV2hlcmVDbGF1c2UgPSBwU2VsZWN0Tm9kZS0+Z2V0Q2hpbGQoMyk7Cgl9IGVsc2UgaWYgKFNRTF9JU1JVTEUocFNlbGVjdE5vZGUsZGVsZXRlX3N0YXRlbWVudF9wb3NpdGlvbmVkKSkgewoJCS8vIG55aQoJCU9TTF9BU1NFUlQoIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0U2VsZWN0aW9uQ3JpdGVyaWE6IHBvc2l0aW9uZWQgbnlpIik7Cgl9IGVsc2UgewoJCS8vIEFuZGVyZXMgU3RhdGVtZW50LiBLZWluZSBTZWxla3Rpb25za3JpdGVyaWVuLgoJCXJldHVybiBmYWxzZTsKCX0KCglpZiAoISBTUUxfSVNSVUxFKHBXaGVyZUNsYXVzZSx3aGVyZV9jbGF1c2UpKSB7CgkJLy8gRGllIFdoZXJlIENsYXVzZSBpc3QgbWVpc3RlbnMgb3B0aW9uYWwsIGQuIGguIGVzIGtvZW5udGUgc2ljaCBhdWNoCgkJLy8gdW0gIm9wdGlvbmFsX3doZXJlX2NsYXVzZSIgaGFuZGVsbi4KCQlPU0xfRU5TVVJFKFNRTF9JU1JVTEUocFdoZXJlQ2xhdXNlLG9wdF93aGVyZV9jbGF1c2UpLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8vIFdlbm4gZXMgYWJlciBlaW5lIHdoZXJlX2NsYXVzZSBpc3QsIGRhbm4gZGFyZiBzaWUgbmljaHQgbGVlciBzZWluOgoJT1NMX0VOU1VSRShwV2hlcmVDbGF1c2UtPmNvdW50KCkgPT0gMiwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoKCU9TUUxQYXJzZU5vZGUgKiBwQ29tcGFyaXNvblByZWRpY2F0ZSA9IHBXaGVyZUNsYXVzZS0+Z2V0Q2hpbGQoMSk7CglPU0xfRU5TVVJFKHBDb21wYXJpc29uUHJlZGljYXRlICE9IE5VTEwsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCgkvLwoJLy8gVW5kIG51biBkaWUgVmVyZ2xlaWNoc2tyaXRlcmllbiBhYmFyYmVpdGVuIChyZWt1cnNpdiwgYWxsZXMgaXN0IGVyc3RtYWwgZWluIE9SLUtyaXRlcml1bSk6CgkvLwoKCXRyYXZlcnNlT1JDcml0ZXJpYShwQ29tcGFyaXNvblByZWRpY2F0ZSk7CgogICAgcmV0dXJuICFoYXNFcnJvcnMoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VPUkNyaXRlcmlhKE9TUUxQYXJzZU5vZGUgKiBwU2VhcmNoQ29uZGl0aW9uKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VPUkNyaXRlcmlhIiApOwoKCglpZiAoCgkJCXBTZWFyY2hDb25kaXRpb24tPmNvdW50KCkgPT0gMyAmJgoJCQlTUUxfSVNQVU5DVFVBVElPTihwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSwiKCIpICYmCgkJCVNRTF9JU1BVTkNUVUFUSU9OKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDIpLCIpIikKCQkpCgl7CgkJLy8gUnVuZGUgS2xhbW1lcm4gdW0gZGVuIEF1c2RydWNrCgkJdHJhdmVyc2VPUkNyaXRlcmlhKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDEpKTsKCX0gZWxzZSBpZiAoU1FMX0lTUlVMRShwU2VhcmNoQ29uZGl0aW9uLHNlYXJjaF9jb25kaXRpb24pICYmCgkJcFNlYXJjaENvbmRpdGlvbi0+Y291bnQoKSA9PSAzICYmCgkJU1FMX0lTVE9LRU4ocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMSksT1IpKQoJewoJCS8vIE9SLVZlcmtudWVwZnVuZzoKCgkJZm9yIChpbnQgaSA9IDA7IGkgPCAzOyBpKyspIHsKCQkJaWYgKGkgPT0gMSkgY29udGludWU7CQkvLyBTY2hsdWVzc2Vsd29ydCBPUiB1ZWJlcnNwcmluZ2VuCgoJCQkvLyBJc3QgZGFzIGVyc3RlIEVsZW1lbnQgd2llZGVyIGVpbmUgT1ItVmVya251ZXBmdW5nPwoJCQlpZiAoaSA9PSAwICYmCgkJCQlTUUxfSVNSVUxFKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDApLHNlYXJjaF9jb25kaXRpb24pICYmCgkJCQlwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKS0+Y291bnQoKSA9PSAzICYmCgkJCQlTUUxfSVNUT0tFTihwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKS0+Z2V0Q2hpbGQoMSksT1IpKQoJCQl7CgkJCQkvLyBEYW5uIHJla3Vyc2l2IGFic3RlaWdlbiAuLi4KCQkJCXRyYXZlcnNlT1JDcml0ZXJpYShwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSk7CgoJCQl9IGVsc2UgewoJCQkJLy8gQU5ELUtyaXRlcmllbiAuLi4KCQkJCXRyYXZlcnNlQU5EQ3JpdGVyaWEocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoaSkpOwoJCQkJLy8JaWYgKCEgYUl0ZXJhdG9yU3RhdHVzLklzU3VjY2Vzc2Z1bCgpKSBicmVhazsKCQkJfQoKCQkJLy8JaWYgKCEgYUl0ZXJhdG9yU3RhdHVzLklzU3VjY2Vzc2Z1bCgpKSBicmVhazsKCQl9Cgl9IGVsc2UgewoJCS8vIE51ciAqZWluKiBLcml0ZXJpdW0gb2RlciBlaW5lIEFORC1WZXJrbnVlcGZ1bmcgdm9uIEtyaXRlcmllbi4KCQkvLyBEaXJla3QgZGllIEFORC1Lcml0ZXJpZW4gYmVoYW5kZWxuLgoJCXRyYXZlcnNlQU5EQ3JpdGVyaWEocFNlYXJjaENvbmRpdGlvbik7CgkJLy8JaWYgKCEgYUl0ZXJhdG9yU3RhdHVzLklzU3VjY2Vzc2Z1bCgpKSByZXR1cm47Cgl9CgoJLy8gRmVobGVyIGVpbmZhY2ggd2VpdGVycmVpY2hlbi4KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VBTkRDcml0ZXJpYShPU1FMUGFyc2VOb2RlICogcFNlYXJjaENvbmRpdGlvbikKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlQU5EQ3JpdGVyaWEiICk7CgoKCWlmICgKCQkJU1FMX0lTUlVMRShwU2VhcmNoQ29uZGl0aW9uLGJvb2xlYW5fcHJpbWFyeSkgJiYKCQkJcFNlYXJjaENvbmRpdGlvbi0+Y291bnQoKSA9PSAzICYmCgkJCVNRTF9JU1BVTkNUVUFUSU9OKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDApLCIoIikgJiYKCQkJU1FMX0lTUFVOQ1RVQVRJT04ocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMiksIikiKQoJCSkKCXsKCQkvLyBSdW5kZSBLbGFtbWVybgoJCXRyYXZlcnNlQU5EQ3JpdGVyaWEocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMSkpOwoJfQoJLy8gRGFzIGVyc3RlIEVsZW1lbnQgaXN0IGVpbmUgT1ItVmVya251ZXBmdW5nCgllbHNlICBpZiAoIFNRTF9JU1JVTEUocFNlYXJjaENvbmRpdGlvbixzZWFyY2hfY29uZGl0aW9uKSAmJiBwU2VhcmNoQ29uZGl0aW9uLT5jb3VudCgpID09IDMgKQoJewoJCS8vIERhbm4gcmVrdXJzaXYgYWJzdGVpZ2VuIChkaWVzZWxiZSBSb3cgYmVudXR6ZW4pIC4uLgoJCXRyYXZlcnNlT1JDcml0ZXJpYShwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSk7Ci8vCQlpZiAoISBhSXRlcmF0b3JTdGF0dXMuSXNTdWNjZXNzZnVsKCkpCi8vCQkJcmV0dXJuOwoKCQkvLyBVbmQgbWl0IGRlbSByZWNodGVuIENoaWxkIHdlaXRlcm1hY2hlbjoKCQl0cmF2ZXJzZUFORENyaXRlcmlhKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDIpKTsKCX0KCS8vIERhcyBlcnN0ZSBFbGVtZW50IGlzdCAod2llZGVyKSBlaW5lIEFORC1WZXJrbnVlcGZ1bmcKCWVsc2UgaWYgKCBTUUxfSVNSVUxFKHBTZWFyY2hDb25kaXRpb24sYm9vbGVhbl90ZXJtKSAmJiBwU2VhcmNoQ29uZGl0aW9uLT5jb3VudCgpID09IDMgKQoJewoJCS8vIERhbm4gcmVrdXJzaXYgYWJzdGVpZ2VuIChkaWVzZWxiZSBSb3cgYmVudXR6ZW4pIC4uLgoJCXRyYXZlcnNlQU5EQ3JpdGVyaWEocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCkpOwovLwkJaWYgKCEgYUl0ZXJhdG9yU3RhdHVzLklzU3VjY2Vzc2Z1bCgpKQovLwkJCXJldHVybjsKCgkJLy8gVW5kIG1pdCBkZW0gcmVjaHRlbiBDaGlsZCB3ZWl0ZXJtYWNoZW46CgkJdHJhdmVyc2VBTkRDcml0ZXJpYShwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgyKSk7Cgl9CgkgLy8gU29uc3QgZWluemVsbmUgU3VjaGtyaXRlcmllbiB3aWUgPSwgIT0sIC4uLiwgTElLRSwgSVMgTlVMTCB1c3cuIGJlaGFuZGVsbjoKCWVsc2UgaWYgKFNRTF9JU1JVTEUocFNlYXJjaENvbmRpdGlvbixjb21wYXJpc29uX3ByZWRpY2F0ZSkgKQoJewoJCTo6cnRsOjpPVVN0cmluZyBhVmFsdWU7CgkJcFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMiktPnBhcnNlTm9kZVRvU3RyKCBhVmFsdWUsIG1fcEltcGwtPm1feENvbm5lY3Rpb24sIE5VTEwsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlICk7CgkJdHJhdmVyc2VPbmVQcmVkaWNhdGUocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksYVZhbHVlLHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDIpKTsKICAgICAgICBpbXBsX2ZpbGxKb2luQ29uZGl0aW9ucyhwU2VhcmNoQ29uZGl0aW9uKTsKLy8JCWlmICghIGFJdGVyYXRvclN0YXR1cy5Jc1N1Y2Nlc3NmdWwoKSkKLy8JCQlyZXR1cm47Cgl9CgllbHNlIGlmIChTUUxfSVNSVUxFKHBTZWFyY2hDb25kaXRpb24sbGlrZV9wcmVkaWNhdGUpIC8qJiYgU1FMX0lTUlVMRShwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSxjb2x1bW5fcmVmKSovKQoJewoJCU9TTF9FTlNVUkUocFNlYXJjaENvbmRpdGlvbi0+Y291bnQoKSA9PSAyLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CiAgICAgICAgY29uc3QgT1NRTFBhcnNlTm9kZSogcFBhcnQyID0gcFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMSk7CgoJCXNhbF9JbnQzMiBuQ3VyZW50UG9zID0gcFBhcnQyLT5jb3VudCgpLTI7CgoJCU9TUUxQYXJzZU5vZGUgKiBwTnVtX3ZhbHVlX2V4cAk9IHBQYXJ0Mi0+Z2V0Q2hpbGQobkN1cmVudFBvcyk7CgkJT1NRTFBhcnNlTm9kZSAqIHBPcHRFc2NhcGUJCT0gcFBhcnQyLT5nZXRDaGlsZChuQ3VyZW50UG9zKzEpOwoKCQlPU0xfRU5TVVJFKHBOdW1fdmFsdWVfZXhwICE9IE5VTEwsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCQlPU0xfRU5TVVJFKHBPcHRFc2NhcGUgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoKCQlpZiAocE9wdEVzY2FwZS0+Y291bnQoKSAhPSAwKQoJCXsKCQkJLy8JYUl0ZXJhdG9yU3RhdHVzLnNldFN0YXRlbWVudFRvb0NvbXBsZXgoKTsKCQkJcmV0dXJuOwoJCX0KCgkJOjpydGw6Ok9VU3RyaW5nIGFWYWx1ZTsKCQlPU1FMUGFyc2VOb2RlICogcFBhcmFtID0gTlVMTDsKCQlpZiAoU1FMX0lTUlVMRShwTnVtX3ZhbHVlX2V4cCxwYXJhbWV0ZXIpKQoJCQlwUGFyYW0gPSBwTnVtX3ZhbHVlX2V4cDsKCQllbHNlIGlmKHBOdW1fdmFsdWVfZXhwLT5pc1Rva2VuKCkpCgkJCS8vIE5vcm1hbGVyIFdlcnQKCQkJYVZhbHVlID0gcE51bV92YWx1ZV9leHAtPmdldFRva2VuVmFsdWUoKTsKCQllbHNlCgkJewoJCQlwTnVtX3ZhbHVlX2V4cC0+cGFyc2VOb2RlVG9TdHIoIGFWYWx1ZSwgbV9wSW1wbC0+bV94Q29ubmVjdGlvbiwgTlVMTCwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgKTsKCQkJcFBhcmFtID0gcE51bV92YWx1ZV9leHA7CgkJfQoKCQl0cmF2ZXJzZU9uZVByZWRpY2F0ZShwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSxhVmFsdWUscFBhcmFtKTsKLy8JCWlmICghIGFJdGVyYXRvclN0YXR1cy5Jc1N1Y2Nlc3NmdWwoKSkKLy8JCQlyZXR1cm47Cgl9CgllbHNlIGlmIChTUUxfSVNSVUxFKHBTZWFyY2hDb25kaXRpb24saW5fcHJlZGljYXRlKSkKCXsKCQlPU0xfRU5TVVJFKHBTZWFyY2hDb25kaXRpb24tPmNvdW50KCkgPT0gMiwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwogICAgICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBQYXJ0MiA9IHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDEpOwoKCQl0cmF2ZXJzZU9SQ3JpdGVyaWEocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCkpOwoJCS8vCWlmICghIGFJdGVyYXRvclN0YXR1cy5Jc1N1Y2Nlc3NmdWwoKSkgcmV0dXJuOwoKCQlPU1FMUGFyc2VOb2RlKiBwQ2hpbGQgPSBwUGFydDItPmdldENoaWxkKDIpOwoJCWlmICggU1FMX0lTUlVMRShwQ2hpbGQtPmdldENoaWxkKDApLHN1YnF1ZXJ5KSApCgkJewoJCQl0cmF2ZXJzZVRhYmxlTmFtZXMoICptX3BJbXBsLT5tX3BTdWJUYWJsZXMgKTsKCQkJdHJhdmVyc2VTZWxlY3Rpb25Dcml0ZXJpYShwQ2hpbGQtPmdldENoaWxkKDApLT5nZXRDaGlsZCgxKSk7CgkJfQoJCWVsc2UKCQl7IC8vICcoJyB2YWx1ZV9leHBfY29tbWFsaXN0ICcpJwoJCQlwQ2hpbGQgPSBwQ2hpbGQtPmdldENoaWxkKDEpOwoJCQlzYWxfSW50MzIgbkNvdW50ID0gcENoaWxkLT5jb3VudCgpOwoJCQlmb3IgKHNhbF9JbnQzMiBpPTA7IGkgPCBuQ291bnQ7ICsraSkKCQkJewoJCQkJdHJhdmVyc2VBTkRDcml0ZXJpYShwQ2hpbGQtPmdldENoaWxkKGkpKTsKCQkJfQoJCX0KCX0KCWVsc2UgaWYgKFNRTF9JU1JVTEUocFNlYXJjaENvbmRpdGlvbix0ZXN0X2Zvcl9udWxsKSAvKiYmIFNRTF9JU1JVTEUocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksY29sdW1uX3JlZikqLykKCXsKCQlPU0xfRU5TVVJFKHBTZWFyY2hDb25kaXRpb24tPmNvdW50KCkgPT0gMiwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwogICAgICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBQYXJ0MiA9IHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDEpOwogICAgICAgICh2b2lkKXBQYXJ0MjsKCQlPU0xfRU5TVVJFKFNRTF9JU1RPS0VOKHBQYXJ0Mi0+Z2V0Q2hpbGQoMCksSVMpLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJCTo6cnRsOjpPVVN0cmluZyBhU3RyaW5nOwoJCXRyYXZlcnNlT25lUHJlZGljYXRlKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDApLGFTdHJpbmcsTlVMTCk7CgkJLy8JaWYgKCEgYUl0ZXJhdG9yU3RhdHVzLklzU3VjY2Vzc2Z1bCgpKSByZXR1cm47Cgl9CgllbHNlIGlmIChTUUxfSVNSVUxFKHBTZWFyY2hDb25kaXRpb24sbnVtX3ZhbHVlX2V4cCkgfHwgU1FMX0lTUlVMRShwU2VhcmNoQ29uZGl0aW9uLHRlcm0pKQoJewoJCTo6cnRsOjpPVVN0cmluZyBhU3RyaW5nOwoJCXRyYXZlcnNlT25lUHJlZGljYXRlKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDApLGFTdHJpbmcscFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCkpOwoJCXRyYXZlcnNlT25lUHJlZGljYXRlKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDIpLGFTdHJpbmcscFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMikpOwoJfQoJLy8gRmVobGVyIGVpbmZhY2ggd2VpdGVycmVpY2hlbi4KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZVBhcmFtZXRlcihjb25zdCBPU1FMUGFyc2VOb2RlKiBfcFBhcnNlTm9kZQoJCQkJCQkJCQkJCSAgLGNvbnN0IE9TUUxQYXJzZU5vZGUqIF9wUGFyZW50Tm9kZQoJCQkJCQkJCQkJCSAgLGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgX2FDb2x1bW5OYW1lCgkJCQkJCQkJCQkJICAsY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBfYVRhYmxlUmFuZ2UKCQkJCQkJCQkJCQkgICxjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIF9yQ29sdW1uQWxpYXMpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZVBhcmFtZXRlciIgKTsKCWlmICggIVNRTF9JU1JVTEUoIF9wUGFyc2VOb2RlLCBwYXJhbWV0ZXIgKSApCiAgICAgICAgcmV0dXJuOwoKICAgIGlmICggKCBtX3BJbXBsLT5tX25JbmNsdWRlTWFzayAmIFBhcmFtZXRlcnMgKSAhPSBQYXJhbWV0ZXJzICkKICAgICAgICAvLyBwYXJhbWV0ZXJzIG5vdCB0byBiZSBpbmNsdWRlZCBpbiB0aGUgdHJhdmVyc2FsCiAgICAgICAgcmV0dXJuOwoKCU9TTF9FTlNVUkUoX3BQYXJzZU5vZGUtPmNvdW50KCkgPiAwLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CglPU1FMUGFyc2VOb2RlICogcE1hcmsgPSBfcFBhcnNlTm9kZS0+Z2V0Q2hpbGQoMCk7Cgk6OnJ0bDo6T1VTdHJpbmcgc1BhcmFtZXRlck5hbWU7CgoJaWYgKFNRTF9JU1BVTkNUVUFUSU9OKHBNYXJrLCI/IikpCgl7CiAgICAgICAgc1BhcmFtZXRlck5hbWUgPSAgICBfckNvbHVtbkFsaWFzLmdldExlbmd0aCgpCiAgICAgICAgICAgICAgICAgICAgICAgID8gICBfckNvbHVtbkFsaWFzCiAgICAgICAgICAgICAgICAgICAgICAgIDogICBfYUNvbHVtbk5hbWUuZ2V0TGVuZ3RoKCkKICAgICAgICAgICAgICAgICAgICAgICAgPyAgIF9hQ29sdW1uTmFtZQogICAgICAgICAgICAgICAgICAgICAgICA6ICAgOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIj8iKTsKCX0KCWVsc2UgaWYgKFNRTF9JU1BVTkNUVUFUSU9OKHBNYXJrLCI6IikpCgl7CgkJc1BhcmFtZXRlck5hbWUgPSBfcFBhcnNlTm9kZS0+Z2V0Q2hpbGQoMSktPmdldFRva2VuVmFsdWUoKTsKCX0KCWVsc2UgaWYgKFNRTF9JU1BVTkNUVUFUSU9OKHBNYXJrLCJbIikpCgl7CgkJc1BhcmFtZXRlck5hbWUgPSBfcFBhcnNlTm9kZS0+Z2V0Q2hpbGQoMSktPmdldFRva2VuVmFsdWUoKTsKCX0KCWVsc2UKCXsKCQlPU0xfQVNTRVJUKCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7Cgl9CgoJLy8gZm91bmQgYSBwYXJhbWV0ZXIKCWlmICggX3BQYXJlbnROb2RlICYmIChTUUxfSVNSVUxFKF9wUGFyZW50Tm9kZSxnZW5lcmFsX3NldF9mY3QpIHx8IFNRTF9JU1JVTEUoX3BQYXJlbnROb2RlLHNldF9mY3Rfc3BlYykpICkKCXsvLyBmb3VuZCBhIGZ1bmN0aW9uIGFzIGNvbHVtbl9yZWYKCQk6OnJ0bDo6T1VTdHJpbmcgc0Z1bmN0aW9uTmFtZTsKCQlfcFBhcmVudE5vZGUtPmdldENoaWxkKDApLT5wYXJzZU5vZGVUb1N0ciggc0Z1bmN0aW9uTmFtZSwgbV9wSW1wbC0+bV94Q29ubmVjdGlvbiwgTlVMTCwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgKTsKICAgICAgICBjb25zdCBzYWxfdUludDMyIG5Db3VudCA9IF9wUGFyZW50Tm9kZS0+Y291bnQoKTsKICAgICAgICBzYWxfdUludDMyIGkgPSAwOwogICAgICAgIGZvcig7IGkgPCBuQ291bnQ7KytpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCBfcFBhcmVudE5vZGUtPmdldENoaWxkKGkpID09IF9wUGFyc2VOb2RlICkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBzYWxfSW50MzIgblR5cGUgPSA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlcjo6Z2V0RnVuY3Rpb25QYXJhbWV0ZXJUeXBlKCBfcFBhcmVudE5vZGUtPmdldENoaWxkKDApLT5nZXRUb2tlbklEKCksIGktMSk7CgoJCU9QYXJzZUNvbHVtbiogcENvbHVtbiA9IG5ldyBPUGFyc2VDb2x1bW4oCXNQYXJhbWV0ZXJOYW1lLAoJCQkJCQkJCQkJCQkJOjpydGw6Ok9VU3RyaW5nKCksCgkJCQkJCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZygpLAoJCQkJCQkJCQkJCQkJQ29sdW1uVmFsdWU6Ok5VTExBQkxFX1VOS05PV04sCgkJCQkJCQkJCQkJCQkwLAoJCQkJCQkJCQkJCQkJMCwKCQkJCQkJCQkJCQkJCW5UeXBlLAoJCQkJCQkJCQkJCQkJc2FsX0ZhbHNlLAoJCQkJCQkJCQkJCQkJc2FsX0ZhbHNlLAoJCQkJCQkJCQkJCQkJaXNDYXNlU2Vuc2l0aXZlKCkpOwoJCXBDb2x1bW4tPnNldEZ1bmN0aW9uKHNhbF9UcnVlKTsKCQlwQ29sdW1uLT5zZXRBZ2dyZWdhdGVGdW5jdGlvbihzYWxfVHJ1ZSk7CgkJcENvbHVtbi0+c2V0UmVhbE5hbWUoc0Z1bmN0aW9uTmFtZSk7CgkJbV9hUGFyYW1ldGVycy0+Z2V0KCkucHVzaF9iYWNrKHBDb2x1bW4pOwoJfQoJZWxzZQoJewoJCXNhbF9Cb29sIGJOb3RGb3VuZCA9IHNhbF9UcnVlOwoJCU9TUUxDb2x1bW5zOjpWZWN0b3I6OmNvbnN0X2l0ZXJhdG9yIGFJdGVyID0gOjpjb25uZWN0aXZpdHk6OmZpbmQoCiAgICAgICAgICAgIG1fYVNlbGVjdENvbHVtbnMtPmdldCgpLmJlZ2luKCksCiAgICAgICAgICAgIG1fYVNlbGVjdENvbHVtbnMtPmdldCgpLmVuZCgpLAogICAgICAgICAgICBfYUNvbHVtbk5hbWUsOjpjb21waGVscGVyOjpVU3RyaW5nTWl4RXF1YWwoIGlzQ2FzZVNlbnNpdGl2ZSgpICkKICAgICAgICApOwoJCWlmKGFJdGVyICE9IG1fYVNlbGVjdENvbHVtbnMtPmdldCgpLmVuZCgpKQoJCXsKCQkJT1BhcnNlQ29sdW1uKiBwTmV3Q29sdW1uID0gbmV3IE9QYXJzZUNvbHVtbigqYUl0ZXIsaXNDYXNlU2Vuc2l0aXZlKCkpOwogICAgICAgICAgICBwTmV3Q29sdW1uLT5zZXROYW1lKHNQYXJhbWV0ZXJOYW1lKTsKCQkJcE5ld0NvbHVtbi0+c2V0UmVhbE5hbWUoX2FDb2x1bW5OYW1lKTsKCQkJbV9hUGFyYW1ldGVycy0+Z2V0KCkucHVzaF9iYWNrKHBOZXdDb2x1bW4pOwoJCQliTm90Rm91bmQgPSBzYWxfRmFsc2U7CgkJfQoJCWVsc2UgaWYoX2FDb2x1bW5OYW1lLmdldExlbmd0aCgpKS8vIHNlYXJjaCBpbiB0aGUgdGFibGVzIGZvciB0aGUgcmlnaHQgb25lCgkJewoKCQkJUmVmZXJlbmNlPFhQcm9wZXJ0eVNldD4geENvbHVtbiA9IGZpbmRDb2x1bW4oIF9hQ29sdW1uTmFtZSwgX2FUYWJsZVJhbmdlLCB0cnVlICk7CgoJCQlpZiAoIHhDb2x1bW4uaXMoKSApCgkJCXsKCQkJCU9QYXJzZUNvbHVtbiogcE5ld0NvbHVtbiA9IG5ldyBPUGFyc2VDb2x1bW4oeENvbHVtbixpc0Nhc2VTZW5zaXRpdmUoKSk7CgkJCQlwTmV3Q29sdW1uLT5zZXROYW1lKHNQYXJhbWV0ZXJOYW1lKTsKCQkJCXBOZXdDb2x1bW4tPnNldFJlYWxOYW1lKF9hQ29sdW1uTmFtZSk7CgkJCQltX2FQYXJhbWV0ZXJzLT5nZXQoKS5wdXNoX2JhY2socE5ld0NvbHVtbik7CgkJCQliTm90Rm91bmQgPSBzYWxfRmFsc2U7CgkJCX0KCQl9CgkJaWYgKCBiTm90Rm91bmQgKQoJCXsKICAgICAgICAgICAgc2FsX0ludDMyIG5UeXBlID0gRGF0YVR5cGU6OlZBUkNIQVI7CiAgICAgICAgICAgIE9TUUxQYXJzZU5vZGUqIHBQYXJlbnQgPSBfcFBhcmVudE5vZGUgPyBfcFBhcmVudE5vZGUtPmdldFBhcmVudCgpIDogTlVMTDsKICAgICAgICAgICAgaWYgKCBwUGFyZW50ICYmIChTUUxfSVNSVUxFKHBQYXJlbnQsZ2VuZXJhbF9zZXRfZmN0KSB8fCBTUUxfSVNSVUxFKHBQYXJlbnQsc2V0X2ZjdF9zcGVjKSkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb25zdCBzYWxfdUludDMyIG5Db3VudCA9IF9wUGFyZW50Tm9kZS0+Y291bnQoKTsKICAgICAgICAgICAgICAgIHNhbF91SW50MzIgaSA9IDA7CiAgICAgICAgICAgICAgICBmb3IoOyBpIDwgbkNvdW50OysraSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIF9wUGFyZW50Tm9kZS0+Z2V0Q2hpbGQoaSkgPT0gX3BQYXJzZU5vZGUgKQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5UeXBlID0gOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZXI6OmdldEZ1bmN0aW9uUGFyYW1ldGVyVHlwZSggcFBhcmVudC0+Z2V0Q2hpbGQoMCktPmdldFRva2VuSUQoKSwgaSsxKTsKICAgICAgICAgICAgfQoKCQkJOjpydGw6Ok9VU3RyaW5nIGFOZXdDb2xOYW1lKCBnZXRVbmlxdWVDb2x1bW5OYW1lKCBzUGFyYW1ldGVyTmFtZSApICk7CgoJCQlPUGFyc2VDb2x1bW4qIHBDb2x1bW4gPSBuZXcgT1BhcnNlQ29sdW1uKGFOZXdDb2xOYW1lLAoJCQkJCQkJCQkJCQkJOjpydGw6Ok9VU3RyaW5nKCksCgkJCQkJCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZygpLAoJCQkJCQkJCQkJCQkJQ29sdW1uVmFsdWU6Ok5VTExBQkxFX1VOS05PV04sCgkJCQkJCQkJCQkJCQkwLAoJCQkJCQkJCQkJCQkJMCwKCQkJCQkJCQkJCQkJCW5UeXBlLAoJCQkJCQkJCQkJCQkJc2FsX0ZhbHNlLAoJCQkJCQkJCQkJCQkJc2FsX0ZhbHNlLAoJCQkJCQkJCQkJCQkJaXNDYXNlU2Vuc2l0aXZlKCkgKTsKCQkJcENvbHVtbi0+c2V0TmFtZShhTmV3Q29sTmFtZSk7CgkJCXBDb2x1bW4tPnNldFJlYWxOYW1lKHNQYXJhbWV0ZXJOYW1lKTsKCQkJbV9hUGFyYW1ldGVycy0+Z2V0KCkucHVzaF9iYWNrKHBDb2x1bW4pOwoJCX0KCX0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZU9uZVByZWRpY2F0ZSgKCQkJCQkJCQlPU1FMUGFyc2VOb2RlICogcENvbHVtblJlZiwKCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcmIHJWYWx1ZSwKCQkJCQkJCQlPU1FMUGFyc2VOb2RlICogcFBhcnNlTm9kZSkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlT25lUHJlZGljYXRlIiApOwoJaWYgKCAhcFBhcnNlTm9kZSApCiAgICAgICAgcmV0dXJuOwoKCS8vIENvbHVtbi1OYW1lICh1bmQgVGFibGVSYW5nZSk6Cgk6OnJ0bDo6T1VTdHJpbmcgYUNvbHVtbk5hbWUsIGFUYWJsZVJhbmdlLCBzQ29sdW1uQWxpYXM7CglnZXRDb2x1bW5SYW5nZSggcENvbHVtblJlZiwgYUNvbHVtbk5hbWUsIGFUYWJsZVJhbmdlLCBzQ29sdW1uQWxpYXMpOwoKCTo6cnRsOjpPVVN0cmluZyBhTmFtZTsKCiAgICAvKmlmIChTUUxfSVNSVUxFKHBQYXJzZU5vZGUscGFyYW1ldGVyKSkKCQl0cmF2ZXJzZVBhcmFtZXRlciggcFBhcnNlTm9kZSwgcENvbHVtblJlZiwgYUNvbHVtbk5hbWUsIGFUYWJsZVJhbmdlLCBzQ29sdW1uQWxpYXMgKTsKCWVsc2UgKi9pZiAoU1FMX0lTUlVMRShwUGFyc2VOb2RlLGNvbHVtbl9yZWYpKS8vIENvbHVtbi1OYW1lICh1bmQgVGFibGVSYW5nZSk6CgkJZ2V0Q29sdW1uUmFuZ2UocFBhcnNlTm9kZSxhTmFtZSxyVmFsdWUpOwoJZWxzZQoJewoJCXRyYXZlcnNlT1JDcml0ZXJpYShwUGFyc2VOb2RlKTsKCQkvLwlpZiAoISBhSXRlcmF0b3JTdGF0dXMuSXNTdWNjZXNzZnVsKCkpIHJldHVybjsKCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VTb21lKCBzYWxfdUludDMyIF9uSW5jbHVkZU1hc2sgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VTb21lIiApOwogICAgaW1wbF90cmF2ZXJzZSggX25JbmNsdWRlTWFzayApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZUFsbCgpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZUFsbCIgKTsKICAgIGltcGxfdHJhdmVyc2UoIEFsbCApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppbXBsX3RyYXZlcnNlKCBzYWxfdUludDMyIF9uSW5jbHVkZU1hc2sgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6aW1wbF90cmF2ZXJzZSIgKTsKICAgIGltcGxfcmVzZXRFcnJvcnMoKTsKICAgIG1fcEltcGwtPm1fbkluY2x1ZGVNYXNrID0gX25JbmNsdWRlTWFzazsKCglpZiAoICF0cmF2ZXJzZVRhYmxlTmFtZXMoICptX3BJbXBsLT5tX3BUYWJsZXMgKSApCiAgICAgICAgcmV0dXJuOwoKICAgIHN3aXRjaCAoIG1fZVN0YXRlbWVudFR5cGUgKQogICAgewogICAgY2FzZSBTUUxfU1RBVEVNRU5UX1NFTEVDVDoKCXsKCQljb25zdCBPU1FMUGFyc2VOb2RlKiBwU2VsZWN0Tm9kZSA9IG1fcFBhcnNlVHJlZTsKICAgICAgICB0cmF2ZXJzZVBhcmFtZXRlcnMoIHBTZWxlY3ROb2RlICk7CgkJaWYgICggICAhdHJhdmVyc2VTZWxlY3RDb2x1bW5OYW1lcyggcFNlbGVjdE5vZGUgKQogICAgICAgICAgICB8fCAgIXRyYXZlcnNlT3JkZXJCeUNvbHVtbk5hbWVzKCBwU2VsZWN0Tm9kZSApCiAgICAgICAgICAgIHx8ICAhdHJhdmVyc2VHcm91cEJ5Q29sdW1uTmFtZXMoIHBTZWxlY3ROb2RlICkKICAgICAgICAgICAgfHwgICF0cmF2ZXJzZVNlbGVjdGlvbkNyaXRlcmlhKCBwU2VsZWN0Tm9kZSApCiAgICAgICAgICAgICkKICAgICAgICAgICAgcmV0dXJuOwoJfQogICAgYnJlYWs7CiAgICBjYXNlIFNRTF9TVEFURU1FTlRfQ1JFQVRFX1RBQkxFOgogICAgewogICAgICAgIC8vMCAgICAgfCAgMSAgfCAgMiAgIHwzfCAgICAgICAgNCAgICAgICAgIHw1CiAgICAgICAgLy9jcmVhdGUgdGFibGUgc2MuZm9vICggYSBjaGFyKDIwKSwgYiBjaGFyICkKCQljb25zdCBPU1FMUGFyc2VOb2RlKiBwQ3JlYXRlTm9kZSA9IG1fcFBhcnNlVHJlZS0+Z2V0Q2hpbGQoNCk7CgkJdHJhdmVyc2VDcmVhdGVDb2x1bW5zKHBDcmVhdGVOb2RlKTsKCX0KICAgIGJyZWFrOwogICAgY2FzZSBTUUxfU1RBVEVNRU5UX0lOU0VSVDoKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgYnJlYWs7CiAgICB9Cn0KCi8vIER1bW15LUltcGxlbWVudGF0aW9uZW46CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk9TUUxUYWJsZSBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfY3JlYXRlVGFibGVPYmplY3QoIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgclRhYmxlTmFtZSwKICAgIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgckNhdGFsb2dOYW1lLCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIHJTY2hlbWFOYW1lICkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfY3JlYXRlVGFibGVPYmplY3QiICk7CiAgICBPU0xfUFJFQ09ORCggbV9lU3RhdGVtZW50VHlwZSA9PSBTUUxfU1RBVEVNRU5UX0NSRUFURV9UQUJMRSwKICAgICAgICAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppbXBsX2NyZWF0ZVRhYmxlT2JqZWN0OiBvbmx5IHRvIGJlIGNhbGxlZCBmb3IgQ1JFQVRFIFRBQkxFIHN0YXRlbWVudHMhIiApOwogICAgICAgIC8vIChpbiBhbGwgb3RoZXIgY2FzZXMsIG1fcFRhYmxlcyBpcyB0byBjb250YWluIHRoZSB0YWJsZSBvYmplY3RzIGFzIG9idGFpbmVkIGZyb20gdGhlIHRhYmxlcwogICAgICAgIC8vIGNvbnRhaW5lciBvZiB0aGUgY29ubmVjdGlvbiAobV94VGFibGVzQ29udGFpbmVyKQoKICAgIE9TUUxUYWJsZSBhUmV0dXJuVGFibGUgPSBuZXcgT1RhYmxlKAogICAgICAgIE5VTEwsCiAgICAgICAgc2FsX0ZhbHNlLAogICAgICAgIHJUYWJsZU5hbWUsCiAgICAgICAgOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlRhYmxlIiksCiAgICAgICAgOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIk5ldyBDcmVhdGVkIFRhYmxlIiksCiAgICAgICAgclNjaGVtYU5hbWUsCiAgICAgICAgckNhdGFsb2dOYW1lCiAgICApOwogICAgcmV0dXJuIGFSZXR1cm5UYWJsZTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjphcHBlbmRDb2x1bW5zKDo6dm9zOjpPUmVmPE9TUUxDb2x1bW5zPiYgX3JDb2x1bW5zLGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgX3JUYWJsZUFsaWFzLGNvbnN0IE9TUUxUYWJsZSYgX3JUYWJsZSkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmFwcGVuZENvbHVtbnMiICk7CgoJaWYgKCFfclRhYmxlLmlzKCkpCgkJcmV0dXJuOwoKCVJlZmVyZW5jZTxYTmFtZUFjY2Vzcz4geENvbHVtbnMgPSBfclRhYmxlLT5nZXRDb2x1bW5zKCk7CglpZiAoICF4Q29sdW1ucy5pcygpICkKCQlyZXR1cm47CgoJU2VxdWVuY2U8IDo6cnRsOjpPVVN0cmluZyA+IGFDb2xOYW1lcyA9ICB4Q29sdW1ucy0+Z2V0RWxlbWVudE5hbWVzKCk7Cgljb25zdCA6OnJ0bDo6T1VTdHJpbmcqIHBCZWdpbiA9IGFDb2xOYW1lcy5nZXRDb25zdEFycmF5KCk7Cgljb25zdCA6OnJ0bDo6T1VTdHJpbmcqIHBFbmQgPSBwQmVnaW4gKyBhQ29sTmFtZXMuZ2V0TGVuZ3RoKCk7CgoJZm9yKDtwQmVnaW4gIT0gcEVuZDsrK3BCZWdpbikKCXsKCgkJOjpydGw6Ok9VU3RyaW5nIGFOYW1lKGdldFVuaXF1ZUNvbHVtbk5hbWUoKnBCZWdpbikpOwoJCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geENvbHVtbjsKCQlpZih4Q29sdW1ucy0+aGFzQnlOYW1lKCpwQmVnaW4pICYmICh4Q29sdW1ucy0+Z2V0QnlOYW1lKCpwQmVnaW4pID4+PSB4Q29sdW1uKSAmJiB4Q29sdW1uLmlzKCkpCgkJewoJCQlPUGFyc2VDb2x1bW4qIHBDb2x1bW4gPSBuZXcgT1BhcnNlQ29sdW1uKGFOYW1lCgkJCQkJCQkJCQkJCSwJZ2V0U3RyaW5nKHhDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoUFJPUEVSVFlfSURfVFlQRU5BTUUpKSkKCQkJCQkJCQkJCQkJLAlnZXRTdHJpbmcoeENvbHVtbi0+Z2V0UHJvcGVydHlWYWx1ZShPTWV0YUNvbm5lY3Rpb246OmdldFByb3BNYXAoKS5nZXROYW1lQnlJbmRleChQUk9QRVJUWV9JRF9ERUZBVUxUVkFMVUUpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLAlnZXRTdHJpbmcoeENvbHVtbi0+Z2V0UHJvcGVydHlWYWx1ZShPTWV0YUNvbm5lY3Rpb246OmdldFByb3BNYXAoKS5nZXROYW1lQnlJbmRleChQUk9QRVJUWV9JRF9ERVNDUklQVElPTikpKQoJCQkJCQkJCQkJCQksCWdldElOVDMyKHhDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoUFJPUEVSVFlfSURfSVNOVUxMQUJMRSkpKQoJCQkJCQkJCQkJCQksCWdldElOVDMyKHhDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoUFJPUEVSVFlfSURfUFJFQ0lTSU9OKSkpCgkJCQkJCQkJCQkJCSwJZ2V0SU5UMzIoeENvbHVtbi0+Z2V0UHJvcGVydHlWYWx1ZShPTWV0YUNvbm5lY3Rpb246OmdldFByb3BNYXAoKS5nZXROYW1lQnlJbmRleChQUk9QRVJUWV9JRF9TQ0FMRSkpKQoJCQkJCQkJCQkJCQksCWdldElOVDMyKHhDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoUFJPUEVSVFlfSURfVFlQRSkpKQoJCQkJCQkJCQkJCQksCWdldEJPT0woeENvbHVtbi0+Z2V0UHJvcGVydHlWYWx1ZShPTWV0YUNvbm5lY3Rpb246OmdldFByb3BNYXAoKS5nZXROYW1lQnlJbmRleChQUk9QRVJUWV9JRF9JU0FVVE9JTkNSRU1FTlQpKSkKCQkJCQkJCQkJCQkJLAlnZXRCT09MKHhDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoUFJPUEVSVFlfSURfSVNDVVJSRU5DWSkpKQoJCQkJCQkJCQkJCQksCWlzQ2FzZVNlbnNpdGl2ZSgpICk7CgoJCQlwQ29sdW1uLT5zZXRUYWJsZU5hbWUoX3JUYWJsZUFsaWFzKTsKCQkJcENvbHVtbi0+c2V0UmVhbE5hbWUoKnBCZWdpbik7CgkJCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0PiB4Q29sID0gcENvbHVtbjsKCQkJX3JDb2x1bW5zLT5nZXQoKS5wdXNoX2JhY2soeENvbCk7CgkJfQoJCWVsc2UKICAgICAgICAgICAgaW1wbF9hcHBlbmRFcnJvciggSVBhcnNlQ29udGV4dDo6RVJST1JfSU5WQUxJRF9DT0xVTU4sIHBCZWdpbiwgJl9yVGFibGVBbGlhcyApOwoJfQp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnNldFNlbGVjdENvbHVtbk5hbWUoOjp2b3M6Ok9SZWY8T1NRTENvbHVtbnM+JiBfckNvbHVtbnMsY29uc3QgOjpydGw6Ok9VU3RyaW5nICYgckNvbHVtbk5hbWUsY29uc3QgOjpydGw6Ok9VU3RyaW5nICYgckNvbHVtbkFsaWFzLCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgJiByVGFibGVSYW5nZSxzYWxfQm9vbCBiRmt0LHNhbF9JbnQzMiBfblR5cGUsc2FsX0Jvb2wgYkFnZ0ZrdCkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnNldFNlbGVjdENvbHVtbk5hbWUiICk7CglpZihyQ29sdW1uTmFtZS50b0NoYXIoKSA9PSAnKicgJiYgIXJUYWJsZVJhbmdlLmdldExlbmd0aCgpKQoJeyAgIC8vIFNFTEVDVCAqIC4uLgoJCU9TTF9FTlNVUkUoX3JDb2x1bW5zID09IG1fYVNlbGVjdENvbHVtbnMsIkludmFsaWQgY29sdW1ucyB1c2VkIGhlcmUhIik7CgkJZm9yKENvbnN0T1NRTFRhYmxlc0l0ZXJhdG9yIGFJdGVyID0gbV9wSW1wbC0+bV9wVGFibGVzLT5iZWdpbigpOyBhSXRlciAhPSBtX3BJbXBsLT5tX3BUYWJsZXMtPmVuZCgpOysrYUl0ZXIpCgkJCWFwcGVuZENvbHVtbnMoX3JDb2x1bW5zLGFJdGVyLT5maXJzdCxhSXRlci0+c2Vjb25kKTsKCX0KCWVsc2UgaWYoIHJDb2x1bW5OYW1lLnRvQ2hhcigpID09ICcqJyAmJiByVGFibGVSYW5nZS5nZXRMZW5ndGgoKSApCgl7ICAgLy8gU0VMRUNUIDx0YWJsZT4uKgoJCU9TTF9FTlNVUkUoX3JDb2x1bW5zID09IG1fYVNlbGVjdENvbHVtbnMsIkludmFsaWQgY29sdW1ucyB1c2VkIGhlcmUhIik7CgkJQ29uc3RPU1FMVGFibGVzSXRlcmF0b3IgYUZpbmQgPSBtX3BJbXBsLT5tX3BUYWJsZXMtPmZpbmQoclRhYmxlUmFuZ2UpOwoKCQlpZihhRmluZCAhPSBtX3BJbXBsLT5tX3BUYWJsZXMtPmVuZCgpKQoJCQlhcHBlbmRDb2x1bW5zKF9yQ29sdW1ucyxyVGFibGVSYW5nZSxhRmluZC0+c2Vjb25kKTsKCX0KCWVsc2UgaWYgKCAhclRhYmxlUmFuZ2UuZ2V0TGVuZ3RoKCkgKQoJeyAgIC8vIFNFTEVDVCA8c29tZXRoaW5nPiAuLi4KICAgICAgICAvLyB3aXRob3V0IHRhYmxlIHNwZWNpZmllZAoJCWlmICggIWJGa3QgKQoJCXsKCQkJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQ+IHhOZXdDb2x1bW47CgogICAgICAgICAgICBmb3IgKCBPU1FMVGFibGVzSXRlcmF0b3IgYUl0ZXIgPSBtX3BJbXBsLT5tX3BUYWJsZXMtPmJlZ2luKCk7IGFJdGVyICE9IG1fcEltcGwtPm1fcFRhYmxlcy0+ZW5kKCk7ICsrYUl0ZXIgKQoJCQl7CgkJCQlpZiAoICFhSXRlci0+c2Vjb25kLmlzKCkgKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTxYTmFtZUFjY2Vzcz4geENvbHVtbnMgPSBhSXRlci0+c2Vjb25kLT5nZXRDb2x1bW5zKCk7CgkJCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhDb2x1bW47CgkJCQlpZiAgKCAgICF4Q29sdW1ucy0+aGFzQnlOYW1lKCByQ29sdW1uTmFtZSApCiAgICAgICAgICAgICAgICAgICAgfHwgICEoIHhDb2x1bW5zLT5nZXRCeU5hbWUoIHJDb2x1bW5OYW1lICkgPj49IHhDb2x1bW4gKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgYU5ld0NvbE5hbWUoZ2V0VW5pcXVlQ29sdW1uTmFtZShyQ29sdW1uQWxpYXMpKTsKCgkJCQlPUGFyc2VDb2x1bW4qIHBDb2x1bW4gPSBuZXcgT1BhcnNlQ29sdW1uKHhDb2x1bW4saXNDYXNlU2Vuc2l0aXZlKCkpOwoJCQkJeE5ld0NvbHVtbiA9IHBDb2x1bW47CgkJCQlwQ29sdW1uLT5zZXRUYWJsZU5hbWUoYUl0ZXItPmZpcnN0KTsKCQkJCXBDb2x1bW4tPnNldE5hbWUoYU5ld0NvbE5hbWUpOwoJCQkJcENvbHVtbi0+c2V0UmVhbE5hbWUockNvbHVtbk5hbWUpOwoKCQkJCWJyZWFrOwoJCQl9CgogICAgICAgICAgICBpZiAoICF4TmV3Q29sdW1uLmlzKCkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBubyBmdW5jdGlvbiAoZHVlIHRvIHRoZSBhYm92ZSAhYkZrdCksIG5vIGV4aXN0aW5nIGNvbHVtbgogICAgICAgICAgICAgICAgLy8gPT4gYXNzdW1lIGFuIGV4cHJlc3Npb24KICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZyBhTmV3Q29sTmFtZSggZ2V0VW5pcXVlQ29sdW1uTmFtZSggckNvbHVtbkFsaWFzICkgKTsKICAgICAgICAgICAgICAgIC8vIGRpZCBub3QgZmluZCBhIGNvbHVtbiB3aXRoIHRoaXMgbmFtZSBpbiBhbnkgb2YgdGhlIHRhYmxlcwoJCQkgICAgT1BhcnNlQ29sdW1uKiBwQ29sdW1uID0gbmV3IE9QYXJzZUNvbHVtbigKICAgICAgICAgICAgICAgICAgICBhTmV3Q29sTmFtZSwKICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSggIlZBUkNIQVIiICksCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IGRvZXMgdGhpcyBtYXRjaCB3aXRoIF9uVHlwZT8KICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3Igc2hvdWxkIGJlIGZpbGwgdGhpcyBmcm9tIHRoZSBnZXRUeXBlSW5mbyBvZiB0aGUgY29ubmVjdGlvbj8KICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICBDb2x1bW5WYWx1ZTo6TlVMTEFCTEVfVU5LTk9XTiwKICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgX25UeXBlLAogICAgICAgICAgICAgICAgICAgIHNhbF9GYWxzZSwKICAgICAgICAgICAgICAgICAgICBzYWxfRmFsc2UsCiAgICAgICAgICAgICAgICAgICAgaXNDYXNlU2Vuc2l0aXZlKCkKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgeE5ld0NvbHVtbiA9IHBDb2x1bW47CgkJCSAgICBwQ29sdW1uLT5zZXRSZWFsTmFtZSggckNvbHVtbk5hbWUgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgX3JDb2x1bW5zLT5nZXQoKS5wdXNoX2JhY2soIHhOZXdDb2x1bW4gKTsKCQl9CgkJZWxzZQoJCXsKCQkJOjpydGw6Ok9VU3RyaW5nIGFOZXdDb2xOYW1lKGdldFVuaXF1ZUNvbHVtbk5hbWUockNvbHVtbkFsaWFzKSk7CgoJCQlPUGFyc2VDb2x1bW4qIHBDb2x1bW4gPSBuZXcgT1BhcnNlQ29sdW1uKGFOZXdDb2xOYW1lLDo6cnRsOjpPVVN0cmluZygpLDo6cnRsOjpPVVN0cmluZygpLDo6cnRsOjpPVVN0cmluZygpLAoJCQkJQ29sdW1uVmFsdWU6Ok5VTExBQkxFX1VOS05PV04sMCwwLF9uVHlwZSxzYWxfRmFsc2Usc2FsX0ZhbHNlLGlzQ2FzZVNlbnNpdGl2ZSgpKTsKCQkJcENvbHVtbi0+c2V0RnVuY3Rpb24oc2FsX1RydWUpOwoJCQlwQ29sdW1uLT5zZXRBZ2dyZWdhdGVGdW5jdGlvbihiQWdnRmt0KTsKCQkJcENvbHVtbi0+c2V0UmVhbE5hbWUockNvbHVtbk5hbWUpOwoKCQkJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQ+IHhDb2wgPSBwQ29sdW1uOwoJCQlfckNvbHVtbnMtPmdldCgpLnB1c2hfYmFjayh4Q29sKTsKCQl9Cgl9CgllbHNlCS8vIENvbHVtbk5hbWUgdW5kIFRhYmxlbmFtZSB2b3JoYW5kZW4KCXsKCQlDb25zdE9TUUxUYWJsZXNJdGVyYXRvciBhRmluZCA9IG1fcEltcGwtPm1fcFRhYmxlcy0+ZmluZChyVGFibGVSYW5nZSk7CgoJCXNhbF9Cb29sIGJFcnJvciA9IHNhbF9GYWxzZTsKCQlpZiAoYUZpbmQgIT0gbV9wSW1wbC0+bV9wVGFibGVzLT5lbmQoKSAmJiBhRmluZC0+c2Vjb25kLmlzKCkpCgkJewoJCQlpZiAoYkZrdCkKCQkJewoJCQkJOjpydGw6Ok9VU3RyaW5nIGFOZXdDb2xOYW1lKGdldFVuaXF1ZUNvbHVtbk5hbWUockNvbHVtbkFsaWFzKSk7CgoJCQkJT1BhcnNlQ29sdW1uKiBwQ29sdW1uID0gbmV3IE9QYXJzZUNvbHVtbihhTmV3Q29sTmFtZSw6OnJ0bDo6T1VTdHJpbmcoKSw6OnJ0bDo6T1VTdHJpbmcoKSw6OnJ0bDo6T1VTdHJpbmcoKSwKCQkJCQlDb2x1bW5WYWx1ZTo6TlVMTEFCTEVfVU5LTk9XTiwwLDAsX25UeXBlLHNhbF9GYWxzZSxzYWxfRmFsc2UsaXNDYXNlU2Vuc2l0aXZlKCkpOwoJCQkJcENvbHVtbi0+c2V0RnVuY3Rpb24oc2FsX1RydWUpOwoJCQkJcENvbHVtbi0+c2V0QWdncmVnYXRlRnVuY3Rpb24oYkFnZ0ZrdCk7CgkJCQlwQ29sdW1uLT5zZXRSZWFsTmFtZShyQ29sdW1uTmFtZSk7CgkJCQlwQ29sdW1uLT5zZXRUYWJsZU5hbWUoYUZpbmQtPmZpcnN0KTsKCgkJCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldD4geENvbCA9IHBDb2x1bW47CgkJCQlfckNvbHVtbnMtPmdldCgpLnB1c2hfYmFjayh4Q29sKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geENvbHVtbjsKCQkJCWlmIChhRmluZC0+c2Vjb25kLT5nZXRDb2x1bW5zKCktPmhhc0J5TmFtZShyQ29sdW1uTmFtZSkgJiYgKGFGaW5kLT5zZWNvbmQtPmdldENvbHVtbnMoKS0+Z2V0QnlOYW1lKHJDb2x1bW5OYW1lKSA+Pj0geENvbHVtbikpCgkJCQl7CgkJCQkJOjpydGw6Ok9VU3RyaW5nIGFOZXdDb2xOYW1lKGdldFVuaXF1ZUNvbHVtbk5hbWUockNvbHVtbkFsaWFzKSk7CgoJCQkJCU9QYXJzZUNvbHVtbiogcENvbHVtbiA9IG5ldyBPUGFyc2VDb2x1bW4oeENvbHVtbixpc0Nhc2VTZW5zaXRpdmUoKSk7CgkJCQkJcENvbHVtbi0+c2V0TmFtZShhTmV3Q29sTmFtZSk7CgkJCQkJcENvbHVtbi0+c2V0UmVhbE5hbWUockNvbHVtbk5hbWUpOwoJCQkJCXBDb2x1bW4tPnNldFRhYmxlTmFtZShhRmluZC0+Zmlyc3QpOwoKCQkJCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldD4geENvbCA9IHBDb2x1bW47CgkJCQkJX3JDb2x1bW5zLT5nZXQoKS5wdXNoX2JhY2soeENvbCk7CgkJCQl9CgkJCQllbHNlCgkJCQkJYkVycm9yID0gc2FsX1RydWU7CgkJCX0KCQl9CgkJZWxzZQoJCQliRXJyb3IgPSBzYWxfVHJ1ZTsKCgkJLy8gVGFiZWxsZSBleGlzdGllcnQgbmljaHQgb2RlciBGZWxkIG5pY2h0IHZvcmhhbmRlbgoJCWlmIChiRXJyb3IpCgkJewoJCQk6OnJ0bDo6T1VTdHJpbmcgYU5ld0NvbE5hbWUoZ2V0VW5pcXVlQ29sdW1uTmFtZShyQ29sdW1uQWxpYXMpKTsKCgkJCU9QYXJzZUNvbHVtbiogcENvbHVtbiA9IG5ldyBPUGFyc2VDb2x1bW4oYU5ld0NvbE5hbWUsOjpydGw6Ok9VU3RyaW5nKCksOjpydGw6Ok9VU3RyaW5nKCksOjpydGw6Ok9VU3RyaW5nKCksCgkJCQlDb2x1bW5WYWx1ZTo6TlVMTEFCTEVfVU5LTk9XTiwwLDAsRGF0YVR5cGU6OlZBUkNIQVIsc2FsX0ZhbHNlLHNhbF9GYWxzZSxpc0Nhc2VTZW5zaXRpdmUoKSk7CgkJCXBDb2x1bW4tPnNldEZ1bmN0aW9uKHNhbF9UcnVlKTsKCQkJcENvbHVtbi0+c2V0QWdncmVnYXRlRnVuY3Rpb24oYkFnZ0ZrdCk7CgoJCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldD4geENvbCA9IHBDb2x1bW47CgkJCV9yQ29sdW1ucy0+Z2V0KCkucHVzaF9iYWNrKHhDb2wpOwoJCX0KCX0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6cnRsOjpPVVN0cmluZyBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldFVuaXF1ZUNvbHVtbk5hbWUoY29uc3QgOjpydGw6Ok9VU3RyaW5nICYgckNvbHVtbk5hbWUpCWNvbnN0CnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRVbmlxdWVDb2x1bW5OYW1lIiApOwoJOjpydGw6Ok9VU3RyaW5nIGFBbGlhcyhyQ29sdW1uTmFtZSk7CgoJT1NRTENvbHVtbnM6OlZlY3Rvcjo6Y29uc3RfaXRlcmF0b3IgYUl0ZXIgPSBmaW5kKAogICAgICAgIG1fYVNlbGVjdENvbHVtbnMtPmdldCgpLmJlZ2luKCksCiAgICAgICAgbV9hU2VsZWN0Q29sdW1ucy0+Z2V0KCkuZW5kKCksCiAgICAgICAgYUFsaWFzLAogICAgICAgIDo6Y29tcGhlbHBlcjo6VVN0cmluZ01peEVxdWFsKCBpc0Nhc2VTZW5zaXRpdmUoKSApCiAgICApOwoJc2FsX0ludDMyIGk9MTsKCXdoaWxlKGFJdGVyICE9IG1fYVNlbGVjdENvbHVtbnMtPmdldCgpLmVuZCgpKQoJewoJCShhQWxpYXMgPSByQ29sdW1uTmFtZSkgKz0gOjpydGw6Ok9VU3RyaW5nOjp2YWx1ZU9mKGkrKyk7CgkJYUl0ZXIgPSBmaW5kKAogICAgICAgICAgICBtX2FTZWxlY3RDb2x1bW5zLT5nZXQoKS5iZWdpbigpLAogICAgICAgICAgICBtX2FTZWxlY3RDb2x1bW5zLT5nZXQoKS5lbmQoKSwKICAgICAgICAgICAgYUFsaWFzLAogICAgICAgICAgICA6OmNvbXBoZWxwZXI6OlVTdHJpbmdNaXhFcXVhbCggaXNDYXNlU2Vuc2l0aXZlKCkgKQogICAgICAgICk7Cgl9CglyZXR1cm4gYUFsaWFzOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnNldE9yZGVyQnlDb2x1bW5OYW1lKGNvbnN0IDo6cnRsOjpPVVN0cmluZyAmIHJDb2x1bW5OYW1lLCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgJiByVGFibGVSYW5nZSxzYWxfQm9vbCBiQXNjZW5kaW5nKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6c2V0T3JkZXJCeUNvbHVtbk5hbWUiICk7CglSZWZlcmVuY2U8WFByb3BlcnR5U2V0PiB4Q29sdW1uID0gZmluZENvbHVtbiggckNvbHVtbk5hbWUsIHJUYWJsZVJhbmdlLCBmYWxzZSApOwoJaWYgKCB4Q29sdW1uLmlzKCkgKQoJCW1fYU9yZGVyQ29sdW1ucy0+Z2V0KCkucHVzaF9iYWNrKG5ldyBPT3JkZXJDb2x1bW4oIHhDb2x1bW4sIHJUYWJsZVJhbmdlLCBpc0Nhc2VTZW5zaXRpdmUoKSwgYkFzY2VuZGluZyApICk7CgllbHNlCgl7CgkJc2FsX0ludDMyIG5JZCA9IHJDb2x1bW5OYW1lLnRvSW50MzIoKTsKCQlpZiAoIG5JZCA+IDAgJiYgbklkIDwgc3RhdGljX2Nhc3Q8c2FsX0ludDMyPihtX2FTZWxlY3RDb2x1bW5zLT5nZXQoKS5zaXplKCkpICkKICAgICAgICAgICAgbV9hT3JkZXJDb2x1bW5zLT5nZXQoKS5wdXNoX2JhY2soIG5ldyBPT3JkZXJDb2x1bW4oICggbV9hU2VsZWN0Q29sdW1ucy0+Z2V0KCkgKVtuSWQtMV0sIGlzQ2FzZVNlbnNpdGl2ZSgpLCBiQXNjZW5kaW5nICkgKTsKCX0KCiNpZmRlZiBTUUxfVEVTVF9QQVJTRVRSRUVJVEVSQVRPUgoJY291dCA8PCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpzZXRPcmRlckJ5Q29sdW1uTmFtZTogIgoJCSA8PCAoY29uc3QgY2hhciAqKSByQ29sdW1uTmFtZSA8PCAiLCAiCgkJIDw8IChjb25zdCBjaGFyICopIHJUYWJsZVJhbmdlIDw8ICIsICIKCQkgPDwgKGJBc2NlbmRpbmcgPyAic2FsX1RydWUiIDogInNhbF9GYWxzZSIpCgkJIDw8ICJcbiI7CiNlbmRpZgp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnNldEdyb3VwQnlDb2x1bW5OYW1lKGNvbnN0IDo6cnRsOjpPVVN0cmluZyAmIHJDb2x1bW5OYW1lLCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgJiByVGFibGVSYW5nZSkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnNldEdyb3VwQnlDb2x1bW5OYW1lIiApOwoJUmVmZXJlbmNlPFhQcm9wZXJ0eVNldD4geENvbHVtbiA9IGZpbmRDb2x1bW4oIHJDb2x1bW5OYW1lLCByVGFibGVSYW5nZSwgZmFsc2UgKTsKCWlmICggeENvbHVtbi5pcygpICkKCQltX2FHcm91cENvbHVtbnMtPmdldCgpLnB1c2hfYmFjayhuZXcgT1BhcnNlQ29sdW1uKHhDb2x1bW4saXNDYXNlU2Vuc2l0aXZlKCkpKTsKCWVsc2UKCXsKCQlzYWxfSW50MzIgbklkID0gckNvbHVtbk5hbWUudG9JbnQzMigpOwoJCWlmICggbklkID4gMCAmJiBuSWQgPCBzdGF0aWNfY2FzdDxzYWxfSW50MzI+KG1fYVNlbGVjdENvbHVtbnMtPmdldCgpLnNpemUoKSkgKQoJCQltX2FHcm91cENvbHVtbnMtPmdldCgpLnB1c2hfYmFjayhuZXcgT1BhcnNlQ29sdW1uKChtX2FTZWxlY3RDb2x1bW5zLT5nZXQoKSlbbklkLTFdLGlzQ2FzZVNlbnNpdGl2ZSgpKSk7Cgl9CgojaWZkZWYgU1FMX1RFU1RfUEFSU0VUUkVFSVRFUkFUT1IKCWNvdXQgPDwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6c2V0T3JkZXJCeUNvbHVtbk5hbWU6ICIKCQkgPDwgKGNvbnN0IGNoYXIgKikgckNvbHVtbk5hbWUgPDwgIiwgIgoJCSA8PCAoY29uc3QgY2hhciAqKSByVGFibGVSYW5nZSA8PCAiLCAiCgkJIDw8IChiQXNjZW5kaW5nID8gInNhbF9UcnVlIiA6ICJzYWxfRmFsc2UiKQoJCSA8PCAiXG4iOwojZW5kaWYKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjb25zdCBPU1FMUGFyc2VOb2RlKiBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldFdoZXJlVHJlZSgpIGNvbnN0CnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRXaGVyZVRyZWUiICk7CgoKCWlmICghbV9wUGFyc2VUcmVlKQoJCXJldHVybiBOVUxMOwoKCS8vIFBhcnNlIFRyZWUgYW5hbHlzaWVyZW4gKGplIG5hY2ggU3RhdGVtZW50LVR5cCkKCS8vIHVuZCBaZWlnZXIgYXVmIFdIRVJFLUtsYXVzZWwgc2V0emVuOgoJT1NRTFBhcnNlTm9kZSAqIHBXaGVyZUNsYXVzZSA9IE5VTEw7CglpZihnZXRTdGF0ZW1lbnRUeXBlKCkgPT0gU1FMX1NUQVRFTUVOVF9TRUxFQ1QpCgl7CgkJT1NMX0VOU1VSRShtX3BQYXJzZVRyZWUtPmNvdW50KCkgPj0gNCwiUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgkJT1NRTFBhcnNlTm9kZSAqIHBUYWJsZUV4cCA9IG1fcFBhcnNlVHJlZS0+Z2V0Q2hpbGQoMyk7CgkJT1NMX0VOU1VSRShwVGFibGVFeHAgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJCU9TTF9FTlNVUkUoU1FMX0lTUlVMRShwVGFibGVFeHAsdGFibGVfZXhwKSwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJCU9TTF9FTlNVUkUocFRhYmxlRXhwLT5jb3VudCgpID09IFRBQkxFX0VYUFJFU1NJT05fQ0hJTERfQ09VTlQsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCgkJcFdoZXJlQ2xhdXNlID0gcFRhYmxlRXhwLT5nZXRDaGlsZCgxKTsKCX0KCWVsc2UgaWYgKFNRTF9JU1JVTEUobV9wUGFyc2VUcmVlLHVwZGF0ZV9zdGF0ZW1lbnRfc2VhcmNoZWQpIHx8CgkJCSBTUUxfSVNSVUxFKG1fcFBhcnNlVHJlZSxkZWxldGVfc3RhdGVtZW50X3NlYXJjaGVkKSkKCXsKCQlwV2hlcmVDbGF1c2UgPSBtX3BQYXJzZVRyZWUtPmdldENoaWxkKG1fcFBhcnNlVHJlZS0+Y291bnQoKS0xKTsKCX0KCWlmKHBXaGVyZUNsYXVzZS0+Y291bnQoKSAhPSAyKQoJCXBXaGVyZUNsYXVzZSA9IE5VTEw7CglyZXR1cm4gcFdoZXJlQ2xhdXNlOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmNvbnN0IE9TUUxQYXJzZU5vZGUqIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0T3JkZXJUcmVlKCkgY29uc3QKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldE9yZGVyVHJlZSIgKTsKCgoJaWYgKCFtX3BQYXJzZVRyZWUgfHwgZ2V0U3RhdGVtZW50VHlwZSgpICE9IFNRTF9TVEFURU1FTlRfU0VMRUNUKQoJCXJldHVybiBOVUxMOwoKCS8vIFBhcnNlIFRyZWUgYW5hbHlzaWVyZW4gKGplIG5hY2ggU3RhdGVtZW50LVR5cCkKCS8vIHVuZCBaZWlnZXIgYXVmIE9SREVSLUtsYXVzZWwgc2V0emVuOgoJT1NRTFBhcnNlTm9kZSAqIHBPcmRlckNsYXVzZSA9IE5VTEw7CglPU0xfRU5TVVJFKG1fcFBhcnNlVHJlZS0+Y291bnQoKSA+PSA0LCJQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCU9TUUxQYXJzZU5vZGUgKiBwVGFibGVFeHAgPSBtX3BQYXJzZVRyZWUtPmdldENoaWxkKDMpOwoJT1NMX0VOU1VSRShwVGFibGVFeHAgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJT1NMX0VOU1VSRShTUUxfSVNSVUxFKHBUYWJsZUV4cCx0YWJsZV9leHApLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CglPU0xfRU5TVVJFKHBUYWJsZUV4cC0+Y291bnQoKSA9PSBUQUJMRV9FWFBSRVNTSU9OX0NISUxEX0NPVU5ULCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJcE9yZGVyQ2xhdXNlID0gcFRhYmxlRXhwLT5nZXRDaGlsZChPUkRFUl9CWV9DSElMRF9QT1MpOwoJLy8gV2VubiBlcyBhYmVyIGVpbmUgb3JkZXJfYnkgaXN0LCBkYW5uIGRhcmYgc2llIG5pY2h0IGxlZXIgc2VpbjoKCWlmKHBPcmRlckNsYXVzZS0+Y291bnQoKSAhPSAzKQoJCXBPcmRlckNsYXVzZSA9IE5VTEw7CglyZXR1cm4gcE9yZGVyQ2xhdXNlOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY29uc3QgT1NRTFBhcnNlTm9kZSogT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRHcm91cEJ5VHJlZSgpIGNvbnN0CnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRHcm91cEJ5VHJlZSIgKTsKCWlmICghbV9wUGFyc2VUcmVlIHx8IGdldFN0YXRlbWVudFR5cGUoKSAhPSBTUUxfU1RBVEVNRU5UX1NFTEVDVCkKCQlyZXR1cm4gTlVMTDsKCgkvLyBQYXJzZSBUcmVlIGFuYWx5c2llcmVuIChqZSBuYWNoIFN0YXRlbWVudC1UeXApCgkvLyB1bmQgWmVpZ2VyIGF1ZiBPUkRFUi1LbGF1c2VsIHNldHplbjoKCU9TUUxQYXJzZU5vZGUgKiBwR3JvdXBDbGF1c2UgPSBOVUxMOwoJT1NMX0VOU1VSRShtX3BQYXJzZVRyZWUtPmNvdW50KCkgPj0gNCwiUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CglPU1FMUGFyc2VOb2RlICogcFRhYmxlRXhwID0gbV9wUGFyc2VUcmVlLT5nZXRDaGlsZCgzKTsKCU9TTF9FTlNVUkUocFRhYmxlRXhwICE9IE5VTEwsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCU9TTF9FTlNVUkUoU1FMX0lTUlVMRShwVGFibGVFeHAsdGFibGVfZXhwKSwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJT1NMX0VOU1VSRShwVGFibGVFeHAtPmNvdW50KCkgPT0gVEFCTEVfRVhQUkVTU0lPTl9DSElMRF9DT1VOVCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoKCXBHcm91cENsYXVzZSA9IHBUYWJsZUV4cC0+Z2V0Q2hpbGQoMik7CgkvLyBXZW5uIGVzIGFiZXIgZWluZSBvcmRlcl9ieSBpc3QsIGRhbm4gZGFyZiBzaWUgbmljaHQgbGVlciBzZWluOgoJaWYocEdyb3VwQ2xhdXNlLT5jb3VudCgpICE9IDMpCgkJcEdyb3VwQ2xhdXNlID0gTlVMTDsKCXJldHVybiBwR3JvdXBDbGF1c2U7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjb25zdCBPU1FMUGFyc2VOb2RlKiBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldEhhdmluZ1RyZWUoKSBjb25zdAp7CglpZiAoIW1fcFBhcnNlVHJlZSB8fCBnZXRTdGF0ZW1lbnRUeXBlKCkgIT0gU1FMX1NUQVRFTUVOVF9TRUxFQ1QpCgkJcmV0dXJuIE5VTEw7CgoJLy8gUGFyc2UgVHJlZSBhbmFseXNpZXJlbiAoamUgbmFjaCBTdGF0ZW1lbnQtVHlwKQoJLy8gdW5kIFplaWdlciBhdWYgT1JERVItS2xhdXNlbCBzZXR6ZW46CglPU1FMUGFyc2VOb2RlICogcEhhdmluZ0NsYXVzZSA9IE5VTEw7CglPU0xfRU5TVVJFKG1fcFBhcnNlVHJlZS0+Y291bnQoKSA+PSA0LCJQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCU9TUUxQYXJzZU5vZGUgKiBwVGFibGVFeHAgPSBtX3BQYXJzZVRyZWUtPmdldENoaWxkKDMpOwoJT1NMX0VOU1VSRShwVGFibGVFeHAgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJT1NMX0VOU1VSRShTUUxfSVNSVUxFKHBUYWJsZUV4cCx0YWJsZV9leHApLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CglPU0xfRU5TVVJFKHBUYWJsZUV4cC0+Y291bnQoKSA9PSBUQUJMRV9FWFBSRVNTSU9OX0NISUxEX0NPVU5ULCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJcEhhdmluZ0NsYXVzZSA9IHBUYWJsZUV4cC0+Z2V0Q2hpbGQoMyk7CgkvLyBXZW5uIGVzIGFiZXIgZWluZSBvcmRlcl9ieSBpc3QsIGRhbm4gZGFyZiBzaWUgbmljaHQgbGVlciBzZWluOgoJaWYocEhhdmluZ0NsYXVzZS0+Y291bnQoKSA8IDEpCgkJcEhhdmluZ0NsYXVzZSA9IE5VTEw7CglyZXR1cm4gcEhhdmluZ0NsYXVzZTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmlzVGFibGVOb2RlKGNvbnN0IE9TUUxQYXJzZU5vZGUqIF9wVGFibGVOb2RlKSBjb25zdAp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6aXNUYWJsZU5vZGUiICk7CglyZXR1cm4gX3BUYWJsZU5vZGUgJiYgKFNRTF9JU1JVTEUoX3BUYWJsZU5vZGUsY2F0YWxvZ19uYW1lKSB8fAoJCQkJCQkgICBTUUxfSVNSVUxFKF9wVGFibGVOb2RlLHNjaGVtYV9uYW1lKSAgfHwKCQkJCQkJICAgU1FMX0lTUlVMRShfcFRhYmxlTm9kZSx0YWJsZV9uYW1lKSk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY29uc3QgT1NRTFBhcnNlTm9kZSogT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTaW1wbGVXaGVyZVRyZWUoKSBjb25zdAp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0U2ltcGxlV2hlcmVUcmVlIiApOwoJY29uc3QgT1NRTFBhcnNlTm9kZSogcE5vZGUgPSBnZXRXaGVyZVRyZWUoKTsKCXJldHVybiBwTm9kZSA/IHBOb2RlLT5nZXRDaGlsZCgxKSA6IE5VTEw7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY29uc3QgT1NRTFBhcnNlTm9kZSogT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTaW1wbGVPcmRlclRyZWUoKSBjb25zdAp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0U2ltcGxlT3JkZXJUcmVlIiApOwoJY29uc3QgT1NRTFBhcnNlTm9kZSogcE5vZGUgPSBnZXRPcmRlclRyZWUoKTsKCXJldHVybiBwTm9kZSA/IHBOb2RlLT5nZXRDaGlsZCgyKSA6IE5VTEw7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY29uc3QgT1NRTFBhcnNlTm9kZSogT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTaW1wbGVHcm91cEJ5VHJlZSgpIGNvbnN0CnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTaW1wbGVHcm91cEJ5VHJlZSIgKTsKCWNvbnN0IE9TUUxQYXJzZU5vZGUqIHBOb2RlID0gZ2V0R3JvdXBCeVRyZWUoKTsKCXJldHVybiBwTm9kZSA/IHBOb2RlLT5nZXRDaGlsZCgyKSA6IE5VTEw7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY29uc3QgT1NRTFBhcnNlTm9kZSogT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTaW1wbGVIYXZpbmdUcmVlKCkgY29uc3QKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldFNpbXBsZUhhdmluZ1RyZWUiICk7Cgljb25zdCBPU1FMUGFyc2VOb2RlKiBwTm9kZSA9IGdldEhhdmluZ1RyZWUoKTsKCXJldHVybiBwTm9kZSA/IHBOb2RlLT5nZXRDaGlsZCgxKSA6IE5VTEw7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4gT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpmaW5kQ29sdW1uKCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgJiByQ29sdW1uTmFtZSwgY29uc3QgOjpydGw6Ok9VU3RyaW5nICYgclRhYmxlUmFuZ2UsIGJvb2wgX2JMb29rSW5TdWJUYWJsZXMgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6ZmluZENvbHVtbiIgKTsKICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geENvbHVtbiA9IGZpbmRDb2x1bW4oICptX3BJbXBsLT5tX3BUYWJsZXMsIHJDb2x1bW5OYW1lLCByVGFibGVSYW5nZSApOwogICAgaWYgKCAheENvbHVtbi5pcygpICYmIF9iTG9va0luU3ViVGFibGVzICkKICAgICAgICB4Q29sdW1uID0gZmluZENvbHVtbiggKm1fcEltcGwtPm1fcFN1YlRhYmxlcywgckNvbHVtbk5hbWUsIHJUYWJsZVJhbmdlICk7CiAgICByZXR1cm4geENvbHVtbjsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmZpbmRDb2x1bW4oY29uc3QgT1NRTFRhYmxlcyYgX3JUYWJsZXMsY29uc3QgOjpydGw6Ok9VU3RyaW5nICYgckNvbHVtbk5hbWUsIGNvbnN0IDo6cnRsOjpPVVN0cmluZyAmIHJUYWJsZVJhbmdlKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6ZmluZENvbHVtbiIgKTsKCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geENvbHVtbjsKCWlmICggclRhYmxlUmFuZ2UuZ2V0TGVuZ3RoKCkgKQoJewoJCUNvbnN0T1NRTFRhYmxlc0l0ZXJhdG9yIGFGaW5kID0gX3JUYWJsZXMuZmluZChyVGFibGVSYW5nZSk7CgoJCWlmICggYUZpbmQgIT0gX3JUYWJsZXMuZW5kKCkKCQkJJiYgYUZpbmQtPnNlY29uZC5pcygpCgkJCSYmIGFGaW5kLT5zZWNvbmQtPmdldENvbHVtbnMoKS5pcygpCgkJCSYmIGFGaW5kLT5zZWNvbmQtPmdldENvbHVtbnMoKS0+aGFzQnlOYW1lKHJDb2x1bW5OYW1lKSApCgkJCWFGaW5kLT5zZWNvbmQtPmdldENvbHVtbnMoKS0+Z2V0QnlOYW1lKHJDb2x1bW5OYW1lKSA+Pj0geENvbHVtbjsKCX0KCWlmICggIXhDb2x1bW4uaXMoKSApCgl7CgkJT1NRTFRhYmxlczo6Y29uc3RfaXRlcmF0b3IgYUVuZCA9IF9yVGFibGVzLmVuZCgpOwoJCWZvcihPU1FMVGFibGVzOjpjb25zdF9pdGVyYXRvciBhSXRlciA9IF9yVGFibGVzLmJlZ2luKCk7IGFJdGVyICE9IGFFbmQ7ICsrYUl0ZXIpCgkJewoJCQlpZiAoIGFJdGVyLT5zZWNvbmQuaXMoKSApCgkJCXsKCQkJCVJlZmVyZW5jZTxYTmFtZUFjY2Vzcz4geENvbHVtbnMgPSBhSXRlci0+c2Vjb25kLT5nZXRDb2x1bW5zKCk7CgkJCQlpZiggeENvbHVtbnMuaXMoKSAmJiB4Q29sdW1ucy0+aGFzQnlOYW1lKHJDb2x1bW5OYW1lKSAmJiAoeENvbHVtbnMtPmdldEJ5TmFtZShyQ29sdW1uTmFtZSkgPj49IHhDb2x1bW4pICkKCQkJCXsKCQkJCQlPU0xfRU5TVVJFKHhDb2x1bW4uaXMoKSwiQ29sdW1uIGlzbid0IGEgcHJvcGVydHlzZXQhIik7CgkJCQkJYnJlYWs7IC8vIGRpZXNlIENvbHVtbiBkYXJmIG51ciBlaW5tYWwgdm9ya29tbWVuCgkJCQl9CgkJCX0KCQl9Cgl9CglyZXR1cm4geENvbHVtbjsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfYXBwZW5kRXJyb3IoIElQYXJzZUNvbnRleHQ6OkVycm9yQ29kZSBfZUVycm9yLCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcqIF9wUmVwbGFjZVRva2VuMSwgY29uc3QgOjpydGw6Ok9VU3RyaW5nKiBfcFJlcGxhY2VUb2tlbjIgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6aW1wbF9hcHBlbmRFcnJvciIgKTsKICAgIDo6cnRsOjpPVVN0cmluZyBzRXJyb3JNZXNzYWdlID0gbV9yUGFyc2VyLmdldENvbnRleHQoKS5nZXRFcnJvck1lc3NhZ2UoIF9lRXJyb3IgKTsKICAgIGlmICggX3BSZXBsYWNlVG9rZW4xICkKICAgIHsKICAgICAgICBib29sIGJUd29Ub2tlbnMgPSAoIF9wUmVwbGFjZVRva2VuMiAhPSBOVUxMICk7CiAgICAgICAgY29uc3Qgc2FsX0NoYXIqIHBQbGFjZUhvbGRlcjEgPSBiVHdvVG9rZW5zID8gIiMxIiA6ICIjIjsKICAgICAgICBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgc1BsYWNlSG9sZGVyMSA9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCBwUGxhY2VIb2xkZXIxICk7CgogICAgICAgIHNFcnJvck1lc3NhZ2UgPSBzRXJyb3JNZXNzYWdlLnJlcGxhY2VBdCggc0Vycm9yTWVzc2FnZS5pbmRleE9mKCBzUGxhY2VIb2xkZXIxICksIHNQbGFjZUhvbGRlcjEuZ2V0TGVuZ3RoKCksICpfcFJlcGxhY2VUb2tlbjEgKTsKICAgICAgICBpZiAoIF9wUmVwbGFjZVRva2VuMiApCiAgICAgICAgICAgIHNFcnJvck1lc3NhZ2UgPSBzRXJyb3JNZXNzYWdlLnJlcGxhY2VBdCggc0Vycm9yTWVzc2FnZS5pbmRleE9mKCA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSggIiMyIiApICksIDIsICpfcFJlcGxhY2VUb2tlbjIgKTsKICAgIH0KCiAgICBpbXBsX2FwcGVuZEVycm9yKCBTUUxFeGNlcHRpb24oCiAgICAgICAgc0Vycm9yTWVzc2FnZSwgTlVMTCwgZ2V0U3RhbmRhcmRTUUxTdGF0ZSggU1FMX0dFTkVSQUxfRVJST1IgKSwgMTAwMCwgQW55KCkgKSApOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6aW1wbF9hcHBlbmRFcnJvciggY29uc3QgU1FMRXhjZXB0aW9uJiBfckVycm9yICkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfYXBwZW5kRXJyb3IiICk7CiAgICBpZiAoIG1fYUVycm9ycy5NZXNzYWdlLmdldExlbmd0aCgpICkKCXsKICAgICAgICBTUUxFeGNlcHRpb24qIHBFcnJvckNoYWluID0gJm1fYUVycm9yczsKCQl3aGlsZSAoIHBFcnJvckNoYWluLT5OZXh0RXhjZXB0aW9uLmhhc1ZhbHVlKCkgKQogICAgICAgICAgICBwRXJyb3JDaGFpbiA9IHN0YXRpY19jYXN0PCBTUUxFeGNlcHRpb24qID4oIHBFcnJvckNoYWluLT5OZXh0RXhjZXB0aW9uLnBEYXRhICk7CgkJcEVycm9yQ2hhaW4tPk5leHRFeGNlcHRpb24gPDw9IF9yRXJyb3I7Cgl9CgllbHNlCgkJbV9hRXJyb3JzID0gX3JFcnJvcjsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfSW50MzIgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRGdW5jdGlvblJldHVyblR5cGUoY29uc3QgT1NRTFBhcnNlTm9kZSogX3BOb2RlICkKewogICAgc2FsX0ludDMyIG5UeXBlID0gRGF0YVR5cGU6Ok9USEVSOwogICAgOjpydGw6Ok9VU3RyaW5nIHNGdW5jdGlvbk5hbWU7CglpZiAoIFNRTF9JU1JVTEUoX3BOb2RlLGxlbmd0aF9leHApICkKICAgIHsKCQlfcE5vZGUtPmdldENoaWxkKDApLT5nZXRDaGlsZCgwKS0+cGFyc2VOb2RlVG9TdHIoc0Z1bmN0aW9uTmFtZSwgbV9wSW1wbC0+bV94Q29ubmVjdGlvbiwgTlVMTCwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgKTsKICAgICAgICBuVHlwZSA9IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VyOjpnZXRGdW5jdGlvblJldHVyblR5cGUoIHNGdW5jdGlvbk5hbWUsICZtX3JQYXJzZXIuZ2V0Q29udGV4dCgpICk7CiAgICB9CiAgICBlbHNlIGlmICggU1FMX0lTUlVMRShfcE5vZGUsbnVtX3ZhbHVlX2V4cCkgfHwgU1FMX0lTUlVMRShfcE5vZGUsdGVybSkgfHwgU1FMX0lTUlVMRShfcE5vZGUsZmFjdG9yKSApCgl7CgkJblR5cGUgPSBEYXRhVHlwZTo6RE9VQkxFOwoJfQoJZWxzZQogICAgewoJCV9wTm9kZS0+Z2V0Q2hpbGQoMCktPnBhcnNlTm9kZVRvU3RyKHNGdW5jdGlvbk5hbWUsIG1fcEltcGwtPm1feENvbm5lY3Rpb24sIE5VTEwsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlICk7CgogICAgICAgIC8vIE1JTiBhbmQgTUFYIGhhdmUgYW5vdGhlciByZXR1cm4gdHlwZSwgd2UgaGF2ZSB0byBjaGVjayB0aGUgZXhwcmVzc2lvbiBpdHNlbGYuCiAgICAgICAgLy8gQHNlZSBodHRwOi8vcWEub3Blbm9mZmljZS5vcmcvaXNzdWVzL3Nob3dfYnVnLmNnaT9pZD05OTU2NgogICAgICAgIGlmICggU1FMX0lTUlVMRShfcE5vZGUsZ2VuZXJhbF9zZXRfZmN0KSAmJiAoU1FMX0lTVE9LRU4oX3BOb2RlLT5nZXRDaGlsZCgwKSxNSU4pIHx8IFNRTF9JU1RPS0VOKF9wTm9kZS0+Z2V0Q2hpbGQoMCksTUFYKSApKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgT1NRTFBhcnNlTm9kZSogcFZhbHVlRXhwID0gX3BOb2RlLT5nZXRDaGlsZCgzKTsKICAgICAgICAgICAgaWYgKFNRTF9JU1JVTEUocFZhbHVlRXhwLGNvbHVtbl9yZWYpKQoJICAgICAgICB7CgkJICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc0NvbHVtbk5hbWU7CgkJICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgYVRhYmxlUmFuZ2U7CgkJICAgICAgICBnZXRDb2x1bW5SYW5nZShwVmFsdWVFeHAsc0NvbHVtbk5hbWUsYVRhYmxlUmFuZ2UpOwoJCSAgICAgICAgT1NMX0VOU1VSRShzQ29sdW1uTmFtZS5nZXRMZW5ndGgoKSwiQ29sdW1ubmFtZSBkYXJmIG5pY2h0IGxlZXIgc2VpbiIpOwogICAgICAgICAgICAgICAgUmVmZXJlbmNlPFhQcm9wZXJ0eVNldD4geENvbHVtbiA9IGZpbmRDb2x1bW4oIHNDb2x1bW5OYW1lLCBhVGFibGVSYW5nZSwgdHJ1ZSApOwoKCQkgICAgICAgIGlmICggeENvbHVtbi5pcygpICkKCQkgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4Q29sdW1uLT5nZXRQcm9wZXJ0eVZhbHVlKE9NZXRhQ29ubmVjdGlvbjo6Z2V0UHJvcE1hcCgpLmdldE5hbWVCeUluZGV4KCBQUk9QRVJUWV9JRF9UWVBFKSkgPj49IG5UeXBlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCBTUUxfSVNSVUxFKHBWYWx1ZUV4cCxudW1fdmFsdWVfZXhwKSB8fCBTUUxfSVNSVUxFKHBWYWx1ZUV4cCx0ZXJtKSB8fCBTUUxfSVNSVUxFKHBWYWx1ZUV4cCxmYWN0b3IpICkKCQkJCXsKCQkJCQluVHlwZSA9IERhdGFUeXBlOjpET1VCTEU7CgkJCQl9CiAgICAgICAgICAgICAgICBlbHNlIGlmICggU1FMX0lTUlVMRShwVmFsdWVFeHAsZGF0ZXRpbWVfcHJpbWFyeSkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaChwVmFsdWVFeHAtPmdldENoaWxkKDApLT5nZXRUb2tlbklEKCkgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTUUxfVE9LRU5fQ1VSUkVOVF9EQVRFOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgblR5cGUgPSBEYXRhVHlwZTo6REFURTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNRTF9UT0tFTl9DVVJSRU5UX1RJTUU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuVHlwZSA9IERhdGFUeXBlOjpUSU1FOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1FMX1RPS0VOX0NVUlJFTlRfVElNRVNUQU1QOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgblR5cGUgPSBEYXRhVHlwZTo6VElNRVNUQU1QOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoIFNRTF9JU1JVTEUocFZhbHVlRXhwLHZhbHVlX2V4cF9wcmltYXJ5KSApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgblR5cGUgPSBnZXRGdW5jdGlvblJldHVyblR5cGUocFZhbHVlRXhwLT5nZXRDaGlsZCgxKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICggU1FMX0lTUlVMRShwVmFsdWVFeHAsY29uY2F0ZW5hdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgfHwgU1FMX0lTUlVMRShwVmFsdWVFeHAsY2hhcl9mYWN0b3IpCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IFNRTF9JU1JVTEUocFZhbHVlRXhwLGJpdF92YWx1ZV9mY3QpCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IFNRTF9JU1JVTEUocFZhbHVlRXhwLGNoYXJfdmFsdWVfZmN0KQogICAgICAgICAgICAgICAgICAgICAgICB8fCBTUUxfSVNSVUxFKHBWYWx1ZUV4cCxjaGFyX3N1YnN0cmluZ19mY3QpCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IFNRTF9JU1JVTEUocFZhbHVlRXhwLGZvbGQpCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IFNRTF9JU1RPS0VOKHBWYWx1ZUV4cCxTVFJJTkcpICkKCQkJCXsKCQkJCQluVHlwZSA9IERhdGFUeXBlOjpWQVJDSEFSOwoJCQkJfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICggblR5cGUgPT0gRGF0YVR5cGU6Ok9USEVSICkKICAgICAgICAgICAgICAgIG5UeXBlID0gRGF0YVR5cGU6OkRPVUJMRTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBuVHlwZSA9IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VyOjpnZXRGdW5jdGlvblJldHVyblR5cGUoIHNGdW5jdGlvbk5hbWUsICZtX3JQYXJzZXIuZ2V0Q29udGV4dCgpICk7CiAgICB9CgogICAgcmV0dXJuIG5UeXBlOwp9Cg==