PD9waHAKLyoKICBQbHVnaW4gTmFtZTogV29yZFByZXNzIGF1dG9tYXRpb24gYnkgSW5zdGFsbGF0cm9uCiAgRGVzY3JpcHRpb246IE1hbmFnZW1lbnQgb2YgdGhpcyBXb3JkUHJlc3Mgc2l0ZSBpcyBwcm92aWRlZCBieSBJbnN0YWxsYXRyb24uCiovCgovLyBUaGlzIHBsdWdpbiB3YXMgYWRkZWQgYmVjYXVzZSBBdXRvbWF0aWMgVXBkYXRlcywgQXV0b21hdGljIEJhY2t1cHMsIGFuZAovLyBvdGhlciBmZWF0dXJlcyBhcmUgbWFuYWdlZCBleHRlcm5hbGx5IGJ5IEluc3RhbGxhdHJvbi4KCi8vIFRvIGJsb2NrIHRoaXMgcGx1Z2luLCBjcmVhdGUgYW4gZW1wdHkgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkgbmFtZWQ6Ci8vICAgICBibG9jay1hdXRvbWF0aW9uLWJ5LWluc3RhbGxhdHJvbi5waHAKCi8vIFR1cm4gb2ZmIFdvcmRQcmVzcyBhdXRvbWF0aWMgdXBkYXRlcyBzaW5jZSB0aGVzZSBhcmUgbWFuYWdlZCBleHRlcm5hbGx5LgovLyBJZiB5b3UgcmVtb3ZlIHRoaXMgdG8gcmUtZW5hYmxlIFdvcmRQcmVzcydzIGF1dG9tYXRpYyB1cGRhdGVzIHRoZW4gaXQncyAKLy8gYWR2aXNlZCB0byBkaXNhYmxlIGF1dG8tdXBkYXRpbmcgaW4gSW5zdGFsbGF0cm9uLgphZGRfZmlsdGVyKCAnYXV0b21hdGljX3VwZGF0ZXJfZGlzYWJsZWQnLCAnX19yZXR1cm5fdHJ1ZScsIC05OTk5ICk7CgovLyBEaXNhYmxlIFdvcmRQcmVzcyBzaXRlIGhlYWx0aCB0ZXN0IGZvciBBdXRvbWF0aWMgVXBkYXRlcyBzaW5jZSB0aGVzZSBhcmUKLy8gbWFuYWdlZCBleHRlcm5hbGx5IGJ5IEluc3RhbGxhdHJvbi4KZnVuY3Rpb24gaW5zdGFsbGF0cm9uX2ZpbHRlcl9zaXRlX3N0YXR1c190ZXN0cygkdGVzdHMpIHsKCXVuc2V0KCR0ZXN0c1snYXN5bmMnXVsnYmFja2dyb3VuZF91cGRhdGVzJ10pOwoJcmV0dXJuICR0ZXN0czsKfQphZGRfZmlsdGVyKCdzaXRlX3N0YXR1c190ZXN0cycsICdpbnN0YWxsYXRyb25fZmlsdGVyX3NpdGVfc3RhdHVzX3Rlc3RzJyk7Cgo=PD9waHAgLy8gcGhwY3M6aWdub3JlIFdvcmRQcmVzcy5GaWxlcy5GaWxlTmFtZS5JbnZhbGlkQ2xhc3NGaWxlTmFtZQovKioKICogUGx1Z2luIE5hbWU6IFdvb0NvbW1lcmNlIEFuYWx5dGljcyAtIFByb3h5IFNwZWVkIE1vZHVsZQogKiBEZXNjcmlwdGlvbjogU3BlZWRzIHVwIFdvb0NvbW1lcmNlIEFuYWx5dGljcycgcHJveHkgZm9yIGF2b2lkaW5nIGFkIGJsb2NrZXJzLgogKiBQbHVnaW4gVVJJOiBodHRwczovL3dvb2NvbW1lcmNlLmNvbQogKiBBdXRob3I6IFdvb0NvbW1lcmNlCiAqIFZlcnNpb246IDEuMC4wCiAqIEF1dGhvciBVUkk6IGh0dHBzOi8vd29vY29tbWVyY2UuY29tCiAqCiAqIFRleHQgRG9tYWluOiB3b29jb21tZXJjZS1hbmFseXRpY3MKICoKICogSW5zcGlyZWQgYnk6IGh0dHBzOi8vZ2l0aHViLmNvbS9wbGF1c2libGUvd29yZHByZXNzL2Jsb2IvMDkyYjk3YjI0N2Y0NWJmMzQ3YWUzMmY5NjE0ZjIwYTgxZDllMTBjMC9tdS1wbHVnaW4vcGxhdXNpYmxlLXByb3h5LXNwZWVkLW1vZHVsZS5waHAKICovCmNsYXNzIFdvb0NvbW1lcmNlQW5hbHl0aWNzUHJveHlTcGVlZCB7CgkvKioKCSAqIFBhdGggb2YgdGhlIHByb3h5IHJlcXVlc3QuCgkgKgoJICogQHZhciBzdHJpbmcKCSAqLwoJY29uc3QgUFJPWFlfUkVRVUVTVF9QQVRIID0gJ3dvb2NvbW1lcmNlLWFuYWx5dGljcy92MS90cmFjayc7CgoJLyoqCgkgKiBBbGxvd2VkIHBsdWdpbiBmaWxlcyBmb3IgcHJveHkgcmVxdWVzdC4KCSAqCgkgKiBAdmFyIGFycmF5CgkgKi8KCXByaXZhdGUgJGFsbG93ZWRfcGx1Z2luX2ZpbGVzID0gYXJyYXkoICd3b29jb21tZXJjZS5waHAnLCAnd29vY29tbWVyY2UtYW5hbHl0aWNzLnBocCcsICdqZXRwYWNrLnBocCcgKTsKCgkvKioKCSAqIEFkZCBmaWx0ZXJzIGFuZCBhY3Rpb25zLgoJICoKCSAqIEByZXR1cm4gdm9pZAoJICovCglwdWJsaWMgZnVuY3Rpb24gaW5pdCgpIHsKCQlhZGRfZmlsdGVyKCAnb3B0aW9uX2FjdGl2ZV9wbHVnaW5zJywgYXJyYXkoICR0aGlzLCAnZmlsdGVyX2FjdGl2ZV9wbHVnaW5zJyApICk7Cgl9CgoJLyoqCgkgKiBGaWx0ZXIgdGhlIGxpc3Qgb2YgYWN0aXZlIHBsdWdpbnMgZm9yIGN1c3RvbSBlbmRwb2ludCByZXF1ZXN0cy4KCSAqCgkgKiBAcGFyYW0gYXJyYXkgJGFjdGl2ZV9wbHVnaW5zIFRoZSBsaXN0IG9mIGFjdGl2ZSBwbHVnaW5zLgoJICoKCSAqIEByZXR1cm4gYXJyYXkgVGhlIGZpbHRlcmVkIGxpc3Qgb2YgYWN0aXZlIHBsdWdpbnMuCgkgKi8KCXB1YmxpYyBmdW5jdGlvbiBmaWx0ZXJfYWN0aXZlX3BsdWdpbnMoICRhY3RpdmVfcGx1Z2lucyApIHsKCQlpZiAoICEgJHRoaXMtPmlzX3Byb3h5X3JlcXVlc3QoKSB8fCAhIGlzX2FycmF5KCAkYWN0aXZlX3BsdWdpbnMgKSApIHsKCQkJcmV0dXJuICRhY3RpdmVfcGx1Z2luczsKCQl9CgoJCSRmaWx0ZXJlZF9wbHVnaW5zID0gYXJyYXkoKTsKCgkJZm9yZWFjaCAoICRhY3RpdmVfcGx1Z2lucyBhcyAkcGx1Z2luICkgewoJCQlmb3JlYWNoICggJHRoaXMtPmFsbG93ZWRfcGx1Z2luX2ZpbGVzIGFzICRhbGxvd2VkX3BsdWdpbl9maWxlICkgewoJCQkJaWYgKCBzdHJwb3MoICRwbHVnaW4sICRhbGxvd2VkX3BsdWdpbl9maWxlICkgIT09IGZhbHNlICkgewoJCQkJCSRmaWx0ZXJlZF9wbHVnaW5zW10gPSAkcGx1Z2luOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJfQoKCQlyZXR1cm4gJGZpbHRlcmVkX3BsdWdpbnM7Cgl9CgoJLyoqCgkgKiBIZWxwZXIgbWV0aG9kIHRvIHJldHJpZXZlIFJlcXVlc3QgVVJJLiBDaGVja3Mgc2V2ZXJhbCBnbG9iYWxzLgoJICoKCSAqIEByZXR1cm4gbWl4ZWQKCSAqLwoJcHJpdmF0ZSBmdW5jdGlvbiBnZXRfcmVxdWVzdF91cmkoKSB7CgkJcmV0dXJuIGlzc2V0KCAkX1NFUlZFUlsnUkVRVUVTVF9VUkknXSApID8gd3BfdW5zbGFzaCggJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10gKSA6ICcnOyAvLyBwaHBjczppZ25vcmUgV29yZFByZXNzLlNlY3VyaXR5LlZhbGlkYXRlZFNhbml0aXplZElucHV0LklucHV0Tm90U2FuaXRpemVkCgl9CgoJLyoqCgkgKiBDaGVjayBpZiBjdXJyZW50IHJlcXVlc3QgaXMgYSBwcm94eSByZXF1ZXN0LgoJICoKCSAqIEByZXR1cm4gYm9vbAoJICovCglwcml2YXRlIGZ1bmN0aW9uIGlzX3Byb3h5X3JlcXVlc3QoKSB7CgkJcmV0dXJuIHN0cnBvcyggJHRoaXMtPmdldF9yZXF1ZXN0X3VyaSgpLCBzZWxmOjpQUk9YWV9SRVFVRVNUX1BBVEggKSAhPT0gZmFsc2U7Cgl9Cn0KCiggbmV3IFdvb0NvbW1lcmNlQW5hbHl0aWNzUHJveHlTcGVlZCgpICktPmluaXQoKTsK