LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogWW91IG1heSBhbWVuZCBhbmQgZGlzdHJpYnV0ZSBhcyB5b3UgbGlrZSwgYnV0IGRvbid0IHJlbW92ZSB0aGlzIGhlYWRlciEKICoKICogRVBQbHVzIHByb3ZpZGVzIHNlcnZlci1zaWRlIGdlbmVyYXRpb24gb2YgRXhjZWwgMjAwNy8yMDEwIHNwcmVhZHNoZWV0cy4KICogU2VlIGh0dHA6Ly93d3cuY29kZXBsZXguY29tL0VQUGx1cyBmb3IgZGV0YWlscy4KICoKICogQ29weXJpZ2h0IChDKSAyMDExICBKYW4gS+RsbG1hbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIAogKiBTZWUgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGNhbiBiZSB2aWV3ZWQgYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9sZ3BsLWxpY2Vuc2UucGhwCiAqIElmIHlvdSB1bmZhbWlsaWFyIHdpdGggdGhpcyBsaWNlbnNlIG9yIGhhdmUgcXVlc3Rpb25zIGFib3V0IGl0LCBoZXJlIGlzIGFuIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtZmFxLmh0bWwKICoKICogQWxsIGNvZGUgYW5kIGV4ZWN1dGFibGVzIGFyZSBwcm92aWRlZCAiYXMgaXMiIHdpdGggbm8gd2FycmFudHkgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCiAqIFRoZSBhdXRob3IgYWNjZXB0cyBubyBsaWFiaWxpdHkgZm9yIGFueSBkYW1hZ2Ugb3IgbG9zcyBvZiBidXNpbmVzcyB0aGF0IHRoaXMgcHJvZHVjdCBtYXkgY2F1c2UuCiAqCiAqIENvZGUgY2hhbmdlIG5vdGVzOgogKiAKICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEphbiBL5GxsbWFuCQkgICAgICAgICAgICAgICAgSW5pdGlhbCBSZWxlYXNlCQkgICAgICAgIDIwMDktMTAtMDEKICogSmFuIEvkbGxtYW4gICAgICAgICAgICAgICAgICAgICAgVG90YWwgcmV3cml0ZSAgICAgICAgICAgICAgIDIwMTAtMDMtMDEKICogSmFuIEvkbGxtYW4JCSAgICBMaWNlbnNlIGNoYW5nZWQgR1BMLS0+TEdQTCAgMjAxMS0xMi0yNwogKiBSYXppcSBZb3JrICAgICAgICAgICAgICAgICAgICAgICBBZGRlZCBDcmVhdGVkICYgTW9kaWZpZWQgICAgMjAxNC0wOC0yMAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KdXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uWG1sOwp1c2luZyBTeXN0ZW0uSU87CnVzaW5nIFN5c3RlbS5HbG9iYWxpemF0aW9uOwp1c2luZyBPZmZpY2VPcGVuWG1sLlV0aWxzOwoKbmFtZXNwYWNlIE9mZmljZU9wZW5YbWwKewogICAgLy8vIDxzdW1tYXJ5PgogICAgLy8vIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgcHJvcGVydGllcyBiYWcgb2YgdGhlIHBhY2thZ2UKICAgIC8vLyA8L3N1bW1hcnk+CiAgICBwdWJsaWMgc2VhbGVkIGNsYXNzIE9mZmljZVByb3BlcnRpZXMgOiBYbWxIZWxwZXIKICAgIHsKICAgICAgICAjcmVnaW9uIFByaXZhdGUgUHJvcGVydGllcwogICAgICAgIHByaXZhdGUgWG1sRG9jdW1lbnQgX3htbFByb3BlcnRpZXNDb3JlOwogICAgICAgIHByaXZhdGUgWG1sRG9jdW1lbnQgX3htbFByb3BlcnRpZXNFeHRlbmRlZDsKICAgICAgICBwcml2YXRlIFhtbERvY3VtZW50IF94bWxQcm9wZXJ0aWVzQ3VzdG9tOwoKICAgICAgICBwcml2YXRlIFVyaSBfdXJpUHJvcGVydGllc0NvcmUgPSBuZXcgVXJpKCIvZG9jUHJvcHMvY29yZS54bWwiLCBVcmlLaW5kLlJlbGF0aXZlKTsKICAgICAgICBwcml2YXRlIFVyaSBfdXJpUHJvcGVydGllc0V4dGVuZGVkID0gbmV3IFVyaSgiL2RvY1Byb3BzL2FwcC54bWwiLCBVcmlLaW5kLlJlbGF0aXZlKTsKICAgICAgICBwcml2YXRlIFVyaSBfdXJpUHJvcGVydGllc0N1c3RvbSA9IG5ldyBVcmkoIi9kb2NQcm9wcy9jdXN0b20ueG1sIiwgVXJpS2luZC5SZWxhdGl2ZSk7CgogICAgICAgIFhtbEhlbHBlciBfY29yZUhlbHBlcjsKICAgICAgICBYbWxIZWxwZXIgX2V4dGVuZGVkSGVscGVyOwogICAgICAgIFhtbEhlbHBlciBfY3VzdG9tSGVscGVyOwogICAgICAgIHByaXZhdGUgRXhjZWxQYWNrYWdlIF9wYWNrYWdlOwogICAgICAgICNlbmRyZWdpb24KCiAgICAgICAgI3JlZ2lvbiBFeGNlbFByb3BlcnRpZXMgQ29uc3RydWN0b3IKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFByb3ZpZGVzIGFjY2VzcyB0byBhbGwgdGhlIG9mZmljZSBkb2N1bWVudCBwcm9wZXJ0aWVzLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJwYWNrYWdlIj48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibnMiPjwvcGFyYW0+CiAgICAgICAgaW50ZXJuYWwgT2ZmaWNlUHJvcGVydGllcyhFeGNlbFBhY2thZ2UgcGFja2FnZSwgWG1sTmFtZXNwYWNlTWFuYWdlciBucykgOgogICAgICAgICAgICBiYXNlKG5zKQogICAgICAgIHsKICAgICAgICAgICAgX3BhY2thZ2UgPSBwYWNrYWdlOwoKICAgICAgICAgICAgX2NvcmVIZWxwZXIgPSBYbWxIZWxwZXJGYWN0b3J5LkNyZWF0ZShucywgQ29yZVByb3BlcnRpZXNYbWwuU2VsZWN0U2luZ2xlTm9kZSgiY3A6Y29yZVByb3BlcnRpZXMiLCBOYW1lU3BhY2VNYW5hZ2VyKSk7CiAgICAgICAgICAgIF9leHRlbmRlZEhlbHBlciA9IFhtbEhlbHBlckZhY3RvcnkuQ3JlYXRlKG5zLCBFeHRlbmRlZFByb3BlcnRpZXNYbWwpOwogICAgICAgICAgICBfY3VzdG9tSGVscGVyID0gWG1sSGVscGVyRmFjdG9yeS5DcmVhdGUobnMsIEN1c3RvbVByb3BlcnRpZXNYbWwpOwoKICAgICAgICB9CiAgICAgICAgI2VuZHJlZ2lvbgogICAgICAgICNyZWdpb24gQ29yZVByb3BlcnRpZXNYbWwKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgWE1MIGRvY3VtZW50IHRoYXQgaG9sZHMgYWxsIHRoZSBjb2RlIAogICAgICAgIC8vLyBkb2N1bWVudCBwcm9wZXJ0aWVzLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIFhtbERvY3VtZW50IENvcmVQcm9wZXJ0aWVzWG1sCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF94bWxQcm9wZXJ0aWVzQ29yZSA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0cmluZyB4bWwgPSBzdHJpbmcuRm9ybWF0KCI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVVEYtOFwiIHN0YW5kYWxvbmU9XCJ5ZXNcIiA/PjxjcDpjb3JlUHJvcGVydGllcyB4bWxuczpjcD1cInswfVwiIHhtbG5zOmRjPVwiezF9XCIgeG1sbnM6ZGN0ZXJtcz1cInsyfVwiIHhtbG5zOmRjbWl0eXBlPVwiezN9XCIgeG1sbnM6eHNpPVwiezR9XCI+PC9jcDpjb3JlUHJvcGVydGllcz4iLAogICAgICAgICAgICAgICAgICAgICAgICBFeGNlbFBhY2thZ2Uuc2NoZW1hQ29yZSwKICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxQYWNrYWdlLnNjaGVtYURjLAogICAgICAgICAgICAgICAgICAgICAgICBFeGNlbFBhY2thZ2Uuc2NoZW1hRGNUZXJtcywKICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxQYWNrYWdlLnNjaGVtYURjbWlUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICBFeGNlbFBhY2thZ2Uuc2NoZW1hWHNpKTsKCiAgICAgICAgICAgICAgICAgICAgX3htbFByb3BlcnRpZXNDb3JlID0gR2V0WG1sRG9jdW1lbnQoeG1sLCBfdXJpUHJvcGVydGllc0NvcmUsIEAiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLXBhY2thZ2UuY29yZS1wcm9wZXJ0aWVzK3htbCIsIEAiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3BhY2thZ2UvMjAwNi9yZWxhdGlvbnNoaXBzL21ldGFkYXRhL2NvcmUtcHJvcGVydGllcyIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIChfeG1sUHJvcGVydGllc0NvcmUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFhtbERvY3VtZW50IEdldFhtbERvY3VtZW50KHN0cmluZyBzdGFydFhtbCwgVXJpIHVyaSwgc3RyaW5nIGNvbnRlbnRUeXBlLCBzdHJpbmcgcmVsYXRpb25zaGlwKQogICAgICAgIHsKICAgICAgICAgICAgWG1sRG9jdW1lbnQgeG1sRG9jOwogICAgICAgICAgICBpZiAoX3BhY2thZ2UuUGFja2FnZS5QYXJ0RXhpc3RzKHVyaSkpCiAgICAgICAgICAgICAgICB4bWxEb2MgPSBfcGFja2FnZS5HZXRYbWxGcm9tVXJpKHVyaSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgeG1sRG9jID0gbmV3IFhtbERvY3VtZW50KCk7CiAgICAgICAgICAgICAgICB4bWxEb2MuTG9hZFhtbChzdGFydFhtbCk7CgogICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGEgdGhlIHBhcnQgYW5kIGFkZCB0byB0aGUgcGFja2FnZQogICAgICAgICAgICAgICAgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IHBhcnQgPSBfcGFja2FnZS5QYWNrYWdlLkNyZWF0ZVBhcnQodXJpLCBjb250ZW50VHlwZSk7CgogICAgICAgICAgICAgICAgLy8gU2F2ZSBpdCB0byB0aGUgcGFja2FnZQogICAgICAgICAgICAgICAgU3RyZWFtV3JpdGVyIHN0cmVhbSA9IG5ldyBTdHJlYW1Xcml0ZXIocGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgICAgICAgICB4bWxEb2MuU2F2ZShzdHJlYW0pOwogICAgICAgICAgICAgICAgLy9zdHJlYW0uQ2xvc2UoKTsKICAgICAgICAgICAgICAgIF9wYWNrYWdlLlBhY2thZ2UuRmx1c2goKTsKCiAgICAgICAgICAgICAgICAvLyBjcmVhdGUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSB3b3JrYm9vayBhbmQgdGhlIG5ldyBzaGFyZWQgc3RyaW5ncyBwYXJ0CiAgICAgICAgICAgICAgICBfcGFja2FnZS5QYWNrYWdlLkNyZWF0ZVJlbGF0aW9uc2hpcChVcmlIZWxwZXIuR2V0UmVsYXRpdmVVcmkobmV3IFVyaSgiL3hsIiwgVXJpS2luZC5SZWxhdGl2ZSksIHVyaSksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCByZWxhdGlvbnNoaXApOwogICAgICAgICAgICAgICAgX3BhY2thZ2UuUGFja2FnZS5GbHVzaCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB4bWxEb2M7CiAgICAgICAgfQogICAgICAgICNlbmRyZWdpb24KICAgICAgICAjcmVnaW9uIENvcmUgUHJvcGVydGllcwogICAgICAgIGNvbnN0IHN0cmluZyBUaXRsZVBhdGggPSAiZGM6dGl0bGUiOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0cy9zZXRzIHRoZSB0aXRsZSBwcm9wZXJ0eSBvZiB0aGUgZG9jdW1lbnQgKGNvcmUgcHJvcGVydHkpCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgc3RyaW5nIFRpdGxlCiAgICAgICAgewogICAgICAgICAgICBnZXQgeyByZXR1cm4gX2NvcmVIZWxwZXIuR2V0WG1sTm9kZVN0cmluZyhUaXRsZVBhdGgpOyB9CiAgICAgICAgICAgIHNldCB7IF9jb3JlSGVscGVyLlNldFhtbE5vZGVTdHJpbmcoVGl0bGVQYXRoLCB2YWx1ZSk7IH0KICAgICAgICB9CgogICAgICAgIGNvbnN0IHN0cmluZyBTdWJqZWN0UGF0aCA9ICJkYzpzdWJqZWN0IjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldHMvc2V0cyB0aGUgc3ViamVjdCBwcm9wZXJ0eSBvZiB0aGUgZG9jdW1lbnQgKGNvcmUgcHJvcGVydHkpCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgc3RyaW5nIFN1YmplY3QKICAgICAgICB7CiAgICAgICAgICAgIGdldCB7IHJldHVybiBfY29yZUhlbHBlci5HZXRYbWxOb2RlU3RyaW5nKFN1YmplY3RQYXRoKTsgfQogICAgICAgICAgICBzZXQgeyBfY29yZUhlbHBlci5TZXRYbWxOb2RlU3RyaW5nKFN1YmplY3RQYXRoLCB2YWx1ZSk7IH0KICAgICAgICB9CgogICAgICAgIGNvbnN0IHN0cmluZyBBdXRob3JQYXRoID0gImRjOmNyZWF0b3IiOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0cy9zZXRzIHRoZSBhdXRob3IgcHJvcGVydHkgb2YgdGhlIGRvY3VtZW50IChjb3JlIHByb3BlcnR5KQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIHN0cmluZyBBdXRob3IKICAgICAgICB7CiAgICAgICAgICAgIGdldCB7IHJldHVybiBfY29yZUhlbHBlci5HZXRYbWxOb2RlU3RyaW5nKEF1dGhvclBhdGgpOyB9CiAgICAgICAgICAgIHNldCB7IF9jb3JlSGVscGVyLlNldFhtbE5vZGVTdHJpbmcoQXV0aG9yUGF0aCwgdmFsdWUpOyB9CiAgICAgICAgfQoKICAgICAgICBjb25zdCBzdHJpbmcgQ29tbWVudHNQYXRoID0gImRjOmRlc2NyaXB0aW9uIjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldHMvc2V0cyB0aGUgY29tbWVudHMgcHJvcGVydHkgb2YgdGhlIGRvY3VtZW50IChjb3JlIHByb3BlcnR5KQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIHN0cmluZyBDb21tZW50cwogICAgICAgIHsKICAgICAgICAgICAgZ2V0IHsgcmV0dXJuIF9jb3JlSGVscGVyLkdldFhtbE5vZGVTdHJpbmcoQ29tbWVudHNQYXRoKTsgfQogICAgICAgICAgICBzZXQgeyBfY29yZUhlbHBlci5TZXRYbWxOb2RlU3RyaW5nKENvbW1lbnRzUGF0aCwgdmFsdWUpOyB9CiAgICAgICAgfQoKICAgICAgICBjb25zdCBzdHJpbmcgS2V5d29yZHNQYXRoID0gImNwOmtleXdvcmRzIjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldHMvc2V0cyB0aGUga2V5d29yZHMgcHJvcGVydHkgb2YgdGhlIGRvY3VtZW50IChjb3JlIHByb3BlcnR5KQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIHN0cmluZyBLZXl3b3JkcwogICAgICAgIHsKICAgICAgICAgICAgZ2V0IHsgcmV0dXJuIF9jb3JlSGVscGVyLkdldFhtbE5vZGVTdHJpbmcoS2V5d29yZHNQYXRoKTsgfQogICAgICAgICAgICBzZXQgeyBfY29yZUhlbHBlci5TZXRYbWxOb2RlU3RyaW5nKEtleXdvcmRzUGF0aCwgdmFsdWUpOyB9CiAgICAgICAgfQoKICAgICAgICBjb25zdCBzdHJpbmcgTGFzdE1vZGlmaWVkQnlQYXRoID0gImNwOmxhc3RNb2RpZmllZEJ5IjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldHMvc2V0cyB0aGUgbGFzdE1vZGlmaWVkQnkgcHJvcGVydHkgb2YgdGhlIGRvY3VtZW50IChjb3JlIHByb3BlcnR5KQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIHN0cmluZyBMYXN0TW9kaWZpZWRCeQogICAgICAgIHsKICAgICAgICAgICAgZ2V0IHsgcmV0dXJuIF9jb3JlSGVscGVyLkdldFhtbE5vZGVTdHJpbmcoTGFzdE1vZGlmaWVkQnlQYXRoKTsgfQogICAgICAgICAgICBzZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX2NvcmVIZWxwZXIuU2V0WG1sTm9kZVN0cmluZyhMYXN0TW9kaWZpZWRCeVBhdGgsIHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgY29uc3Qgc3RyaW5nIExhc3RQcmludGVkUGF0aCA9ICJjcDpsYXN0UHJpbnRlZCI7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBHZXRzL3NldHMgdGhlIGxhc3RQcmludGVkIHByb3BlcnR5IG9mIHRoZSBkb2N1bWVudCAoY29yZSBwcm9wZXJ0eSkKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBzdHJpbmcgTGFzdFByaW50ZWQKICAgICAgICB7CiAgICAgICAgICAgIGdldCB7IHJldHVybiBfY29yZUhlbHBlci5HZXRYbWxOb2RlU3RyaW5nKExhc3RQcmludGVkUGF0aCk7IH0KICAgICAgICAgICAgc2V0IHsgX2NvcmVIZWxwZXIuU2V0WG1sTm9kZVN0cmluZyhMYXN0UHJpbnRlZFBhdGgsIHZhbHVlKTsgfQogICAgICAgIH0KCiAgICAgICAgY29uc3Qgc3RyaW5nIENyZWF0ZWRQYXRoID0gImRjdGVybXM6Y3JlYXRlZCI7CgogICAgICAgIC8vLyA8c3VtbWFyeT4KCSAgICAvLy8gR2V0cy9zZXRzIHRoZSBjcmVhdGVkIHByb3BlcnR5IG9mIHRoZSBkb2N1bWVudCAoY29yZSBwcm9wZXJ0eSkKCSAgICAvLy8gPC9zdW1tYXJ5PgoJICAgIHB1YmxpYyBEYXRlVGltZSBDcmVhdGVkCgkgICAgewoJICAgICAgICBnZXQKCSAgICAgICAgewoJICAgICAgICAgICAgRGF0ZVRpbWUgZGF0ZTsKCSAgICAgICAgICAgIHJldHVybiBEYXRlVGltZS5UcnlQYXJzZShfY29yZUhlbHBlci5HZXRYbWxOb2RlU3RyaW5nKENyZWF0ZWRQYXRoKSwgb3V0IGRhdGUpID8gZGF0ZSA6IERhdGVUaW1lLk1pblZhbHVlOwoJICAgICAgICB9CgkgICAgICAgIHNldAoJICAgICAgICB7CgkgICAgICAgICAgICB2YXIgZGF0ZVN0cmluZyA9IHZhbHVlLlRvVW5pdmVyc2FsVGltZSgpLlRvU3RyaW5nKCJzIiwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkgKyAiWiI7CgkgICAgICAgICAgICBfY29yZUhlbHBlci5TZXRYbWxOb2RlU3RyaW5nKENyZWF0ZWRQYXRoLCBkYXRlU3RyaW5nKTsKICAgICAgICAgICAgICAgIF9jb3JlSGVscGVyLlNldFhtbE5vZGVTdHJpbmcoQ3JlYXRlZFBhdGggKyAiL0B4c2k6dHlwZSIsICJkY3Rlcm1zOlczQ0RURiIpOwoJICAgICAgICB9CgkgICAgfQoKICAgICAgICBjb25zdCBzdHJpbmcgQ2F0ZWdvcnlQYXRoID0gImNwOmNhdGVnb3J5IjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldHMvc2V0cyB0aGUgY2F0ZWdvcnkgcHJvcGVydHkgb2YgdGhlIGRvY3VtZW50IChjb3JlIHByb3BlcnR5KQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIHN0cmluZyBDYXRlZ29yeQogICAgICAgIHsKICAgICAgICAgICAgZ2V0IHsgcmV0dXJuIF9jb3JlSGVscGVyLkdldFhtbE5vZGVTdHJpbmcoQ2F0ZWdvcnlQYXRoKTsgfQogICAgICAgICAgICBzZXQgeyBfY29yZUhlbHBlci5TZXRYbWxOb2RlU3RyaW5nKENhdGVnb3J5UGF0aCwgdmFsdWUpOyB9CiAgICAgICAgfQoKICAgICAgICBjb25zdCBzdHJpbmcgQ29udGVudFN0YXR1c1BhdGggPSAiY3A6Y29udGVudFN0YXR1cyI7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBHZXRzL3NldHMgdGhlIHN0YXR1cyBwcm9wZXJ0eSBvZiB0aGUgZG9jdW1lbnQgKGNvcmUgcHJvcGVydHkpCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgc3RyaW5nIFN0YXR1cwogICAgICAgIHsKICAgICAgICAgICAgZ2V0IHsgcmV0dXJuIF9jb3JlSGVscGVyLkdldFhtbE5vZGVTdHJpbmcoQ29udGVudFN0YXR1c1BhdGgpOyB9CiAgICAgICAgICAgIHNldCB7IF9jb3JlSGVscGVyLlNldFhtbE5vZGVTdHJpbmcoQ29udGVudFN0YXR1c1BhdGgsIHZhbHVlKTsgfQogICAgICAgIH0KICAgICAgICAjZW5kcmVnaW9uCgogICAgICAgICNyZWdpb24gRXh0ZW5kZWQgUHJvcGVydGllcwogICAgICAgICNyZWdpb24gRXh0ZW5kZWRQcm9wZXJ0aWVzWG1sCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBQcm92aWRlcyBhY2Nlc3MgdG8gdGhlIFhNTCBkb2N1bWVudCB0aGF0IGhvbGRzIHRoZSBleHRlbmRlZCBwcm9wZXJ0aWVzIG9mIHRoZSBkb2N1bWVudCAoYXBwLnhtbCkKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBYbWxEb2N1bWVudCBFeHRlbmRlZFByb3BlcnRpZXNYbWwKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX3htbFByb3BlcnRpZXNFeHRlbmRlZCA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF94bWxQcm9wZXJ0aWVzRXh0ZW5kZWQgPSBHZXRYbWxEb2N1bWVudChzdHJpbmcuRm9ybWF0KCI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVVEYtOFwiIHN0YW5kYWxvbmU9XCJ5ZXNcIiA/PjxQcm9wZXJ0aWVzIHhtbG5zOnZ0PVwiezB9XCIgeG1sbnM9XCJ7MX1cIj48L1Byb3BlcnRpZXM+IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VsUGFja2FnZS5zY2hlbWFWdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VsUGFja2FnZS5zY2hlbWFFeHRlbmRlZCksCiAgICAgICAgICAgICAgICAgICAgICAgIF91cmlQcm9wZXJ0aWVzRXh0ZW5kZWQsCiAgICAgICAgICAgICAgICAgICAgICAgIEAiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LmV4dGVuZGVkLXByb3BlcnRpZXMreG1sIiwKICAgICAgICAgICAgICAgICAgICAgICAgQCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzL2V4dGVuZGVkLXByb3BlcnRpZXMiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAoX3htbFByb3BlcnRpZXNFeHRlbmRlZCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgI2VuZHJlZ2lvbgoKICAgICAgICBjb25zdCBzdHJpbmcgQXBwbGljYXRpb25QYXRoID0gInhwOlByb3BlcnRpZXMveHA6QXBwbGljYXRpb24iOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0cy9TZXQgdGhlIEFwcGxpY2F0aW9uIHByb3BlcnR5IG9mIHRoZSBkb2N1bWVudCAoZXh0ZW5kZWQgcHJvcGVydHkpCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgc3RyaW5nIEFwcGxpY2F0aW9uCiAgICAgICAgewogICAgICAgICAgICBnZXQgeyByZXR1cm4gX2V4dGVuZGVkSGVscGVyLkdldFhtbE5vZGVTdHJpbmcoQXBwbGljYXRpb25QYXRoKTsgfQogICAgICAgICAgICBzZXQgeyBfZXh0ZW5kZWRIZWxwZXIuU2V0WG1sTm9kZVN0cmluZyhBcHBsaWNhdGlvblBhdGgsIHZhbHVlKTsgfQogICAgICAgIH0KCiAgICAgICAgY29uc3Qgc3RyaW5nIEh5cGVybGlua0Jhc2VQYXRoID0gInhwOlByb3BlcnRpZXMveHA6SHlwZXJsaW5rQmFzZSI7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBHZXRzL3NldHMgdGhlIEh5cGVybGlua0Jhc2UgcHJvcGVydHkgb2YgdGhlIGRvY3VtZW50IChleHRlbmRlZCBwcm9wZXJ0eSkKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBVcmkgSHlwZXJsaW5rQmFzZQogICAgICAgIHsKICAgICAgICAgICAgZ2V0IHsgcmV0dXJuIG5ldyBVcmkoX2V4dGVuZGVkSGVscGVyLkdldFhtbE5vZGVTdHJpbmcoSHlwZXJsaW5rQmFzZVBhdGgpLCBVcmlLaW5kLkFic29sdXRlKTsgfQogICAgICAgICAgICBzZXQgeyBfZXh0ZW5kZWRIZWxwZXIuU2V0WG1sTm9kZVN0cmluZyhIeXBlcmxpbmtCYXNlUGF0aCwgdmFsdWUuQWJzb2x1dGVVcmkpOyB9CiAgICAgICAgfQoKICAgICAgICBjb25zdCBzdHJpbmcgQXBwVmVyc2lvblBhdGggPSAieHA6UHJvcGVydGllcy94cDpBcHBWZXJzaW9uIjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldHMvU2V0IHRoZSBBcHBWZXJzaW9uIHByb3BlcnR5IG9mIHRoZSBkb2N1bWVudCAoZXh0ZW5kZWQgcHJvcGVydHkpCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgc3RyaW5nIEFwcFZlcnNpb24KICAgICAgICB7CiAgICAgICAgICAgIGdldCB7IHJldHVybiBfZXh0ZW5kZWRIZWxwZXIuR2V0WG1sTm9kZVN0cmluZyhBcHBWZXJzaW9uUGF0aCk7IH0KICAgICAgICAgICAgc2V0IHsgX2V4dGVuZGVkSGVscGVyLlNldFhtbE5vZGVTdHJpbmcoQXBwVmVyc2lvblBhdGgsIHZhbHVlKTsgfQogICAgICAgIH0KICAgICAgICBjb25zdCBzdHJpbmcgQ29tcGFueVBhdGggPSAieHA6UHJvcGVydGllcy94cDpDb21wYW55IjsKCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBHZXRzL3NldHMgdGhlIENvbXBhbnkgcHJvcGVydHkgb2YgdGhlIGRvY3VtZW50IChleHRlbmRlZCBwcm9wZXJ0eSkKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBzdHJpbmcgQ29tcGFueQogICAgICAgIHsKICAgICAgICAgICAgZ2V0IHsgcmV0dXJuIF9leHRlbmRlZEhlbHBlci5HZXRYbWxOb2RlU3RyaW5nKENvbXBhbnlQYXRoKTsgfQogICAgICAgICAgICBzZXQgeyBfZXh0ZW5kZWRIZWxwZXIuU2V0WG1sTm9kZVN0cmluZyhDb21wYW55UGF0aCwgdmFsdWUpOyB9CiAgICAgICAgfQoKICAgICAgICBjb25zdCBzdHJpbmcgTWFuYWdlclBhdGggPSAieHA6UHJvcGVydGllcy94cDpNYW5hZ2VyIjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldHMvc2V0cyB0aGUgTWFuYWdlciBwcm9wZXJ0eSBvZiB0aGUgZG9jdW1lbnQgKGV4dGVuZGVkIHByb3BlcnR5KQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIHN0cmluZyBNYW5hZ2VyCiAgICAgICAgewogICAgICAgICAgICBnZXQgeyByZXR1cm4gX2V4dGVuZGVkSGVscGVyLkdldFhtbE5vZGVTdHJpbmcoTWFuYWdlclBhdGgpOyB9CiAgICAgICAgICAgIHNldCB7IF9leHRlbmRlZEhlbHBlci5TZXRYbWxOb2RlU3RyaW5nKE1hbmFnZXJQYXRoLCB2YWx1ZSk7IH0KICAgICAgICB9CgogICAgICAgIGNvbnN0IHN0cmluZyBNb2RpZmllZFBhdGggPSAiZGN0ZXJtczptb2RpZmllZCI7CgkgICAgLy8vIDxzdW1tYXJ5PgoJICAgIC8vLyBHZXRzL3NldHMgdGhlIG1vZGlmaWVkIHByb3BlcnR5IG9mIHRoZSBkb2N1bWVudCAoY29yZSBwcm9wZXJ0eSkKCSAgICAvLy8gPC9zdW1tYXJ5PgoJICAgIHB1YmxpYyBEYXRlVGltZSBNb2RpZmllZAoJICAgIHsKCSAgICAgICAgZ2V0CgkgICAgICAgIHsKCSAgICAgICAgICAgIERhdGVUaW1lIGRhdGU7CgkgICAgICAgICAgICByZXR1cm4gRGF0ZVRpbWUuVHJ5UGFyc2UoX2NvcmVIZWxwZXIuR2V0WG1sTm9kZVN0cmluZyhNb2RpZmllZFBhdGgpLCBvdXQgZGF0ZSkgPyBkYXRlIDogRGF0ZVRpbWUuTWluVmFsdWU7CgkgICAgICAgIH0KCSAgICAgICAgc2V0CgkgICAgICAgIHsKCSAgICAgICAgICAgIHZhciBkYXRlU3RyaW5nID0gdmFsdWUuVG9Vbml2ZXJzYWxUaW1lKCkuVG9TdHJpbmcoInMiLCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSArICJaIjsKCSAgICAgICAgICAgIF9jb3JlSGVscGVyLlNldFhtbE5vZGVTdHJpbmcoTW9kaWZpZWRQYXRoLCBkYXRlU3RyaW5nKTsKICAgICAgICAgICAgICAgIF9jb3JlSGVscGVyLlNldFhtbE5vZGVTdHJpbmcoTW9kaWZpZWRQYXRoICsgIi9AeHNpOnR5cGUiLCAiZGN0ZXJtczpXM0NEVEYiKTsKCSAgICAgICAgfQoJICAgIH0KCiAgICAgICAgI3JlZ2lvbiBHZXQgYW5kIFNldCBFeHRlbmRlZCBQcm9wZXJ0aWVzCiAgICAgICAgcHJpdmF0ZSBzdHJpbmcgR2V0RXh0ZW5kZWRQcm9wZXJ0eVZhbHVlKHN0cmluZyBwcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICBzdHJpbmcgcmV0VmFsdWUgPSBudWxsOwogICAgICAgICAgICBzdHJpbmcgc2VhcmNoU3RyaW5nID0gc3RyaW5nLkZvcm1hdCgieHA6UHJvcGVydGllcy94cDp7MH0iLCBwcm9wZXJ0eU5hbWUpOwogICAgICAgICAgICBYbWxOb2RlIG5vZGUgPSBFeHRlbmRlZFByb3BlcnRpZXNYbWwuU2VsZWN0U2luZ2xlTm9kZShzZWFyY2hTdHJpbmcsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICBpZiAobm9kZSAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXRWYWx1ZSA9IG5vZGUuSW5uZXJUZXh0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXRWYWx1ZTsKICAgICAgICB9CiAgICAgICAgI2VuZHJlZ2lvbgogICAgICAgICNlbmRyZWdpb24KCiAgICAgICAgI3JlZ2lvbiBDdXN0b20gUHJvcGVydGllcwoKICAgICAgICAjcmVnaW9uIEN1c3RvbVByb3BlcnRpZXNYbWwKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgWE1MIGRvY3VtZW50IHdoaWNoIGhvbGRzIHRoZSBkb2N1bWVudCdzIGN1c3RvbSBwcm9wZXJ0aWVzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgWG1sRG9jdW1lbnQgQ3VzdG9tUHJvcGVydGllc1htbAogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfeG1sUHJvcGVydGllc0N1c3RvbSA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF94bWxQcm9wZXJ0aWVzQ3VzdG9tID0gR2V0WG1sRG9jdW1lbnQoc3RyaW5nLkZvcm1hdCgiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIiBzdGFuZGFsb25lPVwieWVzXCIgPz48UHJvcGVydGllcyB4bWxuczp2dD1cInswfVwiIHhtbG5zPVwiezF9XCI+PC9Qcm9wZXJ0aWVzPiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeGNlbFBhY2thZ2Uuc2NoZW1hVnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeGNlbFBhY2thZ2Uuc2NoZW1hQ3VzdG9tKSwKICAgICAgICAgICAgICAgICAgICAgICAgIF91cmlQcm9wZXJ0aWVzQ3VzdG9tLCAKICAgICAgICAgICAgICAgICAgICAgICAgIEAiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LmN1c3RvbS1wcm9wZXJ0aWVzK3htbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICBAImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9vZmZpY2VEb2N1bWVudC8yMDA2L3JlbGF0aW9uc2hpcHMvY3VzdG9tLXByb3BlcnRpZXMiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAoX3htbFByb3BlcnRpZXNDdXN0b20pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICNlbmRyZWdpb24KCiAgICAgICAgI3JlZ2lvbiBHZXQgYW5kIFNldCBDdXN0b20gUHJvcGVydGllcwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0cyB0aGUgdmFsdWUgb2YgYSBjdXN0b20gcHJvcGVydHkKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icHJvcGVydHlOYW1lIj5UaGUgbmFtZSBvZiB0aGUgcHJvcGVydHk8L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcHJvcGVydHk8L3JldHVybnM+CiAgICAgICAgcHVibGljIG9iamVjdCBHZXRDdXN0b21Qcm9wZXJ0eVZhbHVlKHN0cmluZyBwcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICBzdHJpbmcgc2VhcmNoU3RyaW5nID0gc3RyaW5nLkZvcm1hdCgiY3RwOlByb3BlcnRpZXMvY3RwOnByb3BlcnR5W0BuYW1lPSd7MH0nXSIsIHByb3BlcnR5TmFtZSk7CiAgICAgICAgICAgIFhtbEVsZW1lbnQgbm9kZSA9IEN1c3RvbVByb3BlcnRpZXNYbWwuU2VsZWN0U2luZ2xlTm9kZShzZWFyY2hTdHJpbmcsIE5hbWVTcGFjZU1hbmFnZXIpIGFzIFhtbEVsZW1lbnQ7CiAgICAgICAgICAgIGlmIChub2RlICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmluZyB2YWx1ZSA9IG5vZGUuTGFzdENoaWxkLklubmVyVGV4dDsKICAgICAgICAgICAgICAgIHN3aXRjaCAobm9kZS5MYXN0Q2hpbGQuTG9jYWxOYW1lKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhc2UgImZpbGV0aW1lIjoKICAgICAgICAgICAgICAgICAgICAgICAgRGF0ZVRpbWUgZHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChEYXRlVGltZS5UcnlQYXJzZSh2YWx1ZSwgb3V0IGR0KSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGR0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXNlICJpNCI6CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW50LlRyeVBhcnNlKHZhbHVlLCBvdXQgaSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXNlICJyOCI6CiAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBkOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG91YmxlLlRyeVBhcnNlKHZhbHVlLCBOdW1iZXJTdHlsZXMuQW55LCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlLCBvdXQgZCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXNlICJib29sIjoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09ICJ0cnVlIikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gImZhbHNlIikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBbGxvd3MgeW91IHRvIHNldCB0aGUgdmFsdWUgb2YgYSBjdXJyZW50IGN1c3RvbSBwcm9wZXJ0eSBvciBjcmVhdGUgeW91ciBvd24gY3VzdG9tIHByb3BlcnR5LiAgCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InByb3BlcnR5TmFtZSI+VGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InZhbHVlIj5UaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5PC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZXRDdXN0b21Qcm9wZXJ0eVZhbHVlKHN0cmluZyBwcm9wZXJ0eU5hbWUsIG9iamVjdCB2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIFhtbE5vZGUgYWxsUHJvcHMgPSBDdXN0b21Qcm9wZXJ0aWVzWG1sLlNlbGVjdFNpbmdsZU5vZGUoQCJjdHA6UHJvcGVydGllcyIsIE5hbWVTcGFjZU1hbmFnZXIpOwoKICAgICAgICAgICAgdmFyIHByb3AgPSBzdHJpbmcuRm9ybWF0KCJjdHA6UHJvcGVydGllcy9jdHA6cHJvcGVydHlbQG5hbWU9J3swfSddIiwgcHJvcGVydHlOYW1lKTsKICAgICAgICAgICAgWG1sRWxlbWVudCBub2RlID0gQ3VzdG9tUHJvcGVydGllc1htbC5TZWxlY3RTaW5nbGVOb2RlKHByb3AsIE5hbWVTcGFjZU1hbmFnZXIpIGFzIFhtbEVsZW1lbnQ7CiAgICAgICAgICAgIGlmIChub2RlID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCBwaWQ7CiAgICAgICAgICAgICAgICB2YXIgTWF4Tm9kZSA9IEN1c3RvbVByb3BlcnRpZXNYbWwuU2VsZWN0U2luZ2xlTm9kZSgiY3RwOlByb3BlcnRpZXMvY3RwOnByb3BlcnR5W25vdChAcGlkIDw9IHByZWNlZGluZy1zaWJsaW5nOjpjdHA6cHJvcGVydHkvQHBpZCkgYW5kIG5vdChAcGlkIDw9IGZvbGxvd2luZy1zaWJsaW5nOjpjdHA6cHJvcGVydHkvQHBpZCldIiwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgICAgICBpZiAoTWF4Tm9kZSA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHBpZCA9IDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpbnQuVHJ5UGFyc2UoTWF4Tm9kZS5BdHRyaWJ1dGVzWyJwaWQiXS5WYWx1ZSwgb3V0IHBpZCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBwaWQgPSAyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwaWQrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5vZGUgPSBDdXN0b21Qcm9wZXJ0aWVzWG1sLkNyZWF0ZUVsZW1lbnQoInByb3BlcnR5IiwgRXhjZWxQYWNrYWdlLnNjaGVtYUN1c3RvbSk7CiAgICAgICAgICAgICAgICBub2RlLlNldEF0dHJpYnV0ZSgiZm10aWQiLCAie0Q1Q0RENTA1LTJFOUMtMTAxQi05Mzk3LTA4MDAyQjJDRjlBRX0iKTsKICAgICAgICAgICAgICAgIG5vZGUuU2V0QXR0cmlidXRlKCJwaWQiLCBwaWQuVG9TdHJpbmcoKSk7ICAvLyBjdXN0b20gcHJvcGVydHkgcGlkCiAgICAgICAgICAgICAgICBub2RlLlNldEF0dHJpYnV0ZSgibmFtZSIsIHByb3BlcnR5TmFtZSk7CgogICAgICAgICAgICAgICAgYWxsUHJvcHMuQXBwZW5kQ2hpbGQobm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB3aGlsZSAobm9kZS5DaGlsZE5vZGVzLkNvdW50ID4gMCkgbm9kZS5SZW1vdmVDaGlsZChub2RlLkNoaWxkTm9kZXNbMF0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFhtbEVsZW1lbnQgdmFsdWVFbGVtOwogICAgICAgICAgICBpZiAodmFsdWUgaXMgYm9vbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFsdWVFbGVtID0gQ3VzdG9tUHJvcGVydGllc1htbC5DcmVhdGVFbGVtZW50KCJ2dCIsICJib29sIiwgRXhjZWxQYWNrYWdlLnNjaGVtYVZ0KTsKICAgICAgICAgICAgICAgIHZhbHVlRWxlbS5Jbm5lclRleHQgPSB2YWx1ZS5Ub1N0cmluZygpLlRvTG93ZXIoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgaXMgRGF0ZVRpbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhbHVlRWxlbSA9IEN1c3RvbVByb3BlcnRpZXNYbWwuQ3JlYXRlRWxlbWVudCgidnQiLCAiZmlsZXRpbWUiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hVnQpOwogICAgICAgICAgICAgICAgdmFsdWVFbGVtLklubmVyVGV4dCA9ICgoRGF0ZVRpbWUpdmFsdWUpLkFkZEhvdXJzKC0xKS5Ub1N0cmluZygieXl5eS1NTS1kZFRISDptbTpzc1oiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpcyBzaG9ydCB8fCB2YWx1ZSBpcyBpbnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhbHVlRWxlbSA9IEN1c3RvbVByb3BlcnRpZXNYbWwuQ3JlYXRlRWxlbWVudCgidnQiLCAiaTQiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hVnQpOwogICAgICAgICAgICAgICAgdmFsdWVFbGVtLklubmVyVGV4dCA9IHZhbHVlLlRvU3RyaW5nKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgaXMgZG91YmxlIHx8IHZhbHVlIGlzIGRlY2ltYWwgfHwgdmFsdWUgaXMgZmxvYXQgfHwgdmFsdWUgaXMgbG9uZykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFsdWVFbGVtID0gQ3VzdG9tUHJvcGVydGllc1htbC5DcmVhdGVFbGVtZW50KCJ2dCIsICJyOCIsIEV4Y2VsUGFja2FnZS5zY2hlbWFWdCk7CiAgICAgICAgICAgICAgICBpZiAodmFsdWUgaXMgZG91YmxlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhbHVlRWxlbS5Jbm5lclRleHQgPSAoKGRvdWJsZSl2YWx1ZSkuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpcyBmbG9hdCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YWx1ZUVsZW0uSW5uZXJUZXh0ID0gKChmbG9hdCl2YWx1ZSkuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpcyBkZWNpbWFsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhbHVlRWxlbS5Jbm5lclRleHQgPSAoKGRlY2ltYWwpdmFsdWUpLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhbHVlRWxlbS5Jbm5lclRleHQgPSB2YWx1ZS5Ub1N0cmluZygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFsdWVFbGVtID0gQ3VzdG9tUHJvcGVydGllc1htbC5DcmVhdGVFbGVtZW50KCJ2dCIsICJscHdzdHIiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hVnQpOwogICAgICAgICAgICAgICAgdmFsdWVFbGVtLklubmVyVGV4dCA9IHZhbHVlLlRvU3RyaW5nKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbm9kZS5BcHBlbmRDaGlsZCh2YWx1ZUVsZW0pOwogICAgICAgIH0KICAgICAgICAjZW5kcmVnaW9uCiAgICAgICAgI2VuZHJlZ2lvbgoKICAgICAgICAjcmVnaW9uIFNhdmUKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNhdmVzIHRoZSBkb2N1bWVudCBwcm9wZXJ0aWVzIGJhY2sgdG8gdGhlIHBhY2thZ2UuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBpbnRlcm5hbCB2b2lkIFNhdmUoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKF94bWxQcm9wZXJ0aWVzQ29yZSAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfcGFja2FnZS5TYXZlUGFydChfdXJpUHJvcGVydGllc0NvcmUsIF94bWxQcm9wZXJ0aWVzQ29yZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKF94bWxQcm9wZXJ0aWVzRXh0ZW5kZWQgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3BhY2thZ2UuU2F2ZVBhcnQoX3VyaVByb3BlcnRpZXNFeHRlbmRlZCwgX3htbFByb3BlcnRpZXNFeHRlbmRlZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKF94bWxQcm9wZXJ0aWVzQ3VzdG9tICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF9wYWNrYWdlLlNhdmVQYXJ0KF91cmlQcm9wZXJ0aWVzQ3VzdG9tLCBfeG1sUHJvcGVydGllc0N1c3RvbSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgfQogICAgICAgICNlbmRyZWdpb24KCiAgICB9Cn0K