wao 0.41.3 → 0.41.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc-cjs +5 -0
- package/.babelrc-esm +5 -0
- package/.gitmodules +4 -0
- package/.prettierrc +6 -0
- package/README.md +90 -0
- package/app/.eslintrc.json +3 -0
- package/app/.mocharc.cjs +6 -0
- package/app/arweave.mjs +87 -0
- package/app/components/Footer.js +76 -0
- package/app/components/Global.js +1128 -0
- package/app/components/Header.js +306 -0
- package/app/components/Left.js +28 -0
- package/app/components/Logo.js +34 -0
- package/app/components/Middle.js +37 -0
- package/app/components/Sidebar.js +93 -0
- package/app/components/Tags.js +42 -0
- package/app/components/editor/Editor.js +322 -0
- package/app/components/editor/FilePath.js +42 -0
- package/app/components/editor/MonacoEditor.js +44 -0
- package/app/components/left/LeftMessages.js +85 -0
- package/app/components/left/LeftModules.js +86 -0
- package/app/components/left/LeftNetworks.js +438 -0
- package/app/components/left/LeftProcesses.js +98 -0
- package/app/components/left/LeftProjects.js +397 -0
- package/app/components/left/LeftTests.js +189 -0
- package/app/components/middle/MiddleBlocks.js +79 -0
- package/app/components/middle/MiddleEntity.js +16 -0
- package/app/components/middle/MiddleEntityAccount.js +264 -0
- package/app/components/middle/MiddleEntityAssignment.js +104 -0
- package/app/components/middle/MiddleEntityBlock.js +148 -0
- package/app/components/middle/MiddleEntityMessage.js +430 -0
- package/app/components/middle/MiddleEntityModule.js +183 -0
- package/app/components/middle/MiddleEntityProcess.js +323 -0
- package/app/components/middle/MiddleEntityTx.js +211 -0
- package/app/components/middle/MiddleMessages.js +87 -0
- package/app/components/middle/MiddleModules.js +89 -0
- package/app/components/middle/MiddleNetworks.js +516 -0
- package/app/components/middle/MiddleProcesses.js +87 -0
- package/app/components/middle/MiddleTests.js +134 -0
- package/app/components/modals/CreateFileModal.js +115 -0
- package/app/components/modals/CreateFolderModal.js +83 -0
- package/app/components/modals/CreateProjectModal.js +63 -0
- package/app/components/modals/FSModal.js +141 -0
- package/app/components/modals/ImportModal.js +105 -0
- package/app/components/modals/LaunchNetworkModal.js +95 -0
- package/app/components/modals/Modal.js +38 -0
- package/app/components/modals/ProxyModal.js +122 -0
- package/app/components/modals/RenameFileModal.js +95 -0
- package/app/components/styles/EditorScrollbarStyle.js +29 -0
- package/app/components/styles/EntityScrollbarStyle.js +29 -0
- package/app/components/styles/GlobalStyle.js +102 -0
- package/app/components/styles/XtermStyle.js +37 -0
- package/app/components/terminal/Terminal.js +132 -0
- package/app/components/terminal/Xterm.js +160 -0
- package/app/components/ui/avatar.jsx +49 -0
- package/app/components/ui/checkbox.jsx +17 -0
- package/app/components/ui/close-button.jsx +20 -0
- package/app/components/ui/color-mode.jsx +61 -0
- package/app/components/ui/dialog.jsx +54 -0
- package/app/components/ui/drawer.jsx +44 -0
- package/app/components/ui/field.jsx +22 -0
- package/app/components/ui/input-group.jsx +39 -0
- package/app/components/ui/popover.jsx +49 -0
- package/app/components/ui/provider.jsx +12 -0
- package/app/components/ui/radio.jsx +17 -0
- package/app/components/ui/slider.jsx +107 -0
- package/app/components/ui/toaster.jsx +69 -0
- package/app/components/ui/tooltip.jsx +35 -0
- package/app/index.js +10 -0
- package/app/jsconfig.json +7 -0
- package/app/lib/GithubCSS.js +1218 -0
- package/app/lib/addon-fit.js +72 -0
- package/app/lib/data.js +31 -0
- package/app/lib/github-markdown.css +1169 -0
- package/app/lib/global.js +1 -0
- package/app/lib/guide.js +82 -0
- package/app/lib/hub.js +109 -0
- package/app/lib/scripts.js +47 -0
- package/app/lib/store.js +34 -0
- package/app/lib/use.js +64 -0
- package/app/lib/utils.js +387 -0
- package/app/lib/webrtc.js +217 -0
- package/app/next.config.js +25 -0
- package/app/package.json +62 -0
- package/app/pages/404.js +9 -0
- package/app/pages/_app.js +10 -0
- package/app/pages/_document.js +14 -0
- package/app/pages/index.js +121 -0
- package/app/playwright.config.mjs +41 -0
- package/app/proxy.mjs +21 -0
- package/app/public/assets/cover.png +0 -0
- package/app/public/blueprints/apm.lua +91 -0
- package/app/public/blueprints/arena.lua +345 -0
- package/app/public/blueprints/arns.lua +318 -0
- package/app/public/blueprints/chat.lua +210 -0
- package/app/public/blueprints/chatroom.lua +56 -0
- package/app/public/blueprints/patch-legacy-reply.lua +13 -0
- package/app/public/blueprints/staking.lua +93 -0
- package/app/public/blueprints/token.lua +298 -0
- package/app/public/blueprints/voting.lua +45 -0
- package/app/public/favicon.ico +0 -0
- package/app/public/logo.png +0 -0
- package/cli-esm.js +55 -0
- package/cli.js +54 -0
- package/devnet/app/api.js +129 -0
- package/devnet/app/components/layout.js +89 -0
- package/devnet/app/components/pagination.js +144 -0
- package/devnet/app/components/search.js +159 -0
- package/devnet/app/components/table.js +124 -0
- package/devnet/app/components/tags.js +89 -0
- package/devnet/app/index.html +14 -0
- package/devnet/app/main.js +215 -0
- package/devnet/app/router.js +59 -0
- package/devnet/app/state.js +19 -0
- package/devnet/app/style.css +1606 -0
- package/devnet/app/utils.js +77 -0
- package/devnet/app/views/blocks.js +75 -0
- package/devnet/app/views/dashboard.js +127 -0
- package/devnet/app/views/entity.js +1473 -0
- package/devnet/app/views/messages.js +90 -0
- package/devnet/app/views/modules.js +165 -0
- package/devnet/app/views/processes.js +90 -0
- package/devnet/app/views/schedulers.js +90 -0
- package/devnet/app/views/transactions.js +88 -0
- package/devnet/migrations/0001_initial.sql +51 -0
- package/devnet/package.json +26 -0
- package/devnet/playwright.config.js +7 -0
- package/devnet/src/cu-worker.js +166 -0
- package/devnet/src/index.js +309 -0
- package/devnet/vite.config.js +17 -0
- package/devnet/vitest.config.js +10 -0
- package/devnet/wrangler-cu.toml +32 -0
- package/devnet/wrangler.toml +38 -0
- package/dhfs-tutorial-app/package.json +15 -0
- package/dist/esm/workspace/dashboard/public/favicon.png +0 -0
- package/dist/esm/workspace/src/counter.lua +14 -0
- package/dist/package.json +82 -0
- package/hb.sh +18 -0
- package/hbsig/.babelrc-cjs +5 -0
- package/hbsig/.babelrc-esm +5 -0
- package/hbsig/README.md +1 -0
- package/hbsig/dist/cjs/bin_to_str.js +44 -0
- package/hbsig/dist/cjs/collect-body-keys.js +470 -0
- package/hbsig/dist/cjs/commit.js +330 -0
- package/hbsig/dist/cjs/encode-array-item.js +110 -0
- package/hbsig/dist/cjs/encode-utils.js +242 -0
- package/hbsig/dist/cjs/encode.js +1365 -0
- package/hbsig/dist/cjs/erl_json.js +326 -0
- package/hbsig/dist/cjs/erl_str.js +1042 -0
- package/hbsig/dist/cjs/flat.js +279 -0
- package/hbsig/dist/cjs/http-message-signatures/httpbis.js +489 -0
- package/hbsig/dist/cjs/http-message-signatures/index.js +25 -0
- package/hbsig/dist/cjs/http-message-signatures/structured-header.js +129 -0
- package/hbsig/dist/cjs/httpsig.js +861 -0
- package/hbsig/dist/cjs/id.js +470 -0
- package/hbsig/dist/cjs/index.js +174 -0
- package/hbsig/dist/cjs/nocrypto.js +51 -0
- package/hbsig/dist/cjs/parser.js +201 -0
- package/hbsig/dist/cjs/send-utils.js +1231 -0
- package/hbsig/dist/cjs/send.js +211 -0
- package/hbsig/dist/cjs/signer-utils.js +494 -0
- package/hbsig/dist/cjs/signer.js +436 -0
- package/hbsig/dist/cjs/structured.js +515 -0
- package/hbsig/dist/cjs/test.js +12 -0
- package/hbsig/dist/cjs/utils.js +44 -0
- package/hbsig/dist/esm/bin_to_str.js +46 -0
- package/hbsig/dist/esm/collect-body-keys.js +436 -0
- package/hbsig/dist/esm/commit.js +219 -0
- package/hbsig/dist/esm/encode-array-item.js +112 -0
- package/hbsig/dist/esm/encode-utils.js +191 -0
- package/hbsig/dist/esm/encode.js +1256 -0
- package/hbsig/dist/esm/erl_json.js +292 -0
- package/hbsig/dist/esm/erl_str.js +1144 -0
- package/hbsig/dist/esm/flat.js +250 -0
- package/hbsig/dist/esm/http-message-signatures/httpbis.js +438 -0
- package/hbsig/dist/esm/http-message-signatures/index.js +4 -0
- package/hbsig/dist/esm/http-message-signatures/structured-header.js +105 -0
- package/hbsig/dist/esm/httpsig.js +866 -0
- package/hbsig/dist/esm/id.js +459 -0
- package/hbsig/dist/esm/index.js +13 -0
- package/hbsig/dist/esm/nocrypto.js +4 -0
- package/hbsig/dist/esm/package.json +3 -0
- package/hbsig/dist/esm/parser.js +171 -0
- package/hbsig/dist/esm/send-utils.js +1132 -0
- package/hbsig/dist/esm/send.js +142 -0
- package/hbsig/dist/esm/signer-utils.js +375 -0
- package/hbsig/dist/esm/signer.js +312 -0
- package/hbsig/dist/esm/structured.js +496 -0
- package/hbsig/dist/esm/test.js +2 -0
- package/hbsig/dist/esm/utils.js +29 -0
- package/hbsig/dist/package.json +39 -0
- package/hbsig/make.js +36 -0
- package/hbsig/package.json +39 -0
- package/hbsig/src/bin_to_str.js +46 -0
- package/hbsig/src/collect-body-keys.js +436 -0
- package/hbsig/src/commit.js +219 -0
- package/hbsig/src/encode-array-item.js +112 -0
- package/hbsig/src/encode-utils.js +191 -0
- package/hbsig/src/encode.js +1256 -0
- package/hbsig/src/erl_json.js +292 -0
- package/hbsig/src/erl_str.js +1144 -0
- package/hbsig/src/flat.js +250 -0
- package/hbsig/src/http-message-signatures/httpbis.js +438 -0
- package/hbsig/src/http-message-signatures/index.js +4 -0
- package/hbsig/src/http-message-signatures/structured-header.js +105 -0
- package/hbsig/src/httpsig.js +866 -0
- package/hbsig/src/id.js +459 -0
- package/hbsig/src/index.js +13 -0
- package/hbsig/src/nocrypto.js +4 -0
- package/hbsig/src/parser.js +171 -0
- package/hbsig/src/send-utils.js +1132 -0
- package/hbsig/src/send.js +142 -0
- package/hbsig/src/signer-utils.js +375 -0
- package/hbsig/src/signer.js +312 -0
- package/hbsig/src/structured.js +496 -0
- package/hbsig/src/test.js +2 -0
- package/hbsig/src/utils.js +29 -0
- package/lp/index.html +25 -0
- package/lp/package.json +19 -0
- package/lp/public/cover.png +0 -0
- package/lp/public/favicon.ico +0 -0
- package/lp/public/favicon.png +0 -0
- package/lp/public/images/book.jpg +0 -0
- package/lp/public/images/dashboard.png +0 -0
- package/lp/public/images/devnet.png +0 -0
- package/lp/public/images/hero-bg.png +0 -0
- package/lp/public/images/hyperadd.png +0 -0
- package/lp/public/images/message-flow.png +0 -0
- package/lp/public/images/mobile.png +0 -0
- package/lp/public/images/og-cover.png +0 -0
- package/lp/public/images/scan.png +0 -0
- package/lp/public/images/wao-hub.png +0 -0
- package/lp/public/images/wao-web.png +0 -0
- package/lp/public/logo.png +0 -0
- package/lp/src/App.jsx +29 -0
- package/lp/src/components/CodeBlock.jsx +37 -0
- package/lp/src/components/CodeBlock.module.css +89 -0
- package/lp/src/components/Footer.jsx +22 -0
- package/lp/src/components/Footer.module.css +60 -0
- package/lp/src/components/Nav.jsx +80 -0
- package/lp/src/components/Nav.module.css +177 -0
- package/lp/src/components/SectionWrapper.jsx +15 -0
- package/lp/src/hooks/useReveal.js +25 -0
- package/lp/src/hooks/useScrolled.js +14 -0
- package/lp/src/main.jsx +10 -0
- package/lp/src/sections/Book.jsx +60 -0
- package/lp/src/sections/Book.module.css +204 -0
- package/lp/src/sections/Browser.jsx +46 -0
- package/lp/src/sections/Browser.module.css +67 -0
- package/lp/src/sections/Devnet.jsx +55 -0
- package/lp/src/sections/Devnet.module.css +136 -0
- package/lp/src/sections/GetStarted.jsx +51 -0
- package/lp/src/sections/GetStarted.module.css +128 -0
- package/lp/src/sections/Hero.jsx +67 -0
- package/lp/src/sections/Hero.module.css +202 -0
- package/lp/src/sections/HyperADD.jsx +46 -0
- package/lp/src/sections/HyperADD.module.css +113 -0
- package/lp/src/sections/SDK.jsx +90 -0
- package/lp/src/sections/SDK.module.css +122 -0
- package/lp/src/sections/Testing.jsx +47 -0
- package/lp/src/sections/Testing.module.css +124 -0
- package/lp/src/sections/Vision.jsx +93 -0
- package/lp/src/sections/Vision.module.css +147 -0
- package/lp/src/styles/globals.css +285 -0
- package/lp/src/utils/scrollTo.js +4 -0
- package/lp/vite.config.js +7 -0
- package/make.js +39 -0
- package/package.json +17 -12
- package/patches/@permaweb+ao-loader+0.0.44.patch +64 -0
- package/plan.md +435 -0
- package/rebar.lock +1 -0
- package/src/accounts-web.js +128 -0
- package/src/accounts.js +124 -0
- package/src/adaptor-base.js +622 -0
- package/src/adaptor-cf.js +11 -0
- package/src/adaptor-web.js +11 -0
- package/src/adaptor.js +10 -0
- package/src/ao-loader.js +30660 -0
- package/src/ao.js +1173 -0
- package/src/aoconnect-base.js +1098 -0
- package/src/aoconnect-cf.js +9 -0
- package/src/aoconnect-web.js +8 -0
- package/src/aoconnect.js +8 -0
- package/src/aos_wamr.js +1 -0
- package/src/ar-remote.js +87 -0
- package/src/ar.js +276 -0
- package/src/armem-base.js +529 -0
- package/src/armem-cf.js +67 -0
- package/src/armem-web.js +19 -0
- package/src/armem.js +26 -0
- package/src/bao.js +141 -0
- package/src/bar.js +366 -0
- package/src/build.js +7 -0
- package/src/bundler.js +119 -0
- package/src/car.js +10 -0
- package/src/cf-env.js +29 -0
- package/src/cf.js +11 -0
- package/src/cli.js +561 -0
- package/src/compress.js +112 -0
- package/src/create.js +415 -0
- package/src/devs.js +86 -0
- package/src/dirname.js +1 -0
- package/src/dodb.js +26 -0
- package/src/erl_json.js +289 -0
- package/src/erl_str.js +1139 -0
- package/src/gql.js +229 -0
- package/src/hb.js +967 -0
- package/src/helpers.js +203 -0
- package/src/http.js +619 -0
- package/src/hub/bundler.js +123 -0
- package/src/hub/cu.js +74 -0
- package/src/hub/fs.js +157 -0
- package/src/hub/index.js +85 -0
- package/src/hub/utils.js +64 -0
- package/src/hub/ws-proxy.js +67 -0
- package/src/hyper-aos.js +1 -0
- package/src/hyperbeam-server.js +21 -0
- package/src/hyperbeam.js +585 -0
- package/src/index.js +5 -0
- package/src/keygen.js +47 -0
- package/src/lfdb.js +67 -0
- package/src/lua/aos.wasm +0 -0
- package/src/lua/aos2_0_1.js +1 -0
- package/src/lua/aos2_0_1.wasm +0 -0
- package/src/lua/aos2_0_3.js +1 -0
- package/src/lua/aos2_0_3.wasm +0 -0
- package/src/lua/aos2_0_4_32.js +1 -0
- package/src/lua/aos2_0_4_32.wasm +0 -0
- package/src/lua/aos2_0_6.wasm +0 -0
- package/src/lua/apm.lua +61 -0
- package/src/lua/llama.wasm +0 -0
- package/src/lua/process.wasm +0 -0
- package/src/lua/sqlite.js +1 -0
- package/src/lua/sqlite.wasm +0 -0
- package/src/lua/weavedb_mock.lua +44 -0
- package/src/lua/weavedrive.lua +53 -0
- package/src/run.js +25 -0
- package/src/server.js +173 -0
- package/src/storage-multi.js +183 -0
- package/src/tao.js +12 -0
- package/src/tar.js +10 -0
- package/src/test.js +42 -0
- package/src/tgql-d1.js +407 -0
- package/src/tgql.js +310 -0
- package/src/toerl.js +162 -0
- package/src/utils.js +777 -0
- package/src/wao.js +29 -0
- package/src/waosm/README.md +81 -0
- package/src/waosm/waosm.d.ts +40 -0
- package/src/waosm/waosm.js +240 -0
- package/src/waosm/waosm_bg.wasm +0 -0
- package/src/waosm/waosm_bg.wasm.d.ts +8 -0
- package/src/waosm-node/README.md +81 -0
- package/src/waosm-node/waosm.d.ts +8 -0
- package/src/waosm-node/waosm.js +4 -0
- package/src/waosm-node/waosm_bg.js +147 -0
- package/src/waosm-node/waosm_bg.wasm +0 -0
- package/src/waosm-node/waosm_bg.wasm.d.ts +8 -0
- package/src/waosm-node/waosm_bg.wasm.js +14 -0
- package/src/waosm-node.js +9 -0
- package/src/war.js +10 -0
- package/src/weavedrive.js +376 -0
- package/src/web.js +11 -0
- package/src/workspace/.mcp.json +8 -0
- package/src/workspace/CLAUDE.md +258 -0
- package/src/workspace/README.md +85 -0
- package/src/workspace/dashboard/index.html +163 -0
- package/src/workspace/dashboard/package.json +18 -0
- package/src/workspace/dashboard/public/favicon.ico +0 -0
- package/src/workspace/dashboard/public/favicon.png +0 -0
- package/src/workspace/dashboard/server.js +224 -0
- package/src/workspace/dashboard/src/App.jsx +2350 -0
- package/{cjs/workspace/frontend → src/workspace/dashboard}/vite.config.js +6 -0
- package/src/workspace/package.json +18 -0
- package/src/workspace/src/counter.lua +14 -0
- package/tsconfig.json +18 -0
- package/types/index.d.ts +329 -0
- package/waollama/.eslintrc.json +3 -0
- package/waollama/README.md +19 -0
- package/waollama/arweave.mjs +87 -0
- package/waollama/components/ui/avatar.jsx +49 -0
- package/waollama/components/ui/checkbox.jsx +17 -0
- package/waollama/components/ui/close-button.jsx +20 -0
- package/waollama/components/ui/color-mode.jsx +61 -0
- package/waollama/components/ui/dialog.jsx +54 -0
- package/waollama/components/ui/drawer.jsx +44 -0
- package/waollama/components/ui/field.jsx +22 -0
- package/waollama/components/ui/input-group.jsx +39 -0
- package/waollama/components/ui/popover.jsx +49 -0
- package/waollama/components/ui/provider.jsx +12 -0
- package/waollama/components/ui/radio.jsx +17 -0
- package/waollama/components/ui/slider.jsx +107 -0
- package/waollama/components/ui/tooltip.jsx +35 -0
- package/waollama/index.js +10 -0
- package/waollama/jsconfig.json +7 -0
- package/waollama/lib/ao-loader.js +30654 -0
- package/waollama/lib/client.js +1 -0
- package/waollama/lib/wasm.js +1 -0
- package/waollama/next.config.js +25 -0
- package/waollama/package.json +43 -0
- package/waollama/pages/404.js +9 -0
- package/waollama/pages/_app.js +9 -0
- package/waollama/pages/_document.js +14 -0
- package/waollama/pages/index.js +212 -0
- package/waollama/playwright.config.js +31 -0
- package/waollama/proxy.mjs +21 -0
- package/waollama/public/favicon.ico +0 -0
- package/waollama/public/human.png +0 -0
- package/waollama/public/llama.png +0 -0
- package/waosm/Cargo.toml +11 -0
- package/waosm/README.md +81 -0
- package/waosm/compress.js +112 -0
- package/waosm/make.js +33 -0
- package/waosm/package.json +10 -0
- package/waosm/src/lib.rs +180 -0
- package/waosm/test.js +16 -0
- package/cjs/workspace/.claude/agents/builder.md +0 -99
- package/cjs/workspace/.claude/agents/device-builder.md +0 -86
- package/cjs/workspace/.claude/agents/tester.md +0 -90
- package/cjs/workspace/.claude/mcp/dashboard/server.js +0 -128
- package/cjs/workspace/.claude/rules/deploy.md +0 -45
- package/cjs/workspace/.claude/rules/frontend.md +0 -69
- package/cjs/workspace/.claude/rules/hyperbeam.md +0 -104
- package/cjs/workspace/.claude/rules/lua.md +0 -108
- package/cjs/workspace/.claude/rules/testing.md +0 -257
- package/cjs/workspace/.claude/settings.json +0 -109
- package/cjs/workspace/.claude/skills/build/SKILL.md +0 -214
- package/cjs/workspace/.claude/skills/build-aos/SKILL.md +0 -129
- package/cjs/workspace/.claude/skills/build-device/SKILL.md +0 -192
- package/cjs/workspace/.claude/skills/build-frontend/SKILL.md +0 -134
- package/cjs/workspace/.claude/skills/build-module/SKILL.md +0 -281
- package/cjs/workspace/.claude/skills/create-aos/SKILL.md +0 -63
- package/cjs/workspace/.claude/skills/create-device/SKILL.md +0 -87
- package/cjs/workspace/.claude/skills/create-module/SKILL.md +0 -162
- package/cjs/workspace/.claude/skills/debug/SKILL.md +0 -57
- package/cjs/workspace/.claude/skills/deploy/SKILL.md +0 -85
- package/cjs/workspace/.claude/skills/dev/SKILL.md +0 -32
- package/cjs/workspace/.claude/skills/plan/SKILL.md +0 -176
- package/cjs/workspace/.claude/skills/readme/SKILL.md +0 -186
- package/cjs/workspace/.claude/skills/report/SKILL.md +0 -49
- package/cjs/workspace/.claude/skills/team/SKILL.md +0 -101
- package/cjs/workspace/.claude/skills/test/SKILL.md +0 -56
- package/cjs/workspace/.claude/skills/test-device/SKILL.md +0 -114
- package/cjs/workspace/.claude/skills/test-e2e/SKILL.md +0 -103
- package/cjs/workspace/.claude/skills/test-hb/SKILL.md +0 -76
- package/cjs/workspace/.claude/skills/validate/SKILL.md +0 -96
- package/cjs/workspace/.claude/skills/validate/scripts/check-lua.sh +0 -41
- package/cjs/workspace/docs/aos-lua.md +0 -428
- package/cjs/workspace/docs/debug.md +0 -230
- package/cjs/workspace/docs/hyperbeam-dev.md +0 -606
- package/cjs/workspace/docs/hyperbeam-devices.md +0 -618
- package/cjs/workspace/docs/wao-sdk.md +0 -807
- package/cjs/workspace/frontend/e2e/.gitkeep +0 -0
- package/cjs/workspace/frontend/index.html +0 -12
- package/cjs/workspace/frontend/package.json +0 -24
- package/cjs/workspace/frontend/playwright.config.js +0 -10
- package/cjs/workspace/frontend/src/App.jsx +0 -24
- package/cjs/workspace/frontend/test/.gitkeep +0 -0
- package/cjs/workspace/frontend/vitest.config.js +0 -10
- package/cjs/workspace/scripts/deploy.js +0 -140
- package/cjs/workspace/scripts/keygen.js +0 -52
- package/cjs/workspace/test/aos.test.js +0 -98
- package/cjs/workspace/test/hyperbeam.test.js +0 -80
- package/esm/compiler/native +0 -0
- package/esm/workspace/.claude/agents/builder.md +0 -99
- package/esm/workspace/.claude/agents/device-builder.md +0 -86
- package/esm/workspace/.claude/agents/tester.md +0 -90
- package/esm/workspace/.claude/mcp/dashboard/server.js +0 -128
- package/esm/workspace/.claude/rules/deploy.md +0 -45
- package/esm/workspace/.claude/rules/frontend.md +0 -69
- package/esm/workspace/.claude/rules/hyperbeam.md +0 -104
- package/esm/workspace/.claude/rules/lua.md +0 -108
- package/esm/workspace/.claude/rules/testing.md +0 -257
- package/esm/workspace/.claude/settings.json +0 -109
- package/esm/workspace/.claude/skills/build/SKILL.md +0 -214
- package/esm/workspace/.claude/skills/build-aos/SKILL.md +0 -129
- package/esm/workspace/.claude/skills/build-device/SKILL.md +0 -192
- package/esm/workspace/.claude/skills/build-frontend/SKILL.md +0 -134
- package/esm/workspace/.claude/skills/build-module/SKILL.md +0 -281
- package/esm/workspace/.claude/skills/create-aos/SKILL.md +0 -63
- package/esm/workspace/.claude/skills/create-device/SKILL.md +0 -87
- package/esm/workspace/.claude/skills/create-module/SKILL.md +0 -162
- package/esm/workspace/.claude/skills/debug/SKILL.md +0 -57
- package/esm/workspace/.claude/skills/deploy/SKILL.md +0 -85
- package/esm/workspace/.claude/skills/dev/SKILL.md +0 -32
- package/esm/workspace/.claude/skills/plan/SKILL.md +0 -176
- package/esm/workspace/.claude/skills/readme/SKILL.md +0 -186
- package/esm/workspace/.claude/skills/report/SKILL.md +0 -49
- package/esm/workspace/.claude/skills/team/SKILL.md +0 -101
- package/esm/workspace/.claude/skills/test/SKILL.md +0 -56
- package/esm/workspace/.claude/skills/test-device/SKILL.md +0 -114
- package/esm/workspace/.claude/skills/test-e2e/SKILL.md +0 -103
- package/esm/workspace/.claude/skills/test-hb/SKILL.md +0 -76
- package/esm/workspace/.claude/skills/validate/SKILL.md +0 -96
- package/esm/workspace/.claude/skills/validate/scripts/check-lua.sh +0 -41
- package/esm/workspace/docs/aos-lua.md +0 -428
- package/esm/workspace/docs/debug.md +0 -230
- package/esm/workspace/docs/hyperbeam-dev.md +0 -606
- package/esm/workspace/docs/hyperbeam-devices.md +0 -618
- package/esm/workspace/docs/wao-sdk.md +0 -807
- package/esm/workspace/frontend/e2e/.gitkeep +0 -0
- package/esm/workspace/frontend/index.html +0 -12
- package/esm/workspace/frontend/package.json +0 -24
- package/esm/workspace/frontend/playwright.config.js +0 -10
- package/esm/workspace/frontend/src/App.jsx +0 -24
- package/esm/workspace/frontend/src/main.jsx +0 -9
- package/esm/workspace/frontend/test/.gitkeep +0 -0
- package/esm/workspace/frontend/vite.config.js +0 -6
- package/esm/workspace/frontend/vitest.config.js +0 -10
- package/esm/workspace/scripts/deploy.js +0 -140
- package/esm/workspace/scripts/keygen.js +0 -52
- package/esm/workspace/test/aos.test.js +0 -98
- package/esm/workspace/test/hyperbeam.test.js +0 -80
- /package/{cjs/workspace/dashboard/public → devnet/app}/favicon.ico +0 -0
- /package/{cjs/workspace → dhfs-tutorial-app}/src/counter.lua +0 -0
- /package/{cjs → dist/cjs}/accounts-web.js +0 -0
- /package/{cjs → dist/cjs}/accounts.js +0 -0
- /package/{cjs → dist/cjs}/adaptor-base.js +0 -0
- /package/{cjs → dist/cjs}/adaptor-cf.js +0 -0
- /package/{cjs → dist/cjs}/adaptor-web.js +0 -0
- /package/{cjs → dist/cjs}/adaptor.js +0 -0
- /package/{cjs → dist/cjs}/ao-loader.js +0 -0
- /package/{cjs → dist/cjs}/ao.js +0 -0
- /package/{cjs → dist/cjs}/aoconnect-base.js +0 -0
- /package/{cjs → dist/cjs}/aoconnect-cf.js +0 -0
- /package/{cjs → dist/cjs}/aoconnect-web.js +0 -0
- /package/{cjs → dist/cjs}/aoconnect.js +0 -0
- /package/{cjs → dist/cjs}/aos_wamr.js +0 -0
- /package/{cjs → dist/cjs}/ar-remote.js +0 -0
- /package/{cjs → dist/cjs}/ar.js +0 -0
- /package/{cjs → dist/cjs}/armem-base.js +0 -0
- /package/{cjs → dist/cjs}/armem-cf.js +0 -0
- /package/{cjs → dist/cjs}/armem-web.js +0 -0
- /package/{cjs → dist/cjs}/armem.js +0 -0
- /package/{cjs → dist/cjs}/bao.js +0 -0
- /package/{cjs → dist/cjs}/bar.js +0 -0
- /package/{cjs → dist/cjs}/build.js +0 -0
- /package/{cjs → dist/cjs}/bundler.js +0 -0
- /package/{cjs → dist/cjs}/car.js +0 -0
- /package/{cjs → dist/cjs}/cf-env.js +0 -0
- /package/{cjs → dist/cjs}/cf.js +0 -0
- /package/{cjs → dist/cjs}/cli.js +0 -0
- /package/{cjs → dist/cjs}/compress.js +0 -0
- /package/{cjs → dist/cjs}/create.js +0 -0
- /package/{cjs → dist/cjs}/devs.js +0 -0
- /package/{cjs → dist/cjs}/dirname.js +0 -0
- /package/{cjs → dist/cjs}/dodb.js +0 -0
- /package/{cjs → dist/cjs}/erl_json.js +0 -0
- /package/{cjs → dist/cjs}/erl_str.js +0 -0
- /package/{cjs → dist/cjs}/gql.js +0 -0
- /package/{cjs → dist/cjs}/hb.js +0 -0
- /package/{cjs → dist/cjs}/helpers.js +0 -0
- /package/{cjs → dist/cjs}/http.js +0 -0
- /package/{cjs → dist/cjs}/hub/bundler.js +0 -0
- /package/{cjs → dist/cjs}/hub/cu.js +0 -0
- /package/{cjs → dist/cjs}/hub/fs.js +0 -0
- /package/{cjs → dist/cjs}/hub/index.js +0 -0
- /package/{cjs → dist/cjs}/hub/utils.js +0 -0
- /package/{cjs → dist/cjs}/hub/ws-proxy.js +0 -0
- /package/{cjs → dist/cjs}/hyper-aos.js +0 -0
- /package/{cjs → dist/cjs}/hyperbeam-server.js +0 -0
- /package/{cjs → dist/cjs}/hyperbeam.js +0 -0
- /package/{cjs → dist/cjs}/index.js +0 -0
- /package/{cjs → dist/cjs}/keygen.js +0 -0
- /package/{cjs → dist/cjs}/lfdb.js +0 -0
- /package/{cjs → dist/cjs}/lua/aos.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_1.js +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_1.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_3.js +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_3.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_4_32.js +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_4_32.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_6.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/apm.lua +0 -0
- /package/{cjs → dist/cjs}/lua/llama.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/process.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/sqlite.js +0 -0
- /package/{cjs → dist/cjs}/lua/sqlite.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/weavedb_mock.lua +0 -0
- /package/{cjs → dist/cjs}/lua/weavedrive.lua +0 -0
- /package/{cjs → dist/cjs}/run.js +0 -0
- /package/{cjs → dist/cjs}/server.js +0 -0
- /package/{cjs → dist/cjs}/storage-multi.js +0 -0
- /package/{cjs → dist/cjs}/tao.js +0 -0
- /package/{cjs → dist/cjs}/tar.js +0 -0
- /package/{cjs → dist/cjs}/test.js +0 -0
- /package/{cjs → dist/cjs}/tgql-d1.js +0 -0
- /package/{cjs → dist/cjs}/tgql.js +0 -0
- /package/{cjs → dist/cjs}/toerl.js +0 -0
- /package/{cjs → dist/cjs}/utils.js +0 -0
- /package/{cjs → dist/cjs}/wao.js +0 -0
- /package/{cjs → dist/cjs}/waosm/waosm.js +0 -0
- /package/{cjs → dist/cjs}/waosm-node/waosm.js +0 -0
- /package/{cjs → dist/cjs}/waosm-node/waosm_bg.js +0 -0
- /package/{cjs → dist/cjs}/waosm-node/waosm_bg.wasm +0 -0
- /package/{cjs → dist/cjs}/waosm-node/waosm_bg.wasm.js +0 -0
- /package/{cjs → dist/cjs}/waosm-node.js +0 -0
- /package/{cjs → dist/cjs}/war.js +0 -0
- /package/{cjs → dist/cjs}/weavedrive.js +0 -0
- /package/{cjs → dist/cjs}/web.js +0 -0
- /package/{cjs → dist/cjs}/workspace/.mcp.json +0 -0
- /package/{cjs → dist/cjs}/workspace/CLAUDE.md +0 -0
- /package/{cjs → dist/cjs}/workspace/README.md +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/index.html +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/package.json +0 -0
- /package/{esm → dist/cjs}/workspace/dashboard/public/favicon.ico +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/public/favicon.png +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/server.js +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/src/App.jsx +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/src/main.jsx +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/vite.config.js +0 -0
- /package/{cjs → dist/cjs}/workspace/package.json +0 -0
- /package/{esm → dist/cjs}/workspace/src/counter.lua +0 -0
- /package/{esm → dist/esm}/accounts-web.js +0 -0
- /package/{esm → dist/esm}/accounts.js +0 -0
- /package/{esm → dist/esm}/adaptor-base.js +0 -0
- /package/{esm → dist/esm}/adaptor-cf.js +0 -0
- /package/{esm → dist/esm}/adaptor-web.js +0 -0
- /package/{esm → dist/esm}/adaptor.js +0 -0
- /package/{esm → dist/esm}/ao-loader.js +0 -0
- /package/{esm → dist/esm}/ao.js +0 -0
- /package/{esm → dist/esm}/aoconnect-base.js +0 -0
- /package/{esm → dist/esm}/aoconnect-cf.js +0 -0
- /package/{esm → dist/esm}/aoconnect-web.js +0 -0
- /package/{esm → dist/esm}/aoconnect.js +0 -0
- /package/{esm → dist/esm}/aos_wamr.js +0 -0
- /package/{esm → dist/esm}/ar-remote.js +0 -0
- /package/{esm → dist/esm}/ar.js +0 -0
- /package/{esm → dist/esm}/armem-base.js +0 -0
- /package/{esm → dist/esm}/armem-cf.js +0 -0
- /package/{esm → dist/esm}/armem-web.js +0 -0
- /package/{esm → dist/esm}/armem.js +0 -0
- /package/{esm → dist/esm}/bao.js +0 -0
- /package/{esm → dist/esm}/bar.js +0 -0
- /package/{esm → dist/esm}/build.js +0 -0
- /package/{esm → dist/esm}/bundler.js +0 -0
- /package/{esm → dist/esm}/car.js +0 -0
- /package/{esm → dist/esm}/cf-env.js +0 -0
- /package/{esm → dist/esm}/cf.js +0 -0
- /package/{esm → dist/esm}/cli.js +0 -0
- /package/{esm → dist/esm}/compress.js +0 -0
- /package/{esm → dist/esm}/create.js +0 -0
- /package/{esm → dist/esm}/devs.js +0 -0
- /package/{esm → dist/esm}/dirname.js +0 -0
- /package/{esm → dist/esm}/dodb.js +0 -0
- /package/{esm → dist/esm}/erl_json.js +0 -0
- /package/{esm → dist/esm}/erl_str.js +0 -0
- /package/{esm → dist/esm}/gql.js +0 -0
- /package/{esm → dist/esm}/hb.js +0 -0
- /package/{esm → dist/esm}/helpers.js +0 -0
- /package/{esm → dist/esm}/http.js +0 -0
- /package/{esm → dist/esm}/hub/bundler.js +0 -0
- /package/{esm → dist/esm}/hub/cu.js +0 -0
- /package/{esm → dist/esm}/hub/fs.js +0 -0
- /package/{esm → dist/esm}/hub/index.js +0 -0
- /package/{esm → dist/esm}/hub/utils.js +0 -0
- /package/{esm → dist/esm}/hub/ws-proxy.js +0 -0
- /package/{esm → dist/esm}/hyper-aos.js +0 -0
- /package/{esm → dist/esm}/hyperbeam-server.js +0 -0
- /package/{esm → dist/esm}/hyperbeam.js +0 -0
- /package/{esm → dist/esm}/index.js +0 -0
- /package/{esm → dist/esm}/keygen.js +0 -0
- /package/{esm → dist/esm}/lfdb.js +0 -0
- /package/{esm → dist/esm}/lua/aos.wasm +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_1.js +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_1.wasm +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_3.js +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_3.wasm +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_4_32.js +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_4_32.wasm +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_6.wasm +0 -0
- /package/{esm → dist/esm}/lua/apm.lua +0 -0
- /package/{esm → dist/esm}/lua/llama.wasm +0 -0
- /package/{esm → dist/esm}/lua/process.wasm +0 -0
- /package/{esm → dist/esm}/lua/sqlite.js +0 -0
- /package/{esm → dist/esm}/lua/sqlite.wasm +0 -0
- /package/{esm → dist/esm}/lua/weavedb_mock.lua +0 -0
- /package/{esm → dist/esm}/lua/weavedrive.lua +0 -0
- /package/{esm → dist/esm}/package.json +0 -0
- /package/{esm → dist/esm}/run.js +0 -0
- /package/{esm → dist/esm}/server.js +0 -0
- /package/{esm → dist/esm}/storage-multi.js +0 -0
- /package/{esm → dist/esm}/tao.js +0 -0
- /package/{esm → dist/esm}/tar.js +0 -0
- /package/{esm → dist/esm}/test.js +0 -0
- /package/{esm → dist/esm}/tgql-d1.js +0 -0
- /package/{esm → dist/esm}/tgql.js +0 -0
- /package/{esm → dist/esm}/toerl.js +0 -0
- /package/{esm → dist/esm}/utils.js +0 -0
- /package/{esm → dist/esm}/wao.js +0 -0
- /package/{esm → dist/esm}/waosm/README.md +0 -0
- /package/{esm → dist/esm}/waosm/waosm.d.ts +0 -0
- /package/{esm → dist/esm}/waosm/waosm.js +0 -0
- /package/{esm → dist/esm}/waosm/waosm_bg.wasm +0 -0
- /package/{esm → dist/esm}/waosm/waosm_bg.wasm.d.ts +0 -0
- /package/{esm → dist/esm}/waosm-node/README.md +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm.d.ts +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm.js +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm_bg.js +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm_bg.wasm +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm_bg.wasm.d.ts +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm_bg.wasm.js +0 -0
- /package/{esm → dist/esm}/waosm-node.js +0 -0
- /package/{esm → dist/esm}/war.js +0 -0
- /package/{esm → dist/esm}/weavedrive.js +0 -0
- /package/{esm → dist/esm}/web.js +0 -0
- /package/{esm → dist/esm}/workspace/.mcp.json +0 -0
- /package/{esm → dist/esm}/workspace/CLAUDE.md +0 -0
- /package/{esm → dist/esm}/workspace/README.md +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/index.html +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/package.json +0 -0
- /package/{esm/workspace/dashboard/public/favicon.png → dist/esm/workspace/dashboard/public/favicon.ico} +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/server.js +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/src/App.jsx +0 -0
- /package/{cjs/workspace/frontend → dist/esm/workspace/dashboard}/src/main.jsx +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/vite.config.js +0 -0
- /package/{esm → dist/esm}/workspace/package.json +0 -0
- /package/{postinstall.cjs → dist/postinstall.cjs} +0 -0
- /package/{esm → src}/workspace/dashboard/src/main.jsx +0 -0
package/src/hyper-aos.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default "CmxvY2FsIGZ1bmN0aW9uIGxvYWRfanNvbigpIAogIGxvY2FsIGpzb24gPSB7X3ZlcnNpb24gPSAiMC4yLjAifQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotLSBFbmNvZGUKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKbG9jYWwgZW5jb2RlCgpsb2NhbCBlc2NhcGVfY2hhcl9tYXAgPSB7CiAgICBbIlxcIl0gPSAiXFwiLAogICAgWyJcIiJdID0gIlwiIiwKICAgIFsiXGIiXSA9ICJiIiwKICAgIFsiXGYiXSA9ICJmIiwKICAgIFsiXG4iXSA9ICJuIiwKICAgIFsiXHIiXSA9ICJyIiwKICAgIFsiXHQiXSA9ICJ0Igp9Cgpsb2NhbCBlc2NhcGVfY2hhcl9tYXBfaW52ID0ge1siLyJdID0gIi8ifQpmb3IgaywgdiBpbiBwYWlycyhlc2NhcGVfY2hhcl9tYXApIGRvIGVzY2FwZV9jaGFyX21hcF9pbnZbdl0gPSBrIGVuZAoKbG9jYWwgZnVuY3Rpb24gZXNjYXBlX2NoYXIoYykKICAgIHJldHVybiAiXFwiIC4uIChlc2NhcGVfY2hhcl9tYXBbY10gb3Igc3RyaW5nLmZvcm1hdCgidSUwNHgiLCBjOmJ5dGUoKSkpCmVuZAoKbG9jYWwgZnVuY3Rpb24gZW5jb2RlX25pbCh2YWwpIHJldHVybiAibnVsbCIgZW5kCgpsb2NhbCBmdW5jdGlvbiBlbmNvZGVfdGFibGUodmFsLCBzdGFjaykKICAgIGxvY2FsIHJlcyA9IHt9CiAgICBzdGFjayA9IHN0YWNrIG9yIHt9CgogICAgLS0gQ2lyY3VsYXIgcmVmZXJlbmNlPwogICAgaWYgc3RhY2tbdmFsXSB0aGVuIGVycm9yKCJjaXJjdWxhciByZWZlcmVuY2UiKSBlbmQKCiAgICBzdGFja1t2YWxdID0gdHJ1ZQoKICAgIGlmIHJhd2dldCh2YWwsIDEpIH49IG5pbCBvciBuZXh0KHZhbCkgPT0gbmlsIHRoZW4KICAgICAgICAtLSBUcmVhdCBhcyBhcnJheSAtLSBjaGVjayBrZXlzIGFyZSB2YWxpZCBhbmQgaXQgaXMgbm90IHNwYXJzZQogICAgICAgIGxvY2FsIG4gPSAwCiAgICAgICAgZm9yIGsgaW4gcGFpcnModmFsKSBkbwogICAgICAgICAgICBpZiB0eXBlKGspIH49ICJudW1iZXIiIHRoZW4KICAgICAgICAgICAgICAgIGVycm9yKCJpbnZhbGlkIHRhYmxlOiBtaXhlZCBvciBpbnZhbGlkIGtleSB0eXBlcyIpCiAgICAgICAgICAgIGVuZAogICAgICAgICAgICBuID0gbiArIDEKICAgICAgICBlbmQKICAgICAgICBpZiBuIH49ICN2YWwgdGhlbiBlcnJvcigiaW52YWxpZCB0YWJsZTogc3BhcnNlIGFycmF5IikgZW5kCiAgICAgICAgLS0gRW5jb2RlCiAgICAgICAgZm9yIGkgPSAxLCAjdmFsIGRvIHJlc1tpXSA9IGVuY29kZSh2YWxbaV0sIHN0YWNrKSBlbmQKICAgICAgICBzdGFja1t2YWxdID0gbmlsCiAgICAgICAgcmV0dXJuICJbIiAuLiB0YWJsZS5jb25jYXQocmVzLCAiLCIpIC4uICJdIgogICAgZWxzZQogICAgICAgIC0tIFRyZWF0IGFzIGFuIG9iamVjdAogICAgICAgIGxvY2FsIGkgPSAxCiAgICAgICAgZm9yIGssIHYgaW4gcGFpcnModmFsKSBkbwogICAgICAgICAgICBpZiB0eXBlKGspIH49ICJzdHJpbmciIHRoZW4KICAgICAgICAgICAgICAgIGVycm9yKCJpbnZhbGlkIHRhYmxlOiBtaXhlZCBvciBpbnZhbGlkIGtleSB0eXBlcyIpCiAgICAgICAgICAgIGVuZAogICAgICAgICAgICBpZiB0eXBlKHYpIH49ICJmdW5jdGlvbiIgdGhlbgogICAgICAgICAgICAgICAgcmVzW2ldID0gZW5jb2RlKGssIHN0YWNrKSAuLiAiOiIgLi4gZW5jb2RlKHYsIHN0YWNrKQogICAgICAgICAgICAgICAgaSA9IGkgKyAxCiAgICAgICAgICAgIGVuZAogICAgICAgIGVuZAogICAgICAgIHN0YWNrW3ZhbF0gPSBuaWwKICAgICAgICByZXR1cm4gInsiIC4uIHRhYmxlLmNvbmNhdChyZXMsICIsIikgLi4gIn0iCiAgICBlbmQKZW5kCgpsb2NhbCBmdW5jdGlvbiBlbmNvZGVfc3RyaW5nKHZhbCkKICAgIHJldHVybiAnIicgLi4gdmFsOmdzdWIoJ1slelwxLVwzMVxcIl0nLCBlc2NhcGVfY2hhcikgLi4gJyInCmVuZAoKbG9jYWwgZnVuY3Rpb24gZW5jb2RlX251bWJlcih2YWwpCiAgICAtLSBDaGVjayBmb3IgTmFOLCAtaW5mIGFuZCBpbmYKICAgIGlmIHZhbCB+PSB2YWwgb3IgdmFsIDw9IC1tYXRoLmh1Z2Ugb3IgdmFsID49IG1hdGguaHVnZSB0aGVuCiAgICAgICAgZXJyb3IoInVuZXhwZWN0ZWQgbnVtYmVyIHZhbHVlICciIC4uIHRvc3RyaW5nKHZhbCkgLi4gIiciKQogICAgZW5kCiAgICByZXR1cm4gc3RyaW5nLmZvcm1hdCgiJS4xNGciLCB2YWwpCmVuZAoKbG9jYWwgdHlwZV9mdW5jX21hcCA9IHsKICAgIFsibmlsIl0gPSBlbmNvZGVfbmlsLAogICAgWyJ0YWJsZSJdID0gZW5jb2RlX3RhYmxlLAogICAgWyJzdHJpbmciXSA9IGVuY29kZV9zdHJpbmcsCiAgICBbIm51bWJlciJdID0gZW5jb2RlX251bWJlciwKICAgIFsiYm9vbGVhbiJdID0gdG9zdHJpbmcKfQoKZW5jb2RlID0gZnVuY3Rpb24odmFsLCBzdGFjaykKICAgIGxvY2FsIHQgPSB0eXBlKHZhbCkKICAgIGxvY2FsIGYgPSB0eXBlX2Z1bmNfbWFwW3RdCiAgICBpZiBmIHRoZW4gcmV0dXJuIGYodmFsLCBzdGFjaykgZW5kCiAgICBlcnJvcigidW5leHBlY3RlZCB0eXBlICciIC4uIHQgLi4gIiciKQplbmQKCmZ1bmN0aW9uIGpzb24uZW5jb2RlKHZhbCkgcmV0dXJuIChlbmNvZGUodmFsKSkgZW5kCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0tIERlY29kZQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpsb2NhbCBwYXJzZQoKbG9jYWwgZnVuY3Rpb24gY3JlYXRlX3NldCguLi4pCiAgICBsb2NhbCByZXMgPSB7fQogICAgZm9yIGkgPSAxLCBzZWxlY3QoIiMiLCAuLi4pIGRvIHJlc1tzZWxlY3QoaSwgLi4uKV0gPSB0cnVlIGVuZAogICAgcmV0dXJuIHJlcwplbmQKCmxvY2FsIHNwYWNlX2NoYXJzID0gY3JlYXRlX3NldCgiICIsICJcdCIsICJcciIsICJcbiIpCmxvY2FsIGRlbGltX2NoYXJzID0gY3JlYXRlX3NldCgiICIsICJcdCIsICJcciIsICJcbiIsICJdIiwgIn0iLCAiLCIpCmxvY2FsIGVzY2FwZV9jaGFycyA9IGNyZWF0ZV9zZXQoIlxcIiwgIi8iLCAnIicsICJiIiwgImYiLCAibiIsICJyIiwgInQiLCAidSIpCmxvY2FsIGxpdGVyYWxzID0gY3JlYXRlX3NldCgidHJ1ZSIsICJmYWxzZSIsICJudWxsIikKCmxvY2FsIGxpdGVyYWxfbWFwID0ge1sidHJ1ZSJdID0gdHJ1ZSwgWyJmYWxzZSJdID0gZmFsc2UsIFsibnVsbCJdID0gbmlsfQoKbG9jYWwgZnVuY3Rpb24gbmV4dF9jaGFyKHN0ciwgaWR4LCBzZXQsIG5lZ2F0ZSkKICAgIGZvciBpID0gaWR4LCAjc3RyIGRvIGlmIHNldFtzdHI6c3ViKGksIGkpXSB+PSBuZWdhdGUgdGhlbiByZXR1cm4gaSBlbmQgZW5kCiAgICByZXR1cm4gI3N0ciArIDEKZW5kCgpsb2NhbCBmdW5jdGlvbiBkZWNvZGVfZXJyb3Ioc3RyLCBpZHgsIG1zZykKICAgIGxvY2FsIGxpbmVfY291bnQgPSAxCiAgICBsb2NhbCBjb2xfY291bnQgPSAxCiAgICBmb3IgaSA9IDEsIGlkeCAtIDEgZG8KICAgICAgICBjb2xfY291bnQgPSBjb2xfY291bnQgKyAxCiAgICAgICAgaWYgc3RyOnN1YihpLCBpKSA9PSAiXG4iIHRoZW4KICAgICAgICAgICAgbGluZV9jb3VudCA9IGxpbmVfY291bnQgKyAxCiAgICAgICAgICAgIGNvbF9jb3VudCA9IDEKICAgICAgICBlbmQKICAgIGVuZAogICAgZXJyb3Ioc3RyaW5nLmZvcm1hdCgiJXMgYXQgbGluZSAlZCBjb2wgJWQiLCBtc2csIGxpbmVfY291bnQsIGNvbF9jb3VudCkpCmVuZAoKbG9jYWwgZnVuY3Rpb24gY29kZXBvaW50X3RvX3V0ZjgobikKICAgIGxvY2FsIGYgPSBtYXRoLmZsb29yCiAgICBpZiBuIDw9IDB4N2YgdGhlbgogICAgICAgIHJldHVybiBzdHJpbmcuY2hhcihuKQogICAgZWxzZWlmIG4gPD0gMHg3ZmYgdGhlbgogICAgICAgIHJldHVybiBzdHJpbmcuY2hhcihmKG4gLyA2NCkgKyAxOTIsIG4gJSA2NCArIDEyOCkKICAgIGVsc2VpZiBuIDw9IDB4ZmZmZiB0aGVuCiAgICAgICAgcmV0dXJuIHN0cmluZy5jaGFyKGYobiAvIDQwOTYpICsgMjI0LCBmKG4gJSA0MDk2IC8gNjQpICsgMTI4LAogICAgICAgICAgICAgICAgICAgICAgICAgICBuICUgNjQgKyAxMjgpCiAgICBlbHNlaWYgbiA8PSAweDEwZmZmZiB0aGVuCiAgICAgICAgcmV0dXJuIHN0cmluZy5jaGFyKGYobiAvIDI2MjE0NCkgKyAyNDAsIGYobiAlIDI2MjE0NCAvIDQwOTYpICsgMTI4LAogICAgICAgICAgICAgICAgICAgICAgICAgICBmKG4gJSA0MDk2IC8gNjQpICsgMTI4LCBuICUgNjQgKyAxMjgpCiAgICBlbmQKICAgIGVycm9yKHN0cmluZy5mb3JtYXQoImludmFsaWQgdW5pY29kZSBjb2RlcG9pbnQgJyV4JyIsIG4pKQplbmQKCmxvY2FsIGZ1bmN0aW9uIHBhcnNlX3VuaWNvZGVfZXNjYXBlKHMpCiAgICBsb2NhbCBuMSA9IHRvbnVtYmVyKHM6c3ViKDEsIDQpLCAxNikKICAgIGxvY2FsIG4yID0gdG9udW1iZXIoczpzdWIoNywgMTApLCAxNikKICAgIGlmIG4yIHRoZW4KICAgICAgICByZXR1cm4KICAgICAgICAgICAgY29kZXBvaW50X3RvX3V0ZjgoKG4xIC0gMHhkODAwKSAqIDB4NDAwICsgKG4yIC0gMHhkYzAwKSArIDB4MTAwMDApCiAgICBlbHNlCiAgICAgICAgcmV0dXJuIGNvZGVwb2ludF90b191dGY4KG4xKQogICAgZW5kCmVuZAoKbG9jYWwgZnVuY3Rpb24gcGFyc2Vfc3RyaW5nKHN0ciwgaSkKICAgIGxvY2FsIHJlcyA9IHt9CiAgICBsb2NhbCBqID0gaSArIDEKICAgIGxvY2FsIGsgPSBqCgogICAgd2hpbGUgaiA8PSAjc3RyIGRvCiAgICAgICAgbG9jYWwgeCA9IHN0cjpieXRlKGopCgogICAgICAgIGlmIHggPCAzMiB0aGVuCiAgICAgICAgICAgIGRlY29kZV9lcnJvcihzdHIsIGosICJjb250cm9sIGNoYXJhY3RlciBpbiBzdHJpbmciKQogICAgICAgIGVsc2VpZiB4ID09IDkyIHRoZW4gLS0gYFxgOiBFc2NhcGUKICAgICAgICAgICAgcmVzWyNyZXMgKyAxXSA9IHN0cjpzdWIoaywgaiAtIDEpCiAgICAgICAgICAgIGogPSBqICsgMQogICAgICAgICAgICBsb2NhbCBjID0gc3RyOnN1YihqLCBqKQogICAgICAgICAgICBpZiBjID09ICJ1IiB0aGVuCiAgICAgICAgICAgICAgICBsb2NhbCBoZXggPSBzdHI6bWF0Y2goIl5bZERdWzg5YUFiQl0leCV4XFx1JXgleCV4JXgiLCBqICsgMSkgb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHI6bWF0Y2goIl4leCV4JXgleCIsIGogKyAxKSBvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY29kZV9lcnJvcihzdHIsIGogLSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCB1bmljb2RlIGVzY2FwZSBpbiBzdHJpbmciKQogICAgICAgICAgICAgICAgcmVzWyNyZXMgKyAxXSA9IHBhcnNlX3VuaWNvZGVfZXNjYXBlKGhleCkKICAgICAgICAgICAgICAgIGogPSBqICsgI2hleAogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBpZiBub3QgZXNjYXBlX2NoYXJzW2NdIHRoZW4KICAgICAgICAgICAgICAgICAgICBkZWNvZGVfZXJyb3Ioc3RyLCBqIC0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgZXNjYXBlIGNoYXIgJyIgLi4gYyAuLiAiJyBpbiBzdHJpbmciKQogICAgICAgICAgICAgICAgZW5kCiAgICAgICAgICAgICAgICByZXNbI3JlcyArIDFdID0gZXNjYXBlX2NoYXJfbWFwX2ludltjXQogICAgICAgICAgICBlbmQKICAgICAgICAgICAgayA9IGogKyAxCiAgICAgICAgZWxzZWlmIHggPT0gMzQgdGhlbiAtLSBgImA6IEVuZCBvZiBzdHJpbmcKICAgICAgICAgICAgcmVzWyNyZXMgKyAxXSA9IHN0cjpzdWIoaywgaiAtIDEpCiAgICAgICAgICAgIHJldHVybiB0YWJsZS5jb25jYXQocmVzKSwgaiArIDEKICAgICAgICBlbmQKICAgICAgICBqID0gaiArIDEKICAgIGVuZAoKICAgIGRlY29kZV9lcnJvcihzdHIsIGksICJleHBlY3RlZCBjbG9zaW5nIHF1b3RlIGZvciBzdHJpbmciKQplbmQKCmxvY2FsIGZ1bmN0aW9uIHBhcnNlX251bWJlcihzdHIsIGkpCiAgICBsb2NhbCB4ID0gbmV4dF9jaGFyKHN0ciwgaSwgZGVsaW1fY2hhcnMpCiAgICBsb2NhbCBzID0gc3RyOnN1YihpLCB4IC0gMSkKICAgIGxvY2FsIG4gPSB0b251bWJlcihzKQogICAgaWYgbm90IG4gdGhlbiBkZWNvZGVfZXJyb3Ioc3RyLCBpLCAiaW52YWxpZCBudW1iZXIgJyIgLi4gcyAuLiAiJyIpIGVuZAogICAgcmV0dXJuIG4sIHgKZW5kCgpsb2NhbCBmdW5jdGlvbiBwYXJzZV9saXRlcmFsKHN0ciwgaSkKICAgIGxvY2FsIHggPSBuZXh0X2NoYXIoc3RyLCBpLCBkZWxpbV9jaGFycykKICAgIGxvY2FsIHdvcmQgPSBzdHI6c3ViKGksIHggLSAxKQogICAgaWYgbm90IGxpdGVyYWxzW3dvcmRdIHRoZW4KICAgICAgICBkZWNvZGVfZXJyb3Ioc3RyLCBpLCAiaW52YWxpZCBsaXRlcmFsICciIC4uIHdvcmQgLi4gIiciKQogICAgZW5kCiAgICByZXR1cm4gbGl0ZXJhbF9tYXBbd29yZF0sIHgKZW5kCgpsb2NhbCBmdW5jdGlvbiBwYXJzZV9hcnJheShzdHIsIGkpCiAgICBsb2NhbCByZXMgPSB7fQogICAgbG9jYWwgbiA9IDEKICAgIGkgPSBpICsgMQogICAgd2hpbGUgdHJ1ZSBkbwogICAgICAgIGxvY2FsIHgKICAgICAgICBpID0gbmV4dF9jaGFyKHN0ciwgaSwgc3BhY2VfY2hhcnMsIHRydWUpCiAgICAgICAgaWYgc3RyOnN1YihpLCBpKSA9PSAiXSIgdGhlbgogICAgICAgICAgICBpID0gaSArIDEKICAgICAgICAgICAgYnJlYWsKICAgICAgICBlbmQKICAgICAgICB4LCBpID0gcGFyc2Uoc3RyLCBpKQogICAgICAgIHJlc1tuXSA9IHgKICAgICAgICBuID0gbiArIDEKICAgICAgICBpID0gbmV4dF9jaGFyKHN0ciwgaSwgc3BhY2VfY2hhcnMsIHRydWUpCiAgICAgICAgbG9jYWwgY2hyID0gc3RyOnN1YihpLCBpKQogICAgICAgIGkgPSBpICsgMQogICAgICAgIGlmIGNociA9PSAiXSIgdGhlbiBicmVhayBlbmQKICAgICAgICBpZiBjaHIgfj0gIiwiIHRoZW4gZGVjb2RlX2Vycm9yKHN0ciwgaSwgImV4cGVjdGVkICddJyBvciAnLCciKSBlbmQKICAgIGVuZAogICAgcmV0dXJuIHJlcywgaQplbmQKCmxvY2FsIGZ1bmN0aW9uIHBhcnNlX29iamVjdChzdHIsIGkpCiAgICBsb2NhbCByZXMgPSB7fQogICAgaSA9IGkgKyAxCiAgICB3aGlsZSB0cnVlIGRvCiAgICAgICAgbG9jYWwga2V5LCB2YWwKICAgICAgICBpID0gbmV4dF9jaGFyKHN0ciwgaSwgc3BhY2VfY2hhcnMsIHRydWUpCiAgICAgICAgaWYgc3RyOnN1YihpLCBpKSA9PSAifSIgdGhlbgogICAgICAgICAgICBpID0gaSArIDEKICAgICAgICAgICAgYnJlYWsKICAgICAgICBlbmQKICAgICAgICBpZiBzdHI6c3ViKGksIGkpIH49ICciJyB0aGVuCiAgICAgICAgICAgIGRlY29kZV9lcnJvcihzdHIsIGksICJleHBlY3RlZCBzdHJpbmcgZm9yIGtleSIpCiAgICAgICAgZW5kCiAgICAgICAga2V5LCBpID0gcGFyc2Uoc3RyLCBpKQogICAgICAgIGkgPSBuZXh0X2NoYXIoc3RyLCBpLCBzcGFjZV9jaGFycywgdHJ1ZSkKICAgICAgICBpZiBzdHI6c3ViKGksIGkpIH49ICI6IiB0aGVuCiAgICAgICAgICAgIGRlY29kZV9lcnJvcihzdHIsIGksICJleHBlY3RlZCAnOicgYWZ0ZXIga2V5IikKICAgICAgICBlbmQKICAgICAgICBpID0gbmV4dF9jaGFyKHN0ciwgaSArIDEsIHNwYWNlX2NoYXJzLCB0cnVlKQogICAgICAgIHZhbCwgaSA9IHBhcnNlKHN0ciwgaSkKICAgICAgICByZXNba2V5XSA9IHZhbAogICAgICAgIGkgPSBuZXh0X2NoYXIoc3RyLCBpLCBzcGFjZV9jaGFycywgdHJ1ZSkKICAgICAgICBsb2NhbCBjaHIgPSBzdHI6c3ViKGksIGkpCiAgICAgICAgaSA9IGkgKyAxCiAgICAgICAgaWYgY2hyID09ICJ9IiB0aGVuIGJyZWFrIGVuZAogICAgICAgIGlmIGNociB+PSAiLCIgdGhlbiBkZWNvZGVfZXJyb3Ioc3RyLCBpLCAiZXhwZWN0ZWQgJ30nIG9yICcsJyIpIGVuZAogICAgZW5kCiAgICByZXR1cm4gcmVzLCBpCmVuZAoKbG9jYWwgY2hhcl9mdW5jX21hcCA9IHsKICAgIFsnIiddID0gcGFyc2Vfc3RyaW5nLAogICAgWyIwIl0gPSBwYXJzZV9udW1iZXIsCiAgICBbIjEiXSA9IHBhcnNlX251bWJlciwKICAgIFsiMiJdID0gcGFyc2VfbnVtYmVyLAogICAgWyIzIl0gPSBwYXJzZV9udW1iZXIsCiAgICBbIjQiXSA9IHBhcnNlX251bWJlciwKICAgIFsiNSJdID0gcGFyc2VfbnVtYmVyLAogICAgWyI2Il0gPSBwYXJzZV9udW1iZXIsCiAgICBbIjciXSA9IHBhcnNlX251bWJlciwKICAgIFsiOCJdID0gcGFyc2VfbnVtYmVyLAogICAgWyI5Il0gPSBwYXJzZV9udW1iZXIsCiAgICBbIi0iXSA9IHBhcnNlX251bWJlciwKICAgIFsidCJdID0gcGFyc2VfbGl0ZXJhbCwKICAgIFsiZiJdID0gcGFyc2VfbGl0ZXJhbCwKICAgIFsibiJdID0gcGFyc2VfbGl0ZXJhbCwKICAgIFsiWyJdID0gcGFyc2VfYXJyYXksCiAgICBbInsiXSA9IHBhcnNlX29iamVjdAp9CgpwYXJzZSA9IGZ1bmN0aW9uKHN0ciwgaWR4KQogICAgbG9jYWwgY2hyID0gc3RyOnN1YihpZHgsIGlkeCkKICAgIGxvY2FsIGYgPSBjaGFyX2Z1bmNfbWFwW2Nocl0KICAgIGlmIGYgdGhlbiByZXR1cm4gZihzdHIsIGlkeCkgZW5kCiAgICBkZWNvZGVfZXJyb3Ioc3RyLCBpZHgsICJ1bmV4cGVjdGVkIGNoYXJhY3RlciAnIiAuLiBjaHIgLi4gIiciKQplbmQKCmZ1bmN0aW9uIGpzb24uZGVjb2RlKHN0cikKICAgIGlmIHR5cGUoc3RyKSB+PSAic3RyaW5nIiB0aGVuCiAgICAgICAgZXJyb3IoImV4cGVjdGVkIGFyZ3VtZW50IG9mIHR5cGUgc3RyaW5nLCBnb3QgIiAuLiB0eXBlKHN0cikpCiAgICBlbmQKICAgIGxvY2FsIHJlcywgaWR4ID0gcGFyc2Uoc3RyLCBuZXh0X2NoYXIoc3RyLCAxLCBzcGFjZV9jaGFycywgdHJ1ZSkpCiAgICBpZHggPSBuZXh0X2NoYXIoc3RyLCBpZHgsIHNwYWNlX2NoYXJzLCB0cnVlKQogICAgaWYgaWR4IDw9ICNzdHIgdGhlbiBkZWNvZGVfZXJyb3Ioc3RyLCBpZHgsICJ0cmFpbGluZyBnYXJiYWdlIikgZW5kCiAgICByZXR1cm4gcmVzCmVuZAoKcmV0dXJuIGpzb24KCmVuZApfRy5wYWNrYWdlLmxvYWRlZFsiLmpzb24iXSA9IGxvYWRfanNvbigpCnByaW50KCJsb2FkZWQganNvbiIpCiAgCgoKbG9jYWwgZnVuY3Rpb24gbG9hZF9zdHJpbmdpZnkoKSAKICAtLS0gVGhlIFN0cmluZ2lmeSBtb2R1bGUgcHJvdmlkZXMgdXRpbGl0aWVzIGZvciBmb3JtYXR0aW5nIGFuZCBkaXNwbGF5aW5nIEx1YSB0YWJsZXMgaW4gYSBtb3JlIHJlYWRhYmxlIG1hbm5lci4gUmV0dXJucyB0aGUgc3RyaW5naWZ5IHRhYmxlLgotLSBAbW9kdWxlIHN0cmluZ2lmeQoKLS0tIFRoZSBzdHJpbmdpZnkgdGFibGUKLS0gQHRhYmxlIHN0cmluZ2lmeQotLSBAZmllbGQgX3ZlcnNpb24gVGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBzdHJpbmdpZnkgbW9kdWxlCi0tIEBmaWVsZCBpc1NpbXBsZUFycmF5IFRoZSBpc1NpbXBsZUFycmF5IGZ1bmN0aW9uCi0tIEBmaWVsZCBmb3JtYXQgVGhlIGZvcm1hdCBmdW5jdGlvbgpsb2NhbCBzdHJpbmdpZnkgPSB7IF92ZXJzaW9uID0gIjAuMC4xIiB9CgotLSBBTlNJIGNvbG9yIGNvZGVzCmxvY2FsIGNvbG9ycyA9IHsKICByZWQgPSAiXDI3WzMxbSIsCiAgZ3JlZW4gPSAiXDI3WzMybSIsCiAgYmx1ZSA9ICJcMjdbMzRtIiwKICByZXNldCA9ICJcMjdbMG0iCn0KCi0tLSBDaGVja3MgaWYgYSB0YWJsZSBpcyBhIHNpbXBsZSBhcnJheSAoaS5lLiwgYW4gYXJyYXkgd2l0aCBjb25zZWN1dGl2ZSBudW1lcmljIGtleXMgc3RhcnRpbmcgZnJvbSAxKS4KLS0gQGZ1bmN0aW9uIGlzU2ltcGxlQXJyYXkKLS0gQHRwYXJhbSB7dGFibGV9IHRibCBUaGUgdGFibGUgdG8gY2hlY2sKLS0gQHRyZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHRhYmxlIGlzIGEgc2ltcGxlIGFycmF5CmZ1bmN0aW9uIHN0cmluZ2lmeS5pc1NpbXBsZUFycmF5KHRibCkKICBsb2NhbCBhcnJheUluZGV4ID0gMQogIGZvciBrLCB2IGluIHBhaXJzKHRibCkgZG8KICAgIGlmIGsgfj0gYXJyYXlJbmRleCBvciAodHlwZSh2KSB+PSAibnVtYmVyIiBhbmQgdHlwZSh2KSB+PSAic3RyaW5nIikgdGhlbgogICAgICByZXR1cm4gZmFsc2UKICAgIGVuZAogICAgYXJyYXlJbmRleCA9IGFycmF5SW5kZXggKyAxCiAgZW5kCiAgcmV0dXJuIHRydWUKZW5kCgotLS0gRm9ybWF0cyBhIHRhYmxlIGZvciBkaXNwbGF5LCBoYW5kbGluZyBjaXJjdWxhciByZWZlcmVuY2VzIGFuZCBmb3JtYXR0aW5nIHN0cmluZ3MgYW5kIHRhYmxlcyByZWN1cnNpdmVseS4KLS0gQGZ1bmN0aW9uIGZvcm1hdAotLSBAdHBhcmFtIHt0YWJsZX0gdGJsIFRoZSB0YWJsZSB0byBmb3JtYXQKLS0gQHRwYXJhbSB7bnVtYmVyfSBpbmRlbnQgVGhlIGluZGVudGF0aW9uIGxldmVsIChkZWZhdWx0IGlzIDApCi0tIEB0cGFyYW0ge3RhYmxlfSB2aXNpdGVkIEEgdGFibGUgdG8gdHJhY2sgdmlzaXRlZCB0YWJsZXMgYW5kIGRldGVjdCBjaXJjdWxhciByZWZlcmVuY2VzIChvcHRpb25hbCkKLS0gQHRyZXR1cm4ge3N0cmluZ30gQSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHRhYmxlCmZ1bmN0aW9uIHN0cmluZ2lmeS5mb3JtYXQodGJsLCBpbmRlbnQsIHZpc2l0ZWQpCiAgaW5kZW50ID0gaW5kZW50IG9yIDAKICBsb2NhbCB0b0luZGVudCA9IHN0cmluZy5yZXAoIiAiLCBpbmRlbnQpCiAgbG9jYWwgdG9JbmRlbnRDaGlsZCA9IHN0cmluZy5yZXAoIiAiLCBpbmRlbnQgKyAyKQoKICBsb2NhbCByZXN1bHQgPSB7fQogIGxvY2FsIGlzQXJyYXkgPSB0cnVlCiAgbG9jYWwgYXJyYXlJbmRleCA9IDEKCiAgaWYgc3RyaW5naWZ5LmlzU2ltcGxlQXJyYXkodGJsKSB0aGVuCiAgICBmb3IgXywgdiBpbiBpcGFpcnModGJsKSBkbwogICAgICBpZiB0eXBlKHYpID09ICJzdHJpbmciIHRoZW4KICAgICAgICB2ID0gY29sb3JzLmdyZWVuIC4uICciJyAuLiB2IC4uICciJyAuLiBjb2xvcnMucmVzZXQKICAgICAgZWxzZQogICAgICAgIHYgPSBjb2xvcnMuYmx1ZSAuLiB0b3N0cmluZyh2KSAuLiBjb2xvcnMucmVzZXQKICAgICAgZW5kCiAgICAgIHRhYmxlLmluc2VydChyZXN1bHQsIHYpCiAgICBlbmQKICAgIHJldHVybiAieyAiIC4uIHRhYmxlLmNvbmNhdChyZXN1bHQsICIsICIpIC4uICIgfSIKICBlbmQKCiAgZm9yIGssIHYgaW4gcGFpcnModGJsKSBkbwogICAgaWYgaXNBcnJheSB0aGVuCiAgICAgIGlmIGsgPT0gYXJyYXlJbmRleCB0aGVuCiAgICAgICAgYXJyYXlJbmRleCA9IGFycmF5SW5kZXggKyAxCiAgICAgICAgaWYgdHlwZSh2KSA9PSAidGFibGUiIHRoZW4KICAgICAgICAgIHYgPSBzdHJpbmdpZnkuZm9ybWF0KHYsIGluZGVudCArIDIpCiAgICAgICAgZWxzZWlmIHR5cGUodikgPT0gInN0cmluZyIgdGhlbgogICAgICAgICAgdiA9IGNvbG9ycy5ncmVlbiAuLiAnIicgLi4gdiAuLiAnIicgLi4gY29sb3JzLnJlc2V0CiAgICAgICAgZWxzZQogICAgICAgICAgdiA9IGNvbG9ycy5ibHVlIC4uIHRvc3RyaW5nKHYpIC4uIGNvbG9ycy5yZXNldAogICAgICAgIGVuZAogICAgICAgIHRhYmxlLmluc2VydChyZXN1bHQsIHRvSW5kZW50Q2hpbGQgLi4gdikKICAgICAgZWxzZQogICAgICAgIGlzQXJyYXkgPSBmYWxzZQogICAgICAgIHJlc3VsdCA9IHt9CiAgICAgIGVuZAogICAgZW5kCiAgICBpZiBub3QgaXNBcnJheSB0aGVuCiAgICAgIGlmIHR5cGUodikgPT0gInRhYmxlIiB0aGVuCiAgICAgICAgdmlzaXRlZCA9IHZpc2l0ZWQgb3Ige30KICAgICAgICBpZiB2aXNpdGVkW3ZdIHRoZW4KICAgICAgICAgICAgcmV0dXJuICI8Y2lyY3VsYXIgcmVmZXJlbmNlPiIKICAgICAgICBlbmQKICAgICAgICB2aXNpdGVkW3ZdID0gdHJ1ZQoKICAgICAgICB2ID0gc3RyaW5naWZ5LmZvcm1hdCh2LCBpbmRlbnQgKyAyLCB2aXNpdGVkKQogICAgICBlbHNlaWYgdHlwZSh2KSA9PSAic3RyaW5nIiB0aGVuCiAgICAgICAgdiA9IGNvbG9ycy5ncmVlbiAuLiAnIicgLi4gdiAuLiAnIicgLi4gY29sb3JzLnJlc2V0CiAgICAgIGVsc2UKICAgICAgICB2ID0gY29sb3JzLmJsdWUgLi4gdG9zdHJpbmcodikgLi4gY29sb3JzLnJlc2V0CiAgICAgIGVuZAogICAgICBrID0gY29sb3JzLnJlZCAuLiBrIC4uIGNvbG9ycy5yZXNldAogICAgICB0YWJsZS5pbnNlcnQocmVzdWx0LCB0b0luZGVudENoaWxkIC4uIGsgLi4gIiA9ICIgLi4gdikKICAgIGVuZAogIGVuZAoKICBsb2NhbCBwcmVmaXggPSBpc0FycmF5IGFuZCAie1xuIiBvciAie1xuICIKICBsb2NhbCBzdWZmaXggPSBpc0FycmF5IGFuZCAiXG4iIC4uIHRvSW5kZW50IC4uICIgfSIgb3IgIlxuIiAuLiB0b0luZGVudCAuLiAifSIKICBsb2NhbCBzZXBhcmF0b3IgPSBpc0FycmF5IGFuZCAiLFxuIiBvciAiLFxuICIKICByZXR1cm4gcHJlZml4IC4uIHRhYmxlLmNvbmNhdChyZXN1bHQsIHNlcGFyYXRvcikgLi4gc3VmZml4CmVuZAoKcmV0dXJuIHN0cmluZ2lmeQoKZW5kCl9HLnBhY2thZ2UubG9hZGVkWyIuc3RyaW5naWZ5Il0gPSBsb2FkX3N0cmluZ2lmeSgpCnByaW50KCJsb2FkZWQgc3RyaW5naWZ5IikKICAKCgpsb2NhbCBmdW5jdGlvbiBsb2FkX2V2YWwoKSAKICAtLS0gVGhlIEV2YWwgbW9kdWxlIHByb3ZpZGVzIGEgaGFuZGxlciBmb3IgZXZhbHVhdGluZyBMdWEgZXhwcmVzc2lvbnMuIFJldHVybnMgdGhlIGV2YWwgZnVuY3Rpb24uCi0tIEBtb2R1bGUgZXZhbAoKbG9jYWwgc3RyaW5naWZ5ID0gcmVxdWlyZSgiLnN0cmluZ2lmeSIpCmxvY2FsIGpzb24gPSByZXF1aXJlKCcuanNvbicpCi0tLSBUaGUgZXZhbCBmdW5jdGlvbi4KLS0gSGFuZGxlciBmb3IgZXhlY3V0aW5nIGFuZCBldmFsdWF0aW5nIEx1YSBleHByZXNzaW9ucy4KLS0gQWZ0ZXIgZXhlY3V0aW9uLCB0aGUgcmVzdWx0IGlzIHN0cmluZ2lmaWVkIGFuZCBwbGFjZWQgaW4gYW8ub3V0Ym94Lk91dHB1dC4KLS0gQGZ1bmN0aW9uIGV2YWwKLS0gQHRwYXJhbSB7dGFibGV9IGFvIFRoZSBhbyBlbnZpcm9ubWVudCBvYmplY3QKLS0gQHRyZXR1cm4ge2Z1bmN0aW9ufSBUaGUgaGFuZGxlciBmdW5jdGlvbiwgd2hpY2ggdGFrZXMgYSBtZXNzYWdlIGFzIGFuIGFyZ3VtZW50LgotLSBAc2VlIHN0cmluZ2lmeQpyZXR1cm4gZnVuY3Rpb24gKGFvKQogIHJldHVybiBmdW5jdGlvbiAocmVxKQogICAgbG9jYWwgbXNnID0gcmVxLmJvZHkKICAgIC0tIGV4ZWMgZXhwcmVzc2lvbgogICAgbG9jYWwgZXhwciA9IG1zZy5ib2R5IGFuZCBtc2cuYm9keS5ib2R5IG9yIG1zZy5kYXRhIG9yICIiCiAgICBsb2NhbCBmdW5jLCBlcnIgPSBsb2FkKCJyZXR1cm4gIiAuLiBleHByLCAnYW9zJywgJ3QnLCBfRykKICAgIGxvY2FsIG91dHB1dCA9ICIiCiAgICBsb2NhbCBlID0gbmlsCiAgICBpZiBlcnIgdGhlbgogICAgICBmdW5jLCBlcnIgPSBsb2FkKGV4cHIsICdhb3MnLCAndCcsIF9HKQogICAgZW5kCiAgICBpZiBmdW5jIHRoZW4KICAgICAgb3V0cHV0LCBlID0gZnVuYygpCiAgICBlbHNlCiAgICAgIGFvLm91dGJveC5FcnJvciA9IGVycgogICAgICByZXR1cm4KICAgIGVuZAogICAgaWYgZSB0aGVuCiAgICAgIGFvLm91dGJveC5FcnJvciA9IGUKICAgICAgcmV0dXJuCiAgICBlbmQKICAgIGlmIEhhbmRsZXJQcmludExvZ3MgYW5kIG91dHB1dCB0aGVuCiAgICAgIHRhYmxlLmluc2VydChIYW5kbGVyUHJpbnRMb2dzLAogICAgICAgIHR5cGUob3V0cHV0KSA9PSAidGFibGUiCiAgICAgICAgYW5kIHN0cmluZ2lmeS5mb3JtYXQob3V0cHV0KQogICAgICAgIG9yIHRvc3RyaW5nKG91dHB1dCkKICAgICAgKQogICAgICAtLSBwcmludChzdHJpbmdpZnkuZm9ybWF0KEhhbmRsZXJQcmludExvZ3MpKQogICAgLS0gZWxzZQogICAgLS0gICAtLSBzZXQgcmVzdWx0IGluIG91dGJveC5PdXRwdXQgKExlZnQgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5KQogICAgLS0gICBhby5vdXRib3guT3V0cHV0ID0gewogICAgLS0gICAgIGRhdGEgPSB0eXBlKG91dHB1dCkgPT0gInRhYmxlIiAKICAgIC0tICAgICAgIGFuZCBzdHJpbmdpZnkuZm9ybWF0KG91dHB1dCkgb3IgdG9zdHJpbmcob3V0cHV0KSwKICAgIC0tICAgICBwcm9tcHQgPSBQcm9tcHQoKQogICAgLS0gICB9CiAgICAtLQogICAgZW5kCiAgZW5kCmVuZAoKZW5kCl9HLnBhY2thZ2UubG9hZGVkWyIuZXZhbCJdID0gbG9hZF9ldmFsKCkKcHJpbnQoImxvYWRlZCBldmFsIikKICAKCgpsb2NhbCBmdW5jdGlvbiBsb2FkX3V0aWxzKCkgCiAgLS0tIFRoZSBVdGlscyBtb2R1bGUgcHJvdmlkZXMgYSBjb2xsZWN0aW9uIG9mIHV0aWxpdHkgZnVuY3Rpb25zIGZvciBmdW5jdGlvbmFsIHByb2dyYW1taW5nIGluIEx1YS4gSXQgaW5jbHVkZXMgZnVuY3Rpb25zIGZvciBhcnJheSBtYW5pcHVsYXRpb24gc3VjaCBhcyBjb25jYXRlbmF0aW9uLCBtYXBwaW5nLCByZWR1Y3Rpb24sIGZpbHRlcmluZywgYW5kIGZpbmRpbmcgZWxlbWVudHMsIGFzIHdlbGwgYXMgYSBwcm9wZXJ0eSBlcXVhbGl0eSBjaGVja2VyLgotLSBAbW9kdWxlIHV0aWxzCgotLS0gVGhlIHV0aWxzIHRhYmxlCi0tIEB0YWJsZSB1dGlscwotLSBAZmllbGQgX3ZlcnNpb24gVGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSB1dGlscyBtb2R1bGUKLS0gQGZpZWxkIG1hdGNoZXNQYXR0ZXJuIFRoZSBtYXRjaGVzUGF0dGVybiBmdW5jdGlvbgotLSBAZmllbGQgbWF0Y2hlc1NwZWMgVGhlIG1hdGNoZXNTcGVjIGZ1bmN0aW9uCi0tIEBmaWVsZCBjdXJyeSBUaGUgY3VycnkgZnVuY3Rpb24KLS0gQGZpZWxkIGNvbmNhdCBUaGUgY29uY2F0IGZ1bmN0aW9uCi0tIEBmaWVsZCByZWR1Y2UgVGhlIHJlZHVjZSBmdW5jdGlvbgotLSBAZmllbGQgbWFwIFRoZSBtYXAgZnVuY3Rpb24KLS0gQGZpZWxkIGZpbHRlciBUaGUgZmlsdGVyIGZ1bmN0aW9uCi0tIEBmaWVsZCBmaW5kIFRoZSBmaW5kIGZ1bmN0aW9uCi0tIEBmaWVsZCBwcm9wRXEgVGhlIHByb3BFcSBmdW5jdGlvbgotLSBAZmllbGQgcmV2ZXJzZSBUaGUgcmV2ZXJzZSBmdW5jdGlvbgotLSBAZmllbGQgY29tcG9zZSBUaGUgY29tcG9zZSBmdW5jdGlvbgotLSBAZmllbGQgcHJvcCBUaGUgcHJvcCBmdW5jdGlvbgotLSBAZmllbGQgaW5jbHVkZXMgVGhlIGluY2x1ZGVzIGZ1bmN0aW9uCi0tIEBmaWVsZCBrZXlzIFRoZSBrZXlzIGZ1bmN0aW9uCi0tIEBmaWVsZCB2YWx1ZXMgVGhlIHZhbHVlcyBmdW5jdGlvbgpsb2NhbCB1dGlscyA9IHsgX3ZlcnNpb24gPSAiMC4wLjUiIH0KCi0tLSBHaXZlbiBhIHBhdHRlcm4sIGEgdmFsdWUsIGFuZCBhIG1lc3NhZ2UsIHJldHVybnMgd2hldGhlciB0aGVyZSBpcyBhIHBhdHRlcm4gbWF0Y2guCi0tIEB1c2FnZSB1dGlscy5tYXRjaGVzUGF0dGVybihwYXR0ZXJuLCB2YWx1ZSwgbXNnKQotLSBAcGFyYW0gcGF0dGVybiBUaGUgcGF0dGVybiB0byBtYXRjaAotLSBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrIGZvciBpbiB0aGUgcGF0dGVybgotLSBAcGFyYW0gbXNnIFRoZSBtZXNzYWdlIHRvIGNoZWNrIGZvciB0aGUgcGF0dGVybgotLSBAdHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB0aGVyZSBpcyBhIHBhdHRlcm4gbWF0Y2gKZnVuY3Rpb24gdXRpbHMubWF0Y2hlc1BhdHRlcm4ocGF0dGVybiwgdmFsdWUsIG1zZykKICAtLSBJZiB0aGUga2V5IGlzIG5vdCBpbiB0aGUgbWVzc2FnZSwgdGhlbiBpdCBkb2VzIG5vdCBtYXRjaAogIGlmIChub3QgcGF0dGVybikgdGhlbgogICAgcmV0dXJuIGZhbHNlCiAgZW5kCiAgLS0gaWYgdGhlIHBhdHRlcm5NYXRjaFNwZWMgaXMgYSB3aWxkY2FyZCwgdGhlbiBpdCBhbHdheXMgbWF0Y2hlcwogIGlmIHBhdHRlcm4gPT0gJ18nIHRoZW4KICAgIHJldHVybiB0cnVlCiAgZW5kCiAgLS0gaWYgdGhlIHBhdHRlcm5NYXRjaFNwZWMgaXMgYSBmdW5jdGlvbiwgdGhlbiBpdCBpcyBleGVjdXRlZCBvbiB0aGUgdGFnIHZhbHVlCiAgaWYgdHlwZShwYXR0ZXJuKSA9PSAiZnVuY3Rpb24iIHRoZW4KICAgIGlmIHBhdHRlcm4odmFsdWUsIG1zZykgdGhlbgogICAgICByZXR1cm4gdHJ1ZQogICAgZWxzZQogICAgICByZXR1cm4gZmFsc2UKICAgIGVuZAogIGVuZAogIC0tIGlmIHRoZSBwYXR0ZXJuTWF0Y2hTcGVjIGlzIGEgc3RyaW5nLCBjaGVjayBpdCBmb3Igc3BlY2lhbCBzeW1ib2xzIChsZXNzIGAtYCBhbG9uZSkKICAtLSBhbmQgZXhhY3Qgc3RyaW5nIG1hdGNoIG1vZGUKICBpZiAodHlwZShwYXR0ZXJuKSA9PSAnc3RyaW5nJykgdGhlbgogICAgaWYgc3RyaW5nLm1hdGNoKHBhdHRlcm4sICJbJV4lJCUoJSklJSUuJVslXSUqJSslP10iKSB0aGVuCiAgICAgIGlmIHN0cmluZy5tYXRjaCh2YWx1ZSwgcGF0dGVybikgdGhlbgogICAgICAgIHJldHVybiB0cnVlCiAgICAgIGVuZAogICAgZWxzZQogICAgICBpZiB2YWx1ZSA9PSBwYXR0ZXJuIHRoZW4KICAgICAgICByZXR1cm4gdHJ1ZQogICAgICBlbmQKICAgIGVuZAogIGVuZAoKICAtLSBpZiB0aGUgcGF0dGVybiBpcyBhIHRhYmxlLCByZWN1cnNpdmVseSBjaGVjayBpZiBhbnkgb2YgaXRzIHN1Yi1wYXR0ZXJucyBtYXRjaAogIGlmIHR5cGUocGF0dGVybikgPT0gJ3RhYmxlJyB0aGVuCiAgICBmb3IgXywgc3ViUGF0dGVybiBpbiBwYWlycyhwYXR0ZXJuKSBkbwogICAgICBpZiB1dGlscy5tYXRjaGVzUGF0dGVybihzdWJQYXR0ZXJuLCB2YWx1ZSwgbXNnKSB0aGVuCiAgICAgICAgcmV0dXJuIHRydWUKICAgICAgZW5kCiAgICBlbmQKICBlbmQKCiAgcmV0dXJuIGZhbHNlCmVuZAoKLS0tIEdpdmVuIGEgbWVzc2FnZSBhbmQgYSBzcGVjLCByZXR1cm5zIHdoZXRoZXIgdGhlcmUgaXMgYSBzcGVjIG1hdGNoLgotLSBAdXNhZ2UgdXRpbHMubWF0Y2hlc1NwZWMobXNnLCBzcGVjKQotLSBAcGFyYW0gbXNnIFRoZSBtZXNzYWdlIHRvIGNoZWNrIGZvciB0aGUgc3BlYwotLSBAcGFyYW0gc3BlYyBUaGUgc3BlYyB0byBjaGVjayBmb3IgaW4gdGhlIG1lc3NhZ2UKLS0gQHRyZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdGhlcmUgaXMgYSBzcGVjIG1hdGNoCmZ1bmN0aW9uIHV0aWxzLm1hdGNoZXNTcGVjKG1zZywgc3BlYykKICBpZiB0eXBlKHNwZWMpID09ICdmdW5jdGlvbicgdGhlbgogICAgcmV0dXJuIHNwZWMobXNnKQogIC0tIElmIHRoZSBzcGVjIGlzIGEgdGFibGUsIHN0ZXAgdGhyb3VnaCBldmVyeSBrZXkvdmFsdWUgcGFpciBpbiB0aGUgcGF0dGVybiBhbmQgY2hlY2sgaWYgdGhlIG1zZyBtYXRjaGVzCiAgLS0gU3VwcG9ydGVkIHBhdHRlcm4gdHlwZXM6CiAgLS0gICAtIEV4YWN0IHN0cmluZyBtYXRjaAogIC0tICAgLSBMdWEgZ21hdGNoIHN0cmluZwogIC0tICAgLSAnXycgKHdpbGRjYXJkOiBNZXNzYWdlIGhhcyB0YWcsIGJ1dCBjYW4gYmUgYW55IHZhbHVlKQogIC0tICAgLSBGdW5jdGlvbiBleGVjdXRpb24gb24gdGhlIHRhZywgb3B0aW9uYWxseSB1c2luZyB0aGUgbXNnIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQKICAtLSAgIC0gVGFibGUgb2YgcGF0dGVybnMsIHdoZXJlIEFOWSBvZiB0aGUgc3ViLXBhdHRlcm5zIG1hdGNoaW5nIHRoZSB0YWcgd2lsbCByZXN1bHQgaW4gYSBtYXRjaAogIGVuZAogIGlmIHR5cGUoc3BlYykgPT0gJ3RhYmxlJyB0aGVuCiAgICBmb3Iga2V5LCBwYXR0ZXJuIGluIHBhaXJzKHNwZWMpIGRvCiAgICAgIC0tIFRoZSBrZXkgY2FuIGVpdGhlciBiZSBpbiB0aGUgdG9wIGxldmVsIG9mIHRoZSAnbXNnJyBvYmplY3QgIAogICAgICAtLSBvciBpbiB0aGUgYm9keSB0YWJsZSBvZiB0aGUgbXNnCiAgICAgIGxvY2FsIG1zZ1ZhbHVlID0gbXNnW2tleV0gb3IgbXNnLmJvZHlba2V5XQogICAgICBpZiBub3QgbXNnVmFsdWUgdGhlbgogICAgICAgIHJldHVybiBmYWxzZQogICAgICBlbmQKICAgICAgbG9jYWwgbWF0Y2hlc01zZ1ZhbHVlID0gdXRpbHMubWF0Y2hlc1BhdHRlcm4ocGF0dGVybiwgbXNnVmFsdWUsIG1zZykKICAgICAgaWYgbm90IG1hdGNoZXNNc2dWYWx1ZSB0aGVuCiAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgIGVuZAoKICAgIGVuZAogICAgcmV0dXJuIHRydWUKICBlbmQKCiAgaWYgdHlwZShzcGVjKSA9PSAnc3RyaW5nJyBhbmQgbXNnLmFjdGlvbiBhbmQgbXNnLmFjdGlvbiA9PSBzcGVjIHRoZW4KICAgIHJldHVybiB0cnVlCiAgZW5kCiAgaWYgdHlwZShzcGVjKSA9PSAnc3RyaW5nJyBhbmQgbXNnLmJvZHkuYWN0aW9uIGFuZCBtc2cuYm9keS5hY3Rpb24gPT0gc3BlYyB0aGVuCiAgICByZXR1cm4gdHJ1ZQogIGVuZAogIHJldHVybiBmYWxzZQplbmQKCi0tLSBHaXZlbiBhIHRhYmxlLCByZXR1cm5zIHdoZXRoZXIgaXQgaXMgYW4gYXJyYXkuCi0tIEFuICdhcnJheScgaXMgZGVmaW5lZCBhcyBhIHRhYmxlIHdpdGggaW50ZWdlciBrZXlzIHN0YXJ0aW5nIGZyb20gMSBhbmQKLS0gaGF2aW5nIG5vIGdhcHMgYmV0d2VlbiB0aGUga2V5cy4KLS0gQGxmdW5jdGlvbiBpc0FycmF5Ci0tIEBwYXJhbSB0YWJsZSBUaGUgdGFibGUgdG8gY2hlY2sKLS0gQHRyZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHRhYmxlIGlzIGFuIGFycmF5CmxvY2FsIGZ1bmN0aW9uIGlzQXJyYXkodGFibGUpCiAgaWYgdHlwZSh0YWJsZSkgPT0gInRhYmxlIiB0aGVuCiAgICAgIGxvY2FsIG1heEluZGV4ID0gMAogICAgICBmb3IgaywgdiBpbiBwYWlycyh0YWJsZSkgZG8KICAgICAgICAgIGlmIHR5cGUoaykgfj0gIm51bWJlciIgb3IgayA8IDEgb3IgbWF0aC5mbG9vcihrKSB+PSBrIHRoZW4KICAgICAgICAgICAgICByZXR1cm4gZmFsc2UgLS0gSWYgdGhlcmUncyBhIG5vbi1pbnRlZ2VyIGtleSwgaXQncyBub3QgYW4gYXJyYXkKICAgICAgICAgIGVuZAogICAgICAgICAgbWF4SW5kZXggPSBtYXRoLm1heChtYXhJbmRleCwgaykKICAgICAgZW5kCiAgICAgIC0tIElmIHRoZSBoaWdoZXN0IG51bWVyaWMgaW5kZXggaXMgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBlbGVtZW50cywgaXQncyBhbiBhcnJheQogICAgICByZXR1cm4gbWF4SW5kZXggPT0gI3RhYmxlCiAgZW5kCiAgcmV0dXJuIGZhbHNlCmVuZAoKLS0tIEN1cnJpZXMgYSBmdW5jdGlvbi4KLS0gQHRwYXJhbSB7ZnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBjdXJyeQotLSBAdHBhcmFtIHtudW1iZXJ9IGFyaXR5IFRoZSBhcml0eSBvZiB0aGUgZnVuY3Rpb24KLS0gQHRyZXR1cm4ge2Z1bmN0aW9ufSBUaGUgY3VycmllZCBmdW5jdGlvbgp1dGlscy5jdXJyeSA9IGZ1bmN0aW9uIChmbiwgYXJpdHkpCiAgYXNzZXJ0KHR5cGUoZm4pID09ICJmdW5jdGlvbiIsICJmdW5jdGlvbiBpcyByZXF1aXJlZCBhcyBmaXJzdCBhcmd1bWVudCIpCiAgYXJpdHkgPSBhcml0eSBvciBkZWJ1Zy5nZXRpbmZvKGZuLCAidSIpLm5wYXJhbXMKICBpZiBhcml0eSA8IDIgdGhlbiByZXR1cm4gZm4gZW5kCgogIHJldHVybiBmdW5jdGlvbiAoLi4uKQogICAgbG9jYWwgYXJncyA9IHsuLi59CgogICAgaWYgI2FyZ3MgPj0gYXJpdHkgdGhlbgogICAgICByZXR1cm4gZm4odGFibGUudW5wYWNrKGFyZ3MpKQogICAgZWxzZQogICAgICByZXR1cm4gdXRpbHMuY3VycnkoZnVuY3Rpb24gKC4uLikKICAgICAgICByZXR1cm4gZm4odGFibGUudW5wYWNrKGFyZ3MpLCAgLi4uKQogICAgICBlbmQsIGFyaXR5IC0gI2FyZ3MpCiAgICBlbmQKICBlbmQKZW5kCgotLS0gQ29uY2F0IHR3byBBcnJheSBUYWJsZXMKLS0gQGZ1bmN0aW9uIGNvbmNhdAotLSBAdXNhZ2UgdXRpbHMuY29uY2F0KGEpKGIpCi0tIEB1c2FnZSB1dGlscy5jb25jYXQoezEsIDJ9KSh7MywgNH0pIC0tPiB7MSwgMiwgMywgNH0KLS0gQHRwYXJhbSB7dGFibGU8QXJyYXk+fSBhIFRoZSBmaXJzdCBhcnJheQotLSBAdHBhcmFtIHt0YWJsZTxBcnJheT59IGIgVGhlIHNlY29uZCBhcnJheQotLSBAdHJldHVybiB7dGFibGU8QXJyYXk+fSBUaGUgY29uY2F0ZW5hdGVkIGFycmF5CnV0aWxzLmNvbmNhdCA9IHV0aWxzLmN1cnJ5KGZ1bmN0aW9uIChhLCBiKQogIGFzc2VydCh0eXBlKGEpID09ICJ0YWJsZSIsICJmaXJzdCBhcmd1bWVudCBzaG91bGQgYmUgYSB0YWJsZSB0aGF0IGlzIGFuIGFycmF5IikKICBhc3NlcnQodHlwZShiKSA9PSAidGFibGUiLCAic2Vjb25kIGFyZ3VtZW50IHNob3VsZCBiZSBhIHRhYmxlIHRoYXQgaXMgYW4gYXJyYXkiKQogIGFzc2VydChpc0FycmF5KGEpLCAiZmlyc3QgYXJndW1lbnQgc2hvdWxkIGJlIGEgdGFibGUiKQogIGFzc2VydChpc0FycmF5KGIpLCAic2Vjb25kIGFyZ3VtZW50IHNob3VsZCBiZSBhIHRhYmxlIikKCiAgbG9jYWwgcmVzdWx0ID0ge30KICBmb3IgaSA9IDEsICNhIGRvCiAgICAgIHJlc3VsdFsjcmVzdWx0ICsgMV0gPSBhW2ldCiAgZW5kCiAgZm9yIGkgPSAxLCAjYiBkbwogICAgICByZXN1bHRbI3Jlc3VsdCArIDFdID0gYltpXQogIGVuZAogIHJldHVybiByZXN1bHQKZW5kLCAyKQoKLS0tIEFwcGxpZXMgYSBmdW5jdGlvbiB0byBlYWNoIGVsZW1lbnQgb2YgYSB0YWJsZSwgcmVkdWNpbmcgaXQgdG8gYSBzaW5nbGUgdmFsdWUuCi0tIEBmdW5jdGlvbiB1dGlscy5yZWR1Y2UKLS0gQHVzYWdlIHV0aWxzLnJlZHVjZShmbikoaW5pdGlhbCkodCkKLS0gQHVzYWdlIHV0aWxzLnJlZHVjZShmdW5jdGlvbihhY2MsIHgpIHJldHVybiBhY2MgKyB4IGVuZCkoMCkoezEsIDIsIDN9KSAtLT4gNgotLSBAdHBhcmFtIHtmdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGFwcGx5Ci0tIEBwYXJhbSBpbml0aWFsIFRoZSBpbml0aWFsIHZhbHVlCi0tIEB0cGFyYW0ge3RhYmxlPEFycmF5Pn0gdCBUaGUgdGFibGUgdG8gcmVkdWNlCi0tIEByZXR1cm4gVGhlIHJlZHVjZWQgdmFsdWUKdXRpbHMucmVkdWNlID0gdXRpbHMuY3VycnkoZnVuY3Rpb24gKGZuLCBpbml0aWFsLCB0KQogIGFzc2VydCh0eXBlKGZuKSA9PSAiZnVuY3Rpb24iLCAiZmlyc3QgYXJndW1lbnQgc2hvdWxkIGJlIGEgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIChyZXN1bHQsIHZhbHVlLCBrZXkpIikKICBhc3NlcnQodHlwZSh0KSA9PSAidGFibGUiIGFuZCBpc0FycmF5KHQpLCAidGhpcmQgYXJndW1lbnQgc2hvdWxkIGJlIGEgdGFibGUgdGhhdCBpcyBhbiBhcnJheSIpCiAgbG9jYWwgcmVzdWx0ID0gaW5pdGlhbAogIGZvciBrLCB2IGluIHBhaXJzKHQpIGRvCiAgICBpZiByZXN1bHQgPT0gbmlsIHRoZW4KICAgICAgcmVzdWx0ID0gdgogICAgZWxzZQogICAgICByZXN1bHQgPSBmbihyZXN1bHQsIHYsIGspCiAgICBlbmQKICBlbmQKICByZXR1cm4gcmVzdWx0CmVuZCwgMykKCi0tLSBBcHBsaWVzIGEgZnVuY3Rpb24gdG8gZWFjaCBlbGVtZW50IG9mIGFuIGFycmF5IHRhYmxlLCBtYXBwaW5nIGl0IHRvIGEgbmV3IHZhbHVlLgotLSBAZnVuY3Rpb24gdXRpbHMubWFwCi0tIEB1c2FnZSB1dGlscy5tYXAoZm4pKHQpCi0tIEB1c2FnZSB1dGlscy5tYXAoZnVuY3Rpb24oeCkgcmV0dXJuIHggKiAyIGVuZCkoezEsIDIsIDN9KSAtLT4gezIsIDQsIDZ9Ci0tIEB0cGFyYW0ge2Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gYXBwbHkgdG8gZWFjaCBlbGVtZW50Ci0tIEB0cGFyYW0ge3RhYmxlPEFycmF5Pn0gZGF0YSBUaGUgdGFibGUgdG8gbWFwIG92ZXIKLS0gQHRyZXR1cm4ge3RhYmxlPEFycmF5Pn0gVGhlIG1hcHBlZCB0YWJsZQp1dGlscy5tYXAgPSB1dGlscy5jdXJyeShmdW5jdGlvbiAoZm4sIGRhdGEpCiAgYXNzZXJ0KHR5cGUoZm4pID09ICJmdW5jdGlvbiIsICJmaXJzdCBhcmd1bWVudCBzaG91bGQgYmUgYSB1bmFyeSBmdW5jdGlvbiIpCiAgYXNzZXJ0KHR5cGUoZGF0YSkgPT0gInRhYmxlIiBhbmQgaXNBcnJheShkYXRhKSwgInNlY29uZCBhcmd1bWVudCBzaG91bGQgYmUgYW4gQXJyYXkiKQoKICBsb2NhbCBmdW5jdGlvbiBtYXAgKHJlc3VsdCwgdiwgaykKICAgIHJlc3VsdFtrXSA9IGZuKHYsIGspCiAgICByZXR1cm4gcmVzdWx0CiAgZW5kCgogIHJldHVybiB1dGlscy5yZWR1Y2UobWFwLCB7fSwgZGF0YSkKZW5kLCAyKQoKLS0tIEZpbHRlcnMgYW4gYXJyYXkgdGFibGUgYmFzZWQgb24gYSBwcmVkaWNhdGUgZnVuY3Rpb24uCi0tIEBmdW5jdGlvbiB1dGlscy5maWx0ZXIKLS0gQHVzYWdlIHV0aWxzLmZpbHRlcihmbikodCkKLS0gQHVzYWdlIHV0aWxzLmZpbHRlcihmdW5jdGlvbih4KSByZXR1cm4geCA+IDEgZW5kKSh7MSwgMiwgM30pIC0tPiB7MiwzfQotLSBAdHBhcmFtIHtmdW5jdGlvbn0gZm4gVGhlIHByZWRpY2F0ZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgaWYgYW4gZWxlbWVudCBzaG91bGQgYmUgaW5jbHVkZWQuCi0tIEB0cGFyYW0ge3RhYmxlPEFycmF5Pn0gZGF0YSBUaGUgYXJyYXkgdG8gZmlsdGVyCi0tIEB0cmV0dXJuIHt0YWJsZTxBcnJheT59IFRoZSBmaWx0ZXJlZCB0YWJsZQp1dGlscy5maWx0ZXIgPSB1dGlscy5jdXJyeShmdW5jdGlvbiAoZm4sIGRhdGEpCiAgYXNzZXJ0KHR5cGUoZm4pID09ICJmdW5jdGlvbiIsICJmaXJzdCBhcmd1bWVudCBzaG91bGQgYmUgYSB1bmFyeSBmdW5jdGlvbiIpCiAgYXNzZXJ0KHR5cGUoZGF0YSkgPT0gInRhYmxlIiBhbmQgaXNBcnJheShkYXRhKSwgInNlY29uZCBhcmd1bWVudCBzaG91bGQgYmUgYW4gQXJyYXkiKQoKICBsb2NhbCBmdW5jdGlvbiBmaWx0ZXIgKHJlc3VsdCwgdiwgX2spCiAgICBpZiBmbih2KSB0aGVuCiAgICAgIHRhYmxlLmluc2VydChyZXN1bHQsIHYpCiAgICBlbmQKICAgIHJldHVybiByZXN1bHQKICBlbmQKCiAgcmV0dXJuIHV0aWxzLnJlZHVjZShmaWx0ZXIse30sIGRhdGEpCmVuZCwgMikKCi0tLSBGaW5kcyB0aGUgZmlyc3QgZWxlbWVudCBpbiBhbiBhcnJheSB0YWJsZSB0aGF0IHNhdGlzZmllcyBhIHByZWRpY2F0ZSBmdW5jdGlvbi4KLS0gQGZ1bmN0aW9uIHV0aWxzLmZpbmQKLS0gQHVzYWdlIHV0aWxzLmZpbmQoZm4pKHQpCi0tIEB1c2FnZSB1dGlscy5maW5kKGZ1bmN0aW9uKHgpIHJldHVybiB4ID4gMSBlbmQpKHsxLCAyLCAzfSkgLS0+IDIKLS0gQHRwYXJhbSB7ZnVuY3Rpb259IGZuIFRoZSBwcmVkaWNhdGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGlmIGFuIGVsZW1lbnQgc2hvdWxkIGJlIGluY2x1ZGVkLgotLSBAdHBhcmFtIHt0YWJsZTxBcnJheT59IHQgVGhlIGFycmF5IHRhYmxlIHRvIHNlYXJjaAotLSBAdHJldHVybiBUaGUgZmlyc3QgZWxlbWVudCB0aGF0IHNhdGlzZmllcyB0aGUgcHJlZGljYXRlIGZ1bmN0aW9uCnV0aWxzLmZpbmQgPSB1dGlscy5jdXJyeShmdW5jdGlvbiAoZm4sIHQpCiAgYXNzZXJ0KHR5cGUoZm4pID09ICJmdW5jdGlvbiIsICJmaXJzdCBhcmd1bWVudCBzaG91bGQgYmUgYSB1bmFyeSBmdW5jdGlvbiIpCiAgYXNzZXJ0KHR5cGUodCkgPT0gInRhYmxlIiwgInNlY29uZCBhcmd1bWVudCBzaG91bGQgYmUgYSB0YWJsZSB0aGF0IGlzIGFuIGFycmF5IikKICBmb3IgXywgdiBpbiBwYWlycyh0KSBkbwogICAgaWYgZm4odikgdGhlbgogICAgICByZXR1cm4gdgogICAgZW5kCiAgZW5kCmVuZCwgMikKCi0tLSBDaGVja3MgaWYgYSBwcm9wZXJ0eSBvZiBhbiBvYmplY3QgaXMgZXF1YWwgdG8gYSB2YWx1ZS4KLS0gQGZ1bmN0aW9uIHV0aWxzLnByb3BFcQotLSBAdXNhZ2UgdXRpbHMucHJvcEVxKHByb3BOYW1lKSh2YWx1ZSkob2JqZWN0KQotLSBAdXNhZ2UgdXRpbHMucHJvcEVxKCJuYW1lIikoIkx1YSIpKHtuYW1lID0gIkx1YSJ9KSAtLT4gdHJ1ZQotLSBAdHBhcmFtIHtzdHJpbmd9IHByb3BOYW1lIFRoZSBwcm9wZXJ0eSBuYW1lIHRvIGNoZWNrCi0tIEB0cGFyYW0ge3N0cmluZ30gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrIGFnYWluc3QKLS0gQHRwYXJhbSB7dGFibGV9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNoZWNrCi0tIEB0cmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHRoZSBwcm9wZXJ0eSBpcyBlcXVhbCB0byB0aGUgdmFsdWUKdXRpbHMucHJvcEVxID0gdXRpbHMuY3VycnkoZnVuY3Rpb24gKHByb3BOYW1lLCB2YWx1ZSwgb2JqZWN0KQogIGFzc2VydCh0eXBlKHByb3BOYW1lKSA9PSAic3RyaW5nIiwgImZpcnN0IGFyZ3VtZW50IHNob3VsZCBiZSBhIHN0cmluZyIpCiAgYXNzZXJ0KHR5cGUodmFsdWUpID09ICJzdHJpbmciLCAic2Vjb25kIGFyZ3VtZW50IHNob3VsZCBiZSBhIHN0cmluZyIpCiAgYXNzZXJ0KHR5cGUob2JqZWN0KSA9PSAidGFibGUiLCAidGhpcmQgYXJndW1lbnQgc2hvdWxkIGJlIGEgdGFibGU8b2JqZWN0PiIpCiAgCiAgcmV0dXJuIG9iamVjdFtwcm9wTmFtZV0gPT0gdmFsdWUKZW5kLCAzKQoKLS0tIFJldmVyc2VzIGFuIGFycmF5IHRhYmxlLgotLSBAZnVuY3Rpb24gdXRpbHMucmV2ZXJzZQotLSBAdXNhZ2UgdXRpbHMucmV2ZXJzZShkYXRhKQotLSBAdXNhZ2UgdXRpbHMucmV2ZXJzZSh7MSwgMiwgM30pIC0tPiB7MywgMiwgMX0KLS0gQHRwYXJhbSB7dGFibGU8QXJyYXk+fSBkYXRhIFRoZSBhcnJheSB0YWJsZSB0byByZXZlcnNlCi0tIEB0cmV0dXJuIHt0YWJsZTxBcnJheT59IFRoZSByZXZlcnNlZCBhcnJheSB0YWJsZQp1dGlscy5yZXZlcnNlID0gZnVuY3Rpb24gKGRhdGEpCiAgYXNzZXJ0KHR5cGUoZGF0YSkgPT0gInRhYmxlIiwgImFyZ3VtZW50IG5lZWRzIHRvIGJlIGEgdGFibGUgdGhhdCBpcyBhbiBhcnJheSIpCiAgcmV0dXJuIHV0aWxzLnJlZHVjZSgKICAgIGZ1bmN0aW9uIChyZXN1bHQsIHYsIGkpCiAgICAgIHJlc3VsdFsjZGF0YSAtIGkgKyAxXSA9IHYKICAgICAgcmV0dXJuIHJlc3VsdAogICAgZW5kLAogICAge30sCiAgICBkYXRhCiAgKQplbmQKCi0tLSBDb21wb3NlcyBhIHNlcmllcyBvZiBmdW5jdGlvbnMgaW50byBhIHNpbmdsZSBmdW5jdGlvbi4KLS0gQGZ1bmN0aW9uIHV0aWxzLmNvbXBvc2UKLS0gQHVzYWdlIHV0aWxzLmNvbXBvc2UoZm4xKShmbjIpKGZuMykodikKLS0gQHVzYWdlIHV0aWxzLmNvbXBvc2UoZnVuY3Rpb24oeCkgcmV0dXJuIHggKyAxIGVuZCkoZnVuY3Rpb24oeCkgcmV0dXJuIHggKiAyIGVuZCkoMykgLS0+IDcKLS0gQHRwYXJhbSB7ZnVuY3Rpb259IC4uLiBUaGUgZnVuY3Rpb25zIHRvIGNvbXBvc2UKLS0gQHRyZXR1cm4ge2Z1bmN0aW9ufSBUaGUgY29tcG9zZWQgZnVuY3Rpb24KdXRpbHMuY29tcG9zZSA9IHV0aWxzLmN1cnJ5KGZ1bmN0aW9uICguLi4pCiAgbG9jYWwgbXV0YXRpb25zID0gdXRpbHMucmV2ZXJzZSh7Li4ufSkKCiAgcmV0dXJuIGZ1bmN0aW9uICh2KQogICAgbG9jYWwgcmVzdWx0ID0gdgogICAgZm9yIF8sIGZuIGluIHBhaXJzKG11dGF0aW9ucykgZG8KICAgICAgYXNzZXJ0KHR5cGUoZm4pID09ICJmdW5jdGlvbiIsICJlYWNoIGFyZ3VtZW50IG5lZWRzIHRvIGJlIGEgZnVuY3Rpb24iKQogICAgICByZXN1bHQgPSBmbihyZXN1bHQpCiAgICBlbmQKICAgIHJldHVybiByZXN1bHQKICBlbmQKZW5kLCAyKQoKLS0tIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgb2YgYW4gb2JqZWN0LgotLSBAZnVuY3Rpb24gdXRpbHMucHJvcAotLSBAdXNhZ2UgdXRpbHMucHJvcChwcm9wTmFtZSkob2JqZWN0KQotLSBAdXNhZ2UgdXRpbHMucHJvcCgibmFtZSIpKHtuYW1lID0gIkx1YSJ9KSAtLT4gIkx1YSIKLS0gQHRwYXJhbSB7c3RyaW5nfSBwcm9wTmFtZSBUaGUgcHJvcGVydHkgbmFtZSB0byBnZXQKLS0gQHRwYXJhbSB7dGFibGV9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGdldCB0aGUgcHJvcGVydHkgZnJvbQotLSBAdHJldHVybiBUaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5CnV0aWxzLnByb3AgPSB1dGlscy5jdXJyeShmdW5jdGlvbiAocHJvcE5hbWUsIG9iamVjdCkgCiAgcmV0dXJuIG9iamVjdFtwcm9wTmFtZV0KZW5kLCAyKQoKLS0tIENoZWNrcyBpZiBhbiBhcnJheSB0YWJsZSBpbmNsdWRlcyBhIHZhbHVlLgotLSBAZnVuY3Rpb24gdXRpbHMuaW5jbHVkZXMKLS0gQHVzYWdlIHV0aWxzLmluY2x1ZGVzKHZhbCkodCkKLS0gQHVzYWdlIHV0aWxzLmluY2x1ZGVzKDIpKHsxLCAyLCAzfSkgLS0+IHRydWUKLS0gQHBhcmFtIHZhbCBUaGUgdmFsdWUgdG8gY2hlY2sgZm9yCi0tIEB0cGFyYW0ge3RhYmxlPEFycmF5Pn0gdCBUaGUgYXJyYXkgdGFibGUgdG8gY2hlY2sKLS0gQHRyZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHZhbHVlIGlzIGluIHRoZSBhcnJheSB0YWJsZQp1dGlscy5pbmNsdWRlcyA9IHV0aWxzLmN1cnJ5KGZ1bmN0aW9uICh2YWwsIHQpCiAgYXNzZXJ0KHR5cGUodCkgPT0gInRhYmxlIiwgImFyZ3VtZW50IG5lZWRzIHRvIGJlIGEgdGFibGUiKQogIGFzc2VydChpc0FycmF5KHQpLCAiYXJndW1lbnQgc2hvdWxkIGJlIGEgdGFibGUgdGhhdCBpcyBhbiBhcnJheSIpCiAgcmV0dXJuIHV0aWxzLmZpbmQoZnVuY3Rpb24gKHYpIHJldHVybiB2ID09IHZhbCBlbmQsIHQpIH49IG5pbAplbmQsIDIpCgotLS0gUmV0dXJucyB0aGUga2V5cyBvZiBhIHRhYmxlLgotLSBAdXNhZ2UgdXRpbHMua2V5cyh0KQotLSBAdXNhZ2UgdXRpbHMua2V5cyh7bmFtZSA9ICJMdWEiLCBhZ2UgPSAyNX0pIC0tPiB7Im5hbWUiLCAiYWdlIn0KLS0gQHRwYXJhbSB7dGFibGV9IHQgVGhlIHRhYmxlIHRvIGdldCB0aGUga2V5cyBmcm9tCi0tIEB0cmV0dXJuIHt0YWJsZTxBcnJheT59IFRoZSBrZXlzIG9mIHRoZSB0YWJsZQp1dGlscy5rZXlzID0gZnVuY3Rpb24gKHQpCiAgYXNzZXJ0KHR5cGUodCkgPT0gInRhYmxlIiwgImFyZ3VtZW50IG5lZWRzIHRvIGJlIGEgdGFibGUiKQogIGxvY2FsIGtleXMgPSB7fQogIGZvciBrZXkgaW4gcGFpcnModCkgZG8KICAgIHRhYmxlLmluc2VydChrZXlzLCBrZXkpCiAgZW5kCiAgcmV0dXJuIGtleXMKZW5kCgotLS0gUmV0dXJucyB0aGUgdmFsdWVzIG9mIGEgdGFibGUuCi0tIEB1c2FnZSB1dGlscy52YWx1ZXModCkKLS0gQHVzYWdlIHV0aWxzLnZhbHVlcyh7bmFtZSA9ICJMdWEiLCBhZ2UgPSAyNX0pIC0tPiB7Ikx1YSIsIDI1fQotLSBAdHBhcmFtIHt0YWJsZX0gdCBUaGUgdGFibGUgdG8gZ2V0IHRoZSB2YWx1ZXMgZnJvbQotLSBAdHJldHVybiB7dGFibGU8QXJyYXk+fSBUaGUgdmFsdWVzIG9mIHRoZSB0YWJsZQp1dGlscy52YWx1ZXMgPSBmdW5jdGlvbiAodCkKICBhc3NlcnQodHlwZSh0KSA9PSAidGFibGUiLCAiYXJndW1lbnQgbmVlZHMgdG8gYmUgYSB0YWJsZSIpCiAgbG9jYWwgdmFsdWVzID0ge30KICBmb3IgXywgdmFsdWUgaW4gcGFpcnModCkgZG8KICAgIHRhYmxlLmluc2VydCh2YWx1ZXMsIHZhbHVlKQogIGVuZAogIHJldHVybiB2YWx1ZXMKZW5kCgotLS0gQ29udmVydCBhIG1lc3NhZ2UncyB0YWdzIHRvIGEgdGFibGUgb2Yga2V5LXZhbHVlIHBhaXJzCi0tIEBmdW5jdGlvbiBUYWIKLS0gQHRwYXJhbSB7dGFibGV9IG1zZyBUaGUgbWVzc2FnZSBjb250YWluaW5nIHRhZ3MKLS0gQHRyZXR1cm4ge3RhYmxlfSBBIHRhYmxlIHdpdGggdGFnIG5hbWVzIGFzIGtleXMgYW5kIHRoZWlyIHZhbHVlcwpmdW5jdGlvbiB1dGlscy5UYWIobXNnKQogIGxvY2FsIGlucHV0cyA9IHt9CiAgZm9yIF8sIG8gaW4gaXBhaXJzKG1zZy5UYWdzKSBkbwogICAgaWYgbm90IGlucHV0c1tvLm5hbWVdIHRoZW4KICAgICAgaW5wdXRzW28ubmFtZV0gPSBvLnZhbHVlCiAgICBlbmQKICBlbmQKICByZXR1cm4gaW5wdXRzCmVuZAoKCnJldHVybiB1dGlscwoKZW5kCl9HLnBhY2thZ2UubG9hZGVkWyIudXRpbHMiXSA9IGxvYWRfdXRpbHMoKQpwcmludCgibG9hZGVkIHV0aWxzIikKICAKCgpsb2NhbCBmdW5jdGlvbiBsb2FkX2hhbmRsZXJzX3V0aWxzKCkgCiAgLS0tIFRoZSBIYW5kbGVyIFV0aWxzIG1vZHVsZSBpcyBhIGxpZ2h0d2VpZ2h0IEx1YSB1dGlsaXR5IGxpYnJhcnkgZGVzaWduZWQgdG8gcHJvdmlkZSBjb21tb24gZnVuY3Rpb25hbGl0aWVzIGZvciBoYW5kbGluZyBhbmQgcHJvY2Vzc2luZyBtZXNzYWdlcyB3aXRoaW4gdGhlIEFPUyBjb21wdXRlciBzeXN0ZW0uIEl0IG9mZmVycyBhIHNldCBvZiBmdW5jdGlvbnMgdG8gY2hlY2sgbWVzc2FnZSBhdHRyaWJ1dGVzIGFuZCBzZW5kIHJlcGxpZXMsIHNpbXBsaWZ5aW5nIHRoZSBkZXZlbG9wbWVudCBvZiBtb3JlIGNvbXBsZXggc2NyaXB0cyBhbmQgbW9kdWxlcy4gVGhpcyBkb2N1bWVudCB3aWxsIGd1aWRlIHlvdSB0aHJvdWdoIHRoZSBtb2R1bGUncyBmdW5jdGlvbmFsaXRpZXMsIGluc3RhbGxhdGlvbiwgYW5kIHVzYWdlLiBSZXR1cm5zIHRoZSBfdXRpbHMgdGFibGUuCi0tIEBtb2R1bGUgaGFuZGxlcnMtdXRpbHMKCi0tLSBUaGUgX3V0aWxzIHRhYmxlCi0tIEB0YWJsZSBfdXRpbHMKLS0gQGZpZWxkIF92ZXJzaW9uIFRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUgX3V0aWxzIG1vZHVsZQotLSBAZmllbGQgaGFzTWF0Y2hpbmdUYWcgVGhlIGhhc01hdGNoaW5nVGFnIGZ1bmN0aW9uCi0tIEBmaWVsZCBoYXNNYXRjaGluZ1RhZ09mIFRoZSBoYXNNYXRjaGluZ1RhZ09mIGZ1bmN0aW9uCi0tIEBmaWVsZCBoYXNNYXRjaGluZ0RhdGEgVGhlIGhhc01hdGNoaW5nRGF0YSBmdW5jdGlvbgotLSBAZmllbGQgcmVwbHkgVGhlIHJlcGx5IGZ1bmN0aW9uCi0tIEBmaWVsZCBjb250aW51ZSBUaGUgY29udGludWUgZnVuY3Rpb24KbG9jYWwgX3V0aWxzID0geyBfdmVyc2lvbiA9ICIwLjAuMiIgfQoKbG9jYWwgXyA9IHJlcXVpcmUoJy51dGlscycpCgotLS0gQ2hlY2tzIGlmIGEgZ2l2ZW4gbWVzc2FnZSBoYXMgYSB0YWcgdGhhdCBtYXRjaGVzIHRoZSBzcGVjaWZpZWQgbmFtZSBhbmQgdmFsdWUuCi0tIEBmdW5jdGlvbiBoYXNNYXRjaGluZ1RhZwotLSBAdHBhcmFtIHtzdHJpbmd9IG5hbWUgVGhlIHRhZyBuYW1lIHRvIGNoZWNrCi0tIEB0cGFyYW0ge3N0cmluZ30gdmFsdWUgVGhlIHZhbHVlIHRvIG1hdGNoIGZvciBpbiB0aGUgdGFnCi0tIEB0cmV0dXJuIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0aGF0IHRha2VzIGEgbWVzc2FnZSBhbmQgcmV0dXJucyB3aGV0aGVyIHRoZXJlIGlzIGEgdGFnIG1hdGNoICgtMSBpZiBtYXRjaGVzLCAwIG90aGVyd2lzZSkKZnVuY3Rpb24gX3V0aWxzLmhhc01hdGNoaW5nVGFnKG5hbWUsIHZhbHVlKQogIGFzc2VydCh0eXBlKG5hbWUpID09ICdzdHJpbmcnIGFuZCB0eXBlKHZhbHVlKSA9PSAnc3RyaW5nJywgJ2ludmFsaWQgYXJndW1lbnRzOiAobmFtZSA6IHN0cmluZywgdmFsdWUgOiBzdHJpbmcpJykKCiAgcmV0dXJuIGZ1bmN0aW9uIChtc2cpCiAgICByZXR1cm4gbXNnLlRhZ3NbbmFtZV0gPT0gdmFsdWUKICBlbmQKZW5kCgotLS0gQ2hlY2tzIGlmIGEgZ2l2ZW4gbWVzc2FnZSBoYXMgYSB0YWcgdGhhdCBtYXRjaGVzIHRoZSBzcGVjaWZpZWQgbmFtZSBhbmQgb25lIG9mIHRoZSBzcGVjaWZpZWQgdmFsdWVzLgotLSBAZnVuY3Rpb24gaGFzTWF0Y2hpbmdUYWdPZgotLSBAdHBhcmFtIHtzdHJpbmd9IG5hbWUgVGhlIHRhZyBuYW1lIHRvIGNoZWNrCi0tIEB0cGFyYW0ge3N0cmluZ1tdfSB2YWx1ZXMgVGhlIGxpc3Qgb2YgdmFsdWVzIG9mIHdoaWNoIG9uZSBzaG91bGQgbWF0Y2gKLS0gQHRyZXR1cm4ge2Z1bmN0aW9ufSBBIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYSBtZXNzYWdlIGFuZCByZXR1cm5zIHdoZXRoZXIgdGhlcmUgaXMgYSB0YWcgbWF0Y2ggKC0xIGlmIG1hdGNoZXMsIDAgb3RoZXJ3aXNlKQpmdW5jdGlvbiBfdXRpbHMuaGFzTWF0Y2hpbmdUYWdPZihuYW1lLCB2YWx1ZXMpCiAgYXNzZXJ0KHR5cGUobmFtZSkgPT0gJ3N0cmluZycgYW5kIHR5cGUodmFsdWVzKSA9PSAndGFibGUnLCAnaW52YWxpZCBhcmd1bWVudHM6IChuYW1lIDogc3RyaW5nLCB2YWx1ZXMgOiBzdHJpbmdbXSknKQogIHJldHVybiBmdW5jdGlvbiAobXNnKQogICAgZm9yIF8sIHZhbHVlIGluIGlwYWlycyh2YWx1ZXMpIGRvCiAgICAgIGxvY2FsIHBhdHRlcm5SZXN1bHQgPSBIYW5kbGVycy51dGlscy5oYXNNYXRjaGluZ1RhZyhuYW1lLCB2YWx1ZSkobXNnKQoKICAgICAgaWYgcGF0dGVyblJlc3VsdCB+PSAwIGFuZCBwYXR0ZXJuUmVzdWx0IH49IGZhbHNlIGFuZCBwYXR0ZXJuUmVzdWx0IH49ICJza2lwIiB0aGVuCiAgICAgICAgcmV0dXJuIHBhdHRlcm5SZXN1bHQKICAgICAgZW5kCiAgICBlbmQKCiAgICByZXR1cm4gMAogIGVuZAplbmQKCi0tLSBDaGVja3MgaWYgYSBnaXZlbiBtZXNzYWdlIGhhcyBkYXRhIHRoYXQgbWF0Y2hlcyB0aGUgc3BlY2lmaWVkIHZhbHVlLgotLSBAZnVuY3Rpb24gaGFzTWF0Y2hpbmdEYXRhCi0tIEB0cGFyYW0ge3N0cmluZ30gdmFsdWUgVGhlIHZhbHVlIHRvIG1hdGNoIGFnYWluc3QgdGhlIG1lc3NhZ2UgZGF0YQotLSBAdHJldHVybiB7ZnVuY3Rpb259IEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhIG1lc3NhZ2UgYW5kIHJldHVybnMgd2hldGhlciB0aGUgZGF0YSBtYXRjaGVzIHRoZSB2YWx1ZSAoLTEgaWYgbWF0Y2hlcywgMCBvdGhlcndpc2UpCmZ1bmN0aW9uIF91dGlscy5oYXNNYXRjaGluZ0RhdGEodmFsdWUpCiAgYXNzZXJ0KHR5cGUodmFsdWUpID09ICdzdHJpbmcnLCAnaW52YWxpZCBhcmd1bWVudHM6ICh2YWx1ZSA6IHN0cmluZyknKQogIHJldHVybiBmdW5jdGlvbiAobXNnKQogICAgcmV0dXJuIG1zZy5EYXRhID09IHZhbHVlCiAgZW5kCmVuZAoKLS0tIEdpdmVuIGFuIGlucHV0LCByZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhIG1lc3NhZ2UgYW5kIHJlcGxpZXMgdG8gaXQuCi0tIEBmdW5jdGlvbiByZXBseQotLSBAdHBhcmFtIHt0YWJsZSB8IHN0cmluZ30gaW5wdXQgVGhlIGNvbnRlbnQgdG8gc2VuZCBiYWNrLiBJZiBhIHN0cmluZywgaXQgc2VuZHMgaXQgYXMgZGF0YS4gSWYgYSB0YWJsZSwgaXQgYXNzdW1lcyBhIHN0cnVjdHVyZSB3aXRoIGBUYWdzYC4KLS0gQHRyZXR1cm4ge2Z1bmN0aW9ufSBBIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYSBtZXNzYWdlIGFuZCByZXBsaWVzIHRvIGl0CmZ1bmN0aW9uIF91dGlscy5yZXBseShpbnB1dCkgCiAgYXNzZXJ0KHR5cGUoaW5wdXQpID09ICd0YWJsZScgb3IgdHlwZShpbnB1dCkgPT0gJ3N0cmluZycsICdpbnZhbGlkIGFyZ3VtZW50czogKGlucHV0IDogdGFibGUgb3Igc3RyaW5nKScpCiAgcmV0dXJuIGZ1bmN0aW9uIChtc2cpCiAgICBpZiB0eXBlKGlucHV0KSA9PSAnc3RyaW5nJyB0aGVuCiAgICAgIG1zZy5yZXBseSh7IERhdGEgPSBpbnB1dCB9KQogICAgICByZXR1cm4KICAgIGVuZAogICAgbXNnLnJlcGx5KGlucHV0KQogIGVuZAplbmQKCi0tLSBJbnZlcnRzIHRoZSBwcm92aWRlZCBwYXR0ZXJuJ3MgcmVzdWx0IGlmIGl0IG1hdGNoZXMsIHNvIHRoYXQgaXQgY29udGludWVzIGV4ZWN1dGlvbiB3aXRoIHRoZSBuZXh0IG1hdGNoaW5nIGhhbmRsZXIuCi0tIEBmdW5jdGlvbiBjb250aW51ZQotLSBAdHBhcmFtIHt0YWJsZSB8IGZ1bmN0aW9ufSBwYXR0ZXJuIFRoZSBwYXR0ZXJuIHRvIGNoZWNrIGZvciBpbiB0aGUgbWVzc2FnZQotLSBAdHJldHVybiB7ZnVuY3Rpb259IEZ1bmN0aW9uIHRoYXQgZXhlY3V0ZXMgdGhlIHBhdHRlcm4gbWF0Y2hpbmcgZnVuY3Rpb24gYW5kIHJldHVybnMgYDFgIChjb250aW51ZSksIHNvIHRoYXQgdGhlIGV4ZWN1dGlvbiBvZiBoYW5kbGVycyBjb250aW51ZXMuCmZ1bmN0aW9uIF91dGlscy5jb250aW51ZShwYXR0ZXJuKQogIHJldHVybiBmdW5jdGlvbiAobXNnKQogICAgbG9jYWwgbWF0Y2ggPSBfLm1hdGNoZXNTcGVjKG1zZywgcGF0dGVybikKCiAgICBpZiBub3QgbWF0Y2ggb3IgbWF0Y2ggPT0gMCBvciBtYXRjaCA9PSAic2tpcCIgdGhlbgogICAgICByZXR1cm4gbWF0Y2gKICAgIGVuZAogICAgcmV0dXJuIDEKICBlbmQKZW5kCgpyZXR1cm4gX3V0aWxzCgplbmQKX0cucGFja2FnZS5sb2FkZWRbIi5oYW5kbGVycy11dGlscyJdID0gbG9hZF9oYW5kbGVyc191dGlscygpCnByaW50KCJsb2FkZWQgaGFuZGxlcnMtdXRpbHMiKQogIAoKCmxvY2FsIGZ1bmN0aW9uIGxvYWRfaGFuZGxlcnMoKSAKICAtLS0gVGhlIEhhbmRsZXJzIGxpYnJhcnkgcHJvdmlkZXMgYSBmbGV4aWJsZSB3YXkgdG8gbWFuYWdlIGFuZCBleGVjdXRlIGEgc2VyaWVzIG9mIGhhbmRsZXJzIGJhc2VkIG9uIHBhdHRlcm5zLiBFYWNoIGhhbmRsZXIgY29uc2lzdHMgb2YgYSBwYXR0ZXJuIGZ1bmN0aW9uLCBhIGhhbmRsZSBmdW5jdGlvbiwgYW5kIGEgbmFtZS4gVGhpcyBsaWJyYXJ5IGlzIHN1aXRhYmxlIGZvciBzY2VuYXJpb3Mgd2hlcmUgZGlmZmVyZW50IGFjdGlvbnMgbmVlZCB0byBiZSB0YWtlbiBiYXNlZCBvbiB2YXJ5aW5nIGlucHV0IGNyaXRlcmlhLiBSZXR1cm5zIHRoZSBoYW5kbGVycyB0YWJsZS4KLS0gQG1vZHVsZSBoYW5kbGVycwoKLS0tIFRoZSBoYW5kbGVycyB0YWJsZQotLSBAdGFibGUgaGFuZGxlcnMKLS0gQGZpZWxkIF92ZXJzaW9uIFRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUgaGFuZGxlcnMgbW9kdWxlCi0tIEBmaWVsZCBsaXN0IFRoZSBsaXN0IG9mIGhhbmRsZXJzCi0tIEBmaWVsZCBvbmNlTm9uY2UgVGhlIG5vbmNlIGZvciB0aGUgb25jZSBoYW5kbGVycwotLSBAZmllbGQgdXRpbHMgVGhlIGhhbmRsZXJzLXV0aWxzIG1vZHVsZQotLSBAZmllbGQgZ2VuZXJhdGVSZXNvbHZlciBUaGUgZ2VuZXJhdGVSZXNvbHZlciBmdW5jdGlvbgotLSBAZmllbGQgcmVjZWl2ZSBUaGUgcmVjZWl2ZSBmdW5jdGlvbgotLSBAZmllbGQgb25jZSBUaGUgb25jZSBmdW5jdGlvbgotLSBAZmllbGQgYWRkIFRoZSBhZGQgZnVuY3Rpb24KLS0gQGZpZWxkIGFwcGVuZCBUaGUgYXBwZW5kIGZ1bmN0aW9uCi0tIEBmaWVsZCBwcmVwZW5kIFRoZSBwcmVwZW5kIGZ1bmN0aW9uCi0tIEBmaWVsZCByZW1vdmUgVGhlIHJlbW92ZSBmdW5jdGlvbgotLSBAZmllbGQgZXZhbHVhdGUgVGhlIGV2YWx1YXRlIGZ1bmN0aW9uCmxvY2FsIGhhbmRsZXJzID0geyBfdmVyc2lvbiA9ICIwLjAuNSIgfQpsb2NhbCB1dGlscyA9IHJlcXVpcmUoJy51dGlscycpCgpoYW5kbGVycy51dGlscyA9IHJlcXVpcmUoJy5oYW5kbGVycy11dGlscycpCi0tIGlmIHVwZGF0ZSB3ZSBuZWVkIHRvIGtlZXAgZGVmaW5lZCBoYW5kbGVycwppZiBIYW5kbGVycyB0aGVuCiAgaGFuZGxlcnMubGlzdCA9IEhhbmRsZXJzLmxpc3Qgb3Ige30KZWxzZQogIGhhbmRsZXJzLmxpc3QgPSB7fQplbmQKaGFuZGxlcnMub25jZU5vbmNlID0gMAoKLS0tIEdpdmVuIGFuIGFycmF5LCBhIHByb3BlcnR5IG5hbWUsIGFuZCBhIHZhbHVlLCByZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgb2JqZWN0IGluIHRoZSBhcnJheSB0aGF0IGhhcyB0aGUgcHJvcGVydHkgd2l0aCB0aGUgdmFsdWUuCi0tIEBsZnVuY3Rpb24gZmluZEluZGV4QnlQcm9wCi0tIEB0cGFyYW0ge3RhYmxlW119IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2ggdGhyb3VnaAotLSBAdHBhcmFtIHtzdHJpbmd9IHByb3AgVGhlIHByb3BlcnR5IG5hbWUgdG8gY2hlY2sKLS0gQHRwYXJhbSB7YW55fSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2sgZm9yIGluIHRoZSBwcm9wZXJ0eQotLSBAdHJldHVybiB7bnVtYmVyIHwgbmlsfSBUaGUgaW5kZXggb2YgdGhlIG9iamVjdCBpbiB0aGUgYXJyYXkgdGhhdCBoYXMgdGhlIHByb3BlcnR5IHdpdGggdGhlIHZhbHVlLCBvciBuaWwgaWYgbm8gc3VjaCBvYmplY3QgaXMgZm91bmQKbG9jYWwgZnVuY3Rpb24gZmluZEluZGV4QnlQcm9wKGFycmF5LCBwcm9wLCB2YWx1ZSkKICBmb3IgaW5kZXgsIG9iamVjdCBpbiBpcGFpcnMoYXJyYXkpIGRvCiAgICBpZiBvYmplY3RbcHJvcF0gPT0gdmFsdWUgdGhlbgogICAgICByZXR1cm4gaW5kZXgKICAgIGVuZAogIGVuZAogIHJldHVybiBuaWwKZW5kCgotLS0gR2l2ZW4gYSBuYW1lLCBhIHBhdHRlcm4sIGFuZCBhIGhhbmRsZSwgYXNzZXJ0cyB0aGF0IHRoZSBhcmd1bWVudHMgYXJlIHZhbGlkLgotLSBAbGZ1bmN0aW9uIGFzc2VydEFkZEFyZ3MKLS0gQHRwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBoYW5kbGVyCi0tIEB0cGFyYW0ge3RhYmxlIHwgZnVuY3Rpb24gfCBzdHJpbmd9IHBhdHRlcm4gVGhlIHBhdHRlcm4gdG8gY2hlY2sgZm9yIGluIHRoZSBtZXNzYWdlCi0tIEB0cGFyYW0ge2Z1bmN0aW9ufSBoYW5kbGUgVGhlIGZ1bmN0aW9uIHRvIGNhbGwgaWYgdGhlIHBhdHRlcm4gbWF0Y2hlcwotLSBAdHBhcmFtIHtudW1iZXIgfCBzdHJpbmcgfCBuaWx9IG1heFJ1bnMgVGhlIG1heGltdW0gbnVtYmVyIG9mIHRpbWVzIHRoZSBoYW5kbGVyIHNob3VsZCBydW4sIG9yIG5pbCBpZiB0aGVyZSBpcyBubyBsaW1pdApsb2NhbCBmdW5jdGlvbiBhc3NlcnRBZGRBcmdzKG5hbWUsIHBhdHRlcm4sIGhhbmRsZSwgbWF4UnVucykKICBhc3NlcnQoCiAgICB0eXBlKG5hbWUpID09ICdzdHJpbmcnIGFuZAogICAgKHR5cGUocGF0dGVybikgPT0gJ2Z1bmN0aW9uJyBvciB0eXBlKHBhdHRlcm4pID09ICd0YWJsZScgb3IgdHlwZShwYXR0ZXJuKSA9PSAnc3RyaW5nJyksCiAgICAnSW52YWxpZCBhcmd1bWVudHMgZ2l2ZW4uIEV4cGVjdGVkOiBcbicgLi4KICAgICdcdG5hbWUgOiBzdHJpbmcsICcgLi4KICAgICdcdHBhdHRlcm4gOiBhY3Rpb24gOiBzdHJpbmcgfCBNc2dNYXRjaCA6IHRhYmxlLFxuJyAuLgogICAgJ1x0XHRmdW5jdGlvbihtc2c6IE1lc3NhZ2UpIDogey0xID0gYnJlYWssIDAgPSBza2lwLCAxID0gY29udGludWV9LFxuJyAuLgogICAgJ1x0aGFuZGxlKG1zZyA6IE1lc3NhZ2UpIDogdm9pZCkgfCBSZXNvbHZlcixcbicgLi4KICAgICdcdE1heFJ1bnM/IDogbnVtYmVyIHwgImluZiIgfCBuaWwnKQplbmQKCi0tLSBHaXZlbiBhIHJlc29sdmVyIHNwZWNpZmljYXRpb24sIHJldHVybnMgYSByZXNvbHZlciBmdW5jdGlvbi4KLS0gQGZ1bmN0aW9uIGdlbmVyYXRlUmVzb2x2ZXIKLS0gQHRwYXJhbSB7dGFibGUgfCBmdW5jdGlvbn0gcmVzb2x2ZVNwZWMgVGhlIHJlc29sdmVyIHNwZWNpZmljYXRpb24KLS0gQHRyZXR1cm4ge2Z1bmN0aW9ufSBBIHJlc29sdmVyIGZ1bmN0aW9uCmZ1bmN0aW9uIGhhbmRsZXJzLmdlbmVyYXRlUmVzb2x2ZXIocmVzb2x2ZVNwZWMpCiAgcmV0dXJuIGZ1bmN0aW9uKG1zZykKICAgIC0tIElmIHRoZSByZXNvbHZlciBpcyBhIHNpbmdsZSBmdW5jdGlvbiwgY2FsbCBpdC4KICAgIC0tIEVsc2UsIGZpbmQgdGhlIGZpcnN0IG1hdGNoaW5nIHBhdHRlcm4gKGJ5IGl0cyBtYXRjaFNwZWMpLCBhbmQgZXhlYy4KICAgIGlmIHR5cGUocmVzb2x2ZVNwZWMpID09ICJmdW5jdGlvbiIgdGhlbgogICAgICByZXR1cm4gcmVzb2x2ZVNwZWMobXNnKQogICAgZWxzZQogICAgICAgIGZvciBtYXRjaFNwZWMsIGZ1bmMgaW4gcGFpcnMocmVzb2x2ZVNwZWMpIGRvCiAgICAgICAgICAgIGlmIHV0aWxzLm1hdGNoZXNTcGVjKG1zZywgbWF0Y2hTcGVjKSB0aGVuCiAgICAgICAgICAgICAgICByZXR1cm4gZnVuYyhtc2cpCiAgICAgICAgICAgIGVuZAogICAgICAgIGVuZAogICAgZW5kCiAgZW5kCmVuZAoKLS0tIEdpdmVuIGEgcGF0dGVybiwgcmV0dXJucyB0aGUgbmV4dCBtZXNzYWdlIHRoYXQgbWF0Y2hlcyB0aGUgcGF0dGVybi4KLS0gVGhpcyBmdW5jdGlvbiB1c2VzIEx1YSdzIGNvcm91dGluZXMgdW5kZXItdGhlLWhvb2QgdG8gYWRkIGEgaGFuZGxlciwgcGF1c2UsCi0tIGFuZCB0aGVuIHJlc3VtZSB0aGUgY3VycmVudCBjb3JvdXRpbmUuIFRoaXMgYWxsb3dzIHVzIHRvIGVmZmVjdGl2ZWx5IGJsb2NrCi0tIHByb2Nlc3Npbmcgb2Ygb25lIG1lc3NhZ2UgdW50aWwgYW5vdGhlciBpcyByZWNlaXZlZCB0aGF0IG1hdGNoZXMgdGhlIHBhdHRlcm4uCi0tIEBmdW5jdGlvbiByZWNlaXZlCi0tIEB0cGFyYW0ge3RhYmxlIHwgZnVuY3Rpb259IHBhdHRlcm4gVGhlIHBhdHRlcm4gdG8gY2hlY2sgZm9yIGluIHRoZSBtZXNzYWdlCmZ1bmN0aW9uIGhhbmRsZXJzLnJlY2VpdmUocGF0dGVybikKICByZXR1cm4gJ25vdCBpbXBsZW1lbnRlZCcKZW5kCgotLS0gR2l2ZW4gYSBuYW1lLCBhIHBhdHRlcm4sIGFuZCBhIGhhbmRsZSwgYWRkcyBhIGhhbmRsZXIgdG8gdGhlIGxpc3QuCi0tIElmIG5hbWUgaXMgbm90IHByb3ZpZGVkLCAiX29uY2VfIiBwcmVmaXggcGx1cyBvbmNlTm9uY2Ugd2lsbCBiZSB1c2VkIGFzIHRoZSBuYW1lLgotLSBBZGRzIGhhbmRsZXIgd2l0aCBtYXhSdW5zIG9mIDEgc3VjaCB0aGF0IGl0IHdpbGwgb25seSBiZSBjYWxsZWQgb25jZSB0aGVuIHJlbW92ZWQgZnJvbSB0aGUgbGlzdC4KLS0gQGZ1bmN0aW9uIG9uY2UKLS0gQHRwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBoYW5kbGVyCi0tIEB0cGFyYW0ge3RhYmxlIHwgZnVuY3Rpb24gfCBzdHJpbmd9IHBhdHRlcm4gVGhlIHBhdHRlcm4gdG8gY2hlY2sgZm9yIGluIHRoZSBtZXNzYWdlCi0tIEB0cGFyYW0ge2Z1bmN0aW9ufSBoYW5kbGUgVGhlIGZ1bmN0aW9uIHRvIGNhbGwgaWYgdGhlIHBhdHRlcm4gbWF0Y2hlcwpmdW5jdGlvbiBoYW5kbGVycy5vbmNlKC4uLikKICBsb2NhbCBuYW1lLCBwYXR0ZXJuLCBoYW5kbGUKICBpZiBzZWxlY3QoIiMiLCAuLi4pID09IDMgdGhlbgogICAgbmFtZSA9IHNlbGVjdCgxLCAuLi4pCiAgICBwYXR0ZXJuID0gc2VsZWN0KDIsIC4uLikKICAgIGhhbmRsZSA9IHNlbGVjdCgzLCAuLi4pCiAgZWxzZQogICAgbmFtZSA9ICJfb25jZV8iIC4uIHRvc3RyaW5nKGhhbmRsZXJzLm9uY2VOb25jZSkKICAgIGhhbmRsZXJzLm9uY2VOb25jZSA9IGhhbmRsZXJzLm9uY2VOb25jZSArIDEKICAgIHBhdHRlcm4gPSBzZWxlY3QoMSwgLi4uKQogICAgaGFuZGxlID0gc2VsZWN0KDIsIC4uLikKICBlbmQKICBoYW5kbGVycy5wcmVwZW5kKG5hbWUsIHBhdHRlcm4sIGhhbmRsZSwgMSkKZW5kCgotLS0gR2l2ZW4gYSBuYW1lLCBhIHBhdHRlcm4sIGFuZCBhIGhhbmRsZSwgYWRkcyBhIGhhbmRsZXIgdG8gdGhlIGxpc3QuCi0tIEBmdW5jdGlvbiBhZGQKLS0gQHRwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBoYW5kbGVyCi0tIEB0cGFyYW0ge3RhYmxlIHwgZnVuY3Rpb24gfCBzdHJpbmd9IHBhdHRlcm4gVGhlIHBhdHRlcm4gdG8gY2hlY2sgZm9yIGluIHRoZSBtZXNzYWdlCi0tIEB0cGFyYW0ge2Z1bmN0aW9ufSBoYW5kbGUgVGhlIGZ1bmN0aW9uIHRvIGNhbGwgaWYgdGhlIHBhdHRlcm4gbWF0Y2hlcwotLSBAdHBhcmFtIHtudW1iZXIgfCBzdHJpbmcgfCBuaWx9IG1heFJ1bnMgVGhlIG1heGltdW0gbnVtYmVyIG9mIHRpbWVzIHRoZSBoYW5kbGVyIHNob3VsZCBydW4sIG9yIG5pbCBpZiB0aGVyZSBpcyBubyBsaW1pdApmdW5jdGlvbiBoYW5kbGVycy5hZGQoLi4uKQogIGxvY2FsIG5hbWUsIHBhdHRlcm4sIGhhbmRsZSwgbWF4UnVucwogIGxvY2FsIGFyZ3MgPSBzZWxlY3QoIiMiLCAuLi4pCiAgaWYgYXJncyA9PSAyIHRoZW4KICAgIG5hbWUgPSBzZWxlY3QoMSwgLi4uKQogICAgcGF0dGVybiA9IHNlbGVjdCgxLCAuLi4pCiAgICBoYW5kbGUgPSBzZWxlY3QoMiwgLi4uKQogICAgbWF4UnVucyA9IG5pbAogIGVsc2VpZiBhcmdzID09IDMgdGhlbgogICAgbmFtZSA9IHNlbGVjdCgxLCAuLi4pCiAgICBwYXR0ZXJuID0gc2VsZWN0KDIsIC4uLikKICAgIGhhbmRsZSA9IHNlbGVjdCgzLCAuLi4pCiAgICBtYXhSdW5zID0gbmlsCiAgZWxzZQogICAgbmFtZSA9IHNlbGVjdCgxLCAuLi4pCiAgICBwYXR0ZXJuID0gc2VsZWN0KDIsIC4uLikKICAgIGhhbmRsZSA9IHNlbGVjdCgzLCAuLi4pCiAgICBtYXhSdW5zID0gc2VsZWN0KDQsIC4uLikKICBlbmQKICBhc3NlcnRBZGRBcmdzKG5hbWUsIHBhdHRlcm4sIGhhbmRsZSwgbWF4UnVucykKCiAgaGFuZGxlID0gaGFuZGxlcnMuZ2VuZXJhdGVSZXNvbHZlcihoYW5kbGUpCgogIC0tIHVwZGF0ZSBleGlzdGluZyBoYW5kbGVyIGJ5IG5hbWUKICBsb2NhbCBpZHggPSBmaW5kSW5kZXhCeVByb3AoaGFuZGxlcnMubGlzdCwgIm5hbWUiLCBuYW1lKQogIGlmIGlkeCB+PSBuaWwgYW5kIGlkeCA+IDAgdGhlbgogICAgLS0gZm91bmQgdXBkYXRlCiAgICBoYW5kbGVycy5saXN0W2lkeF0ucGF0dGVybiA9IHBhdHRlcm4KICAgIGhhbmRsZXJzLmxpc3RbaWR4XS5oYW5kbGUgPSBoYW5kbGUKICAgIGhhbmRsZXJzLmxpc3RbaWR4XS5tYXhSdW5zID0gbWF4UnVucwogIGVsc2UKICAgIC0tIG5vdCBmb3VuZCB0aGVuIGFkZCAgICAKICAgIHRhYmxlLmluc2VydChoYW5kbGVycy5saXN0LCB7IHBhdHRlcm4gPSBwYXR0ZXJuLCBoYW5kbGUgPSBoYW5kbGUsIG5hbWUgPSBuYW1lLCBtYXhSdW5zID0gbWF4UnVucyB9KQoKICBlbmQKICByZXR1cm4gI2hhbmRsZXJzLmxpc3QKZW5kCgotLS0gQXBwZW5kcyBhIG5ldyBoYW5kbGVyIHRvIHRoZSBlbmQgb2YgdGhlIGhhbmRsZXJzIGxpc3QuCi0tIEBmdW5jdGlvbiBhcHBlbmQKLS0gQHRwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBoYW5kbGVyCi0tIEB0cGFyYW0ge3RhYmxlIHwgZnVuY3Rpb24gfCBzdHJpbmd9IHBhdHRlcm4gVGhlIHBhdHRlcm4gdG8gY2hlY2sgZm9yIGluIHRoZSBtZXNzYWdlCi0tIEB0cGFyYW0ge2Z1bmN0aW9ufSBoYW5kbGUgVGhlIGZ1bmN0aW9uIHRvIGNhbGwgaWYgdGhlIHBhdHRlcm4gbWF0Y2hlcwotLSBAdHBhcmFtIHtudW1iZXIgfCBzdHJpbmcgfCBuaWx9IG1heFJ1bnMgVGhlIG1heGltdW0gbnVtYmVyIG9mIHRpbWVzIHRoZSBoYW5kbGVyIHNob3VsZCBydW4sIG9yIG5pbCBpZiB0aGVyZSBpcyBubyBsaW1pdApmdW5jdGlvbiBoYW5kbGVycy5hcHBlbmQoLi4uKQogIGxvY2FsIG5hbWUsIHBhdHRlcm4sIGhhbmRsZSwgbWF4UnVucwogIGxvY2FsIGFyZ3MgPSBzZWxlY3QoIiMiLCAuLi4pCiAgaWYgYXJncyA9PSAyIHRoZW4KICAgIG5hbWUgPSBzZWxlY3QoMSwgLi4uKQogICAgcGF0dGVybiA9IHNlbGVjdCgxLCAuLi4pCiAgICBoYW5kbGUgPSBzZWxlY3QoMiwgLi4uKQogICAgbWF4UnVucyA9IG5pbAogIGVsc2VpZiBhcmdzID09IDMgdGhlbgogICAgbmFtZSA9IHNlbGVjdCgxLCAuLi4pCiAgICBwYXR0ZXJuID0gc2VsZWN0KDIsIC4uLikKICAgIGhhbmRsZSA9IHNlbGVjdCgzLCAuLi4pCiAgICBtYXhSdW5zID0gbmlsCiAgZWxzZQogICAgbmFtZSA9IHNlbGVjdCgxLCAuLi4pCiAgICBwYXR0ZXJuID0gc2VsZWN0KDIsIC4uLikKICAgIGhhbmRsZSA9IHNlbGVjdCgzLCAuLi4pCiAgICBtYXhSdW5zID0gc2VsZWN0KDQsIC4uLikKICBlbmQKICBhc3NlcnRBZGRBcmdzKG5hbWUsIHBhdHRlcm4sIGhhbmRsZSwgbWF4UnVucykKCiAgaGFuZGxlID0gaGFuZGxlcnMuZ2VuZXJhdGVSZXNvbHZlcihoYW5kbGUpCiAgLS0gdXBkYXRlIGV4aXN0aW5nIGhhbmRsZXIgYnkgbmFtZQogIGxvY2FsIGlkeCA9IGZpbmRJbmRleEJ5UHJvcChoYW5kbGVycy5saXN0LCAibmFtZSIsIG5hbWUpCiAgaWYgaWR4IH49IG5pbCBhbmQgaWR4ID4gMCB0aGVuCiAgICAtLSBmb3VuZCB1cGRhdGUKICAgIGhhbmRsZXJzLmxpc3RbaWR4XS5wYXR0ZXJuID0gcGF0dGVybgogICAgaGFuZGxlcnMubGlzdFtpZHhdLmhhbmRsZSA9IGhhbmRsZQogICAgaGFuZGxlcnMubGlzdFtpZHhdLm1heFJ1bnMgPSBtYXhSdW5zCiAgZWxzZQogICAgdGFibGUuaW5zZXJ0KGhhbmRsZXJzLmxpc3QsIHsgcGF0dGVybiA9IHBhdHRlcm4sIGhhbmRsZSA9IGhhbmRsZSwgbmFtZSA9IG5hbWUsIG1heFJ1bnMgPSBtYXhSdW5zIH0pCiAgZW5kCmVuZAoKLS0tIFByZXBlbmRzIGEgbmV3IGhhbmRsZXIgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgaGFuZGxlcnMgbGlzdC4KLS0gQGZ1bmN0aW9uIHByZXBlbmQKLS0gQHRwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBoYW5kbGVyCi0tIEB0cGFyYW0ge3RhYmxlIHwgZnVuY3Rpb24gfCBzdHJpbmd9IHBhdHRlcm4gVGhlIHBhdHRlcm4gdG8gY2hlY2sgZm9yIGluIHRoZSBtZXNzYWdlCi0tIEB0cGFyYW0ge2Z1bmN0aW9ufSBoYW5kbGUgVGhlIGZ1bmN0aW9uIHRvIGNhbGwgaWYgdGhlIHBhdHRlcm4gbWF0Y2hlcwotLSBAdHBhcmFtIHtudW1iZXIgfCBzdHJpbmcgfCBuaWx9IG1heFJ1bnMgVGhlIG1heGltdW0gbnVtYmVyIG9mIHRpbWVzIHRoZSBoYW5kbGVyIHNob3VsZCBydW4sIG9yIG5pbCBpZiB0aGVyZSBpcyBubyBsaW1pdApmdW5jdGlvbiBoYW5kbGVycy5wcmVwZW5kKC4uLikKICBsb2NhbCBuYW1lLCBwYXR0ZXJuLCBoYW5kbGUsIG1heFJ1bnMKICBsb2NhbCBhcmdzID0gc2VsZWN0KCIjIiwgLi4uKQogIGlmIGFyZ3MgPT0gMiB0aGVuCiAgICBuYW1lID0gc2VsZWN0KDEsIC4uLikKICAgIHBhdHRlcm4gPSBzZWxlY3QoMSwgLi4uKQogICAgaGFuZGxlID0gc2VsZWN0KDIsIC4uLikKICAgIG1heFJ1bnMgPSBuaWwKICBlbHNlaWYgYXJncyA9PSAzIHRoZW4KICAgIG5hbWUgPSBzZWxlY3QoMSwgLi4uKQogICAgcGF0dGVybiA9IHNlbGVjdCgyLCAuLi4pCiAgICBoYW5kbGUgPSBzZWxlY3QoMywgLi4uKQogICAgbWF4UnVucyA9IG5pbAogIGVsc2UgCiAgICBuYW1lID0gc2VsZWN0KDEsIC4uLikKICAgIHBhdHRlcm4gPSBzZWxlY3QoMiwgLi4uKQogICAgaGFuZGxlID0gc2VsZWN0KDMsIC4uLikKICAgIG1heFJ1bnMgPSBzZWxlY3QoNCwgLi4uKQogIGVuZAogIGFzc2VydEFkZEFyZ3MobmFtZSwgcGF0dGVybiwgaGFuZGxlLCBtYXhSdW5zKQoKICBoYW5kbGUgPSBoYW5kbGVycy5nZW5lcmF0ZVJlc29sdmVyKGhhbmRsZSkKCiAgLS0gdXBkYXRlIGV4aXN0aW5nIGhhbmRsZXIgYnkgbmFtZQogIGxvY2FsIGlkeCA9IGZpbmRJbmRleEJ5UHJvcChoYW5kbGVycy5saXN0LCAibmFtZSIsIG5hbWUpCiAgaWYgaWR4IH49IG5pbCBhbmQgaWR4ID4gMCB0aGVuCiAgICAtLSBmb3VuZCB1cGRhdGUKICAgIGhhbmRsZXJzLmxpc3RbaWR4XS5wYXR0ZXJuID0gcGF0dGVybgogICAgaGFuZGxlcnMubGlzdFtpZHhdLmhhbmRsZSA9IGhhbmRsZQogICAgaGFuZGxlcnMubGlzdFtpZHhdLm1heFJ1bnMgPSBtYXhSdW5zCiAgZWxzZSAgCiAgICB0YWJsZS5pbnNlcnQoaGFuZGxlcnMubGlzdCwgMSwgeyBwYXR0ZXJuID0gcGF0dGVybiwgaGFuZGxlID0gaGFuZGxlLCBuYW1lID0gbmFtZSwgbWF4UnVucyA9IG1heFJ1bnMgfSkKICBlbmQKZW5kCgotLS0gUmV0dXJucyBhbiBvYmplY3QgdGhhdCBhbGxvd3MgYWRkaW5nIGEgbmV3IGhhbmRsZXIgYmVmb3JlIGEgc3BlY2lmaWVkIGhhbmRsZXIuCi0tIEBmdW5jdGlvbiBiZWZvcmUKLS0gQHRwYXJhbSB7c3RyaW5nfSBoYW5kbGVOYW1lIFRoZSBuYW1lIG9mIHRoZSBoYW5kbGVyIGJlZm9yZSB3aGljaCB0aGUgbmV3IGhhbmRsZXIgd2lsbCBiZSBhZGRlZAotLSBAdHJldHVybiB7dGFibGV9IEFuIG9iamVjdCB3aXRoIGFuIGBhZGRgIG1ldGhvZCB0byBpbnNlcnQgdGhlIG5ldyBoYW5kbGVyCmZ1bmN0aW9uIGhhbmRsZXJzLmJlZm9yZShoYW5kbGVOYW1lKQogIGFzc2VydCh0eXBlKGhhbmRsZU5hbWUpID09ICdzdHJpbmcnLCAnSGFuZGxlciBuYW1lIE1VU1QgYmUgYSBzdHJpbmcnKQoKICBsb2NhbCBpZHggPSBmaW5kSW5kZXhCeVByb3AoaGFuZGxlcnMubGlzdCwgIm5hbWUiLCBoYW5kbGVOYW1lKQogIHJldHVybiB7CiAgICBhZGQgPSBmdW5jdGlvbiAobmFtZSwgcGF0dGVybiwgaGFuZGxlLCBtYXhSdW5zKSAKICAgICAgYXNzZXJ0QWRkQXJncyhuYW1lLCBwYXR0ZXJuLCBoYW5kbGUsIG1heFJ1bnMpCiAgICAgIGhhbmRsZSA9IGhhbmRsZXJzLmdlbmVyYXRlUmVzb2x2ZXIoaGFuZGxlKQogICAgICBpZiBpZHggdGhlbgogICAgICAgIHRhYmxlLmluc2VydChoYW5kbGVycy5saXN0LCBpZHgsIHsgcGF0dGVybiA9IHBhdHRlcm4sIGhhbmRsZSA9IGhhbmRsZSwgbmFtZSA9IG5hbWUsIG1heFJ1bnMgPSBtYXhSdW5zIH0pCiAgICAgIGVuZAogICAgZW5kCiAgfQplbmQKCi0tLSBSZXR1cm5zIGFuIG9iamVjdCB0aGF0IGFsbG93cyBhZGRpbmcgYSBuZXcgaGFuZGxlciBhZnRlciBhIHNwZWNpZmllZCBoYW5kbGVyLgotLSBAZnVuY3Rpb24gYWZ0ZXIKLS0gQHRwYXJhbSB7c3RyaW5nfSBoYW5kbGVOYW1lIFRoZSBuYW1lIG9mIHRoZSBoYW5kbGVyIGFmdGVyIHdoaWNoIHRoZSBuZXcgaGFuZGxlciB3aWxsIGJlIGFkZGVkCi0tIEB0cmV0dXJuIHt0YWJsZX0gQW4gb2JqZWN0IHdpdGggYW4gYGFkZGAgbWV0aG9kIHRvIGluc2VydCB0aGUgbmV3IGhhbmRsZXIKZnVuY3Rpb24gaGFuZGxlcnMuYWZ0ZXIoaGFuZGxlTmFtZSkKICBhc3NlcnQodHlwZShoYW5kbGVOYW1lKSA9PSAnc3RyaW5nJywgJ0hhbmRsZXIgbmFtZSBNVVNUIGJlIGEgc3RyaW5nJykKICBsb2NhbCBpZHggPSBmaW5kSW5kZXhCeVByb3AoaGFuZGxlcnMubGlzdCwgIm5hbWUiLCBoYW5kbGVOYW1lKQogIHJldHVybiB7CiAgICBhZGQgPSBmdW5jdGlvbiAobmFtZSwgcGF0dGVybiwgaGFuZGxlLCBtYXhSdW5zKQogICAgICBhc3NlcnRBZGRBcmdzKG5hbWUsIHBhdHRlcm4sIGhhbmRsZSwgbWF4UnVucykKICAgICAgaGFuZGxlID0gaGFuZGxlcnMuZ2VuZXJhdGVSZXNvbHZlcihoYW5kbGUpCiAgICAgIGlmIGlkeCB0aGVuCiAgICAgICAgdGFibGUuaW5zZXJ0KGhhbmRsZXJzLmxpc3QsIGlkeCArIDEsIHsgcGF0dGVybiA9IHBhdHRlcm4sIGhhbmRsZSA9IGhhbmRsZSwgbmFtZSA9IG5hbWUsIG1heFJ1bnMgPSBtYXhSdW5zIH0pCiAgICAgIGVuZAogICAgZW5kCiAgfQoKZW5kCgotLS0gUmVtb3ZlcyBhIGhhbmRsZXIgZnJvbSB0aGUgaGFuZGxlcnMgbGlzdCBieSBuYW1lLgotLSBAZnVuY3Rpb24gcmVtb3ZlCi0tIEB0cGFyYW0ge3N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgaGFuZGxlciB0byBiZSByZW1vdmVkCmZ1bmN0aW9uIGhhbmRsZXJzLnJlbW92ZShuYW1lKQogIGFzc2VydCh0eXBlKG5hbWUpID09ICdzdHJpbmcnLCAnbmFtZSBNVVNUIGJlIHN0cmluZycpCiAgaWYgI2hhbmRsZXJzLmxpc3QgPT0gMSBhbmQgaGFuZGxlcnMubGlzdFsxXS5uYW1lID09IG5hbWUgdGhlbgogICAgaGFuZGxlcnMubGlzdCA9IHt9CiAgZW5kCgogIGxvY2FsIGlkeCA9IGZpbmRJbmRleEJ5UHJvcChoYW5kbGVycy5saXN0LCAibmFtZSIsIG5hbWUpCiAgaWYgaWR4IH49IG5pbCBhbmQgaWR4ID4gMCB0aGVuCiAgICB0YWJsZS5yZW1vdmUoaGFuZGxlcnMubGlzdCwgaWR4KQogIGVuZAplbmQKCi0tLSBFdmFsdWF0ZXMgZWFjaCBoYW5kbGVyIGFnYWluc3QgYSBnaXZlbiBtZXNzYWdlIGFuZCBlbnZpcm9ubWVudC4gSGFuZGxlcnMgYXJlIGNhbGxlZCBpbiB0aGUgb3JkZXIgdGhleSBhcHBlYXIgaW4gdGhlIGhhbmRsZXJzIGxpc3QuCi0tIFJldHVybiAwIHRvIG5vdCBjYWxsIGhhbmRsZXIsIC0xIHRvIGJyZWFrIGFmdGVyIGhhbmRsZXIgaXMgY2FsbGVkLCAxIHRvIGNvbnRpbnVlCi0tIEBmdW5jdGlvbiBldmFsdWF0ZQotLSBAdHBhcmFtIHt0YWJsZX0gbXNnIFRoZSBtZXNzYWdlIHRvIGJlIHByb2Nlc3NlZCBieSB0aGUgaGFuZGxlcnMuCi0tIEB0cGFyYW0ge3RhYmxlfSBlbnYgVGhlIGVudmlyb25tZW50IGluIHdoaWNoIHRoZSBoYW5kbGVycyBhcmUgZXhlY3V0ZWQuCi0tIEB0cmV0dXJuIFRoZSByZXNwb25zZSBmcm9tIHRoZSBoYW5kbGVyKHMpLiBSZXR1cm5zIGEgZGVmYXVsdCBtZXNzYWdlIGlmIG5vIGhhbmRsZXIgbWF0Y2hlcy4KZnVuY3Rpb24gaGFuZGxlcnMuZXZhbHVhdGUobXNnLCBlbnYpCiAgbG9jYWwgaGFuZGxlZCA9IGZhbHNlCiAgYXNzZXJ0KHR5cGUobXNnKSA9PSAndGFibGUnLCAnbXNnIGlzIG5vdCB2YWxpZCcpCiAgYXNzZXJ0KHR5cGUoZW52KSA9PSAndGFibGUnLCAnZW52IGlzIG5vdCB2YWxpZCcpCiAgZm9yIF8sIG8gaW4gaXBhaXJzKGhhbmRsZXJzLmxpc3QpIGRvCiAgICBpZiBvLm5hbWUgfj0gIl9kZWZhdWx0IiB0aGVuCiAgICAgIGxvY2FsIG1hdGNoID0gdXRpbHMubWF0Y2hlc1NwZWMobXNnLCBvLnBhdHRlcm4pCiAgICAgIGlmIG5vdCAodHlwZShtYXRjaCkgPT0gJ251bWJlcicgb3IgdHlwZShtYXRjaCkgPT0gJ3N0cmluZycgb3IgdHlwZShtYXRjaCkgPT0gJ2Jvb2xlYW4nKSB0aGVuCiAgICAgICAgZXJyb3IoIlBhdHRlcm4gcmVzdWx0IGlzIG5vdCB2YWxpZCwgaXQgTVVTVCBiZSBzdHJpbmcsIG51bWJlciwgb3IgYm9vbGVhbiIpCiAgICAgIGVuZAogICAgICAtLSBoYW5kbGUgYm9vbGVhbiByZXR1cm5zCiAgICAgIGlmIHR5cGUobWF0Y2gpID09ICJib29sZWFuIiBhbmQgbWF0Y2ggPT0gdHJ1ZSB0aGVuCiAgICAgICAgbWF0Y2ggPSAtMQogICAgICBlbHNlaWYgdHlwZShtYXRjaCkgPT0gImJvb2xlYW4iIGFuZCBtYXRjaCA9PSBmYWxzZSB0aGVuCiAgICAgICAgbWF0Y2ggPSAwCiAgICAgIGVuZAoKICAgICAgLS0gaGFuZGxlIHN0cmluZyByZXR1cm5zCiAgICAgIGlmIHR5cGUobWF0Y2gpID09ICJzdHJpbmciIHRoZW4KICAgICAgICBpZiBtYXRjaCA9PSAiY29udGludWUiIHRoZW4KICAgICAgICAgIG1hdGNoID0gMQogICAgICAgIGVsc2VpZiBtYXRjaCA9PSAiYnJlYWsiIHRoZW4KICAgICAgICAgIG1hdGNoID0gLTEKICAgICAgICBlbHNlCiAgICAgICAgICBtYXRjaCA9IDAKICAgICAgICBlbmQKICAgICAgZW5kCgogICAgICBpZiBtYXRjaCB+PSAwIHRoZW4KICAgICAgICBpZiBtYXRjaCA8IDAgdGhlbgogICAgICAgICAgaGFuZGxlZCA9IHRydWUKICAgICAgICBlbmQKICAgICAgICAtLSBlYWNoIGhhbmRsZSBmdW5jdGlvbiBjYW4gYWNjZXB0LCB0aGUgbXNnLCBlbnYKICAgICAgICBsb2NhbCBzdGF0dXMsIGVyciA9IHBjYWxsKG8uaGFuZGxlLCBtc2csIGVudikKICAgICAgICBpZiBub3Qgc3RhdHVzIHRoZW4KICAgICAgICAgIGVycm9yKGVycikKICAgICAgICBlbmQKICAgICAgICAtLSByZW1vdmUgaGFuZGxlciBpZiBtYXhSdW5zIGlzIHJlYWNoZWQuIG1heFJ1bnMgY2FuIGJlIGVpdGhlciBhIG51bWJlciBvciAiaW5mIgogICAgICAgIGlmIG8ubWF4UnVucyB+PSBuaWwgYW5kIG8ubWF4UnVucyB+PSAiaW5mIiB0aGVuCiAgICAgICAgICBvLm1heFJ1bnMgPSBvLm1heFJ1bnMgLSAxCiAgICAgICAgICBpZiBvLm1heFJ1bnMgPT0gMCB0aGVuCiAgICAgICAgICAgIGhhbmRsZXJzLnJlbW92ZShvLm5hbWUpCiAgICAgICAgICBlbmQKICAgICAgICBlbmQKICAgICAgZW5kCiAgICAgIGlmIG1hdGNoIDwgMCB0aGVuCiAgICAgICAgcmV0dXJuIGhhbmRsZWQKICAgICAgZW5kCiAgICBlbmQKICBlbmQKICAtLSBkbyBkZWZhdWx0CiAgaWYgbm90IGhhbmRsZWQgdGhlbgogICAgbG9jYWwgaWR4ID0gZmluZEluZGV4QnlQcm9wKGhhbmRsZXJzLmxpc3QsICJuYW1lIiwgIl9kZWZhdWx0IikKICAgIGhhbmRsZXJzLmxpc3RbaWR4XS5oYW5kbGUobXNnLGVudikKICBlbmQKZW5kCgpyZXR1cm4gaGFuZGxlcnMKCmVuZApfRy5wYWNrYWdlLmxvYWRlZFsiLmhhbmRsZXJzIl0gPSBsb2FkX2hhbmRsZXJzKCkKcHJpbnQoImxvYWRlZCBoYW5kbGVycyIpCiAgCgoKbG9jYWwgZnVuY3Rpb24gbG9hZF9kdW1wKCkgCiAgLS0KLS0gQ29weXJpZ2h0IChDKSAyMDE4IE1hc2F0b3NoaSBUZXJ1eWEKLS0KLS0gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQotLSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAotLSBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCi0tIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKLS0gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCi0tIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6Ci0tCi0tIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCi0tIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgotLQotLSBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgotLSBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLS0gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRQotLSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCi0tIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCi0tIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KLS0gVEhFIFNPRlRXQVJFLgotLQotLSBkdW1wLmx1YQotLSBsdWEtZHVtcAotLSBDcmVhdGVkIGJ5IE1hc2F0b3NoaSBUZXJ1eWEgb24gMTgvMDQvMjIuCi0tCi0tLSBmaWxlLXNjb3BlIHZhcmlhYmxlcwpsb2NhbCB0eXBlID0gdHlwZQpsb2NhbCBmbG9vciA9IG1hdGguZmxvb3IKbG9jYWwgdG9zdHJpbmcgPSB0b3N0cmluZwpsb2NhbCB0Ymxzb3J0ID0gdGFibGUuc29ydApsb2NhbCB0Ymxjb25jYXQgPSB0YWJsZS5jb25jYXQKbG9jYWwgc3RybWF0Y2ggPSBzdHJpbmcubWF0Y2gKbG9jYWwgc3RyZm9ybWF0ID0gc3RyaW5nLmZvcm1hdAotLS0gY29uc3RhbnRzCmxvY2FsIElORklOSVRFX1BPUyA9IG1hdGguaHVnZQpsb2NhbCBMVUFfRklFTEROQU1FX1BBVCA9ICdeW2EtekEtWl9dW2EtekEtWjAtOV9dKiQnCmxvY2FsIEZPUl9LRVkgPSAna2V5Jwpsb2NhbCBGT1JfVkFMID0gJ3ZhbCcKbG9jYWwgRk9SX0NJUkNVTEFSID0gJ2NpcmN1bGFyJwpsb2NhbCBSRVNFUlZFRF9XT1JEID0gewogICAgLS0gcHJpbWl0aXZlIGRhdGEKICAgIFsnbmlsJ10gPSB0cnVlLAogICAgWyd0cnVlJ10gPSB0cnVlLAogICAgWydmYWxzZSddID0gdHJ1ZSwKICAgIC0tIGRlY2xhcmF0b24KICAgIFsnbG9jYWwnXSA9IHRydWUsCiAgICBbJ2Z1bmN0aW9uJ10gPSB0cnVlLAogICAgLS0gYm9vbGVhbiBsb2dpYwogICAgWydhbmQnXSA9IHRydWUsCiAgICBbJ29yJ10gPSB0cnVlLAogICAgWydub3QnXSA9IHRydWUsCiAgICAtLSBjb25kaXRpb25hbCBzdGF0ZW1lbnQKICAgIFsnaWYnXSA9IHRydWUsCiAgICBbJ2Vsc2VpZiddID0gdHJ1ZSwKICAgIFsnZWxzZSddID0gdHJ1ZSwKICAgIC0tIGl0ZXJhdGlvbiBzdGF0ZW1lbnQKICAgIFsnZm9yJ10gPSB0cnVlLAogICAgWydpbiddID0gdHJ1ZSwKICAgIFsnd2hpbGUnXSA9IHRydWUsCiAgICBbJ3VudGlsJ10gPSB0cnVlLAogICAgWydyZXBlYXQnXSA9IHRydWUsCiAgICAtLSBqdW1wIHN0YXRlbWVudAogICAgWydicmVhayddID0gdHJ1ZSwKICAgIFsnZ290byddID0gdHJ1ZSwKICAgIFsncmV0dXJuJ10gPSB0cnVlLAogICAgLS0gYmxvY2sgc2NvcGUgc3RhdGVtZW50CiAgICBbJ3RoZW4nXSA9IHRydWUsCiAgICBbJ2RvJ10gPSB0cnVlLAogICAgWydlbmQnXSA9IHRydWUsCn0KbG9jYWwgREVGQVVMVF9JTkRFTlQgPSA0CgotLS0gZmlsdGVyIGZ1bmN0aW9uIGZvciBkdW1wCi0tLSBAcGFyYW0gdmFsIGFueQotLS0gQHBhcmFtIGRlcHRoIGludGVnZXIKLS0tIEBwYXJhbSB2dHlwZSBzdHJpbmcKLS0tIEBwYXJhbSB1c2Ugc3RyaW5nCi0tLSBAcGFyYW0ga2V5IGFueQotLS0gQHBhcmFtIHVkYXRhIGFueQotLS0gQHJldHVybiBhbnkgdmFsCi0tLSBAcmV0dXJuIGJvb2xlYW4gbm9kdW1wCmxvY2FsIGZ1bmN0aW9uIERFRkFVTFRfRklMVEVSKHZhbCkKICAgIHJldHVybiB2YWwKZW5kCgotLS0gc29ydF9pbmRleAotLS0gQHBhcmFtIGEgdGFibGUKLS0tIEBwYXJhbSBiIHRhYmxlCmxvY2FsIGZ1bmN0aW9uIHNvcnRfaW5kZXgoYSwgYikKICAgIGlmIGEudHlwID09IGIudHlwIHRoZW4KICAgICAgICBpZiBhLnR5cCA9PSAnYm9vbGVhbicgdGhlbgogICAgICAgICAgICByZXR1cm4gYi5rZXkKICAgICAgICBlbmQKCiAgICAgICAgcmV0dXJuIGEua2V5IDwgYi5rZXkKICAgIGVuZAoKICAgIHJldHVybiBhLnR5cCA9PSAnbnVtYmVyJwplbmQKCi0tLSBkdW1wdGJsCi0tLSBAcGFyYW0gdGJsIHRhYmxlCi0tLSBAcGFyYW0gZGVwdGggaW50ZWdlcgotLS0gQHBhcmFtIGluZGVudCBzdHJpbmcKLS0tIEBwYXJhbSBuZXN0SW5kZW50IHN0cmluZwotLS0gQHBhcmFtIGN0eCB0YWJsZQotLS0gQHJldHVybiBzdHJpbmcKbG9jYWwgZnVuY3Rpb24gZHVtcHRibCh0YmwsIGRlcHRoLCBpbmRlbnQsIG5lc3RJbmRlbnQsIGN0eCkKICAgIGxvY2FsIHJlZiA9IHRvc3RyaW5nKHRibCkKCiAgICAtLSBjaXJjdWxhciByZWZlcmVuY2UKICAgIGlmIGN0eC5jaXJjdWxhcltyZWZdIHRoZW4KICAgICAgICBsb2NhbCB2YWwsIG5vZHVtcCA9IGN0eC5maWx0ZXIodGJsLCBkZXB0aCwgdHlwZSh0YmwpLCBGT1JfQ0lSQ1VMQVIsIHRibCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LnVkYXRhKQoKICAgICAgICBpZiB2YWwgfj0gbmlsIGFuZCB2YWwgfj0gdGJsIHRoZW4KICAgICAgICAgICAgbG9jYWwgdCA9IHR5cGUodmFsKQoKICAgICAgICAgICAgaWYgdCA9PSAndGFibGUnIHRoZW4KICAgICAgICAgICAgICAgIC0tIGR1bXAgdGFibGUgdmFsdWUKICAgICAgICAgICAgICAgIGlmIG5vdCBub2R1bXAgdGhlbgogICAgICAgICAgICAgICAgICAgIHJldHVybiBkdW1wdGJsKHZhbCwgZGVwdGggKyAxLCBpbmRlbnQsIG5lc3RJbmRlbnQsIGN0eCkKICAgICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgICAgcmV0dXJuIHRvc3RyaW5nKHZhbCkKICAgICAgICAgICAgZWxzZWlmIHQgPT0gJ3N0cmluZycgdGhlbgogICAgICAgICAgICAgICAgcmV0dXJuIHN0cmZvcm1hdCgnJXEnLCB2YWwpCiAgICAgICAgICAgIGVsc2VpZiB0ID09ICdudW1iZXInIG9yIHQgPT0gJ2Jvb2xlYW4nIHRoZW4KICAgICAgICAgICAgICAgIHJldHVybiB0b3N0cmluZyh2YWwpCiAgICAgICAgICAgIGVuZAoKICAgICAgICAgICAgcmV0dXJuIHN0cmZvcm1hdCgnJXEnLCB0b3N0cmluZyh2YWwpKQogICAgICAgIGVuZAoKICAgICAgICByZXR1cm4gJyI8Q2lyY3VsYXIgJyAuLiByZWYgLi4gJz4iJwogICAgZW5kCgogICAgbG9jYWwgcmVzID0ge30KICAgIGxvY2FsIGFyciA9IHt9CiAgICBsb2NhbCBuYXJyID0gMAogICAgbG9jYWwgZmllbGRJbmRlbnQgPSBpbmRlbnQgLi4gbmVzdEluZGVudAoKICAgIC0tIHNhdmUgcmVmZXJlbmNlCiAgICBjdHguY2lyY3VsYXJbcmVmXSA9IHRydWUKCiAgICBmb3IgaywgdiBpbiBwYWlycyh0YmwpIGRvCiAgICAgICAgLS0gY2hlY2sga2V5CiAgICAgICAgbG9jYWwga2V5LCBub2tkdW1wID0gY3R4LmZpbHRlcihrLCBkZXB0aCwgdHlwZShrKSwgRk9SX0tFWSwgbmlsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LnVkYXRhKQoKICAgICAgICBpZiBrZXkgfj0gbmlsIHRoZW4KICAgICAgICAgICAgLS0gY2hlY2sgdmFsCiAgICAgICAgICAgIGxvY2FsIHZhbCwgbm92ZHVtcCA9IGN0eC5maWx0ZXIodiwgZGVwdGgsIHR5cGUodiksIEZPUl9WQUwsIGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgudWRhdGEpCiAgICAgICAgICAgIGxvY2FsIGt2CgogICAgICAgICAgICBpZiB2YWwgfj0gbmlsIHRoZW4KICAgICAgICAgICAgICAgIGxvY2FsIGt0ID0gdHlwZShrZXkpCiAgICAgICAgICAgICAgICBsb2NhbCB2dCA9IHR5cGUodmFsKQoKICAgICAgICAgICAgICAgIC0tIGNvbnZlcnQga2V5IHRvIHN1aXRhYmxlIHRvIGJlIHNhZmVseSByZWFkIGJhY2sKICAgICAgICAgICAgICAgIC0tIGJ5IHRoZSBMdWEgaW50ZXJwcmV0ZXIKICAgICAgICAgICAgICAgIGlmIGt0ID09ICdudW1iZXInIG9yIGt0ID09ICdib29sZWFuJyB0aGVuCiAgICAgICAgICAgICAgICAgICAgayA9IGtleQogICAgICAgICAgICAgICAgICAgIGtleSA9ICdbJyAuLiB0b3N0cmluZyhrZXkpIC4uICddJwogICAgICAgICAgICAgICAgICAgIC0tIGR1bXAgdGFibGUgdmFsdWUKICAgICAgICAgICAgICAgIGVsc2VpZiBrdCA9PSAndGFibGUnIGFuZCBub3Qgbm9rZHVtcCB0aGVuCiAgICAgICAgICAgICAgICAgICAga2V5ID0gJ1snIC4uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1bXB0Ymwoa2V5LCBkZXB0aCArIDEsIGZpZWxkSW5kZW50LCBuZXN0SW5kZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eCkgLi4gJ10nCiAgICAgICAgICAgICAgICAgICAgayA9IGtleQogICAgICAgICAgICAgICAgICAgIGt0ID0gJ3N0cmluZycKICAgICAgICAgICAgICAgIGVsc2VpZiBrdCB+PSAnc3RyaW5nJyBvciBSRVNFUlZFRF9XT1JEW2tleV0gb3IKICAgICAgICAgICAgICAgICAgICBub3Qgc3RybWF0Y2goa2V5LCBMVUFfRklFTEROQU1FX1BBVCkgdGhlbgogICAgICAgICAgICAgICAgICAgIGtleSA9IHN0cmZvcm1hdCgiWyVxXSIsIHRvc3RyaW5nKGtleSksIHYpCiAgICAgICAgICAgICAgICAgICAgayA9IGtleQogICAgICAgICAgICAgICAgICAgIGt0ID0gJ3N0cmluZycKICAgICAgICAgICAgICAgIGVuZAoKICAgICAgICAgICAgICAgIC0tIGNvbnZlcnQga2V5LXZhbCBwYWlyIHRvIHN1aXRhYmxlIHRvIGJlIHNhZmVseSByZWFkIGJhY2sKICAgICAgICAgICAgICAgIC0tIGJ5IHRoZSBMdWEgaW50ZXJwcmV0ZXIKICAgICAgICAgICAgICAgIGlmIHZ0ID09ICdudW1iZXInIG9yIHZ0ID09ICdib29sZWFuJyB0aGVuCiAgICAgICAgICAgICAgICAgICAga3YgPSBzdHJmb3JtYXQoJyVzJXMgPSAlcycsIGZpZWxkSW5kZW50LCBrZXksIHRvc3RyaW5nKHZhbCkpCiAgICAgICAgICAgICAgICBlbHNlaWYgdnQgPT0gJ3N0cmluZycgdGhlbgogICAgICAgICAgICAgICAgICAgIC0tIGR1bXAgYSBzdHJpbmctdmFsdWUKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgbm92ZHVtcCB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAgIGt2ID0gc3RyZm9ybWF0KCclcyVzID0gJXEnLCBmaWVsZEluZGVudCwga2V5LCB2YWwpCiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBrdiA9IHN0cmZvcm1hdCgnJXMlcyA9ICVzJywgZmllbGRJbmRlbnQsIGtleSwgdmFsKQogICAgICAgICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgICAgZWxzZWlmIHZ0ID09ICd0YWJsZScgYW5kIG5vdCBub3ZkdW1wIHRoZW4KICAgICAgICAgICAgICAgICAgICBrdiA9IHN0cmZvcm1hdCgnJXMlcyA9ICVzJywgZmllbGRJbmRlbnQsIGtleSwgZHVtcHRibCh2YWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGggKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkSW5kZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lc3RJbmRlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4KSkKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBrdiA9IHN0cmZvcm1hdCgnJXMlcyA9ICVxJywgZmllbGRJbmRlbnQsIGtleSwgdG9zdHJpbmcodmFsKSkKICAgICAgICAgICAgICAgIGVuZAoKICAgICAgICAgICAgICAgIC0tIGFkZCB0byBhcnJheQogICAgICAgICAgICAgICAgbmFyciA9IG5hcnIgKyAxCiAgICAgICAgICAgICAgICBhcnJbbmFycl0gPSB7CiAgICAgICAgICAgICAgICAgICAgdHlwID0ga3QsCiAgICAgICAgICAgICAgICAgICAga2V5ID0gaywKICAgICAgICAgICAgICAgICAgICB2YWwgPSBrdiwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5kCiAgICAgICAgZW5kCiAgICBlbmQKCiAgICAtLSByZW1vdmUgcmVmZXJlbmNlCiAgICBjdHguY2lyY3VsYXJbcmVmXSA9IG5pbAogICAgLS0gY29uY2F0IHJlc3VsdAogICAgaWYgbmFyciA+IDAgdGhlbgogICAgICAgIHRibHNvcnQoYXJyLCBzb3J0X2luZGV4KQoKICAgICAgICBmb3IgaSA9IDEsIG5hcnIgZG8KICAgICAgICAgICAgcmVzW2ldID0gYXJyW2ldLnZhbAogICAgICAgIGVuZAogICAgICAgIHJlc1sxXSA9ICd7JyAuLiBjdHguTEYgLi4gcmVzWzFdCiAgICAgICAgcmVzID0gdGJsY29uY2F0KHJlcywgJywnIC4uIGN0eC5MRikgLi4gY3R4LkxGIC4uIGluZGVudCAuLiAnfScKICAgIGVsc2UKICAgICAgICByZXMgPSAne30nCiAgICBlbmQKCiAgICByZXR1cm4gcmVzCmVuZAoKLS0tIGlzX3VpbnQKLS0tIEBwYXJhbSB2IGFueQotLS0gQHJldHVybiBib29sZWFuIG9rCmxvY2FsIGZ1bmN0aW9uIGlzX3VpbnQodikKICAgIHJldHVybiB0eXBlKHYpID09ICdudW1iZXInIGFuZCB2IDwgSU5GSU5JVEVfUE9TIGFuZCB2ID49IDAgYW5kIGZsb29yKHYpID09IHYKZW5kCgotLS0gZHVtcAotLS0gQHBhcmFtIHZhbCBhbnkKLS0tIEBwYXJhbSBpbmRlbnQgaW50ZWdlcgotLS0gQHBhcmFtIHBhZGRpbmcgaW50ZWdlcgotLS0gQHBhcmFtIGZpbHRlciBmdW5jdGlvbgotLS0gQHBhcmFtIHVkYXRhCi0tLSBAcmV0dXJuIHN0cmluZwpsb2NhbCBmdW5jdGlvbiBkdW1wKHZhbCwgaW5kZW50LCBwYWRkaW5nLCBmaWx0ZXIsIHVkYXRhKQogICAgbG9jYWwgdCA9IHR5cGUodmFsKQoKICAgIC0tIGNoZWNrIGluZGVudAogICAgaWYgaW5kZW50ID09IG5pbCB0aGVuCiAgICAgICAgaW5kZW50ID0gREVGQVVMVF9JTkRFTlQKICAgIGVsc2VpZiBub3QgaXNfdWludChpbmRlbnQpIHRoZW4KICAgICAgICBlcnJvcignaW5kZW50IG11c3QgYmUgdW5zaWduZWQgaW50ZWdlcicsIDIpCiAgICBlbmQKCiAgICAtLSBjaGVjayBwYWRkaW5nCiAgICBpZiBwYWRkaW5nID09IG5pbCB0aGVuCiAgICAgICAgcGFkZGluZyA9IDAKICAgIGVsc2VpZiBub3QgaXNfdWludChwYWRkaW5nKSB0aGVuCiAgICAgICAgZXJyb3IoJ3BhZGRpbmcgbXVzdCBiZSB1bnNpZ25lZCBpbnRlZ2VyJywgMikKICAgIGVuZAoKICAgIC0tIGNoZWNrIGZpbHRlcgogICAgaWYgZmlsdGVyID09IG5pbCB0aGVuCiAgICAgICAgZmlsdGVyID0gREVGQVVMVF9GSUxURVIKICAgIGVsc2VpZiB0eXBlKGZpbHRlcikgfj0gJ2Z1bmN0aW9uJyB0aGVuCiAgICAgICAgZXJyb3IoJ2ZpbHRlciBtdXN0IGJlIGZ1bmN0aW9uJywgMikKICAgIGVuZAoKICAgIC0tIGR1bXAgdGFibGUKICAgIGlmIHQgPT0gJ3RhYmxlJyB0aGVuCiAgICAgICAgbG9jYWwgaXNwYWNlID0gJycKICAgICAgICBsb2NhbCBwc3BhY2UgPSAnJwoKICAgICAgICBpZiBpbmRlbnQgPiAwIHRoZW4KICAgICAgICAgICAgaXNwYWNlID0gc3RyZm9ybWF0KCclJyAuLiB0b3N0cmluZyhpbmRlbnQpIC4uICdzJywgJycpCiAgICAgICAgZW5kCgogICAgICAgIGlmIHBhZGRpbmcgPiAwIHRoZW4KICAgICAgICAgICAgcHNwYWNlID0gc3RyZm9ybWF0KCclJyAuLiB0b3N0cmluZyhwYWRkaW5nKSAuLiAncycsICcnKQogICAgICAgIGVuZAoKICAgICAgICByZXR1cm4gZHVtcHRibCh2YWwsIDEsIHBzcGFjZSwgaXNwYWNlLCB7CiAgICAgICAgICAgIExGID0gaXNwYWNlID09ICcnIGFuZCAnICcgb3IgJ1xuJywKICAgICAgICAgICAgY2lyY3VsYXIgPSB7fSwKICAgICAgICAgICAgZmlsdGVyID0gZmlsdGVyLAogICAgICAgICAgICB1ZGF0YSA9IHVkYXRhLAogICAgICAgIH0pCiAgICBlbmQKCiAgICAtLSBkdW1wIHZhbHVlCiAgICBsb2NhbCB2LCBub2R1bXAgPSBmaWx0ZXIodmFsLCAwLCB0LCBGT1JfVkFMLCBuaWwsIHVkYXRhKQogICAgaWYgbm9kdW1wID09IHRydWUgdGhlbgogICAgICAgIHJldHVybiB0b3N0cmluZyh2KQogICAgZW5kCiAgICByZXR1cm4gc3RyZm9ybWF0KCclcScsIHRvc3RyaW5nKHYpKQplbmQKCnJldHVybiBkdW1wCmVuZApfRy5wYWNrYWdlLmxvYWRlZFsiLmR1bXAiXSA9IGxvYWRfZHVtcCgpCnByaW50KCJsb2FkZWQgZHVtcCIpCiAgCgoKbG9jYWwgZnVuY3Rpb24gbG9hZF9wcmV0dHkoKSAKICBsb2NhbCBwcmV0dHkgPSB7IF92ZXJzaW9uID0gIjAuMC4xIiB9CgpwcmV0dHkudHByaW50ID0gZnVuY3Rpb24gKHRibCwgaW5kZW50KQogIGlmIG5vdCBpbmRlbnQgdGhlbiBpbmRlbnQgPSAwIGVuZAogIGxvY2FsIG91dHB1dCA9ICIiCiAgZm9yIGssIHYgaW4gcGFpcnModGJsKSBkbwogICAgbG9jYWwgZm9ybWF0dGluZyA9IHN0cmluZy5yZXAoIiAiLCBpbmRlbnQpIC4uIGsgLi4gIjogIgogICAgaWYgdHlwZSh2KSA9PSAidGFibGUiIHRoZW4KICAgICAgb3V0cHV0ID0gb3V0cHV0IC4uIGZvcm1hdHRpbmcgLi4gIlxuIgogICAgICBvdXRwdXQgPSBvdXRwdXQgLi4gcHJldHR5LnRwcmludCh2LCBpbmRlbnQrMSkKICAgIGVsc2VpZiB0eXBlKHYpID09ICdib29sZWFuJyB0aGVuCiAgICAgIG91dHB1dCA9IG91dHB1dCAuLiBmb3JtYXR0aW5nIC4uIHRvc3RyaW5nKHYpIC4uICJcbiIKICAgIGVsc2UKICAgICAgb3V0cHV0ID0gb3V0cHV0IC4uIGZvcm1hdHRpbmcgLi4gdiAuLiAiXG4iCiAgICBlbmQKICBlbmQKICByZXR1cm4gb3V0cHV0CmVuZAoKcmV0dXJuIHByZXR0eQoKZW5kCl9HLnBhY2thZ2UubG9hZGVkWyIucHJldHR5Il0gPSBsb2FkX3ByZXR0eSgpCnByaW50KCJsb2FkZWQgcHJldHR5IikKICAKCgpsb2NhbCBmdW5jdGlvbiBsb2FkX2NoYW5jZSgpIAogIC0tLSBUaGUgQ2hhbmNlIG1vZHVsZSBwcm92aWRlcyB1dGlsaXRpZXMgZm9yIGdlbmVyYXRpbmcgcmFuZG9tIG51bWJlcnMgYW5kIHZhbHVlcy4gUmV0dXJucyB0aGUgY2hhbmNlIHRhYmxlLgotLSBAbW9kdWxlIGNoYW5jZQoKbG9jYWwgTiA9IDYyNApsb2NhbCBNID0gMzk3CmxvY2FsIE1BVFJJWF9BID0gMHg5OTA4YjBkZgpsb2NhbCBVUFBFUl9NQVNLID0gMHg4MDAwMDAwMApsb2NhbCBMT1dFUl9NQVNLID0gMHg3ZmZmZmZmZgoKLS0tIEluaXRpYWxpemVzIG10W05dIHdpdGggYSBzZWVkCi0tIEBsZnVuY3Rpb24gaW5pdF9nZW5yYW5kCi0tIEB0cGFyYW0ge3RhYmxlfSBvIFRoZSB0YWJsZSB0byBpbml0aWFsaXplCi0tIEB0cGFyYW0ge251bWJlcn0gcyBUaGUgc2VlZApsb2NhbCBmdW5jdGlvbiBpbml0X2dlbnJhbmQobywgcykKICAgIG8ubXRbMF0gPSBzICYgMHhmZmZmZmZmZgogICAgZm9yIGkgPSAxLCBOIC0gMSBkbwogICAgICAgIG8ubXRbaV0gPSAoMTgxMjQzMzI1MyAqIChvLm10W2kgLSAxXSB+IChvLm10W2kgLSAxXSA+PiAzMCkpKSArIGkKICAgICAgICAtLSBTZWUgS251dGggVEFPQ1AgVm9sMi4gM3JkIEVkLiBQLjEwNiBmb3IgbXVsdGlwbGllci4KICAgICAgICAtLSBJbiB0aGUgcHJldmlvdXMgdmVyc2lvbnMsIE1TQnMgb2YgdGhlIHNlZWQgYWZmZWN0CiAgICAgICAgLS0gb25seSBNU0JzIG9mIHRoZSBhcnJheSBtdFtdLgogICAgICAgIC0tIDIwMDIvMDEvMDkgbW9kaWZpZWQgYnkgTWFrb3RvIE1hdHN1bW90bwogICAgICAgIG8ubXRbaV0gPSBvLm10W2ldICYgMHhmZmZmZmZmZgogICAgICAgIC0tIGZvciA+MzIgYml0IG1hY2hpbmVzCiAgICBlbmQKICAgIG8ubXRpID0gTgplbmQKCi0tLSBHZW5lcmF0ZXMgYSByYW5kb20gbnVtYmVyIG9uIFswLDB4ZmZmZmZmZmZdLWludGVydmFsCi0tIEBsZnVuY3Rpb24gZ2VucmFuZF9pbnQzMgotLSBAdHBhcmFtIHt0YWJsZX0gbyBUaGUgdGFibGUgdG8gZ2VuZXJhdGUgdGhlIHJhbmRvbSBudW1iZXIgZnJvbQotLSBAdHJldHVybiB7bnVtYmVyfSBUaGUgcmFuZG9tIG51bWJlcgpsb2NhbCBmdW5jdGlvbiBnZW5yYW5kX2ludDMyKG8pCiAgICBsb2NhbCB5CiAgICBsb2NhbCBtYWcwMSA9IHt9IC0tIG1hZzAxW3hdID0geCAqIE1BVFJJWF9BICBmb3IgeD0wLDEKICAgIG1hZzAxWzBdID0gMHgwCiAgICBtYWcwMVsxXSA9IE1BVFJJWF9BCiAgICBpZiBvLm10aSA+PSBOIHRoZW4gIC0tIGdlbmVyYXRlIE4gd29yZHMgYXQgb25lIHRpbWUKICAgICAgICBpZiBvLm10aSA9PSBOICsgMSB0aGVuIC0tIGlmIGluaXRfZ2VucmFuZCgpIGhhcyBub3QgYmVlbiBjYWxsZWQsCiAgICAgICAgICAgIGluaXRfZ2VucmFuZChvLCA1NDg5KSAgIC0tIGEgZGVmYXVsdCBpbml0aWFsIHNlZWQgaXMgdXNlZAogICAgICAgIGVuZAogICAgICAgIGZvciBrayA9IDAsIE4gLSBNIC0gMSBkbwogICAgICAgICAgICB5ID0gKG8ubXRba2tdICYgVVBQRVJfTUFTSykgfCAoby5tdFtrayArIDFdICYgTE9XRVJfTUFTSykKICAgICAgICAgICAgby5tdFtra10gPSBvLm10W2trICsgTV0gfiAoeSA+PiAxKSB+IG1hZzAxW3kgJiAweDFdCiAgICAgICAgZW5kCiAgICAgICAgZm9yIGtrID0gTiAtIE0sIE4gLSAyIGRvCiAgICAgICAgICAgIHkgPSAoby5tdFtra10gJiBVUFBFUl9NQVNLKSB8IChvLm10W2trICsgMV0gJiBMT1dFUl9NQVNLKQogICAgICAgICAgICBvLm10W2trXSA9IG8ubXRba2sgKyAoTSAtIE4pXSB+ICh5ID4+IDEpIH4gbWFnMDFbeSAmIDB4MV0KICAgICAgICBlbmQKICAgICAgICB5ID0gKG8ubXRbTiAtIDFdICYgVVBQRVJfTUFTSykgfCAoby5tdFswXSAmIExPV0VSX01BU0spCiAgICAgICAgby5tdFtOIC0gMV0gPSBvLm10W00gLSAxXSB+ICh5ID4+IDEpIH4gbWFnMDFbeSAmIDB4MV0KCiAgICAgICAgby5tdGkgPSAwCiAgICBlbmQKCiAgICB5ID0gby5tdFtvLm10aV0KICAgIG8ubXRpID0gby5tdGkgKyAxCgogICAgLS0gVGVtcGVyaW5nCiAgICB5ID0geSB+ICh5ID4+IDExKQogICAgeSA9IHkgfiAoKHkgPDwgNykgJiAweDlkMmM1NjgwKQogICAgeSA9IHkgfiAoKHkgPDwgMTUpICYgMHhlZmM2MDAwMCkKICAgIHkgPSB5IH4gKHkgPj4gMTgpCgogICAgcmV0dXJuIHkKZW5kCgpsb2NhbCBNZXJzZW5uZVR3aXN0ZXIgPSB7fQpNZXJzZW5uZVR3aXN0ZXIubXQgPSB7fQpNZXJzZW5uZVR3aXN0ZXIubXRpID0gTiArIDEKCgotLS0gVGhlIFJhbmRvbSB0YWJsZQotLSBAdGFibGUgUmFuZG9tCi0tIEBmaWVsZCBzZWVkIFRoZSBzZWVkIGZ1bmN0aW9uCi0tIEBmaWVsZCByYW5kb20gVGhlIHJhbmRvbSBmdW5jdGlvbgotLSBAZmllbGQgaW50ZWdlciBUaGUgaW50ZWdlciBmdW5jdGlvbgpsb2NhbCBSYW5kb20gPSB7fQoKLS0tIFNldHMgYSBuZXcgcmFuZG9tIHRhYmxlIGdpdmVuIGEgc2VlZC4KLS0gQGZ1bmN0aW9uIHNlZWQKLS0gQHRwYXJhbSB7bnVtYmVyfSBzZWVkIFRoZSBzZWVkCmZ1bmN0aW9uIFJhbmRvbS5zZWVkKHNlZWQpCiAgICBpbml0X2dlbnJhbmQoTWVyc2VubmVUd2lzdGVyLCBzZWVkKQplbmQKCi0tLSBHZW5lcmF0ZXMgYSByYW5kb20gbnVtYmVyIG9uIFswLDEpLXJlYWwtaW50ZXJ2YWwuCi0tIEBmdW5jdGlvbiByYW5kb20KLS0gQHRyZXR1cm4ge251bWJlcn0gVGhlIHJhbmRvbSBudW1iZXIKZnVuY3Rpb24gUmFuZG9tLnJhbmRvbSgpCiAgICByZXR1cm4gZ2VucmFuZF9pbnQzMihNZXJzZW5uZVR3aXN0ZXIpICogKDEuMCAvIDQyOTQ5NjcyOTYuMCkKZW5kCgotLS0gUmV0dXJucyBhIHJhbmRvbSBpbnRlZ2VyLiBUaGUgbWluIGFuZCBtYXggYXJlIElOQ0xVREVEIGluIHRoZSByYW5nZS4KLS0gVGhlIG1heCBpbnRlZ2VyIGluIGx1YSBpcyBtYXRoLm1heGludGVnZXIKLS0gVGhlIG1pbiBpcyBtYXRoLm1pbmludGVnZXIKLS0gQGZ1bmN0aW9uIFJhbmRvbS5pbnRlZ2VyCi0tIEB0cGFyYW0ge251bWJlcn0gbWluIFRoZSBtaW5pbXVtIHZhbHVlCi0tIEB0cGFyYW0ge251bWJlcn0gbWF4IFRoZSBtYXhpbXVtIHZhbHVlCi0tIEB0cmV0dXJuIHtudW1iZXJ9IFRoZSByYW5kb20gaW50ZWdlcgpmdW5jdGlvbiBSYW5kb20uaW50ZWdlcihtaW4sIG1heCkKICAgIGFzc2VydChtYXggPj0gbWluLCAibWF4IG11c3QgYmlnZ2VyIHRoYW4gbWluIikKICAgIHJldHVybiBtYXRoLmZsb29yKFJhbmRvbS5yYW5kb20oKSAqIChtYXggLSBtaW4gKyAxKSArIG1pbikKZW5kCgpyZXR1cm4gUmFuZG9tCmVuZApfRy5wYWNrYWdlLmxvYWRlZFsiLmNoYW5jZSJdID0gbG9hZF9jaGFuY2UoKQpwcmludCgibG9hZGVkIGNoYW5jZSIpCiAgCgoKbG9jYWwgZnVuY3Rpb24gbG9hZF9ib290KCkgCiAgLS0tIFRoZSBCb290IG1vZHVsZSBwcm92aWRlcyBmdW5jdGlvbmFsaXR5IGZvciBib290aW5nIHRoZSBwcm9jZXNzLiBSZXR1cm5zIHRoZSBib290IGZ1bmN0aW9uLgotLSBAbW9kdWxlIGJvb3QKCi0tIFRoaXMgaXMgZm9yIGFvcDYgQm9vdCBMb2FkZXIKLS0gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vcGVybWF3ZWIvYW9zL2lzc3Vlcy8zNDIKLS0gRm9yIHRoZSBQcm9jZXNzIGFzIHRoZSBmaXJzdCBNZXNzYWdlLCBpZiBPbi1Cb290Ci0tIGhhcyB0aGUgdmFsdWUgJ2RhdGEnIHRoZW4gZXZhbHVhdGUgdGhlIGRhdGEKLS0gaWYgaXQgaXMgYSB0eCBpZCwgdGhlbiBkb3dubG9hZCBhbmQgZXZhbHVhdGUgdGhlIHR4Cgpsb2NhbCBkcml2ZSA9IHsgX3ZlcnNpb24gPSAiMC4wLjEiIH0KCmZ1bmN0aW9uIGRyaXZlLmdldERhdGEodHhJZCkKICBsb2NhbCBmaWxlID0gaW8ub3BlbignL2RhdGEvJyAuLiB0eElkKQogIGlmIG5vdCBmaWxlIHRoZW4KICAgIHJldHVybiBuaWwsICJGaWxlIG5vdCBmb3VuZCEiCiAgZW5kCiAgbG9jYWwgY29udGVudHMgPSBmaWxlOnJlYWQoCiAgICBmaWxlOnNlZWsoJ2VuZCcpCiAgKQogIGZpbGU6Y2xvc2UoKQogIHJldHVybiBjb250ZW50cwplbmQKCi0tLSBUaGUgYm9vdCBmdW5jdGlvbi4KLS0gSWYgdGhlIG1lc3NhZ2UgaGFzIG5vIE9uLUJvb3QgdGFnLCBkbyBub3RoaW5nLgotLSBJZiB0aGUgbWVzc2FnZSBoYXMgYW4gT24tQm9vdCB0YWcgd2l0aCB0aGUgdmFsdWUgJ0RhdGEnLCB0aGVuIGV2YWx1YXRlIHRoZSBtZXNzYWdlLgotLSBJZiB0aGUgbWVzc2FnZSBoYXMgYW4gT24tQm9vdCB0YWcgd2l0aCBhIHR4IGlkLCB0aGVuIGRvd25sb2FkIGFuZCBldmFsdWF0ZSB0aGUgdHggZGF0YS4KLS0gQGZ1bmN0aW9uIGJvb3QKLS0gQHBhcmFtIGFvIFRoZSBhbyBlbnZpcm9ubWVudCBvYmplY3QKLS0gQHNlZSBldmFsCnJldHVybiBmdW5jdGlvbiAoYW8pCiAgbG9jYWwgZXZhbCA9IHJlcXVpcmUoIi5ldmFsIikoYW8pCiAgcmV0dXJuIGZ1bmN0aW9uIChtc2cpCiAgICBpZiAjSW5ib3ggPT0gMCB0aGVuCiAgICAgIHRhYmxlLmluc2VydChJbmJveCwgbXNnKQogICAgZW5kCiAgICBpZiBtc2cuVGFnc1snT24tQm9vdCddID09IG5pbCB0aGVuCiAgICAgIHJldHVybgogICAgZW5kCiAgICBpZiBtc2cuVGFnc1snT24tQm9vdCddID09ICdEYXRhJyB0aGVuCiAgICAgIGV2YWwobXNnKQogICAgZWxzZQogICAgICBsb2NhbCBsb2FkZWRWYWwgPSBkcml2ZS5nZXREYXRhKG1zZy5UYWdzWydPbi1Cb290J10pCiAgICAgIGV2YWwoeyBEYXRhID0gbG9hZGVkVmFsIH0pCiAgICBlbmQKICBlbmQKZW5kCmVuZApfRy5wYWNrYWdlLmxvYWRlZFsiLmJvb3QiXSA9IGxvYWRfYm9vdCgpCnByaW50KCJsb2FkZWQgYm9vdCIpCiAgCgoKbG9jYWwgZnVuY3Rpb24gbG9hZF9kZWZhdWx0KCkgCiAgbG9jYWwganNvbiA9IHJlcXVpcmUoJy5qc29uJykKLS0gZGVmYXVsdCBoYW5kbGVyIGZvciBhb3MKcmV0dXJuIGZ1bmN0aW9uIChpbnNlcnRJbmJveCkKICByZXR1cm4gZnVuY3Rpb24gKG1zZykKICAgIC0tIEFkZCBNZXNzYWdlIHRvIEluYm94CiAgICBpbnNlcnRJbmJveChtc2cpCgogICAgLS0gbG9jYWwgdHh0ID0gQ29sb3JzLmdyYXkgLi4gIk5ldyBNZXNzYWdlIEZyb20gIiAuLiBDb2xvcnMuZ3JlZW4gLi4gCiAgICAtLSAobXNnLkZyb20gYW5kIChtc2cuRnJvbTpzdWIoMSwzKSAuLiAiLi4uIiAuLiBtc2cuRnJvbTpzdWIoLTMpKSBvciAidW5rbm93biIpIC4uIENvbG9ycy5ncmF5IC4uICI6ICIKICAgIC0tIGlmIG1zZy5BY3Rpb24gdGhlbgogICAgLS0gICB0eHQgPSB0eHQgLi4gQ29sb3JzLmdyYXkgLi4gKG1zZy5BY3Rpb24gYW5kICgiQWN0aW9uID0gIiAuLiBDb2xvcnMuYmx1ZSAuLiBtc2cuQWN0aW9uOnN1YigxLDIwKSkgb3IgIiIpIC4uIENvbG9ycy5yZXNldAogICAgLS0gZWxzZQogICAgLS0gICBsb2NhbCBkYXRhID0gbXNnLkRhdGEKICAgIC0tICAgaWYgdHlwZShkYXRhKSA9PSAndGFibGUnIHRoZW4KICAgIC0tICAgICBkYXRhID0ganNvbi5lbmNvZGUoZGF0YSkKICAgIC0tICAgZW5kCiAgICAtLSAgIHR4dCA9IHR4dCAuLiBDb2xvcnMuZ3JheSAuLiAiRGF0YSA9ICIgLi4gQ29sb3JzLmJsdWUgLi4gKGRhdGEgYW5kIGRhdGE6c3ViKDEsMjApIG9yICIiKSAuLiBDb2xvcnMucmVzZXQKICAgIC0tIGVuZAogICAgLS0gUHJpbnQgdG8gT3V0cHV0CiAgICAtLSBwcmludCh0eHQpCiAgICBwcmludCgiTmV3IE1lc3NhZ2UiKQogIGVuZAoKZW5kCgplbmQKX0cucGFja2FnZS5sb2FkZWRbIi5kZWZhdWx0Il0gPSBsb2FkX2RlZmF1bHQoKQpwcmludCgibG9hZGVkIGRlZmF1bHQiKQogIAoKCmxvY2FsIGZ1bmN0aW9uIGxvYWRfYW8oKSAKICBIYW5kbGVycyA9IEhhbmRsZXJzIG9yIHJlcXVpcmUoJy5oYW5kbGVycycpCgpsb2NhbCBvbGRhbyA9IGFvIG9yIHt9Cgpsb2NhbCB1dGlscyA9IHJlcXVpcmUoJy51dGlscycpCgpsb2NhbCBhbyA9IHsKICAgIF92ZXJzaW9uID0gIjAuMC42IiwKICAgIGlkID0gb2xkYW8uaWQgb3IgIiIsCiAgICBfbW9kdWxlID0gb2xkYW8uX21vZHVsZSBvciAiIiwKICAgIGF1dGhvcml0aWVzID0gb2xkYW8uYXV0aG9yaXRpZXMgb3Ige30sCiAgICByZWZlcmVuY2UgPSBvbGRhby5yZWZlcmVuY2Ugb3IgMCwKICAgIG91dGJveCA9IG9sZGFvLm91dGJveCBvcgogICAgICAgIHtPdXRwdXQgPSB7fSwgTWVzc2FnZXMgPSB7fSwgU3Bhd25zID0ge30sIEFzc2lnbm1lbnRzID0ge319LAogICAgbm9uRXh0cmFjdGFibGVUYWdzID0gewogICAgICAgICdkYXRhLXByb3RvY29sJywgJ3ZhcmlhbnQnLCAnZnJvbS1wcm9jZXNzJywgJ2Zyb20tbW9kdWxlJywgJ3R5cGUnLAogICAgICAgICdmcm9tJywgJ293bmVyJywgJ2FuY2hvcicsICd0YXJnZXQnLCAnZGF0YScsICd0YWdzJywgJ3JlYWQtb25seScKICAgIH0sCiAgICBub25Gb3J3YXJkYWJsZVRhZ3MgPSB7CiAgICAgICAgJ2RhdGEtcHJvdG9jb2wnLCAndmFyaWFudCcsICdmcm9tLXByb2Nlc3MnLCAnZnJvbS1tb2R1bGUnLCAndHlwZScsCiAgICAgICAgJ2Zyb20nLCAnb3duZXInLCAnYW5jaG9yJywgJ3RhcmdldCcsICd0YWdzJywgJ3RhZ0FycmF5JywgJ2hhc2gtY2hhaW4nLAogICAgICAgICd0aW1lc3RhbXAnLCAnbm9uY2UnLCAnc2xvdCcsICdlcG9jaCcsICdzaWduYXR1cmUnLCAnZm9yd2FyZGVkLWJ5JywKICAgICAgICAncHVzaGVkLWZvcicsICdyZWFkLW9ubHknLCAnY3JvbicsICdibG9jay1oZWlnaHQnLCAncmVmZXJlbmNlJywgJ2lkJywKICAgICAgICAncmVwbHktdG8nCiAgICB9LAogICAgTm9uY2UgPSBuaWwKfQoKZnVuY3Rpb24gYW8uY2xlYXJPdXRib3goKQogIGFvLm91dGJveCA9IHsgT3V0cHV0ID0ge30sIE1lc3NhZ2VzID0ge30sIFNwYXducyA9IHt9LCBBc3NpZ25tZW50cyA9IHt9fQplbmQKCmxvY2FsIGZ1bmN0aW9uIGdldElkKG0pCiAgbG9jYWwgaWQgPSAiIgogIHV0aWxzLm1hcChmdW5jdGlvbiAoaykKICAgIGxvY2FsIGMgPSBtLmNvbW1pdG1lbnRzW2tdCiAgICBpZiBjLnR5cGUgPT0gInJzYS1wc3Mtc2hhNTEyIiB0aGVuCiAgICAgIGlkID0gawogICAgZWxzZWlmIGMudHlwZSA9PSAic2lnbmVkIiBhbmQgY1snY29tbWl0bWVudC1kZXZpY2UnXSA9PSAiYW5zMTA0IiB0aGVuCiAgICAgIGlkID0gawogICAgZW5kCiAgZW5kLCB1dGlscy5rZXlzKG0uY29tbWl0bWVudHMpCiAgKQogIHJldHVybiBpZAplbmQKCmZ1bmN0aW9uIGFvLmluaXQoZW52KQogIGlmIF9HLmFvLmlkID09ICIiIHRoZW4gX0cuYW8uaWQgPSBnZXRJZChlbnYucHJvY2VzcykgZW5kCgogIC0tIGlmIGFvLl9tb2R1bGUgPT0gIiIgdGhlbgogIC0tICAgYW8uX21vZHVsZSA9IGVudi5Nb2R1bGUuSWQKICAtLSBlbmQKICAtLSBUT0RPOiBuZWVkIHRvIGRlYWwgd2l0aCBhc3NpZ25hYmxlcwogIGlmIF9HLmFvLmF1dGhvcml0aWVzID09IG5pbCBvciAjIF9HLmFvLmF1dGhvcml0aWVzIDwgMSB0aGVuCiAgICAgIGlmIHR5cGUoZW52LnByb2Nlc3MuYXV0aG9yaXR5KSA9PSAnc3RyaW5nJyB0aGVuCiAgICAgICAgX0cuYW8uYXV0aG9yaXRpZXMgPSB7IGVudi5wcm9jZXNzLmF1dGhvcml0eSB9CiAgICAgIGVsc2UKICAgICAgICBfRy5hby5hdXRob3JpdGllcyA9IGVudi5wcm9jZXNzLmF1dGhvcml0eSBvciB7fQogICAgICBlbmQKICBlbmQKICBfRy5hby5vdXRib3ggPSB7T3V0cHV0ID0ge30sIE1lc3NhZ2VzID0ge30sIFNwYXducyA9IHt9LCBBc3NpZ25tZW50cyA9IHt9fQogIF9HLmFvLmVudiA9IGVudgoKZW5kCgpmdW5jdGlvbiBhby5zZW5kKG1zZykKICBhc3NlcnQodHlwZShtc2cpID09ICd0YWJsZScsICdtc2cgc2hvdWxkIGJlIGEgdGFibGUnKQoKICBhby5yZWZlcmVuY2UgPSBhby5yZWZlcmVuY2UgKyAxCiAgbG9jYWwgcmVmZXJlbmNlU3RyaW5nID0gdG9zdHJpbmcoYW8ucmVmZXJlbmNlKQogIC0tIHNldCBrdgogIG1zZy5yZWZlcmVuY2UgPSByZWZlcmVuY2VTdHJpbmcKCiAgLS0gY2xvbmUgbWVzc2FnZSBpbmZvIGFuZCBhZGQgdG8gb3V0Ym94CiAgdGFibGUuaW5zZXJ0KGFvLm91dGJveC5NZXNzYWdlcywgdXRpbHMucmVkdWNlKAogICAgZnVuY3Rpb24gKGFjYywga2V5KQogICAgICBhY2Nba2V5XSA9IG1zZ1trZXldCiAgICAgIHJldHVybiBhY2MKICAgIGVuZCwKICAgIHt9LAogICAgdXRpbHMua2V5cyhtc2cpCiAgKSkKCiAgaWYgbXNnLnRhcmdldCB0aGVuCiAgICBtc2cub25SZXBseSA9IGZ1bmN0aW9uKC4uLikKICAgICAgbG9jYWwgZnJvbSwgcmVzb2x2ZXIKICAgICAgaWYgc2VsZWN0KCIjIiwgLi4uKSA9PSAyIHRoZW4KICAgICAgICBmcm9tID0gc2VsZWN0KDEsIC4uLikKICAgICAgICByZXNvbHZlciA9IHNlbGVjdCgyLCAuLi4pCiAgICAgIGVsc2UKICAgICAgICBmcm9tID0gbXNnLnRhcmdldAogICAgICAgIHJlc29sdmVyID0gc2VsZWN0KDEsIC4uLikKICAgICAgZW5kCiAgICAgIEhhbmRsZXJzLm9uY2UoewogICAgICAgIGZyb20gPSBmcm9tLAogICAgICAgIFsieC1yZWZlcmVuY2UiXSA9IHJlZmVyZW5jZVN0cmluZwogICAgICB9LCByZXNvbHZlcikKICAgIGVuZAogIGVuZAoKICAtLSBBZGQgcmVjZWl2ZSgpIG1ldGhvZCBmb3Igc3luY2hyb25vdXMgc2VsZi1tZXNzYWdlIGhhbmRsaW5nCiAgLS0gVGhpcyBlbmFibGVzIFNlbmQoeyBUYXJnZXQgPSBhby5pZCwgLi4uIH0pLnJlY2VpdmUoKSBwYXR0ZXJuCiAgbXNnLnJlY2VpdmUgPSBmdW5jdGlvbihwYXR0ZXJuKQogICAgbG9jYWwgdGFyZ2V0ID0gbXNnLlRhcmdldCBvciBtc2cudGFyZ2V0CiAgICAtLSBPbmx5IGhhbmRsZSBzZWxmLW1lc3NhZ2VzIHN5bmNocm9ub3VzbHkKICAgIGlmIHRhcmdldCB+PSBhby5pZCB0aGVuCiAgICAgIC0tIEZvciBjcm9zcy1wcm9jZXNzIG1lc3NhZ2VzLCByZXR1cm4gbmlsIChhc3luYyBvbmx5KQogICAgICByZXR1cm4gbmlsCiAgICBlbmQKCiAgICAtLSBDcmVhdGUgYSBmYWtlIHJlcXVlc3QgbWVzc2FnZSBmcm9tIHRoZSBzZW50IG1lc3NhZ2UKICAgIGxvY2FsIGZha2VSZXEgPSB7CiAgICAgIGJvZHkgPSB7CiAgICAgICAgYWN0aW9uID0gbXNnLkFjdGlvbiBvciBtc2cuYWN0aW9uLAogICAgICAgIEFjdGlvbiA9IG1zZy5BY3Rpb24gb3IgbXNnLmFjdGlvbiwKICAgICAgICBEYXRhID0gbXNnLkRhdGEgb3IgbXNnLmRhdGEsCiAgICAgICAgRnJvbSA9IGFvLmlkLAogICAgICAgIFsnZnJvbS1wcm9jZXNzJ10gPSBhby5pZCwKICAgICAgICByZWZlcmVuY2UgPSByZWZlcmVuY2VTdHJpbmcsCiAgICAgICAgY29tbWl0bWVudHMgPSB7fQogICAgICB9LAogICAgICBzbG90ID0gX0cuYW8uc2xvdCBvciAwLAogICAgICBbJ2Jsb2NrLXRpbWVzdGFtcCddID0gb3MudGltZSBhbmQgb3MudGltZSgpIG9yIDAKICAgIH0KICAgIC0tIENvcHkgYWxsIG1zZyBmaWVsZHMgdG8gZmFrZVJlcS5ib2R5CiAgICBmb3IgaywgdiBpbiBwYWlycyhtc2cpIGRvCiAgICAgIGlmIGsgfj0gJ3JlY2VpdmUnIGFuZCBrIH49ICdvblJlcGx5JyB0aGVuCiAgICAgICAgZmFrZVJlcS5ib2R5W2tdID0gdgogICAgICBlbmQKICAgIGVuZAogICAgLS0gQWRkIHJlcGx5IGZ1bmN0aW9uIHRvIGZha2VSZXEKICAgIGxvY2FsIHJlcGx5RGF0YSA9IG5pbAogICAgZmFrZVJlcS5yZXBseSA9IGZ1bmN0aW9uKGRhdGEpCiAgICAgIHJlcGx5RGF0YSA9IGRhdGEKICAgIGVuZAoKICAgIC0tIEZpbmQgYW5kIGV4ZWN1dGUgbWF0Y2hpbmcgaGFuZGxlciAoc2tpcCBfZGVmYXVsdCBhbmQgX2V2YWwpCiAgICBmb3IgXywgaCBpbiBpcGFpcnMoSGFuZGxlcnMubGlzdCkgZG8KICAgICAgaWYgaC5uYW1lIH49ICJfZGVmYXVsdCIgYW5kIGgubmFtZSB+PSAiX2V2YWwiIHRoZW4KICAgICAgICBsb2NhbCBtYXRjaCA9IHV0aWxzLm1hdGNoZXNTcGVjKGZha2VSZXEsIGgucGF0dGVybikKICAgICAgICBpZiBtYXRjaCBhbmQgbWF0Y2ggfj0gMCBhbmQgbWF0Y2ggfj0gZmFsc2UgYW5kIG1hdGNoIH49ICJza2lwIiB0aGVuCiAgICAgICAgICAtLSBFeGVjdXRlIHRoZSBoYW5kbGVyCiAgICAgICAgICBsb2NhbCBzdGF0dXMsIGVyciA9IHBjYWxsKGguaGFuZGxlLCBmYWtlUmVxLCBfRy5hby5lbnYpCiAgICAgICAgICBpZiBub3Qgc3RhdHVzIHRoZW4KICAgICAgICAgICAgcmV0dXJuIHsgRXJyb3IgPSBlcnIgfQogICAgICAgICAgZW5kCiAgICAgICAgICAtLSBJZiBoYW5kbGVyIGNhbGxlZCByZXBseSgpLCByZXR1cm4gdGhhdCBkYXRhCiAgICAgICAgICBpZiByZXBseURhdGEgdGhlbgogICAgICAgICAgICByZXR1cm4gcmVwbHlEYXRhCiAgICAgICAgICBlbmQKICAgICAgICAgIC0tIE90aGVyd2lzZSBjaGVjayBpZiBoYW5kbGVyIGFkZGVkIG1lc3NhZ2VzIHRvIG91dGJveAogICAgICAgICAgbG9jYWwgbGFzdE1zZyA9IGFvLm91dGJveC5NZXNzYWdlc1sjYW8ub3V0Ym94Lk1lc3NhZ2VzXQogICAgICAgICAgaWYgbGFzdE1zZyBhbmQgbGFzdE1zZy5yZWZlcmVuY2Ugfj0gcmVmZXJlbmNlU3RyaW5nIHRoZW4KICAgICAgICAgICAgcmV0dXJuIGxhc3RNc2cKICAgICAgICAgIGVuZAogICAgICAgICAgYnJlYWsKICAgICAgICBlbmQKICAgICAgZW5kCiAgICBlbmQKCiAgICByZXR1cm4gbmlsCiAgZW5kCgogIHJldHVybiBtc2cKZW5kCgpmdW5jdGlvbiBhby5zcGF3bihtb2R1bGUsIG1zZykKICBhc3NlcnQodHlwZShtb2R1bGUpID09ICJzdHJpbmciLCAiTW9kdWxlIHNvdXJjZSBpZCBpcyByZXF1aXJlZCEiKQogIGFzc2VydCh0eXBlKG1zZykgPT0gInRhYmxlIiwgIk1lc3NhZ2UgbXVzdCBiZSBhIHRhYmxlLiIpCgogIGFvLnJlZmVyZW5jZSA9IGFvLnJlZmVyZW5jZSArIDEKCiAgbG9jYWwgc3Bhd25SZWYgPSB0b3N0cmluZyhhby5yZWZlcmVuY2UpCgogIG1zZ1sicmVmZXJlbmNlIl0gPSBzcGF3blJlZgoKICAtLSBjbG9uZSBtZXNzYWdlIGluZm8gYW5kIGFkZCB0byBvdXRib3gKICB0YWJsZS5pbnNlcnQoYW8ub3V0Ym94LlNwYXducywgdXRpbHMucmVkdWNlKAogICAgZnVuY3Rpb24gKGFjYywga2V5KQogICAgICBhY2Nba2V5XSA9IG1zZ1trZXldCiAgICAgIHJldHVybiBhY2MKICAgIGVuZCwKICAgIHt9LAogICAgdXRpbHMua2V5cyhtc2cpCiAgKSkKCiAgbXNnLm9uUmVwbHkgPSBmdW5jdGlvbihjYikKICAgIEhhbmRsZXJzLm9uY2UoewogICAgICBhY3Rpb24gPSAiU3Bhd25lZCIsCiAgICAgIGZyb20gPSBhby5pZCwKICAgICAgWyJ4LXJlZmVyZW5jZSJdID0gc3Bhd25SZWYKICAgIH0sIGNiKQogIGVuZAoKICByZXR1cm4gbXNnCgplbmQKCmZ1bmN0aW9uIGFvLnJlc3VsdChyZXN1bHQpCiAgaWYgYW8ub3V0Ym94LkVycm9yIG9yIHJlc3VsdC5FcnJvciB0aGVuCiAgICByZXR1cm4geyBFcnJvciA9IHJlc3VsdC5FcnJvciBvciBhby5vdXRib3guRXJyb3IgfQogIGVuZAogIHJldHVybiB7CiAgICBPdXRwdXQgPSByZXN1bHQuT3V0cHV0IG9yIGFvLm91dHB1dC5PdXRwdXQsCiAgICBNZXNzYWdlcyA9IGFvLm91dGJveC5NZXNzYWdlcywKICAgIFNwYXducyA9IGFvLm91dGJveC5TcGF3bnMsCiAgICBBc3NpZ25tZW50cyA9IGFvLm91dGJveC5Bc3NpZ25tZW50cwogIH0KZW5kCgotLSBzZXQgZ2xvYmFsIFNlbmQgYW5kIFNwYXduClNlbmQgPSBTZW5kIG9yIGFvLnNlbmQKU3Bhd24gPSBTcGF3biBvciBhby5zcGF3bgoKcmV0dXJuIGFvCgplbmQKX0cucGFja2FnZS5sb2FkZWRbIi5hbyJdID0gbG9hZF9hbygpCnByaW50KCJsb2FkZWQgYW8iKQogIAoKCmxvY2FsIGZ1bmN0aW9uIGxvYWRfYmFzZTY0KCkgCiAgLS1bWwoKIGJhc2U2NCAtLSB2MS41LjMgcHVibGljIGRvbWFpbiBMdWEgYmFzZTY0IGVuY29kZXIvZGVjb2Rlcgogbm8gd2FycmFudHkgaW1wbGllZDsgdXNlIGF0IHlvdXIgb3duIHJpc2sKCiBOZWVkcyBiaXQzMi5leHRyYWN0IGZ1bmN0aW9uLiBJZiBub3QgcHJlc2VudCBpdCdzIGltcGxlbWVudGVkIHVzaW5nIEJpdE9wCiBvciBMdWEgNS4zIG5hdGl2ZSBiaXQgb3BlcmF0b3JzLiBGb3IgTHVhIDUuMSBmYWxsYmFja3MgdG8gcHVyZSBMdWEKIGltcGxlbWVudGF0aW9uIGluc3BpcmVkIGJ5IFJpY2kgTGFrZSdzIHBvc3Q6CiAgIGh0dHA6Ly9yaWNpbGFrZS5ibG9nc3BvdC5jby51ay8yMDA3LzEwL2l0ZXJhdGluZy1iaXRzLWluLWx1YS5odG1sCgogYXV0aG9yOiBJbHlhIEtvbGJpbiAoaXNrb2xiaW5AZ21haWwuY29tKQogdXJsOiBnaXRodWIuY29tL2lza29sYmluL2xiYXNlNjQKCiBDT01QQVRJQklMSVRZCgogTHVhIDUuMSssIEx1YUpJVAoKIExJQ0VOU0UKCiBTZWUgZW5kIG9mIGZpbGUgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uCgotLV1dCgoKbG9jYWwgYmFzZTY0ID0ge30KCmxvY2FsIGV4dHJhY3QgPSBfRy5iaXQzMiBhbmQgX0cuYml0MzIuZXh0cmFjdCAtLSBMdWEgNS4yL0x1YSA1LjMgaW4gY29tcGF0aWJpbGl0eSBtb2RlCmlmIG5vdCBleHRyYWN0IHRoZW4KCWlmIF9HLmJpdCB0aGVuIC0tIEx1YUpJVAoJCWxvY2FsIHNobCwgc2hyLCBiYW5kID0gX0cuYml0LmxzaGlmdCwgX0cuYml0LnJzaGlmdCwgX0cuYml0LmJhbmQKCQlleHRyYWN0ID0gZnVuY3Rpb24oIHYsIGZyb20sIHdpZHRoICkKCQkJcmV0dXJuIGJhbmQoIHNociggdiwgZnJvbSApLCBzaGwoIDEsIHdpZHRoICkgLSAxICkKCQllbmQKCWVsc2VpZiBfRy5fVkVSU0lPTiA9PSAiTHVhIDUuMSIgdGhlbgoJCWV4dHJhY3QgPSBmdW5jdGlvbiggdiwgZnJvbSwgd2lkdGggKQoJCQlsb2NhbCB3ID0gMAoJCQlsb2NhbCBmbGFnID0gMl5mcm9tCgkJCWZvciBpID0gMCwgd2lkdGgtMSBkbwoJCQkJbG9jYWwgZmxhZzIgPSBmbGFnICsgZmxhZwoJCQkJaWYgdiAlIGZsYWcyID49IGZsYWcgdGhlbgoJCQkJCXcgPSB3ICsgMl5pCgkJCQllbmQKCQkJCWZsYWcgPSBmbGFnMgoJCQllbmQKCQkJcmV0dXJuIHcKCQllbmQKCWVsc2UgLS0gTHVhIDUuMysKCQlleHRyYWN0ID0gbG9hZFtbcmV0dXJuIGZ1bmN0aW9uKCB2LCBmcm9tLCB3aWR0aCApCgkJCXJldHVybiAoIHYgPj4gZnJvbSApICYgKCgxIDw8IHdpZHRoKSAtIDEpCgkJZW5kXV0oKQoJZW5kCmVuZAoKCmZ1bmN0aW9uIGJhc2U2NC5tYWtlZW5jb2RlciggczYyLCBzNjMsIHNwYWQgKQoJbG9jYWwgZW5jb2RlciA9IHt9Cglmb3IgYjY0Y29kZSwgY2hhciBpbiBwYWlyc3tbMF09J0EnLCdCJywnQycsJ0QnLCdFJywnRicsJ0cnLCdIJywnSScsJ0onLAoJCSdLJywnTCcsJ00nLCdOJywnTycsJ1AnLCdRJywnUicsJ1MnLCdUJywnVScsJ1YnLCdXJywnWCcsJ1knLAoJCSdaJywnYScsJ2InLCdjJywnZCcsJ2UnLCdmJywnZycsJ2gnLCdpJywnaicsJ2snLCdsJywnbScsJ24nLAoJCSdvJywncCcsJ3EnLCdyJywncycsJ3QnLCd1JywndicsJ3cnLCd4JywneScsJ3onLCcwJywnMScsJzInLAoJCSczJywnNCcsJzUnLCc2JywnNycsJzgnLCc5JyxzNjIgb3IgJysnLHM2MyBvcicvJyxzcGFkIG9yJz0nfSBkbwoJCWVuY29kZXJbYjY0Y29kZV0gPSBjaGFyOmJ5dGUoKQoJZW5kCglyZXR1cm4gZW5jb2RlcgplbmQKCmZ1bmN0aW9uIGJhc2U2NC5tYWtlZGVjb2RlciggczYyLCBzNjMsIHNwYWQgKQoJbG9jYWwgZGVjb2RlciA9IHt9Cglmb3IgYjY0Y29kZSwgY2hhcmNvZGUgaW4gcGFpcnMoIGJhc2U2NC5tYWtlZW5jb2RlciggczYyLCBzNjMsIHNwYWQgKSkgZG8KCQlkZWNvZGVyW2NoYXJjb2RlXSA9IGI2NGNvZGUKCWVuZAoJcmV0dXJuIGRlY29kZXIKZW5kCgpsb2NhbCBERUZBVUxUX0VOQ09ERVIgPSBiYXNlNjQubWFrZWVuY29kZXIoKQpsb2NhbCBERUZBVUxUX0RFQ09ERVIgPSBiYXNlNjQubWFrZWRlY29kZXIoKQoKbG9jYWwgY2hhciwgY29uY2F0ID0gc3RyaW5nLmNoYXIsIHRhYmxlLmNvbmNhdAoKZnVuY3Rpb24gYmFzZTY0LmVuY29kZSggc3RyLCBlbmNvZGVyLCB1c2VjYWNoaW5nICkKCWVuY29kZXIgPSBlbmNvZGVyIG9yIERFRkFVTFRfRU5DT0RFUgoJbG9jYWwgdCwgaywgbiA9IHt9LCAxLCAjc3RyCglsb2NhbCBsYXN0biA9IG4gJSAzCglsb2NhbCBjYWNoZSA9IHt9Cglmb3IgaSA9IDEsIG4tbGFzdG4sIDMgZG8KCQlsb2NhbCBhLCBiLCBjID0gc3RyOmJ5dGUoIGksIGkrMiApCgkJbG9jYWwgdiA9IGEqMHgxMDAwMCArIGIqMHgxMDAgKyBjCgkJbG9jYWwgcwoJCWlmIHVzZWNhY2hpbmcgdGhlbgoJCQlzID0gY2FjaGVbdl0KCQkJaWYgbm90IHMgdGhlbgoJCQkJcyA9IGNoYXIoZW5jb2RlcltleHRyYWN0KHYsMTgsNildLCBlbmNvZGVyW2V4dHJhY3QodiwxMiw2KV0sIGVuY29kZXJbZXh0cmFjdCh2LDYsNildLCBlbmNvZGVyW2V4dHJhY3QodiwwLDYpXSkKCQkJCWNhY2hlW3ZdID0gcwoJCQllbmQKCQllbHNlCgkJCXMgPSBjaGFyKGVuY29kZXJbZXh0cmFjdCh2LDE4LDYpXSwgZW5jb2RlcltleHRyYWN0KHYsMTIsNildLCBlbmNvZGVyW2V4dHJhY3Qodiw2LDYpXSwgZW5jb2RlcltleHRyYWN0KHYsMCw2KV0pCgkJZW5kCgkJdFtrXSA9IHMKCQlrID0gayArIDEKCWVuZAoJaWYgbGFzdG4gPT0gMiB0aGVuCgkJbG9jYWwgYSwgYiA9IHN0cjpieXRlKCBuLTEsIG4gKQoJCWxvY2FsIHYgPSBhKjB4MTAwMDAgKyBiKjB4MTAwCgkJdFtrXSA9IGNoYXIoZW5jb2RlcltleHRyYWN0KHYsMTgsNildLCBlbmNvZGVyW2V4dHJhY3QodiwxMiw2KV0sIGVuY29kZXJbZXh0cmFjdCh2LDYsNildLCBlbmNvZGVyWzY0XSkKCWVsc2VpZiBsYXN0biA9PSAxIHRoZW4KCQlsb2NhbCB2ID0gc3RyOmJ5dGUoIG4gKSoweDEwMDAwCgkJdFtrXSA9IGNoYXIoZW5jb2RlcltleHRyYWN0KHYsMTgsNildLCBlbmNvZGVyW2V4dHJhY3QodiwxMiw2KV0sIGVuY29kZXJbNjRdLCBlbmNvZGVyWzY0XSkKCWVuZAoJcmV0dXJuIGNvbmNhdCggdCApCmVuZAoKZnVuY3Rpb24gYmFzZTY0LmRlY29kZSggYjY0LCBkZWNvZGVyLCB1c2VjYWNoaW5nICkKCWRlY29kZXIgPSBkZWNvZGVyIG9yIERFRkFVTFRfREVDT0RFUgoJbG9jYWwgcGF0dGVybiA9ICdbXiV3JSslLyU9XScKCWlmIGRlY29kZXIgdGhlbgoJCWxvY2FsIHM2MiwgczYzCgkJZm9yIGNoYXJjb2RlLCBiNjRjb2RlIGluIHBhaXJzKCBkZWNvZGVyICkgZG8KCQkJaWYgYjY0Y29kZSA9PSA2MiB0aGVuIHM2MiA9IGNoYXJjb2RlCgkJCWVsc2VpZiBiNjRjb2RlID09IDYzIHRoZW4gczYzID0gY2hhcmNvZGUKCQkJZW5kCgkJZW5kCgkJcGF0dGVybiA9ICgnW14lJXclJSVzJSUlcyUlPV0nKTpmb3JtYXQoIGNoYXIoczYyKSwgY2hhcihzNjMpICkKCWVuZAoJYjY0ID0gYjY0OmdzdWIoIHBhdHRlcm4sICcnICkKCWxvY2FsIGNhY2hlID0gdXNlY2FjaGluZyBhbmQge30KCWxvY2FsIHQsIGsgPSB7fSwgMQoJbG9jYWwgbiA9ICNiNjQKCWxvY2FsIHBhZGRpbmcgPSBiNjQ6c3ViKC0yKSA9PSAnPT0nIGFuZCAyIG9yIGI2NDpzdWIoLTEpID09ICc9JyBhbmQgMSBvciAwCglmb3IgaSA9IDEsIHBhZGRpbmcgPiAwIGFuZCBuLTQgb3IgbiwgNCBkbwoJCWxvY2FsIGEsIGIsIGMsIGQgPSBiNjQ6Ynl0ZSggaSwgaSszICkKCQlsb2NhbCBzCgkJaWYgdXNlY2FjaGluZyB0aGVuCgkJCWxvY2FsIHYwID0gYSoweDEwMDAwMDAgKyBiKjB4MTAwMDAgKyBjKjB4MTAwICsgZAoJCQlzID0gY2FjaGVbdjBdCgkJCWlmIG5vdCBzIHRoZW4KCQkJCWxvY2FsIHYgPSBkZWNvZGVyW2FdKjB4NDAwMDAgKyBkZWNvZGVyW2JdKjB4MTAwMCArIGRlY29kZXJbY10qMHg0MCArIGRlY29kZXJbZF0KCQkJCXMgPSBjaGFyKCBleHRyYWN0KHYsMTYsOCksIGV4dHJhY3Qodiw4LDgpLCBleHRyYWN0KHYsMCw4KSkKCQkJCWNhY2hlW3YwXSA9IHMKCQkJZW5kCgkJZWxzZQoJCQlsb2NhbCB2ID0gZGVjb2RlclthXSoweDQwMDAwICsgZGVjb2RlcltiXSoweDEwMDAgKyBkZWNvZGVyW2NdKjB4NDAgKyBkZWNvZGVyW2RdCgkJCXMgPSBjaGFyKCBleHRyYWN0KHYsMTYsOCksIGV4dHJhY3Qodiw4LDgpLCBleHRyYWN0KHYsMCw4KSkKCQllbmQKCQl0W2tdID0gcwoJCWsgPSBrICsgMQoJZW5kCglpZiBwYWRkaW5nID09IDEgdGhlbgoJCWxvY2FsIGEsIGIsIGMgPSBiNjQ6Ynl0ZSggbi0zLCBuLTEgKQoJCWxvY2FsIHYgPSBkZWNvZGVyW2FdKjB4NDAwMDAgKyBkZWNvZGVyW2JdKjB4MTAwMCArIGRlY29kZXJbY10qMHg0MAoJCXRba10gPSBjaGFyKCBleHRyYWN0KHYsMTYsOCksIGV4dHJhY3Qodiw4LDgpKQoJZWxzZWlmIHBhZGRpbmcgPT0gMiB0aGVuCgkJbG9jYWwgYSwgYiA9IGI2NDpieXRlKCBuLTMsIG4tMiApCgkJbG9jYWwgdiA9IGRlY29kZXJbYV0qMHg0MDAwMCArIGRlY29kZXJbYl0qMHgxMDAwCgkJdFtrXSA9IGNoYXIoIGV4dHJhY3QodiwxNiw4KSkKCWVuZAoJcmV0dXJuIGNvbmNhdCggdCApCmVuZAoKcmV0dXJuIGJhc2U2NAoKLS1bWwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KVGhpcyBzb2Z0d2FyZSBpcyBhdmFpbGFibGUgdW5kZXIgMiBsaWNlbnNlcyAtLSBjaG9vc2Ugd2hpY2hldmVyIHlvdSBwcmVmZXIuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpBTFRFUk5BVElWRSBBIC0gTUlUIExpY2Vuc2UKQ29weXJpZ2h0IChjKSAyMDE4IElseWEgS29sYmluClBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkgb2YKdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwgaW4KdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0bwp1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcwpvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8Kc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgpUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwKY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCkZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQpBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCkxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCk9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFClNPRlRXQVJFLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KQUxURVJOQVRJVkUgQiAtIFB1YmxpYyBEb21haW4gKHd3dy51bmxpY2Vuc2Uub3JnKQpUaGlzIGlzIGZyZWUgYW5kIHVuZW5jdW1iZXJlZCBzb2Z0d2FyZSByZWxlYXNlZCBpbnRvIHRoZSBwdWJsaWMgZG9tYWluLgpBbnlvbmUgaXMgZnJlZSB0byBjb3B5LCBtb2RpZnksIHB1Ymxpc2gsIHVzZSwgY29tcGlsZSwgc2VsbCwgb3IgZGlzdHJpYnV0ZSB0aGlzCnNvZnR3YXJlLCBlaXRoZXIgaW4gc291cmNlIGNvZGUgZm9ybSBvciBhcyBhIGNvbXBpbGVkIGJpbmFyeSwgZm9yIGFueSBwdXJwb3NlLApjb21tZXJjaWFsIG9yIG5vbi1jb21tZXJjaWFsLCBhbmQgYnkgYW55IG1lYW5zLgpJbiBqdXJpc2RpY3Rpb25zIHRoYXQgcmVjb2duaXplIGNvcHlyaWdodCBsYXdzLCB0aGUgYXV0aG9yIG9yIGF1dGhvcnMgb2YgdGhpcwpzb2Z0d2FyZSBkZWRpY2F0ZSBhbnkgYW5kIGFsbCBjb3B5cmlnaHQgaW50ZXJlc3QgaW4gdGhlIHNvZnR3YXJlIHRvIHRoZSBwdWJsaWMKZG9tYWluLiBXZSBtYWtlIHRoaXMgZGVkaWNhdGlvbiBmb3IgdGhlIGJlbmVmaXQgb2YgdGhlIHB1YmxpYyBhdCBsYXJnZSBhbmQgdG8KdGhlIGRldHJpbWVudCBvZiBvdXIgaGVpcnMgYW5kIHN1Y2Nlc3NvcnMuIFdlIGludGVuZCB0aGlzIGRlZGljYXRpb24gdG8gYmUgYW4Kb3ZlcnQgYWN0IG9mIHJlbGlucXVpc2htZW50IGluIHBlcnBldHVpdHkgb2YgYWxsIHByZXNlbnQgYW5kIGZ1dHVyZSByaWdodHMgdG8KdGhpcyBzb2Z0d2FyZSB1bmRlciBjb3B5cmlnaHQgbGF3LgpUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgpJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCkFVVEhPUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOCkFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04KV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotLV1dCmVuZApfRy5wYWNrYWdlLmxvYWRlZFsiLmJhc2U2NCJdID0gbG9hZF9iYXNlNjQoKQpwcmludCgibG9hZGVkIGJhc2U2NCIpCiAgCgoKbG9jYWwgZnVuY3Rpb24gbG9hZF9zdGF0ZSgpIAogIGFvID0gYW8gb3IgcmVxdWlyZSgnLmFvJykKbG9jYWwgc3RhdGUgPSB7fQpsb2NhbCBzdHJpbmdpZnkgPSByZXF1aXJlKCcuc3RyaW5naWZ5JykKbG9jYWwgdXRpbHMgPSByZXF1aXJlKCcudXRpbHMnKQoKQ29sb3JzID0geyByZWQgPSAiXDI3WzMxbSIsIGdyZWVuID0gIlwyN1szMm0iLAogIGJsdWUgPSAiXDI3WzM0bSIsIHJlc2V0ID0gIlwyN1swbSIsIGdyYXkgPSAiXDI3WzkwbSIKfQpCZWxsID0gIlx4MDciCgpJbml0aWFsaXplZCA9IEluaXRpYWxpemVkIG9yIGZhbHNlCk5hbWUgPSBOYW1lIG9yICJhb3MiCgpPd25lciA9IE93bmVyIG9yICIiCkluYm94ID0gSW5ib3ggb3Ige30KCi0tIGdsb2JhbCBwcm9tcHQgZnVuY3Rpb24KZnVuY3Rpb24gUHJvbXB0KCkKICByZXR1cm4gImFvcz4gIgplbmQKCmxvY2FsIG1heEluYm94Q291bnQgPSAxMDAwMAoKZnVuY3Rpb24gc3RhdGUuaW5zZXJ0SW5ib3gobXNnKQogIHRhYmxlLmluc2VydChJbmJveCwgbXNnKQogIGxvY2FsIG92ZXJmbG93ID0gI0luYm94IC0gbWF4SW5ib3hDb3VudAogIGZvciBpID0gMSxvdmVyZmxvdyBkbwogICAgdGFibGUucmVtb3ZlKEluYm94LDEpCiAgZW5kCmVuZApsb2NhbCBmdW5jdGlvbiBnZXRPd25lckFkZHJlc3MobSkKICBsb2NhbCBfb3duZXIgPSBuaWwgCiAgdXRpbHMubWFwKGZ1bmN0aW9uIChrKQogICAgbG9jYWwgYyA9IG0uY29tbWl0bWVudHNba10KICAgIGlmIGMuYWxnID09ICJyc2EtcHNzLXNoYTUxMiIgdGhlbgogICAgICBfb3duZXIgPSBjLmNvbW1pdHRlcgogICAgZWxzZWlmIGMuYWxnID09ICJzaWduZWQiIGFuZCBjWydjb21taXRtZW50LWRldmljZSddID09ICJhbnMxMDQiIHRoZW4KICAgICAgX293bmVyID0gYy5jb21taXRlcgogICAgZW5kCiAgZW5kLCB1dGlscy5rZXlzKG0uY29tbWl0bWVudHMpKQogIHJldHVybiBfb3duZXIKZW5kCgpsb2NhbCBmdW5jdGlvbiBpc0Zyb21Pd25lcihtKQogIGxvY2FsIF9vd25lciA9IGdldE93bmVyQWRkcmVzcyhtKQogIGxvY2FsIF9mcm9tUHJvY2VzcyA9IG1bJ2Zyb20tcHJvY2VzcyddIG9yIF9vd25lcgogIHJldHVybiBfb3duZXIgfj0gbmlsIGFuZCBfZnJvbVByb2Nlc3MgPT0gX293bmVyCmVuZAoKbG9jYWwgZnVuY3Rpb24gZ2V0T3duZXIobSkKICBsb2NhbCBpZCA9ICIiCiAgaWYgbVsnZnJvbS1wcm9jZXNzJ10gdGhlbgogICAgcmV0dXJuIG1bJ2Zyb20tcHJvY2VzcyddCiAgZW5kCgogIHV0aWxzLm1hcChmdW5jdGlvbiAoaykKICAgIGxvY2FsIGMgPSBtLmNvbW1pdG1lbnRzW2tdCiAgICBpZiBjLnR5cGUgPT0gInJzYS1wc3Mtc2hhNTEyIiB0aGVuCiAgICAgICAgaWQgPSBjLmNvbW1pdHRlcgogICAgZWxzZWlmIGMuYWxnID09ICJzaWduZWQiIGFuZCBjWydjb21taXRtZW50LWRldmljZSddID09ICJhbnMxMDQiIHRoZW4KICAgICAgICBpZCA9IGMuY29tbWl0dGVyCiAgICBlbmQKZW5kLCB1dGlscy5rZXlzKG0uY29tbWl0bWVudHMpCikKICByZXR1cm4gaWQKZW5kCgpmdW5jdGlvbiBzdGF0ZS5pbml0KHJlcSwgYmFzZSkKICBpZiBub3QgSW5pdGlhbGl6ZWQgdGhlbgogICAgT3duZXIgPSBnZXRPd25lcihiYXNlLnByb2Nlc3MpCiAgICAtLSBpZiBwcm9jZXNzIGlkIGlzIGVxdWFsIHRvIG1lc3NhZ2UgaWQgdGhlbiBzZXQgT3duZXIKICAgIC0tIFRPRE86IG5lZWQgYWRkaXRpb25hbCBjaGVjaywgbGlrZSBtc2cuU2xvdCA9PSAxCiAgICAtLSBpZiBlbnYuUHJvY2Vzcy5JZCA9PSBtc2cuSWQgYW5kIE93bmVyIH49IG1zZy5JZCB0aGVuCiAgICAtLSAgIE93bmVyID0gZW52LlByb2Nlc3NbJ0Zyb20tUHJvY2VzcyddIG9yIG1zZy5Gcm9tCiAgICAtLSBlbmQKICAgIC0tIGlmIGVudi5Qcm9jZXNzLk5hbWUgdGhlbgogICAgLS0gICBOYW1lID0gTmFtZSA9PSAiYW9zIiBhbmQgZW52LlByb2Nlc3MuTmFtZQogICAgLS0gZW5kCiAgICAtLSBnbG9iYWwgcHJpbnQgZnVuY3Rpb24KICAgIGZ1bmN0aW9uIHByaW50KGEpCiAgICAgIGlmIHR5cGUoYSkgPT0gInRhYmxlIiB0aGVuCiAgICAgICAgYSA9IHN0cmluZ2lmeS5mb3JtYXQoYSkKICAgICAgZW5kCgogICAgICBpZiB0eXBlKGEpID09ICJib29sZWFuIiB0aGVuCiAgICAgICAgYSA9IENvbG9ycy5ibHVlIC4uIHRvc3RyaW5nKGEpIC4uIENvbG9ycy5yZXNldAogICAgICBlbmQKICAgICAgaWYgdHlwZShhKSA9PSAibmlsIiB0aGVuCiAgICAgICAgYSA9IENvbG9ycy5yZWQgLi4gdG9zdHJpbmcoYSkgLi4gQ29sb3JzLnJlc2V0CiAgICAgIGVuZAogICAgICBpZiB0eXBlKGEpID09ICJudW1iZXIiIHRoZW4KICAgICAgICBhID0gQ29sb3JzLmdyZWVuIC4uIHRvc3RyaW5nKGEpIC4uIENvbG9ycy5yZXNldAogICAgICBlbmQKCiAgICAgIGlmIEhhbmRsZXJQcmludExvZ3MgdGhlbgogICAgICAgIHRhYmxlLmluc2VydChIYW5kbGVyUHJpbnRMb2dzLCBhKQogICAgICAgIHJldHVybiBuaWwKICAgICAgZW5kCgogICAgICByZXR1cm4gdG9zdHJpbmcoYSkKICAgIGVuZAoKICAgIEluaXRpYWxpemVkID0gdHJ1ZQogIGVuZAplbmQKCmZ1bmN0aW9uIHN0YXRlLmdldEZyb20ocmVxKQogIHJldHVybiBnZXRPd25lcihyZXEuYm9keSkKZW5kCgpmdW5jdGlvbiBzdGF0ZS5pc1RydXN0ZWQocmVxKQogIGlmIGlzRnJvbU93bmVyKHJlcS5ib2R5KSB0aGVuCiAgICByZXR1cm4gdHJ1ZQogIGVuZAogIGxvY2FsIF90cnVzdGVkID0gZmFsc2UKICAKICBpZiByZXEuYm9keVsnZnJvbS1wcm9jZXNzJ10gdGhlbgogICAgX3RydXN0ZWQgPSB1dGlscy5pbmNsdWRlcygKICAgICAgICByZXEuYm9keVsnZnJvbS1wcm9jZXNzJ10sCiAgICAgICAgYW8uYXV0aG9yaXRpZXMKICAgICkKZW5kCgppZiBub3QgX3RydXN0ZWQgdGhlbgogICAgX3RydXN0ZWQgPSB1dGlscy5pbmNsdWRlcygKICAgICAgICBnZXRPd25lcihyZXEuYm9keSksIGFvLmF1dGhvcml0aWVzCiAgICApCmVuZAoKICByZXR1cm4gX3RydXN0ZWQKZW5kCgpmdW5jdGlvbiBzdGF0ZS5jaGVja1Nsb3QocmVxLCBhbykKICAtLSBzbG90IGNoZWNrCiAgaWYgbm90IGFvLnNsb3QgdGhlbgogICAgYW8uc2xvdCA9IHRvbnVtYmVyKHJlcS5zbG90KQogIGVsc2UKICAgIGlmIHRvbnVtYmVyKHJlcS5zbG90KSB+PSAoYW8uc2xvdCArIDEpIHRoZW4KICAgICAgcHJpbnQodGFibGUuY29uY2F0KHsKICAgICAgQ29sb3JzLnJlZCwKICAgICAgIldBUk5JTkc6IFNsb3QgZGlkIG5vdCBtYXRjaCwgbWF5IGJlIGR1ZSB0byBhbiBlcnJvciBnZW5lcmF0ZWQgYnkgcHJvY2VzcyIsCiAgICAgIENvbG9ycy5yZXNldAogICAgICB9KSkKICAgICAgcHJpbnQoIiIpCiAgICBlbmQKICBlbmQKZW5kCgpmdW5jdGlvbiBzdGF0ZS5yZXNldCh0YmwpCiAgdGJsID0gbmlsCiAgY29sbGVjdGdhcmJhZ2UoKQogIHJldHVybiB7fQplbmQKCnJldHVybiBzdGF0ZQoKZW5kCl9HLnBhY2thZ2UubG9hZGVkWyIuc3RhdGUiXSA9IGxvYWRfc3RhdGUoKQpwcmludCgibG9hZGVkIHN0YXRlIikKICAKCgpsb2NhbCBmdW5jdGlvbiBsb2FkX3Byb2Nlc3MoKSAKICBhbyA9IGFvIG9yIHJlcXVpcmUoJy5hbycpCkhhbmRsZXJzID0gcmVxdWlyZSgnLmhhbmRsZXJzJykKVXRpbHMgPSByZXF1aXJlKCcudXRpbHMnKQpEdW1wID0gcmVxdWlyZSgnLmR1bXAnKQoKbG9jYWwgcHJvY2VzcyA9IHsgX3ZlcnNpb24gPSAiMi4wLjciIH0KbG9jYWwgc3RhdGUgPSByZXF1aXJlKCcuc3RhdGUnKQpsb2NhbCBldmFsID0gcmVxdWlyZSgnLmV2YWwnKQpsb2NhbCBkZWZhdWx0ID0gcmVxdWlyZSgnLmRlZmF1bHQnKQpsb2NhbCBqc29uID0gcmVxdWlyZSgnLmpzb24nKQoKZnVuY3Rpb24gUHJvbXB0KCkKICByZXR1cm4gImFvcz4gIgplbmQKCmZ1bmN0aW9uIHByb2Nlc3MuaGFuZGxlKHJlcSwgYmFzZSkKICBIYW5kbGVyUHJpbnRMb2dzID0gc3RhdGUucmVzZXQoSGFuZGxlclByaW50TG9ncykKICBvcy50aW1lID0gZnVuY3Rpb24gKCkgcmV0dXJuIHRvbnVtYmVyKHJlcVsnYmxvY2stdGltZXN0YW1wJ10pIGVuZAoKICBhby5pbml0KGJhc2UpCiAgLS0gaW5pdGlhbGl6ZSBzdGF0ZQogIHN0YXRlLmluaXQocmVxLCBiYXNlKQoKCiAgLS0gbWFnaWMgdGFibGUKICByZXEuYm9keS5kYXRhID0gcmVxLmJvZHlbJ0NvbnRlbnQtVHlwZSddID09ICdhcHBsaWNhdGlvbi9qc29uJwogICAgYW5kIGpzb24uZGVjb2RlKHJlcS5ib2R5LmRhdGEgb3IgInt9IikKICAgIG9yIHJlcS5ib2R5LmRhdGEKCiAgRXJyb3JzID0gRXJyb3JzIG9yIHt9CiAgLS0gY2xlYXIgb3V0Ym94CiAgYW8uY2xlYXJPdXRib3goKQoKICBpZiBub3Qgc3RhdGUuaXNUcnVzdGVkKHJlcSkgdGhlbgogICAgcmV0dXJuIGFvLnJlc3VsdCh7CiAgICAgIE91dHB1dCA9IHsKICAgICAgICBkYXRhID0gIk1lc3NhZ2UgaXMgbm90IHRydXN0ZWQuIgogICAgICB9CiAgICB9KQogIGVuZAogIHJlcS5yZXBseSA9IGZ1bmN0aW9uIChfcmVwbHkpCiAgICBsb2NhbCBfZnJvbSA9IHN0YXRlLmdldEZyb20ocmVxKQogICAgX3JlcGx5LnRhcmdldCA9IF9yZXBseS50YXJnZXQgYW5kIF9yZXBseS50YXJnZXQgb3IgX2Zyb20KICAgIF9yZXBseVsneC1yZWZlcmVuY2UnXSA9IHJlcS5ib2R5LnJlZmVyZW5jZSBvciBuaWwKICAgIF9yZXBseVsneC1vcmlnaW4nXSA9IHJlcS5ib2R5Wyd4LW9yaWdpbiddIG9yIG5pbAogICAgcmV0dXJuIGFvLnNlbmQoX3JlcGx5KQogIGVuZAoKCiAgLS0gc3RhdGUuY2hlY2tTbG90KG1zZywgYW8pCiAgSGFuZGxlcnMuYWRkKCJfZXZhbCIsIGZ1bmN0aW9uIChfcmVxKQogICAgbG9jYWwgZnVuY3Rpb24gZ2V0T3duZXJGcm9tKG0pCiAgICAgIGxvY2FsIGZyb20gPSAiIgogICAgICBVdGlscy5tYXAoCiAgICAgICAgZnVuY3Rpb24gKGspCiAgICAgICAgICBsb2NhbCBjID0gbS5jb21taXRtZW50c1trXQogICAgICAgICAgaWYgYy50eXBlID09ICJyc2EtcHNzLXNoYTUxMiIgdGhlbgogICAgICAgICAgICBmcm9tID0gYy5jb21taXR0ZXIKICAgICAgICAgIGVuZAogICAgICAgIGVuZCwKICAgICAgICBVdGlscy5rZXlzKG0uY29tbWl0bWVudHMpCiAgICAgICkKICAgICAgcmV0dXJuIGZyb20KICAgIGVuZAogICAgcmV0dXJuIF9yZXEuYm9keS5hY3Rpb24gPT0gIkV2YWwiIGFuZCBPd25lciA9PSBnZXRPd25lckZyb20oX3JlcS5ib2R5KQogIGVuZCwgZXZhbChhbykpCgogIEhhbmRsZXJzLmFkZCgiX2RlZmF1bHQiLAogICAgZnVuY3Rpb24gKCkgcmV0dXJuIHRydWUgZW5kLAogICAgZGVmYXVsdChzdGF0ZS5pbnNlcnRJbmJveCkKICApCgogIGxvY2FsIHN0YXR1cywgZXJyb3IgPSBwY2FsbChIYW5kbGVycy5ldmFsdWF0ZSwgcmVxLCBiYXNlKQoKICAtLSBjbGVhbnVwIGhhbmRsZXJzIHNvIHRoYXQgdGhleSBhcmUgYWx3YXlzIGF0IHRoZSBlbmQgb2YgdGhlIHBpcGVsaW5lCiAgSGFuZGxlcnMucmVtb3ZlKCJfZXZhbCIpCiAgSGFuZGxlcnMucmVtb3ZlKCJfZGVmYXVsdCIpCgogIGxvY2FsIHByaW50RGF0YSA9IHRhYmxlLmNvbmNhdChIYW5kbGVyUHJpbnRMb2dzLCAiXG4iKQogIGlmIG5vdCBzdGF0dXMgdGhlbgogICAgaWYgcmVxLmJvZHkuYWN0aW9uID09ICJFdmFsIiB0aGVuCiAgICAgIHJldHVybiB7CiAgICAgICAgRXJyb3IgPSB0YWJsZS5jb25jYXQoewogICAgICAgICAgcHJpbnREYXRhLAogICAgICAgICAgIlxuIiwKICAgICAgICAgIENvbG9ycy5yZWQsCiAgICAgICAgICAiZXJyb3I6ICIgLi4gZXJyb3IsCiAgICAgICAgICBDb2xvcnMucmVzZXQsCiAgICAgICAgfSkKICAgICAgfQogICAgZW5kCiAgICBwcmludChDb2xvcnMucmVkIC4uICJFcnJvciIgLi4gQ29sb3JzLmdyYXkgLi4gIiBoYW5kbGluZyBtZXNzYWdlICIgLi4gQ29sb3JzLnJlc2V0KQogICAgcHJpbnQoQ29sb3JzLmdyZWVuIC4uIGVycm9yIC4uIENvbG9ycy5yZXNldCkKICAgIC0tIHByaW50KCJcbiIgLi4gQ29sb3JzLmdyYXkgLi4gZGVidWcudHJhY2ViYWNrKCkgLi4gQ29sb3JzLnJlc2V0KQogICAgcmV0dXJuIGFvLnJlc3VsdCh7CiAgICAgIE91dHB1dCA9IHsKICAgICAgICBkYXRhID0gcHJpbnREYXRhIC4uICdcblxuJyAuLiBDb2xvcnMucmVkIC4uICdlcnJvcjpcbicgLi4gQ29sb3JzLnJlc2V0IC4uIGVycm9yCiAgICAgIH0sCiAgICAgIE1lc3NhZ2VzID0ge30sCiAgICAgIFNwYXducyA9IHt9LAogICAgICBBc3NpZ25tZW50cyA9IHt9CiAgICB9KQogIGVuZAoKICBsb2NhbCByZXNwb25zZSA9IHt9CgogIGlmIHJlcS5ib2R5LmFjdGlvbiA9PSAiRXZhbCIgdGhlbgogICAgcmVzcG9uc2UgPSBhby5yZXN1bHQoewogICAgICBPdXRwdXQgPSB7CiAgICAgICAgZGF0YSA9IHByaW50RGF0YSwKICAgICAgICBwcm9tcHQgPSBQcm9tcHQoKQogICAgICB9CiAgICB9KQogIGVsc2UKICAgIHJlc3BvbnNlID0gYW8ucmVzdWx0KHsKICAgICAgT3V0cHV0ID0gewogICAgICAgIGRhdGEgPSBwcmludERhdGEsCiAgICAgICAgcHJvbXB0ID0gUHJvbXB0KCksCiAgICAgICAgcHJpbnQgPSB0cnVlCiAgICAgIH0KICAgIH0pCiAgZW5kCgogIEhhbmRsZXJQcmludExvZ3MgPSBzdGF0ZS5yZXNldChIYW5kbGVyUHJpbnRMb2dzKSAtLSBjbGVhciBsb2dzCiAgLS0gYW8uU2xvdCA9IG1zZy5TbG90CiAgcmV0dXJuIHJlc3BvbnNlCmVuZAoKZnVuY3Rpb24gVmVyc2lvbigpCiAgcHJpbnQoInZlcnNpb246ICIgLi4gcHJvY2Vzcy5fdmVyc2lvbikKZW5kCgpyZXR1cm4gcHJvY2VzcwoKZW5kCl9HLnBhY2thZ2UubG9hZGVkWyIucHJvY2VzcyJdID0gbG9hZF9wcm9jZXNzKCkKcHJpbnQoImxvYWRlZCBwcm9jZXNzIikKICAKCmFvID0gcmVxdWlyZSgnLmFvJykKbG9jYWwgX3Byb2Nlc3MgPSByZXF1aXJlKCcucHJvY2VzcycpCgpmdW5jdGlvbiBjb21wdXRlKGJhc2UsIHJlcSwgb3B0cykKICBsb2NhbCBfcmVzdWx0cyA9IF9wcm9jZXNzLmhhbmRsZShyZXEsIGJhc2UpCiAgYmFzZS5yZXN1bHRzID0gewogICAgb3V0Ym94ID0ge30sCiAgICBvdXRwdXQgPSBfcmVzdWx0cy5PdXRwdXQKICB9CiAgZm9yIGk9MSwjX3Jlc3VsdHMuTWVzc2FnZXMgZG8KICAgIGJhc2UucmVzdWx0cy5vdXRib3hbdG9zdHJpbmcoaSldID0gX3Jlc3VsdHMuTWVzc2FnZXNbaV0KICBlbmQKICByZXR1cm4gYmFzZQplbmQKCgpwcmludCBbWyAgICAgXyAgICBfX18gIF9fX18gIAogICAgLyBcICAvIF8gXC8gX19ffCAKICAgLyBfIFx8IHwgfCBcX19fIFwgCiAgLyBfX18gXCB8X3wgfF9fXykgfAogL18vICAgXF9cX19fL3xfX19fLyAKICAgICAgICAgICAgICAgICAgICAgXV0K"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import express from "express"
|
|
2
|
+
import cors from "cors"
|
|
3
|
+
import bodyParser from "body-parser"
|
|
4
|
+
|
|
5
|
+
const run = (port = 4000) => {
|
|
6
|
+
const app = express()
|
|
7
|
+
app.use(cors())
|
|
8
|
+
app.use(
|
|
9
|
+
express.raw({
|
|
10
|
+
type: "application/octet-stream",
|
|
11
|
+
limit: "10mb",
|
|
12
|
+
})
|
|
13
|
+
)
|
|
14
|
+
app.use(express.json())
|
|
15
|
+
app.post("/relay", async (req, res) => {
|
|
16
|
+
res.json({ success: true, body: req.body.toString() })
|
|
17
|
+
})
|
|
18
|
+
return app.listen(port, () => console.log(`Hyper WAO on port ${port}`))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { run }
|