{"id":"CVE-2016-6816","description":"The code in Apache Tomcat 9.0.0.M1 to 9.0.0.M11, 8.5.0 to 8.5.6, 8.0.0.RC1 to 8.0.38, 7.0.0 to 7.0.72, and 6.0.0 to 6.0.47 that parsed the HTTP request line permitted invalid characters. This could be exploited, in conjunction with a proxy that also permitted the invalid characters but with a different interpretation, to inject data into the HTTP response. By manipulating the HTTP response the attacker could poison a web-cache, perform an XSS attack and/or obtain sensitive information from requests other then their own.","cvssScore":7.1,"cvssVersion":"3.0","cvssVector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:L","cvssMetrics":[{"version":"3.0","score":7.1,"severity":"HIGH","vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:L","source":"nvd@nist.gov","sourceName":"NVD","type":"Primary"},{"version":"2.0","score":6.8,"vector":"AV:N/AC:M/Au:N/C:P/I:P/A:P","source":"nvd@nist.gov","sourceName":"NVD","type":"Primary"}],"cwes":["CWE-20"],"resolved":"MITIGATED-BY-RASP","published":"2017-03-20","lastModified":"2026-06-17","affectedProducts":[{"vendor":"apache","product":"tomcat","version":"6.0.0"},{"vendor":"apache","product":"tomcat","version":"6.0.1"},{"vendor":"apache","product":"tomcat","version":"6.0.2"},{"vendor":"apache","product":"tomcat","version":"6.0.3"},{"vendor":"apache","product":"tomcat","version":"6.0.4"},{"vendor":"apache","product":"tomcat","version":"6.0.5"},{"vendor":"apache","product":"tomcat","version":"6.0.6"},{"vendor":"apache","product":"tomcat","version":"6.0.7"},{"vendor":"apache","product":"tomcat","version":"6.0.8"},{"vendor":"apache","product":"tomcat","version":"6.0.9"},{"vendor":"apache","product":"tomcat","version":"6.0.10"},{"vendor":"apache","product":"tomcat","version":"6.0.11"},{"vendor":"apache","product":"tomcat","version":"6.0.12"},{"vendor":"apache","product":"tomcat","version":"6.0.13"},{"vendor":"apache","product":"tomcat","version":"6.0.14"},{"vendor":"apache","product":"tomcat","version":"6.0.15"},{"vendor":"apache","product":"tomcat","version":"6.0.16"},{"vendor":"apache","product":"tomcat","version":"6.0.17"},{"vendor":"apache","product":"tomcat","version":"6.0.18"},{"vendor":"apache","product":"tomcat","version":"6.0.19"}],"totalAffectedProducts":1,"references":[{"url":"https://github.com/apache/tomcat/commit/516bda676ac8d0284da3e0295a7df70391315360","source":"osv","tags":["WEB"]},{"url":"https://github.com/apache/tomcat/commit/cdc0a935c2173aff60039a0b85e57a461381107c","source":"osv","tags":["WEB"]},{"url":"https://github.com/apache/tomcat/commit/f96f5751d418ae5a2f550be040daf9c5f7d99256","source":"osv","tags":["WEB"]},{"url":"https://github.com/apache/tomcat80/commit/779d5d34e68e50d2f721897050b147106992f566","source":"osv","tags":["WEB"]},{"url":"https://access.redhat.com/errata/RHSA-2017:0455","source":"osv","tags":["WEB"]},{"url":"https://lists.apache.org/thread.html/b8a1bf18155b552dcf9a928ba808cbadad84c236d85eab3033662cfb@%3Cdev.tomcat.apache.org%3E","source":"osv","tags":["WEB"]},{"url":"https://lists.apache.org/thread.html/r03c597a64de790ba42c167efacfa23300c3d6c9fe589ab87fe02859c%40%3Cdev.tomcat.apache.org%3E","source":"osv","tags":["WEB"]},{"url":"https://lists.apache.org/thread.html/r03c597a64de790ba42c167efacfa23300c3d6c9fe589ab87fe02859c@%3Cdev.tomcat.apache.org%3E","source":"osv","tags":["WEB"]},{"url":"https://lists.apache.org/thread.html/r587e50b86c1a96ee301f751d50294072d142fd6dc08a8987ae9f3a9b%40%3Cdev.tomcat.apache.org%3E","source":"osv","tags":["WEB"]},{"url":"https://lists.apache.org/thread.html/r587e50b86c1a96ee301f751d50294072d142fd6dc08a8987ae9f3a9b@%3Cdev.tomcat.apache.org%3E","source":"osv","tags":["WEB"]}],"reasoning":{"decidingSource":"armr-patch-file","decidingReason":"CVE has an ARMR patch rule that provides mitigation","verdicts":[{"rule":"rejected","stage":"identity","outcome":"no-match"},{"rule":"armr-patch-file","stage":"scope","outcome":"matched","status":"MITIGATED-BY-RASP","detail":"ARMR patch file exists for this CVE","decisive":true}],"affectedPackages":[{"name":"org.apache.tomcat:tomcat-coyote","introduced":"9.0.0.M1","fixed":"9.0.0.M12"},{"name":"org.apache.tomcat:tomcat-coyote","introduced":"8.5.0","fixed":"8.5.8"},{"name":"org.apache.tomcat:tomcat-coyote","introduced":"8.0.0RC1","fixed":"8.0.39"},{"name":"org.apache.tomcat:tomcat-coyote","introduced":"7.0.0","fixed":"7.0.73"},{"name":"org.apache.tomcat:tomcat-coyote","introduced":"6.0.0","fixed":"6.0.48"}]},"relatedFiles":{"patchFiles":[{"path":"rules/appservers/tomcat/CVE-2016-6816/patch/2.6/CVE-2016-6816.armr","url":"https://github.com/waratek/java-patches/blob/develop/rules/appservers/tomcat/CVE-2016-6816/patch/2.6/CVE-2016-6816.armr","updated":"2026-03-04T16:48:46Z","content":"YXBwKCJBUEFDSEUgVE9NQ0FUIik6CiAgICByZXF1aXJlcyh2ZXJzaW9uOiBBUk1SLzIuNikKCiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgQ1ZFLTIwMTYtNjgxNiAoQVBBQ0hFIFRPTUNBVCkKCiAgICAgICAgQ1ZTUyAzLjAgU3VtbWFyeToKICAgICAgICAgICAgQmFzZSBTY29yZSAgICAgICAgICB8IDcuMQogICAgICAgICAgICBBdHRhY2sgVmVjdG9yICAgICAgIHwgTmV0d29yawogICAgICAgICAgICBBdHRhY2sgQ29tcGxleGl0eSAgIHwgTG93CiAgICAgICAgICAgIFByaXZpbGVnZXMgUmVxdWlyZWQgfCBOb25lCiAgICAgICAgICAgIFVzZXIgSW50ZXJhY3Rpb24gICAgfCBSZXF1aXJlZAogICAgICAgICAgICBTY29wZSAgICAgICAgICAgICAgIHwgQ2hhbmdlZAogICAgICAgICAgICBDb25maWRlbnRpYWxpdHkgICAgIHwgTG93CiAgICAgICAgICAgIEludGVncml0eSAgICAgICAgICAgfCBMb3cKICAgICAgICAgICAgQXZhaWxhYmlsaXR5ICAgICAgICB8IExvdwoKICAgICAgICBEZXNjcmlwdGlvbjoKICAgICAgICAgICAgVGhlIGNvZGUgdGhhdCBwYXJzZWQgdGhlIEhUVFAgcmVxdWVzdCBsaW5lIHBlcm1pdHRlZCBpbnZhbGlkCiAgICAgICAgICAgIGNoYXJhY3RlcnMuIFRoaXMgY291bGQgYmUgZXhwbG9pdGVkLCBpbiBjb25qdW5jdGlvbiB3aXRoIGEgcHJveHkKICAgICAgICAgICAgdGhhdCBhbHNvIHBlcm1pdHRlZCB0aGUgaW52YWxpZCBjaGFyYWN0ZXJzIGJ1dCB3aXRoIGEgZGlmZmVyZW50CiAgICAgICAgICAgIGludGVycHJldGF0aW9uLCB0byBpbmplY3QgZGF0YSBpbnRvIHRoZSBIVFRQIHJlc3BvbnNlLiBCeQogICAgICAgICAgICBtYW5pcHVsYXRpbmcgdGhlIEhUVFAgcmVzcG9uc2UgdGhlIGF0dGFja2VyIGNvdWxkIHBvaXNvbiBhCiAgICAgICAgICAgIHdlYi1jYWNoZSwgcGVyZm9ybSBhbiBYU1MgYXR0YWNrIGFuZC9vciBvYnRhaW4gc2Vuc2l0aXZlIGluZm9ybWF0aW9uCiAgICAgICAgICAgIGZyb20gcmVxdWVzdHMgb3RoZXIgdGhlbiB0aGVpciBvd24uCgogICAgICAgIFJlc291cmNlczoKICAgICAgICAgICAgaHR0cHM6Ly93d3cuZXhwbG9pdC1kYi5jb20vZXhwbG9pdHMvNDE3ODMvCiAgICAgICAgICAgIGh0dHBzOi8vd3d3LnczLm9yZy9Qcm90b2NvbHMvcmZjMjYxNi9yZmMyNjE2LXNlYzIuaHRtbAogICAgICAgICAgICBodHRwczovL2dpdGh1Yi5jb20vYXBhY2hlL3RvbWNhdDgwL2NvbW1pdC83NzlkNWQzNGU2OGU1MGQyZjcyMTg5NzA1MGIxNDcxMDY5OTJmNTY2CiAgICAgICAgICAgIGh0dHBzOi8vdG9tY2F0LmFwYWNoZS5vcmcvc2VjdXJpdHktNi5odG1sI0ZpeGVkX2luX0FwYWNoZV9Ub21jYXRfNi4wLjQ4CiAgICAgICAgICAgIGh0dHA6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZyZXZpc2lvbj0xNzY3NjgzCgogICAgICAgIEFmZmVjdGVkIE9wZXJhdGluZyBTeXN0ZW1zOgogICAgICAgICAgICBBbnkKCiAgICAgICAgQWZmZWN0ZWQgVmVyc2lvbnM6CiAgICAgICAgICAgIEFwYWNoZSBUb21jYXQ6CiAgICAgICAgICAgICAgICA2LjAuMCAtIDYuMC40NwogICAgICAgICAgICAgICAgNy4wLjAgLSA3LjAuNzIKICAgICAgICAgICAgICAgIDguMC4wLlJDMSAtIDguMC4zOAogICAgICAgICAgICAgICAgOC41LjAgLSA4LjUuNgogICAgICAgICAgICAgICAgOS4wLjAuTTEgLSA5LjAuMC5NMTEKCiAgICAgICAgVGVzdGVkIFZlcnNpb25zOgogICAgICAgICAgICBBcGFjaGUgVG9tY2F0IDYuMC40NSwgNi4wLjQ3LCA4LjAuMzgKCiAgICAgICAgUHJvdGVjdGlvbiBQcm92aWRlZDoKICAgICAgICAgICAgRnVuY3Rpb25hbAoKICAgICAgICBQYXRjaCBWZXJzaW9uOgogICAgICAgICAgICAxLjAKICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgQ1ZFLTIwMTYtNjgxNjogVG9tY2F0IDYuMC40NSwgNi4wLjQ3CiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgcGF0Y2goIkNWRS0yMDE2LTY4MTYgOlRDNiAwMSIpOgogICAgICAgIGZ1bmN0aW9uKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxOaW9JbnB1dEJ1ZmZlci5wYXJzZVJlcXVlc3RMaW5lKFopWiIsCiAgICAgICAgICAgIGNoZWNrc3VtczogWyI1ZTA3ZTQzNWZjIiwgIjg5NTkzNTRmMmIiXSkgLy8gNi4wLjQ1LCA2LjAuNDcKICAgICAgICByZWFkcmV0dXJuKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxOaW9JbnB1dEJ1ZmZlci5sYXN0VmFsaWQiLAogICAgICAgICAgICBvY2N1cnJlbmNlczogWzRdKQoKICAgICAgICBjb2RlKGxhbmd1YWdlOiBqYXZhLCBpbXBvcnQ6IFsiamF2YS5pby5FT0ZFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcmcuYXBhY2hlLmNveW90ZS5odHRwMTEuQ29uc3RhbnRzIl0pOgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQVJSQVlfU0laRSA9IDEyODsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0NPTlRST0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1NFUEFSQVRPUiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfVE9LRU4gPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hFWCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfTk9UX1JFUVVFU1RfVEFSR0VUID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IVFRQX1BST1RPQ09MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CgogICAgICAgICAgICBzdGF0aWMgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBBUlJBWV9TSVpFOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAvLyBDb250cm9sPiAwLTMxLCAxMjcKICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IDMyIHx8IGkgPT0gMTI3KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0NPTlRST0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gU2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCAgICBpID09ICcoJyB8fCBpID09ICcpJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyAgfHwgaSA9PSAnQCcgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcsJyB8fCBpID09ICc7JyB8fCBpID09ICc6JyB8fCBpID09ICdcXCcgfHwgaSA9PSAnXCInIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcvJyB8fCBpID09ICdbJyB8fCBpID09ICddJyB8fCBpID09ICc/JyAgfHwgaSA9PSAnPScgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICd7JyB8fCBpID09ICd9JyB8fCBpID09ICcgJyB8fCBpID09ICdcdCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfU0VQQVJBVE9SW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFRva2VuOiBBbnl0aGluZyAwLTEyNyB0aGF0IGlzIG5vdCBhIGNvbnRyb2wgYW5kIG5vdCBhIHNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICghSVNfQ09OVFJPTFtpXSAmJiAhSVNfU0VQQVJBVE9SW2ldICYmIGkgPCAxMjgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfVE9LRU5baV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gSGV4OiAwLTksIGEtZiwgQS1GCiAgICAgICAgICAgICAgICAgICAgaWYgKChpID49ICcwJyAmJiBpIDw9JzknKSB8fCAoaSA+PSAnYScgJiYgaSA8PSAnZicpIHx8IChpID49ICdBJyAmJiBpIDw9ICdGJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSEVYW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgcmVxdWVzdCB0YXJnZXQuCiAgICAgICAgICAgICAgICAgICAgLy8gQ29tYmluYXRpb24gb2YgbXVsdGlwbGUgcnVsZXMgZnJvbSBSRkM3MjMwIGFuZCBSRkMgMzk4Ni4gTXVzdCBiZQogICAgICAgICAgICAgICAgICAgIC8vIEFTQ0lJLCBubyBjb250cm9scyBwbHVzIGEgZmV3IGFkZGl0aW9uYWwgY2hhcmFjdGVycyBleGNsdWRlZAogICAgICAgICAgICAgICAgICAgIGlmIChJU19DT05UUk9MW2ldIHx8IGkgPiAxMjcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJyAnIHx8IGkgPT0gJ1wiJyB8fCBpID09ICcjJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyB8fCBpID09ICdcXCcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ14nIHx8IGkgPT0gJ2AnICB8fCBpID09ICd7JyB8fCBpID09ICd8JyB8fCBpID09ICd9JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19OT1RfUkVRVUVTVF9UQVJHRVRbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciBIVFRQIHByb3RvY29sCiAgICAgICAgICAgICAgICAgICAgLy8gIkhUVFAvIiBESUdJVCAiLiIgRElHSVQKICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAnSCcgfHwgaSA9PSAnVCcgfHwgaSA9PSAnUCcgfHwgaSA9PSAnLycgfHwgaSA9PSAnLicgfHwgKGkgPj0gJzAnICYmIGkgPD0gJzknKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IVFRQX1BST1RPQ09MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBidWZGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIHBvc0ZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhTWV0aG9kIGZpbGxNZXRob2Q7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBsb2FkKCkgewogICAgICAgICAgICAgICAgYnVmRmllbGQgPQogICAgICAgICAgICAgICAgICAgIEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxOaW9JbnB1dEJ1ZmZlci5idWYiKTsKICAgICAgICAgICAgICAgIHBvc0ZpZWxkID0KICAgICAgICAgICAgICAgICAgICBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsTmlvSW5wdXRCdWZmZXIucG9zIik7CiAgICAgICAgICAgICAgICBmaWxsTWV0aG9kID0KICAgICAgICAgICAgICAgICAgICBKYXZhTWV0aG9kLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbE5pb0lucHV0QnVmZmVyLmZpbGwoWlopWiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBwYXRjaChKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZpbmFsIE9iamVjdCBzZWxmID0gZnJhbWUubG9hZFRoaXNWYXJpYWJsZSgpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBzcGFjZSA9IGZyYW1lLmxvYWRCb29sZWFuVmFyaWFibGUoMik7CiAgICAgICAgICAgICAgICBpbnQgbGFzdFZhbGlkID0gZnJhbWUubG9hZEludE9wZXJhbmQoMCk7CiAgICAgICAgICAgICAgICBieXRlW10gYnVmID0gKGJ5dGVbXSkgYnVmRmllbGQucmVhZE9iamVjdChzZWxmKTsKICAgICAgICAgICAgICAgIGludCBwb3MgPSBwb3NGaWVsZC5yZWFkSW50KHNlbGYpOwoKICAgICAgICAgICAgICAgIHdoaWxlICghc3BhY2UpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zID49IGxhc3RWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZpbGwgPSAoQm9vbGVhbikgZmlsbE1ldGhvZC5jYWxsKHNlbGYsIHRydWUsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmaWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5yZXR1cm5Cb29sZWFuKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLlNQIHx8IGJ1Zltwb3NdID09IENvbnN0YW50cy5IVCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNUb2tlbihidWZbcG9zXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZnJhbWUpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNUb2tlbihpbnQgYykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gSVNfVE9LRU5bY107CiAgICAgICAgICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIGNoYXJhY3RlciBmb3VuZCBpbiBtZXRob2QgbmFtZS4gSFRUUCBtZXRob2QgbmFtZXMgbXVzdCBiZSB0b2tlbnMiKSk7CiAgICAgICAgICAgIH0KICAgICAgICBlbmRjb2RlCiAgICBlbmRwYXRjaAoKICAgIHBhdGNoKCJDVkUtMjAxNi02ODE2IDpUQzYgMDIiKToKICAgICAgICBmdW5jdGlvbigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsTmlvSW5wdXRCdWZmZXIucGFyc2VSZXF1ZXN0TGluZShaKVoiLAogICAgICAgICAgICBjaGVja3N1bXM6IFsiNWUwN2U0MzVmYyIsICI4OTU5MzU0ZjJiIl0pIC8vIDYuMC40NSwgNi4wLjQ3CiAgICAgICAgcmVhZHJldHVybigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsTmlvSW5wdXRCdWZmZXIubGFzdFZhbGlkIiwKICAgICAgICAgICAgb2NjdXJyZW5jZXM6IFs2XSkKCiAgICAgICAgY29kZShsYW5ndWFnZTogamF2YSwgaW1wb3J0OiBbImphdmEuaW8uRU9GRXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLmFwYWNoZS5jb3lvdGUuaHR0cDExLkNvbnN0YW50cyJdKToKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFSUkFZX1NJWkUgPSAxMjg7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19DT05UUk9MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19TRVBBUkFUT1IgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1RPS0VOID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IRVggPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX05PVF9SRVFVRVNUX1RBUkdFVCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSFRUUF9QUk9UT0NPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwoKICAgICAgICAgICAgc3RhdGljIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQVJSQVlfU0laRTsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQ29udHJvbD4gMC0zMSwgMTI3CiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCAzMiB8fCBpID09IDEyNykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19DT05UUk9MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICggICAgaSA9PSAnKCcgfHwgaSA9PSAnKScgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgIHx8IGkgPT0gJ0AnICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLCcgfHwgaSA9PSAnOycgfHwgaSA9PSAnOicgfHwgaSA9PSAnXFwnIHx8IGkgPT0gJ1wiJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLycgfHwgaSA9PSAnWycgfHwgaSA9PSAnXScgfHwgaSA9PSAnPycgIHx8IGkgPT0gJz0nICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAneycgfHwgaSA9PSAnfScgfHwgaSA9PSAnICcgfHwgaSA9PSAnXHQnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1NFUEFSQVRPUltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBUb2tlbjogQW55dGhpbmcgMC0xMjcgdGhhdCBpcyBub3QgYSBjb250cm9sIGFuZCBub3QgYSBzZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoIUlTX0NPTlRST0xbaV0gJiYgIUlTX1NFUEFSQVRPUltpXSAmJiBpIDwgMTI4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1RPS0VOW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIEhleDogMC05LCBhLWYsIEEtRgogICAgICAgICAgICAgICAgICAgIGlmICgoaSA+PSAnMCcgJiYgaSA8PSc5JykgfHwgKGkgPj0gJ2EnICYmIGkgPD0gJ2YnKSB8fCAoaSA+PSAnQScgJiYgaSA8PSAnRicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hFWFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIHJlcXVlc3QgdGFyZ2V0LgogICAgICAgICAgICAgICAgICAgIC8vIENvbWJpbmF0aW9uIG9mIG11bHRpcGxlIHJ1bGVzIGZyb20gUkZDNzIzMCBhbmQgUkZDIDM5ODYuIE11c3QgYmUKICAgICAgICAgICAgICAgICAgICAvLyBBU0NJSSwgbm8gY29udHJvbHMgcGx1cyBhIGZldyBhZGRpdGlvbmFsIGNoYXJhY3RlcnMgZXhjbHVkZWQKICAgICAgICAgICAgICAgICAgICBpZiAoSVNfQ09OVFJPTFtpXSB8fCBpID4gMTI3IHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcgJyB8fCBpID09ICdcIicgfHwgaSA9PSAnIycgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgfHwgaSA9PSAnXFwnIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICdeJyB8fCBpID09ICdgJyAgfHwgaSA9PSAneycgfHwgaSA9PSAnfCcgfHwgaSA9PSAnfScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfTk9UX1JFUVVFU1RfVEFSR0VUW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgSFRUUCBwcm90b2NvbAogICAgICAgICAgICAgICAgICAgIC8vICJIVFRQLyIgRElHSVQgIi4iIERJR0lUCiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gJ0gnIHx8IGkgPT0gJ1QnIHx8IGkgPT0gJ1AnIHx8IGkgPT0gJy8nIHx8IGkgPT0gJy4nIHx8IChpID49ICcwJyAmJiBpIDw9ICc5JykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSFRUUF9QUk9UT0NPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgYnVmRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBwb3NGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIHBhcnNpbmdSZXF1ZXN0TGluZVFQb3NGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YU1ldGhvZCBmaWxsTWV0aG9kOwoKICAgICAgICAgICAgcHVibGljIHZvaWQgbG9hZCgpIHsKICAgICAgICAgICAgICAgIGJ1ZkZpZWxkID0KICAgICAgICAgICAgICAgICAgICBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsTmlvSW5wdXRCdWZmZXIuYnVmIik7CiAgICAgICAgICAgICAgICBwb3NGaWVsZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbE5pb0lucHV0QnVmZmVyLnBvcyIpOwogICAgICAgICAgICAgICAgcGFyc2luZ1JlcXVlc3RMaW5lUVBvc0ZpZWxkID0KICAgICAgICAgICAgICAgICAgICBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsTmlvSW5wdXRCdWZmZXIucGFyc2luZ1JlcXVlc3RMaW5lUVBvcyIpOwogICAgICAgICAgICAgICAgZmlsbE1ldGhvZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YU1ldGhvZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxOaW9JbnB1dEJ1ZmZlci5maWxsKFpaKVoiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgcGF0Y2goSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3Qgc2VsZiA9IGZyYW1lLmxvYWRUaGlzVmFyaWFibGUoKTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gc3BhY2UgPSBmcmFtZS5sb2FkQm9vbGVhblZhcmlhYmxlKDMpOwogICAgICAgICAgICAgICAgaW50IGxhc3RWYWxpZCA9IGZyYW1lLmxvYWRJbnRPcGVyYW5kKDApOwogICAgICAgICAgICAgICAgYnl0ZVtdIGJ1ZiA9IChieXRlW10pIGJ1ZkZpZWxkLnJlYWRPYmplY3Qoc2VsZik7CiAgICAgICAgICAgICAgICBpbnQgcG9zID0gcG9zRmllbGQucmVhZEludChzZWxmKTsKICAgICAgICAgICAgICAgIGludCBwYXJzaW5nUmVxdWVzdExpbmVRUG9zID0gcGFyc2luZ1JlcXVlc3RMaW5lUVBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CgogICAgICAgICAgICAgICAgd2hpbGUgKCFzcGFjZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChwb3MgPj0gbGFzdFZhbGlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZmlsbCA9IChCb29sZWFuKSBmaWxsTWV0aG9kLmNhbGwoc2VsZiwgdHJ1ZSwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lLnJldHVybkJvb2xlYW4oZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChidWZbcG9zXSA9PSBDb25zdGFudHMuU1AgfHwgYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkhUKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChidWZbcG9zXSA9PSBDb25zdGFudHMuQ1IpIHx8IChidWZbcG9zXSA9PSBDb25zdGFudHMuTEYpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChidWZbcG9zXSA9PSBDb25zdGFudHMuUVVFU1RJT04pICYmIChwYXJzaW5nUmVxdWVzdExpbmVRUG9zID09IC0xKSkgewogICAgICAgICAgICAgICAgICAgICAgICBwYXJzaW5nUmVxdWVzdExpbmVRUG9zID0gcG9zOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNOb3RSZXF1ZXN0VGFyZ2V0KGJ1Zltwb3NdKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihmcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc05vdFJlcXVlc3RUYXJnZXQoaW50IGMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElTX05PVF9SRVFVRVNUX1RBUkdFVFtjXTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHZvaWQgdGhyb3dJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBjaGFyYWN0ZXIgZm91bmQgaW4gdGhlIHJlcXVlc3QgdGFyZ2V0LiBUaGUgdmFsaWQgY2hhcmFjdGVycyBhcmUgZGVmaW5lZCBpbiBSRkMgNzIzMCBhbmQgUkZDIDM5ODYiKSk7CiAgICAgICAgICAgIH0KICAgICAgICBlbmRjb2RlCiAgICBlbmRwYXRjaAoKICAgIHBhdGNoKCJDVkUtMjAxNi02ODE2IDpUQzYgMDMiKToKICAgICAgICBmdW5jdGlvbigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsTmlvSW5wdXRCdWZmZXIucGFyc2VSZXF1ZXN0TGluZShaKVoiLAogICAgICAgICAgICBjaGVja3N1bXM6IFsiNWUwN2U0MzVmYyIsICI4OTU5MzU0ZjJiIl0pIC8vIDYuMC40NSwgNi4wLjQ3CiAgICAgICAgcmVhZHJldHVybigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsTmlvSW5wdXRCdWZmZXIubGFzdFZhbGlkIiwKICAgICAgICAgICAgb2NjdXJyZW5jZXM6IFs4XSkKCiAgICAgICAgY29kZShsYW5ndWFnZTogamF2YSwgaW1wb3J0OiBbImphdmEuaW8uRU9GRXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLmFwYWNoZS5jb3lvdGUuaHR0cDExLkNvbnN0YW50cyJdKToKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFSUkFZX1NJWkUgPSAxMjg7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19DT05UUk9MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19TRVBBUkFUT1IgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1RPS0VOID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IRVggPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX05PVF9SRVFVRVNUX1RBUkdFVCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSFRUUF9QUk9UT0NPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwoKICAgICAgICAgICAgc3RhdGljIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQVJSQVlfU0laRTsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQ29udHJvbD4gMC0zMSwgMTI3CiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCAzMiB8fCBpID09IDEyNykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19DT05UUk9MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICggICAgaSA9PSAnKCcgfHwgaSA9PSAnKScgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgIHx8IGkgPT0gJ0AnICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLCcgfHwgaSA9PSAnOycgfHwgaSA9PSAnOicgfHwgaSA9PSAnXFwnIHx8IGkgPT0gJ1wiJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLycgfHwgaSA9PSAnWycgfHwgaSA9PSAnXScgfHwgaSA9PSAnPycgIHx8IGkgPT0gJz0nICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAneycgfHwgaSA9PSAnfScgfHwgaSA9PSAnICcgfHwgaSA9PSAnXHQnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1NFUEFSQVRPUltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBUb2tlbjogQW55dGhpbmcgMC0xMjcgdGhhdCBpcyBub3QgYSBjb250cm9sIGFuZCBub3QgYSBzZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoIUlTX0NPTlRST0xbaV0gJiYgIUlTX1NFUEFSQVRPUltpXSAmJiBpIDwgMTI4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1RPS0VOW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIEhleDogMC05LCBhLWYsIEEtRgogICAgICAgICAgICAgICAgICAgIGlmICgoaSA+PSAnMCcgJiYgaSA8PSc5JykgfHwgKGkgPj0gJ2EnICYmIGkgPD0gJ2YnKSB8fCAoaSA+PSAnQScgJiYgaSA8PSAnRicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hFWFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIHJlcXVlc3QgdGFyZ2V0LgogICAgICAgICAgICAgICAgICAgIC8vIENvbWJpbmF0aW9uIG9mIG11bHRpcGxlIHJ1bGVzIGZyb20gUkZDNzIzMCBhbmQgUkZDIDM5ODYuIE11c3QgYmUKICAgICAgICAgICAgICAgICAgICAvLyBBU0NJSSwgbm8gY29udHJvbHMgcGx1cyBhIGZldyBhZGRpdGlvbmFsIGNoYXJhY3RlcnMgZXhjbHVkZWQKICAgICAgICAgICAgICAgICAgICBpZiAoSVNfQ09OVFJPTFtpXSB8fCBpID4gMTI3IHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcgJyB8fCBpID09ICdcIicgfHwgaSA9PSAnIycgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgfHwgaSA9PSAnXFwnIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICdeJyB8fCBpID09ICdgJyAgfHwgaSA9PSAneycgfHwgaSA9PSAnfCcgfHwgaSA9PSAnfScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfTk9UX1JFUVVFU1RfVEFSR0VUW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgSFRUUCBwcm90b2NvbAogICAgICAgICAgICAgICAgICAgIC8vICJIVFRQLyIgRElHSVQgIi4iIERJR0lUCiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gJ0gnIHx8IGkgPT0gJ1QnIHx8IGkgPT0gJ1AnIHx8IGkgPT0gJy8nIHx8IGkgPT0gJy4nIHx8IChpID49ICcwJyAmJiBpIDw9ICc5JykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSFRUUF9QUk9UT0NPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgYnVmRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBwb3NGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIHBhcnNpbmdSZXF1ZXN0TGluZUVvbEZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhTWV0aG9kIGZpbGxNZXRob2Q7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBsb2FkKCkgewogICAgICAgICAgICAgICAgYnVmRmllbGQgPQogICAgICAgICAgICAgICAgICAgIEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxOaW9JbnB1dEJ1ZmZlci5idWYiKTsKICAgICAgICAgICAgICAgIHBvc0ZpZWxkID0KICAgICAgICAgICAgICAgICAgICBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsTmlvSW5wdXRCdWZmZXIucG9zIik7CiAgICAgICAgICAgICAgICBwYXJzaW5nUmVxdWVzdExpbmVFb2xGaWVsZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbE5pb0lucHV0QnVmZmVyLnBhcnNpbmdSZXF1ZXN0TGluZUVvbCIpOwogICAgICAgICAgICAgICAgZmlsbE1ldGhvZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YU1ldGhvZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxOaW9JbnB1dEJ1ZmZlci5maWxsKFpaKVoiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgcGF0Y2goSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3Qgc2VsZiA9IGZyYW1lLmxvYWRUaGlzVmFyaWFibGUoKTsKICAgICAgICAgICAgICAgIGludCBsYXN0VmFsaWQgPSBmcmFtZS5sb2FkSW50T3BlcmFuZCgwKTsKICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSAoYnl0ZVtdKSBidWZGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CiAgICAgICAgICAgICAgICBib29sZWFuIHBhcnNpbmdSZXF1ZXN0TGluZUVvbCA9IHBhcnNpbmdSZXF1ZXN0TGluZUVvbEZpZWxkLnJlYWRCb29sZWFuKHNlbGYpOwoKICAgICAgICAgICAgICAgIHdoaWxlICghcGFyc2luZ1JlcXVlc3RMaW5lRW9sKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBvcyA+PSBsYXN0VmFsaWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmaWxsID0gKEJvb2xlYW4pIGZpbGxNZXRob2QuY2FsbChzZWxmLCB0cnVlLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUucmV0dXJuQm9vbGVhbihmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1Zltwb3NdID09IENvbnN0YW50cy5DUikgewogICAgICAgICAgICAgICAgICAgICAgICA7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChidWZbcG9zXSA9PSBDb25zdGFudHMuTEYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlzSHR0cFByb3RvY29sKGJ1Zltwb3NdKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihmcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc0h0dHBQcm90b2NvbChpbnQgYykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gSVNfSFRUUF9QUk9UT0NPTFtjXTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIHRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgY2hhcmFjdGVyIGZvdW5kIGluIHRoZSBIVFRQIHByb3RvY29sIikpOwogICAgICAgICAgICB9CiAgICAgICAgZW5kY29kZQogICAgZW5kcGF0Y2gKCiAgICBwYXRjaCgiQ1ZFLTIwMTYtNjgxNiA6VEM2IDA0Iik6CiAgICAgICAgZnVuY3Rpb24oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbE5pb0lucHV0QnVmZmVyLnBhcnNlSGVhZGVyKClMb3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsTmlvSW5wdXRCdWZmZXIkSGVhZGVyUGFyc2VTdGF0dXM7IiwKICAgICAgICAgICAgY2hlY2tzdW1zOiBbIjVlMDdlNDM1ZmMiLCAiODk1OTM1NGYyYiJdKSAvLyA2LjAuNDUsIDYuMC40NwogICAgICAgIHJlYWRyZXR1cm4oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbE5pb0lucHV0QnVmZmVyLmxhc3RWYWxpZCIsCiAgICAgICAgICAgIG9jY3VycmVuY2VzOiBbMl0pCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsIGltcG9ydDogWyJqYXZhLmlvLkVPRkV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuY295b3RlLmh0dHAxMS5Db25zdGFudHMiXSk6CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBUlJBWV9TSVpFID0gMTI4OwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfQ09OVFJPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfU0VQQVJBVE9SID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19UT0tFTiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSEVYID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19OT1RfUkVRVUVTVF9UQVJHRVQgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hUVFBfUFJPVE9DT0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKCiAgICAgICAgICAgIHN0YXRpYyB7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEFSUkFZX1NJWkU7IGkrKykgewogICAgICAgICAgICAgICAgICAgIC8vIENvbnRyb2w+IDAtMzEsIDEyNwogICAgICAgICAgICAgICAgICAgIGlmIChpIDwgMzIgfHwgaSA9PSAxMjcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfQ09OVFJPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBTZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoICAgIGkgPT0gJygnIHx8IGkgPT0gJyknIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nICB8fCBpID09ICdAJyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJywnIHx8IGkgPT0gJzsnIHx8IGkgPT0gJzonIHx8IGkgPT0gJ1xcJyB8fCBpID09ICdcIicgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJy8nIHx8IGkgPT0gJ1snIHx8IGkgPT0gJ10nIHx8IGkgPT0gJz8nICB8fCBpID09ICc9JyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ3snIHx8IGkgPT0gJ30nIHx8IGkgPT0gJyAnIHx8IGkgPT0gJ1x0JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19TRVBBUkFUT1JbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gVG9rZW46IEFueXRoaW5nIDAtMTI3IHRoYXQgaXMgbm90IGEgY29udHJvbCBhbmQgbm90IGEgc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCFJU19DT05UUk9MW2ldICYmICFJU19TRVBBUkFUT1JbaV0gJiYgaSA8IDEyOCkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19UT0tFTltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBIZXg6IDAtOSwgYS1mLCBBLUYKICAgICAgICAgICAgICAgICAgICBpZiAoKGkgPj0gJzAnICYmIGkgPD0nOScpIHx8IChpID49ICdhJyAmJiBpIDw9ICdmJykgfHwgKGkgPj0gJ0EnICYmIGkgPD0gJ0YnKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IRVhbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciByZXF1ZXN0IHRhcmdldC4KICAgICAgICAgICAgICAgICAgICAvLyBDb21iaW5hdGlvbiBvZiBtdWx0aXBsZSBydWxlcyBmcm9tIFJGQzcyMzAgYW5kIFJGQyAzOTg2LiBNdXN0IGJlCiAgICAgICAgICAgICAgICAgICAgLy8gQVNDSUksIG5vIGNvbnRyb2xzIHBsdXMgYSBmZXcgYWRkaXRpb25hbCBjaGFyYWN0ZXJzIGV4Y2x1ZGVkCiAgICAgICAgICAgICAgICAgICAgaWYgKElTX0NPTlRST0xbaV0gfHwgaSA+IDEyNyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnICcgfHwgaSA9PSAnXCInIHx8IGkgPT0gJyMnIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nIHx8IGkgPT0gJ1xcJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnXicgfHwgaSA9PSAnYCcgIHx8IGkgPT0gJ3snIHx8IGkgPT0gJ3wnIHx8IGkgPT0gJ30nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX05PVF9SRVFVRVNUX1RBUkdFVFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIEhUVFAgcHJvdG9jb2wKICAgICAgICAgICAgICAgICAgICAvLyAiSFRUUC8iIERJR0lUICIuIiBESUdJVAogICAgICAgICAgICAgICAgICAgIGlmIChpID09ICdIJyB8fCBpID09ICdUJyB8fCBpID09ICdQJyB8fCBpID09ICcvJyB8fCBpID09ICcuJyB8fCAoaSA+PSAnMCcgJiYgaSA8PSAnOScpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hUVFBfUFJPVE9DT0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIGJ1ZkZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgcG9zRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBoZWFkZXJQYXJzZVBvc0ZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgSEVBREVSX05BTUVfRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBORUVEX01PUkVfREFUQV9GaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIGxhc3RTaWduaWZpY2FudENoYXJGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIGhlYWRlckRhdGFGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YU1ldGhvZCBza2lwTGluZU1ldGhvZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YU1ldGhvZCBmaWxsTWV0aG9kOwoKICAgICAgICAgICAgcHVibGljIHZvaWQgbG9hZCgpIHsKICAgICAgICAgICAgICAgIGJ1ZkZpZWxkID0KICAgICAgICAgICAgICAgICAgICBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsTmlvSW5wdXRCdWZmZXIuYnVmIik7CiAgICAgICAgICAgICAgICBwb3NGaWVsZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbE5pb0lucHV0QnVmZmVyLnBvcyIpOwogICAgICAgICAgICAgICAgaGVhZGVyUGFyc2VQb3NGaWVsZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbE5pb0lucHV0QnVmZmVyLmhlYWRlclBhcnNlUG9zIik7CiAgICAgICAgICAgICAgICBIRUFERVJfTkFNRV9GaWVsZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbE5pb0lucHV0QnVmZmVyJEhlYWRlclBhcnNlUG9zaXRpb24uSEVBREVSX05BTUUiKTsKICAgICAgICAgICAgICAgIE5FRURfTU9SRV9EQVRBX0ZpZWxkID0KICAgICAgICAgICAgICAgICAgICBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0TmlvSW5wdXRCdWZmZXIkSGVhZGVyUGFyc2VTdGF0dXMuTkVFRF9NT1JFX0RBVEEiKTsKICAgICAgICAgICAgICAgIGxhc3RTaWduaWZpY2FudENoYXJGaWVsZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbE5pb0lucHV0QnVmZmVyJEhlYWRlclBhcnNlRGF0YS5sYXN0U2lnbmlmaWNhbnRDaGFyIik7CiAgICAgICAgICAgICAgICBoZWFkZXJEYXRhRmllbGQgPQogICAgICAgICAgICAgICAgICAgIEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxOaW9JbnB1dEJ1ZmZlci5oZWFkZXJEYXRhIik7CiAgICAgICAgICAgICAgICBza2lwTGluZU1ldGhvZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YU1ldGhvZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxOaW9JbnB1dEJ1ZmZlci5za2lwTGluZSgpTG9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbE5pb0lucHV0QnVmZmVyJEhlYWRlclBhcnNlU3RhdHVzOyIpOwogICAgICAgICAgICAgICAgZmlsbE1ldGhvZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YU1ldGhvZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxOaW9JbnB1dEJ1ZmZlci5maWxsKFpaKVoiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgcGF0Y2goSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3Qgc2VsZiA9IGZyYW1lLmxvYWRUaGlzVmFyaWFibGUoKTsKICAgICAgICAgICAgICAgIGJ5dGUgY2hyID0gZnJhbWUubG9hZEJ5dGVWYXJpYWJsZSgxKTsKICAgICAgICAgICAgICAgIGludCBsYXN0VmFsaWQgPSBmcmFtZS5sb2FkSW50T3BlcmFuZCgwKTsKICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSAoYnl0ZVtdKSBidWZGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CiAgICAgICAgICAgICAgICBPYmplY3QgaGVhZGVyUGFyc2VQb3MgPSBoZWFkZXJQYXJzZVBvc0ZpZWxkLnJlYWRPYmplY3Qoc2VsZik7CiAgICAgICAgICAgICAgICBPYmplY3QgSEVBREVSX05BTUUgPSBIRUFERVJfTkFNRV9GaWVsZC5yZWFkT2JqZWN0KG51bGwpOwoKICAgICAgICAgICAgICAgIHdoaWxlIChoZWFkZXJQYXJzZVBvcyA9PSBIRUFERVJfTkFNRSkgewogICAgICAgICAgICAgICAgICAgIGlmIChwb3MgPj0gbGFzdFZhbGlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZmlsbCA9IChCb29sZWFuKSBmaWxsTWV0aG9kLmNhbGwoc2VsZiwgdHJ1ZSwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCBORUVEX01PUkVfREFUQSA9IE5FRURfTU9SRV9EQVRBX0ZpZWxkLnJlYWRPYmplY3QobnVsbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5yZXR1cm5PYmplY3QoTkVFRF9NT1JFX0RBVEEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNociA9IGJ1Zltwb3NdOwogICAgICAgICAgICAgICAgICAgIGlmIChjaHIgPT0gQ29uc3RhbnRzLkNPTE9OKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFpc1Rva2VuKGJ1Zltwb3NdKSkgewogICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgaGVhZGVyRGF0YSA9IGhlYWRlckRhdGFGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgICAgICAgICBsYXN0U2lnbmlmaWNhbnRDaGFyRmllbGQud3JpdGVJbnQoaGVhZGVyRGF0YSwgcG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUucmV0dXJuT2JqZWN0KHNraXBMaW5lTWV0aG9kLmNhbGwoc2VsZikpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgoY2hyID49IENvbnN0YW50cy5BKSAmJiAoY2hyIDw9IENvbnN0YW50cy5aKSkgewogICAgICAgICAgICAgICAgICAgICAgICBidWZbcG9zXSA9IChieXRlKSAoY2hyIC0gQ29uc3RhbnRzLkxDX09GRlNFVCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzVG9rZW4oaW50IGMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElTX1RPS0VOW2NdOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgIGVuZGNvZGUKICAgICBlbmRwYXRjaAoKICAgIHBhdGNoKCJDVkUtMjAxNi02ODE2IDpUQzYgMDUiKToKICAgICAgICBmdW5jdGlvbigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsQXBySW5wdXRCdWZmZXIucGFyc2VSZXF1ZXN0TGluZShaKVoiLAogICAgICAgICAgICBjaGVja3N1bXM6IFsiOGJjMzg2NTViMiIsICIyYTg3ZTZiNjQzIl0pIC8vIDYuMC40NSwgNi4wLjQ3CiAgICAgICAgcmVhZHJldHVybigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsQXBySW5wdXRCdWZmZXIubGFzdFZhbGlkIiwKICAgICAgICAgICAgb2NjdXJyZW5jZXM6IFszXSkKCiAgICAgICAgY29kZShsYW5ndWFnZTogamF2YSwgaW1wb3J0OiBbImphdmEuaW8uRU9GRXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLmFwYWNoZS5jb3lvdGUuaHR0cDExLkNvbnN0YW50cyJdKToKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFSUkFZX1NJWkUgPSAxMjg7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19DT05UUk9MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19TRVBBUkFUT1IgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1RPS0VOID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IRVggPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX05PVF9SRVFVRVNUX1RBUkdFVCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSFRUUF9QUk9UT0NPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwoKICAgICAgICAgICAgc3RhdGljIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQVJSQVlfU0laRTsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQ29udHJvbD4gMC0zMSwgMTI3CiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCAzMiB8fCBpID09IDEyNykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19DT05UUk9MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICggICAgaSA9PSAnKCcgfHwgaSA9PSAnKScgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgIHx8IGkgPT0gJ0AnICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLCcgfHwgaSA9PSAnOycgfHwgaSA9PSAnOicgfHwgaSA9PSAnXFwnIHx8IGkgPT0gJ1wiJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLycgfHwgaSA9PSAnWycgfHwgaSA9PSAnXScgfHwgaSA9PSAnPycgIHx8IGkgPT0gJz0nICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAneycgfHwgaSA9PSAnfScgfHwgaSA9PSAnICcgfHwgaSA9PSAnXHQnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1NFUEFSQVRPUltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBUb2tlbjogQW55dGhpbmcgMC0xMjcgdGhhdCBpcyBub3QgYSBjb250cm9sIGFuZCBub3QgYSBzZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoIUlTX0NPTlRST0xbaV0gJiYgIUlTX1NFUEFSQVRPUltpXSAmJiBpIDwgMTI4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1RPS0VOW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIEhleDogMC05LCBhLWYsIEEtRgogICAgICAgICAgICAgICAgICAgIGlmICgoaSA+PSAnMCcgJiYgaSA8PSc5JykgfHwgKGkgPj0gJ2EnICYmIGkgPD0gJ2YnKSB8fCAoaSA+PSAnQScgJiYgaSA8PSAnRicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hFWFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIHJlcXVlc3QgdGFyZ2V0LgogICAgICAgICAgICAgICAgICAgIC8vIENvbWJpbmF0aW9uIG9mIG11bHRpcGxlIHJ1bGVzIGZyb20gUkZDNzIzMCBhbmQgUkZDIDM5ODYuIE11c3QgYmUKICAgICAgICAgICAgICAgICAgICAvLyBBU0NJSSwgbm8gY29udHJvbHMgcGx1cyBhIGZldyBhZGRpdGlvbmFsIGNoYXJhY3RlcnMgZXhjbHVkZWQKICAgICAgICAgICAgICAgICAgICBpZiAoSVNfQ09OVFJPTFtpXSB8fCBpID4gMTI3IHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcgJyB8fCBpID09ICdcIicgfHwgaSA9PSAnIycgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgfHwgaSA9PSAnXFwnIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICdeJyB8fCBpID09ICdgJyAgfHwgaSA9PSAneycgfHwgaSA9PSAnfCcgfHwgaSA9PSAnfScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfTk9UX1JFUVVFU1RfVEFSR0VUW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgSFRUUCBwcm90b2NvbAogICAgICAgICAgICAgICAgICAgIC8vICJIVFRQLyIgRElHSVQgIi4iIERJR0lUCiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gJ0gnIHx8IGkgPT0gJ1QnIHx8IGkgPT0gJ1AnIHx8IGkgPT0gJy8nIHx8IGkgPT0gJy4nIHx8IChpID49ICcwJyAmJiBpIDw9ICc5JykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSFRUUF9QUk9UT0NPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgYnVmRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBwb3NGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YU1ldGhvZCBmaWxsTWV0aG9kOwoKICAgICAgICAgICAgcHVibGljIHZvaWQgbG9hZCgpIHsKICAgICAgICAgICAgICAgIGJ1ZkZpZWxkID0KICAgICAgICAgICAgICAgICAgICBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsQXBySW5wdXRCdWZmZXIuYnVmIik7CiAgICAgICAgICAgICAgICBwb3NGaWVsZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbEFwcklucHV0QnVmZmVyLnBvcyIpOwogICAgICAgICAgICAgICAgZmlsbE1ldGhvZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YU1ldGhvZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxBcHJJbnB1dEJ1ZmZlci5maWxsKClaIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHBhdGNoKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgT2JqZWN0IHNlbGYgPSBmcmFtZS5sb2FkVGhpc1ZhcmlhYmxlKCk7CiAgICAgICAgICAgICAgICBib29sZWFuIHNwYWNlID0gZnJhbWUubG9hZEJvb2xlYW5WYXJpYWJsZSg0KTsKICAgICAgICAgICAgICAgIGludCBsYXN0VmFsaWQgPSBmcmFtZS5sb2FkSW50T3BlcmFuZCgwKTsKICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSAoYnl0ZVtdKSBidWZGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CgogICAgICAgICAgICAgICAgd2hpbGUgKCFzcGFjZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChwb3MgPj0gbGFzdFZhbGlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZmlsbCA9IChCb29sZWFuKSBmaWxsTWV0aG9kLmNhbGwoc2VsZik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dFT0ZFeGNlcHRpb24oZnJhbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChidWZbcG9zXSA9PSBDb25zdGFudHMuU1AgfHwgYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkhUKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFpc1Rva2VuKGJ1Zltwb3NdKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihmcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc1Rva2VuKGludCBjKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBJU19UT0tFTltjXTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIHRocm93RU9GRXhjZXB0aW9uKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgbmV3IEVPRkV4Y2VwdGlvbigiVW5leHBlY3RlZCBFT0YgcmVhZCBvbiB0aGUgc29ja2V0IikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHZvaWQgdGhyb3dJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBjaGFyYWN0ZXIgZm91bmQgaW4gbWV0aG9kIG5hbWUuIEhUVFAgbWV0aG9kIG5hbWVzIG11c3QgYmUgdG9rZW5zIikpOwogICAgICAgICAgICB9CiAgICAgICAgZW5kY29kZQogICAgZW5kcGF0Y2gKCiAgICBwYXRjaCgiQ1ZFLTIwMTYtNjgxNiA6VEM2IDA2Iik6CiAgICAgICAgZnVuY3Rpb24oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbEFwcklucHV0QnVmZmVyLnBhcnNlUmVxdWVzdExpbmUoWilaIiwKICAgICAgICAgICAgY2hlY2tzdW1zOiBbIjhiYzM4NjU1YjIiLCAiMmE4N2U2YjY0MyJdKSAvLyA2LjAuNDUsIDYuMC40NwogICAgICAgIHJlYWRyZXR1cm4oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbEFwcklucHV0QnVmZmVyLmxhc3RWYWxpZCIsCiAgICAgICAgICAgIG9jY3VycmVuY2VzOiBbNV0pCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsIGltcG9ydDogWyJqYXZhLmlvLkVPRkV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuY295b3RlLmh0dHAxMS5Db25zdGFudHMiXSk6CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBUlJBWV9TSVpFID0gMTI4OwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfQ09OVFJPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfU0VQQVJBVE9SID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19UT0tFTiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSEVYID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19OT1RfUkVRVUVTVF9UQVJHRVQgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hUVFBfUFJPVE9DT0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKCiAgICAgICAgICAgIHN0YXRpYyB7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEFSUkFZX1NJWkU7IGkrKykgewogICAgICAgICAgICAgICAgICAgIC8vIENvbnRyb2w+IDAtMzEsIDEyNwogICAgICAgICAgICAgICAgICAgIGlmIChpIDwgMzIgfHwgaSA9PSAxMjcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfQ09OVFJPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBTZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoICAgIGkgPT0gJygnIHx8IGkgPT0gJyknIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nICB8fCBpID09ICdAJyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJywnIHx8IGkgPT0gJzsnIHx8IGkgPT0gJzonIHx8IGkgPT0gJ1xcJyB8fCBpID09ICdcIicgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJy8nIHx8IGkgPT0gJ1snIHx8IGkgPT0gJ10nIHx8IGkgPT0gJz8nICB8fCBpID09ICc9JyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ3snIHx8IGkgPT0gJ30nIHx8IGkgPT0gJyAnIHx8IGkgPT0gJ1x0JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19TRVBBUkFUT1JbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gVG9rZW46IEFueXRoaW5nIDAtMTI3IHRoYXQgaXMgbm90IGEgY29udHJvbCBhbmQgbm90IGEgc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCFJU19DT05UUk9MW2ldICYmICFJU19TRVBBUkFUT1JbaV0gJiYgaSA8IDEyOCkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19UT0tFTltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBIZXg6IDAtOSwgYS1mLCBBLUYKICAgICAgICAgICAgICAgICAgICBpZiAoKGkgPj0gJzAnICYmIGkgPD0nOScpIHx8IChpID49ICdhJyAmJiBpIDw9ICdmJykgfHwgKGkgPj0gJ0EnICYmIGkgPD0gJ0YnKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IRVhbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciByZXF1ZXN0IHRhcmdldC4KICAgICAgICAgICAgICAgICAgICAvLyBDb21iaW5hdGlvbiBvZiBtdWx0aXBsZSBydWxlcyBmcm9tIFJGQzcyMzAgYW5kIFJGQyAzOTg2LiBNdXN0IGJlCiAgICAgICAgICAgICAgICAgICAgLy8gQVNDSUksIG5vIGNvbnRyb2xzIHBsdXMgYSBmZXcgYWRkaXRpb25hbCBjaGFyYWN0ZXJzIGV4Y2x1ZGVkCiAgICAgICAgICAgICAgICAgICAgaWYgKElTX0NPTlRST0xbaV0gfHwgaSA+IDEyNyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnICcgfHwgaSA9PSAnXCInIHx8IGkgPT0gJyMnIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nIHx8IGkgPT0gJ1xcJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnXicgfHwgaSA9PSAnYCcgIHx8IGkgPT0gJ3snIHx8IGkgPT0gJ3wnIHx8IGkgPT0gJ30nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX05PVF9SRVFVRVNUX1RBUkdFVFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIEhUVFAgcHJvdG9jb2wKICAgICAgICAgICAgICAgICAgICAvLyAiSFRUUC8iIERJR0lUICIuIiBESUdJVAogICAgICAgICAgICAgICAgICAgIGlmIChpID09ICdIJyB8fCBpID09ICdUJyB8fCBpID09ICdQJyB8fCBpID09ICcvJyB8fCBpID09ICcuJyB8fCAoaSA+PSAnMCcgJiYgaSA8PSAnOScpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hUVFBfUFJPVE9DT0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIGJ1ZkZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgcG9zRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFNZXRob2QgZmlsbE1ldGhvZDsKCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIGxvYWQoKSB7CiAgICAgICAgICAgICAgICBidWZGaWVsZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbEFwcklucHV0QnVmZmVyLmJ1ZiIpOwogICAgICAgICAgICAgICAgcG9zRmllbGQgPQogICAgICAgICAgICAgICAgICAgIEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxBcHJJbnB1dEJ1ZmZlci5wb3MiKTsKICAgICAgICAgICAgICAgIGZpbGxNZXRob2QgPQogICAgICAgICAgICAgICAgICAgIEphdmFNZXRob2QubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsQXBySW5wdXRCdWZmZXIuZmlsbCgpWiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBwYXRjaChKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIE9iamVjdCBzZWxmID0gZnJhbWUubG9hZFRoaXNWYXJpYWJsZSgpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBzcGFjZSA9IGZyYW1lLmxvYWRCb29sZWFuVmFyaWFibGUoNCk7CiAgICAgICAgICAgICAgICBpbnQgcXVlc3Rpb25Qb3MgPSBmcmFtZS5sb2FkSW50VmFyaWFibGUoNik7CiAgICAgICAgICAgICAgICBpbnQgbGFzdFZhbGlkID0gZnJhbWUubG9hZEludE9wZXJhbmQoMCk7CiAgICAgICAgICAgICAgICBieXRlW10gYnVmID0gKGJ5dGVbXSkgYnVmRmllbGQucmVhZE9iamVjdChzZWxmKTsKICAgICAgICAgICAgICAgIGludCBwb3MgPSBwb3NGaWVsZC5yZWFkSW50KHNlbGYpOwoKICAgICAgICAgICAgICAgIHdoaWxlICghc3BhY2UpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zID49IGxhc3RWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZpbGwgPSAoQm9vbGVhbikgZmlsbE1ldGhvZC5jYWxsKHNlbGYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93RU9GRXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLlNQIHx8IGJ1Zltwb3NdID09IENvbnN0YW50cy5IVCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkNSKSB8fCAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkxGKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLlFVRVNUSU9OKSAmJiAocXVlc3Rpb25Qb3MgPT0gLTEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXN0aW9uUG9zID0gcG9zOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNOb3RSZXF1ZXN0VGFyZ2V0KGJ1Zltwb3NdKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihmcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc05vdFJlcXVlc3RUYXJnZXQoaW50IGMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElTX05PVF9SRVFVRVNUX1RBUkdFVFtjXTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHZvaWQgdGhyb3dFT0ZFeGNlcHRpb24oSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBuZXcgRU9GRXhjZXB0aW9uKCJVbmV4cGVjdGVkIEVPRiByZWFkIG9uIHRoZSBzb2NrZXQiKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIGNoYXJhY3RlciBmb3VuZCBpbiB0aGUgcmVxdWVzdCB0YXJnZXQuIFRoZSB2YWxpZCBjaGFyYWN0ZXJzIGFyZSBkZWZpbmVkIGluIFJGQyA3MjMwIGFuZCBSRkMgMzk4NiIpKTsKICAgICAgICAgICAgfQogICAgICAgIGVuZGNvZGUKICAgIGVuZHBhdGNoCgogICAgcGF0Y2goIkNWRS0yMDE2LTY4MTYgOlRDNiAwNyIpOgogICAgICAgIGZ1bmN0aW9uKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxBcHJJbnB1dEJ1ZmZlci5wYXJzZVJlcXVlc3RMaW5lKFopWiIsCiAgICAgICAgICAgIGNoZWNrc3VtczogWyI4YmMzODY1NWIyIiwgIjJhODdlNmI2NDMiXSkgLy8gNi4wLjQ1LCA2LjAuNDcKICAgICAgICByZWFkcmV0dXJuKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxBcHJJbnB1dEJ1ZmZlci5sYXN0VmFsaWQiLAogICAgICAgICAgICBvY2N1cnJlbmNlczogWzddKQoKICAgICAgICBjb2RlKGxhbmd1YWdlOiBqYXZhLCBpbXBvcnQ6IFsiamF2YS5pby5FT0ZFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcmcuYXBhY2hlLmNveW90ZS5odHRwMTEuQ29uc3RhbnRzIl0pOgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQVJSQVlfU0laRSA9IDEyODsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0NPTlRST0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1NFUEFSQVRPUiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfVE9LRU4gPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hFWCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfTk9UX1JFUVVFU1RfVEFSR0VUID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IVFRQX1BST1RPQ09MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CgogICAgICAgICAgICBzdGF0aWMgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBBUlJBWV9TSVpFOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAvLyBDb250cm9sPiAwLTMxLCAxMjcKICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IDMyIHx8IGkgPT0gMTI3KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0NPTlRST0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gU2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCAgICBpID09ICcoJyB8fCBpID09ICcpJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyAgfHwgaSA9PSAnQCcgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcsJyB8fCBpID09ICc7JyB8fCBpID09ICc6JyB8fCBpID09ICdcXCcgfHwgaSA9PSAnXCInIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcvJyB8fCBpID09ICdbJyB8fCBpID09ICddJyB8fCBpID09ICc/JyAgfHwgaSA9PSAnPScgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICd7JyB8fCBpID09ICd9JyB8fCBpID09ICcgJyB8fCBpID09ICdcdCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfU0VQQVJBVE9SW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFRva2VuOiBBbnl0aGluZyAwLTEyNyB0aGF0IGlzIG5vdCBhIGNvbnRyb2wgYW5kIG5vdCBhIHNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICghSVNfQ09OVFJPTFtpXSAmJiAhSVNfU0VQQVJBVE9SW2ldICYmIGkgPCAxMjgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfVE9LRU5baV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gSGV4OiAwLTksIGEtZiwgQS1GCiAgICAgICAgICAgICAgICAgICAgaWYgKChpID49ICcwJyAmJiBpIDw9JzknKSB8fCAoaSA+PSAnYScgJiYgaSA8PSAnZicpIHx8IChpID49ICdBJyAmJiBpIDw9ICdGJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSEVYW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgcmVxdWVzdCB0YXJnZXQuCiAgICAgICAgICAgICAgICAgICAgLy8gQ29tYmluYXRpb24gb2YgbXVsdGlwbGUgcnVsZXMgZnJvbSBSRkM3MjMwIGFuZCBSRkMgMzk4Ni4gTXVzdCBiZQogICAgICAgICAgICAgICAgICAgIC8vIEFTQ0lJLCBubyBjb250cm9scyBwbHVzIGEgZmV3IGFkZGl0aW9uYWwgY2hhcmFjdGVycyBleGNsdWRlZAogICAgICAgICAgICAgICAgICAgIGlmIChJU19DT05UUk9MW2ldIHx8IGkgPiAxMjcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJyAnIHx8IGkgPT0gJ1wiJyB8fCBpID09ICcjJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyB8fCBpID09ICdcXCcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ14nIHx8IGkgPT0gJ2AnICB8fCBpID09ICd7JyB8fCBpID09ICd8JyB8fCBpID09ICd9JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19OT1RfUkVRVUVTVF9UQVJHRVRbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciBIVFRQIHByb3RvY29sCiAgICAgICAgICAgICAgICAgICAgLy8gIkhUVFAvIiBESUdJVCAiLiIgRElHSVQKICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAnSCcgfHwgaSA9PSAnVCcgfHwgaSA9PSAnUCcgfHwgaSA9PSAnLycgfHwgaSA9PSAnLicgfHwgKGkgPj0gJzAnICYmIGkgPD0gJzknKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IVFRQX1BST1RPQ09MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBidWZGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIHBvc0ZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhTWV0aG9kIGZpbGxNZXRob2Q7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBsb2FkKCkgewogICAgICAgICAgICAgICAgYnVmRmllbGQgPQogICAgICAgICAgICAgICAgICAgIEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxBcHJJbnB1dEJ1ZmZlci5idWYiKTsKICAgICAgICAgICAgICAgIHBvc0ZpZWxkID0KICAgICAgICAgICAgICAgICAgICBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsQXBySW5wdXRCdWZmZXIucG9zIik7CiAgICAgICAgICAgICAgICBmaWxsTWV0aG9kID0KICAgICAgICAgICAgICAgICAgICBKYXZhTWV0aG9kLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbEFwcklucHV0QnVmZmVyLmZpbGwoKVoiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgcGF0Y2goSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBPYmplY3Qgc2VsZiA9IGZyYW1lLmxvYWRUaGlzVmFyaWFibGUoKTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gZW9sID0gZnJhbWUubG9hZEJvb2xlYW5WYXJpYWJsZSg3KTsKICAgICAgICAgICAgICAgIGludCBsYXN0VmFsaWQgPSBmcmFtZS5sb2FkSW50T3BlcmFuZCgwKTsKICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSAoYnl0ZVtdKSBidWZGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CgogICAgICAgICAgICAgICAgd2hpbGUgKCFlb2wpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zID49IGxhc3RWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZpbGwgPSAoQm9vbGVhbikgZmlsbE1ldGhvZC5jYWxsKHNlbGYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93RU9GRXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkNSKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ1Zltwb3NdID09IENvbnN0YW50cy5MRikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNIdHRwUHJvdG9jb2woYnVmW3Bvc10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzSHR0cFByb3RvY29sKGludCBjKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBJU19IVFRQX1BST1RPQ09MW2NdOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHZvaWQgdGhyb3dFT0ZFeGNlcHRpb24oSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBuZXcgRU9GRXhjZXB0aW9uKCJVbmV4cGVjdGVkIEVPRiByZWFkIG9uIHRoZSBzb2NrZXQiKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIGNoYXJhY3RlciBmb3VuZCBpbiB0aGUgSFRUUCBwcm90b2NvbCIpKTsKICAgICAgICAgICAgfQogICAgICAgIGVuZGNvZGUKICAgIGVuZHBhdGNoCgogICAgcGF0Y2goIkNWRS0yMDE2LTY4MTYgOlRDNiAwOCIpOgogICAgICAgIGZ1bmN0aW9uKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxBcHJJbnB1dEJ1ZmZlci5wYXJzZUhlYWRlcigpWiIsCiAgICAgICAgICAgIGNoZWNrc3VtczogWyI4YmMzODY1NWIyIiwgIjJhODdlNmI2NDMiXSkgLy8gNi4wLjQ1LCA2LjAuNDcKICAgICAgICByZWFkcmV0dXJuKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxBcHJJbnB1dEJ1ZmZlci5sYXN0VmFsaWQiLAogICAgICAgICAgICBvY2N1cnJlbmNlczogWzJdKQoKICAgICAgICBjb2RlKGxhbmd1YWdlOiBqYXZhLCBpbXBvcnQ6IFsiamF2YS5pby5FT0ZFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcmcuYXBhY2hlLmNveW90ZS5odHRwMTEuQ29uc3RhbnRzIl0pOgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQVJSQVlfU0laRSA9IDEyODsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0NPTlRST0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1NFUEFSQVRPUiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfVE9LRU4gPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hFWCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfTk9UX1JFUVVFU1RfVEFSR0VUID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IVFRQX1BST1RPQ09MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CgogICAgICAgICAgICBzdGF0aWMgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBBUlJBWV9TSVpFOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAvLyBDb250cm9sPiAwLTMxLCAxMjcKICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IDMyIHx8IGkgPT0gMTI3KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0NPTlRST0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gU2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCAgICBpID09ICcoJyB8fCBpID09ICcpJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyAgfHwgaSA9PSAnQCcgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcsJyB8fCBpID09ICc7JyB8fCBpID09ICc6JyB8fCBpID09ICdcXCcgfHwgaSA9PSAnXCInIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcvJyB8fCBpID09ICdbJyB8fCBpID09ICddJyB8fCBpID09ICc/JyAgfHwgaSA9PSAnPScgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICd7JyB8fCBpID09ICd9JyB8fCBpID09ICcgJyB8fCBpID09ICdcdCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfU0VQQVJBVE9SW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFRva2VuOiBBbnl0aGluZyAwLTEyNyB0aGF0IGlzIG5vdCBhIGNvbnRyb2wgYW5kIG5vdCBhIHNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICghSVNfQ09OVFJPTFtpXSAmJiAhSVNfU0VQQVJBVE9SW2ldICYmIGkgPCAxMjgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfVE9LRU5baV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gSGV4OiAwLTksIGEtZiwgQS1GCiAgICAgICAgICAgICAgICAgICAgaWYgKChpID49ICcwJyAmJiBpIDw9JzknKSB8fCAoaSA+PSAnYScgJiYgaSA8PSAnZicpIHx8IChpID49ICdBJyAmJiBpIDw9ICdGJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSEVYW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgcmVxdWVzdCB0YXJnZXQuCiAgICAgICAgICAgICAgICAgICAgLy8gQ29tYmluYXRpb24gb2YgbXVsdGlwbGUgcnVsZXMgZnJvbSBSRkM3MjMwIGFuZCBSRkMgMzk4Ni4gTXVzdCBiZQogICAgICAgICAgICAgICAgICAgIC8vIEFTQ0lJLCBubyBjb250cm9scyBwbHVzIGEgZmV3IGFkZGl0aW9uYWwgY2hhcmFjdGVycyBleGNsdWRlZAogICAgICAgICAgICAgICAgICAgIGlmIChJU19DT05UUk9MW2ldIHx8IGkgPiAxMjcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJyAnIHx8IGkgPT0gJ1wiJyB8fCBpID09ICcjJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyB8fCBpID09ICdcXCcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ14nIHx8IGkgPT0gJ2AnICB8fCBpID09ICd7JyB8fCBpID09ICd8JyB8fCBpID09ICd9JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19OT1RfUkVRVUVTVF9UQVJHRVRbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciBIVFRQIHByb3RvY29sCiAgICAgICAgICAgICAgICAgICAgLy8gIkhUVFAvIiBESUdJVCAiLiIgRElHSVQKICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAnSCcgfHwgaSA9PSAnVCcgfHwgaSA9PSAnUCcgfHwgaSA9PSAnLycgfHwgaSA9PSAnLicgfHwgKGkgPj0gJzAnICYmIGkgPD0gJzknKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IVFRQX1BST1RPQ09MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBidWZGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIHBvc0ZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhTWV0aG9kIGZpbGxNZXRob2Q7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFNZXRob2Qgc2tpcExpbmVNZXRob2Q7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBsb2FkKCkgewogICAgICAgICAgICAgICAgYnVmRmllbGQgPQogICAgICAgICAgICAgICAgICAgIEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxBcHJJbnB1dEJ1ZmZlci5idWYiKTsKICAgICAgICAgICAgICAgIHBvc0ZpZWxkID0KICAgICAgICAgICAgICAgICAgICBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsQXBySW5wdXRCdWZmZXIucG9zIik7CiAgICAgICAgICAgICAgICBmaWxsTWV0aG9kID0KICAgICAgICAgICAgICAgICAgICBKYXZhTWV0aG9kLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbEFwcklucHV0QnVmZmVyLmZpbGwoKVoiKTsKICAgICAgICAgICAgICAgIHNraXBMaW5lTWV0aG9kID0KICAgICAgICAgICAgICAgICAgICBKYXZhTWV0aG9kLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbEFwcklucHV0QnVmZmVyLnNraXBMaW5lKEkpViIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBwYXRjaChKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIE9iamVjdCBzZWxmID0gZnJhbWUubG9hZFRoaXNWYXJpYWJsZSgpOwogICAgICAgICAgICAgICAgYnl0ZSBjaHIgPSBmcmFtZS5sb2FkQnl0ZVZhcmlhYmxlKDEpOwogICAgICAgICAgICAgICAgaW50IHN0YXJ0ID0gZnJhbWUubG9hZEludFZhcmlhYmxlKDIpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBjb2xvbiA9IGZyYW1lLmxvYWRCb29sZWFuVmFyaWFibGUoMyk7CiAgICAgICAgICAgICAgICBpbnQgbGFzdFZhbGlkID0gZnJhbWUubG9hZEludE9wZXJhbmQoMCk7CiAgICAgICAgICAgICAgICBieXRlW10gYnVmID0gKGJ5dGVbXSkgYnVmRmllbGQucmVhZE9iamVjdChzZWxmKTsKICAgICAgICAgICAgICAgIGludCBwb3MgPSBwb3NGaWVsZC5yZWFkSW50KHNlbGYpOwoKICAgICAgICAgICAgICAgIHdoaWxlICghY29sb24pIHsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zID49IGxhc3RWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZpbGwgPSAoQm9vbGVhbikgZmlsbE1ldGhvZC5jYWxsKHNlbGYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93RU9GRXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkNPTE9OKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFpc1Rva2VuKGJ1Zltwb3NdKSkgewogICAgICAgICAgICAgICAgICAgICAgICBza2lwTGluZU1ldGhvZC5jYWxsKHNlbGYsIHN0YXJ0KTsKICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUucmV0dXJuQm9vbGVhbih0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjaHIgPSBidWZbcG9zXTsKICAgICAgICAgICAgICAgICAgICBpZiAoKGNociA+PSBDb25zdGFudHMuQSkgJiYgKGNociA8PSBDb25zdGFudHMuWikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmW3Bvc10gPSAoYnl0ZSkgKGNociAtIENvbnN0YW50cy5MQ19PRkZTRVQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzVG9rZW4oaW50IGMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElTX1RPS0VOW2NdOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHZvaWQgdGhyb3dFT0ZFeGNlcHRpb24oSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBuZXcgRU9GRXhjZXB0aW9uKCJVbmV4cGVjdGVkIEVPRiByZWFkIG9uIHRoZSBzb2NrZXQiKSk7CiAgICAgICAgICAgIH0KICAgICAgICBlbmRjb2RlCiAgICBlbmRwYXRjaAoKCgogICAgcGF0Y2goIkNWRS0yMDE2LTY4MTYgOlRDNiAwOSIpOgogICAgICAgIGZ1bmN0aW9uKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5wYXJzZVJlcXVlc3RMaW5lKClWIiwKICAgICAgICAgICAgY2hlY2tzdW1zOiBbIjI4ZTY5MDc1NjQiLCAiMjFlYjVhZjYyYiJdKSAvLyA2LjAuNDUsIDYuMC40NwogICAgICAgIHJlYWRyZXR1cm4oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLmxhc3RWYWxpZCIsCiAgICAgICAgICAgIG9jY3VycmVuY2VzOiBbMl0pCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsIGltcG9ydDogWyJqYXZhLmlvLkVPRkV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuY295b3RlLmh0dHAxMS5Db25zdGFudHMiXSk6CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBUlJBWV9TSVpFID0gMTI4OwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfQ09OVFJPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfU0VQQVJBVE9SID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19UT0tFTiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSEVYID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19OT1RfUkVRVUVTVF9UQVJHRVQgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hUVFBfUFJPVE9DT0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKCiAgICAgICAgICAgIHN0YXRpYyB7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEFSUkFZX1NJWkU7IGkrKykgewogICAgICAgICAgICAgICAgICAgIC8vIENvbnRyb2w+IDAtMzEsIDEyNwogICAgICAgICAgICAgICAgICAgIGlmIChpIDwgMzIgfHwgaSA9PSAxMjcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfQ09OVFJPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBTZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoICAgIGkgPT0gJygnIHx8IGkgPT0gJyknIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nICB8fCBpID09ICdAJyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJywnIHx8IGkgPT0gJzsnIHx8IGkgPT0gJzonIHx8IGkgPT0gJ1xcJyB8fCBpID09ICdcIicgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJy8nIHx8IGkgPT0gJ1snIHx8IGkgPT0gJ10nIHx8IGkgPT0gJz8nICB8fCBpID09ICc9JyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ3snIHx8IGkgPT0gJ30nIHx8IGkgPT0gJyAnIHx8IGkgPT0gJ1x0JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19TRVBBUkFUT1JbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gVG9rZW46IEFueXRoaW5nIDAtMTI3IHRoYXQgaXMgbm90IGEgY29udHJvbCBhbmQgbm90IGEgc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCFJU19DT05UUk9MW2ldICYmICFJU19TRVBBUkFUT1JbaV0gJiYgaSA8IDEyOCkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19UT0tFTltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBIZXg6IDAtOSwgYS1mLCBBLUYKICAgICAgICAgICAgICAgICAgICBpZiAoKGkgPj0gJzAnICYmIGkgPD0nOScpIHx8IChpID49ICdhJyAmJiBpIDw9ICdmJykgfHwgKGkgPj0gJ0EnICYmIGkgPD0gJ0YnKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IRVhbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciByZXF1ZXN0IHRhcmdldC4KICAgICAgICAgICAgICAgICAgICAvLyBDb21iaW5hdGlvbiBvZiBtdWx0aXBsZSBydWxlcyBmcm9tIFJGQzcyMzAgYW5kIFJGQyAzOTg2LiBNdXN0IGJlCiAgICAgICAgICAgICAgICAgICAgLy8gQVNDSUksIG5vIGNvbnRyb2xzIHBsdXMgYSBmZXcgYWRkaXRpb25hbCBjaGFyYWN0ZXJzIGV4Y2x1ZGVkCiAgICAgICAgICAgICAgICAgICAgaWYgKElTX0NPTlRST0xbaV0gfHwgaSA+IDEyNyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnICcgfHwgaSA9PSAnXCInIHx8IGkgPT0gJyMnIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nIHx8IGkgPT0gJ1xcJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnXicgfHwgaSA9PSAnYCcgIHx8IGkgPT0gJ3snIHx8IGkgPT0gJ3wnIHx8IGkgPT0gJ30nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX05PVF9SRVFVRVNUX1RBUkdFVFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIEhUVFAgcHJvdG9jb2wKICAgICAgICAgICAgICAgICAgICAvLyAiSFRUUC8iIERJR0lUICIuIiBESUdJVAogICAgICAgICAgICAgICAgICAgIGlmIChpID09ICdIJyB8fCBpID09ICdUJyB8fCBpID09ICdQJyB8fCBpID09ICcvJyB8fCBpID09ICcuJyB8fCAoaSA+PSAnMCcgJiYgaSA8PSAnOScpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hUVFBfUFJPVE9DT0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIGJ1ZkZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgcG9zRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFNZXRob2QgZmlsbE1ldGhvZDsKCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIGxvYWQoKSB7CiAgICAgICAgICAgICAgICBidWZGaWVsZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLmJ1ZiIpOwogICAgICAgICAgICAgICAgcG9zRmllbGQgPQogICAgICAgICAgICAgICAgICAgIEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5wb3MiKTsKICAgICAgICAgICAgICAgIGZpbGxNZXRob2QgPQogICAgICAgICAgICAgICAgICAgIEphdmFNZXRob2QubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsSW5wdXRCdWZmZXIuZmlsbCgpWiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBwYXRjaChKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIE9iamVjdCBzZWxmID0gZnJhbWUubG9hZFRoaXNWYXJpYWJsZSgpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBzcGFjZSA9IGZyYW1lLmxvYWRCb29sZWFuVmFyaWFibGUoMyk7CiAgICAgICAgICAgICAgICBpbnQgbGFzdFZhbGlkID0gZnJhbWUubG9hZEludE9wZXJhbmQoMCk7CiAgICAgICAgICAgICAgICBieXRlW10gYnVmID0gKGJ5dGVbXSkgYnVmRmllbGQucmVhZE9iamVjdChzZWxmKTsKICAgICAgICAgICAgICAgIGludCBwb3MgPSBwb3NGaWVsZC5yZWFkSW50KHNlbGYpOwoKICAgICAgICAgICAgICAgIHdoaWxlICghc3BhY2UpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zID49IGxhc3RWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZpbGwgPSAoQm9vbGVhbikgZmlsbE1ldGhvZC5jYWxsKHNlbGYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93RU9GRXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLlNQIHx8IGJ1Zltwb3NdID09IENvbnN0YW50cy5IVCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNUb2tlbihidWZbcG9zXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZnJhbWUpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNUb2tlbihpbnQgYykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gSVNfVE9LRU5bY107CiAgICAgICAgICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0VPRkV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIG5ldyBFT0ZFeGNlcHRpb24oIlVuZXhwZWN0ZWQgRU9GIHJlYWQgb24gdGhlIHNvY2tldCIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIHRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgY2hhcmFjdGVyIGZvdW5kIGluIG1ldGhvZCBuYW1lLiBIVFRQIG1ldGhvZCBuYW1lcyBtdXN0IGJlIHRva2VucyIpKTsKICAgICAgICAgICAgfQogICAgICAgIGVuZGNvZGUKICAgIGVuZHBhdGNoCgogICAgcGF0Y2goIkNWRS0yMDE2LTY4MTYgOlRDNiAxMCIpOgogICAgICAgIGZ1bmN0aW9uKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5wYXJzZVJlcXVlc3RMaW5lKClWIiwKICAgICAgICAgICAgY2hlY2tzdW1zOiBbIjI4ZTY5MDc1NjQiLCAiMjFlYjVhZjYyYiJdKSAvLyA2LjAuNDUsIDYuMC40NwogICAgICAgIHJlYWRyZXR1cm4oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLmxhc3RWYWxpZCIsCiAgICAgICAgICAgIG9jY3VycmVuY2VzOiBbNF0pCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsIGltcG9ydDogWyJqYXZhLmlvLkVPRkV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuY295b3RlLmh0dHAxMS5Db25zdGFudHMiXSk6CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBUlJBWV9TSVpFID0gMTI4OwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfQ09OVFJPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfU0VQQVJBVE9SID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19UT0tFTiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSEVYID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19OT1RfUkVRVUVTVF9UQVJHRVQgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hUVFBfUFJPVE9DT0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKCiAgICAgICAgICAgIHN0YXRpYyB7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEFSUkFZX1NJWkU7IGkrKykgewogICAgICAgICAgICAgICAgICAgIC8vIENvbnRyb2w+IDAtMzEsIDEyNwogICAgICAgICAgICAgICAgICAgIGlmIChpIDwgMzIgfHwgaSA9PSAxMjcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfQ09OVFJPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBTZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoICAgIGkgPT0gJygnIHx8IGkgPT0gJyknIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nICB8fCBpID09ICdAJyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJywnIHx8IGkgPT0gJzsnIHx8IGkgPT0gJzonIHx8IGkgPT0gJ1xcJyB8fCBpID09ICdcIicgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJy8nIHx8IGkgPT0gJ1snIHx8IGkgPT0gJ10nIHx8IGkgPT0gJz8nICB8fCBpID09ICc9JyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ3snIHx8IGkgPT0gJ30nIHx8IGkgPT0gJyAnIHx8IGkgPT0gJ1x0JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19TRVBBUkFUT1JbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gVG9rZW46IEFueXRoaW5nIDAtMTI3IHRoYXQgaXMgbm90IGEgY29udHJvbCBhbmQgbm90IGEgc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCFJU19DT05UUk9MW2ldICYmICFJU19TRVBBUkFUT1JbaV0gJiYgaSA8IDEyOCkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19UT0tFTltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBIZXg6IDAtOSwgYS1mLCBBLUYKICAgICAgICAgICAgICAgICAgICBpZiAoKGkgPj0gJzAnICYmIGkgPD0nOScpIHx8IChpID49ICdhJyAmJiBpIDw9ICdmJykgfHwgKGkgPj0gJ0EnICYmIGkgPD0gJ0YnKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IRVhbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciByZXF1ZXN0IHRhcmdldC4KICAgICAgICAgICAgICAgICAgICAvLyBDb21iaW5hdGlvbiBvZiBtdWx0aXBsZSBydWxlcyBmcm9tIFJGQzcyMzAgYW5kIFJGQyAzOTg2LiBNdXN0IGJlCiAgICAgICAgICAgICAgICAgICAgLy8gQVNDSUksIG5vIGNvbnRyb2xzIHBsdXMgYSBmZXcgYWRkaXRpb25hbCBjaGFyYWN0ZXJzIGV4Y2x1ZGVkCiAgICAgICAgICAgICAgICAgICAgaWYgKElTX0NPTlRST0xbaV0gfHwgaSA+IDEyNyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnICcgfHwgaSA9PSAnXCInIHx8IGkgPT0gJyMnIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nIHx8IGkgPT0gJ1xcJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnXicgfHwgaSA9PSAnYCcgIHx8IGkgPT0gJ3snIHx8IGkgPT0gJ3wnIHx8IGkgPT0gJ30nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX05PVF9SRVFVRVNUX1RBUkdFVFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIEhUVFAgcHJvdG9jb2wKICAgICAgICAgICAgICAgICAgICAvLyAiSFRUUC8iIERJR0lUICIuIiBESUdJVAogICAgICAgICAgICAgICAgICAgIGlmIChpID09ICdIJyB8fCBpID09ICdUJyB8fCBpID09ICdQJyB8fCBpID09ICcvJyB8fCBpID09ICcuJyB8fCAoaSA+PSAnMCcgJiYgaSA8PSAnOScpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hUVFBfUFJPVE9DT0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIGJ1ZkZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgcG9zRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFNZXRob2QgZmlsbE1ldGhvZDsKCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIGxvYWQoKSB7CiAgICAgICAgICAgICAgICBidWZGaWVsZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLmJ1ZiIpOwogICAgICAgICAgICAgICAgcG9zRmllbGQgPQogICAgICAgICAgICAgICAgICAgIEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5wb3MiKTsKICAgICAgICAgICAgICAgIGZpbGxNZXRob2QgPQogICAgICAgICAgICAgICAgICAgIEphdmFNZXRob2QubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsSW5wdXRCdWZmZXIuZmlsbCgpWiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBwYXRjaChKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIE9iamVjdCBzZWxmID0gZnJhbWUubG9hZFRoaXNWYXJpYWJsZSgpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBzcGFjZSA9IGZyYW1lLmxvYWRCb29sZWFuVmFyaWFibGUoMyk7CiAgICAgICAgICAgICAgICBpbnQgcXVlc3Rpb25Qb3MgPSBmcmFtZS5sb2FkSW50VmFyaWFibGUoNSk7CiAgICAgICAgICAgICAgICBpbnQgbGFzdFZhbGlkID0gZnJhbWUubG9hZEludE9wZXJhbmQoMCk7CiAgICAgICAgICAgICAgICBieXRlW10gYnVmID0gKGJ5dGVbXSkgYnVmRmllbGQucmVhZE9iamVjdChzZWxmKTsKICAgICAgICAgICAgICAgIGludCBwb3MgPSBwb3NGaWVsZC5yZWFkSW50KHNlbGYpOwoKICAgICAgICAgICAgICAgIHdoaWxlICghc3BhY2UpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zID49IGxhc3RWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZpbGwgPSAoQm9vbGVhbikgZmlsbE1ldGhvZC5jYWxsKHNlbGYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93RU9GRXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLlNQIHx8IGJ1Zltwb3NdID09IENvbnN0YW50cy5IVCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkNSKSB8fCAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkxGKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLlFVRVNUSU9OKSAmJiAocXVlc3Rpb25Qb3MgPT0gLTEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXN0aW9uUG9zID0gcG9zOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNOb3RSZXF1ZXN0VGFyZ2V0KGJ1Zltwb3NdKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihmcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc05vdFJlcXVlc3RUYXJnZXQoaW50IGMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElTX05PVF9SRVFVRVNUX1RBUkdFVFtjXTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHZvaWQgdGhyb3dFT0ZFeGNlcHRpb24oSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBuZXcgRU9GRXhjZXB0aW9uKCJVbmV4cGVjdGVkIEVPRiByZWFkIG9uIHRoZSBzb2NrZXQiKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIGNoYXJhY3RlciBmb3VuZCBpbiB0aGUgcmVxdWVzdCB0YXJnZXQuIFRoZSB2YWxpZCBjaGFyYWN0ZXJzIGFyZSBkZWZpbmVkIGluIFJGQyA3MjMwIGFuZCBSRkMgMzk4NiIpKTsKICAgICAgICAgICAgfQogICAgICAgIGVuZGNvZGUKICAgIGVuZHBhdGNoCgogICAgcGF0Y2goIkNWRS0yMDE2LTY4MTYgOlRDNiAxMSIpOgogICAgICAgIGZ1bmN0aW9uKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5wYXJzZVJlcXVlc3RMaW5lKClWIiwKICAgICAgICAgICAgY2hlY2tzdW1zOiBbIjI4ZTY5MDc1NjQiLCAiMjFlYjVhZjYyYiJdKSAvLyA2LjAuNDUsIDYuMC40NwogICAgICAgIHJlYWRyZXR1cm4oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLmxhc3RWYWxpZCIsCiAgICAgICAgICAgIG9jY3VycmVuY2VzOiBbNl0pCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsIGltcG9ydDogWyJqYXZhLmlvLkVPRkV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuY295b3RlLmh0dHAxMS5Db25zdGFudHMiXSk6CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBUlJBWV9TSVpFID0gMTI4OwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfQ09OVFJPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfU0VQQVJBVE9SID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19UT0tFTiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSEVYID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19OT1RfUkVRVUVTVF9UQVJHRVQgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hUVFBfUFJPVE9DT0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKCiAgICAgICAgICAgIHN0YXRpYyB7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEFSUkFZX1NJWkU7IGkrKykgewogICAgICAgICAgICAgICAgICAgIC8vIENvbnRyb2w+IDAtMzEsIDEyNwogICAgICAgICAgICAgICAgICAgIGlmIChpIDwgMzIgfHwgaSA9PSAxMjcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfQ09OVFJPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBTZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoICAgIGkgPT0gJygnIHx8IGkgPT0gJyknIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nICB8fCBpID09ICdAJyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJywnIHx8IGkgPT0gJzsnIHx8IGkgPT0gJzonIHx8IGkgPT0gJ1xcJyB8fCBpID09ICdcIicgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJy8nIHx8IGkgPT0gJ1snIHx8IGkgPT0gJ10nIHx8IGkgPT0gJz8nICB8fCBpID09ICc9JyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ3snIHx8IGkgPT0gJ30nIHx8IGkgPT0gJyAnIHx8IGkgPT0gJ1x0JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19TRVBBUkFUT1JbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gVG9rZW46IEFueXRoaW5nIDAtMTI3IHRoYXQgaXMgbm90IGEgY29udHJvbCBhbmQgbm90IGEgc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCFJU19DT05UUk9MW2ldICYmICFJU19TRVBBUkFUT1JbaV0gJiYgaSA8IDEyOCkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19UT0tFTltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBIZXg6IDAtOSwgYS1mLCBBLUYKICAgICAgICAgICAgICAgICAgICBpZiAoKGkgPj0gJzAnICYmIGkgPD0nOScpIHx8IChpID49ICdhJyAmJiBpIDw9ICdmJykgfHwgKGkgPj0gJ0EnICYmIGkgPD0gJ0YnKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IRVhbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciByZXF1ZXN0IHRhcmdldC4KICAgICAgICAgICAgICAgICAgICAvLyBDb21iaW5hdGlvbiBvZiBtdWx0aXBsZSBydWxlcyBmcm9tIFJGQzcyMzAgYW5kIFJGQyAzOTg2LiBNdXN0IGJlCiAgICAgICAgICAgICAgICAgICAgLy8gQVNDSUksIG5vIGNvbnRyb2xzIHBsdXMgYSBmZXcgYWRkaXRpb25hbCBjaGFyYWN0ZXJzIGV4Y2x1ZGVkCiAgICAgICAgICAgICAgICAgICAgaWYgKElTX0NPTlRST0xbaV0gfHwgaSA+IDEyNyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnICcgfHwgaSA9PSAnXCInIHx8IGkgPT0gJyMnIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nIHx8IGkgPT0gJ1xcJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnXicgfHwgaSA9PSAnYCcgIHx8IGkgPT0gJ3snIHx8IGkgPT0gJ3wnIHx8IGkgPT0gJ30nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX05PVF9SRVFVRVNUX1RBUkdFVFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIEhUVFAgcHJvdG9jb2wKICAgICAgICAgICAgICAgICAgICAvLyAiSFRUUC8iIERJR0lUICIuIiBESUdJVAogICAgICAgICAgICAgICAgICAgIGlmIChpID09ICdIJyB8fCBpID09ICdUJyB8fCBpID09ICdQJyB8fCBpID09ICcvJyB8fCBpID09ICcuJyB8fCAoaSA+PSAnMCcgJiYgaSA8PSAnOScpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hUVFBfUFJPVE9DT0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIGJ1ZkZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgcG9zRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFNZXRob2QgZmlsbE1ldGhvZDsKCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIGxvYWQoKSB7CiAgICAgICAgICAgICAgICBidWZGaWVsZCA9CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLmJ1ZiIpOwogICAgICAgICAgICAgICAgcG9zRmllbGQgPQogICAgICAgICAgICAgICAgICAgIEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5wb3MiKTsKICAgICAgICAgICAgICAgIGZpbGxNZXRob2QgPQogICAgICAgICAgICAgICAgICAgIEphdmFNZXRob2QubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsSW5wdXRCdWZmZXIuZmlsbCgpWiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBwYXRjaChKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIE9iamVjdCBzZWxmID0gZnJhbWUubG9hZFRoaXNWYXJpYWJsZSgpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBlb2wgPSBmcmFtZS5sb2FkQm9vbGVhblZhcmlhYmxlKDYpOwogICAgICAgICAgICAgICAgaW50IGxhc3RWYWxpZCA9IGZyYW1lLmxvYWRJbnRPcGVyYW5kKDApOwogICAgICAgICAgICAgICAgYnl0ZVtdIGJ1ZiA9IChieXRlW10pIGJ1ZkZpZWxkLnJlYWRPYmplY3Qoc2VsZik7CiAgICAgICAgICAgICAgICBpbnQgcG9zID0gcG9zRmllbGQucmVhZEludChzZWxmKTsKCiAgICAgICAgICAgICAgICB3aGlsZSAoIWVvbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChwb3MgPj0gbGFzdFZhbGlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZmlsbCA9IChCb29sZWFuKSBmaWxsTWV0aG9kLmNhbGwoc2VsZik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dFT0ZFeGNlcHRpb24oZnJhbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChidWZbcG9zXSA9PSBDb25zdGFudHMuQ1IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkxGKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFpc0h0dHBQcm90b2NvbChidWZbcG9zXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZnJhbWUpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNIdHRwUHJvdG9jb2woaW50IGMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElTX0hUVFBfUFJPVE9DT0xbY107CiAgICAgICAgICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0VPRkV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIG5ldyBFT0ZFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIEVPRiByZWFkIG9uIHRoZSBzb2NrZXQiKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIGNoYXJhY3RlciBmb3VuZCBpbiB0aGUgSFRUUCBwcm90b2NvbCIpKTsKICAgICAgICAgICAgfQogICAgICAgIGVuZGNvZGUKICAgIGVuZHBhdGNoCgogICAgcGF0Y2goIkNWRS0yMDE2LTY4MTYgOlRDNiAxMiIpOgogICAgICAgIGZ1bmN0aW9uKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5wYXJzZUhlYWRlcigpViIsCiAgICAgICAgICAgIGNoZWNrc3VtczogWyIyOGU2OTA3NTY0IiwgIjIxZWI1YWY2MmIiXSkgLy8gNi4wLjQ1LCA2LjAuNDcKICAgICAgICByZWFkcmV0dXJuKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5sYXN0VmFsaWQiLAogICAgICAgICAgICBvY2N1cnJlbmNlczogWzJdKQoKICAgICAgICBjb2RlKGxhbmd1YWdlOiBqYXZhLCBpbXBvcnQ6IFsiamF2YS5pby5FT0ZFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcmcuYXBhY2hlLmNveW90ZS5odHRwMTEuQ29uc3RhbnRzIl0pOgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQVJSQVlfU0laRSA9IDEyODsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0NPTlRST0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1NFUEFSQVRPUiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfVE9LRU4gPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hFWCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfTk9UX1JFUVVFU1RfVEFSR0VUID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IVFRQX1BST1RPQ09MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CgogICAgICAgICAgICBzdGF0aWMgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBBUlJBWV9TSVpFOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAvLyBDb250cm9sPiAwLTMxLCAxMjcKICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IDMyIHx8IGkgPT0gMTI3KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0NPTlRST0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gU2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCAgICBpID09ICcoJyB8fCBpID09ICcpJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyAgfHwgaSA9PSAnQCcgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcsJyB8fCBpID09ICc7JyB8fCBpID09ICc6JyB8fCBpID09ICdcXCcgfHwgaSA9PSAnXCInIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcvJyB8fCBpID09ICdbJyB8fCBpID09ICddJyB8fCBpID09ICc/JyAgfHwgaSA9PSAnPScgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICd7JyB8fCBpID09ICd9JyB8fCBpID09ICcgJyB8fCBpID09ICdcdCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfU0VQQVJBVE9SW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFRva2VuOiBBbnl0aGluZyAwLTEyNyB0aGF0IGlzIG5vdCBhIGNvbnRyb2wgYW5kIG5vdCBhIHNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICghSVNfQ09OVFJPTFtpXSAmJiAhSVNfU0VQQVJBVE9SW2ldICYmIGkgPCAxMjgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfVE9LRU5baV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gSGV4OiAwLTksIGEtZiwgQS1GCiAgICAgICAgICAgICAgICAgICAgaWYgKChpID49ICcwJyAmJiBpIDw9JzknKSB8fCAoaSA+PSAnYScgJiYgaSA8PSAnZicpIHx8IChpID49ICdBJyAmJiBpIDw9ICdGJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSEVYW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgcmVxdWVzdCB0YXJnZXQuCiAgICAgICAgICAgICAgICAgICAgLy8gQ29tYmluYXRpb24gb2YgbXVsdGlwbGUgcnVsZXMgZnJvbSBSRkM3MjMwIGFuZCBSRkMgMzk4Ni4gTXVzdCBiZQogICAgICAgICAgICAgICAgICAgIC8vIEFTQ0lJLCBubyBjb250cm9scyBwbHVzIGEgZmV3IGFkZGl0aW9uYWwgY2hhcmFjdGVycyBleGNsdWRlZAogICAgICAgICAgICAgICAgICAgIGlmIChJU19DT05UUk9MW2ldIHx8IGkgPiAxMjcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJyAnIHx8IGkgPT0gJ1wiJyB8fCBpID09ICcjJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyB8fCBpID09ICdcXCcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ14nIHx8IGkgPT0gJ2AnICB8fCBpID09ICd7JyB8fCBpID09ICd8JyB8fCBpID09ICd9JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19OT1RfUkVRVUVTVF9UQVJHRVRbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciBIVFRQIHByb3RvY29sCiAgICAgICAgICAgICAgICAgICAgLy8gIkhUVFAvIiBESUdJVCAiLiIgRElHSVQKICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAnSCcgfHwgaSA9PSAnVCcgfHwgaSA9PSAnUCcgfHwgaSA9PSAnLycgfHwgaSA9PSAnLicgfHwgKGkgPj0gJzAnICYmIGkgPD0gJzknKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IVFRQX1BST1RPQ09MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBidWZGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIHBvc0ZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhTWV0aG9kIGZpbGxNZXRob2Q7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFNZXRob2Qgc2tpcExpbmVNZXRob2Q7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBsb2FkKCkgewogICAgICAgICAgICAgICAgYnVmRmllbGQgPQogICAgICAgICAgICAgICAgICAgIEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5idWYiKTsKICAgICAgICAgICAgICAgIHBvc0ZpZWxkID0KICAgICAgICAgICAgICAgICAgICBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsSW5wdXRCdWZmZXIucG9zIik7CiAgICAgICAgICAgICAgICBmaWxsTWV0aG9kID0KICAgICAgICAgICAgICAgICAgICBKYXZhTWV0aG9kLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLmZpbGwoKVoiKTsKICAgICAgICAgICAgICAgIHNraXBMaW5lTWV0aG9kID0KICAgICAgICAgICAgICAgICAgICBKYXZhTWV0aG9kLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLnNraXBMaW5lKEkpViIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBwYXRjaChKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIE9iamVjdCBzZWxmID0gZnJhbWUubG9hZFRoaXNWYXJpYWJsZSgpOwogICAgICAgICAgICAgICAgYnl0ZSBjaHIgPSBmcmFtZS5sb2FkQnl0ZVZhcmlhYmxlKDEpOwogICAgICAgICAgICAgICAgaW50IHN0YXJ0ID0gZnJhbWUubG9hZEludFZhcmlhYmxlKDIpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBjb2xvbiA9IGZyYW1lLmxvYWRCb29sZWFuVmFyaWFibGUoMyk7CiAgICAgICAgICAgICAgICBpbnQgbGFzdFZhbGlkID0gZnJhbWUubG9hZEludE9wZXJhbmQoMCk7CiAgICAgICAgICAgICAgICBieXRlW10gYnVmID0gKGJ5dGVbXSkgYnVmRmllbGQucmVhZE9iamVjdChzZWxmKTsKICAgICAgICAgICAgICAgIGludCBwb3MgPSBwb3NGaWVsZC5yZWFkSW50KHNlbGYpOwoKICAgICAgICAgICAgICAgIHdoaWxlICghY29sb24pIHsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zID49IGxhc3RWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZpbGwgPSAoQm9vbGVhbikgZmlsbE1ldGhvZC5jYWxsKHNlbGYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93RU9GRXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkNPTE9OKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFpc1Rva2VuKGJ1Zltwb3NdKSkgewoKICAgICAgICAgICAgICAgICAgICAgICAgc2tpcExpbmUuY2FsbChzZWxmLCBzdGFydCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lLnJldHVybkJvb2xlYW4odHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2hyID0gYnVmW3Bvc107CiAgICAgICAgICAgICAgICAgICAgaWYgKChjaHIgPj0gQ29uc3RhbnRzLkEpICYmIChjaHIgPD0gQ29uc3RhbnRzLlopKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zltwb3NdID0gKGJ5dGUpIChjaHIgLSBDb25zdGFudHMuTENfT0ZGU0VUKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc1Rva2VuKGludCBjKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBJU19UT0tFTltjXTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIHRocm93RU9GRXhjZXB0aW9uKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgbmV3IEVPRkV4Y2VwdGlvbigiVW5leHBlY3RlZCBFT0YgcmVhZCBvbiB0aGUgc29ja2V0IikpOwogICAgICAgICAgICB9CiAgICAgICAgZW5kY29kZQogICAgZW5kcGF0Y2gKCiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgQ1ZFLTIwMTYtNjgxNjogVG9tY2F0IDguMC4zOAogICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIHBhdGNoKCJDVkUtMjAxNi02ODE2IDpUQzggMDEiKToKICAgICAgICBmdW5jdGlvbigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIuPGluaXQ+KClWIiwKICAgICAgICAgICAgY2hlY2tzdW1zOiBbImRhN2RlYjY0YjciXSkgICAvLyA4LjAuMzgKICAgICAgICBlbnRyeSgpCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsIGltcG9ydDogWyJqYXZhLnV0aWwuQ29sbGVjdGlvbnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuSGFzaE1hcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5NYXAiXSk6CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBCVUZGRVJfTUFQID0gImJ1ZmZlck1hcCI7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBTklCX1BSTF8zID0gImFuaWJfcHJsXzMiOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQU5JQl9QUkxfNSA9ICJhbmliX3BybF81IjsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFOSUJfUFJMXzcgPSAiYW5pYl9wcmxfNyI7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBTklCX1BIXzIgPSAiYW5pYl9waF8yIjsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBJQUlCX1BSTF8zID0gImlhaWJfcHJsXzMiOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUFJQl9QUkxfNSA9ICJpYWliX3BybF81IjsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIElBSUJfUFJMXzcgPSAiaWFpYl9wcmxfNyI7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBJQUlCX1BIXzIgPSAiaWFpYl9waF8yIjsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBJSUJfUFJMXzIgPSAiaWliX3BybF8yIjsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIElJQl9QUkxfNCA9ICJpaWJfcHJsXzQiOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUlCX1BSTF82ID0gImlpYl9wcmxfNiI7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBJSUJfUEhfMiA9ICJpaWJfcGhfMiI7CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBCb29sZWFuPiBidWZmZXJNYXAgPQogICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMuc3luY2hyb25pemVkTWFwKG5ldyBIYXNoTWFwPFN0cmluZywgQm9vbGVhbj4oKSk7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBwYXRjaChKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBpbml0aWFsIHZhbHVlIGlzICdmYWxzZScsIHdoaWNoIG1lYW5zIHRoZSBwYXRjaAogICAgICAgICAgICAgICAgLy8gaGFzIG5vdCBydW4uIEVhY2ggcGF0Y2ggd2lsbCBzZXQgaXQncyByZXNwZWN0aXZlIHZhbHVlCiAgICAgICAgICAgICAgICAvLyB0byAndHJ1ZScgb25jZSB0aGUgcGF0Y2ggaGFzIHJ1bi4KICAgICAgICAgICAgICAgIGJ1ZmZlck1hcC5wdXQoQU5JQl9QUkxfMywgZmFsc2UpOwogICAgICAgICAgICAgICAgYnVmZmVyTWFwLnB1dChBTklCX1BSTF81LCBmYWxzZSk7CiAgICAgICAgICAgICAgICBidWZmZXJNYXAucHV0KEFOSUJfUFJMXzcsIGZhbHNlKTsKICAgICAgICAgICAgICAgIGJ1ZmZlck1hcC5wdXQoQU5JQl9QSF8yLCBmYWxzZSk7CgogICAgICAgICAgICAgICAgYnVmZmVyTWFwLnB1dChJQUlCX1BSTF8zLCBmYWxzZSk7CiAgICAgICAgICAgICAgICBidWZmZXJNYXAucHV0KElBSUJfUFJMXzUsIGZhbHNlKTsKICAgICAgICAgICAgICAgIGJ1ZmZlck1hcC5wdXQoSUFJQl9QUkxfNywgZmFsc2UpOwogICAgICAgICAgICAgICAgYnVmZmVyTWFwLnB1dChJQUlCX1BIXzIsIGZhbHNlKTsKCiAgICAgICAgICAgICAgICBidWZmZXJNYXAucHV0KElJQl9QUkxfMiwgZmFsc2UpOwogICAgICAgICAgICAgICAgYnVmZmVyTWFwLnB1dChJSUJfUFJMXzQsIGZhbHNlKTsKICAgICAgICAgICAgICAgIGJ1ZmZlck1hcC5wdXQoSUlCX1BSTF82LCBmYWxzZSk7CiAgICAgICAgICAgICAgICBidWZmZXJNYXAucHV0KElJQl9QSF8yLCBmYWxzZSk7CgogICAgICAgICAgICAgICAgc2F2ZVZhbHVlKEJVRkZFUl9NQVAsIGJ1ZmZlck1hcCk7CiAgICAgICAgICAgIH0KICAgICAgICBlbmRjb2RlCiAgICBlbmRwYXRjaAoKICAgIHBhdGNoKCJDVkUtMjAxNi02ODE2IDpUQzggMDIiKToKICAgICAgICBmdW5jdGlvbigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0TmlvSW5wdXRCdWZmZXIucGFyc2VSZXF1ZXN0TGluZShaKVoiLAogICAgICAgICAgICBjaGVja3N1bXM6IFsiYjBlYTE5Y2M3NCJdKSAgIC8vIDguMC4zOAogICAgICAgIHJlYWRyZXR1cm4oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdE5pb0lucHV0QnVmZmVyLmxhc3RWYWxpZCIsCiAgICAgICAgICAgIG9jY3VycmVuY2VzOiBbM10pCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsIGltcG9ydDogWyJqYXZhLnV0aWwuTWFwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLmFwYWNoZS5jb3lvdGUuaHR0cDExLkNvbnN0YW50cyJdKToKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFSUkFZX1NJWkUgPSAxMjg7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19DT05UUk9MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19TRVBBUkFUT1IgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1RPS0VOID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IRVggPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX05PVF9SRVFVRVNUX1RBUkdFVCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSFRUUF9QUk9UT0NPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwoKICAgICAgICAgICAgc3RhdGljIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQVJSQVlfU0laRTsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQ29udHJvbD4gMC0zMSwgMTI3CiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCAzMiB8fCBpID09IDEyNykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19DT05UUk9MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICggICAgaSA9PSAnKCcgfHwgaSA9PSAnKScgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgIHx8IGkgPT0gJ0AnICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLCcgfHwgaSA9PSAnOycgfHwgaSA9PSAnOicgfHwgaSA9PSAnXFwnIHx8IGkgPT0gJ1wiJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLycgfHwgaSA9PSAnWycgfHwgaSA9PSAnXScgfHwgaSA9PSAnPycgIHx8IGkgPT0gJz0nICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAneycgfHwgaSA9PSAnfScgfHwgaSA9PSAnICcgfHwgaSA9PSAnXHQnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1NFUEFSQVRPUltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBUb2tlbjogQW55dGhpbmcgMC0xMjcgdGhhdCBpcyBub3QgYSBjb250cm9sIGFuZCBub3QgYSBzZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoIUlTX0NPTlRST0xbaV0gJiYgIUlTX1NFUEFSQVRPUltpXSAmJiBpIDwgMTI4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1RPS0VOW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIEhleDogMC05LCBhLWYsIEEtRgogICAgICAgICAgICAgICAgICAgIGlmICgoaSA+PSAnMCcgJiYgaSA8PSc5JykgfHwgKGkgPj0gJ2EnICYmIGkgPD0gJ2YnKSB8fCAoaSA+PSAnQScgJiYgaSA8PSAnRicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hFWFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIHJlcXVlc3QgdGFyZ2V0LgogICAgICAgICAgICAgICAgICAgIC8vIENvbWJpbmF0aW9uIG9mIG11bHRpcGxlIHJ1bGVzIGZyb20gUkZDNzIzMCBhbmQgUkZDIDM5ODYuIE11c3QgYmUKICAgICAgICAgICAgICAgICAgICAvLyBBU0NJSSwgbm8gY29udHJvbHMgcGx1cyBhIGZldyBhZGRpdGlvbmFsIGNoYXJhY3RlcnMgZXhjbHVkZWQKICAgICAgICAgICAgICAgICAgICBpZiAoSVNfQ09OVFJPTFtpXSB8fCBpID4gMTI3IHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcgJyB8fCBpID09ICdcIicgfHwgaSA9PSAnIycgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgfHwgaSA9PSAnXFwnIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICdeJyB8fCBpID09ICdgJyAgfHwgaSA9PSAneycgfHwgaSA9PSAnfCcgfHwgaSA9PSAnfScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfTk9UX1JFUVVFU1RfVEFSR0VUW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgSFRUUCBwcm90b2NvbAogICAgICAgICAgICAgICAgICAgIC8vICJIVFRQLyIgRElHSVQgIi4iIERJR0lUCiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gJ0gnIHx8IGkgPT0gJ1QnIHx8IGkgPT0gJ1AnIHx8IGkgPT0gJy8nIHx8IGkgPT0gJy4nIHx8IChpID49ICcwJyAmJiBpIDw9ICc5JykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSFRUUF9QUk9UT0NPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQlVGRkVSX01BUCA9ICJidWZmZXJNYXAiOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQU5JQl9QUkxfMyA9ICJhbmliX3BybF8zIjsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBsYXN0VmFsaWRGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIGJ1ZkZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgcG9zRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFNZXRob2QgZmlsbE1ldGhvZDsKCiAgICAgICAgICAgIHByaXZhdGUgT2JqZWN0IHNlbGY7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBsb2FkKCkgewogICAgICAgICAgICAgICAgbGFzdFZhbGlkRmllbGQgPSBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIubGFzdFZhbGlkIik7CiAgICAgICAgICAgICAgICBidWZGaWVsZCA9IEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3RJbnB1dEJ1ZmZlci5idWYiKTsKICAgICAgICAgICAgICAgIHBvc0ZpZWxkID0gSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdElucHV0QnVmZmVyLnBvcyIpOwogICAgICAgICAgICAgICAgZmlsbE1ldGhvZCA9IEphdmFNZXRob2QubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIuZmlsbChaKVoiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgcGF0Y2goSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBCb29sZWFuPiBidWZmZXJNYXAgPSAoTWFwPFN0cmluZywgQm9vbGVhbj4pIHJlc3RvcmVWYWx1ZShCVUZGRVJfTUFQKTsKICAgICAgICAgICAgICAgIGlmIChidWZmZXJNYXAuZ2V0KEFOSUJfUFJMXzMpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnVmZmVyTWFwLnB1dChBTklCX1BSTF8zLCB0cnVlKTsKICAgICAgICAgICAgICAgIHNlbGYgPSBmcmFtZS5sb2FkVGhpc1ZhcmlhYmxlKCk7CiAgICAgICAgICAgICAgICBib29sZWFuIHNwYWNlID0gZnJhbWUubG9hZEJvb2xlYW5WYXJpYWJsZSgyKTsKICAgICAgICAgICAgICAgIGludCBvcmlnaW5hbFBvcyA9IHBvcygpOwoKICAgICAgICAgICAgICAgIHdoaWxlICghc3BhY2UpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zKCkgPj0gbGFzdFZhbGlkKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmaWxsID0gKGJvb2xlYW4pIGZpbGxNZXRob2QuY2FsbChzZWxmLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUucmV0dXJuQm9vbGVhbihmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1ZigpW3BvcygpXSA9PSBDb25zdGFudHMuU1AgfHwgYnVmKClbcG9zKCldID09IENvbnN0YW50cy5IVCkgewogICAgICAgICAgICAgICAgICAgICAgICBwb3Mob3JpZ2luYWxQb3MpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNUb2tlbihidWYoKVtwb3MoKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlck1hcC5wdXQoQU5JQl9QUkxfMywgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihmcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcG9zKHBvcygpICsgMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgaW50IGxhc3RWYWxpZCgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBsYXN0VmFsaWRGaWVsZC5yZWFkSW50KHNlbGYpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIGJ5dGVbXSBidWYoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKGJ5dGVbXSkgYnVmRmllbGQucmVhZE9iamVjdChzZWxmKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBpbnQgcG9zKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCBwb3MoaW50IGkpIHsKICAgICAgICAgICAgICAgIHBvc0ZpZWxkLndyaXRlSW50KHNlbGYsIGkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNUb2tlbihpbnQgYykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gSVNfVE9LRU5bY107CiAgICAgICAgICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIGNoYXJhY3RlciBmb3VuZCBpbiBtZXRob2QgbmFtZS4gSFRUUCBtZXRob2QgbmFtZXMgbXVzdCBiZSB0b2tlbnMiKSk7CiAgICAgICAgICAgIH0KICAgICAgICBlbmRjb2RlCiAgICBlbmRwYXRjaAoKICAgIHBhdGNoKCJDVkUtMjAxNi02ODE2IDpUQzggMDMiKToKICAgICAgICBmdW5jdGlvbigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0TmlvSW5wdXRCdWZmZXIucGFyc2VSZXF1ZXN0TGluZShaKVoiLAogICAgICAgICAgICBjaGVja3N1bXM6IFsiYjBlYTE5Y2M3NCJdKSAgIC8vIDguMC4zOAogICAgICAgIHJlYWRyZXR1cm4oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdE5pb0lucHV0QnVmZmVyLmxhc3RWYWxpZCIsCiAgICAgICAgICAgIG9jY3VycmVuY2VzOiBbNV0pCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsIGltcG9ydDogWyJqYXZhLnV0aWwuTWFwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLmFwYWNoZS5jb3lvdGUuaHR0cDExLkNvbnN0YW50cyJdKToKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFSUkFZX1NJWkUgPSAxMjg7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19DT05UUk9MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19TRVBBUkFUT1IgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1RPS0VOID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IRVggPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX05PVF9SRVFVRVNUX1RBUkdFVCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSFRUUF9QUk9UT0NPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwoKICAgICAgICAgICAgc3RhdGljIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQVJSQVlfU0laRTsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQ29udHJvbD4gMC0zMSwgMTI3CiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCAzMiB8fCBpID09IDEyNykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19DT05UUk9MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICggICAgaSA9PSAnKCcgfHwgaSA9PSAnKScgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgIHx8IGkgPT0gJ0AnICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLCcgfHwgaSA9PSAnOycgfHwgaSA9PSAnOicgfHwgaSA9PSAnXFwnIHx8IGkgPT0gJ1wiJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLycgfHwgaSA9PSAnWycgfHwgaSA9PSAnXScgfHwgaSA9PSAnPycgIHx8IGkgPT0gJz0nICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAneycgfHwgaSA9PSAnfScgfHwgaSA9PSAnICcgfHwgaSA9PSAnXHQnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1NFUEFSQVRPUltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBUb2tlbjogQW55dGhpbmcgMC0xMjcgdGhhdCBpcyBub3QgYSBjb250cm9sIGFuZCBub3QgYSBzZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoIUlTX0NPTlRST0xbaV0gJiYgIUlTX1NFUEFSQVRPUltpXSAmJiBpIDwgMTI4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1RPS0VOW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIEhleDogMC05LCBhLWYsIEEtRgogICAgICAgICAgICAgICAgICAgIGlmICgoaSA+PSAnMCcgJiYgaSA8PSc5JykgfHwgKGkgPj0gJ2EnICYmIGkgPD0gJ2YnKSB8fCAoaSA+PSAnQScgJiYgaSA8PSAnRicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hFWFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIHJlcXVlc3QgdGFyZ2V0LgogICAgICAgICAgICAgICAgICAgIC8vIENvbWJpbmF0aW9uIG9mIG11bHRpcGxlIHJ1bGVzIGZyb20gUkZDNzIzMCBhbmQgUkZDIDM5ODYuIE11c3QgYmUKICAgICAgICAgICAgICAgICAgICAvLyBBU0NJSSwgbm8gY29udHJvbHMgcGx1cyBhIGZldyBhZGRpdGlvbmFsIGNoYXJhY3RlcnMgZXhjbHVkZWQKICAgICAgICAgICAgICAgICAgICBpZiAoSVNfQ09OVFJPTFtpXSB8fCBpID4gMTI3IHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcgJyB8fCBpID09ICdcIicgfHwgaSA9PSAnIycgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgfHwgaSA9PSAnXFwnIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICdeJyB8fCBpID09ICdgJyAgfHwgaSA9PSAneycgfHwgaSA9PSAnfCcgfHwgaSA9PSAnfScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfTk9UX1JFUVVFU1RfVEFSR0VUW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgSFRUUCBwcm90b2NvbAogICAgICAgICAgICAgICAgICAgIC8vICJIVFRQLyIgRElHSVQgIi4iIERJR0lUCiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gJ0gnIHx8IGkgPT0gJ1QnIHx8IGkgPT0gJ1AnIHx8IGkgPT0gJy8nIHx8IGkgPT0gJy4nIHx8IChpID49ICcwJyAmJiBpIDw9ICc5JykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSFRUUF9QUk9UT0NPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQlVGRkVSX01BUCA9ICJidWZmZXJNYXAiOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQU5JQl9QUkxfNSA9ICJhbmliX3BybF81IjsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBsYXN0VmFsaWRGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIGJ1ZkZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgcG9zRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBwYXJzaW5nUmVxdWVzdExpbmVRUG9zRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFNZXRob2QgZmlsbE1ldGhvZDsKCiAgICAgICAgICAgIHByaXZhdGUgT2JqZWN0IHNlbGY7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBsb2FkKCkgewogICAgICAgICAgICAgICAgbGFzdFZhbGlkRmllbGQgPSBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIubGFzdFZhbGlkIik7CiAgICAgICAgICAgICAgICBidWZGaWVsZCA9IEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3RJbnB1dEJ1ZmZlci5idWYiKTsKICAgICAgICAgICAgICAgIHBvc0ZpZWxkID0gSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdElucHV0QnVmZmVyLnBvcyIpOwogICAgICAgICAgICAgICAgcGFyc2luZ1JlcXVlc3RMaW5lUVBvc0ZpZWxkID0gSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdE5pb0lucHV0QnVmZmVyLnBhcnNpbmdSZXF1ZXN0TGluZVFQb3MiKTsKICAgICAgICAgICAgICAgIGZpbGxNZXRob2QgPSBKYXZhTWV0aG9kLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdElucHV0QnVmZmVyLmZpbGwoWilaIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHBhdGNoKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgTWFwPFN0cmluZywgQm9vbGVhbj4gYnVmZmVyTWFwID0gKE1hcDxTdHJpbmcsIEJvb2xlYW4+KSByZXN0b3JlVmFsdWUoQlVGRkVSX01BUCk7CiAgICAgICAgICAgICAgICBpZiAoYnVmZmVyTWFwLmdldChBTklCX1BSTF81KSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJ1ZmZlck1hcC5wdXQoQU5JQl9QUkxfNSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBzZWxmID0gZnJhbWUubG9hZFRoaXNWYXJpYWJsZSgpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBzcGFjZSA9IGZyYW1lLmxvYWRCb29sZWFuVmFyaWFibGUoMyk7CiAgICAgICAgICAgICAgICBpbnQgb3JpZ2luYWxQb3MgPSBwb3MoKTsKICAgICAgICAgICAgICAgIGludCBwYXJzaW5nUmVxdWVzdExpbmVRUG9zID0gcGFyc2luZ1JlcXVlc3RMaW5lUVBvcygpOwoKICAgICAgICAgICAgICAgIHdoaWxlICghc3BhY2UpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zKCkgPj0gbGFzdFZhbGlkKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmaWxsID0gKGJvb2xlYW4pIGZpbGxNZXRob2QuY2FsbChzZWxmLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUucmV0dXJuQm9vbGVhbihmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1ZigpW3BvcygpXSA9PSBDb25zdGFudHMuU1AgfHwgYnVmKClbcG9zKCldID09IENvbnN0YW50cy5IVCkgewogICAgICAgICAgICAgICAgICAgICAgICBwb3Mob3JpZ2luYWxQb3MpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChidWYoKVtwb3MoKV0gPT0gQ29uc3RhbnRzLkNSIHx8IGJ1ZigpW3BvcygpXSA9PSBDb25zdGFudHMuTEYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcG9zKG9yaWdpbmFsUG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnVmKClbcG9zKCldID09IENvbnN0YW50cy5RVUVTVElPTiAmJiBwYXJzaW5nUmVxdWVzdExpbmVRUG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzaW5nUmVxdWVzdExpbmVRUG9zID0gcG9zKCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc05vdFJlcXVlc3RUYXJnZXQoYnVmKClbcG9zKCldKSkgewogICAgICAgICAgICAgICAgICAgICAgICBidWZmZXJNYXAucHV0KEFOSUJfUFJMXzUsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZnJhbWUpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHBvcyhwb3MoKSArIDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIGludCBsYXN0VmFsaWQoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbGFzdFZhbGlkRmllbGQucmVhZEludChzZWxmKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBieXRlW10gYnVmKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIChieXRlW10pIGJ1ZkZpZWxkLnJlYWRPYmplY3Qoc2VsZik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgaW50IHBvcygpIHsKICAgICAgICAgICAgICAgIHJldHVybiBwb3NGaWVsZC5yZWFkSW50KHNlbGYpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHZvaWQgcG9zKGludCBpKSB7CiAgICAgICAgICAgICAgICBwb3NGaWVsZC53cml0ZUludChzZWxmLCBpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBpbnQgcGFyc2luZ1JlcXVlc3RMaW5lUVBvcygpIHsKICAgICAgICAgICAgICAgIHJldHVybiBwYXJzaW5nUmVxdWVzdExpbmVRUG9zRmllbGQucmVhZEludChzZWxmKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNOb3RSZXF1ZXN0VGFyZ2V0KGludCBjKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBJU19OT1RfUkVRVUVTVF9UQVJHRVRbY107CiAgICAgICAgICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIHRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgY2hhcmFjdGVyIGZvdW5kIGluIHRoZSByZXF1ZXN0IHRhcmdldC4gVGhlIHZhbGlkIGNoYXJhY3RlcnMgYXJlIGRlZmluZWQgaW4gUkZDIDcyMzAgYW5kIFJGQyAzOTg2IikpOwogICAgICAgICAgICB9CiAgICAgICAgZW5kY29kZQogICAgZW5kcGF0Y2gKCiAgICBwYXRjaCgiQ1ZFLTIwMTYtNjgxNiA6VEM4IDA0Iik6CiAgICAgICAgZnVuY3Rpb24oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdE5pb0lucHV0QnVmZmVyLnBhcnNlUmVxdWVzdExpbmUoWilaIiwKICAgICAgICAgICAgY2hlY2tzdW1zOiBbImIwZWExOWNjNzQiXSkgICAvLyA4LjAuMzgKICAgICAgICByZWFkcmV0dXJuKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3ROaW9JbnB1dEJ1ZmZlci5sYXN0VmFsaWQiLAogICAgICAgICAgICBvY2N1cnJlbmNlczogWzddKQoKICAgICAgICBjb2RlKGxhbmd1YWdlOiBqYXZhLCBpbXBvcnQ6IFsiamF2YS51dGlsLk1hcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuY295b3RlLmh0dHAxMS5Db25zdGFudHMiXSk6CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBUlJBWV9TSVpFID0gMTI4OwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfQ09OVFJPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfU0VQQVJBVE9SID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19UT0tFTiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSEVYID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19OT1RfUkVRVUVTVF9UQVJHRVQgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hUVFBfUFJPVE9DT0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKCiAgICAgICAgICAgIHN0YXRpYyB7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEFSUkFZX1NJWkU7IGkrKykgewogICAgICAgICAgICAgICAgICAgIC8vIENvbnRyb2w+IDAtMzEsIDEyNwogICAgICAgICAgICAgICAgICAgIGlmIChpIDwgMzIgfHwgaSA9PSAxMjcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfQ09OVFJPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBTZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoICAgIGkgPT0gJygnIHx8IGkgPT0gJyknIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nICB8fCBpID09ICdAJyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJywnIHx8IGkgPT0gJzsnIHx8IGkgPT0gJzonIHx8IGkgPT0gJ1xcJyB8fCBpID09ICdcIicgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJy8nIHx8IGkgPT0gJ1snIHx8IGkgPT0gJ10nIHx8IGkgPT0gJz8nICB8fCBpID09ICc9JyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ3snIHx8IGkgPT0gJ30nIHx8IGkgPT0gJyAnIHx8IGkgPT0gJ1x0JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19TRVBBUkFUT1JbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gVG9rZW46IEFueXRoaW5nIDAtMTI3IHRoYXQgaXMgbm90IGEgY29udHJvbCBhbmQgbm90IGEgc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCFJU19DT05UUk9MW2ldICYmICFJU19TRVBBUkFUT1JbaV0gJiYgaSA8IDEyOCkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19UT0tFTltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBIZXg6IDAtOSwgYS1mLCBBLUYKICAgICAgICAgICAgICAgICAgICBpZiAoKGkgPj0gJzAnICYmIGkgPD0nOScpIHx8IChpID49ICdhJyAmJiBpIDw9ICdmJykgfHwgKGkgPj0gJ0EnICYmIGkgPD0gJ0YnKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IRVhbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciByZXF1ZXN0IHRhcmdldC4KICAgICAgICAgICAgICAgICAgICAvLyBDb21iaW5hdGlvbiBvZiBtdWx0aXBsZSBydWxlcyBmcm9tIFJGQzcyMzAgYW5kIFJGQyAzOTg2LiBNdXN0IGJlCiAgICAgICAgICAgICAgICAgICAgLy8gQVNDSUksIG5vIGNvbnRyb2xzIHBsdXMgYSBmZXcgYWRkaXRpb25hbCBjaGFyYWN0ZXJzIGV4Y2x1ZGVkCiAgICAgICAgICAgICAgICAgICAgaWYgKElTX0NPTlRST0xbaV0gfHwgaSA+IDEyNyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnICcgfHwgaSA9PSAnXCInIHx8IGkgPT0gJyMnIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nIHx8IGkgPT0gJ1xcJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnXicgfHwgaSA9PSAnYCcgIHx8IGkgPT0gJ3snIHx8IGkgPT0gJ3wnIHx8IGkgPT0gJ30nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX05PVF9SRVFVRVNUX1RBUkdFVFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIEhUVFAgcHJvdG9jb2wKICAgICAgICAgICAgICAgICAgICAvLyAiSFRUUC8iIERJR0lUICIuIiBESUdJVAogICAgICAgICAgICAgICAgICAgIGlmIChpID09ICdIJyB8fCBpID09ICdUJyB8fCBpID09ICdQJyB8fCBpID09ICcvJyB8fCBpID09ICcuJyB8fCAoaSA+PSAnMCcgJiYgaSA8PSAnOScpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hUVFBfUFJPVE9DT0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEJVRkZFUl9NQVAgPSAiYnVmZmVyTWFwIjsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFOSUJfUFJMXzcgPSAiYW5pYl9wcmxfNyI7CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgbGFzdFZhbGlkRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBidWZGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIHBvc0ZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgcGFyc2luZ1JlcXVlc3RMaW5lUVBvc0ZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgcGFyc2luZ1JlcXVlc3RMaW5lRW9sRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFNZXRob2QgZmlsbE1ldGhvZDsKCiAgICAgICAgICAgIHByaXZhdGUgT2JqZWN0IHNlbGY7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBsb2FkKCkgewogICAgICAgICAgICAgICAgbGFzdFZhbGlkRmllbGQgPSBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIubGFzdFZhbGlkIik7CiAgICAgICAgICAgICAgICBidWZGaWVsZCA9IEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3RJbnB1dEJ1ZmZlci5idWYiKTsKICAgICAgICAgICAgICAgIHBvc0ZpZWxkID0gSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdElucHV0QnVmZmVyLnBvcyIpOwogICAgICAgICAgICAgICAgcGFyc2luZ1JlcXVlc3RMaW5lUVBvc0ZpZWxkID0gSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdE5pb0lucHV0QnVmZmVyLnBhcnNpbmdSZXF1ZXN0TGluZVFQb3MiKTsKICAgICAgICAgICAgICAgIHBhcnNpbmdSZXF1ZXN0TGluZUVvbEZpZWxkID0gSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdE5pb0lucHV0QnVmZmVyLnBhcnNpbmdSZXF1ZXN0TGluZUVvbCIpOwogICAgICAgICAgICAgICAgZmlsbE1ldGhvZCA9IEphdmFNZXRob2QubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIuZmlsbChaKVoiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgcGF0Y2goSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBCb29sZWFuPiBidWZmZXJNYXAgPSAoTWFwPFN0cmluZywgQm9vbGVhbj4pIHJlc3RvcmVWYWx1ZShCVUZGRVJfTUFQKTsKICAgICAgICAgICAgICAgIGlmIChidWZmZXJNYXAuZ2V0KEFOSUJfUFJMXzcpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnVmZmVyTWFwLnB1dChBTklCX1BSTF83LCB0cnVlKTsKICAgICAgICAgICAgICAgIHNlbGYgPSBmcmFtZS5sb2FkVGhpc1ZhcmlhYmxlKCk7CiAgICAgICAgICAgICAgICBpbnQgbGFzdFZhbGlkID0gZnJhbWUubG9hZEludE9wZXJhbmQoMCk7CgogICAgICAgICAgICAgICAgYm9vbGVhbiBwYXJzaW5nUmVxdWVzdExpbmVFb2wgPSBwYXJzaW5nUmVxdWVzdExpbmVFb2xGaWVsZC5yZWFkQm9vbGVhbihzZWxmKTsKICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSAoYnl0ZVtdKSBidWZGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CgogICAgICAgICAgICAgICAgd2hpbGUgKCFwYXJzaW5nUmVxdWVzdExpbmVFb2wpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zID49IGxhc3RWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZpbGwgPSAoYm9vbGVhbikgZmlsbE1ldGhvZC5jYWxsKHNlbGYsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmaWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5yZXR1cm5Cb29sZWFuKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkNSKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ1Zltwb3NdID09IENvbnN0YW50cy5MRikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNIdHRwUHJvdG9jb2woYnVmW3Bvc10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNIdHRwUHJvdG9jb2woaW50IGMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElTX0hUVFBfUFJPVE9DT0xbY107CiAgICAgICAgICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIGNoYXJhY3RlciBmb3VuZCBpbiB0aGUgSFRUUCBwcm90b2NvbCIpKTsKICAgICAgICAgICAgfQogICAgICAgIGVuZGNvZGUKICAgIGVuZHBhdGNoCgogICAgcGF0Y2goIkNWRS0yMDE2LTY4MTYgOlRDOCAwNSIpOgogICAgICAgIGZ1bmN0aW9uKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3ROaW9JbnB1dEJ1ZmZlci5wYXJzZUhlYWRlcigpTG9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdE5pb0lucHV0QnVmZmVyJEhlYWRlclBhcnNlU3RhdHVzOyIsCiAgICAgICAgICAgIGNoZWNrc3VtczogWyJiMGVhMTljYzc0Il0pICAgLy8gOC4wLjM4CiAgICAgICAgcmVhZHJldHVybigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0TmlvSW5wdXRCdWZmZXIubGFzdFZhbGlkIiwKICAgICAgICAgICAgb2NjdXJyZW5jZXM6IFsyXSkKCiAgICAgICAgY29kZShsYW5ndWFnZTogamF2YSwgaW1wb3J0OiBbImphdmEudXRpbC5NYXAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcmcuYXBhY2hlLmNveW90ZS5odHRwMTEuQ29uc3RhbnRzIl0pOgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQVJSQVlfU0laRSA9IDEyODsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0NPTlRST0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1NFUEFSQVRPUiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfVE9LRU4gPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hFWCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfTk9UX1JFUVVFU1RfVEFSR0VUID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IVFRQX1BST1RPQ09MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CgogICAgICAgICAgICBzdGF0aWMgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBBUlJBWV9TSVpFOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAvLyBDb250cm9sPiAwLTMxLCAxMjcKICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IDMyIHx8IGkgPT0gMTI3KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0NPTlRST0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gU2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCAgICBpID09ICcoJyB8fCBpID09ICcpJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyAgfHwgaSA9PSAnQCcgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcsJyB8fCBpID09ICc7JyB8fCBpID09ICc6JyB8fCBpID09ICdcXCcgfHwgaSA9PSAnXCInIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcvJyB8fCBpID09ICdbJyB8fCBpID09ICddJyB8fCBpID09ICc/JyAgfHwgaSA9PSAnPScgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICd7JyB8fCBpID09ICd9JyB8fCBpID09ICcgJyB8fCBpID09ICdcdCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfU0VQQVJBVE9SW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFRva2VuOiBBbnl0aGluZyAwLTEyNyB0aGF0IGlzIG5vdCBhIGNvbnRyb2wgYW5kIG5vdCBhIHNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICghSVNfQ09OVFJPTFtpXSAmJiAhSVNfU0VQQVJBVE9SW2ldICYmIGkgPCAxMjgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfVE9LRU5baV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gSGV4OiAwLTksIGEtZiwgQS1GCiAgICAgICAgICAgICAgICAgICAgaWYgKChpID49ICcwJyAmJiBpIDw9JzknKSB8fCAoaSA+PSAnYScgJiYgaSA8PSAnZicpIHx8IChpID49ICdBJyAmJiBpIDw9ICdGJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSEVYW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgcmVxdWVzdCB0YXJnZXQuCiAgICAgICAgICAgICAgICAgICAgLy8gQ29tYmluYXRpb24gb2YgbXVsdGlwbGUgcnVsZXMgZnJvbSBSRkM3MjMwIGFuZCBSRkMgMzk4Ni4gTXVzdCBiZQogICAgICAgICAgICAgICAgICAgIC8vIEFTQ0lJLCBubyBjb250cm9scyBwbHVzIGEgZmV3IGFkZGl0aW9uYWwgY2hhcmFjdGVycyBleGNsdWRlZAogICAgICAgICAgICAgICAgICAgIGlmIChJU19DT05UUk9MW2ldIHx8IGkgPiAxMjcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJyAnIHx8IGkgPT0gJ1wiJyB8fCBpID09ICcjJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyB8fCBpID09ICdcXCcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ14nIHx8IGkgPT0gJ2AnICB8fCBpID09ICd7JyB8fCBpID09ICd8JyB8fCBpID09ICd9JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19OT1RfUkVRVUVTVF9UQVJHRVRbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciBIVFRQIHByb3RvY29sCiAgICAgICAgICAgICAgICAgICAgLy8gIkhUVFAvIiBESUdJVCAiLiIgRElHSVQKICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAnSCcgfHwgaSA9PSAnVCcgfHwgaSA9PSAnUCcgfHwgaSA9PSAnLycgfHwgaSA9PSAnLicgfHwgKGkgPj0gJzAnICYmIGkgPD0gJzknKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IVFRQX1BST1RPQ09MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBidWZGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIHBvc0ZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgaGVhZGVyUGFyc2VQb3NGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YU1ldGhvZCBmaWxsTWV0aG9kOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgbGFzdFNpZ25pZmljYW50Q2hhckZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhTWV0aG9kIHNraXBMaW5lTWV0aG9kOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgaGVhZGVyRGF0YUZpZWxkOwoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgT2JqZWN0IEhFQURFUl9OQU1FOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBPYmplY3QgTkVFRF9NT1JFX0RBVEE7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gc2hvdWxkSW5pdCA9IHRydWU7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBpbml0KCkgewogICAgICAgICAgICAgICAgSEVBREVSX05BTUUgPQogICAgICAgICAgICAgICAgICAgIEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3ROaW9JbnB1dEJ1ZmZlciRIZWFkZXJQYXJzZVBvc2l0aW9uLkhFQURFUl9OQU1FIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVhZE9iamVjdChudWxsKTsKICAgICAgICAgICAgICAgIE5FRURfTU9SRV9EQVRBID0KICAgICAgICAgICAgICAgICAgICBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0TmlvSW5wdXRCdWZmZXIkSGVhZGVyUGFyc2VTdGF0dXMuTkVFRF9NT1JFX0RBVEEiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KG51bGwpOwogICAgICAgICAgICAgICAgc2hvdWxkSW5pdCA9IGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBsb2FkKCkgewogICAgICAgICAgICAgICAgYnVmRmllbGQgPSBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIuYnVmIik7CiAgICAgICAgICAgICAgICBwb3NGaWVsZCA9IEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3RJbnB1dEJ1ZmZlci5wb3MiKTsKICAgICAgICAgICAgICAgIGhlYWRlclBhcnNlUG9zRmllbGQgPSBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0TmlvSW5wdXRCdWZmZXIuaGVhZGVyUGFyc2VQb3MiKTsKICAgICAgICAgICAgICAgIGZpbGxNZXRob2QgPSBKYXZhTWV0aG9kLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdElucHV0QnVmZmVyLmZpbGwoWilaIik7CiAgICAgICAgICAgICAgICBsYXN0U2lnbmlmaWNhbnRDaGFyRmllbGQgPSBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0TmlvSW5wdXRCdWZmZXIkSGVhZGVyUGFyc2VEYXRhLmxhc3RTaWduaWZpY2FudENoYXIiKTsKICAgICAgICAgICAgICAgIHNraXBMaW5lTWV0aG9kID0gSmF2YU1ldGhvZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3ROaW9JbnB1dEJ1ZmZlci5za2lwTGluZSgpTG9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdE5pb0lucHV0QnVmZmVyJEhlYWRlclBhcnNlU3RhdHVzOyIpOwogICAgICAgICAgICAgICAgaGVhZGVyRGF0YUZpZWxkID0gSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdE5pb0lucHV0QnVmZmVyLmhlYWRlckRhdGEiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgcGF0Y2goSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBpZiAoc2hvdWxkSW5pdCkgewogICAgICAgICAgICAgICAgICAgIGluaXQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIE9iamVjdCBzZWxmID0gZnJhbWUubG9hZFRoaXNWYXJpYWJsZSgpOwogICAgICAgICAgICAgICAgYnl0ZSBjaHIgPSBmcmFtZS5sb2FkQnl0ZVZhcmlhYmxlKDEpOwogICAgICAgICAgICAgICAgaW50IGxhc3RWYWxpZCA9IGZyYW1lLmxvYWRJbnRPcGVyYW5kKDApOwoKICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSAoYnl0ZVtdKSBidWZGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CiAgICAgICAgICAgICAgICBPYmplY3QgaGVhZGVyUGFyc2VQb3MgPSBoZWFkZXJQYXJzZVBvc0ZpZWxkLnJlYWRPYmplY3Qoc2VsZik7CgogICAgICAgICAgICAgICAgd2hpbGUgKGhlYWRlclBhcnNlUG9zID09IEhFQURFUl9OQU1FKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBvcyA+PSBsYXN0VmFsaWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmaWxsID0gKGJvb2xlYW4pIGZpbGxNZXRob2QuY2FsbChzZWxmLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUucmV0dXJuT2JqZWN0KE5FRURfTU9SRV9EQVRBKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjaHIgPSBidWZbcG9zXTsKICAgICAgICAgICAgICAgICAgICBpZiAoY2hyID09IENvbnN0YW50cy5DT0xPTikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNUb2tlbihjaHIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCBoZWFkZXJEYXRhID0gaGVhZGVyRGF0YUZpZWxkLnJlYWRPYmplY3Qoc2VsZik7CiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RTaWduaWZpY2FudENoYXJGaWVsZC53cml0ZUludChoZWFkZXJEYXRhLCBwb3MpOwogICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5yZXR1cm5PYmplY3Qoc2tpcExpbmVNZXRob2QuY2FsbChzZWxmKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKChjaHIgPj0gQ29uc3RhbnRzLkEpICYmIChjaHIgPD0gQ29uc3RhbnRzLlopKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zltwb3NdID0gKGJ5dGUpIChjaHIgLSBDb25zdGFudHMuTENfT0ZGU0VUKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc1Rva2VuKGludCBjKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBJU19UT0tFTltjXTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIGVuZGNvZGUKICAgIGVuZHBhdGNoCgogICAgcGF0Y2goIkNWRS0yMDE2LTY4MTYgOlRDOCAwNiIpOgogICAgICAgIGZ1bmN0aW9uKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3ROaW9JbnB1dEJ1ZmZlci5wYXJzZVJlcXVlc3RMaW5lKFopWiIsCiAgICAgICAgICAgIGNoZWNrc3VtczogWyJiMGVhMTljYzc0Il0pICAgLy8gOC4wLjM4CiAgICAgICAgZXhpdCgpCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsIGltcG9ydDogWyJqYXZhLnV0aWwuQ29sbGVjdGlvbnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuSGFzaE1hcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5NYXAiXSk6CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBCVUZGRVJfTUFQID0gImJ1ZmZlck1hcCI7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBTklCX1BSTF8zID0gImFuaWJfcHJsXzMiOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQU5JQl9QUkxfNSA9ICJhbmliX3BybF81IjsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFOSUJfUFJMXzcgPSAiYW5pYl9wcmxfNyI7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBTklCX1BIXzIgPSAiYW5pYl9waF8yIjsKCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHBhdGNoKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgTWFwPFN0cmluZywgQm9vbGVhbj4gYnVmZmVyTWFwID0gKE1hcDxTdHJpbmcsIEJvb2xlYW4+KSByZXN0b3JlVmFsdWUoQlVGRkVSX01BUCk7CiAgICAgICAgICAgICAgICBidWZmZXJNYXAucHV0KEFOSUJfUFJMXzMsIGZhbHNlKTsKICAgICAgICAgICAgICAgIGJ1ZmZlck1hcC5wdXQoQU5JQl9QUkxfNSwgZmFsc2UpOwogICAgICAgICAgICAgICAgYnVmZmVyTWFwLnB1dChBTklCX1BSTF83LCBmYWxzZSk7CiAgICAgICAgICAgICAgICBidWZmZXJNYXAucHV0KEFOSUJfUEhfMiwgZmFsc2UpOwogICAgICAgICAgICB9CiAgICAgICAgZW5kY29kZQogICAgZW5kcGF0Y2gKCiAgICBwYXRjaCgiQ1ZFLTIwMTYtNjgxNiA6VEM4IDA3Iik6CiAgICAgICAgZnVuY3Rpb24oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbEFwcklucHV0QnVmZmVyLnBhcnNlUmVxdWVzdExpbmUoWilaIiwKICAgICAgICAgICAgY2hlY2tzdW1zOiBbIjY3OWVmZWQ2NmEiXSkgICAvLyA4LjAuMzgKICAgICAgICByZWFkcmV0dXJuKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxBcHJJbnB1dEJ1ZmZlci5sYXN0VmFsaWQiLAogICAgICAgICAgICBvY2N1cnJlbmNlczogWzNdKQoKICAgICAgICBjb2RlKGxhbmd1YWdlOiBqYXZhLCBpbXBvcnQ6IFsiamF2YS51dGlsLk1hcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS5pby5FT0ZFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuY295b3RlLmh0dHAxMS5Db25zdGFudHMiXSk6CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBUlJBWV9TSVpFID0gMTI4OwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfQ09OVFJPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfU0VQQVJBVE9SID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19UT0tFTiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSEVYID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19OT1RfUkVRVUVTVF9UQVJHRVQgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hUVFBfUFJPVE9DT0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKCiAgICAgICAgICAgIHN0YXRpYyB7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEFSUkFZX1NJWkU7IGkrKykgewogICAgICAgICAgICAgICAgICAgIC8vIENvbnRyb2w+IDAtMzEsIDEyNwogICAgICAgICAgICAgICAgICAgIGlmIChpIDwgMzIgfHwgaSA9PSAxMjcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfQ09OVFJPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBTZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoICAgIGkgPT0gJygnIHx8IGkgPT0gJyknIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nICB8fCBpID09ICdAJyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJywnIHx8IGkgPT0gJzsnIHx8IGkgPT0gJzonIHx8IGkgPT0gJ1xcJyB8fCBpID09ICdcIicgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJy8nIHx8IGkgPT0gJ1snIHx8IGkgPT0gJ10nIHx8IGkgPT0gJz8nICB8fCBpID09ICc9JyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ3snIHx8IGkgPT0gJ30nIHx8IGkgPT0gJyAnIHx8IGkgPT0gJ1x0JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19TRVBBUkFUT1JbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gVG9rZW46IEFueXRoaW5nIDAtMTI3IHRoYXQgaXMgbm90IGEgY29udHJvbCBhbmQgbm90IGEgc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCFJU19DT05UUk9MW2ldICYmICFJU19TRVBBUkFUT1JbaV0gJiYgaSA8IDEyOCkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19UT0tFTltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBIZXg6IDAtOSwgYS1mLCBBLUYKICAgICAgICAgICAgICAgICAgICBpZiAoKGkgPj0gJzAnICYmIGkgPD0nOScpIHx8IChpID49ICdhJyAmJiBpIDw9ICdmJykgfHwgKGkgPj0gJ0EnICYmIGkgPD0gJ0YnKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IRVhbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciByZXF1ZXN0IHRhcmdldC4KICAgICAgICAgICAgICAgICAgICAvLyBDb21iaW5hdGlvbiBvZiBtdWx0aXBsZSBydWxlcyBmcm9tIFJGQzcyMzAgYW5kIFJGQyAzOTg2LiBNdXN0IGJlCiAgICAgICAgICAgICAgICAgICAgLy8gQVNDSUksIG5vIGNvbnRyb2xzIHBsdXMgYSBmZXcgYWRkaXRpb25hbCBjaGFyYWN0ZXJzIGV4Y2x1ZGVkCiAgICAgICAgICAgICAgICAgICAgaWYgKElTX0NPTlRST0xbaV0gfHwgaSA+IDEyNyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnICcgfHwgaSA9PSAnXCInIHx8IGkgPT0gJyMnIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nIHx8IGkgPT0gJ1xcJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnXicgfHwgaSA9PSAnYCcgIHx8IGkgPT0gJ3snIHx8IGkgPT0gJ3wnIHx8IGkgPT0gJ30nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX05PVF9SRVFVRVNUX1RBUkdFVFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIEhUVFAgcHJvdG9jb2wKICAgICAgICAgICAgICAgICAgICAvLyAiSFRUUC8iIERJR0lUICIuIiBESUdJVAogICAgICAgICAgICAgICAgICAgIGlmIChpID09ICdIJyB8fCBpID09ICdUJyB8fCBpID09ICdQJyB8fCBpID09ICcvJyB8fCBpID09ICcuJyB8fCAoaSA+PSAnMCcgJiYgaSA8PSAnOScpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hUVFBfUFJPVE9DT0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIGJ1ZkZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgcG9zRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFNZXRob2QgZmlsbE1ldGhvZDsKCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIGxvYWQoKSB7CiAgICAgICAgICAgICAgICBidWZGaWVsZCA9IEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3RJbnB1dEJ1ZmZlci5idWYiKTsKICAgICAgICAgICAgICAgIHBvc0ZpZWxkID0gSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdElucHV0QnVmZmVyLnBvcyIpOwogICAgICAgICAgICAgICAgZmlsbE1ldGhvZCA9IEphdmFNZXRob2QubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsQXBySW5wdXRCdWZmZXIuZmlsbChaKVoiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgcGF0Y2goSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBPYmplY3Qgc2VsZiA9IGZyYW1lLmxvYWRUaGlzVmFyaWFibGUoKTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gc3BhY2UgPSBmcmFtZS5sb2FkQm9vbGVhblZhcmlhYmxlKDQpOwogICAgICAgICAgICAgICAgaW50IGxhc3RWYWxpZCA9IGZyYW1lLmxvYWRJbnRPcGVyYW5kKDApOwogICAgICAgICAgICAgICAgYnl0ZVtdIGJ1ZiA9IChieXRlW10pIGJ1ZkZpZWxkLnJlYWRPYmplY3Qoc2VsZik7CiAgICAgICAgICAgICAgICBpbnQgcG9zID0gcG9zRmllbGQucmVhZEludChzZWxmKTsKCiAgICAgICAgICAgICAgICB3aGlsZSAoIXNwYWNlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBvcyA+PSBsYXN0VmFsaWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmaWxsID0gKGJvb2xlYW4pIGZpbGxNZXRob2QuY2FsbChzZWxmLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmaWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd0VPRkV4Y2VwdGlvbihmcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1Zltwb3NdID09IENvbnN0YW50cy5TUCB8fCBidWZbcG9zXSA9PSBDb25zdGFudHMuSFQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlzVG9rZW4oYnVmW3Bvc10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzVG9rZW4oaW50IGMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElTX1RPS0VOW2NdOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHZvaWQgdGhyb3dFT0ZFeGNlcHRpb24oSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBuZXcgRU9GRXhjZXB0aW9uKCJVbmV4cGVjdGVkIEVPRiByZWFkIG9uIHRoZSBzb2NrZXQiKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIGNoYXJhY3RlciBmb3VuZCBpbiBtZXRob2QgbmFtZS4gSFRUUCBtZXRob2QgbmFtZXMgbXVzdCBiZSB0b2tlbnMiKSk7CiAgICAgICAgICAgIH0KICAgICAgICBlbmRjb2RlCiAgICBlbmRwYXRjaAoKICAgIHBhdGNoKCJDVkUtMjAxNi02ODE2IDpUQzggMDgiKToKICAgICAgICBmdW5jdGlvbigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsQXBySW5wdXRCdWZmZXIucGFyc2VSZXF1ZXN0TGluZShaKVoiLAogICAgICAgICAgICBjaGVja3N1bXM6IFsiNjc5ZWZlZDY2YSJdKSAgIC8vIDguMC4zOAogICAgICAgIHJlYWRyZXR1cm4oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbEFwcklucHV0QnVmZmVyLmxhc3RWYWxpZCIsCiAgICAgICAgICAgIG9jY3VycmVuY2VzOiBbNV0pCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsIGltcG9ydDogWyJqYXZhLnV0aWwuTWFwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS5pby5FT0ZFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcmcuYXBhY2hlLmNveW90ZS5odHRwMTEuQ29uc3RhbnRzIl0pOgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQVJSQVlfU0laRSA9IDEyODsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0NPTlRST0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1NFUEFSQVRPUiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfVE9LRU4gPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hFWCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfTk9UX1JFUVVFU1RfVEFSR0VUID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IVFRQX1BST1RPQ09MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CgogICAgICAgICAgICBzdGF0aWMgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBBUlJBWV9TSVpFOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAvLyBDb250cm9sPiAwLTMxLCAxMjcKICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IDMyIHx8IGkgPT0gMTI3KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0NPTlRST0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gU2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCAgICBpID09ICcoJyB8fCBpID09ICcpJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyAgfHwgaSA9PSAnQCcgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcsJyB8fCBpID09ICc7JyB8fCBpID09ICc6JyB8fCBpID09ICdcXCcgfHwgaSA9PSAnXCInIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcvJyB8fCBpID09ICdbJyB8fCBpID09ICddJyB8fCBpID09ICc/JyAgfHwgaSA9PSAnPScgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICd7JyB8fCBpID09ICd9JyB8fCBpID09ICcgJyB8fCBpID09ICdcdCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfU0VQQVJBVE9SW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFRva2VuOiBBbnl0aGluZyAwLTEyNyB0aGF0IGlzIG5vdCBhIGNvbnRyb2wgYW5kIG5vdCBhIHNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICghSVNfQ09OVFJPTFtpXSAmJiAhSVNfU0VQQVJBVE9SW2ldICYmIGkgPCAxMjgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfVE9LRU5baV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gSGV4OiAwLTksIGEtZiwgQS1GCiAgICAgICAgICAgICAgICAgICAgaWYgKChpID49ICcwJyAmJiBpIDw9JzknKSB8fCAoaSA+PSAnYScgJiYgaSA8PSAnZicpIHx8IChpID49ICdBJyAmJiBpIDw9ICdGJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSEVYW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgcmVxdWVzdCB0YXJnZXQuCiAgICAgICAgICAgICAgICAgICAgLy8gQ29tYmluYXRpb24gb2YgbXVsdGlwbGUgcnVsZXMgZnJvbSBSRkM3MjMwIGFuZCBSRkMgMzk4Ni4gTXVzdCBiZQogICAgICAgICAgICAgICAgICAgIC8vIEFTQ0lJLCBubyBjb250cm9scyBwbHVzIGEgZmV3IGFkZGl0aW9uYWwgY2hhcmFjdGVycyBleGNsdWRlZAogICAgICAgICAgICAgICAgICAgIGlmIChJU19DT05UUk9MW2ldIHx8IGkgPiAxMjcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJyAnIHx8IGkgPT0gJ1wiJyB8fCBpID09ICcjJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyB8fCBpID09ICdcXCcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ14nIHx8IGkgPT0gJ2AnICB8fCBpID09ICd7JyB8fCBpID09ICd8JyB8fCBpID09ICd9JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19OT1RfUkVRVUVTVF9UQVJHRVRbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciBIVFRQIHByb3RvY29sCiAgICAgICAgICAgICAgICAgICAgLy8gIkhUVFAvIiBESUdJVCAiLiIgRElHSVQKICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAnSCcgfHwgaSA9PSAnVCcgfHwgaSA9PSAnUCcgfHwgaSA9PSAnLycgfHwgaSA9PSAnLicgfHwgKGkgPj0gJzAnICYmIGkgPD0gJzknKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IVFRQX1BST1RPQ09MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBidWZGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIHBvc0ZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhTWV0aG9kIGZpbGxNZXRob2Q7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBsb2FkKCkgewogICAgICAgICAgICAgICAgYnVmRmllbGQgPSBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIuYnVmIik7CiAgICAgICAgICAgICAgICBwb3NGaWVsZCA9IEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3RJbnB1dEJ1ZmZlci5wb3MiKTsKICAgICAgICAgICAgICAgIGZpbGxNZXRob2QgPSBKYXZhTWV0aG9kLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbEFwcklucHV0QnVmZmVyLmZpbGwoWilaIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHBhdGNoKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHNlbGYgPSBmcmFtZS5sb2FkVGhpc1ZhcmlhYmxlKCk7CiAgICAgICAgICAgICAgICBib29sZWFuIHNwYWNlID0gZnJhbWUubG9hZEJvb2xlYW5WYXJpYWJsZSg0KTsKICAgICAgICAgICAgICAgIGludCBxdWVzdGlvblBvcyA9IGZyYW1lLmxvYWRJbnRWYXJpYWJsZSg2KTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gZW9sID0gZnJhbWUubG9hZEJvb2xlYW5WYXJpYWJsZSg3KTsKICAgICAgICAgICAgICAgIGludCBsYXN0VmFsaWQgPSBmcmFtZS5sb2FkSW50T3BlcmFuZCgwKTsKICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSAoYnl0ZVtdKSBidWZGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CgogICAgICAgICAgICAgICAgd2hpbGUgKCFzcGFjZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChwb3MgPj0gbGFzdFZhbGlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZmlsbCA9IChib29sZWFuKSBmaWxsTWV0aG9kLmNhbGwoc2VsZiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dFT0ZFeGNlcHRpb24oZnJhbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChidWZbcG9zXSA9PSBDb25zdGFudHMuU1AgfHwgYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkhUKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChidWZbcG9zXSA9PSBDb25zdGFudHMuQ1IpIHx8IChidWZbcG9zXSA9PSBDb25zdGFudHMuTEYpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChidWZbcG9zXSA9PSBDb25zdGFudHMuUVVFU1RJT04pICYmIChxdWVzdGlvblBvcyA9PSAtMSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcXVlc3Rpb25Qb3MgPSBwb3M7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc05vdFJlcXVlc3RUYXJnZXQoYnVmW3Bvc10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNOb3RSZXF1ZXN0VGFyZ2V0KGludCBjKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBJU19OT1RfUkVRVUVTVF9UQVJHRVRbY107CiAgICAgICAgICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIHRocm93RU9GRXhjZXB0aW9uKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgbmV3IEVPRkV4Y2VwdGlvbigiVW5leHBlY3RlZCBFT0YgcmVhZCBvbiB0aGUgc29ja2V0IikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHZvaWQgdGhyb3dJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBjaGFyYWN0ZXIgZm91bmQgaW4gdGhlIHJlcXVlc3QgdGFyZ2V0LiBUaGUgdmFsaWQgY2hhcmFjdGVycyBhcmUgZGVmaW5lZCBpbiBSRkMgNzIzMCBhbmQgUkZDIDM5ODYiKSk7CiAgICAgICAgICAgIH0KICAgICAgICBlbmRjb2RlCiAgICBlbmRwYXRjaAoKICAgIHBhdGNoKCJDVkUtMjAxNi02ODE2IDpUQzggMDkiKToKICAgICAgICBmdW5jdGlvbigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsQXBySW5wdXRCdWZmZXIucGFyc2VSZXF1ZXN0TGluZShaKVoiLAogICAgICAgICAgICBjaGVja3N1bXM6IFsiNjc5ZWZlZDY2YSJdKSAgIC8vIDguMC4zOAogICAgICAgIHJlYWRyZXR1cm4oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbEFwcklucHV0QnVmZmVyLmxhc3RWYWxpZCIsCiAgICAgICAgICAgIG9jY3VycmVuY2VzOiBbN10pCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsIGltcG9ydDogWyJqYXZhLnV0aWwuTWFwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS5pby5FT0ZFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcmcuYXBhY2hlLmNveW90ZS5odHRwMTEuQ29uc3RhbnRzIl0pOgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQVJSQVlfU0laRSA9IDEyODsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0NPTlRST0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1NFUEFSQVRPUiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfVE9LRU4gPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hFWCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfTk9UX1JFUVVFU1RfVEFSR0VUID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IVFRQX1BST1RPQ09MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CgogICAgICAgICAgICBzdGF0aWMgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBBUlJBWV9TSVpFOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAvLyBDb250cm9sPiAwLTMxLCAxMjcKICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IDMyIHx8IGkgPT0gMTI3KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0NPTlRST0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gU2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCAgICBpID09ICcoJyB8fCBpID09ICcpJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyAgfHwgaSA9PSAnQCcgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcsJyB8fCBpID09ICc7JyB8fCBpID09ICc6JyB8fCBpID09ICdcXCcgfHwgaSA9PSAnXCInIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcvJyB8fCBpID09ICdbJyB8fCBpID09ICddJyB8fCBpID09ICc/JyAgfHwgaSA9PSAnPScgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICd7JyB8fCBpID09ICd9JyB8fCBpID09ICcgJyB8fCBpID09ICdcdCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfU0VQQVJBVE9SW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFRva2VuOiBBbnl0aGluZyAwLTEyNyB0aGF0IGlzIG5vdCBhIGNvbnRyb2wgYW5kIG5vdCBhIHNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICghSVNfQ09OVFJPTFtpXSAmJiAhSVNfU0VQQVJBVE9SW2ldICYmIGkgPCAxMjgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfVE9LRU5baV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gSGV4OiAwLTksIGEtZiwgQS1GCiAgICAgICAgICAgICAgICAgICAgaWYgKChpID49ICcwJyAmJiBpIDw9JzknKSB8fCAoaSA+PSAnYScgJiYgaSA8PSAnZicpIHx8IChpID49ICdBJyAmJiBpIDw9ICdGJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSEVYW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgcmVxdWVzdCB0YXJnZXQuCiAgICAgICAgICAgICAgICAgICAgLy8gQ29tYmluYXRpb24gb2YgbXVsdGlwbGUgcnVsZXMgZnJvbSBSRkM3MjMwIGFuZCBSRkMgMzk4Ni4gTXVzdCBiZQogICAgICAgICAgICAgICAgICAgIC8vIEFTQ0lJLCBubyBjb250cm9scyBwbHVzIGEgZmV3IGFkZGl0aW9uYWwgY2hhcmFjdGVycyBleGNsdWRlZAogICAgICAgICAgICAgICAgICAgIGlmIChJU19DT05UUk9MW2ldIHx8IGkgPiAxMjcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJyAnIHx8IGkgPT0gJ1wiJyB8fCBpID09ICcjJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyB8fCBpID09ICdcXCcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ14nIHx8IGkgPT0gJ2AnICB8fCBpID09ICd7JyB8fCBpID09ICd8JyB8fCBpID09ICd9JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19OT1RfUkVRVUVTVF9UQVJHRVRbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciBIVFRQIHByb3RvY29sCiAgICAgICAgICAgICAgICAgICAgLy8gIkhUVFAvIiBESUdJVCAiLiIgRElHSVQKICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAnSCcgfHwgaSA9PSAnVCcgfHwgaSA9PSAnUCcgfHwgaSA9PSAnLycgfHwgaSA9PSAnLicgfHwgKGkgPj0gJzAnICYmIGkgPD0gJzknKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IVFRQX1BST1RPQ09MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBidWZGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIHBvc0ZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhTWV0aG9kIGZpbGxNZXRob2Q7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBsb2FkKCkgewogICAgICAgICAgICAgICAgYnVmRmllbGQgPSBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIuYnVmIik7CiAgICAgICAgICAgICAgICBwb3NGaWVsZCA9IEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3RJbnB1dEJ1ZmZlci5wb3MiKTsKICAgICAgICAgICAgICAgIGZpbGxNZXRob2QgPSBKYXZhTWV0aG9kLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbEFwcklucHV0QnVmZmVyLmZpbGwoWilaIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHBhdGNoKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHNlbGYgPSBmcmFtZS5sb2FkVGhpc1ZhcmlhYmxlKCk7CiAgICAgICAgICAgICAgICBib29sZWFuIHNwYWNlID0gZnJhbWUubG9hZEJvb2xlYW5WYXJpYWJsZSg0KTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gZW9sID0gZnJhbWUubG9hZEJvb2xlYW5WYXJpYWJsZSg3KTsKICAgICAgICAgICAgICAgIGludCBsYXN0VmFsaWQgPSBmcmFtZS5sb2FkSW50T3BlcmFuZCgwKTsKICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSAoYnl0ZVtdKSBidWZGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CgogICAgICAgICAgICAgICAgd2hpbGUgKCFlb2wpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zID49IGxhc3RWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZpbGwgPSAoYm9vbGVhbikgZmlsbE1ldGhvZC5jYWxsKHNlbGYsIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93RU9GRXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkNSKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ1Zltwb3NdID09IENvbnN0YW50cy5MRikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNIdHRwUHJvdG9jb2woYnVmW3Bvc10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzSHR0cFByb3RvY29sKGludCBjKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBJU19IVFRQX1BST1RPQ09MW2NdOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHZvaWQgdGhyb3dFT0ZFeGNlcHRpb24oSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBuZXcgRU9GRXhjZXB0aW9uKCJVbmV4cGVjdGVkIEVPRiByZWFkIG9uIHRoZSBzb2NrZXQiKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIGNoYXJhY3RlciBmb3VuZCBpbiB0aGUgSFRUUCBwcm90b2NvbCIpKTsKICAgICAgICAgICAgfQogICAgICAgIGVuZGNvZGUKICAgIGVuZHBhdGNoCgogICAgcGF0Y2goIkNWRS0yMDE2LTY4MTYgOlRDOCAxMCIpOgogICAgICAgIGZ1bmN0aW9uKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxBcHJJbnB1dEJ1ZmZlci5wYXJzZUhlYWRlcigpWiIsCiAgICAgICAgICAgIGNoZWNrc3VtczogWyI2NzllZmVkNjZhIl0pICAgLy8gOC4wLjM4CiAgICAgICAgcmVhZHJldHVybigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsQXBySW5wdXRCdWZmZXIubGFzdFZhbGlkIiwKICAgICAgICAgICAgb2NjdXJyZW5jZXM6IFsyXSkKCiAgICAgICAgY29kZShsYW5ndWFnZTogamF2YSwgaW1wb3J0OiBbImphdmEudXRpbC5NYXAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLmlvLkVPRkV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuY295b3RlLmh0dHAxMS5Db25zdGFudHMiXSk6CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBUlJBWV9TSVpFID0gMTI4OwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfQ09OVFJPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfU0VQQVJBVE9SID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19UT0tFTiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSEVYID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19OT1RfUkVRVUVTVF9UQVJHRVQgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hUVFBfUFJPVE9DT0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKCiAgICAgICAgICAgIHN0YXRpYyB7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEFSUkFZX1NJWkU7IGkrKykgewogICAgICAgICAgICAgICAgICAgIC8vIENvbnRyb2w+IDAtMzEsIDEyNwogICAgICAgICAgICAgICAgICAgIGlmIChpIDwgMzIgfHwgaSA9PSAxMjcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfQ09OVFJPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBTZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoICAgIGkgPT0gJygnIHx8IGkgPT0gJyknIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nICB8fCBpID09ICdAJyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJywnIHx8IGkgPT0gJzsnIHx8IGkgPT0gJzonIHx8IGkgPT0gJ1xcJyB8fCBpID09ICdcIicgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJy8nIHx8IGkgPT0gJ1snIHx8IGkgPT0gJ10nIHx8IGkgPT0gJz8nICB8fCBpID09ICc9JyAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ3snIHx8IGkgPT0gJ30nIHx8IGkgPT0gJyAnIHx8IGkgPT0gJ1x0JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19TRVBBUkFUT1JbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gVG9rZW46IEFueXRoaW5nIDAtMTI3IHRoYXQgaXMgbm90IGEgY29udHJvbCBhbmQgbm90IGEgc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCFJU19DT05UUk9MW2ldICYmICFJU19TRVBBUkFUT1JbaV0gJiYgaSA8IDEyOCkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19UT0tFTltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBIZXg6IDAtOSwgYS1mLCBBLUYKICAgICAgICAgICAgICAgICAgICBpZiAoKGkgPj0gJzAnICYmIGkgPD0nOScpIHx8IChpID49ICdhJyAmJiBpIDw9ICdmJykgfHwgKGkgPj0gJ0EnICYmIGkgPD0gJ0YnKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IRVhbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciByZXF1ZXN0IHRhcmdldC4KICAgICAgICAgICAgICAgICAgICAvLyBDb21iaW5hdGlvbiBvZiBtdWx0aXBsZSBydWxlcyBmcm9tIFJGQzcyMzAgYW5kIFJGQyAzOTg2LiBNdXN0IGJlCiAgICAgICAgICAgICAgICAgICAgLy8gQVNDSUksIG5vIGNvbnRyb2xzIHBsdXMgYSBmZXcgYWRkaXRpb25hbCBjaGFyYWN0ZXJzIGV4Y2x1ZGVkCiAgICAgICAgICAgICAgICAgICAgaWYgKElTX0NPTlRST0xbaV0gfHwgaSA+IDEyNyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnICcgfHwgaSA9PSAnXCInIHx8IGkgPT0gJyMnIHx8IGkgPT0gJzwnIHx8IGkgPT0gJz4nIHx8IGkgPT0gJ1xcJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnXicgfHwgaSA9PSAnYCcgIHx8IGkgPT0gJ3snIHx8IGkgPT0gJ3wnIHx8IGkgPT0gJ30nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX05PVF9SRVFVRVNUX1RBUkdFVFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIEhUVFAgcHJvdG9jb2wKICAgICAgICAgICAgICAgICAgICAvLyAiSFRUUC8iIERJR0lUICIuIiBESUdJVAogICAgICAgICAgICAgICAgICAgIGlmIChpID09ICdIJyB8fCBpID09ICdUJyB8fCBpID09ICdQJyB8fCBpID09ICcvJyB8fCBpID09ICcuJyB8fCAoaSA+PSAnMCcgJiYgaSA8PSAnOScpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hUVFBfUFJPVE9DT0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIGJ1ZkZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgcG9zRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFNZXRob2QgZmlsbE1ldGhvZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YU1ldGhvZCBza2lwTGluZU1ldGhvZDsKCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIGxvYWQoKSB7CiAgICAgICAgICAgICAgICBidWZGaWVsZCA9IEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3RJbnB1dEJ1ZmZlci5idWYiKTsKICAgICAgICAgICAgICAgIHBvc0ZpZWxkID0gSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdElucHV0QnVmZmVyLnBvcyIpOwogICAgICAgICAgICAgICAgZmlsbE1ldGhvZCA9IEphdmFNZXRob2QubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsQXBySW5wdXRCdWZmZXIuZmlsbChaKVoiKTsKICAgICAgICAgICAgICAgIHNraXBMaW5lTWV0aG9kID0gSmF2YU1ldGhvZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxBcHJJbnB1dEJ1ZmZlci5za2lwTGluZShJKVYiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgcGF0Y2goSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBPYmplY3Qgc2VsZiA9IGZyYW1lLmxvYWRUaGlzVmFyaWFibGUoKTsKICAgICAgICAgICAgICAgIGJ5dGUgY2hyID0gZnJhbWUubG9hZEJ5dGVWYXJpYWJsZSgxKTsKICAgICAgICAgICAgICAgIGludCBzdGFydCA9IGZyYW1lLmxvYWRJbnRWYXJpYWJsZSgyKTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gY29sb24gPSBmcmFtZS5sb2FkQm9vbGVhblZhcmlhYmxlKDMpOwogICAgICAgICAgICAgICAgaW50IGxhc3RWYWxpZCA9IGZyYW1lLmxvYWRJbnRPcGVyYW5kKDApOwogICAgICAgICAgICAgICAgYnl0ZVtdIGJ1ZiA9IChieXRlW10pIGJ1ZkZpZWxkLnJlYWRPYmplY3Qoc2VsZik7CiAgICAgICAgICAgICAgICBpbnQgcG9zID0gcG9zRmllbGQucmVhZEludChzZWxmKTsKCiAgICAgICAgICAgICAgICB3aGlsZSAoIWNvbG9uKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBvcyA+PSBsYXN0VmFsaWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmaWxsID0gKGJvb2xlYW4pIGZpbGxNZXRob2QuY2FsbChzZWxmLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmaWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd0VPRkV4Y2VwdGlvbihmcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1Zltwb3NdID09IENvbnN0YW50cy5DT0xPTikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNUb2tlbihidWZbcG9zXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2tpcExpbmVNZXRob2QuY2FsbChzZWxmLCBzdGFydCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lLnJldHVybkJvb2xlYW4odHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2hyID0gYnVmW3Bvc107CiAgICAgICAgICAgICAgICAgICAgaWYgKChjaHIgPj0gQ29uc3RhbnRzLkEpICYmIChjaHIgPD0gQ29uc3RhbnRzLlopKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zltwb3NdID0gKGJ5dGUpIChjaHIgLSBDb25zdGFudHMuTENfT0ZGU0VUKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc1Rva2VuKGludCBjKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBJU19UT0tFTltjXTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIHRocm93RU9GRXhjZXB0aW9uKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgbmV3IEVPRkV4Y2VwdGlvbigiVW5leHBlY3RlZCBFT0YgcmVhZCBvbiB0aGUgc29ja2V0IikpOwogICAgICAgICAgICB9CiAgICAgICAgZW5kY29kZQogICAgZW5kcGF0Y2gKCiAgICBwYXRjaCgiQ1ZFLTIwMTYtNjgxNiA6VEM4IDExIik6CiAgICAgICAgZnVuY3Rpb24oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLnBhcnNlUmVxdWVzdExpbmUoWilaIiwKICAgICAgICAgICAgY2hlY2tzdW1zOiBbImJjZGZlODExZjEiXSkgICAvLyA4LjAuMzgKICAgICAgICByZWFkcmV0dXJuKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5sYXN0VmFsaWQiLAogICAgICAgICAgICBvY2N1cnJlbmNlczogWzJdKQoKICAgICAgICBjb2RlKGxhbmd1YWdlOiBqYXZhLCBpbXBvcnQ6IFsiamF2YS51dGlsLk1hcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEuaW8uRU9GRXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLmFwYWNoZS5jb3lvdGUuaHR0cDExLkNvbnN0YW50cyJdKToKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFSUkFZX1NJWkUgPSAxMjg7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19DT05UUk9MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19TRVBBUkFUT1IgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1RPS0VOID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IRVggPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX05PVF9SRVFVRVNUX1RBUkdFVCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSFRUUF9QUk9UT0NPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwoKICAgICAgICAgICAgc3RhdGljIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQVJSQVlfU0laRTsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQ29udHJvbD4gMC0zMSwgMTI3CiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCAzMiB8fCBpID09IDEyNykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19DT05UUk9MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICggICAgaSA9PSAnKCcgfHwgaSA9PSAnKScgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgIHx8IGkgPT0gJ0AnICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLCcgfHwgaSA9PSAnOycgfHwgaSA9PSAnOicgfHwgaSA9PSAnXFwnIHx8IGkgPT0gJ1wiJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLycgfHwgaSA9PSAnWycgfHwgaSA9PSAnXScgfHwgaSA9PSAnPycgIHx8IGkgPT0gJz0nICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAneycgfHwgaSA9PSAnfScgfHwgaSA9PSAnICcgfHwgaSA9PSAnXHQnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1NFUEFSQVRPUltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBUb2tlbjogQW55dGhpbmcgMC0xMjcgdGhhdCBpcyBub3QgYSBjb250cm9sIGFuZCBub3QgYSBzZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoIUlTX0NPTlRST0xbaV0gJiYgIUlTX1NFUEFSQVRPUltpXSAmJiBpIDwgMTI4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1RPS0VOW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIEhleDogMC05LCBhLWYsIEEtRgogICAgICAgICAgICAgICAgICAgIGlmICgoaSA+PSAnMCcgJiYgaSA8PSc5JykgfHwgKGkgPj0gJ2EnICYmIGkgPD0gJ2YnKSB8fCAoaSA+PSAnQScgJiYgaSA8PSAnRicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hFWFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIHJlcXVlc3QgdGFyZ2V0LgogICAgICAgICAgICAgICAgICAgIC8vIENvbWJpbmF0aW9uIG9mIG11bHRpcGxlIHJ1bGVzIGZyb20gUkZDNzIzMCBhbmQgUkZDIDM5ODYuIE11c3QgYmUKICAgICAgICAgICAgICAgICAgICAvLyBBU0NJSSwgbm8gY29udHJvbHMgcGx1cyBhIGZldyBhZGRpdGlvbmFsIGNoYXJhY3RlcnMgZXhjbHVkZWQKICAgICAgICAgICAgICAgICAgICBpZiAoSVNfQ09OVFJPTFtpXSB8fCBpID4gMTI3IHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcgJyB8fCBpID09ICdcIicgfHwgaSA9PSAnIycgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgfHwgaSA9PSAnXFwnIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICdeJyB8fCBpID09ICdgJyAgfHwgaSA9PSAneycgfHwgaSA9PSAnfCcgfHwgaSA9PSAnfScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfTk9UX1JFUVVFU1RfVEFSR0VUW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgSFRUUCBwcm90b2NvbAogICAgICAgICAgICAgICAgICAgIC8vICJIVFRQLyIgRElHSVQgIi4iIERJR0lUCiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gJ0gnIHx8IGkgPT0gJ1QnIHx8IGkgPT0gJ1AnIHx8IGkgPT0gJy8nIHx8IGkgPT0gJy4nIHx8IChpID49ICcwJyAmJiBpIDw9ICc5JykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSFRUUF9QUk9UT0NPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgYnVmRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBwb3NGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YU1ldGhvZCBmaWxsTWV0aG9kOwoKICAgICAgICAgICAgcHVibGljIHZvaWQgbG9hZCgpIHsKICAgICAgICAgICAgICAgIGJ1ZkZpZWxkID0gSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdElucHV0QnVmZmVyLmJ1ZiIpOwogICAgICAgICAgICAgICAgcG9zRmllbGQgPSBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIucG9zIik7CiAgICAgICAgICAgICAgICBmaWxsTWV0aG9kID0gSmF2YU1ldGhvZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5maWxsKClaIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHBhdGNoKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgT2JqZWN0IHNlbGYgPSBmcmFtZS5sb2FkVGhpc1ZhcmlhYmxlKCk7CiAgICAgICAgICAgICAgICBib29sZWFuIHNwYWNlID0gZnJhbWUubG9hZEJvb2xlYW5WYXJpYWJsZSg0KTsKICAgICAgICAgICAgICAgIGludCBsYXN0VmFsaWQgPSBmcmFtZS5sb2FkSW50T3BlcmFuZCgwKTsKICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSAoYnl0ZVtdKSBidWZGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CgogICAgICAgICAgICAgICAgd2hpbGUgKCFzcGFjZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChwb3MgPj0gbGFzdFZhbGlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZmlsbCA9IChib29sZWFuKSBmaWxsTWV0aG9kLmNhbGwoc2VsZik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dFT0ZFeGNlcHRpb24oZnJhbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChidWZbcG9zXSA9PSBDb25zdGFudHMuU1AgfHwgYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkhUKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFpc1Rva2VuKGJ1Zltwb3NdKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihmcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc1Rva2VuKGludCBjKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBJU19UT0tFTltjXTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIHRocm93RU9GRXhjZXB0aW9uKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgbmV3IEVPRkV4Y2VwdGlvbigiVW5leHBlY3RlZCBFT0YgcmVhZCBvbiB0aGUgc29ja2V0IikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHZvaWQgdGhyb3dJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBjaGFyYWN0ZXIgZm91bmQgaW4gbWV0aG9kIG5hbWUuIEhUVFAgbWV0aG9kIG5hbWVzIG11c3QgYmUgdG9rZW5zIikpOwogICAgICAgICAgICB9CiAgICAgICAgZW5kY29kZQogICAgZW5kcGF0Y2gKCiAgICBwYXRjaCgiQ1ZFLTIwMTYtNjgxNiA6VEM4IDEyIik6CiAgICAgICAgZnVuY3Rpb24oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLnBhcnNlUmVxdWVzdExpbmUoWilaIiwKICAgICAgICAgICAgY2hlY2tzdW1zOiBbImJjZGZlODExZjEiXSkgICAvLyA4LjAuMzgKICAgICAgICByZWFkcmV0dXJuKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5sYXN0VmFsaWQiLAogICAgICAgICAgICBvY2N1cnJlbmNlczogWzRdKQoKICAgICAgICBjb2RlKGxhbmd1YWdlOiBqYXZhLCBpbXBvcnQ6IFsiamF2YS51dGlsLk1hcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEuaW8uRU9GRXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLmFwYWNoZS5jb3lvdGUuaHR0cDExLkNvbnN0YW50cyJdKToKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFSUkFZX1NJWkUgPSAxMjg7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19DT05UUk9MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19TRVBBUkFUT1IgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1RPS0VOID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IRVggPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX05PVF9SRVFVRVNUX1RBUkdFVCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSFRUUF9QUk9UT0NPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwoKICAgICAgICAgICAgc3RhdGljIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQVJSQVlfU0laRTsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQ29udHJvbD4gMC0zMSwgMTI3CiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCAzMiB8fCBpID09IDEyNykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19DT05UUk9MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICggICAgaSA9PSAnKCcgfHwgaSA9PSAnKScgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgIHx8IGkgPT0gJ0AnICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLCcgfHwgaSA9PSAnOycgfHwgaSA9PSAnOicgfHwgaSA9PSAnXFwnIHx8IGkgPT0gJ1wiJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLycgfHwgaSA9PSAnWycgfHwgaSA9PSAnXScgfHwgaSA9PSAnPycgIHx8IGkgPT0gJz0nICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAneycgfHwgaSA9PSAnfScgfHwgaSA9PSAnICcgfHwgaSA9PSAnXHQnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1NFUEFSQVRPUltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBUb2tlbjogQW55dGhpbmcgMC0xMjcgdGhhdCBpcyBub3QgYSBjb250cm9sIGFuZCBub3QgYSBzZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoIUlTX0NPTlRST0xbaV0gJiYgIUlTX1NFUEFSQVRPUltpXSAmJiBpIDwgMTI4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1RPS0VOW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIEhleDogMC05LCBhLWYsIEEtRgogICAgICAgICAgICAgICAgICAgIGlmICgoaSA+PSAnMCcgJiYgaSA8PSc5JykgfHwgKGkgPj0gJ2EnICYmIGkgPD0gJ2YnKSB8fCAoaSA+PSAnQScgJiYgaSA8PSAnRicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hFWFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIHJlcXVlc3QgdGFyZ2V0LgogICAgICAgICAgICAgICAgICAgIC8vIENvbWJpbmF0aW9uIG9mIG11bHRpcGxlIHJ1bGVzIGZyb20gUkZDNzIzMCBhbmQgUkZDIDM5ODYuIE11c3QgYmUKICAgICAgICAgICAgICAgICAgICAvLyBBU0NJSSwgbm8gY29udHJvbHMgcGx1cyBhIGZldyBhZGRpdGlvbmFsIGNoYXJhY3RlcnMgZXhjbHVkZWQKICAgICAgICAgICAgICAgICAgICBpZiAoSVNfQ09OVFJPTFtpXSB8fCBpID4gMTI3IHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcgJyB8fCBpID09ICdcIicgfHwgaSA9PSAnIycgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgfHwgaSA9PSAnXFwnIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICdeJyB8fCBpID09ICdgJyAgfHwgaSA9PSAneycgfHwgaSA9PSAnfCcgfHwgaSA9PSAnfScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfTk9UX1JFUVVFU1RfVEFSR0VUW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgSFRUUCBwcm90b2NvbAogICAgICAgICAgICAgICAgICAgIC8vICJIVFRQLyIgRElHSVQgIi4iIERJR0lUCiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gJ0gnIHx8IGkgPT0gJ1QnIHx8IGkgPT0gJ1AnIHx8IGkgPT0gJy8nIHx8IGkgPT0gJy4nIHx8IChpID49ICcwJyAmJiBpIDw9ICc5JykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSFRUUF9QUk9UT0NPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgYnVmRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBwb3NGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YU1ldGhvZCBmaWxsTWV0aG9kOwoKICAgICAgICAgICAgcHVibGljIHZvaWQgbG9hZCgpIHsKICAgICAgICAgICAgICAgIGJ1ZkZpZWxkID0gSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdElucHV0QnVmZmVyLmJ1ZiIpOwogICAgICAgICAgICAgICAgcG9zRmllbGQgPSBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIucG9zIik7CiAgICAgICAgICAgICAgICBmaWxsTWV0aG9kID0gSmF2YU1ldGhvZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5maWxsKClaIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHBhdGNoKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHNlbGYgPSBmcmFtZS5sb2FkVGhpc1ZhcmlhYmxlKCk7CiAgICAgICAgICAgICAgICBib29sZWFuIHNwYWNlID0gZnJhbWUubG9hZEJvb2xlYW5WYXJpYWJsZSg0KTsKICAgICAgICAgICAgICAgIGludCBxdWVzdGlvblBvcyA9IGZyYW1lLmxvYWRJbnRWYXJpYWJsZSg2KTsKICAgICAgICAgICAgICAgIGludCBsYXN0VmFsaWQgPSBmcmFtZS5sb2FkSW50T3BlcmFuZCgwKTsKICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSAoYnl0ZVtdKSBidWZGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CgogICAgICAgICAgICAgICAgd2hpbGUgKCFzcGFjZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChwb3MgPj0gbGFzdFZhbGlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZmlsbCA9IChib29sZWFuKSBmaWxsTWV0aG9kLmNhbGwoc2VsZik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dFT0ZFeGNlcHRpb24oZnJhbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChidWZbcG9zXSA9PSBDb25zdGFudHMuU1AgfHwgYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkhUKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChidWZbcG9zXSA9PSBDb25zdGFudHMuQ1IpIHx8IChidWZbcG9zXSA9PSBDb25zdGFudHMuTEYpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChidWZbcG9zXSA9PSBDb25zdGFudHMuUVVFU1RJT04pICYmIChxdWVzdGlvblBvcyA9PSAtMSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcXVlc3Rpb25Qb3MgPSBwb3M7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc05vdFJlcXVlc3RUYXJnZXQoYnVmW3Bvc10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNOb3RSZXF1ZXN0VGFyZ2V0KGludCBjKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBJU19OT1RfUkVRVUVTVF9UQVJHRVRbY107CiAgICAgICAgICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIHRocm93RU9GRXhjZXB0aW9uKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgbmV3IEVPRkV4Y2VwdGlvbigiVW5leHBlY3RlZCBFT0YgcmVhZCBvbiB0aGUgc29ja2V0IikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHZvaWQgdGhyb3dJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBjaGFyYWN0ZXIgZm91bmQgaW4gdGhlIHJlcXVlc3QgdGFyZ2V0LiBUaGUgdmFsaWQgY2hhcmFjdGVycyBhcmUgZGVmaW5lZCBpbiBSRkMgNzIzMCBhbmQgUkZDIDM5ODYiKSk7CiAgICAgICAgICAgIH0KICAgICAgICBlbmRjb2RlCiAgICBlbmRwYXRjaAoKICAgIHBhdGNoKCJDVkUtMjAxNi02ODE2IDpUQzggMTMiKToKICAgICAgICBmdW5jdGlvbigib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsSW5wdXRCdWZmZXIucGFyc2VSZXF1ZXN0TGluZShaKVoiLAogICAgICAgICAgICBjaGVja3N1bXM6IFsiYmNkZmU4MTFmMSJdKSAgIC8vIDguMC4zOAogICAgICAgIHJlYWRyZXR1cm4oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLmxhc3RWYWxpZCIsCiAgICAgICAgICAgIG9jY3VycmVuY2VzOiBbNl0pCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsIGltcG9ydDogWyJqYXZhLnV0aWwuTWFwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS5pby5FT0ZFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcmcuYXBhY2hlLmNveW90ZS5odHRwMTEuQ29uc3RhbnRzIl0pOgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQVJSQVlfU0laRSA9IDEyODsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0NPTlRST0wgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1NFUEFSQVRPUiA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfVE9LRU4gPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX0hFWCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfTk9UX1JFUVVFU1RfVEFSR0VUID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IVFRQX1BST1RPQ09MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CgogICAgICAgICAgICBzdGF0aWMgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBBUlJBWV9TSVpFOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAvLyBDb250cm9sPiAwLTMxLCAxMjcKICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IDMyIHx8IGkgPT0gMTI3KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0NPTlRST0xbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gU2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgaWYgKCAgICBpID09ICcoJyB8fCBpID09ICcpJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyAgfHwgaSA9PSAnQCcgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcsJyB8fCBpID09ICc7JyB8fCBpID09ICc6JyB8fCBpID09ICdcXCcgfHwgaSA9PSAnXCInIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcvJyB8fCBpID09ICdbJyB8fCBpID09ICddJyB8fCBpID09ICc/JyAgfHwgaSA9PSAnPScgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICd7JyB8fCBpID09ICd9JyB8fCBpID09ICcgJyB8fCBpID09ICdcdCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfU0VQQVJBVE9SW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFRva2VuOiBBbnl0aGluZyAwLTEyNyB0aGF0IGlzIG5vdCBhIGNvbnRyb2wgYW5kIG5vdCBhIHNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICghSVNfQ09OVFJPTFtpXSAmJiAhSVNfU0VQQVJBVE9SW2ldICYmIGkgPCAxMjgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfVE9LRU5baV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gSGV4OiAwLTksIGEtZiwgQS1GCiAgICAgICAgICAgICAgICAgICAgaWYgKChpID49ICcwJyAmJiBpIDw9JzknKSB8fCAoaSA+PSAnYScgJiYgaSA8PSAnZicpIHx8IChpID49ICdBJyAmJiBpIDw9ICdGJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSEVYW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgcmVxdWVzdCB0YXJnZXQuCiAgICAgICAgICAgICAgICAgICAgLy8gQ29tYmluYXRpb24gb2YgbXVsdGlwbGUgcnVsZXMgZnJvbSBSRkM3MjMwIGFuZCBSRkMgMzk4Ni4gTXVzdCBiZQogICAgICAgICAgICAgICAgICAgIC8vIEFTQ0lJLCBubyBjb250cm9scyBwbHVzIGEgZmV3IGFkZGl0aW9uYWwgY2hhcmFjdGVycyBleGNsdWRlZAogICAgICAgICAgICAgICAgICAgIGlmIChJU19DT05UUk9MW2ldIHx8IGkgPiAxMjcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJyAnIHx8IGkgPT0gJ1wiJyB8fCBpID09ICcjJyB8fCBpID09ICc8JyB8fCBpID09ICc+JyB8fCBpID09ICdcXCcgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gJ14nIHx8IGkgPT0gJ2AnICB8fCBpID09ICd7JyB8fCBpID09ICd8JyB8fCBpID09ICd9JykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19OT1RfUkVRVUVTVF9UQVJHRVRbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHZhbGlkIGZvciBIVFRQIHByb3RvY29sCiAgICAgICAgICAgICAgICAgICAgLy8gIkhUVFAvIiBESUdJVCAiLiIgRElHSVQKICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAnSCcgfHwgaSA9PSAnVCcgfHwgaSA9PSAnUCcgfHwgaSA9PSAnLycgfHwgaSA9PSAnLicgfHwgKGkgPj0gJzAnICYmIGkgPD0gJzknKSkgewogICAgICAgICAgICAgICAgICAgICAgICBJU19IVFRQX1BST1RPQ09MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBidWZGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpZWxkIHBvc0ZpZWxkOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhTWV0aG9kIGZpbGxNZXRob2Q7CgogICAgICAgICAgICBwdWJsaWMgdm9pZCBsb2FkKCkgewogICAgICAgICAgICAgICAgYnVmRmllbGQgPSBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIuYnVmIik7CiAgICAgICAgICAgICAgICBwb3NGaWVsZCA9IEphdmFGaWVsZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvQWJzdHJhY3RJbnB1dEJ1ZmZlci5wb3MiKTsKICAgICAgICAgICAgICAgIGZpbGxNZXRob2QgPSBKYXZhTWV0aG9kLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLmZpbGwoKVoiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgcGF0Y2goSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3Qgc2VsZiA9IGZyYW1lLmxvYWRUaGlzVmFyaWFibGUoKTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gZW9sID0gZnJhbWUubG9hZEJvb2xlYW5WYXJpYWJsZSg3KTsKICAgICAgICAgICAgICAgIGludCBsYXN0VmFsaWQgPSBmcmFtZS5sb2FkSW50T3BlcmFuZCgwKTsKICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSAoYnl0ZVtdKSBidWZGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CgogICAgICAgICAgICAgICAgd2hpbGUgKCFlb2wpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zID49IGxhc3RWYWxpZCkgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZpbGwgPSAoYm9vbGVhbikgZmlsbE1ldGhvZC5jYWxsKHNlbGYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93RU9GRXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoYnVmW3Bvc10gPT0gQ29uc3RhbnRzLkNSKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ1Zltwb3NdID09IENvbnN0YW50cy5MRikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNIdHRwUHJvdG9jb2woYnVmW3Bvc10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNIdHRwUHJvdG9jb2woaW50IGMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElTX0hUVFBfUFJPVE9DT0xbY107CiAgICAgICAgICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0VPRkV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIG5ldyBFT0ZFeGNlcHRpb24oIlVuZXhwZWN0ZWQgRU9GIHJlYWQgb24gdGhlIHNvY2tldCIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIHRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgY2hhcmFjdGVyIGZvdW5kIGluIHRoZSBIVFRQIHByb3RvY29sIikpOwogICAgICAgICAgICB9CiAgICAgICAgZW5kY29kZQogICAgZW5kcGF0Y2gKCiAgICBwYXRjaCgiQ1ZFLTIwMTYtNjgxNiA6VEM4IDE0Iik6CiAgICAgICAgZnVuY3Rpb24oIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9JbnRlcm5hbElucHV0QnVmZmVyLnBhcnNlSGVhZGVyKClaIiwKICAgICAgICAgICAgY2hlY2tzdW1zOiBbImJjZGZlODExZjEiXSkgICAvLyA4LjAuMzgKICAgICAgICByZWFkcmV0dXJuKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5sYXN0VmFsaWQiLAogICAgICAgICAgICBvY2N1cnJlbmNlczogWzJdKQoKICAgICAgICBjb2RlKGxhbmd1YWdlOiBqYXZhLCBpbXBvcnQ6IFsiamF2YS51dGlsLk1hcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEuaW8uRU9GRXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLmFwYWNoZS5jb3lvdGUuaHR0cDExLkNvbnN0YW50cyJdKToKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFSUkFZX1NJWkUgPSAxMjg7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19DT05UUk9MID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19TRVBBUkFUT1IgPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX1RPS0VOID0gbmV3IGJvb2xlYW5bQVJSQVlfU0laRV07CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBJU19IRVggPSBuZXcgYm9vbGVhbltBUlJBWV9TSVpFXTsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIElTX05PVF9SRVFVRVNUX1RBUkdFVCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuW10gSVNfSFRUUF9QUk9UT0NPTCA9IG5ldyBib29sZWFuW0FSUkFZX1NJWkVdOwoKICAgICAgICAgICAgc3RhdGljIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQVJSQVlfU0laRTsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQ29udHJvbD4gMC0zMSwgMTI3CiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCAzMiB8fCBpID09IDEyNykgewogICAgICAgICAgICAgICAgICAgICAgICBJU19DT05UUk9MW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFNlcGFyYXRvcgogICAgICAgICAgICAgICAgICAgIGlmICggICAgaSA9PSAnKCcgfHwgaSA9PSAnKScgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgIHx8IGkgPT0gJ0AnICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLCcgfHwgaSA9PSAnOycgfHwgaSA9PSAnOicgfHwgaSA9PSAnXFwnIHx8IGkgPT0gJ1wiJyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAnLycgfHwgaSA9PSAnWycgfHwgaSA9PSAnXScgfHwgaSA9PSAnPycgIHx8IGkgPT0gJz0nICB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9PSAneycgfHwgaSA9PSAnfScgfHwgaSA9PSAnICcgfHwgaSA9PSAnXHQnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1NFUEFSQVRPUltpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBUb2tlbjogQW55dGhpbmcgMC0xMjcgdGhhdCBpcyBub3QgYSBjb250cm9sIGFuZCBub3QgYSBzZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBpZiAoIUlTX0NPTlRST0xbaV0gJiYgIUlTX1NFUEFSQVRPUltpXSAmJiBpIDwgMTI4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX1RPS0VOW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIEhleDogMC05LCBhLWYsIEEtRgogICAgICAgICAgICAgICAgICAgIGlmICgoaSA+PSAnMCcgJiYgaSA8PSc5JykgfHwgKGkgPj0gJ2EnICYmIGkgPD0gJ2YnKSB8fCAoaSA+PSAnQScgJiYgaSA8PSAnRicpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElTX0hFWFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgdmFsaWQgZm9yIHJlcXVlc3QgdGFyZ2V0LgogICAgICAgICAgICAgICAgICAgIC8vIENvbWJpbmF0aW9uIG9mIG11bHRpcGxlIHJ1bGVzIGZyb20gUkZDNzIzMCBhbmQgUkZDIDM5ODYuIE11c3QgYmUKICAgICAgICAgICAgICAgICAgICAvLyBBU0NJSSwgbm8gY29udHJvbHMgcGx1cyBhIGZldyBhZGRpdGlvbmFsIGNoYXJhY3RlcnMgZXhjbHVkZWQKICAgICAgICAgICAgICAgICAgICBpZiAoSVNfQ09OVFJPTFtpXSB8fCBpID4gMTI3IHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICcgJyB8fCBpID09ICdcIicgfHwgaSA9PSAnIycgfHwgaSA9PSAnPCcgfHwgaSA9PSAnPicgfHwgaSA9PSAnXFwnIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID09ICdeJyB8fCBpID09ICdgJyAgfHwgaSA9PSAneycgfHwgaSA9PSAnfCcgfHwgaSA9PSAnfScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfTk9UX1JFUVVFU1RfVEFSR0VUW2ldID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdCB2YWxpZCBmb3IgSFRUUCBwcm90b2NvbAogICAgICAgICAgICAgICAgICAgIC8vICJIVFRQLyIgRElHSVQgIi4iIERJR0lUCiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gJ0gnIHx8IGkgPT0gJ1QnIHx8IGkgPT0gJ1AnIHx8IGkgPT0gJy8nIHx8IGkgPT0gJy4nIHx8IChpID49ICcwJyAmJiBpIDw9ICc5JykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVNfSFRUUF9QUk9UT0NPTFtpXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhRmllbGQgYnVmRmllbGQ7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIEphdmFGaWVsZCBwb3NGaWVsZDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSmF2YU1ldGhvZCBmaWxsTWV0aG9kOwogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBKYXZhTWV0aG9kIHNraXBMaW5lTWV0aG9kOwoKICAgICAgICAgICAgcHVibGljIHZvaWQgbG9hZCgpIHsKICAgICAgICAgICAgICAgIGJ1ZkZpZWxkID0gSmF2YUZpZWxkLmxvYWQoIm9yZy9hcGFjaGUvY295b3RlL2h0dHAxMS9BYnN0cmFjdElucHV0QnVmZmVyLmJ1ZiIpOwogICAgICAgICAgICAgICAgcG9zRmllbGQgPSBKYXZhRmllbGQubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0Fic3RyYWN0SW5wdXRCdWZmZXIucG9zIik7CiAgICAgICAgICAgICAgICBmaWxsTWV0aG9kID0gSmF2YU1ldGhvZC5sb2FkKCJvcmcvYXBhY2hlL2NveW90ZS9odHRwMTEvSW50ZXJuYWxJbnB1dEJ1ZmZlci5maWxsKClaIik7CiAgICAgICAgICAgICAgICBza2lwTGluZU1ldGhvZCA9IEphdmFNZXRob2QubG9hZCgib3JnL2FwYWNoZS9jb3lvdGUvaHR0cDExL0ludGVybmFsSW5wdXRCdWZmZXIuc2tpcExpbmUoSSlWIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHBhdGNoKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgT2JqZWN0IHNlbGYgPSBmcmFtZS5sb2FkVGhpc1ZhcmlhYmxlKCk7CiAgICAgICAgICAgICAgICBieXRlIGNociA9IGZyYW1lLmxvYWRCeXRlVmFyaWFibGUoMSk7CiAgICAgICAgICAgICAgICBpbnQgc3RhcnQgPSBmcmFtZS5sb2FkSW50VmFyaWFibGUoMik7CiAgICAgICAgICAgICAgICBib29sZWFuIGNvbG9uID0gZnJhbWUubG9hZEJvb2xlYW5WYXJpYWJsZSgzKTsKICAgICAgICAgICAgICAgIGludCBsYXN0VmFsaWQgPSBmcmFtZS5sb2FkSW50T3BlcmFuZCgwKTsKICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSAoYnl0ZVtdKSBidWZGaWVsZC5yZWFkT2JqZWN0KHNlbGYpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHBvc0ZpZWxkLnJlYWRJbnQoc2VsZik7CgogICAgICAgICAgICAgICAgd2hpbGUgKCFjb2xvbikgewogICAgICAgICAgICAgICAgICAgIGlmIChwb3MgPj0gbGFzdFZhbGlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZmlsbCA9IChib29sZWFuKSBmaWxsTWV0aG9kLmNhbGwoc2VsZik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dFT0ZFeGNlcHRpb24oZnJhbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChidWZbcG9zXSA9PSBDb25zdGFudHMuQ09MT04pIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlzVG9rZW4oYnVmW3Bvc10pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNraXBMaW5lTWV0aG9kLmNhbGwoc2VsZiwgc3RhcnQpOwogICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5yZXR1cm5Cb29sZWFuKHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNociA9IGJ1Zltwb3NdOwogICAgICAgICAgICAgICAgICAgIGlmICgoY2hyID49IENvbnN0YW50cy5BKSAmJiAoY2hyIDw9IENvbnN0YW50cy5aKSkgewogICAgICAgICAgICAgICAgICAgICAgICBidWZbcG9zXSA9IChieXRlKSAoY2hyIC0gQ29uc3RhbnRzLkxDX09GRlNFVCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNUb2tlbihpbnQgYykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gSVNfVE9LRU5bY107CiAgICAgICAgICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCB0aHJvd0VPRkV4Y2VwdGlvbihKYXZhRnJhbWUgZnJhbWUpIHsKICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uCiAgICAgICAgICAgICAgICAgICAgKG5ldyBFT0ZFeGNlcHRpb24oIlVuZXhwZWN0ZWQgRU9GIHJlYWQgb24gdGhlIHNvY2tldCIpKTsKICAgICAgICAgICAgfQogICAgICAgIGVuZGNvZGUKICAgIGVuZHBhdGNoCgplbmRhcHAK"}]},"assessment":{"record":{"state":"active"},"protection":{"level":"full","mechanisms":["patch-rule"]},"action":{"state":"available","type":"patch-rule"},"review":{"state":"human","basis":"armr-file"}},"exploits":[{"source":"exploit-db","url":"https://www.exploit-db.com/exploits/41783","title":"Apache Tomcat 6/7/8/9 - Information Disclosure","date":"2017-04-04"}],"signals":{"hasPOC":true,"pocCount":1,"pocSources":["exploit-db"],"firstPOCDate":"2017-04-04"},"kev":{"inKEV":false},"epss":{"available":true,"score":0.39633,"percentile":0.98535},"ssvc":{"available":true,"exploitation":"none","automatable":"no","technicalImpact":"partial"},"lastActivity":"2026-03-04T16:48:46Z"}