{"log":{"version":"1.2","creator":{"name":"Charles Proxy","version":"4.0"},"entries":[{"startedDateTime":"2017-03-23T09:47:02.257-04:00","time":481,"request":{"method":"GET","url":"https://jenkins.madmobile.com/blue/organizations/jenkins/Concierge%2FConcierge%20Internal%20Build/detail/Concierge%20Internal%20Build/16/tests/","httpVersion":"HTTP/1.1","cookies":[{"name":"JSESSIONID.07665201","value":"jvj7v811ia6a24xswzx3mx84"},{"name":"m.tickets.com","value":"285266442.36895.0000"},{"name":"JSESSIONID.671a2176","value":"7x7hbwsd1udpfluq5aqttf77"},{"name":"_ga","value":"GA1.2.1568028303.1489761292"},{"name":"__hstc","value":"155897444.2001d13d16178aaccc25d25d70c2dbbc.1490035088857.1490035088857.1490035088857.1"},{"name":"__hssrc","value":"1"},{"name":"hubspotutk","value":"2001d13d16178aaccc25d25d70c2dbbc"},{"name":"JSESSIONID.e58ba09b","value":"1ui3v5lrs0po81jdt31ywi97wa"},{"name":"JSESSIONID.176688ac","value":"1qf3qt3u78nxy1c80vpergut8j"},{"name":"screenResolution","value":"1920x1200"},{"name":"JSESSIONID.630fb4ae","value":"14o29p0lzolb3ei79cn6vxnb6"}],"headers":[{"name":"Host","value":"jenkins.madmobile.com"},{"name":"Connection","value":"keep-alive"},{"name":"Pragma","value":"no-cache"},{"name":"Cache-Control","value":"no-cache"},{"name":"Upgrade-Insecure-Requests","value":"1"},{"name":"User-Agent","value":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3047.0 Safari/537.36"},{"name":"Accept","value":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"},{"name":"Accept-Encoding","value":"gzip, deflate, sdch, br"},{"name":"Accept-Language","value":"en-US,en;q=0.8"},{"name":"Cookie","value":"JSESSIONID.07665201=jvj7v811ia6a24xswzx3mx84; m.tickets.com=285266442.36895.0000; JSESSIONID.671a2176=7x7hbwsd1udpfluq5aqttf77; _ga=GA1.2.1568028303.1489761292; __hstc=155897444.2001d13d16178aaccc25d25d70c2dbbc.1490035088857.1490035088857.1490035088857.1; __hssrc=1; hubspotutk=2001d13d16178aaccc25d25d70c2dbbc; JSESSIONID.e58ba09b=1ui3v5lrs0po81jdt31ywi97wa; JSESSIONID.176688ac=1qf3qt3u78nxy1c80vpergut8j; screenResolution=1920x1200; JSESSIONID.630fb4ae=14o29p0lzolb3ei79cn6vxnb6"}],"queryString":[],"headersSize":1051,"bodySize":0},"response":{"_charlesStatus":"COMPLETE","status":200,"statusText":"OK","httpVersion":"HTTP/1.1","cookies":[],"headers":[{"name":"Date","value":"Thu, 23 Mar 2017 13:47:02 GMT"},{"name":"X-Content-Type-Options","value":"nosniff"},{"name":"Content-Encoding","value":"gzip"},{"name":"Content-Type","value":"text/html;charset=UTF-8"},{"name":"Content-Length","value":"5176"},{"name":"Server","value":"Jetty(9.2.z-SNAPSHOT)"},{"name":"Connection","value":"Keep-alive"}],"content":{"size":27372,"compression":22196,"mimeType":"text/html;charset=UTF-8","text":"\n \n\n Jenkins Blue Ocean<\/title><link rel=\"stylesheet\" type=\"text/css\" href=\"/static/9d9967fa/plugin/blueocean-web/assets/jdl/css/jenkins-design-language.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"/static/9d9967fa/plugin/blueocean-web/assets/corejs/css/blueocean-core-js.css\" /><script>\n (function () {\n // construct the state object parent path inside window.$$blueocean.\n function setState(statePropertyPath, state) {\n var pathTokens = ('$blueocean.' + statePropertyPath).split('.');\n var contextObj = window;\n\n // Basically an Array shift\n function nextToken() {\n var nextToken = pathTokens[0];\n pathTokens = pathTokens.slice(1);\n return nextToken;\n }\n\n var pathToken = nextToken();\n\n // Construct up to, but not including, the last point in the graph.\n while (pathTokens.length !== 0) {\n if (!contextObj[pathToken]) {\n contextObj[pathToken] = {};\n }\n contextObj = contextObj[pathToken];\n pathToken = nextToken();\n }\n // And set the state on the last object on the graph.\n contextObj[pathToken] = state;\n }\n\n \n // State Preloader: io.jenkins.blueocean.config.BlueOceanConfigStatePreloader\n setState('config', {\"version\":\"1.0.0-rc1\",\"jenkinsConfig\":{\"version\":\"2.50\",\"security\":{\"enabled\":true,\"loginUrl\":\"login\",\"authorizationStrategy\":{\"allowAnonymousRead\":true},\"enableJWT\":false}},\"features\":{\"organizations.enabled\":false}});\n // State Preloader: io.jenkins.blueocean.config.JenkinsJSExtensionsStatePreloader\n setState('jsExtensions', [{\"hpiPluginId\":\"git-server\",\"hpiPluginVer\":\"1.7\",\"extensions\":[]},{\"hpiPluginId\":\"authentication-tokens\",\"hpiPluginVer\":\"1.3\",\"extensions\":[]},{\"hpiPluginId\":\"git-client\",\"hpiPluginVer\":\"2.3.0\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-jwt\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[]},{\"hpiPluginId\":\"ldap\",\"hpiPluginVer\":\"1.14\",\"extensions\":[]},{\"hpiPluginId\":\"multiple-scms\",\"hpiPluginVer\":\"0.6\",\"extensions\":[]},{\"hpiPluginId\":\"purge-job-history\",\"hpiPluginVer\":\"1.1\",\"extensions\":[]},{\"hpiPluginId\":\"ws-cleanup\",\"hpiPluginVer\":\"0.32\",\"extensions\":[]},{\"hpiPluginId\":\"display-url-api\",\"hpiPluginVer\":\"1.1.1\",\"extensions\":[]},{\"hpiPluginId\":\"docker-workflow\",\"hpiPluginVer\":\"1.10\",\"extensions\":[]},{\"hpiPluginId\":\"ssh-slaves\",\"hpiPluginVer\":\"1.15\",\"extensions\":[]},{\"hpiPluginId\":\"bitbucket-approve\",\"hpiPluginVer\":\"1.0.3\",\"extensions\":[]},{\"hpiPluginId\":\"ssh-credentials\",\"hpiPluginVer\":\"1.13\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-milestone-step\",\"hpiPluginVer\":\"1.3\",\"extensions\":[]},{\"hpiPluginId\":\"ace-editor\",\"hpiPluginVer\":\"1.1\",\"extensions\":[]},{\"hpiPluginId\":\"icon-shim\",\"hpiPluginVer\":\"2.0.3\",\"extensions\":[]},{\"hpiPluginId\":\"matrix-project\",\"hpiPluginVer\":\"1.8\",\"extensions\":[]},{\"hpiPluginId\":\"workflow-scm-step\",\"hpiPluginVer\":\"2.4\",\"extensions\":[]},{\"hpiPluginId\":\"slack\",\"hpiPluginVer\":\"2.2\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-i18n\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[]},{\"hpiPluginId\":\"cloudbees-folder\",\"hpiPluginVer\":\"6.0.3\",\"extensions\":[]},{\"hpiPluginId\":\"bitbucket-build-status-notifier\",\"hpiPluginVer\":\"1.3.3\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-commons\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[]},{\"hpiPluginId\":\"simple-theme-plugin\",\"hpiPluginVer\":\"0.3\",\"extensions\":[]},{\"hpiPluginId\":\"mercurial\",\"hpiPluginVer\":\"1.59\",\"extensions\":[]},{\"hpiPluginId\":\"workflow-api\",\"hpiPluginVer\":\"2.12\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-rest-impl\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[]},{\"hpiPluginId\":\"mapdb-api\",\"hpiPluginVer\":\"1.0.9.0\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-input-step\",\"hpiPluginVer\":\"2.5\",\"extensions\":[]},{\"hpiPluginId\":\"credentials\",\"hpiPluginVer\":\"2.1.13\",\"extensions\":[]},{\"hpiPluginId\":\"role-strategy\",\"hpiPluginVer\":\"2.3.2\",\"extensions\":[]},{\"hpiPluginId\":\"javadoc\",\"hpiPluginVer\":\"1.4\",\"extensions\":[]},{\"hpiPluginId\":\"subversion\",\"hpiPluginVer\":\"2.7.2\",\"extensions\":[]},{\"hpiPluginId\":\"sse-gateway\",\"hpiPluginVer\":\"1.15\",\"extensions\":[]},{\"hpiPluginId\":\"structs\",\"hpiPluginVer\":\"1.6\",\"extensions\":[]},{\"hpiPluginId\":\"cloudbees-bitbucket-branch-source\",\"hpiPluginVer\":\"2.1.2\",\"extensions\":[]},{\"hpiPluginId\":\"matrix-auth\",\"hpiPluginVer\":\"1.4\",\"extensions\":[]},{\"hpiPluginId\":\"plain-credentials\",\"hpiPluginVer\":\"1.4\",\"extensions\":[]},{\"hpiPluginId\":\"workflow-basic-steps\",\"hpiPluginVer\":\"2.4\",\"extensions\":[]},{\"hpiPluginId\":\"pubsub-light\",\"hpiPluginVer\":\"1.7\",\"extensions\":[]},{\"hpiPluginId\":\"resource-disposer\",\"hpiPluginVer\":\"0.6\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-rest-api\",\"hpiPluginVer\":\"2.6\",\"extensions\":[]},{\"hpiPluginId\":\"bouncycastle-api\",\"hpiPluginVer\":\"2.16.0\",\"extensions\":[]},{\"hpiPluginId\":\"jquery-detached\",\"hpiPluginVer\":\"1.2.1\",\"extensions\":[]},{\"hpiPluginId\":\"hipchat\",\"hpiPluginVer\":\"2.1.1\",\"extensions\":[]},{\"hpiPluginId\":\"external-monitor-job\",\"hpiPluginVer\":\"1.7\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-build-step\",\"hpiPluginVer\":\"2.4\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-rest\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[]},{\"hpiPluginId\":\"workflow-cps-global-lib\",\"hpiPluginVer\":\"2.7\",\"extensions\":[]},{\"hpiPluginId\":\"windows-slaves\",\"hpiPluginVer\":\"1.3.1\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-stage-tags-metadata\",\"hpiPluginVer\":\"1.1.1\",\"extensions\":[]},{\"hpiPluginId\":\"antisamy-markup-formatter\",\"hpiPluginVer\":\"1.5\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-display-url\",\"hpiPluginVer\":\"1.5.1\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-model-extensions\",\"hpiPluginVer\":\"1.1.1\",\"extensions\":[]},{\"hpiPluginId\":\"mailer\",\"hpiPluginVer\":\"1.20\",\"extensions\":[]},{\"hpiPluginId\":\"credentials-binding\",\"hpiPluginVer\":\"1.10\",\"extensions\":[]},{\"hpiPluginId\":\"favorite\",\"hpiPluginVer\":\"2.0.4\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-graph-analysis\",\"hpiPluginVer\":\"1.3\",\"extensions\":[]},{\"hpiPluginId\":\"junit\",\"hpiPluginVer\":\"1.20\",\"extensions\":[]},{\"hpiPluginId\":\"jackson2-api\",\"hpiPluginVer\":\"2.7.3\",\"extensions\":[]},{\"hpiPluginId\":\"workflow-cps\",\"hpiPluginVer\":\"2.29\",\"extensions\":[]},{\"hpiPluginId\":\"workflow-aggregator\",\"hpiPluginVer\":\"2.5\",\"extensions\":[]},{\"hpiPluginId\":\"variant\",\"hpiPluginVer\":\"1.1\",\"extensions\":[]},{\"hpiPluginId\":\"workflow-durable-task-step\",\"hpiPluginVer\":\"2.10\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-autofavorite\",\"hpiPluginVer\":\"0.6\",\"extensions\":[]},{\"hpiPluginId\":\"token-macro\",\"hpiPluginVer\":\"2.0\",\"extensions\":[]},{\"hpiPluginId\":\"codedeploy\",\"hpiPluginVer\":\"1.15\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-pipeline-editor\",\"extensionCSS\":\"org/jenkins/ui/jsmodules/blueocean-pipeline-editor/extensions.css\",\"hpiPluginVer\":\"0.2-rc1\",\"extensions\":[{\"extensionPoint\":\"jenkins.main.routes\",\"component\":\"EditorRoutes\"},{\"dataType\":\"org.jenkinsci.plugins.workflow.job.WorkflowRun\",\"extensionPoint\":\"jenkins.blueocean.rundetails.top.widgets\",\"component\":\"PipelineEditorLink\"},{\"extensionPoint\":\"jenkins.pipeline.branches.list.action\",\"component\":\"PipelineEditorLink\",\"ordinal\":50},{\"extensionPoint\":\"pipeline.editor.css\",\"component\":\"components/editor/EditorCSS\"},{\"extensionPoint\":\"jenkins.pipeline.editor\",\"component\":\"PipelineEditor\"},{\"extensionPoint\":\"jenkins.pipeline.create.missing.jenkinsfile\",\"component\":\"PipelineCreateButton\"}],\"i18nBundles\":[]},{\"hpiPluginId\":\"blueocean-pipeline-api-impl\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[]},{\"hpiPluginId\":\"pam-auth\",\"hpiPluginVer\":\"1.3\",\"extensions\":[]},{\"hpiPluginId\":\"github-api\",\"hpiPluginVer\":\"1.85\",\"extensions\":[]},{\"hpiPluginId\":\"cvs\",\"hpiPluginVer\":\"2.13\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-events\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[]},{\"hpiPluginId\":\"git\",\"hpiPluginVer\":\"3.1.0\",\"extensions\":[]},{\"hpiPluginId\":\"workflow-support\",\"hpiPluginVer\":\"2.13\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-personalization\",\"extensionCSS\":\"org/jenkins/ui/jsmodules/blueocean-personalization/extensions.css\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[{\"extensionPoint\":\"jenkins.main.stores\",\"component\":\"redux/FavoritesStore\"},{\"extensionPoint\":\"jenkins.pipeline.list.top\",\"component\":\"components/DashboardCards\"},{\"extensionPoint\":\"jenkins.pipeline.list.action\",\"component\":\"components/FavoritePipeline\"},{\"extensionPoint\":\"jenkins.pipeline.detail.header.action\",\"component\":\"components/FavoritePipelineHeader\"},{\"extensionPoint\":\"jenkins.pipeline.branches.list.action\",\"component\":\"components/FavoritePipeline\",\"ordinal\":100}],\"i18nBundles\":[\"jenkins.plugins.blueocean.personalization.Messages\"]},{\"hpiPluginId\":\"blueocean-github-pipeline\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[]},{\"hpiPluginId\":\"bitbucket-pullrequest-builder\",\"hpiPluginVer\":\"1.4.25\",\"extensions\":[]},{\"hpiPluginId\":\"hockeyapp\",\"hpiPluginVer\":\"1.2.2\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-git-pipeline\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[]},{\"hpiPluginId\":\"xcode-plugin\",\"hpiPluginVer\":\"1.4.11\",\"extensions\":[]},{\"hpiPluginId\":\"workflow-step-api\",\"hpiPluginVer\":\"2.9\",\"extensions\":[]},{\"hpiPluginId\":\"github-organization-folder\",\"hpiPluginVer\":\"1.6\",\"extensions\":[]},{\"hpiPluginId\":\"ssh\",\"hpiPluginVer\":\"2.4\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-dashboard\",\"extensionCSS\":\"org/jenkins/ui/jsmodules/blueocean-dashboard/extensions.css\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[{\"extensionPoint\":\"jenkins.logo.top\",\"component\":\"AdminNavLink\"},{\"extensionPoint\":\"jenkins.main.routes\",\"component\":\"PipelineRoutes\"},{\"extensionPoint\":\"jenkins.main.stores\",\"component\":\"PipelineStore\"},{\"extensionPoint\":\"jenkins.pipeline.run.result\",\"component\":\"components/PipelineRunGraph\"},{\"dataType\":\"hudson.tasks.test.TestResult\",\"extensionPoint\":\"jenkins.test.result\",\"component\":\"components/testing/TestResults\"},{\"extensionPoint\":\"jenkins.pipeline.create.scm.provider\",\"component\":\"creation/git/GitScmProvider\"},{\"extensionPoint\":\"jenkins.pipeline.create.scm.provider\",\"component\":\"creation/github/GithubScmProvider\"}],\"i18nBundles\":[\"jenkins.plugins.blueocean.dashboard.Messages\"]},{\"hpiPluginId\":\"docker-commons\",\"hpiPluginVer\":\"1.6\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-stage-step\",\"hpiPluginVer\":\"2.2\",\"extensions\":[]},{\"hpiPluginId\":\"branch-api\",\"hpiPluginVer\":\"2.0.8\",\"extensions\":[]},{\"hpiPluginId\":\"aws-java-sdk\",\"hpiPluginVer\":\"1.11.68\",\"extensions\":[]},{\"hpiPluginId\":\"maven-plugin\",\"hpiPluginVer\":\"2.15.1\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean-web\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[],\"i18nBundles\":[\"jenkins.plugins.blueocean.web.Messages\"]},{\"hpiPluginId\":\"blueocean-config\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[]},{\"hpiPluginId\":\"build-token-root\",\"hpiPluginVer\":\"1.4\",\"extensions\":[]},{\"hpiPluginId\":\"scm-api\",\"hpiPluginVer\":\"2.1.1\",\"extensions\":[]},{\"hpiPluginId\":\"durable-task\",\"hpiPluginVer\":\"1.13\",\"extensions\":[]},{\"hpiPluginId\":\"metrics\",\"hpiPluginVer\":\"3.1.2.9\",\"extensions\":[]},{\"hpiPluginId\":\"translation\",\"hpiPluginVer\":\"1.15\",\"extensions\":[]},{\"hpiPluginId\":\"script-security\",\"hpiPluginVer\":\"1.27\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-model-declarative-agent\",\"hpiPluginVer\":\"1.1.1\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-github-lib\",\"hpiPluginVer\":\"1.0\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-model-api\",\"hpiPluginVer\":\"1.1.1\",\"extensions\":[]},{\"hpiPluginId\":\"workflow-job\",\"hpiPluginVer\":\"2.10\",\"extensions\":[]},{\"hpiPluginId\":\"ant\",\"hpiPluginVer\":\"1.4\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-model-definition\",\"hpiPluginVer\":\"1.1.1\",\"extensions\":[]},{\"hpiPluginId\":\"github\",\"hpiPluginVer\":\"1.26.1\",\"extensions\":[]},{\"hpiPluginId\":\"workflow-multibranch\",\"hpiPluginVer\":\"2.14\",\"extensions\":[]},{\"hpiPluginId\":\"momentjs\",\"hpiPluginVer\":\"1.1.1\",\"extensions\":[]},{\"hpiPluginId\":\"blueocean\",\"hpiPluginVer\":\"1.0.0-rc1\",\"extensions\":[]},{\"hpiPluginId\":\"github-branch-source\",\"hpiPluginVer\":\"2.0.4\",\"extensions\":[]},{\"hpiPluginId\":\"pipeline-stage-view\",\"hpiPluginVer\":\"2.6\",\"extensions\":[]},{\"hpiPluginId\":\"handlebars\",\"hpiPluginVer\":\"1.1.1\",\"extensions\":[]}]);\n // State Preloader: io.jenkins.blueocean.preload.FavoritesStatePreloader\n setState('prefetchdata.FavoritesStatePreloader', {\"restUrl\":\"/blue/rest/users/jbrito/favorites/\",\"data\":\"[]\"});\n // State Preloader: io.jenkins.blueocean.preload.PipelineActivityStatePreloader\n \n // State Preloader: io.jenkins.blueocean.preload.PipelineBranchRunStatePreloader\n \n // State Preloader: io.jenkins.blueocean.preload.PipelineStatePreloader\n setState('prefetchdata.PipelineStatePreloader', {\"restUrl\":\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/\",\"data\":\"{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.impl.pipeline.PipelineImpl\\\",\\\"_links\\\":{\\\"queue\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/queue/\\\"},\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/\\\"},\\\"activities\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/activities/\\\"},\\\"runs\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/\\\"},\\\"actions\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/actions/\\\"}},\\\"actions\\\":[{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.ActionProxiesImpl\\\",\\\"_links\\\":{\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/credentials/\\\"}},\\\"_class\\\":\\\"com.cloudbees.plugins.credentials.ViewCredentialsAction\\\",\\\"stores\\\":{},\\\"urlName\\\":\\\"credentials\\\"}],\\\"displayName\\\":\\\"Concierge Internal Build\\\",\\\"estimatedDurationInMillis\\\":421072,\\\"fullDisplayName\\\":\\\"Concierge/Concierge%20Internal%20Build\\\",\\\"fullName\\\":\\\"Concierge/Concierge Internal Build\\\",\\\"lastSuccessfulRun\\\":\\\"http://jenkins.madmobile.com/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/\\\",\\\"latestRun\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.impl.pipeline.PipelineRunImpl\\\",\\\"_links\\\":{\\\"nodes\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/nodes/\\\"},\\\"parent\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/\\\"},\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/\\\"},\\\"steps\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/steps/\\\"},\\\"log\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/log/\\\"},\\\"actions\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/actions/\\\"},\\\"artifacts\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/artifacts/\\\"}},\\\"actions\\\":[{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.ActionProxiesImpl\\\",\\\"_links\\\":{\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/parameters/\\\"}},\\\"_class\\\":\\\"hudson.model.ParametersAction\\\",\\\"parameters\\\":[{\\\"_class\\\":\\\"hudson.model.StringParameterValue\\\",\\\"name\\\":\\\"Certificate\\\",\\\"value\\\":\\\"Dev\\\"},{\\\"_class\\\":\\\"hudson.model.StringParameterValue\\\",\\\"name\\\":\\\"Release\\\",\\\"value\\\":\\\"Alpha\\\"},{\\\"_class\\\":\\\"hudson.model.StringParameterValue\\\",\\\"name\\\":\\\"Config\\\",\\\"value\\\":\\\"Debug\\\"},{\\\"_class\\\":\\\"hudson.model.TextParameterValue\\\",\\\"name\\\":\\\"Branch\\\",\\\"value\\\":\\\"develop\\\"}],\\\"urlName\\\":\\\"parameters\\\"},{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.ActionProxiesImpl\\\",\\\"_links\\\":{\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/cause/\\\"}},\\\"_class\\\":\\\"hudson.model.CauseAction\\\",\\\"causes\\\":[{\\\"_class\\\":\\\"hudson.model.Cause$UserIdCause\\\",\\\"shortDescription\\\":\\\"Started by user Jonathan Brito\\\",\\\"userId\\\":\\\"jbrito\\\",\\\"userName\\\":\\\"Jonathan Brito\\\"}],\\\"urlName\\\":\\\"cause\\\"},{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.ActionProxiesImpl\\\",\\\"_links\\\":{\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/timings/\\\"}},\\\"_class\\\":\\\"jenkins.metrics.impl.TimeInQueueAction\\\",\\\"queuingDurationMillis\\\":7,\\\"totalDurationMillis\\\":502820,\\\"urlName\\\":\\\"timings\\\"},{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.ActionProxiesImpl\\\",\\\"_links\\\":{\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/git/\\\"}},\\\"_class\\\":\\\"hudson.plugins.git.util.BuildData\\\",\\\"buildsByBranchName\\\":{\\\"refs/remotes/origin/develop\\\":{\\\"_class\\\":\\\"hudson.plugins.git.util.Build\\\",\\\"buildNumber\\\":10,\\\"buildResult\\\":null,\\\"marked\\\":{\\\"SHA1\\\":\\\"bb3eadc1484dc6d6b0f5be612f96aa2d3069393c\\\",\\\"branch\\\":[{\\\"SHA1\\\":\\\"bb3eadc1484dc6d6b0f5be612f96aa2d3069393c\\\",\\\"name\\\":\\\"refs/remotes/origin/develop\\\"}]},\\\"revision\\\":{\\\"SHA1\\\":\\\"bb3eadc1484dc6d6b0f5be612f96aa2d3069393c\\\",\\\"branch\\\":[{\\\"SHA1\\\":\\\"bb3eadc1484dc6d6b0f5be612f96aa2d3069393c\\\",\\\"name\\\":\\\"refs/remotes/origin/develop\\\"}]}},\\\"refs/remotes/origin/feature/internal-build\\\":{\\\"_class\\\":\\\"hudson.plugins.git.util.Build\\\",\\\"buildNumber\\\":16,\\\"buildResult\\\":null,\\\"marked\\\":{\\\"SHA1\\\":\\\"c0fdf4dda88d1d983939e4610933495fdc3be58b\\\",\\\"branch\\\":[{\\\"SHA1\\\":\\\"c0fdf4dda88d1d983939e4610933495fdc3be58b\\\",\\\"name\\\":\\\"refs/remotes/origin/feature/internal-build\\\"}]},\\\"revision\\\":{\\\"SHA1\\\":\\\"c0fdf4dda88d1d983939e4610933495fdc3be58b\\\",\\\"branch\\\":[{\\\"SHA1\\\":\\\"c0fdf4dda88d1d983939e4610933495fdc3be58b\\\",\\\"name\\\":\\\"refs/remotes/origin/feature/internal-build\\\"}]}}},\\\"lastBuiltRevision\\\":{\\\"SHA1\\\":\\\"c0fdf4dda88d1d983939e4610933495fdc3be58b\\\",\\\"branch\\\":[{\\\"SHA1\\\":\\\"c0fdf4dda88d1d983939e4610933495fdc3be58b\\\",\\\"name\\\":\\\"refs/remotes/origin/feature/internal-build\\\"}]},\\\"remoteUrls\\\":[\\\"git@bitbucket.org:madmobile/the-oracle.git\\\"],\\\"scmName\\\":\\\"\\\",\\\"urlName\\\":\\\"git\\\"},{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.ActionProxiesImpl\\\",\\\"_links\\\":{\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/tagBuild/\\\"}},\\\"_class\\\":\\\"hudson.plugins.git.GitTagAction\\\",\\\"tags\\\":[],\\\"urlName\\\":\\\"tagBuild\\\"},{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.ActionProxiesImpl\\\",\\\"_links\\\":{\\\"self\\\":null},\\\"_class\\\":\\\"org.jenkinsci.plugins.workflow.cps.EnvActionImpl\\\",\\\"environment\\\":{},\\\"urlName\\\":null},{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.ActionProxiesImpl\\\",\\\"_links\\\":{\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/git/\\\"}},\\\"_class\\\":\\\"hudson.plugins.git.util.BuildData\\\",\\\"buildsByBranchName\\\":{\\\"refs/remotes/origin/develop\\\":{\\\"_class\\\":\\\"hudson.plugins.git.util.Build\\\",\\\"buildNumber\\\":16,\\\"buildResult\\\":null,\\\"marked\\\":{\\\"SHA1\\\":\\\"b020b3f0f623eaf1f8ea975e1d429dc270cb359d\\\",\\\"branch\\\":[{\\\"SHA1\\\":\\\"b020b3f0f623eaf1f8ea975e1d429dc270cb359d\\\",\\\"name\\\":\\\"refs/remotes/origin/develop\\\"}]},\\\"revision\\\":{\\\"SHA1\\\":\\\"b020b3f0f623eaf1f8ea975e1d429dc270cb359d\\\",\\\"branch\\\":[{\\\"SHA1\\\":\\\"b020b3f0f623eaf1f8ea975e1d429dc270cb359d\\\",\\\"name\\\":\\\"refs/remotes/origin/develop\\\"}]}},\\\"refs/remotes/origin/feature/internal-build\\\":{\\\"_class\\\":\\\"hudson.plugins.git.util.Build\\\",\\\"buildNumber\\\":15,\\\"buildResult\\\":null,\\\"marked\\\":{\\\"SHA1\\\":\\\"d56d6c6c250eb6d642354788de666e088ee20672\\\",\\\"branch\\\":[{\\\"SHA1\\\":\\\"d56d6c6c250eb6d642354788de666e088ee20672\\\",\\\"name\\\":\\\"refs/remotes/origin/feature/internal-build\\\"}]},\\\"revision\\\":{\\\"SHA1\\\":\\\"d56d6c6c250eb6d642354788de666e088ee20672\\\",\\\"branch\\\":[{\\\"SHA1\\\":\\\"d56d6c6c250eb6d642354788de666e088ee20672\\\",\\\"name\\\":\\\"refs/remotes/origin/feature/internal-build\\\"}]}}},\\\"lastBuiltRevision\\\":{\\\"SHA1\\\":\\\"b020b3f0f623eaf1f8ea975e1d429dc270cb359d\\\",\\\"branch\\\":[{\\\"SHA1\\\":\\\"b020b3f0f623eaf1f8ea975e1d429dc270cb359d\\\",\\\"name\\\":\\\"refs/remotes/origin/develop\\\"}]},\\\"remoteUrls\\\":[\\\"git@bitbucket.org:madmobile/the-oracle.git\\\"],\\\"scmName\\\":\\\"\\\",\\\"urlName\\\":\\\"git\\\"},{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.ActionProxiesImpl\\\",\\\"_links\\\":{\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/tagBuild/\\\"}},\\\"_class\\\":\\\"hudson.plugins.git.GitTagAction\\\",\\\"tags\\\":[],\\\"urlName\\\":\\\"tagBuild\\\"},{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.ActionProxiesImpl\\\",\\\"_links\\\":{\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/testReport/\\\"}},\\\"_class\\\":\\\"hudson.tasks.junit.TestResultAction\\\",\\\"failCount\\\":0,\\\"skipCount\\\":0,\\\"totalCount\\\":30,\\\"urlName\\\":\\\"testReport\\\"}],\\\"artifactsZipFile\\\":\\\"/job/Concierge/job/Concierge%20Internal%20Build/16/artifact/*zip*/archive.zip\\\",\\\"changeSet\\\":[{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.ChangeSetResource\\\",\\\"_links\\\":{\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/organizations/jenkins/pipelines/Concierge/pipelines/Concierge Internal Build/runs/16/changeset/c0fdf4dda88d1d983939e4610933495fdc3be58b/\\\"}},\\\"affectedPaths\\\":[\\\"Jenkinsfile\\\"],\\\"author\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.UserImpl\\\",\\\"_links\\\":{\\\"self\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/users/jbrito/\\\"},\\\"favorites\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.rest.hal.Link\\\",\\\"href\\\":\\\"/blue/rest/users/jbrito/favorites/\\\"}},\\\"avatar\\\":null,\\\"email\\\":\\\"jbrito@madmobile.com\\\",\\\"fullName\\\":\\\"Jonathan Brito\\\",\\\"id\\\":\\\"jbrito\\\",\\\"permission\\\":{\\\"_class\\\":\\\"io.jenkins.blueocean.service.embedded.rest.UserImpl$1\\\",\\\"administrator\\\":true,\\\"credential\\\":{\\\"create\\\":true,\\\"view\\\":true,\\\"delete\\\":true,\\\"update\\\":true,\\\"manageDomains\\\":true},\\\"pipeline\\\":{\\\"create\\\":true,\\\"read\\\":true,\\\"start\\\":true,\\\"stop\\\":true,\\\"configure\\\":true}}},\\\"commitId\\\":\\\"c0fdf4dda88d1d983939e4610933495fdc3be58b\\\",\\\"msg\\\":\\\"Update jenkins file.\\\",\\\"timestamp\\\":\\\"2017-03-22T09:18:30.000-0400\\\",\\\"url\\\":null}],\\\"durationInMillis\\\":502813,\\\"enQueueTime\\\":\\\"2017-03-22T09:21:36.712-0400\\\",\\\"endTime\\\":\\\"2017-03-22T09:29:59.534-0400\\\",\\\"estimatedDurationInMillis\\\":421072,\\\"id\\\":\\\"16\\\",\\\"organization\\\":\\\"jenkins\\\",\\\"pipeline\\\":\\\"Concierge Internal Build\\\",\\\"result\\\":\\\"SUCCESS\\\",\\\"runSummary\\\":\\\"back to normal\\\",\\\"startTime\\\":\\\"2017-03-22T09:21:36.721-0400\\\",\\\"state\\\":\\\"FINISHED\\\",\\\"type\\\":\\\"WorkflowRun\\\",\\\"commitId\\\":\\\"c0fdf4dda88d1d983939e4610933495fdc3be58b\\\"},\\\"name\\\":\\\"Concierge Internal Build\\\",\\\"organization\\\":\\\"jenkins\\\",\\\"parameters\\\":[{\\\"_class\\\":\\\"hudson.model.ChoiceParameterDefinition\\\",\\\"defaultParameterValue\\\":{\\\"_class\\\":\\\"hudson.model.StringParameterValue\\\",\\\"name\\\":\\\"Certificate\\\",\\\"value\\\":\\\"Dev\\\"},\\\"description\\\":\\\"For iOS Cert/Provisioning Profile, for Windows Sign or Don't Sign\\\",\\\"name\\\":\\\"Certificate\\\",\\\"type\\\":\\\"ChoiceParameterDefinition\\\",\\\"choices\\\":[\\\"Dev\\\",\\\"Enterprise\\\"]},{\\\"_class\\\":\\\"hudson.model.ChoiceParameterDefinition\\\",\\\"defaultParameterValue\\\":{\\\"_class\\\":\\\"hudson.model.StringParameterValue\\\",\\\"name\\\":\\\"Release\\\",\\\"value\\\":\\\"Alpha\\\"},\\\"description\\\":\\\"What version to build in HockeyApp\\\",\\\"name\\\":\\\"Release\\\",\\\"type\\\":\\\"ChoiceParameterDefinition\\\",\\\"choices\\\":[\\\"Alpha\\\",\\\"Beta\\\",\\\"UAT\\\",\\\"Production\\\"]},{\\\"_class\\\":\\\"hudson.model.ChoiceParameterDefinition\\\",\\\"defaultParameterValue\\\":{\\\"_class\\\":\\\"hudson.model.StringParameterValue\\\",\\\"name\\\":\\\"Config\\\",\\\"value\\\":\\\"Debug\\\"},\\\"description\\\":\\\"Debug or Release?\\\",\\\"name\\\":\\\"Config\\\",\\\"type\\\":\\\"ChoiceParameterDefinition\\\",\\\"choices\\\":[\\\"Debug\\\",\\\"Release\\\"]},{\\\"_class\\\":\\\"hudson.model.TextParameterDefinition\\\",\\\"defaultParameterValue\\\":{\\\"_class\\\":\\\"hudson.model.StringParameterValue\\\",\\\"name\\\":\\\"Branch\\\",\\\"value\\\":\\\"develop\\\"},\\\"description\\\":\\\"Branch\\\",\\\"name\\\":\\\"Branch\\\",\\\"type\\\":\\\"TextParameterDefinition\\\"}],\\\"permissions\\\":{\\\"create\\\":true,\\\"configure\\\":true,\\\"read\\\":true,\\\"start\\\":true,\\\"stop\\\":true},\\\"weatherScore\\\":40}\"});\n // State Preloader: io.jenkins.blueocean.preload.UserStatePreloader\n setState('user', {\"_class\":\"io.jenkins.blueocean.service.embedded.rest.UserImpl\",\"_links\":{\"self\":{\"_class\":\"io.jenkins.blueocean.rest.hal.Link\",\"href\":\"/blue/rest/users/jbrito/\"},\"favorites\":{\"_class\":\"io.jenkins.blueocean.rest.hal.Link\",\"href\":\"/blue/rest/users/jbrito/favorites/\"}},\"avatar\":null,\"email\":\"jbrito@madmobile.com\",\"fullName\":\"Jonathan Brito\",\"id\":\"jbrito\",\"permission\":{\"_class\":\"io.jenkins.blueocean.service.embedded.rest.UserImpl$1\",\"administrator\":true,\"credential\":{\"create\":true,\"view\":true,\"delete\":true,\"update\":true,\"manageDomains\":true},\"pipeline\":{\"create\":true,\"read\":true,\"start\":true,\"stop\":true,\"configure\":true}}});\n })();\n <\/script><style type=\"text/css\">\n #loadbar{background:#4A90E2;height:5px;width:0;position:fixed;top:0;left:0;opacity:1;z-index:10000}\n .loadbar-light #loadbar{background:#fff;transition:background-color .1s}\n #loadbar.go{transition:width 1s ease-in;width:40%}\n #loadbar.go.long{transition: all 5s ease-out;width:70%}\n #loadbar.go.long.longer{transition: all 60s ease-out;width:95%}\n #loadbar.go.complete.complete.complete{transition: all .5s ease-out;width:100%;opacity:0;}\n <\/style><\/head><body><div id=\"loadbar\"><\/div><script>window.isDevelopmentMode = false;\n function lb(c,t){setTimeout(function(){document.getElementById('loadbar').classList.add(c)},t)}\n lb('go',10);lb('long',1000);lb('longer',6000);<\/script><div id=\"root\" class=\"container-fluid\"><noscript><div><a href=\"https://jenkins.io/projects/blueocean\" target=\"_blank\">\n Blue Ocean\n <\/a>\n requires JavaScript to function properly, please enable JavaScript or use a browser which supports it.\n <\/div><\/noscript><\/div><link rel='stylesheet' href='/adjuncts/9d9967fa/io/jenkins/blueocean/blueocean.css' type='text/css' /><script src='/adjuncts/9d9967fa/io/jenkins/blueocean/blueocean.js' type='text/javascript'><\/script><\/body><\/html>"},"redirectURL":null,"headersSize":205,"bodySize":5176},"serverIPAddress":"184.106.4.69","cache":{},"timings":{"dns":-1,"connect":131,"ssl":129,"send":133,"wait":152,"receive":65}},{"startedDateTime":"2017-03-23T09:47:02.609-04:00","time":141,"request":{"method":"GET","url":"https://jenkins.madmobile.com/static/9d9967fa/plugin/blueocean-web/assets/jdl/css/jenkins-design-language.css","httpVersion":"HTTP/1.1","cookies":[{"name":"JSESSIONID.07665201","value":"jvj7v811ia6a24xswzx3mx84"},{"name":"m.tickets.com","value":"285266442.36895.0000"},{"name":"JSESSIONID.671a2176","value":"7x7hbwsd1udpfluq5aqttf77"},{"name":"_ga","value":"GA1.2.1568028303.1489761292"},{"name":"__hstc","value":"155897444.2001d13d16178aaccc25d25d70c2dbbc.1490035088857.1490035088857.1490035088857.1"},{"name":"__hssrc","value":"1"},{"name":"hubspotutk","value":"2001d13d16178aaccc25d25d70c2dbbc"},{"name":"JSESSIONID.e58ba09b","value":"1ui3v5lrs0po81jdt31ywi97wa"},{"name":"JSESSIONID.176688ac","value":"1qf3qt3u78nxy1c80vpergut8j"},{"name":"screenResolution","value":"1920x1200"},{"name":"JSESSIONID.630fb4ae","value":"14o29p0lzolb3ei79cn6vxnb6"}],"headers":[{"name":"Host","value":"jenkins.madmobile.com"},{"name":"Connection","value":"keep-alive"},{"name":"Pragma","value":"no-cache"},{"name":"Cache-Control","value":"no-cache"},{"name":"User-Agent","value":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3047.0 Safari/537.36"},{"name":"Accept","value":"text/css,*/*;q=0.1"},{"name":"Referer","value":"https://jenkins.madmobile.com/blue/organizations/jenkins/Concierge%2FConcierge%20Internal%20Build/detail/Concierge%20Internal%20Build/16/tests/"},{"name":"Accept-Encoding","value":"gzip, deflate, sdch, br"},{"name":"Accept-Language","value":"en-US,en;q=0.8"},{"name":"Cookie","value":"JSESSIONID.07665201=jvj7v811ia6a24xswzx3mx84; m.tickets.com=285266442.36895.0000; JSESSIONID.671a2176=7x7hbwsd1udpfluq5aqttf77; _ga=GA1.2.1568028303.1489761292; __hstc=155897444.2001d13d16178aaccc25d25d70c2dbbc.1490035088857.1490035088857.1490035088857.1; __hssrc=1; hubspotutk=2001d13d16178aaccc25d25d70c2dbbc; JSESSIONID.e58ba09b=1ui3v5lrs0po81jdt31ywi97wa; JSESSIONID.176688ac=1qf3qt3u78nxy1c80vpergut8j; screenResolution=1920x1200; JSESSIONID.630fb4ae=14o29p0lzolb3ei79cn6vxnb6"}],"queryString":[],"headersSize":1074,"bodySize":0},"response":{"_charlesStatus":"COMPLETE","status":200,"statusText":"OK","httpVersion":"HTTP/1.1","cookies":[],"headers":[{"name":"Date","value":"Thu, 23 Mar 2017 13:47:02 GMT"},{"name":"X-Content-Type-Options","value":"nosniff"},{"name":"Cache-Control","value":"public, max-age=31536000"},{"name":"Last-Modified","value":"Wed, 15 Mar 2017 01:13:34 GMT"},{"name":"Accept-Ranges","value":"bytes"},{"name":"Content-Type","value":"text/css"},{"name":"Content-Encoding","value":"gzip"},{"name":"Content-Length","value":"17601"},{"name":"Server","value":"Jetty(9.2.z-SNAPSHOT)"},{"name":"Connection","value":"Keep-alive"}],"content":{"size":118713,"compression":101112,"mimeType":"text/css","text":"/*!\n* Jenkins Design Language CSS Theme\n*\n* Licensed under MIT\n*/\n/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */\n\n/**\n * 1. Change the default font family in all browsers (opinionated).\n * 2. Correct the line height in all browsers.\n * 3. Prevent adjustments of font size after orientation changes in\n * IE on Windows Phone and in iOS.\n */\n\n/* Document\n ========================================================================== */\n\nhtml {\n font-family: sans-serif; /* 1 */\n line-height: 1.15; /* 2 */\n -ms-text-size-adjust: 100%; /* 3 */\n -webkit-text-size-adjust: 100%; /* 3 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers (opinionated).\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Add the correct display in IE 9-.\n */\n\narticle,\naside,\nfooter,\nheader,\nnav,\nsection {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * Add the correct display in IE 9-.\n * 1. Add the correct display in IE.\n */\n\nfigcaption,\nfigure,\nmain { /* 1 */\n display: block;\n}\n\n/**\n * Add the correct margin in IE 8.\n */\n\nfigure {\n margin: 1em 40px;\n}\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * 1. Remove the gray background on active links in IE 10.\n * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.\n */\n\na {\n background-color: transparent; /* 1 */\n -webkit-text-decoration-skip: objects; /* 2 */\n}\n\n/**\n * Remove the outline on focused links when they are also active or hovered\n * in all browsers (opinionated).\n */\n\na:active,\na:hover {\n outline-width: 0;\n}\n\n/**\n * 1. Remove the bottom border in Firefox 39-.\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Prevent the duplicate application of `bolder` by the next rule in Safari 6.\n */\n\nb,\nstrong {\n font-weight: inherit;\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font style in Android 4.3-.\n */\n\ndfn {\n font-style: italic;\n}\n\n/**\n * Add the correct background and color in IE 9-.\n */\n\nmark {\n background-color: #ff0;\n color: #000;\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Add the correct display in IE 9-.\n */\n\naudio,\nvideo {\n display: inline-block;\n}\n\n/**\n * Add the correct display in iOS 4-7.\n */\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n/**\n * Remove the border on images inside links in IE 10-.\n */\n\nimg {\n border-style: none;\n}\n\n/**\n * Hide the overflow in IE.\n */\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers (opinionated).\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: sans-serif; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput { /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\n * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n * controls in Android 4.\n * 2. Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\nhtml [type=\"button\"], /* 1 */\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; /* 2 */\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Change the border, margin, and padding in all browsers (opinionated).\n */\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * 1. Add the correct display in IE 9-.\n * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n display: inline-block; /* 1 */\n vertical-align: baseline; /* 2 */\n}\n\n/**\n * Remove the default vertical scrollbar in IE.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10-.\n * 2. Remove the padding in IE 10-.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in IE 9-.\n * 1. Add the correct display in Edge, IE, and Firefox.\n */\n\ndetails, /* 1 */\nmenu {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Scripting\n ========================================================================== */\n\n/**\n * Add the correct display in IE 9-.\n */\n\ncanvas {\n display: inline-block;\n}\n\n/**\n * Add the correct display in IE.\n */\n\ntemplate {\n display: none;\n}\n\n/* Hidden\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10-.\n */\n\n[hidden] {\n display: none;\n}\n\n/* Webfont: LatoLatin-Light */@font-face {\n font-family: 'LatoLatinWebLight';\n src: url('../fonts/LatoLatin-Light.woff') format('woff');\n font-style: normal;\n font-weight: normal;\n text-rendering: optimizeLegibility;\n}\n\n/* Webfont: LatoLatin-Regular */@font-face {\n font-family: 'LatoLatinWeb';\n src: url('../fonts/LatoLatin-Regular.woff') format('woff');\n font-style: normal;\n font-weight: normal;\n text-rendering: optimizeLegibility;\n}\n\n/* Webfont: LatoLatin-Bold */@font-face {\n font-family: 'LatoLatinWeb';\n src: url('../fonts/LatoLatin-Bold.woff') format('woff');\n font-style: normal;\n font-weight: bold;\n text-rendering: optimizeLegibility;\n}\n\n/* Webfont: LatoLatin-Italic */@font-face {\n font-family: 'LatoLatinWeb';\n src: url('../fonts/LatoLatin-Italic.woff') format('woff');\n font-style: italic;\n font-weight: normal;\n text-rendering: optimizeLegibility;\n}\n\n/* Webfont: LatoLatin-Medium */@font-face {\n font-family: 'LatoLatinWebMedium';\n src: url('../fonts/LatoLatin-Medium.woff') format('woff');\n font-style: normal;\n font-weight: normal;\n text-rendering: optimizeLegibility;\n}\n\n/* Webfont: LatoLatin-Semibold */@font-face {\n font-family: 'LatoLatinWebSemibold';\n src: url('../fonts/LatoLatin-Semibold.woff') format('woff');\n font-style: normal;\n font-weight: normal;\n text-rendering: optimizeLegibility;\n}\n\n\n@font-face {\n font-family:\"Octicons\";\n src:url(\"octicons.eot?ef21c39f0ca9b1b5116e5eb7ac5eabe6\");\n src:url(\"octicons.eot?#iefix\") format(\"embedded-opentype\"),\n\t\turl(\"octicons.woff2?ef21c39f0ca9b1b5116e5eb7ac5eabe6\") format(\"woff2\"),\n\t\turl(\"octicons.woff?ef21c39f0ca9b1b5116e5eb7ac5eabe6\") format(\"woff\"),\n\t\turl(\"octicons.ttf?ef21c39f0ca9b1b5116e5eb7ac5eabe6\") format(\"truetype\"),\n\t\turl(\"octicons.svg?ef21c39f0ca9b1b5116e5eb7ac5eabe6#octicons\") format(\"svg\");\n font-weight:normal;\n font-style:normal;\n}\n\n\n/*\n\n.octicon is optimized for 16px.\n.mega-octicon is optimized for 32px but can be used larger.\n\n*/\n.octicon, .mega-octicon {\n font: normal normal normal 16px/1 Octicons;\n display: inline-block;\n text-decoration: none;\n text-rendering: auto;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n speak: none;\n}\n.mega-octicon { font-size: 32px; }\n\n.octicon-alert:before { content:\"\\f02d\"; }\n\n.octicon-arrow-down:before { content:\"\\f03f\"; }\n\n.octicon-arrow-left:before { content:\"\\f040\"; }\n\n.octicon-arrow-right:before { content:\"\\f03e\"; }\n\n.octicon-arrow-small-down:before { content:\"\\f0a0\"; }\n\n.octicon-arrow-small-left:before { content:\"\\f0a1\"; }\n\n.octicon-arrow-small-right:before { content:\"\\f071\"; }\n\n.octicon-arrow-small-up:before { content:\"\\f09f\"; }\n\n.octicon-arrow-up:before { content:\"\\f03d\"; }\n\n.octicon-beaker:before { content:\"\\f0dd\"; }\n\n.octicon-bell:before { content:\"\\f0de\"; }\n\n.octicon-bold:before { content:\"\\f0e2\"; }\n\n.octicon-book:before { content:\"\\f007\"; }\n\n.octicon-bookmark:before { content:\"\\f07b\"; }\n\n.octicon-briefcase:before { content:\"\\f0d3\"; }\n\n.octicon-broadcast:before { content:\"\\f048\"; }\n\n.octicon-browser:before { content:\"\\f0c5\"; }\n\n.octicon-bug:before { content:\"\\f091\"; }\n\n.octicon-calendar:before { content:\"\\f068\"; }\n\n.octicon-check:before { content:\"\\f03a\"; }\n\n.octicon-checklist:before { content:\"\\f076\"; }\n\n.octicon-chevron-down:before { content:\"\\f0a3\"; }\n\n.octicon-chevron-left:before { content:\"\\f0a4\"; }\n\n.octicon-chevron-right:before { content:\"\\f078\"; }\n\n.octicon-chevron-up:before { content:\"\\f0a2\"; }\n\n.octicon-circle-slash:before { content:\"\\f084\"; }\n\n.octicon-circuit-board:before { content:\"\\f0d6\"; }\n\n.octicon-clippy:before { content:\"\\f035\"; }\n\n.octicon-clock:before { content:\"\\f046\"; }\n\n.octicon-cloud-download:before { content:\"\\f00b\"; }\n\n.octicon-cloud-upload:before { content:\"\\f00c\"; }\n\n.octicon-code:before { content:\"\\f05f\"; }\n\n.octicon-comment-discussion:before { content:\"\\f04f\"; }\n\n.octicon-comment:before { content:\"\\f02b\"; }\n\n.octicon-credit-card:before { content:\"\\f045\"; }\n\n.octicon-dash:before { content:\"\\f0ca\"; }\n\n.octicon-dashboard:before { content:\"\\f07d\"; }\n\n.octicon-database:before { content:\"\\f096\"; }\n\n.octicon-desktop-download:before { content:\"\\f0dc\"; }\n\n.octicon-device-camera-video:before { content:\"\\f057\"; }\n\n.octicon-device-camera:before { content:\"\\f056\"; }\n\n.octicon-device-desktop:before { content:\"\\f27c\"; }\n\n.octicon-device-mobile:before { content:\"\\f038\"; }\n\n.octicon-diff-added:before { content:\"\\f06b\"; }\n\n.octicon-diff-ignored:before { content:\"\\f099\"; }\n\n.octicon-diff-modified:before { content:\"\\f06d\"; }\n\n.octicon-diff-removed:before { content:\"\\f06c\"; }\n\n.octicon-diff-renamed:before { content:\"\\f06e\"; }\n\n.octicon-diff:before { content:\"\\f04d\"; }\n\n.octicon-ellipses:before { content:\"\\f101\"; }\n\n.octicon-ellipsis:before { content:\"\\f09a\"; }\n\n.octicon-eye:before { content:\"\\f04e\"; }\n\n.octicon-file-binary:before { content:\"\\f094\"; }\n\n.octicon-file-code:before { content:\"\\f010\"; }\n\n.octicon-file-directory:before { content:\"\\f016\"; }\n\n.octicon-file-media:before { content:\"\\f012\"; }\n\n.octicon-file-pdf:before { content:\"\\f014\"; }\n\n.octicon-file-submodule:before { content:\"\\f017\"; }\n\n.octicon-file-symlink-directory:before { content:\"\\f0b1\"; }\n\n.octicon-file-symlink-file:before { content:\"\\f0b0\"; }\n\n.octicon-file-text:before { content:\"\\f011\"; }\n\n.octicon-file-zip:before { content:\"\\f013\"; }\n\n.octicon-file:before { content:\"\\f102\"; }\n\n.octicon-flame:before { content:\"\\f0d2\"; }\n\n.octicon-fold:before { content:\"\\f0cc\"; }\n\n.octicon-gear:before { content:\"\\f02f\"; }\n\n.octicon-gift:before { content:\"\\f042\"; }\n\n.octicon-gist-secret:before { content:\"\\f08c\"; }\n\n.octicon-gist:before { content:\"\\f00e\"; }\n\n.octicon-git-branch:before { content:\"\\f020\"; }\n\n.octicon-git-commit:before { content:\"\\f01f\"; }\n\n.octicon-git-compare:before { content:\"\\f0ac\"; }\n\n.octicon-git-merge:before { content:\"\\f023\"; }\n\n.octicon-git-pull-request:before { content:\"\\f009\"; }\n\n.octicon-globe:before { content:\"\\f0b6\"; }\n\n.octicon-grabber:before { content:\"\\f103\"; }\n\n.octicon-graph:before { content:\"\\f043\"; }\n\n.octicon-heart:before { content:\"\\2665\"; }\n\n.octicon-history:before { content:\"\\f07e\"; }\n\n.octicon-home:before { content:\"\\f08d\"; }\n\n.octicon-horizontal-rule:before { content:\"\\f070\"; }\n\n.octicon-hubot:before { content:\"\\f09d\"; }\n\n.octicon-inbox:before { content:\"\\f0cf\"; }\n\n.octicon-info:before { content:\"\\f059\"; }\n\n.octicon-issue-closed:before { content:\"\\f028\"; }\n\n.octicon-issue-opened:before { content:\"\\f026\"; }\n\n.octicon-issue-reopened:before { content:\"\\f027\"; }\n\n.octicon-italic:before { content:\"\\f0e4\"; }\n\n.octicon-jersey:before { content:\"\\f019\"; }\n\n.octicon-key:before { content:\"\\f049\"; }\n\n.octicon-keyboard:before { content:\"\\f00d\"; }\n\n.octicon-law:before { content:\"\\f0d8\"; }\n\n.octicon-light-bulb:before { content:\"\\f000\"; }\n\n.octicon-link-external:before { content:\"\\f07f\"; }\n\n.octicon-link:before { content:\"\\f05c\"; }\n\n.octicon-list-ordered:before { content:\"\\f062\"; }\n\n.octicon-list-unordered:before { content:\"\\f061\"; }\n\n.octicon-location:before { content:\"\\f060\"; }\n\n.octicon-lock:before { content:\"\\f06a\"; }\n\n.octicon-logo-gist:before { content:\"\\f0ad\"; }\n\n.octicon-logo-github:before { content:\"\\f092\"; }\n\n.octicon-mail-read:before { content:\"\\f03c\"; }\n\n.octicon-mail-reply:before { content:\"\\f051\"; }\n\n.octicon-mail:before { content:\"\\f03b\"; }\n\n.octicon-mark-github:before { content:\"\\f00a\"; }\n\n.octicon-markdown:before { content:\"\\f0c9\"; }\n\n.octicon-megaphone:before { content:\"\\f077\"; }\n\n.octicon-mention:before { content:\"\\f0be\"; }\n\n.octicon-milestone:before { content:\"\\f075\"; }\n\n.octicon-mirror:before { content:\"\\f024\"; }\n\n.octicon-mortar-board:before { content:\"\\f0d7\"; }\n\n.octicon-mute:before { content:\"\\f080\"; }\n\n.octicon-no-newline:before { content:\"\\f09c\"; }\n\n.octicon-octoface:before { content:\"\\f008\"; }\n\n.octicon-organization:before { content:\"\\f037\"; }\n\n.octicon-package:before { content:\"\\f0c4\"; }\n\n.octicon-paintcan:before { content:\"\\f0d1\"; }\n\n.octicon-pencil:before { content:\"\\f058\"; }\n\n.octicon-person:before { content:\"\\f018\"; }\n\n.octicon-pin:before { content:\"\\f041\"; }\n\n.octicon-plug:before { content:\"\\f0d4\"; }\n\n.octicon-plus-small:before { content:\"\\f104\"; }\n\n.octicon-plus:before { content:\"\\f05d\"; }\n\n.octicon-primitive-dot:before { content:\"\\f052\"; }\n\n.octicon-primitive-square:before { content:\"\\f053\"; }\n\n.octicon-pulse:before { content:\"\\f085\"; }\n\n.octicon-question:before { content:\"\\f02c\"; }\n\n.octicon-quote:before { content:\"\\f063\"; }\n\n.octicon-radio-tower:before { content:\"\\f030\"; }\n\n.octicon-reply:before { content:\"\\f105\"; }\n\n.octicon-repo-clone:before { content:\"\\f04c\"; }\n\n.octicon-repo-force-push:before { content:\"\\f04a\"; }\n\n.octicon-repo-forked:before { content:\"\\f002\"; }\n\n.octicon-repo-pull:before { content:\"\\f006\"; }\n\n.octicon-repo-push:before { content:\"\\f005\"; }\n\n.octicon-repo:before { content:\"\\f001\"; }\n\n.octicon-rocket:before { content:\"\\f033\"; }\n\n.octicon-rss:before { content:\"\\f034\"; }\n\n.octicon-ruby:before { content:\"\\f047\"; }\n\n.octicon-search:before { content:\"\\f02e\"; }\n\n.octicon-server:before { content:\"\\f097\"; }\n\n.octicon-settings:before { content:\"\\f07c\"; }\n\n.octicon-shield:before { content:\"\\f0e1\"; }\n\n.octicon-sign-in:before { content:\"\\f036\"; }\n\n.octicon-sign-out:before { content:\"\\f032\"; }\n\n.octicon-smiley:before { content:\"\\f0e7\"; }\n\n.octicon-squirrel:before { content:\"\\f0b2\"; }\n\n.octicon-star:before { content:\"\\f02a\"; }\n\n.octicon-stop:before { content:\"\\f08f\"; }\n\n.octicon-sync:before { content:\"\\f087\"; }\n\n.octicon-tag:before { content:\"\\f015\"; }\n\n.octicon-tasklist:before { content:\"\\f0e5\"; }\n\n.octicon-telescope:before { content:\"\\f088\"; }\n\n.octicon-terminal:before { content:\"\\f0c8\"; }\n\n.octicon-text-size:before { content:\"\\f0e3\"; }\n\n.octicon-three-bars:before { content:\"\\f05e\"; }\n\n.octicon-thumbsdown:before { content:\"\\f0db\"; }\n\n.octicon-thumbsup:before { content:\"\\f0da\"; }\n\n.octicon-tools:before { content:\"\\f031\"; }\n\n.octicon-trashcan:before { content:\"\\f0d0\"; }\n\n.octicon-triangle-down:before { content:\"\\f05b\"; }\n\n.octicon-triangle-left:before { content:\"\\f044\"; }\n\n.octicon-triangle-right:before { content:\"\\f05a\"; }\n\n.octicon-triangle-up:before { content:\"\\f0aa\"; }\n\n.octicon-unfold:before { content:\"\\f039\"; }\n\n.octicon-unmute:before { content:\"\\f0ba\"; }\n\n.octicon-unverified:before { content:\"\\f0e8\"; }\n\n.octicon-verified:before { content:\"\\f0e6\"; }\n\n.octicon-versions:before { content:\"\\f064\"; }\n\n.octicon-watch:before { content:\"\\f0e0\"; }\n\n.octicon-x:before { content:\"\\f081\"; }\n\n.octicon-zap:before { content:\"\\26a1\"; }\n\n\n.weather-icon {\n display: inline-block;\n width: 32px;\n height: 32px;\n background-size: contain;\n background-repeat: no-repeat;\n background-position: center center;\n}\n.weather-icon.large-icon {\n width: 60px;\n height: 60px;\n}\n.jdl-table td .weather-icon {\n vertical-align: middle;\n}\n.weather-sunny {\n background-image: url(\"../icons/weather/Sunny.svg\");\n}\n.weather-partially-sunny {\n background-image: url(\"../icons/weather/Partially%20Sunny.svg\");\n}\n.weather-cloudy {\n background-image: url(\"../icons/weather/Cloudy.svg\");\n}\n.weather-raining {\n background-image: url(\"../icons/weather/Raining.svg\");\n}\n.weather-storm {\n background-image: url(\"../icons/weather/Storm.svg\");\n}\n.control-border {\n border: 1px solid rgba(73, 73, 73, 0.5);\n border-radius: 3px;\n}\n.focus-rect {\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\n.ie11-focus-rect {\n box-shadow: inset 0 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n.focus-styles {\n outline: 0;\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\n.u-disabled {\n opacity: 0.4;\n cursor: auto;\n}\n.u-error-color {\n color: #d54c53;\n}\n.u-error-border {\n border-color: #d54c53;\n}\n.cloak {\n border: 0;\n clip: rect(0, 0, 0, 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n width: 1px;\n}\nbutton,\n.btn,\n.btn-default,\n.btn-primary {\n display: inline-block;\n border: solid 1px #4A90E2;\n border-radius: 3px;\n text-align: center;\n text-decoration: none;\n background-color: #4A90E2;\n color: #fff;\n cursor: pointer;\n padding: 6px 20px;\n}\nbutton:hover,\n.btn:hover,\n.btn-default:hover,\n.btn-primary:hover,\nbutton.hover,\n.btn.hover,\n.btn-default.hover,\n.btn-primary.hover {\n color: #fff;\n background-color: #3080de;\n text-decoration: none;\n}\nbutton:focus,\n.btn:focus,\n.btn-default:focus,\n.btn-primary:focus,\nbutton.focus,\n.btn.focus,\n.btn-default.focus,\n.btn-primary.focus {\n outline: 0;\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\nbutton:active,\n.btn:active,\n.btn-default:active,\n.btn-primary:active,\nbutton.active,\n.btn.active,\n.btn-default.active,\n.btn-primary.active {\n background-color: #2171ce;\n}\nbutton.disabled,\n.btn.disabled,\n.btn-default.disabled,\n.btn-primary.disabled,\nbutton[disabled],\n.btn[disabled],\n.btn-default[disabled],\n.btn-primary[disabled],\nfieldset[disabled] button,\nfieldset[disabled] .btn,\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nbutton.disabled:hover,\n.btn.disabled:hover,\n.btn-default.disabled:hover,\n.btn-primary.disabled:hover,\nbutton[disabled]:hover,\n.btn[disabled]:hover,\n.btn-default[disabled]:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] button:hover,\nfieldset[disabled] .btn:hover,\nfieldset[disabled] .btn-default:hover,\nfieldset[disabled] .btn-primary:hover,\nbutton.disabled:focus,\n.btn.disabled:focus,\n.btn-default.disabled:focus,\n.btn-primary.disabled:focus,\nbutton[disabled]:focus,\n.btn[disabled]:focus,\n.btn-default[disabled]:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] button:focus,\nfieldset[disabled] .btn:focus,\nfieldset[disabled] .btn-default:focus,\nfieldset[disabled] .btn-primary:focus,\nbutton.disabled.focus,\n.btn.disabled.focus,\n.btn-default.disabled.focus,\n.btn-primary.disabled.focus,\nbutton[disabled].focus,\n.btn[disabled].focus,\n.btn-default[disabled].focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] button.focus,\nfieldset[disabled] .btn.focus,\nfieldset[disabled] .btn-default.focus,\nfieldset[disabled] .btn-primary.focus,\nbutton.disabled:active,\n.btn.disabled:active,\n.btn-default.disabled:active,\n.btn-primary.disabled:active,\nbutton[disabled]:active,\n.btn[disabled]:active,\n.btn-default[disabled]:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] button:active,\nfieldset[disabled] .btn:active,\nfieldset[disabled] .btn-default:active,\nfieldset[disabled] .btn-primary:active,\nbutton.disabled.active,\n.btn.disabled.active,\n.btn-default.disabled.active,\n.btn-primary.disabled.active,\nbutton[disabled].active,\n.btn[disabled].active,\n.btn-default[disabled].active,\n.btn-primary[disabled].active,\nfieldset[disabled] button.active,\nfieldset[disabled] .btn.active,\nfieldset[disabled] .btn-default.active,\nfieldset[disabled] .btn-primary.active {\n opacity: 0.4;\n cursor: auto;\n background-color: #4A90E2;\n}\n.layout-small button,\n.layout-small .btn,\n.layout-small .btn-default,\n.layout-small .btn-primary {\n padding: 5px 10px;\n}\n.layout-large button,\n.layout-large .btn,\n.layout-large .btn-default,\n.layout-large .btn-primary {\n padding: 8px 24px;\n}\na.btn-link {\n display: inline-block;\n border: solid 1px transparent;\n border-radius: 3px;\n text-align: center;\n text-decoration: none;\n background-color: transparent;\n color: #4A90E2;\n cursor: pointer;\n text-align: left;\n}\na.btn-link:hover,\na.btn-link.hover {\n color: #4A90E2;\n background-color: rgba(74, 144, 226, 0.08);\n text-decoration: none;\n}\na.btn-link:focus,\na.btn-link.focus {\n outline: 0;\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\na.btn-link:active,\na.btn-link.active {\n background-color: rgba(74, 144, 226, 0.18);\n}\na.btn-link.disabled,\na.btn-link[disabled],\nfieldset[disabled] a.btn-link,\na.btn-link.disabled:hover,\na.btn-link[disabled]:hover,\nfieldset[disabled] a.btn-link:hover,\na.btn-link.disabled:focus,\na.btn-link[disabled]:focus,\nfieldset[disabled] a.btn-link:focus,\na.btn-link.disabled.focus,\na.btn-link[disabled].focus,\nfieldset[disabled] a.btn-link.focus,\na.btn-link.disabled:active,\na.btn-link[disabled]:active,\nfieldset[disabled] a.btn-link:active,\na.btn-link.disabled.active,\na.btn-link[disabled].active,\nfieldset[disabled] a.btn-link.active {\n opacity: 0.4;\n cursor: auto;\n background-color: transparent;\n}\n.btn-secondary {\n display: inline-block;\n border: solid 1px rgba(74, 144, 226, 0.5);\n border-radius: 3px;\n text-align: center;\n text-decoration: none;\n background-color: transparent;\n color: #4A90E2;\n cursor: pointer;\n}\n.btn-secondary:hover,\n.btn-secondary.hover {\n color: #4A90E2;\n background-color: rgba(74, 144, 226, 0.08);\n text-decoration: none;\n}\n.btn-secondary:focus,\n.btn-secondary.focus {\n outline: 0;\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\n.btn-secondary:active,\n.btn-secondary.active {\n background-color: rgba(74, 144, 226, 0.18);\n}\n.btn-secondary.disabled,\n.btn-secondary[disabled],\nfieldset[disabled] .btn-secondary,\n.btn-secondary.disabled:hover,\n.btn-secondary[disabled]:hover,\nfieldset[disabled] .btn-secondary:hover,\n.btn-secondary.disabled:focus,\n.btn-secondary[disabled]:focus,\nfieldset[disabled] .btn-secondary:focus,\n.btn-secondary.disabled.focus,\n.btn-secondary[disabled].focus,\nfieldset[disabled] .btn-secondary.focus,\n.btn-secondary.disabled:active,\n.btn-secondary[disabled]:active,\nfieldset[disabled] .btn-secondary:active,\n.btn-secondary.disabled.active,\n.btn-secondary[disabled].active,\nfieldset[disabled] .btn-secondary.active {\n opacity: 0.4;\n cursor: auto;\n background-color: transparent;\n}\n.btn-danger {\n display: inline-block;\n border: solid 1px #d54c53;\n border-radius: 3px;\n text-align: center;\n text-decoration: none;\n background-color: #d54c53;\n color: #fff;\n cursor: pointer;\n}\n.btn-danger:hover,\n.btn-danger.hover {\n color: #fff;\n background-color: #d54c53;\n text-decoration: none;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n outline: 0;\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #d54c53;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n opacity: 0.4;\n cursor: auto;\n background-color: #d54c53;\n}\n.btn-secondary.btn-danger {\n display: inline-block;\n border: solid 1px rgba(213, 76, 83, 0.5);\n border-radius: 3px;\n text-align: center;\n text-decoration: none;\n background-color: transparent;\n color: #d54c53;\n cursor: pointer;\n}\n.btn-secondary.btn-danger:hover,\n.btn-secondary.btn-danger.hover {\n color: #d54c53;\n background-color: rgba(213, 76, 83, 0.08);\n text-decoration: none;\n}\n.btn-secondary.btn-danger:focus,\n.btn-secondary.btn-danger.focus {\n outline: 0;\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\n.btn-secondary.btn-danger:active,\n.btn-secondary.btn-danger.active {\n background-color: rgba(213, 76, 83, 0.18);\n}\n.btn-secondary.btn-danger.disabled,\n.btn-secondary.btn-danger[disabled],\nfieldset[disabled] .btn-secondary.btn-danger,\n.btn-secondary.btn-danger.disabled:hover,\n.btn-secondary.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-secondary.btn-danger:hover,\n.btn-secondary.btn-danger.disabled:focus,\n.btn-secondary.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-secondary.btn-danger:focus,\n.btn-secondary.btn-danger.disabled.focus,\n.btn-secondary.btn-danger[disabled].focus,\nfieldset[disabled] .btn-secondary.btn-danger.focus,\n.btn-secondary.btn-danger.disabled:active,\n.btn-secondary.btn-danger[disabled]:active,\nfieldset[disabled] .btn-secondary.btn-danger:active,\n.btn-secondary.btn-danger.disabled.active,\n.btn-secondary.btn-danger[disabled].active,\nfieldset[disabled] .btn-secondary.btn-danger.active {\n opacity: 0.4;\n cursor: auto;\n background-color: transparent;\n}\nbutton.inverse,\n.btn.inverse,\n.btn-default.inverse,\n.btn-primary.inverse,\n.btn-secondary.inverse,\n.btn-danger.inverse,\na.btn-link.inverse,\n.inverse button,\n.inverse .btn,\n.inverse .btn-default,\n.inverse .btn-primary,\n.inverse .btn-secondary,\n.inverse .btn-danger,\n.inverse a.btn-link,\n.inverse-background button,\n.inverse-background .btn,\n.inverse-background .btn-default,\n.inverse-background .btn-primary,\n.inverse-background .btn-secondary,\n.inverse-background .btn-danger,\n.inverse-background a.btn-link {\n display: inline-block;\n border: solid 1px #fff;\n border-radius: 3px;\n text-align: center;\n text-decoration: none;\n background-color: transparent;\n color: #fff;\n cursor: pointer;\n}\nbutton.inverse:hover,\n.btn.inverse:hover,\n.btn-default.inverse:hover,\n.btn-primary.inverse:hover,\n.btn-secondary.inverse:hover,\n.btn-danger.inverse:hover,\na.btn-link.inverse:hover,\n.inverse button:hover,\n.inverse .btn:hover,\n.inverse .btn-default:hover,\n.inverse .btn-primary:hover,\n.inverse .btn-secondary:hover,\n.inverse .btn-danger:hover,\n.inverse a.btn-link:hover,\n.inverse-background button:hover,\n.inverse-background .btn:hover,\n.inverse-background .btn-default:hover,\n.inverse-background .btn-primary:hover,\n.inverse-background .btn-secondary:hover,\n.inverse-background .btn-danger:hover,\n.inverse-background a.btn-link:hover,\nbutton.inverse.hover,\n.btn.inverse.hover,\n.btn-default.inverse.hover,\n.btn-primary.inverse.hover,\n.btn-secondary.inverse.hover,\n.btn-danger.inverse.hover,\na.btn-link.inverse.hover,\n.inverse button.hover,\n.inverse .btn.hover,\n.inverse .btn-default.hover,\n.inverse .btn-primary.hover,\n.inverse .btn-secondary.hover,\n.inverse .btn-danger.hover,\n.inverse a.btn-link.hover,\n.inverse-background button.hover,\n.inverse-background .btn.hover,\n.inverse-background .btn-default.hover,\n.inverse-background .btn-primary.hover,\n.inverse-background .btn-secondary.hover,\n.inverse-background .btn-danger.hover,\n.inverse-background a.btn-link.hover {\n color: #fff;\n background-color: rgba(255, 255, 255, 0.1);\n text-decoration: none;\n}\nbutton.inverse:focus,\n.btn.inverse:focus,\n.btn-default.inverse:focus,\n.btn-primary.inverse:focus,\n.btn-secondary.inverse:focus,\n.btn-danger.inverse:focus,\na.btn-link.inverse:focus,\n.inverse button:focus,\n.inverse .btn:focus,\n.inverse .btn-default:focus,\n.inverse .btn-primary:focus,\n.inverse .btn-secondary:focus,\n.inverse .btn-danger:focus,\n.inverse a.btn-link:focus,\n.inverse-background button:focus,\n.inverse-background .btn:focus,\n.inverse-background .btn-default:focus,\n.inverse-background .btn-primary:focus,\n.inverse-background .btn-secondary:focus,\n.inverse-background .btn-danger:focus,\n.inverse-background a.btn-link:focus,\nbutton.inverse.focus,\n.btn.inverse.focus,\n.btn-default.inverse.focus,\n.btn-primary.inverse.focus,\n.btn-secondary.inverse.focus,\n.btn-danger.inverse.focus,\na.btn-link.inverse.focus,\n.inverse button.focus,\n.inverse .btn.focus,\n.inverse .btn-default.focus,\n.inverse .btn-primary.focus,\n.inverse .btn-secondary.focus,\n.inverse .btn-danger.focus,\n.inverse a.btn-link.focus,\n.inverse-background button.focus,\n.inverse-background .btn.focus,\n.inverse-background .btn-default.focus,\n.inverse-background .btn-primary.focus,\n.inverse-background .btn-secondary.focus,\n.inverse-background .btn-danger.focus,\n.inverse-background a.btn-link.focus {\n outline: 0;\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\nbutton.inverse:active,\n.btn.inverse:active,\n.btn-default.inverse:active,\n.btn-primary.inverse:active,\n.btn-secondary.inverse:active,\n.btn-danger.inverse:active,\na.btn-link.inverse:active,\n.inverse button:active,\n.inverse .btn:active,\n.inverse .btn-default:active,\n.inverse .btn-primary:active,\n.inverse .btn-secondary:active,\n.inverse .btn-danger:active,\n.inverse a.btn-link:active,\n.inverse-background button:active,\n.inverse-background .btn:active,\n.inverse-background .btn-default:active,\n.inverse-background .btn-primary:active,\n.inverse-background .btn-secondary:active,\n.inverse-background .btn-danger:active,\n.inverse-background a.btn-link:active,\nbutton.inverse.active,\n.btn.inverse.active,\n.btn-default.inverse.active,\n.btn-primary.inverse.active,\n.btn-secondary.inverse.active,\n.btn-danger.inverse.active,\na.btn-link.inverse.active,\n.inverse button.active,\n.inverse .btn.active,\n.inverse .btn-default.active,\n.inverse .btn-primary.active,\n.inverse .btn-secondary.active,\n.inverse .btn-danger.active,\n.inverse a.btn-link.active,\n.inverse-background button.active,\n.inverse-background .btn.active,\n.inverse-background .btn-default.active,\n.inverse-background .btn-primary.active,\n.inverse-background .btn-secondary.active,\n.inverse-background .btn-danger.active,\n.inverse-background a.btn-link.active {\n background-color: rgba(255, 255, 255, 0.2);\n}\nbutton.inverse.disabled,\n.btn.inverse.disabled,\n.btn-default.inverse.disabled,\n.btn-primary.inverse.disabled,\n.btn-secondary.inverse.disabled,\n.btn-danger.inverse.disabled,\na.btn-link.inverse.disabled,\n.inverse button.disabled,\n.inverse .btn.disabled,\n.inverse .btn-default.disabled,\n.inverse .btn-primary.disabled,\n.inverse .btn-secondary.disabled,\n.inverse .btn-danger.disabled,\n.inverse a.btn-link.disabled,\n.inverse-background button.disabled,\n.inverse-background .btn.disabled,\n.inverse-background .btn-default.disabled,\n.inverse-background .btn-primary.disabled,\n.inverse-background .btn-secondary.disabled,\n.inverse-background .btn-danger.disabled,\n.inverse-background a.btn-link.disabled,\nbutton.inverse[disabled],\n.btn.inverse[disabled],\n.btn-default.inverse[disabled],\n.btn-primary.inverse[disabled],\n.btn-secondary.inverse[disabled],\n.btn-danger.inverse[disabled],\na.btn-link.inverse[disabled],\n.inverse button[disabled],\n.inverse .btn[disabled],\n.inverse .btn-default[disabled],\n.inverse .btn-primary[disabled],\n.inverse .btn-secondary[disabled],\n.inverse .btn-danger[disabled],\n.inverse a.btn-link[disabled],\n.inverse-background button[disabled],\n.inverse-background .btn[disabled],\n.inverse-background .btn-default[disabled],\n.inverse-background .btn-primary[disabled],\n.inverse-background .btn-secondary[disabled],\n.inverse-background .btn-danger[disabled],\n.inverse-background a.btn-link[disabled],\nfieldset[disabled] button.inverse,\nfieldset[disabled] .btn.inverse,\nfieldset[disabled] .btn-default.inverse,\nfieldset[disabled] .btn-primary.inverse,\nfieldset[disabled] .btn-secondary.inverse,\nfieldset[disabled] .btn-danger.inverse,\nfieldset[disabled] a.btn-link.inverse,\nfieldset[disabled] .inverse button,\nfieldset[disabled] .inverse .btn,\nfieldset[disabled] .inverse .btn-default,\nfieldset[disabled] .inverse .btn-primary,\nfieldset[disabled] .inverse .btn-secondary,\nfieldset[disabled] .inverse .btn-danger,\nfieldset[disabled] .inverse a.btn-link,\nfieldset[disabled] .inverse-background button,\nfieldset[disabled] .inverse-background .btn,\nfieldset[disabled] .inverse-background .btn-default,\nfieldset[disabled] .inverse-background .btn-primary,\nfieldset[disabled] .inverse-background .btn-secondary,\nfieldset[disabled] .inverse-background .btn-danger,\nfieldset[disabled] .inverse-background a.btn-link,\nbutton.inverse.disabled:hover,\n.btn.inverse.disabled:hover,\n.btn-default.inverse.disabled:hover,\n.btn-primary.inverse.disabled:hover,\n.btn-secondary.inverse.disabled:hover,\n.btn-danger.inverse.disabled:hover,\na.btn-link.inverse.disabled:hover,\n.inverse button.disabled:hover,\n.inverse .btn.disabled:hover,\n.inverse .btn-default.disabled:hover,\n.inverse .btn-primary.disabled:hover,\n.inverse .btn-secondary.disabled:hover,\n.inverse .btn-danger.disabled:hover,\n.inverse a.btn-link.disabled:hover,\n.inverse-background button.disabled:hover,\n.inverse-background .btn.disabled:hover,\n.inverse-background .btn-default.disabled:hover,\n.inverse-background .btn-primary.disabled:hover,\n.inverse-background .btn-secondary.disabled:hover,\n.inverse-background .btn-danger.disabled:hover,\n.inverse-background a.btn-link.disabled:hover,\nbutton.inverse[disabled]:hover,\n.btn.inverse[disabled]:hover,\n.btn-default.inverse[disabled]:hover,\n.btn-primary.inverse[disabled]:hover,\n.btn-secondary.inverse[disabled]:hover,\n.btn-danger.inverse[disabled]:hover,\na.btn-link.inverse[disabled]:hover,\n.inverse button[disabled]:hover,\n.inverse .btn[disabled]:hover,\n.inverse .btn-default[disabled]:hover,\n.inverse .btn-primary[disabled]:hover,\n.inverse .btn-secondary[disabled]:hover,\n.inverse .btn-danger[disabled]:hover,\n.inverse a.btn-link[disabled]:hover,\n.inverse-background button[disabled]:hover,\n.inverse-background .btn[disabled]:hover,\n.inverse-background .btn-default[disabled]:hover,\n.inverse-background .btn-primary[disabled]:hover,\n.inverse-background .btn-secondary[disabled]:hover,\n.inverse-background .btn-danger[disabled]:hover,\n.inverse-background a.btn-link[disabled]:hover,\nfieldset[disabled] button.inverse:hover,\nfieldset[disabled] .btn.inverse:hover,\nfieldset[disabled] .btn-default.inverse:hover,\nfieldset[disabled] .btn-primary.inverse:hover,\nfieldset[disabled] .btn-secondary.inverse:hover,\nfieldset[disabled] .btn-danger.inverse:hover,\nfieldset[disabled] a.btn-link.inverse:hover,\nfieldset[disabled] .inverse button:hover,\nfieldset[disabled] .inverse .btn:hover,\nfieldset[disabled] .inverse .btn-default:hover,\nfieldset[disabled] .inverse .btn-primary:hover,\nfieldset[disabled] .inverse .btn-secondary:hover,\nfieldset[disabled] .inverse .btn-danger:hover,\nfieldset[disabled] .inverse a.btn-link:hover,\nfieldset[disabled] .inverse-background button:hover,\nfieldset[disabled] .inverse-background .btn:hover,\nfieldset[disabled] .inverse-background .btn-default:hover,\nfieldset[disabled] .inverse-background .btn-primary:hover,\nfieldset[disabled] .inverse-background .btn-secondary:hover,\nfieldset[disabled] .inverse-background .btn-danger:hover,\nfieldset[disabled] .inverse-background a.btn-link:hover,\nbutton.inverse.disabled:focus,\n.btn.inverse.disabled:focus,\n.btn-default.inverse.disabled:focus,\n.btn-primary.inverse.disabled:focus,\n.btn-secondary.inverse.disabled:focus,\n.btn-danger.inverse.disabled:focus,\na.btn-link.inverse.disabled:focus,\n.inverse button.disabled:focus,\n.inverse .btn.disabled:focus,\n.inverse .btn-default.disabled:focus,\n.inverse .btn-primary.disabled:focus,\n.inverse .btn-secondary.disabled:focus,\n.inverse .btn-danger.disabled:focus,\n.inverse a.btn-link.disabled:focus,\n.inverse-background button.disabled:focus,\n.inverse-background .btn.disabled:focus,\n.inverse-background .btn-default.disabled:focus,\n.inverse-background .btn-primary.disabled:focus,\n.inverse-background .btn-secondary.disabled:focus,\n.inverse-background .btn-danger.disabled:focus,\n.inverse-background a.btn-link.disabled:focus,\nbutton.inverse[disabled]:focus,\n.btn.inverse[disabled]:focus,\n.btn-default.inverse[disabled]:focus,\n.btn-primary.inverse[disabled]:focus,\n.btn-secondary.inverse[disabled]:focus,\n.btn-danger.inverse[disabled]:focus,\na.btn-link.inverse[disabled]:focus,\n.inverse button[disabled]:focus,\n.inverse .btn[disabled]:focus,\n.inverse .btn-default[disabled]:focus,\n.inverse .btn-primary[disabled]:focus,\n.inverse .btn-secondary[disabled]:focus,\n.inverse .btn-danger[disabled]:focus,\n.inverse a.btn-link[disabled]:focus,\n.inverse-background button[disabled]:focus,\n.inverse-background .btn[disabled]:focus,\n.inverse-background .btn-default[disabled]:focus,\n.inverse-background .btn-primary[disabled]:focus,\n.inverse-background .btn-secondary[disabled]:focus,\n.inverse-background .btn-danger[disabled]:focus,\n.inverse-background a.btn-link[disabled]:focus,\nfieldset[disabled] button.inverse:focus,\nfieldset[disabled] .btn.inverse:focus,\nfieldset[disabled] .btn-default.inverse:focus,\nfieldset[disabled] .btn-primary.inverse:focus,\nfieldset[disabled] .btn-secondary.inverse:focus,\nfieldset[disabled] .btn-danger.inverse:focus,\nfieldset[disabled] a.btn-link.inverse:focus,\nfieldset[disabled] .inverse button:focus,\nfieldset[disabled] .inverse .btn:focus,\nfieldset[disabled] .inverse .btn-default:focus,\nfieldset[disabled] .inverse .btn-primary:focus,\nfieldset[disabled] .inverse .btn-secondary:focus,\nfieldset[disabled] .inverse .btn-danger:focus,\nfieldset[disabled] .inverse a.btn-link:focus,\nfieldset[disabled] .inverse-background button:focus,\nfieldset[disabled] .inverse-background .btn:focus,\nfieldset[disabled] .inverse-background .btn-default:focus,\nfieldset[disabled] .inverse-background .btn-primary:focus,\nfieldset[disabled] .inverse-background .btn-secondary:focus,\nfieldset[disabled] .inverse-background .btn-danger:focus,\nfieldset[disabled] .inverse-background a.btn-link:focus,\nbutton.inverse.disabled.focus,\n.btn.inverse.disabled.focus,\n.btn-default.inverse.disabled.focus,\n.btn-primary.inverse.disabled.focus,\n.btn-secondary.inverse.disabled.focus,\n.btn-danger.inverse.disabled.focus,\na.btn-link.inverse.disabled.focus,\n.inverse button.disabled.focus,\n.inverse .btn.disabled.focus,\n.inverse .btn-default.disabled.focus,\n.inverse .btn-primary.disabled.focus,\n.inverse .btn-secondary.disabled.focus,\n.inverse .btn-danger.disabled.focus,\n.inverse a.btn-link.disabled.focus,\n.inverse-background button.disabled.focus,\n.inverse-background .btn.disabled.focus,\n.inverse-background .btn-default.disabled.focus,\n.inverse-background .btn-primary.disabled.focus,\n.inverse-background .btn-secondary.disabled.focus,\n.inverse-background .btn-danger.disabled.focus,\n.inverse-background a.btn-link.disabled.focus,\nbutton.inverse[disabled].focus,\n.btn.inverse[disabled].focus,\n.btn-default.inverse[disabled].focus,\n.btn-primary.inverse[disabled].focus,\n.btn-secondary.inverse[disabled].focus,\n.btn-danger.inverse[disabled].focus,\na.btn-link.inverse[disabled].focus,\n.inverse button[disabled].focus,\n.inverse .btn[disabled].focus,\n.inverse .btn-default[disabled].focus,\n.inverse .btn-primary[disabled].focus,\n.inverse .btn-secondary[disabled].focus,\n.inverse .btn-danger[disabled].focus,\n.inverse a.btn-link[disabled].focus,\n.inverse-background button[disabled].focus,\n.inverse-background .btn[disabled].focus,\n.inverse-background .btn-default[disabled].focus,\n.inverse-background .btn-primary[disabled].focus,\n.inverse-background .btn-secondary[disabled].focus,\n.inverse-background .btn-danger[disabled].focus,\n.inverse-background a.btn-link[disabled].focus,\nfieldset[disabled] button.inverse.focus,\nfieldset[disabled] .btn.inverse.focus,\nfieldset[disabled] .btn-default.inverse.focus,\nfieldset[disabled] .btn-primary.inverse.focus,\nfieldset[disabled] .btn-secondary.inverse.focus,\nfieldset[disabled] .btn-danger.inverse.focus,\nfieldset[disabled] a.btn-link.inverse.focus,\nfieldset[disabled] .inverse button.focus,\nfieldset[disabled] .inverse .btn.focus,\nfieldset[disabled] .inverse .btn-default.focus,\nfieldset[disabled] .inverse .btn-primary.focus,\nfieldset[disabled] .inverse .btn-secondary.focus,\nfieldset[disabled] .inverse .btn-danger.focus,\nfieldset[disabled] .inverse a.btn-link.focus,\nfieldset[disabled] .inverse-background button.focus,\nfieldset[disabled] .inverse-background .btn.focus,\nfieldset[disabled] .inverse-background .btn-default.focus,\nfieldset[disabled] .inverse-background .btn-primary.focus,\nfieldset[disabled] .inverse-background .btn-secondary.focus,\nfieldset[disabled] .inverse-background .btn-danger.focus,\nfieldset[disabled] .inverse-background a.btn-link.focus,\nbutton.inverse.disabled:active,\n.btn.inverse.disabled:active,\n.btn-default.inverse.disabled:active,\n.btn-primary.inverse.disabled:active,\n.btn-secondary.inverse.disabled:active,\n.btn-danger.inverse.disabled:active,\na.btn-link.inverse.disabled:active,\n.inverse button.disabled:active,\n.inverse .btn.disabled:active,\n.inverse .btn-default.disabled:active,\n.inverse .btn-primary.disabled:active,\n.inverse .btn-secondary.disabled:active,\n.inverse .btn-danger.disabled:active,\n.inverse a.btn-link.disabled:active,\n.inverse-background button.disabled:active,\n.inverse-background .btn.disabled:active,\n.inverse-background .btn-default.disabled:active,\n.inverse-background .btn-primary.disabled:active,\n.inverse-background .btn-secondary.disabled:active,\n.inverse-background .btn-danger.disabled:active,\n.inverse-background a.btn-link.disabled:active,\nbutton.inverse[disabled]:active,\n.btn.inverse[disabled]:active,\n.btn-default.inverse[disabled]:active,\n.btn-primary.inverse[disabled]:active,\n.btn-secondary.inverse[disabled]:active,\n.btn-danger.inverse[disabled]:active,\na.btn-link.inverse[disabled]:active,\n.inverse button[disabled]:active,\n.inverse .btn[disabled]:active,\n.inverse .btn-default[disabled]:active,\n.inverse .btn-primary[disabled]:active,\n.inverse .btn-secondary[disabled]:active,\n.inverse .btn-danger[disabled]:active,\n.inverse a.btn-link[disabled]:active,\n.inverse-background button[disabled]:active,\n.inverse-background .btn[disabled]:active,\n.inverse-background .btn-default[disabled]:active,\n.inverse-background .btn-primary[disabled]:active,\n.inverse-background .btn-secondary[disabled]:active,\n.inverse-background .btn-danger[disabled]:active,\n.inverse-background a.btn-link[disabled]:active,\nfieldset[disabled] button.inverse:active,\nfieldset[disabled] .btn.inverse:active,\nfieldset[disabled] .btn-default.inverse:active,\nfieldset[disabled] .btn-primary.inverse:active,\nfieldset[disabled] .btn-secondary.inverse:active,\nfieldset[disabled] .btn-danger.inverse:active,\nfieldset[disabled] a.btn-link.inverse:active,\nfieldset[disabled] .inverse button:active,\nfieldset[disabled] .inverse .btn:active,\nfieldset[disabled] .inverse .btn-default:active,\nfieldset[disabled] .inverse .btn-primary:active,\nfieldset[disabled] .inverse .btn-secondary:active,\nfieldset[disabled] .inverse .btn-danger:active,\nfieldset[disabled] .inverse a.btn-link:active,\nfieldset[disabled] .inverse-background button:active,\nfieldset[disabled] .inverse-background .btn:active,\nfieldset[disabled] .inverse-background .btn-default:active,\nfieldset[disabled] .inverse-background .btn-primary:active,\nfieldset[disabled] .inverse-background .btn-secondary:active,\nfieldset[disabled] .inverse-background .btn-danger:active,\nfieldset[disabled] .inverse-background a.btn-link:active,\nbutton.inverse.disabled.active,\n.btn.inverse.disabled.active,\n.btn-default.inverse.disabled.active,\n.btn-primary.inverse.disabled.active,\n.btn-secondary.inverse.disabled.active,\n.btn-danger.inverse.disabled.active,\na.btn-link.inverse.disabled.active,\n.inverse button.disabled.active,\n.inverse .btn.disabled.active,\n.inverse .btn-default.disabled.active,\n.inverse .btn-primary.disabled.active,\n.inverse .btn-secondary.disabled.active,\n.inverse .btn-danger.disabled.active,\n.inverse a.btn-link.disabled.active,\n.inverse-background button.disabled.active,\n.inverse-background .btn.disabled.active,\n.inverse-background .btn-default.disabled.active,\n.inverse-background .btn-primary.disabled.active,\n.inverse-background .btn-secondary.disabled.active,\n.inverse-background .btn-danger.disabled.active,\n.inverse-background a.btn-link.disabled.active,\nbutton.inverse[disabled].active,\n.btn.inverse[disabled].active,\n.btn-default.inverse[disabled].active,\n.btn-primary.inverse[disabled].active,\n.btn-secondary.inverse[disabled].active,\n.btn-danger.inverse[disabled].active,\na.btn-link.inverse[disabled].active,\n.inverse button[disabled].active,\n.inverse .btn[disabled].active,\n.inverse .btn-default[disabled].active,\n.inverse .btn-primary[disabled].active,\n.inverse .btn-secondary[disabled].active,\n.inverse .btn-danger[disabled].active,\n.inverse a.btn-link[disabled].active,\n.inverse-background button[disabled].active,\n.inverse-background .btn[disabled].active,\n.inverse-background .btn-default[disabled].active,\n.inverse-background .btn-primary[disabled].active,\n.inverse-background .btn-secondary[disabled].active,\n.inverse-background .btn-danger[disabled].active,\n.inverse-background a.btn-link[disabled].active,\nfieldset[disabled] button.inverse.active,\nfieldset[disabled] .btn.inverse.active,\nfieldset[disabled] .btn-default.inverse.active,\nfieldset[disabled] .btn-primary.inverse.active,\nfieldset[disabled] .btn-secondary.inverse.active,\nfieldset[disabled] .btn-danger.inverse.active,\nfieldset[disabled] a.btn-link.inverse.active,\nfieldset[disabled] .inverse button.active,\nfieldset[disabled] .inverse .btn.active,\nfieldset[disabled] .inverse .btn-default.active,\nfieldset[disabled] .inverse .btn-primary.active,\nfieldset[disabled] .inverse .btn-secondary.active,\nfieldset[disabled] .inverse .btn-danger.active,\nfieldset[disabled] .inverse a.btn-link.active,\nfieldset[disabled] .inverse-background button.active,\nfieldset[disabled] .inverse-background .btn.active,\nfieldset[disabled] .inverse-background .btn-default.active,\nfieldset[disabled] .inverse-background .btn-primary.active,\nfieldset[disabled] .inverse-background .btn-secondary.active,\nfieldset[disabled] .inverse-background .btn-danger.active,\nfieldset[disabled] .inverse-background a.btn-link.active {\n opacity: 0.4;\n cursor: auto;\n background-color: transparent;\n}\nbutton.inverse:focus,\n.btn.inverse:focus,\n.btn-default.inverse:focus,\n.btn-primary.inverse:focus,\n.btn-secondary.inverse:focus,\n.btn-danger.inverse:focus,\na.btn-link.inverse:focus,\n.inverse button:focus,\n.inverse .btn:focus,\n.inverse .btn-default:focus,\n.inverse .btn-primary:focus,\n.inverse .btn-secondary:focus,\n.inverse .btn-danger:focus,\n.inverse a.btn-link:focus,\n.inverse-background button:focus,\n.inverse-background .btn:focus,\n.inverse-background .btn-default:focus,\n.inverse-background .btn-primary:focus,\n.inverse-background .btn-secondary:focus,\n.inverse-background .btn-danger:focus,\n.inverse-background a.btn-link:focus,\nbutton.inverse.focus,\n.btn.inverse.focus,\n.btn-default.inverse.focus,\n.btn-primary.inverse.focus,\n.btn-secondary.inverse.focus,\n.btn-danger.inverse.focus,\na.btn-link.inverse.focus,\n.inverse button.focus,\n.inverse .btn.focus,\n.inverse .btn-default.focus,\n.inverse .btn-primary.focus,\n.inverse .btn-secondary.focus,\n.inverse .btn-danger.focus,\n.inverse a.btn-link.focus,\n.inverse-background button.focus,\n.inverse-background .btn.focus,\n.inverse-background .btn-default.focus,\n.inverse-background .btn-primary.focus,\n.inverse-background .btn-secondary.focus,\n.inverse-background .btn-danger.focus,\n.inverse-background a.btn-link.focus {\n outline: 0;\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n box-shadow: inset 0 0 1px 3px rgba(255, 255, 255, 0.4);\n}\nbutton.monochrome,\n.btn.monochrome,\n.btn-default.monochrome,\n.btn-primary.monochrome,\n.btn-secondary.monochrome {\n display: inline-block;\n border: solid 1px #777777;\n border-radius: 3px;\n text-align: center;\n text-decoration: none;\n background-color: transparent;\n color: #4A4A4A;\n cursor: pointer;\n}\nbutton.monochrome:hover,\n.btn.monochrome:hover,\n.btn-default.monochrome:hover,\n.btn-primary.monochrome:hover,\n.btn-secondary.monochrome:hover,\nbutton.monochrome.hover,\n.btn.monochrome.hover,\n.btn-default.monochrome.hover,\n.btn-primary.monochrome.hover,\n.btn-secondary.monochrome.hover {\n color: #4A4A4A;\n background-color: #e4e4e4;\n text-decoration: none;\n}\nbutton.monochrome:focus,\n.btn.monochrome:focus,\n.btn-default.monochrome:focus,\n.btn-primary.monochrome:focus,\n.btn-secondary.monochrome:focus,\nbutton.monochrome.focus,\n.btn.monochrome.focus,\n.btn-default.monochrome.focus,\n.btn-primary.monochrome.focus,\n.btn-secondary.monochrome.focus {\n outline: 0;\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\nbutton.monochrome:active,\n.btn.monochrome:active,\n.btn-default.monochrome:active,\n.btn-primary.monochrome:active,\n.btn-secondary.monochrome:active,\nbutton.monochrome.active,\n.btn.monochrome.active,\n.btn-default.monochrome.active,\n.btn-primary.monochrome.active,\n.btn-secondary.monochrome.active {\n background-color: #e4e4e4;\n}\nbutton.monochrome.disabled,\n.btn.monochrome.disabled,\n.btn-default.monochrome.disabled,\n.btn-primary.monochrome.disabled,\n.btn-secondary.monochrome.disabled,\nbutton.monochrome[disabled],\n.btn.monochrome[disabled],\n.btn-default.monochrome[disabled],\n.btn-primary.monochrome[disabled],\n.btn-secondary.monochrome[disabled],\nfieldset[disabled] button.monochrome,\nfieldset[disabled] .btn.monochrome,\nfieldset[disabled] .btn-default.monochrome,\nfieldset[disabled] .btn-primary.monochrome,\nfieldset[disabled] .btn-secondary.monochrome,\nbutton.monochrome.disabled:hover,\n.btn.monochrome.disabled:hover,\n.btn-default.monochrome.disabled:hover,\n.btn-primary.monochrome.disabled:hover,\n.btn-secondary.monochrome.disabled:hover,\nbutton.monochrome[disabled]:hover,\n.btn.monochrome[disabled]:hover,\n.btn-default.monochrome[disabled]:hover,\n.btn-primary.monochrome[disabled]:hover,\n.btn-secondary.monochrome[disabled]:hover,\nfieldset[disabled] button.monochrome:hover,\nfieldset[disabled] .btn.monochrome:hover,\nfieldset[disabled] .btn-default.monochrome:hover,\nfieldset[disabled] .btn-primary.monochrome:hover,\nfieldset[disabled] .btn-secondary.monochrome:hover,\nbutton.monochrome.disabled:focus,\n.btn.monochrome.disabled:focus,\n.btn-default.monochrome.disabled:focus,\n.btn-primary.monochrome.disabled:focus,\n.btn-secondary.monochrome.disabled:focus,\nbutton.monochrome[disabled]:focus,\n.btn.monochrome[disabled]:focus,\n.btn-default.monochrome[disabled]:focus,\n.btn-primary.monochrome[disabled]:focus,\n.btn-secondary.monochrome[disabled]:focus,\nfieldset[disabled] button.monochrome:focus,\nfieldset[disabled] .btn.monochrome:focus,\nfieldset[disabled] .btn-default.monochrome:focus,\nfieldset[disabled] .btn-primary.monochrome:focus,\nfieldset[disabled] .btn-secondary.monochrome:focus,\nbutton.monochrome.disabled.focus,\n.btn.monochrome.disabled.focus,\n.btn-default.monochrome.disabled.focus,\n.btn-primary.monochrome.disabled.focus,\n.btn-secondary.monochrome.disabled.focus,\nbutton.monochrome[disabled].focus,\n.btn.monochrome[disabled].focus,\n.btn-default.monochrome[disabled].focus,\n.btn-primary.monochrome[disabled].focus,\n.btn-secondary.monochrome[disabled].focus,\nfieldset[disabled] button.monochrome.focus,\nfieldset[disabled] .btn.monochrome.focus,\nfieldset[disabled] .btn-default.monochrome.focus,\nfieldset[disabled] .btn-primary.monochrome.focus,\nfieldset[disabled] .btn-secondary.monochrome.focus,\nbutton.monochrome.disabled:active,\n.btn.monochrome.disabled:active,\n.btn-default.monochrome.disabled:active,\n.btn-primary.monochrome.disabled:active,\n.btn-secondary.monochrome.disabled:active,\nbutton.monochrome[disabled]:active,\n.btn.monochrome[disabled]:active,\n.btn-default.monochrome[disabled]:active,\n.btn-primary.monochrome[disabled]:active,\n.btn-secondary.monochrome[disabled]:active,\nfieldset[disabled] button.monochrome:active,\nfieldset[disabled] .btn.monochrome:active,\nfieldset[disabled] .btn-default.monochrome:active,\nfieldset[disabled] .btn-primary.monochrome:active,\nfieldset[disabled] .btn-secondary.monochrome:active,\nbutton.monochrome.disabled.active,\n.btn.monochrome.disabled.active,\n.btn-default.monochrome.disabled.active,\n.btn-primary.monochrome.disabled.active,\n.btn-secondary.monochrome.disabled.active,\nbutton.monochrome[disabled].active,\n.btn.monochrome[disabled].active,\n.btn-default.monochrome[disabled].active,\n.btn-primary.monochrome[disabled].active,\n.btn-secondary.monochrome[disabled].active,\nfieldset[disabled] button.monochrome.active,\nfieldset[disabled] .btn.monochrome.active,\nfieldset[disabled] .btn-default.monochrome.active,\nfieldset[disabled] .btn-primary.monochrome.active,\nfieldset[disabled] .btn-secondary.monochrome.active {\n opacity: 0.4;\n cursor: auto;\n background-color: transparent;\n}\nbutton,\n.btn,\n.btn-default,\n.btn-primary,\n.btn-secondary,\n.btn-danger,\na.btn-link {\n padding: 6px 20px;\n}\n.layout-small button,\n.layout-small .btn,\n.layout-small .btn-default,\n.layout-small .btn-primary,\n.layout-small .btn-secondary,\n.layout-small .btn-danger,\n.layout-small a.btn-link {\n padding: 5px 10px;\n}\n.layout-large button,\n.layout-large .btn,\n.layout-large .btn-default,\n.layout-large .btn-primary,\n.layout-large .btn-secondary,\n.layout-large .btn-danger,\n.layout-large a.btn-link {\n padding: 8px 24px;\n}\n.Button-small {\n padding: 5px 10px;\n}\n.Button-medium {\n padding: 6px 20px;\n}\n.Button-large {\n padding: 8px 24px;\n}\n.Checkbox {\n display: inline-block;\n}\n.Checkbox .svg-icon {\n width: 20px;\n height: 20px;\n}\n.Checkbox .Checkbox-wrapper {\n display: flex;\n align-items: center;\n}\n.Checkbox input[type=\"checkbox\"] {\n border: 0;\n clip: rect(0, 0, 0, 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n width: 1px;\n}\n.Checkbox .Checkbox-indicator {\n display: flex;\n border: 1px solid rgba(73, 73, 73, 0.5);\n border-radius: 3px;\n cursor: pointer;\n}\n.Checkbox .Checkbox-text {\n margin-left: 5px;\n cursor: pointer;\n}\n.Checkbox .svg-icon {\n opacity: 0;\n fill: #fff;\n transition: opacity 0.1s linear;\n}\n.Checkbox input[type=\"checkbox\"]:checked + .Checkbox-indicator {\n background-color: #4A90E2;\n border-color: #4A90E2;\n}\n.Checkbox input[type=\"checkbox\"]:checked + .Checkbox-indicator .svg-icon {\n opacity: 1;\n}\n.Checkbox input[type=\"checkbox\"]:focus + .Checkbox-indicator,\n.Checkbox.focus .Checkbox-indicator {\n outline: 0;\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\n.Checkbox input[disabled] + .Checkbox-indicator,\nfieldset[disabled] .Checkbox input + .Checkbox-indicator,\n.Checkbox input[disabled] ~ .Checkbox-text,\nfieldset[disabled] .Checkbox input ~ .Checkbox-text {\n opacity: 0.4;\n cursor: auto;\n}\n@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {\n .Checkbox input[type=\"checkbox\"]:focus + .Checkbox-indicator,\n .Checkbox.focus .Checkbox-indicator {\n box-shadow: inset 0 0 1px 3px rgba(0, 0, 0, 0.2);\n }\n}\n@supports (-ms-ime-align:auto) {\n .Checkbox input[type=\"checkbox\"]:focus + .Checkbox-indicator,\n .Checkbox.focus .Checkbox-indicator {\n box-shadow: inset 0 0 1px 3px rgba(0, 0, 0, 0.2);\n }\n}\n.Checkbox-small .svg-icon {\n width: 18px;\n height: 18px;\n}\n.Checkbox-medium .svg-icon {\n width: 20px;\n height: 20px;\n}\n.Checkbox-large .svg-icon {\n width: 24px;\n height: 24px;\n}\n.layout-small .Checkbox .svg-icon {\n width: 18px;\n height: 18px;\n}\n.layout-large .Checkbox .svg-icon {\n width: 24px;\n height: 24px;\n}\n.Dropdown {\n display: inline-flex;\n width: 100%;\n align-items: center;\n}\n.Dropdown .Dropdown-button {\n width: 100%;\n padding: 5px 8px;\n padding-right: 25px;\n flex-grow: 0;\n text-align: left;\n color: #4A4A4A;\n background-color: #fff;\n font-family: \"LatoLatinWeb\", \"Lato\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n border: 1px solid rgba(73, 73, 73, 0.5);\n border-radius: 3px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.Dropdown .Dropdown-button[disabled]:hover,\nfieldset[disabled]:hover .Dropdown .Dropdown-button {\n background-color: #fff;\n}\n.Dropdown .Dropdown-thumb {\n width: 16px;\n height: 16px;\n margin-left: -25px;\n margin-right: 9px;\n flex-shrink: 0;\n cursor: pointer;\n}\n.Dropdown .Dropdown-thumb .svg-icon.keyboard_arrow_down {\n display: block;\n width: 100%;\n height: 100%;\n fill: #949494;\n}\n.Dropdown .Dropdown-menu {\n width: 100%;\n overflow-y: scroll;\n max-height: 200px;\n list-style-type: none;\n padding: 0;\n margin: 0;\n background: #fff;\n border: 1px solid rgba(73, 73, 73, 0.5);\n border-radius: 3px;\n border-color: #4A90E2;\n}\n.Dropdown .Dropdown-menu .Dropdown-menu-item {\n display: inline-block;\n width: 100%;\n height: 100%;\n padding: 5px 10px;\n cursor: pointer;\n color: #4A4A4A;\n}\n.Dropdown .Dropdown-menu .Dropdown-menu-item:hover {\n text-decoration: none;\n background: rgba(74, 144, 226, 0.15);\n}\n.Dropdown .Dropdown-menu .Dropdown-menu-item:focus {\n background: rgba(74, 144, 226, 0.15);\n outline: 0;\n}\n.Dropdown.Dropdown-menu-open .Dropdown-button {\n border-color: #4A90E2;\n}\n.empty-state {\n display: flex;\n justify-content: center;\n}\n.empty-state .empty-state-container {\n display: flex;\n justify-content: center;\n flex-grow: 1;\n min-width: 40rem;\n max-width: 80rem;\n padding: 4rem 4rem;\n margin: 4rem 4rem;\n border-radius: 2px;\n background-image: linear-gradient(90deg, #49A3E0 0%, #4AC2E2 100%);\n}\n.empty-state .empty-state-container .empty-state-icon {\n margin-right: 3rem;\n display: block;\n width: 150px;\n height: 150px;\n padding-left: 150px;\n}\n.empty-state .empty-state-container .empty-state-icon.branch {\n background: url(\"../icons/nounproject/branch.svg\") no-repeat right center;\n}\n.empty-state .empty-state-container .empty-state-icon.goat {\n background: url(\"../icons/nounproject/goat.svg\") no-repeat right center;\n}\n.empty-state .empty-state-container .empty-state-icon.shoes {\n background: url(\"../icons/nounproject/shoes.svg\") no-repeat right center;\n}\n.empty-state .empty-state-container .empty-state-content {\n color: white;\n max-width: 40rem;\n}\n.empty-state .empty-state-container .empty-state-content h1 {\n font-size: 2.4rem;\n}\n.empty-state .empty-state-container .empty-state-content button,\n.empty-state .empty-state-container .empty-state-content a {\n display: inline-block;\n border: solid 1px white;\n border-radius: 3px;\n text-align: center;\n text-decoration: none;\n background-color: white;\n color: #49A3E0;\n cursor: pointer;\n}\n.empty-state .empty-state-container .empty-state-content button:hover,\n.empty-state .empty-state-container .empty-state-content a:hover,\n.empty-state .empty-state-container .empty-state-content button.hover,\n.empty-state .empty-state-container .empty-state-content a.hover {\n color: #49A3E0;\n background-color: white;\n text-decoration: none;\n}\n.empty-state .empty-state-container .empty-state-content button:focus,\n.empty-state .empty-state-container .empty-state-content a:focus,\n.empty-state .empty-state-container .empty-state-content button.focus,\n.empty-state .empty-state-container .empty-state-content a.focus {\n outline: 0;\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\n.empty-state .empty-state-container .empty-state-content button:active,\n.empty-state .empty-state-container .empty-state-content a:active,\n.empty-state .empty-state-container .empty-state-content button.active,\n.empty-state .empty-state-container .empty-state-content a.active {\n background-color: white;\n}\n.empty-state .empty-state-container .empty-state-content button.disabled,\n.empty-state .empty-state-container .empty-state-content a.disabled,\n.empty-state .empty-state-container .empty-state-content button[disabled],\n.empty-state .empty-state-container .empty-state-content a[disabled],\nfieldset[disabled] .empty-state .empty-state-container .empty-state-content button,\nfieldset[disabled] .empty-state .empty-state-container .empty-state-content a,\n.empty-state .empty-state-container .empty-state-content button.disabled:hover,\n.empty-state .empty-state-container .empty-state-content a.disabled:hover,\n.empty-state .empty-state-container .empty-state-content button[disabled]:hover,\n.empty-state .empty-state-container .empty-state-content a[disabled]:hover,\nfieldset[disabled] .empty-state .empty-state-container .empty-state-content button:hover,\nfieldset[disabled] .empty-state .empty-state-container .empty-state-content a:hover,\n.empty-state .empty-state-container .empty-state-content button.disabled:focus,\n.empty-state .empty-state-container .empty-state-content a.disabled:focus,\n.empty-state .empty-state-container .empty-state-content button[disabled]:focus,\n.empty-state .empty-state-container .empty-state-content a[disabled]:focus,\nfieldset[disabled] .empty-state .empty-state-container .empty-state-content button:focus,\nfieldset[disabled] .empty-state .empty-state-container .empty-state-content a:focus,\n.empty-state .empty-state-container .empty-state-content button.disabled.focus,\n.empty-state .empty-state-container .empty-state-content a.disabled.focus,\n.empty-state .empty-state-container .empty-state-content button[disabled].focus,\n.empty-state .empty-state-container .empty-state-content a[disabled].focus,\nfieldset[disabled] .empty-state .empty-state-container .empty-state-content button.focus,\nfieldset[disabled] .empty-state .empty-state-container .empty-state-content a.focus,\n.empty-state .empty-state-container .empty-state-content button.disabled:active,\n.empty-state .empty-state-container .empty-state-content a.disabled:active,\n.empty-state .empty-state-container .empty-state-content button[disabled]:active,\n.empty-state .empty-state-container .empty-state-content a[disabled]:active,\nfieldset[disabled] .empty-state .empty-state-container .empty-state-content button:active,\nfieldset[disabled] .empty-state .empty-state-container .empty-state-content a:active,\n.empty-state .empty-state-container .empty-state-content button.disabled.active,\n.empty-state .empty-state-container .empty-state-content a.disabled.active,\n.empty-state .empty-state-container .empty-state-content button[disabled].active,\n.empty-state .empty-state-container .empty-state-content a[disabled].active,\nfieldset[disabled] .empty-state .empty-state-container .empty-state-content button.active,\nfieldset[disabled] .empty-state .empty-state-container .empty-state-content a.active {\n opacity: 0.4;\n cursor: auto;\n background-color: white;\n}\n.empty-state .empty-state-container.tight-spacing {\n padding: 0.5rem 0;\n}\n.ErrorMessage {\n margin-bottom: 10px;\n color: #d54c53;\n}\n.ErrorMessage-small {\n margin-bottom: 6px;\n}\n.ErrorMessage-medium {\n margin-bottom: 10px;\n}\n.ErrorMessage-large {\n margin-bottom: 16px;\n}\n.layout-small .ErrorMessage {\n margin-bottom: 6px;\n}\n.layout-large .ErrorMessage {\n margin-bottom: 16px;\n}\n.expandable-path {\n display: inline-flex;\n}\n.expandable-path .link {\n cursor: pointer;\n}\n.expandable-path .path-list {\n display: inline-flex;\n list-style-type: none;\n flex-wrap: wrap;\n margin: 0;\n padding: 0;\n /* always hide the last slash */\n /* on hover, show all labels */\n}\n.expandable-path .path-list .path-item {\n display: inline-flex;\n align-items: center;\n}\n.expandable-path .path-list .path-item.show-label .svg-icon.folder {\n display: none;\n}\n.expandable-path .path-list .path-item.show-label .path-text {\n display: inline;\n}\n.expandable-path .path-list .path-item.show-folder .svg-icon.folder {\n display: inline;\n}\n.expandable-path .path-list .path-item.show-folder .path-text {\n display: none;\n}\n.expandable-path .path-list .path-item:last-child .separator {\n display: none;\n}\n.expandable-path .path-list:hover .svg-icon.folder {\n display: none !important;\n}\n.expandable-path .path-list:hover .path-text {\n display: inline !important;\n}\n.expandable-path .svg-icon.folder {\n fill: #ccc;\n}\n.expandable-path.dark-theme .svg-icon.folder {\n fill: #fff;\n opacity: 0.5;\n}\n.Favorite .Checkbox-indicator {\n border: 0;\n width: 24px;\n height: 24px;\n overflow: hidden;\n}\n.Favorite .Checkbox-indicator .star-icon {\n flex-shrink: 0;\n}\n.Favorite input[type=\"checkbox\"]:checked + .Checkbox-indicator {\n background: none;\n}\n.Favorite input[type=\"checkbox\"]:checked + .Checkbox-indicator .star-icon {\n transform: translate(-264px, 0px);\n transition: 0.3s steps(11);\n}\n.Favorite:hover .star-empty {\n fill: #1b5dab;\n}\n.Favorite:hover .star-filled {\n fill: #aa6d08;\n}\n.Favorite.dark-yellow .star-empty {\n fill: #FFF;\n}\n.Favorite.dark-yellow:hover .star-empty {\n fill: #cccccc;\n}\n.Favorite.dark-yellow:hover .start-filled {\n fill: #aa6d08;\n}\n.Favorite.dark-white path[fill='#4a90e2'],\n.Favorite.dark-white path[fill='#4A90E2'],\n.Favorite.dark-white path[fill='#f5a623'],\n.Favorite.dark-white path[fill='#F5A623'] {\n fill: #FFF;\n}\n.Favorite.dark-white circle[stroke='#f5a623'],\n.Favorite.dark-white circle[stroke='#F5A623'] {\n stroke: #FFF;\n}\n.Favorite.dark-white:hover .star-empty {\n fill: #cccccc;\n}\n.Favorite.dark-white:hover .star-filled {\n fill: #cccccc;\n}\n.FilterableList {\n display: flex;\n flex-flow: column nowrap;\n}\n.FilterableList .FilterableList-empty-text {\n padding: 8px;\n background-color: rgba(228, 228, 228, 0.25);\n}\n.FloatingElement {\n position: fixed;\n left: 0;\n top: 0;\n width: 0;\n height: 0;\n z-index: 100;\n}\n.FloatingElement-wrapper {\n position: fixed;\n left: 0;\n top: 0;\n}\nfieldset {\n padding: 0;\n border: 0;\n margin: 0;\n}\n.FormElement {\n margin-bottom: 10px;\n display: flex;\n flex-direction: column;\n}\n.FormElement .FormElement-heading {\n padding-bottom: 4px;\n}\n.FormElement.u-show-divider .FormElement-heading {\n margin-bottom: 6px;\n}\n.FormElement > .FormElement-heading .ErrorMessage {\n display: inline;\n}\n.FormElement .FormElement-children {\n display: flex;\n align-items: flex-start;\n}\n.FormElement.u-show-divider > .FormElement-heading {\n border-bottom: 1px solid #e4e4e4;\n}\n.FormElement.u-layout-vertical .FormElement-children {\n flex-direction: column;\n}\n.FormElement.u-child-free > .FormElement-heading {\n padding-bottom: 0;\n}\n.FormElement-small {\n margin-bottom: 6px;\n}\n.FormElement-small .FormElement-heading {\n padding-bottom: 2px;\n}\n.FormElement-small.u-show-divider .FormElement-heading {\n margin-bottom: 4px;\n}\n.FormElement-medium {\n margin-bottom: 10px;\n}\n.FormElement-medium .FormElement-heading {\n padding-bottom: 4px;\n}\n.FormElement-medium.u-show-divider .FormElement-heading {\n margin-bottom: 6px;\n}\n.FormElement-large {\n margin-bottom: 16px;\n}\n.FormElement-large .FormElement-heading {\n padding-bottom: 8px;\n}\n.FormElement-large.u-show-divider .FormElement-heading {\n margin-bottom: 12px;\n}\n.layout-small .FormElement {\n margin-bottom: 6px;\n}\n.layout-small .FormElement .FormElement-heading {\n padding-bottom: 2px;\n}\n.layout-small .FormElement.u-show-divider .FormElement-heading {\n margin-bottom: 4px;\n}\n.layout-large .FormElement {\n margin-bottom: 16px;\n}\n.layout-large .FormElement .FormElement-heading {\n padding-bottom: 8px;\n}\n.layout-large .FormElement.u-show-divider .FormElement-heading {\n margin-bottom: 12px;\n}\n.FormElement.u-error-state > .FormElement-heading {\n color: #d54c53;\n}\n.FormElement .FormElement-children > .FormElement {\n flex-grow: 1;\n margin-top: 10px;\n margin-right: 10px;\n}\n.FormElement .FormElement-children > .FormElement:last-child {\n margin-right: 0;\n}\n.layout-small .FormElement .FormElement-children > .FormElement {\n margin-top: 6px;\n margin-right: 6px;\n}\n.layout-large .FormElement .FormElement-children > .FormElement {\n margin-top: 16px;\n margin-right: 16px;\n}\n.FormElement.u-layout-vertical .FormElement-children > .FormElement {\n align-self: stretch;\n margin-right: 0;\n}\n.BasicHeader {\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n}\n.BasicHeader--default {\n background: #4A90E2;\n color: white;\n}\n.BasicHeader--unknown {\n background: #bd0fe1;\n color: white;\n}\n.BasicHeader--success {\n background: #78b037;\n color: white;\n}\n.BasicHeader--failure {\n background: #d54c53;\n color: white;\n}\n.BasicHeader--running {\n background: #3a70b0;\n color: white;\n}\n.BasicHeader--notBuilt {\n background: #949393;\n color: white;\n}\n.BasicHeader--unstable {\n background: #F5A623;\n color: white;\n}\n.BasicHeader--aborted {\n background: #949393;\n color: white;\n}\n.BasicHeader--paused {\n background: #24B0D5;\n color: white;\n}\n.Header-topNav {\n width: 100%;\n background-color: rgba(0, 0, 0, 0.1);\n}\n.Header-topNav-inner {\n height: 48px;\n display: flex;\n flex-direction: row;\n align-items: center;\n width: 100%;\n max-width: 1200px;\n margin-left: auto;\n margin-right: auto;\n padding-right: 15px;\n padding-left: 15px;\n}\n.Header-topNav-inner nav {\n display: flex;\n height: 100%;\n}\n.Header-topNav-inner nav a {\n display: inline-block;\n align-items: center;\n height: 100%;\n color: white;\n text-decoration: none;\n font-size: 14px;\n padding: 0 20px;\n line-height: 47px;\n}\n.Header-topNav-inner nav a .u-no-padding {\n padding: 0;\n}\n.Header-topNav-inner nav a:hover,\n.Header-topNav-inner nav a.selected,\n.Header-topNav-inner nav:hover a.selected:hover {\n background: rgba(0, 0, 0, 0.1);\n}\n.Header-topNav-inner nav:hover a.selected {\n background: none;\n}\n.Header-title {\n display: flex;\n flex-grow: 1;\n align-items: center;\n}\n.Header-details {\n height: 72px;\n display: flex;\n flex-direction: row;\n align-items: center;\n width: 100%;\n max-width: 1200px;\n margin-left: auto;\n margin-right: auto;\n padding-right: 15px;\n padding-left: 15px;\n}\n.Header-pageTabs {\n height: 100%;\n display: flex;\n}\n.Header-pageTabs a {\n color: white;\n display: flex;\n padding: 0 20px;\n height: 100%;\n align-items: center;\n text-decoration: none;\n position: relative;\n overflow: hidden;\n transform: translateZ(0);\n}\n.Header-pageTabs a:hover {\n text-decoration: none;\n color: white;\n}\n.Header-pageTabs a:before {\n content: \"\";\n position: absolute;\n z-index: -1;\n left: 0;\n right: 0;\n bottom: 0;\n background: white;\n height: 3px;\n transition-timing-function: ease-out;\n transition-duration: 0.2s;\n transform: translateY(3px);\n transition-property: transform;\n}\n.Header-pageTabs a:hover:before,\n.Header-pageTabs a.selected:before,\n.Header-pageTabs:hover a.selected:hover:before {\n transform: translateY(0);\n}\n.Header-pageTabs:hover a.selected:before {\n transform: translateY(3px);\n}\nbutton.IconButton {\n padding-top: 4px;\n padding-bottom: 4px;\n}\nbutton.IconButton .IconButton-icon > * {\n width: 20px;\n height: 20px;\n}\nbutton.IconButton.u-inner-margin .IconButton-icon {\n margin-right: 10px;\n}\nbutton.IconButton .IconButton-wrapper {\n display: flex;\n align-items: center;\n}\nbutton.IconButton .IconButton-icon > * {\n display: block;\n}\nbutton.IconButton .IconButton-icon .svg-icon {\n fill: #fff;\n}\nbutton.IconButton.monochrome .IconButton-icon .svg-icon {\n fill: #4A4A4A;\n}\n.IconButton-small {\n padding-top: 3.5px;\n padding-bottom: 3.5px;\n}\n.IconButton-small .IconButton-icon > * {\n width: 16px;\n height: 16px;\n}\n.IconButton-small.u-inner-margin .IconButton-icon {\n margin-right: 5px;\n}\n.IconButton-medium {\n padding-top: 4px;\n padding-bottom: 4px;\n}\n.IconButton-medium .IconButton-icon > * {\n width: 20px;\n height: 20px;\n}\n.IconButton-medium.u-inner-margin .IconButton-icon {\n margin-right: 10px;\n}\n.IconButton-large {\n padding-top: 6px;\n padding-bottom: 6px;\n}\n.IconButton-large .IconButton-icon > * {\n width: 24px;\n height: 24px;\n}\n.IconButton-large.u-inner-margin .IconButton-icon {\n margin-right: 12px;\n}\n.layout-small .IconButton {\n padding-top: 3.5px;\n padding-bottom: 3.5px;\n}\n.layout-small .IconButton .IconButton-icon > * {\n width: 16px;\n height: 16px;\n}\n.layout-small .IconButton.u-inner-margin .IconButton-icon {\n margin-right: 5px;\n}\n.layout-large .IconButton {\n padding-top: 6px;\n padding-bottom: 6px;\n}\n.layout-large .IconButton .IconButton-icon > * {\n width: 24px;\n height: 24px;\n}\n.layout-large .IconButton.u-inner-margin .IconButton-icon {\n margin-right: 12px;\n}\n.List {\n width: 100%;\n overflow-x: hidden;\n overflow-y: auto;\n}\n.List .List-Item {\n position: relative;\n}\n.List.disabled,\n.List[disabled],\nfieldset[disabled] .List {\n opacity: 0.4;\n cursor: auto;\n pointer-events: none;\n}\n.List.u-default-list-container {\n padding: 8px;\n padding-bottom: 0;\n background-color: rgba(228, 228, 228, 0.25);\n border-radius: 3px;\n}\n.List.u-default-list-container .List-Radio:focus + .List-Item {\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\n.List.u-default-list-container .List-Item {\n margin-bottom: 8px;\n background-color: #fff;\n border: 1px solid rgba(73, 73, 73, 0.5);\n border-radius: 3px;\n}\n.List.u-default-list-container .List-Item.List-Item-selected {\n background-color: #e4e4e4;\n}\n.List.u-default-list-container .List-Item:hover {\n background-color: #e4e4e4;\n cursor: pointer;\n}\n.List.u-default-list-container.disabled .List-Item:hover,\n.List.u-default-list-container[disabled] .List-Item:hover,\nfieldset[disabled] .List.u-default-list-container .List-Item:hover {\n background-color: #fff;\n cursor: default;\n}\n.List .List-DefaultRenderer {\n overflow: hidden;\n padding: 8px 16px;\n}\n.popup-shadow {\n filter: drop-shadow(0px 2px 4px rgba(0, 0, 0, 0.5));\n}\n.popup-appearance {\n background: white;\n border: none;\n border-radius: 3px;\n}\n.ModalContainer {\n position: fixed;\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.ModalContainer-modalScreen {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n background: black;\n opacity: 0.25;\n z-index: 99;\n}\n.Dialog {\n background: white;\n border: none;\n border-radius: 3px;\n filter: drop-shadow(0px 2px 4px rgba(0, 0, 0, 0.5));\n z-index: 100;\n max-width: 95%;\n max-height: 90%;\n display: flex;\n flex-direction: column;\n}\n.Dialog-header {\n display: flex;\n align-items: center;\n width: 100%;\n height: 80px;\n flex-shrink: 0;\n background: #4A90E2;\n color: white;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n padding: 0 32px;\n}\n.Dialog--input .Dialog-header {\n background: #24B0D5;\n}\n.Dialog--error .Dialog-header {\n background: #d54c53;\n}\n.Dialog--success .Dialog-header {\n background: #78b037;\n}\n.Dialog--warning .Dialog-header {\n background: #F5A623;\n}\n.Dialog-content-scroll {\n overflow: auto;\n flex-shrink: 1;\n}\n.Dialog-content-margin {\n margin: 32px 32px 16px 32px;\n}\n.Dialog-button-bar {\n padding: 0 32px;\n margin: 16px 0 32px;\n display: flex;\n width: 100%;\n justify-content: flex-start;\n flex-shrink: 0;\n}\n.Dialog-button-bar > Button + Button {\n margin-left: 0.5em;\n}\n.Popover {\n position: fixed;\n z-index: 120;\n left: 0;\n top: 0;\n filter: drop-shadow(0px 2px 4px rgba(0, 0, 0, 0.5));\n}\n.Popover-content {\n background: white;\n border: none;\n border-radius: 3px;\n padding: 2em 2em;\n}\n.Popover-point {\n fill: white;\n position: absolute;\n}\n.Popover-point--above {\n bottom: -10px;\n left: 50%;\n margin-left: -10px;\n}\n.Popover-point--below {\n top: -10px;\n left: 50%;\n margin-left: -10px;\n}\n.Popover-point--left {\n right: -10px;\n top: 50%;\n margin-top: -10px;\n}\n.Popover-point--right {\n left: -10px;\n top: 50%;\n margin-top: -10px;\n}\n.progress-container {\n width: 100%;\n height: 5px;\n}\n.progress-container line {\n stroke-width: 5px;\n}\n.progress-container line.progress-bg {\n stroke: #a7c7f2;\n z-index: 0;\n}\n.progress-container line.progress-bar {\n stroke: #4A90E2;\n}\n@keyframes slidein {\n from {\n transform: translate(0, 0) scale(2, 1);\n -webkit-transform: translate(0, 0) scale(2, 1);\n -o-transform: translate(0, 0) scale(2, 1);\n -moz-transform: translate(0, 0) scale(2, 1);\n }\n 100% {\n transform: translate(100px, 0) scale(1);\n -webkit-transform: translate(100px, 0) scale(1);\n -o-transform: translate(100px, 0) scale(1);\n -moz-transform: translate(100px, 0) scale(1);\n }\n}\n@keyframes bounce {\n from {\n transform: translate(0, 0);\n -webkit-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n -moz-transform: translate(0, 0);\n }\n 50% {\n transform: translate(90px, 0) scale(1);\n -webkit-transform: translate(90px, 0) scale(1);\n -o-transform: translate(90px, 0) scale(1);\n -moz-transform: translate(90px, 0) scale(1);\n }\n to {\n transform: translate(0, 0);\n -webkit-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n -moz-transform: translate(0, 0);\n }\n}\n.progress-container.indeterminate line.progress-bar {\n z-index: 10;\n animation-duration: 1s;\n animation-name: slidein;\n animation-iteration-count: infinite;\n}\n.progress-container.bounce line.progress-bar {\n z-index: 10;\n animation-duration: 3s;\n animation-name: bounce;\n animation-iteration-count: infinite;\n}\n.RadioButtonGroup {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n}\n.RadioButtonGroup .RadioButtonGroup-item {\n margin-bottom: 6px;\n}\n.RadioButtonGroup .RadioButtonGroup-indicator,\n.RadioButtonGroup .RadioButtonGroup-focus {\n width: 20px;\n height: 20px;\n}\n.RadioButtonGroup .RadioButtonGroup-item {\n display: flex;\n align-items: center;\n}\n.RadioButtonGroup .RadioButtonGroup-item input[type=\"radio\"] {\n border: 0;\n clip: rect(0, 0, 0, 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n width: 1px;\n}\n.RadioButtonGroup .RadioButtonGroup-item .RadioButtonGroup-indicator {\n position: relative;\n cursor: pointer;\n flex-shrink: 0;\n}\n.RadioButtonGroup .RadioButtonGroup-item .RadioButtonGroup-indicator .svg-shape {\n display: block;\n}\n.RadioButtonGroup .RadioButtonGroup-item .RadioButtonGroup-indicator .outer-circle {\n stroke: #777777;\n}\n.RadioButtonGroup .RadioButtonGroup-item .RadioButtonGroup-indicator .RadioButtonGroup-focus {\n position: absolute;\n top: 0;\n border-radius: 100%;\n}\n.RadioButtonGroup .RadioButtonGroup-item .RadioButtonGroup-text {\n margin-left: 5px;\n cursor: pointer;\n}\n.RadioButtonGroup .RadioButtonGroup-item input[type=\"radio\"]:checked + .RadioButtonGroup-indicator .outer-circle {\n fill: #4A90E2;\n stroke: #4A90E2;\n}\n.RadioButtonGroup .RadioButtonGroup-item input[type=\"radio\"]:focus + .RadioButtonGroup-indicator .RadioButtonGroup-focus {\n outline: 0;\n box-shadow: inset 0 0 2px 3px rgba(0, 0, 0, 0.2);\n}\n.RadioButtonGroup .RadioButtonGroup-item input[type=\"radio\"][disabled] ~ .RadioButtonGroup-indicator,\nfieldset[disabled] .RadioButtonGroup .RadioButtonGroup-item input[type=\"radio\"] ~ .RadioButtonGroup-indicator,\n.RadioButtonGroup .RadioButtonGroup-item input[type=\"radio\"][disabled] ~ .RadioButtonGroup-text,\nfieldset[disabled] .RadioButtonGroup .RadioButtonGroup-item input[type=\"radio\"] ~ .RadioButtonGroup-text {\n opacity: 0.4;\n cursor: auto;\n}\n.RadioButtonGroup.u-layout-horizontal {\n flex-direction: row;\n}\n.RadioButtonGroup.u-layout-horizontal .RadioButtonGroup-item {\n margin-right: 10px;\n}\n@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {\n input[type=\"radio\"]:focus + .RadioButtonGroup-indicator .RadioButtonGroup-focus {\n box-shadow: inset 0 0 1px 3px rgba(0, 0, 0, 0.2);\n margin-top: -1px;\n }\n}\n@supports (-ms-ime-align:auto) {\n input[type=\"radio\"]:focus + .RadioButtonGroup-indicator .RadioButtonGroup-focus {\n box-shadow: inset 0 0 1px 3px rgba(0, 0, 0, 0.2);\n margin-top: -1px;\n }\n}\n.RadioButtonGroup-small .RadioButtonGroup-item {\n margin-bottom: 4px;\n}\n.RadioButtonGroup-small .RadioButtonGroup-indicator,\n.RadioButtonGroup-small .RadioButtonGroup-focus {\n width: 16px;\n height: 16px;\n}\n.RadioButtonGroup-medium .RadioButtonGroup-item {\n margin-bottom: 6px;\n}\n.RadioButtonGroup-medium .RadioButtonGroup-indicator,\n.RadioButtonGroup-medium .RadioButtonGroup-focus {\n width: 20px;\n height: 20px;\n}\n.RadioButtonGroup-large .RadioButtonGroup-item {\n margin-bottom: 10px;\n}\n.RadioButtonGroup-large .RadioButtonGroup-indicator,\n.RadioButtonGroup-large .RadioButtonGroup-focus {\n width: 24px;\n height: 24px;\n}\n.layout-small .RadioButtonGroup .RadioButtonGroup-item {\n margin-bottom: 4px;\n}\n.layout-small .RadioButtonGroup .RadioButtonGroup-indicator,\n.layout-small .RadioButtonGroup .RadioButtonGroup-focus {\n width: 16px;\n height: 16px;\n}\n.layout-large .RadioButtonGroup .RadioButtonGroup-item {\n margin-bottom: 10px;\n}\n.layout-large .RadioButtonGroup .RadioButtonGroup-indicator,\n.layout-large .RadioButtonGroup .RadioButtonGroup-focus {\n width: 24px;\n height: 24px;\n}\n/*\n Styles for the pipeline result status displays used in both build/branch lists, and\n within the PipelineGraph component.\n*/\n.result-status-glyph {\n stroke: none;\n fill: #fff;\n}\n.svgResultStatus.no-background .circle-bg {\n opacity: 0;\n}\n.svgResultStatus circle.success {\n stroke: none;\n fill: #8CC04F;\n}\n.svgResultStatus circle.failure {\n stroke: none;\n fill: #D54C53;\n}\n.svgResultStatus circle.unstable {\n stroke: none;\n fill: #F6B44B;\n}\n.svgResultStatus circle.aborted,\n.svgResultStatus circle.not_built {\n stroke: none;\n fill: #949393;\n}\n.svgResultStatus circle.paused {\n stroke: none;\n fill: #24B0D5;\n}\n.svgResultStatus circle.unknown {\n stroke: none;\n fill: #D54CC4;\n}\n.jdl-table td .svgResultStatus {\n vertical-align: middle;\n}\n.progress-spinner.running circle {\n fill: none;\n stroke: #a7c7f2;\n}\n.progress-spinner.running path {\n fill: none;\n stroke: #1D7DCF;\n}\n.progress-spinner.pc-over-100 circle {\n fill: none;\n stroke: #1D7DCF;\n}\n.progress-spinner.pc-over-100 path {\n fill: none;\n stroke: #F6B44B;\n}\n.inverse .progress-spinner.running circle {\n fill: none;\n stroke: #4C9BD5;\n}\n.inverse .progress-spinner.running path {\n fill: none;\n stroke: white;\n}\n.inverse .progress-spinner.running circle.inner {\n fill: #4C9BD5;\n stroke: #4C9BD5;\n}\n.progress-spinner circle.inner,\n.progress-spinner.running.spin circle.inner {\n display: none;\n animation: progress-spinner-pulsate 1.2s ease-out;\n animation-iteration-count: infinite;\n opacity: 0;\n}\n.progress-spinner.running circle.inner {\n display: block;\n fill: #4C9BD5;\n stroke: #4C9BD5;\n}\n@keyframes progress-spinner-pulsate {\n 0% {\n transform: scale(0.1, 0.1);\n opacity: 0.0;\n }\n 50% {\n opacity: 1;\n }\n 100% {\n transform: scale(1.2, 1.2);\n opacity: 0.0;\n }\n}\n.progress-spinner.queued circle {\n fill: none;\n stroke: #949393;\n}\n.progress-spinner.queued circle.inner {\n display: block;\n fill: #949393;\n stroke: #949393;\n}\n.empty-state-content svg {\n vertical-align: middle;\n}\n.empty-state-content > span {\n padding-left: 15px;\n}\n.progress-spinner.queued path {\n fill: none;\n stroke: none;\n}\n.progress-spinner.not_built circle {\n fill: none;\n stroke: #949393;\n}\n.progress-spinner.not_built path {\n fill: none;\n stroke: none;\n}\n.result-bg.success {\n background: #8CC04F;\n border-bottom: 1px solid rgba(114, 162, 58, 0.5);\n}\n.result-bg.failure {\n background: #D54C53;\n border-bottom: 1px solid rgba(193, 45, 53, 0.5);\n}\n.result-bg.not_built,\n.result-bg.aborted,\n.result-bg.queued {\n background: #949393;\n border-bottom: 1px solid rgba(123, 121, 121, 0.5);\n}\n.result-bg.running {\n background: #1D7DCF;\n border-bottom: 1px solid rgba(23, 98, 162, 0.5);\n}\n.result-bg.unstable {\n background: #F6B44B;\n border-bottom: 1px solid rgba(244, 160, 26, 0.5);\n}\n.result-bg.paused {\n background: #24B0D5;\n border-bottom: 1px solid rgba(29, 140, 169, 0.5);\n}\n.result-bg.unknown {\n background: #D54CC4;\n border-bottom: 1px solid rgba(193, 45, 174, 0.5);\n}\n.result-item + .result-item .result-item-head {\n border-top: 0;\n}\n.result-item-head {\n display: flex;\n align-items: stretch;\n cursor: pointer;\n border: solid 1px #e4e4e4;\n}\n.result-item-icon {\n display: flex;\n align-items: flex-start;\n margin: -1px 0 -1px -1px;\n}\n.result-item-title {\n flex: 1 1 auto;\n display: flex;\n align-items: center;\n}\n.result-item-extra-info {\n padding-right: 0.6em;\n}\n.result-item-label {\n flex: 1 1 auto;\n font-family: \"LatoLatinWeb\", \"Lato\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\n.result-item-head:hover {\n background: #f8f8f8;\n}\n.result-item-expando {\n cursor: pointer;\n}\n.expando-glyph {\n transform: rotate(0deg);\n transition: transform 150ms ease-in;\n fill: #4A4A4A;\n}\n.result-item-expando.expanded .expando-glyph {\n transform: rotate(90deg);\n transition: transform 150ms ease-in;\n}\n.result-item-expando.disabled .expando-glyph {\n opacity: 0.3;\n}\n.result-item-children {\n background-color: #333333;\n color: #f5f5f5;\n padding: 0.5em;\n margin-bottom: 1px;\n border-left: solid 28px #262626;\n}\n.slide-down-enter,\n.slide-down-appear {\n max-height: 0;\n overflow: hidden;\n}\n.slide-down-enter.slide-down-enter-active,\n.slide-down-appear.slide-down-appear-active {\n max-height: 600px;\n transition: all 300ms ease-in;\n}\n.slide-down-leave {\n max-height: 600px;\n overflow: hidden;\n}\n.slide-down-leave.slide-down-leave-active {\n max-height: 0;\n transition: all 300ms ease-out;\n}\n.pipeline-connector {\n stroke: #949393;\n}\n.pipeline-small-label {\n font-size: 80%;\n}\n.pipeline-big-label.selected,\n.pipeline-small-label.selected {\n font-weight: bold;\n}\n.pipeline-selection-highlight circle {\n fill: none;\n stroke: #949393;\n}\ntd,\nth {\n padding: 0;\n}\n.jdl-table {\n border-collapse: collapse;\n width: 100%;\n}\n.jdl-table td,\n.jdl-table th {\n text-align: left;\n}\n.jdl-table th {\n font-family: \"LatoLatinWebSemibold\", \"Lato\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-weight: normal;\n}\n.jdl-table a {\n color: #4A4A4A;\n}\n.jdl-table.u-fixed {\n table-layout: fixed;\n}\n.jdl-table.u-highlight-rows tbody tr:hover {\n cursor: pointer;\n background-color: rgba(148, 147, 147, 0.1);\n}\n.jdl-table.u-table-padding td,\n.jdl-table.u-table-padding th,\n.jdl-table td.u-table-padding,\n.jdl-table th.u-table-padding {\n padding: 0.5rem 0;\n}\n.jdl-table.u-table-padding td:first-child,\n.jdl-table.u-table-padding th:first-child,\n.jdl-table td.u-table-padding:first-child,\n.jdl-table th.u-table-padding:first-child {\n padding-left: 1rem;\n}\n.jdl-table.u-table-padding td:last-child,\n.jdl-table.u-table-padding th:last-child,\n.jdl-table td.u-table-padding:last-child,\n.jdl-table th.u-table-padding:last-child {\n padding-right: 1rem;\n}\n.jdl-table.u-single-line td,\n.jdl-table.u-single-line th,\n.jdl-table td.u-single-line,\n.jdl-table th.u-single-line {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.jdl-table.u-table-padding tr.jdl-table-divider td,\n.jdl-table tr.jdl-table-divider td {\n padding: 0.5rem 0;\n}\n.jdl-table.u-table-padding tr.jdl-table-divider hr,\n.jdl-table tr.jdl-table-divider hr {\n height: 1px;\n color: #4A4A4A;\n background: #4A4A4A;\n border: none;\n font-size: 0;\n opacity: 0.5;\n}\n.TextArea {\n height: 102px;\n display: inline-block;\n width: 100%;\n}\n.TextArea .TextArea-control {\n padding: 10px;\n}\n.TextArea .TextArea-control {\n width: 100%;\n height: 100%;\n color: #4A4A4A;\n border: 1px solid rgba(73, 73, 73, 0.5);\n border-radius: 3px;\n}\n.TextArea .TextArea-control:focus {\n border-color: #4A90E2;\n outline: 0;\n}\n.TextArea .TextArea-control[disabled],\nfieldset[disabled] .TextArea .TextArea-control {\n opacity: 0.4;\n cursor: auto;\n}\n.TextArea-small {\n height: 83px;\n}\n.TextArea-small .TextArea-control {\n padding: 8px;\n}\n.TextArea-medium {\n height: 102px;\n}\n.TextArea-medium .TextArea-control {\n padding: 10px;\n}\n.TextArea-large {\n height: 126px;\n}\n.TextArea-large .TextArea-control {\n padding: 12px;\n}\n.layout-small .TextArea {\n height: 83px;\n}\n.layout-small .TextArea .TextArea-control {\n padding: 8px;\n}\n.layout-large .TextArea {\n height: 126px;\n}\n.layout-large .TextArea .TextArea-control {\n padding: 12px;\n}\n.FormElement.u-error-state > .FormElement-children > .TextArea .TextArea-control {\n border-color: #d54c53;\n}\ninput[type=\"text\"]::-ms-clear {\n display: none;\n}\n.TextInput,\n.PasswordInput {\n display: inline-block;\n position: relative;\n background-color: #fff;\n}\n.TextInput .TextInput-icon,\n.PasswordInput .TextInput-icon {\n width: 24px;\n height: 24px;\n margin-top: -12px;\n}\n.TextInput .TextInput-icon .svg-icon,\n.PasswordInput .TextInput-icon .svg-icon {\n width: 24px;\n height: 24px;\n}\n.TextInput.u-icon-left .TextInput-icon.u-icon-left,\n.PasswordInput.u-icon-left .TextInput-icon.u-icon-left {\n left: 4px;\n}\n.TextInput.u-icon-left .TextInput-control,\n.PasswordInput.u-icon-left .TextInput-control {\n padding-left: 28px;\n margin-right: -18px;\n}\n.TextInput.u-icon-right .TextInput-icon.u-icon-right,\n.PasswordInput.u-icon-right .TextInput-icon.u-icon-right {\n right: 4px;\n}\n.TextInput.u-icon-right .TextInput-control,\n.PasswordInput.u-icon-right .TextInput-control {\n padding-right: 28px;\n margin-right: -18px;\n}\n.TextInput.u-icon-left.u-icon-right .TextInput-control,\n.PasswordInput.u-icon-left.u-icon-right .TextInput-control {\n margin-right: -36px;\n}\n.TextInput .TextInput-control,\n.PasswordInput .TextInput-control {\n padding: 6px 10px;\n}\n.TextInput .TextInput-control,\n.PasswordInput .TextInput-control {\n width: 100%;\n color: #4A4A4A;\n background-color: transparent;\n border: 1px solid rgba(73, 73, 73, 0.5);\n border-radius: 3px;\n}\n.TextInput .TextInput-control:focus,\n.PasswordInput .TextInput-control:focus {\n border-color: #4A90E2;\n outline: 0;\n}\n.TextInput .TextInput-control[disabled],\n.PasswordInput .TextInput-control[disabled],\nfieldset[disabled] .TextInput .TextInput-control,\nfieldset[disabled] .PasswordInput .TextInput-control {\n opacity: 0.4;\n cursor: auto;\n}\n.TextInput .TextInput-icon,\n.PasswordInput .TextInput-icon {\n position: absolute;\n top: 50%;\n fill: #999;\n cursor: default;\n}\n.TextInput-small .TextInput-icon {\n width: 20px;\n height: 20px;\n margin-top: -10px;\n}\n.TextInput-small .TextInput-icon .svg-icon {\n width: 20px;\n height: 20px;\n}\n.TextInput-small.u-icon-left .TextInput-icon.u-icon-left {\n left: 4px;\n}\n.TextInput-small.u-icon-left .TextInput-control {\n padding-left: 24px;\n margin-right: -16px;\n}\n.TextInput-small.u-icon-right .TextInput-icon.u-icon-right {\n right: 4px;\n}\n.TextInput-small.u-icon-right .TextInput-control {\n padding-right: 24px;\n margin-right: -16px;\n}\n.TextInput-small.u-icon-left.u-icon-right .TextInput-control {\n margin-right: -32px;\n}\n.TextInput-small .TextInput-control {\n padding: 5px 8px;\n}\n.TextInput-medium .TextInput-icon {\n width: 24px;\n height: 24px;\n margin-top: -12px;\n}\n.TextInput-medium .TextInput-icon .svg-icon {\n width: 24px;\n height: 24px;\n}\n.TextInput-medium.u-icon-left .TextInput-icon.u-icon-left {\n left: 4px;\n}\n.TextInput-medium.u-icon-left .TextInput-control {\n padding-left: 28px;\n margin-right: -18px;\n}\n.TextInput-medium.u-icon-right .TextInput-icon.u-icon-right {\n right: 4px;\n}\n.TextInput-medium.u-icon-right .TextInput-control {\n padding-right: 28px;\n margin-right: -18px;\n}\n.TextInput-medium.u-icon-left.u-icon-right .TextInput-control {\n margin-right: -36px;\n}\n.TextInput-medium .TextInput-control {\n padding: 6px 10px;\n}\n.TextInput-large .TextInput-icon {\n width: 28px;\n height: 28px;\n margin-top: -14px;\n}\n.TextInput-large .TextInput-icon .svg-icon {\n width: 28px;\n height: 28px;\n}\n.TextInput-large.u-icon-left .TextInput-icon.u-icon-left {\n left: 6px;\n}\n.TextInput-large.u-icon-left .TextInput-control {\n padding-left: 34px;\n margin-right: -22px;\n}\n.TextInput-large.u-icon-right .TextInput-icon.u-icon-right {\n right: 6px;\n}\n.TextInput-large.u-icon-right .TextInput-control {\n padding-right: 34px;\n margin-right: -22px;\n}\n.TextInput-large.u-icon-left.u-icon-right .TextInput-control {\n margin-right: -44px;\n}\n.TextInput-large .TextInput-control {\n padding: 8px 12px;\n}\n.layout-small .TextInput .TextInput-icon {\n width: 20px;\n height: 20px;\n margin-top: -10px;\n}\n.layout-small .TextInput .TextInput-icon .svg-icon {\n width: 20px;\n height: 20px;\n}\n.layout-small .TextInput.u-icon-left .TextInput-icon.u-icon-left {\n left: 4px;\n}\n.layout-small .TextInput.u-icon-left .TextInput-control {\n padding-left: 24px;\n margin-right: -16px;\n}\n.layout-small .TextInput.u-icon-right .TextInput-icon.u-icon-right {\n right: 4px;\n}\n.layout-small .TextInput.u-icon-right .TextInput-control {\n padding-right: 24px;\n margin-right: -16px;\n}\n.layout-small .TextInput.u-icon-left.u-icon-right .TextInput-control {\n margin-right: -32px;\n}\n.layout-small .TextInput .TextInput-control {\n padding: 5px 8px;\n}\n.layout-large .TextInput .TextInput-icon {\n width: 28px;\n height: 28px;\n margin-top: -14px;\n}\n.layout-large .TextInput .TextInput-icon .svg-icon {\n width: 28px;\n height: 28px;\n}\n.layout-large .TextInput.u-icon-left .TextInput-icon.u-icon-left {\n left: 6px;\n}\n.layout-large .TextInput.u-icon-left .TextInput-control {\n padding-left: 34px;\n margin-right: -22px;\n}\n.layout-large .TextInput.u-icon-right .TextInput-icon.u-icon-right {\n right: 6px;\n}\n.layout-large .TextInput.u-icon-right .TextInput-control {\n padding-right: 34px;\n margin-right: -22px;\n}\n.layout-large .TextInput.u-icon-left.u-icon-right .TextInput-control {\n margin-right: -44px;\n}\n.layout-large .TextInput .TextInput-control {\n padding: 8px 12px;\n}\n.FormElement.u-error-state > .FormElement-children > .TextInput .TextInput-control,\n.FormElement.u-error-state > .FormElement-children > .PasswordInput .TextInput-control {\n border-color: #d54c53;\n}\n.toaster {\n width: 100%;\n height: 100%;\n}\n.toaster .toast {\n margin-bottom: 10px;\n}\n.toaster > span {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column-reverse;\n justify-content: flex-start;\n align-items: flex-start;\n overflow-y: hidden;\n}\n.toast {\n display: inline-flex;\n max-width: 350px;\n flex-shrink: 0;\n padding: 20px;\n background-color: #4A4A4A;\n border-radius: 4px;\n /* TODO: get proper values from updated sketch file */\n -webkit-box-shadow: 1px 2px 2px rgba(0, 0, 0, 0.5);\n box-shadow: 1px 2px 2px rgba(0, 0, 0, 0.5);\n}\n.toast.success,\n.toast.error {\n border-left: 5px solid;\n}\n.toast.success {\n border-left-color: #8CC04F;\n}\n.toast.error {\n border-left-color: #D54C53;\n}\n.toast .caption {\n margin-bottom: 10px;\n}\n.toast .text,\n.toast .action,\n.toast .dismiss {\n align-self: center;\n}\n.toast .text {\n font-family: \"LatoLatinWebMedium\", \"Lato\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n color: white;\n max-height: 85px;\n overflow: hidden;\n}\n.toast .action,\n.toast .dismiss {\n cursor: pointer;\n}\n.toast .action:hover,\n.toast .dismiss:hover {\n text-decoration: none;\n}\n.toast .action {\n margin: 0 20px;\n text-transform: uppercase;\n}\n.toast .dismiss {\n color: white;\n}\n.toast .dismiss svg {\n vertical-align: middle;\n}\n.toast-enter,\n.toast-appear {\n opacity: 0.01;\n}\n.toast-enter.toast-enter-active,\n.toast-appear.toast-appear-active {\n opacity: 1;\n transition: all 300ms ease-in;\n}\n.toast-leave {\n opacity: 1;\n max-height: 150px;\n}\n.toast-leave.toast-leave-active {\n opacity: 0.01;\n max-height: 0;\n transition: all 300ms ease-in;\n}\n.Alert {\n font-size: 14px;\n min-height: 48px;\n border-radius: 3px;\n background-color: #ffffff;\n border: solid 1px #e6eaee;\n display: flex;\n align-items: stretch;\n}\n.Alert .border {\n flex: 0 0 6px;\n min-height: 100%;\n margin-top: -1px;\n margin-bottom: -1px;\n}\n.Alert .title-div {\n flex: 1 1 auto;\n display: flex;\n align-items: center;\n}\n.Alert .title {\n padding-left: 24px;\n font-weight: bold;\n}\n.Alert .message {\n color: #4A4A4A;\n line-height: 1.71;\n padding-left: 16px;\n}\n.Alert.Info {\n border-left-color: #4C9BD5;\n color: #4C9BD5;\n}\n.Alert.Info .border {\n background-color: #4C9BD5;\n}\n.Alert.Warning {\n border-left-color: #F5A623;\n color: #F5A623;\n}\n.Alert.Warning .border {\n background-color: #F5A623;\n}\n.Alert.Error {\n border-left-color: #D54C53;\n color: #D54C53;\n}\n.Alert.Error .border {\n background-color: #D54C53;\n}\n.Alert.Success {\n border-left-color: #78b037;\n color: #78b037;\n}\n.Alert.Success .border {\n background-color: #78b037;\n}\n.layout-small {\n font-size: 12px;\n}\n.layout-medium {\n font-size: 14px;\n}\n.layout-large {\n font-size: 18px;\n}\nhtml {\n font-size: 62.5%;\n}\n#root {\n font-size: 1.4rem;\n}\nbody {\n color: #4A4A4A;\n text-rendering: optimizeSpeed;\n font-feature-settings: \"kern\" on, \"liga\" off;\n -moz-font-feature-settings: \"kern\" on, \"liga\" off;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n line-height: 1.2;\n}\n* {\n box-sizing: border-box;\n}\np {\n margin: 1em 0;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: 100%;\n font-family: \"LatoLatinWebLight\", \"Lato\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n margin: 0;\n padding: 0;\n}\nh1 {\n font-size: 18px;\n font-family: \"LatoLatinWeb\", \"Lato\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\nh2 {\n font-size: 30px;\n}\nh3 {\n font-size: 24px;\n}\nh4 {\n font-size: 18px;\n}\nh5 {\n font-size: 14px;\n}\nh6 {\n font-size: 12px;\n}\n.u-content-page-sizing {\n width: 100%;\n max-width: 1200px;\n margin-left: auto;\n margin-right: auto;\n padding-right: 15px;\n padding-left: 15px;\n}\n.success-bg {\n background-color: #78b037;\n}\n.success-bg-lite {\n background-color: #8CC04F;\n}\n.success-fill {\n fill: #78b037;\n}\n.success-fill-lite {\n fill: #8CC04F;\n}\n.success-color {\n color: #78b037;\n}\n.success-color-lite {\n color: #8CC04F;\n}\n.info-bg {\n background-color: #3a70b0;\n}\n.info-bg-lite {\n background-color: #4C9BD5;\n}\n.info-fill {\n fill: #3a70b0;\n}\n.info-fill-lite {\n fill: #4C9BD5;\n}\n.info-color {\n color: #3a70b0;\n}\n.info-color-lite {\n color: #4C9BD5;\n}\n.running-bg {\n background-color: #3a70b0;\n}\n.running-bg-lite {\n background-color: #4C9BD5;\n}\n.running-fill {\n fill: #3a70b0;\n}\n.running-fill-lite {\n fill: #4C9BD5;\n}\n.running-color {\n color: #3a70b0;\n}\n.running-color-lite {\n color: #4C9BD5;\n}\n.failure-bg {\n background-color: #d54c53;\n}\n.failure-bg-lite {\n background-color: #D54C53;\n}\n.failure-fill {\n fill: #d54c53;\n}\n.failure-fill-lite {\n fill: #D54C53;\n}\n.failure-color {\n color: #d54c53;\n}\n.failure-color-lite {\n color: #D54C53;\n}\n.aborted-bg {\n background-color: #4A4A4A;\n}\n.aborted-bg-lite {\n background-color: #949393;\n}\n.aborted-fill {\n fill: #4A4A4A;\n}\n.aborted-fill-lite {\n fill: #949393;\n}\n.aborted-color {\n color: #4A4A4A;\n}\n.aborted-color-lite {\n color: #949393;\n}\n.unstable-bg {\n background-color: #F5A623;\n}\n.unstable-bg-lite {\n background-color: #F6B44B;\n}\n.unstable-fill {\n fill: #F5A623;\n}\n.unstable-fill-lite {\n fill: #F6B44B;\n}\n.unstable-color {\n color: #F5A623;\n}\n.unstable-color-lite {\n color: #F6B44B;\n}\n.not_built-bg {\n background-color: #4A4A4A;\n}\n.not_built-bg-lite {\n background-color: #949393;\n}\n.not_built-fill {\n fill: #4A4A4A;\n}\n.not_built-fill-lite {\n fill: #949393;\n}\n.not_built-color {\n color: #4A4A4A;\n}\n.not_built-color-lite {\n color: #949393;\n}\n.queued-bg {\n background-color: #4A4A4A;\n}\n.queued-bg-lite {\n background-color: #949393;\n}\n.queued-fill {\n fill: #4A4A4A;\n}\n.queued-fill-lite {\n fill: #949393;\n}\n.queued-color {\n color: #4A4A4A;\n}\n.queued-color-lite {\n color: #949393;\n}\n.paused-bg {\n background-color: #24B0D5;\n}\n.paused-bg-lite {\n background-color: #24B0D5;\n}\n.paused-fill {\n fill: #24B0D5;\n}\n.paused-fill-lite {\n fill: #24B0D5;\n}\n.paused-color {\n color: #24B0D5;\n}\n.paused-color-lite {\n color: #24B0D5;\n}\n.unknown-bg {\n background-color: #bd0fe1;\n}\n.unknown-bg-lite {\n background-color: #D54CC4;\n}\n.unknown-fill {\n fill: #bd0fe1;\n}\n.unknown-fill-lite {\n fill: #D54CC4;\n}\n.unknown-color {\n color: #bd0fe1;\n}\n.unknown-color-lite {\n color: #D54CC4;\n}\n.label-danger {\n background-color: #d54c53;\n}\n.label-warning {\n background-color: #F5A623;\n}\n.label-info {\n background-color: #3a70b0;\n}\n.label-success {\n background-color: #78b037;\n}\n.label-primary {\n background-color: #4A90E2;\n}\na {\n text-decoration: none;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge,\na {\n color: #4A90E2;\n}\na:hover {\n color: #1f69c1;\n text-decoration: underline;\n}\na.inverse {\n color: white;\n}\na.inverse:hover {\n color: white;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text {\n color: white;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:focus {\n background-color: #4A90E2;\n}\n.nav-pills > li.active > a:hover {\n background-color: #1f69c1;\n}\n.progress-bar {\n background-color: #4A90E2;\n}\nbody {\n font-family: \"LatoLatinWeb\", \"Lato\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n background-color: #FFF;\n}\n@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {\n body {\n font-family: sans-serif !important;\n }\n}\ncode,\npre,\nkbd {\n font-family: \"Source Code Pro\", Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #4A90E2 0%, #3483de 100%);\n background-image: -o-linear-gradient(top, #4A90E2 0%, #3483de 100%);\n background-image: linear-gradient(to bottom, #4A90E2 0%, #3483de 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4a90e2', endColorstr='#ff3483de', GradientType=0);\n background-color: #3483de;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #4A90E2 0%, #3483de 100%);\n background-image: -o-linear-gradient(top, #4A90E2 0%, #3483de 100%);\n background-image: linear-gradient(to bottom, #4A90E2 0%, #3483de 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4a90e2', endColorstr='#ff3483de', GradientType=0);\n }\n}\n.alert {\n border: none;\n}\n.alert-success {\n background-color: #8CC04F;\n color: white;\n border-radius: 3px;\n}\n.alert-info {\n background-color: #4C9BD5;\n color: white;\n border-radius: 3px;\n}\n.alert-warning {\n background-color: #F6B44B;\n color: white;\n border-radius: 3px;\n}\n.alert-danger {\n background-color: #D54C53;\n color: white;\n border-radius: 3px;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #95bcef 0%, #a7c7f2 100%);\n background-image: -o-linear-gradient(top, #95bcef 0%, #a7c7f2 100%);\n background-image: linear-gradient(to bottom, #95bcef 0%, #a7c7f2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff95bcef', endColorstr='#ffa7c7f2', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #4A90E2 0%, #2275d7 100%);\n background-image: -o-linear-gradient(top, #4A90E2 0%, #2275d7 100%);\n background-image: linear-gradient(to bottom, #4A90E2 0%, #2275d7 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4a90e2', endColorstr='#ff2275d7', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #78b037 0%, #5e892b 100%);\n background-image: -o-linear-gradient(top, #78b037 0%, #5e892b 100%);\n background-image: linear-gradient(to bottom, #78b037 0%, #5e892b 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff78b037', endColorstr='#ff5e892b', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #3a70b0 0%, #2d588a 100%);\n background-image: -o-linear-gradient(top, #3a70b0 0%, #2d588a 100%);\n background-image: linear-gradient(to bottom, #3a70b0 0%, #2d588a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3a70b0', endColorstr='#ff2d588a', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #F5A623 0%, #db8c0a 100%);\n background-image: -o-linear-gradient(top, #F5A623 0%, #db8c0a 100%);\n background-image: linear-gradient(to bottom, #F5A623 0%, #db8c0a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5a623', endColorstr='#ffdb8c0a', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d54c53 0%, #c12d35 100%);\n background-image: -o-linear-gradient(top, #d54c53 0%, #c12d35 100%);\n background-image: linear-gradient(to bottom, #d54c53 0%, #c12d35 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd54c53', endColorstr='#ffc12d35', GradientType=0);\n}\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #2275d7;\n background-image: -webkit-linear-gradient(top, #4A90E2 0%, #297cdd 100%);\n background-image: -o-linear-gradient(top, #4A90E2 0%, #297cdd 100%);\n background-image: linear-gradient(to bottom, #4A90E2 0%, #297cdd 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4a90e2', endColorstr='#ff297cdd', GradientType=0);\n border-color: #297cdd;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-color: #f5f5f5;\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n color: white;\n border: inherit;\n}\n.panel-primary > .panel-heading {\n background-color: #4A90E2;\n background-image: -webkit-linear-gradient(top, #4A90E2 0%, #3483de 100%);\n background-image: -o-linear-gradient(top, #4A90E2 0%, #3483de 100%);\n background-image: linear-gradient(to bottom, #4A90E2 0%, #3483de 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4a90e2', endColorstr='#ff3483de', GradientType=0);\n color: white;\n border: inherit;\n}\n.panel-success > .panel-heading {\n background-color: #8CC04F;\n background-image: -webkit-linear-gradient(top, #8CC04F 0%, #7fb541 100%);\n background-image: -o-linear-gradient(top, #8CC04F 0%, #7fb541 100%);\n background-image: linear-gradient(to bottom, #8CC04F 0%, #7fb541 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff8cc04f', endColorstr='#ff7fb541', GradientType=0);\n color: white;\n border: inherit;\n}\n.panel-info > .panel-heading {\n background-color: #4C9BD5;\n background-image: -webkit-linear-gradient(top, #4C9BD5 0%, #378fd0 100%);\n background-image: -o-linear-gradient(top, #4C9BD5 0%, #378fd0 100%);\n background-image: linear-gradient(to bottom, #4C9BD5 0%, #378fd0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4c9bd5', endColorstr='#ff378fd0', GradientType=0);\n color: white;\n border: inherit;\n}\n.panel-warning > .panel-heading {\n background-color: #F6B44B;\n background-image: -webkit-linear-gradient(top, #F6B44B 0%, #f5aa33 100%);\n background-image: -o-linear-gradient(top, #F6B44B 0%, #f5aa33 100%);\n background-image: linear-gradient(to bottom, #F6B44B 0%, #f5aa33 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff6b44b', endColorstr='#fff5aa33', GradientType=0);\n color: white;\n border: inherit;\n}\n.panel-danger > .panel-heading {\n background-color: #D54C53;\n background-image: -webkit-linear-gradient(top, #D54C53 0%, #d0373f 100%);\n background-image: -o-linear-gradient(top, #D54C53 0%, #d0373f 100%);\n background-image: linear-gradient(to bottom, #D54C53 0%, #d0373f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd54c53', endColorstr='#ffd0373f', GradientType=0);\n color: white;\n border: inherit;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-primary {\n border-color: #4A90E2;\n}\n.panel-success {\n border-color: #93b541;\n}\n.panel-info {\n border-color: #30a5cd;\n}\n.panel-warning {\n border-color: #f58a33;\n}\n.panel-danger {\n border-color: #d03759;\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n.log-header {\n font-family: \"LatoLatinWeb\", \"Lato\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 5px;\n}\n.log-header__section {\n display: flex;\n align-items: center;\n}\n.log-header__section a {\n padding-left: 10px;\n}\n.download-log-button {\n cursor: pointer;\n opacity: 0.87000002;\n}\ncode {\n font-family: \"Source Code Pro\", Menlo, Monaco, Consolas, \"Courier New\", monospace;\n width: 100%;\n min-height: 12px;\n border: 1px solid #ccc;\n border-radius: 4px;\n position: relative;\n counter-reset: line;\n font-size: 1.2rem;\n}\ncode p:hover {\n background-color: #444 !important;\n}\ncode p {\n counter-increment: line;\n margin: 0;\n display: flex;\n align-items: baseline;\n}\ncode p::nth-line {\n color: yellow !important;\n}\ncode p a {\n margin: 0;\n padding: 0 15px 0 20px;\n word-break: break-all;\n display: inline;\n color: #f5f5f5;\n}\ncode a:hover {\n color: #f5f5f5;\n text-decoration: none;\n}\ncode p::before {\n color: #777777;\n content: counter(line);\n min-width: 35px;\n white-space: nowrap;\n padding-right: 1em;\n padding-left: 10px;\n text-align: right;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\ncode.block {\n background-color: #333333;\n color: #f5f5f5;\n display: block;\n padding: 0.5rem;\n border: solid 1px #000000;\n white-space: pre-wrap;\n}\ncode.inline {\n display: inline-block;\n padding: inherit;\n white-space: pre-wrap;\n}\ncode.hash {\n border: 0;\n font-size: 1.4rem;\n}\n.material-icons {\n color: #4A90E2;\n}\n.material-icons.selected {\n color: #F5A623;\n}\n.u-flex-grow {\n flex-grow: 1;\n}\nmain article {\n width: 100%;\n max-width: 1200px;\n margin-left: auto;\n margin-right: auto;\n padding-right: 15px;\n padding-left: 15px;\n padding-top: 1rem;\n padding-bottom: 1rem;\n}\n.container-fluid {\n padding: 0;\n}\nfooter {\n text-align: center;\n margin: 1em;\n}\n.overlayStyles {\n position: fixed;\n display: block;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n zIndex: 99;\n background-color: rgba(0, 0, 0, 0.3);\n}\n.dialog {\n width: 100%;\n height: 100%;\n min-width: 640px;\n position: fixed;\n top: 0;\n left: 0;\n display: flex;\n flex-direction: column;\n background-color: #fff;\n border-radius: 2px;\n z-index: 100;\n box-shadow: 0 0 4px rgba(0, 0, 0, 0.14), 0 4px 8px rgba(0, 0, 0, 0.28);\n}\n.expand-in-appear {\n -webkit-transition: all ease-out 0.15s;\n -o-transition: all ease-out 0.15s;\n transition: all ease-out 0.15s;\n top: 4%;\n opacity: 0.01;\n transform: scale(0.96);\n}\n.expand-in-appear.expand-in-appear-active {\n top: 0;\n opacity: 1;\n transform: scale(1);\n}\n.expand-in-leave {\n -webkit-transition: all ease-out 0.1s;\n -o-transition: all ease-out 0.1s;\n transition: all ease-out 0.1s;\n top: 0;\n opacity: 1;\n transform: scale(1);\n}\n.expand-in-leave.expand-in-leave-active {\n top: 4%;\n opacity: 0.01;\n transform: scale(0.96);\n}\n.slideup-appear {\n -webkit-transition: all ease-out 0.3s;\n -o-transition: all ease-out 0.3s;\n transition: all ease-out 0.3s;\n top: 75%;\n opacity: 0.01;\n}\n.slideup-appear.slideup-appear-active {\n top: 0;\n opacity: 1;\n}\n.slideup-leave {\n -webkit-transition: all ease-out 0.3s;\n -o-transition: all ease-out 0.3s;\n transition: all ease-out 0.3s;\n top: 0;\n opacity: 1;\n}\n.slideup-leave.slideup-leave-active {\n top: 75%;\n opacity: 0.01;\n}\n.fadein-appear {\n -webkit-transition: opacity ease-out 1s;\n -o-transition: opacity ease-out 1s;\n transition: opacity ease-out 1s;\n opacity: 0.01;\n}\n.fadein-appear.fadein-appear-active {\n opacity: 1;\n}\n.dialog .header {\n color: #ffffff;\n font-weight: normal;\n line-height: 20px;\n font-size: 1.6rem;\n}\n.dialog .header-content {\n padding: 0 50px 0 50px;\n}\n.dialog .header.success {\n background-color: #78b037;\n}\n.dialog .header.failure {\n background-color: #d54c53;\n}\n.dialog .header.unstable {\n background-color: #F5A623;\n}\n.dialog .header.info,\n.dialog .header.running {\n background-color: #3a70b0;\n}\n.dialog .header.not_built {\n background-color: #4A4A4A;\n}\n.dialog .header.queued,\n.dialog .header.aborted {\n background-color: #949393;\n}\n.dialog .header.paused {\n background-color: #24B0D5;\n}\n.dialog .header.unknown {\n background-color: #bd0fe1;\n}\n.dialog .content {\n width: 100%;\n height: 100%;\n overflow-y: auto;\n padding: 25px 50px 25px 50px;\n background-color: #fff;\n}\n.header .title {\n margin-top: 0;\n}\n.header .closeButton {\n cursor: pointer;\n text-decoration: none;\n position: absolute;\n font-size: 3em;\n color: #ffffff;\n right: 10px;\n top: 10px;\n}\n.spin {\n -webkit-animation-name: spin;\n -webkit-animation-duration: 4000ms;\n -webkit-animation-iteration-count: infinite;\n -webkit-animation-timing-function: linear;\n -moz-animation-name: spin;\n -moz-animation-duration: 4000ms;\n -moz-animation-iteration-count: infinite;\n -moz-animation-timing-function: linear;\n -ms-animation-name: spin;\n -ms-animation-duration: 4000ms;\n -ms-animation-iteration-count: infinite;\n -ms-animation-timing-function: linear;\n animation-name: spin;\n animation-duration: 4000ms;\n animation-iteration-count: infinite;\n animation-timing-function: linear;\n}\n@-ms-keyframes spin {\n from {\n -ms-transform: rotate(0deg);\n }\n to {\n -ms-transform: rotate(360deg);\n }\n}\n@-moz-keyframes spin {\n from {\n -moz-transform: rotate(0deg);\n }\n to {\n -moz-transform: rotate(360deg);\n }\n}\n@-webkit-keyframes spin {\n from {\n -webkit-transform: rotate(0deg);\n }\n to {\n -webkit-transform: rotate(360deg);\n }\n}\n@keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n.left {\n float: left;\n}\n.right {\n float: right;\n}\n.clickIndicator {\n cursor: pointer;\n}\n.Site {\n display: flex;\n min-height: 100vh;\n flex-direction: column;\n}\n#outer {\n flex: 1;\n}\n.development-footer {\n padding-bottom: 10px;\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n color: #777777;\n}\n\n/*# sourceMappingURL=jenkins-design-language.css.map */\n"},"redirectURL":null,"headersSize":300,"bodySize":17601},"serverIPAddress":"184.106.4.69","cache":{},"timings":{"dns":-1,"connect":-1,"ssl":-1,"send":2,"wait":71,"receive":68}},{"startedDateTime":"2017-03-23T09:47:02.751-04:00","time":129,"request":{"method":"GET","url":"https://jenkins.madmobile.com/static/9d9967fa/plugin/blueocean-web/assets/corejs/css/blueocean-core-js.css","httpVersion":"HTTP/1.1","cookies":[{"name":"JSESSIONID.07665201","value":"jvj7v811ia6a24xswzx3mx84"},{"name":"m.tickets.com","value":"285266442.36895.0000"},{"name":"JSESSIONID.671a2176","value":"7x7hbwsd1udpfluq5aqttf77"},{"name":"_ga","value":"GA1.2.1568028303.1489761292"},{"name":"__hstc","value":"155897444.2001d13d16178aaccc25d25d70c2dbbc.1490035088857.1490035088857.1490035088857.1"},{"name":"__hssrc","value":"1"},{"name":"hubspotutk","value":"2001d13d16178aaccc25d25d70c2dbbc"},{"name":"JSESSIONID.e58ba09b","value":"1ui3v5lrs0po81jdt31ywi97wa"},{"name":"JSESSIONID.176688ac","value":"1qf3qt3u78nxy1c80vpergut8j"},{"name":"screenResolution","value":"1920x1200"},{"name":"JSESSIONID.630fb4ae","value":"14o29p0lzolb3ei79cn6vxnb6"}],"headers":[{"name":"Host","value":"jenkins.madmobile.com"},{"name":"Connection","value":"keep-alive"},{"name":"Pragma","value":"no-cache"},{"name":"Cache-Control","value":"no-cache"},{"name":"User-Agent","value":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3047.0 Safari/537.36"},{"name":"Accept","value":"text/css,*/*;q=0.1"},{"name":"Referer","value":"https://jenkins.madmobile.com/blue/organizations/jenkins/Concierge%2FConcierge%20Internal%20Build/detail/Concierge%20Internal%20Build/16/tests/"},{"name":"Accept-Encoding","value":"gzip, deflate, sdch, br"},{"name":"Accept-Language","value":"en-US,en;q=0.8"},{"name":"Cookie","value":"JSESSIONID.07665201=jvj7v811ia6a24xswzx3mx84; m.tickets.com=285266442.36895.0000; JSESSIONID.671a2176=7x7hbwsd1udpfluq5aqttf77; _ga=GA1.2.1568028303.1489761292; __hstc=155897444.2001d13d16178aaccc25d25d70c2dbbc.1490035088857.1490035088857.1490035088857.1; __hssrc=1; hubspotutk=2001d13d16178aaccc25d25d70c2dbbc; JSESSIONID.e58ba09b=1ui3v5lrs0po81jdt31ywi97wa; JSESSIONID.176688ac=1qf3qt3u78nxy1c80vpergut8j; screenResolution=1920x1200; JSESSIONID.630fb4ae=14o29p0lzolb3ei79cn6vxnb6"}],"queryString":[],"headersSize":1071,"bodySize":0},"response":{"_charlesStatus":"COMPLETE","status":200,"statusText":"OK","httpVersion":"HTTP/1.1","cookies":[],"headers":[{"name":"Date","value":"Thu, 23 Mar 2017 13:47:02 GMT"},{"name":"X-Content-Type-Options","value":"nosniff"},{"name":"Cache-Control","value":"public, max-age=31536000"},{"name":"Last-Modified","value":"Wed, 15 Mar 2017 01:13:34 GMT"},{"name":"Accept-Ranges","value":"bytes"},{"name":"Content-Type","value":"text/css"},{"name":"Content-Encoding","value":"gzip"},{"name":"Content-Length","value":"907"},{"name":"Server","value":"Jetty(9.2.z-SNAPSHOT)"},{"name":"Connection","value":"Keep-alive"}],"content":{"size":4632,"compression":3725,"mimeType":"text/css","text":".replay-button-component {\n display: inline-block;\n}\n.replay-button-component .replay-button {\n display: inline-block;\n cursor: pointer;\n}\n.replay-button-component .svg-icon {\n display: none;\n}\n.replay-button-component.icon-button {\n height: 24px;\n}\n.replay-button-component.icon-button .replay-button {\n width: 24px;\n height: 24px;\n background: transparent;\n border: 0;\n position: relative;\n}\n.replay-button-component.icon-button .replay-button .svg-icon {\n display: block;\n position: absolute;\n top: 0;\n left: 0;\n}\n.replay-button-component.icon-button .button-label {\n display: none;\n}\n.replay-button-component .svg-icon {\n fill: #4A90E2;\n}\n.replay-button-component .svg-icon:hover {\n fill: #1C436A;\n}\n.replay-button-component.dark .btn {\n background: transparent;\n color: white;\n border-color: white;\n}\n.replay-button-component.dark .svg-icon {\n fill: white;\n}\n.replay-button-component.dark .svg-icon:hover {\n fill: #CCC;\n}\n.run-button-component {\n display: inline-block;\n}\n.run-button-component .run-button,\n.run-button-component .stop-button {\n display: inline-block;\n cursor: pointer;\n}\n.run-button-component .svg-icon {\n display: none;\n}\n.run-button-component.icon-button {\n height: 24px;\n}\n.run-button-component.icon-button .run-button,\n.run-button-component.icon-button .stop-button {\n width: 24px;\n height: 24px;\n background: transparent;\n border: 0;\n position: relative;\n}\n.run-button-component.icon-button .run-button .svg-icon,\n.run-button-component.icon-button .stop-button .svg-icon {\n display: block;\n position: absolute;\n top: 0;\n left: 0;\n}\n.run-button-component.icon-button .stop-button {\n /* asset has different padding than material-icon asset used in .run-button: nudge it slightly */\n top: 2px;\n left: 2px;\n}\n.run-button-component.icon-button .stop-button.stopping {\n opacity: 0.4;\n cursor: auto;\n}\n.run-button-component.icon-button .button-label {\n display: none;\n}\n.run-button-component .svg-icon,\n.run-button-component .svg-icon-inner {\n fill: #4A90E2;\n}\n.run-button-component .svg-icon:hover {\n fill: #1C436A;\n}\n.run-button-component .svg-icon:hover .svg-icon-inner {\n fill: #1C436A;\n}\n.run-button-component.dark .btn {\n background: transparent;\n color: white;\n border-color: white;\n}\n.run-button-component.dark .svg-icon,\n.run-button-component.dark .svg-icon-inner {\n fill: white;\n}\n.run-button-component.dark .svg-icon:hover {\n fill: #CCC;\n}\n.run-button-component.dark .svg-icon:hover .svg-icon-inner {\n fill: #CCC;\n}\n.BlueOceanLogo,\n.BlueOceanLogo:hover {\n display: flex;\n color: white;\n text-decoration: none;\n align-items: center;\n font-size: 18px;\n position: relative;\n top: -1px;\n}\n.BlueOceanLogo svg,\n.BlueOceanLogo:hover svg {\n height: 20px;\n fill: white;\n top: 1px;\n position: relative;\n}\n.ContentPageHeader,\n.ResultPageHeader {\n color: white;\n}\n.ContentPageHeader a,\n.ResultPageHeader a,\n.ContentPageHeader a:hover,\n.ResultPageHeader a:hover {\n color: white;\n}\n.ContentPageHeader-user {\n display: flex;\n height: 100%;\n padding-left: 1em;\n}\n.ContentPageHeader-user * {\n margin-left: 1em;\n}\n.ContentPageHeader-user .btn-sign-in {\n background: none;\n min-width: 0;\n border-color: rgba(0, 0, 0, 0);\n}\n.ContentPageHeader-user .btn-sign-in:hover {\n border-color: white;\n}\n.ContentPageHeader-user .btn-sign-up {\n background: none;\n min-width: 0;\n border-color: white;\n}\n.ContentPageHeader-user .user-component {\n display: inline-block;\n align-items: center;\n height: 100%;\n}\n.ContentPageHeader-user .user-component.icon {\n padding-top: 13px;\n}\n.ContentPageHeader-user .user-component.icon svg {\n fill: white;\n width: 24px;\n height: 24px;\n}\n.ContentPageHeader-user .user-component.button-bar {\n padding-top: 11px;\n}\n.ResultPageHeader-run {\n padding-left: 1em;\n display: flex;\n align-items: center;\n}\n.ResultPageHeader-run > * + * {\n margin-left: 1em;\n}\n.ResultPageHeader-run button {\n min-width: 0;\n color: white;\n border-color: white;\n}\n.ResultPageHeader-run button:hover {\n color: white;\n border-color: white;\n}\n.ContentPageHeader-main,\n.ResultPageHeader-main {\n display: flex;\n align-items: center;\n height: 100%;\n}\n.ContentPageHeader-main > * + *,\n.ResultPageHeader-main > * + * {\n margin-left: 10px;\n}\n.ResultPageHeader-indicator {\n margin-right: 10px;\n height: 24px;\n}\n.ResultPageHeader-title {\n display: flex;\n align-items: center;\n}\n.ResultPageHeader-title a {\n text-decoration: underline;\n}\n.ResultPageHeader-close {\n margin-left: 24px;\n cursor: pointer;\n stroke: none;\n fill: white;\n}\n.ResultPageHeader-close:hover {\n stroke: white;\n}\n\n/*# sourceMappingURL=blueocean-core-js.css.map */\n"},"redirectURL":null,"headersSize":298,"bodySize":907},"serverIPAddress":"184.106.4.69","cache":{},"timings":{"dns":-1,"connect":-1,"ssl":-1,"send":2,"wait":126,"receive":1}},{"startedDateTime":"2017-03-23T09:47:03.085-04:00","time":1095,"request":{"method":"GET","url":"https://jenkins.madmobile.com/adjuncts/9d9967fa/io/jenkins/blueocean/blueocean.js","httpVersion":"HTTP/1.1","cookies":[{"name":"JSESSIONID.07665201","value":"jvj7v811ia6a24xswzx3mx84"},{"name":"m.tickets.com","value":"285266442.36895.0000"},{"name":"JSESSIONID.671a2176","value":"7x7hbwsd1udpfluq5aqttf77"},{"name":"_ga","value":"GA1.2.1568028303.1489761292"},{"name":"__hstc","value":"155897444.2001d13d16178aaccc25d25d70c2dbbc.1490035088857.1490035088857.1490035088857.1"},{"name":"__hssrc","value":"1"},{"name":"hubspotutk","value":"2001d13d16178aaccc25d25d70c2dbbc"},{"name":"JSESSIONID.e58ba09b","value":"1ui3v5lrs0po81jdt31ywi97wa"},{"name":"JSESSIONID.176688ac","value":"1qf3qt3u78nxy1c80vpergut8j"},{"name":"screenResolution","value":"1920x1200"},{"name":"JSESSIONID.630fb4ae","value":"14o29p0lzolb3ei79cn6vxnb6"}],"headers":[{"name":"Host","value":"jenkins.madmobile.com"},{"name":"Connection","value":"keep-alive"},{"name":"Pragma","value":"no-cache"},{"name":"Cache-Control","value":"no-cache"},{"name":"User-Agent","value":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3047.0 Safari/537.36"},{"name":"Accept","value":"*/*"},{"name":"Referer","value":"https://jenkins.madmobile.com/blue/organizations/jenkins/Concierge%2FConcierge%20Internal%20Build/detail/Concierge%20Internal%20Build/16/tests/"},{"name":"Accept-Encoding","value":"gzip, deflate, sdch, br"},{"name":"Accept-Language","value":"en-US,en;q=0.8"},{"name":"Cookie","value":"JSESSIONID.07665201=jvj7v811ia6a24xswzx3mx84; m.tickets.com=285266442.36895.0000; JSESSIONID.671a2176=7x7hbwsd1udpfluq5aqttf77; _ga=GA1.2.1568028303.1489761292; __hstc=155897444.2001d13d16178aaccc25d25d70c2dbbc.1490035088857.1490035088857.1490035088857.1; __hssrc=1; hubspotutk=2001d13d16178aaccc25d25d70c2dbbc; JSESSIONID.e58ba09b=1ui3v5lrs0po81jdt31ywi97wa; JSESSIONID.176688ac=1qf3qt3u78nxy1c80vpergut8j; screenResolution=1920x1200; JSESSIONID.630fb4ae=14o29p0lzolb3ei79cn6vxnb6"}],"queryString":[],"headersSize":1031,"bodySize":0},"response":{"_charlesStatus":"COMPLETE","status":200,"statusText":"OK","httpVersion":"HTTP/1.1","cookies":[],"headers":[{"name":"Date","value":"Thu, 23 Mar 2017 13:47:03 GMT"},{"name":"X-Content-Type-Options","value":"nosniff"},{"name":"Cache-Control","value":"public, max-age=31536000"},{"name":"Last-Modified","value":"Wed, 15 Mar 2017 01:13:34 GMT"},{"name":"Accept-Ranges","value":"bytes"},{"name":"Content-Type","value":"application/javascript"},{"name":"Content-Encoding","value":"gzip"},{"name":"Server","value":"Jetty(9.2.z-SNAPSHOT)"},{"name":"Transfer-Encoding","value":"chunked"},{"name":"Connection","value":"Keep-alive"}],"content":{"size":3906215,"compression":3042909,"mimeType":"application/javascript","text":"KGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT0iZnVuY3Rpb24iJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKCJDYW5ub3QgZmluZCBtb2R1bGUgJyIrbysiJyIpO3Rocm93IGYuY29kZT0iTU9EVUxFX05PVF9GT1VORCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT0iZnVuY3Rpb24iJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSh7MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgovKioKICogU2ltcGxlIGNvbXBvbmVudCB0byByZW5kZXIgYSBmdWxsLXBhZ2Ugb3ZlcmxheSB3aXRob3V0IGFueSBkZWNvcmF0aW9uCiAqLwp2YXIgRnVsbHNjcmVlbiA9IGZ1bmN0aW9uIEZ1bGxzY3JlZW4oX3JlZikgewogICAgdmFyIGNsYXNzTmFtZSA9IF9yZWYuY2xhc3NOYW1lLAogICAgICAgIGNoaWxkcmVuID0gX3JlZi5jaGlsZHJlbjsKICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAnZGl2JywKICAgICAgICB7IGNsYXNzTmFtZTogJ2Z1bGxzY3JlZW4gJyArIGNsYXNzTmFtZSB9LAogICAgICAgIGNoaWxkcmVuCiAgICApOwp9OwoKRnVsbHNjcmVlbi5wcm9wVHlwZXMgPSB7CiAgICBjbGFzc05hbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgY2hpbGRyZW46IF9yZWFjdC5Qcm9wVHlwZXMuYW55Cn07CgpleHBvcnRzLmRlZmF1bHQgPSBGdWxsc2NyZWVuOwp9LHsicmVhY3QiOjYyM31dLDI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKCmZ1bmN0aW9uIF90b0NvbnN1bWFibGVBcnJheShhcnIpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgeyBmb3IgKHZhciBpID0gMCwgYXJyMiA9IEFycmF5KGFyci5sZW5ndGgpOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7IGFycjJbaV0gPSBhcnJbaV07IH0gcmV0dXJuIGFycjI7IH0gZWxzZSB7IHJldHVybiBBcnJheS5mcm9tKGFycik7IH0gfQoKLyoqCiAqIFRoaXMgY29udGFpbnMgYSBiaXQgdGhhdCByZXVzZXMgdGhlIGluZGV4LmplbGx5IHByb2dyZXNzIGJhcgogKiBzbyBSZWFjdCBjb21wb25lbnRzIGNhbiBqdXN0IGFkZCBhIDxQYWdlTG9hZGluZy8+IGluZGljYXRvciwKICogYW5kIG92ZXJsYXBwaW5nIGxvYWRpbmcgc2hvdWxkIGp1c3QgZXh0ZW5kIHRoZSB0aW1lLCBldGMuCiAqLwp2YXIgbG9hZGluZ0NvdW50ID0gMDsKdmFyIHRpbWVvdXRzID0gW107CgovLyB1c2UgYSBzaG9ydCB0aW1lb3V0IHNvIGZhc3QgY29ubmVjdGlvbnMgYXJlbid0IHNlZWluZwovLyBmbGFzaGVzIG9mIHRoZSBwcm9ncmVzcyBiYXIgYWxsIHRoZSB0aW1lCnZhciBkZWxheSA9IDM1MDsKdmFyIGxvYWRiYXIgPSB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2FkYmFyJyk7CgovKioKICogUmVtb3ZlIHF1ZXVlZCBwcm9ncmVzcyBhZGRpdGlvbnMKICovCmZ1bmN0aW9uIGNsZWFyVGltZW91dHMoKSB7CiAgICB3aGlsZSAodGltZW91dHMubGVuZ3RoKSB7CiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRzLnBvcCgpKTsKICAgIH0KfQoKLyoqCiAqIEFkZCBhIHRpbWVvdXQgdG8gdHJhbnNpdGlvbiB0aGUgbG9hZGluZyBhbmltYXRpb24gZGlmZmVyZW50bHkKICovCmZ1bmN0aW9uIHNldExvYWRlckNsYXNzKGMsIHQpIHsKICAgIHRpbWVvdXRzLnB1c2goc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgbG9hZGJhci5jbGFzc0xpc3QuYWRkKGMpOwogICAgfSwgdCkpOwp9CgovKioKICogU2ltcGxlIG1vc3RseSBjc3MtYmFzZWQgbG9hZGluZyBhbmltYXRpb24KICovCmV4cG9ydHMuZGVmYXVsdCA9IHsKICAgIHNob3c6IGZ1bmN0aW9uIHNob3coKSB7CiAgICAgICAgaWYgKGxvYWRiYXIpIHsKICAgICAgICAgICAgaWYgKGxvYWRpbmdDb3VudCA9PT0gMCkgewogICAgICAgICAgICAgICAgLy8gKHJlKXN0YXJ0IHRoZSBsb2FkaW5nIGFuaW1hdGlvbgogICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0cygpOwogICAgICAgICAgICAgICAgbG9hZGJhci5jbGFzc0xpc3QucmVtb3ZlKCdjb21wbGV0ZScpOwogICAgICAgICAgICAgICAgc2V0TG9hZGVyQ2xhc3MoJ2dvJywgZGVsYXkpOyAvLyB0aGVzZSB0aW1lcyBuZWVkIHRvIG1hdGNoIHRoZSBpbmRleC5qZWxseSBDU1MgZGVmaW5pdGlvbnMKICAgICAgICAgICAgICAgIHNldExvYWRlckNsYXNzKCdsb25nJywgZGVsYXkgKyAxMDAwKTsKICAgICAgICAgICAgICAgIHNldExvYWRlckNsYXNzKCdsb25nZXInLCBkZWxheSArIDYwMDApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxvYWRpbmdDb3VudCsrOwogICAgICAgIH0KICAgIH0sCiAgICBoaWRlOiBmdW5jdGlvbiBoaWRlKCkgewogICAgICAgIGlmIChsb2FkYmFyKSB7CiAgICAgICAgICAgIGlmIChsb2FkaW5nQ291bnQgPiAwKSB7CiAgICAgICAgICAgICAgICBsb2FkaW5nQ291bnQtLTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGxvYWRpbmdDb3VudCA9PT0gMCkgewogICAgICAgICAgICAgICAgLy8gc3RvcCB0aGUgbG9hZGluZyBhbmltYXRpb24KICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dHMoKTsKICAgICAgICAgICAgICAgIHNldExvYWRlckNsYXNzKCdjb21wbGV0ZScsIDEwKTsKICAgICAgICAgICAgICAgIHRpbWVvdXRzLnB1c2goc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIEVsZW1lbnQuY2xhc3NMaXN0IGlzIGEgcmVhZC1vbmx5IHByb3BlcnR5CiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzTGlzdCA9IGxvYWRiYXIuY2xhc3NMaXN0OwogICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc0xpc3QgJiYgY2xhc3NMaXN0Lmxlbmd0aCAmJiBjbGFzc0xpc3QubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgYWxsIGl0ZW1zIC0gY29tcGF0aWJsZSB3aXRoIG9sZGVyIGJyb3dzZXIKICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NMaXN0LnJlbW92ZS5hcHBseShjbGFzc0xpc3QsIFtdLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkoY2xhc3NMaXN0KSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sIDUwMCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwKCgogICAgLy8gVE9ETyBzaG91bGQgbWFrZSB0aGlzIGEgc3RhY2sgdG8gcHVzaC9wb3AKICAgIHNldERhcmtCYWNrZ3JvdW5kOiBmdW5jdGlvbiBzZXREYXJrQmFja2dyb3VuZCgpIHsKICAgICAgICBpZiAobG9hZGJhcikgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2JvZHknKVswXS5jbGFzc0xpc3QuYWRkKCdsb2FkYmFyLWxpZ2h0Jyk7CiAgICB9LAogICAgc2V0TGlnaHRCYWNrZ3JvdW5kOiBmdW5jdGlvbiBzZXRMaWdodEJhY2tncm91bmQoKSB7CiAgICAgICAgaWYgKGxvYWRiYXIpIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdib2R5JylbMF0uY2xhc3NMaXN0LnJlbW92ZSgnbG9hZGJhci1saWdodCcpOwogICAgfQp9Owp9LHt9XSwzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9GdWxsc2NyZWVuID0gcmVxdWlyZSgnLi9GdWxsc2NyZWVuJyk7Cgp2YXIgX0Z1bGxzY3JlZW4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfRnVsbHNjcmVlbik7Cgp2YXIgX3JlYWN0Um91dGVyID0gcmVxdWlyZSgncmVhY3Qtcm91dGVyJyk7Cgp2YXIgX2kxOG4gPSByZXF1aXJlKCcuL2kxOG4vaTE4bicpOwoKdmFyIF9pMThuMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2kxOG4pOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCnZhciB0cmFuc2xhdGUgPSAoMCwgX2kxOG4yLmRlZmF1bHQpKCdibHVlb2NlYW4td2ViJyk7CgovKioKICogU2ltcGxlIGNvbXBvbmVudCB0byByZW5kZXIgYSBmdWxsc2NyZWVuIDQwNCBwYWdlCiAqLwoKZXhwb3J0cy5kZWZhdWx0ID0gZnVuY3Rpb24gKCkgewogICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgIF9GdWxsc2NyZWVuMi5kZWZhdWx0LAogICAgICAgIHsgY2xhc3NOYW1lOiAnZXJyb3JzY3JlZW4gbm90LWZvdW5kJyB9LAogICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdtZXNzYWdlLWJveCcgfSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnaDMnLAogICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgIHRyYW5zbGF0ZSgnTm90LmZvdW5kLmhlYWRpbmcnLCB7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAnUGFnZSBub3QgZm91bmQgKDQwNCknCiAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICApLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdtZXNzYWdlJyB9LAogICAgICAgICAgICAgICAgdHJhbnNsYXRlKCdOb3QuZm91bmQubWVzc2FnZScsIHsgZGVmYXVsdFZhbHVlOiAnSmVua2lucyBjb3VsZCBub3QgZmluZCB0aGUgcGFnZSB5b3Ugd2VyZSBsb29raW5nIGZvci4gQ2hlY2sgdGhlIFVSTCBmb3IgZXJyb3JzIG9yIHByZXNzIHRoZSBiYWNrIGJ1dHRvbi4nIH0pCiAgICAgICAgICAgICksCiAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2FjdGlvbnMnIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICBfcmVhY3RSb3V0ZXIuTGluaywKICAgICAgICAgICAgICAgICAgICB7IHRvOiAnLycsIGNsYXNzTmFtZTogJ2J0bicgfSwKICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGUoJ09wZW4uZGFzaGJvYXJkJywgeyBkZWZhdWx0VmFsdWU6ICdPcGVuIERhc2hib2FyZCcgfSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKQogICAgICAgICkKICAgICk7Cn07Cn0seyIuL0Z1bGxzY3JlZW4iOjEsIi4vaTE4bi9pMThuIjoyNCwicmVhY3QiOjYyMywicmVhY3Qtcm91dGVyIjo0Njh9XSw0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuVG9hc3RTZXJ2aWNlID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX2Rlc2MsIF92YWx1ZSwgX2NsYXNzLCBfZGVzY3JpcHRvcjsgLyoqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBDcmVhdGVkIGJ5IGNtZXllcnMgb24gOC8xOC8xNi4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwoKCnZhciBfbW9ieCA9IHJlcXVpcmUoJ21vYngnKTsKCmZ1bmN0aW9uIF9pbml0RGVmaW5lUHJvcCh0YXJnZXQsIHByb3BlcnR5LCBkZXNjcmlwdG9yLCBjb250ZXh0KSB7CiAgICBpZiAoIWRlc2NyaXB0b3IpIHJldHVybjsKICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCB7CiAgICAgICAgZW51bWVyYWJsZTogZGVzY3JpcHRvci5lbnVtZXJhYmxlLAogICAgICAgIGNvbmZpZ3VyYWJsZTogZGVzY3JpcHRvci5jb25maWd1cmFibGUsCiAgICAgICAgd3JpdGFibGU6IGRlc2NyaXB0b3Iud3JpdGFibGUsCiAgICAgICAgdmFsdWU6IGRlc2NyaXB0b3IuaW5pdGlhbGl6ZXIgPyBkZXNjcmlwdG9yLmluaXRpYWxpemVyLmNhbGwoY29udGV4dCkgOiB2b2lkIDAKICAgIH0pOwp9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IodGFyZ2V0LCBwcm9wZXJ0eSwgZGVjb3JhdG9ycywgZGVzY3JpcHRvciwgY29udGV4dCkgewogICAgdmFyIGRlc2MgPSB7fTsKICAgIE9iamVjdFsna2UnICsgJ3lzJ10oZGVzY3JpcHRvcikuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7CiAgICAgICAgZGVzY1trZXldID0gZGVzY3JpcHRvcltrZXldOwogICAgfSk7CiAgICBkZXNjLmVudW1lcmFibGUgPSAhIWRlc2MuZW51bWVyYWJsZTsKICAgIGRlc2MuY29uZmlndXJhYmxlID0gISFkZXNjLmNvbmZpZ3VyYWJsZTsKCiAgICBpZiAoJ3ZhbHVlJyBpbiBkZXNjIHx8IGRlc2MuaW5pdGlhbGl6ZXIpIHsKICAgICAgICBkZXNjLndyaXRhYmxlID0gdHJ1ZTsKICAgIH0KCiAgICBkZXNjID0gZGVjb3JhdG9ycy5zbGljZSgpLnJldmVyc2UoKS5yZWR1Y2UoZnVuY3Rpb24gKGRlc2MsIGRlY29yYXRvcikgewogICAgICAgIHJldHVybiBkZWNvcmF0b3IodGFyZ2V0LCBwcm9wZXJ0eSwgZGVzYykgfHwgZGVzYzsKICAgIH0sIGRlc2MpOwoKICAgIGlmIChjb250ZXh0ICYmIGRlc2MuaW5pdGlhbGl6ZXIgIT09IHZvaWQgMCkgewogICAgICAgIGRlc2MudmFsdWUgPSBkZXNjLmluaXRpYWxpemVyID8gZGVzYy5pbml0aWFsaXplci5jYWxsKGNvbnRleHQpIDogdm9pZCAwOwogICAgICAgIGRlc2MuaW5pdGlhbGl6ZXIgPSB1bmRlZmluZWQ7CiAgICB9CgogICAgaWYgKGRlc2MuaW5pdGlhbGl6ZXIgPT09IHZvaWQgMCkgewogICAgICAgIE9iamVjdFsnZGVmaW5lJyArICdQcm9wZXJ0eSddKHRhcmdldCwgcHJvcGVydHksIGRlc2MpOwogICAgICAgIGRlc2MgPSBudWxsOwogICAgfQoKICAgIHJldHVybiBkZXNjOwp9CgpmdW5jdGlvbiBfaW5pdGlhbGl6ZXJXYXJuaW5nSGVscGVyKGRlc2NyaXB0b3IsIGNvbnRleHQpIHsKICAgIHRocm93IG5ldyBFcnJvcignRGVjb3JhdGluZyBjbGFzcyBwcm9wZXJ0eSBmYWlsZWQuIFBsZWFzZSBlbnN1cmUgdGhhdCB0cmFuc2Zvcm0tY2xhc3MtcHJvcGVydGllcyBpcyBlbmFibGVkLicpOwp9CgovKioKICogSG9sZHMgb25lIG9yIG1vcmUgdG9hc3RzIGluIHN0YXRlIGZvciBkaXNwbGF5IGluIFVJLgogKi8KdmFyIFRvYXN0U2VydmljZSA9IGV4cG9ydHMuVG9hc3RTZXJ2aWNlID0gKF9jbGFzcyA9IGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFRvYXN0U2VydmljZSgpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVG9hc3RTZXJ2aWNlKTsKCiAgICAgICAgX2luaXREZWZpbmVQcm9wKHRoaXMsICd0b2FzdHMnLCBfZGVzY3JpcHRvciwgdGhpcyk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFRvYXN0U2VydmljZSwgW3sKICAgICAgICBrZXk6ICduZXdUb2FzdCcsCgoKICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IHRvYXN0IHRoYXQgaXMgYWRkZWQgdG8gdGhlIGxpc3QuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gdG9hc3Qgb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBzaGFwZToKICAgICAgICAgKiB7CiAgICAgICAgICogIHRleHQ6IHN0cmluZywgbWVzc2FnZSB0ZXh0IHRvIGRpc3BsYXkKICAgICAgICAgKiAgYWN0aW9uOiBzdHJpbmcsIHRleHQgZm9yIGFjdGlvbiBsaW5rCiAgICAgICAgICogIG9uQWN0aW9uQ2xpY2s6IGZ1bmN0aW9uLCBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiBhY3Rpb24gbGluayBpcyBjbGlja2VkCiAgICAgICAgICogIG9uRGlzbWlzczogZnVuY3Rpb24sIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRvYXN0IGlzIGRpc21pc3NlZCAoaW1tZWRpYXRlbHksIG9yIGFmdGVyIHRpbWVvdXQpCiAgICAgICAgICogIGRpc21pc3NEZWxheTogbnVtYmVyLCBkdXJhdGlvbiBpbiBtaWxsaXMgYWZ0ZXIgd2hpY2ggdG8gYXV0by1kaXNtaXNzIHRoaXMgVG9hc3QKICAgICAgICAgKiAgaWQ6IHVuaXF1ZSBpZGVudGlmaWVyIChvcHRpb25hbCwgd2lsbCBiZSBhdXRvZ2VuZXJhdGVkIGlmIG9tbWl0dGVkKQogICAgICAgICAqIH0KICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSB1bmlxdWUgSUQgb2YgdG9hc3QKICAgICAgICAgKi8KICAgICAgICB2YWx1ZTogZnVuY3Rpb24gbmV3VG9hc3QodG9hc3QpIHsKICAgICAgICAgICAgLy8gcHJldmVudCBkdXBsaWNhdGUgdG9hc3RzIGZyb20gYXBwZWFyaW5nIHdoZW4gbXVsdGlwbGUgVUkgZWxlbWVudHMKICAgICAgICAgICAgLy8gYXJlIGxpc3RlbmluZyBmb3IgYW4gZXZlbnQgdGhhdCB0cmlnZ2VycyBjcmVhdGlvbiBvZiBhIHRvYXN0CiAgICAgICAgICAgIGlmICh0aGlzLl9oYXNEdXBsaWNhdGUodG9hc3QpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIG5ld1RvYXN0ID0gdG9hc3Q7CgogICAgICAgICAgICBpZiAoIW5ld1RvYXN0LmlkKSB7CiAgICAgICAgICAgICAgICBuZXdUb2FzdC5pZCA9IE1hdGgucmFuZG9tKCkgKiBNYXRoLnBvdygxMCwgMTYpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLnRvYXN0cy5wdXNoKG5ld1RvYXN0KTsKCiAgICAgICAgICAgIHJldHVybiBuZXdUb2FzdC5pZDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJlbW92ZXMgYSB0b2FzdCB3aXRoIHRoZSBtYXRjaGluZyB2YWx1ZSBvZiB0b2FzdC5pZC4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB0b2FzdAogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdyZW1vdmVUb2FzdCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbW92ZVRvYXN0KHRvYXN0KSB7CiAgICAgICAgICAgIHRoaXMudG9hc3RzID0gdGhpcy50b2FzdHMuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdG9hc3QuaWQgIT09IGl0ZW0uaWQ7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfaGFzRHVwbGljYXRlJywKCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiBhIHRvYXN0IHdpdGggdGhlIHNhbWUgJ3RleHQnIGFuZCAnYWN0aW9uJyBhbHJlYWR5IGV4aXN0cwogICAgICAgICAqIEBwYXJhbSBuZXdUb2FzdAogICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufQogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9oYXNEdXBsaWNhdGUobmV3VG9hc3QpIHsKICAgICAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSB0cnVlOwogICAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IgPSBmYWxzZTsKICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvciA9IHRoaXMudG9hc3RzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXA7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IChfc3RlcCA9IF9pdGVyYXRvci5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIHZhciB0b2FzdCA9IF9zdGVwLnZhbHVlOwoKICAgICAgICAgICAgICAgICAgICBpZiAodG9hc3QudGV4dCA9PT0gbmV3VG9hc3QudGV4dCAmJiB0b2FzdC5hY3Rpb24gPT09IG5ld1RvYXN0LmFjdGlvbikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IgPSB0cnVlOwogICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IgPSBlcnI7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiAmJiBfaXRlcmF0b3IucmV0dXJuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvci5yZXR1cm4oKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcikgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY291bnQnLAogICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy50b2FzdHMgPyB0aGlzLnRvYXN0cy5sZW5ndGggOiAwOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gVG9hc3RTZXJ2aWNlOwp9KCksIChfZGVzY3JpcHRvciA9IF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ3RvYXN0cycsIFtfbW9ieC5vYnNlcnZhYmxlXSwgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGluaXRpYWxpemVyOiBmdW5jdGlvbiBpbml0aWFsaXplcigpIHsKICAgICAgICByZXR1cm4gW107CiAgICB9Cn0pLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICduZXdUb2FzdCcsIFtfbW9ieC5hY3Rpb25dLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICduZXdUb2FzdCcpLCBfY2xhc3MucHJvdG90eXBlKSwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAncmVtb3ZlVG9hc3QnLCBbX21vYnguYWN0aW9uXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAncmVtb3ZlVG9hc3QnKSwgX2NsYXNzLnByb3RvdHlwZSksIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ2NvdW50JywgW19tb2J4LmNvbXB1dGVkXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAnY291bnQnKSwgX2NsYXNzLnByb3RvdHlwZSkpLCBfY2xhc3MpOwp9LHsibW9ieCI6Mzg5fV0sNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwoKdmFyIF9pbmRleCA9IHJlcXVpcmUoJy4vaW5kZXgnKTsKCnZhciBfVXJsQnVpbGRlciA9IHJlcXVpcmUoJy4vVXJsQnVpbGRlcicpOwoKdmFyIF9pMThuID0gcmVxdWlyZSgnLi9pMThuL2kxOG4nKTsKCnZhciBfaTE4bjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pMThuKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9Cgp2YXIgQ0FQQUJJTElUWV9NVUxUSUJSQU5DSF9QSVBFTElORSA9ICdpby5qZW5raW5zLmJsdWVvY2Vhbi5yZXN0Lm1vZGVsLkJsdWVNdWx0aUJyYW5jaFBpcGVsaW5lJzsgLyoqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBDcmVhdGVkIGJ5IGNtZXllcnMgb24gOS8yMS8xNi4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwoKdmFyIENBUEFCSUxJVFlfTVVMVElCUkFOQ0hfQlJBTkNIID0gJ2lvLmplbmtpbnMuYmx1ZW9jZWFuLnJlc3QubW9kZWwuQmx1ZUJyYW5jaCc7CgpleHBvcnRzLmRlZmF1bHQgPSB7CiAgICAvKioKICAgICAqCiAgICAgKiBAcGFyYW0gcnVubmFibGUKICAgICAqIEBwYXJhbSBydW5JbmZvCiAgICAgKiBAcGFyYW0gdG9hc3RBY3Rpb24KICAgICAqLwogICAgY3JlYXRlUnVuU3RhcnRlZFRvYXN0OiBmdW5jdGlvbiBjcmVhdGVSdW5TdGFydGVkVG9hc3QocnVubmFibGUsIHJ1bkluZm8sIHRvYXN0QWN0aW9uKSB7CiAgICAgICAgdmFyIHRyYW5zbGF0ZSA9ICgwLCBfaTE4bjIuZGVmYXVsdCkoJ2JsdWVvY2Vhbi13ZWInKTsKICAgICAgICB2YXIgaXNNdWx0aUJyYW5jaCA9IHJ1bm5hYmxlLl9jYXBhYmlsaXRpZXMuc29tZShmdW5jdGlvbiAoY2FwYWJpbGl0eSkgewogICAgICAgICAgICByZXR1cm4gW0NBUEFCSUxJVFlfTVVMVElCUkFOQ0hfUElQRUxJTkUsIENBUEFCSUxJVFlfTVVMVElCUkFOQ0hfQlJBTkNIXS5pbmRleE9mKGNhcGFiaWxpdHkpICE9PSAtMTsKICAgICAgICB9KTsKCiAgICAgICAgdmFyIHJ1bklkID0gcnVuSW5mby5leHBlY3RlZEJ1aWxkTnVtYmVyOwoKICAgICAgICB2YXIgcnVuRGV0YWlsc1VybCA9ICgwLCBfVXJsQnVpbGRlci5idWlsZFJ1bkRldGFpbHNVcmxGcm9tUXVldWUpKHJ1bkluZm8uX2xpbmtzLnNlbGYuaHJlZiwgaXNNdWx0aUJyYW5jaCwgcnVuSWQpOwoKICAgICAgICB2YXIgbmFtZSA9IGRlY29kZVVSSUNvbXBvbmVudChydW5uYWJsZS5uYW1lKTsKICAgICAgICB2YXIgdGV4dCA9IHRyYW5zbGF0ZSgndG9hc3QucnVuLnN0YXJ0ZWQnLCB7CiAgICAgICAgICAgIDA6IG5hbWUsCiAgICAgICAgICAgIDE6IHJ1bklkLAogICAgICAgICAgICBkZWZhdWx0VmFsdWU6ICdTdGFydGVkICJ7MH0iICN7MX0nCiAgICAgICAgfSk7CgogICAgICAgIHZhciBjYXB0aW9uID0gdHJhbnNsYXRlKCd0b2FzdC5ydW4ub3BlbicsIHsKICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAnT3BlbicKICAgICAgICB9KTsKICAgICAgICBfaW5kZXguVG9hc3RTZXJ2aWNlLm5ld1RvYXN0KHsKICAgICAgICAgICAgdGV4dDogdGV4dCwKICAgICAgICAgICAgYWN0aW9uOiBjYXB0aW9uLAogICAgICAgICAgICBvbkFjdGlvbkNsaWNrOiBmdW5jdGlvbiBvbkFjdGlvbkNsaWNrKCkgewogICAgICAgICAgICAgICAgaWYgKHRvYXN0QWN0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgdG9hc3RBY3Rpb24ocnVuRGV0YWlsc1VybCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuIHJ1bkRldGFpbHNVcmw7CiAgICB9Cn07Cn0seyIuL1VybEJ1aWxkZXIiOjYsIi4vaTE4bi9pMThuIjoyNCwiLi9pbmRleCI6MjV9XSw2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gInN5bWJvbCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gInN5bWJvbCIgOiB0eXBlb2Ygb2JqOyB9OwoKLyoqCiAqIENyZWF0ZWQgYnkgY21leWVycyBvbiA4LzI1LzE2LgogKi8KCnZhciBleHRyYWN0UmVzdFVybCA9IGZ1bmN0aW9uIGV4dHJhY3RSZXN0VXJsKHN1YmplY3QpIHsKICAgIHZhciByZXN0VXJsID0gbnVsbDsKCiAgICBpZiAoKHR5cGVvZiBzdWJqZWN0ID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihzdWJqZWN0KSkgPT09ICdvYmplY3QnKSB7CiAgICAgICAgaWYgKHN1YmplY3QgJiYgc3ViamVjdC5fbGlua3MgJiYgc3ViamVjdC5fbGlua3Muc2VsZikgewogICAgICAgICAgICByZXN0VXJsID0gc3ViamVjdC5fbGlua3Muc2VsZi5ocmVmOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAodHlwZW9mIHN1YmplY3QgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgcmVzdFVybCA9IHN1YmplY3Q7CiAgICB9CgogICAgaWYgKCFyZXN0VXJsKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZmluZCBpbnB1dCBVUkwnKTsKICAgIH0KCiAgICByZXR1cm4gcmVzdFVybDsKfTsKCi8qKgogKiBSZXR1cm4gYSBuZXcgYXJyYXkgd2l0aCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlIGVsZW1lbnRzIHJlbW92ZWQuCiAqCiAqIEBwYXJhbSB7QXJyYXl9IHRva2VucwogKiBAcmV0dXJucyB7QXJyYXl9CiAqLwp2YXIgdHJpbUVtcHR5VG9rZW5zID0gZnVuY3Rpb24gdHJpbUVtcHR5VG9rZW5zKHRva2VucykgewogICAgdmFyIGNvcHkgPSB0b2tlbnMuc2xpY2UoKTsKCiAgICBpZiAoY29weVswXSA9PT0gJycpIHsKICAgICAgICBjb3B5LnNoaWZ0KCk7CiAgICB9CgogICAgaWYgKGNvcHlbY29weS5sZW5ndGggLSAxXSA9PT0gJycpIHsKICAgICAgICBjb3B5LnBvcCgpOwogICAgfQoKICAgIHJldHVybiBjb3B5Owp9OwoKLyoqCiAqIEJ1aWxkcyB0aGUgcHJvcGVyIFVSTCB0byB2aWV3IFJ1biBEZXRhaWxzIGZvciB0aGUgc3BlY2lmaWVkIHJ1bi4KICogUnVuIGlzIGVpdGhlciBhIHJ1biBvYmplY3Qgd2l0aCAiX2xpbmtzLnNlbGYuaHJlZiIgcHJvcGVydHksIG9yIHRoZSBVUkwgaXRzZWxmLgogKgogKiBAcGFyYW0ge29iamVjdHxzdHJpbmd9IHJ1bgogKiBAcmV0dXJucyB7c3RyaW5nfQogKi8KdmFyIGJ1aWxkUnVuRGV0YWlsc1VybCA9IGV4cG9ydHMuYnVpbGRSdW5EZXRhaWxzVXJsID0gZnVuY3Rpb24gYnVpbGRSdW5EZXRhaWxzVXJsKHJ1bikgewogICAgdmFyIHJlc3RVcmwgPSBleHRyYWN0UmVzdFVybChydW4pOwogICAgdmFyIHRva2VucyA9IHRyaW1FbXB0eVRva2VucyhyZXN0VXJsLnNwbGl0KCcvJykpOwoKICAgIC8vIGdpdmVuIHRoZSBmb2xsb3dpbmcgVVJMICcvYmx1ZS9yZXN0L29yZ2FuaXphdGlvbnMvamVua2lucy9waXBlbGluZXMvZm9sZGVyMS9waXBlbGluZXMvZm9sZGVyMi9waXBlbGluZXMvZm9sZGVyMy9waXBlbGluZXMvamRsLTIKICAgIC8vIC9icmFuY2hlcy9leHBlcmltZW50JTI1MkZidWlsZC1sb2NhbGx5LWRvY2tlci9ydW5zLzIxLwoKICAgIHZhciBvcmdhbml6YXRpb25OYW1lID0gdG9rZW5zWzNdOwogICAgdmFyIGlzTXVsdGlCcmFuY2ggPSB0b2tlbnNbdG9rZW5zLmxlbmd0aCAtIDRdID09PSAnYnJhbmNoZXMnOwoKICAgIHZhciBmdWxsTmFtZVN0YXJ0ID0gNDsKICAgIHZhciBmdWxsTmFtZUVuZCA9ICFpc011bHRpQnJhbmNoID8gdG9rZW5zLmxlbmd0aCAtIDIgOiB0b2tlbnMubGVuZ3RoIC0gNDsKICAgIC8vIGdyYWIgdGhlIHRva2VucyB0aGF0IG1ha2UgdXAgdGhlIGZ1bGwgbmFtZSwgdGhlbiBmaWx0ZXIgb3V0IHRoZSBldmVuIHZhbHVlcyAoJy9waXBlbGluZXMnKQogICAgLy8gc28gdGhlIGNsZWFuIGZvbGRlciBwYXRoIGlzIHJldHVybmVkLCBlLmcuIGZvbGRlcjEvZm9sZGVyMi9mb2xkZXIzL2pkbC0yCiAgICB2YXIgZnVsbE5hbWUgPSB0b2tlbnMuc2xpY2UoZnVsbE5hbWVTdGFydCwgZnVsbE5hbWVFbmQpLmZpbHRlcihmdW5jdGlvbiAobmFtZSwgaW5kZXgpIHsKICAgICAgICByZXR1cm4gaW5kZXggJSAyID09PSAxOwogICAgfSkuam9pbignLycpOwoKICAgIHZhciBwaXBlbGluZU5hbWUgPSB0b2tlbnNbZnVsbE5hbWVFbmQgLSAxXTsKICAgIHZhciBicmFuY2hOYW1lID0gaXNNdWx0aUJyYW5jaCA/IHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gM10gOiAnJzsKICAgIHZhciBydW5JZCA9IHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gMV07CgogICAgdmFyIGRldGFpbE5hbWUgPSBpc011bHRpQnJhbmNoID8gZGVjb2RlVVJJQ29tcG9uZW50KGJyYW5jaE5hbWUpIDogcGlwZWxpbmVOYW1lOwoKICAgIC8vIGZhaWwgZmFzdAogICAgaWYgKCFvcmdhbml6YXRpb25OYW1lIHx8ICFmdWxsTmFtZSB8fCAhZGV0YWlsTmFtZSB8fCAhcnVuSWQpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBleHRyYWN0IFVSSSBjb21wb25lbnRzJyk7CiAgICB9CgogICAgcmV0dXJuICcvb3JnYW5pemF0aW9ucy8nICsgb3JnYW5pemF0aW9uTmFtZSArICgnLycgKyBlbmNvZGVVUklDb21wb25lbnQoZnVsbE5hbWUpICsgJy9kZXRhaWwnKSArICgnLycgKyBkZXRhaWxOYW1lICsgJy8nICsgcnVuSWQgKyAnL3BpcGVsaW5lJyk7Cn07Cgp2YXIgYnVpbGRSdW5EZXRhaWxzVXJsRnJvbVF1ZXVlID0gZXhwb3J0cy5idWlsZFJ1bkRldGFpbHNVcmxGcm9tUXVldWUgPSBmdW5jdGlvbiBidWlsZFJ1bkRldGFpbHNVcmxGcm9tUXVldWUocXVldWVJdGVtLCBpc011bHRpQnJhbmNoLCBleHBlY3RlZEJ1aWxkTnVtYmVyKSB7CiAgICB2YXIgcmVzdFVybCA9IGV4dHJhY3RSZXN0VXJsKHF1ZXVlSXRlbSk7CiAgICB2YXIgdG9rZW5zID0gdHJpbUVtcHR5VG9rZW5zKHJlc3RVcmwuc3BsaXQoJy8nKSk7CgogICAgLy8gZ2l2ZW4gdGhlIGZvbGxvd2luZyBVUkwgJy9ibHVlL3Jlc3Qvb3JnYW5pemF0aW9ucy9qZW5raW5zL3BpcGVsaW5lcy9qZW5raW5zZmlsZS1leHBlcmltZW50cy9waXBlbGluZXMvUFItMi9xdWV1ZS8zMS8nCgogICAgLy8gbW9kaWZ5IHRoZSAncXVldWUnIFVSTCBzbyBpdCBsb29rcyBsaWtlIGEgJ3J1bnMnIFVSTAogICAgdG9rZW5zW3Rva2Vucy5sZW5ndGggLSAyXSA9ICdydW5zJzsKCiAgICAvLyByZXBsYWNlIHRoZSBxdWV1ZSBudW1iZXIgd2l0aCB0aGUgZXhwZWN0ZWQgcnVuSWQKICAgIHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gMV0gPSBleHBlY3RlZEJ1aWxkTnVtYmVyOwoKICAgIC8vIGlmIG11bHRpLWJyYW5jaCwgY2hhbmdlIHRoZSBsYXN0IHZhbHVlIG9mICdwaXBlbGluZXMnIHRvICdicmFuY2hlcycgc28gaXQgbG9va3MgbGlrZSBhIG11bHRpYnJhbmNoIFJFU1QgVVJMCiAgICBpZiAoaXNNdWx0aUJyYW5jaCkgewogICAgICAgIHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gNF0gPSAnYnJhbmNoZXMnOwogICAgfQoKICAgIHJldHVybiBidWlsZFJ1bkRldGFpbHNVcmwodG9rZW5zLmpvaW4oJy8nKSk7Cn07CgpleHBvcnRzLmRlZmF1bHQgPSB7CiAgICBidWlsZFJ1bkRldGFpbHNVcmw6IGJ1aWxkUnVuRGV0YWlsc1VybCwgYnVpbGRSdW5EZXRhaWxzVXJsRnJvbVF1ZXVlOiBidWlsZFJ1bkRldGFpbHNVcmxGcm9tUXVldWUKfTsKfSx7fV0sNzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlRlc3RVdGlsID0gZXhwb3J0cy5Vc2VyID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7IC8qKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogQ3JlYXRlZCBieSBjbWV5ZXJzIG9uIDcvOC8xNi4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwoKdmFyIF9zY29wZXMgPSByZXF1aXJlKCcuL3Njb3BlcycpOwoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9Cgp2YXIgUGlwZWxpbmVQZXJtaXNzaW9ucyA9IGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFBpcGVsaW5lUGVybWlzc2lvbnMoKSB7CiAgICAgICAgdmFyIGJsdWVVc2VyID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB7fTsKCiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFBpcGVsaW5lUGVybWlzc2lvbnMpOwoKICAgICAgICBpZiAoYmx1ZVVzZXIucGVybWlzc2lvbiAmJiBibHVlVXNlci5wZXJtaXNzaW9uLnBpcGVsaW5lKSB7CiAgICAgICAgICAgIHRoaXMuX3Blcm1pc3Npb25zID0gYmx1ZVVzZXIucGVybWlzc2lvbi5waXBlbGluZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGlzLl9wZXJtaXNzaW9ucyA9IHt9OwogICAgICAgIH0KICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoUGlwZWxpbmVQZXJtaXNzaW9ucywgW3sKICAgICAgICBrZXk6ICdjcmVhdGUnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjcmVhdGUoKSB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMuX3Blcm1pc3Npb25zLmNyZWF0ZTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAncmVhZCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlYWQoKSB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMuX3Blcm1pc3Npb25zLnJlYWQ7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3N0YXJ0JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gc3RhcnQoKSB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMuX3Blcm1pc3Npb25zLnN0YXJ0OwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdzdG9wJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gc3RvcCgpIHsKICAgICAgICAgICAgcmV0dXJuICEhdGhpcy5fcGVybWlzc2lvbnMuc3RvcDsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY29uZmlndXJlJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29uZmlndXJlKCkgewogICAgICAgICAgICByZXR1cm4gISF0aGlzLl9wZXJtaXNzaW9ucy5jb25maWd1cmU7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBQaXBlbGluZVBlcm1pc3Npb25zOwp9KCk7Cgp2YXIgQ3JlZGVudGlhbFBlcm1pc3Npb25zID0gZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gQ3JlZGVudGlhbFBlcm1pc3Npb25zKCkgewogICAgICAgIHZhciBibHVlVXNlciA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDoge307CgogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDcmVkZW50aWFsUGVybWlzc2lvbnMpOwoKICAgICAgICBpZiAoYmx1ZVVzZXIucGVybWlzc2lvbiAmJiBibHVlVXNlci5wZXJtaXNzaW9uLmNyZWRlbnRpYWwpIHsKICAgICAgICAgICAgdGhpcy5fcGVybWlzc2lvbnMgPSBibHVlVXNlci5wZXJtaXNzaW9uLmNyZWRlbnRpYWw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhpcy5fcGVybWlzc2lvbnMgPSB7fTsKICAgICAgICB9CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKENyZWRlbnRpYWxQZXJtaXNzaW9ucywgW3sKICAgICAgICBrZXk6ICdjcmVhdGUnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjcmVhdGUoKSB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMuX3Blcm1pc3Npb25zLmNyZWF0ZTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAndmlldycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHZpZXcoKSB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMuX3Blcm1pc3Npb25zLnZpZXc7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2RlbGV0ZScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9kZWxldGUoKSB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMuX3Blcm1pc3Npb25zLmRlbGV0ZTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAndXBkYXRlJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdXBkYXRlKCkgewogICAgICAgICAgICByZXR1cm4gISF0aGlzLl9wZXJtaXNzaW9ucy51cGRhdGU7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ21hbmFnZURvbWFpbnMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBtYW5hZ2VEb21haW5zKCkgewogICAgICAgICAgICByZXR1cm4gISF0aGlzLl9wZXJtaXNzaW9ucy5tYW5hZ2VEb21haW5zOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gQ3JlZGVudGlhbFBlcm1pc3Npb25zOwp9KCk7Cgp2YXIgVXNlciA9IGV4cG9ydHMuVXNlciA9IGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFVzZXIoKSB7CiAgICAgICAgdmFyIGJsdWVVc2VyID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB7fTsKCiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFVzZXIpOwoKICAgICAgICB0aGlzLl9ibHVlVXNlciA9IGJsdWVVc2VyOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhVc2VyLCBbewogICAgICAgIGtleTogJ2lzQW5vbnltb3VzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gaXNBbm9ueW1vdXMoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmlkID09PSAnYW5vbnltb3VzJzsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX2NsYXNzJywKICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JsdWVVc2VyLl9jbGFzczsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX2xpbmtzJywKICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JsdWVVc2VyLl9saW5rczsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnZW1haWwnLAogICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5fYmx1ZVVzZXIuZW1haWw7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2Z1bGxOYW1lJywKICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JsdWVVc2VyLmZ1bGxOYW1lOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdpZCcsCiAgICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9ibHVlVXNlci5pZCB8fCAnYW5vbnltb3VzJzsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnaXNBZG1pbmlzdHJhdG9yJywKICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICAgICAgdmFyIHBlcm1pc3Npb24gPSB0aGlzLl9ibHVlVXNlci5wZXJtaXNzaW9uIHx8IHt9OwogICAgICAgICAgICByZXR1cm4gISFwZXJtaXNzaW9uLmFkbWluaXN0cmF0b3I7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3Blcm1pc3Npb25zJywKICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIHBpcGVsaW5lOiBuZXcgUGlwZWxpbmVQZXJtaXNzaW9ucyh0aGlzLl9ibHVlVXNlciksCiAgICAgICAgICAgICAgICBjcmVkZW50aWFsOiBuZXcgQ3JlZGVudGlhbFBlcm1pc3Npb25zKHRoaXMuX2JsdWVVc2VyKQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH1dLCBbewogICAgICAgIGtleTogJ2N1cnJlbnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjdXJyZW50KCkgewogICAgICAgICAgICByZXR1cm4gQ1VSUkVOVDsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11c2UtYmVmb3JlLWRlZmluZQogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gVXNlcjsKfSgpOwoKdmFyIENVUlJFTlQgPSBuZXcgVXNlcihfc2NvcGVzLmJsdWVvY2Vhbi51c2VyKTsKCi8qIGVzbGludC1kaXNhYmxlICovCnZhciBUZXN0VXRpbCA9IGV4cG9ydHMuVGVzdFV0aWwgPSB7CiAgICBzZXRDdXJyZW50OiBmdW5jdGlvbiBzZXRDdXJyZW50KHVzZXIpIHsKICAgICAgICBDVVJSRU5UID0gbmV3IFVzZXIodXNlcik7CiAgICB9Cn07Cn0seyIuL3Njb3BlcyI6NDN9XSw4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuQ2FwYWJpbGl0eUFwaSA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOyAvKioKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIENyZWF0ZWQgYnkgY21leWVycyBvbiA5LzgvMTYuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCgp2YXIgX2ZldGNoID0gcmVxdWlyZSgnLi4vZmV0Y2gnKTsKCnZhciBfdXJsY29uZmlnID0gcmVxdWlyZSgnLi4vdXJsY29uZmlnJyk7Cgp2YXIgX3VybGNvbmZpZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF91cmxjb25maWcpOwoKdmFyIF91dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7Cgp2YXIgX3V0aWxzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3V0aWxzKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCnZhciBDYXBhYmlsaXR5QXBpID0gZXhwb3J0cy5DYXBhYmlsaXR5QXBpID0gZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gQ2FwYWJpbGl0eUFwaSgpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQ2FwYWJpbGl0eUFwaSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKENhcGFiaWxpdHlBcGksIFt7CiAgICAgICAga2V5OiAnZmV0Y2hDYXBhYmlsaXRpZXMnLAoKCiAgICAgICAgLyoqCiAgICAgICAgICogRmV0Y2ggdGhlIGNhcGFiaWxpdGllcyBmb3Igb25lIG9yIG1vcmUgY2xhc3MgbmFtZXMuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBjbGFzc05hbWVzCiAgICAgICAgICogQHJldHVybnMge1Byb21pc2V9IHdpdGggZnVsZmlsbGVkIHtvYmplY3R9IGtleWVkIGJ5IGNsYXNzTmFtZSwgd2l0aCBhbiBhcnJheSBvZiBzdHJpbmcgY2FwYWJpbGl0eSBuYW1lcy4KICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmZXRjaENhcGFiaWxpdGllcyhjbGFzc05hbWVzKSB7CiAgICAgICAgICAgIHZhciBub0R1cGxpY2F0ZXMgPSBjbGFzc05hbWVzLmZpbHRlcihmdW5jdGlvbiAoaXRlbSwgaW5kZXgsIHNlbGYpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLmluZGV4T2YoaXRlbSkgPT09IGluZGV4OwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgdmFyIHBhdGggPSBfdXJsY29uZmlnMi5kZWZhdWx0LmdldEplbmtpbnNSb290VVJMKCk7CiAgICAgICAgICAgIHZhciBjbGFzc2VzVXJsID0gX3V0aWxzMi5kZWZhdWx0LmNsZWFuU2xhc2hlcyhwYXRoICsgJy9ibHVlL3Jlc3QvY2xhc3Nlcy8nKTsKCiAgICAgICAgICAgIHZhciBmZXRjaE9wdGlvbnMgPSB7CiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJywKICAgICAgICAgICAgICAgIGhlYWRlcnM6IHsKICAgICAgICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBxOiBub0R1cGxpY2F0ZXMgfSkKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHJldHVybiBfZmV0Y2guRmV0Y2guZmV0Y2hKU09OKGNsYXNzZXNVcmwsIHsgZGlzYWJsZUNhcGFiaWxpdGVzOiB0cnVlLCBmZXRjaE9wdGlvbnM6IGZldGNoT3B0aW9ucyB9KTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIENhcGFiaWxpdHlBcGk7Cn0oKTsKfSx7Ii4uL2ZldGNoIjoyMiwiLi4vdXJsY29uZmlnIjo1OCwiLi4vdXRpbHMiOjU5fV0sOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gInN5bWJvbCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gInN5bWJvbCIgOiB0eXBlb2Ygb2JqOyB9OwoKZnVuY3Rpb24gX3RvQ29uc3VtYWJsZUFycmF5KGFycikgeyBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSB7IGZvciAodmFyIGkgPSAwLCBhcnIyID0gQXJyYXkoYXJyLmxlbmd0aCk7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHsgYXJyMltpXSA9IGFycltpXTsgfSByZXR1cm4gYXJyMjsgfSBlbHNlIHsgcmV0dXJuIEFycmF5LmZyb20oYXJyKTsgfSB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCi8qKgogKiBDcmVhdGVkIGJ5IGNtZXllcnMgb24gOS84LzE2LgogKi8KCnZhciBhZGRDbGFzcyA9IGZ1bmN0aW9uIGFkZENsYXNzKGNsYXp6LCBjbGFzc01hcCkgewogICAgdmFyIGNsYXNzTmFtZSA9IHZvaWQgMDsKCiAgICBpZiAoQXJyYXkuaXNBcnJheShjbGF6ei5fY2xhc3MpKSB7CiAgICAgICAgLy8gSWYgaXQncyBhbiBhcnJheSBvZiBjbGFzcyBuYW1lcywganVzdCB0YWtlIHRoZSBmaXJzdC4KICAgICAgICAvLyBUT0RPOiBIbW1tIC4uLiBub3Qgc3VyZSBpZiB0aGlzIGlzIHRoZSByaWdodCB0aGluZyB0byBkbyB3aGVuIHdlIGhhdmUgYW4gYXJyYXkgb2YgY2xhc3MgbmFtZXMuCiAgICAgICAgLy8gTm90IHN1cmUgd2hhdCB0aGUgYXJyYXkgaXMgYWJvdXQgdGJoLiBXaGF0IGFyZSB0aGUgcmVsYXRpb25zaGlwcz8KICAgICAgICBpZiAoY2xhenouX2NsYXNzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgY2xhc3NOYW1lID0gY2xhenouX2NsYXNzWzBdOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGNsYXNzTmFtZSA9IGNsYXp6Ll9jbGFzczsKICAgIH0KCiAgICBpZiAoIWNsYXNzTWFwW2NsYXNzTmFtZV0pIHsKICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ24KICAgICAgICBjbGFzc01hcFtjbGFzc05hbWVdID0gW107CiAgICB9CgogICAgY2xhc3NNYXBbY2xhc3NOYW1lXS5wdXNoKGNsYXp6KTsKfTsKCnZhciBjYW5XYWxrID0gZnVuY3Rpb24gY2FuV2FsayhpdGVtKSB7CiAgICByZXR1cm4gaXRlbSAmJiAoKHR5cGVvZiBpdGVtID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihpdGVtKSkgPT09ICdvYmplY3QnIHx8IEFycmF5LmlzQXJyYXkoaXRlbSkpOwp9OwoKdmFyIERFRkFVTFRfSUdOT1JFRF9QUk9QUyA9IFsnX2xpbmtzJ107CgovKioKICogRGVjb3JhdGUgYW4gb2JqZWN0IGdyYXBoIHdpdGggYSAnX2NhcGFiaWxpdGllcycgcHJvcGVydHkgZm9yIGVhY2ggb2JqZWN0IHdpdGggYSB2YWxpZCAnX2NsYXNzJwogKiBVc2FnZToKICogICAgICBpbXBvcnQgeyBjYXBhYmlsaXR5QXVnbWVudGVyIH0gZnJvbSAnQGplbmtpbnMtY2QvYmx1ZW9jZWFuLWNvcmUtanMnOwogKiAgICAgIGNvbnN0IGF1Z21lbnRDYXBhYmlsaXR5ID0gY2FwYWJpbGl0eUF1Z21lbnRlci5hdWdtZW50Q2FwYWJpbGl0eTsKICoKICogICAgICBmZXRjaCh1cmwsIGZldGNoT3B0aW9ucykKICogICAgICAgICAgLnRoZW4oZGF0YSA9PiBhdWdtZW50Q2FwYWJpbGl0eShkYXRhKSk7CiAqLwoKdmFyIENhcGFiaWxpdHlBdWdtZW50ZXIgPSBleHBvcnRzLkNhcGFiaWxpdHlBdWdtZW50ZXIgPSBmdW5jdGlvbiAoKSB7CiAgICBmdW5jdGlvbiBDYXBhYmlsaXR5QXVnbWVudGVyKGNhcGFiaWxpdHlTdG9yZSkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDYXBhYmlsaXR5QXVnbWVudGVyKTsKCiAgICAgICAgdGhpcy5fY2FwYWJpbGl0eVN0b3JlID0gY2FwYWJpbGl0eVN0b3JlOwogICAgICAgIHRoaXMuX3BlcmZMb2dnaW5nRW5hYmxlZCA9IGZhbHNlOwogICAgICAgIHRoaXMuX3dhcm5Mb2dnaW5nRW5hYmxlZCA9IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQWRkICJfY2FwYWJpbGl0aWVzIiBkYXRhIG9yIGFsbCBvYmplY3RzIHdpdGggYSAiX2NsYXNzIiBwcm9wZXJ0eS4KICAgICAqCiAgICAgKiBAcGFyYW0ge29iamVjdHxBcnJheX0gZGF0YQogICAgICogQHJldHVybnMge1Byb21pc2V9CiAgICAgKi8KCgogICAgX2NyZWF0ZUNsYXNzKENhcGFiaWxpdHlBdWdtZW50ZXIsIFt7CiAgICAgICAga2V5OiAnYXVnbWVudENhcGFiaWxpdGllcycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGF1Z21lbnRDYXBhYmlsaXRpZXMoZGF0YSkgewogICAgICAgICAgICB2YXIgY2xhc3NNYXAgPSB0aGlzLl9maW5kQ2xhc3Nlc0luVHJlZShkYXRhKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc29sdmVDYXBhYmlsaXRpZXMoZGF0YSwgY2xhc3NNYXApOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdlbmFibGVQZXJmTG9nZ2luZycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGVuYWJsZVBlcmZMb2dnaW5nKCkgewogICAgICAgICAgICB0aGlzLl9wZXJmTG9nZ2luZ0VuYWJsZWQgPSB0cnVlOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdlbmFibGVXYXJuaW5nTG9nZ2luZycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGVuYWJsZVdhcm5pbmdMb2dnaW5nKCkgewogICAgICAgICAgICB0aGlzLl93YXJuTG9nZ2luZ0VuYWJsZWQgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogRmluZCBhbGwgb2YgdGhlIGRpc3RpbmN0ICJfY2xhc3MiIHZhbHVlcyBpbiBzdXBwbGllZCBvYmplY3QuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge29iamVjdHxBcnJheX0gZGF0YQogICAgICAgICAqIEByZXR1cm5zIHtvYmplY3R9IGtleT0gIl9jbGFzcyIgbmFtZSwgdmFsdWU9IGFycmF5IG9mIGFsbCBvYmplY3RzIG9mIHRoYXQgY2xhc3MuCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnX2ZpbmRDbGFzc2VzSW5UcmVlJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX2ZpbmRDbGFzc2VzSW5UcmVlKGRhdGEpIHsKICAgICAgICAgICAgdmFyIGNsYXNzTWFwID0ge307CiAgICAgICAgICAgIHZhciBub2Rlc1RvV2FsayA9IFtkYXRhXTsKICAgICAgICAgICAgdmFyIG5vZGVzQWxyZWFkeVdhbGtlZCA9IFtdOwogICAgICAgICAgICB2YXIgaWdub3JlZFByb3BzID0gREVGQVVMVF9JR05PUkVEX1BST1BTLnNsaWNlKCk7CgogICAgICAgICAgICB2YXIgc3RhcnRlZCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpOwoKICAgICAgICAgICAgdmFyIG5vZGUgPSBub2Rlc1RvV2Fsay5zaGlmdCgpOwoKICAgICAgICAgICAgd2hpbGUgKG5vZGUpIHsKICAgICAgICAgICAgICAgIG5vZGVzQWxyZWFkeVdhbGtlZC5wdXNoKG5vZGUpOwoKICAgICAgICAgICAgICAgIC8vIHNhdmUgYSByZWYgdG8gdGhlIGNsYXNzIHNvIHdlIGNhbiBhdHRhY2ggY2FwYWJpbGl0aWVzIGxhdGVyCiAgICAgICAgICAgICAgICBpZiAoKHR5cGVvZiBub2RlID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihub2RlKSkgPT09ICdvYmplY3QnICYmIG5vZGUuX2NsYXNzKSB7CiAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3Mobm9kZSwgY2xhc3NNYXApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBub2RlS2V5cyA9IE9iamVjdC5rZXlzKG5vZGUpOwoKICAgICAgICAgICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvciA9IGZhbHNlOwogICAgICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gbm9kZUtleXNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gKF9zdGVwID0gX2l0ZXJhdG9yLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXkgPSBfc3RlcC52YWx1ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IG5vZGVba2V5XTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdhbGsgdGhpcyBub2RlIGF0IGEgbGF0ZXIgaXRlcmF0aW9uIGFzIGxvbmcgYXMKICAgICAgICAgICAgICAgICAgICAgICAgLy8gLSB3ZSBkaWRuJ3QgYWxyZWFkeSB3YWxrIGl0IChjeWNsZXMgY2F1c2UgYW4gaW5maW5pdGUgbG9vcCBvdGhlcndpc2UpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC0gdGhlIHByb3BlcnR5IG5hbWUgaXNuJ3Qgb24gdGhlIGJsYWNrbGlzdAogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2FuV2Fsayh2YWx1ZSkgJiYgbm9kZXNBbHJlYWR5V2Fsa2VkLmluZGV4T2YodmFsdWUpID09PSAtMSAmJiBpZ25vcmVkUHJvcHMuaW5kZXhPZihrZXkpID09PSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXNUb1dhbGsucHVzaCh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgICAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvciA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IgPSBlcnI7CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiAmJiBfaXRlcmF0b3IucmV0dXJuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3IucmV0dXJuKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIG5vZGUgPSBub2Rlc1RvV2Fsay5zaGlmdCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5fcGVyZkxvZ2dpbmdFbmFibGVkKSB7CiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdhdWdtZW50ZXIucGFyc2U6ICcgKyAobmV3IERhdGUoKS5nZXRUaW1lKCkgLSBzdGFydGVkKSArICdtcycpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gY2xhc3NNYXA7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ19yZXNvbHZlQ2FwYWJpbGl0aWVzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX3Jlc29sdmVDYXBhYmlsaXRpZXMoZGF0YSwgY2xhc3NNYXApIHsKICAgICAgICAgICAgdmFyIF9jYXBhYmlsaXR5U3RvcmUsCiAgICAgICAgICAgICAgICBfdGhpcyA9IHRoaXM7CgogICAgICAgICAgICB2YXIgY2xhc3NOYW1lcyA9IE9iamVjdC5rZXlzKGNsYXNzTWFwKTsKCiAgICAgICAgICAgIHJldHVybiAoX2NhcGFiaWxpdHlTdG9yZSA9IHRoaXMuX2NhcGFiaWxpdHlTdG9yZSkucmVzb2x2ZUNhcGFiaWxpdGllcy5hcHBseShfY2FwYWJpbGl0eVN0b3JlLCBfdG9Db25zdW1hYmxlQXJyYXkoY2xhc3NOYW1lcykpLnRoZW4oZnVuY3Rpb24gKGNhcGFiaWxpdGllc01hcCkgewogICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLl9pbmplY3RDYXBhYmlsaXRpZXMoY2xhc3NNYXAsIGNhcGFiaWxpdGllc01hcCk7CiAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGRhdGE7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQWRkIHRoZSBjYXBhYmlsaXRpZXMgdG8gdGhlICJfY2FwYWJpbGl0aWVzIiBwcm9wZXJ0eSBvZiBhbGwgb2JqZWN0cyBpbiB0aGUgY2xhc3MgbWFwLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGNsYXNzTWFwCiAgICAgICAgICogQHBhcmFtIGNhcGFiaWxpdGllc01hcAogICAgICAgICAqIEByZXR1cm5zIHtvYmplY3R9IGNsYXNzTWFwCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnX2luamVjdENhcGFiaWxpdGllcycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9pbmplY3RDYXBhYmlsaXRpZXMoY2xhc3NNYXAsIGNhcGFiaWxpdGllc01hcCkgewogICAgICAgICAgICB2YXIgc3RhcnRlZCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpOwogICAgICAgICAgICB2YXIgdW5yZXNvbHZlZCA9IFtdOwoKICAgICAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yID0gdHJ1ZTsKICAgICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yMiA9IGZhbHNlOwogICAgICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IyID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjIgPSBPYmplY3Qua2V5cyhjbGFzc01hcClbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDI7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIgPSAoX3N0ZXAyID0gX2l0ZXJhdG9yMi5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMiA9IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZSA9IF9zdGVwMi52YWx1ZTsKICAgICAgICAgICAgICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3I0ID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3I0ID0gY2xhc3NNYXBbX2NsYXNzTmFtZV1bU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDQ7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjQgPSAoX3N0ZXA0ID0gX2l0ZXJhdG9yNC5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uNCA9IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSBfc3RlcDQudmFsdWU7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNhcGFiaWxpdGllcyA9IGNhcGFiaWxpdGllc01hcFtfY2xhc3NOYW1lXTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNhcGFiaWxpdGllcyAmJiB1bnJlc29sdmVkLmluZGV4T2YoX2NsYXNzTmFtZSkgPT09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5yZXNvbHZlZC5wdXNoKF9jbGFzc05hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC5fY2FwYWJpbGl0aWVzID0gY2FwYWJpbGl0aWVzIHx8IFtdOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yNCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvckVycm9yNCA9IGVycjsKICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uNCAmJiBfaXRlcmF0b3I0LnJldHVybikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvcjQucmV0dXJuKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3I0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3I0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yMiA9IHRydWU7CiAgICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvcjIgPSBlcnI7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIgJiYgX2l0ZXJhdG9yMi5yZXR1cm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yMi5yZXR1cm4oKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRoaXMuX3BlcmZMb2dnaW5nRW5hYmxlZCkgewogICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnYXVnbWVudGVyLmluamVjdDogJyArIChuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHN0YXJ0ZWQpICsgJ21zJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh0aGlzLl93YXJuTG9nZ2luZ0VuYWJsZWQpIHsKICAgICAgICAgICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMyA9IHRydWU7CiAgICAgICAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IzID0gZmFsc2U7CiAgICAgICAgICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IzID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMyA9IHVucmVzb2x2ZWRbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDM7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMgPSAoX3N0ZXAzID0gX2l0ZXJhdG9yMy5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMyA9IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzTmFtZSA9IF9zdGVwMy52YWx1ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignY291bGQgbm90IHJlc29sdmUgY2FwYWJpbGl0aWVzIGZvciAnICsgY2xhc3NOYW1lICsgJzsgYW4gZXJyb3IgbWF5IGhhdmUgb2NjdXJyZWQgZHVyaW5nIGxvb2t1cCcpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yMyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IzID0gZXJyOwogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zICYmIF9pdGVyYXRvcjMucmV0dXJuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3IzLnJldHVybigpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IzOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gY2xhc3NNYXA7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBDYXBhYmlsaXR5QXVnbWVudGVyOwp9KCk7Cn0se31dLDEwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuQ2FwYWJpbGl0eVN0b3JlID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7IC8qKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogQ3JlYXRlZCBieSBjbWV5ZXJzIG9uIDgvMzEvMTYuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCgp2YXIgX2VzNlByb21pc2UgPSByZXF1aXJlKCdlczYtcHJvbWlzZScpOwoKdmFyIF9lczZQcm9taXNlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2VzNlByb21pc2UpOwoKdmFyIF9zdG9yYWdlID0gcmVxdWlyZSgnLi4vc3RvcmFnZScpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKX2VzNlByb21pc2UyLmRlZmF1bHQucG9seWZpbGwoKTsKCgovLyBDcmVhdGUgYSBkZWRpY2F0ZWQgc3RvcmFnZSBuYW1lc3BhY2UgdGhhdCB3ZSB1c2UgdG8gc3RvcmUgY2xhc3NlcwovLyBpbmZvIGluIHRoZSBicm93c2VyLCBlbGltaW5hdGluZyBjbGllbnQgUkVTVCBjYWxsIG92ZXJoZWFkIGZvciBjbGFzc2VzCi8vIGluZm8uIFRoaXMgc3RvcmFnZSBuYW1lc3BhY2Ugd2lsbCBiZSBhdXRvLWNsZWFyZWQgaWYgdGhlIGplc25raW5zIHZlcnNpb24KLy8gY2hhbmdlcywgb3IgaWYgdGhlIGFjdGl2ZSBwbHVnaW5zIGNoYW5nZS4KdmFyIGNsYXNzZXNJbmZvTlMgPSBfc3RvcmFnZS5pbnN0YWxsSW5mby5zdWJzcGFjZSgnY2xhc3Nlc0luZm8nKTsKCi8qKgogKiBSZXRyaWV2ZXMgY2FwYWJpbGl0eSBtZXRhZGF0YSBmb3IgY2xhc3MgbmFtZXMuCiAqIFVzZXMgYW4gaW50ZXJuYWwgY2FjaGUgdG8gbWluaW1pemUgUkVTVCBBUEkgY2FsbHMuCiAqLwoKdmFyIENhcGFiaWxpdHlTdG9yZSA9IGV4cG9ydHMuQ2FwYWJpbGl0eVN0b3JlID0gZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gQ2FwYWJpbGl0eVN0b3JlKGNhcGFiaWxpdHlBcGkpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQ2FwYWJpbGl0eVN0b3JlKTsKCiAgICAgICAgdGhpcy5fbG9jYWxTdG9yZSA9IHt9OwogICAgICAgIHRoaXMuX2NhcGFiaWxpdHlBcGkgPSBjYXBhYmlsaXR5QXBpOwogICAgfQoKICAgIC8qKgogICAgICogRmV0Y2ggdGhlIGNhcGFiaWxpdGllcyBmb3Igb25lIG9yIG1vcmUgY2xhc3MgbmFtZXMuCiAgICAgKiBXaWxsIHVzZWQgY2FjaGVkIHZhbHVlcyBpZiBhdmFpbGFibGUuCiAgICAgKgogICAgICogQHBhcmFtIGNsYXNzTmFtZXMKICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSB3aXRoIGZ1bGZpbGxlZCB7b2JqZWN0fSBrZXllZCBieSBjbGFzc05hbWUsIHdpdGggYW4gYXJyYXkgb2Ygc3RyaW5nIGNhcGFiaWxpdHkgbmFtZXMuCiAgICAgKi8KCgogICAgX2NyZWF0ZUNsYXNzKENhcGFiaWxpdHlTdG9yZSwgW3sKICAgICAgICBrZXk6ICdyZXNvbHZlQ2FwYWJpbGl0aWVzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVzb2x2ZUNhcGFiaWxpdGllcygpIHsKICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHt9OwogICAgICAgICAgICB2YXIgY2xhc3Nlc1RvRmV0Y2ggPSBbXTsKCiAgICAgICAgICAgIC8vIGRldGVybWluZSB3aGljaCBjbGFzcyBuYW1lcyBhcmUgYWxyZWFkeSBpbiB0aGUgY2FjaGUgYW5kIHdoaWNoIGFyZW4ndAoKICAgICAgICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGNsYXNzTmFtZXMgPSBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHsKICAgICAgICAgICAgICAgIGNsYXNzTmFtZXNbX2tleV0gPSBhcmd1bWVudHNbX2tleV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZTsKICAgICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yID0gZmFsc2U7CiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JFcnJvciA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBjbGFzc05hbWVzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXA7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IChfc3RlcCA9IF9pdGVyYXRvci5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc05hbWUgPSBfc3RlcC52YWx1ZTsKCiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzSW5mbyA9IHRoaXMuX2dldFN0b3JlZENsYXNzSW5mbyhjbGFzc05hbWUpOwogICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc0luZm8pIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2NsYXNzTmFtZV0gPSBjbGFzc0luZm87CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3Nlc1RvRmV0Y2gucHVzaChjbGFzc05hbWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBpZiBub3RoaW5nIHRvIGZldGNoLCBqdXN0IHJldHVybiBhbiBpbW1lZGlhdGVseSBmdWxmaWxsZWQgUHJvbWlzZQogICAgICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yID0gdHJ1ZTsKICAgICAgICAgICAgICAgIF9pdGVyYXRvckVycm9yID0gZXJyOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gJiYgX2l0ZXJhdG9yLnJldHVybikgewogICAgICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3IucmV0dXJuKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3I7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY2xhc3Nlc1RvRmV0Y2gubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXN1bHQpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGZldGNoIHRoZSBjYXBhYmlsaXRpZXMgYW5kIHRoZW4gbWVyZ2UgdGhhdCB3aXRoIHRoZSB2YWx1ZXMgYWxyZWFkeSBpbiB0aGUgY2FjaGUKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZldGNoQ2FwYWJpbGl0aWVzKGNsYXNzZXNUb0ZldGNoKS50aGVuKGZ1bmN0aW9uIChmZXRjaGVkQ2FwYWJpbGl0aWVzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihyZXN1bHQsIGZldGNoZWRDYXBhYmlsaXRpZXMpOwogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEZldGNoIHRoZSBjYXBhYmlsaXRpZXMgZm9yIG9uZSBvciBtb3JlIGNsYXNzIG5hbWVzLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGNsYXNzTmFtZXMKICAgICAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gd2l0aCBmdWxmaWxsZWQge29iamVjdH0ga2V5ZWQgYnkgY2xhc3NOYW1lLCB3aXRoIGFuIGFycmF5IG9mIHN0cmluZyBjYXBhYmlsaXR5IG5hbWVzLgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ19mZXRjaENhcGFiaWxpdGllcycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9mZXRjaENhcGFiaWxpdGllcyhjbGFzc05hbWVzKSB7CiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7CgogICAgICAgICAgICByZXR1cm4gdGhpcy5fY2FwYWJpbGl0eUFwaS5mZXRjaENhcGFiaWxpdGllcyhjbGFzc05hbWVzKS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMuX3N0b3JlQ2FwYWJpbGl0aWVzKGRhdGEubWFwKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBTdG9yZSB0aGUgdmFsdWVzIGluIHRoZSBjYWNoZSBhbmQgcmV0dXJuIGl0LgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIG1hcAogICAgICAgICAqIEByZXR1cm5zIHtvYmplY3R9IGtleWVkIGJ5IGNsYXNzTmFtZSwgd2l0aCBhbiBhcnJheSBvZiBzdHJpbmcgY2FwYWJpbGl0eSBuYW1lcy4KICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdfc3RvcmVDYXBhYmlsaXRpZXMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfc3RvcmVDYXBhYmlsaXRpZXMobWFwKSB7CiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzOwoKICAgICAgICAgICAgdmFyIHN0b3JlZENhcGFiaWxpdGllcyA9IHt9OwoKICAgICAgICAgICAgT2JqZWN0LmtleXMobWFwKS5mb3JFYWNoKGZ1bmN0aW9uIChjbGFzc05hbWUpIHsKICAgICAgICAgICAgICAgIHZhciBjYXBhYmlsaXRpZXMgPSBtYXBbY2xhc3NOYW1lXTsKICAgICAgICAgICAgICAgIF90aGlzMi5fbG9jYWxTdG9yZVtjbGFzc05hbWVdID0gc3RvcmVkQ2FwYWJpbGl0aWVzW2NsYXNzTmFtZV0gPSBjYXBhYmlsaXRpZXMuY2xhc3Nlcy5zbGljZSgpOwogICAgICAgICAgICAgICAgLy8gQWxzbyBzdG9yZSBpbiB0aGUgYnJvd3NlciBzbyB3ZSBkb24ndCBoYXZlIHRvIGxvb2sKICAgICAgICAgICAgICAgIC8vIHVwIHRoaXMgaW5mbyBhZ2FpbiAodW5sZXNzIHRoZSBzdG9yYWdlIG5hbWVzcGFjZSBpcwogICAgICAgICAgICAgICAgLy8gY2xlYXJlZCBkdWUgdG8gamVua2lucyBvciBwbHVnaW4gY2hhbmdlcykuCiAgICAgICAgICAgICAgICBjbGFzc2VzSW5mb05TLnNldChjbGFzc05hbWUsIF90aGlzMi5fbG9jYWxTdG9yZVtjbGFzc05hbWVdKTsKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICByZXR1cm4gc3RvcmVkQ2FwYWJpbGl0aWVzOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfZ2V0U3RvcmVkQ2xhc3NJbmZvJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX2dldFN0b3JlZENsYXNzSW5mbyhjbGFzc05hbWUpIHsKICAgICAgICAgICAgaWYgKCF0aGlzLl9sb2NhbFN0b3JlW2NsYXNzTmFtZV0pIHsKICAgICAgICAgICAgICAgIC8vIElmIHdlIGRvbid0IGhhdmUgYSBjb3B5IG9mIHRoZSBjbGFzcyBpbmZvIGluIHRoZSBsb2NhbFN0b3JlLAogICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhlIGJyb3dzZXIgc3RvcmFnZSBhbmQgY29weSBpdCBpbnRvIHRoZSBsb2NhbFN0b3JlLgogICAgICAgICAgICAgICAgLy8gV2Ugc3RpbGwgd2FudCB0byB1c2UgdGhlIGxvY2FsU3RvcmUgYmVjYXVzZSBpdCBob2xkcyBkZXNlcmlhbGl6ZWQKICAgICAgICAgICAgICAgIC8vIGNvcGllcyBvZiB0aGUgY2xhc3MgaW5mbywgd2hpY2ggbWVhbnMgdGhhdCBhIGxvY2FsU3RvcmUgbG9va3VwCiAgICAgICAgICAgICAgICAvLyB3b3VsZCBiZSBsb3dlciBvdmVyaGVhZCBhbmQgcHJvYmFibHkgZmFzdGVyLgogICAgICAgICAgICAgICAgdGhpcy5fbG9jYWxTdG9yZVtjbGFzc05hbWVdID0gY2xhc3Nlc0luZm9OUy5nZXQoY2xhc3NOYW1lKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxTdG9yZVtjbGFzc05hbWVdOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gQ2FwYWJpbGl0eVN0b3JlOwp9KCk7Cn0seyIuLi9zdG9yYWdlIjo1NSwiZXM2LXByb21pc2UiOjIzMn1dLDExOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSAic3ltYm9sIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyAic3ltYm9sIiA6IHR5cGVvZiBvYmo7IH07CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCi8qKgogKiBDcmVhdGVkIGJ5IGNtZXllcnMgb24gOS85LzE2LgogKi8KCi8qKgogKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHN1cHBsaWVkIG9iamVjdCBoYXMgYXQgbGVhc3Qgb25lIG9mIHRoZSBzdXBwbGllZCBjYXBhYmlsaXRpZXMuCiAqCiAqIEFzIGNhcGFiaWxpdGllcyBhcmUgdHlwaWNhbGx5IG5hbWUtc3BhY2VkLCB0aGlzIG1ldGhvZCB3aWxsIG1hdGNoIG9uIGxvbmcgb3Igc2hvcnQgbmFtZXMsIGUuZy4KICogZ2l2ZW46IF9jYXBhYmlsaXRpZXMgPSBbJ2EuYi5DYXBhYmlsaXR5MSddCiAqIHBhc3NpbmcgZWl0aGVyICdhLmIuQ2FwYWJpbGl0eTEnIG9yICdDYXBhYmlsaXR5MScgd2lsbCBtYXRjaAogKgogKiBAcGFyYW0ge29iamVjdH0gc3ViamVjdAogKiBAcGFyYW0gey4uLnN0cmluZ30gY2FwYWJpbGl0eU5hbWVzCiAqIEByZXR1cm5zIHtib29sZWFufQogKi8KdmFyIGNhcGFibGUgPSBleHBvcnRzLmNhcGFibGUgPSBmdW5jdGlvbiBjYXBhYmxlKHN1YmplY3QpIHsKICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBjYXBhYmlsaXR5TmFtZXMgPSBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7CiAgICAgICAgY2FwYWJpbGl0eU5hbWVzW19rZXkgLSAxXSA9IGFyZ3VtZW50c1tfa2V5XTsKICAgIH0KCiAgICBpZiAoc3ViamVjdCAmJiBzdWJqZWN0Ll9jYXBhYmlsaXRpZXMpIHsKICAgICAgICB2YXIgX3JldCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIF9yZWY7CgogICAgICAgICAgICAvLyBpbiBjYXNlIGFuIGFycmF5IHdhcyBwYXNzZWQgaW4sIGZsYXR0ZW4gaXQgb3V0CiAgICAgICAgICAgIHZhciBmbGF0dGVuZWRDYXBhYmlsaXRpZXMgPSAoX3JlZiA9IFtdKS5jb25jYXQuYXBwbHkoX3JlZiwgY2FwYWJpbGl0eU5hbWVzKTsKCiAgICAgICAgICAgIC8vIGZpbmQgdGhlIGludGVyc2VjdGlvbiBvZiBzdWJqZWN0J3MgY2FwcyB3aXRoIHRoZSBwYXNzZWQtaW4gY2FwcwogICAgICAgICAgICB2YXIgbG9uZ05hbWVNYXRjaGVzID0gZmxhdHRlbmVkQ2FwYWJpbGl0aWVzLmZpbHRlcihmdW5jdGlvbiAobG9uZ05hbWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzdWJqZWN0Ll9jYXBhYmlsaXRpZXMuaW5kZXhPZihsb25nTmFtZSkgIT09IC0xOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgaWYgKGxvbmdOYW1lTWF0Y2hlcy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgIHY6IHRydWUKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGJ1aWxkIHNob3J0IGZvcm0gb2Ygc3ViamVjdCdzIGNhcHMsIHRoZW4gZmluZCBpbnRlcnNlY3Rpb24KICAgICAgICAgICAgdmFyIHNob3J0TmFtZXMgPSBzdWJqZWN0Ll9jYXBhYmlsaXRpZXMubWFwKGZ1bmN0aW9uIChsb25nTmFtZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGxvbmdOYW1lLnNwbGl0KCcuJykuc2xpY2UoLTEpLmpvaW4oJycpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIHZhciBzaG9ydE5hbWVNYXRjaGVzID0gZmxhdHRlbmVkQ2FwYWJpbGl0aWVzLmZpbHRlcihmdW5jdGlvbiAobG9uZ05hbWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzaG9ydE5hbWVzLmluZGV4T2YobG9uZ05hbWUpICE9PSAtMTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmIChzaG9ydE5hbWVNYXRjaGVzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgICAgdjogdHJ1ZQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgIH0oKTsKCiAgICAgICAgaWYgKCh0eXBlb2YgX3JldCA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YoX3JldCkpID09PSAib2JqZWN0IikgcmV0dXJuIF9yZXQudjsKICAgIH0KCiAgICByZXR1cm4gZmFsc2U7Cn07CgovKioKICogUHJvdmlkZXMgc29tZSBjb252ZW5pZW5jZSBtZXRob2RzIGZvciBob3N0IG9iamVjdCBvZiBfY2xhc3MvX2NhcGFiaWxpdGllcwogKi8KCnZhciBDYXBhYmxlID0gZXhwb3J0cy5DYXBhYmxlID0gZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gQ2FwYWJsZSgpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQ2FwYWJsZSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKENhcGFibGUsIFt7CiAgICAgICAga2V5OiAnY2FuJywKCiAgICAgICAgLyoqCiAgICAgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBob3N0IG9iamVjdCBoYXMgdGhlIHN1cHBsaWVkIGNhcGFiaWxpdHkuCiAgICAgICAgICogQXMgY2FwYWJpbGl0aWVzIGFyZSB0eXBpY2FsbHkgbmFtZS1zcGFjZWQsIHRoaXMgbWV0aG9kIHdpbGwgbWF0Y2ggb24gbG9uZyBvciBzaG9ydCBuYW1lcywgZS5nLgogICAgICAgICAqIGlmIF9jYXBhYmlsaXRpZXMgPSBbJ2EuYi5DYXBhYmlsaXR5MSddCiAgICAgICAgICogcGFzc2luZyBlaXRoZXIgJ2EuYi5DYXBhYmlsaXR5MScgb3IgJ0NhcGFiaWxpdHkxJyB3aWxsIG1hdGNoCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gY2FwYWJpbGl0eU5hbWUKICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0KICAgICAgICAgKi8KICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY2FuKGNhcGFiaWxpdHlOYW1lKSB7CiAgICAgICAgICAgIHJldHVybiBjYXBhYmxlKHRoaXMsIGNhcGFiaWxpdHlOYW1lKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIENhcGFibGU7Cn0oKTsKCmV4cG9ydHMuZGVmYXVsdCA9IG5ldyBDYXBhYmxlKCk7Cn0se31dLDEyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLmNhcGFibGUgPSBleHBvcnRzLmNhcGFiaWxpdHlBdWdtZW50ZXIgPSBleHBvcnRzLmNhcGFiaWxpdHlTdG9yZSA9IHVuZGVmaW5lZDsKCnZhciBfQ2FwYWJsZSA9IHJlcXVpcmUoJy4vQ2FwYWJsZScpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdjYXBhYmxlJywgewogIGVudW1lcmFibGU6IHRydWUsCiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICByZXR1cm4gX0NhcGFibGUuY2FwYWJsZTsKICB9Cn0pOwoKdmFyIF9DYXBhYmlsaXR5QXBpID0gcmVxdWlyZSgnLi9DYXBhYmlsaXR5QXBpJyk7Cgp2YXIgX0NhcGFiaWxpdHlTdG9yZSA9IHJlcXVpcmUoJy4vQ2FwYWJpbGl0eVN0b3JlJyk7Cgp2YXIgX0NhcGFiaWxpdHlBdWdtZW50ZXIgPSByZXF1aXJlKCcuL0NhcGFiaWxpdHlBdWdtZW50ZXInKTsKCnZhciBhcGkgPSBuZXcgX0NhcGFiaWxpdHlBcGkuQ2FwYWJpbGl0eUFwaSgpOyAvKioKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIENyZWF0ZWQgYnkgY21leWVycyBvbiA5LzgvMTYuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCnZhciBzdG9yZSA9IG5ldyBfQ2FwYWJpbGl0eVN0b3JlLkNhcGFiaWxpdHlTdG9yZShhcGkpOwp2YXIgYXVnbWVudGVyID0gbmV3IF9DYXBhYmlsaXR5QXVnbWVudGVyLkNhcGFiaWxpdHlBdWdtZW50ZXIoc3RvcmUpOwoKLy8gZXhwb3J0IGFzIG5hbWVkIHNpbmdsZXRvbnMKZXhwb3J0cy5jYXBhYmlsaXR5U3RvcmUgPSBzdG9yZTsKZXhwb3J0cy5jYXBhYmlsaXR5QXVnbWVudGVyID0gYXVnbWVudGVyOwp9LHsiLi9DYXBhYmlsaXR5QXBpIjo4LCIuL0NhcGFiaWxpdHlBdWdtZW50ZXIiOjksIi4vQ2FwYWJpbGl0eVN0b3JlIjoxMCwiLi9DYXBhYmxlIjoxMX1dLDEzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKInVzZSBzdHJpY3QiOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewoJdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuQmx1ZUxvZ28gPSB1bmRlZmluZWQ7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgicmVhY3QiKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCnZhciBKZW5raW5zTG9nbyA9IGZ1bmN0aW9uIEplbmtpbnNMb2dvKCkgewoJcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAoJCSJzdmciLAoJCXsgdmVyc2lvbjogIjEuMSIsCgkJCWlkOiAic3ZnMiIsCgkJCXhtbG5zOiAiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciLCB4OiAiMHB4IiwgeTogIjBweCIsIHZpZXdCb3g6ICI1MzMuNTAwMTIyMDcwMzEyNSAzNDcuMzk5OTkzODk2NDg0NCA3MDUuOTAwMDI0NDE0MDYyNSAxNDYuMzk5OTkzODk2NDg0MzgiCgkJfSwKCQlfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKCQkJImciLAoJCQludWxsLAoJCQlfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgicGF0aCIsIHsgZDogIk02MzQuNCwzNTguNWgtNjYuNnY2LjljMS42LDAuMiwzLjcsMC42LDYuMiwxLjFzNC42LDEuMSw2LjQsMS45YzIuNSwxLjEsNC4xLDIuMyw0LjcsMy43YzAuNywxLjQsMSwzLjIsMSw1LjMgdjc3LjVjMCwxMC4yLTIsMTcuOS02LDIyLjljLTQsNS4xLTkuNSw3LjYtMTYuNiw3LjZjLTEuOCwwLTMuNi0wLjQtNS40LTEuMmMtMS43LTAuOC0yLjktMS44LTMuNC0zdi0xLjFjMy4zLTIuNyw2LjMtNS42LDguOS04LjggczMuOS02LjYsMy45LTEwLjRjMC00LjQtMS41LTguMS00LjUtMTEuMXMtNy4xLTQuNS0xMi4yLTQuNWMtNS40LDAtOS42LDEuOC0xMi43LDUuNGMtMy4xLDMuNS00LjYsOC4xLTQuNiwxMy41IGMwLDkuMiwzLjQsMTYuNCwxMC4xLDIxLjdzMTUuNSw3LjksMjYuNSw3LjljNi4zLDAsMTIuMi0wLjksMTcuOC0yLjdjNS41LTEuOCwxMC42LTQuNSwxNS4xLThjNC40LTMuNiw4LTgsMTAuNS0xMy4zIHMzLjgtMTEuMSwzLjgtMTcuNHYtNzUuOGMwLTIuMSwwLjMtNCwxLTUuNnMyLjItMi44LDQuNi0zLjRjMi0wLjUsMy45LTAuOSw1LjUtMS4yYzEuNy0wLjMsMy43LTAuNiw2LTAuOVYzNTguNXoiCgkJCX0pLAoJCQlfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgicGF0aCIsIHsgZDogIk03MDcuNSw0NjkuMWMtNC40LDMtOS40LDQuNS0xNC45LDQuNWMtMTAuMSwwLTE3LjUtMy4xLTIyLjEtOS40Yy00LjYtNi4yLTYuOS0xNS40LTYuOS0yNy40SDcyM3YtNS43IGMwLTUtMC44LTkuOC0yLjMtMTQuM3MtNC04LjUtNy4zLTExLjhjLTMuNS0zLjYtNy44LTYuMy0xMy4xLTguM3MtMTItMy0yMC4yLTNjLTcuNSwwLTE0LjIsMS4zLTIwLjMsMy45cy0xMS4xLDUuOS0xNS4xLDEwLjEgYy00LjEsNC4yLTcuMiw5LjEtOS40LDE0LjZzLTMuMywxMS4yLTMuMywxNy4yYzAsNi42LDEsMTIuNywzLDE4LjRjMiw1LjYsNS4xLDEwLjUsOS4yLDE0LjdjNC4xLDQuMSw5LjMsNy40LDE1LjYsOS45IHMxMy44LDMuNywyMi41LDMuN2M1LjIsMCw5LjgtMC42LDEzLjgtMS43YzQtMS4yLDgtMi45LDExLjktNS4xYzMuNy0yLjEsNy00LjYsOS45LTcuNmMyLjktMi45LDUuMy02LjEsNy40LTkuNGwtNi42LTQuOCBDNzE1LjYsNDYyLjQsNzExLjksNDY2LjEsNzA3LjUsNDY5LjF6IE02NjguMSw0MDcuN2MyLjctNC42LDYuMy02LjksMTAuOC02LjljMi42LDAsNC44LDAuNyw2LjUsMi4xczMuMSwzLjQsNC4xLDYuMiBjMC44LDIuNCwxLjUsNS40LDEuOCw5LjFzMC41LDcuMywwLjUsMTAuOGwtMjguMSwwLjRDNjYzLjksNDE5LjUsNjY1LjQsNDEyLjMsNjY4LjEsNDA3Ljd6IgoJCQl9KSwKCQkJX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoInBhdGgiLCB7IGQ6ICJNODM2LjQsNDc1Yy0xLjgtMC44LTMtMS44LTMuNi0zLjFjLTAuNy0xLjMtMS0zLTEtNS4ydi00My4xYzAtOS0yLjQtMTYuMi03LjItMjEuNnMtMTItOC4xLTIxLjUtOC4xIGMtMy45LDAtNy43LDAuNS0xMS4yLDEuNXMtNi4zLDIuMi04LjUsMy42Yy0yLDEuMy00LjIsMi45LTYuNSw1Yy0yLjQsMi4xLTQuNCwzLjgtNiw1LjNoLTAuNHYtMTIuN2wtMS4zLTEuM2wtNDEuOSwyLjN2Ni40IGMxLjksMC4yLDMuNywwLjUsNS4zLDFzMi45LDEuMSw0LDEuOGMxLjUsMS4xLDIuOCwyLjUsMy43LDQuM3MxLjQsMy42LDEuNCw1LjR2NTEuMmMwLDIuMi0wLjQsNC0xLjEsNS4zYy0wLjcsMS40LTIsMi40LTMuOSwzIGMtMSwwLjMtMi4zLDAuNi0zLjgsMC44cy0yLjksMC40LTQuNCwwLjV2Ni40aDUzLjR2LTYuNGMtMS4zLTAuMi0yLjctMC41LTQuMS0wLjljLTEuNC0wLjQtMi42LTAuOS0zLjUtMS40IGMtMS4zLTAuNy0yLjMtMS43LTIuOS0zLjFjLTAuNi0xLjMtMC45LTMtMC45LTUuMXYtNDcuMmMwLjctMSwxLjYtMi4xLDIuNi0zLjNjMS0xLjIsMi40LTIuNCw0LjEtMy42YzEuOS0xLjQsMy45LTIuNCw1LjktMy4xIGMyLjEtMC43LDQuMi0xLjEsNi42LTEuMWM0LjMsMCw3LjUsMS41LDkuNyw0LjVzMy4zLDcuNSwzLjMsMTMuNXY0MS4xYzAsMi40LTAuMyw0LjItMC44LDUuNGMtMC41LDEuMi0xLjQsMi4yLTIuNiwyLjggYy0wLjgsMC40LTIuMSwwLjgtMy42LDAuOXMtMi45LDAuMy00LDAuNHY2LjRoNTIuOGgwLjF2LTYuNGMtMS44LTAuMi0zLjMtMC41LTQuNy0wLjlDODM4LjUsNDc1LjgsODM3LjMsNDc1LjQsODM2LjQsNDc1eiIKCQkJfSksCgkJCV9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCJwYXRoIiwgeyBkOiAiTTk5OS45LDM1Ni40Yy00LjgsMC04LjksMS42LTEyLjMsNC43Yy0zLjQsMy4xLTUuMSw2LjktNS4xLDExLjRzMS43LDguMyw1LjEsMTEuNGMzLjUsMy4xLDcuNiw0LjcsMTIuMyw0LjcgczguOC0xLjYsMTIuMi00LjdjMy40LTMuMiw1LjEtNi45LDUuMS0xMS40cy0xLjctOC4zLTUuMS0xMS40QzEwMDguNywzNTgsMTAwNC43LDM1Ni40LDk5OS45LDM1Ni40eiIKCQkJfSksCgkJCV9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCJwYXRoIiwgeyBkOiAiTTExNDMuNyw0NzVjLTEuOC0wLjgtMy0xLjgtMy42LTMuMWMtMC43LTEuMy0xLTMtMS01LjJ2LTQzLjFjMC05LTIuNC0xNi4yLTcuMi0yMS42Yy00LjgtNS40LTEyLTguMS0yMS41LTguMSBjLTMuOSwwLTcuNywwLjUtMTEuMiwxLjVzLTYuMywyLjItOC41LDMuNmMtMiwxLjMtNC4yLDIuOS02LjUsNWMtMi40LDIuMS00LjQsMy44LTYsNS4zaC0wLjR2LTEyLjdsLTEuMy0xLjNsLTQxLjksMi4zdjYuNCBjMS45LDAuMiwzLjcsMC41LDUuMywxczIuOSwxLjEsNCwxLjhjMS41LDEuMSwyLjgsMi41LDMuNyw0LjNjMC45LDEuOCwxLjQsMy42LDEuNCw1LjR2NTEuMmMwLDIuMi0wLjQsNC0xLjEsNS4zIGMtMC43LDEuNC0yLDIuNC0zLjksM2MtMSwwLjMtMi4zLDAuNi0zLjgsMC44cy0yLjksMC40LTQuNCwwLjV2Ni40aDUzLjR2LTYuNGMtMS4zLTAuMi0yLjctMC41LTQuMS0wLjlzLTIuNi0wLjktMy41LTEuNCBjLTEuMy0wLjctMi4zLTEuNy0yLjktMy4xYy0wLjYtMS4zLTAuOS0zLTAuOS01LjF2LTQ3LjJjMC43LTEsMS42LTIuMSwyLjYtMy4zczIuNC0yLjQsNC4xLTMuNmMxLjktMS40LDMuOS0yLjQsNS45LTMuMSBjMi4xLTAuNyw0LjItMS4xLDYuNi0xLjFjNC4zLDAsNy41LDEuNSw5LjcsNC41czMuMyw3LjUsMy4zLDEzLjV2NDEuMWMwLDIuNC0wLjMsNC4yLTAuOCw1LjRjLTAuNSwxLjItMS40LDIuMi0yLjYsMi44IGMtMC44LDAuNC0yLjEsMC44LTMuNiwwLjlzLTIuOSwwLjMtNCwwLjR2Ni40aDUyLjhoMC4xdi02LjRjLTEuOC0wLjItMy4zLTAuNS00LjctMC45UzExNDQuNiw0NzUuNCwxMTQzLjcsNDc1eiIKCQkJfSksCgkJCV9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCJwYXRoIiwgeyBkOiAiTTEyMzIuMSw0MzguMmMtMi0xLjktMS42LTEuNC0wLjctMC42Yy00LjktNC4zLTEyLjMtNy44LTIyLjMtMTAuNGMtNi43LTEuNy0xMi0zLjYtMTUuOC01LjZzLTUuNy01LjItNS43LTkuNyBjMC0zLjMsMS4zLTUuOSwzLjktNy44YzIuNS0xLjksNi4xLTIuOCwxMC42LTIuOGM1LjgsMCwxMS4xLDIuMiwxNi4xLDYuNmM0LjksNC40LDguNCw5LjcsMTAuNSwxNS44aDYuMmwtMS40LTMwaC02Ljd2MC4xIGMwLjEsMS44LTAuNSwzLTEuNCwzLjVjLTIsMS02LTAuNC02LTAuNGMtMS43LTAuNS0zLjYtMS4xLTUuNy0xLjZjLTQuNS0xLjEtOS40LTEuNi0xNC43LTEuNmMtMTEuMywwLTIwLjQsMi41LTI3LjMsNy42IHMtMTAuNCwxMS43LTEwLjQsMjBjMCw0LjQsMC44LDguMywyLjQsMTEuNWMxLjYsMy4zLDMuNyw2LDYuMyw4LjNjMywyLjYsNiw0LjUsOC44LDUuN3M2LjIsMi40LDEwLjIsMy42czcuNCwyLjIsMTAuMSwzIHM1LjIsMS44LDcuNSwzYzIsMS4yLDMuNiwyLjUsNC44LDRjMS4yLDEuNSwxLjgsMy41LDEuOCw1LjhjMCw0LjMtMS4zLDcuNS0zLjksOS42cy02LjYsMy4xLTExLjksMy4xYy00LjEsMC03LjktMC45LTExLjQtMi43IGMtMy41LTEuOC02LjYtNC4xLTkuNC02LjdjLTIuNi0yLjYtNC45LTUuNi03LTguOXMtMy41LTYuMy00LjQtOC45aC02LjRsMC44LDIzLjlsMC4zLDguOWg2LjNjMCwwLDAsMCwwLTAuMSBjLTAuMi0yLDAuNS0zLjMsMS41LTMuOGMyLjgtMS4zLDUuNiwwLjEsOC40LDEuMWMxLjgsMC43LDMuNywxLjQsNS45LDIuMWMwLjksMC4zLDEuOCwwLjUsMi43LDAuOGM0LjYsMS4yLDkuMiwxLjcsMTQsMS43IGMxMi4xLDAsMjItMi42LDI5LjQtOGM3LjUtNS4yLDExLjMtMTIuNywxMS4zLTIyLjNjMC02LjktMi4yLTEyLjYtNi43LTE3LjJDMTIzMy43LDQzOS43LDEyMzQuMSw0NDAuMiwxMjMyLjEsNDM4LjJ6IgoJCQl9KSwKCQkJX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoInBhdGgiLCB7IGQ6ICJNOTU2LjksNDc1LjVjLTIuNy0wLjktNS0yLjctNi44LTUuNWMtNS40LTcuOS0xMC40LTE1LjQtMTUuMy0yMi41cy0xMC4yLTE0LjgtMTUuOS0yMy4xIGMzLTIuNiw1LjYtNC44LDcuOC02LjVjMi4zLTEuOCw0LjYtMy40LDctNWMzLjYtMi40LDYuOS00LjQsMTAtNS44czYuNS0zLDEyLjQtNC42di02LjFoLTQzLjZ2Ni4yYzMuOCwwLjUsNi41LDEuMSw4LjQsMS44IHMyLjgsMS41LDIuOCwyLjZjMCwwLjItMC4xLDAuOS0wLjMsMS45cy0xLjMsMi41LTMuMiw0LjVjLTMuMiwzLjQtNy42LDcuNi0xMywxMi43cy0xMC4zLDkuNS0xNC42LDEzLjR2LTkwLjdsLTEuMy0xLjRsLTQzLjgsMi4zIHY2LjRjMS45LDAuMSwzLjksMC40LDYuMSwwLjljMi4yLDAuNSwzLjksMS4xLDUsMS44YzEuNiwxLjEsMi45LDIuNiwzLjcsNC43YzAuOSwyLjEsMS4zLDQuMSwxLjMsNnY5OGMwLDIuMi0wLjMsNC0xLDUuMyBjLTAuNiwxLjQtMS45LDIuNC0zLjgsM2MtMS4xLDAuMy0yLjQsMC42LTMuOSwwLjhzLTIuOSwwLjQtNC40LDAuNXY2LjRoNTQuNnYtNi40Yy0xLjQtMC4xLTIuOC0wLjQtNC4yLTAuNyBjLTEuNC0wLjMtMi42LTAuNy0zLjctMS4yYy0xLjgtMC43LTMtMS43LTMuNi0zYy0wLjYtMS40LTAuOS0zLjEtMC45LTUuMnYtMTkuMmw1LjItNC40YzMuNyw1LjMsNy43LDExLjEsMTEuOSwxNy4zIGM0LjMsNi4yLDguOSwxMy44LDE0LDIyLjdIOTY1di02LjFDOTYyLjMsNDc3LDk1OS42LDQ3Ni40LDk1Ni45LDQ3NS41eiIKCQkJfSksCgkJCV9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCJwYXRoIiwgeyBkOiAiTTEwMTkuOSw0NzQuOGMtMS43LTAuNy0yLjktMS44LTMuOC0zLjJjLTAuOS0xLjQtMS4zLTMuMS0xLjMtNS4ydi02OS44bC0xLjMtMS4zbC00NS4xLDIuM3Y2LjQgYzEuNywwLjEsNS43LDAuNiw3LjgsMS4yczMuNywxLjMsNC44LDJjMS40LDAuOSwyLjYsMi4xLDMuNSwzLjdjMC45LDEuNSwxLjQsMy4zLDEuNCw1LjR2NTEuMmMwLDIuMS0wLjMsMy45LTEuMSw1LjIgYy0wLjgsMS4zLTIuMSwyLjMtNCwzYy0xLjEsMC40LTIuMywwLjctMy44LDAuOWMtMS41LDAuMS0zLDAuMy00LjUsMC40djYuNGg1NS41aDAuMnYtNi4zYy0xLjUtMC4yLTMtMC41LTQuNC0wLjkgQzEwMjIuNCw0NzUuOCwxMDIxLjEsNDc1LjMsMTAxOS45LDQ3NC44eiIKCQkJfSkKCQkpCgkpOwp9OwoKdmFyIEJsdWVMb2dvID0gZXhwb3J0cy5CbHVlTG9nbyA9IGZ1bmN0aW9uIEJsdWVMb2dvKHByb3BzKSB7CglyZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCgkJImEiLAoJCXsgaHJlZjogcHJvcHMuaHJlZiB8fCAnIycsIGNsYXNzTmFtZTogIkJsdWVPY2VhbkxvZ28iIH0sCgkJX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoSmVua2luc0xvZ28sIG51bGwpCgkpOwp9OwoKQmx1ZUxvZ28ucHJvcFR5cGVzID0gewoJaHJlZjogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcKfTsKfSx7InJlYWN0Ijo2MjN9XSwxNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLkNvbnRlbnRQYWdlSGVhZGVyID0gZXhwb3J0cy5TaXRlSGVhZGVyID0gdW5kZWZpbmVkOwpleHBvcnRzLl93cmFwID0gX3dyYXA7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9kZXNpZ25MYW5ndWFnZSA9IHJlcXVpcmUoJ0BqZW5raW5zLWNkL2Rlc2lnbi1sYW5ndWFnZScpOwoKdmFyIF9CbHVlTG9nbyA9IHJlcXVpcmUoJy4vQmx1ZUxvZ28nKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfdG9Db25zdW1hYmxlQXJyYXkoYXJyKSB7IGlmIChBcnJheS5pc0FycmF5KGFycikpIHsgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBBcnJheShhcnIubGVuZ3RoKTsgaSA8IGFyci5sZW5ndGg7IGkrKykgeyBhcnIyW2ldID0gYXJyW2ldOyB9IHJldHVybiBhcnIyOyB9IGVsc2UgeyByZXR1cm4gQXJyYXkuZnJvbShhcnIpOyB9IH0KCi8vIFdyYXAgYW4gYXJyYXkgb2YgZWxlbWVudHMgaW4gYSBwYXJlbnQgZWxlbWVudCB3aXRob3V0IHJlcXVpcmluZyBhIGJ1bmNoICJrZXkiIHByb3BzCi8vIEZJWE1FOiBUaGlzIHNob3VsZCBiZSBzdHJlbmd0aGVuZWQgYSBsaXR0bGUsIGFuZCBwcm9tb3RlZCB0byBKREwgd2l0aCBzb21lIHRlc3RzCmZ1bmN0aW9uIF93cmFwKGNoaWxkcmVuKSB7CiAgICB2YXIgZWxlbWVudE9yQ29tcG9uZW50ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAnZGl2JzsKICAgIHZhciBwcm9wcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDoge307CgogICAgaWYgKCFjaGlsZHJlbikgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHZhciBjaGlsZEFycmF5ID0gQXJyYXkuaXNBcnJheShjaGlsZHJlbikgPyBjaGlsZHJlbiA6IFtjaGlsZHJlbl07CiAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQuYXBwbHkoX3JlYWN0Mi5kZWZhdWx0LCBbZWxlbWVudE9yQ29tcG9uZW50LCBwcm9wc10uY29uY2F0KF90b0NvbnN1bWFibGVBcnJheShjaGlsZEFycmF5KSkpOwp9Cgp2YXIgU2l0ZUhlYWRlciA9IGV4cG9ydHMuU2l0ZUhlYWRlciA9IGZ1bmN0aW9uIFNpdGVIZWFkZXIocHJvcHMpIHsKICAgIHZhciB0b3BOYXZMaW5rcyA9IF93cmFwKHByb3BzLnRvcE5hdkxpbmtzLCAnbmF2Jyk7CiAgICB2YXIgdXNlckNvbXBvbmVudHMgPSBfd3JhcChwcm9wcy51c2VyQ29tcG9uZW50cywgJ2RpdicsIHsgY2xhc3NOYW1lOiAnQ29udGVudFBhZ2VIZWFkZXItdXNlcicgfSk7CgogICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgIF9kZXNpZ25MYW5ndWFnZS5CYXNpY0hlYWRlciwKICAgICAgICB7IGNsYXNzTmFtZTogJ0NvbnRlbnRQYWdlSGVhZGVyJyB9LAogICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICBfZGVzaWduTGFuZ3VhZ2UuVG9wTmF2LAogICAgICAgICAgICBudWxsLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChfQmx1ZUxvZ28uQmx1ZUxvZ28sIHsgaHJlZjogcHJvcHMuaG9tZVVSTCB9KSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ2RpdicsIHsgY2xhc3NOYW1lOiAndS1mbGV4LWdyb3cnIH0pLAogICAgICAgICAgICB0b3BOYXZMaW5rcywKICAgICAgICAgICAgdXNlckNvbXBvbmVudHMKICAgICAgICApCiAgICApOwp9OwoKU2l0ZUhlYWRlci5wcm9wVHlwZXMgPSB7CiAgICB0b3BOYXZMaW5rczogX3JlYWN0LlByb3BUeXBlcy5ub2RlLAogICAgdXNlckNvbXBvbmVudHM6IF9yZWFjdC5Qcm9wVHlwZXMubm9kZSwKICAgIGNoaWxkcmVuOiBfcmVhY3QuUHJvcFR5cGVzLm5vZGUsCiAgICBob21lVVJMOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZwp9OwoKdmFyIENvbnRlbnRQYWdlSGVhZGVyID0gZXhwb3J0cy5Db250ZW50UGFnZUhlYWRlciA9IGZ1bmN0aW9uIENvbnRlbnRQYWdlSGVhZGVyKHByb3BzKSB7CiAgICB2YXIgcGFnZVRhYkxpbmtzID0gX3dyYXAocHJvcHMucGFnZVRhYkxpbmtzLCBfZGVzaWduTGFuZ3VhZ2UuUGFnZVRhYnMsIHsgYmFzZTogcHJvcHMucGFnZVRhYkJhc2UgfSk7CgogICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgIF9kZXNpZ25MYW5ndWFnZS5CYXNpY0hlYWRlciwKICAgICAgICB7IGNsYXNzTmFtZTogJ0NvbnRlbnRQYWdlSGVhZGVyJyB9LAogICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICBfZGVzaWduTGFuZ3VhZ2UuSGVhZGVyRGV0YWlscywKICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnQ29udGVudFBhZ2VIZWFkZXItbWFpbiB1LWZsZXgtZ3JvdycgfSwKICAgICAgICAgICAgICAgIHByb3BzLmNoaWxkcmVuCiAgICAgICAgICAgICksCiAgICAgICAgICAgIHBhZ2VUYWJMaW5rcwogICAgICAgICkKICAgICk7Cn07CgpDb250ZW50UGFnZUhlYWRlci5wcm9wVHlwZXMgPSB7CiAgICBwYWdlVGFiTGlua3M6IF9yZWFjdC5Qcm9wVHlwZXMubm9kZSwKICAgIGNoaWxkcmVuOiBfcmVhY3QuUHJvcFR5cGVzLm5vZGUsCiAgICBwYWdlVGFiQmFzZTogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcKfTsKCmV4cG9ydHMuZGVmYXVsdCA9IENvbnRlbnRQYWdlSGVhZGVyOwp9LHsiLi9CbHVlTG9nbyI6MTMsIkBqZW5raW5zLWNkL2Rlc2lnbi1sYW5ndWFnZSI6MTA3LCJyZWFjdCI6NjIzfV0sMTU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5MaXZlU3RhdHVzSW5kaWNhdG9yID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9kZXNpZ25MYW5ndWFnZSA9IHJlcXVpcmUoJ0BqZW5raW5zLWNkL2Rlc2lnbi1sYW5ndWFnZScpOwoKdmFyIF9UaW1lSGFybW9uaXplciA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvVGltZUhhcm1vbml6ZXInKTsKCnZhciBfbG9nZ2luZyA9IHJlcXVpcmUoJy4uL2xvZ2dpbmcnKTsKCnZhciBfbG9nZ2luZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9sb2dnaW5nKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0KCnZhciBsb2dnZXIgPSBfbG9nZ2luZzIuZGVmYXVsdC5sb2dnZXIoJ2lvLmplbmtpbnMuYmx1ZW9jZWFuLmNvcmUuTGl2ZVN0YXR1c0luZGljYXRvcicpOwoKdmFyIExpdmVTdGF0dXNJbmRpY2F0b3IgPSBleHBvcnRzLkxpdmVTdGF0dXNJbmRpY2F0b3IgPSBmdW5jdGlvbiAoX0NvbXBvbmVudCkgewogICAgX2luaGVyaXRzKExpdmVTdGF0dXNJbmRpY2F0b3IsIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIExpdmVTdGF0dXNJbmRpY2F0b3IoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIExpdmVTdGF0dXNJbmRpY2F0b3IpOwoKICAgICAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKExpdmVTdGF0dXNJbmRpY2F0b3IuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihMaXZlU3RhdHVzSW5kaWNhdG9yKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKExpdmVTdGF0dXNJbmRpY2F0b3IsIFt7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcywKICAgICAgICAgICAgICAgIHJlc3VsdCA9IF9wcm9wcy5yZXN1bHQsCiAgICAgICAgICAgICAgICBnZXRJMThuVGl0bGUgPSBfcHJvcHMuZ2V0STE4blRpdGxlOwoKICAgICAgICAgICAgdmFyIHRpdGxlID0gZ2V0STE4blRpdGxlKHJlc3VsdCk7CiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnaTE4biB0aXRsZScsIHRpdGxlKTsKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICB7IHRpdGxlOiB0aXRsZSB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoX2Rlc2lnbkxhbmd1YWdlLkxpdmVTdGF0dXNJbmRpY2F0b3IsIHRoaXMucHJvcHMpCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBMaXZlU3RhdHVzSW5kaWNhdG9yOwp9KF9yZWFjdC5Db21wb25lbnQpOwoKTGl2ZVN0YXR1c0luZGljYXRvci5wcm9wVHlwZXMgPSB7CiAgICByZXN1bHQ6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgcGVyY2VudGFnZTogX3JlYWN0LlByb3BUeXBlcy5udW1iZXIsCiAgICB3aWR0aDogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBoZWlnaHQ6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgbm9CYWNrZ3JvdW5kOiBfcmVhY3QuUHJvcFR5cGVzLmJvb2wsCiAgICBzdGFydFRpbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgZXN0aW1hdGVkRHVyYXRpb246IF9yZWFjdC5Qcm9wVHlwZXMubnVtYmVyLAogICAgZHVyYXRpb25Jbk1pbGxpczogX3JlYWN0LlByb3BUeXBlcy5udW1iZXIsCiAgICBnZXRJMThuVGl0bGU6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYwp9OwoKZXhwb3J0cy5kZWZhdWx0ID0gKDAsIF9UaW1lSGFybW9uaXplci5UaW1lSGFybW9uaXplcikoTGl2ZVN0YXR1c0luZGljYXRvcik7Cn0seyIuLi9jb21wb25lbnRzL1RpbWVIYXJtb25pemVyIjoyMCwiLi4vbG9nZ2luZyI6MjcsIkBqZW5raW5zLWNkL2Rlc2lnbi1sYW5ndWFnZSI6MTA3LCJyZWFjdCI6NjIzfV0sMTY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5SZXBsYXlCdXR0b24gPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX3JlYWN0TWF0ZXJpYWxJY29ucyA9IHJlcXVpcmUoJ0BqZW5raW5zLWNkL3JlYWN0LW1hdGVyaWFsLWljb25zJyk7Cgp2YXIgX2luZGV4ID0gcmVxdWlyZSgnLi4vaW5kZXgnKTsKCnZhciBfc2VjdXJpdHkgPSByZXF1aXJlKCcuLi9zZWN1cml0eScpOwoKdmFyIF9zZWN1cml0eTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zZWN1cml0eSk7Cgp2YXIgX2kxOG4gPSByZXF1aXJlKCcuLi9pMThuL2kxOG4nKTsKCnZhciBfaTE4bjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pMThuKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0gLyoqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIENyZWF0ZWQgYnkgY21leWVycyBvbiA4LzMwLzE2LgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCnZhciBwZXJtaXQgPSBfc2VjdXJpdHkyLmRlZmF1bHQucGVybWl0OwoKdmFyIHRyYW5zbGF0ZSA9ICgwLCBfaTE4bjIuZGVmYXVsdCkoJ2JsdWVvY2Vhbi13ZWInKTsKCnZhciBzdG9wUHJvcCA9IGZ1bmN0aW9uIHN0b3BQcm9wKGV2ZW50KSB7CiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKfTsKCnZhciBDQVBBQklMSVRZX01VTFRJQlJBTkNIX1BJUEVMSU5FID0gJ2lvLmplbmtpbnMuYmx1ZW9jZWFuLnJlc3QubW9kZWwuQmx1ZU11bHRpQnJhbmNoUGlwZWxpbmUnOwp2YXIgQ0FQQUJJTElUWV9NVUxUSUJSQU5DSF9CUkFOQ0ggPSAnaW8uamVua2lucy5ibHVlb2NlYW4ucmVzdC5tb2RlbC5CbHVlQnJhbmNoJzsKdmFyIENBUEFCSUxJVFlfU0lNUExFX1BJUEVMSU5FID0gJ29yZy5qZW5raW5zY2kucGx1Z2lucy53b3JrZmxvdy5qb2IuV29ya2Zsb3dKb2InOwp2YXIgUElQRUxJTkVfQ0FQQUJJTElUSUVTID0gW0NBUEFCSUxJVFlfU0lNUExFX1BJUEVMSU5FLCBDQVBBQklMSVRZX01VTFRJQlJBTkNIX1BJUEVMSU5FLCBDQVBBQklMSVRZX01VTFRJQlJBTkNIX0JSQU5DSF07CgpmdW5jdGlvbiBpc1J1bkZpbmlzaGVkKHJ1bikgewogICAgcmV0dXJuICEhKHJ1biAmJiBydW4uc3RhdGUgPT09ICdGSU5JU0hFRCcpOwp9CgovKioKICogUmVwbGF5QnV0dG9uIGFsbG93cyBhIHBpcGVsaW5lIG9yIGJyYW5jaCB0byBiZSByZS1ydW4gd2hlbiBpbiBhIGZhaWx1cmUgc3RhdGUuCiAqLwoKdmFyIFJlcGxheUJ1dHRvbiA9IGV4cG9ydHMuUmVwbGF5QnV0dG9uID0gZnVuY3Rpb24gKF9Db21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhSZXBsYXlCdXR0b24sIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIFJlcGxheUJ1dHRvbihwcm9wcykgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBSZXBsYXlCdXR0b24pOwoKICAgICAgICB2YXIgX3RoaXMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoUmVwbGF5QnV0dG9uLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoUmVwbGF5QnV0dG9uKSkuY2FsbCh0aGlzLCBwcm9wcykpOwoKICAgICAgICBfdGhpcy5zdGF0ZSA9IHsKICAgICAgICAgICAgcmVwbGF5aW5nOiBmYWxzZQogICAgICAgIH07CiAgICAgICAgcmV0dXJuIF90aGlzOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhSZXBsYXlCdXR0b24sIFt7CiAgICAgICAga2V5OiAnY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7CiAgICAgICAgICAgIHZhciBzdGF0dXNDaGFuZ2VkID0gaXNSdW5GaW5pc2hlZCh0aGlzLnByb3BzLmxhdGVzdFJ1bikgIT09IGlzUnVuRmluaXNoZWQobmV4dFByb3BzLmxhdGVzdFJ1bik7CgogICAgICAgICAgICBpZiAoc3RhdHVzQ2hhbmdlZCkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7CiAgICAgICAgICAgICAgICAgICAgcmVwbGF5aW5nOiBmYWxzZQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX29uUmVwbGF5Q2xpY2snLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfb25SZXBsYXlDbGljaygpIHsKICAgICAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7CgogICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5yZXBsYXlpbmcpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7CiAgICAgICAgICAgICAgICByZXBsYXlpbmc6IHRydWUKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICBfaW5kZXguUnVuQXBpLnJlcGxheVJ1bih0aGlzLnByb3BzLmxhdGVzdFJ1bikudGhlbihmdW5jdGlvbiAocnVuSW5mbykgewogICAgICAgICAgICAgICAgcmV0dXJuIF9pbmRleC5Ub2FzdFV0aWxzLmNyZWF0ZVJ1blN0YXJ0ZWRUb2FzdChfdGhpczIucHJvcHMucnVubmFibGUsIHJ1bkluZm8sIF90aGlzMi5wcm9wcy5vbk5hdmlnYXRpb24pOwogICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChydW5EZXRhaWxzVXJsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMyLl9hZnRlclJlcGxheVN0YXJ0ZWQocnVuRGV0YWlsc1VybCk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfYWZ0ZXJSZXBsYXlTdGFydGVkJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX2FmdGVyUmVwbGF5U3RhcnRlZChydW5EZXRhaWxzVXJsKSB7CiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmF1dG9OYXZpZ2F0ZSAmJiB0aGlzLnByb3BzLm9uTmF2aWdhdGlvbikgewogICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vbk5hdmlnYXRpb24ocnVuRGV0YWlsc1VybCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX3RoaXMzID0gdGhpczsKCiAgICAgICAgICAgIGlmICghdGhpcy5wcm9wcy5ydW5uYWJsZSB8fCAhdGhpcy5wcm9wcy5sYXRlc3RSdW4pIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgb3V0ZXJDbGFzcyA9IHRoaXMucHJvcHMuY2xhc3NOYW1lID8gdGhpcy5wcm9wcy5jbGFzc05hbWUgOiAnJzsKICAgICAgICAgICAgdmFyIG91dGVyQ2xhc3NOYW1lcyA9IG91dGVyQ2xhc3Muc3BsaXQoJyAnKTsKICAgICAgICAgICAgdmFyIGlubmVyQnV0dG9uQ2xhc3MgPSBvdXRlckNsYXNzTmFtZXMuaW5kZXhPZignaWNvbi1idXR0b24nKSA9PT0gLTEgPyAnYnRuIGludmVyc2UnIDogJyc7CgogICAgICAgICAgICB2YXIgaXNGaW5pc2hlZCA9IGlzUnVuRmluaXNoZWQodGhpcy5wcm9wcy5sYXRlc3RSdW4pOwogICAgICAgICAgICB2YXIgaXNQaXBlbGluZSA9ICgwLCBfaW5kZXguY2FwYWJsZSkodGhpcy5wcm9wcy5ydW5uYWJsZSwgUElQRUxJTkVfQ0FQQUJJTElUSUVTKTsKICAgICAgICAgICAgdmFyIGhhc1Blcm1pc3Npb24gPSBwZXJtaXQodGhpcy5wcm9wcy5ydW5uYWJsZSkuc3RhcnQoKTsKCiAgICAgICAgICAgIHZhciByZXBsYXlMYWJlbCA9IHRyYW5zbGF0ZSgndG9hc3QucmUtcnVuJywgeyBkZWZhdWx0VmFsdWU6ICdSZS1ydW4nIH0pOwoKICAgICAgICAgICAgaWYgKCFpc0ZpbmlzaGVkIHx8ICFpc1BpcGVsaW5lIHx8ICFoYXNQZXJtaXNzaW9uKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3JlcGxheS1idXR0b24tY29tcG9uZW50ICcgKyBvdXRlckNsYXNzLCBvbkNsaWNrOiBmdW5jdGlvbiBvbkNsaWNrKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdG9wUHJvcChldmVudCk7CiAgICAgICAgICAgICAgICAgICAgfSB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2EnLAogICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAncmVwbGF5LWJ1dHRvbiAnICsgaW5uZXJCdXR0b25DbGFzcywgdGl0bGU6IHJlcGxheUxhYmVsLCBvbkNsaWNrOiBmdW5jdGlvbiBvbkNsaWNrKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzMy5fb25SZXBsYXlDbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICB9IH0sCiAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoX3JlYWN0TWF0ZXJpYWxJY29ucy5JY29uLCB7IHNpemU6IDI0LCBpY29uOiAncmVwbGF5JyB9KSwKICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLAogICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2J1dHRvbi1sYWJlbCcgfSwKICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGF5TGFiZWwKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBSZXBsYXlCdXR0b247Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpSZXBsYXlCdXR0b24ucHJvcFR5cGVzID0gewogICAgY2xhc3NOYW1lOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIHJ1bm5hYmxlOiBfcmVhY3QuUHJvcFR5cGVzLm9iamVjdCwKICAgIGxhdGVzdFJ1bjogX3JlYWN0LlByb3BUeXBlcy5vYmplY3QsCiAgICBhdXRvTmF2aWdhdGU6IF9yZWFjdC5Qcm9wVHlwZXMuYm9vbCwKICAgIG9uTmF2aWdhdGlvbjogX3JlYWN0LlByb3BUeXBlcy5mdW5jCn07Cn0seyIuLi9pMThuL2kxOG4iOjI0LCIuLi9pbmRleCI6MjUsIi4uL3NlY3VyaXR5Ijo0NCwiQGplbmtpbnMtY2QvcmVhY3QtbWF0ZXJpYWwtaWNvbnMiOjEyOSwicmVhY3QiOjYyM31dLDE3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuUmVzdWx0UGFnZUhlYWRlciA9IHVuZGVmaW5lZDsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX2Rlc2lnbkxhbmd1YWdlID0gcmVxdWlyZSgnQGplbmtpbnMtY2QvZGVzaWduLWxhbmd1YWdlJyk7Cgp2YXIgX0NvbnRlbnRQYWdlSGVhZGVyID0gcmVxdWlyZSgnLi9Db250ZW50UGFnZUhlYWRlcicpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCi8vIEV4cG9ydGVkIGZyb20gWmVwbGluLCBwYXRoIGNvdWxkIHVzZSBhIGxpdHRsZSBjbGVhbnVwCnZhciBDbG9zZUJ1dHRvbiA9IGZ1bmN0aW9uIENsb3NlQnV0dG9uKHByb3BzKSB7CiAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgJ3N2ZycsCiAgICAgICAgeyBjbGFzc05hbWU6ICdSZXN1bHRQYWdlSGVhZGVyLWNsb3NlJywgd2lkdGg6ICcyNHB4JywgaGVpZ2h0OiAnMjRweCcsCiAgICAgICAgICAgIHZpZXdCb3g6ICcwIDAgMjQgMjQnLAogICAgICAgICAgICBvbkNsaWNrOiBwcm9wcy5vbkNsaWNrLAogICAgICAgICAgICB2ZXJzaW9uOiAnMS4xJwogICAgICAgIH0sCiAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICdnJywKICAgICAgICAgICAgeyBzdHJva2VXaWR0aDogJzEnIH0sCiAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwb2x5Z29uJywgeyBwb2ludHM6ICcxOSA2LjQxNSAxNy41ODUgNSAxMiAxMC41ODUgNi40MTUgNSA1IDYuNDE1IDEwLjU4NSAxMiA1IDE3LjU4NSA2LjQxNSAxOSAxMiAxMy40MTUgMTcuNTg1IDE5IDE5IDE3LjU4NSAxMy40MTUgMTInIH0pCiAgICAgICAgKQogICAgKTsKfTsKCkNsb3NlQnV0dG9uLnByb3BUeXBlcyA9IHsKICAgIG9uQ2xpY2s6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYwp9OwoKdmFyIFJlc3VsdFBhZ2VIZWFkZXIgPSBleHBvcnRzLlJlc3VsdFBhZ2VIZWFkZXIgPSBmdW5jdGlvbiBSZXN1bHRQYWdlSGVhZGVyKHByb3BzKSB7CiAgICB2YXIgX3Byb3BzJHN0YXR1cyA9IHByb3BzLnN0YXR1cywKICAgICAgICBzdGF0dXMgPSBfcHJvcHMkc3RhdHVzID09PSB1bmRlZmluZWQgPyAndW5rbm93bicgOiBfcHJvcHMkc3RhdHVzLAogICAgICAgIHRpdGxlID0gcHJvcHMudGl0bGUsCiAgICAgICAgb25DbG9zZUNsaWNrID0gcHJvcHMub25DbG9zZUNsaWNrLAogICAgICAgIHN0YXJ0VGltZSA9IHByb3BzLnN0YXJ0VGltZSwKICAgICAgICBlc3RpbWF0ZWREdXJhdGlvbkluTWlsbGlzID0gcHJvcHMuZXN0aW1hdGVkRHVyYXRpb25Jbk1pbGxpczsKCgogICAgdmFyIGNsb3NlQ2xpY2tlZCA9IGZ1bmN0aW9uIGNsb3NlQ2xpY2tlZCgpIHsKICAgICAgICBpZiAob25DbG9zZUNsaWNrKSB7CiAgICAgICAgICAgIG9uQ2xvc2VDbGljaygpOwogICAgICAgIH0KICAgIH07CgogICAgdmFyIHRpdGxlQ29tcCA9ICgwLCBfQ29udGVudFBhZ2VIZWFkZXIuX3dyYXApKHRpdGxlLCAnZGl2JywgeyBjbGFzc05hbWU6ICdSZXN1bHRQYWdlSGVhZGVyLXRpdGxlIHUtZmxleC1ncm93JyB9KTsKICAgIHZhciB0b3BOYXZMaW5rcyA9ICgwLCBfQ29udGVudFBhZ2VIZWFkZXIuX3dyYXApKHByb3BzLnRvcE5hdkxpbmtzLCAnbmF2Jyk7CiAgICB2YXIgcnVuQnV0dG9uID0gKDAsIF9Db250ZW50UGFnZUhlYWRlci5fd3JhcCkocHJvcHMucnVuQnV0dG9uLCAnZGl2JywgeyBjbGFzc05hbWU6ICdSZXN1bHRQYWdlSGVhZGVyLXJ1bicgfSk7CgogICAgdmFyIGNsYXNzTmFtZXMgPSBbJ1Jlc3VsdFBhZ2VIZWFkZXInXTsKICAgIGlmIChwcm9wcy5jbGFzc05hbWUpIHsKICAgICAgICBjbGFzc05hbWVzLnB1c2gocHJvcHMuY2xhc3NOYW1lKTsKICAgIH0KCiAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgX2Rlc2lnbkxhbmd1YWdlLkJhc2ljSGVhZGVyLAogICAgICAgIHsgY2xhc3NOYW1lOiBjbGFzc05hbWVzLmpvaW4oJyAnKSwgc3RhdHVzQ29sb3I6IHN0YXR1cyB9LAogICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICBfZGVzaWduTGFuZ3VhZ2UuVG9wTmF2LAogICAgICAgICAgICBudWxsLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdzZWN0aW9uJywKICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnUmVzdWx0UGFnZUhlYWRlci1pbmRpY2F0b3Igc3RhdHVzIGludmVyc2UnIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChfZGVzaWduTGFuZ3VhZ2UuTGl2ZVN0YXR1c0luZGljYXRvciwgeyByZXN1bHQ6IHN0YXR1cywgc3RhcnRUaW1lOiBzdGFydFRpbWUsCiAgICAgICAgICAgICAgICAgICAgZXN0aW1hdGVkRHVyYXRpb246IGVzdGltYXRlZER1cmF0aW9uSW5NaWxsaXMsCiAgICAgICAgICAgICAgICAgICAgbm9CYWNrZ3JvdW5kOiB0cnVlCiAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICApLAogICAgICAgICAgICB0aXRsZUNvbXAsCiAgICAgICAgICAgIHRvcE5hdkxpbmtzLAogICAgICAgICAgICBydW5CdXR0b24sCiAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KENsb3NlQnV0dG9uLCB7IG9uQ2xpY2s6IGNsb3NlQ2xpY2tlZCB9KQogICAgICAgICksCiAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgIF9kZXNpZ25MYW5ndWFnZS5IZWFkZXJEZXRhaWxzLAogICAgICAgICAgICBudWxsLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdSZXN1bHRQYWdlSGVhZGVyLW1haW4gdS1mbGV4LWdyb3cnIH0sCiAgICAgICAgICAgICAgICBwcm9wcy5jaGlsZHJlbgogICAgICAgICAgICApCiAgICAgICAgKQogICAgKTsKfTsKClJlc3VsdFBhZ2VIZWFkZXIucHJvcFR5cGVzID0gewogICAgY2xhc3NOYW1lOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIGNoaWxkcmVuOiBfcmVhY3QuUHJvcFR5cGVzLm5vZGUsCiAgICBzdGF0dXM6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgb25DbG9zZUNsaWNrOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsCiAgICB0aXRsZTogX3JlYWN0LlByb3BUeXBlcy5ub2RlLAogICAgdG9wTmF2TGlua3M6IF9yZWFjdC5Qcm9wVHlwZXMubm9kZSwKICAgIHJ1bkJ1dHRvbjogX3JlYWN0LlByb3BUeXBlcy5ub2RlLAogICAgc3RhcnRUaW1lOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIGVzdGltYXRlZER1cmF0aW9uSW5NaWxsaXM6IF9yZWFjdC5Qcm9wVHlwZXMubnVtYmVyCn07Cn0seyIuL0NvbnRlbnRQYWdlSGVhZGVyIjoxNCwiQGplbmtpbnMtY2QvZGVzaWduLWxhbmd1YWdlIjoxMDcsInJlYWN0Ijo2MjN9XSwxODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlJ1bkJ1dHRvbiA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfcmVhY3RNYXRlcmlhbEljb25zID0gcmVxdWlyZSgnQGplbmtpbnMtY2QvcmVhY3QtbWF0ZXJpYWwtaWNvbnMnKTsKCnZhciBfID0gcmVxdWlyZSgnLi4vJyk7Cgp2YXIgX3NlY3VyaXR5ID0gcmVxdWlyZSgnLi4vc2VjdXJpdHknKTsKCnZhciBfc2VjdXJpdHkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfc2VjdXJpdHkpOwoKdmFyIF9pMThuID0gcmVxdWlyZSgnLi4vaTE4bi9pMThuJyk7Cgp2YXIgX2kxOG4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaTE4bik7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9IC8qKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBDcmVhdGVkIGJ5IGNtZXllcnMgb24gOC8yNi8xNi4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCgoKdmFyIHRyYW5zbGF0ZSA9ICgwLCBfaTE4bjIuZGVmYXVsdCkoJ2JsdWVvY2Vhbi13ZWInKTsKCnZhciBwZXJtaXQgPSBfc2VjdXJpdHkyLmRlZmF1bHQucGVybWl0OwoKCnZhciBzdG9wUHJvcCA9IGZ1bmN0aW9uIHN0b3BQcm9wKGV2ZW50KSB7CiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKfTsKCi8qKgogKiBSdW4gQnV0dG9ucyBhbGxvd3MgYSBwaXBlbGluZSBvciBicmFuY2ggdG8gYmUgcnVuIGFuZCBhbHNvIGJlIHN0b3BwZWQgdGhlcmVhZnRlci4KICovCgp2YXIgUnVuQnV0dG9uID0gZXhwb3J0cy5SdW5CdXR0b24gPSBmdW5jdGlvbiAoX0NvbXBvbmVudCkgewogICAgX2luaGVyaXRzKFJ1bkJ1dHRvbiwgX0NvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gUnVuQnV0dG9uKHByb3BzKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFJ1bkJ1dHRvbik7CgogICAgICAgIHZhciBfdGhpcyA9IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChSdW5CdXR0b24uX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihSdW5CdXR0b24pKS5jYWxsKHRoaXMsIHByb3BzKSk7CgogICAgICAgIF90aGlzLnN0YXRlID0gewogICAgICAgICAgICBydW5uaW5nOiBmYWxzZSwKICAgICAgICAgICAgc3RvcHBpbmc6IGZhbHNlCiAgICAgICAgfTsKICAgICAgICByZXR1cm4gX3RoaXM7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFJ1bkJ1dHRvbiwgW3sKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHsKICAgICAgICAgICAgdGhpcy5fdXBkYXRlU3RhdGUobmV4dFByb3BzKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX3VwZGF0ZVN0YXRlJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX3VwZGF0ZVN0YXRlKG5leHRQcm9wcykgewogICAgICAgICAgICB2YXIgb2xkU3RhdHVzID0gdGhpcy5wcm9wcy5sYXRlc3RSdW4gJiYgdGhpcy5wcm9wcy5sYXRlc3RSdW4uc3RhdGUgfHwgJyc7CiAgICAgICAgICAgIHZhciBuZXdTdGF0dXMgPSBuZXh0UHJvcHMubGF0ZXN0UnVuICYmIG5leHRQcm9wcy5sYXRlc3RSdW4uc3RhdGUgfHwgJyc7CgogICAgICAgICAgICAvLyBpZiB0aGUgc3RhdGUgb2YgdGhlIHJ1biBjaGFuZ2VkLCB0aGVuIGFzc3VtZSBpdCdzIG5vIGxvbmdlciB0cnlpbmcgdG8gc3RvcAogICAgICAgICAgICBpZiAob2xkU3RhdHVzICE9PSBuZXdTdGF0dXMpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoewogICAgICAgICAgICAgICAgICAgIHN0b3BwaW5nOiBmYWxzZQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX29uUnVuQ2xpY2snLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfb25SdW5DbGljaygpIHsKICAgICAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7CgogICAgICAgICAgICBfLlJ1bkFwaS5zdGFydFJ1bih0aGlzLnByb3BzLnJ1bm5hYmxlKS50aGVuKGZ1bmN0aW9uIChydW5JbmZvKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gXy5Ub2FzdFV0aWxzLmNyZWF0ZVJ1blN0YXJ0ZWRUb2FzdChfdGhpczIucHJvcHMucnVubmFibGUsIHJ1bkluZm8sIF90aGlzMi5wcm9wcy5vbk5hdmlnYXRpb24pOwogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX29uU3RvcENsaWNrJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX29uU3RvcENsaWNrKCkgewogICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zdG9wcGluZykgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsKICAgICAgICAgICAgICAgIHN0b3BwaW5nOiB0cnVlCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMubGF0ZXN0UnVuLnN0YXRlID09PSAnUVVFVUVEJykgewogICAgICAgICAgICAgICAgXy5SdW5BcGkucmVtb3ZlRnJvbVF1ZXVlKHRoaXMucHJvcHMubGF0ZXN0UnVuKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIF8uUnVuQXBpLnN0b3BSdW4odGhpcy5wcm9wcy5sYXRlc3RSdW4pOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbmFtZSA9IGRlY29kZVVSSUNvbXBvbmVudCh0aGlzLnByb3BzLnJ1bm5hYmxlLm5hbWUpOwogICAgICAgICAgICB2YXIgcnVuSWQgPSB0aGlzLnByb3BzLmxhdGVzdFJ1bi5pZDsKICAgICAgICAgICAgdmFyIHRleHQgPSB0cmFuc2xhdGUoJ3RvYXN0LnJ1bi5zdG9wcGluZycsIHsKICAgICAgICAgICAgICAgIDA6IG5hbWUsCiAgICAgICAgICAgICAgICAxOiBydW5JZCwKICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZTogJ1N0b3BwcGluZyAiezB9IiAjezF9JwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIF8uVG9hc3RTZXJ2aWNlLm5ld1RvYXN0KHsgdGV4dDogdGV4dCB9KTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX3RoaXMzID0gdGhpczsKCiAgICAgICAgICAgIHZhciBidXR0b25UeXBlID0gdGhpcy5wcm9wcy5idXR0b25UeXBlOwogICAgICAgICAgICB2YXIgb3V0ZXJDbGFzcyA9IHRoaXMucHJvcHMuY2xhc3NOYW1lID8gdGhpcy5wcm9wcy5jbGFzc05hbWUgOiAnJzsKICAgICAgICAgICAgdmFyIG91dGVyQ2xhc3NOYW1lcyA9IG91dGVyQ2xhc3Muc3BsaXQoJyAnKTsKICAgICAgICAgICAgdmFyIGlubmVyQnV0dG9uQ2xhc3MgPSBvdXRlckNsYXNzTmFtZXMuaW5kZXhPZignaWNvbi1idXR0b24nKSA9PT0gLTEgPyB0aGlzLnByb3BzLmlubmVyQnV0dG9uQ2xhc3NlcyA6ICcnOwogICAgICAgICAgICB2YXIgc3RvcENsYXNzID0gdGhpcy5zdGF0ZS5zdG9wcGluZyA/ICdzdG9wcGluZycgOiAnJzsKCiAgICAgICAgICAgIHZhciBzdGF0dXMgPSB0aGlzLnByb3BzLmxhdGVzdFJ1biA/IHRoaXMucHJvcHMubGF0ZXN0UnVuLnN0YXRlIDogJyc7CiAgICAgICAgICAgIHZhciBpc1BhdXNlZCA9IHN0YXR1cy50b0xvd2VyQ2FzZSgpID09PSAncGF1c2VkJzsKICAgICAgICAgICAgdmFyIHJ1bm5pbmdTdGF0dXMgPSBzdGF0dXMgJiYgKGlzUGF1c2VkIHx8IHN0YXR1cy50b0xvd2VyQ2FzZSgpID09PSAncnVubmluZycgfHwgc3RhdHVzLnRvTG93ZXJDYXNlKCkgPT09ICdxdWV1ZWQnKTsKCiAgICAgICAgICAgIHZhciBzaG93UnVuQnV0dG9uID0gYnV0dG9uVHlwZSA9PT0gJ3J1bi1vbmx5JyB8fCBidXR0b25UeXBlID09PSAndG9nZ2xlJyAmJiAhcnVubmluZ1N0YXR1czsKICAgICAgICAgICAgdmFyIHNob3dTdG9wQnV0dG9uID0gcnVubmluZ1N0YXR1cyAmJiAoYnV0dG9uVHlwZSA9PT0gJ3RvZ2dsZScgfHwgYnV0dG9uVHlwZSA9PT0gJ3N0b3Atb25seScpOwoKICAgICAgICAgICAgc2hvd1J1bkJ1dHRvbiA9IHNob3dSdW5CdXR0b24gJiYgcGVybWl0KHRoaXMucHJvcHMucnVubmFibGUpLnN0YXJ0KCk7CiAgICAgICAgICAgIHNob3dTdG9wQnV0dG9uID0gc2hvd1N0b3BCdXR0b24gJiYgcGVybWl0KHRoaXMucHJvcHMucnVubmFibGUpLnN0b3AoKTsKCiAgICAgICAgICAgIHZhciBydW5MYWJlbCA9IHRoaXMucHJvcHMucnVuVGV4dCB8fCB0cmFuc2xhdGUoJ3RvYXN0LnJ1bicsIHsKICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZTogJ1J1bicKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHZhciBzdG9wTGFiZWwgPSB0aGlzLnN0YXRlLnN0b3BwaW5nID8gdHJhbnNsYXRlKCd0b2FzdC5zdG9wcGluZycsIHsKICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZTogJ1N0b3BwaW5nIC4uLicKICAgICAgICAgICAgfSkgOiB0cmFuc2xhdGUoJ3RvYXN0LnN0b3AnLCB7CiAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWU6ICdTdG9wJwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGlmIChpc1BhdXNlZCAmJiAhdGhpcy5zdGF0ZS5zdG9wcGluZykgewogICAgICAgICAgICAgICAgc3RvcExhYmVsID0gdHJhbnNsYXRlKCd0b2FzdC5hYm9ydCcsIHsgZGVmYXVsdFZhbHVlOiAnQWJvcnQnIH0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIXNob3dSdW5CdXR0b24gJiYgIXNob3dTdG9wQnV0dG9uKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIF9wcm9wcyRvbkNsaWNrID0gdGhpcy5wcm9wcy5vbkNsaWNrLAogICAgICAgICAgICAgICAgb25DbGljayA9IF9wcm9wcyRvbkNsaWNrID09PSB1bmRlZmluZWQgPyBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMzLl9vblJ1bkNsaWNrKCk7CiAgICAgICAgICAgIH0gOiBfcHJvcHMkb25DbGljazsKCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdydW4tYnV0dG9uLWNvbXBvbmVudCAnICsgb3V0ZXJDbGFzcywgb25DbGljazogZnVuY3Rpb24gb25DbGljayhldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RvcFByb3AoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIH0gfSwKICAgICAgICAgICAgICAgIHNob3dSdW5CdXR0b24gJiYgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2EnLAogICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAncnVuLWJ1dHRvbiAnICsgaW5uZXJCdXR0b25DbGFzcywgdGl0bGU6IHJ1bkxhYmVsLCBvbkNsaWNrOiBvbkNsaWNrIH0sCiAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoX3JlYWN0TWF0ZXJpYWxJY29ucy5JY29uLCB7IHNpemU6IDI0LCBpY29uOiAncGxheV9jaXJjbGVfb3V0bGluZScgfSksCiAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgICAgICdzcGFuJywKICAgICAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdidXR0b24tbGFiZWwnIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bkxhYmVsCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgIHNob3dTdG9wQnV0dG9uICYmIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICdhJywKICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3N0b3AtYnV0dG9uICcgKyBpbm5lckJ1dHRvbkNsYXNzICsgJyAnICsgc3RvcENsYXNzLCB0aXRsZTogc3RvcExhYmVsLCBvbkNsaWNrOiBmdW5jdGlvbiBvbkNsaWNrKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzMy5fb25TdG9wQ2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSB9LAogICAgICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICAgICAnc3ZnJywKICAgICAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdzdmctaWNvbicsIHdpZHRoOiAnMjAnLCBoZWlnaHQ6ICcyMCcsIHZpZXdCb3g6ICcwIDAgMjAgMjAnLCB4bWxuczogJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyB9LAogICAgICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdnJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgZmlsbDogJ25vbmUnLCAnZmlsbC1ydWxlJzogJ2V2ZW5vZGQnIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgZDogJ00tMi0yaDI0djI0SC0yeicgfSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgY2xhc3NOYW1lOiAnc3ZnLWljb24taW5uZXInLCBkOiAnTTEwIDBDNC40OCAwIDAgNC40OCAwIDEwczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNS41MiAwIDEwIDB6TTcgN2g2djZIN1Y3em0zIDExYy00LjQxIDAtOC0zLjU5LTgtOHMzLjU5LTggOC04IDggMy41OSA4IDgtMy41OSA4LTggOHonLCBmaWxsOiAnIzRBOTBFMicgfSkKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgICAgICdzcGFuJywKICAgICAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdidXR0b24tbGFiZWwnIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHN0b3BMYWJlbAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFJ1bkJ1dHRvbjsKfShfcmVhY3QuQ29tcG9uZW50KTsKClJ1bkJ1dHRvbi5wcm9wVHlwZXMgPSB7CiAgICBidXR0b25UeXBlOiBfcmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsndG9nZ2xlJywgJ3N0b3Atb25seScsICdydW4tb25seSddKSwKICAgIGNsYXNzTmFtZTogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBydW5uYWJsZTogX3JlYWN0LlByb3BUeXBlcy5vYmplY3QsCiAgICBsYXRlc3RSdW46IF9yZWFjdC5Qcm9wVHlwZXMub2JqZWN0LAogICAgb25OYXZpZ2F0aW9uOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsCiAgICBvbkNsaWNrOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsCiAgICBydW5UZXh0OiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIGlubmVyQnV0dG9uQ2xhc3NlczogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcKfTsKClJ1bkJ1dHRvbi5kZWZhdWx0UHJvcHMgPSB7CiAgICBidXR0b25UeXBlOiAndG9nZ2xlJywKICAgIGlubmVyQnV0dG9uQ2xhc3NlczogJ2J0biBpbnZlcnNlJwp9Owp9LHsiLi4vIjoyNSwiLi4vaTE4bi9pMThuIjoyNCwiLi4vc2VjdXJpdHkiOjQ0LCJAamVua2lucy1jZC9yZWFjdC1tYXRlcmlhbC1pY29ucyI6MTI5LCJyZWFjdCI6NjIzfV0sMTk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5TaG93TW9yZUJ1dHRvbiA9IHVuZGVmaW5lZDsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX2kxOG4gPSByZXF1aXJlKCcuLi9pMThuL2kxOG4nKTsKCnZhciBfaTE4bjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pMThuKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9Cgp2YXIgdHJhbnNsYXRlID0gKDAsIF9pMThuMi5kZWZhdWx0KSgnYmx1ZW9jZWFuLXdlYicpOwoKdmFyIGJ1dHRvblRleHQgPSBmdW5jdGlvbiBidXR0b25UZXh0KHBhZ2VyKSB7CiAgICBpZiAocGFnZXIucGVuZGluZykgewogICAgICAgIHJldHVybiB0cmFuc2xhdGUoJ2NvbW1vbi5wYWdlci5sb2FkaW5nJywgeyBkZWZhdWx0VmFsdWU6ICdMb2FkaW5nLi4uJyB9KTsKICAgIH0KCiAgICByZXR1cm4gdHJhbnNsYXRlKCdjb21tb24ucGFnZXIubW9yZScsIHsgZGVmYXVsdFZhbHVlOiAnU2hvdyBtb3JlJyB9KTsKfTsKCnZhciBTaG93TW9yZUJ1dHRvbiA9IGV4cG9ydHMuU2hvd01vcmVCdXR0b24gPSBmdW5jdGlvbiBTaG93TW9yZUJ1dHRvbihwcm9wcykgewogICAgdmFyIHBhZ2VyID0gcHJvcHMucGFnZXI7CgogICAgaWYgKCFwYWdlciB8fCAhcGFnZXIuaGFzTW9yZSkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICdidXR0b24nLAogICAgICAgIHsKICAgICAgICAgICAgY2xhc3NOYW1lOiAnYnRuLXNob3ctbW9yZSBidG4tc2Vjb25kYXJ5JywKICAgICAgICAgICAgb25DbGljazogZnVuY3Rpb24gb25DbGljaygpIHsKICAgICAgICAgICAgICAgIHJldHVybiBwYWdlci5mZXRjaE5leHRQYWdlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGJ1dHRvblRleHQocGFnZXIpCiAgICApOwp9OwoKU2hvd01vcmVCdXR0b24ucHJvcFR5cGVzID0gewogICAgcGFnZXI6IF9yZWFjdC5Qcm9wVHlwZXMub2JqZWN0Cn07Cn0seyIuLi9pMThuL2kxOG4iOjI0LCJyZWFjdCI6NjIzfV0sMjA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5UaW1lSGFybW9uaXplciA9IHVuZGVmaW5lZDsKCnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX3NlcnZlckJyb3dzZXJUaW1lSGFybW9uaXplID0gcmVxdWlyZSgnLi4vdXRpbHMvc2VydmVyQnJvd3NlclRpbWVIYXJtb25pemUnKTsKCnZhciBfbG9nZ2luZyA9IHJlcXVpcmUoJy4uL2xvZ2dpbmcnKTsKCnZhciBfbG9nZ2luZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9sb2dnaW5nKTsKCnZhciBfaTE4biA9IHJlcXVpcmUoJy4uL2kxOG4vaTE4bicpOwoKdmFyIF9pMThuMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2kxOG4pOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKdmFyIHRyYW5zbGF0ZSA9ICgwLCBfaTE4bjIuZGVmYXVsdCkoJ2JsdWVvY2Vhbi13ZWInKTsKdmFyIHRpbWVNYW5hZ2VyID0gbmV3IF9zZXJ2ZXJCcm93c2VyVGltZUhhcm1vbml6ZS5UaW1lTWFuYWdlcigpOwp2YXIgbG9nZ2VyID0gX2xvZ2dpbmcyLmRlZmF1bHQubG9nZ2VyKCdpby5qZW5raW5zLmJsdWVvY2Vhbi5jb3JlLlRpbWVIYXJtb25pemVyJyk7Cgp2YXIgVGltZUhhcm1vbml6ZXIgPSBleHBvcnRzLlRpbWVIYXJtb25pemVyID0gZnVuY3Rpb24gVGltZUhhcm1vbml6ZXIoQ29tcG9zZWRDb21wb25lbnQpIHsKICAgIHZhciBOZXdDb21wb25lbnQgPSBmdW5jdGlvbiAoX0NvbXBvbmVudCkgewogICAgICAgIF9pbmhlcml0cyhOZXdDb21wb25lbnQsIF9Db21wb25lbnQpOwoKICAgICAgICBmdW5jdGlvbiBOZXdDb21wb25lbnQocHJvcHMsIGNvbnRleHQpIHsKICAgICAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIE5ld0NvbXBvbmVudCk7CgogICAgICAgICAgICB2YXIgX3RoaXMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoTmV3Q29tcG9uZW50Ll9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoTmV3Q29tcG9uZW50KSkuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCkpOwoKICAgICAgICAgICAgbG9nZ2VyLndhcm4ocHJvcHMsIGNvbnRleHQpOwogICAgICAgICAgICB2YXIgc3RhcnRUaW1lID0gX3RoaXMucHJvcHMuc3RhcnRUaW1lOwoKICAgICAgICAgICAgX3RoaXMuc2tld01pbGxpcyA9IF90aGlzLmNvbnRleHQgJiYgX3RoaXMuY29udGV4dC5jb25maWcgPyBfdGhpcy5jb250ZXh0LmNvbmZpZy5nZXRTZXJ2ZXJCcm93c2VyVGltZVNrZXdNaWxsaXMoKSA6IDA7CiAgICAgICAgICAgIF90aGlzLmR1cmF0aW9uTWlsbGlzID0gc3RhcnRUaW1lID8gX3RoaXMuZ2V0VGltZXMocHJvcHMpLmR1cmF0aW9uTWlsbGlzIDogMDsKICAgICAgICAgICAgX3RoaXMuZ2V0STE4blRpdGxlID0gX3RoaXMuZ2V0STE4blRpdGxlLmJpbmQoX3RoaXMpOwogICAgICAgICAgICBfdGhpcy5nZXREdXJhdGlvbiA9IF90aGlzLmdldER1cmF0aW9uLmJpbmQoX3RoaXMpOwogICAgICAgICAgICBfdGhpcy5nZXRUaW1lcyA9IF90aGlzLmdldFRpbWVzLmJpbmQoX3RoaXMpOwogICAgICAgICAgICByZXR1cm4gX3RoaXM7CiAgICAgICAgfQoKICAgICAgICBfY3JlYXRlQ2xhc3MoTmV3Q29tcG9uZW50LCBbewogICAgICAgICAgICBrZXk6ICdnZXREdXJhdGlvbicsCiAgICAgICAgICAgIHZhbHVlOiBmdW5jdGlvbiBnZXREdXJhdGlvbihyZXN1bHQpIHsKICAgICAgICAgICAgICAgIHZhciBkdXJhdGlvbk1pbGxpcyA9IHRoaXMuaXNSdW5uaW5nRnVuY3Rpb24ocmVzdWx0KSgpID8gdGhpcy5kdXJhdGlvbk1pbGxpcyA6IHRoaXMuZ2V0VGltZXMoKS5kdXJhdGlvbk1pbGxpczsKICAgICAgICAgICAgICAgIHJldHVybiBkdXJhdGlvbk1pbGxpczsKICAgICAgICAgICAgfQogICAgICAgIH0sIHsKICAgICAgICAgICAga2V5OiAnZ2V0VGltZXMnLAogICAgICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0VGltZXMoKSB7CiAgICAgICAgICAgICAgICB2YXIgcHJvcHMgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHRoaXMucHJvcHM7CiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gcHJvcHMucmVzdWx0LAogICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IHByb3BzLnN0YXJ0VGltZSwKICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbkluTWlsbGlzID0gcHJvcHMuZHVyYXRpb25Jbk1pbGxpcywKICAgICAgICAgICAgICAgICAgICBlbmRUaW1lID0gcHJvcHMuZW5kVGltZTsKCiAgICAgICAgICAgICAgICBpZiAoIXN0YXJ0VGltZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB7fTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgd2UgY2FsY3VsYXRlIHdpdGggdGhlIGNvcnJlY3QgdGltZSBvZmZzZXQKICAgICAgICAgICAgICAgIHZhciBoYXJtb25pemVUaW1lcyA9IHRpbWVNYW5hZ2VyLmhhcm1vbml6ZVRpbWVzKHsKICAgICAgICAgICAgICAgICAgICBzdGFydFRpbWU6IHN0YXJ0VGltZSwKICAgICAgICAgICAgICAgICAgICBlbmRUaW1lOiBlbmRUaW1lLAogICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uSW5NaWxsaXM6IGR1cmF0aW9uSW5NaWxsaXMsCiAgICAgICAgICAgICAgICAgICAgaXNSdW5uaW5nOiB0aGlzLmlzUnVubmluZ0Z1bmN0aW9uKHJlc3VsdCkoKQogICAgICAgICAgICAgICAgfSwgdGhpcy5za2V3TWlsbGlzKTsKICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdSZXR1cm5pbmcgb2JqZWN0JywgaGFybW9uaXplVGltZXMpOwogICAgICAgICAgICAgICAgcmV0dXJuIGhhcm1vbml6ZVRpbWVzOwogICAgICAgICAgICB9CiAgICAgICAgfSwgewogICAgICAgICAgICBrZXk6ICdnZXRJMThuVGl0bGUnLAogICAgICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0STE4blRpdGxlKHJlc3VsdCkgewogICAgICAgICAgICAgICAgdmFyIGR1cmF0aW9uTWlsbGlzID0gdGhpcy5nZXREdXJhdGlvbihyZXN1bHQpOwogICAgICAgICAgICAgICAgdmFyIGkxOG5EdXJhdGlvbiA9IHRpbWVNYW5hZ2VyLmZvcm1hdChkdXJhdGlvbk1pbGxpcywgdHJhbnNsYXRlKCdjb21tb24uZGF0ZS5kdXJhdGlvbi5oaW50LmZvcm1hdCcsIHsgZGVmYXVsdFZhbHVlOiAnTSBbbW9udGhdLCBkIFtkYXlzXSwgaFtoXSwgbVttXSwgc1tzXScgfSkpOwoKICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCd0aW1lcycsIHsgdGhpc0R1cmF0aW9uOiB0aGlzLmR1cmF0aW9uTWlsbGlzLCBpMThuRHVyYXRpb246IGkxOG5EdXJhdGlvbiwgZHVyYXRpb25NaWxsaXM6IGR1cmF0aW9uTWlsbGlzIH0pOwogICAgICAgICAgICAgICAgdmFyIHRpdGxlID0gdHJhbnNsYXRlKCdjb21tb24uc3RhdGUuJyArIHJlc3VsdC50b0xvd2VyQ2FzZSgpLCB7IDA6IGkxOG5EdXJhdGlvbiB9KTsKICAgICAgICAgICAgICAgIHJldHVybiB0aXRsZTsKICAgICAgICAgICAgfQogICAgICAgIH0sIHsKICAgICAgICAgICAga2V5OiAnaXNSdW5uaW5nRnVuY3Rpb24nLAogICAgICAgICAgICB2YWx1ZTogZnVuY3Rpb24gaXNSdW5uaW5nRnVuY3Rpb24ocmVzdWx0KSB7CiAgICAgICAgICAgICAgICB2YXIgaXNSdW5uaW5nID0gZnVuY3Rpb24gaXNSdW5uaW5nKCkgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocmVzdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1JVTk5JTkcnOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdQQVVTRUQnOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdRVUVVRUQnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIHJldHVybiBpc1J1bm5pbmc7CiAgICAgICAgICAgIH0KICAgICAgICB9LCB7CiAgICAgICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgICAgICAvLyBjcmVhdGUgYSBjb21wb3NlZENvbXBvbmVudCBhbmQgaW5qZWN0IHRoZSBmdW5jdGlvbnMgd2Ugd2FudCB0byBleHBvc2UKICAgICAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChDb21wb3NlZENvbXBvbmVudCwgX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHRoaXMuc3RhdGUsIHsKICAgICAgICAgICAgICAgICAgICBnZXRUaW1lczogdGhpcy5nZXRUaW1lcywKICAgICAgICAgICAgICAgICAgICBnZXREdXJhdGlvbjogdGhpcy5nZXREdXJhdGlvbiwKICAgICAgICAgICAgICAgICAgICBnZXRJMThuVGl0bGU6IHRoaXMuZ2V0STE4blRpdGxlLAogICAgICAgICAgICAgICAgICAgIGlzUnVubmluZzogdGhpcy5pc1J1bm5pbmcKICAgICAgICAgICAgICAgIH0pKTsKICAgICAgICAgICAgfQogICAgICAgIH1dKTsKCiAgICAgICAgcmV0dXJuIE5ld0NvbXBvbmVudDsKICAgIH0oX3JlYWN0LkNvbXBvbmVudCk7CgogICAgTmV3Q29tcG9uZW50LnByb3BUeXBlcyA9IHsKICAgICAgICByZXN1bHQ6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgICAgIHN0YXJ0VGltZTogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICAgICAgZW5kVGltZTogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICAgICAgZHVyYXRpb25Jbk1pbGxpczogX3JlYWN0LlByb3BUeXBlcy5udW1iZXIKICAgIH07CgogICAgTmV3Q29tcG9uZW50LmNvbnRleHRUeXBlcyA9IHsKICAgICAgICBjb25maWc6IF9yZWFjdC5Qcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQKICAgIH07CiAgICByZXR1cm4gTmV3Q29tcG9uZW50Owp9Owp9LHsiLi4vaTE4bi9pMThuIjoyNCwiLi4vbG9nZ2luZyI6MjcsIi4uL3V0aWxzL3NlcnZlckJyb3dzZXJUaW1lSGFybW9uaXplIjo2MiwicmVhY3QiOjYyM31dLDIxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX3Njb3BlcyA9IHJlcXVpcmUoJy4vc2NvcGVzJyk7Cgp2YXIgY29uZmlnID0gX3Njb3Blcy5ibHVlb2NlYW4uY29uZmlnIHx8IHt9OyAvKioKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVGhpcyBjb25maWcgb2JqZWN0IGNvbWVzIGZyb20gYmx1ZW9jZWFuLWNvbmZpZy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCgp2YXIgZmVhdHVyZXMgPSBjb25maWcuZmVhdHVyZXMgfHwge307CgpleHBvcnRzLmRlZmF1bHQgPSB7CiAgICBsb2FkVXJsczogZnVuY3Rpb24gbG9hZFVybHMoKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdmFyIGhlYWRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXTsKCiAgICAgICAgICAgIC8vIExvb2sgdXAgd2hlcmUgdGhlIEJsdWUgT2NlYW4gYXBwIGlzIGhvc3RlZAogICAgICAgICAgICBjb25maWcuYmx1ZW9jZWFuQXBwVVJMID0gaGVhZEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWFwcHVybCcpOwoKICAgICAgICAgICAgaWYgKHR5cGVvZiBjb25maWcuYmx1ZW9jZWFuQXBwVVJMICE9PSAnc3RyaW5nJykgewogICAgICAgICAgICAgICAgY29uZmlnLmJsdWVvY2VhbkFwcFVSTCA9ICcvJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29uZmlnLmplbmtpbnNSb290VVJMID0gaGVhZEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXJvb3R1cmwnKTsKICAgICAgICAgICAgY29uZmlnLmlzTG9hZGVkID0gdHJ1ZTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIC8vIGhlYWRsZXNzIGVzY2FwZQogICAgICAgICAgICBjb25maWcuamVua2luc1Jvb3RVUkwgPSAnL2plbmtpbnMnOwogICAgICAgIH0KICAgIH0sCiAgICBnZXRDb25maWc6IGZ1bmN0aW9uIGdldENvbmZpZygpIHsKICAgICAgICByZXR1cm4gY29uZmlnOwogICAgfSwKICAgIGdldEplbmtpbnNDb25maWc6IGZ1bmN0aW9uIGdldEplbmtpbnNDb25maWcoKSB7CiAgICAgICAgcmV0dXJuIGNvbmZpZy5qZW5raW5zQ29uZmlnIHx8IHt9OwogICAgfSwKICAgIGdldFNlY3VyaXR5Q29uZmlnOiBmdW5jdGlvbiBnZXRTZWN1cml0eUNvbmZpZygpIHsKICAgICAgICByZXR1cm4gdGhpcy5nZXRKZW5raW5zQ29uZmlnKCkuc2VjdXJpdHkgfHwge307CiAgICB9LAogICAgaXNKV1RFbmFibGVkOiBmdW5jdGlvbiBpc0pXVEVuYWJsZWQoKSB7CiAgICAgICAgcmV0dXJuICEhdGhpcy5nZXRTZWN1cml0eUNvbmZpZygpLmVuYWJsZUpXVDsKICAgIH0sCiAgICBnZXRMb2dpblVybDogZnVuY3Rpb24gZ2V0TG9naW5VcmwoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U2VjdXJpdHlDb25maWcoKS5sb2dpblVybDsKICAgIH0sCiAgICBnZXRQbHVnaW5JbmZvOiBmdW5jdGlvbiBnZXRQbHVnaW5JbmZvKHBsdWdpbklkKSB7CiAgICAgICAgcmV0dXJuIF9zY29wZXMuYmx1ZW9jZWFuLmpzRXh0ZW5zaW9ucy5maW5kKGZ1bmN0aW9uIChwbHVnaW5JbmZvKSB7CiAgICAgICAgICAgIHJldHVybiBwbHVnaW5JbmZvLmhwaVBsdWdpbklkID09PSBwbHVnaW5JZDsKICAgICAgICB9KTsKICAgIH0sCiAgICBpc0ZlYXR1cmVFbmFibGVkOiBmdW5jdGlvbiBpc0ZlYXR1cmVFbmFibGVkKG5hbWUsIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIHZhciB2YWx1ZSA9IGZlYXR1cmVzW25hbWVdOwogICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykgewogICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfQogICAgICAgIGlmICh0eXBlb2YgZGVmYXVsdFZhbHVlID09PSAnYm9vbGVhbicpIHsKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfSwKICAgIHNob3dPcmc6IGZ1bmN0aW9uIHNob3dPcmcoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuaXNGZWF0dXJlRW5hYmxlZCgnb3JnYW5pemF0aW9ucy5lbmFibGVkJywgZmFsc2UpOwogICAgfSwKICAgIGdldEplbmtpbnNSb290VVJMOiBmdW5jdGlvbiBnZXRKZW5raW5zUm9vdFVSTCgpIHsKICAgICAgICBpZiAoIWNvbmZpZy5pc0xvYWRlZCkgewogICAgICAgICAgICB0aGlzLmxvYWRVcmxzKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0eXBlb2YgY29uZmlnLmplbmtpbnNSb290VVJMID09PSAnc3RyaW5nJyA/IGNvbmZpZy5qZW5raW5zUm9vdFVSTCA6ICcvamVua2lucyc7CiAgICB9LAogICAgZ2V0UmVzdFJvb3Q6IGZ1bmN0aW9uIGdldFJlc3RSb290KCkgewogICAgICAgIHJldHVybiBjb25maWcuZ2V0SmVua2luc1Jvb3RVUkwoKSArICcvYmx1ZS9yZXN0JzsKICAgIH0sCgoKICAgIC8qKgogICAgICogU2V0IGEgbmV3ICJqZW5raW5zQ29uZmlnIiBvYmplY3QuCiAgICAgKiBVc2VmdWwgZm9yIHRlc3RpbmcgaW4gYSBoZWFkbGVzcyBlbnZpcm9ubWVudC4KICAgICAqIEBwYXJhbSBuZXdDb25maWcKICAgICAqIEBwcml2YXRlCiAgICAgKi8KICAgIF9zZXRKZW5raW5zQ29uZmlnOiBmdW5jdGlvbiBfc2V0SmVua2luc0NvbmZpZyhuZXdDb25maWcpIHsKICAgICAgICBjb25maWcuamVua2luc0NvbmZpZyA9IG5ld0NvbmZpZzsKICAgIH0KfTsKfSx7Ii4vc2NvcGVzIjo0M31dLDIyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuRmV0Y2ggPSBleHBvcnRzLkZldGNoRnVuY3Rpb25zID0gdW5kZWZpbmVkOwoKdmFyIF9lczZQcm9taXNlID0gcmVxdWlyZSgnZXM2LXByb21pc2UnKTsKCnZhciBfZXM2UHJvbWlzZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9lczZQcm9taXNlKTsKCnZhciBfand0ID0gcmVxdWlyZSgnLi9qd3QnKTsKCnZhciBfand0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2p3dCk7Cgp2YXIgX2lzb21vcnBoaWNGZXRjaCA9IHJlcXVpcmUoJ2lzb21vcnBoaWMtZmV0Y2gnKTsKCnZhciBfaXNvbW9ycGhpY0ZldGNoMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzb21vcnBoaWNGZXRjaCk7Cgp2YXIgX3V0aWxzID0gcmVxdWlyZSgnLi91dGlscycpOwoKdmFyIF91dGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF91dGlscyk7Cgp2YXIgX2NvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7Cgp2YXIgX2NvbmZpZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9jb25maWcpOwoKdmFyIF9kZWR1cGVDYWxscyA9IHJlcXVpcmUoJy4vdXRpbHMvZGVkdXBlLWNhbGxzJyk7Cgp2YXIgX2RlZHVwZUNhbGxzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2RlZHVwZUNhbGxzKTsKCnZhciBfdXJsY29uZmlnID0gcmVxdWlyZSgnLi91cmxjb25maWcnKTsKCnZhciBfdXJsY29uZmlnMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3VybGNvbmZpZyk7Cgp2YXIgX3Njb3BlcyA9IHJlcXVpcmUoJy4vc2NvcGVzJyk7Cgp2YXIgX0xvYWRpbmdJbmRpY2F0b3IgPSByZXF1aXJlKCcuL0xvYWRpbmdJbmRpY2F0b3InKTsKCnZhciBfTG9hZGluZ0luZGljYXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Mb2FkaW5nSW5kaWNhdG9yKTsKCnZhciBfaW5kZXggPSByZXF1aXJlKCcuL2NhcGFiaWxpdHkvaW5kZXgnKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpfZXM2UHJvbWlzZTIuZGVmYXVsdC5wb2x5ZmlsbCgpOwoKCnZhciBQcm9taXNlID0gX2VzNlByb21pc2UyLmRlZmF1bHQuUHJvbWlzZTsKCnZhciByZWZyZXNoVG9rZW4gPSBudWxsOwp2YXIgRmV0Y2hGdW5jdGlvbnMgPSBleHBvcnRzLkZldGNoRnVuY3Rpb25zID0gewogICAgY2hlY2tSZWZyZXNoSGVhZGVyOiBmdW5jdGlvbiBjaGVja1JlZnJlc2hIZWFkZXIocmVzcG9uc2UpIHsKICAgICAgICB2YXIgX3JlZnJlc2hUb2tlbiA9IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdYLUJsdWVvY2Vhbi1SZWZyZXNoZXInKTsKICAgICAgICAvLyBObyB0b2tlbiBpbiByZXNwb25zZSwgbGV0cyBqdXN0IGlnbm9yZS4KICAgICAgICBpZiAoIV9yZWZyZXNoVG9rZW4pIHsKICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlOwogICAgICAgIH0KCiAgICAgICAgLy8gRmlyc3QgdGltZSB3ZSBoYXZlIHNlZW4gYSByZWZyZXNoIHRva2VuLCBlYXJseSBleGl0LgogICAgICAgIGlmICghcmVmcmVzaFRva2VuKSB7CiAgICAgICAgICAgIHJlZnJlc2hUb2tlbiA9IF9yZWZyZXNoVG9rZW47CiAgICAgICAgICAgIHJldHVybiByZXNwb25zZTsKICAgICAgICB9CgogICAgICAgIC8vIFdlIG5lZWQgdG8gcmVmcmVzaCB0aGUgcGFnZSBub3chCiAgICAgICAgaWYgKHJlZnJlc2hUb2tlbiAhPT0gX3JlZnJlc2hUb2tlbikgewogICAgICAgICAgICBfdXRpbHMyLmRlZmF1bHQucmVmcmVzaFBhZ2UoKTsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdyZWZyZXNoaW5nIGFwZ2UnKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3BvbnNlOwogICAgfSwKCgogICAgLyoqCiAgICAgKiBUaGlzIG1ldGhvZCBjaGVja3MgZm9yIGZvciAyWFggaHR0cCBjb2Rlcy4gVGhyb3dzIGVycm9yIGl0IGl0IGlzIG5vdC4KICAgICAqIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBpZiBub3QgdXNpbmcgZmV0Y2ggb3IgZmV0Y2hKc29uLgogICAgICovCiAgICBjaGVja1N0YXR1czogZnVuY3Rpb24gY2hlY2tTdGF0dXMocmVzcG9uc2UpIHsKICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID49IDMwMCB8fCByZXNwb25zZS5zdGF0dXMgPCAyMDApIHsKICAgICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQpOwogICAgICAgICAgICBlcnJvci5yZXNwb25zZSA9IHJlc3BvbnNlOwogICAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3BvbnNlOwogICAgfSwKICAgIHN0b3BMb2FkaW5nSW5kaWNhdG9yOiBmdW5jdGlvbiBzdG9wTG9hZGluZ0luZGljYXRvcihyZXNwb25zZSkgewogICAgICAgIF9Mb2FkaW5nSW5kaWNhdG9yMi5kZWZhdWx0LmhpZGUoKTsKICAgICAgICByZXR1cm4gcmVzcG9uc2U7CiAgICB9LAoKCiAgICAvKioKICAgICAqIEFkZHMgc2FtZS1vcmlnaW4gb3B0aW9uIHRvIHRoZSBmZXRjaC4KICAgICAqLwogICAgc2FtZU9yaWdpbkZldGNoT3B0aW9uOiBmdW5jdGlvbiBzYW1lT3JpZ2luRmV0Y2hPcHRpb24oKSB7CiAgICAgICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHt9OwoKICAgICAgICB2YXIgbmV3T3B0cyA9IF91dGlsczIuZGVmYXVsdC5jbG9uZShvcHRpb25zKTsKICAgICAgICBuZXdPcHRzLmNyZWRlbnRpYWxzID0gbmV3T3B0cy5jcmVkZW50aWFscyB8fCAnc2FtZS1vcmlnaW4nOwogICAgICAgIHJldHVybiBuZXdPcHRzOwogICAgfSwKCgogICAgLyoqCiAgICAgKiBFbmhhbmNlcyB0aGUgZmV0Y2hPcHRpb25zIHdpdGggdGhlIEpXVCBiZWFyZXIgdG9rZW4uIFdpbGwgb25seSBiZSBuZWVkZWQKICAgICAqIGlmIG5vdCB1c2luZyBmZXRjaCBvciBmZXRjaEpzb24uCiAgICAgKi8KICAgIGp3dEZldGNoT3B0aW9uOiBmdW5jdGlvbiBqd3RGZXRjaE9wdGlvbih0b2tlbikgewogICAgICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTsKCiAgICAgICAgdmFyIG5ld09wdHMgPSBfdXRpbHMyLmRlZmF1bHQuY2xvbmUob3B0aW9ucyk7CiAgICAgICAgbmV3T3B0cy5oZWFkZXJzID0gbmV3T3B0cy5oZWFkZXJzIHx8IHt9OwogICAgICAgIG5ld09wdHMuaGVhZGVycy5BdXRob3JpemF0aW9uID0gbmV3T3B0cy5oZWFkZXJzLkF1dGhvcml6YXRpb24gfHwgJ0JlYXJlciAnICsgdG9rZW47CiAgICAgICAgcmV0dXJuIG5ld09wdHM7CiAgICB9LAoKCiAgICAvKioKICAgICAqIFJFdHVybnMgdGhlIGpzb24gYm9keSBmcm9tIHRoZSByZXNwb25zZS4gSXQgaXMgb25seSBuZWVkZWQgaWYKICAgICAqIHlvdSBhcmUgdXNpbmcgRmV0Y2hVdGlscy5mZXRjaAogICAgICoKICAgICAqIFVzYWdlOgogICAgICogRmV0Y2hVdGlscy5mZXRjaCguLikudGhlbihGZXRjaFV0aWxzLnBhcnNlSlNPTikKICAgICAqLwogICAgcGFyc2VKU09OOiBmdW5jdGlvbiBwYXJzZUpTT04ocmVzcG9uc2UpIHsKICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpCiAgICAgICAgLy8gRklYTUU6IHdvcmthcm91bmQgZm9yIHN0YXR1cz0yMDAgdy8gZW1wdHkgcmVzcG9uc2UgYm9keSB0aGF0IGNhdXNlcyBlcnJvciBpbiBDaHJvbWUKICAgICAgICAvLyBzZXJ2ZXIgc2hvdWxkIHByb2JhYmx5IHJldHVybiBIVFRQIDIwNCBpbnN0ZWFkCiAgICAgICAgLmNhdGNoKGZ1bmN0aW9uIChlcnJvcikgewogICAgICAgICAgICBpZiAoZXJyb3IubWVzc2FnZSA9PT0gJ1VuZXhwZWN0ZWQgZW5kIG9mIEpTT04gaW5wdXQnKSB7CiAgICAgICAgICAgICAgICByZXR1cm4ge307CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgfSk7CiAgICB9LAoKCiAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1wYXJhbS1yZWFzc2lnbiAqLwogICAgLyoqCiAgICAgKiBQYXJzZXMgdGhlIHJlc3BvbnNlIGJvZHkgZm9yIHRoZSBlcnJvciBnZW5lcmF0ZWQgaW4gY2hlY2tTdGF0dXMuCiAgICAgKi8KICAgIHBhcnNlRXJyb3JKc29uOiBmdW5jdGlvbiBwYXJzZUVycm9ySnNvbihlcnJvcikgewogICAgICAgIHJldHVybiBlcnJvci5yZXNwb25zZS5qc29uKCkudGhlbihmdW5jdGlvbiAoYm9keSkgewogICAgICAgICAgICBlcnJvci5yZXNwb25zZUJvZHkgPSBib2R5OwogICAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9LCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGVycm9yLnJlc3BvbnNlQm9keSA9IG51bGw7CiAgICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgIH0pOwogICAgfSwKCiAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXBhcmFtLXJlYXNzaWduICovCgogICAgLyoqCiAgICAqIEVycm9yIGZ1bmN0aW9uIGhlbHBlciB0byBsb2cgZXJyb3JzIHRvIGNvbnNvbGUuCiAgICAqCiAgICAqIFVzYWdlOwogICAgKiBmZXRjaEpzb24oLi4pLmNhdGNoKEZldGNoVXRpbHMuY29uc29sZUVycm9yKQogICAgKi8KICAgIGNvbnNvbGVFcnJvcjogZnVuY3Rpb24gY29uc29sZUVycm9yKGVycm9yKSB7CiAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tY29uc29sZQogICAgfSwKCgogICAgLyoqCiAgICAgKiBFcnJvciBmdW5jdGlvbiBoZWxwZXIgdG8gY2FsbCBhIGNhbGxiYWNrIG9uIGEgcmVqZWN0ZWQgcHJvbWlzZS4KICAgICAqIGlmIGNhbGxiYWNrIGlzIG51bGwsIGxvZyB0byBjb25zb2xlKS4gVXNlIC5jYXRjaCgpIGlmIHlvdSBrbm93IGl0CiAgICAgKiB3aWxsIG5vdCBiZSBudWxsIHRob3VnaC4KICAgICAqCiAgICAgKiBVc2FnZTsKICAgICAqIGZldGNoSnNvbiguLikuY2F0Y2goRmV0Y2hVdGlscy5vbkVycm9yKGVycm9yID0+IC8vZG8gc29tZXRoaW5nKQogICAgICovCiAgICBvbkVycm9yOiBmdW5jdGlvbiBvbkVycm9yKGVycm9yRnVuYykgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IpIHsKICAgICAgICAgICAgaWYgKGVycm9yRnVuYykgewogICAgICAgICAgICAgICAgZXJyb3JGdW5jKGVycm9yKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEZldGNoRnVuY3Rpb25zLmNvbnNvbGVFcnJvcihlcnJvcik7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfSwKCgogICAgLyoqCiAgICAqIFJhdyBmZXRjaCB0aGF0IHJldHVybnMgdGhlIGpzb24gYm9keS4KICAgICoKICAgICogVGhpcyBtZXRob2QgaXMgc2VtaS1wcml2YXRlLCB1bmRlciBub3JtYWwgY29uZGl0aW9ucyBpdCBzaG91bGQgbm90IGJlCiAgICAqIHVzZWQgYXMgaXQgZG9lcyBub3QgaW5jbHVkZSB0aGUgSldUIGJlYXJlciB0b2tlbgogICAgKgogICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIC0gVGhlIFVSTCB0byBmZXRjaCBmcm9tLgogICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdCiAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtvcHRpb25zLm9uU3VjY2Vzc10gLSBPcHRpb25hbCBjYWxsYmFjayBzdWNjZXNzIGZ1bmN0aW9uLgogICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbb3B0aW9ucy5vbkVycm9yXSAtIE9wdGlvbmFsIGVycm9yIGNhbGxiYWNrLgogICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuZmV0Y2hPcHRpb25zXSAtIE9wdGlvbmFsIGlzb21vcnBoaWMtZmV0Y2ggb3B0aW9ucy4KICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5kaXNhYmxlRGVkdXBlXSAtIE9wdGlvbmFsIGZsYWcgdG8gZGlzYWJsZSBkZWR1cGUgZm9yIHRoaXMgcmVxdWVzdC4KICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5kaXNhYmxlTG9hZGluZ0luZGljYXRvcl0gLSBPcHRpb25hbCBmbGFnIHRvIGRpc2FibGUgbG9hZGluZyBpbmRpY2F0b3IgZm9yIHRoaXMgcmVxdWVzdC4KICAgICogQHJldHVybnMgSlNPTiBib2R5CiAgICAqLwogICAgcmF3RmV0Y2hKU09OOiBmdW5jdGlvbiByYXdGZXRjaEpTT04odXJsKSB7CiAgICAgICAgdmFyIF9yZWYgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9LAogICAgICAgICAgICBvblN1Y2Nlc3MgPSBfcmVmLm9uU3VjY2VzcywKICAgICAgICAgICAgb25FcnJvciA9IF9yZWYub25FcnJvciwKICAgICAgICAgICAgZmV0Y2hPcHRpb25zID0gX3JlZi5mZXRjaE9wdGlvbnMsCiAgICAgICAgICAgIGRpc2FibGVEZWR1cGUgPSBfcmVmLmRpc2FibGVEZWR1cGUsCiAgICAgICAgICAgIGRpc2FibGVMb2FkaW5nSW5kaWNhdG9yID0gX3JlZi5kaXNhYmxlTG9hZGluZ0luZGljYXRvcjsKCiAgICAgICAgdmFyIHJlcXVlc3QgPSBmdW5jdGlvbiByZXF1ZXN0KCkgewogICAgICAgICAgICB2YXIgZnV0dXJlID0gZ2V0UHJlZmV0Y2hlZERhdGFGdXR1cmUodXJsKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11c2UtYmVmb3JlLWRlZmluZQogICAgICAgICAgICBpZiAoIWZ1dHVyZSkgewogICAgICAgICAgICAgICAgaWYgKCFkaXNhYmxlTG9hZGluZ0luZGljYXRvcikgewogICAgICAgICAgICAgICAgICAgIF9Mb2FkaW5nSW5kaWNhdG9yMi5kZWZhdWx0LnNob3coKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmdXR1cmUgPSAoMCwgX2lzb21vcnBoaWNGZXRjaDIuZGVmYXVsdCkodXJsLCBGZXRjaEZ1bmN0aW9ucy5zYW1lT3JpZ2luRmV0Y2hPcHRpb24oZmV0Y2hPcHRpb25zKSkudGhlbihGZXRjaEZ1bmN0aW9ucy5jaGVja1JlZnJlc2hIZWFkZXIpLnRoZW4oRmV0Y2hGdW5jdGlvbnMuY2hlY2tTdGF0dXMpLnRoZW4oRmV0Y2hGdW5jdGlvbnMucGFyc2VKU09OLCBGZXRjaEZ1bmN0aW9ucy5wYXJzZUVycm9ySnNvbik7CgogICAgICAgICAgICAgICAgaWYgKCFkaXNhYmxlTG9hZGluZ0luZGljYXRvcikgewogICAgICAgICAgICAgICAgICAgIGZ1dHVyZSA9IGZ1dHVyZS50aGVuKEZldGNoRnVuY3Rpb25zLnN0b3BMb2FkaW5nSW5kaWNhdG9yLCBmdW5jdGlvbiAoZXJyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEZldGNoRnVuY3Rpb25zLnN0b3BMb2FkaW5nSW5kaWNhdG9yKCk7dGhyb3cgZXJyOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChvblN1Y2Nlc3MpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmdXR1cmUudGhlbihvblN1Y2Nlc3MpLmNhdGNoKEZldGNoRnVuY3Rpb25zLm9uRXJyb3Iob25FcnJvcikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZnV0dXJlOwogICAgICAgIH07CiAgICAgICAgaWYgKGRpc2FibGVEZWR1cGUpIHsKICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3QoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAoMCwgX2RlZHVwZUNhbGxzMi5kZWZhdWx0KSh1cmwsIHJlcXVlc3QpOwogICAgfSwKCiAgICAvKioKICAgICAqIFJhdyBmZXRjaC4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBpcyBzZW1pLXByaXZhdGUsIHVuZGVyIG5vcm1hbCBjb25kaXRpb25zIGl0IHNob3VsZCBub3QgYmUKICAgICAqIHVzZWQgYXMgaXQgZG9lcyBub3QgaW5jbHVkZSB0aGUgSldUIGJlYXJlciB0b2tlbgogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSBUaGUgVVJMIHRvIGZldGNoIGZyb20uCiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdCiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbb3B0aW9ucy5vblN1Y2Nlc3NdIC0gT3B0aW9uYWwgY2FsbGJhY2sgc3VjY2VzcyBmdW5jdGlvbi4KICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtvcHRpb25zLm9uRXJyb3JdIC0gT3B0aW9uYWwgZXJyb3IgY2FsbGJhY2suCiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuZmV0Y2hPcHRpb25zXSAtIE9wdGlvbmFsIGlzb21vcnBoaWMtZmV0Y2ggb3B0aW9ucy4KICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuZGlzYWJsZURlZHVwZV0gLSBPcHRpb25hbCBmbGFnIHRvIGRpc2FibGUgZGVkdXBlIGZvciB0aGlzIHJlcXVlc3QuCiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmRpc2FibGVMb2FkaW5nSW5kaWNhdG9yXSAtIE9wdGlvbmFsIGZsYWcgdG8gZGlzYWJsZSBsb2FkaW5nIGluZGljYXRvciBmb3IgdGhpcyByZXF1ZXN0LgogICAgICogQHJldHVybnMgZmV0Y2ggcmVzcG9uc2UKICAgICAqLwogICAgcmF3RmV0Y2g6IGZ1bmN0aW9uIHJhd0ZldGNoKHVybCkgewogICAgICAgIHZhciBfcmVmMiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge30sCiAgICAgICAgICAgIG9uU3VjY2VzcyA9IF9yZWYyLm9uU3VjY2VzcywKICAgICAgICAgICAgb25FcnJvciA9IF9yZWYyLm9uRXJyb3IsCiAgICAgICAgICAgIGZldGNoT3B0aW9ucyA9IF9yZWYyLmZldGNoT3B0aW9ucywKICAgICAgICAgICAgZGlzYWJsZURlZHVwZSA9IF9yZWYyLmRpc2FibGVEZWR1cGUsCiAgICAgICAgICAgIGRpc2FibGVMb2FkaW5nSW5kaWNhdG9yID0gX3JlZjIuZGlzYWJsZUxvYWRpbmdJbmRpY2F0b3I7CgogICAgICAgIHZhciByZXF1ZXN0ID0gZnVuY3Rpb24gcmVxdWVzdCgpIHsKICAgICAgICAgICAgdmFyIGZ1dHVyZSA9IGdldFByZWZldGNoZWREYXRhRnV0dXJlKHVybCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmUKICAgICAgICAgICAgaWYgKCFmdXR1cmUpIHsKICAgICAgICAgICAgICAgIGlmICghZGlzYWJsZUxvYWRpbmdJbmRpY2F0b3IpIHsKICAgICAgICAgICAgICAgICAgICBfTG9hZGluZ0luZGljYXRvcjIuZGVmYXVsdC5zaG93KCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZnV0dXJlID0gKDAsIF9pc29tb3JwaGljRmV0Y2gyLmRlZmF1bHQpKHVybCwgRmV0Y2hGdW5jdGlvbnMuc2FtZU9yaWdpbkZldGNoT3B0aW9uKGZldGNoT3B0aW9ucykpLnRoZW4oRmV0Y2hGdW5jdGlvbnMuY2hlY2tSZWZyZXNoSGVhZGVyKS50aGVuKEZldGNoRnVuY3Rpb25zLmNoZWNrU3RhdHVzKTsKCiAgICAgICAgICAgICAgICBpZiAoIWRpc2FibGVMb2FkaW5nSW5kaWNhdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgZnV0dXJlID0gZnV0dXJlLnRoZW4oRmV0Y2hGdW5jdGlvbnMuc3RvcExvYWRpbmdJbmRpY2F0b3IsIGZ1bmN0aW9uIChlcnIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgRmV0Y2hGdW5jdGlvbnMuc3RvcExvYWRpbmdJbmRpY2F0b3IoKTt0aHJvdyBlcnI7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG9uU3VjY2VzcykgewogICAgICAgICAgICAgICAgcmV0dXJuIGZ1dHVyZS50aGVuKG9uU3VjY2VzcykuY2F0Y2goRmV0Y2hGdW5jdGlvbnMub25FcnJvcihvbkVycm9yKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZ1dHVyZTsKICAgICAgICB9OwoKICAgICAgICBpZiAoZGlzYWJsZURlZHVwZSkgewogICAgICAgICAgICByZXR1cm4gcmVxdWVzdCgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICgwLCBfZGVkdXBlQ2FsbHMyLmRlZmF1bHQpKHVybCwgcmVxdWVzdCk7CiAgICB9Cn07Cgp2YXIgRmV0Y2ggPSBleHBvcnRzLkZldGNoID0gewogICAgLyoqCiAgICAgKiBGZXRjaCBKU09OIGRhdGEuCiAgICAgKiA8cD4KICAgICAqIFV0aWxpdHkgZnVuY3Rpb24gdGhhdCBjYW4gYmUgbW9ja2VkIGZvciB0ZXN0aW5nLgogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSBUaGUgVVJMIHRvIGZldGNoIGZyb20uCiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdCiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbb3B0aW9ucy5vblN1Y2Nlc3NdIC0gT3B0aW9uYWwgY2FsbGJhY2sgc3VjY2VzcyBmdW5jdGlvbi4KICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtvcHRpb25zLm9uRXJyb3JdIC0gT3B0aW9uYWwgZXJyb3IgY2FsbGJhY2suCiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuZmV0Y2hPcHRpb25zXSAtIE9wdGlvbmFsIGlzb21vcnBoaWMtZmV0Y2ggb3B0aW9ucy4KICAgICAqIEByZXR1cm5zIEpTT04gYm9keS4KICAgICAqLwogICAgZmV0Y2hKU09OOiBmdW5jdGlvbiBmZXRjaEpTT04odXJsKSB7CiAgICAgICAgdmFyIF9yZWYzID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fSwKICAgICAgICAgICAgb25TdWNjZXNzID0gX3JlZjMub25TdWNjZXNzLAogICAgICAgICAgICBvbkVycm9yID0gX3JlZjMub25FcnJvciwKICAgICAgICAgICAgZmV0Y2hPcHRpb25zID0gX3JlZjMuZmV0Y2hPcHRpb25zLAogICAgICAgICAgICBkaXNhYmxlQ2FwYWJpbGl0ZXMgPSBfcmVmMy5kaXNhYmxlQ2FwYWJpbGl0ZXM7CgogICAgICAgIHZhciBmaXhlZFVybCA9IHVybDsKICAgICAgICBpZiAoX3VybGNvbmZpZzIuZGVmYXVsdC5nZXRKZW5raW5zUm9vdFVSTCgpICE9PSAnJyAmJiAhdXJsLnN0YXJ0c1dpdGgoX3VybGNvbmZpZzIuZGVmYXVsdC5nZXRKZW5raW5zUm9vdFVSTCgpKSkgewogICAgICAgICAgICBmaXhlZFVybCA9ICcnICsgX3VybGNvbmZpZzIuZGVmYXVsdC5nZXRKZW5raW5zUm9vdFVSTCgpICsgdXJsOwogICAgICAgIH0KICAgICAgICB2YXIgZnV0dXJlID0gdm9pZCAwOwogICAgICAgIGlmICghX2NvbmZpZzIuZGVmYXVsdC5pc0pXVEVuYWJsZWQoKSkgewogICAgICAgICAgICBmdXR1cmUgPSBGZXRjaEZ1bmN0aW9ucy5yYXdGZXRjaEpTT04oZml4ZWRVcmwsIHsgb25TdWNjZXNzOiBvblN1Y2Nlc3MsIG9uRXJyb3I6IG9uRXJyb3IsIGZldGNoT3B0aW9uczogZmV0Y2hPcHRpb25zIH0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZ1dHVyZSA9IF9qd3QyLmRlZmF1bHQuZ2V0VG9rZW4oKS50aGVuKGZ1bmN0aW9uICh0b2tlbikgewogICAgICAgICAgICAgICAgcmV0dXJuIEZldGNoRnVuY3Rpb25zLnJhd0ZldGNoSlNPTihmaXhlZFVybCwgewogICAgICAgICAgICAgICAgICAgIG9uU3VjY2Vzczogb25TdWNjZXNzLAogICAgICAgICAgICAgICAgICAgIG9uRXJyb3I6IG9uRXJyb3IsCiAgICAgICAgICAgICAgICAgICAgZmV0Y2hPcHRpb25zOiBGZXRjaEZ1bmN0aW9ucy5qd3RGZXRjaE9wdGlvbih0b2tlbiwgZmV0Y2hPcHRpb25zKQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFkaXNhYmxlQ2FwYWJpbGl0ZXMpIHsKICAgICAgICAgICAgcmV0dXJuIGZ1dHVyZS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX2luZGV4LmNhcGFiaWxpdHlBdWdtZW50ZXIuYXVnbWVudENhcGFiaWxpdGllcyhfdXRpbHMyLmRlZmF1bHQuY2xvbmUoZGF0YSkpOwogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmdXR1cmU7CiAgICB9LAoKCiAgICAvKioKICAgICAqIEZldGNoIGRhdGEuCiAgICAgKiA8cD4KICAgICAqIFV0aWxpdHkgZnVuY3Rpb24gdGhhdCBjYW4gYmUgbW9ja2VkIGZvciB0ZXN0aW5nLgogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSBUaGUgVVJMIHRvIGZldGNoIGZyb20uCiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdCiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbb3B0aW9ucy5vblN1Y2Nlc3NdIC0gT3B0aW9uYWwgY2FsbGJhY2sgc3VjY2VzcyBmdW5jdGlvbi4KICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtvcHRpb25zLm9uRXJyb3JdIC0gT3B0aW9uYWwgZXJyb3IgY2FsbGJhY2suCiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuZmV0Y2hPcHRpb25zXSAtIE9wdGlvbmFsIGlzb21vcnBoaWMtZmV0Y2ggb3B0aW9ucy4KICAgICAqIEByZXR1cm5zIGZldGNoIGJvZHkuCiAgICAgKi8KICAgIGZldGNoOiBmdW5jdGlvbiBmZXRjaCh1cmwpIHsKICAgICAgICB2YXIgX3JlZjQgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9LAogICAgICAgICAgICBvblN1Y2Nlc3MgPSBfcmVmNC5vblN1Y2Nlc3MsCiAgICAgICAgICAgIG9uRXJyb3IgPSBfcmVmNC5vbkVycm9yLAogICAgICAgICAgICBmZXRjaE9wdGlvbnMgPSBfcmVmNC5mZXRjaE9wdGlvbnM7CgogICAgICAgIHZhciBmaXhlZFVybCA9IHVybDsKCiAgICAgICAgaWYgKF91cmxjb25maWcyLmRlZmF1bHQuZ2V0SmVua2luc1Jvb3RVUkwoKSAhPT0gJycgJiYgIXVybC5zdGFydHNXaXRoKF91cmxjb25maWcyLmRlZmF1bHQuZ2V0SmVua2luc1Jvb3RVUkwoKSkpIHsKICAgICAgICAgICAgZml4ZWRVcmwgPSAnJyArIF91cmxjb25maWcyLmRlZmF1bHQuZ2V0SmVua2luc1Jvb3RVUkwoKSArIHVybDsKICAgICAgICB9CiAgICAgICAgaWYgKCFfY29uZmlnMi5kZWZhdWx0LmlzSldURW5hYmxlZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBGZXRjaEZ1bmN0aW9ucy5yYXdGZXRjaChmaXhlZFVybCwgeyBvblN1Y2Nlc3M6IG9uU3VjY2Vzcywgb25FcnJvcjogb25FcnJvciwgZmV0Y2hPcHRpb25zOiBmZXRjaE9wdGlvbnMgfSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gX2p3dDIuZGVmYXVsdC5nZXRUb2tlbigpLnRoZW4oZnVuY3Rpb24gKHRva2VuKSB7CiAgICAgICAgICAgIHJldHVybiBGZXRjaEZ1bmN0aW9ucy5yYXdGZXRjaChmaXhlZFVybCwgewogICAgICAgICAgICAgICAgb25TdWNjZXNzOiBvblN1Y2Nlc3MsCiAgICAgICAgICAgICAgICBvbkVycm9yOiBvbkVycm9yLAogICAgICAgICAgICAgICAgZmV0Y2hPcHRpb25zOiBGZXRjaEZ1bmN0aW9ucy5qd3RGZXRjaE9wdGlvbih0b2tlbiwgZmV0Y2hPcHRpb25zKQogICAgICAgICAgICB9KTsKICAgICAgICB9KTsKICAgIH0KfTsKCmZ1bmN0aW9uIHRyaW1SZXN0VXJsKHVybCkgewogICAgdmFyIFJFU1RfUFJFRklYID0gJ2JsdWUvcmVzdC8nOwogICAgdmFyIHByZWZpeE9mZnNldCA9IHVybC5pbmRleE9mKFJFU1RfUFJFRklYKTsKCiAgICBpZiAocHJlZml4T2Zmc2V0ICE9PSAtMSkgewogICAgICAgIHJldHVybiB1cmwuc3Vic3RyaW5nKHByZWZpeE9mZnNldCk7CiAgICB9CgogICAgcmV0dXJuIHVybDsKfQoKZnVuY3Rpb24gZ2V0UHJlZmV0Y2hlZERhdGFGdXR1cmUodXJsKSB7CiAgICB2YXIgdHJpbW1lZFVybCA9IHRyaW1SZXN0VXJsKHVybCk7CgogICAgZm9yICh2YXIgcHJvcCBpbiBfc2NvcGVzLnByZWZldGNoZGF0YSkgewogICAgICAgIGlmIChfc2NvcGVzLnByZWZldGNoZGF0YS5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgewogICAgICAgICAgICB2YXIgcHJlRmV0Y2hFbnRyeSA9IF9zY29wZXMucHJlZmV0Y2hkYXRhW3Byb3BdOwogICAgICAgICAgICBpZiAocHJlRmV0Y2hFbnRyeS5yZXN0VXJsICYmIHByZUZldGNoRW50cnkuZGF0YSkgewogICAgICAgICAgICAgICAgLy8gSWYgdGhlIHRyaW1tZWQvbm9ybWFsaXplZCByZXN0IFVSTCBtYXRjaGVzIHRoZSB1cmwgYXJnIHN1cHBsaWVkCiAgICAgICAgICAgICAgICAvLyB0byB0aGUgZnVuY3Rpb24sIGNvbnN0cnVjdCBhIHByZS1yZXNvbHZlZCBmdXR1cmUgb2JqZWN0IGNvbnRhaW5pbmcKICAgICAgICAgICAgICAgIC8vIHRoZSBwcmVmZXRjaGVkIGRhdGEgYXMgdGhlIHZhbHVlLgogICAgICAgICAgICAgICAgaWYgKHRyaW1SZXN0VXJsKHByZUZldGNoRW50cnkucmVzdFVybCkgPT09IHRyaW1tZWRVcmwpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKEpTT04ucGFyc2UocHJlRmV0Y2hFbnRyeS5kYXRhKSk7CiAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRlIHRoZSBwcmVGZXRjaEVudHJ5IGkuZS4gd2Ugb25seSB1c2UgdGhlc2UgZW50cmllcyBvbmNlLiBTbywgdGhpcwogICAgICAgICAgICAgICAgICAgICAgICAvLyB3b3JrcyBvbmx5IGZvciB0aGUgZmlyc3QgcmVxdWVzdCBmb3IgdGhlIGRhdGEgYXQgdGhhdCBVUkwuIFN1YnNlcXVlbnQKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FsbHMgb24gdGhhdCBSRVNUIGVuZHBvaW50IHdpbGwgcmVzdWx0IGluIGEgcHJvcGVyIGZldGNoLiBBIGxvY2FsCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN0b3JlIG5lZWRzIHRvIGJlIHVzZWQgKHJlZHV4L21vYnggZXRjKSBpZiB5b3Ugd2FudCB0byBhdm9pZCBtdWx0aXBsZSBjYWxscwogICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgdGhlIHNhbWUgZGF0YS4gVGhpcyBpcyBub3QgYSBjYWNoaW5nIGxheWVyL21lY2hhbmlzbSAhISEKICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIF9zY29wZXMucHJlZmV0Y2hkYXRhW3Byb3BdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gdW5kZWZpbmVkOwp9Cn0seyIuL0xvYWRpbmdJbmRpY2F0b3IiOjIsIi4vY2FwYWJpbGl0eS9pbmRleCI6MTIsIi4vY29uZmlnIjoyMSwiLi9qd3QiOjI2LCIuL3Njb3BlcyI6NDMsIi4vdXJsY29uZmlnIjo1OCwiLi91dGlscyI6NTksIi4vdXRpbHMvZGVkdXBlLWNhbGxzIjo2MSwiZXM2LXByb21pc2UiOjIzMiwiaXNvbW9ycGhpYy1mZXRjaCI6MzI5fV0sMjM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5leGVjdXRlID0gZXhlY3V0ZTsKCnZhciBfY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7Cgp2YXIgX2NvbmZpZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9jb25maWcpOwoKdmFyIF9sb2dnaW5nID0gcmVxdWlyZSgnLi4vbG9nZ2luZycpOwoKdmFyIF9sb2dnaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2xvZ2dpbmcpOwoKdmFyIF9pMThuID0gcmVxdWlyZSgnLi9pMThuJyk7Cgp2YXIgX2kxOG4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaTE4bik7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKdmFyIGxvZ2dlciA9IF9sb2dnaW5nMi5kZWZhdWx0LmxvZ2dlcignaW8uamVua2lucy5ibHVlb2NlYW4uaTE4bi5zdGFydHVwJyk7CgovKioKICogTG9hZCB0aGUgaTE4biByZXNvdXJjZXMgZGVmaW5lZCBmb3IgdGhlIHBsdWdpbiAoaW4gdGhlIGV4dGVuc2lvbnMpLgogKgogKiBAcGFyYW0ge2Z1bmN0aW9ufSBkb25lIENhbGxiYWNrIGZ1bmN0aW9uLiBDYWxsZWQgb25jZSBhbGwgcmVzb3VyY2VzLgogKiBAcGFyYW0ge29iamVjdH0gYnVuZGxlQ29uZmlnIEJ1bmRsZSBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMuCiAqLwovKgogKiBUaGUgTUlUIExpY2Vuc2UKICoKICogQ29weXJpZ2h0IChjKSAyMDE3LCBDbG91ZEJlZXMsIEluYy4KICoKICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQogKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAogKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgogKiBUSEUgU09GVFdBUkUuCiAqLwoKLyoqCiAqIENsaWVudCBidW5kbGUgc3RhcnR1cCBzY3JpcHQgZm9yIGxvYWRpbmcgaTE4biByZXNvdXJjZXMuCiAqIDxwPgogKiBFbnN1cmVzIHRoYXQgaTE4biByZXNvdXJjZXMgYXJlIGxvYWRlZCBiZWZvcmUgdGhlIGJ1bmRsZSBzdGFydHMgdG8gZXhlY3V0ZS4KICovCgpmdW5jdGlvbiBleGVjdXRlKGRvbmUsIGJ1bmRsZUNvbmZpZykgewogICAgaWYgKGJ1bmRsZUNvbmZpZy5ocGlQbHVnaW5JZCkgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBwbHVnaW5JbmZvID0gX2NvbmZpZzIuZGVmYXVsdC5nZXRQbHVnaW5JbmZvKGJ1bmRsZUNvbmZpZy5ocGlQbHVnaW5JZCk7CiAgICAgICAgICAgIGlmIChwbHVnaW5JbmZvKSB7CiAgICAgICAgICAgICAgICBpZiAocGx1Z2luSW5mby5pMThuQnVuZGxlcyAmJiBwbHVnaW5JbmZvLmkxOG5CdW5kbGVzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1BsdWdpbiAnICsgYnVuZGxlQ29uZmlnLmhwaVBsdWdpbklkICsgJyBkZWZpbmVzIGkxOG4gcmVzb3VyY2UgYnVuZGxlcyB0aGF0IG11c3QgYmUgbG9hZGVkOicsIHBsdWdpbkluZm8uaTE4bkJ1bmRsZXMpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbG9hZGVkQnVuZGxlcyA9IFtdOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbG9hZEJ1bmRsZSA9IGZ1bmN0aW9uIGxvYWRCdW5kbGUobmFtZXNwYWNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhbnNsYXRvciA9ICgwLCBfaTE4bjIuZGVmYXVsdCkoYnVuZGxlQ29uZmlnLmhwaVBsdWdpbklkLCBuYW1lc3BhY2UsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9hZGVkQnVuZGxlcy5pbmRleE9mKG5hbWVzcGFjZSkgPT09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnTG9hZGluZyBvZiBpMThuIHJlc291cmNlIGJ1bmRsZSAiJyArIGJ1bmRsZUNvbmZpZy5ocGlQbHVnaW5JZCArICc6JyArIG5hbWVzcGFjZSArICciIGRvbmUuJyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlZEJ1bmRsZXMucHVzaChuYW1lc3BhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9hZGVkQnVuZGxlcy5sZW5ndGggPT09IHBsdWdpbkluZm8uaTE4bkJ1bmRsZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBbGwgYnVuZGxlcyBhcmUgbG9hZGVkIC4uLiBvayBmb3IgdGhlIGJ1bmRsZSB0byBleGVjdXRlIG5vdyAoZnJvbSBhbiBpMThuIHBvdikuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKCdBbGwgaTE4biAiJyArIGJ1bmRsZUNvbmZpZy5ocGlQbHVnaW5JZCArICciIHJlc291cmNlIGJ1bmRsZXMgbG9hZGVkLicsIHBsdWdpbkluZm8uaTE4bkJ1bmRsZXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDYWxsIHRoZSB0cmFuc2xhdG9yIHRvIHRyaWdnZXIgbG9hZGluZy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFueSByYW5kb20ga2V5IGlzIGZpbmUgLi4uIGp1c3QgbmVlZHMgdG8gdHJpZ2dlciB0aGUgbG9hZGluZy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0b3IoJ3h4eHgnKTsKICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2luSW5mby5pMThuQnVuZGxlcy5mb3JFYWNoKGZ1bmN0aW9uIChidW5kbGVOYW1lc3BhY2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2FkQnVuZGxlKGJ1bmRsZU5hbWVzcGFjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0pKCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnUGx1Z2luICInICsgYnVuZGxlQ29uZmlnLmhwaVBsdWdpbklkICsgJyIgZG9lc25cJ3QgZGVmaW5lIGFueSBpMThuIHJlc291cmNlIGJ1bmRsZXMuJyk7CiAgICAgICAgICAgICAgICAgICAgZG9uZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1VuZXhwZWN0ZWQgZXJyb3IgZmluZGluZyBwbHVnaW5nIGluZm8gZm9yIHBsdWdpbiAnICsgYnVuZGxlQ29uZmlnLmhwaVBsdWdpbklkICsgJy4gVGhlcmUgc2hvdWxkIGJlIGEgcHJlbG9hZGVkIGpzRXh0ZW5zaW9ucyBlbnRyeS4nKTsKICAgICAgICAgICAgICAgIGRvbmUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0pKCk7CiAgICB9IGVsc2UgewogICAgICAgIGRvbmUoKTsKICAgIH0KfQp9LHsiLi4vY29uZmlnIjoyMSwiLi4vbG9nZ2luZyI6MjcsIi4vaTE4biI6MjR9XSwyNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLmRlZmF1bHRMbmdEZXRlY3RvciA9IHVuZGVmaW5lZDsKZXhwb3J0cy5kZWZhdWx0ID0gaTE4blRyYW5zbGF0b3I7CmV4cG9ydHMuZW5hYmxlTW9ja3NGb3JJMThuID0gZW5hYmxlTW9ja3NGb3JJMThuOwpleHBvcnRzLmRpc2FibGVNb2Nrc0ZvckkxOG4gPSBkaXNhYmxlTW9ja3NGb3JJMThuOwoKdmFyIF9pMThuZXh0ID0gcmVxdWlyZSgnaTE4bmV4dCcpOwoKdmFyIF9pMThuZXh0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2kxOG5leHQpOwoKdmFyIF9pMThuZXh0QnJvd3Nlckxhbmd1YWdlZGV0ZWN0b3IgPSByZXF1aXJlKCdpMThuZXh0LWJyb3dzZXItbGFuZ3VhZ2VkZXRlY3RvcicpOwoKdmFyIF9pMThuZXh0QnJvd3Nlckxhbmd1YWdlZGV0ZWN0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaTE4bmV4dEJyb3dzZXJMYW5ndWFnZWRldGVjdG9yKTsKCnZhciBfaTE4bmV4dFhockJhY2tlbmQgPSByZXF1aXJlKCdpMThuZXh0LXhoci1iYWNrZW5kJyk7Cgp2YXIgX2kxOG5leHRYaHJCYWNrZW5kMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2kxOG5leHRYaHJCYWNrZW5kKTsKCnZhciBfanNFeHRlbnNpb25zID0gcmVxdWlyZSgnQGplbmtpbnMtY2QvanMtZXh0ZW5zaW9ucycpOwoKdmFyIF91cmxjb25maWcgPSByZXF1aXJlKCcuLi91cmxjb25maWcnKTsKCnZhciBfdXJsY29uZmlnMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3VybGNvbmZpZyk7Cgp2YXIgX2xvZ2dpbmcgPSByZXF1aXJlKCcuLi9sb2dnaW5nJyk7Cgp2YXIgX2xvZ2dpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbG9nZ2luZyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKdmFyIGxvZ2dlciA9IF9sb2dnaW5nMi5kZWZhdWx0LmxvZ2dlcignaW8uamVua2lucy5ibHVlb2NlYW4uaTE4bicpOwoKLyoqCiAqIEluaXQgbGFuZ3VhZ2UgZGV0ZWN0b3IsIHdlIGFyZSBnb2luZyB0byB1c2UgZmlyc3QgcXVlcnlTdHJpbmcgYW5kIHRoZW4gdGhlIG5hdmlnYXRvciBwcmVmZXJlZCBsYW5ndWFnZQogKi8KdmFyIGRlZmF1bHRMbmdEZXRlY3RvciA9IGV4cG9ydHMuZGVmYXVsdExuZ0RldGVjdG9yID0gbmV3IF9pMThuZXh0QnJvd3Nlckxhbmd1YWdlZGV0ZWN0b3IyLmRlZmF1bHQobnVsbCwgewogICAgLy8gb3JkZXIgYW5kIGZyb20gd2hlcmUgdXNlciBsYW5ndWFnZSBzaG91bGQgYmUgZGV0ZWN0ZWQKICAgIG9yZGVyOiBbJ3F1ZXJ5c3RyaW5nJywgJ2h0bWxUYWcnLCAnbmF2aWdhdG9yJ10sCiAgICAvLyBrZXlzIG9yIHBhcmFtcyB0byBsb29rdXAgbGFuZ3VhZ2UgZnJvbQogICAgbG9va3VwUXVlcnlzdHJpbmc6ICdsYW5ndWFnZScsCiAgICAvLyBEb24ndCB1c2UgdGhlIGRlZmF1bHQgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkgYmVjYXVzZSB0aGF0IGNhbgogICAgLy8gdHJpZ2dlciB0aGUgYnJvd3NlcnMgYXV0by10cmFuc2xhdGUsIHdoaWNoIGlzIHF1aXRlIGFubm95aW5nLgogICAgaHRtbFRhZzogd2luZG93LmRvY3VtZW50ID8gd2luZG93LmRvY3VtZW50LmhlYWQgOiB1bmRlZmluZWQKfSk7CnZhciBwcmVmaXggPSBfdXJsY29uZmlnMi5kZWZhdWx0LmdldEplbmtpbnNSb290VVJMKCkgfHwgJyc7CnZhciBGQUxMQkFDS19MQU5HID0gJyc7CgpmdW5jdGlvbiBuZXdQbHVnaW5YSFIocGx1Z2luTmFtZSwgb25Mb2FkKSB7CiAgICB2YXIgcGx1Z2luVmVyc2lvbiA9IF9qc0V4dGVuc2lvbnMuc3RvcmUuZ2V0UGx1Z2luVmVyc2lvbihwbHVnaW5OYW1lKTsKCiAgICBpZiAoIXBsdWdpblZlcnNpb24pIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBjcmVhdGUgYW4gaTE4biBpbnN0YW5jZSBmb3IgcGx1Z2luICInICsgcGx1Z2luTmFtZSArICciLiBUaGlzIHBsdWdpbiBpcyBub3QgY3VycmVudGx5IGluc3RhbGxlZCwgb3IgaXMgZGlzYWJsZWQuJyk7CiAgICB9CgogICAgcGx1Z2luVmVyc2lvbiA9IGVuY29kZVVSSUNvbXBvbmVudChwbHVnaW5WZXJzaW9uKTsKCiAgICB2YXIgbG9hZFBhdGggPSBwcmVmaXggKyAnL2JsdWUvcmVzdC9pMThuLycgKyBwbHVnaW5OYW1lICsgJy8nICsgcGx1Z2luVmVyc2lvbiArICcve25zfS97bG5nfSc7CiAgICByZXR1cm4gbmV3IF9pMThuZXh0WGhyQmFja2VuZDIuZGVmYXVsdChudWxsLCB7CiAgICAgICAgbG9hZFBhdGg6IGxvYWRQYXRoLAogICAgICAgIGFsbG93TXVsdGlMb2FkaW5nOiBmYWxzZSwKICAgICAgICBwYXJzZTogZnVuY3Rpb24gcGFyc2UoZGF0YSkgewogICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIHBhcnNlIHRoZSByZXNwb25zZSBhbmQgdGhlbiBleHRyYWN0IHRoZSBkYXRhIHNpbmNlIHRoZSByZXN0IGlzIGdhcmJhZ2UgZm9yIHVzCiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IEpTT04ucGFyc2UoZGF0YSk7CiAgICAgICAgICAgIGlmIChsb2dnZXIuaXNEZWJ1Z0VuYWJsZWQoKSkgewogICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdSZWNlaXZlZCBpMThuIHJlc291cmNlIGJ1bmRsZSBmb3IgcGx1Z2luICIlcyIuJywgcGx1Z2luTmFtZSwgcmVzcG9uc2UuZGF0YSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHR5cGVvZiBvbkxvYWQgPT09ICdmdW5jdGlvbicpIHsKICAgICAgICAgICAgICAgIG9uTG9hZCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXNwb25zZS5kYXRhOwogICAgICAgIH0KICAgIH0pOwp9CgovKioKICogQ3JlYXRlIGEgaW5zdGFuY2Ugb2YgaTE4bmV4dCBhbmQgaW5pdCBpdAogKiBpbiBjYXNlIHdlIGFyZSBpbiB0ZXN0IG1vZGUgYW5kIHJ1biB1bml0IHRlc3QsIHdlIGRlbGl2ZXIgYSBpMThuZXh0IGluc3RhbmNlIHRoYXQgYXJlIG5vdCB1c2luZyBhbnkgYmFja2VuZCBub3IgbGFuZ3VhZ2UgZGV0ZWN0aW9uCiAqIEBwYXJhbSBiYWNrZW5kICB7b2JqZWN0fSAtIHRoZSBiYWNrZW5kIFhIUiBpbnZva2VyIHdlIHdhbnQgdG8gdXNlCiAqIEBwYXJhbSBsbmdEZXRlY3RvciB7b2JqZWN0fSAtIHRoZSBjb21wb25lbnQgdGhhdCBkZXRlY3RzIHdoaWNoIGxhbmd1YWdlIHdlIHdhbnQgdG8gZGlzcGxheQogKiBAcGFyYW0gb3B0aW9ucyB7b2JqZWN0fSAtIGdlbmVyYWwgb3B0aW9ucyBmb3IgaTE4bmV4dAogKiBAc2VlIGRlZmF1bHRPcHRpb25zCiAqLwp2YXIgaTE4bmV4dEluc3RhbmNlID0gZnVuY3Rpb24gaTE4bmV4dEluc3RhbmNlKGJhY2tlbmQpIHsKICAgIHZhciBsbmdEZXRlY3RvciA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogZGVmYXVsdExuZ0RldGVjdG9yOwogICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHNbMl07CgogICAgaWYgKCFiYWNrZW5kKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNhbGwgdG8gY3JlYXRlIGEgbmV3IGkxOG5leHQgaW5zdGFuY2UuIE5vIGJhY2tlbmQgWEhSIGludm9rZXIgc3VwcGxpZWQuJyk7CiAgICB9CiAgICBpZiAoIW9wdGlvbnMpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY2FsbCB0byBjcmVhdGUgYSBuZXcgaTE4bmV4dCBpbnN0YW5jZS4gTm8gaTE4bmV4dCBvcHRpb25zIHN1cHBsaWVkLicpOwogICAgfQogICAgcmV0dXJuIF9pMThuZXh0Mi5kZWZhdWx0LmNyZWF0ZUluc3RhbmNlKCkudXNlKGJhY2tlbmQpLnVzZShsbmdEZXRlY3RvcikuaW5pdChvcHRpb25zKTsKfTsKCnZhciB0cmFuc2xhdG9yQ2FjaGUgPSB7fTsKdmFyIHVzZU1vY2tGYWxsYmFjayA9IGZhbHNlOwoKdmFyIGFzc2VydFBsdWdpbk5hbWVEZWZpbmVkID0gZnVuY3Rpb24gYXNzZXJ0UGx1Z2luTmFtZURlZmluZWQocGx1Z2luTmFtZSkgewogICAgaWYgKCFwbHVnaW5OYW1lKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCcicGx1Z2luTmFtZSIgYXJnIGNhbm5vdCBiZSBudWxsL2JsYW5rJyk7CiAgICB9Cn07Cgp2YXIgdG9EZWZhdWx0TmFtZXNwYWNlID0gZnVuY3Rpb24gdG9EZWZhdWx0TmFtZXNwYWNlKHBsdWdpbk5hbWUpIHsKICAgIGFzc2VydFBsdWdpbk5hbWVEZWZpbmVkKHBsdWdpbk5hbWUpOwogICAgLy8gUmVwbGFjZSBhbGwgaHlwaGVuIGNoYXJzIHdpdGggYSBkb3QuCiAgICByZXR1cm4gJ2plbmtpbnMucGx1Z2lucy4nICsgcGx1Z2luTmFtZS5yZXBsYWNlKC8tL2csICcuJykgKyAnLk1lc3NhZ2VzJzsKfTsKCi8qKgogKiBDcmVhdGUgYW4gaTE4bmV4dCBpbnN0YW5jZSBmb3IgYWNjZXNzaW5nIGkxOG4gcmVzb3VyY2UgYnVuZGxlcwogKiBpbiB0aGUgbmFtZWQgcGx1Z2luIG5hbWVzcGFjZS4KICogQHBhcmFtIHBsdWdpbk5hbWUgVGhlIG5hbWUgb2YgdGhlIHBsdWdpbi4KICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgcmVzb3VyY2UgYnVuZGxlIG5hbWVzcGFjZS4gT3B0aW9uYWwsIGRlZmF1bHRpbmcgdG8KICogdGhlIHBsdWdpbidzIGRlZmF1bHQgcmVzb3VyY2UgYnVuZGxlIGUuZy4gImplbmtpbnMucGx1Z2lucy5ibHVlb2NlYW4ud2ViLk1lc3NhZ2VzIgogKiBmb3IgdGhlICJibHVlb2NlYW4td2ViIiBwbHVnaW4gYW5kICJqZW5raW5zLnBsdWdpbnMuYmx1ZW9jZWFuLmRhc2hib2FyZC5NZXNzYWdlcyIKICogZm9yIHRoZSAiYmx1ZW9jZWFuLWRhc2hib2FyZCIgcGx1Z2luLgogKiBAcmV0dXJuIEFuIGkxOG4gaW5zdGFuY2UuCiAqLwp2YXIgcGx1Z2luSTE4bmV4dCA9IGZ1bmN0aW9uIHBsdWdpbkkxOG5leHQocGx1Z2luTmFtZSkgewogICAgdmFyIG5hbWVzcGFjZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogdG9EZWZhdWx0TmFtZXNwYWNlKHBsdWdpbk5hbWUpOwogICAgdmFyIG9uTG9hZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkOwoKICAgIGFzc2VydFBsdWdpbk5hbWVEZWZpbmVkKHBsdWdpbk5hbWUpOwoKICAgIHZhciBpbml0T3B0aW9ucyA9IHsKICAgICAgICBuczogW25hbWVzcGFjZV0sCiAgICAgICAgZGVmYXVsdE5TOiBuYW1lc3BhY2UsCiAgICAgICAga2V5U2VwYXJhdG9yOiBmYWxzZSwgLy8gd2UgZG8gbm90IGhhdmUgYW55IG5lc3RlZCBrZXlzIGluIHByb3BlcnRpZXMgZmlsZXMKICAgICAgICBkZWJ1ZzogZmFsc2UsCiAgICAgICAgZmFsbGJhY2tMbmc6IEZBTExCQUNLX0xBTkcsCiAgICAgICAgbG9hZDogJ2N1cnJlbnRPbmx5JywKICAgICAgICBpbnRlcnBvbGF0aW9uOiB7CiAgICAgICAgICAgIHByZWZpeDogJ3snLAogICAgICAgICAgICBzdWZmaXg6ICd9JywKICAgICAgICAgICAgZXNjYXBlVmFsdWU6IGZhbHNlIH0KICAgIH07CgogICAgcmV0dXJuIGkxOG5leHRJbnN0YW5jZShuZXdQbHVnaW5YSFIocGx1Z2luTmFtZSwgb25Mb2FkKSwgZGVmYXVsdExuZ0RldGVjdG9yLCBpbml0T3B0aW9ucyk7Cn07CgpmdW5jdGlvbiBidWlsZENhY2hlS2V5KHBsdWdpbk5hbWUpIHsKICAgIHZhciBuYW1lc3BhY2UgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHRvRGVmYXVsdE5hbWVzcGFjZShwbHVnaW5OYW1lKTsKCiAgICByZXR1cm4gcGx1Z2luTmFtZSArICc6JyArIG5hbWVzcGFjZTsKfQoKLyoqCiAqIENyZWF0ZSBhbiBpMThuIFRyYW5zbGF0b3IgaW5zdGFuY2UgZm9yIGFjY2Vzc2luZyBpMThuIHJlc291cmNlIGJ1bmRsZXMKICogaW4gdGhlIG5hbWVkIHBsdWdpbiBuYW1lc3BhY2UuCiAqIEBwYXJhbSBwbHVnaW5OYW1lIFRoZSBuYW1lIG9mIHRoZSBwbHVnaW4uCiAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIHJlc291cmNlIGJ1bmRsZSBuYW1lc3BhY2UuIE9wdGlvbmFsLCBkZWZhdWx0aW5nIHRvCiAqIHRoZSBwbHVnaW4ncyBkZWZhdWx0IHJlc291cmNlIGJ1bmRsZSBlLmcuICJqZW5raW5zLnBsdWdpbnMuYmx1ZW9jZWFuLndlYi5NZXNzYWdlcyIKICogZm9yIHRoZSAiYmx1ZW9jZWFuLXdlYiIgcGx1Z2luIGFuZCAiamVua2lucy5wbHVnaW5zLmJsdWVvY2Vhbi5kYXNoYm9hcmQuTWVzc2FnZXMiCiAqIGZvciB0aGUgImJsdWVvY2Vhbi1kYXNoYm9hcmQiIHBsdWdpbi4KICogQHJldHVybiBBbiBpMThuIFRyYW5zbGF0b3IgaW5zdGFuY2UuCiAqLwpmdW5jdGlvbiBpMThuVHJhbnNsYXRvcihwbHVnaW5OYW1lLCBuYW1lc3BhY2UsIG9uTG9hZCkgewogICAgYXNzZXJ0UGx1Z2luTmFtZURlZmluZWQocGx1Z2luTmFtZSk7CgogICAgdmFyIHRyYW5zbGF0b3JDYWNoZUtleSA9IGJ1aWxkQ2FjaGVLZXkocGx1Z2luTmFtZSwgbmFtZXNwYWNlKTsKICAgIHZhciB0cmFuc2xhdG9yID0gdHJhbnNsYXRvckNhY2hlW3RyYW5zbGF0b3JDYWNoZUtleV07CgogICAgaWYgKHRyYW5zbGF0b3IpIHsKICAgICAgICBpZiAodHlwZW9mIG9uTG9hZCA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICBvbkxvYWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRyYW5zbGF0b3I7CiAgICB9CgogICAgLy8gTGF6aWx5IGNvbnN0cnVjdCB3aGF0IHdlIG5lZWQgaW5zdGVhZCBvZiBvbiBjcmVhdGlvbgogICAgcmV0dXJuIGZ1bmN0aW9uIHRyYW5zbGF0ZShrZXksIHBhcmFtcykgewogICAgICAgIGlmICh1c2VNb2NrRmFsbGJhY2spIHsKICAgICAgICAgICAgcmV0dXJuIHBhcmFtcyAmJiBwYXJhbXMuZGVmYXVsdFZhbHVlIHx8IGtleTsKICAgICAgICB9CgogICAgICAgIGlmICghdHJhbnNsYXRvcikgewogICAgICAgICAgICAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIEkxOG4gPSBwbHVnaW5JMThuZXh0KHBsdWdpbk5hbWUsIG5hbWVzcGFjZSwgb25Mb2FkKTsKCiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYW5kIGNhY2hlIHRoZSB0cmFuc2xhdG9yIGluc3RhbmNlLgogICAgICAgICAgICAgICAgdmFyIGRldGVjdGVkTGFuZyA9IHZvaWQgMDsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgZGV0ZWN0ZWRMYW5nID0gZGVmYXVsdExuZ0RldGVjdG9yLmRldGVjdCgpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgIGRldGVjdGVkTGFuZyA9IEZBTExCQUNLX0xBTkc7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGxvZ2dlci5pc0xvZ0VuYWJsZWQoKSkgewogICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coJ1RyYW5zbGF0b3IgaW5zdGFuY2UgY3JlYXRlZCBmb3IgIiVzIi4gTGFuZ3VhZ2UgZGV0ZWN0ZWQgYXMgIiVzIi4nLCB0cmFuc2xhdG9yQ2FjaGVLZXksIGRldGVjdGVkTGFuZyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyIGZpeGVkVCA9IEkxOG4uZ2V0Rml4ZWRUKGRldGVjdGVkTGFuZywgbmFtZXNwYWNlKTsKICAgICAgICAgICAgICAgIHRyYW5zbGF0b3IgPSBmdW5jdGlvbiB0cmFuc2xhdG9yKGkxOG5LZXksIGkxOG5QYXJhbXMpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbm9ybWFsaXplZEtleSA9IGkxOG5LZXkucmVwbGFjZSgvW1xXXS9nLCAnLicpOwogICAgICAgICAgICAgICAgICAgIHZhciBwYXNzZWRQYXJhbXMgPSBpMThuUGFyYW1zOwogICAgICAgICAgICAgICAgICAgIGlmIChub3JtYWxpemVkS2V5ICE9PSBpMThuS2V5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcGFzc2VkUGFyYW1zKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXNzZWRQYXJhbXMgPSB7fTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXBhc3NlZFBhcmFtcy5kZWZhdWx0VmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3NlZFBhcmFtcy5kZWZhdWx0VmFsdWUgPSBpMThuS2V5OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2dnZXIuaXNEZWJ1Z0VuYWJsZWQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdOb3JtYWxpemVkIGkxOG4ga2V5ICInICsgaTE4bktleSArICciIHRvICInICsgbm9ybWFsaXplZEtleSArICciLicpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmaXhlZFQobm9ybWFsaXplZEtleSwgcGFzc2VkUGFyYW1zKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB0cmFuc2xhdG9yQ2FjaGVbdHJhbnNsYXRvckNhY2hlS2V5XSA9IHRyYW5zbGF0b3I7CiAgICAgICAgICAgIH0pKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoa2V5KSB7CiAgICAgICAgICAgIHJldHVybiB0cmFuc2xhdG9yKGtleSwgcGFyYW1zKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgIH07Cn0KCmZ1bmN0aW9uIGVuYWJsZU1vY2tzRm9ySTE4bigpIHsKICAgIHVzZU1vY2tGYWxsYmFjayA9IHRydWU7Cn0KCmZ1bmN0aW9uIGRpc2FibGVNb2Nrc0ZvckkxOG4oKSB7CiAgICB1c2VNb2NrRmFsbGJhY2sgPSBmYWxzZTsKfQp9LHsiLi4vbG9nZ2luZyI6MjcsIi4uL3VybGNvbmZpZyI6NTgsIkBqZW5raW5zLWNkL2pzLWV4dGVuc2lvbnMiOjEyMiwiaTE4bmV4dCI6MzE5LCJpMThuZXh0LWJyb3dzZXItbGFuZ3VhZ2VkZXRlY3RvciI6Mjk5LCJpMThuZXh0LXhoci1iYWNrZW5kIjozMDN9XSwyNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLnRvQ2xhc3NpY0pvYlBhZ2UgPSBleHBvcnRzLnJlbGF0aXZlVXJsID0gZXhwb3J0cy5idWlsZFVybCA9IGV4cG9ydHMuZ2V0UmVzdFVybCA9IGV4cG9ydHMuZW5kU2xhc2ggPSBleHBvcnRzLnBhZ2luYXRlVXJsID0gZXhwb3J0cy5jYWxjdWxhdGVSdW5Mb2dVUkxPYmplY3QgPSBleHBvcnRzLmNhbGN1bGF0ZVN0ZXBzQmFzZVVybCA9IGV4cG9ydHMuY2FsY3VsYXRlTm9kZUJhc2VVcmwgPSBleHBvcnRzLmNhbGN1bGF0ZUxvZ1VybCA9IGV4cG9ydHMuY2FsY3VsYXRlTG9nVmlldyA9IGV4cG9ydHMuY2FsY3VsYXRlRmV0Y2hBbGwgPSBleHBvcnRzLmFwcGx5RmV0Y2hBbGwgPSBleHBvcnRzLmZldGNoQWxsU3VmZml4ID0gZXhwb3J0cy5kb3VibGVVcmlFbmNvZGUgPSBleHBvcnRzLmJ1aWxkUnVuRGV0YWlsc1VybCA9IGV4cG9ydHMuYnVpbGRDbGFzc2ljQnVpbGRVcmwgPSBleHBvcnRzLmJ1aWxkQ2xhc3NpY0lucHV0VXJsID0gZXhwb3J0cy5idWlsZENsYXNzaWNDb25maWdVcmwgPSBleHBvcnRzLnJvb3RQYXRoID0gZXhwb3J0cy5idWlsZFBpcGVsaW5lVXJsID0gZXhwb3J0cy5idWlsZE9yZ2FuaXphdGlvblVybCA9IGV4cG9ydHMuTGl2ZVN0YXR1c0luZGljYXRvciA9IGV4cG9ydHMuVGltZUhhcm1vbml6ZXIgPSBleHBvcnRzLlRpbWVNYW5hZ2VyID0gZXhwb3J0cy5ERUJVRyA9IGV4cG9ydHMubG9jYXRpb25TZXJ2aWNlID0gZXhwb3J0cy5waXBlbGluZVNlcnZpY2UgPSBleHBvcnRzLmFjdGl2aXR5U2VydmljZSA9IGV4cG9ydHMuc3NlU2VydmljZSA9IGV4cG9ydHMucGFnZXJTZXJ2aWNlID0gZXhwb3J0cy5SdW5BcGkgPSBleHBvcnRzLlRvYXN0U2VydmljZSA9IGV4cG9ydHMuU3NlQnVzID0gZXhwb3J0cy5jYXBhYmlsaXR5QXVnbWVudGVyID0gZXhwb3J0cy5jYXBhYmlsaXR5U3RvcmUgPSBleHBvcnRzLmNhcGFibGUgPSBleHBvcnRzLnNzZUNvbm5lY3Rpb24gPSBleHBvcnRzLlJlc3VsdFBhZ2VIZWFkZXIgPSBleHBvcnRzLlNpdGVIZWFkZXIgPSBleHBvcnRzLkNvbnRlbnRQYWdlSGVhZGVyID0gZXhwb3J0cy5CbHVlT2NlYW5JY29uID0gZXhwb3J0cy5CbHVlTG9nbyA9IGV4cG9ydHMuUGFyYW1ldGVyc1JlbmRlciA9IGV4cG9ydHMuc3VwcG9ydGVkSW5wdXRUeXBlc01hcHBpbmcgPSBleHBvcnRzLlBhc3N3b3JkID0gZXhwb3J0cy5UZXh0ID0gZXhwb3J0cy5TdHJpbmcgPSBleHBvcnRzLkNob2ljZSA9IGV4cG9ydHMuQm9vbGVhbiA9IGV4cG9ydHMuUGFyYW1ldGVyQXBpID0gZXhwb3J0cy5QYXJhbWV0ZXJTZXJ2aWNlID0gZXhwb3J0cy5SdW5CdXR0b24gPSBleHBvcnRzLlJ1bkJ1dHRvbkJhc2UgPSBleHBvcnRzLlJlcGxheUJ1dHRvbiA9IGV4cG9ydHMuU2hvd01vcmVCdXR0b24gPSBleHBvcnRzLk5vdEZvdW5kID0gZXhwb3J0cy5GdWxsc2NyZWVuID0gZXhwb3J0cy5TdHJpbmdVdGlsID0gZXhwb3J0cy5BY3Rpdml0eVNlcnZpY2UgPSBleHBvcnRzLlNTRVNlcnZpY2UgPSBleHBvcnRzLlBpcGVsaW5lU2VydmljZSA9IGV4cG9ydHMuUGFnZXJTZXJ2aWNlID0gZXhwb3J0cy5QYWdlciA9IGV4cG9ydHMuUGF0aHMgPSBleHBvcnRzLlNlY3VyaXR5ID0gZXhwb3J0cy5BcHBDb25maWcgPSBleHBvcnRzLlVzZXIgPSBleHBvcnRzLlV0aWxzID0gZXhwb3J0cy5Ub2FzdFV0aWxzID0gZXhwb3J0cy5UZXN0VXRpbHMgPSBleHBvcnRzLkpXVCA9IGV4cG9ydHMuVXJsQ29uZmlnID0gZXhwb3J0cy5VcmxCdWlsZGVyID0gZXhwb3J0cy5GZXRjaEZ1bmN0aW9ucyA9IGV4cG9ydHMuRmV0Y2ggPSBleHBvcnRzLmxvYWRpbmdJbmRpY2F0b3IgPSBleHBvcnRzLmxvZ2dpbmcgPSBleHBvcnRzLmRlZmF1bHRMbmdEZXRlY3RvciA9IGV4cG9ydHMuaTE4blRyYW5zbGF0b3IgPSB1bmRlZmluZWQ7Cgp2YXIgX2kxOG4gPSByZXF1aXJlKCcuL2kxOG4vaTE4bicpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdkZWZhdWx0TG5nRGV0ZWN0b3InLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9pMThuLmRlZmF1bHRMbmdEZXRlY3RvcjsKICAgIH0KfSk7Cgp2YXIgX2ZldGNoID0gcmVxdWlyZSgnLi9mZXRjaCcpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdGZXRjaCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX2ZldGNoLkZldGNoOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdGZXRjaEZ1bmN0aW9ucycsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX2ZldGNoLkZldGNoRnVuY3Rpb25zOwogICAgfQp9KTsKCnZhciBfVXNlciA9IHJlcXVpcmUoJy4vVXNlcicpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdVc2VyJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfVXNlci5Vc2VyOwogICAgfQp9KTsKCnZhciBfU2hvd01vcmVCdXR0b24gPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvU2hvd01vcmVCdXR0b24nKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnU2hvd01vcmVCdXR0b24nLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9TaG93TW9yZUJ1dHRvbi5TaG93TW9yZUJ1dHRvbjsKICAgIH0KfSk7Cgp2YXIgX1JlcGxheUJ1dHRvbiA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9SZXBsYXlCdXR0b24nKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnUmVwbGF5QnV0dG9uJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfUmVwbGF5QnV0dG9uLlJlcGxheUJ1dHRvbjsKICAgIH0KfSk7Cgp2YXIgX1J1bkJ1dHRvbiA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9SdW5CdXR0b24nKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnUnVuQnV0dG9uQmFzZScsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1J1bkJ1dHRvbi5SdW5CdXR0b247CiAgICB9Cn0pOwoKdmFyIF9wYXJhbWV0ZXIgPSByZXF1aXJlKCcuL3BhcmFtZXRlcicpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdSdW5CdXR0b24nLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9wYXJhbWV0ZXIuUGFyYW1ldGVyc1J1bkJ1dHRvbjsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnUGFyYW1ldGVyU2VydmljZScsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX3BhcmFtZXRlci5QYXJhbWV0ZXJTZXJ2aWNlOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdQYXJhbWV0ZXJBcGknLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9wYXJhbWV0ZXIuUGFyYW1ldGVyQXBpOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdCb29sZWFuJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfcGFyYW1ldGVyLkJvb2xlYW47CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ0Nob2ljZScsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX3BhcmFtZXRlci5DaG9pY2U7CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1N0cmluZycsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX3BhcmFtZXRlci5TdHJpbmc7CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1RleHQnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9wYXJhbWV0ZXIuVGV4dDsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnUGFzc3dvcmQnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9wYXJhbWV0ZXIuUGFzc3dvcmQ7CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ3N1cHBvcnRlZElucHV0VHlwZXNNYXBwaW5nJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfcGFyYW1ldGVyLnN1cHBvcnRlZElucHV0VHlwZXNNYXBwaW5nOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdQYXJhbWV0ZXJzUmVuZGVyJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfcGFyYW1ldGVyLlBhcmFtZXRlcnNSZW5kZXI7CiAgICB9Cn0pOwoKdmFyIF9CbHVlTG9nbyA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9CbHVlTG9nbycpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdCbHVlTG9nbycsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX0JsdWVMb2dvLkJsdWVMb2dvOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdCbHVlT2NlYW5JY29uJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfQmx1ZUxvZ28uQmx1ZU9jZWFuSWNvbjsKICAgIH0KfSk7Cgp2YXIgX0NvbnRlbnRQYWdlSGVhZGVyID0gcmVxdWlyZSgnLi9jb21wb25lbnRzL0NvbnRlbnRQYWdlSGVhZGVyJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ0NvbnRlbnRQYWdlSGVhZGVyJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfQ29udGVudFBhZ2VIZWFkZXIuQ29udGVudFBhZ2VIZWFkZXI7CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1NpdGVIZWFkZXInLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9Db250ZW50UGFnZUhlYWRlci5TaXRlSGVhZGVyOwogICAgfQp9KTsKCnZhciBfUmVzdWx0UGFnZUhlYWRlciA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9SZXN1bHRQYWdlSGVhZGVyJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1Jlc3VsdFBhZ2VIZWFkZXInLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9SZXN1bHRQYWdlSGVhZGVyLlJlc3VsdFBhZ2VIZWFkZXI7CiAgICB9Cn0pOwoKdmFyIF9pbmRleCA9IHJlcXVpcmUoJy4vY2FwYWJpbGl0eS9pbmRleCcpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdjYXBhYmxlJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfaW5kZXguY2FwYWJsZTsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnY2FwYWJpbGl0eVN0b3JlJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfaW5kZXguY2FwYWJpbGl0eVN0b3JlOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdjYXBhYmlsaXR5QXVnbWVudGVyJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfaW5kZXguY2FwYWJpbGl0eUF1Z21lbnRlcjsKICAgIH0KfSk7Cgp2YXIgX3NlcnZlckJyb3dzZXJUaW1lSGFybW9uaXplID0gcmVxdWlyZSgnLi91dGlscy9zZXJ2ZXJCcm93c2VyVGltZUhhcm1vbml6ZScpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdUaW1lTWFuYWdlcicsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX3NlcnZlckJyb3dzZXJUaW1lSGFybW9uaXplLlRpbWVNYW5hZ2VyOwogICAgfQp9KTsKCnZhciBfVGltZUhhcm1vbml6ZXIgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvVGltZUhhcm1vbml6ZXInKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnVGltZUhhcm1vbml6ZXInLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9UaW1lSGFybW9uaXplci5UaW1lSGFybW9uaXplcjsKICAgIH0KfSk7Cgp2YXIgX1VybFV0aWxzID0gcmVxdWlyZSgnLi91dGlscy9VcmxVdGlscycpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdidWlsZE9yZ2FuaXphdGlvblVybCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1VybFV0aWxzLmJ1aWxkT3JnYW5pemF0aW9uVXJsOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdidWlsZFBpcGVsaW5lVXJsJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfVXJsVXRpbHMuYnVpbGRQaXBlbGluZVVybDsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAncm9vdFBhdGgnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9VcmxVdGlscy5yb290UGF0aDsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnYnVpbGRDbGFzc2ljQ29uZmlnVXJsJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfVXJsVXRpbHMuYnVpbGRDbGFzc2ljQ29uZmlnVXJsOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdidWlsZENsYXNzaWNJbnB1dFVybCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1VybFV0aWxzLmJ1aWxkQ2xhc3NpY0lucHV0VXJsOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdidWlsZENsYXNzaWNCdWlsZFVybCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1VybFV0aWxzLmJ1aWxkQ2xhc3NpY0J1aWxkVXJsOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdidWlsZFJ1bkRldGFpbHNVcmwnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9VcmxVdGlscy5idWlsZFJ1bkRldGFpbHNVcmw7CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ2RvdWJsZVVyaUVuY29kZScsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1VybFV0aWxzLmRvdWJsZVVyaUVuY29kZTsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnZmV0Y2hBbGxTdWZmaXgnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9VcmxVdGlscy5mZXRjaEFsbFN1ZmZpeDsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnYXBwbHlGZXRjaEFsbCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1VybFV0aWxzLmFwcGx5RmV0Y2hBbGw7CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ2NhbGN1bGF0ZUZldGNoQWxsJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfVXJsVXRpbHMuY2FsY3VsYXRlRmV0Y2hBbGw7CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ2NhbGN1bGF0ZUxvZ1ZpZXcnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9VcmxVdGlscy5jYWxjdWxhdGVMb2dWaWV3OwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdjYWxjdWxhdGVMb2dVcmwnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9VcmxVdGlscy5jYWxjdWxhdGVMb2dVcmw7CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ2NhbGN1bGF0ZU5vZGVCYXNlVXJsJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfVXJsVXRpbHMuY2FsY3VsYXRlTm9kZUJhc2VVcmw7CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ2NhbGN1bGF0ZVN0ZXBzQmFzZVVybCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1VybFV0aWxzLmNhbGN1bGF0ZVN0ZXBzQmFzZVVybDsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnY2FsY3VsYXRlUnVuTG9nVVJMT2JqZWN0JywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfVXJsVXRpbHMuY2FsY3VsYXRlUnVuTG9nVVJMT2JqZWN0OwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdwYWdpbmF0ZVVybCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1VybFV0aWxzLnBhZ2luYXRlVXJsOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdlbmRTbGFzaCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1VybFV0aWxzLmVuZFNsYXNoOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdnZXRSZXN0VXJsJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfVXJsVXRpbHMuZ2V0UmVzdFVybDsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnYnVpbGRVcmwnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9VcmxVdGlscy5idWlsZFVybDsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAncmVsYXRpdmVVcmwnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9VcmxVdGlscy5yZWxhdGl2ZVVybDsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAndG9DbGFzc2ljSm9iUGFnZScsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1VybFV0aWxzLnRvQ2xhc3NpY0pvYlBhZ2U7CiAgICB9Cn0pOwoKdmFyIF9zc2VHYXRld2F5ID0gcmVxdWlyZSgnQGplbmtpbnMtY2Qvc3NlLWdhdGV3YXknKTsKCnZhciBzc2UgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfc3NlR2F0ZXdheSk7Cgp2YXIgX1J1bkFwaSA9IHJlcXVpcmUoJy4vcmVzdC9SdW5BcGknKTsKCnZhciBfU3NlQnVzID0gcmVxdWlyZSgnLi9zc2UvU3NlQnVzJyk7Cgp2YXIgX1RvYXN0U2VydmljZSA9IHJlcXVpcmUoJy4vVG9hc3RTZXJ2aWNlJyk7Cgp2YXIgX2kxOG4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaTE4bik7Cgp2YXIgX2xvZ2dpbmcyID0gcmVxdWlyZSgnLi9sb2dnaW5nJyk7Cgp2YXIgX2xvZ2dpbmczID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbG9nZ2luZzIpOwoKdmFyIF9Mb2FkaW5nSW5kaWNhdG9yID0gcmVxdWlyZSgnLi9Mb2FkaW5nSW5kaWNhdG9yJyk7Cgp2YXIgX0xvYWRpbmdJbmRpY2F0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTG9hZGluZ0luZGljYXRvcik7Cgp2YXIgX1VybEJ1aWxkZXIyID0gcmVxdWlyZSgnLi9VcmxCdWlsZGVyJyk7Cgp2YXIgX1VybEJ1aWxkZXIzID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXJsQnVpbGRlcjIpOwoKdmFyIF91cmxjb25maWcgPSByZXF1aXJlKCcuL3VybGNvbmZpZycpOwoKdmFyIF91cmxjb25maWcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdXJsY29uZmlnKTsKCnZhciBfand0ID0gcmVxdWlyZSgnLi9qd3QnKTsKCnZhciBfand0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2p3dCk7Cgp2YXIgX3Rlc3R1dGlscyA9IHJlcXVpcmUoJy4vdGVzdHV0aWxzJyk7Cgp2YXIgX3Rlc3R1dGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF90ZXN0dXRpbHMpOwoKdmFyIF9Ub2FzdFV0aWxzMiA9IHJlcXVpcmUoJy4vVG9hc3RVdGlscycpOwoKdmFyIF9Ub2FzdFV0aWxzMyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1RvYXN0VXRpbHMyKTsKCnZhciBfdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7Cgp2YXIgX3V0aWxzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3V0aWxzKTsKCnZhciBfY29uZmlnID0gcmVxdWlyZSgnLi9jb25maWcnKTsKCnZhciBfY29uZmlnMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2NvbmZpZyk7Cgp2YXIgX3NlY3VyaXR5ID0gcmVxdWlyZSgnLi9zZWN1cml0eScpOwoKdmFyIF9zZWN1cml0eTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zZWN1cml0eSk7Cgp2YXIgX2luZGV4MiA9IHJlcXVpcmUoJy4vcGF0aHMvaW5kZXgnKTsKCnZhciBfaW5kZXgzID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaW5kZXgyKTsKCnZhciBfaW5kZXg0ID0gcmVxdWlyZSgnLi9zZXJ2aWNlcy9pbmRleCcpOwoKdmFyIF9zdHJpbmdVdGlsID0gcmVxdWlyZSgnLi9zdHJpbmdVdGlsJyk7Cgp2YXIgc3RyaW5nVXRpbCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9zdHJpbmdVdGlsKTsKCnZhciBfRnVsbHNjcmVlbjIgPSByZXF1aXJlKCcuL0Z1bGxzY3JlZW4nKTsKCnZhciBfRnVsbHNjcmVlbjMgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9GdWxsc2NyZWVuMik7Cgp2YXIgX05vdEZvdW5kMiA9IHJlcXVpcmUoJy4vTm90Rm91bmQnKTsKCnZhciBfTm90Rm91bmQzID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTm90Rm91bmQyKTsKCnZhciBfTGl2ZVN0YXR1c0luZGljYXRvciA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9MaXZlU3RhdHVzSW5kaWNhdG9yJyk7Cgp2YXIgX0xpdmVTdGF0dXNJbmRpY2F0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTGl2ZVN0YXR1c0luZGljYXRvcik7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7IGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsgcmV0dXJuIG9iajsgfSBlbHNlIHsgdmFyIG5ld09iaiA9IHt9OyBpZiAob2JqICE9IG51bGwpIHsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsgfSB9IG5ld09iai5kZWZhdWx0ID0gb2JqOyByZXR1cm4gbmV3T2JqOyB9IH0KCi8qKgogKiBDcmVhdGVkIGJ5IGNtZXllcnMgb24gOC8xOC8xNi4KICovCgpleHBvcnRzLmkxOG5UcmFuc2xhdG9yID0gX2kxOG4yLmRlZmF1bHQ7CgovLyBleHBvcnQgaTE4biBwcm92aWRlcgoKZXhwb3J0cy5sb2dnaW5nID0gX2xvZ2dpbmczLmRlZmF1bHQ7CmV4cG9ydHMubG9hZGluZ0luZGljYXRvciA9IF9Mb2FkaW5nSW5kaWNhdG9yMi5kZWZhdWx0OwpleHBvcnRzLlVybEJ1aWxkZXIgPSBfVXJsQnVpbGRlcjMuZGVmYXVsdDsKZXhwb3J0cy5VcmxDb25maWcgPSBfdXJsY29uZmlnMi5kZWZhdWx0OwpleHBvcnRzLkpXVCA9IF9qd3QyLmRlZmF1bHQ7CmV4cG9ydHMuVGVzdFV0aWxzID0gX3Rlc3R1dGlsczIuZGVmYXVsdDsKZXhwb3J0cy5Ub2FzdFV0aWxzID0gX1RvYXN0VXRpbHMzLmRlZmF1bHQ7CmV4cG9ydHMuVXRpbHMgPSBfdXRpbHMyLmRlZmF1bHQ7CmV4cG9ydHMuQXBwQ29uZmlnID0gX2NvbmZpZzIuZGVmYXVsdDsKZXhwb3J0cy5TZWN1cml0eSA9IF9zZWN1cml0eTIuZGVmYXVsdDsKZXhwb3J0cy5QYXRocyA9IF9pbmRleDMuZGVmYXVsdDsKZXhwb3J0cy5QYWdlciA9IF9pbmRleDQuUGFnZXI7CmV4cG9ydHMuUGFnZXJTZXJ2aWNlID0gX2luZGV4NC5QYWdlclNlcnZpY2U7CmV4cG9ydHMuUGlwZWxpbmVTZXJ2aWNlID0gX2luZGV4NC5QaXBlbGluZVNlcnZpY2U7CmV4cG9ydHMuU1NFU2VydmljZSA9IF9pbmRleDQuU1NFU2VydmljZTsKZXhwb3J0cy5BY3Rpdml0eVNlcnZpY2UgPSBfaW5kZXg0LkFjdGl2aXR5U2VydmljZTsKZXhwb3J0cy5TdHJpbmdVdGlsID0gc3RyaW5nVXRpbDsKZXhwb3J0cy5GdWxsc2NyZWVuID0gX0Z1bGxzY3JlZW4zLmRlZmF1bHQ7CmV4cG9ydHMuTm90Rm91bmQgPSBfTm90Rm91bmQzLmRlZmF1bHQ7CgoKLy8gQ3JlYXRlIGFuZCBleHBvcnQgdGhlIFNTRSBjb25uZWN0aW9uIHRoYXQgd2lsbCBiZSBzaGFyZWQgYnkgb3RoZXIKLy8gQmx1ZSBPY2VhbiBjb21wb25lbnRzIHZpYSB0aGlzIHBhY2thZ2UuCnZhciBzc2VDb25uZWN0aW9uID0gZXhwb3J0cy5zc2VDb25uZWN0aW9uID0gc3NlLmNvbm5lY3QoJ2plbmtpbnMtYmx1ZW9jZWFuLWNvcmUtanMnKTsKCi8vIGV4cG9ydCBzZXJ2aWNlcyBhcyBhIHNpbmdsZXRvbiBzbyBhbGwgcGx1Z2lucyB3aWxsIHVzZSB0aGUgc2FtZSBpbnN0YW5jZQoKLy8gY2FwYWJpbGl0aWVzCgoKLy8gbGltaXQgdG8gc2luZ2xlIGluc3RhbmNlIHNvIHRoYXQgZHVwbGljYXRlIFJFU1QgY2FsbHMgYXJlbid0IG1hZGUgYXMgZXZlbnRzIGNvbWUgaW4KdmFyIHNzZUJ1cyA9IG5ldyBfU3NlQnVzLlNzZUJ1cyhzc2VDb25uZWN0aW9uLCBfZmV0Y2guRmV0Y2guZmV0Y2hKU09OKTsKZXhwb3J0cy5Tc2VCdXMgPSBzc2VCdXM7CgovLyByZXF1aXJlZCBzbyBuZXcgdG9hc3RzIGFyZSByb3V0ZWQgdG8gdGhlIGluc3RhbmNlIHVzZWQgaW4gYmx1ZW9jZWFuLXdlYgoKdmFyIHRvYXN0U2VydmljZSA9IG5ldyBfVG9hc3RTZXJ2aWNlLlRvYXN0U2VydmljZSgpOwpleHBvcnRzLlRvYXN0U2VydmljZSA9IHRvYXN0U2VydmljZTsKCgp2YXIgcnVuQXBpID0gbmV3IF9SdW5BcGkuUnVuQXBpKCk7CmV4cG9ydHMuUnVuQXBpID0gcnVuQXBpOwp2YXIgcGFnZXJTZXJ2aWNlID0gZXhwb3J0cy5wYWdlclNlcnZpY2UgPSBuZXcgX2luZGV4NC5QYWdlclNlcnZpY2UoKTsKdmFyIHNzZVNlcnZpY2UgPSBleHBvcnRzLnNzZVNlcnZpY2UgPSBuZXcgX2luZGV4NC5TU0VTZXJ2aWNlKHNzZUNvbm5lY3Rpb24pOwp2YXIgYWN0aXZpdHlTZXJ2aWNlID0gZXhwb3J0cy5hY3Rpdml0eVNlcnZpY2UgPSBuZXcgX2luZGV4NC5BY3Rpdml0eVNlcnZpY2UocGFnZXJTZXJ2aWNlKTsKdmFyIHBpcGVsaW5lU2VydmljZSA9IGV4cG9ydHMucGlwZWxpbmVTZXJ2aWNlID0gbmV3IF9pbmRleDQuUGlwZWxpbmVTZXJ2aWNlKHBhZ2VyU2VydmljZSwgYWN0aXZpdHlTZXJ2aWNlKTsKdmFyIGxvY2F0aW9uU2VydmljZSA9IGV4cG9ydHMubG9jYXRpb25TZXJ2aWNlID0gbmV3IF9pbmRleDQuTG9jYXRpb25TZXJ2aWNlKCk7Cgp2YXIgZGVmYXVsdFNTRWhhbmRsZXIgPSBuZXcgX2luZGV4NC5EZWZhdWx0U1NFSGFuZGxlcihwaXBlbGluZVNlcnZpY2UsIGFjdGl2aXR5U2VydmljZSwgcGFnZXJTZXJ2aWNlKTsKc3NlU2VydmljZS5yZWdpc3RlckhhbmRsZXIoZGVmYXVsdFNTRWhhbmRsZXIuaGFuZGxlRXZlbnRzKTsKCi8vIEV4cG9ydCBzb21lIGRlYnVnZ2luZyBzdHVmZiBjbGllbnQgY29kZSBtYXkgbmVlZAoKdmFyIERFQlVHID0gZXhwb3J0cy5ERUJVRyA9IHsKICAgIGVuYWJsZU1vY2tzRm9ySTE4bjogX2kxOG4uZW5hYmxlTW9ja3NGb3JJMThuLAogICAgZGlzYWJsZU1vY2tzRm9ySTE4bjogX2kxOG4uZGlzYWJsZU1vY2tzRm9ySTE4bgp9OwoKZXhwb3J0cy5MaXZlU3RhdHVzSW5kaWNhdG9yID0gX0xpdmVTdGF0dXNJbmRpY2F0b3IyLmRlZmF1bHQ7Cn0seyIuL0Z1bGxzY3JlZW4iOjEsIi4vTG9hZGluZ0luZGljYXRvciI6MiwiLi9Ob3RGb3VuZCI6MywiLi9Ub2FzdFNlcnZpY2UiOjQsIi4vVG9hc3RVdGlscyI6NSwiLi9VcmxCdWlsZGVyIjo2LCIuL1VzZXIiOjcsIi4vY2FwYWJpbGl0eS9pbmRleCI6MTIsIi4vY29tcG9uZW50cy9CbHVlTG9nbyI6MTMsIi4vY29tcG9uZW50cy9Db250ZW50UGFnZUhlYWRlciI6MTQsIi4vY29tcG9uZW50cy9MaXZlU3RhdHVzSW5kaWNhdG9yIjoxNSwiLi9jb21wb25lbnRzL1JlcGxheUJ1dHRvbiI6MTYsIi4vY29tcG9uZW50cy9SZXN1bHRQYWdlSGVhZGVyIjoxNywiLi9jb21wb25lbnRzL1J1bkJ1dHRvbiI6MTgsIi4vY29tcG9uZW50cy9TaG93TW9yZUJ1dHRvbiI6MTksIi4vY29tcG9uZW50cy9UaW1lSGFybW9uaXplciI6MjAsIi4vY29uZmlnIjoyMSwiLi9mZXRjaCI6MjIsIi4vaTE4bi9pMThuIjoyNCwiLi9qd3QiOjI2LCIuL2xvZ2dpbmciOjI3LCIuL3BhcmFtZXRlciI6MzUsIi4vcGF0aHMvaW5kZXgiOjQwLCIuL3Jlc3QvUnVuQXBpIjo0MiwiLi9zZWN1cml0eSI6NDQsIi4vc2VydmljZXMvaW5kZXgiOjUzLCIuL3NzZS9Tc2VCdXMiOjU0LCIuL3N0cmluZ1V0aWwiOjU2LCIuL3Rlc3R1dGlscyI6NTcsIi4vdXJsY29uZmlnIjo1OCwiLi91dGlscyI6NTksIi4vdXRpbHMvVXJsVXRpbHMiOjYwLCIuL3V0aWxzL3NlcnZlckJyb3dzZXJUaW1lSGFybW9uaXplIjo2MiwiQGplbmtpbnMtY2Qvc3NlLWdhdGV3YXkiOjEzM31dLDI2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX2VzNlByb21pc2UgPSByZXF1aXJlKCdlczYtcHJvbWlzZScpOwoKdmFyIF9lczZQcm9taXNlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2VzNlByb21pc2UpOwoKdmFyIF9pc29tb3JwaGljRmV0Y2ggPSByZXF1aXJlKCdpc29tb3JwaGljLWZldGNoJyk7Cgp2YXIgX2lzb21vcnBoaWNGZXRjaDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc29tb3JwaGljRmV0Y2gpOwoKdmFyIF9qc29ud2VidG9rZW4gPSByZXF1aXJlKCdqc29ud2VidG9rZW4nKTsKCnZhciBfanNvbndlYnRva2VuMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2pzb253ZWJ0b2tlbik7Cgp2YXIgX3VybGNvbmZpZyA9IHJlcXVpcmUoJy4vdXJsY29uZmlnJyk7Cgp2YXIgX2ZldGNoID0gcmVxdWlyZSgnLi9mZXRjaCcpOwoKdmFyIF9wZW1Kd2sgPSByZXF1aXJlKCdwZW0tandrJyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKX2VzNlByb21pc2UyLmRlZmF1bHQucG9seWZpbGwoKTsKCnZhciBzdG9yZWRUb2tlbiA9IG51bGw7CnZhciBwdWJsaWNLZXlTdG9yZSA9IG51bGw7CnZhciB0b2tlbkZldGNoUHJvbWlzZSA9IG51bGw7Cgp2YXIgQ0xPQ0tfU0tFV19TRUNPTkRTID0gNjA7CmV4cG9ydHMuZGVmYXVsdCA9IHsKICAgIC8qKgogICAgICogRmV0Y2hlcyB0aGUgSldUIHRva2VuLiBUaGlzIHRva2VuIGlzIGNhY2hlZCBmb3IgYSBkZWZhdWx0IG9mIDI1bWlucy4KICAgICAqIElmIGl0IGlzIHdpdGhpbiA1bWlucyBvciBleHBpcnkgaXQgd2lsbCBmZXRjaCBhIG5ldyBvbmUuCiAgICAgKi8KICAgIGZldGNoSldUOiBmdW5jdGlvbiBmZXRjaEpXVCgpIHsKICAgICAgICBpZiAoc3RvcmVkVG9rZW4gJiYgc3RvcmVkVG9rZW4uZXhwKSB7CiAgICAgICAgICAgIHZhciBkaWZmID0gc3RvcmVkVG9rZW4uZXhwIC0gTWF0aC50cnVuYyhuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApOwoKICAgICAgICAgICAgLy8gcmVmZXRjaCB0b2tlbiBpZiB3ZSBhcmUgd2l0aGluIDYwcyBvZiBpdCBleHAKICAgICAgICAgICAgaWYgKGRpZmYgPCBDTE9DS19TS0VXX1NFQ09ORFMpIHsKICAgICAgICAgICAgICAgIHRva2VuRmV0Y2hQcm9taXNlID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCF0b2tlbkZldGNoUHJvbWlzZSkgewogICAgICAgICAgICB0b2tlbkZldGNoUHJvbWlzZSA9ICgwLCBfaXNvbW9ycGhpY0ZldGNoMi5kZWZhdWx0KShfdXJsY29uZmlnLkJsdWVVcmwuZ2V0SmVua2luc1Jvb3RVUkwoKSArICcvand0LWF1dGgvdG9rZW4nLCB7IGNyZWRlbnRpYWxzOiAnc2FtZS1vcmlnaW4nIH0pLnRoZW4odGhpcy5jaGVja1N0YXR1cykudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHsKICAgICAgICAgICAgICAgIHZhciB0b2tlbiA9IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdYLUJMVUVPQ0VBTi1KV1QnKTsKICAgICAgICAgICAgICAgIGlmICh0b2tlbikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0b2tlbjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBmZXRjaCBqd3RfdG9rZW4nKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdG9rZW5GZXRjaFByb21pc2U7CiAgICB9LAoKCiAgICAvKioKICAgICAqIFZlcmlmaWVzIHRoZSB0b2tlbiB1c2luZyB0aGUgcHVibGljIGtleS4KICAgICAqLwogICAgdmVyaWZ5VG9rZW46IGZ1bmN0aW9uIHZlcmlmeVRva2VuKHRva2VuLCBjZXJ0T2JqZWN0KSB7CiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsKICAgICAgICAgICAgcmV0dXJuIF9qc29ud2VidG9rZW4yLmRlZmF1bHQudmVyaWZ5KHRva2VuLCAoMCwgX3BlbUp3ay5qd2sycGVtKShjZXJ0T2JqZWN0KSwgeyBhbGdvcml0aG1zOiBbY2VydE9iamVjdC5hbGddLCBjbG9ja1RvbGVyYW5jZTogQ0xPQ0tfU0tFV19TRUNPTkRTIH0sIGZ1bmN0aW9uIChlcnIsIHBheWxvYWQpIHsKICAgICAgICAgICAgICAgIGlmIChlcnIpIHsKICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShwYXlsb2FkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfSk7CiAgICB9LAoKCiAgICAvKioKICAgICAqIEZldGNoZXMgdGhlIHB1YmxpYyBrZXkgdGhhdCBpcyB1c2VkIHRvIHZlcmlmeSB0b2tlbnMuCiAgICAgKi8KICAgIGZldGNoSldUUHVibGljS2V5OiBmdW5jdGlvbiBmZXRjaEpXVFB1YmxpY0tleSh0b2tlbikgewogICAgICAgIHZhciBfdGhpcyA9IHRoaXM7CgogICAgICAgIHZhciBkZWNvZGVkID0gX2pzb253ZWJ0b2tlbjIuZGVmYXVsdC5kZWNvZGUodG9rZW4sIHsgY29tcGxldGU6IHRydWUgfSk7CiAgICAgICAgdmFyIHVybCA9IF91cmxjb25maWcuQmx1ZVVybC5nZXRKZW5raW5zUm9vdFVSTCgpICsgJy9qd3QtYXV0aC9qd2tzLycgKyBkZWNvZGVkLmhlYWRlci5raWQgKyAnLyc7CiAgICAgICAgaWYgKCFwdWJsaWNLZXlTdG9yZSkgewogICAgICAgICAgICBwdWJsaWNLZXlTdG9yZSA9ICgwLCBfaXNvbW9ycGhpY0ZldGNoMi5kZWZhdWx0KSh1cmwsIHsgY3JlZGVudGlhbHM6ICdzYW1lLW9yaWdpbicgfSkudGhlbihfZmV0Y2guRmV0Y2hGdW5jdGlvbnMuY2hlY2tTdGF0dXMpLnRoZW4oX2ZldGNoLkZldGNoRnVuY3Rpb25zLnBhcnNlSlNPTikudGhlbihmdW5jdGlvbiAoY2VydCkgewogICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLnZlcmlmeVRva2VuKHRva2VuLCBjZXJ0KS50aGVuKGZ1bmN0aW9uIChwYXlsb2FkKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW46IHRva2VuLAogICAgICAgICAgICAgICAgICAgICAgICBwYXlsb2FkOiBwYXlsb2FkCiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwdWJsaWNLZXlTdG9yZTsKICAgIH0sCgoKICAgIC8qKgogICAgICogUHV0cyB0aGUgdG9rZW4gaW50byBnbG9iYWwgc3RvcmFnZSBmb3IgbGF0ZXIgdXNlLgogICAgICovCiAgICBzdG9yZVRva2VuOiBmdW5jdGlvbiBzdG9yZVRva2VuKGRhdGEpIHsKICAgICAgICBzdG9yZWRUb2tlbiA9IGRhdGEucGF5bG9hZDsKICAgICAgICByZXR1cm4gZGF0YTsKICAgIH0sCgoKICAgIC8qKgogICAgICogVXNlIHRoaXMgZnVuY3Rpb24gaWYgeW91IHdhbnQgdGhlIHBheWxvYWQgZnJvbSB0aGUgdG9rZW4uCiAgICAgKi8KICAgIGdldFRva2VuV2l0aFBheWxvYWQ6IGZ1bmN0aW9uIGdldFRva2VuV2l0aFBheWxvYWQoKSB7CiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7CgogICAgICAgIHJldHVybiB0aGlzLmZldGNoSldUKCkudGhlbihfZmV0Y2guRmV0Y2hGdW5jdGlvbnMuY2hlY2tTdGF0dXMpLnRoZW4oZnVuY3Rpb24gKHRva2VuKSB7CiAgICAgICAgICAgIHJldHVybiBfdGhpczIuZmV0Y2hKV1RQdWJsaWNLZXkodG9rZW4pOwogICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHsKICAgICAgICAgICAgcmV0dXJuIF90aGlzMi5zdG9yZVRva2VuKGRhdGEpOwogICAgICAgIH0pOwogICAgfSwKCgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSB0b2tlbiBmcm9tIHRlIHNlcnZlciBhbmQgdmVyaWZpZXMgaXQuCiAgICAgKi8KICAgIGdldFRva2VuOiBmdW5jdGlvbiBnZXRUb2tlbigpIHsKICAgICAgICByZXR1cm4gdGhpcy5nZXRUb2tlbldpdGhQYXlsb2FkKCkudGhlbihmdW5jdGlvbiAodG9rZW4pIHsKICAgICAgICAgICAgcmV0dXJuIHRva2VuLnRva2VuOwogICAgICAgIH0pOwogICAgfQp9Owp9LHsiLi9mZXRjaCI6MjIsIi4vdXJsY29uZmlnIjo1OCwiZXM2LXByb21pc2UiOjIzMiwiaXNvbW9ycGhpYy1mZXRjaCI6MzI5LCJqc29ud2VidG9rZW4iOjM0OCwicGVtLWp3ayI6NDE4fV0sMjc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX2xvZ2dpbmcgPSByZXF1aXJlKCdAamVua2lucy1jZC9sb2dnaW5nJyk7Cgp2YXIgbG9nZ2luZyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9sb2dnaW5nKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKG9iaikgeyBpZiAob2JqICYmIG9iai5fX2VzTW9kdWxlKSB7IHJldHVybiBvYmo7IH0gZWxzZSB7IHZhciBuZXdPYmogPSB7fTsgaWYgKG9iaiAhPSBudWxsKSB7IGZvciAodmFyIGtleSBpbiBvYmopIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIG5ld09ialtrZXldID0gb2JqW2tleV07IH0gfSBuZXdPYmouZGVmYXVsdCA9IG9iajsgcmV0dXJuIG5ld09iajsgfSB9CgpleHBvcnRzLmRlZmF1bHQgPSBsb2dnaW5nOwp9LHsiQGplbmtpbnMtY2QvbG9nZ2luZyI6MTI4fV0sMjg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5QYXJhbWV0ZXJzUnVuQnV0dG9uID0gdW5kZWZpbmVkOwoKdmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfZGVzaWduTGFuZ3VhZ2UgPSByZXF1aXJlKCdAamVua2lucy1jZC9kZXNpZ24tbGFuZ3VhZ2UnKTsKCnZhciBfcmVhY3RSZW1hcmthYmxlID0gcmVxdWlyZSgncmVhY3QtcmVtYXJrYWJsZScpOwoKdmFyIF9yZWFjdFJlbWFya2FibGUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3RSZW1hcmthYmxlKTsKCnZhciBfaW5kZXggPSByZXF1aXJlKCcuLi9pbmRleCcpOwoKdmFyIF9pMThuID0gcmVxdWlyZSgnLi4vaTE4bi9pMThuJyk7Cgp2YXIgX2kxOG4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaTE4bik7Cgp2YXIgX2luZGV4MiA9IHJlcXVpcmUoJy4vaW5kZXgnKTsKCnZhciBfbG9nZ2luZyA9IHJlcXVpcmUoJy4uL2xvZ2dpbmcnKTsKCnZhciBfbG9nZ2luZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9sb2dnaW5nKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0KCnZhciBsb2dnZXIgPSBfbG9nZ2luZzIuZGVmYXVsdC5sb2dnZXIoJ2lvLmplbmtpbnMuYmx1ZW9jZWFuLmNvcmUuUGFyYW1ldGVyc1J1bkJ1dHRvbicpOwoKLyoqCiAqIFRyYW5zbGF0ZSBmdW5jdGlvbgogKi8KdmFyIHQgPSAoMCwgX2kxOG4yLmRlZmF1bHQpKCdibHVlb2NlYW4td2ViJyk7CnZhciBNVUxUSUJSQU5DSF9QSVBFTElORSA9ICdpby5qZW5raW5zLmJsdWVvY2Vhbi5yZXN0Lm1vZGVsLkJsdWVNdWx0aUJyYW5jaFBpcGVsaW5lJzsKLyoqCiAqIENyZWF0aW5nIGEgIjxmb3JtLz4ibGVzcyBmb3JtIHRvIHN1Ym1pdCB0aGUgYnVpbGQgcGFyYW1ldGVycyByZXF1ZXN0ZWQgYnkgdGhlIHVzZXIgZm9yIGEgcGFyYW1ldHJpc2VkIGpvYi4uCiAqCiAqIFdlIGtlZXAgYWxsIGZvcm0gZGF0YSBpbiB0aGUgUGFyYW1ldGVyU2VydmljZSBhbmQgY2hhbmdlIHRoZW0gb25DaGFuZ2UgYW5kIG9uVG9nZ2xlIChkZXBlbmRpbmcgb2YgdGhlIHBhcmFtZXRlcgogKiB0eXBlKS4gV2UgbWF0Y2ggdGhlIGRpZmZlcmVudCBzdXBwb3J0ZWQgaW5wdXRUeXBlcyB3aXRoIGEgbWFwcGluZyBmdW5jdGlvbnMKICogQHNlZSBzdXBwb3J0ZWRJbnB1dFR5cGVzTWFwcGluZwogKiBUaGF0IG1hcHBpbmcgZGVsZWdhdGVzIHRvIHRoZSBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbiB3aGVyZSB3ZSBmdXJ0aGVyIGRlbGVnYXRlIHRvIEpETCBjb21wb25lbnRzLgogKiBJbiBjYXNlIHlvdSB3YW50IHRvIHJlZ2lzdGVyIGEgbmV3IG1hcHBpbmcgeW91IG5lZWQgdG8gZWRpdCAnLi9wYXJhbWV0ZXIvaW5kZXgnIHRvIGFkZCBhIG5ldyBtYXBwaW5nCiAqIGFuZCBmdXJ0aGVyIGluICcuL3BhcmFtZXRlci9jb21tb25Qcm9wdHlwZXMnIHlvdSBuZWVkIHRvIGluY2x1ZGUgdGhlIG5ldyB0eXBlIGluIHRoZSBvbmVPZiBhcnJheS4KICovCgp2YXIgUGFyYW1ldGVyc1J1bkJ1dHRvbiA9IGV4cG9ydHMuUGFyYW1ldGVyc1J1bkJ1dHRvbiA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoUGFyYW1ldGVyc1J1bkJ1dHRvbiwgX0NvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gUGFyYW1ldGVyc1J1bkJ1dHRvbihwcm9wcykgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQYXJhbWV0ZXJzUnVuQnV0dG9uKTsKCiAgICAgICAgdmFyIF90aGlzID0gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKFBhcmFtZXRlcnNSdW5CdXR0b24uX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihQYXJhbWV0ZXJzUnVuQnV0dG9uKSkuY2FsbCh0aGlzLCBwcm9wcykpOwoKICAgICAgICBfdGhpcy5zdGF0ZSA9IHt9OwoKICAgICAgICBpZiAocHJvcHMucnVubmFibGUgJiYgcHJvcHMucnVubmFibGUucGFyYW1ldGVycykgewogICAgICAgICAgICB2YXIgcGFyYW1ldGVycyA9IHByb3BzLnJ1bm5hYmxlLnBhcmFtZXRlcnM7CgogICAgICAgICAgICBfdGhpcy5wYXJhbWV0ZXJTZXJ2aWNlID0gbmV3IF9pbmRleDIuUGFyYW1ldGVyU2VydmljZSgpOwogICAgICAgICAgICBfdGhpcy5wYXJhbWV0ZXJTZXJ2aWNlLmluaXQocGFyYW1ldGVycyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3RoaXMucGFyYW1ldGVyU2VydmljZSA9IHsgcGFyYW1ldGVyczogW10gfTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIF90aGlzOwogICAgfQogICAgLy8gd2Ugc3RhcnQgd2l0aCBhbiBlbXB0eSBzdGF0ZQoKCiAgICBfY3JlYXRlQ2xhc3MoUGFyYW1ldGVyc1J1bkJ1dHRvbiwgW3sKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsTW91bnQnLAoKICAgICAgICAvKioKICAgICAgICAgKiByZWFjdCBsaWZlIGN5Y2xlIG1hcHBlciB0byBpbnZva2UgdGhlIGNyZWF0aW9uIG9mIHRoZSBmb3JtIHN0YXRlCiAgICAgICAgICovCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxNb3VudCgpIHsKICAgICAgICAgICAgdGhpcy5jcmVhdGVGb3JtU3RhdGUodGhpcy5wcm9wcyk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIHJlYWN0IGxpZmUgY3ljbGUgbWFwcGVyIHRvIGludm9rZSB0aGUgdXBkYXRlIG9mIHRoZSBzZXJ2aWNlCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykgewogICAgICAgICAgICBpZiAobmV4dFByb3BzLnJ1bm5hYmxlICYmIG5leHRQcm9wcy5ydW5uYWJsZS5wYXJhbWV0ZXJzICYmIHRoaXMucHJvcHMucnVubmFibGUgJiYgdGhpcy5wcm9wcy5ydW5uYWJsZS5wYXJhbWV0ZXJzICYmIG5leHRQcm9wcy5ydW5uYWJsZS5wYXJhbWV0ZXJzICE9PSB0aGlzLnByb3BzLnJ1bm5hYmxlLnBhcmFtZXRlcnMpIHsKICAgICAgICAgICAgICAgIHRoaXMucGFyYW1ldGVyU2VydmljZS5pbml0KG5leHRQcm9wcy5ydW5uYWJsZS5wYXJhbWV0ZXJzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGUgc29tZSBpbmZvcm1hdGlvbiBmb3IgZm9ybSBoYW5kbGluZwogICAgICAgICAqIEBwYXJhbSBwcm9wcwogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdjcmVhdGVGb3JtU3RhdGUnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjcmVhdGVGb3JtU3RhdGUocHJvcHMpIHsKICAgICAgICAgICAgdmFyIHJ1bm5hYmxlID0gcHJvcHMucnVubmFibGU7CgogICAgICAgICAgICBpZiAocnVubmFibGUpIHsKICAgICAgICAgICAgICAgIHZhciBfY29udGV4dCRjb25maWcgPSB0aGlzLmNvbnRleHQuY29uZmlnLAogICAgICAgICAgICAgICAgICAgIGNvbmZpZyA9IF9jb250ZXh0JGNvbmZpZyA9PT0gdW5kZWZpbmVkID8ge30gOiBfY29udGV4dCRjb25maWc7CiAgICAgICAgICAgICAgICB2YXIgaHJlZiA9IHJ1bm5hYmxlLl9saW5rcy5zZWxmLmhyZWY7CgogICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7CiAgICAgICAgICAgICAgICAgICAgaHJlZjogJycgKyBjb25maWcuX3Jvb3RVUkwgKyBocmVmICsgJy9ydW5zLycsCiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIEhpZGUgdGhlIGRpYWxvZyAvIFN1Ym1pdCB0aGUgZm9ybSBhcyAiY2FuY2VsIgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdoaWRlJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gaGlkZSgpIHsKICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHZpc2libGU6IGZhbHNlIH0pOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiBTaG93IHRoZSBkaWFsb2cKICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnc2hvdycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNob3coKSB7CiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyB2aXNpYmxlOiB0cnVlIH0pOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiBTdWJtaXQgdGhlIGZvcm0gb3V0IG9mIHRoZSBkYXRhIHBhcmFtZXRlcnMgYW5kIGNyZWF0ZSBhIFRvYXN0CiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ2luaXRpYWxpemVCdWlsZCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGluaXRpYWxpemVCdWlsZCgpIHsKICAgICAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7CgogICAgICAgICAgICB2YXIgcGFyYW1ldGVycyA9IHRoaXMucGFyYW1ldGVyU2VydmljZS5wYXJhbWV0ZXJzVG9TdWJtaXRBcnJheSgpOwogICAgICAgICAgICBfaW5kZXgyLlBhcmFtZXRlckFwaS5zdGFydFJ1bldpdGhQYXJhbWV0ZXJzKHRoaXMuc3RhdGUuaHJlZiwgcGFyYW1ldGVycykudGhlbihmdW5jdGlvbiAocnVuSW5mbykgewogICAgICAgICAgICAgICAgX2luZGV4LlRvYXN0VXRpbHMuY3JlYXRlUnVuU3RhcnRlZFRvYXN0KF90aGlzMi5wcm9wcy5ydW5uYWJsZSwgcnVuSW5mbywgX3RoaXMyLnByb3BzLm9uTmF2aWdhdGlvbik7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICByZXR1cm4gdGhpcy5oaWRlKCk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgdmFyIF90aGlzMyA9IHRoaXM7CgogICAgICAgICAgICB2YXIgcGFyYW1ldGVycyA9IHRoaXMucGFyYW1ldGVyU2VydmljZS5wYXJhbWV0ZXJzOwoKICAgICAgICAgICAgLy8gQ2FwdGlvbnMKCiAgICAgICAgICAgIHZhciBtZXNzYWdlID0gdCgncGFyYW1ldHJpc2VkLnBpcGVsaW5lLmhlYWRlcicsIHsgZGVmYXVsdFZhbHVlOiAnSW5wdXQgcmVxdWlyZWQnIH0pOwogICAgICAgICAgICB2YXIgb2sgPSB0KCdwYXJhbWV0cmlzZWQucGlwZWxpbmUuc3VibWl0JywgeyBkZWZhdWx0VmFsdWU6ICdSdW4nIH0pOwogICAgICAgICAgICB2YXIgY2FuY2VsQ2FwdGlvbiA9IHQoJ3BhcmFtZXRyaXNlZC5waXBlbGluZS5jYW5jZWwnLCB7IGRlZmF1bHRWYWx1ZTogJ0NhbmNlbCcgfSk7CiAgICAgICAgICAgIC8vIGJ1dHRvbnMKICAgICAgICAgICAgdmFyIGNhbmNlbEJ1dHRvbiA9IF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2J1dHRvbicsCiAgICAgICAgICAgICAgICB7IHRpdGxlOiBjYW5jZWxDYXB0aW9uLCBvbkNsaWNrOiBmdW5jdGlvbiBvbkNsaWNrKCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMzLmhpZGUoKTsKICAgICAgICAgICAgICAgICAgICB9LCBjbGFzc05hbWU6ICdidG4gaW5wdXRTdGVwQ2FuY2VsIHJ1bi1idXR0b24gYnRuLXNlY29uZGFyeScgfSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICdzcGFuJywKICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2J1dHRvbi1sYWJlbCcgfSwKICAgICAgICAgICAgICAgICAgICBjYW5jZWxDYXB0aW9uCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHZhciBva0J1dHRvbiA9IF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2J1dHRvbicsCiAgICAgICAgICAgICAgICB7IHRpdGxlOiBvaywgb25DbGljazogZnVuY3Rpb24gb25DbGljaygpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzMy5pbml0aWFsaXplQnVpbGQoKTsKICAgICAgICAgICAgICAgICAgICB9LCBjbGFzc05hbWU6ICdidG4gaW5wdXRTdGVwU3VibWl0JyB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLAogICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnYnV0dG9uLWxhYmVsJyB9LAogICAgICAgICAgICAgICAgICAgIG9rCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIC8vIGNvbW1vbiBydW4gcHJvcGVydGllcwogICAgICAgICAgICB2YXIgcnVuQnV0dG9uUHJvcHMgPSBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcyk7CiAgICAgICAgICAgIC8vIHdoZW4gd2UgaGF2ZSBidWlsZCBwYXJhbWV0ZXJzIHdlIG5lZWQgdG8gc2hvdyB0aGVtIGJlZm9yZSB0cmlnZ2VyIGEgYnVpbGQKICAgICAgICAgICAgaWYgKHBhcmFtZXRlcnMubGVuZ3RoID4gMCAmJiBydW5CdXR0b25Qcm9wcy5idXR0b25UeXBlICE9PSAnc3RvcC1vbmx5JykgewogICAgICAgICAgICAgICAgcnVuQnV0dG9uUHJvcHMub25DbGljayA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICBfdGhpczMuc2hvdygpOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgaXNNdWx0aUJyYW5jaCA9ICgwLCBfaW5kZXguY2FwYWJsZSkodGhpcy5wcm9wcy5ydW5uYWJsZSwgTVVMVElCUkFOQ0hfUElQRUxJTkUpOwogICAgICAgICAgICB2YXIgcGlwZSA9IHsgZnVsbE5hbWU6IHRoaXMucHJvcHMucnVubmFibGUuZnVsbE5hbWUgfTsKICAgICAgICAgICAgaWYgKGlzTXVsdGlCcmFuY2gpIHsKICAgICAgICAgICAgICAgIHBpcGUuZnVsbE5hbWUgKz0gJy8nICsgcGlwZS5icmFuY2g7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGNsYXNzaWNCdWlsZFVybCA9ICgwLCBfaW5kZXguYnVpbGRDbGFzc2ljQnVpbGRVcmwpKHBpcGUpOwogICAgICAgICAgICB2YXIgc2FuaXR5ID0gcGFyYW1ldGVycy5maWx0ZXIoZnVuY3Rpb24gKHBhcmFtZXRlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIF9pbmRleDIuc3VwcG9ydGVkSW5wdXRUeXBlc01hcHBpbmdbcGFyYW1ldGVyLnR5cGVdICE9PSB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBsb2dnZXIuZGVidWcoJ3NhbmU/Jywgc2FuaXR5Lmxlbmd0aCA9PT0gcGFyYW1ldGVycy5sZW5ndGgsICdjbGFzc2ljQnVpbGRVcmw6ICcsIGNsYXNzaWNCdWlsZFVybCk7CiAgICAgICAgICAgIHZhciBkaWFsb2cgPSB2b2lkIDA7CiAgICAgICAgICAgIGlmIChzYW5pdHkubGVuZ3RoICE9PSBwYXJhbWV0ZXJzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdzYW5pdHkgY2hlY2sgZmFpbGVkLiBSZXR1cm5pbmcgQWxlcnQgaW5zdGVhZCBvZiB0aGUgZm9ybS4nKTsKICAgICAgICAgICAgICAgIHZhciBhbGVydENhcHRpb24gPSBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICBfcmVhY3RSZW1hcmthYmxlMi5kZWZhdWx0LAogICAgICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAgICAgdCgnaW5wdXRQYXJhbWV0ZXIuZXJyb3IubWVzc2FnZScsIHsKICAgICAgICAgICAgICAgICAgICAgICAgMDogY2xhc3NpY0J1aWxkVXJsLAogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWU6ICdUaGlzIHBpcGVsaW5lIHVzZXMgaW5wdXQgdHlwZXMgdGhhdCBhcmUgdW5zdXBwb3J0ZWQuIFVzZSBbSmVua2lucyBDbGFzc2ljXSh7MH0pIHRvIHJlc29sdmUgcGFyYW1ldHJpemVkIGJ1aWxkJwogICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgdmFyIGFsZXJ0VGl0bGUgPSB0KCdpbnB1dFBhcmFtZXRlci5lcnJvci50aXRsZScsIHsgZGVmYXVsdFZhbHVlOiAnRXJyb3InIH0pOwogICAgICAgICAgICAgICAgZGlhbG9nID0gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgX2Rlc2lnbkxhbmd1YWdlLkRpYWxvZywKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9uRGlzbWlzczogdGhpcy5oaWRlLmJpbmQodGhpcyksCiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBtZXNzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICdEaWFsb2ctLWlucHV0JwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoX2Rlc2lnbkxhbmd1YWdlLkFsZXJ0cywgeyBtZXNzYWdlOiBhbGVydENhcHRpb24sIHR5cGU6ICdFcnJvcicsIHRpdGxlOiBhbGVydFRpdGxlIH0pCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZGlhbG9nID0gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgX2Rlc2lnbkxhbmd1YWdlLkRpYWxvZywKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbnM6IFtva0J1dHRvbiwgY2FuY2VsQnV0dG9uXSwKICAgICAgICAgICAgICAgICAgICAgICAgb25EaXNtaXNzOiB0aGlzLmhpZGUuYmluZCh0aGlzKSwKICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IG1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ0RpYWxvZy0taW5wdXQnCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChfaW5kZXgyLlBhcmFtZXRlcnNSZW5kZXIsIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyczogcGFyYW1ldGVycywKICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U6IGZ1bmN0aW9uIG9uQ2hhbmdlKGluZGV4LCBuZXdWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzMy5wYXJhbWV0ZXJTZXJ2aWNlLmNoYW5nZVBhcmFtZXRlcihpbmRleCwgbmV3VmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoX2luZGV4LlJ1bkJ1dHRvbkJhc2UsIHJ1bkJ1dHRvblByb3BzKSwKICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUudmlzaWJsZSAmJiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2lucHV0UGFyYW1ldGVycycgfSwKICAgICAgICAgICAgICAgICAgICBkaWFsb2cKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFBhcmFtZXRlcnNSdW5CdXR0b247Cn0oX3JlYWN0LkNvbXBvbmVudCk7Cgp2YXIgYm9vbCA9IF9yZWFjdC5Qcm9wVHlwZXMuYm9vbCwKICAgIGZ1bmMgPSBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsCiAgICBvYmplY3QgPSBfcmVhY3QuUHJvcFR5cGVzLm9iamVjdCwKICAgIG9uZU9mID0gX3JlYWN0LlByb3BUeXBlcy5vbmVPZiwKICAgIHN0cmluZyA9IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nOwoKClBhcmFtZXRlcnNSdW5CdXR0b24ucHJvcFR5cGVzID0gewogICAgdmlzaWJsZTogYm9vbCwKICAgIG9uTmF2aWdhdGlvbjogZnVuYywKICAgIHJ1bm5hYmxlOiBvYmplY3QsCiAgICBsYXRlc3RSdW46IG9iamVjdCwKICAgIGJ1dHRvblR5cGU6IG9uZU9mKFsndG9nZ2xlJywgJ3N0b3Atb25seScsICdydW4tb25seSddKSwKICAgIGNsYXNzTmFtZTogc3RyaW5nLAogICAgb25DbGljazogZnVuYywKICAgIHJ1blRleHQ6IHN0cmluZywKICAgIGlubmVyQnV0dG9uQ2xhc3Nlczogc3RyaW5nCn07CgpQYXJhbWV0ZXJzUnVuQnV0dG9uLmNvbnRleHRUeXBlcyA9IHsKICAgIGNvbmZpZzogb2JqZWN0LmlzUmVxdWlyZWQKfTsKfSx7Ii4uL2kxOG4vaTE4biI6MjQsIi4uL2luZGV4IjoyNSwiLi4vbG9nZ2luZyI6MjcsIi4vaW5kZXgiOjM1LCJAamVua2lucy1jZC9kZXNpZ24tbGFuZ3VhZ2UiOjEwNywicmVhY3QiOjYyMywicmVhY3QtcmVtYXJrYWJsZSI6NDM4fV0sMjk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5wcm9wVHlwZXMgPSB1bmRlZmluZWQ7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCnZhciBvbmVPZiA9IF9yZWFjdC5Qcm9wVHlwZXMub25lT2YsCiAgICBzaGFwZSA9IF9yZWFjdC5Qcm9wVHlwZXMuc2hhcGUsCiAgICBzdHJpbmcgPSBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZzsKLyoqCiAqIEFsbCBvdXIgaW5wdXQgdHJlYXRpbmcgY29tcG9uZW50cyBzaGFyZSB0aGUgZm9sbG93aW5nIHByb3BUeXBlcwogKiBAdHlwZSB7e3BhcmFtZXRlcjogKn19CiAqLwoKdmFyIHByb3BUeXBlcyA9IGV4cG9ydHMucHJvcFR5cGVzID0gewogICAgcGFyYW1ldGVyOiBzaGFwZSh7CiAgICAgICAgZGVmYXVsdFBhcmFtZXRlclZhbHVlOiBzaGFwZSh7CiAgICAgICAgICAgIG5hbWU6IHN0cmluZywKICAgICAgICAgICAgdmFsdWU6IHN0cmluZwogICAgICAgIH0pLAogICAgICAgIGRlc2NyaXB0aW9uOiBzdHJpbmcsCiAgICAgICAgbmFtZTogc3RyaW5nLAogICAgICAgIHR5cGU6IG9uZU9mKFsnQm9vbGVhblBhcmFtZXRlckRlZmluaXRpb24nLCAnQ2hvaWNlUGFyYW1ldGVyRGVmaW5pdGlvbicsICdUZXh0UGFyYW1ldGVyRGVmaW5pdGlvbicsICdTdHJpbmdQYXJhbWV0ZXJEZWZpbml0aW9uJywgJ1Bhc3N3b3JkUGFyYW1ldGVyRGVmaW5pdGlvbiddKQogICAgfSkKfTsKfSx7InJlYWN0Ijo2MjN9XSwzMDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLkJvb2xlYW4gPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX2Rlc2lnbkxhbmd1YWdlID0gcmVxdWlyZSgnQGplbmtpbnMtY2QvZGVzaWduLWxhbmd1YWdlJyk7Cgp2YXIgX2NvbW1vblByb3B0eXBlcyA9IHJlcXVpcmUoJy4uL2NvbW1vblByb3B0eXBlcycpOwoKdmFyIF9zdHJpbmdVdGlsID0gcmVxdWlyZSgnLi4vLi4vc3RyaW5nVXRpbCcpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKdmFyIEJvb2xlYW4gPSBleHBvcnRzLkJvb2xlYW4gPSBmdW5jdGlvbiAoX0NvbXBvbmVudCkgewogICAgX2luaGVyaXRzKEJvb2xlYW4sIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIEJvb2xlYW4oKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEJvb2xlYW4pOwoKICAgICAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKEJvb2xlYW4uX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihCb29sZWFuKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKEJvb2xlYW4sIFt7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcywKICAgICAgICAgICAgICAgIHZhbHVlID0gX3Byb3BzLmRlZmF1bHRQYXJhbWV0ZXJWYWx1ZS52YWx1ZSwKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gX3Byb3BzLmRlc2NyaXB0aW9uLAogICAgICAgICAgICAgICAgbmFtZSA9IF9wcm9wcy5uYW1lLAogICAgICAgICAgICAgICAgb25DaGFuZ2UgPSBfcHJvcHMub25DaGFuZ2U7CgogICAgICAgICAgICB2YXIgY2xlYW5OYW1lID0gKDAsIF9zdHJpbmdVdGlsLnJlbW92ZU1hcmt1cFRhZ3MpKG5hbWUpOwogICAgICAgICAgICB2YXIgY2xlYW5EZXNjcmlwdGlvbiA9ICgwLCBfc3RyaW5nVXRpbC5yZW1vdmVNYXJrdXBUYWdzKShkZXNjcmlwdGlvbik7CiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgIF9kZXNpZ25MYW5ndWFnZS5Gb3JtRWxlbWVudCwKICAgICAgICAgICAgICAgIHsgdGl0bGU6IGNsZWFuRGVzY3JpcHRpb24sIGNsYXNzTmFtZTogJ3VuZGVybGluZScgfSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KF9kZXNpZ25MYW5ndWFnZS5DaGVja2JveCwgeyBjaGVja2VkOiB2YWx1ZSwgbmFtZTogY2xlYW5OYW1lLCBsYWJlbDogY2xlYW5OYW1lLCBvblRvZ2dsZTogb25DaGFuZ2UgfSkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIEJvb2xlYW47Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpCb29sZWFuLnByb3BUeXBlcyA9IF9jb21tb25Qcm9wdHlwZXMucHJvcFR5cGVzOwp9LHsiLi4vLi4vc3RyaW5nVXRpbCI6NTYsIi4uL2NvbW1vblByb3B0eXBlcyI6MjksIkBqZW5raW5zLWNkL2Rlc2lnbi1sYW5ndWFnZSI6MTA3LCJyZWFjdCI6NjIzfV0sMzE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5DaG9pY2UgPSB1bmRlZmluZWQ7Cgp2YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9OwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9kZXNpZ25MYW5ndWFnZSA9IHJlcXVpcmUoJ0BqZW5raW5zLWNkL2Rlc2lnbi1sYW5ndWFnZScpOwoKdmFyIF9jb21tb25Qcm9wdHlwZXMgPSByZXF1aXJlKCcuLi9jb21tb25Qcm9wdHlwZXMnKTsKCnZhciBfc3RyaW5nVXRpbCA9IHJlcXVpcmUoJy4uLy4uL3N0cmluZ1V0aWwnKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0KCnZhciBDaG9pY2UgPSBleHBvcnRzLkNob2ljZSA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoQ2hvaWNlLCBfQ29tcG9uZW50KTsKCiAgICBmdW5jdGlvbiBDaG9pY2UoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIENob2ljZSk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoQ2hvaWNlLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoQ2hvaWNlKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKENob2ljZSwgW3sKICAgICAgICBrZXk6ICdyYWRpb09yRHJvcERvd24nLAoKCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hvb3NlIHdoZXRoZXIgdG8gc2hvdyBhIGRyb3Bkb3duIGNob2ljZSBvciBhIHJhZGlvQnV0dG9uR3JvdXAKICAgICAgICAgKiBAcGFyYW0gY2hvaWNlcyAtIGFsdGVybmF0aXZlcyB3ZSBjYW4gcHJlc2VudAogICAgICAgICAqLwogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByYWRpb09yRHJvcERvd24oY2hvaWNlcykgewogICAgICAgICAgICBpZiAoY2hvaWNlcy5sZW5ndGggPiA2KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX2Rlc2lnbkxhbmd1YWdlLkRyb3Bkb3duOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBfZGVzaWduTGFuZ3VhZ2UuUmFkaW9CdXR0b25Hcm91cDsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcywKICAgICAgICAgICAgICAgIHZhbHVlID0gX3Byb3BzLmRlZmF1bHRQYXJhbWV0ZXJWYWx1ZS52YWx1ZSwKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gX3Byb3BzLmRlc2NyaXB0aW9uLAogICAgICAgICAgICAgICAgbmFtZSA9IF9wcm9wcy5uYW1lLAogICAgICAgICAgICAgICAgY2hvaWNlcyA9IF9wcm9wcy5jaG9pY2VzLAogICAgICAgICAgICAgICAgb25DaGFuZ2UgPSBfcHJvcHMub25DaGFuZ2U7CgogICAgICAgICAgICB2YXIgdXhDaG9pY2UgPSB0aGlzLnJhZGlvT3JEcm9wRG93bihjaG9pY2VzKTsKICAgICAgICAgICAgdmFyIGNsZWFuTmFtZSA9ICgwLCBfc3RyaW5nVXRpbC5yZW1vdmVNYXJrdXBUYWdzKShuYW1lKTsKICAgICAgICAgICAgdmFyIGNsZWFuRGVzY3JpcHRpb24gPSAoMCwgX3N0cmluZ1V0aWwucmVtb3ZlTWFya3VwVGFncykoZGVzY3JpcHRpb24pOwogICAgICAgICAgICB2YXIgb3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGRlZmF1bHRPcHRpb246IHZhbHVlLAogICAgICAgICAgICAgICAgb3B0aW9uczogY2hvaWNlcywKICAgICAgICAgICAgICAgIG5hbWU6IGNsZWFuTmFtZSwKICAgICAgICAgICAgICAgIG9uQ2hhbmdlOiBvbkNoYW5nZQogICAgICAgICAgICB9OwogICAgICAgICAgICAvLyBjc3MgdHdlYWtzCiAgICAgICAgICAgIHZhciBjbGFzc05hbWUgPSAnQ2hvaWNlJzsKICAgICAgICAgICAgdmFyIGZvcm1Qcm9wZXJ0aWVzID0geyB0aXRsZTogY2xlYW5EZXNjcmlwdGlvbiB9OwogICAgICAgICAgICBpZiAoY2hvaWNlcy5sZW5ndGggPiA2KSB7CiAgICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gJyBGdWxsV2lkdGgnOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY2xhc3NOYW1lICs9ICcgdW5kZXJsaW5lJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JtUHJvcGVydGllcy5jbGFzc05hbWUgPSBjbGFzc05hbWU7CgogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICBfZGVzaWduTGFuZ3VhZ2UuRm9ybUVsZW1lbnQsCiAgICAgICAgICAgICAgICBmb3JtUHJvcGVydGllcywKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KHV4Q2hvaWNlLCBfZXh0ZW5kcyh7fSwgb3B0aW9ucykpCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBDaG9pY2U7Cn0oX3JlYWN0LkNvbXBvbmVudCk7Ci8vIDxEcm9wZG93biB7Li4ub3B0aW9uc30gLz4KLy8gZXh0ZW5kaW5nIHRoZSBjb21tb24gcHJvcFR5cGUgc2luY2Ugd2UgaGF2ZSBhZGRpdGlvbmFsIHByb3BlcnRpZXMKLy8gY29uc3QgY2hvaWNlUHJvcFR5cGVzID0gcHJvcFR5cGVzOwovLyBjaG9pY2VQcm9wVHlwZXMucGFyYW1ldGVycy5jaG9pY2VzID0gUHJvcFR5cGVzLmFycmF5OwoKCkNob2ljZS5wcm9wVHlwZXMgPSBfY29tbW9uUHJvcHR5cGVzLnByb3BUeXBlczsKfSx7Ii4uLy4uL3N0cmluZ1V0aWwiOjU2LCIuLi9jb21tb25Qcm9wdHlwZXMiOjI5LCJAamVua2lucy1jZC9kZXNpZ24tbGFuZ3VhZ2UiOjEwNywicmVhY3QiOjYyM31dLDMyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuUGFzc3dvcmQgPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX2Rlc2lnbkxhbmd1YWdlID0gcmVxdWlyZSgnQGplbmtpbnMtY2QvZGVzaWduLWxhbmd1YWdlJyk7Cgp2YXIgX2NvbW1vblByb3B0eXBlcyA9IHJlcXVpcmUoJy4uL2NvbW1vblByb3B0eXBlcycpOwoKdmFyIF9zdHJpbmdVdGlsID0gcmVxdWlyZSgnLi4vLi4vc3RyaW5nVXRpbCcpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKLy8gaW1wb3J0IHsgRGVidWdSZW5kZXIgfSBmcm9tICcuL0RlYnVnUmVuZGVyJzsKCnZhciBQYXNzd29yZCA9IGV4cG9ydHMuUGFzc3dvcmQgPSBmdW5jdGlvbiAoX0NvbXBvbmVudCkgewogICAgX2luaGVyaXRzKFBhc3N3b3JkLCBfQ29tcG9uZW50KTsKCiAgICBmdW5jdGlvbiBQYXNzd29yZCgpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUGFzc3dvcmQpOwoKICAgICAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKFBhc3N3b3JkLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoUGFzc3dvcmQpKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoUGFzc3dvcmQsIFt7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICAvLyBjb25zdCBkZWJ1Z2dpbmcgPSBSZWFjdC5jcmVhdGVFbGVtZW50KERlYnVnUmVuZGVyLCB0aGlzLnByb3BzKTsKICAgICAgICAgICAgLy8gRklYTUU6IGRlZmF1bHRWYWx1ZSBkb2VzIG5vdCBjb250YWluIHRoZSB2YWx1ZSB3ZSB3YWl0IGZvcgogICAgICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcywKICAgICAgICAgICAgICAgIHZhbHVlID0gX3Byb3BzLmRlZmF1bHRQYXJhbWV0ZXJWYWx1ZS52YWx1ZSwKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gX3Byb3BzLmRlc2NyaXB0aW9uLAogICAgICAgICAgICAgICAgbmFtZSA9IF9wcm9wcy5uYW1lLAogICAgICAgICAgICAgICAgb25DaGFuZ2UgPSBfcHJvcHMub25DaGFuZ2U7CgogICAgICAgICAgICB2YXIgY2xlYW5OYW1lID0gKDAsIF9zdHJpbmdVdGlsLnJlbW92ZU1hcmt1cFRhZ3MpKG5hbWUpOwogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICBfZGVzaWduTGFuZ3VhZ2UuRm9ybUVsZW1lbnQsCiAgICAgICAgICAgICAgICB7IHRpdGxlOiBjbGVhbk5hbWUgfSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnUGFzc3dvcmQgRnVsbFdpZHRoJyB9LAogICAgICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KF9kZXNpZ25MYW5ndWFnZS5QYXNzd29yZElucHV0LCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUsIG5hbWU6IGNsZWFuTmFtZSwgb25DaGFuZ2U6IG9uQ2hhbmdlIH0pLAogICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICYmIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdpbnB1dERlc2NyaXB0aW9uJyB9LAogICAgICAgICAgICAgICAgICAgICAgICAoMCwgX3N0cmluZ1V0aWwucmVtb3ZlTWFya3VwVGFncykoZGVzY3JpcHRpb24pCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gUGFzc3dvcmQ7Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpQYXNzd29yZC5wcm9wVHlwZXMgPSBfY29tbW9uUHJvcHR5cGVzLnByb3BUeXBlczsKfSx7Ii4uLy4uL3N0cmluZ1V0aWwiOjU2LCIuLi9jb21tb25Qcm9wdHlwZXMiOjI5LCJAamVua2lucy1jZC9kZXNpZ24tbGFuZ3VhZ2UiOjEwNywicmVhY3QiOjYyM31dLDMzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuU3RyaW5nID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9kZXNpZ25MYW5ndWFnZSA9IHJlcXVpcmUoJ0BqZW5raW5zLWNkL2Rlc2lnbi1sYW5ndWFnZScpOwoKdmFyIF9jb21tb25Qcm9wdHlwZXMgPSByZXF1aXJlKCcuLi9jb21tb25Qcm9wdHlwZXMnKTsKCnZhciBfc3RyaW5nVXRpbCA9IHJlcXVpcmUoJy4uLy4uL3N0cmluZ1V0aWwnKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0KCnZhciBTdHJpbmcgPSBleHBvcnRzLlN0cmluZyA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoU3RyaW5nLCBfQ29tcG9uZW50KTsKCiAgICBmdW5jdGlvbiBTdHJpbmcoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFN0cmluZyk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoU3RyaW5nLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoU3RyaW5nKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFN0cmluZywgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzLAogICAgICAgICAgICAgICAgdmFsdWUgPSBfcHJvcHMuZGVmYXVsdFBhcmFtZXRlclZhbHVlLnZhbHVlLAogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSBfcHJvcHMuZGVzY3JpcHRpb24sCiAgICAgICAgICAgICAgICBuYW1lID0gX3Byb3BzLm5hbWUsCiAgICAgICAgICAgICAgICBvbkNoYW5nZSA9IF9wcm9wcy5vbkNoYW5nZTsKCiAgICAgICAgICAgIHZhciBjbGVhbkRlc2NyaXB0aW9uID0gKDAsIF9zdHJpbmdVdGlsLnJlbW92ZU1hcmt1cFRhZ3MpKGRlc2NyaXB0aW9uKTsKICAgICAgICAgICAgdmFyIGNsZWFuTmFtZSA9ICgwLCBfc3RyaW5nVXRpbC5yZW1vdmVNYXJrdXBUYWdzKShuYW1lKTsKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgX2Rlc2lnbkxhbmd1YWdlLkZvcm1FbGVtZW50LAogICAgICAgICAgICAgICAgeyB0aXRsZTogY2xlYW5EZXNjcmlwdGlvbiB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdTdHJpbmcgRnVsbFdpZHRoJyB9LAogICAgICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KF9kZXNpZ25MYW5ndWFnZS5UZXh0SW5wdXQsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSwgbmFtZTogY2xlYW5OYW1lLCBvbkNoYW5nZTogb25DaGFuZ2UgfSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFN0cmluZzsKfShfcmVhY3QuQ29tcG9uZW50KTsKClN0cmluZy5wcm9wVHlwZXMgPSBfY29tbW9uUHJvcHR5cGVzLnByb3BUeXBlczsKfSx7Ii4uLy4uL3N0cmluZ1V0aWwiOjU2LCIuLi9jb21tb25Qcm9wdHlwZXMiOjI5LCJAamVua2lucy1jZC9kZXNpZ24tbGFuZ3VhZ2UiOjEwNywicmVhY3QiOjYyM31dLDM0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuVGV4dCA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfZGVzaWduTGFuZ3VhZ2UgPSByZXF1aXJlKCdAamVua2lucy1jZC9kZXNpZ24tbGFuZ3VhZ2UnKTsKCnZhciBfY29tbW9uUHJvcHR5cGVzID0gcmVxdWlyZSgnLi4vY29tbW9uUHJvcHR5cGVzJyk7Cgp2YXIgX3N0cmluZ1V0aWwgPSByZXF1aXJlKCcuLi8uLi9zdHJpbmdVdGlsJyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9Cgp2YXIgVGV4dCA9IGV4cG9ydHMuVGV4dCA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoVGV4dCwgX0NvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gVGV4dCgpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVGV4dCk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoVGV4dC5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKFRleHQpKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoVGV4dCwgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzLAogICAgICAgICAgICAgICAgdmFsdWUgPSBfcHJvcHMuZGVmYXVsdFBhcmFtZXRlclZhbHVlLnZhbHVlLAogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSBfcHJvcHMuZGVzY3JpcHRpb24sCiAgICAgICAgICAgICAgICBuYW1lID0gX3Byb3BzLm5hbWUsCiAgICAgICAgICAgICAgICBvbkNoYW5nZSA9IF9wcm9wcy5vbkNoYW5nZTsKCiAgICAgICAgICAgIHZhciBjbGVhbk5hbWUgPSAoMCwgX3N0cmluZ1V0aWwucmVtb3ZlTWFya3VwVGFncykobmFtZSk7CiAgICAgICAgICAgIHZhciBjbGVhbkRlc2NyaXB0aW9uID0gKDAsIF9zdHJpbmdVdGlsLnJlbW92ZU1hcmt1cFRhZ3MpKGRlc2NyaXB0aW9uKTsKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgX2Rlc2lnbkxhbmd1YWdlLkZvcm1FbGVtZW50LAogICAgICAgICAgICAgICAgeyB0aXRsZTogY2xlYW5EZXNjcmlwdGlvbiB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdUZXh0IEZ1bGxXaWR0aCcgfSwKICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChfZGVzaWduTGFuZ3VhZ2UuVGV4dEFyZWEsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSwgbmFtZTogY2xlYW5OYW1lLCBvbkNoYW5nZTogb25DaGFuZ2UgfSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFRleHQ7Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpUZXh0LnByb3BUeXBlcyA9IF9jb21tb25Qcm9wdHlwZXMucHJvcFR5cGVzOwp9LHsiLi4vLi4vc3RyaW5nVXRpbCI6NTYsIi4uL2NvbW1vblByb3B0eXBlcyI6MjksIkBqZW5raW5zLWNkL2Rlc2lnbi1sYW5ndWFnZSI6MTA3LCJyZWFjdCI6NjIzfV0sMzU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuUGFyYW1ldGVyQXBpID0gZXhwb3J0cy5zdXBwb3J0ZWRJbnB1dFR5cGVzID0gZXhwb3J0cy5zdXBwb3J0ZWRJbnB1dFR5cGVzTWFwcGluZyA9IGV4cG9ydHMuUGFyYW1ldGVyc1J1bkJ1dHRvbiA9IGV4cG9ydHMuUGFyYW1ldGVyU2VydmljZSA9IGV4cG9ydHMuRGVidWdSZW5kZXIgPSBleHBvcnRzLlBhcmFtZXRlcnNSZW5kZXIgPSBleHBvcnRzLlBhc3N3b3JkID0gZXhwb3J0cy5UZXh0ID0gZXhwb3J0cy5TdHJpbmcgPSBleHBvcnRzLkNob2ljZSA9IGV4cG9ydHMuQm9vbGVhbiA9IHVuZGVmaW5lZDsKCnZhciBfUGFyYW1ldGVyc1JlbmRlciA9IHJlcXVpcmUoJy4vcmVuZGVyZXIvUGFyYW1ldGVyc1JlbmRlcicpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdQYXJhbWV0ZXJzUmVuZGVyJywgewogIGVudW1lcmFibGU6IHRydWUsCiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICByZXR1cm4gX1BhcmFtZXRlcnNSZW5kZXIuUGFyYW1ldGVyc1JlbmRlcjsKICB9Cn0pOwoKdmFyIF9EZWJ1Z1JlbmRlciA9IHJlcXVpcmUoJy4vcmVuZGVyZXIvRGVidWdSZW5kZXInKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnRGVidWdSZW5kZXInLCB7CiAgZW51bWVyYWJsZTogdHJ1ZSwKICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgIHJldHVybiBfRGVidWdSZW5kZXIuRGVidWdSZW5kZXI7CiAgfQp9KTsKCnZhciBfUGFyYW1ldGVyU2VydmljZSA9IHJlcXVpcmUoJy4vc2VydmljZXMvUGFyYW1ldGVyU2VydmljZScpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdQYXJhbWV0ZXJTZXJ2aWNlJywgewogIGVudW1lcmFibGU6IHRydWUsCiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICByZXR1cm4gX1BhcmFtZXRlclNlcnZpY2UuUGFyYW1ldGVyU2VydmljZTsKICB9Cn0pOwoKdmFyIF9QYXJhbWV0ZXJzUnVuQnV0dG9uID0gcmVxdWlyZSgnLi9QYXJhbWV0ZXJzUnVuQnV0dG9uJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1BhcmFtZXRlcnNSdW5CdXR0b24nLCB7CiAgZW51bWVyYWJsZTogdHJ1ZSwKICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgIHJldHVybiBfUGFyYW1ldGVyc1J1bkJ1dHRvbi5QYXJhbWV0ZXJzUnVuQnV0dG9uOwogIH0KfSk7Cgp2YXIgX0Jvb2xlYW4gPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvQm9vbGVhbicpOwoKdmFyIF9DaG9pY2UgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvQ2hvaWNlJyk7Cgp2YXIgX1N0cmluZyA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9TdHJpbmcnKTsKCnZhciBfVGV4dCA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9UZXh0Jyk7Cgp2YXIgX1Bhc3N3b3JkID0gcmVxdWlyZSgnLi9jb21wb25lbnRzL1Bhc3N3b3JkJyk7Cgp2YXIgX1BhcmFtZXRlckFwaSA9IHJlcXVpcmUoJy4vcmVzdC9QYXJhbWV0ZXJBcGknKTsKCmV4cG9ydHMuQm9vbGVhbiA9IF9Cb29sZWFuLkJvb2xlYW47CmV4cG9ydHMuQ2hvaWNlID0gX0Nob2ljZS5DaG9pY2U7CmV4cG9ydHMuU3RyaW5nID0gX1N0cmluZy5TdHJpbmc7CmV4cG9ydHMuVGV4dCA9IF9UZXh0LlRleHQ7CmV4cG9ydHMuUGFzc3dvcmQgPSBfUGFzc3dvcmQuUGFzc3dvcmQ7Ci8vIFJlbmRlcmVyCi8vIEltcGxlbWVudGF0aW9ucwoKLyoqCiAqIGFsbCBpbnB1dCB0eXBlcyB0aGF0IHdlIGtub3cgb2YgbWFwcGluZyBhZ2FpbnN0IHRoZSBjb21wb25lbnQKICogQHR5cGUge3tCb29sZWFuUGFyYW1ldGVyRGVmaW5pdGlvbjogQm9vbGVhbiwgQ2hvaWNlUGFyYW1ldGVyRGVmaW5pdGlvbjogQ2hvaWNlLCBUZXh0UGFyYW1ldGVyRGVmaW5pdGlvbjogU3RyaW5nLCBTdHJpbmdQYXJhbWV0ZXJEZWZpbml0aW9uOiBUZXh0LCBQYXNzd29yZFBhcmFtZXRlckRlZmluaXRpb246IFBhc3N3b3JkfX0KICovCnZhciBzdXBwb3J0ZWRJbnB1dFR5cGVzTWFwcGluZyA9IGV4cG9ydHMuc3VwcG9ydGVkSW5wdXRUeXBlc01hcHBpbmcgPSB7CiAgQm9vbGVhblBhcmFtZXRlckRlZmluaXRpb246IF9Cb29sZWFuLkJvb2xlYW4sCiAgQ2hvaWNlUGFyYW1ldGVyRGVmaW5pdGlvbjogX0Nob2ljZS5DaG9pY2UsCiAgVGV4dFBhcmFtZXRlckRlZmluaXRpb246IF9UZXh0LlRleHQsCiAgU3RyaW5nUGFyYW1ldGVyRGVmaW5pdGlvbjogX1N0cmluZy5TdHJpbmcsCiAgUGFzc3dvcmRQYXJhbWV0ZXJEZWZpbml0aW9uOiBfUGFzc3dvcmQuUGFzc3dvcmQKfTsKLyoqCiAqIGFsbCBpbnB1dCB0eXBlcyB0aGF0IHdlIGtub3cgb2YKICogQHR5cGUge0FycmF5fQogKi8KdmFyIHN1cHBvcnRlZElucHV0VHlwZXMgPSBleHBvcnRzLnN1cHBvcnRlZElucHV0VHlwZXMgPSBPYmplY3Qua2V5cyhzdXBwb3J0ZWRJbnB1dFR5cGVzTWFwcGluZyk7Cgp2YXIgcGFyYW1ldGVyQXBpID0gbmV3IF9QYXJhbWV0ZXJBcGkuUGFyYW1ldGVyQXBpKCk7CmV4cG9ydHMuUGFyYW1ldGVyQXBpID0gcGFyYW1ldGVyQXBpOwp9LHsiLi9QYXJhbWV0ZXJzUnVuQnV0dG9uIjoyOCwiLi9jb21wb25lbnRzL0Jvb2xlYW4iOjMwLCIuL2NvbXBvbmVudHMvQ2hvaWNlIjozMSwiLi9jb21wb25lbnRzL1Bhc3N3b3JkIjozMiwiLi9jb21wb25lbnRzL1N0cmluZyI6MzMsIi4vY29tcG9uZW50cy9UZXh0IjozNCwiLi9yZW5kZXJlci9EZWJ1Z1JlbmRlciI6MzYsIi4vcmVuZGVyZXIvUGFyYW1ldGVyc1JlbmRlciI6MzcsIi4vcmVzdC9QYXJhbWV0ZXJBcGkiOjM4LCIuL3NlcnZpY2VzL1BhcmFtZXRlclNlcnZpY2UiOjM5fV0sMzY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5EZWJ1Z1JlbmRlciA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfY29tbW9uUHJvcHR5cGVzID0gcmVxdWlyZSgnLi4vY29tbW9uUHJvcHR5cGVzJyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9Cgp2YXIgRGVidWdSZW5kZXIgPSBleHBvcnRzLkRlYnVnUmVuZGVyID0gZnVuY3Rpb24gKF9Db21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhEZWJ1Z1JlbmRlciwgX0NvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gRGVidWdSZW5kZXIoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIERlYnVnUmVuZGVyKTsKCiAgICAgICAgcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChEZWJ1Z1JlbmRlci5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKERlYnVnUmVuZGVyKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKERlYnVnUmVuZGVyLCBbewogICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHMsCiAgICAgICAgICAgICAgICB2YWx1ZSA9IF9wcm9wcy5kZWZhdWx0UGFyYW1ldGVyVmFsdWUudmFsdWUsCiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiA9IF9wcm9wcy5kZXNjcmlwdGlvbiwKICAgICAgICAgICAgICAgIG5hbWUgPSBfcHJvcHMubmFtZSwKICAgICAgICAgICAgICAgIHR5cGUgPSBfcHJvcHMudHlwZTsKCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICd1bCcsCiAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2xpJywKICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICduYW1lOiAnLAogICAgICAgICAgICAgICAgICAgIG5hbWUKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAnbGknLAogICAgICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAgICAgJ3ZhbHVlOiAnLAogICAgICAgICAgICAgICAgICAgIHZhbHVlCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2xpJywKICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICdkZXNjcmlwdGlvbjogJywKICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICdsaScsCiAgICAgICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgICAgICAnbmFtZTogJywKICAgICAgICAgICAgICAgICAgICBuYW1lCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2xpJywKICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICd0eXBlOiAnLAogICAgICAgICAgICAgICAgICAgIHR5cGUKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIERlYnVnUmVuZGVyOwp9KF9yZWFjdC5Db21wb25lbnQpOwoKRGVidWdSZW5kZXIucHJvcFR5cGVzID0gX2NvbW1vblByb3B0eXBlcy5wcm9wVHlwZXM7Cn0seyIuLi9jb21tb25Qcm9wdHlwZXMiOjI5LCJyZWFjdCI6NjIzfV0sMzc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKCnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07CgpleHBvcnRzLlBhcmFtZXRlcnNSZW5kZXIgPSBQYXJhbWV0ZXJzUmVuZGVyOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfZGVzaWduTGFuZ3VhZ2UgPSByZXF1aXJlKCdAamVua2lucy1jZC9kZXNpZ24tbGFuZ3VhZ2UnKTsKCnZhciBfaTE4biA9IHJlcXVpcmUoJy4uLy4uL2kxOG4vaTE4bicpOwoKdmFyIF9pMThuMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2kxOG4pOwoKdmFyIF9pbmRleCA9IHJlcXVpcmUoJy4uL2luZGV4Jyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKLyoqCiAqIFRyYW5zbGF0ZSBmdW5jdGlvbgogKi8KdmFyIHRyYW5zbGF0ZSA9ICgwLCBfaTE4bjIuZGVmYXVsdCkoJ2JsdWVvY2Vhbi13ZWInKTsKCmZ1bmN0aW9uIFBhcmFtZXRlcnNSZW5kZXIocHJvcGVydGllcykgewogICAgdmFyIF90aGlzID0gdGhpczsKCiAgICB2YXIgcGFyYW1ldGVycyA9IHByb3BlcnRpZXMucGFyYW1ldGVycywKICAgICAgICBfcHJvcGVydGllcyRvbkNoYW5nZSA9IHByb3BlcnRpZXMub25DaGFuZ2UsCiAgICAgICAgb25DaGFuZ2UgPSBfcHJvcGVydGllcyRvbkNoYW5nZSA9PT0gdW5kZWZpbmVkID8gZnVuY3Rpb24gKCkge30gOiBfcHJvcGVydGllcyRvbkNoYW5nZTsKCiAgICB2YXIgcmVuZGVyZWRQYXJhbWV0ZXJzID0gcGFyYW1ldGVycy5tYXAoZnVuY3Rpb24gKHBhcmFtZXRlciwgaW5kZXgpIHsKICAgICAgICB2YXIgdHlwZSA9IHBhcmFtZXRlci50eXBlOwoKICAgICAgICB2YXIgcmV0dXJuVmFsdWUgPSBfaW5kZXguc3VwcG9ydGVkSW5wdXRUeXBlc01hcHBpbmdbdHlwZV07CiAgICAgICAgaWYgKHJldHVyblZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChyZXR1cm5WYWx1ZSwgX2V4dGVuZHMoe30sIHBhcmFtZXRlciwgewogICAgICAgICAgICAgICAga2V5OiBpbmRleCwKICAgICAgICAgICAgICAgIG9uQ2hhbmdlOiBvbkNoYW5nZS5iaW5kKF90aGlzLCBpbmRleCkKICAgICAgICAgICAgfSkpOwogICAgICAgIH0KICAgICAgICAvLyBlcnJvciBjYXNlIC0gcmV0dXJuaW5nIGFuIGVycm9yIGFsZXJ0CiAgICAgICAgdmFyIGFsZXJ0Q2FwdGlvbiA9IHRyYW5zbGF0ZSgncGFyYW1ldGVyLmVycm9yLm1lc3NhZ2UnLCB7IDA6IHR5cGUgfSk7CiAgICAgICAgdmFyIGFsZXJ0VGl0bGUgPSB0cmFuc2xhdGUoJ3BhcmFtZXRlci5lcnJvci50aXRsZScpOwogICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChfZGVzaWduTGFuZ3VhZ2UuQWxlcnRzLCB7IG1lc3NhZ2U6IGFsZXJ0Q2FwdGlvbiwgdHlwZTogJ0Vycm9yJywgdGl0bGU6IGFsZXJ0VGl0bGUgfSk7CiAgICB9KTsKCiAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgJ2RpdicsCiAgICAgICAgbnVsbCwKICAgICAgICByZW5kZXJlZFBhcmFtZXRlcnMKICAgICk7Cn0KfSx7Ii4uLy4uL2kxOG4vaTE4biI6MjQsIi4uL2luZGV4IjozNSwiQGplbmtpbnMtY2QvZGVzaWduLWxhbmd1YWdlIjoxMDcsInJlYWN0Ijo2MjN9XSwzODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlBhcmFtZXRlckFwaSA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF8gPSByZXF1aXJlKCcuLi8uLicpOwoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgovKioKICogR2VuZXJpYyBvcHRpb25zIG5lZWRlZCBmb3IgYWxsIHJlcXVlc3RzCiAqIEB0eXBlIHt7Y3JlZGVudGlhbHM6IHN0cmluZywgbWV0aG9kOiBzdHJpbmcsIGhlYWRlcnM6IHtDb250ZW50LVR5cGU6IHN0cmluZ319fQogKi8KdmFyIGZldGNoT3B0aW9uc0NvbW1vbiA9IHsKICAgIGNyZWRlbnRpYWxzOiAnaW5jbHVkZScsCiAgICBtZXRob2Q6ICdQT1NUJywKICAgIGhlYWRlcnM6IHsKICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nCiAgICB9Cn07Ci8qKgogKiBIZWxwZXIgbWV0aG9kIHRvIGNsb25lIGFuZCBwcmVwYXJlIHRoZSBib2R5IGlmIGF0dGFjaGVkCiAqIEBwYXJhbSBib2R5IC0gSlNPTiBvYmplY3QgdGhhdCB3ZSB3YW50IHRvIHNlbnQgdG8gdGhlIHNlcnZlcgogKiBAcmV0dXJucyB7Kn0gZmV0Y2hPcHRpb25zCiAqLwpmdW5jdGlvbiBwcmVwYXJlT3B0aW9ucyhib2R5KSB7CiAgICB2YXIgZmV0Y2hPcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgZmV0Y2hPcHRpb25zQ29tbW9uKTsKICAgIGlmIChib2R5KSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgZmV0Y2hPcHRpb25zLmJvZHkgPSBKU09OLnN0cmluZ2lmeShib2R5KTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIGNvbnNvbGUud2FybignVGhlIGZvcm0gYm9keSBhcmUgbm90IGFkZGVkLiBDb3VsZCBub3QgZXh0cmFjdCBkYXRhIGZyb20gdGhlIGJvZHkgZWxlbWVudCcsIGJvZHkpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBmZXRjaE9wdGlvbnM7Cn0KCnZhciBQYXJhbWV0ZXJBcGkgPSBleHBvcnRzLlBhcmFtZXRlckFwaSA9IGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFBhcmFtZXRlckFwaSgpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUGFyYW1ldGVyQXBpKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoUGFyYW1ldGVyQXBpLCBbewogICAgICAgIGtleTogJ3N0YXJ0UnVuV2l0aFBhcmFtZXRlcnMnLAoKCiAgICAgICAgLyoqCiAgICAgICAgICogU3RhcnQgYSBydW4gd2l0aCBwYXJhbWV0ZXJzCiAgICAgICAgICogQHBhcmFtIGhyZWYgLSB0aGUgZGVzdGluYXRpb24gKGVuZHMgbm9ybWFsbHkgd2l0aCAvcnVucy8pCiAgICAgICAgICogQHBhcmFtIHBhcmFtZXRlcnMgLSB0aGUgcGFyYW1ldGVycyB3ZSB3YW50IHRvIHN1Ym1pdAogICAgICAgICAqIEByZXR1cm5zIHsqfSBQcm9taXNlCiAgICAgICAgICovCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHN0YXJ0UnVuV2l0aFBhcmFtZXRlcnMoaHJlZiwgcGFyYW1ldGVycykgewogICAgICAgICAgICB2YXIgZmV0Y2hPcHRpb25zID0gcHJlcGFyZU9wdGlvbnMoeyBwYXJhbWV0ZXJzOiBwYXJhbWV0ZXJzIH0pOwogICAgICAgICAgICByZXR1cm4gXy5GZXRjaC5mZXRjaEpTT04oaHJlZiwgeyBmZXRjaE9wdGlvbnM6IGZldGNoT3B0aW9ucyB9KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFN1Ym1pdCBhbiBJbnB1dFN0ZXAgZm9ybQogICAgICAgICAqIEBwYXJhbSBocmVmIC0gdGhlIGRlc3RpbmF0aW9uICh0aGUgc3RlcCBocmVmKQogICAgICAgICAqIEBwYXJhbSBpZCAtIHVuaXF1ZSBpZCBvZiB0aGUgaW5wdXQgc3RlcCB3ZSBzdWJtaXQgdG8KICAgICAgICAgKiBAcGFyYW0gcGFyYW1ldGVycyAtIHRoZSBwYXJhbWV0ZXJzIHdlIHdhbnQgdG8gc3VibWl0CiAgICAgICAgICogQHJldHVybnMgeyp9IFByb21pc2UKICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnc3VibWl0SW5wdXRQYXJhbWV0ZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzdWJtaXRJbnB1dFBhcmFtZXRlcihocmVmLCBpZCwgcGFyYW1ldGVycykgewogICAgICAgICAgICB2YXIgZmV0Y2hPcHRpb25zID0gcHJlcGFyZU9wdGlvbnMoeyBpZDogaWQsIHBhcmFtZXRlcnM6IHBhcmFtZXRlcnMgfSk7CiAgICAgICAgICAgIHJldHVybiBfLkZldGNoLmZldGNoSlNPTihocmVmLCB7IGZldGNoT3B0aW9uczogZmV0Y2hPcHRpb25zIH0pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ2FuY2VsIGFuIElucHV0U3RlcCBmb3JtCiAgICAgICAgICogQHBhcmFtIGhyZWYgLSB0aGUgZGVzdGluYXRpb24gKHRoZSBzdGVwIGhyZWYpCiAgICAgICAgICogQHBhcmFtIGlkIC0gdW5pcXVlIGlkIG9mIHRoZSBpbnB1dCBzdGVwIHdlIHdhbnQgdG8gY2FuY2VsCiAgICAgICAgICogQHJldHVybnMgeyp9IFByb21pc2UKICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnY2FuY2VsSW5wdXRQYXJhbWV0ZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjYW5jZWxJbnB1dFBhcmFtZXRlcihocmVmLCBpZCkgewogICAgICAgICAgICB2YXIgZmV0Y2hPcHRpb25zID0gcHJlcGFyZU9wdGlvbnMoKTsKICAgICAgICAgICAgZmV0Y2hPcHRpb25zLmJvZHkgPSBKU09OLnN0cmluZ2lmeSh7IGlkOiBpZCwgYWJvcnQ6IHRydWUgfSk7CiAgICAgICAgICAgIHJldHVybiBfLkZldGNoLmZldGNoSlNPTihocmVmLCB7IGZldGNoT3B0aW9uczogZmV0Y2hPcHRpb25zIH0pOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gUGFyYW1ldGVyQXBpOwp9KCk7Cn0seyIuLi8uLiI6MjV9XSwzOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlBhcmFtZXRlclNlcnZpY2UgPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfZGVzYywgX3ZhbHVlLCBfY2xhc3MsIF9kZXNjcmlwdG9yOwoKdmFyIF9tb2J4ID0gcmVxdWlyZSgnbW9ieCcpOwoKZnVuY3Rpb24gX2luaXREZWZpbmVQcm9wKHRhcmdldCwgcHJvcGVydHksIGRlc2NyaXB0b3IsIGNvbnRleHQpIHsKICAgIGlmICghZGVzY3JpcHRvcikgcmV0dXJuOwogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHksIHsKICAgICAgICBlbnVtZXJhYmxlOiBkZXNjcmlwdG9yLmVudW1lcmFibGUsCiAgICAgICAgY29uZmlndXJhYmxlOiBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSwKICAgICAgICB3cml0YWJsZTogZGVzY3JpcHRvci53cml0YWJsZSwKICAgICAgICB2YWx1ZTogZGVzY3JpcHRvci5pbml0aWFsaXplciA/IGRlc2NyaXB0b3IuaW5pdGlhbGl6ZXIuY2FsbChjb250ZXh0KSA6IHZvaWQgMAogICAgfSk7Cn0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcih0YXJnZXQsIHByb3BlcnR5LCBkZWNvcmF0b3JzLCBkZXNjcmlwdG9yLCBjb250ZXh0KSB7CiAgICB2YXIgZGVzYyA9IHt9OwogICAgT2JqZWN0WydrZScgKyAneXMnXShkZXNjcmlwdG9yKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsKICAgICAgICBkZXNjW2tleV0gPSBkZXNjcmlwdG9yW2tleV07CiAgICB9KTsKICAgIGRlc2MuZW51bWVyYWJsZSA9ICEhZGVzYy5lbnVtZXJhYmxlOwogICAgZGVzYy5jb25maWd1cmFibGUgPSAhIWRlc2MuY29uZmlndXJhYmxlOwoKICAgIGlmICgndmFsdWUnIGluIGRlc2MgfHwgZGVzYy5pbml0aWFsaXplcikgewogICAgICAgIGRlc2Mud3JpdGFibGUgPSB0cnVlOwogICAgfQoKICAgIGRlc2MgPSBkZWNvcmF0b3JzLnNsaWNlKCkucmV2ZXJzZSgpLnJlZHVjZShmdW5jdGlvbiAoZGVzYywgZGVjb3JhdG9yKSB7CiAgICAgICAgcmV0dXJuIGRlY29yYXRvcih0YXJnZXQsIHByb3BlcnR5LCBkZXNjKSB8fCBkZXNjOwogICAgfSwgZGVzYyk7CgogICAgaWYgKGNvbnRleHQgJiYgZGVzYy5pbml0aWFsaXplciAhPT0gdm9pZCAwKSB7CiAgICAgICAgZGVzYy52YWx1ZSA9IGRlc2MuaW5pdGlhbGl6ZXIgPyBkZXNjLmluaXRpYWxpemVyLmNhbGwoY29udGV4dCkgOiB2b2lkIDA7CiAgICAgICAgZGVzYy5pbml0aWFsaXplciA9IHVuZGVmaW5lZDsKICAgIH0KCiAgICBpZiAoZGVzYy5pbml0aWFsaXplciA9PT0gdm9pZCAwKSB7CiAgICAgICAgT2JqZWN0WydkZWZpbmUnICsgJ1Byb3BlcnR5J10odGFyZ2V0LCBwcm9wZXJ0eSwgZGVzYyk7CiAgICAgICAgZGVzYyA9IG51bGw7CiAgICB9CgogICAgcmV0dXJuIGRlc2M7Cn0KCmZ1bmN0aW9uIF9pbml0aWFsaXplcldhcm5pbmdIZWxwZXIoZGVzY3JpcHRvciwgY29udGV4dCkgewogICAgdGhyb3cgbmV3IEVycm9yKCdEZWNvcmF0aW5nIGNsYXNzIHByb3BlcnR5IGZhaWxlZC4gUGxlYXNlIGVuc3VyZSB0aGF0IHRyYW5zZm9ybS1jbGFzcy1wcm9wZXJ0aWVzIGlzIGVuYWJsZWQuJyk7Cn0KCi8qKgogKiBIb2xkcyBvbmUgb3IgbW9yZSBwYXJhbWV0ZXJzIGluIHN0YXRlIGZvciBkaXNwbGF5IGluIFVJLgogKi8KdmFyIFBhcmFtZXRlclNlcnZpY2UgPSBleHBvcnRzLlBhcmFtZXRlclNlcnZpY2UgPSAoX2NsYXNzID0gZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gUGFyYW1ldGVyU2VydmljZSgpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUGFyYW1ldGVyU2VydmljZSk7CgogICAgICAgIF9pbml0RGVmaW5lUHJvcCh0aGlzLCAncGFyYW1ldGVycycsIF9kZXNjcmlwdG9yLCB0aGlzKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoUGFyYW1ldGVyU2VydmljZSwgW3sKICAgICAgICBrZXk6ICdpbml0JywKCgogICAgICAgIC8qKgogICAgICAgICAqIGluaXRpYWxpemUgYXJyYXkgZnJvbSBwYXJhbWV0ZXJzLgogICAgICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJzIC0gYXJyYXkgb2YgcGFyYW1ldGVyCiAgICAgICAgICovCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGluaXQocGFyYW1ldGVycykgewogICAgICAgICAgICB0aGlzLnBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiBBZGRzIGEgcGFyYW1ldGVyIHRvIHRoZSBsaXN0LgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHBhcmFtZXRlciBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIHNoYXBlOgogICAgICAgICAqIHsKICAgICAgICAgKiAiX2NsYXNzIjogImh1ZHNvbi5tb2RlbC5Cb29sZWFuUGFyYW1ldGVyRGVmaW5pdGlvbiIsCiAgICAgICAgICogImRlZmF1bHRQYXJhbWV0ZXJWYWx1ZSI6IHsKICAgICAgICAgKiAgICAiX2NsYXNzIjogImh1ZHNvbi5tb2RlbC5Cb29sZWFuUGFyYW1ldGVyVmFsdWUiLAogICAgICAgICAqICAgICJuYW1lIjogImlzRm9vIiwKICAgICAgICAgKiAgICAidmFsdWUiOiBmYWxzZSwKICAgICAgICAgKiAgICAiX2NhcGFiaWxpdGllcyI6IFsiaHVkc29uLm1vZGVsLlBhcmFtZXRlclZhbHVlIl0KICAgICAgICAgKiB9LAogICAgICAgICAqICJkZXNjcmlwdGlvbiI6ICJpc0ZvbyBzaG91bGQgYmUgZmFsc2UiLAogICAgICAgICAqICJuYW1lIjogImlzRm9vIiwKICAgICAgICAgKiAidHlwZSI6ICJCb29sZWFuUGFyYW1ldGVyRGVmaW5pdGlvbiIsCiAgICAgICAgICogIl9jYXBhYmlsaXRpZXMiOiBbImh1ZHNvbi5tb2RlbC5TaW1wbGVQYXJhbWV0ZXJEZWZpbml0aW9uIiwgImh1ZHNvbi5tb2RlbC5QYXJhbWV0ZXJEZWZpbml0aW9uIl0KICAgICAgICAgKiB9CiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ2FkZFBhcmFtZXRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGFkZFBhcmFtZXRlcihwYXJhbWV0ZXIpIHsKICAgICAgICAgICAgdGhpcy5wYXJhbWV0ZXJzLnB1c2gocGFyYW1ldGVyKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEFkZCBhbiBhcnJheSBvZiBwYXJhbWV0ZXJzLgogICAgICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJzIC0gYXJyYXkgb2YgcGFyYW1ldGVyCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ2FkZFBhcmFtZXRlcnMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBhZGRQYXJhbWV0ZXJzKHBhcmFtZXRlcnMpIHsKICAgICAgICAgICAgdGhpcy5wYXJhbWV0ZXJzLnB1c2guYXBwbHkodGhpcy5wYXJhbWV0ZXJzLCBwYXJhbWV0ZXJzKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENoYW5nZSB0aGUgZGVmYXVsdFZhbHVlIG9mIGFuIGV4aXN0aW5nIHBhcmFtZXRlcgogICAgICAgICAqIEBwYXJhbSBpbmRleCAtIHRoZSBwb3NpdGlvbiBvZiB0aGUgb2JqZWN0CiAgICAgICAgICogQHBhcmFtIG5ld1ZhbHVlIC0gdGhlIHZhbHVlIG9mIHRoZSB1c2VyIHNlbGVjdGlvbiBiZWNvbWVzIHRoZSBuZSBkZWZhdWx0IHBhcmFtZXRlcgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdjaGFuZ2VQYXJhbWV0ZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjaGFuZ2VQYXJhbWV0ZXIoaW5kZXgsIG5ld1ZhbHVlKSB7CiAgICAgICAgICAgIHRoaXMucGFyYW1ldGVyc1tpbmRleF0uZGVmYXVsdFBhcmFtZXRlclZhbHVlLnZhbHVlID0gbmV3VmFsdWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGVzIGFuIGFycmF5IGZyb20gdGhlIHBhcmFtZXRlciBhcnJheSB3aGljaCBpcyBpbiB0aGUgY3VycmVudCBzdGF0ZQogICAgICAgICAqIEByZXR1cm5zIHthcnJheX0KICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAncGFyYW1ldGVyc1RvU3VibWl0QXJyYXknLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBwYXJhbWV0ZXJzVG9TdWJtaXRBcnJheSgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyYW1ldGVycy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgICAgICAgICAgIHZhciBwYXJhbWV0ZXIgPSB7IG5hbWU6IGl0ZW0ubmFtZSwgdmFsdWU6IGl0ZW0uZGVmYXVsdFBhcmFtZXRlclZhbHVlLnZhbHVlIH07CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyYW1ldGVyOwogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY291bnQnLAogICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJhbWV0ZXJzID8gdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aCA6IDA7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBQYXJhbWV0ZXJTZXJ2aWNlOwp9KCksIChfZGVzY3JpcHRvciA9IF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ3BhcmFtZXRlcnMnLCBbX21vYngub2JzZXJ2YWJsZV0sIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBpbml0aWFsaXplcjogZnVuY3Rpb24gaW5pdGlhbGl6ZXIoKSB7CiAgICAgICAgcmV0dXJuIFtdOwogICAgfQp9KSwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAnaW5pdCcsIFtfbW9ieC5hY3Rpb25dLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdpbml0JyksIF9jbGFzcy5wcm90b3R5cGUpLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdhZGRQYXJhbWV0ZXInLCBbX21vYnguYWN0aW9uXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAnYWRkUGFyYW1ldGVyJyksIF9jbGFzcy5wcm90b3R5cGUpLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdhZGRQYXJhbWV0ZXJzJywgW19tb2J4LmFjdGlvbl0sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ2FkZFBhcmFtZXRlcnMnKSwgX2NsYXNzLnByb3RvdHlwZSksIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ2NoYW5nZVBhcmFtZXRlcicsIFtfbW9ieC5hY3Rpb25dLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdjaGFuZ2VQYXJhbWV0ZXInKSwgX2NsYXNzLnByb3RvdHlwZSksIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ2NvdW50JywgW19tb2J4LmNvbXB1dGVkXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAnY291bnQnKSwgX2NsYXNzLnByb3RvdHlwZSkpLCBfY2xhc3MpOwp9LHsibW9ieCI6Mzg5fV0sNDA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKCnZhciBfcmVzdCA9IHJlcXVpcmUoJy4vcmVzdCcpOwoKdmFyIF9yZXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3Jlc3QpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmV4cG9ydHMuZGVmYXVsdCA9IHsKICAgIHJlc3Q6IF9yZXN0Mi5kZWZhdWx0Cn07Cn0seyIuL3Jlc3QiOjQxfV0sNDE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKLyoqCiAqIFRoaXMgb2JqZWN0IGRlZmluZXMgcmVzdCBwYXRocwogKi8KZXhwb3J0cy5kZWZhdWx0ID0gewogICAgX2NvbnZlcnRTbGFzaGVzOiBmdW5jdGlvbiBfY29udmVydFNsYXNoZXMocGlwZWxpbmUpIHsKICAgICAgICByZXR1cm4gcGlwZWxpbmUucmVwbGFjZSgvXC8vZywgJy9waXBlbGluZXMvJyk7CiAgICB9LAogICAgYXBpUm9vdDogZnVuY3Rpb24gYXBpUm9vdCgpIHsKICAgICAgICByZXR1cm4gJy9ibHVlL3Jlc3QnOwogICAgfSwKICAgIG9yZ2FuaXphdGlvblBpcGVsaW5lczogZnVuY3Rpb24gb3JnYW5pemF0aW9uUGlwZWxpbmVzKG9yZ2FuaXphdGlvbk5hbWUpIHsKICAgICAgICByZXR1cm4gdGhpcy5hcGlSb290KCkgKyAnL3NlYXJjaC8/cT10eXBlOnBpcGVsaW5lO29yZ2FuaXphdGlvbjonICsgZW5jb2RlVVJJQ29tcG9uZW50KG9yZ2FuaXphdGlvbk5hbWUpICsgJztleGNsdWRlZEZyb21GbGF0dGVuaW5nOmplbmtpbnMuYnJhbmNoLk11bHRpQnJhbmNoUHJvamVjdCxodWRzb24ubWF0cml4Lk1hdHJpeFByb2plY3QmZmlsdGVyPW5vLWZvbGRlcnMnOwogICAgfSwKICAgIGFsbFBpcGVsaW5lczogZnVuY3Rpb24gYWxsUGlwZWxpbmVzKCkgewogICAgICAgIHJldHVybiB0aGlzLmFwaVJvb3QoKSArICcvc2VhcmNoLz9xPXR5cGU6cGlwZWxpbmU7ZXhjbHVkZWRGcm9tRmxhdHRlbmluZzpqZW5raW5zLmJyYW5jaC5NdWx0aUJyYW5jaFByb2plY3QsaHVkc29uLm1hdHJpeC5NYXRyaXhQcm9qZWN0JmZpbHRlcj1uby1mb2xkZXJzJzsKICAgIH0sCiAgICBhY3Rpdml0aWVzOiBmdW5jdGlvbiBhY3Rpdml0aWVzKG9yZ2FuaXphdGlvbiwgcGlwZWxpbmUsIGJyYW5jaCkgewogICAgICAgIHZhciBicmFuY2hTdHIgPSBicmFuY2ggPyAnP2JyYW5jaD0nICsgYnJhbmNoIDogJyc7CiAgICAgICAgcmV0dXJuIHRoaXMuYXBpUm9vdCgpICsgJy9vcmdhbml6YXRpb25zLycgKyBlbmNvZGVVUklDb21wb25lbnQob3JnYW5pemF0aW9uKSArICcvcGlwZWxpbmVzLycgKyBwaXBlbGluZSArICcvYWN0aXZpdGllcy8nICsgYnJhbmNoU3RyOwogICAgfSwKICAgIHJ1bjogZnVuY3Rpb24gcnVuKF9yZWYpIHsKICAgICAgICB2YXIgb3JnYW5pemF0aW9uID0gX3JlZi5vcmdhbml6YXRpb24sCiAgICAgICAgICAgIHBpcGVsaW5lID0gX3JlZi5waXBlbGluZSwKICAgICAgICAgICAgYnJhbmNoID0gX3JlZi5icmFuY2gsCiAgICAgICAgICAgIHJ1bklkID0gX3JlZi5ydW5JZDsKCiAgICAgICAgaWYgKGJyYW5jaCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5waXBlbGluZShvcmdhbml6YXRpb24sIHBpcGVsaW5lKSArICdicmFuY2hlcy8nICsgZW5jb2RlVVJJQ29tcG9uZW50KGVuY29kZVVSSUNvbXBvbmVudChicmFuY2gpKSArICcvcnVucy8nICsgcnVuSWQgKyAnLyc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdGhpcy5waXBlbGluZShvcmdhbml6YXRpb24sIHBpcGVsaW5lKSArICdydW5zLycgKyBydW5JZCArICcvJzsKICAgIH0sCiAgICBwaXBlbGluZTogZnVuY3Rpb24gcGlwZWxpbmUob3JnYW5pemF0aW9uLCBfcGlwZWxpbmUpIHsKICAgICAgICByZXR1cm4gdGhpcy5hcGlSb290KCkgKyAnL29yZ2FuaXphdGlvbnMvJyArIGVuY29kZVVSSUNvbXBvbmVudChvcmdhbml6YXRpb24pICsgJy9waXBlbGluZXMvJyArIHRoaXMuX2NvbnZlcnRTbGFzaGVzKF9waXBlbGluZSkgKyAnLyc7CiAgICB9LAogICAgYnJhbmNoZXM6IGZ1bmN0aW9uIGJyYW5jaGVzKG9yZ2FuaXphdGlvbiwgcGlwZWxpbmUpIHsKICAgICAgICByZXR1cm4gdGhpcy5hcGlSb290KCkgKyAnL29yZ2FuaXphdGlvbnMvJyArIGVuY29kZVVSSUNvbXBvbmVudChvcmdhbml6YXRpb24pICsgJy9waXBlbGluZXMvJyArIHBpcGVsaW5lICsgJy9icmFuY2hlcy8/ZmlsdGVyPW9yaWdpbic7CiAgICB9LAogICAgcHVsbFJlcXVlc3RzOiBmdW5jdGlvbiBwdWxsUmVxdWVzdHMob3JnYW5pemF0aW9uLCBwaXBlbGluZSkgewogICAgICAgIHJldHVybiB0aGlzLmFwaVJvb3QoKSArICcvb3JnYW5pemF0aW9ucy8nICsgZW5jb2RlVVJJQ29tcG9uZW50KG9yZ2FuaXphdGlvbikgKyAnL3BpcGVsaW5lcy8nICsgcGlwZWxpbmUgKyAnL2JyYW5jaGVzLz9maWx0ZXI9cHVsbC1yZXF1ZXN0cyc7CiAgICB9LAogICAgcXVldWVkSXRlbTogZnVuY3Rpb24gcXVldWVkSXRlbShvcmdhbml6YXRpb24sIHBpcGVsaW5lLCBxdWV1ZUlkKSB7CiAgICAgICAgcmV0dXJuIHRoaXMucGlwZWxpbmUob3JnYW5pemF0aW9uLCBwaXBlbGluZSkgKyAncXVldWUvJyArIHF1ZXVlSWQgKyAnLyc7CiAgICB9Cn07Cn0se31dLDQyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuUnVuQXBpID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7IC8qKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogQ3JlYXRlZCBieSBjbWV5ZXJzIG9uIDgvMjkvMTYuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCgp2YXIgX2ZldGNoID0gcmVxdWlyZSgnLi4vZmV0Y2gnKTsKCnZhciBfdXJsY29uZmlnID0gcmVxdWlyZSgnLi4vdXJsY29uZmlnJyk7Cgp2YXIgX3VybGNvbmZpZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF91cmxjb25maWcpOwoKdmFyIF91dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7Cgp2YXIgX3V0aWxzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3V0aWxzKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCnZhciBSdW5BcGkgPSBleHBvcnRzLlJ1bkFwaSA9IGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFJ1bkFwaSgpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUnVuQXBpKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoUnVuQXBpLCBbewogICAgICAgIGtleTogJ3N0YXJ0UnVuJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gc3RhcnRSdW4oaXRlbSkgewogICAgICAgICAgICB2YXIgcGF0aCA9IF91cmxjb25maWcyLmRlZmF1bHQuZ2V0SmVua2luc1Jvb3RVUkwoKTsKICAgICAgICAgICAgdmFyIHJ1blVybCA9IF91dGlsczIuZGVmYXVsdC5jbGVhblNsYXNoZXMocGF0aCArICcvJyArIGl0ZW0uX2xpbmtzLnNlbGYuaHJlZiArICcvcnVucy8nKTsKCiAgICAgICAgICAgIHZhciBmZXRjaE9wdGlvbnMgPSB7CiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJywKICAgICAgICAgICAgICAgIGhlYWRlcnM6IHsKICAgICAgICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICAgICAgICByZXR1cm4gX2ZldGNoLkZldGNoLmZldGNoSlNPTihydW5VcmwsIHsgZmV0Y2hPcHRpb25zOiBmZXRjaE9wdGlvbnMgfSk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3N0b3BSdW4nLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzdG9wUnVuKHJ1bikgewogICAgICAgICAgICB2YXIgcGF0aCA9IF91cmxjb25maWcyLmRlZmF1bHQuZ2V0SmVua2luc1Jvb3RVUkwoKTsKICAgICAgICAgICAgdmFyIHJ1blVybCA9IHJ1bi5fbGlua3Muc2VsZi5ocmVmOwogICAgICAgICAgICB2YXIgc3RvcFVybCA9IF91dGlsczIuZGVmYXVsdC5jbGVhblNsYXNoZXMocGF0aCArICcvJyArIHJ1blVybCArICcvc3RvcC8/YmxvY2tpbmc9dHJ1ZSZ0aW1lT3V0SW5TZWNzPTEwJyk7CgogICAgICAgICAgICB2YXIgZmV0Y2hPcHRpb25zID0gewogICAgICAgICAgICAgICAgbWV0aG9kOiAnUFVUJywKICAgICAgICAgICAgICAgIGhlYWRlcnM6IHsKICAgICAgICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICAgICAgICByZXR1cm4gX2ZldGNoLkZldGNoLmZldGNoKHN0b3BVcmwsIHsgZmV0Y2hPcHRpb25zOiBmZXRjaE9wdGlvbnMgfSk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3JlbW92ZUZyb21RdWV1ZScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbW92ZUZyb21RdWV1ZShxdWV1ZUl0ZW0pIHsKICAgICAgICAgICAgdmFyIHBhdGggPSBfdXJsY29uZmlnMi5kZWZhdWx0LmdldEplbmtpbnNSb290VVJMKCk7CiAgICAgICAgICAgIHZhciBxdWV1ZUl0ZW1VcmwgPSB2b2lkIDA7CgogICAgICAgICAgICAvLyBhIHF1ZXVlIGl0ZW0gaXMgYSAicHNldWRvIHJ1biIgd2l0aCB0aGUgcXVldWUgaHJlZiBhdHRhY2hlZCB2aWEgX2l0ZW0KICAgICAgICAgICAgaWYgKHF1ZXVlSXRlbS5faXRlbSAmJiBxdWV1ZUl0ZW0uX2l0ZW0uX2xpbmtzKSB7CiAgICAgICAgICAgICAgICBxdWV1ZUl0ZW1VcmwgPSBxdWV1ZUl0ZW0uX2l0ZW0uX2xpbmtzLnNlbGYuaHJlZjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignY291bGQgbm90IGV4dHJhY3QgZGF0YSB0byByZW1vdmUgaXRlbSBmcm9tIHF1ZXVlOyBhYm9ydGluZycpOwogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciByZW1vdmVRdWV1ZVVybCA9IF91dGlsczIuZGVmYXVsdC5jbGVhblNsYXNoZXMocGF0aCArICcvJyArIHF1ZXVlSXRlbVVybCk7CgogICAgICAgICAgICB2YXIgZmV0Y2hPcHRpb25zID0gewogICAgICAgICAgICAgICAgbWV0aG9kOiAnREVMRVRFJywKICAgICAgICAgICAgICAgIGhlYWRlcnM6IHsKICAgICAgICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICAgICAgICByZXR1cm4gX2ZldGNoLkZldGNoLmZldGNoKHJlbW92ZVF1ZXVlVXJsLCB7IGZldGNoT3B0aW9uczogZmV0Y2hPcHRpb25zIH0pOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdyZXBsYXlSdW4nLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZXBsYXlSdW4ocnVuKSB7CiAgICAgICAgICAgIHZhciBwYXRoID0gX3VybGNvbmZpZzIuZGVmYXVsdC5nZXRKZW5raW5zUm9vdFVSTCgpOwogICAgICAgICAgICB2YXIgcnVuVXJsID0gcnVuLl9saW5rcy5zZWxmLmhyZWY7CiAgICAgICAgICAgIHZhciByZXBsYXlQaXBlbGluZVVybCA9IF91dGlsczIuZGVmYXVsdC5jbGVhblNsYXNoZXMocGF0aCArICcvJyArIHJ1blVybCArICcvcmVwbGF5LycpOwoKICAgICAgICAgICAgdmFyIGZldGNoT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLAogICAgICAgICAgICAgICAgaGVhZGVyczogewogICAgICAgICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHJldHVybiBfZmV0Y2guRmV0Y2guZmV0Y2hKU09OKHJlcGxheVBpcGVsaW5lVXJsLCB7IGZldGNoT3B0aW9uczogZmV0Y2hPcHRpb25zIH0pOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gUnVuQXBpOwp9KCk7Cn0seyIuLi9mZXRjaCI6MjIsIi4uL3VybGNvbmZpZyI6NTgsIi4uL3V0aWxzIjo1OX1dLDQzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKKGZ1bmN0aW9uIChnbG9iYWwpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gInN5bWJvbCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gInN5bWJvbCIgOiB0eXBlb2Ygb2JqOyB9OwoKLyoKICogVGhlIE1JVCBMaWNlbnNlCiAqCiAqIENvcHlyaWdodCAoYykgMjAxNiwgQ2xvdWRCZWVzLCBJbmMuCiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwogKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwogKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgogKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQogKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KICogVEhFIFNPRlRXQVJFLgogKi8KCnZhciByb290ID0gZXhwb3J0cy5yb290ID0gKHR5cGVvZiBzZWxmID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihzZWxmKSkgPT09ICdvYmplY3QnICYmIHNlbGYuc2VsZiA9PT0gc2VsZiAmJiBzZWxmIHx8ICh0eXBlb2YgZ2xvYmFsID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihnbG9iYWwpKSA9PT0gJ29iamVjdCcgJiYgZ2xvYmFsLmdsb2JhbCA9PT0gZ2xvYmFsICYmIGdsb2JhbCB8fCB1bmRlZmluZWQ7CgovLwovLyBTZWUgYmx1ZW9jZWFuLWNvbmZpZy9zcmMvbWFpbi9qYXZhL2lvL2plbmtpbnMvYmx1ZW9jZWFuL2NvbmZpZy9CbHVlT2NlYW5Db25maWcuamF2YQovLyBhbmQgYmx1ZW9jZWFuLWNvbmZpZy9zcmMvbWFpbi9yZXNvdXJjZXMvaW8vamVua2lucy9ibHVlb2NlYW4vY29uZmlnL0JsdWVPY2VhbkNvbmZpZy9oZWFkZXIuamVsbHkKLy8KdmFyIGJsdWVvY2VhbiA9IGV4cG9ydHMuYmx1ZW9jZWFuID0gcm9vdC4kYmx1ZW9jZWFuIHx8IHt9OwoKdmFyIHByZWZldGNoZGF0YSA9IGV4cG9ydHMucHJlZmV0Y2hkYXRhID0gYmx1ZW9jZWFuLnByZWZldGNoZGF0YSB8fCB7fTsKCgp9KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gInVuZGVmaW5lZCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gInVuZGVmaW5lZCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gInVuZGVmaW5lZCIgPyB3aW5kb3cgOiB7fSkKfSx7fV0sNDQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKCnZhciBfY29uZmlnID0gcmVxdWlyZSgnLi9jb25maWcnKTsKCnZhciBfY29uZmlnMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2NvbmZpZyk7Cgp2YXIgX1VzZXIgPSByZXF1aXJlKCcuL1VzZXInKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgovKioKICogUmV0dXJucyBhIGtleSBvZiBwZXJtaXNzaW9ucyBmdW5jdGlvbnMgdGhhdCBlYWNoIHJldHVybiBib29sZWFuIHRvIGluZGljYXRlIGF1dGhvcml6YXRpb24uCiAqIFVzYWdlOgogKiAgICAgIHBlcm1pdChwaXBlbGluZSkuY3JlYXRlKCk7CiAqCiAqIEBwYXJhbSBzdWJqZWN0CiAqIEByZXR1cm5zIHt7cmVhZDogKGZ1bmN0aW9uKCkpLCBjcmVhdGU6IChmdW5jdGlvbigpKSwgc3RhcnQ6IChmdW5jdGlvbigpKSwgc3RvcDogKGZ1bmN0aW9uKCkpfX0KICovCi8qKgogKiBDcmVhdGVkIGJ5IGNtZXllcnMgb24gOS8xNi8xNi4KICovCgp2YXIgcGVybWl0ID0gZnVuY3Rpb24gcGVybWl0KHN1YmplY3QpIHsKICAgIHZhciBjaGVja1Blcm1pc3Npb25zID0gZnVuY3Rpb24gY2hlY2tQZXJtaXNzaW9ucyhwZXJtaXNzaW9uTmFtZSkgewogICAgICAgIHJldHVybiBzdWJqZWN0ICYmIHN1YmplY3QucGVybWlzc2lvbnMgJiYgISFzdWJqZWN0LnBlcm1pc3Npb25zW3Blcm1pc3Npb25OYW1lXTsKICAgIH07CgogICAgcmV0dXJuIHsKICAgICAgICByZWFkOiBmdW5jdGlvbiByZWFkKCkgewogICAgICAgICAgICByZXR1cm4gY2hlY2tQZXJtaXNzaW9ucygncmVhZCcpOwogICAgICAgIH0sCiAgICAgICAgY29uZmlndXJlOiBmdW5jdGlvbiBjb25maWd1cmUoKSB7CiAgICAgICAgICAgIHJldHVybiBjaGVja1Blcm1pc3Npb25zKCdjb25maWd1cmUnKTsKICAgICAgICB9LAogICAgICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKCkgewogICAgICAgICAgICByZXR1cm4gY2hlY2tQZXJtaXNzaW9ucygnY3JlYXRlJyk7CiAgICAgICAgfSwKICAgICAgICBzdGFydDogZnVuY3Rpb24gc3RhcnQoKSB7CiAgICAgICAgICAgIHJldHVybiBjaGVja1Blcm1pc3Npb25zKCdzdGFydCcpOwogICAgICAgIH0sCiAgICAgICAgc3RvcDogZnVuY3Rpb24gc3RvcCgpIHsKICAgICAgICAgICAgcmV0dXJuIGNoZWNrUGVybWlzc2lvbnMoJ3N0b3AnKTsKICAgICAgICB9CiAgICB9Owp9OwoKZnVuY3Rpb24gaXNTZWN1cml0eUVuYWJsZWQoKSB7CiAgICByZXR1cm4gISFfY29uZmlnMi5kZWZhdWx0LmdldFNlY3VyaXR5Q29uZmlnKCkuZW5hYmxlZDsKfQoKZnVuY3Rpb24gaXNBbm9ueW1vdXNVc2VyKCkgewogICAgcmV0dXJuIF9Vc2VyLlVzZXIuY3VycmVudCgpLmlzQW5vbnltb3VzKCk7Cn0KCmV4cG9ydHMuZGVmYXVsdCA9IHsKICAgIHBlcm1pdDogcGVybWl0LAogICAgaXNTZWN1cml0eUVuYWJsZWQ6IGlzU2VjdXJpdHlFbmFibGVkLAogICAgaXNBbm9ueW1vdXNVc2VyOiBpc0Fub255bW91c1VzZXIKfTsKfSx7Ii4vVXNlciI6NywiLi9jb25maWciOjIxfV0sNDU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5BY3Rpdml0eVNlcnZpY2UgPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfUGFnZXIgPSByZXF1aXJlKCcuL1BhZ2VyJyk7Cgp2YXIgX3Jlc3QgPSByZXF1aXJlKCcuLi9wYXRocy9yZXN0Jyk7Cgp2YXIgX3Jlc3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVzdCk7Cgp2YXIgX2ZldGNoID0gcmVxdWlyZSgnLi4vZmV0Y2gnKTsKCnZhciBfQnVua2VyU2VydmljZTIgPSByZXF1aXJlKCcuL0J1bmtlclNlcnZpY2UnKTsKCnZhciBfdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpOwoKdmFyIF91dGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF91dGlscyk7Cgp2YXIgX21vYnhVdGlscyA9IHJlcXVpcmUoJ21vYngtdXRpbHMnKTsKCnZhciBfbW9ieFV0aWxzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21vYnhVdGlscyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9CgovKgogKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGFjdGl2aXR5IHJlbGF0ZWQgc2VydmljZXMuCiAqCiAqIEBleHBvcnQKICogQGNsYXNzIEFjdGl2aXR5U2VydmljZQogKiBAZXh0ZW5kcyB7QnVua2VyU2VydmljZX0KICovCnZhciBBY3Rpdml0eVNlcnZpY2UgPSBleHBvcnRzLkFjdGl2aXR5U2VydmljZSA9IGZ1bmN0aW9uIChfQnVua2VyU2VydmljZSkgewogICAgX2luaGVyaXRzKEFjdGl2aXR5U2VydmljZSwgX0J1bmtlclNlcnZpY2UpOwoKICAgIGZ1bmN0aW9uIEFjdGl2aXR5U2VydmljZSgpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQWN0aXZpdHlTZXJ2aWNlKTsKCiAgICAgICAgcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChBY3Rpdml0eVNlcnZpY2UuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihBY3Rpdml0eVNlcnZpY2UpKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoQWN0aXZpdHlTZXJ2aWNlLCBbewogICAgICAgIGtleTogJ3BhZ2VyS2V5JywKCiAgICAgICAgLyoqCiAgICAgICAgICogR2VuZXJhdGVzIGEgcGFnZXIga2V5IGZvciBbQGxpbmsgUGFnZXJTZXJ2aWNlXSB0byBzdG9yZSB0aGUgW0BsaW5rIFBhZ2VyXSB1bmRlci4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcmdhbml6YXRpb24gSmVua2lucyBvcmdhbml6YXRpb24gdGhhdCB0aGlzIHBhZ2VyIGJlbG9uZ3MgdG8uCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHBpcGVsaW5lIFBpcGVsaW5lIHRoYXQgdGhpcyBwYWdlciBiZWxvbmdzIHRvLgogICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBicmFuY2ggT3B0aW9uYWwgYnJhbmNoIHRoYXQgdGhpcyBwYWdlciBiZWxvbmdzIHRvLgogICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IGtleSBmb3IgW0BsaW5rIFBhZ2VyU2VydmljZV0KICAgICAgICAgKi8KICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcGFnZXJLZXkob3JnYW5pemF0aW9uLCBwaXBlbGluZSwgYnJhbmNoKSB7CiAgICAgICAgICAgIHJldHVybiAnQWN0aXZpdGllcy8nICsgb3JnYW5pemF0aW9uICsgJy0nICsgcGlwZWxpbmUgKyAnLScgKyBicmFuY2g7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBHZXRzIHRoZSBhY3Rpdml0eSBwYWdlcgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IG9yZ2FuaXphdGlvbiBKZW5raW5zIG9yZ2FuaXphdGlvbiB0aGF0IHRoaXMgcGFnZXIgYmVsb25ncyB0by4KICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGlwZWxpbmUgUGlwZWxpbmUgdGhhdCB0aGlzIHBhZ2VyIGJlbG9uZ3MgdG8uCiAgICAgICAgICogQHJldHVybnMge1BhZ2VyfSBQYWdlciBmb3IgdGhpcyBwaXBlbG5lLgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdhY3Rpdml0eVBhZ2VyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gYWN0aXZpdHlQYWdlcihvcmdhbml6YXRpb24sIHBpcGVsaW5lLCBicmFuY2gpIHsKICAgICAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7CgogICAgICAgICAgICByZXR1cm4gdGhpcy5wYWdlclNlcnZpY2UuZ2V0UGFnZXIoewogICAgICAgICAgICAgICAga2V5OiB0aGlzLnBhZ2VyS2V5KG9yZ2FuaXphdGlvbiwgcGlwZWxpbmUsIGJyYW5jaCksCiAgICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgICAqIExhemlseSBnZW5lcmF0ZSB0aGUgcGFnZXIgaW5jYXNlIGl0cyBuZWVkZWQuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGxhenlQYWdlcjogZnVuY3Rpb24gbGF6eVBhZ2VyKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgX1BhZ2VyLlBhZ2VyKF9yZXN0Mi5kZWZhdWx0LmFjdGl2aXRpZXMob3JnYW5pemF0aW9uLCBwaXBlbGluZSwgYnJhbmNoKSwgMjUsIF90aGlzMik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogTWFwcyBxdWV1ZWQgZGF0YSBpbnRvIGEgcHN1ZGVvcnVuCiAgICAgICAgICoKICAgICAgICAgKiBAc2VlIF9tYXBRdWV1ZVRvUHN1ZWRvUnVuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YSBSYXcgZGF0YSBmcm9tIGV4dGVuYWwgc291cmNlLgogICAgICAgICAqIEByZXR1cm5zIEEgcnVuIG9yIHBzdWRlb3J1bi4KICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnYnVua2VyTWFwcGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gYnVua2VyTWFwcGVyKGRhdGEpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21hcFF1ZXVlVG9Qc3VlZG9SdW4oZGF0YSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBHZXRzIGFuIGFjdGl2aXR5IGZyb20gdGhlIHN0b3JlLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGhyZWYgU2VsZiBocmVmIGZvciBhY3Rpdml0eS4KICAgICAgICAgKiBAcmV0dXJucyB7b2JqZWN0fSBNb2J4IGNvbXB1dGVkIHZhbHVlCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ2dldEFjdGl2aXR5JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0QWN0aXZpdHkoaHJlZikgewogICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRJdGVtKGhyZWYpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogRmV0Y2hlcyBhbiBhY3Rpdml0eSBmcm9tIHJlc3QgYXBpLgogICAgICAgICAqCiAgICAgICAgICogTm90ZTogVGhpcyBvbmx5IHdvcmtzIGZvciBhY3Rpdml0aWVzIHRoYXQgYXJlIG5vdCBpbiB0aGUgcXVldWUuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gaHJlZiBzZWxmIGhyZWYgb2YgYWN0aXZpdHkuCiAgICAgICAgICogQHBhcmFtIHtib29sZWFufSB1c2VDYWNoZSBVc2UgdGhlIGNhY2hlIHRvIGxvb2t1cCBkYXRhIG9yIGFsd2F5cyBmZXRjaCBhIG5ldyBvbmUuCiAgICAgICAgICogQHBhcmFtIHtib29sZWFufSBvdmVycmlkZVF1ZXVlZFN0YXRlIEhhY2sgdG8gbWFrZSBTU0Ugd29yay4gTm90IHVzZSB1bmxlc3MgeW91IGtub3cgd2hhdCB5b3UgYXJlIGRvaW5nISEhCiAgICAgICAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2Ugb2YgZmV0Y2hlZCBkYXRhLgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdmZXRjaEFjdGl2aXR5JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZmV0Y2hBY3Rpdml0eShocmVmKSB7CiAgICAgICAgICAgIHZhciBfdGhpczMgPSB0aGlzOwoKICAgICAgICAgICAgdmFyIF9yZWYgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9LAogICAgICAgICAgICAgICAgdXNlQ2FjaGUgPSBfcmVmLnVzZUNhY2hlLAogICAgICAgICAgICAgICAgb3ZlcnJpZGVRdWV1ZWRTdGF0ZSA9IF9yZWYub3ZlcnJpZGVRdWV1ZWRTdGF0ZTsKCiAgICAgICAgICAgIGlmICh1c2VDYWNoZSAmJiB0aGlzLmhhc0l0ZW0oaHJlZikpIHsKICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5nZXRJdGVtKGhyZWYpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIF9mZXRjaC5GZXRjaC5mZXRjaEpTT04oaHJlZikudGhlbihmdW5jdGlvbiAoZGF0YSkgewogICAgICAgICAgICAgICAgLy8gU2hvdWxkIHJlYWxseSBoYXZlIGRlZHVwZSBvbiBtZXRob2RzIGxpa2UgdGhlc2UsIGJ1dCBmb3Igbm93CiAgICAgICAgICAgICAgICAvLyBqdXN0IGNsb25lIGRhdGEgc28gdGhhdCB3ZSBkb250IG1vZGlmeSBvdGhlciBpbnN0YW5jZXMuCiAgICAgICAgICAgICAgICB2YXIgcnVuID0gX3V0aWxzMi5kZWZhdWx0LmNsb25lKGRhdGEpOwoKICAgICAgICAgICAgICAgIC8vIFVnbHkgaGFjayB0byBtYWtlIFNTRSB3b3JrLgogICAgICAgICAgICAgICAgaWYgKG92ZXJyaWRlUXVldWVkU3RhdGUpIHsKICAgICAgICAgICAgICAgICAgICBydW4uc3RhdGUgPSAnUlVOTklORyc7CiAgICAgICAgICAgICAgICAgICAgcnVuLnJlc3VsdCA9ICdVTktOT1dOJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczMuc2V0SXRlbShydW4pOwogICAgICAgICAgICB9KS5jYXRjaChmdW5jdGlvbiAoZXJyKSB7CiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVGhlcmUgaGFzIGJlZW4gYW4gZXJyb3Igd2hpbGUgdHJ5aW5nIHRvIGdldCB0aGUgZGF0YS4nLCBlcnIpOyAvLyBGSVhNRTogSXZhbiB3aGF0IGlzIHRoZSB3YXkgdG8gcmV0dXJuIGFuICJlcnJvciIgb3BiamVjdCBzbyB1bmRlcmx5aW5nIGNvbXBvbmVudCBhcmUgYXdhcmUgb2YgdGhlIHByb2JsZW0gYW5kIGNhbiByZWFjdAogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEZldGNoZXMgYXJ0aWZhY3RzIGZvciBhIGdpdmVuIHJ1bi4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBydW5IcmVmIFRoZSBocmVmIG9mIHRoZSBydW4gdG8gZmV0Y2ZoIGFydGlmYWN0cyBmb3IuCiAgICAgICAgICogQHJldHVybnMge09iamVjdH0gT2JqZWN0IGNvbnRhaW5pbmcgemlwRmlsZSBsaW5rIGFuZCBsaXN0IG9mIGFydGlmYWN0cy4KICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnZmV0Y2hBcnRpZmFjdHMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmZXRjaEFydGlmYWN0cyhydW5IcmVmKSB7CiAgICAgICAgICAgIHJldHVybiBfbW9ieFV0aWxzMi5kZWZhdWx0LmZyb21Qcm9taXNlKF9mZXRjaC5GZXRjaC5mZXRjaEpTT04ocnVuSHJlZiArICdhcnRpZmFjdHMvP3N0YXJ0PTAmbGltaXQ9MTAxJykpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGhpcyBmdW5jdGlvbiBtYXBzIGEgcXVldWUgaXRlbSBpbnRvIGEgcnVuIGluc3RhbmNjZS4KICAgICAgICAgKgogICAgICAgICAqIFdlIGRvIHRoaXMgYmVjYXVzZSB0aGUgYXBpIHJldHVybnMgdXMgcXVldWVkIGl0ZW1zIGFzIHdlbGwKICAgICAgICAgKiBhcyBydW5zIGFuZCBpdHMgZWFzaWVyIHRvIGRlYWwgd2l0aCB0aGVtIGlmIHRoZXkgYXJlIG1vZGVsZWQKICAgICAgICAgKiBhcyB0aGUgc2FtZSB0aGluZy4gSWYgdGhlIHJhdyBkYXRhIGlzIG5lZWRlZCBpZiBjYW4gYmUgZmV0Y2hlZAogICAgICAgICAqIGZyb20gX2l0ZW0uCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge29iamVjdH0gcnVuIFJhdyBkYXRhIGZyb20gYXBpLgogICAgICAgICAqIEByZXR1cm5zIHBzdWRlb3J1bgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdfbWFwUXVldWVUb1BzdWVkb1J1bicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9tYXBRdWV1ZVRvUHN1ZWRvUnVuKHJ1bikgewogICAgICAgICAgICBpZiAocnVuLl9jbGFzcyA9PT0gJ2lvLmplbmtpbnMuYmx1ZW9jZWFuLnNlcnZpY2UuZW1iZWRkZWQucmVzdC5RdWV1ZUl0ZW1JbXBsJykgewogICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICBpZDogU3RyaW5nKHJ1bi5leHBlY3RlZEJ1aWxkTnVtYmVyKSwKICAgICAgICAgICAgICAgICAgICBzdGF0ZTogJ1FVRVVFRCcsCiAgICAgICAgICAgICAgICAgICAgcGlwZWxpbmU6IHJ1bi5waXBlbGluZSwKICAgICAgICAgICAgICAgICAgICB0eXBlOiAnUXVldWVkSXRlbScsCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0OiAnVU5LTk9XTicsCiAgICAgICAgICAgICAgICAgICAgam9iX3J1bl9xdWV1ZUlkOiBydW4uaWQsCiAgICAgICAgICAgICAgICAgICAgZW5RdWV1ZVRpbWU6IHJ1bi5xdWV1ZWRUaW1lLAogICAgICAgICAgICAgICAgICAgIG9yZ2FuaXphdGlvbjogcnVuLm9yZ2FuaXphdGlvbiwKICAgICAgICAgICAgICAgICAgICBjaGFuZ2VTZXQ6IFtdLAogICAgICAgICAgICAgICAgICAgIF9saW5rczogewogICAgICAgICAgICAgICAgICAgICAgICBzZWxmOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBocmVmOiBydW4uX2xpbmtzLnBhcmVudC5ocmVmICsgJ3J1bnMvJyArIHJ1bi5leHBlY3RlZEJ1aWxkTnVtYmVyICsgJy8nCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudDogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaHJlZjogcnVuLl9saW5rcy5wYXJlbnQuaHJlZgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBfaXRlbTogcnVuCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBydW47CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDYWxjdWxhdGUgYW4gZXhwZWN0ZWQgYnVpbGQgbnVtYmVyIGZvciBhIHF1ZXVlZCBpdGVtLgogICAgICAgICAqCiAgICAgICAgICogVE9ETzogRW5oYW5jZSBTU0Ugc28gdGhhdCB0aGlzIGlzIGRvbmUgc2VydmVyIHNpZGUuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge2FueX0gZXZlbnQgU1NFIGV2ZW50LgogICAgICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IEV4cGVjdGVkIGJ1aWxkIG51bWJlcgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdnZXRFeHBlY3RlZEJ1aWxkTnVtYmVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0RXhwZWN0ZWRCdWlsZE51bWJlcihldmVudCkgewogICAgICAgICAgICB2YXIgcnVucyA9IHRoaXMuX2RhdGEudmFsdWVzKCk7CiAgICAgICAgICAgIHZhciBldmVudEpvYlVybCA9IGV2ZW50LmJsdWVvY2Vhbl9qb2JfcmVzdF91cmw7CiAgICAgICAgICAgIHZhciBuZXh0SWQgPSAwOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJ1bnMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBydW4gPSBydW5zW2ldOwogICAgICAgICAgICAgICAgaWYgKGV2ZW50Sm9iVXJsICE9PSBydW4uX2xpbmtzLnBhcmVudC5ocmVmKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAocnVuLmpvYl9ydW5fcXVldWVJZCA9PT0gZXZlbnQuam9iX3J1bl9xdWV1ZUlkKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gV2UgYWxyZWFkeSBoYXZlIGEgImR1bW15IiByZWNvcmQgZm9yIHRoaXMgcXVldWVkIGpvYgogICAgICAgICAgICAgICAgICAgIC8vIHJ1bi4gTm8gbmVlZCB0byBjcmVhdGUgYW5vdGhlciBpLmUuIGlnbm9yZSB0aGlzIGV2ZW50LgogICAgICAgICAgICAgICAgICAgIHJldHVybiBydW4uaWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAocGFyc2VJbnQocnVuLmlkLCAxMCkgPiBuZXh0SWQpIHsKICAgICAgICAgICAgICAgICAgICAvLyBmaWd1cmUgb3V0IHRoZSBuZXh0IGlkLCBleHBlY3RlZEJ1aWxkTnVtYmVyCiAgICAgICAgICAgICAgICAgICAgbmV4dElkID0gcGFyc2VJbnQocnVuLmlkLCAxMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBuZXh0SWQgKyAxOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gQWN0aXZpdHlTZXJ2aWNlOwp9KF9CdW5rZXJTZXJ2aWNlMi5CdW5rZXJTZXJ2aWNlKTsKfSx7Ii4uL2ZldGNoIjoyMiwiLi4vcGF0aHMvcmVzdCI6NDEsIi4uL3V0aWxzIjo1OSwiLi9CdW5rZXJTZXJ2aWNlIjo0NiwiLi9QYWdlciI6NDksIm1vYngtdXRpbHMiOjM4Nn1dLDQ2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLkJ1bmtlclNlcnZpY2UgPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfZGVzYywgX3ZhbHVlLCBfY2xhc3MsIF9kZXNjcmlwdG9yOwoKdmFyIF9tb2J4ID0gcmVxdWlyZSgnbW9ieCcpOwoKZnVuY3Rpb24gX2luaXREZWZpbmVQcm9wKHRhcmdldCwgcHJvcGVydHksIGRlc2NyaXB0b3IsIGNvbnRleHQpIHsKICBpZiAoIWRlc2NyaXB0b3IpIHJldHVybjsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eSwgewogICAgZW51bWVyYWJsZTogZGVzY3JpcHRvci5lbnVtZXJhYmxlLAogICAgY29uZmlndXJhYmxlOiBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSwKICAgIHdyaXRhYmxlOiBkZXNjcmlwdG9yLndyaXRhYmxlLAogICAgdmFsdWU6IGRlc2NyaXB0b3IuaW5pdGlhbGl6ZXIgPyBkZXNjcmlwdG9yLmluaXRpYWxpemVyLmNhbGwoY29udGV4dCkgOiB2b2lkIDAKICB9KTsKfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKHRhcmdldCwgcHJvcGVydHksIGRlY29yYXRvcnMsIGRlc2NyaXB0b3IsIGNvbnRleHQpIHsKICB2YXIgZGVzYyA9IHt9OwogIE9iamVjdFsna2UnICsgJ3lzJ10oZGVzY3JpcHRvcikuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7CiAgICBkZXNjW2tleV0gPSBkZXNjcmlwdG9yW2tleV07CiAgfSk7CiAgZGVzYy5lbnVtZXJhYmxlID0gISFkZXNjLmVudW1lcmFibGU7CiAgZGVzYy5jb25maWd1cmFibGUgPSAhIWRlc2MuY29uZmlndXJhYmxlOwoKICBpZiAoJ3ZhbHVlJyBpbiBkZXNjIHx8IGRlc2MuaW5pdGlhbGl6ZXIpIHsKICAgIGRlc2Mud3JpdGFibGUgPSB0cnVlOwogIH0KCiAgZGVzYyA9IGRlY29yYXRvcnMuc2xpY2UoKS5yZXZlcnNlKCkucmVkdWNlKGZ1bmN0aW9uIChkZXNjLCBkZWNvcmF0b3IpIHsKICAgIHJldHVybiBkZWNvcmF0b3IodGFyZ2V0LCBwcm9wZXJ0eSwgZGVzYykgfHwgZGVzYzsKICB9LCBkZXNjKTsKCiAgaWYgKGNvbnRleHQgJiYgZGVzYy5pbml0aWFsaXplciAhPT0gdm9pZCAwKSB7CiAgICBkZXNjLnZhbHVlID0gZGVzYy5pbml0aWFsaXplciA/IGRlc2MuaW5pdGlhbGl6ZXIuY2FsbChjb250ZXh0KSA6IHZvaWQgMDsKICAgIGRlc2MuaW5pdGlhbGl6ZXIgPSB1bmRlZmluZWQ7CiAgfQoKICBpZiAoZGVzYy5pbml0aWFsaXplciA9PT0gdm9pZCAwKSB7CiAgICBPYmplY3RbJ2RlZmluZScgKyAnUHJvcGVydHknXSh0YXJnZXQsIHByb3BlcnR5LCBkZXNjKTsKICAgIGRlc2MgPSBudWxsOwogIH0KCiAgcmV0dXJuIGRlc2M7Cn0KCmZ1bmN0aW9uIF9pbml0aWFsaXplcldhcm5pbmdIZWxwZXIoZGVzY3JpcHRvciwgY29udGV4dCkgewogIHRocm93IG5ldyBFcnJvcignRGVjb3JhdGluZyBjbGFzcyBwcm9wZXJ0eSBmYWlsZWQuIFBsZWFzZSBlbnN1cmUgdGhhdCB0cmFuc2Zvcm0tY2xhc3MtcHJvcGVydGllcyBpcyBlbmFibGVkLicpOwp9CgovKioKICogQWJzdHJhY3QgY2xhc3MgdXNlZCBieSBzZXJ2aWNlcyB0aGF0IG5lZWQgdG8gc3RvcmUgZGF0YSBpbiBhIGtleS92YWx1ZSBzdG9yZS4KICoKICogSXQgaXMgZGVzaWduZWQgdG8gc3RvcmUganNvbiBvYmplY3RzIGZyb20gYSByZXN0IGFwaS4KICoKICogQGV4cG9ydAogKiBAY2xhc3MgQnVua2VyU2VydmljZQogKi8KdmFyIEJ1bmtlclNlcnZpY2UgPSBleHBvcnRzLkJ1bmtlclNlcnZpY2UgPSAoX2NsYXNzID0gZnVuY3Rpb24gKCkgewoKICAvKioKICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIEJ1bmtlclNlcnZpY2UuCiAgICoKICAgKiBAcGFyYW0ge1BhZ2VyU2VydmljZX0gcGFnZXJTZXJ2aWNlCiAgICovCiAgZnVuY3Rpb24gQnVua2VyU2VydmljZShwYWdlclNlcnZpY2UpIHsKICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBCdW5rZXJTZXJ2aWNlKTsKCiAgICBfaW5pdERlZmluZVByb3AodGhpcywgJ19kYXRhJywgX2Rlc2NyaXB0b3IsIHRoaXMpOwoKICAgIHRoaXMucGFnZXJTZXJ2aWNlID0gcGFnZXJTZXJ2aWNlOwogIH0KCiAgLyoqCiAgICogRXh0cmFjdHMgdGhlIGtleSB0byBzdG9yZSB0aGUgZGFhdGEgdW5kZXIgb3V0IG9mIHRoZSBvYmplY3QKICAgKgogICAqIERlZmF1bHQgaW1wbCB1c2VzIHRoZSBzZWxmIGhyZWYgbGluayBpbiBCbHVlT2N1ZWFuIG9iamVjdHMuCiAgICoKICAgKiBAcGFyYW0ge29iamVjdH0gZGF0YSBEYXRhIHRvIGJlIHN0b3JlZCBvbmNlIGl0IGhhcyBiZWVuIHBhc3NlZCB0aHJvdWdoCiAgICogICAgICAgICAgICAgICAgICAgICAgW0BsaW5rIGJ1bmtlck1hcHBlcl0KICAgKiBAcmV0dXJucyB7YW55fSBUaGUga2V5IGZvciB0aGUgc3RvcmUuCiAgICovCgoKICBfY3JlYXRlQ2xhc3MoQnVua2VyU2VydmljZSwgW3sKICAgIGtleTogJ2J1bmtlcktleScsCiAgICB2YWx1ZTogZnVuY3Rpb24gYnVua2VyS2V5KGRhdGEpIHsKICAgICAgcmV0dXJuIGRhdGEuX2xpbmtzLnNlbGYuaHJlZjsKICAgIH0KCiAgICAvKioKICAgICAqIE1hcHMgdGhlIGRhdGEgZnJvbSB0aGUgc291cmNlIGludG8gd2hhdCBuZWVkcyB0byBiZSBzdG9yZWQuCiAgICAgKgogICAgICogRGVmYXVsdCBpbXBsIGlzIGlkZW50aXR5LgogICAgICoKICAgICAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhIFJhdyBkYXRhIGZyb20gZXh0ZXJuYWwgc291cmNlLgogICAgICogQHJldHVybnMge29iamVjdH0gTW9kaWZpZWQgZGF0YSBvYmplY3QuCiAgICAgKi8KCiAgfSwgewogICAga2V5OiAnYnVua2VyTWFwcGVyJywKICAgIHZhbHVlOiBmdW5jdGlvbiBidW5rZXJNYXBwZXIoZGF0YSkgewogICAgICByZXR1cm4gZGF0YTsKICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IHdpbGwgbWFrZSBhbGwgcGFnZXJzIHVzaW5nIHRoaXMgYnVua2VyIHJlZmV0Y2ggdGhlIGRhdGEKICAgICAqIHRoZXkgYXJlIGRpc3BsYXlpbmcuIFVzZWZ1bCBpZiBzb3J0aW5nIGNoYW5nZXMgKGZvciBleGFtcGxlIGEgbmV3IGl0ZW0gaXMgYWRkZWQpLgogICAgICovCgogIH0sIHsKICAgIGtleTogJ3JlZnJlc2hQYWdlcnMnLAogICAgdmFsdWU6IGZ1bmN0aW9uIHJlZnJlc2hQYWdlcnMoKSB7CiAgICAgIHRoaXMucGFnZXJTZXJ2aWNlLnJlZnJlc2godGhpcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGFuIGl0ZW0gaW4gdGhlIHN0b3JlLgogICAgICoKICAgICAqIEl0IHVzZXMgdGhlIFtAbGluayBidW5rZXJLZXldIGFuZCBbQGxpbmsgYnVua2VyTWFwcGVyXSB0byBnZW5lcmF0ZSB0aGUga2V5L3ZhbHVlCiAgICAgKiB0byBiZSBzdG9yZWQuCiAgICAgKgogICAgICogQHBhcmFtIHtPYmplY3R9IGl0ZW0gUmF3IGRhdGEgZnJvbSBleHRlbmFsIHNvdXJjZS4KICAgICAqIEByZXR1cm5zIHtPYmplY3R9IGl0ZW0gbWFwcGVkIGJ5IFtAbGluayBidW5rZXJNYXBwZXJdLiBJdCBpcyBhbHNvIGEgbW9ieCBjb21wdXRlZCB2YWx1ZS4KICAgICAqLwoKICB9LCB7CiAgICBrZXk6ICdzZXRJdGVtJywKICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRJdGVtKGl0ZW0pIHsKICAgICAgdmFyIG1hcHBlZEl0ZW0gPSAoMCwgX21vYngub2JzZXJ2YWJsZSkodGhpcy5idW5rZXJNYXBwZXIoaXRlbSkpOwogICAgICB2YXIga2V5SXRlbSA9IHRoaXMuYnVua2VyS2V5KG1hcHBlZEl0ZW0pOwogICAgICB0aGlzLl9kYXRhLnNldChrZXlJdGVtLCBtYXBwZWRJdGVtKTsKICAgICAgcmV0dXJuIHRoaXMuZ2V0SXRlbShrZXlJdGVtKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYW4gYXJyYXkgb24gaXRlbSBpbiB0aGUgc3RvcmUuIENhbGxzIFtAbGluayBzZXRJdGVtXSBmb3IgZXZlbiBpdGVtIGluIGFycmF5LgogICAgICoKICAgICAqIEBwYXJhbSB7T2JqZWN0W119IGl0ZW1zIEFycmF5IG9mIGl0ZW1zIHRvIHNldC4KICAgICAqIEByZXR1cm5zIHtPYmplY3RbXX0gQXJyYXkgb2YgbW9ieCBjb21wdXRlZCB2YWx1ZXMgZnJvbSBzdG9yZS4KICAgICAqLwoKICB9LCB7CiAgICBrZXk6ICdzZXRJdGVtcycsCiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0SXRlbXMoaXRlbXMpIHsKICAgICAgdmFyIF90aGlzID0gdGhpczsKCiAgICAgIHJldHVybiBpdGVtcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgICByZXR1cm4gX3RoaXMuc2V0SXRlbShpdGVtKTsKICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGl0ZW0gZnJvbSBzdG9yZS4KICAgICAqCiAgICAgKiBAcGFyYW0ge2FueX0ga2V5IEtleSBvZiBpdGVtIGluIHN0b3JlLgogICAgICogQHJldHVybnMge09iamVjdH0gTW9ieCBjb21wdXRlZCB2YWx1ZSBvZiB2YWx1ZSBpbiBzdG9yZS4KICAgICAqLwoKICB9LCB7CiAgICBrZXk6ICdnZXRJdGVtJywKICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRJdGVtKGtleSkgewogICAgICB2YXIgX3RoaXMyID0gdGhpczsKCiAgICAgIHJldHVybiAoMCwgX21vYnguY29tcHV0ZWQpKGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gX3RoaXMyLl9kYXRhLmdldChrZXkpOwogICAgICB9KS5nZXQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgaXRlbSBmcm9tIHN0b3JlLgogICAgICoKICAgICAqIEBwYXJhbSB7YW55fSBrZXkgS2V5IG9mIGl0ZW0gaW4gc3RvcmUuCiAgICAgKi8KCiAgfSwgewogICAga2V5OiAncmVtb3ZlSXRlbScsCiAgICB2YWx1ZTogZnVuY3Rpb24gcmVtb3ZlSXRlbShrZXkpIHsKICAgICAgdGhpcy5fZGF0YS5kZWxldGUoa2V5KTsKICAgIH0KCiAgICAvKioKICAgICAqIFRlc3RzIHRvIHNlZSBpZiBpdGVtIGV4aXN0cyBpbiBzdG9yZS4KICAgICAqCiAgICAgKiBAcGFyYW0ge2FueX0ga2V5IEtleSBvZiBpdGVtIGluIHN0b3JlLgogICAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgaXRlbSBleGlzdHMgaW4gc3RvcmUuCiAgICAgKi8KCiAgfSwgewogICAga2V5OiAnaGFzSXRlbScsCiAgICB2YWx1ZTogZnVuY3Rpb24gaGFzSXRlbShrZXkpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RhdGEuaGFzKGtleSk7CiAgICB9CiAgfV0pOwoKICByZXR1cm4gQnVua2VyU2VydmljZTsKfSgpLCAoX2Rlc2NyaXB0b3IgPSBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdfZGF0YScsIFtfbW9ieC5vYnNlcnZhYmxlXSwgewogIGVudW1lcmFibGU6IHRydWUsCiAgaW5pdGlhbGl6ZXI6IGZ1bmN0aW9uIGluaXRpYWxpemVyKCkgewogICAgcmV0dXJuICgwLCBfbW9ieC5hc01hcCkoKTsKICB9Cn0pLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdzZXRJdGVtJywgW19tb2J4LmFjdGlvbl0sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ3NldEl0ZW0nKSwgX2NsYXNzLnByb3RvdHlwZSksIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ3JlbW92ZUl0ZW0nLCBbX21vYnguYWN0aW9uXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAncmVtb3ZlSXRlbScpLCBfY2xhc3MucHJvdG90eXBlKSksIF9jbGFzcyk7Cn0seyJtb2J4IjozODl9XSw0NzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCnZhciBEZWZhdWx0U1NFSGFuZGxlciA9IGV4cG9ydHMuRGVmYXVsdFNTRUhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7CiAgICBmdW5jdGlvbiBEZWZhdWx0U1NFSGFuZGxlcihwaXBlbGluZVNlcnZpY2UsIGFjdGl2aXR5U2VydmljZSwgcGFnZXJTZXJ2aWNlKSB7CiAgICAgICAgdmFyIF90aGlzID0gdGhpczsKCiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIERlZmF1bHRTU0VIYW5kbGVyKTsKCiAgICAgICAgdGhpcy5oYW5kbGVFdmVudHMgPSBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgc3dpdGNoIChldmVudC5qZW5raW5zX2V2ZW50KSB7CiAgICAgICAgICAgICAgICBjYXNlICdqb2JfcnVuX3BhdXNlZCc6CiAgICAgICAgICAgICAgICBjYXNlICdqb2JfcnVuX3VucGF1c2VkJzoKICAgICAgICAgICAgICAgICAgICBfdGhpcy51cGRhdGVKb2IoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnam9iX2NydWRfY3JlYXRlZCc6CiAgICAgICAgICAgICAgICAgICAgLy8gUmVmZXRjaCBwYWdlcnMgaGVyZS4gVGhpcyB3aWxsIHB1bGwgaW4gdGhlIG5ld2x5IGNyZWF0ZWQgcGlwZWxpbmUgaW50byB0aGUgYnVua2VyLgogICAgICAgICAgICAgICAgICAgIF90aGlzLnBpcGVsaW5lU2VydmljZS5yZWZyZXNoUGFnZXJzKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdqb2JfY3J1ZF9kZWxldGVkJzoKICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgZGlyZWN0bHkgZnJvbSBidW5rZXIuIE5vIG5lZWQgdG8gcmVmcmVzaCBidW5rZXJzIGFzIGl0IHdpbGwganVzdCBzaG93IG9uZSBsZXNzIGl0ZW0uCiAgICAgICAgICAgICAgICAgICAgX3RoaXMucGlwZWxpbmVTZXJ2aWNlLnJlbW92ZUl0ZW0oZXZlbnQuYmx1ZW9jZWFuX2pvYl9yZXN0X3VybCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdqb2JfY3J1ZF9yZW5hbWVkJzoKICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBJbXBsZW1lbnQgdGhpcy4KICAgICAgICAgICAgICAgICAgICAvLyBTZWVtcyB0byBiZSB0aGF0IFNTRSBmaXJlcyBhbiB1cGRhdGVkIGV2ZW50IGZvciB0aGUgb2xkIGpvYiwKICAgICAgICAgICAgICAgICAgICAvLyB0aGVuIGEgcmVuYW1lIGZvciB0aGUgbmV3IG9uZS4gVGhpcyBpcyBzb21ld2hhdCBjb25mdXNpbmcgZm9yIHVzLgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnam9iX3J1bl9xdWV1ZV9idWlsZGFibGUnOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnam9iX3J1bl9xdWV1ZV9lbnRlcic6CiAgICAgICAgICAgICAgICAgICAgX3RoaXMucXVldWVFbnRlcihldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdqb2JfcnVuX3F1ZXVlX2xlZnQnOgogICAgICAgICAgICAgICAgICAgIF90aGlzLnF1ZXVlTGVmdChldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdqb2JfcnVuX3F1ZXVlX2Jsb2NrZWQnOgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2FzZSAnam9iX3J1bl9zdGFydGVkJzoKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnVwZGF0ZUpvYihldmVudCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhc2UgJ2pvYl9ydW5fZW5kZWQnOgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMudXBkYXRlSm9iKGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIC8vIEVsc2UgaWdub3JlIHRoZSBldmVudC4KICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIHRoaXMucGlwZWxpbmVTZXJ2aWNlID0gcGlwZWxpbmVTZXJ2aWNlOwogICAgICAgIHRoaXMuYWN0aXZpdHlTZXJ2aWNlID0gYWN0aXZpdHlTZXJ2aWNlOwogICAgICAgIHRoaXMucGFnZXJTZXJ2aWNlID0gcGFnZXJTZXJ2aWNlOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhEZWZhdWx0U1NFSGFuZGxlciwgW3sKICAgICAgICBrZXk6ICdicmFuY2hQYWdlcktleXMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBicmFuY2hQYWdlcktleXMoZXZlbnQpIHsKICAgICAgICAgICAgaWYgKCFldmVudC5ibHVlb2NlYW5fam9iX2JyYW5jaF9uYW1lKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gW3RoaXMuYWN0aXZpdHlTZXJ2aWNlLnBhZ2VyS2V5KGV2ZW50LmplbmtpbnNfb3JnLCBldmVudC5ibHVlb2NlYW5fam9iX3BpcGVsaW5lX25hbWUpXTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gW3RoaXMuYWN0aXZpdHlTZXJ2aWNlLnBhZ2VyS2V5KGV2ZW50LmplbmtpbnNfb3JnLCBldmVudC5ibHVlb2NlYW5fam9iX3BpcGVsaW5lX25hbWUpLCB0aGlzLmFjdGl2aXR5U2VydmljZS5wYWdlcktleShldmVudC5qZW5raW5zX29yZywgZXZlbnQuYmx1ZW9jZWFuX2pvYl9waXBlbGluZV9uYW1lLCBldmVudC5ibHVlb2NlYW5fam9iX2JyYW5jaF9uYW1lKV07CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3VwZGF0ZUpvYicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHVwZGF0ZUpvYihldmVudCwgb3ZlcnJpZGVRdWV1ZWRTdGF0ZSkgewogICAgICAgICAgICB2YXIgX3RoaXMyID0gdGhpczsKCiAgICAgICAgICAgIC8vIGNvbnN0IHF1ZXVlSWQgPSBldmVudC5qb2JfcnVuX3F1ZXVlSWQ7CiAgICAgICAgICAgIC8vIGNvbnN0IHF1ZXVlU2VsZiA9IGAke2V2ZW50LmJsdWVvY2Vhbl9qb2JfcmVzdF91cmx9cXVldWUvJHtxdWV1ZUlkfS9gOwogICAgICAgICAgICB2YXIgcnVuU2VsZiA9IGV2ZW50LmJsdWVvY2Vhbl9qb2JfcmVzdF91cmwgKyAncnVucy8nICsgZXZlbnQuamVua2luc19vYmplY3RfaWQgKyAnLyc7CgogICAgICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWU7CiAgICAgICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvciA9IGZhbHNlOwogICAgICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IgPSB1bmRlZmluZWQ7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmFyIF9sb29wID0gZnVuY3Rpb24gX2xvb3AoKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGtleSA9IF9zdGVwLnZhbHVlOwoKICAgICAgICAgICAgICAgICAgICB2YXIgcGFnZXIgPSBfdGhpczIucGFnZXJTZXJ2aWNlLmdldFBhZ2VyKHsga2V5OiBrZXkgfSk7CiAgICAgICAgICAgICAgICAgICAgX3RoaXMyLmFjdGl2aXR5U2VydmljZS5mZXRjaEFjdGl2aXR5KHJ1blNlbGYsIHsgb3ZlcnJpZGVRdWV1ZWRTdGF0ZTogb3ZlcnJpZGVRdWV1ZWRTdGF0ZSB9KS50aGVuKGZ1bmN0aW9uIChkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYWdlciAmJiAhcGFnZXIuaGFzKHJ1blNlbGYpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlci5pbnNlcnQocnVuU2VsZik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMyLnBpcGVsaW5lU2VydmljZS51cGRhdGVMYXRlc3RSdW4oZCk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvciA9IHRoaXMuYnJhbmNoUGFnZXJLZXlzKGV2ZW50KVtTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSAoX3N0ZXAgPSBfaXRlcmF0b3IubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICBfbG9vcCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yID0gdHJ1ZTsKICAgICAgICAgICAgICAgIF9pdGVyYXRvckVycm9yID0gZXJyOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gJiYgX2l0ZXJhdG9yLnJldHVybikgewogICAgICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3IucmV0dXJuKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3I7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3F1ZXVlQ2FuY2VsJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcXVldWVDYW5jZWwoZXZlbnQpIHsKICAgICAgICAgICAgaWYgKGV2ZW50LmpvYl9ydW5fc3RhdHVzID09PSAnQ0FOQ0VMTEVEJykgewogICAgICAgICAgICAgICAgdmFyIHF1ZXVlSWQgPSBldmVudC5qb2JfcnVuX3F1ZXVlSWQ7CiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IGV2ZW50LmJsdWVvY2Vhbl9qb2JfcmVzdF91cmwgKyAncXVldWUvJyArIHF1ZXVlSWQgKyAnLyc7CiAgICAgICAgICAgICAgICB0aGlzLmFjdGl2aXR5U2VydmljZS5yZW1vdmVJdGVtKHNlbGYpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3F1ZXVlRW50ZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBxdWV1ZUVudGVyKGV2ZW50KSB7CiAgICAgICAgICAgIC8vIElnbm9yZSB0aGUgZXZlbnQgaWYgdGhlcmUncyBubyBicmFuY2ggbmFtZS4gVXN1YWxseSBpbmRpY2F0ZXMKICAgICAgICAgICAgLy8gdGhhdCB0aGUgZXZlbnQgaXMgd3J0IE1CUCBpbmRleGluZy4KICAgICAgICAgICAgaWYgKGV2ZW50LmpvYl9pc211bHRpYnJhbmNoICYmICFldmVudC5ibHVlb2NlYW5fam9iX2JyYW5jaF9uYW1lKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBxdWV1ZUlkID0gZXZlbnQuam9iX3J1bl9xdWV1ZUlkOwogICAgICAgICAgICB2YXIgc2VsZiA9IGV2ZW50LmJsdWVvY2Vhbl9qb2JfcmVzdF91cmwgKyAncXVldWUvJyArIHF1ZXVlSWQgKyAnLyc7CiAgICAgICAgICAgIHZhciBpZCA9IHRoaXMuYWN0aXZpdHlTZXJ2aWNlLmdldEV4cGVjdGVkQnVpbGROdW1iZXIoZXZlbnQpOwoKICAgICAgICAgICAgdmFyIHJ1blNlbGYgPSBldmVudC5ibHVlb2NlYW5fam9iX3Jlc3RfdXJsICsgJ3J1bnMvJyArIGlkICsgJy8nOwoKICAgICAgICAgICAgdmFyIG5ld1J1biA9IHsKICAgICAgICAgICAgICAgIGlkOiBpZCwKICAgICAgICAgICAgICAgIF9saW5rczogewogICAgICAgICAgICAgICAgICAgIHNlbGY6IHsKICAgICAgICAgICAgICAgICAgICAgICAgaHJlZjogcnVuU2VsZgogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGhyZWY6IGV2ZW50LmJsdWVvY2Vhbl9qb2JfcmVzdF91cmwKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgam9iX3J1bl9xdWV1ZUlkOiBxdWV1ZUlkLAogICAgICAgICAgICAgICAgcGlwZWxpbmU6IGV2ZW50LmJsdWVvY2Vhbl9qb2JfYnJhbmNoX25hbWUsCiAgICAgICAgICAgICAgICByZXN1bHQ6ICdVTktOT1dOJywKICAgICAgICAgICAgICAgIHN0YXRlOiAnUVVFVUVEJywKICAgICAgICAgICAgICAgIF9pdGVtOiB7CiAgICAgICAgICAgICAgICAgICAgX2xpbmtzOiB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGY6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhyZWY6IHNlbGYKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50OiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBocmVmOiBldmVudC5ibHVlb2NlYW5fam9iX3Jlc3RfdXJsCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICAgICAgICB0aGlzLmFjdGl2aXR5U2VydmljZS5zZXRJdGVtKG5ld1J1bik7CgogICAgICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIgPSB0cnVlOwogICAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IyID0gZmFsc2U7CiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjIgPSB1bmRlZmluZWQ7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IHRoaXMuYnJhbmNoUGFnZXJLZXlzKGV2ZW50KVtTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwMjsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMiA9IChfc3RlcDIgPSBfaXRlcmF0b3IyLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yID0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBrZXkgPSBfc3RlcDIudmFsdWU7CgogICAgICAgICAgICAgICAgICAgIHZhciBfcGFnZXIgPSB0aGlzLnBhZ2VyU2VydmljZS5nZXRQYWdlcih7IGtleToga2V5IH0pOwogICAgICAgICAgICAgICAgICAgIGlmIChfcGFnZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3BhZ2VyLmluc2VydChydW5TZWxmKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IyID0gdHJ1ZTsKICAgICAgICAgICAgICAgIF9pdGVyYXRvckVycm9yMiA9IGVycjsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMiAmJiBfaXRlcmF0b3IyLnJldHVybikgewogICAgICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3IyLnJldHVybigpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMikgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3F1ZXVlTGVmdCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHF1ZXVlTGVmdChldmVudCkgewogICAgICAgICAgICBpZiAoZXZlbnQuam9iX3J1bl9zdGF0dXMgPT09ICdDQU5DRUxMRUQnKSB7CiAgICAgICAgICAgICAgICB2YXIgaWQgPSB0aGlzLmFjdGl2aXR5U2VydmljZS5nZXRFeHBlY3RlZEJ1aWxkTnVtYmVyKGV2ZW50KTsKICAgICAgICAgICAgICAgIHZhciBydW5TZWxmID0gZXZlbnQuYmx1ZW9jZWFuX2pvYl9yZXN0X3VybCArICdydW5zLycgKyBpZCArICcvJzsKICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZpdHlTZXJ2aWNlLnJlbW92ZUl0ZW0ocnVuU2VsZik7CiAgICAgICAgICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMgPSB0cnVlOwogICAgICAgICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yMyA9IGZhbHNlOwogICAgICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yMyA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjMgPSB0aGlzLmJyYW5jaFBhZ2VyS2V5cyhldmVudClbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDM7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMgPSAoX3N0ZXAzID0gX2l0ZXJhdG9yMy5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMyA9IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGtleSA9IF9zdGVwMy52YWx1ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBfcGFnZXIyID0gdGhpcy5wYWdlclNlcnZpY2UuZ2V0UGFnZXIoeyBrZXk6IGtleSB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9wYWdlcjIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wYWdlcjIucmVtb3ZlKHJ1blNlbGYpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvcjMgPSBlcnI7CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMgJiYgX2l0ZXJhdG9yMy5yZXR1cm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvcjMucmV0dXJuKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIERlZmF1bHRTU0VIYW5kbGVyOwp9KCk7Cn0se31dLDQ4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuTG9jYXRpb25TZXJ2aWNlID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX2Rlc2MsIF92YWx1ZSwgX2NsYXNzLCBfZGVzY3JpcHRvciwgX2Rlc2NyaXB0b3IyOwoKdmFyIF9tb2J4ID0gcmVxdWlyZSgnbW9ieCcpOwoKZnVuY3Rpb24gX2luaXREZWZpbmVQcm9wKHRhcmdldCwgcHJvcGVydHksIGRlc2NyaXB0b3IsIGNvbnRleHQpIHsKICAgIGlmICghZGVzY3JpcHRvcikgcmV0dXJuOwogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHksIHsKICAgICAgICBlbnVtZXJhYmxlOiBkZXNjcmlwdG9yLmVudW1lcmFibGUsCiAgICAgICAgY29uZmlndXJhYmxlOiBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSwKICAgICAgICB3cml0YWJsZTogZGVzY3JpcHRvci53cml0YWJsZSwKICAgICAgICB2YWx1ZTogZGVzY3JpcHRvci5pbml0aWFsaXplciA/IGRlc2NyaXB0b3IuaW5pdGlhbGl6ZXIuY2FsbChjb250ZXh0KSA6IHZvaWQgMAogICAgfSk7Cn0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcih0YXJnZXQsIHByb3BlcnR5LCBkZWNvcmF0b3JzLCBkZXNjcmlwdG9yLCBjb250ZXh0KSB7CiAgICB2YXIgZGVzYyA9IHt9OwogICAgT2JqZWN0WydrZScgKyAneXMnXShkZXNjcmlwdG9yKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsKICAgICAgICBkZXNjW2tleV0gPSBkZXNjcmlwdG9yW2tleV07CiAgICB9KTsKICAgIGRlc2MuZW51bWVyYWJsZSA9ICEhZGVzYy5lbnVtZXJhYmxlOwogICAgZGVzYy5jb25maWd1cmFibGUgPSAhIWRlc2MuY29uZmlndXJhYmxlOwoKICAgIGlmICgndmFsdWUnIGluIGRlc2MgfHwgZGVzYy5pbml0aWFsaXplcikgewogICAgICAgIGRlc2Mud3JpdGFibGUgPSB0cnVlOwogICAgfQoKICAgIGRlc2MgPSBkZWNvcmF0b3JzLnNsaWNlKCkucmV2ZXJzZSgpLnJlZHVjZShmdW5jdGlvbiAoZGVzYywgZGVjb3JhdG9yKSB7CiAgICAgICAgcmV0dXJuIGRlY29yYXRvcih0YXJnZXQsIHByb3BlcnR5LCBkZXNjKSB8fCBkZXNjOwogICAgfSwgZGVzYyk7CgogICAgaWYgKGNvbnRleHQgJiYgZGVzYy5pbml0aWFsaXplciAhPT0gdm9pZCAwKSB7CiAgICAgICAgZGVzYy52YWx1ZSA9IGRlc2MuaW5pdGlhbGl6ZXIgPyBkZXNjLmluaXRpYWxpemVyLmNhbGwoY29udGV4dCkgOiB2b2lkIDA7CiAgICAgICAgZGVzYy5pbml0aWFsaXplciA9IHVuZGVmaW5lZDsKICAgIH0KCiAgICBpZiAoZGVzYy5pbml0aWFsaXplciA9PT0gdm9pZCAwKSB7CiAgICAgICAgT2JqZWN0WydkZWZpbmUnICsgJ1Byb3BlcnR5J10odGFyZ2V0LCBwcm9wZXJ0eSwgZGVzYyk7CiAgICAgICAgZGVzYyA9IG51bGw7CiAgICB9CgogICAgcmV0dXJuIGRlc2M7Cn0KCmZ1bmN0aW9uIF9pbml0aWFsaXplcldhcm5pbmdIZWxwZXIoZGVzY3JpcHRvciwgY29udGV4dCkgewogICAgdGhyb3cgbmV3IEVycm9yKCdEZWNvcmF0aW5nIGNsYXNzIHByb3BlcnR5IGZhaWxlZC4gUGxlYXNlIGVuc3VyZSB0aGF0IHRyYW5zZm9ybS1jbGFzcy1wcm9wZXJ0aWVzIGlzIGVuYWJsZWQuJyk7Cn0KCi8qKgogKiBTdG9yZXMgdGhlIHByZXZpb3VzIGFuZCBjdXJyZW50IGxvY2F0aW9uIHBhdGhuYW1lcy4KICovCnZhciBMb2NhdGlvblNlcnZpY2UgPSBleHBvcnRzLkxvY2F0aW9uU2VydmljZSA9IChfY2xhc3MgPSBmdW5jdGlvbiAoKSB7CiAgICBmdW5jdGlvbiBMb2NhdGlvblNlcnZpY2UoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIExvY2F0aW9uU2VydmljZSk7CgogICAgICAgIF9pbml0RGVmaW5lUHJvcCh0aGlzLCAnY3VycmVudCcsIF9kZXNjcmlwdG9yLCB0aGlzKTsKCiAgICAgICAgX2luaXREZWZpbmVQcm9wKHRoaXMsICdwcmV2aW91cycsIF9kZXNjcmlwdG9yMiwgdGhpcyk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKExvY2F0aW9uU2VydmljZSwgW3sKICAgICAgICBrZXk6ICdzZXRDdXJyZW50JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gc2V0Q3VycmVudChuZXdMb2NhdGlvbikgewogICAgICAgICAgICBpZiAobmV3TG9jYXRpb24uYWN0aW9uICE9PSAnUkVQTEFDRScpIHsKICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXMgPSB0aGlzLmN1cnJlbnQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuY3VycmVudCA9IG5ld0xvY2F0aW9uLnBhdGhuYW1lOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gTG9jYXRpb25TZXJ2aWNlOwp9KCksIChfZGVzY3JpcHRvciA9IF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ2N1cnJlbnQnLCBbX21vYngub2JzZXJ2YWJsZV0sIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBpbml0aWFsaXplcjogbnVsbAp9KSwgX2Rlc2NyaXB0b3IyID0gX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAncHJldmlvdXMnLCBbX21vYngub2JzZXJ2YWJsZV0sIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBpbml0aWFsaXplcjogbnVsbAp9KSwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAnc2V0Q3VycmVudCcsIFtfbW9ieC5hY3Rpb25dLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdzZXRDdXJyZW50JyksIF9jbGFzcy5wcm90b3R5cGUpKSwgX2NsYXNzKTsKfSx7Im1vYngiOjM4OX1dLDQ5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlBhZ2VyID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX2Rlc2MsIF92YWx1ZSwgX2NsYXNzLCBfZGVzY3JpcHRvciwgX2Rlc2NyaXB0b3IyLCBfZGVzY3JpcHRvcjMsIF9kZXNjcmlwdG9yNCwgX2Rlc2NyaXB0b3I1OwoKZXhwb3J0cy5wYWdpbmF0ZVVybCA9IHBhZ2luYXRlVXJsOwoKdmFyIF9tb2J4ID0gcmVxdWlyZSgnbW9ieCcpOwoKdmFyIF9mZXRjaCA9IHJlcXVpcmUoJy4uL2ZldGNoJyk7CgpmdW5jdGlvbiBfaW5pdERlZmluZVByb3AodGFyZ2V0LCBwcm9wZXJ0eSwgZGVzY3JpcHRvciwgY29udGV4dCkgewogIGlmICghZGVzY3JpcHRvcikgcmV0dXJuOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCB7CiAgICBlbnVtZXJhYmxlOiBkZXNjcmlwdG9yLmVudW1lcmFibGUsCiAgICBjb25maWd1cmFibGU6IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlLAogICAgd3JpdGFibGU6IGRlc2NyaXB0b3Iud3JpdGFibGUsCiAgICB2YWx1ZTogZGVzY3JpcHRvci5pbml0aWFsaXplciA/IGRlc2NyaXB0b3IuaW5pdGlhbGl6ZXIuY2FsbChjb250ZXh0KSA6IHZvaWQgMAogIH0pOwp9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IodGFyZ2V0LCBwcm9wZXJ0eSwgZGVjb3JhdG9ycywgZGVzY3JpcHRvciwgY29udGV4dCkgewogIHZhciBkZXNjID0ge307CiAgT2JqZWN0WydrZScgKyAneXMnXShkZXNjcmlwdG9yKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsKICAgIGRlc2Nba2V5XSA9IGRlc2NyaXB0b3Jba2V5XTsKICB9KTsKICBkZXNjLmVudW1lcmFibGUgPSAhIWRlc2MuZW51bWVyYWJsZTsKICBkZXNjLmNvbmZpZ3VyYWJsZSA9ICEhZGVzYy5jb25maWd1cmFibGU7CgogIGlmICgndmFsdWUnIGluIGRlc2MgfHwgZGVzYy5pbml0aWFsaXplcikgewogICAgZGVzYy53cml0YWJsZSA9IHRydWU7CiAgfQoKICBkZXNjID0gZGVjb3JhdG9ycy5zbGljZSgpLnJldmVyc2UoKS5yZWR1Y2UoZnVuY3Rpb24gKGRlc2MsIGRlY29yYXRvcikgewogICAgcmV0dXJuIGRlY29yYXRvcih0YXJnZXQsIHByb3BlcnR5LCBkZXNjKSB8fCBkZXNjOwogIH0sIGRlc2MpOwoKICBpZiAoY29udGV4dCAmJiBkZXNjLmluaXRpYWxpemVyICE9PSB2b2lkIDApIHsKICAgIGRlc2MudmFsdWUgPSBkZXNjLmluaXRpYWxpemVyID8gZGVzYy5pbml0aWFsaXplci5jYWxsKGNvbnRleHQpIDogdm9pZCAwOwogICAgZGVzYy5pbml0aWFsaXplciA9IHVuZGVmaW5lZDsKICB9CgogIGlmIChkZXNjLmluaXRpYWxpemVyID09PSB2b2lkIDApIHsKICAgIE9iamVjdFsnZGVmaW5lJyArICdQcm9wZXJ0eSddKHRhcmdldCwgcHJvcGVydHksIGRlc2MpOwogICAgZGVzYyA9IG51bGw7CiAgfQoKICByZXR1cm4gZGVzYzsKfQoKZnVuY3Rpb24gX2luaXRpYWxpemVyV2FybmluZ0hlbHBlcihkZXNjcmlwdG9yLCBjb250ZXh0KSB7CiAgdGhyb3cgbmV3IEVycm9yKCdEZWNvcmF0aW5nIGNsYXNzIHByb3BlcnR5IGZhaWxlZC4gUGxlYXNlIGVuc3VyZSB0aGF0IHRyYW5zZm9ybS1jbGFzcy1wcm9wZXJ0aWVzIGlzIGVuYWJsZWQuJyk7Cn0KCi8qKgogKiBQcm92aWRlIGEgcGFnaW5hdGlvbiBmdW5jdGlvbiBmb3IgdGhlIGdlbmVyaWMKICogYmx1ZW9jZWFuIHBhZ2luYXRpb24KICoKICogQGV4cG9ydAogKiBAcGFyYW0ge3N0cmluZ30gdXJsIC0gQmFzZSB1cmwgdG8gcGFnaW5hdGUuCiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gLSBGdW5jdGlvbiB0aGF0IHByb3ZpZGVzIHBhZ2luY2F0ZWQgdXJscy4KICovCmZ1bmN0aW9uIHBhZ2luYXRlVXJsKHVybCkgewogIHZhciBzZXAgPSB1cmwuaW5kZXhPZignPycpID49IDAgPyAnJicgOiAnPyc7CiAgcmV0dXJuIGZ1bmN0aW9uIChzdGFydCwgbGltaXQpIHsKICAgIHJldHVybiAnJyArIHVybCArIHNlcCArICdzdGFydD0nICsgc3RhcnQgKyAnJmxpbWl0PScgKyBsaW1pdDsKICB9Owp9CgovKioKICogVGhlIHBhZ2VyIGZldGNoZXMgcGFnZXMgb2YgZGF0YSBmcm9tIHRoZSBCbHVlT2NlYW4gYXBpLiBJdCBmZXRjaGVzIHBhZ2VzIG9mIGRhdGEsIHRoZW4KICogaW5zZXJ0cyB0aGVtIGludG8gdGhlIFtAbGluayBCdW5rZXJTZXJ2aWNlXSwgYW5kIHN0b3JlcyB0aGUgaHJlZiBmcm9tIHRoZSBkYXRhLgogKgogKiBNb2JYIGNvbXB1dGVzIGEgZGF0YSBmaWVsZCBmcm9tIHRoZSBocmVmcyBiYWNrZWQgYnkgdGhlIGJhY2tlbmQgY2FjaGUuIFRoaXMgYWxsb3dzIGZvciBTU0UgZXZlbnRzCiAqIHRvIGJlIHByb3BvcmdhdGVkIHRvIHRoZSBwYWdlci4KICoKICogQGV4cG9ydAogKiBAY2xhc3MgUGFnZXIKICovCnZhciBQYWdlciA9IGV4cG9ydHMuUGFnZXIgPSAoX2NsYXNzID0gZnVuY3Rpb24gKCkgewogIF9jcmVhdGVDbGFzcyhQYWdlciwgW3sKICAgIGtleTogJ2RhdGEnLAoKCiAgICAvKioKICAgICAqIE1vYnggY29tcHV0ZWQgdmFsdWUgdGhhdCBjcmVhdGVzIGFuIGFycmF5IG9mIG9iamVjdHMgZnJvbSB0aGUgbGlzdCBvZiBocmVmcyBzdG9yZWQuIElmIGVpdGhlciB0aGUKICAgICAqIGJ1bmtlciBjaGFuZ2VzLCBvciB0aGUgaHJlZnMgY2hhbmdlLCB0aGlzIGlzIHJlY2FsY3VsYXRlZCBhbmQgd2lsbCB0cmlnZ2VyIGEgcmVhY3QgcmVhY3Rpb24uCiAgICAgKgogICAgICogSWYgaXRlbSBkb2VzIG5vdCBleGlzdCBpbiBidW5rZXIsIHRoZW4gd2UganVzdCBpZ25vcmUgaXQuCiAgICAgKiBAcmVhZG9ubHkKICAgICAqIEB0eXBlIHtBcnJheTxPYmplY3Q+fQogICAgICovCgogICAgLyoqCiAgICAgKiBUaGUgbGF0ZXN0IHBhZ2UgdGhlIHBhZ2VyIGhhcyBmZXRjaGVkLgogICAgICovCgogICAgLyoqCiAgICAgKiBwYWdlciBpcyBmZXRjaGluZyBkYXRhLgogICAgICovCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgdmFyIF90aGlzID0gdGhpczsKCiAgICAgIHJldHVybiB0aGlzLmhyZWZzLm1hcChmdW5jdGlvbiAoaHJlZikgewogICAgICAgIHJldHVybiBfdGhpcy5idW5rZXIuZ2V0SXRlbShocmVmKTsKICAgICAgfSkuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgICAgcmV0dXJuIGl0ZW0gIT09IHVuZGVmaW5lZDsKICAgICAgfSk7CiAgICB9CiAgICAvKioKICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgUGFnZXIgYW5kIGZldGNoZXMgdGhlIGZpcnN0IHBhZ2UuCiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIEJhc2UgdXJsIG9mIGNvbGxlY3RpbiB0byBmZXRjaAogICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2VTaXplIC0gUGFnZSBzaXplIHRvIGZldGNoIGR1cmluZyBvbmUgbG9hZC4KICAgICAqIEBwYXJhbSB7QnVua2VyU2VydmljZX0gYnVua2VyIC0gRGF0YSBzdG9yZQogICAgICogQHBhcmFtIHtVcmxQcm92aWRlcn0gW3VybFByb3ZpZGVyPXBhZ2luYXRlVXJsXQogICAgICovCgogICAgLyoqCiAgICAgKiBNb3JlIHBhZ2VzIHRvIGZldGNoLgogICAgICovCgogICAgLyoqCiAgICAgKiBXaWxsIGJlIHNldCBpbiBhbiBlcnJvciBvY2N1cnMuCiAgICAgKi8KCiAgfV0pOwoKICBmdW5jdGlvbiBQYWdlcih1cmwsIHBhZ2VTaXplLCBidW5rZXIpIHsKICAgIHZhciB1cmxQcm92aWRlciA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDogcGFnaW5hdGVVcmw7CgogICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFBhZ2VyKTsKCiAgICBfaW5pdERlZmluZVByb3AodGhpcywgJ2hyZWZzJywgX2Rlc2NyaXB0b3IsIHRoaXMpOwoKICAgIF9pbml0RGVmaW5lUHJvcCh0aGlzLCAncGVuZGluZycsIF9kZXNjcmlwdG9yMiwgdGhpcyk7CgogICAgX2luaXREZWZpbmVQcm9wKHRoaXMsICdlcnJvcicsIF9kZXNjcmlwdG9yMywgdGhpcyk7CgogICAgX2luaXREZWZpbmVQcm9wKHRoaXMsICdjdXJyZW50UGFnZScsIF9kZXNjcmlwdG9yNCwgdGhpcyk7CgogICAgX2luaXREZWZpbmVQcm9wKHRoaXMsICdoYXNNb3JlJywgX2Rlc2NyaXB0b3I1LCB0aGlzKTsKCiAgICB0aGlzLnBhZ2VTaXplID0gcGFnZVNpemU7CiAgICB0aGlzLnVybCA9IHVybDsKICAgIHRoaXMudXJsUHJvdmlkZXIgPSB1cmxQcm92aWRlcjsKICAgIHRoaXMucGFnZWRVcmwgPSB0aGlzLnVybFByb3ZpZGVyKHVybCk7CiAgICB0aGlzLnBhZ2VTaXplID0gcGFnZVNpemU7CiAgICB0aGlzLmJ1bmtlciA9IGJ1bmtlcjsKCiAgICAvLyBGZXRjaCB0aGUgZmlyc3QgcGFnZSBzbyB0aGF0IHRoZSB1c2VyIGRvZXMgbm90IGhhdmUgdG8uCiAgICB0aGlzLmZldGNoTmV4dFBhZ2UoKTsKICB9CgogIC8qKgogICAqIEZldGNoZXMgdGhlIG5leHQgcGFnZSBmcm9tIHRoZSBiYWNrZW5kLgogICAqCiAgICogQHJldHVybnMge1Byb21pc2V9CiAgICovCgoKICBfY3JlYXRlQ2xhc3MoUGFnZXIsIFt7CiAgICBrZXk6ICdmZXRjaE5leHRQYWdlJywKICAgIHZhbHVlOiBmdW5jdGlvbiBmZXRjaE5leHRQYWdlKCkgewogICAgICB2YXIgX3RoaXMyID0gdGhpczsKCiAgICAgIC8vIEdldCB0aGUgbmV4dCBwYWdlJ3MgdXJsLicKICAgICAgdmFyIHVybCA9IHRoaXMucGFnZWRVcmwodGhpcy5jdXJyZW50UGFnZSAqIHRoaXMucGFnZVNpemUsIHRoaXMucGFnZVNpemUgKyAxKTsKCiAgICAgIHRoaXMucGVuZGluZyA9IHRydWU7CgogICAgICByZXR1cm4gX2ZldGNoLkZldGNoLmZldGNoSlNPTih1cmwpLnRoZW4oKDAsIF9tb2J4LmFjdGlvbikoJ1Byb2Nlc3MgcGFnZXIgZGF0YScsIGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgLy8gU3RvcmUgaXRlbSBpbiBidW5rZXIuCiAgICAgICAgdmFyIHNhdmVkID0gX3RoaXMyLmJ1bmtlci5zZXRJdGVtcyhkYXRhKTsKCiAgICAgICAgLy8gMSBleHRyYSBpdGVtIGlzIGZldGNoZWQgYmVjYXVzZSBuZWVkIHRvIGtub3cgaWYgdGhlcmUgYXJlIG1vcmUgcGFja2FnZXMuIFNvCiAgICAgICAgLy8gc2xpY2Ugb2ZmIHRoZSBsYXN0IGl0ZW0sIHRoZW4gbWFwIGFsbCBpdGVtcyB0byBqdXN0IGJlIGhyZWZzLgogICAgICAgIHZhciB0cmltbWVkSHJlZnMgPSBzYXZlZC5zbGljZSgwLCBfdGhpczIucGFnZVNpemUpLm1hcChmdW5jdGlvbiAoaXRlbSkgewogICAgICAgICAgcmV0dXJuIGl0ZW0uX2xpbmtzLnNlbGYuaHJlZjsKICAgICAgICB9KTsKCiAgICAgICAgLy8gQXBwZW5kIHRoZSBuZXcgSHJlZnMgdG8gdGhlIGV4aXN0aW5nIG9uZXMuCiAgICAgICAgX3RoaXMyLmhyZWZzID0gX3RoaXMyLmhyZWZzLmNvbmNhdCh0cmltbWVkSHJlZnMpOwoKICAgICAgICAvLyBUcnVlIGlmIHdlIGZldGNoIG1vcmUgaXRlbXMgdGhhbiB0aGUgcGFnZSBzaXplLgogICAgICAgIF90aGlzMi5oYXNNb3JlID0gZGF0YS5sZW5ndGggPiBfdGhpczIucGFnZVNpemU7CiAgICAgICAgX3RoaXMyLmN1cnJlbnRQYWdlID0gX3RoaXMyLmN1cnJlbnRQYWdlICsgMTsKICAgICAgICBfdGhpczIucGVuZGluZyA9IGZhbHNlOwogICAgICB9KSkuY2F0Y2goZnVuY3Rpb24gKGVycikgewogICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZldGNoaW5nIHBhZ2UnLCBlcnIpOwogICAgICAgICgwLCBfbW9ieC5hY3Rpb24pKCdzZXQgZXJyb3InLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICBfdGhpczIuZXJyb3IgPSBlcnI7CiAgICAgICAgfSk7CiAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICogUmVmcmVzaGVzIHRoZSBIcmVmcyBmb3IgdGhlIHBhZ2VyLiBJdCBhbHNvIHN0b3JlcyB0aGUgbGF0ZXN0IGRhdGEgaW4gdGhlIFtAbGluayBCdW5rZXJTZXJ2aWNlXQogICAgICoKICAgICAqIFRoaXMgbWlnaHQgYmUgY2FsbGVkIGlmIHNvbWV0aGluZyBsaWtlIHNvcnRpbmcgb2YgYSBsaXN0IGNoYW5nZXMuCiAgICAgKgogICAgICogQHJldHVybnMge1Byb21pc2V9CiAgICAgKi8KCiAgfSwgewogICAga2V5OiAncmVmcmVzaCcsCiAgICB2YWx1ZTogZnVuY3Rpb24gcmVmcmVzaCgpIHsKICAgICAgdmFyIF90aGlzMyA9IHRoaXM7CgogICAgICB2YXIgdXJsID0gdGhpcy5wYWdlZFVybCgwLCB0aGlzLmN1cnJlbnRQYWdlICogdGhpcy5wYWdlU2l6ZSArIDEpOwogICAgICB0aGlzLnBlbmRpbmcgPSB0cnVlOwogICAgICByZXR1cm4gX2ZldGNoLkZldGNoLmZldGNoSlNPTih1cmwpIC8vIEZldGNoIGRhdGEKICAgICAgLnRoZW4oKDAsIF9tb2J4LmFjdGlvbikoJ3NldCBkYXRhJywgZnVuY3Rpb24gKGRhdGEpIHsKICAgICAgICBfdGhpczMuYnVua2VyLnNldEl0ZW1zKGRhdGEpOwogICAgICAgIF90aGlzMy5ocmVmcyA9IGRhdGEuc2xpY2UoMCwgX3RoaXMzLnBhZ2VTaXplKS5tYXAoZnVuY3Rpb24gKHgpIHsKICAgICAgICAgIHJldHVybiB4Ll9saW5rcy5zZWxmLmhyZWY7CiAgICAgICAgfSk7CiAgICAgICAgX3RoaXMzLmhhc01vcmUgPSBkYXRhLmxlbmd0aCA+IF90aGlzMy5wYWdlU2l6ZTsKICAgICAgICBfdGhpczMuY3VycmVudFBhZ2UgPSBfdGhpczMuY3VycmVudFBhZ2UgKyAxOwogICAgICAgIF90aGlzMy5wZW5kaW5nID0gZmFsc2U7CiAgICAgIH0pKS5jYXRjaChmdW5jdGlvbiAoZXJyKSB7CiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZmV0Y2hpbmcgcGFnZScsIGVycik7CiAgICAgICAgX3RoaXMzLmVyciA9IGVycjsKICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnNlcnRzIGFuIGhyZWYgaW50byB0aGUgbGlzdC4gVGhpcyB3aWxsIGNhdXNlIGEgcmVhY3Rpb24gcmVuZGVyIGZvciB0aGUgcGFnZWQgbGlzdCBvZiBkYXRhLgogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSBocmVmIC0gaHJlZiBvZiBpdGVtIHRvIGRpc3BsYXkKICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcG9zPTBdIC0gUG9zaXRpb24gdG8gaW5zZXJ0IGl0LiBEZWZhdWx0IGlzIGZpcnN0IGl0ZW0uCiAgICAgKi8KCiAgfSwgewogICAga2V5OiAnaW5zZXJ0JywKICAgIHZhbHVlOiBmdW5jdGlvbiBpbnNlcnQoaHJlZikgewogICAgICB2YXIgcG9zID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAwOwoKICAgICAgdGhpcy5ocmVmcy5zcGxpY2UocG9zLCAwLCBocmVmKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgYW4gaHJlZiBpbnRvIHRoZSBsaXN0LiBUaGlzIHdpbGwgY2F1c2UgYSByZWFjdGlvbiByZW5kZXIgZm9yIHRoZSBwYWdlZCBsaXN0IG9mIGRhdGEuCiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IGhyZWYgLSBocmVmIG9mIGl0ZW0gdG8gcmVtb3ZlCiAgICAgKi8KCiAgfSwgewogICAga2V5OiAncmVtb3ZlJywKICAgIHZhbHVlOiBmdW5jdGlvbiByZW1vdmUoaHJlZikgewogICAgICB2YXIgaWR4ID0gdGhpcy5ocmVmcy5pbmRleE9mKGhyZWYpOwogICAgICB0aGlzLmhyZWZzLnNwbGljZShpZHgsIDEpOwogICAgfQoKICAgIC8qKgogICAgICogSHJlZiBleGlzdHMgaW4gcGFnZXIuCiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IGhyZWYKICAgICAqIEByZXR1cm5zIHtib29sZWFufSAtIFRydWUgaWYgdGhpcyBwYWdlciBkb2VzIGhhdmUgdGhpcyBocmVmCiAgICAgKi8KCiAgfSwgewogICAga2V5OiAnaGFzJywKICAgIHZhbHVlOiBmdW5jdGlvbiBoYXMoaHJlZikgewogICAgICByZXR1cm4gdGhpcy5ocmVmcy5pbmRleE9mKGhyZWYpID4gLTE7CiAgICB9CiAgfV0pOwoKICByZXR1cm4gUGFnZXI7Cn0oKSwgKF9kZXNjcmlwdG9yID0gX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAnaHJlZnMnLCBbX21vYngub2JzZXJ2YWJsZV0sIHsKICBlbnVtZXJhYmxlOiB0cnVlLAogIGluaXRpYWxpemVyOiBmdW5jdGlvbiBpbml0aWFsaXplcigpIHsKICAgIHJldHVybiBbXTsKICB9Cn0pLCBfZGVzY3JpcHRvcjIgPSBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdwZW5kaW5nJywgW19tb2J4Lm9ic2VydmFibGVdLCB7CiAgZW51bWVyYWJsZTogdHJ1ZSwKICBpbml0aWFsaXplcjogZnVuY3Rpb24gaW5pdGlhbGl6ZXIoKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQp9KSwgX2Rlc2NyaXB0b3IzID0gX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAnZXJyb3InLCBbX21vYngub2JzZXJ2YWJsZV0sIHsKICBlbnVtZXJhYmxlOiB0cnVlLAogIGluaXRpYWxpemVyOiBmdW5jdGlvbiBpbml0aWFsaXplcigpIHsKICAgIHJldHVybiBudWxsOwogIH0KfSksIF9kZXNjcmlwdG9yNCA9IF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ2N1cnJlbnRQYWdlJywgW19tb2J4Lm9ic2VydmFibGVdLCB7CiAgZW51bWVyYWJsZTogdHJ1ZSwKICBpbml0aWFsaXplcjogZnVuY3Rpb24gaW5pdGlhbGl6ZXIoKSB7CiAgICByZXR1cm4gMDsKICB9Cn0pLCBfZGVzY3JpcHRvcjUgPSBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdoYXNNb3JlJywgW19tb2J4Lm9ic2VydmFibGVdLCB7CiAgZW51bWVyYWJsZTogdHJ1ZSwKICBpbml0aWFsaXplcjogZnVuY3Rpb24gaW5pdGlhbGl6ZXIoKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9Cn0pLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdkYXRhJywgW19tb2J4LmNvbXB1dGVkXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAnZGF0YScpLCBfY2xhc3MucHJvdG90eXBlKSwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAnZmV0Y2hOZXh0UGFnZScsIFtfbW9ieC5hY3Rpb25dLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdmZXRjaE5leHRQYWdlJyksIF9jbGFzcy5wcm90b3R5cGUpLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdyZWZyZXNoJywgW19tb2J4LmFjdGlvbl0sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ3JlZnJlc2gnKSwgX2NsYXNzLnByb3RvdHlwZSksIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ2luc2VydCcsIFtfbW9ieC5hY3Rpb25dLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdpbnNlcnQnKSwgX2NsYXNzLnByb3RvdHlwZSksIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgJ3JlbW92ZScsIFtfbW9ieC5hY3Rpb25dLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICdyZW1vdmUnKSwgX2NsYXNzLnByb3RvdHlwZSkpLCBfY2xhc3MpOwp9LHsiLi4vZmV0Y2giOjIyLCJtb2J4IjozODl9XSw1MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7CiJ1c2Ugc3RyaWN0IjsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCi8qKgogKiBUaGlzIHNlcnZpY2UgbWFuYWdlcyB0aGUgdmFyaW91cyBpbnN0YW5jZXMgb2YgcGFnZXJzIHRoYXQgY3VycmVudGx5IGV4aXN0LgogKgogKiBUT0RPOiBDdXJyZW50bHkgYSBuZXcgcGFnZXIgaXMgY3JlYXRlZCBmb3IgYW55IG5ldyBsaXN0IG9mIGl0ZW1zIHRvIGJlIHBhZ2VkLiBDbGVhbnVwIG1heSBiZQogKiByZXF1aXJlZCB0byBzdG9wIG1lbW9yeSBsZWFrZXMuIEhvd2V2ZXIgUGFnZXJzIGRvbid0IHN0b3JlIG1vcmUgZGF0YSBzbyB0aGlzIG1heSBub3QgYmUgYW4gaXNzdWUuJwogKgogKiBAZXhwb3J0CiAqIEBjbGFzcyBQYWdlclNlcnZpY2UKICovCnZhciBQYWdlclNlcnZpY2UgPSBleHBvcnRzLlBhZ2VyU2VydmljZSA9IGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFBhZ2VyU2VydmljZSgpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUGFnZXJTZXJ2aWNlKTsKCiAgICAgICAgdGhpcy5fcGFnZXJNYXAgPSBuZXcgTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIE1vYlggbWFwIHRvIGhvbGQgW0BsaW5rIFBhZ2VyXSdzJwogICAgICovCgoKICAgIF9jcmVhdGVDbGFzcyhQYWdlclNlcnZpY2UsIFt7CiAgICAgICAga2V5OiAicmVnaXN0ZXJQYWdlciIsCgoKICAgICAgICAvKioKICAgICAgICAgKiBSZWdpc3RlcnMgYSBwYWdlciB3aXRoIHRoZSBQYWdlclNlcnZpY2UuCiAgICAgICAgICoKICAgICAgICAgKiBOYW1lc3BhY2luZyBzdHJpbmdzIGlzIHByZWZlcmVkIHRvIHN0b3AgY29saXNpb25zLiBFLmcuIEFjdGl2aXR5LyRvcmctJHBpcGVsaW5lLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHthbnl9IGtleSAtIEtleSB0byByZWdpc3RlciB0aGUgcGFnZXIgdW5kZXIuCiAgICAgICAgICogQHBhcmFtIHtQYWdlcn0gcGFnZXIgLSBwYWdlciB0byByZWdpc2VyLgogICAgICAgICAqLwogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZWdpc3RlclBhZ2VyKGtleSwgcGFnZXIpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX3BhZ2VyTWFwLmhhcyhrZXkpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlBhZ2VyICciICsga2V5ICsgIicgYWxyZWFkeSBleGl0cyBpbiBQYWdlclNlcnZpY2UiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl9wYWdlck1hcC5zZXQoa2V5LCBwYWdlcik7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSZW1vdmVzIHBhZ2VyIGZyb20gdGhlIGNhY2hlLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHthbnl9IGtleQogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICJyZW1vdmVQYWdlciIsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbW92ZVBhZ2VyKGtleSkgewogICAgICAgICAgICBpZiAodGhpcy5fcGFnZXJNYXAuaGFzKGtleSkpIHsKICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2VyTWFwLmRlbGV0ZShrZXkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBMYXppbHkgY3JlYXRlcyBhIHBhZ2VyLiBEbyB0aGlzIGJlY2F1c2UgcGFnZXIgZmV0Y2hlcyB0aGUgZmlyc3QgcGFnZSB3aGVuIGl0IGlzIGNyZWF0ZWQuCiAgICAgICAgICoKICAgICAgICAgKiBAY2FsbGJhY2sgbGF6eVBhZ2VyCiAgICAgICAgICogQHJldHVybnMge1BhZ2VyfQogICAgICAgICAqLwogICAgICAgIC8qKgogICAgICAgICAqIEdldHMgYSBwYWdlciBmcm9tIHRoZSBjYWNoZS4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zCiAgICAgICAgICogQHBhcmFtIHthbnl9IG9wdGlvbnMua2V5IC0gS2V5IHRvIHN0b3JlIHBhZ2VyIHVuZGVyLgogICAgICAgICAqIEBwYXJhbSB7bGF6eVBhZ2VyfSBvcHRpb25zLmxhenlQYWdlciAtIGZ1bmN0aW9uIHRvIGxhemlseSBjcmV0ZSB0aGUgcGFnZXIuCiAgICAgICAgICogQHJldHVybnMge1BhZ2VyfQogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICJnZXRQYWdlciIsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldFBhZ2VyKF9yZWYpIHsKICAgICAgICAgICAgdmFyIGtleSA9IF9yZWYua2V5LAogICAgICAgICAgICAgICAgbGF6eVBhZ2VyID0gX3JlZi5sYXp5UGFnZXI7CgogICAgICAgICAgICBpZiAodGhpcy5fcGFnZXJNYXAuaGFzKGtleSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYWdlck1hcC5nZXQoa2V5KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobGF6eVBhZ2VyKSB7CiAgICAgICAgICAgICAgICB2YXIgcGFnZXIgPSBsYXp5UGFnZXIoKTsKICAgICAgICAgICAgICAgIHRoaXMucmVnaXN0ZXJQYWdlcihrZXksIHBhZ2VyKTsKICAgICAgICAgICAgICAgIHJldHVybiBwYWdlcjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSZWZldGNoZXMgdGhlIGxpc3Qgb2YgaXRlbXMgdGhlIHBhZ2VycyB0aGF0IHVzZSBhIHNwZWNpZmljIFtAbGluayBCdW5rZXJTZXJ2aWNlXSB0byBkaXNwbGF5LgogICAgICAgICAqIFRoaXMgaXMgZG9uZSBpbiB0aGUgY2FzZSBvZiByZW9yZGVyaW5nLgogICAgICAgICAqCiAgICAgICAgICogVE9ETzogTWFrZSB0aGlzIG1vcmUgdGFyZ2V0dGVkLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtCdW5rZXJTZXJ2aWNlfSBidW5rZXJTZXJ2aWNlIEEgc2VydmljZSB0aGF0IGV4dGVuZHMgW0BsaW5rIEJ1bmtlclNlcnZpY2VdCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogInJlZnJlc2giLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZWZyZXNoKGJ1bmtlclNlcnZpY2UpIHsKICAgICAgICAgICAgdGhpcy5fcGFnZXJNYXAuZm9yRWFjaChmdW5jdGlvbiAocGFnZXIpIHsKICAgICAgICAgICAgICAgIGlmIChidW5rZXJTZXJ2aWNlID09PSBwYWdlci5idW5rZXIpIHsKICAgICAgICAgICAgICAgICAgICBwYWdlci5yZWZyZXNoKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0cyBhbGwgcGFnZXJzIGZvciBhIFtAbGluayBCdW5rZXJTZXJ2aWNlXQogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtCdW5rZXJTZXJ2aWNlfSBidW5rZXIKICAgICAgICAgKiBAcmV0dXJucyB7UGFnZXJbXX0KICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAiZ2V0UGFnZXJzIiwKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0UGFnZXJzKGJ1bmtlcikgewogICAgICAgICAgICB2YXIgcmV0ID0gW107CiAgICAgICAgICAgIHRoaXMuX3BhZ2VyTWFwLmZvckVhY2goZnVuY3Rpb24gKHBhZ2VyKSB7CiAgICAgICAgICAgICAgICBpZiAoYnVua2VyID09PSBwYWdlci5idW5rZXIpIHsKICAgICAgICAgICAgICAgICAgICByZXQucHVzaChidW5rZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBQYWdlclNlcnZpY2U7Cn0oKTsKfSx7fV0sNTE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5QaXBlbGluZVNlcnZpY2UgPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfZGVzYywgX3ZhbHVlLCBfY2xhc3M7Cgp2YXIgX1BhZ2VyID0gcmVxdWlyZSgnLi9QYWdlcicpOwoKdmFyIF9yZXN0ID0gcmVxdWlyZSgnLi4vcGF0aHMvcmVzdCcpOwoKdmFyIF9yZXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3Jlc3QpOwoKdmFyIF9mZXRjaCA9IHJlcXVpcmUoJy4uL2ZldGNoJyk7Cgp2YXIgX3V0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTsKCnZhciBfdXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdXRpbHMpOwoKdmFyIF9CdW5rZXJTZXJ2aWNlMiA9IHJlcXVpcmUoJy4vQnVua2VyU2VydmljZScpOwoKdmFyIF9tb2J4ID0gcmVxdWlyZSgnbW9ieCcpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKZnVuY3Rpb24gX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcih0YXJnZXQsIHByb3BlcnR5LCBkZWNvcmF0b3JzLCBkZXNjcmlwdG9yLCBjb250ZXh0KSB7CiAgICB2YXIgZGVzYyA9IHt9OwogICAgT2JqZWN0WydrZScgKyAneXMnXShkZXNjcmlwdG9yKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsKICAgICAgICBkZXNjW2tleV0gPSBkZXNjcmlwdG9yW2tleV07CiAgICB9KTsKICAgIGRlc2MuZW51bWVyYWJsZSA9ICEhZGVzYy5lbnVtZXJhYmxlOwogICAgZGVzYy5jb25maWd1cmFibGUgPSAhIWRlc2MuY29uZmlndXJhYmxlOwoKICAgIGlmICgndmFsdWUnIGluIGRlc2MgfHwgZGVzYy5pbml0aWFsaXplcikgewogICAgICAgIGRlc2Mud3JpdGFibGUgPSB0cnVlOwogICAgfQoKICAgIGRlc2MgPSBkZWNvcmF0b3JzLnNsaWNlKCkucmV2ZXJzZSgpLnJlZHVjZShmdW5jdGlvbiAoZGVzYywgZGVjb3JhdG9yKSB7CiAgICAgICAgcmV0dXJuIGRlY29yYXRvcih0YXJnZXQsIHByb3BlcnR5LCBkZXNjKSB8fCBkZXNjOwogICAgfSwgZGVzYyk7CgogICAgaWYgKGNvbnRleHQgJiYgZGVzYy5pbml0aWFsaXplciAhPT0gdm9pZCAwKSB7CiAgICAgICAgZGVzYy52YWx1ZSA9IGRlc2MuaW5pdGlhbGl6ZXIgPyBkZXNjLmluaXRpYWxpemVyLmNhbGwoY29udGV4dCkgOiB2b2lkIDA7CiAgICAgICAgZGVzYy5pbml0aWFsaXplciA9IHVuZGVmaW5lZDsKICAgIH0KCiAgICBpZiAoZGVzYy5pbml0aWFsaXplciA9PT0gdm9pZCAwKSB7CiAgICAgICAgT2JqZWN0WydkZWZpbmUnICsgJ1Byb3BlcnR5J10odGFyZ2V0LCBwcm9wZXJ0eSwgZGVzYyk7CiAgICAgICAgZGVzYyA9IG51bGw7CiAgICB9CgogICAgcmV0dXJuIGRlc2M7Cn0KCi8qKgogKiBUaGlzIGNsYXNzIGhhbmRsZXMgcGlwZWxpbmUgcmVsYXRlZCBkYXRhLiBUaGlzIGluY2x1ZGVzIHBpcGVsaW5lcywgYnJhbmNoZXMgYW5kIHB1bGxyZXF1ZXVzdHMgYXMgdGhleSBhcmUKICogYWxsIHBpcGVsaW5lcyBpbiB0aGUgYmFja2VuZC4KICoKICogQGV4cG9ydAogKiBAY2xhc3MgUGlwZWxpbmVTZXJ2aWNlCiAqIEBleHRlbmRzIHtCdW5rZXJTZXJ2aWNlfQogKi8KdmFyIFBpcGVsaW5lU2VydmljZSA9IGV4cG9ydHMuUGlwZWxpbmVTZXJ2aWNlID0gKF9jbGFzcyA9IGZ1bmN0aW9uIChfQnVua2VyU2VydmljZSkgewogICAgX2luaGVyaXRzKFBpcGVsaW5lU2VydmljZSwgX0J1bmtlclNlcnZpY2UpOwoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBQaXBlbGluZVNlcnZpY2UuCiAgICAgKgogICAgICogQHBhcmFtIHtQYWdlclNlcnZpY2V9IHBhZ2VyU2VydmljZQogICAgICogQHBhcmFtIHtBY3Rpdml0eVNlcnZpY2V9IGFjdGl2aXR5U2VydmljZQogICAgICovCiAgICBmdW5jdGlvbiBQaXBlbGluZVNlcnZpY2UocGFnZXJTZXJ2aWNlLCBhY3Rpdml0eVNlcnZpY2UpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUGlwZWxpbmVTZXJ2aWNlKTsKCiAgICAgICAgdmFyIF90aGlzID0gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKFBpcGVsaW5lU2VydmljZS5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKFBpcGVsaW5lU2VydmljZSkpLmNhbGwodGhpcywgcGFnZXJTZXJ2aWNlKSk7CgogICAgICAgIF90aGlzLmJ1bmtlck1hcHBlciA9IGZ1bmN0aW9uIChwaXBlbGluZURhdGEpIHsKICAgICAgICAgICAgdmFyIGRhdGEgPSBfdXRpbHMyLmRlZmF1bHQuY2xvbmUocGlwZWxpbmVEYXRhKTsKICAgICAgICAgICAgdmFyIGxhdGVzdFJ1biA9IGRhdGEubGF0ZXN0UnVuOwoKICAgICAgICAgICAgaWYgKGxhdGVzdFJ1bikgewogICAgICAgICAgICAgICAgZGF0YS5sYXRlc3RSdW4gPSBfdGhpcy5hY3Rpdml0eVNlcnZpY2Uuc2V0SXRlbShsYXRlc3RSdW4pOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZGF0YTsKICAgICAgICB9OwoKICAgICAgICBfdGhpcy5hY3Rpdml0eVNlcnZpY2UgPSBhY3Rpdml0eVNlcnZpY2U7CiAgICAgICAgcmV0dXJuIF90aGlzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBwYWdlciBmb3IgL2JsdWUvcGlwZWxpbmVzCiAgICAgKgogICAgICogQHJldHVybnMge1BhZ2VyfQogICAgICovCgoKICAgIF9jcmVhdGVDbGFzcyhQaXBlbGluZVNlcnZpY2UsIFt7CiAgICAgICAga2V5OiAnYWxsUGlwZWxpbmVzUGFnZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBhbGxQaXBlbGluZXNQYWdlcigpIHsKICAgICAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7CgogICAgICAgICAgICByZXR1cm4gdGhpcy5wYWdlclNlcnZpY2UuZ2V0UGFnZXIoewogICAgICAgICAgICAgICAga2V5OiAnUGlwZWxpbmVzQWxsJywKICAgICAgICAgICAgICAgIGxhenlQYWdlcjogZnVuY3Rpb24gbGF6eVBhZ2VyKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgX1BhZ2VyLlBhZ2VyKF9yZXN0Mi5kZWZhdWx0LmFsbFBpcGVsaW5lcygpLCAyNSwgX3RoaXMyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBHZXRzIHBhZ2VyIGZvciAvYmx1ZS9vcmdhbml6YXRpb24vOm9yZ2FuaXphdGlvbi9waXBlbGluZXMKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7c3RyaW5ifSBvcmdhbml6YXRpb24gb3JnYW5pemF0aW9uIHBhZ2VyIGJlbG9uZ3MgdG8uCiAgICAgICAgICogQHJldHVybnMge1BhZ2VyfQogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdvcmdhbml6dGlvblBpcGVsaW5lc1BhZ2VyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gb3JnYW5penRpb25QaXBlbGluZXNQYWdlcihvcmdhbml6YXRpb24pIHsKICAgICAgICAgICAgdmFyIF90aGlzMyA9IHRoaXM7CgogICAgICAgICAgICByZXR1cm4gdGhpcy5wYWdlclNlcnZpY2UuZ2V0UGFnZXIoewogICAgICAgICAgICAgICAga2V5OiAnUGlwZWxpbmVzLycgKyBvcmdhbml6YXRpb24sCiAgICAgICAgICAgICAgICBsYXp5UGFnZXI6IGZ1bmN0aW9uIGxhenlQYWdlcigpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IF9QYWdlci5QYWdlcihfcmVzdDIuZGVmYXVsdC5vcmdhbml6YXRpb25QaXBlbGluZXMob3JnYW5pemF0aW9uKSwgMjUsIF90aGlzMyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0cyBwYWdlciBmb3IgL2JsdWUvb3JnYW5pemF0aW9uLzpvcmdhbml6YXRpb24vcGlwZWxpbmVzLzpwaXBlbGluZS9icmFuY2hlcwogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IG9yZ2FuaXphdGlvbgogICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwaXBlbGluZQogICAgICAgICAqIEByZXR1cm5zIHtQYWdlcn0KICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnYnJhbmNoUGFnZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBicmFuY2hQYWdlcihvcmdhbml6YXRpb24sIHBpcGVsaW5lKSB7CiAgICAgICAgICAgIHZhciBfdGhpczQgPSB0aGlzOwoKICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFnZXJTZXJ2aWNlLmdldFBhZ2VyKHsKICAgICAgICAgICAgICAgIGtleTogJ0JyYW5jaGVzLycgKyBvcmdhbml6YXRpb24gKyAnLScgKyBwaXBlbGluZSwKICAgICAgICAgICAgICAgIGxhenlQYWdlcjogZnVuY3Rpb24gbGF6eVBhZ2VyKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgX1BhZ2VyLlBhZ2VyKF9yZXN0Mi5kZWZhdWx0LmJyYW5jaGVzKG9yZ2FuaXphdGlvbiwgcGlwZWxpbmUpLCAyNSwgX3RoaXM0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBHZXRzIHBhZ2VyIGZvciAvYmx1ZS9vcmdhbml6YXRpb24vOm9yZ2FuaXphdGlvbi9waXBlbGluZXMvOnBpcGVsaW5lL3B1bGxSZXF1ZXN0cwogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IG9yZ2FuaXphdGlvbgogICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwaXBlbGluZQogICAgICAgICAqIEByZXR1cm5zIHtQYWdlcn0KICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAncHJQYWdlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHByUGFnZXIob3JnYW5pemF0aW9uLCBwaXBlbGluZSkgewogICAgICAgICAgICB2YXIgX3RoaXM1ID0gdGhpczsKCiAgICAgICAgICAgIHJldHVybiB0aGlzLnBhZ2VyU2VydmljZS5nZXRQYWdlcih7CiAgICAgICAgICAgICAgICBrZXk6ICdQUnMvJyArIG9yZ2FuaXphdGlvbiArICctJyArIHBpcGVsaW5lLAogICAgICAgICAgICAgICAgbGF6eVBhZ2VyOiBmdW5jdGlvbiBsYXp5UGFnZXIoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBfUGFnZXIuUGFnZXIoX3Jlc3QyLmRlZmF1bHQucHVsbFJlcXVlc3RzKG9yZ2FuaXphdGlvbiwgcGlwZWxpbmUpLCAyNSwgX3RoaXM1KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIEFkZHMgdGhlIGxhdGVzdCBydW4gdG8gdGhlIFtAbGluayBBY3Rpdml0eVNlcnZpY2VdLCBhbmQgc2V0cyB0aGUgbGF0ZXN0UnVuIGFzIGEgbW9ieCBjb21wdXRlZCB2YWx1ZS4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwaXBlbGluZURhdGEgUmF3IGRhdGEgZnJvbSBiYWNrZW5kLgogICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gbWFwcGVkIHBpcGVsaW5lRGF0YSB3aXRoIGxhdGVzdFJ1biBzZXQgdG8gYmUgYSBtb2J4IGNvbXB1dGVkIHZhbHVlLgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdnZXRQaXBlbGluZScsCgogICAgICAgIC8qKgogICAgICAgICAqIEdldHMgYSBwaXBlbGluZSBmcm9tIHRoZSBzdG9yZQogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGhyZWYgLSBTZWxmIGhyZWYgb2YgdGhlIHBpcGVsaW5lLgogICAgICAgICAqIEByZXR1cm5zIHtPYmplY3R9IC0gTW9ieCBjb21wdXRlZCB2YWx1ZSBvZiB0aGUgcGlwZWxpbmUuCiAgICAgICAgICovCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldFBpcGVsaW5lKGhyZWYpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SXRlbShocmVmKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEZldGNoZXMgcGlwZWxpbmUgZnJvbSB0aGUgYmFja2VuZCBhbmQgc3RvcmVzIGl0IGluCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gaHJlZiAtIFNlbGYgaHJlZiBvZiB0aGUgcGlwZWxpbmUuCiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMKICAgICAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IG9wdGlvbnMudXNlQ2FjaGUgLSBJZiB0cnVlIGZldGNoIGZyb20gdGhlIHN0b3JlIGlmIGl0IGV4aXN0cy4KICAgICAgICAgKiBAcmV0dXJucwogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdmZXRjaFBpcGVsaW5lJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZmV0Y2hQaXBlbGluZShocmVmKSB7CiAgICAgICAgICAgIHZhciBfdGhpczYgPSB0aGlzOwoKICAgICAgICAgICAgdmFyIF9yZWYgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9LAogICAgICAgICAgICAgICAgdXNlQ2FjaGUgPSBfcmVmLnVzZUNhY2hlOwoKICAgICAgICAgICAgaWYgKHVzZUNhY2hlICYmIHRoaXMuaGFzSXRlbShocmVmKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLmdldEl0ZW0oaHJlZikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gX2ZldGNoLkZldGNoLmZldGNoSlNPTihocmVmKS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXM2LnNldEl0ZW0oZGF0YSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogTW9iWCBBY3Rpb24gdG8gdXBkYXRlIHRoZSBsYXRlc3QgcnVuIG9uIGEgcGlwZWxpbmUuIFVzZSBmb3IgU1NFLiBUaGlzIHdpbGwgY2F1c2UgYSByZWFjdGlvbgogICAgICAgICAqIGFuZCByZXJlbmRlciBhbnl0aGluZyB0aGF0IHVzZXMgdGhlIGxhdGVzdCBydW4gb2YgdGhpcyBwaXBlbGluZS4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBydW4gQW4gYWN0aXZpdHkgZnJvbSBhY3Rpdml0eVNlcnZpY2UuZ2V0SXRlbSgpLgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICd1cGRhdGVMYXRlc3RSdW4nLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiB1cGRhdGVMYXRlc3RSdW4ocnVuKSB7CiAgICAgICAgICAgIHZhciBwaXBlbGluZSA9IHRoaXMuZ2V0SXRlbShydW4uX2xpbmtzLnBhcmVudC5ocmVmKTsKICAgICAgICAgICAgaWYgKHBpcGVsaW5lKSB7CiAgICAgICAgICAgICAgICBwaXBlbGluZS5sYXRlc3RSdW4gPSBydW47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFBpcGVsaW5lU2VydmljZTsKfShfQnVua2VyU2VydmljZTIuQnVua2VyU2VydmljZSksIChfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsICd1cGRhdGVMYXRlc3RSdW4nLCBbX21vYnguYWN0aW9uXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCAndXBkYXRlTGF0ZXN0UnVuJyksIF9jbGFzcy5wcm90b3R5cGUpKSwgX2NsYXNzKTsKfSx7Ii4uL2ZldGNoIjoyMiwiLi4vcGF0aHMvcmVzdCI6NDEsIi4uL3V0aWxzIjo1OSwiLi9CdW5rZXJTZXJ2aWNlIjo0NiwiLi9QYWdlciI6NDksIm1vYngiOjM4OX1dLDUyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuU1NFU2VydmljZSA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF91dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7Cgp2YXIgX3V0aWxzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3V0aWxzKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCnZhciBTU0VTZXJ2aWNlID0gZXhwb3J0cy5TU0VTZXJ2aWNlID0gZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gU1NFU2VydmljZShjb25uZWN0aW9uKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFNTRVNlcnZpY2UpOwoKICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uOwogICAgICAgIHRoaXMuX2hhbmRsZXJzID0gW107CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFNTRVNlcnZpY2UsIFt7CiAgICAgICAga2V5OiAnX2luaXRMaXN0ZW5lcnMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfaW5pdExpc3RlbmVycygpIHsKICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpczsKCiAgICAgICAgICAgIGlmICghdGhpcy5qb2JMaXN0ZW5lcikgewogICAgICAgICAgICAgICAgdGhpcy5qb2JMaXN0ZW5lciA9IHRoaXMuY29ubmVjdGlvbi5zdWJzY3JpYmUoJ2pvYicsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgIF90aGlzLl9oYW5kbGVKb2JFdmVudChldmVudCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQWRkIGEgaGFuZGxlciBmb3Igam9iIGV2ZW50cy4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJGbgogICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IGlkIHVzZWQgYnkgcmVtb3ZlSGFuZGxlcgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdyZWdpc3RlckhhbmRsZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZWdpc3RlckhhbmRsZXIoaGFuZGxlckZuKSB7CiAgICAgICAgICAgIHZhciBpZCA9IF91dGlsczIuZGVmYXVsdC5yYW5kb21JZCgnc3NlJyk7CgogICAgICAgICAgICB0aGlzLl9oYW5kbGVycy5wdXNoKHsKICAgICAgICAgICAgICAgIGlkOiBpZCwKICAgICAgICAgICAgICAgIGhhbmRsZXJGbjogaGFuZGxlckZuCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgcmV0dXJuIGlkOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUmVtb3ZlIGEgcHJldmlvdXNseS1yZWdpc3RlcmVkIGhhbmRsZXIuCiAgICAgICAgICogQHBhcmFtIGlkCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ3JlbW92ZUhhbmRsZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW1vdmVIYW5kbGVyKGlkKSB7CiAgICAgICAgICAgIHRoaXMuX2hhbmRsZXJzID0gdGhpcy5faGFuZGxlcnMuZmlsdGVyKGZ1bmN0aW9uIChoYW5kbGVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlci5pZCAhPT0gaWQ7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfaGFuZGxlSm9iRXZlbnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfaGFuZGxlSm9iRXZlbnQoZXZlbnQpIHsKICAgICAgICAgICAgdGhpcy5faGFuZGxlcnMuZm9yRWFjaChmdW5jdGlvbiAoaGFuZGxlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZXIuaGFuZGxlckZuKGV2ZW50KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBTU0VTZXJ2aWNlOwp9KCk7Cn0seyIuLi91dGlscyI6NTl9XSw1MzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICB2YWx1ZTogdHJ1ZQp9KTsKCnZhciBfUGFnZXJTZXJ2aWNlID0gcmVxdWlyZSgnLi9QYWdlclNlcnZpY2UnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnUGFnZXJTZXJ2aWNlJywgewogIGVudW1lcmFibGU6IHRydWUsCiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICByZXR1cm4gX1BhZ2VyU2VydmljZS5QYWdlclNlcnZpY2U7CiAgfQp9KTsKCnZhciBfUGlwZWxpbmVTZXJ2aWNlID0gcmVxdWlyZSgnLi9QaXBlbGluZVNlcnZpY2UnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnUGlwZWxpbmVTZXJ2aWNlJywgewogIGVudW1lcmFibGU6IHRydWUsCiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICByZXR1cm4gX1BpcGVsaW5lU2VydmljZS5QaXBlbGluZVNlcnZpY2U7CiAgfQp9KTsKCnZhciBfU1NFU2VydmljZSA9IHJlcXVpcmUoJy4vU1NFU2VydmljZScpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdTU0VTZXJ2aWNlJywgewogIGVudW1lcmFibGU6IHRydWUsCiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICByZXR1cm4gX1NTRVNlcnZpY2UuU1NFU2VydmljZTsKICB9Cn0pOwoKdmFyIF9QYWdlciA9IHJlcXVpcmUoJy4vUGFnZXInKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnUGFnZXInLCB7CiAgZW51bWVyYWJsZTogdHJ1ZSwKICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgIHJldHVybiBfUGFnZXIuUGFnZXI7CiAgfQp9KTsKCnZhciBfQWN0aXZpdHlTZXJ2aWNlID0gcmVxdWlyZSgnLi9BY3Rpdml0eVNlcnZpY2UnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnQWN0aXZpdHlTZXJ2aWNlJywgewogIGVudW1lcmFibGU6IHRydWUsCiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICByZXR1cm4gX0FjdGl2aXR5U2VydmljZS5BY3Rpdml0eVNlcnZpY2U7CiAgfQp9KTsKCnZhciBfRGVmYXVsdFNTRUhhbmRsZXIgPSByZXF1aXJlKCcuL0RlZmF1bHRTU0VIYW5kbGVyJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ0RlZmF1bHRTU0VIYW5kbGVyJywgewogIGVudW1lcmFibGU6IHRydWUsCiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICByZXR1cm4gX0RlZmF1bHRTU0VIYW5kbGVyLkRlZmF1bHRTU0VIYW5kbGVyOwogIH0KfSk7Cgp2YXIgX0xvY2F0aW9uU2VydmljZSA9IHJlcXVpcmUoJy4vTG9jYXRpb25TZXJ2aWNlJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ0xvY2F0aW9uU2VydmljZScsIHsKICBlbnVtZXJhYmxlOiB0cnVlLAogIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgcmV0dXJuIF9Mb2NhdGlvblNlcnZpY2UuTG9jYXRpb25TZXJ2aWNlOwogIH0KfSk7Cn0seyIuL0FjdGl2aXR5U2VydmljZSI6NDUsIi4vRGVmYXVsdFNTRUhhbmRsZXIiOjQ3LCIuL0xvY2F0aW9uU2VydmljZSI6NDgsIi4vUGFnZXIiOjQ5LCIuL1BhZ2VyU2VydmljZSI6NTAsIi4vUGlwZWxpbmVTZXJ2aWNlIjo1MSwiLi9TU0VTZXJ2aWNlIjo1Mn1dLDU0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuU3NlQnVzID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7IC8qKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogQ3JlYXRlZCBieSBjbWV5ZXJzIG9uIDcvMjkvMTYuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCgp2YXIgX2lzb21vcnBoaWNGZXRjaCA9IHJlcXVpcmUoJ2lzb21vcnBoaWMtZmV0Y2gnKTsKCnZhciBfaXNvbW9ycGhpY0ZldGNoMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzb21vcnBoaWNGZXRjaCk7Cgp2YXIgX3VybGNvbmZpZyA9IHJlcXVpcmUoJy4uL3VybGNvbmZpZycpOwoKdmFyIF91cmxjb25maWcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdXJsY29uZmlnKTsKCnZhciBfdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpOwoKdmFyIF91dGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF91dGlscyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgovKioKICogV3JhcHMgdGhlIFNTRSBHYXRld2F5IGFuZCBmZXRjaGVzIGRhdGEgcmVsYXRlZCB0byBldmVudHMgZnJvbSBSRVNUIEFQSS4KICovCnZhciBTc2VCdXMgPSBleHBvcnRzLlNzZUJ1cyA9IGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFNzZUJ1cyhjb25uZWN0aW9uLCBmZXRjaCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTc2VCdXMpOwoKICAgICAgICB0aGlzLmlkID0gdGhpcy5fcmFuZG9tKCk7CiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjsKICAgICAgICB0aGlzLmZldGNoID0gZmV0Y2ggfHwgX2lzb21vcnBoaWNGZXRjaDIuZGVmYXVsdDsKICAgICAgICB0aGlzLmV4dGVybmFsTGlzdGVuZXJzID0ge307CiAgICAgICAgdGhpcy5zc2VMaXN0ZW5lcnMgPSB7fTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoU3NlQnVzLCBbewogICAgICAgIGtleTogJ2Rpc3Bvc2UnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBkaXNwb3NlKCkgewogICAgICAgICAgICB2YXIgX3RoaXMgPSB0aGlzOwoKICAgICAgICAgICAgT2JqZWN0LmtleXModGhpcy5zc2VMaXN0ZW5lcnMpLmZvckVhY2goZnVuY3Rpb24gKHRva2VuKSB7CiAgICAgICAgICAgICAgICBfdGhpcy51bnN1YnNjcmliZSh0b2tlbik7CiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgdGhpcy5leHRlcm5hbExpc3RlbmVycyA9IHt9OwogICAgICAgICAgICB0aGlzLnNzZUxpc3RlbmVycyA9IHt9OwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogU3Vic2NyaWJlIHRvIGpvYiBldmVudHMuCiAgICAgICAgICogQHBhcmFtIGNhbGxiYWNrIGZ1bmMgdG8gaW52b2tlIHdpdGggam9iIGRhdGEKICAgICAgICAgKiBAcGFyYW0gam9iRmlsdGVyIGZ1bmMgaW52b2tlZCBmb3IgZWFjaCBqb2IgZXZlbnQsIHJldHVybiBmYWxzZSB0byBzdXBwcmVzcyBjYWxsYmFjayBpbnZvY2F0aW9uCiAgICAgICAgICogQHJldHVybnMge251bWJlcn0gdW5zdWJzY3JpYmUgdG9rZW4KICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnc3Vic2NyaWJlVG9Kb2InLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzdWJzY3JpYmVUb0pvYihjYWxsYmFjaywgam9iRmlsdGVyKSB7CiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzOwoKICAgICAgICAgICAgdmFyIGlkID0gdGhpcy5fcmFuZG9tKCk7CgogICAgICAgICAgICB0aGlzLmV4dGVybmFsTGlzdGVuZXJzW2lkXSA9IHsKICAgICAgICAgICAgICAgIGxpc3RlbmVyOiBjYWxsYmFjaywKICAgICAgICAgICAgICAgIGZpbHRlcjogam9iRmlsdGVyCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBpZiAoIXRoaXMuc3NlTGlzdGVuZXJzLmpvYikgewogICAgICAgICAgICAgICAgdmFyIHNzZUxpc3RlbmVyID0gdGhpcy5jb25uZWN0aW9uLnN1YnNjcmliZSgnam9iJywgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgX3RoaXMyLl9oYW5kbGVKb2JFdmVudChldmVudCk7CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICB0aGlzLnNzZUxpc3RlbmVycy5qb2IgPSBzc2VMaXN0ZW5lcjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGlkOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICd1bnN1YnNjcmliZScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHVuc3Vic2NyaWJlKHRva2VuKSB7CiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmV4dGVybmFsTGlzdGVuZXJzW3Rva2VuXTsKCiAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLmV4dGVybmFsTGlzdGVuZXJzKS5sZW5ndGggPT09IDApIHsKICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi51bnN1YnNjcmliZSh0aGlzLnNzZUxpc3RlbmVycy5qb2IpOwogICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3NlTGlzdGVuZXJzLmpvYjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfaGFuZGxlSm9iRXZlbnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfaGFuZGxlSm9iRXZlbnQoZXZlbnQpIHsKICAgICAgICAgICAgdmFyIF90aGlzMyA9IHRoaXM7CgogICAgICAgICAgICB2YXIgc3Vic2NyaXB0aW9ucyA9IE9iamVjdC5rZXlzKHRoaXMuZXh0ZXJuYWxMaXN0ZW5lcnMpLm1hcChmdW5jdGlvbiAoc3ViSWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczMuZXh0ZXJuYWxMaXN0ZW5lcnNbc3ViSWRdOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIHZhciBpbnRlcmVzdGVkTGlzdGVuZXJzID0gc3Vic2NyaXB0aW9ucy5maWx0ZXIoZnVuY3Rpb24gKHN1YikgewogICAgICAgICAgICAgICAgcmV0dXJuIHN1Yi5maWx0ZXIoZXZlbnQpOwogICAgICAgICAgICB9KS5tYXAoZnVuY3Rpb24gKHN1YikgewogICAgICAgICAgICAgICAgcmV0dXJuIHN1Yi5saXN0ZW5lcjsKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAvLyBpZiBubyBmaWx0ZXJzIGFyZSBpbnRlcmVzdGVkIGluIHRoZSBldmVudCwgYmFpbAogICAgICAgICAgICBpZiAoaW50ZXJlc3RlZExpc3RlbmVycy5sZW5ndGggPT09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3dpdGNoIChldmVudC5qZW5raW5zX2V2ZW50KSB7CiAgICAgICAgICAgICAgICBjYXNlICdqb2JfY3J1ZF9jcmVhdGVkJzoKICAgICAgICAgICAgICAgIGNhc2UgJ2pvYl9jcnVkX2RlbGV0ZWQnOgogICAgICAgICAgICAgICAgY2FzZSAnam9iX2NydWRfcmVuYW1lZCc6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVmZXRjaFBpcGVsaW5lcygpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnam9iX3J1bl9xdWV1ZV9idWlsZGFibGUnOgogICAgICAgICAgICAgICAgY2FzZSAnam9iX3J1bl9xdWV1ZV9lbnRlcic6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZW5xdWV1ZUpvYihldmVudCwgaW50ZXJlc3RlZExpc3RlbmVycyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdqb2JfcnVuX3F1ZXVlX2xlZnQnOgogICAgICAgICAgICAgICAgY2FzZSAnam9iX3J1bl9xdWV1ZV9ibG9ja2VkJzoKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhc2UgJ2pvYl9ydW5fcGF1c2VkJzoKICAgICAgICAgICAgICAgIGNhc2UgJ2pvYl9ydW5fdW5wYXVzZWQnOgogICAgICAgICAgICAgICAgY2FzZSAnam9iX3J1bl9zdGFydGVkJzoKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUpvYihldmVudCwgaW50ZXJlc3RlZExpc3RlbmVycyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhc2UgJ2pvYl9ydW5fZW5kZWQnOgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlSm9iKGV2ZW50LCBpbnRlcmVzdGVkTGlzdGVuZXJzKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIC8vIEVsc2UgaWdub3JlIHRoZSBldmVudC4KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfcmVmZXRjaFBpcGVsaW5lcycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9yZWZldGNoUGlwZWxpbmVzKCkgewogICAgICAgICAgICAvLyBUT0RPOiBpbXBsZW1lbnQgb25jZSBtaWdyYXRpb24gaW50byBjb21tb25zIEpTCiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ19lbnF1ZXVlSm9iJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX2VucXVldWVKb2IoZXZlbnQsIGxpc3RlbmVycykgewogICAgICAgICAgICB2YXIgcXVldWVkUnVuID0ge307CgogICAgICAgICAgICBxdWV1ZWRSdW4ucGlwZWxpbmUgPSBldmVudC5qb2JfaXNtdWx0aWJyYW5jaCA/IGV2ZW50LmJsdWVvY2Vhbl9qb2JfYnJhbmNoX25hbWUgOiBldmVudC5ibHVlb2NlYW5fam9iX3BpcGVsaW5lX25hbWU7CgogICAgICAgICAgICB2YXIgcnVuVXJsID0gX3V0aWxzMi5kZWZhdWx0LmNsZWFuU2xhc2hlcyhldmVudC5ibHVlb2NlYW5fam9iX3Jlc3RfdXJsICsgJy9ydW5zLycgKyBldmVudC5qb2JfcnVuX3F1ZXVlSWQpOwoKICAgICAgICAgICAgcXVldWVkUnVuLl9saW5rcyA9IHsKICAgICAgICAgICAgICAgIHNlbGY6IHsKICAgICAgICAgICAgICAgICAgICBocmVmOiBydW5VcmwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHF1ZXVlZFJ1bi5zdGF0ZSA9ICdRVUVVRUQnOwogICAgICAgICAgICBxdWV1ZWRSdW4ucmVzdWx0ID0gJ1VOS05PV04nOwoKICAgICAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSB0cnVlOwogICAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IgPSBmYWxzZTsKICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvciA9IGxpc3RlbmVyc1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSAoX3N0ZXAgPSBfaXRlcmF0b3IubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBfc3RlcC52YWx1ZTsKCiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIocXVldWVkUnVuLCBldmVudCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IgPSB0cnVlOwogICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IgPSBlcnI7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiAmJiBfaXRlcmF0b3IucmV0dXJuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvci5yZXR1cm4oKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcikgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX3VwZGF0ZUpvYicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF91cGRhdGVKb2IoZXZlbnQsIGxpc3RlbmVycykgewogICAgICAgICAgICB2YXIgYmFzZVVybCA9IF91cmxjb25maWcyLmRlZmF1bHQuZ2V0SmVua2luc1Jvb3RVUkwoKTsKICAgICAgICAgICAgdmFyIHVybCA9IF91dGlsczIuZGVmYXVsdC5jbGVhblNsYXNoZXMoYmFzZVVybCArICcvJyArIGV2ZW50LmJsdWVvY2Vhbl9qb2JfcmVzdF91cmwgKyAnL3J1bnMvJyArIGV2ZW50LmplbmtpbnNfb2JqZWN0X2lkKTsKCiAgICAgICAgICAgIHRoaXMuZmV0Y2godXJsKS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgICAgICAgICB2YXIgdXBkYXRlZFJ1biA9IF91dGlsczIuZGVmYXVsdC5jbG9uZShkYXRhKTsKCiAgICAgICAgICAgICAgICAvLyBGSVhNRTogVGFsayB0byBDTWV5ZXJzIHdoeSB3ZSBjYW5ub3QgdXNlIHRoZSBkYXRhLnN0YXRlPwogICAgICAgICAgICAgICAgLy8gaW4gbWFueSBjYXNlcyB0aGUgU1NFIGFuZCBzdWJzZXF1ZW50IFJFU1QgY2FsbCBvY2N1ciBzbyBxdWlja2x5CiAgICAgICAgICAgICAgICAvLyB0aGF0IHRoZSBydW4ncyBzdGF0ZSBpcyBzdGFsZS4gZm9yY2UgdGhlIHN0YXRlIHRvIHRoZSBjb3JyZWN0IHZhbHVlLgogICAgICAgICAgICAgICAgaWYgKGV2ZW50LmplbmtpbnNfZXZlbnQgPT09ICdqb2JfcnVuX2VuZGVkJykgewogICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRSdW4uc3RhdGUgPSAnRklOSVNIRUQnOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudC5qZW5raW5zX2V2ZW50ID09PSAnam9iX3J1bl9wYXVzZWQnKSB7CiAgICAgICAgICAgICAgICAgICAgdXBkYXRlZFJ1bi5zdGF0ZSA9ICdQQVVTRUQnOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB1cGRhdGVkUnVuLnN0YXRlID0gJ1JVTk5JTkcnOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMiA9IHRydWU7CiAgICAgICAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IyID0gZmFsc2U7CiAgICAgICAgICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IyID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IGxpc3RlbmVyc1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwMjsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMiA9IChfc3RlcDIgPSBfaXRlcmF0b3IyLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yID0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBfc3RlcDIudmFsdWU7CgogICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcih1cGRhdGVkUnVuLCBldmVudCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IyID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvcjIgPSBlcnI7CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIgJiYgX2l0ZXJhdG9yMi5yZXR1cm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvcjIucmV0dXJuKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfdXBkYXRlTXVsdGlCcmFuY2hQaXBlbGluZUJyYW5jaGVzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX3VwZGF0ZU11bHRpQnJhbmNoUGlwZWxpbmVCcmFuY2hlcygpIHt9CiAgICAgICAgLy8gVE9ETzogaW1wbGVtZW50IG9uY2UgbWlncmF0aW9uIGludG8gY29tbW9ucyBKUwoKCiAgICAgICAgLyoqCiAgICAgICAgICogQHJldHVybnMge251bWJlcn0KICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdfcmFuZG9tJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX3JhbmRvbSgpIHsKICAgICAgICAgICAgcmV0dXJuIE1hdGgucmFuZG9tKCkgKiBNYXRoLnBvdygxMCwgMTYpOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gU3NlQnVzOwp9KCk7Cn0seyIuLi91cmxjb25maWciOjU4LCIuLi91dGlscyI6NTksImlzb21vcnBoaWMtZmV0Y2giOjMyOX1dLDU1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuX2NsZWFySmVua2luc05TID0gZXhwb3J0cy5pbnN0YWxsSW5mbyA9IGV4cG9ydHMuamVua2luc05TID0gdW5kZWZpbmVkOwoKdmFyIF9zdG9yYWdlID0gcmVxdWlyZSgnQGplbmtpbnMtY2Qvc3RvcmFnZScpOwoKdmFyIHN0b3JhZ2UgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfc3RvcmFnZSk7Cgp2YXIgX3Njb3BlcyA9IHJlcXVpcmUoJy4vc2NvcGVzJyk7Cgp2YXIgX2NvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7Cgp2YXIgX2NvbmZpZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9jb25maWcpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKG9iaikgeyBpZiAob2JqICYmIG9iai5fX2VzTW9kdWxlKSB7IHJldHVybiBvYmo7IH0gZWxzZSB7IHZhciBuZXdPYmogPSB7fTsgaWYgKG9iaiAhPSBudWxsKSB7IGZvciAodmFyIGtleSBpbiBvYmopIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIG5ld09ialtrZXldID0gb2JqW2tleV07IH0gfSBuZXdPYmouZGVmYXVsdCA9IG9iajsgcmV0dXJuIG5ld09iajsgfSB9Cgp2YXIgamVua2luc05TID0gZXhwb3J0cy5qZW5raW5zTlMgPSBzdG9yYWdlLmplbmtpbnNOYW1lc3BhY2UoKTsgLyoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFRoZSBNSVQgTGljZW5zZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIENvcHlyaWdodCAoYykgMjAxNywgQ2xvdWRCZWVzLCBJbmMuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVEhFIFNPRlRXQVJFLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCgovKioKICogQ2xpZW50LXNpZGUgbG9jYWwgc3RvcmFnZSBmb3IgQmx1ZSBPY2Vhbi4KICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9qZW5raW5zY2kvanMtc3RvcmFnZQogKi8KCnZhciBpbnN0YWxsSW5mbyA9IGV4cG9ydHMuaW5zdGFsbEluZm8gPSBqZW5raW5zTlMuc3Vic3BhY2UoJ2luc3RhbGxJbmZvJyk7CgovKioKICogQ2hlY2sgZG8gd2UgbmVlZCB0byBjbGVhciB0aGUgamVua2luc05TLgogKiA8cD4KICogU2ltcGxlIHByb2Nlc3Mgb2YgY2hlY2tpbmcgaWYgdGhlIHZlcnNpb24gT1IgbGlzdCBvZiBwbHVnaW5zCiAqIHN0b3JlZCAoZnJvbSB0aGUgbGFzdCBjaGFuZ2UpIGhhdmUgY2hhbmdlZCBiYXNlZCBvbiB3aGF0IHdhcwogKiBkZWxpdmVyZWQgd2l0aCB0aGlzIHBhZ2UuCiAqIDxwPgogKiBJbnRlcm5hbCB1c2Ugb25seS4gRXhwb3J0ZWQgZm9yIHRlc3RpbmcgcHVycG9zZXMgb25seS4KICogQHBhcmFtIHtzdHJpbmd9IGluc3RhbGxWZXJzaW9uIFRoZSB2ZXJzaW9uIG9mIHRoZSBKZW5raW5zIGluc3RhbmNlIHRoYXQncyBydW5uaW5nIG5vdwogKiBpLmUuIHRoYXQgbG9hZGVkIHRoaXMgcGFnZS4KICogQHBhcmFtIHtBcnJheX0gaW5zdGFsbFBsdWdpbkxpc3QgVGhlIGxpc3Qgb2YgYWN0aXZlIHBsdWdpbnMgaW5zdGFsbGVkIGluIHRoZSBKZW5raW5zIGluc3RhbmNlCiAqIHRoYXQncyBydW5uaW5nIG5vdyBpLmUuIHRoYXQgbG9hZGVkIHRoaXMgcGFnZS4KICogQHByaXZhdGUKICovCnZhciBfY2xlYXJKZW5raW5zTlMgPSBleHBvcnRzLl9jbGVhckplbmtpbnNOUyA9IGZ1bmN0aW9uIF9jbGVhckplbmtpbnNOUyhpbnN0YWxsVmVyc2lvbiwgaW5zdGFsbFBsdWdpbkxpc3QpIHsKICAgIC8vIEluZm8gYWJvdXQgdGhlIEplbmtpbnMgdGhhdCB3YXMgcnVubmluZyB0aGUgbGFzdCB0aW1lIHdlIGxvYWRlZCB0aGlzIHBhZ2UuCiAgICB2YXIgc3RvcmVkVmVyc2lvbiA9IGluc3RhbGxJbmZvLmdldCgndmVyc2lvbicpOwogICAgdmFyIHN0b3JlZFBsdWdpbkxpc3QgPSBpbnN0YWxsSW5mby5nZXQoJ3BsdWdpbnMnKTsKCiAgICB2YXIgZG9DbGVhciA9IGZ1bmN0aW9uIGRvQ2xlYXIoYmVjYXVzZSkgewogICAgICAgIGplbmtpbnNOUy5jbGVhcigpOwogICAgICAgIGluc3RhbGxJbmZvLnNldCgndmVyc2lvbicsIGluc3RhbGxWZXJzaW9uKTsKICAgICAgICBpbnN0YWxsSW5mby5zZXQoJ3BsdWdpbnMnLCBpbnN0YWxsUGx1Z2luTGlzdCk7CiAgICAgICAgaW5zdGFsbEluZm8uc2V0KCdsYXN0Y2xlYXJlZCcsIHsKICAgICAgICAgICAgYXQ6IERhdGUubm93KCksCiAgICAgICAgICAgIGJlY2F1c2U6IGJlY2F1c2UKICAgICAgICB9KTsKICAgIH07CgogICAgdHJ5IHsKICAgICAgICBpZiAoc3RvcmVkVmVyc2lvbiAmJiBzdG9yZWRQbHVnaW5MaXN0KSB7CiAgICAgICAgICAgIC8vIGNvbXBhcmUgdGhlIEplbmtpbnMgdmVyc2lvbgogICAgICAgICAgICBpZiAoaW5zdGFsbFZlcnNpb24gIT09IHN0b3JlZFZlcnNpb24pIHsKICAgICAgICAgICAgICAgIGRvQ2xlYXIoJ0plbmtpbnMgdmVyc2lvbnMgZGlkIG5vdCBtYXRjaC4gaW5zdGFsbFZlcnNpb246ICcgKyBpbnN0YWxsVmVyc2lvbiArICcsIHN0b3JlZFZlcnNpb246ICcgKyBzdG9yZWRWZXJzaW9uKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGNvbXBhcmUgdGhlIHBsdWdpbiBsaXN0cwogICAgICAgICAgICAgICAgaWYgKGluc3RhbGxQbHVnaW5MaXN0Lmxlbmd0aCAhPT0gc3RvcmVkUGx1Z2luTGlzdC5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAvLyBEaWZmZXJlbnQgbnVtYmVyIG9mIGFjdGl2ZSBwbHVnaW5zLgogICAgICAgICAgICAgICAgICAgIC8vIE5vIG5lZWQgdG8gY2hlY2sgdGhlIG5hbWVzIGFuZCB2ZXJzaW9ucy4KICAgICAgICAgICAgICAgICAgICBkb0NsZWFyKCdEaWZmZXJlbnQgbnVtYmVyIG9mIGFjdGl2ZSBwbHVnaW5zJyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIFNhbWUgbnVtYmVyIG9mIHBsdWdpbnMuIExldHMgY2hlY2sgdGhhdCB0aGV5IGFsbAogICAgICAgICAgICAgICAgICAgIC8vIG1hdGNoIHVwIGkuZS4gdGhhdCB3ZSBjYW4gZmluZCBlYWNoIHBsdWdpbiBpbiBlYWNoIGxpc3QgYW5kCiAgICAgICAgICAgICAgICAgICAgLy8gdGhhdCB0aGUgdmVyc2lvbnMgbWF0Y2guCiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFsbFBsdWdpbkxpc3QuZm9yRWFjaChmdW5jdGlvbiAoaW5zdGFsbGVkUGx1Z2luKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZm91bmQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlZFBsdWdpbkxpc3QuZm9yRWFjaChmdW5jdGlvbiAoc3RvcmVkUGx1Z2luKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0b3JlZFBsdWdpbi5ocGlQbHVnaW5JZCA9PT0gaW5zdGFsbGVkUGx1Z2luLmhwaVBsdWdpbklkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNhbWUgcGx1Z2luLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoZSB2ZXJzaW9ucy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0b3JlZFBsdWdpbi5ocGlQbHVnaW5WZXIgIT09IGluc3RhbGxlZFBsdWdpbi5ocGlQbHVnaW5WZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRGlmZmVyZW50IHBsdWdpbiB2ZXJzaW9ucyBmb3IgcGx1Z2luICcgKyBpbnN0YWxsZWRQbHVnaW4uaHBpUGx1Z2luSWQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZvdW5kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOZXcgcGx1Z2luIGluc3RhbGxlZCAnICsgaW5zdGFsbGVkUGx1Z2luLmhwaVBsdWdpbklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgb2YgdGhlIHBsdWdpbnMgaGFzIGJlZW4gdXBkYXRlZCBvciByZW1vdmVkLgogICAgICAgICAgICAgICAgICAgICAgICAvLyBTZWUgRXJyb3JzIHRocm93biBpbnNpZGUgYWJvdmUgdHJ5L2NhdGNoLgogICAgICAgICAgICAgICAgICAgICAgICBkb0NsZWFyKGUubWVzc2FnZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gVGhlb3JldGljYWxseSBubyBuZWVkIHRvIGNsZWFyIGluIHRoaXMgY2FzZSwKICAgICAgICAgICAgLy8gYnV0IGxldHMgZG8gaXQgYW55d2F5LgogICAgICAgICAgICBkb0NsZWFyKCdObyBKZW5raW5zIGluZm8gc3RvcmVkLiBDbGVhcmluZyBhbnl3YXksIGp1c3QgaW4gY2FzZS4nKTsKICAgICAgICB9CiAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgY29uc29sZS5lcnJvcignVW5leHBlY3RlZCBlcnJvciB3aGlsZSBjaGVja2luZy9jbGVhcmluZyBKZW5raW5zIGluc3RhbmNlIGNsaWVudC1zaWRlIHN0b3JhZ2UuIENsZWFyaW5nIGFzIGEgcHJlY2F1dGlvbi4nLCBlKTsKICAgICAgICBkb0NsZWFyKCdVbmV4cGVjdGVkIGVycm9yIHdoaWxlIGNoZWNraW5nL2NsZWFyaW5nIEplbmtpbnMgaW5zdGFuY2UgY2xpZW50LXNpZGUgc3RvcmFnZTogJyArIGUubWVzc2FnZSk7CiAgICB9Cn07CgovLyBDYWxsIHRoZSBjbGVhciBmdW5jdGlvbiBhdXRvbWF0aWNhbGx5Lgp2YXIgaW5zdGFsbFZlcnNpb24gPSBfY29uZmlnMi5kZWZhdWx0LmdldEplbmtpbnNDb25maWcoKS52ZXJzaW9uOwp2YXIgaW5zdGFsbFBsdWdpbkxpc3QgPSBfc2NvcGVzLmJsdWVvY2Vhbi5qc0V4dGVuc2lvbnM7CmlmIChpbnN0YWxsVmVyc2lvbiAmJiBpbnN0YWxsUGx1Z2luTGlzdCkgewogICAgX2NsZWFySmVua2luc05TKGluc3RhbGxWZXJzaW9uLCBpbnN0YWxsUGx1Z2luTGlzdCk7Cn0gZWxzZSB7CiAgICBjb25zb2xlLndhcm4oJ1VuZXhwZWN0ZWQgc3RhdGUuIEJsdWUgT2NlYW4gcHJlbG9hZCBzdGF0ZSBub3Qgb24gcGFnZSBhcyBleHBlY3RlZC4gVGhpcyBpcyBva2F5IGlmIHJ1bm5pbmcgaW4gYSB0ZXN0LicpOwp9Cn0seyIuL2NvbmZpZyI6MjEsIi4vc2NvcGVzIjo0MywiQGplbmtpbnMtY2Qvc3RvcmFnZSI6MTM3fV0sNTY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgdmFsdWU6IHRydWUKfSk7Ci8qCiAqIFRoZSBNSVQgTGljZW5zZQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTcsIENsb3VkQmVlcywgSW5jLgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5CiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKICogdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAogKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgogKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAogKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOCiAqIFRIRSBTT0ZUV0FSRS4KICovCgovKioKICogUmVtb3ZlIGFsbCBodG1sIG1hcmt1cCB0YWdzIGZyb20gdGhlIHN1cHBsaWVkIG1hcmt1cCB0ZXh0LgogKiBAcGFyYW0ge3N0cmluZ30gbWFya3VwVGV4dCBUaGUgbWFya3VwIHRleHQgdG8gYmUgImNsZWFuZWQiLgogKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBjbGVhbmVkIG1hcmt1cCB0ZXh0LgogKi8KdmFyIHJlbW92ZU1hcmt1cFRhZ3MgPSBleHBvcnRzLnJlbW92ZU1hcmt1cFRhZ3MgPSBmdW5jdGlvbiByZW1vdmVNYXJrdXBUYWdzKG1hcmt1cFRleHQpIHsKICBpZiAodHlwZW9mIG1hcmt1cFRleHQgIT09ICdzdHJpbmcnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXJnIHR5cGUgZm9yICJtYXJrdXBUZXh0Ii4gTXVzdCBiZSBhIHN0cmluZy4nKTsKICB9CiAgcmV0dXJuIG1hcmt1cFRleHQucmVwbGFjZSgvPFtePl0qPi9nLCAnJyk7Cn07Cn0se31dLDU3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX2ZldGNoMiA9IHJlcXVpcmUoJy4vZmV0Y2gnKTsKCi8vIGRlZmF1bHQgaW1wbHMKdmFyIGZldGNoSlNPTiA9IF9mZXRjaDIuRmV0Y2guZmV0Y2hKU09OOwp2YXIgZmV0Y2ggPSBfZmV0Y2gyLkZldGNoLmZldGNoOwoKZXhwb3J0cy5kZWZhdWx0ID0gewoKICAgIC8qKgogICAgICogU3dpdGNoZXMgZmV0Y2ggZnVuY3Rpb25zIHdpdGggYXJiaXRyYXJ5IHJlcGxhY2VtZW50cy4KICAgICAqIFVzZWZ1bCBmb3IgdGVzdCBzcGllcy4KICAgICAqCiAgICAgKiBAcGFyYW0gX2ZldGNoSlNPTgogICAgICogQHBhcmFtIF9mZXRjaAogICAgICovCiAgICBwYXRjaEZldGNoOiBmdW5jdGlvbiBwYXRjaEZldGNoKF9mZXRjaEpTT04sIF9mZXRjaCkgewogICAgICAgIF9mZXRjaDIuRmV0Y2guZmV0Y2hKU09OID0gX2ZldGNoSlNPTjsKICAgICAgICBfZmV0Y2gyLkZldGNoLmZldGNoID0gX2ZldGNoOwogICAgfSwKCgogICAgLyoqCiAgICAgKiBTd2l0Y2hlcyBmZXRjaCBmdW5jdGlvbnMgZm9yIG9uZXMgdGhhdCBkb250IHVzZSBKV1QuIE5lZWRlZAogICAgICogZm9yIHJ1bm5pbmcgdGVzdHMuCiAgICAgKi8KICAgIHBhdGNoRmV0Y2hOb0pXVDogZnVuY3Rpb24gcGF0Y2hGZXRjaE5vSldUKCkgewogICAgICAgIF9mZXRjaDIuRmV0Y2guZmV0Y2hKU09OID0gX2ZldGNoMi5GZXRjaEZ1bmN0aW9ucy5yYXdGZXRjaEpTT047CiAgICAgICAgX2ZldGNoMi5GZXRjaC5mZXRjaCA9IF9mZXRjaDIuRmV0Y2hGdW5jdGlvbnMucmF3RmV0Y2g7CiAgICB9LAoKCiAgICAvKioKICAgICAqIFJlc3RvcmVzIG9yaWdpbmFsIGZldGNoIGZ1bmN0aW9ucy4KICAgICAqLwogICAgcmVzdG9yZUZldGNoOiBmdW5jdGlvbiByZXN0b3JlRmV0Y2goKSB7CiAgICAgICAgX2ZldGNoMi5GZXRjaC5mZXRjaEpTT04gPSBmZXRjaEpTT047CiAgICAgICAgX2ZldGNoMi5GZXRjaC5mZXRjaCA9IGZldGNoOwogICAgfSwKCgogICAgLyoqCiAgICAgKiBQYXRjaGVzIGZldGNoIGZ1bmN0aW9ucyB3aXRoIGEgcmVzb2x2ZWQgcHJvbWlzZS4gVGhpcyB3aWxsIG1ha2UgYWxsIGZldGNoIGNhbGxzIHJldHVybgogICAgICogdGhpcyBkYXRhLgogICAgICoKICAgICAqIFVzYWdlCiAgICAgKgogICAgICogVGVzdFV0aWxzLnBhdGNoRmV0Y2hXaXRoRGF0YSgodXJsLCBvcHRpb25zKSA9PiB7CiAgICAgKiAgICAgIGFzc2VydC5lcXVhbHModXJsLCJzb21ldXJsIikKICAgICAqICAgICAgcmV0dXJuIHsgbXlkYXRhOiA1IH0KICAgICAqIH0pCiAgICAgKi8KICAgIHBhdGNoRmV0Y2hXaXRoRGF0YTogZnVuY3Rpb24gcGF0Y2hGZXRjaFdpdGhEYXRhKGRhdGFGbikgewogICAgICAgIF9mZXRjaDIuRmV0Y2guZmV0Y2hKU09OID0gX2ZldGNoMi5GZXRjaC5mZXRjaCA9IGZ1bmN0aW9uICh1cmwsIG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIF9yZWYgPSBvcHRpb25zIHx8IHt9LAogICAgICAgICAgICAgICAgb25TdWNjZXNzID0gX3JlZi5vblN1Y2Nlc3MsCiAgICAgICAgICAgICAgICBvbkVycm9yID0gX3JlZi5vbkVycm9yOwoKICAgICAgICAgICAgdmFyIGRhdGEgPSBQcm9taXNlLnJlc29sdmUoZGF0YUZuKHVybCwgb3B0aW9ucykpOwoKICAgICAgICAgICAgaWYgKG9uU3VjY2VzcykgewogICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEudGhlbihvblN1Y2Nlc3MpLmNhdGNoKF9mZXRjaDIuRmV0Y2hGdW5jdGlvbnMub25FcnJvcihvbkVycm9yKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBkYXRhOwogICAgICAgIH07CiAgICB9Cn07Cn0seyIuL2ZldGNoIjoyMn1dLDU4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CnZhciBqZW5raW5zUm9vdFVSTCA9ICcnOwp2YXIgYmx1ZU9jZWFuQXBwVVJMID0gJy8nOwp2YXIgcmVzdEJhc2VVUkwgPSAnJzsKCnZhciBsb2FkZWQgPSBmYWxzZTsKCmZ1bmN0aW9uIGxvYWRDb25maWcoKSB7CiAgICB0cnkgewogICAgICAgIHZhciBoZWFkRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF07CgogICAgICAgIC8vIHR5cGljYWxseSAnL2plbmtpbnMvJwogICAgICAgIGplbmtpbnNSb290VVJMID0gaGVhZEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXJvb3R1cmwnKTsKCiAgICAgICAgLy8gdHlwaWNhbGx5ICcvamVua2lucy9ibHVlJwogICAgICAgIGJsdWVPY2VhbkFwcFVSTCA9IGhlYWRFbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1hcHB1cmwnKTsKICAgICAgICBpZiAodHlwZW9mIGJsdWVPY2VhbkFwcFVSTCAhPT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgYmx1ZU9jZWFuQXBwVVJMID0gJy8nOwogICAgICAgIH0KCiAgICAgICAgLy8gdHlwaWNhbGx5ICcvamVua2lucy9ibHVlL3Jlc3QnCiAgICAgICAgcmVzdEJhc2VVUkwgPSAoYmx1ZU9jZWFuQXBwVVJMICsgJy9yZXN0JykucmVwbGFjZSgvXC9cLysvZywgJy8nKTsgLy8gZWxpbWluYXRlIGFueSBkdXBsaWNhdGVkIHNsYXNoZXMKCiAgICAgICAgbG9hZGVkID0gdHJ1ZTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGUKICAgICAgICBjb25zb2xlLndhcm4oJ2Vycm9yIHJlYWRpbmcgYXR0cmlidXRlcyBmcm9tIGRvY3VtZW50OyB1cmxzIHdpbGwgYmUgZW1wdHknLCBlcnJvcik7CgogICAgICAgIGxvYWRlZCA9IGZhbHNlOwogICAgfQp9CgpleHBvcnRzLmRlZmF1bHQgPSB7CiAgICBnZXRKZW5raW5zUm9vdFVSTDogZnVuY3Rpb24gZ2V0SmVua2luc1Jvb3RVUkwoKSB7CiAgICAgICAgaWYgKCFsb2FkZWQpIHsKICAgICAgICAgICAgbG9hZENvbmZpZygpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gamVua2luc1Jvb3RVUkw7CiAgICB9LAogICAgZ2V0Qmx1ZU9jZWFuQXBwVVJMOiBmdW5jdGlvbiBnZXRCbHVlT2NlYW5BcHBVUkwoKSB7CiAgICAgICAgaWYgKCFsb2FkZWQpIHsKICAgICAgICAgICAgbG9hZENvbmZpZygpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYmx1ZU9jZWFuQXBwVVJMOwogICAgfSwKICAgIGdldFJlc3RCYXNlVVJMOiBmdW5jdGlvbiBnZXRSZXN0QmFzZVVSTCgpIHsKICAgICAgICBpZiAoIWxvYWRlZCkgewogICAgICAgICAgICBsb2FkQ29uZmlnKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN0QmFzZVVSTDsKICAgIH0sCgogICAgLy8gZm9yIHRlc3RpbmcgcHVycG9zZXM6IGFsbG93IHVybCdzIHRvIGJlIHJlbG9hZGVkCiAgICBlbmFibGVSZWxvYWQ6IGZ1bmN0aW9uIGVuYWJsZVJlbG9hZCgpIHsKICAgICAgICBsb2FkZWQgPSBmYWxzZTsKICAgIH0KfTsKfSx7fV0sNTk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewooZnVuY3Rpb24gKGdsb2JhbCl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwoKdmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSAiZnVuY3Rpb24iICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICJzeW1ib2wiID8gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfSA6IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSAiZnVuY3Rpb24iICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/ICJzeW1ib2wiIDogdHlwZW9mIG9iajsgfTsKCi8qKgogKiBUcmltcyBkdXBsaWNhdGUgZm9yd2FyZCBzbGFzaGVzIHRvIGEgc2luZ2xlIHNsYXNoIGFuZCBhZGRzIHRyYWlsaW5nIHNsYXNoIGlmIG5lZWRlZC4KICogQHBhcmFtIHVybAogKiBAcmV0dXJucyB7c3RyaW5nfQogKi8KZnVuY3Rpb24gY2xlYW5TbGFzaGVzKHVybCkgewogICAgdmFyIGJhc2VVcmwgPSAnJzsKICAgIHZhciB1cmxQYXJhbXMgPSAnJzsKCiAgICBpZiAodXJsICYmIHVybC5pbmRleE9mKCc/JykgPiAtMSkgewogICAgICAgIGJhc2VVcmwgPSB1cmwuc3BsaXQoJz8nKS5zbGljZSgwLCAxKS5qb2luKCcnKTsKICAgICAgICB1cmxQYXJhbXMgPSB1cmwuc3BsaXQoJz8nKS5zbGljZSgtMSkuam9pbignJyk7CiAgICB9IGVsc2UgewogICAgICAgIGJhc2VVcmwgPSB1cmw7CiAgICB9CgogICAgLy8gcmVwbGFjZSBhbnkgbnVtYmVyIG9mIGNvbnNlY3V0aXZlIHNsYXNoZXMgd2l0aCBvbmUgc2xhc2gKICAgIGJhc2VVcmwgPSBiYXNlVXJsLnJlcGxhY2UoL1wvXC8rL2csICcvJyk7CgogICAgaWYgKGJhc2VVcmwuc3Vic3RyKC0xKSAhPT0gJy8nKSB7CiAgICAgICAgYmFzZVVybCA9IGJhc2VVcmwgKyAnLyc7CiAgICB9CgogICAgcmV0dXJuICF1cmxQYXJhbXMgPyBiYXNlVXJsIDogYmFzZVVybCArICc/JyArIHVybFBhcmFtczsKfQoKLyoqCiAqIEdlbmVyYXRlIGEgInVuaXF1ZSIgSUQgd2l0aCBhbiBvcHRpb25hbCBwcmVmaXgKICogQHBhcmFtIHByZWZpeAogKiBAcmV0dXJucyB7c3RyaW5nfQogKi8KZnVuY3Rpb24gcmFuZG9tSWQoKSB7CiAgICB2YXIgcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiAnaWQnOwoKICAgIHZhciBpbnRlZ2VyID0gTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpOwogICAgcmV0dXJuIHByZWZpeCArICctJyArIGludGVnZXI7Cn0KCmV4cG9ydHMuZGVmYXVsdCA9IHsKICAgIGNsZWFuU2xhc2hlczogY2xlYW5TbGFzaGVzLAogICAgcmFuZG9tSWQ6IHJhbmRvbUlkLAogICAgY2xvbmU6IGZ1bmN0aW9uIGNsb25lKG9iaikgewogICAgICAgIGlmICghb2JqKSByZXR1cm4gb2JqOwogICAgICAgIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iaikpOwogICAgfSwKICAgIHdpbmRvd09yR2xvYmFsOiBmdW5jdGlvbiB3aW5kb3dPckdsb2JhbCgpIHsKICAgICAgICByZXR1cm4gKHR5cGVvZiBzZWxmID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihzZWxmKSkgPT09ICdvYmplY3QnICYmIHNlbGYuc2VsZiA9PT0gc2VsZiAmJiBzZWxmIHx8ICh0eXBlb2YgZ2xvYmFsID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihnbG9iYWwpKSA9PT0gJ29iamVjdCcgJiYgZ2xvYmFsLmdsb2JhbCA9PT0gZ2xvYmFsICYmIGdsb2JhbCB8fCB0aGlzOwogICAgfSwKICAgIHJlZnJlc2hQYWdlOiBmdW5jdGlvbiByZWZyZXNoUGFnZSgpIHsKICAgICAgICBpZiAodGhpcy53aW5kb3dPckdsb2JhbCgpLmxvY2F0aW9uLnJlbG9hZCkgewogICAgICAgICAgICB0aGlzLndpbmRvd09yR2xvYmFsKCkubG9jYXRpb24ucmVsb2FkKHRydWUpOwogICAgICAgIH0KICAgIH0KfTsKCgp9KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gInVuZGVmaW5lZCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gInVuZGVmaW5lZCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gInVuZGVmaW5lZCIgPyB3aW5kb3cgOiB7fSkKfSx7fV0sNjA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5jYWxjdWxhdGVMb2dVcmwgPSBleHBvcnRzLmNhbGN1bGF0ZUxvZ1ZpZXcgPSBleHBvcnRzLmZldGNoQWxsU3VmZml4ID0gZXhwb3J0cy5kb3VibGVVcmlFbmNvZGUgPSBleHBvcnRzLmJ1aWxkUnVuRGV0YWlsc1VybCA9IGV4cG9ydHMuYnVpbGRDbGFzc2ljQnVpbGRVcmwgPSBleHBvcnRzLmJ1aWxkQ2xhc3NpY0lucHV0VXJsID0gZXhwb3J0cy5idWlsZENsYXNzaWNDb25maWdVcmwgPSBleHBvcnRzLnJvb3RQYXRoID0gZXhwb3J0cy5idWlsZFBpcGVsaW5lVXJsID0gZXhwb3J0cy5idWlsZE9yZ2FuaXphdGlvblVybCA9IHVuZGVmaW5lZDsKCnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSAic3ltYm9sIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyAic3ltYm9sIiA6IHR5cGVvZiBvYmo7IH07CgpleHBvcnRzLmFwcGx5RmV0Y2hBbGwgPSBhcHBseUZldGNoQWxsOwpleHBvcnRzLmNhbGN1bGF0ZUZldGNoQWxsID0gY2FsY3VsYXRlRmV0Y2hBbGw7CmV4cG9ydHMuY2FsY3VsYXRlTm9kZUJhc2VVcmwgPSBjYWxjdWxhdGVOb2RlQmFzZVVybDsKZXhwb3J0cy5jYWxjdWxhdGVTdGVwc0Jhc2VVcmwgPSBjYWxjdWxhdGVTdGVwc0Jhc2VVcmw7CmV4cG9ydHMuY2FsY3VsYXRlUnVuTG9nVVJMT2JqZWN0ID0gY2FsY3VsYXRlUnVuTG9nVVJMT2JqZWN0OwpleHBvcnRzLnBhZ2luYXRlVXJsID0gcGFnaW5hdGVVcmw7CmV4cG9ydHMuZW5kU2xhc2ggPSBlbmRTbGFzaDsKZXhwb3J0cy5nZXRSZXN0VXJsID0gZ2V0UmVzdFVybDsKZXhwb3J0cy5idWlsZFVybCA9IGJ1aWxkVXJsOwpleHBvcnRzLnJlbGF0aXZlVXJsID0gcmVsYXRpdmVVcmw7CmV4cG9ydHMudG9DbGFzc2ljSm9iUGFnZSA9IHRvQ2xhc3NpY0pvYlBhZ2U7Cgp2YXIgX2NvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpOwoKdmFyIF9jb25maWcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfY29uZmlnKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgovKioKICogQnVpbGQgYSByb290LXJlbGF0aXZlIFVSTCB0byB0aGUgb3JnYW5pemF0aW9uJ3MgcGlwZWxpbmUgbGlzdCBzY3JlZW4uCiAqIEBwYXJhbSBvcmdhbml6YXRpb24KICovCnZhciBidWlsZE9yZ2FuaXphdGlvblVybCA9IGV4cG9ydHMuYnVpbGRPcmdhbml6YXRpb25VcmwgPSBmdW5jdGlvbiBidWlsZE9yZ2FuaXphdGlvblVybChvcmdhbml6YXRpb24pIHsKICAgIHJldHVybiAnL29yZ2FuaXphdGlvbnMvJyArIGVuY29kZVVSSUNvbXBvbmVudChvcmdhbml6YXRpb24pOwp9OwoKLyoqCiAqIEJ1aWxkIGEgcm9vdC1yZWxhdGl2ZSBVUkwgdG8gdGhlIHBpcGVsaW5lIGRldGFpbHMgc2NyZWVuLgogKiBAcGFyYW0gb3JnYW5pemF0aW9uCiAqIEBwYXJhbSBmdWxsTmFtZQogKiBAcGFyYW0gdGFiTmFtZQogKiBAcmV0dXJucyB7c3RyaW5nfQogKi8KdmFyIGJ1aWxkUGlwZWxpbmVVcmwgPSBleHBvcnRzLmJ1aWxkUGlwZWxpbmVVcmwgPSBmdW5jdGlvbiBidWlsZFBpcGVsaW5lVXJsKG9yZ2FuaXphdGlvbiwgZnVsbE5hbWUsIHRhYk5hbWUpIHsKICAgIHZhciBiYXNlVXJsID0gJy9vcmdhbml6YXRpb25zLycgKyBlbmNvZGVVUklDb21wb25lbnQob3JnYW5pemF0aW9uKSArICcvJyArICgnJyArIGVuY29kZVVSSUNvbXBvbmVudChmdWxsTmFtZSkpOwoKICAgIHJldHVybiB0YWJOYW1lID8gYmFzZVVybCArICcvJyArIHRhYk5hbWUgOiBiYXNlVXJsOwp9OwoKdmFyIHJvb3RQYXRoID0gZXhwb3J0cy5yb290UGF0aCA9IGZ1bmN0aW9uIHJvb3RQYXRoKG5hbWUpIHsKICAgIHZhciBqZW5raW5zVXJsID0gX2NvbmZpZzIuZGVmYXVsdC5nZXRKZW5raW5zUm9vdFVSTCgpOwogICAgcmV0dXJuIGplbmtpbnNVcmwgKyAnL2pvYi8nICsgbmFtZS5zcGxpdCgnLycpLmpvaW4oJy9qb2IvJykgKyAnLyc7Cn07Cgp2YXIgYnVpbGRDbGFzc2ljQ29uZmlnVXJsID0gZXhwb3J0cy5idWlsZENsYXNzaWNDb25maWdVcmwgPSBmdW5jdGlvbiBidWlsZENsYXNzaWNDb25maWdVcmwocGlwZWxpbmUpIHsKICAgIGlmIChwaXBlbGluZSAmJiBwaXBlbGluZS5mdWxsTmFtZSkgewogICAgICAgIHJldHVybiByb290UGF0aChwaXBlbGluZS5mdWxsTmFtZSkgKyAnY29uZmlndXJlJzsKICAgIH0KICAgIHJldHVybiBudWxsOwp9OwoKdmFyIGJ1aWxkQ2xhc3NpY0lucHV0VXJsID0gZXhwb3J0cy5idWlsZENsYXNzaWNJbnB1dFVybCA9IGZ1bmN0aW9uIGJ1aWxkQ2xhc3NpY0lucHV0VXJsKHBpcGVsaW5lLCBydW5OdW1iZXIpIHsKICAgIGlmIChwaXBlbGluZSAmJiBwaXBlbGluZS5mdWxsTmFtZSkgewogICAgICAgIHJldHVybiAnJyArIHJvb3RQYXRoKHBpcGVsaW5lLmZ1bGxOYW1lKSArIHJ1bk51bWJlciArICcvaW5wdXQvJzsKICAgIH0KICAgIHJldHVybiBudWxsOwp9OwoKLy8gaHR0cDovL2xvY2FsaG9zdDo4MDgwL2plbmtpbnMvam9iL3NjaGVybGVyL2pvYi9KZW5raW5zLTQwNjE3LXBhcmFtcy9idWlsZD9kZWxheT0wc2VjCnZhciBidWlsZENsYXNzaWNCdWlsZFVybCA9IGV4cG9ydHMuYnVpbGRDbGFzc2ljQnVpbGRVcmwgPSBmdW5jdGlvbiBidWlsZENsYXNzaWNCdWlsZFVybChwaXBlbGluZSkgewogICAgaWYgKHBpcGVsaW5lICYmIHBpcGVsaW5lLmZ1bGxOYW1lKSB7CiAgICAgICAgcmV0dXJuIHJvb3RQYXRoKHBpcGVsaW5lLmZ1bGxOYW1lKSArICdidWlsZD9kZWxheT0wc2VjJzsKICAgIH0KICAgIHJldHVybiBudWxsOwp9OwoKLyoqCiAqIEJ1aWxkIGEgcm9vdC1yZWxhdGl2ZSBVUkwgdG8gdGhlIHJ1biBkZXRhaWxzIHNjcmVlbi4KICogQHBhcmFtIG9yZ2FuaXphdGlvbgogKiBAcGFyYW0gcGlwZWxpbmUKICogQHBhcmFtIGJyYW5jaAogKiBAcGFyYW0gcnVuSWQKICogQHBhcmFtIHRhYk5hbWUKICovCnZhciBidWlsZFJ1bkRldGFpbHNVcmwgPSBleHBvcnRzLmJ1aWxkUnVuRGV0YWlsc1VybCA9IGZ1bmN0aW9uIGJ1aWxkUnVuRGV0YWlsc1VybChvcmdhbml6YXRpb24sIHBpcGVsaW5lLCBicmFuY2gsIHJ1bklkLCB0YWJOYW1lKSB7CiAgICB2YXIgYmFzZVVybCA9ICcvb3JnYW5pemF0aW9ucy8nICsgZW5jb2RlVVJJQ29tcG9uZW50KG9yZ2FuaXphdGlvbikgKyAnLycgKyAoZW5jb2RlVVJJQ29tcG9uZW50KHBpcGVsaW5lKSArICcvZGV0YWlsLycpICsgKGVuY29kZVVSSUNvbXBvbmVudChicmFuY2gpICsgJy8nICsgZW5jb2RlVVJJQ29tcG9uZW50KHJ1bklkKSk7CiAgICByZXR1cm4gdGFiTmFtZSA/IGJhc2VVcmwgKyAnLycgKyB0YWJOYW1lIDogYmFzZVVybDsKfTsKCi8qKgogKiBEb3VibGUgZW5jb2RlIG5hbWUsIGZlYXR1cmUvdGVzdCMxIGlzIGVuY29kZWQgYXMgZmVhdHVyZSUyNTJGdGVzdCUyNTIzMQogKi8KdmFyIGRvdWJsZVVyaUVuY29kZSA9IGV4cG9ydHMuZG91YmxlVXJpRW5jb2RlID0gZnVuY3Rpb24gZG91YmxlVXJpRW5jb2RlKGlucHV0KSB7CiAgICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KGVuY29kZVVSSUNvbXBvbmVudChpbnB1dCkpOwp9OwoKLy8gZ2VuZXJhbCBmZXRjaEFsbFRyaWdnZXIKdmFyIGZldGNoQWxsU3VmZml4ID0gZXhwb3J0cy5mZXRjaEFsbFN1ZmZpeCA9ICc/c3RhcnQ9MCc7CgovLyBBZGQgZmV0Y2hBbGxTdWZmaXggaW4gY2FzZSBpdCBpcyBuZWVkZWQKZnVuY3Rpb24gYXBwbHlGZXRjaEFsbChjb25maWcsIHVybCkgewogICAgLy8gaWYgd2UgcGFzcyBmZXRjaEFsbCBtZWFucyB3ZSB3YW50IHRoZSBmdWxsIGxvZyAtPiBzdGFydD0wIHdpbGwgdHJpZ2dlciB0aGF0IG9uIHRoZSBzZXJ2ZXIKICAgIGlmIChjb25maWcuZmV0Y2hBbGwgJiYgIXVybC5pbmNsdWRlcyhmZXRjaEFsbFN1ZmZpeCkpIHsKICAgICAgICByZXR1cm4gJycgKyB1cmwgKyBmZXRjaEFsbFN1ZmZpeDsKICAgIH0KICAgIHJldHVybiB1cmw7Cn0KCi8vIHVzaW5nIHRoZSBob29rICdsb2NhdGlvbi5zZWFyY2gnLmluY2x1ZGVzKCdzdGFydD0wJykgdG8gdHJpZ2dlciBmZXRjaEFsbApmdW5jdGlvbiBjYWxjdWxhdGVGZXRjaEFsbChwcm9wcykgewogICAgdmFyIHNlYXJjaCA9IHByb3BzLmxvY2F0aW9uLnNlYXJjaDsKCgogICAgaWYgKHNlYXJjaCkgewogICAgICAgIHZhciBzdGVwUmVnID0gL3N0YXJ0PShbMC05XXsxLH0pLzsKICAgICAgICB2YXIgbWF0Y2ggPSBzdGVwUmVnLmV4ZWMoc2VhcmNoKTsKICAgICAgICBpZiAobWF0Y2ggJiYgbWF0Y2hbMV0gJiYgTnVtYmVyKG1hdGNoWzFdKSA9PT0gMCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7Cn0KCi8vIHVzaW5nIHRoZSBob29rICdsb2NhdGlvbi5zZWFyY2gnLmluY2x1ZGVzKCd2aWV3PTAnKSB0byB0cmlnZ2VyIHRoZSBsb2dDb25zb2xlIHZpZXcgaW5zdGVhZCBvZiBzdGVwcwp2YXIgY2FsY3VsYXRlTG9nVmlldyA9IGV4cG9ydHMuY2FsY3VsYXRlTG9nVmlldyA9IGZ1bmN0aW9uIGNhbGN1bGF0ZUxvZ1ZpZXcocHJvcHMpIHsKICAgIHZhciBzZWFyY2ggPSBwcm9wcy5sb2NhdGlvbi5zZWFyY2g7CgoKICAgIGlmIChzZWFyY2gpIHsKICAgICAgICB2YXIgdmlld1JlZyA9IC92aWV3PShbMC05XXsxLH0pLzsKICAgICAgICB2YXIgbWF0Y2ggPSB2aWV3UmVnLmV4ZWMoc2VhcmNoKTsKICAgICAgICBpZiAobWF0Y2ggJiYgbWF0Y2hbMV0gJiYgTnVtYmVyKG1hdGNoWzFdKSA9PT0gMCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7Cn07Ci8qCiAqIGhlbHBlciB0byBjYWxjdWxhdGUgbG9nIHVybC4gV2hlbiB3ZSBoYXZlIGEgbm9kZSB3ZSBnZXQgY3JlYXRlIGEgc3BlY2lhbCB1cmwsIG90aGVyd2lzZSB3ZSB1c2UgdGhlIHVybCBwYXNzZWQgdG8gdXMKICogQHBhcmFtIGNvbmZpZyB7IG5vZGVzQmFzZVVybCwgbm9kZSwgdXJsfQogKi8KdmFyIGNhbGN1bGF0ZUxvZ1VybCA9IGV4cG9ydHMuY2FsY3VsYXRlTG9nVXJsID0gZnVuY3Rpb24gY2FsY3VsYXRlTG9nVXJsKGNvbmZpZykgewogICAgdmFyIHJldHVyblVybCA9IGNvbmZpZy51cmw7CiAgICBpZiAoY29uZmlnLm5vZGUpIHsKICAgICAgICB2YXIgbm9kZXNCYXNlVXJsID0gY29uZmlnLm5vZGVzQmFzZVVybCwKICAgICAgICAgICAgbm9kZSA9IGNvbmZpZy5ub2RlOwoKICAgICAgICByZXR1cm5VcmwgPSBub2Rlc0Jhc2VVcmwgKyAnLycgKyBub2RlLmlkICsgJy9sb2cvJzsKICAgIH0KICAgIHJldHVybiBhcHBseUZldGNoQWxsKGNvbmZpZywgcmV0dXJuVXJsKTsKfTsKCi8qCiAqIGhlbHBlciB0byBjYWxjdWxhdGUgbm9kZShmbG93Tm9kZXMpIHVybC4KICogSWYgd2UgaGF2ZSBtdWx0aWJyYW5jaCB3ZSBnZW5lcmF0ZSBhIHNsaWdodGx5IGRpZmZlcmVudCB1cmwKICogQHBhcmFtIGNvbmZpZyB7IG5hbWUsIHJ1bklkLCBicmFuY2gsIF9hcHBVUkxCYXNlLCBpc011bHRpQnJhbmNofQogKi8KZnVuY3Rpb24gY2FsY3VsYXRlTm9kZUJhc2VVcmwoY29uZmlnKSB7CiAgICB2YXIgbmFtZSA9IGNvbmZpZy5uYW1lLAogICAgICAgIHJ1bklkID0gY29uZmlnLnJ1bklkLAogICAgICAgIGJyYW5jaCA9IGNvbmZpZy5icmFuY2gsCiAgICAgICAgX2FwcFVSTEJhc2UgPSBjb25maWcuX2FwcFVSTEJhc2UsCiAgICAgICAgaXNNdWx0aUJyYW5jaCA9IGNvbmZpZy5pc011bHRpQnJhbmNoOwoKICAgIHZhciBiYXNlVXJsID0gX2FwcFVSTEJhc2UgKyAnL3Jlc3Qvb3JnYW5pemF0aW9ucy9qZW5raW5zLycgKyAoJ3BpcGVsaW5lcy8nICsgbmFtZSk7CiAgICBpZiAoaXNNdWx0aUJyYW5jaCkgewogICAgICAgIHJldHVybiBiYXNlVXJsICsgJy9icmFuY2hlcy8nICsgZG91YmxlVXJpRW5jb2RlKGJyYW5jaCkgKyAnL3J1bnMvJyArIHJ1bklkICsgJy9ub2Rlcy8nOwogICAgfQogICAgcmV0dXJuIGJhc2VVcmwgKyAnL3J1bnMvJyArIHJ1bklkICsgJy9ub2Rlcy8nOwp9CgovKgogKiBoZWxwZXIgdG8gY2FsY3VsYXRlIHN0ZXBzKGZsb3dOb2RlcykgdXJsLgogKiBJZiB3ZSBoYXZlIG11bHRpYnJhbmNoIHdlIGdlbmVyYXRlIGEgc2xpZ2h0bHkgZGlmZmVyZW50IHVybAogKiBhbmQgaWYgdGhlcmUgYXJlIG5vZGUgaW4gd2UgcmVxdWVzdCB0aGUgc3RlcHMgZm9yIHRoaXMgbm9kZQogKiBAcGFyYW0gY29uZmlnIHsgbmFtZSwgcnVuSWQsIGJyYW5jaCwgX2FwcFVSTEJhc2UsIGlzTXVsdGlCcmFuY2gsIG5vZGV9CiAqLwpmdW5jdGlvbiBjYWxjdWxhdGVTdGVwc0Jhc2VVcmwoY29uZmlnKSB7CiAgICB2YXIgbmFtZSA9IGNvbmZpZy5uYW1lLAogICAgICAgIHJ1bklkID0gY29uZmlnLnJ1bklkLAogICAgICAgIGJyYW5jaCA9IGNvbmZpZy5icmFuY2gsCiAgICAgICAgX2FwcFVSTEJhc2UgPSBjb25maWcuX2FwcFVSTEJhc2UsCiAgICAgICAgaXNNdWx0aUJyYW5jaCA9IGNvbmZpZy5pc011bHRpQnJhbmNoLAogICAgICAgIG5vZGUgPSBjb25maWcubm9kZTsKCiAgICB2YXIgYmFzZVVybCA9IF9hcHBVUkxCYXNlICsgJy9yZXN0L29yZ2FuaXphdGlvbnMvamVua2lucy8nICsgKCdwaXBlbGluZXMvJyArIG5hbWUpOwogICAgaWYgKGlzTXVsdGlCcmFuY2gpIHsKICAgICAgICBiYXNlVXJsID0gYmFzZVVybCArICcvYnJhbmNoZXMvJyArIGRvdWJsZVVyaUVuY29kZShicmFuY2gpOwogICAgfQogICAgaWYgKG5vZGUgJiYgbm9kZSAhPT0gbnVsbCkgewogICAgICAgIHJldHVybiBiYXNlVXJsICsgJy9ydW5zLycgKyBydW5JZCArICcvbm9kZXMvJyArIG5vZGUgKyAnL3N0ZXBzLyc7CiAgICB9CiAgICByZXR1cm4gYmFzZVVybCArICcvcnVucy8nICsgcnVuSWQgKyAnL3N0ZXBzLyc7Cn0KLyoKICogaGVscGVyIHRvIGNhbGN1bGF0ZSBnZW5lcmFsIGxvZyB1cmwsIGluY2x1ZGVzIGZpbGVuYW1lLgogKiBJZiB3ZSBoYXZlIG11bHRpYnJhbmNoIHdlIGdlbmVyYXRlIGEgc2xpZ2h0bHkgZGlmZmVyZW50IHVybAogKiBAcGFyYW0gY29uZmlnIHsgbmFtZSwgcnVuSWQsIGJyYW5jaCwgX2FwcFVSTEJhc2UsIGlzTXVsdGlCcmFuY2h9CiAqLwpmdW5jdGlvbiBjYWxjdWxhdGVSdW5Mb2dVUkxPYmplY3QoY29uZmlnKSB7CiAgICB2YXIgbmFtZSA9IGNvbmZpZy5uYW1lLAogICAgICAgIHJ1bklkID0gY29uZmlnLnJ1bklkLAogICAgICAgIGJyYW5jaCA9IGNvbmZpZy5icmFuY2gsCiAgICAgICAgX2FwcFVSTEJhc2UgPSBjb25maWcuX2FwcFVSTEJhc2UsCiAgICAgICAgaXNNdWx0aUJyYW5jaCA9IGNvbmZpZy5pc011bHRpQnJhbmNoOwoKICAgIHZhciBiYXNlVXJsID0gX2FwcFVSTEJhc2UgKyAnL3Jlc3Qvb3JnYW5pemF0aW9ucy9qZW5raW5zJyArICgnL3BpcGVsaW5lcy8nICsgbmFtZSk7CiAgICB2YXIgdXJsID0gdm9pZCAwOwogICAgdmFyIGZpbGVOYW1lID0gdm9pZCAwOwogICAgaWYgKGlzTXVsdGlCcmFuY2gpIHsKICAgICAgICB1cmwgPSBiYXNlVXJsICsgJy9icmFuY2hlcy8nICsgZG91YmxlVXJpRW5jb2RlKGJyYW5jaCkgKyAnL3J1bnMvJyArIHJ1bklkICsgJy9sb2cvJzsKICAgICAgICBmaWxlTmFtZSA9IGJyYW5jaCArICctJyArIHJ1bklkICsgJy50eHQnOwogICAgfSBlbHNlIHsKICAgICAgICB1cmwgPSBiYXNlVXJsICsgJy9ydW5zLycgKyBydW5JZCArICcvbG9nLyc7CiAgICAgICAgZmlsZU5hbWUgPSBydW5JZCArICcudHh0JzsKICAgIH0KICAgIHVybCA9IGFwcGx5RmV0Y2hBbGwoY29uZmlnLCB1cmwpOwogICAgcmV0dXJuIHsKICAgICAgICB1cmw6IHVybCwKICAgICAgICBmaWxlTmFtZTogZmlsZU5hbWUKICAgIH07Cn0KCi8qKgogKiBQcm92aWRlIGEgcGFnaW5hdGlvbiBmdW5jdGlvbiBmb3IgdGhlIGdlbmVyaWMKICogYmx1ZW9jZWFuIHBhZ2luYXRpb24KICovCmZ1bmN0aW9uIHBhZ2luYXRlVXJsKHVybCkgewogICAgdmFyIHNlcCA9IHVybC5pbmRleE9mKCc/JykgPj0gMCA/ICcmJyA6ICc/JzsKICAgIHJldHVybiBmdW5jdGlvbiAoc3RhcnQsIGxpbWl0KSB7CiAgICAgICAgcmV0dXJuICcnICsgdXJsICsgc2VwICsgJ3N0YXJ0PScgKyBzdGFydCArICcmbGltaXQ9JyArIGxpbWl0OwogICAgfTsKfQoKLyoqCiAqIFJldHVybnMgYSBuZXcgc3RyaW5nIHdoaWNoIGVuZHMgd2l0aCBhIHNsYXNoLCBvciB0aGUKICogb3JpZ2luYWwgaWYgaXQgYWxyZWFkeSBkb2VzCiAqLwpmdW5jdGlvbiBlbmRTbGFzaChzdHIpIHsKICAgIGlmICghc3RyKSB7CiAgICAgICAgcmV0dXJuIHN0cjsKICAgIH0KICAgIGlmIChzdHIuY2hhckF0KHN0ci5sZW5ndGggLSAxKSAhPT0gJy8nKSB7CiAgICAgICAgcmV0dXJuIHN0ciArICcvJzsKICAgIH0KICAgIHJldHVybiBzdHI7Cn0KCi8qKgogKiBFeGFtaW5lcyB0aGUgcHJvdmlkZWQgb2JqZWN0IGZvcjoKICogb3JnYW5pemF0aW9uLCBwaXBlbGluZSwgYnJhbmNoLCBydW5JZAogKiBhbmQgYnVpbGRzIGEgcGF0aCB0byB0aGUgdGhpbmcgYXMgYmVzdCBpdCBjYW4uLi4KICovCmZ1bmN0aW9uIGdldFJlc3RVcmwoX3JlZikgewogICAgdmFyIG9yZ2FuaXphdGlvbiA9IF9yZWYub3JnYW5pemF0aW9uLAogICAgICAgIHBpcGVsaW5lID0gX3JlZi5waXBlbGluZSwKICAgICAgICBicmFuY2ggPSBfcmVmLmJyYW5jaCwKICAgICAgICBydW5JZCA9IF9yZWYucnVuSWQ7CgogICAgdmFyIHBpcGVsaW5lTmFtZSA9ICh0eXBlb2YgcGlwZWxpbmUgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHBpcGVsaW5lKSkgPT09ICdvYmplY3QnID8gcGlwZWxpbmUuZnVsbE5hbWUgOiBwaXBlbGluZTsKICAgIHZhciBvcmdhbml6YXRpb25OYW1lID0gb3JnYW5pemF0aW9uIHx8ICgodHlwZW9mIHBpcGVsaW5lID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihwaXBlbGluZSkpID09PSAnb2JqZWN0JyA/IHBpcGVsaW5lLm9yZ2FuaXphdGlvbiA6ICcnKTsKICAgIHZhciBqZW5raW5zVXJsID0gX2NvbmZpZzIuZGVmYXVsdC5nZXRKZW5raW5zUm9vdFVSTCgpOwogICAgdmFyIHVybCA9IGplbmtpbnNVcmwgKyAnL2JsdWUvcmVzdC9vcmdhbml6YXRpb25zLycgKyBlbmNvZGVVUklDb21wb25lbnQob3JnYW5pemF0aW9uTmFtZSk7CiAgICBpZiAocGlwZWxpbmVOYW1lKSB7CiAgICAgICAgLy8gcGlwZWxpbmVOYW1lIG1pZ2h0IGluY2x1ZGUgYSBmb2xkZXIgcGF0aCwgZG9uJ3QgZW5jb2RlIGl0CiAgICAgICAgdXJsICs9ICcvcGlwZWxpbmVzLycgKyBwaXBlbGluZU5hbWU7CiAgICB9CiAgICBpZiAoYnJhbmNoKSB7CiAgICAgICAgLy8gSkVOS0lOUy0zNzcxMiBicmFuY2ggbmVlZHMgdG8gYmUgZG91YmxlLWVuY29kZWQgZm9yIHNvbWUgcmVhc29uCiAgICAgICAgdXJsICs9ICcvYnJhbmNoZXMvJyArIGVuY29kZVVSSUNvbXBvbmVudChlbmNvZGVVUklDb21wb25lbnQoYnJhbmNoKSk7CiAgICB9CiAgICBpZiAocnVuSWQpIHsKICAgICAgICB1cmwgKz0gJy9ydW5zLycgKyBlbmNvZGVVUklDb21wb25lbnQocnVuSWQpOwogICAgfQogICAgcmV0dXJuIGVuZFNsYXNoKHVybCk7Cn0KCi8qKgogKiBDb25zdHJ1Y3RzIGFuIGVzY2FwZWQgdXJsIGJhc2VkIG9uIHRoZSBhcmd1bWVudHMsIHdpdGggZm9yd2FyZCBzbGFzaGVzIGJldHdlZW4gdGhlbQogKiBlLmcuIGJ1aWxkVVJMKCdvcmdhbml6YXRpb25zJywgb3JnTmFtZSwgJ3J1bnMnLCBydW5JZCkgPT4gb3JnYW5pemF0aW9ucy9teSUyMG9yZy9ydW5zLzM0CiAqLwpmdW5jdGlvbiBidWlsZFVybCgpIHsKICAgIHZhciB1cmwgPSAnJzsKCiAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykgewogICAgICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07CiAgICB9CgogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgaWYgKGkgPiAwKSB7CiAgICAgICAgICAgIHVybCArPSAnLyc7CiAgICAgICAgfQogICAgICAgIHVybCArPSBlbmNvZGVVUklDb21wb25lbnQoYXJnc1tpXSk7CiAgICB9CiAgICByZXR1cm4gdXJsOwp9CgovKioKICogUmV0dXJucyBhIHJlbGF0aXZlIFVSTCBiYXNlZCBvbiB0aGUgY3VycmVudCBsb2NhdGlvbgogKi8KZnVuY3Rpb24gcmVsYXRpdmVVcmwobG9jYXRpb24pIHsKICAgIGZvciAodmFyIF9sZW4yID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4yID4gMSA/IF9sZW4yIC0gMSA6IDApLCBfa2V5MiA9IDE7IF9rZXkyIDwgX2xlbjI7IF9rZXkyKyspIHsKICAgICAgICBhcmdzW19rZXkyIC0gMV0gPSBhcmd1bWVudHNbX2tleTJdOwogICAgfQoKICAgIHJldHVybiBlbmRTbGFzaChsb2NhdGlvbi5wYXRobmFtZSkgKyBidWlsZFVybC5hcHBseShudWxsLCBhcmdzKTsKfQoKLyoqCiAqIENoZWNrIGlzIHRoZSBjdXJyZW50IEJsdWUgb2NlYW4gcGFnZSBhIHBpcGVsaW5lIHBhZ2UgYW5kIGlmIHNvLAogKiBkZWNvZGUgaXQgdG8gdGhlIGNvcnJlc3BvbmRpbmcgY2xhc3NpYyBKZW5raW5zIEpvYiBwYWdlLgogKiBAcmV0dXJucyB7c3RyaW5nfHVuZGVmaW5lZH0gVGhlIGNsYXNzaWMgam9iIHBhZ2UsIG9yIHVuZGVmaW5lZCBpZgogKiBpdCB3YXMgdW5hYmxlIHRvIGRlY29kZSB0aGUgcGFnZSBVUkwuCiAqLwpmdW5jdGlvbiB0b0NsYXNzaWNKb2JQYWdlKHBhZ2VVcmwpIHsKICAgIHZhciBpc011bHRpYnJhbmNoID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBmYWxzZTsKCiAgICB2YXIgcGFnZVVybFRva2VucyA9IHBhZ2VVcmwuc3BsaXQoJy8nKS5maWx0ZXIoZnVuY3Rpb24gKHRva2VuKSB7CiAgICAgICAgcmV0dXJuIHR5cGVvZiB0b2tlbiA9PT0gJ3N0cmluZycgJiYgdG9rZW4gIT09ICcnOwogICAgfSk7CgogICAgLy8gUmVtb3ZlIGFsbCBwYXRoIGVsZW1lbnRzIHVwIHRvIGFuZCBpbmNsdWRpbmcgdGhlIEplbmtpbnMKICAgIC8vIG9yZ2FuaXphdGlvbiBuYW1lLgogICAgdmFyIHRva2VuID0gcGFnZVVybFRva2Vucy5zaGlmdCgpOwogICAgd2hpbGUgKHRva2VuICE9PSB1bmRlZmluZWQgJiYgdG9rZW4gIT09ICdvcmdhbml6YXRpb25zJykgewogICAgICAgIHRva2VuID0gcGFnZVVybFRva2Vucy5zaGlmdCgpOwogICAgfQoKICAgIGlmIChwYWdlVXJsVG9rZW5zLmxlbmd0aCA+IDEpIHsKICAgICAgICAvLyBUaGUgbmV4dCB0b2tlbiBpcyB0aGUgYWN0dWFsIG9yZ2FuaXphdGlvbiBuYW1lIGUuZy4gImplbmtpbnMiLgogICAgICAgIC8vIFJlbW92ZSB0aGF0IHNpbmNlIHdlIGRvbid0IG5lZWQgaXQuCiAgICAgICAgcGFnZVVybFRva2Vucy5zaGlmdCgpOwoKICAgICAgICAvLyBUaGUgbmV4dCB0b2tlbiBpcyB0aGUgImZ1bGwiIGpvYiBuYW1lLCBVUkwgZW5jb2RlZC4KICAgICAgICB2YXIgZnVsbEpvYk5hbWUgPSBkZWNvZGVVUklDb21wb25lbnQocGFnZVVybFRva2Vucy5zaGlmdCgpKTsKICAgICAgICB2YXIgZnVsbEpvYk5hbWVUb2tlbnMgPSBmdWxsSm9iTmFtZS5zcGxpdCgnLycpOwogICAgICAgIHZhciBjbGFzc2ljSm9iRnVsbE5hbWUgPSAnL2pvYi8nICsgZnVsbEpvYk5hbWVUb2tlbnMuam9pbignL2pvYi8nKTsKCiAgICAgICAgaWYgKHBhZ2VVcmxUb2tlbnMubGVuZ3RoID4gMSkgewogICAgICAgICAgICAvLyBUaGUgbmV4dCB0b2tlbiBiZWluZyAiZGV0YWlsIiBpbmRpY2F0ZXMgdGhhdCB3ZSdyZSBsb29raW5nCiAgICAgICAgICAgIC8vIGF0IGEgYnJhbmNoLgogICAgICAgICAgICBpZiAocGFnZVVybFRva2Vucy5zaGlmdCgpID09PSAnZGV0YWlsJykgewogICAgICAgICAgICAgICAgLy8gaXMgZ29pbmcgdG8gYmUgc29tZXRoaW5nIGxpa2Ugb25lIG9mOgogICAgICAgICAgICAgICAgLy8gLSBkZXRhaWwvW2ZyZWVzdHlsZUEvYWN0aXZpdHldCiAgICAgICAgICAgICAgICAvLyAtIGRldGFpbC9bZnJlZXN0eWxlQS8yL3BpcGVsaW5lXQogICAgICAgICAgICAgICAgaWYgKGlzTXVsdGlicmFuY2gpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgYnJhbmNoTmFtZSA9IHBhZ2VVcmxUb2tlbnMuc2hpZnQoKTsgLy8gImZyZWVzdHlsZUEiCiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzaWNKb2JCcmFuY2ggPSBjbGFzc2ljSm9iRnVsbE5hbWUgKyAnL2pvYi8nICsgYnJhbmNoTmFtZTsKCiAgICAgICAgICAgICAgICAgICAgLy8gQW5kIGlmIHRoZXJlJ3MgbW9yZSB0aGFuIG9uZSB0b2tlbiBsZWZ0IHRoZW4gd2UgaGF2ZQogICAgICAgICAgICAgICAgICAgIC8vIHRoZSBkZXRhaWwvZnJlZXN0eWxlQS9bMi9waXBlbGluZV0gdmFyaWFudC4gVGhlIG5leHQKICAgICAgICAgICAgICAgICAgICAvLyB0b2tlbiBpcyB0aGUgcnVuSWQKICAgICAgICAgICAgICAgICAgICBpZiAocGFnZVVybFRva2Vucy5sZW5ndGggPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbGFzc2ljSm9iQnJhbmNoICsgJy8nICsgcGFnZVVybFRva2Vucy5zaGlmdCgpOyAvLyAiMiIKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBjbGFzc2ljSm9iQnJhbmNoOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYWdlVXJsVG9rZW5zLmxlbmd0aCA+IDIpIHsKICAgICAgICAgICAgICAgICAgICAvLyBBbmQgaWYgdGhlcmUncyBtb3JlIHRoYW4gdHdvIHRva2VucyBsZWZ0IHRoZW4gd2UgaGF2ZQogICAgICAgICAgICAgICAgICAgIC8vIHRoZSBkZXRhaWwvW2ZyZWVzdHlsZUEvMi9waXBlbGluZV0gdmFyaWFudC4KICAgICAgICAgICAgICAgICAgICAvLyBOZXh0IHRva2VuIGlzIHRoZSBicmFuY2ggbmFtZSAtIG5vdCByZWFsbHkgYSBicmFuY2ggbmFtZSAhIQogICAgICAgICAgICAgICAgICAgIC8vIElnbm9yaW5nIGl0LgogICAgICAgICAgICAgICAgICAgIHBhZ2VVcmxUb2tlbnMuc2hpZnQoKTsgLy8gImZyZWVzdHlsZUEiCiAgICAgICAgICAgICAgICAgICAgLy8gQW5kIHRoZSBuZXh0IHRva2VuIGlzIHRoZSBydW5JZC4KICAgICAgICAgICAgICAgICAgICB2YXIgcnVuSWQgPSBwYWdlVXJsVG9rZW5zLnNoaWZ0KCk7IC8vICIyIgogICAgICAgICAgICAgICAgICAgIHJldHVybiBjbGFzc2ljSm9iRnVsbE5hbWUgKyAnLycgKyBydW5JZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGNsYXNzaWNKb2JGdWxsTmFtZTsKICAgIH0KCiAgICByZXR1cm4gdW5kZWZpbmVkOwp9Cn0seyIuLi9jb25maWciOjIxfV0sNjE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5EZUR1cGVDYWxsVHJhY2tlciA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKZXhwb3J0cy5kZWZhdWx0ID0gZGVkdXBlOwoKdmFyIF9lczZQcm9taXNlID0gcmVxdWlyZSgnZXM2LXByb21pc2UnKTsKCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKLyoqCiAqIER1cGxpY2F0ZUNhbGxUcmFja2VyIG1haW50YWlucyBhY3RpdmUgY2FsbHMgYWdhaW5zdCBhIHBhcnRpY3VsYXIga2V5CiAqLwp2YXIgRGVEdXBlQ2FsbFRyYWNrZXIgPSBleHBvcnRzLkRlRHVwZUNhbGxUcmFja2VyID0gZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gRGVEdXBlQ2FsbFRyYWNrZXIoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIERlRHVwZUNhbGxUcmFja2VyKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogT25sb2FkIGNhbGxiYWNrcyBjYWNoZS4gVXNlZCB0byBlbnN1cmUgd2UgZG9uJ3QKICAgICAgICAgKiBpc3N1ZSBtdWx0aXBsZSBpbi1wYXJhbGxlbCByZXF1ZXN0cyBmb3IgdGhlIHNhbWUKICAgICAgICAgKiBjbGFzcyBtZXRhZGF0YS4KICAgICAgICAgKi8KICAgICAgICB0aGlzLnByb21pc2VzID0ge307CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmFsaXphdGlvbiBvZiBkdXBsaWNhdGUgcmVxdWVzdCBjb25zb2xpZGF0aW9uOgogICAgICoKICAgICAqIEBrZXk6IGtleSB0byB1c2UgdG8gdHJhY2sgdGhlIGR1cGxpY2F0ZSByZXF1ZXN0cwogICAgICogQHByb21pc2VDcmVhdG9yOiBmdW5jdGlvbiB0aGF0IHdpbGwgcmV0dXJuIGFuIGluaXRpYWwgcHJvbWlzZSwgZS5nLiAoKSA9PiBmZXRjaCguLi4pCiAgICAgKiBAcmV0dXJuIGEgUHJvbWlzZQogICAgICovCgoKICAgIF9jcmVhdGVDbGFzcyhEZUR1cGVDYWxsVHJhY2tlciwgW3sKICAgICAgICBrZXk6ICdkZWR1cGUnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBkZWR1cGUoa2V5LCBwcm9taXNlQ3JlYXRvcikgewogICAgICAgICAgICB2YXIgX3RoaXMgPSB0aGlzOwoKICAgICAgICAgICAgLy8gZ2V0IGFjdGl2ZSBvciBjcmVhdGUKICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvbWlzZXNba2V5XSB8fCAodGhpcy5wcm9taXNlc1trZXldID0gcHJvbWlzZUNyZWF0b3IoKS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgICAgICAgICBkZWxldGUgX3RoaXMucHJvbWlzZXNba2V5XTsKICAgICAgICAgICAgICAgIHJldHVybiBkYXRhOwogICAgICAgICAgICB9KS5jYXRjaChmdW5jdGlvbiAoZXJyKSB7CiAgICAgICAgICAgICAgICBkZWxldGUgX3RoaXMucHJvbWlzZXNba2V5XTsKICAgICAgICAgICAgICAgIHJldHVybiBfZXM2UHJvbWlzZS5Qcm9taXNlLnJlamVjdChlcnIpOwogICAgICAgICAgICB9KSk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBEZUR1cGVDYWxsVHJhY2tlcjsKfSgpOwoKdmFyIGRlRHVwZUNhbGxUcmFja2VyID0gbmV3IERlRHVwZUNhbGxUcmFja2VyKCk7CgovKioKICogR2VuZXJhbGl6YXRpb24gb2YgZHVwbGljYXRlIHJlcXVlc3QgY29uc29saWRhdGlvbjoKICoKICogQGtleToga2V5IHRvIHVzZSB0byB0cmFjayB0aGUgZHVwbGljYXRlIHJlcXVlc3RzCiAqIEBwcm9taXNlQ3JlYXRvcjogZnVuY3Rpb24gdGhhdCB3aWxsIHJldHVybiBhbiBpbml0aWFsIHByb21pc2UsIGUuZy4gKCkgPT4gZmV0Y2goLi4uKQogKiBAcmV0dXJuIGEgUHJvbWlzZQogKi8KZnVuY3Rpb24gZGVkdXBlKGtleSwgcHJvbWlzZUNyZWF0b3IpIHsKICAgIHJldHVybiBkZUR1cGVDYWxsVHJhY2tlci5kZWR1cGUoa2V5LCBwcm9taXNlQ3JlYXRvcik7Cn0KfSx7ImVzNi1wcm9taXNlIjoyMzJ9XSw2MjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlRpbWVNYW5hZ2VyID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX21vbWVudCA9IHJlcXVpcmUoJ21vbWVudCcpOwoKdmFyIF9tb21lbnQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbW9tZW50KTsKCnZhciBfbG9nZ2luZyA9IHJlcXVpcmUoJy4uL2xvZ2dpbmcnKTsKCnZhciBfbG9nZ2luZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9sb2dnaW5nKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCnZhciBsb2dnZXIgPSBfbG9nZ2luZzIuZGVmYXVsdC5sb2dnZXIoJ2lvLmplbmtpbnMuYmx1ZW9jZWFuLmRhc2hib2FyZC5oYXJtb25pemVUaW1lcycpOwovKioKICogd2UgbmVlZCB0byBtYWtlIHN1cmUgdGhhdCB3ZSBjYWxjdWxhdGUgd2l0aCB0aGUgY29ycmVjdCB0aW1lIG9mZnNldAogKgogKiBAcGFyYW0gcnVuCiAqIEBwYXJhbSBza2V3TWlsbGlzCiAqIEByZXR1cm5zIHt7IGR1cmF0aW9uTWlsbGlzOiBkaWZmLCBlbmRUaW1lOiBEYXRlLCBzdGFydFRpbWU6IERhdGV9fQogKi8KCnZhciBUaW1lTWFuYWdlciA9IGV4cG9ydHMuVGltZU1hbmFnZXIgPSBmdW5jdGlvbiAoKSB7CiAgICBmdW5jdGlvbiBUaW1lTWFuYWdlcigpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVGltZU1hbmFnZXIpOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhUaW1lTWFuYWdlciwgW3sKICAgICAgICBrZXk6ICdjdXJyZW50VGltZScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGN1cnJlbnRUaW1lKCkgewogICAgICAgICAgICByZXR1cm4gKDAsIF9tb21lbnQyLmRlZmF1bHQpKCk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2Zvcm1hdCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZvcm1hdChtaWxsaXMsIGhpbnRGb3JtYXQpIHsKICAgICAgICAgICAgcmV0dXJuIF9tb21lbnQyLmRlZmF1bHQuZHVyYXRpb24obWlsbGlzKS5mb3JtYXQoaGludEZvcm1hdCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBwcm9wcwogICAgICAgICAqIEBwYXJhbSBza2V3TWlsbGlzCiAgICAgICAgICogQHJldHVybnMgewogICAgICAgICAgICAgICAgZHVyYXRpb25NaWxsaXMsCiAgICAgICAgICAgICAgICBlbmRUaW1lLAogICAgICAgICAgICAgICAgc3RhcnRUaW1lLAogICAgICAgICAgICB9CiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ2hhcm1vbml6ZVRpbWVzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gaGFybW9uaXplVGltZXMocHJvcHMpIHsKICAgICAgICAgICAgdmFyIHNrZXdNaWxsaXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDA7CgogICAgICAgICAgICBsb2dnZXIuZGVidWcoJ3NrZXdNaWxsaXMnLCBza2V3TWlsbGlzKTsKICAgICAgICAgICAgaWYgKCFwcm9wcy5zdGFydFRpbWUpIHsKICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignbm90IGZvdW5kIGFueSBzdGFydFRpbWUsIHNlZW1zIHRoYXQgYSBjb21wb25lbnQgc2hvdWxkIG5vdCBoYXZlIGNhbGxlZCB0aGlzIG1lJyk7CiAgICAgICAgICAgICAgICByZXR1cm4ge307CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gV2hhdCB0aW1lIGlzIGl0IG5vdyBvbiB0aGUgY2xpZW50CiAgICAgICAgICAgIHZhciBjbGllbnRUaW1lID0gdGhpcy5jdXJyZW50VGltZSgpOwogICAgICAgICAgICAvLyB3aGF0IGlzIHRoZSBzdGFydCB0aW1lIG9mIHRoZSBzZXJ2ZXIKICAgICAgICAgICAgdmFyIHNlcnZlclN0YXJ0VGltZSA9ICgwLCBfbW9tZW50Mi5kZWZhdWx0KShwcm9wcy5zdGFydFRpbWUpOwogICAgICAgICAgICAvLyBzeW5jIHNlcnZlciBzdGFydCBkYXRlIHRvIGxvY2FsIHRpbWUgdmlhIHRoZSBza2V3TWlsbGlzCiAgICAgICAgICAgIGlmIChza2V3TWlsbGlzIDwgMCkgewogICAgICAgICAgICAgICAgc2VydmVyU3RhcnRUaW1lLmFkZCh7IG1pbGxpc2Vjb25kczogTWF0aC5hYnMoc2tld01pbGxpcykgfSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZXJ2ZXJTdGFydFRpbWUuc3VidHJhY3QoeyBtaWxsaXNlY29uZHM6IHNrZXdNaWxsaXMgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gZXhwb3J0IHRoZSBoYXJtb25pemVkIHN0YXJ0IHRpbWUKICAgICAgICAgICAgdmFyIHN0YXJ0VGltZSA9IHNlcnZlclN0YXJ0VGltZS50b0pTT04oKTsKICAgICAgICAgICAgLy8gaG93IGxvbmcgaGFzIHBhc3NlZCBmcm9tIHRoZSBzdGFydCB0byBub3cgaW4gbWlsbGlzZWNvbmRzCiAgICAgICAgICAgIHZhciB0aW1lRWxhcHNlZCA9IGNsaWVudFRpbWUuZGlmZihzZXJ2ZXJTdGFydFRpbWUsICdtaWxsaXNlY29uZHMnKTsKICAgICAgICAgICAgLy8gYXNzdW1lIHdlIGRvIG5vdCBoYXZlIGFuIGVuZCBkYXRlCiAgICAgICAgICAgIHZhciBlbmRUaW1lID0gbnVsbDsKICAgICAgICAgICAgdmFyIGR1cmF0aW9uTWlsbGlzID0gMDsKICAgICAgICAgICAgaWYgKHByb3BzLmVuZFRpbWUpIHsKICAgICAgICAgICAgICAgIC8vIHN5bmMgc2VydmVyIGVuZCBkYXRlIHRvIGxvY2FsIHRpbWUgdmlhIHRoZSBza2V3TWlsbGlzCiAgICAgICAgICAgICAgICB2YXIgc2VydmVyRW5kVGltZSA9ICgwLCBfbW9tZW50Mi5kZWZhdWx0KShwcm9wcy5lbmRUaW1lKTsKICAgICAgICAgICAgICAgIGlmIChza2V3TWlsbGlzIDwgMCkgewogICAgICAgICAgICAgICAgICAgIHNlcnZlckVuZFRpbWUuYWRkKHsgbWlsbGlzZWNvbmRzOiBNYXRoLmFicyhza2V3TWlsbGlzKSB9KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc2VydmVyRW5kVGltZS5zdWJ0cmFjdCh7IG1pbGxpc2Vjb25kczogc2tld01pbGxpcyB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVuZFRpbWUgPSBzZXJ2ZXJFbmRUaW1lLnRvSlNPTigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChwcm9wcy5lbmRUaW1lIHx8ICFwcm9wcy5pc1J1bm5pbmcpIHsKICAgICAgICAgICAgICAgIC8vIHN5bmMgc2VydmVyIGVuZCBkYXRlIHRvIGxvY2FsIHRpbWUgdmlhIHRoZSBza2V3TWlsbGlzCiAgICAgICAgICAgICAgICBkdXJhdGlvbk1pbGxpcyA9IHByb3BzLmR1cmF0aW9uSW5NaWxsaXM7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoJ3J1bm5pbmcsIHVzaW5nIHRpbWVFbGFwc2VkIGZvciBkdXJhdGlvbicpOwogICAgICAgICAgICAgICAgZHVyYXRpb25NaWxsaXMgPSBNYXRoLmFicyh0aW1lRWxhcHNlZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdkdXJhdGlvbk1pbGxpczonLCBkdXJhdGlvbk1pbGxpcyk7CiAgICAgICAgICAgIHZhciBoYXJtb25pemVkID0gewogICAgICAgICAgICAgICAgZHVyYXRpb25NaWxsaXM6IGR1cmF0aW9uTWlsbGlzLAogICAgICAgICAgICAgICAgZW5kVGltZTogZW5kVGltZSwKICAgICAgICAgICAgICAgIHN0YXJ0VGltZTogc3RhcnRUaW1lCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygncmV0dXJuaW5nJywgaGFybW9uaXplZCk7CiAgICAgICAgICAgIHJldHVybiBoYXJtb25pemVkOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gVGltZU1hbmFnZXI7Cn0oKTsKfSx7Ii4uL2xvZ2dpbmciOjI3LCJtb21lbnQiOjM5Mn1dLDYzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKInVzZSBzdHJpY3QiOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuZGVmYXVsdCA9IHsKICAgIFRBQjogOSwKICAgIEVOVEVSOiAxMywKICAgIEVTQzogMjcsCiAgICBTUEFDRUJBUjogMzIsCiAgICBQQUdFX1VQOiAzMywKICAgIFBBR0VfRE9XTjogMzQsCiAgICBFTkQ6IDM1LAogICAgSE9NRTogMzYsCiAgICBBUlJPV19MRUZUOiAzNywKICAgIEFSUk9XX1VQOiAzOCwKICAgIEFSUk9XX1JJR0hUOiAzOSwKICAgIEFSUk9XX0RPV046IDQwCn07Cn0se31dLDY0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7Ci8qKgogKiBHZW5lcmF0ZSBhICJ1bmlxdWUiIElEIHdpdGggYW4gb3B0aW9uYWwgcHJlZml4CiAqIEBwYXJhbSBwcmVmaXgKICogQHJldHVybnMge3N0cmluZ30KICovCmZ1bmN0aW9uIHJhbmRvbUlkKCkgewogICAgdmFyIHByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogJ2lkJzsKCiAgICB2YXIgaW50ZWdlciA9IE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSKTsKICAgIHJldHVybiBwcmVmaXggKyAnLScgKyBpbnRlZ2VyOwp9CgpleHBvcnRzLmRlZmF1bHQgPSB7CiAgICByYW5kb21JZDogcmFuZG9tSWQKfTsKfSx7fV0sNjU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5BbGVydHMgPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9Cgp2YXIgQWxlcnRzID0gZXhwb3J0cy5BbGVydHMgPSBmdW5jdGlvbiAoX0NvbXBvbmVudCkgewogICAgX2luaGVyaXRzKEFsZXJ0cywgX0NvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gQWxlcnRzKCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBBbGVydHMpOwoKICAgICAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKEFsZXJ0cy5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKEFsZXJ0cykpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhBbGVydHMsIFt7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcywKICAgICAgICAgICAgICAgIF9wcm9wcyR0eXBlID0gX3Byb3BzLnR5cGUsCiAgICAgICAgICAgICAgICB0eXBlID0gX3Byb3BzJHR5cGUgPT09IHVuZGVmaW5lZCA/ICdJbmZvJyA6IF9wcm9wcyR0eXBlLAogICAgICAgICAgICAgICAgX3Byb3BzJG1lc3NhZ2UgPSBfcHJvcHMubWVzc2FnZSwKICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBfcHJvcHMkbWVzc2FnZSA9PT0gdW5kZWZpbmVkID8gdHlwZSArICcgbWVzc2FnZScgOiBfcHJvcHMkbWVzc2FnZSwKICAgICAgICAgICAgICAgIF9wcm9wcyR0aXRsZSA9IF9wcm9wcy50aXRsZSwKICAgICAgICAgICAgICAgIHRpdGxlID0gX3Byb3BzJHRpdGxlID09PSB1bmRlZmluZWQgPyB0eXBlIDogX3Byb3BzJHRpdGxlOwoKICAgICAgICAgICAgdmFyIGNsYXNzTmFtZXMgPSAnQWxlcnQgJyArIHR5cGU7CiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IGNsYXNzTmFtZXMgfSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnYm9yZGVyJyB9LAogICAgICAgICAgICAgICAgICAgICdceEEwJwogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAndGl0bGUtZGl2JyB9LAogICAgICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICAgICAnc3BhbicsCiAgICAgICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAndGl0bGUnIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlCiAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLAogICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ21lc3NhZ2UnIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBBbGVydHM7Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpBbGVydHMucHJvcFR5cGVzID0gewogICAgdHlwZTogX3JlYWN0LlByb3BUeXBlcy5vbmVPZihbJ1dhcm5pbmcnLCAnRXJyb3InLCAnU3VjY2VzcycsICdJbmZvJ10pLAogICAgbWVzc2FnZTogX3JlYWN0LlByb3BUeXBlcy5vbmVPZlR5cGUoW19yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLCBfcmVhY3QuUHJvcFR5cGVzLmVsZW1lbnRdKSwKICAgIHRpdGxlOiBfcmVhY3QuUHJvcFR5cGVzLm9uZU9mVHlwZShbX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsIF9yZWFjdC5Qcm9wVHlwZXMuZWxlbWVudF0pCn07Cn0seyJyZWFjdCI6NjIzfV0sNjY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewoidXNlIHN0cmljdCI7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5Db21taXRIYXNoID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgicmVhY3QiKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKdmFyIEhBU0hfUkVHRVggPSAvXGJbMC05YS1mXXs1LDQwfVxiLzsKCi8qKgogKiBEaXNwbGF5cyBhIGNvbW1pdCBoYXNoIGluIHRoZSBwcm9wZXIgc3R5bGUuCiAqLwoKdmFyIENvbW1pdEhhc2ggPSBleHBvcnRzLkNvbW1pdEhhc2ggPSBmdW5jdGlvbiAoX0NvbXBvbmVudCkgewogICAgX2luaGVyaXRzKENvbW1pdEhhc2gsIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIENvbW1pdEhhc2goKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIENvbW1pdEhhc2gpOwoKICAgICAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKENvbW1pdEhhc2guX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihDb21taXRIYXNoKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKENvbW1pdEhhc2gsIFt7CiAgICAgICAga2V5OiAicmVuZGVyIiwKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICBpZiAoSEFTSF9SRUdFWC50ZXN0KHRoaXMucHJvcHMuY29tbWl0SWQpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgImNvZGUiLAogICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAiaGFzaCIgfSwKICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmNvbW1pdElkLnN1YnN0cmluZygwLCA3KQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAic3BhbiIsCiAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgIi0iCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBDb21taXRIYXNoOwp9KF9yZWFjdC5Db21wb25lbnQpOwoKQ29tbWl0SGFzaC5wcm9wVHlwZXMgPSB7CiAgICBjb21taXRJZDogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcKfTsKfSx7InJlYWN0Ijo2MjN9XSw2NzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLkRvd25sb2FkTGluayA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfcmVhY3RNYXRlcmlhbEljb25zID0gcmVxdWlyZSgnQGplbmtpbnMtY2QvcmVhY3QtbWF0ZXJpYWwtaWNvbnMnKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0KCnZhciBvYmplY3QgPSBfcmVhY3QuUHJvcFR5cGVzLm9iamVjdCwKICAgIHN0cmluZyA9IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nOwoKdmFyIERvd25sb2FkTGluayA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoRG93bmxvYWRMaW5rLCBfQ29tcG9uZW50KTsKCiAgICBmdW5jdGlvbiBEb3dubG9hZExpbmsoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIERvd25sb2FkTGluayk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoRG93bmxvYWRMaW5rLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoRG93bmxvYWRMaW5rKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKERvd25sb2FkTGluaywgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzLAogICAgICAgICAgICAgICAgc3R5bGUgPSBfcHJvcHMuc3R5bGUsCiAgICAgICAgICAgICAgICBmaWxlRGF0YSA9IF9wcm9wcy5maWxlRGF0YSwKICAgICAgICAgICAgICAgIF9wcm9wcyR0aXRsZSA9IF9wcm9wcy50aXRsZSwKICAgICAgICAgICAgICAgIHRpdGxlID0gX3Byb3BzJHRpdGxlID09PSB1bmRlZmluZWQgPyAnRG93bmxvYWQgdGhlIGxvZycgOiBfcHJvcHMkdGl0bGU7CgogICAgICAgICAgICBpZiAoIWZpbGVEYXRhKSByZXR1cm4gbnVsbDsKICAgICAgICAgICAgdmFyIGNvbnRlbnRzID0gZmlsZURhdGEuY29udGVudHMsCiAgICAgICAgICAgICAgICBtaW1lID0gZmlsZURhdGEubWltZSwKICAgICAgICAgICAgICAgIGZpbGVuYW1lID0gZmlsZURhdGEuZmlsZW5hbWU7CgogICAgICAgICAgICB2YXIgYmxvYiA9IG5ldyBCbG9iKFtjb250ZW50c10sIHsgdHlwZTogbWltZSB9KTsKICAgICAgICAgICAgdmFyIHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7CgogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnYScsCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZG93bmxvYWQ6IGZpbGVuYW1lLAogICAgICAgICAgICAgICAgICAgIGhyZWY6IHVybCwKICAgICAgICAgICAgICAgICAgICB0aXRsZTogdGl0bGUKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChfcmVhY3RNYXRlcmlhbEljb25zLkljb24sIHsgc3R5bGU6IHN0eWxlLCBpY29uOiAnZmlsZV9kb3dubG9hZCcgfSkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIERvd25sb2FkTGluazsKfShfcmVhY3QuQ29tcG9uZW50KTsKCkRvd25sb2FkTGluay5wcm9wVHlwZXMgPSB7CiAgICBmaWxlRGF0YTogb2JqZWN0LAogICAgc3R5bGU6IG9iamVjdCwKICAgIHRpdGxlOiBzdHJpbmcKfTsKZXhwb3J0cy5Eb3dubG9hZExpbmsgPSBEb3dubG9hZExpbms7Cn0seyJAamVua2lucy1jZC9yZWFjdC1tYXRlcmlhbC1pY29ucyI6MTI5LCJyZWFjdCI6NjIzfV0sNjg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5FbXB0eVN0YXRlSWNvbiA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0KCi8qKgogKiBEaXNwbGF5cyBvbmUgb2YgdGhlIGF2YWlsYWJsZSAiTm91biBQcm9qZWN0IiBpY29ucyB1c2VkIGluIGVtcHR5IHN0YXRlIHBhbmVscwogKi8KdmFyIEVtcHR5U3RhdGVJY29uID0gZXhwb3J0cy5FbXB0eVN0YXRlSWNvbiA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoRW1wdHlTdGF0ZUljb24sIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIEVtcHR5U3RhdGVJY29uKCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFbXB0eVN0YXRlSWNvbik7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoRW1wdHlTdGF0ZUljb24uX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihFbXB0eVN0YXRlSWNvbikpLmNhbGwodGhpcykpOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhFbXB0eVN0YXRlSWNvbiwgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBjbGFzc05hbWVzID0gJ2VtcHR5LXN0YXRlLWljb24gJyArIHRoaXMucHJvcHMubmFtZTsKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdkaXYnLCB7IGNsYXNzTmFtZTogY2xhc3NOYW1lcyB9KTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIEVtcHR5U3RhdGVJY29uOwp9KF9yZWFjdC5Db21wb25lbnQpOwoKRW1wdHlTdGF0ZUljb24ucHJvcFR5cGVzID0gewogICAgbmFtZTogX3JlYWN0LlByb3BUeXBlcy5vbmVPZihbJ2JyYW5jaCcsICdnb2F0JywgJ3Nob2VzJ10pLmlzUmVxdWlyZWQKfTsKfSx7InJlYWN0Ijo2MjN9XSw2OTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLkVtcHR5U3RhdGVWaWV3ID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9FbXB0eVN0YXRlSWNvbiA9IHJlcXVpcmUoJy4vRW1wdHlTdGF0ZUljb24nKTsKCnZhciBfcmVhY3RNYXRlcmlhbEljb25zID0gcmVxdWlyZSgnQGplbmtpbnMtY2QvcmVhY3QtbWF0ZXJpYWwtaWNvbnMnKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0KCi8qKgogKiBEaXNwbGF5cyBhbiAiZW1wdHkgc3RhdGUiIGRpYWxvZyB3aXRoIGFyYml0cmFyeSBjaGlsZCBjb250ZW50IGFuZCBhbiBvcHRpb25hbCBpY29uLgogKgogKiBDb250ZW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybSB3aWxsIHJlY2VudCBuaWNlIGRlZmF1bHQgc3R5bGVzOgogKgogKiA8aDE+VGl0bGU8aDE+CiAqIDxwPkEgbG9uZ2VyIG1lc3NhZ2UuLi48L3A+CiAqIDxidXR0b24+VGFrZSBBY3Rpb24hPC9idXR0b24+ICoKICoKICogUHJvcGVydGllczoKICogaWNvbk5hbWU9ImJyYW5jaHxnb2F0fHNob2VzfDxhbnktSWNvbi10eXBlPiIKICogdGlnaHRTcGFjaW5nPXt0cnVlfGZhbHNlfQogKi8KdmFyIEVtcHR5U3RhdGVWaWV3ID0gZXhwb3J0cy5FbXB0eVN0YXRlVmlldyA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoRW1wdHlTdGF0ZVZpZXcsIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIEVtcHR5U3RhdGVWaWV3KCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFbXB0eVN0YXRlVmlldyk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoRW1wdHlTdGF0ZVZpZXcuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihFbXB0eVN0YXRlVmlldykpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhFbXB0eVN0YXRlVmlldywgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBsYXlvdXRDbGFzc2VzID0gJ2VtcHR5LXN0YXRlLWNvbnRhaW5lcic7CgogICAgICAgICAgICBpZiAodGhpcy5wcm9wcy50aWdodFNwYWNpbmcpIHsKICAgICAgICAgICAgICAgIGxheW91dENsYXNzZXMgPSBsYXlvdXRDbGFzc2VzICsgJyB0aWdodC1zcGFjaW5nJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGljb24gPSBudWxsOwogICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5pY29uTmFtZSkgewogICAgICAgICAgICAgICAgaWYgKFsnYnJhbmNoJywgJ2dvYXQnLCAnc2hvZXMnXS5pbmRleE9mKHRoaXMucHJvcHMuaWNvbk5hbWUpID49IDApIHsKICAgICAgICAgICAgICAgICAgICBpY29uID0gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoX0VtcHR5U3RhdGVJY29uLkVtcHR5U3RhdGVJY29uLCB7IG5hbWU6IHRoaXMucHJvcHMuaWNvbk5hbWUgfSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGljb24gPSBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnZW1wdHktc3RhdGUtaWNvbicsIHN0eWxlOiB7IHBhZGRpbmdMZWZ0OiAwIH0gfSwKICAgICAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoX3JlYWN0TWF0ZXJpYWxJY29ucy5JY29uLCB7IHNpemU6IDE1MCwgaWNvbjogdGhpcy5wcm9wcy5pY29uTmFtZSwgc3R5bGU6IHsgZmlsbDogJyNmZmYnIH0gfSkKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnZW1wdHktc3RhdGUnIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogbGF5b3V0Q2xhc3NlcyB9LAogICAgICAgICAgICAgICAgICAgIGljb24sCiAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2VtcHR5LXN0YXRlLWNvbnRlbnQnIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuY2hpbGRyZW4KICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBFbXB0eVN0YXRlVmlldzsKfShfcmVhY3QuQ29tcG9uZW50KTsKCkVtcHR5U3RhdGVWaWV3LnByb3BUeXBlcyA9IHsKICAgIGNoaWxkcmVuOiBfcmVhY3QuUHJvcFR5cGVzLm5vZGUsCiAgICBpY29uTmFtZTogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICB0aWdodFNwYWNpbmc6IF9yZWFjdC5Qcm9wVHlwZXMuYm9vbAp9Owp9LHsiLi9FbXB0eVN0YXRlSWNvbiI6NjgsIkBqZW5raW5zLWNkL3JlYWN0LW1hdGVyaWFsLWljb25zIjoxMjksInJlYWN0Ijo2MjN9XSw3MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLkVycm9yTWVzc2FnZSA9IEVycm9yTWVzc2FnZTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gRXJyb3JNZXNzYWdlKHByb3BzKSB7CiAgICB2YXIgZXh0cmFDbGFzcyA9IHByb3BzLmNsYXNzTmFtZTsKICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAnZGl2JywKICAgICAgICB7IGNsYXNzTmFtZTogJ0Vycm9yTWVzc2FnZSAnICsgZXh0cmFDbGFzcyB9LAogICAgICAgIHByb3BzLmNoaWxkcmVuCiAgICApOwp9CgpFcnJvck1lc3NhZ2UucHJvcFR5cGVzID0gewogICAgY2hpbGRyZW46IF9yZWFjdC5Qcm9wVHlwZXMubm9kZSwKICAgIGNsYXNzTmFtZTogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcKfTsKCkVycm9yTWVzc2FnZS5kZWZhdWx0UHJvcHMgPSB7CiAgICBjbGFzc05hbWU6ICcnCn07Cn0seyJyZWFjdCI6NjIzfV0sNzE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5FeHBhbmRhYmxlUGF0aCA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfcmVhY3RNYXRlcmlhbEljb25zID0gcmVxdWlyZSgnQGplbmtpbnMtY2QvcmVhY3QtbWF0ZXJpYWwtaWNvbnMnKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0gLyoqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIENyZWF0ZWQgYnkgY21leWVycyBvbiAxMC80LzE2LgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCgp2YXIgU0hPV19MQUJFTF9DTEFTUyA9ICdzaG93LWxhYmVsJzsKdmFyIFNIT1dfRk9MREVSX0NMQVNTID0gJ3Nob3ctZm9sZGVyJzsKCi8qKgogKiBFeHBhbmRhYmxlUGF0aCBkaXNwbGF5cyBhIGxpc3Qgb2YgcGF0aCBlbGVtZW50cyB3aXRoIGJ1aWx0LWluIHRydW5jYXRpb24gbG9naWMuCiAqIEJ5IGRlZmF1bHQgdGhlIGZpcnN0LCBsYXN0IGFuZCBzZWNvbmQtdG8tbGFzdCBwYXRoIGl0ZW1zIHdpbGwgYWx3YXlzIGJlIHNob3duIGFzIGxhYmVscy4KICogSW50ZXJtZWRpYXRlIHBhdGggaXRlbXMgd2lsbCBiZSBkaXNwbGF5ZWQgYXMgZm9sZGVyIGljb25zIGFuZCBleHBhbmQgdG8gc2hvdyBsYWJlbHMgb24gaG92ZXIuCiAqCiAqIFByb3BzOgogKiAgICAgIGNsYXNzTmFtZTogQ1NTIGNsYXNzIHRvIHB1dCBvbiByb290IGVsZW1lbnQKICogICAgICBpY29uU2l6ZTogZm9yIGZvbGRlciBpY29ucywgaW4gcGl4ZWxzCiAqICAgICAgcGF0aDogYSBmb3J3YXJkLXNsYXNoIGRlbGltaXRlZCBzdHJpbmcgb2YgYSBwYXRoLCBlLmcuICdmb2xkZXIxL2ZvbGRlcjIvcGlwZWxpbmUnCiAqICAgICAgaGlkZUZpcnN0OiBzZXQgdG8gdHJ1ZSB0byBkaXNwbGF5IHRoZSBmaXJzdCBwYXRoIGVsZW1lbnQgYXMgYSBmb2xkZXIuCiAqICAgICAgdXJpRGVjb2RlOiBzZXQgdG8gdHJ1ZSB0byBzaG93IHVyaS1kZWNvZGVkIGZvcm0gb2YgZWFjaCBwYXRoIGVsZW1lbnQuCiAqLwoKdmFyIEV4cGFuZGFibGVQYXRoID0gZXhwb3J0cy5FeHBhbmRhYmxlUGF0aCA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoRXhwYW5kYWJsZVBhdGgsIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIEV4cGFuZGFibGVQYXRoKCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFeHBhbmRhYmxlUGF0aCk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoRXhwYW5kYWJsZVBhdGguX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihFeHBhbmRhYmxlUGF0aCkpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhFeHBhbmRhYmxlUGF0aCwgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzOwoKICAgICAgICAgICAgaWYgKCF0aGlzLnByb3BzLnBhdGgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgcGF0aEVsZW1lbnRzID0gdGhpcy5wcm9wcy5wYXRoLnNwbGl0KCcvJyk7CiAgICAgICAgICAgIHZhciBleHRyYUNsYXNzID0gdGhpcy5wcm9wcy5jbGFzc05hbWUgfHwgJyc7CgogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnc3BhbicsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2V4cGFuZGFibGUtcGF0aCAnICsgZXh0cmFDbGFzcyB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ3VsJywKICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3BhdGgtbGlzdCcgfSwKICAgICAgICAgICAgICAgICAgICBwYXRoRWxlbWVudHMubWFwKGZ1bmN0aW9uIChwYXRoRWxlbSwgaW5kZXgsIGVsZW1lbnRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc0ZpcnN0ID0gaW5kZXggPT09IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc1NlY29uZExhc3QgPSBpbmRleCArIDEgPT09IGVsZW1lbnRzLmxlbmd0aCAtIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc0xhc3QgPSBpbmRleCArIDEgPT09IGVsZW1lbnRzLmxlbmd0aDsKCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYWJlbCA9IF90aGlzMi5wcm9wcy51cmlEZWNvZGUgPyBkZWNvZGVVUklDb21wb25lbnQocGF0aEVsZW0pIDogcGF0aEVsZW07CgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGlzcGxheUNsYXNzID0gU0hPV19GT0xERVJfQ0xBU1M7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNGaXJzdCAmJiAhX3RoaXMyLnByb3BzLmhpZGVGaXJzdCB8fCBpc1NlY29uZExhc3QgfHwgaXNMYXN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5Q2xhc3MgPSBTSE9XX0xBQkVMX0NMQVNTOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbGknLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgeyBrZXk6IGluZGV4LCBjbGFzc05hbWU6ICdwYXRoLWl0ZW0gJyArIGRpc3BsYXlDbGFzcyB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoX3JlYWN0TWF0ZXJpYWxJY29ucy5JY29uLCB7IHNpemU6IF90aGlzMi5wcm9wcy5pY29uU2l6ZSwgaWNvbjogJ2ZvbGRlcicgfSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3BhbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdwYXRoLXRleHQnIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwudHJpbSgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnc2VwYXJhdG9yJyB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdceEEwL1x4QTAnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSwgW3sKICAgICAgICBrZXk6ICdyZXBsYWNlTGFzdFBhdGhFbGVtZW50JywKCgogICAgICAgIC8qKgogICAgICAgICAqIFJlcGxhY2UgdGhlIGxhc3QgZWxlbWVudCBpbiAncGF0aCcgd2l0aCAnbGFiZWwnLgogICAgICAgICAqIEhlbHBmdWwgZm9yIHRyYW5zZm9ybWluZyBhIHBhdGggdG8gaW5jbHVkZSBhIGZyaWVuZGx5IGRpc3BsYXkgbmFtZS4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGxhYmVsCiAgICAgICAgICogQHJldHVybnMge3N0cmluZ30KICAgICAgICAgKi8KICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVwbGFjZUxhc3RQYXRoRWxlbWVudChwYXRoLCBsYWJlbCkgewogICAgICAgICAgICByZXR1cm4gcGF0aCA/IHBhdGguc3BsaXQoJy8nKS5zbGljZSgwLCAtMSkuY29uY2F0KGxhYmVsKS5qb2luKCcvJykgOiAnJzsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIEV4cGFuZGFibGVQYXRoOwp9KF9yZWFjdC5Db21wb25lbnQpOwoKRXhwYW5kYWJsZVBhdGgucHJvcFR5cGVzID0gewogICAgY2xhc3NOYW1lOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIGljb25TaXplOiBfcmVhY3QuUHJvcFR5cGVzLm51bWJlciwKICAgIHBhdGg6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgaGlkZUZpcnN0OiBfcmVhY3QuUHJvcFR5cGVzLmJvb2wsCiAgICB1cmlEZWNvZGU6IF9yZWFjdC5Qcm9wVHlwZXMuYm9vbAp9OwoKRXhwYW5kYWJsZVBhdGguZGVmYXVsdFByb3BzID0gewogICAgaWNvblNpemU6IDE2LAogICAgaGlkZUZpcnN0OiBmYWxzZSwKICAgIHVyaURlY29kZTogdHJ1ZQp9Owp9LHsiQGplbmtpbnMtY2QvcmVhY3QtbWF0ZXJpYWwtaWNvbnMiOjEyOSwicmVhY3QiOjYyM31dLDcyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuRmlsZVNpemUgPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9Cgp2YXIgb25lT2ZUeXBlID0gX3JlYWN0LlByb3BUeXBlcy5vbmVPZlR5cGUsCiAgICBudW1iZXIgPSBfcmVhY3QuUHJvcFR5cGVzLm51bWJlciwKICAgIHN0cmluZyA9IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nOwoKdmFyIHVuaXRzID0gWydieXRlcycsICdLQicsICdNQicsICdHQicsICdUQicsICdQQiddOwoKLy8gUG9ueWZpbGwgZm9yIG9sZCBicm93c2VycyBhbmQgSUUKLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvTWF0aC9sb2cxMAp2YXIgbG9nMTAgPSBNYXRoLmxvZzEwIHx8IGZ1bmN0aW9uICh4KSB7CiAgICByZXR1cm4gTWF0aC5sb2coeCkgLyBNYXRoLkxOMTA7Cn07Cgp2YXIgRmlsZVNpemUgPSBleHBvcnRzLkZpbGVTaXplID0gZnVuY3Rpb24gKF9Db21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhGaWxlU2l6ZSwgX0NvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gRmlsZVNpemUoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEZpbGVTaXplKTsKCiAgICAgICAgcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChGaWxlU2l6ZS5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKEZpbGVTaXplKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKEZpbGVTaXplLCBbewogICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgdmFyIGJ5dGVzID0gdGhpcy5wcm9wcy5ieXRlczsKCiAgICAgICAgICAgIHZhciBvdXRwdXQgPSAnLSc7CgogICAgICAgICAgICBpZiAodHlwZW9mIGJ5dGVzID09ICdzdHJpbmcnKSB7CiAgICAgICAgICAgICAgICBieXRlcyA9IHBhcnNlSW50KGJ5dGVzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGJ5dGVzID09PSAwKSB7CiAgICAgICAgICAgICAgICBvdXRwdXQgPSAnMCAnICsgdW5pdHNbMF07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlzTmFOKGJ5dGVzKSkgewogICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSB1bml0IChlLmcuICdNQicpIHRvIGRpc3BsYXkKICAgICAgICAgICAgICAgIC8vIGJ1dCBlbnN1cmUgaXQgZG9lc24ndCBnbyBvdmVyIHRoZSBtYXggd2Ugc3VwcG9ydAogICAgICAgICAgICAgICAgdmFyIHBvd2VyID0gTWF0aC5mbG9vcihsb2cxMChNYXRoLmFicyhieXRlcykpIC8gbG9nMTAoMTAyNCkpOwogICAgICAgICAgICAgICAgcG93ZXIgPSBNYXRoLm1pbihwb3dlciwgdW5pdHMubGVuZ3RoIC0gMSk7CgogICAgICAgICAgICAgICAgLy8gcm91bmQgZGlzcGxheWVkIHZhbHVlIHRvIG9uZSBkZWNpbWFsIHBsYWNlCiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSBNYXRoLnJvdW5kKGJ5dGVzIC8gTWF0aC5wb3coMTAyNCwgcG93ZXIpICogMTApIC8gMTA7CiAgICAgICAgICAgICAgICBvdXRwdXQgPSB2YWx1ZSArICcgJyArIHVuaXRzW3Bvd2VyXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ3NwYW4nLAogICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgIG91dHB1dAogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gRmlsZVNpemU7Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpGaWxlU2l6ZS5wcm9wVHlwZXMgPSB7CiAgICBieXRlczogb25lT2ZUeXBlKFtudW1iZXIsIHN0cmluZ10pCn07Cn0seyJyZWFjdCI6NjIzfV0sNzM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5GaWx0ZXJhYmxlTGlzdCA9IHVuZGVmaW5lZDsKCnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX2xvZGFzaCA9IHJlcXVpcmUoJ2xvZGFzaC5kZWJvdW5jZScpOwoKdmFyIF9sb2Rhc2gyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbG9kYXNoKTsKCnZhciBfTGlzdCA9IHJlcXVpcmUoJy4vTGlzdCcpOwoKdmFyIF9UZXh0SW5wdXQgPSByZXF1aXJlKCcuL2Zvcm1zL1RleHRJbnB1dCcpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKZnVuY3Rpb24gZGVmYXVsdEZpbHRlckZ1bmN0aW9uKHRleHQsIGl0ZW0pIHsKICAgIHJldHVybiBpdGVtICYmIGl0ZW0udG9TdHJpbmcoKS5pbmRleE9mKHRleHQpID49IDA7Cn0KCi8qKgogKiBDb250cm9sIHRoYXQgZGlzcGxheXMgYSBMaXN0IG9mIGl0ZW1zIGFuZCBhbGxvd3MgZm9yIHNlbGVjdGlvbi4KICogSW5jbHVkZXMgYSB0ZXh0IGZpZWxkIGFib3ZlIGZvciBxdWljayBmaWx0ZXJpbmcgb2YgaXRlbXMgaW4gdGhlIGxpc3QuCiAqIFByb3ZpZGUgYSBmaWx0ZXJGdW5jdGlvbiB0aGF0IGRldGVybWluZXMgd2hldGhlciBpdGVtIHNob3VsZCBiZSBkaXNwbGF5ZWQgd2l0aCB0ZXh0LgogKiBTZWUgIkxpc3QiIGNvbXBvbmVudCBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBAcHJvcGVydHkge3N0cmluZ30gY2xhc3NOYW1lIGFkZGl0aW9uYWwgImNsYXNzIiB0byBhZGQgdG8gb3V0ZXJtb3N0IGVsZW1lbnQgKGFsb25nc2lkZSAiRmlsdGVyYWJsZUxpc3QiKQogKiBAcHJvcGVydHkge2FycmF5fSBjaGlsZHJlbiBSZWFjdCBjaGlsZHJlbgogKiBAcHJvcGVydHkge09iamVjdH0gc3R5bGUgUmVhY3Qgc3R5bGUgb2JqZWN0IHRvIGJlIGFwcGxpZWQgdG8gb3V0ZXIgZWxlbWVudC4KICogQHByb3BlcnR5IHthcnJheX0gW2RhdGFdIGRhdGEgdG8gcmVuZGVyIGluIHRoZSBsaXN0LgogKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBbbGFiZWxGdW5jdGlvbl0gY29udmVydHMgZWFjaCBvYmplY3QgdG8gYSBzdHJpbmcgaW4gdGhlIGRlZmF1bHQgcmVuZGVyZXIuCiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IFtrZXlGdW5jdGlvbl0KICogQHByb3BlcnR5IHtib29sZWFufSBbZGVmYXVsdFN0eWxlc10gc2V0ICJmYWxzZSIgdG8gcmVtb3ZlIGFsbCBkZWZhdWx0IHN0eWxpbmcgZnJvbSB0aGUgTGlzdC4KICogQHByb3BlcnR5IHtPYmplY3R9IFtkZWZhdWx0U2VsZWN0aW9uXSBpdGVtIHRvIHNlbGVjdCBpbiB0aGUgbGlzdCBieSBkZWZhdWx0CiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IFtvbkl0ZW1TZWxlY3RdIGNhbGxiYWNrIHdoZW4gYW4gaXRlbSBpcyBzZWxlY3RlZCwgcmVjZWl2aW5nIGxpc3RJbmRleCBhbmQgbGlzdEl0ZW0uCiAqCiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsaXN0U3R5bGUgUmVhY3Qgc3R5bGUgb2JqZWN0IHRvIGJlIGFwcGxpZWQgdG8gY2hpbGQgTGlzdC4KICogQHByb3BlcnR5IHtGdW5jdGlvbn0gZmlsdGVyRnVuY3Rpb24gcmVjZWl2ZXMgdGV4dCwgaXRlbTsgcmV0dXJuIHRydWUvZmFsc2UgdG8gc2hvdyBlYWNoIGl0ZW0KICogQHByb3BlcnR5IHtzdHJpbmd9IHBsYWNlaG9sZGVyIHRleHQgdG8gZGlzcGxheSBpbiBmaWx0ZXIgaW5wdXQgd2hlbiBlbXB0eQogKiBAcHJvcGVydHkge3N0cmluZ30gZW1wdHlUZXh0IHRleHQgdG8gZGlzcGxheSB3aGVuIG5vIG1hdGNoZXMgb2NjdXIKICovCgp2YXIgRmlsdGVyYWJsZUxpc3QgPSBleHBvcnRzLkZpbHRlcmFibGVMaXN0ID0gZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhGaWx0ZXJhYmxlTGlzdCwgX1JlYWN0JENvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gRmlsdGVyYWJsZUxpc3QocHJvcHMpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRmlsdGVyYWJsZUxpc3QpOwoKICAgICAgICB2YXIgX3RoaXMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoRmlsdGVyYWJsZUxpc3QuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihGaWx0ZXJhYmxlTGlzdCkpLmNhbGwodGhpcywgcHJvcHMpKTsKCiAgICAgICAgX3RoaXMuX29uRmlsdGVyQ2hhbmdlID0gKDAsIF9sb2Rhc2gyLmRlZmF1bHQpKGZ1bmN0aW9uICh0ZXh0KSB7CiAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsKICAgICAgICAgICAgICAgIHRleHQ6IHRleHQKICAgICAgICAgICAgfSk7CiAgICAgICAgfSwgMjUwKTsKCgogICAgICAgIF90aGlzLnN0YXRlID0ge307CiAgICAgICAgcmV0dXJuIF90aGlzOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhGaWx0ZXJhYmxlTGlzdCwgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzOwoKICAgICAgICAgICAgLy8gcGFzc3Rocm91Z2ggcHJvcHMgZm9yIExpc3QKICAgICAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHMsCiAgICAgICAgICAgICAgICBrZXlGdW5jdGlvbiA9IF9wcm9wcy5rZXlGdW5jdGlvbiwKICAgICAgICAgICAgICAgIGxhYmVsRnVuY3Rpb24gPSBfcHJvcHMubGFiZWxGdW5jdGlvbiwKICAgICAgICAgICAgICAgIGxpc3RTdHlsZSA9IF9wcm9wcy5saXN0U3R5bGUsCiAgICAgICAgICAgICAgICBkZWZhdWx0U3R5bGVzID0gX3Byb3BzLmRlZmF1bHRTdHlsZXMsCiAgICAgICAgICAgICAgICBkZWZhdWx0U2VsZWN0aW9uID0gX3Byb3BzLmRlZmF1bHRTZWxlY3Rpb24sCiAgICAgICAgICAgICAgICBvbkl0ZW1TZWxlY3QgPSBfcHJvcHMub25JdGVtU2VsZWN0OwogICAgICAgICAgICB2YXIgX3Byb3BzMiA9IHRoaXMucHJvcHMsCiAgICAgICAgICAgICAgICBkYXRhID0gX3Byb3BzMi5kYXRhLAogICAgICAgICAgICAgICAgZGlzYWJsZWQgPSBfcHJvcHMyLmRpc2FibGVkLAogICAgICAgICAgICAgICAgZW1wdHlUZXh0ID0gX3Byb3BzMi5lbXB0eVRleHQsCiAgICAgICAgICAgICAgICBmaWx0ZXJGdW5jdGlvbiA9IF9wcm9wczIuZmlsdGVyRnVuY3Rpb24sCiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlciA9IF9wcm9wczIucGxhY2Vob2xkZXIsCiAgICAgICAgICAgICAgICBzdHlsZSA9IF9wcm9wczIuc3R5bGU7CiAgICAgICAgICAgIHZhciB0ZXh0ID0gdGhpcy5zdGF0ZS50ZXh0OwoKICAgICAgICAgICAgdmFyIGZpbHRlcmVkID0gZGF0YSA/IGRhdGEuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIXRleHQgfHwgZmlsdGVyRnVuY3Rpb24odGV4dCwgaXRlbSk7CiAgICAgICAgICAgIH0pIDogW107CiAgICAgICAgICAgIHZhciBub01hdGNoZXMgPSB0ZXh0ICYmIGZpbHRlcmVkLmxlbmd0aCA9PT0gMDsKCiAgICAgICAgICAgIHZhciBsaXN0UHJvcHMgPSB7CiAgICAgICAgICAgICAgICBsYWJlbEZ1bmN0aW9uOiBsYWJlbEZ1bmN0aW9uLAogICAgICAgICAgICAgICAga2V5RnVuY3Rpb246IGtleUZ1bmN0aW9uLAogICAgICAgICAgICAgICAgZGVmYXVsdFN0eWxlczogZGVmYXVsdFN0eWxlcywKICAgICAgICAgICAgICAgIGRlZmF1bHRTZWxlY3Rpb246IGRlZmF1bHRTZWxlY3Rpb24sCiAgICAgICAgICAgICAgICBvbkl0ZW1TZWxlY3Q6IG9uSXRlbVNlbGVjdAogICAgICAgICAgICB9OwoKICAgICAgICAgICAgdmFyIG91dGVyQ2xhc3MgPSB0aGlzLnByb3BzLmNsYXNzTmFtZSB8fCAnJzsKCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdGaWx0ZXJhYmxlTGlzdCAnICsgb3V0ZXJDbGFzcywgc3R5bGU6IHN0eWxlIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChfVGV4dElucHV0LlRleHRJbnB1dCwgewogICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiBwbGFjZWhvbGRlciwKICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZDogZGlzYWJsZWQsCiAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U6IGZ1bmN0aW9uIG9uQ2hhbmdlKHRleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzMi5fb25GaWx0ZXJDaGFuZ2UodGV4dCk7CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBpY29uTGVmdDogJ3NlYXJjaCcKICAgICAgICAgICAgICAgIH0pLAogICAgICAgICAgICAgICAgbm9NYXRjaGVzICYmIGVtcHR5VGV4dCAmJiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ0ZpbHRlcmFibGVMaXN0LWVtcHR5LXRleHQnIH0sCiAgICAgICAgICAgICAgICAgICAgZW1wdHlUZXh0CiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgIW5vTWF0Y2hlcyAmJiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICBfTGlzdC5MaXN0LAogICAgICAgICAgICAgICAgICAgIF9leHRlbmRzKHt9LCBsaXN0UHJvcHMsIHsKICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ6IGRpc2FibGVkLAogICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICdGaWx0ZXJhYmxlTGlzdC1MaXN0JywKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogZmlsdGVyZWQsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBsaXN0U3R5bGUKICAgICAgICAgICAgICAgICAgICB9KSwKICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmNoaWxkcmVuCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBGaWx0ZXJhYmxlTGlzdDsKfShfcmVhY3QyLmRlZmF1bHQuQ29tcG9uZW50KTsKCkZpbHRlcmFibGVMaXN0LmRlZmF1bHRQcm9wcyA9IHsKICAgIHN0eWxlOiB7fSwKICAgIGxpc3RTdHlsZToge30sCiAgICBmaWx0ZXJGdW5jdGlvbjogZGVmYXVsdEZpbHRlckZ1bmN0aW9uLAogICAgcGxhY2Vob2xkZXI6ICdTZWFyY2guLi4nLAogICAgZW1wdHlUZXh0OiAnTm8gbWF0Y2hlcy4nCn07CgoKRmlsdGVyYWJsZUxpc3QucHJvcFR5cGVzID0gewogICAgLy8gZnJvbSBMaXN0CiAgICBjbGFzc05hbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgY2hpbGRyZW46IF9yZWFjdC5Qcm9wVHlwZXMuZWxlbWVudCwKICAgIHN0eWxlOiBfcmVhY3QuUHJvcFR5cGVzLm9iamVjdCwKICAgIGRhdGE6IF9yZWFjdC5Qcm9wVHlwZXMuYXJyYXksCiAgICBkaXNhYmxlZDogX3JlYWN0LlByb3BUeXBlcy5ib29sLAogICAgbGFiZWxGdW5jdGlvbjogX3JlYWN0LlByb3BUeXBlcy5mdW5jLAogICAga2V5RnVuY3Rpb246IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYywKICAgIGRlZmF1bHRTdHlsZXM6IF9yZWFjdC5Qcm9wVHlwZXMuYm9vbCwKICAgIGRlZmF1bHRTZWxlY3Rpb246IF9yZWFjdC5Qcm9wVHlwZXMuYW55LAogICAgb25JdGVtU2VsZWN0OiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsCiAgICAvLyBmb3IgRmlsdGVyYWJsZUxpc3QKICAgIGxpc3RTdHlsZTogX3JlYWN0LlByb3BUeXBlcy5vYmplY3QsCiAgICBmaWx0ZXJGdW5jdGlvbjogX3JlYWN0LlByb3BUeXBlcy5mdW5jLAogICAgcGxhY2Vob2xkZXI6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgZW1wdHlUZXh0OiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZwp9Owp9LHsiLi9MaXN0Ijo3NiwiLi9mb3Jtcy9UZXh0SW5wdXQiOjEwMSwibG9kYXNoLmRlYm91bmNlIjozNjMsInJlYWN0Ijo2MjN9XSw3NDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLkZsb2F0aW5nRWxlbWVudCA9IHVuZGVmaW5lZDsKCnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vCi8vICBDb25zdGFudHMgLyB0eXBlcwovLwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2YXIgcG9sbGluZ0ludGVydmFsID0gNTA7IC8vIG1zCnZhciBmaXhlZEFuaW1hdGlvbkR1cmF0aW9uID0gNTAwOyAvLyBtcwoKdmFyIHN0YXRlSW5pdCA9ICdpbml0JzsgLy8gQ3JlYXRlZCwgbm90IHlldCBjb3JyZWN0bHkgcG9zaXRpb25lZAp2YXIgc3RhdGVTdGFibGUgPSAnc3RhYmxlJzsgLy8gQ29ycmVjdGx5IHBvc2l0aW9uZWQsIGFsbCBnb29kCnZhciBzdGF0ZU1vdmluZyA9ICdtb3ZpbmcnOyAvLyBNb3ZpbmcgdG8gbmV3IGNvcnJlY3QgcG9zaXRpb24KCnZhciBsaWZlY3ljbGVTdGF0ZXMgPSB7CiAgICBpbml0OiAnaW5pdCcsCiAgICBzdGFibGU6ICdzdGFibGUnLAogICAgbW92aW5nOiAnbW92aW5nJwp9OwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLwovLyAgSGVscGVycwovLwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgQW5pbWF0aW9uIGVhc2luZwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovLyB0OiBjdXJyZW50IHRpbWUsIGI6IGJlZ2lubmluZyB2YWx1ZSwgYzogY2hhbmdlIEluIHZhbHVlLCBkOiBkdXJhdGlvbgovLyBCYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vZGFucm8vanF1ZXJ5LWVhc2luZy8KCnZhciB0d2VlbiA9IGVhc2VJbk91dEN1YmljOwoKZnVuY3Rpb24gZWFzZUluT3V0Q3ViaWModCwgYiwgYywgZCkgewogICAgaWYgKCh0IC89IGQgLyAyKSA8IDEpIHJldHVybiBjIC8gMiAqIHQgKiB0ICogdCArIGI7CiAgICByZXR1cm4gYyAvIDIgKiAoKHQgLT0gMikgKiB0ICogdCArIDIpICsgYjsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLwovLyAgTWFpbiBDb21wb25lbnQKLy8KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdmFyIEZsb2F0aW5nRWxlbWVudCA9IGV4cG9ydHMuRmxvYXRpbmdFbGVtZW50ID0gZnVuY3Rpb24gKF9Db21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhGbG9hdGluZ0VsZW1lbnQsIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIEZsb2F0aW5nRWxlbWVudCgpIHsKICAgICAgICB2YXIgX3JlZjsKCiAgICAgICAgdmFyIF90ZW1wLCBfdGhpcywgX3JldDsKCiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEZsb2F0aW5nRWxlbWVudCk7CgogICAgICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7CiAgICAgICAgICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gX3JldCA9IChfdGVtcCA9IChfdGhpcyA9IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChfcmVmID0gRmxvYXRpbmdFbGVtZW50Ll9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoRmxvYXRpbmdFbGVtZW50KSkuY2FsbC5hcHBseShfcmVmLCBbdGhpc10uY29uY2F0KGFyZ3MpKSksIF90aGlzKSwgX3RoaXMubGlmZWN5Y2xlU3RhdGUgPSBzdGF0ZUluaXQsIF90aGlzLmN1cnJlbnRMZWZ0ID0gMCwgX3RoaXMuY3VycmVudFRvcCA9IDAsIF90aGlzLmFuaW1hdGlvblN0YXJ0ID0gMCwgX3RoaXMuYW5pbWF0aW9uRHVyYXRpb24gPSAwLCBfdGhpcy5nb2FsTGVmdCA9IDAsIF90aGlzLmdvYWxUb3AgPSAwLCBfdGhpcy5zZWxmV2lkdGggPSAwLCBfdGhpcy5zZWxmSGVpZ2h0ID0gMCwgX3RoaXMudGFyZ2V0V2lkdGggPSAwLCBfdGhpcy50YXJnZXRIZWlnaHQgPSAwLCBfdGhpcy50YXJnZXRMZWZ0ID0gMCwgX3RoaXMudGFyZ2V0VG9wID0gMCwgX3RoaXMudmlld3BvcnRXaWR0aCA9IDAsIF90aGlzLnZpZXdwb3J0SGVpZ2h0ID0gMCwgX3RoaXMucG9zaXRpb25pbmdWYWxpZCA9IGZhbHNlLCBfdGhpcy52YWxpZGF0ZVBvc2l0aW9uaW5nU2NoZWR1bGVkID0gZmFsc2UsIF90aGlzLmNoZWNrRE9NRGVwZW5kZW5jaWVzU2NoZWR1bGVkID0gZmFsc2UsIF90aGlzLnBvbGxpbmdUaW1lb3V0ID0gbnVsbCwgX3RoaXMubW92ZVBvcG92ZXJBbmltYXRpb25GcmFtZSA9IGZ1bmN0aW9uIChub3cpIHsKICAgICAgICAgICAgdmFyIG5vZGUgPSBfdGhpcy5yZWZzLndyYXBwZXI7CiAgICAgICAgICAgIHZhciBfdGhpczIgPSBfdGhpcywKICAgICAgICAgICAgICAgIGxpZmVjeWNsZVN0YXRlID0gX3RoaXMyLmxpZmVjeWNsZVN0YXRlLAogICAgICAgICAgICAgICAgY3VycmVudExlZnQgPSBfdGhpczIuY3VycmVudExlZnQsCiAgICAgICAgICAgICAgICBjdXJyZW50VG9wID0gX3RoaXMyLmN1cnJlbnRUb3AsCiAgICAgICAgICAgICAgICBhbmltYXRpb25TdGFydCA9IF90aGlzMi5hbmltYXRpb25TdGFydCwKICAgICAgICAgICAgICAgIGFuaW1hdGlvbkR1cmF0aW9uID0gX3RoaXMyLmFuaW1hdGlvbkR1cmF0aW9uLAogICAgICAgICAgICAgICAgZ29hbExlZnQgPSBfdGhpczIuZ29hbExlZnQsCiAgICAgICAgICAgICAgICBnb2FsVG9wID0gX3RoaXMyLmdvYWxUb3A7CgoKICAgICAgICAgICAgaWYgKCFub2RlIHx8IGxpZmVjeWNsZVN0YXRlICE9PSBzdGF0ZU1vdmluZykgewogICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBOb3RoaW5nIHRvIGRvIGhlcmUKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gSWYgd2UncmUgZG9uZSwgbWFrZSBzdXJlIHRvIHNldCBjb3JyZWN0IGxvY2F0aW9uLCBzdG9wIGFuaW1hdGlvbgogICAgICAgICAgICBpZiAobm93ID49IGFuaW1hdGlvblN0YXJ0ICsgYW5pbWF0aW9uRHVyYXRpb24pIHsKICAgICAgICAgICAgICAgIF90aGlzLmN1cnJlbnRMZWZ0ID0gZ29hbExlZnQ7CiAgICAgICAgICAgICAgICBfdGhpcy5jdXJyZW50VG9wID0gZ29hbFRvcDsKICAgICAgICAgICAgICAgIF90aGlzLmFuaW1hdGlvblN0YXJ0ID0gMDsKICAgICAgICAgICAgICAgIF90aGlzLmFuaW1hdGlvbkR1cmF0aW9uID0gMDsKICAgICAgICAgICAgICAgIF90aGlzLmdvYWxMZWZ0ID0gMDsKICAgICAgICAgICAgICAgIF90aGlzLmdvYWxUb3AgPSAwOwogICAgICAgICAgICAgICAgX3RoaXMubGlmZWN5Y2xlU3RhdGUgPSBzdGF0ZVN0YWJsZTsKCiAgICAgICAgICAgICAgICBub2RlLnN0eWxlLmxlZnQgPSBnb2FsTGVmdCArICdweCc7CiAgICAgICAgICAgICAgICBub2RlLnN0eWxlLnRvcCA9IGdvYWxUb3AgKyAncHgnOwoKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIG5ld0xlZnQgPSAwLAogICAgICAgICAgICAgICAgbmV3VG9wID0gMDsKICAgICAgICAgICAgdmFyIHRpbWUgPSBub3cgLSBhbmltYXRpb25TdGFydDsKCiAgICAgICAgICAgIG5ld0xlZnQgPSBNYXRoLnJvdW5kKHR3ZWVuKHRpbWUsIGN1cnJlbnRMZWZ0LCBnb2FsTGVmdCAtIGN1cnJlbnRMZWZ0LCBhbmltYXRpb25EdXJhdGlvbikpOwoKICAgICAgICAgICAgbmV3VG9wID0gTWF0aC5yb3VuZCh0d2Vlbih0aW1lLCBjdXJyZW50VG9wLCBnb2FsVG9wIC0gY3VycmVudFRvcCwgYW5pbWF0aW9uRHVyYXRpb24pKTsKCiAgICAgICAgICAgIC8vIFBvc2l0aW9uIHRoZSBub2RlLCB1cGRhdGUgc3RhdGUKICAgICAgICAgICAgbm9kZS5zdHlsZS5sZWZ0ID0gbmV3TGVmdCArICdweCc7CiAgICAgICAgICAgIG5vZGUuc3R5bGUudG9wID0gbmV3VG9wICsgJ3B4JzsKCiAgICAgICAgICAgIC8vIFJlcXVlc3QgYW5vdGhlciBmcmFtZQogICAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKF90aGlzLm1vdmVQb3BvdmVyQW5pbWF0aW9uRnJhbWUpOwogICAgICAgIH0sIF90ZW1wKSwgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oX3RoaXMsIF9yZXQpOwogICAgfQoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vICBJbnRlcm5hbCBTdGF0ZQogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vICBBbmltYXRpb24gUHJvZ3Jlc3MKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvLyBtcwogICAgLy8gbXMKICAgIC8vIEdvYWwtcG9pbnQgZm9yIGFuaW1hdGlvbgogICAgLy8gR29hbC1wb2ludCBmb3IgYW5pbWF0aW9uCgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gIExhc3Qta25vd24gbWVhc3VyZW1lbnRzCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gIFBvc2l0aW9uaW5nIExvb3AKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBfY3JlYXRlQ2xhc3MoRmxvYXRpbmdFbGVtZW50LCBbewogICAgICAgIGtleTogJ2NoZWNrRE9NRGVwZW5kZW5jaWVzJywKCgogICAgICAgIC8qKgogICAgICAgICBDaGVja3MgdGhlIG1lYXN1cmVtZW50cyBvZiB0aGluZ3Mgd2UgZGVwZW5kIG9uLCBhbmQgaW52YWxpZGF0ZSBwb3NpdGlvbmluZwogICAgICAgICBpZiB0aGV5J3ZlIGNoYW5nZWQuIFRoaXMgaXMgZGVzaWduZWQgdG8gYmUgY2FsbGVkIG9mdGVuLCBmcm9tIGEgdGltZXIgb3IKICAgICAgICAgZXZlbnQgbGlzdGVuZXJzLgogICAgICAgICAgQ2FuIGJlIGNhbGxlZCBhdCBhbnkgdGltZSwgYW5kIHdpbGwgc2NoZWR1bGUgaXRzZWxmIGludG8gYW4gYW5pbWF0aW9uCiAgICAgICAgIGZyYW1lLgogICAgICAgICAqLwogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjaGVja0RPTURlcGVuZGVuY2llcygpIHsKICAgICAgICAgICAgdmFyIF90aGlzMyA9IHRoaXM7CgogICAgICAgICAgICBpZiAodGhpcy5wb3NpdGlvbmluZ1ZhbGlkICYmICF0aGlzLnZhbGlkYXRlUG9zaXRpb25pbmdTY2hlZHVsZWQgJiYgIXRoaXMuY2hlY2tET01EZXBlbmRlbmNpZXNTY2hlZHVsZWQpIHsKCiAgICAgICAgICAgICAgICB0aGlzLmNoZWNrRE9NRGVwZW5kZW5jaWVzU2NoZWR1bGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIF90aGlzMy5jaGVja0RPTURlcGVuZGVuY2llc1NjaGVkdWxlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGlmIChfdGhpczMubWVhc3VyZURPTU5vZGVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMzLmludmFsaWRhdGVQb3NpdGlvbmluZygpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgQ2FsbCB3aGVuIHlvdSB3YW50IHRvIG1ha2Ugc3VyZSB0byByZS1jYWxjdWxhdGUgdGhlIHBvc2l0aW9uaW5nLgogICAgICAgICAgQ2FuIGJlIGNhbGxlZCBhdCBhbnkgdGltZSwgYW5kIHdpbGwgc2NoZWR1bGUgaXRzZWxmIGludG8gYW4gYW5pbWF0aW9uCiAgICAgICAgIGZyYW1lLgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdpbnZhbGlkYXRlUG9zaXRpb25pbmcnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBpbnZhbGlkYXRlUG9zaXRpb25pbmcoKSB7CiAgICAgICAgICAgIHZhciBfdGhpczQgPSB0aGlzOwoKICAgICAgICAgICAgaWYgKHRoaXMucG9zaXRpb25pbmdWYWxpZCkgewogICAgICAgICAgICAgICAgdGhpcy5wb3NpdGlvbmluZ1ZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghdGhpcy52YWxpZGF0ZVBvc2l0aW9uaW5nU2NoZWR1bGVkKSB7CiAgICAgICAgICAgICAgICB0aGlzLnZhbGlkYXRlUG9zaXRpb25pbmdTY2hlZHVsZWQgPSB0cnVlOwoKICAgICAgICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIF90aGlzNC52YWxpZGF0ZVBvc2l0aW9uaW5nU2NoZWR1bGVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgX3RoaXM0LnZhbGlkYXRlUG9zaXRpb25pbmcoKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgQ2hlY2sgZm9yIGludmFsaWRhdGVkIHBvc2l0aW9uaW5nLCBhbmQgcmUtY2FsY3VsYXRlIC8gbW92ZSBpZiBuZWNlc3NhcnkKICAgICAgICAgIFNob3VsZCBvbmx5IGJlIGNhbGxlZCB2aWEgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgpLgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICd2YWxpZGF0ZVBvc2l0aW9uaW5nJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdmFsaWRhdGVQb3NpdGlvbmluZygpIHsKICAgICAgICAgICAgaWYgKCF0aGlzLnBvc2l0aW9uaW5nVmFsaWQpIHsKICAgICAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlQW5kU2V0UG9wdXBQb3NpdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgTG9jYXRlIGFuZCBtZWFzdXJlIHRoZSBET00gbm9kZXMgb2YgdGFyZ2V0IGFuZCBzZWxmLgogICAgICAgICBSZXR1cm5zIHRydWUgaWYgdGhlcmUncyBhIGNoYW5nZS4KICAgICAgICAgIFNob3VsZCBvbmx5IGJlIGNhbGxlZCB2aWEgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgpLgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdtZWFzdXJlRE9NTm9kZXMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBtZWFzdXJlRE9NTm9kZXMoKSB7CgogICAgICAgICAgICB2YXIgbmV3U2VsZldpZHRoID0gMDsKICAgICAgICAgICAgdmFyIG5ld1NlbGZIZWlnaHQgPSAwOwoKICAgICAgICAgICAgdmFyIG5ld1RhcmdldFdpZHRoID0gMDsKICAgICAgICAgICAgdmFyIG5ld1RhcmdldEhlaWdodCA9IDA7CiAgICAgICAgICAgIHZhciBuZXdUYXJnZXRMZWZ0ID0gMDsKICAgICAgICAgICAgdmFyIG5ld1RhcmdldFRvcCA9IDA7CgogICAgICAgICAgICB2YXIgbmV3Vmlld3BvcnRXaWR0aCA9IDA7CiAgICAgICAgICAgIHZhciBuZXdWaWV3cG9ydEhlaWdodCA9IDA7CgogICAgICAgICAgICAvLyBNZWFzdXJlIHNlbGYKICAgICAgICAgICAgdmFyIHNlbGZOb2RlID0gdGhpcy5yZWZzLndyYXBwZXI7CiAgICAgICAgICAgIGlmIChzZWxmTm9kZSkgewogICAgICAgICAgICAgICAgbmV3U2VsZldpZHRoID0gc2VsZk5vZGUub2Zmc2V0V2lkdGg7CiAgICAgICAgICAgICAgICBuZXdTZWxmSGVpZ2h0ID0gc2VsZk5vZGUub2Zmc2V0SGVpZ2h0OwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBNZWFzdXJlIGFuZCBsb2NhdGUgdGFyZ2V0IGVsZW1lbnQKICAgICAgICAgICAgdmFyIHRhcmdldE5vZGUgPSB0aGlzLnByb3BzLnRhcmdldEVsZW1lbnQ7CgogICAgICAgICAgICBpZiAodGFyZ2V0Tm9kZSkgewogICAgICAgICAgICAgICAgbmV3VGFyZ2V0V2lkdGggPSB0YXJnZXROb2RlLm9mZnNldFdpZHRoOwogICAgICAgICAgICAgICAgbmV3VGFyZ2V0SGVpZ2h0ID0gdGFyZ2V0Tm9kZS5vZmZzZXRIZWlnaHQ7CgogICAgICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHRvdGFsIHBvc2l0aW9uIChvbmx5IG9mZnNldFBhcmVudCBjaGFpbikKICAgICAgICAgICAgICAgIHZhciBub2RlID0gdGFyZ2V0Tm9kZTsKICAgICAgICAgICAgICAgIHdoaWxlIChub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgbmV3VGFyZ2V0TGVmdCArPSBub2RlLm9mZnNldExlZnQ7CiAgICAgICAgICAgICAgICAgICAgbmV3VGFyZ2V0VG9wICs9IG5vZGUub2Zmc2V0VG9wOwoKICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5vZmZzZXRQYXJlbnQ7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHRvdGFsIHNjcm9sbCBvZmZzZXQgKGNhbiBiZSBpbiBhbnkgYW5jZXN0b3IpCiAgICAgICAgICAgICAgICBub2RlID0gdGFyZ2V0Tm9kZS5wYXJlbnRFbGVtZW50OwogICAgICAgICAgICAgICAgd2hpbGUgKG5vZGUpIHsKCiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUuc2Nyb2xsTGVmdCkgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdUYXJnZXRMZWZ0IC09IG5vZGUuc2Nyb2xsTGVmdDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUuc2Nyb2xsVG9wKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1RhcmdldFRvcCAtPSBub2RlLnNjcm9sbFRvcDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudEVsZW1lbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFZpZXdwb3J0CiAgICAgICAgICAgIG5ld1ZpZXdwb3J0V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDsKICAgICAgICAgICAgbmV3Vmlld3BvcnRIZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7CgogICAgICAgICAgICB2YXIgY2hhbmdlZCA9IG5ld1NlbGZXaWR0aCAhPT0gdGhpcy5zZWxmV2lkdGggfHwgbmV3U2VsZkhlaWdodCAhPT0gdGhpcy5zZWxmSGVpZ2h0IHx8IG5ld1RhcmdldFdpZHRoICE9PSB0aGlzLnRhcmdldFdpZHRoIHx8IG5ld1RhcmdldEhlaWdodCAhPT0gdGhpcy50YXJnZXRIZWlnaHQgfHwgbmV3VGFyZ2V0TGVmdCAhPT0gdGhpcy50YXJnZXRMZWZ0IHx8IG5ld1RhcmdldFRvcCAhPT0gdGhpcy50YXJnZXRUb3AgfHwgbmV3Vmlld3BvcnRXaWR0aCAhPT0gdGhpcy52aWV3cG9ydFdpZHRoIHx8IG5ld1ZpZXdwb3J0SGVpZ2h0ICE9PSB0aGlzLnZpZXdwb3J0SGVpZ2h0OwoKICAgICAgICAgICAgaWYgKGNoYW5nZWQpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2VsZldpZHRoID0gbmV3U2VsZldpZHRoOwogICAgICAgICAgICAgICAgdGhpcy5zZWxmSGVpZ2h0ID0gbmV3U2VsZkhlaWdodDsKICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0V2lkdGggPSBuZXdUYXJnZXRXaWR0aDsKICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0SGVpZ2h0ID0gbmV3VGFyZ2V0SGVpZ2h0OwogICAgICAgICAgICAgICAgdGhpcy50YXJnZXRMZWZ0ID0gbmV3VGFyZ2V0TGVmdDsKICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0VG9wID0gbmV3VGFyZ2V0VG9wOwogICAgICAgICAgICAgICAgdGhpcy52aWV3cG9ydFdpZHRoID0gbmV3Vmlld3BvcnRXaWR0aDsKICAgICAgICAgICAgICAgIHRoaXMudmlld3BvcnRIZWlnaHQgPSBuZXdWaWV3cG9ydEhlaWdodDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGNoYW5nZWQ7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBTZXQgdGhlIHBvcG92ZXIncyBpbml0aWFsIHBvc2l0aW9uIChvZmYtc2NyZWVuKQogICAgICAgICAqIEF2b2lkcyBhIFNhZmFyaS9JRSBidWcgd2hlcmUgY29udGVudCB3b3VsZCBmbGFzaCBhdCAwLzAgYmVmb3JlIGJlaW5nIHBvc2l0aW9uZWQuCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ3NldEluaXRpYWxQb3NpdGlvbicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNldEluaXRpYWxQb3NpdGlvbigpIHsKICAgICAgICAgICAgdGhpcy5tb3ZlUG9wb3ZlcigtOTk5OSwgLTk5OTkpOwogICAgICAgICAgICAvLyBsZWF2ZSBpbiB0aGUgaW5pdCBzdGF0ZSBzbyB0aGUgZXZlbnR1YWwgcmVwb3NpdGlvbmluZyB3aWxsIGhhcHBlbiBpbW1lZGlhdGVseSAobm8gYW5pbSkKICAgICAgICAgICAgdGhpcy5saWZlY3ljbGVTdGF0ZSA9IGxpZmVjeWNsZVN0YXRlcy5pbml0OwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgIENhbGN1bGF0ZSBwb3BvdmVyIHBvc2l0b24gYmFzZWQgb24gaXRzIGRpbWVuc2lvbnMsIHByZWZlcnJlZCBwb3NpdGlvbiwKICAgICAgICAgYW5kIHRoZSBkaW1lbnNpb25zIGFuZCBwb3NpdGlvbiBvZiB0aGUgYW5jaG9yLiBJZiB0aGVyZSdzIGEgY2hhbmdlLAogICAgICAgICBpbnZva2VzIG1vdmVQb3BvdmVyIHRvIG1vdmUgdGhlIHBvcG92ZXIuCiAgICAgICAgICBTaG91bGQgb25seSBiZSBjYWxsZWQgdmlhIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKS4KICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnY2FsY3VsYXRlQW5kU2V0UG9wdXBQb3NpdGlvbicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNhbGN1bGF0ZUFuZFNldFBvcHVwUG9zaXRpb24oKSB7CgogICAgICAgICAgICB0aGlzLm1lYXN1cmVET01Ob2RlcygpOwoKICAgICAgICAgICAgdmFyIHNlbGZXaWR0aCA9IHRoaXMuc2VsZldpZHRoLAogICAgICAgICAgICAgICAgc2VsZkhlaWdodCA9IHRoaXMuc2VsZkhlaWdodCwKICAgICAgICAgICAgICAgIHRhcmdldFdpZHRoID0gdGhpcy50YXJnZXRXaWR0aCwKICAgICAgICAgICAgICAgIHRhcmdldEhlaWdodCA9IHRoaXMudGFyZ2V0SGVpZ2h0LAogICAgICAgICAgICAgICAgdGFyZ2V0TGVmdCA9IHRoaXMudGFyZ2V0TGVmdCwKICAgICAgICAgICAgICAgIHRhcmdldFRvcCA9IHRoaXMudGFyZ2V0VG9wLAogICAgICAgICAgICAgICAgdmlld3BvcnRXaWR0aCA9IHRoaXMudmlld3BvcnRXaWR0aCwKICAgICAgICAgICAgICAgIHZpZXdwb3J0SGVpZ2h0ID0gdGhpcy52aWV3cG9ydEhlaWdodDsKCgogICAgICAgICAgICB2YXIgbmV3UG9zaXRpb25zID0gdGhpcy5wcm9wcy5wb3NpdGlvbkZ1bmN0aW9uKHNlbGZXaWR0aCwgc2VsZkhlaWdodCwgdGFyZ2V0V2lkdGgsIHRhcmdldEhlaWdodCwgdGFyZ2V0TGVmdCwgdGFyZ2V0VG9wLCB2aWV3cG9ydFdpZHRoLCB2aWV3cG9ydEhlaWdodCk7CgogICAgICAgICAgICB2YXIgbmV3TGVmdCA9IG5ld1Bvc2l0aW9ucy5uZXdMZWZ0LAogICAgICAgICAgICAgICAgbmV3VG9wID0gbmV3UG9zaXRpb25zLm5ld1RvcDsKCgogICAgICAgICAgICB0aGlzLm1vdmVQb3BvdmVyKG5ld0xlZnQsIG5ld1RvcCk7CiAgICAgICAgICAgIHRoaXMucG9zaXRpb25pbmdWYWxpZCA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgTW92ZSB0aGUgcG9wb3ZlciBkaXYgdG8gaXRzIG5ldyBsb2NhdGlvbi4gTWF5IGJlZ2luIGFuIGFuaW1hdGlvbgogICAgICAgICBkZXBlbmRpbmcgb24gY3VycmVudCBzdGF0ZQogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdtb3ZlUG9wb3ZlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIG1vdmVQb3BvdmVyKG5ld0xlZnQsIG5ld1RvcCkgewogICAgICAgICAgICB2YXIgbm9kZSA9IHRoaXMucmVmcy53cmFwcGVyOwoKICAgICAgICAgICAgaWYgKCFub2RlKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5saWZlY3ljbGVTdGF0ZSkgewogICAgICAgICAgICAgICAgY2FzZSBzdGF0ZUluaXQ6CiAgICAgICAgICAgICAgICAgICAgLy8gV2lzaGxpc3Q6IEFkZCBhbiBpbml0aWFsICJhcHBlYXIiIGFuaW1hdGlvbj8KICAgICAgICAgICAgICAgICAgICB0aGlzLmxpZmVjeWNsZVN0YXRlID0gc3RhdGVTdGFibGU7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50TGVmdCA9IG5ld0xlZnQ7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50VG9wID0gbmV3VG9wOwogICAgICAgICAgICAgICAgICAgIG5vZGUuc3R5bGUubGVmdCA9IHRoaXMuY3VycmVudExlZnQgKyAncHgnOwogICAgICAgICAgICAgICAgICAgIG5vZGUuc3R5bGUudG9wID0gdGhpcy5jdXJyZW50VG9wICsgJ3B4JzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIHN0YXRlU3RhYmxlOgogICAgICAgICAgICAgICAgICAgIHRoaXMubGlmZWN5Y2xlU3RhdGUgPSBzdGF0ZU1vdmluZzsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFuaW1hdGlvblN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hbmltYXRpb25EdXJhdGlvbiA9IGZpeGVkQW5pbWF0aW9uRHVyYXRpb247CiAgICAgICAgICAgICAgICAgICAgdGhpcy5nb2FsTGVmdCA9IG5ld0xlZnQ7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5nb2FsVG9wID0gbmV3VG9wOwogICAgICAgICAgICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLm1vdmVQb3BvdmVyQW5pbWF0aW9uRnJhbWUpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBzdGF0ZU1vdmluZzoKICAgICAgICAgICAgICAgICAgICAvLyBXaXNobGlzdDogdHJ5IHRvIG1lcmdlIG9sZCBhbmQgbmV3IGFuaW1hdGlvbnMgaWYgbW92aW5nIGJ5CiAgICAgICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRpbmcgYSBuZXcgdmlydHVhbCBzdGFydCBwb3NpdGlvbj8KICAgICAgICAgICAgICAgICAgICB0aGlzLmdvYWxMZWZ0ID0gbmV3TGVmdDsKICAgICAgICAgICAgICAgICAgICB0aGlzLmdvYWxUb3AgPSBuZXdUb3A7CiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMubW92ZVBvcG92ZXJBbmltYXRpb25GcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICBTY2hlZHVsZSBhIGZ1dHVyZSBjaGVjayBvZiBET00gc2l6ZXMgYW5kIHBvc2l0aW9ucyB0byBzZWUgaWYgd2UgbmVlZCB0bwogICAgICAgICBtb3ZlIG91ciBwb3BvdmVyLiBXaWxsIHJlc2NoZWR1bGUgaXRzZWxmIGFmdGVyd2FyZHMuCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ3N0YXJ0UG9sbFRpbWVvdXQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzdGFydFBvbGxUaW1lb3V0KCkgewogICAgICAgICAgICB2YXIgX3RoaXM1ID0gdGhpczsKCiAgICAgICAgICAgIGlmICh0aGlzLnBvbGxpbmdUaW1lb3V0KSB7CiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wb2xsaW5nVGltZW91dCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMucG9sbGluZ1RpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIF90aGlzNS5wb2xsaW5nVGltZW91dCA9IG51bGw7CiAgICAgICAgICAgICAgICBfdGhpczUuY2hlY2tET01EZXBlbmRlbmNpZXMoKTsKICAgICAgICAgICAgICAgIF90aGlzNS5zdGFydFBvbGxUaW1lb3V0KCk7CiAgICAgICAgICAgIH0sIHBvbGxpbmdJbnRlcnZhbCk7CiAgICAgICAgfQoKICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgLy8gIEFuaW1hdGlvbgogICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAgICAgLyoqCiAgICAgICAgIFJlbmRlcnMgYSBmcmFtZSBpbiB0aGUgcHJvY2VzcyBvZiBhbmltYXRpbmcgZnJvbSBjdXJyZW50TGVmdCAvIGN1cnJlbnRUb3AKICAgICAgICAgdG8gZ29hbExlZnQgLyBnb2FsVG9wCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ3JlbmRlcicsCgoKICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgLy8gIFJlYWN0IExpZmVjeWNsZQogICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHMsCiAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IF9wcm9wcy5jaGlsZHJlbiwKICAgICAgICAgICAgICAgIHN0eWxlID0gX3Byb3BzLnN0eWxlOwoKICAgICAgICAgICAgdmFyIHdyYXBwZXJTdHlsZSA9IF9leHRlbmRzKHt9LCBzdHlsZSwgewogICAgICAgICAgICAgICAgbGVmdDogdGhpcy5jdXJyZW50TGVmdCArICdweCcsCiAgICAgICAgICAgICAgICB0b3A6IHRoaXMuY3VycmVudFRvcCArICdweCcKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdGbG9hdGluZ0VsZW1lbnQnIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgICAgICAgICB7IHJlZjogJ3dyYXBwZXInLCBjbGFzc05hbWU6ICdGbG9hdGluZ0VsZW1lbnQtd3JhcHBlcicsIHN0eWxlOiB3cmFwcGVyU3R5bGUgfSwKICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHsKICAgICAgICAgICAgaWYgKG5leHRQcm9wcy5wb3NpdGlvbkZ1bmN0aW9uICE9PSB0aGlzLnByb3BzLnBvc2l0aW9uRnVuY3Rpb24gfHwgbmV4dFByb3BzLnRhcmdldEVsZW1lbnQgIT09IHRoaXMucHJvcHMudGFyZ2V0RWxlbWVudCkgewogICAgICAgICAgICAgICAgdGhpcy5pbnZhbGlkYXRlUG9zaXRpb25pbmcoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjb21wb25lbnREaWRNb3VudCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkgewogICAgICAgICAgICB0aGlzLmNvbXBvbmVudFJlbmRlcmVkKCk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2NvbXBvbmVudERpZFVwZGF0ZScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZFVwZGF0ZSgpIHsKICAgICAgICAgICAgdGhpcy5jb21wb25lbnRSZW5kZXJlZCgpOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjb21wb25lbnRSZW5kZXJlZCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFJlbmRlcmVkKCkgewogICAgICAgICAgICB2YXIgX3RoaXM2ID0gdGhpczsKCiAgICAgICAgICAgIHRoaXMuc2V0SW5pdGlhbFBvc2l0aW9uKCk7CiAgICAgICAgICAgIC8vIEFzIHNvb24gYXMgcG9zc2libGUsIHdlIG5lZWQgdG8gcmUtY2FsY3VsYXRlIG91ciBwb3NpdGlvbgogICAgICAgICAgICB0aGlzLnZhbGlkYXRlUG9zaXRpb25pbmdTY2hlZHVsZWQgPSB0cnVlOwogICAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIF90aGlzNi52YWxpZGF0ZVBvc2l0aW9uaW5nU2NoZWR1bGVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICBfdGhpczYudmFsaWRhdGVQb3NpdGlvbmluZygpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIC8vIFN0YXJ0IHRoZSBwZXJpb2RpYyB0aW1lb3V0IHRvIGNoZWNrIGRvbSBtZWFzdXJlbWVudHMKICAgICAgICAgICAgdGhpcy5zdGFydFBvbGxUaW1lb3V0KCk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2NvbXBvbmVudFdpbGxVbm1vdW50JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7CiAgICAgICAgICAgIGlmICh0aGlzLnBvbGxpbmdUaW1lb3V0KSB7CiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wb2xsaW5nVGltZW91dCk7CiAgICAgICAgICAgICAgICB0aGlzLnBvbGxpbmdUaW1lb3V0ID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gRmxvYXRpbmdFbGVtZW50Owp9KF9yZWFjdC5Db21wb25lbnQpOwoKRmxvYXRpbmdFbGVtZW50LnByb3BUeXBlcyA9IHsKICAgIHRhcmdldEVsZW1lbnQ6IF9yZWFjdC5Qcm9wVHlwZXMub2JqZWN0LAogICAgcG9zaXRpb25GdW5jdGlvbjogX3JlYWN0LlByb3BUeXBlcy5mdW5jLAogICAgc3R5bGU6IF9yZWFjdC5Qcm9wVHlwZXMub2JqZWN0LAogICAgY2hpbGRyZW46IF9yZWFjdC5Qcm9wVHlwZXMubm9kZQp9Owp9LHsicmVhY3QiOjYyM31dLDc1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9OwoKZXhwb3J0cy5JY29uQnV0dG9uID0gSWNvbkJ1dHRvbjsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX3JlYWN0TWF0ZXJpYWxJY29ucyA9IHJlcXVpcmUoJ0BqZW5raW5zLWNkL3JlYWN0LW1hdGVyaWFsLWljb25zJyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKLyoqCiAqIGJ1dHRvbiBlbGVtZW50IHdpdGggaWNvbi4KICogVXNlICJpY29uTmFtZSIgZm9yIHN0YW5kYXJkIG1hdGVyaWFsLXVpIGljb25zCiAqIFVzZSAiY2hpbGRyZW4iIGZvciBjdXN0b20gaWNvbi4gUHJvdmlkZSBlbGVtZW50IChlLmcuIHJhdyBzdmcpLCBvciBSZWFjdCBjb21wb25lbnQKICoKICogQHBhcmFtIHtvYmplY3R9IFtwcm9wcy5jaGlsZHJlbl0gLSBSZWFjdCBlbGVtZW50IG9yIGN1c3RvbSBjb21wb25lbnQgdG8gcmVuZGVyIGFzIGljb24KICogQHBhcmFtIHtzdHJpbmd9IFtwcm9wcy5jbGFzc05hbWVdIC0gY3VzdG9tIGNsYXNzIG5hbWUgZm9yIG91dGVyIGVsZW1lbnQKICogQHBhcmFtIHtvYmplY3R9IFtwcm9wcy5zdHlsZV0gLSBjdXN0b20gc3R5bGUgb2JqZWN0CiAqIEBwYXJhbSB7c3RyaW5nfSBbcHJvcHMubGFiZWxdIC0gYnV0dG9uIHRleHQKICogQHBhcmFtIHtzdHJpbmd9IFtwcm9wcy5pY29uTmFtZV0gLSBuYW1lIG9mIG1hdGVyaWFsLXVpIGljb24gdG8gZGlzcGxheQogKiBAcGFyYW0ge251bWJlcn0gW3Byb3BzLmljb25TaXplXSAtIHdpZHRoL2hlaWdodCBvZiBpY29uCiAqIEBwYXJhbSB7c3RyaW5nfSBbcHJvcHMuaWNvbkZpbGxdIC0gY29sb3IgY29kZSB0byBhcHBseSBhcyBmaWxsCiAqIEBwYXJhbSB7ZnVuY3Rpb259IFtwcm9wcy5vbkNsaWNrXSAtIG9uY2xpY2sgY2FsbGJhY2sgZnVuY3Rpb24KICogQGNvbnN0cnVjdG9yCiAqLwpmdW5jdGlvbiBJY29uQnV0dG9uKHByb3BzKSB7CiAgICBmdW5jdGlvbiBfb25DbGljaygpIHsKICAgICAgICBpZiAob25DbGljaykgewogICAgICAgICAgICBvbkNsaWNrKCk7CiAgICAgICAgfQogICAgfQoKICAgIHZhciBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuLAogICAgICAgIGNsYXNzTmFtZSA9IHByb3BzLmNsYXNzTmFtZSwKICAgICAgICBzdHlsZSA9IHByb3BzLnN0eWxlLAogICAgICAgIGxhYmVsID0gcHJvcHMubGFiZWwsCiAgICAgICAgaWNvbk5hbWUgPSBwcm9wcy5pY29uTmFtZSwKICAgICAgICBpY29uU2l6ZSA9IHByb3BzLmljb25TaXplLAogICAgICAgIGljb25GaWxsID0gcHJvcHMuaWNvbkZpbGwsCiAgICAgICAgb25DbGljayA9IHByb3BzLm9uQ2xpY2s7CgoKICAgIHZhciBpY29uID0gbnVsbDsKCiAgICBpZiAoaWNvbk5hbWUpIHsKICAgICAgICAvLyB1c2UgcmVhY3QtbWF0ZXJpYWwtaWNvbnMgYW5kIGFkYXB0IEljb25CdXR0b24gcHJvcHMgdG8gSWNvbidzIEFQSQogICAgICAgIHZhciBtYXRlcmlhbFByb3BzID0gewogICAgICAgICAgICBzaXplOiBpY29uU2l6ZSwKICAgICAgICAgICAgc3R5bGU6IHsKICAgICAgICAgICAgICAgIGZpbGw6IGljb25GaWxsCiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIGljb24gPSBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChfcmVhY3RNYXRlcmlhbEljb25zLkljb24sIF9leHRlbmRzKHsgaWNvbjogaWNvbk5hbWUgfSwgbWF0ZXJpYWxQcm9wcykpOwogICAgfSBlbHNlIGlmIChjaGlsZHJlbikgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIHBhc3MgZG93biBwcm9wcyBvZiBpbnRlcmVzdCB0byB0aGUgY2hpbGQgc28gaXQgY2FuIHJlYWN0CiAgICAgICAgICAgIHZhciBpY29uUHJvcHMgPSB7CiAgICAgICAgICAgICAgICB3aWR0aDogaWNvblNpemUsCiAgICAgICAgICAgICAgICBoZWlnaHQ6IGljb25TaXplLAogICAgICAgICAgICAgICAgc2l6ZTogaWNvblNpemUsCiAgICAgICAgICAgICAgICBmaWxsOiBpY29uRmlsbAogICAgICAgICAgICB9OwoKICAgICAgICAgICAgaWNvbiA9IF9yZWFjdDIuZGVmYXVsdC5DaGlsZHJlbi5tYXAoY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jbG9uZUVsZW1lbnQoY2hpbGQsIGljb25Qcm9wcyk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0pKCk7CiAgICB9CgogICAgdmFyIGN1c3RvbUNsYXNzID0gY2xhc3NOYW1lIHx8ICcnOwogICAgdmFyIGljb25OYW1lQ2xhc3MgPSBpY29uTmFtZSA/ICd1LWljb24tJyArIGljb25OYW1lIDogJyc7CiAgICB2YXIgbWF0ZXJpYWxDbGFzcyA9IGljb25OYW1lID8gJ3UtbWF0ZXJpYWwtaWNvbicgOiAnJzsKICAgIHZhciBzcGFjaW5nQ2xhc3MgPSBsYWJlbCAmJiBpY29uID8gJ3UtaW5uZXItbWFyZ2luJyA6ICcnOwoKICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAnYnV0dG9uJywKICAgICAgICB7CiAgICAgICAgICAgIGNsYXNzTmFtZTogJ0ljb25CdXR0b24gJyArIGN1c3RvbUNsYXNzICsgJyAnICsgaWNvbk5hbWVDbGFzcyArICcgJyArIG1hdGVyaWFsQ2xhc3MgKyAnICcgKyBzcGFjaW5nQ2xhc3MsCiAgICAgICAgICAgIHN0eWxlOiBzdHlsZSwKICAgICAgICAgICAgb25DbGljazogX29uQ2xpY2sKICAgICAgICB9LAogICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdJY29uQnV0dG9uLXdyYXBwZXInIH0sCiAgICAgICAgICAgIGljb24gJiYgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnc3BhbicsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ0ljb25CdXR0b24taWNvbicgfSwKICAgICAgICAgICAgICAgIGljb24KICAgICAgICAgICAgKSwKICAgICAgICAgICAgbGFiZWwgJiYgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnc3BhbicsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ0ljb25CdXR0b24tdGV4dCcgfSwKICAgICAgICAgICAgICAgIGxhYmVsCiAgICAgICAgICAgICkKICAgICAgICApCiAgICApOwp9CgpJY29uQnV0dG9uLnByb3BUeXBlcyA9IHsKICAgIGNoaWxkcmVuOiBfcmVhY3QuUHJvcFR5cGVzLmVsZW1lbnQsCiAgICBjbGFzc05hbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgc3R5bGU6IF9yZWFjdC5Qcm9wVHlwZXMub2JqZWN0LAogICAgbGFiZWw6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgaWNvbk5hbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgaWNvblNpemU6IF9yZWFjdC5Qcm9wVHlwZXMubnVtYmVyLAogICAgaWNvbkZpbGw6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgb25DbGljazogX3JlYWN0LlByb3BUeXBlcy5mdW5jCn07Cn0seyJAamVua2lucy1jZC9yZWFjdC1tYXRlcmlhbC1pY29ucyI6MTI5LCJyZWFjdCI6NjIzfV0sNzY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5MaXN0ID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9VdGlscyA9IHJlcXVpcmUoJy4uL1V0aWxzJyk7Cgp2YXIgX1V0aWxzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1V0aWxzKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0KCi8qKgogKiBDaGVja3Mgd2hldGhlciB0aGUgc3VwcGxpZWQgY2hpbGQgaXMgc2Nyb2xsZWQgYWJvdmUgb3IgYmVsb3cgdGhlIHBhcmVudCdzIHRvcC9ib3R0b20gZWRnZXMuCiAqIEBwYXJhbSBwYXJlbnQKICogQHBhcmFtIGNoaWxkCiAqIEByZXR1cm5zIHt7YWJvdmU6IGJvb2xlYW4sIGJlbG93OiBib29sZWFufX0KICovCmZ1bmN0aW9uIGlzU2Nyb2xsZWRBYm92ZU9yQmVsb3cocGFyZW50LCBjaGlsZCkgewogICAgdmFyIHJlc3VsdCA9IHsKICAgICAgICBhYm92ZTogZmFsc2UsCiAgICAgICAgYmVsb3c6IGZhbHNlCiAgICB9OwoKICAgIHZhciBjaGlsZFJlY3QgPSBjaGlsZC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgIHZhciBwYXJlbnRSZWN0ID0gcGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwoKICAgIGlmIChjaGlsZFJlY3QudG9wIDwgcGFyZW50UmVjdC50b3ApIHsKICAgICAgICByZXN1bHQuYWJvdmUgPSB0cnVlOwogICAgfSBlbHNlIGlmIChjaGlsZFJlY3QuYm90dG9tID4gcGFyZW50UmVjdC5ib3R0b20pIHsKICAgICAgICByZXN1bHQuYmVsb3cgPSB0cnVlOwogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBDb250cm9sIHRoYXQgZGlzcGxheXMgYSBMaXN0IG9mIGl0ZW1zIGFuZCBhbGxvd3MgZm9yIHNlbGVjdGlvbi4KICogRnVuY3Rpb25zIGxpa2UgYSBsaXN0IG9mIHJhZGlvIGJ1dHRvbnMgZnJvbSBhIGtleWJvYXJkIGFjY2Vzc2liaWxpdHkgc3RhbmRwb2ludC4KICogQnkgZGVmYXVsdCBpdCB1c2VzIGEgc2ltcGxlIHJlbmRlcmVyIHRoYXQgY29udmVydHMgZWFjaCBvYmplY3QgdG8gYSBzdHJpbmcuCiAqIEEgY3VzdG9tIHJlbmRlcmVyIGNhbiBiZSBwcm92aWRlZCBhcyBhIHNpbmdsZSBSZWFjdCBjaGlsZCB0byB0aGUgZWxlbWVudCwgZS5nLgogKiAgICAgIDxMaXN0IGRhdGE9e2RhdGF9PgogKiAgICAgICAgICA8TXlSZW5kZXJlciAvPgogKiAgICAgIDwvTGlzdD4KICoKICogICAgICBmdW5jdGlvbiBNeVJlbmRlcmVyKHByb3BzKSB7CiAqICAgICAgICAgIHJldHVybiAoCiAqICAgICAgICAgICAgICA8ZGl2Pntwcm9wcy5saXN0SW5kZXh9IHtwcm9wcy5saXN0SXRlbX08L2Rpdj4KICogICAgICAgICAgKTsKICogICAgICB9CiAqIEN1c3RvbSByZW5kZXIgd2lsbCByZWNlaXZlIHRocmVlIHByb3BzOiBsaXN0SW5kZXgsIGxpc3RJdGVtIGFuZCBsYWJlbEZ1bmN0aW9uIChmcm9tIHBhcmVudCkKICogQSBrZXlGdW5jdGlvbiBpcyBlbmNvdXJhZ2VkIHRvIGdlbmVyYXRlIGEgUmVhY3Qga2V5IGZvciBlYWNoIHJvdy4gRGVmYXVsdCBpcyB0byB1c2UgbGlzdEluZGV4LgogKgogKiBAcHJvcGVydHkge3N0cmluZ30gY2xhc3NOYW1lIGFkZGl0aW9uYWwgImNsYXNzIiB0byBhZGQgdG8gb3V0ZXJtb3N0IGVsZW1lbnQgKGFsb25nc2lkZSAiTGlzdCIpCiAqIEBwcm9wZXJ0eSB7YXJyYXl9IGNoaWxkcmVuIFJlYWN0IGNoaWxkcmVuCiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBzdHlsZSBSZWFjdCBzdHlsZSBvYmplY3QgdG8gYmUgYXBwbGllZCB0byBvdXRlciBlbGVtZW50LgogKiBAcHJvcGVydHkge2FycmF5fSBbZGF0YV0gZGF0YSB0byByZW5kZXIgaW4gdGhlIGxpc3QuCiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IFtsYWJlbEZ1bmN0aW9uXSBjb252ZXJ0cyBlYWNoIG9iamVjdCB0byBhIHN0cmluZyBpbiB0aGUgZGVmYXVsdCByZW5kZXJlci4KICogQHByb3BlcnR5IHtGdW5jdGlvbn0gW2tleUZ1bmN0aW9uXQogKiBAcHJvcGVydHkge2Jvb2xlYW59IFtkZWZhdWx0U3R5bGVzXSBzZXQgImZhbHNlIiB0byByZW1vdmUgYWxsIGRlZmF1bHQgc3R5bGluZyBmcm9tIHRoZSBMaXN0LgogKiBAcHJvcGVydHkge09iamVjdH0gW2RlZmF1bHRTZWxlY3Rpb25dIGl0ZW0gdG8gc2VsZWN0IGluIHRoZSBsaXN0IGJ5IGRlZmF1bHQKICogQHByb3BlcnR5IHtGdW5jdGlvbn0gW29uSXRlbVNlbGVjdF0gY2FsbGJhY2sgd2hlbiBhbiBpdGVtIGlzIHNlbGVjdGVkLCByZWNlaXZpbmcgbGlzdEluZGV4IGFuZCBsaXN0SXRlbS4KICovCgp2YXIgTGlzdCA9IGV4cG9ydHMuTGlzdCA9IGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoTGlzdCwgX1JlYWN0JENvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gTGlzdChwcm9wcykgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBMaXN0KTsKCiAgICAgICAgdmFyIF90aGlzID0gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKExpc3QuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihMaXN0KSkuY2FsbCh0aGlzLCBwcm9wcykpOwoKICAgICAgICBfdGhpcy5zdGF0ZSA9IHt9OwoKICAgICAgICBfdGhpcy5ncm91cElkID0gX1V0aWxzMi5kZWZhdWx0LnJhbmRvbUlkKCdMaXN0Jyk7CiAgICAgICAgcmV0dXJuIF90aGlzOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhMaXN0LCBbewogICAgICAgIGtleTogJ2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykgewogICAgICAgICAgICB2YXIgc2VsZWN0ZWRJdGVtID0gdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW07CiAgICAgICAgICAgIHZhciBkYXRhID0gbmV4dFByb3BzLmRhdGE7CgogICAgICAgICAgICAvLyBpZiB0aGUgc2VsZWN0ZWRJdGVtIGlzIG5vdCBmb3VuZCBpbiBuZXcgZGF0YSwgZGlzY2FyZCBpdAoKICAgICAgICAgICAgaWYgKHNlbGVjdGVkSXRlbSAmJiAoIWRhdGEgfHwgZGF0YS5pbmRleE9mKHNlbGVjdGVkSXRlbSkgPT09IC0xKSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7CiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRJdGVtOiB1bmRlZmluZWQKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLl9kZWZhdWx0U2VsZWN0aW9uKG5leHRQcm9wcyk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2NvbXBvbmVudERpZE1vdW50JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7CiAgICAgICAgICAgIHRoaXMuX2RlZmF1bHRTZWxlY3Rpb24odGhpcy5wcm9wcyk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ19zdG9yZVNlbGZOb2RlJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX3N0b3JlU2VsZk5vZGUobm9kZSkgewogICAgICAgICAgICB0aGlzLnNlbGZOb2RlID0gbm9kZTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX2RlZmF1bHRTZWxlY3Rpb24nLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfZGVmYXVsdFNlbGVjdGlvbihuZXh0UHJvcHMpIHsKICAgICAgICAgICAgaWYgKCF0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbSAmJiBuZXh0UHJvcHMuZGVmYXVsdFNlbGVjdGlvbikgewogICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7CiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRJdGVtOiBuZXh0UHJvcHMuZGVmYXVsdFNlbGVjdGlvbgogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX29uQ2hhbmdlU2VsZWN0aW9uJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX29uQ2hhbmdlU2VsZWN0aW9uKGV2ZW50LCBpbmRleCwgaXRlbSkgewogICAgICAgICAgICAvLyBGaXJlZm94IGFuZCBTYWZhcmkgZG9uJ3QgYXBwbHkgZm9jdXMgYWZ0ZXIgImNoYW5nZSIgc28gZm9yY2UgaXQKICAgICAgICAgICAgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgIT09IGV2ZW50LmN1cnJlbnRUYXJnZXQgJiYgZXZlbnQuY3VycmVudFRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7CiAgICAgICAgICAgICAgICBldmVudC5jdXJyZW50VGFyZ2V0LmZvY3VzKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoewogICAgICAgICAgICAgICAgc2VsZWN0ZWRJdGVtOiBpdGVtCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMub25JdGVtU2VsZWN0KSB7CiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLm9uSXRlbVNlbGVjdChpbmRleCwgaXRlbSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX3Njcm9sbEZvY3VzZWRJdGVtSW50b1ZpZXcnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfc2Nyb2xsRm9jdXNlZEl0ZW1JbnRvVmlldyhldmVudCkgewogICAgICAgICAgICBpZiAoZXZlbnQuY3VycmVudFRhcmdldCBpbnN0YW5jZW9mIEVsZW1lbnQgJiYgZXZlbnQuY3VycmVudFRhcmdldC5wYXJlbnRFbGVtZW50KSB7CiAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIC5MaXN0LUl0ZW0gYXNzb2NpYXRlZCB3LyB0aGUgZm9jdXNlZCBpbnB1dFt0eXBlPSJyYWRpbyJdCiAgICAgICAgICAgICAgICB2YXIgcGFyZW50RWxlbWVudCA9IGV2ZW50LmN1cnJlbnRUYXJnZXQucGFyZW50RWxlbWVudDsKICAgICAgICAgICAgICAgIHZhciBpdGVtcyA9IHBhcmVudEVsZW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnTGlzdC1JdGVtJyk7CiAgICAgICAgICAgICAgICB0aGlzLl9zY3JvbGxOb2RlSW50b1ZpZXcoaXRlbXNbMF0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ19zY3JvbGxOb2RlSW50b1ZpZXcnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfc2Nyb2xsTm9kZUludG9WaWV3KHRhcmdldE5vZGUpIHsKICAgICAgICAgICAgdmFyIHBvc2l0aW9uID0gaXNTY3JvbGxlZEFib3ZlT3JCZWxvdyh0aGlzLnNlbGZOb2RlLCB0YXJnZXROb2RlKTsKCiAgICAgICAgICAgIGlmIChwb3NpdGlvbi5hYm92ZSB8fCBwb3NpdGlvbi5iZWxvdykgewogICAgICAgICAgICAgICAgdGFyZ2V0Tm9kZS5zY3JvbGxJbnRvVmlldyhwb3NpdGlvbi5hYm92ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX3RoaXMyID0gdGhpczsKCiAgICAgICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzLAogICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBfcHJvcHMuY2hpbGRyZW4sCiAgICAgICAgICAgICAgICBkYXRhID0gX3Byb3BzLmRhdGEsCiAgICAgICAgICAgICAgICBkaXNhYmxlZCA9IF9wcm9wcy5kaXNhYmxlZCwKICAgICAgICAgICAgICAgIGtleUZ1bmN0aW9uID0gX3Byb3BzLmtleUZ1bmN0aW9uLAogICAgICAgICAgICAgICAgbGFiZWxGdW5jdGlvbiA9IF9wcm9wcy5sYWJlbEZ1bmN0aW9uOwoKCiAgICAgICAgICAgIHZhciBjaGlsZENvdW50ID0gX3JlYWN0Mi5kZWZhdWx0LkNoaWxkcmVuLmNvdW50KGNoaWxkcmVuKTsKCiAgICAgICAgICAgIHZhciBjaGlsZFRlbXBsYXRlID0gdm9pZCAwOwoKICAgICAgICAgICAgaWYgKGNoaWxkQ291bnQgPT09IDApIHsKICAgICAgICAgICAgICAgIGNoaWxkVGVtcGxhdGUgPSBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChEZWZhdWx0UmVuZGVyZXIsIG51bGwpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGNoaWxkQ291bnQgPT09IDEpIHsKICAgICAgICAgICAgICAgIGNoaWxkVGVtcGxhdGUgPSBfcmVhY3QyLmRlZmF1bHQuQ2hpbGRyZW4ub25seShjaGlsZHJlbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdcJ2NoaWxkcmVuXCcgc3VwcGxpZWQgdG8gTGlzdCBtdXN0IGJlIHplcm8gb3Igb25lIGVsZW1lbnRzJyk7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGxpc3RDbGFzcyA9IHRoaXMucHJvcHMuY2xhc3NOYW1lIHx8ICcnOwogICAgICAgICAgICB2YXIgc2VsZWN0ZWRDbGFzcyA9IHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtID8gJ0xpc3Qtc2VsZWN0ZWQnIDogJyc7CiAgICAgICAgICAgIHZhciBkZWZhdWx0Q2xhc3MgPSB0aGlzLnByb3BzLmRlZmF1bHRTdHlsZXMgPyAndS1kZWZhdWx0LWxpc3QtY29udGFpbmVyJyA6ICcnOwogICAgICAgICAgICB2YXIgZGlzYWJsZWRDbGFzcyA9IGRpc2FibGVkID8gJ2Rpc2FibGVkJyA6ICcnOwoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVmOiBmdW5jdGlvbiByZWYobm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMyLl9zdG9yZVNlbGZOb2RlKG5vZGUpOwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnTGlzdCAnICsgc2VsZWN0ZWRDbGFzcyArICcgJyArIGxpc3RDbGFzcyArICcgJyArIGRlZmF1bHRDbGFzcyArICcgJyArIGRpc2FibGVkQ2xhc3MsCiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHRoaXMucHJvcHMuc3R5bGUKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBkYXRhICYmIGRhdGEubWFwKGZ1bmN0aW9uIChpdGVtLCBpbmRleCkgewogICAgICAgICAgICAgICAgICAgIHZhciBpdGVtU2VsZWN0ZWRDbGFzcyA9IGl0ZW0gPT09IF90aGlzMi5zdGF0ZS5zZWxlY3RlZEl0ZW0gPyAnTGlzdC1JdGVtLXNlbGVjdGVkJyA6ICcnOwogICAgICAgICAgICAgICAgICAgIHZhciBrZXlWYWx1ZSA9IGtleUZ1bmN0aW9uID8ga2V5RnVuY3Rpb24oaXRlbSkgOiBpbmRleDsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICAgICAnbGFiZWwnLAogICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ0xpc3QtUm93Jywga2V5OiBrZXlWYWx1ZSB9LAogICAgICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgnaW5wdXQnLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAncmFkaW8nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogX3RoaXMyLmdyb3VwSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICdMaXN0LVJhZGlvIGNsb2FrJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlOiBmdW5jdGlvbiBvbkNoYW5nZShldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIuX29uQ2hhbmdlU2VsZWN0aW9uKGV2ZW50LCBpbmRleCwgaXRlbSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb25Gb2N1czogZnVuY3Rpb24gb25Gb2N1cyhldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIuX3Njcm9sbEZvY3VzZWRJdGVtSW50b1ZpZXcoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkOiBkaXNhYmxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrZWQ6ICEhaXRlbVNlbGVjdGVkQ2xhc3MKICAgICAgICAgICAgICAgICAgICAgICAgfSksCiAgICAgICAgICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ0xpc3QtSXRlbSAnICsgaXRlbVNlbGVjdGVkQ2xhc3MgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jbG9uZUVsZW1lbnQoY2hpbGRUZW1wbGF0ZSwgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RJbmRleDogaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdEl0ZW06IGl0ZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxGdW5jdGlvbjogbGFiZWxGdW5jdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdzZWxlY3RlZEluZGV4JywKICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICAgICAgdmFyIHNlbGVjdGVkSXRlbSA9IHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtOwogICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMucHJvcHMuZGF0YTsKCgogICAgICAgICAgICByZXR1cm4gc2VsZWN0ZWRJdGVtICYmIGRhdGEgPyBkYXRhLmluZGV4T2Yoc2VsZWN0ZWRJdGVtKSA6IC0xOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdzZWxlY3RlZEl0ZW0nLAogICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW07CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBMaXN0Owp9KF9yZWFjdDIuZGVmYXVsdC5Db21wb25lbnQpOwoKTGlzdC5kZWZhdWx0UHJvcHMgPSB7CiAgICBzdHlsZToge30sCiAgICBkZWZhdWx0U3R5bGVzOiB0cnVlLAogICAgbGFiZWxGdW5jdGlvbjogaXRlbVRvTGFiZWwKfTsKCgpMaXN0LnByb3BUeXBlcyA9IHsKICAgIGNsYXNzTmFtZTogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBjaGlsZHJlbjogX3JlYWN0LlByb3BUeXBlcy5lbGVtZW50LAogICAgc3R5bGU6IF9yZWFjdC5Qcm9wVHlwZXMub2JqZWN0LAogICAgZGF0YTogX3JlYWN0LlByb3BUeXBlcy5hcnJheSwKICAgIGRpc2FibGVkOiBfcmVhY3QuUHJvcFR5cGVzLmJvb2wsCiAgICBsYWJlbEZ1bmN0aW9uOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsCiAgICBrZXlGdW5jdGlvbjogX3JlYWN0LlByb3BUeXBlcy5mdW5jLAogICAgZGVmYXVsdFN0eWxlczogX3JlYWN0LlByb3BUeXBlcy5ib29sLAogICAgZGVmYXVsdFNlbGVjdGlvbjogX3JlYWN0LlByb3BUeXBlcy5hbnksCiAgICBvbkl0ZW1TZWxlY3Q6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYwp9OwoKZnVuY3Rpb24gaXRlbVRvTGFiZWwoaXRlbSkgewogICAgaWYgKHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykgewogICAgICAgIHJldHVybiBpdGVtOwogICAgfSBlbHNlIGlmIChpdGVtLnRvU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIGl0ZW0udG9TdHJpbmcoKTsKICAgIH0KCiAgICByZXR1cm4gJyc7Cn0KCmZ1bmN0aW9uIERlZmF1bHRSZW5kZXJlcihwcm9wcykgewogICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICdkaXYnLAogICAgICAgIHsgY2xhc3NOYW1lOiAnTGlzdC1EZWZhdWx0UmVuZGVyZXInIH0sCiAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICdzcGFuJywKICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdMaXN0LURlZmF1bHRSZW5kZXJlci10ZXh0JyB9LAogICAgICAgICAgICBwcm9wcy5sYWJlbEZ1bmN0aW9uKHByb3BzLmxpc3RJdGVtKQogICAgICAgICkKICAgICk7Cn0KCkRlZmF1bHRSZW5kZXJlci5wcm9wVHlwZXMgPSB7CiAgICBsaXN0SW5kZXg6IF9yZWFjdC5Qcm9wVHlwZXMubnVtYmVyLAogICAgbGlzdEl0ZW06IF9yZWFjdC5Qcm9wVHlwZXMub25lT2ZUeXBlKFtfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywgX3JlYWN0LlByb3BUeXBlcy5vYmplY3RdKSwKICAgIGxhYmVsRnVuY3Rpb246IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYwp9Owp9LHsiLi4vVXRpbHMiOjY0LCJyZWFjdCI6NjIzfV0sNzc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5QaXBlbGluZUdyYXBoID0gZXhwb3J0cy5kZWZhdWx0TGF5b3V0ID0gdW5kZWZpbmVkOwoKdmFyIF9zbGljZWRUb0FycmF5ID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBzbGljZUl0ZXJhdG9yKGFyciwgaSkgeyB2YXIgX2FyciA9IFtdOyB2YXIgX24gPSB0cnVlOyB2YXIgX2QgPSBmYWxzZTsgdmFyIF9lID0gdW5kZWZpbmVkOyB0cnkgeyBmb3IgKHZhciBfaSA9IGFycltTeW1ib2wuaXRlcmF0b3JdKCksIF9zOyAhKF9uID0gKF9zID0gX2kubmV4dCgpKS5kb25lKTsgX24gPSB0cnVlKSB7IF9hcnIucHVzaChfcy52YWx1ZSk7IGlmIChpICYmIF9hcnIubGVuZ3RoID09PSBpKSBicmVhazsgfSB9IGNhdGNoIChlcnIpIHsgX2QgPSB0cnVlOyBfZSA9IGVycjsgfSBmaW5hbGx5IHsgdHJ5IHsgaWYgKCFfbiAmJiBfaVsicmV0dXJuIl0pIF9pWyJyZXR1cm4iXSgpOyB9IGZpbmFsbHkgeyBpZiAoX2QpIHRocm93IF9lOyB9IH0gcmV0dXJuIF9hcnI7IH0gcmV0dXJuIGZ1bmN0aW9uIChhcnIsIGkpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgeyByZXR1cm4gYXJyOyB9IGVsc2UgaWYgKFN5bWJvbC5pdGVyYXRvciBpbiBPYmplY3QoYXJyKSkgeyByZXR1cm4gc2xpY2VJdGVyYXRvcihhcnIsIGkpOyB9IGVsc2UgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJJbnZhbGlkIGF0dGVtcHQgdG8gZGVzdHJ1Y3R1cmUgbm9uLWl0ZXJhYmxlIGluc3RhbmNlIik7IH0gfTsgfSgpOwoKdmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfU3RhdHVzSW5kaWNhdG9yID0gcmVxdWlyZSgnLi9zdGF0dXMvU3RhdHVzSW5kaWNhdG9yJyk7Cgp2YXIgX1N2Z1NwaW5uZXIgPSByZXF1aXJlKCcuL3N0YXR1cy9TdmdTcGlubmVyJyk7Cgp2YXIgX1RydW5jYXRpbmdMYWJlbCA9IHJlcXVpcmUoJy4vVHJ1bmNhdGluZ0xhYmVsJyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9Cgp2YXIgeXBTdGFydCA9IDU1OwoKLy8gRGltZW5zaW9ucyB1c2VkIGZvciBsYXlvdXQsIHB4CnZhciBkZWZhdWx0TGF5b3V0ID0gZXhwb3J0cy5kZWZhdWx0TGF5b3V0ID0gewogICAgbm9kZVNwYWNpbmdIOiAxMjAsCiAgICBub2RlU3BhY2luZ1Y6IDcwLAogICAgbm9kZVJhZGl1czogMTIsCiAgICBjdXJ2ZVJhZGl1czogMTIsCiAgICBjb25uZWN0b3JTdHJva2VXaWR0aDogMy41LAogICAgbGFiZWxPZmZzZXRWOiAyMCwKICAgIHNtYWxsTGFiZWxPZmZzZXRWOiAxNQp9OwoKLy8gVHlwZWRlZnMKCi8vIEZJWE1FLUZMT1c6IEN1cnJlbnRseSBuZWVkIHRvIGR1cGxpY2F0ZSByZWFjdCdzIHByb3BUeXBlcyBvYmogaW4gRmxvdy4KLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svZmxvdy9pc3N1ZXMvMTc3MAoKdmFyIFBpcGVsaW5lR3JhcGggPSBleHBvcnRzLlBpcGVsaW5lR3JhcGggPSBmdW5jdGlvbiAoX0NvbXBvbmVudCkgewogICAgX2luaGVyaXRzKFBpcGVsaW5lR3JhcGgsIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIFBpcGVsaW5lR3JhcGgocHJvcHMpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUGlwZWxpbmVHcmFwaCk7CgogICAgICAgIHZhciBfdGhpcyA9IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChQaXBlbGluZUdyYXBoLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoUGlwZWxpbmVHcmFwaCkpLmNhbGwodGhpcywgcHJvcHMpKTsKCiAgICAgICAgX3RoaXMuc3RhdGUgPSB7CiAgICAgICAgICAgIG5vZGVzOiBbXSwKICAgICAgICAgICAgY29ubmVjdGlvbnM6IFtdLAogICAgICAgICAgICBiaWdMYWJlbHM6IFtdLAogICAgICAgICAgICBzbWFsbExhYmVsczogW10sCiAgICAgICAgICAgIG1lYXN1cmVkV2lkdGg6IDAsCiAgICAgICAgICAgIG1lYXN1cmVkSGVpZ2h0OiAwLAogICAgICAgICAgICBsYXlvdXQ6IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRMYXlvdXQsIHByb3BzLmxheW91dCksCiAgICAgICAgICAgIHNlbGVjdGVkU3RhZ2U6IHByb3BzLnNlbGVjdGVkU3RhZ2UKICAgICAgICB9OwogICAgICAgIHJldHVybiBfdGhpczsKICAgIH0KCiAgICAvLyBGbG93IHR5cGVkZWZzCgoKICAgIF9jcmVhdGVDbGFzcyhQaXBlbGluZUdyYXBoLCBbewogICAgICAgIGtleTogJ2NvbXBvbmVudFdpbGxNb3VudCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxNb3VudCgpIHsKICAgICAgICAgICAgdGhpcy5zdGFnZXNVcGRhdGVkKHRoaXMucHJvcHMuc3RhZ2VzKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7CiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzOwoKICAgICAgICAgICAgdmFyIG5ld1N0YXRlID0gbnVsbDsgLy8gbnVsbCA9PSBubyBuZXcgc3RhdGUKICAgICAgICAgICAgdmFyIG5lZWRzTGF5b3V0ID0gZmFsc2U7CgogICAgICAgICAgICBpZiAobmV4dFByb3BzLmxheW91dCAhPSB0aGlzLnByb3BzLmxheW91dCkgewogICAgICAgICAgICAgICAgLy8gVE9ETzogRG9lcyBsYXlvdXQgb2JqIHJlYWxseSBuZWVkIHRvIGJlIGluIHN0YXRlPwogICAgICAgICAgICAgICAgbmV3U3RhdGUgPSBfZXh0ZW5kcyh7fSwgbmV3U3RhdGUsIHsgbGF5b3V0OiBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0TGF5b3V0LCB0aGlzLnByb3BzLmxheW91dCkgfSk7CiAgICAgICAgICAgICAgICBuZWVkc0xheW91dCA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChuZXh0UHJvcHMuc2VsZWN0ZWRTdGFnZSAhPT0gdGhpcy5wcm9wcy5zZWxlY3RlZFN0YWdlKSB7CiAgICAgICAgICAgICAgICAvLyBJZiB3ZSdyZSBqdXN0IGNoYW5naW5nIHNlbGVjdGVkU3RhZ2UsIHdlIGRvbid0IG5lZWQgdG8gcmUtZ2VuZXJhdGUgdGhlIGNoaWxkcmVuCiAgICAgICAgICAgICAgICBuZXdTdGF0ZSA9IF9leHRlbmRzKHt9LCBuZXdTdGF0ZSwgeyBzZWxlY3RlZFN0YWdlOiBuZXh0UHJvcHMuc2VsZWN0ZWRTdGFnZSB9KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG5leHRQcm9wcy5zdGFnZXMgIT09IHRoaXMucHJvcHMuc3RhZ2VzKSB7CiAgICAgICAgICAgICAgICBuZWVkc0xheW91dCA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBkb0xheW91dElmTmVlZGVkID0gZnVuY3Rpb24gZG9MYXlvdXRJZk5lZWRlZCgpIHsKICAgICAgICAgICAgICAgIGlmIChuZWVkc0xheW91dCkgewogICAgICAgICAgICAgICAgICAgIF90aGlzMi5zdGFnZXNVcGRhdGVkKG5leHRQcm9wcy5zdGFnZXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgICAgICAgaWYgKG5ld1N0YXRlKSB7CiAgICAgICAgICAgICAgICAvLyBJZiB3ZSBuZWVkIHRvIHVwZGF0ZSB0aGUgc3RhdGUsIHRoZW4gd2UnbGwgZGVsYXkgYW55IGxheW91dCBjaGFuZ2VzCiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKG5ld1N0YXRlLCBkb0xheW91dElmTmVlZGVkKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGRvTGF5b3V0SWZOZWVkZWQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdhZGRDb25uZWN0aW9uRGV0YWlscycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGFkZENvbm5lY3Rpb25EZXRhaWxzKGNvbm5lY3Rpb25zLCBwcmV2aW91c05vZGVzLCBjb2x1bW5Ob2RlcykgewogICAgICAgICAgICAvLyBDb25uZWN0IHRvIHRvcCBvZiBwcmV2aW91cy9uZXh0IGNvbHVtbi4gQ3VydmVzIGFkZGVkIHdoZW4gY3JlYXRpbmcgU1ZHCgogICAgICAgICAgICAvLyBDb2xsYXBzZSBmcm9tIHByZXZpb3VzIG5vZGUocykgdG8gdG9wIGNvbHVtbiBub2RlCiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZTsKICAgICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yID0gZmFsc2U7CiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JFcnJvciA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBwcmV2aW91c05vZGVzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXA7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IChfc3RlcCA9IF9pdGVyYXRvci5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBwcmV2aW91c05vZGUgPSBfc3RlcC52YWx1ZTsKCiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMucHVzaChbcHJldmlvdXNOb2RlLCBjb2x1bW5Ob2Rlc1swXV0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIEV4cGFuZCBmcm9tIHRvcCBwcmV2aW91cyBub2RlIHRvIGNvbHVtbiBub2RlKHMpIC0gZmlyc3Qgb25lIGRvbmUgYWxyZWFkeSBhYm92ZQogICAgICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yID0gdHJ1ZTsKICAgICAgICAgICAgICAgIF9pdGVyYXRvckVycm9yID0gZXJyOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gJiYgX2l0ZXJhdG9yLnJldHVybikgewogICAgICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3IucmV0dXJuKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3I7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIgPSB0cnVlOwogICAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IyID0gZmFsc2U7CiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjIgPSB1bmRlZmluZWQ7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IGNvbHVtbk5vZGVzLnNsaWNlKDEpW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAyOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yID0gKF9zdGVwMiA9IF9pdGVyYXRvcjIubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIgPSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbHVtbk5vZGUgPSBfc3RlcDIudmFsdWU7CgogICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLnB1c2goW3ByZXZpb3VzTm9kZXNbMF0sIGNvbHVtbk5vZGVdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjIgPSB0cnVlOwogICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IyID0gZXJyOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yICYmIF9pdGVyYXRvcjIucmV0dXJuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvcjIucmV0dXJuKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yMjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnc3RhZ2VzVXBkYXRlZCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHN0YWdlc1VwZGF0ZWQoKSB7CiAgICAgICAgICAgIHZhciBuZXdTdGFnZXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IFtdOwogICAgICAgICAgICB2YXIgX3N0YXRlJGxheW91dCA9IHRoaXMuc3RhdGUubGF5b3V0LAogICAgICAgICAgICAgICAgbm9kZVNwYWNpbmdIID0gX3N0YXRlJGxheW91dC5ub2RlU3BhY2luZ0gsCiAgICAgICAgICAgICAgICBub2RlU3BhY2luZ1YgPSBfc3RhdGUkbGF5b3V0Lm5vZGVTcGFjaW5nVjsKCgogICAgICAgICAgICB2YXIgbm9kZXMgPSBbXTsKICAgICAgICAgICAgdmFyIGNvbm5lY3Rpb25zID0gW107CiAgICAgICAgICAgIHZhciBiaWdMYWJlbHMgPSBbXTsKICAgICAgICAgICAgdmFyIHNtYWxsTGFiZWxzID0gW107CgogICAgICAgICAgICAvLyBuZXh0IG5vZGUgcG9zaXRpb24KICAgICAgICAgICAgdmFyIHhwID0gbm9kZVNwYWNpbmdIIC8gMjsKICAgICAgICAgICAgdmFyIHlwID0gMDsKCiAgICAgICAgICAgIHZhciBwcmV2aW91c05vZGVzID0gW107CiAgICAgICAgICAgIHZhciBtb3N0Q29sdW1uTm9kZXMgPSAwOwoKICAgICAgICAgICAgLy8gRm9yIHJlYWNoIHRvcC1sZXZlbCBzdGFnZSB3ZSBoYXZlIGEgY29sdW1uIG9mIG5vZGUocykKICAgICAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zID0gdHJ1ZTsKICAgICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yMyA9IGZhbHNlOwogICAgICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IzID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjMgPSBuZXdTdGFnZXNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDM7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMgPSAoX3N0ZXAzID0gX2l0ZXJhdG9yMy5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMyA9IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdG9wU3RhZ2UgPSBfc3RlcDMudmFsdWU7CgoKICAgICAgICAgICAgICAgICAgICB5cCA9IHlwU3RhcnQ7CgogICAgICAgICAgICAgICAgICAgIC8vIEFsd2F5cyBoYXZlIGEgc2luZ2xlIGJpZ0xhYmVsIHBlciB0b3AtbGV2ZWwgc3RhZ2UKICAgICAgICAgICAgICAgICAgICBiaWdMYWJlbHMucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgICAgIHg6IHhwLAogICAgICAgICAgICAgICAgICAgICAgICB5OiB5cCwKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogdG9wU3RhZ2UubmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhZ2U6IHRvcFN0YWdlCiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgIC8vIElmIHN0YWdlIGhhcyBjaGlsZHJlbiwgd2UgZG9uJ3QgZHJhdyBhIG5vZGUgZm9yIGl0LCBqdXN0IGl0cyBjaGlsZHJlbgogICAgICAgICAgICAgICAgICAgIHZhciBub2RlU3RhZ2VzID0gdG9wU3RhZ2UuY2hpbGRyZW4gJiYgdG9wU3RhZ2UuY2hpbGRyZW4ubGVuZ3RoID8gdG9wU3RhZ2UuY2hpbGRyZW4gOiBbdG9wU3RhZ2VdOwoKICAgICAgICAgICAgICAgICAgICB2YXIgY29sdW1uTm9kZXMgPSBbXTsKCiAgICAgICAgICAgICAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb240ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3I0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yNCA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yNCA9IG5vZGVTdGFnZXNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDQ7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjQgPSAoX3N0ZXA0ID0gX2l0ZXJhdG9yNC5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uNCA9IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlU3RhZ2UgPSBfc3RlcDQudmFsdWU7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogeHAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogeXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogbm9kZVN0YWdlLm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGU6IG5vZGVTdGFnZS5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZVBlcmNlbnQ6IG5vZGVTdGFnZS5jb21wbGV0ZVBlcmNlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IG5vZGVTdGFnZS5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFnZTogbm9kZVN0YWdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbk5vZGVzLnB1c2gobm9kZSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBzZXBhcmF0ZSBjaGlsZCBub2RlcyBuZWVkIGEgc21hbGxMYWJlbCwgYXMgdG9wU3RhZ2UgYWxyZWFkeSBoYXMgYSBiaWdMYWJlbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVTdGFnZSAhPSB0b3BTdGFnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNtYWxsTGFiZWxzLnB1c2goewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiB4cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogeXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IG5vZGVTdGFnZS5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFnZTogbm9kZVN0YWdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgeXAgKz0gbm9kZVNwYWNpbmdWOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yNCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvckVycm9yNCA9IGVycjsKICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uNCAmJiBfaXRlcmF0b3I0LnJldHVybikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvcjQucmV0dXJuKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3I0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3I0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAocHJldmlvdXNOb2Rlcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRDb25uZWN0aW9uRGV0YWlscyhjb25uZWN0aW9ucywgcHJldmlvdXNOb2RlcywgY29sdW1uTm9kZXMpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeHAgKz0gbm9kZVNwYWNpbmdIOwogICAgICAgICAgICAgICAgICAgIG1vc3RDb2x1bW5Ob2RlcyA9IE1hdGgubWF4KG1vc3RDb2x1bW5Ob2Rlcywgbm9kZVN0YWdlcy5sZW5ndGgpOwogICAgICAgICAgICAgICAgICAgIG5vZGVzLnB1c2guYXBwbHkobm9kZXMsIGNvbHVtbk5vZGVzKTsKICAgICAgICAgICAgICAgICAgICBwcmV2aW91c05vZGVzID0gY29sdW1uTm9kZXM7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gQ2FsYyBkaW1lbnNpb25zCiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IzID0gdHJ1ZTsKICAgICAgICAgICAgICAgIF9pdGVyYXRvckVycm9yMyA9IGVycjsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMyAmJiBfaXRlcmF0b3IzLnJldHVybikgewogICAgICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3IzLnJldHVybigpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMykgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbWVhc3VyZWRXaWR0aCA9IHhwIC0gTWF0aC5mbG9vcihub2RlU3BhY2luZ0ggLyAyKTsKICAgICAgICAgICAgdmFyIG1lYXN1cmVkSGVpZ2h0ID0geXBTdGFydCArIG1vc3RDb2x1bW5Ob2RlcyAqIG5vZGVTcGFjaW5nVjsKCiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoewogICAgICAgICAgICAgICAgbm9kZXM6IG5vZGVzLAogICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IGNvbm5lY3Rpb25zLAogICAgICAgICAgICAgICAgYmlnTGFiZWxzOiBiaWdMYWJlbHMsCiAgICAgICAgICAgICAgICBzbWFsbExhYmVsczogc21hbGxMYWJlbHMsCiAgICAgICAgICAgICAgICBtZWFzdXJlZFdpZHRoOiBtZWFzdXJlZFdpZHRoLAogICAgICAgICAgICAgICAgbWVhc3VyZWRIZWlnaHQ6IG1lYXN1cmVkSGVpZ2h0CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdyZW5kZXJCaWdMYWJlbCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlckJpZ0xhYmVsKGRldGFpbHMpIHsKICAgICAgICAgICAgdmFyIF9zdGF0ZSRsYXlvdXQyID0gdGhpcy5zdGF0ZS5sYXlvdXQsCiAgICAgICAgICAgICAgICBub2RlU3BhY2luZ0ggPSBfc3RhdGUkbGF5b3V0Mi5ub2RlU3BhY2luZ0gsCiAgICAgICAgICAgICAgICBsYWJlbE9mZnNldFYgPSBfc3RhdGUkbGF5b3V0Mi5sYWJlbE9mZnNldFYsCiAgICAgICAgICAgICAgICBjb25uZWN0b3JTdHJva2VXaWR0aCA9IF9zdGF0ZSRsYXlvdXQyLmNvbm5lY3RvclN0cm9rZVdpZHRoOwoKCiAgICAgICAgICAgIHZhciBsYWJlbFdpZHRoID0gbm9kZVNwYWNpbmdIIC0gY29ubmVjdG9yU3Ryb2tlV2lkdGggKiAyOwogICAgICAgICAgICB2YXIgbGFiZWxIZWlnaHQgPSB5cFN0YXJ0IC0gbGFiZWxPZmZzZXRWOwogICAgICAgICAgICB2YXIgbGFiZWxPZmZzZXRIID0gTWF0aC5mbG9vcihsYWJlbFdpZHRoIC8gLTIpOwoKICAgICAgICAgICAgLy8gVGhlc2UgYXJlIGFib3V0IGxheW91dCBtb3JlIHRoYW4gYXBwZWFyYW5jZSwgc28gdGhleSBzaG91bGQgcHJvYmFibHkgcmVtYWluIGlubGluZQogICAgICAgICAgICB2YXIgYmlnTGFiZWxTdHlsZSA9IHsKICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAiYWJzb2x1dGUiLAogICAgICAgICAgICAgICAgd2lkdGg6IGxhYmVsV2lkdGgsCiAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IGxhYmVsSGVpZ2h0ICsgInB4IiwKICAgICAgICAgICAgICAgIHRleHRBbGlnbjogImNlbnRlciIsCiAgICAgICAgICAgICAgICBtYXJnaW5MZWZ0OiBsYWJlbE9mZnNldEgKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHZhciB4ID0gZGV0YWlscy54OwogICAgICAgICAgICB2YXIgYm90dG9tID0gdGhpcy5zdGF0ZS5tZWFzdXJlZEhlaWdodCAtIGRldGFpbHMueSArIGxhYmVsT2Zmc2V0VjsKCiAgICAgICAgICAgIHZhciBzdHlsZSA9IE9iamVjdC5hc3NpZ24oe30sIGJpZ0xhYmVsU3R5bGUsIHsKICAgICAgICAgICAgICAgIGJvdHRvbTogYm90dG9tICsgInB4IiwKICAgICAgICAgICAgICAgIGxlZnQ6IHggKyAicHgiCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgdmFyIGtleSA9IGRldGFpbHMuc3RhZ2UuaWQgKyAiLWJpZyI7CgogICAgICAgICAgICB2YXIgY2xhc3NOYW1lcyA9IFsicGlwZWxpbmUtYmlnLWxhYmVsIl07CiAgICAgICAgICAgIGlmICh0aGlzLnN0YWdlSXNTZWxlY3RlZChkZXRhaWxzLnN0YWdlKSB8fCB0aGlzLnN0YWdlQ2hpbGRJc1NlbGVjdGVkKGRldGFpbHMuc3RhZ2UpKSB7CiAgICAgICAgICAgICAgICBjbGFzc05hbWVzLnB1c2goInNlbGVjdGVkIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgIF9UcnVuY2F0aW5nTGFiZWwuVHJ1bmNhdGluZ0xhYmVsLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IGNsYXNzTmFtZXMuam9pbigiICIpLCBzdHlsZTogc3R5bGUsIGtleToga2V5IH0sCiAgICAgICAgICAgICAgICBkZXRhaWxzLnRleHQKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAncmVuZGVyU21hbGxMYWJlbCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlclNtYWxsTGFiZWwoZGV0YWlscykgewogICAgICAgICAgICB2YXIgX3N0YXRlJGxheW91dDMgPSB0aGlzLnN0YXRlLmxheW91dCwKICAgICAgICAgICAgICAgIG5vZGVTcGFjaW5nSCA9IF9zdGF0ZSRsYXlvdXQzLm5vZGVTcGFjaW5nSCwKICAgICAgICAgICAgICAgIG5vZGVTcGFjaW5nViA9IF9zdGF0ZSRsYXlvdXQzLm5vZGVTcGFjaW5nViwKICAgICAgICAgICAgICAgIGN1cnZlUmFkaXVzID0gX3N0YXRlJGxheW91dDMuY3VydmVSYWRpdXMsCiAgICAgICAgICAgICAgICBjb25uZWN0b3JTdHJva2VXaWR0aCA9IF9zdGF0ZSRsYXlvdXQzLmNvbm5lY3RvclN0cm9rZVdpZHRoLAogICAgICAgICAgICAgICAgbm9kZVJhZGl1cyA9IF9zdGF0ZSRsYXlvdXQzLm5vZGVSYWRpdXMsCiAgICAgICAgICAgICAgICBzbWFsbExhYmVsT2Zmc2V0ViA9IF9zdGF0ZSRsYXlvdXQzLnNtYWxsTGFiZWxPZmZzZXRWOwoKCiAgICAgICAgICAgIHZhciBzbWFsbExhYmVsV2lkdGggPSBNYXRoLmZsb29yKG5vZGVTcGFjaW5nSCAtIDIgKiBjdXJ2ZVJhZGl1cyAtIDIgKiBjb25uZWN0b3JTdHJva2VXaWR0aCk7IC8vIEZpdCBiZXR3ZWVuIGxpbmVzCiAgICAgICAgICAgIHZhciBzbWFsbExhYmVsSGVpZ2h0ID0gTWF0aC5mbG9vcihub2RlU3BhY2luZ1YgLSBzbWFsbExhYmVsT2Zmc2V0ViAtIG5vZGVSYWRpdXMgLSBfU3ZnU3Bpbm5lci5zdHJva2VXaWR0aCk7CiAgICAgICAgICAgIHZhciBzbWFsbExhYmVsT2Zmc2V0SCA9IE1hdGguZmxvb3Ioc21hbGxMYWJlbFdpZHRoICogLTAuNSk7CgogICAgICAgICAgICAvLyBUaGVzZSBhcmUgYWJvdXQgbGF5b3V0IG1vcmUgdGhhbiBhcHBlYXJhbmNlLCBzbyB0aGV5IHNob3VsZCBwcm9iYWJseSByZW1haW4gaW5saW5lCiAgICAgICAgICAgIHZhciBzbWFsbExhYmVsU3R5bGUgPSB7CiAgICAgICAgICAgICAgICBwb3NpdGlvbjogImFic29sdXRlIiwKICAgICAgICAgICAgICAgIHdpZHRoOiBzbWFsbExhYmVsV2lkdGgsCiAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IHNtYWxsTGFiZWxIZWlnaHQsCiAgICAgICAgICAgICAgICB0ZXh0QWxpZ246ICJjZW50ZXIiCiAgICAgICAgICAgIH07CgogICAgICAgICAgICB2YXIgeCA9IGRldGFpbHMueCArIHNtYWxsTGFiZWxPZmZzZXRIOwogICAgICAgICAgICB2YXIgdG9wID0gZGV0YWlscy55ICsgc21hbGxMYWJlbE9mZnNldFY7CgogICAgICAgICAgICB2YXIgc3R5bGUgPSBPYmplY3QuYXNzaWduKHt9LCBzbWFsbExhYmVsU3R5bGUsIHsKICAgICAgICAgICAgICAgIHRvcDogdG9wLAogICAgICAgICAgICAgICAgbGVmdDogeAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGlmIChkZXRhaWxzLnRleHQuaW5kZXhPZigna29tcCcpICE9PSAtMSkgewogICAgICAgICAgICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoc3R5bGUsIG51bGwsIDQpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGtleSA9IGRldGFpbHMuc3RhZ2UuaWQgKyAnLXNtYWxsJzsKCiAgICAgICAgICAgIHZhciBjbGFzc05hbWVzID0gWyJwaXBlbGluZS1zbWFsbC1sYWJlbCJdOwogICAgICAgICAgICBpZiAodGhpcy5zdGFnZUlzU2VsZWN0ZWQoZGV0YWlscy5zdGFnZSkpIHsKICAgICAgICAgICAgICAgIGNsYXNzTmFtZXMucHVzaCgic2VsZWN0ZWQiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgX1RydW5jYXRpbmdMYWJlbC5UcnVuY2F0aW5nTGFiZWwsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogY2xhc3NOYW1lcy5qb2luKCIgIiksIHN0eWxlOiBzdHlsZSwga2V5OiBrZXkgfSwKICAgICAgICAgICAgICAgIGRldGFpbHMudGV4dAogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdyZW5kZXJDb25uZWN0aW9uJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyQ29ubmVjdGlvbihjb25uZWN0aW9uKSB7CiAgICAgICAgICAgIHZhciBfc3RhdGUkbGF5b3V0NCA9IHRoaXMuc3RhdGUubGF5b3V0LAogICAgICAgICAgICAgICAgbm9kZVJhZGl1cyA9IF9zdGF0ZSRsYXlvdXQ0Lm5vZGVSYWRpdXMsCiAgICAgICAgICAgICAgICBjdXJ2ZVJhZGl1cyA9IF9zdGF0ZSRsYXlvdXQ0LmN1cnZlUmFkaXVzLAogICAgICAgICAgICAgICAgY29ubmVjdG9yU3Ryb2tlV2lkdGggPSBfc3RhdGUkbGF5b3V0NC5jb25uZWN0b3JTdHJva2VXaWR0aDsKCiAgICAgICAgICAgIHZhciBfY29ubmVjdGlvbiA9IF9zbGljZWRUb0FycmF5KGNvbm5lY3Rpb24sIDIpLAogICAgICAgICAgICAgICAgbGVmdE5vZGUgPSBfY29ubmVjdGlvblswXSwKICAgICAgICAgICAgICAgIHJpZ2h0Tm9kZSA9IF9jb25uZWN0aW9uWzFdOwoKICAgICAgICAgICAgdmFyIGtleSA9IGxlZnROb2RlLm5hbWUgKyBsZWZ0Tm9kZS5pZCArICJfY29uXyIgKyByaWdodE5vZGUubmFtZSArIHJpZ2h0Tm9kZS5pZDsKCiAgICAgICAgICAgIHZhciBsZWZ0UG9zID0gewogICAgICAgICAgICAgICAgeDogbGVmdE5vZGUueCArIG5vZGVSYWRpdXMgLSBfU3ZnU3Bpbm5lci5zdHJva2VXaWR0aCAvIDIsCiAgICAgICAgICAgICAgICB5OiBsZWZ0Tm9kZS55CiAgICAgICAgICAgIH07CgogICAgICAgICAgICB2YXIgcmlnaHRQb3MgPSB7CiAgICAgICAgICAgICAgICB4OiByaWdodE5vZGUueCAtIG5vZGVSYWRpdXMgKyBfU3ZnU3Bpbm5lci5zdHJva2VXaWR0aCAvIDIsCiAgICAgICAgICAgICAgICB5OiByaWdodE5vZGUueQogICAgICAgICAgICB9OwoKICAgICAgICAgICAgLy8gU3Ryb2tlIHByb3BzIGNvbW1vbiB0byBzdHJhaWdodCAvIGN1cnZlZCBjb25uZWN0aW9ucwogICAgICAgICAgICB2YXIgY29ubmVjdG9yU3Ryb2tlID0gewogICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAicGlwZWxpbmUtY29ubmVjdG9yIiwKICAgICAgICAgICAgICAgIHN0cm9rZVdpZHRoOiBjb25uZWN0b3JTdHJva2VXaWR0aAogICAgICAgICAgICB9OwoKICAgICAgICAgICAgaWYgKGxlZnRQb3MueSA9PSByaWdodFBvcy55KSB7CiAgICAgICAgICAgICAgICAvLyBOaWNlIGhvcml6b250YWwgbGluZQogICAgICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdsaW5lJywgX2V4dGVuZHMoe30sIGNvbm5lY3RvclN0cm9rZSwgewogICAgICAgICAgICAgICAgICAgIGtleToga2V5LAogICAgICAgICAgICAgICAgICAgIHgxOiBsZWZ0UG9zLngsCiAgICAgICAgICAgICAgICAgICAgeTE6IGxlZnRQb3MueSwKICAgICAgICAgICAgICAgICAgICB4MjogcmlnaHRQb3MueCwKICAgICAgICAgICAgICAgICAgICB5MjogcmlnaHRQb3MueSB9KSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgd2UnZCBsaWtlIGEgY3VydmUKCiAgICAgICAgICAgIHZhciB2ZXJ0aWNhbERpcmVjdGlvbiA9IE1hdGguc2lnbihyaWdodFBvcy55IC0gbGVmdFBvcy55KTsgLy8gMSA9PSBjdXJ2ZSBkb3duLCAtMSA9PSBjdXJ2ZSB1cAogICAgICAgICAgICB2YXIgbWlkUG9pbnRYID0gTWF0aC5yb3VuZCgobGVmdFBvcy54ICsgcmlnaHRQb3MueCkgLyAyICsgY3VydmVSYWRpdXMgKiB2ZXJ0aWNhbERpcmVjdGlvbik7CiAgICAgICAgICAgIHZhciB3MSA9IG1pZFBvaW50WCAtIGN1cnZlUmFkaXVzIC0gbGVmdFBvcy54OwogICAgICAgICAgICB2YXIgdzIgPSByaWdodFBvcy54IC0gY3VydmVSYWRpdXMgLSBtaWRQb2ludFg7CiAgICAgICAgICAgIHZhciB2ID0gcmlnaHRQb3MueSAtIGxlZnRQb3MueSAtIDIgKiBjdXJ2ZVJhZGl1cyAqIHZlcnRpY2FsRGlyZWN0aW9uOyAvLyBXaWxsIGJlIC1pdmUgaWYgY3VydmUgdXAKICAgICAgICAgICAgdmFyIGN2ID0gdmVydGljYWxEaXJlY3Rpb24gKiBjdXJ2ZVJhZGl1czsKCiAgICAgICAgICAgIHZhciBwYXRoRGF0YSA9ICdNICcgKyBsZWZ0UG9zLnggKyAnICcgKyBsZWZ0UG9zLnkgLy8gc3RhcnQgcG9zaXRpb24KICAgICAgICAgICAgKyAoJyBsICcgKyB3MSArICcgMCcpIC8vIGZpcnN0IGhvcml6b250YWwgbGluZQogICAgICAgICAgICArICgnIGMgJyArIGN1cnZlUmFkaXVzICsgJyAwICcgKyBjdXJ2ZVJhZGl1cyArICcgJyArIGN2ICsgJyAnICsgY3VydmVSYWRpdXMgKyAnICcgKyBjdikgLy8gdHVybgogICAgICAgICAgICArICgnIGwgMCAnICsgdikgLy8gdmVydGljYWwgbGluZQogICAgICAgICAgICArICgnIGMgMCAnICsgY3YgKyAnICcgKyBjdXJ2ZVJhZGl1cyArICcgJyArIGN2ICsgJyAnICsgY3VydmVSYWRpdXMgKyAnICcgKyBjdikgLy8gdHVybiBhZ2FpbgogICAgICAgICAgICArICgnIGwgJyArIHcyICsgJyAwJykgLy8gc2Vjb25kIGhvcml6b250YWwgbGluZQogICAgICAgICAgICA7CgogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCBfZXh0ZW5kcyh7fSwgY29ubmVjdG9yU3Ryb2tlLCB7IGtleToga2V5LCBkOiBwYXRoRGF0YSwgZmlsbDogJ25vbmUnIH0pKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAncmVuZGVyTm9kZScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlck5vZGUobm9kZSkgewogICAgICAgICAgICB2YXIgX3RoaXMzID0gdGhpczsKCiAgICAgICAgICAgIHZhciBub2RlSXNTZWxlY3RlZCA9IHRoaXMuc3RhZ2VJc1NlbGVjdGVkKG5vZGUuc3RhZ2UpOwogICAgICAgICAgICB2YXIgX3N0YXRlJGxheW91dDUgPSB0aGlzLnN0YXRlLmxheW91dCwKICAgICAgICAgICAgICAgIG5vZGVSYWRpdXMgPSBfc3RhdGUkbGF5b3V0NS5ub2RlUmFkaXVzLAogICAgICAgICAgICAgICAgY29ubmVjdG9yU3Ryb2tlV2lkdGggPSBfc3RhdGUkbGF5b3V0NS5jb25uZWN0b3JTdHJva2VXaWR0aDsKICAgICAgICAgICAgLy8gVXNlIGEgYmlnZ2VyIHJhZGl1cyBmb3IgaW52aXNpYmxlIGNsaWNrL3RvdWNoIHRhcmdldAoKICAgICAgICAgICAgdmFyIG1vdXNlVGFyZ2V0UmFkaXVzID0gbm9kZVJhZGl1cyArIDIgKiBjb25uZWN0b3JTdHJva2VXaWR0aDsKCiAgICAgICAgICAgIHZhciByZXN1bHRDbGVhbiA9ICgwLCBfU3RhdHVzSW5kaWNhdG9yLmRlY29kZVJlc3VsdFZhbHVlKShub2RlLnN0YXRlKTsKICAgICAgICAgICAgdmFyIGtleSA9ICJuXyIgKyBub2RlLm5hbWUgKyBub2RlLmlkOwoKICAgICAgICAgICAgdmFyIGNvbXBsZXRlUGVyY2VudCA9IG5vZGUuY29tcGxldGVQZXJjZW50IHx8IDA7CiAgICAgICAgICAgIHZhciBncm91cENoaWxkcmVuID0gWygwLCBfU3RhdHVzSW5kaWNhdG9yLmdldEdyb3VwRm9yUmVzdWx0KShyZXN1bHRDbGVhbiwgY29tcGxldGVQZXJjZW50LCBub2RlUmFkaXVzKV07CiAgICAgICAgICAgIHZhciB0aXRsZSA9IG5vZGUuc3RhZ2UudGl0bGU7CgogICAgICAgICAgICBpZiAodGl0bGUpIHsKICAgICAgICAgICAgICAgIGdyb3VwQ2hpbGRyZW4ucHVzaChfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAndGl0bGUnLAogICAgICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAgICAgdGl0bGUKICAgICAgICAgICAgICAgICkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEFkZCBhbiBpbnZpc2libGUgY2xpY2svdG91Y2ggdGFyZ2V0LCBjb3ogdGhlIG5vZGVzIGFyZSBzbWFsbCBhbmQgKG1vcmUgaW1wb3J0YW50bHkpCiAgICAgICAgICAgIC8vIG1hbnkgYXJlIGhvbGxvdy4KICAgICAgICAgICAgZ3JvdXBDaGlsZHJlbi5wdXNoKF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdjaXJjbGUnLCB7IHI6IG1vdXNlVGFyZ2V0UmFkaXVzLAogICAgICAgICAgICAgICAgY3Vyc29yOiAncG9pbnRlcicsCiAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICdwaXBlbGluZS1ub2RlLWhpdHRhcmdldCcsCiAgICAgICAgICAgICAgICBmaWxsT3BhY2l0eTogJzAnLAogICAgICAgICAgICAgICAgc3Ryb2tlOiAnbm9uZScsCiAgICAgICAgICAgICAgICBvbkNsaWNrOiBmdW5jdGlvbiBvbkNsaWNrKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczMubm9kZUNsaWNrZWQobm9kZSk7CiAgICAgICAgICAgICAgICB9IH0pKTsKCiAgICAgICAgICAgIC8vIEFsbCB0aGUgbm9kZXMgYXJlIGluIHNoYXJlZCBjb2RlLCBzbyB0aGV5J3JlIHJlbmRlcmVkIGF0IDAsMCBzbyB3ZSB0cmFuc2Zvcm0gd2l0aGluIGEgPGc+CiAgICAgICAgICAgIHZhciBncm91cFByb3BzID0gewogICAgICAgICAgICAgICAga2V5OiBrZXksCiAgICAgICAgICAgICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGUoJyArIG5vZGUueCArICcsJyArIG5vZGUueSArICcpJywKICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogbm9kZUlzU2VsZWN0ZWQgPyAicGlwZWxpbmUtbm9kZS1zZWxlY3RlZCIgOiAicGlwZWxpbmUtbm9kZSIKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudC5hcHBseShfcmVhY3QyLmRlZmF1bHQsIFsiZyIsIGdyb3VwUHJvcHNdLmNvbmNhdChncm91cENoaWxkcmVuKSk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3JlbmRlclNlbGVjdGlvbkhpZ2hsaWdodCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlclNlbGVjdGlvbkhpZ2hsaWdodCgpIHsKICAgICAgICAgICAgdmFyIF9zdGF0ZSRsYXlvdXQ2ID0gdGhpcy5zdGF0ZS5sYXlvdXQsCiAgICAgICAgICAgICAgICBub2RlUmFkaXVzID0gX3N0YXRlJGxheW91dDYubm9kZVJhZGl1cywKICAgICAgICAgICAgICAgIGNvbm5lY3RvclN0cm9rZVdpZHRoID0gX3N0YXRlJGxheW91dDYuY29ubmVjdG9yU3Ryb2tlV2lkdGg7CgogICAgICAgICAgICB2YXIgaGlnaGxpZ2h0UmFkaXVzID0gbm9kZVJhZGl1cyArIDAuNDkgKiBjb25uZWN0b3JTdHJva2VXaWR0aDsKICAgICAgICAgICAgdmFyIHNlbGVjdGVkTm9kZSA9IG51bGw7CgogICAgICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjUgPSB0cnVlOwogICAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3I1ID0gZmFsc2U7CiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjUgPSB1bmRlZmluZWQ7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yNSA9IHRoaXMuc3RhdGUubm9kZXNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDU7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjUgPSAoX3N0ZXA1ID0gX2l0ZXJhdG9yNS5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uNSA9IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZSA9IF9zdGVwNS52YWx1ZTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhZ2VJc1NlbGVjdGVkKG5vZGUuc3RhZ2UpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IG5vZGU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjUgPSB0cnVlOwogICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3I1ID0gZXJyOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb241ICYmIF9pdGVyYXRvcjUucmV0dXJuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvcjUucmV0dXJuKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3I1KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yNTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghc2VsZWN0ZWROb2RlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHRyYW5zZm9ybSA9ICd0cmFuc2xhdGUoJyArIHNlbGVjdGVkTm9kZS54ICsgJyAnICsgc2VsZWN0ZWROb2RlLnkgKyAnKSc7CgogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnZycsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3BpcGVsaW5lLXNlbGVjdGlvbi1oaWdobGlnaHQnLCB0cmFuc2Zvcm06IHRyYW5zZm9ybSB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ2NpcmNsZScsIHsgcjogaGlnaGxpZ2h0UmFkaXVzLCBzdHJva2VXaWR0aDogY29ubmVjdG9yU3Ryb2tlV2lkdGggKiAxLjEgfSkKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIC8vIFB1dCBpbiBhIGZ1bmN0aW9uIHNvIHdlIGNhbiBtYWtlIGltcHJvdmVtZW50cyAvIG11bHRpLXNlbGVjdAoKICAgIH0sIHsKICAgICAgICBrZXk6ICdzdGFnZUlzU2VsZWN0ZWQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzdGFnZUlzU2VsZWN0ZWQoc3RhZ2UpIHsKICAgICAgICAgICAgdmFyIHNlbGVjdGVkU3RhZ2UgPSB0aGlzLnN0YXRlLnNlbGVjdGVkU3RhZ2U7CgoKICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGVkU3RhZ2UgJiYgc2VsZWN0ZWRTdGFnZSA9PT0gc3RhZ2U7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3N0YWdlQ2hpbGRJc1NlbGVjdGVkJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gc3RhZ2VDaGlsZElzU2VsZWN0ZWQoc3RhZ2UpIHsKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gc3RhZ2UuY2hpbGRyZW47CiAgICAgICAgICAgIHZhciBzZWxlY3RlZFN0YWdlID0gdGhpcy5zdGF0ZS5zZWxlY3RlZFN0YWdlOwoKCiAgICAgICAgICAgIGlmIChjaGlsZHJlbiAmJiBzZWxlY3RlZFN0YWdlKSB7CiAgICAgICAgICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjYgPSB0cnVlOwogICAgICAgICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yNiA9IGZhbHNlOwogICAgICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yNiA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjYgPSBjaGlsZHJlbltTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwNjsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uNiA9IChfc3RlcDYgPSBfaXRlcmF0b3I2Lm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb242ID0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGQgPSBfc3RlcDYudmFsdWU7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQgPT09IHNlbGVjdGVkU3RhZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3I2ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvcjYgPSBlcnI7CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjYgJiYgX2l0ZXJhdG9yNi5yZXR1cm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvcjYucmV0dXJuKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3I2KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjY7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdub2RlQ2xpY2tlZCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIG5vZGVDbGlja2VkKG5vZGUpIHsKICAgICAgICAgICAgdmFyIHN0YWdlID0gbm9kZS5zdGFnZTsKICAgICAgICAgICAgdmFyIGxpc3RlbmVyID0gdGhpcy5wcm9wcy5vbk5vZGVDbGljazsKCiAgICAgICAgICAgIGlmIChsaXN0ZW5lcikgewogICAgICAgICAgICAgICAgbGlzdGVuZXIoc3RhZ2UubmFtZSwgc3RhZ2UuaWQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBVcGRhdGUgc2VsZWN0aW9uCiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZFN0YWdlOiBzdGFnZSB9KTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX3RoaXM0ID0gdGhpczsKCiAgICAgICAgICAgIHZhciBfc3RhdGUgPSB0aGlzLnN0YXRlLAogICAgICAgICAgICAgICAgX3N0YXRlJG5vZGVzID0gX3N0YXRlLm5vZGVzLAogICAgICAgICAgICAgICAgbm9kZXMgPSBfc3RhdGUkbm9kZXMgPT09IHVuZGVmaW5lZCA/IFtdIDogX3N0YXRlJG5vZGVzLAogICAgICAgICAgICAgICAgX3N0YXRlJGNvbm5lY3Rpb25zID0gX3N0YXRlLmNvbm5lY3Rpb25zLAogICAgICAgICAgICAgICAgY29ubmVjdGlvbnMgPSBfc3RhdGUkY29ubmVjdGlvbnMgPT09IHVuZGVmaW5lZCA/IFtdIDogX3N0YXRlJGNvbm5lY3Rpb25zLAogICAgICAgICAgICAgICAgX3N0YXRlJGJpZ0xhYmVscyA9IF9zdGF0ZS5iaWdMYWJlbHMsCiAgICAgICAgICAgICAgICBiaWdMYWJlbHMgPSBfc3RhdGUkYmlnTGFiZWxzID09PSB1bmRlZmluZWQgPyBbXSA6IF9zdGF0ZSRiaWdMYWJlbHMsCiAgICAgICAgICAgICAgICBfc3RhdGUkc21hbGxMYWJlbHMgPSBfc3RhdGUuc21hbGxMYWJlbHMsCiAgICAgICAgICAgICAgICBzbWFsbExhYmVscyA9IF9zdGF0ZSRzbWFsbExhYmVscyA9PT0gdW5kZWZpbmVkID8gW10gOiBfc3RhdGUkc21hbGxMYWJlbHMsCiAgICAgICAgICAgICAgICBtZWFzdXJlZFdpZHRoID0gX3N0YXRlLm1lYXN1cmVkV2lkdGgsCiAgICAgICAgICAgICAgICBtZWFzdXJlZEhlaWdodCA9IF9zdGF0ZS5tZWFzdXJlZEhlaWdodDsKCiAgICAgICAgICAgIC8vIFRoZXNlIGFyZSBhYm91dCBsYXlvdXQgbW9yZSB0aGFuIGFwcGVhcmFuY2UsIHNvIHRoZXkgc2hvdWxkIHByb2JhYmx5IHJlbWFpbiBpbmxpbmUKCiAgICAgICAgICAgIHZhciBvdXRlckRpdlN0eWxlID0gewogICAgICAgICAgICAgICAgcG9zaXRpb246ICJyZWxhdGl2ZSIsIC8vIFNvIHdlIGNhbiBwdXQgdGhlIGxhYmVscyB3aGVyZSB3ZSBuZWVkIHRoZW0KICAgICAgICAgICAgICAgIG92ZXJmbG93OiAidmlzaWJsZSIgLy8gU28gbG9uZyBsYWJlbHMgY2FuIGVzY2FwZSB0aGlzIGNvbXBvbmVudCBpbiBsYXlvdXQKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgeyBzdHlsZTogb3V0ZXJEaXZTdHlsZSB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ3N2ZycsCiAgICAgICAgICAgICAgICAgICAgeyB3aWR0aDogbWVhc3VyZWRXaWR0aCwgaGVpZ2h0OiBtZWFzdXJlZEhlaWdodCB9LAogICAgICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyU2VsZWN0aW9uSGlnaGxpZ2h0KCksCiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMubWFwKGZ1bmN0aW9uIChjb25uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczQucmVuZGVyQ29ubmVjdGlvbihjb25uKTsKICAgICAgICAgICAgICAgICAgICB9KSwKICAgICAgICAgICAgICAgICAgICBub2Rlcy5tYXAoZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzNC5yZW5kZXJOb2RlKG5vZGUpOwogICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgYmlnTGFiZWxzLm1hcChmdW5jdGlvbiAobGFiZWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXM0LnJlbmRlckJpZ0xhYmVsKGxhYmVsKTsKICAgICAgICAgICAgICAgIH0pLAogICAgICAgICAgICAgICAgc21hbGxMYWJlbHMubWFwKGZ1bmN0aW9uIChsYWJlbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczQucmVuZGVyU21hbGxMYWJlbChsYWJlbCk7CiAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gUGlwZWxpbmVHcmFwaDsKfShfcmVhY3QuQ29tcG9uZW50KTsKClBpcGVsaW5lR3JhcGgucHJvcFR5cGVzID0gewogICAgc3RhZ2VzOiBfcmVhY3QuUHJvcFR5cGVzLmFycmF5LAogICAgbGF5b3V0OiBfcmVhY3QuUHJvcFR5cGVzLm9iamVjdCwKICAgIG9uTm9kZUNsaWNrOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMKfTsKfSx7Ii4vVHJ1bmNhdGluZ0xhYmVsIjo4OSwiLi9zdGF0dXMvU3RhdHVzSW5kaWNhdG9yIjoxMTAsIi4vc3RhdHVzL1N2Z1NwaW5uZXIiOjExMSwicmVhY3QiOjYyM31dLDc4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlBvcG92ZXIgPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX0Zsb2F0aW5nRWxlbWVudCA9IHJlcXVpcmUoJy4vRmxvYXRpbmdFbGVtZW50Jyk7Cgp2YXIgX1Bvc2l0aW9uID0gcmVxdWlyZSgnLi9Qb3NpdGlvbicpOwoKdmFyIF8gPSByZXF1aXJlKCcuJyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9Cgp2YXIgUG9wb3ZlciA9IGV4cG9ydHMuUG9wb3ZlciA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgX2luaGVyaXRzKFBvcG92ZXIsIF9Db21wb25lbnQpOwoKICBmdW5jdGlvbiBQb3BvdmVyKCkgewogICAgdmFyIF9yZWY7CgogICAgdmFyIF90ZW1wLCBfdGhpcywgX3JldDsKCiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUG9wb3Zlcik7CgogICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHsKICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTsKICAgIH0KCiAgICByZXR1cm4gX3JldCA9IChfdGVtcCA9IChfdGhpcyA9IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChfcmVmID0gUG9wb3Zlci5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKFBvcG92ZXIpKS5jYWxsLmFwcGx5KF9yZWYsIFt0aGlzXS5jb25jYXQoYXJncykpKSwgX3RoaXMpLCBfdGhpcy5tb2RhbFNjcmVlbkNsaWNrZWQgPSBmdW5jdGlvbiAoKSB7CiAgICAgIHZhciBvbkRpc21pc3MgPSBfdGhpcy5wcm9wcy5vbkRpc21pc3M7CgoKICAgICAgaWYgKG9uRGlzbWlzcykgewogICAgICAgIG9uRGlzbWlzcygpOwogICAgICB9CiAgICB9LCBfdGhpcy5rZXlQcmVzc2VkID0gZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgIHZhciBfdGhpcyRwcm9wcyA9IF90aGlzLnByb3BzLAogICAgICAgICAgb25EaXNtaXNzID0gX3RoaXMkcHJvcHMub25EaXNtaXNzLAogICAgICAgICAgaWdub3JlRXNjYXBlS2V5ID0gX3RoaXMkcHJvcHMuaWdub3JlRXNjYXBlS2V5OwoKCiAgICAgIGlmICghaWdub3JlRXNjYXBlS2V5ICYmIG9uRGlzbWlzcyAmJiBldmVudC5rZXlDb2RlID09PSAyNykgewogICAgICAgIG9uRGlzbWlzcygpOwogICAgICB9CiAgICB9LCBfdGVtcCksIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKF90aGlzLCBfcmV0KTsKICB9CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyAgVXNlciBJbnRlcmFjdGlvbgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgX2NyZWF0ZUNsYXNzKFBvcG92ZXIsIFt7CiAgICBrZXk6ICdyZW5kZXInLAoKCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyAgUmVhY3QgTGlmZWN5Y2xlCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHMsCiAgICAgICAgICBjaGlsZHJlbiA9IF9wcm9wcy5jaGlsZHJlbiwKICAgICAgICAgIHN0eWxlID0gX3Byb3BzLnN0eWxlOwoKICAgICAgdmFyIHBvc2l0aW9uID0gKDAsIF9Qb3NpdGlvbi5zYW5pdGl6ZVBvc2l0aW9uKSh0aGlzLnByb3BzLnBvc2l0aW9uKTsKICAgICAgdmFyIHBvaW50Q2xhc3NOYW1lID0gJ1BvcG92ZXItcG9pbnQgUG9wb3Zlci1wb2ludC0tJyArIHBvc2l0aW9uOwogICAgICB2YXIgcG9zaXRpb25GdW5jdGlvbiA9IF9Qb3NpdGlvbi5Qb3NpdGlvbkZ1bmN0aW9uc1twb3NpdGlvbl07CgogICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgXy5Nb2RhbENvbnRhaW5lciwKICAgICAgICB7IG9uU2NyZWVuQ2xpY2s6IHRoaXMubW9kYWxTY3JlZW5DbGlja2VkIH0sCiAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICBfRmxvYXRpbmdFbGVtZW50LkZsb2F0aW5nRWxlbWVudCwKICAgICAgICAgIHsKICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogdGhpcy5wcm9wcy50YXJnZXRFbGVtZW50LAogICAgICAgICAgICBwb3NpdGlvbkZ1bmN0aW9uOiBwb3NpdGlvbkZ1bmN0aW9uCiAgICAgICAgICB9LAogICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICB7IGNsYXNzTmFtZTogJ1BvcG92ZXItd3JhcHBlcicsIHN0eWxlOiBzdHlsZSB9LAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAnc3ZnJywKICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogcG9pbnRDbGFzc05hbWUsIHZpZXdCb3g6ICcwIDAgMiAyJywgd2lkdGg6ICcyMCcsIGhlaWdodDogJzIwJyB9LAogICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTSAxIDAgTCAyIDEgTCAxIDIgTCAwIDEgTCAxIDAnIH0pCiAgICAgICAgICAgICksCiAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnUG9wb3Zlci1jb250ZW50JyB9LAogICAgICAgICAgICAgIGNoaWxkcmVuCiAgICAgICAgICAgICkKICAgICAgICAgICkKICAgICAgICApCiAgICAgICk7CiAgICB9CiAgfSwgewogICAga2V5OiAnY29tcG9uZW50RGlkTW91bnQnLAogICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkgewogICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJrZXl1cCIsIHRoaXMua2V5UHJlc3NlZCwgZmFsc2UpOwogICAgfQogIH0sIHsKICAgIGtleTogJ2NvbXBvbmVudFdpbGxVbm1vdW50JywKICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHsKICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigia2V5dXAiLCB0aGlzLmtleVByZXNzZWQsIGZhbHNlKTsKICAgIH0KICB9XSk7CgogIHJldHVybiBQb3BvdmVyOwp9KF9yZWFjdC5Db21wb25lbnQpOwoKUG9wb3Zlci5wcm9wVHlwZXMgPSB7CiAgdGFyZ2V0RWxlbWVudDogX3JlYWN0LlByb3BUeXBlcy5vYmplY3QsCiAgcG9zaXRpb246IF9yZWFjdC5Qcm9wVHlwZXMub25lT2YoX1Bvc2l0aW9uLnBvc2l0aW9ucyksCiAgb25EaXNtaXNzOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsCiAgaWdub3JlRXNjYXBlS2V5OiBfcmVhY3QuUHJvcFR5cGVzLmJvb2wsCiAgc3R5bGU6IF9yZWFjdC5Qcm9wVHlwZXMub2JqZWN0LAogIGNoaWxkcmVuOiBfcmVhY3QuUHJvcFR5cGVzLm5vZGUKfTsKfSx7Ii4iOjEwNywiLi9GbG9hdGluZ0VsZW1lbnQiOjc0LCIuL1Bvc2l0aW9uIjo3OSwicmVhY3QiOjYyM31dLDc5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuc2FuaXRpemVQb3NpdGlvbiA9IHNhbml0aXplUG9zaXRpb247CnZhciBwb3NpdGlvblZhbHVlcyA9IGV4cG9ydHMucG9zaXRpb25WYWx1ZXMgPSB7CiAgICBhYm92ZTogJ2Fib3ZlJywKICAgIGJlbG93OiAnYmVsb3cnLAogICAgbGVmdDogJ2xlZnQnLAogICAgcmlnaHQ6ICdyaWdodCcKfTsKCnZhciBwb3NpdGlvbnMgPSBleHBvcnRzLnBvc2l0aW9ucyA9IE9iamVjdC5rZXlzKHBvc2l0aW9uVmFsdWVzKTsKCmZ1bmN0aW9uIHNhbml0aXplUG9zaXRpb24oaW5wdXQpIHsKCiAgICBpZiAocG9zaXRpb25zLmluZGV4T2YoaW5wdXQpID09PSAtMSkgewogICAgICAgIHJldHVybiBwb3NpdGlvblZhbHVlcy5hYm92ZTsKICAgIH0KCiAgICByZXR1cm4gaW5wdXQ7Cn0KCmZ1bmN0aW9uIG1ha2VQb3NpdGlvbihwb3NpdGlvbikgewogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW4sIHVudXNlZC12YXIKICAgIHJldHVybiBmdW5jdGlvbiBzaW1wbGVQb3NpdGlvbkZ1bmN0aW9uKHNlbGZXaWR0aCwgc2VsZkhlaWdodCwgdGFyZ2V0V2lkdGgsIHRhcmdldEhlaWdodCwgdGFyZ2V0TGVmdCwgdGFyZ2V0VG9wLCB2aWV3cG9ydFdpZHRoLCB2aWV3cG9ydEhlaWdodCkgewogICAgICAgIHZhciBuZXdMZWZ0ID0gdm9pZCAwLAogICAgICAgICAgICBuZXdUb3AgPSB2b2lkIDA7CiAgICAgICAgdmFyIG1hcmdpbiA9IDU7IC8vIFBYCiAgICAgICAgdmFyIHByZWZlcnJlZCA9IHNhbml0aXplUG9zaXRpb24ocG9zaXRpb24gfHwgcG9zaXRpb25WYWx1ZXMuYWJvdmUpOwoKICAgICAgICAvLyBJbml0aWFsIGNhbGN1bGF0aW9ucwogICAgICAgIHN3aXRjaCAocHJlZmVycmVkKSB7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGNhc2UgcG9zaXRpb25WYWx1ZXMuYWJvdmU6CiAgICAgICAgICAgICAgICBuZXdMZWZ0ID0gdGFyZ2V0TGVmdCAtIE1hdGguZmxvb3IoKHNlbGZXaWR0aCAtIHRhcmdldFdpZHRoKSAvIDIpOwogICAgICAgICAgICAgICAgbmV3VG9wID0gdGFyZ2V0VG9wIC0gc2VsZkhlaWdodCAtIG1hcmdpbjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIHBvc2l0aW9uVmFsdWVzLmJlbG93OgogICAgICAgICAgICAgICAgbmV3TGVmdCA9IHRhcmdldExlZnQgLSBNYXRoLmZsb29yKChzZWxmV2lkdGggLSB0YXJnZXRXaWR0aCkgLyAyKTsKICAgICAgICAgICAgICAgIG5ld1RvcCA9IHRhcmdldFRvcCArIHRhcmdldEhlaWdodCArIG1hcmdpbjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIHBvc2l0aW9uVmFsdWVzLmxlZnQ6CiAgICAgICAgICAgICAgICBuZXdMZWZ0ID0gdGFyZ2V0TGVmdCAtIHNlbGZXaWR0aCAtIG1hcmdpbjsKICAgICAgICAgICAgICAgIG5ld1RvcCA9IHRhcmdldFRvcCAtIE1hdGguZmxvb3IoKHNlbGZIZWlnaHQgLSB0YXJnZXRIZWlnaHQpIC8gMik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBwb3NpdGlvblZhbHVlcy5yaWdodDoKICAgICAgICAgICAgICAgIG5ld0xlZnQgPSB0YXJnZXRMZWZ0ICsgdGFyZ2V0V2lkdGggKyBtYXJnaW47CiAgICAgICAgICAgICAgICBuZXdUb3AgPSB0YXJnZXRUb3AgLSBNYXRoLmZsb29yKChzZWxmSGVpZ2h0IC0gdGFyZ2V0SGVpZ2h0KSAvIDIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICAvLyBEbyBhIGJhc2ljIGFkanVzdG1lbnQgdG8gbWFrZSBzdXJlIGl0J3Mgd2l0aGluIHRoZSB2aWV3cG9ydCBpZiBwb3NzaWJsZQogICAgICAgIGlmIChuZXdMZWZ0IDwgbWFyZ2luKSB7CiAgICAgICAgICAgIG5ld0xlZnQgPSBtYXJnaW47CiAgICAgICAgfSBlbHNlIGlmIChuZXdMZWZ0ICsgc2VsZldpZHRoICsgbWFyZ2luID4gdmlld3BvcnRXaWR0aCkgewogICAgICAgICAgICBuZXdMZWZ0ID0gdmlld3BvcnRXaWR0aCAtIHNlbGZXaWR0aCAtIG1hcmdpbjsKICAgICAgICB9CgogICAgICAgIGlmIChuZXdUb3AgPCBtYXJnaW4pIHsKICAgICAgICAgICAgbmV3VG9wID0gbWFyZ2luOwogICAgICAgIH0gZWxzZSBpZiAobmV3VG9wICsgc2VsZkhlaWdodCArIG1hcmdpbiA+IHZpZXdwb3J0SGVpZ2h0KSB7CiAgICAgICAgICAgIG5ld1RvcCA9IHZpZXdwb3J0SGVpZ2h0IC0gc2VsZkhlaWdodCAtIG1hcmdpbjsKICAgICAgICB9CgogICAgICAgIC8vIFdpc2hsaXN0OiBUcnkgb3RoZXIgcHJlZmVycmVkIHBvc2l0aW9ucyByYXRoZXIgdGhhbiBqdXN0IHNoaWZ0aW5nCiAgICAgICAgLy8gaW50byB2aWV3cG9ydD8KCiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgbmV3TGVmdDogbmV3TGVmdCwKICAgICAgICAgICAgbmV3VG9wOiBuZXdUb3AKICAgICAgICB9OwogICAgfTsKfQoKdmFyIFBvc2l0aW9uRnVuY3Rpb25zID0gZXhwb3J0cy5Qb3NpdGlvbkZ1bmN0aW9ucyA9IHsKICAgIGFib3ZlOiBtYWtlUG9zaXRpb24ocG9zaXRpb25WYWx1ZXMuYWJvdmUpLAogICAgYmVsb3c6IG1ha2VQb3NpdGlvbihwb3NpdGlvblZhbHVlcy5iZWxvdyksCiAgICBsZWZ0OiBtYWtlUG9zaXRpb24ocG9zaXRpb25WYWx1ZXMubGVmdCksCiAgICByaWdodDogbWFrZVBvc2l0aW9uKHBvc2l0aW9uVmFsdWVzLnJpZ2h0KQp9Owp9LHt9XSw4MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlByb2dyZXNzID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKdmFyIFByb2dyZXNzID0gZXhwb3J0cy5Qcm9ncmVzcyA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoUHJvZ3Jlc3MsIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIFByb2dyZXNzKCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQcm9ncmVzcyk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoUHJvZ3Jlc3MuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihQcm9ncmVzcykpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhQcm9ncmVzcywgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBwZXJjZW50YWdlID0gdGhpcy5wcm9wcy5wZXJjZW50YWdlOwogICAgICAgICAgICB2YXIgZ3JvdXBDbGFzc2VzID0gWydwcm9ncmVzcy1jb250YWluZXInXTsKCiAgICAgICAgICAgIGlmICh0eXBlb2YgcGVyY2VudGFnZSAhPT0gJ251bWJlcicgfHwgaXNOYU4ocGVyY2VudGFnZSkgfHwgcGVyY2VudGFnZSA8IDApIHsKICAgICAgICAgICAgICAgIGdyb3VwQ2xhc3Nlcy5wdXNoKCdpbmRldGVybWluYXRlJyk7CiAgICAgICAgICAgICAgICBwZXJjZW50YWdlID0gMTIuNTsKICAgICAgICAgICAgfSBlbHNlIGlmIChwZXJjZW50YWdlID4gMTAwKSB7CiAgICAgICAgICAgICAgICBncm91cENsYXNzZXMucHVzaCgnYm91bmNlJyk7CiAgICAgICAgICAgICAgICBwZXJjZW50YWdlID0gMTA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICdzdmcnLAogICAgICAgICAgICAgICAgICAgIHsgeG1sbnM6ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsCiAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlcnZlQXNwZWN0UmF0aW86ICdub25lJywKICAgICAgICAgICAgICAgICAgICAgICAgdmlld0JveDogJzAgMCAxMDAgMTAnLAogICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGdyb3VwQ2xhc3Nlcy5qb2luKCcgJykKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdsaW5lJywgeyB4MTogJzAnLCB5MTogJzUnLCB4MjogJzEwMCcsIHkyOiAnNScsIGNsYXNzTmFtZTogJ3Byb2dyZXNzLWJnJyB9KSwKICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgnbGluZScsIHsgeDE6ICcwJywgeTE6ICc1JywgeDI6IHBlcmNlbnRhZ2UsIHkyOiAnNScsIGNsYXNzTmFtZTogJ3Byb2dyZXNzLWJhcicgfSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFByb2dyZXNzOwp9KF9yZWFjdC5Db21wb25lbnQpOwoKUHJvZ3Jlc3MucHJvcFR5cGVzID0gewogICAgcGVyY2VudGFnZTogX3JlYWN0LlByb3BUeXBlcy5udW1iZXIKfTsKfSx7InJlYWN0Ijo2MjN9XSw4MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlJlYWRhYmxlRGF0ZSA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50Jyk7Cgp2YXIgX21vbWVudDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9tb21lbnQpOwoKcmVxdWlyZSgnbW9tZW50L21pbi9sb2NhbGVzLm1pbicpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQovLyBuZWVkcyB0byBiZSBsb2FkZWQgc2luY2UgdGhlIG1vbWVudCBsaWIgd2lsbCB1c2UgcmVxdWlyZSB3aGljaCBpbiBydW4gdGltZSB3aWxsIGZhaWwKCgovKioKICogRGlzcGxheXMgYSBkYXRlIGluIG1vbWVudCdzICJmcm9tTm93IiBmb3JtYXQsIGUuZy4gIjIgaG91cnMgYWdvIiwgIjUgZGF5cyBhZ28iIGV0YwogKiBBbHNvIGRpc3BsYXlzIHRoZSBvcmlnaW5hbCBkYXRlIG9uIGhvdmVyLgogKiBFeHBlY3RzICJkYXRlIiB0byBiZSBwYXNzZWQgaW4gYXMgSVNPLTg2MDEgc3RyaW5nIHdpdGggdGltZSB6b25lIGluZm8uCiAqIElmIHRpbWUgem9uZSBpcyBvbWl0dGVkLCB0aGVuIFVUQyBpcyBhc3N1bWVkLgogKi8KdmFyIFJlYWRhYmxlRGF0ZSA9IGV4cG9ydHMuUmVhZGFibGVEYXRlID0gZnVuY3Rpb24gKF9Db21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhSZWFkYWJsZURhdGUsIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIFJlYWRhYmxlRGF0ZShwcm9wcykgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBSZWFkYWJsZURhdGUpOwoKICAgICAgICAvLyBXaGVuIHVwZGF0aW5nLCBhdmVyYWdlIDFzIHBlcmlvZCwgd2l0aCBqaXR0ZXIgdG8gc3ByZWFkIG91dCB0aGUgd29yawogICAgICAgIHZhciBfdGhpcyA9IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChSZWFkYWJsZURhdGUuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihSZWFkYWJsZURhdGUpKS5jYWxsKHRoaXMsIHByb3BzKSk7CgogICAgICAgIF90aGlzLnRpbWVyUGVyaW9kTWlsbGlzID0gNzUwICsgTWF0aC5jZWlsKE1hdGgucmFuZG9tKCkgKiA1MDApOwogICAgICAgIF90aGlzLnRpbWVyID0gMDsKICAgICAgICBfdGhpcy5zdGF0ZSA9IHsgZGF0ZTogbnVsbCB9OwogICAgICAgIHJldHVybiBfdGhpczsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoUmVhZGFibGVEYXRlLCBbewogICAgICAgIGtleTogJ2NvbXBvbmVudFdpbGxNb3VudCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxNb3VudCgpIHsKICAgICAgICAgICAgdGhpcy5oYW5kbGVQcm9wcyh0aGlzLnByb3BzKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7CiAgICAgICAgICAgIHRoaXMuaGFuZGxlUHJvcHMobmV4dFByb3BzKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnaGFuZGxlUHJvcHMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBoYW5kbGVQcm9wcyhwcm9wcykgewogICAgICAgICAgICB2YXIgX3RoaXMyID0gdGhpczsKCiAgICAgICAgICAgIHZhciBfcHJvcHMkbG9jYWxlID0gcHJvcHMubG9jYWxlLAogICAgICAgICAgICAgICAgbG9jYWxlID0gX3Byb3BzJGxvY2FsZSA9PT0gdW5kZWZpbmVkID8gJ2VuJyA6IF9wcm9wcyRsb2NhbGU7CgoKICAgICAgICAgICAgaWYgKHRoaXMudGltZXIpIHsKICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy50aW1lcik7CiAgICAgICAgICAgICAgICB0aGlzLnRpbWVyID0gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGRhdGUgPSBudWxsOwoKICAgICAgICAgICAgaWYgKHByb3BzLmRhdGUpIHsKICAgICAgICAgICAgICAgIF9tb21lbnQyLmRlZmF1bHQubG9jYWxlKGxvY2FsZSk7CiAgICAgICAgICAgICAgICAvLyBlbmZvcmNlIGEgSVNPLTg2MDEgZGF0ZSBhbmQgdHJ5IHRvIHNldCBwcm9wZXIgdGltZXpvbmUKICAgICAgICAgICAgICAgIHZhciBhTW9tZW50ID0gKDAsIF9tb21lbnQyLmRlZmF1bHQpKHByb3BzLmRhdGUsIF9tb21lbnQyLmRlZmF1bHQuSVNPXzg2MDEpLnV0Y09mZnNldChwcm9wcy5kYXRlKTsKCiAgICAgICAgICAgICAgICBpZiAoYU1vbWVudC5pc1ZhbGlkKCkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBhIG1vbWVudCBoYXMgbm8gbmFtZS4KICAgICAgICAgICAgICAgICAgICBkYXRlID0gYU1vbWVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGRhdGUgJiYgcHJvcHMubGl2ZVVwZGF0ZSkgewogICAgICAgICAgICAgICAgdGhpcy50aW1lciA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICBfdGhpczIuZm9yY2VVcGRhdGUoKTsKICAgICAgICAgICAgICAgIH0sIHRoaXMudGltZXJQZXJpb2RNaWxsaXMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZGF0ZTogZGF0ZSB9KTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY29tcG9uZW50V2lsbFVubW91bnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHsKICAgICAgICAgICAgaWYgKHRoaXMudGltZXIpIHsKICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy50aW1lcik7CiAgICAgICAgICAgICAgICB0aGlzLnRpbWVyID0gMDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBkYXRlID0gdGhpcy5zdGF0ZS5kYXRlOwogICAgICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcywKICAgICAgICAgICAgICAgIF9wcm9wcyRzaG9ydEZvcm1hdCA9IF9wcm9wcy5zaG9ydEZvcm1hdCwKICAgICAgICAgICAgICAgIHNob3J0Rm9ybWF0ID0gX3Byb3BzJHNob3J0Rm9ybWF0ID09PSB1bmRlZmluZWQgPyAnTU1NIEREIGg6bW1hIFonIDogX3Byb3BzJHNob3J0Rm9ybWF0LAogICAgICAgICAgICAgICAgX3Byb3BzJGxvbmdGb3JtYXQgPSBfcHJvcHMubG9uZ0Zvcm1hdCwKICAgICAgICAgICAgICAgIGxvbmdGb3JtYXQgPSBfcHJvcHMkbG9uZ0Zvcm1hdCA9PT0gdW5kZWZpbmVkID8gJ01NTSBERCBZWVlZIGg6bW1hIFonIDogX3Byb3BzJGxvbmdGb3JtYXQ7CgoKICAgICAgICAgICAgaWYgKGRhdGUpIHsKICAgICAgICAgICAgICAgIHZhciBub3cgPSAoMCwgX21vbWVudDIuZGVmYXVsdCkoKS51dGMoKTsKCiAgICAgICAgICAgICAgICAvLyBvbmx5IHNob3cgdGhlIHllYXIgaWYgZnJvbSBkaWZmZXJlbnQgeWVhcgogICAgICAgICAgICAgICAgdmFyIHRvb2x0aXAgPSBkYXRlLnllYXIoKSAhPT0gbm93LnllYXIoKSA/IGRhdGUuZm9ybWF0KGxvbmdGb3JtYXQpIDogZGF0ZS5mb3JtYXQoc2hvcnRGb3JtYXQpOwoKICAgICAgICAgICAgICAgIHRvb2x0aXAgPSB0b29sdGlwLnJlcGxhY2UoJyswMDowMCcsICdVVEMnKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ3RpbWUnLAogICAgICAgICAgICAgICAgICAgIHsgZGF0ZVRpbWU6IHRoaXMucHJvcHMuZGF0ZSwgdGl0bGU6IHRvb2x0aXAgfSwKICAgICAgICAgICAgICAgICAgICBkYXRlLmZyb21Ob3coKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ3NwYW4nLAogICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgICctJwogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gUmVhZGFibGVEYXRlOwp9KF9yZWFjdC5Db21wb25lbnQpOwoKUmVhZGFibGVEYXRlLnByb3BUeXBlcyA9IHsKICAgIGRhdGU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgbGl2ZVVwZGF0ZTogX3JlYWN0LlByb3BUeXBlcy5ib29sLAogICAgbG9uZ0Zvcm1hdDogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBzaG9ydEZvcm1hdDogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcKfTsKfSx7Im1vbWVudCI6MzkyLCJtb21lbnQvbWluL2xvY2FsZXMubWluIjozOTEsInJlYWN0Ijo2MjN9XSw4MjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlJlc3VsdEl0ZW0gPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX3JlYWN0QWRkb25zQ3NzVHJhbnNpdGlvbkdyb3VwID0gcmVxdWlyZSgncmVhY3QtYWRkb25zLWNzcy10cmFuc2l0aW9uLWdyb3VwJyk7Cgp2YXIgX3JlYWN0QWRkb25zQ3NzVHJhbnNpdGlvbkdyb3VwMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0QWRkb25zQ3NzVHJhbnNpdGlvbkdyb3VwKTsKCnZhciBfU3RhdHVzSW5kaWNhdG9yID0gcmVxdWlyZSgnLi9zdGF0dXMvU3RhdHVzSW5kaWNhdG9yJyk7Cgp2YXIgX1N2Z1N0YXR1cyA9IHJlcXVpcmUoJy4vc3RhdHVzL1N2Z1N0YXR1cycpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKdmFyIFJlc3VsdEl0ZW0gPSBleHBvcnRzLlJlc3VsdEl0ZW0gPSBmdW5jdGlvbiAoX0NvbXBvbmVudCkgewogICAgX2luaGVyaXRzKFJlc3VsdEl0ZW0sIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIFJlc3VsdEl0ZW0ocHJvcHMpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUmVzdWx0SXRlbSk7CgogICAgICAgIHZhciBfdGhpcyA9IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChSZXN1bHRJdGVtLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoUmVzdWx0SXRlbSkpLmNhbGwodGhpcywgcHJvcHMpKTsKCiAgICAgICAgX3RoaXMudG9nZ2xlRXhwYW5kZWQgPSBmdW5jdGlvbiAoZSkgewogICAgICAgICAgICBpZiAoX3RoaXMucHJvcHMuY2hpbGRyZW4pIHsKICAgICAgICAgICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGV4cGFuZGVkID0gIV90aGlzLnN0YXRlLmV4cGFuZGVkOwoKICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IGV4cGFuZGVkOiBleHBhbmRlZCB9LCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBfdGhpcyRwcm9wcyA9IF90aGlzLnByb3BzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IF90aGlzJHByb3BzLmRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkV4cGFuZCA9IF90aGlzJHByb3BzLm9uRXhwYW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb25Db2xsYXBzZSA9IF90aGlzJHByb3BzLm9uQ29sbGFwc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIERhdGEgaXMgYXJiaXRyYXJ5LCBzZXQgYnkgcGFyZW50CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAob25FeHBhbmQgJiYgZXhwYW5kZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uRXhwYW5kKGRhdGEsIGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAob25Db2xsYXBzZSAmJiAhZXhwYW5kZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ29sbGFwc2UoZGF0YSwgZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0pKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBfdGhpcy5zdGF0ZSA9IHsKICAgICAgICAgICAgcmVzdWx0Q2xlYW46IF9TdGF0dXNJbmRpY2F0b3IuU3RhdHVzSW5kaWNhdG9yLnZhbGlkUmVzdWx0VmFsdWVzLnVua25vd24sCiAgICAgICAgICAgIHN0YXR1c0dseXBoOiBudWxsLAogICAgICAgICAgICBleHBhbmRlZDogcHJvcHMuZXhwYW5kZWQgfHwgZmFsc2UKICAgICAgICB9OwogICAgICAgIHJldHVybiBfdGhpczsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoUmVzdWx0SXRlbSwgW3sKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsTW91bnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsTW91bnQoKSB7CiAgICAgICAgICAgIHRoaXMuaGFuZGxlUHJvcHModGhpcy5wcm9wcyk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykgewogICAgICAgICAgICB0aGlzLmhhbmRsZVByb3BzKG5leHRQcm9wcyk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2hhbmRsZVByb3BzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gaGFuZGxlUHJvcHMocHJvcHMpIHsKICAgICAgICAgICAgdmFyIHJlc3VsdENsZWFuID0gKDAsIF9TdGF0dXNJbmRpY2F0b3IuZGVjb2RlUmVzdWx0VmFsdWUpKHByb3BzLnJlc3VsdCk7CiAgICAgICAgICAgIGlmIChyZXN1bHRDbGVhbiAhPT0gdGhpcy5zdGF0ZS5yZXN1bHRDbGVhbikgewogICAgICAgICAgICAgICAgdmFyIF9zdGF0dXNHbHlwaCA9ICgwLCBfU3ZnU3RhdHVzLmdldEdseXBoRm9yKShyZXN1bHRDbGVhbik7CiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgcmVzdWx0Q2xlYW46IHJlc3VsdENsZWFuLCBzdGF0dXNHbHlwaDogX3N0YXR1c0dseXBoIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgd2Ugd2FudCB0byBjaGFuZ2UgdGhlIHN0YXRlIG9yIHdoZXRoZXIgd2UgYWxyZWFkeSBhcmUgaW4gdGhlIGNvcnJlY3Qgc3RhdGUKICAgICAgICAgICAgaWYgKHByb3BzLmV4cGFuZGVkICE9PSB0aGlzLnN0YXRlLmV4cGFuZGVkKSB7CiAgICAgICAgICAgICAgICB0aGlzLnRvZ2dsZUV4cGFuZGVkKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcywKICAgICAgICAgICAgICAgIGxhYmVsID0gX3Byb3BzLmxhYmVsLAogICAgICAgICAgICAgICAgZXh0cmFJbmZvID0gX3Byb3BzLmV4dHJhSW5mbzsKICAgICAgICAgICAgdmFyIF9zdGF0ZSA9IHRoaXMuc3RhdGUsCiAgICAgICAgICAgICAgICByZXN1bHRDbGVhbiA9IF9zdGF0ZS5yZXN1bHRDbGVhbiwKICAgICAgICAgICAgICAgIHN0YXR1c0dseXBoID0gX3N0YXRlLnN0YXR1c0dseXBoOwoKCiAgICAgICAgICAgIHZhciBoYXNDaGlsZHJlbiA9ICEhdGhpcy5wcm9wcy5jaGlsZHJlbjsKICAgICAgICAgICAgdmFyIGV4cGFuZGVkID0gdGhpcy5zdGF0ZS5leHBhbmRlZCAmJiBoYXNDaGlsZHJlbjsKCiAgICAgICAgICAgIHZhciBjbGFzc2VzID0gWydyZXN1bHQtaXRlbScsIHJlc3VsdENsZWFuXTsKCiAgICAgICAgICAgIGlmIChleHBhbmRlZCkgewogICAgICAgICAgICAgICAgY2xhc3Nlcy5wdXNoKCdleHBhbmRlZCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgb3V0ZXJDbGFzc05hbWUgPSBjbGFzc2VzLmpvaW4oJyAnKTsKICAgICAgICAgICAgdmFyIGljb25DbGFzc05hbWUgPSAncmVzdWx0LWl0ZW0taWNvbiByZXN1bHQtYmcgJyArIHJlc3VsdENsZWFuOwoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogb3V0ZXJDbGFzc05hbWUgfSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAncmVzdWx0LWl0ZW0taGVhZCcsIG9uQ2xpY2s6IHRoaXMudG9nZ2xlRXhwYW5kZWQgfSwKICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLAogICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogaWNvbkNsYXNzTmFtZSB9LAogICAgICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdmcnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgeyB3aWR0aDogJzI4JywgaGVpZ2h0OiAnMzQnIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUoMTQgMTgpJywgY2xhc3NOYW1lOiAncmVzdWx0LXN0YXR1cy1nbHlwaCcgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNHbHlwaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLAogICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3Jlc3VsdC1pdGVtLXRpdGxlJyB9LAogICAgICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChFeHBhbmRvLCB7IGV4cGFuZGVkOiBleHBhbmRlZCwgZGlzYWJsZWQ6ICFoYXNDaGlsZHJlbiB9KSwKICAgICAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3BhbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3Jlc3VsdC1pdGVtLWxhYmVsJyB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwKICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3BhbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3Jlc3VsdC1pdGVtLWV4dHJhLWluZm8nIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYUluZm8KICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICBfcmVhY3RBZGRvbnNDc3NUcmFuc2l0aW9uR3JvdXAyLmRlZmF1bHQsCiAgICAgICAgICAgICAgICAgICAgeyB0cmFuc2l0aW9uTmFtZTogJ3NsaWRlLWRvd24nLAogICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2l0aW9uQXBwZWFyOiB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2l0aW9uQXBwZWFyVGltZW91dDogMzAwLAogICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2l0aW9uRW50ZXJUaW1lb3V0OiAzMDAsCiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zaXRpb25MZWF2ZVRpbWVvdXQ6IDMwMCB9LAogICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkID8gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3Jlc3VsdC1pdGVtLWNoaWxkcmVuJywga2V5OiAnaycgfSwKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5jaGlsZHJlbgogICAgICAgICAgICAgICAgICAgICkgOiBudWxsCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBSZXN1bHRJdGVtOwp9KF9yZWFjdC5Db21wb25lbnQpOwoKUmVzdWx0SXRlbS5wcm9wVHlwZXMgPSB7CiAgICByZXN1bHQ6IF9yZWFjdC5Qcm9wVHlwZXMub25lT2YoT2JqZWN0LmtleXMoX1N0YXR1c0luZGljYXRvci5TdGF0dXNJbmRpY2F0b3IudmFsaWRSZXN1bHRWYWx1ZXMpKSwKICAgIGxhYmVsOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIGV4dHJhSW5mbzogX3JlYWN0LlByb3BUeXBlcy5vbmVPZlR5cGUoW19yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLCBfcmVhY3QuUHJvcFR5cGVzLm9iamVjdF0pLAogICAgZGF0YTogX3JlYWN0LlByb3BUeXBlcy5hbnksIC8vIFdoYXRldmVyIHlvdSB3YW50LCB3aWxsIGJlIHNlbnQgYmFjayB0byBsaXN0ZW5lcnMKICAgIG9uRXhwYW5kOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsIC8vIGYoZGF0YToqLCBvcmlnaW5hbEV2ZW50Oj9ldmVudCkKICAgIG9uQ29sbGFwc2U6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYywgLy8gZihkYXRhOiosIG9yaWdpbmFsRXZlbnQ6P2V2ZW50KQogICAgY2hpbGRyZW46IF9yZWFjdC5Qcm9wVHlwZXMubm9kZQp9OwoKLy8gV2UgY2FuIGV4dHJhY3QgdGhpcyBpbnRvIGFuIGV4cG9ydGVkIGNvbXBvbmVudCBpZiB3ZSBuZWVkIGl0IGVsc2V3aGVyZQoKdmFyIEV4cGFuZG8gPSBmdW5jdGlvbiAoX0NvbXBvbmVudDIpIHsKICAgIF9pbmhlcml0cyhFeHBhbmRvLCBfQ29tcG9uZW50Mik7CgogICAgZnVuY3Rpb24gRXhwYW5kbygpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRXhwYW5kbyk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoRXhwYW5kby5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKEV4cGFuZG8pKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoRXhwYW5kbywgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CgogICAgICAgICAgICB2YXIgY2xhc3NlcyA9IFsncmVzdWx0LWl0ZW0tZXhwYW5kbyddOwoKICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuZXhwYW5kZWQpIHsKICAgICAgICAgICAgICAgIGNsYXNzZXMucHVzaCgnZXhwYW5kZWQnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuZGlzYWJsZWQpIHsKICAgICAgICAgICAgICAgIGNsYXNzZXMucHVzaCgnZGlzYWJsZWQnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIG91dGVyQ2xhc3NOYW1lID0gY2xhc3Nlcy5qb2luKCcgJyk7CiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdzdmcnLAogICAgICAgICAgICAgICAgeyB3aWR0aDogJzI4JywgaGVpZ2h0OiAnMjQnLCBjbGFzc05hbWU6IG91dGVyQ2xhc3NOYW1lIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAnZycsCiAgICAgICAgICAgICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUoMTQgMTIpJyB9LAogICAgICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICAgICAnZycsCiAgICAgICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnZXhwYW5kby1nbHlwaCcgfSwKICAgICAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BvbHlnb24nLCB7IHBvaW50czogJy0xLjcsLTUgMy4zLDAgLTEuNyw1IC0yLjksMy44IDEsMCAtMi45LC0zLjgnIH0pCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gRXhwYW5kbzsKfShfcmVhY3QuQ29tcG9uZW50KTsKCkV4cGFuZG8ucHJvcFR5cGVzID0gewogICAgZXhwYW5kZWQ6IF9yZWFjdC5Qcm9wVHlwZXMuYm9vbCwKICAgIGRpc2FibGVkOiBfcmVhY3QuUHJvcFR5cGVzLmJvb2wKfTsKfSx7Ii4vc3RhdHVzL1N0YXR1c0luZGljYXRvciI6MTEwLCIuL3N0YXR1cy9TdmdTdGF0dXMiOjExMiwicmVhY3QiOjYyMywicmVhY3QtYWRkb25zLWNzcy10cmFuc2l0aW9uLWdyb3VwIjo0Mjl9XSw4MzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLnBvbGFyVG9DYXJ0ZXNpYW4gPSBwb2xhclRvQ2FydGVzaWFuOwpleHBvcnRzLmRlc2NyaWJlQXJjQXNQYXRoID0gZGVzY3JpYmVBcmNBc1BhdGg7CgoKLy8KLy8gQ29tbW9uIEhlbHBlciBmdW5jdGlvbnMgZm9yIGJ1aWxkaW5nIFNWR3MuIENvdWxkIGluY2x1ZGUgc2ltcGxlIG1hdGggZnVuY3MgYXMgd2VsbCBhcyBoaWdoZXItb3JkZXIgY29tcG9uZW50cy4KLy8KCmZ1bmN0aW9uIHBvbGFyVG9DYXJ0ZXNpYW4oY2VudGVyWCwgY2VudGVyWSwgcmFkaXVzLCBhbmdsZUluRGVncmVlcykgewoKICAgIHZhciBhbmdsZUluUmFkaWFucyA9IChhbmdsZUluRGVncmVlcyAtIDkwKSAqIE1hdGguUEkgLyAxODAuMDsKCiAgICByZXR1cm4gewogICAgICAgIHg6IGNlbnRlclggKyByYWRpdXMgKiBNYXRoLmNvcyhhbmdsZUluUmFkaWFucyksCiAgICAgICAgeTogY2VudGVyWSArIHJhZGl1cyAqIE1hdGguc2luKGFuZ2xlSW5SYWRpYW5zKQogICAgfTsKfQoKZnVuY3Rpb24gZGVzY3JpYmVBcmNBc1BhdGgoeCwgeSwgcmFkaXVzLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSkgewogICAgdmFyIHN0YXJ0ID0gcG9sYXJUb0NhcnRlc2lhbih4LCB5LCByYWRpdXMsIGVuZEFuZ2xlKTsKICAgIHZhciBlbmQgPSBwb2xhclRvQ2FydGVzaWFuKHgsIHksIHJhZGl1cywgc3RhcnRBbmdsZSk7CgogICAgdmFyIGFyY1N3ZWVwID0gZW5kQW5nbGUgLSBzdGFydEFuZ2xlIDw9IDE4MCA/ICcwJyA6ICcxJzsKCiAgICB2YXIgZCA9IFsnTScsIHN0YXJ0LngsIHN0YXJ0LnksICdBJywgcmFkaXVzLCByYWRpdXMsIDAsIGFyY1N3ZWVwLCAwLCBlbmQueCwgZW5kLnldLmpvaW4oJyAnKTsKCiAgICByZXR1cm4gZDsKfQoKLy8gQWxzbyBleHBvcnQgYW4gT0JKIG9mIGNsYXNzZXMgKyBmdW5zLCBsaWtlIE1hdGgKdmFyIFNWRyA9IHsKICAgIHBvbGFyVG9DYXJ0ZXNpYW46IHBvbGFyVG9DYXJ0ZXNpYW4sCiAgICBkZXNjcmliZUFyY0FzUGF0aDogZGVzY3JpYmVBcmNBc1BhdGgKfTsKCmV4cG9ydHMuZGVmYXVsdCA9IFNWRzsKfSx7fV0sODQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5UYWJMaW5rID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9yZWFjdFJvdXRlciA9IHJlcXVpcmUoJ3JlYWN0LXJvdXRlcicpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKdmFyIFRhYkxpbmsgPSBleHBvcnRzLlRhYkxpbmsgPSBmdW5jdGlvbiAoX0NvbXBvbmVudCkgewogICAgX2luaGVyaXRzKFRhYkxpbmssIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIFRhYkxpbmsoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFRhYkxpbmspOwoKICAgICAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKFRhYkxpbmsuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihUYWJMaW5rKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFRhYkxpbmssIFt7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX2NvbnRleHQgPSB0aGlzLmNvbnRleHQsCiAgICAgICAgICAgICAgICBfY29udGV4dCRyb3V0ZXIgPSBfY29udGV4dC5yb3V0ZXIsCiAgICAgICAgICAgICAgICByb3V0ZXIgPSBfY29udGV4dCRyb3V0ZXIgPT09IHVuZGVmaW5lZCA/IHt9IDogX2NvbnRleHQkcm91dGVyLAogICAgICAgICAgICAgICAgX2NvbnRleHQkbG9jYXRpb24gPSBfY29udGV4dC5sb2NhdGlvbiwKICAgICAgICAgICAgICAgIGxvY2F0aW9uID0gX2NvbnRleHQkbG9jYXRpb24gPT09IHVuZGVmaW5lZCA/IHt9IDogX2NvbnRleHQkbG9jYXRpb247CiAgICAgICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzLAogICAgICAgICAgICAgICAgX3Byb3BzJGJhc2UgPSBfcHJvcHMuYmFzZSwKICAgICAgICAgICAgICAgIGJhc2UgPSBfcHJvcHMkYmFzZSA9PT0gdW5kZWZpbmVkID8gJycgOiBfcHJvcHMkYmFzZSwKICAgICAgICAgICAgICAgIF9wcm9wcyR0byA9IF9wcm9wcy50bywKICAgICAgICAgICAgICAgIHRvT3JnID0gX3Byb3BzJHRvID09PSB1bmRlZmluZWQgPyAnJyA6IF9wcm9wcyR0bzsKCiAgICAgICAgICAgIHZhciB0byA9IHRvT3JnLnN1YnN0cmluZygxKTsKICAgICAgICAgICAgdmFyIHJvdXRlVXJsID0gYmFzZSArICcvJyArIHRvOwogICAgICAgICAgICB2YXIgbGlua0NsYXNzTmFtZSA9IHJvdXRlci5pc0FjdGl2ZShyb3V0ZVVybCkgPyAic2VsZWN0ZWQgIiArIHRvIDogdG87CiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgIF9yZWFjdFJvdXRlci5MaW5rLAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRvOiByb3V0ZVVybCwKICAgICAgICAgICAgICAgICAgICBxdWVyeTogbG9jYXRpb24ucXVlcnksCiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBsaW5rQ2xhc3NOYW1lCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5jaGlsZHJlbgogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gVGFiTGluazsKfShfcmVhY3QuQ29tcG9uZW50KTsKClRhYkxpbmsucHJvcFR5cGVzID0gewogICAgY2hpbGRyZW46IF9yZWFjdC5Qcm9wVHlwZXMubm9kZSwKICAgIGJhc2U6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgdG86IF9yZWFjdC5Qcm9wVHlwZXMub25lT2ZUeXBlKFtfcmVhY3QuUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLCBfcmVhY3QuUHJvcFR5cGVzLnNoYXBlLmlzUmVxdWlyZWRdKQp9OwoKVGFiTGluay5jb250ZXh0VHlwZXMgPSB7CiAgICByb3V0ZXI6IF9yZWFjdC5Qcm9wVHlwZXMub2JqZWN0LAogICAgbG9jYXRpb246IF9yZWFjdC5Qcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQgfTsKfSx7InJlYWN0Ijo2MjMsInJlYWN0LXJvdXRlciI6NDY4fV0sODU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5UYWJsZURpdmlkZXIgPSBleHBvcnRzLlRhYmxlID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKZnVuY3Rpb24gZ2V0S2V5KGNvbHVtbikgewogICAgaWYgKHR5cGVvZiBjb2x1bW4gPT09ICdzdHJpbmcnKSB7CiAgICAgICAgcmV0dXJuIGNvbHVtbjsKICAgIH0KICAgIHJldHVybiBjb2x1bW4ubGFiZWw7Cn0KCmZ1bmN0aW9uIGdldExhYmVsKGNvbHVtbikgewogICAgaWYgKHR5cGVvZiBjb2x1bW4gPT09ICdzdHJpbmcnKSB7CiAgICAgICAgcmV0dXJuIGNvbHVtbjsKICAgIH0KICAgIHJldHVybiBjb2x1bW4ubGFiZWw7Cn0KCmZ1bmN0aW9uIGdldENsYXNzKGNvbHVtbikgewogICAgaWYgKHR5cGVvZiBjb2x1bW4gPT09ICdzdHJpbmcnKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICByZXR1cm4gY29sdW1uLmNsYXNzTmFtZTsKfQoKLyoqCiAqIFJlbmRlcnMgYSBzaW1wbGUgSFRNTCB0YWJsZSB3aXRoIG9wdGlvbmFsIGhlYWRlciBlbGVtZW50cy4KICoKICogUHJvcGVydGllczoKICoKICogImNoaWxkcmVuIjogb25lIG9yIG1vcmUgVFIgZWxlbWVudHMKICoKICogImhlYWRlcnMiOiBhbiBhcnJheSBvZiBTdHJpbmdzIHRvIHJlbmRlciwgb3IKICogICAgICAgICAgICBhbiBhcnJheSBvZiBPYmplY3RzIHdpdGggc2hhcGU6IHsgbGFiZWw6U3RyaW5nLCBjbGFzc05hbWU6U3RyaW5nIH0KICoKICogImRpc2FibGVIZWFkZXJEaXZpZGVyIjogT3B0aW9uYWwsIHRydXRoeSBpZiB5b3Ugd2lzaCB0byBkaXNhYmxlIHRoZSBIUiByb3cgYXQgdGhlIGJvdHRvbSBvZiBUSEVBRC4KICoKICogImRpc2FibGVEZWZhdWx0UGFkZGluZyI6IE9wdGlvbmFsLCB0cnV0aHkgaWYgeW91IHdpc2ggdG8gZGlzYWJsZSBkZWZhdWx0IHBhZGRpbmcgYWRkZWQgYnkgcmVtb3ZpbmcgInUtdGFibGUtcGFkZGluZyIKICogY2xhc3NOYW1lIGZyb20gdGhlIFRBQkxFIGVsZW1lbnQuCiAqCiAqICJkaXNhYmxlTm9XcmFwIjogT3B0aW9uYWwsIHRydXRoeSBpZiB5b3Ugd2lzaCB0byBkaXNhYmxlIHRoZSAidS1zaW5nbGUtbGluZSIgY2xhc3NOYW1lLCBhbmQgYWxsb3cgY2VsbCBjb250ZW50cyB0bwogKiB3cmFwLgogKgogKiAiZGlzYWJsZUZpeGVkIjogT3B0aW9uYWwsIHRydXRoeSBpZiB5b3Ugd2lzaCB0byBkaXNhYmxlIHRoZSAidS1maXhlZCIgY2xhc3NOYW1lLCBhbmQgdXNlIGRlZmF1bHQgYnJvd3NlciBmbHVpZCBsYXlvdXQuCiAqCiAqIFNwZWNpZnkgYWRkaXRpb25hbCBjbGFzc05hbWU9InUtaGlnaGxpZ2h0LXJvd3MiIGZvciB3aG9sZS1yb3cgbW91c2VvdmVyIGhvdmVyLgogKgogKiBIZWFkIC8gYm9keSBkaXZpZGVyIHdpbGwgb25seSBiZSBpbmNsdWRlZCBhdXRvbWFnaWNhbGx5IHdoZW4gdXNpbmcgaGVhZGVycyBwcm9wLiBUYWJsZURpdmlkZXIgY29tcG9uZW50IGNhbiBiZSB1c2VkCiAqIHdoZW4gbWFudWFsbHkgY29uc3RydWN0aW5nIGEgdGFibGUgeW91IHdpc2ggdG8gbG9vayB0aGUgc2FtZS4KICovCgp2YXIgVGFibGUgPSBleHBvcnRzLlRhYmxlID0gZnVuY3Rpb24gKF9Db21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhUYWJsZSwgX0NvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gVGFibGUoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFRhYmxlKTsKCiAgICAgICAgcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChUYWJsZS5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKFRhYmxlKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFRhYmxlLCBbewogICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHMsCiAgICAgICAgICAgICAgICBzdHlsZSA9IF9wcm9wcy5zdHlsZSwKICAgICAgICAgICAgICAgIGhlYWRlcnMgPSBfcHJvcHMuaGVhZGVycywKICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gX3Byb3BzLmNoaWxkcmVuLAogICAgICAgICAgICAgICAgY2xhc3NOYW1lID0gX3Byb3BzLmNsYXNzTmFtZSwKICAgICAgICAgICAgICAgIGRpc2FibGVIZWFkZXJEaXZpZGVyID0gX3Byb3BzLmRpc2FibGVIZWFkZXJEaXZpZGVyLAogICAgICAgICAgICAgICAgZGlzYWJsZURlZmF1bHRQYWRkaW5nID0gX3Byb3BzLmRpc2FibGVEZWZhdWx0UGFkZGluZywKICAgICAgICAgICAgICAgIGRpc2FibGVOb1dyYXAgPSBfcHJvcHMuZGlzYWJsZU5vV3JhcCwKICAgICAgICAgICAgICAgIGRpc2FibGVGaXhlZCA9IF9wcm9wcy5kaXNhYmxlRml4ZWQ7CgoKICAgICAgICAgICAgdmFyIGRpdmlkZXIgPSBoZWFkZXJzICYmIGhlYWRlcnMubGVuZ3RoICYmICFkaXNhYmxlSGVhZGVyRGl2aWRlciA/IF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFRhYmxlRGl2aWRlciwgeyBudW1Db2xzOiBoZWFkZXJzLmxlbmd0aCB9KSA6IHVuZGVmaW5lZDsKCiAgICAgICAgICAgIHZhciBoZWFkZXJSb3dDZWxscyA9IGhlYWRlcnMgJiYgaGVhZGVycy5tYXAoZnVuY3Rpb24gKGNvbHVtbikgewogICAgICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICd0aCcsCiAgICAgICAgICAgICAgICAgICAgeyBrZXk6IGdldEtleShjb2x1bW4pLCBjbGFzc05hbWU6IGdldENsYXNzKGNvbHVtbikgfSwKICAgICAgICAgICAgICAgICAgICBnZXRMYWJlbChjb2x1bW4pCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIHZhciB0YWJsZUhlYWRlciA9IGhlYWRlcnMgJiYgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAndGhlYWQnLAogICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICd0cicsCiAgICAgICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgICAgICBoZWFkZXJSb3dDZWxscwogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgIGRpdmlkZXIKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIHZhciB0YWJsZUNsYXNzZXMgPSBbJ2pkbC10YWJsZSddOwoKICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSkgewogICAgICAgICAgICAgICAgdGFibGVDbGFzc2VzLnB1c2goY2xhc3NOYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFkaXNhYmxlRGVmYXVsdFBhZGRpbmcpIHsKICAgICAgICAgICAgICAgIHRhYmxlQ2xhc3Nlcy5wdXNoKCd1LXRhYmxlLXBhZGRpbmcnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFkaXNhYmxlTm9XcmFwKSB7CiAgICAgICAgICAgICAgICB0YWJsZUNsYXNzZXMucHVzaCgndS1zaW5nbGUtbGluZScpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWRpc2FibGVGaXhlZCkgewogICAgICAgICAgICAgICAgdGFibGVDbGFzc2VzLnB1c2goJ3UtZml4ZWQnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHdyYXBDaGlsZHJlbiA9IGhlYWRlcnMgJiYgY2hpbGRyZW4gJiYgY2hpbGRyZW4udHlwZSAhPT0gJ3Rib2R5JzsKCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICd0YWJsZScsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogdGFibGVDbGFzc2VzLmpvaW4oJyAnKSwgc3R5bGU6IHN0eWxlIH0sCiAgICAgICAgICAgICAgICB0YWJsZUhlYWRlciwKICAgICAgICAgICAgICAgIHdyYXBDaGlsZHJlbiA/IF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICd0Ym9keScsCiAgICAgICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbgogICAgICAgICAgICAgICAgKSA6IGNoaWxkcmVuCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBUYWJsZTsKfShfcmVhY3QuQ29tcG9uZW50KTsKClRhYmxlLnByb3BUeXBlcyA9IHsKICAgIGNoaWxkcmVuOiBfcmVhY3QuUHJvcFR5cGVzLm5vZGUsCiAgICBjbGFzc05hbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgc3R5bGU6IF9yZWFjdC5Qcm9wVHlwZXMuYW55LAogICAgaGVhZGVyczogX3JlYWN0LlByb3BUeXBlcy5hcnJheSwKICAgIGRpc2FibGVIZWFkZXJEaXZpZGVyOiBfcmVhY3QuUHJvcFR5cGVzLmJvb2wsCiAgICBkaXNhYmxlRGVmYXVsdFBhZGRpbmc6IF9yZWFjdC5Qcm9wVHlwZXMuYm9vbCwKICAgIGRpc2FibGVOb1dyYXA6IF9yZWFjdC5Qcm9wVHlwZXMuYm9vbCwKICAgIGRpc2FibGVGaXhlZDogX3JlYWN0LlByb3BUeXBlcy5ib29sCn07Cgp2YXIgVGFibGVEaXZpZGVyID0gZXhwb3J0cy5UYWJsZURpdmlkZXIgPSBmdW5jdGlvbiBUYWJsZURpdmlkZXIocHJvcHMpIHsKICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAndHInLAogICAgICAgIHsgY2xhc3NOYW1lOiAnamRsLXRhYmxlLWRpdmlkZXInIH0sCiAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICd0ZCcsCiAgICAgICAgICAgIHsgY29sU3BhbjogcHJvcHMubnVtQ29scyB9LAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgnaHInLCBudWxsKQogICAgICAgICkKICAgICk7Cn07CgpUYWJsZURpdmlkZXIucHJvcFR5cGVzID0gewogICAgbnVtQ29sczogX3JlYWN0LlByb3BUeXBlcy5udW1iZXIuaXNSZXF1aXJlZAp9Owp9LHsicmVhY3QiOjYyM31dLDg2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuVGltZUR1cmF0aW9uID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9tb21lbnQgPSByZXF1aXJlKCdtb21lbnQnKTsKCnZhciBfbW9tZW50MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21vbWVudCk7CgpyZXF1aXJlKCdtb21lbnQvbWluL2xvY2FsZXMubWluJyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9CgpyZXF1aXJlKCdtb21lbnQtZHVyYXRpb24tZm9ybWF0Jyk7Ci8vIG5lZWRzIHRvIGJlIGxvYWRlZCBzaW5jZSB0aGUgbW9tZW50IGxpYiB3aWxsIHVzZSByZXF1aXJlIHdoaWNoIGluIHJ1biB0aW1lIHdpbGwgZmFpbAoKLyoqCiAqIERpc3BsYXlzIGEgbWlsbGlzZWNvbmQgZHVyYXRpb24gYXMgdGV4dCBpbiBtb21lbnQtZHVyYXRpb24tZm9ybWF0J3MgImh1bWFuaXplKCkiIGZvcm1hdCwKICogZS5nLiAiYSBmZXcgc2Vjb25kcyIsICIyIGhvdXJzIiwgZXRjLgogKiBBbHNvIGRpc3BsYXlzIHRvb2x0aXAgd2l0aCBtb3JlIHByZWNpc2UgZHVyYXRpb24gaW4gIm1vcywgZGF5cywgaG91cnMsIG1pbnMsIHNlY3MiIGZvcm1hdC4KICogVG9vbHRpcCB0ZXh0IGNhbiBiZSBvdmVycmlkZGVuIHZpYSAiaGludCIgcHJvcGVydHkuCiAqIFNldCBsaXZlVXBkYXRlPXRydWUgdG8gdGljayB0aGUgZHVyYXRpb24gdXAgYXMgdGltZSBlbGFwc2VzLgogKgogKiBQcm9wZXJ0aWVzOgogKiAibWlsbGlzIjogbnVtYmVyIG9yIHN0cmluZy4KICogImhpbnQiOiBzdHJpbmcgdG8gdXNlIGZvciB0b29sdGlwLgogKiAibGl2ZVVwZGF0ZSI6IGJvb2xlYW4KICovCnZhciBUaW1lRHVyYXRpb24gPSBleHBvcnRzLlRpbWVEdXJhdGlvbiA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoVGltZUR1cmF0aW9uLCBfQ29tcG9uZW50KTsKCiAgICBmdW5jdGlvbiBUaW1lRHVyYXRpb24ocHJvcHMpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVGltZUR1cmF0aW9uKTsKCiAgICAgICAgLy8gdHJhY2sgaG93IG11Y2ggdGltZSBoYXMgZWxhcHNlZCBzaW5jZSBsaXZlIHVwZGF0aW5nIHRyYWNraW5nIHN0YXJ0ZWQKICAgICAgICB2YXIgX3RoaXMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoVGltZUR1cmF0aW9uLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoVGltZUR1cmF0aW9uKSkuY2FsbCh0aGlzLCBwcm9wcykpOwoKICAgICAgICBfdGhpcy5zdGF0ZSA9IHsgZWxhcHNlZDogMCB9OwogICAgICAgIHZhciBfdGhpcyRwcm9wcyR1cGRhdGVQZXIgPSBfdGhpcy5wcm9wcy51cGRhdGVQZXJpb2QsCiAgICAgICAgICAgIHVwZGF0ZVBlcmlvZCA9IF90aGlzJHByb3BzJHVwZGF0ZVBlciA9PT0gdW5kZWZpbmVkID8gMzAwMDAgOiBfdGhpcyRwcm9wcyR1cGRhdGVQZXI7CgogICAgICAgIF90aGlzLnRpbWVyUGVyaW9kTWlsbGlzID0gdHlwZW9mIHVwZGF0ZVBlcmlvZCAhPT0gJ251bWJlcicgfHwgaXNOYU4odXBkYXRlUGVyaW9kKSA/IDMwMDAwIDogdXBkYXRlUGVyaW9kOwogICAgICAgIF90aGlzLmNsZWFySW50ZXJ2YWxJZCA9IDA7CgogICAgICAgIHJldHVybiBfdGhpczsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoVGltZUR1cmF0aW9uLCBbewogICAgICAgIGtleTogJ2NvbXBvbmVudFdpbGxNb3VudCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxNb3VudCgpIHsKICAgICAgICAgICAgdGhpcy5faGFuZGxlUHJvcHModGhpcy5wcm9wcyk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykgewogICAgICAgICAgICB0aGlzLl9oYW5kbGVQcm9wcyhuZXh0UHJvcHMpOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfaGFuZGxlUHJvcHMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfaGFuZGxlUHJvcHMocHJvcHMpIHsKICAgICAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7CgogICAgICAgICAgICBpZiAodGhpcy5jbGVhckludGVydmFsSWQpIHsKICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jbGVhckludGVydmFsSWQpOwogICAgICAgICAgICAgICAgdGhpcy5jbGVhckludGVydmFsSWQgPSAwOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocHJvcHMubWlsbGlzID49IDAgJiYgcHJvcHMubGl2ZVVwZGF0ZSkgewogICAgICAgICAgICAgICAgdGhpcy5jbGVhckludGVydmFsSWQgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgX3RoaXMyLl91cGRhdGVUaW1lKCk7CiAgICAgICAgICAgICAgICB9LCB0aGlzLnRpbWVyUGVyaW9kTWlsbGlzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gaWYgbGl2ZSB1cGRhdGUgaXMgZGlzYWJsZWQsIHdlIG5vIGxvbmdlciBuZWVkIHRvIHRyYWNrIGVsYXBzZWQgdGltZQogICAgICAgICAgICBpZiAoIXByb3BzLmxpdmVVcGRhdGUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoewogICAgICAgICAgICAgICAgICAgIGVsYXBzZWQ6IDAKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ191cGRhdGVUaW1lJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX3VwZGF0ZVRpbWUoKSB7CiAgICAgICAgICAgIHZhciBlbGFwc2VkID0gdGhpcy5zdGF0ZS5lbGFwc2VkICsgdGhpcy50aW1lclBlcmlvZE1pbGxpczsKICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7CiAgICAgICAgICAgICAgICBlbGFwc2VkOiBlbGFwc2VkCiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsVW5tb3VudCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkgewogICAgICAgICAgICBpZiAodGhpcy5jbGVhckludGVydmFsSWQpIHsKICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jbGVhckludGVydmFsSWQpOwogICAgICAgICAgICAgICAgdGhpcy5jbGVhckludGVydmFsSWQgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgdmFyIG1pbGxpcyA9IHBhcnNlSW50KHRoaXMucHJvcHMubWlsbGlzKSArIHRoaXMuc3RhdGUuZWxhcHNlZDsKCiAgICAgICAgICAgIGlmICghaXNOYU4obWlsbGlzKSkgewogICAgICAgICAgICAgICAgaWYgKG1pbGxpcyA8IDEwMDApIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgICAgICdzcGFuJywKICAgICAgICAgICAgICAgICAgICAgICAgeyB0aXRsZTogdGhpcy5wcm9wcy5oaW50ID8gdGhpcy5wcm9wcy5oaW50IDogJzwxcycgfSwKICAgICAgICAgICAgICAgICAgICAgICAgJzwxcycKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzLAogICAgICAgICAgICAgICAgICAgIF9wcm9wcyRsb2NhbGUgPSBfcHJvcHMubG9jYWxlLAogICAgICAgICAgICAgICAgICAgIF9sb2NhbGUgPSBfcHJvcHMkbG9jYWxlID09PSB1bmRlZmluZWQgPyAnZW4nIDogX3Byb3BzJGxvY2FsZSwKICAgICAgICAgICAgICAgICAgICBfcHJvcHMkZGlzcGxheUZvcm1hdCA9IF9wcm9wcy5kaXNwbGF5Rm9ybWF0LAogICAgICAgICAgICAgICAgICAgIF9kaXNwbGF5Rm9ybWF0ID0gX3Byb3BzJGRpc3BsYXlGb3JtYXQgPT09IHVuZGVmaW5lZCA/ICdkW2RdIGhbaF0gbVttXSBzW3NdJyA6IF9wcm9wcyRkaXNwbGF5Rm9ybWF0LAogICAgICAgICAgICAgICAgICAgIF9wcm9wcyRsaXZlRm9ybWF0ID0gX3Byb3BzLmxpdmVGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgX2xpdmVGb3JtYXQgPSBfcHJvcHMkbGl2ZUZvcm1hdCA9PT0gdW5kZWZpbmVkID8gJ2RbZF0gaFtoXSBtW21dIHNbc10nIDogX3Byb3BzJGxpdmVGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgX3Byb3BzJGhpbnRGb3JtYXQgPSBfcHJvcHMuaGludEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICBfaGludEZvcm1hdCA9IF9wcm9wcyRoaW50Rm9ybWF0ID09PSB1bmRlZmluZWQgPyAnTSBbbW9udGhzXSwgZCBbZGF5c10sIGggW2hvdXJzXSwgbSBbbWludXRlc10sIHMgW3NlY29uZHNdJyA6IF9wcm9wcyRoaW50Rm9ybWF0OwoKICAgICAgICAgICAgICAgIF9tb21lbnQyLmRlZmF1bHQubG9jYWxlKF9sb2NhbGUpOwogICAgICAgICAgICAgICAgLy8gaW4gY2FzZSB3ZSBhcmUgaW4gbGl2ZSB1cGRhdGUgd2UgYXJlIGludGVyZXN0ZWQgaW4gc2Vjb25kcwogICAgICAgICAgICAgICAgdmFyIGR1cmF0aW9uID0gdGhpcy5wcm9wcy5saXZlVXBkYXRlID8gX21vbWVudDIuZGVmYXVsdC5kdXJhdGlvbihtaWxsaXMpLmZvcm1hdChfbGl2ZUZvcm1hdCkgOiBfbW9tZW50Mi5kZWZhdWx0LmR1cmF0aW9uKG1pbGxpcykuZm9ybWF0KF9kaXNwbGF5Rm9ybWF0KTsKCiAgICAgICAgICAgICAgICB2YXIgX2hpbnQgPSB0aGlzLnByb3BzLmhpbnQgPyB0aGlzLnByb3BzLmhpbnQgOiBfbW9tZW50Mi5kZWZhdWx0LmR1cmF0aW9uKG1pbGxpcykuZm9ybWF0KF9oaW50Rm9ybWF0KTsKCiAgICAgICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLAogICAgICAgICAgICAgICAgICAgIHsgdGl0bGU6IF9oaW50IH0sCiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24KICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdzcGFuJywKICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAnLScKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFRpbWVEdXJhdGlvbjsKfShfcmVhY3QuQ29tcG9uZW50KTsKClRpbWVEdXJhdGlvbi5wcm9wVHlwZXMgPSB7CiAgICBtaWxsaXM6IF9yZWFjdC5Qcm9wVHlwZXMub25lT2ZUeXBlKFtfcmVhY3QuUHJvcFR5cGVzLm51bWJlciwgX3JlYWN0LlByb3BUeXBlcy5zdHJpbmddKSwKICAgIHVwZGF0ZVBlcmlvZDogX3JlYWN0LlByb3BUeXBlcy5vbmVPZlR5cGUoW19yZWFjdC5Qcm9wVHlwZXMubnVtYmVyLCBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZ10pLAogICAgaGludDogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBsaXZlVXBkYXRlOiBfcmVhY3QuUHJvcFR5cGVzLmJvb2wsCiAgICBsb2NhbGU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgZGlzcGxheUZvcm1hdDogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBsaXZlRm9ybWF0OiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIGhpbnRGb3JtYXQ6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nCn07Cn0seyJtb21lbnQiOjM5MiwibW9tZW50LWR1cmF0aW9uLWZvcm1hdCI6MzkwLCJtb21lbnQvbWluL2xvY2FsZXMubWluIjozOTEsInJlYWN0Ijo2MjN9XSw4NzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlRvYXN0ID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9yZWFjdE1hdGVyaWFsSWNvbnMgPSByZXF1aXJlKCdAamVua2lucy1jZC9yZWFjdC1tYXRlcmlhbC1pY29ucycpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKLyoqCiAqIFRvYXN0IGRpc3BsYXlzIGEgc21hbGwgY29uZmlybWF0aW9uIG1lc3NhZ2Ugd2l0aCBhbiBvcHRpb25hbCBhY3Rpb24gbGluayBhbmQgZGlzbWlzcyBsaW5rLgogKiBUb2FzdCB3aWxsIGF1dG8tZGlzbWlzcyBpdHNlbGYgYWZ0ZXIgNXMuCiAqCiAqIFN1cHBvcnRlZCBwcm9wczoKICogdGV4dCAtIENvbmZpcm1hdGlvbiBtZXNzYWdlIHRleHQsIGUuZy4gIlJ1biBTdGFydGVkIgogKiBhY3Rpb24gLSBPcHRpb25hbCBhY3Rpb24gbGluaywgZS5nLiAiT3BlbiIKICogb25BY3Rpb25DbGljayAtIGZ1bmN0aW9uIHRvIGludm9rZSB3aGVuIGFjdGlvbiBsaW5rIGlzIGNsaWNrZWQKICogb25EaXNtaXNzIC0gZnVuY3Rpb24gdG8gaW52b2tlIHdoZW4gZGlzbWlzcyBsaW5rIGlzIGNsaWNrZWQsIG9yIFRvYXN0IGF1dG8tZGlzbWlzc2VzLgogKi8KdmFyIFRvYXN0ID0gZXhwb3J0cy5Ub2FzdCA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoVG9hc3QsIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIFRvYXN0KCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUb2FzdCk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoVG9hc3QuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihUb2FzdCkpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhUb2FzdCwgW3sKICAgICAgICBrZXk6ICdvbkFjdGlvbkNsaWNrJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gb25BY3Rpb25DbGljaygpIHsKICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMub25BY3Rpb25DbGljaykgewogICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkFjdGlvbkNsaWNrKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnb25EaXNtaXNzQ2xpY2snLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBvbkRpc21pc3NDbGljaygpIHsKICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMub25EaXNtaXNzKSB7CiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLm9uRGlzbWlzcygpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7CgogICAgICAgICAgICB2YXIgdG9hc3RTdHlsZSA9IHRoaXMucHJvcHMuc3R5bGUgfHwgJ2RlZmF1bHQnOwogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAndG9hc3QgJyArIHRvYXN0U3R5bGUgfSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICdzcGFuJywKICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3RleHQnIH0sCiAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoQ2FwdGlvbiwgeyB0ZXh0OiB0aGlzLnByb3BzLmNhcHRpb24gfSksCiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy50ZXh0CiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2EnLAogICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnYWN0aW9uJywgb25DbGljazogZnVuY3Rpb24gb25DbGljaygpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIub25BY3Rpb25DbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICB9IH0sCiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5hY3Rpb24KICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAnYScsCiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdkaXNtaXNzJywgb25DbGljazogZnVuY3Rpb24gb25DbGljaygpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIub25EaXNtaXNzQ2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSB9LAogICAgICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KF9yZWFjdE1hdGVyaWFsSWNvbnMuSWNvbiwgewogICAgICAgICAgICAgICAgICAgICAgICBzaXplOiAxOCwKICAgICAgICAgICAgICAgICAgICAgICAgaWNvbjogJ2NsZWFyJywKICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHsgZmlsbDogIiNmZmYiIH0KICAgICAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gVG9hc3Q7Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpUb2FzdC5wcm9wVHlwZXMgPSB7CiAgICBjYXB0aW9uOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIHRleHQ6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgc3R5bGU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgYWN0aW9uOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIG9uQWN0aW9uQ2xpY2s6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYywKICAgIG9uRGlzbWlzczogX3JlYWN0LlByb3BUeXBlcy5mdW5jCn07Cgp2YXIgQ2FwdGlvbiA9IGZ1bmN0aW9uIENhcHRpb24oX3JlZikgewogICAgdmFyIHRleHQgPSBfcmVmLnRleHQ7CgogICAgaWYgKCF0ZXh0KSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgJ2g0JywKICAgICAgICB7IGNsYXNzTmFtZTogJ2NhcHRpb24nIH0sCiAgICAgICAgdGV4dAogICAgKTsKfTsKQ2FwdGlvbi5wcm9wVHlwZXMgPSB7CiAgICB0ZXh0OiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZwp9Owp9LHsiQGplbmtpbnMtY2QvcmVhY3QtbWF0ZXJpYWwtaWNvbnMiOjEyOSwicmVhY3QiOjYyM31dLDg4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuVG9hc3RlciA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfcmVhY3RBZGRvbnNDc3NUcmFuc2l0aW9uR3JvdXAgPSByZXF1aXJlKCdyZWFjdC1hZGRvbnMtY3NzLXRyYW5zaXRpb24tZ3JvdXAnKTsKCnZhciBfcmVhY3RBZGRvbnNDc3NUcmFuc2l0aW9uR3JvdXAyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3RBZGRvbnNDc3NUcmFuc2l0aW9uR3JvdXApOwoKdmFyIF9Ub2FzdCA9IHJlcXVpcmUoJy4vVG9hc3QnKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0gLyoqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIENyZWF0ZWQgYnkgY21leWVycyBvbiA4LzE3LzE2LgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCgovKioKICogVG9hc3RlciBpcyBhIGNvbnRhaW5lciBmb3IgVG9hc3QgaW5zdGFuY2VzIGRpc3BsYXllZCBiYXNlZCBvbiBzdXBwbGllZCAndG9hc3RzJyBwcm9wLgogKgogKiBTdXBwb3J0ZWQgcHJvcHM6CiAqIHRvYXN0cyAtIGFycmF5IG9mIHRvYXN0IG9iamVjdHMKICogewogKiAgICAgaWQ6IHVuaXF1ZSBpZGVudGlmaWVyCiAqICAgICB0ZXh0OiBzdHJpbmcsIG1lc3NhZ2UgdGV4dCB0byBkaXNwbGF5CiAqICAgICBhY3Rpb246IHN0cmluZywgdGV4dCBmb3IgYWN0aW9uIGxpbmsKICogICAgIG9uQWN0aW9uQ2xpY2s6IGZ1bmN0aW9uLCBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiBhY3Rpb24gbGluayBpcyBjbGlja2VkCiAqICAgICBvbkRpc21pc3M6IGZ1bmN0aW9uLCBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0b2FzdCBpcyBkaXNtaXNzZWQgKGltbWVkaWF0ZWx5LCBvciBhZnRlciB0aW1lb3V0KQogKiAgICAgZGlzbWlzc0RlbGF5OiBudW1iZXIsIGR1cmF0aW9uIGluIG1pbGxpcyBhZnRlciB3aGljaCB0byBhdXRvLWRpc21pc3MgdGhpcyBUb2FzdAogKiB9CiAqIGRpc21pc3NEZWxheSAtIG51bWJlciwgZGVmYXVsdCBkdXJhdGlvbiBpbiBtaWxsaXMgYWZ0ZXIgd2hpY2ggdG8gaGlkZSBhIFRvYXN0CiAqLwp2YXIgVG9hc3RlciA9IGV4cG9ydHMuVG9hc3RlciA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoVG9hc3RlciwgX0NvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gVG9hc3RlcigpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVG9hc3Rlcik7CgogICAgICAgIHZhciBfdGhpcyA9IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChUb2FzdGVyLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoVG9hc3RlcikpLmNhbGwodGhpcykpOwoKICAgICAgICBfdGhpcy5hY3RpdmVUb2FzdHMgPSB7fTsKICAgICAgICByZXR1cm4gX3RoaXM7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFRvYXN0ZXIsIFt7CiAgICAgICAga2V5OiAnY29tcG9uZW50V2lsbE1vdW50JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbE1vdW50KCkgewogICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplKHRoaXMucHJvcHMpOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHsKICAgICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZShuZXh0UHJvcHMpOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfaW5pdGlhbGl6ZScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9pbml0aWFsaXplKHByb3BzKSB7CiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzOwoKICAgICAgICAgICAgaWYgKCFwcm9wcy50b2FzdHMpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSB0cnVlOwogICAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IgPSBmYWxzZTsKICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHZhciBfbG9vcCA9IGZ1bmN0aW9uIF9sb29wKCkgewogICAgICAgICAgICAgICAgICAgIHZhciB0b2FzdCA9IF9zdGVwLnZhbHVlOwoKICAgICAgICAgICAgICAgICAgICB2YXIgZGlzbWlzc0RlbGF5ID0gdG9hc3QuZGlzbWlzc0RlbGF5IHx8IHByb3BzLmRpc21pc3NEZWxheSB8fCA1MDAwOwoKICAgICAgICAgICAgICAgICAgICAvLyBpZiB3ZSBhcmVuJ3QgYWxyZWFkeSB0cmFja2luZyB0aGUgdG9hc3QsIGFkZCBhbiBhdXRvLWRpc21pc3MgaGFuZGxlciBhbmQgc3RvcmUgdGhlIHRpbWVvdXRJZAogICAgICAgICAgICAgICAgICAgIGlmICghX3RoaXMyLmFjdGl2ZVRvYXN0c1t0b2FzdC5pZF0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzMi5fb25EaXNtaXNzKHRvYXN0KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwgZGlzbWlzc0RlbGF5KTsKICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMyLmFjdGl2ZVRvYXN0c1t0b2FzdC5pZF0gPSB0aW1lb3V0SWQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBwcm9wcy50b2FzdHNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gKF9zdGVwID0gX2l0ZXJhdG9yLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgX2xvb3AoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvciA9IHRydWU7CiAgICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvciA9IGVycjsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uICYmIF9pdGVyYXRvci5yZXR1cm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yLnJldHVybigpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfb25BY3Rpb25DbGljaycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9vbkFjdGlvbkNsaWNrKHRvYXN0KSB7CiAgICAgICAgICAgIHRoaXMuX2NsZWFudXAodG9hc3QpOwoKICAgICAgICAgICAgaWYgKHRvYXN0Lm9uQWN0aW9uQ2xpY2spIHsKICAgICAgICAgICAgICAgIHRvYXN0Lm9uQWN0aW9uQ2xpY2soKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMub25BY3Rpb25DbGljaykgewogICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkFjdGlvbkNsaWNrKHRvYXN0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfb25EaXNtaXNzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX29uRGlzbWlzcyh0b2FzdCkgewogICAgICAgICAgICB0aGlzLl9jbGVhbnVwKHRvYXN0KTsKCiAgICAgICAgICAgIGlmICh0b2FzdC5vbkRpc21pc3MpIHsKICAgICAgICAgICAgICAgIHRvYXN0Lm9uRGlzbWlzcygpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5vbkRpc21pc3MpIHsKICAgICAgICAgICAgICAgIHRoaXMucHJvcHMub25EaXNtaXNzKHRvYXN0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfY2xlYW51cCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9jbGVhbnVwKHRvYXN0KSB7CiAgICAgICAgICAgIHZhciB0aW1lb3V0SWQgPSB0aGlzLmFjdGl2ZVRvYXN0c1t0b2FzdC5pZF07CgogICAgICAgICAgICBpZiAodGltZW91dElkKSB7CiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTsKICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmFjdGl2ZVRvYXN0c1t0b2FzdC5pZF07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX3RoaXMzID0gdGhpczsKCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICd0b2FzdGVyJyB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgX3JlYWN0QWRkb25zQ3NzVHJhbnNpdGlvbkdyb3VwMi5kZWZhdWx0LAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNpdGlvbk5hbWU6ICd0b2FzdCcsCiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zaXRpb25BcHBlYXI6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zaXRpb25BcHBlYXJUaW1lb3V0OiAzMDAsIHRyYW5zaXRpb25FbnRlclRpbWVvdXQ6IDMwMCwgdHJhbnNpdGlvbkxlYXZlVGltZW91dDogMzAwCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnRvYXN0cy5tYXAoZnVuY3Rpb24gKHRvYXN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdG9hc3QuaWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oInRvYXN0IGNhbm5vdCBiZSBhZGRlZCB3aXRob3V0ICdpZCcgcHJvcGVydHkiLCB0b2FzdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGtleSA9IHRvYXN0LmlkOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KF9Ub2FzdC5Ub2FzdCwgewogICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5OiBrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXB0aW9uOiB0b2FzdC5jYXB0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogdG9hc3QudGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiB0b2FzdC5zdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbjogdG9hc3QuYWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb25BY3Rpb25DbGljazogZnVuY3Rpb24gb25BY3Rpb25DbGljaygpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMzLl9vbkFjdGlvbkNsaWNrKHRvYXN0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkRpc21pc3M6IGZ1bmN0aW9uIG9uRGlzbWlzcygpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMzLl9vbkRpc21pc3ModG9hc3QpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gVG9hc3RlcjsKfShfcmVhY3QuQ29tcG9uZW50KTsKClRvYXN0ZXIucHJvcFR5cGVzID0gewogICAgdG9hc3RzOiBfcmVhY3QuUHJvcFR5cGVzLmFycmF5LAogICAgb25BY3Rpb25DbGljazogX3JlYWN0LlByb3BUeXBlcy5mdW5jLAogICAgb25EaXNtaXNzOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsCiAgICBkaXNtaXNzRGVsYXk6IF9yZWFjdC5Qcm9wVHlwZXMubnVtYmVyCn07CgpUb2FzdGVyLmRlZmF1bHRQcm9wcyA9IHsKICAgIHRvYXN0czogW10KfTsKfSx7Ii4vVG9hc3QiOjg3LCJyZWFjdCI6NjIzLCJyZWFjdC1hZGRvbnMtY3NzLXRyYW5zaXRpb24tZ3JvdXAiOjQyOX1dLDg5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuVHJ1bmNhdGluZ0xhYmVsID0gZXhwb3J0cy5SZW5kZXJTdGF0ZVZhbHVlcyA9IHVuZGVmaW5lZDsKCnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSAic3ltYm9sIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyAic3ltYm9sIiA6IHR5cGVvZiBvYmo7IH07Cgp2YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9OwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX1JlbmRlclN0YXRlVmFsdWVzOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfcmVhY3REb20gPSByZXF1aXJlKCdyZWFjdC1kb20nKTsKCnZhciBfcmVhY3REb20yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3REb20pOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKZnVuY3Rpb24gX2RlZmluZVByb3BlcnR5KG9iaiwga2V5LCB2YWx1ZSkgeyBpZiAoa2V5IGluIG9iaikgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHsgdmFsdWU6IHZhbHVlLCBlbnVtZXJhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUsIHdyaXRhYmxlOiB0cnVlIH0pOyB9IGVsc2UgeyBvYmpba2V5XSA9IHZhbHVlOyB9IHJldHVybiBvYmo7IH0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gIFNhZmV0eSBjb25zdGFudHMKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdmFyIE1JTkxFTkdUSCA9IDU7IC8vIE1pbmltdW0gc2l6ZSBvZiBjdXQtZG93biB0ZXh0CnZhciBNQVhMT09QUyA9IDUwOyAvLyBNYXggbm8gb2YgaXRlcmF0aW9ucyBhdHRlbXB0aW5nIHRvIGZpbmQgdGhlIGNvcnJlY3Qgc2l6ZSB0ZXh0CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICBGbG93IHR5cGVzCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8vIFJlbmRlciBsaWZlY3ljbGUKdmFyIFJTX01FQVNVUkUgPSAnbWVhc3VyZSc7IC8vIE1vdW50ZWQsIHRleHQvcHJvcHMgY2hhbmdlZCwgbWVhc3VyZW1lbnQgbmVlZGVkLgp2YXIgUlNfRkxVSUQgPSAnZmx1aWQnOyAvLyBUZXh0IHRvbyBiaWcsIGluIHRoZSBwcm9jZXNzIG9mIHRyaW1taW5nIGl0IGRvd24KdmFyIFJTX1NUQUJMRSA9ICdzdGFibGUnOyAvLyBEb25lIG1lYXN1cmluZywgdW50aWwgcHJvcHMgY2hhbmdlCgp2YXIgUmVuZGVyU3RhdGVWYWx1ZXMgPSBleHBvcnRzLlJlbmRlclN0YXRlVmFsdWVzID0gKF9SZW5kZXJTdGF0ZVZhbHVlcyA9IHt9LCBfZGVmaW5lUHJvcGVydHkoX1JlbmRlclN0YXRlVmFsdWVzLCBSU19NRUFTVVJFLCBSU19NRUFTVVJFKSwgX2RlZmluZVByb3BlcnR5KF9SZW5kZXJTdGF0ZVZhbHVlcywgUlNfRkxVSUQsIFJTX0ZMVUlEKSwgX2RlZmluZVByb3BlcnR5KF9SZW5kZXJTdGF0ZVZhbHVlcywgUlNfU1RBQkxFLCBSU19TVEFCTEUpLCBfUmVuZGVyU3RhdGVWYWx1ZXMpOwoKLy8gcmVhY3QuQ29tcG9uZW50LnByb3BzCgovKioKICogTXVsdGktbGluZSBsYWJlbCB0aGF0IHdpbGwgdHJ1bmNhdGUgd2l0aCBlbGxpcHNlcwogKgogKiBVc2Ugd2l0aCBhIHNldCB3aWR0aCArIGhlaWdodCAob3IgbWF4V2lkdGggLyBtYXhIZWlnaHQpIHRvIGdldCBhbnkgdXNlIGZyb20gaXQgOkQKICovCnZhciBUcnVuY2F0aW5nTGFiZWwgPSBleHBvcnRzLlRydW5jYXRpbmdMYWJlbCA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoVHJ1bmNhdGluZ0xhYmVsLCBfQ29tcG9uZW50KTsKCiAgICBmdW5jdGlvbiBUcnVuY2F0aW5nTGFiZWwoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFRydW5jYXRpbmdMYWJlbCk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoVHJ1bmNhdGluZ0xhYmVsLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoVHJ1bmNhdGluZ0xhYmVsKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFRydW5jYXRpbmdMYWJlbCwgW3sKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsTW91bnQnLAogICAgICAgIC8vIHRvIGF2b2lkIGluZmluaXRlIGl0ZXJhdGlvbgoKICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgLy8gIFJlYWN0IExpZmVjeWNsZQogICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAgICAgLy8gTGVuZ3RoIG9mIHRoZSBsb25nZXN0IHRydW5jYXRlZCB0ZXh0IHRoYXQgZml0cwogICAgICAgIC8vIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgaGFuZGxlCgogICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAvLyAgQmluYXJ5IHNlYXJjaCBzdGF0ZQogICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAgICAgLy8gQ3VycmVudCBpbm5lclRleHQgb2YgZWxlbWVudCAtIGluY2x1ZGVzIHBvc3NpYmxlIGVsbGlwc2VzCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxNb3VudCgpIHsKICAgICAgICAgICAgdGhpcy5oYW5kbGVQcm9wcyh0aGlzLnByb3BzKTsKICAgICAgICB9IC8vIExlbmd0aCBvZiB0aGUgc2hvcnRlc3QgdHJ1bmNhdGVkIHRleHQgdGhhdCBkb2VzIG5vdCBmaXQKICAgICAgICAvLyBMYXN0IGNvdW50IHVzZWQgdG8gdHJ1bmNhdGUgY29tcGxldGVUZXh0CiAgICAgICAgLy8gSW50ZXJuYWwgcmVuZGVyaW5nIGxpZmVjeWNsZSBzdGF0ZQogICAgICAgIC8vIFVuYWJyaWRnZWQgcGxhaW4gdGV4dCBjb250ZW50CgoKICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgLy8gIENvbXBvbmVudCBzdGF0ZSAvIGxpZmVjeWNsZQogICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICB9LCB7CiAgICAgICAga2V5OiAnY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7CiAgICAgICAgICAgIHRoaXMuaGFuZGxlUHJvcHMobmV4dFByb3BzKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY29tcG9uZW50RGlkTW91bnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHsKICAgICAgICAgICAgdGhpcy5pbnZhbGlkYXRlU2l6ZSgpOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjb21wb25lbnREaWRVcGRhdGUnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRVcGRhdGUoKSB7CiAgICAgICAgICAgIHRoaXMuaW52YWxpZGF0ZVNpemUoKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY29tcG9uZW50V2lsbFVubW91bnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHsKICAgICAgICAgICAgaWYgKHRoaXMuY2hlY2tTaXplUmVxdWVzdCkgewogICAgICAgICAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5jaGVja1NpemVSZXF1ZXN0KTsKICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tTaXplUmVxdWVzdCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAvLyAgUmVuZGVyCiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIH0sIHsKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzLAogICAgICAgICAgICAgICAgX3Byb3BzJHN0eWxlID0gX3Byb3BzLnN0eWxlLAogICAgICAgICAgICAgICAgc3R5bGUgPSBfcHJvcHMkc3R5bGUgPT09IHVuZGVmaW5lZCA/IHt9IDogX3Byb3BzJHN0eWxlLAogICAgICAgICAgICAgICAgX3Byb3BzJGNsYXNzTmFtZSA9IF9wcm9wcy5jbGFzc05hbWUsCiAgICAgICAgICAgICAgICBjbGFzc05hbWUgPSBfcHJvcHMkY2xhc3NOYW1lID09PSB1bmRlZmluZWQgPyAnJyA6IF9wcm9wcyRjbGFzc05hbWU7CgoKICAgICAgICAgICAgdmFyIG1lcmdlZFN0eWxlID0gX2V4dGVuZHMoewogICAgICAgICAgICAgICAgb3ZlcmZsb3c6ICdoaWRkZW4nLAogICAgICAgICAgICAgICAgd29yZFdyYXA6ICdicmVhay13b3JkJwogICAgICAgICAgICB9LCBzdHlsZSk7CgogICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJTdGF0ZSAhPT0gUlNfU1RBQkxFKSB7CiAgICAgICAgICAgICAgICBtZXJnZWRTdHlsZS5vcGFjaXR5ID0gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICB7IHN0eWxlOiBtZXJnZWRTdHlsZSwgY2xhc3NOYW1lOiAnVHJ1bmNhdGluZ0xhYmVsICcgKyBjbGFzc05hbWUgfSwKICAgICAgICAgICAgICAgIHRoaXMuaW5uZXJUZXh0CiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgLy8gIEludGVybmFsIFJlbmRlcmluZyBMaWZlY3ljbGUKICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgfSwgewogICAgICAgIGtleTogJ2hhbmRsZVByb3BzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gaGFuZGxlUHJvcHMocHJvcHMpIHsKICAgICAgICAgICAgdmFyIF9wcm9wcyRjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuLAogICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBfcHJvcHMkY2hpbGRyZW4gPT09IHVuZGVmaW5lZCA/ICIiIDogX3Byb3BzJGNoaWxkcmVuOwoKCiAgICAgICAgICAgIGlmICh0eXBlb2YgY2hpbGRyZW4gPT09ICJzdHJpbmciKSB7CiAgICAgICAgICAgICAgICB0aGlzLmNvbXBsZXRlVGV4dCA9IGNoaWxkcmVuOwogICAgICAgICAgICB9IGVsc2UgaWYgKGNoaWxkcmVuID09PSBudWxsIHx8IGNoaWxkcmVuID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0ZVRleHQgPSAiIjsgLy8gQXNzdW1lIGNvbnRlbnQgaGFzIGJlZW4gYm9vbGVhbidkIG91dAogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCJUcnVuY2F0aW5nTGFiZWwgLSBMYWJlbCBjaGlsZHJlbiBtdXN0IGJlIHN0cmluZyBidXQgaXMiLCB0eXBlb2YgY2hpbGRyZW4gPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKGNoaWxkcmVuKSwgY2hpbGRyZW4pOwogICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0ZVRleHQgPSAiQ29udGVudHMgbXVzdCBiZSBzdHJpbmciOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLnJlbmRlclN0YXRlID0gUlNfTUVBU1VSRTsKICAgICAgICAgICAgdGhpcy5pbm5lclRleHQgPSB0aGlzLmNvbXBsZXRlVGV4dDsKICAgICAgICAgICAgdGhpcy5sb29wQ291bnQgPSAwOwogICAgICAgICAgICB0aGlzLmxvbmdlc3RHb29kID0gTUlOTEVOR1RIOwogICAgICAgICAgICB0aGlzLnNob3J0ZXN0QmFkID0gdGhpcy5pbm5lclRleHQubGVuZ3RoOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdpbnZhbGlkYXRlU2l6ZScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGludmFsaWRhdGVTaXplKCkgewogICAgICAgICAgICB2YXIgX3RoaXMyID0gdGhpczsKCiAgICAgICAgICAgIGlmICghdGhpcy5jaGVja1NpemVSZXF1ZXN0KSB7CiAgICAgICAgICAgICAgICB0aGlzLmNoZWNrU2l6ZVJlcXVlc3QgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIuY2hlY2tTaXplKCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjaGVja1NpemUnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjaGVja1NpemUoKSB7CiAgICAgICAgICAgIHRoaXMuY2hlY2tTaXplUmVxdWVzdCA9IDA7CgogICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJTdGF0ZSA9PT0gUlNfU1RBQkxFKSB7CiAgICAgICAgICAgICAgICByZXR1cm47IC8vIE5vdGhpbmcgdG8gY2hlY2ssIG5vIG1vcmUgY2hlY2tzIHRvIHNjaGVkdWxlCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciB0aGlzRWxlbWVudCA9IF9yZWFjdERvbTIuZGVmYXVsdC5maW5kRE9NTm9kZSh0aGlzKTsKICAgICAgICAgICAgdmFyIHNjcm9sbEhlaWdodCA9IHRoaXNFbGVtZW50LnNjcm9sbEhlaWdodCwKICAgICAgICAgICAgICAgIGNsaWVudEhlaWdodCA9IHRoaXNFbGVtZW50LmNsaWVudEhlaWdodCwKICAgICAgICAgICAgICAgIHNjcm9sbFdpZHRoID0gdGhpc0VsZW1lbnQuc2Nyb2xsV2lkdGgsCiAgICAgICAgICAgICAgICBjbGllbnRXaWR0aCA9IHRoaXNFbGVtZW50LmNsaWVudFdpZHRoOwoKCiAgICAgICAgICAgIHZhciB0b29CaWcgPSBzY3JvbGxIZWlnaHQgPiBjbGllbnRIZWlnaHQgfHwgc2Nyb2xsV2lkdGggPiBjbGllbnRXaWR0aDsKCiAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclN0YXRlID09PSBSU19NRUFTVVJFKSB7CiAgICAgICAgICAgICAgICAvLyBGaXJzdCBtZWFzdXJlbWVudCBzaW5jZSBtb3VudCAvIHByb3BzIGNoYW5nZWQKCiAgICAgICAgICAgICAgICBpZiAodG9vQmlnKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJTdGF0ZSA9IFJTX0ZMVUlEOwoKICAgICAgICAgICAgICAgICAgICAvLyBTZXQgaW5pdGlhbCBwYXJhbXMgZm9yIGJpbmFyeSBzZWFyY2ggb2YgbGVuZ3RoIAogICAgICAgICAgICAgICAgICAgIHRoaXMubG9uZ2VzdEdvb2QgPSBNSU5MRU5HVEg7CiAgICAgICAgICAgICAgICAgICAgdGhpcy50ZXh0Q3V0b2ZmTGVuZ3RoID0gdGhpcy5zaG9ydGVzdEJhZCA9IHRoaXMuaW5uZXJUZXh0Lmxlbmd0aDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJTdGF0ZSA9IFJTX1NUQUJMRTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcmNlVXBkYXRlKCk7IC8vIFJlLXJlbmRlciB2aWEgcmVhY3Qgc28gaXQgY2FuIHVwZGF0ZSB0aGUgYWxwaGEKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyU3RhdGUgPT09IFJTX0ZMVUlEKSB7CiAgICAgICAgICAgICAgICB0aGlzLmxvb3BDb3VudCsrOwoKICAgICAgICAgICAgICAgIHZhciBsYXN0TGVuZ3RoID0gdGhpcy50ZXh0Q3V0b2ZmTGVuZ3RoOwoKICAgICAgICAgICAgICAgIHZhciBrZWVwTWVhc3VyaW5nID0gdm9pZCAwOwoKICAgICAgICAgICAgICAgIGlmICh0aGlzLmxvb3BDb3VudCA+PSBNQVhMT09QUykgewogICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgcmVhbGx5IHNob3VsZG4ndCBoYXBwZW4hCiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignVHJ1bmNhdGluZ0xhYmVsIC0gVE9PIE1BTlkgTE9PUFMnKTsKICAgICAgICAgICAgICAgICAgICBrZWVwTWVhc3VyaW5nID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGxhc3RMZW5ndGggPD0gTUlOTEVOR1RIKSB7CiAgICAgICAgICAgICAgICAgICAga2VlcE1lYXN1cmluZyA9IGZhbHNlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNYXRoLmFicyh0aGlzLnNob3J0ZXN0QmFkIC0gdGhpcy5sb25nZXN0R29vZCkgPCAyKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gV2UncmUgZG9uZSBzZWFyY2hpbmcsIGhvb3JheXMhCiAgICAgICAgICAgICAgICAgICAga2VlcE1lYXN1cmluZyA9IGZhbHNlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKCiAgICAgICAgICAgICAgICAgICAgLy8gVXBkYXRlIHNlYXJjaCBzcGFjZQogICAgICAgICAgICAgICAgICAgIGlmICh0b29CaWcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zaG9ydGVzdEJhZCA9IE1hdGgubWluKHRoaXMuc2hvcnRlc3RCYWQsIGxhc3RMZW5ndGgpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9uZ2VzdEdvb2QgPSBNYXRoLm1heCh0aGlzLmxvbmdlc3RHb29kLCBsYXN0TGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgbmV4dCBsZW5ndGggYW5kIHVwZGF0ZSB0aGUgdGV4dAogICAgICAgICAgICAgICAgICAgIHRoaXMudGV4dEN1dG9mZkxlbmd0aCA9IE1hdGguZmxvb3IoKHRoaXMubG9uZ2VzdEdvb2QgKyB0aGlzLnNob3J0ZXN0QmFkKSAvIDIpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5uZXJUZXh0ID0gdGhpcy5jb21wbGV0ZVRleHQuc3Vic3RyKDAsIHRoaXMudGV4dEN1dG9mZkxlbmd0aCkgKyAn4oCmJzsKCiAgICAgICAgICAgICAgICAgICAgLy8gQnlwYXNzIHJlYWN0J3MgcmVuZGVyIGxvb3AgZHVyaW5nIHRoZSAiZmx1aWQiIHN0YXRlIGZvciBwZXJmb3JtYW5jZQogICAgICAgICAgICAgICAgICAgIHRoaXNFbGVtZW50LmlubmVyVGV4dCA9IHRoaXMuaW5uZXJUZXh0OwogICAgICAgICAgICAgICAgICAgIGtlZXBNZWFzdXJpbmcgPSB0cnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChrZWVwTWVhc3VyaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnZhbGlkYXRlU2l6ZSgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbmRlclN0YXRlID0gUlNfU1RBQkxFOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZm9yY2VVcGRhdGUoKTsgLy8gUmUtcmVuZGVyIHZpYSByZWFjdCBzbyBpdCBrbm93cyBhYm91dCB1cGRhdGVkIGFscGhhIGFuZCBmaW5hbCBjb250ZW50CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFRydW5jYXRpbmdMYWJlbDsKfShfcmVhY3QuQ29tcG9uZW50KTsKClRydW5jYXRpbmdMYWJlbC5wcm9wVHlwZXMgPSB7CiAgICBjaGlsZHJlbjogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBzdHlsZTogX3JlYWN0LlByb3BUeXBlcy5vYmplY3QsCiAgICBjbGFzc05hbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nCn07Cn0seyJyZWFjdCI6NjIzLCJyZWFjdC1kb20iOjQzMH1dLDkwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuRGlhbG9nID0gZXhwb3J0cy5EaWFsb2dCdXR0b25CYXIgPSBleHBvcnRzLkRpYWxvZ0NvbnRlbnQgPSBleHBvcnRzLkRpYWxvZ0hlYWRlciA9IGV4cG9ydHMuQmFzaWNEaWFsb2cgPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX01vZGFsQ29udGFpbmVyID0gcmVxdWlyZSgnLi9Nb2RhbENvbnRhaW5lcicpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF90b0NvbnN1bWFibGVBcnJheShhcnIpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgeyBmb3IgKHZhciBpID0gMCwgYXJyMiA9IEFycmF5KGFyci5sZW5ndGgpOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7IGFycjJbaV0gPSBhcnJbaV07IH0gcmV0dXJuIGFycjI7IH0gZWxzZSB7IHJldHVybiBBcnJheS5mcm9tKGFycik7IH0gfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vCi8vICBCYXNpYyBEaWFsb2cKLy8KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiBCYXNpYywgYmFyZS1ib25lcyBEaWFsb2cgY29tcG9uZW50OgoKIC0gU2hvdyB0aGUgdXNlciBhIHN0eWxlZCBkaWFsb2csIHdpdGggYW55IGNoaWxkIGNvbnRlbnQgdG8gYmUgc2V0IGJ5IG93bmVyLgogLSBMaXN0ZW4gZm9yIGFuZCByZS1kaXNwYXRjaCB1c2VyIGRpc21pc3MgcmVxdWVzdHMuCgogKi8KdmFyIEJhc2ljRGlhbG9nID0gZXhwb3J0cy5CYXNpY0RpYWxvZyA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoQmFzaWNEaWFsb2csIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIEJhc2ljRGlhbG9nKCkgewogICAgICAgIHZhciBfcmVmOwoKICAgICAgICB2YXIgX3RlbXAsIF90aGlzLCBfcmV0OwoKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQmFzaWNEaWFsb2cpOwoKICAgICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykgewogICAgICAgICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIF9yZXQgPSAoX3RlbXAgPSAoX3RoaXMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoX3JlZiA9IEJhc2ljRGlhbG9nLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoQmFzaWNEaWFsb2cpKS5jYWxsLmFwcGx5KF9yZWYsIFt0aGlzXS5jb25jYXQoYXJncykpKSwgX3RoaXMpLCBfdGhpcy5tb2RhbFNjcmVlbkNsaWNrZWQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBvbkRpc21pc3MgPSBfdGhpcy5wcm9wcy5vbkRpc21pc3M7CgoKICAgICAgICAgICAgaWYgKG9uRGlzbWlzcykgewogICAgICAgICAgICAgICAgb25EaXNtaXNzKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LCBfdGhpcy5rZXlQcmVzc2VkID0gZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgIC8vIFRPRE86IE1vdmUgdGhpcyBpbnRvIE1vZGFsQ29udGFpbmVyLCBhbmQgcmVtb3ZlIGZyb20gUG9wb3ZlciBhcyB3ZWxsIQogICAgICAgICAgICB2YXIgX3RoaXMkcHJvcHMgPSBfdGhpcy5wcm9wcywKICAgICAgICAgICAgICAgIG9uRGlzbWlzcyA9IF90aGlzJHByb3BzLm9uRGlzbWlzcywKICAgICAgICAgICAgICAgIGlnbm9yZUVzY2FwZUtleSA9IF90aGlzJHByb3BzLmlnbm9yZUVzY2FwZUtleTsKCgogICAgICAgICAgICBpZiAoIWlnbm9yZUVzY2FwZUtleSAmJiBvbkRpc21pc3MgJiYgZXZlbnQua2V5Q29kZSA9PT0gMjcpIHsKICAgICAgICAgICAgICAgIG9uRGlzbWlzcygpOwogICAgICAgICAgICB9CiAgICAgICAgfSwgX3RlbXApLCBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihfdGhpcywgX3JldCk7CiAgICB9CgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gIFVzZXIgSW50ZXJhY3Rpb24KICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBfY3JlYXRlQ2xhc3MoQmFzaWNEaWFsb2csIFt7CiAgICAgICAga2V5OiAncmVuZGVyJywKCgogICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAvLyAgUmVhY3QgTGlmZWN5Y2xlCiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcywKICAgICAgICAgICAgICAgIGNsYXNzTmFtZSA9IF9wcm9wcy5jbGFzc05hbWUsCiAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IF9wcm9wcy5jaGlsZHJlbjsKCiAgICAgICAgICAgIHZhciBuZXdDbGFzc05hbWUgPSAoY2xhc3NOYW1lID8gY2xhc3NOYW1lICsgIiAiIDogIiIpICsgJyBEaWFsb2cnOwoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgX01vZGFsQ29udGFpbmVyLk1vZGFsQ29udGFpbmVyLAogICAgICAgICAgICAgICAgeyBvblNjcmVlbkNsaWNrOiB0aGlzLm1vZGFsU2NyZWVuQ2xpY2tlZCB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IG5ld0NsYXNzTmFtZSB9LAogICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2NvbXBvbmVudERpZE1vdW50JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7CiAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoImtleXVwIiwgdGhpcy5rZXlQcmVzc2VkLCBmYWxzZSk7CiAgICAgICAgICAgIC8vIFRPRE86IFJlbW92ZSBmcm9tIGhlcmUgYW5kIFBvcG92ZXIKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY29tcG9uZW50V2lsbFVubW91bnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHsKICAgICAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigia2V5dXAiLCB0aGlzLmtleVByZXNzZWQsIGZhbHNlKTsKICAgICAgICAgICAgLy8gVE9ETzogUmVtb3ZlIGZyb20gaGVyZSBhbmQgUG9wb3ZlcgogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gQmFzaWNEaWFsb2c7Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpCYXNpY0RpYWxvZy5wcm9wVHlwZXMgPSB7CiAgICBvbkRpc21pc3M6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYywKICAgIGlnbm9yZUVzY2FwZUtleTogX3JlYWN0LlByb3BUeXBlcy5ib29sLAogICAgY2hpbGRyZW46IF9yZWFjdC5Qcm9wVHlwZXMubm9kZQp9OwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLwovLyAgRGlhbG9nIEhlYWRlciAvIFRpdGxlIEJhcgovLwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKiogQmFzaWMgaGVhZGVyIGZvciBkaWFsb2dzICovCgp2YXIgRGlhbG9nSGVhZGVyID0gZXhwb3J0cy5EaWFsb2dIZWFkZXIgPSBmdW5jdGlvbiAoX0NvbXBvbmVudDIpIHsKICAgIF9pbmhlcml0cyhEaWFsb2dIZWFkZXIsIF9Db21wb25lbnQyKTsKCiAgICBmdW5jdGlvbiBEaWFsb2dIZWFkZXIoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIERpYWxvZ0hlYWRlcik7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoRGlhbG9nSGVhZGVyLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoRGlhbG9nSGVhZGVyKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKERpYWxvZ0hlYWRlciwgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdEaWFsb2ctaGVhZGVyJyB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2gzJywKICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuY2hpbGRyZW4KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIERpYWxvZ0hlYWRlcjsKfShfcmVhY3QuQ29tcG9uZW50KTsKCkRpYWxvZ0hlYWRlci5wcm9wVHlwZXMgPSB7CiAgICBjaGlsZHJlbjogX3JlYWN0LlByb3BUeXBlcy5ub2RlCn07CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vCi8vICBTY3JvbGxpbmcgQ29udGVudCBQYW5lCi8vCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKiBXcmFwcyB0aGUgY29udGVudCBvZiBhIGRpYWxvZyB0byBwcm92aWRlIGEgc2Nyb2xsYmFyIGlmIHRoZXJlJ3MgdG9vIG11Y2ggdG8gZml0ICovCgp2YXIgRGlhbG9nQ29udGVudCA9IGV4cG9ydHMuRGlhbG9nQ29udGVudCA9IGZ1bmN0aW9uIChfQ29tcG9uZW50MykgewogICAgX2luaGVyaXRzKERpYWxvZ0NvbnRlbnQsIF9Db21wb25lbnQzKTsKCiAgICBmdW5jdGlvbiBEaWFsb2dDb250ZW50KCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBEaWFsb2dDb250ZW50KTsKCiAgICAgICAgcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChEaWFsb2dDb250ZW50Ll9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoRGlhbG9nQ29udGVudCkpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhEaWFsb2dDb250ZW50LCBbewogICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ0RpYWxvZy1jb250ZW50LXNjcm9sbCcgfSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnRGlhbG9nLWNvbnRlbnQtbWFyZ2luJyB9LAogICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuY2hpbGRyZW4KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIERpYWxvZ0NvbnRlbnQ7Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpEaWFsb2dDb250ZW50LnByb3BUeXBlcyA9IHsKICAgIGNoaWxkcmVuOiBfcmVhY3QuUHJvcFR5cGVzLm5vZGUKfTsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8KLy8gIEJ1dHRvbiBiYXIKLy8KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqIEEgY29udGFpbmVyIGZvciBkaWFsb2cgYWN0aW9uIGJ1dHRvbnMgKi8KCnZhciBEaWFsb2dCdXR0b25CYXIgPSBleHBvcnRzLkRpYWxvZ0J1dHRvbkJhciA9IGZ1bmN0aW9uIChfQ29tcG9uZW50NCkgewogICAgX2luaGVyaXRzKERpYWxvZ0J1dHRvbkJhciwgX0NvbXBvbmVudDQpOwoKICAgIGZ1bmN0aW9uIERpYWxvZ0J1dHRvbkJhcigpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRGlhbG9nQnV0dG9uQmFyKTsKCiAgICAgICAgcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChEaWFsb2dCdXR0b25CYXIuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihEaWFsb2dCdXR0b25CYXIpKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoRGlhbG9nQnV0dG9uQmFyLCBbewogICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5wcm9wcy5jaGlsZHJlbjsKCgogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnRGlhbG9nLWJ1dHRvbi1iYXInIH0sCiAgICAgICAgICAgICAgICBjaGlsZHJlbgogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gRGlhbG9nQnV0dG9uQmFyOwp9KF9yZWFjdC5Db21wb25lbnQpOwoKRGlhbG9nQnV0dG9uQmFyLnByb3BUeXBlcyA9IHsKICAgIGNoaWxkcmVuOiBfcmVhY3QuUHJvcFR5cGVzLm5vZGUKfTsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8KLy8gIEVhc3ktdG8tdXNlIERpYWxvZwovLwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKiogQW4gZWFzeS10by11c2UgRGlhbG9nIGNvbXBvbmVudCB3aXRoIGEgdGl0bGUgYW5kIGJ1dHRvbiBiYXIsIGFuZCBzY3JvbGwgcGFuZSBmb3IgY2hpbGRyZW4gKi8KCnZhciBEaWFsb2cgPSBleHBvcnRzLkRpYWxvZyA9IGZ1bmN0aW9uIChfQ29tcG9uZW50NSkgewogICAgX2luaGVyaXRzKERpYWxvZywgX0NvbXBvbmVudDUpOwoKICAgIGZ1bmN0aW9uIERpYWxvZygpIHsKICAgICAgICB2YXIgX3JlZjI7CgogICAgICAgIHZhciBfdGVtcDIsIF90aGlzNSwgX3JldDI7CgogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBEaWFsb2cpOwoKICAgICAgICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBBcnJheShfbGVuMiksIF9rZXkyID0gMDsgX2tleTIgPCBfbGVuMjsgX2tleTIrKykgewogICAgICAgICAgICBhcmdzW19rZXkyXSA9IGFyZ3VtZW50c1tfa2V5Ml07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gX3JldDIgPSAoX3RlbXAyID0gKF90aGlzNSA9IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChfcmVmMiA9IERpYWxvZy5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKERpYWxvZykpLmNhbGwuYXBwbHkoX3JlZjIsIFt0aGlzXS5jb25jYXQoYXJncykpKSwgX3RoaXM1KSwgX3RoaXM1LnVzZXJEaXNtaXNzZWQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBvbkRpc21pc3MgPSBfdGhpczUucHJvcHMub25EaXNtaXNzOwoKICAgICAgICAgICAgaWYgKG9uRGlzbWlzcykgewogICAgICAgICAgICAgICAgb25EaXNtaXNzKF90aGlzNSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LCBfdGVtcDIpLCBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihfdGhpczUsIF9yZXQyKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoRGlhbG9nLCBbewogICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgdmFyIF9wcm9wczIgPSB0aGlzLnByb3BzLAogICAgICAgICAgICAgICAgY2xhc3NOYW1lID0gX3Byb3BzMi5jbGFzc05hbWUsCiAgICAgICAgICAgICAgICB0aXRsZSA9IF9wcm9wczIudGl0bGUsCiAgICAgICAgICAgICAgICBidXR0b25zID0gX3Byb3BzMi5idXR0b25zLAogICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBfcHJvcHMyLmNoaWxkcmVuLAogICAgICAgICAgICAgICAgaWdub3JlRXNjYXBlS2V5ID0gX3Byb3BzMi5pZ25vcmVFc2NhcGVLZXk7CgoKICAgICAgICAgICAgdmFyIGRlZmF1bHRCdXR0b24gPSBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdidXR0b24nLAogICAgICAgICAgICAgICAgeyBvbkNsaWNrOiB0aGlzLnVzZXJEaXNtaXNzZWQgfSwKICAgICAgICAgICAgICAgICdDbG9zZScKICAgICAgICAgICAgKTsKICAgICAgICAgICAgdmFyIGJ1dHRvbkFycmF5ID0gW10uY29uY2F0KGJ1dHRvbnMgfHwgZGVmYXVsdEJ1dHRvbik7CgogICAgICAgICAgICAvLyBEb2luZyB0aGlzIHdpbGwgYXZvaWQgZ2V0dGluZyBhbm5veWluZyBtZXNzYWdlcyBmcm9tIFJlYWN0IGFib3V0IGFycmF5IGtleXMKICAgICAgICAgICAgdmFyIGJ1dHRvbkJhciA9IF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50LmFwcGx5KF9yZWFjdDIuZGVmYXVsdCwgW0RpYWxvZ0J1dHRvbkJhciwge31dLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkoYnV0dG9uQXJyYXkpKSk7CgogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICBCYXNpY0RpYWxvZywKICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBjbGFzc05hbWUsCiAgICAgICAgICAgICAgICAgICAgaWdub3JlRXNjYXBlS2V5OiBpZ25vcmVFc2NhcGVLZXksCiAgICAgICAgICAgICAgICAgICAgb25EaXNtaXNzOiB0aGlzLnVzZXJEaXNtaXNzZWQgfSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgIERpYWxvZ0hlYWRlciwKICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgIHRpdGxlCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgRGlhbG9nQ29udGVudCwKICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgYnV0dG9uQmFyCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBEaWFsb2c7Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpEaWFsb2cucHJvcFR5cGVzID0gewogICAgY2xhc3NOYW1lOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIHRpdGxlOiBfcmVhY3QuUHJvcFR5cGVzLm5vZGUsCiAgICBidXR0b25zOiBfcmVhY3QuUHJvcFR5cGVzLm5vZGUsCiAgICBjaGlsZHJlbjogX3JlYWN0LlByb3BUeXBlcy5ub2RlLAogICAgb25EaXNtaXNzOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsCiAgICBpZ25vcmVFc2NhcGVLZXk6IF9yZWFjdC5Qcm9wVHlwZXMuYm9vbAp9Owp9LHsiLi9Nb2RhbENvbnRhaW5lciI6OTEsInJlYWN0Ijo2MjN9XSw5MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7CiJ1c2Ugc3RyaWN0IjsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLk1vZGFsQ29udGFpbmVyID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgicmVhY3QiKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKLyoqCiBXcmFwcyBjaGlsZHJlbiBpbiBhIC5Nb2RhbENvbnRhaW5lciwgc2hvd3MgYSBkYXJrIHNjcmVlbiBvdmVyIHBhZ2UgY29udGVudCwgYW5kIGxpc3RlbnMgZm9yIHVzZXIgZGlzbWlzcyBldmVudHMuCgogVGhpcyBpcyB3aGVyZSB3ZSdkIHdhbnQgdG8gbWFuYWdlIHNob3cvaGlkZSBhbmltYXRpb24gaWYgd2UgYWRkIHRoZW0gYXQgc29tZSBwb2ludC4KCiBGSVhNRTogSXNvbGF0ZSB0aGUgdGFiLWZvY3VzIGxvb3AgdG8gY2hpbGRyZW4KIEZJWE1FOiBCbG9jayB1c2VyIHNjcm9sbCBpbnB1dCBhdCAuTW9kYWxDb250YWluZXIgb24gY2FwdHVyZQogKi8KdmFyIE1vZGFsQ29udGFpbmVyID0gZXhwb3J0cy5Nb2RhbENvbnRhaW5lciA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoTW9kYWxDb250YWluZXIsIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIE1vZGFsQ29udGFpbmVyKCkgewogICAgICAgIHZhciBfcmVmOwoKICAgICAgICB2YXIgX3RlbXAsIF90aGlzLCBfcmV0OwoKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTW9kYWxDb250YWluZXIpOwoKICAgICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykgewogICAgICAgICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIF9yZXQgPSAoX3RlbXAgPSAoX3RoaXMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoX3JlZiA9IE1vZGFsQ29udGFpbmVyLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoTW9kYWxDb250YWluZXIpKS5jYWxsLmFwcGx5KF9yZWYsIFt0aGlzXS5jb25jYXQoYXJncykpKSwgX3RoaXMpLCBfdGhpcy5zY3JlZW5DbGlja2VkID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgb25TY3JlZW5DbGljayA9IF90aGlzLnByb3BzLm9uU2NyZWVuQ2xpY2s7CgoKICAgICAgICAgICAgaWYgKG9uU2NyZWVuQ2xpY2spIHsKICAgICAgICAgICAgICAgIG9uU2NyZWVuQ2xpY2soX3RoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwgX3RlbXApLCBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihfdGhpcywgX3JldCk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKE1vZGFsQ29udGFpbmVyLCBbewogICAgICAgIGtleTogInJlbmRlciIsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgImRpdiIsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogIk1vZGFsQ29udGFpbmVyIiB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoImRpdiIsIHsgY2xhc3NOYW1lOiAiTW9kYWxDb250YWluZXItbW9kYWxTY3JlZW4iLCBvbkNsaWNrOiB0aGlzLnNjcmVlbkNsaWNrZWQgfSksCiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmNoaWxkcmVuCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBNb2RhbENvbnRhaW5lcjsKfShfcmVhY3QuQ29tcG9uZW50KTsKCk1vZGFsQ29udGFpbmVyLnByb3BUeXBlcyA9IHsKICAgIG9uU2NyZWVuQ2xpY2s6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYywKICAgIGNoaWxkcmVuOiBfcmVhY3QuUHJvcFR5cGVzLmVsZW1lbnQuaXNSZXF1aXJlZAp9OwoKZXhwb3J0cy5kZWZhdWx0ID0gTW9kYWxDb250YWluZXI7Cn0seyJyZWFjdCI6NjIzfV0sOTI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKCnZhciBfTW9kYWxDb250YWluZXIgPSByZXF1aXJlKCcuL01vZGFsQ29udGFpbmVyJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ01vZGFsQ29udGFpbmVyJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfTW9kYWxDb250YWluZXIuTW9kYWxDb250YWluZXI7CiAgICB9Cn0pOwoKdmFyIF9EaWFsb2cgPSByZXF1aXJlKCcuL0RpYWxvZycpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdCYXNpY0RpYWxvZycsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX0RpYWxvZy5CYXNpY0RpYWxvZzsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnRGlhbG9nSGVhZGVyJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfRGlhbG9nLkRpYWxvZ0hlYWRlcjsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnRGlhbG9nQ29udGVudCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX0RpYWxvZy5EaWFsb2dDb250ZW50OwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdEaWFsb2dCdXR0b25CYXInLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9EaWFsb2cuRGlhbG9nQnV0dG9uQmFyOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdEaWFsb2cnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9EaWFsb2cuRGlhbG9nOwogICAgfQp9KTsKfSx7Ii4vRGlhbG9nIjo5MCwiLi9Nb2RhbENvbnRhaW5lciI6OTF9XSw5MzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLkZhdm9yaXRlID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9DaGVja2JveCA9IHJlcXVpcmUoJy4uL2Zvcm1zL0NoZWNrYm94Jyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9Cgp2YXIgRmF2b3JpdGUgPSBleHBvcnRzLkZhdm9yaXRlID0gZnVuY3Rpb24gKF9Db21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhGYXZvcml0ZSwgX0NvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gRmF2b3JpdGUoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEZhdm9yaXRlKTsKCiAgICAgICAgcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChGYXZvcml0ZS5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKEZhdm9yaXRlKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKEZhdm9yaXRlLCBbewogICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7CgogICAgICAgICAgICB2YXIgZXh0cmFDbGFzcyA9IHRoaXMucHJvcHMuY2xhc3NOYW1lIHx8ICcnOwoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgX0NoZWNrYm94LkNoZWNrYm94LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlZjogZnVuY3Rpb24gcmVmKGNoZWNrYm94KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMi5jaGVja2JveCA9IGNoZWNrYm94OwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnRmF2b3JpdGUgJyArIGV4dHJhQ2xhc3MsCiAgICAgICAgICAgICAgICAgICAgY2hlY2tlZDogdGhpcy5wcm9wcy5jaGVja2VkLAogICAgICAgICAgICAgICAgICAgIG9uVG9nZ2xlOiB0aGlzLnByb3BzLm9uVG9nZ2xlLAogICAgICAgICAgICAgICAgICAgIGxhYmVsOiB0aGlzLnByb3BzLmxhYmVsCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoRmF2b3JpdGVTdGFyU3ZnLCBudWxsKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjaGVja2VkJywKICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2hlY2tib3guY2hlY2tlZDsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIEZhdm9yaXRlOwp9KF9yZWFjdC5Db21wb25lbnQpOwoKRmF2b3JpdGUuZGVmYXVsdFByb3BzID0gewogICAgY2hlY2tlZDogZmFsc2UsCiAgICBjbGFzc05hbWU6ICcnCn07CgoKRmF2b3JpdGUucHJvcFR5cGVzID0gewogICAgY2xhc3NOYW1lOiBfcmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsnJywgJ2RhcmsteWVsbG93JywgJ2Rhcmstd2hpdGUnXSksCiAgICBjaGVja2VkOiBfcmVhY3QuUHJvcFR5cGVzLmJvb2wsCiAgICBsYWJlbDogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBvblRvZ2dsZTogX3JlYWN0LlByb3BUeXBlcy5mdW5jCn07CgovKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovCmZ1bmN0aW9uIEZhdm9yaXRlU3RhclN2ZygpIHsKICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAnc3ZnJywKICAgICAgICB7IGNsYXNzTmFtZTogJ3N0YXItaWNvbicsIHdpZHRoOiAnMjg4JywgaGVpZ2h0OiAnMjQnLCB2aWV3Qm94OiAnMCAwIDI4OCAyNCcsIHhtbG5zOiAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLAogICAgICAgICAgICBmb2N1c2FibGU6ICdmYWxzZScKICAgICAgICB9LAogICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAndGl0bGUnLAogICAgICAgICAgICBudWxsLAogICAgICAgICAgICAnc3RhcnMgZm9yIGxpZ2h0IGJhY2tncm91bmQnCiAgICAgICAgKSwKICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgJ2cnLAogICAgICAgICAgICB7IGZpbGw6ICdub25lJywgZmlsbFJ1bGU6ICdldmVub2RkJyB9LAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgY2xhc3NOYW1lOiAnc3Rhci1lbXB0eScsIGQ6ICdNMjIgOS4yNGwtNy4xOS0uNjJMMTIgMiA5LjE5IDguNjMgMiA5LjI0bDUuNDYgNC43M0w1LjgyIDIxIDEyIDE3LjI3IDE4LjE4IDIxbC0xLjYzLTcuMDNMMjIgOS4yNHpNMTIgMTUuNGwtMy43NiAyLjI3IDEtNC4yOC0zLjMyLTIuODggNC4zOC0uMzhMMTIgNi4xbDEuNzEgNC4wNCA0LjM4LjM4LTMuMzIgMi44OCAxIDQuMjhMMTIgMTUuNHonLCBmaWxsOiAnIzRBOTBFMicgfSksCiAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTTAgMGgyNHYyNEgwVjB6TTQ5LTFoMjR2MjRINDlWLTF6JyB9KSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNNDktMWgyNHYyNEg0OVYtMXpNMTQ0IDBoMjR2MjRoLTI0VjB6JyB9KSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNMTQ0IDBoMjR2MjRoLTI0VjB6JyB9KSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnZycsCiAgICAgICAgICAgICAgICB7IHN0cm9rZTogJyNGNUE2MjMnLCBzdHJva2VXaWR0aDogJy44Jywgc3Ryb2tlTGluZWNhcDogJ3NxdWFyZScgfSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTTE1MyA4bC0xLjUtMS41TTE1OSA4bDEuNS0xLjVNMTUxLjA1MSAxNC4wNTRsLTEuNTc2IDEuNDJNMTYyLjQ2IDE1LjAzOEwxNjEgMTRNMTU1LjY5MSAxOC44NDlsLjAyLTEuMTInIH0pCiAgICAgICAgICAgICksCiAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTTE1NiAxNS42ODlsNC4zMjYgMi42MTEtMS4xNDgtNC45MjFMMTYzIDEwLjA2OGwtNS4wMzMtLjQyN0wxNTYgNWwtMS45NjcgNC42NDEtNS4wMzMuNDI3IDMuODIyIDMuMzExLTEuMTQ4IDQuOTIxTDE1NiAxNS42ODl6JywgZmlsbDogJyNGNUE2MjMnIH0pLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgZDogJ00yNCAwaDI0djI0SDI0VjB6JyB9KSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNMjQgMGgyNHYyNEgyNFYweicgfSksCiAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTTM2IDE0LjYzNWwzLjA5IDEuODY1LS44Mi0zLjUxNUw0MSAxMC42MmwtMy41OTUtLjMwNUwzNiA3bC0xLjQwNSAzLjMxNUwzMSAxMC42MmwyLjczIDIuMzY1LS44MiAzLjUxNUwzNiAxNC42MzV6JywgZmlsbDogJyNGNUE2MjMnLCBvcGFjaXR5OiAnLjcyJyB9KSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNNDggMGgyNHYyNEg0OFYweicgfSksCiAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTTQ4IDBoMjR2MjRINDhWMHonIH0pLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgZDogJ002MC41IDE1LjM5OWwzLjM5OSAyLjA1MS0uOTAyLTMuODY2TDY2IDEwLjk4MmwtMy45NTQtLjMzNUw2MC41IDdsLTEuNTQ2IDMuNjQ2LTMuOTU0LjMzNiAzLjAwMyAyLjYwMi0uOTAyIDMuODY2IDMuMzk5LTIuMDUxeicsIGZpbGw6ICcjRjVBNjIzJywgb3BhY2l0eTogJy44MicgfSksCiAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTTcyIDBoMjR2MjRINzJWMHonIH0pLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgZDogJ003MiAwaDI0djI0SDcyVjB6JyB9KSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNODQgMTUuMTYybDMuNzA4IDIuMjM4LS45ODQtNC4yMThMOTAgMTAuMzQ0bC00LjMxNC0uMzY2TDg0IDZsLTEuNjg2IDMuOTc4LTQuMzE0LjM2NiAzLjI3NiAyLjgzOC0uOTg0IDQuMjE4TDg0IDE1LjE2MnonLCBmaWxsOiAnI0Y1QTYyMycsIG9wYWNpdHk6ICcuODUnIH0pLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgZDogJ005NiAwaDI0djI0SDk2VjB6JyB9KSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNOTYgMGgyNHYyNEg5NlYweicgfSksCiAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTTEwOC41IDE1LjkyNWw0LjAxNyAyLjQyNS0xLjA2Ni00LjU3TDExNSAxMC43MDdsLTQuNjc0LS4zOTZMMTA4LjUgNmwtMS44MjYgNC4zMS00LjY3NC4zOTYgMy41NDkgMy4wNzUtMS4wNjYgNC41NjkgNC4wMTctMi40MjV6JywgZmlsbDogJyNGNUE2MjMnIH0pLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdnJywKICAgICAgICAgICAgICAgIHsgc3Ryb2tlOiAnI0Y1QTYyMycsIHN0cm9rZVdpZHRoOiAnLjUnLCBzdHJva2VMaW5lY2FwOiAnc3F1YXJlJyB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNMTA3IDExbC0xLjUtMS41TTExMCAxMWwxLjUtMS41TTEwNi4wNTEgMTMuMDU0bC0xLjU3NiAxLjQyTTExMi40NiAxNC4wMzhMMTExIDEzTTEwOC42OTEgMTYuODQ5bC4wMi0xLjEyJyB9KQogICAgICAgICAgICApLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdnJywKICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgZDogJ00xMjAgMGgyNHYyNGgtMjRWMHonIH0pLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNMTIwIDBoMjR2MjRoLTI0VjB6JyB9KSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTTEzMS43NSAxNS4zMDdsNC4xNzEgMi41MTgtMS4xMDYtNC43NDUgMy42ODUtMy4xOTMtNC44NTMtLjQxMkwxMzEuNzUgNWwtMS44OTcgNC40NzUtNC44NTMuNDEyIDMuNjg1IDMuMTkzLTEuMTA3IDQuNzQ1IDQuMTcyLTIuNTE4eicsIGZpbGw6ICcjRjVBNjIzJyB9KSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICdnJywKICAgICAgICAgICAgICAgICAgICB7IHN0cm9rZTogJyNGNUE2MjMnLCBzdHJva2VXaWR0aDogJy41Jywgc3Ryb2tlTGluZWNhcDogJ3NxdWFyZScgfSwKICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgZDogJ00xMjkgOGwtMS41LTEuNU0xMzUgOGwxLjUtMS41TTEyNy4wNTEgMTQuMDU0bC0xLjQxMiAxLjI3MU0xMzguNDYgMTUuMDM4TDEzNyAxNE0xMzEuNjkxIDE4Ljg0OWwuMDItMS4xMicgfSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnZycsCiAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNMTY4IDBoMjR2MjRoLTI0VjB6JyB9KSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTTE2OCAwaDI0djI0aC0yNFYweicgfSksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAnZycsCiAgICAgICAgICAgICAgICAgICAgeyBzdHJva2U6ICcjRjVBNjIzJywgc3Ryb2tlV2lkdGg6ICcuOCcsIHN0cm9rZUxpbmVjYXA6ICdzcXVhcmUnIH0sCiAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNMTc3IDhsLTEuNS0xLjVNMTgzIDhsMS41LTEuNU0xNzUuMDUxIDE0LjA1NGwtMS41NzYgMS40Mk0xODYuNDYgMTUuMDM4TDE4NSAxNE0xODAuMzk2IDE4Ljg0OWwuMDA4LTEuMTInIH0pCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNMTgwIDE2Ljc0M2w1LjU2MiAzLjM1Ny0xLjQ3Ni02LjMyN0wxODkgOS41MTZsLTYuNDcxLS41NDlMMTgwIDNsLTIuNTI5IDUuOTY3LTYuNDcxLjU0OSA0LjkxNCA0LjI1Ny0xLjQ3NiA2LjMyN0wxODAgMTYuNzQzeicsIGZpbGw6ICcjRjVBNjIzJyB9KQogICAgICAgICAgICApLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdnJywKICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgZDogJ00xOTIgMGgyNHYyNGgtMjRWMHonIH0pLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNMjA0IDE3LjI3bDYuMTggMy43My0xLjY0LTcuMDNMMjE0IDkuMjRsLTcuMTktLjYxTDIwNCAybC0yLjgxIDYuNjMtNy4xOS42MSA1LjQ2IDQuNzMtMS42NCA3LjAzIDYuMTgtMy43M3onLCBmaWxsOiAnI0Y1QTYyMycgfSksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgZDogJ00xOTIgMGgyNHYyNGgtMjRWMHonIH0pLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2cnLAogICAgICAgICAgICAgICAgICAgIHsgc3Ryb2tlOiAnI0Y1QTYyMycsIHN0cm9rZUxpbmVjYXA6ICdzcXVhcmUnIH0sCiAgICAgICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNMjAxIDhsLTEuNS0xLjVNMjA3IDhsMS41LTEuNU0xOTkuMDUxIDE0LjA1NGwtMS41NzYgMS40Mk0yMTAuNDYgMTUuMDM4TDIwOSAxNE0yMDMuNDk1IDE4Ljg0OWwuMDEtMS4xMicgfSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnZycsCiAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNMjE2IDBoMjR2MjRoLTI0VjB6JyB9KSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTTIyOCAxOC4zMjRsNy40MTYgNC40NzYtMS45NjgtOC40MzZMMjQwIDguNjg4bC04LjYyOC0uNzMyTDIyOCAwbC0zLjM3MiA3Ljk1Ni04LjYyOC43MzIgNi41NTIgNS42NzYtMS45NjggOC40MzZMMjI4IDE4LjMyNHonLCBmaWxsOiAnI0Y1QTYyMycgfSksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgZDogJ00yMTYgMGgyNHYyNGgtMjRWMHonIH0pCiAgICAgICAgICAgICksCiAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2cnLAogICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTTI2NCAwaDI0djI0aC0yNFYweicgfSksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgY2xhc3NOYW1lOiAnc3Rhci1maWxsZWQnLCBkOiAnTTI3NiAxNy4yN2w2LjE4IDMuNzMtMS42NC03LjAzTDI4NiA5LjI0bC03LjE5LS42MUwyNzYgMmwtMi44MSA2LjYzLTcuMTkuNjEgNS40NiA0LjczLTEuNjQgNy4wMyA2LjE4LTMuNzN6JywgZmlsbDogJyNGNUE2MjMnIH0pLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNMjY0IDBoMjR2MjRoLTI0VjB6JyB9KQogICAgICAgICAgICApLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdnJywKICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgZDogJ00yNDAgMGgyNHYyNGgtMjRWMHonIH0pLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGQ6ICdNMjUyIDE3Ljc5N2w2Ljc5OCA0LjEwMy0xLjgwNC03LjczM0wyNjMgOC45NjRsLTcuOTA5LS42NzFMMjUyIDFsLTMuMDkxIDcuMjkzLTcuOTA5LjY3MSA2LjAwNiA1LjIwMy0xLjgwNCA3LjczM0wyNTIgMTcuNzk3eicsIGZpbGw6ICcjRjVBNjIzJyB9KSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdwYXRoJywgeyBkOiAnTTI0MCAwaDI0djI0aC0yNFYweicgfSkKICAgICAgICAgICAgKSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ2NpcmNsZScsIHsgc3Ryb2tlOiAnI0Y1QTYyMycsIHN0cm9rZVdpZHRoOiAnLjUnLCBjeDogJzE1NicsIGN5OiAnMTInLCByOiAnOCcgfSksCiAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdjaXJjbGUnLCB7IHN0cm9rZTogJyNGNUE2MjMnLCBzdHJva2VXaWR0aDogJy4zJywgY3g6ICcxODAnLCBjeTogJzEyJywgcjogJzEwJyB9KSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ2NpcmNsZScsIHsgc3Ryb2tlOiAnI0Y1QTYyMycsIHN0cm9rZVdpZHRoOiAnLjEnLCBjeDogJzIwNCcsIGN5OiAnMTInLCByOiAnMTEnIH0pLAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgnY2lyY2xlJywgeyBzdHJva2U6ICcjRjVBNjIzJywgc3Ryb2tlV2lkdGg6ICcuOCcsIGN4OiAnMTMyJywgY3k6ICcxMicsIHI6ICc3JyB9KSwKICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ2NpcmNsZScsIHsgc3Ryb2tlOiAnI0Y1QTYyMycsIGN4OiAnMTA4LjUnLCBjeTogJzEyLjUnLCByOiAnNS41JyB9KQogICAgICAgICkKICAgICk7Cn0KfSx7Ii4uL2Zvcm1zL0NoZWNrYm94Ijo5NCwicmVhY3QiOjYyM31dLDk0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuQ2hlY2tib3ggPSB1bmRlZmluZWQ7Cgp2YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9OwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9yZWFjdE1hdGVyaWFsSWNvbnMgPSByZXF1aXJlKCdAamVua2lucy1jZC9yZWFjdC1tYXRlcmlhbC1pY29ucycpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKdmFyIENoZWNrYm94ID0gZXhwb3J0cy5DaGVja2JveCA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoQ2hlY2tib3gsIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIENoZWNrYm94KCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDaGVja2JveCk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoQ2hlY2tib3guX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihDaGVja2JveCkpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhDaGVja2JveCwgW3sKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsTW91bnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsTW91bnQoKSB7CiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVN0YXRlKHRoaXMucHJvcHMpOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhwcm9wcykgewogICAgICAgICAgICB0aGlzLl91cGRhdGVTdGF0ZShwcm9wcyk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ191cGRhdGVTdGF0ZScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF91cGRhdGVTdGF0ZShwcm9wcykgewogICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsKICAgICAgICAgICAgICAgIGNoZWNrZWQ6IHByb3BzLmNoZWNrZWQKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ190b2dnbGUnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfdG9nZ2xlKGUpIHsKICAgICAgICAgICAgaWYgKGUudGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkgewogICAgICAgICAgICAgICAgdmFyIF9jaGVja2VkID0gZS50YXJnZXQuY2hlY2tlZDsKCiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsKICAgICAgICAgICAgICAgICAgICBjaGVja2VkOiBfY2hlY2tlZAogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMub25Ub2dnbGUpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLm9uVG9nZ2xlKF9jaGVja2VkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBleHRyYUNsYXNzID0gdGhpcy5wcm9wcy5jbGFzc05hbWUgfHwgJyc7CgogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnQ2hlY2tib3ggJyArIGV4dHJhQ2xhc3MgfSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICdsYWJlbCcsCiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdDaGVja2JveC13cmFwcGVyJywKICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljazogZnVuY3Rpb24gb25DbGljayhldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgnaW5wdXQnLCBfZXh0ZW5kcyh7IHR5cGU6ICdjaGVja2JveCcKICAgICAgICAgICAgICAgICAgICB9LCB7IG5hbWU6IHRoaXMucHJvcHMubmFtZSB9LCB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlOiB0aGlzLl90b2dnbGUuYmluZCh0aGlzKSwKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZDogdGhpcy5zdGF0ZS5jaGVja2VkLAogICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZDogdGhpcy5wcm9wcy5kaXNhYmxlZAogICAgICAgICAgICAgICAgICAgIH0pKSwKICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnQ2hlY2tib3gtaW5kaWNhdG9yJyB9LAogICAgICAgICAgICAgICAgICAgICAgICAhdGhpcy5wcm9wcy5jaGlsZHJlbiA/IF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KF9yZWFjdE1hdGVyaWFsSWNvbnMuSWNvbiwgeyBpY29uOiAnY2hlY2snIH0pIDogdGhpcy5wcm9wcy5jaGlsZHJlbgogICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5sYWJlbCAmJiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnQ2hlY2tib3gtdGV4dCcgfSwKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5sYWJlbAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY2hlY2tlZCcsCiAgICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXRlLmNoZWNrZWQ7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBDaGVja2JveDsKfShfcmVhY3QuQ29tcG9uZW50KTsKCkNoZWNrYm94LmRlZmF1bHRQcm9wcyA9IHsKICAgIGNsYXNzTmFtZTogJycsCiAgICBjaGVja2VkOiBmYWxzZQp9OwoKCkNoZWNrYm94LnByb3BUeXBlcyA9IHsKICAgIGNoaWxkcmVuOiBfcmVhY3QuUHJvcFR5cGVzLm5vZGUsCiAgICBjbGFzc05hbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgbGFiZWw6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgbmFtZTogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBjaGVja2VkOiBfcmVhY3QuUHJvcFR5cGVzLmJvb2wsCiAgICBkaXNhYmxlZDogX3JlYWN0LlByb3BUeXBlcy5ib29sLAogICAgb25Ub2dnbGU6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYwp9Owp9LHsiQGplbmtpbnMtY2QvcmVhY3QtbWF0ZXJpYWwtaWNvbnMiOjEyOSwicmVhY3QiOjYyM31dLDk1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuRHJvcGRvd24gPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX2xvZGFzaCA9IHJlcXVpcmUoJ2xvZGFzaC5kZWJvdW5jZScpOwoKdmFyIF9sb2Rhc2gyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbG9kYXNoKTsKCnZhciBfcmVhY3RNYXRlcmlhbEljb25zID0gcmVxdWlyZSgnQGplbmtpbnMtY2QvcmVhY3QtbWF0ZXJpYWwtaWNvbnMnKTsKCnZhciBfRmxvYXRpbmdFbGVtZW50ID0gcmVxdWlyZSgnLi4vRmxvYXRpbmdFbGVtZW50Jyk7Cgp2YXIgX0tleUNvZGVzID0gcmVxdWlyZSgnLi4vLi4vS2V5Q29kZXMnKTsKCnZhciBfS2V5Q29kZXMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfS2V5Q29kZXMpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKdmFyIFBPU0lUSU9OID0gewogICAgRklSU1Q6ICdmaXJzdCcsCiAgICBQUkVWOiAncHJldicsCiAgICBORVhUOiAnbmV4dCcsCiAgICBMQVNUOiAnbGFzdCcsCgogICAgdmFsdWVzOiBmdW5jdGlvbiB2YWx1ZXMoKSB7CiAgICAgICAgcmV0dXJuIFtQT1NJVElPTi5GSVJTVCwgUE9TSVRJT04uUFJFViwgUE9TSVRJT04uTkVYVCwgUE9TSVRJT04uTEFTVF07CiAgICB9Cn07Cgp2YXIgRHJvcGRvd24gPSBleHBvcnRzLkRyb3Bkb3duID0gZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhEcm9wZG93biwgX1JlYWN0JENvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gRHJvcGRvd24ocHJvcHMpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRHJvcGRvd24pOwoKICAgICAgICB2YXIgX3RoaXMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoRHJvcGRvd24uX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihEcm9wZG93bikpLmNhbGwodGhpcywgcHJvcHMpKTsKCiAgICAgICAgX3RoaXMuX29uRHJvcGRvd25Nb3VzZUV2ZW50ID0gZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdfb25Ecm9wZG93bk1vdXNlRXZlbnQnKTsKICAgICAgICAgICAgLy8gcHJldmVudCBuYXZpZ2F0aW9uIGlmIGFuY2hvciB3YXMgY2xpY2tlZAogICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICBfdGhpcy5fdG9nZ2xlRHJvcGRvd25NZW51KCk7CiAgICAgICAgfTsKCiAgICAgICAgX3RoaXMuX2hhbmRsZUtleUV2ZW50ID0gZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdfaGFuZGxlS2V5RXZlbnQnLCB0aGlzLnN0YXRlLm1lbnVPcGVuKTsKICAgICAgICAgICAgaWYgKCFfdGhpcy5zdGF0ZS5tZW51T3BlbikgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIga2V5Q29kZSA9IGV2ZW50LmtleUNvZGU7CgoKICAgICAgICAgICAgc3dpdGNoIChrZXlDb2RlKSB7CiAgICAgICAgICAgICAgICBjYXNlIF9LZXlDb2RlczIuZGVmYXVsdC5UQUI6CiAgICAgICAgICAgICAgICAgICAgLy8gdGFiYmluZyB3aGlsZSBvcGVuIHdpbGwgYWR2YW5jZSB0byB0aGUgbmV4dCBlbGVtZW50IGFmdGVyIHRoaXMgRHJvcGRvd24KICAgICAgICAgICAgICAgICAgICBfdGhpcy5fY2xvc2VEcm9wZG93bk1lbnUoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgX0tleUNvZGVzMi5kZWZhdWx0LkVTQzoKICAgICAgICAgICAgICAgICAgICBfdGhpcy5fY2xvc2VEcm9wZG93bk1lbnUoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIC8vIGRvbid0IGxldCBhcnJvdyBrZXlzIHNjcm9sbCB0aGUgY29udGVudDsgZm9jdXMgY2hhbmdlIHdpbGwgZG8gdGhhdCBmb3IgdXMKICAgICAgICAgICAgICAgIGNhc2UgX0tleUNvZGVzMi5kZWZhdWx0LkFSUk9XX0RPV046CiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgICAgICBfdGhpcy5fY2hhbmdlRm9jdXNQb3NpdGlvbihQT1NJVElPTi5ORVhUKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgX0tleUNvZGVzMi5kZWZhdWx0LkFSUk9XX1VQOgogICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgX3RoaXMuX2NoYW5nZUZvY3VzUG9zaXRpb24oUE9TSVRJT04uUFJFVik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvLyBwYWdlL3VwIGRvd24gc2Nyb2xscyBhcyBub3JtYWwgYnV0IGFwcGxpZXMgZm9jdXMKICAgICAgICAgICAgICAgIGNhc2UgX0tleUNvZGVzMi5kZWZhdWx0LlBBR0VfRE9XTjoKICAgICAgICAgICAgICAgIGNhc2UgX0tleUNvZGVzMi5kZWZhdWx0LlBBR0VfVVA6CiAgICAgICAgICAgICAgICAgICAgX3RoaXMuX3N5bmNGb2N1c0FmdGVyU2Nyb2xsKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIF9LZXlDb2RlczIuZGVmYXVsdC5IT01FOgogICAgICAgICAgICAgICAgICAgIF90aGlzLl9jaGFuZ2VGb2N1c1Bvc2l0aW9uKFBPU0lUSU9OLkZJUlNUKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgX0tleUNvZGVzMi5kZWZhdWx0LkVORDoKICAgICAgICAgICAgICAgICAgICBfdGhpcy5fY2hhbmdlRm9jdXNQb3NpdGlvbihQT1NJVElPTi5MQVNUKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgX0tleUNvZGVzMi5kZWZhdWx0LlNQQUNFQkFSOgogICAgICAgICAgICAgICAgY2FzZSBfS2V5Q29kZXMyLmRlZmF1bHQuRU5URVI6CiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgICAgICBfdGhpcy5fc2VsZWN0Rm9jdXNlZEl0ZW0oKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBfdGhpcy5faGFuZGxlTW91c2VFdmVudCA9IGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAvLyBjb25zb2xlLmxvZygiX2hhbmRsZU1vdXNlRXZlbnQiKTsKICAgICAgICAgICAgdmFyIGNsaWVudFggPSBldmVudC5jbGllbnRYLAogICAgICAgICAgICAgICAgY2xpZW50WSA9IGV2ZW50LmNsaWVudFk7CgoKICAgICAgICAgICAgaWYgKF90aGlzLnN0YXRlLm1lbnVPcGVuKSB7CiAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoY2xpZW50WCwgY2xpZW50WSk7CgogICAgICAgICAgICAgICAgLy8gY2xvc2UgdGhlIGRyb3Bkb3duIG9ubHkgaWYgdGhlIHVzZXIgY2xpY2tlZCAib3V0c2lkZSIgb2YgaXQKICAgICAgICAgICAgICAgIC8vIChvbmx5IGlmIHRoZSBidXR0b24sIHRodW1iIGFuZCBtZW51IHdhcyBub3QgY2xpY2tlZCkKICAgICAgICAgICAgICAgIC8vIGNsaWNraW5nIHRob3NlIGVsZW1lbnRzIHdpbGwgYWN0dWFsbHkgY2xvc2UgdGhlIGl0IHZpYSBkaWZmZXJlbnQgbWVhbnMKICAgICAgICAgICAgICAgIHZhciBjbGlja2VkT3V0c2lkZURyb3Bkb3duID0gIV90aGlzLmJ1dHRvblJlZi5jb250YWlucyhlbGVtZW50KSAmJiAhX3RoaXMudGh1bWJSZWYuY29udGFpbnMoZWxlbWVudCkgJiYgIV90aGlzLm1lbnVSZWYuY29udGFpbnMoZWxlbWVudCk7CgogICAgICAgICAgICAgICAgaWYgKGNsaWNrZWRPdXRzaWRlRHJvcGRvd24pIHsKICAgICAgICAgICAgICAgICAgICBfdGhpcy5fY2xvc2VEcm9wZG93bk1lbnUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIF90aGlzLl9vbk1lbnVTY3JvbGxFdmVudCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgX3RoaXMuX3N5bmNGb2N1c0FmdGVyU2Nyb2xsKCk7CiAgICAgICAgfTsKCiAgICAgICAgX3RoaXMuX3N5bmNGb2N1c0FmdGVyU2Nyb2xsID0gKDAsIF9sb2Rhc2gyLmRlZmF1bHQpKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKF90aGlzLm1lbnVSZWYuc2Nyb2xsVG9wID09PSBfdGhpcy5sYXN0U2Nyb2xsVG9wKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBzY3JvbGxEb3duID0gX3RoaXMubWVudVJlZi5zY3JvbGxUb3AgPiBfdGhpcy5sYXN0U2Nyb2xsVG9wOwogICAgICAgICAgICBfdGhpcy5sYXN0U2Nyb2xsVG9wID0gX3RoaXMubWVudVJlZi5zY3JvbGxUb3A7CiAgICAgICAgICAgIHZhciByZWN0ID0gX3RoaXMubWVudVJlZi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgICAgICAgdmFyIG5leHRGb2N1c0l0ZW0gPSBzY3JvbGxEb3duID8gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChyZWN0LmxlZnQgKyAxLCByZWN0LnRvcCArIHJlY3QuaGVpZ2h0IC0gMikgOiBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KHJlY3QubGVmdCArIDEsIHJlY3QudG9wICsgMSk7CgogICAgICAgICAgICBfdGhpcy5fZm9jdXNMaXN0SXRlbShuZXh0Rm9jdXNJdGVtLnBhcmVudE5vZGUpOwogICAgICAgIH0sIDIwMCk7CgoKICAgICAgICBfdGhpcy5idXR0b25SZWYgPSBudWxsOwogICAgICAgIF90aGlzLnRodW1iUmVmID0gbnVsbDsKICAgICAgICBfdGhpcy5tZW51UmVmID0gbnVsbDsKICAgICAgICBfdGhpcy5sYXN0U2Nyb2xsVG9wID0gMDsKCiAgICAgICAgX3RoaXMuc3RhdGUgPSB7CiAgICAgICAgICAgIG1lbnVPcGVuOiBmYWxzZSwKICAgICAgICAgICAgc2VsZWN0ZWRPcHRpb246IG51bGwKICAgICAgICB9OwogICAgICAgIHJldHVybiBfdGhpczsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoRHJvcGRvd24sIFt7CiAgICAgICAga2V5OiAnY29tcG9uZW50V2lsbE1vdW50JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbE1vdW50KCkgewogICAgICAgICAgICB0aGlzLl9kZWZhdWx0U2VsZWN0aW9uKHRoaXMucHJvcHMpOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjb21wb25lbnREaWRNb3VudCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkgewogICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5faGFuZGxlS2V5RXZlbnQpOwogICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLl9oYW5kbGVNb3VzZUV2ZW50KTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY29tcG9uZW50RGlkVXBkYXRlJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wcywgcHJldlN0YXRlKSB7CiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLm1lbnVPcGVuICYmICFwcmV2U3RhdGUubWVudU9wZW4pIHsKICAgICAgICAgICAgICAgIHRoaXMuX3NldEluaXRpYWxGb2N1cygpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2NvbXBvbmVudFdpbGxVbm1vdW50JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7CiAgICAgICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLl9oYW5kbGVLZXlFdmVudCk7CiAgICAgICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMuX2hhbmRsZU1vdXNlRXZlbnQpOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfZGVmYXVsdFNlbGVjdGlvbicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9kZWZhdWx0U2VsZWN0aW9uKHByb3BzKSB7CiAgICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZE9wdGlvbiAmJiBwcm9wcy5kZWZhdWx0T3B0aW9uKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsKICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZE9wdGlvbjogcHJvcHMuZGVmYXVsdE9wdGlvbgogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX3RvZ2dsZURyb3Bkb3duTWVudScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF90b2dnbGVEcm9wZG93bk1lbnUoKSB7CiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLm1lbnVPcGVuKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9jbG9zZURyb3Bkb3duTWVudSgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5fb3BlbkRyb3Bkb3duTWVudSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ19vcGVuRHJvcGRvd25NZW51JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX29wZW5Ecm9wZG93bk1lbnUoKSB7CiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoewogICAgICAgICAgICAgICAgbWVudU9wZW46IHRydWUKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ19jbG9zZURyb3Bkb3duTWVudScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9jbG9zZURyb3Bkb3duTWVudSgpIHsKICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7CiAgICAgICAgICAgICAgICBtZW51T3BlbjogZmFsc2UKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAvLyAobm90ZTogYWxzbyB0cmlnZ2VyZWQgdmlhIHNwYWNlYmFyIHByZXNzIHdoZW4gYnV0dG9uIGhhcyBmb2N1cykKCiAgICB9LCB7CiAgICAgICAga2V5OiAnX3NldEluaXRpYWxGb2N1cycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9zZXRJbml0aWFsRm9jdXMoKSB7CiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdfc2V0SW5pdGlhbEZvY3VzJyk7CiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkT3B0aW9uKSB7CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWRJbmRleCA9IHRoaXMucHJvcHMub3B0aW9ucy5pbmRleE9mKHRoaXMuc3RhdGUuc2VsZWN0ZWRPcHRpb24pOwogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkTGlzdEl0ZW0gPSB0aGlzLm1lbnVSZWYuY2hpbGRyZW5bc2VsZWN0ZWRJbmRleF07CiAgICAgICAgICAgICAgICB0aGlzLl9mb2N1c0xpc3RJdGVtKHNlbGVjdGVkTGlzdEl0ZW0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5fY2hhbmdlRm9jdXNQb3NpdGlvbihQT1NJVElPTi5GSVJTVCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX2NoYW5nZUZvY3VzUG9zaXRpb24nLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfY2hhbmdlRm9jdXNQb3NpdGlvbihwb3NpdGlvbikgewogICAgICAgICAgICBpZiAoUE9TSVRJT04udmFsdWVzKCkuaW5kZXhPZihwb3NpdGlvbikgPT09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PT0gUE9TSVRJT04uRklSU1QgfHwgIXRoaXMubWVudVJlZi5jb250YWlucyhkb2N1bWVudC5hY3RpdmVFbGVtZW50KSkgewogICAgICAgICAgICAgICAgdmFyIGxpc3RJdGVtID0gdGhpcy5tZW51UmVmLmNoaWxkcmVuWzBdOwogICAgICAgICAgICAgICAgdGhpcy5fZm9jdXNMaXN0SXRlbShsaXN0SXRlbSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBhbGxMaXN0SXRlbXMgPSBbXS5zbGljZS5jYWxsKHRoaXMubWVudVJlZi5jaGlsZHJlbik7CgogICAgICAgICAgICBpZiAocG9zaXRpb24gPT09IFBPU0lUSU9OLk5FWFQgfHwgcG9zaXRpb24gPT09IFBPU0lUSU9OLlBSRVYpIHsKICAgICAgICAgICAgICAgIHZhciBmb2N1c2VkTGlzdEl0ZW0gPSBkb2N1bWVudC5hY3RpdmVFbGVtZW50LnBhcmVudE5vZGU7CiAgICAgICAgICAgICAgICB2YXIgZm9jdXNlZEluZGV4ID0gYWxsTGlzdEl0ZW1zLmluZGV4T2YoZm9jdXNlZExpc3RJdGVtKTsKICAgICAgICAgICAgICAgIHZhciBuZXh0Rm9jdXNJbmRleCA9IGZvY3VzZWRJbmRleCArIChwb3NpdGlvbiA9PT0gUE9TSVRJT04uTkVYVCA/IDEgOiAtMSk7CgogICAgICAgICAgICAgICAgaWYgKDAgPD0gbmV4dEZvY3VzSW5kZXggJiYgbmV4dEZvY3VzSW5kZXggPD0gYWxsTGlzdEl0ZW1zLmxlbmd0aCAtIDEpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbmV4dExpc3RJdGVtID0gYWxsTGlzdEl0ZW1zW25leHRGb2N1c0luZGV4XTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9mb2N1c0xpc3RJdGVtKG5leHRMaXN0SXRlbSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09IFBPU0lUSU9OLkxBU1QpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2ZvY3VzTGlzdEl0ZW0oYWxsTGlzdEl0ZW1zW2FsbExpc3RJdGVtcy5sZW5ndGggLSAxXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX2ZvY3VzTGlzdEl0ZW0nLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfZm9jdXNMaXN0SXRlbShsaXN0SXRlbU5vZGUpIHsKICAgICAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7CgogICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnX2ZvY3VzTGlzdEl0ZW0nLCBsaXN0SXRlbU5vZGUpOwogICAgICAgICAgICBpZiAodGhpcy5tZW51UmVmLmNvbnRhaW5zKGxpc3RJdGVtTm9kZSkpIHsKICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gZGVsYXkgfjEgZnJhbWUgZm9yIHRoZSBmb2N1cyBhbmQgc2Nyb2xsIHRvIGJlIHJlbGlhYmxlCiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICBsaXN0SXRlbU5vZGUuY2hpbGRyZW5bMF0uZm9jdXMoKTsKCiAgICAgICAgICAgICAgICAgICAgdmFyIGxpc3RJdGVtUmVjdCA9IGxpc3RJdGVtTm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgICAgICAgICAgICAgICB2YXIgbWVudVJlY3QgPSBfdGhpczIubWVudVJlZi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gbWFrZSB0aGUgZm9jdXNlZCBpdGVtICJzdGljayIgdG8gdG9wIG9yIGJvdHRvbSBlZGdlCiAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RJdGVtUmVjdC50b3AgPCBtZW51UmVjdC50b3ApIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMyLm1lbnVSZWYuc2Nyb2xsVG9wID0gbGlzdEl0ZW1Ob2RlLm9mZnNldFRvcDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGxpc3RJdGVtUmVjdC5ib3R0b20gPiBtZW51UmVjdC5ib3R0b20pIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMyLm1lbnVSZWYuc2Nyb2xsVG9wICs9IGxpc3RJdGVtUmVjdC5ib3R0b20gLSBtZW51UmVjdC5ib3R0b207CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgMTAwMCAvIDYwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVXBkYXRlcyB0aGUgZHJvcGRvd24ncyBzdGF0ZSBzdWNoIHRoYXQgaXRzIHNlbGVjdGVkT3B0aW9uIGNvcnJlc3BvbmRzIHRvIHRoZSBpdGVtIHdoaWNoIGN1cnJlbnRseSBoYXMgZm9jdXMuCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnX3NlbGVjdEZvY3VzZWRJdGVtJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX3NlbGVjdEZvY3VzZWRJdGVtKCkgewogICAgICAgICAgICBpZiAodGhpcy5tZW51UmVmLmNvbnRhaW5zKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpKSB7CiAgICAgICAgICAgICAgICB2YXIgYWxsTGlzdEl0ZW1zID0gW10uc2xpY2UuY2FsbCh0aGlzLm1lbnVSZWYuY2hpbGRyZW4pOwogICAgICAgICAgICAgICAgdmFyIGZvY3VzZWRMaXN0SXRlbSA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgIHZhciBmb2N1c2VkSW5kZXggPSBhbGxMaXN0SXRlbXMuaW5kZXhPZihmb2N1c2VkTGlzdEl0ZW0pOwogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkT3B0aW9uID0gdGhpcy5wcm9wcy5vcHRpb25zW2ZvY3VzZWRJbmRleF07CiAgICAgICAgICAgICAgICB0aGlzLl9hcHBseVNlbGVjdGlvbihzZWxlY3RlZE9wdGlvbiwgZm9jdXNlZEluZGV4KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfb25NZW51SXRlbUNsaWNrJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX29uTWVudUl0ZW1DbGljayhldmVudCwgb3B0aW9uLCBpbmRleCkgewogICAgICAgICAgICAvLyBwcmV2ZW50IGFueSBuYXZpZ2F0aW9uIHJlc3VsdGluZyBmcm9tIGNsaWNrCiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgIHRoaXMuX2FwcGx5U2VsZWN0aW9uKG9wdGlvbiwgaW5kZXgpOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfYXBwbHlTZWxlY3Rpb24nLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfYXBwbHlTZWxlY3Rpb24ob3B0aW9uLCBpbmRleCkgewogICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsKICAgICAgICAgICAgICAgIHNlbGVjdGVkT3B0aW9uOiBvcHRpb24sCiAgICAgICAgICAgICAgICBtZW51T3BlbjogZmFsc2UKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5vbkNoYW5nZSkgewogICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5nZShvcHRpb24sIGluZGV4KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfb3B0aW9uVG9MYWJlbCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9vcHRpb25Ub0xhYmVsKG9wdGlvbikgewogICAgICAgICAgICBpZiAoIW9wdGlvbikgewogICAgICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5sYWJlbEZpZWxkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9uW3RoaXMucHJvcHMubGFiZWxGaWVsZF07CiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy5sYWJlbEZ1bmN0aW9uKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wcm9wcy5sYWJlbEZ1bmN0aW9uKG9wdGlvbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9uLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICB2YXIgX3RoaXMzID0gdGhpczsKCiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdyZW5kZXInLCB0aGlzLnN0YXRlLm1lbnVPcGVuKTsKICAgICAgICAgICAgdmFyIGV4dHJhQ2xhc3MgPSB0aGlzLnByb3BzLmNsYXNzTmFtZSB8fCAnJzsKICAgICAgICAgICAgdmFyIG9wZW5DbGFzcyA9IHRoaXMuc3RhdGUubWVudU9wZW4gPyAnRHJvcGRvd24tbWVudS1vcGVuJyA6ICdEcm9wZG93bi1tZW51LWNsb3NlZCc7CiAgICAgICAgICAgIHZhciBwcm9tcHRDbGFzcyA9ICF0aGlzLnN0YXRlLnNlbGVjdGVkT3B0aW9uID8gJ0Ryb3Bkb3duLXBsYWNlaG9sZGVyJyA6ICcnOwogICAgICAgICAgICB2YXIgYnV0dG9uTGFiZWwgPSB0aGlzLl9vcHRpb25Ub0xhYmVsKHRoaXMuc3RhdGUuc2VsZWN0ZWRPcHRpb24pIHx8IHRoaXMucHJvcHMucGxhY2Vob2xkZXI7CiAgICAgICAgICAgIHZhciBtZW51V2lkdGggPSB0aGlzLmJ1dHRvblJlZiAmJiB0aGlzLmJ1dHRvblJlZi5vZmZzZXRXaWR0aCB8fCAwOwoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ0Ryb3Bkb3duICcgKyBvcGVuQ2xhc3MgKyAnICcgKyBleHRyYUNsYXNzIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAnYnV0dG9uJywKICAgICAgICAgICAgICAgICAgICB7IHJlZjogZnVuY3Rpb24gcmVmKGJ1dHRvbikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMzLmJ1dHRvblJlZiA9IGJ1dHRvbjsKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnRHJvcGRvd24tYnV0dG9uICcgKyBwcm9tcHRDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ6IHRoaXMucHJvcHMuZGlzYWJsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBidXR0b25MYWJlbCwKICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljazogdGhpcy5fb25Ecm9wZG93bk1vdXNlRXZlbnQKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIGJ1dHRvbkxhYmVsCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2EnLAogICAgICAgICAgICAgICAgICAgIHsgcmVmOiBmdW5jdGlvbiByZWYodGh1bWIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMy50aHVtYlJlZiA9IHRodW1iOwogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICdEcm9wZG93bi10aHVtYicsCiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s6IHRoaXMuX29uRHJvcGRvd25Nb3VzZUV2ZW50CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChfcmVhY3RNYXRlcmlhbEljb25zLkljb24sIHsgaWNvbjogJ2tleWJvYXJkX2Fycm93X2Rvd24nLCBzaXplOiAxNiB9KQogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUubWVudU9wZW4gJiYgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgX0Zsb2F0aW5nRWxlbWVudC5GbG9hdGluZ0VsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0aGlzLmJ1dHRvblJlZiwKICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25GdW5jdGlvbjogcG9zaXRpb25NZW51LAogICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogeyB3aWR0aDogbWVudVdpZHRoIH0KICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICAgICAndWwnLAogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWY6IGZ1bmN0aW9uIHJlZihsaXN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMzLm1lbnVSZWYgPSBsaXN0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ0Ryb3Bkb3duLW1lbnUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb25XaGVlbDogdGhpcy5fb25NZW51U2Nyb2xsRXZlbnQKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vcHRpb25zLm1hcChmdW5jdGlvbiAob3B0aW9uLCBpbmRleCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkQ2xhc3MgPSBfdGhpczMuc3RhdGUuc2VsZWN0ZWRPcHRpb24gPT09IG9wdGlvbiA/ICdEcm9wZG93bi1tZW51LWl0ZW0tc2VsZWN0ZWQnIDogJyc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3B0aW9uTGFiZWwgPSBfdGhpczMuX29wdGlvblRvTGFiZWwob3B0aW9uKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2xpJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IGtleTogaW5kZXgsICdkYXRhLXBvc2l0aW9uJzogaW5kZXggfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2EnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ0Ryb3Bkb3duLW1lbnUtaXRlbSAnICsgc2VsZWN0ZWRDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhyZWY6ICcjJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s6IGZ1bmN0aW9uIG9uQ2xpY2soZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMzLl9vbk1lbnVJdGVtQ2xpY2soZXZlbnQsIG9wdGlvbiwgaW5kZXgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25MYWJlbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdzZWxlY3RlZE9wdGlvbicsCiAgICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXRlLnNlbGVjdGVkT3B0aW9uOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gRHJvcGRvd247Cn0oX3JlYWN0Mi5kZWZhdWx0LkNvbXBvbmVudCk7Cgp2YXIgQk9SREVSX09GRlNFVCA9IDI7CgovLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlbiwgbm8tdW51c2VkLXZhcnMKZnVuY3Rpb24gcG9zaXRpb25NZW51KHNlbGZXaWR0aCwgc2VsZkhlaWdodCwgdGFyZ2V0V2lkdGgsIHRhcmdldEhlaWdodCwgdGFyZ2V0TGVmdCwgdGFyZ2V0VG9wLCB2aWV3cG9ydFdpZHRoLCB2aWV3cG9ydEhlaWdodCkgewogICAgcmV0dXJuIHsKICAgICAgICBuZXdMZWZ0OiB0YXJnZXRMZWZ0LAogICAgICAgIG5ld1RvcDogdGFyZ2V0VG9wICsgdGFyZ2V0SGVpZ2h0ICsgQk9SREVSX09GRlNFVAogICAgfTsKfQoKRHJvcGRvd24ucHJvcFR5cGVzID0gewogICAgY2xhc3NOYW1lOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIHBsYWNlaG9sZGVyOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIG9wdGlvbnM6IF9yZWFjdC5Qcm9wVHlwZXMuYXJyYXksCiAgICBkZWZhdWx0T3B0aW9uOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIGxhYmVsRmllbGQ6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgbGFiZWxGdW5jdGlvbjogX3JlYWN0LlByb3BUeXBlcy5mdW5jLAogICAgZGlzYWJsZWQ6IF9yZWFjdC5Qcm9wVHlwZXMuYm9vbCwKICAgIG9uQ2hhbmdlOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMKfTsKCkRyb3Bkb3duLmRlZmF1bHRQcm9wcyA9IHsKICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0IGFuIG9wdGlvbicKfTsKfSx7Ii4uLy4uL0tleUNvZGVzIjo2MywiLi4vRmxvYXRpbmdFbGVtZW50Ijo3NCwiQGplbmtpbnMtY2QvcmVhY3QtbWF0ZXJpYWwtaWNvbnMiOjEyOSwibG9kYXNoLmRlYm91bmNlIjozNjMsInJlYWN0Ijo2MjN9XSw5NjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLkZvcm1FbGVtZW50ID0gRm9ybUVsZW1lbnQ7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9FcnJvck1lc3NhZ2UgPSByZXF1aXJlKCcuLi9FcnJvck1lc3NhZ2UnKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBGb3JtRWxlbWVudChwcm9wcykgewogICAgaWYgKCFwcm9wcy50aXRsZSAmJiAhcHJvcHMuZXJyb3JNZXNzYWdlICYmICFwcm9wcy5jaGlsZHJlbikgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHZhciBleHRyYUNsYXNzID0gcHJvcHMuY2xhc3NOYW1lIHx8ICcnOwogICAgdmFyIGVycm9yQ2xhc3MgPSBwcm9wcy5lcnJvck1lc3NhZ2UgPyAndS1lcnJvci1zdGF0ZScgOiAnJzsKICAgIHZhciBkaXZpZGVyQ2xhc3MgPSBwcm9wcy5zaG93RGl2aWRlciA/ICd1LXNob3ctZGl2aWRlcicgOiAnJzsKICAgIHZhciBsYXlvdXRDbGFzcyA9IHByb3BzLnZlcnRpY2FsTGF5b3V0ID8gJ3UtbGF5b3V0LXZlcnRpY2FsJyA6ICcnOwogICAgdmFyIGNoaWxkRnJlZUNsYXNzID0gIXByb3BzLmNoaWxkcmVuID8gJ3UtY2hpbGQtZnJlZScgOiAnJzsKCiAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgJ2RpdicsCiAgICAgICAgeyBjbGFzc05hbWU6ICdGb3JtRWxlbWVudCAnICsgZXh0cmFDbGFzcyArICcgJyArIGVycm9yQ2xhc3MgKyAnICcgKyBkaXZpZGVyQ2xhc3MgKyAnICcgKyBsYXlvdXRDbGFzcyArICcgJyArIGNoaWxkRnJlZUNsYXNzIH0sCiAgICAgICAgKHByb3BzLnRpdGxlIHx8IHByb3BzLmVycm9yTWVzc2FnZSkgJiYgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICdkaXYnLAogICAgICAgICAgICB7IGNsYXNzTmFtZTogJ0Zvcm1FbGVtZW50LWhlYWRpbmcnIH0sCiAgICAgICAgICAgIHByb3BzLnRpdGxlICYmIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2xhYmVsJywKICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnRm9ybUVsZW1lbnQtdGl0bGUnIH0sCiAgICAgICAgICAgICAgICBwcm9wcy50aXRsZQogICAgICAgICAgICApLAogICAgICAgICAgICBwcm9wcy50aXRsZSAmJiBwcm9wcy5lcnJvck1lc3NhZ2UgJiYgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnc3BhbicsCiAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgJ1x4QTAtXHhBMCcKICAgICAgICAgICAgKSwKICAgICAgICAgICAgcHJvcHMuZXJyb3JNZXNzYWdlICYmIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgX0Vycm9yTWVzc2FnZS5FcnJvck1lc3NhZ2UsCiAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgcHJvcHMuZXJyb3JNZXNzYWdlCiAgICAgICAgICAgICkKICAgICAgICApLAogICAgICAgIHByb3BzLmNoaWxkcmVuICYmIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdGb3JtRWxlbWVudC1jaGlsZHJlbicgfSwKICAgICAgICAgICAgcHJvcHMuY2hpbGRyZW4KICAgICAgICApCiAgICApOwp9CgpGb3JtRWxlbWVudC5wcm9wVHlwZXMgPSB7CiAgICBjaGlsZHJlbjogX3JlYWN0LlByb3BUeXBlcy5ub2RlLAogICAgY2xhc3NOYW1lOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIHRpdGxlOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIGVycm9yTWVzc2FnZTogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBzaG93RGl2aWRlcjogX3JlYWN0LlByb3BUeXBlcy5ib29sLAogICAgdmVydGljYWxMYXlvdXQ6IF9yZWFjdC5Qcm9wVHlwZXMuYm9vbAp9Owp9LHsiLi4vRXJyb3JNZXNzYWdlIjo3MCwicmVhY3QiOjYyM31dLDk3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuUGFzc3dvcmRJbnB1dCA9IHVuZGVmaW5lZDsKCnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX1RleHRDb250cm9sID0gcmVxdWlyZSgnLi9UZXh0Q29udHJvbCcpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKdmFyIFBhc3N3b3JkSW5wdXQgPSBleHBvcnRzLlBhc3N3b3JkSW5wdXQgPSBmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkgewogICAgX2luaGVyaXRzKFBhc3N3b3JkSW5wdXQsIF9SZWFjdCRDb21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIFBhc3N3b3JkSW5wdXQoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFBhc3N3b3JkSW5wdXQpOwoKICAgICAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKFBhc3N3b3JkSW5wdXQuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihQYXNzd29yZElucHV0KSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFBhc3N3b3JkSW5wdXQsIFt7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICBfVGV4dENvbnRyb2wuVGV4dENvbnRyb2wsCiAgICAgICAgICAgICAgICBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcywgeyBjbGFzc05hbWU6ICdQYXNzd29yZElucHV0ICcgKyB0aGlzLnByb3BzLmNsYXNzTmFtZSB9KSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdpbnB1dCcsIF9leHRlbmRzKHsgdHlwZTogJ3Bhc3N3b3JkJywgY2xhc3NOYW1lOiAnVGV4dElucHV0LWNvbnRyb2wnIH0sIHsgbmFtZTogdGhpcy5wcm9wcy5uYW1lIH0pKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gUGFzc3dvcmRJbnB1dDsKfShfcmVhY3QyLmRlZmF1bHQuQ29tcG9uZW50KTsKClBhc3N3b3JkSW5wdXQucHJvcFR5cGVzID0gewogICAgY2xhc3NOYW1lOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIG5hbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgcGxhY2Vob2xkZXI6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgZGVmYXVsdFZhbHVlOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIG9uQ2hhbmdlOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsCiAgICBvbkJsdXI6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYwp9OwoKUGFzc3dvcmRJbnB1dC5kZWZhdWx0UHJvcHMgPSB7CiAgICBjbGFzc05hbWU6ICcnCn07Cn0seyIuL1RleHRDb250cm9sIjoxMDAsInJlYWN0Ijo2MjN9XSw5ODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlJhZGlvQnV0dG9uR3JvdXAgPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7Cgp2YXIgX1V0aWxzID0gcmVxdWlyZSgnLi4vLi4vVXRpbHMnKTsKCnZhciBfVXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXRpbHMpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKLyoqCiAqIFJlbmRlcnMgYSBncm91cCBvZiByYWRpbyBidXR0b25zIGZvciB0aGUgcHJvdmlkZWQgJ29wdGlvbnMnCiAqIEJ5IGRlZmF1bHQgdGhlIHJhZGlvIGJ1dHRvbnMgYXJlIGFycmFuZ2VkIHZlcnRpY2FsbHkKICoKICogUHJvcHM6CiAqICAgICAgY2xhc3NOYW1lOiBhZGRpdGlvbmFsIGNsYXNzIG5hbWUocykgdG8gYWRkIHRvIHJvb3QgZWxlbWVudC4KICogICAgICAgICAgVXNlICdpcy1sYXlvdXQtaG9yaXpvbnRhbCcgdG8gY2hhbmdlIGxheW91dCBkaXJlY3Rpb24uCiAqICAgICAgb3B0aW9uczogYW4gYXJyYXkgb2Ygb3B0aW9ucyB0byBtYXAgdG8gcmFkaW8gYnV0dG9ucy4gQ2FuIGJlIHN0cmluZ3Mgb3Igb2JqZWN0cy4KICogICAgICBkZWZhdWx0T3B0aW9uOiBvcHRpb24gdG8gc2VsZWN0L2NoZWNrIGJ5IGRlZmF1bHQgaWYgbm8gc2VsZWN0aW9uIHdhcyBhbHJlYWR5IG1hZGUgYnkgdXNlci4KICogICAgICBsYWJlbEZpZWxkOiBpZiB1c2luZyBvYmplY3RzIGZvciBvcHRpb25zLCBuYW1lIG9mIHByb3BlcnR5IHRvIHVzZSBmb3IgbGFiZWwuCiAqICAgICAgbGFiZWxGdW5jdGlvbjogYSBmdW5jdGlvbiB0aGF0IHJlY2VpdmVzIHRoZSBvcHRpb24gYW5kIHJldHVybnMgYSBzdHJpbmcgZm9yIGxhYmVsLgogKiAgICAgIG9uQ2hhbmdlOiBoYW5kbGVyIGZ1bmMgY2FsbHMgd2hlbiB1c2VyIGNoYW5nZXMgc2VsZWN0aW9uLCByZWNlaXZpbmcgJ29wdGlvbicgYXMgb25seSBhcmcuCiAqLwp2YXIgUmFkaW9CdXR0b25Hcm91cCA9IGV4cG9ydHMuUmFkaW9CdXR0b25Hcm91cCA9IGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoUmFkaW9CdXR0b25Hcm91cCwgX1JlYWN0JENvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gUmFkaW9CdXR0b25Hcm91cChwcm9wcykgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBSYWRpb0J1dHRvbkdyb3VwKTsKCiAgICAgICAgdmFyIF90aGlzID0gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKFJhZGlvQnV0dG9uR3JvdXAuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihSYWRpb0J1dHRvbkdyb3VwKSkuY2FsbCh0aGlzLCBwcm9wcykpOwoKICAgICAgICBfdGhpcy5zdGF0ZSA9IHsKICAgICAgICAgICAgc2VsZWN0ZWRPcHRpb246IG51bGwKICAgICAgICB9OwoKICAgICAgICBfdGhpcy5ncm91cElkID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gX1V0aWxzMi5kZWZhdWx0LnJhbmRvbUlkKCdSYWRpb0J1dHRvbkdyb3VwJyk7CiAgICAgICAgfTsKICAgICAgICByZXR1cm4gX3RoaXM7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFJhZGlvQnV0dG9uR3JvdXAsIFt7CiAgICAgICAga2V5OiAnY29tcG9uZW50V2lsbE1vdW50JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbE1vdW50KCkgewogICAgICAgICAgICB0aGlzLl9kZWZhdWx0U2VsZWN0aW9uKHRoaXMucHJvcHMpOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHsKICAgICAgICAgICAgdGhpcy5fZGVmYXVsdFNlbGVjdGlvbihuZXh0UHJvcHMpOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfZGVmYXVsdFNlbGVjdGlvbicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9kZWZhdWx0U2VsZWN0aW9uKHByb3BzKSB7CiAgICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZE9wdGlvbiAmJiBwcm9wcy5kZWZhdWx0T3B0aW9uKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsKICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZE9wdGlvbjogcHJvcHMuZGVmYXVsdE9wdGlvbgogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX29uQ2hhbmdlJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX29uQ2hhbmdlKG9wdGlvbikgewogICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsKICAgICAgICAgICAgICAgIHNlbGVjdGVkT3B0aW9uOiBvcHRpb24KICAgICAgICAgICAgfSk7CgogICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5vbkNoYW5nZSkgewogICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5nZShvcHRpb24pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7CgogICAgICAgICAgICB2YXIgZ3JvdXBJZCA9IHRoaXMuZ3JvdXBJZCgpOwoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ1JhZGlvQnV0dG9uR3JvdXAgJyArIHRoaXMucHJvcHMuY2xhc3NOYW1lIH0sCiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLm9wdGlvbnMubWFwKGZ1bmN0aW9uIChvcHRpb24sIGluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNoZWNrZWQgPSBvcHRpb24gPT09IF90aGlzMi5zdGF0ZS5zZWxlY3RlZE9wdGlvbjsKCiAgICAgICAgICAgICAgICAgICAgdmFyIGxhYmVsVmFsdWUgPSAnJzsKCiAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzMi5wcm9wcy5sYWJlbEZpZWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsVmFsdWUgPSBvcHRpb25bX3RoaXMyLnByb3BzLmxhYmVsRmllbGRdOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoX3RoaXMyLnByb3BzLmxhYmVsRnVuY3Rpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxWYWx1ZSA9IF90aGlzMi5wcm9wcy5sYWJlbEZ1bmN0aW9uKG9wdGlvbik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxWYWx1ZSA9IG9wdGlvbi50b1N0cmluZygpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgICAgICAgICAnbGFiZWwnLAogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnUmFkaW9CdXR0b25Hcm91cC1pdGVtJwogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgnaW5wdXQnLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICdSYWRpb0J1dHRvbkdyb3VwLWJ1dHRvbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBncm91cElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3JhZGlvJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrZWQ6IGNoZWNrZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZDogX3RoaXMyLnByb3BzLmRpc2FibGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U6IGZ1bmN0aW9uIG9uQ2hhbmdlKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIuX29uQ2hhbmdlKG9wdGlvbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0pLAogICAgICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChJbmRpY2F0b3IsIG51bGwpLAogICAgICAgICAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzcGFuJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnUmFkaW9CdXR0b25Hcm91cC10ZXh0JyB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxWYWx1ZQogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3NlbGVjdGVkT3B0aW9uJywKICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGUuc2VsZWN0ZWRPcHRpb247CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBSYWRpb0J1dHRvbkdyb3VwOwp9KF9yZWFjdDIuZGVmYXVsdC5Db21wb25lbnQpOwoKUmFkaW9CdXR0b25Hcm91cC5wcm9wVHlwZXMgPSB7CiAgICBjbGFzc05hbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgb3B0aW9uczogX3JlYWN0LlByb3BUeXBlcy5hcnJheSwKICAgIGRlZmF1bHRPcHRpb246IF9yZWFjdC5Qcm9wVHlwZXMuYW55LAogICAgbGFiZWxGaWVsZDogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBsYWJlbEZ1bmN0aW9uOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsCiAgICBkaXNhYmxlZDogX3JlYWN0LlByb3BUeXBlcy5ib29sLAogICAgb25DaGFuZ2U6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYwp9OwoKUmFkaW9CdXR0b25Hcm91cC5kZWZhdWx0UHJvcHMgPSB7CiAgICBjbGFzc05hbWU6ICcnCn07CgpmdW5jdGlvbiBJbmRpY2F0b3IoKSB7CiAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgJ2RpdicsCiAgICAgICAgeyBjbGFzc05hbWU6ICdSYWRpb0J1dHRvbkdyb3VwLWluZGljYXRvcicgfSwKICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgJ3N2ZycsCiAgICAgICAgICAgIHsgeG1sbnM6ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsIHZpZXdCb3g6ICcwIDAgMjAgMjAnLAogICAgICAgICAgICAgICAgd2lkdGg6ICcxMDAlJywgaGVpZ2h0OiAnMTAwJScsIGNsYXNzTmFtZTogJ3N2Zy1zaGFwZScsIGZvY3VzYWJsZTogJ2ZhbHNlJwogICAgICAgICAgICB9LAogICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdnJywKICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgnY2lyY2xlJywgeyBjbGFzc05hbWU6ICdvdXRlci1jaXJjbGUnLCBjeDogJzEwJywgY3k6ICcxMCcsIHI6ICc5LjUnLCBzdHJva2U6ICdibGFjaycsIHN0cm9rZVdpZHRoOiAnMScsIGZpbGw6ICdub25lJywKICAgICAgICAgICAgICAgICAgICBzaGFwZVJlbmRlcmluZzogJ2dlb21ldHJpY1ByZWNpc2lvbicgfSksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgnY2lyY2xlJywgeyBjbGFzc05hbWU6ICdpbm5lci1jaXJjbGUnLCBjeDogJzEwJywgY3k6ICcxMCcsIHI6ICczJywgZmlsbDogJ3doaXRlJywKICAgICAgICAgICAgICAgICAgICBzaGFwZVJlbmRlcmluZzogJ2dlb21ldHJpY1ByZWNpc2lvbicgfSkKICAgICAgICAgICAgKQogICAgICAgICksCiAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ2RpdicsIHsgY2xhc3NOYW1lOiAnUmFkaW9CdXR0b25Hcm91cC1mb2N1cycgfSkKICAgICk7Cn0KfSx7Ii4uLy4uL1V0aWxzIjo2NCwicmVhY3QiOjYyM31dLDk5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuVGV4dEFyZWEgPSB1bmRlZmluZWQ7Cgp2YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9OwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9UZXh0Q29udHJvbCA9IHJlcXVpcmUoJy4vVGV4dENvbnRyb2wnKTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0KCnZhciBUZXh0QXJlYSA9IGV4cG9ydHMuVGV4dEFyZWEgPSBmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkgewogICAgX2luaGVyaXRzKFRleHRBcmVhLCBfUmVhY3QkQ29tcG9uZW50KTsKCiAgICBmdW5jdGlvbiBUZXh0QXJlYSgpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVGV4dEFyZWEpOwoKICAgICAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKFRleHRBcmVhLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoVGV4dEFyZWEpKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoVGV4dEFyZWEsIFt7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICBfVGV4dENvbnRyb2wuVGV4dENvbnRyb2wsCiAgICAgICAgICAgICAgICBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcywgeyBjbGFzc05hbWU6ICdUZXh0QXJlYSAnICsgdGhpcy5wcm9wcy5jbGFzc05hbWUgfSksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgndGV4dGFyZWEnLCB7IGNsYXNzTmFtZTogJ1RleHRBcmVhLWNvbnRyb2wnLCBuYW1lOiB0aGlzLnByb3BzLm5hbWUgfSkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFRleHRBcmVhOwp9KF9yZWFjdDIuZGVmYXVsdC5Db21wb25lbnQpOwoKVGV4dEFyZWEucHJvcFR5cGVzID0gewogICAgY2xhc3NOYW1lOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIHBsYWNlaG9sZGVyOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIG5hbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgZGVmYXVsdFZhbHVlOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIGRpc2FibGVkOiBfcmVhY3QuUHJvcFR5cGVzLmJvb2wsCiAgICBvbkNoYW5nZTogX3JlYWN0LlByb3BUeXBlcy5mdW5jLAogICAgb25CbHVyOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMKfTsKClRleHRBcmVhLmRlZmF1bHRQcm9wcyA9IHsKICAgIGNsYXNzTmFtZTogJycKfTsKfSx7Ii4vVGV4dENvbnRyb2wiOjEwMCwicmVhY3QiOjYyM31dLDEwMDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLlRleHRDb250cm9sID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKLyoqCiAqIENvbnRhaW5zIGNvbW1vbiBsb2dpYyBmb3IgdGV4dC1iYXNlZCBjb250cm9scy4KICogTm90IGludGVuZGVkIHRvIGJlIHVzZWQgZGlyZWN0bHkuCiAqLwp2YXIgVGV4dENvbnRyb2wgPSBleHBvcnRzLlRleHRDb250cm9sID0gZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhUZXh0Q29udHJvbCwgX1JlYWN0JENvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gVGV4dENvbnRyb2wocHJvcHMpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVGV4dENvbnRyb2wpOwoKICAgICAgICB2YXIgX3RoaXMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoVGV4dENvbnRyb2wuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihUZXh0Q29udHJvbCkpLmNhbGwodGhpcywgcHJvcHMpKTsKCiAgICAgICAgX3RoaXMuc3RhdGUgPSB7CiAgICAgICAgICAgIHZhbHVlOiAnJwogICAgICAgIH07CiAgICAgICAgcmV0dXJuIF90aGlzOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhUZXh0Q29udHJvbCwgW3sKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsTW91bnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsTW91bnQoKSB7CiAgICAgICAgICAgIHRoaXMuX2luaXRpYWxpemUodGhpcy5wcm9wcyk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ19pbml0aWFsaXplJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX2luaXRpYWxpemUocHJvcHMpIHsKICAgICAgICAgICAgaWYgKHByb3BzLmRlZmF1bHRWYWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7CiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHByb3BzLmRlZmF1bHRWYWx1ZQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX29uQ2hhbmdlJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX29uQ2hhbmdlKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IGV2ZW50LmN1cnJlbnRUYXJnZXQudmFsdWU7CgoKICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7CiAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5vbkNoYW5nZSkgewogICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5nZSh2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX29uQmx1cicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9vbkJsdXIoZXZlbnQpIHsKICAgICAgICAgICAgdmFyIHZhbHVlID0gZXZlbnQuY3VycmVudFRhcmdldC52YWx1ZTsKCgogICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5vbkJsdXIpIHsKICAgICAgICAgICAgICAgIHRoaXMucHJvcHMub25CbHVyKHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzOwoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2RpdicsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogdGhpcy5wcm9wcy5jbGFzc05hbWUgfSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5DaGlsZHJlbi5tYXAodGhpcy5wcm9wcy5jaGlsZHJlbiwgZnVuY3Rpb24gKGNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gd2hpbGUgbXVsdGlwbGUgY2hpbGRyZW4gY2FuIGJlIHBhc3NlZCBpbiAoaWNvbnMsIGV0YykKICAgICAgICAgICAgICAgICAgICAvLyB3ZSBvbmx5IHdhbnQgdG8gcGFzcyBkb3duIHByb3BzIHRvIHVuZGVybHlpbmcgdGV4dCBjb250cm9sCiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkICYmIChjaGlsZC50eXBlID09PSAnaW5wdXQnIHx8IGNoaWxkLnR5cGUgPT09ICd0ZXh0YXJlYScpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY2xvbmVFbGVtZW50KGNoaWxkLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogX3RoaXMyLnByb3BzLnBsYWNlaG9sZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ6IF90aGlzMi5wcm9wcy5kaXNhYmxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBfdGhpczIuc3RhdGUudmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UoZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIuX29uQ2hhbmdlKGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQmx1cjogZnVuY3Rpb24gb25CbHVyKGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMyLl9vbkJsdXIoZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkOwogICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAndmFsdWUnLAogICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZS52YWx1ZTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFRleHRDb250cm9sOwp9KF9yZWFjdDIuZGVmYXVsdC5Db21wb25lbnQpOwoKVGV4dENvbnRyb2wucHJvcFR5cGVzID0gewogICAgY2hpbGRyZW46IF9yZWFjdC5Qcm9wVHlwZXMubm9kZSwKICAgIGNsYXNzTmFtZTogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBwbGFjZWhvbGRlcjogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBkZWZhdWx0VmFsdWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgZGlzYWJsZWQ6IF9yZWFjdC5Qcm9wVHlwZXMuYm9vbCwKICAgIG9uQ2hhbmdlOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMsCiAgICBvbkJsdXI6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYwp9OwoKVGV4dENvbnRyb2wuZGVmYXVsdFByb3BzID0gewogICAgY2xhc3NOYW1lOiAnVGV4dENvbnRyb2wnCn07Cn0seyJyZWFjdCI6NjIzfV0sMTAxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuVGV4dElucHV0ID0gdW5kZWZpbmVkOwoKdmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfcmVhY3RNYXRlcmlhbEljb25zID0gcmVxdWlyZSgnQGplbmtpbnMtY2QvcmVhY3QtbWF0ZXJpYWwtaWNvbnMnKTsKCnZhciBfVGV4dENvbnRyb2wgPSByZXF1aXJlKCcuL1RleHRDb250cm9sJyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9CgovLyB3cmFwcyB0aGUgSWNvbiBpbiBhIGRpdiB0byBwcm92aWRlIGNvbnNpc3RlbnQgY3Vyc29yIGJlaGF2aW9yCmZ1bmN0aW9uIE5lc3RlZEljb24ocHJvcHMpIHsKICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAnZGl2JywKICAgICAgICB7IGNsYXNzTmFtZTogJ1RleHRJbnB1dC1pY29uICcgKyBwcm9wcy5jbGFzc05hbWUgfSwKICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudChfcmVhY3RNYXRlcmlhbEljb25zLkljb24sIHsgaWNvbjogcHJvcHMuaWNvbiB9KQogICAgKTsKfQoKTmVzdGVkSWNvbi5wcm9wVHlwZXMgPSB7CiAgICBjbGFzc05hbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgaWNvbjogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcKfTsKCnZhciBUZXh0SW5wdXQgPSBleHBvcnRzLlRleHRJbnB1dCA9IGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoVGV4dElucHV0LCBfUmVhY3QkQ29tcG9uZW50KTsKCiAgICBmdW5jdGlvbiBUZXh0SW5wdXQoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFRleHRJbnB1dCk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoVGV4dElucHV0Ll9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoVGV4dElucHV0KSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFRleHRJbnB1dCwgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBjbGFzc0xlZnQgPSB0aGlzLnByb3BzLmljb25MZWZ0ID8gJ3UtaWNvbi1sZWZ0JyA6ICcnOwogICAgICAgICAgICB2YXIgY2xhc3NSaWdodCA9IHRoaXMucHJvcHMuaWNvblJpZ2h0ID8gJ3UtaWNvbi1yaWdodCcgOiAnJzsKCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgIF9UZXh0Q29udHJvbC5UZXh0Q29udHJvbCwKICAgICAgICAgICAgICAgIF9leHRlbmRzKHt9LCB0aGlzLnByb3BzLCB7IGNsYXNzTmFtZTogJ1RleHRJbnB1dCAnICsgdGhpcy5wcm9wcy5jbGFzc05hbWUgKyAnICcgKyBjbGFzc0xlZnQgKyAnICcgKyBjbGFzc1JpZ2h0IH0pLAogICAgICAgICAgICAgICAgY2xhc3NMZWZ0ICYmIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KE5lc3RlZEljb24sIHsgY2xhc3NOYW1lOiBjbGFzc0xlZnQsIGljb246IHRoaXMucHJvcHMuaWNvbkxlZnQgfSksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgnaW5wdXQnLCBfZXh0ZW5kcyh7IHR5cGU6ICd0ZXh0JywgY2xhc3NOYW1lOiAnVGV4dElucHV0LWNvbnRyb2wnIH0sIHsgbmFtZTogdGhpcy5wcm9wcy5uYW1lIH0pKSwKICAgICAgICAgICAgICAgIGNsYXNzUmlnaHQgJiYgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoTmVzdGVkSWNvbiwgeyBjbGFzc05hbWU6IGNsYXNzUmlnaHQsIGljb246IHRoaXMucHJvcHMuaWNvblJpZ2h0IH0pCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBUZXh0SW5wdXQ7Cn0oX3JlYWN0Mi5kZWZhdWx0LkNvbXBvbmVudCk7CgpUZXh0SW5wdXQucHJvcFR5cGVzID0gewogICAgY2xhc3NOYW1lOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIG5hbWU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgcGxhY2Vob2xkZXI6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgZGVmYXVsdFZhbHVlOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIGRpc2FibGVkOiBfcmVhY3QuUHJvcFR5cGVzLmJvb2wsCiAgICBpY29uTGVmdDogX3JlYWN0LlByb3BUeXBlcy5zdHJpbmcsCiAgICBpY29uUmlnaHQ6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgb25DaGFuZ2U6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYywKICAgIG9uQmx1cjogX3JlYWN0LlByb3BUeXBlcy5mdW5jCn07CgpUZXh0SW5wdXQuZGVmYXVsdFByb3BzID0gewogICAgY2xhc3NOYW1lOiAnJwp9Owp9LHsiLi9UZXh0Q29udHJvbCI6MTAwLCJAamVua2lucy1jZC9yZWFjdC1tYXRlcmlhbC1pY29ucyI6MTI5LCJyZWFjdCI6NjIzfV0sMTAyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuQmFzaWNIZWFkZXIgPSB1bmRlZmluZWQ7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIGNsYXNzTmFtZUZvclN0YXR1c0NvbG9yKHN0YXR1c0NvbG9yKSB7CiAgICBzd2l0Y2ggKHN0YXR1c0NvbG9yKSB7CiAgICAgICAgY2FzZSBudWxsOgogICAgICAgIGNhc2UgdW5kZWZpbmVkOgogICAgICAgIGNhc2UgIiI6CiAgICAgICAgICAgIHJldHVybiAiQmFzaWNIZWFkZXItLWRlZmF1bHQiOwogICAgICAgIGNhc2UgInN1Y2Nlc3MiOgogICAgICAgICAgICByZXR1cm4gIkJhc2ljSGVhZGVyLS1zdWNjZXNzIjsKICAgICAgICBjYXNlICJmYWlsdXJlIjoKICAgICAgICAgICAgcmV0dXJuICJCYXNpY0hlYWRlci0tZmFpbHVyZSI7CiAgICAgICAgY2FzZSAicnVubmluZyI6CiAgICAgICAgICAgIHJldHVybiAiQmFzaWNIZWFkZXItLXJ1bm5pbmciOwogICAgICAgIGNhc2UgInF1ZXVlZCI6CiAgICAgICAgY2FzZSAibm90X2J1aWx0IjoKICAgICAgICAgICAgcmV0dXJuICJCYXNpY0hlYWRlci0tbm90QnVpbHQiOwogICAgICAgIGNhc2UgInVuc3RhYmxlIjoKICAgICAgICAgICAgcmV0dXJuICJCYXNpY0hlYWRlci0tdW5zdGFibGUiOwogICAgICAgIGNhc2UgImFib3J0ZWQiOgogICAgICAgICAgICByZXR1cm4gIkJhc2ljSGVhZGVyLS1hYm9ydGVkIjsKICAgICAgICBjYXNlICJwYXVzZWQiOgogICAgICAgICAgICByZXR1cm4gIkJhc2ljSGVhZGVyLS1wYXVzZWQiOwogICAgfQoKICAgIHJldHVybiAiQmFzaWNIZWFkZXItLXVua25vd24iOwp9Cgp2YXIgQmFzaWNIZWFkZXIgPSBleHBvcnRzLkJhc2ljSGVhZGVyID0gZnVuY3Rpb24gQmFzaWNIZWFkZXIocHJvcHMpIHsKCiAgICB2YXIgY2xhc3NOYW1lcyA9IFsiQmFzaWNIZWFkZXIiLCBjbGFzc05hbWVGb3JTdGF0dXNDb2xvcihwcm9wcy5zdGF0dXNDb2xvcildOwoKICAgIGlmIChwcm9wcy5jbGFzc05hbWUpIHsKICAgICAgICBjbGFzc05hbWVzLnB1c2gocHJvcHMuY2xhc3NOYW1lKTsKICAgIH0KCiAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgJ3NlY3Rpb24nLAogICAgICAgIHsgY2xhc3NOYW1lOiBjbGFzc05hbWVzLmpvaW4oJyAnKSB9LAogICAgICAgIHByb3BzLmNoaWxkcmVuCiAgICApOwp9OwoKQmFzaWNIZWFkZXIucHJvcFR5cGVzID0gewogICAgY2hpbGRyZW46IF9yZWFjdC5Qcm9wVHlwZXMubm9kZSwKICAgIHN0YXR1c0NvbG9yOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZwp9Owp9LHsicmVhY3QiOjYyM31dLDEwMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwpleHBvcnRzLkhlYWRlckRldGFpbHMgPSB1bmRlZmluZWQ7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCnZhciBIZWFkZXJEZXRhaWxzID0gZXhwb3J0cy5IZWFkZXJEZXRhaWxzID0gZnVuY3Rpb24gSGVhZGVyRGV0YWlscyhwcm9wcykgewoKICAgIHZhciBzdHlsZSA9IHByb3BzLnN0eWxlIHx8IHt9OwogICAgdmFyIGNsYXNzTmFtZXMgPSBbIkhlYWRlci1kZXRhaWxzIl07CgogICAgaWYgKHByb3BzLmNsYXNzTmFtZSkgewogICAgICAgIGNsYXNzTmFtZXMucHVzaChwcm9wcy5jbGFzc05hbWUpOwogICAgfQoKICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAnZGl2JywKICAgICAgICB7IGNsYXNzTmFtZTogY2xhc3NOYW1lcy5qb2luKCcgJyksIHN0eWxlOiBzdHlsZSB9LAogICAgICAgIHByb3BzLmNoaWxkcmVuCiAgICApOwp9OwoKSGVhZGVyRGV0YWlscy5wcm9wVHlwZXMgPSB7CiAgICBjaGlsZHJlbjogX3JlYWN0LlByb3BUeXBlcy5ub2RlCn07Cn0seyJyZWFjdCI6NjIzfV0sMTA0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKInVzZSBzdHJpY3QiOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuUGFnZVRhYnMgPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCJyZWFjdCIpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9Cgp2YXIgUGFnZVRhYnMgPSBleHBvcnRzLlBhZ2VUYWJzID0gZnVuY3Rpb24gKF9Db21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhQYWdlVGFicywgX0NvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gUGFnZVRhYnMoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFBhZ2VUYWJzKTsKCiAgICAgICAgcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChQYWdlVGFicy5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKFBhZ2VUYWJzKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFBhZ2VUYWJzLCBbewogICAgICAgIGtleTogInJlbmRlciIsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHMsCiAgICAgICAgICAgICAgICBiYXNlID0gX3Byb3BzLmJhc2UsCiAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IF9wcm9wcy5jaGlsZHJlbjsKCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICJuYXYiLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICJIZWFkZXItcGFnZVRhYnMiIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuQ2hpbGRyZW4ubWFwKGNoaWxkcmVuLCBmdW5jdGlvbiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNsb25lRWxlbWVudChjaGlsZCwgeyBiYXNlOiBiYXNlIH0pOwogICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFBhZ2VUYWJzOwp9KF9yZWFjdC5Db21wb25lbnQpOwoKUGFnZVRhYnMucHJvcFR5cGVzID0gewogICAgY2hpbGRyZW46IF9yZWFjdC5Qcm9wVHlwZXMubm9kZSwKICAgIGJhc2U6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nCn07Cn0seyJyZWFjdCI6NjIzfV0sMTA1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuVG9wTmF2ID0gdW5kZWZpbmVkOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9Cgp2YXIgVG9wTmF2ID0gZXhwb3J0cy5Ub3BOYXYgPSBmdW5jdGlvbiBUb3BOYXYocHJvcHMpIHsKCiAgICB2YXIgc3R5bGUgPSBwcm9wcy5zdHlsZSB8fCB7fTsKICAgIHZhciBjbGFzc05hbWVzID0gWyJIZWFkZXItdG9wTmF2Il07CgogICAgaWYgKHByb3BzLmNsYXNzTmFtZSkgewogICAgICAgIGNsYXNzTmFtZXMucHVzaChwcm9wcy5jbGFzc05hbWUpOwogICAgfQoKICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAnZGl2JywKICAgICAgICB7IGNsYXNzTmFtZTogY2xhc3NOYW1lcy5qb2luKCcgJyksIHN0eWxlOiBzdHlsZSB9LAogICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdIZWFkZXItdG9wTmF2LWlubmVyJyB9LAogICAgICAgICAgICBwcm9wcy5jaGlsZHJlbgogICAgICAgICkKICAgICk7Cn07CgpUb3BOYXYucHJvcFR5cGVzID0gewogICAgY2hpbGRyZW46IF9yZWFjdC5Qcm9wVHlwZXMubm9kZQp9Owp9LHsicmVhY3QiOjYyM31dLDEwNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICB2YWx1ZTogdHJ1ZQp9KTsKCnZhciBfQmFzaWNIZWFkZXIgPSByZXF1aXJlKCcuL0Jhc2ljSGVhZGVyJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ0Jhc2ljSGVhZGVyJywgewogIGVudW1lcmFibGU6IHRydWUsCiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICByZXR1cm4gX0Jhc2ljSGVhZGVyLkJhc2ljSGVhZGVyOwogIH0KfSk7Cgp2YXIgX1RvcE5hdiA9IHJlcXVpcmUoJy4vVG9wTmF2Jyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1RvcE5hdicsIHsKICBlbnVtZXJhYmxlOiB0cnVlLAogIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgcmV0dXJuIF9Ub3BOYXYuVG9wTmF2OwogIH0KfSk7Cgp2YXIgX0hlYWRlckRldGFpbHMgPSByZXF1aXJlKCcuL0hlYWRlckRldGFpbHMnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnSGVhZGVyRGV0YWlscycsIHsKICBlbnVtZXJhYmxlOiB0cnVlLAogIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgcmV0dXJuIF9IZWFkZXJEZXRhaWxzLkhlYWRlckRldGFpbHM7CiAgfQp9KTsKCnZhciBfUGFnZVRhYnMgPSByZXF1aXJlKCcuL1BhZ2VUYWJzJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1BhZ2VUYWJzJywgewogIGVudW1lcmFibGU6IHRydWUsCiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICByZXR1cm4gX1BhZ2VUYWJzLlBhZ2VUYWJzOwogIH0KfSk7Cn0seyIuL0Jhc2ljSGVhZGVyIjoxMDIsIi4vSGVhZGVyRGV0YWlscyI6MTAzLCIuL1BhZ2VUYWJzIjoxMDQsIi4vVG9wTmF2IjoxMDV9XSwxMDc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKCnZhciBfd2VhdGhlckljb24gPSByZXF1aXJlKCcuL3dlYXRoZXItaWNvbicpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdXZWF0aGVySWNvbicsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX3dlYXRoZXJJY29uLldlYXRoZXJJY29uOwogICAgfQp9KTsKCnZhciBfcGFnZSA9IHJlcXVpcmUoJy4vcGFnZScpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdQYWdlJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfcGFnZS5QYWdlOwogICAgfQp9KTsKCnZhciBfVGFiTGluayA9IHJlcXVpcmUoJy4vVGFiTGluaycpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdUYWJMaW5rJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfVGFiTGluay5UYWJMaW5rOwogICAgfQp9KTsKCnZhciBfVGFibGUgPSByZXF1aXJlKCcuL1RhYmxlJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1RhYmxlJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfVGFibGUuVGFibGU7CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1RhYmxlRGl2aWRlcicsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1RhYmxlLlRhYmxlRGl2aWRlcjsKICAgIH0KfSk7Cgp2YXIgX1N0YXR1c0luZGljYXRvciA9IHJlcXVpcmUoJy4vc3RhdHVzL1N0YXR1c0luZGljYXRvcicpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdTdGF0dXNJbmRpY2F0b3InLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9TdGF0dXNJbmRpY2F0b3IuU3RhdHVzSW5kaWNhdG9yOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdTdmdTcGlubmVyJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfU3RhdHVzSW5kaWNhdG9yLlN2Z1NwaW5uZXI7CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1N2Z1N0YXR1cycsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1N0YXR1c0luZGljYXRvci5TdmdTdGF0dXM7CiAgICB9Cn0pOwoKdmFyIF9MaXZlU3RhdHVzSW5kaWNhdG9yID0gcmVxdWlyZSgnLi9zdGF0dXMvTGl2ZVN0YXR1c0luZGljYXRvcicpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdMaXZlU3RhdHVzSW5kaWNhdG9yJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfTGl2ZVN0YXR1c0luZGljYXRvci5MaXZlU3RhdHVzSW5kaWNhdG9yOwogICAgfQp9KTsKCnZhciBfRXJyb3JNZXNzYWdlID0gcmVxdWlyZSgnLi9FcnJvck1lc3NhZ2UnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnRXJyb3JNZXNzYWdlJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfRXJyb3JNZXNzYWdlLkVycm9yTWVzc2FnZTsKICAgIH0KfSk7Cgp2YXIgX0Zhdm9yaXRlID0gcmVxdWlyZSgnLi9mYXZvcml0ZS9GYXZvcml0ZScpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdGYXZvcml0ZScsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX0Zhdm9yaXRlLkZhdm9yaXRlOwogICAgfQp9KTsKCnZhciBfUmVhZGFibGVEYXRlID0gcmVxdWlyZSgnLi9SZWFkYWJsZURhdGUnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnUmVhZGFibGVEYXRlJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfUmVhZGFibGVEYXRlLlJlYWRhYmxlRGF0ZTsKICAgIH0KfSk7Cgp2YXIgX0NvbW1pdEhhc2ggPSByZXF1aXJlKCcuL0NvbW1pdEhhc2gnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnQ29tbWl0SGFzaCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX0NvbW1pdEhhc2guQ29tbWl0SGFzaDsKICAgIH0KfSk7Cgp2YXIgX0Rvd25sb2FkTGluayA9IHJlcXVpcmUoJy4vRG93bmxvYWRMaW5rJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ0Rvd25sb2FkTGluaycsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX0Rvd25sb2FkTGluay5Eb3dubG9hZExpbms7CiAgICB9Cn0pOwoKdmFyIF9FbXB0eVN0YXRlVmlldyA9IHJlcXVpcmUoJy4vRW1wdHlTdGF0ZVZpZXcnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnRW1wdHlTdGF0ZVZpZXcnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9FbXB0eVN0YXRlVmlldy5FbXB0eVN0YXRlVmlldzsKICAgIH0KfSk7Cgp2YXIgX0VtcHR5U3RhdGVJY29uID0gcmVxdWlyZSgnLi9FbXB0eVN0YXRlSWNvbicpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdFbXB0eVN0YXRlSWNvbicsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX0VtcHR5U3RhdGVJY29uLkVtcHR5U3RhdGVJY29uOwogICAgfQp9KTsKCnZhciBfUGlwZWxpbmVHcmFwaCA9IHJlcXVpcmUoJy4vUGlwZWxpbmVHcmFwaCcpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdQaXBlbGluZUdyYXBoJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfUGlwZWxpbmVHcmFwaC5QaXBlbGluZUdyYXBoOwogICAgfQp9KTsKCnZhciBfRmlsZVNpemUgPSByZXF1aXJlKCcuL0ZpbGVTaXplJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ0ZpbGVTaXplJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfRmlsZVNpemUuRmlsZVNpemU7CiAgICB9Cn0pOwoKdmFyIF9Ub2FzdCA9IHJlcXVpcmUoJy4vVG9hc3QnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnVG9hc3QnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9Ub2FzdC5Ub2FzdDsKICAgIH0KfSk7Cgp2YXIgX1RvYXN0ZXIgPSByZXF1aXJlKCcuL1RvYXN0ZXInKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnVG9hc3RlcicsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1RvYXN0ZXIuVG9hc3RlcjsKICAgIH0KfSk7Cgp2YXIgX1Jlc3VsdEl0ZW0gPSByZXF1aXJlKCcuL1Jlc3VsdEl0ZW0nKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnUmVzdWx0SXRlbScsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1Jlc3VsdEl0ZW0uUmVzdWx0SXRlbTsKICAgIH0KfSk7Cgp2YXIgX1RpbWVEdXJhdGlvbiA9IHJlcXVpcmUoJy4vVGltZUR1cmF0aW9uJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1RpbWVEdXJhdGlvbicsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1RpbWVEdXJhdGlvbi5UaW1lRHVyYXRpb247CiAgICB9Cn0pOwoKdmFyIF9Qcm9ncmVzcyA9IHJlcXVpcmUoJy4vUHJvZ3Jlc3MnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnUHJvZ3Jlc3MnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9Qcm9ncmVzcy5Qcm9ncmVzczsKICAgIH0KfSk7Cgp2YXIgX1BvcG92ZXIgPSByZXF1aXJlKCcuL1BvcG92ZXInKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnUG9wb3ZlcicsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1BvcG92ZXIuUG9wb3ZlcjsKICAgIH0KfSk7Cgp2YXIgX1Bvc2l0aW9uID0gcmVxdWlyZSgnLi9Qb3NpdGlvbicpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdQb3NpdGlvbkZ1bmN0aW9ucycsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1Bvc2l0aW9uLlBvc2l0aW9uRnVuY3Rpb25zOwogICAgfQp9KTsKCnZhciBfRXhwYW5kYWJsZVBhdGggPSByZXF1aXJlKCcuL0V4cGFuZGFibGVQYXRoJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ0V4cGFuZGFibGVQYXRoJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfRXhwYW5kYWJsZVBhdGguRXhwYW5kYWJsZVBhdGg7CiAgICB9Cn0pOwoKdmFyIF9GaWx0ZXJhYmxlTGlzdCA9IHJlcXVpcmUoJy4vRmlsdGVyYWJsZUxpc3QnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnRmlsdGVyYWJsZUxpc3QnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9GaWx0ZXJhYmxlTGlzdC5GaWx0ZXJhYmxlTGlzdDsKICAgIH0KfSk7Cgp2YXIgX0xpc3QgPSByZXF1aXJlKCcuL0xpc3QnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnTGlzdCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX0xpc3QuTGlzdDsKICAgIH0KfSk7Cgp2YXIgX2RpYWxvZyA9IHJlcXVpcmUoJy4vZGlhbG9nJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ0Jhc2ljRGlhbG9nJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfZGlhbG9nLkJhc2ljRGlhbG9nOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdNb2RhbENvbnRhaW5lcicsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX2RpYWxvZy5Nb2RhbENvbnRhaW5lcjsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnRGlhbG9nSGVhZGVyJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfZGlhbG9nLkRpYWxvZ0hlYWRlcjsKICAgIH0KfSk7Ck9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnRGlhbG9nQ29udGVudCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX2RpYWxvZy5EaWFsb2dDb250ZW50OwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdEaWFsb2dCdXR0b25CYXInLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9kaWFsb2cuRGlhbG9nQnV0dG9uQmFyOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdEaWFsb2cnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9kaWFsb2cuRGlhbG9nOwogICAgfQp9KTsKCnZhciBfRmxvYXRpbmdFbGVtZW50ID0gcmVxdWlyZSgnLi9GbG9hdGluZ0VsZW1lbnQnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnRmxvYXRpbmdFbGVtZW50JywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfRmxvYXRpbmdFbGVtZW50LkZsb2F0aW5nRWxlbWVudDsKICAgIH0KfSk7Cgp2YXIgX0ljb25CdXR0b24gPSByZXF1aXJlKCcuL0ljb25CdXR0b24nKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnSWNvbkJ1dHRvbicsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX0ljb25CdXR0b24uSWNvbkJ1dHRvbjsKICAgIH0KfSk7Cgp2YXIgX0Ryb3Bkb3duID0gcmVxdWlyZSgnLi9mb3Jtcy9Ecm9wZG93bicpOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdEcm9wZG93bicsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX0Ryb3Bkb3duLkRyb3Bkb3duOwogICAgfQp9KTsKCnZhciBfQ2hlY2tib3ggPSByZXF1aXJlKCcuL2Zvcm1zL0NoZWNrYm94Jyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ0NoZWNrYm94JywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfQ2hlY2tib3guQ2hlY2tib3g7CiAgICB9Cn0pOwoKdmFyIF9SYWRpb0J1dHRvbkdyb3VwID0gcmVxdWlyZSgnLi9mb3Jtcy9SYWRpb0J1dHRvbkdyb3VwJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1JhZGlvQnV0dG9uR3JvdXAnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9SYWRpb0J1dHRvbkdyb3VwLlJhZGlvQnV0dG9uR3JvdXA7CiAgICB9Cn0pOwoKdmFyIF9UZXh0QXJlYSA9IHJlcXVpcmUoJy4vZm9ybXMvVGV4dEFyZWEnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnVGV4dEFyZWEnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9UZXh0QXJlYS5UZXh0QXJlYTsKICAgIH0KfSk7Cgp2YXIgX1RleHRJbnB1dCA9IHJlcXVpcmUoJy4vZm9ybXMvVGV4dElucHV0Jyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1RleHRJbnB1dCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1RleHRJbnB1dC5UZXh0SW5wdXQ7CiAgICB9Cn0pOwoKdmFyIF9Gb3JtRWxlbWVudCA9IHJlcXVpcmUoJy4vZm9ybXMvRm9ybUVsZW1lbnQnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnRm9ybUVsZW1lbnQnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9Gb3JtRWxlbWVudC5Gb3JtRWxlbWVudDsKICAgIH0KfSk7Cgp2YXIgX1Bhc3N3b3JkSW5wdXQgPSByZXF1aXJlKCcuL2Zvcm1zL1Bhc3N3b3JkSW5wdXQnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnUGFzc3dvcmRJbnB1dCcsIHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsKICAgICAgICByZXR1cm4gX1Bhc3N3b3JkSW5wdXQuUGFzc3dvcmRJbnB1dDsKICAgIH0KfSk7Cgp2YXIgX2hlYWRlciA9IHJlcXVpcmUoJy4vaGVhZGVyJyk7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ0Jhc2ljSGVhZGVyJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfaGVhZGVyLkJhc2ljSGVhZGVyOwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdUb3BOYXYnLCB7CiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7CiAgICAgICAgcmV0dXJuIF9oZWFkZXIuVG9wTmF2OwogICAgfQp9KTsKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdIZWFkZXJEZXRhaWxzJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfaGVhZGVyLkhlYWRlckRldGFpbHM7CiAgICB9Cn0pOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ1BhZ2VUYWJzJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfaGVhZGVyLlBhZ2VUYWJzOwogICAgfQp9KTsKCnZhciBfQWxlcnRzID0gcmVxdWlyZSgnLi9BbGVydHMnKTsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnQWxlcnRzJywgewogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgewogICAgICAgIHJldHVybiBfQWxlcnRzLkFsZXJ0czsKICAgIH0KfSk7Cn0seyIuL0FsZXJ0cyI6NjUsIi4vQ29tbWl0SGFzaCI6NjYsIi4vRG93bmxvYWRMaW5rIjo2NywiLi9FbXB0eVN0YXRlSWNvbiI6NjgsIi4vRW1wdHlTdGF0ZVZpZXciOjY5LCIuL0Vycm9yTWVzc2FnZSI6NzAsIi4vRXhwYW5kYWJsZVBhdGgiOjcxLCIuL0ZpbGVTaXplIjo3MiwiLi9GaWx0ZXJhYmxlTGlzdCI6NzMsIi4vRmxvYXRpbmdFbGVtZW50Ijo3NCwiLi9JY29uQnV0dG9uIjo3NSwiLi9MaXN0Ijo3NiwiLi9QaXBlbGluZUdyYXBoIjo3NywiLi9Qb3BvdmVyIjo3OCwiLi9Qb3NpdGlvbiI6NzksIi4vUHJvZ3Jlc3MiOjgwLCIuL1JlYWRhYmxlRGF0ZSI6ODEsIi4vUmVzdWx0SXRlbSI6ODIsIi4vVGFiTGluayI6ODQsIi4vVGFibGUiOjg1LCIuL1RpbWVEdXJhdGlvbiI6ODYsIi4vVG9hc3QiOjg3LCIuL1RvYXN0ZXIiOjg4LCIuL2RpYWxvZyI6OTIsIi4vZmF2b3JpdGUvRmF2b3JpdGUiOjkzLCIuL2Zvcm1zL0NoZWNrYm94Ijo5NCwiLi9mb3Jtcy9Ecm9wZG93biI6OTUsIi4vZm9ybXMvRm9ybUVsZW1lbnQiOjk2LCIuL2Zvcm1zL1Bhc3N3b3JkSW5wdXQiOjk3LCIuL2Zvcm1zL1JhZGlvQnV0dG9uR3JvdXAiOjk4LCIuL2Zvcm1zL1RleHRBcmVhIjo5OSwiLi9mb3Jtcy9UZXh0SW5wdXQiOjEwMSwiLi9oZWFkZXIiOjEwNiwiLi9wYWdlIjoxMDgsIi4vc3RhdHVzL0xpdmVTdGF0dXNJbmRpY2F0b3IiOjEwOSwiLi9zdGF0dXMvU3RhdHVzSW5kaWNhdG9yIjoxMTAsIi4vd2VhdGhlci1pY29uIjoxMTN9XSwxMDg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewoidXNlIHN0cmljdCI7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5QYWdlID0gdW5kZWZpbmVkOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgicmVhY3QiKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKdmFyIFBhZ2UgPSBleHBvcnRzLlBhZ2UgPSBmdW5jdGlvbiAoX0NvbXBvbmVudCkgewogICAgX2luaGVyaXRzKFBhZ2UsIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIFBhZ2UoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFBhZ2UpOwoKICAgICAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKFBhZ2UuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihQYWdlKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFBhZ2UsIFt7CiAgICAgICAga2V5OiAicmVuZGVyIiwKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAiZGl2IiwKICAgICAgICAgICAgICAgIHsgaWQ6ICJvdXRlciIgfSwKICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuY2hpbGRyZW4KICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFBhZ2U7Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpQYWdlLnByb3BUeXBlcyA9IHsKICAgIGNoaWxkcmVuOiBfcmVhY3QuUHJvcFR5cGVzLm5vZGUKfTsKfSx7InJlYWN0Ijo2MjN9XSwxMDk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5MaXZlU3RhdHVzSW5kaWNhdG9yID0gdW5kZWZpbmVkOwoKdmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50Jyk7Cgp2YXIgX21vbWVudDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9tb21lbnQpOwoKdmFyIF9TdGF0dXNJbmRpY2F0b3IgPSByZXF1aXJlKCcuL1N0YXR1c0luZGljYXRvcicpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKLyoqCiAqIExpdmVTdGF0dXNJbmRpY2F0b3IgaXMgYSB3cmFwcGVyIGFyb3VuZCBTdGF0dXNJbmRpY2F0b3IgdGhhdCBhbGxvd3MKICogZm9yIGFuIGluLXByb2dyZXNzIHN0YXR1cyB0byBzZWxmIHVwZGF0ZS4KICoKICogUHJvcGVydGllczoKICogImVzdGltYXRlZER1cmF0aW9uIjogdGltZSBpbiBtaWxsaXMgb3ZlciB3aGljaCB0aGUgcHJvZ3Jlc3MgaW5kaWNhdG9yIHdpbGwgdXBkYXRlLgogKiAic3RhcnRUaW1lIjogSVNPLTg2MDEgc3RyaW5nIGluZGljYXRpbmcgd2hlbiB0cmFja2luZyBvZiBwcm9ncmVzcyBiZWdpbnMgZnJvbS4KICovCnZhciBMaXZlU3RhdHVzSW5kaWNhdG9yID0gZXhwb3J0cy5MaXZlU3RhdHVzSW5kaWNhdG9yID0gZnVuY3Rpb24gKF9Db21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhMaXZlU3RhdHVzSW5kaWNhdG9yLCBfQ29tcG9uZW50KTsKCiAgICBmdW5jdGlvbiBMaXZlU3RhdHVzSW5kaWNhdG9yKHByb3BzKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIExpdmVTdGF0dXNJbmRpY2F0b3IpOwoKICAgICAgICB2YXIgX3RoaXMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoTGl2ZVN0YXR1c0luZGljYXRvci5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKExpdmVTdGF0dXNJbmRpY2F0b3IpKS5jYWxsKHRoaXMsIHByb3BzKSk7CgogICAgICAgIF90aGlzLnN0YXRlID0gewogICAgICAgICAgICAvLyBwZXJjZW50YWdlIG9mIHByb2dyZXNzIGN1cnJlbnRseSBkcmF3biBpbiBVSQogICAgICAgICAgICBwZXJjZW50YWdlOiAwCiAgICAgICAgfTsKCiAgICAgICAgLy8gcGVyY2VudGFnZSBvZiBwcm9ncmVzcyBiYXNlZCBvbiBsYXN0IGNoZWNrCiAgICAgICAgX3RoaXMucGVyY2VudGFnZSA9IDA7CiAgICAgICAgX3RoaXMuc3RhcnRUaW1lID0gbnVsbDsKICAgICAgICBfdGhpcy5jbGVhckludGVydmFsSWQgPSAwOwogICAgICAgIF90aGlzLmFuaW1hdGlvbkZyYW1lSWQgPSAwOwogICAgICAgIHJldHVybiBfdGhpczsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoTGl2ZVN0YXR1c0luZGljYXRvciwgW3sKICAgICAgICBrZXk6ICdjb21wb25lbnREaWRNb3VudCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkgewogICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplUHJvZ3Jlc3ModGhpcy5wcm9wcyk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykgewogICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplUHJvZ3Jlc3MobmV4dFByb3BzKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX2luaXRpYWxpemVQcm9ncmVzcycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9pbml0aWFsaXplUHJvZ3Jlc3MocHJvcHMpIHsKICAgICAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7CgogICAgICAgICAgICAvLyBlbnN1cmUgd2UgZG9uJ3QgbGVhayBzZXRJbnRlcnZhbCBieSBwcm9hY3RpdmVseSBjbGVhcmluZyBpdAogICAgICAgICAgICAvLyB0aGUgY29kZSB3aWxsIHJlc3RhcnQgdGhlIGludGVydmFsIGlmIG5lZWRlZAogICAgICAgICAgICB0aGlzLl9zdG9wUHJvZ3Jlc3NVcGRhdGVzKCk7CgogICAgICAgICAgICBpZiAoIXByb3BzKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBjbGVhblJlc3VsdCA9ICgwLCBfU3RhdHVzSW5kaWNhdG9yLmRlY29kZVJlc3VsdFZhbHVlKShwcm9wcy5yZXN1bHQpOwogICAgICAgICAgICAvLyBUT0RPOiBwdWxsIGluIHZhbGlkUmVzdWx0VmFsdWVzIGZyb20gU3RhdHVzSW5kaWNhdG9yCiAgICAgICAgICAgIHZhciBpc1J1bm5pbmcgPSBjbGVhblJlc3VsdCA9PT0gJ3J1bm5pbmcnOwoKICAgICAgICAgICAgaWYgKGlzUnVubmluZykgewogICAgICAgICAgICAgICAgdGhpcy5zdGFydFRpbWUgPSAoMCwgX21vbWVudDIuZGVmYXVsdCkocHJvcHMuc3RhcnRUaW1lLCBfbW9tZW50Mi5kZWZhdWx0LklTT184NjAxKS51dGNPZmZzZXQocHJvcHMuc3RhcnRUaW1lKTsKCiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgdGhlIHByb2dyZXNzIGVhY2ggc2Vjb25kCiAgICAgICAgICAgICAgICB0aGlzLmNsZWFySW50ZXJ2YWxJZCA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICBfdGhpczIuX3VwZGF0ZVByb2dyZXNzKF90aGlzMi5wcm9wcyk7CiAgICAgICAgICAgICAgICB9LCAxMDAwKTsKCiAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVQcm9ncmVzcyhwcm9wcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX3VwZGF0ZVByb2dyZXNzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX3VwZGF0ZVByb2dyZXNzKHByb3BzKSB7CiAgICAgICAgICAgIHZhciBub3cgPSAoMCwgX21vbWVudDIuZGVmYXVsdCkoKTsKICAgICAgICAgICAgdmFyIGVsYXBzZWQgPSBub3cuZGlmZih0aGlzLnN0YXJ0VGltZSk7CiAgICAgICAgICAgIHZhciBlc3RpbWF0ZWREdXJhdGlvbiA9IHByb3BzLmVzdGltYXRlZER1cmF0aW9uOwoKICAgICAgICAgICAgaWYgKGVsYXBzZWQgPiAwICYmIGVzdGltYXRlZER1cmF0aW9uID4gMCkgewogICAgICAgICAgICAgICAgdGhpcy5wZXJjZW50YWdlID0gTWF0aC5mbG9vcihlbGFwc2VkIC8gZXN0aW1hdGVkRHVyYXRpb24gKiAxMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gaWYgYm90aCBhcmVuJ3QgYXZhaWxhYmxlLCBzZXQgdG8gJ2luZGV0ZXJtaW5hdGUnIHN0YXRlIAogICAgICAgICAgICAgICAgdGhpcy5wZXJjZW50YWdlID0gMTAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoMCA8PSB0aGlzLnBlcmNlbnRhZ2UgJiYgdGhpcy5wZXJjZW50YWdlIDw9IDEwMCkgewogICAgICAgICAgICAgICAgdGhpcy5fZHJhd1Byb2dyZXNzKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBzZXQgdGhlIHBlcmNlbnRhZ2UgPiAxMDAgc28gdGhlIGluZGV0ZXJtaW5hdGUgc3Bpbm5lciB3aWxsIGRpc3BsYXkKICAgICAgICAgICAgICAgIC8vIG5vIG1vcmUgcHJvZ3Jlc3MgdXBkYXRlcyBhcmUgcmVxdWlyZWQKICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoewogICAgICAgICAgICAgICAgICAgIHBlcmNlbnRhZ2U6IDEwMQogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgdGhpcy5fc3RvcFByb2dyZXNzVXBkYXRlcygpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ19kcmF3UHJvZ3Jlc3MnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfZHJhd1Byb2dyZXNzKCkgewogICAgICAgICAgICB2YXIgX3RoaXMzID0gdGhpczsKCiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnBlcmNlbnRhZ2UgPD0gdGhpcy5wZXJjZW50YWdlKSB7CiAgICAgICAgICAgICAgICAvLyBpbmNyZW1lbnQgdGhlIHByb2dyZXNzIHRvIHRyaWdnZXIgYSByZXJlbmRlcgogICAgICAgICAgICAgICAgLy8gdGhlbiByZXF1ZXN0IGFub3RoZXIgZHJhdyBvbiBuZXh0IGZyYW1lCiAgICAgICAgICAgICAgICB2YXIgbmV3UGVyY2VudCA9IHRoaXMuc3RhdGUucGVyY2VudGFnZSArIDE7CiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsKICAgICAgICAgICAgICAgICAgICBwZXJjZW50YWdlOiBuZXdQZXJjZW50CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICB0aGlzLmFuaW1hdGlvbkZyYW1lSWQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIF90aGlzMy5fZHJhd1Byb2dyZXNzKCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfc3RvcFByb2dyZXNzVXBkYXRlcycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9zdG9wUHJvZ3Jlc3NVcGRhdGVzKCkgewogICAgICAgICAgICBjbGVhckludGVydmFsKHRoaXMuY2xlYXJJbnRlcnZhbElkKTsKICAgICAgICAgICAgdGhpcy5jbGVhckludGVydmFsSWQgPSAwOwogICAgICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLmFuaW1hdGlvbkZyYW1lSWQpOwogICAgICAgICAgICB0aGlzLmFuaW1hdGlvbkZyYW1lSWQgPSAwOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsVW5tb3VudCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkgewogICAgICAgICAgICB0aGlzLl9zdG9wUHJvZ3Jlc3NVcGRhdGVzKCk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ3JlbmRlcicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KF9TdGF0dXNJbmRpY2F0b3IuU3RhdHVzSW5kaWNhdG9yLCBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcywgeyBwZXJjZW50YWdlOiB0aGlzLnN0YXRlLnBlcmNlbnRhZ2UgfSkpOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gTGl2ZVN0YXR1c0luZGljYXRvcjsKfShfcmVhY3QuQ29tcG9uZW50KTsKCkxpdmVTdGF0dXNJbmRpY2F0b3IucHJvcFR5cGVzID0gewogICAgcmVzdWx0OiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIHBlcmNlbnRhZ2U6IF9yZWFjdC5Qcm9wVHlwZXMubnVtYmVyLAogICAgd2lkdGg6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgaGVpZ2h0OiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIG5vQmFja2dyb3VuZDogX3JlYWN0LlByb3BUeXBlcy5ib29sLAogICAgc3RhcnRUaW1lOiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIGVzdGltYXRlZER1cmF0aW9uOiBfcmVhY3QuUHJvcFR5cGVzLm51bWJlcgp9Owp9LHsiLi9TdGF0dXNJbmRpY2F0b3IiOjExMCwibW9tZW50IjozOTIsInJlYWN0Ijo2MjN9XSwxMTA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5TdmdTdGF0dXMgPSBleHBvcnRzLlN2Z1NwaW5uZXIgPSBleHBvcnRzLlN0YXR1c0luZGljYXRvciA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKZXhwb3J0cy5kZWNvZGVSZXN1bHRWYWx1ZSA9IGRlY29kZVJlc3VsdFZhbHVlOwpleHBvcnRzLmdldEdyb3VwRm9yUmVzdWx0ID0gZ2V0R3JvdXBGb3JSZXN1bHQ7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9TdmdTcGlubmVyID0gcmVxdWlyZSgnLi9TdmdTcGlubmVyJyk7Cgp2YXIgX1N2Z1NwaW5uZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU3ZnU3Bpbm5lcik7Cgp2YXIgX1N2Z1N0YXR1cyA9IHJlcXVpcmUoJy4vU3ZnU3RhdHVzJyk7Cgp2YXIgX1N2Z1N0YXR1czIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TdmdTdGF0dXMpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKdmFyIHZhbGlkUmVzdWx0VmFsdWVzID0gewogICAgLy8gTW9zdGx5IGZyb20gaW8vamVua2lucy9ibHVlb2NlYW4vcmVzdC9tb2RlbC9CbHVlUnVuLmphdmEKICAgIHN1Y2Nlc3M6ICdzdWNjZXNzJywKICAgIGZhaWx1cmU6ICdmYWlsdXJlJywKICAgIHJ1bm5pbmc6ICdydW5uaW5nJywKICAgIHF1ZXVlZDogJ3F1ZXVlZCcsCiAgICBwYXVzZWQ6ICdwYXVzZWQnLAogICAgdW5zdGFibGU6ICd1bnN0YWJsZScsCiAgICBhYm9ydGVkOiAnYWJvcnRlZCcsCiAgICBub3RfYnVpbHQ6ICdub3RfYnVpbHQnLAogICAgdW5rbm93bjogJ3Vua25vd24nCn07CgovLyBFbnVtIHR5cGUgZnJvbSBjb25zdCB2YWxpZFJlc3VsdFZhbHVlcwoKCi8vIENsZWFuIHVwIHJlc3VsdCB2YWx1ZSwgb3IgcmV0dXJuICJpbnZhbGlkIiB2YWx1ZQpmdW5jdGlvbiBkZWNvZGVSZXN1bHRWYWx1ZShyZXN1bHRNYXliZSkgewogICAgaWYgKHJlc3VsdE1heWJlKSB7CiAgICAgICAgdmFyIGxjUmVzdWx0ID0gU3RyaW5nKHJlc3VsdE1heWJlKS50b0xvd2VyQ2FzZSgpOwogICAgICAgIGlmICh2YWxpZFJlc3VsdFZhbHVlcy5oYXNPd25Qcm9wZXJ0eShsY1Jlc3VsdCkpIHsKICAgICAgICAgICAgcmV0dXJuIHZhbGlkUmVzdWx0VmFsdWVzW2xjUmVzdWx0XTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gJ3Vua25vd24nOwp9CgovLyBSZXR1cm5zIHRoZSBjb3JyZWN0IDxnPiBlbGVtZW50IGZvciB0aGUgcmVzdWx0IC8gcHJvZ3Jlc3MgcGVyY2VudApmdW5jdGlvbiBnZXRHcm91cEZvclJlc3VsdChyZXN1bHQsIHBlcmNlbnRhZ2UsIHJhZGl1cykgewogICAgaWYgKHVzZXNTdmdTcGlubmVyKHJlc3VsdCkpIHsKICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoX1N2Z1NwaW5uZXIyLmRlZmF1bHQsIHsgcmFkaXVzOiByYWRpdXMsIHJlc3VsdDogcmVzdWx0LCBwZXJjZW50YWdlOiBwZXJjZW50YWdlIH0pOwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoX1N2Z1N0YXR1czIuZGVmYXVsdCwgeyByYWRpdXM6IHJhZGl1cywgcmVzdWx0OiByZXN1bHQgfSk7CiAgICB9Cn0KCi8vIGluZGljYXRlcyB3aGV0aGVyIHJlc3VsdCBzaG91bGQgdXNlIHRoZSBTcGlubmVyIChvciBTdGF0dXMpCmZ1bmN0aW9uIHVzZXNTdmdTcGlubmVyKHJlc3VsdCkgewogICAgc3dpdGNoIChyZXN1bHQpIHsKICAgICAgICBjYXNlICdydW5uaW5nJzoKICAgICAgICBjYXNlICdxdWV1ZWQnOgogICAgICAgIGNhc2UgJ25vdF9idWlsdCc6CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQoKdmFyIFN0YXR1c0luZGljYXRvciA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoU3RhdHVzSW5kaWNhdG9yLCBfQ29tcG9uZW50KTsKCiAgICBmdW5jdGlvbiBTdGF0dXNJbmRpY2F0b3IoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFN0YXR1c0luZGljYXRvcik7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoU3RhdHVzSW5kaWNhdG9yLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoU3RhdHVzSW5kaWNhdG9yKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFN0YXR1c0luZGljYXRvciwgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzLAogICAgICAgICAgICAgICAgcmVzdWx0ID0gX3Byb3BzLnJlc3VsdCwKICAgICAgICAgICAgICAgIHBlcmNlbnRhZ2UgPSBfcHJvcHMucGVyY2VudGFnZSwKICAgICAgICAgICAgICAgIF9wcm9wcyR3aWR0aCA9IF9wcm9wcy53aWR0aCwKICAgICAgICAgICAgICAgIHdpZHRoID0gX3Byb3BzJHdpZHRoID09PSB1bmRlZmluZWQgPyAnMjRweCcgOiBfcHJvcHMkd2lkdGgsCiAgICAgICAgICAgICAgICBfcHJvcHMkaGVpZ2h0ID0gX3Byb3BzLmhlaWdodCwKICAgICAgICAgICAgICAgIGhlaWdodCA9IF9wcm9wcyRoZWlnaHQgPT09IHVuZGVmaW5lZCA/ICcyNHB4JyA6IF9wcm9wcyRoZWlnaHQsCiAgICAgICAgICAgICAgICBub0JhY2tncm91bmQgPSBfcHJvcHMubm9CYWNrZ3JvdW5kOwoKCiAgICAgICAgICAgIHZhciBncm91cENsYXNzZXMgPSBbJ3N2Z1Jlc3VsdFN0YXR1cycsIG5vQmFja2dyb3VuZCA/ICduby1iYWNrZ3JvdW5kJyA6IG51bGxdOwoKICAgICAgICAgICAgdmFyIHJhZGl1cyA9IDEyOyAvLyBweC4KICAgICAgICAgICAgdmFyIHJlc3VsdENsZWFuID0gZGVjb2RlUmVzdWx0VmFsdWUocmVzdWx0KTsKCiAgICAgICAgICAgIHZhciB0cmFuc2xhdGUgPSAndHJhbnNsYXRlKCcgKyByYWRpdXMgKyAnICcgKyByYWRpdXMgKyAnKSc7CiAgICAgICAgICAgIC8vIFN2Z1N0YXR1cyBuZWVkcyB0byBiZSBzY2FsZWQgdXAgdG8gZmlsbCB0aGUgYXZhaWxhYmxlIHNwYWNlIHdoZW4gbm8gYmcgaXMgdXNlZAogICAgICAgICAgICB2YXIgc2NhbGUgPSBub0JhY2tncm91bmQgJiYgIXVzZXNTdmdTcGlubmVyKHJlc3VsdENsZWFuKSA/ICdzY2FsZSgyLDIpJyA6IG51bGw7CgogICAgICAgICAgICB2YXIgdHJhbnNmb3JtcyA9IFt0cmFuc2xhdGUsIHNjYWxlXTsKCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdzdmcnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IGdyb3VwQ2xhc3Nlcy5qb2luKCcgJyksIHhtbG5zOiAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLAogICAgICAgICAgICAgICAgICAgIHZpZXdCb3g6ICcwIDAgJyArIDIgKiByYWRpdXMgKyAnICcgKyAyICogcmFkaXVzLCB3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ3RpdGxlJywKICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgIHJlc3VsdENsZWFuCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgJ2cnLAogICAgICAgICAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2Zvcm1zLmpvaW4oJyAnKSB9LAogICAgICAgICAgICAgICAgICAgIGdldEdyb3VwRm9yUmVzdWx0KHJlc3VsdENsZWFuLCBwZXJjZW50YWdlLCByYWRpdXMpCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBTdGF0dXNJbmRpY2F0b3I7Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpTdGF0dXNJbmRpY2F0b3IucHJvcFR5cGVzID0gewogICAgcmVzdWx0OiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIHBlcmNlbnRhZ2U6IF9yZWFjdC5Qcm9wVHlwZXMubnVtYmVyLAogICAgd2lkdGg6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLAogICAgaGVpZ2h0OiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIG5vQmFja2dyb3VuZDogX3JlYWN0LlByb3BUeXBlcy5ib29sCn07CgpTdGF0dXNJbmRpY2F0b3IudmFsaWRSZXN1bHRWYWx1ZXMgPSB2YWxpZFJlc3VsdFZhbHVlczsKCmV4cG9ydHMuU3RhdHVzSW5kaWNhdG9yID0gU3RhdHVzSW5kaWNhdG9yOwpleHBvcnRzLlN2Z1NwaW5uZXIgPSBfU3ZnU3Bpbm5lcjIuZGVmYXVsdDsKZXhwb3J0cy5TdmdTdGF0dXMgPSBfU3ZnU3RhdHVzMi5kZWZhdWx0Owp9LHsiLi9TdmdTcGlubmVyIjoxMTEsIi4vU3ZnU3RhdHVzIjoxMTIsInJlYWN0Ijo2MjN9XSwxMTE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKZXhwb3J0cy5zdHJva2VXaWR0aCA9IHVuZGVmaW5lZDsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKdmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7Cgp2YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTsKCnZhciBfU1ZHID0gcmVxdWlyZSgnLi4vU1ZHJyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9Cgp2YXIgc3Ryb2tlV2lkdGggPSBleHBvcnRzLnN0cm9rZVdpZHRoID0gMy41OyAvLyBweC4gTWF5YmUgd2UgY2FuIGZldGNoIHRoaXMgZnJvbSBDU1MgYXQgcnVudGltZSBpbiB0aGUgZnV0dXJlCgp2YXIgU3ZnU3Bpbm5lciA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoU3ZnU3Bpbm5lciwgX0NvbXBvbmVudCk7CgogICAgZnVuY3Rpb24gU3ZnU3Bpbm5lcigpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgU3ZnU3Bpbm5lcik7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoU3ZnU3Bpbm5lci5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKFN2Z1NwaW5uZXIpKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoU3ZnU3Bpbm5lciwgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciByZXN1bHQgPSB0aGlzLnByb3BzLnJlc3VsdDsKCiAgICAgICAgICAgIHZhciByYWRpdXMgPSAodGhpcy5wcm9wcy5yYWRpdXMgfHwgMTIpIC0gMC41ICogc3Ryb2tlV2lkdGg7IC8vIE5vICJpbnNpZGUiIHN0cm9raW5nIGluIFNWR2AKCiAgICAgICAgICAgIHZhciBwZXJjZW50YWdlID0gdGhpcy5wcm9wcy5wZXJjZW50YWdlOwogICAgICAgICAgICB2YXIgZ3JvdXBDbGFzc2VzID0gWydwcm9ncmVzcy1zcGlubmVyJywgcmVzdWx0XTsKCiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09ICdxdWV1ZWQnKSB7CiAgICAgICAgICAgICAgICBwZXJjZW50YWdlID0gMDsKICAgICAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQgPT09ICdub3RfYnVpbHQnKSB7CiAgICAgICAgICAgICAgICBwZXJjZW50YWdlID0gMDsKICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgcGVyY2VudGFnZSAhPT0gJ251bWJlcicgfHwgaXNOYU4ocGVyY2VudGFnZSkgfHwgcGVyY2VudGFnZSA8IDApIHsKICAgICAgICAgICAgICAgIHBlcmNlbnRhZ2UgPSAwOwogICAgICAgICAgICB9IGVsc2UgaWYgKHBlcmNlbnRhZ2UgPT09IDEwMCkgewogICAgICAgICAgICAgICAgZ3JvdXBDbGFzc2VzLnB1c2goJ3BjLW92ZXItMTAwJyk7CiAgICAgICAgICAgICAgICBwZXJjZW50YWdlID0gMDsKICAgICAgICAgICAgfSBlbHNlIGlmIChwZXJjZW50YWdlID4gMTAwKSB7CiAgICAgICAgICAgICAgICBncm91cENsYXNzZXMucHVzaCgnc3BpbicpOwogICAgICAgICAgICAgICAgcGVyY2VudGFnZSA9IDI1OwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgcm90YXRlID0gcGVyY2VudGFnZSAvIDEwMCAqIDM2MDsKICAgICAgICAgICAgdmFyIGQgPSAoMCwgX1NWRy5kZXNjcmliZUFyY0FzUGF0aCkoMCwgMCwgcmFkaXVzLCAwLCByb3RhdGUpOwoKICAgICAgICAgICAgdmFyIGlubmVyUmFkaXVzID0gcmFkaXVzIC8gMzsKCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdnJywKICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBncm91cENsYXNzZXMuam9pbignICcpIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgnY2lyY2xlJywgeyBjeDogJzAnLCBjeTogJzAnLCByOiByYWRpdXMsIHN0cm9rZVdpZHRoOiBzdHJva2VXaWR0aCB9KSwKICAgICAgICAgICAgICAgIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KCdjaXJjbGUnLCB7IGNsYXNzTmFtZTogJ2lubmVyJywgY3g6ICcwJywgY3k6ICcwJywgcjogaW5uZXJSYWRpdXMgfSksCiAgICAgICAgICAgICAgICBwZXJjZW50YWdlID8gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IGNsYXNzTmFtZTogcmVzdWx0LCBmaWxsOiAnbm9uZScsIHN0cm9rZVdpZHRoOiBzdHJva2VXaWR0aCwgZDogZCB9KSA6IG51bGwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFN2Z1NwaW5uZXI7Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpleHBvcnRzLmRlZmF1bHQgPSBTdmdTcGlubmVyOwoKClN2Z1NwaW5uZXIucHJvcFR5cGVzID0gewogICAgcGVyY2VudGFnZTogX3JlYWN0LlByb3BUeXBlcy5udW1iZXIsCiAgICByYWRpdXM6IF9yZWFjdC5Qcm9wVHlwZXMubnVtYmVyLAogICAgcmVzdWx0OiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZwp9Owp9LHsiLi4vU1ZHIjo4MywicmVhY3QiOjYyM31dLDExMjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7CgpleHBvcnRzLmdldEdseXBoRm9yID0gZ2V0R2x5cGhGb3I7Cgp2YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTsKCnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpOwoKdmFyIF9TdmdTcGlubmVyID0gcmVxdWlyZSgnLi9TdmdTcGlubmVyJyk7Cgp2YXIgX1NWRyA9IHJlcXVpcmUoJy4uL1NWRycpOwoKZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKLy8gVGhlc2Ugd2VyZSBtb3N0bHkgdGFrZW4gZnJvbSBTVkcgYW5kIHByZS10cmFuc2xhdGVkCnZhciBxdWVzdGlvbk1hcmtQYXRoID0gIk0tMC42NzIsNC4yOSBMMC43NTMsNC4yOSBMMC43NTMsNS43OCBMLTAuNjcyLDUuNzggTC0wLjY3Miw0LjI5IFogTS0yLjIxLC0zLjk0ICIgKyAiQy0xLjYzLC00LjU3IC0wLjgzMCwtNC44OCAwLjE4NywtNC44OCBDMS4xMywtNC44OCAxLjg4LC00LjYxIDIuNDUsLTQuMDcgQzMuMDEsLTMuNTQgMy4zMCwtMi44NSAzLjMwLC0yLjAxICIgKyAiQzMuMzAsLTEuNTEgMy4xOSwtMS4xMCAyLjk5LC0wLjc4MiBDMi43OCwtMC40NjcgMi4zNiwtMC4wMDM0NiAxLjczLDAuNjA4IEMxLjI3LDEuMDUgMC45NzIsMS40MyAwLjgzNiwxLjc0ICIgKyAiQzAuNzAwLDIuMDQgMC42MzIsMi41MCAwLjYzMiwzLjEwIEwtMC42NDQsMy4xMCBDLTAuNjQ0LDIuNDIgLTAuNTYyLDEuODcgLTAuNDAwLDEuNDUgIiArICJDLTAuMjM4LDEuMDMgMC4xMTgsMC41NTMgMC42NjgsMC4wMTMzIEwxLjI0LC0wLjU1MyBDMS40MSwtMC43MTUgMS41NSwtMC44ODUgMS42NiwtMS4wNiAiICsgIkMxLjg1LC0xLjM3IDEuOTQsLTEuNjkgMS45NCwtMi4wMyBDMS45NCwtMi41MCAxLjgwLC0yLjkwIDEuNTIsLTMuMjUgQzEuMjQsLTMuNTkgMC43ODIsLTMuNzYgMC4xMzcsLTMuNzYgIiArICJDLTAuNjYwLC0zLjc2IC0xLjIxLC0zLjQ3IC0xLjUyLC0yLjg3IEMtMS42OSwtMi41NCAtMS43OSwtMi4wNyAtMS44MSwtMS40NSBMLTMuMDksLTEuNDUgIiArICJDLTMuMDksLTIuNDggLTIuODAsLTMuMzEgLTIuMjEsLTMuOTQgTC0yLjIxLC0zLjk0IFoiOwoKdmFyIGhvbGxvd0NpcmNsZVBhdGggPSAiTSAwLC02IEEgNiw2IDAgMCAxIDAsNiBBIDYsNiAwIDAgMSAwLC02IG0gMCwxLjMgQSA0LDQgMCAwIDAgMCw0LjcgQSA0LDQgMCAwIDAgMCwtNC43IjsKCnZhciBjaGVja01hcmtQb2ludHMgPSAiLTIuMDAgMi44MCAtNC44MCAwLjAwIC01LjczIDAuOTMzIC0yLjAwIDQuNjcgNi4wMCAtMy4zMyA1LjA3IC00LjI3IjsKCnZhciBjcm9zc1BvaW50cyA9ICI0LjY3IC0zLjczIDMuNzMgLTQuNjcgMCAtMC45NCAtMy43MyAtNC42NyAtNC42NyAtMy43MyAtMC45NCAwIC00LjY3IDMuNzMgLTMuNzMgNC42NyAwIDAuOTQgIiArICIzLjczIDQuNjcgNC42NyAzLjczIDAuOTQgMCI7CgovKioKICAgIFJldHVybnMgYSBnbHlwaCAoYXMgPGc+KSBmb3Igc3BlY2lmaWVkIHJlc3VsdCB0eXBlLiBDZW50ZXJlZCBhdCAwLDAsIHNjYWxlZCBmb3IgMjRweCBpY29ucy4KICovCmZ1bmN0aW9uIGdldEdseXBoRm9yKHJlc3VsdCkgewoKICAgIC8vIE5COiBJZiB3ZSBzdGFydCByZXNpemluZyB0aGVzZSB0aGluZ3MsIHdlJ2xsIG5lZWQgdG8gdXNlIHJhZGl1cy8xMiB0bwogICAgLy8gZ2VuZXJhdGUgYSAic2NhbGUiIHRyYW5zZm9ybSBmb3IgdGhlIGdyb3VwCgogICAgc3dpdGNoIChyZXN1bHQpIHsKICAgICAgICBjYXNlICJhYm9ydGVkIjoKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2cnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdyZXN1bHQtc3RhdHVzLWdseXBoJyB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BvbHlnb24nLCB7IHBvaW50czogJy01IC0xIDUgLTEgNSAxIC01IDEnIH0pCiAgICAgICAgICAgICk7CiAgICAgICAgY2FzZSAicGF1c2VkIjoKICAgICAgICAgICAgLy8gInx8IgogICAgICAgICAgICAvLyA4cHggOS4zcHgKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2cnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdyZXN1bHQtc3RhdHVzLWdseXBoJyB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BvbHlnb24nLCB7IHBvaW50czogJy00LC00LjY1IC00LDQuNjUgLTQsNC42NSAtMS41LDQuNjUgLTEuNSwtNC42NScgfSksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncG9seWdvbicsIHsgcG9pbnRzOiAnNCwtNC42NSAxLjUsLTQuNjUgMS41LC00LjY1IDEuNSw0LjY1IDQsNC42NScgfSkKICAgICAgICAgICAgKTsKICAgICAgICBjYXNlICJ1bnN0YWJsZSI6CiAgICAgICAgICAgIC8vICIhIgogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnZycsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3Jlc3VsdC1zdGF0dXMtZ2x5cGgnIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncG9seWdvbicsIHsgcG9pbnRzOiAnLTEgLTUgMSAtNSAxIDEgLTEgMScgfSksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncG9seWdvbicsIHsgcG9pbnRzOiAnLTEgMyAxIDMgMSA1IC0xIDUnIH0pCiAgICAgICAgICAgICk7CiAgICAgICAgY2FzZSAic3VjY2VzcyI6CiAgICAgICAgICAgIC8vIGNoZWNrLW1hcmsKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2cnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdyZXN1bHQtc3RhdHVzLWdseXBoJyB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BvbHlnb24nLCB7IHBvaW50czogY2hlY2tNYXJrUG9pbnRzIH0pCiAgICAgICAgICAgICk7CiAgICAgICAgY2FzZSAiZmFpbHVyZSI6CiAgICAgICAgICAgIC8vICJYIgogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgICAgICAgICAnZycsCiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3Jlc3VsdC1zdGF0dXMtZ2x5cGgnIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncG9seWdvbicsIHsgcG9pbnRzOiBjcm9zc1BvaW50cyB9KQogICAgICAgICAgICApOwogICAgICAgIGNhc2UgInJ1bm5pbmciOgogICAgICAgICAgICAvLyBob2xsb3cgY2lyY2xlCiAgICAgICAgICAgIHZhciByYWRpdXMgPSAxMiAtIDAuNSAqIF9TdmdTcGlubmVyLnN0cm9rZVdpZHRoOwogICAgICAgICAgICB2YXIgZCA9ICgwLCBfU1ZHLmRlc2NyaWJlQXJjQXNQYXRoKSgwLCAwLCByYWRpdXMsIDAsIDEyMCk7CiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdnJywKICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAncmVzdWx0LXN0YXR1cy1nbHlwaCcsIHRyYW5zZm9ybTogJ3NjYWxlKDAuNSknIH0sCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgnY2lyY2xlJywgeyBzdHJva2U6ICcjYTdjN2YyJywKICAgICAgICAgICAgICAgICAgICBmaWxsOiAnbm9uZScsCiAgICAgICAgICAgICAgICAgICAgY3g6ICcwJywgY3k6ICcwJywgcjogcmFkaXVzLCBzdHJva2VXaWR0aDogX1N2Z1NwaW5uZXIuc3Ryb2tlV2lkdGggfSksCiAgICAgICAgICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsKICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICd3aGl0ZScsCiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnc3BpbicsIGZpbGw6ICdub25lJywgc3Ryb2tlV2lkdGg6IF9TdmdTcGlubmVyLnN0cm9rZVdpZHRoLAogICAgICAgICAgICAgICAgICAgIGQ6IGQgfSkKICAgICAgICAgICAgKTsKICAgICAgICBjYXNlICJub3RfYnVpbHQiOgogICAgICAgIGNhc2UgInF1ZXVlZCI6CiAgICAgICAgICAgIC8vIGhvbGxvdyBjaXJjbGUKICAgICAgICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KAogICAgICAgICAgICAgICAgJ2cnLAogICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdyZXN1bHQtc3RhdHVzLWdseXBoJyB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3BhdGgnLCB7IHRyYW5zZm9ybTogJ3NjYWxlKDAuOSknLCBkOiBob2xsb3dDaXJjbGVQYXRoIH0pCiAgICAgICAgICAgICk7CiAgICB9CiAgICAvLyAiPyIgZm9yIHVua25vd24gLyBpbnZhbGlkCiAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgJ2cnLAogICAgICAgIHsgY2xhc3NOYW1lOiAncmVzdWx0LXN0YXR1cy1nbHlwaCcgfSwKICAgICAgICBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgncGF0aCcsIHsgZDogcXVlc3Rpb25NYXJrUGF0aCB9KQogICAgKTsKfQoKdmFyIFN2Z1N0YXR1cyA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoU3ZnU3RhdHVzLCBfQ29tcG9uZW50KTsKCiAgICBmdW5jdGlvbiBTdmdTdGF0dXMoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFN2Z1N0YXR1cyk7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoU3ZnU3RhdHVzLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoU3ZnU3RhdHVzKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFN2Z1N0YXR1cywgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzLAogICAgICAgICAgICAgICAgcmVzdWx0ID0gX3Byb3BzLnJlc3VsdCwKICAgICAgICAgICAgICAgIF9wcm9wcyRyYWRpdXMgPSBfcHJvcHMucmFkaXVzLAogICAgICAgICAgICAgICAgcmFkaXVzID0gX3Byb3BzJHJhZGl1cyA9PT0gdW5kZWZpbmVkID8gMTIgOiBfcHJvcHMkcmFkaXVzOwoKCiAgICAgICAgICAgIHJldHVybiBfcmVhY3QyLmRlZmF1bHQuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICdnJywKICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnc3ZnUmVzdWx0U3RhdHVzJyB9LAogICAgICAgICAgICAgICAgX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ2NpcmNsZScsIHsgY3g6ICcwJywgY3k6ICcwJywgcjogcmFkaXVzLCBjbGFzc05hbWU6ICdjaXJjbGUtYmcgJyArIHJlc3VsdCB9KSwKICAgICAgICAgICAgICAgIGdldEdseXBoRm9yKHJlc3VsdCkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFN2Z1N0YXR1czsKfShfcmVhY3QuQ29tcG9uZW50KTsKCmV4cG9ydHMuZGVmYXVsdCA9IFN2Z1N0YXR1czsKCgpTdmdTdGF0dXMucHJvcFR5cGVzID0gewogICAgcmVzdWx0OiBfcmVhY3QuUHJvcFR5cGVzLnN0cmluZywKICAgIHJhZGl1czogX3JlYWN0LlByb3BUeXBlcy5udW1iZXIKfTsKfSx7Ii4uL1NWRyI6ODMsIi4vU3ZnU3Bpbm5lciI6MTExLCJyZWFjdCI6NjIzfV0sMTEzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7CmV4cG9ydHMuV2VhdGhlckljb24gPSB1bmRlZmluZWQ7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9CgpmdW5jdGlvbiBnZXRTdGF0dXNDbGFzc05hbWUoc3VjY2Vzc3BjKSB7CiAgICBpZiAoc3VjY2Vzc3BjIDwgMjEpIHJldHVybiAnd2VhdGhlci1zdG9ybSc7CiAgICBpZiAoc3VjY2Vzc3BjIDwgNDEpIHJldHVybiAnd2VhdGhlci1yYWluaW5nJzsKICAgIGlmIChzdWNjZXNzcGMgPCA2MSkgcmV0dXJuICd3ZWF0aGVyLWNsb3VkeSc7CiAgICBpZiAoc3VjY2Vzc3BjIDwgODEpIHJldHVybiAnd2VhdGhlci1wYXJ0aWFsbHktc3VubnknOwogICAgcmV0dXJuICd3ZWF0aGVyLXN1bm55JzsKfQoKdmFyIFdlYXRoZXJJY29uID0gZXhwb3J0cy5XZWF0aGVySWNvbiA9IGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoV2VhdGhlckljb24sIF9Db21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIFdlYXRoZXJJY29uKCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBXZWF0aGVySWNvbik7CgogICAgICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoV2VhdGhlckljb24uX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihXZWF0aGVySWNvbikpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpOwogICAgfQoKICAgIF9jcmVhdGVDbGFzcyhXZWF0aGVySWNvbiwgW3sKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBzdWNjZXNzcGMgPSBwYXJzZUludCh0aGlzLnByb3BzLnNjb3JlKSB8fCAwOwogICAgICAgICAgICB2YXIgc3RhdHVzID0gZ2V0U3RhdHVzQ2xhc3NOYW1lKHN1Y2Nlc3NwYyk7CiAgICAgICAgICAgIHZhciBjbGFzc05hbWVzID0gJ3dlYXRoZXItaWNvbiAnICsgc3RhdHVzOwoKICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuc2l6ZSA9PT0gImxhcmdlIikgewogICAgICAgICAgICAgICAgY2xhc3NOYW1lcyArPSAiIGxhcmdlLWljb24iOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoJ3N2ZycsIHsgdGl0bGU6IHN0YXR1cywgY2xhc3NOYW1lOiBjbGFzc05hbWVzIH0pOwogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gV2VhdGhlckljb247Cn0oX3JlYWN0LkNvbXBvbmVudCk7CgpXZWF0aGVySWNvbi5kZWZhdWx0UHJvcHMgPSB7CiAgICBzaXplOiAiZGVmYXVsdCIKfTsKV2VhdGhlckljb24ucHJvcFR5cGVzID0gewogICAgc2NvcmU6IF9yZWFjdC5Qcm9wVHlwZXMub25lT2ZUeXBlKFtfcmVhY3QuUHJvcFR5cGVzLm51bWJlciwgX3JlYWN0LlByb3BUeXBlcy5zdHJpbmddKSwKICAgIHNpemU6IF9yZWFjdC5Qcm9wVHlwZXMuc3RyaW5nCn07Cn0seyJyZWFjdCI6NjIzfV0sMTE0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gInN5bWJvbCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gInN5bWJvbCIgOiB0eXBlb2Ygb2JqOyB9OwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7CgpmdW5jdGlvbiBfdG9Db25zdW1hYmxlQXJyYXkoYXJyKSB7IGlmIChBcnJheS5pc0FycmF5KGFycikpIHsgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBBcnJheShhcnIubGVuZ3RoKTsgaSA8IGFyci5sZW5ndGg7IGkrKykgeyBhcnIyW2ldID0gYXJyW2ldOyB9IHJldHVybiBhcnIyOyB9IGVsc2UgeyByZXR1cm4gQXJyYXkuZnJvbShhcnIpOyB9IH0KCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKLyoqCiAqIENsYXNzTWV0YWRhdGFTdG9yZSBpcyByZXNwb25zaWJsZSBmb3IgbWFpbnRhaW5pbmcgZXh0ZW5zaW9uIG1ldGFkYXRhCiAqIGluY2x1ZGluZyB0eXBlL2NhcGFiaWxpdHkgaW5mbwogKi8KdmFyIENsYXNzTWV0YWRhdGFTdG9yZSA9IGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIENsYXNzTWV0YWRhdGFTdG9yZSgpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQ2xhc3NNZXRhZGF0YVN0b3JlKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoQ2xhc3NNZXRhZGF0YVN0b3JlLCBbewogICAgICAgIGtleTogJ2luaXQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBpbml0KGNsYXNzTWV0YWRhdGFQcm92aWRlcikgewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogVHlwZSBpbmZvIGNhY2hlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB0aGlzLmNsYXNzTWV0YWRhdGEgPSB7fTsKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBGZXRjaCBmdW5jdGlvbiBmb3IgdGhlIGNsYXNzTWV0YWRhdGEKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHRoaXMuY2xhc3NNZXRhZGF0YVByb3ZpZGVyID0gY2xhc3NNZXRhZGF0YVByb3ZpZGVyOwoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIE9ubG9hZCBjYWxsYmFja3MgY2FjaGUuIFVzZWQgdG8gZW5zdXJlIHdlIGRvbid0CiAgICAgICAgICAgICAqIGlzc3VlIG11bHRpcGxlIGluLXBhcmFsbGVsIHJlcXVlc3RzIGZvciB0aGUgc2FtZQogICAgICAgICAgICAgKiBjbGFzcyBtZXRhZGF0YS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHRoaXMuY2xhc3NNZXRhZGF0YU9ubG9hZENhbGxiYWNrcyA9IHt9OwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0cyB0aGUgdHlwZS9jYXBhYmlsaXR5IGluZm8gZm9yIHRoZSBnaXZlbiBkYXRhIHR5cGUKICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnZ2V0Q2xhc3NNZXRhZGF0YScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldENsYXNzTWV0YWRhdGEodHlwZSwgb25sb2FkKSB7CiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7CgogICAgICAgICAgICB2YXIgY2xhc3NNZXRhID0gdGhpcy5jbGFzc01ldGFkYXRhW3R5cGVdOwogICAgICAgICAgICBpZiAoY2xhc3NNZXRhKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb25sb2FkKGNsYXNzTWV0YSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNsYXNzTWV0YWRhdGFPbmxvYWRDYWxsYmFja3NbdHlwZV07CiAgICAgICAgICAgIGlmICghY2FsbGJhY2tzKSB7CiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCByZXF1ZXN0IGZvciB0aGlzIHR5cGUuIEluaXRpYWxpc2UgdGhlCiAgICAgICAgICAgICAgICAvLyBjYWxsYmFjayBjYWNoZSBhbmQgdGhlbiBpc3N1ZSB0aGUgcmVxdWVzdCB0bwogICAgICAgICAgICAgICAgLy8gdGhlIGNsYXNzTWV0YWRhdGFQcm92aWRlci4KICAgICAgICAgICAgICAgIGNhbGxiYWNrcyA9IHRoaXMuY2xhc3NNZXRhZGF0YU9ubG9hZENhbGxiYWNrc1t0eXBlXSA9IFtvbmxvYWRdOwogICAgICAgICAgICAgICAgdGhpcy5jbGFzc01ldGFkYXRhUHJvdmlkZXIodHlwZSwgZnVuY3Rpb24gKGRhdGEpIHsKICAgICAgICAgICAgICAgICAgICBjbGFzc01ldGEgPSBfdGhpcy5jbGFzc01ldGFkYXRhW3R5cGVdID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkYXRhKSk7CiAgICAgICAgICAgICAgICAgICAgY2xhc3NNZXRhLmNsYXNzZXMgPSBjbGFzc01ldGEuY2xhc3NlcyB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIHR5cGUgaXRzZWxmIGlzIGluIHRoZSBsaXN0CiAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzTWV0YS5jbGFzc2VzLmluZGV4T2YodHlwZSkgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTWV0YS5jbGFzc2VzID0gW3R5cGVdLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkoY2xhc3NNZXRhLmNsYXNzZXMpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIF90aGlzLmNsYXNzTWV0YWRhdGFPbmxvYWRDYWxsYmFja3NbdHlwZV07CgogICAgICAgICAgICAgICAgICAgIC8vIE5vdGlmeSBhbGwgY2FsbGJhY2tzCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrc1tpXShjbGFzc01ldGEpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdVbmV4cGVjdGVkIEVycm9yIGluIENsYXNzTWV0YWRhdGFTdG9yZSBvbmxvYWQgY2FsbGJhY2sgZnVuY3Rpb24uJywgZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIFdlIGFscmVhZHkgaGF2ZSBhbiBpbmZsaWdodCByZXF1ZXN0IHRvIGdldCBjbGFzcyBtZXRhZGF0YSBpbmZvIGFib3V0CiAgICAgICAgICAgICAgICAvLyB0aGUgcmVxdWVzdGVkIHR5cGUsIHNvIG5vdGhpbmcgdG8gZG8gZXhjZXB0IHN0b3JlIHRoZSBvbmxvYWQgY2FsbGJhY2suCiAgICAgICAgICAgICAgICBjYWxsYmFja3MucHVzaChvbmxvYWQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2RhdGFUeXBlJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZGF0YVR5cGUoX2RhdGFUeXBlKSB7CiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzOwoKICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChleHRlbnNpb25zLCBvbmxvYWQpIHsKICAgICAgICAgICAgICAgIGlmIChfZGF0YVR5cGUgJiYgKHR5cGVvZiBfZGF0YVR5cGUgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKF9kYXRhVHlwZSkpID09PSAnb2JqZWN0JyAmJiAnX2NsYXNzJyBpbiBfZGF0YVR5cGUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBoYW5kbGUgdGhlIGNvbW1vbiBBUEkgaW5jb21pbmcgZGF0YQogICAgICAgICAgICAgICAgICAgIF9kYXRhVHlwZSA9IF9kYXRhVHlwZS5fY2xhc3M7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgX3RoaXMyLmdldENsYXNzTWV0YWRhdGEoX2RhdGFUeXBlLCBmdW5jdGlvbiAoY3VycmVudFR5cGVJbmZvKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gcHJldmVudCByZXR1cm5pbmcgZXh0ZW5zaW9ucyBmb3IgdGhlIGdpdmVuIHR5cGUKICAgICAgICAgICAgICAgICAgICAvLyB3aGVuIGEgbW9yZSBzcGVjaWZpYyBleHRlbnNpb24gaXMgZm91bmQKICAgICAgICAgICAgICAgICAgICB2YXIgbWF0Y2hpbmdFeHRlbnNpb25zID0gW107CiAgICAgICAgICAgICAgICAgICAgZWFjaFR5cGU6IGZvciAodmFyIHR5cGVJbmRleCA9IDA7IHR5cGVJbmRleCA8IGN1cnJlbnRUeXBlSW5mby5jbGFzc2VzLmxlbmd0aDsgdHlwZUluZGV4KyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY3VycmVudFR5cGVJbmZvLmNsYXNzZXMgaXMgb3JkZXJlZCBieSBqYXZhIGhpZXJhcmNoeSwgaW5jbHVkaW5nCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBiZWdpbm5pbmcgd2l0aCB0aGUgY3VycmVudCBkYXRhIHR5cGUKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHR5cGUgPSBjdXJyZW50VHlwZUluZm8uY2xhc3Nlc1t0eXBlSW5kZXhdOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGV4dGVuc2lvbnMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHRlbnNpb24gPSBleHRlbnNpb25zW2ldOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUgPT09IGV4dGVuc2lvbi5kYXRhVHlwZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoaW5nRXh0ZW5zaW9ucy5wdXNoKGV4dGVuc2lvbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgd2UgaGF2ZSB0aGlzIHNwZWNpZmljIHR5cGUgaGFuZGxlZCwgZG9uJ3QKICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJvY2VlZCB0byBwYXJlbnQgdHlwZXMKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoaW5nRXh0ZW5zaW9ucy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBlYWNoVHlwZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBvbmxvYWQobWF0Y2hpbmdFeHRlbnNpb25zKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyBhIGZpbHRlcmluZyBmdW5jdGlvbiB0byBvbmx5IHJldHVybiB1bnR5cGVkIGV4dGVuc2lvbnMKICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAndW50eXBlZCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHVudHlwZWQoKSB7CiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXh0ZW5zaW9ucywgb25sb2FkKSB7CiAgICAgICAgICAgICAgICAvLyBleGNsdWRlIHR5cGVkIGV4dGVuc2lvbnMgd2hlbiB0eXBlcyBub3QgcmVxdWVzdGVkCiAgICAgICAgICAgICAgICBleHRlbnNpb25zID0gZXh0ZW5zaW9ucy5maWx0ZXIoZnVuY3Rpb24gKG0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gISgnZGF0YVR5cGUnIGluIG0pOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBvbmxvYWQoZXh0ZW5zaW9ucyk7CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBDbGFzc01ldGFkYXRhU3RvcmU7Cn0oKTsKCmV4cG9ydHMuZGVmYXVsdCA9IENsYXNzTWV0YWRhdGFTdG9yZTsKfSx7fV0sMTE1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gInN5bWJvbCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gInN5bWJvbCIgOiB0eXBlb2Ygb2JqOyB9OwoKZXhwb3J0cy5pc1R5cGUgPSBpc1R5cGU7CmV4cG9ydHMuY29tcG9uZW50VHlwZSA9IGNvbXBvbmVudFR5cGU7Ci8qKgogKiBUcmllcyB0byBkZXRlcm1pbmUgaWYgdGhlIG9iamVjdFRvVGVzdCBpcyBvZiB0aGUgZ2l2ZW4gdHlwZS4KICogV2lsbCBub3JtYWxpemUgdGhpbmdzIGxpa2UgU3RyaW5nLydzdHJpbmcnIGluY29uc2lzdGVuY2llcwogKiBhcyB3ZWxsIGFzIEVTNiBjbGFzcyAmIHRyYWRpdGlvbmFsIHByb3RvdHlwZSBpbmhlcml0YW5jZS4KICogTk9URTogVGhpcyBBTFNPIHRlc3RzIHRoZSBwcm90b3R5cGUgaGllcmFyY2h5IGlmIG9iamVjdFRvVGVzdAogKiBpcyBhIEZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gaXNUeXBlKG9iamVjdFRvVGVzdCwgdHlwZSkgewogICAgdmFyIG8gPSBvYmplY3RUb1Rlc3Q7CiAgICBpZiAoKHR5cGVvZiBvID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihvKSkgPT09IHR5cGUpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIGlmICh0eXBlID09PSBTdHJpbmcgfHwgdHlwZSA9PT0gJ3N0cmluZycpIHsKICAgICAgICByZXR1cm4gbyBpbnN0YW5jZW9mIFN0cmluZzsKICAgIH0KICAgIGlmICh0eXBlID09PSBGdW5jdGlvbiB8fCB0eXBlID09PSAnZnVuY3Rpb24nKSB7CiAgICAgICAgcmV0dXJuIG8gaW5zdGFuY2VvZiBGdW5jdGlvbjsKICAgIH0KICAgIGlmICh0eXBlID09PSBPYmplY3QgfHwgdHlwZSA9PT0gJ29iamVjdCcpIHsKICAgICAgICByZXR1cm4gbyBpbnN0YW5jZW9mIE9iamVjdDsKICAgIH0KICAgIGlmIChvYmplY3RUb1Rlc3QgaW5zdGFuY2VvZiBGdW5jdGlvbikgewogICAgICAgIHZhciBwcm90byA9IG9iamVjdFRvVGVzdDsKICAgICAgICB3aGlsZSAocHJvdG8pIHsKICAgICAgICAgICAgaWYgKHByb3RvID09PSB0eXBlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIG9iamVjdFRvVGVzdCBpbnN0YW5jZW9mIHR5cGU7Cn0KCmZ1bmN0aW9uIGNvbXBvbmVudFR5cGUoY29tcG9uZW50VHlwZSkgewogICAgcmV0dXJuIGZ1bmN0aW9uIChleHRlbnNpb25zLCBvbmxvYWQpIHsKICAgICAgICBleHRlbnNpb25zID0gZXh0ZW5zaW9ucy5maWx0ZXIoZnVuY3Rpb24gKGUpIHsKICAgICAgICAgICAgcmV0dXJuIGlzVHlwZShlLmluc3RhbmNlLCBjb21wb25lbnRUeXBlKTsKICAgICAgICB9KTsKICAgICAgICBvbmxvYWQoZXh0ZW5zaW9ucyk7CiAgICB9Owp9Cn0se31dLDExNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7CgpmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpOyB9IH0KCmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHsgaWYgKCFzZWxmKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSAib2JqZWN0IiB8fCB0eXBlb2YgY2FsbCA9PT0gImZ1bmN0aW9uIikgPyBjYWxsIDogc2VsZjsgfQoKZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gImZ1bmN0aW9uIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgIiArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH0KCi8qKgogKiBDcmVhdGVkIGJ5IGNtZXllcnMgb24gMTAvMjEvMTYuCiAqLwp2YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwp2YXIgUHJvcFR5cGVzID0gUmVhY3QuUHJvcFR5cGVzOwoKLyoqCiAqIEFuIGludGVybmFsIGNvbXBvbmVudCB0aGF0IGluc2VydHMgdGhpbmdzIGludG8gdGhlIChzZXBhcmF0ZSkgY29udGV4dCBvZiBtb3VudGVkIGV4dGVuc2lvbnMuIFdlIG5lZWQgdGhpcyBmb3Igb3VyCiAqIGNvbmZpZ3VyYXRpb24gb2JqZWN0LCB3aGljaCBoZWxwcyByZXNvbHZlIFVSTHMgZm9yIG1lZGlhLCBSRVNUIGVuZHBvaW50cywgZXRjLCBhbmQgd2UgYWxzbyBuZWVkIHRvIGJyaWRnZSB0aGUKICogInJvdXRlciIgY29udGV4dCBwcm9wZXJ0eSBpbiBvcmRlciBmb3IgZXh0ZW5zaW9ucyB0byBiZSBhYmxlIHRvIHVzZSAmbHQ7TGluayZndDsgZnJvbSByZWFjdC1yb3V0ZXIuCiAqLwoKdmFyIENvbnRleHRCcmlkZ2UgPSBleHBvcnRzLkNvbnRleHRCcmlkZ2UgPSBmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkgewogICAgX2luaGVyaXRzKENvbnRleHRCcmlkZ2UsIF9SZWFjdCRDb21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIENvbnRleHRCcmlkZ2UoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIENvbnRleHRCcmlkZ2UpOwoKICAgICAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKENvbnRleHRCcmlkZ2UuX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihDb250ZXh0QnJpZGdlKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKENvbnRleHRCcmlkZ2UsIFt7CiAgICAgICAga2V5OiAnZ2V0Q2hpbGRDb250ZXh0JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0Q2hpbGRDb250ZXh0KCkgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgcm91dGVyOiB0aGlzLnByb3BzLnJvdXRlciwKICAgICAgICAgICAgICAgIGNvbmZpZzogdGhpcy5wcm9wcy5jb25maWcKICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAncmVuZGVyJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5wcm9wcy5jaGlsZHJlbjsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIENvbnRleHRCcmlkZ2U7Cn0oUmVhY3QuQ29tcG9uZW50KTsKCkNvbnRleHRCcmlkZ2UuY2hpbGRDb250ZXh0VHlwZXMgPSB7CiAgICByb3V0ZXI6IFByb3BUeXBlcy5vYmplY3QsCiAgICBjb25maWc6IFByb3BUeXBlcy5vYmplY3QKfTsKCkNvbnRleHRCcmlkZ2UucHJvcFR5cGVzID0gewogICAgY2hpbGRyZW46IFByb3BUeXBlcy5hbnksCiAgICByb3V0ZXI6IFByb3BUeXBlcy5vYmplY3QsCiAgICBjb25maWc6IFByb3BUeXBlcy5vYmplY3QKfTsKfSx7InJlYWN0Ijo2MjN9XSwxMTc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewoidXNlIHN0cmljdCI7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKCnZhciBfcmVhY3QgPSByZXF1aXJlKCJyZWFjdCIpOwoKdmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKLyoqCiAqIENvbnZlcnQgYW4gZXJyb3IgdG8gYSBzdWl0YWJsZSBSZWFjdCBlbGVtZW50IGZvciBkaXNwbGF5IGluIFVJLgogKiBAcGFyYW0gZXJyb3IKICovCmZ1bmN0aW9uIGVycm9yVG9FbGVtZW50KGVycm9yKSB7CiAgICByZXR1cm4gX3JlYWN0Mi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoCiAgICAgICAgImRpdiIsCiAgICAgICAgeyBjbGFzc05hbWU6ICJlcnJvciIgfSwKICAgICAgICAiRXJyb3IgcmVuZGVyaW5nOiAiLAogICAgICAgIGVycm9yLnRvU3RyaW5nKCkKICAgICk7Cn0gLyoqCiAgICogQ3JlYXRlZCBieSBjbWV5ZXJzIG9uIDEwLzI0LzE2LgogICAqLwpleHBvcnRzLmRlZmF1bHQgPSB7CiAgICBlcnJvclRvRWxlbWVudDogZXJyb3JUb0VsZW1lbnQKfTsKfSx7InJlYWN0Ijo2MjN9XSwxMTg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7CiAgICB2YWx1ZTogdHJ1ZQp9KTsKCnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpOwoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgpmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIGNhbGwgPT09ICJmdW5jdGlvbiIpID8gY2FsbCA6IHNlbGY7IH0KCmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICJmdW5jdGlvbiIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9Cgp2YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpOwp2YXIgUmVhY3RET00gPSByZXF1aXJlKCdyZWFjdC1kb20nKTsKdmFyIENvbnRleHRCcmlkZ2UgPSByZXF1aXJlKCcuL0NvbnRleHRCcmlkZ2UnKS5Db250ZXh0QnJpZGdlOwp2YXIgaW1wb3J0ZWRFeHRlbnNpb25TdG9yZSA9IHJlcXVpcmUoJy4vRXh0ZW5zaW9uU3RvcmUuanMnKS5pbnN0YW5jZTsKdmFyIGltcG9ydGVkUmVzb3VyY2VMb2FkVHJhY2tlciA9IHJlcXVpcmUoJy4vUmVzb3VyY2VMb2FkVHJhY2tlcicpLmluc3RhbmNlOwoKLyoqCiAqIFJlbmRlcmVyIGZvciByZWFjdCBjb21wb25lbnQgZXh0ZW5zaW9ucyBmb3Igd2hpY2ggb3RoZXIgcGx1Z2lucyBjYW4gcHJvdmlkZSBhbiBpbXBsZW1lbnRpbmcgQ29tcG9uZW50LgogKi8KCnZhciBFeHRlbnNpb25SZW5kZXJlciA9IGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7CiAgICBfaW5oZXJpdHMoRXh0ZW5zaW9uUmVuZGVyZXIsIF9SZWFjdCRDb21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIEV4dGVuc2lvblJlbmRlcmVyKCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFeHRlbnNpb25SZW5kZXJlcik7CgogICAgICAgIC8vIEluaXRpYWwgc3RhdGUgaXMgZW1wdHkuIFNlZSB0aGUgY29tcG9uZW50RGlkTW91bnQgYW5kIHJlbmRlciBmdW5jdGlvbnMuCiAgICAgICAgdmFyIF90aGlzID0gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKEV4dGVuc2lvblJlbmRlcmVyLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoRXh0ZW5zaW9uUmVuZGVyZXIpKS5jYWxsKHRoaXMpKTsKCiAgICAgICAgX3RoaXMuc3RhdGUgPSB7IGV4dGVuc2lvbnM6IG51bGwgfTsKICAgICAgICByZXR1cm4gX3RoaXM7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKEV4dGVuc2lvblJlbmRlcmVyLCBbewogICAgICAgIGtleTogJ2NvbXBvbmVudFdpbGxNb3VudCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxNb3VudCgpIHsKICAgICAgICAgICAgdGhpcy5fc2V0RXh0ZW5zaW9ucyh0aGlzLnByb3BzKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY29tcG9uZW50RGlkTW91bnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHsKICAgICAgICAgICAgRXh0ZW5zaW9uUmVuZGVyZXIucmVzb3VyY2VMb2FkVHJhY2tlci5vbk1vdW50KHRoaXMucHJvcHMuZXh0ZW5zaW9uUG9pbnQpOwogICAgICAgICAgICB0aGlzLl9yZW5kZXJBbGxFeHRlbnNpb25zKCk7CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2NvbXBvbmVudFdpbGxVcGRhdGUnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVXBkYXRlKG5leHRQcm9wcywgbmV4dFN0YXRlKSB7CiAgICAgICAgICAgIGlmICghbmV4dFN0YXRlLmV4dGVuc2lvbnMpIHsKICAgICAgICAgICAgICAgIHRoaXMuX3NldEV4dGVuc2lvbnMobmV4dFByb3BzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjb21wb25lbnREaWRVcGRhdGUnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRVcGRhdGUoKSB7CiAgICAgICAgICAgIHRoaXMuX3JlbmRlckFsbEV4dGVuc2lvbnMoKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnY29tcG9uZW50V2lsbFVubW91bnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHsKICAgICAgICAgICAgdGhpcy5fdW5tb3VudEFsbEV4dGVuc2lvbnMoKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEZvcmNlIGEgcmVsb2FkIGFuZCByZS1yZW5kZXIgb2YgYWxsIGV4dGVuc2lvbnMgcmVnaXN0ZXJlZCB3aXRoIHRoaXMgRXh0ZW5zaW9uUG9pbnQuCiAgICAgICAgICogVXNlZnVsIGlmIHRoZSBwcm9wcyAoc3VjaCBhcyAnZmlsdGVyJykgaGF2ZSBjaGFuZ2VkIGFuZCBuZWVkIHRvIGJlIHJlLWV2YWx1YXRlZC4KICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAncmVsb2FkRXh0ZW5zaW9ucycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbG9hZEV4dGVuc2lvbnMoKSB7CiAgICAgICAgICAgIC8vIHRyaWdnZXJzIGEgcmVsb2FkIG9mIGV4dGVuc2lvbnMgdmlhIGNvbXBvbmVudFdpbGxVcGRhdGUKICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7CiAgICAgICAgICAgICAgICBleHRlbnNpb25zOiBudWxsCiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdfc2V0RXh0ZW5zaW9ucycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9zZXRFeHRlbnNpb25zKCkgewogICAgICAgICAgICB2YXIgX3RoaXMyID0gdGhpczsKCiAgICAgICAgICAgIEV4dGVuc2lvblJlbmRlcmVyLmV4dGVuc2lvblN0b3JlLmdldEV4dGVuc2lvbnModGhpcy5wcm9wcy5leHRlbnNpb25Qb2ludCwgdGhpcy5wcm9wcy5maWx0ZXIsIGZ1bmN0aW9uIChleHRlbnNpb25zKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMyLnNldFN0YXRlKHsgZXh0ZW5zaW9uczogZXh0ZW5zaW9ucyB9KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIG1ldGhvZCByZW5kZXJzIHRoZSAibGVhZiBub2RlIiBjb250YWluZXIgZGl2cywgb25lIGZvciBlYWNoIHJlZ2lzdGVyZWQgZXh0ZW5zaW9uLCB0aGF0IGxpdmUgaW4gdGhlIHNhbWUKICAgICAgICAgKiByZWFjdCBoaWVyYXJjaHkgYXMgdGhlICZsdDtFeHRlbnNpb25SZW5kZXJlciZndDsgaW5zdGFuY2UgaXRzZWxmLiBBcyBmYXIgYXMgb3VyIHJlYWN0IGlzIGNvbmNlcm5lZCwgdGhlc2UgYXJlCiAgICAgICAgICogY2hpbGRsZXNzIGRpdnMgdGhhdCBhcmUgbmV2ZXIgdXBkYXRlZC4gQWN0dWFsbHkgcmVuZGVyaW5nIHRoZSBleHRlbnNpb25zIHRoZW1zZWx2ZXMgaXMgZG9uZSBieQogICAgICAgICAqIF9yZW5kZXJBbGxFeHRlbnNpb25zLgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBleHRlbnNpb25zID0gdGhpcy5zdGF0ZS5leHRlbnNpb25zOwoKICAgICAgICAgICAgaWYgKCFleHRlbnNpb25zKSB7CiAgICAgICAgICAgICAgICAvLyBSZW5kZXJlZCBiZWZvcmUgZXh0ZW5zaW9uIGRhdGEgaXMgYXZhaWxhYmxlIC0gaWYgZGF0YSBpcyBsb2FkZWQgYnV0IG5vCiAgICAgICAgICAgICAgICAvLyBleHRlbnNpb25zIGFyZSBmb3VuZCwgd2Ugd2lsbCBnZXQgW10gcmF0aGVyIHRoYW4gbnVsbCwgYW5kIHdpbGwgd2FudCB0bwogICAgICAgICAgICAgICAgLy8gcmVuZGVyIGFuIGVtcHR5IHdyYXBwaW5nRWxlbWVudCwgb3IgcG9zc2libHkgImRlZmF1bHQiIGNoaWxkcmVuCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIG5ld0NoaWxkcmVuID0gW107CgogICAgICAgICAgICAvLyBBZGQgYSA8ZGl2PiBmb3IgZWFjaCBvZiB0aGUgZXh0ZW5zaW9ucy4gU2VlIHRoZSBfX3JlbmRlckFsbEV4dGVuc2lvbnMgZnVuY3Rpb24uCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXh0ZW5zaW9ucy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgbmV3Q2hpbGRyZW4ucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KCdkaXYnLCB7IGtleTogaSB9KSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChuZXdDaGlsZHJlbi5sZW5ndGggPT09IDAgJiYgdGhpcy5wcm9wcy5jaGlsZHJlbikgewogICAgICAgICAgICAgICAgbmV3Q2hpbGRyZW4gPSB0aGlzLnByb3BzLmNoaWxkcmVuOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudCh0aGlzLnByb3BzLndyYXBwaW5nRWxlbWVudCwgbnVsbCwgbmV3Q2hpbGRyZW4pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogRm9yIGVhY2ggZXh0ZW5zaW9uLCB3ZSBoYXZlIGNyZWF0ZWQgYSAibGVhZiBub2RlIiBlbGVtZW50IGluIHRoZSBET00uIFRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgcmVhY3QgaGllcmFyY2h5CiAgICAgICAgICogZm9yIGVhY2gsIGFuZCBpbnN0cnVjdHMgaXQgdG8gcmVuZGVyLiBGcm9tIHRoYXQgcG9pbnQgb24gd2UgaGF2ZSBhIHNlcGFyYXRpb24gdGhhdCBrZWVwcyB0aGUgbWFpbiBhcHAgaW5zdWxhdGVkCiAgICAgICAgICogZnJvbSBhbnkgcGx1Z2luIGlzc3VlcyB0aGF0IG1heSBjYXVzZSByZWFjdCB0byB0aHJvdyB3aGlsZSB1cGRhdGluZy4gSW5zcGlyZWQgYnkgTnlsYXMgTjEuCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ19yZW5kZXJBbGxFeHRlbnNpb25zJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX3JlbmRlckFsbEV4dGVuc2lvbnMoKSB7CiAgICAgICAgICAgIHZhciBleHRlbnNpb25zID0gdGhpcy5zdGF0ZS5leHRlbnNpb25zOwoKICAgICAgICAgICAgaWYgKCFleHRlbnNpb25zIHx8IGV4dGVuc2lvbnMubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgICAgICAvLyBObyBleHRlbnNpb25zIGxvYWRlZC4gUmV0dXJuIGVhcmx5IGJlY2F1c2Ugd2UgbWF5IGhhdmUgZGVmYXVsdCBET00gY2hpbGRyZW4uCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIE5COiBUaGlzIG5lZWRzIHRvIGJlIGEgbG90IGNsZXZlcmVyIGlmIHRoZSBsaXN0IG9mIGV4dGVuc2lvbnMgZm9yIGEgc3BlY2lmaWMgcG9pbnQgY2FuIGNoYW5nZTsKICAgICAgICAgICAgLy8gV2Ugd2lsbCBuZWVkIHRvIGxpbmsgZWFjaCBleHRlbnNpb24gd2l0aCBpdHMgY29udGFpbmluZyBlbGVtZW50LCBpbiBzb21lIHdheSB0aGF0IGRvZXNuJ3QgbGVhayA6KSBFYXN5IGluCiAgICAgICAgICAgIC8vIGJyb3dzZXJzIHdpdGggV2Vha01hcCwgbGVzcyBzbyBvdGhlcndpc2UuCiAgICAgICAgICAgIHZhciBlbCA9IFJlYWN0RE9NLmZpbmRET01Ob2RlKHRoaXMpOwogICAgICAgICAgICBpZiAoZWwpIHsKICAgICAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IGVsLmNoaWxkcmVuOwogICAgICAgICAgICAgICAgaWYgKGNoaWxkcmVuKSB7CgogICAgICAgICAgICAgICAgICAgIC8vIFRoZSBudW1iZXIgb2YgY2hpbGRyZW4gc2hvdWxkIGJlIGV4YWN0bHkgdGhlIHNhbWUgYXMgdGhlIG51bWJlcgogICAgICAgICAgICAgICAgICAgIC8vIG9mIGV4dGVuc2lvbnMuIFNlZSB0aGUgcmVuZGVyIGZ1bmN0aW9uIGZvciB3aGVyZSB0aGVzZSBhcmUgYWRkZWQuCiAgICAgICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbnMubGVuZ3RoICE9PSBjaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignVW5leHBlY3RlZCBlcnJvciBpbiBKZW5raW5zIEV4dGVuc2lvblJlbmRlcmVyIHJlbmRlcmluZyAoJyArIHRoaXMucHJvcHMuZXh0ZW5zaW9uUG9pbnQgKyAnKS4gRXhwZWN0aW5nIGEgY2hpbGQgRE9NIG5vZGUgZm9yIGVhY2ggZXh0ZW5zaW9uIHBvaW50LicpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIHJlbmRlciBlYWNoIGV4dGVuc2lvbiBvbiB0aGUgYWxsb2NhdGVkIGNoaWxkIG5vZGUuCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBleHRlbnNpb25zLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlbmRlckV4dGVuc2lvbihjaGlsZHJlbltpXSwgZXh0ZW5zaW9uc1tpXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiogQWN0dWFsbHkgcmVuZGVyIGFuIGluZGl2aWR1YWwgZXh0ZW5zaW9uICovCgogICAgfSwgewogICAgICAgIGtleTogJ19yZW5kZXJFeHRlbnNpb24nLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfcmVuZGVyRXh0ZW5zaW9uKGVsZW1lbnQsIGV4dGVuc2lvbikgewogICAgICAgICAgICB2YXIgY29tcG9uZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChleHRlbnNpb24sIHRoaXMucHJvcHMpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmFyIGNvbnRleHRWYWx1ZXNBc1Byb3BzID0gewogICAgICAgICAgICAgICAgICAgIGNvbmZpZzogdGhpcy5jb250ZXh0LmNvbmZpZywKICAgICAgICAgICAgICAgICAgICByb3V0ZXI6IHRoaXMuY29udGV4dC5yb3V0ZXIKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB2YXIgYnJpZGdlZENvbXBvbmVudCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoQ29udGV4dEJyaWRnZSwgY29udGV4dFZhbHVlc0FzUHJvcHMsIGNvbXBvbmVudCk7CiAgICAgICAgICAgICAgICBSZWFjdERPTS5yZW5kZXIoYnJpZGdlZENvbXBvbmVudCwgZWxlbWVudCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJlcnJvciByZW5kZXJpbmciLCBleHRlbnNpb24ubmFtZSwgZSk7CgogICAgICAgICAgICAgICAgdmFyIGVycm9yRGl2ID0gUmVhY3QuY3JlYXRlRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICAnZGl2JywKICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2Vycm9yIGFsaWVuJyB9LAogICAgICAgICAgICAgICAgICAgICdFcnJvciByZW5kZXJpbmcgJywKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24ubmFtZSwKICAgICAgICAgICAgICAgICAgICAnOiAnLAogICAgICAgICAgICAgICAgICAgIGUudG9TdHJpbmcoKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIFJlYWN0RE9NLnJlbmRlcihlcnJvckRpdiwgZWxlbWVudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENsZWFuIHVwIGNoaWxkIGV4dGVuc2lvbnMnIHJlYWN0IGhpZXJhcmNoaWVzLiBOZWNlc3NhcnkgYmVjYXVzZSB0aGV5IGxpdmUgaW4gdGhlaXIgb3duIHJlYWN0IGhpZXJhcmNoaWVzIHRoYXQKICAgICAgICAgKiB3b3VsZCBvdGhlcndpc2Ugbm90IGJlIG5vdGlmaWVkIHdoZW4gdGhpcyBpcyBiZWluZyB1bm1vdW50ZWQuCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ191bm1vdW50QWxsRXh0ZW5zaW9ucycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF91bm1vdW50QWxsRXh0ZW5zaW9ucygpIHsKCiAgICAgICAgICAgIHZhciBleHRlbnNpb25zID0gdGhpcy5zdGF0ZS5leHRlbnNpb25zOwoKICAgICAgICAgICAgaWYgKCFleHRlbnNpb25zIHx8IGV4dGVuc2lvbnMubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgICAgICAvLyBObyBleHRlbnNpb25zIGxvYWRlZC4gUmV0dXJuIGVhcmx5IGJlY2F1c2Ugd2UgbWF5IGhhdmUgZGVmYXVsdCBET00gY2hpbGRyZW4gd2hpY2ggcmVhY3QKICAgICAgICAgICAgICAgIC8vIHdpbGwgdW5tb3VudCBub3JtYWxseQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgdGhpc05vZGUgPSBSZWFjdERPTS5maW5kRE9NTm9kZSh0aGlzKTsKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpc05vZGUgPyB0aGlzTm9kZS5jaGlsZHJlbiA6IG51bGw7CiAgICAgICAgICAgIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGQgPSBjaGlsZHJlbltpXTsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0RE9NLnVubW91bnRDb21wb25lbnRBdE5vZGUoY2hpbGQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIExvZyBhbmQgY29udGludWUsIGRvbid0IHdhbnQgdG8gc3RvcCB1bm1vdW50aW5nIGNoaWxkcmVuCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJFcnJvciB1bm1vdW50aW5nIGNvbXBvbmVudCIsIGNoaWxkLCBlcnIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH1dKTsKCiAgICByZXR1cm4gRXh0ZW5zaW9uUmVuZGVyZXI7Cn0oUmVhY3QuQ29tcG9uZW50KTsKCmV4cG9ydHMuZGVmYXVsdCA9IEV4dGVuc2lvblJlbmRlcmVyOwoKCkV4dGVuc2lvblJlbmRlcmVyLmRlZmF1bHRQcm9wcyA9IHsKICAgIHdyYXBwaW5nRWxlbWVudDogImRpdiIKfTsKCkV4dGVuc2lvblJlbmRlcmVyLnByb3BUeXBlcyA9IHsKICAgIGNoaWxkcmVuOiBSZWFjdC5Qcm9wVHlwZXMubm9kZSwKICAgIGV4dGVuc2lvblBvaW50OiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsCiAgICBmaWx0ZXI6IFJlYWN0LlByb3BUeXBlcy5hbnksCiAgICB3cmFwcGluZ0VsZW1lbnQ6IFJlYWN0LlByb3BUeXBlcy5vbmVPZlR5cGUoW1JlYWN0LlByb3BUeXBlcy5zdHJpbmcsIFJlYWN0LlByb3BUeXBlcy5lbGVtZW50XSkKfTsKCkV4dGVuc2lvblJlbmRlcmVyLmNvbnRleHRUeXBlcyA9IHsKICAgIHJvdXRlcjogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCwKICAgIGNvbmZpZzogUmVhY3QuUHJvcFR5cGVzLm9iamVjdAp9Owp9LHsiLi9Db250ZXh0QnJpZGdlIjoxMTYsIi4vRXh0ZW5zaW9uU3RvcmUuanMiOjExOSwiLi9SZXNvdXJjZUxvYWRUcmFja2VyIjoxMjAsInJlYWN0Ijo2MjMsInJlYWN0LWRvbSI6NDMwfV0sMTE5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsgLyoqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBFeHRlbnNpb25TdG9yZSBpcyByZXNwb25zaWJsZSBmb3IgbWFpbnRhaW5pbmcgZXh0ZW5zaW9uIG1ldGFkYXRhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBpbmNsdWRpbmcgdHlwZS9jYXBhYmlsaXR5IGluZm8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwoKdmFyIF9sb2dnaW5nID0gcmVxdWlyZSgnQGplbmtpbnMtY2QvbG9nZ2luZycpOwoKdmFyIGxvZ2dpbmcgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfbG9nZ2luZyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHsgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkgeyByZXR1cm4gb2JqOyB9IGVsc2UgeyB2YXIgbmV3T2JqID0ge307IGlmIChvYmogIT0gbnVsbCkgeyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gbmV3T2JqLmRlZmF1bHQgPSBvYmo7IHJldHVybiBuZXdPYmo7IH0gfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9Cgp2YXIgbG9nZ2VyID0gbG9nZ2luZy5sb2dnZXIoJ2lvLmplbmtpbnMuYmx1ZW9jZWFuLmpzZXh0ZW5zaW9ucy5FeHRlbnNpb25TdG9yZScpOwoKdmFyIEV4dGVuc2lvblN0b3JlID0gZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gRXh0ZW5zaW9uU3RvcmUoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEV4dGVuc2lvblN0b3JlKTsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoRXh0ZW5zaW9uU3RvcmUsIFt7CiAgICAgICAga2V5OiAnaW5pdCcsCgogICAgICAgIC8qKgogICAgICAgICAqICBGSVhNRSB0aGlzIGlzIE5PVCBhIGNvbnN0cnVjdG9yLCBhcyB0aGVyZSdzIG5vIGNvbW1vbiB3YXkgdG8KICAgICAgICAgKiAgcGFzcyBhcm91bmQgYSBESSBzaW5nbGV0b24gYXQgdGhlIG1vbWVudCBhY3Jvc3MgZXZlcnl0aGluZwogICAgICAgICAqICB0aGF0IG5lZWRzIGl0IChlLmcuIHJlZHV4IHdvcmtzIGZvciB0aGUgYXBwLCBub3QgZm9yIG90aGVyCiAgICAgICAgICogIHRoaW5ncyBpbiB0aGlzIG1vZHVsZSkuCiAgICAgICAgICoKICAgICAgICAgKiAgTk9URTogdGhpcyBpcyBjdXJyZW50bHkgY2FsbGVkIGZyb20gYGJsdWVvY2Vhbi13ZWIvc3JjL21haW4vanMvaW5pdC5qc3hgCiAgICAgICAgICoKICAgICAgICAgKiAgTmVlZHM6CiAgICAgICAgICogIGFyZ3MgPSB7CiAgICAgICAgICogICAgICBleHRlbnNpb25EYXRhOiBbYXJyYXkgb2YgZXh0ZW5zaW9ucyBkYXRhXSwKICAgICAgICAgKiAgICAgIGNsYXNzTWV0YWRhdGFTdG9yZTogewogICAgICAgICAqICAgICAgICAgIGdldENsYXNzTWV0YWRhdGEoZGF0YVR5cGUsIGNhbGxiYWNrKSA9PiB7CiAgICAgICAgICogICAgICAgICAgICAgIC4uLiAvLyBnZXQgdGhlIGRhdGEgYmFzZWQgb24gJ2RhdGFUeXBlJwogICAgICAgICAqICAgICAgICAgICAgICBjYWxsYmFjayh0eXBlSW5mbyk7CiAgICAgICAgICogICAgICAgICAgfQogICAgICAgICAqICAgICAgfQogICAgICAgICAqICB9CiAgICAgICAgICovCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGluaXQoYXJncykgewogICAgICAgICAgICB0aGlzLmV4dGVuc2lvbkRhdGEgPSBhcmdzLmV4dGVuc2lvbkRhdGE7CiAgICAgICAgICAgIHRoaXMuZXh0ZW5zaW9uUG9pbnRMaXN0ID0gdW5kZWZpbmVkOyAvLyBjYWNoZSBmcm9tIGV4dGVuc2lvbkRhdGEuIFNlZSBfaW5pdEV4dGVuc2lvblBvaW50TGlzdCgpLgoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFRoZSByZWdpc3RlcmVkIEV4dGVuc2lvblBvaW50IG1ldGFkYXRhICsgaW5zdGFuY2UgcmVmcwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdGhpcy5leHRlbnNpb25Qb2ludHMgPSB7fTsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFVzZWQgdG8gZmV0Y2ggdHlwZSBpbmZvcm1hdGlvbgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdGhpcy5jbGFzc01ldGFkYXRhU3RvcmUgPSBhcmdzLmNsYXNzTWV0YWRhdGFTdG9yZTsKCiAgICAgICAgICAgIC8vIE5vdyBpbml0IHRoZSBleHRlbnNpb24gcG9pbnQgbGlzdC4KICAgICAgICAgICAgdGhpcy5faW5pdEV4dGVuc2lvblBvaW50TGlzdCgpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUmVnaXN0ZXIgdGhlIGV4dGVuc2lvbiBzY3JpcHQgb2JqZWN0CiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ19yZWdpc3RlckNvbXBvbmVudEluc3RhbmNlJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX3JlZ2lzdGVyQ29tcG9uZW50SW5zdGFuY2UoZXh0ZW5zaW9uUG9pbnRJZCwgcGx1Z2luSWQsIGNvbXBvbmVudCwgaW5zdGFuY2UpIHsKICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpczsKCiAgICAgICAgICAgIHZhciBleHRlbnNpb25zID0gdGhpcy5leHRlbnNpb25Qb2ludHNbZXh0ZW5zaW9uUG9pbnRJZF07CiAgICAgICAgICAgIGlmICghZXh0ZW5zaW9ucykgewogICAgICAgICAgICAgICAgdGhpcy5fbG9hZEJ1bmRsZXMoZXh0ZW5zaW9uUG9pbnRJZCwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpcy5fcmVnaXN0ZXJDb21wb25lbnRJbnN0YW5jZShleHRlbnNpb25Qb2ludElkLCBwbHVnaW5JZCwgY29tcG9uZW50LCBpbnN0YW5jZSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZXh0ZW5zaW9uID0gdGhpcy5fZmluZFBsdWdpbihleHRlbnNpb25Qb2ludElkLCBwbHVnaW5JZCwgY29tcG9uZW50KTsKICAgICAgICAgICAgaWYgKGV4dGVuc2lvbikgewogICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmluc3RhbmNlID0gaW5zdGFuY2U7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gbG9jYXRlIHBsdWdpbiBmb3IgJyArIGV4dGVuc2lvblBvaW50SWQgKyAnIC8gJyArIHBsdWdpbklkICsgJyAvICcgKyBjb21wb25lbnQpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogT24gcGx1Z2luIGNvbXBvbmVudCByZWdpc3RyYXRpb24gY29tcGxldGUKICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnX29uUGx1Z2luQ29tcG9uZW50UmVnaXN0cmF0aW9uQ29tcGxldGUnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfb25QbHVnaW5Db21wb25lbnRSZWdpc3RyYXRpb25Db21wbGV0ZShwbHVnaW5JZCkgewogICAgICAgICAgICBsb2dnZXIubG9nKCdBbGwganMtZXh0ZW5zaW9ucyBmb3IgcGx1Z2luICIlcyIgYXJlIG5vdyByZWdpc3RlcmVkLicsIHBsdWdpbklkKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEZpbmRzIGEgcGx1Z2luIGJ5IGV4dGVuc2lvbiBwb2ludCBpZCwgcGx1Z2luIGlkLCBjb21wb25lbnQgbmFtZQogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdfZmluZFBsdWdpbicsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9maW5kUGx1Z2luKGV4dGVuc2lvblBvaW50SWQsIHBsdWdpbklkLCBjb21wb25lbnQpIHsKICAgICAgICAgICAgdmFyIGV4dGVuc2lvbnMgPSB0aGlzLmV4dGVuc2lvblBvaW50c1tleHRlbnNpb25Qb2ludElkXTsKICAgICAgICAgICAgaWYgKGV4dGVuc2lvbnMpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXh0ZW5zaW9ucy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHZhciBleHRlbnNpb24gPSBleHRlbnNpb25zW2ldOwogICAgICAgICAgICAgICAgICAgIGlmIChleHRlbnNpb24ucGx1Z2luSWQgPT0gcGx1Z2luSWQgJiYgZXh0ZW5zaW9uLmNvbXBvbmVudCA9PSBjb21wb25lbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvbjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBwcmltYXJ5IGZ1bmN0aW9uIHRvIHVzZSBpbiBvcmRlciB0byBnZXQgZXh0ZW5zaW9ucywKICAgICAgICAgKiB3aWxsIGNhbGwgdGhlIG9ubG9hZCBjYWxsYmFjayB3aXRoIGEgbGlzdCBvZiBleHBvcnRlZCBleHRlbnNpb24KICAgICAgICAgKiBvYmplY3RzIChlLmcuIFJlYWN0IGNsYXNzZXMgb3Igb3RoZXJ3aXNlKS4KICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnZ2V0RXh0ZW5zaW9ucycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldEV4dGVuc2lvbnMoZXh0ZW5zaW9uUG9pbnQsIGZpbHRlciwgb25sb2FkKSB7CiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzOwoKICAgICAgICAgICAgLy8gQWxsb3cgY2FsbHMgbGlrZTogZ2V0RXh0ZW5zaW9ucygnc29tZXRoaW5nJywgYSA9PiAuLi4pCiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyICYmIHR5cGVvZiBmaWx0ZXIgPT09ICdmdW5jdGlvbicpIHsKICAgICAgICAgICAgICAgIG9ubG9hZCA9IGZpbHRlcjsKICAgICAgICAgICAgICAgIGZpbHRlciA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQW5kIGNhbGxzIGxpa2U6IGdldEV4dGVuc2lvbnMoWydhJywnYiddLCAoYSxiKSA9PiAuLi4pCiAgICAgICAgICAgIGlmIChleHRlbnNpb25Qb2ludCBpbnN0YW5jZW9mIEFycmF5KSB7CiAgICAgICAgICAgICAgICB2YXIgYXJncyA9IFtdOwogICAgICAgICAgICAgICAgdmFyIG5leHRBcmcgPSBmdW5jdGlvbiBuZXh0QXJnKGV4dCkgewogICAgICAgICAgICAgICAgICAgIGlmIChleHQpIGFyZ3MucHVzaChleHQpOwogICAgICAgICAgICAgICAgICAgIGlmIChleHRlbnNpb25Qb2ludC5sZW5ndGggPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgb25sb2FkLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFyZyA9IGV4dGVuc2lvblBvaW50WzBdOwogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25Qb2ludCA9IGV4dGVuc2lvblBvaW50LnNsaWNlKDEpOwogICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIuZ2V0RXh0ZW5zaW9ucyhhcmcsIGZpbHRlciwgbmV4dEFyZyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIG5leHRBcmcoKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fbG9hZEJ1bmRsZXMoZXh0ZW5zaW9uUG9pbnQsIGZ1bmN0aW9uIChleHRlbnNpb25zKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMyLl9maWx0ZXJFeHRlbnNpb25zKGV4dGVuc2lvbnMsIGZpbHRlciwgb25sb2FkKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBHZXQgdGhlIHZlcnNpb24gc3RyaW5nIGZvciB0aGUgbmFtZWQgcGx1Z2luLgogICAgICAgICAqIEBwYXJhbSBwbHVnaW5OYW1lIFRoZSBwbHVnaW4gbmFtZS9JZCAoc2hvcnQgbmFtZSkuCiAgICAgICAgICogQHJldHVybiBUaGUgdmVyc2lvbiBzdHJpbmcgZm9yIHRoZSBuYW1lZCBwbHVnaW4sIG9yIHVuZGVmaW5lZCBpZiB0aGUgcGx1Z2luIGlzIG5vdCBpbnN0YWxsZWQvYWN0aXZlLgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdnZXRQbHVnaW5WZXJzaW9uJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0UGx1Z2luVmVyc2lvbihwbHVnaW5OYW1lKSB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5leHRlbnNpb25Qb2ludExpc3QubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBwbHVnaW5NZXRhZGF0YSA9IHRoaXMuZXh0ZW5zaW9uUG9pbnRMaXN0W2ldOwogICAgICAgICAgICAgICAgaWYgKHBsdWdpbk1ldGFkYXRhLmhwaVBsdWdpbklkID09PSBwbHVnaW5OYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBsdWdpbk1ldGFkYXRhLmhwaVBsdWdpblZlcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX2ZpbHRlckV4dGVuc2lvbnMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfZmlsdGVyRXh0ZW5zaW9ucyhleHRlbnNpb25zLCBmaWx0ZXJzLCBvbmxvYWQpIHsKICAgICAgICAgICAgaWYgKGV4dGVuc2lvbnMubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgICAgICBvbmxvYWQoZXh0ZW5zaW9ucyk7IC8vIG5vIGV4dGVuc2lvbnMgdG8gZmlsdGVyCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChmaWx0ZXJzKSB7CiAgICAgICAgICAgICAgICAvLyBhbGxvdyBjYWxscyBsaWtlOiBnZXRFeHRlbnNpb25zKCdhYmNkJywgZGF0YVR5cGUoc29tZXRoaW5nKSwgZXh0ID0+IC4uLikKICAgICAgICAgICAgICAgIGlmICghZmlsdGVycy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBmaWx0ZXJzID0gW2ZpbHRlcnNdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHJlbWFpbmluZyA9IFtdLmNvbmNhdChmaWx0ZXJzKTsKICAgICAgICAgICAgICAgIHZhciBuZXh0RmlsdGVyID0gZnVuY3Rpb24gbmV4dEZpbHRlcihleHRlbnNpb25zKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlbWFpbmluZy5sZW5ndGggPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFwIHRvIGluc3RhbmNlcyBhbmQgcHJvY2VlZAogICAgICAgICAgICAgICAgICAgICAgICBvbmxvYWQoZXh0ZW5zaW9ucy5tYXAoZnVuY3Rpb24gKG0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmluc3RhbmNlOwogICAgICAgICAgICAgICAgICAgICAgICB9KSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHJlbWFpbmluZ1swXTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVtYWluaW5nID0gcmVtYWluaW5nLnNsaWNlKDEpOwogICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoZXh0ZW5zaW9ucywgbmV4dEZpbHRlcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIG5leHRGaWx0ZXIoZXh0ZW5zaW9ucyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBNYXAgdG8gaW5zdGFuY2VzIGFuZCBwcm9jZWVkCiAgICAgICAgICAgICAgICBvbmxvYWQoZXh0ZW5zaW9ucy5tYXAoZnVuY3Rpb24gKG0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbS5pbnN0YW5jZTsKICAgICAgICAgICAgICAgIH0pKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogSW5pdGlhbGl6ZSB0aGUgZXh0ZW5zaW9uIHBvaW50IGxpc3QgZnJvbSB0aGUgY29uZmlndXJlZCBleHRlbnNpb24gZGF0YS4KICAgICAgICAgKi8KCiAgICB9LCB7CiAgICAgICAga2V5OiAnX2luaXRFeHRlbnNpb25Qb2ludExpc3QnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfaW5pdEV4dGVuc2lvblBvaW50TGlzdCgpIHsKICAgICAgICAgICAgaWYgKCF0aGlzLmV4dGVuc2lvbkRhdGEpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiTXVzdCBjYWxsIEV4dGVuc2lvblN0b3JlLmluaXQoeyBleHRlbnNpb25EYXRhOiBhcnJheSwgdHlwZUluZm9Qcm92aWRlcjogKHR5cGUsIGNiKSA9PiAuLi4gfSkgZmlyc3QiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5leHRlbnNpb25Qb2ludExpc3QpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gV2UgY2xvbmUgdGhlIGRhdGEgYmVjYXVzZSB3ZSBhZGQgdG8gaXQuCiAgICAgICAgICAgIHRoaXMuZXh0ZW5zaW9uUG9pbnRMaXN0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLmV4dGVuc2lvbkRhdGEpKTsKICAgICAgICAgICAgZm9yICh2YXIgaTEgPSAwOyBpMSA8IHRoaXMuZXh0ZW5zaW9uUG9pbnRMaXN0Lmxlbmd0aDsgaTErKykgewogICAgICAgICAgICAgICAgdmFyIHBsdWdpbk1ldGFkYXRhID0gdGhpcy5leHRlbnNpb25Qb2ludExpc3RbaTFdOwogICAgICAgICAgICAgICAgdmFyIGV4dGVuc2lvbnMgPSBwbHVnaW5NZXRhZGF0YS5leHRlbnNpb25zIHx8IFtdOwoKICAgICAgICAgICAgICAgIGZvciAodmFyIGkyID0gMDsgaTIgPCBleHRlbnNpb25zLmxlbmd0aDsgaTIrKykgewogICAgICAgICAgICAgICAgICAgIHZhciBleHRlbnNpb25NZXRhZGF0YSA9IGV4dGVuc2lvbnNbaTJdOwogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbk1ldGFkYXRhLnBsdWdpbklkID0gcGx1Z2luTWV0YWRhdGEuaHBpUGx1Z2luSWQ7CiAgICAgICAgICAgICAgICAgICAgdmFyIGV4dGVuc2lvblBvaW50TWV0YWRhdGFzID0gdGhpcy5leHRlbnNpb25Qb2ludHNbZXh0ZW5zaW9uTWV0YWRhdGEuZXh0ZW5zaW9uUG9pbnRdID0gdGhpcy5leHRlbnNpb25Qb2ludHNbZXh0ZW5zaW9uTWV0YWRhdGEuZXh0ZW5zaW9uUG9pbnRdIHx8IFtdOwogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblBvaW50TWV0YWRhdGFzLnB1c2goZXh0ZW5zaW9uTWV0YWRhdGEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMucmVzb3VyY2VMb2FkVHJhY2tlci5zZXRFeHRlbnNpb25Qb2ludE1ldGFkYXRhKHRoaXMuZXh0ZW5zaW9uUG9pbnRMaXN0KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIExvYWQgdGhlIGJ1bmRsZXMgZm9yIHRoZSBnaXZlbiB0eXBlCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ19sb2FkQnVuZGxlcycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9sb2FkQnVuZGxlcyhleHRlbnNpb25Qb2ludElkLCBvbmxvYWQpIHsKICAgICAgICAgICAgdmFyIGV4dGVuc2lvblBvaW50TWV0YWRhdGFzID0gdGhpcy5leHRlbnNpb25Qb2ludHNbZXh0ZW5zaW9uUG9pbnRJZF07CiAgICAgICAgICAgIGlmIChleHRlbnNpb25Qb2ludE1ldGFkYXRhcyAmJiBleHRlbnNpb25Qb2ludE1ldGFkYXRhcy5sb2FkZWQpIHsKICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnQnVuZGxlcyBmb3IgZXh0ZW5zaW9uIHBvaW50ICIlcyIgYWxyZWFkeSBsb2FkZWQuJywgZXh0ZW5zaW9uUG9pbnRJZCk7CiAgICAgICAgICAgICAgICBvbmxvYWQoZXh0ZW5zaW9uUG9pbnRNZXRhZGF0YXMpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsb2dnZXIuZGVidWcoJ0J1bmRsZXMgZm9yIGV4dGVuc2lvbiBwb2ludCAiJXMiIG5vdCB5ZXQgbG9hZGVkLiBJbml0aWF0aW5nIGFzeW5jIGxvYWQuJywgZXh0ZW5zaW9uUG9pbnRJZCk7CgogICAgICAgICAgICBleHRlbnNpb25Qb2ludE1ldGFkYXRhcyA9IHRoaXMuZXh0ZW5zaW9uUG9pbnRzW2V4dGVuc2lvblBvaW50SWRdID0gdGhpcy5leHRlbnNpb25Qb2ludHNbZXh0ZW5zaW9uUG9pbnRJZF0gfHwgW107CgogICAgICAgICAgICB2YXIganNNb2R1bGVzID0gcmVxdWlyZSgnQGplbmtpbnMtY2QvanMtbW9kdWxlcycpOwogICAgICAgICAgICB2YXIgbG9hZENvdW50TW9uaXRvciA9IG5ldyBMb2FkQ291bnRNb25pdG9yKCk7CgogICAgICAgICAgICB2YXIgbG9hZFBsdWdpbkJ1bmRsZSA9IGZ1bmN0aW9uIGxvYWRQbHVnaW5CdW5kbGUocGx1Z2luTWV0YWRhdGEpIHsKICAgICAgICAgICAgICAgIGxvYWRDb3VudE1vbml0b3IuaW5jKCk7CgogICAgICAgICAgICAgICAgLy8gVGhlIHBsdWdpbiBidW5kbGUgZm9yIHRoaXMgcGx1Z2luIG1heSBhbHJlYWR5IGJlIGluIHRoZSBwcm9jZXNzIG9mIGxvYWRpbmcgKGFzeW5jIGV4dGVuc2lvbgogICAgICAgICAgICAgICAgLy8gcG9pbnQgcmVuZGVyaW5nKS4gSWYgaXQncyBub3QsIHBsdWdpbk1ldGFkYXRhLmxvYWRDb3VudE1vbml0b3JzIHdpbGwgbm90IGJlIHVuZGVmaW5lZCwKICAgICAgICAgICAgICAgIC8vIHdoaWNoIG1lYW5zIHdlIGNhbiBnbyBhaGVhZCB3aXRoIHRoZSBhc3luYyBsb2FkaW5nLiBJZiBpdCBpcywgcGx1Z2luTWV0YWRhdGEubG9hZENvdW50TW9uaXRvcnMKICAgICAgICAgICAgICAgIC8vIGlzIGRlZmluZWQsIHdlIGp1c3QgYWRkICJ0aGlzIiBsb2FkQ291bnRNb25pdG9yIHRvIHBsdWdpbk1ldGFkYXRhLmxvYWRDb3VudE1vbml0b3JzLgogICAgICAgICAgICAgICAgLy8gSXQgd2lsbCBnZXQgY2FsbGVkIGFzIHNvb24gYXMgdGhlIHNjcmlwdCBsb2FkaW5nIGlzIGNvbXBsZXRlLgogICAgICAgICAgICAgICAgaWYgKCFwbHVnaW5NZXRhZGF0YS5sb2FkQ291bnRNb25pdG9ycykgewogICAgICAgICAgICAgICAgICAgIHBsdWdpbk1ldGFkYXRhLmxvYWRDb3VudE1vbml0b3JzID0gW107CiAgICAgICAgICAgICAgICAgICAgcGx1Z2luTWV0YWRhdGEubG9hZENvdW50TW9uaXRvcnMucHVzaChsb2FkQ291bnRNb25pdG9yKTsKICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoJ0luaXRpYXRpbmcganMtZXh0ZW5zaW9ucyBidW5kbGUgbG9hZGluZyBmb3IgcGx1Z2luICIlcyIuIFRyaWdnZXJlZCBieSBleHRlbnNpb25Qb2ludElkICIlcyIuJywgcGx1Z2luTWV0YWRhdGEuaHBpUGx1Z2luSWQsIGV4dGVuc2lvblBvaW50SWQpOwogICAgICAgICAgICAgICAgICAgIGpzTW9kdWxlcy5pbXBvcnRNb2R1bGUocGx1Z2luTWV0YWRhdGEuaHBpUGx1Z2luSWQgKyAnOmplbmtpbnMtanMtZXh0ZW5zaW9uJykub25GdWxmaWxsZWQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKCdqcy1leHRlbnNpb25zIGJ1bmRsZSBmb3IgcGx1Z2luICIlcyIgbG9hZGVkLicsIHBsdWdpbk1ldGFkYXRhLmhwaVBsdWdpbklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2luTWV0YWRhdGEuYnVuZGxlTG9hZGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwbHVnaW5NZXRhZGF0YS5sb2FkQ291bnRNb25pdG9ycy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2luTWV0YWRhdGEubG9hZENvdW50TW9uaXRvcnNbaV0uZGVjKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHBsdWdpbk1ldGFkYXRhLmxvYWRDb3VudE1vbml0b3JzOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBwbHVnaW5NZXRhZGF0YS5sb2FkQ291bnRNb25pdG9ycy5wdXNoKGxvYWRDb3VudE1vbml0b3IpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgICAgICAgdmFyIGNoZWNrTG9hZGluZyA9IGZ1bmN0aW9uIGNoZWNrTG9hZGluZygpIHsKICAgICAgICAgICAgICAgIGlmIChsb2FkQ291bnRNb25pdG9yLmNvdW50ZXIgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25Qb2ludE1ldGFkYXRhcy5sb2FkZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIG9ubG9hZChleHRlbnNpb25Qb2ludE1ldGFkYXRhcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICAgICAgICAvLyBJdGVyYXRlIG92ZXIgZWFjaCBwbHVnaW4gaW4gZXh0ZW5zaW9uUG9pbnRNZXRhZGF0YSwgYXN5bmMgbG9hZGluZwogICAgICAgICAgICAvLyB0aGUgZXh0ZW5zaW9uIHBvaW50IC5qcyBidW5kbGUgKGlmIG5vdCBhbHJlYWR5IGxvYWRlZCkgZm9yIGVhY2ggb2YgdGhlCiAgICAgICAgICAgIC8vIHBsdWdpbnMgdGhhdCBpbXBsZW1lbnQgdGhlIHNwZWNpZmllZCBleHRlbnNpb25Qb2ludElkLgogICAgICAgICAgICBmb3IgKHZhciBpMSA9IDA7IGkxIDwgdGhpcy5leHRlbnNpb25Qb2ludExpc3QubGVuZ3RoOyBpMSsrKSB7CgogICAgICAgICAgICAgICAgdmFyIHBsdWdpbk1ldGFkYXRhID0gdGhpcy5leHRlbnNpb25Qb2ludExpc3RbaTFdOwogICAgICAgICAgICAgICAgdmFyIGV4dGVuc2lvbnMgPSBwbHVnaW5NZXRhZGF0YS5leHRlbnNpb25zIHx8IFtdOwoKICAgICAgICAgICAgICAgIGZvciAodmFyIGkyID0gMDsgaTIgPCBleHRlbnNpb25zLmxlbmd0aDsgaTIrKykgewogICAgICAgICAgICAgICAgICAgIHZhciBleHRlbnNpb25NZXRhZGF0YSA9IGV4dGVuc2lvbnNbaTJdOwogICAgICAgICAgICAgICAgICAgIGlmIChleHRlbnNpb25NZXRhZGF0YS5leHRlbnNpb25Qb2ludCA9PT0gZXh0ZW5zaW9uUG9pbnRJZCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIHBsdWdpbiBpbXBsZW1lbnRzIHRoZSBFeHRlbnNpb25Qb2ludC4KICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgd2UgaGF2ZW4ndCBhbHJlYWR5IGxvYWRlZCB0aGUgZXh0ZW5zaW9uIHBvaW50CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1bmRsZSBmb3IgdGhpcyBwbHVnaW4sIGxldHMgbG9hZCBpdCBub3cuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcGx1Z2luTWV0YWRhdGEuYnVuZGxlTG9hZGVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2FkUGx1Z2luQnVuZGxlKHBsdWdpbk1ldGFkYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gTGlzdGVuIHRvIHRoZSBpbmMvZGVjIGNhbGxzIG5vdyB0aGF0IHdlJ3ZlIGl0ZXJhdGVkCiAgICAgICAgICAgIC8vIG92ZXIgYWxsIG9mIHRoZSBwbHVnaW5zLgogICAgICAgICAgICBsb2FkQ291bnRNb25pdG9yLm9uY2hhbmdlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGNoZWNrTG9hZGluZygpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIC8vIENhbGwgY2hlY2tMb2FkaW5nIGltbWVkaWF0ZWx5IGluIGNhc2UgYWxsIHBsdWdpbgogICAgICAgICAgICAvLyBidW5kbGVzIGhhdmUgYmVlbiBsb2FkZWQgYWxyZWFkeS4KICAgICAgICAgICAgY2hlY2tMb2FkaW5nKCk7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBFeHRlbnNpb25TdG9yZTsKfSgpOwoKLyoqCiAqIE1haW50YWlucyBsb2FkIGNvdW50cyBmb3IgY29tcG9uZW50cwogKi8KCgpleHBvcnRzLmRlZmF1bHQgPSBFeHRlbnNpb25TdG9yZTsKCnZhciBMb2FkQ291bnRNb25pdG9yID0gZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gTG9hZENvdW50TW9uaXRvcigpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTG9hZENvdW50TW9uaXRvcik7CgogICAgICAgIHRoaXMuY291bnRlciA9IDA7CiAgICAgICAgdGhpcy5jYWxsYmFjayA9IHVuZGVmaW5lZDsKICAgIH0KCiAgICBfY3JlYXRlQ2xhc3MoTG9hZENvdW50TW9uaXRvciwgW3sKICAgICAgICBrZXk6ICdpbmMnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBpbmMoKSB7CiAgICAgICAgICAgIHRoaXMuY291bnRlcisrOwogICAgICAgICAgICBpZiAodGhpcy5jYWxsYmFjaykgewogICAgICAgICAgICAgICAgdGhpcy5jYWxsYmFjaygpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2RlYycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRlYygpIHsKICAgICAgICAgICAgdGhpcy5jb3VudGVyLS07CiAgICAgICAgICAgIGlmICh0aGlzLmNhbGxiYWNrKSB7CiAgICAgICAgICAgICAgICB0aGlzLmNhbGxiYWNrKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnb25jaGFuZ2UnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBvbmNoYW5nZShjYWxsYmFjaykgewogICAgICAgICAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBMb2FkQ291bnRNb25pdG9yOwp9KCk7Cn0seyJAamVua2lucy1jZC9qcy1tb2R1bGVzIjoxMjUsIkBqZW5raW5zLWNkL2xvZ2dpbmciOjEyOH1dLDEyMDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAiX19lc01vZHVsZSIsIHsKICAgIHZhbHVlOiB0cnVlCn0pOwoKdmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7Cgp2YXIgX2pzTW9kdWxlcyA9IHJlcXVpcmUoJ0BqZW5raW5zLWNkL2pzLW1vZHVsZXMnKTsKCnZhciBfanNNb2R1bGVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2pzTW9kdWxlcyk7CgpmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfQoKZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsgfSB9CgovKioKICogQ1NTIGxvYWQgdHJhY2tlci4KICogPHAvPgogKiBLZWVwcyB0cmFjayBvZiBwYWdlIENTUywgYWRkaW5nIGFuZCByZW1vdmluZyBDU1MgYXMgRXh0ZW5zaW9uUG9pbnQgY29tcG9uZW50cyBhcmUKICogbW91bnRlZCBhbmQgdW5tb3VudGVkLgogKi8KdmFyIFJlc291cmNlTG9hZFRyYWNrZXIgPSBmdW5jdGlvbiAoKSB7CiAgICBmdW5jdGlvbiBSZXNvdXJjZUxvYWRUcmFja2VyKCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBSZXNvdXJjZUxvYWRUcmFja2VyKTsKCiAgICAgICAgLy8gVGhlIENTUyByZXNvdXJjZXMgdG8gYmUgYWRkZWQgZm9yIGVhY2ggRXh0ZW5zaW9uIHBvaW50LgogICAgICAgIC8vIEtleTogICAgIEV4dGVuc2lvbiBwb2ludCBuYW1lLgogICAgICAgIC8vIFZhbHVlOiAgIEFuIGFycmF5IG9mIENTUyBhZGp1bmN0IFVSTHMgdGhhdCBuZWVkIHRvIGJlIGFjdGl2YXRlZCB3aGVuIHRoZSBleHRlbnNpb24gcG9pbnQgaXMgcmVuZGVyZWQuCiAgICAgICAgdGhpcy5wb2ludENTU3MgPSB7fTsKCiAgICAgICAgLy8gQWN0aXZlIENTUy4KICAgICAgICAvLyBLZXk6ICAgICBDU1MgVVJMLgogICAgICAgIC8vIFZhbHVlOiAgIENvdW50ZXIgb2YgdGhlIG51bWJlciBvZiBtb3VudGVkIEV4dGVuc2lvbiBQb2ludHMgdGhhdCBuZWVkIHRoZSBDU1MgdG8gYmUgYWN0aXZlLgogICAgICAgIC8vICAgICAgICAgICAgICAgVGhlIG9uTW91bnQgYW5kIG9uVW5tb3VudCBmdW5jdGlvbnMgaW5jcmVtZW50IGFuZCBkZWNyZW1lbnQgdGhlIGNvdW50ZXIuIFdoZW4gdGhlCiAgICAgICAgLy8gICAgICAgICAgICAgICBjb3VudGVyIGdldHMgYmFjayB0byB6ZXJvLCB0aGUgQ1NTIGNhbiBiZSByZW1vdmVkIGZyb20gdGhlIHBhZ2UuCiAgICAgICAgdGhpcy5hY3RpdmVDU1NzID0ge307CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplIHRoZSBsb2FkZXIgd2l0aCB0aGUgZXh0ZW5zaW9uIHBvaW50IGluZm9ybWF0aW9uLgogICAgICogQHBhcmFtIGV4dGVuc2lvblBvaW50TGlzdCBUaGUgRXh0ZW5zaW9uIHBvaW50IGxpc3QuIEFuIGFycmF5IGNvbnRhaW5pbmcgRXh0ZW5zaW9uUG9pbnQKICAgICAqIG1ldGFkYXRhIGZvciBhbGwgcGx1Z2lucyB0aGF0IGRlZmluZSBzdWNoLiBJdCdzIGFuIGFnZ3JlZ2F0aW9uIG9mCiAgICAgKiBvZiB0aGUgL2plbmtpbnMtanMtZXh0ZW5zaW9uLmpzb24gZmlsZXMgZm91bmQgb24gdGhlIHNlcnZlciBjbGFzc3BhdGguCiAgICAgKi8KCgogICAgX2NyZWF0ZUNsYXNzKFJlc291cmNlTG9hZFRyYWNrZXIsIFt7CiAgICAgICAga2V5OiAnc2V0RXh0ZW5zaW9uUG9pbnRNZXRhZGF0YScsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNldEV4dGVuc2lvblBvaW50TWV0YWRhdGEoZXh0ZW5zaW9uUG9pbnRMaXN0KSB7CiAgICAgICAgICAgIC8vIFJlc2V0IC0gZm9yIHRlc3RpbmcuCiAgICAgICAgICAgIHRoaXMucG9pbnRDU1NzID0ge307CiAgICAgICAgICAgIHRoaXMuYWN0aXZlQ1NTcyA9IHt9OwoKICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aHJvdWdoIGVhY2ggcGx1Z2luIC9qZW5raW5zLWpzLWV4dGVuc2lvbi5qc29uCiAgICAgICAgICAgIGZvciAodmFyIGkxID0gMDsgaTEgPCBleHRlbnNpb25Qb2ludExpc3QubGVuZ3RoOyBpMSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgcGx1Z2luTWV0YWRhdGEgPSBleHRlbnNpb25Qb2ludExpc3RbaTFdOwogICAgICAgICAgICAgICAgdmFyIGV4dGVuc2lvbnMgPSBwbHVnaW5NZXRhZGF0YS5leHRlbnNpb25zOyAvLyBBbGwgdGhlIGV4dGVuc2lvbnMgZGVmaW5lZCBvbiB0aGUgcGx1Z2luCiAgICAgICAgICAgICAgICB2YXIgcGx1Z2luQ1NTID0gcGx1Z2luTWV0YWRhdGEuZXh0ZW5zaW9uQ1NTOyAvLyBUaGUgcGx1Z2luIENTUyBVUkwgKGFkanVuY3QgVVJMKS4KCiAgICAgICAgICAgICAgICAvLyBJdGVyYXRlIHRocm91Z2ggdGhlIEV4dGVuc2lvblBvaW50cyBkZWZpbmVkIGluIGVhY2ggcGx1Z2luCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpMiA9IDA7IGkyIDwgZXh0ZW5zaW9ucy5sZW5ndGg7IGkyKyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZXh0ZW5zaW9uUG9pbnQgPSBleHRlbnNpb25zW2kyXS5leHRlbnNpb25Qb2ludDsgLy8gVGhlIGV4dGVuc2lvbiBwb2ludCBuYW1lLgogICAgICAgICAgICAgICAgICAgIHZhciBwb2ludENTUyA9IHRoaXMucG9pbnRDU1NzW2V4dGVuc2lvblBvaW50XTsgLy8gVGhlIGN1cnJlbnQgbGlzdCBvZiBDU1MgVVJMcyBmb3IgdGhlIG5hbWVkIGV4dGVuc2lvbiBwb2ludC4KCiAgICAgICAgICAgICAgICAgICAgaWYgKCFwb2ludENTUykgewogICAgICAgICAgICAgICAgICAgICAgICBwb2ludENTUyA9IFtdOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBvaW50Q1NTc1tleHRlbnNpb25Qb2ludF0gPSBwb2ludENTUzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIEFkZCB0aGUgcGx1Z2luIENTUyBpZiBpdCdzIG5vdCBhbHJlYWR5IGluIHRoZSBsaXN0LgogICAgICAgICAgICAgICAgICAgIGlmIChwb2ludENTUy5pbmRleE9mKHBsdWdpbkNTUykgPT09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50Q1NTLnB1c2gocGx1Z2luQ1NTKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENhbGxlZCB3aGVuIGEgSmVua2lucyBFeHRlbnNpb25Qb2ludCBpcyBtb3VudGVkLgogICAgICAgICAqIDxwLz4KICAgICAgICAgKiBJZiB0aGUgZXh0ZW5zaW9uIHBvaW50IGltcGxlbWVudGF0aW9ucyB1c2UgQ1NTIChjb21lcyBmcm9tIHBsdWdpbnMgdGhhdCBkZWZpbmUgQ1NTKQogICAgICAgICAqIHRoZW4gdGhpcyBtZXRob2Qgd2lsbCB1c2UgcmVxdWlyZUNTUywgYW5kIHRoZW4gYWRkQ1NTLCBmb3IgZWFjaCBDU1MuIGFkZENTUyBvbmx5CiAgICAgICAgICogZ2V0cyBjYWxsZWQgZm9yIGEgQ1NTIGJ5IHRoZSBmaXJzdCBleHRlbnNpb24gcG9pbnQgdG8gInJlcXVpcmUiIHRoYXQgQ1NTLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGV4dGVuc2lvblBvaW50TmFtZSBUaGUgZXh0ZW5zaW9uIHBvaW50IG5hbWUuCiAgICAgICAgICovCgogICAgfSwgewogICAgICAgIGtleTogJ29uTW91bnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBvbk1vdW50KGV4dGVuc2lvblBvaW50TmFtZSkgewogICAgICAgICAgICB2YXIgcG9pbnRDU1MgPSB0aGlzLnBvaW50Q1NTc1tleHRlbnNpb25Qb2ludE5hbWVdOwogICAgICAgICAgICBpZiAocG9pbnRDU1MpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRDU1MubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZXF1aXJlQ1NTKHBvaW50Q1NTW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ2FsbGVkIHdoZW4gYSBKZW5raW5zIEV4dGVuc2lvblBvaW50IGlzIHVubW91bnRlZC4KICAgICAgICAgKiA8cC8+CiAgICAgICAgICogSWYgdGhlIGV4dGVuc2lvbiBwb2ludCBpbXBsZW1lbnRhdGlvbnMgdXNlIENTUyAoY29tZXMgZnJvbSBwbHVnaW5zIHRoYXQgZGVmaW5lIENTUykKICAgICAgICAgKiB0aGVuIHRoaXMgbWV0aG9kIHdpbGwgdXNlIHVucmVxdWlyZUNTUywgYW5kIHRoZW4gcmVtb3ZlQ1NTLCBmb3IgZWFjaCBDU1MuIHJlbW92ZUNTUyBvbmx5CiAgICAgICAgICogZ2V0cyBjYWxsZWQgZm9yIGEgQ1NTIGJ5IHRoZSBsYXN0IGV4dGVuc2lvbiBwb2ludCB0byAidW5yZXF1aXJlIiB0aGF0IENTUy4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBleHRlbnNpb25Qb2ludE5hbWUgVGhlIGV4dGVuc2lvbiBwb2ludCBuYW1lLgogICAgICAgICAqLwoKICAgIH0sIHsKICAgICAgICBrZXk6ICdvblVubW91bnQnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBvblVubW91bnQoZXh0ZW5zaW9uUG9pbnROYW1lKSB7CiAgICAgICAgICAgIHZhciBwb2ludENTUyA9IHRoaXMucG9pbnRDU1NzW2V4dGVuc2lvblBvaW50TmFtZV07CiAgICAgICAgICAgIGlmIChwb2ludENTUykgewogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludENTUy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX3VucmVxdWlyZUNTUyhwb2ludENTU1tpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX3JlcXVpcmVDU1MnLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfcmVxdWlyZUNTUyh1cmwpIHsKICAgICAgICAgICAgaWYgKCF0aGlzLmFjdGl2ZUNTU3NbdXJsXSkgewogICAgICAgICAgICAgICAgdGhpcy5fYWRkQ1NTKHVybCk7CiAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZUNTU3NbdXJsXSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX3VucmVxdWlyZUNTUycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF91bnJlcXVpcmVDU1ModXJsKSB7CiAgICAgICAgICAgIHZhciBhY3RpdmVDb3VudCA9IHRoaXMuYWN0aXZlQ1NTc1t1cmxdOwoKICAgICAgICAgICAgaWYgKCFhY3RpdmVDb3VudCkgewogICAgICAgICAgICAgICAgLy8gSHVoPwogICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdVbmV4cGVjdGVkIGNhbGwgdG8gZGVhY3RpdmF0ZSBhbiBpbmFjdGl2ZSBKZW5raW5zIEV4dGVuc2lvbiBQb2ludCBDU1M6ICcgKyB1cmwpOwogICAgICAgICAgICAgICAgLy8gRG9lcyB0aGlzIG1lYW4gdGhhdCByZWFjdCBjYWxscyB1bm1vdW50IG11bHRpcGxlIHRpbWVzIGZvciBhIGdpdmVuIGNvbXBvbmVudCBpbnN0YW5jZT8KICAgICAgICAgICAgICAgIC8vIFRoYXQgd291bGQgc291bmQgbGlrZSBhIGJ1Zywgbm8/CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhY3RpdmVDb3VudC0tOwogICAgICAgICAgICAgICAgaWYgKGFjdGl2ZUNvdW50ID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQWxsIGV4dGVuc2lvbiBwb2ludHMgdXNpbmcgdGhpcyBDU1MgaGF2ZSBiZWVuIHVubW91bnRlZC4KICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5hY3RpdmVDU1NzW3VybF07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlQ1NTKHVybCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlQ1NTc1t1cmxdID0gYWN0aXZlQ291bnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX2FkZENTUycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9hZGRDU1ModXJsKSB7CiAgICAgICAgICAgIHZhciBjc3NVUkxQcmVmaXggPSBfanNNb2R1bGVzMi5kZWZhdWx0LmdldEFkanVuY3RVUkwoKTsKICAgICAgICAgICAgX2pzTW9kdWxlczIuZGVmYXVsdC5hZGRDU1NUb1BhZ2UoY3NzVVJMUHJlZml4ICsgJy8nICsgdXJsKTsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX3JlbW92ZUNTUycsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9yZW1vdmVDU1ModXJsKSB7CiAgICAgICAgICAgIHZhciBjc3NVUkxQcmVmaXggPSBfanNNb2R1bGVzMi5kZWZhdWx0LmdldEFkanVuY3RVUkwoKTsKICAgICAgICAgICAgdmFyIGNzc1VSTCA9IGNzc1VSTFByZWZpeCArICcvJyArIHVybDsKICAgICAgICAgICAgdmFyIGxpbmtFbElkID0gX2pzTW9kdWxlczIuZGVmYXVsdC50b0NTU0lkKGNzc1VSTCk7CiAgICAgICAgICAgIHZhciBsaW5rRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChsaW5rRWxJZCk7CgogICAgICAgICAgICBpZiAobGlua0VsKSB7CiAgICAgICAgICAgICAgICBsaW5rRWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChsaW5rRWwpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfV0pOwoKICAgIHJldHVybiBSZXNvdXJjZUxvYWRUcmFja2VyOwp9KCk7CgpleHBvcnRzLmRlZmF1bHQgPSBSZXNvdXJjZUxvYWRUcmFja2VyOwp9LHsiQGplbmtpbnMtY2QvanMtbW9kdWxlcyI6MTI1fV0sMTIxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKfSk7Cgp2YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCJ2YWx1ZSIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsKCmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7IH0gfQoKZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsgfSByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICJvYmplY3QiIHx8IHR5cGVvZiBjYWxsID09PSAiZnVuY3Rpb24iKSA/IGNhbGwgOiBzZWxmOyB9CgpmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAiZnVuY3Rpb24iICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfQoKLyoqCiAqIENyZWF0ZWQgYnkgY21leWVycyBvbiAxMC8yMS8xNi4KICovCnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7CnZhciBSZWFjdERPTSA9IHJlcXVpcmUoJ3JlYWN0LWRvbScpOwp2YXIgUHJvcFR5cGVzID0gUmVhY3QuUHJvcFR5cGVzOwoKdmFyIENvbnRleHRCcmlkZ2UgPSByZXF1aXJlKCcuL0NvbnRleHRCcmlkZ2UnKS5Db250ZXh0QnJpZGdlOwp2YXIgRXJyb3JVdGlscyA9IHJlcXVpcmUoJy4vRXJyb3JVdGlscycpLmRlZmF1bHQ7CgovKioKICogQ29tcG9uZW50IHRoYXQgcmVuZGVycyBhbnkgcGFzc2VkLWluIGNoaWxkcmVuIHZpYSBhIHNlcGFyYXRlIFJlYWN0RE9NLnJlbmRlciBjYWxsLgogKiBVc2VmdWwgZm9yIHJlbmRlcmluZyB1bnRydXN0ZWQgUmVhY3QgZWxlbWVudHM6IGVycm9ycyB3aWxsIGJlIHRyYXBwZWQgYW5kIGRpc3BsYXllZCBzbyB0aGUgbWFpbiBVSSBpc24ndCBicm9rZW4uCiAqLwoKdmFyIFNhbmRib3hlZENvbXBvbmVudCA9IGV4cG9ydHMuU2FuZGJveGVkQ29tcG9uZW50ID0gZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHsKICAgIF9pbmhlcml0cyhTYW5kYm94ZWRDb21wb25lbnQsIF9SZWFjdCRDb21wb25lbnQpOwoKICAgIGZ1bmN0aW9uIFNhbmRib3hlZENvbXBvbmVudChwcm9wcykgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTYW5kYm94ZWRDb21wb25lbnQpOwoKICAgICAgICB2YXIgX3RoaXMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoU2FuZGJveGVkQ29tcG9uZW50Ll9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoU2FuZGJveGVkQ29tcG9uZW50KSkuY2FsbCh0aGlzLCBwcm9wcykpOwoKICAgICAgICBfdGhpcy5kb21Ob2RlID0gbnVsbDsKICAgICAgICByZXR1cm4gX3RoaXM7CiAgICB9CgogICAgX2NyZWF0ZUNsYXNzKFNhbmRib3hlZENvbXBvbmVudCwgW3sKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHsKICAgICAgICAgICAgaWYgKG5leHRQcm9wcy5jaGlsZHJlbiAhPT0gdGhpcy5wcm9wcy5jaGlsZHJlbikgewogICAgICAgICAgICAgICAgdGhpcy5fY2xlYW51cENoaWxkKCk7CiAgICAgICAgICAgICAgICB0aGlzLl9yZW5kZXJDaGlsZChuZXh0UHJvcHMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwgewogICAgICAgIGtleTogJ2NvbXBvbmVudERpZE1vdW50JywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7CiAgICAgICAgICAgIHRoaXMuX3JlbmRlckNoaWxkKHRoaXMucHJvcHMpOwogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdjb21wb25lbnRXaWxsVW5tb3VudCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkgewogICAgICAgICAgICB0aGlzLl9jbGVhbnVwQ2hpbGQoKTsKICAgICAgICAgICAgdGhpcy5kb21Ob2RlID0gbnVsbDsKICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX3JlbmRlckNoaWxkJywKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX3JlbmRlckNoaWxkKHByb3BzKSB7CiAgICAgICAgICAgIGlmICghdGhpcy5kb21Ob2RlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHZhciBjb250ZXh0VmFsdWVzQXNQcm9wcyA9IHsKICAgICAgICAgICAgICAgICAgICBjb25maWc6IHRoaXMuY29udGV4dC5jb25maWcsCiAgICAgICAgICAgICAgICAgICAgcm91dGVyOiB0aGlzLmNvbnRleHQucm91dGVyCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgdmFyIGJyaWRnZWRDb21wb25lbnQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KENvbnRleHRCcmlkZ2UsIGNvbnRleHRWYWx1ZXNBc1Byb3BzLCBwcm9wcy5jaGlsZHJlbik7CiAgICAgICAgICAgICAgICBSZWFjdERPTS5yZW5kZXIoYnJpZGdlZENvbXBvbmVudCwgdGhpcy5kb21Ob2RlKTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdlcnJvciByZW5kZXJpbmc6ICcsIGUpOwogICAgICAgICAgICAgICAgUmVhY3RET00ucmVuZGVyKEVycm9yVXRpbHMuZXJyb3JUb0VsZW1lbnQoZSksIHRoaXMuZG9tTm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LCB7CiAgICAgICAga2V5OiAnX2NsZWFudXBDaGlsZCcsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9jbGVhbnVwQ2hpbGQoKSB7CiAgICAgICAgICAgIGlmICh0aGlzLmRvbU5vZGUpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgUmVhY3RET00udW5tb3VudENvbXBvbmVudEF0Tm9kZSh0aGlzLmRvbU5vZGUpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coIkVycm9yIHVubW91bnRpbmcgY29tcG9uZW50IiwgZXJyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sIHsKICAgICAgICBrZXk6ICdyZW5kZXInLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzOwoKICAgICAgICAgICAgdmFyIGV4dHJhQ2xhc3MgPSB0aGlzLnByb3BzLmNsYXNzTmFtZSB8fCAnJzsKCiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KCdkaXYnLCB7IGNsYXNzTmFtZTogJ3NhbmRib3gtY29tcG9uZW50ICcgKyBleHRyYUNsYXNzLCByZWY6IGZ1bmN0aW9uIHJlZihub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgX3RoaXMyLmRvbU5vZGUgPSBub2RlOwogICAgICAgICAgICAgICAgfSB9KTsKICAgICAgICB9CiAgICB9XSk7CgogICAgcmV0dXJuIFNhbmRib3hlZENvbXBvbmVudDsKfShSZWFjdC5Db21wb25lbnQpOwoKU2FuZGJveGVkQ29tcG9uZW50LnByb3BUeXBlcyA9IHsKICAgIGNoaWxkcmVuOiBQcm9wVHlwZXMubm9kZSwKICAgIGNsYXNzTmFtZTogUHJvcFR5cGVzLnN0cmluZwp9OwoKU2FuZGJveGVkQ29tcG9uZW50LmNvbnRleHRUeXBlcyA9IHsKICAgIHJvdXRlcjogUHJvcFR5cGVzLm9iamVjdCwKICAgIGNvbmZpZzogUHJvcFR5cGVzLm9iamVjdAp9Owp9LHsiLi9Db250ZXh0QnJpZGdlIjoxMTYsIi4vRXJyb3JVdGlscyI6MTE3LCJyZWFjdCI6NjIzLCJyZWFjdC1kb20iOjQzMH1dLDEyMjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7CmNvbnN0IEV4dGVuc2lvblN0b3JlID0gcmVxdWlyZSgnLi9kaXN0L0V4dGVuc2lvblN0b3JlLmpzJykuZGVmYXVsdDsKZXhwb3J0cy5zdG9yZSA9IG5ldyBFeHRlbnNpb25TdG9yZSgpOwoKZXhwb3J0cy5SZW5kZXJlciA9IHJlcXVpcmUoJy4vZGlzdC9FeHRlbnNpb25SZW5kZXJlci5qcycpLmRlZmF1bHQ7CgovL2luIGxpZXUgb2YgREkKY29uc3QgUmVzb3VyY2VMb2FkVHJhY2tlciA9IHJlcXVpcmUoJy4vZGlzdC9SZXNvdXJjZUxvYWRUcmFja2VyLmpzJykuZGVmYXVsdDsKY29uc3QgcmVzb3VyY2VMb2FkVHJhY2tlciA9IG5ldyBSZXNvdXJjZUxvYWRUcmFja2VyKCk7CmV4cG9ydHMuc3RvcmUucmVzb3VyY2VMb2FkVHJhY2tlciA9IHJlc291cmNlTG9hZFRyYWNrZXI7CgovL1B1dCB0aGVzZSBpbiBzdGF0aWNzIHNvIHdlIGNhbiBtb2NrIHRoZW0gZm9yIHRlc3RpbmcuIElkZWFsbHkgdGhleSB3b3VsZCBjb21lIGZyb20gUmVhY3Qgc2NvcGUuCmV4cG9ydHMuUmVuZGVyZXIuZXh0ZW5zaW9uU3RvcmUgPSBleHBvcnRzLnN0b3JlOwpleHBvcnRzLlJlbmRlcmVyLnJlc291cmNlTG9hZFRyYWNrZXIgPSByZXNvdXJjZUxvYWRUcmFja2VyOwoKY29uc3QgQ2xhc3NNZXRhZGF0YVN0b3JlID0gcmVxdWlyZSgnLi9kaXN0L0NsYXNzTWV0YWRhdGFTdG9yZS5qcycpLmRlZmF1bHQ7CmV4cG9ydHMuY2xhc3NNZXRhZGF0YVN0b3JlID0gbmV3IENsYXNzTWV0YWRhdGFTdG9yZSgpOwoKZXhwb3J0cy5TYW5kYm94ZWRDb21wb25lbnQgPSByZXF1aXJlKCcuL2Rpc3QvU2FuZGJveGVkQ29tcG9uZW50LmpzJykuU2FuZGJveGVkQ29tcG9uZW50OwoKZXhwb3J0cy5FcnJvclV0aWxzID0gcmVxdWlyZSgnLi9kaXN0L0Vycm9yVXRpbHMuanMnKS5kZWZhdWx0OwoKZXhwb3J0cy5kYXRhVHlwZSA9IGZ1bmN0aW9uIGRhdGFUeXBlKGRhdGFUeXBlKSB7IHJldHVybiBleHBvcnRzLmNsYXNzTWV0YWRhdGFTdG9yZS5kYXRhVHlwZShkYXRhVHlwZSk7IH07CgpleHBvcnRzLnVudHlwZWQgPSBmdW5jdGlvbiB1bnR5cGVkKCkgeyByZXR1cm4gZXhwb3J0cy5jbGFzc01ldGFkYXRhU3RvcmUudW50eXBlZCgpOyB9OwoKZXhwb3J0cy5pc1R5cGUgPSByZXF1aXJlKCcuL2Rpc3QvQ29tcG9uZW50VHlwZUZpbHRlci5qcycpLmlzVHlwZTsKCmV4cG9ydHMuY29tcG9uZW50VHlwZSA9IHJlcXVpcmUoJy4vZGlzdC9Db21wb25lbnRUeXBlRmlsdGVyLmpzJykuY29tcG9uZW50VHlwZTsKCmV4cG9ydHMuaW5pdCA9IGZ1bmN0aW9uIGluaXQoYXJncykgewogICAgZXhwb3J0cy5jbGFzc01ldGFkYXRhU3RvcmUuaW5pdChhcmdzLmNsYXNzTWV0YWRhdGFQcm92aWRlcik7CiAgICBleHBvcnRzLnN0b3JlLmluaXQoewogICAgICAgIGV4dGVuc2lvbkRhdGE6IGFyZ3MuZXh0ZW5zaW9uRGF0YSwKICAgICAgICBjbGFzc01ldGFkYXRhU3RvcmU6IGV4cG9ydHMuY2xhc3NNZXRhZGF0YVN0b3JlLAogICAgfSk7Cn07Cn0seyIuL2Rpc3QvQ2xhc3NNZXRhZGF0YVN0b3JlLmpzIjoxMTQsIi4vZGlzdC9Db21wb25lbnRUeXBlRmlsdGVyLmpzIjoxMTUsIi4vZGlzdC9FcnJvclV0aWxzLmpzIjoxMTcsIi4vZGlzdC9FeHRlbnNpb25SZW5kZXJlci5qcyI6MTE4LCIuL2Rpc3QvRXh0ZW5zaW9uU3RvcmUuanMiOjExOSwiLi9kaXN0L1Jlc291cmNlTG9hZFRyYWNrZXIuanMiOjEyMCwiLi9kaXN0L1NhbmRib3hlZENvbXBvbmVudC5qcyI6MTIxfV0sMTIzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKdmFyIFZlcnNpb24gPSByZXF1aXJlKCcuL1ZlcnNpb24nKTsKCmZ1bmN0aW9uIE1vZHVsZVNwZWMocU5hbWUpIHsKICAgIHZhciBxTmFtZVRva2VucyA9IHFOYW1lLnNwbGl0KCI6Iik7CiAgICAKICAgIGlmIChxTmFtZVRva2Vucy5sZW5ndGggPT09IDIpIHsKICAgICAgICB2YXIgbmFtZXNwYWNlID0gcU5hbWVUb2tlbnNbMF0udHJpbSgpOwogICAgICAgIHZhciBuc1Rva2VucyA9IG5hbWVzcGFjZS5zcGxpdCgiLyIpOwogICAgICAgIHZhciBuYW1lc3BhY2VQcm92aWRlciA9IHVuZGVmaW5lZDsKICAgICAgICBpZiAobnNUb2tlbnMubGVuZ3RoID09PSAyKSB7CiAgICAgICAgICAgIG5hbWVzcGFjZVByb3ZpZGVyID0gbnNUb2tlbnNbMF0udHJpbSgpOwogICAgICAgICAgICBuYW1lc3BhY2UgPSBuc1Rva2Vuc1sxXS50cmltKCk7CiAgICAgICAgICAgIGlmIChuYW1lc3BhY2VQcm92aWRlciAhPT0gJ3BsdWdpbicgJiYgbmFtZXNwYWNlUHJvdmlkZXIgIT09ICdjb3JlLWFzc2V0cycpIHsKICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1Vuc3VwcG9ydGVkIG1vZHVsZSBuYW1lc3BhY2UgcHJvdmlkZXIgIicgKyBuYW1lc3BhY2VQcm92aWRlciArICciLiBTZXR0aW5nIHRvIHVuZGVmaW5lZC4nKTsKICAgICAgICAgICAgICAgIG5hbWVzcGFjZVByb3ZpZGVyID0gdW5kZWZpbmVkOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHZhciBucG1OYW1lID0gcGFyc2VOUE1OYW1lKHFOYW1lVG9rZW5zWzFdLnRyaW0oKSk7CiAgICAgICAgCiAgICAgICAgdGhpcy5uc1Byb3ZpZGVyID0gbmFtZXNwYWNlUHJvdmlkZXI7CiAgICAgICAgdGhpcy5uYW1lc3BhY2UgPSBuYW1lc3BhY2U7CiAgICAgICAgdGhpcy5tb2R1bGVOYW1lID0gbnBtTmFtZS5uYW1lOwogICAgICAgIHRoaXMubW9kdWxlVmVyc2lvbiA9IG5wbU5hbWUudmVyc2lvbjsKICAgIH0gZWxzZSB7CiAgICAgICAgLy8gVGhlIG1vZHVsZS9idW5kbGUgaXMgbm90IGluIGEgbmFtZXNwYWNlIGFuZCBkb2Vzbid0CiAgICAgICAgLy8gbmVlZCB0byBiZSBsb2FkZWQgaS5lLiBpdCB3aWxsIGxvYWQgaXRzZWxmIGFuZCBleHBvcnQuCiAgICAgICAgdmFyIG5wbU5hbWUgPSBwYXJzZU5QTU5hbWUocU5hbWVUb2tlbnNbMF0udHJpbSgpKTsKCiAgICAgICAgdGhpcy5tb2R1bGVOYW1lID0gbnBtTmFtZS5uYW1lOwogICAgICAgIHRoaXMubW9kdWxlVmVyc2lvbiA9IG5wbU5hbWUudmVyc2lvbjsKICAgIH0KCiAgICAvLyBBdHRhY2ggdmVyc2lvbiBjb21wYXRpYmlsaXR5IGluZm8KICAgIHZhciB2ZXJzaW9ucyA9IFtdOwogICAgCiAgICBpZiAodGhpcy5tb2R1bGVWZXJzaW9uKSB7CiAgICAgICAgdmFyIG1vZHVsZVZlcnNpb25Ub2tlbnMgPSB0aGlzLm1vZHVsZVZlcnNpb24uc3BsaXQoL1ssfF0rLyk7CgogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbW9kdWxlVmVyc2lvblRva2Vucy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICB2YXIgbW9kdWxlVmVyc2lvblRva2VuID0gbW9kdWxlVmVyc2lvblRva2Vuc1tpXS50cmltKCk7CiAgICAgICAgICAgIHZhciBwYXJzZWRWZXJzaW9uID0gbmV3IFZlcnNpb24obW9kdWxlVmVyc2lvblRva2VuKTsKICAgICAgICAgICAgdmVyc2lvbnMucHVzaChwYXJzZWRWZXJzaW9uKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIHRoaXMubW9kdWxlQ29tcGF0VmVyc2lvbnMgPSB2ZXJzaW9uczsKfQoKTW9kdWxlU3BlYy5wcm90b3R5cGUuZ2V0TG9hZEJ1bmRsZVZlcnNpb24gPSBmdW5jdGlvbigpIHsKICAgIGlmICh0aGlzLm1vZHVsZUNvbXBhdFZlcnNpb25zLmxlbmd0aCA9PT0gMCkgewogICAgICAgIC8vIElmIG5vIHZlcnNpb25zIHdlcmUgc3BlY2lmaWVkIG9uIHRoZSBuYW1lLCB0aGVuIHdlCiAgICAgICAgLy8ganVzdCByZXR1cm4gdW5kZWZpbmVkLgogICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICB9CiAgICAvLyBJZiBhIHZlcnNpb24