Docs/Skills and code/Top-level code
test-youtube-channel-fetch.mjs
What the file says about itself
YouTube Ecosystem Intelligence — YouTube channel fetch diagnostic Run: node test-youtube-channel-fetch.mjs - Installs its own dependencies into an isolated temp directory.
#!/usr/bin/env node
/**
* YouTube Ecosystem Intelligence — YouTube channel fetch diagnostic
*
* Run: node test-youtube-channel-fetch.mjs
*
* - Installs its own dependencies into an isolated temp directory.
* - Does not modify your project's package.json, lockfile, or database.
* - Tests youtubei.js channel resolution, metadata shape, video feed shape,
* available sort filters, sort application, pagination, and sort separation.
* - Cross-checks channel search with ytsearch.js.
* - Writes JSON + Markdown reports into the current working directory.
*
* Node.js 20+ recommended. Requires npm and internet access.
*/
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { spawnSync } from "node:child_process";
const VERSION = "1.0.6";
const WORK_DIR = path.join(os.tmpdir(), "youtube-ecosystem-fetch-diagnostic");
const RUNNER_PATH = path.join(WORK_DIR, "diagnostic-runner.mjs");
const PACKAGE_PATH = path.join(WORK_DIR, "package.json");
const OUTPUT_JSON = path.resolve(process.cwd(), "channel-fetch-diagnostic-output.json");
const OUTPUT_MD = path.resolve(process.cwd(), "channel-fetch-diagnostic-report.md");
function log(message, extra) {
console.log(`\n[bootstrap] ${message}`);
if (extra !== undefined) console.log(typeof extra === "string" ? extra : JSON.stringify(extra, null, 2));
}
function run(command, args, options = {}) {
const result = spawnSync(command, args, {
stdio: "inherit",
windowsHide: true,
...options
});
if (result.error) throw result.error;
if (result.status !== 0) throw new Error(`${command} ${args.join(" ")} exited with status ${result.status}`);
}
const runnerSource = Buffer.from("CmltcG9ydCBmcyBmcm9tICJub2RlOmZzIjsKaW1wb3J0IHBhdGggZnJvbSAibm9kZTpwYXRoIjsKaW1wb3J0IHsgcGF0aFRvRmlsZVVSTCB9IGZyb20gIm5vZGU6dXJsIjsKaW1wb3J0IHsgSW5uZXJ0dWJlIH0gZnJvbSAieW91dHViZWkuanMiOwppbXBvcnQgeyBzZWFyY2hZb3VUdWJlIH0gZnJvbSAieXRzZWFyY2guanMiOwoKY29uc3QgQ0hBTk5FTFMgPSBbCiAgeyBsYWJlbDogIkNOTiIsIGhhbmRsZTogImNubiIsIGNoYW5uZWxJZDogIlVDdXB2WkctNWtvX2VpWEF1cGJEZnhXdyIsIHVybDogImh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL0Bjbm4iLCBtYXhQYWdlczogNSB9LAogIHsgbGFiZWw6ICJHcmVhdCBBcnQgRXhwbGFpbmVkIiwgaGFuZGxlOiAiR3JlYXRBcnRFeHBsYWluZWQiLCB1cmw6ICJodHRwczovL3d3dy55b3V0dWJlLmNvbS9AR3JlYXRBcnRFeHBsYWluZWQiLCBtYXhQYWdlczogMyB9LAogIHsgbGFiZWw6ICJWYW4gR29naCBNdXNldW0iLCBoYW5kbGU6ICJWYW5Hb2doTXVzZXVtIiwgdXJsOiAiaHR0cHM6Ly93d3cueW91dHViZS5jb20vQFZhbkdvZ2hNdXNldW0iLCBtYXhQYWdlczogMyB9LAogIHsgbGFiZWw6ICJSb3lhbCBBY2FkZW15IG9mIEFydHMiLCBoYW5kbGU6ICJyb3lhbGFjYWRlbXkiLCB1cmw6ICJodHRwczovL3d3dy55b3V0dWJlLmNvbS9Acm95YWxhY2FkZW15IiB9LAogIHsgbGFiZWw6ICJNdXNldW0gb2YgRmluZSBBcnRzLCBCb3N0b24iLCBoYW5kbGU6ICJtZmFib3N0b24iLCB1cmw6ICJodHRwczovL3d3dy55b3V0dWJlLmNvbS9AbWZhYm9zdG9uIiB9LAogIHsgbGFiZWw6ICJUaGUgR2F6ZSIsIGhhbmRsZTogIlRoZUdhemUiLCB1cmw6ICJodHRwczovL3d3dy55b3V0dWJlLmNvbS9AVGhlR2F6ZSIgfQpdOwpjb25zdCBERUZBVUxUX01BWF9QQUdFUyA9IDM7CmNvbnN0IFNPUlRfRkFMTEJBQ0tfTEFCRUxTID0gWyJMYXRlc3QiLCAiUG9wdWxhciJdOwpjb25zdCBQQVVTRV9NUyA9IDkwMDsKY29uc3QgcmVwb3J0ID0gewogIGdlbmVyYXRlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksCiAgZGlhZ25vc3RpY1ZlcnNpb246ICIxLjAuNiIsCiAgcnVudGltZTogeyBub2RlOiBwcm9jZXNzLnZlcnNpb24sIHBsYXRmb3JtOiBwcm9jZXNzLnBsYXRmb3JtLCBhcmNoOiBwcm9jZXNzLmFyY2ggfSwKICB2ZXJzaW9uczoge30sCiAgc2V0dGluZ3M6IHsKICAgIGRlZmF1bHRNYXhQYWdlczogREVGQVVMVF9NQVhfUEFHRVMsCiAgICBjbm5NYXhQYWdlczogNSwKICAgIHBhdXNlTXM6IFBBVVNFX01TLAogICAgc3RyYXRlZ3k6ICJib3VuZGVkIHBhZ2luYXRpb24gcGlsb3Q7IGRvZXMgbm90IGF0dGVtcHQgYSBmdWxsLWNhdGFsb2d1ZSBjcmF3bCIKICB9LAogIGNoYW5uZWxzOiBbXSwKICB3YXJuaW5nczogW10sCiAgc3VtbWFyeToge30KfTsKCmNvbnN0IHNsZWVwID0gbXMgPT4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7CmNvbnN0IHRleHQgPSB2YWx1ZSA9PiB7CiAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBudWxsOwogIGlmICh0eXBlb2YgdmFsdWUgPT09ICJzdHJpbmciIHx8IHR5cGVvZiB2YWx1ZSA9PT0gIm51bWJlciIgfHwgdHlwZW9mIHZhbHVlID09PSAiYm9vbGVhbiIpIHJldHVybiB2YWx1ZTsKICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB2YWx1ZS5zbGljZSgwLCA4KS5tYXAodGV4dCk7CiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gIm9iamVjdCIpIHsKICAgIGlmICh0eXBlb2YgdmFsdWUudGV4dCA9PT0gInN0cmluZyIpIHJldHVybiB2YWx1ZS50ZXh0OwogICAgaWYgKHR5cGVvZiB2YWx1ZS50b1N0cmluZyA9PT0gImZ1bmN0aW9uIikgewogICAgICBjb25zdCBzID0gU3RyaW5nKHZhbHVlKTsKICAgICAgaWYgKHMgIT09ICJbb2JqZWN0IE9iamVjdF0iKSByZXR1cm4gczsKICAgIH0KICAgIHJldHVybiBzYWZlT2JqZWN0KHZhbHVlLCAwKTsKICB9CiAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7Cn07CmZ1bmN0aW9uIHNhZmVPYmplY3Qob2JqLCBkZXB0aCA9IDApIHsKICBpZiAob2JqID09IG51bGwgfHwgZGVwdGggPiAyKSByZXR1cm4gb2JqID09IG51bGwgPyBudWxsIDogIltkZXB0aC1saW1pdF0iOwogIGlmICh0eXBlb2Ygb2JqICE9PSAib2JqZWN0IikgcmV0dXJuIHRleHQob2JqKTsKICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSByZXR1cm4gb2JqLnNsaWNlKDAsIDgpLm1hcCh2ID0+IHNhZmVPYmplY3QodiwgZGVwdGggKyAxKSk7CiAgY29uc3Qgb3V0ID0ge307CiAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMob2JqKS5zbGljZSgwLCAzNSkpIHsKICAgIGNvbnN0IHYgPSBvYmpba2V5XTsKICAgIGlmICh0eXBlb2YgdiA9PT0gImZ1bmN0aW9uIikgY29udGludWU7CiAgICBpZiAoL2NsaWVudHxzZXNzaW9ufHRva2VufGNvb2tpZXxhdXRob3JpemF0aW9ufHZpc2l0b3JfZGF0YXxhcGlfa2V5L2kudGVzdChrZXkpKSB7CiAgICAgIG91dFtrZXldID0gIltvbWl0dGVkXSI7CiAgICAgIGNvbnRpbnVlOwogICAgfQogICAgaWYgKHYgPT0gbnVsbCB8fCBbInN0cmluZyIsICJudW1iZXIiLCAiYm9vbGVhbiJdLmluY2x1ZGVzKHR5cGVvZiB2KSkgb3V0W2tleV0gPSB2OwogICAgZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2KSkgb3V0W2tleV0gPSB2LnNsaWNlKDAsIDUpLm1hcCh4ID0+IHNhZmVPYmplY3QoeCwgZGVwdGggKyAxKSk7CiAgICBlbHNlIGlmIChkZXB0aCA8IDIpIG91dFtrZXldID0gc2FmZU9iamVjdCh2LCBkZXB0aCArIDEpOwogIH0KICByZXR1cm4gb3V0Owp9CmZ1bmN0aW9uIHNjYW5Tb3J0TWVudGlvbnMocm9vdCwgbWF4SXRlbXMgPSA4MCkgewogIGNvbnN0IG91dCA9IFtdOwogIGNvbnN0IHNlZW4gPSBuZXcgV2Vha1NldCgpOwogIGZ1bmN0aW9uIHZpc2l0KHZhbHVlLCBwYXRoID0gIiQiLCBkZXB0aCA9IDApIHsKICAgIGlmIChvdXQubGVuZ3RoID49IG1heEl0ZW1zIHx8IHZhbHVlID09IG51bGwgfHwgdHlwZW9mIHZhbHVlICE9PSAib2JqZWN0IiB8fCBkZXB0aCA+IDgpIHJldHVybjsKICAgIGlmIChzZWVuLmhhcyh2YWx1ZSkpIHJldHVybjsKICAgIHNlZW4uYWRkKHZhbHVlKTsKICAgIGNvbnN0IGVudHJpZXMgPSBBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlLnNsaWNlKDAsIDQwKS5tYXAoKHYsIGkpID0+IFtTdHJpbmcoaSksIHZdKSA6IE9iamVjdC5lbnRyaWVzKHZhbHVlKS5zbGljZSgwLCAxMDApOwogICAgZm9yIChjb25zdCBba2V5LCBjaGlsZF0gb2YgZW50cmllcykgewogICAgICBpZiAob3V0Lmxlbmd0aCA+PSBtYXhJdGVtcykgYnJlYWs7CiAgICAgIGNvbnN0IGNoaWxkUGF0aCA9IGAke3BhdGh9LiR7a2V5fWA7CiAgICAgIGlmICgvKHNvcnR8ZmlsdGVyfGNoaXB8ZHJvcGRvd258bWVudSkvaS50ZXN0KGtleSkpIHsKICAgICAgICBsZXQgdmFsdWVTdW1tYXJ5ID0gbnVsbDsKICAgICAgICBpZiAoY2hpbGQgPT0gbnVsbCB8fCBbInN0cmluZyIsICJudW1iZXIiLCAiYm9vbGVhbiJdLmluY2x1ZGVzKHR5cGVvZiBjaGlsZCkpIHZhbHVlU3VtbWFyeSA9IGNoaWxkOwogICAgICAgIGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoY2hpbGQpKSB2YWx1ZVN1bW1hcnkgPSBgYXJyYXkoJHtjaGlsZC5sZW5ndGh9KWA7CiAgICAgICAgZWxzZSB2YWx1ZVN1bW1hcnkgPSBgb2JqZWN0KCR7T2JqZWN0LmtleXMoY2hpbGQpLnNsaWNlKDAsIDEyKS5qb2luKCIsIil9KWA7CiAgICAgICAgb3V0LnB1c2goeyBwYXRoOiBjaGlsZFBhdGgsIHZhbHVlOiB2YWx1ZVN1bW1hcnkgfSk7CiAgICAgIH0KICAgICAgaWYgKGNoaWxkICYmIHR5cGVvZiBjaGlsZCA9PT0gIm9iamVjdCIpIHZpc2l0KGNoaWxkLCBjaGlsZFBhdGgsIGRlcHRoICsgMSk7CiAgICB9CiAgfQogIHZpc2l0KHJvb3QpOwogIHJldHVybiBvdXQ7Cn0KZnVuY3Rpb24gc2FmZVJlYWQob2JqLCBrZXkpIHsKICB0cnkgeyByZXR1cm4geyBvazogdHJ1ZSwgdmFsdWU6IG9iaj8uW2tleV0gfTsgfQogIGNhdGNoIChlcnJvcikgeyByZXR1cm4geyBvazogZmFsc2UsIGVycm9yOiBlcnJJbmZvKGVycm9yKSB9OyB9Cn0KZnVuY3Rpb24gc29ydFN1cmZhY2UoZmVlZCkgewogIC8vIFNvbWUgeW91dHViZWkuanMgdjE4IGdldHRlcnMgY2FzdCBwYWdlX2NvbnRlbnRzIHRvIFNlY3Rpb25MaXN0IGV2ZW4gd2hlbgogIC8vIHRoZSBhY3R1YWwgdGFiIHVzZXMgUmljaEdyaWQuIEEgZGlhZ25vc3RpYyBnZXR0ZXIgbXVzdCBuZXZlciBhYm9ydCBmZXRjaGluZy4KICBjb25zdCByZWFkID0ga2V5ID0+IHNhZmVSZWFkKGZlZWQsIGtleSk7CiAgY29uc3QgdG9BcnJheSA9IHJlc3VsdCA9PiByZXN1bHQub2sgJiYgQXJyYXkuaXNBcnJheShyZXN1bHQudmFsdWUpID8gcmVzdWx0LnZhbHVlLm1hcCh0ZXh0KSA6IFtdOwogIGNvbnN0IHNvcnQgPSByZWFkKCJzb3J0X2ZpbHRlcnMiKTsKICBjb25zdCBwcmltYXJ5ID0gcmVhZCgiZmlsdGVycyIpOwogIGNvbnN0IHNlY29uZGFyeSA9IHJlYWQoInNlY29uZGFyeV9maWx0ZXJzIik7CiAgY29uc3QgY29udGVudFR5cGUgPSByZWFkKCJjb250ZW50X3R5cGVfZmlsdGVycyIpOwogIGNvbnN0IG5vZGVzID0gcmVhZCgiZmlsdGVyX25vZGVzIik7CiAgY29uc3QgcGFnZSA9IHJlYWQoInBhZ2UiKTsKICByZXR1cm4gewogICAgc29ydEZpbHRlcnM6IHRvQXJyYXkoc29ydCksCiAgICBwcmltYXJ5RmlsdGVyczogdG9BcnJheShwcmltYXJ5KSwKICAgIHNlY29uZGFyeUZpbHRlcnM6IHRvQXJyYXkoc2Vjb25kYXJ5KSwKICAgIGNvbnRlbnRUeXBlRmlsdGVyczogdG9BcnJheShjb250ZW50VHlwZSksCiAgICBnZXR0ZXJFcnJvcnM6IE9iamVjdC5mcm9tRW50cmllcyhbWyJzb3J0X2ZpbHRlcnMiLCBzb3J0XSwgWyJmaWx0ZXJzIiwgcHJpbWFyeV0sCiAgICAgIFsic2Vjb25kYXJ5X2ZpbHRlcnMiLCBzZWNvbmRhcnldLCBbImNvbnRlbnRfdHlwZV9maWx0ZXJzIiwgY29udGVudFR5cGVdLAogICAgICBbImZpbHRlcl9ub2RlcyIsIG5vZGVzXV0uZmlsdGVyKChbLCByXSkgPT4gIXIub2spLm1hcCgoW2ssIHJdKSA9PiBbaywgci5lcnJvcl0pKSwKICAgIGZpbHRlck5vZGVzOiBub2Rlcy5vayA/IHNhZmVPYmplY3Qobm9kZXMudmFsdWUpIDogbnVsbCwKICAgIHBhZ2VLZXlzOiBwYWdlLm9rICYmIHBhZ2UudmFsdWUgJiYgdHlwZW9mIHBhZ2UudmFsdWUgPT09ICJvYmplY3QiID8gT2JqZWN0LmtleXMocGFnZS52YWx1ZSkuc2xpY2UoMCwgODApIDogW10sCiAgICBwYWdlU29ydE1lbnRpb25zOiBwYWdlLm9rID8gc2NhblNvcnRNZW50aW9ucyhwYWdlLnZhbHVlKSA6IFtdCiAgfTsKfQpmdW5jdGlvbiBmaXJzdERlZmluZWQoLi4udmFsdWVzKSB7CiAgcmV0dXJuIHZhbHVlcy5maW5kKHYgPT4gdiAhPT0gdW5kZWZpbmVkICYmIHYgIT09IG51bGwgJiYgdiAhPT0gIiIpOwp9CmZ1bmN0aW9uIHBpY2tUZXh0KC4uLnZhbHVlcykgewogIGNvbnN0IHYgPSBmaXJzdERlZmluZWQoLi4udmFsdWVzKTsKICBpZiAodiA9PSBudWxsKSByZXR1cm4gbnVsbDsKICBpZiAodHlwZW9mIHYgPT09ICJzdHJpbmciIHx8IHR5cGVvZiB2ID09PSAibnVtYmVyIikgcmV0dXJuIHY7CiAgaWYgKHR5cGVvZiB2ID09PSAib2JqZWN0IikgewogICAgaWYgKHYudGV4dCAhPSBudWxsKSByZXR1cm4gU3RyaW5nKHYudGV4dCk7CiAgICBpZiAodi5zaW1wbGVUZXh0ICE9IG51bGwpIHJldHVybiBTdHJpbmcodi5zaW1wbGVUZXh0KTsKICAgIGlmICh2LmNvbnRlbnQgIT0gbnVsbCkgcmV0dXJuIFN0cmluZyh2LmNvbnRlbnQpOwogICAgaWYgKHYudmFsdWUgIT0gbnVsbCkgcmV0dXJuIFN0cmluZyh2LnZhbHVlKTsKICB9CiAgcmV0dXJuIHRleHQodik7Cn0KZnVuY3Rpb24gdmlkZW9JZCh2aWRlbykgewogIHJldHVybiBmaXJzdERlZmluZWQoCiAgICB2aWRlbz8uaWQsIHZpZGVvPy52aWRlb19pZCwgdmlkZW8/LnZpZGVvSWQsIHZpZGVvPy5jb250ZW50X2lkLCB2aWRlbz8uY29udGVudElkLAogICAgdmlkZW8/LmVuZHBvaW50Py5wYXlsb2FkPy52aWRlb0lkLCB2aWRlbz8ubmF2aWdhdGlvbl9lbmRwb2ludD8ucGF5bG9hZD8udmlkZW9JZCwKICAgIHZpZGVvPy5vbl90YXBfZW5kcG9pbnQ/LnBheWxvYWQ/LnZpZGVvSWQsIHZpZGVvPy5yZW5kZXJlcl9jb250ZXh0Py5jb21tYW5kX2NvbnRleHQ/Lm9uX3RhcD8uaW5uZXJ0dWJlX2NvbW1hbmQ/LndhdGNoX2VuZHBvaW50Py52aWRlb0lkCiAgKSA/PyBudWxsOwp9CmZ1bmN0aW9uIHBhcnNlQ291bnQodmFsdWUpIHsKICBpZiAodHlwZW9mIHZhbHVlID09PSAibnVtYmVyIikgcmV0dXJuIE51bWJlci5pc0Zpbml0ZSh2YWx1ZSkgPyB2YWx1ZSA6IG51bGw7CiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gInN0cmluZyIpIHJldHVybiBudWxsOwogIGNvbnN0IG5vcm1hbGl6ZWQgPSB2YWx1ZS50cmltKCkucmVwbGFjZSgvLC9nLCAiIik7CiAgY29uc3QgbWF0Y2ggPSBub3JtYWxpemVkLm1hdGNoKC8oWzAtOV0rKD86XC5bMC05XSspPylccyooW0tNQl0pPy9pKTsKICBpZiAoIW1hdGNoKSByZXR1cm4gbnVsbDsKICBjb25zdCBhbW91bnQgPSBOdW1iZXIobWF0Y2hbMV0pOwogIGNvbnN0IG11bHRpcGxpZXIgPSAoeyBLOiAxZTMsIE06IDFlNiwgQjogMWU5IH0pW1N0cmluZyhtYXRjaFsyXSA/PyAiIikudG9VcHBlckNhc2UoKV0gPz8gMTsKICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKGFtb3VudCkgPyBhbW91bnQgKiBtdWx0aXBsaWVyIDogbnVsbDsKfQpmdW5jdGlvbiB2aWRlb1ZpZXdzKHZpZGVvKSB7CiAgcmV0dXJuIHBhcnNlQ291bnQoZmlyc3REZWZpbmVkKAogICAgdmlkZW8/LnZpZXdfY291bnQsIHZpZGVvPy52aWV3Q291bnQsIHZpZGVvPy52aWV3cywgdmlkZW8/LnNob3J0X3ZpZXdfY291bnQsIHZpZGVvPy5zaG9ydFZpZXdDb3VudCwKICAgIHZpZGVvPy52aWV3X2NvdW50X3RleHQsIHZpZGVvPy52aWV3Q291bnRUZXh0LCB2aWRlbz8uc2hvcnRfdmlld19jb3VudF90ZXh0LCB2aWRlbz8uc2hvcnRWaWV3Q291bnRUZXh0CiAgKSk7Cn0KZnVuY3Rpb24gdGV4dExlYXZlcyh2YWx1ZSwgbWF4RGVwdGggPSA2LCBzZWVuID0gbmV3IFNldCgpKSB7CiAgY29uc3Qgb3V0ID0gW107CiAgZnVuY3Rpb24gd2Fsayhub2RlLCBkZXB0aCkgewogICAgaWYgKG5vZGUgPT0gbnVsbCB8fCBkZXB0aCA+IG1heERlcHRoKSByZXR1cm47CiAgICBpZiAodHlwZW9mIG5vZGUgPT09ICJzdHJpbmciKSB7IGlmIChub2RlLnRyaW0oKSkgb3V0LnB1c2gobm9kZS50cmltKCkpOyByZXR1cm47IH0KICAgIGlmICh0eXBlb2Ygbm9kZSA9PT0gIm51bWJlciIgfHwgdHlwZW9mIG5vZGUgPT09ICJib29sZWFuIikgcmV0dXJuOwogICAgaWYgKHR5cGVvZiBub2RlICE9PSAib2JqZWN0IiB8fCBzZWVuLmhhcyhub2RlKSkgcmV0dXJuOwogICAgc2Vlbi5hZGQobm9kZSk7CiAgICBsZXQga2V5cyA9IFtdOwogICAgdHJ5IHsga2V5cyA9IE9iamVjdC5rZXlzKG5vZGUpOyB9IGNhdGNoIHsgcmV0dXJuOyB9CiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7CiAgICAgIHRyeSB7CiAgICAgICAgY29uc3QgY2hpbGQgPSBub2RlW2tleV07CiAgICAgICAgaWYgKGtleSA9PT0gInRleHQiIHx8IGtleSA9PT0gInNpbXBsZV90ZXh0IiB8fCBrZXkgPT09ICJjb250ZW50IikgewogICAgICAgICAgaWYgKHR5cGVvZiBjaGlsZCA9PT0gInN0cmluZyIgJiYgY2hpbGQudHJpbSgpKSBvdXQucHVzaChjaGlsZC50cmltKCkpOwogICAgICAgIH0KICAgICAgICB3YWxrKGNoaWxkLCBkZXB0aCArIDEpOwogICAgICB9IGNhdGNoIHt9CiAgICB9CiAgfQogIHdhbGsodmFsdWUsIDApOwogIHJldHVybiBbLi4ubmV3IFNldChvdXQpXTsKfQpmdW5jdGlvbiByZWxhdGl2ZURhdGVUZXh0KHN0cmluZ3MpIHsKICByZXR1cm4gc3RyaW5ncy5maW5kKHMgPT4gL1xcYig/OlxcZCtcXHMrKD86c2Vjb25kcz98bWludXRlcz98aG91cnM/fGRheXM/fHdlZWtzP3xtb250aHM/fHllYXJzPylcXHMrYWdvfHllc3RlcmRheXx0b2RheSlcXGIvaS50ZXN0KHMpKSA/PyBudWxsOwp9CmZ1bmN0aW9uIGFwcHJveGltYXRlUHVibGlzaGVkVGltZSh2YWx1ZSkgewogIGlmICghdmFsdWUpIHJldHVybiBudWxsOwogIGNvbnN0IGV4YWN0ID0gRGF0ZS5wYXJzZSh2YWx1ZSk7CiAgaWYgKCFOdW1iZXIuaXNOYU4oZXhhY3QpKSByZXR1cm4gZXhhY3Q7CiAgY29uc3Qgbm9ybWFsaXplZCA9IFN0cmluZyh2YWx1ZSkudG9Mb3dlckNhc2UoKTsKICBpZiAobm9ybWFsaXplZCA9PT0gInRvZGF5IikgcmV0dXJuIERhdGUubm93KCk7CiAgaWYgKG5vcm1hbGl6ZWQgPT09ICJ5ZXN0ZXJkYXkiKSByZXR1cm4gRGF0ZS5ub3coKSAtIDg2NDAwMDAwOwogIGNvbnN0IG0gPSBub3JtYWxpemVkLm1hdGNoKC8oXFxkKylcXHMrKHNlY29uZHxtaW51dGV8aG91cnxkYXl8d2Vla3xtb250aHx5ZWFyKXM/XFxzK2Fnby8pOwogIGlmICghbSkgcmV0dXJuIG51bGw7CiAgY29uc3QgbiA9IE51bWJlcihtWzFdKTsKICBjb25zdCB1bml0cyA9IHsgc2Vjb25kOiAxMDAwLCBtaW51dGU6IDYwMDAwLCBob3VyOiAzNjAwMDAwLCBkYXk6IDg2NDAwMDAwLCB3ZWVrOiA2MDQ4MDAwMDAsIG1vbnRoOiAyNjI5ODAwMDAwLCB5ZWFyOiAzMTU1NzYwMDAwMCB9OwogIHJldHVybiBEYXRlLm5vdygpIC0gbiAqIHVuaXRzW21bMl1dOwp9CmZ1bmN0aW9uIG5vcm1hbGl6ZVZpZGVvKHYpIHsKICBjb25zdCBzdHJpbmdzID0gdGV4dExlYXZlcyh2KTsKICBjb25zdCB2aWV3VGV4dCA9IHN0cmluZ3MuZmluZChzID0+IC9cXGJ2aWV3cz9cXGIvaS50ZXN0KHMpICYmIC9bMC05XS8udGVzdChzKSkgPz8gbnVsbDsKICBjb25zdCBwdWJsaXNoZWQgPSBwaWNrVGV4dCh2Py5wdWJsaXNoZWQsIHY/LnB1Ymxpc2hlZF90aW1lLCB2Py5wdWJsaXNoZWRUaW1lLCB2Py5wdWJsaXNoZWRfYXQsIHY/LnVwbG9hZF9kYXRlKQogICAgPz8gcmVsYXRpdmVEYXRlVGV4dChzdHJpbmdzKTsKICByZXR1cm4gewogICAgaWQ6IHZpZGVvSWQodiksCiAgICB0aXRsZTogcGlja1RleHQodj8udGl0bGUsIHY/LmhlYWRsaW5lLCB2Py5tZXRhZGF0YT8udGl0bGUpLAogICAgdmlld3M6IHZpZGVvVmlld3ModikgPz8gcGFyc2VDb3VudCh2aWV3VGV4dCksCiAgICB2aWV3c1Jhdzogdmlld1RleHQsCiAgICBwdWJsaXNoZWQsCiAgICBwdWJsaXNoZWRBcHByb3hNczogYXBwcm94aW1hdGVQdWJsaXNoZWRUaW1lKHB1Ymxpc2hlZCksCiAgICBkdXJhdGlvbjogcGlja1RleHQodj8uZHVyYXRpb24sIHY/Lmxlbmd0aF90ZXh0LCB2Py5sZW5ndGhUZXh0KSwKICAgIHR5cGU6IHY/LmNvbnN0cnVjdG9yPy5uYW1lID8/IHR5cGVvZiB2LAogICAgcmF3S2V5czogdiAmJiB0eXBlb2YgdiA9PT0gIm9iamVjdCIgPyBPYmplY3Qua2V5cyh2KS5zbGljZSgwLCA0MCkgOiBbXQogIH07Cn0KZnVuY3Rpb24gc3VtbWFyaXplQ2hhbm5lbChjaCwgYWJvdXQpIHsKICBjb25zdCBtID0gY2g/Lm1ldGFkYXRhID8/IHt9OwogIC8vIHlvdXR1YmVpLmpzIHYxOCByZXR1cm5zIEFib3V0Q2hhbm5lbCB7IG1ldGFkYXRhOiBBYm91dENoYW5uZWxWaWV3LCAuLi4gfS4KICAvLyBSZWFkIHRoZSBuZXN0ZWQgQWJvdXRDaGFubmVsVmlldyBmaWVsZHMgd2l0aG91dCBkaXNjYXJkaW5nIHRoZSByYXcgZW52ZWxvcGUuCiAgY29uc3QgYWJvdXRWaWV3ID0gYWJvdXQ/Lm1ldGFkYXRhID8/IGFib3V0Py5kYXRhPy5tZXRhZGF0YSA/PyBhYm91dCA/PyB7fTsKICByZXR1cm4gewogICAgY29uc3RydWN0b3I6IGNoPy5jb25zdHJ1Y3Rvcj8ubmFtZSA/PyBudWxsLAogICAgdGl0bGU6IHBpY2tUZXh0KGFib3V0Vmlldz8udGl0bGUsIGNoPy5oZWFkZXI/LnRpdGxlLCBtPy50aXRsZSwgY2g/LnRpdGxlKSwKICAgIGNoYW5uZWxJZDogZmlyc3REZWZpbmVkKGNoPy5pZCwgY2g/LmNoYW5uZWxfaWQsIGNoPy5jaGFubmVsSWQsIG0/LmV4dGVybmFsX2lkLCBhYm91dFZpZXc/LmNoYW5uZWxfaWQsIGFib3V0Vmlldz8uZXh0ZXJuYWxfaWQpID8/IG51bGwsCiAgICB1cmw6IGZpcnN0RGVmaW5lZChhYm91dFZpZXc/LmNhbm9uaWNhbF9jaGFubmVsX3VybCwgY2g/LnVybCwgY2g/LmNhbm9uaWNhbF91cmwsIG0/LnVybF9jYW5vbmljYWwsIG0/LnZhbml0eV9jaGFubmVsX3VybCkgPz8gbnVsbCwKICAgIGRlc2NyaXB0aW9uOiBwaWNrVGV4dChhYm91dFZpZXc/LmRlc2NyaXB0aW9uLCBjaD8uZGVzY3JpcHRpb24sIG0/LmRlc2NyaXB0aW9uKSwKICAgIHN1YnNjcmliZXJzOiBwaWNrVGV4dChhYm91dFZpZXc/LnN1YnNjcmliZXJfY291bnQsIGNoPy5zdWJzY3JpYmVyX2NvdW50LCBjaD8uc3Vic2NyaWJlcnMsIG0/LnN1YnNjcmliZXJfY291bnQpLAogICAgdG90YWxWaWV3czogcGlja1RleHQoYWJvdXRWaWV3Py52aWV3X2NvdW50KSwKICAgIHZpZGVvQ291bnQ6IHBpY2tUZXh0KGFib3V0Vmlldz8udmlkZW9fY291bnQsIGNoPy52aWRlb19jb3VudCwgY2g/LnZpZGVvc19jb3VudCwgbT8udmlkZW9fY291bnQpLAogICAgam9pbmVkRGF0ZTogcGlja1RleHQoYWJvdXRWaWV3Py5qb2luZWRfZGF0ZSwgYWJvdXRWaWV3Py5qb2luZWQsIGFib3V0Vmlldz8uam9pbmVkRGF0ZSksCiAgICBjb3VudHJ5OiBwaWNrVGV4dChhYm91dFZpZXc/LmNvdW50cnkpLAogICAgc29ydEZpbHRlcnM6ICgoKSA9PiB7IGNvbnN0IHIgPSBzYWZlUmVhZChjaCwgInNvcnRfZmlsdGVycyIpOyByZXR1cm4gci5vayAmJiBBcnJheS5pc0FycmF5KHIudmFsdWUpID8gci52YWx1ZS5tYXAodGV4dCkgOiBudWxsOyB9KSgpLAogICAgdGFiczogQXJyYXkuaXNBcnJheShjaD8udGFicykgPyBjaC50YWJzLm1hcCh0ZXh0KSA6IG51bGwsCiAgICBjdXJyZW50VGFiVGl0bGU6IHBpY2tUZXh0KGNoPy5jdXJyZW50X3RhYj8udGl0bGUsIGNoPy5jdXJyZW50X3RhYj8udGFiX3RpdGxlKSwKICAgIHJhd0tleXM6IGNoICYmIHR5cGVvZiBjaCA9PT0gIm9iamVjdCIgPyBPYmplY3Qua2V5cyhjaCkuc2xpY2UoMCwgNzApIDogW10sCiAgICBtZXRhZGF0YUtleXM6IG0gJiYgdHlwZW9mIG0gPT09ICJvYmplY3QiID8gT2JqZWN0LmtleXMobSkuc2xpY2UoMCwgNjApIDogW10sCiAgICBhYm91dEtleXM6IGFib3V0VmlldyAmJiB0eXBlb2YgYWJvdXRWaWV3ID09PSAib2JqZWN0IiA/IE9iamVjdC5rZXlzKGFib3V0Vmlldykuc2xpY2UoMCwgNjApIDogW10sCiAgICBhYm91dEVudmVsb3BlS2V5czogYWJvdXQgJiYgdHlwZW9mIGFib3V0ID09PSAib2JqZWN0IiA/IE9iamVjdC5rZXlzKGFib3V0KS5zbGljZSgwLCA2MCkgOiBbXSwKICAgIGFib3V0U2FtcGxlOiBzYWZlT2JqZWN0KGFib3V0KQogIH07Cn0KZnVuY3Rpb24gZmlsdGVyTWF0Y2goZmlsdGVycywgcmVnZXhlcykgewogIGZvciAoY29uc3QgZiBvZiBmaWx0ZXJzID8/IFtdKSB7CiAgICBjb25zdCBsYWJlbCA9IFN0cmluZyhmKTsKICAgIGlmIChyZWdleGVzLnNvbWUociA9PiByLnRlc3QobGFiZWwpKSkgcmV0dXJuIGxhYmVsOwogIH0KICByZXR1cm4gbnVsbDsKfQphc3luYyBmdW5jdGlvbiBjb2xsZWN0VmlkZW9zKGNoYW5uZWwsIG1heFBhZ2VzLCBsYWJlbCkgewogIGNvbnN0IHN0YXJ0ZWRBdE1zID0gRGF0ZS5ub3coKTsKICBjb25zdCByZXN1bHQgPSB7IHJlcXVlc3RlZFNvcnQ6IGxhYmVsLCBwYWdlczogW10sIHZpZGVvczogW10sIGVycm9yOiBudWxsLCBjb21wbGV0ZW5lc3M6ICJ1bmtub3duIiB9OwogIGxldCBwYWdlID0gY2hhbm5lbDsKICBjb25zdCBzZWVuID0gbmV3IFNldCgpOwogIGZvciAobGV0IHBhZ2VObyA9IDE7IHBhZ2VObyA8PSBtYXhQYWdlczsgcGFnZU5vKyspIHsKICAgIGxldCBpdGVtcyA9IFtdOwogICAgdHJ5IHsKICAgICAgY29uc3QgY2FuZGlkYXRlID0gcGFnZT8udmlkZW9zOwogICAgICBpZiAoY2FuZGlkYXRlICYmIHR5cGVvZiBjYW5kaWRhdGVbU3ltYm9sLml0ZXJhdG9yXSA9PT0gImZ1bmN0aW9uIikgaXRlbXMgPSBbLi4uY2FuZGlkYXRlXTsKICAgICAgZWxzZSBpZiAoQXJyYXkuaXNBcnJheShwYWdlKSkgaXRlbXMgPSBwYWdlOwogICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgcmVzdWx0LmVycm9yID0gYENvdWxkIG5vdCByZWFkIHBhZ2UudmlkZW9zOiAke2Vycm9yLm1lc3NhZ2V9YDsKICAgICAgYnJlYWs7CiAgICB9CiAgICBsZXQgYWRkZWQgPSAwOwogICAgbGV0IG1pc3NpbmdJZHMgPSAwOwogICAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1zKSB7CiAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVWaWRlbyhpdGVtKTsKICAgICAgaWYgKCFub3JtYWxpemVkLmlkKSB7IG1pc3NpbmdJZHMrKzsgY29udGludWU7IH0KICAgICAgaWYgKHNlZW4uaGFzKG5vcm1hbGl6ZWQuaWQpKSBjb250aW51ZTsKICAgICAgc2Vlbi5hZGQobm9ybWFsaXplZC5pZCk7CiAgICAgIHJlc3VsdC52aWRlb3MucHVzaChub3JtYWxpemVkKTsKICAgICAgYWRkZWQrKzsKICAgIH0KICAgIGNvbnN0IGNvbnRpbnVhdGlvblN0YXRlID0gc2FmZVJlYWQocGFnZSwgImhhc19jb250aW51YXRpb24iKTsKICAgIGNvbnN0IGhhc0NvbnRpbnVhdGlvbiA9IGNvbnRpbnVhdGlvblN0YXRlLm9rICYmIEJvb2xlYW4oY29udGludWF0aW9uU3RhdGUudmFsdWUpOwogICAgcmVzdWx0LnBhZ2VzLnB1c2goewogICAgICBwYWdlOiBwYWdlTm8sCiAgICAgIGNvbnN0cnVjdG9yOiBwYWdlPy5jb25zdHJ1Y3Rvcj8ubmFtZSA/PyBudWxsLAogICAgICByYXdJdGVtQ291bnQ6IGl0ZW1zLmxlbmd0aCwKICAgICAgYWNjZXB0ZWRVbmlxdWVXaXRoSWQ6IGFkZGVkLAogICAgICBtaXNzaW5nSWRDb3VudDogbWlzc2luZ0lkcywKICAgICAgaGFzQ29udGludWF0aW9uLAogICAgICBrZXlzOiBwYWdlICYmIHR5cGVvZiBwYWdlID09PSAib2JqZWN0IiA/IE9iamVjdC5rZXlzKHBhZ2UpLnNsaWNlKDAsIDMwKSA6IFtdLAogICAgICBpdGVtU2FtcGxlczogaXRlbXMuc2xpY2UoMCwgMykubWFwKGl0ZW0gPT4gKHsKICAgICAgICBjb25zdHJ1Y3RvcjogaXRlbT8uY29uc3RydWN0b3I/Lm5hbWUgPz8gdHlwZW9mIGl0ZW0sCiAgICAgICAga2V5czogaXRlbSAmJiB0eXBlb2YgaXRlbSA9PT0gIm9iamVjdCIgPyBPYmplY3Qua2V5cyhpdGVtKS5zbGljZSgwLCA1MCkgOiBbXSwKICAgICAgICBpZENhbmRpZGF0ZXM6IHsKICAgICAgICAgIGlkOiBpdGVtPy5pZCA/PyBudWxsLAogICAgICAgICAgdmlkZW9faWQ6IGl0ZW0/LnZpZGVvX2lkID8/IG51bGwsCiAgICAgICAgICB2aWRlb0lkOiBpdGVtPy52aWRlb0lkID8/IG51bGwsCiAgICAgICAgICBjb250ZW50X2lkOiBpdGVtPy5jb250ZW50X2lkID8/IG51bGwsCiAgICAgICAgICBjb250ZW50SWQ6IGl0ZW0/LmNvbnRlbnRJZCA/PyBudWxsCiAgICAgICAgfSwKICAgICAgICBzYW1wbGU6IHNhZmVPYmplY3QoaXRlbSkKICAgICAgfSkpCiAgICB9KTsKICAgIGNvbnNvbGUubG9nKGBbZmVlZDoke2xhYmVsfV0gcGFnZT0ke3BhZ2VOb30gcmF3PSR7aXRlbXMubGVuZ3RofSBhZGRlZD0ke2FkZGVkfSBjb250aW51YXRpb249JHtoYXNDb250aW51YXRpb259YCk7CiAgICBpZiAoIWhhc0NvbnRpbnVhdGlvbiB8fCB0eXBlb2YgcGFnZT8uZ2V0Q29udGludWF0aW9uICE9PSAiZnVuY3Rpb24iKSB7CiAgICAgIHJlc3VsdC5jb21wbGV0ZW5lc3MgPSAiZmVlZC1lbmRlZCI7CiAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKHBhZ2VObyA9PT0gbWF4UGFnZXMpIHsKICAgICAgcmVzdWx0LmNvbXBsZXRlbmVzcyA9ICJwYWdlLWxpbWl0LXJlYWNoZWQiOwogICAgICBicmVhazsKICAgIH0KICAgIHRyeSB7CiAgICAgIGF3YWl0IHNsZWVwKFBBVVNFX01TKTsKICAgICAgcGFnZSA9IGF3YWl0IHBhZ2UuZ2V0Q29udGludWF0aW9uKCk7CiAgICB9IGNhdGNoIChlcnJvcikgewogICAgICByZXN1bHQuZXJyb3IgPSBgQ29udGludWF0aW9uIGZhaWxlZCBhZnRlciBwYWdlICR7cGFnZU5vfTogJHtlcnJvcj8uc3RhY2sgPz8gZXJyb3J9YDsKICAgICAgcmVzdWx0LmNvbXBsZXRlbmVzcyA9ICJjb250aW51YXRpb24tZXJyb3IiOwogICAgICBicmVhazsKICAgIH0KICB9CiAgcmVzdWx0LmVsYXBzZWRNcyA9IERhdGUubm93KCkgLSBzdGFydGVkQXRNczsKICByZXN1bHQudW5pcXVlQ291bnQgPSByZXN1bHQudmlkZW9zLmxlbmd0aDsKICByZXN1bHQuaWRzID0gcmVzdWx0LnZpZGVvcy5tYXAodiA9PiB2LmlkKTsKICByZXN1bHQudmlld3NBdmFpbGFibGUgPSByZXN1bHQudmlkZW9zLmZpbHRlcih2ID0+IHYudmlld3MgIT0gbnVsbCkubGVuZ3RoOwogIHJlc3VsdC5kYXRlc0F2YWlsYWJsZSA9IHJlc3VsdC52aWRlb3MuZmlsdGVyKHYgPT4gdi5wdWJsaXNoZWQgIT0gbnVsbCkubGVuZ3RoOwogIHJldHVybiByZXN1bHQ7Cn0KZnVuY3Rpb24gbG9jYWxTb3J0UHJvYmUodmlkZW9zKSB7CiAgY29uc3QgdmFsaWREYXRlcyA9IHZpZGVvcy5maWx0ZXIodiA9PiBOdW1iZXIuaXNGaW5pdGUodi5wdWJsaXNoZWRBcHByb3hNcykpOwogIGNvbnN0IHZhbGlkVmlld3MgPSB2aWRlb3MuZmlsdGVyKHYgPT4gTnVtYmVyLmlzRmluaXRlKHYudmlld3MpKTsKICBjb25zdCBieVRpdGxlID0gWy4uLnZpZGVvc10uZmlsdGVyKHYgPT4gdi50aXRsZSkuc29ydCgoYSwgYikgPT4gYS50aXRsZS5sb2NhbGVDb21wYXJlKGIudGl0bGUpKTsKICBjb25zdCBieURhdGUgPSBbLi4udmFsaWREYXRlc10uc29ydCgoYSwgYikgPT4gYi5wdWJsaXNoZWRBcHByb3hNcyAtIGEucHVibGlzaGVkQXBwcm94TXMpOwogIGNvbnN0IGJ5Vmlld3MgPSBbLi4udmFsaWRWaWV3c10uc29ydCgoYSwgYikgPT4gYi52aWV3cyAtIGEudmlld3MpOwogIHJldHVybiB7CiAgICBzYW1wbGVkVmlkZW9Db3VudDogdmlkZW9zLmxlbmd0aCwKICAgIHVuaXF1ZUlkczogbmV3IFNldCh2aWRlb3MubWFwKHYgPT4gdi5pZCkuZmlsdGVyKEJvb2xlYW4pKS5zaXplLAogICAgdGl0bGVBdmFpbGFibGU6IHZpZGVvcy5maWx0ZXIodiA9PiB2LnRpdGxlKS5sZW5ndGgsCiAgICBkYXRlQXZhaWxhYmxlOiB2YWxpZERhdGVzLmxlbmd0aCwKICAgIG51bWVyaWNWaWV3Q291bnRBdmFpbGFibGU6IHZhbGlkVmlld3MubGVuZ3RoLAogICAgbG9jYWxUaXRsZVNvcnQ6IGJ5VGl0bGUuc2xpY2UoMCwgNSkubWFwKHYgPT4gKHsgaWQ6IHYuaWQsIHRpdGxlOiB2LnRpdGxlIH0pKSwKICAgIGxvY2FsTmV3ZXN0U29ydDogYnlEYXRlLnNsaWNlKDAsIDUpLm1hcCh2ID0+ICh7IGlkOiB2LmlkLCB0aXRsZTogdi50aXRsZSwgcHVibGlzaGVkOiB2LnB1Ymxpc2hlZCwgYXBwcm94aW1hdGU6ICF2LnB1Ymxpc2hlZCB8fCBOdW1iZXIuaXNOYU4oRGF0ZS5wYXJzZSh2LnB1Ymxpc2hlZCkpIH0pKSwKICAgIGxvY2FsUG9wdWxhclNvcnQ6IGJ5Vmlld3Muc2xpY2UoMCwgNSkubWFwKHYgPT4gKHsgaWQ6IHYuaWQsIHRpdGxlOiB2LnRpdGxlLCB2aWV3czogdi52aWV3cyB9KSksCiAgICBjb25jbHVzaW9uOiB2YWxpZERhdGVzLmxlbmd0aCA+PSAzICYmIHZhbGlkVmlld3MubGVuZ3RoID49IDMKICAgICAgPyAiU2FtcGxlIHN1cHBvcnRzIGxvY2FsIGxhdGVzdC9wb3B1bGFyIHNvcnRpbmcsIGJ1dCBub3QgY2F0YWxvZ3VlIGNvbXBsZXRlbmVzcy4iCiAgICAgIDogIklEcy90aXRsZXMgY2FuIGJlIHNvcnRlZCBsb2NhbGx5OyBsYXRlc3QvcG9wdWxhciBuZWVkIGRhdGUvdmlldyBtZXRhZGF0YSBlbnJpY2htZW50IGZvciBtb3N0IGl0ZW1zLiIKICB9Owp9CmZ1bmN0aW9uIHBhcnNlQXBwcm94Q291bnQodmFsdWUpIHsKICBpZiAodHlwZW9mIHZhbHVlID09PSAibnVtYmVyIikgcmV0dXJuIHZhbHVlOwogIGlmICh0eXBlb2YgdmFsdWUgIT09ICJzdHJpbmciKSByZXR1cm4gbnVsbDsKICBjb25zdCBjbGVhbmVkID0gdmFsdWUudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC8sL2csICIiKS50cmltKCk7CiAgY29uc3QgbSA9IGNsZWFuZWQubWF0Y2goLyhbMC05XSsoPzpcXC5bMC05XSspPylcXHMqKFtrbWJdKT8vKTsKICBpZiAoIW0pIHJldHVybiBudWxsOwogIHJldHVybiBNYXRoLnJvdW5kKE51bWJlcihtWzFdKSAqICh7IGs6IDFlMywgbTogMWU2LCBiOiAxZTkgfVttWzJdXSA/PyAxKSk7Cn0KZnVuY3Rpb24gb3ZlcmxhcChhLCBiKSB7CiAgY29uc3QgQSA9IG5ldyBTZXQoYSA/PyBbXSksIEIgPSBuZXcgU2V0KGIgPz8gW10pOwogIGNvbnN0IGludGVyc2VjdGlvbiA9IFsuLi5BXS5maWx0ZXIoeCA9PiBCLmhhcyh4KSkubGVuZ3RoOwogIGNvbnN0IHVuaW9uID0gbmV3IFNldChbLi4uQSwgLi4uQl0pLnNpemU7CiAgcmV0dXJuIHsgYTogQS5zaXplLCBiOiBCLnNpemUsIGludGVyc2VjdGlvbiwgdW5pb24sIGphY2NhcmQ6IHVuaW9uID8gTnVtYmVyKChpbnRlcnNlY3Rpb24gLyB1bmlvbikudG9GaXhlZCg0KSkgOiBudWxsIH07Cn0KZnVuY3Rpb24gZGVzY2VuZGluZ1ZpZXdzKHZpZGVvcykgewogIGNvbnN0IHdpdGhWaWV3cyA9IHZpZGVvcy5maWx0ZXIodiA9PiBOdW1iZXIuaXNGaW5pdGUodi52aWV3cykpOwogIGlmICh3aXRoVmlld3MubGVuZ3RoIDwgMykgcmV0dXJuIHsgY2hlY2tlZDogZmFsc2UsIHJlYXNvbjogIkZld2VyIHRoYW4gdGhyZWUgdmlkZW9zIGV4cG9zZSBhIHBhcnNlYWJsZSB2aWV3IGNvdW50LiIsIG1vbm90b25pYzogbnVsbCwgd2l0aFZpZXdzOiB3aXRoVmlld3MubGVuZ3RoIH07CiAgY29uc3QgdmFsdWVzID0gd2l0aFZpZXdzLm1hcCh2ID0+IHYudmlld3MpOwogIGxldCB2aW9sYXRpb25zID0gMDsKICBmb3IgKGxldCBpID0gMTsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykgaWYgKHZhbHVlc1tpXSA+IHZhbHVlc1tpIC0gMV0pIHZpb2xhdGlvbnMrKzsKICByZXR1cm4geyBjaGVja2VkOiB0cnVlLCB3aXRoVmlld3M6IHZhbHVlcy5sZW5ndGgsIG1vbm90b25pYzogdmlvbGF0aW9ucyA9PT0gMCwgYWRqYWNlbnRPcmRlclZpb2xhdGlvbnM6IHZpb2xhdGlvbnMsIGNhdmVhdDogIk9ubHkgdGVzdHMgdGhlIHJldHVybmVkIG9yZGVyOyB2aWV3IGNvdW50cyBtYXkgYmUgYWJzZW50IG9yIHN0YWxlLiIgfTsKfQpmdW5jdGlvbiBlcnJJbmZvKGVycm9yKSB7CiAgcmV0dXJuIHsgbmFtZTogZXJyb3I/Lm5hbWUgPz8gIkVycm9yIiwgbWVzc2FnZTogZXJyb3I/Lm1lc3NhZ2UgPz8gU3RyaW5nKGVycm9yKSwgc3RhY2s6IFN0cmluZyhlcnJvcj8uc3RhY2sgPz8gIiIpLnNwbGl0KCJcbiIpLnNsaWNlKDAsIDcpLmpvaW4oIlxuIikgfTsKfQoKYXN5bmMgZnVuY3Rpb24gbWFpbigpIHsKICBjb25zb2xlLmxvZygiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Iik7CiAgY29uc29sZS5sb2coIkFSVCBJTlRFTExJR0VOQ0Ug4oCUIExJVkUgQ0hBTk5FTCBGRVRDSCBESUFHTk9TVElDIik7CiAgY29uc29sZS5sb2coIk5vIGRhdGFiYXNlIHdyaXRlcy4gUHVibGljIFlvdVR1YmUgcGFnZXMgb25seS4iKTsKICBjb25zb2xlLmxvZygiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Iik7CiAgcmVwb3J0LnZlcnNpb25zLnlvdXR1YmVpID0gImluc3RhbGxlZCBwYWNrYWdlIjsKICByZXBvcnQudmVyc2lvbnMueXRzZWFyY2ggPSAiaW5zdGFsbGVkIHBhY2thZ2UiOwogIGNvbnN0IHl0ID0gYXdhaXQgSW5uZXJ0dWJlLmNyZWF0ZSgpOwogIGNvbnNvbGUubG9nKCJbaW5pdF0gSW5uZXJ0dWJlIGNsaWVudCBjcmVhdGVkLiIpOwoKICBmb3IgKGNvbnN0IHNlZWQgb2YgQ0hBTk5FTFMpIHsKICAgIGNvbnN0IHJvdyA9IHsKICAgICAgc2VlZCwKICAgICAgc3RhcnRlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksCiAgICAgIGlkZW50aXR5OiBudWxsLAogICAgICBtZXRhZGF0YTogbnVsbCwKICAgICAgcmF3U29ydEZpbHRlcnM6IG51bGwsCiAgICAgIHZpZGVvVGFiUHJvYmU6IG51bGwsCiAgICAgIGRlZmF1bHRGZWVkOiBudWxsLAogICAgICBsYXRlc3RGZWVkOiBudWxsLAogICAgICBwb3B1bGFyRmVlZDogbnVsbCwKICAgICAgc29ydENvbXBhcmlzb246IG51bGwsCiAgICAgIHl0c2VhcmNoQ3Jvc3NDaGVjazogbnVsbCwKICAgICAgZXJyb3JzOiBbXSwKICAgICAgc3RhdHVzOiAic3RhcnRlZCIKICAgIH07CiAgICByZXBvcnQuY2hhbm5lbHMucHVzaChyb3cpOwogICAgY29uc29sZS5sb2coIlxuXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKTsKICAgIGNvbnNvbGUubG9nKGBbY2hhbm5lbF0gJHtzZWVkLmxhYmVsfSDigJQgJHtzZWVkLnVybH1gKTsKICAgIGNvbnNvbGUubG9nKCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKTsKCiAgICAvLyBSZXNvbHZlIHRoZSBAaGFuZGxlIHRvIGEgc3RhYmxlIGNoYW5uZWwgSUQgZmlyc3QuIHlvdXR1YmVpLmpzIHYxOAogICAgLy8gZ2V0Q2hhbm5lbCgpIGV4cGVjdHMgYSBjaGFubmVsIElELCBub3QgYSBjaGFubmVsIFVSTC4KICAgIHRyeSB7CiAgICAgIGF3YWl0IHNsZWVwKFBBVVNFX01TKTsKICAgICAgY29uc3Qgc2VhcmNoID0gYXdhaXQgc2VhcmNoWW91VHViZShzZWVkLmhhbmRsZSwgeyB0eXBlOiAiY2hhbm5lbCIsIGxpbWl0OiAxMCB9KTsKICAgICAgY29uc3QgY2hhbm5lbHMgPSBBcnJheS5pc0FycmF5KHNlYXJjaD8uY2hhbm5lbHMpID8gc2VhcmNoLmNoYW5uZWxzIDogW107CiAgICAgIHJvdy55dHNlYXJjaENyb3NzQ2hlY2sgPSB7CiAgICAgICAgcmVzdWx0Q291bnQ6IGNoYW5uZWxzLmxlbmd0aCwKICAgICAgICBtZXRhZGF0YTogc2FmZU9iamVjdChzZWFyY2g/Lm1ldGFkYXRhKSwKICAgICAgICBtYXRjaGVzOiBjaGFubmVscy5zbGljZSgwLCAxMCkubWFwKGMgPT4gKHsKICAgICAgICAgIHRpdGxlOiBwaWNrVGV4dChjPy50aXRsZSwgYz8ubmFtZSksCiAgICAgICAgICBpZDogZmlyc3REZWZpbmVkKGM/LmlkLCBjPy5jaGFubmVsSWQsIGM/LmNoYW5uZWxfaWQpID8/IG51bGwsCiAgICAgICAgICB1cmw6IGZpcnN0RGVmaW5lZChjPy51cmwsIGM/LmNoYW5uZWxVcmwsIGM/LmNoYW5uZWxfdXJsKSA/PyBudWxsLAogICAgICAgICAgc3Vic2NyaWJlcnM6IHBpY2tUZXh0KGM/LnN1YnNjcmliZXJDb3VudCwgYz8uc3Vic2NyaWJlcl9jb3VudCwgYz8uc3Vic2NyaWJlcnMpLAogICAgICAgICAgdmVyaWZpZWQ6IGZpcnN0RGVmaW5lZChjPy52ZXJpZmllZCwgYz8uaXNWZXJpZmllZCkgPz8gbnVsbCwKICAgICAgICAgIHJhd0tleXM6IGMgJiYgdHlwZW9mIGMgPT09ICJvYmplY3QiID8gT2JqZWN0LmtleXMoYykuc2xpY2UoMCwgMzUpIDogW10KICAgICAgICB9KSkKICAgICAgfTsKICAgICAgY29uc29sZS5sb2coIlt5dHNlYXJjaC5qcyBjaGFubmVsIHJlc29sdXRpb25dIiwgSlNPTi5zdHJpbmdpZnkocm93Lnl0c2VhcmNoQ3Jvc3NDaGVjaywgbnVsbCwgMikpOwogICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgcm93LmVycm9ycy5wdXNoKHsgc3RhZ2U6ICJ5dHNlYXJjaC5jaGFubmVsU2VhcmNoIiwgLi4uZXJySW5mbyhlcnJvcikgfSk7CiAgICAgIGNvbnNvbGUuZXJyb3IoIltFUlJPUl0geXRzZWFyY2guanMgY2hhbm5lbCByZXNvbHV0aW9uIGZhaWxlZDoiLCBlcnJvcj8uc3RhY2sgPz8gZXJyb3IpOwogICAgfQoKICAgIGNvbnN0IGV4cGVjdGVkSGFuZGxlID0gc2VlZC5oYW5kbGUudG9Mb3dlckNhc2UoKTsKICAgIGNvbnN0IGV4YWN0TWF0Y2ggPSByb3cueXRzZWFyY2hDcm9zc0NoZWNrPy5tYXRjaGVzPy5maW5kKG1hdGNoID0+IHsKICAgICAgdHJ5IHsKICAgICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKG1hdGNoLnVybCk7CiAgICAgICAgY29uc3QgYWN0dWFsSGFuZGxlID0gdXJsLnBhdGhuYW1lLnJlcGxhY2UoL15cL0A/LywgIiIpLnJlcGxhY2UoL15ALywgIiIpLnJlcGxhY2UoL1wvJC8sICIiKS50b0xvd2VyQ2FzZSgpOwogICAgICAgIHJldHVybiBhY3R1YWxIYW5kbGUgPT09IGV4cGVjdGVkSGFuZGxlICYmIC9eVUNbXHctXSskLy50ZXN0KG1hdGNoLmlkID8/ICIiKTsKICAgICAgfSBjYXRjaCB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICB9KTsKICAgIGNvbnN0IHJlc29sdmVkQ2hhbm5lbElkID0gc2VlZC5jaGFubmVsSWQgPz8gZXhhY3RNYXRjaD8uaWQgPz8gbnVsbDsKICAgIGNvbnNvbGUubG9nKCJbcmVzb2x1dGlvbl0gZXhhY3QgaGFuZGxlIG1hdGNoOiIsIEpTT04uc3RyaW5naWZ5KHsKICAgICAgZXhwZWN0ZWRIYW5kbGU6IHNlZWQuaGFuZGxlLAogICAgICBjaGFubmVsSWQ6IHJlc29sdmVkQ2hhbm5lbElkLAogICAgICBtYXRjaGVkVGl0bGU6IGV4YWN0TWF0Y2g/LnRpdGxlID8/IG51bGwsCiAgICAgIG1hdGNoZWRVcmw6IGV4YWN0TWF0Y2g/LnVybCA/PyBudWxsCiAgICB9KSk7CgogICAgbGV0IGNoYW5uZWwgPSBudWxsOwogICAgdHJ5IHsKICAgICAgaWYgKCFyZXNvbHZlZENoYW5uZWxJZCkgdGhyb3cgbmV3IEVycm9yKCJDb3VsZCBub3QgcmVzb2x2ZSBleGFjdCBAaGFuZGxlIHRvIGEgY2hhbm5lbCBJRDsgcmVmdXNpbmcgdG8gZ3Vlc3MgZnJvbSBmdXp6eSBzZWFyY2ggcmVzdWx0cy4iKTsKICAgICAgY2hhbm5lbCA9IGF3YWl0IHl0LmdldENoYW5uZWwocmVzb2x2ZWRDaGFubmVsSWQpOwogICAgICByb3cuc3RhdHVzID0gInJlc29sdmVkIjsKICAgICAgcm93LmlkZW50aXR5ID0gc3VtbWFyaXplQ2hhbm5lbChjaGFubmVsLCBudWxsKTsKICAgICAgY29uc29sZS5sb2coIltpZGVudGl0eV0iLCBKU09OLnN0cmluZ2lmeSh7CiAgICAgICAgdGl0bGU6IHJvdy5pZGVudGl0eS50aXRsZSwKICAgICAgICBpZDogcm93LmlkZW50aXR5LmNoYW5uZWxJZCwKICAgICAgICB1cmw6IHJvdy5pZGVudGl0eS51cmwsCiAgICAgICAgY29uc3RydWN0b3I6IHJvdy5pZGVudGl0eS5jb25zdHJ1Y3RvciwKICAgICAgICByYXdLZXlzOiByb3cuaWRlbnRpdHkucmF3S2V5cywKICAgICAgICB0YWJzOiByb3cuaWRlbnRpdHkudGFicywKICAgICAgICBzb3J0RmlsdGVyczogcm93LmlkZW50aXR5LnNvcnRGaWx0ZXJzCiAgICAgIH0sIG51bGwsIDIpKTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgIHJvdy5lcnJvcnMucHVzaCh7IHN0YWdlOiAieW91dHViZWkuZ2V0Q2hhbm5lbCIsIC4uLmVyckluZm8oZXJyb3IpIH0pOwogICAgICBjb25zb2xlLmVycm9yKCJbRVJST1JdIHlvdXR1YmVpLmpzIGdldENoYW5uZWwgZmFpbGVkOiIsIGVycm9yPy5zdGFjayA/PyBlcnJvcik7CiAgICB9CgogICAgaWYgKGNoYW5uZWwpIHsKICAgICAgdHJ5IHsKICAgICAgICBpZiAodHlwZW9mIGNoYW5uZWwuZ2V0QWJvdXQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgIGNvbnN0IGFib3V0ID0gYXdhaXQgY2hhbm5lbC5nZXRBYm91dCgpOwogICAgICAgICAgcm93Lm1ldGFkYXRhID0gc3VtbWFyaXplQ2hhbm5lbChjaGFubmVsLCBhYm91dCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJvdy5tZXRhZGF0YSA9IHN1bW1hcml6ZUNoYW5uZWwoY2hhbm5lbCwgbnVsbCk7CiAgICAgICAgICByb3cubWV0YWRhdGEuYWJvdXRGZXRjaCA9ICJDaGFubmVsLmdldEFib3V0KCkgdW5hdmFpbGFibGUiOwogICAgICAgIH0KICAgICAgICBjb25zdCBjaGFubmVsU29ydFJlYWQgPSBzYWZlUmVhZChjaGFubmVsLCAic29ydF9maWx0ZXJzIik7CiAgICAgICAgcm93LnJhd1NvcnRGaWx0ZXJzID0gY2hhbm5lbFNvcnRSZWFkLm9rICYmIEFycmF5LmlzQXJyYXkoY2hhbm5lbFNvcnRSZWFkLnZhbHVlKSA/IGNoYW5uZWxTb3J0UmVhZC52YWx1ZS5tYXAodGV4dCkgOiBbXTsKICAgICAgICBjb25zb2xlLmxvZygiW21ldGFkYXRhXSIsIEpTT04uc3RyaW5naWZ5KHsKICAgICAgICAgIHRpdGxlOiByb3cubWV0YWRhdGEudGl0bGUsCiAgICAgICAgICBjaGFubmVsSWQ6IHJvdy5tZXRhZGF0YS5jaGFubmVsSWQsCiAgICAgICAgICB1cmw6IHJvdy5tZXRhZGF0YS51cmwsCiAgICAgICAgICBzdWJzY3JpYmVyczogcm93Lm1ldGFkYXRhLnN1YnNjcmliZXJzLAogICAgICAgICAgdG90YWxWaWV3czogcm93Lm1ldGFkYXRhLnRvdGFsVmlld3MsCiAgICAgICAgICB2aWRlb0NvdW50OiByb3cubWV0YWRhdGEudmlkZW9Db3VudCwKICAgICAgICAgIGpvaW5lZERhdGU6IHJvdy5tZXRhZGF0YS5qb2luZWREYXRlLAogICAgICAgICAgY291bnRyeTogcm93Lm1ldGFkYXRhLmNvdW50cnksCiAgICAgICAgICBkZXNjcmlwdGlvbjogcm93Lm1ldGFkYXRhLmRlc2NyaXB0aW9uPy5zbGljZSgwLCAyNDApID8/IG51bGwsCiAgICAgICAgICBtZXRhZGF0YUtleXM6IHJvdy5tZXRhZGF0YS5tZXRhZGF0YUtleXMsCiAgICAgICAgICBhYm91dEtleXM6IHJvdy5tZXRhZGF0YS5hYm91dEtleXMKICAgICAgICB9LCBudWxsLCAyKSk7CiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgcm93LmVycm9ycy5wdXNoKHsgc3RhZ2U6ICJ5b3V0dWJlaS5nZXRBYm91dCIsIC4uLmVyckluZm8oZXJyb3IpIH0pOwogICAgICAgIGNvbnNvbGUuZXJyb3IoIltFUlJPUl0gYWJvdXQvbWV0YWRhdGEgZmV0Y2ggZmFpbGVkOiIsIGVycm9yPy5zdGFjayA/PyBlcnJvcik7CiAgICAgIH0KCiAgICAgIGxldCB2aWRlb0NoYW5uZWwgPSBudWxsOwogICAgICB0cnkgewogICAgICAgIGlmICh0eXBlb2YgY2hhbm5lbC5nZXRWaWRlb3MgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgIHZpZGVvQ2hhbm5lbCA9IGF3YWl0IGNoYW5uZWwuZ2V0VmlkZW9zKCk7CiAgICAgICAgICBjb25zb2xlLmxvZygiW3ZpZGVvcy10YWJdIGNoYW5uZWwuZ2V0VmlkZW9zKCkiLCBKU09OLnN0cmluZ2lmeSh7CiAgICAgICAgICAgIGNvbnN0cnVjdG9yOiB2aWRlb0NoYW5uZWw/LmNvbnN0cnVjdG9yPy5uYW1lID8/IG51bGwsCiAgICAgICAgICAgIHRpdGxlOiBwaWNrVGV4dCh2aWRlb0NoYW5uZWw/LnRpdGxlKSwKICAgICAgICAgICAgY3VycmVudFRhYlRpdGxlOiBwaWNrVGV4dCh2aWRlb0NoYW5uZWw/LmN1cnJlbnRfdGFiPy50aXRsZSwgdmlkZW9DaGFubmVsPy5jdXJyZW50X3RhYj8udGFiX3RpdGxlKSwKICAgICAgICAgICAgdGFiczogQXJyYXkuaXNBcnJheSh2aWRlb0NoYW5uZWw/LnRhYnMpID8gdmlkZW9DaGFubmVsLnRhYnMubWFwKHRleHQpIDogW10sCiAgICAgICAgICAgIHNvcnRGaWx0ZXJzOiAoKCkgPT4geyBjb25zdCByID0gc2FmZVJlYWQodmlkZW9DaGFubmVsLCAic29ydF9maWx0ZXJzIik7IHJldHVybiByLm9rICYmIEFycmF5LmlzQXJyYXkoci52YWx1ZSkgPyByLnZhbHVlLm1hcCh0ZXh0KSA6IFtdOyB9KSgpLAogICAgICAgICAgICB2aWRlb0l0ZW1zOiAoKCkgPT4geyBjb25zdCByID0gc2FmZVJlYWQodmlkZW9DaGFubmVsLCAidmlkZW9zIik7IHJldHVybiByLm9rID8gci52YWx1ZT8ubGVuZ3RoID8/IG51bGwgOiBudWxsOyB9KSgpLAogICAgICAgICAgICBoYXNDb250aW51YXRpb246ICgoKSA9PiB7IGNvbnN0IHIgPSBzYWZlUmVhZCh2aWRlb0NoYW5uZWwsICJoYXNfY29udGludWF0aW9uIik7IHJldHVybiByLm9rID8gQm9vbGVhbihyLnZhbHVlKSA6IGZhbHNlOyB9KSgpCiAgICAgICAgICB9LCBudWxsLCAyKSk7CiAgICAgICAgfQogICAgICAgIC8vIEV4cGxpY2l0IHRhYiBsb29rdXAgaXMgYSBkaWFnbm9zdGljIGNyb3NzLWNoZWNrOyB1c2Ugd2hpY2hldmVyIG9iamVjdAogICAgICAgIC8vIGFjdHVhbGx5IGV4cG9zZXMgYSB2aWRlbyBmZWVkIG9yIHNvcnQgZmlsdGVycy4KICAgICAgICBsZXQgbmFtZWRWaWRlb3NUYWIgPSBudWxsOwogICAgICAgIGlmICh0eXBlb2YgY2hhbm5lbC5nZXRUYWJCeU5hbWUgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIG5hbWVkVmlkZW9zVGFiID0gYXdhaXQgY2hhbm5lbC5nZXRUYWJCeU5hbWUoIlZpZGVvcyIpOwogICAgICAgICAgfSBjYXRjaCAodGFiRXJyb3IpIHsKICAgICAgICAgICAgcm93LmVycm9ycy5wdXNoKHsgc3RhZ2U6ICJ5b3V0dWJlaS5nZXRUYWJCeU5hbWUuVmlkZW9zIiwgLi4uZXJySW5mbyh0YWJFcnJvcikgfSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbnN0IGdldFZpZGVvc1Njb3JlID0gKGZlZWQpID0+IHsKICAgICAgICAgIGNvbnN0IHNmID0gc2FmZVJlYWQoZmVlZCwgInNvcnRfZmlsdGVycyIpOwogICAgICAgICAgY29uc3QgdnMgPSBzYWZlUmVhZChmZWVkLCAidmlkZW9zIik7CiAgICAgICAgICByZXR1cm4gKHNmLm9rICYmIEFycmF5LmlzQXJyYXkoc2YudmFsdWUpID8gc2YudmFsdWUubGVuZ3RoIDogMCkgKiAxMDAwICsKICAgICAgICAgICAgKHZzLm9rID8gdnMudmFsdWU/Lmxlbmd0aCA/PyAwIDogMCk7CiAgICAgICAgfTsKICAgICAgICByb3cudmlkZW9UYWJQcm9iZSA9IHsKICAgICAgICAgIGdldFZpZGVvczogdmlkZW9DaGFubmVsID8gewogICAgICAgICAgICB0aXRsZTogcGlja1RleHQodmlkZW9DaGFubmVsPy50aXRsZSksCiAgICAgICAgICAgIGN1cnJlbnRUYWJUaXRsZTogcGlja1RleHQodmlkZW9DaGFubmVsPy5jdXJyZW50X3RhYj8udGl0bGUsIHZpZGVvQ2hhbm5lbD8uY3VycmVudF90YWI/LnRhYl90aXRsZSksCiAgICAgICAgICAgIC4uLnNvcnRTdXJmYWNlKHZpZGVvQ2hhbm5lbCksCiAgICAgICAgICAgIHZpZGVvSXRlbUNvdW50OiAoKCkgPT4geyBjb25zdCByID0gc2FmZVJlYWQodmlkZW9DaGFubmVsLCAidmlkZW9zIik7IHJldHVybiByLm9rID8gci52YWx1ZT8ubGVuZ3RoID8/IG51bGwgOiBudWxsOyB9KSgpLAogICAgICAgICAgICBmaXJzdFZpZGVvSXRlbXM6ICgoKSA9PiB7IGNvbnN0IHIgPSBzYWZlUmVhZCh2aWRlb0NoYW5uZWwsICJ2aWRlb3MiKTsgcmV0dXJuIHIub2sgJiYgci52YWx1ZSA/IFsuLi5yLnZhbHVlXS5zbGljZSgwLCAzKSA6IFtdOyB9KSgpLm1hcChpdGVtID0+ICh7CiAgICAgICAgICAgICAgY29uc3RydWN0b3I6IGl0ZW0/LmNvbnN0cnVjdG9yPy5uYW1lID8/IHR5cGVvZiBpdGVtLAogICAgICAgICAgICAgIGtleXM6IGl0ZW0gJiYgdHlwZW9mIGl0ZW0gPT09ICJvYmplY3QiID8gT2JqZWN0LmtleXMoaXRlbSkuc2xpY2UoMCwgNTApIDogW10sCiAgICAgICAgICAgICAgaWRDYW5kaWRhdGVzOiB7CiAgICAgICAgICAgICAgICBpZDogaXRlbT8uaWQgPz8gbnVsbCwgdmlkZW9faWQ6IGl0ZW0/LnZpZGVvX2lkID8/IG51bGwsIHZpZGVvSWQ6IGl0ZW0/LnZpZGVvSWQgPz8gbnVsbCwKICAgICAgICAgICAgICAgIGNvbnRlbnRfaWQ6IGl0ZW0/LmNvbnRlbnRfaWQgPz8gbnVsbCwgY29udGVudElkOiBpdGVtPy5jb250ZW50SWQgPz8gbnVsbAogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgc2FtcGxlOiBzYWZlT2JqZWN0KGl0ZW0pCiAgICAgICAgICAgIH0pKQogICAgICAgICAgfSA6IG51bGwsCiAgICAgICAgICBnZXRUYWJCeU5hbWVWaWRlb3M6IG5hbWVkVmlkZW9zVGFiID8gewogICAgICAgICAgICB0aXRsZTogcGlja1RleHQobmFtZWRWaWRlb3NUYWI/LnRpdGxlKSwKICAgICAgICAgICAgY3VycmVudFRhYlRpdGxlOiBwaWNrVGV4dChuYW1lZFZpZGVvc1RhYj8uY3VycmVudF90YWI/LnRpdGxlLCBuYW1lZFZpZGVvc1RhYj8uY3VycmVudF90YWI/LnRhYl90aXRsZSksCiAgICAgICAgICAgIC4uLnNvcnRTdXJmYWNlKG5hbWVkVmlkZW9zVGFiKSwKICAgICAgICAgICAgdmlkZW9JdGVtQ291bnQ6ICgoKSA9PiB7IGNvbnN0IHIgPSBzYWZlUmVhZChuYW1lZFZpZGVvc1RhYiwgInZpZGVvcyIpOyByZXR1cm4gci5vayA/IHIudmFsdWU/Lmxlbmd0aCA/PyBudWxsIDogbnVsbDsgfSkoKSwKICAgICAgICAgICAgZmlyc3RWaWRlb0l0ZW1zOiAoKCkgPT4geyBjb25zdCByID0gc2FmZVJlYWQobmFtZWRWaWRlb3NUYWIsICJ2aWRlb3MiKTsgcmV0dXJuIHIub2sgJiYgci52YWx1ZSA/IFsuLi5yLnZhbHVlXS5zbGljZSgwLCAzKSA6IFtdOyB9KSgpLm1hcChpdGVtID0+ICh7CiAgICAgICAgICAgICAgY29uc3RydWN0b3I6IGl0ZW0/LmNvbnN0cnVjdG9yPy5uYW1lID8/IHR5cGVvZiBpdGVtLAogICAgICAgICAgICAgIGtleXM6IGl0ZW0gJiYgdHlwZW9mIGl0ZW0gPT09ICJvYmplY3QiID8gT2JqZWN0LmtleXMoaXRlbSkuc2xpY2UoMCwgNTApIDogW10sCiAgICAgICAgICAgICAgaWRDYW5kaWRhdGVzOiB7CiAgICAgICAgICAgICAgICBpZDogaXRlbT8uaWQgPz8gbnVsbCwgdmlkZW9faWQ6IGl0ZW0/LnZpZGVvX2lkID8/IG51bGwsIHZpZGVvSWQ6IGl0ZW0/LnZpZGVvSWQgPz8gbnVsbCwKICAgICAgICAgICAgICAgIGNvbnRlbnRfaWQ6IGl0ZW0/LmNvbnRlbnRfaWQgPz8gbnVsbCwgY29udGVudElkOiBpdGVtPy5jb250ZW50SWQgPz8gbnVsbAogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgc2FtcGxlOiBzYWZlT2JqZWN0KGl0ZW0pCiAgICAgICAgICAgIH0pKQogICAgICAgICAgfSA6IG51bGwKICAgICAgICB9OwogICAgICAgIGlmIChuYW1lZFZpZGVvc1RhYiAmJiAoIXZpZGVvQ2hhbm5lbCB8fCBnZXRWaWRlb3NTY29yZShuYW1lZFZpZGVvc1RhYikgPiBnZXRWaWRlb3NTY29yZSh2aWRlb0NoYW5uZWwpKSkgewogICAgICAgICAgY29uc29sZS5sb2coIlt2aWRlb3MtdGFiXSBFeHBsaWNpdCBnZXRUYWJCeU5hbWUoJ1ZpZGVvcycpIHByb2JlIGlzIHJpY2hlcjsgdXNpbmcgaXQuIik7CiAgICAgICAgICB2aWRlb0NoYW5uZWwgPSBuYW1lZFZpZGVvc1RhYjsKICAgICAgICB9CiAgICAgICAgaWYgKCF2aWRlb0NoYW5uZWwpIHRocm93IG5ldyBFcnJvcigiTm8gdmlkZW8gdGFiIG9iamVjdCByZXR1cm5lZCBieSBnZXRWaWRlb3MoKSBvciBnZXRUYWJCeU5hbWUoJ1ZpZGVvcycpLiIpOwogICAgICAgIGNvbnN0IHNvcnRSZWFkID0gc2FmZVJlYWQodmlkZW9DaGFubmVsLCAic29ydF9maWx0ZXJzIik7CiAgICAgICAgcm93LnJhd1NvcnRGaWx0ZXJzID0gc29ydFJlYWQub2sgJiYgQXJyYXkuaXNBcnJheShzb3J0UmVhZC52YWx1ZSkgPyBzb3J0UmVhZC52YWx1ZS5tYXAodGV4dCkgOiBbXTsKICAgICAgICBjb25zdCBtYXhQYWdlcyA9IHNlZWQubWF4UGFnZXMgPz8gREVGQVVMVF9NQVhfUEFHRVM7CiAgICAgICAgcm93LmRlZmF1bHRGZWVkID0gYXdhaXQgY29sbGVjdFZpZGVvcyh2aWRlb0NoYW5uZWwsIG1heFBhZ2VzLCAiZGVmYXVsdCIpOwogICAgICAgIHJvdy5sb2NhbFNvcnRQcm9iZSA9IGxvY2FsU29ydFByb2JlKHJvdy5kZWZhdWx0RmVlZC52aWRlb3MpOwogICAgICAgIGNvbnN0IGRlY2xhcmVkQ291bnQgPSBwYXJzZUFwcHJveENvdW50KHJvdy5tZXRhZGF0YT8udmlkZW9Db3VudCk7CiAgICAgICAgY29uc3QgYXZnQmF0Y2ggPSByb3cuZGVmYXVsdEZlZWQucGFnZXMubGVuZ3RoCiAgICAgICAgICA/IHJvdy5kZWZhdWx0RmVlZC5wYWdlcy5yZWR1Y2UoKHN1bSwgcCkgPT4gc3VtICsgcC5yYXdJdGVtQ291bnQsIDApIC8gcm93LmRlZmF1bHRGZWVkLnBhZ2VzLmxlbmd0aAogICAgICAgICAgOiBudWxsOwogICAgICAgIGNvbnN0IHJlcXVlc3RzRm9yRnVsbENhdGFsb2d1ZSA9IGRlY2xhcmVkQ291bnQgJiYgYXZnQmF0Y2ggPyBNYXRoLmNlaWwoZGVjbGFyZWRDb3VudCAvIGF2Z0JhdGNoKSA6IG51bGw7CiAgICAgICAgcm93LmZ1bGxDYXRhbG9ndWVFc3RpbWF0ZSA9IHsKICAgICAgICAgIGRlY2xhcmVkVmlkZW9Db3VudFJhdzogcm93Lm1ldGFkYXRhPy52aWRlb0NvdW50ID8/IG51bGwsCiAgICAgICAgICBkZWNsYXJlZFZpZGVvQ291bnRBcHByb3g6IGRlY2xhcmVkQ291bnQsCiAgICAgICAgICBzYW1wbGVkUGFnZXM6IHJvdy5kZWZhdWx0RmVlZC5wYWdlcy5sZW5ndGgsCiAgICAgICAgICBzYW1wbGVkSXRlbXM6IHJvdy5kZWZhdWx0RmVlZC52aWRlb3MubGVuZ3RoLAogICAgICAgICAgb2JzZXJ2ZWRBdmVyYWdlSXRlbXNQZXJQYWdlOiBhdmdCYXRjaCA9PSBudWxsID8gbnVsbCA6IE51bWJlcihhdmdCYXRjaC50b0ZpeGVkKDIpKSwKICAgICAgICAgIGVzdGltYXRlZFBhZ2VzQXRPYnNlcnZlZFBhZ2VTaXplOiByZXF1ZXN0c0ZvckZ1bGxDYXRhbG9ndWUsCiAgICAgICAgICBvYnNlcnZlZFBpbG90RWxhcHNlZE1zOiByb3cuZGVmYXVsdEZlZWQuZWxhcHNlZE1zID8/IG51bGwsCiAgICAgICAgICBlc3RpbWF0ZWRTZWNvbmRzQXRQaWxvdFBhY2U6IHJlcXVlc3RzRm9yRnVsbENhdGFsb2d1ZSAmJiByb3cuZGVmYXVsdEZlZWQucGFnZXMubGVuZ3RoCiAgICAgICAgICAgID8gTnVtYmVyKCgocm93LmRlZmF1bHRGZWVkLmVsYXBzZWRNcyAvIHJvdy5kZWZhdWx0RmVlZC5wYWdlcy5sZW5ndGgpICogcmVxdWVzdHNGb3JGdWxsQ2F0YWxvZ3VlIC8gMTAwMCkudG9GaXhlZCgxKSkKICAgICAgICAgICAgOiBudWxsLAogICAgICAgICAgY2F1dGlvbjogIkVzdGltYXRlIG9ubHk6IGRlY2xhcmVkIGNvdW50cyBtYXkgYmUgcm91bmRlZDsgaW5hY2Nlc3NpYmxlL2RlbGV0ZWQvcHJpdmF0ZSBpdGVtcywgcGFnaW5hdGlvbiBiZWhhdmlvciwgYW5kIHJhdGUgbGltaXRzIGNhbiBjaGFuZ2UgYWN0dWFsIHJlc3VsdHMuIFBpbG90IHBhY2UgaXMgbm90IGEgZ3VhcmFudGVlIG9mIHN1c3RhaW5lZCBjcmF3bCBzcGVlZC4iCiAgICAgICAgfTsKICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICByb3cuZXJyb3JzLnB1c2goeyBzdGFnZTogInlvdXR1YmVpLmRlZmF1bHRWaWRlb3MiLCAuLi5lcnJJbmZvKGVycm9yKSB9KTsKICAgICAgICBjb25zb2xlLmVycm9yKCJbRVJST1JdIGRlZmF1bHQgZ2V0VmlkZW9zIGZhaWxlZDoiLCBlcnJvcj8uc3RhY2sgPz8gZXJyb3IpOwogICAgICB9CgogICAgICBjb25zdCBmaWx0ZXJzID0gcm93LnJhd1NvcnRGaWx0ZXJzID8/IFtdOwogICAgICBjb25zdCBsYXRlc3RMYWJlbCA9IGZpbHRlck1hdGNoKGZpbHRlcnMsIFsvbGF0ZXN0L2ksIC9uZXdlc3QvaSwgL3JlY2VudC9pXSk7CiAgICAgIGNvbnN0IHBvcHVsYXJMYWJlbCA9IGZpbHRlck1hdGNoKGZpbHRlcnMsIFsvcG9wdWxhci9pLCAvbW9zdCB2aWV3ZWQvaSwgL3ZpZXcgY291bnQvaV0pOwogICAgICByb3cuc29ydExhYmVscyA9IHsgbGF0ZXN0OiBsYXRlc3RMYWJlbCwgcG9wdWxhcjogcG9wdWxhckxhYmVsIH07CiAgICAgIGNvbnNvbGUubG9nKCJbc29ydF0gZmlsdGVycyBmcm9tIFZpZGVvcyB0YWI6IiwgSlNPTi5zdHJpbmdpZnkoZmlsdGVycykpOwogICAgICBjb25zb2xlLmxvZygiW3NvcnRdIHNlbGVjdGVkIGxhYmVsczoiLCBKU09OLnN0cmluZ2lmeShyb3cuc29ydExhYmVscykpOwoKICAgICAgLy8gSWYgdGhlIHBhcnNlciBleHBvc2VzIG5vIHNvcnRfZmlsdGVycywgdGVzdCB0aGUgZG9jdW1lbnRlZCBhcHBseVNvcnQgQVBJCiAgICAgIC8vIHdpdGggdGhlIHR3byBjb21tb24gVUkgbGFiZWxzLiBLZWVwIHRoaXMgZXhwbGljaXRseSBkaWFnbm9zdGljOiBzdWNjZXNzCiAgICAgIC8vIGFsb25lIGRvZXMgbm90IHByb3ZlIHRoYXQgdGhlIHJlc3VsdGluZyBvcmRlciBjaGFuZ2VkLgogICAgICByb3cuc29ydEZhbGxiYWNrUHJvYmUgPSBbXTsKICAgICAgaWYgKHZpZGVvQ2hhbm5lbCAmJiBmaWx0ZXJzLmxlbmd0aCA9PT0gMCAmJiB0eXBlb2YgdmlkZW9DaGFubmVsLmFwcGx5U29ydCA9PT0gImZ1bmN0aW9uIikgewogICAgICAgIGNvbnN0IGJhc2VsaW5lSWRzID0gKHJvdy5kZWZhdWx0RmVlZD8uaWRzID8/IFtdKS5zbGljZSgwLCAzMCk7CiAgICAgICAgZm9yIChjb25zdCBsYWJlbCBvZiBTT1JUX0ZBTExCQUNLX0xBQkVMUykgewogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgY29uc29sZS5sb2coYFtzb3J0LWZhbGxiYWNrXSBwcm9iaW5nIGFwcGx5U29ydCgke2xhYmVsfSkgZGVzcGl0ZSBlbXB0eSBzb3J0X2ZpbHRlcnNgKTsKICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlID0gYXdhaXQgdmlkZW9DaGFubmVsLmFwcGx5U29ydChsYWJlbCk7CiAgICAgICAgICAgIGNvbnN0IHByb2JlRmVlZCA9IGF3YWl0IGNvbGxlY3RWaWRlb3MoY2FuZGlkYXRlLCAxLCBgZmFsbGJhY2stcHJvYmU6JHtsYWJlbH1gKTsKICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlSWRzID0gcHJvYmVGZWVkLmlkcyA/PyBbXTsKICAgICAgICAgICAgY29uc3QgYmFzZVNldCA9IG5ldyBTZXQoYmFzZWxpbmVJZHMpOwogICAgICAgICAgICBjb25zdCBvdmVybGFwQ291bnQgPSBjYW5kaWRhdGVJZHMuZmlsdGVyKGlkID0+IGJhc2VTZXQuaGFzKGlkKSkubGVuZ3RoOwogICAgICAgICAgICByb3cuc29ydEZhbGxiYWNrUHJvYmUucHVzaCh7CiAgICAgICAgICAgICAgbGFiZWwsCiAgICAgICAgICAgICAgc3VjY2VlZGVkOiB0cnVlLAogICAgICAgICAgICAgIGNvdW50OiBwcm9iZUZlZWQudW5pcXVlQ291bnQgPz8gY2FuZGlkYXRlSWRzLmxlbmd0aCwKICAgICAgICAgICAgICBpZHM6IGNhbmRpZGF0ZUlkcywKICAgICAgICAgICAgICB0aXRsZXM6IChwcm9iZUZlZWQudmlkZW9zID8/IFtdKS5zbGljZSgwLCAxMCkubWFwKHYgPT4gdi50aXRsZSksCiAgICAgICAgICAgICAgc2FtZUZpcnN0UGFnZTogYmFzZWxpbmVJZHMubGVuZ3RoID09PSBjYW5kaWRhdGVJZHMubGVuZ3RoICYmIGJhc2VsaW5lSWRzLmV2ZXJ5KChpZCwgaSkgPT4gaWQgPT09IGNhbmRpZGF0ZUlkc1tpXSksCiAgICAgICAgICAgICAgYmFzZWxpbmVPdmVybGFwOiBvdmVybGFwQ291bnQsCiAgICAgICAgICAgICAgZXJyb3I6IG51bGwKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgICAgICByb3cuc29ydEZhbGxiYWNrUHJvYmUucHVzaCh7IGxhYmVsLCBzdWNjZWVkZWQ6IGZhbHNlLCBlcnJvcjogZXJySW5mbyhlcnJvcikgfSk7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbc29ydC1mYWxsYmFja10gYXBwbHlTb3J0KCR7bGFiZWx9KSBmYWlsZWQ6YCwgZXJyb3I/Lm1lc3NhZ2UgPz8gZXJyb3IpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgaWYgKGxhdGVzdExhYmVsICYmIHZpZGVvQ2hhbm5lbCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICBjb25zdCBzb3J0ZWQgPSBhd2FpdCB2aWRlb0NoYW5uZWwuYXBwbHlTb3J0KGxhdGVzdExhYmVsKTsKICAgICAgICAgIHJvdy5sYXRlc3RGZWVkID0gYXdhaXQgY29sbGVjdFZpZGVvcyhzb3J0ZWQsIERFRkFVTFRfTUFYX1BBR0VTLCBgbGF0ZXN0OiR7bGF0ZXN0TGFiZWx9YCk7CiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICAgIHJvdy5lcnJvcnMucHVzaCh7IHN0YWdlOiBgeW91dHViZWkuYXBwbHlTb3J0LmxhdGVzdDoke2xhdGVzdExhYmVsfWAsIC4uLmVyckluZm8oZXJyb3IpIH0pOwogICAgICAgICAgY29uc29sZS5lcnJvcihgW0VSUk9SXSBhcHBseVNvcnQoJHtsYXRlc3RMYWJlbH0pIGZhaWxlZDpgLCBlcnJvcj8uc3RhY2sgPz8gZXJyb3IpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICByb3cubGF0ZXN0RmVlZCA9IHsgc2tpcHBlZDogdHJ1ZSwgcmVhc29uOiAiTm8gTGF0ZXN0L05ld2VzdC9SZWNlbnQgbGFiZWwgZm91bmQgaW4gdGhlIFZpZGVvcyB0YWIncyBhY3R1YWwgc29ydF9maWx0ZXJzLiIgfTsKICAgICAgfQoKICAgICAgaWYgKHBvcHVsYXJMYWJlbCAmJiB2aWRlb0NoYW5uZWwpIHsKICAgICAgICB0cnkgewogICAgICAgICAgY29uc3Qgc29ydGVkID0gYXdhaXQgdmlkZW9DaGFubmVsLmFwcGx5U29ydChwb3B1bGFyTGFiZWwpOwogICAgICAgICAgcm93LnBvcHVsYXJGZWVkID0gYXdhaXQgY29sbGVjdFZpZGVvcyhzb3J0ZWQsIERFRkFVTFRfTUFYX1BBR0VTLCBgcG9wdWxhcjoke3BvcHVsYXJMYWJlbH1gKTsKICAgICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgICAgcm93LmVycm9ycy5wdXNoKHsgc3RhZ2U6IGB5b3V0dWJlaS5hcHBseVNvcnQucG9wdWxhcjoke3BvcHVsYXJMYWJlbH1gLCAuLi5lcnJJbmZvKGVycm9yKSB9KTsKICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtFUlJPUl0gYXBwbHlTb3J0KCR7cG9wdWxhckxhYmVsfSkgZmFpbGVkOmAsIGVycm9yPy5zdGFjayA/PyBlcnJvcik7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIHJvdy5wb3B1bGFyRmVlZCA9IHsgc2tpcHBlZDogdHJ1ZSwgcmVhc29uOiAiTm8gUG9wdWxhci9Nb3N0IHZpZXdlZC9WaWV3IGNvdW50IGxhYmVsIGZvdW5kIGluIHRoZSBWaWRlb3MgdGFiJ3MgYWN0dWFsIHNvcnRfZmlsdGVycy4iIH07CiAgICAgIH0KCiAgICAgIGNvbnN0IG5ld2VzdElkcyA9IHJvdy5sYXRlc3RGZWVkPy5pZHMgPz8gcm93LmRlZmF1bHRGZWVkPy5pZHMgPz8gW107CiAgICAgIGNvbnN0IHBvcHVsYXJJZHMgPSByb3cucG9wdWxhckZlZWQ/LmlkcyA/PyBbXTsKICAgICAgcm93LnNvcnRDb21wYXJpc29uID0gewogICAgICAgIGxhdGVzdFNvdXJjZTogcm93LmxhdGVzdEZlZWQ/LnNraXBwZWQgPyAiZGVmYXVsdCIgOiAibGF0ZXN0IiwKICAgICAgICBsYXRlc3RWc1BvcHVsYXI6IG92ZXJsYXAobmV3ZXN0SWRzLCBwb3B1bGFySWRzKSwKICAgICAgICBsYXRlc3RWaWV3T3JkZXI6IGRlc2NlbmRpbmdWaWV3cyhyb3cubGF0ZXN0RmVlZD8udmlkZW9zID8/IHJvdy5kZWZhdWx0RmVlZD8udmlkZW9zID8/IFtdKSwKICAgICAgICBwb3B1bGFyVmlld09yZGVyOiBkZXNjZW5kaW5nVmlld3Mocm93LnBvcHVsYXJGZWVkPy52aWRlb3MgPz8gW10pLAogICAgICAgIHZlcmRpY3Q6ICJub3QtZXZhbHVhdGVkIgogICAgICB9OwogICAgICBpZiAocm93LnBvcHVsYXJGZWVkPy5za2lwcGVkIHx8IHJvdy5sYXRlc3RGZWVkPy5za2lwcGVkKSB7CiAgICAgICAgcm93LnNvcnRDb21wYXJpc29uLnZlcmRpY3QgPSAiVU5TVVBQT1JURURfT1JfVU5ESVNDT1ZFUkVEX1NPUlRfRklMVEVSIjsKICAgICAgfSBlbHNlIGlmIChyb3cubGF0ZXN0RmVlZD8uZXJyb3IgfHwgcm93LnBvcHVsYXJGZWVkPy5lcnJvcikgewogICAgICAgIHJvdy5zb3J0Q29tcGFyaXNvbi52ZXJkaWN0ID0gIlNPUlRfRkVUQ0hfRVJST1IiOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IGogPSByb3cuc29ydENvbXBhcmlzb24ubGF0ZXN0VnNQb3B1bGFyLmphY2NhcmQ7CiAgICAgICAgY29uc3Qgb3JkZXJMb29rc1BvcHVsYXIgPSByb3cuc29ydENvbXBhcmlzb24ucG9wdWxhclZpZXdPcmRlci5tb25vdG9uaWMgPT09IHRydWU7CiAgICAgICAgaWYgKGogPT09IDEgJiYgIW9yZGVyTG9va3NQb3B1bGFyKSByb3cuc29ydENvbXBhcmlzb24udmVyZGljdCA9ICJTVVNQSUNJT1VTX0lERU5USUNBTF9TRVRTX0FORF9QT1BVTEFSX05PVF9ERVNDRU5ESU5HIjsKICAgICAgICBlbHNlIGlmIChqID09PSAxKSByb3cuc29ydENvbXBhcmlzb24udmVyZGljdCA9ICJTQU1FX1ZJREVPX1NFVDsgaW5zcGVjdCBvcmRlcmluZyBhbmQgcGFnaW5hdGlvbiBiZWZvcmUgdHJ1c3Rpbmcgc29ydCI7CiAgICAgICAgZWxzZSBpZiAoaiAhPSBudWxsICYmIGogPCAwLjkgJiYgb3JkZXJMb29rc1BvcHVsYXIpIHJvdy5zb3J0Q29tcGFyaXNvbi52ZXJkaWN0ID0gIlNPUlRTX0xPT0tfRElTVElOQ1RfQU5EX1BPUFVMQVJfT1JERVJfTE9PS1NfUExBVVNJQkxFIjsKICAgICAgICBlbHNlIGlmIChqICE9IG51bGwgJiYgaiA8IDAuOSkgcm93LnNvcnRDb21wYXJpc29uLnZlcmRpY3QgPSAiU0VUU19ESUZGRVJfQlVUX1BPUFVMQVJfT1JERVJfTk9UX1ZFUklGSUVEIjsKICAgICAgICBlbHNlIHJvdy5zb3J0Q29tcGFyaXNvbi52ZXJkaWN0ID0gIklOQ09OQ0xVU0lWRTsgc21hbGwgc2FtcGxlIG9yIG1pc3NpbmcgdmlldyBjb3VudHMiOwogICAgICB9CiAgICAgIGNvbnNvbGUubG9nKCJbc29ydC1jb21wYXJpc29uXSIsIEpTT04uc3RyaW5naWZ5KHJvdy5zb3J0Q29tcGFyaXNvbiwgbnVsbCwgMikpOwogICAgICBjb25zb2xlLmxvZygiW3NhbXBsZSBsYXRlc3RdIiwgSlNPTi5zdHJpbmdpZnkoKHJvdy5sYXRlc3RGZWVkPy52aWRlb3MgPz8gcm93LmRlZmF1bHRGZWVkPy52aWRlb3MgPz8gW10pLnNsaWNlKDAsIDgpLCBudWxsLCAyKSk7CiAgICAgIGNvbnNvbGUubG9nKCJbc2FtcGxlIHBvcHVsYXJdIiwgSlNPTi5zdHJpbmdpZnkoKHJvdy5wb3B1bGFyRmVlZD8udmlkZW9zID8/IFtdKS5zbGljZSgwLCA4KSwgbnVsbCwgMikpOwogICAgfQoKICAgIHJvdy5maW5pc2hlZEF0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpOwogICAgaWYgKHJvdy5lcnJvcnMubGVuZ3RoICYmICFyb3cuZGVmYXVsdEZlZWQpIHJvdy5zdGF0dXMgPSAicGFydGlhbC1mYWlsdXJlIjsKICAgIGVsc2UgaWYgKHJvdy5lcnJvcnMubGVuZ3RoKSByb3cuc3RhdHVzID0gInBhcnRpYWwtc3VjY2Vzcy13aXRoLWVycm9ycyI7CiAgICBlbHNlIHJvdy5zdGF0dXMgPSAiY29tcGxldGVkIjsKICAgIGF3YWl0IHNsZWVwKFBBVVNFX01TKTsKICB9CgogIGNvbnN0IHZlcmRpY3RDb3VudHMgPSB7fTsKICBmb3IgKGNvbnN0IGMgb2YgcmVwb3J0LmNoYW5uZWxzKSB7CiAgICBjb25zdCB2ZXJkaWN0ID0gYy5zb3J0Q29tcGFyaXNvbj8udmVyZGljdCA/PyAiTk9fU09SVF9DT01QQVJJU09OIjsKICAgIHZlcmRpY3RDb3VudHNbdmVyZGljdF0gPSAodmVyZGljdENvdW50c1t2ZXJkaWN0XSA/PyAwKSArIDE7CiAgfQogIHJlcG9ydC5zdW1tYXJ5ID0gewogICAgY2hhbm5lbHNUZXN0ZWQ6IHJlcG9ydC5jaGFubmVscy5sZW5ndGgsCiAgICByZXNvbHZlZENoYW5uZWxzOiByZXBvcnQuY2hhbm5lbHMuZmlsdGVyKGMgPT4gYy5pZGVudGl0eSkubGVuZ3RoLAogICAgbWV0YWRhdGFGZXRjaGVkOiByZXBvcnQuY2hhbm5lbHMuZmlsdGVyKGMgPT4gYy5tZXRhZGF0YSkubGVuZ3RoLAogICAgZGVmYXVsdEZlZWRGZXRjaGVkOiByZXBvcnQuY2hhbm5lbHMuZmlsdGVyKGMgPT4gYy5kZWZhdWx0RmVlZCkubGVuZ3RoLAogICAgc29ydFZlcmRpY3RzOiB2ZXJkaWN0Q291bnRzLAogICAgY3JpdGljYWxXYXJuaW5nOiAiVGhpcyBkaWFnbm9zdGljIHBlcmZvcm1zIGEgYm91bmRlZCBwYWdpbmF0aW9uIHBpbG90IChDTk4gdXAgdG8gZml2ZSBwYWdlczsgb3RoZXIgY2hhbm5lbHMgdXAgdG8gdGhyZWUpLiBJdCBkb2VzIG5vdCBhdHRlbXB0IGZ1bGwtY2F0YWxvZ3VlIGNvbXBsZXRlbmVzcyBvciBlc3RhYmxpc2ggZ2xvYmFsIHBvcHVsYXJpdHkgcmFua2luZy4iLAogICAgbm9EYXRhYmFzZVdyaXRlczogdHJ1ZQogIH07CgogIGNvbnN0IG91dFBhdGggPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgImNoYW5uZWwtZmV0Y2gtZGlhZ25vc3RpYy1vdXRwdXQuanNvbiIpOwogIGZzLndyaXRlRmlsZVN5bmMob3V0UGF0aCwgSlNPTi5zdHJpbmdpZnkocmVwb3J0LCBudWxsLCAyKSwgInV0ZjgiKTsKICBjb25zdCBtZCA9IFtdOwogIG1kLnB1c2goIiMgWW91VHViZSBjaGFubmVsIGZldGNoIGRpYWdub3N0aWMiLCAiIiwgYEdlbmVyYXRlZDogJHtyZXBvcnQuZ2VuZXJhdGVkQXR9YCwgIiIsICIjIyBTdW1tYXJ5IiwgIiIsCiAgICBgLSBDaGFubmVscyB0ZXN0ZWQ6ICR7cmVwb3J0LnN1bW1hcnkuY2hhbm5lbHNUZXN0ZWR9YCwKICAgIGAtIENoYW5uZWwgcmVzb2x1dGlvbnM6ICR7cmVwb3J0LnN1bW1hcnkucmVzb2x2ZWRDaGFubmVsc31gLAogICAgYC0gTWV0YWRhdGEgZmV0Y2hlczogJHtyZXBvcnQuc3VtbWFyeS5tZXRhZGF0YUZldGNoZWR9YCwKICAgIGAtIERlZmF1bHQgZmVlZCBmZXRjaGVzOiAke3JlcG9ydC5zdW1tYXJ5LmRlZmF1bHRGZWVkRmV0Y2hlZH1gLAogICAgYC0gU29ydCB2ZXJkaWN0czogJHtKU09OLnN0cmluZ2lmeSh2ZXJkaWN0Q291bnRzKX1gLAogICAgIi0gTm8gZGF0YWJhc2Ugd3JpdGVzIHdlcmUgcGVyZm9ybWVkLiIsCiAgICAiIiwKICAgICIjIyBQZXItY2hhbm5lbCByZXN1bHRzIiwgIiIpOwogIGZvciAoY29uc3QgYyBvZiByZXBvcnQuY2hhbm5lbHMpIHsKICAgIG1kLnB1c2goYCMjIyAke2Muc2VlZC5sYWJlbH1gLCAiIiwKICAgICAgYC0gVVJMOiAke2Muc2VlZC51cmx9YCwKICAgICAgYC0gU3RhdHVzOiAke2Muc3RhdHVzfWAsCiAgICAgIGAtIFJlc29sdmVkIHRpdGxlIC8gSUQ6ICR7Yy5pZGVudGl0eT8udGl0bGUgPz8gIuKAlCJ9IC8gJHtjLmlkZW50aXR5Py5jaGFubmVsSWQgPz8gIuKAlCJ9YCwKICAgICAgYC0gTWV0YWRhdGE6IHN1YnNjcmliZXJzPSR7Yy5tZXRhZGF0YT8uc3Vic2NyaWJlcnMgPz8gInVua25vd24ifSwgdG90YWwgdmlld3M9JHtjLm1ldGFkYXRhPy50b3RhbFZpZXdzID8/ICJ1bmtub3duIn0sIGRlY2xhcmVkIHZpZGVvcz0ke2MubWV0YWRhdGE/LnZpZGVvQ291bnQgPz8gInVua25vd24ifSwgam9pbmVkPSR7Yy5tZXRhZGF0YT8uam9pbmVkRGF0ZSA/PyAidW5rbm93biJ9LCBjb3VudHJ5PSR7Yy5tZXRhZGF0YT8uY291bnRyeSA/PyAidW5rbm93biJ9YCwKICAgICAgYC0gVmlkZW9zLXRhYiBzb3J0IGZpbHRlcnM6ICR7KGMucmF3U29ydEZpbHRlcnMgPz8gW10pLmpvaW4oIiwgIikgfHwgIm5vbmUgZXhwb3NlZCJ9YCwKICAgICAgYC0gT3RoZXIgcGFyc2VyIGZpbHRlciBzdXJmYWNlczogcHJpbWFyeT0keyhjLnZpZGVvVGFiUHJvYmU/LmdldFZpZGVvcz8ucHJpbWFyeUZpbHRlcnMgPz8gW10pLmpvaW4oIiwgIikgfHwgIm5vbmUifTsgc2Vjb25kYXJ5PSR7KGMudmlkZW9UYWJQcm9iZT8uZ2V0VmlkZW9zPy5zZWNvbmRhcnlGaWx0ZXJzID8/IFtdKS5qb2luKCIsICIpIHx8ICJub25lIn07IGNvbnRlbnQtdHlwZT0keyhjLnZpZGVvVGFiUHJvYmU/LmdldFZpZGVvcz8uY29udGVudFR5cGVGaWx0ZXJzID8/IFtdKS5qb2luKCIsICIpIHx8ICJub25lIn1gLAogICAgICBgLSBSYXcgcmVzcG9uc2Ugc29ydC9maWx0ZXIgbWVudGlvbnM6ICR7KGMudmlkZW9UYWJQcm9iZT8uZ2V0VmlkZW9zPy5wYWdlU29ydE1lbnRpb25zID8/IFtdKS5sZW5ndGh9YCwKICAgICAgYC0gTWFudWFsIGFwcGx5U29ydCBwcm9iZXM6ICR7KGMuc29ydEZhbGxiYWNrUHJvYmUgPz8gW10pLm1hcChwID0+IGAke3AubGFiZWx9PSR7cC5zdWNjZWVkZWQgPyBgc3VjY2VzcyAoJHtwLmNvdW50fSBpdGVtczsgc2FtZSBmaXJzdCBwYWdlPSR7cC5zYW1lRmlyc3RQYWdlfSlgIDogYGZhaWxlZCAoJHtwLmVycm9yPy5tZXNzYWdlID8/ICJ1bmtub3duIGVycm9yIn0pYH1gKS5qb2luKCI7ICIpIHx8ICJub3QgcnVuIn1gLAogICAgICBgLSBWaWRlbyB0YWIgcHJvYmU6IGdldFZpZGVvcz0ke2MudmlkZW9UYWJQcm9iZT8uZ2V0VmlkZW9zPy52aWRlb0l0ZW1Db3VudCA/PyAidW5hdmFpbGFibGUifSBpdGVtczsgZ2V0VGFiQnlOYW1lPSR7Yy52aWRlb1RhYlByb2JlPy5nZXRUYWJCeU5hbWVWaWRlb3M/LnZpZGVvSXRlbUNvdW50ID8/ICJ1bmF2YWlsYWJsZSJ9IGl0ZW1zYCwKICAgICAgYC0gRmVlZCBjb3VudHM6IGRlZmF1bHQ9JHtjLmRlZmF1bHRGZWVkPy51bmlxdWVDb3VudCA/PyAibm90IGZldGNoZWQifSwgbGF0ZXN0PSR7Yy5sYXRlc3RGZWVkPy51bmlxdWVDb3VudCA/PyAoYy5sYXRlc3RGZWVkPy5za2lwcGVkID8gInNraXBwZWQiIDogImZhaWxlZCIpfSwgcG9wdWxhcj0ke2MucG9wdWxhckZlZWQ/LnVuaXF1ZUNvdW50ID8/IChjLnBvcHVsYXJGZWVkPy5za2lwcGVkID8gInNraXBwZWQiIDogImZhaWxlZCIpfWAsCiAgICAgIGAtIExvY2FsIHNvcnRhYmlsaXR5OiBkYXRlcz0ke2MubG9jYWxTb3J0UHJvYmU/LmRhdGVBdmFpbGFibGUgPz8gMH0vJHtjLmxvY2FsU29ydFByb2JlPy5zYW1wbGVkVmlkZW9Db3VudCA/PyAwfTsgbnVtZXJpYyB2aWV3cz0ke2MubG9jYWxTb3J0UHJvYmU/Lm51bWVyaWNWaWV3Q291bnRBdmFpbGFibGUgPz8gMH0vJHtjLmxvY2FsU29ydFByb2JlPy5zYW1wbGVkVmlkZW9Db3VudCA/PyAwfWAsCiAgICAgIGAtIEZ1bGwtY2F0YWxvZ3VlIGVzdGltYXRlOiBkZWNsYXJlZOKJiCR7Yy5mdWxsQ2F0YWxvZ3VlRXN0aW1hdGU/LmRlY2xhcmVkVmlkZW9Db3VudEFwcHJveCA/PyAidW5rbm93biJ9OyBlc3RpbWF0ZWQgcGFnZXPiiYgke2MuZnVsbENhdGFsb2d1ZUVzdGltYXRlPy5lc3RpbWF0ZWRQYWdlc0F0T2JzZXJ2ZWRQYWdlU2l6ZSA/PyAidW5rbm93biJ9OyBwaWxvdC1wYWNlIHNlY29uZHPiiYgke2MuZnVsbENhdGFsb2d1ZUVzdGltYXRlPy5lc3RpbWF0ZWRTZWNvbmRzQXRQaWxvdFBhY2UgPz8gInVua25vd24ifSAoZXN0aW1hdGUgb25seTsgbm8gZnVsbCBjcmF3bCBhdHRlbXB0ZWQpYCwKICAgICAgYC0gU29ydCBjb21wYXJpc29uOiAke2Muc29ydENvbXBhcmlzb24/LnZlcmRpY3QgPz8gIm5vdCBhdmFpbGFibGUifWAsCiAgICAgIGAtIExhdGVzdCB2cyBwb3B1bGFyIEphY2NhcmQgb3ZlcmxhcDogJHtjLnNvcnRDb21wYXJpc29uPy5sYXRlc3RWc1BvcHVsYXI/LmphY2NhcmQgPz8gInVua25vd24ifWAsCiAgICAgIGAtIEVycm9yczogJHtjLmVycm9ycz8ubGVuZ3RoID8/IDB9YCwKICAgICAgIiIpOwogICAgaWYgKGMuZXJyb3JzPy5sZW5ndGgpIGZvciAoY29uc3QgZSBvZiBjLmVycm9ycykgbWQucHVzaChgICAtIFxgJHtlLnN0YWdlfVxgOiAke2UubWVzc2FnZX1gKTsKICB9CiAgbWQucHVzaCgiIyMgSW50ZXJwcmV0YXRpb24gY2F1dGlvbnMiLCAiIiwKICAgICItIFlvdVR1YmUgbWF5IGNoYW5nZSByZXNwb25zZSBzdHJ1Y3R1cmVzIG9yIHJlc3RyaWN0IHJlcXVlc3RzOyBmYWlsdXJlcyBhcmUgZXZpZGVuY2UgYWJvdXQgdGhpcyBydW4sIG5vdCBwcm9vZiBhIGNoYW5uZWwgaGFzIG5vIHZpZGVvcy4iLAogICAgIi0gQW4gYWJzZW50IG1ldGFkYXRhIGZpZWxkIGlzIHVua25vd24sIG5vdCB6ZXJvLiIsCiAgICAiLSBUaGlzIHJ1biBpcyBhIGJvdW5kZWQgcGFnaW5hdGlvbiBwaWxvdCAoQ05OIHVwIHRvIGZpdmUgcGFnZXM7IGNvbXBhcmlzb24gY2hhbm5lbHMgdXAgdG8gdGhyZWUpOyBpdCBkb2VzIG5vdCBhdHRlbXB0IGEgZnVsbCBjYXRhbG9ndWUgY3Jhd2wuIiwKICAgICItIExvY2FsIHNvcnRpbmcgaXMgb25seSBhcyBnb29kIGFzIGZpZWxkcyBwcmVzZW50IGluIGVhY2ggZmVlZCBpdGVtLiBSZWxhdGl2ZSB1cGxvYWQgYWdlcyBhcmUgYXBwcm94aW1hdGU7IHBvcHVsYXJpdHkgc29ydGluZyBuZWVkcyB1c2FibGUgcGVyLXZpZGVvIHZpZXcgY291bnRzLiIsCiAgICAiLSBBIGxhcmdlIGNoYW5uZWwncyBlc3RpbWF0ZWQgcGFnZSBjb3VudCBleHRyYXBvbGF0ZXMgZnJvbSB0aGUgb2JzZXJ2ZWQgYmF0Y2ggc2l6ZSBhbmQgZGVjbGFyZWQgY291bnQ7IGl0IGlzIG5vdCBwcm9vZiB0aGF0IGV2ZXJ5IGhpc3RvcmljYWwgdXBsb2FkIGlzIHB1YmxpY2x5IHJldHJpZXZhYmxlLiIsCiAgICAiLSBhcHBseVNvcnQgaXMgdHJlYXRlZCBhcyBhIGRpYWdub3N0aWMgb25seS4gQSBzdWNjZXNzZnVsIG1ldGhvZCBjYWxsIHdvdWxkIG5vdCBwcm92ZSBzb3J0aW5nIHVubGVzcyByZXR1cm5lZCBJRHMvb3JkZXIgY2hhbmdlIGFuZCBtYXRjaCB0aGUgcmVxdWVzdGVkIGNyaXRlcmlvbi4iLAogICAgIi0gUG9wdWxhciBvcmRlcmluZyBpcyBvbmx5IGNvbnNpZGVyZWQgcGxhdXNpYmxlIGlmIGF0IGxlYXN0IHRocmVlIHJldHVybmVkIHZpZGVvcyBleHBvc2UgcGFyc2VhYmxlIHZpZXcgY291bnRzIGFuZCB0aG9zZSBjb3VudHMgYXJlIG5vbi1pbmNyZWFzaW5nLiIsCiAgICAiLSBNZXRhZGF0YSBmaWVsZHMgYXJlIHJlYWQgZnJvbSB0aGUgbmVzdGVkIEFib3V0Q2hhbm5lbCBtZXRhZGF0YSBlbnZlbG9wZS4iLAogICAgIi0gU29ydCBkaWFnbm9zdGljcyBpbnNwZWN0IHNvcnRfZmlsdGVycywgcHJpbWFyeS9zZWNvbmRhcnkvY29udGVudC10eXBlIGZpbHRlcnMsIGZpbHRlcl9ub2RlcywgYW5kIHJhdyByZXNwb25zZSBwYXRocyBjb250YWluaW5nIHNvcnQvZmlsdGVyL2NoaXAvbWVudSB0ZXJtcy4iLAogICAgIi0gSWYgc29ydF9maWx0ZXJzIGlzIGVtcHR5LCBjb21tb24gYXBwbHlTb3J0IGxhYmVscyBhcmUgcHJvYmVkIGRpYWdub3N0aWNhbGx5LiBBIHN1Y2Nlc3NmdWwgY2FsbCBpcyBub3QgcHJvb2Ygb2YgYSBjaGFuZ2VkIG9yZGVyOyBjb21wYXJlIHJldHVybmVkIElEcyBhbmQgc2FtZUZpcnN0UGFnZS4iLAogICAgIi0geXRzZWFyY2guanMgaXMgYSBzZWNvbmRhcnkgc2VhcmNoIGNyb3NzLWNoZWNrLCBub3QgYW4gYXV0aG9yaXRhdGl2ZSBzb3VyY2UgZm9yIGNoYW5uZWwgbWV0YWRhdGEuIiwKICAgICItIEZvciBkdXJhYmxlIHJhbmtpbmdzLCBzdG9yZSByYXcgc25hcHNob3RzIHdpdGggZmV0Y2ggdGltZXN0YW1wcyBhbmQgc291cmNlL2xpYnJhcnkgdmVyc2lvbnMuIiwKICAgICIiLAogICAgIiMjIEZpbGVzIiwgIiIsCiAgICAiLSBgY2hhbm5lbC1mZXRjaC1kaWFnbm9zdGljLW91dHB1dC5qc29uYCDigJQgY29tcGxldGUgbm9ybWFsaXplZC9yYXctc2hhcGUgcmVwb3J0LiIsCiAgICAiLSBgY2hhbm5lbC1mZXRjaC1kaWFnbm9zdGljLXJlcG9ydC5tZGAg4oCUIGNvbmNpc2UgaHVtYW4tcmVhZGFibGUgcmVwb3J0LiIsCiAgICAiIik7CiAgY29uc3QgbWRQYXRoID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksICJjaGFubmVsLWZldGNoLWRpYWdub3N0aWMtcmVwb3J0Lm1kIik7CiAgZnMud3JpdGVGaWxlU3luYyhtZFBhdGgsIG1kLmpvaW4oIlxuIiksICJ1dGY4Iik7CiAgY29uc29sZS5sb2coIlxuXG49PT09PT09PT09PT09PT09PT09PSBTVU1NQVJZID09PT09PT09PT09PT09PT09PT09Iik7CiAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocmVwb3J0LnN1bW1hcnksIG51bGwsIDIpKTsKICBjb25zb2xlLmxvZyhgXG5bb3V0cHV0XSAke291dFBhdGh9YCk7CiAgY29uc29sZS5sb2coYFtvdXRwdXRdICR7bWRQYXRofWApOwogIGNvbnNvbGUubG9nKCJbZG9uZV0gUGxlYXNlIHNlbmQgYm90aCBmaWxlcyBiYWNrIGZvciBhbmFseXNpcywgZXNwZWNpYWxseSB0aGUgSlNPTi4iKTsKfQoKbWFpbigpLmNhdGNoKGVycm9yID0+IHsKICBjb25zb2xlLmVycm9yKCJbZmF0YWxdIiwgZXJyb3I/LnN0YWNrID8/IGVycm9yKTsKICBwcm9jZXNzLmV4aXRDb2RlID0gMTsKfSk7Cg==", "base64").toString("utf8"); {
console.log("YouTube Ecosystem Intelligence — self-installing diagnostic");
console.log(`Node: ${process.version}`);
if (Number(process.versions.node.split(".")[0]) < 18) {
throw new Error("Please run with Node.js 18+ (Node.js 20+ recommended).");
}
fs.mkdirSync(WORK_DIR, { recursive: true });
fs.writeFileSync(PACKAGE_PATH, JSON.stringify({
name: "youtube-ecosystem-fetch-diagnostic",
private: true,
type: "module",
dependencies: {
"youtubei.js": "18.1.0",
"ytsearch.js": "2.1.3"
}
}, null, 2));
log("Installing isolated dependencies", { directory: WORK_DIR, packages: ["youtubei.js@18.1.0", "ytsearch.js@2.1.3"] });
if (process.platform === "win32") {
// Prefer invoking npm's JavaScript CLI through the current Node executable.
// This avoids Windows cmd.exe/.cmd quoting edge cases (including paths with
// spaces). Fall back to a shell only if npm's standard CLI path is absent.
const npmCli = path.join(path.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
if (fs.existsSync(npmCli)) {
run(process.execPath, [npmCli, "install", "--prefix", WORK_DIR, "--no-audit", "--no-fund"], { cwd: WORK_DIR });
} else {
log("Standard npm CLI path not found; falling back to npm.cmd via shell");
run("npm.cmd", ["install", "--prefix", WORK_DIR, "--no-audit", "--no-fund"], { cwd: WORK_DIR, shell: true });
}
} else {
run("npm", ["install", "--prefix", WORK_DIR, "--no-audit", "--no-fund"], { cwd: WORK_DIR });
}
fs.writeFileSync(RUNNER_PATH, runnerSource, "utf8");
log("Starting live tests", "This makes public YouTube requests. It can take a few minutes.");
run(process.execPath, [RUNNER_PATH], { cwd: process.cwd() });
if (!fs.existsSync(OUTPUT_JSON) || !fs.existsSync(OUTPUT_MD)) {
throw new Error("Runner ended without creating both expected output files.");
}
log("Diagnostic completed", {
json: OUTPUT_JSON,
markdown: OUTPUT_MD,
note: "No project files, package files, or SQLite database were modified."
});
}
Shown as it is in the repository at build time (2026-11-03); the home directory appears as <home>. If this page and the file differ, the file is right. Back to the catalogue.