#!/usr/bin/env node // coding-tools/figma-tools/js/src/_utils/cli-args.ts function parseArgs(argv = process.argv.slice(2)) { const args = { _: [] }; for (let i = 0; i < argv.length; i += 1) { const arg = argv[i]; if (!arg.startsWith("-") || arg === "-") { args._.push(arg); continue; } if (arg === "--") { const remaining = argv.slice(i + 1); args._.push(...remaining); break; } const [rawKey, inlineValue] = arg.split("=", 2); const normalisedKey = rawKey.replace(/^-+/, ""); let value; if (inlineValue !== void 0) { value = inlineValue; } else { const next = argv[i + 1]; if (next !== void 0 && !next.startsWith("-")) { value = next; i += 1; } else { value = true; } } args[normalisedKey] = value; } return args; } // coding-tools/figma-tools/js/src/_utils/url-parse.ts var FILE_KEY_REGEX = /figma\.com\/(?:file|design)\/([A-Za-z0-9]+)\//i; function parseFigmaUrl(input) { if (!input) return { fileKey: null, nodeId: null }; try { const url = new URL(input); const match = url.href.match(FILE_KEY_REGEX); const fileKey = match ? match[1] : null; const nodeParam = url.searchParams.get("node-id"); const nodeId = nodeParam ? ensureNodeId(nodeParam) : null; return { fileKey, nodeId }; } catch { return { fileKey: null, nodeId: null }; } } function ensureNodeId(value) { if (!value) return null; const decoded = decodeURIComponent(value); if (decoded.includes(":")) return decoded; if (/^[0-9]+-[0-9]+$/.test(decoded)) { const [left, right] = decoded.split("-", 2); return `${left}:${right}`; } return decoded; } // coding-tools/figma-tools/js/src/_utils/config.ts var config_default = { schemaVersion: "1.0.0", source: "agentic-coding-templates/figma-tools", http: { maxAttempts: 5, initialDelayMs: 250 } }; // coding-tools/figma-tools/js/src/_utils/envelope.ts function buildRateLimitMeta(rateLimit = {}) { return { remaining: rateLimit.remaining ?? null, resetAt: rateLimit.resetAt ?? null, attempts: rateLimit.attempts ?? 1, lastWaitMs: rateLimit.lastWaitMs ?? 0 }; } function createEnvelope({ tool, input = {}, data = {}, warnings = [], errors = [], rateLimit, schemaVersion }) { return { schemaVersion: schemaVersion ?? config_default.schemaVersion, tool, input, meta: { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), source: config_default.source, rateLimit: buildRateLimitMeta(rateLimit) }, data, warnings, errors }; } // coding-tools/figma-tools/js/src/_utils/errors.ts var ERROR_EXIT_CODES = { INPUT_INVALID: 1, CONFIG_INVALID: 1, FIGMA_AUTH: 1, FIGMA_NOT_FOUND: 2, FIGMA_RATE_LIMIT: 2, NETWORK: 2, INTERNAL: 3 }; function createError(code, message, detail) { return { code, message, detail: detail ?? null }; } function getExitCode(errors = []) { if (!errors.length) { return 0; } return errors.reduce((max, error) => { const exitCode = ERROR_EXIT_CODES[error.code] ?? 1; return Math.max(max, exitCode); }, 0); } // coding-tools/figma-tools/js/src/_utils/http-client.ts var BASE_URL = "https://api.figma.com"; function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } function parseJsonSafely(text) { try { return text ? JSON.parse(text) : {}; } catch { return { raw: text }; } } function parseRateLimit(headers, attempts, lastWaitMs) { const remainingHeader = headers.get("x-ratelimit-remaining"); const resetHeader = headers.get("x-ratelimit-reset"); let remaining = null; if (remainingHeader !== null && remainingHeader !== void 0) { const parsed = Number(remainingHeader); remaining = Number.isNaN(parsed) ? null : parsed; } let resetAt = null; if (resetHeader) { const numericReset = Number(resetHeader); if (!Number.isNaN(numericReset)) { resetAt = new Date(numericReset * 1e3).toISOString(); } else { const date = new Date(resetHeader); if (!Number.isNaN(date.valueOf())) { resetAt = date.toISOString(); } } } return { remaining, resetAt, attempts, lastWaitMs }; } function computeBackoffMs(attempt, initialDelayMs) { return initialDelayMs * 2 ** (attempt - 1); } async function figmaRequest(options) { const { path, method = "GET", token, headers = {}, body, searchParams, maxAttempts = config_default.http?.maxAttempts ?? 5, initialDelayMs = config_default.http?.initialDelayMs ?? 250 } = options; if (!token) { return { ok: false, error: createError("FIGMA_AUTH", "FIGMA_ACCESS_TOKEN is missing from the environment."), status: null, rateLimit: null }; } const url = new URL(path, BASE_URL); if (searchParams) { Object.entries(searchParams).forEach(([key, value]) => { if (value === void 0 || value === null) return; url.searchParams.append(key, String(value)); }); } let attempt = 0; let lastWaitMs = 0; while (attempt < maxAttempts) { attempt += 1; const response = await fetch(url, { method, headers: { "Content-Type": "application/json", "X-Figma-Token": token, ...headers }, body: body ? JSON.stringify(body) : void 0 }); const text = await response.text(); const payload = parseJsonSafely(text); const rateLimit = parseRateLimit(response.headers, attempt, lastWaitMs); if (response.ok) { return { ok: true, data: payload, rateLimit }; } const status = response.status; if (status === 401 || status === 403) { return { ok: false, error: createError("FIGMA_AUTH", payload?.message ?? "Figma token is unauthorized.", { status }), status, rateLimit }; } if (status === 404) { return { ok: false, error: createError("FIGMA_NOT_FOUND", payload?.message ?? "Resource not found.", { status }), status, rateLimit }; } if (status === 429 || status >= 500) { if (attempt >= maxAttempts) { return { ok: false, error: createError(status === 429 ? "FIGMA_RATE_LIMIT" : "NETWORK", payload?.message ?? "Figma request failed after maximum retries.", { status }), status, rateLimit }; } let waitMs = computeBackoffMs(attempt, initialDelayMs); const resetHeader = response.headers.get("x-ratelimit-reset"); if (resetHeader) { const asNumber = Number(resetHeader); if (!Number.isNaN(asNumber)) { const resetMs = asNumber * 1e3; const delta = resetMs - Date.now(); if (delta > 0) waitMs = Math.max(waitMs, delta); } } const jitter = Math.floor(Math.random() * 100); lastWaitMs = waitMs + jitter; await sleep(lastWaitMs); continue; } return { ok: false, error: createError("INTERNAL", payload?.message ?? "Unexpected error from Figma API.", { status }), status, rateLimit }; } return { ok: false, error: createError("NETWORK", "Unable to reach Figma API."), status: null, rateLimit: { remaining: null, resetAt: null, attempts: maxAttempts, lastWaitMs } }; } // coding-tools/figma-tools/js/src/get-variable-definitions.ts var TOOL_NAME = "get-variable-definitions"; function log(message, verbose) { if (verbose) process.stderr.write(`[${TOOL_NAME}] ${message} `); } function toOptionalString(value) { return typeof value === "string" && value.length > 0 ? value : null; } function exitWithEnvelope(envelope, errors = []) { process.stdout.write(`${JSON.stringify(envelope, null, 2)} `); process.exit(getExitCode(errors)); } function resolveCollectionName(id, collections) { if (!id) return null; const entry = collections.find((c) => c.id === id); return entry?.name ?? null; } function buildVariableEntry(variable, collections, sets) { return { id: variable.id, name: variable.name, key: variable.key, resolvedType: variable.resolvedType, collectionId: variable.collectionId ?? variable.variableCollectionId ?? null, collectionName: resolveCollectionName(variable.collectionId ?? variable.variableCollectionId, collections), variableSetId: variable.variableSetId ?? null, variableSetName: resolveCollectionName(variable.variableSetId, sets), scopes: variable.scopes ?? [], description: variable.description ?? null, defaultValue: variable.valuesByMode?.[variable.defaultModeId ?? ""] ?? null, valuesByMode: variable.valuesByMode ?? {} }; } function partitionVariables(list) { const colors = []; const spacing = []; const typography = []; const others = []; for (const entry of list) { switch (entry.resolvedType) { case "COLOR": colors.push(entry); break; case "FLOAT": spacing.push(entry); break; case "STRING": case "BOOLEAN": typography.push(entry); break; default: others.push(entry); } } return { colors, spacing, typography, others }; } function extractStyles(payload) { if (!payload) return []; if (Array.isArray(payload.styles)) return payload.styles; if (payload.meta?.styles) return Object.values(payload.meta.styles); return []; } async function main() { const args = parseArgs(); const verbose = Boolean(args.verbose ?? args.v); const schemaVersion = toOptionalString(args["schema-version"]) ?? void 0; const warnings = []; const errors = []; const token = process.env.FIGMA_ACCESS_TOKEN; if (!token || !token.trim()) { errors.push(createError("FIGMA_AUTH", "FIGMA_ACCESS_TOKEN is required but was not provided.")); const envelope2 = createEnvelope({ tool: TOOL_NAME, input: { fileKey: null, includeStyles: false }, warnings, errors, schemaVersion, data: {} }); exitWithEnvelope(envelope2, errors); } const urlInput = toOptionalString(args.url) ?? toOptionalString(args.u); let fileKey = toOptionalString(args["file-key"]) ?? void 0; if (urlInput) { const parsed = parseFigmaUrl(urlInput); fileKey = fileKey || parsed.fileKey || void 0; } const includeStyles = args["include-styles"] !== "false"; const input = { fileKey: fileKey ?? null, includeStyles }; if (!fileKey) { errors.push(createError("INPUT_INVALID", "A valid Figma file key is required (--file-key or --url).")); } if (errors.length) { const envelope2 = createEnvelope({ tool: TOOL_NAME, input, warnings, errors, data: {}, schemaVersion }); exitWithEnvelope(envelope2, errors); } const resolvedFileKey = fileKey; log("Fetching variables", verbose); const variablesResponse = await figmaRequest({ path: `/v1/files/${resolvedFileKey}/variables/local`, token }); let stylesResponse; if (includeStyles) { log("Fetching styles", verbose); stylesResponse = await figmaRequest({ path: `/v1/files/${resolvedFileKey}/styles`, token }); } else { stylesResponse = { ok: true, data: { styles: [] }, rateLimit: null }; } if (!variablesResponse.ok) { errors.push(variablesResponse.error ?? createError("INTERNAL", "Failed to fetch variables.")); const envelope2 = createEnvelope({ tool: TOOL_NAME, input, warnings, errors, rateLimit: variablesResponse.rateLimit ?? void 0, schemaVersion, data: {} }); exitWithEnvelope(envelope2, errors); } if (!stylesResponse.ok) { warnings.push(stylesResponse.error?.message ?? "Failed to fetch styles."); } const variablesPayload = variablesResponse.data ?? {}; const variableCollections = variablesPayload.collections ?? []; const variableSets = variablesPayload.variableCollections ?? []; const variables = variablesPayload.variables ?? []; const normalisedVariables = variables.map((v) => buildVariableEntry(v, variableCollections, variableSets)); const partitions = partitionVariables(normalisedVariables); const styles = stylesResponse.ok ? extractStyles(stylesResponse.data) : []; const data = { file: { key: resolvedFileKey }, variables: partitions, rawVariables: normalisedVariables, styles }; const envelope = createEnvelope({ tool: TOOL_NAME, input, data, warnings, errors, rateLimit: variablesResponse.rateLimit ?? void 0, schemaVersion }); process.stdout.write(`${JSON.stringify(envelope, null, 2)} `); process.exit(getExitCode(errors)); } main().catch((error) => { const message = error instanceof Error ? error.message : "Unknown error"; const envelope = createEnvelope({ tool: TOOL_NAME, input: { fileKey: null, includeStyles: false }, errors: [createError("INTERNAL", message, { stack: error instanceof Error ? error.stack : void 0 })], data: {} }); process.stdout.write(`${JSON.stringify(envelope, null, 2)} `); process.exit(3); }); //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL191dGlscy9jbGktYXJncy50cyIsICIuLi9zcmMvX3V0aWxzL3VybC1wYXJzZS50cyIsICIuLi9zcmMvX3V0aWxzL2NvbmZpZy50cyIsICIuLi9zcmMvX3V0aWxzL2VudmVsb3BlLnRzIiwgIi4uL3NyYy9fdXRpbHMvZXJyb3JzLnRzIiwgIi4uL3NyYy9fdXRpbHMvaHR0cC1jbGllbnQudHMiLCAiLi4vc3JjL2dldC12YXJpYWJsZS1kZWZpbml0aW9ucy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiZXhwb3J0IHR5cGUgQ2xpQXJnVmFsdWUgPSBzdHJpbmcgfCBib29sZWFuO1xuXG5leHBvcnQgaW50ZXJmYWNlIENsaUFyZ3Mge1xuICBfOiBzdHJpbmdbXTtcbiAgW2tleTogc3RyaW5nXTogQ2xpQXJnVmFsdWUgfCBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQXJncyhhcmd2OiBzdHJpbmdbXSA9IHByb2Nlc3MuYXJndi5zbGljZSgyKSk6IENsaUFyZ3Mge1xuICBjb25zdCBhcmdzOiBDbGlBcmdzID0geyBfOiBbXSB9O1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJndi5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGNvbnN0IGFyZyA9IGFyZ3ZbaV07XG5cbiAgICBpZiAoIWFyZy5zdGFydHNXaXRoKCctJykgfHwgYXJnID09PSAnLScpIHtcbiAgICAgIGFyZ3MuXy5wdXNoKGFyZyk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoYXJnID09PSAnLS0nKSB7XG4gICAgICBjb25zdCByZW1haW5pbmcgPSBhcmd2LnNsaWNlKGkgKyAxKTtcbiAgICAgIGFyZ3MuXy5wdXNoKC4uLnJlbWFpbmluZyk7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjb25zdCBbcmF3S2V5LCBpbmxpbmVWYWx1ZV0gPSBhcmcuc3BsaXQoJz0nLCAyKTtcbiAgICBjb25zdCBub3JtYWxpc2VkS2V5ID0gcmF3S2V5LnJlcGxhY2UoL14tKy8sICcnKTtcblxuICAgIGxldCB2YWx1ZTogQ2xpQXJnVmFsdWU7XG4gICAgaWYgKGlubGluZVZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhbHVlID0gaW5saW5lVmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG5leHQgPSBhcmd2W2kgKyAxXTtcbiAgICAgIGlmIChuZXh0ICE9PSB1bmRlZmluZWQgJiYgIW5leHQuc3RhcnRzV2l0aCgnLScpKSB7XG4gICAgICAgIHZhbHVlID0gbmV4dDtcbiAgICAgICAgaSArPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWUgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGFyZ3Nbbm9ybWFsaXNlZEtleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIHJldHVybiBhcmdzO1xufVxuXG4iLCAiY29uc3QgRklMRV9LRVlfUkVHRVggPSAvZmlnbWFcXC5jb21cXC8oPzpmaWxlfGRlc2lnbilcXC8oW0EtWmEtejAtOV0rKVxcLy9pO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBhcnNlZEZpZ21hVXJsIHtcbiAgZmlsZUtleTogc3RyaW5nIHwgbnVsbDtcbiAgbm9kZUlkOiBzdHJpbmcgfCBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VGaWdtYVVybChpbnB1dDogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCk6IFBhcnNlZEZpZ21hVXJsIHtcbiAgaWYgKCFpbnB1dCkgcmV0dXJuIHsgZmlsZUtleTogbnVsbCwgbm9kZUlkOiBudWxsIH07XG4gIHRyeSB7XG4gICAgY29uc3QgdXJsID0gbmV3IFVSTChpbnB1dCk7XG4gICAgY29uc3QgbWF0Y2ggPSB1cmwuaHJlZi5tYXRjaChGSUxFX0tFWV9SRUdFWCk7XG4gICAgY29uc3QgZmlsZUtleSA9IG1hdGNoID8gbWF0Y2hbMV0gOiBudWxsO1xuICAgIGNvbnN0IG5vZGVQYXJhbSA9IHVybC5zZWFyY2hQYXJhbXMuZ2V0KCdub2RlLWlkJyk7XG4gICAgY29uc3Qgbm9kZUlkID0gbm9kZVBhcmFtID8gZW5zdXJlTm9kZUlkKG5vZGVQYXJhbSkgOiBudWxsO1xuICAgIHJldHVybiB7IGZpbGVLZXksIG5vZGVJZCB9O1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4geyBmaWxlS2V5OiBudWxsLCBub2RlSWQ6IG51bGwgfTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlTm9kZUlkKHZhbHVlOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgbnVsbCB7XG4gIGlmICghdmFsdWUpIHJldHVybiBudWxsO1xuICBjb25zdCBkZWNvZGVkID0gZGVjb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcbiAgaWYgKGRlY29kZWQuaW5jbHVkZXMoJzonKSkgcmV0dXJuIGRlY29kZWQ7XG4gIGlmICgvXlswLTldKy1bMC05XSskLy50ZXN0KGRlY29kZWQpKSB7XG4gICAgY29uc3QgW2xlZnQsIHJpZ2h0XSA9IGRlY29kZWQuc3BsaXQoJy0nLCAyKTtcbiAgICByZXR1cm4gYCR7bGVmdH06JHtyaWdodH1gO1xuICB9XG4gIHJldHVybiBkZWNvZGVkO1xufVxuXG4iLCAiZXhwb3J0IGRlZmF1bHQge1xuICBzY2hlbWFWZXJzaW9uOiAnMS4wLjAnLFxuICBzb3VyY2U6ICdhZ2VudGljLWNvZGluZy10ZW1wbGF0ZXMvZmlnbWEtdG9vbHMnLFxuICBodHRwOiB7XG4gICAgbWF4QXR0ZW1wdHM6IDUsXG4gICAgaW5pdGlhbERlbGF5TXM6IDI1MCxcbiAgfSxcbn0gYXMgY29uc3Q7XG5cbiIsICJpbXBvcnQgY29uZmlnIGZyb20gJy4vY29uZmlnLnRzJztcbmltcG9ydCB0eXBlIHsgVG9vbEVycm9yIH0gZnJvbSAnLi9lcnJvcnMudHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJhdGVMaW1pdE1ldGEge1xuICByZW1haW5pbmc6IG51bWJlciB8IG51bGw7XG4gIHJlc2V0QXQ6IHN0cmluZyB8IG51bGw7XG4gIGF0dGVtcHRzOiBudW1iZXI7XG4gIGxhc3RXYWl0TXM6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUb29sRW52ZWxvcGU8XG4gIFRJbnB1dCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0gUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIFREYXRhID0gdW5rbm93blxuPiB7XG4gIHNjaGVtYVZlcnNpb246IHN0cmluZztcbiAgdG9vbDogc3RyaW5nO1xuICBpbnB1dDogVElucHV0O1xuICBtZXRhOiB7XG4gICAgZ2VuZXJhdGVkQXQ6IHN0cmluZztcbiAgICBzb3VyY2U6IHN0cmluZztcbiAgICByYXRlTGltaXQ6IFJhdGVMaW1pdE1ldGE7XG4gIH07XG4gIGRhdGE6IFREYXRhO1xuICB3YXJuaW5nczogc3RyaW5nW107XG4gIGVycm9yczogVG9vbEVycm9yW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlRW52ZWxvcGVPcHRpb25zPFxuICBUSW5wdXQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBURGF0YSA9IHVua25vd25cbj4ge1xuICB0b29sOiBzdHJpbmc7XG4gIGlucHV0PzogVElucHV0O1xuICBkYXRhPzogVERhdGE7XG4gIHdhcm5pbmdzPzogc3RyaW5nW107XG4gIGVycm9ycz86IFRvb2xFcnJvcltdO1xuICByYXRlTGltaXQ/OiBQYXJ0aWFsPFJhdGVMaW1pdE1ldGE+O1xuICBzY2hlbWFWZXJzaW9uPzogc3RyaW5nO1xufVxuXG5mdW5jdGlvbiBidWlsZFJhdGVMaW1pdE1ldGEocmF0ZUxpbWl0OiBQYXJ0aWFsPFJhdGVMaW1pdE1ldGE+ID0ge30pOiBSYXRlTGltaXRNZXRhIHtcbiAgcmV0dXJuIHtcbiAgICByZW1haW5pbmc6IHJhdGVMaW1pdC5yZW1haW5pbmcgPz8gbnVsbCxcbiAgICByZXNldEF0OiByYXRlTGltaXQucmVzZXRBdCA/PyBudWxsLFxuICAgIGF0dGVtcHRzOiByYXRlTGltaXQuYXR0ZW1wdHMgPz8gMSxcbiAgICBsYXN0V2FpdE1zOiByYXRlTGltaXQubGFzdFdhaXRNcyA/PyAwLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRW52ZWxvcGU8XG4gIFRJbnB1dCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0gUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIFREYXRhID0gdW5rbm93blxuPih7XG4gIHRvb2wsXG4gIGlucHV0ID0ge30gYXMgVElucHV0LFxuICBkYXRhID0ge30gYXMgVERhdGEsXG4gIHdhcm5pbmdzID0gW10sXG4gIGVycm9ycyA9IFtdLFxuICByYXRlTGltaXQsXG4gIHNjaGVtYVZlcnNpb24sXG59OiBDcmVhdGVFbnZlbG9wZU9wdGlvbnM8VElucHV0LCBURGF0YT4pOiBUb29sRW52ZWxvcGU8VElucHV0LCBURGF0YT4ge1xuICByZXR1cm4ge1xuICAgIHNjaGVtYVZlcnNpb246IHNjaGVtYVZlcnNpb24gPz8gY29uZmlnLnNjaGVtYVZlcnNpb24sXG4gICAgdG9vbCxcbiAgICBpbnB1dCxcbiAgICBtZXRhOiB7XG4gICAgICBnZW5lcmF0ZWRBdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgc291cmNlOiBjb25maWcuc291cmNlLFxuICAgICAgcmF0ZUxpbWl0OiBidWlsZFJhdGVMaW1pdE1ldGEocmF0ZUxpbWl0KSxcbiAgICB9LFxuICAgIGRhdGEsXG4gICAgd2FybmluZ3MsXG4gICAgZXJyb3JzLFxuICB9O1xufVxuXG4iLCAiZXhwb3J0IGNvbnN0IEVSUk9SX0VYSVRfQ09ERVMgPSB7XG4gIElOUFVUX0lOVkFMSUQ6IDEsXG4gIENPTkZJR19JTlZBTElEOiAxLFxuICBGSUdNQV9BVVRIOiAxLFxuICBGSUdNQV9OT1RfRk9VTkQ6IDIsXG4gIEZJR01BX1JBVEVfTElNSVQ6IDIsXG4gIE5FVFdPUks6IDIsXG4gIElOVEVSTkFMOiAzLFxufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgRXJyb3JDb2RlID0ga2V5b2YgdHlwZW9mIEVSUk9SX0VYSVRfQ09ERVM7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVG9vbEVycm9yPFREZXRhaWwgPSB1bmtub3duPiB7XG4gIGNvZGU6IEVycm9yQ29kZSB8IHN0cmluZztcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBkZXRhaWw/OiBURGV0YWlsIHwgbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVycm9yPFREZXRhaWwgPSB1bmtub3duPihcbiAgY29kZTogRXJyb3JDb2RlIHwgc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmcsXG4gIGRldGFpbD86IFREZXRhaWwgfCBudWxsXG4pOiBUb29sRXJyb3I8VERldGFpbD4ge1xuICByZXR1cm4ge1xuICAgIGNvZGUsXG4gICAgbWVzc2FnZSxcbiAgICBkZXRhaWw6IGRldGFpbCA/PyBudWxsLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXhpdENvZGUoZXJyb3JzOiBUb29sRXJyb3JbXSA9IFtdKTogbnVtYmVyIHtcbiAgaWYgKCFlcnJvcnMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICByZXR1cm4gZXJyb3JzLnJlZHVjZSgobWF4LCBlcnJvcikgPT4ge1xuICAgIGNvbnN0IGV4aXRDb2RlID0gRVJST1JfRVhJVF9DT0RFU1tlcnJvci5jb2RlIGFzIEVycm9yQ29kZV0gPz8gMTtcbiAgICByZXR1cm4gTWF0aC5tYXgobWF4LCBleGl0Q29kZSk7XG4gIH0sIDApO1xufVxuXG4iLCAiaW1wb3J0IGNvbmZpZyBmcm9tICcuL2NvbmZpZy50cyc7XG5pbXBvcnQgeyBjcmVhdGVFcnJvciB9IGZyb20gJy4vZXJyb3JzLnRzJztcbmltcG9ydCB0eXBlIHsgVG9vbEVycm9yIH0gZnJvbSAnLi9lcnJvcnMudHMnO1xuaW1wb3J0IHR5cGUgeyBSYXRlTGltaXRNZXRhIH0gZnJvbSAnLi9lbnZlbG9wZS50cyc7XG5cbmNvbnN0IEJBU0VfVVJMID0gJ2h0dHBzOi8vYXBpLmZpZ21hLmNvbSc7XG5cbnR5cGUgU2VhcmNoUGFyYW1zID0gUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG51bGwgfCB1bmRlZmluZWQ+O1xuXG5pbnRlcmZhY2UgRmlnbWFSZXF1ZXN0T3B0aW9ucyB7XG4gIHBhdGg6IHN0cmluZztcbiAgbWV0aG9kPzogc3RyaW5nO1xuICB0b2tlbj86IHN0cmluZztcbiAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGJvZHk/OiB1bmtub3duO1xuICBzZWFyY2hQYXJhbXM/OiBTZWFyY2hQYXJhbXM7XG4gIG1heEF0dGVtcHRzPzogbnVtYmVyO1xuICBpbml0aWFsRGVsYXlNcz86IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIEZpZ21hU3VjY2VzczxURGF0YT4ge1xuICBvazogdHJ1ZTtcbiAgZGF0YTogVERhdGE7XG4gIHJhdGVMaW1pdDogUmF0ZUxpbWl0TWV0YTtcbn1cblxuaW50ZXJmYWNlIEZpZ21hRmFpbHVyZSB7XG4gIG9rOiBmYWxzZTtcbiAgZXJyb3I6IFRvb2xFcnJvcjx7IHN0YXR1cz86IG51bWJlciB9PjtcbiAgc3RhdHVzPzogbnVtYmVyIHwgbnVsbDtcbiAgcmF0ZUxpbWl0OiBSYXRlTGltaXRNZXRhIHwgbnVsbDtcbn1cblxuZXhwb3J0IHR5cGUgRmlnbWFSZXNwb25zZTxURGF0YT4gPSBGaWdtYVN1Y2Nlc3M8VERhdGE+IHwgRmlnbWFGYWlsdXJlO1xuXG5mdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUpzb25TYWZlbHkodGV4dDogc3RyaW5nKTogdW5rbm93biB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHRleHQgPyBKU09OLnBhcnNlKHRleHQpIDoge307XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB7IHJhdzogdGV4dCB9O1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhcnNlUmF0ZUxpbWl0KGhlYWRlcnM6IEhlYWRlcnMsIGF0dGVtcHRzOiBudW1iZXIsIGxhc3RXYWl0TXM6IG51bWJlcik6IFJhdGVMaW1pdE1ldGEge1xuICBjb25zdCByZW1haW5pbmdIZWFkZXIgPSBoZWFkZXJzLmdldCgneC1yYXRlbGltaXQtcmVtYWluaW5nJyk7XG4gIGNvbnN0IHJlc2V0SGVhZGVyID0gaGVhZGVycy5nZXQoJ3gtcmF0ZWxpbWl0LXJlc2V0Jyk7XG5cbiAgbGV0IHJlbWFpbmluZzogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIGlmIChyZW1haW5pbmdIZWFkZXIgIT09IG51bGwgJiYgcmVtYWluaW5nSGVhZGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBwYXJzZWQgPSBOdW1iZXIocmVtYWluaW5nSGVhZGVyKTtcbiAgICByZW1haW5pbmcgPSBOdW1iZXIuaXNOYU4ocGFyc2VkKSA/IG51bGwgOiBwYXJzZWQ7XG4gIH1cblxuICBsZXQgcmVzZXRBdDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIGlmIChyZXNldEhlYWRlcikge1xuICAgIGNvbnN0IG51bWVyaWNSZXNldCA9IE51bWJlcihyZXNldEhlYWRlcik7XG4gICAgaWYgKCFOdW1iZXIuaXNOYU4obnVtZXJpY1Jlc2V0KSkge1xuICAgICAgcmVzZXRBdCA9IG5ldyBEYXRlKG51bWVyaWNSZXNldCAqIDEwMDApLnRvSVNPU3RyaW5nKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZShyZXNldEhlYWRlcik7XG4gICAgICBpZiAoIU51bWJlci5pc05hTihkYXRlLnZhbHVlT2YoKSkpIHtcbiAgICAgICAgcmVzZXRBdCA9IGRhdGUudG9JU09TdHJpbmcoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHJlbWFpbmluZyxcbiAgICByZXNldEF0LFxuICAgIGF0dGVtcHRzLFxuICAgIGxhc3RXYWl0TXMsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVCYWNrb2ZmTXMoYXR0ZW1wdDogbnVtYmVyLCBpbml0aWFsRGVsYXlNczogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIGluaXRpYWxEZWxheU1zICogMiAqKiAoYXR0ZW1wdCAtIDEpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmlnbWFSZXF1ZXN0PFREYXRhID0gdW5rbm93bj4oXG4gIG9wdGlvbnM6IEZpZ21hUmVxdWVzdE9wdGlvbnNcbik6IFByb21pc2U8RmlnbWFSZXNwb25zZTxURGF0YT4+IHtcbiAgY29uc3Qge1xuICAgIHBhdGgsXG4gICAgbWV0aG9kID0gJ0dFVCcsXG4gICAgdG9rZW4sXG4gICAgaGVhZGVycyA9IHt9LFxuICAgIGJvZHksXG4gICAgc2VhcmNoUGFyYW1zLFxuICAgIG1heEF0dGVtcHRzID0gY29uZmlnLmh0dHA/Lm1heEF0dGVtcHRzID8/IDUsXG4gICAgaW5pdGlhbERlbGF5TXMgPSBjb25maWcuaHR0cD8uaW5pdGlhbERlbGF5TXMgPz8gMjUwLFxuICB9ID0gb3B0aW9ucztcblxuICBpZiAoIXRva2VuKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9rOiBmYWxzZSxcbiAgICAgIGVycm9yOiBjcmVhdGVFcnJvcignRklHTUFfQVVUSCcsICdGSUdNQV9BQ0NFU1NfVE9LRU4gaXMgbWlzc2luZyBmcm9tIHRoZSBlbnZpcm9ubWVudC4nKSxcbiAgICAgIHN0YXR1czogbnVsbCxcbiAgICAgIHJhdGVMaW1pdDogbnVsbCxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgdXJsID0gbmV3IFVSTChwYXRoLCBCQVNFX1VSTCk7XG5cbiAgaWYgKHNlYXJjaFBhcmFtcykge1xuICAgIE9iamVjdC5lbnRyaWVzKHNlYXJjaFBhcmFtcykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCkgcmV0dXJuO1xuICAgICAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoa2V5LCBTdHJpbmcodmFsdWUpKTtcbiAgICB9KTtcbiAgfVxuXG4gIGxldCBhdHRlbXB0ID0gMDtcbiAgbGV0IGxhc3RXYWl0TXMgPSAwO1xuXG4gIHdoaWxlIChhdHRlbXB0IDwgbWF4QXR0ZW1wdHMpIHtcbiAgICBhdHRlbXB0ICs9IDE7XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCwge1xuICAgICAgbWV0aG9kLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAnWC1GaWdtYS1Ub2tlbic6IHRva2VuLFxuICAgICAgICAuLi5oZWFkZXJzLFxuICAgICAgfSxcbiAgICAgIGJvZHk6IGJvZHkgPyBKU09OLnN0cmluZ2lmeShib2R5KSA6IHVuZGVmaW5lZCxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG4gICAgY29uc3QgcGF5bG9hZCA9IHBhcnNlSnNvblNhZmVseSh0ZXh0KSBhcyB7IG1lc3NhZ2U/OiBzdHJpbmcgfTtcbiAgICBjb25zdCByYXRlTGltaXQgPSBwYXJzZVJhdGVMaW1pdChyZXNwb25zZS5oZWFkZXJzLCBhdHRlbXB0LCBsYXN0V2FpdE1zKTtcblxuICAgIGlmIChyZXNwb25zZS5vaykge1xuICAgICAgcmV0dXJuIHsgb2s6IHRydWUsIGRhdGE6IHBheWxvYWQgYXMgVERhdGEsIHJhdGVMaW1pdCB9O1xuICAgIH1cblxuICAgIGNvbnN0IHN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cztcblxuICAgIGlmIChzdGF0dXMgPT09IDQwMSB8fCBzdGF0dXMgPT09IDQwMykge1xuICAgICAgcmV0dXJuIHsgb2s6IGZhbHNlLCBlcnJvcjogY3JlYXRlRXJyb3IoJ0ZJR01BX0FVVEgnLCBwYXlsb2FkPy5tZXNzYWdlID8/ICdGaWdtYSB0b2tlbiBpcyB1bmF1dGhvcml6ZWQuJywgeyBzdGF0dXMgfSksIHN0YXR1cywgcmF0ZUxpbWl0IH07XG4gICAgfVxuXG4gICAgaWYgKHN0YXR1cyA9PT0gNDA0KSB7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIGVycm9yOiBjcmVhdGVFcnJvcignRklHTUFfTk9UX0ZPVU5EJywgcGF5bG9hZD8ubWVzc2FnZSA/PyAnUmVzb3VyY2Ugbm90IGZvdW5kLicsIHsgc3RhdHVzIH0pLCBzdGF0dXMsIHJhdGVMaW1pdCB9O1xuICAgIH1cblxuICAgIGlmIChzdGF0dXMgPT09IDQyOSB8fCBzdGF0dXMgPj0gNTAwKSB7XG4gICAgICBpZiAoYXR0ZW1wdCA+PSBtYXhBdHRlbXB0cykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG9rOiBmYWxzZSxcbiAgICAgICAgICBlcnJvcjogY3JlYXRlRXJyb3Ioc3RhdHVzID09PSA0MjkgPyAnRklHTUFfUkFURV9MSU1JVCcgOiAnTkVUV09SSycsIHBheWxvYWQ/Lm1lc3NhZ2UgPz8gJ0ZpZ21hIHJlcXVlc3QgZmFpbGVkIGFmdGVyIG1heGltdW0gcmV0cmllcy4nLCB7IHN0YXR1cyB9KSxcbiAgICAgICAgICBzdGF0dXMsXG4gICAgICAgICAgcmF0ZUxpbWl0LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBsZXQgd2FpdE1zID0gY29tcHV0ZUJhY2tvZmZNcyhhdHRlbXB0LCBpbml0aWFsRGVsYXlNcyk7XG4gICAgICBjb25zdCByZXNldEhlYWRlciA9IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCd4LXJhdGVsaW1pdC1yZXNldCcpO1xuICAgICAgaWYgKHJlc2V0SGVhZGVyKSB7XG4gICAgICAgIGNvbnN0IGFzTnVtYmVyID0gTnVtYmVyKHJlc2V0SGVhZGVyKTtcbiAgICAgICAgaWYgKCFOdW1iZXIuaXNOYU4oYXNOdW1iZXIpKSB7XG4gICAgICAgICAgY29uc3QgcmVzZXRNcyA9IGFzTnVtYmVyICogMTAwMDtcbiAgICAgICAgICBjb25zdCBkZWx0YSA9IHJlc2V0TXMgLSBEYXRlLm5vdygpO1xuICAgICAgICAgIGlmIChkZWx0YSA+IDApIHdhaXRNcyA9IE1hdGgubWF4KHdhaXRNcywgZGVsdGEpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGppdHRlciA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDEwMCk7XG4gICAgICBsYXN0V2FpdE1zID0gd2FpdE1zICsgaml0dGVyO1xuICAgICAgYXdhaXQgc2xlZXAobGFzdFdhaXRNcyk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBvazogZmFsc2UsIGVycm9yOiBjcmVhdGVFcnJvcignSU5URVJOQUwnLCBwYXlsb2FkPy5tZXNzYWdlID8/ICdVbmV4cGVjdGVkIGVycm9yIGZyb20gRmlnbWEgQVBJLicsIHsgc3RhdHVzIH0pLCBzdGF0dXMsIHJhdGVMaW1pdCB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBvazogZmFsc2UsXG4gICAgZXJyb3I6IGNyZWF0ZUVycm9yKCdORVRXT1JLJywgJ1VuYWJsZSB0byByZWFjaCBGaWdtYSBBUEkuJyksXG4gICAgc3RhdHVzOiBudWxsLFxuICAgIHJhdGVMaW1pdDogeyByZW1haW5pbmc6IG51bGwsIHJlc2V0QXQ6IG51bGwsIGF0dGVtcHRzOiBtYXhBdHRlbXB0cywgbGFzdFdhaXRNcyB9LFxuICB9O1xufVxuXG4iLCAiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuXG5pbXBvcnQgeyBwYXJzZUFyZ3MsIHR5cGUgQ2xpQXJncyB9IGZyb20gJy4vX3V0aWxzL2NsaS1hcmdzLnRzJ1xuaW1wb3J0IHsgcGFyc2VGaWdtYVVybCB9IGZyb20gJy4vX3V0aWxzL3VybC1wYXJzZS50cydcbmltcG9ydCB7IGNyZWF0ZUVudmVsb3BlLCB0eXBlIFRvb2xFbnZlbG9wZSB9IGZyb20gJy4vX3V0aWxzL2VudmVsb3BlLnRzJ1xuaW1wb3J0IHsgY3JlYXRlRXJyb3IsIGdldEV4aXRDb2RlLCB0eXBlIFRvb2xFcnJvciB9IGZyb20gJy4vX3V0aWxzL2Vycm9ycy50cydcbmltcG9ydCB7IGZpZ21hUmVxdWVzdCB9IGZyb20gJy4vX3V0aWxzL2h0dHAtY2xpZW50LnRzJ1xuXG5jb25zdCBUT09MX05BTUUgPSAnZ2V0LXZhcmlhYmxlLWRlZmluaXRpb25zJ1xudHlwZSBFbXB0eURhdGEgPSBSZWNvcmQ8c3RyaW5nLCBuZXZlcj5cblxuaW50ZXJmYWNlIFRvb2xJbnB1dCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgZmlsZUtleTogc3RyaW5nIHwgbnVsbFxuICBpbmNsdWRlU3R5bGVzOiBib29sZWFuXG59XG5cbmludGVyZmFjZSBWYXJpYWJsZU1vZGUgeyBtb2RlSWQ6IHN0cmluZzsgbmFtZTogc3RyaW5nIH1cblxuaW50ZXJmYWNlIFZhcmlhYmxlUGF5bG9hZEVudHJ5IHtcbiAgaWQ6IHN0cmluZ1xuICBuYW1lOiBzdHJpbmdcbiAga2V5Pzogc3RyaW5nXG4gIHJlc29sdmVkVHlwZT86IHN0cmluZ1xuICBjb2xsZWN0aW9uSWQ/OiBzdHJpbmdcbiAgdmFyaWFibGVDb2xsZWN0aW9uSWQ/OiBzdHJpbmdcbiAgdmFyaWFibGVTZXRJZD86IHN0cmluZ1xuICB2YXJpYWJsZUNvbGxlY3Rpb24/OiBzdHJpbmdcbiAgdmFyaWFibGVTZXQ/OiBzdHJpbmdcbiAgc2NvcGVzPzogc3RyaW5nW11cbiAgZGVzY3JpcHRpb24/OiBzdHJpbmdcbiAgZGVmYXVsdE1vZGVJZD86IHN0cmluZ1xuICB2YWx1ZXNCeU1vZGU/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICBtb2Rlcz86IFZhcmlhYmxlTW9kZVtdXG59XG5cbmludGVyZmFjZSBWYXJpYWJsZUNvbGxlY3Rpb25NZXRhIHsgaWQ6IHN0cmluZzsgbmFtZT86IHN0cmluZyB9XG5cbmludGVyZmFjZSBWYXJpYWJsZXNSZXNwb25zZVBheWxvYWQge1xuICBjb2xsZWN0aW9ucz86IFZhcmlhYmxlQ29sbGVjdGlvbk1ldGFbXVxuICB2YXJpYWJsZUNvbGxlY3Rpb25zPzogVmFyaWFibGVDb2xsZWN0aW9uTWV0YVtdXG4gIHZhcmlhYmxlcz86IFZhcmlhYmxlUGF5bG9hZEVudHJ5W11cbn1cblxuaW50ZXJmYWNlIFN0eWxlc1Jlc3BvbnNlUGF5bG9hZCB7IG1ldGE/OiB7IHN0eWxlcz86IFJlY29yZDxzdHJpbmcsIEZpZ21hU3R5bGU+IH07IHN0eWxlcz86IEZpZ21hU3R5bGVbXSB9XG5pbnRlcmZhY2UgRmlnbWFTdHlsZSB7IGtleT86IHN0cmluZzsgbmFtZT86IHN0cmluZzsgc3R5bGVfdHlwZT86IHN0cmluZzsgZGVzY3JpcHRpb24/OiBzdHJpbmcgfVxuXG5pbnRlcmZhY2UgVmFyaWFibGVFbnRyeSB7XG4gIGlkOiBzdHJpbmdcbiAgbmFtZTogc3RyaW5nXG4gIGtleT86IHN0cmluZ1xuICByZXNvbHZlZFR5cGU/OiBzdHJpbmdcbiAgY29sbGVjdGlvbklkOiBzdHJpbmcgfCBudWxsXG4gIGNvbGxlY3Rpb25OYW1lOiBzdHJpbmcgfCBudWxsXG4gIHZhcmlhYmxlU2V0SWQ6IHN0cmluZyB8IG51bGxcbiAgdmFyaWFibGVTZXROYW1lOiBzdHJpbmcgfCBudWxsXG4gIHNjb3Blczogc3RyaW5nW11cbiAgZGVzY3JpcHRpb246IHN0cmluZyB8IG51bGxcbiAgZGVmYXVsdFZhbHVlOiB1bmtub3duXG4gIHZhbHVlc0J5TW9kZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbn1cblxuaW50ZXJmYWNlIFBhcnRpdGlvbmVkVmFyaWFibGVzIHtcbiAgY29sb3JzOiBWYXJpYWJsZUVudHJ5W11cbiAgc3BhY2luZzogVmFyaWFibGVFbnRyeVtdXG4gIHR5cG9ncmFwaHk6IFZhcmlhYmxlRW50cnlbXVxuICBvdGhlcnM6IFZhcmlhYmxlRW50cnlbXVxufVxuXG5pbnRlcmZhY2UgVmFyaWFibGVEYXRhIHtcbiAgZmlsZTogeyBrZXk6IHN0cmluZyB9XG4gIHZhcmlhYmxlczogUGFydGl0aW9uZWRWYXJpYWJsZXNcbiAgcmF3VmFyaWFibGVzOiBWYXJpYWJsZUVudHJ5W11cbiAgc3R5bGVzOiBGaWdtYVN0eWxlW11cbn1cblxuZnVuY3Rpb24gbG9nKG1lc3NhZ2U6IHN0cmluZywgdmVyYm9zZTogYm9vbGVhbik6IHZvaWQge1xuICBpZiAodmVyYm9zZSkgcHJvY2Vzcy5zdGRlcnIud3JpdGUoYFske1RPT0xfTkFNRX1dICR7bWVzc2FnZX1cXG5gKVxufVxuXG5mdW5jdGlvbiB0b09wdGlvbmFsU3RyaW5nKHZhbHVlOiBDbGlBcmdzW3N0cmluZ10pOiBzdHJpbmcgfCBudWxsIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUubGVuZ3RoID4gMCA/IHZhbHVlIDogbnVsbFxufVxuXG5mdW5jdGlvbiBleGl0V2l0aEVudmVsb3BlKFxuICBlbnZlbG9wZTogVG9vbEVudmVsb3BlPFRvb2xJbnB1dCwgVmFyaWFibGVEYXRhIHwgRW1wdHlEYXRhPixcbiAgZXJyb3JzOiBUb29sRXJyb3JbXSA9IFtdXG4pOiBuZXZlciB7XG4gIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGAke0pTT04uc3RyaW5naWZ5KGVudmVsb3BlLCBudWxsLCAyKX1cXG5gKVxuICBwcm9jZXNzLmV4aXQoZ2V0RXhpdENvZGUoZXJyb3JzKSlcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZUNvbGxlY3Rpb25OYW1lKGlkOiBzdHJpbmcgfCB1bmRlZmluZWQsIGNvbGxlY3Rpb25zOiBWYXJpYWJsZUNvbGxlY3Rpb25NZXRhW10pOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKCFpZCkgcmV0dXJuIG51bGxcbiAgY29uc3QgZW50cnkgPSBjb2xsZWN0aW9ucy5maW5kKChjKSA9PiBjLmlkID09PSBpZClcbiAgcmV0dXJuIGVudHJ5Py5uYW1lID8/IG51bGxcbn1cblxuZnVuY3Rpb24gYnVpbGRWYXJpYWJsZUVudHJ5KFxuICB2YXJpYWJsZTogVmFyaWFibGVQYXlsb2FkRW50cnksXG4gIGNvbGxlY3Rpb25zOiBWYXJpYWJsZUNvbGxlY3Rpb25NZXRhW10sXG4gIHNldHM6IFZhcmlhYmxlQ29sbGVjdGlvbk1ldGFbXVxuKTogVmFyaWFibGVFbnRyeSB7XG4gIHJldHVybiB7XG4gICAgaWQ6IHZhcmlhYmxlLmlkLFxuICAgIG5hbWU6IHZhcmlhYmxlLm5hbWUsXG4gICAga2V5OiB2YXJpYWJsZS5rZXksXG4gICAgcmVzb2x2ZWRUeXBlOiB2YXJpYWJsZS5yZXNvbHZlZFR5cGUsXG4gICAgY29sbGVjdGlvbklkOiB2YXJpYWJsZS5jb2xsZWN0aW9uSWQgPz8gdmFyaWFibGUudmFyaWFibGVDb2xsZWN0aW9uSWQgPz8gbnVsbCxcbiAgICBjb2xsZWN0aW9uTmFtZTpcbiAgICAgIHJlc29sdmVDb2xsZWN0aW9uTmFtZSh2YXJpYWJsZS5jb2xsZWN0aW9uSWQgPz8gdmFyaWFibGUudmFyaWFibGVDb2xsZWN0aW9uSWQsIGNvbGxlY3Rpb25zKSxcbiAgICB2YXJpYWJsZVNldElkOiB2YXJpYWJsZS52YXJpYWJsZVNldElkID8/IG51bGwsXG4gICAgdmFyaWFibGVTZXROYW1lOiByZXNvbHZlQ29sbGVjdGlvbk5hbWUodmFyaWFibGUudmFyaWFibGVTZXRJZCwgc2V0cyksXG4gICAgc2NvcGVzOiB2YXJpYWJsZS5zY29wZXMgPz8gW10sXG4gICAgZGVzY3JpcHRpb246IHZhcmlhYmxlLmRlc2NyaXB0aW9uID8/IG51bGwsXG4gICAgZGVmYXVsdFZhbHVlOiB2YXJpYWJsZS52YWx1ZXNCeU1vZGU/Llt2YXJpYWJsZS5kZWZhdWx0TW9kZUlkID8/ICcnXSA/PyBudWxsLFxuICAgIHZhbHVlc0J5TW9kZTogdmFyaWFibGUudmFsdWVzQnlNb2RlID8/IHt9LFxuICB9XG59XG5cbmZ1bmN0aW9uIHBhcnRpdGlvblZhcmlhYmxlcyhsaXN0OiBWYXJpYWJsZUVudHJ5W10pOiBQYXJ0aXRpb25lZFZhcmlhYmxlcyB7XG4gIGNvbnN0IGNvbG9yczogVmFyaWFibGVFbnRyeVtdID0gW11cbiAgY29uc3Qgc3BhY2luZzogVmFyaWFibGVFbnRyeVtdID0gW11cbiAgY29uc3QgdHlwb2dyYXBoeTogVmFyaWFibGVFbnRyeVtdID0gW11cbiAgY29uc3Qgb3RoZXJzOiBWYXJpYWJsZUVudHJ5W10gPSBbXVxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGxpc3QpIHtcbiAgICBzd2l0Y2ggKGVudHJ5LnJlc29sdmVkVHlwZSkge1xuICAgICAgY2FzZSAnQ09MT1InOlxuICAgICAgICBjb2xvcnMucHVzaChlbnRyeSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ0ZMT0FUJzpcbiAgICAgICAgc3BhY2luZy5wdXNoKGVudHJ5KVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnU1RSSU5HJzpcbiAgICAgIGNhc2UgJ0JPT0xFQU4nOlxuICAgICAgICB0eXBvZ3JhcGh5LnB1c2goZW50cnkpXG4gICAgICAgIGJyZWFrXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBvdGhlcnMucHVzaChlbnRyeSlcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHsgY29sb3JzLCBzcGFjaW5nLCB0eXBvZ3JhcGh5LCBvdGhlcnMgfVxufVxuXG5mdW5jdGlvbiBleHRyYWN0U3R5bGVzKHBheWxvYWQ6IFN0eWxlc1Jlc3BvbnNlUGF5bG9hZCB8IG51bGwgfCB1bmRlZmluZWQpOiBGaWdtYVN0eWxlW10ge1xuICBpZiAoIXBheWxvYWQpIHJldHVybiBbXVxuICBpZiAoQXJyYXkuaXNBcnJheShwYXlsb2FkLnN0eWxlcykpIHJldHVybiBwYXlsb2FkLnN0eWxlc1xuICBpZiAocGF5bG9hZC5tZXRhPy5zdHlsZXMpIHJldHVybiBPYmplY3QudmFsdWVzKHBheWxvYWQubWV0YS5zdHlsZXMpXG4gIHJldHVybiBbXVxufVxuXG5hc3luYyBmdW5jdGlvbiBtYWluKCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBhcmdzID0gcGFyc2VBcmdzKClcbiAgY29uc3QgdmVyYm9zZSA9IEJvb2xlYW4oYXJncy52ZXJib3NlID8/IGFyZ3MudilcbiAgY29uc3Qgc2NoZW1hVmVyc2lvbiA9IHRvT3B0aW9uYWxTdHJpbmcoYXJnc1snc2NoZW1hLXZlcnNpb24nXSkgPz8gdW5kZWZpbmVkXG5cbiAgY29uc3Qgd2FybmluZ3M6IHN0cmluZ1tdID0gW11cbiAgY29uc3QgZXJyb3JzOiBUb29sRXJyb3JbXSA9IFtdXG5cbiAgY29uc3QgdG9rZW4gPSBwcm9jZXNzLmVudi5GSUdNQV9BQ0NFU1NfVE9LRU5cbiAgaWYgKCF0b2tlbiB8fCAhdG9rZW4udHJpbSgpKSB7XG4gICAgZXJyb3JzLnB1c2goY3JlYXRlRXJyb3IoJ0ZJR01BX0FVVEgnLCAnRklHTUFfQUNDRVNTX1RPS0VOIGlzIHJlcXVpcmVkIGJ1dCB3YXMgbm90IHByb3ZpZGVkLicpKVxuICAgIGNvbnN0IGVudmVsb3BlID0gY3JlYXRlRW52ZWxvcGU8VG9vbElucHV0LCBFbXB0eURhdGE+KHtcbiAgICAgIHRvb2w6IFRPT0xfTkFNRSxcbiAgICAgIGlucHV0OiB7IGZpbGVLZXk6IG51bGwsIGluY2x1ZGVTdHlsZXM6IGZhbHNlIH0sXG4gICAgICB3YXJuaW5ncyxcbiAgICAgIGVycm9ycyxcbiAgICAgIHNjaGVtYVZlcnNpb24sXG4gICAgICBkYXRhOiB7fSBhcyBFbXB0eURhdGEsXG4gICAgfSlcbiAgICBleGl0V2l0aEVudmVsb3BlKGVudmVsb3BlLCBlcnJvcnMpXG4gIH1cblxuICBjb25zdCB1cmxJbnB1dCA9IHRvT3B0aW9uYWxTdHJpbmcoYXJncy51cmwpID8/IHRvT3B0aW9uYWxTdHJpbmcoYXJncy51KVxuICBsZXQgZmlsZUtleSA9IHRvT3B0aW9uYWxTdHJpbmcoYXJnc1snZmlsZS1rZXknXSkgPz8gdW5kZWZpbmVkXG4gIGlmICh1cmxJbnB1dCkge1xuICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlRmlnbWFVcmwodXJsSW5wdXQpXG4gICAgZmlsZUtleSA9IGZpbGVLZXkgfHwgcGFyc2VkLmZpbGVLZXkgfHwgdW5kZWZpbmVkXG4gIH1cblxuICBjb25zdCBpbmNsdWRlU3R5bGVzID0gYXJnc1snaW5jbHVkZS1zdHlsZXMnXSAhPT0gJ2ZhbHNlJ1xuXG4gIGNvbnN0IGlucHV0OiBUb29sSW5wdXQgPSB7IGZpbGVLZXk6IGZpbGVLZXkgPz8gbnVsbCwgaW5jbHVkZVN0eWxlcyB9XG5cbiAgaWYgKCFmaWxlS2V5KSB7XG4gICAgZXJyb3JzLnB1c2goY3JlYXRlRXJyb3IoJ0lOUFVUX0lOVkFMSUQnLCAnQSB2YWxpZCBGaWdtYSBmaWxlIGtleSBpcyByZXF1aXJlZCAoLS1maWxlLWtleSBvciAtLXVybCkuJykpXG4gIH1cbiAgaWYgKGVycm9ycy5sZW5ndGgpIHtcbiAgICBjb25zdCBlbnZlbG9wZSA9IGNyZWF0ZUVudmVsb3BlPFRvb2xJbnB1dCwgRW1wdHlEYXRhPih7IHRvb2w6IFRPT0xfTkFNRSwgaW5wdXQsIHdhcm5pbmdzLCBlcnJvcnMsIGRhdGE6IHt9IGFzIEVtcHR5RGF0YSwgc2NoZW1hVmVyc2lvbiB9KVxuICAgIGV4aXRXaXRoRW52ZWxvcGUoZW52ZWxvcGUsIGVycm9ycylcbiAgfVxuXG4gIGNvbnN0IHJlc29sdmVkRmlsZUtleSA9IGZpbGVLZXkgYXMgc3RyaW5nXG5cbiAgbG9nKCdGZXRjaGluZyB2YXJpYWJsZXMnLCB2ZXJib3NlKVxuICBjb25zdCB2YXJpYWJsZXNSZXNwb25zZSA9IGF3YWl0IGZpZ21hUmVxdWVzdDxWYXJpYWJsZXNSZXNwb25zZVBheWxvYWQ+KHtcbiAgICBwYXRoOiBgL3YxL2ZpbGVzLyR7cmVzb2x2ZWRGaWxlS2V5fS92YXJpYWJsZXMvbG9jYWxgLFxuICAgIHRva2VuLFxuICB9KVxuXG4gIGxldCBzdHlsZXNSZXNwb25zZTpcbiAgICB8IEF3YWl0ZWQ8UmV0dXJuVHlwZTx0eXBlb2YgZmlnbWFSZXF1ZXN0PFN0eWxlc1Jlc3BvbnNlUGF5bG9hZD4+PlxuICAgIHwgeyBvazogdHJ1ZTsgZGF0YTogU3R5bGVzUmVzcG9uc2VQYXlsb2FkOyByYXRlTGltaXQ6IG51bGwgfVxuXG4gIGlmIChpbmNsdWRlU3R5bGVzKSB7XG4gICAgbG9nKCdGZXRjaGluZyBzdHlsZXMnLCB2ZXJib3NlKVxuICAgIHN0eWxlc1Jlc3BvbnNlID0gYXdhaXQgZmlnbWFSZXF1ZXN0PFN0eWxlc1Jlc3BvbnNlUGF5bG9hZD4oeyBwYXRoOiBgL3YxL2ZpbGVzLyR7cmVzb2x2ZWRGaWxlS2V5fS9zdHlsZXNgLCB0b2tlbiB9KVxuICB9IGVsc2Uge1xuICAgIHN0eWxlc1Jlc3BvbnNlID0geyBvazogdHJ1ZSwgZGF0YTogeyBzdHlsZXM6IFtdIH0sIHJhdGVMaW1pdDogbnVsbCB9XG4gIH1cblxuICBpZiAoIXZhcmlhYmxlc1Jlc3BvbnNlLm9rKSB7XG4gICAgZXJyb3JzLnB1c2godmFyaWFibGVzUmVzcG9uc2UuZXJyb3IgPz8gY3JlYXRlRXJyb3IoJ0lOVEVSTkFMJywgJ0ZhaWxlZCB0byBmZXRjaCB2YXJpYWJsZXMuJykpXG4gICAgY29uc3QgZW52ZWxvcGUgPSBjcmVhdGVFbnZlbG9wZTxUb29sSW5wdXQsIEVtcHR5RGF0YT4oeyB0b29sOiBUT09MX05BTUUsIGlucHV0LCB3YXJuaW5ncywgZXJyb3JzLCByYXRlTGltaXQ6IHZhcmlhYmxlc1Jlc3BvbnNlLnJhdGVMaW1pdCA/PyB1bmRlZmluZWQsIHNjaGVtYVZlcnNpb24sIGRhdGE6IHt9IGFzIEVtcHR5RGF0YSB9KVxuICAgIGV4aXRXaXRoRW52ZWxvcGUoZW52ZWxvcGUsIGVycm9ycylcbiAgfVxuXG4gIGlmICghc3R5bGVzUmVzcG9uc2Uub2spIHtcbiAgICB3YXJuaW5ncy5wdXNoKHN0eWxlc1Jlc3BvbnNlLmVycm9yPy5tZXNzYWdlID8/ICdGYWlsZWQgdG8gZmV0Y2ggc3R5bGVzLicpXG4gIH1cblxuICBjb25zdCB2YXJpYWJsZXNQYXlsb2FkID0gdmFyaWFibGVzUmVzcG9uc2UuZGF0YSA/PyB7fVxuICBjb25zdCB2YXJpYWJsZUNvbGxlY3Rpb25zID0gdmFyaWFibGVzUGF5bG9hZC5jb2xsZWN0aW9ucyA/PyBbXVxuICBjb25zdCB2YXJpYWJsZVNldHMgPSB2YXJpYWJsZXNQYXlsb2FkLnZhcmlhYmxlQ29sbGVjdGlvbnMgPz8gW11cbiAgY29uc3QgdmFyaWFibGVzID0gdmFyaWFibGVzUGF5bG9hZC52YXJpYWJsZXMgPz8gW11cblxuICBjb25zdCBub3JtYWxpc2VkVmFyaWFibGVzID0gdmFyaWFibGVzLm1hcCgodikgPT4gYnVpbGRWYXJpYWJsZUVudHJ5KHYsIHZhcmlhYmxlQ29sbGVjdGlvbnMsIHZhcmlhYmxlU2V0cykpXG4gIGNvbnN0IHBhcnRpdGlvbnMgPSBwYXJ0aXRpb25WYXJpYWJsZXMobm9ybWFsaXNlZFZhcmlhYmxlcylcbiAgY29uc3Qgc3R5bGVzID0gc3R5bGVzUmVzcG9uc2Uub2sgPyBleHRyYWN0U3R5bGVzKHN0eWxlc1Jlc3BvbnNlLmRhdGEpIDogW11cblxuICBjb25zdCBkYXRhOiBWYXJpYWJsZURhdGEgPSB7XG4gICAgZmlsZTogeyBrZXk6IHJlc29sdmVkRmlsZUtleSB9LFxuICAgIHZhcmlhYmxlczogcGFydGl0aW9ucyxcbiAgICByYXdWYXJpYWJsZXM6IG5vcm1hbGlzZWRWYXJpYWJsZXMsXG4gICAgc3R5bGVzLFxuICB9XG5cbiAgY29uc3QgZW52ZWxvcGUgPSBjcmVhdGVFbnZlbG9wZTxUb29sSW5wdXQsIFZhcmlhYmxlRGF0YT4oeyB0b29sOiBUT09MX05BTUUsIGlucHV0LCBkYXRhLCB3YXJuaW5ncywgZXJyb3JzLCByYXRlTGltaXQ6IHZhcmlhYmxlc1Jlc3BvbnNlLnJhdGVMaW1pdCA/PyB1bmRlZmluZWQsIHNjaGVtYVZlcnNpb24gfSlcbiAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoYCR7SlNPTi5zdHJpbmdpZnkoZW52ZWxvcGUsIG51bGwsIDIpfVxcbmApXG4gIHByb2Nlc3MuZXhpdChnZXRFeGl0Q29kZShlcnJvcnMpKVxufVxuXG5tYWluKCkuY2F0Y2goKGVycm9yOiB1bmtub3duKSA9PiB7XG4gIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICdVbmtub3duIGVycm9yJ1xuICBjb25zdCBlbnZlbG9wZSA9IGNyZWF0ZUVudmVsb3BlPFRvb2xJbnB1dCwgRW1wdHlEYXRhPih7IHRvb2w6IFRPT0xfTkFNRSwgaW5wdXQ6IHsgZmlsZUtleTogbnVsbCwgaW5jbHVkZVN0eWxlczogZmFsc2UgfSwgZXJyb3JzOiBbY3JlYXRlRXJyb3IoJ0lOVEVSTkFMJywgbWVzc2FnZSwgeyBzdGFjazogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLnN0YWNrIDogdW5kZWZpbmVkIH0pXSwgZGF0YToge30gYXMgRW1wdHlEYXRhIH0pXG4gIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGAke0pTT04uc3RyaW5naWZ5KGVudmVsb3BlLCBudWxsLCAyKX1cXG5gKVxuICBwcm9jZXNzLmV4aXQoMylcbn0pXG5cbiJdLAogICJtYXBwaW5ncyI6ICI7OztBQU9PLFNBQVMsVUFBVSxPQUFpQixRQUFRLEtBQUssTUFBTSxDQUFDLEdBQVk7QUFDekUsUUFBTSxPQUFnQixFQUFFLEdBQUcsQ0FBQyxFQUFFO0FBRTlCLFdBQVMsSUFBSSxHQUFHLElBQUksS0FBSyxRQUFRLEtBQUssR0FBRztBQUN2QyxVQUFNLE1BQU0sS0FBSyxDQUFDO0FBRWxCLFFBQUksQ0FBQyxJQUFJLFdBQVcsR0FBRyxLQUFLLFFBQVEsS0FBSztBQUN2QyxXQUFLLEVBQUUsS0FBSyxHQUFHO0FBQ2Y7QUFBQSxJQUNGO0FBRUEsUUFBSSxRQUFRLE1BQU07QUFDaEIsWUFBTSxZQUFZLEtBQUssTUFBTSxJQUFJLENBQUM7QUFDbEMsV0FBSyxFQUFFLEtBQUssR0FBRyxTQUFTO0FBQ3hCO0FBQUEsSUFDRjtBQUVBLFVBQU0sQ0FBQyxRQUFRLFdBQVcsSUFBSSxJQUFJLE1BQU0sS0FBSyxDQUFDO0FBQzlDLFVBQU0sZ0JBQWdCLE9BQU8sUUFBUSxPQUFPLEVBQUU7QUFFOUMsUUFBSTtBQUNKLFFBQUksZ0JBQWdCLFFBQVc7QUFDN0IsY0FBUTtBQUFBLElBQ1YsT0FBTztBQUNMLFlBQU0sT0FBTyxLQUFLLElBQUksQ0FBQztBQUN2QixVQUFJLFNBQVMsVUFBYSxDQUFDLEtBQUssV0FBVyxHQUFHLEdBQUc7QUFDL0MsZ0JBQVE7QUFDUixhQUFLO0FBQUEsTUFDUCxPQUFPO0FBQ0wsZ0JBQVE7QUFBQSxNQUNWO0FBQUEsSUFDRjtBQUVBLFNBQUssYUFBYSxJQUFJO0FBQUEsRUFDeEI7QUFFQSxTQUFPO0FBQ1Q7OztBQzVDQSxJQUFNLGlCQUFpQjtBQU9o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